import React, { ReactElement, useCallback, useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { keyframes } from 'tss-react'; import { makeStyles } from 'tss-react/mui'; import { IReduxState } from '../../../app/types'; import { isMobileBrowser } from '../../environment/utils'; import Popover from '../../popover/components/Popover.web'; import { withPixelLineHeight } from '../../styles/functions.web'; import { hideTooltip, showTooltip } from '../actions'; const TOOLTIP_DELAY = 300; const ANIMATION_DURATION = 0.2; interface IProps { children: ReactElement; containerClassName?: string; content: string; position?: 'top' | 'bottom' | 'left' | 'right'; } const useStyles = makeStyles()(theme => { return { container: { backgroundColor: theme.palette.uiBackground, borderRadius: '3px', padding: theme.spacing(2), ...withPixelLineHeight(theme.typography.labelRegular), color: theme.palette.text01, position: 'relative', '&.mounting-animation': { animation: `${keyframes` 0% { opacity: 0; } 100% { opacity: 1; } `} ${ANIMATION_DURATION}s forwards ease-in` }, '&.unmounting': { animation: `${keyframes` 0% { opacity: 1; } 100% { opacity: 0; } `} ${ANIMATION_DURATION}s forwards ease-out` } } }; }); const Tooltip = ({ containerClassName, content, children, position = 'top' }: IProps) => { const dispatch = useDispatch(); const [ visible, setVisible ] = useState(false); const [ isUnmounting, setIsUnmounting ] = useState(false); const { classes, cx } = useStyles(); const timeoutID = useRef({ open: 0, close: 0 }); const { content: storeContent, previousContent, visible: isVisible } = useSelector((state: IReduxState) => state['features/base/tooltip']); if (isMobileBrowser()) { return children; } const contentComponent = (
{content}
); const openPopover = () => { setVisible(true); dispatch(showTooltip(content)); }; const closePopover = () => { setVisible(false); dispatch(hideTooltip(content)); setIsUnmounting(false); }; const onPopoverOpen = useCallback(() => { clearTimeout(timeoutID.current.close); timeoutID.current.close = 0; if (!visible) { if (isVisible) { openPopover(); } else { timeoutID.current.open = window.setTimeout(() => { openPopover(); }, TOOLTIP_DELAY); } } }, [ visible, isVisible ]); const onPopoverClose = useCallback(() => { clearTimeout(timeoutID.current.open); if (visible) { timeoutID.current.close = window.setTimeout(() => { setIsUnmounting(true); }, TOOLTIP_DELAY); } }, [ visible ]); useEffect(() => { if (isUnmounting) { setTimeout(() => { if (timeoutID.current.close !== 0) { closePopover(); } }, (ANIMATION_DURATION * 1000) + 10); } }, [ isUnmounting ]); useEffect(() => { if (storeContent !== content) { closePopover(); clearTimeout(timeoutID.current.close); timeoutID.current.close = 0; } }, [ storeContent ]); return ( {children} ); }; export default Tooltip;