Files
hossein-por-shop/frontend/components/global/Modal.vue
T
2025-03-09 20:37:50 +03:30

108 lines
3.4 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 = ref(modelValue.value);
watch(
() => isShow.value,
(nv) => {
if (!nv) {
emit("update:modelValue", false);
emit("close", null);
}
}
);
</script>
<template>
<DialogRoot
v-model:open="isShow"
@update:open="
(state) => {
!state ? (isShow = false) : null;
}
"
>
<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"
/>
<div
class="fixed inset-0 w-full h-svh z-9999 flex-center"
v-if="isShow"
>
<div
:class="contectClass"
class="overflow-y-auto max-h-svh absolute left-[50%] py-10 w-fit max-w-[50rem] translate-x-[-50%]"
>
<DialogContent
class="data-[state=open]:animate-content-show text-black font-iran-yekan-x focus:outline-none z-[100]"
>
<div
class="rounded-2xl bg-white 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="bi:x-lg"
class="**:fill-black"
/>
</DialogClose>
<DialogTitle
class="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>
</DialogContent>
</div>
</div>
</DialogPortal>
</DialogRoot>
</template>
<style scoped></style>