import type { FC } from '../../lib/teact/teact'; import React, { useCallback, useMemo, useRef, useState, } from '../../lib/teact/teact'; import Icon from '../common/icons/Icon'; import Button from './Button'; import Menu from './Menu'; import './DropdownMenu.scss'; type OwnProps = { className?: string; bubbleClassName?: string; trigger?: FC<{ onTrigger: () => void; isOpen?: boolean }>; transformOriginX?: number; transformOriginY?: number; positionX?: 'left' | 'right'; positionY?: 'top' | 'bottom'; footer?: string; forceOpen?: boolean; onOpen?: NoneToVoidFunction; onClose?: NoneToVoidFunction; onHide?: NoneToVoidFunction; onTransitionEnd?: NoneToVoidFunction; onMouseEnterBackdrop?: (e: React.MouseEvent) => void; children: React.ReactNode; autoClose?: boolean; }; const DropdownMenu: FC = ({ trigger, className, bubbleClassName, children, transformOriginX, transformOriginY, positionX = 'left', positionY = 'top', footer, forceOpen, onOpen, onClose, onTransitionEnd, onMouseEnterBackdrop, onHide, autoClose = true, }) => { // eslint-disable-next-line no-null/no-null const menuRef = useRef(null); const [isOpen, setIsOpen] = useState(false); const toggleIsOpen = () => { setIsOpen(!isOpen); if (isOpen) { onClose?.(); } else { onOpen?.(); } }; const handleKeyDown = (e: React.KeyboardEvent) => { const menu = menuRef.current; if (!isOpen || e.keyCode !== 40 || !menu) { return; } const focusedElement = document.activeElement; const elementChildren = Array.from(menu.children); if (!focusedElement || elementChildren.indexOf(focusedElement) === -1) { (elementChildren[0] as HTMLElement).focus(); } }; const handleClose = useCallback(() => { setIsOpen(false); onClose?.(); }, [onClose]); const triggerComponent: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => { if (trigger) return trigger; return ({ onTrigger, isOpen: isMenuOpen }) => ( ); }, [trigger]); return (
{triggerComponent({ onTrigger: toggleIsOpen, isOpen })} {children}
); }; export default DropdownMenu;