{"version":3,"file":"alert.mjs","sources":["../../../../src/moj/components/alert/alert.mjs"],"sourcesContent":["import { ConfigurableComponent } from 'govuk-frontend'\n\nimport { setFocus } from '../../common/index.mjs'\nimport {\n  findNearestMatchingElement,\n  getPreviousSibling\n} from '../../helpers.mjs'\n\n/**\n * @augments {ConfigurableComponent<AlertConfig>}\n */\nexport class Alert extends ConfigurableComponent {\n  /**\n   * @param {Element | null} $root - HTML element to use for alert\n   * @param {AlertConfig} [config] - Alert config\n   */\n  constructor($root, config = {}) {\n    super($root, config)\n\n    /**\n     * Focus the alert\n     *\n     * If `role=\"alert\"` is set, focus the element to help some assistive\n     * technologies prioritise announcing it.\n     *\n     * You can turn off the auto-focus functionality by setting\n     * `data-disable-auto-focus=\"true\"` in the component HTML. You might wish to\n     * do this based on user research findings, or to avoid a clash with another\n     * element which should be focused when the page loads.\n     */\n    if (\n      this.$root.getAttribute('role') === 'alert' &&\n      !this.config.disableAutoFocus\n    ) {\n      setFocus(this.$root)\n    }\n\n    this.$dismissButton = this.$root.querySelector('.moj-alert__dismiss')\n\n    if (this.config.dismissible && this.$dismissButton) {\n      this.$dismissButton.innerHTML = this.config.dismissText\n      this.$dismissButton.removeAttribute('hidden')\n\n      this.$root.addEventListener('click', (event) => {\n        if (\n          event.target instanceof Node &&\n          this.$dismissButton.contains(event.target)\n        ) {\n          this.dimiss()\n        }\n      })\n    }\n  }\n\n  /**\n   * Handle dismissing the alert\n   */\n  dimiss() {\n    let $elementToRecieveFocus\n\n    // If a selector has been provided, attempt to find that element\n    if (this.config.focusOnDismissSelector) {\n      $elementToRecieveFocus = document.querySelector(\n        this.config.focusOnDismissSelector\n      )\n    }\n\n    // Is the next sibling another alert\n    if (!$elementToRecieveFocus) {\n      const $nextSibling = this.$root.nextElementSibling\n      if ($nextSibling && $nextSibling.matches('.moj-alert')) {\n        $elementToRecieveFocus = $nextSibling\n      }\n    }\n\n    // Else try to find any preceding sibling alert or heading\n    if (!$elementToRecieveFocus) {\n      $elementToRecieveFocus = getPreviousSibling(\n        this.$root,\n        '.moj-alert, h1, h2, h3, h4, h5, h6'\n      )\n    }\n\n    // Else find the closest ancestor heading, or fallback to main, or last resort\n    // use the body element\n    if (!$elementToRecieveFocus) {\n      $elementToRecieveFocus = findNearestMatchingElement(\n        this.$root,\n        'h1, h2, h3, h4, h5, h6, main, body'\n      )\n    }\n\n    // If we have an element, place focus on it\n    if ($elementToRecieveFocus instanceof HTMLElement) {\n      setFocus($elementToRecieveFocus)\n    }\n\n    // Remove the alert\n    this.$root.remove()\n  }\n\n  /**\n   * Name for the component used when initialising using data-module attributes.\n   */\n  static moduleName = 'moj-alert'\n\n  /**\n   * Alert default config\n   *\n   * @type {AlertConfig}\n   */\n  static defaults = Object.freeze({\n    dismissible: false,\n    dismissText: 'Dismiss',\n    disableAutoFocus: false\n  })\n\n  /**\n   * Alert config schema\n   *\n   * @satisfies {Schema<AlertConfig>}\n   */\n  static schema = Object.freeze(\n    /** @type {const} */ ({\n      properties: {\n        dismissible: { type: 'boolean' },\n        dismissText: { type: 'string' },\n        disableAutoFocus: { type: 'boolean' },\n        focusOnDismissSelector: { type: 'string' }\n      }\n    })\n  )\n}\n\n/**\n * @typedef {object} AlertConfig\n * @property {boolean} [dismissible=false] - Can the alert be dismissed by the user\n * @property {string} [dismissText=Dismiss] - the label text for the dismiss button\n * @property {boolean} [disableAutoFocus=false] - whether the alert will be autofocused\n * @property {string} [focusOnDismissSelector] - CSS Selector for element to be focused on dismiss\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n"],"names":["Alert","ConfigurableComponent","constructor","$root","config","getAttribute","disableAutoFocus","setFocus","$dismissButton","querySelector","dismissible","innerHTML","dismissText","removeAttribute","addEventListener","event","target","Node","contains","dimiss","$elementToRecieveFocus","focusOnDismissSelector","document","$nextSibling","nextElementSibling","matches","getPreviousSibling","findNearestMatchingElement","HTMLElement","remove","moduleName","defaults","Object","freeze","schema","properties","type"],"mappings":";;;;AAQA;AACA;AACA;AACO,MAAMA,KAAK,SAASC,qBAAqB,CAAC;AAC/C;AACF;AACA;AACA;AACEC,EAAAA,WAAWA,CAACC,KAAK,EAAEC,MAAM,GAAG,EAAE,EAAE;AAC9B,IAAA,KAAK,CAACD,KAAK,EAAEC,MAAM,CAAC;;AAEpB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACI,IAAA,IACE,IAAI,CAACD,KAAK,CAACE,YAAY,CAAC,MAAM,CAAC,KAAK,OAAO,IAC3C,CAAC,IAAI,CAACD,MAAM,CAACE,gBAAgB,EAC7B;AACAC,MAAAA,QAAQ,CAAC,IAAI,CAACJ,KAAK,CAAC;AACtB,IAAA;IAEA,IAAI,CAACK,cAAc,GAAG,IAAI,CAACL,KAAK,CAACM,aAAa,CAAC,qBAAqB,CAAC;IAErE,IAAI,IAAI,CAACL,MAAM,CAACM,WAAW,IAAI,IAAI,CAACF,cAAc,EAAE;MAClD,IAAI,CAACA,cAAc,CAACG,SAAS,GAAG,IAAI,CAACP,MAAM,CAACQ,WAAW;AACvD,MAAA,IAAI,CAACJ,cAAc,CAACK,eAAe,CAAC,QAAQ,CAAC;MAE7C,IAAI,CAACV,KAAK,CAACW,gBAAgB,CAAC,OAAO,EAAGC,KAAK,IAAK;AAC9C,QAAA,IACEA,KAAK,CAACC,MAAM,YAAYC,IAAI,IAC5B,IAAI,CAACT,cAAc,CAACU,QAAQ,CAACH,KAAK,CAACC,MAAM,CAAC,EAC1C;UACA,IAAI,CAACG,MAAM,EAAE;AACf,QAAA;AACF,MAAA,CAAC,CAAC;AACJ,IAAA;AACF,EAAA;;AAEA;AACF;AACA;AACEA,EAAAA,MAAMA,GAAG;AACP,IAAA,IAAIC,sBAAsB;;AAE1B;AACA,IAAA,IAAI,IAAI,CAAChB,MAAM,CAACiB,sBAAsB,EAAE;MACtCD,sBAAsB,GAAGE,QAAQ,CAACb,aAAa,CAC7C,IAAI,CAACL,MAAM,CAACiB,sBACd,CAAC;AACH,IAAA;;AAEA;IACA,IAAI,CAACD,sBAAsB,EAAE;AAC3B,MAAA,MAAMG,YAAY,GAAG,IAAI,CAACpB,KAAK,CAACqB,kBAAkB;MAClD,IAAID,YAAY,IAAIA,YAAY,CAACE,OAAO,CAAC,YAAY,CAAC,EAAE;AACtDL,QAAAA,sBAAsB,GAAGG,YAAY;AACvC,MAAA;AACF,IAAA;;AAEA;IACA,IAAI,CAACH,sBAAsB,EAAE;MAC3BA,sBAAsB,GAAGM,kBAAkB,CACzC,IAAI,CAACvB,KAAK,EACV,oCACF,CAAC;AACH,IAAA;;AAEA;AACA;IACA,IAAI,CAACiB,sBAAsB,EAAE;MAC3BA,sBAAsB,GAAGO,0BAA0B,CACjD,IAAI,CAACxB,KAAK,EACV,oCACF,CAAC;AACH,IAAA;;AAEA;IACA,IAAIiB,sBAAsB,YAAYQ,WAAW,EAAE;MACjDrB,QAAQ,CAACa,sBAAsB,CAAC;AAClC,IAAA;;AAEA;AACA,IAAA,IAAI,CAACjB,KAAK,CAAC0B,MAAM,EAAE;AACrB,EAAA;;AAEA;AACF;AACA;AA6BA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AArIa7B,KAAK,CA6FT8B,UAAU,GAAG,WAAW;AAE/B;AACF;AACA;AACA;AACA;AAnGa9B,KAAK,CAoGT+B,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAAC;AAC9BvB,EAAAA,WAAW,EAAE,KAAK;AAClBE,EAAAA,WAAW,EAAE,SAAS;AACtBN,EAAAA,gBAAgB,EAAE;AACpB,CAAC,CAAC;AAEF;AACF;AACA;AACA;AACA;AA9GaN,KAAK,CA+GTkC,MAAM,GAAGF,MAAM,CAACC,MAAM,qBACL;AACpBE,EAAAA,UAAU,EAAE;AACVzB,IAAAA,WAAW,EAAE;AAAE0B,MAAAA,IAAI,EAAE;KAAW;AAChCxB,IAAAA,WAAW,EAAE;AAAEwB,MAAAA,IAAI,EAAE;KAAU;AAC/B9B,IAAAA,gBAAgB,EAAE;AAAE8B,MAAAA,IAAI,EAAE;KAAW;AACrCf,IAAAA,sBAAsB,EAAE;AAAEe,MAAAA,IAAI,EAAE;AAAS;AAC3C;AACF,CACF,CAAC;;;;"}