{"version":3,"file":"BqDropdownMenu-XYjxzHN-.cjs","names":[],"sources":["../src/components/dropdown-menu/BqDropdownMenu.ts"],"sourcesContent":["/**\r\n * Dropdown menu component — a trigger-activated overlay for actions or navigation.\r\n * @element bq-dropdown-menu\r\n * @prop {string}  label      - Accessible label for the dropdown menu\r\n * @prop {string}  placement  - bottom-start | bottom-end | top-start | top-end\r\n * @prop {boolean} open       - Whether the menu is open\r\n * @prop {boolean} disabled\r\n * @slot trigger  - Element that opens the menu (button, link, etc.)\r\n * @slot          - Menu items (typically <button> or <a> elements)\r\n * @fires bq-open\r\n * @fires bq-close\r\n * @fires bq-select - { value: string } — emitted when a menu item is activated\r\n */\r\nimport type { ComponentDefinition } from '@bquery/bquery/component';\r\nimport { component, html } from '@bquery/bquery/component';\r\nimport { escapeHtml } from '@bquery/bquery/security';\r\nimport { getAnimationTimeoutMs, uniqueId } from '../../utils/dom.js';\r\nimport { getBaseStyles } from '../../utils/styles.js';\r\n\r\ntype BqDropdownMenuProps = {\r\n  label: string;\r\n  placement: string;\r\n  open: boolean;\r\n  disabled: boolean;\r\n};\r\ntype BqDropdownMenuState = { uid: string };\r\nconst FAST_DURATION = '150ms';\r\n\r\nconst definition: ComponentDefinition<\r\n  BqDropdownMenuProps,\r\n  BqDropdownMenuState\r\n> = {\r\n  props: {\r\n    label: { type: String, default: '' },\r\n    placement: { type: String, default: 'bottom-start' },\r\n    open: { type: Boolean, default: false },\r\n    disabled: { type: Boolean, default: false },\r\n  },\r\n  state: {\r\n    uid: '',\r\n  },\r\n  styles: `\r\n    ${getBaseStyles()}\r\n    *, *::before, *::after { box-sizing: border-box; }\r\n    :host { display: inline-block; position: relative; }\r\n    .trigger-wrap { display: inline-flex; }\r\n    .menu {\r\n      display: none; position: absolute; z-index: var(--bq-z-dropdown,100);\r\n      min-width: 10rem; max-height: 20rem; overflow-y: auto;\r\n      background: var(--bq-bg-base,#fff); border: 1px solid var(--bq-border-base,#e2e8f0);\r\n      border-radius: var(--bq-radius-lg,0.5rem); box-shadow: var(--bq-shadow-lg);\r\n      padding: var(--bq-space-1,0.25rem) 0; font-family: var(--bq-font-family-sans);\r\n      animation: menuFadeIn var(--bq-duration-fast,150ms) var(--bq-easing-decelerate);\r\n    }\r\n    :host([open]:not([data-closing])) .menu { display: block; }\r\n    :host([open][data-closing]) .menu { display: block; animation: menuFadeOut var(--bq-duration-fast,150ms) var(--bq-easing-accelerate) forwards; }\r\n    @keyframes menuFadeIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }\r\n    @keyframes menuFadeOut { to { opacity: 0; transform: translateY(-4px); } }\r\n    :host([placement=\"bottom-start\"]) .menu { top: 100%; left: 0; margin-top: 0.25rem; }\r\n    :host([placement=\"bottom-end\"]) .menu { top: 100%; right: 0; margin-top: 0.25rem; }\r\n    :host([placement=\"top-start\"]) .menu { bottom: 100%; left: 0; margin-bottom: 0.25rem; }\r\n    :host([placement=\"top-end\"]) .menu { bottom: 100%; right: 0; margin-bottom: 0.25rem; }\r\n    :host(:not([placement])) .menu { top: 100%; left: 0; margin-top: 0.25rem; }\r\n    ::slotted(button),\r\n    ::slotted(a) {\r\n      display: flex; align-items: center; gap: 0.5rem; width: 100%;\r\n      padding: 0.5rem 0.875rem; border: none; background: none;\r\n      color: var(--bq-text-base,#0f172a); font-size: var(--bq-font-size-sm,0.875rem);\r\n      font-family: var(--bq-font-family-sans); text-align: left; cursor: pointer;\r\n      text-decoration: none; white-space: nowrap;\r\n      transition: background var(--bq-duration-fast) var(--bq-easing-standard);\r\n    }\r\n    ::slotted(button:hover),\r\n    ::slotted(a:hover) { background: var(--bq-bg-subtle,#f8fafc); }\r\n    ::slotted(button:focus-visible),\r\n    ::slotted(a:focus-visible) { outline: none; background: var(--bq-bg-muted,#f1f5f9); box-shadow: inset 0 0 0 2px var(--bq-border-focus,#2563eb); }\r\n    ::slotted(button[disabled]),\r\n    ::slotted(a[disabled]),\r\n    ::slotted(a[aria-disabled=\"true\"]) { opacity: 0.5; cursor: not-allowed; pointer-events: none; }\r\n    ::slotted(hr) { border: none; border-top: 1px solid var(--bq-border-base,#e2e8f0); margin: 0.25rem 0; }\r\n    @media (prefers-reduced-motion: reduce) {\r\n      .menu { animation: none !important; }\r\n      ::slotted(button),\r\n      ::slotted(a) { transition: none; }\r\n    }\r\n  `,\r\n  connected() {\r\n    type BQEl = HTMLElement & {\r\n      setState(k: 'uid', v: string): void;\r\n      getState<T>(k: string): T;\r\n    };\r\n    const self = this as unknown as BQEl;\r\n    const record = self as unknown as Record<string, unknown>;\r\n    if (!self.getState<string>('uid')) self.setState('uid', uniqueId('bq-dm'));\r\n\r\n    const getTrigger = (): HTMLElement | null =>\r\n      self.querySelector('[slot=\"trigger\"]') as HTMLElement | null;\r\n\r\n    const isDisabledItem = (el: HTMLElement): boolean =>\r\n      el.hasAttribute('disabled') ||\r\n      el.getAttribute('aria-disabled') === 'true';\r\n\r\n    const getItemLabel = (el: HTMLElement): string =>\r\n      (el.getAttribute('data-value') || el.textContent || '')\r\n        .trim()\r\n        .toLowerCase();\r\n\r\n    const getMenuRoots = (): HTMLElement[] => {\r\n      const slot = self.shadowRoot?.querySelector(\r\n        'slot:not([name])'\r\n      ) as HTMLSlotElement | null;\r\n      if (!slot) return [];\r\n      return slot\r\n        .assignedElements({ flatten: true })\r\n        .filter((el): el is HTMLElement => el instanceof HTMLElement);\r\n    };\r\n\r\n    const syncTriggerA11y = () => {\r\n      const trigger = getTrigger();\r\n      if (!trigger) return;\r\n      const uid = self.getState<string>('uid') || 'bq-dm';\r\n      const isDisabled = self.hasAttribute('disabled');\r\n      trigger.setAttribute('aria-haspopup', 'menu');\r\n      trigger.setAttribute(\r\n        'aria-expanded',\r\n        self.hasAttribute('open') ? 'true' : 'false'\r\n      );\r\n      trigger.setAttribute('aria-controls', `${uid}-menu`);\r\n      trigger.setAttribute('aria-disabled', isDisabled ? 'true' : 'false');\r\n      if (trigger.tagName === 'BUTTON') {\r\n        (trigger as HTMLButtonElement).disabled = isDisabled;\r\n      }\r\n    };\r\n\r\n    const syncMenuItemRoles = () => {\r\n      getMenuRoots().forEach((el) => {\r\n        if (el.tagName === 'HR') {\r\n          el.setAttribute('role', 'separator');\r\n          return;\r\n        }\r\n        if (el.tagName === 'BUTTON' || el.tagName === 'A') {\r\n          if (!el.hasAttribute('role')) el.setAttribute('role', 'menuitem');\r\n          if (el.tagName === 'BUTTON' && !el.hasAttribute('type')) {\r\n            el.setAttribute('type', 'button');\r\n          }\r\n          if (isDisabledItem(el)) {\r\n            if (el.tagName === 'A') el.setAttribute('aria-disabled', 'true');\r\n            el.setAttribute('tabindex', '-1');\r\n            return;\r\n          }\r\n          if (!el.hasAttribute('tabindex')) el.setAttribute('tabindex', '-1');\r\n        }\r\n      });\r\n    };\r\n\r\n    const open = () => {\r\n      if (self.hasAttribute('disabled') || self.hasAttribute('open')) return;\r\n      self.setAttribute('open', '');\r\n      syncTriggerA11y();\r\n      self.dispatchEvent(\r\n        new CustomEvent('bq-open', { bubbles: true, composed: true })\r\n      );\r\n      // Focus first item\r\n      requestAnimationFrame(() => {\r\n        if (!self.hasAttribute('open') || self.hasAttribute('data-closing'))\r\n          return;\r\n        const items = getMenuItems();\r\n        if (items.length > 0) items[0]!.focus();\r\n      });\r\n    };\r\n    const close = ({\r\n      restoreFocus = false,\r\n    }: { restoreFocus?: boolean } = {}) => {\r\n      if (!self.hasAttribute('open') || self.hasAttribute('data-closing'))\r\n        return;\r\n      clearTypeaheadBuffer();\r\n      const clearCloseTimer = () => {\r\n        const closeTimer = record['_closeTimer'] as\r\n          | ReturnType<typeof setTimeout>\r\n          | undefined;\r\n        if (closeTimer) {\r\n          clearTimeout(closeTimer);\r\n          delete record['_closeTimer'];\r\n        }\r\n      };\r\n      const reducedMotion = self.ownerDocument.defaultView?.matchMedia?.(\r\n        '(prefers-reduced-motion: reduce)'\r\n      )?.matches;\r\n      const finalize = () => {\r\n        clearCloseTimer();\r\n        self.removeAttribute('data-closing');\r\n        self.removeAttribute('open');\r\n        syncTriggerA11y();\r\n        self.dispatchEvent(\r\n          new CustomEvent('bq-close', { bubbles: true, composed: true })\r\n        );\r\n        if (restoreFocus) getTrigger()?.focus();\r\n      };\r\n      if (reducedMotion) {\r\n        finalize();\r\n      } else {\r\n        self.setAttribute('data-closing', '');\r\n        const menu = self.shadowRoot?.querySelector('.menu');\r\n        const timeoutMs = menu ? getAnimationTimeoutMs(menu, FAST_DURATION) : 0;\r\n        if (timeoutMs <= 0) {\r\n          finalize();\r\n        } else {\r\n          record['_closeTimer'] = setTimeout(\r\n            finalize,\r\n            Math.ceil(timeoutMs) + 20\r\n          );\r\n        }\r\n      }\r\n    };\r\n    const toggle = () => {\r\n      if (self.hasAttribute('open')) close();\r\n      else open();\r\n    };\r\n\r\n    let typeaheadBuffer = '';\r\n    let typeaheadTimeout = 0;\r\n\r\n    const clearTypeaheadBuffer = () => {\r\n      typeaheadBuffer = '';\r\n      if (typeaheadTimeout) {\r\n        clearTimeout(typeaheadTimeout);\r\n        typeaheadTimeout = 0;\r\n      }\r\n    };\r\n\r\n    const focusTypeaheadMatch = (search: string, currentIndex: number) => {\r\n      const items = getMenuItems();\r\n      if (items.length === 0) return;\r\n\r\n      const orderedItems =\r\n        currentIndex >= 0\r\n          ? [\r\n              ...items.slice(currentIndex + 1),\r\n              ...items.slice(0, currentIndex + 1),\r\n            ]\r\n          : items;\r\n\r\n      const match = orderedItems.find((item) =>\r\n        getItemLabel(item).startsWith(search)\r\n      );\r\n      match?.focus();\r\n    };\r\n\r\n    const getMenuItems = (): HTMLElement[] => {\r\n      return getMenuRoots().filter(\r\n        (el): el is HTMLElement =>\r\n          (el.tagName === 'BUTTON' || el.tagName === 'A') && !isDisabledItem(el)\r\n      );\r\n    };\r\n\r\n    // Trigger click\r\n    const triggerHandler = (e: Event) => {\r\n      const triggerSlot = self.shadowRoot?.querySelector(\r\n        'slot[name=\"trigger\"]'\r\n      ) as HTMLSlotElement | null;\r\n      if (!triggerSlot) return;\r\n      const assigned = triggerSlot.assignedElements({ flatten: true });\r\n      const clickedTrigger = assigned.some(\r\n        (el) => el === e.target || el.contains(e.target as Node)\r\n      );\r\n      if (clickedTrigger) {\r\n        e.preventDefault();\r\n        toggle();\r\n      }\r\n    };\r\n\r\n    // Menu item click\r\n    const menuClickHandler = (e: Event) => {\r\n      const target = e.target as HTMLElement | null;\r\n      if (!target) return;\r\n\r\n      const trigger = getTrigger();\r\n      if (trigger && (target === trigger || trigger.contains(target))) return;\r\n\r\n      const item = target.closest('button, a') as HTMLElement | null;\r\n      if (!item) return;\r\n\r\n      if (isDisabledItem(item)) {\r\n        e.preventDefault();\r\n        return;\r\n      }\r\n\r\n      const isInMenu = getMenuRoots().some(\r\n        (el) => el === item || el.contains(item)\r\n      );\r\n      if (!isInMenu) return;\r\n\r\n      const value =\r\n        item.getAttribute('data-value') || item.textContent?.trim() || '';\r\n      self.dispatchEvent(\r\n        new CustomEvent('bq-select', {\r\n          detail: { value },\r\n          bubbles: true,\r\n          composed: true,\r\n        })\r\n      );\r\n      close({ restoreFocus: true });\r\n    };\r\n\r\n    // Keyboard navigation\r\n    const keyHandler = (e: Event) => {\r\n      const ke = e as KeyboardEvent;\r\n      if (self.hasAttribute('disabled')) return;\r\n\r\n      // On trigger: open on ArrowDown/Enter/Space\r\n      const triggerSlot = self.shadowRoot?.querySelector(\r\n        'slot[name=\"trigger\"]'\r\n      ) as HTMLSlotElement | null;\r\n      const triggerEls = triggerSlot?.assignedElements({ flatten: true }) ?? [];\r\n      const isOnTrigger = triggerEls.some(\r\n        (el) => el === ke.target || el.contains(ke.target as Node)\r\n      );\r\n\r\n      if (isOnTrigger) {\r\n        if (ke.key === 'ArrowDown' || ke.key === 'Enter' || ke.key === ' ') {\r\n          ke.preventDefault();\r\n          open();\r\n          return;\r\n        }\r\n        if (ke.key === 'Escape') {\r\n          close({ restoreFocus: true });\r\n          return;\r\n        }\r\n      }\r\n\r\n      // Inside menu\r\n      if (!self.hasAttribute('open')) return;\r\n      const items = getMenuItems();\r\n      const currentItem = (ke.target as HTMLElement | null)?.closest(\r\n        'button, a'\r\n      ) as HTMLElement | null;\r\n      const currentIndex = currentItem ? items.indexOf(currentItem) : -1;\r\n\r\n      switch (ke.key) {\r\n        case 'ArrowDown': {\r\n          ke.preventDefault();\r\n          const next = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\r\n          items[next]?.focus();\r\n          break;\r\n        }\r\n        case 'ArrowUp': {\r\n          ke.preventDefault();\r\n          const prev = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\r\n          items[prev]?.focus();\r\n          break;\r\n        }\r\n        case 'Home': {\r\n          ke.preventDefault();\r\n          items[0]?.focus();\r\n          break;\r\n        }\r\n        case 'End': {\r\n          ke.preventDefault();\r\n          items[items.length - 1]?.focus();\r\n          break;\r\n        }\r\n        case 'Enter':\r\n        case ' ': {\r\n          if (currentIndex === -1) break;\r\n          ke.preventDefault();\r\n          currentItem?.click();\r\n          break;\r\n        }\r\n        case 'Escape':\r\n          close({ restoreFocus: true });\r\n          break;\r\n        case 'Tab': {\r\n          close();\r\n          break;\r\n        }\r\n        default: {\r\n          // Skip typeahead while an IME composition is active — the keys\r\n          // are part of the candidate selection, not menu navigation.\r\n          // Also ignore the synthetic key fired on composition end (229).\r\n          if (ke.isComposing || ke.keyCode === 229) break;\r\n          if (ke.key.length === 1 && !ke.altKey && !ke.ctrlKey && !ke.metaKey) {\r\n            typeaheadBuffer = `${typeaheadBuffer}${ke.key.toLowerCase()}`;\r\n            if (typeaheadTimeout) clearTimeout(typeaheadTimeout);\r\n            typeaheadTimeout = window.setTimeout(() => {\r\n              typeaheadBuffer = '';\r\n              typeaheadTimeout = 0;\r\n            }, 500);\r\n            focusTypeaheadMatch(typeaheadBuffer, currentIndex);\r\n          }\r\n        }\r\n      }\r\n    };\r\n\r\n    // Click outside\r\n    const outsideHandler = (e: Event) => {\r\n      if (!self.hasAttribute('open')) return;\r\n      if (!self.contains(e.target as Node)) close({ restoreFocus: true });\r\n    };\r\n    let outsideListening = false;\r\n    const syncOutsideListener = () => {\r\n      if (self.hasAttribute('open')) {\r\n        if (!outsideListening) {\r\n          document.addEventListener('click', outsideHandler);\r\n          outsideListening = true;\r\n        }\r\n        return;\r\n      }\r\n      if (outsideListening) {\r\n        document.removeEventListener('click', outsideHandler);\r\n        outsideListening = false;\r\n      }\r\n    };\r\n\r\n    const slotChangeHandler = () => {\r\n      syncTriggerA11y();\r\n      syncMenuItemRoles();\r\n    };\r\n\r\n    const s = self as unknown as Record<string, unknown>;\r\n    s['_triggerHandler'] = triggerHandler;\r\n    s['_menuClickHandler'] = menuClickHandler;\r\n    s['_keyHandler'] = keyHandler;\r\n    s['_outsideHandler'] = outsideHandler;\r\n    s['_syncOutsideListener'] = syncOutsideListener;\r\n    s['_slotChangeHandler'] = slotChangeHandler;\r\n    s['_clearTypeaheadBuffer'] = clearTypeaheadBuffer;\r\n\r\n    self.addEventListener('click', triggerHandler);\r\n    self.addEventListener('click', menuClickHandler);\r\n    self.addEventListener('keydown', keyHandler);\r\n    self.shadowRoot\r\n      ?.querySelector('slot[name=\"trigger\"]')\r\n      ?.addEventListener('slotchange', slotChangeHandler);\r\n    self.shadowRoot\r\n      ?.querySelector('slot:not([name])')\r\n      ?.addEventListener('slotchange', slotChangeHandler);\r\n\r\n    requestAnimationFrame(() => {\r\n      syncTriggerA11y();\r\n      syncMenuItemRoles();\r\n      syncOutsideListener();\r\n    });\r\n  },\r\n  disconnected() {\r\n    const s = this as unknown as Record<string, unknown>;\r\n    const triggerHandler = s['_triggerHandler'] as EventListener | undefined;\r\n    const menuClickHandler = s['_menuClickHandler'] as\r\n      | EventListener\r\n      | undefined;\r\n    const keyHandler = s['_keyHandler'] as EventListener | undefined;\r\n    const outsideHandler = s['_outsideHandler'] as EventListener | undefined;\r\n    const slotChangeHandler = s['_slotChangeHandler'] as\r\n      | EventListener\r\n      | undefined;\r\n    const clearTypeaheadBuffer = s['_clearTypeaheadBuffer'] as\r\n      | (() => void)\r\n      | undefined;\r\n    const closeTimer = s['_closeTimer'] as\r\n      | ReturnType<typeof setTimeout>\r\n      | undefined;\r\n    if (triggerHandler) this.removeEventListener('click', triggerHandler);\r\n    if (menuClickHandler) this.removeEventListener('click', menuClickHandler);\r\n    if (keyHandler) this.removeEventListener('keydown', keyHandler);\r\n    if (outsideHandler) document.removeEventListener('click', outsideHandler);\r\n    clearTypeaheadBuffer?.();\r\n    if (closeTimer) {\r\n      clearTimeout(closeTimer);\r\n      delete s['_closeTimer'];\r\n      this.removeAttribute('data-closing');\r\n      this.removeAttribute('open');\r\n    }\r\n    if (slotChangeHandler) {\r\n      this.shadowRoot\r\n        ?.querySelector('slot[name=\"trigger\"]')\r\n        ?.removeEventListener('slotchange', slotChangeHandler);\r\n      this.shadowRoot\r\n        ?.querySelector('slot:not([name])')\r\n        ?.removeEventListener('slotchange', slotChangeHandler);\r\n    }\r\n  },\r\n  updated() {\r\n    const s = this as unknown as Record<string, unknown>;\r\n    const syncOutsideListener = s['_syncOutsideListener'] as\r\n      | (() => void)\r\n      | undefined;\r\n    syncOutsideListener?.();\r\n    const trigger = this.querySelector(\r\n      '[slot=\"trigger\"]'\r\n    ) as HTMLElement | null;\r\n    if (trigger)\r\n      trigger.setAttribute(\r\n        'aria-expanded',\r\n        this.hasAttribute('open') ? 'true' : 'false'\r\n      );\r\n  },\r\n  render({ props, state }) {\r\n    const uid = state.uid || 'bq-dm';\r\n    const menuId = `${uid}-menu`;\r\n    return html`\r\n      <div class=\"trigger-wrap\" part=\"trigger\">\r\n        <slot name=\"trigger\"></slot>\r\n      </div>\r\n      <div\r\n        class=\"menu\"\r\n        id=\"${menuId}\"\r\n        part=\"menu\"\r\n        role=\"menu\"\r\n        ${props.label ? `aria-label=\"${escapeHtml(props.label)}\"` : ''}\r\n      >\r\n        <slot></slot>\r\n      </div>\r\n    `;\r\n  },\r\n};\r\n\r\ncomponent<BqDropdownMenuProps, BqDropdownMenuState>(\r\n  'bq-dropdown-menu',\r\n  definition\r\n);\r\n"],"mappings":"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"}