{"version":3,"file":"emoji_picker-Cl-T4BXK.cjs","names":["$emit","ARROW_KEYS","$refs"],"sources":["../components/emoji_picker/modules/emoji_search.vue","../components/emoji_picker/modules/emoji_tabset.vue","../components/emoji_picker/composables/useKeyboardNavigation.js","../components/emoji_picker/modules/emoji_selector.vue","../components/emoji_picker/modules/emoji_skin_selector.vue","../components/emoji_picker/modules/emoji_description.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-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          size=\"xs\"\n          class=\"d-emoji-picker__search-x-button\"\n          circle\n          kind=\"muted\"\n          @click=\"clearSearch\"\n        >\n          <template #icon>\n            <dt-icon-close\n              size=\"200\"\n            />\n          </template>\n        </dt-button>\n      </template>\n    </dt-input>\n  </div>\n</template>\n\n<script setup>\nimport { DtIconSearch, DtIconClose } from '@dialpad/dialtone-icons/vue3';\nimport { DtInput } from '@/components/input';\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      :selected=\"selectedTab\"\n      size=\"sm\"\n      tab-list-class=\"d-emoji-picker__tabset-list\"\n    >\n      <template #tabs>\n        <dt-tab\n          v-for=\"(tab, index) in tabs\"\n          :id=\"tab.id\"\n          :key=\"tab.id\"\n          :ref=\"el => { if (el) setTabsetRef(el) }\"\n          :label=\"tab.label\"\n          :panel-id=\"tab.panelId\"\n          :tabindex=\"index + 1\"\n          aria-controls=\"d-emoji-picker-list\"\n          @keydown=\"handleKeyDown($event, tab.id)\"\n          @click.capture.stop=\"selectTabset(tab.id)\"\n        >\n          <component\n            :is=\"tab.icon\"\n            size=\"400\"\n          />\n        </dt-tab>\n      </template>\n    </dt-tab-group>\n  </div>\n</template>\n\n<script setup>\nimport { computed, ref, watch } from 'vue';\nimport { DtTab, DtTabGroup } from '@/components/tab';\nimport { returnFirstEl } from '@/common/utils';\nimport {\n  DtIconClock,\n  DtIconSatisfied,\n  DtIconLivingThing,\n  DtIconFood,\n  DtIconObject,\n  DtIconTransportation,\n  DtIconLightbulb,\n  DtIconHeart,\n  DtIconFlag,\n  DtIconDialpadStar,\n} from '@dialpad/dialtone-icons/vue3';\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  /**\n   * Whether to show the custom emojis tab or not\n   * @type {Boolean}\n   * @default false\n   */\n  showCustomEmojisTab: {\n    type: Boolean,\n    default: false,\n  },\n\n  scrollIntoTab: {\n    type: Number,\n    required: true,\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: props.tabSetLabels[0], icon: DtIconClock },\n  { label: props.tabSetLabels[1], icon: DtIconSatisfied },\n  { label: props.tabSetLabels[2], icon: DtIconLivingThing },\n  { label: props.tabSetLabels[3], icon: DtIconFood },\n  { label: props.tabSetLabels[4], icon: DtIconObject },\n  { label: props.tabSetLabels[5], icon: DtIconTransportation },\n  { label: props.tabSetLabels[6], icon: DtIconLightbulb },\n  { label: props.tabSetLabels[7], icon: DtIconHeart },\n  { label: props.tabSetLabels[8], icon: DtIconFlag },\n  { label: props.tabSetLabels[9], icon: DtIconDialpadStar },\n];\n\nconst tabs = computed(() => {\n  const tabsData = props.showRecentlyUsedTab ? TABS_DATA : TABS_DATA.slice(1);\n  // if showCustomEmojisTab is false remove last index of TABS_DATA\n  if (!props.showCustomEmojisTab) {\n    tabsData.pop();\n  }\n\n  return tabsData.map((tab, index) => ({\n    ...tab,\n    // IDs on dt-tab component need to be on string\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 tabsetRef = ref([]);\n\nwatch(() => props.scrollIntoTab,\n  () => {\n    if (!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  // IDs on scrollToTab need to be on number\n  const parseId = parseInt(id);\n  // IDs on dt-tab component need to be on string\n  selectedTab.value = id;\n  emits('selected-tabset', parseId);\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(returnFirstEl(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","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=\"event => selectEmoji(emoji, event)\"\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)\"\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=\"event => selectEmoji(emoji, event)\"\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-lines */\nimport { emojisGrouped as emojis } from '@dialpad/dialtone-emojis';\nimport { computed, onMounted, onBeforeUnmount, 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  /**\n   * The list of custom emojis\n   * @type {Array}\n   */\n  customEmojis: {\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 user reach bottom scroll\n   * This event is used on handleScroll method\n   * @event scroll-bottom-reached\n   */\n  'scroll-bottom-reached',\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', 'Custom'];\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 or custom emojis list is empty\n * If it is empty, it will remove it\n */\nconst tabLabels = computed(() => {\n  let updateTabLabels = props.tabsetLabels.map((label) => ({ label, ref: ref(null) }));\n\n  if (props.recentlyUsedEmojis && !props.recentlyUsedEmojis.length) {\n    updateTabLabels = props.tabsetLabels.slice(1).map((label) => ({ label, ref: ref(null) }));\n  }\n\n  if (props.customEmojis && !props.customEmojis.length) {\n    updateTabLabels.pop();\n  }\n\n  return updateTabLabels;\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 or custom emojis is empty\n * If it is empty, it will remove it\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  const updateTabsOrder = props.recentlyUsedEmojis.length ? TABS_DATA.slice() : TABS_DATA.slice(1);\n\n  if (props.customEmojis && !props.customEmojis.length) {\n    updateTabsOrder.pop();\n  }\n\n  return updateTabsOrder;\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 * handleScroll will be defined when user scroll\n */\nconst handleScroll = () => {\n  const container = listRef.value;\n  // TODO -- this will probably need to be updated if we add more emojis.\n  // because the container height will change.\n  // maybe with a nextTick similar of scrollToTab.\n  if (container.scrollTop + container.clientHeight >= container.scrollHeight) {\n    emits('scroll-bottom-reached');\n  }\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 * Update the custom emojis list on custom emojis prop changes\n * @listens customEmojis\n */\nwatch(() => props.customEmojis,\n  () => {\n    emojis.Custom = props.customEmojis;\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  // TODO Update json structure to have a property for custom emojis and avoid using date_added\n  if (emoji.date_added) { // if custom emoji\n    return emoji.image;\n  } else { // if regular emoji\n    return CDN_URL + emoji.unicode_character + '.png';\n  }\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 - 15;\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\nfunction setBottomScrollListener () {\n  listRef.value.addEventListener('scroll', handleScroll);\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(async (entries) => {\n    // eslint-disable-next-line complexity\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, event);\n      break;\n    default:\n      break;\n  }\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, event);\n      break;\n\n    default:\n      break;\n  }\n};\n\nfunction selectEmoji (emoji, event) {\n  emits('selected-emoji', { ...emoji, shift_key: event.shiftKey });\n}\n\nfunction highlightEmoji (emoji) {\n  emits('highlighted-emoji', emoji);\n}\n\nfunction focusEmojiSelector () {\n  focusEmoji(0, 0);\n}\n\nfunction focusLastEmoji () {\n  scrollToTab(tabs.value.length, true);\n}\n\nonMounted(() => {\n  setTabLabelObserver();\n  setBottomScrollListener();\n});\n\nonBeforeUnmount(() => {\n  tabLabelObserver.value.disconnect();\n  listRef.value.removeEventListener('scroll', handleScroll);\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/emoji_picker_constants.js';\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 class=\"d-emoji-picker__data\">\n    <img\n      v-if=\"emoji\"\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)\"\n    >\n    <div>{{ emoji?.name }}</div>\n  </div>\n</template>\n\n<script setup>\nimport { CDN_URL } from '@/components/emoji_picker/emoji_picker_constants';\n\ndefineProps({\n  /**\n   * Emoji data\n   * @type {Object}\n   * @default null\n   */\n  emoji: {\n    type: Object,\n    default: null,\n  },\n});\n\nfunction getImgSrc (emoji) {\n  if (emoji.date_added) { // if custom emoji\n    return emoji.image;\n  } else { // if regular emoji\n    return `${CDN_URL + emoji.unicode_character}.png`;\n  }\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-custom-emojis-tab=\"showCustomEmojisTab\"\n        :show-recently-used-tab=\"showRecentlyUsedTab\"\n        :scroll-into-tab=\"scrollIntoTab\"\n        :tab-set-labels=\"tabSetLabels\"\n        @focus-skin-selector=\"$refs.skinSelectorRef.focusSkinSelector()\"\n        @focus-search-input=\"showSearch\n          ? $refs.searchInputRef.focusSearchInput()\n          : $refs.emojiSelectorRef.focusEmojiSelector()\"\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        :custom-emojis=\"customEmojis\"\n        :selected-tabset=\"selectedTabset\"\n        @scroll-into-tab=\"updateScrollIntoTab\"\n        @highlighted-emoji=\"updateHighlightedEmoji\"\n        @selected-emoji=\"emits('selected-emoji', $event)\"\n        @focus-skin-selector=\"$refs.skinSelectorRef.focusSkinSelector()\"\n        @focus-search-input=\"showSearch ? $refs.searchInputRef.focusSearchInput() : $refs.tabsetRef.focusTabset()\"\n        @keydown.esc=\"emits('close')\"\n        @scroll-bottom-reached=\"emits('scroll-bottom-reached')\"\n      />\n    </div>\n    <div class=\"d-emoji-picker--footer\">\n      <dt-button\n        v-if=\"showAddEmojiButton && !highlightedEmoji\"\n        importance=\"outlined\"\n        :aria-label=\"addEmojiLabel\"\n        class=\"d-emoji-picker__add-emoji\"\n        @click=\"emits('add-emoji')\"\n      >\n        {{ addEmojiLabel }}\n      </dt-button>\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 { DtButton } from '../button';\nimport { computed, ref, watch } from 'vue';\nimport { DialtoneLocalization } from '@/localization';\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 array with custom emojis object\n     * This list is necessary to fill the custom tab\n     * @type {Array}\n     * @default []\n     * @example\n     * <dt-emoji-picker :customEmojis=\"[emojiObject, emojiObject]\" />\n     */\n  customEmojis: {\n    type: Array,\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\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  /**\n     * Shows the add emoji button in the footer when no emoji is highlighted\n     * @type {Boolean}\n     * @example\n     * <dt-emoji-picker :show-add-emoji-button=\"true\" />\n     */\n    showAddEmojiButton: {\n      type: Boolean,\n      default: false,\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   * Emitted when the user reach bottom scroll\n   * This is being handled by handleScroll method\n   * @event scroll-bottom-reached\n   */\n    'scroll-bottom-reached',\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     * Emitted when the user clicks on the add emoji button\n     * @event add-emoji\n     */\n    'add-emoji',\n  ],\n);\n\nconst internalSearchQuery = ref(props.searchQuery.value);\nconst highlightedEmoji = ref(null);\nconst selectedTabset = ref({});\n\nconst scrollIntoTab = ref(0);\n\nconst showRecentlyUsedTab = computed(() => props.recentlyUsedEmojis?.length > 0);\nconst showCustomEmojisTab = computed(() => props.customEmojis?.length > 0);\n\nconst i18n = new DialtoneLocalization();\n\nconst tabSetLabels = [\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_RECENTLY_USED_LABEL'),\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_SMILEYS_AND_PEOPLE_LABEL'),\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_NATURE_LABEL'),\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_FOOD_LABEL'),\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_ACTIVITY_LABEL'),\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_TRAVEL_LABEL'),\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_OBJECTS_LABEL'),\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_SYMBOLS_LABEL'),\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_FLAGS_LABEL'),\n  i18n.$t('DIALTONE_EMOJI_PICKER_TABSET_CUSTOM_LABEL'),\n];\n\nconst searchPlaceholderLabel = i18n.$t('DIALTONE_EMOJI_PICKER_SEARCH_PLACEHOLDER_LABEL');\nconst searchResultsLabel = i18n.$t('DIALTONE_EMOJI_PICKER_SEARCH_RESULTS_LABEL');\nconst searchNoResultsLabel = i18n.$t('DIALTONE_EMOJI_PICKER_SEARCH_NO_RESULTS_LABEL');\nconst skinSelectorButtonTooltipLabel = i18n.$t('DIALTONE_EMOJI_PICKER_SKIN_SELECTOR_BUTTON_TOOLTIP_LABEL');\nconst addEmojiLabel = i18n.$t('DIALTONE_EMOJI_PICKER_ADD_EMOJI_LABEL');\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 tabId {String} - The id of the tab that was selected\n */\nfunction scrollToSelectedTabset (tabId) {\n  internalSearchQuery.value = '';\n  selectedTabset.value = { ...selectedTabset.value, tabId };\n}\n\nfunction updateScrollIntoTab (value) {\n  scrollIntoTab.value = value;\n}\n\nfunction updateHighlightedEmoji (emoji) {\n  highlightedEmoji.value = emoji;\n}\n</script>\n"],"mappings":"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"}