{"version":3,"file":"hovercard.cjs","names":["$emit"],"sources":["../../../components/hovercard/hovercard.vue"],"sourcesContent":["<!-- eslint-disable vue/multi-word-component-names -->\n<template>\n  <dt-popover\n    :id=\"id\"\n    ref=\"popover\"\n    :open=\"hovercardOpen\"\n    :placement=\"placement\"\n    :content-class=\"contentClass\"\n    :dialog-class=\"dialogClass\"\n    :fallback-placements=\"fallbackPlacements\"\n    :padding=\"padding\"\n    :transition=\"transition ? 'fade' : null\"\n    :offset=\"offset\"\n    :modal=\"false\"\n    initial-focus-element=\"none\"\n    :header-class=\"headerClass\"\n    :footer-class=\"footerClass\"\n    :append-to=\"appendTo\"\n    :external-anchor-element=\"externalAnchorElement\"\n    data-qa=\"dt-hovercard\"\n    :enter-delay=\"enterDelay\"\n    :leave-delay=\"leaveDelay\"\n    @opened=\"(e) => ($emit('opened', e))\"\n    @mouseenter-popover=\"onMouseEnter\"\n    @mouseleave-popover=\"onMouseLeave\"\n    @mouseenter-popover-anchor=\"onMouseEnter\"\n    @mouseleave-popover-anchor=\"onMouseLeave\"\n  >\n    <template #anchor=\"{ attrs }\">\n      <!-- @slot Anchor element that activates the hovercard. Usually a button. -->\n      <slot\n        name=\"anchor\"\n        v-bind=\"attrs\"\n      />\n    </template>\n    <template #content>\n      <div\n        @focusin=\"onContentFocusIn\"\n        @focusout=\"onContentFocusOut\"\n      >\n        <!-- @slot Slot for the content that is displayed in the hovercard. -->\n        <slot name=\"content\" />\n      </div>\n    </template>\n    <template #headerContent>\n      <!-- @slot Slot for hovercard header content -->\n      <slot name=\"headerContent\" />\n    </template>\n\n    <template #footerContent>\n      <!-- @slot Slot for the footer content. -->\n      <slot name=\"footerContent\" />\n    </template>\n  </dt-popover>\n</template>\n\n<script setup>\nimport { ref, watch, nextTick, onMounted, onBeforeUnmount } from 'vue';\nimport { POPOVER_APPEND_TO_VALUES, POPOVER_PADDING_CLASSES, DtPopover } from '@/components/popover/index.js';\nimport { TOOLTIP_DIRECTIONS, TOOLTIP_DELAY_MS } from '@/components/tooltip/index.js';\nimport { getUniqueString } from '@/common/utils';\n\nconst props = defineProps({\n  /**\n     * Fade transition when the content display is toggled.\n     * @type boolean\n     * @values true, false\n     */\n  transition: {\n    type: Boolean,\n    default: false,\n  },\n\n  /**\n     * Controls whether the hovercard is shown. Leaving this null will have the hovercard trigger on hover by default.\n     * If you set this value, the default trigger behavior will be disabled, and you can control it as you need.\n     * Supports .sync modifier\n     * @values null, true, false\n     */\n  open: {\n    type: Boolean,\n    default: null,\n  },\n\n  /**\n      * If the popover does not fit in the direction described by \"placement\",\n     * it will attempt to change its direction to the \"fallbackPlacements\".\n     * @see https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements\"\n     */\n  fallbackPlacements: {\n    type: Array,\n    default: () => {\n      return ['auto'];\n    },\n  },\n\n  /**\n     * The direction the popover displays relative to the anchor.\n     * @see https://atomiks.github.io/tippyjs/v6/all-props/#placement\"\n     * @values top, top-start, top-end,\n     * right, right-start, right-end,\n     * left, left-start, left-end,\n     * bottom, bottom-start, bottom-end,\n     * auto, auto-start, auto-end\n     */\n  placement: {\n    type: String,\n    default: 'top-start',\n    validator (placement) {\n      return TOOLTIP_DIRECTIONS.includes(placement);\n    },\n  },\n\n  /**\n     * Padding size class for the popover content.\n     * @values none, small, medium, large\n     */\n  padding: {\n    type: String,\n    default: 'large',\n    validator: (padding) => {\n      return Object.keys(POPOVER_PADDING_CLASSES).some((item) => item === padding);\n    },\n  },\n\n  /**\n     * Displaces the content box from its anchor element\n     * by the specified number of pixels.\n     * @see https://atomiks.github.io/tippyjs/v6/all-props/#offset\"\n     */\n  offset: {\n    type: Array,\n    default: () => [0, 16],\n  },\n\n  /**\n     * The id of the tooltip\n     */\n  id: {\n    type: String,\n    default () { return getUniqueString(); },\n  },\n\n  /**\n     * Additional class name for the header content wrapper element.\n     */\n  headerClass: {\n    type: [String, Array, Object],\n    default: '',\n  },\n\n  /**\n     * Additional class name for the footer content wrapper element.\n     */\n  footerClass: {\n    type: [String, Array, Object],\n    default: '',\n  },\n\n  /**\n     * Additional class name for the dialog element.\n     */\n  dialogClass: {\n    type: [String, Array, Object],\n    default: '',\n  },\n\n  /**\n     * Additional class name for the content wrapper element.\n     */\n  contentClass: {\n    type: [String, Array, Object],\n    default: '',\n  },\n\n  /**\n     * Sets the element to which the popover is going to append to.\n     * 'body' will append to the nearest body (supports shadow DOM).\n     * @values 'body', 'parent', HTMLElement,\n     */\n  appendTo: {\n    type: [HTMLElement, String],\n    default: 'body',\n    validator: appendTo => {\n      return POPOVER_APPEND_TO_VALUES.includes(appendTo) ||\n            (appendTo instanceof HTMLElement);\n    },\n  },\n\n  /**\n   * The enter delay in milliseconds before the hovercard is shown.\n   * @type number\n   */\n  enterDelay: {\n    type: Number,\n    default: TOOLTIP_DELAY_MS,\n  },\n\n  /**\n   * The leave delay in milliseconds before the hovercard is hidden.\n   * @type number\n   */\n  leaveDelay: {\n    type: Number,\n    default: TOOLTIP_DELAY_MS,\n  },\n\n  /**\n   * External anchor element reference. Use this instead of the anchor slot when\n   * the anchor may be inside a Shadow DOM, as querySelector cannot pierce shadow boundaries.\n   */\n  externalAnchorElement: {\n    type: HTMLElement,\n    default: null,\n  },\n});\n\ndefineEmits([\n  /**\n   * Emitted when hovercard is shown or hidden\n   *\n   * @event opened\n   * @type {Boolean | Array}\n   */\n  'opened',\n]);\n\nconst hovercardOpen = ref(props.open);\nconst contentFocused = ref(false);\nconst mouseOverHovercard = ref(false);\nconst inTimer = ref(null);\nconst outTimer = ref(null);\nconst anchorEl = ref(null);\nconst observer = ref(null);\nconst popover = ref(null);\n\nonMounted(() => {\n  nextTick(() => {\n    anchorEl.value = popover.value?.$refs?.anchor?.firstElementChild;\n\n    observer.value = new MutationObserver(() => {\n      if (anchorEl.value && !anchorEl.value.isConnected) {\n        hovercardOpen.value = false;\n      }\n    });\n\n    observer.value.observe(document.body, {\n      childList: true,\n      subtree: true,\n    });\n  });\n});\n\nonBeforeUnmount(() => {\n  if (observer.value) {\n    observer.value.disconnect();\n  }\n  clearTimeout(inTimer);\n  clearTimeout(outTimer);\n});\n\nwatch(() => props.open, (open) => {\n  hovercardOpen.value = open;\n}, { immediate: true });\n\ndefineExpose({ show: onMouseEnter, hide: onMouseLeave });\n\nfunction setInTimer () {\n  if (props.open === null) {\n    clearTimeout(outTimer.value);\n    inTimer.value = setTimeout(() => {\n      hovercardOpen.value = true;\n    }, props.enterDelay);\n  }\n}\n\nfunction setOutTimer () {\n  if (props.open === null) {\n    clearTimeout(inTimer.value);\n    outTimer.value = setTimeout(() => {\n      hovercardOpen.value = false;\n    }, props.leaveDelay);\n  }\n}\n\nfunction onMouseEnter () {\n  mouseOverHovercard.value = true;\n  setInTimer();\n}\n\nfunction onMouseLeave () {\n  mouseOverHovercard.value = false;\n  if (contentFocused.value) {\n    return;\n  }\n  setOutTimer();\n}\n\nfunction onContentFocusIn () {\n  contentFocused.value = true;\n  setInTimer();\n}\n\nfunction onContentFocusOut () {\n  contentFocused.value = false;\n\n  // If mouse is not over the hovercard, close it\n  if (!mouseOverHovercard.value) {\n    setOutTimer();\n  }\n}\n</script>\n"],"mappings":"swCA8DA,IAAM,EAAQ,EAqKR,GAAA,EAAA,EAAA,KAAoB,EAAM,KAAK,CAC/B,GAAA,EAAA,EAAA,KAAqB,GAAM,CAC3B,GAAA,EAAA,EAAA,KAAyB,GAAM,CAC/B,GAAA,EAAA,EAAA,KAAc,KAAK,CACnB,GAAA,EAAA,EAAA,KAAe,KAAK,CACpB,GAAA,EAAA,EAAA,KAAe,KAAK,CACpB,GAAA,EAAA,EAAA,KAAe,KAAK,CACpB,GAAA,EAAA,EAAA,KAAc,KAAK,EAEzB,EAAA,EAAA,eAAgB,EACd,EAAA,EAAA,cAAe,CACb,EAAS,MAAQ,EAAQ,OAAO,OAAO,QAAQ,kBAE/C,EAAS,MAAQ,IAAI,qBAAuB,CACtC,EAAS,OAAS,CAAC,EAAS,MAAM,cACpC,EAAc,MAAQ,KAExB,CAEF,EAAS,MAAM,QAAQ,SAAS,KAAM,CACpC,UAAW,GACX,QAAS,GACV,CAAC,EACF,EACF,EAEF,EAAA,EAAA,qBAAsB,CAChB,EAAS,OACX,EAAS,MAAM,YAAY,CAE7B,aAAa,EAAQ,CACrB,aAAa,EAAS,EACtB,EAEF,EAAA,EAAA,WAAY,EAAM,KAAO,GAAS,CAChC,EAAc,MAAQ,GACrB,CAAE,UAAW,GAAM,CAAC,CAEvB,EAAa,CAAE,KAAM,EAAc,KAAM,EAAc,CAAC,CAExD,SAAS,GAAc,CACjB,EAAM,OAAS,OACjB,aAAa,EAAS,MAAM,CAC5B,EAAQ,MAAQ,eAAiB,CAC/B,EAAc,MAAQ,IACrB,EAAM,WAAW,EAIxB,SAAS,GAAe,CAClB,EAAM,OAAS,OACjB,aAAa,EAAQ,MAAM,CAC3B,EAAS,MAAQ,eAAiB,CAChC,EAAc,MAAQ,IACrB,EAAM,WAAW,EAIxB,SAAS,GAAgB,CACvB,EAAmB,MAAQ,GAC3B,GAAY,CAGd,SAAS,GAAgB,CACvB,EAAmB,MAAQ,GACvB,GAAe,OAGnB,GAAa,CAGf,SAAS,GAAoB,CAC3B,EAAe,MAAQ,GACvB,GAAY,CAGd,SAAS,GAAqB,CAC5B,EAAe,MAAQ,GAGlB,EAAmB,OACtB,GAAa,+DA/PF,EAAA,QAAA,CAAA,CAlDV,GAAI,EAAA,WACD,UAAJ,IAAI,EACH,KAAM,EAAA,MACN,UAAW,EAAA,UACX,gBAAe,EAAA,aACf,eAAc,EAAA,YACd,sBAAqB,EAAA,mBACrB,QAAS,EAAA,QACT,WAAY,EAAA,WAAU,OAAA,KACtB,OAAQ,EAAA,OACR,MAAO,GACR,wBAAsB,OACrB,eAAc,EAAA,YACd,eAAc,EAAA,YACd,YAAW,EAAA,SACX,0BAAyB,EAAA,sBAC1B,UAAQ,eACP,cAAa,EAAA,WACb,cAAa,EAAA,WACb,SAAM,EAAA,KAAA,EAAA,GAAG,GAAOA,EAAAA,MAAK,SAAW,EAAC,EACjC,oBAAoB,EACpB,oBAAoB,EACpB,0BAA2B,EAC3B,0BAA2B,IAEjB,QAAA,EAAA,EAAA,UAKP,CALiB,WAAK,EAAA,EAAA,EAAA,YAKtB,EAAA,OAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,EAAA,oBADQ,EAAK,CAAA,CAAA,CAAA,CAAA,CAGN,SAAA,EAAA,EAAA,aAOH,EAAA,EAAA,EAAA,oBAAA,MAAA,CALH,UAAS,EACT,WAAU,qBAGY,EAAA,OAAA,UAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAGhB,eAAA,EAAA,EAAA,aAEoB,EAAA,EAAA,EAAA,YAAA,EAAA,OAAA,gBAAA,CAAA,CAAA,CAGpB,eAAA,EAAA,EAAA,aAEoB,EAAA,EAAA,EAAA,YAAA,EAAA,OAAA,gBAAA,CAAA,CAAA"}