import { useState, type MouseEvent } from 'react' import { Box, Divider, IconButton, Menu, MenuItem, Typography, } from '@mui/material' import { ChecklistOutlined as ChecklistIcon, VisibilityOutlined as VisibilityIcon, } from '@mui/icons-material' import { Tooltip } from '../../../components/tooltip/tooltip' import { getLegendStore, selectVisibleLayersGrouped, useLegendId, useLegendShallow, useLegendStore, } from '../../stores' import { useLegendConfig } from '../../provider' import { styles } from './styles' /** `key` ties section derivation to the visibility fingerprint subscription. */ function sectionsForKey(legendId: string, key: string) { void key return selectVisibleLayersGrouped(getLegendStore(legendId).getState()) } /** * Panel checklist of visible layers — each entry hides its layer; the menu * closes when nothing remains to list. * * @experimental This API is new and may change in a future release. */ export function LegendVisibleLayers() { const id = useLegendId() const [anchorEl, setAnchorEl] = useState(null) // Fingerprint avoids opacity-driven re-renders (React Compiler would hoist stale useMemo). const visibleKey = useLegendStore(id, (s) => selectVisibleLayersGrouped(s) .map( ({ group, layers }) => `${group?.id ?? ''}\x1f${group?.label ?? ''}:${layers .map((l) => `${l.id}\x1f${l.name}`) .join(',')}`, ) .join('|'), ) const sections = sectionsForKey(id, visibleKey) const setVisibility = useLegendShallow(id, (s) => s.setVisibility) const { labels } = useLegendConfig() const count = sections.reduce((n, s) => n + s.layers.length, 0) // Derived close when count hits 0; clear anchor on exit so it can't reopen stale. const open = Boolean(anchorEl) && count > 0 const handleOpen = (e: MouseEvent) => setAnchorEl(e.currentTarget) const handleClose = () => setAnchorEl(null) return ( <> {/* Span: MUI Tooltip can't attach listeners to a disabled button. */} {`${labels.enabledLayers} (${count})`} {sections.flatMap((section, index) => [ index > 0 ? ( ) : null, section.group ? ( {section.group.label} ) : null, ...section.layers.map((layer) => ( setVisibility(layer.id, false)} > {layer.name} )), ])} ) }