@choice-ui/react 1.7.8 → 1.8.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/components/emoji-picker/dist/index.d.ts +29 -1
- package/dist/components/emoji-picker/dist/index.js +144 -42
- 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/dist/index.d.ts +1 -1
- package/dist/components/icon-button/dist/index.js +29 -0
- package/dist/components/textarea/dist/index.js +3 -1
- package/dist/components/tooltip/dist/index.d.ts +2 -0
- package/dist/components/tooltip/dist/index.js +23 -5
- 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/dist/components/virtual-select/dist/index.d.ts +48 -0
- package/package.json +20 -32
|
@@ -15,12 +15,24 @@ type VirtualItem = {
|
|
|
15
15
|
emojis: EmojiData[];
|
|
16
16
|
type: "emojis";
|
|
17
17
|
};
|
|
18
|
+
interface CategoryNames {
|
|
19
|
+
activities: string;
|
|
20
|
+
animalsNature: string;
|
|
21
|
+
flags: string;
|
|
22
|
+
foodDrink: string;
|
|
23
|
+
frequentlyUsed: string;
|
|
24
|
+
objects: string;
|
|
25
|
+
smileysPeople: string;
|
|
26
|
+
symbols: string;
|
|
27
|
+
travelPlaces: string;
|
|
28
|
+
}
|
|
18
29
|
interface UseEmojiDataProps {
|
|
30
|
+
categoryNames?: CategoryNames;
|
|
19
31
|
columns: number;
|
|
20
32
|
searchQuery: string;
|
|
21
33
|
showFrequentlyUsed: boolean;
|
|
22
34
|
}
|
|
23
|
-
declare function useEmojiData({ searchQuery, columns, showFrequentlyUsed }: UseEmojiDataProps): {
|
|
35
|
+
declare function useEmojiData({ searchQuery, columns, showFrequentlyUsed, categoryNames, }: UseEmojiDataProps): {
|
|
24
36
|
categorizedData: VirtualItem[];
|
|
25
37
|
categoryIndexMap: Map<EmojiCategory, number>;
|
|
26
38
|
searchResults: {
|
|
@@ -52,6 +64,22 @@ interface EmojiPickerProps {
|
|
|
52
64
|
showFooter?: boolean;
|
|
53
65
|
value?: EmojiData | null;
|
|
54
66
|
variant?: "default" | "dark" | "light";
|
|
67
|
+
i18n?: {
|
|
68
|
+
noEmojisFoundTitle?: string;
|
|
69
|
+
noEmojisFoundDescription?: string;
|
|
70
|
+
footerPickAnEmoji?: string;
|
|
71
|
+
categories?: {
|
|
72
|
+
frequentlyUsed: string;
|
|
73
|
+
smileysPeople: string;
|
|
74
|
+
animalsNature: string;
|
|
75
|
+
foodDrink: string;
|
|
76
|
+
travelPlaces: string;
|
|
77
|
+
activities: string;
|
|
78
|
+
objects: string;
|
|
79
|
+
symbols: string;
|
|
80
|
+
flags: string;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
55
83
|
}
|
|
56
84
|
declare const EmojiPicker: React.NamedExoticComponent<EmojiPickerProps>;
|
|
57
85
|
|
|
@@ -141,7 +141,7 @@ var emojiFooterTv = tcv({
|
|
|
141
141
|
var emojiEmptyTv = tcv({
|
|
142
142
|
slots: {
|
|
143
143
|
container: "flex h-32 flex-col items-center justify-center p-4 text-center",
|
|
144
|
-
title: "text-
|
|
144
|
+
title: "text-body-large-strong",
|
|
145
145
|
description: "mt-2 w-32"
|
|
146
146
|
},
|
|
147
147
|
variants: {
|
|
@@ -179,13 +179,20 @@ var EmojiCategoryHeader = forwardRef(
|
|
|
179
179
|
);
|
|
180
180
|
}
|
|
181
181
|
);
|
|
182
|
-
|
|
182
|
+
var EmojiFooter = memo(function EmojiFooter2({
|
|
183
|
+
hoveredEmoji,
|
|
184
|
+
selectedEmoji,
|
|
185
|
+
variant = "dark",
|
|
186
|
+
i18n = {
|
|
187
|
+
pickAnEmoji: "Pick an emoji..."
|
|
188
|
+
}
|
|
189
|
+
}) {
|
|
183
190
|
var _a, _b;
|
|
184
191
|
const tv = emojiFooterTv({ variant });
|
|
185
192
|
return /* @__PURE__ */ jsxs("div", { className: tv.footer(), children: [
|
|
186
193
|
/* @__PURE__ */ jsx("div", { className: tv.emojiPreview(), children: ((_a = hoveredEmoji || selectedEmoji) == null ? void 0 : _a.emoji) || /* @__PURE__ */ jsx("div", { className: tv.emojiPreviewEmpty() }) }),
|
|
187
194
|
/* @__PURE__ */ jsxs("div", { className: tv.emojiInfo(), children: [
|
|
188
|
-
/* @__PURE__ */ jsx("div", { className: tv.emojiName(), children: (hoveredEmoji == null ? void 0 : hoveredEmoji.name) || (selectedEmoji == null ? void 0 : selectedEmoji.name) ||
|
|
195
|
+
/* @__PURE__ */ jsx("div", { className: tv.emojiName(), children: (hoveredEmoji == null ? void 0 : hoveredEmoji.name) || (selectedEmoji == null ? void 0 : selectedEmoji.name) || i18n.pickAnEmoji }),
|
|
189
196
|
hoveredEmoji || selectedEmoji ? /* @__PURE__ */ jsxs("div", { className: tv.emojiCode(), children: [
|
|
190
197
|
":",
|
|
191
198
|
(_b = hoveredEmoji || selectedEmoji) == null ? void 0 : _b.nameUrl,
|
|
@@ -193,7 +200,7 @@ function EmojiFooter({ hoveredEmoji, selectedEmoji, variant = "dark" }) {
|
|
|
193
200
|
] }) : /* @__PURE__ */ jsx(Fragment, {})
|
|
194
201
|
] })
|
|
195
202
|
] });
|
|
196
|
-
}
|
|
203
|
+
});
|
|
197
204
|
var EmojiItem = memo(function EmojiItem2(props) {
|
|
198
205
|
const { emoji, onSelect, onHover, selected = false, variant = "dark" } = props;
|
|
199
206
|
return /* @__PURE__ */ jsx(
|
|
@@ -209,11 +216,17 @@ var EmojiItem = memo(function EmojiItem2(props) {
|
|
|
209
216
|
}
|
|
210
217
|
);
|
|
211
218
|
});
|
|
212
|
-
var EmojiEmpty = memo(function EmojiEmpty2({
|
|
219
|
+
var EmojiEmpty = memo(function EmojiEmpty2({
|
|
220
|
+
variant = "dark",
|
|
221
|
+
i18n = {
|
|
222
|
+
title: "No emoji found",
|
|
223
|
+
description: "You can search for an emoji by name or use the search bar to find it."
|
|
224
|
+
}
|
|
225
|
+
}) {
|
|
213
226
|
const tv = emojiEmptyTv({ variant });
|
|
214
227
|
return /* @__PURE__ */ jsxs("div", { className: tv.container(), children: [
|
|
215
|
-
/* @__PURE__ */ jsx("div", { className: tv.title(), children:
|
|
216
|
-
/* @__PURE__ */ jsx("p", { className: tv.description(), children:
|
|
228
|
+
/* @__PURE__ */ jsx("div", { className: tv.title(), children: i18n.title }),
|
|
229
|
+
/* @__PURE__ */ jsx("p", { className: tv.description(), children: i18n.description })
|
|
217
230
|
] });
|
|
218
231
|
});
|
|
219
232
|
var emojis = [
|
|
@@ -11727,15 +11740,15 @@ var emojis = [
|
|
|
11727
11740
|
}
|
|
11728
11741
|
];
|
|
11729
11742
|
var categories = [
|
|
11730
|
-
{ id: "frequently_used"
|
|
11731
|
-
{ id: "smileys_people",
|
|
11732
|
-
{ id: "animals_nature",
|
|
11733
|
-
{ id: "food_drink",
|
|
11734
|
-
{ id: "travel_places",
|
|
11735
|
-
{ id: "activities",
|
|
11736
|
-
{ id: "objects",
|
|
11737
|
-
{ id: "symbols",
|
|
11738
|
-
{ id: "flags",
|
|
11743
|
+
{ id: "frequently_used" },
|
|
11744
|
+
{ id: "smileys_people", range: [1, 460] },
|
|
11745
|
+
{ id: "animals_nature", range: [465, 591] },
|
|
11746
|
+
{ id: "food_drink", range: [592, 712] },
|
|
11747
|
+
{ id: "travel_places", range: [713, 922] },
|
|
11748
|
+
{ id: "activities", range: [923, 1001] },
|
|
11749
|
+
{ id: "objects", range: [1002, 1234] },
|
|
11750
|
+
{ id: "symbols", range: [1235, 1451] },
|
|
11751
|
+
{ id: "flags", range: [1452, 1719] }
|
|
11739
11752
|
];
|
|
11740
11753
|
var STORAGE_KEY = "emoji-picker-frequently-used";
|
|
11741
11754
|
function getEmojiCategory(id) {
|
|
@@ -11769,7 +11782,34 @@ function saveFrequentlyUsedEmoji(emojiId) {
|
|
|
11769
11782
|
} catch {
|
|
11770
11783
|
}
|
|
11771
11784
|
}
|
|
11772
|
-
|
|
11785
|
+
var defaultCategoryNames = {
|
|
11786
|
+
frequentlyUsed: "Frequently used",
|
|
11787
|
+
smileysPeople: "Smileys & People",
|
|
11788
|
+
animalsNature: "Animals & Nature",
|
|
11789
|
+
foodDrink: "Food & Drink",
|
|
11790
|
+
travelPlaces: "Travel & Places",
|
|
11791
|
+
activities: "Activities",
|
|
11792
|
+
objects: "Objects",
|
|
11793
|
+
symbols: "Symbols",
|
|
11794
|
+
flags: "Flags"
|
|
11795
|
+
};
|
|
11796
|
+
var categoryIdToI18nKey = {
|
|
11797
|
+
frequently_used: "frequentlyUsed",
|
|
11798
|
+
smileys_people: "smileysPeople",
|
|
11799
|
+
animals_nature: "animalsNature",
|
|
11800
|
+
food_drink: "foodDrink",
|
|
11801
|
+
travel_places: "travelPlaces",
|
|
11802
|
+
activities: "activities",
|
|
11803
|
+
objects: "objects",
|
|
11804
|
+
symbols: "symbols",
|
|
11805
|
+
flags: "flags"
|
|
11806
|
+
};
|
|
11807
|
+
function useEmojiData({
|
|
11808
|
+
searchQuery,
|
|
11809
|
+
columns,
|
|
11810
|
+
showFrequentlyUsed,
|
|
11811
|
+
categoryNames = defaultCategoryNames
|
|
11812
|
+
}) {
|
|
11773
11813
|
const [frequentlyUsed, setFrequentlyUsed] = useState([]);
|
|
11774
11814
|
useEffect(() => {
|
|
11775
11815
|
if (showFrequentlyUsed) {
|
|
@@ -11799,7 +11839,7 @@ function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
|
|
|
11799
11839
|
items.push({
|
|
11800
11840
|
type: "header",
|
|
11801
11841
|
category: "frequently_used",
|
|
11802
|
-
title:
|
|
11842
|
+
title: categoryNames.frequentlyUsed
|
|
11803
11843
|
});
|
|
11804
11844
|
for (let i = 0; i < frequentlyUsed.length; i += columns) {
|
|
11805
11845
|
items.push({
|
|
@@ -11814,10 +11854,11 @@ function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
|
|
|
11814
11854
|
(emoji) => emoji.id >= category.range[0] && emoji.id <= category.range[1]
|
|
11815
11855
|
);
|
|
11816
11856
|
if (categoryEmojis.length > 0) {
|
|
11857
|
+
const i18nKey = categoryIdToI18nKey[category.id];
|
|
11817
11858
|
items.push({
|
|
11818
11859
|
type: "header",
|
|
11819
11860
|
category: category.id,
|
|
11820
|
-
title: category.
|
|
11861
|
+
title: i18nKey ? categoryNames[i18nKey] : category.id
|
|
11821
11862
|
});
|
|
11822
11863
|
for (let i = 0; i < categoryEmojis.length; i += columns) {
|
|
11823
11864
|
items.push({
|
|
@@ -11828,7 +11869,7 @@ function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
|
|
|
11828
11869
|
}
|
|
11829
11870
|
});
|
|
11830
11871
|
return items;
|
|
11831
|
-
}, [searchQuery, searchResults, frequentlyUsed, columns, showFrequentlyUsed]);
|
|
11872
|
+
}, [searchQuery, searchResults, frequentlyUsed, columns, showFrequentlyUsed, categoryNames]);
|
|
11832
11873
|
const categoryIndexMap = useMemo(() => {
|
|
11833
11874
|
const map = /* @__PURE__ */ new Map();
|
|
11834
11875
|
categorizedData.forEach((item, index) => {
|
|
@@ -11884,6 +11925,8 @@ function useEmojiScroll({
|
|
|
11884
11925
|
const [currentVisibleCategory, setCurrentVisibleCategory] = useState("frequently_used");
|
|
11885
11926
|
const isScrollingToTarget = useRef(false);
|
|
11886
11927
|
const isInternalUpdate = useRef(false);
|
|
11928
|
+
const scrollingTimeoutRef = useRef(null);
|
|
11929
|
+
const internalUpdateTimeoutRef = useRef(null);
|
|
11887
11930
|
const virtualizer = useVirtualizer({
|
|
11888
11931
|
count: categorizedData.length,
|
|
11889
11932
|
getScrollElement: () => scrollRef.current,
|
|
@@ -11948,7 +11991,10 @@ function useEmojiScroll({
|
|
|
11948
11991
|
align: "start",
|
|
11949
11992
|
behavior: "auto"
|
|
11950
11993
|
});
|
|
11951
|
-
|
|
11994
|
+
if (scrollingTimeoutRef.current) {
|
|
11995
|
+
clearTimeout(scrollingTimeoutRef.current);
|
|
11996
|
+
}
|
|
11997
|
+
scrollingTimeoutRef.current = setTimeout(() => {
|
|
11952
11998
|
isScrollingToTarget.current = false;
|
|
11953
11999
|
}, 100);
|
|
11954
12000
|
}
|
|
@@ -11961,17 +12007,33 @@ function useEmojiScroll({
|
|
|
11961
12007
|
align: "center",
|
|
11962
12008
|
behavior: "auto"
|
|
11963
12009
|
});
|
|
11964
|
-
|
|
12010
|
+
if (scrollingTimeoutRef.current) {
|
|
12011
|
+
clearTimeout(scrollingTimeoutRef.current);
|
|
12012
|
+
}
|
|
12013
|
+
scrollingTimeoutRef.current = setTimeout(() => {
|
|
11965
12014
|
isScrollingToTarget.current = false;
|
|
11966
12015
|
}, 100);
|
|
11967
12016
|
}
|
|
11968
12017
|
});
|
|
11969
12018
|
const markInternalUpdate = useEventCallback(() => {
|
|
11970
12019
|
isInternalUpdate.current = true;
|
|
11971
|
-
|
|
12020
|
+
if (internalUpdateTimeoutRef.current) {
|
|
12021
|
+
clearTimeout(internalUpdateTimeoutRef.current);
|
|
12022
|
+
}
|
|
12023
|
+
internalUpdateTimeoutRef.current = setTimeout(() => {
|
|
11972
12024
|
isInternalUpdate.current = false;
|
|
11973
12025
|
}, 50);
|
|
11974
12026
|
});
|
|
12027
|
+
useEffect(() => {
|
|
12028
|
+
return () => {
|
|
12029
|
+
if (scrollingTimeoutRef.current) {
|
|
12030
|
+
clearTimeout(scrollingTimeoutRef.current);
|
|
12031
|
+
}
|
|
12032
|
+
if (internalUpdateTimeoutRef.current) {
|
|
12033
|
+
clearTimeout(internalUpdateTimeoutRef.current);
|
|
12034
|
+
}
|
|
12035
|
+
};
|
|
12036
|
+
}, []);
|
|
11975
12037
|
useEffect(() => {
|
|
11976
12038
|
if (value && !searchQuery.trim() && !isInternalUpdate.current) {
|
|
11977
12039
|
scrollToEmoji(value);
|
|
@@ -11996,17 +12058,6 @@ function useEmojiScroll({
|
|
|
11996
12058
|
PADDING
|
|
11997
12059
|
};
|
|
11998
12060
|
}
|
|
11999
|
-
var categoriesWithIcons = [
|
|
12000
|
-
{ id: "frequently_used", name: "Frequently used", icon: /* @__PURE__ */ jsx(EmojiFrequentlyUsed, {}) },
|
|
12001
|
-
{ id: "smileys_people", name: "Smileys & People", icon: /* @__PURE__ */ jsx(EmojiSmileysPeople, {}) },
|
|
12002
|
-
{ id: "animals_nature", name: "Animals & Nature", icon: /* @__PURE__ */ jsx(EmojiAnimalsNature, {}) },
|
|
12003
|
-
{ id: "food_drink", name: "Food & Drink", icon: /* @__PURE__ */ jsx(EmojiFoodDrink, {}) },
|
|
12004
|
-
{ id: "travel_places", name: "Travel & Places", icon: /* @__PURE__ */ jsx(EmojiTravelPlaces, {}) },
|
|
12005
|
-
{ id: "activities", name: "Activities", icon: /* @__PURE__ */ jsx(EmojiActivity, {}) },
|
|
12006
|
-
{ id: "objects", name: "Objects", icon: /* @__PURE__ */ jsx(EmojiObjects, {}) },
|
|
12007
|
-
{ id: "symbols", name: "Symbols", icon: /* @__PURE__ */ jsx(EmojiSymbols, {}) },
|
|
12008
|
-
{ id: "flags", name: "Flags", icon: /* @__PURE__ */ jsx(EmojiFlags, {}) }
|
|
12009
|
-
];
|
|
12010
12061
|
var EmojiPicker = memo(function EmojiPicker2({
|
|
12011
12062
|
value,
|
|
12012
12063
|
onChange,
|
|
@@ -12019,11 +12070,49 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12019
12070
|
showSearch = true,
|
|
12020
12071
|
showFooter = true,
|
|
12021
12072
|
children,
|
|
12022
|
-
variant = "dark"
|
|
12073
|
+
variant = "dark",
|
|
12074
|
+
i18n = {
|
|
12075
|
+
noEmojisFoundTitle: "No emoji found",
|
|
12076
|
+
noEmojisFoundDescription: "You can search for an emoji by name or use the search bar to find it.",
|
|
12077
|
+
footerPickAnEmoji: "Pick an emoji...",
|
|
12078
|
+
categories: {
|
|
12079
|
+
frequentlyUsed: "Frequently used",
|
|
12080
|
+
smileysPeople: "Smileys & People",
|
|
12081
|
+
animalsNature: "Animals & Nature",
|
|
12082
|
+
foodDrink: "Food & Drink",
|
|
12083
|
+
travelPlaces: "Travel & Places",
|
|
12084
|
+
activities: "Activities",
|
|
12085
|
+
objects: "Objects",
|
|
12086
|
+
symbols: "Symbols",
|
|
12087
|
+
flags: "Flags"
|
|
12088
|
+
}
|
|
12089
|
+
}
|
|
12023
12090
|
}) {
|
|
12024
12091
|
const [searchQuery, setSearchQuery] = useState("");
|
|
12025
12092
|
const [hoveredEmoji, setHoveredEmoji] = useState(null);
|
|
12093
|
+
const safeColumns = Math.max(1, columns);
|
|
12026
12094
|
const tv = emojiTv({ variant });
|
|
12095
|
+
const categoriesWithIcons = useMemo(
|
|
12096
|
+
() => {
|
|
12097
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
12098
|
+
return [
|
|
12099
|
+
{
|
|
12100
|
+
id: "frequently_used",
|
|
12101
|
+
name: (_a = i18n.categories) == null ? void 0 : _a.frequentlyUsed,
|
|
12102
|
+
icon: /* @__PURE__ */ jsx(EmojiFrequentlyUsed, {})
|
|
12103
|
+
},
|
|
12104
|
+
{ id: "smileys_people", name: (_b = i18n.categories) == null ? void 0 : _b.smileysPeople, icon: /* @__PURE__ */ jsx(EmojiSmileysPeople, {}) },
|
|
12105
|
+
{ id: "animals_nature", name: (_c = i18n.categories) == null ? void 0 : _c.animalsNature, icon: /* @__PURE__ */ jsx(EmojiAnimalsNature, {}) },
|
|
12106
|
+
{ id: "food_drink", name: (_d = i18n.categories) == null ? void 0 : _d.foodDrink, icon: /* @__PURE__ */ jsx(EmojiFoodDrink, {}) },
|
|
12107
|
+
{ id: "travel_places", name: (_e = i18n.categories) == null ? void 0 : _e.travelPlaces, icon: /* @__PURE__ */ jsx(EmojiTravelPlaces, {}) },
|
|
12108
|
+
{ id: "activities", name: (_f = i18n.categories) == null ? void 0 : _f.activities, icon: /* @__PURE__ */ jsx(EmojiActivity, {}) },
|
|
12109
|
+
{ id: "objects", name: (_g = i18n.categories) == null ? void 0 : _g.objects, icon: /* @__PURE__ */ jsx(EmojiObjects, {}) },
|
|
12110
|
+
{ id: "symbols", name: (_h = i18n.categories) == null ? void 0 : _h.symbols, icon: /* @__PURE__ */ jsx(EmojiSymbols, {}) },
|
|
12111
|
+
{ id: "flags", name: (_i = i18n.categories) == null ? void 0 : _i.flags, icon: /* @__PURE__ */ jsx(EmojiFlags, {}) }
|
|
12112
|
+
];
|
|
12113
|
+
},
|
|
12114
|
+
[i18n.categories]
|
|
12115
|
+
);
|
|
12027
12116
|
const {
|
|
12028
12117
|
categorizedData,
|
|
12029
12118
|
categoryIndexMap,
|
|
@@ -12031,8 +12120,9 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12031
12120
|
findEmojiPosition
|
|
12032
12121
|
} = useEmojiData({
|
|
12033
12122
|
searchQuery,
|
|
12034
|
-
columns,
|
|
12035
|
-
showFrequentlyUsed
|
|
12123
|
+
columns: safeColumns,
|
|
12124
|
+
showFrequentlyUsed,
|
|
12125
|
+
categoryNames: i18n.categories
|
|
12036
12126
|
});
|
|
12037
12127
|
const {
|
|
12038
12128
|
scrollRef,
|
|
@@ -12048,7 +12138,7 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12048
12138
|
findEmojiPosition,
|
|
12049
12139
|
searchQuery,
|
|
12050
12140
|
value,
|
|
12051
|
-
columns
|
|
12141
|
+
columns: safeColumns
|
|
12052
12142
|
});
|
|
12053
12143
|
const availableCategories = useMemo(() => {
|
|
12054
12144
|
return categoriesWithIcons.filter((category) => {
|
|
@@ -12057,7 +12147,7 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12057
12147
|
}
|
|
12058
12148
|
return true;
|
|
12059
12149
|
});
|
|
12060
|
-
}, [showFrequentlyUsed]);
|
|
12150
|
+
}, [categoriesWithIcons, showFrequentlyUsed]);
|
|
12061
12151
|
const handleEmojiSelect = useEventCallback((emoji) => {
|
|
12062
12152
|
markInternalUpdate();
|
|
12063
12153
|
addToFrequentlyUsed(emoji.id);
|
|
@@ -12073,7 +12163,7 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12073
12163
|
const rootStyle = {
|
|
12074
12164
|
"--emoji-height": `${height}px`,
|
|
12075
12165
|
"--emoji-padding": `${PADDING2}px`,
|
|
12076
|
-
"--emoji-columns": `${
|
|
12166
|
+
"--emoji-columns": `${safeColumns}`
|
|
12077
12167
|
};
|
|
12078
12168
|
return /* @__PURE__ */ jsxs(
|
|
12079
12169
|
"div",
|
|
@@ -12176,7 +12266,16 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12176
12266
|
},
|
|
12177
12267
|
virtualItem.key
|
|
12178
12268
|
);
|
|
12179
|
-
}) : /* @__PURE__ */ jsx(
|
|
12269
|
+
}) : /* @__PURE__ */ jsx(
|
|
12270
|
+
EmojiEmpty,
|
|
12271
|
+
{
|
|
12272
|
+
variant,
|
|
12273
|
+
i18n: {
|
|
12274
|
+
title: i18n.noEmojisFoundTitle,
|
|
12275
|
+
description: i18n.noEmojisFoundDescription
|
|
12276
|
+
}
|
|
12277
|
+
}
|
|
12278
|
+
)
|
|
12180
12279
|
}
|
|
12181
12280
|
)
|
|
12182
12281
|
}
|
|
@@ -12188,7 +12287,10 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12188
12287
|
{
|
|
12189
12288
|
hoveredEmoji,
|
|
12190
12289
|
selectedEmoji: value || null,
|
|
12191
|
-
variant
|
|
12290
|
+
variant,
|
|
12291
|
+
i18n: {
|
|
12292
|
+
pickAnEmoji: i18n.footerPickAnEmoji
|
|
12293
|
+
}
|
|
12192
12294
|
}
|
|
12193
12295
|
),
|
|
12194
12296
|
children
|
|
@@ -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: {
|
|
@@ -14,7 +14,7 @@ interface IconButtonProps extends Omit<HTMLProps<HTMLElement>, "size" | "as"> {
|
|
|
14
14
|
readOnly?: boolean;
|
|
15
15
|
size?: "default" | "large" | "reset";
|
|
16
16
|
tooltip?: TooltipProps;
|
|
17
|
-
variant?: "default" | "secondary" | "solid" | "highlight" | "ghost" | "dark" | "reset";
|
|
17
|
+
variant?: "default" | "secondary" | "solid" | "highlight" | "ghost" | "dark" | "submit" | "reset";
|
|
18
18
|
}
|
|
19
19
|
declare const IconButton: react.ForwardRefExoticComponent<Omit<IconButtonProps, "ref"> & react.RefAttributes<HTMLElement>>;
|
|
20
20
|
|
|
@@ -28,6 +28,12 @@ var iconButtonTv = tcv({
|
|
|
28
28
|
highlight: {},
|
|
29
29
|
ghost: {},
|
|
30
30
|
dark: { button: "text-white" },
|
|
31
|
+
submit: {
|
|
32
|
+
button: [
|
|
33
|
+
"bg-[var(--theme-submit-btn-bg)] text-[var(--theme-submit-btn-text)]",
|
|
34
|
+
"focus-visible:border-transparent"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
31
37
|
reset: {}
|
|
32
38
|
},
|
|
33
39
|
active: {
|
|
@@ -141,6 +147,29 @@ var iconButtonTv = tcv({
|
|
|
141
147
|
variant: "dark",
|
|
142
148
|
disabled: true,
|
|
143
149
|
class: { button: "text-gray-500" }
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
variant: "submit",
|
|
153
|
+
class: {
|
|
154
|
+
button: "focus-visible:shadow-focus"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
variant: "submit",
|
|
159
|
+
focused: true,
|
|
160
|
+
class: {
|
|
161
|
+
button: ["shadow-focus", "border-transparent"]
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
variant: "submit",
|
|
166
|
+
loading: true,
|
|
167
|
+
class: { button: "opacity-70" }
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
variant: "submit",
|
|
171
|
+
disabled: true,
|
|
172
|
+
class: { button: "opacity-50" }
|
|
144
173
|
}
|
|
145
174
|
],
|
|
146
175
|
defaultVariants: {
|
|
@@ -10,6 +10,7 @@ interface TooltipProps {
|
|
|
10
10
|
className?: string;
|
|
11
11
|
content?: React.ReactNode;
|
|
12
12
|
disabled?: boolean;
|
|
13
|
+
interactive?: boolean;
|
|
13
14
|
offset?: number;
|
|
14
15
|
onOpenChange?: (open: boolean) => void;
|
|
15
16
|
open?: boolean;
|
|
@@ -23,6 +24,7 @@ interface TooltipProps {
|
|
|
23
24
|
withArrow?: boolean;
|
|
24
25
|
}
|
|
25
26
|
interface TooltipContentProps extends React.HTMLProps<HTMLDivElement> {
|
|
27
|
+
interactive?: boolean;
|
|
26
28
|
portalId?: string;
|
|
27
29
|
variant?: "default" | "light";
|
|
28
30
|
withArrow?: boolean;
|
|
@@ -128,7 +128,15 @@ var TooltipArrow = forwardRef(function TooltipArrow2({ className, variant = "def
|
|
|
128
128
|
});
|
|
129
129
|
var TooltipContent = forwardRef(
|
|
130
130
|
function TooltipContent2(props, propRef) {
|
|
131
|
-
const {
|
|
131
|
+
const {
|
|
132
|
+
className,
|
|
133
|
+
withArrow = true,
|
|
134
|
+
variant = "default",
|
|
135
|
+
children,
|
|
136
|
+
portalId,
|
|
137
|
+
interactive = true,
|
|
138
|
+
...rest
|
|
139
|
+
} = props;
|
|
132
140
|
const state = useTooltipState();
|
|
133
141
|
const ref = useMergeRefs([state.refs.setFloating, propRef]);
|
|
134
142
|
const { isInstantPhase, currentId } = useDelayGroup(state.context, {
|
|
@@ -157,19 +165,27 @@ var TooltipContent = forwardRef(
|
|
|
157
165
|
});
|
|
158
166
|
const tv = useMemo(() => tooltipContentVariants({ variant }), [variant]);
|
|
159
167
|
if (state.disabled || !isMounted) return null;
|
|
168
|
+
const floatingProps = state.getFloatingProps(rest);
|
|
160
169
|
return /* @__PURE__ */ jsx(FloatingPortal, { id: portalId, children: /* @__PURE__ */ jsx(
|
|
161
170
|
"div",
|
|
162
171
|
{
|
|
163
172
|
ref,
|
|
164
|
-
style:
|
|
165
|
-
|
|
173
|
+
style: {
|
|
174
|
+
...state.floatingStyles,
|
|
175
|
+
pointerEvents: interactive ? void 0 : "none"
|
|
176
|
+
},
|
|
177
|
+
...floatingProps,
|
|
166
178
|
className: "z-tooltip",
|
|
167
179
|
children: /* @__PURE__ */ jsxs(
|
|
168
180
|
"div",
|
|
169
181
|
{
|
|
170
182
|
className: tcx(tv.root({ className })),
|
|
171
183
|
"data-state": state.open ? "open" : "closed",
|
|
172
|
-
style:
|
|
184
|
+
style: {
|
|
185
|
+
...styles,
|
|
186
|
+
pointerEvents: interactive ? void 0 : "none",
|
|
187
|
+
cursor: interactive ? void 0 : "default"
|
|
188
|
+
},
|
|
173
189
|
children: [
|
|
174
190
|
children,
|
|
175
191
|
withArrow && /* @__PURE__ */ jsx(TooltipArrow, { variant })
|
|
@@ -272,7 +288,8 @@ function TooltipRoot(props) {
|
|
|
272
288
|
withArrow = true,
|
|
273
289
|
variant = "default",
|
|
274
290
|
offset: offset2 = 8,
|
|
275
|
-
portalId = PORTAL_ROOT_ID
|
|
291
|
+
portalId = PORTAL_ROOT_ID,
|
|
292
|
+
interactive = true
|
|
276
293
|
} = props;
|
|
277
294
|
const tooltip = useTooltip({
|
|
278
295
|
placement,
|
|
@@ -291,6 +308,7 @@ function TooltipRoot(props) {
|
|
|
291
308
|
variant,
|
|
292
309
|
portalId,
|
|
293
310
|
className,
|
|
311
|
+
interactive,
|
|
294
312
|
children: [
|
|
295
313
|
content,
|
|
296
314
|
shortcut && /* @__PURE__ */ jsx(
|
|
@@ -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;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { MenuContextContent, MenuDivider, MenuEmpty, MenuContextItem, MenuSearch, MenuTrigger, MenuValue } from '../../menus/src';
|
|
2
|
+
import { FloatingFocusManagerProps } from '@floating-ui/react';
|
|
3
|
+
import { default as React } from 'react';
|
|
4
|
+
interface VirtualSelectOption<T = unknown> {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
data?: T;
|
|
9
|
+
}
|
|
10
|
+
interface VirtualSelectProps<T = unknown> {
|
|
11
|
+
className?: string;
|
|
12
|
+
closeOnEscape?: boolean;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
emptyText?: string;
|
|
15
|
+
focusManagerProps?: Partial<FloatingFocusManagerProps>;
|
|
16
|
+
matchTriggerWidth?: boolean;
|
|
17
|
+
maxHeight?: number;
|
|
18
|
+
onChange?: (value: string) => void;
|
|
19
|
+
onOpenChange?: (open: boolean) => void;
|
|
20
|
+
open?: boolean;
|
|
21
|
+
options: VirtualSelectOption<T>[];
|
|
22
|
+
overscan?: number;
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
placement?: "bottom-start" | "bottom-end";
|
|
25
|
+
portalId?: string;
|
|
26
|
+
readOnly?: boolean;
|
|
27
|
+
renderOption?: (option: VirtualSelectOption<T>, isSelected: boolean) => React.ReactNode;
|
|
28
|
+
renderValue?: (option: VirtualSelectOption<T> | null) => React.ReactNode;
|
|
29
|
+
root?: HTMLElement | null;
|
|
30
|
+
searchPlaceholder?: string;
|
|
31
|
+
size?: "default" | "large";
|
|
32
|
+
value?: string | null;
|
|
33
|
+
variant?: "default" | "light" | "reset";
|
|
34
|
+
}
|
|
35
|
+
interface VirtualSelectComponentType {
|
|
36
|
+
<T = unknown>(props: VirtualSelectProps<T>): React.ReactElement | null;
|
|
37
|
+
displayName?: string;
|
|
38
|
+
Content: typeof MenuContextContent;
|
|
39
|
+
Divider: typeof MenuDivider;
|
|
40
|
+
Empty: typeof MenuEmpty;
|
|
41
|
+
Item: typeof MenuContextItem;
|
|
42
|
+
Search: typeof MenuSearch;
|
|
43
|
+
Trigger: typeof MenuTrigger;
|
|
44
|
+
Value: typeof MenuValue;
|
|
45
|
+
}
|
|
46
|
+
declare const VirtualSelect: VirtualSelectComponentType;
|
|
47
|
+
|
|
48
|
+
export { VirtualSelect, type VirtualSelectOption, type VirtualSelectProps };
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@choice-ui/react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "A desktop-first React UI component library built for professional desktop applications with comprehensive documentation",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"source": "./app/index.ts",
|
|
8
8
|
"main": "./dist/index.js",
|
|
9
|
-
"types": "./
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
12
|
"README.md",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"exports": {
|
|
16
16
|
".": {
|
|
17
|
-
"types": "./
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
18
|
"import": "./dist/index.js"
|
|
19
19
|
},
|
|
20
20
|
"./styles/*": "./dist/styles/*",
|
|
@@ -22,36 +22,10 @@
|
|
|
22
22
|
"./llms.txt": "./dist/llms.txt"
|
|
23
23
|
},
|
|
24
24
|
"publishConfig": {
|
|
25
|
-
"access": "public"
|
|
26
|
-
"types": "./dist/index.d.ts",
|
|
27
|
-
"main": "./dist/index.js",
|
|
28
|
-
"exports": {
|
|
29
|
-
".": {
|
|
30
|
-
"types": "./dist/index.d.ts",
|
|
31
|
-
"import": "./dist/index.js"
|
|
32
|
-
},
|
|
33
|
-
"./styles/*": "./dist/styles/*",
|
|
34
|
-
"./tailwind.css": "./dist/tailwind.css",
|
|
35
|
-
"./llms.txt": "./dist/llms.txt"
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
"scripts": {
|
|
39
|
-
"build": "pnpm run clean && pnpm --filter @choice-ui/shared build && vite build",
|
|
40
|
-
"build:watch": "vite build --watch",
|
|
41
|
-
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,md}\"",
|
|
42
|
-
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
|
|
43
|
-
"lint:types": "tsc",
|
|
44
|
-
"clean": "rimraf dist",
|
|
45
|
-
"prepublishOnly": "pnpm run build",
|
|
46
|
-
"plop": "pnpm dlx plop",
|
|
47
|
-
"test": "jest",
|
|
48
|
-
"test:watch": "jest --watch",
|
|
49
|
-
"test:coverage": "jest --coverage",
|
|
50
|
-
"madge": "npx madge --circular --extensions ts app/"
|
|
25
|
+
"access": "public"
|
|
51
26
|
},
|
|
52
27
|
"dependencies": {
|
|
53
28
|
"@choiceform/icons-react": "^1.3.8",
|
|
54
|
-
"@choice-ui/design-tokens": "workspace:*",
|
|
55
29
|
"classnames": "^2.5.1",
|
|
56
30
|
"tailwind-merge": "^3.3.1",
|
|
57
31
|
"tailwind-variants": "^3.1.0",
|
|
@@ -85,7 +59,8 @@
|
|
|
85
59
|
"remark-breaks": "^4.0.0",
|
|
86
60
|
"remark-math": "^6.0.0",
|
|
87
61
|
"harden-react-markdown": "^1.0.4",
|
|
88
|
-
"shiki": "^3.9.2"
|
|
62
|
+
"shiki": "^3.9.2",
|
|
63
|
+
"@choice-ui/design-tokens": "0.2.13"
|
|
89
64
|
},
|
|
90
65
|
"devDependencies": {
|
|
91
66
|
"@babel/core": "^7.27.1",
|
|
@@ -136,5 +111,18 @@
|
|
|
136
111
|
"peerDependencies": {
|
|
137
112
|
"react": ">=18.0.0",
|
|
138
113
|
"react-dom": ">=18.0.0"
|
|
114
|
+
},
|
|
115
|
+
"scripts": {
|
|
116
|
+
"build": "pnpm run clean && pnpm --filter @choice-ui/shared build && vite build",
|
|
117
|
+
"build:watch": "vite build --watch",
|
|
118
|
+
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,md}\"",
|
|
119
|
+
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
|
|
120
|
+
"lint:types": "tsc",
|
|
121
|
+
"clean": "rimraf dist",
|
|
122
|
+
"plop": "pnpm dlx plop",
|
|
123
|
+
"test": "jest",
|
|
124
|
+
"test:watch": "jest --watch",
|
|
125
|
+
"test:coverage": "jest --coverage",
|
|
126
|
+
"madge": "npx madge --circular --extensions ts app/"
|
|
139
127
|
}
|
|
140
|
-
}
|
|
128
|
+
}
|