@dialpad/dialtone 9.49.2 → 9.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/dialtone.css +2 -2
- package/dist/tokens/css/variables-dark.css +1 -1
- package/dist/tokens/css/variables-expressive-dark.css +1 -1
- package/dist/tokens/css/variables-expressive-light.css +1 -1
- package/dist/tokens/css/variables-expressive-sm-dark.css +1 -1
- package/dist/tokens/css/variables-expressive-sm-light.css +1 -1
- package/dist/tokens/css/variables-light.css +1 -1
- package/dist/tokens/css/variables-tmo-dark.css +1 -1
- package/dist/tokens/css/variables-tmo-light.css +1 -1
- package/dist/tokens/less/variables-dark.less +1 -1
- package/dist/tokens/less/variables-expressive-dark.less +1 -1
- package/dist/tokens/less/variables-expressive-light.less +1 -1
- package/dist/tokens/less/variables-expressive-sm-dark.less +1 -1
- package/dist/tokens/less/variables-expressive-sm-light.less +1 -1
- package/dist/tokens/less/variables-light.less +1 -1
- package/dist/tokens/less/variables-tmo-dark.less +1 -1
- package/dist/tokens/less/variables-tmo-light.less +1 -1
- package/dist/vue2/chunks/{dropdown-8L_PePwv.js → dropdown-6UoczdUY.js} +2 -2
- package/dist/vue2/chunks/{dropdown-8L_PePwv.js.map → dropdown-6UoczdUY.js.map} +1 -1
- package/dist/vue2/chunks/{dropdown-2D4i6Qkg.js → dropdown-pHxnQPzT.js} +2 -2
- package/dist/vue2/chunks/{dropdown-2D4i6Qkg.js.map → dropdown-pHxnQPzT.js.map} +1 -1
- package/dist/vue2/chunks/{popover_constants-kQaX7G4a.js → popover_constants-WsOUIY-m.js} +2 -2
- package/dist/vue2/chunks/{popover_constants-kQaX7G4a.js.map → popover_constants-WsOUIY-m.js.map} +1 -1
- package/dist/vue2/chunks/{popover_constants-qUYTzsS3.js → popover_constants-XnGWXaxX.js} +2 -2
- package/dist/vue2/chunks/{popover_constants-qUYTzsS3.js.map → popover_constants-XnGWXaxX.js.map} +1 -1
- package/dist/vue2/component-documentation.json +1 -1
- package/dist/vue2/dialtone-vue.cjs +2 -2
- package/dist/vue2/dialtone-vue.js +2 -2
- package/dist/vue2/lib/callbar-button-with-popover.cjs +1 -1
- package/dist/vue2/lib/callbar-button-with-popover.js +1 -1
- package/dist/vue2/lib/callbar-button.cjs +1 -1
- package/dist/vue2/lib/callbar-button.js +1 -1
- package/dist/vue2/lib/combobox-multi-select.cjs +1 -1
- package/dist/vue2/lib/combobox-multi-select.js +1 -1
- package/dist/vue2/lib/combobox-with-popover.cjs +1 -1
- package/dist/vue2/lib/combobox-with-popover.js +1 -1
- package/dist/vue2/lib/contact-row.cjs +1 -1
- package/dist/vue2/lib/contact-row.js +1 -1
- package/dist/vue2/lib/datepicker.cjs +1 -1
- package/dist/vue2/lib/datepicker.js +1 -1
- package/dist/vue2/lib/dropdown.cjs +2 -2
- package/dist/vue2/lib/dropdown.js +2 -2
- package/dist/vue2/lib/editor.cjs +1 -1
- package/dist/vue2/lib/editor.js +1 -1
- package/dist/vue2/lib/emoji-picker.cjs +24 -12
- package/dist/vue2/lib/emoji-picker.cjs.map +1 -1
- package/dist/vue2/lib/emoji-picker.js +24 -12
- package/dist/vue2/lib/emoji-picker.js.map +1 -1
- package/dist/vue2/lib/emoji-row.cjs +1 -1
- package/dist/vue2/lib/emoji-row.js +1 -1
- package/dist/vue2/lib/general-row.cjs +21 -4
- package/dist/vue2/lib/general-row.cjs.map +1 -1
- package/dist/vue2/lib/general-row.js +21 -4
- package/dist/vue2/lib/general-row.js.map +1 -1
- package/dist/vue2/lib/group-row.cjs +1 -1
- package/dist/vue2/lib/group-row.js +1 -1
- package/dist/vue2/lib/hovercard.cjs +1 -1
- package/dist/vue2/lib/hovercard.js +1 -1
- package/dist/vue2/lib/input.cjs +5 -3
- package/dist/vue2/lib/input.cjs.map +1 -1
- package/dist/vue2/lib/input.js +5 -3
- package/dist/vue2/lib/input.js.map +1 -1
- package/dist/vue2/lib/ivr-node.cjs +2 -2
- package/dist/vue2/lib/ivr-node.js +2 -2
- package/dist/vue2/lib/message-input.cjs +1 -1
- package/dist/vue2/lib/message-input.js +1 -1
- package/dist/vue2/lib/popover.cjs +50 -3
- package/dist/vue2/lib/popover.cjs.map +1 -1
- package/dist/vue2/lib/popover.js +51 -4
- package/dist/vue2/lib/popover.js.map +1 -1
- package/dist/vue2/lib/tooltip-directive.cjs +1 -1
- package/dist/vue2/lib/tooltip-directive.js +1 -1
- package/dist/vue2/lib/tooltip.cjs +1 -1
- package/dist/vue2/lib/tooltip.js +2 -2
- package/dist/vue2/style.css +64 -56
- package/dist/vue2/types/components/input/input.vue.d.ts +6 -4
- package/dist/vue2/types/components/input/input.vue.d.ts.map +1 -1
- package/dist/vue2/types/components/input/input_constants.d.ts +1 -0
- package/dist/vue2/types/components/popover/popover_constants.d.ts.map +1 -1
- package/dist/vue2/types/recipes/leftbar/general_row/general_row.vue.d.ts +23 -0
- package/dist/vue2/types/recipes/leftbar/general_row/general_row.vue.d.ts.map +1 -1
- package/dist/vue3/chunks/{dropdown-tVfEPEl1.js → dropdown-oA-_Gotg.js} +2 -2
- package/dist/vue3/chunks/{dropdown-tVfEPEl1.js.map → dropdown-oA-_Gotg.js.map} +1 -1
- package/dist/vue3/chunks/{dropdown-XFYig-ys.js → dropdown-p-Azgwov.js} +2 -2
- package/dist/vue3/chunks/{dropdown-XFYig-ys.js.map → dropdown-p-Azgwov.js.map} +1 -1
- package/dist/vue3/chunks/{popover_constants-kQaX7G4a.js → popover_constants-WsOUIY-m.js} +2 -2
- package/dist/vue3/chunks/{popover_constants-kQaX7G4a.js.map → popover_constants-WsOUIY-m.js.map} +1 -1
- package/dist/vue3/chunks/{popover_constants-qUYTzsS3.js → popover_constants-XnGWXaxX.js} +2 -2
- package/dist/vue3/chunks/{popover_constants-qUYTzsS3.js.map → popover_constants-XnGWXaxX.js.map} +1 -1
- package/dist/vue3/component-documentation.json +1 -1
- package/dist/vue3/dialtone-vue.cjs +2 -2
- package/dist/vue3/dialtone-vue.js +2 -2
- package/dist/vue3/lib/callbar-button-with-popover.cjs +1 -1
- package/dist/vue3/lib/callbar-button-with-popover.js +1 -1
- package/dist/vue3/lib/callbar-button.cjs +1 -1
- package/dist/vue3/lib/callbar-button.js +1 -1
- package/dist/vue3/lib/combobox-multi-select.cjs +1 -1
- package/dist/vue3/lib/combobox-multi-select.js +1 -1
- package/dist/vue3/lib/combobox-with-popover.cjs +1 -1
- package/dist/vue3/lib/combobox-with-popover.js +1 -1
- package/dist/vue3/lib/contact-row.cjs +1 -1
- package/dist/vue3/lib/contact-row.js +1 -1
- package/dist/vue3/lib/datepicker.cjs +1 -1
- package/dist/vue3/lib/datepicker.js +1 -1
- package/dist/vue3/lib/dropdown.cjs +2 -2
- package/dist/vue3/lib/dropdown.js +2 -2
- package/dist/vue3/lib/editor.cjs +1 -1
- package/dist/vue3/lib/editor.js +1 -1
- package/dist/vue3/lib/emoji-picker.cjs +50 -28
- package/dist/vue3/lib/emoji-picker.cjs.map +1 -1
- package/dist/vue3/lib/emoji-picker.js +50 -28
- package/dist/vue3/lib/emoji-picker.js.map +1 -1
- package/dist/vue3/lib/emoji-row.cjs +1 -1
- package/dist/vue3/lib/emoji-row.js +1 -1
- package/dist/vue3/lib/general-row.cjs +21 -4
- package/dist/vue3/lib/general-row.cjs.map +1 -1
- package/dist/vue3/lib/general-row.js +21 -4
- package/dist/vue3/lib/general-row.js.map +1 -1
- package/dist/vue3/lib/group-row.cjs +1 -1
- package/dist/vue3/lib/group-row.js +1 -1
- package/dist/vue3/lib/hovercard.cjs +1 -1
- package/dist/vue3/lib/hovercard.js +1 -1
- package/dist/vue3/lib/input.cjs +5 -3
- package/dist/vue3/lib/input.cjs.map +1 -1
- package/dist/vue3/lib/input.js +5 -3
- package/dist/vue3/lib/input.js.map +1 -1
- package/dist/vue3/lib/ivr-node.cjs +2 -2
- package/dist/vue3/lib/ivr-node.js +2 -2
- package/dist/vue3/lib/message-input.cjs +1 -1
- package/dist/vue3/lib/message-input.js +1 -1
- package/dist/vue3/lib/popover.cjs +50 -3
- package/dist/vue3/lib/popover.cjs.map +1 -1
- package/dist/vue3/lib/popover.js +51 -4
- package/dist/vue3/lib/popover.js.map +1 -1
- package/dist/vue3/lib/tooltip-directive.cjs +1 -1
- package/dist/vue3/lib/tooltip-directive.js +1 -1
- package/dist/vue3/lib/tooltip.cjs +1 -1
- package/dist/vue3/lib/tooltip.js +2 -2
- package/dist/vue3/style.css +64 -56
- package/dist/vue3/types/components/emoji_picker/modules/emoji_selector.vue.d.ts +1 -1
- package/dist/vue3/types/components/emoji_picker/modules/emoji_tabset.vue.d.ts +1 -1
- package/dist/vue3/types/components/emoji_picker/modules/emoji_tabset.vue.d.ts.map +1 -1
- package/dist/vue3/types/components/input/input.vue.d.ts +6 -4
- package/dist/vue3/types/components/input/input.vue.d.ts.map +1 -1
- package/dist/vue3/types/components/input/input_constants.d.ts +1 -0
- package/dist/vue3/types/components/popover/popover_constants.d.ts.map +1 -1
- package/dist/vue3/types/recipes/leftbar/general_row/general_row.vue.d.ts +23 -0
- package/dist/vue3/types/recipes/leftbar/general_row/general_row.vue.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emoji-picker.js","sources":["../../components/emoji_picker/modules/emoji_search.vue","../../components/emoji_picker/modules/emoji_tabset.vue","../../components/emoji_picker/emoji_picker_constants.js","../../components/emoji_picker/composables/useKeyboardNavigation.js","../../components/emoji_picker/modules/emoji_selector.vue","../../components/emoji_picker/modules/emoji_skin_selector.vue","../../components/emoji_picker/emoji_picker.vue"],"sourcesContent":["<template>\n <div class=\"d-emoji-picker__search d-emoji-picker__alignment\">\n <dt-input\n id=\"searchInput\"\n ref=\"searchInput\"\n :placeholder=\"searchPlaceholderLabel\"\n :model-value=\"modelValue\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n @keydown.up=\"$emit('focus-tabset')\"\n @keydown.down.prevent=\"$emit('focus-emoji-selector')\"\n @keydown.enter=\"$emit('select-first-emoji')\"\n >\n <template #leftIcon>\n <dt-icon\n name=\"search\"\n size=\"200\"\n />\n </template>\n <template\n v-if=\"modelValue.length > 0\"\n #rightIcon\n >\n <dt-button\n importance=\"clear\"\n kind=\"muted\"\n @click=\"clearSearch\"\n >\n <template #icon>\n <dt-icon\n name=\"x-circle\"\n size=\"200\"\n />\n </template>\n </dt-button>\n </template>\n </dt-input>\n </div>\n</template>\n\n<script setup>\nimport { DtInput } from '@/components/input';\nimport { DtIcon } from '@/components/icon';\nimport { DtButton } from '@/components/button';\nimport { onMounted, ref } from 'vue';\n\ndefineProps({\n searchPlaceholderLabel: {\n type: String,\n required: true,\n },\n modelValue: {\n type: String,\n default: '',\n },\n});\n\nconst emits = defineEmits(['update:modelValue', 'focus-emoji-selector', 'focus-tabset', 'select-first-emoji']);\n\nconst searchInput = ref(null);\n\nfunction clearSearch () {\n emits('update:modelValue', '');\n focusSearchInput();\n}\n\nfunction focusSearchInput () {\n searchInput.value.focus();\n}\nonMounted(() => {\n focusSearchInput();\n});\n\ndefineExpose({\n focusSearchInput,\n});\n</script>\n","<template>\n <div class=\"d-emoji-picker__tabset\">\n <dt-tab-group\n tab-list-class=\"d-emoji-picker__tabset-list\"\n :selected=\"selectedTab\"\n >\n <template #tabs>\n <dt-tab\n v-for=\"(tab, index) in tabs\"\n :id=\"tab.id\"\n :ref=\"el => { if (el) setTabsetRef(el) }\"\n :key=\"tab.id\"\n :panel-id=\"tab.panelId\"\n :label=\"tab.label\"\n aria-controls=\"d-emoji-picker-list\"\n :tabindex=\"index + 1\"\n @click.capture.stop=\"selectTabset(tab.id)\"\n @keydown=\"handleKeyDown($event, tab.id)\"\n >\n <dt-icon\n size=\"400\"\n :name=\"tab.icon\"\n />\n </dt-tab>\n </template>\n </dt-tab-group>\n </div>\n</template>\n\n<script setup>\nimport { computed, ref, toRefs, watch } from 'vue';\nimport { DtTab, DtTabGroup } from '@/components/tabs';\nimport { DtIcon } from '@/components/icon';\nimport { EMOJI_PICKER_CATEGORIES } from '@/components/emoji_picker';\n\nconst props = defineProps({\n /**\n * Whether to show the recently used tab or not\n * @type {Boolean}\n * @default false\n */\n showRecentlyUsedTab: {\n type: Boolean,\n default: false,\n },\n\n scrollIntoTab: {\n type: Number,\n required: true,\n },\n\n isScrolling: {\n type: Boolean,\n default: false,\n },\n\n emojiFilter: {\n type: String,\n default: '',\n },\n\n /**\n * The labels for the aria-label\n * @type {Array}\n * @required\n */\n tabsetLabels: {\n type: Array,\n required: true,\n },\n});\n\nconst emits = defineEmits([\n /**\n * Emitted when a tab is selected\n * @event selected-tabset\n * @param {String} tabId - The name of the tab that was selected\n */\n 'selected-tabset',\n\n 'focus-search-input',\n 'focus-skin-selector',\n]);\n\nconst TABS_DATA = [\n { label: EMOJI_PICKER_CATEGORIES.MOST_RECENTLY_USED, icon: 'clock' },\n { label: EMOJI_PICKER_CATEGORIES.SMILEYS_AND_PEOPLE, icon: 'satisfied' },\n { label: EMOJI_PICKER_CATEGORIES.NATURE, icon: 'living-thing' },\n { label: EMOJI_PICKER_CATEGORIES.FOOD, icon: 'food' },\n { label: EMOJI_PICKER_CATEGORIES.ACTIVITY, icon: 'object' },\n { label: EMOJI_PICKER_CATEGORIES.TRAVEL, icon: 'transportation' },\n { label: EMOJI_PICKER_CATEGORIES.OBJECTS, icon: 'lightbulb' },\n { label: EMOJI_PICKER_CATEGORIES.SYMBOLS, icon: 'heart' },\n { label: EMOJI_PICKER_CATEGORIES.FLAGS, icon: 'flag' },\n];\n\nconst tabs = computed(() => {\n const tabsData = props.showRecentlyUsedTab ? TABS_DATA : TABS_DATA.slice(1);\n\n return tabsData.map((tab, index) => ({\n ...tab,\n label: props.tabsetLabels[index],\n id: (index + 1).toString(),\n panelId: (index + 1).toString(),\n }));\n});\n\nconst isSearching = computed(() => props.emojiFilter.length > 0);\n\nconst selectedTab = ref('1');\n\nconst { isScrolling } = toRefs(props);\n\nconst tabsetRef = ref([]);\n\nwatch(() => props.scrollIntoTab,\n () => {\n if (!isScrolling.value && !isSearching.value) {\n selectedTab.value = (props.scrollIntoTab + 1).toString();\n }\n });\n\nwatch(isSearching,\n () => {\n if (isSearching.value) {\n selectedTab.value = null;\n }\n });\n\n/**\n * We are using .capture.stop modifiers on the click event\n * because we don't want to trigger the click event of the\n * dt-tab component\n */\nfunction selectTabset (id) {\n if (!isScrolling.value) {\n selectedTab.value = id;\n }\n emits('selected-tabset', id);\n}\n\nfunction setTabsetRef (ref) {\n // We push the $el, because $el is the button inside the dt-tab component\n // and we need the button to focus it\n tabsetRef.value.push(ref.$el);\n}\n\nfunction focusTabset () {\n tabsetRef.value[0].focus();\n}\n\nfunction handleKeyDown (event, tabId) {\n if (event.key === 'Enter') {\n selectTabset(tabId);\n // We blur because seems like the tab component override the selected prop, and it removes the selected style\n tabsetRef.value[tabId - 1].blur();\n }\n\n if (event.key === 'Tab') {\n event.preventDefault();\n if (event.shiftKey) {\n emits('focus-skin-selector');\n } else {\n emits('focus-search-input');\n }\n }\n\n if (event.key === 'ArrowDown') {\n // Jump to search input\n emits('focus-search-input');\n }\n}\n\ndefineExpose({\n focusTabset,\n});\n</script>\n","export const ARROW_KEYS = {\n ARROW_UP: 'ArrowUp',\n ARROW_DOWN: 'ArrowDown',\n ARROW_LEFT: 'ArrowLeft',\n ARROW_RIGHT: 'ArrowRight',\n};\n\nexport const CDN_URL = 'https://static.dialpadcdn.com/joypixels/png/unicode/32/';\nexport const EMOJIS_PER_ROW = 9;\nexport const EMOJI_PICKER_SKIN_TONE_MODIFIERS = {\n DEFAULT: 'Default',\n LIGHT: 'Light',\n MEDIUM_LIGHT: 'MediumLight',\n MEDIUM: 'Medium',\n MEDIUM_DARK: 'MediumDark',\n DARK: 'Dark',\n};\n\nexport const EMOJI_PICKER_CATEGORIES = {\n MOST_RECENTLY_USED: 'Most recently used',\n SMILEYS_AND_PEOPLE: 'Smileys and people',\n NATURE: 'Nature',\n FOOD: 'Food',\n ACTIVITY: 'Activity',\n TRAVEL: 'Travel',\n OBJECTS: 'Objects',\n SYMBOLS: 'Symbols',\n FLAGS: 'Flags',\n};\n\nexport default {\n EMOJI_PICKER_SKIN_TONE_MODIFIERS,\n EMOJI_PICKER_CATEGORIES,\n};\n","import { ref } from 'vue';\nimport { EMOJIS_PER_ROW, ARROW_KEYS } from '@/components/emoji_picker/emoji_picker_constants';\n\nexport function useKeyboardNavigation () {\n const emojiRefs = ref([]);\n const emojiFilteredRefs = ref([]);\n const isFiltering = ref(false);\n const hoverFirstEmoji = ref(true);\n\n function _handleArrowLeft (indexTab, indexEmoji) {\n if (!focusEmoji(indexTab, indexEmoji - 1)) {\n if (emojiRefs.value[indexTab - 1]) {\n focusEmoji(indexTab - 1, emojiRefs.value[indexTab - 1].length - 1);\n } else {\n focusEmoji(emojiRefs.value.length - 1, emojiRefs.value[emojiRefs.value.length - 1].length - 1);\n }\n }\n }\n\n function _handleArrowRight (indexTab, indexEmoji) {\n if (!focusEmoji(indexTab, indexEmoji + 1)) {\n if (!focusEmoji(indexTab + 1, 0)) {\n focusEmoji(0, 0);\n }\n }\n }\n\n function _handleArrowLeftFiltered (indexTab, indexEmoji) {\n if (!focusEmoji(0, indexEmoji - 1)) {\n focusEmoji(0, emojiFilteredRefs.value.length - 1);\n }\n }\n\n function _handleArrowRightFiltered (indexTab, indexEmoji) {\n if (!focusEmoji(0, indexEmoji + 1)) {\n focusEmoji(0, 0);\n }\n }\n\n function _handleHorizontalNavigation (direction, indexTab, indexEmoji) {\n if (isFiltering.value) {\n if (direction === 'left') {\n _handleArrowLeftFiltered(indexTab, indexEmoji);\n } else if (direction === 'right') {\n _handleArrowRightFiltered(indexTab, indexEmoji);\n }\n } else {\n if (direction === 'left') {\n _handleArrowLeft(indexTab, indexEmoji);\n } else if (direction === 'right') {\n _handleArrowRight(indexTab, indexEmoji);\n }\n }\n }\n\n function focusEmoji (indexTab, indexEmoji) {\n const emojiRef = isFiltering.value\n ? emojiFilteredRefs.value?.[indexEmoji]\n : emojiRefs.value?.[indexTab]?.[indexEmoji];\n\n if (emojiRef) {\n emojiRef.focus();\n return true;\n }\n\n return false;\n }\n\n function setEmojiRef (el, indexTab, indexEmoji) {\n if (!emojiRefs.value[indexTab]) {\n emojiRefs.value[indexTab] = [];\n }\n emojiRefs.value[indexTab][indexEmoji] = el;\n }\n\n function setFilteredRef (el, index) {\n emojiFilteredRefs.value[index] = el;\n }\n\n function handleArrowNavigationFiltered (key, indexEmoji) {\n hoverFirstEmoji.value = false;\n\n if (key === ARROW_KEYS.ARROW_UP) {\n const position = indexEmoji % EMOJIS_PER_ROW;\n\n if (!focusEmoji(0, indexEmoji - EMOJIS_PER_ROW)) {\n const lastEmojiPosition =\n emojiFilteredRefs.value.length - (emojiFilteredRefs.value.length % EMOJIS_PER_ROW) + position;\n\n focusEmoji(0, lastEmojiPosition);\n\n if (!focusEmoji(0, lastEmojiPosition)) {\n focusEmoji(0, emojiFilteredRefs.value.length - 1);\n }\n }\n }\n\n if (key === ARROW_KEYS.ARROW_DOWN) {\n if (!focusEmoji(0, indexEmoji + EMOJIS_PER_ROW)) {\n const position = indexEmoji % EMOJIS_PER_ROW;\n\n if (emojiFilteredRefs.value?.[indexEmoji + (EMOJIS_PER_ROW - position)]) {\n focusEmoji(0, emojiFilteredRefs.value.length - 1);\n } else {\n focusEmoji(0, position);\n }\n }\n }\n\n if (key === ARROW_KEYS.ARROW_LEFT) {\n _handleHorizontalNavigation('left', 0, indexEmoji);\n }\n\n if (key === ARROW_KEYS.ARROW_RIGHT) {\n _handleHorizontalNavigation('right', 0, indexEmoji);\n }\n }\n\n function handleArrowNavigation (key, indexTab, indexEmoji) {\n if (key === 'ArrowUp') {\n const position = indexEmoji % EMOJIS_PER_ROW;\n\n if (indexTab === 0) {\n // we are on the first emoji tab, then we should jump to the last row of the last emoji tab\n const numberOfMissingEmojis =\n EMOJIS_PER_ROW - (emojiRefs.value[emojiRefs.value.length - 1].length % EMOJIS_PER_ROW);\n\n const emojiToJump =\n emojiRefs.value[emojiRefs.value.length - 1].length + numberOfMissingEmojis - (EMOJIS_PER_ROW - position);\n\n if (!focusEmoji(emojiRefs.value.length - 1, emojiToJump)) {\n // if there is no emoji in this position, jump to the last emoji of the row\n focusEmoji(emojiRefs.value.length - 1, emojiRefs.value[emojiRefs.value.length - 1].length - 1);\n }\n return;\n }\n\n // if we are not on the first tab, we should jump to the previous row of the current tab\n if (!focusEmoji(indexTab, indexEmoji - EMOJIS_PER_ROW)) {\n // if there is no previous row, we should jump to emoji in the sampe position of the previous tab\n const previousTab = indexTab - 1 < 0 ? 0 : indexTab - 1;\n const emojisInPreviousTab = emojiRefs.value[previousTab].length;\n const lastEmojiPosition = emojisInPreviousTab - (emojisInPreviousTab % EMOJIS_PER_ROW) + position;\n\n if (!focusEmoji(previousTab, lastEmojiPosition)) {\n // if there is no emoji in this position, jump to the last emoji of the row\n focusEmoji(indexTab - 1, emojiRefs.value[indexTab - 1].length - 1);\n }\n }\n }\n\n if (key === 'ArrowDown') {\n if (!focusEmoji(indexTab, indexEmoji + EMOJIS_PER_ROW)) {\n // if cannot go down\n\n // Calculate position from cell 0 to cell 8\n const position = indexEmoji % EMOJIS_PER_ROW;\n\n // check if it exists a next row in the current tab\n if (emojiRefs.value?.[indexTab]?.[indexEmoji + (EMOJIS_PER_ROW - position)]) {\n // if it exists, we should focus the last emoji of the next row in the current tab\n focusEmoji(indexTab, emojiRefs.value[indexTab].length - 1);\n // if we are at the end of the list it will do nothing\n } else {\n // We don't have next row, we are in the last of the tab, then jump\n // to the next tab but in the equal emoji position in row 0.\n\n if (!focusEmoji(indexTab + 1, position)) {\n // We are on the bottom!, should jump to the same position emoji in the first row of the first tabset\n // if it doesn't has, jump to the last\n if (!focusEmoji(0, position)) {\n focusEmoji(0, emojiRefs.value[0].length - 1);\n }\n }\n }\n }\n }\n\n if (key === 'ArrowLeft') {\n _handleHorizontalNavigation('left', indexTab, indexEmoji);\n }\n\n if (key === 'ArrowRight') {\n _handleHorizontalNavigation('right', indexTab, indexEmoji);\n }\n }\n\n return {\n emojiFilteredRefs,\n isFiltering,\n hoverFirstEmoji,\n setEmojiRef,\n setFilteredRef,\n focusEmoji,\n handleArrowNavigationFiltered,\n handleArrowNavigation,\n };\n}\n","<template>\n <div\n class=\"d-emoji-picker__selector\"\n >\n <div\n id=\"d-emoji-picker-list\"\n ref=\"listRef\"\n class=\"d-emoji-picker__list\"\n >\n <p\n v-if=\"emojiFilter\"\n class=\"d-emoji-picker__search-label d-emoji-picker__alignment\"\n >\n {{ filteredEmojis.length > 0 ? searchResultsLabel : searchNoResultsLabel }}\n </p>\n <div\n v-else\n ref=\"tabCategoryRef\"\n class=\"d-emoji-picker__category d-emoji-picker__alignment\"\n >\n <p>\n {{ fixedLabel }}\n </p>\n </div>\n <div\n v-for=\"(tabLabel, indexTab) in tabLabels\"\n v-show=\"!emojiFilter\"\n :key=\"indexTab\"\n :ref=\"tabLabel.ref\"\n class=\"d-emoji-picker__alignment\"\n >\n <p\n v-if=\"indexTab\"\n >\n {{ tabLabel.label }}\n </p>\n <div\n class=\"d-emoji-picker__tab\"\n >\n <button\n v-for=\"(emoji, indexEmoji) in\n (emojis[tabs[indexTab] + skinTone] ? emojis[tabs[indexTab] + skinTone] : emojis[tabs[indexTab]])\"\n :key=\"emoji.shortname\"\n :ref=\"el => { if (el) setEmojiRef(el, indexTab, indexEmoji) }\"\n type=\"button\"\n :aria-label=\"emoji.name\"\n @click=\"selectEmoji(emoji)\"\n @focusin=\"highlightEmoji(emoji)\"\n @focusout=\"highlightEmoji(null)\"\n @mouseover=\"highlightEmoji(emoji)\"\n @mouseleave=\"highlightEmoji(null)\"\n @keydown=\"event => handleKeyDown(event, indexTab, indexEmoji, emoji)\"\n >\n <img\n class=\"d-icon d-icon--size-500\"\n :alt=\"emoji.name\"\n :aria-label=\"emoji.name\"\n :title=\"emoji.name\"\n :src=\"getImgSrc(emoji.unicode_character)\"\n @error=\"handleImageError\"\n >\n </button>\n </div>\n </div>\n <div\n v-if=\"emojiFilter\"\n class=\"d-emoji-picker__alignment\"\n >\n <div\n class=\"d-emoji-picker__tab \"\n data-qa=\"filtered-emojis\"\n >\n <button\n v-for=\"(emoji, index) in filteredEmojis\"\n :key=\"emoji.shortname\"\n :ref=\"el => { if (el) setFilteredRef(el, index) }\"\n type=\"button\"\n :aria-label=\"emoji.name\"\n :class=\"{\n 'hover-emoji': (index === 0 && hoverFirstEmoji),\n }\"\n @click=\"selectEmoji(emoji)\"\n @focusin=\"highlightEmoji(emoji)\"\n @focusout=\"highlightEmoji(null)\"\n @mouseover=\"hoverEmoji(emoji)\"\n @mouseleave=\"hoverEmoji(null)\"\n @keydown=\"event => handleKeyDownFilteredEmojis(event, index, emoji)\"\n >\n <img\n class=\"d-icon d-icon--size-500\"\n :alt=\"emoji.name\"\n :aria-label=\"emoji.name\"\n :title=\"emoji.name\"\n :src=\"`${CDN_URL + emoji.unicode_character}.png`\"\n >\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup>\n// eslint-disable max-len\nimport { emojisGrouped as emojis } from '@dialpad/dialtone-emojis';\nimport { computed, onMounted, onUnmounted, ref, watch, nextTick } from 'vue';\nimport { CDN_URL, ARROW_KEYS } from '@/components/emoji_picker/emoji_picker_constants';\nimport { useKeyboardNavigation } from '@/components/emoji_picker/composables/useKeyboardNavigation';\n\nconst props = defineProps({\n /**\n * The filter to apply to the emoji list\n * @type {String}\n * @default ''\n */\n emojiFilter: {\n type: String,\n default: '',\n },\n\n /**\n * The skin tone to apply to the emoji list\n * @type {String}\n * @required\n */\n skinTone: {\n type: String,\n required: true,\n },\n\n /**\n * The labels for the tabset\n * @type {Array}\n * @required\n */\n tabsetLabels: {\n type: Array,\n required: true,\n },\n\n selectedTabset: {\n type: Object,\n required: true,\n },\n\n /**\n * The label for the search results tab\n * @type {String}\n * @required\n */\n searchResultsLabel: {\n type: String,\n required: true,\n },\n\n searchNoResultsLabel: {\n type: String,\n required: true,\n },\n\n /**\n * The list of recently used emojis\n * @type {Array}\n */\n recentlyUsedEmojis: {\n type: Array,\n default: () => [],\n },\n});\n\nconst emits = defineEmits([\n /**\n * Emitted when the user hover over an emoji\n * @event highlighted-emoji\n * @param {Object} emoji - The emoji data that was hovered\n */\n 'highlighted-emoji',\n\n /**\n * Emitted when the user select an emoji\n * @event selected-emoji\n * @param {Object} emoji - The emoji data that was selected\n */\n 'selected-emoji',\n\n /**\n * Emitted when the user scroll into an emoji tab\n * @event scroll-into-tab\n * @param {Number} tab-index - The tab that was scrolled into\n */\n 'scroll-into-tab',\n\n /**\n * Emitted when the scrollTo function starts scrolling and stops scrolling\n * @event is-scrolling\n * @param {Boolean} is-scrolling - Whether the user is scrolling with the scroll-to\n */\n 'is-scrolling',\n\n /**\n * Emitted when the user reach the end of the emoji list\n * @event focus-skin-selector\n */\n 'focus-skin-selector',\n\n /**\n * Emitted when the user shift tab in first tab of emoji selector\n * @event focus-search-input\n */\n 'focus-search-input',\n]);\n\nconst {\n emojiFilteredRefs,\n isFiltering,\n hoverFirstEmoji,\n setEmojiRef,\n setFilteredRef,\n focusEmoji,\n handleArrowNavigationFiltered,\n handleArrowNavigation,\n} = useKeyboardNavigation();\n\n/**\n * The ref for the tab category\n * This is used to display the fixed label\n */\nconst tabCategoryRef = ref(null);\n\n/**\n * The ref for the list\n * This is used to display the tabs\n */\nconst listRef = ref(null);\n\n/**\n * The ref for the tab label observer\n * This is used to update the fixed label\n */\nconst tabLabelObserver = ref(null);\n\n/**\n * The list of tabs\n * This is used to display the tabs\n */\nconst TABS_DATA = ['Recently used', 'People', 'Nature', 'Food', 'Activity', 'Travel', 'Objects', 'Symbols', 'Flags'];\n\n/**\n * The list of tab labels\n * This is used to display the tabs\n * This is a computed property because it will check if the recently used emojis list is empty\n * If it is empty, it will remove the recently used tab\n */\nconst tabLabels = computed(() => {\n return props.recentlyUsedEmojis.length\n ? props.tabsetLabels.map((label) => ({ label, ref: ref(null) }))\n : props.tabsetLabels.slice(1).map((label) => ({ label, ref: ref(null) }));\n});\n\n/**\n * The label of the fixed tab\n * This is used to display the fixed label\n */\nconst fixedLabel = ref(tabLabels.value[0].label);\n\n/**\n * The list of tabs\n * This is used to display the tabs\n * This is a computed property because it will check if the recently used emojis list is empty\n * If it is empty, it will remove the recently used tab\n * The difference between this and the tab labels is that this one will set the structure of tabs\n * and the tab labels will set the labels\n */\nconst tabs = computed(() => {\n return props.recentlyUsedEmojis.length ? TABS_DATA : TABS_DATA.slice(1);\n});\n\n/**\n * The list of current emojis that match the filter\n * This will be updated when the emojiFilter changes\n * This is used to display the search results\n * The difference between this and the current emojis list is that this one will not have the skin tone applied\n */\nconst filteredEmojis = ref([]);\n\n/**\n * The current emojis list we are displaying\n * This will be updated when the skin tone changes\n * The difference between this and the emojis list is that this one will have only the skin tone applied\n */\nconst currentEmojis = computed(() => {\n return [\n ...emojis[`People${props.skinTone}`],\n ...emojis.Nature,\n ...emojis.Food,\n ...emojis[`Activity${props.skinTone}`],\n ...emojis.Travel,\n ...emojis[`Objects${props.skinTone}`],\n ...emojis.Symbols,\n ...emojis.Flags,\n ];\n});\n\n/**\n * This will trigger the searchByNameAndKeywords function with debounce of 300 milliseconds\n */\nconst debouncedSearch = debounce(() => {\n // We clean the emojiFilteredRefs to have an updated ref list for the search results\n emojiFilteredRefs.value = [];\n searchByNameAndKeywords();\n});\n\n/**\n * Update the current emojis list on skin tone changes\n * Also update the filtered emojis list\n * @listens skinTone\n */\nwatch(currentEmojis, () => {\n searchByNameAndKeywords();\n}, { immediate: true });\n\n/**\n * Update the recently used emojis list on recently used emojis prop changes\n * @listens recentlyUsedEmojis\n */\nwatch(() => props.recentlyUsedEmojis,\n () => {\n emojis['Recently used'] = props.recentlyUsedEmojis;\n }, { immediate: true });\n\n/**\n * Search for emojis by name and keywords\n * Will update the filtered emojis list on emojiFilter update\n * @listens emojiFilter\n */\nwatch(() => props.emojiFilter, () => {\n resetScroll();\n if (props.emojiFilter) {\n isFiltering.value = true;\n } else {\n isFiltering.value = false;\n // If the emoji filter is empty, emit null to remove the highlighted emoji\n // of the previous search\n highlightEmoji(null);\n }\n debouncedSearch();\n});\n\nwatch(\n () => props.selectedTabset,\n (tab) => {\n scrollToTab(tab.tabId);\n },\n { deep: true },\n);\n\nfunction hoverEmoji (emoji, isFirst = false) {\n hoverFirstEmoji.value = isFirst;\n emits('highlighted-emoji', emoji);\n}\n\n/**\n * Filters an array of emoji objects based on a search string that matches both the name and keywords.\n * Will update the filtered emojis list\n */\nfunction searchByNameAndKeywords () {\n const searchStr = props.emojiFilter.toLowerCase();\n filteredEmojis.value = currentEmojis.value.filter(obj => {\n const nameIncludesSearchStr = obj.name.toLowerCase().includes(searchStr);\n const keywordsIncludeSearchStr = obj.keywords.some(keyword => keyword.toLowerCase().includes(searchStr));\n return nameIncludesSearchStr || keywordsIncludeSearchStr;\n });\n nextTick(() => {\n if (searchStr) {\n hoverEmoji(filteredEmojis.value[0], true);\n }\n });\n}\n\nfunction debounce (fn, delay = 300) {\n let timeout;\n\n return (...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n };\n}\n\nfunction getImgSrc (emoji) {\n return `${CDN_URL + emoji}.png`;\n}\n\n/**\n * Handle image error - We hide the entire button if the image is not found\n */\nfunction handleImageError (event) {\n event.target.parentNode.style.display = 'none';\n}\n\n/**\n * Scroll to the selected tab\n */\nfunction scrollToTab (tabIndex, focusFirstEmoji = true) {\n const tabLabel = tabLabels.value[tabIndex - 1];\n const tabElement = tabLabel.ref.value[0];\n\n nextTick(() => {\n const container = listRef.value;\n const offsetTop = tabIndex === '1' ? 0 : tabElement.offsetTop - 20;\n\n /**\n * This variable is used to check if the user is scrolling inside the emoji picker\n * This is used to check if the user is scrolling using the scrollTo function\n * This is useful because this flag will prevent to update the fixed label when the user is scrolling\n * using the scrollTo function\n */\n let isScrolling = true;\n\n let prevScrollTop = container.scrollTop;\n emits('is-scrolling', true);\n\n /**\n * This event listener checks whether the user is scrolling up or down by comparing the current scrollTop\n * to prevScrollTop. If the scrollToTab function is scrolling from bottom to top and has reached the desired\n * position (scrollTop <= offsetTop),or if the scrollToTab function is scrolling from top to bottom and has\n * passed the desired position(scrollTop >= offsetTop), then isScrolling is set to false.\n */\n container.addEventListener('scroll', () => {\n if (isScrolling) {\n const scrollTop = container.scrollTop;\n if (\n (prevScrollTop < scrollTop && scrollTop >= offsetTop) ||\n (prevScrollTop > scrollTop && scrollTop <= offsetTop)\n ) {\n isScrolling = false;\n emits('is-scrolling', false);\n }\n prevScrollTop = scrollTop;\n }\n });\n\n container.scrollTop = offsetTop;\n\n if (focusFirstEmoji) {\n focusEmoji((tabIndex - 1), 0);\n }\n });\n}\n\nfunction resetScroll () {\n const container = listRef.value;\n\n container.scrollTop = 0;\n}\n\n/**\n * This code creates an IntersectionObserver object that monitors the intersection between\n * the root element (tabCategoryRef) and its targets (the child elements of listRef),\n * and updates the value of the fixedLabel variable accordingly.\n */\nfunction setTabLabelObserver () {\n /**\n * The code extracts the target element and its index from the IntersectionObserverEntry object,\n * and checks whether the target intersects with the root and is positioned above or below it.\n */\n tabLabelObserver.value = new IntersectionObserver(entries => {\n entries.forEach(entry => {\n const { target } = entry;\n const index = parseInt(target.dataset.index);\n\n /**\n * If the target is positioned above the root,\n * the code updates the value of the fixed label to the label of the previous tab,\n * or the first tab if the current tab is the first one. If the target is positioned below the root, the code\n * updates the value of the fixed label to the label of the current tab.\n * If the target stops intersecting with the root and its index is 1 (the second tab),\n * the code updates the value of the fixed label to the label of the first tab.\n * NOTES:\n * This last condition is needed because sometimes it is\n * not detect the intersection between the root and the target.\n * We also provide a 50 pixels offset to the root element in the first condition to always get the\n * first tab if it has fewer emojis, because in some cases if you quickly scroll the observer does not detect it.\n */\n if (entry.isIntersecting && target.offsetTop <= tabCategoryRef.value.offsetTop + 50) {\n fixedLabel.value = tabLabels.value[index - 1]?.label ?? tabLabels.value[0]?.label;\n emits('scroll-into-tab', index - 1);\n } else if (entry.boundingClientRect.bottom <= tabCategoryRef.value?.getBoundingClientRect().bottom) {\n emits('scroll-into-tab', index);\n fixedLabel.value = tabLabels.value[index]?.label;\n } else if (index === 1) {\n emits('scroll-into-tab', index);\n fixedLabel.value = tabLabels.value[0]?.label;\n }\n });\n });\n\n /**\n * The tabLabelObserver is set to observe the root element and all its children elements with\n * the IntersectionObserver object, and sets their data-index attribute to their index.\n */\n tabLabelObserver.value.observe(tabCategoryRef.value);\n\n Array.from(listRef.value.children).forEach((child, index) => {\n tabLabelObserver.value.observe(child);\n child.dataset.index = index;\n });\n}\n\nconst handleKeyDownFilteredEmojis = (event, indexEmoji, emoji) => {\n event.preventDefault();\n\n if (Object.values(ARROW_KEYS).includes(event.key)) {\n handleArrowNavigationFiltered(event.key, indexEmoji);\n return;\n }\n\n switch (event.key) {\n case 'Tab':\n emits('focus-skin-selector');\n break;\n case 'Enter':\n selectEmoji(emoji);\n break;\n default:\n break;\n }\n};\n\nconst handleKeyDown = (event, indexTab, indexEmoji, emoji) => {\n event.preventDefault();\n\n if (Object.values(ARROW_KEYS).includes(event.key)) {\n handleArrowNavigation(event.key, indexTab, indexEmoji);\n return;\n }\n\n switch (event.key) {\n case 'Tab':\n if (event.shiftKey) {\n if (focusEmoji(indexTab, 0) && indexTab > 0) {\n scrollToTab(indexTab, true);\n } else {\n scrollToTab(1, false);\n emits('focus-search-input');\n }\n } else {\n if (focusEmoji(indexTab + 1, 0)) {\n scrollToTab(indexTab + 1 + 1, false);\n } else {\n // We are on the last emoji tabset, jump to the skin selector\n emits('focus-skin-selector');\n }\n }\n break;\n\n case 'Enter':\n selectEmoji(emoji);\n break;\n\n default:\n break;\n }\n};\n\nfunction selectEmoji (emoji) {\n emits('selected-emoji', emoji);\n}\n\nfunction highlightEmoji (emoji) {\n emits('highlighted-emoji', emoji);\n}\n\nfunction focusEmojiSelector () {\n focusEmoji(0, 0);\n}\n\nfunction focusLastEmoji () {\n focusEmoji(tabs.value.length - 1, 0);\n}\n\nonMounted(() => {\n setTabLabelObserver();\n});\n\nonUnmounted(() => {\n tabLabelObserver.value.disconnect();\n});\n\ndefineExpose({\n focusEmojiSelector,\n focusLastEmoji,\n});\n</script>\n","<template>\n <div data-qa=\"skin-selector\">\n <div\n v-show=\"isOpen\"\n class=\"d-emoji-picker__skin-list\"\n >\n <button\n v-for=\"(skin, index) in skinList\"\n :ref=\"el => { if (el) setSkinsRef(el) }\"\n :key=\"skin.name\"\n :class=\"{\n 'selected': skinSelected.skinCode === skin.skinCode,\n }\"\n @keydown=\"event => handleKeyDown(event, skin, index)\"\n @click=\"selectSkin(skin)\"\n >\n <img\n class=\"d-icon d-icon--size-500\"\n :alt=\"skin.name\"\n :aria-label=\"skin.name\"\n :title=\"skin.name\"\n :src=\"`${CDN_URL + skin.unicode_output}.png`\"\n >\n </button>\n </div>\n <div\n v-show=\"!isOpen\"\n class=\"d-emoji-picker__skin-selected\"\n >\n <dt-tooltip placement=\"top-end\">\n {{ skinSelectorButtonTooltipLabel }}\n <template #anchor>\n <button\n ref=\"skinSelectorRef\"\n :aria-label=\"skinSelectorButtonTooltipLabel\"\n tabindex=\"-1\"\n @click=\"toggleSkinList\"\n @keydown=\"event => handleKeyDown(event)\"\n >\n <img\n class=\"d-icon d-icon--size-500\"\n :alt=\"skinSelected.name\"\n :aria-label=\"skinSelected.name\"\n :title=\"skinSelected.name\"\n :src=\"`${CDN_URL + skinSelected.unicode_output}.png`\"\n >\n </button>\n </template>\n </dt-tooltip>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { computed, nextTick, ref, watchEffect } from 'vue';\nimport { CDN_URL, EMOJI_PICKER_SKIN_TONE_MODIFIERS } from '@/components/emoji_picker';\nimport { DtTooltip } from '@/components/tooltip';\n\nconst props = defineProps({\n /**\n * The skin tone to apply to the emoji list\n * @type {String}\n * @required\n */\n skinTone: {\n type: String,\n required: true,\n },\n\n isHovering: {\n type: Boolean,\n default: false,\n },\n\n skinSelectorButtonTooltipLabel: {\n type: String,\n required: true,\n },\n});\n\nconst emits = defineEmits([\n /**\n * The skin tone that was selected\n * @event skin-tone\n * @type {Number}\n */\n 'skin-tone',\n 'focus-tabset',\n 'focus-last-emoji',\n]);\n\nconst skinList = [\n {\n name: ':wave_tone1:',\n unicode_output: '1f44b-1f3fb',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.LIGHT,\n skinCode: '_tone1',\n },\n {\n name: ':wave_tone2:',\n unicode_output: '1f44b-1f3fc',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.MEDIUM_LIGHT,\n skinCode: '_tone2',\n },\n {\n name: ':wave_tone3:',\n unicode_output: '1f44b-1f3fd',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.MEDIUM,\n skinCode: '_tone3',\n },\n {\n name: ':wave_tone4:',\n unicode_output: '1f44b-1f3fe',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.MEDIUM_DARK,\n skinCode: '_tone4',\n },\n {\n name: ':wave_tone5:',\n unicode_output: '1f44b-1f3ff',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.DARK,\n skinCode: '_tone5',\n },\n {\n name: ':wave:',\n unicode_output: '1f44b',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.DEFAULT,\n skinCode: '',\n },\n];\n\nconst isOpen = ref(false);\n\nconst skinSelectorRef = ref(null);\n\nconst skinsRef = ref([]);\n\n/**\n * It will close the skin selector if the user is hovering over the emoji list\n */\nwatchEffect(\n () => props.isHovering && (isOpen.value = false),\n);\n\n/**\n * It will initially display props.skinTone. If a new skin tone is selected,\n * it will display that until props.skinTone changes.\n */\nconst skinPassedIn = computed(() => skinList.find((skin) => skin.skinTone === props.skinTone));\nconst skinSelected = ref(skinPassedIn.value);\nwatchEffect(() => skinPassedIn.value && (skinSelected.value = skinPassedIn.value));\n\nfunction setSkinsRef (ref) {\n skinsRef.value.push(ref);\n}\nfunction focusSkinSelector () {\n skinSelectorRef.value.focus();\n}\n\nfunction selectSkin (skin) {\n skinSelected.value = skin;\n isOpen.value = false;\n emits('skin-tone', skin.skinTone);\n nextTick(() => focusSkinSelector());\n}\n\nconst handleKeyDown = (event, skin, index) => {\n event.preventDefault();\n\n if (event.key === 'ArrowLeft') {\n if (index === 0) skinsRef.value[skinsRef.value.length - 1]?.focus();\n skinsRef.value[index - 1]?.focus();\n }\n\n if (event.key === 'ArrowRight') {\n skinsRef.value[index + 1]?.focus();\n }\n\n if (event.key === 'Enter') {\n if (skin) { selectSkin(skin); } else {\n toggleSkinList();\n }\n }\n\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n emits('focus-last-emoji');\n } else {\n emits('focus-tabset');\n }\n }\n};\n\nfunction toggleSkinList () {\n isOpen.value = !isOpen.value;\n nextTick(() => skinsRef.value[0].focus());\n}\n\ndefineExpose({\n focusSkinSelector,\n});\n</script>\n","<template>\n <div\n class=\"d-emoji-picker\"\n >\n <div class=\"d-emoji-picker--header\">\n <emoji-tabset\n ref=\"tabsetRef\"\n :emoji-filter=\"internalSearchQuery\"\n :show-recently-used-tab=\"showRecentlyUsedTab\"\n :scroll-into-tab=\"scrollIntoTab\"\n :tabset-labels=\"tabSetLabels\"\n :is-scrolling=\"isScrolling\"\n @focus-search-input=\"$refs.searchInputRef.focusSearchInput()\"\n @focus-skin-selector=\"$refs.skinSelectorRef.focusSkinSelector()\"\n @selected-tabset=\"scrollToSelectedTabset\"\n @keydown.esc=\"emits('close')\"\n />\n </div>\n <div class=\"d-emoji-picker--body\">\n <emoji-search\n v-if=\"showSearch\"\n ref=\"searchInputRef\"\n v-model=\"internalSearchQuery\"\n :search-placeholder-label=\"searchPlaceholderLabel\"\n @select-first-emoji=\"emits('selected-emoji', highlightedEmoji)\"\n @focus-tabset=\"$refs.tabsetRef.focusTabset()\"\n @focus-emoji-selector=\"$refs.emojiSelectorRef.focusEmojiSelector()\"\n @keydown.esc=\"emits('close')\"\n />\n <emoji-selector\n ref=\"emojiSelectorRef\"\n :emoji-filter=\"internalSearchQuery\"\n :skin-tone=\"skinTone\"\n :tabset-labels=\"tabSetLabels\"\n :search-results-label=\"searchResultsLabel\"\n :search-no-results-label=\"searchNoResultsLabel\"\n :recently-used-emojis=\"recentlyUsedEmojis\"\n :selected-tabset=\"selectedTabset\"\n @scroll-into-tab=\"updateScrollIntoTab\"\n @is-scrolling=\"updateIsScrolling\"\n @highlighted-emoji=\"updateHighlightedEmoji\"\n @selected-emoji=\"emits('selected-emoji', $event)\"\n @focus-skin-selector=\"$refs.skinSelectorRef.focusSkinSelector()\"\n @focus-search-input=\"$refs.searchInputRef.focusSearchInput()\"\n @keydown.esc=\"emits('close')\"\n />\n </div>\n <div class=\"d-emoji-picker--footer\">\n <emoji-description :emoji=\"highlightedEmoji\" />\n <emoji-skin-selector\n ref=\"skinSelectorRef\"\n :is-hovering=\"!!highlightedEmoji\"\n :skin-selector-button-tooltip-label=\"skinSelectorButtonTooltipLabel\"\n :skin-tone=\"skinTone\"\n @skin-tone=\"emits('skin-tone', $event)\"\n @focus-tabset=\"$refs.tabsetRef.focusTabset()\"\n @focus-last-emoji=\"$refs.emojiSelectorRef.focusLastEmoji()\"\n @keydown.esc=\"emits('close')\"\n />\n </div>\n </div>\n</template>\n\n<script setup>\nimport EmojiSearch from './modules/emoji_search.vue';\nimport EmojiTabset from './modules/emoji_tabset.vue';\nimport EmojiSelector from './modules/emoji_selector.vue';\nimport EmojiSkinSelector from './modules/emoji_skin_selector.vue';\nimport EmojiDescription from './modules/emoji_description.vue';\nimport { computed, ref, watch } from 'vue';\n\nconst props = defineProps({\n /**\n * The array with recently used emoji object\n * This list is necessary to fill the recently used tab\n * @type {Array}\n * @default []\n * @example\n * <dt-emoji-picker :recentlyUsedEmojis=\"[emojiObject, emojiObject]\" />\n */\n // TODO try to simplify this to achieve an array of unicode characters and not an entire emoji data object\n recentlyUsedEmojis: {\n type: Array,\n default: () => ([]),\n },\n\n /**\n * The placeholder text for the search input\n * @type {String}\n * @required\n * @example\n * <dt-emoji-picker :searchPlaceholderLabel=\"'Search...'\" />\n */\n searchPlaceholderLabel: {\n type: String,\n required: true,\n },\n\n /**\n * The label for the search results tab\n * @type {String}\n * @required\n * @example\n * <dt-emoji-picker :searchResultsLabel=\"'Search results'\" />\n */\n searchResultsLabel: {\n type: String,\n required: true,\n },\n\n /**\n * The label for the search no results\n * @type {String}\n * @required\n * @example\n * <dt-emoji-picker :searchNoResultsLabel=\"'No results'\" />\n */\n searchNoResultsLabel: {\n type: String,\n required: true,\n },\n\n /**\n * The list of tabsets to show, it is necessary to be updated with the correct language\n * It must respect the provided order.\n * @type {Array}\n * @required\n * @example\n * <dt-emoji-picker\n * :tabSetLabels=\"['Most recently used', 'Smileys and people', 'Nature',\n * 'Food', 'Activity', 'Travel', 'Objects', 'Symbols', 'Flags']\" />\n */\n tabSetLabels: {\n type: Array,\n required: true,\n },\n\n /**\n * The skin tone to show the emojis\n * This prop gives the possibility to use the skin tone selected by the user previously\n * @type {String}\n * @default 'Default'\n * @values 'Default', 'Light', 'MediumLight', 'Medium', 'MediumDark', 'Dark'\n * @example\n * <dt-emoji-picker :skinTone=\"'Default'\" />\n */\n skinTone: {\n type: String,\n default: 'Default',\n },\n\n /**\n * Tooltip shown when skin selector button is hovered.\n * @type {String}\n * @required\n * @example\n * <dt-emoji-picker :skin-selector-button-tooltip-label=\"'Change default skin tone'\" />\n */\n skinSelectorButtonTooltipLabel: {\n type: String,\n required: true,\n },\n\n /**\n * Sets the search query that filters emojis.\n * @type {String}\n * @example\n * <dt-emoji-picker search-query=\"smile\" />\n */\n searchQuery: {\n type: String,\n default: '',\n },\n\n /**\n * Shows the search input\n * @type {Boolean}\n * @example\n * <dt-emoji-picker :show-search=\"false\" />\n */\n showSearch: {\n type: Boolean,\n default: true,\n },\n});\n\nconst emits = defineEmits(\n [\n /**\n * It will emit the selected emoji\n * @event selected-emoji\n * @param {Object} emoji - The selected emoji from the emoji selector\n */\n 'selected-emoji',\n\n /**\n * It will emit the selected skin tone\n * @event skin-tone\n * @param {String} skin - The selected skin tone from the skin selector\n */\n 'skin-tone',\n\n /**\n * Since the keyboard events are encapsulated, we emit this event to close the picker\n * @event close\n */\n 'close',\n ],\n);\n\nconst internalSearchQuery = ref(props.searchQuery.value);\nconst highlightedEmoji = ref(null);\nconst selectedTabset = ref({});\n\nconst scrollIntoTab = ref(0);\nconst isScrolling = ref(false);\n\nconst showRecentlyUsedTab = computed(() => props.recentlyUsedEmojis.length > 0);\n\nwatch(\n () => props.searchQuery,\n (newValue) => {\n internalSearchQuery.value = newValue;\n },\n);\n\n/**\n * Handle the selected tabset event\n * We're creating a new object with the same value as selectedTabset and assigning it back to selectedTabset.\n * Vue will see this as a new object and trigger the watcher in the child component.\n * Using this method, we are able to trigger the watcher in the child component even if the value being passed is the\n * same as the previous value.\n * @event selectedTabset\n * @param tabName {String} - The name of the tab that was selected\n */\nfunction scrollToSelectedTabset (tabId) {\n internalSearchQuery.value = '';\n selectedTabset.value = tabId;\n selectedTabset.value = { ...selectedTabset.value, tabId };\n}\n\nfunction updateScrollIntoTab (value) {\n scrollIntoTab.value = value;\n}\n\nfunction updateIsScrolling (value) {\n isScrolling.value = value;\n}\nfunction updateHighlightedEmoji (emoji) {\n highlightedEmoji.value = emoji;\n}\n</script>\n"],"names":["ref","emojis"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"emoji-picker.js","sources":["../../components/emoji_picker/modules/emoji_search.vue","../../components/emoji_picker/modules/emoji_tabset.vue","../../components/emoji_picker/emoji_picker_constants.js","../../components/emoji_picker/composables/useKeyboardNavigation.js","../../components/emoji_picker/modules/emoji_selector.vue","../../components/emoji_picker/modules/emoji_skin_selector.vue","../../components/emoji_picker/emoji_picker.vue"],"sourcesContent":["<template>\n <div class=\"d-emoji-picker__search d-emoji-picker__alignment\">\n <dt-input\n id=\"searchInput\"\n ref=\"searchInput\"\n :placeholder=\"searchPlaceholderLabel\"\n :model-value=\"modelValue\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n @keydown.up=\"$emit('focus-tabset')\"\n @keydown.down.prevent=\"$emit('focus-emoji-selector')\"\n @keydown.enter=\"$emit('select-first-emoji')\"\n >\n <template #leftIcon>\n <dt-icon\n name=\"search\"\n size=\"200\"\n />\n </template>\n <template\n v-if=\"modelValue.length > 0\"\n #rightIcon\n >\n <dt-button\n importance=\"clear\"\n kind=\"muted\"\n @click=\"clearSearch\"\n >\n <template #icon>\n <dt-icon\n name=\"x-circle\"\n size=\"200\"\n />\n </template>\n </dt-button>\n </template>\n </dt-input>\n </div>\n</template>\n\n<script setup>\nimport { DtInput } from '@/components/input';\nimport { DtIcon } from '@/components/icon';\nimport { DtButton } from '@/components/button';\nimport { onMounted, ref } from 'vue';\n\ndefineProps({\n searchPlaceholderLabel: {\n type: String,\n required: true,\n },\n modelValue: {\n type: String,\n default: '',\n },\n});\n\nconst emits = defineEmits(['update:modelValue', 'focus-emoji-selector', 'focus-tabset', 'select-first-emoji']);\n\nconst searchInput = ref(null);\n\nfunction clearSearch () {\n emits('update:modelValue', '');\n focusSearchInput();\n}\n\nfunction focusSearchInput () {\n searchInput.value.focus();\n}\nonMounted(() => {\n focusSearchInput();\n});\n\ndefineExpose({\n focusSearchInput,\n});\n</script>\n","<template>\n <div class=\"d-emoji-picker__tabset\">\n <dt-tab-group\n tab-list-class=\"d-emoji-picker__tabset-list\"\n :selected=\"selectedTab\"\n >\n <template #tabs>\n <dt-tab\n v-for=\"(tab, index) in tabs\"\n :id=\"tab.id\"\n :ref=\"el => { if (el) setTabsetRef(el) }\"\n :key=\"tab.id\"\n :panel-id=\"tab.panelId\"\n :label=\"tab.label\"\n aria-controls=\"d-emoji-picker-list\"\n :tabindex=\"index + 1\"\n @click.capture.stop=\"selectTabset(tab.id)\"\n @keydown=\"handleKeyDown($event, tab.id)\"\n >\n <dt-icon\n size=\"400\"\n :name=\"tab.icon\"\n />\n </dt-tab>\n </template>\n </dt-tab-group>\n </div>\n</template>\n\n<script setup>\nimport { computed, ref, toRefs, watch } from 'vue';\nimport { DtTab, DtTabGroup } from '@/components/tabs';\nimport { DtIcon } from '@/components/icon';\nimport { EMOJI_PICKER_CATEGORIES } from '@/components/emoji_picker';\n\nconst props = defineProps({\n /**\n * Whether to show the recently used tab or not\n * @type {Boolean}\n * @default false\n */\n showRecentlyUsedTab: {\n type: Boolean,\n default: false,\n },\n\n scrollIntoTab: {\n type: Number,\n required: true,\n },\n\n isScrolling: {\n type: Boolean,\n default: false,\n },\n\n emojiFilter: {\n type: String,\n default: '',\n },\n\n /**\n * The labels for the aria-label\n * @type {Array}\n * @required\n */\n tabsetLabels: {\n type: Array,\n required: true,\n },\n});\n\nconst emits = defineEmits([\n /**\n * Emitted when a tab is selected\n * @event selected-tabset\n * @param {String} tabId - The name of the tab that was selected\n */\n 'selected-tabset',\n\n 'shift-tab-key-pressed',\n 'tab-key-pressed',\n 'arrow-down-key-pressed',\n]);\n\nconst TABS_DATA = [\n { label: EMOJI_PICKER_CATEGORIES.MOST_RECENTLY_USED, icon: 'clock' },\n { label: EMOJI_PICKER_CATEGORIES.SMILEYS_AND_PEOPLE, icon: 'satisfied' },\n { label: EMOJI_PICKER_CATEGORIES.NATURE, icon: 'living-thing' },\n { label: EMOJI_PICKER_CATEGORIES.FOOD, icon: 'food' },\n { label: EMOJI_PICKER_CATEGORIES.ACTIVITY, icon: 'object' },\n { label: EMOJI_PICKER_CATEGORIES.TRAVEL, icon: 'transportation' },\n { label: EMOJI_PICKER_CATEGORIES.OBJECTS, icon: 'lightbulb' },\n { label: EMOJI_PICKER_CATEGORIES.SYMBOLS, icon: 'heart' },\n { label: EMOJI_PICKER_CATEGORIES.FLAGS, icon: 'flag' },\n];\n\nconst tabs = computed(() => {\n const tabsData = props.showRecentlyUsedTab ? TABS_DATA : TABS_DATA.slice(1);\n\n return tabsData.map((tab, index) => ({\n ...tab,\n label: props.tabsetLabels[index],\n id: (index + 1).toString(),\n panelId: (index + 1).toString(),\n }));\n});\n\nconst isSearching = computed(() => props.emojiFilter.length > 0);\n\nconst selectedTab = ref('1');\n\nconst { isScrolling } = toRefs(props);\n\nconst tabsetRef = ref([]);\n\nwatch(() => props.scrollIntoTab,\n () => {\n if (!isScrolling.value && !isSearching.value) {\n selectedTab.value = (props.scrollIntoTab + 1).toString();\n }\n });\n\nwatch(isSearching,\n () => {\n if (isSearching.value) {\n selectedTab.value = null;\n }\n });\n\n/**\n * We are using .capture.stop modifiers on the click event\n * because we don't want to trigger the click event of the\n * dt-tab component\n */\nfunction selectTabset (id) {\n if (!isScrolling.value) {\n selectedTab.value = id;\n }\n emits('selected-tabset', id);\n}\n\nfunction setTabsetRef (ref) {\n // We push the $el, because $el is the button inside the dt-tab component\n // and we need the button to focus it\n tabsetRef.value.push(ref.$el);\n}\n\nfunction focusTabset () {\n tabsetRef.value[0].focus();\n}\n\nfunction handleKeyDown (event, tabId) {\n if (event.key === 'Enter') {\n selectTabset(tabId);\n // We blur because seems like the tab component override the selected prop, and it removes the selected style\n tabsetRef.value[tabId - 1].blur();\n }\n\n if (event.key === 'Tab') {\n event.preventDefault();\n if (event.shiftKey) {\n emits('shift-tab-key-pressed');\n } else {\n emits('tab-key-pressed');\n }\n }\n\n if (event.key === 'ArrowDown') {\n // Jump to search input\n emits('arrow-down-key-pressed');\n }\n}\n\ndefineExpose({\n focusTabset,\n});\n</script>\n","export const ARROW_KEYS = {\n ARROW_UP: 'ArrowUp',\n ARROW_DOWN: 'ArrowDown',\n ARROW_LEFT: 'ArrowLeft',\n ARROW_RIGHT: 'ArrowRight',\n};\n\nexport const CDN_URL = 'https://static.dialpadcdn.com/joypixels/png/unicode/32/';\nexport const EMOJIS_PER_ROW = 9;\nexport const EMOJI_PICKER_SKIN_TONE_MODIFIERS = {\n DEFAULT: 'Default',\n LIGHT: 'Light',\n MEDIUM_LIGHT: 'MediumLight',\n MEDIUM: 'Medium',\n MEDIUM_DARK: 'MediumDark',\n DARK: 'Dark',\n};\n\nexport const EMOJI_PICKER_CATEGORIES = {\n MOST_RECENTLY_USED: 'Most recently used',\n SMILEYS_AND_PEOPLE: 'Smileys and people',\n NATURE: 'Nature',\n FOOD: 'Food',\n ACTIVITY: 'Activity',\n TRAVEL: 'Travel',\n OBJECTS: 'Objects',\n SYMBOLS: 'Symbols',\n FLAGS: 'Flags',\n};\n\nexport default {\n EMOJI_PICKER_SKIN_TONE_MODIFIERS,\n EMOJI_PICKER_CATEGORIES,\n};\n","import { ref } from 'vue';\nimport { EMOJIS_PER_ROW, ARROW_KEYS } from '@/components/emoji_picker/emoji_picker_constants';\n\nexport function useKeyboardNavigation () {\n const emojiRefs = ref([]);\n const emojiFilteredRefs = ref([]);\n const isFiltering = ref(false);\n const hoverFirstEmoji = ref(true);\n\n function _handleArrowLeft (indexTab, indexEmoji) {\n if (!focusEmoji(indexTab, indexEmoji - 1)) {\n if (emojiRefs.value[indexTab - 1]) {\n focusEmoji(indexTab - 1, emojiRefs.value[indexTab - 1].length - 1);\n } else {\n focusEmoji(emojiRefs.value.length - 1, emojiRefs.value[emojiRefs.value.length - 1].length - 1);\n }\n }\n }\n\n function _handleArrowRight (indexTab, indexEmoji) {\n if (!focusEmoji(indexTab, indexEmoji + 1)) {\n if (!focusEmoji(indexTab + 1, 0)) {\n focusEmoji(0, 0);\n }\n }\n }\n\n function _handleArrowLeftFiltered (indexTab, indexEmoji) {\n if (!focusEmoji(0, indexEmoji - 1)) {\n focusEmoji(0, emojiFilteredRefs.value.length - 1);\n }\n }\n\n function _handleArrowRightFiltered (indexTab, indexEmoji) {\n if (!focusEmoji(0, indexEmoji + 1)) {\n focusEmoji(0, 0);\n }\n }\n\n function _handleHorizontalNavigation (direction, indexTab, indexEmoji) {\n if (isFiltering.value) {\n if (direction === 'left') {\n _handleArrowLeftFiltered(indexTab, indexEmoji);\n } else if (direction === 'right') {\n _handleArrowRightFiltered(indexTab, indexEmoji);\n }\n } else {\n if (direction === 'left') {\n _handleArrowLeft(indexTab, indexEmoji);\n } else if (direction === 'right') {\n _handleArrowRight(indexTab, indexEmoji);\n }\n }\n }\n\n function focusEmoji (indexTab, indexEmoji) {\n const emojiRef = isFiltering.value\n ? emojiFilteredRefs.value?.[indexEmoji]\n : emojiRefs.value?.[indexTab]?.[indexEmoji];\n\n if (emojiRef) {\n emojiRef.focus();\n return true;\n }\n\n return false;\n }\n\n function setEmojiRef (el, indexTab, indexEmoji) {\n if (!emojiRefs.value[indexTab]) {\n emojiRefs.value[indexTab] = [];\n }\n emojiRefs.value[indexTab][indexEmoji] = el;\n }\n\n function setFilteredRef (el, index) {\n emojiFilteredRefs.value[index] = el;\n }\n\n function handleArrowNavigationFiltered (key, indexEmoji) {\n hoverFirstEmoji.value = false;\n\n if (key === ARROW_KEYS.ARROW_UP) {\n const position = indexEmoji % EMOJIS_PER_ROW;\n\n if (!focusEmoji(0, indexEmoji - EMOJIS_PER_ROW)) {\n const lastEmojiPosition =\n emojiFilteredRefs.value.length - (emojiFilteredRefs.value.length % EMOJIS_PER_ROW) + position;\n\n focusEmoji(0, lastEmojiPosition);\n\n if (!focusEmoji(0, lastEmojiPosition)) {\n focusEmoji(0, emojiFilteredRefs.value.length - 1);\n }\n }\n }\n\n if (key === ARROW_KEYS.ARROW_DOWN) {\n if (!focusEmoji(0, indexEmoji + EMOJIS_PER_ROW)) {\n const position = indexEmoji % EMOJIS_PER_ROW;\n\n if (emojiFilteredRefs.value?.[indexEmoji + (EMOJIS_PER_ROW - position)]) {\n focusEmoji(0, emojiFilteredRefs.value.length - 1);\n } else {\n focusEmoji(0, position);\n }\n }\n }\n\n if (key === ARROW_KEYS.ARROW_LEFT) {\n _handleHorizontalNavigation('left', 0, indexEmoji);\n }\n\n if (key === ARROW_KEYS.ARROW_RIGHT) {\n _handleHorizontalNavigation('right', 0, indexEmoji);\n }\n }\n\n function handleArrowNavigation (key, indexTab, indexEmoji) {\n if (key === 'ArrowUp') {\n const position = indexEmoji % EMOJIS_PER_ROW;\n\n if (indexTab === 0) {\n // we are on the first emoji tab, then we should jump to the last row of the last emoji tab\n const numberOfMissingEmojis =\n EMOJIS_PER_ROW - (emojiRefs.value[emojiRefs.value.length - 1].length % EMOJIS_PER_ROW);\n\n const emojiToJump =\n emojiRefs.value[emojiRefs.value.length - 1].length + numberOfMissingEmojis - (EMOJIS_PER_ROW - position);\n\n if (!focusEmoji(emojiRefs.value.length - 1, emojiToJump)) {\n // if there is no emoji in this position, jump to the last emoji of the row\n focusEmoji(emojiRefs.value.length - 1, emojiRefs.value[emojiRefs.value.length - 1].length - 1);\n }\n return;\n }\n\n // if we are not on the first tab, we should jump to the previous row of the current tab\n if (!focusEmoji(indexTab, indexEmoji - EMOJIS_PER_ROW)) {\n // if there is no previous row, we should jump to emoji in the sampe position of the previous tab\n const previousTab = indexTab - 1 < 0 ? 0 : indexTab - 1;\n const emojisInPreviousTab = emojiRefs.value[previousTab].length;\n const lastEmojiPosition = emojisInPreviousTab - (emojisInPreviousTab % EMOJIS_PER_ROW) + position;\n\n if (!focusEmoji(previousTab, lastEmojiPosition)) {\n // if there is no emoji in this position, jump to the last emoji of the row\n focusEmoji(indexTab - 1, emojiRefs.value[indexTab - 1].length - 1);\n }\n }\n }\n\n if (key === 'ArrowDown') {\n if (!focusEmoji(indexTab, indexEmoji + EMOJIS_PER_ROW)) {\n // if cannot go down\n\n // Calculate position from cell 0 to cell 8\n const position = indexEmoji % EMOJIS_PER_ROW;\n\n // check if it exists a next row in the current tab\n if (emojiRefs.value?.[indexTab]?.[indexEmoji + (EMOJIS_PER_ROW - position)]) {\n // if it exists, we should focus the last emoji of the next row in the current tab\n focusEmoji(indexTab, emojiRefs.value[indexTab].length - 1);\n // if we are at the end of the list it will do nothing\n } else {\n // We don't have next row, we are in the last of the tab, then jump\n // to the next tab but in the equal emoji position in row 0.\n\n if (!focusEmoji(indexTab + 1, position)) {\n // We are on the bottom!, should jump to the same position emoji in the first row of the first tabset\n // if it doesn't has, jump to the last\n if (!focusEmoji(0, position)) {\n focusEmoji(0, emojiRefs.value[0].length - 1);\n }\n }\n }\n }\n }\n\n if (key === 'ArrowLeft') {\n _handleHorizontalNavigation('left', indexTab, indexEmoji);\n }\n\n if (key === 'ArrowRight') {\n _handleHorizontalNavigation('right', indexTab, indexEmoji);\n }\n }\n\n return {\n emojiFilteredRefs,\n isFiltering,\n hoverFirstEmoji,\n setEmojiRef,\n setFilteredRef,\n focusEmoji,\n handleArrowNavigationFiltered,\n handleArrowNavigation,\n };\n}\n","<template>\n <div\n class=\"d-emoji-picker__selector\"\n >\n <div\n id=\"d-emoji-picker-list\"\n ref=\"listRef\"\n class=\"d-emoji-picker__list\"\n >\n <p\n v-if=\"emojiFilter\"\n class=\"d-emoji-picker__search-label d-emoji-picker__alignment\"\n >\n {{ filteredEmojis.length > 0 ? searchResultsLabel : searchNoResultsLabel }}\n </p>\n <div\n v-else\n ref=\"tabCategoryRef\"\n class=\"d-emoji-picker__category d-emoji-picker__alignment\"\n >\n <p>\n {{ fixedLabel }}\n </p>\n </div>\n <div\n v-for=\"(tabLabel, indexTab) in tabLabels\"\n v-show=\"!emojiFilter\"\n :key=\"indexTab\"\n :ref=\"tabLabel.ref\"\n class=\"d-emoji-picker__alignment\"\n >\n <p\n v-if=\"indexTab\"\n >\n {{ tabLabel.label }}\n </p>\n <div\n class=\"d-emoji-picker__tab\"\n >\n <button\n v-for=\"(emoji, indexEmoji) in\n (emojis[tabs[indexTab] + skinTone] ? emojis[tabs[indexTab] + skinTone] : emojis[tabs[indexTab]])\"\n :key=\"emoji.shortname\"\n :ref=\"el => { if (el) setEmojiRef(el, indexTab, indexEmoji) }\"\n type=\"button\"\n :aria-label=\"emoji.name\"\n @click=\"selectEmoji(emoji)\"\n @focusin=\"highlightEmoji(emoji)\"\n @focusout=\"highlightEmoji(null)\"\n @mouseover=\"highlightEmoji(emoji)\"\n @mouseleave=\"highlightEmoji(null)\"\n @keydown=\"event => handleKeyDown(event, indexTab, indexEmoji, emoji)\"\n >\n <img\n class=\"d-icon d-icon--size-500\"\n :alt=\"emoji.name\"\n :aria-label=\"emoji.name\"\n :title=\"emoji.name\"\n :src=\"getImgSrc(emoji.unicode_character)\"\n @error=\"handleImageError\"\n >\n </button>\n </div>\n </div>\n <div\n v-if=\"emojiFilter\"\n class=\"d-emoji-picker__alignment\"\n >\n <div\n class=\"d-emoji-picker__tab \"\n data-qa=\"filtered-emojis\"\n >\n <button\n v-for=\"(emoji, index) in filteredEmojis\"\n :key=\"emoji.shortname\"\n :ref=\"el => { if (el) setFilteredRef(el, index) }\"\n type=\"button\"\n :aria-label=\"emoji.name\"\n :class=\"{\n 'hover-emoji': (index === 0 && hoverFirstEmoji),\n }\"\n @click=\"selectEmoji(emoji)\"\n @focusin=\"highlightEmoji(emoji)\"\n @focusout=\"highlightEmoji(null)\"\n @mouseover=\"hoverEmoji(emoji)\"\n @mouseleave=\"hoverEmoji(null)\"\n @keydown=\"event => handleKeyDownFilteredEmojis(event, index, emoji)\"\n >\n <img\n class=\"d-icon d-icon--size-500\"\n :alt=\"emoji.name\"\n :aria-label=\"emoji.name\"\n :title=\"emoji.name\"\n :src=\"`${CDN_URL + emoji.unicode_character}.png`\"\n >\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup>\n// eslint-disable max-len\nimport { emojisGrouped as emojis } from '@dialpad/dialtone-emojis';\nimport { computed, onMounted, onUnmounted, ref, watch, nextTick } from 'vue';\nimport { CDN_URL, ARROW_KEYS } from '@/components/emoji_picker/emoji_picker_constants';\nimport { useKeyboardNavigation } from '@/components/emoji_picker/composables/useKeyboardNavigation';\n\nconst props = defineProps({\n /**\n * The filter to apply to the emoji list\n * @type {String}\n * @default ''\n */\n emojiFilter: {\n type: String,\n default: '',\n },\n\n /**\n * The skin tone to apply to the emoji list\n * @type {String}\n * @required\n */\n skinTone: {\n type: String,\n required: true,\n },\n\n /**\n * The labels for the tabset\n * @type {Array}\n * @required\n */\n tabsetLabels: {\n type: Array,\n required: true,\n },\n\n selectedTabset: {\n type: Object,\n required: true,\n },\n\n /**\n * The label for the search results tab\n * @type {String}\n * @required\n */\n searchResultsLabel: {\n type: String,\n required: true,\n },\n\n searchNoResultsLabel: {\n type: String,\n required: true,\n },\n\n /**\n * The list of recently used emojis\n * @type {Array}\n */\n recentlyUsedEmojis: {\n type: Array,\n default: () => [],\n },\n});\n\nconst emits = defineEmits([\n /**\n * Emitted when the user hover over an emoji\n * @event highlighted-emoji\n * @param {Object} emoji - The emoji data that was hovered\n */\n 'highlighted-emoji',\n\n /**\n * Emitted when the user select an emoji\n * @event selected-emoji\n * @param {Object} emoji - The emoji data that was selected\n */\n 'selected-emoji',\n\n /**\n * Emitted when the user scroll into an emoji tab\n * @event scroll-into-tab\n * @param {Number} tab-index - The tab that was scrolled into\n */\n 'scroll-into-tab',\n\n /**\n * Emitted when the scrollTo function starts scrolling and stops scrolling\n * @event is-scrolling\n * @param {Boolean} is-scrolling - Whether the user is scrolling with the scroll-to\n */\n 'is-scrolling',\n\n /**\n * Emitted when the user reach the end of the emoji list\n * @event focus-skin-selector\n */\n 'focus-skin-selector',\n\n /**\n * Emitted when the user shift tab in first tab of emoji selector\n * @event shift-tab-key-pressed\n */\n 'shift-tab-key-pressed',\n]);\n\nconst {\n emojiFilteredRefs,\n isFiltering,\n hoverFirstEmoji,\n setEmojiRef,\n setFilteredRef,\n focusEmoji,\n handleArrowNavigationFiltered,\n handleArrowNavigation,\n} = useKeyboardNavigation();\n\n/**\n * The ref for the tab category\n * This is used to display the fixed label\n */\nconst tabCategoryRef = ref(null);\n\n/**\n * The ref for the list\n * This is used to display the tabs\n */\nconst listRef = ref(null);\n\n/**\n * The ref for the tab label observer\n * This is used to update the fixed label\n */\nconst tabLabelObserver = ref(null);\n\n/**\n * The list of tabs\n * This is used to display the tabs\n */\nconst TABS_DATA = ['Recently used', 'People', 'Nature', 'Food', 'Activity', 'Travel', 'Objects', 'Symbols', 'Flags'];\n\n/**\n * The list of tab labels\n * This is used to display the tabs\n * This is a computed property because it will check if the recently used emojis list is empty\n * If it is empty, it will remove the recently used tab\n */\nconst tabLabels = computed(() => {\n return props.recentlyUsedEmojis.length\n ? props.tabsetLabels.map((label) => ({ label, ref: ref(null) }))\n : props.tabsetLabels.slice(1).map((label) => ({ label, ref: ref(null) }));\n});\n\n/**\n * The label of the fixed tab\n * This is used to display the fixed label\n */\nconst fixedLabel = ref(tabLabels.value[0].label);\n\n/**\n * The list of tabs\n * This is used to display the tabs\n * This is a computed property because it will check if the recently used emojis list is empty\n * If it is empty, it will remove the recently used tab\n * The difference between this and the tab labels is that this one will set the structure of tabs\n * and the tab labels will set the labels\n */\nconst tabs = computed(() => {\n return props.recentlyUsedEmojis.length ? TABS_DATA : TABS_DATA.slice(1);\n});\n\n/**\n * The list of current emojis that match the filter\n * This will be updated when the emojiFilter changes\n * This is used to display the search results\n * The difference between this and the current emojis list is that this one will not have the skin tone applied\n */\nconst filteredEmojis = ref([]);\n\n/**\n * The current emojis list we are displaying\n * This will be updated when the skin tone changes\n * The difference between this and the emojis list is that this one will have only the skin tone applied\n */\nconst currentEmojis = computed(() => {\n return [\n ...emojis[`People${props.skinTone}`],\n ...emojis.Nature,\n ...emojis.Food,\n ...emojis[`Activity${props.skinTone}`],\n ...emojis.Travel,\n ...emojis[`Objects${props.skinTone}`],\n ...emojis.Symbols,\n ...emojis.Flags,\n ];\n});\n\n/**\n * This will trigger the searchByNameAndKeywords function with debounce of 300 milliseconds\n */\nconst debouncedSearch = debounce(() => {\n // We clean the emojiFilteredRefs to have an updated ref list for the search results\n emojiFilteredRefs.value = [];\n searchByNameAndKeywords();\n});\n\n/**\n * Update the current emojis list on skin tone changes\n * Also update the filtered emojis list\n * @listens skinTone\n */\nwatch(currentEmojis, () => {\n searchByNameAndKeywords();\n}, { immediate: true });\n\n/**\n * Update the recently used emojis list on recently used emojis prop changes\n * @listens recentlyUsedEmojis\n */\nwatch(() => props.recentlyUsedEmojis,\n () => {\n emojis['Recently used'] = props.recentlyUsedEmojis;\n }, { immediate: true });\n\n/**\n * Search for emojis by name and keywords\n * Will update the filtered emojis list on emojiFilter update\n * @listens emojiFilter\n */\nwatch(() => props.emojiFilter, () => {\n resetScroll();\n if (props.emojiFilter) {\n isFiltering.value = true;\n } else {\n isFiltering.value = false;\n // If the emoji filter is empty, emit null to remove the highlighted emoji\n // of the previous search\n highlightEmoji(null);\n }\n debouncedSearch();\n});\n\nwatch(\n () => props.selectedTabset,\n (tab) => {\n scrollToTab(tab.tabId);\n },\n { deep: true },\n);\n\nfunction hoverEmoji (emoji, isFirst = false) {\n hoverFirstEmoji.value = isFirst;\n emits('highlighted-emoji', emoji);\n}\n\n/**\n * Filters an array of emoji objects based on a search string that matches both the name and keywords.\n * Will update the filtered emojis list\n */\nfunction searchByNameAndKeywords () {\n const searchStr = props.emojiFilter.toLowerCase();\n filteredEmojis.value = currentEmojis.value.filter(obj => {\n const nameIncludesSearchStr = obj.name.toLowerCase().includes(searchStr);\n const keywordsIncludeSearchStr = obj.keywords.some(keyword => keyword.toLowerCase().includes(searchStr));\n return nameIncludesSearchStr || keywordsIncludeSearchStr;\n });\n nextTick(() => {\n if (searchStr) {\n hoverEmoji(filteredEmojis.value[0], true);\n }\n });\n}\n\nfunction debounce (fn, delay = 300) {\n let timeout;\n\n return (...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n };\n}\n\nfunction getImgSrc (emoji) {\n return `${CDN_URL + emoji}.png`;\n}\n\n/**\n * Handle image error - We hide the entire button if the image is not found\n */\nfunction handleImageError (event) {\n event.target.parentNode.style.display = 'none';\n}\n\n/**\n * Scroll to the selected tab\n */\nfunction scrollToTab (tabIndex, focusFirstEmoji = true) {\n const tabLabel = tabLabels.value[tabIndex - 1];\n const tabElement = tabLabel.ref.value[0];\n\n nextTick(() => {\n const container = listRef.value;\n const offsetTop = tabIndex === '1' ? 0 : tabElement.offsetTop - 20;\n\n /**\n * This variable is used to check if the user is scrolling inside the emoji picker\n * This is used to check if the user is scrolling using the scrollTo function\n * This is useful because this flag will prevent to update the fixed label when the user is scrolling\n * using the scrollTo function\n */\n let isScrolling = true;\n\n let prevScrollTop = container.scrollTop;\n emits('is-scrolling', true);\n\n /**\n * This event listener checks whether the user is scrolling up or down by comparing the current scrollTop\n * to prevScrollTop. If the scrollToTab function is scrolling from bottom to top and has reached the desired\n * position (scrollTop <= offsetTop),or if the scrollToTab function is scrolling from top to bottom and has\n * passed the desired position(scrollTop >= offsetTop), then isScrolling is set to false.\n */\n container.addEventListener('scroll', () => {\n if (isScrolling) {\n const scrollTop = container.scrollTop;\n if (\n (prevScrollTop < scrollTop && scrollTop >= offsetTop) ||\n (prevScrollTop > scrollTop && scrollTop <= offsetTop)\n ) {\n isScrolling = false;\n emits('is-scrolling', false);\n }\n prevScrollTop = scrollTop;\n }\n });\n\n container.scrollTop = offsetTop;\n\n if (focusFirstEmoji) {\n focusEmoji((tabIndex - 1), 0);\n }\n });\n}\n\nfunction resetScroll () {\n const container = listRef.value;\n\n container.scrollTop = 0;\n}\n\n/**\n * This code creates an IntersectionObserver object that monitors the intersection between\n * the root element (tabCategoryRef) and its targets (the child elements of listRef),\n * and updates the value of the fixedLabel variable accordingly.\n */\nfunction setTabLabelObserver () {\n /**\n * The code extracts the target element and its index from the IntersectionObserverEntry object,\n * and checks whether the target intersects with the root and is positioned above or below it.\n */\n tabLabelObserver.value = new IntersectionObserver(entries => {\n entries.forEach(entry => {\n const { target } = entry;\n const index = parseInt(target.dataset.index);\n\n /**\n * If the target is positioned above the root,\n * the code updates the value of the fixed label to the label of the previous tab,\n * or the first tab if the current tab is the first one. If the target is positioned below the root, the code\n * updates the value of the fixed label to the label of the current tab.\n * If the target stops intersecting with the root and its index is 1 (the second tab),\n * the code updates the value of the fixed label to the label of the first tab.\n * NOTES:\n * This last condition is needed because sometimes it is\n * not detect the intersection between the root and the target.\n * We also provide a 50 pixels offset to the root element in the first condition to always get the\n * first tab if it has fewer emojis, because in some cases if you quickly scroll the observer does not detect it.\n */\n if (entry.isIntersecting && target.offsetTop <= tabCategoryRef.value.offsetTop + 50) {\n fixedLabel.value = tabLabels.value[index - 1]?.label ?? tabLabels.value[0]?.label;\n emits('scroll-into-tab', index - 1);\n } else if (entry.boundingClientRect.bottom <= tabCategoryRef.value?.getBoundingClientRect().bottom) {\n emits('scroll-into-tab', index);\n fixedLabel.value = tabLabels.value[index]?.label;\n } else if (index === 1) {\n emits('scroll-into-tab', index);\n fixedLabel.value = tabLabels.value[0]?.label;\n }\n });\n });\n\n /**\n * The tabLabelObserver is set to observe the root element and all its children elements with\n * the IntersectionObserver object, and sets their data-index attribute to their index.\n */\n tabLabelObserver.value.observe(tabCategoryRef.value);\n\n Array.from(listRef.value.children).forEach((child, index) => {\n tabLabelObserver.value.observe(child);\n child.dataset.index = index;\n });\n}\n\nconst handleKeyDownFilteredEmojis = (event, indexEmoji, emoji) => {\n event.preventDefault();\n\n if (Object.values(ARROW_KEYS).includes(event.key)) {\n handleArrowNavigationFiltered(event.key, indexEmoji);\n return;\n }\n\n switch (event.key) {\n case 'Tab':\n emits('focus-skin-selector');\n break;\n case 'Enter':\n selectEmoji(emoji);\n break;\n default:\n break;\n }\n};\n\nconst handleKeyDown = (event, indexTab, indexEmoji, emoji) => {\n event.preventDefault();\n\n if (Object.values(ARROW_KEYS).includes(event.key)) {\n handleArrowNavigation(event.key, indexTab, indexEmoji);\n return;\n }\n\n switch (event.key) {\n case 'Tab':\n if (event.shiftKey) {\n if (focusEmoji(indexTab, 0) && indexTab > 0) {\n scrollToTab(indexTab, true);\n } else {\n scrollToTab(1, false);\n emits('shift-tab-key-pressed');\n }\n } else {\n if (focusEmoji(indexTab + 1, 0)) {\n scrollToTab(indexTab + 1 + 1, false);\n } else {\n // We are on the last emoji tabset, jump to the skin selector\n emits('focus-skin-selector');\n }\n }\n break;\n\n case 'Enter':\n selectEmoji(emoji);\n break;\n\n default:\n break;\n }\n};\n\nfunction selectEmoji (emoji) {\n emits('selected-emoji', emoji);\n}\n\nfunction highlightEmoji (emoji) {\n emits('highlighted-emoji', emoji);\n}\n\nfunction focusEmojiSelector () {\n focusEmoji(0, 0);\n}\n\nfunction focusLastEmoji () {\n focusEmoji(tabs.value.length - 1, 0);\n}\n\nonMounted(() => {\n setTabLabelObserver();\n});\n\nonUnmounted(() => {\n tabLabelObserver.value.disconnect();\n});\n\ndefineExpose({\n focusEmojiSelector,\n focusLastEmoji,\n});\n</script>\n","<template>\n <div data-qa=\"skin-selector\">\n <div\n v-show=\"isOpen\"\n class=\"d-emoji-picker__skin-list\"\n >\n <button\n v-for=\"(skin, index) in skinList\"\n :ref=\"el => { if (el) setSkinsRef(el) }\"\n :key=\"skin.name\"\n :class=\"{\n 'selected': skinSelected.skinCode === skin.skinCode,\n }\"\n @keydown=\"event => handleKeyDown(event, skin, index)\"\n @click=\"selectSkin(skin)\"\n >\n <img\n class=\"d-icon d-icon--size-500\"\n :alt=\"skin.name\"\n :aria-label=\"skin.name\"\n :title=\"skin.name\"\n :src=\"`${CDN_URL + skin.unicode_output}.png`\"\n >\n </button>\n </div>\n <div\n v-show=\"!isOpen\"\n class=\"d-emoji-picker__skin-selected\"\n >\n <dt-tooltip placement=\"top-end\">\n {{ skinSelectorButtonTooltipLabel }}\n <template #anchor>\n <button\n ref=\"skinSelectorRef\"\n :aria-label=\"skinSelectorButtonTooltipLabel\"\n tabindex=\"-1\"\n @click=\"toggleSkinList\"\n @keydown=\"event => handleKeyDown(event)\"\n >\n <img\n class=\"d-icon d-icon--size-500\"\n :alt=\"skinSelected.name\"\n :aria-label=\"skinSelected.name\"\n :title=\"skinSelected.name\"\n :src=\"`${CDN_URL + skinSelected.unicode_output}.png`\"\n >\n </button>\n </template>\n </dt-tooltip>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { computed, nextTick, ref, watchEffect } from 'vue';\nimport { CDN_URL, EMOJI_PICKER_SKIN_TONE_MODIFIERS } from '@/components/emoji_picker';\nimport { DtTooltip } from '@/components/tooltip';\n\nconst props = defineProps({\n /**\n * The skin tone to apply to the emoji list\n * @type {String}\n * @required\n */\n skinTone: {\n type: String,\n required: true,\n },\n\n isHovering: {\n type: Boolean,\n default: false,\n },\n\n skinSelectorButtonTooltipLabel: {\n type: String,\n required: true,\n },\n});\n\nconst emits = defineEmits([\n /**\n * The skin tone that was selected\n * @event skin-tone\n * @type {Number}\n */\n 'skin-tone',\n 'focus-tabset',\n 'focus-last-emoji',\n]);\n\nconst skinList = [\n {\n name: ':wave_tone1:',\n unicode_output: '1f44b-1f3fb',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.LIGHT,\n skinCode: '_tone1',\n },\n {\n name: ':wave_tone2:',\n unicode_output: '1f44b-1f3fc',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.MEDIUM_LIGHT,\n skinCode: '_tone2',\n },\n {\n name: ':wave_tone3:',\n unicode_output: '1f44b-1f3fd',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.MEDIUM,\n skinCode: '_tone3',\n },\n {\n name: ':wave_tone4:',\n unicode_output: '1f44b-1f3fe',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.MEDIUM_DARK,\n skinCode: '_tone4',\n },\n {\n name: ':wave_tone5:',\n unicode_output: '1f44b-1f3ff',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.DARK,\n skinCode: '_tone5',\n },\n {\n name: ':wave:',\n unicode_output: '1f44b',\n skinTone: EMOJI_PICKER_SKIN_TONE_MODIFIERS.DEFAULT,\n skinCode: '',\n },\n];\n\nconst isOpen = ref(false);\n\nconst skinSelectorRef = ref(null);\n\nconst skinsRef = ref([]);\n\n/**\n * It will close the skin selector if the user is hovering over the emoji list\n */\nwatchEffect(\n () => props.isHovering && (isOpen.value = false),\n);\n\n/**\n * It will initially display props.skinTone. If a new skin tone is selected,\n * it will display that until props.skinTone changes.\n */\nconst skinPassedIn = computed(() => skinList.find((skin) => skin.skinTone === props.skinTone));\nconst skinSelected = ref(skinPassedIn.value);\nwatchEffect(() => skinPassedIn.value && (skinSelected.value = skinPassedIn.value));\n\nfunction setSkinsRef (ref) {\n skinsRef.value.push(ref);\n}\nfunction focusSkinSelector () {\n skinSelectorRef.value.focus();\n}\n\nfunction selectSkin (skin) {\n skinSelected.value = skin;\n isOpen.value = false;\n emits('skin-tone', skin.skinTone);\n nextTick(() => focusSkinSelector());\n}\n\nconst handleKeyDown = (event, skin, index) => {\n event.preventDefault();\n\n if (event.key === 'ArrowLeft') {\n if (index === 0) skinsRef.value[skinsRef.value.length - 1]?.focus();\n skinsRef.value[index - 1]?.focus();\n }\n\n if (event.key === 'ArrowRight') {\n skinsRef.value[index + 1]?.focus();\n }\n\n if (event.key === 'Enter') {\n if (skin) { selectSkin(skin); } else {\n toggleSkinList();\n }\n }\n\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n emits('focus-last-emoji');\n } else {\n emits('focus-tabset');\n }\n }\n};\n\nfunction toggleSkinList () {\n isOpen.value = !isOpen.value;\n nextTick(() => skinsRef.value[0].focus());\n}\n\ndefineExpose({\n focusSkinSelector,\n});\n</script>\n","<template>\n <div\n class=\"d-emoji-picker\"\n >\n <div class=\"d-emoji-picker--header\">\n <emoji-tabset\n ref=\"tabsetRef\"\n :emoji-filter=\"internalSearchQuery\"\n :show-recently-used-tab=\"showRecentlyUsedTab\"\n :scroll-into-tab=\"scrollIntoTab\"\n :tabset-labels=\"tabSetLabels\"\n :is-scrolling=\"isScrolling\"\n @tab-key-pressed=\"focusNextSectionFromEmojiTabSet\"\n @shift-tab-key-pressed=\"$refs.skinSelectorRef.focusSkinSelector()\"\n @arrow-down-key-pressed=\"focusNextSectionFromEmojiTabSet\"\n @selected-tabset=\"scrollToSelectedTabset\"\n @keydown.esc=\"emits('close')\"\n />\n </div>\n <div class=\"d-emoji-picker--body\">\n <emoji-search\n v-if=\"showSearch\"\n ref=\"searchInputRef\"\n v-model=\"internalSearchQuery\"\n :search-placeholder-label=\"searchPlaceholderLabel\"\n @select-first-emoji=\"emits('selected-emoji', highlightedEmoji)\"\n @focus-tabset=\"$refs.tabsetRef.focusTabset()\"\n @focus-emoji-selector=\"$refs.emojiSelectorRef.focusEmojiSelector()\"\n @keydown.esc=\"emits('close')\"\n />\n <emoji-selector\n ref=\"emojiSelectorRef\"\n :emoji-filter=\"internalSearchQuery\"\n :skin-tone=\"skinTone\"\n :tabset-labels=\"tabSetLabels\"\n :search-results-label=\"searchResultsLabel\"\n :search-no-results-label=\"searchNoResultsLabel\"\n :recently-used-emojis=\"recentlyUsedEmojis\"\n :selected-tabset=\"selectedTabset\"\n @scroll-into-tab=\"updateScrollIntoTab\"\n @is-scrolling=\"updateIsScrolling\"\n @highlighted-emoji=\"updateHighlightedEmoji\"\n @selected-emoji=\"emits('selected-emoji', $event)\"\n @focus-skin-selector=\"$refs.skinSelectorRef.focusSkinSelector()\"\n @shift-tab-key-pressed=\"focusNextSectionFromEmojiSelector\"\n @keydown.esc=\"emits('close')\"\n />\n </div>\n <div class=\"d-emoji-picker--footer\">\n <emoji-description :emoji=\"highlightedEmoji\" />\n <emoji-skin-selector\n ref=\"skinSelectorRef\"\n :is-hovering=\"!!highlightedEmoji\"\n :skin-selector-button-tooltip-label=\"skinSelectorButtonTooltipLabel\"\n :skin-tone=\"skinTone\"\n @skin-tone=\"emits('skin-tone', $event)\"\n @focus-tabset=\"$refs.tabsetRef.focusTabset()\"\n @focus-last-emoji=\"$refs.emojiSelectorRef.focusLastEmoji()\"\n @keydown.esc=\"emits('close')\"\n />\n </div>\n </div>\n</template>\n\n<script setup>\nimport EmojiSearch from './modules/emoji_search.vue';\nimport EmojiTabset from './modules/emoji_tabset.vue';\nimport EmojiSelector from './modules/emoji_selector.vue';\nimport EmojiSkinSelector from './modules/emoji_skin_selector.vue';\nimport EmojiDescription from './modules/emoji_description.vue';\nimport { computed, ref, watch } from 'vue';\n\nconst props = defineProps({\n /**\n * The array with recently used emoji object\n * This list is necessary to fill the recently used tab\n * @type {Array}\n * @default []\n * @example\n * <dt-emoji-picker :recentlyUsedEmojis=\"[emojiObject, emojiObject]\" />\n */\n // TODO try to simplify this to achieve an array of unicode characters and not an entire emoji data object\n recentlyUsedEmojis: {\n type: Array,\n default: () => ([]),\n },\n\n /**\n * The placeholder text for the search input\n * @type {String}\n * @required\n * @example\n * <dt-emoji-picker :searchPlaceholderLabel=\"'Search...'\" />\n */\n searchPlaceholderLabel: {\n type: String,\n required: true,\n },\n\n /**\n * The label for the search results tab\n * @type {String}\n * @required\n * @example\n * <dt-emoji-picker :searchResultsLabel=\"'Search results'\" />\n */\n searchResultsLabel: {\n type: String,\n required: true,\n },\n\n /**\n * The label for the search no results\n * @type {String}\n * @required\n * @example\n * <dt-emoji-picker :searchNoResultsLabel=\"'No results'\" />\n */\n searchNoResultsLabel: {\n type: String,\n required: true,\n },\n\n /**\n * The list of tabsets to show, it is necessary to be updated with the correct language\n * It must respect the provided order.\n * @type {Array}\n * @required\n * @example\n * <dt-emoji-picker\n * :tabSetLabels=\"['Most recently used', 'Smileys and people', 'Nature',\n * 'Food', 'Activity', 'Travel', 'Objects', 'Symbols', 'Flags']\" />\n */\n tabSetLabels: {\n type: Array,\n required: true,\n },\n\n /**\n * The skin tone to show the emojis\n * This prop gives the possibility to use the skin tone selected by the user previously\n * @type {String}\n * @default 'Default'\n * @values 'Default', 'Light', 'MediumLight', 'Medium', 'MediumDark', 'Dark'\n * @example\n * <dt-emoji-picker :skinTone=\"'Default'\" />\n */\n skinTone: {\n type: String,\n default: 'Default',\n },\n\n /**\n * Tooltip shown when skin selector button is hovered.\n * @type {String}\n * @required\n * @example\n * <dt-emoji-picker :skin-selector-button-tooltip-label=\"'Change default skin tone'\" />\n */\n skinSelectorButtonTooltipLabel: {\n type: String,\n required: true,\n },\n\n /**\n * Sets the search query that filters emojis.\n * @type {String}\n * @example\n * <dt-emoji-picker search-query=\"smile\" />\n */\n searchQuery: {\n type: String,\n default: '',\n },\n\n /**\n * Shows the search input\n * @type {Boolean}\n * @example\n * <dt-emoji-picker :show-search=\"false\" />\n */\n showSearch: {\n type: Boolean,\n default: true,\n },\n});\n\nconst emits = defineEmits(\n [\n /**\n * It will emit the selected emoji\n * @event selected-emoji\n * @param {Object} emoji - The selected emoji from the emoji selector\n */\n 'selected-emoji',\n\n /**\n * It will emit the selected skin tone\n * @event skin-tone\n * @param {String} skin - The selected skin tone from the skin selector\n */\n 'skin-tone',\n\n /**\n * Since the keyboard events are encapsulated, we emit this event to close the picker\n * @event close\n */\n 'close',\n ],\n);\n\nconst internalSearchQuery = ref(props.searchQuery.value);\nconst highlightedEmoji = ref(null);\nconst selectedTabset = ref({});\n\nconst scrollIntoTab = ref(0);\nconst isScrolling = ref(false);\n\nconst searchInputRef = ref(null);\nconst emojiSelectorRef = ref(null);\nconst tabsetRef = ref(null);\n\nconst showRecentlyUsedTab = computed(() => props.recentlyUsedEmojis.length > 0);\n\nwatch(\n () => props.searchQuery,\n (newValue) => {\n internalSearchQuery.value = newValue;\n },\n);\n\n/**\n * Handle the selected tabset event\n * We're creating a new object with the same value as selectedTabset and assigning it back to selectedTabset.\n * Vue will see this as a new object and trigger the watcher in the child component.\n * Using this method, we are able to trigger the watcher in the child component even if the value being passed is the\n * same as the previous value.\n * @event selectedTabset\n * @param tabName {String} - The name of the tab that was selected\n */\nfunction scrollToSelectedTabset (tabId) {\n internalSearchQuery.value = '';\n selectedTabset.value = tabId;\n selectedTabset.value = { ...selectedTabset.value, tabId };\n}\n\nfunction updateScrollIntoTab (value) {\n scrollIntoTab.value = value;\n}\n\nfunction updateIsScrolling (value) {\n isScrolling.value = value;\n}\nfunction updateHighlightedEmoji (emoji) {\n highlightedEmoji.value = emoji;\n}\n\nfunction focusNextSectionFromEmojiTabSet () {\n if (props.showSearch) {\n searchInputRef.value.focusSearchInput();\n } else {\n emojiSelectorRef.value.focusEmojiSelector();\n }\n}\n\nfunction focusNextSectionFromEmojiSelector () {\n if (props.showSearch) {\n searchInputRef.value.focusSearchInput();\n } else {\n tabsetRef.value.focusTabset();\n }\n}\n</script>\n"],"names":["ref","emojis"],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ const lib_tooltip = require("./tooltip.cjs");
|
|
|
6
6
|
const lib_button = require("./button.cjs");
|
|
7
7
|
const lib_emoji = require("./emoji.cjs");
|
|
8
8
|
const lib_emojiTextWrapper = require("./emoji-text-wrapper.cjs");
|
|
9
|
-
require("../chunks/popover_constants-
|
|
9
|
+
require("../chunks/popover_constants-XnGWXaxX.js");
|
|
10
10
|
require("tippy.js");
|
|
11
11
|
require("../common/utils.cjs");
|
|
12
12
|
require("../common/constants.cjs");
|
|
@@ -4,7 +4,7 @@ import { DtTooltip } from "./tooltip.js";
|
|
|
4
4
|
import { DtButton } from "./button.js";
|
|
5
5
|
import { DtEmoji } from "./emoji.js";
|
|
6
6
|
import { DtEmojiTextWrapper as _sfc_main$1 } from "./emoji-text-wrapper.js";
|
|
7
|
-
import "../chunks/popover_constants-
|
|
7
|
+
import "../chunks/popover_constants-WsOUIY-m.js";
|
|
8
8
|
import "tippy.js";
|
|
9
9
|
import "../common/utils.js";
|
|
10
10
|
import "../common/constants.js";
|
|
@@ -17,7 +17,7 @@ require("./skeleton.cjs");
|
|
|
17
17
|
require("@dialpad/dialtone-icons/vue3");
|
|
18
18
|
require("../common/constants.cjs");
|
|
19
19
|
require("../chunks/link_constants-x8NwdqmA.js");
|
|
20
|
-
require("../chunks/popover_constants-
|
|
20
|
+
require("../chunks/popover_constants-XnGWXaxX.js");
|
|
21
21
|
require("tippy.js");
|
|
22
22
|
const LEFTBAR_GENERAL_ROW_TYPES = {
|
|
23
23
|
INBOX: "inbox",
|
|
@@ -181,6 +181,14 @@ const _sfc_main = {
|
|
|
181
181
|
return Object.keys(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS).includes(color);
|
|
182
182
|
}
|
|
183
183
|
},
|
|
184
|
+
/**
|
|
185
|
+
* The channel setting, either 'mention' or 'always'.
|
|
186
|
+
* @values 'mention', 'always', null.
|
|
187
|
+
*/
|
|
188
|
+
channelSetting: {
|
|
189
|
+
type: String,
|
|
190
|
+
default: null
|
|
191
|
+
},
|
|
184
192
|
/**
|
|
185
193
|
* Styles the row with an increased font weight to convey it has unreads. This must be true to see
|
|
186
194
|
* the unread count badge.
|
|
@@ -343,6 +351,14 @@ const _sfc_main = {
|
|
|
343
351
|
},
|
|
344
352
|
shouldApplyCustomStyleForCountBadge() {
|
|
345
353
|
return this.hasUnreadCount && this.hasUnreadMentionCount;
|
|
354
|
+
},
|
|
355
|
+
/**
|
|
356
|
+
* When a channel in 'always' setting, meaning the user should see both unread count and unread mention count,
|
|
357
|
+
* if there are only mention messages, we should apply the custom background with var(--dt-color-purple-500).
|
|
358
|
+
* @returns {boolean}
|
|
359
|
+
*/
|
|
360
|
+
shouldApplyCustomStyleForMentionOnly() {
|
|
361
|
+
return this.channelSetting === "always" && !this.hasUnreadCount && this.hasUnreadMentionCount;
|
|
346
362
|
}
|
|
347
363
|
},
|
|
348
364
|
watch: {
|
|
@@ -380,7 +396,7 @@ const _sfc_main = {
|
|
|
380
396
|
}
|
|
381
397
|
}
|
|
382
398
|
};
|
|
383
|
-
const _withScopeId = (n) => (vue.pushScopeId("data-v-
|
|
399
|
+
const _withScopeId = (n) => (vue.pushScopeId("data-v-4793665c"), n = n(), vue.popScopeId(), n);
|
|
384
400
|
const _hoisted_1 = ["data-qa", "aria-label", "title", "href"];
|
|
385
401
|
const _hoisted_2 = { class: "dt-leftbar-row__alpha" };
|
|
386
402
|
const _hoisted_3 = {
|
|
@@ -501,7 +517,8 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
501
517
|
"data-qa": "dt-leftbar-row-unread-mention-badge",
|
|
502
518
|
class: vue.normalizeClass([
|
|
503
519
|
"dt-leftbar-row__unread-badge",
|
|
504
|
-
{ "dt-leftbar-row__unread-mention-count-badge": $options.shouldApplyCustomStyleForCountBadge }
|
|
520
|
+
{ "dt-leftbar-row__unread-mention-count-badge": $options.shouldApplyCustomStyleForCountBadge },
|
|
521
|
+
{ "dt-leftbar-row__unread-mention-only-count-badge": $options.shouldApplyCustomStyleForMentionOnly }
|
|
505
522
|
])
|
|
506
523
|
}, {
|
|
507
524
|
default: vue.withCtx(() => [
|
|
@@ -544,7 +561,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
544
561
|
])) : vue.createCommentVNode("", true)
|
|
545
562
|
], 2);
|
|
546
563
|
}
|
|
547
|
-
const DtRecipeGeneralRow = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-
|
|
564
|
+
const DtRecipeGeneralRow = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-4793665c"]]);
|
|
548
565
|
exports.DtRecipeGeneralRow = DtRecipeGeneralRow;
|
|
549
566
|
exports.LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS = LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS;
|
|
550
567
|
exports.LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR = LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general-row.cjs","sources":["../../recipes/leftbar/general_row/general_row_constants.js","../../recipes/leftbar/general_row/leftbar_general_row_icon.vue","../../recipes/leftbar/general_row/general_row.vue"],"sourcesContent":["export const LEFTBAR_GENERAL_ROW_TYPES = {\n INBOX: 'inbox',\n CONTACTS: 'contacts',\n CHANNELS: 'channels',\n THREADS: 'threads',\n LAUNCHPAD: 'launchpad',\n LOCKED_CHANNEL: 'locked channel',\n CONTACT_CENTER: 'contact center',\n QUICK_START: 'quick start',\n COACHING_GROUP: 'coaching group',\n COACHING_CENTER: 'coaching center',\n DIALBOT: 'dialbot',\n ASSIGNED: 'assigned',\n DIGITAL: 'digital',\n};\n\nexport const LEFTBAR_GENERAL_ROW_ICON_MAPPING = {\n [LEFTBAR_GENERAL_ROW_TYPES.INBOX]: 'inbox',\n [LEFTBAR_GENERAL_ROW_TYPES.CONTACTS]: 'contacts',\n [LEFTBAR_GENERAL_ROW_TYPES.CHANNELS]: 'hash',\n [LEFTBAR_GENERAL_ROW_TYPES.THREADS]: 'thread',\n [LEFTBAR_GENERAL_ROW_TYPES.LAUNCHPAD]: 'layout-template',\n [LEFTBAR_GENERAL_ROW_TYPES.LOCKED_CHANNEL]: 'lock',\n [LEFTBAR_GENERAL_ROW_TYPES.QUICK_START]: 'sparkle',\n [LEFTBAR_GENERAL_ROW_TYPES.COACHING_GROUP]: 'users',\n [LEFTBAR_GENERAL_ROW_TYPES.COACHING_CENTER]: 'external-link',\n 'locked channel unread': 'lock-filled',\n 'channel unread': 'hash-bold',\n [LEFTBAR_GENERAL_ROW_TYPES.ASSIGNED]: 'at-sign',\n [LEFTBAR_GENERAL_ROW_TYPES.DIGITAL]: 'laptop-2',\n};\n\nexport const LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS = {\n 'magenta-200': 'd-bgc-magenta-200',\n 'green-200': 'd-bgc-green-200',\n 'gold-300': 'd-bgc-gold-300',\n 'purple-600': 'd-bgc-purple-600',\n 'magenta-300': 'd-bgc-magenta-300',\n 'purple-300': 'd-bgc-purple-300',\n 'green-500': 'd-bgc-green-500',\n 'purple-100': 'd-bgc-purple-100',\n 'magenta-400': 'd-bgc-magenta-400',\n 'magenta-100': 'd-bgc-magenta-100',\n 'black-300': 'd-bgc-black-300',\n};\n\nexport const LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR = 'If type is contact center, color must be one' +\n 'of the following:' + Object.keys(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS).join(', ');\n\nexport const LEFTBAR_GENERAL_ROW_ICON_SIZES = [\n '300',\n '200',\n];\n\nexport default {\n LEFTBAR_GENERAL_ROW_TYPES,\n LEFTBAR_GENERAL_ROW_ICON_MAPPING,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR,\n LEFTBAR_GENERAL_ROW_ICON_SIZES,\n};\n","<template>\n <dt-icon\n v-if=\"isIconType\"\n :name=\"getIconName\"\n :size=\"iconSize\"\n />\n <div\n v-else-if=\"isContactCenterType\"\n :class=\"contactCenterIconClasses\"\n />\n <div\n v-else-if=\"isDialbotType\"\n :class=\"dialbotClasses\"\n data-qa=\"general-row-dialbot\"\n >\n <dt-icon\n name=\"dialbot\"\n size=\"500\"\n />\n </div>\n</template>\n\n<script>\nimport { DtIcon } from '@/components/icon';\nimport {\n LEFTBAR_GENERAL_ROW_ICON_MAPPING as ICON_MAPPING,\n LEFTBAR_GENERAL_ROW_TYPES as TYPES,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS as COLORS,\n} from '@/recipes/leftbar/general_row/general_row_constants';\n\nexport default {\n name: 'DtRecipeLeftbarGeneralRowIcon',\n components: { DtIcon },\n props: {\n type: {\n type: String,\n default: null,\n },\n\n color: {\n type: String,\n default: null,\n },\n\n iconSize: {\n type: String,\n default: '300',\n },\n },\n\n computed: {\n isIconType () {\n return ![TYPES.DIALBOT, TYPES.CONTACT_CENTER].includes(this.type);\n },\n\n isContactCenterType () {\n return this.type === TYPES.CONTACT_CENTER;\n },\n\n isDialbotType () {\n return this.type === TYPES.DIALBOT;\n },\n\n getIconName () {\n return ICON_MAPPING[this.type];\n },\n\n contactCenterIconClasses () {\n return [\n 'dt-leftbar-row__icon-cc',\n COLORS[this.color],\n ];\n },\n\n dialbotClasses () {\n return [\n 'd-d-flex',\n 'd-ai-center',\n 'd-jc-center',\n ];\n },\n },\n};\n</script>\n","<template>\n <div\n :class=\"leftbarGeneralRowClasses\"\n data-qa=\"dt-leftbar-row\"\n >\n <a\n class=\"dt-leftbar-row__primary\"\n :data-qa=\"'data-qa' in $attrs ? $attrs['data-qa'] : 'dt-leftbar-row-link'\"\n :aria-label=\"getAriaLabel\"\n :title=\"description\"\n :href=\"'href' in $attrs ? $attrs.href : 'javascript:void(0)'\"\n v-bind=\"$attrs\"\n v-on=\"generalRowListeners\"\n >\n <div\n class=\"dt-leftbar-row__alpha\"\n >\n <div\n v-if=\"isTyping\"\n class=\"dt-leftbar-row__is-typing\"\n >\n <span /><span /><span />\n </div>\n <slot\n v-else\n name=\"left\"\n >\n <dt-recipe-leftbar-general-row-icon\n :type=\"getIcon\"\n :color=\"color\"\n :icon-size=\"iconSize\"\n data-qa=\"dt-leftbar-row-icon\"\n />\n </slot>\n </div>\n <div\n class=\"dt-leftbar-row__label\"\n :style=\"`flex-basis: ${labelWidth}`\"\n >\n <slot name=\"label\">\n <dt-emoji-text-wrapper\n class=\"dt-leftbar-row__description\"\n data-qa=\"dt-leftbar-row-description\"\n size=\"200\"\n >\n {{ description }}\n </dt-emoji-text-wrapper>\n </slot>\n </div>\n </a>\n <div\n v-if=\"hasActions\"\n class=\"dt-leftbar-row__omega\"\n >\n <dt-tooltip\n v-if=\"dndText\"\n placement=\"top\"\n :message=\"dndTextTooltip\"\n >\n <template #anchor>\n <div\n ref=\"dt-leftbar-row-dnd\"\n class=\"dt-leftbar-row__dnd\"\n data-qa=\"dt-leftbar-row-dnd\"\n >\n {{ dndText }}\n </div>\n </template>\n </dt-tooltip>\n <div\n v-if=\"activeVoiceChat\"\n class=\"dt-leftbar-row__active-voice\"\n >\n <dt-icon\n size=\"300\"\n name=\"waveform\"\n />\n </div>\n <dt-tooltip\n v-else-if=\"showUnreadCount || showUnreadMentionCount\"\n :message=\"unreadCountTooltip\"\n placement=\"top\"\n >\n <template #anchor>\n <dt-badge\n v-if=\"showUnreadCount\"\n kind=\"count\"\n type=\"bulletin\"\n data-qa=\"dt-leftbar-row-unread-badge\"\n :class=\"['dt-leftbar-row__unread-badge', {\n 'dt-leftbar-row__unread-count-badge':\n shouldApplyCustomStyleForCountBadge,\n }]\"\n >\n {{ unreadCount }}\n </dt-badge>\n <dt-badge\n v-if=\"showUnreadMentionCount\"\n kind=\"count\"\n type=\"bulletin\"\n data-qa=\"dt-leftbar-row-unread-mention-badge\"\n :class=\"['dt-leftbar-row__unread-badge',\n { 'dt-leftbar-row__unread-mention-count-badge': shouldApplyCustomStyleForCountBadge },\n ]\"\n >\n {{ unreadMentionCount }}\n </dt-badge>\n </template>\n </dt-tooltip>\n <div\n v-if=\"hasCallButton\"\n class=\"dt-leftbar-row__action\"\n data-qa=\"dt-leftbar-row-action\"\n >\n <dt-tooltip\n :message=\"callButtonTooltip\"\n placement=\"top\"\n >\n <template #anchor>\n <dt-button\n class=\"dt-leftbar-row__action-button\"\n data-qa=\"dt-leftbar-row-action-call-button\"\n :circle=\"true\"\n size=\"xs\"\n kind=\"inverted\"\n :aria-label=\"callButtonTooltip\"\n @focus=\"actionFocused = true\"\n @blur=\"actionFocused = false\"\n @click.stop=\"$emit('call', $event)\"\n >\n <template #icon>\n <dt-icon\n name=\"phone\"\n size=\"200\"\n />\n </template>\n </dt-button>\n </template>\n </dt-tooltip>\n </div>\n </div>\n </div>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport {\n LEFTBAR_GENERAL_ROW_TYPES,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR,\n LEFTBAR_GENERAL_ROW_ICON_SIZES,\n} from './general_row_constants';\nimport { DtBadge } from '@/components/badge';\nimport { DtIcon } from '@/components/icon';\nimport { DtButton } from '@/components/button';\nimport { DtTooltip } from '@/components/tooltip';\nimport DtEmojiTextWrapper from '@/components/emoji_text_wrapper/emoji_text_wrapper.vue';\nimport DtRecipeLeftbarGeneralRowIcon from './leftbar_general_row_icon.vue';\nimport { extractVueListeners, safeConcatStrings } from '@/common/utils';\n\nexport default {\n name: 'DtRecipeGeneralRow',\n\n components: {\n DtEmojiTextWrapper,\n DtBadge,\n DtIcon,\n DtButton,\n DtTooltip,\n DtRecipeLeftbarGeneralRowIcon,\n },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Determines the icon to show.\n * If type is contact center, the color prop must be provided and will determine the color of the icon\n */\n type: {\n type: String,\n default: 'inbox',\n validator: (type) => {\n return Object.values(LEFTBAR_GENERAL_ROW_TYPES).includes(type);\n },\n },\n\n /**\n * Will be read out by a screen reader upon focus of this row. If not defined \"description\" will be read.\n */\n ariaLabel: {\n type: String,\n default: '',\n },\n\n /**\n * Text displayed next to the icon. Required. Even if you are overriding this field using the label slot\n * you still must input this as it will be displayed as the \"title\" attribute for the row.\n */\n description: {\n type: String,\n required: true,\n },\n\n /**\n * Determines the color of the contact center icon\n */\n color: {\n type: String,\n default: null,\n validator: (color) => {\n return Object.keys(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS).includes(color);\n },\n },\n\n /**\n * Styles the row with an increased font weight to convey it has unreads. This must be true to see\n * the unread count badge.\n */\n hasUnreads: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Number of unread messages\n */\n unreadCount: {\n type: String,\n default: null,\n },\n\n /**\n * Number of unread mention messages\n */\n unreadMentionCount: {\n type: String,\n default: null,\n },\n\n /**\n * Text shown when the unread count is hovered.\n */\n unreadCountTooltip: {\n type: String,\n default: '',\n },\n\n /**\n * Determines if the row is selected\n */\n selected: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Gives a faded style to be used when muted\n */\n muted: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Shows styling to represent an active voice chat. This will display over unreadCount.\n */\n activeVoiceChat: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Acronym used to represent \"Do not Disturb\" state. If entered will display the entered text alongside\n * unreadCount.\n */\n dndText: {\n type: String,\n default: '',\n },\n\n /**\n * Text shown in tooltip when you hover the dndText\n */\n dndTextTooltip: {\n type: String,\n default: '',\n },\n\n /**\n * Whether the row should have a call button. Usually only applicable to individual contact rows.\n */\n hasCallButton: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Text shown when the call button is hovered.\n */\n callButtonTooltip: {\n type: String,\n default: '',\n },\n\n /**\n * Shows an \"is typing\" animation over the avatar when true.\n */\n isTyping: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Sets the size of the icon.\n */\n iconSize: {\n type: String,\n default: '300',\n validator: (size) => {\n return LEFTBAR_GENERAL_ROW_ICON_SIZES.includes(size);\n },\n },\n },\n\n emits: [\n /**\n * Call button clicked\n *\n * @event call\n * @type {PointerEvent | KeyboardEvent}\n */\n 'call',\n ],\n\n data () {\n return {\n actionFocused: false,\n labelWidth: '100%',\n };\n },\n\n computed: {\n leftbarGeneralRowClasses () {\n return [\n 'dt-leftbar-row',\n {\n 'dt-leftbar-row--no-action': !this.hasCallButton,\n 'dt-leftbar-row--has-unread': this.hasUnreads,\n 'dt-leftbar-row--unread-count': this.showUnreadCount || this.showUnreadMentionCount,\n 'dt-leftbar-row--selected': this.selected,\n 'dt-leftbar-row--muted': this.muted,\n 'dt-leftbar-row--action-focused': this.actionFocused,\n },\n ];\n },\n\n getIcon () {\n switch (this.type) {\n case LEFTBAR_GENERAL_ROW_TYPES.CHANNELS:\n if (this.hasUnreads) return 'channel unread';\n break;\n case LEFTBAR_GENERAL_ROW_TYPES.LOCKED_CHANNEL:\n if (this.hasUnreads) return 'locked channel unread';\n break;\n }\n return this.type;\n },\n\n generalRowListeners () {\n return extractVueListeners(this.$attrs);\n },\n\n getAriaLabel () {\n return this.ariaLabel\n ? this.ariaLabel\n : safeConcatStrings([this.description, this.unreadCountTooltip, this.dndTextTooltip]);\n },\n\n hasActions () {\n return this.dndText || this.activeVoiceChat || this.showUnreadCount || this.hasCallButton ||\n this.showUnreadMentionCount;\n },\n\n showUnreadCount () {\n return !!this.unreadCount && this.hasUnreads;\n },\n\n showUnreadMentionCount () {\n return !!this.unreadMentionCount && this.hasUnreads;\n },\n\n hasUnreadCount () {\n return this.unreadCount !== null;\n },\n\n hasUnreadMentionCount () {\n return this.unreadMentionCount !== null;\n },\n\n shouldApplyCustomStyleForCountBadge () {\n return this.hasUnreadCount && this.hasUnreadMentionCount;\n },\n },\n\n watch: {\n $props: {\n immediate: true,\n deep: true,\n async handler () {\n this.validateProps();\n await this.$nextTick();\n this.adjustLabelWidth();\n },\n },\n },\n\n mounted () {\n this.resizeObserver = new ResizeObserver(this.adjustLabelWidth);\n this.resizeObserver.observe(this.$el);\n this.adjustLabelWidth();\n },\n\n beforeUnmount: function () {\n this.resizeObserver.disconnect();\n },\n\n methods: {\n validateProps () {\n if (this.type === LEFTBAR_GENERAL_ROW_TYPES.CONTACT_CENTER &&\n !Object.keys(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS).includes(this.color)) {\n console.error(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR);\n }\n },\n\n adjustLabelWidth () {\n const labelWidth = this.$el?.querySelector('.dt-leftbar-row__primary')?.clientWidth || 0;\n const omegaWidth = this.$el?.querySelector('.dt-leftbar-row__omega')?.clientWidth || 0;\n const alphaWidth = this.$el?.querySelector('.dt-leftbar-row__alpha')?.clientWidth || 0;\n const paddings = 16;\n this.labelWidth = labelWidth - (omegaWidth + alphaWidth + paddings) + 'px';\n },\n },\n};\n</script>\n\n<style lang=\"less\" scoped>\n@import \"../style/leftbar_row.less\";\n</style>\n"],"names":["_sfc_main","DtIcon","TYPES","ICON_MAPPING","COLORS","_createBlock","_createElementBlock","_createVNode","DtEmojiTextWrapper","DtBadge","DtButton","DtTooltip","extractVueListeners","safeConcatStrings","_createElementVNode","_mergeProps","_toHandlers","_openBlock","_renderSlot","_normalizeClass","_withModifiers"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"general-row.cjs","sources":["../../recipes/leftbar/general_row/general_row_constants.js","../../recipes/leftbar/general_row/leftbar_general_row_icon.vue","../../recipes/leftbar/general_row/general_row.vue"],"sourcesContent":["export const LEFTBAR_GENERAL_ROW_TYPES = {\n INBOX: 'inbox',\n CONTACTS: 'contacts',\n CHANNELS: 'channels',\n THREADS: 'threads',\n LAUNCHPAD: 'launchpad',\n LOCKED_CHANNEL: 'locked channel',\n CONTACT_CENTER: 'contact center',\n QUICK_START: 'quick start',\n COACHING_GROUP: 'coaching group',\n COACHING_CENTER: 'coaching center',\n DIALBOT: 'dialbot',\n ASSIGNED: 'assigned',\n DIGITAL: 'digital',\n};\n\nexport const LEFTBAR_GENERAL_ROW_ICON_MAPPING = {\n [LEFTBAR_GENERAL_ROW_TYPES.INBOX]: 'inbox',\n [LEFTBAR_GENERAL_ROW_TYPES.CONTACTS]: 'contacts',\n [LEFTBAR_GENERAL_ROW_TYPES.CHANNELS]: 'hash',\n [LEFTBAR_GENERAL_ROW_TYPES.THREADS]: 'thread',\n [LEFTBAR_GENERAL_ROW_TYPES.LAUNCHPAD]: 'layout-template',\n [LEFTBAR_GENERAL_ROW_TYPES.LOCKED_CHANNEL]: 'lock',\n [LEFTBAR_GENERAL_ROW_TYPES.QUICK_START]: 'sparkle',\n [LEFTBAR_GENERAL_ROW_TYPES.COACHING_GROUP]: 'users',\n [LEFTBAR_GENERAL_ROW_TYPES.COACHING_CENTER]: 'external-link',\n 'locked channel unread': 'lock-filled',\n 'channel unread': 'hash-bold',\n [LEFTBAR_GENERAL_ROW_TYPES.ASSIGNED]: 'at-sign',\n [LEFTBAR_GENERAL_ROW_TYPES.DIGITAL]: 'laptop-2',\n};\n\nexport const LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS = {\n 'magenta-200': 'd-bgc-magenta-200',\n 'green-200': 'd-bgc-green-200',\n 'gold-300': 'd-bgc-gold-300',\n 'purple-600': 'd-bgc-purple-600',\n 'magenta-300': 'd-bgc-magenta-300',\n 'purple-300': 'd-bgc-purple-300',\n 'green-500': 'd-bgc-green-500',\n 'purple-100': 'd-bgc-purple-100',\n 'magenta-400': 'd-bgc-magenta-400',\n 'magenta-100': 'd-bgc-magenta-100',\n 'black-300': 'd-bgc-black-300',\n};\n\nexport const LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR = 'If type is contact center, color must be one' +\n 'of the following:' + Object.keys(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS).join(', ');\n\nexport const LEFTBAR_GENERAL_ROW_ICON_SIZES = [\n '300',\n '200',\n];\n\nexport default {\n LEFTBAR_GENERAL_ROW_TYPES,\n LEFTBAR_GENERAL_ROW_ICON_MAPPING,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR,\n LEFTBAR_GENERAL_ROW_ICON_SIZES,\n};\n","<template>\n <dt-icon\n v-if=\"isIconType\"\n :name=\"getIconName\"\n :size=\"iconSize\"\n />\n <div\n v-else-if=\"isContactCenterType\"\n :class=\"contactCenterIconClasses\"\n />\n <div\n v-else-if=\"isDialbotType\"\n :class=\"dialbotClasses\"\n data-qa=\"general-row-dialbot\"\n >\n <dt-icon\n name=\"dialbot\"\n size=\"500\"\n />\n </div>\n</template>\n\n<script>\nimport { DtIcon } from '@/components/icon';\nimport {\n LEFTBAR_GENERAL_ROW_ICON_MAPPING as ICON_MAPPING,\n LEFTBAR_GENERAL_ROW_TYPES as TYPES,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS as COLORS,\n} from '@/recipes/leftbar/general_row/general_row_constants';\n\nexport default {\n name: 'DtRecipeLeftbarGeneralRowIcon',\n components: { DtIcon },\n props: {\n type: {\n type: String,\n default: null,\n },\n\n color: {\n type: String,\n default: null,\n },\n\n iconSize: {\n type: String,\n default: '300',\n },\n },\n\n computed: {\n isIconType () {\n return ![TYPES.DIALBOT, TYPES.CONTACT_CENTER].includes(this.type);\n },\n\n isContactCenterType () {\n return this.type === TYPES.CONTACT_CENTER;\n },\n\n isDialbotType () {\n return this.type === TYPES.DIALBOT;\n },\n\n getIconName () {\n return ICON_MAPPING[this.type];\n },\n\n contactCenterIconClasses () {\n return [\n 'dt-leftbar-row__icon-cc',\n COLORS[this.color],\n ];\n },\n\n dialbotClasses () {\n return [\n 'd-d-flex',\n 'd-ai-center',\n 'd-jc-center',\n ];\n },\n },\n};\n</script>\n","<template>\n <div\n :class=\"leftbarGeneralRowClasses\"\n data-qa=\"dt-leftbar-row\"\n >\n <a\n class=\"dt-leftbar-row__primary\"\n :data-qa=\"'data-qa' in $attrs ? $attrs['data-qa'] : 'dt-leftbar-row-link'\"\n :aria-label=\"getAriaLabel\"\n :title=\"description\"\n :href=\"'href' in $attrs ? $attrs.href : 'javascript:void(0)'\"\n v-bind=\"$attrs\"\n v-on=\"generalRowListeners\"\n >\n <div\n class=\"dt-leftbar-row__alpha\"\n >\n <div\n v-if=\"isTyping\"\n class=\"dt-leftbar-row__is-typing\"\n >\n <span /><span /><span />\n </div>\n <slot\n v-else\n name=\"left\"\n >\n <dt-recipe-leftbar-general-row-icon\n :type=\"getIcon\"\n :color=\"color\"\n :icon-size=\"iconSize\"\n data-qa=\"dt-leftbar-row-icon\"\n />\n </slot>\n </div>\n <div\n class=\"dt-leftbar-row__label\"\n :style=\"`flex-basis: ${labelWidth}`\"\n >\n <slot name=\"label\">\n <dt-emoji-text-wrapper\n class=\"dt-leftbar-row__description\"\n data-qa=\"dt-leftbar-row-description\"\n size=\"200\"\n >\n {{ description }}\n </dt-emoji-text-wrapper>\n </slot>\n </div>\n </a>\n <div\n v-if=\"hasActions\"\n class=\"dt-leftbar-row__omega\"\n >\n <dt-tooltip\n v-if=\"dndText\"\n placement=\"top\"\n :message=\"dndTextTooltip\"\n >\n <template #anchor>\n <div\n ref=\"dt-leftbar-row-dnd\"\n class=\"dt-leftbar-row__dnd\"\n data-qa=\"dt-leftbar-row-dnd\"\n >\n {{ dndText }}\n </div>\n </template>\n </dt-tooltip>\n <div\n v-if=\"activeVoiceChat\"\n class=\"dt-leftbar-row__active-voice\"\n >\n <dt-icon\n size=\"300\"\n name=\"waveform\"\n />\n </div>\n <dt-tooltip\n v-else-if=\"showUnreadCount || showUnreadMentionCount\"\n :message=\"unreadCountTooltip\"\n placement=\"top\"\n >\n <template #anchor>\n <dt-badge\n v-if=\"showUnreadCount\"\n kind=\"count\"\n type=\"bulletin\"\n data-qa=\"dt-leftbar-row-unread-badge\"\n :class=\"['dt-leftbar-row__unread-badge', {\n 'dt-leftbar-row__unread-count-badge':\n shouldApplyCustomStyleForCountBadge,\n }]\"\n >\n {{ unreadCount }}\n </dt-badge>\n <dt-badge\n v-if=\"showUnreadMentionCount\"\n kind=\"count\"\n type=\"bulletin\"\n data-qa=\"dt-leftbar-row-unread-mention-badge\"\n :class=\"['dt-leftbar-row__unread-badge',\n { 'dt-leftbar-row__unread-mention-count-badge': shouldApplyCustomStyleForCountBadge },\n { 'dt-leftbar-row__unread-mention-only-count-badge': shouldApplyCustomStyleForMentionOnly },\n ]\"\n >\n {{ unreadMentionCount }}\n </dt-badge>\n </template>\n </dt-tooltip>\n <div\n v-if=\"hasCallButton\"\n class=\"dt-leftbar-row__action\"\n data-qa=\"dt-leftbar-row-action\"\n >\n <dt-tooltip\n :message=\"callButtonTooltip\"\n placement=\"top\"\n >\n <template #anchor>\n <dt-button\n class=\"dt-leftbar-row__action-button\"\n data-qa=\"dt-leftbar-row-action-call-button\"\n :circle=\"true\"\n size=\"xs\"\n kind=\"inverted\"\n :aria-label=\"callButtonTooltip\"\n @focus=\"actionFocused = true\"\n @blur=\"actionFocused = false\"\n @click.stop=\"$emit('call', $event)\"\n >\n <template #icon>\n <dt-icon\n name=\"phone\"\n size=\"200\"\n />\n </template>\n </dt-button>\n </template>\n </dt-tooltip>\n </div>\n </div>\n </div>\n</template>\n\n<script>\n/* eslint-disable max-lines */\nimport {\n LEFTBAR_GENERAL_ROW_TYPES,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS,\n LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR,\n LEFTBAR_GENERAL_ROW_ICON_SIZES,\n} from './general_row_constants';\nimport { DtBadge } from '@/components/badge';\nimport { DtIcon } from '@/components/icon';\nimport { DtButton } from '@/components/button';\nimport { DtTooltip } from '@/components/tooltip';\nimport DtEmojiTextWrapper from '@/components/emoji_text_wrapper/emoji_text_wrapper.vue';\nimport DtRecipeLeftbarGeneralRowIcon from './leftbar_general_row_icon.vue';\nimport { extractVueListeners, safeConcatStrings } from '@/common/utils';\n\nexport default {\n name: 'DtRecipeGeneralRow',\n\n components: {\n DtEmojiTextWrapper,\n DtBadge,\n DtIcon,\n DtButton,\n DtTooltip,\n DtRecipeLeftbarGeneralRowIcon,\n },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Determines the icon to show.\n * If type is contact center, the color prop must be provided and will determine the color of the icon\n */\n type: {\n type: String,\n default: 'inbox',\n validator: (type) => {\n return Object.values(LEFTBAR_GENERAL_ROW_TYPES).includes(type);\n },\n },\n\n /**\n * Will be read out by a screen reader upon focus of this row. If not defined \"description\" will be read.\n */\n ariaLabel: {\n type: String,\n default: '',\n },\n\n /**\n * Text displayed next to the icon. Required. Even if you are overriding this field using the label slot\n * you still must input this as it will be displayed as the \"title\" attribute for the row.\n */\n description: {\n type: String,\n required: true,\n },\n\n /**\n * Determines the color of the contact center icon\n */\n color: {\n type: String,\n default: null,\n validator: (color) => {\n return Object.keys(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS).includes(color);\n },\n },\n\n /**\n * The channel setting, either 'mention' or 'always'.\n * @values 'mention', 'always', null.\n */\n channelSetting: {\n type: String,\n default: null,\n },\n\n /**\n * Styles the row with an increased font weight to convey it has unreads. This must be true to see\n * the unread count badge.\n */\n hasUnreads: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Number of unread messages\n */\n unreadCount: {\n type: String,\n default: null,\n },\n\n /**\n * Number of unread mention messages\n */\n unreadMentionCount: {\n type: String,\n default: null,\n },\n\n /**\n * Text shown when the unread count is hovered.\n */\n unreadCountTooltip: {\n type: String,\n default: '',\n },\n\n /**\n * Determines if the row is selected\n */\n selected: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Gives a faded style to be used when muted\n */\n muted: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Shows styling to represent an active voice chat. This will display over unreadCount.\n */\n activeVoiceChat: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Acronym used to represent \"Do not Disturb\" state. If entered will display the entered text alongside\n * unreadCount.\n */\n dndText: {\n type: String,\n default: '',\n },\n\n /**\n * Text shown in tooltip when you hover the dndText\n */\n dndTextTooltip: {\n type: String,\n default: '',\n },\n\n /**\n * Whether the row should have a call button. Usually only applicable to individual contact rows.\n */\n hasCallButton: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Text shown when the call button is hovered.\n */\n callButtonTooltip: {\n type: String,\n default: '',\n },\n\n /**\n * Shows an \"is typing\" animation over the avatar when true.\n */\n isTyping: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Sets the size of the icon.\n */\n iconSize: {\n type: String,\n default: '300',\n validator: (size) => {\n return LEFTBAR_GENERAL_ROW_ICON_SIZES.includes(size);\n },\n },\n },\n\n emits: [\n /**\n * Call button clicked\n *\n * @event call\n * @type {PointerEvent | KeyboardEvent}\n */\n 'call',\n ],\n\n data () {\n return {\n actionFocused: false,\n labelWidth: '100%',\n };\n },\n\n computed: {\n leftbarGeneralRowClasses () {\n return [\n 'dt-leftbar-row',\n {\n 'dt-leftbar-row--no-action': !this.hasCallButton,\n 'dt-leftbar-row--has-unread': this.hasUnreads,\n 'dt-leftbar-row--unread-count': this.showUnreadCount || this.showUnreadMentionCount,\n 'dt-leftbar-row--selected': this.selected,\n 'dt-leftbar-row--muted': this.muted,\n 'dt-leftbar-row--action-focused': this.actionFocused,\n },\n ];\n },\n\n getIcon () {\n switch (this.type) {\n case LEFTBAR_GENERAL_ROW_TYPES.CHANNELS:\n if (this.hasUnreads) return 'channel unread';\n break;\n case LEFTBAR_GENERAL_ROW_TYPES.LOCKED_CHANNEL:\n if (this.hasUnreads) return 'locked channel unread';\n break;\n }\n return this.type;\n },\n\n generalRowListeners () {\n return extractVueListeners(this.$attrs);\n },\n\n getAriaLabel () {\n return this.ariaLabel\n ? this.ariaLabel\n : safeConcatStrings([this.description, this.unreadCountTooltip, this.dndTextTooltip]);\n },\n\n hasActions () {\n return this.dndText || this.activeVoiceChat || this.showUnreadCount || this.hasCallButton ||\n this.showUnreadMentionCount;\n },\n\n showUnreadCount () {\n return !!this.unreadCount && this.hasUnreads;\n },\n\n showUnreadMentionCount () {\n return !!this.unreadMentionCount && this.hasUnreads;\n },\n\n hasUnreadCount () {\n return this.unreadCount !== null;\n },\n\n hasUnreadMentionCount () {\n return this.unreadMentionCount !== null;\n },\n\n shouldApplyCustomStyleForCountBadge () {\n return this.hasUnreadCount && this.hasUnreadMentionCount;\n },\n\n /**\n * When a channel in 'always' setting, meaning the user should see both unread count and unread mention count,\n * if there are only mention messages, we should apply the custom background with var(--dt-color-purple-500).\n * @returns {boolean}\n */\n shouldApplyCustomStyleForMentionOnly () {\n return this.channelSetting === 'always' && !this.hasUnreadCount && this.hasUnreadMentionCount;\n },\n },\n\n watch: {\n $props: {\n immediate: true,\n deep: true,\n async handler () {\n this.validateProps();\n await this.$nextTick();\n this.adjustLabelWidth();\n },\n },\n },\n\n mounted () {\n this.resizeObserver = new ResizeObserver(this.adjustLabelWidth);\n this.resizeObserver.observe(this.$el);\n this.adjustLabelWidth();\n },\n\n beforeUnmount: function () {\n this.resizeObserver.disconnect();\n },\n\n methods: {\n validateProps () {\n if (this.type === LEFTBAR_GENERAL_ROW_TYPES.CONTACT_CENTER &&\n !Object.keys(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS).includes(this.color)) {\n console.error(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_VALIDATION_ERROR);\n }\n },\n\n adjustLabelWidth () {\n const labelWidth = this.$el?.querySelector('.dt-leftbar-row__primary')?.clientWidth || 0;\n const omegaWidth = this.$el?.querySelector('.dt-leftbar-row__omega')?.clientWidth || 0;\n const alphaWidth = this.$el?.querySelector('.dt-leftbar-row__alpha')?.clientWidth || 0;\n const paddings = 16;\n this.labelWidth = labelWidth - (omegaWidth + alphaWidth + paddings) + 'px';\n },\n },\n};\n</script>\n\n<style lang=\"less\" scoped>\n@import \"../style/leftbar_row.less\";\n</style>\n"],"names":["_sfc_main","DtIcon","TYPES","ICON_MAPPING","COLORS","_createBlock","_createElementBlock","_createVNode","DtEmojiTextWrapper","DtBadge","DtButton","DtTooltip","extractVueListeners","safeConcatStrings","_createElementVNode","_mergeProps","_toHandlers","_openBlock","_renderSlot","_normalizeClass","_withModifiers"],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ import "./skeleton.js";
|
|
|
15
15
|
import "@dialpad/dialtone-icons/vue3";
|
|
16
16
|
import "../common/constants.js";
|
|
17
17
|
import "../chunks/link_constants-AfTWrr-n.js";
|
|
18
|
-
import "../chunks/popover_constants-
|
|
18
|
+
import "../chunks/popover_constants-WsOUIY-m.js";
|
|
19
19
|
import "tippy.js";
|
|
20
20
|
const LEFTBAR_GENERAL_ROW_TYPES = {
|
|
21
21
|
INBOX: "inbox",
|
|
@@ -179,6 +179,14 @@ const _sfc_main = {
|
|
|
179
179
|
return Object.keys(LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS).includes(color);
|
|
180
180
|
}
|
|
181
181
|
},
|
|
182
|
+
/**
|
|
183
|
+
* The channel setting, either 'mention' or 'always'.
|
|
184
|
+
* @values 'mention', 'always', null.
|
|
185
|
+
*/
|
|
186
|
+
channelSetting: {
|
|
187
|
+
type: String,
|
|
188
|
+
default: null
|
|
189
|
+
},
|
|
182
190
|
/**
|
|
183
191
|
* Styles the row with an increased font weight to convey it has unreads. This must be true to see
|
|
184
192
|
* the unread count badge.
|
|
@@ -341,6 +349,14 @@ const _sfc_main = {
|
|
|
341
349
|
},
|
|
342
350
|
shouldApplyCustomStyleForCountBadge() {
|
|
343
351
|
return this.hasUnreadCount && this.hasUnreadMentionCount;
|
|
352
|
+
},
|
|
353
|
+
/**
|
|
354
|
+
* When a channel in 'always' setting, meaning the user should see both unread count and unread mention count,
|
|
355
|
+
* if there are only mention messages, we should apply the custom background with var(--dt-color-purple-500).
|
|
356
|
+
* @returns {boolean}
|
|
357
|
+
*/
|
|
358
|
+
shouldApplyCustomStyleForMentionOnly() {
|
|
359
|
+
return this.channelSetting === "always" && !this.hasUnreadCount && this.hasUnreadMentionCount;
|
|
344
360
|
}
|
|
345
361
|
},
|
|
346
362
|
watch: {
|
|
@@ -378,7 +394,7 @@ const _sfc_main = {
|
|
|
378
394
|
}
|
|
379
395
|
}
|
|
380
396
|
};
|
|
381
|
-
const _withScopeId = (n) => (pushScopeId("data-v-
|
|
397
|
+
const _withScopeId = (n) => (pushScopeId("data-v-4793665c"), n = n(), popScopeId(), n);
|
|
382
398
|
const _hoisted_1 = ["data-qa", "aria-label", "title", "href"];
|
|
383
399
|
const _hoisted_2 = { class: "dt-leftbar-row__alpha" };
|
|
384
400
|
const _hoisted_3 = {
|
|
@@ -499,7 +515,8 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
499
515
|
"data-qa": "dt-leftbar-row-unread-mention-badge",
|
|
500
516
|
class: normalizeClass([
|
|
501
517
|
"dt-leftbar-row__unread-badge",
|
|
502
|
-
{ "dt-leftbar-row__unread-mention-count-badge": $options.shouldApplyCustomStyleForCountBadge }
|
|
518
|
+
{ "dt-leftbar-row__unread-mention-count-badge": $options.shouldApplyCustomStyleForCountBadge },
|
|
519
|
+
{ "dt-leftbar-row__unread-mention-only-count-badge": $options.shouldApplyCustomStyleForMentionOnly }
|
|
503
520
|
])
|
|
504
521
|
}, {
|
|
505
522
|
default: withCtx(() => [
|
|
@@ -542,7 +559,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
542
559
|
])) : createCommentVNode("", true)
|
|
543
560
|
], 2);
|
|
544
561
|
}
|
|
545
|
-
const DtRecipeGeneralRow = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-
|
|
562
|
+
const DtRecipeGeneralRow = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-4793665c"]]);
|
|
546
563
|
export {
|
|
547
564
|
DtRecipeGeneralRow,
|
|
548
565
|
LEFTBAR_GENERAL_ROW_CONTACT_CENTER_COLORS,
|