{"version":3,"file":"dropdown.cjs","sources":["../../../components/dropdown/dropdown.vue"],"sourcesContent":["<!-- eslint-disable max-lines -->\n<template>\n  <dt-popover\n    ref=\"popover\"\n    :content-width=\"contentWidth\"\n    :open=\"open\"\n    :placement=\"placement\"\n    :initial-focus-element=\"openedWithKeyboard ? 'first' : 'dialog'\"\n    :fallback-placements=\"fallbackPlacements\"\n    padding=\"none\"\n    role=\"menu\"\n    :append-to=\"appendTo\"\n    :modal=\"modal\"\n    :max-height=\"maxHeight\"\n    :max-width=\"maxWidth\"\n    :open-with-arrow-keys=\"shouldOpenWithArrowKeys\"\n    :open-on-context=\"openOnContext\"\n    :tether=\"tether\"\n    :transition=\"transition\"\n    v-on=\"dropdownListeners\"\n  >\n    <template #anchor=\"{ attrs }\">\n      <!-- @slot Anchor element that activates the dropdown -->\n      <slot\n        ref=\"anchor\"\n        name=\"anchor\"\n        v-bind=\"attrs\"\n      />\n    </template>\n    <template #content=\"{ close }\">\n      <!-- eslint-disable-next-line max-len -->\n      <!-- eslint-disable-next-line vuejs-accessibility/mouse-events-have-key-events, vuejs-accessibility/no-static-element-interactions -->\n      <ul\n        :id=\"listId\"\n        ref=\"listWrapper\"\n        :class=\"listClasses\"\n        data-qa=\"dt-dropdown-list-wrapper\"\n        @mouseleave=\"clearHighlightIndex\"\n        @mousemove.capture=\"onMouseHighlight\"\n      >\n        <!-- @slot Slot for the list component -->\n        <slot\n          name=\"list\"\n          :close=\"close\"\n        />\n      </ul>\n    </template>\n    <template #footerContent=\"{ close }\">\n      <!-- @slot Slot for the footer content -->\n      <slot\n        name=\"footer\"\n        :close=\"close\"\n      />\n    </template>\n  </dt-popover>\n</template>\n\n<script>\nimport KeyboardNavigation from '@/common/mixins/keyboard_list_navigation';\nimport { DtPopover, POPOVER_APPEND_TO_VALUES } from '@/components/popover';\nimport { LIST_ITEM_NAVIGATION_TYPES } from '@/components/list_item';\nimport { DROPDOWN_PADDING_CLASSES } from './dropdown_constants';\nimport { getUniqueString } from '@/common/utils';\nimport { EVENT_KEYNAMES } from '@/common/constants';\n\nexport default {\n  name: 'DtDropdown',\n\n  components: {\n    DtPopover,\n  },\n\n  mixins: [\n    KeyboardNavigation({\n      indexKey: 'highlightIndex',\n      idKey: 'highlightId',\n      listElementKey: 'getListElement',\n      listItemRole: 'menuitem',\n      afterHighlightMethod: 'afterHighlight',\n      beginningOfListMethod: 'beginningOfListMethod',\n      endOfListMethod: 'endOfListMethod',\n      activeItemKey: 'activeItemEl',\n      focusOnKeyboardNavigation: true,\n    }),\n  ],\n\n  props: {\n    /**\n     * Controls whether the dropdown is shown. Leaving this null will have the dropdown trigger on click by default.\n     * If you set this value, the default trigger behavior will be disabled and you can control it as you need.\n     * Supports .sync modifier\n     */\n    open: {\n      type: Boolean,\n      default: null,\n    },\n\n    /**\n     * Opens the dropdown on right click (context menu). If you set this value to `true`,\n     * the default trigger behavior will be disabled.\n     */\n    openOnContext: {\n      type: Boolean,\n      default: false,\n    },\n\n    /**\n     * Vertical padding size around the list element.\n     * @values none, small, large\n     */\n    padding: {\n      type: String,\n      default: 'small',\n      validator: (padding) => {\n        return Object.keys(DROPDOWN_PADDING_CLASSES).some((item) => item === padding);\n      },\n    },\n\n    /**\n     * Determines modal state, dropdown has a modal overlay preventing interaction with elements\n     * below it, but it is invisible.\n     */\n    modal: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Width configuration for the popover content. When its value is 'anchor',\n     * the popover content will have the same width as the anchor.\n     * @values null, anchor\n     */\n    contentWidth: {\n      type: String,\n      default: null,\n    },\n\n    /**\n     * Determines maximum height for the popover before overflow.\n     * Possible units rem|px|em\n     */\n    maxHeight: {\n      type: String,\n      default: '',\n    },\n\n    /**\n     * Determines maximum width for the popover before overflow.\n     * Possible units rem|px|%|em\n     */\n    maxWidth: {\n      type: String,\n      default: '',\n    },\n\n    /**\n     * Sets an ID on the list element of the component. Used by several aria attributes\n     * as well as when deriving the IDs for each item.\n     */\n    listId: {\n      type: String,\n      default () { return getUniqueString(); },\n    },\n\n    /**\n     * The type of navigation that this component should support.\n     * - \"arrow-keys\" for items that are navigated with UP/DOWN keys.\n     * - \"tab\" for items that are navigated using the TAB key.\n     * - \"none\" for static items that are not interactive.\n     * @values arrow-keys, tab, none\n     */\n    navigationType: {\n      type: String,\n      default: LIST_ITEM_NAVIGATION_TYPES.ARROW_KEYS,\n      validator: (t) => Object.values(LIST_ITEM_NAVIGATION_TYPES).includes(t),\n    },\n\n    /**\n     * If the dropdown does not fit in the direction described by \"placement\",\n     * it will attempt to change it's direction to the \"fallbackPlacements\".\n     *\n     * @values top, top-start, top-end,\n     * right, right-start, right-end,\n     * left, left-start, left-end,\n     * bottom, bottom-start, bottom-end,\n     * auto, auto-start, auto-end\n     * */\n    fallbackPlacements: {\n      type: Array,\n      default: () => {\n        return ['auto'];\n      },\n    },\n\n    /**\n     * The direction the dropdown displays relative to the anchor.\n     */\n    placement: {\n      type: String,\n      default: 'bottom',\n    },\n\n    /**\n     * A method that will be called when the selection goes past the beginning of the list.\n     */\n    onBeginningOfList: {\n      type: Function,\n      default: null,\n    },\n\n    /**\n     * A method that will be called when the selection goes past the end of the list.\n     */\n    onEndOfList: {\n      type: Function,\n      default: null,\n    },\n\n    /**\n     * Additional class for the wrapper list element.\n     */\n    listClass: {\n      type: [String, Array, Object],\n      default: '',\n    },\n\n    /**\n     * Sets the element to which the popover is going to append to.\n     * 'body' will append to the nearest body (supports shadow DOM).\n     * @values 'body', 'parent', HTMLElement,\n     */\n    appendTo: {\n      type: [HTMLElement, String],\n      default: 'body',\n      validator: appendTo => {\n        return POPOVER_APPEND_TO_VALUES.includes(appendTo) ||\n            (appendTo instanceof HTMLElement);\n      },\n    },\n\n    /**\n     * If set to false the dialog will display over top of the anchor when there is insufficient space.\n     * If set to true it will never move from its position relative to the anchor and will clip instead.\n     * <a\n     *   class=\"d-link\"\n     *   href=\"https://popper.js.org/docs/v2/modifiers/prevent-overflow/#tether\"\n     *   target=\"_blank\"\n     * >\n     *   Popper.js docs\n     * </a>\n     * @values true, false\n     */\n    tether: {\n      type: Boolean,\n      default: true,\n    },\n\n    /**\n     * Named transition when the content display is toggled.\n     * @see DtLazyShow\n     */\n    transition: {\n      type: String,\n      default: 'fade',\n    },\n  },\n\n  emits: [\n    /**\n     * Event fired when the highlight changes\n     *\n     * @event highlight\n     * @type {Number}\n     */\n    'highlight',\n\n    /**\n     * Event fired when dropdown is shown or hidden\n     *\n     * @event opened\n     * @type {Boolean | Array}\n     */\n    'opened',\n\n    /**\n     * Event fired to sync the open prop with the parent component\n     * @event update:open\n     */\n    'update:open',\n  ],\n\n  data () {\n    return {\n      LIST_ITEM_NAVIGATION_TYPES,\n      DROPDOWN_PADDING_CLASSES,\n      EVENT_KEYNAMES,\n      openedWithKeyboard: false,\n      isOpen: null,\n    };\n  },\n\n  computed: {\n    dropdownListeners () {\n      return {\n        ...this.$listeners,\n\n        opened: isPopoverOpen => {\n          this.updateInitialHighlightIndex(isPopoverOpen);\n        },\n\n        keydown: event => {\n          const eventCode = event.code;\n\n          switch (eventCode) {\n            case EVENT_KEYNAMES.up:\n            case EVENT_KEYNAMES.arrowup:\n              this.onUpKeyPress(event);\n              event.stopPropagation();\n              event.preventDefault();\n              break;\n            case EVENT_KEYNAMES.down:\n            case EVENT_KEYNAMES.arrowdown:\n              this.onDownKeyPress(event);\n              event.stopPropagation();\n              event.preventDefault();\n              break;\n            case EVENT_KEYNAMES.space:\n            case EVENT_KEYNAMES.spacebar:\n              this.onSpaceKey();\n              break;\n            case EVENT_KEYNAMES.enter:\n              this.onEnterKey();\n              break;\n            case EVENT_KEYNAMES.home:\n              this.onHomeKeyPress(event);\n              event.stopPropagation();\n              event.preventDefault();\n              break;\n            case EVENT_KEYNAMES.end:\n              this.onEndKeyPress(event);\n              event.stopPropagation();\n              event.preventDefault();\n              break;\n            default:\n              this.onKeyPress(event);\n              break;\n          }\n\n          this.$emit('keydown', event);\n        },\n      };\n    },\n\n    beginningOfListMethod () {\n      return this.onBeginningOfList || this.jumpToEnd;\n    },\n\n    endOfListMethod () {\n      return this.onEndOfList || this.jumpToBeginning;\n    },\n\n    activeItemEl () {\n      return this.getListElement().querySelector('#' + this.highlightId);\n    },\n\n    isArrowKeyNav () {\n      return this.navigationType === this.LIST_ITEM_NAVIGATION_TYPES.ARROW_KEYS;\n    },\n\n    listClasses () {\n      return [\n        'd-dropdown-list',\n        DROPDOWN_PADDING_CLASSES[this.padding],\n        this.listClass,\n        { 'd-context-menu-list': this.openOnContext },\n      ];\n    },\n\n    shouldOpenWithArrowKeys () {\n      return !this.openOnContext;\n    },\n  },\n\n  methods: {\n    onMouseHighlight (e) {\n      const liElement = e.target.closest('li');\n\n      if (liElement && liElement.role && this.highlightId !== liElement.id) {\n        this.setHighlightId(liElement.id);\n        liElement.focus();\n      }\n    },\n\n    getListElement () {\n      return this.$refs.listWrapper;\n    },\n\n    clearHighlightIndex () {\n      this.setHighlightIndex(-1);\n    },\n\n    afterHighlight () {\n      if (this.highlightIndex === this._itemsLength() - 1) {\n        return;\n      }\n\n      this.$emit('highlight', this.highlightIndex);\n    },\n\n    updateInitialHighlightIndex (isPopoverOpen) {\n      this.isOpen = isPopoverOpen;\n\n      if (isPopoverOpen) {\n        if (this.openedWithKeyboard && this.isArrowKeyNav) {\n          this.setHighlightIndex(0);\n        }\n        this.$emit('opened', true);\n      } else {\n        this.clearHighlightIndex();\n        this.openedWithKeyboard = false;\n        this.$emit('opened', false);\n      }\n    },\n\n    onSpaceKey () {\n      if (!this.open) {\n        this.openedWithKeyboard = true;\n      }\n    },\n\n    onEnterKey () {\n      if (!this.open) {\n        this.openedWithKeyboard = true;\n      }\n    },\n\n    onUpKeyPress () {\n      if (!this.isOpen) {\n        this.openedWithKeyboard = true;\n        return;\n      }\n      if (this.isArrowKeyNav) {\n        return this.onUpKey();\n      }\n    },\n\n    onDownKeyPress () {\n      if (!this.isOpen) {\n        this.openedWithKeyboard = true;\n        return;\n      }\n      if (this.isArrowKeyNav) {\n        return this.onDownKey();\n      }\n    },\n\n    onHomeKeyPress () {\n      if (!this.isOpen || !this.isArrowKeyNav) {\n        return;\n      }\n\n      return this.onHomeKey();\n    },\n\n    onEndKeyPress () {\n      if (!this.isOpen || !this.isArrowKeyNav) {\n        return;\n      }\n\n      return this.onEndKey();\n    },\n\n    onKeyPress (e) {\n      if (!this.isOpen || !this.isArrowKeyNav || !this.isValidLetter(e.key)) {\n        return;\n      }\n\n      e.stopPropagation();\n      e.preventDefault();\n\n      return this.onNavigationKey(e.key);\n    },\n  },\n};\n</script>\n"],"names":["_sfc_main","DtPopover","KeyboardNavigation","padding","DROPDOWN_PADDING_CLASSES","item","getUniqueString","LIST_ITEM_NAVIGATION_TYPES","t","appendTo","POPOVER_APPEND_TO_VALUES","EVENT_KEYNAMES","isPopoverOpen","event","liElement"],"mappings":"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"}