@empathyco/x-components
Version:
Empathy X Components
91 lines (88 loc) • 3.55 kB
JavaScript
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