n8n/packages/editor-ui/src/components/ModalDrawer.vue

105 lines
2 KiB
Vue

<script setup lang="ts">
import { useUIStore } from '@/stores/ui.store';
import { onBeforeUnmount, onMounted } from 'vue';
import type { EventBus } from 'n8n-design-system';
import { ElDrawer } from 'element-plus';
const props = withDefaults(
defineProps<{
name: string;
beforeClose?: Function;
eventBus?: EventBus;
direction: 'ltr' | 'rtl' | 'ttb' | 'btt';
modal?: boolean;
width: string;
wrapperClosable?: boolean;
closeOnClickModal?: boolean;
zIndex?: number;
}>(),
{
modal: true,
wrapperClosable: true,
closeOnClickModal: false,
},
);
const emit = defineEmits<{
enter: [];
}>();
const uiStore = useUIStore();
const handleEnter = () => {
if (uiStore.isModalActiveById[props.name]) {
emit('enter');
}
};
const onWindowKeydown = (event: KeyboardEvent) => {
if (!uiStore.isModalActiveById[props.name]) {
return;
}
if (event && event.keyCode === 13) {
handleEnter();
}
};
const close = async () => {
if (props.beforeClose) {
const shouldClose = await props.beforeClose();
if (shouldClose === false) {
// must be strictly false to stop modal from closing
return;
}
}
uiStore.closeModal(props.name);
};
onMounted(() => {
window.addEventListener('keydown', onWindowKeydown);
props.eventBus?.on('close', close);
const activeElement = document.activeElement as HTMLElement;
if (activeElement) {
activeElement.blur();
}
});
onBeforeUnmount(() => {
props.eventBus?.off('close', close);
window.removeEventListener('keydown', onWindowKeydown);
});
</script>
<template>
<ElDrawer
:direction="direction"
:model-value="uiStore.modalsById[name].open"
:size="width"
:before-close="close"
:modal="modal"
:wrapper-closable="wrapperClosable"
:close-on-click-modal="closeOnClickModal"
:z-index="zIndex"
>
<template #header>
<slot name="header" />
</template>
<span @keydown.stop>
<slot name="content" />
</span>
</ElDrawer>
</template>
<style lang="scss">
.el-drawer__header {
margin: 0;
padding: 30px 30px 0 30px;
}
.el-drawer__body {
overflow: hidden;
}
</style>