Files
simrsx-fe/app/components/pub/my-ui/modal/dialog.vue

70 lines
1.9 KiB
Vue

<script setup lang="ts">
import { Dialog } from '~/components/pub/ui/dialog'
import DialogContent from '~/components/pub/ui/dialog/DialogContent.vue'
import DialogDescription from '~/components/pub/ui/dialog/DialogDescription.vue'
interface DialogProps {
title: string
titleIcon?: string
titleClass?: string
description?: string
preventOutside?: boolean
open?: boolean
size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'
}
const props = withDefaults(defineProps<DialogProps>(), {
preventOutside: false,
open: false,
size: 'md',
})
const emit = defineEmits<{
'update:open': [value: boolean]
}>()
// Computed untuk menentukan class size berdasarkan prop size
const sizeClass = computed(() => {
const sizeMap = {
sm: 'sm:max-w-[350px]',
md: 'sm:max-w-[425px]',
lg: 'sm:max-w-[720px]',
xl: 'sm:max-w-[960px]',
'2xl': 'sm:max-w-[1200px]',
full: 'sm:max-w-[95vw]',
}
return sizeMap[props.size]
})
// Computed untuk state dialog
const isOpen = computed({
get: () => props.open,
set: (value) => emit('update:open', value),
})
</script>
<template>
<Dialog v-model:open="isOpen">
<DialogContent
:class="sizeClass"
@interact-outside="(e: any) => preventOutside && e.preventDefault()"
@pointer-down-outside="(e: any) => preventOutside && e.preventDefault()"
>
<DialogHeader>
<DialogTitle :class="`text-sm 2xl:text-base font-semibold flex ${titleClass || ''}`">
<div class="me-2 pt-0.5">
<Icon v-if="props.titleIcon" :name="props.titleIcon" :class="`!pt-2`" />
</div>
<div>
{{ props.title }}
</div>
</DialogTitle>
<DialogDescription v-if="props.description">{{ props.description }}</DialogDescription>
</DialogHeader>
<DialogDescription :class="sizeClass">
<slot />
</DialogDescription>
</DialogContent>
</Dialog>
</template>