UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

1 lines 31 kB
{"version":3,"file":"combobox-multi-select.cjs","names":[],"sources":["../../../components/combobox_multi_select/combobox_multi_select.vue"],"sourcesContent":["<!-- eslint-disable vue/no-static-inline-styles -->\n<template>\n <dt-combobox-with-popover\n ref=\"comboboxWithPopover\"\n :label=\"label\"\n :show-list=\"showList\"\n :max-height=\"listMaxHeight\"\n :max-width=\"listMaxWidth\"\n :popover-offset=\"popoverOffset\"\n :has-suggestion-list=\"hasSuggestionList\"\n content-width=\"anchor\"\n :append-to=\"appendTo\"\n :dialog-class=\"dialogClass\"\n :transition=\"transition\"\n v-bind=\"extractNonListeners($attrs)\"\n @select=\"onComboboxSelect\"\n @highlight=\"comboboxHighlight\"\n >\n <template #input=\"{ onInput }\">\n <span\n ref=\"inputSlotWrapper\"\n class=\"d-recipe-combobox-multi-select__input-wrapper\"\n @focusin=\"handleInputFocusIn\"\n @focusout=\"handleInputFocusOut\"\n >\n <span\n ref=\"chipsWrapper\"\n :class=\"['d-recipe-combobox-multi-select__chip-wrapper', chipWrapperClass]\"\n >\n <dt-chip\n v-for=\"(item, index) in selectedItems\"\n ref=\"chips\"\n :key=\"`${index}-${item}`\"\n :label-class=\"['d-chip__label']\"\n :class=\"[\n 'd-recipe-combobox-multi-select__chip',\n { 'd-recipe-combobox-multi-select__chip--truncate': !!chipMaxWidth },\n ]\"\n :style=\"{ maxWidth: chipMaxWidth }\"\n :size=\"CHIP_SIZES[size]\"\n :disabled=\"disabled\"\n v-on=\"chipListeners\"\n @keydown.backspace=\"onChipRemove(item)\"\n @close=\"onChipRemove(item)\"\n >\n {{ item }}\n </dt-chip>\n </span>\n\n <dt-input\n ref=\"input\"\n v-model=\"value\"\n class=\"d-recipe-combobox-multi-select__input\"\n :input-class=\"[\n inputClass, {\n 'd-recipe-combobox-multi-select__input--hidden': hideInputText,\n }]\"\n :input-wrapper-class=\"inputWrapperClass\"\n :disabled=\"disabled\"\n :aria-label=\"label\"\n :label=\"labelVisible ? label : ''\"\n :description=\"description\"\n :placeholder=\"inputPlaceHolder\"\n :show-messages=\"showInputMessages\"\n :messages=\"inputMessages\"\n :size=\"size\"\n v-bind=\"inputListeners\"\n @input=\"onInput\"\n />\n\n <dt-validation-messages\n :validation-messages=\"maxSelectedMessage\"\n :show-messages=\"showValidationMessages\"\n />\n </span>\n </template>\n\n <!-- @slot slot for popover header -->\n <template\n v-if=\"hasSlotContent($slots.header)\"\n #header\n >\n <div ref=\"header\">\n <slot name=\"header\" />\n </div>\n </template>\n\n <!-- @slot slot for popover list -->\n <template #list>\n <div\n ref=\"list\"\n class=\"d-recipe-combobox-multi-select__list\"\n @mousedown.prevent\n >\n <slot\n v-if=\"!loading\"\n name=\"list\"\n />\n <div\n v-else\n class=\"d-recipe-combobox-multi-select__list--loading\"\n >\n {{ loadingMessage }}\n </div>\n </div>\n </template>\n\n <!-- @slot slot for popover footer -->\n <template\n v-if=\"hasSlotContent($slots.footer)\"\n #footer\n >\n <div ref=\"footer\">\n <slot name=\"footer\" />\n </div>\n </template>\n </dt-combobox-with-popover>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport DtComboboxWithPopover from '@/components/combobox_with_popover/combobox_with_popover.vue';\nimport DtInput from '@/components/input/input.vue';\nimport DtChip from '@/components/chip/chip.vue';\nimport DtValidationMessages from '@/components/validation_messages/validation_messages.vue';\nimport { validationMessageValidator } from '@/common/validators';\nimport { extractVueListeners, extractNonListeners, hasSlotContent, returnFirstEl } from '@/common/utils';\nimport {\n POPOVER_APPEND_TO_VALUES,\n} from '@/components/popover/popover_constants';\nimport {\n MULTI_SELECT_SIZES,\n CHIP_SIZES,\n CHIP_TOP_POSITION,\n} from './combobox_multi_select_constants';\n\nexport default {\n compatConfig: { MODE: 3 },\n name: 'DtComboboxMultiSelect',\n\n components: {\n DtComboboxWithPopover,\n DtInput,\n DtChip,\n DtValidationMessages,\n },\n\n inheritAttrs: false,\n\n props: {\n /**\n * String to use for the input label.\n */\n label: {\n type: String,\n required: true,\n },\n\n /**\n * Determines visibility of input label.\n * @values true, false\n */\n labelVisible: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Description for the input\n */\n description: {\n type: String,\n default: '',\n },\n\n /**\n * Input placeholder\n */\n placeholder: {\n type: String,\n default: 'Select one or start typing',\n },\n\n /**\n * Input validation messages\n */\n inputMessages: {\n type: Array,\n default: () => [],\n validator: inputMessages => {\n return validationMessageValidator(inputMessages);\n },\n },\n\n /**\n * Show input validation message\n */\n showInputMessages: {\n type: Boolean,\n default: true,\n },\n\n // @TODO: https://dialpad.atlassian.net/browse/DP-52324\n // type: {\n // type: String,\n // values: ['input', 'select'],\n // default: 'select',\n // },\n\n /**\n * Determines if the list is loading\n */\n loading: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The message when the list is loading\n */\n loadingMessage: {\n type: String,\n default: 'loading...',\n },\n\n /**\n * Determines when to show the list element and also controls the aria-expanded attribute.\n * Leaving this null will have the combobox trigger on input focus by default.\n * If you set this value, the default trigger behavior will be disabled and you can\n * control it as you need.\n */\n showList: {\n type: Boolean,\n default: null,\n },\n\n /**\n * Determines maximum height for the popover before overflow.\n * Possible units rem|px|em\n */\n listMaxHeight: {\n type: String,\n default: '300px',\n },\n\n /**\n * The selected items\n */\n selectedItems: {\n type: Array,\n default: function () { return []; },\n },\n\n /**\n * Would be the maximum number of selections you can make. 0 is unlimited\n */\n maxSelected: {\n type: Number,\n default: 0,\n },\n\n /**\n * Max select message when the max selections is exceeded with the structure:\n * `[{\"message\": string, \"type\": VALIDATION_MESSAGE_TYPES }]`\n */\n maxSelectedMessage: {\n type: Array,\n default: function () { return []; },\n },\n\n /**\n * Displays the list when the combobox is focused, before the user has typed anything.\n * When this is enabled the list will not close after selection.\n */\n hasSuggestionList: {\n type: Boolean,\n default: true,\n },\n\n /**\n * Size of the chip, one of `xs`, `sm`, `md`\n */\n size: {\n type: String,\n default: 'md',\n validator: (t) => Object.values(MULTI_SELECT_SIZES).includes(t),\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 * Named transition when the content display is toggled.\n * @see DtLazyShow\n */\n transition: {\n type: String,\n default: 'fade',\n },\n\n /**\n * Determines whether the combobox should collapse to a single when losing focus.\n * @type {boolean}\n */\n collapseOnFocusOut: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Determines maximum width for the popover before overflow.\n * Possible units rem|px|em\n */\n listMaxWidth: {\n type: String,\n default: '',\n },\n\n /**\n * Amount of reserved space (in px) on the right side of the input\n * before the chips and the input caret jump to the next line.\n * default is 64\n */\n reservedRightSpace: {\n type: Number,\n default: 64,\n },\n\n /**\n * Determines the maximum width of a single chip. If the text within this chip exceeds the value\n * it will be truncated with ellipses.\n * Possible units rem|px|em\n */\n chipMaxWidth: {\n type: String,\n default: '',\n },\n\n /**\n * Additional class name for the input element.\n * Can accept String, Object, and Array, i.e. has the\n * same API as Vue's built-in handling of the class attribute.\n */\n inputClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * Additional class name for the input wrapper element.\n * Can accept all of String, Object, and Array, i.e. has the\n * same api as Vue's built-in handling of the class attribute.\n */\n inputWrapperClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * When true, disables the underlying input.\n */\n disabled: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Additional class for the popover dialog element.\n */\n dialogClass: {\n type: [String, Object, Array],\n default: '',\n },\n },\n\n emits: [\n /**\n * Native input event\n *\n * @event input\n * @type {String }\n */\n 'input',\n\n /**\n * Event fired when item selected\n *\n * @event select\n * @type {Number}\n */\n 'select',\n\n /**\n * Event fired when item removed\n *\n * @event remove\n * @type {String}\n */\n 'remove',\n\n /**\n * Event fired when max selected items limit is reached\n *\n * @event max-selected\n * @type {Object}\n */\n 'max-selected',\n\n /**\n * Native keydown event fired when a key is pressed in the text input.\n * For the common Escape and Enter cases, listen to `escape` / `enter` instead.\n *\n * @event keydown\n * @type {KeyboardEvent}\n */\n 'keydown',\n\n /**\n * Native keydown event fired when a key is pressed while a chip is focused.\n *\n * @event chip-keydown\n * @type {KeyboardEvent}\n */\n 'chip-keydown',\n\n /**\n * Fired when Escape is pressed in the text input.\n * Not fired when a chip is focused.\n *\n * @event escape\n * @type {KeyboardEvent}\n */\n 'escape',\n\n /**\n * Fired when Enter is pressed in the text input.\n * Not fired when a chip is focused.\n *\n * @event enter\n * @type {KeyboardEvent}\n */\n 'enter',\n\n /**\n * Event fired when combobox item is highlighted\n *\n * @event combobox-highlight\n * @type {Object}\n */\n 'combobox-highlight',\n ],\n\n data () {\n return {\n value: '',\n popoverOffset: [0, 4],\n showValidationMessages: false,\n resizeWindowObserver: null,\n initialInputHeight: null,\n CHIP_SIZES,\n hasSlotContent,\n inputFocused: false,\n hideInputText: false,\n };\n },\n\n computed: {\n inputPlaceHolder () {\n return this.selectedItems?.length > 0 ? '' : this.placeholder;\n },\n\n chipListeners () {\n return {\n keydown: event => {\n if (this.disabled) return;\n this.onChipKeyDown(event);\n this.$emit('chip-keydown', event);\n },\n };\n },\n\n inputListeners () {\n return {\n ...extractVueListeners(this.$attrs),\n onInput: event => {\n this.$emit('input', event);\n if (this.hasSuggestionList) {\n this.showComboboxList();\n }\n },\n\n onKeydown: event => {\n if (this.disabled) return;\n this.onInputKeyDown(event);\n this.$emit('keydown', event);\n // Use event.key (not event.code) so NumpadEnter normalizes to 'Enter'\n // and consumers don't have to special-case the numpad.\n const key = event.key?.toLowerCase();\n if (key === 'escape') {\n this.$emit('escape', event);\n } else if (key === 'enter') {\n this.$emit('enter', event);\n }\n },\n\n onClick: () => {\n if (this.hasSuggestionList) {\n this.showComboboxList();\n }\n },\n };\n },\n\n chipWrapperClass () {\n return {\n [`d-recipe-combobox-multi-select__chip-wrapper-${this.size}--collapsed`]: !this.inputFocused && this.collapseOnFocusOut,\n };\n },\n },\n\n watch: {\n selectedItems: {\n deep: true,\n handler: async function () {\n await this.initSelectedItems();\n },\n },\n\n chipMaxWidth: {\n async handler () {\n await this.initSelectedItems();\n },\n },\n\n async label () {\n await this.$nextTick();\n // Adjust the chips position if label changed\n this.setChipsTopPosition();\n },\n\n async description () {\n await this.$nextTick();\n // Adjust the chips position if description changed\n this.setChipsTopPosition();\n },\n\n size: {\n async handler () {\n await this.$nextTick();\n const input = this.getInput();\n this.revertInputPadding(input);\n this.initialInputHeight = input.getBoundingClientRect().height;\n this.setInputPadding();\n this.setChipsTopPosition();\n },\n },\n },\n\n async mounted () {\n this.setInitialInputHeight();\n // Recalculate chip position and input padding when resizing window\n this.resizeWindowObserver = new ResizeObserver(async () => {\n this.setChipsTopPosition();\n this.setInputPadding();\n });\n this.resizeWindowObserver.observe(document.body);\n\n await this.initSelectedItems();\n },\n\n beforeUnmount () {\n this.resizeWindowObserver?.unobserve(document.body);\n },\n\n methods: {\n extractNonListeners,\n comboboxHighlight (highlightIndex) {\n this.$emit('combobox-highlight', highlightIndex);\n },\n\n async initSelectedItems () {\n await this.$nextTick();\n this.setInputPadding();\n this.setChipsTopPosition();\n this.setInputMinWidth();\n this.checkMaxSelected();\n },\n\n onChipRemove (item) {\n this.$emit('remove', item);\n this.$refs.input?.focus();\n },\n\n onComboboxSelect (i) {\n if (this.loading) return;\n this.value = '';\n this.$emit('select', i);\n },\n\n showComboboxList () {\n if (this.showList != null) { return; }\n this.$refs.comboboxWithPopover?.showComboboxList();\n },\n\n closeComboboxList () {\n if (this.showList != null) { return; }\n this.$refs.comboboxWithPopover?.closeComboboxList();\n },\n\n getChips () {\n if (!this.selectedItems.length || !this.$refs.chips) return null;\n\n // Use the order from selectedItems to not rely on DOM order which may be stale.\n // Track matched indices to handle duplicate item names correctly.\n const matched = new Set();\n const chips = this.selectedItems.map(item => {\n return this.$refs.chips.find((chip, index) => {\n if (matched.has(index)) return false;\n const chipLabel = returnFirstEl(chip.$el)?.querySelector('.d-chip__label')?.textContent?.trim();\n if (chipLabel === item) {\n matched.add(index);\n return true;\n }\n return false;\n });\n });\n return chips.filter(Boolean).map(chip => returnFirstEl(chip.$el));\n },\n\n getChipButtons () {\n const chips = this.getChips();\n return chips && chips.map(chip => returnFirstEl(chip).querySelector('button'));\n },\n\n getLastChipButton () {\n const chipButtons = this.getChipButtons();\n return chipButtons && chipButtons[chipButtons.length - 1];\n },\n\n getLastChip () {\n const chips = this.getChips();\n return chips && chips[chips.length - 1];\n },\n\n getFirstChip () {\n const chips = this.getChips();\n return chips && chips[0];\n },\n\n getInput () {\n return this.$refs.input?.$refs.input;\n },\n\n onChipKeyDown (event) {\n const key = event.code?.toLowerCase();\n if (key === 'arrowleft') {\n // Move to the previous chip\n this.navigateBetweenChips(event.target, true);\n } else if (key === 'arrowright') {\n if (event.target.id === this.getLastChipButton().id) {\n // Move to the input if it's the last chip\n this.moveFromChipToInput();\n } else {\n // Move to the next chip\n this.navigateBetweenChips(event.target, false);\n }\n }\n },\n\n onInputKeyDown (event) {\n const key = event.key?.toLowerCase();\n // If the cursor is at the start of the text,\n // press 'backspace' or 'left' focuses the last chip\n if (this.selectedItems.length > 0 && event.target.selectionStart === 0) {\n // if there is selected text, do not focus the last chip\n if (event.target.selectionEnd !== event.target.selectionStart) {\n return;\n }\n if (key === 'backspace' || key === 'arrowleft') {\n this.moveFromInputToChip();\n }\n }\n },\n\n moveFromInputToChip () {\n this.getLastChipButton().focus();\n this.$refs.input?.blur();\n this.closeComboboxList();\n },\n\n moveFromChipToInput () {\n this.getLastChipButton().blur();\n this.$refs.input?.focus();\n this.showComboboxList();\n },\n\n navigateBetweenChips (target, toLeft) {\n const from = this.getChipButtons().indexOf(target);\n const to = toLeft ? from - 1 : from + 1;\n if (to < 0 || to >= this.$refs.chips?.length) {\n return;\n }\n this.getChipButtons()[from].blur();\n this.getChipButtons()[to].focus();\n this.closeComboboxList();\n },\n\n setChipsTopPosition () {\n // To place the chips in the input box\n // The chip \"top\" position should be the same line as the input box\n const input = this.getInput();\n if (!input) return;\n const inputSlotWrapper = this.$refs.inputSlotWrapper;\n const top = input.getBoundingClientRect().top -\n inputSlotWrapper.getBoundingClientRect().top;\n const chipsWrapper = this.$refs.chipsWrapper;\n chipsWrapper.style.top = (top - CHIP_TOP_POSITION[this.size]) + 'px';\n },\n\n setInputPadding () {\n const lastChip = this.getLastChip();\n const input = this.getInput();\n const chipsWrapper = this.$refs.chipsWrapper;\n if (!input) return;\n this.revertInputPadding(input);\n this.popoverOffset = [0, 4];\n if (!lastChip) return;\n // Avoid adding extra padding when the input is not focused if collapseOnFocusOut is true\n // This ensures the input returns to its original state when resizing\n if (this.collapseOnFocusOut && !this.inputFocused) return;\n\n // Get the position of the last chip\n // The input cursor should be the same \"top\" as that chip and next besides it\n const left = lastChip.offsetLeft + this.getFullWidth(lastChip);\n const spaceLeft = input.getBoundingClientRect().width - left;\n // input.style.paddingLeft = left + 'px';\n\n if (spaceLeft > this.reservedRightSpace) {\n input.style.paddingLeft = left + 'px';\n } else {\n input.style.paddingLeft = '4px';\n }\n\n // Get the chip wrapper height minus the 4px padding\n const chipsWrapperHeight = chipsWrapper.getBoundingClientRect().height - 4;\n const lastChipHeight = lastChip.getBoundingClientRect().height - 4;\n\n // Get lastChip offsetTop plus 2px of the input padding.\n const top = spaceLeft > this.reservedRightSpace\n ? lastChip.offsetTop + 2\n : (chipsWrapperHeight + lastChipHeight - 9);\n\n input.style.paddingTop = `${top}px`;\n },\n\n revertInputPadding (input) {\n input.style.paddingLeft = '';\n input.style.paddingTop = '';\n input.style.paddingBottom = '';\n },\n\n getFullWidth (el) {\n const styles = window.getComputedStyle(el);\n return el.offsetWidth + parseInt(styles.marginLeft) + parseInt(styles.marginRight);\n },\n\n setInputMinWidth () {\n // Ensure the width of the input is \"slightly bigger\" than the width of a single chip\n const firstChip = this.getFirstChip();\n const input = this.getInput();\n if (!input) return;\n if (firstChip) {\n // Add 4px buffer for typing room\n input.style.minWidth = (this.getFullWidth(firstChip) + 4) + 'px';\n } else {\n input.style.minWidth = '';\n }\n },\n\n checkMaxSelected () {\n if (this.maxSelected === 0) return;\n if (this.selectedItems.length > this.maxSelected) {\n this.showValidationMessages = true;\n this.$emit('max-selected');\n } else {\n this.showValidationMessages = false;\n }\n },\n\n setInitialInputHeight () {\n const input = this.getInput();\n if (!input) return;\n this.initialInputHeight = input.getBoundingClientRect().height;\n },\n\n async handleInputFocusIn () {\n this.inputFocused = true;\n if (this.collapseOnFocusOut) {\n this.hideInputText = false;\n await this.$nextTick();\n this.setInputPadding();\n }\n },\n\n async handleInputFocusOut () {\n this.inputFocused = false;\n if (this.collapseOnFocusOut) {\n this.hideInputText = true;\n const input = this.getInput();\n if (!input) return;\n // Hide the input text when is not on first line\n if (!input.style.paddingTop) {\n return;\n }\n this.revertInputPadding(input);\n }\n },\n },\n};\n</script>\n"],"mappings":"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"}