emoji-picker-react 4.2.0 → 4.4.0-rc.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/README.md +24 -20
- package/dist/config/config.d.ts +5 -2
- package/dist/config/useConfig.d.ts +5 -3
- package/dist/emoji-picker-react.cjs.development.js +32 -8
- 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 +32 -8
- package/dist/emoji-picker-react.esm.js.map +1 -1
- package/dist/predicates/isFunction.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/main/PickerMain.tsx +3 -3
- package/src/config/config.ts +14 -9
- package/src/config/useConfig.ts +21 -4
- package/src/hooks/useDisallowedEmojis.ts +17 -4
- package/src/hooks/useFilter.ts +10 -9
- package/src/predicates/isFunction.ts +5 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function isFunction(value: any): value is (...args: any[]) => any;
|
package/package.json
CHANGED
|
@@ -37,15 +37,15 @@ function PickerRootElement({ children }: RootProps) {
|
|
|
37
37
|
useOnFocus();
|
|
38
38
|
|
|
39
39
|
const style = {
|
|
40
|
-
height
|
|
41
|
-
width
|
|
40
|
+
height,
|
|
41
|
+
width
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
return (
|
|
45
45
|
<aside
|
|
46
46
|
className={clsx(ClassNames.emojiPicker, 'epr-main', {
|
|
47
47
|
[ClassNames.searchActive]: searchModeActive,
|
|
48
|
-
'epr-dark-theme': theme === Theme.DARK
|
|
48
|
+
'epr-dark-theme': theme === Theme.DARK
|
|
49
49
|
})}
|
|
50
50
|
ref={PickerMainRef}
|
|
51
51
|
style={style}
|
package/src/config/config.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { GetEmojiUrl } from '../components/emoji/Emoji';
|
|
2
|
+
import { DataEmoji } from '../dataUtils/DataTypes';
|
|
2
3
|
import { emojiUrlByUnified } from '../dataUtils/emojiSelectors';
|
|
3
4
|
import {
|
|
4
5
|
EmojiClickData,
|
|
5
6
|
EmojiStyle,
|
|
6
7
|
SkinTones,
|
|
7
8
|
SuggestionMode,
|
|
8
|
-
Theme
|
|
9
|
+
Theme
|
|
9
10
|
} from '../types/exposedTypes';
|
|
10
11
|
|
|
11
12
|
import {
|
|
12
13
|
CategoriesConfig,
|
|
13
14
|
baseCategoriesConfig,
|
|
14
|
-
mergeCategoriesConfig
|
|
15
|
+
mergeCategoriesConfig
|
|
15
16
|
} from './categoryConfig';
|
|
16
17
|
|
|
17
18
|
export function mergeConfig(
|
|
@@ -26,13 +27,13 @@ export function mergeConfig(
|
|
|
26
27
|
const config = Object.assign(base, userConfig);
|
|
27
28
|
|
|
28
29
|
const categories = mergeCategoriesConfig(userConfig.categories, {
|
|
29
|
-
suggestionMode: config.suggestedEmojisMode
|
|
30
|
+
suggestionMode: config.suggestedEmojisMode
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
return {
|
|
33
34
|
...config,
|
|
34
35
|
categories,
|
|
35
|
-
previewConfig
|
|
36
|
+
previewConfig
|
|
36
37
|
};
|
|
37
38
|
}
|
|
38
39
|
|
|
@@ -55,13 +56,14 @@ export function basePickerConfig(): PickerConfigInternal {
|
|
|
55
56
|
event: MouseEvent
|
|
56
57
|
) {},
|
|
57
58
|
previewConfig: {
|
|
58
|
-
...basePreviewConfig
|
|
59
|
+
...basePreviewConfig
|
|
59
60
|
},
|
|
60
61
|
searchPlaceHolder: 'Search',
|
|
62
|
+
showEmoji: undefined,
|
|
61
63
|
skinTonesDisabled: false,
|
|
62
64
|
suggestedEmojisMode: SuggestionMode.FREQUENT,
|
|
63
65
|
theme: Theme.LIGHT,
|
|
64
|
-
width: 350
|
|
66
|
+
width: 350
|
|
65
67
|
};
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -78,9 +80,10 @@ export type PickerConfigInternal = {
|
|
|
78
80
|
suggestedEmojisMode: SuggestionMode;
|
|
79
81
|
lazyLoadEmojis: boolean;
|
|
80
82
|
previewConfig: PreviewConfig;
|
|
81
|
-
height:
|
|
82
|
-
width:
|
|
83
|
+
height: PickerDimensions;
|
|
84
|
+
width: PickerDimensions;
|
|
83
85
|
getEmojiUrl: GetEmojiUrl;
|
|
86
|
+
showEmoji: undefined | ((emoji: DataEmoji) => boolean);
|
|
84
87
|
};
|
|
85
88
|
|
|
86
89
|
export type PreviewConfig = {
|
|
@@ -92,7 +95,7 @@ export type PreviewConfig = {
|
|
|
92
95
|
const basePreviewConfig: PreviewConfig = {
|
|
93
96
|
defaultEmoji: '1f60a',
|
|
94
97
|
defaultCaption: "What's your mood?",
|
|
95
|
-
showPreview: true
|
|
98
|
+
showPreview: true
|
|
96
99
|
};
|
|
97
100
|
|
|
98
101
|
type ConfigExternal = {
|
|
@@ -100,3 +103,5 @@ type ConfigExternal = {
|
|
|
100
103
|
} & Omit<PickerConfigInternal, 'previewConfig'>;
|
|
101
104
|
|
|
102
105
|
export type PickerConfig = Partial<ConfigExternal>;
|
|
106
|
+
|
|
107
|
+
export type PickerDimensions = string | number;
|
package/src/config/useConfig.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { isSystemDarkTheme } from '../DomUtils/isDarkTheme';
|
|
2
2
|
import { usePickerConfig } from '../components/context/PickerConfigContext';
|
|
3
|
+
import { DataEmoji } from '../dataUtils/DataTypes';
|
|
3
4
|
import {
|
|
4
5
|
EmojiClickData,
|
|
5
6
|
EmojiStyle,
|
|
6
7
|
SkinTones,
|
|
7
8
|
SuggestionMode,
|
|
8
|
-
Theme
|
|
9
|
+
Theme
|
|
9
10
|
} from '../types/exposedTypes';
|
|
10
11
|
|
|
11
12
|
import { CategoriesConfig } from './categoryConfig';
|
|
12
|
-
import { PreviewConfig } from './config';
|
|
13
|
+
import { PickerDimensions, PreviewConfig } from './config';
|
|
13
14
|
|
|
14
15
|
export function useSearchPlaceHolderConfig(): string {
|
|
15
16
|
const { searchPlaceHolder } = usePickerConfig();
|
|
@@ -74,9 +75,12 @@ export function useLazyLoadEmojisConfig(): boolean {
|
|
|
74
75
|
return lazyLoadEmojis;
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
export function usePickerSizeConfig(): {
|
|
78
|
+
export function usePickerSizeConfig(): {
|
|
79
|
+
height: PickerDimensions;
|
|
80
|
+
width: PickerDimensions;
|
|
81
|
+
} {
|
|
78
82
|
const { height, width } = usePickerConfig();
|
|
79
|
-
return { height, width };
|
|
83
|
+
return { height: getDimension(height), width: getDimension(width) };
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
export function useEmojiVersionConfig(): string | null {
|
|
@@ -91,3 +95,16 @@ export function useGetEmojiUrlConfig(): (
|
|
|
91
95
|
const { getEmojiUrl } = usePickerConfig();
|
|
92
96
|
return getEmojiUrl;
|
|
93
97
|
}
|
|
98
|
+
|
|
99
|
+
export function useShowEmojiConfig():
|
|
100
|
+
| undefined
|
|
101
|
+
| ((emoji: DataEmoji) => boolean) {
|
|
102
|
+
const { showEmoji } = usePickerConfig();
|
|
103
|
+
return showEmoji;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getDimension(dimensionConfig: PickerDimensions): PickerDimensions {
|
|
107
|
+
return typeof dimensionConfig === 'number'
|
|
108
|
+
? `${dimensionConfig}px`
|
|
109
|
+
: dimensionConfig;
|
|
110
|
+
}
|
|
@@ -1,28 +1,41 @@
|
|
|
1
1
|
import { useRef, useMemo } from 'react';
|
|
2
2
|
|
|
3
|
-
import { useEmojiVersionConfig } from '../config/useConfig';
|
|
3
|
+
import { useEmojiVersionConfig, useShowEmojiConfig } from '../config/useConfig';
|
|
4
4
|
import { DataEmoji } from '../dataUtils/DataTypes';
|
|
5
5
|
import { addedIn, allEmojis, emojiUnified } from '../dataUtils/emojiSelectors';
|
|
6
|
+
import isFunction from '../predicates/isFunction';
|
|
6
7
|
|
|
7
8
|
export function useDisallowedEmojis() {
|
|
8
9
|
const DisallowedEmojisRef = useRef<Record<string, boolean>>({});
|
|
9
10
|
const emojiVersionConfig = useEmojiVersionConfig();
|
|
11
|
+
const shouldShowEmoji = useShowEmojiConfig();
|
|
10
12
|
|
|
11
13
|
return useMemo(() => {
|
|
12
14
|
const emojiVersion = parseFloat(`${emojiVersionConfig}`);
|
|
13
15
|
|
|
14
|
-
if (
|
|
16
|
+
if (
|
|
17
|
+
(!emojiVersionConfig || Number.isNaN(emojiVersion)) &&
|
|
18
|
+
!shouldShowEmoji
|
|
19
|
+
) {
|
|
15
20
|
return DisallowedEmojisRef.current;
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
return allEmojis.reduce((disallowedEmojis, emoji) => {
|
|
24
|
+
if (isFunction(shouldShowEmoji) && !shouldShowEmoji(emoji)) {
|
|
25
|
+
disallowEmoji();
|
|
26
|
+
}
|
|
27
|
+
|
|
19
28
|
if (addedInNewerVersion(emoji, emojiVersion)) {
|
|
20
|
-
|
|
29
|
+
disallowEmoji();
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
return disallowedEmojis;
|
|
33
|
+
|
|
34
|
+
function disallowEmoji() {
|
|
35
|
+
disallowedEmojis[emojiUnified(emoji)] = true;
|
|
36
|
+
}
|
|
24
37
|
}, DisallowedEmojisRef.current);
|
|
25
|
-
}, [emojiVersionConfig]);
|
|
38
|
+
}, [emojiVersionConfig, shouldShowEmoji]);
|
|
26
39
|
}
|
|
27
40
|
|
|
28
41
|
function addedInNewerVersion(
|
package/src/hooks/useFilter.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { scrollTo } from '../DomUtils/scrollTo';
|
|
2
2
|
import {
|
|
3
3
|
usePickerMainRef,
|
|
4
|
-
useSearchInputRef
|
|
4
|
+
useSearchInputRef
|
|
5
5
|
} from '../components/context/ElementRefContext';
|
|
6
6
|
import {
|
|
7
7
|
FilterState,
|
|
8
8
|
useFilterRef,
|
|
9
|
-
useSearchTermState
|
|
9
|
+
useSearchTermState
|
|
10
10
|
} from '../components/context/PickerContext';
|
|
11
11
|
import { DataEmoji } from '../dataUtils/DataTypes';
|
|
12
12
|
import { emojiNames } from '../dataUtils/emojiSelectors';
|
|
13
|
+
import isFunction from '../predicates/isFunction';
|
|
13
14
|
|
|
14
15
|
import { useFocusSearchInput } from './useFocus';
|
|
15
16
|
|
|
@@ -19,7 +20,7 @@ function useSetFilterRef() {
|
|
|
19
20
|
return function setFilter(
|
|
20
21
|
setter: FilterState | ((current: FilterState) => FilterState)
|
|
21
22
|
): void {
|
|
22
|
-
if (
|
|
23
|
+
if (isFunction(setter)) {
|
|
23
24
|
return setFilter(setter(filterRef.current));
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -67,7 +68,7 @@ export function useFilter() {
|
|
|
67
68
|
return {
|
|
68
69
|
onChange,
|
|
69
70
|
searchTerm,
|
|
70
|
-
SearchInputRef
|
|
71
|
+
SearchInputRef
|
|
71
72
|
};
|
|
72
73
|
|
|
73
74
|
function onChange(inputValue: string) {
|
|
@@ -87,9 +88,9 @@ export function useFilter() {
|
|
|
87
88
|
return applySearch(nextValue);
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
setFilterRef(
|
|
91
|
+
setFilterRef(current =>
|
|
91
92
|
Object.assign(current, {
|
|
92
|
-
[nextValue]: filterEmojiObjectByKeyword(longestMatch, nextValue)
|
|
93
|
+
[nextValue]: filterEmojiObjectByKeyword(longestMatch, nextValue)
|
|
93
94
|
})
|
|
94
95
|
);
|
|
95
96
|
applySearch(nextValue);
|
|
@@ -129,14 +130,14 @@ function filterEmojiObjectByKeyword(
|
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
function hasMatch(emoji: DataEmoji, keyword: string): boolean {
|
|
132
|
-
return emojiNames(emoji).some(
|
|
133
|
+
return emojiNames(emoji).some(name => name.includes(keyword));
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
export function useIsEmojiFiltered(): (unified: string) => boolean {
|
|
136
137
|
const { current: filter } = useFilterRef();
|
|
137
138
|
const [searchTerm] = useSearchTermState();
|
|
138
139
|
|
|
139
|
-
return
|
|
140
|
+
return unified => isEmojiFilteredBySearchTerm(unified, filter, searchTerm);
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
function isEmojiFilteredBySearchTerm(
|
|
@@ -167,7 +168,7 @@ function findLongestMatch(
|
|
|
167
168
|
|
|
168
169
|
const longestMatchingKey = Object.keys(dict)
|
|
169
170
|
.sort((a, b) => b.length - a.length)
|
|
170
|
-
.find(
|
|
171
|
+
.find(key => keyword.includes(key));
|
|
171
172
|
|
|
172
173
|
if (longestMatchingKey) {
|
|
173
174
|
return dict[longestMatchingKey];
|