UNPKG

@empathyco/x-components

Version:
91 lines (88 loc) 3.55 kB
import { defineComponent, ref } from 'vue'; import { use$x } from '../../composables/use-_x.js'; import { AnimationProp } from '../../types/animation-prop.js'; import { isElementEqualOrContained, getTargetElement } from '../../utils/html.js'; import BaseModal from './base-modal.vue.js'; /** * Component containing a modal that emits a {@link XEventsTypes.UserClickedCloseEventsModal} when * clicking outside the content rendered in the default slot and can receive, through the * eventsToCloseModal prop, a list of {@link XEvent} to listen to in order to close * also the modal, eventsToOpenModal prop, another list of {@link XEvent} to customize * the events to listen to open the modal and a prop, displayOverlay, to display an * overlay over the rest of the html. The default slot offers the possibility to customize the * modal content. * * @public */ var _sfc_main = defineComponent({ name: 'BaseEventsModal', components: { BaseModal, }, props: { /** Array of {@link XEvent} to listen to open the modal. */ eventsToOpenModal: { type: Array, default: () => ['UserClickedOpenEventsModal'], }, /** Array of {@link XEvent} to listen to close the modal. */ eventsToCloseModal: { type: Array, default: () => ['UserClickedCloseEventsModal', 'UserClickedOutOfEventsModal'], }, /** Event to emit when any part of the website out of the modal has been clicked. */ bodyClickEvent: { type: String, default: 'UserClickedOutOfEventsModal', }, /** Animation to use for opening/closing the modal. */ animation: AnimationProp, }, setup(props) { const $x = use$x(); /** Whether the modal is open or not. */ const isOpen = ref(false); /** The element that opened the modal. */ const openerElement = ref(); const baseModalEl = ref(); /** * Opens the modal. * * @param _payload - The payload of the event that opened the modal. * @param metadata - The metadata of the event that opened the modal. */ props.eventsToOpenModal?.forEach(event => $x.on(event, true).subscribe(({ metadata }) => { if (!isOpen.value) { openerElement.value = metadata.target; isOpen.value = true; } })); /** Closes the modal. */ props.eventsToCloseModal?.forEach(event => $x.on(event, false).subscribe(() => { if (isOpen.value) { isOpen.value = false; } })); /** * Emits the event defined in the {@link BaseEventsModal.bodyClickEvent} event unless the passed * event target is the button that opened the modal. * * @param event - The event that triggered the close attempt. */ const emitBodyClickEvent = (event) => { // Prevents clicking the open button when the panel is already open to close the panel. if (!openerElement.value || !isElementEqualOrContained(openerElement.value, getTargetElement(event))) { $x.emit(props.bodyClickEvent, undefined, { target: baseModalEl.value }); } }; return { isOpen, openerElement, baseModalEl, emitBodyClickEvent, }; }, }); export { _sfc_main as default }; //# sourceMappingURL=base-events-modal.vue2.js.map