import { TOOLTIP_DELAY_MS as o, TOOLTIP_KIND_MODIFIERS as s, TOOLTIP_STICKY_VALUES as a, TOOLTIP_DIRECTIONS as h } from "./tooltip-constants.js";
import { POPOVER_APPEND_TO_VALUES as l } from "../popover/popover-constants.js";
import { flushPromises as d, getUniqueString as c } from "../../common/utils/index.js";
import { getPopperOptions as r, createTippy as u, getAnchor as p } from "../popover/tippy-utils.js";
import { n as f } from "../../_plugin-vue2_normalizer-DSLOjnn3.js";
const m = {
  name: "DtTooltip",
  props: {
    /**
     * The id of the tooltip
     */
    id: {
      type: String,
      default() {
        return c();
      }
    },
    /**
     * If the popover does not fit in the direction described by "placement",
     * it will attempt to change its direction to the "fallbackPlacements"
     * if defined, otherwise it will automatically position to a new location
     * as it sees best fit. See
     * <a
     *   class="d-link"
     *   href="https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements"
     *   target="_blank"
     * >
     *   Popper.js docs
     * </a>
     * */
    fallbackPlacements: {
      type: Array,
      default: () => ["auto"]
    },
    /**
     * If true, applies inverted styles to the tooltip
     * @values true, false
     */
    inverted: {
      type: Boolean,
      default: !1
    },
    /**
     *  Displaces the tooltip from its reference element
     *  by the specified number of pixels. See
     *  <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, 12]
    },
    /**
     * The direction the popover displays relative to the anchor. See
     * <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: "top",
      validator(t) {
        return h.includes(t);
      }
    },
    /**
     * If the tooltip 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. See
     * <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: !0,
      validator: (t) => a.includes(t)
    },
    /**
     * Sets the element to which the tooltip is going to append to.
     * 'body' will append to the nearest body (supports shadow DOM).
     * This prop is not reactive, must be set on initial render.
     * @values 'body', 'parent', HTMLElement,
     */
    appendTo: {
      type: [HTMLElement, String],
      default: "body",
      validator: (t) => l.includes(t) || t instanceof HTMLElement
    },
    /**
     * Additional css classes for the tooltip content element.
     * Can accept all of String, Object, and Array, i.e. has the
     * same api as Vue's built-in handling of the class attribute.
     */
    contentClass: {
      type: [String, Object, Array],
      default: ""
    },
    /**
     * A provided message for the tooltip content
     */
    message: {
      type: String,
      default: ""
    },
    /**
     * Controls whether hover/focus causes the tooltip to appear.
     * Cannot be combined with the show prop. show value will be ignored.
     * by default this is true, if you override with false, the tooltip will never show up.
     */
    enabled: {
      type: Boolean,
      default: !0
    },
    /**
     * Controls whether the tooltip is shown. Leaving this null will have the tooltip trigger on mouseover by default.
     * If you set this value, the default mouseover behavior will be disabled and you can control it as you need.
     * Supports .sync modifier
     * @values null, true, false
     */
    show: {
      type: Boolean,
      default: null
    },
    /**
     * Whether the tooltip should have a transition effect (fade).
     */
    transition: {
      type: Boolean,
      default: !0
    },
    /**
     * Whether the tooltip will have a delay when being focused or moused over.
     * @values true, false
     */
    delay: {
      type: Boolean,
      default: !0
    },
    /**
     * Set a custom theme on the tooltip. See https://atomiks.github.io/tippyjs/v6/themes/
     */
    theme: {
      type: String,
      default: null
    },
    /**
     * 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: null
    }
  },
  emits: [
    /**
     * Emitted when tooltip is shown or hidden
     *
     * @event shown
     * @type {Boolean}
     */
    "shown",
    /**
     * Sync show value
     *
     * @event update:show
     */
    "update:show"
  ],
  data() {
    return {
      TOOLTIP_KIND_MODIFIERS: s,
      tip: null,
      inTimer: null,
      // Internal state for whether the tooltip is shown. Changing the prop
      // will update this.
      internalShow: !1,
      // this is where the placement currently is, this can be different than
      // the placement prop when there is not enough available room for the tip
      // to display and it uses a fallback placement.
      currentPlacement: this.placement
    };
  },
  computed: {
    tippyProps() {
      return {
        offset: this.offset,
        delay: this.delay ? o : !1,
        placement: this.placement,
        sticky: this.sticky,
        theme: this.inverted ? "inverted" : this.theme,
        animation: this.transition ? "fade" : !1,
        // onShown only triggers when transition is truthy
        onShown: (t) => this.onShow(t, "onShown"),
        // onShown will always be called, but it will be called before the animation is complete
        onShow: (t) => this.onShow(t, "onShow"),
        onHidden: this.onHide,
        popperOptions: r({
          fallbackPlacements: this.fallbackPlacements,
          hasHideModifierEnabled: !0
        })
      };
    },
    anchor() {
      return this.externalAnchor ? document.body.querySelector(this.externalAnchor) : p(this.$refs.anchor);
    }
  },
  watch: {
    tippyProps: {
      handler: "setProps",
      deep: !0
    },
    show: {
      handler: function(t) {
        t !== null && this.enabled && (this.internalShow = t);
      },
      immediate: !0
    },
    internalShow(t) {
      !this.tip || !this.anchor || (t ? (this.setProps(), this.tip.show()) : this.tip.hide());
    },
    sticky(t) {
      this.tip.setProps({
        sticky: t
      });
    }
  },
  async mounted() {
    !this.enabled && this.show != null && (console.warn("Tooltip: You cannot use both the enabled and show props at the same time."), console.warn("The show prop will be ignored.")), this.tip = u(this.anchor, this.initOptions()), this.externalAnchor && (await d(), this.addExternalAnchorEventListeners());
  },
  beforeDestroy() {
    var t, e;
    this.externalAnchor && this.removeExternalAnchorEventListeners(), (t = this.anchor) != null && t._tippy && ((e = this.tip) == null || e.destroy());
  },
  methods: {
    calculateAnchorZindex() {
      return this.$el.getRootNode().querySelector(
        `.d-modal[aria-hidden="false"],
          .d-modal--transparent[aria-hidden="false"],
          .d-modal:not([aria-hidden]),
          .d-modal--transparent:not([aria-hidden])`
      ) || // Special case because we don't have any dialtone drawer component yet. Render at 651 when
      // anchor of popover is within a drawer.
      this.$el.closest(".d-zi-drawer") ? 651 : 400;
    },
    hasVisibleFocus() {
      return this.anchor.matches(":focus-visible");
    },
    onEnterAnchor(t) {
      this.enabled && (this.delay && this.inTimer === null ? this.inTimer = setTimeout(() => {
        this.triggerShow(t);
      }, o) : this.triggerShow(t));
    },
    triggerShow(t) {
      t.type === "focusin" ? this.show === null && this.hasVisibleFocus() && (this.internalShow = !0) : this.show === null && (this.internalShow = !0);
    },
    onLeaveAnchor(t) {
      t.type === "keydown" && t.code !== "Escape" || (clearTimeout(this.inTimer), this.inTimer = null, this.triggerHide());
    },
    triggerHide() {
      this.show === null && (this.internalShow = !1);
    },
    onChangePlacement(t) {
      this.currentPlacement = t;
    },
    onHide() {
      var t;
      (t = this.tip) == null || t.unmount(), this.$emit("shown", !1), this.show !== null && this.$emit("update:show", !1);
    },
    onShow(t, e) {
      if (!this.tooltipHasContent(t))
        return !1;
      this.transition && e === "onShow" || (this.$emit("shown", !0), this.show !== null && this.$emit("update:show", !0));
    },
    setProps() {
      var t, e;
      !this.tip || !this.tip.setProps || !this.anchor || this.tip && this.tip.setProps && this.tip.setProps({
        ...this.tippyProps,
        // these need to be set here rather than in tippyProps because they are non-reactive
        appendTo: this.appendTo === "body" ? (e = (t = this.anchor) == null ? void 0 : t.getRootNode()) == null ? void 0 : e.querySelector("body") : this.appendTo,
        zIndex: this.calculateAnchorZindex()
      });
    },
    onMount() {
      this.setProps();
    },
    tooltipHasContent(t) {
      return t.props.content.textContent.trim().length !== 0;
    },
    // set initial options here. If any of the options need to dynamically change, they should be put in
    // tippyProps instead.
    initOptions() {
      return {
        content: this.$refs.content,
        arrow: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="7"><path d="M 14.5,7 8,0 1.5,7 Z"/></svg>',
        // transition duration - same as our custom fade delay in dialtone-globals.less
        duration: 180,
        interactive: !1,
        trigger: "manual",
        hideOnClick: !1,
        // disable tooltip from displaying on touch devices
        touch: !1,
        onMount: this.onMount,
        showOnCreate: this.internalShow,
        popperOptions: r({
          hasHideModifierEnabled: !0
        })
      };
    },
    addExternalAnchorEventListeners() {
      ["focusin", "mouseenter"].forEach((t) => {
        var e;
        (e = this.anchor) == null || e.addEventListener(t, (n) => this.onEnterAnchor(n));
      }), ["focusout", "mouseleave", "keydown"].forEach((t) => {
        var e;
        (e = this.anchor) == null || e.addEventListener(t, (n) => this.onLeaveAnchor(n));
      });
    },
    removeExternalAnchorEventListeners() {
      ["focusin", "mouseenter"].forEach((t) => {
        var e;
        (e = this.anchor) == null || e.removeEventListener(t, (n) => this.onEnterAnchor(n));
      }), ["focusout", "mouseleave", "keydown"].forEach((t) => {
        var e;
        (e = this.anchor) == null || e.removeEventListener(t, (n) => this.onLeaveAnchor(n));
      });
    }
  }
};
var y = function() {
  var e = this, n = e._self._c;
  return n("div", { attrs: { "data-qa": "dt-tooltip-container" } }, [e.externalAnchor ? e._e() : n("span", { ref: "anchor", attrs: { "data-qa": "dt-tooltip-anchor" }, on: { focusin: e.onEnterAnchor, focusout: e.onLeaveAnchor, mouseenter: e.onEnterAnchor, mouseleave: e.onLeaveAnchor, keydown: function(i) {
    return !i.type.indexOf("key") && e._k(i.keyCode, "esc", 27, i.key, ["Esc", "Escape"]) ? null : e.onLeaveAnchor.apply(null, arguments);
  } } }, [e._t("anchor")], 2), n("div", e._g({ ref: "content", class: [
    // eslint-disable-next-line vue/no-restricted-class
    "d-tooltip",
    {
      [e.TOOLTIP_KIND_MODIFIERS.inverted]: e.inverted
    },
    e.contentClass
  ], attrs: { id: e.id, "data-qa": "dt-tooltip" } }, e.$listeners), [e._t("default", function() {
    return [e._v(" " + e._s(e.message) + " ")];
  })], 2)]);
}, w = [], v = /* @__PURE__ */ f(
  m,
  y,
  w
);
const T = v.exports;
export {
  T as default
};
//# sourceMappingURL=tooltip.js.map
