import clsx from 'clsx'; import { supportsPassiveEvents } from 'detect-passive-events'; import React, { useCallback, useEffect, useRef } from 'react'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { Text } from 'soapbox/components/ui'; const messages = defineMessages({ emoji: { id: 'icon_button.label', defaultMessage: 'Select icon' }, }); const listenerOptions = supportsPassiveEvents ? { passive: true } : false; interface IIconPickerMenu { icons: Record> onClose: () => void onPick: (icon: string) => void style?: React.CSSProperties } const IconPickerMenu: React.FC = ({ icons, onClose, onPick, style }) => { const intl = useIntl(); const node = useRef(null); const handleDocumentClick = useCallback((e: MouseEvent | TouchEvent) => { if (node.current && !node.current.contains(e.target as Node)) { onClose(); } }, []); useEffect(() => { document.addEventListener('click', handleDocumentClick, false); document.addEventListener('touchend', handleDocumentClick, listenerOptions); return () => { document.removeEventListener('click', handleDocumentClick, false); document.removeEventListener('touchend', handleDocumentClick, listenerOptions as any); }; }, []); const setRef = (c: HTMLDivElement) => { node.current = c; if (!c) return; // Nice and dirty hack to display the icons c.querySelectorAll('button.emoji-mart-emoji > img').forEach(elem => { const newIcon = document.createElement('span'); newIcon.innerHTML = ``; (elem.parentNode as any).replaceChild(newIcon, elem); }); }; const handleClick = (icon: string) => { onClose(); onPick(icon); }; const renderIcon = (icon: string) => { const name = icon.replace('fa fa-', ''); return (
  • ); }; const title = intl.formatMessage(messages.emoji); return (
      {Object.values(icons).flat().map(icon => renderIcon(icon))}
    ); }; export default IconPickerMenu;