{"version":3,"sources":["jsdelivr-header.js","/npm/@aurodesignsystem/auro-library@5.5.3/scripts/runtime/Focusables/Focusables.mjs","/npm/@aurodesignsystem/auro-library@5.5.3/scripts/runtime/FocusTrap/FocusTrap.mjs"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,ACLO,MAAM,EAAsB,CACjC,UACA,yBACA,2BACA,wBACA,yBACA,+BACA,gCACA,kCACA,kCACA,oDAIW,EAAuB,CAClC,gBACA,aACA,gBACA,cACA,gBACA,aACA,eACA,YACA,cACA,kBACA,iBACA,kBAiCK,SAAS,EAAqB,GAEnC,MAAM,EAA2B,GAG3B,EAA4B,IAEhC,GAAI,EAAK,WAAa,KAAK,aAAc,CAIvC,GAlCC,SAA8B,GACnC,MAAM,EAAgB,EAAQ,QAAQ,cAGtC,SAAK,EAAqB,MAAM,GAAS,EAAQ,aAAa,IAAS,IAAkB,KAGrF,EAAQ,aAAa,aAGrB,EAAc,MAAM,eAAiB,EAAQ,aAAa,QAIhE,CAkBmC,CAAqB,GAKhD,YADA,EAAyB,KAAK,GAKhC,IAAK,MAAM,KAAY,EACrB,GAAI,EAAK,UAAU,GAAW,CAC5B,EAAyB,KAAK,GAC9B,KACV,CAcM,GAVI,EAAK,YAEH,EAAK,WAAW,UAClB,MAAM,KAAK,EAAK,WAAW,UAAU,SAAQ,IAC3C,EAAyB,EAAM,IAMhB,SAAjB,EAAK,QAAoB,CAC3B,MAAM,EAAgB,EAAK,cAAc,CAAE,SAAS,IACpD,IAAK,MAAM,KAAQ,EACjB,EAAyB,EAEnC,MAEY,EAAK,UACP,MAAM,KAAK,EAAK,UAAU,SAAQ,IAChC,EAAyB,EAAM,GAI3C,GAIE,EAAyB,GAIzB,MAAM,EAAiB,GACjB,EAAO,IAAI,IAEjB,IAAK,MAAM,KAAW,EACf,EAAK,IAAI,KACZ,EAAK,IAAI,GACT,EAAe,KAAK,IAIxB,OAAO,CACT,CC1HO,MAAM,EAQX,WAAA,CAAY,GACV,KAAK,GAAe,aAAqB,aACvC,MAAM,IAAI,MAAM,2CAGlB,KAAK,UAAY,EACjB,KAAK,aAAe,UAEpB,KAAK,OACT,CAQE,KAAA,GAGM,UAAW,YAAY,YACzB,KAAK,UAAU,OAAQ,EACvB,KAAK,UAAU,aAAa,6BAA6B,IAI3D,KAAK,UAAU,iBAAiB,UAAW,KAAK,WACpD,CASE,WAAc,IAEZ,GAAc,QAAV,EAAE,IAAe,CAGnB,KAAK,aAAe,EAAE,SAAW,WAAa,UAK9C,IAAI,EAAgB,SAAS,cAC7B,MAAM,EAAW,CAAC,GAClB,KAAO,GAAe,YAAY,eAChC,EAAQ,KAAK,EAAc,WAAW,eACtC,EAAgB,EAAc,WAAW,cAI3C,MAAM,EAAa,KAAK,wBAGlB,GACH,EAAQ,SAAS,EAAW,KAAO,EAAQ,SAAS,KAAK,aAAqC,aAAtB,KAAK,aAC1E,EAAW,OAAS,EACpB,EAAQ,SAAS,EAAW,EAAW,OAAS,KAA6B,YAAtB,KAAK,aAC1D,EACA,KAEW,OAAf,IACF,EAAW,GAAY,QACvB,EAAE,iBACF,EAAE,kBAEV,GAUE,qBAAA,GAKE,OAHiB,EAAqB,KAAK,UAI/C,CAME,iBAAA,GACE,MAAM,EAAa,KAAK,wBACpB,EAAW,QAAQ,EAAW,GAAG,OACzC,CAME,gBAAA,GACE,MAAM,EAAa,KAAK,wBACpB,EAAW,QAAQ,EAAW,EAAW,OAAS,GAAG,OAC7D,CAME,UAAA,GAEM,KAAK,UAAU,aAAa,8BAC9B,KAAK,UAAU,gBAAgB,6BAGjC,KAAK,UAAU,oBAAoB,UAAW,KAAK,WACvD,S","file":"/npm/@aurodesignsystem/auro-library@5.5.3/scripts/runtime/FocusTrap/index.mjs/+esm","sourceRoot":"","sourcesContent":["/**\n * Bundled by jsDelivr using Rollup v2.79.2 and Terser v5.39.0.\n * Original file: /npm/@aurodesignsystem/auro-library@5.5.3/scripts/runtime/FocusTrap/index.mjs\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","// Selectors for focusable elements\nexport const FOCUSABLE_SELECTORS = [\n  'a[href]',\n  'button:not([disabled])',\n  'textarea:not([disabled])',\n  'input:not([disabled])',\n  'select:not([disabled])',\n  '[role=\"tab\"]:not([disabled])',\n  '[role=\"link\"]:not([disabled])',\n  '[role=\"button\"]:not([disabled])',\n  '[tabindex]:not([tabindex=\"-1\"])',\n  '[contenteditable]:not([contenteditable=\"false\"])'\n];\n\n// List of custom components that are known to be focusable\nexport const FOCUSABLE_COMPONENTS = [\n  'auro-checkbox',\n  'auro-radio',\n  'auro-dropdown',\n  'auro-button',\n  'auro-combobox',\n  'auro-input',\n  'auro-counter',\n  'auro-menu',\n  'auro-select',\n  'auro-datepicker',\n  'auro-hyperlink',\n  'auro-accordion',\n];\n\n/**\n * Determines if a given element is a custom focusable component.\n * Returns true if the element matches a known focusable component and is not disabled.\n *\n * @param {HTMLElement} element The element to check for focusability.\n * @returns {boolean} True if the element is a focusable custom component, false otherwise.\n */\nexport function isFocusableComponent(element) {\n  const componentName = element.tagName.toLowerCase();\n\n  // Guard Clause: Element is a focusable component\n  if (!FOCUSABLE_COMPONENTS.some((name) => element.hasAttribute(name) || componentName === name)) return false;\n\n  // Guard Clause: Element is not disabled\n  if (element.hasAttribute('disabled')) return false;\n\n  // Guard Clause: The element is a hyperlink and has no href attribute\n  if (componentName.match(\"hyperlink\") && !element.hasAttribute('href')) return false;\n\n  // If all guard clauses pass, the element is a focusable component\n  return true;\n}\n\n/**\n * Retrieves all focusable elements within the container in DOM order, including those in shadow DOM and slots.\n * Returns a unique, ordered array of elements that can receive focus.\n *\n * @param {HTMLElement} container The container to search within\n * @returns {Array<HTMLElement>} An array of focusable elements within the container.\n */\nexport function getFocusableElements(container) {\n  // Get elements in DOM order by walking the tree\n  const orderedFocusableElements = [];\n\n  // Define a recursive function to collect focusable elements in DOM order\n  const collectFocusableElements = (root) => {\n    // Check if current element is focusable\n    if (root.nodeType === Node.ELEMENT_NODE) {\n      // Check if this is a custom component that is focusable\n      const isComponentFocusable = isFocusableComponent(root);\n\n      if (isComponentFocusable) {\n        // Add the component itself as a focusable element and don't traverse its shadow DOM\n        orderedFocusableElements.push(root);\n        return; // Skip traversing inside this component\n      }\n\n      // Check if the element itself matches any selector\n      for (const selector of FOCUSABLE_SELECTORS) {\n        if (root.matches?.(selector)) {\n          orderedFocusableElements.push(root);\n          break; // Once we know it's focusable, no need to check other selectors\n        }\n      }\n\n      // Process shadow DOM only for non-Auro components\n      if (root.shadowRoot) {\n        // Process shadow DOM children in order\n        if (root.shadowRoot.children) {\n          Array.from(root.shadowRoot.children).forEach(child => {\n            collectFocusableElements(child);\n          });\n        }\n      }\n\n      // Process slots and their assigned nodes in order\n      if (root.tagName === 'SLOT') {\n        const assignedNodes = root.assignedNodes({ flatten: true });\n        for (const node of assignedNodes) {\n          collectFocusableElements(node);\n        }\n      } else {\n        // Process light DOM children in order\n        if (root.children) {\n          Array.from(root.children).forEach(child => {\n            collectFocusableElements(child);\n          });\n        }\n      }\n    }\n  };\n\n  // Start the traversal from the container\n  collectFocusableElements(container);\n\n  // Remove duplicates that might have been collected through different paths\n  // while preserving order\n  const uniqueElements = [];\n  const seen = new Set();\n\n  for (const element of orderedFocusableElements) {\n    if (!seen.has(element)) {\n      seen.add(element);\n      uniqueElements.push(element);\n    }\n  }\n\n  return uniqueElements;\n}","import { getFocusableElements } from '../Focusables/Focusables.mjs';\n\n/**\n * FocusTrap manages keyboard focus within a specified container element, ensuring that focus does not leave the container when tabbing.\n * It is commonly used for modal dialogs or overlays to improve accessibility by trapping focus within interactive UI components.\n */\nexport class FocusTrap {\n  /**\n   * Creates a new FocusTrap instance for the given container element.\n   * Initializes event listeners and prepares the container for focus management.\n   *\n   * @param {HTMLElement} container The DOM element to trap focus within.\n   * @throws {Error} If the provided container is not a valid HTMLElement.\n   */\n  constructor(container) {\n    if (!container || !(container instanceof HTMLElement)) {\n      throw new Error(\"FocusTrap requires a valid HTMLElement.\");\n    }\n\n    this.container = container;\n    this.tabDirection = 'forward'; // or 'backward'\n\n    this._init();\n  }\n\n  /**\n   * Initializes the focus trap by setting up event listeners and attributes on the container.\n   * Prepares the container for focus management, including support for shadow DOM and inert attributes.\n   *\n   * @private\n   */\n  _init() {\n\n    // Add inert attribute to prevent focusing programmatically as well (if supported)\n    if ('inert' in HTMLElement.prototype) {\n      this.container.inert = false; // Ensure the container isn't inert\n      this.container.setAttribute('data-focus-trap-container', true); // Mark for identification\n    }\n\n    // Track tab direction\n    this.container.addEventListener('keydown', this._onKeydown);\n  }\n\n  /**\n   * Handles keydown events to manage tab navigation within the container.\n   * Ensures that focus wraps around when reaching the first or last focusable element.\n   *\n   * @param {KeyboardEvent} e The keyboard event triggered by user interaction.\n   * @private\n   */\n  _onKeydown = (e) => {\n    \n    if (e.key === 'Tab') {\n\n      // Set the tab direction based on the key pressed\n      this.tabDirection = e.shiftKey ? 'backward' : 'forward';\n\n      // Get the active element(s) in the document and shadow root\n      // This will include the active element in the shadow DOM if it exists\n      // Active element may be inside the shadow DOM depending on delegatesFocus, so we need to check both\n      let activeElement = document.activeElement;\n      const actives =  [activeElement];\n      while (activeElement?.shadowRoot?.activeElement) {\n        actives.push(activeElement.shadowRoot.activeElement);\n        activeElement = activeElement.shadowRoot.activeElement;\n      }\n\n      // Update the focusable elements\n      const focusables = this._getFocusableElements();\n\n      // If we're at either end of the focusable elements, wrap around to the other end\n      const focusIndex =\n        (actives.includes(focusables[0]) || actives.includes(this.container)) && this.tabDirection === 'backward'\n          ? focusables.length - 1\n          : actives.includes(focusables[focusables.length - 1]) && this.tabDirection === 'forward'\n            ? 0\n            : null;\n\n      if (focusIndex !== null) {\n        focusables[focusIndex].focus();\n        e.preventDefault(); // Prevent default tab behavior\n        e.stopPropagation(); // Stop the event from bubbling up\n      }\n    }\n  };\n\n  /**\n   * Retrieves all focusable elements within the container in DOM order, including those in shadow DOM and slots.\n   * Returns a unique, ordered array of elements that can receive focus.\n   *\n   * @returns {Array<HTMLElement>} An array of focusable elements within the container.\n   * @private\n   */\n  _getFocusableElements() {\n    // Use the imported utility function to get focusable elements\n    const elements = getFocusableElements(this.container);\n    \n    // Filter out any elements with the 'focus-bookend' class\n    return elements;\n  }\n\n  /**\n   * Moves focus to the first focusable element within the container.\n   * Useful for setting initial focus when activating the focus trap.\n   */\n  focusFirstElement() {\n    const focusables = this._getFocusableElements();\n    if (focusables.length) focusables[0].focus();\n  }\n\n  /**\n   * Moves focus to the last focusable element within the container.\n   * Useful for setting focus when deactivating or cycling focus in reverse.\n   */\n  focusLastElement() {\n    const focusables = this._getFocusableElements();\n    if (focusables.length) focusables[focusables.length - 1].focus();\n  }\n\n  /**\n   * Removes event listeners and attributes added by the focus trap.\n   * Call this method to clean up when the focus trap is no longer needed.\n   */\n  disconnect() {\n\n    if (this.container.hasAttribute('data-focus-trap-container')) {\n      this.container.removeAttribute('data-focus-trap-container');\n    }\n\n    this.container.removeEventListener('keydown', this._onKeydown);\n  }\n}\n"]}