mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-16 04:02:15 +01:00
refactor to shadcn components, dynamically load extension frontend
add jetstream permissions, add dynamic inertia module loading, add shadcn components, change modals and dropdowns to shadcn dismissable layer,
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, onUnmounted, watch } from 'vue';
|
||||
import { useId } from 'radix-vue';
|
||||
import { isLastLayer, layers } from '@/packages/ui/src/utils/dismissableLayer';
|
||||
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap';
|
||||
import { ref } from 'vue';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
} from '@/Components/ui/dialog'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
show: {
|
||||
@@ -22,51 +23,12 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
watch(
|
||||
() => props.show,
|
||||
() => {
|
||||
if (props.show) {
|
||||
document.body.style.overflow = 'hidden';
|
||||
} else {
|
||||
document.body.style.overflow = 'visible';
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const close = () => {
|
||||
if (props.closeable) {
|
||||
emit('close');
|
||||
}
|
||||
};
|
||||
const id = useId();
|
||||
|
||||
const closeOnEscape = (e: KeyboardEvent) => {
|
||||
if (isLastLayer(id)) {
|
||||
if (e.key === 'Escape' && props.show) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('keydown', closeOnEscape);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('keydown', closeOnEscape);
|
||||
document.body.style.overflow = 'visible';
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.show,
|
||||
(value) => {
|
||||
if (value) {
|
||||
layers.value.push(id);
|
||||
} else {
|
||||
layers.value = layers.value.filter((layer) => layer !== id);
|
||||
}
|
||||
}
|
||||
);
|
||||
const maxWidthClass = computed(() => {
|
||||
return {
|
||||
sm: 'sm:max-w-sm',
|
||||
@@ -76,67 +38,19 @@ const maxWidthClass = computed(() => {
|
||||
'2xl': 'sm:max-w-2xl',
|
||||
}[props.maxWidth];
|
||||
});
|
||||
|
||||
const target = ref();
|
||||
const { activate, deactivate } = useFocusTrap(target, {
|
||||
allowOutsideClick: true,
|
||||
});
|
||||
watch(
|
||||
() => props.show,
|
||||
(value) => {
|
||||
if (value) {
|
||||
nextTick(() => {
|
||||
activate();
|
||||
});
|
||||
} else {
|
||||
nextTick(() => {
|
||||
deactivate();
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<teleport to="body">
|
||||
<transition leave-active-class="duration-200">
|
||||
<div
|
||||
v-show="show"
|
||||
class="fixed inset-0 overflow-y-auto px-4 py-32 sm:px-0 z-50"
|
||||
scroll-region>
|
||||
<transition
|
||||
enter-active-class="ease-out duration-300"
|
||||
enter-from-class="opacity-0"
|
||||
enter-to-class="opacity-100"
|
||||
leave-active-class="ease-in duration-200"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0">
|
||||
<div
|
||||
v-show="show"
|
||||
class="fixed inset-0 transform transition-all backdrop-blur-sm"
|
||||
@click="close">
|
||||
<div
|
||||
class="absolute inset-0 bg-default-background opacity-30" />
|
||||
</div>
|
||||
</transition>
|
||||
<Dialog :open="show" @update:open="close">
|
||||
<DialogContent :class="maxWidthClass">
|
||||
|
||||
<transition
|
||||
enter-active-class="ease-out duration-300"
|
||||
enter-from-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enter-to-class="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave-active-class="ease-in duration-200"
|
||||
leave-from-class="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave-to-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
|
||||
<div
|
||||
v-show="show"
|
||||
ref="target"
|
||||
role="dialog"
|
||||
class="mb-6 bg-default-background border border-card-border rounded-lg shadow-xl transform transition-all sm:w-full sm:mx-auto"
|
||||
:class="maxWidthClass">
|
||||
<slot v-if="show" />
|
||||
</div>
|
||||
</transition>
|
||||
<div>
|
||||
<slot />
|
||||
</div>
|
||||
</transition>
|
||||
</teleport>
|
||||
|
||||
<DialogFooter>
|
||||
<slot name="footer" />
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user