emoji-picker-react 4.0.0-rc.10 → 4.0.0-rc.13
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/README.md +87 -44
- package/dist/DomUtils/isDarkTheme.d.ts +1 -0
- package/dist/components/context/PickerContext.d.ts +1 -0
- package/dist/config/config.d.ts +2 -2
- package/dist/config/useConfig.d.ts +3 -3
- package/dist/emoji-picker-react.cjs.development.js +42 -9
- package/dist/emoji-picker-react.cjs.development.js.map +1 -1
- package/dist/emoji-picker-react.cjs.production.min.js +1 -1
- package/dist/emoji-picker-react.cjs.production.min.js.map +1 -1
- package/dist/emoji-picker-react.esm.js +43 -10
- package/dist/emoji-picker-react.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/DomUtils/isDarkTheme.ts +7 -0
- package/src/components/body/RecentlyUsed.tsx +8 -2
- package/src/components/context/PickerContext.tsx +16 -0
- package/src/components/main/PickerMain.tsx +1 -1
- package/src/config/config.ts +9 -5
- package/src/config/useConfig.ts +15 -4
- package/src/dataUtils/recentlyUsed.ts +5 -7
- package/src/hooks/useMouseDownHandlers.ts +6 -3
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ An emoji picker component for React applications.
|
|
|
6
6
|
|
|
7
7
|
## What to know before using
|
|
8
8
|
|
|
9
|
-
- This package assumes it runs in the browser. I have taken many steps to prevent it from failing on the server, but still, it is recommended to only render the component on the client.
|
|
9
|
+
- This package assumes it runs in the browser. I have taken many steps to prevent it from failing on the server, but still, it is recommended to only render the component on the client. See troubleshooting section for more information.
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
@@ -14,6 +14,20 @@ An emoji picker component for React applications.
|
|
|
14
14
|
npm install emoji-picker-react
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
## Usage:
|
|
18
|
+
|
|
19
|
+
```jsx
|
|
20
|
+
import EmojiPicker from 'emoji-picker-react';
|
|
21
|
+
|
|
22
|
+
function App() {
|
|
23
|
+
return (
|
|
24
|
+
<div>
|
|
25
|
+
<EmojiPicker />
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
17
31
|
## Features
|
|
18
32
|
|
|
19
33
|
- Custom click handler
|
|
@@ -24,46 +38,47 @@ npm install emoji-picker-react
|
|
|
24
38
|
- Different emoji sets (Google, Apple, Facebook, Twitter)
|
|
25
39
|
- Native Emoji support
|
|
26
40
|
|
|
27
|
-
|
|
41
|
+
# Props
|
|
42
|
+
|
|
43
|
+
The following props are accepted by them picker:
|
|
28
44
|
|
|
29
|
-
-
|
|
45
|
+
- `onEmojiClick`: `(emojiData: EmojiClickData, event: MouseEvent) => void` - Callback function when an emoji is clicked. The callback receives the event and the emoji data. The emoji data is comprised of the following properties:
|
|
30
46
|
|
|
31
|
-
```ts
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
```ts
|
|
48
|
+
{
|
|
49
|
+
activeSkinTone: SkinTones;
|
|
50
|
+
unified: string;
|
|
51
|
+
unifiedWithoutSkinTone: string;
|
|
52
|
+
emoji: string;
|
|
53
|
+
names: string[];
|
|
54
|
+
getImageUrl: (emojiStyle: EmojiStyle) => string;
|
|
38
55
|
}
|
|
39
56
|
```
|
|
40
57
|
|
|
41
|
-
-
|
|
58
|
+
- `theme`: `Theme` - The theme of the picker. Can be `light`, `dark` or auto. Default is `light`.
|
|
42
59
|
The `Theme` enum can be imported from the package.
|
|
43
60
|
|
|
44
61
|
```ts
|
|
45
62
|
import { Theme } from 'emoji-picker-react';
|
|
46
63
|
```
|
|
47
64
|
|
|
48
|
-
-
|
|
65
|
+
- `emojiStyle`: `EmojiStyle` - The emoji style to use. Can be either `apple`, `google`, `facebook`, `twitter` or `native`. Default is `apple`.
|
|
49
66
|
The `EmojiStyle` enum can be imported from the package.
|
|
50
67
|
|
|
51
68
|
```ts
|
|
52
69
|
import { EmojiStyle } from 'emoji-picker-react';
|
|
53
70
|
```
|
|
54
71
|
|
|
55
|
-
*
|
|
72
|
+
* `autoFocusSearch`: `boolean` - Whether to focus the search input on mount. Defaults to `true`.
|
|
56
73
|
|
|
57
|
-
*
|
|
74
|
+
* `defaultSkinTone`: `SkinTones` - The default skin tone to use when an emoji is clicked. Defaults to `SkinTones.Neutral`. Possible skin tones are:
|
|
58
75
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
✋🏿 DARK = '1f3ff'
|
|
66
|
-
```
|
|
76
|
+
- ✋ 'neutral'
|
|
77
|
+
- ✋🏻 '1f3fb'
|
|
78
|
+
- ✋🏼 '1f3fc'
|
|
79
|
+
- ✋🏽 '1f3fd'
|
|
80
|
+
- ✋🏾 '1f3fe'
|
|
81
|
+
- ✋🏿 '1f3ff'
|
|
67
82
|
|
|
68
83
|
The skin tones typescript enum can be imported directly from the package:
|
|
69
84
|
|
|
@@ -71,35 +86,63 @@ The skin tones typescript enum can be imported directly from the package:
|
|
|
71
86
|
import { SkinTones } from 'emoji-picker-react';
|
|
72
87
|
```
|
|
73
88
|
|
|
74
|
-
-
|
|
89
|
+
- `skinTonesDisabled`: `boolean` - Whether to disable the skin tone selection. Defaults to `false`.
|
|
75
90
|
|
|
76
|
-
-
|
|
91
|
+
- `showPreview`: `boolean` - Whether to show the preview of the selected emoji. Defaults to `true`.
|
|
77
92
|
|
|
78
|
-
-
|
|
93
|
+
- `searchPlaceholder`: `string` - The placeholder text for the search input. Defaults to `Search`.
|
|
79
94
|
|
|
80
95
|
- categories: Allows full config over ordering, naming and display of categories.
|
|
81
96
|
To only sort/omit categories, you can simply pass an array of category names to display:
|
|
82
97
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
- 'recently_used',
|
|
99
|
+
- 'smileys_people',
|
|
100
|
+
- 'animals_nature',
|
|
101
|
+
- 'food_drink',
|
|
102
|
+
- 'travel_places',
|
|
103
|
+
- 'activities',
|
|
104
|
+
- 'objects',
|
|
105
|
+
- 'symbols',
|
|
106
|
+
- 'flags'
|
|
107
|
+
|
|
108
|
+
For a more in-depth configuration, you can pass an array with category config:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
[
|
|
112
|
+
{
|
|
113
|
+
category: 'recently_used',
|
|
114
|
+
name: 'Recently Used'
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
category: 'smileys_people',
|
|
118
|
+
name: 'Faces...'
|
|
119
|
+
}
|
|
120
|
+
];
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
# Troubleshooting
|
|
124
|
+
|
|
125
|
+
## Next.js
|
|
126
|
+
|
|
127
|
+
To avoid errors such as "document is not defined" on the server side, you should make sure the library is only imported on the client side. Here is how to do that:
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
import dynamic from 'next/dynamic';
|
|
131
|
+
|
|
132
|
+
const Picker = dynamic(
|
|
133
|
+
() => {
|
|
134
|
+
return import('emoji-picker-react');
|
|
135
|
+
},
|
|
136
|
+
{ ssr: false }
|
|
137
|
+
);
|
|
93
138
|
```
|
|
94
139
|
|
|
95
|
-
|
|
140
|
+
## Vite
|
|
96
141
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
name: "Faces...";
|
|
104
|
-
}]
|
|
142
|
+
For reference, if you only need to shim global, you can add
|
|
143
|
+
|
|
144
|
+
```html
|
|
145
|
+
<script>
|
|
146
|
+
window.global = window;
|
|
147
|
+
</script>
|
|
105
148
|
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isSystemDarkTheme(): boolean;
|
|
@@ -16,6 +16,7 @@ export declare function useEmojisThatFailedToLoadState(): ReactState<Set<string>
|
|
|
16
16
|
export declare function useIsPastInitialLoad(): boolean;
|
|
17
17
|
export declare function useEmojiVariationPickerState(): ReactState<DataEmoji | null>;
|
|
18
18
|
export declare function useSkinToneFanOpenState(): ReactState<boolean>;
|
|
19
|
+
export declare function useUpdateRecentlyUsed(): [number, () => void];
|
|
19
20
|
export declare type FilterState = Record<string, FilterDict>;
|
|
20
21
|
declare type ActiveCategoryState = null | string;
|
|
21
22
|
export {};
|
package/dist/config/config.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare function mergeConfig(userConfig?: PickerConfig): {
|
|
|
7
7
|
skinTonesDisabled: boolean;
|
|
8
8
|
autoFocusSearch: boolean;
|
|
9
9
|
emojiStyle: EmojiStyle;
|
|
10
|
-
onEmojiClick: (
|
|
10
|
+
onEmojiClick: (emoji: EmojiClickData, event: MouseEvent) => void;
|
|
11
11
|
showPreview: boolean;
|
|
12
12
|
theme: Theme;
|
|
13
13
|
};
|
|
@@ -19,7 +19,7 @@ export declare type PickerConfigInternal = {
|
|
|
19
19
|
autoFocusSearch: boolean;
|
|
20
20
|
emojiStyle: EmojiStyle;
|
|
21
21
|
categories: CategoriesConfig;
|
|
22
|
-
onEmojiClick: (
|
|
22
|
+
onEmojiClick: (emoji: EmojiClickData, event: MouseEvent) => void;
|
|
23
23
|
showPreview: boolean;
|
|
24
24
|
theme: Theme;
|
|
25
25
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EmojiClickData, EmojiStyle, SkinTones } from '../types/exposedTypes';
|
|
1
|
+
import { EmojiClickData, EmojiStyle, SkinTones, Theme } from '../types/exposedTypes';
|
|
2
2
|
import { CategoriesConfig } from './categoryConfig';
|
|
3
3
|
export declare function useSearchPlaceHolderConfig(): string;
|
|
4
4
|
export declare function useDefaultSkinToneConfig(): SkinTones;
|
|
@@ -6,6 +6,6 @@ export declare function useSkinTonesDisabledConfig(): boolean;
|
|
|
6
6
|
export declare function useEmojiStyleConfig(): EmojiStyle;
|
|
7
7
|
export declare function useAutoFocusSearchConfig(): boolean;
|
|
8
8
|
export declare function useCategoriesConfig(): CategoriesConfig;
|
|
9
|
-
export declare function useOnEmojiClickConfig(): (
|
|
9
|
+
export declare function useOnEmojiClickConfig(): (emoji: EmojiClickData, event: MouseEvent) => void;
|
|
10
10
|
export declare function useShowPreviewConfig(): boolean;
|
|
11
|
-
export declare function useThemeConfig():
|
|
11
|
+
export declare function useThemeConfig(): Theme;
|
|
@@ -200,8 +200,8 @@ function basePickerConfig() {
|
|
|
200
200
|
defaultSkinTone: exports.SkinTones.NEUTRAL,
|
|
201
201
|
emojiStyle: exports.EmojiStyle.APPLE,
|
|
202
202
|
onEmojiClick: function defaultOnClickHandler( // @ts-ignore
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
emoji, // @ts-ignore
|
|
204
|
+
event) {},
|
|
205
205
|
searchPlaceHolder: 'Search',
|
|
206
206
|
showPreview: true,
|
|
207
207
|
skinTonesDisabled: false,
|
|
@@ -223,6 +223,14 @@ function usePickerConfig() {
|
|
|
223
223
|
return React.useContext(ConfigContext);
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
function isSystemDarkTheme() {
|
|
227
|
+
if (typeof window === 'undefined') {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return !!window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
232
|
+
}
|
|
233
|
+
|
|
226
234
|
function useSearchPlaceHolderConfig() {
|
|
227
235
|
var _usePickerConfig = usePickerConfig(),
|
|
228
236
|
searchPlaceHolder = _usePickerConfig.searchPlaceHolder;
|
|
@@ -275,6 +283,10 @@ function useThemeConfig() {
|
|
|
275
283
|
var _usePickerConfig9 = usePickerConfig(),
|
|
276
284
|
theme = _usePickerConfig9.theme;
|
|
277
285
|
|
|
286
|
+
if (theme === exports.Theme.AUTO) {
|
|
287
|
+
return isSystemDarkTheme() ? exports.Theme.DARK : exports.Theme.LIGHT;
|
|
288
|
+
}
|
|
289
|
+
|
|
278
290
|
return theme;
|
|
279
291
|
}
|
|
280
292
|
|
|
@@ -15474,6 +15486,7 @@ function PickerContextProvider(_ref) {
|
|
|
15474
15486
|
|
|
15475
15487
|
var filterRef = React.useRef(alphaNumericEmojiIndex);
|
|
15476
15488
|
var disallowClickRef = React.useRef(false);
|
|
15489
|
+
var recentlyUsedUpdateState = useDebouncedState(Date.now(), 250);
|
|
15477
15490
|
var searchTerm = useDebouncedState('', 100);
|
|
15478
15491
|
var skinToneFanOpenState = React.useState(false);
|
|
15479
15492
|
var activeSkinTone = React.useState(defaultSkinTone);
|
|
@@ -15488,6 +15501,7 @@ function PickerContextProvider(_ref) {
|
|
|
15488
15501
|
useMarkInitialLoad(setIsPastInitialLoad);
|
|
15489
15502
|
return React.createElement(PickerContext.Provider, {
|
|
15490
15503
|
value: {
|
|
15504
|
+
recentlyUsedUpdateState: recentlyUsedUpdateState,
|
|
15491
15505
|
filterRef: filterRef,
|
|
15492
15506
|
searchTerm: searchTerm,
|
|
15493
15507
|
activeCategoryState: activeCategoryState,
|
|
@@ -15501,6 +15515,7 @@ function PickerContextProvider(_ref) {
|
|
|
15501
15515
|
}, children);
|
|
15502
15516
|
}
|
|
15503
15517
|
var PickerContext = /*#__PURE__*/React.createContext({
|
|
15518
|
+
recentlyUsedUpdateState: [/*#__PURE__*/Date.now(), function () {}],
|
|
15504
15519
|
searchTerm: ['', function () {}],
|
|
15505
15520
|
activeCategoryState: [null, function () {}],
|
|
15506
15521
|
activeSkinTone: [exports.SkinTones.NEUTRAL, function () {}],
|
|
@@ -15581,6 +15596,16 @@ function useSkinToneFanOpenState() {
|
|
|
15581
15596
|
|
|
15582
15597
|
return skinToneFanOpenState;
|
|
15583
15598
|
}
|
|
15599
|
+
function useUpdateRecentlyUsed() {
|
|
15600
|
+
var _React$useContext10 = React.useContext(PickerContext),
|
|
15601
|
+
recentlyUsedUpdateState = _React$useContext10.recentlyUsedUpdateState;
|
|
15602
|
+
|
|
15603
|
+
var recentlyUsedUpdated = recentlyUsedUpdateState[0],
|
|
15604
|
+
setRecentlyUsedUpdate = recentlyUsedUpdateState[1];
|
|
15605
|
+
return [recentlyUsedUpdated, function updateRecentlyUsed() {
|
|
15606
|
+
setRecentlyUsedUpdate(Date.now());
|
|
15607
|
+
}];
|
|
15608
|
+
}
|
|
15584
15609
|
|
|
15585
15610
|
function useActiveCategoryScrollDetection(bodyRef) {
|
|
15586
15611
|
var _useActiveCategorySta = useActiveCategoryState(),
|
|
@@ -15755,11 +15780,9 @@ function setRecentlyUsed(emoji, skinTone) {
|
|
|
15755
15780
|
nextList.length = Math.min(nextList.length, 14);
|
|
15756
15781
|
|
|
15757
15782
|
try {
|
|
15758
|
-
|
|
15759
|
-
var _window3;
|
|
15783
|
+
var _window3;
|
|
15760
15784
|
|
|
15761
|
-
|
|
15762
|
-
}, 10);
|
|
15785
|
+
(_window3 = window) == null ? void 0 : _window3.localStorage.setItem(RECENTLY_USED_LS_KEY, JSON.stringify(nextList)); // Prevents the change from being seen immediately.
|
|
15763
15786
|
} catch (_unused2) {// ignore
|
|
15764
15787
|
}
|
|
15765
15788
|
}
|
|
@@ -15826,6 +15849,10 @@ function useMouseDownHandlers(BodyRef) {
|
|
|
15826
15849
|
|
|
15827
15850
|
var onEmojiClick = useOnEmojiClickConfig();
|
|
15828
15851
|
var emojiStyle = useEmojiStyleConfig();
|
|
15852
|
+
|
|
15853
|
+
var _useUpdateRecentlyUse = useUpdateRecentlyUsed(),
|
|
15854
|
+
updateRecentlyUsed = _useUpdateRecentlyUse[1];
|
|
15855
|
+
|
|
15829
15856
|
React.useEffect(function () {
|
|
15830
15857
|
if (!BodyRef.current) {
|
|
15831
15858
|
return;
|
|
@@ -15862,8 +15889,9 @@ function useMouseDownHandlers(BodyRef) {
|
|
|
15862
15889
|
|
|
15863
15890
|
var unified = emojiUnified(emoji);
|
|
15864
15891
|
var skinToneToUse = activeVariationFromUnified(unified) || activeSkinTone;
|
|
15892
|
+
updateRecentlyUsed();
|
|
15865
15893
|
setRecentlyUsed(emoji, skinToneToUse);
|
|
15866
|
-
onEmojiClick(
|
|
15894
|
+
onEmojiClick(emojiClickOutput(emoji, skinToneToUse), event);
|
|
15867
15895
|
}
|
|
15868
15896
|
|
|
15869
15897
|
function onMouseDown(event) {
|
|
@@ -15892,7 +15920,7 @@ function useMouseDownHandlers(BodyRef) {
|
|
|
15892
15920
|
closeAllOpenToggles();
|
|
15893
15921
|
setAnchoredEmojiRef(event.target);
|
|
15894
15922
|
setEmojiVariationPicker(emoji);
|
|
15895
|
-
},
|
|
15923
|
+
}, 500);
|
|
15896
15924
|
}
|
|
15897
15925
|
|
|
15898
15926
|
function onMouseUp() {
|
|
@@ -16252,10 +16280,15 @@ function EmojiCategory(_ref) {
|
|
|
16252
16280
|
function RecentlyUsed(_ref) {
|
|
16253
16281
|
var categoryConfig = _ref.categoryConfig;
|
|
16254
16282
|
|
|
16283
|
+
var _useUpdateRecentlyUse = useUpdateRecentlyUsed(),
|
|
16284
|
+
recentlyUsedUpdated = _useUpdateRecentlyUse[0];
|
|
16285
|
+
|
|
16255
16286
|
var _useSearchTermState = useSearchTermState(),
|
|
16256
16287
|
searchTerm = _useSearchTermState[0];
|
|
16257
16288
|
|
|
16258
|
-
var recentlyUsed =
|
|
16289
|
+
var recentlyUsed = React.useMemo(function () {
|
|
16290
|
+
return getRecentlyUsed();
|
|
16291
|
+
}, [recentlyUsedUpdated]);
|
|
16259
16292
|
var emojiStyle = useEmojiStyleConfig();
|
|
16260
16293
|
|
|
16261
16294
|
if (searchTerm) {
|