/** * Export dropdown menu component * Renders a single "Export ▾" button that opens a list of format options. * Disabled items are shown greyed with an optional badge, but cannot be selected. */ import React, { useCallback, useEffect, useRef, useState } from 'react' export interface ExportFormat { key: string label: string disabled?: boolean badge?: string } interface ExportMenuProps { label?: string formats: ExportFormat[] onSelect: (key: string) => void } export function ExportMenu({ label = 'Export', formats, onSelect }: ExportMenuProps) { const [isOpen, setIsOpen] = useState(false) const wrapperRef = useRef(null) const toggle = useCallback(() => { setIsOpen(prev => !prev) }, []) const select = useCallback( (format: ExportFormat) => { if (format.disabled) return setIsOpen(false) onSelect(format.key) }, [onSelect], ) useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) { setIsOpen(false) } } const handleKeydown = (event: KeyboardEvent) => { if (event.key === 'Escape') { setIsOpen(false) } } document.addEventListener('mousedown', handleClickOutside) document.addEventListener('keydown', handleKeydown) return () => { document.removeEventListener('mousedown', handleClickOutside) document.removeEventListener('keydown', handleKeydown) } }, []) return (
{isOpen && (
{formats.map(format => ( ))}
)}
) }