'use client'; import { useEffect, useRef } from 'react'; import { useTranslations } from 'next-intl'; import { WIDGET_REGISTRY, type WidgetType } from './widget-registry'; interface WidgetCatalogModalProps { isOpen: boolean; onClose: () => void; onAddWidget: (type: WidgetType) => void; } const WIDGET_TYPES: WidgetType[] = [ 'clock', 'search', 'calendar', 'note', 'calculator', 'favorites', 'stopwatch', ]; /** * Modal dialog showing available widget types as selectable cards. * Click on a card adds the widget to the dashboard and closes the modal. * Escape to close, click outside to close, focus trap (D-01 flow). */ export function WidgetCatalogModal({ isOpen, onClose, onAddWidget, }: WidgetCatalogModalProps) { const t = useTranslations('widgets'); const dialogRef = useRef(null); // Focus trap + Escape handler useEffect(() => { if (!isOpen) return; function handleKeyDown(e: KeyboardEvent) { if (e.key === 'Escape') { onClose(); } } document.addEventListener('keydown', handleKeyDown); // Focus the dialog on open dialogRef.current?.focus(); return () => document.removeEventListener('keydown', handleKeyDown); }, [isOpen, onClose]); if (!isOpen) return null; return (
{/* Backdrop — visually only, hidden from assistive tech */} ); }