♻️ refactor: modal component improved

This commit is contained in:
Paul Valerie GOMA 2025-07-28 00:58:31 +02:00
parent 80dc6e4161
commit 24ea6cb51b

View File

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import Dialog from 'primevue/dialog'; import Dialog from 'primevue/dialog';
import type IVModal from './IVModal.type'; import type IVModal from './IVModal.type';
import { useId, computed } from 'vue'; import { useId, computed, watch, ref } from 'vue';
import VButtonGroup from '../button/VButtonGroup.vue'; import VButtonGroup from '../button/VButtonGroup.vue';
import VButton from '../button/VButton.vue'; import VButton from '../button/VButton.vue';
import styles from '@visua/typography.module.css'; import styles from '@visua/typography.module.css';
@ -14,9 +14,17 @@ const props = withDefaults(defineProps<IVModal>(), {
closeButtonLabel: 'Fermer', closeButtonLabel: 'Fermer',
closeButtonTitle: 'Fermer la fenêtre modale', closeButtonTitle: 'Fermer la fenêtre modale',
title: undefined, title: undefined,
opened: false, visible: false,
isAlert: false, isAlert: false,
breakpoints: undefined, breakpoints: undefined,
modal: true,
dismissableMask: false,
blockScroll: true,
position: 'center',
maximizable: false,
draggable: true,
showHeader: true,
closeOnEscape: true,
}) })
const role = computed(() => { const role = computed(() => {
@ -36,12 +44,28 @@ const modalSize = computed(() => {
} }
}) })
const emit = defineEmits(['update:opened']) const emit = defineEmits([
'update:visible',
'hide',
'after-hide',
'show',
'maximize',
'unmaximize',
'dragstart',
'dragend'
]);
const visible = computed({ const localVisible = ref(props.visible);
get: () => props.opened, watch(() => props.visible, (newVal) => {
set: (value: boolean) => emit('update:opened', value), if(localVisible.value !== newVal){
localVisible.value = newVal;
}
}) })
watch(localVisible, (newVal) => {
if(props.visible !== newVal){
emit('update:visible', newVal);
}
});
</script> </script>
@ -49,14 +73,29 @@ const visible = computed({
<Dialog <Dialog
:header="props.title" :header="props.title"
id="modal" id="modal"
modal :modal="props.modal"
v-model:visible="visible" :dismissable-mask="props.dismissableMask"
:role="role" :role="role"
:aria-model="true" :aria-model="true"
:aria-labelledby="`modal-${props.modalId}-dialog`" :aria-labelledby="`modal-${props.modalId}-dialog`"
ref="modal" ref="modal"
:style="modalSize" :style="modalSize"
:breakpoints="props.breakpoints" :breakpoints="props.breakpoints"
:block-scroll="props.blockScroll"
:position="props.position"
:maximizable="props.maximizable"
:draggable="props.draggable"
:show-header="props.showHeader"
:close-on-escape="props.closeOnEscape"
v-model:visible="localVisible"
@update:visible="emit('update:visible', $event)"
@after-hide="emit('after-hide', $event)"
@dragend="emit('dragend', $event)"
@dragstart="emit('dragstart', $event)"
@hide="emit('hide', $event)"
@maximize="emit('maximize', $event)"
@unmaximize="emit('unmaximize', $event)"
@show="emit('show', $event)"
> >
<template #header> <template #header>
<slot name="header" v-if="props.icon !== undefined"> <slot name="header" v-if="props.icon !== undefined">