@choice-ui/react 1.7.8 → 1.8.1
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/components/emoji-picker/src/components/emoji-empty.d.ts +4 -0
- package/dist/components/emoji-picker/src/components/emoji-empty.js +9 -3
- package/dist/components/emoji-picker/src/components/emoji-footer.d.ts +4 -1
- package/dist/components/emoji-picker/src/components/emoji-footer.js +11 -3
- package/dist/components/emoji-picker/src/emoji-picker.d.ts +16 -0
- package/dist/components/emoji-picker/src/emoji-picker.js +59 -19
- package/dist/components/emoji-picker/src/hooks/index.d.ts +1 -1
- package/dist/components/emoji-picker/src/hooks/use-emoji-data.d.ts +13 -10
- package/dist/components/emoji-picker/src/hooks/use-emoji-data.js +41 -13
- package/dist/components/emoji-picker/src/hooks/use-emoji-scroll.js +24 -3
- package/dist/components/emoji-picker/src/tv.js +1 -1
- package/dist/components/icon-button/src/tv.js +11 -1
- package/dist/components/tooltip/src/components/tooltip-content.js +20 -4
- package/dist/components/tooltip/src/tooltip.js +3 -1
- package/dist/components/tooltip/src/types.d.ts +3 -0
- package/package.json +1 -1
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { memo } from "react";
|
|
3
3
|
import { emojiEmptyTv } from "../tv.js";
|
|
4
|
-
const EmojiEmpty = memo(function EmojiEmpty2({
|
|
4
|
+
const EmojiEmpty = memo(function EmojiEmpty2({
|
|
5
|
+
variant = "dark",
|
|
6
|
+
i18n = {
|
|
7
|
+
title: "No emoji found",
|
|
8
|
+
description: "You can search for an emoji by name or use the search bar to find it."
|
|
9
|
+
}
|
|
10
|
+
}) {
|
|
5
11
|
const tv = emojiEmptyTv({ variant });
|
|
6
12
|
return /* @__PURE__ */ jsxs("div", { className: tv.container(), children: [
|
|
7
|
-
/* @__PURE__ */ jsx("div", { className: tv.title(), children:
|
|
8
|
-
/* @__PURE__ */ jsx("p", { className: tv.description(), children:
|
|
13
|
+
/* @__PURE__ */ jsx("div", { className: tv.title(), children: i18n.title }),
|
|
14
|
+
/* @__PURE__ */ jsx("p", { className: tv.description(), children: i18n.description })
|
|
9
15
|
] });
|
|
10
16
|
});
|
|
11
17
|
export {
|
|
@@ -3,6 +3,9 @@ interface EmojiFooterProps {
|
|
|
3
3
|
hoveredEmoji: EmojiData | null;
|
|
4
4
|
selectedEmoji: EmojiData | null;
|
|
5
5
|
variant?: "default" | "dark" | "light";
|
|
6
|
+
i18n?: {
|
|
7
|
+
pickAnEmoji?: string;
|
|
8
|
+
};
|
|
6
9
|
}
|
|
7
|
-
export declare
|
|
10
|
+
export declare const EmojiFooter: import('react').NamedExoticComponent<EmojiFooterProps>;
|
|
8
11
|
export {};
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from "react";
|
|
2
3
|
import { emojiFooterTv } from "../tv.js";
|
|
3
|
-
|
|
4
|
+
const EmojiFooter = memo(function EmojiFooter2({
|
|
5
|
+
hoveredEmoji,
|
|
6
|
+
selectedEmoji,
|
|
7
|
+
variant = "dark",
|
|
8
|
+
i18n = {
|
|
9
|
+
pickAnEmoji: "Pick an emoji..."
|
|
10
|
+
}
|
|
11
|
+
}) {
|
|
4
12
|
var _a, _b;
|
|
5
13
|
const tv = emojiFooterTv({ variant });
|
|
6
14
|
return /* @__PURE__ */ jsxs("div", { className: tv.footer(), children: [
|
|
7
15
|
/* @__PURE__ */ jsx("div", { className: tv.emojiPreview(), children: ((_a = hoveredEmoji || selectedEmoji) == null ? void 0 : _a.emoji) || /* @__PURE__ */ jsx("div", { className: tv.emojiPreviewEmpty() }) }),
|
|
8
16
|
/* @__PURE__ */ jsxs("div", { className: tv.emojiInfo(), children: [
|
|
9
|
-
/* @__PURE__ */ jsx("div", { className: tv.emojiName(), children: (hoveredEmoji == null ? void 0 : hoveredEmoji.name) || (selectedEmoji == null ? void 0 : selectedEmoji.name) ||
|
|
17
|
+
/* @__PURE__ */ jsx("div", { className: tv.emojiName(), children: (hoveredEmoji == null ? void 0 : hoveredEmoji.name) || (selectedEmoji == null ? void 0 : selectedEmoji.name) || i18n.pickAnEmoji }),
|
|
10
18
|
hoveredEmoji || selectedEmoji ? /* @__PURE__ */ jsxs("div", { className: tv.emojiCode(), children: [
|
|
11
19
|
":",
|
|
12
20
|
(_b = hoveredEmoji || selectedEmoji) == null ? void 0 : _b.nameUrl,
|
|
@@ -14,7 +22,7 @@ function EmojiFooter({ hoveredEmoji, selectedEmoji, variant = "dark" }) {
|
|
|
14
22
|
] }) : /* @__PURE__ */ jsx(Fragment, {})
|
|
15
23
|
] })
|
|
16
24
|
] });
|
|
17
|
-
}
|
|
25
|
+
});
|
|
18
26
|
export {
|
|
19
27
|
EmojiFooter
|
|
20
28
|
};
|
|
@@ -13,6 +13,22 @@ export interface EmojiPickerProps {
|
|
|
13
13
|
showFooter?: boolean;
|
|
14
14
|
value?: EmojiData | null;
|
|
15
15
|
variant?: "default" | "dark" | "light";
|
|
16
|
+
i18n?: {
|
|
17
|
+
noEmojisFoundTitle?: string;
|
|
18
|
+
noEmojisFoundDescription?: string;
|
|
19
|
+
footerPickAnEmoji?: string;
|
|
20
|
+
categories?: {
|
|
21
|
+
frequentlyUsed: string;
|
|
22
|
+
smileysPeople: string;
|
|
23
|
+
animalsNature: string;
|
|
24
|
+
foodDrink: string;
|
|
25
|
+
travelPlaces: string;
|
|
26
|
+
activities: string;
|
|
27
|
+
objects: string;
|
|
28
|
+
symbols: string;
|
|
29
|
+
flags: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
16
32
|
}
|
|
17
33
|
export declare const EmojiPicker: React.NamedExoticComponent<EmojiPickerProps>;
|
|
18
34
|
export default EmojiPicker;
|
|
@@ -12,17 +12,6 @@ import { EmojiCategoryHeader } from "./components/emoji-category-header.js";
|
|
|
12
12
|
import { EmojiItem } from "./components/emoji-item.js";
|
|
13
13
|
import { EmojiEmpty } from "./components/emoji-empty.js";
|
|
14
14
|
import { EmojiFooter } from "./components/emoji-footer.js";
|
|
15
|
-
const categoriesWithIcons = [
|
|
16
|
-
{ id: "frequently_used", name: "Frequently used", icon: /* @__PURE__ */ jsx(EmojiFrequentlyUsed, {}) },
|
|
17
|
-
{ id: "smileys_people", name: "Smileys & People", icon: /* @__PURE__ */ jsx(EmojiSmileysPeople, {}) },
|
|
18
|
-
{ id: "animals_nature", name: "Animals & Nature", icon: /* @__PURE__ */ jsx(EmojiAnimalsNature, {}) },
|
|
19
|
-
{ id: "food_drink", name: "Food & Drink", icon: /* @__PURE__ */ jsx(EmojiFoodDrink, {}) },
|
|
20
|
-
{ id: "travel_places", name: "Travel & Places", icon: /* @__PURE__ */ jsx(EmojiTravelPlaces, {}) },
|
|
21
|
-
{ id: "activities", name: "Activities", icon: /* @__PURE__ */ jsx(EmojiActivity, {}) },
|
|
22
|
-
{ id: "objects", name: "Objects", icon: /* @__PURE__ */ jsx(EmojiObjects, {}) },
|
|
23
|
-
{ id: "symbols", name: "Symbols", icon: /* @__PURE__ */ jsx(EmojiSymbols, {}) },
|
|
24
|
-
{ id: "flags", name: "Flags", icon: /* @__PURE__ */ jsx(EmojiFlags, {}) }
|
|
25
|
-
];
|
|
26
15
|
const EmojiPicker = memo(function EmojiPicker2({
|
|
27
16
|
value,
|
|
28
17
|
onChange,
|
|
@@ -35,11 +24,49 @@ const EmojiPicker = memo(function EmojiPicker2({
|
|
|
35
24
|
showSearch = true,
|
|
36
25
|
showFooter = true,
|
|
37
26
|
children,
|
|
38
|
-
variant = "dark"
|
|
27
|
+
variant = "dark",
|
|
28
|
+
i18n = {
|
|
29
|
+
noEmojisFoundTitle: "No emoji found",
|
|
30
|
+
noEmojisFoundDescription: "You can search for an emoji by name or use the search bar to find it.",
|
|
31
|
+
footerPickAnEmoji: "Pick an emoji...",
|
|
32
|
+
categories: {
|
|
33
|
+
frequentlyUsed: "Frequently used",
|
|
34
|
+
smileysPeople: "Smileys & People",
|
|
35
|
+
animalsNature: "Animals & Nature",
|
|
36
|
+
foodDrink: "Food & Drink",
|
|
37
|
+
travelPlaces: "Travel & Places",
|
|
38
|
+
activities: "Activities",
|
|
39
|
+
objects: "Objects",
|
|
40
|
+
symbols: "Symbols",
|
|
41
|
+
flags: "Flags"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
39
44
|
}) {
|
|
40
45
|
const [searchQuery, setSearchQuery] = useState("");
|
|
41
46
|
const [hoveredEmoji, setHoveredEmoji] = useState(null);
|
|
47
|
+
const safeColumns = Math.max(1, columns);
|
|
42
48
|
const tv = emojiTv({ variant });
|
|
49
|
+
const categoriesWithIcons = useMemo(
|
|
50
|
+
() => {
|
|
51
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
id: "frequently_used",
|
|
55
|
+
name: (_a = i18n.categories) == null ? void 0 : _a.frequentlyUsed,
|
|
56
|
+
icon: /* @__PURE__ */ jsx(EmojiFrequentlyUsed, {})
|
|
57
|
+
},
|
|
58
|
+
{ id: "smileys_people", name: (_b = i18n.categories) == null ? void 0 : _b.smileysPeople, icon: /* @__PURE__ */ jsx(EmojiSmileysPeople, {}) },
|
|
59
|
+
{ id: "animals_nature", name: (_c = i18n.categories) == null ? void 0 : _c.animalsNature, icon: /* @__PURE__ */ jsx(EmojiAnimalsNature, {}) },
|
|
60
|
+
{ id: "food_drink", name: (_d = i18n.categories) == null ? void 0 : _d.foodDrink, icon: /* @__PURE__ */ jsx(EmojiFoodDrink, {}) },
|
|
61
|
+
{ id: "travel_places", name: (_e = i18n.categories) == null ? void 0 : _e.travelPlaces, icon: /* @__PURE__ */ jsx(EmojiTravelPlaces, {}) },
|
|
62
|
+
{ id: "activities", name: (_f = i18n.categories) == null ? void 0 : _f.activities, icon: /* @__PURE__ */ jsx(EmojiActivity, {}) },
|
|
63
|
+
{ id: "objects", name: (_g = i18n.categories) == null ? void 0 : _g.objects, icon: /* @__PURE__ */ jsx(EmojiObjects, {}) },
|
|
64
|
+
{ id: "symbols", name: (_h = i18n.categories) == null ? void 0 : _h.symbols, icon: /* @__PURE__ */ jsx(EmojiSymbols, {}) },
|
|
65
|
+
{ id: "flags", name: (_i = i18n.categories) == null ? void 0 : _i.flags, icon: /* @__PURE__ */ jsx(EmojiFlags, {}) }
|
|
66
|
+
];
|
|
67
|
+
},
|
|
68
|
+
[i18n.categories]
|
|
69
|
+
);
|
|
43
70
|
const {
|
|
44
71
|
categorizedData,
|
|
45
72
|
categoryIndexMap,
|
|
@@ -48,8 +75,9 @@ const EmojiPicker = memo(function EmojiPicker2({
|
|
|
48
75
|
findEmojiByChar
|
|
49
76
|
} = useEmojiData({
|
|
50
77
|
searchQuery,
|
|
51
|
-
columns,
|
|
52
|
-
showFrequentlyUsed
|
|
78
|
+
columns: safeColumns,
|
|
79
|
+
showFrequentlyUsed,
|
|
80
|
+
categoryNames: i18n.categories
|
|
53
81
|
});
|
|
54
82
|
const {
|
|
55
83
|
scrollRef,
|
|
@@ -65,7 +93,7 @@ const EmojiPicker = memo(function EmojiPicker2({
|
|
|
65
93
|
findEmojiPosition,
|
|
66
94
|
searchQuery,
|
|
67
95
|
value,
|
|
68
|
-
columns
|
|
96
|
+
columns: safeColumns
|
|
69
97
|
});
|
|
70
98
|
const availableCategories = useMemo(() => {
|
|
71
99
|
return categoriesWithIcons.filter((category) => {
|
|
@@ -74,7 +102,7 @@ const EmojiPicker = memo(function EmojiPicker2({
|
|
|
74
102
|
}
|
|
75
103
|
return true;
|
|
76
104
|
});
|
|
77
|
-
}, [showFrequentlyUsed]);
|
|
105
|
+
}, [categoriesWithIcons, showFrequentlyUsed]);
|
|
78
106
|
const handleEmojiSelect = useEventCallback((emoji) => {
|
|
79
107
|
markInternalUpdate();
|
|
80
108
|
addToFrequentlyUsed(emoji.id);
|
|
@@ -90,7 +118,7 @@ const EmojiPicker = memo(function EmojiPicker2({
|
|
|
90
118
|
const rootStyle = {
|
|
91
119
|
"--emoji-height": `${height}px`,
|
|
92
120
|
"--emoji-padding": `${PADDING}px`,
|
|
93
|
-
"--emoji-columns": `${
|
|
121
|
+
"--emoji-columns": `${safeColumns}`
|
|
94
122
|
};
|
|
95
123
|
return /* @__PURE__ */ jsxs(
|
|
96
124
|
"div",
|
|
@@ -193,7 +221,16 @@ const EmojiPicker = memo(function EmojiPicker2({
|
|
|
193
221
|
},
|
|
194
222
|
virtualItem.key
|
|
195
223
|
);
|
|
196
|
-
}) : /* @__PURE__ */ jsx(
|
|
224
|
+
}) : /* @__PURE__ */ jsx(
|
|
225
|
+
EmojiEmpty,
|
|
226
|
+
{
|
|
227
|
+
variant,
|
|
228
|
+
i18n: {
|
|
229
|
+
title: i18n.noEmojisFoundTitle,
|
|
230
|
+
description: i18n.noEmojisFoundDescription
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
)
|
|
197
234
|
}
|
|
198
235
|
)
|
|
199
236
|
}
|
|
@@ -205,7 +242,10 @@ const EmojiPicker = memo(function EmojiPicker2({
|
|
|
205
242
|
{
|
|
206
243
|
hoveredEmoji,
|
|
207
244
|
selectedEmoji: value || null,
|
|
208
|
-
variant
|
|
245
|
+
variant,
|
|
246
|
+
i18n: {
|
|
247
|
+
pickAnEmoji: i18n.footerPickAnEmoji
|
|
248
|
+
}
|
|
209
249
|
}
|
|
210
250
|
),
|
|
211
251
|
children
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { useEmojiData } from './use-emoji-data';
|
|
2
2
|
export { useEmojiScroll } from './use-emoji-scroll';
|
|
3
|
-
export type { EmojiData, EmojiCategory, VirtualItem } from './use-emoji-data';
|
|
3
|
+
export type { EmojiData, EmojiCategory, VirtualItem, CategoryNames } from './use-emoji-data';
|
|
@@ -16,47 +16,50 @@ export type VirtualItem = {
|
|
|
16
16
|
};
|
|
17
17
|
export declare const categories: readonly [{
|
|
18
18
|
readonly id: "frequently_used";
|
|
19
|
-
readonly name: "Frequently used";
|
|
20
19
|
}, {
|
|
21
20
|
readonly id: "smileys_people";
|
|
22
|
-
readonly name: "Smileys & People";
|
|
23
21
|
readonly range: readonly [1, 460];
|
|
24
22
|
}, {
|
|
25
23
|
readonly id: "animals_nature";
|
|
26
|
-
readonly name: "Animals & Nature";
|
|
27
24
|
readonly range: readonly [465, 591];
|
|
28
25
|
}, {
|
|
29
26
|
readonly id: "food_drink";
|
|
30
|
-
readonly name: "Food & Drink";
|
|
31
27
|
readonly range: readonly [592, 712];
|
|
32
28
|
}, {
|
|
33
29
|
readonly id: "travel_places";
|
|
34
|
-
readonly name: "Travel & Places";
|
|
35
30
|
readonly range: readonly [713, 922];
|
|
36
31
|
}, {
|
|
37
32
|
readonly id: "activities";
|
|
38
|
-
readonly name: "Activities";
|
|
39
33
|
readonly range: readonly [923, 1001];
|
|
40
34
|
}, {
|
|
41
35
|
readonly id: "objects";
|
|
42
|
-
readonly name: "Objects";
|
|
43
36
|
readonly range: readonly [1002, 1234];
|
|
44
37
|
}, {
|
|
45
38
|
readonly id: "symbols";
|
|
46
|
-
readonly name: "Symbols";
|
|
47
39
|
readonly range: readonly [1235, 1451];
|
|
48
40
|
}, {
|
|
49
41
|
readonly id: "flags";
|
|
50
|
-
readonly name: "Flags";
|
|
51
42
|
readonly range: readonly [1452, 1719];
|
|
52
43
|
}];
|
|
53
44
|
export declare function getEmojiCategory(id: number): EmojiCategory;
|
|
45
|
+
export interface CategoryNames {
|
|
46
|
+
activities: string;
|
|
47
|
+
animalsNature: string;
|
|
48
|
+
flags: string;
|
|
49
|
+
foodDrink: string;
|
|
50
|
+
frequentlyUsed: string;
|
|
51
|
+
objects: string;
|
|
52
|
+
smileysPeople: string;
|
|
53
|
+
symbols: string;
|
|
54
|
+
travelPlaces: string;
|
|
55
|
+
}
|
|
54
56
|
interface UseEmojiDataProps {
|
|
57
|
+
categoryNames?: CategoryNames;
|
|
55
58
|
columns: number;
|
|
56
59
|
searchQuery: string;
|
|
57
60
|
showFrequentlyUsed: boolean;
|
|
58
61
|
}
|
|
59
|
-
export declare function useEmojiData({ searchQuery, columns, showFrequentlyUsed }: UseEmojiDataProps): {
|
|
62
|
+
export declare function useEmojiData({ searchQuery, columns, showFrequentlyUsed, categoryNames, }: UseEmojiDataProps): {
|
|
60
63
|
categorizedData: VirtualItem[];
|
|
61
64
|
categoryIndexMap: Map<EmojiCategory, number>;
|
|
62
65
|
searchResults: {
|
|
@@ -2,15 +2,15 @@ import { useState, useEffect, useMemo } from "react";
|
|
|
2
2
|
import { emojis } from "../utils/emoji-data.js";
|
|
3
3
|
import { isBrowser } from "../../../../shared/utils/ssr.js";
|
|
4
4
|
const categories = [
|
|
5
|
-
{ id: "frequently_used"
|
|
6
|
-
{ id: "smileys_people",
|
|
7
|
-
{ id: "animals_nature",
|
|
8
|
-
{ id: "food_drink",
|
|
9
|
-
{ id: "travel_places",
|
|
10
|
-
{ id: "activities",
|
|
11
|
-
{ id: "objects",
|
|
12
|
-
{ id: "symbols",
|
|
13
|
-
{ id: "flags",
|
|
5
|
+
{ id: "frequently_used" },
|
|
6
|
+
{ id: "smileys_people", range: [1, 460] },
|
|
7
|
+
{ id: "animals_nature", range: [465, 591] },
|
|
8
|
+
{ id: "food_drink", range: [592, 712] },
|
|
9
|
+
{ id: "travel_places", range: [713, 922] },
|
|
10
|
+
{ id: "activities", range: [923, 1001] },
|
|
11
|
+
{ id: "objects", range: [1002, 1234] },
|
|
12
|
+
{ id: "symbols", range: [1235, 1451] },
|
|
13
|
+
{ id: "flags", range: [1452, 1719] }
|
|
14
14
|
];
|
|
15
15
|
const STORAGE_KEY = "emoji-picker-frequently-used";
|
|
16
16
|
function getEmojiCategory(id) {
|
|
@@ -44,7 +44,34 @@ function saveFrequentlyUsedEmoji(emojiId) {
|
|
|
44
44
|
} catch {
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
const defaultCategoryNames = {
|
|
48
|
+
frequentlyUsed: "Frequently used",
|
|
49
|
+
smileysPeople: "Smileys & People",
|
|
50
|
+
animalsNature: "Animals & Nature",
|
|
51
|
+
foodDrink: "Food & Drink",
|
|
52
|
+
travelPlaces: "Travel & Places",
|
|
53
|
+
activities: "Activities",
|
|
54
|
+
objects: "Objects",
|
|
55
|
+
symbols: "Symbols",
|
|
56
|
+
flags: "Flags"
|
|
57
|
+
};
|
|
58
|
+
const categoryIdToI18nKey = {
|
|
59
|
+
frequently_used: "frequentlyUsed",
|
|
60
|
+
smileys_people: "smileysPeople",
|
|
61
|
+
animals_nature: "animalsNature",
|
|
62
|
+
food_drink: "foodDrink",
|
|
63
|
+
travel_places: "travelPlaces",
|
|
64
|
+
activities: "activities",
|
|
65
|
+
objects: "objects",
|
|
66
|
+
symbols: "symbols",
|
|
67
|
+
flags: "flags"
|
|
68
|
+
};
|
|
69
|
+
function useEmojiData({
|
|
70
|
+
searchQuery,
|
|
71
|
+
columns,
|
|
72
|
+
showFrequentlyUsed,
|
|
73
|
+
categoryNames = defaultCategoryNames
|
|
74
|
+
}) {
|
|
48
75
|
const [frequentlyUsed, setFrequentlyUsed] = useState([]);
|
|
49
76
|
useEffect(() => {
|
|
50
77
|
if (showFrequentlyUsed) {
|
|
@@ -74,7 +101,7 @@ function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
|
|
|
74
101
|
items.push({
|
|
75
102
|
type: "header",
|
|
76
103
|
category: "frequently_used",
|
|
77
|
-
title:
|
|
104
|
+
title: categoryNames.frequentlyUsed
|
|
78
105
|
});
|
|
79
106
|
for (let i = 0; i < frequentlyUsed.length; i += columns) {
|
|
80
107
|
items.push({
|
|
@@ -89,10 +116,11 @@ function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
|
|
|
89
116
|
(emoji) => emoji.id >= category.range[0] && emoji.id <= category.range[1]
|
|
90
117
|
);
|
|
91
118
|
if (categoryEmojis.length > 0) {
|
|
119
|
+
const i18nKey = categoryIdToI18nKey[category.id];
|
|
92
120
|
items.push({
|
|
93
121
|
type: "header",
|
|
94
122
|
category: category.id,
|
|
95
|
-
title: category.
|
|
123
|
+
title: i18nKey ? categoryNames[i18nKey] : category.id
|
|
96
124
|
});
|
|
97
125
|
for (let i = 0; i < categoryEmojis.length; i += columns) {
|
|
98
126
|
items.push({
|
|
@@ -103,7 +131,7 @@ function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
|
|
|
103
131
|
}
|
|
104
132
|
});
|
|
105
133
|
return items;
|
|
106
|
-
}, [searchQuery, searchResults, frequentlyUsed, columns, showFrequentlyUsed]);
|
|
134
|
+
}, [searchQuery, searchResults, frequentlyUsed, columns, showFrequentlyUsed, categoryNames]);
|
|
107
135
|
const categoryIndexMap = useMemo(() => {
|
|
108
136
|
const map = /* @__PURE__ */ new Map();
|
|
109
137
|
categorizedData.forEach((item, index) => {
|
|
@@ -17,6 +17,8 @@ function useEmojiScroll({
|
|
|
17
17
|
const [currentVisibleCategory, setCurrentVisibleCategory] = useState("frequently_used");
|
|
18
18
|
const isScrollingToTarget = useRef(false);
|
|
19
19
|
const isInternalUpdate = useRef(false);
|
|
20
|
+
const scrollingTimeoutRef = useRef(null);
|
|
21
|
+
const internalUpdateTimeoutRef = useRef(null);
|
|
20
22
|
const virtualizer = useVirtualizer({
|
|
21
23
|
count: categorizedData.length,
|
|
22
24
|
getScrollElement: () => scrollRef.current,
|
|
@@ -81,7 +83,10 @@ function useEmojiScroll({
|
|
|
81
83
|
align: "start",
|
|
82
84
|
behavior: "auto"
|
|
83
85
|
});
|
|
84
|
-
|
|
86
|
+
if (scrollingTimeoutRef.current) {
|
|
87
|
+
clearTimeout(scrollingTimeoutRef.current);
|
|
88
|
+
}
|
|
89
|
+
scrollingTimeoutRef.current = setTimeout(() => {
|
|
85
90
|
isScrollingToTarget.current = false;
|
|
86
91
|
}, 100);
|
|
87
92
|
}
|
|
@@ -94,17 +99,33 @@ function useEmojiScroll({
|
|
|
94
99
|
align: "center",
|
|
95
100
|
behavior: "auto"
|
|
96
101
|
});
|
|
97
|
-
|
|
102
|
+
if (scrollingTimeoutRef.current) {
|
|
103
|
+
clearTimeout(scrollingTimeoutRef.current);
|
|
104
|
+
}
|
|
105
|
+
scrollingTimeoutRef.current = setTimeout(() => {
|
|
98
106
|
isScrollingToTarget.current = false;
|
|
99
107
|
}, 100);
|
|
100
108
|
}
|
|
101
109
|
});
|
|
102
110
|
const markInternalUpdate = useEventCallback(() => {
|
|
103
111
|
isInternalUpdate.current = true;
|
|
104
|
-
|
|
112
|
+
if (internalUpdateTimeoutRef.current) {
|
|
113
|
+
clearTimeout(internalUpdateTimeoutRef.current);
|
|
114
|
+
}
|
|
115
|
+
internalUpdateTimeoutRef.current = setTimeout(() => {
|
|
105
116
|
isInternalUpdate.current = false;
|
|
106
117
|
}, 50);
|
|
107
118
|
});
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
return () => {
|
|
121
|
+
if (scrollingTimeoutRef.current) {
|
|
122
|
+
clearTimeout(scrollingTimeoutRef.current);
|
|
123
|
+
}
|
|
124
|
+
if (internalUpdateTimeoutRef.current) {
|
|
125
|
+
clearTimeout(internalUpdateTimeoutRef.current);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}, []);
|
|
108
129
|
useEffect(() => {
|
|
109
130
|
if (value && !searchQuery.trim() && !isInternalUpdate.current) {
|
|
110
131
|
scrollToEmoji(value);
|
|
@@ -132,7 +132,7 @@ const emojiFooterTv = tcv({
|
|
|
132
132
|
const emojiEmptyTv = tcv({
|
|
133
133
|
slots: {
|
|
134
134
|
container: "flex h-32 flex-col items-center justify-center p-4 text-center",
|
|
135
|
-
title: "text-
|
|
135
|
+
title: "text-body-large-strong",
|
|
136
136
|
description: "mt-2 w-32"
|
|
137
137
|
},
|
|
138
138
|
variants: {
|
|
@@ -145,8 +145,18 @@ const iconButtonTv = tcv({
|
|
|
145
145
|
},
|
|
146
146
|
{
|
|
147
147
|
variant: "submit",
|
|
148
|
+
active: false,
|
|
149
|
+
disabled: false,
|
|
150
|
+
class: {
|
|
151
|
+
button: ["focus-visible:shadow-focus", "hover:opacity-70", "active:opacity-70"]
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
variant: "submit",
|
|
156
|
+
active: true,
|
|
157
|
+
disabled: false,
|
|
148
158
|
class: {
|
|
149
|
-
button: "
|
|
159
|
+
button: "opacity-70"
|
|
150
160
|
}
|
|
151
161
|
},
|
|
152
162
|
{
|
|
@@ -7,7 +7,15 @@ import { TooltipArrow } from "./tooltip-arrow.js";
|
|
|
7
7
|
import { tcx } from "../../../../shared/utils/tcx/tcx.js";
|
|
8
8
|
const TooltipContent = forwardRef(
|
|
9
9
|
function TooltipContent2(props, propRef) {
|
|
10
|
-
const {
|
|
10
|
+
const {
|
|
11
|
+
className,
|
|
12
|
+
withArrow = true,
|
|
13
|
+
variant = "default",
|
|
14
|
+
children,
|
|
15
|
+
portalId,
|
|
16
|
+
interactive = true,
|
|
17
|
+
...rest
|
|
18
|
+
} = props;
|
|
11
19
|
const state = useTooltipState();
|
|
12
20
|
const ref = useMergeRefs([state.refs.setFloating, propRef]);
|
|
13
21
|
const { isInstantPhase, currentId } = useDelayGroup(state.context, {
|
|
@@ -36,19 +44,27 @@ const TooltipContent = forwardRef(
|
|
|
36
44
|
});
|
|
37
45
|
const tv = useMemo(() => tooltipContentVariants({ variant }), [variant]);
|
|
38
46
|
if (state.disabled || !isMounted) return null;
|
|
47
|
+
const floatingProps = state.getFloatingProps(rest);
|
|
39
48
|
return /* @__PURE__ */ jsx(FloatingPortal, { id: portalId, children: /* @__PURE__ */ jsx(
|
|
40
49
|
"div",
|
|
41
50
|
{
|
|
42
51
|
ref,
|
|
43
|
-
style:
|
|
44
|
-
|
|
52
|
+
style: {
|
|
53
|
+
...state.floatingStyles,
|
|
54
|
+
pointerEvents: interactive ? void 0 : "none"
|
|
55
|
+
},
|
|
56
|
+
...floatingProps,
|
|
45
57
|
className: "z-tooltip",
|
|
46
58
|
children: /* @__PURE__ */ jsxs(
|
|
47
59
|
"div",
|
|
48
60
|
{
|
|
49
61
|
className: tcx(tv.root({ className })),
|
|
50
62
|
"data-state": state.open ? "open" : "closed",
|
|
51
|
-
style:
|
|
63
|
+
style: {
|
|
64
|
+
...styles,
|
|
65
|
+
pointerEvents: interactive ? void 0 : "none",
|
|
66
|
+
cursor: interactive ? void 0 : "default"
|
|
67
|
+
},
|
|
52
68
|
children: [
|
|
53
69
|
children,
|
|
54
70
|
withArrow && /* @__PURE__ */ jsx(TooltipArrow, { variant })
|
|
@@ -17,7 +17,8 @@ function TooltipRoot(props) {
|
|
|
17
17
|
withArrow = true,
|
|
18
18
|
variant = "default",
|
|
19
19
|
offset = 8,
|
|
20
|
-
portalId = PORTAL_ROOT_ID
|
|
20
|
+
portalId = PORTAL_ROOT_ID,
|
|
21
|
+
interactive = true
|
|
21
22
|
} = props;
|
|
22
23
|
const tooltip = useTooltip({
|
|
23
24
|
placement,
|
|
@@ -36,6 +37,7 @@ function TooltipRoot(props) {
|
|
|
36
37
|
variant,
|
|
37
38
|
portalId,
|
|
38
39
|
className,
|
|
40
|
+
interactive,
|
|
39
41
|
children: [
|
|
40
42
|
content,
|
|
41
43
|
shortcut && /* @__PURE__ */ jsx(
|
|
@@ -4,6 +4,7 @@ import { KbdKey } from '../../kbd/src';
|
|
|
4
4
|
export interface TooltipOptions {
|
|
5
5
|
disabled?: boolean;
|
|
6
6
|
initialOpen?: boolean;
|
|
7
|
+
interactive?: boolean;
|
|
7
8
|
offset?: number;
|
|
8
9
|
onOpenChange?: (open: boolean) => void;
|
|
9
10
|
open?: boolean;
|
|
@@ -32,6 +33,7 @@ export interface TooltipProps {
|
|
|
32
33
|
className?: string;
|
|
33
34
|
content?: React.ReactNode;
|
|
34
35
|
disabled?: boolean;
|
|
36
|
+
interactive?: boolean;
|
|
35
37
|
offset?: number;
|
|
36
38
|
onOpenChange?: (open: boolean) => void;
|
|
37
39
|
open?: boolean;
|
|
@@ -45,6 +47,7 @@ export interface TooltipProps {
|
|
|
45
47
|
withArrow?: boolean;
|
|
46
48
|
}
|
|
47
49
|
export interface TooltipContentProps extends React.HTMLProps<HTMLDivElement> {
|
|
50
|
+
interactive?: boolean;
|
|
48
51
|
portalId?: string;
|
|
49
52
|
variant?: "default" | "light";
|
|
50
53
|
withArrow?: boolean;
|
package/package.json
CHANGED