import { useCallback, useMemo, useRef, useState, type MouseEvent, type ReactNode, } from 'react' import { IconButton, Menu } from '@mui/material' import { MoreVert as MoreVertIcon } from '@mui/icons-material' import { Tooltip } from '../../../components/tooltip/tooltip' import { useLegendConfig } from '../../provider' import { LegendMenuContext, type LegendMenuController } from '../contexts' export interface LegendOverflowMenuProps { /** Menu items; async items use `stopPropagation` + `runAsyncMenuAction`. */ children?: ReactNode /** When `false`, render nothing. Defaults to `true`. */ gate?: boolean /** `aria-label` for the ⋮ trigger. */ ariaLabel: string /** Extra `.active` pin (e.g. inline opacity bar open). */ active?: boolean } export function LegendOverflowMenu({ children, gate = true, ariaLabel, active = false, }: LegendOverflowMenuProps) { const [anchorEl, setAnchorEl] = useState(null) const [busy, setBusyState] = useState(false) // Ref so close-guards and click gates see the flag before the next render. const busyRef = useRef(false) const open = Boolean(anchorEl) const { labels } = useLegendConfig() const close = useCallback(() => setAnchorEl(null), []) const setBusy = useCallback((next: boolean) => { busyRef.current = next setBusyState(next) }, []) const isBusy = useCallback(() => busyRef.current, []) const handleClose = useCallback(() => { if (busyRef.current) return close() }, [close]) const menu = useMemo( () => ({ busy, isBusy, setBusy, close }), [busy, isBusy, setBusy, close], ) if (!gate || !children) return null const handleOpen = (e: MouseEvent) => { e.stopPropagation() setAnchorEl(e.currentTarget) } return ( {children} ) }