Files
hossein-por-shop/frontend/components/global/Modal.vue
T

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>