Pre-alpha: React with any emoji, behind flag

This commit is contained in:
Ken Powers 2020-05-05 15:49:34 -04:00 committed by Scott Nonnenberg
parent d13c3d3350
commit 0865a5481c
31 changed files with 572 additions and 234 deletions

View file

@ -1,56 +0,0 @@
#### Default
```jsx
<util.ConversationContext theme={util.theme}>
<div
style={{
height: '500px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
}}
>
<EmojiButton
i18n={util.i18n}
onPickEmoji={e => console.log('onPickEmoji', e)}
skinTone={0}
onSetSkinTone={t => console.log('onSetSkinTone', t)}
onClose={() => console.log('onClose')}
recentEmojis={[
'grinning',
'grin',
'joy',
'rolling_on_the_floor_laughing',
'smiley',
'smile',
'sweat_smile',
'laughing',
'wink',
'blush',
'yum',
'sunglasses',
'heart_eyes',
'kissing_heart',
'kissing',
'kissing_smiling_eyes',
'kissing_closed_eyes',
'relaxed',
'slightly_smiling_face',
'hugging_face',
'grinning_face_with_star_eyes',
'thinking_face',
'face_with_one_eyebrow_raised',
'neutral_face',
'expressionless',
'no_mouth',
'face_with_rolling_eyes',
'smirk',
'persevere',
'disappointed_relieved',
'open_mouth',
'zipper_mouth_face',
]}
/>
</div>
</util.ConversationContext>
```

View file

@ -0,0 +1,66 @@
import * as React from 'react';
// @ts-ignore
import { setup as setupI18n } from '../../../js/modules/i18n';
// @ts-ignore
import enMessages from '../../../_locales/en/messages.json';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { EmojiButton } from './EmojiButton';
const i18n = setupI18n('en', enMessages);
storiesOf('Components/emojis/EmojiButton', module).add('Base', () => {
return (
<div
style={{
height: '500px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
}}
>
<EmojiButton
i18n={i18n}
onPickEmoji={action('onPickEmoji')}
skinTone={0}
onSetSkinTone={action('onSetSkinTone')}
recentEmojis={[
'grinning',
'grin',
'joy',
'rolling_on_the_floor_laughing',
'smiley',
'smile',
'sweat_smile',
'laughing',
'wink',
'blush',
'yum',
'sunglasses',
'heart_eyes',
'kissing_heart',
'kissing',
'kissing_smiling_eyes',
'kissing_closed_eyes',
'relaxed',
'slightly_smiling_face',
'hugging_face',
'grinning_face_with_star_eyes',
'thinking_face',
'face_with_one_eyebrow_raised',
'neutral_face',
'expressionless',
'no_mouth',
'face_with_rolling_eyes',
'smirk',
'persevere',
'disappointed_relieved',
'open_mouth',
'zipper_mouth_face',
]}
/>
</div>
);
});

View file

@ -1,60 +0,0 @@
#### Default
```jsx
<util.ConversationContext theme={util.theme}>
<EmojiPicker
i18n={util.i18n}
onPickEmoji={e => console.log('onPickEmoji', e)}
onSetSkinTone={t => console.log('onSetSkinTone', t)}
onClose={() => console.log('onClose')}
recentEmojis={[
'grinning',
'grin',
'joy',
'rolling_on_the_floor_laughing',
'smiley',
'smile',
'sweat_smile',
'laughing',
'wink',
'blush',
'yum',
'sunglasses',
'heart_eyes',
'kissing_heart',
'kissing',
'kissing_smiling_eyes',
'kissing_closed_eyes',
'relaxed',
'slightly_smiling_face',
'hugging_face',
'grinning_face_with_star_eyes',
'thinking_face',
'face_with_one_eyebrow_raised',
'neutral_face',
'expressionless',
'no_mouth',
'face_with_rolling_eyes',
'smirk',
'persevere',
'disappointed_relieved',
'open_mouth',
'zipper_mouth_face',
]}
/>
</util.ConversationContext>
```
#### No Recents
```jsx
<util.ConversationContext theme={util.theme}>
<EmojiPicker
i18n={util.i18n}
onPickEmoji={e => console.log('onPickEmoji', e)}
onSetSkinTone={t => console.log('onSetSkinTone', t)}
onClose={() => console.log('onClose')}
recentEmojis={[]}
/>
</util.ConversationContext>
```

View file

@ -0,0 +1,71 @@
import * as React from 'react';
// @ts-ignore
import { setup as setupI18n } from '../../../js/modules/i18n';
// @ts-ignore
import enMessages from '../../../_locales/en/messages.json';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { EmojiPicker } from './EmojiPicker';
const i18n = setupI18n('en', enMessages);
storiesOf('Components/emojis/EmojiPicker', module)
.add('Base', () => {
return (
<EmojiPicker
i18n={i18n}
onPickEmoji={action('onPickEmoji')}
onSetSkinTone={action('onSetSkinTone')}
onClose={action('onClose')}
skinTone={0}
recentEmojis={[
'grinning',
'grin',
'joy',
'rolling_on_the_floor_laughing',
'smiley',
'smile',
'sweat_smile',
'laughing',
'wink',
'blush',
'yum',
'sunglasses',
'heart_eyes',
'kissing_heart',
'kissing',
'kissing_smiling_eyes',
'kissing_closed_eyes',
'relaxed',
'slightly_smiling_face',
'hugging_face',
'grinning_face_with_star_eyes',
'thinking_face',
'face_with_one_eyebrow_raised',
'neutral_face',
'expressionless',
'no_mouth',
'face_with_rolling_eyes',
'smirk',
'persevere',
'disappointed_relieved',
'open_mouth',
'zipper_mouth_face',
]}
/>
);
})
.add('No Recents', () => {
return (
<EmojiPicker
i18n={i18n}
onPickEmoji={action('onPickEmoji')}
onSetSkinTone={action('onSetSkinTone')}
onClose={action('onClose')}
skinTone={0}
recentEmojis={[]}
/>
);
});

View file

@ -17,7 +17,7 @@ import {
} from 'lodash';
import { Emoji } from './Emoji';
import { dataByCategory, search } from './lib';
import { useRestoreFocus } from '../hooks';
import { useRestoreFocus } from '../../util/hooks';
import { LocalizerType } from '../../types/Util';
export type EmojiPickDataType = { skinTone?: number; shortName: string };
@ -29,7 +29,7 @@ export type OwnProps = {
readonly skinTone: number;
readonly onSetSkinTone: (tone: number) => unknown;
readonly recentEmojis?: Array<string>;
readonly onClose: () => unknown;
readonly onClose?: () => unknown;
};
export type Props = OwnProps & Pick<React.HTMLProps<HTMLDivElement>, 'style'>;
@ -83,11 +83,15 @@ export const EmojiPicker = React.memo(
const [scrollToRow, setScrollToRow] = React.useState(0);
const [selectedTone, setSelectedTone] = React.useState(skinTone);
const handleToggleSearch = React.useCallback(() => {
setSearchText('');
setSelectedCategory(categories[0]);
setSearchMode(m => !m);
}, [setSearchText, setSearchMode]);
const handleToggleSearch = React.useCallback(
(e: React.MouseEvent) => {
e.stopPropagation();
setSearchText('');
setSelectedCategory(categories[0]);
setSearchMode(m => !m);
},
[setSearchText, setSearchMode]
);
const debounceSearchChange = React.useMemo(
() =>
@ -122,15 +126,16 @@ export const EmojiPicker = React.memo(
| React.KeyboardEvent<HTMLButtonElement>
) => {
if ('key' in e) {
if (e.key === 'Enter') {
if (e.key === 'Enter' && doSend) {
e.stopPropagation();
e.preventDefault();
if (doSend) {
doSend();
}
doSend();
}
} else {
const { shortName } = e.currentTarget.dataset;
if (shortName) {
e.stopPropagation();
e.preventDefault();
onPickEmoji({ skinTone: selectedTone, shortName });
}
}
@ -160,7 +165,9 @@ export const EmojiPicker = React.memo(
' ', // Space
].includes(event.key)
) {
onClose();
if (onClose) {
onClose();
}
event.preventDefault();
event.stopPropagation();
@ -224,8 +231,9 @@ export const EmojiPicker = React.memo(
);
const handleSelectCategory = React.useCallback(
({ currentTarget }: React.MouseEvent<HTMLButtonElement>) => {
const { category } = currentTarget.dataset;
(e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation();
const { category } = e.currentTarget.dataset;
if (category) {
setSelectedCategory(category);
setScrollToRow(catToRowOffsets[category]);