@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/index.js CHANGED
@@ -1,254 +1,290 @@
1
+ import {
2
+ render,
3
+ useSearchValue
4
+ } from "./chunk-DMO3WEXH.js";
5
+
1
6
  // src/index.tsx
2
- import { useCallback as useCallback2, useEffect as useEffect7, useMemo as useMemo2, useRef as useRef2, useState as useState7 } from "react";
7
+ import { lazy, Suspense, useCallback as useCallback2, useEffect as useEffect5, useMemo as useMemo2, useRef as useRef2 } from "react";
3
8
 
4
- // src/categoryDisplay.tsx
5
- import { ChevronDown } from "lucide-react";
6
- import { memo, useEffect as useEffect2, useState as useState2, useCallback, useMemo } from "react";
9
+ // src/searchbar.tsx
10
+ import { useEffect, useRef, useState } from "react";
7
11
 
8
- // src/render.tsx
9
- import tw from "@twemoji/api";
10
- function render(txt) {
11
- let twemojiparsed = tw.parse(txt).replaceAll("<img", '<img style="object-fit: cover;" loading="lazy"');
12
- if (txt.startsWith("<:") || txt.startsWith("<a:")) {
13
- const id = txt.split(":")[2].split(">")[0];
14
- const isAnimated = txt.startsWith("<a:");
15
- const url = `https://cdn.discordapp.com/emojis/${id}.${isAnimated ? "gif" : "webp"}`;
16
- twemojiparsed = `<img style="object-fit: cover;" src="${url}" loading="lazy" />`;
17
- }
18
- return twemojiparsed;
19
- }
12
+ // src/icons.tsx
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ var MagniferLinear = (props) => {
15
+ return /* @__PURE__ */ jsxs(
16
+ "svg",
17
+ {
18
+ "aria-hidden": "true",
19
+ fill: "none",
20
+ focusable: "false",
21
+ height: "1em",
22
+ role: "presentation",
23
+ viewBox: "0 0 24 24",
24
+ width: "1em",
25
+ ...props,
26
+ children: [
27
+ /* @__PURE__ */ jsx(
28
+ "circle",
29
+ {
30
+ cx: "11.5",
31
+ cy: "11.5",
32
+ r: "9.5",
33
+ stroke: "currentColor",
34
+ strokeWidth: "1.5"
35
+ }
36
+ ),
37
+ /* @__PURE__ */ jsx(
38
+ "path",
39
+ {
40
+ d: "M18.5 18.5L22 22",
41
+ stroke: "currentColor",
42
+ strokeWidth: "1.5",
43
+ strokeLinecap: "round"
44
+ }
45
+ )
46
+ ]
47
+ }
48
+ );
49
+ };
20
50
 
21
- // src/hooks.tsx
22
- import { useEffect, useState } from "react";
23
- function useSkin({ pickerId }) {
24
- const [skin, setSkin] = useState(0);
51
+ // src/searchbar.tsx
52
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
53
+ function SearchBar({
54
+ searchPlaceholder,
55
+ id
56
+ }) {
57
+ const [isFocused, setIsFocused] = useState(false);
58
+ const inputRef = useRef(null);
59
+ const [inputPlaceholder, setInputPlaceholder] = useState(searchPlaceholder);
25
60
  useEffect(() => {
26
- let raf;
27
- const loop = () => {
28
- const newSkin = window["emojipicker-" + pickerId]?.skin;
29
- setSkin(newSkin || 0);
30
- raf = requestAnimationFrame(loop);
61
+ window["emojipicker-" + id].changeSearchbarPlaceholder = (emoji) => {
62
+ setInputPlaceholder(emoji);
31
63
  };
32
- raf = requestAnimationFrame(loop);
33
- return () => {
34
- cancelAnimationFrame(raf);
64
+ window["emojipicker-" + id].setSearchValue = (value) => {
65
+ inputRef.current.value = value;
66
+ window["emojipicker-" + id].searchValue = value;
35
67
  };
36
- }, [pickerId]);
37
- return skin;
68
+ }, []);
69
+ return /* @__PURE__ */ jsxs2(
70
+ "div",
71
+ {
72
+ "data-focused": isFocused ? "true" : "false",
73
+ className: "bg-white/5 items-center w-full border-1 border-[#323337] p-2 px-3 flex rounded-md data-[focused=true]:border-[#3687E9]",
74
+ children: [
75
+ /* @__PURE__ */ jsx2(
76
+ "input",
77
+ {
78
+ ref: inputRef,
79
+ onChange: (e) => window["emojipicker-" + id].searchValue = e.target.value,
80
+ className: "!outline-0 text-lg w-full",
81
+ onFocus: () => setIsFocused(true),
82
+ onBlur: () => setIsFocused(false),
83
+ placeholder: inputPlaceholder
84
+ }
85
+ ),
86
+ /* @__PURE__ */ jsx2(MagniferLinear, { className: "size-5 opacity-50" })
87
+ ]
88
+ }
89
+ );
38
90
  }
39
- function useSearchValue({ pickerId }) {
40
- const [searchValue, setSearchValue] = useState("");
41
- useEffect(() => {
42
- let raf;
43
- const loop = () => {
44
- const newSearchValue = window["emojipicker-" + pickerId]?.searchValue || "";
45
- setSearchValue(newSearchValue);
46
- raf = requestAnimationFrame(loop);
47
- };
48
- raf = requestAnimationFrame(loop);
49
- return () => {
50
- cancelAnimationFrame(raf);
91
+
92
+ // src/footer.tsx
93
+ import { useEffect as useEffect2, useState as useState2 } from "react";
94
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
95
+ function Footer({
96
+ id,
97
+ firstEmoji
98
+ }) {
99
+ const [footerEmoji, setFooterEmoji] = useState2(firstEmoji);
100
+ useEffect2(() => {
101
+ window["emojipicker-" + id].changeFooterEmoji = (emoji) => {
102
+ setFooterEmoji(emoji);
51
103
  };
52
- }, [pickerId]);
53
- return searchValue;
104
+ }, []);
105
+ return /* @__PURE__ */ jsxs3("div", { className: "HOKKIEMOJIPICKER-footer relative mt-auto flex gap-2 items-center px-4 py-3 bg-[#070709]", children: [
106
+ /* @__PURE__ */ jsx3(
107
+ "div",
108
+ {
109
+ style: {
110
+ cssText: `
111
+ left: 0;
112
+ position: absolute;
113
+ background-color: transparent;
114
+ top: 0;
115
+ width: 12px;
116
+ height: 12px;
117
+ transform: translateY(-100%);
118
+ border-radius: 100%;
119
+ box-shadow: -14px 14px 0px 10px #070709;`
120
+ }
121
+ }
122
+ ),
123
+ /* @__PURE__ */ jsx3(
124
+ "div",
125
+ {
126
+ className: "*:size-9 *:min-w-9 *:max-w-9",
127
+ dangerouslySetInnerHTML: { __html: render(footerEmoji.char) }
128
+ }
129
+ ),
130
+ /* @__PURE__ */ jsx3("p", { className: "text-lg whitespace-nowrap overflow-hidden text-ellipsis font-gg font-semibold", children: (footerEmoji.name || "").split(" ").map((e) => `:${e || ""}:`).join(" ") })
131
+ ] });
54
132
  }
55
133
 
56
- // src/categoryDisplay.tsx
57
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
58
- var Emoji = memo(function Emoji2({
59
- pickerId,
60
- emoji,
61
- onEmojiMouseEnter,
62
- onEmojiMouseLeave,
63
- onEmojiSelect
134
+ // src/sidebarCategory.tsx
135
+ import { useEffect as useEffect3, useState as useState3 } from "react";
136
+ import { jsx as jsx4 } from "react/jsx-runtime";
137
+ function SidebarCategory({
138
+ categoryName,
139
+ picker,
140
+ icon,
141
+ id
64
142
  }) {
65
- const handleMouseEnter = useCallback(() => {
66
- window["emojipicker-" + pickerId].changeFooterEmoji(emoji);
67
- window["emojipicker-" + pickerId].changeSearchbarPlaceholder(emoji.name);
68
- onEmojiMouseEnter(emoji);
69
- }, [pickerId, emoji, onEmojiMouseEnter]);
70
- const handleMouseLeave = useCallback(() => {
71
- onEmojiMouseLeave(emoji);
72
- }, [emoji, onEmojiMouseLeave]);
73
- const handleClick = useCallback(() => {
74
- onEmojiSelect(emoji);
75
- }, [emoji, onEmojiSelect]);
76
- const html = useMemo(() => render(emoji.char), [emoji.char]);
77
- return /* @__PURE__ */ jsx(
78
- "div",
79
- {
80
- tabIndex: -1,
81
- onMouseEnter: handleMouseEnter,
82
- onMouseLeave: handleMouseLeave,
83
- onClick: handleClick,
84
- className: "HOKKIEMOJIPICKER-emoji text-4xl p-1 cursor-pointer hover:bg-white/15 focus:bg-white/20 rounded-sm size-12.5 flex items-center justify-center overflow-hidden",
85
- dangerouslySetInnerHTML: { __html: html }
143
+ const searchValue = useSearchValue({ pickerId: id });
144
+ const [isActive, setIsActive] = useState3(false);
145
+ useEffect3(() => {
146
+ if ((searchValue || "").length > 0) {
147
+ setIsActive(false);
148
+ return;
86
149
  }
87
- );
88
- });
89
- var SkinEmoji = memo(function SkinEmoji2({
90
- pickerId,
91
- emoji,
92
- onEmojiSelect,
93
- onEmojiMouseEnter,
94
- onEmojiMouseLeave
95
- }) {
96
- const skin = useSkin({ pickerId });
97
- const fakeEmoji = useMemo(() => {
98
- const charForSkin = [1, 2, 3, 4, 5].includes(skin) ? emoji.tones.find((a) => a.tone.find((b) => b === skin) === skin)?.char : emoji.char;
99
- return {
100
- ...emoji,
101
- char: charForSkin,
102
- preRendered: true,
103
- tones: [
104
- {
105
- name: emoji.tones[0].name.replaceAll("1", "0"),
106
- tone: [0],
107
- char: emoji.char
108
- },
109
- ...emoji.tones
110
- ]
150
+ const elem = picker.current;
151
+ const updateActive = () => {
152
+ if (!elem) return;
153
+ const header = elem.querySelector(
154
+ ".HOKKIEMOJIPICKER-categoryHeader." + categoryName
155
+ );
156
+ if (!header) return;
157
+ const categoryContainer = header.parentElement;
158
+ const scrollElem = elem.querySelector(
159
+ ".HOKKIEMOJIPICKER-emojidisplay"
160
+ );
161
+ if (!scrollElem) return;
162
+ const containerRect = scrollElem.getBoundingClientRect();
163
+ const categoryRect = categoryContainer.getBoundingClientRect();
164
+ const headerHeight = header.offsetHeight;
165
+ const categoryTop = categoryRect.top - containerRect.top + scrollElem.scrollTop;
166
+ const categoryBottom = categoryTop + categoryContainer.offsetHeight;
167
+ const sTop = scrollElem.scrollTop;
168
+ const inView = sTop >= categoryTop - headerHeight && sTop < categoryBottom - headerHeight;
169
+ setIsActive(inView);
111
170
  };
112
- }, [emoji, skin]);
113
- const handleMouseEnter = useCallback(() => {
114
- window["emojipicker-" + pickerId].changeFooterEmoji(fakeEmoji);
115
- window["emojipicker-" + pickerId].changeSearchbarPlaceholder(emoji.name);
116
- onEmojiMouseEnter(fakeEmoji);
117
- }, [pickerId, fakeEmoji, emoji.name, onEmojiMouseEnter]);
118
- const handleMouseLeave = useCallback(() => {
119
- onEmojiMouseLeave(fakeEmoji);
120
- }, [fakeEmoji, onEmojiMouseLeave]);
121
- const handleClick = useCallback(() => {
122
- onEmojiSelect(fakeEmoji);
123
- }, [fakeEmoji, onEmojiSelect]);
124
- const html = useMemo(() => render(fakeEmoji.char), [fakeEmoji.char]);
125
- return /* @__PURE__ */ jsx(
126
- "div",
171
+ elem.querySelector(".HOKKIEMOJIPICKER-emojidisplay").addEventListener("scroll", updateActive);
172
+ updateActive();
173
+ return () => {
174
+ elem.querySelector(".HOKKIEMOJIPICKER-emojidisplay").removeEventListener("scroll", updateActive);
175
+ };
176
+ }, [picker, searchValue]);
177
+ return /* @__PURE__ */ jsx4(
178
+ "button",
127
179
  {
128
- tabIndex: -1,
129
- onMouseEnter: handleMouseEnter,
130
- onMouseLeave: handleMouseLeave,
131
- onClick: handleClick,
132
- className: "HOKKIEMOJIPICKER-skinemoji text-4xl p-1 cursor-pointer hover:bg-white/15 focus:bg-white/20 rounded-sm size-12.5 flex items-center justify-center overflow-hidden",
133
- dangerouslySetInnerHTML: { __html: html }
180
+ onClick: () => {
181
+ const elem = picker.current;
182
+ if (!elem) return;
183
+ const doScroll = () => {
184
+ const header = elem.querySelector(
185
+ ".HOKKIEMOJIPICKER-categoryHeader." + categoryName
186
+ );
187
+ if (!header) return;
188
+ const categoryContainer = header.parentElement;
189
+ const scrollElem = elem.querySelector(
190
+ ".HOKKIEMOJIPICKER-emojidisplay"
191
+ );
192
+ if (!scrollElem) return;
193
+ const containerRect = scrollElem.getBoundingClientRect();
194
+ const categoryRect = categoryContainer.getBoundingClientRect();
195
+ const headerHeight = header.offsetHeight;
196
+ const targetTop = categoryRect.top - containerRect.top + scrollElem.scrollTop - headerHeight;
197
+ scrollElem.scrollTo({
198
+ top: Math.max(0, targetTop),
199
+ behavior: "smooth"
200
+ });
201
+ };
202
+ if ((searchValue || "").length > 0) {
203
+ window["emojipicker-" + id].setSearchValue("");
204
+ setTimeout(doScroll, 50);
205
+ } else {
206
+ doScroll();
207
+ }
208
+ },
209
+ "data-active": isActive ? "true" : "false",
210
+ className: "!outline-0 HOKKIEMOJIPICKER-sidebarButton cursor-pointer size-8 data-[active=true]:bg-white/5 hover:bg-white/10 overflow-hidden *:!size-6.5 transition-all hover:*:!opacity-85 data-[active=true]:*:!opacity-100 flex items-center justify-center rounded-sm *:opacity-50",
211
+ children: icon
134
212
  }
135
213
  );
136
- });
137
- var CategoryDisplay = memo(function CategoryDisplay2({
138
- category,
139
- categoryInfo,
140
- isToneSelectorEnabled,
141
- onEmojiSelect,
142
- onEmojiMouseEnter,
143
- onEmojiMouseLeave,
144
- pickerId
145
- }) {
146
- const [isOpen, setIsOpen] = useState2(true);
147
- const searchValue = useSearchValue({ pickerId });
148
- useEffect2(() => {
149
- setIsOpen(
150
- (localStorage.getItem(
151
- "hokkiemojipicker-category-" + category.name + "-open"
152
- ) || "true") === "true"
153
- );
154
- }, [category.name]);
155
- const searchLower = useMemo(
156
- () => (searchValue || "").toLowerCase().replace(/_/g, " "),
157
- [searchValue]
214
+ }
215
+
216
+ // src/skinselector.tsx
217
+ import { useCallback, useEffect as useEffect4, useMemo, useState as useState4 } from "react";
218
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
219
+ function SkinSelector({ id }) {
220
+ const skins = useMemo(() => ["\u{1F44F}", "\u{1F44F}\u{1F3FB}", "\u{1F44F}\u{1F3FC}", "\u{1F44F}\u{1F3FD}", "\u{1F44F}\u{1F3FE}", "\u{1F44F}\u{1F3FF}"], []);
221
+ const [selectedTone, setSelectedTone] = useState4(() => {
222
+ const cached = localStorage?.getItem("hokkiemojipicker-skin");
223
+ return cached ? parseInt(cached, 10) : 0;
224
+ });
225
+ const [open, setOpen] = useState4(false);
226
+ useEffect4(() => {
227
+ window["emojipicker-" + id].skin = selectedTone;
228
+ }, [selectedTone, id]);
229
+ const toggleOpen = useCallback(() => setOpen((prev) => !prev), []);
230
+ const handleSkinSelect = useCallback((i) => {
231
+ setOpen(false);
232
+ setSelectedTone(i);
233
+ try {
234
+ localStorage?.setItem("hokkiemojipicker-skin", String(i));
235
+ } catch (e) {
236
+ }
237
+ }, []);
238
+ const renderedCurrentSkin = useMemo(
239
+ () => render(skins[selectedTone]),
240
+ [skins, selectedTone]
241
+ );
242
+ const availableSkins = useMemo(
243
+ () => skins.map((skin, i) => skin === skins[selectedTone] ? null : { skin, i }).filter(Boolean),
244
+ [skins, selectedTone]
158
245
  );
159
- const filteredEmojis = useMemo(() => {
160
- if (!searchLower) return null;
161
- return category.emojis.filter(
162
- (emoji) => emoji.name.toLowerCase().replace(/_/g, " ").includes(searchLower)
163
- );
164
- }, [category.emojis, searchLower]);
165
- if (searchLower) {
166
- if (category.name === "recentlyUsed")
167
- return /* @__PURE__ */ jsx("div", { className: "h-1.5 w-full" });
168
- return /* @__PURE__ */ jsx(Fragment, { children: filteredEmojis.map((emoji) => {
169
- if (emoji.hasTone && !emoji.preRendered) {
170
- return /* @__PURE__ */ jsx(
171
- SkinEmoji,
172
- {
173
- onEmojiSelect,
174
- pickerId,
175
- onEmojiMouseEnter,
176
- onEmojiMouseLeave,
177
- emoji
178
- },
179
- emoji.name
180
- );
246
+ return /* @__PURE__ */ jsxs4("div", { className: "relative mr-1", children: [
247
+ /* @__PURE__ */ jsx5(
248
+ "div",
249
+ {
250
+ className: "HOKKIEMOJIPICKER-skinselector-trigger opacity-75 hover:opacity-100 cursor-pointer *:size-7 *:min-w-7",
251
+ onClick: toggleOpen,
252
+ dangerouslySetInnerHTML: { __html: renderedCurrentSkin }
181
253
  }
182
- return /* @__PURE__ */ jsx(
183
- Emoji,
184
- {
185
- onEmojiSelect,
186
- pickerId,
187
- emoji,
188
- onEmojiMouseEnter,
189
- onEmojiMouseLeave
190
- },
191
- emoji.name
192
- );
193
- }) });
194
- }
195
- return /* @__PURE__ */ jsxs("div", { className: "HOKKIEMOJIPICKER-categorydisplay flex flex-col relative w-full pt-2", children: [
196
- /* @__PURE__ */ jsx(
254
+ ),
255
+ /* @__PURE__ */ jsx5(
197
256
  "div",
198
257
  {
199
- className: "HOKKIEMOJIPICKER-categoryHeader sticky top-0 pt-2 cursor-pointer text-white px-2 flex bg-[#131416] p-1 pb-2 " + category.name,
200
- onClick: () => {
201
- const newOpen = !isOpen;
202
- setIsOpen(newOpen);
203
- localStorage.setItem(
204
- "hokkiemojipicker-category-" + category.name + "-open",
205
- newOpen ? "true" : "false"
206
- );
258
+ style: {
259
+ opacity: open ? 1 : 0,
260
+ pointerEvents: open ? "all" : "none"
207
261
  },
208
- children: /* @__PURE__ */ jsxs("span", { className: "flex gap-1.5 items-center opacity-75 hover:opacity-100", children: [
209
- /* @__PURE__ */ jsx("span", { className: "*:size-4.5", children: categoryInfo.icon }),
210
- " ",
211
- /* @__PURE__ */ jsx("span", { className: "text-md font-semibold font-gg", children: categoryInfo.name }),
212
- /* @__PURE__ */ jsx(
213
- ChevronDown,
262
+ className: "absolute flex transition-all flex-col cursor-pointer top-full translate-y-2 overflow-hidden -left-2 rounded-sm border-1 bg-neutral-900",
263
+ children: availableSkins.map((item) => {
264
+ const { skin, i } = item;
265
+ return /* @__PURE__ */ jsx5(
266
+ "div",
214
267
  {
215
- strokeWidth: 2,
216
- className: "transition-all size-5 data-[open=false]:-rotate-90",
217
- "data-open": isOpen ? "true" : "false"
218
- }
219
- )
220
- ] })
221
- }
222
- ),
223
- isOpen && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-y-0.5", children: category.emojis.map((emoji) => {
224
- if (emoji.hasTone && !emoji.preRendered && isToneSelectorEnabled) {
225
- return /* @__PURE__ */ jsx(
226
- SkinEmoji,
227
- {
228
- onEmojiSelect,
229
- pickerId,
230
- emoji,
231
- onEmojiMouseEnter,
232
- onEmojiMouseLeave
233
- },
234
- emoji.name
235
- );
268
+ className: "HOKKIEMOJIPICKER-skinselector-skinoption *:size-7 *:min-w-7 hover:bg-white/5 p-2 transition-all",
269
+ onClick: () => handleSkinSelect(i),
270
+ dangerouslySetInnerHTML: {
271
+ __html: render(skin)
272
+ }
273
+ },
274
+ i
275
+ );
276
+ })
236
277
  }
237
- return /* @__PURE__ */ jsx(
238
- Emoji,
239
- {
240
- onEmojiSelect,
241
- pickerId,
242
- onEmojiMouseEnter,
243
- onEmojiMouseLeave,
244
- emoji
245
- },
246
- emoji.name
247
- );
248
- }) })
278
+ )
249
279
  ] });
250
- });
251
- var categoryDisplay_default = CategoryDisplay;
280
+ }
281
+
282
+ // src/cn.ts
283
+ import { clsx } from "clsx";
284
+ import { twMerge } from "tailwind-merge";
285
+ var cn = (...inputs) => {
286
+ return twMerge(clsx(inputs));
287
+ };
252
288
 
253
289
  // src/emojilib.json
254
290
  var emojilib_default = [
@@ -16980,260 +17016,9 @@ var emojilib_default = [
16980
17016
  }
16981
17017
  ];
16982
17018
 
16983
- // src/searchbar.tsx
16984
- import { useEffect as useEffect3, useRef, useState as useState3 } from "react";
16985
-
16986
- // src/icons.tsx
16987
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
16988
- var MagniferLinear = (props) => {
16989
- return /* @__PURE__ */ jsxs2(
16990
- "svg",
16991
- {
16992
- "aria-hidden": "true",
16993
- fill: "none",
16994
- focusable: "false",
16995
- height: "1em",
16996
- role: "presentation",
16997
- viewBox: "0 0 24 24",
16998
- width: "1em",
16999
- ...props,
17000
- children: [
17001
- /* @__PURE__ */ jsx2(
17002
- "circle",
17003
- {
17004
- cx: "11.5",
17005
- cy: "11.5",
17006
- r: "9.5",
17007
- stroke: "currentColor",
17008
- strokeWidth: "1.5"
17009
- }
17010
- ),
17011
- /* @__PURE__ */ jsx2(
17012
- "path",
17013
- {
17014
- d: "M18.5 18.5L22 22",
17015
- stroke: "currentColor",
17016
- strokeWidth: "1.5",
17017
- strokeLinecap: "round"
17018
- }
17019
- )
17020
- ]
17021
- }
17022
- );
17023
- };
17024
-
17025
- // src/searchbar.tsx
17026
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
17027
- function SearchBar({
17028
- searchPlaceholder,
17029
- id
17030
- }) {
17031
- const [isFocused, setIsFocused] = useState3(false);
17032
- const inputRef = useRef(null);
17033
- const [inputPlaceholder, setInputPlaceholder] = useState3(searchPlaceholder);
17034
- useEffect3(() => {
17035
- window["emojipicker-" + id].changeSearchbarPlaceholder = (emoji) => {
17036
- setInputPlaceholder(emoji);
17037
- };
17038
- window["emojipicker-" + id].setSearchValue = (value) => {
17039
- inputRef.current.value = value;
17040
- window["emojipicker-" + id].searchValue = value;
17041
- };
17042
- }, []);
17043
- return /* @__PURE__ */ jsxs3(
17044
- "div",
17045
- {
17046
- "data-focused": isFocused ? "true" : "false",
17047
- className: "bg-[#121214] items-center w-full border-1 border-[#323337] p-2 px-3 flex rounded-md data-[focused=true]:border-[#3687E9]",
17048
- children: [
17049
- /* @__PURE__ */ jsx3(
17050
- "input",
17051
- {
17052
- ref: inputRef,
17053
- onChange: (e) => window["emojipicker-" + id].searchValue = e.target.value,
17054
- className: "!outline-0 text-lg w-full",
17055
- onFocus: () => setIsFocused(true),
17056
- onBlur: () => setIsFocused(false),
17057
- placeholder: inputPlaceholder
17058
- }
17059
- ),
17060
- /* @__PURE__ */ jsx3(MagniferLinear, { className: "size-5 opacity-50" })
17061
- ]
17062
- }
17063
- );
17064
- }
17065
-
17066
- // src/footer.tsx
17067
- import { useEffect as useEffect4, useState as useState4 } from "react";
17068
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
17069
- function Footer({
17070
- id,
17071
- firstEmoji
17072
- }) {
17073
- const [footerEmoji, setFooterEmoji] = useState4(firstEmoji);
17074
- useEffect4(() => {
17075
- window["emojipicker-" + id].changeFooterEmoji = (emoji) => {
17076
- setFooterEmoji(emoji);
17077
- };
17078
- }, []);
17079
- return /* @__PURE__ */ jsxs4("div", { className: "HOKKIEMOJIPICKER-footer mt-auto flex gap-2 items-center border-t-1 px-4 py-3 border-[#363639] bg-[#070709]", children: [
17080
- /* @__PURE__ */ jsx4(
17081
- "div",
17082
- {
17083
- className: "*:size-9 *:min-w-9 *:max-w-9",
17084
- dangerouslySetInnerHTML: { __html: render(footerEmoji.char) }
17085
- }
17086
- ),
17087
- /* @__PURE__ */ jsx4("p", { className: "text-lg whitespace-nowrap overflow-hidden text-ellipsis font-gg font-semibold", children: (footerEmoji.name || "").split(" ").map((e) => `:${e || ""}:`).join(" ") })
17088
- ] });
17089
- }
17090
-
17091
- // src/sidebarCategory.tsx
17092
- import { useEffect as useEffect5, useState as useState5 } from "react";
17093
- import { jsx as jsx5 } from "react/jsx-runtime";
17094
- function SidebarCategory({
17095
- categoryName,
17096
- picker,
17097
- icon,
17098
- id
17099
- }) {
17100
- const searchValue = useSearchValue({ pickerId: id });
17101
- const [isActive, setIsActive] = useState5(false);
17102
- useEffect5(() => {
17103
- if ((searchValue || "").length > 0) {
17104
- setIsActive(false);
17105
- return;
17106
- }
17107
- const elem = picker.current;
17108
- const updateActive = () => {
17109
- if (!elem) return;
17110
- const header = elem.querySelector(
17111
- ".HOKKIEMOJIPICKER-categoryHeader." + categoryName
17112
- );
17113
- if (!header) return;
17114
- const categoryContainer = header.parentElement;
17115
- const scrollElem = elem.querySelector(
17116
- ".HOKKIEMOJIPICKER-emojidisplay"
17117
- );
17118
- if (!scrollElem) return;
17119
- const containerRect = scrollElem.getBoundingClientRect();
17120
- const categoryRect = categoryContainer.getBoundingClientRect();
17121
- const headerHeight = header.offsetHeight;
17122
- const categoryTop = categoryRect.top - containerRect.top + scrollElem.scrollTop;
17123
- const categoryBottom = categoryTop + categoryContainer.offsetHeight;
17124
- const sTop = scrollElem.scrollTop;
17125
- const inView = sTop >= categoryTop - headerHeight && sTop < categoryBottom - headerHeight;
17126
- setIsActive(inView);
17127
- };
17128
- elem.querySelector(".HOKKIEMOJIPICKER-emojidisplay").addEventListener("scroll", updateActive);
17129
- updateActive();
17130
- return () => {
17131
- elem.querySelector(".HOKKIEMOJIPICKER-emojidisplay").removeEventListener("scroll", updateActive);
17132
- };
17133
- }, [picker, searchValue]);
17134
- return /* @__PURE__ */ jsx5(
17135
- "button",
17136
- {
17137
- onClick: () => {
17138
- const elem = picker.current;
17139
- if (!elem) return;
17140
- const doScroll = () => {
17141
- const header = elem.querySelector(
17142
- ".HOKKIEMOJIPICKER-categoryHeader." + categoryName
17143
- );
17144
- if (!header) return;
17145
- const categoryContainer = header.parentElement;
17146
- const scrollElem = elem.querySelector(
17147
- ".HOKKIEMOJIPICKER-emojidisplay"
17148
- );
17149
- if (!scrollElem) return;
17150
- const containerRect = scrollElem.getBoundingClientRect();
17151
- const categoryRect = categoryContainer.getBoundingClientRect();
17152
- const headerHeight = header.offsetHeight;
17153
- const targetTop = categoryRect.top - containerRect.top + scrollElem.scrollTop - headerHeight;
17154
- scrollElem.scrollTo({
17155
- top: Math.max(0, targetTop),
17156
- behavior: "smooth"
17157
- });
17158
- };
17159
- if ((searchValue || "").length > 0) {
17160
- window["emojipicker-" + id].setSearchValue("");
17161
- setTimeout(doScroll, 50);
17162
- } else {
17163
- doScroll();
17164
- }
17165
- },
17166
- "data-active": isActive ? "true" : "false",
17167
- className: "!outline-0 HOKKIEMOJIPICKER-sidebarButton cursor-pointer size-8 data-[active=true]:bg-white/5 hover:bg-white/10 overflow-hidden *:!size-6.5 transition-all hover:*:!opacity-85 data-[active=true]:*:!opacity-100 flex items-center justify-center rounded-sm *:opacity-50",
17168
- children: icon
17169
- }
17170
- );
17171
- }
17172
-
17173
- // src/skinselector.tsx
17174
- import { useEffect as useEffect6, useState as useState6 } from "react";
17175
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
17176
- function SkinSelector({ id }) {
17177
- const skins = ["\u{1F44F}", "\u{1F44F}\u{1F3FB}", "\u{1F44F}\u{1F3FC}", "\u{1F44F}\u{1F3FD}", "\u{1F44F}\u{1F3FE}", "\u{1F44F}\u{1F3FF}"];
17178
- const [selectedTone, setSelectedTone] = useState6(0);
17179
- const [open, setOpen] = useState6(false);
17180
- useEffect6(() => {
17181
- setSelectedTone(
17182
- parseInt(localStorage.getItem("hokkiemojipicker-skin") || "0")
17183
- );
17184
- }, []);
17185
- useEffect6(() => {
17186
- window["emojipicker-" + id].skin = selectedTone;
17187
- }, [selectedTone]);
17188
- return /* @__PURE__ */ jsxs5("div", { className: "relative mr-1", children: [
17189
- /* @__PURE__ */ jsx6(
17190
- "div",
17191
- {
17192
- className: "HOKKIEMOJIPICKER-skinselector-trigger opacity-75 hover:opacity-100 cursor-pointer *:size-7 *:min-w-7",
17193
- onClick: () => {
17194
- setOpen(!open);
17195
- },
17196
- dangerouslySetInnerHTML: { __html: render(skins[selectedTone]) }
17197
- }
17198
- ),
17199
- /* @__PURE__ */ jsx6(
17200
- "div",
17201
- {
17202
- style: {
17203
- opacity: open ? 1 : 0,
17204
- pointerEvents: open ? "all" : "none"
17205
- },
17206
- className: "absolute flex transition-all flex-col cursor-pointer top-full translate-y-2 overflow-hidden -left-2 rounded-sm border-1 bg-neutral-900",
17207
- children: skins.filter((a) => a !== skins[selectedTone]).map((skin, i) => {
17208
- return /* @__PURE__ */ jsx6(
17209
- "div",
17210
- {
17211
- className: "HOKKIEMOJIPICKER-skinselector-skinoption *:size-7 *:min-w-7 hover:bg-white/5 p-2 transition-all",
17212
- onClick: () => {
17213
- setOpen(!open);
17214
- setSelectedTone(i);
17215
- localStorage.setItem("hokkiemojipicker-skin", i + "");
17216
- },
17217
- dangerouslySetInnerHTML: {
17218
- __html: render(skin)
17219
- }
17220
- }
17221
- );
17222
- })
17223
- }
17224
- )
17225
- ] });
17226
- }
17227
-
17228
- // src/cn.ts
17229
- import { clsx } from "clsx";
17230
- import { twMerge } from "tailwind-merge";
17231
- var cn = (...inputs) => {
17232
- return twMerge(clsx(inputs));
17233
- };
17234
-
17235
17019
  // src/index.tsx
17236
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
17020
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
17021
+ var CategoryDisplay = lazy(() => import("./categoryDisplay-AZPE23IJ.js"));
17237
17022
  function EmojiSelector({
17238
17023
  categories = {},
17239
17024
  customEmojis = {},
@@ -17252,15 +17037,18 @@ function EmojiSelector({
17252
17037
  height = 500,
17253
17038
  width = 520
17254
17039
  }) {
17255
- let recentlyUsed = JSON.parse(
17256
- (localStorage || { getItem: (a) => "[]" }).getItem(
17257
- "hokkiemojipicker-recentlyused"
17258
- ) || "[]"
17040
+ const recentlyUsed = useMemo2(
17041
+ () => JSON.parse(
17042
+ (localStorage || { getItem: (a) => "[]" }).getItem(
17043
+ "hokkiemojipicker-recentlyused"
17044
+ ) || "[]"
17045
+ ),
17046
+ []
17259
17047
  );
17260
17048
  const categoryData = {
17261
17049
  recentlyUsed: recentlyUsed.length > 0 ? {
17262
17050
  name: "Recently Used",
17263
- icon: /* @__PURE__ */ jsx7(
17051
+ icon: /* @__PURE__ */ jsx6(
17264
17052
  "svg",
17265
17053
  {
17266
17054
  "aria-hidden": "true",
@@ -17270,7 +17058,7 @@ function EmojiSelector({
17270
17058
  height: "24",
17271
17059
  fill: "none",
17272
17060
  viewBox: "0 0 24 24",
17273
- children: /* @__PURE__ */ jsx7(
17061
+ children: /* @__PURE__ */ jsx6(
17274
17062
  "path",
17275
17063
  {
17276
17064
  fill: "currentColor",
@@ -17284,7 +17072,7 @@ function EmojiSelector({
17284
17072
  } : false,
17285
17073
  customServerIcons: (customEmojis.emojis || []).length > 0 ? {
17286
17074
  name: customEmojis.serverName,
17287
- icon: /* @__PURE__ */ jsx7("div", { className: "relative rounded-full overflow-hidden", children: /* @__PURE__ */ jsx7(
17075
+ icon: /* @__PURE__ */ jsx6("div", { className: "relative rounded-full overflow-hidden", children: /* @__PURE__ */ jsx6(
17288
17076
  "img",
17289
17077
  {
17290
17078
  src: customEmojis.serverIconURL,
@@ -17295,7 +17083,7 @@ function EmojiSelector({
17295
17083
  separator: true,
17296
17084
  people: {
17297
17085
  name: "People",
17298
- icon: /* @__PURE__ */ jsx7(
17086
+ icon: /* @__PURE__ */ jsx6(
17299
17087
  "svg",
17300
17088
  {
17301
17089
  "aria-hidden": "true",
@@ -17305,7 +17093,7 @@ function EmojiSelector({
17305
17093
  height: "24",
17306
17094
  fill: "none",
17307
17095
  viewBox: "0 0 24 24",
17308
- children: /* @__PURE__ */ jsx7(
17096
+ children: /* @__PURE__ */ jsx6(
17309
17097
  "path",
17310
17098
  {
17311
17099
  fill: "currentColor",
@@ -17320,7 +17108,7 @@ function EmojiSelector({
17320
17108
  },
17321
17109
  nature: {
17322
17110
  name: "Nature",
17323
- icon: /* @__PURE__ */ jsx7(
17111
+ icon: /* @__PURE__ */ jsx6(
17324
17112
  "svg",
17325
17113
  {
17326
17114
  "aria-hidden": "true",
@@ -17330,7 +17118,7 @@ function EmojiSelector({
17330
17118
  height: "24",
17331
17119
  fill: "none",
17332
17120
  viewBox: "0 0 24 24",
17333
- children: /* @__PURE__ */ jsx7(
17121
+ children: /* @__PURE__ */ jsx6(
17334
17122
  "path",
17335
17123
  {
17336
17124
  fill: "currentColor",
@@ -17343,7 +17131,7 @@ function EmojiSelector({
17343
17131
  },
17344
17132
  food: {
17345
17133
  name: "Food",
17346
- icon: /* @__PURE__ */ jsx7(
17134
+ icon: /* @__PURE__ */ jsx6(
17347
17135
  "svg",
17348
17136
  {
17349
17137
  "aria-hidden": "true",
@@ -17353,7 +17141,7 @@ function EmojiSelector({
17353
17141
  height: "24",
17354
17142
  fill: "none",
17355
17143
  viewBox: "0 0 24 24",
17356
- children: /* @__PURE__ */ jsx7(
17144
+ children: /* @__PURE__ */ jsx6(
17357
17145
  "path",
17358
17146
  {
17359
17147
  fill: "currentColor",
@@ -17366,7 +17154,7 @@ function EmojiSelector({
17366
17154
  },
17367
17155
  activities: {
17368
17156
  name: "Activities",
17369
- icon: /* @__PURE__ */ jsx7(
17157
+ icon: /* @__PURE__ */ jsx6(
17370
17158
  "svg",
17371
17159
  {
17372
17160
  "aria-hidden": "true",
@@ -17376,7 +17164,7 @@ function EmojiSelector({
17376
17164
  height: "24",
17377
17165
  fill: "none",
17378
17166
  viewBox: "0 0 24 24",
17379
- children: /* @__PURE__ */ jsx7(
17167
+ children: /* @__PURE__ */ jsx6(
17380
17168
  "path",
17381
17169
  {
17382
17170
  fill: "currentColor",
@@ -17391,7 +17179,7 @@ function EmojiSelector({
17391
17179
  },
17392
17180
  travel: {
17393
17181
  name: "Travel",
17394
- icon: /* @__PURE__ */ jsx7(
17182
+ icon: /* @__PURE__ */ jsx6(
17395
17183
  "svg",
17396
17184
  {
17397
17185
  "aria-hidden": "true",
@@ -17401,7 +17189,7 @@ function EmojiSelector({
17401
17189
  height: "24",
17402
17190
  fill: "none",
17403
17191
  viewBox: "0 0 24 24",
17404
- children: /* @__PURE__ */ jsx7(
17192
+ children: /* @__PURE__ */ jsx6(
17405
17193
  "path",
17406
17194
  {
17407
17195
  fill: "currentColor",
@@ -17416,7 +17204,7 @@ function EmojiSelector({
17416
17204
  },
17417
17205
  objects: {
17418
17206
  name: "Objects",
17419
- icon: /* @__PURE__ */ jsxs6(
17207
+ icon: /* @__PURE__ */ jsxs5(
17420
17208
  "svg",
17421
17209
  {
17422
17210
  "aria-hidden": "true",
@@ -17427,14 +17215,14 @@ function EmojiSelector({
17427
17215
  fill: "none",
17428
17216
  viewBox: "0 0 24 24",
17429
17217
  children: [
17430
- /* @__PURE__ */ jsx7(
17218
+ /* @__PURE__ */ jsx6(
17431
17219
  "path",
17432
17220
  {
17433
17221
  fill: "currentColor",
17434
17222
  d: "M10.41 3.59 11.6 2.4a2 2 0 0 1 2.82 0l1.3 1.3a1 1 0 0 0 .7.29h4.18a1.41 1.41 0 0 1 1 2.41L14.4 13.6a1.41 1.41 0 0 1-2.41-1V8.4l-3.11 3.12a2 2 0 0 0-.53 1.87L9.9 20H15a1 1 0 1 1 0 2H3a1 1 0 1 1 0-2h4.86L6.4 13.86a4 4 0 0 1 1.06-3.75L10.8 6.8l-.38-.38a2 2 0 0 1 0-2.82Z"
17435
17223
  }
17436
17224
  ),
17437
- /* @__PURE__ */ jsx7(
17225
+ /* @__PURE__ */ jsx6(
17438
17226
  "path",
17439
17227
  {
17440
17228
  fill: "currentColor",
@@ -17448,7 +17236,7 @@ function EmojiSelector({
17448
17236
  },
17449
17237
  symbols: {
17450
17238
  name: "Symbols",
17451
- icon: /* @__PURE__ */ jsx7(
17239
+ icon: /* @__PURE__ */ jsx6(
17452
17240
  "svg",
17453
17241
  {
17454
17242
  "aria-hidden": "true",
@@ -17458,7 +17246,7 @@ function EmojiSelector({
17458
17246
  height: "24",
17459
17247
  fill: "none",
17460
17248
  viewBox: "0 0 24 24",
17461
- children: /* @__PURE__ */ jsx7(
17249
+ children: /* @__PURE__ */ jsx6(
17462
17250
  "path",
17463
17251
  {
17464
17252
  fill: "currentColor",
@@ -17471,7 +17259,7 @@ function EmojiSelector({
17471
17259
  },
17472
17260
  flags: {
17473
17261
  name: "Flags",
17474
- icon: /* @__PURE__ */ jsx7(
17262
+ icon: /* @__PURE__ */ jsx6(
17475
17263
  "svg",
17476
17264
  {
17477
17265
  "aria-hidden": "true",
@@ -17481,7 +17269,7 @@ function EmojiSelector({
17481
17269
  height: "24",
17482
17270
  fill: "none",
17483
17271
  viewBox: "0 0 24 24",
17484
- children: /* @__PURE__ */ jsx7(
17272
+ children: /* @__PURE__ */ jsx6(
17485
17273
  "path",
17486
17274
  {
17487
17275
  fill: "currentColor",
@@ -17493,34 +17281,32 @@ function EmojiSelector({
17493
17281
  ...categories.flags
17494
17282
  }
17495
17283
  };
17496
- const emojis = [
17497
- recentlyUsed.length > 0 ? {
17498
- name: "recentlyUsed",
17499
- emojis: recentlyUsed
17500
- } : void 0,
17501
- (customEmojis?.emojis || []).length > 0 ? {
17502
- name: "customServerIcons",
17503
- emojis: customEmojis.emojis.map((a) => {
17504
- return { name: a.split(":")[1].split(":")[0], char: a };
17505
- })
17506
- } : void 0,
17507
- ...emojilib_default
17508
- ].filter((a) => a !== void 0);
17284
+ const emojis = useMemo2(() => {
17285
+ return [
17286
+ recentlyUsed.length > 0 ? {
17287
+ name: "recentlyUsed",
17288
+ emojis: recentlyUsed
17289
+ } : void 0,
17290
+ (customEmojis?.emojis || []).length > 0 ? {
17291
+ name: "customServerIcons",
17292
+ emojis: customEmojis.emojis.map((a) => {
17293
+ return { name: a.split(":")[1].split(":")[0], char: a };
17294
+ })
17295
+ } : void 0,
17296
+ ...emojilib_default
17297
+ ].filter((a) => a !== void 0);
17298
+ }, [recentlyUsed, customEmojis]);
17509
17299
  const navHeight = showNav ? Math.floor(height / 7) : 0;
17510
- const id = useMemo2(
17511
- () => Math.random().toString(36).substring(2, 15),
17512
- []
17513
- );
17300
+ const id = useMemo2(() => Math.random().toString(36).substring(2, 15), []);
17514
17301
  const picker = useRef2(null);
17515
17302
  const scrollRef = useRef2(null);
17516
- const [focusIndex, setFocusIndex] = useState7(-1);
17517
17303
  const handleWheel = useCallback2((e) => {
17518
17304
  const el = scrollRef.current;
17519
17305
  if (!el) return;
17520
17306
  e.preventDefault();
17521
17307
  el.scrollTop += e.deltaY;
17522
17308
  }, []);
17523
- useEffect7(() => {
17309
+ useEffect5(() => {
17524
17310
  const el = scrollRef.current;
17525
17311
  if (!el) return;
17526
17312
  el.addEventListener("wheel", handleWheel, { passive: false });
@@ -17528,35 +17314,7 @@ function EmojiSelector({
17528
17314
  el.removeEventListener("wheel", handleWheel);
17529
17315
  };
17530
17316
  }, [handleWheel]);
17531
- const handleKeyDown = useCallback2(
17532
- (e) => {
17533
- const el = scrollRef.current;
17534
- if (!el) return;
17535
- const emojiElements = el.querySelectorAll(
17536
- ".HOKKIEMOJIPICKER-emoji, .HOKKIEMOJIPICKER-skinemoji"
17537
- );
17538
- const count = emojiElements.length;
17539
- if (count === 0) return;
17540
- if (e.key === "Tab") {
17541
- e.preventDefault();
17542
- let next = focusIndex + (e.shiftKey ? -1 : 1);
17543
- if (next < 0) next = count - 1;
17544
- if (next >= count) next = 0;
17545
- setFocusIndex(next);
17546
- const target = emojiElements[next];
17547
- if (target) {
17548
- target.scrollIntoView({ block: "nearest" });
17549
- target.focus();
17550
- }
17551
- } else if (e.key === "Enter" && focusIndex >= 0) {
17552
- e.preventDefault();
17553
- const target = emojiElements[focusIndex];
17554
- if (target) target.click();
17555
- }
17556
- },
17557
- [focusIndex]
17558
- );
17559
- return /* @__PURE__ */ jsx7("div", { className: "HOKKIEMOJIPICKER-emojiContainer", children: /* @__PURE__ */ jsxs6(
17317
+ return /* @__PURE__ */ jsx6("div", { className: "HOKKIEMOJIPICKER-emojiContainer", children: /* @__PURE__ */ jsxs5(
17560
17318
  "div",
17561
17319
  {
17562
17320
  ref: picker,
@@ -17574,30 +17332,30 @@ function EmojiSelector({
17574
17332
  minWidth: width
17575
17333
  },
17576
17334
  children: [
17577
- showNav && /* @__PURE__ */ jsxs6(
17335
+ showNav && /* @__PURE__ */ jsxs5(
17578
17336
  "div",
17579
17337
  {
17580
- className: "HOKKIEMOJIPICKER-nav border-[#363639] flex items-center gap-4 border-b-1 p-3 relative z-50",
17338
+ className: "HOKKIEMOJIPICKER-nav flex items-center gap-4 p-3 relative z-50",
17581
17339
  style: {
17582
17340
  height: navHeight,
17583
17341
  maxHeight: navHeight,
17584
17342
  minHeight: navHeight
17585
17343
  },
17586
17344
  children: [
17587
- /* @__PURE__ */ jsx7(SearchBar, { id, searchPlaceholder }),
17588
- toneSelector && /* @__PURE__ */ jsx7(SkinSelector, { id })
17345
+ /* @__PURE__ */ jsx6(SearchBar, { id, searchPlaceholder }),
17346
+ toneSelector && /* @__PURE__ */ jsx6(SkinSelector, { id })
17589
17347
  ]
17590
17348
  }
17591
17349
  ),
17592
- /* @__PURE__ */ jsxs6("div", { className: "flex h-full", children: [
17593
- showSidebar && /* @__PURE__ */ jsxs6("div", { className: "HOKKIEMOJIPICKER-sidebar bg-[#070709] flex p-2 gap-1 flex-col", children: [
17350
+ /* @__PURE__ */ jsxs5("div", { className: "flex h-full", children: [
17351
+ showSidebar && /* @__PURE__ */ jsxs5("div", { className: "HOKKIEMOJIPICKER-sidebar rounded-t-md bg-[#070709] flex p-2 gap-1 flex-col", children: [
17594
17352
  Object.keys(categoryData).filter((categoryName) => categoryData[categoryName] !== false).map((categoryName) => {
17595
17353
  const category = categoryData[categoryName];
17596
17354
  if (category === true) {
17597
- return /* @__PURE__ */ jsx7("div", { className: "w-full h-0 border-b-1 my-2" });
17355
+ return /* @__PURE__ */ jsx6("div", { className: "w-full h-0 border-b-1 my-2" });
17598
17356
  }
17599
17357
  const icon = category.icon;
17600
- return /* @__PURE__ */ jsx7(
17358
+ return /* @__PURE__ */ jsx6(
17601
17359
  SidebarCategory,
17602
17360
  {
17603
17361
  id,
@@ -17608,9 +17366,9 @@ function EmojiSelector({
17608
17366
  categoryName
17609
17367
  );
17610
17368
  }),
17611
- /* @__PURE__ */ jsx7("div", { className: "h-24" })
17369
+ /* @__PURE__ */ jsx6("div", { className: "h-24" })
17612
17370
  ] }),
17613
- /* @__PURE__ */ jsxs6(
17371
+ /* @__PURE__ */ jsxs5(
17614
17372
  "div",
17615
17373
  {
17616
17374
  style: {
@@ -17620,51 +17378,60 @@ function EmojiSelector({
17620
17378
  },
17621
17379
  className: "HOKKIEMOJIPICKER-emojidisplaycontainer overflow-hidden flex flex-col w-full",
17622
17380
  children: [
17623
- /* @__PURE__ */ jsx7(
17381
+ /* @__PURE__ */ jsx6(
17624
17382
  "div",
17625
17383
  {
17626
17384
  ref: scrollRef,
17627
- tabIndex: 0,
17628
- onKeyDown: handleKeyDown,
17629
17385
  style: {
17630
17386
  flexBasis: "fit-content"
17631
17387
  },
17632
17388
  className: "HOKKIEMOJIPICKER-emojidisplay overflow-y-scroll bg-[#131416] h-full w-full flex flex-wrap px-2 items-start justfy-start justify-self-start gap-y-0.5",
17633
- children: emojis.map((category) => {
17634
- if (!category) return;
17635
- const categoryInfo = categoryData[category.name];
17636
- return /* @__PURE__ */ jsx7(
17637
- categoryDisplay_default,
17638
- {
17639
- onEmojiMouseEnter,
17640
- onEmojiMouseLeave,
17641
- isToneSelectorEnabled: toneSelector,
17642
- onEmojiSelect: (a) => {
17643
- onEmojiSelect(a);
17644
- if (a.char.startsWith("<")) return;
17645
- let newRecentlyUsed = JSON.parse(
17646
- localStorage.getItem("hokkiemojipicker-recentlyused") || "[]"
17647
- );
17648
- newRecentlyUsed = newRecentlyUsed.filter(
17649
- (b) => b.char !== a.char
17650
- );
17651
- newRecentlyUsed.push(a);
17652
- newRecentlyUsed = newRecentlyUsed.slice(0, 20);
17653
- localStorage.setItem(
17654
- "hokkiemojipicker-recentlyused",
17655
- JSON.stringify(newRecentlyUsed)
17656
- );
17657
- },
17658
- category,
17659
- pickerId: id,
17660
- categoryInfo
17661
- },
17662
- category.name
17663
- );
17664
- })
17389
+ children: /* @__PURE__ */ jsx6(
17390
+ Suspense,
17391
+ {
17392
+ fallback: /* @__PURE__ */ jsx6("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsxs5("div", { className: "flex flex-col items-center gap-3", children: [
17393
+ /* @__PURE__ */ jsx6("div", { className: "animate-spin size-8 border-2 border-white/20 border-t-white/80 rounded-full" }),
17394
+ /* @__PURE__ */ jsx6("span", { className: "text-white/60 text-sm", children: "Loading emojis..." })
17395
+ ] }) }),
17396
+ children: emojis.map((category) => {
17397
+ if (!category) return;
17398
+ const categoryInfo = categoryData[category.name];
17399
+ return /* @__PURE__ */ jsx6(
17400
+ CategoryDisplay,
17401
+ {
17402
+ onEmojiMouseEnter,
17403
+ onEmojiMouseLeave,
17404
+ isToneSelectorEnabled: toneSelector,
17405
+ onEmojiSelect: (a) => {
17406
+ onEmojiSelect(a);
17407
+ if (a.char.startsWith("<")) return;
17408
+ let newRecentlyUsed = JSON.parse(
17409
+ localStorage.getItem(
17410
+ "hokkiemojipicker-recentlyused"
17411
+ ) || "[]"
17412
+ );
17413
+ newRecentlyUsed = newRecentlyUsed.filter(
17414
+ (b) => b.char !== a.char
17415
+ );
17416
+ newRecentlyUsed.push(a);
17417
+ newRecentlyUsed = newRecentlyUsed.slice(0, 20);
17418
+ localStorage.setItem(
17419
+ "hokkiemojipicker-recentlyused",
17420
+ JSON.stringify(newRecentlyUsed)
17421
+ );
17422
+ },
17423
+ category,
17424
+ pickerId: id,
17425
+ categoryInfo
17426
+ },
17427
+ category.name
17428
+ );
17429
+ })
17430
+ }
17431
+ )
17665
17432
  }
17666
17433
  ),
17667
- showFooter && /* @__PURE__ */ jsx7(Footer, { id, firstEmoji: emojis[0].emojis[0] })
17434
+ showFooter && /* @__PURE__ */ jsx6(Footer, { id, firstEmoji: emojis[0].emojis[0] })
17668
17435
  ]
17669
17436
  }
17670
17437
  )