emoji-picker-react 3.6.1 → 4.0.0-rc.3
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/LICENSE +17 -20
- package/README.md +129 -168
- package/dist/DomUtils/categoryNameFromDom.d.ts +1 -0
- package/dist/DomUtils/scrollCategoryIntoView.d.ts +1 -0
- package/dist/DomUtils/scrollTo.d.ts +1 -0
- package/dist/DomUtils/selectors.d.ts +12 -0
- package/dist/components/Layout/Flex.d.ts +14 -0
- package/dist/components/Layout/Relative.d.ts +7 -0
- package/dist/components/body/Body.d.ts +3 -0
- package/dist/components/body/EmojiCategory.d.ts +10 -0
- package/dist/components/body/EmojiList.d.ts +3 -0
- package/dist/components/body/EmojiVariationPicker.d.ts +3 -0
- package/dist/components/body/RecentlyUsed.d.ts +7 -0
- package/dist/components/context/ElementRefContext.d.ts +17 -0
- package/dist/components/context/PickerConfigContext.d.ts +8 -0
- package/dist/components/context/PickerContext.d.ts +21 -0
- package/dist/components/emoji/Emoji.d.ts +14 -0
- package/dist/components/footer/Preview.d.ts +7 -0
- package/dist/components/header/Header.d.ts +3 -0
- package/dist/components/header/Search.d.ts +3 -0
- package/dist/components/header/SkinTonePicker.d.ts +3 -0
- package/dist/components/main/PickerMain.d.ts +7 -0
- package/dist/components/navigation/CategoryNavigation.d.ts +3 -0
- package/dist/config/categoryConfig.d.ts +21 -0
- package/dist/config/cdnUrls.d.ts +2 -0
- package/dist/config/config.d.ts +26 -0
- package/dist/config/useConfig.d.ts +11 -0
- package/dist/data/emojis.d.ts +40 -0
- package/dist/data/groups.d.ts +2 -0
- package/dist/data/skinToneVariations.d.ts +3 -0
- package/dist/dataUtils/DataTypes.d.ts +8 -0
- package/dist/dataUtils/alphaNumericEmojiIndex.d.ts +4 -0
- package/dist/dataUtils/asEmoji.d.ts +2 -0
- package/dist/dataUtils/emojiSelectors.d.ts +15 -0
- package/dist/dataUtils/parseNativeEmoji.d.ts +1 -0
- package/dist/dataUtils/recentlyUsed.d.ts +11 -0
- package/dist/emoji-picker-react.cjs.development.css +13 -0
- package/dist/emoji-picker-react.cjs.development.js +7419 -0
- package/dist/emoji-picker-react.cjs.development.js.map +1 -0
- package/dist/emoji-picker-react.cjs.production.min.js +2 -0
- package/dist/emoji-picker-react.cjs.production.min.js.map +1 -0
- package/dist/emoji-picker-react.esm.js +7485 -0
- package/dist/emoji-picker-react.esm.js.map +1 -0
- package/dist/hooks/preloadEmoji.d.ts +4 -0
- package/dist/hooks/useActiveCategoryScrollDetection.d.ts +2 -0
- package/dist/hooks/useCloseAllOpenToggles.d.ts +4 -0
- package/dist/hooks/useEmojiElements.d.ts +1 -0
- package/dist/hooks/useEmojiMouseEnter.d.ts +3 -0
- package/dist/hooks/useFilter.d.ts +8 -0
- package/dist/hooks/useInitialLoad.d.ts +2 -0
- package/dist/hooks/useIsEmojiHidden.d.ts +2 -0
- package/dist/hooks/useIsSearchMode.d.ts +1 -0
- package/dist/hooks/useMouseDownHandlers.d.ts +2 -0
- package/dist/hooks/useOnScroll.d.ts +2 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +8 -3
- package/dist/types/exposedTypes.d.ts +28 -0
- package/package.json +72 -52
- package/src/DomUtils/categoryNameFromDom.ts +3 -0
- package/src/DomUtils/scrollCategoryIntoView.ts +18 -0
- package/src/DomUtils/scrollTo.ts +11 -0
- package/src/DomUtils/selectors.ts +93 -0
- package/src/EmojiPickerReact.css +85 -0
- package/src/components/Layout/Flex.css +11 -0
- package/src/components/Layout/Flex.tsx +28 -0
- package/src/components/Layout/Relative.tsx +14 -0
- package/src/components/body/Body.css +6 -0
- package/src/components/body/Body.tsx +24 -0
- package/src/components/body/EmojiCategory.css +38 -0
- package/src/components/body/EmojiCategory.tsx +27 -0
- package/src/components/body/EmojiList.css +5 -0
- package/src/components/body/EmojiList.tsx +101 -0
- package/src/components/body/EmojiVariationPicker.css +65 -0
- package/src/components/body/EmojiVariationPicker.tsx +154 -0
- package/src/components/body/RecentlyUsed.tsx +50 -0
- package/src/components/body/svg/triangle.svg +11 -0
- package/src/components/context/ElementRefContext.tsx +61 -0
- package/src/components/context/PickerConfigContext.tsx +29 -0
- package/src/components/context/PickerContext.tsx +139 -0
- package/src/components/emoji/Emoji.css +44 -0
- package/src/components/emoji/Emoji.tsx +104 -0
- package/src/components/footer/Preview.css +14 -0
- package/src/components/footer/Preview.tsx +80 -0
- package/src/components/header/Header.css +4 -0
- package/src/components/header/Header.tsx +21 -0
- package/src/components/header/Search.css +72 -0
- package/src/components/header/Search.tsx +36 -0
- package/src/components/header/SkinTonePicker.css +86 -0
- package/src/components/header/SkinTonePicker.tsx +55 -0
- package/src/components/header/svg/magnifier.svg +13 -0
- package/src/components/header/svg/times.svg +33 -0
- package/src/components/main/PickerMain.css +11 -0
- package/src/components/main/PickerMain.tsx +42 -0
- package/src/components/navigation/CategoryNavigation.css +82 -0
- package/src/components/navigation/CategoryNavigation.tsx +32 -0
- package/src/components/navigation/svg/CategoryNav.svg +508 -0
- package/src/config/categoryConfig.ts +107 -0
- package/src/config/cdnUrls.ts +24 -0
- package/src/config/config.ts +50 -0
- package/src/config/useConfig.ts +52 -0
- package/src/data/emojis.ts +5350 -0
- package/src/data/groups.ts +12 -0
- package/src/data/skinToneVariations.ts +12 -0
- package/src/dataUtils/DataTypes.ts +10 -0
- package/src/dataUtils/alphaNumericEmojiIndex.ts +23 -0
- package/src/dataUtils/asEmoji.ts +5 -0
- package/src/dataUtils/emojiSelectors.ts +94 -0
- package/src/dataUtils/parseNativeEmoji.ts +6 -0
- package/src/dataUtils/recentlyUsed.ts +61 -0
- package/src/hooks/preloadEmoji.ts +29 -0
- package/src/hooks/useActiveCategoryScrollDetection.ts +46 -0
- package/src/hooks/useCloseAllOpenToggles.ts +26 -0
- package/src/hooks/useEmojiElements.ts +7 -0
- package/src/hooks/useEmojiMouseEnter.ts +59 -0
- package/src/hooks/useFilter.ts +142 -0
- package/src/hooks/useInitialLoad.ts +9 -0
- package/src/hooks/useIsEmojiHidden.ts +16 -0
- package/src/hooks/useIsSearchMode.ts +7 -0
- package/src/hooks/useMouseDownHandlers.ts +160 -0
- package/src/hooks/useOnScroll.ts +28 -0
- package/src/index.tsx +27 -0
- package/src/types/exposedTypes.ts +31 -0
- package/.babelrc +0 -30
- package/.eslintrc.js +0 -37
- package/.github/workflows/npmpublish.yml +0 -30
- package/.prettierignore +0 -2
- package/.storybook/addons.js +0 -2
- package/.storybook/config.js +0 -9
- package/assets/captured.gif +0 -0
- package/dist/index.js.LICENSE.txt +0 -5
- package/dist/index.js.map +0 -1
- package/dist/main.css +0 -206
- package/dist/main.css.map +0 -1
- package/emoji-picker-react.d.ts +0 -45
- package/webpack.config.js +0 -52
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
useEmojiStyleConfig,
|
|
6
|
+
useShowPreviewConfig
|
|
7
|
+
} from '../../config/useConfig';
|
|
8
|
+
import { asEmoji } from '../../dataUtils/asEmoji';
|
|
9
|
+
import {
|
|
10
|
+
emojiByUnified,
|
|
11
|
+
emojiName,
|
|
12
|
+
emojiUnified
|
|
13
|
+
} from '../../dataUtils/emojiSelectors';
|
|
14
|
+
import { useEmojiMouseEnter } from '../../hooks/useEmojiMouseEnter';
|
|
15
|
+
import Flex from '../Layout/Flex';
|
|
16
|
+
import { Emoji } from '../emoji/Emoji';
|
|
17
|
+
import './Preview.css';
|
|
18
|
+
|
|
19
|
+
export function Preview() {
|
|
20
|
+
const showPreview = useShowPreviewConfig();
|
|
21
|
+
const [hoveredEmoji, setHoveredEmoji] = useState<HoveredEmoji>(null);
|
|
22
|
+
const emojiStyle = useEmojiStyleConfig();
|
|
23
|
+
useEmojiMouseEnter(showPreview, setHoveredEmoji);
|
|
24
|
+
|
|
25
|
+
if (!showPreview) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const emoji = emojiByUnified(hoveredEmoji?.originalUnified);
|
|
30
|
+
|
|
31
|
+
const show = emoji != null && hoveredEmoji != null;
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Flex className="epr-preview">
|
|
35
|
+
<PreviewContent />
|
|
36
|
+
</Flex>
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
function PreviewContent() {
|
|
40
|
+
const defaultEmoji = asEmoji(emojiByUnified('1f60a'));
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<>
|
|
44
|
+
<div>
|
|
45
|
+
{show ? (
|
|
46
|
+
<Emoji
|
|
47
|
+
unified={hoveredEmoji?.unified as string}
|
|
48
|
+
emoji={asEmoji(emoji)}
|
|
49
|
+
showVariations={false}
|
|
50
|
+
emojiStyle={emojiStyle}
|
|
51
|
+
hidden={false}
|
|
52
|
+
size={45}
|
|
53
|
+
/>
|
|
54
|
+
) : (
|
|
55
|
+
<Emoji
|
|
56
|
+
unified={emojiUnified(defaultEmoji)}
|
|
57
|
+
emoji={defaultEmoji}
|
|
58
|
+
showVariations={false}
|
|
59
|
+
emojiStyle={emojiStyle}
|
|
60
|
+
hidden={false}
|
|
61
|
+
size={45}
|
|
62
|
+
/>
|
|
63
|
+
)}
|
|
64
|
+
</div>
|
|
65
|
+
{show ? (
|
|
66
|
+
<div className="epr-preview-emoji-label">
|
|
67
|
+
{emojiName(asEmoji(emoji))}
|
|
68
|
+
</div>
|
|
69
|
+
) : (
|
|
70
|
+
<div className="epr-preview-emoji-label">What's your mood?</div>
|
|
71
|
+
)}
|
|
72
|
+
</>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type HoveredEmoji = null | {
|
|
78
|
+
unified: string;
|
|
79
|
+
originalUnified: string;
|
|
80
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import Flex from '../Layout/Flex';
|
|
4
|
+
import Relative from '../Layout/Relative';
|
|
5
|
+
import { CategoryNavigation } from '../navigation/CategoryNavigation';
|
|
6
|
+
|
|
7
|
+
import { Search } from './Search';
|
|
8
|
+
import { SkinTonePicker } from './SkinTonePicker';
|
|
9
|
+
import './Header.css';
|
|
10
|
+
|
|
11
|
+
export function Header() {
|
|
12
|
+
return (
|
|
13
|
+
<Relative className="epr-header">
|
|
14
|
+
<Flex className="epr-header-overlay">
|
|
15
|
+
<Search />
|
|
16
|
+
<SkinTonePicker />
|
|
17
|
+
</Flex>
|
|
18
|
+
<CategoryNavigation />
|
|
19
|
+
</Relative>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
.EmojiPickerReact .epr-search-container {
|
|
2
|
+
flex: 1;
|
|
3
|
+
display: block;
|
|
4
|
+
min-width: 0;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.EmojiPickerReact .epr-search-container input.epr-search {
|
|
8
|
+
outline: none;
|
|
9
|
+
transition: all 0.2s ease-in-out;
|
|
10
|
+
color: var(--epr-search-bar-text-color);
|
|
11
|
+
border-radius: var(--epr-search-input-border-radius);
|
|
12
|
+
padding: var(--epr-search-input-padding);
|
|
13
|
+
height: var(--epr-search-input-height);
|
|
14
|
+
background-color: var(--epr-search-bar-bg-color);
|
|
15
|
+
border: 1px solid var(--epr-search-bar-bg-color);
|
|
16
|
+
width: 100%;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.EmojiPickerReact .epr-search-container button.epr-btn-clear-search {
|
|
20
|
+
background-image: svg-load(./svg/times.svg);
|
|
21
|
+
height: 20px;
|
|
22
|
+
width: 20px;
|
|
23
|
+
background-color: transparent;
|
|
24
|
+
background-repeat: no-repeat;
|
|
25
|
+
position: absolute;
|
|
26
|
+
top: 50%;
|
|
27
|
+
right: 10px;
|
|
28
|
+
transform: translateY(-50%);
|
|
29
|
+
background-size: 20px;
|
|
30
|
+
}
|
|
31
|
+
.EmojiPickerReact .epr-search-container button.epr-btn-clear-search:hover {
|
|
32
|
+
background-position-y: -20px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.EmojiPickerReact..epr-dark-theme
|
|
36
|
+
.epr-search-container
|
|
37
|
+
button.epr-btn-clear-search {
|
|
38
|
+
background-position-y: -40px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.EmojiPickerReact..epr-dark-theme
|
|
42
|
+
.epr-search-container
|
|
43
|
+
button.epr-btn-clear-search:hover {
|
|
44
|
+
background-position-y: -60px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.EmojiPickerReact .epr-search-container .epr-icn-search {
|
|
48
|
+
content: '';
|
|
49
|
+
position: absolute;
|
|
50
|
+
top: 50%;
|
|
51
|
+
left: 10px;
|
|
52
|
+
transform: translateY(-50%);
|
|
53
|
+
width: 20px;
|
|
54
|
+
height: 20px;
|
|
55
|
+
background-image: svg-load(./svg/magnifier.svg);
|
|
56
|
+
background-repeat: no-repeat;
|
|
57
|
+
background-position: 0 0;
|
|
58
|
+
background-size: 20px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.EmojiPickerReact.epr-dark-theme .epr-search-container .epr-icn-search {
|
|
62
|
+
background-position-y: -20px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.EmojiPickerReact .epr-search-container input.epr-search::placeholder {
|
|
66
|
+
color: var(--epr-search-bar-placeholder-color);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.EmojiPickerReact .epr-search-container input.epr-search:focus {
|
|
70
|
+
background-color: var(--epr-search-bar-bg-color-active);
|
|
71
|
+
border: 1px solid var(--epr-search-border-color);
|
|
72
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
useAutoFocusSearchConfig,
|
|
5
|
+
useSearchPlaceHolderConfig
|
|
6
|
+
} from '../../config/useConfig';
|
|
7
|
+
import { useCloseAllOpenToggles } from '../../hooks/useCloseAllOpenToggles';
|
|
8
|
+
import { useFilter } from '../../hooks/useFilter';
|
|
9
|
+
import Relative from '../Layout/Relative';
|
|
10
|
+
import './Search.css';
|
|
11
|
+
|
|
12
|
+
export function Search() {
|
|
13
|
+
const { closeAllOpenToggles } = useCloseAllOpenToggles();
|
|
14
|
+
|
|
15
|
+
const placeholder = useSearchPlaceHolderConfig();
|
|
16
|
+
const autoFocus = useAutoFocusSearchConfig();
|
|
17
|
+
const { onChange, searchTerm, clearSearch } = useFilter();
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Relative className="epr-search-container">
|
|
21
|
+
<input
|
|
22
|
+
autoFocus={autoFocus}
|
|
23
|
+
onFocus={closeAllOpenToggles}
|
|
24
|
+
className="epr-search"
|
|
25
|
+
type="text"
|
|
26
|
+
placeholder={placeholder}
|
|
27
|
+
onChange={event => onChange(event.target.value)}
|
|
28
|
+
value={searchTerm}
|
|
29
|
+
/>
|
|
30
|
+
<div className="epr-icn-search" />
|
|
31
|
+
{searchTerm ? (
|
|
32
|
+
<button className="epr-btn-clear-search" onClick={clearSearch} />
|
|
33
|
+
) : null}
|
|
34
|
+
</Relative>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
.EmojiPickerReact .epr-skin-tones {
|
|
2
|
+
/* margin: 0 5px 0 15px; */
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
justify-content: flex-end;
|
|
6
|
+
transition: all 0.3s ease-in-out;
|
|
7
|
+
flex-basis: 30px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.EmojiPickerReact .epr-skin-tones.open {
|
|
11
|
+
flex-basis: 170px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.EmojiPickerReact .epr-skin-tone-select {
|
|
15
|
+
position: relative;
|
|
16
|
+
width: 16px;
|
|
17
|
+
height: 16px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.EmojiPickerReact .epr-skin-tones.open .epr-tone {
|
|
21
|
+
transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.EmojiPickerReact .epr-skin-tones:not(.open) .epr-tone {
|
|
25
|
+
z-index: 0;
|
|
26
|
+
opacity: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone.active {
|
|
30
|
+
z-index: 1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone {
|
|
34
|
+
display: block;
|
|
35
|
+
cursor: pointer;
|
|
36
|
+
border-radius: 4px;
|
|
37
|
+
height: 100%;
|
|
38
|
+
width: 100%;
|
|
39
|
+
position: absolute;
|
|
40
|
+
right: 0;
|
|
41
|
+
transition: transform 0.3s ease-in-out, opacity 0.5s ease-in-out;
|
|
42
|
+
z-index: 1;
|
|
43
|
+
box-shadow: 0 0 0 0px var(--epr-active-skin-hover-color);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone:hover {
|
|
47
|
+
box-shadow: 0 0 0 5px var(--epr-active-skin-hover-color);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.EmojiPickerReact
|
|
51
|
+
.epr-skin-tones.open
|
|
52
|
+
.epr-skin-tone-select
|
|
53
|
+
.epr-tone.active:after {
|
|
54
|
+
content: '';
|
|
55
|
+
position: absolute;
|
|
56
|
+
top: -2px;
|
|
57
|
+
left: -2px;
|
|
58
|
+
right: -2px;
|
|
59
|
+
bottom: -2px;
|
|
60
|
+
border-radius: 5px;
|
|
61
|
+
border: 1px solid var(--epr-active-skin-tone-indicator-border-color);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone.active {
|
|
65
|
+
opacity: 1;
|
|
66
|
+
z-index: 1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone.epr-tone-neutral {
|
|
70
|
+
background-color: #ffd225;
|
|
71
|
+
}
|
|
72
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone.epr-tone-1f3fb {
|
|
73
|
+
background-color: #ffdfbd;
|
|
74
|
+
}
|
|
75
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone.epr-tone-1f3fc {
|
|
76
|
+
background-color: #e9c197;
|
|
77
|
+
}
|
|
78
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone.epr-tone-1f3fd {
|
|
79
|
+
background-color: #c88e62;
|
|
80
|
+
}
|
|
81
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone.epr-tone-1f3fe {
|
|
82
|
+
background-color: #a86637;
|
|
83
|
+
}
|
|
84
|
+
.EmojiPickerReact .epr-skin-tones .epr-tone.epr-tone-1f3ff {
|
|
85
|
+
background-color: #60463a;
|
|
86
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
import { useSkinTonesDisabledConfig } from '../../config/useConfig';
|
|
5
|
+
import skinToneVariations from '../../data/skinToneVariations';
|
|
6
|
+
import { useCloseAllOpenToggles } from '../../hooks/useCloseAllOpenToggles';
|
|
7
|
+
import Relative from '../Layout/Relative';
|
|
8
|
+
import {
|
|
9
|
+
useActiveSkinToneState,
|
|
10
|
+
useSkinToneFanOpenState
|
|
11
|
+
} from '../context/PickerContext';
|
|
12
|
+
import './SkinTonePicker.css';
|
|
13
|
+
|
|
14
|
+
export function SkinTonePicker() {
|
|
15
|
+
const isDisabled = useSkinTonesDisabledConfig();
|
|
16
|
+
const [isOpen, setIsOpen] = useSkinToneFanOpenState();
|
|
17
|
+
const [activeSkinTone, setActiveSkinTone] = useActiveSkinToneState();
|
|
18
|
+
const { closeAllOpenToggles } = useCloseAllOpenToggles();
|
|
19
|
+
|
|
20
|
+
if (isDisabled) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Relative
|
|
26
|
+
className={clsx('epr-skin-tones', {
|
|
27
|
+
open: isOpen
|
|
28
|
+
})}
|
|
29
|
+
>
|
|
30
|
+
<div className="epr-skin-tone-select" onClick={() => setIsOpen(!isOpen)}>
|
|
31
|
+
{skinToneVariations.map((skinToneVariation, i) => {
|
|
32
|
+
const active = skinToneVariation === activeSkinTone;
|
|
33
|
+
return (
|
|
34
|
+
<button
|
|
35
|
+
style={{
|
|
36
|
+
transform: clsx(
|
|
37
|
+
`translateX(-${i * (isOpen ? 28 : 0)}px)`,
|
|
38
|
+
isOpen && active && 'scale(1.3)'
|
|
39
|
+
)
|
|
40
|
+
}}
|
|
41
|
+
onClick={() => {
|
|
42
|
+
isOpen && setActiveSkinTone(skinToneVariation);
|
|
43
|
+
closeAllOpenToggles();
|
|
44
|
+
}}
|
|
45
|
+
key={skinToneVariation}
|
|
46
|
+
className={clsx(`epr-tone-${skinToneVariation}`, 'epr-tone', {
|
|
47
|
+
active
|
|
48
|
+
})}
|
|
49
|
+
></button>
|
|
50
|
+
);
|
|
51
|
+
})}
|
|
52
|
+
</div>
|
|
53
|
+
</Relative>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Generator: Adobe Illustrator 26.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
3
|
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
4
|
+
width="20px" height="40px" viewBox="0 0 20 40" enable-background="new 0 0 20 40" xml:space="preserve">
|
|
5
|
+
<path fill-rule="evenodd" clip-rule="evenodd" fill="#868686" d="M12,8.81c0,2.08-1.68,3.76-3.76,3.76c-2.08,0-3.76-1.68-3.76-3.76
|
|
6
|
+
c0-2.08,1.68-3.76,3.76-3.76C10.32,5.05,12,6.73,12,8.81z M11.23,12.72c-0.83,0.64-1.87,1.01-2.99,1.01c-2.72,0-4.92-2.2-4.92-4.92
|
|
7
|
+
c0-2.72,2.2-4.92,4.92-4.92c2.72,0,4.92,2.2,4.92,4.92c0,1.13-0.38,2.16-1.01,2.99l3.94,3.93c0.25,0.25,0.25,0.66,0,0.92
|
|
8
|
+
c-0.25,0.25-0.66,0.25-0.92,0L11.23,12.72z"/>
|
|
9
|
+
<path fill-rule="evenodd" clip-rule="evenodd" fill="#C0C0BF" d="M12,28.81c0,2.08-1.68,3.76-3.76,3.76c-2.08,0-3.76-1.68-3.76-3.76
|
|
10
|
+
c0-2.08,1.68-3.76,3.76-3.76C10.32,25.05,12,26.73,12,28.81z M11.23,32.72c-0.83,0.64-1.87,1.01-2.99,1.01
|
|
11
|
+
c-2.72,0-4.92-2.2-4.92-4.92c0-2.72,2.2-4.92,4.92-4.92c2.72,0,4.92,2.2,4.92,4.92c0,1.13-0.38,2.16-1.01,2.99l3.94,3.93
|
|
12
|
+
c0.25,0.25,0.25,0.66,0,0.92c-0.25,0.25-0.66,0.25-0.92,0L11.23,32.72z"/>
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Generator: Adobe Illustrator 26.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
3
|
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
4
|
+
width="20px" height="80px" viewBox="0 0 20 80" enable-background="new 0 0 20 80" xml:space="preserve">
|
|
5
|
+
<path fill="#868686" d="M6.98,13.59c0.1,0.1,0.24,0.15,0.37,0.15s0.27-0.05,0.37-0.15l2.42-2.42l2.43,2.43
|
|
6
|
+
c0.1,0.1,0.24,0.15,0.37,0.15c0.14,0,0.27-0.05,0.37-0.15c0.21-0.21,0.21-0.54,0-0.75l-2.43-2.43L13.32,8
|
|
7
|
+
c0.21-0.21,0.21-0.54,0-0.75c-0.21-0.21-0.54-0.21-0.75,0l-2.42,2.42L7.74,7.27c-0.21-0.21-0.54-0.21-0.75,0
|
|
8
|
+
c-0.21,0.21-0.21,0.54,0,0.75l2.41,2.41l-2.42,2.42C6.77,13.05,6.77,13.39,6.98,13.59L6.98,13.59z"/>
|
|
9
|
+
<path fill="#868686" d="M10.15,18.43c4.41,0,8-3.59,8-8c0-4.41-3.59-8-8-8c-4.41,0-8,3.59-8,8C2.15,14.84,5.74,18.43,10.15,18.43z
|
|
10
|
+
M10.15,3.49c3.83,0,6.94,3.11,6.94,6.94c0,3.83-3.11,6.94-6.94,6.94c-3.83,0-6.94-3.11-6.94-6.94C3.21,6.6,6.33,3.49,10.15,3.49
|
|
11
|
+
L10.15,3.49z"/>
|
|
12
|
+
<path fill="#3371B7" d="M6.98,33.59c0.1,0.1,0.24,0.15,0.37,0.15s0.27-0.05,0.37-0.15l2.42-2.42l2.43,2.43
|
|
13
|
+
c0.1,0.1,0.24,0.15,0.37,0.15c0.14,0,0.27-0.05,0.37-0.15c0.21-0.21,0.21-0.54,0-0.75l-2.43-2.43L13.32,28
|
|
14
|
+
c0.21-0.21,0.21-0.54,0-0.75c-0.21-0.21-0.54-0.21-0.75,0l-2.42,2.42l-2.41-2.41c-0.21-0.21-0.54-0.21-0.75,0
|
|
15
|
+
c-0.21,0.21-0.21,0.54,0,0.75l2.41,2.41l-2.42,2.42C6.77,33.05,6.77,33.39,6.98,33.59L6.98,33.59z"/>
|
|
16
|
+
<path fill="#3371B7" d="M10.15,38.43c4.41,0,8-3.59,8-8c0-4.41-3.59-8-8-8c-4.41,0-8,3.59-8,8C2.15,34.84,5.74,38.43,10.15,38.43z
|
|
17
|
+
M10.15,23.49c3.83,0,6.94,3.11,6.94,6.94c0,3.83-3.11,6.94-6.94,6.94c-3.83,0-6.94-3.11-6.94-6.94
|
|
18
|
+
C3.21,26.6,6.33,23.49,10.15,23.49L10.15,23.49z"/>
|
|
19
|
+
<path fill="#C0C0BF" d="M6.98,53.59c0.1,0.1,0.24,0.15,0.37,0.15s0.27-0.05,0.37-0.15l2.42-2.42l2.43,2.43
|
|
20
|
+
c0.1,0.1,0.24,0.15,0.37,0.15c0.14,0,0.27-0.05,0.37-0.15c0.21-0.21,0.21-0.54,0-0.75l-2.43-2.43L13.32,48
|
|
21
|
+
c0.21-0.21,0.21-0.54,0-0.75c-0.21-0.21-0.54-0.21-0.75,0l-2.42,2.42l-2.41-2.41c-0.21-0.21-0.54-0.21-0.75,0
|
|
22
|
+
c-0.21,0.21-0.21,0.54,0,0.75l2.41,2.41l-2.42,2.42C6.77,53.05,6.77,53.39,6.98,53.59L6.98,53.59z"/>
|
|
23
|
+
<path fill="#C0C0BF" d="M10.15,58.43c4.41,0,8-3.59,8-8c0-4.41-3.59-8-8-8c-4.41,0-8,3.59-8,8C2.15,54.84,5.74,58.43,10.15,58.43z
|
|
24
|
+
M10.15,43.49c3.83,0,6.94,3.11,6.94,6.94c0,3.83-3.11,6.94-6.94,6.94c-3.83,0-6.94-3.11-6.94-6.94
|
|
25
|
+
C3.21,46.6,6.33,43.49,10.15,43.49L10.15,43.49z"/>
|
|
26
|
+
<path fill="#6AA9DD" d="M6.98,73.59c0.1,0.1,0.24,0.15,0.37,0.15s0.27-0.05,0.37-0.15l2.42-2.42l2.43,2.43
|
|
27
|
+
c0.1,0.1,0.24,0.15,0.37,0.15c0.14,0,0.27-0.05,0.37-0.15c0.21-0.21,0.21-0.54,0-0.75l-2.43-2.43L13.32,68
|
|
28
|
+
c0.21-0.21,0.21-0.54,0-0.75c-0.21-0.21-0.54-0.21-0.75,0l-2.42,2.42l-2.41-2.41c-0.21-0.21-0.54-0.21-0.75,0
|
|
29
|
+
c-0.21,0.21-0.21,0.54,0,0.75l2.41,2.41l-2.42,2.42C6.77,73.05,6.77,73.39,6.98,73.59L6.98,73.59z"/>
|
|
30
|
+
<path fill="#6AA9DD" d="M10.15,78.43c4.41,0,8-3.59,8-8c0-4.41-3.59-8-8-8c-4.41,0-8,3.59-8,8C2.15,74.84,5.74,78.43,10.15,78.43z
|
|
31
|
+
M10.15,63.49c3.83,0,6.94,3.11,6.94,6.94c0,3.83-3.11,6.94-6.94,6.94c-3.83,0-6.94-3.11-6.94-6.94
|
|
32
|
+
C3.21,66.6,6.33,63.49,10.15,63.49L10.15,63.49z"/>
|
|
33
|
+
</svg>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
aside.EmojiPickerReact.epr-main {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
border-width: 1px;
|
|
6
|
+
border-style: solid;
|
|
7
|
+
border-radius: var(--epr-picker-border-radius);
|
|
8
|
+
border-color: var(--epr-picker-border-color);
|
|
9
|
+
width: var(--epr-picker-width);
|
|
10
|
+
height: var(--epr-picker-height);
|
|
11
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
import { useThemeConfig } from '../../config/useConfig';
|
|
5
|
+
import useIsSearchMode from '../../hooks/useIsSearchMode';
|
|
6
|
+
import { Theme } from '../../types/exposedTypes';
|
|
7
|
+
import { usePickerMainRef } from '../context/ElementRefContext';
|
|
8
|
+
import { PickerContextProvider } from '../context/PickerContext';
|
|
9
|
+
import './PickerMain.css';
|
|
10
|
+
|
|
11
|
+
type Props = Readonly<{
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
}>;
|
|
14
|
+
|
|
15
|
+
export default function PickerMain({ children }: Props) {
|
|
16
|
+
return (
|
|
17
|
+
<PickerContextProvider>
|
|
18
|
+
<PickerRootElement>{children}</PickerRootElement>
|
|
19
|
+
</PickerContextProvider>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type RootProps = Readonly<{
|
|
24
|
+
children: React.ReactNode;
|
|
25
|
+
}>;
|
|
26
|
+
|
|
27
|
+
function PickerRootElement({ children }: RootProps) {
|
|
28
|
+
const theme = useThemeConfig();
|
|
29
|
+
const searchModeActive = useIsSearchMode();
|
|
30
|
+
const PickerMainRef = usePickerMainRef();
|
|
31
|
+
return (
|
|
32
|
+
<aside
|
|
33
|
+
className={clsx('EmojiPickerReact', 'epr-main', {
|
|
34
|
+
'epr-search-active': searchModeActive,
|
|
35
|
+
'epr-dark-theme': theme === Theme.DARK
|
|
36
|
+
})}
|
|
37
|
+
ref={PickerMainRef}
|
|
38
|
+
>
|
|
39
|
+
{children}
|
|
40
|
+
</aside>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
.EmojiPickerReact .epr-category-nav {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: row;
|
|
4
|
+
justify-content: space-around;
|
|
5
|
+
padding: var(--epr-header-padding);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.EmojiPickerReact .epr-category-nav > button.epr-cat-btn {
|
|
9
|
+
display: inline-block;
|
|
10
|
+
transition: opacity 0.2s ease-in-out;
|
|
11
|
+
position: relative;
|
|
12
|
+
height: var(--epr-category-navigation-button-size);
|
|
13
|
+
width: var(--epr-category-navigation-button-size);
|
|
14
|
+
background-size: calc(var(--epr-category-navigation-button-size) * 10);
|
|
15
|
+
outline: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.EmojiPickerReact.epr-search-active .epr-category-nav > button.epr-cat-btn,
|
|
19
|
+
.EmojiPickerReact.epr-search-active
|
|
20
|
+
.epr-category-nav
|
|
21
|
+
> button.epr-cat-btn:hover,
|
|
22
|
+
.EmojiPickerReact.epr-search-active
|
|
23
|
+
.epr-category-nav
|
|
24
|
+
> button.epr-cat-btn.active {
|
|
25
|
+
opacity: 0.3;
|
|
26
|
+
cursor: default;
|
|
27
|
+
pointer-events: none;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.EmojiPickerReact:not(.epr-search-active)
|
|
31
|
+
.epr-category-nav
|
|
32
|
+
> button.epr-cat-btn:hover,
|
|
33
|
+
.EmojiPickerReact:not(.epr-search-active)
|
|
34
|
+
.epr-category-nav
|
|
35
|
+
> button.epr-cat-btn.active {
|
|
36
|
+
opacity: 1;
|
|
37
|
+
background-position-y: var(--epr-category-navigation-button-size);
|
|
38
|
+
}
|
|
39
|
+
.EmojiPickerReact .epr-category-nav > button.epr-cat-btn {
|
|
40
|
+
background-image: svg-load(./svg/CategoryNav.svg);
|
|
41
|
+
background-position: 0 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.EmojiPickerReact.epr-dark-theme .epr-category-nav > button.epr-cat-btn {
|
|
45
|
+
background-position-y: calc(var(--epr-category-navigation-button-size) * 2);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.EmojiPickerReact.epr-dark-theme:not(.epr-search-active)
|
|
49
|
+
.epr-category-nav
|
|
50
|
+
> button.epr-cat-btn:hover,
|
|
51
|
+
.EmojiPickerReact.epr-dark-theme:not(.epr-search-active)
|
|
52
|
+
.epr-category-nav
|
|
53
|
+
> button.epr-cat-btn.active {
|
|
54
|
+
background-position-y: calc(var(--epr-category-navigation-button-size) * 3);
|
|
55
|
+
}
|
|
56
|
+
.EmojiPickerReact button.epr-cat-btn.epr-icn-recently_used {
|
|
57
|
+
background-position-x: calc(var(--epr-category-navigation-button-size) * -8);
|
|
58
|
+
}
|
|
59
|
+
.EmojiPickerReact button.epr-cat-btn.epr-icn-activities {
|
|
60
|
+
background-position-x: calc(var(--epr-category-navigation-button-size) * -4);
|
|
61
|
+
}
|
|
62
|
+
.EmojiPickerReact button.epr-cat-btn.epr-icn-animals_nature {
|
|
63
|
+
background-position-x: calc(var(--epr-category-navigation-button-size) * -1);
|
|
64
|
+
}
|
|
65
|
+
.EmojiPickerReact button.epr-cat-btn.epr-icn-flags {
|
|
66
|
+
background-position-x: calc(var(--epr-category-navigation-button-size) * -7);
|
|
67
|
+
}
|
|
68
|
+
.EmojiPickerReact button.epr-cat-btn.epr-icn-food_drink {
|
|
69
|
+
background-position-x: calc(var(--epr-category-navigation-button-size) * -2);
|
|
70
|
+
}
|
|
71
|
+
.EmojiPickerReact button.epr-cat-btn.epr-icn-objects {
|
|
72
|
+
background-position-x: calc(var(--epr-category-navigation-button-size) * -5);
|
|
73
|
+
}
|
|
74
|
+
.EmojiPickerReact button.epr-cat-btn.epr-icn-smileys_people {
|
|
75
|
+
background-position-x: 0px;
|
|
76
|
+
}
|
|
77
|
+
.EmojiPickerReact button.epr-cat-btn.epr-icn-symbols {
|
|
78
|
+
background-position-x: calc(var(--epr-category-navigation-button-size) * -6);
|
|
79
|
+
}
|
|
80
|
+
.EmojiPickerReact button.epr-cat-btn.epr-icn-travel_places {
|
|
81
|
+
background-position-x: calc(var(--epr-category-navigation-button-size) * -3);
|
|
82
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import './CategoryNavigation.css';
|
|
4
|
+
|
|
5
|
+
import { categoryFromCategoryConfig } from '../../config/categoryConfig';
|
|
6
|
+
import { useCategoriesConfig } from '../../config/useConfig';
|
|
7
|
+
import { useActiveCategoryState } from '../context/PickerContext';
|
|
8
|
+
|
|
9
|
+
export function CategoryNavigation() {
|
|
10
|
+
const categoriesConfig = useCategoriesConfig();
|
|
11
|
+
const [
|
|
12
|
+
activeCategory,
|
|
13
|
+
,
|
|
14
|
+
setActiveCategoryAndScroll
|
|
15
|
+
] = useActiveCategoryState();
|
|
16
|
+
return (
|
|
17
|
+
<div className="epr-category-nav">
|
|
18
|
+
{categoriesConfig.map(categoryConfig => {
|
|
19
|
+
const category = categoryFromCategoryConfig(categoryConfig);
|
|
20
|
+
return (
|
|
21
|
+
<button
|
|
22
|
+
className={clsx('epr-cat-btn', `epr-icn-${category}`, {
|
|
23
|
+
active: category === activeCategory
|
|
24
|
+
})}
|
|
25
|
+
key={category}
|
|
26
|
+
onClick={() => setActiveCategoryAndScroll(category)}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
})}
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|