96 lines
3.1 KiB
Vue
96 lines
3.1 KiB
Vue
<script setup lang="ts">
|
|
// types
|
|
|
|
type Props = {
|
|
modelValue: boolean;
|
|
icon?: string;
|
|
title: string;
|
|
iconSize?: string;
|
|
contectClass?: string;
|
|
};
|
|
|
|
type Emits = {
|
|
"update:modelValue": [value: boolean];
|
|
close: [value: null];
|
|
};
|
|
|
|
// props
|
|
|
|
const props = defineProps<Props>();
|
|
|
|
const { modelValue } = toRefs(props);
|
|
|
|
// emit
|
|
|
|
const emit = defineEmits<Emits>();
|
|
|
|
// computed
|
|
|
|
const isShow = computed({
|
|
get: () => modelValue.value ?? false,
|
|
set: (value) => {
|
|
emit("update:modelValue", value);
|
|
if (!value) {
|
|
emit("close", null);
|
|
}
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<DialogRoot
|
|
v-model:open="isShow"
|
|
@update:open="(state) => (isShow = state)"
|
|
>
|
|
<DialogTrigger :class="!$slots['trigger'] ? 'hidden' : ''">
|
|
<slot name="trigger" />
|
|
</DialogTrigger>
|
|
<DialogPortal>
|
|
<DialogOverlay
|
|
class="bg-black/50 backdrop-blur-sm data-[state=open]:animate-overlay-show fixed inset-0 z-999"
|
|
/>
|
|
|
|
<DialogContent
|
|
class="fixed inset-0 z-9999 flex items-start justify-center overflow-y-auto overscroll-contain data-[state=open]:animate-content-show focus:outline-none"
|
|
style="touch-action: pan-y"
|
|
>
|
|
<div
|
|
:class="contectClass"
|
|
class="relative w-fit max-w-[50rem] my-auto py-10"
|
|
>
|
|
<div
|
|
class="rounded-2xl bg-white text-black font-iran-yekan-x shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px]"
|
|
>
|
|
<div
|
|
class="w-full flex items-center px-6 justify-between py-[1.5rem] border-b border-slate-200"
|
|
>
|
|
<DialogClose
|
|
class="inline-flex size-8 items-center justify-center transition-all rounded-full bg-gray-50 border border-slate-200 hover:border-black focus:outline-none"
|
|
aria-label="Close"
|
|
>
|
|
<Icon
|
|
name="ci:bi-x-lg"
|
|
class="**:fill-black"
|
|
/>
|
|
</DialogClose>
|
|
<DialogTitle class="typo-sub-h-md lg:typo-sub-h-xl font-semibold flex items-center gap-3">
|
|
{{ title }}
|
|
<Icon
|
|
v-if="!!icon"
|
|
:name="icon"
|
|
:size="iconSize"
|
|
/>
|
|
</DialogTitle>
|
|
</div>
|
|
<div class="w-full px-6">
|
|
<slot name="content" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
</DialogPortal>
|
|
</DialogRoot>
|
|
</template>
|
|
|
|
<style scoped></style>
|