Initial move towards new ESLint config supporting TS
Co-authored-by: Sidney Keese <sidney@carbonfive.com>
This commit is contained in:
parent
c2aa8eb82b
commit
5b1536cc02
22 changed files with 3300 additions and 597 deletions
|
@ -1,13 +1,7 @@
|
|||
import * as React from 'react';
|
||||
import { Emoji, EmojiSizes, Props } from './Emoji';
|
||||
|
||||
// @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 { boolean, select, text } from '@storybook/addon-knobs';
|
||||
import { Emoji, EmojiSizes, Props } from './Emoji';
|
||||
|
||||
const story = storiesOf('Components/Emoji/Emoji', module);
|
||||
|
||||
|
|
|
@ -33,11 +33,13 @@ export const Emoji = React.memo(
|
|||
}: Props,
|
||||
ref
|
||||
) => {
|
||||
const image = shortName
|
||||
? getImagePath(shortName, skinTone)
|
||||
: emoji
|
||||
? emojiToImage(emoji)
|
||||
: '';
|
||||
let image = '';
|
||||
if (shortName) {
|
||||
image = getImagePath(shortName, skinTone);
|
||||
} else if (emoji) {
|
||||
image = emojiToImage(emoji) || '';
|
||||
}
|
||||
|
||||
const backgroundStyle = inline
|
||||
? { backgroundImage: `url('${image}')` }
|
||||
: {};
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
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 { setup as setupI18n } from '../../../js/modules/i18n';
|
||||
import enMessages from '../../../_locales/en/messages.json';
|
||||
|
||||
import { EmojiButton } from './EmojiButton';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
|
|
@ -105,12 +105,14 @@ export const EmojiButton = React.memo(
|
|||
<Reference>
|
||||
{({ ref }) => (
|
||||
<button
|
||||
type="button"
|
||||
ref={ref}
|
||||
onClick={handleClickButton}
|
||||
className={classNames({
|
||||
'module-emoji-button__button': true,
|
||||
'module-emoji-button__button--active': open,
|
||||
})}
|
||||
aria-label={i18n('EmojiButton__label')}
|
||||
/>
|
||||
)}
|
||||
</Reference>
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
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 { setup as setupI18n } from '../../../js/modules/i18n';
|
||||
import enMessages from '../../../_locales/en/messages.json';
|
||||
|
||||
import { EmojiPicker } from './EmojiPicker';
|
||||
|
||||
const i18n = setupI18n('en', enMessages);
|
||||
|
|
|
@ -73,10 +73,7 @@ export const EmojiPicker = React.memo(
|
|||
ref
|
||||
) => {
|
||||
const focusRef = React.useRef<HTMLButtonElement>(null);
|
||||
// Per design: memoize the initial recent emojis so the grid only updates after re-opening the picker.
|
||||
const firstRecent = React.useMemo(() => {
|
||||
return recentEmojis;
|
||||
}, []);
|
||||
const [firstRecent] = React.useState(recentEmojis);
|
||||
const [selectedCategory, setSelectedCategory] = React.useState(
|
||||
categories[0]
|
||||
);
|
||||
|
@ -208,7 +205,7 @@ export const EmojiPicker = React.memo(
|
|||
);
|
||||
|
||||
return [...chunk(firstRecent, COL_COUNT), ...chunks];
|
||||
}, [dataByCategory, categories, firstRecent, searchText]);
|
||||
}, [firstRecent, renderableCategories, searchText]);
|
||||
|
||||
const catRowEnds = React.useMemo(() => {
|
||||
const rowEnds: Array<number> = [
|
||||
|
@ -223,13 +220,13 @@ export const EmojiPicker = React.memo(
|
|||
});
|
||||
|
||||
return rowEnds;
|
||||
}, [categories, dataByCategory]);
|
||||
}, [firstRecent.length, renderableCategories]);
|
||||
|
||||
const catToRowOffsets = React.useMemo(() => {
|
||||
const offsets = initial(catRowEnds).map(i => i + 1);
|
||||
|
||||
return zipObject(categories, [0, ...offsets]);
|
||||
}, [categories, catRowEnds]);
|
||||
}, [catRowEnds]);
|
||||
|
||||
const catOffsetEntries = React.useMemo(
|
||||
() => Object.entries(catToRowOffsets),
|
||||
|
@ -259,6 +256,7 @@ export const EmojiPicker = React.memo(
|
|||
style={cellStyle}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className="module-emoji-picker__button"
|
||||
onClick={handlePickEmoji}
|
||||
onKeyDown={handlePickEmoji}
|
||||
|
@ -270,7 +268,7 @@ export const EmojiPicker = React.memo(
|
|||
</div>
|
||||
) : null;
|
||||
},
|
||||
[emojiGrid, selectedTone]
|
||||
[emojiGrid, handlePickEmoji, selectedTone]
|
||||
);
|
||||
|
||||
const getRowHeight = React.useCallback(
|
||||
|
@ -297,13 +295,14 @@ export const EmojiPicker = React.memo(
|
|||
|
||||
setSelectedCategory(cat);
|
||||
}, 10),
|
||||
[catOffsetEntries, categories]
|
||||
[catOffsetEntries]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="module-emoji-picker" ref={ref} style={style}>
|
||||
<header className="module-emoji-picker__header">
|
||||
<button
|
||||
type="button"
|
||||
ref={focusRef}
|
||||
onClick={handleToggleSearch}
|
||||
title={i18n('EmojiPicker--search-placeholder')}
|
||||
|
@ -314,6 +313,7 @@ export const EmojiPicker = React.memo(
|
|||
? 'module-emoji-picker__button--icon--close'
|
||||
: 'module-emoji-picker__button--icon--search'
|
||||
)}
|
||||
aria-label={i18n('EmojiPicker--search-placeholder')}
|
||||
/>
|
||||
{searchMode ? (
|
||||
<div className="module-emoji-picker__header__search-field">
|
||||
|
@ -328,6 +328,7 @@ export const EmojiPicker = React.memo(
|
|||
categories.map(cat =>
|
||||
cat === 'recents' && firstRecent.length === 0 ? null : (
|
||||
<button
|
||||
type="button"
|
||||
key={cat}
|
||||
data-category={cat}
|
||||
title={cat}
|
||||
|
@ -340,6 +341,7 @@ export const EmojiPicker = React.memo(
|
|||
? 'module-emoji-picker__button--selected'
|
||||
: null
|
||||
)}
|
||||
aria-label={i18n(`EmojiPicker__button--${cat}`)}
|
||||
/>
|
||||
)
|
||||
)
|
||||
|
@ -377,7 +379,7 @@ export const EmojiPicker = React.memo(
|
|||
<Emoji
|
||||
shortName="slightly_frowning_face"
|
||||
size={16}
|
||||
inline={true}
|
||||
inline
|
||||
style={{ marginLeft: '4px' }}
|
||||
/>
|
||||
</div>
|
||||
|
@ -386,6 +388,7 @@ export const EmojiPicker = React.memo(
|
|||
<footer className="module-emoji-picker__footer">
|
||||
{[0, 1, 2, 3, 4, 5].map(tone => (
|
||||
<button
|
||||
type="button"
|
||||
key={tone}
|
||||
data-tone={tone}
|
||||
onClick={handlePickTone}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// @ts-ignore: untyped json
|
||||
// Camelcase disabled due to emoji-datasource using snake_case
|
||||
/* eslint-disable camelcase */
|
||||
import untypedData from 'emoji-datasource';
|
||||
import emojiRegex from 'emoji-regex';
|
||||
import {
|
||||
|
@ -17,8 +18,6 @@ import Fuse from 'fuse.js';
|
|||
import PQueue from 'p-queue';
|
||||
import is from '@sindresorhus/is';
|
||||
|
||||
export type ValuesOf<T extends Array<any>> = T[number];
|
||||
|
||||
export const skinTones = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF'];
|
||||
|
||||
export type SkinToneKey = '1F3FB' | '1F3FC' | '1F3FD' | '1F3FE' | '1F3FF';
|
||||
|
@ -82,7 +81,6 @@ const data = (untypedData as Array<EmojiData>)
|
|||
: emoji
|
||||
);
|
||||
|
||||
// @ts-ignore
|
||||
const ROOT_PATH = get(
|
||||
// tslint:disable-next-line no-typeof-undefined
|
||||
typeof window !== 'undefined' ? window : null,
|
||||
|
@ -97,7 +95,7 @@ const makeImagePath = (src: string) => {
|
|||
const imageQueue = new PQueue({ concurrency: 10 });
|
||||
const images = new Set();
|
||||
|
||||
export const preloadImages = async () => {
|
||||
export const preloadImages = async (): Promise<void> => {
|
||||
// Preload images
|
||||
const preload = async (src: string) =>
|
||||
new Promise((resolve, reject) => {
|
||||
|
@ -110,7 +108,7 @@ export const preloadImages = async () => {
|
|||
setTimeout(reject, 5000);
|
||||
});
|
||||
|
||||
// tslint:disable-next-line no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Preloading emoji images');
|
||||
const start = Date.now();
|
||||
|
||||
|
@ -129,7 +127,7 @@ export const preloadImages = async () => {
|
|||
await imageQueue.onEmpty();
|
||||
|
||||
const end = Date.now();
|
||||
// tslint:disable-next-line no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Done preloading emoji images in ${end - start}ms`);
|
||||
};
|
||||
|
||||
|
@ -222,7 +220,7 @@ const fuse = new Fuse(data, {
|
|||
keys: ['name', 'short_name', 'short_names'],
|
||||
});
|
||||
|
||||
export function search(query: string, count: number = 0) {
|
||||
export function search(query: string, count = 0): Array<EmojiData> {
|
||||
const results = fuse.search(query.substr(0, 32));
|
||||
|
||||
if (count) {
|
||||
|
@ -237,11 +235,11 @@ const shortNames = new Set([
|
|||
...compact<string>(flatMap(data, 'short_names')),
|
||||
]);
|
||||
|
||||
export function isShortName(name: string) {
|
||||
export function isShortName(name: string): boolean {
|
||||
return shortNames.has(name);
|
||||
}
|
||||
|
||||
export function unifiedToEmoji(unified: string) {
|
||||
export function unifiedToEmoji(unified: string): string {
|
||||
return unified
|
||||
.split('-')
|
||||
.map(c => String.fromCodePoint(parseInt(c, 16)))
|
||||
|
@ -251,7 +249,7 @@ export function unifiedToEmoji(unified: string) {
|
|||
export function convertShortName(
|
||||
shortName: string,
|
||||
skinTone: number | SkinToneKey = 0
|
||||
) {
|
||||
): string {
|
||||
const base = dataByShortName[shortName];
|
||||
|
||||
if (!base) {
|
||||
|
@ -300,15 +298,17 @@ export function getSizeClass(str: string): SizeClassType {
|
|||
|
||||
if (emojiCount > 8) {
|
||||
return '';
|
||||
} else if (emojiCount > 6) {
|
||||
return 'small';
|
||||
} else if (emojiCount > 4) {
|
||||
return 'medium';
|
||||
} else if (emojiCount > 2) {
|
||||
return 'large';
|
||||
} else {
|
||||
return 'jumbo';
|
||||
}
|
||||
if (emojiCount > 6) {
|
||||
return 'small';
|
||||
}
|
||||
if (emojiCount > 4) {
|
||||
return 'medium';
|
||||
}
|
||||
if (emojiCount > 2) {
|
||||
return 'large';
|
||||
}
|
||||
return 'jumbo';
|
||||
}
|
||||
|
||||
data.forEach(emoji => {
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue