UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

952 lines (951 loc) 33.2 kB
import { POPOVER_ROLES, POPOVER_PADDING_CLASSES, POPOVER_CONTENT_WIDTHS, POPOVER_STICKY_VALUES, POPOVER_INITIAL_FOCUS_STRINGS, POPOVER_APPEND_TO_VALUES, POPOVER_HEADER_FOOTER_PADDING_CLASSES } from "./popover_constants.js"; import { getUniqueString, hasSlotContent, warnIfUnmounted, returnFirstEl, isOutOfViewPort, disableRootScrolling, enableRootScrolling } from "../../common/utils.js"; import Modal from "../../common/mixins/modal.js"; import { getPopperOptions, createTippyPopover } from "./tippy_utils.js"; import PopoverHeaderFooter from "./popover_header_footer.vue.js"; import SrOnlyCloseButtonMixin from "../../common/mixins/sr_only_close_button.js"; import SrOnlyCloseButton from "../../common/sr_only_close_button.vue.js"; import { resolveComponent, openBlock, createElementBlock, createBlock, Teleport, createElementVNode, withModifiers, createCommentVNode, resolveDynamicComponent, normalizeClass, withCtx, withKeys, renderSlot, createVNode, mergeProps, toHandlers } from "vue"; import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js"; import DtLazyShow from "../lazy_show/lazy_show.vue.js"; const _sfc_main = { compatConfig: { MODE: 3 }, name: "DtPopover", /******************** * CHILD COMPONENTS * ********************/ components: { SrOnlyCloseButton, DtLazyShow, PopoverHeaderFooter }, mixins: [Modal, SrOnlyCloseButtonMixin], props: { /** * Controls whether the popover is shown. Leaving this null will have the popover trigger on click by default. * If you set this value, the default trigger behavior will be disabled, and you can control it as you need. * Supports v-model * @values null, true, false */ open: { type: Boolean, default: null }, /** * Opens the popover on right click (context menu). If you set this value to `true`, * the default trigger behavior will be disabled. * @values true, false */ openOnContext: { type: Boolean, default: false }, /** * Element type (tag name) of the root element of the component. */ elementType: { type: String, default: "div" }, /** * Named transition when the content display is toggled. * @see DtLazyShow */ transition: { type: String, default: "fade" }, /** * ARIA role for the content of the popover. Defaults to "dialog". * <a class="d-link" href="https://www.w3.org/TR/wai-aria/#aria-haspopup" target="_blank">aria-haspopup</a> */ role: { type: String, default: "dialog", validator: (role) => { return POPOVER_ROLES.includes(role); } }, /** * ID of the element that serves as the label for the popover content. * Defaults to the "anchor" element; this exists to provide a different * ID of the label element if, for example, the anchor slot contains * other items that do not serve as a label. You should provide this * or ariaLabel, but not both. */ ariaLabelledby: { type: String, default: null }, /** * Descriptive label for the popover content. You should provide this * or ariaLabelledby, but not both. */ ariaLabel: { type: String, default: null }, /** * A set of props to be passed into the popover's header close button. * Requires an 'ariaLabel' property, when the header popover is visible */ closeButtonProps: { type: Object, default: () => ({}) }, /** * Padding size class for the popover content. * @values none, small, medium, large */ padding: { type: String, default: "large", validator: (padding) => { return Object.keys(POPOVER_PADDING_CLASSES).some((item) => item === padding); } }, /** * Additional class name for the content wrapper element. */ contentClass: { type: [String, Array, Object], default: "" }, /** * Width configuration for the popover content. When its value is 'anchor', * the popover content will have the same width as the anchor. * @values null, anchor */ contentWidth: { type: String, default: "", validator: (contentWidth) => POPOVER_CONTENT_WIDTHS.includes(contentWidth) }, /** * Whether to apply transition on initial render in the content lazy show component. */ contentAppear: { type: Boolean, default: null }, /** * Tabindex value for the content. Passing null, no tabindex attribute will be set. */ contentTabindex: { type: Number || null, default: -1 }, /** * External anchor id to use in those cases the anchor can't be provided via the slot. * For instance, using the combobox's input as the anchor for the popover. */ externalAnchor: { type: String, default: "" }, /** * The id of the tooltip */ id: { type: String, default() { return getUniqueString(); } }, /** * Displaces the content box from its anchor element * by the specified number of pixels. * <a * class="d-link" * href="https://atomiks.github.io/tippyjs/v6/all-props/#offset" * target="_blank" * > * Tippy.js docs * </a> */ offset: { type: Array, default: () => [0, 4] }, /** * Determines if the popover hides upon clicking the * anchor or outside the content box. * @values true, false */ hideOnClick: { type: Boolean, default: true }, /** * Determines modal state. If enabled popover has a modal overlay * preventing interaction with elements below it, but it is invisible. * @values true, false */ modal: { type: Boolean, default: true }, /** * If the popover does not fit in the direction described by "placement", * it will attempt to change its direction to the "fallbackPlacements". * <a * class="d-link" * href="https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements" * target="_blank" * > * Popper.js docs * </a> * */ fallbackPlacements: { type: Array, default: () => { return ["auto"]; } }, /** * The direction the popover displays relative to the anchor. * <a * class="d-link" * href="https://atomiks.github.io/tippyjs/v6/all-props/#placement" * target="_blank" * > * Tippy.js docs * </a> * @values top, top-start, top-end, * right, right-start, right-end, * left, left-start, left-end, * bottom, bottom-start, bottom-end, * auto, auto-start, auto-end */ placement: { type: String, default: "bottom-end" }, /** * If set to false the dialog will display over top of the anchor when there is insufficient space. * If set to true it will never move from its position relative to the anchor and will clip instead. * <a * class="d-link" * href="https://popper.js.org/docs/v2/modifiers/prevent-overflow/#tether" * target="_blank" * > * Popper.js docs * </a> * @values true, false */ tether: { type: Boolean, default: true }, /** * If the popover sticks to the anchor. This is usually not needed, but can be needed * if the reference element's position is animating, or to automatically update the popover * position in those cases the DOM layout changes the reference element's position. * `true` enables it, `reference` only checks the "reference" rect for changes and `popper` only * checks the "popper" rect for changes. * <a * class="d-link" * href="https://atomiks.github.io/tippyjs/v6/all-props/#sticky" * target="_blank" * > * Tippy.js docs * </a> * @values true, false, reference, popper */ sticky: { type: [Boolean, String], default: false, validator: (sticky) => { return POPOVER_STICKY_VALUES.includes(sticky); } }, /** * Determines maximum height for the popover before overflow. * Possible units rem|px|em */ maxHeight: { type: String, default: "" }, /** * Determines maximum width for the popover before overflow. * Possible units rem|px|%|em */ maxWidth: { type: String, default: "" }, /** * Determines visibility for close button * @values true, false */ showCloseButton: { type: Boolean, default: false }, /** * Additional class name for the header content wrapper element. */ headerClass: { type: [String, Array, Object], default: "" }, /** * Additional class name for the footer content wrapper element. */ footerClass: { type: [String, Array, Object], default: "" }, /** * Additional class name for the dialog element. */ dialogClass: { type: [String, Array, Object], default: "" }, /** * The element that is focused when the popover is opened. This can be an * HTMLElement within the popover, a string starting with '#' which will * find the element by ID. 'first' which will automatically focus * the first element, or 'dialog' which will focus the dialog window itself. * If the dialog is modal this prop cannot be 'none'. * @values none, dialog, first */ initialFocusElement: { type: [String, HTMLElement], default: "first", validator: (initialFocusElement) => { return POPOVER_INITIAL_FOCUS_STRINGS.includes(initialFocusElement) || initialFocusElement instanceof HTMLElement || initialFocusElement.startsWith("#"); } }, /** * If the popover should open pressing up or down arrow key on the anchor element. * This can be set when not passing open prop. * @values true, false */ openWithArrowKeys: { type: Boolean, default: false }, /** * Sets the element to which the popover is going to append to. * 'body' will append to the nearest body (supports shadow DOM). * 'root' will try append to the iFrame's parent body if it is contained in an iFrame * and has permissions to access it, else, it'd default to 'parent'. * @values 'body', 'parent', 'root', HTMLElement */ appendTo: { type: [HTMLElement, String], default: "body", validator: (appendTo) => { return POPOVER_APPEND_TO_VALUES.includes(appendTo) || appendTo instanceof HTMLElement; } } }, emits: [ /** * Native keydown event * * @event keydown * @type {KeyboardEvent} */ "keydown", /** * Event fired to sync the open prop with the parent component * @event update:open */ "update:open", /** * Emitted when popover is shown or hidden * * @event opened * @type {Boolean | Array} */ "opened", /** * Emitted when the mouse enters the popover * * @event mouseenter-popover */ "mouseenter-popover", /** * Emitted when the mouse leaves the popover * * @event mouseleave-popover */ "mouseleave-popover", /** * Emitted when the mouse enters the popover anchor * * @event mouseenter-popover-anchor */ "mouseenter-popover-anchor", /** * Emitted when the mouse leaves the popover anchor * * @event mouseleave-popover-anchor */ "mouseleave-popover-anchor" ], data() { return { POPOVER_PADDING_CLASSES, POPOVER_HEADER_FOOTER_PADDING_CLASSES, intersectionObserver: null, isOutsideViewport: false, isOpen: false, toAppear: false, anchorEl: null, popoverContentEl: null, hasSlotContent }; }, computed: { popoverListeners() { return { keydown: (event) => { this.onKeydown(event); }, "after-leave": (event) => { this.onLeaveTransitionComplete(); }, "after-enter": (event) => { this.onEnterTransitionComplete(); } }; }, calculatedMaxHeight() { if (this.isOutsideViewport && this.modal) { return `calc(100vh - var(--dt-space-300))`; } return this.maxHeight; }, labelledBy() { return this.ariaLabelledby || !this.ariaLabel && getUniqueString("DtPopover__anchor"); } }, watch: { $props: { immediate: true, deep: true, handler() { this.validateProps(); } }, modal(modal) { var _a; (_a = this.tip) == null ? void 0 : _a.setProps({ zIndex: modal ? 650 : this.calculateAnchorZindex() }); }, offset(offset) { var _a; (_a = this.tip) == null ? void 0 : _a.setProps({ offset }); }, sticky(sticky) { var _a; (_a = this.tip) == null ? void 0 : _a.setProps({ sticky }); }, fallbackPlacements() { var _a; (_a = this.tip) == null ? void 0 : _a.setProps({ popperOptions: this.popperOptions() }); }, tether() { var _a; (_a = this.tip) == null ? void 0 : _a.setProps({ popperOptions: this.popperOptions() }); }, placement(placement) { var _a; (_a = this.tip) == null ? void 0 : _a.setProps({ placement }); }, open: { handler: function(open) { if (open !== null) { this.isOpen = open; } if (open === true) { this.toAppear = true; } }, immediate: true }, contentAppear: { handler: function(contentAppear) { if (contentAppear !== null) { this.toAppear = contentAppear; } } }, isOpen(isOpen, isPrev) { if (isOpen) { this.initTippyInstance(); this.tip.show(); } else if (!isOpen && isPrev !== isOpen) { this.removeEventListeners(); this.tip.hide(); } } }, mounted() { var _a; warnIfUnmounted(returnFirstEl(this.$el), this.$options.name); const externalAnchorEl = this.externalAnchor ? this.$refs.anchor.getRootNode().querySelector(`#${this.externalAnchor}`) : null; this.anchorEl = externalAnchorEl ?? this.$refs.anchor.children[0]; this.popoverContentEl = returnFirstEl((_a = this.$refs.content) == null ? void 0 : _a.$el); if (this.isOpen) { this.initTippyInstance(); this.tip.show(); } this.intersectionObserver = new IntersectionObserver(this.hasIntersectedViewport); this.intersectionObserver.observe(this.popoverContentEl); }, beforeUnmount() { var _a, _b; (_a = this.tip) == null ? void 0 : _a.destroy(); (_b = this.intersectionObserver) == null ? void 0 : _b.disconnect(); this.removeReferences(); this.removeEventListeners(); }, /****************** * METHODS * ******************/ methods: { hasIntersectedViewport(entries) { var _a; const dialog = (_a = entries == null ? void 0 : entries[0]) == null ? void 0 : _a.target; if (!dialog) return; const isOut = isOutOfViewPort(dialog); this.isOutsideViewport = isOut.bottom || isOut.top; }, popperOptions() { return getPopperOptions({ fallbackPlacements: this.fallbackPlacements, tether: this.tether, hasHideModifierEnabled: true }); }, validateProps() { if (this.modal && this.initialFocusElement === "none") { console.error('If the popover is modal you must set the initialFocusElement prop. Possible values: "dialog", "first", HTMLElement'); } }, calculateAnchorZindex() { var _a; if (returnFirstEl(this.$el).getRootNode().querySelector('.d-modal[aria-hidden="false"], .d-modal--transparent[aria-hidden="false"]') || // Special case because we don't have any dialtone drawer component yet. Render at 650 when // anchor of popover is within a drawer. ((_a = this.anchorEl) == null ? void 0 : _a.closest(".d-zi-drawer"))) { return 650; } else { return 300; } }, defaultToggleOpen(e) { var _a, _b, _c; if (this.openOnContext) { return; } if (this.open === null || this.open === void 0) { if (!((_a = this.anchorEl) == null ? void 0 : _a.contains(e.target)) && !((_b = this.anchorEl) == null ? void 0 : _b.isEqualNode(e.target)) || ((_c = this.anchorEl) == null ? void 0 : _c.disabled)) { return; } this.toggleOpen(); } }, async onContext(event) { if (!this.openOnContext) { return; } event.preventDefault(); this.isOpen = true; await this.$nextTick(); this.tip.setProps({ placement: "right-start", getReferenceClientRect: () => ({ width: 0, height: 0, top: event.clientY, bottom: event.clientY, left: event.clientX, right: event.clientX }) }); }, toggleOpen() { this.isOpen = !this.isOpen; }, onArrowKeyPress(e) { var _a; if (this.open !== null) { return; } if (this.openWithArrowKeys && ((_a = this.anchorEl) == null ? void 0 : _a.contains(e.target))) { if (!this.isOpen) { this.isOpen = true; } } this.$emit("keydown", e); }, addEventListeners() { window.addEventListener("dt-popover-close", this.closePopover); if (this.contentWidth === "anchor") { window.addEventListener("resize", this.onResize); } }, removeEventListeners() { window.removeEventListener("dt-popover-close", this.closePopover); if (this.contentWidth === "anchor") { window.removeEventListener("resize", this.onResize); } }, closePopover() { this.isOpen = false; }, /* * Prevents scrolling outside of the currently opened modal popover by: * - when anchor is not within another popover: setting the body to overflow: hidden * - when anchor is within another popover: set the popover dialog container to it's non-modal z-index * since it is no longer the active modal. This puts it underneath the overlay and prevents scrolling. **/ preventScrolling() { var _a, _b; if (this.modal) { const element = (_a = this.anchorEl) == null ? void 0 : _a.closest("body, .tippy-box"); if (!element) return; if (((_b = element.tagName) == null ? void 0 : _b.toLowerCase()) === "body") { disableRootScrolling(this.anchorEl.getRootNode().host); this.tip.setProps({ offset: this.offset }); } else { element.classList.add("d-zi-popover"); } } }, /* * Resets the prevent scrolling properties set in preventScrolling() back to normal. **/ enableScrolling() { var _a, _b; const element = (_a = this.anchorEl) == null ? void 0 : _a.closest("body, .tippy-box"); if (!element) return; if (((_b = element.tagName) == null ? void 0 : _b.toLowerCase()) === "body") { enableRootScrolling(this.anchorEl.getRootNode().host); this.tip.setProps({ offset: this.offset }); } else { element.classList.remove("d-zi-popover"); } }, removeReferences() { this.anchorEl = null; this.popoverContentEl = null; this.tip = null; }, async onShow() { if (this.contentWidth === "anchor") { await this.setPopoverContentAnchorWidth(); } if (this.contentWidth === null) { this.popoverContentEl.style.width = "auto"; } this.addEventListeners(); }, async onLeaveTransitionComplete() { var _a; if (this.modal) { await this.focusFirstElement(this.$refs.anchor); await this.$nextTick(); this.enableScrolling(); } (_a = this.tip) == null ? void 0 : _a.unmount(); this.$emit("opened", false); if (this.open !== null) { this.$emit("update:open", false); } }, async onEnterTransitionComplete() { this.focusInitialElement(); await this.$nextTick(); this.preventScrolling(); this.$emit("opened", true, this.$refs.popover__content); if (this.open !== null) { this.$emit("update:open", true); } }, focusInitialElement() { var _a, _b; if (this.initialFocusElement === "dialog") { (_b = returnFirstEl((_a = this.$refs.content) == null ? void 0 : _a.$el)) == null ? void 0 : _b.focus(); } if (this.initialFocusElement.startsWith("#")) { this.focusInitialElementById(); } if (this.initialFocusElement === "first") { this.focusFirstElementIfNeeded(this.$refs.popover__content); } if (this.initialFocusElement instanceof HTMLElement) { this.initialFocusElement.focus(); } }, focusInitialElementById() { var _a, _b, _c; const result = (_b = returnFirstEl((_a = this.$refs.content) == null ? void 0 : _a.$el)) == null ? void 0 : _b.querySelector(this.initialFocusElement); if (result) { result.focus(); } else { console.warn('Could not find the element specified in dt-popover prop "initialFocusElement". Defaulting to focusing the dialog.'); } result ? result.focus() : returnFirstEl((_c = this.$refs.content) == null ? void 0 : _c.$el).focus(); }, onResize() { this.closePopover(); }, onClickOutside() { var _a; if (!this.hideOnClick) return; const innerModals = (_a = this.popoverContentEl) == null ? void 0 : _a.querySelector(".d-popover__anchor--opened"); if (!innerModals) { this.closePopover(); } }, onKeydown(e) { if (e.key === "Tab") { if (this.modal) { this.focusTrappedTabPress(e, this.popoverContentEl); } } if (e.key === "Escape") { this.closePopover(); } this.$emit("keydown", e); }, async setPopoverContentAnchorWidth() { var _a; await this.$nextTick(); this.popoverContentEl.style.width = `${(_a = this.anchorEl) == null ? void 0 : _a.clientWidth}px`; }, focusFirstElementIfNeeded(domEl) { var _a, _b; const focusableElements = this._getFocusableElements(domEl, true); if (focusableElements.length !== 0) { this.focusFirstElement(domEl); } else if (this.showCloseButton) { (_a = this.$refs.popover__header) == null ? void 0 : _a.focusCloseButton(); } else { returnFirstEl((_b = this.$refs.content) == null ? void 0 : _b.$el).focus(); } }, /** * Return's the anchor ClientRect object relative to the window. * Refer to: https://atomiks.github.io/tippyjs/v6/all-props/#getreferenceclientrect for more information * @param error */ getReferenceClientRect(error) { var _a, _b; const anchorReferenceRect = (_a = this.anchorEl) == null ? void 0 : _a.getBoundingClientRect(); if (this.appendTo !== "root" || error) return anchorReferenceRect; const anchorOwnerDocument = (_b = this.anchorEl) == null ? void 0 : _b.ownerDocument; const anchorParentWindow = (anchorOwnerDocument == null ? void 0 : anchorOwnerDocument.defaultView) || (anchorOwnerDocument == null ? void 0 : anchorOwnerDocument.parentWindow); const anchorIframe = anchorParentWindow == null ? void 0 : anchorParentWindow.frameElement; if (!anchorIframe) return anchorReferenceRect; const iframeReferenceRect = anchorIframe.getBoundingClientRect(); return { width: anchorReferenceRect == null ? void 0 : anchorReferenceRect.width, height: anchorReferenceRect == null ? void 0 : anchorReferenceRect.height, top: (iframeReferenceRect == null ? void 0 : iframeReferenceRect.top) + (anchorReferenceRect == null ? void 0 : anchorReferenceRect.top), left: (iframeReferenceRect == null ? void 0 : iframeReferenceRect.left) + (anchorReferenceRect == null ? void 0 : anchorReferenceRect.left), right: (iframeReferenceRect == null ? void 0 : iframeReferenceRect.right) + (anchorReferenceRect == null ? void 0 : anchorReferenceRect.right), bottom: (iframeReferenceRect == null ? void 0 : iframeReferenceRect.bottom) + (anchorReferenceRect == null ? void 0 : anchorReferenceRect.bottom) }; }, initTippyInstance() { var _a, _b; let internalAppendTo = null; let iFrameError = false; switch (this.appendTo) { case "body": internalAppendTo = (_b = (_a = this.anchorEl) == null ? void 0 : _a.getRootNode()) == null ? void 0 : _b.querySelector("body"); break; case "root": try { internalAppendTo = window.parent.document.body; } catch (err) { console.error("Could not attach the popover to iframe parent window: ", err); internalAppendTo = "parent"; iFrameError = true; } break; default: internalAppendTo = this.appendTo; break; } this.tip = createTippyPopover(this.anchorEl, { popperOptions: this.popperOptions(), contentElement: this.popoverContentEl, placement: this.placement, offset: this.offset, sticky: this.sticky, appendTo: internalAppendTo, interactive: true, trigger: "manual", getReferenceClientRect: () => this.getReferenceClientRect(iFrameError), // We have to manage hideOnClick functionality manually to handle // popover within popover situations. hideOnClick: false, zIndex: this.modal ? 650 : this.calculateAnchorZindex(), onClickOutside: this.onClickOutside, onShow: this.onShow }); }, onMouseEnter() { this.$emit("mouseenter-popover"); }, onMouseLeave() { this.$emit("mouseleave-popover"); }, onMouseEnterAnchor() { this.$emit("mouseenter-popover-anchor"); }, onMouseLeaveAnchor() { this.$emit("mouseleave-popover-anchor"); } } }; const _hoisted_1 = ["aria-hidden"]; const _hoisted_2 = ["id", "data-qa", "tabindex"]; const _hoisted_3 = ["data-qa"]; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_popover_header_footer = resolveComponent("popover-header-footer"); const _component_sr_only_close_button = resolveComponent("sr-only-close-button"); const _component_dt_lazy_show = resolveComponent("dt-lazy-show"); return openBlock(), createElementBlock("div", null, [ $props.modal && $data.isOpen ? (openBlock(), createBlock(Teleport, { key: 0, to: "body" }, [ createElementVNode("div", { class: "d-modal--transparent", "aria-hidden": $props.modal && $data.isOpen ? "false" : "true", onClick: _cache[0] || (_cache[0] = withModifiers(() => { }, ["prevent", "stop"])) }, null, 8, _hoisted_1) ])) : createCommentVNode("", true), (openBlock(), createBlock(resolveDynamicComponent($props.elementType), { ref: "popover", class: normalizeClass(["d-popover", { "d-popover__anchor--opened": $data.isOpen }]), "data-qa": "dt-popover-container" }, { default: withCtx(() => [ createElementVNode("div", { id: !$props.ariaLabelledby && $options.labelledBy, ref: "anchor", "data-qa": _ctx.$attrs["data-qa"] ? `${_ctx.$attrs["data-qa"]}-anchor` : "dt-popover-anchor", tabindex: $props.openOnContext ? 0 : void 0, onClickCapture: _cache[1] || (_cache[1] = (...args) => $options.defaultToggleOpen && $options.defaultToggleOpen(...args)), onContextmenu: _cache[2] || (_cache[2] = (...args) => $options.onContext && $options.onContext(...args)), onKeydown: [ _cache[3] || (_cache[3] = withKeys(withModifiers((...args) => $options.onArrowKeyPress && $options.onArrowKeyPress(...args), ["prevent"]), ["up"])), _cache[4] || (_cache[4] = withKeys(withModifiers((...args) => $options.onArrowKeyPress && $options.onArrowKeyPress(...args), ["prevent"]), ["down"])), _cache[6] || (_cache[6] = withKeys(($event) => _ctx.$emit("keydown", $event), ["enter"])), _cache[7] || (_cache[7] = withKeys(($event) => _ctx.$emit("keydown", $event), ["space"])) ], onKeydownCapture: _cache[5] || (_cache[5] = withKeys((...args) => $options.closePopover && $options.closePopover(...args), ["escape"])), onMouseenter: _cache[8] || (_cache[8] = (...args) => $options.onMouseEnter && $options.onMouseEnter(...args)), onMouseleave: _cache[9] || (_cache[9] = (...args) => $options.onMouseLeave && $options.onMouseLeave(...args)) }, [ renderSlot(_ctx.$slots, "anchor", { attrs: { "aria-expanded": $data.isOpen.toString(), "aria-controls": $props.id, "aria-haspopup": $props.role } }) ], 40, _hoisted_2), createVNode(_component_dt_lazy_show, mergeProps({ id: $props.id, ref: "content", role: $props.role, "data-qa": _ctx.$attrs["data-qa"] ? `${_ctx.$attrs["data-qa"]}__dialog` : "dt-popover", "aria-hidden": `${!$data.isOpen}`, "aria-labelledby": $options.labelledBy, "aria-label": $props.ariaLabel, "aria-modal": `${!$props.modal}`, transition: $props.transition, show: $data.isOpen, appear: $data.toAppear, class: ["d-popover__dialog", { "d-popover__dialog--modal": $props.modal }, $props.dialogClass], style: { "max-height": $options.calculatedMaxHeight, "max-width": $props.maxWidth }, css: _ctx.$attrs.css, tabindex: $props.contentTabindex }, toHandlers($options.popoverListeners), { onMouseenter: $options.onMouseEnterAnchor, onMouseleave: $options.onMouseLeaveAnchor }), { default: withCtx(() => [ $data.hasSlotContent(_ctx.$slots.headerContent) || $props.showCloseButton ? (openBlock(), createBlock(_component_popover_header_footer, { key: 0, ref: "popover__header", class: normalizeClass($data.POPOVER_HEADER_FOOTER_PADDING_CLASSES[$props.padding]), "content-class": $props.headerClass, type: "header", "show-close-button": $props.showCloseButton, "close-button-props": $props.closeButtonProps, onClose: $options.closePopover }, { content: withCtx(() => [ renderSlot(_ctx.$slots, "headerContent", { close: $options.closePopover }) ]), _: 3 }, 8, ["class", "content-class", "show-close-button", "close-button-props", "onClose"])) : createCommentVNode("", true), createElementVNode("div", { ref: "popover__content", "data-qa": _ctx.$attrs["data-qa"] ? `${_ctx.$attrs["data-qa"]}-content` : "dt-popover-content", class: normalizeClass([ "d-popover__content", $data.POPOVER_PADDING_CLASSES[$props.padding], $props.contentClass ]) }, [ renderSlot(_ctx.$slots, "content", { close: $options.closePopover }) ], 10, _hoisted_3), $data.hasSlotContent(_ctx.$slots.footerContent) ? (openBlock(), createBlock(_component_popover_header_footer, { key: 1, ref: "popover__footer", type: "footer", class: normalizeClass($data.POPOVER_HEADER_FOOTER_PADDING_CLASSES[$props.padding]), "content-class": $props.footerClass }, { content: withCtx(() => [ renderSlot(_ctx.$slots, "footerContent", { close: $options.closePopover }) ]), _: 3 }, 8, ["class", "content-class"])) : createCommentVNode("", true), _ctx.showVisuallyHiddenClose ? (openBlock(), createBlock(_component_sr_only_close_button, { key: 2, "visually-hidden-close-label": _ctx.visuallyHiddenCloseLabel, onClose: $options.closePopover }, null, 8, ["visually-hidden-close-label", "onClose"])) : createCommentVNode("", true) ]), _: 3 }, 16, ["id", "role", "data-qa", "aria-hidden", "aria-labelledby", "aria-label", "aria-modal", "transition", "show", "appear", "class", "style", "css", "tabindex", "onMouseenter", "onMouseleave"]) ]), _: 3 }, 8, ["class"])) ]); } const DtPopover = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { DtPopover as default }; //# sourceMappingURL=popover.vue.js.map