{"version":3,"file":"modal.cjs","sources":["../../../common/mixins/modal.js"],"sourcesContent":["const focusableAttrs = ':not(:disabled):not([aria-disabled=\"true\"]):not([role=\"presentation\"])';\nconst tabbableAttrs = `${focusableAttrs}:not([tabindex=\"-1\"])`;\nconst focusableElementsList = `button,[href],input,select,textarea,details,[tabindex]`;\n\n/**\n * This mixin provides the methods to automatically trap tab focus within\n * the component this mixin is on, meaning it is not possible to tab out\n * of the component without dismissing it.\n *\n * Useful for accessibility reasons on things like important actionable alerts.\n *\n * Use focusFirstElement to focus on the first tabbable element within your component, and call\n * focusTrappedTabPress every time tab is pressed to trap tab within this\n * component.\n *\n * Note that focusFirstElement WILL focus elements with tabindex=\"-1\",\n * however focusTrappedTabPress will not.\n * @displayName Modal Mixin\n */\nexport default {\n  methods: {\n    /**\n     * get the first focusable element in your component, includes tabindex=\"-1\".\n     * @param {object} el - optional - ref of dom element to trap focus on.\n     *  will default to the root node of the vue component\n     */\n    async getFirstFocusableElement (el) {\n      await this.$nextTick();\n      const focusableElements = this._getFocusableElements(el, true);\n      return this._getFirstFocusElement(focusableElements);\n    },\n\n    /**\n     * set focus to the first focusable element in your component, includes tabindex=\"-1\".\n     * @param {object} el - optional - ref of dom element to trap focus on.\n     *  will default to the root node of the vue component\n     */\n    async focusFirstElement (el = this.$el) {\n      const elToFocus = await this.getFirstFocusableElement(el);\n      elToFocus?.focus({ preventScroll: true });\n    },\n\n    async focusElementById (elementId) {\n      await this.$nextTick();\n      const result = this.$el?.querySelector(elementId);\n      if (result) {\n        result.focus();\n        return;\n      }\n\n      // eslint-disable-next-line no-console\n      console.warn('Could not find the element specified in dt-modal prop \"initialFocusElement\". ' +\n        'Defaulting to focusing the first element.');\n      await this.focusFirstElement();\n    },\n\n    /**\n     * internal use only.\n     *\n     * @param focusableElements - list of focusable elements\n     * @returns {*} - first DOM element that is focusable.\n     * @private\n     */\n    _getFirstFocusElement (focusableElements) {\n      if (!focusableElements.length) {\n        return;\n      }\n      let firstFocusEl = focusableElements[0];\n      // If first element is a checkbox, put focus on the selected checkbox or the first checkbox if none are selected.\n      if (firstFocusEl.matches('[type=\"radio\"]:not(:checked)')) {\n        firstFocusEl = focusableElements.find(el => el.checked && el.name === firstFocusEl.name) || firstFocusEl;\n      }\n      return firstFocusEl;\n    },\n\n    /**\n     * internal use only.\n     *\n     * gets all the focusable elements within the component\n     * and sets the first and last of those elements.\n     *\n     * @param {object} el - the root dom element to find focusable elements in.\n     * @param {bool} includeNegativeTabIndex - will include tabindex=\"-1\" in the list of focusable elements.\n     */\n    _getFocusableElements (el = this.$el, includeNegativeTabIndex = false) {\n      if (!el) return [];\n      const focusableContent = [...el.querySelectorAll(focusableElementsList)];\n      return focusableContent.filter((fc) => {\n        const style = window.getComputedStyle(fc);\n        return style.getPropertyValue('display') !== 'none' &&\n          style.getPropertyValue('visibility') !== 'hidden' &&\n          fc.matches(includeNegativeTabIndex ? focusableAttrs : tabbableAttrs);\n      });\n    },\n\n    /**\n     * tabs to the next element contained within your component, does not include tabindex=\"-1\".\n     * @param {object} e - keypress event\n     * @param {object} el - optional - ref of dom element to trap focus on.\n     *  will default to the root node of the vue component\n     */\n    focusTrappedTabPress (e, el) {\n      const isTabPressed = e.key === 'Tab';\n\n      if (!isTabPressed) {\n        return;\n      }\n\n      const focusableElements = this._getFocusableElements(el);\n      if (!focusableElements.length) {\n        e.preventDefault();\n        return;\n      }\n\n      const firstFocusableElement = this._getFirstFocusElement(focusableElements);\n      const lastFocusableElement = focusableElements[focusableElements.length - 1];\n\n      if (e.shiftKey) {\n        if (document.activeElement === firstFocusableElement) {\n          lastFocusableElement.focus();\n          e.preventDefault();\n        }\n      } else {\n        if (document.activeElement === lastFocusableElement) {\n          firstFocusableElement.focus();\n          e.preventDefault();\n        }\n      }\n    },\n  },\n};\n"],"names":[],"mappings":";;AAAA,MAAM,iBAAiB;AACvB,MAAM,gBAAgB,GAAG,cAAc;AACvC,MAAM,wBAAwB;AAiB9B,MAAe,QAAA;AAAA,EACb,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMP,MAAM,yBAA0B,IAAI;AAClC,YAAM,KAAK;AACX,YAAM,oBAAoB,KAAK,sBAAsB,IAAI,IAAI;AAC7D,aAAO,KAAK,sBAAsB,iBAAiB;AAAA,IACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOD,MAAM,kBAAmB,KAAK,KAAK,KAAK;AACtC,YAAM,YAAY,MAAM,KAAK,yBAAyB,EAAE;AACxD,6CAAW,MAAM,EAAE,eAAe,KAAM;AAAA,IACzC;AAAA,IAED,MAAM,iBAAkB,WAAW;;AACjC,YAAM,KAAK;AACX,YAAM,UAAS,UAAK,QAAL,mBAAU,cAAc;AACvC,UAAI,QAAQ;AACV,eAAO,MAAK;AACZ;AAAA,MACD;AAGD,cAAQ,KAAK,wHACgC;AAC7C,YAAM,KAAK;IACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASD,sBAAuB,mBAAmB;AACxC,UAAI,CAAC,kBAAkB,QAAQ;AAC7B;AAAA,MACD;AACD,UAAI,eAAe,kBAAkB,CAAC;AAEtC,UAAI,aAAa,QAAQ,8BAA8B,GAAG;AACxD,uBAAe,kBAAkB,KAAK,QAAM,GAAG,WAAW,GAAG,SAAS,aAAa,IAAI,KAAK;AAAA,MAC7F;AACD,aAAO;AAAA,IACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWD,sBAAuB,KAAK,KAAK,KAAK,0BAA0B,OAAO;AACrE,UAAI,CAAC,GAAI,QAAO;AAChB,YAAM,mBAAmB,CAAC,GAAG,GAAG,iBAAiB,qBAAqB,CAAC;AACvE,aAAO,iBAAiB,OAAO,CAAC,OAAO;AACrC,cAAM,QAAQ,OAAO,iBAAiB,EAAE;AACxC,eAAO,MAAM,iBAAiB,SAAS,MAAM,UAC3C,MAAM,iBAAiB,YAAY,MAAM,YACzC,GAAG,QAAQ,0BAA0B,iBAAiB,aAAa;AAAA,MAC7E,CAAO;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQD,qBAAsB,GAAG,IAAI;AAC3B,YAAM,eAAe,EAAE,QAAQ;AAE/B,UAAI,CAAC,cAAc;AACjB;AAAA,MACD;AAED,YAAM,oBAAoB,KAAK,sBAAsB,EAAE;AACvD,UAAI,CAAC,kBAAkB,QAAQ;AAC7B,UAAE,eAAc;AAChB;AAAA,MACD;AAED,YAAM,wBAAwB,KAAK,sBAAsB,iBAAiB;AAC1E,YAAM,uBAAuB,kBAAkB,kBAAkB,SAAS,CAAC;AAE3E,UAAI,EAAE,UAAU;AACd,YAAI,SAAS,kBAAkB,uBAAuB;AACpD,+BAAqB,MAAK;AAC1B,YAAE,eAAc;AAAA,QACjB;AAAA,MACT,OAAa;AACL,YAAI,SAAS,kBAAkB,sBAAsB;AACnD,gCAAsB,MAAK;AAC3B,YAAE,eAAc;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACH;;"}