{"version":3,"sources":["components/dropdown/dropdown.ts"],"names":[],"mappings":"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","file":"dropdown.d.ts","sourcesContent":["/**\n * @license\n *\n * Copyright IBM Corp. 2019, 2021\n *\n * This source code is licensed under the Apache-2.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport settings from 'carbon-components/es/globals/js/settings';\nimport { classMap } from 'lit-html/directives/class-map';\nimport { TemplateResult } from 'lit-html';\nimport { ifDefined } from 'lit-html/directives/if-defined';\nimport { html, property, query, customElement, LitElement } from 'lit-element';\nimport ChevronDown16 from '@carbon/icons/lib/chevron--down/16';\nimport WarningFilled16 from '@carbon/icons/lib/warning--filled/16';\nimport FocusMixin from '../../globals/mixins/focus';\nimport FormMixin from '../../globals/mixins/form';\nimport HostListenerMixin from '../../globals/mixins/host-listener';\nimport ValidityMixin from '../../globals/mixins/validity';\nimport HostListener from '../../globals/decorators/host-listener';\nimport { find, forEach, indexOf } from '../../globals/internal/collection-helpers';\nimport { DROPDOWN_COLOR_SCHEME, DROPDOWN_KEYBOARD_ACTION, DROPDOWN_SIZE, DROPDOWN_TYPE, NAVIGATION_DIRECTION } from './defs';\nimport BXDropdownItem from './dropdown-item';\nimport styles from './dropdown.scss';\n\nexport { DROPDOWN_COLOR_SCHEME, DROPDOWN_KEYBOARD_ACTION, DROPDOWN_SIZE, DROPDOWN_TYPE, NAVIGATION_DIRECTION };\n\nconst { prefix } = settings;\n\n/**\n * Dropdown.\n * @element bx-dropdown\n * @csspart label-text The label text.\n * @csspart helper-text The helper text.\n * @csspart trigger-button The trigger button.\n * @csspart menu-body The menu body.\n * @csspart validity-message The validity message.\n * @fires bx-dropdown-beingselected\n *   The custom event fired before a dropdown item is selected upon a user gesture.\n *   Cancellation of this event stops changing the user-initiated selection.\n * @fires bx-dropdown-beingtoggled\n *   The custom event fired before the open state of this dropdown is toggled upon a user gesture.\n *   Cancellation of this event stops the user-initiated toggling.\n * @fires bx-dropdown-selected - The custom event fired after a dropdown item is selected upon a user gesture.\n * @fires bx-dropdown-toggled - The custom event fired after the open state of this dropdown is toggled upon a user gesture.\n */\n@customElement(`${prefix}-dropdown`)\nclass BXDropdown extends ValidityMixin(HostListenerMixin(FormMixin(FocusMixin(LitElement)))) {\n  /**\n   * The latest status of this dropdown, for screen reader to accounce.\n   */\n  protected _assistiveStatusText?: string;\n\n  /**\n   * The content of the selected item.\n   */\n  protected _selectedItemContent: DocumentFragment | null = null;\n\n  /**\n   * `true` if the trigger button should be focusable.\n   * Derived class can set `false` to this if the trigger button contains another primary focusable element (e.g. `<input>`).\n   */\n  protected _shouldTriggerBeFocusable = true;\n\n  /**\n   * The list box `<div>` node.\n   */\n  @query(`.${prefix}--list-box`)\n  protected _listBoxNode!: HTMLDivElement;\n\n  /**\n   * The `<slot>` element for the helper text in the shadow DOM.\n   */\n  @query('slot[name=\"helper-text\"]')\n  protected _slotHelperTextNode!: HTMLSlotElement;\n\n  /**\n   * The `<slot>` element for the label text in the shadow DOM.\n   */\n  @query('slot[name=\"label-text\"]')\n  protected _slotLabelTextNode!: HTMLSlotElement;\n\n  /**\n   * @param itemToSelect A dropdown item. Absense of this argument means clearing selection.\n   * @returns `true` if the selection of this dropdown should change if the given item is selected upon user interaction.\n   */\n  protected _selectionShouldChange(itemToSelect?: BXDropdownItem) {\n    return !itemToSelect || itemToSelect.value !== this.value;\n  }\n\n  /**\n   * A callback that runs after change in dropdown selection upon user interaction is confirmed.\n   * @param itemToSelect\n   *   A dropdown item.\n   *   Absense of this argument means clearing selection, which may be handled by a derived class.\n   */\n  protected _selectionDidChange(itemToSelect?: BXDropdownItem) {\n    if (itemToSelect) {\n      this.value = itemToSelect.value;\n      forEach(this.querySelectorAll((this.constructor as typeof BXDropdown).selectorItemSelected), item => {\n        (item as BXDropdownItem).selected = false;\n      });\n      itemToSelect.selected = true;\n      this._assistiveStatusText = this.selectedItemAssistiveText;\n      this._handleUserInitiatedToggle(false);\n    }\n  }\n\n  /**\n   * Handles `click` event on the top-level element in the shadow DOM.\n   * @param event The event.\n   */\n  protected _handleClickInner(event: MouseEvent) {\n    if (this.shadowRoot!.contains(event.target as Node)) {\n      this._handleUserInitiatedToggle();\n    } else {\n      const item = (event.target as Element).closest((this.constructor as typeof BXDropdown).selectorItem) as BXDropdownItem;\n      if (this.contains(item)) {\n        this._handleUserInitiatedSelectItem(item);\n      }\n    }\n  }\n\n  /**\n   * Handler for the `keydown` event on the top-level element in the shadow DOM.\n   */\n  protected _handleKeydownInner(event: KeyboardEvent) {\n    const { key } = event;\n    const action = (this.constructor as typeof BXDropdown).getAction(key);\n    if (!this.open) {\n      switch (action) {\n        case DROPDOWN_KEYBOARD_ACTION.NAVIGATING:\n          this._handleUserInitiatedToggle(true);\n          // If this menu gets open with an arrow key, reset the highlight\n          this._clearHighlight();\n          break;\n        default:\n          break;\n      }\n    } else {\n      switch (action) {\n        case DROPDOWN_KEYBOARD_ACTION.CLOSING:\n          this._handleUserInitiatedToggle(false);\n          break;\n        case DROPDOWN_KEYBOARD_ACTION.NAVIGATING:\n          this._navigate(NAVIGATION_DIRECTION[key]);\n          break;\n        default:\n          break;\n      }\n    }\n  }\n\n  /**\n   * Handler for the `keypress` event on the top-level element in the shadow DOM.\n   */\n  protected _handleKeypressInner(event: KeyboardEvent) {\n    const { key } = event;\n    const action = (this.constructor as typeof BXDropdown).getAction(key);\n    if (!this.open) {\n      switch (action) {\n        case DROPDOWN_KEYBOARD_ACTION.TRIGGERING:\n          this._handleUserInitiatedToggle(true);\n          break;\n        default:\n          break;\n      }\n    } else {\n      switch (action) {\n        case DROPDOWN_KEYBOARD_ACTION.TRIGGERING:\n          {\n            const constructor = this.constructor as typeof BXDropdown;\n            const highlightedItem = this.querySelector(constructor.selectorItemHighlighted) as BXDropdownItem;\n            if (highlightedItem) {\n              this._handleUserInitiatedSelectItem(highlightedItem);\n            } else {\n              this._handleUserInitiatedToggle(false);\n            }\n          }\n          break;\n        default:\n          break;\n      }\n    }\n  }\n\n  /**\n   * Handles `blur` event handler on the document this element is in.\n   * @param event The event.\n   */\n  @HostListener('focusout')\n  // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to\n  protected _handleFocusOut(event: FocusEvent) {\n    if (!this.contains(event.relatedTarget as Node)) {\n      this._handleUserInitiatedToggle(false);\n    }\n  }\n\n  /**\n   * Handles `slotchange` event for the `<slot>` for helper text.\n   */\n  protected _handleSlotchangeHelperText() {\n    this.requestUpdate();\n  }\n\n  /**\n   * Handles `slotchange` event for the `<slot>` for label text.\n   */\n  protected _handleSlotchangeLabelText() {\n    this.requestUpdate();\n  }\n\n  /**\n   * Handles user-initiated selection of a dropdown item.\n   * @param [item] The dropdown item user wants to select. Absense of this argument means clearing selection.\n   */\n  protected _handleUserInitiatedSelectItem(item?: BXDropdownItem) {\n    if (this._selectionShouldChange(item)) {\n      const init = {\n        bubbles: true,\n        composed: true,\n        detail: {\n          item,\n        },\n      };\n      const constructor = this.constructor as typeof BXDropdown;\n      const beforeSelectEvent = new CustomEvent(constructor.eventBeforeSelect, {\n        ...init,\n        cancelable: true,\n      });\n      if (this.dispatchEvent(beforeSelectEvent)) {\n        this._selectionDidChange(item);\n        const afterSelectEvent = new CustomEvent(constructor.eventSelect, init);\n        this.dispatchEvent(afterSelectEvent);\n      }\n    }\n  }\n\n  /**\n   * Handles user-initiated toggling the open state.\n   * @param [force] If specified, forces the open state to the given one.\n   */\n  protected _handleUserInitiatedToggle(force: boolean = !this.open) {\n    const { eventBeforeToggle, eventToggle } = this.constructor as typeof BXDropdown;\n    const init = {\n      bubbles: true,\n      cancelable: true,\n      composed: true,\n      detail: {\n        open: force,\n      },\n    };\n    if (this.dispatchEvent(new CustomEvent(eventBeforeToggle, init))) {\n      this.open = force;\n      if (this.open) {\n        this._assistiveStatusText = this.selectingItemsAssistiveText;\n      } else {\n        const {\n          selectedItemAssistiveText,\n          triggerContent,\n          _assistiveStatusText: assistiveStatusText,\n          _selectedItemContent: selectedItemContent,\n        } = this;\n        const selectedItemText = (selectedItemContent && selectedItemContent.textContent) || triggerContent;\n        if (selectedItemText && assistiveStatusText !== selectedItemAssistiveText) {\n          this._assistiveStatusText = selectedItemText;\n        }\n        forEach(this.querySelectorAll((this.constructor as typeof BXDropdown).selectorItemHighlighted), item => {\n          (item as BXDropdownItem).highlighted = false;\n        });\n      }\n      this.requestUpdate();\n      this.dispatchEvent(new CustomEvent(eventToggle, init));\n    }\n  }\n\n  /**\n   * Clears the selection of dropdown items.\n   */\n  protected _clearHighlight() {\n    forEach(this.querySelectorAll((this.constructor as typeof BXDropdown).selectorItem), item => {\n      (item as BXDropdownItem).highlighted = false;\n    });\n  }\n\n  /**\n   * Navigate through dropdown items.\n   * @param direction `-1` to navigate backward, `1` to navigate forward.\n   */\n  protected _navigate(direction: number) {\n    const constructor = this.constructor as typeof BXDropdown;\n    const items = this.querySelectorAll(constructor.selectorItem);\n    const highlightedItem = this.querySelector(constructor.selectorItemHighlighted);\n    const highlightedIndex = indexOf(items, highlightedItem!);\n    let nextIndex = highlightedIndex + direction;\n    if (nextIndex < 0) {\n      nextIndex = items.length - 1;\n    }\n    if (nextIndex >= items.length) {\n      nextIndex = 0;\n    }\n    forEach(items, (item, i) => {\n      (item as BXDropdownItem).highlighted = i === nextIndex;\n    });\n\n    const nextItem = items[nextIndex];\n    // Using `{ block: 'nearest' }` to prevent scrolling unless scrolling is absolutely necessary.\n    // `scrollIntoViewOptions` seems to work in latest Safari despite of MDN/caniuse table.\n    // IE falls back to the old behavior.\n    nextItem.scrollIntoView({ block: 'nearest' });\n\n    const nextItemText = nextItem.textContent;\n    if (nextItemText) {\n      this._assistiveStatusText = nextItemText;\n    }\n    this.requestUpdate();\n  }\n\n  /* eslint-disable class-methods-use-this */\n  /**\n   * @returns The content preceding the trigger button.\n   */\n  protected _renderPrecedingTriggerContent(): TemplateResult | void {\n    return undefined;\n  }\n  /* eslint-enable class-methods-use-this */\n\n  /**\n   * @returns The main content of the trigger button.\n   */\n  protected _renderTriggerContent(): TemplateResult {\n    const { triggerContent, _selectedItemContent: selectedItemContent } = this;\n    return html` <span id=\"trigger-label\" class=\"${prefix}--list-box__label\">${selectedItemContent || triggerContent}</span> `;\n  }\n\n  /* eslint-disable class-methods-use-this */\n  /**\n   * @returns The content following the trigger button.\n   */\n  protected _renderFollowingTriggerContent(): TemplateResult | void {\n    return undefined;\n  }\n  /* eslint-enable class-methods-use-this */\n\n  /**\n   * Handles event to include selected value on the parent form.\n   * @param event The event.\n   */\n  _handleFormdata(event: Event) {\n    const { formData } = event as any; // TODO: Wait for `FormDataEvent` being available in `lib.dom.d.ts`\n    const { disabled, name, value } = this;\n    if (!disabled) {\n      formData.append(name, value);\n    }\n  }\n\n  /**\n   * The color scheme.\n   */\n  @property({ attribute: 'color-scheme', reflect: true })\n  colorScheme = DROPDOWN_COLOR_SCHEME.REGULAR;\n\n  /**\n   * `true` if this dropdown should be disabled.\n   */\n  @property({ type: Boolean, reflect: true })\n  disabled = false;\n\n  /**\n   * The helper text.\n   */\n  @property({ attribute: 'helper-text' })\n  helperText = '';\n\n  /**\n   * `true` to show the UI of the invalid state.\n   */\n  @property({ type: Boolean, reflect: true })\n  invalid = false;\n\n  /**\n   * The label text.\n   */\n  @property({ attribute: 'label-text' })\n  labelText = '';\n\n  /**\n   * Name for the dropdown in the `FormData`\n   */\n  @property()\n  name = '';\n\n  /**\n   * `true` if this dropdown should be open.\n   */\n  @property({ type: Boolean, reflect: true })\n  open = false;\n\n  /**\n   * `true` if the value is required.\n   */\n  @property({ type: Boolean, reflect: true })\n  required = false;\n\n  /**\n   * The special validity message for `required`.\n   */\n  @property({ attribute: 'required-validity-message' })\n  requiredValidityMessage = 'Please fill out this field.';\n\n  /**\n   * An assistive text for screen reader to announce, telling the open state.\n   */\n  @property({ attribute: 'selecting-items-assistive-text' })\n  selectingItemsAssistiveText = 'Selecting items. Use up and down arrow keys to navigate.';\n\n  /**\n   * An assistive text for screen reader to announce, telling that an item is selected.\n   */\n  @property({ attribute: 'selected-item-assistive-text' })\n  selectedItemAssistiveText = 'Selected an item.';\n\n  /**\n   * Dropdown size.\n   */\n  @property({ reflect: true })\n  size = DROPDOWN_SIZE.REGULAR;\n\n  /**\n   * The `aria-label` attribute for the UI indicating the closed state.\n   */\n  @property({ attribute: 'toggle-label-closed' })\n  toggleLabelClosed = '';\n\n  /**\n   * The `aria-label` attribute for the UI indicating the open state.\n   */\n  @property({ attribute: 'toggle-label-open' })\n  toggleLabelOpen = '';\n\n  /**\n   * The content of the trigger button.\n   */\n  @property({ attribute: 'trigger-content' })\n  triggerContent = '';\n\n  /**\n   * `true` if this dropdown should use the inline UI variant.\n   */\n  @property({ reflect: true })\n  type = DROPDOWN_TYPE.REGULAR;\n\n  /**\n   * The validity message.\n   */\n  @property({ attribute: 'validity-message' })\n  validityMessage = '';\n\n  /**\n   * The value of the selected item.\n   */\n  @property({ reflect: true })\n  value = '';\n\n  createRenderRoot() {\n    return this.attachShadow({\n      mode: 'open',\n      delegatesFocus: Number((/Safari\\/(\\d+)/.exec(navigator.userAgent) ?? ['', 0])[1]) <= 537,\n    });\n  }\n\n  shouldUpdate(changedProperties) {\n    const { selectorItem } = this.constructor as typeof BXDropdown;\n    if (changedProperties.has('size')) {\n      forEach(this.querySelectorAll(selectorItem), elem => {\n        (elem as BXDropdownItem).size = this.size;\n      });\n    }\n    if (changedProperties.has('value')) {\n      // `<bx-multi-select>` updates selection beforehand\n      // because our rendering logic for `<bx-multi-select>` looks for selected items via `qSA()`\n      forEach(this.querySelectorAll(selectorItem), elem => {\n        (elem as BXDropdownItem).selected = (elem as BXDropdownItem).value === this.value;\n      });\n      const item = find(this.querySelectorAll(selectorItem), elem => (elem as BXDropdownItem).value === this.value);\n      if (item) {\n        const range = this.ownerDocument!.createRange();\n        range.selectNodeContents(item);\n        this._selectedItemContent = range.cloneContents();\n      } else {\n        this._selectedItemContent = null;\n      }\n    }\n    return true;\n  }\n\n  updated(changedProperties) {\n    const { helperText, type } = this;\n    const inline = type === DROPDOWN_TYPE.INLINE;\n    const { selectorItem } = this.constructor as typeof BXDropdown;\n    if (changedProperties.has('disabled')) {\n      const { disabled } = this;\n      // Propagate `disabled` attribute to descendants until `:host-context()` gets supported in all major browsers\n      forEach(this.querySelectorAll(selectorItem), elem => {\n        (elem as BXDropdownItem).disabled = disabled;\n      });\n    }\n    if ((changedProperties.has('helperText') || changedProperties.has('type')) && helperText && inline) {\n      // eslint-disable-next-line no-console\n      console.warn('Found `helperText` property/attribute usage in inline mode, that is not supported, at:', this);\n    }\n  }\n\n  render() {\n    const {\n      colorScheme,\n      disabled,\n      helperText,\n      invalid,\n      labelText,\n      open,\n      toggleLabelClosed,\n      toggleLabelOpen,\n      size,\n      type,\n      validityMessage,\n      _assistiveStatusText: assistiveStatusText,\n      _shouldTriggerBeFocusable: shouldTriggerBeFocusable,\n      _handleClickInner: handleClickInner,\n      _handleKeydownInner: handleKeydownInner,\n      _handleKeypressInner: handleKeypressInner,\n      _handleSlotchangeHelperText: handleSlotchangeHelperText,\n      _handleSlotchangeLabelText: handleSlotchangeLabelText,\n      _slotHelperTextNode: slotHelperTextNode,\n      _slotLabelTextNode: slotLabelTextNode,\n    } = this;\n    const inline = type === DROPDOWN_TYPE.INLINE;\n    const selectedItemsCount = this.querySelectorAll((this.constructor as typeof BXDropdown).selectorItemSelected).length;\n    const classes = classMap({\n      [`${prefix}--dropdown`]: true,\n      [`${prefix}--list-box`]: true,\n      [`${prefix}--list-box--${colorScheme}`]: colorScheme,\n      [`${prefix}--list-box--disabled`]: disabled,\n      [`${prefix}--list-box--inline`]: inline,\n      [`${prefix}--list-box--expanded`]: open,\n      [`${prefix}--list-box--${size}`]: size,\n      [`${prefix}--dropdown--invalid`]: invalid,\n      [`${prefix}--dropdown--inline`]: inline,\n      [`${prefix}--dropdown--selected`]: selectedItemsCount > 0,\n    });\n    const labelClasses = classMap({\n      [`${prefix}--label`]: true,\n      [`${prefix}--label--disabled`]: disabled,\n    });\n    const helperClasses = classMap({\n      [`${prefix}--form__helper-text`]: true,\n      [`${prefix}--form__helper-text--disabled`]: disabled,\n    });\n    const iconContainerClasses = classMap({\n      [`${prefix}--list-box__menu-icon`]: true,\n      [`${prefix}--list-box__menu-icon--open`]: open,\n    });\n    const toggleLabel = (open ? toggleLabelOpen : toggleLabelClosed) || undefined;\n    const hasHelperText = helperText || (slotHelperTextNode && slotHelperTextNode.assignedNodes().length > 0);\n    const hasLabelText = labelText || (slotLabelTextNode && slotLabelTextNode.assignedNodes().length > 0);\n    const helper = !invalid\n      ? html`\n          <div part=\"helper-text\" class=\"${helperClasses}\" ?hidden=\"${inline || !hasHelperText}\">\n            <slot name=\"helper-text\" @slotchange=\"${handleSlotchangeHelperText}\">${helperText}</slot>\n          </div>\n        `\n      : html`\n          <div part=\"validity-message\" class=${`${prefix}--form-requirement`}>\n            <slot name=\"validity-message\">${validityMessage}</slot>\n          </div>\n        `;\n    const validityIcon = !invalid\n      ? undefined\n      : WarningFilled16({ class: `${prefix}--list-box__invalid-icon`, 'aria-label': toggleLabel });\n    const menuBody = !open\n      ? undefined\n      : html`\n          <div id=\"menu-body\" part=\"menu-body\" class=\"${prefix}--list-box__menu\" role=\"listbox\" tabindex=\"-1\">\n            <slot></slot>\n          </div>\n        `;\n    return html`\n      <label part=\"label-text\" class=\"${labelClasses}\" ?hidden=\"${!hasLabelText}\">\n        <slot name=\"label-text\" @slotchange=\"${handleSlotchangeLabelText}\">${labelText}</slot>\n      </label>\n      <div\n        role=\"listbox\"\n        class=\"${classes}\"\n        ?data-invalid=${invalid}\n        @click=${handleClickInner}\n        @keydown=${handleKeydownInner}\n        @keypress=${handleKeypressInner}>\n        ${validityIcon}\n        <div\n          part=\"trigger-button\"\n          role=\"${ifDefined(!shouldTriggerBeFocusable ? undefined : 'button')}\"\n          class=\"${prefix}--list-box__field\"\n          tabindex=\"${ifDefined(!shouldTriggerBeFocusable ? undefined : '0')}\"\n          aria-labelledby=\"trigger-label\"\n          aria-expanded=\"${String(open)}\"\n          aria-haspopup=\"listbox\"\n          aria-owns=\"menu-body\"\n          aria-controls=\"menu-body\">\n          ${this._renderPrecedingTriggerContent()}${this._renderTriggerContent()}${this._renderFollowingTriggerContent()}\n          <div class=\"${iconContainerClasses}\">${ChevronDown16({ 'aria-label': toggleLabel })}</div>\n        </div>\n        ${menuBody}\n      </div>\n      ${helper}\n      <div class=\"${prefix}--assistive-text\" role=\"status\" aria-live=\"assertive\" aria-relevant=\"additions text\">\n        ${assistiveStatusText}\n      </div>\n    `;\n  }\n\n  /**\n   * Symbols of keys that triggers opening/closing menu and selecting/deselecting menu item.\n   */\n  static TRIGGER_KEYS = new Set([' ', 'Enter']);\n\n  /**\n   * A selector that will return highlighted items.\n   */\n  static get selectorItemHighlighted() {\n    return `${prefix}-dropdown-item[highlighted]`;\n  }\n\n  /**\n   * A selector that will return dropdown items.\n   */\n  static get selectorItem() {\n    return `${prefix}-dropdown-item`;\n  }\n\n  /**\n   * A selector that will return selected items.\n   */\n  static get selectorItemSelected() {\n    return `${prefix}-dropdown-item[selected]`;\n  }\n\n  /**\n   * The name of the custom event fired before a dropdown item is selected upon a user gesture.\n   * Cancellation of this event stops changing the user-initiated selection.\n   */\n  static get eventBeforeSelect() {\n    return `${prefix}-dropdown-beingselected`;\n  }\n\n  /**\n   * The name of the custom event fired after a a dropdown item is selected upon a user gesture.\n   */\n  static get eventSelect() {\n    return `${prefix}-dropdown-selected`;\n  }\n\n  /**\n   * The name of the custom event fired before this dropdown item is being toggled upon a user gesture.\n   * Cancellation of this event stops the user-initiated action of toggling this dropdown item.\n   */\n  static get eventBeforeToggle() {\n    return `${prefix}-dropdown-beingtoggled`;\n  }\n\n  /**\n   * The name of the custom event fired after this dropdown item is toggled upon a user gesture.\n   */\n  static get eventToggle() {\n    return `${prefix}-dropdown-toggled`;\n  }\n\n  static styles = styles;\n\n  /**\n   * @returns A action for dropdown for the given key symbol.\n   */\n  static getAction(key: string) {\n    if (key === 'Escape') {\n      return DROPDOWN_KEYBOARD_ACTION.CLOSING;\n    }\n    if (key in NAVIGATION_DIRECTION) {\n      return DROPDOWN_KEYBOARD_ACTION.NAVIGATING;\n    }\n    if (this.TRIGGER_KEYS.has(key)) {\n      return DROPDOWN_KEYBOARD_ACTION.TRIGGERING;\n    }\n    return DROPDOWN_KEYBOARD_ACTION.NONE;\n  }\n}\n\nexport default BXDropdown;\n"]}