138 lines
3.3 KiB
Vue
138 lines
3.3 KiB
Vue
<script setup lang="ts">
|
|
import Dialog from 'primevue/dialog';
|
|
import type IVModal from './IVModal.type';
|
|
import { useId, computed, watch, ref } from 'vue';
|
|
import VButtonGroup from '../button/VButtonGroup.vue';
|
|
import VButton from '../button/VButton.vue';
|
|
import styles from '@visua/typography.module.css';
|
|
|
|
const props = withDefaults(defineProps<IVModal>(), {
|
|
modalId: () => useId(),
|
|
actions: () => [],
|
|
icon: undefined,
|
|
size: 'md',
|
|
closeButtonLabel: 'Fermer',
|
|
closeButtonTitle: 'Fermer la fenêtre modale',
|
|
title: undefined,
|
|
visible: false,
|
|
isAlert: false,
|
|
breakpoints: undefined,
|
|
modal: true,
|
|
dismissableMask: false,
|
|
blockScroll: true,
|
|
position: 'center',
|
|
maximizable: false,
|
|
draggable: true,
|
|
showHeader: true,
|
|
closeOnEscape: true,
|
|
})
|
|
|
|
const role = computed(() => {
|
|
return props.isAlert ? 'alertdialog' : 'dialog'
|
|
})
|
|
|
|
const modalSize = computed(() => {
|
|
switch (props.size) {
|
|
case 'lg':
|
|
return `width: 49.5rem;`
|
|
case 'md':
|
|
return `width: 36.75rem;`
|
|
case 'sm':
|
|
return `width: 24rem;`
|
|
default:
|
|
return `width: 36.75rem;`
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits([
|
|
'update:visible',
|
|
'hide',
|
|
'after-hide',
|
|
'show',
|
|
'maximize',
|
|
'unmaximize',
|
|
'dragstart',
|
|
'dragend'
|
|
]);
|
|
|
|
const localVisible = ref(props.visible);
|
|
watch(() => props.visible, (newVal) => {
|
|
if(localVisible.value !== newVal){
|
|
localVisible.value = newVal;
|
|
}
|
|
})
|
|
watch(localVisible, (newVal) => {
|
|
if(props.visible !== newVal){
|
|
emit('update:visible', newVal);
|
|
}
|
|
});
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<Dialog
|
|
:header="props.title"
|
|
id="modal"
|
|
:modal="props.modal"
|
|
:dismissable-mask="props.dismissableMask"
|
|
:role="role"
|
|
:aria-model="true"
|
|
:aria-labelledby="`modal-${props.modalId}-dialog`"
|
|
ref="modal"
|
|
:style="modalSize"
|
|
: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>
|
|
<slot name="header" v-if="props.icon !== undefined">
|
|
<span :class="[styles['titles-H6-XXS']]">
|
|
<i :class="props.icon"></i>
|
|
{{ props.title }}
|
|
</span>
|
|
</slot>
|
|
</template>
|
|
<slot name="content"/>
|
|
<template #footer>
|
|
<slot name="footer">
|
|
<VButtonGroup
|
|
v-if="props.actions?.length"
|
|
inline-layout-when="always"
|
|
align="right"
|
|
:buttons="props.actions"
|
|
size="sm"
|
|
title="groupe de boutons"
|
|
/>
|
|
</slot>
|
|
</template>
|
|
<template #closebutton="{closeCallback}">
|
|
<VButton
|
|
tertiary
|
|
noOutline
|
|
size="sm"
|
|
icon="ri-close-line"
|
|
iconRight
|
|
@click="closeCallback"
|
|
:label="closeButtonLabel"
|
|
:title="closeButtonTitle"
|
|
ref="closeBtn"
|
|
aria-controls="modal-1"
|
|
type="button"
|
|
/>
|
|
</template>
|
|
</Dialog>
|
|
</template>
|