@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
1,064 lines (1,063 loc) • 33.6 kB
JavaScript
import { ref as k, onMounted as ue, openBlock as h, createElementBlock as R, createVNode as O, unref as $, withKeys as P, withModifiers as ce, createSlots as Re, withCtx as U, computed as M, watch as N, Fragment as W, renderList as J, createBlock as Z, resolveDynamicComponent as we, nextTick as x, onBeforeUnmount as Te, createElementVNode as _, toDisplayString as H, withDirectives as oe, createCommentVNode as Y, vShow as le, normalizeClass as fe, watchEffect as re, createTextVNode as de } from "vue";
import { DtIconSearch as $e, DtIconClose as _e, DtIconClock as Le, DtIconSatisfied as Ie, DtIconLivingThing as Fe, DtIconFood as Ae, DtIconObject as Ce, DtIconTransportation as De, DtIconLightbulb as Oe, DtIconHeart as Ke, DtIconFlag as Ne, DtIconTiktok as Ue } from "@dialpad/dialtone-icons/vue3";
import Me from "../input/input.js";
import me from "../button/button.js";
import { returnFirstEl as Be } from "../../common/utils/index.js";
import { EMOJI_PICKER_CATEGORIES as D, ARROW_KEYS as z, EMOJIS_PER_ROW as L, CDN_URL as Q, EMOJI_PICKER_SKIN_TONE_MODIFIERS as V } from "./emoji-picker-constants.js";
import qe from "../tab/tab-group.js";
import Pe from "../tab/tab.js";
import { emojisGrouped as F } from "@dialpad/dialtone-emojis";
import Ve from "../tooltip/tooltip.js";
const ze = { class: "d-emoji-picker__search d-emoji-picker__alignment" }, He = {
__name: "emoji_search",
props: {
searchPlaceholderLabel: {
type: String,
required: !0
},
modelValue: {
type: String,
default: ""
}
},
emits: ["update:modelValue", "focus-emoji-selector", "focus-tabset", "select-first-emoji"],
setup(o, { expose: g, emit: y }) {
const n = y, u = k(null);
function T() {
n("update:modelValue", ""), p();
}
function p() {
u.value.focus();
}
return ue(() => {
p();
}), g({
focusSearchInput: p
}), (j, f) => (h(), R("div", ze, [
O($(Me), {
id: "searchInput",
ref_key: "searchInput",
ref: u,
placeholder: o.searchPlaceholderLabel,
"model-value": o.modelValue,
"onUpdate:modelValue": f[0] || (f[0] = (i) => j.$emit("update:modelValue", i)),
onKeydown: [
f[1] || (f[1] = P((i) => j.$emit("focus-tabset"), ["up"])),
f[2] || (f[2] = P(ce((i) => j.$emit("focus-emoji-selector"), ["prevent"]), ["down"])),
f[3] || (f[3] = P((i) => j.$emit("select-first-emoji"), ["enter"]))
]
}, Re({
leftIcon: U(() => [
O($($e), { size: "200" })
]),
_: 2
}, [
o.modelValue.length > 0 ? {
name: "rightIcon",
fn: U(() => [
O($(me), {
importance: "clear",
size: "xs",
class: "d-emoji-picker__search-x-button",
circle: "",
kind: "muted",
onClick: T
}, {
icon: U(() => [
O($(_e), { size: "200" })
]),
_: 1
})
]),
key: "0"
} : void 0
]), 1032, ["placeholder", "model-value"])
]));
}
}, Ge = { class: "d-emoji-picker__tabset" }, We = {
__name: "emoji_tabset",
props: {
/**
* Whether to show the recently used tab or not
* @type {Boolean}
* @default false
*/
showRecentlyUsedTab: {
type: Boolean,
default: !1
},
/**
* Whether to show the custom emojis tab or not
* @type {Boolean}
* @default false
*/
showCustomEmojisTab: {
type: Boolean,
default: !1
},
scrollIntoTab: {
type: Number,
required: !0
},
emojiFilter: {
type: String,
default: ""
},
/**
* The labels for the aria-label
* @type {Array}
* @required
*/
tabsetLabels: {
type: Array,
required: !0
}
},
emits: [
/**
* Emitted when a tab is selected
* @event selected-tabset
* @param {String} tabId - The name of the tab that was selected
*/
"selected-tabset",
"focus-search-input",
"focus-skin-selector"
],
setup(o, { expose: g, emit: y }) {
const n = o, u = y, T = [
{ label: D.MOST_RECENTLY_USED, icon: Le },
{ label: D.SMILEYS_AND_PEOPLE, icon: Ie },
{ label: D.NATURE, icon: Fe },
{ label: D.FOOD, icon: Ae },
{ label: D.ACTIVITY, icon: Ce },
{ label: D.TRAVEL, icon: De },
{ label: D.OBJECTS, icon: Oe },
{ label: D.SYMBOLS, icon: Ke },
{ label: D.FLAGS, icon: Ne },
{ label: D.CUSTOM, icon: Ue }
], p = M(() => {
const e = n.showRecentlyUsedTab ? T : T.slice(1);
return n.showCustomEmojisTab || e.pop(), e.map((t, s) => ({
...t,
label: n.tabsetLabels[s],
// IDs on dt-tab component need to be on string
id: (s + 1).toString(),
panelId: (s + 1).toString()
}));
}), j = M(() => n.emojiFilter.length > 0), f = k("1"), i = k([]);
N(
() => n.scrollIntoTab,
() => {
j.value || (f.value = (n.scrollIntoTab + 1).toString());
}
), N(
j,
() => {
j.value && (f.value = null);
}
);
function S(e) {
const t = parseInt(e);
f.value = e, u("selected-tabset", t);
}
function K(e) {
i.value.push(Be(e.$el));
}
function A() {
i.value[0].focus();
}
function r(e, t) {
e.key === "Enter" && (S(t), i.value[t - 1].blur()), e.key === "Tab" && (e.preventDefault(), e.shiftKey ? u("focus-skin-selector") : u("focus-search-input")), e.key === "ArrowDown" && u("focus-search-input");
}
return g({
focusTabset: A
}), (e, t) => (h(), R("div", Ge, [
O($(qe), {
size: "sm",
"tab-list-class": "d-emoji-picker__tabset-list",
selected: f.value
}, {
tabs: U(() => [
(h(!0), R(W, null, J(p.value, (s, m) => (h(), Z($(Pe), {
id: s.id,
ref_for: !0,
ref: (c) => {
c && K(c);
},
key: s.id,
"panel-id": s.panelId,
label: s.label,
"aria-controls": "d-emoji-picker-list",
tabindex: m + 1,
onClickCapture: ce((c) => S(s.id), ["stop"]),
onKeydown: (c) => r(c, s.id)
}, {
default: U(() => [
(h(), Z(we(s.icon), { size: "400" }))
]),
_: 2
}, 1032, ["id", "panel-id", "label", "tabindex", "onClickCapture", "onKeydown"]))), 128))
]),
_: 1
}, 8, ["selected"])
]));
}
};
function Je() {
const o = k([]), g = k([]), y = k(!1), n = k(!0);
function u(e, t) {
i(e, t - 1) || (o.value[e - 1] ? i(e - 1, o.value[e - 1].length - 1) : i(o.value.length - 1, o.value[o.value.length - 1].length - 1));
}
function T(e, t) {
i(e, t + 1) || i(e + 1, 0) || i(0, 0);
}
function p(e, t) {
i(0, t - 1) || i(0, g.value.length - 1);
}
function j(e, t) {
i(0, t + 1) || i(0, 0);
}
function f(e, t, s) {
y.value ? e === "left" ? p(t, s) : e === "right" && j(t, s) : e === "left" ? u(t, s) : e === "right" && T(t, s);
}
function i(e, t) {
var m, c, E;
const s = y.value ? (m = g.value) == null ? void 0 : m[t] : (E = (c = o.value) == null ? void 0 : c[e]) == null ? void 0 : E[t];
return s ? (s.focus(), !0) : !1;
}
function S(e, t, s) {
o.value[t] || (o.value[t] = []), o.value[t][s] = e;
}
function K(e, t) {
g.value[t] = e;
}
function A(e, t) {
var s;
if (n.value = !1, e === z.ARROW_UP) {
const m = t % L;
if (!i(0, t - L)) {
const c = g.value.length - g.value.length % L + m;
i(0, c), i(0, c) || i(0, g.value.length - 1);
}
}
if (e === z.ARROW_DOWN && !i(0, t + L)) {
const m = t % L;
(s = g.value) != null && s[t + (L - m)] ? i(0, g.value.length - 1) : i(0, m);
}
e === z.ARROW_LEFT && f("left", 0, t), e === z.ARROW_RIGHT && f("right", 0, t);
}
function r(e, t, s) {
var m, c;
if (e === "ArrowUp") {
const E = s % L;
if (t === 0) {
const w = L - o.value[o.value.length - 1].length % L, C = o.value[o.value.length - 1].length + w - (L - E);
i(o.value.length - 1, C) || i(o.value.length - 1, o.value[o.value.length - 1].length - 1);
return;
}
if (!i(t, s - L)) {
const w = t - 1 < 0 ? 0 : t - 1, C = o.value[w].length, ee = C - C % L + E;
i(w, ee) || i(t - 1, o.value[t - 1].length - 1);
}
}
if (e === "ArrowDown" && !i(t, s + L)) {
const E = s % L;
(c = (m = o.value) == null ? void 0 : m[t]) != null && c[s + (L - E)] ? i(t, o.value[t].length - 1) : i(t + 1, E) || i(0, E) || i(0, o.value[0].length - 1);
}
e === "ArrowLeft" && f("left", t, s), e === "ArrowRight" && f("right", t, s);
}
return {
emojiFilteredRefs: g,
isFiltering: y,
hoverFirstEmoji: n,
setEmojiRef: S,
setFilteredRef: K,
focusEmoji: i,
handleArrowNavigationFiltered: A,
handleArrowNavigation: r
};
}
const Ye = { class: "d-emoji-picker__selector" }, Qe = {
key: 0,
class: "d-emoji-picker__search-label d-emoji-picker__alignment"
}, Xe = { key: 0 }, Ze = { class: "d-emoji-picker__tab" }, xe = ["aria-label", "onClick", "onFocusin", "onMouseover", "onKeydown"], et = ["alt", "aria-label", "title", "src"], tt = {
key: 2,
class: "d-emoji-picker__alignment"
}, ot = {
class: "d-emoji-picker__tab",
"data-qa": "filtered-emojis"
}, lt = ["aria-label", "onClick", "onFocusin", "onMouseover", "onKeydown"], st = ["alt", "aria-label", "title", "src"], nt = {
__name: "emoji_selector",
props: {
/**
* The filter to apply to the emoji list
* @type {String}
* @default ''
*/
emojiFilter: {
type: String,
default: ""
},
/**
* The skin tone to apply to the emoji list
* @type {String}
* @required
*/
skinTone: {
type: String,
required: !0
},
/**
* The labels for the tabset
* @type {Array}
* @required
*/
tabsetLabels: {
type: Array,
required: !0
},
selectedTabset: {
type: Object,
required: !0
},
/**
* The label for the search results tab
* @type {String}
* @required
*/
searchResultsLabel: {
type: String,
required: !0
},
searchNoResultsLabel: {
type: String,
required: !0
},
/**
* The list of recently used emojis
* @type {Array}
*/
recentlyUsedEmojis: {
type: Array,
default: () => []
},
/**
* The list of custom emojis
* @type {Array}
*/
customEmojis: {
type: Array,
default: () => []
}
},
emits: [
/**
* Emitted when the user hover over an emoji
* @event highlighted-emoji
* @param {Object} emoji - The emoji data that was hovered
*/
"highlighted-emoji",
/**
* Emitted when the user select an emoji
* @event selected-emoji
* @param {Object} emoji - The emoji data that was selected
*/
"selected-emoji",
/**
* Emitted when the user scroll into an emoji tab
* @event scroll-into-tab
* @param {Number} tab-index - The tab that was scrolled into
*/
"scroll-into-tab",
/**
* Emitted when the user reach bottom scroll
* This event is used on handleScroll method
* @event scroll-bottom-reached
*/
"scroll-bottom-reached",
/**
* Emitted when the user reach the end of the emoji list
* @event focus-skin-selector
*/
"focus-skin-selector",
/**
* Emitted when the user shift tab in first tab of emoji selector
* @event focus-search-input
*/
"focus-search-input"
],
setup(o, { expose: g, emit: y }) {
const n = o, u = y, {
emojiFilteredRefs: T,
isFiltering: p,
hoverFirstEmoji: j,
setEmojiRef: f,
setFilteredRef: i,
focusEmoji: S,
handleArrowNavigationFiltered: K,
handleArrowNavigation: A
} = Je(), r = k(null), e = k(null), t = k(null), s = ["Recently used", "People", "Nature", "Food", "Activity", "Travel", "Objects", "Symbols", "Flags", "Custom"], m = M(() => {
let l = n.tabsetLabels.map((a) => ({ label: a, ref: k(null) }));
return n.recentlyUsedEmojis && !n.recentlyUsedEmojis.length && (l = n.tabsetLabels.slice(1).map((a) => ({ label: a, ref: k(null) }))), n.customEmojis && !n.customEmojis.length && l.pop(), l;
}), c = k(m.value[0].label), E = M(() => {
const l = n.recentlyUsedEmojis.length ? s.slice() : s.slice(1);
return n.customEmojis && !n.customEmojis.length && l.pop(), l;
}), w = k([]), C = M(() => [
...F[`People${n.skinTone}`],
...F.Nature,
...F.Food,
...F[`Activity${n.skinTone}`],
...F.Travel,
...F[`Objects${n.skinTone}`],
...F.Symbols,
...F.Flags
]), ee = ve(() => {
T.value = [], ne();
}), se = () => {
const l = e.value;
l.scrollTop + l.clientHeight >= l.scrollHeight && u("scroll-bottom-reached");
};
N(C, () => {
ne();
}, { immediate: !0 }), N(
() => n.recentlyUsedEmojis,
() => {
F["Recently used"] = n.recentlyUsedEmojis;
},
{ immediate: !0 }
), N(
() => n.customEmojis,
() => {
F.Custom = n.customEmojis;
},
{ immediate: !0 }
), N(() => n.emojiFilter, () => {
pe(), n.emojiFilter ? p.value = !0 : (p.value = !1, B(null)), ee();
}), N(
() => n.selectedTabset,
(l) => {
G(l.tabId);
},
{ deep: !0 }
);
function te(l, a = !1) {
j.value = a, u("highlighted-emoji", l);
}
function ne() {
const l = n.emojiFilter.toLowerCase();
w.value = C.value.filter((a) => {
const v = a.name.toLowerCase().includes(l), b = a.keywords.some((d) => d.toLowerCase().includes(l));
return v || b;
}), x(() => {
l && te(w.value[0], !0);
});
}
function ve(l, a = 300) {
let v;
return (...b) => {
clearTimeout(v), v = setTimeout(() => l(...b), a);
};
}
function be(l) {
return l.date_added ? l.image : Q + l.unicode_character + ".png";
}
function he(l) {
l.target.parentNode.style.display = "none";
}
function G(l, a = !0) {
const b = m.value[l - 1].ref.value[0];
x(() => {
const d = e.value, q = l === 1 ? 0 : b.offsetTop - 15;
d.scrollTop = q, a && S(l - 1, 0);
});
}
function pe() {
const l = e.value;
l.scrollTop = 0;
}
function ke() {
e.value.addEventListener("scroll", se);
}
function ge() {
t.value = new IntersectionObserver(async (l) => {
l.forEach((a) => {
var d, q, I, ie, ae;
const { target: v } = a, b = parseInt(v.dataset.index);
a.isIntersecting && v.offsetTop <= r.value.offsetTop + 50 ? (c.value = ((d = m.value[b - 1]) == null ? void 0 : d.label) ?? ((q = m.value[0]) == null ? void 0 : q.label), u("scroll-into-tab", b - 1)) : a.boundingClientRect.bottom <= ((I = r.value) == null ? void 0 : I.getBoundingClientRect().bottom) ? (u("scroll-into-tab", b), c.value = (ie = m.value[b]) == null ? void 0 : ie.label) : b === 1 && (u("scroll-into-tab", b), c.value = (ae = m.value[0]) == null ? void 0 : ae.label);
});
}), t.value.observe(r.value), Array.from(e.value.children).forEach((l, a) => {
t.value.observe(l), l.dataset.index = a;
});
}
const ye = (l, a, v) => {
if (l.preventDefault(), Object.values(z).includes(l.key)) {
K(l.key, a);
return;
}
switch (l.key) {
case "Tab":
u("focus-skin-selector");
break;
case "Enter":
X(v, l);
break;
}
}, je = (l, a, v, b) => {
if (l.preventDefault(), Object.values(z).includes(l.key)) {
A(l.key, a, v);
return;
}
switch (l.key) {
case "Tab":
l.shiftKey ? S(a, 0) && a > 0 ? G(a, !0) : (G(1, !1), u("focus-search-input")) : S(a + 1, 0) ? G(a + 1 + 1, !1) : u("focus-skin-selector");
break;
case "Enter":
X(b, l);
break;
}
};
function X(l, a) {
u("selected-emoji", { ...l, shift_key: a.shiftKey });
}
function B(l) {
u("highlighted-emoji", l);
}
function Se() {
S(0, 0);
}
function Ee() {
G(E.value.length, !0);
}
return ue(() => {
ge(), ke();
}), Te(() => {
t.value.disconnect(), e.value.removeEventListener("scroll", se);
}), g({
focusEmojiSelector: Se,
focusLastEmoji: Ee
}), (l, a) => (h(), R("div", Ye, [
_("div", {
id: "d-emoji-picker-list",
ref_key: "listRef",
ref: e,
class: "d-emoji-picker__list"
}, [
o.emojiFilter ? (h(), R("p", Qe, H(w.value.length > 0 ? o.searchResultsLabel : o.searchNoResultsLabel), 1)) : (h(), R("div", {
key: 1,
ref_key: "tabCategoryRef",
ref: r,
class: "d-emoji-picker__category d-emoji-picker__alignment"
}, [
_("p", null, H(c.value), 1)
], 512)),
(h(!0), R(W, null, J(m.value, (v, b) => oe((h(), R("div", {
key: b,
ref_for: !0,
ref: v.ref,
class: "d-emoji-picker__alignment"
}, [
b ? (h(), R("p", Xe, H(v.label), 1)) : Y("", !0),
_("div", Ze, [
(h(!0), R(W, null, J($(F)[E.value[b] + o.skinTone] ? $(F)[E.value[b] + o.skinTone] : $(F)[E.value[b]], (d, q) => (h(), R("button", {
key: d.shortname,
ref_for: !0,
ref: (I) => {
I && $(f)(I, b, q);
},
type: "button",
"aria-label": d.name,
onClick: (I) => X(d, I),
onFocusin: (I) => B(d),
onFocusout: a[0] || (a[0] = (I) => B(null)),
onMouseover: (I) => B(d),
onMouseleave: a[1] || (a[1] = (I) => B(null)),
onKeydown: (I) => je(I, b, q, d)
}, [
_("img", {
class: "d-icon d-icon--size-500",
alt: d.name,
"aria-label": d.name,
title: d.name,
src: be(d),
onError: he
}, null, 40, et)
], 40, xe))), 128))
])
])), [
[le, !o.emojiFilter]
])), 128)),
o.emojiFilter ? (h(), R("div", tt, [
_("div", ot, [
(h(!0), R(W, null, J(w.value, (v, b) => (h(), R("button", {
key: v.shortname,
ref_for: !0,
ref: (d) => {
d && $(i)(d, b);
},
type: "button",
"aria-label": v.name,
class: fe({
"hover-emoji": b === 0 && $(j)
}),
onClick: (d) => X(v, d),
onFocusin: (d) => B(v),
onFocusout: a[2] || (a[2] = (d) => B(null)),
onMouseover: (d) => te(v),
onMouseleave: a[3] || (a[3] = (d) => te(null)),
onKeydown: (d) => ye(d, b, v)
}, [
_("img", {
class: "d-icon d-icon--size-500",
alt: v.name,
"aria-label": v.name,
title: v.name,
src: `${$(Q) + v.unicode_character}.png`
}, null, 8, st)
], 42, lt))), 128))
])
])) : Y("", !0)
], 512)
]));
}
}, it = { "data-qa": "skin-selector" }, at = { class: "d-emoji-picker__skin-list" }, rt = ["onKeydown", "onClick"], ut = ["alt", "aria-label", "title", "src"], ct = { class: "d-emoji-picker__skin-selected" }, ft = ["aria-label"], dt = ["alt", "aria-label", "title", "src"], mt = {
__name: "emoji_skin_selector",
props: {
/**
* The skin tone to apply to the emoji list
* @type {String}
* @required
*/
skinTone: {
type: String,
required: !0
},
isHovering: {
type: Boolean,
default: !1
},
skinSelectorButtonTooltipLabel: {
type: String,
required: !0
}
},
emits: [
/**
* The skin tone that was selected
* @event skin-tone
* @type {Number}
*/
"skin-tone",
"focus-tabset",
"focus-last-emoji"
],
setup(o, { expose: g, emit: y }) {
const n = o, u = y, T = [
{
name: ":wave_tone1:",
unicode_output: "1f44b-1f3fb",
skinTone: V.LIGHT,
skinCode: "_tone1"
},
{
name: ":wave_tone2:",
unicode_output: "1f44b-1f3fc",
skinTone: V.MEDIUM_LIGHT,
skinCode: "_tone2"
},
{
name: ":wave_tone3:",
unicode_output: "1f44b-1f3fd",
skinTone: V.MEDIUM,
skinCode: "_tone3"
},
{
name: ":wave_tone4:",
unicode_output: "1f44b-1f3fe",
skinTone: V.MEDIUM_DARK,
skinCode: "_tone4"
},
{
name: ":wave_tone5:",
unicode_output: "1f44b-1f3ff",
skinTone: V.DARK,
skinCode: "_tone5"
},
{
name: ":wave:",
unicode_output: "1f44b",
skinTone: V.DEFAULT,
skinCode: ""
}
], p = k(!1), j = k(null), f = k([]);
re(
() => n.isHovering && (p.value = !1)
);
const i = M(() => T.find((s) => s.skinTone === n.skinTone)), S = k(i.value);
re(() => i.value && (S.value = i.value));
function K(s) {
f.value.push(s);
}
function A() {
j.value.focus();
}
function r(s) {
S.value = s, p.value = !1, u("skin-tone", s.skinTone), x(() => A());
}
const e = (s, m, c) => {
var E, w, C;
s.preventDefault(), s.key === "ArrowLeft" && (c === 0 && ((E = f.value[f.value.length - 1]) == null || E.focus()), (w = f.value[c - 1]) == null || w.focus()), s.key === "ArrowRight" && ((C = f.value[c + 1]) == null || C.focus()), s.key === "Enter" && (m ? r(m) : t()), s.key === "Tab" && (s.shiftKey ? u("focus-last-emoji") : u("focus-tabset"));
};
function t() {
p.value = !p.value, x(() => f.value[0].focus());
}
return g({
focusSkinSelector: A
}), (s, m) => (h(), R("div", it, [
oe(_("div", at, [
(h(), R(W, null, J(T, (c, E) => _("button", {
ref_for: !0,
ref: (w) => {
w && K(w);
},
key: c.name,
class: fe({
selected: S.value.skinCode === c.skinCode
}),
onKeydown: (w) => e(w, c, E),
onClick: (w) => r(c)
}, [
_("img", {
class: "d-icon d-icon--size-500",
alt: c.name,
"aria-label": c.name,
title: c.name,
src: `${$(Q) + c.unicode_output}.png`
}, null, 8, ut)
], 42, rt)), 64))
], 512), [
[le, p.value]
]),
oe(_("div", ct, [
O($(Ve), { placement: "top-end" }, {
anchor: U(() => [
_("button", {
ref_key: "skinSelectorRef",
ref: j,
"aria-label": o.skinSelectorButtonTooltipLabel,
tabindex: "-1",
onClick: t,
onKeydown: m[0] || (m[0] = (c) => e(c))
}, [
_("img", {
class: "d-icon d-icon--size-500",
alt: S.value.name,
"aria-label": S.value.name,
title: S.value.name,
src: `${$(Q) + S.value.unicode_output}.png`
}, null, 8, dt)
], 40, ft)
]),
default: U(() => [
de(H(o.skinSelectorButtonTooltipLabel) + " ", 1)
]),
_: 1
})
], 512), [
[le, !p.value]
])
]));
}
}, vt = { class: "d-emoji-picker__data" }, bt = ["alt", "aria-label", "title", "src"], ht = {
__name: "emoji_description",
props: {
/**
* Emoji data
* @type {Object}
* @default null
*/
emoji: {
type: Object,
default: null
}
},
setup(o) {
function g(y) {
return y.date_added ? y.image : `${Q + y.unicode_character}.png`;
}
return (y, n) => {
var u;
return h(), R("div", vt, [
o.emoji ? (h(), R("img", {
key: 0,
class: "d-icon d-icon--size-500",
alt: o.emoji.name,
"aria-label": o.emoji.name,
title: o.emoji.name,
src: g(o.emoji)
}, null, 8, bt)) : Y("", !0),
_("div", null, H((u = o.emoji) == null ? void 0 : u.name), 1)
]);
};
}
}, pt = { class: "d-emoji-picker" }, kt = { class: "d-emoji-picker--header" }, gt = { class: "d-emoji-picker--body" }, yt = { class: "d-emoji-picker--footer" }, Ft = {
__name: "emoji_picker",
props: {
/**
* The array with recently used emoji object
* This list is necessary to fill the recently used tab
* @type {Array}
* @default []
* @example
* <dt-emoji-picker :recentlyUsedEmojis="[emojiObject, emojiObject]" />
*/
// TODO try to simplify this to achieve an array of unicode characters and not an entire emoji data object
recentlyUsedEmojis: {
type: Array,
default: () => []
},
/**
* The array with custom emojis object
* This list is necessary to fill the custom tab
* @type {Array}
* @default []
* @example
* <dt-emoji-picker :customEmojis="[emojiObject, emojiObject]" />
*/
customEmojis: {
type: Array
},
/**
* The label for the add emoji button
* required false because it is still experimental
* @type {String}
* @example
* <dt-emoji-picker :addEmojiLabel="'Add emoji'" />
*/
addEmojiLabel: {
type: String,
required: !1,
default: "Add emoji"
},
/**
* The placeholder text for the search input
* @type {String}
* @required
* @example
* <dt-emoji-picker :searchPlaceholderLabel="'Search...'" />
*/
searchPlaceholderLabel: {
type: String,
required: !0
},
/**
* The label for the search results tab
* @type {String}
* @required
* @example
* <dt-emoji-picker :searchResultsLabel="'Search results'" />
*/
searchResultsLabel: {
type: String,
required: !0
},
/**
* The label for the search no results
* @type {String}
* @required
* @example
* <dt-emoji-picker :searchNoResultsLabel="'No results'" />
*/
searchNoResultsLabel: {
type: String,
required: !0
},
/**
* The list of tabsets to show, it is necessary to be updated with the correct language
* It must respect the provided order.
* @type {Array}
* @required
* @example
* <dt-emoji-picker
* :tabSetLabels="['Most recently used', 'Smileys and people', 'Nature',
* 'Food', 'Activity', 'Travel', 'Objects', 'Symbols', 'Flags', 'Custom']" />
*/
tabSetLabels: {
type: Array,
required: !0
},
/**
* The skin tone to show the emojis
* This prop gives the possibility to use the skin tone selected by the user previously
* @type {String}
* @default 'Default'
* @values 'Default', 'Light', 'MediumLight', 'Medium', 'MediumDark', 'Dark'
* @example
* <dt-emoji-picker :skinTone="'Default'" />
*/
skinTone: {
type: String,
default: "Default"
},
/**
* Tooltip shown when skin selector button is hovered.
* @type {String}
* @required
* @example
* <dt-emoji-picker :skin-selector-button-tooltip-label="'Change default skin tone'" />
*/
skinSelectorButtonTooltipLabel: {
type: String,
required: !0
},
/**
* Sets the search query that filters emojis.
* @type {String}
* @example
* <dt-emoji-picker search-query="smile" />
*/
searchQuery: {
type: String,
default: ""
},
/**
* Shows the search input
* @type {Boolean}
* @example
* <dt-emoji-picker :show-search="false" />
*/
showSearch: {
type: Boolean,
default: !0
}
},
emits: [
/**
* It will emit the selected emoji
* @event selected-emoji
* @param {Object} emoji - The selected emoji from the emoji selector
*/
"selected-emoji",
/**
* Emitted when the user reach bottom scroll
* This is being handled by handleScroll method
* @event scroll-bottom-reached
*/
"scroll-bottom-reached",
/**
* It will emit the selected skin tone
* @event skin-tone
* @param {String} skin - The selected skin tone from the skin selector
*/
"skin-tone",
/**
* Since the keyboard events are encapsulated, we emit this event to close the picker
* @event close
*/
"close",
/**
* Emitted when the user clicks on the add emoji button
* @event add-emoji
*/
"add-emoji"
],
setup(o, { emit: g }) {
const y = o, n = g, u = k(y.searchQuery.value), T = k(null), p = k({}), j = k(0), f = M(() => {
var r;
return ((r = y.recentlyUsedEmojis) == null ? void 0 : r.length) > 0;
}), i = M(() => {
var r;
return ((r = y.customEmojis) == null ? void 0 : r.length) > 0;
});
N(
() => y.searchQuery,
(r) => {
u.value = r;
}
);
function S(r) {
u.value = "", p.value = r, p.value = { ...p.value, tabId: r };
}
function K(r) {
j.value = r;
}
function A(r) {
T.value = r;
}
return (r, e) => (h(), R("div", pt, [
_("div", kt, [
O(We, {
ref: "tabsetRef",
"emoji-filter": u.value,
"show-custom-emojis-tab": i.value,
"show-recently-used-tab": f.value,
"scroll-into-tab": j.value,
"tabset-labels": o.tabSetLabels,
onFocusSkinSelector: e[0] || (e[0] = (t) => r.$refs.skinSelectorRef.focusSkinSelector()),
onFocusSearchInput: e[1] || (e[1] = (t) => o.showSearch ? r.$refs.searchInputRef.focusSearchInput() : r.$refs.emojiSelectorRef.focusEmojiSelector()),
onSelectedTabset: S,
onKeydown: e[2] || (e[2] = P((t) => n("close"), ["esc"]))
}, null, 8, ["emoji-filter", "show-custom-emojis-tab", "show-recently-used-tab", "scroll-into-tab", "tabset-labels"])
]),
_("div", gt, [
o.showSearch ? (h(), Z(He, {
key: 0,
ref: "searchInputRef",
modelValue: u.value,
"onUpdate:modelValue": e[3] || (e[3] = (t) => u.value = t),
"search-placeholder-label": o.searchPlaceholderLabel,
onSelectFirstEmoji: e[4] || (e[4] = (t) => n("selected-emoji", T.value)),
onFocusTabset: e[5] || (e[5] = (t) => r.$refs.tabsetRef.focusTabset()),
onFocusEmojiSelector: e[6] || (e[6] = (t) => r.$refs.emojiSelectorRef.focusEmojiSelector()),
onKeydown: e[7] || (e[7] = P((t) => n("close"), ["esc"]))
}, null, 8, ["modelValue", "search-placeholder-label"])) : Y("", !0),
O(nt, {
ref: "emojiSelectorRef",
"emoji-filter": u.value,
"skin-tone": o.skinTone,
"tabset-labels": o.tabSetLabels,
"search-results-label": o.searchResultsLabel,
"search-no-results-label": o.searchNoResultsLabel,
"recently-used-emojis": o.recentlyUsedEmojis,
"custom-emojis": o.customEmojis,
"selected-tabset": p.value,
onScrollIntoTab: K,
onHighlightedEmoji: A,
onSelectedEmoji: e[8] || (e[8] = (t) => n("selected-emoji", t)),
onFocusSkinSelector: e[9] || (e[9] = (t) => r.$refs.skinSelectorRef.focusSkinSelector()),
onFocusSearchInput: e[10] || (e[10] = (t) => o.showSearch ? r.$refs.searchInputRef.focusSearchInput() : r.$refs.tabsetRef.focusTabset()),
onKeydown: e[11] || (e[11] = P((t) => n("close"), ["esc"])),
onScrollBottomReached: e[12] || (e[12] = (t) => n("scroll-bottom-reached"))
}, null, 8, ["emoji-filter", "skin-tone", "tabset-labels", "search-results-label", "search-no-results-label", "recently-used-emojis", "custom-emojis", "selected-tabset"])
]),
_("div", yt, [
i.value && !T.value ? (h(), Z($(me), {
key: 0,
importance: "outlined",
"aria-label": o.addEmojiLabel,
class: "d-emoji-picker__add-emoji",
onClick: e[13] || (e[13] = (t) => n("add-emoji"))
}, {
default: U(() => [
de(H(o.addEmojiLabel), 1)
]),
_: 1
}, 8, ["aria-label"])) : Y("", !0),
O(ht, { emoji: T.value }, null, 8, ["emoji"]),
O(mt, {
ref: "skinSelectorRef",
"is-hovering": !!T.value,
"skin-selector-button-tooltip-label": o.skinSelectorButtonTooltipLabel,
"skin-tone": o.skinTone,
onSkinTone: e[14] || (e[14] = (t) => n("skin-tone", t)),
onFocusTabset: e[15] || (e[15] = (t) => r.$refs.tabsetRef.focusTabset()),
onFocusLastEmoji: e[16] || (e[16] = (t) => r.$refs.emojiSelectorRef.focusLastEmoji()),
onKeydown: e[17] || (e[17] = P((t) => n("close"), ["esc"]))
}, null, 8, ["is-hovering", "skin-selector-button-tooltip-label", "skin-tone"])
])
]));
}
};
export {
Ft as default
};
//# sourceMappingURL=emoji-picker.js.map