import React, { useRef } from 'react'; import { emojiIndex, EmojiData } from 'emoji-mart'; import useOutsideClick from '../../hooks/useOutsideClick'; import useMediaQuery from '../../hooks/useMediaQuery'; import { Popup, Suggestions, Heading, EmojiSearchTerm, Results, Result, Emoji, Colons, } from './styles'; type EmojiInputProps = { value: string; onSelection(contentWithEmoji: string, suggestedEmoji?: boolean): any; }; const getEmojisFromEmojiSearchTerm = (emojiSearchTerm: string) => emojiIndex.search(emojiSearchTerm) as any as EmojiData[]; const getEmojiSearchTerm = (content: string) => { let search = ''; const colons = content.match(/:([a-z_]+)(:)?/); if (colons) { if (colons[2] !== undefined) { const match = emojiIndex.emojis[colons[1]]; if (match && 'native' in match) { content = content.replace(colons[0], match.native); search = ''; } else { const results = emojiIndex.search(colons[1]) as any as EmojiData[]; if (results[0] && 'native' in results[0]) { content = content.replace(colons[0], (results[0] as any).native); } search = ''; } } else if (colons[1].length > 1) { search = colons[1]; } else if (colons[1]) { search = ''; } } return search; }; const EmojiSuggestion = ({ value, onSelection }: EmojiInputProps) => { const suggestions = useRef(null); const isSmall = useMediaQuery('649px'); const replaceEmoji = (search: string, emoji: EmojiData) => { if ('native' in emoji) { const txt = value.replace(`:${search}`, emoji.native); onSelection(txt, true); } }; let displayed = false; const emojiSearchTerm = getEmojiSearchTerm(value); const emojis = getEmojisFromEmojiSearchTerm(emojiSearchTerm); if (emojiSearchTerm !== '' && emojis.length > 0) { displayed = true; } else { displayed = false; } useOutsideClick([suggestions], () => { displayed = false; }); return ( {displayed && ( Suggestions for {emojiSearchTerm} {emojis.slice(0, isSmall ? 7 : 35).map((emoji) => ( replaceEmoji(emojiSearchTerm, emoji)} > {'native' in emoji && emoji.native} {emoji.colons} ))} )} ); }; export default EmojiSuggestion;