/** * DTMenu — Hierarchical menu with beveled items. * * CSS reference: forms-dt.css .dt-menu-item, .active, .selected */ import { useState, useCallback, type ReactNode, type CSSProperties } from 'react'; import type { DTVariant } from '@dangerousthings/tokens'; import { cx } from '../utils/cx'; import { getVariantClass } from '../utils/variantClasses'; export interface DTMenuItem { id: string; title: string; icon?: ReactNode; items?: DTMenuItem[]; isActive?: boolean; isSelected?: boolean; } interface DTMenuProps { items: DTMenuItem[]; /** Color variant @default 'normal' */ variant?: DTVariant; onItemClick?: (id: string) => void; className?: string; style?: CSSProperties; } export function DTMenu({ items, variant = 'normal', onItemClick, className, style, }: DTMenuProps) { return (
{items.map(item => ( ))}
); } function MenuItem({ item, level, onItemClick, }: { item: DTMenuItem; level: number; onItemClick?: (id: string) => void; }) { const [expanded, setExpanded] = useState(false); const hasChildren = item.items && item.items.length > 0; const handleClick = useCallback(() => { if (hasChildren) { setExpanded(prev => !prev); } onItemClick?.(item.id); }, [hasChildren, item.id, onItemClick]); return ( <> {hasChildren && expanded && item.items!.map(child => ( ))} ); }