/* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable jsx-a11y/click-events-have-key-events */ import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import './EmojiBoard.scss'; import EventEmitter from 'events'; import parse from 'html-react-parser'; import twemoji from 'twemoji'; import { emojiGroups, searchEmoji } from './emoji'; import Text from '../../atoms/text/Text'; import RawIcon from '../../atoms/system-icons/RawIcon'; import IconButton from '../../atoms/button/IconButton'; import Input from '../../atoms/input/Input'; import ScrollView from '../../atoms/scroll/ScrollView'; import SearchIC from '../../../../public/res/ic/outlined/search.svg'; import EmojiIC from '../../../../public/res/ic/outlined/emoji.svg'; import DogIC from '../../../../public/res/ic/outlined/dog.svg'; import CupIC from '../../../../public/res/ic/outlined/cup.svg'; import BallIC from '../../../../public/res/ic/outlined/ball.svg'; import PhotoIC from '../../../../public/res/ic/outlined/photo.svg'; import BulbIC from '../../../../public/res/ic/outlined/bulb.svg'; import PeaceIC from '../../../../public/res/ic/outlined/peace.svg'; import FlagIC from '../../../../public/res/ic/outlined/flag.svg'; const viewEvent = new EventEmitter(); function EmojiGroup({ name, emojis }) { function getEmojiBoard() { const emojiBoard = []; const ROW_EMOJIS_COUNT = 7; const totalEmojis = emojis.length; for (let r = 0; r < totalEmojis; r += ROW_EMOJIS_COUNT) { const emojiRow = []; for (let c = r; c < r + ROW_EMOJIS_COUNT; c += 1) { const emojiIndex = c; if (emojiIndex >= totalEmojis) break; const emoji = emojis[emojiIndex]; emojiRow.push( { parse(twemoji.parse( emoji.unicode, { attributes: () => ({ unicode: emoji.unicode, shortcodes: emoji.shortcodes?.toString(), hexcode: emoji.hexcode, }), }, )) } , ); } emojiBoard.push(
{emojiRow}
); } return emojiBoard; } return (
{name}
{getEmojiBoard()}
); } EmojiGroup.propTypes = { name: PropTypes.string.isRequired, emojis: PropTypes.arrayOf(PropTypes.shape({ length: PropTypes.number, unicode: PropTypes.string, hexcode: PropTypes.string, shortcodes: PropTypes.oneOfType([ PropTypes.string, PropTypes.arrayOf(PropTypes.string), ]), })).isRequired, }; function SearchedEmoji() { const [searchedEmojis, setSearchedEmojis] = useState([]); function handleSearchEmoji(term) { if (term.trim() === '') { setSearchedEmojis([]); return; } setSearchedEmojis(searchEmoji(term).map((finding) => finding.item)); } useEffect(() => { viewEvent.on('search-emoji', handleSearchEmoji); return () => { viewEvent.removeListener('search-emoji', handleSearchEmoji); }; }, []); return searchedEmojis.length !== 0 && ; } function EmojiBoard({ onSelect }) { const searchRef = useRef(null); const scrollEmojisRef = useRef(null); const emojiInfo = useRef(null); function isTargetNotEmoji(target) { return target.classList.contains('emoji') === false; } function getEmojiDataFromTarget(target) { const unicode = target.getAttribute('unicode'); const hexcode = target.getAttribute('hexcode'); let shortcodes = target.getAttribute('shortcodes'); if (typeof shortcodes === 'undefined') shortcodes = undefined; else shortcodes = shortcodes.split(','); return { unicode, hexcode, shortcodes }; } function selectEmoji(e) { if (isTargetNotEmoji(e.target)) return; const emoji = e.target; onSelect(getEmojiDataFromTarget(emoji)); } function setEmojiInfo(emoji) { const infoEmoji = emojiInfo.current.firstElementChild.firstElementChild; const infoShortcode = emojiInfo.current.lastElementChild; const emojiSrc = infoEmoji.src; infoEmoji.src = `${emojiSrc.slice(0, emojiSrc.lastIndexOf('/') + 1)}${emoji.hexcode.toLowerCase()}.png`; infoShortcode.textContent = `:${emoji.shortcode}:`; } function hoverEmoji(e) { if (isTargetNotEmoji(e.target)) return; const emoji = e.target; const { shortcodes, hexcode } = getEmojiDataFromTarget(emoji); if (typeof shortcodes === 'undefined') { searchRef.current.placeholder = 'Search'; setEmojiInfo({ hexcode: '1f643', shortcode: 'slight_smile' }); return; } if (searchRef.current.placeholder === shortcodes[0]) return; searchRef.current.setAttribute('placeholder', `:${shortcodes[0]}:`); setEmojiInfo({ hexcode, shortcode: shortcodes[0] }); } function handleSearchChange(e) { const term = e.target.value; setTimeout(() => { if (e.target.value !== term) return; viewEvent.emit('search-emoji', term); scrollEmojisRef.current.scrollTop = 0; }, 500); } function openGroup(groupOrder) { let tabIndex = groupOrder; const $emojiContent = scrollEmojisRef.current.firstElementChild; const groupCount = $emojiContent.childElementCount; if (groupCount > emojiGroups.length) tabIndex += groupCount - emojiGroups.length; $emojiContent.children[tabIndex].scrollIntoView(); } return (
{ emojiGroups.map((group) => ( )) }
{ parse(twemoji.parse('🙂')) }
:slight_smile:
openGroup(0)} src={EmojiIC} tooltip="Smileys" tooltipPlacement="right" /> openGroup(1)} src={DogIC} tooltip="Animals" tooltipPlacement="right" /> openGroup(2)} src={CupIC} tooltip="Food" tooltipPlacement="right" /> openGroup(3)} src={BallIC} tooltip="Activity" tooltipPlacement="right" /> openGroup(4)} src={PhotoIC} tooltip="Travel" tooltipPlacement="right" /> openGroup(5)} src={BulbIC} tooltip="Objects" tooltipPlacement="right" /> openGroup(6)} src={PeaceIC} tooltip="Symbols" tooltipPlacement="right" /> openGroup(7)} src={FlagIC} tooltip="Flags" tooltipPlacement="right" />
); } EmojiBoard.propTypes = { onSelect: PropTypes.func.isRequired, }; export default EmojiBoard;