@hokkiai/discord-emoji-selector 1.1.6 → 1.2.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/categoryDisplay-AZPE23IJ.js +205 -0
- package/dist/categoryDisplay-BV7OPJVG.js +205 -0
- package/dist/categoryDisplay-EAVZYFPJ.js +205 -0
- package/dist/chunk-DMO3WEXH.js +53 -0
- package/dist/chunk-LP6LBWNJ.js +59 -0
- package/dist/index.cjs +569 -532
- package/dist/index.css +51 -0
- package/dist/index.js +364 -597
- package/package.json +1 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import {
|
|
2
|
+
render,
|
|
3
|
+
useSearchValue,
|
|
4
|
+
useSkin
|
|
5
|
+
} from "./chunk-DMO3WEXH.js";
|
|
6
|
+
|
|
7
|
+
// src/categoryDisplay.tsx
|
|
8
|
+
import { ChevronDown } from "lucide-react";
|
|
9
|
+
import { memo, useState, useCallback, useMemo } from "react";
|
|
10
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
var Emoji = memo(function Emoji2({
|
|
12
|
+
pickerId,
|
|
13
|
+
emoji,
|
|
14
|
+
onEmojiMouseEnter,
|
|
15
|
+
onEmojiMouseLeave,
|
|
16
|
+
onEmojiSelect
|
|
17
|
+
}) {
|
|
18
|
+
const handleMouseEnter = useCallback(() => {
|
|
19
|
+
window["emojipicker-" + pickerId].changeFooterEmoji(emoji);
|
|
20
|
+
window["emojipicker-" + pickerId].changeSearchbarPlaceholder(emoji.name);
|
|
21
|
+
onEmojiMouseEnter(emoji);
|
|
22
|
+
}, [pickerId, emoji, onEmojiMouseEnter]);
|
|
23
|
+
const handleMouseLeave = useCallback(() => {
|
|
24
|
+
onEmojiMouseLeave(emoji);
|
|
25
|
+
}, [emoji, onEmojiMouseLeave]);
|
|
26
|
+
const handleClick = useCallback(() => {
|
|
27
|
+
onEmojiSelect(emoji);
|
|
28
|
+
}, [emoji, onEmojiSelect]);
|
|
29
|
+
const html = useMemo(() => render(emoji.char), [emoji.char]);
|
|
30
|
+
return /* @__PURE__ */ jsx(
|
|
31
|
+
"div",
|
|
32
|
+
{
|
|
33
|
+
onMouseEnter: handleMouseEnter,
|
|
34
|
+
onMouseLeave: handleMouseLeave,
|
|
35
|
+
onClick: handleClick,
|
|
36
|
+
className: "HOKKIEMOJIPICKER-emoji text-4xl p-1 cursor-pointer hover:bg-white/15 rounded-sm size-12.5 flex items-center justify-center overflow-hidden",
|
|
37
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
var SkinEmoji = memo(function SkinEmoji2({
|
|
42
|
+
pickerId,
|
|
43
|
+
emoji,
|
|
44
|
+
onEmojiSelect,
|
|
45
|
+
onEmojiMouseEnter,
|
|
46
|
+
onEmojiMouseLeave
|
|
47
|
+
}) {
|
|
48
|
+
const skin = useSkin({ pickerId });
|
|
49
|
+
const fakeEmoji = useMemo(() => {
|
|
50
|
+
const charForSkin = [1, 2, 3, 4, 5].includes(skin) ? emoji.tones.find((a) => a.tone.find((b) => b === skin) === skin)?.char : emoji.char;
|
|
51
|
+
return {
|
|
52
|
+
...emoji,
|
|
53
|
+
char: charForSkin,
|
|
54
|
+
preRendered: true,
|
|
55
|
+
tones: [
|
|
56
|
+
{
|
|
57
|
+
name: emoji.tones[0].name.replaceAll("1", "0"),
|
|
58
|
+
tone: [0],
|
|
59
|
+
char: emoji.char
|
|
60
|
+
},
|
|
61
|
+
...emoji.tones
|
|
62
|
+
]
|
|
63
|
+
};
|
|
64
|
+
}, [emoji, skin]);
|
|
65
|
+
const handleMouseEnter = useCallback(() => {
|
|
66
|
+
window["emojipicker-" + pickerId].changeFooterEmoji(fakeEmoji);
|
|
67
|
+
window["emojipicker-" + pickerId].changeSearchbarPlaceholder(emoji.name);
|
|
68
|
+
onEmojiMouseEnter(fakeEmoji);
|
|
69
|
+
}, [pickerId, fakeEmoji, emoji.name, onEmojiMouseEnter]);
|
|
70
|
+
const handleMouseLeave = useCallback(() => {
|
|
71
|
+
onEmojiMouseLeave(fakeEmoji);
|
|
72
|
+
}, [fakeEmoji, onEmojiMouseLeave]);
|
|
73
|
+
const handleClick = useCallback(() => {
|
|
74
|
+
onEmojiSelect(fakeEmoji);
|
|
75
|
+
}, [fakeEmoji, onEmojiSelect]);
|
|
76
|
+
const html = useMemo(() => render(fakeEmoji.char), [fakeEmoji.char]);
|
|
77
|
+
return /* @__PURE__ */ jsx(
|
|
78
|
+
"div",
|
|
79
|
+
{
|
|
80
|
+
onMouseEnter: handleMouseEnter,
|
|
81
|
+
onMouseLeave: handleMouseLeave,
|
|
82
|
+
onClick: handleClick,
|
|
83
|
+
className: "HOKKIEMOJIPICKER-skinemoji text-4xl p-1 cursor-pointer hover:bg-white/15 rounded-sm size-12.5 flex items-center justify-center overflow-hidden",
|
|
84
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
var CategoryDisplay = memo(function CategoryDisplay2({
|
|
89
|
+
category,
|
|
90
|
+
categoryInfo,
|
|
91
|
+
isToneSelectorEnabled,
|
|
92
|
+
onEmojiSelect,
|
|
93
|
+
onEmojiMouseEnter,
|
|
94
|
+
onEmojiMouseLeave,
|
|
95
|
+
pickerId
|
|
96
|
+
}) {
|
|
97
|
+
const storageKey = `hokkiemojipicker-category-${category.name}-open`;
|
|
98
|
+
const [isOpen, setIsOpen] = useState(() => {
|
|
99
|
+
const cached = localStorage?.getItem(storageKey);
|
|
100
|
+
return cached === null ? true : cached === "true";
|
|
101
|
+
});
|
|
102
|
+
const searchValue = useSearchValue({ pickerId });
|
|
103
|
+
const handleToggle = useCallback(() => {
|
|
104
|
+
setIsOpen((prev) => {
|
|
105
|
+
const newState = !prev;
|
|
106
|
+
try {
|
|
107
|
+
localStorage?.setItem(storageKey, String(newState));
|
|
108
|
+
} catch (e) {
|
|
109
|
+
}
|
|
110
|
+
return newState;
|
|
111
|
+
});
|
|
112
|
+
}, [storageKey]);
|
|
113
|
+
const searchLower = useMemo(
|
|
114
|
+
() => (searchValue || "").toLowerCase().replace(/_/g, " "),
|
|
115
|
+
[searchValue]
|
|
116
|
+
);
|
|
117
|
+
const filteredEmojis = useMemo(() => {
|
|
118
|
+
if (!searchLower) return null;
|
|
119
|
+
return category.emojis.filter(
|
|
120
|
+
(emoji) => emoji.name.toLowerCase().replace(/_/g, " ").includes(searchLower)
|
|
121
|
+
);
|
|
122
|
+
}, [category.emojis, searchLower]);
|
|
123
|
+
if (searchLower) {
|
|
124
|
+
if (category.name === "recentlyUsed")
|
|
125
|
+
return /* @__PURE__ */ jsx("div", { className: "h-1.5 w-full" });
|
|
126
|
+
return /* @__PURE__ */ jsx(Fragment, { children: filteredEmojis.map((emoji) => {
|
|
127
|
+
if (emoji.hasTone && !emoji.preRendered) {
|
|
128
|
+
return /* @__PURE__ */ jsx(
|
|
129
|
+
SkinEmoji,
|
|
130
|
+
{
|
|
131
|
+
onEmojiSelect,
|
|
132
|
+
pickerId,
|
|
133
|
+
onEmojiMouseEnter,
|
|
134
|
+
onEmojiMouseLeave,
|
|
135
|
+
emoji
|
|
136
|
+
},
|
|
137
|
+
emoji.name
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return /* @__PURE__ */ jsx(
|
|
141
|
+
Emoji,
|
|
142
|
+
{
|
|
143
|
+
onEmojiSelect,
|
|
144
|
+
pickerId,
|
|
145
|
+
emoji,
|
|
146
|
+
onEmojiMouseEnter,
|
|
147
|
+
onEmojiMouseLeave
|
|
148
|
+
},
|
|
149
|
+
emoji.name
|
|
150
|
+
);
|
|
151
|
+
}) });
|
|
152
|
+
}
|
|
153
|
+
return /* @__PURE__ */ jsxs("div", { className: "HOKKIEMOJIPICKER-categorydisplay flex flex-col relative w-full pt-2", children: [
|
|
154
|
+
/* @__PURE__ */ jsx(
|
|
155
|
+
"div",
|
|
156
|
+
{
|
|
157
|
+
className: "HOKKIEMOJIPICKER-categoryHeader sticky top-0 pt-2 cursor-pointer text-white px-2 flex bg-[#131416] p-1 pb-2 " + category.name,
|
|
158
|
+
onClick: handleToggle,
|
|
159
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex gap-1.5 items-center opacity-75 hover:opacity-100", children: [
|
|
160
|
+
/* @__PURE__ */ jsx("span", { className: "*:size-4.5", children: categoryInfo.icon }),
|
|
161
|
+
" ",
|
|
162
|
+
/* @__PURE__ */ jsx("span", { className: "text-md font-semibold font-gg", children: categoryInfo.name }),
|
|
163
|
+
/* @__PURE__ */ jsx(
|
|
164
|
+
ChevronDown,
|
|
165
|
+
{
|
|
166
|
+
strokeWidth: 2,
|
|
167
|
+
className: "transition-all size-5 data-[open=false]:-rotate-90",
|
|
168
|
+
"data-open": isOpen ? "true" : "false"
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
] })
|
|
172
|
+
}
|
|
173
|
+
),
|
|
174
|
+
isOpen && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-y-0.5", children: category.emojis.map((emoji) => {
|
|
175
|
+
if (emoji.hasTone && !emoji.preRendered && isToneSelectorEnabled) {
|
|
176
|
+
return /* @__PURE__ */ jsx(
|
|
177
|
+
SkinEmoji,
|
|
178
|
+
{
|
|
179
|
+
onEmojiSelect,
|
|
180
|
+
pickerId,
|
|
181
|
+
emoji,
|
|
182
|
+
onEmojiMouseEnter,
|
|
183
|
+
onEmojiMouseLeave
|
|
184
|
+
},
|
|
185
|
+
emoji.name
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
return /* @__PURE__ */ jsx(
|
|
189
|
+
Emoji,
|
|
190
|
+
{
|
|
191
|
+
onEmojiSelect,
|
|
192
|
+
pickerId,
|
|
193
|
+
onEmojiMouseEnter,
|
|
194
|
+
onEmojiMouseLeave,
|
|
195
|
+
emoji
|
|
196
|
+
},
|
|
197
|
+
emoji.name
|
|
198
|
+
);
|
|
199
|
+
}) })
|
|
200
|
+
] });
|
|
201
|
+
});
|
|
202
|
+
var categoryDisplay_default = CategoryDisplay;
|
|
203
|
+
export {
|
|
204
|
+
categoryDisplay_default as default
|
|
205
|
+
};
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import {
|
|
2
|
+
render,
|
|
3
|
+
useSearchValue,
|
|
4
|
+
useSkin
|
|
5
|
+
} from "./chunk-DMO3WEXH.js";
|
|
6
|
+
|
|
7
|
+
// src/categoryDisplay.tsx
|
|
8
|
+
import { ChevronDown } from "lucide-react";
|
|
9
|
+
import { memo, useEffect, useState, useCallback, useMemo } from "react";
|
|
10
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
var Emoji = memo(function Emoji2({
|
|
12
|
+
pickerId,
|
|
13
|
+
emoji,
|
|
14
|
+
onEmojiMouseEnter,
|
|
15
|
+
onEmojiMouseLeave,
|
|
16
|
+
onEmojiSelect
|
|
17
|
+
}) {
|
|
18
|
+
const handleMouseEnter = useCallback(() => {
|
|
19
|
+
window["emojipicker-" + pickerId].changeFooterEmoji(emoji);
|
|
20
|
+
window["emojipicker-" + pickerId].changeSearchbarPlaceholder(emoji.name);
|
|
21
|
+
onEmojiMouseEnter(emoji);
|
|
22
|
+
}, [pickerId, emoji, onEmojiMouseEnter]);
|
|
23
|
+
const handleMouseLeave = useCallback(() => {
|
|
24
|
+
onEmojiMouseLeave(emoji);
|
|
25
|
+
}, [emoji, onEmojiMouseLeave]);
|
|
26
|
+
const handleClick = useCallback(() => {
|
|
27
|
+
onEmojiSelect(emoji);
|
|
28
|
+
}, [emoji, onEmojiSelect]);
|
|
29
|
+
const html = useMemo(() => render(emoji.char), [emoji.char]);
|
|
30
|
+
return /* @__PURE__ */ jsx(
|
|
31
|
+
"div",
|
|
32
|
+
{
|
|
33
|
+
onMouseEnter: handleMouseEnter,
|
|
34
|
+
onMouseLeave: handleMouseLeave,
|
|
35
|
+
onClick: handleClick,
|
|
36
|
+
className: "HOKKIEMOJIPICKER-emoji text-4xl p-1 cursor-pointer hover:bg-white/15 rounded-sm size-12.5 flex items-center justify-center overflow-hidden",
|
|
37
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
var SkinEmoji = memo(function SkinEmoji2({
|
|
42
|
+
pickerId,
|
|
43
|
+
emoji,
|
|
44
|
+
onEmojiSelect,
|
|
45
|
+
onEmojiMouseEnter,
|
|
46
|
+
onEmojiMouseLeave
|
|
47
|
+
}) {
|
|
48
|
+
const skin = useSkin({ pickerId });
|
|
49
|
+
const fakeEmoji = useMemo(() => {
|
|
50
|
+
const charForSkin = [1, 2, 3, 4, 5].includes(skin) ? emoji.tones.find((a) => a.tone.find((b) => b === skin) === skin)?.char : emoji.char;
|
|
51
|
+
return {
|
|
52
|
+
...emoji,
|
|
53
|
+
char: charForSkin,
|
|
54
|
+
preRendered: true,
|
|
55
|
+
tones: [
|
|
56
|
+
{
|
|
57
|
+
name: emoji.tones[0].name.replaceAll("1", "0"),
|
|
58
|
+
tone: [0],
|
|
59
|
+
char: emoji.char
|
|
60
|
+
},
|
|
61
|
+
...emoji.tones
|
|
62
|
+
]
|
|
63
|
+
};
|
|
64
|
+
}, [emoji, skin]);
|
|
65
|
+
const handleMouseEnter = useCallback(() => {
|
|
66
|
+
window["emojipicker-" + pickerId].changeFooterEmoji(fakeEmoji);
|
|
67
|
+
window["emojipicker-" + pickerId].changeSearchbarPlaceholder(emoji.name);
|
|
68
|
+
onEmojiMouseEnter(fakeEmoji);
|
|
69
|
+
}, [pickerId, fakeEmoji, emoji.name, onEmojiMouseEnter]);
|
|
70
|
+
const handleMouseLeave = useCallback(() => {
|
|
71
|
+
onEmojiMouseLeave(fakeEmoji);
|
|
72
|
+
}, [fakeEmoji, onEmojiMouseLeave]);
|
|
73
|
+
const handleClick = useCallback(() => {
|
|
74
|
+
onEmojiSelect(fakeEmoji);
|
|
75
|
+
}, [fakeEmoji, onEmojiSelect]);
|
|
76
|
+
const html = useMemo(() => render(fakeEmoji.char), [fakeEmoji.char]);
|
|
77
|
+
return /* @__PURE__ */ jsx(
|
|
78
|
+
"div",
|
|
79
|
+
{
|
|
80
|
+
onMouseEnter: handleMouseEnter,
|
|
81
|
+
onMouseLeave: handleMouseLeave,
|
|
82
|
+
onClick: handleClick,
|
|
83
|
+
className: "HOKKIEMOJIPICKER-skinemoji text-4xl p-1 cursor-pointer hover:bg-white/15 rounded-sm size-12.5 flex items-center justify-center overflow-hidden",
|
|
84
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
var CategoryDisplay = memo(function CategoryDisplay2({
|
|
89
|
+
category,
|
|
90
|
+
categoryInfo,
|
|
91
|
+
isToneSelectorEnabled,
|
|
92
|
+
onEmojiSelect,
|
|
93
|
+
onEmojiMouseEnter,
|
|
94
|
+
onEmojiMouseLeave,
|
|
95
|
+
pickerId
|
|
96
|
+
}) {
|
|
97
|
+
const [isOpen, setIsOpen] = useState(true);
|
|
98
|
+
const searchValue = useSearchValue({ pickerId });
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
setIsOpen(
|
|
101
|
+
(localStorage.getItem(
|
|
102
|
+
"hokkiemojipicker-category-" + category.name + "-open"
|
|
103
|
+
) || "true") === "true"
|
|
104
|
+
);
|
|
105
|
+
}, [category.name]);
|
|
106
|
+
const searchLower = useMemo(
|
|
107
|
+
() => (searchValue || "").toLowerCase().replace(/_/g, " "),
|
|
108
|
+
[searchValue]
|
|
109
|
+
);
|
|
110
|
+
const filteredEmojis = useMemo(() => {
|
|
111
|
+
if (!searchLower) return null;
|
|
112
|
+
return category.emojis.filter(
|
|
113
|
+
(emoji) => emoji.name.toLowerCase().replace(/_/g, " ").includes(searchLower)
|
|
114
|
+
);
|
|
115
|
+
}, [category.emojis, searchLower]);
|
|
116
|
+
if (searchLower) {
|
|
117
|
+
if (category.name === "recentlyUsed")
|
|
118
|
+
return /* @__PURE__ */ jsx("div", { className: "h-1.5 w-full" });
|
|
119
|
+
return /* @__PURE__ */ jsx(Fragment, { children: filteredEmojis.map((emoji) => {
|
|
120
|
+
if (emoji.hasTone && !emoji.preRendered) {
|
|
121
|
+
return /* @__PURE__ */ jsx(
|
|
122
|
+
SkinEmoji,
|
|
123
|
+
{
|
|
124
|
+
onEmojiSelect,
|
|
125
|
+
pickerId,
|
|
126
|
+
onEmojiMouseEnter,
|
|
127
|
+
onEmojiMouseLeave,
|
|
128
|
+
emoji
|
|
129
|
+
},
|
|
130
|
+
emoji.name
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
return /* @__PURE__ */ jsx(
|
|
134
|
+
Emoji,
|
|
135
|
+
{
|
|
136
|
+
onEmojiSelect,
|
|
137
|
+
pickerId,
|
|
138
|
+
emoji,
|
|
139
|
+
onEmojiMouseEnter,
|
|
140
|
+
onEmojiMouseLeave
|
|
141
|
+
},
|
|
142
|
+
emoji.name
|
|
143
|
+
);
|
|
144
|
+
}) });
|
|
145
|
+
}
|
|
146
|
+
return /* @__PURE__ */ jsxs("div", { className: "HOKKIEMOJIPICKER-categorydisplay flex flex-col relative w-full pt-2", children: [
|
|
147
|
+
/* @__PURE__ */ jsx(
|
|
148
|
+
"div",
|
|
149
|
+
{
|
|
150
|
+
className: "HOKKIEMOJIPICKER-categoryHeader sticky top-0 pt-2 cursor-pointer text-white px-2 flex bg-[#131416] p-1 pb-2 " + category.name,
|
|
151
|
+
onClick: () => {
|
|
152
|
+
const newOpen = !isOpen;
|
|
153
|
+
setIsOpen(newOpen);
|
|
154
|
+
localStorage.setItem(
|
|
155
|
+
"hokkiemojipicker-category-" + category.name + "-open",
|
|
156
|
+
newOpen ? "true" : "false"
|
|
157
|
+
);
|
|
158
|
+
},
|
|
159
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex gap-1.5 items-center opacity-75 hover:opacity-100", children: [
|
|
160
|
+
/* @__PURE__ */ jsx("span", { className: "*:size-4.5", children: categoryInfo.icon }),
|
|
161
|
+
" ",
|
|
162
|
+
/* @__PURE__ */ jsx("span", { className: "text-md font-semibold font-gg", children: categoryInfo.name }),
|
|
163
|
+
/* @__PURE__ */ jsx(
|
|
164
|
+
ChevronDown,
|
|
165
|
+
{
|
|
166
|
+
strokeWidth: 2,
|
|
167
|
+
className: "transition-all size-5 data-[open=false]:-rotate-90",
|
|
168
|
+
"data-open": isOpen ? "true" : "false"
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
] })
|
|
172
|
+
}
|
|
173
|
+
),
|
|
174
|
+
isOpen && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-y-0.5", children: category.emojis.map((emoji) => {
|
|
175
|
+
if (emoji.hasTone && !emoji.preRendered && isToneSelectorEnabled) {
|
|
176
|
+
return /* @__PURE__ */ jsx(
|
|
177
|
+
SkinEmoji,
|
|
178
|
+
{
|
|
179
|
+
onEmojiSelect,
|
|
180
|
+
pickerId,
|
|
181
|
+
emoji,
|
|
182
|
+
onEmojiMouseEnter,
|
|
183
|
+
onEmojiMouseLeave
|
|
184
|
+
},
|
|
185
|
+
emoji.name
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
return /* @__PURE__ */ jsx(
|
|
189
|
+
Emoji,
|
|
190
|
+
{
|
|
191
|
+
onEmojiSelect,
|
|
192
|
+
pickerId,
|
|
193
|
+
onEmojiMouseEnter,
|
|
194
|
+
onEmojiMouseLeave,
|
|
195
|
+
emoji
|
|
196
|
+
},
|
|
197
|
+
emoji.name
|
|
198
|
+
);
|
|
199
|
+
}) })
|
|
200
|
+
] });
|
|
201
|
+
});
|
|
202
|
+
var categoryDisplay_default = CategoryDisplay;
|
|
203
|
+
export {
|
|
204
|
+
categoryDisplay_default as default
|
|
205
|
+
};
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import {
|
|
2
|
+
render,
|
|
3
|
+
useSearchValue,
|
|
4
|
+
useSkin
|
|
5
|
+
} from "./chunk-LP6LBWNJ.js";
|
|
6
|
+
|
|
7
|
+
// src/categoryDisplay.tsx
|
|
8
|
+
import { ChevronDown } from "lucide-react";
|
|
9
|
+
import { memo, useEffect, useState, useCallback, useMemo } from "react";
|
|
10
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
var Emoji = memo(function Emoji2({
|
|
12
|
+
pickerId,
|
|
13
|
+
emoji,
|
|
14
|
+
onEmojiMouseEnter,
|
|
15
|
+
onEmojiMouseLeave,
|
|
16
|
+
onEmojiSelect
|
|
17
|
+
}) {
|
|
18
|
+
const handleMouseEnter = useCallback(() => {
|
|
19
|
+
window["emojipicker-" + pickerId].changeFooterEmoji(emoji);
|
|
20
|
+
window["emojipicker-" + pickerId].changeSearchbarPlaceholder(emoji.name);
|
|
21
|
+
onEmojiMouseEnter(emoji);
|
|
22
|
+
}, [pickerId, emoji, onEmojiMouseEnter]);
|
|
23
|
+
const handleMouseLeave = useCallback(() => {
|
|
24
|
+
onEmojiMouseLeave(emoji);
|
|
25
|
+
}, [emoji, onEmojiMouseLeave]);
|
|
26
|
+
const handleClick = useCallback(() => {
|
|
27
|
+
onEmojiSelect(emoji);
|
|
28
|
+
}, [emoji, onEmojiSelect]);
|
|
29
|
+
const html = useMemo(() => render(emoji.char), [emoji.char]);
|
|
30
|
+
return /* @__PURE__ */ jsx(
|
|
31
|
+
"div",
|
|
32
|
+
{
|
|
33
|
+
onMouseEnter: handleMouseEnter,
|
|
34
|
+
onMouseLeave: handleMouseLeave,
|
|
35
|
+
onClick: handleClick,
|
|
36
|
+
className: "HOKKIEMOJIPICKER-emoji text-4xl p-1 cursor-pointer hover:bg-white/15 rounded-sm size-12.5 flex items-center justify-center overflow-hidden",
|
|
37
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
var SkinEmoji = memo(function SkinEmoji2({
|
|
42
|
+
pickerId,
|
|
43
|
+
emoji,
|
|
44
|
+
onEmojiSelect,
|
|
45
|
+
onEmojiMouseEnter,
|
|
46
|
+
onEmojiMouseLeave
|
|
47
|
+
}) {
|
|
48
|
+
const skin = useSkin({ pickerId });
|
|
49
|
+
const fakeEmoji = useMemo(() => {
|
|
50
|
+
const charForSkin = [1, 2, 3, 4, 5].includes(skin) ? emoji.tones.find((a) => a.tone.find((b) => b === skin) === skin)?.char : emoji.char;
|
|
51
|
+
return {
|
|
52
|
+
...emoji,
|
|
53
|
+
char: charForSkin,
|
|
54
|
+
preRendered: true,
|
|
55
|
+
tones: [
|
|
56
|
+
{
|
|
57
|
+
name: emoji.tones[0].name.replaceAll("1", "0"),
|
|
58
|
+
tone: [0],
|
|
59
|
+
char: emoji.char
|
|
60
|
+
},
|
|
61
|
+
...emoji.tones
|
|
62
|
+
]
|
|
63
|
+
};
|
|
64
|
+
}, [emoji, skin]);
|
|
65
|
+
const handleMouseEnter = useCallback(() => {
|
|
66
|
+
window["emojipicker-" + pickerId].changeFooterEmoji(fakeEmoji);
|
|
67
|
+
window["emojipicker-" + pickerId].changeSearchbarPlaceholder(emoji.name);
|
|
68
|
+
onEmojiMouseEnter(fakeEmoji);
|
|
69
|
+
}, [pickerId, fakeEmoji, emoji.name, onEmojiMouseEnter]);
|
|
70
|
+
const handleMouseLeave = useCallback(() => {
|
|
71
|
+
onEmojiMouseLeave(fakeEmoji);
|
|
72
|
+
}, [fakeEmoji, onEmojiMouseLeave]);
|
|
73
|
+
const handleClick = useCallback(() => {
|
|
74
|
+
onEmojiSelect(fakeEmoji);
|
|
75
|
+
}, [fakeEmoji, onEmojiSelect]);
|
|
76
|
+
const html = useMemo(() => render(fakeEmoji.char), [fakeEmoji.char]);
|
|
77
|
+
return /* @__PURE__ */ jsx(
|
|
78
|
+
"div",
|
|
79
|
+
{
|
|
80
|
+
onMouseEnter: handleMouseEnter,
|
|
81
|
+
onMouseLeave: handleMouseLeave,
|
|
82
|
+
onClick: handleClick,
|
|
83
|
+
className: "HOKKIEMOJIPICKER-skinemoji text-4xl p-1 cursor-pointer hover:bg-white/15 rounded-sm size-12.5 flex items-center justify-center overflow-hidden",
|
|
84
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
var CategoryDisplay = memo(function CategoryDisplay2({
|
|
89
|
+
category,
|
|
90
|
+
categoryInfo,
|
|
91
|
+
isToneSelectorEnabled,
|
|
92
|
+
onEmojiSelect,
|
|
93
|
+
onEmojiMouseEnter,
|
|
94
|
+
onEmojiMouseLeave,
|
|
95
|
+
pickerId
|
|
96
|
+
}) {
|
|
97
|
+
const [isOpen, setIsOpen] = useState(true);
|
|
98
|
+
const searchValue = useSearchValue({ pickerId });
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
setIsOpen(
|
|
101
|
+
(localStorage.getItem(
|
|
102
|
+
"hokkiemojipicker-category-" + category.name + "-open"
|
|
103
|
+
) || "true") === "true"
|
|
104
|
+
);
|
|
105
|
+
}, [category.name]);
|
|
106
|
+
const searchLower = useMemo(
|
|
107
|
+
() => (searchValue || "").toLowerCase().replace(/_/g, " "),
|
|
108
|
+
[searchValue]
|
|
109
|
+
);
|
|
110
|
+
const filteredEmojis = useMemo(() => {
|
|
111
|
+
if (!searchLower) return null;
|
|
112
|
+
return category.emojis.filter(
|
|
113
|
+
(emoji) => emoji.name.toLowerCase().replace(/_/g, " ").includes(searchLower)
|
|
114
|
+
);
|
|
115
|
+
}, [category.emojis, searchLower]);
|
|
116
|
+
if (searchLower) {
|
|
117
|
+
if (category.name === "recentlyUsed")
|
|
118
|
+
return /* @__PURE__ */ jsx("div", { className: "h-1.5 w-full" });
|
|
119
|
+
return /* @__PURE__ */ jsx(Fragment, { children: filteredEmojis.map((emoji) => {
|
|
120
|
+
if (emoji.hasTone && !emoji.preRendered) {
|
|
121
|
+
return /* @__PURE__ */ jsx(
|
|
122
|
+
SkinEmoji,
|
|
123
|
+
{
|
|
124
|
+
onEmojiSelect,
|
|
125
|
+
pickerId,
|
|
126
|
+
onEmojiMouseEnter,
|
|
127
|
+
onEmojiMouseLeave,
|
|
128
|
+
emoji
|
|
129
|
+
},
|
|
130
|
+
emoji.name
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
return /* @__PURE__ */ jsx(
|
|
134
|
+
Emoji,
|
|
135
|
+
{
|
|
136
|
+
onEmojiSelect,
|
|
137
|
+
pickerId,
|
|
138
|
+
emoji,
|
|
139
|
+
onEmojiMouseEnter,
|
|
140
|
+
onEmojiMouseLeave
|
|
141
|
+
},
|
|
142
|
+
emoji.name
|
|
143
|
+
);
|
|
144
|
+
}) });
|
|
145
|
+
}
|
|
146
|
+
return /* @__PURE__ */ jsxs("div", { className: "HOKKIEMOJIPICKER-categorydisplay flex flex-col relative w-full pt-2", children: [
|
|
147
|
+
/* @__PURE__ */ jsx(
|
|
148
|
+
"div",
|
|
149
|
+
{
|
|
150
|
+
className: "HOKKIEMOJIPICKER-categoryHeader sticky top-0 pt-2 cursor-pointer text-white px-2 flex bg-[#131416] p-1 pb-2 " + category.name,
|
|
151
|
+
onClick: () => {
|
|
152
|
+
const newOpen = !isOpen;
|
|
153
|
+
setIsOpen(newOpen);
|
|
154
|
+
localStorage.setItem(
|
|
155
|
+
"hokkiemojipicker-category-" + category.name + "-open",
|
|
156
|
+
newOpen ? "true" : "false"
|
|
157
|
+
);
|
|
158
|
+
},
|
|
159
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex gap-1.5 items-center opacity-75 hover:opacity-100", children: [
|
|
160
|
+
/* @__PURE__ */ jsx("span", { className: "*:size-4.5", children: categoryInfo.icon }),
|
|
161
|
+
" ",
|
|
162
|
+
/* @__PURE__ */ jsx("span", { className: "text-md font-semibold font-gg", children: categoryInfo.name }),
|
|
163
|
+
/* @__PURE__ */ jsx(
|
|
164
|
+
ChevronDown,
|
|
165
|
+
{
|
|
166
|
+
strokeWidth: 2,
|
|
167
|
+
className: "transition-all size-5 data-[open=false]:-rotate-90",
|
|
168
|
+
"data-open": isOpen ? "true" : "false"
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
] })
|
|
172
|
+
}
|
|
173
|
+
),
|
|
174
|
+
isOpen && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-y-0.5", children: category.emojis.map((emoji) => {
|
|
175
|
+
if (emoji.hasTone && !emoji.preRendered && isToneSelectorEnabled) {
|
|
176
|
+
return /* @__PURE__ */ jsx(
|
|
177
|
+
SkinEmoji,
|
|
178
|
+
{
|
|
179
|
+
onEmojiSelect,
|
|
180
|
+
pickerId,
|
|
181
|
+
emoji,
|
|
182
|
+
onEmojiMouseEnter,
|
|
183
|
+
onEmojiMouseLeave
|
|
184
|
+
},
|
|
185
|
+
emoji.name
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
return /* @__PURE__ */ jsx(
|
|
189
|
+
Emoji,
|
|
190
|
+
{
|
|
191
|
+
onEmojiSelect,
|
|
192
|
+
pickerId,
|
|
193
|
+
onEmojiMouseEnter,
|
|
194
|
+
onEmojiMouseLeave,
|
|
195
|
+
emoji
|
|
196
|
+
},
|
|
197
|
+
emoji.name
|
|
198
|
+
);
|
|
199
|
+
}) })
|
|
200
|
+
] });
|
|
201
|
+
});
|
|
202
|
+
var categoryDisplay_default = CategoryDisplay;
|
|
203
|
+
export {
|
|
204
|
+
categoryDisplay_default as default
|
|
205
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// src/render.tsx
|
|
2
|
+
import tw from "@twemoji/api";
|
|
3
|
+
function render(txt) {
|
|
4
|
+
let twemojiparsed = tw.parse(txt).replaceAll("<img", '<img style="object-fit: cover;" loading="lazy"');
|
|
5
|
+
if (txt.startsWith("<:") || txt.startsWith("<a:")) {
|
|
6
|
+
const id = txt.split(":")[2].split(">")[0];
|
|
7
|
+
const isAnimated = txt.startsWith("<a:");
|
|
8
|
+
const url = `https://cdn.discordapp.com/emojis/${id}.${isAnimated ? "gif" : "webp"}`;
|
|
9
|
+
twemojiparsed = `<img style="object-fit: cover;" src="${url}" loading="lazy" />`;
|
|
10
|
+
}
|
|
11
|
+
return twemojiparsed;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/hooks.tsx
|
|
15
|
+
import { useEffect, useState } from "react";
|
|
16
|
+
function useSkin({ pickerId }) {
|
|
17
|
+
const [skin, setSkin] = useState(0);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
let raf;
|
|
20
|
+
const loop = () => {
|
|
21
|
+
const newSkin = window["emojipicker-" + pickerId]?.skin;
|
|
22
|
+
setSkin(newSkin || 0);
|
|
23
|
+
raf = requestAnimationFrame(loop);
|
|
24
|
+
};
|
|
25
|
+
raf = requestAnimationFrame(loop);
|
|
26
|
+
return () => {
|
|
27
|
+
cancelAnimationFrame(raf);
|
|
28
|
+
};
|
|
29
|
+
}, [pickerId]);
|
|
30
|
+
return skin;
|
|
31
|
+
}
|
|
32
|
+
function useSearchValue({ pickerId }) {
|
|
33
|
+
const [searchValue, setSearchValue] = useState("");
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
let raf;
|
|
36
|
+
const loop = () => {
|
|
37
|
+
const newSearchValue = window["emojipicker-" + pickerId]?.searchValue || "";
|
|
38
|
+
setSearchValue(newSearchValue);
|
|
39
|
+
raf = requestAnimationFrame(loop);
|
|
40
|
+
};
|
|
41
|
+
raf = requestAnimationFrame(loop);
|
|
42
|
+
return () => {
|
|
43
|
+
cancelAnimationFrame(raf);
|
|
44
|
+
};
|
|
45
|
+
}, [pickerId]);
|
|
46
|
+
return searchValue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
render,
|
|
51
|
+
useSkin,
|
|
52
|
+
useSearchValue
|
|
53
|
+
};
|