@birhaus/core
Version:
BIRHAUS Core Components - UndoSystem, CommandPalette, AuditTimeline
1 lines • 39.2 kB
Source Map (JSON)
{"version":3,"sources":["../src/components/UndoSystem.tsx","../src/components/CommandPalette.tsx","../src/constants.ts"],"names":["UndoContext","createContext","useUndo","context","useContext","UndoProvider","children","defaultTimeoutMs","maxActions","actions","setActions","useState","useEffect","interval","prev","action","addAction","actionData","id","createdAt","expiresAt","newAction","undoAction","actionId","a","error","dismissAction","clearExpired","getActionsByType","type","jsx","useUndoAction","description","undoFunction","options","cn","classes","DEFAULT_CATEGORIES","CommandPalette","items","placeholder","emptyMessage","recentLabel","maxRecent","open","setOpen","search","setSearch","selectedIndex","setSelectedIndex","recentIds","setRecentIds","inputRef","listRef","filteredItems","recent","item","otherItems","searchLower","filtered","titleMatch","descMatch","keywordMatch","k","allFilteredItems","groupedItems","groups","category","handleKeyDown","e","executeCommand","selectedEl","jsxs","Fragment","Search","index","CommandItemRow","actualIndex","categoryItems","_index","Command","selected","onClick","Icon","ChevronRight","BIRHAUS_LIMITS"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client'\n\nimport { useState, useEffect, createContext, useContext, ReactNode } from 'react'\nimport { Undo2, X, CheckCircle, AlertTriangle, Clock } from 'lucide-react'\n\n/**\n * BIRHAUS Undo System\n * \n * Implements BIRHAUS principle #5: \"Undo over confirm\"\n * \n * Core Philosophy:\n * - Actions execute immediately without confirmation dialogs\n * - Users can undo critical actions within a time window\n * - Provides clear feedback about what was done and how to undo\n * - Reduces cognitive load by eliminating confirmation interruptions\n */\n\n// BIRHAUS: Utility function (replaces @/lib/utils cn)\nfunction cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(' ')\n}\n\nexport interface UndoAction {\n id: string\n type: 'create' | 'update' | 'delete' | 'transfer' | 'approve'\n entityType: string\n entityId: string\n description: string\n undoFunction: () => Promise<void>\n createdAt: Date\n expiresAt: Date\n priority: 'low' | 'normal' | 'high' | 'critical'\n icon?: ReactNode\n metadata?: Record<string, unknown>\n}\n\ninterface UndoContextType {\n actions: UndoAction[]\n addAction: (action: Omit<UndoAction, 'id' | 'createdAt' | 'expiresAt'>) => string\n undoAction: (actionId: string) => Promise<void>\n dismissAction: (actionId: string) => void\n clearExpired: () => void\n getActionsByType: (type: string) => UndoAction[]\n}\n\nconst UndoContext = createContext<UndoContextType | null>(null)\n\nexport function useUndo() {\n const context = useContext(UndoContext)\n if (!context) {\n throw new Error('useUndo must be used within an UndoProvider')\n }\n return context\n}\n\n// BIRHAUS: Undo Provider with automatic cleanup\nexport interface UndoProviderProps {\n children: ReactNode\n defaultTimeoutMs?: number\n maxActions?: number\n}\n\nexport function UndoProvider({ \n children, \n defaultTimeoutMs = 10000, // 10 seconds default\n maxActions = 5 \n}: UndoProviderProps) {\n const [actions, setActions] = useState<UndoAction[]>([])\n \n // Cleanup expired actions\n useEffect(() => {\n const interval = setInterval(() => {\n setActions(prev => prev.filter(action => action.expiresAt > new Date()))\n }, 1000)\n \n return () => clearInterval(interval)\n }, [])\n \n const addAction = (actionData: Omit<UndoAction, 'id' | 'createdAt' | 'expiresAt'>): string => {\n const id = `undo_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`\n const createdAt = new Date()\n const expiresAt = new Date(createdAt.getTime() + defaultTimeoutMs)\n \n const newAction: UndoAction = {\n ...actionData,\n id,\n createdAt,\n expiresAt\n }\n \n setActions(prev => {\n // Remove oldest actions if we exceed maxActions\n const updated = [newAction, ...prev].slice(0, maxActions)\n return updated\n })\n \n return id\n }\n \n const undoAction = async (actionId: string): Promise<void> => {\n const action = actions.find(a => a.id === actionId)\n if (!action) {\n throw new Error('Action not found or expired')\n }\n \n try {\n await action.undoFunction()\n // Remove the action after successful undo\n setActions(prev => prev.filter(a => a.id !== actionId))\n } catch (error) {\n console.error('Failed to undo action:', error)\n throw error\n }\n }\n \n const dismissAction = (actionId: string) => {\n setActions(prev => prev.filter(a => a.id !== actionId))\n }\n \n const clearExpired = () => {\n setActions(prev => prev.filter(action => action.expiresAt > new Date()))\n }\n \n const getActionsByType = (type: string) => {\n return actions.filter(action => action.entityType === type)\n }\n \n return (\n <UndoContext.Provider value={{\n actions,\n addAction,\n undoAction,\n dismissAction,\n clearExpired,\n getActionsByType\n }}>\n {children}\n </UndoContext.Provider>\n )\n}\n\n// BIRHAUS: Simple Button component for the library\ninterface BirhausButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'primary' | 'secondary' | 'outline' | 'quiet'\n size?: 'sm' | 'md'\n}\n\nfunction BirhausButton({ \n className, \n variant = 'secondary', \n size = 'md', \n children, \n ...props \n}: BirhausButtonProps) {\n const baseStyles = \"inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\"\n \n const variants = {\n primary: \"bg-primary-600 text-white hover:bg-primary-700\",\n secondary: \"border border-gray-300 bg-white text-gray-700 hover:bg-gray-50\", \n outline: \"border border-gray-300 bg-transparent text-gray-700 hover:bg-gray-50\",\n quiet: \"text-gray-600 hover:text-gray-900 hover:bg-gray-100\"\n }\n \n const sizes = {\n sm: \"h-8 px-3 text-xs\",\n md: \"h-10 px-4 text-sm\"\n }\n \n // ESLint suppressions for controlled object access\n /* eslint-disable security/detect-object-injection */\n return (\n <button\n className={cn(baseStyles, variants[variant], sizes[size], className)}\n {...props}\n >\n {children}\n </button>\n )\n}\n\n// BIRHAUS: Simple Card component for the library\ninterface BirhausCardProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nfunction BirhausCard({ className, children, ...props }: BirhausCardProps) {\n return (\n <div\n className={cn(\n \"bg-white border border-gray-200 rounded-lg shadow-sm\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\n// BIRHAUS: Simple Badge component for the library\ninterface BirhausBadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n variant?: 'default' | 'outline'\n}\n\nfunction BirhausBadge({ className, variant = 'default', children, ...props }: BirhausBadgeProps) {\n const variants = {\n default: \"bg-gray-100 text-gray-800\",\n outline: \"border border-gray-300 bg-transparent text-gray-700\"\n }\n \n return (\n <span\n className={cn(\n \"inline-flex items-center rounded-sm px-2 py-1 text-xs font-medium\",\n variants[variant],\n className\n )}\n {...props}\n >\n {children}\n </span>\n )\n}\n\n// BIRHAUS: Undo Toast Component\nexport interface UndoToastProps {\n action: UndoAction\n onUndo: () => void\n onDismiss: () => void\n className?: string\n}\n\n// eslint-disable-next-line max-lines-per-function -- UndoToast requires complex state management and UI logic\nexport function UndoToast({ action, onUndo, onDismiss, className }: UndoToastProps) {\n const [timeLeft, setTimeLeft] = useState<number>(0)\n const [isUndoing, setIsUndoing] = useState(false)\n \n useEffect(() => {\n const updateTimeLeft = () => {\n const now = new Date()\n const remaining = Math.max(0, action.expiresAt.getTime() - now.getTime())\n setTimeLeft(remaining)\n \n if (remaining === 0) {\n onDismiss()\n }\n }\n \n updateTimeLeft()\n const interval = setInterval(updateTimeLeft, 100)\n \n return () => clearInterval(interval)\n }, [action.expiresAt, onDismiss])\n \n const handleUndo = async () => {\n setIsUndoing(true)\n try {\n await onUndo()\n } catch (error) {\n console.error('Undo failed:', error)\n setIsUndoing(false)\n }\n }\n \n const progress = (timeLeft / (action.expiresAt.getTime() - action.createdAt.getTime())) * 100\n \n const priorityStyles = {\n low: 'border-blue-200 bg-blue-50',\n normal: 'border-green-200 bg-green-50',\n high: 'border-yellow-200 bg-yellow-50',\n critical: 'border-red-200 bg-red-50'\n }\n \n const priorityIcons = {\n low: <CheckCircle className=\"h-4 w-4 text-blue-600\" />,\n normal: <CheckCircle className=\"h-4 w-4 text-green-600\" />,\n high: <AlertTriangle className=\"h-4 w-4 text-yellow-600\" />,\n critical: <AlertTriangle className=\"h-4 w-4 text-red-600\" />\n }\n \n return (\n <BirhausCard className={cn(\n \"relative overflow-hidden border transition-all duration-200\",\n priorityStyles[action.priority],\n className\n )}>\n {/* Progress bar */}\n <div \n className=\"absolute bottom-0 left-0 h-1 bg-current opacity-30 transition-all duration-100\"\n style={{ width: `${progress}%` }}\n />\n \n <div className=\"p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\n {action.icon || priorityIcons[action.priority]}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-1\">\n <span className=\"text-sm font-medium\">Acción completada</span>\n <BirhausBadge variant=\"outline\" className=\"text-xs\">\n {action.type}\n </BirhausBadge>\n </div>\n <p className=\"text-sm text-gray-600\">\n {action.description}\n </p>\n <div className=\"flex items-center gap-1 mt-2 text-xs text-gray-500\">\n <Clock className=\"h-3 w-3\" />\n <span>{Math.ceil(timeLeft / 1000)}s para deshacer</span>\n </div>\n </div>\n </div>\n \n <div className=\"flex items-center gap-2\">\n <BirhausButton\n size=\"sm\"\n variant=\"outline\"\n onClick={handleUndo}\n disabled={isUndoing}\n className=\"text-xs\"\n >\n <Undo2 className=\"h-3 w-3 mr-1\" />\n {isUndoing ? 'Deshaciendo...' : 'Deshacer'}\n </BirhausButton>\n <BirhausButton\n size=\"sm\"\n variant=\"quiet\"\n onClick={onDismiss}\n className=\"text-xs p-1\"\n >\n <X className=\"h-3 w-3\" />\n </BirhausButton>\n </div>\n </div>\n </div>\n </BirhausCard>\n )\n}\n\n// BIRHAUS: Undo Container for displaying active undo actions\nexport interface UndoContainerProps {\n position?: 'top-right' | 'bottom-right' | 'bottom-left' | 'top-left'\n className?: string\n}\n\nexport function UndoContainer({ \n position = 'top-right', \n className \n}: UndoContainerProps) {\n const { actions, undoAction, dismissAction } = useUndo()\n \n const positionStyles = {\n 'top-right': 'fixed top-4 right-4 z-50',\n 'bottom-right': 'fixed bottom-4 right-4 z-50',\n 'bottom-left': 'fixed bottom-4 left-4 z-50',\n 'top-left': 'fixed top-4 left-4 z-50'\n }\n \n if (actions.length === 0) return null\n \n return (\n <div className={cn(\n positionStyles[position],\n \"w-96 max-w-[calc(100vw-2rem)] space-y-3\",\n className\n )}>\n {actions.map((action) => (\n <UndoToast\n key={action.id}\n action={action}\n onUndo={() => undoAction(action.id)}\n onDismiss={() => dismissAction(action.id)}\n />\n ))}\n </div>\n )\n}\n\n// BIRHAUS: Utility hook for common undo patterns\nexport function useUndoAction() {\n const { addAction } = useUndo()\n \n const createUndoableAction = (\n description: string,\n undoFunction: () => Promise<void>,\n options: {\n type?: UndoAction['type']\n entityType: string\n entityId: string\n priority?: UndoAction['priority']\n icon?: ReactNode\n timeoutMs?: number\n }\n ) => {\n return addAction({\n type: options.type || 'update',\n entityType: options.entityType,\n entityId: options.entityId,\n description,\n undoFunction,\n priority: options.priority || 'normal',\n icon: options.icon\n })\n }\n \n return { createUndoableAction }\n}\n\n","'use client'\n\nimport * as React from 'react'\nimport { Search, ChevronRight, Command } from 'lucide-react'\n\n/**\n * BIRHAUS CommandPalette\n * \n * Implements BIRHAUS principle #1: \"Form serves flow\"\n * - Reduces cognitive load by hiding 95% of actions behind ⌘K search\n * - Spanish-first interface with categorized actions\n * - Keyboard-first navigation (↑↓ to navigate, Enter to execute)\n * - Recent actions for efficiency\n * - Progressive disclosure through categories\n */\n\n// BIRHAUS: Utility function (replaces @/lib/utils cn)\nfunction cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(' ')\n}\n\nexport interface CommandItem {\n id: string\n title: string\n description?: string\n icon?: React.ElementType\n category?: string\n keywords?: string[]\n action: () => void\n shortcut?: string\n}\n\nexport interface CommandPaletteProps {\n items: CommandItem[]\n placeholder?: string\n emptyMessage?: string\n recentLabel?: string\n maxRecent?: number\n}\n\n// BIRHAUS: Spanish-first categories\nconst DEFAULT_CATEGORIES = {\n navigation: 'Navegación',\n actions: 'Acciones', \n search: 'Búsqueda',\n settings: 'Configuración'\n}\n\n// eslint-disable-next-line max-lines-per-function -- CommandPalette requires complex rendering logic with multiple sections\nexport function CommandPalette({\n items,\n placeholder = 'Buscar o ejecutar comando...',\n emptyMessage = 'No se encontraron comandos',\n recentLabel = 'Recientes',\n maxRecent = 5\n}: CommandPaletteProps) {\n const [open, setOpen] = React.useState(false)\n const [search, setSearch] = React.useState('')\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n const [recentIds, setRecentIds] = React.useState<string[]>([])\n \n const inputRef = React.useRef<HTMLInputElement>(null)\n const listRef = React.useRef<HTMLDivElement>(null)\n \n // Filter items based on search\n const filteredItems = React.useMemo(() => {\n if (!search) {\n // Show recent items when no search\n const recent = recentIds\n .map(id => items.find(item => item.id === id))\n .filter(Boolean) as CommandItem[]\n \n const otherItems = items.filter(item => !recentIds.includes(item.id))\n \n return {\n recent,\n filtered: otherItems\n }\n }\n \n const searchLower = search.toLowerCase()\n const filtered = items.filter(item => {\n const titleMatch = item.title.toLowerCase().includes(searchLower)\n const descMatch = item.description?.toLowerCase().includes(searchLower)\n const keywordMatch = item.keywords?.some(k => k.toLowerCase().includes(searchLower))\n return titleMatch || descMatch || keywordMatch\n })\n \n return {\n recent: [],\n filtered\n }\n }, [items, search, recentIds])\n \n const allFilteredItems = [...filteredItems.recent, ...filteredItems.filtered]\n \n // Group items by category\n const groupedItems = React.useMemo(() => {\n const groups: Record<string, CommandItem[]> = {}\n \n filteredItems.filtered.forEach(item => {\n const category = item.category || 'actions'\n // eslint-disable-next-line security/detect-object-injection -- Safe: category is validated string\n if (!groups[category]) {\n // eslint-disable-next-line security/detect-object-injection -- Safe: category is validated string\n groups[category] = []\n }\n // eslint-disable-next-line security/detect-object-injection -- Safe: category is validated string\n groups[category].push(item)\n })\n \n return groups\n }, [filteredItems.filtered])\n \n // Handle keyboard shortcut (BIRHAUS: ⌘K global shortcut)\n React.useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Cmd/Ctrl + K to open\n if ((e.metaKey || e.ctrlKey) && e.key === 'k') {\n e.preventDefault()\n setOpen(prev => !prev)\n }\n \n // Escape to close\n if (e.key === 'Escape' && open) {\n setOpen(false)\n }\n }\n \n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [open])\n \n // Focus input when opened\n React.useEffect(() => {\n if (open && inputRef.current) {\n inputRef.current.focus()\n setSearch('')\n setSelectedIndex(0)\n }\n }, [open])\n \n // Handle keyboard navigation (BIRHAUS: Keyboard-first design)\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n setSelectedIndex(prev => \n prev < allFilteredItems.length - 1 ? prev + 1 : prev\n )\n break\n \n case 'ArrowUp':\n e.preventDefault()\n setSelectedIndex(prev => prev > 0 ? prev - 1 : 0)\n break\n \n case 'Enter':\n e.preventDefault()\n // eslint-disable-next-line security/detect-object-injection -- Safe: selectedIndex is controlled number\n if (allFilteredItems[selectedIndex]) {\n // eslint-disable-next-line security/detect-object-injection -- Safe: selectedIndex is controlled number\n executeCommand(allFilteredItems[selectedIndex])\n }\n break\n }\n }\n \n // Execute command\n const executeCommand = (item: CommandItem) => {\n // Add to recent\n setRecentIds(prev => {\n const filtered = prev.filter(id => id !== item.id)\n return [item.id, ...filtered].slice(0, maxRecent)\n })\n \n // Execute action\n item.action()\n \n // Close palette\n setOpen(false)\n }\n \n // Scroll selected item into view\n React.useEffect(() => {\n if (open && listRef.current) {\n const selectedEl = listRef.current.querySelector(`[data-index=\"${selectedIndex}\"]`)\n if (selectedEl) {\n selectedEl.scrollIntoView({ block: 'nearest' })\n }\n }\n }, [selectedIndex, open])\n\n // BIRHAUS: Programmatic control via props\n // Use the `open` and `onOpenChange` props for external control\n \n if (!open) return null\n \n return (\n <>\n {/* Backdrop */}\n <div \n className=\"fixed inset-0 z-50 bg-black/20 backdrop-blur-sm\"\n onClick={() => setOpen(false)}\n />\n \n {/* Command Palette */}\n <div className=\"fixed inset-x-0 top-20 z-50 mx-auto max-w-2xl px-4\">\n <div className=\"rounded-lg border border-gray-200 bg-white shadow-2xl\">\n {/* Search Input */}\n <div className=\"flex items-center border-b border-gray-200 px-4\">\n <Search className=\"h-5 w-5 text-gray-400\" />\n <input\n ref={inputRef}\n type=\"text\"\n value={search}\n onChange={(e) => {\n setSearch(e.target.value)\n setSelectedIndex(0)\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className={cn(\n \"flex-1 bg-transparent px-3 py-4 text-sm text-gray-900\",\n \"placeholder:text-gray-400\",\n \"focus:outline-none\"\n )}\n />\n <kbd className=\"hidden sm:inline-block px-2 py-1 text-xs bg-gray-100 text-gray-500 rounded border\">\n ESC\n </kbd>\n </div>\n \n {/* Results */}\n <div \n ref={listRef}\n className=\"max-h-96 overflow-auto p-2\"\n >\n {allFilteredItems.length === 0 ? (\n <div className=\"py-8 text-center text-sm text-gray-500\">\n {emptyMessage}\n </div>\n ) : (\n <>\n {/* Recent items */}\n {!search && filteredItems.recent.length > 0 && (\n <div className=\"mb-2\">\n <div className=\"px-2 py-1 text-xs font-medium text-gray-500 uppercase tracking-wider\">\n {recentLabel}\n </div>\n {filteredItems.recent.map((item, index) => (\n <CommandItemRow\n key={item.id}\n item={item}\n index={index}\n selected={selectedIndex === index}\n onClick={() => executeCommand(item)}\n />\n ))}\n </div>\n )}\n \n {/* Grouped items */}\n {search ? (\n // Show flat list when searching\n filteredItems.filtered.map((item, index) => {\n const actualIndex = filteredItems.recent.length + index\n return (\n <CommandItemRow\n key={item.id}\n item={item}\n index={actualIndex}\n selected={selectedIndex === actualIndex}\n onClick={() => executeCommand(item)}\n />\n )\n })\n ) : (\n // Show grouped when not searching (BIRHAUS: Progressive disclosure)\n Object.entries(groupedItems).map(([category, categoryItems]) => (\n <div key={category} className=\"mb-2\">\n <div className=\"px-2 py-1 text-xs font-medium text-gray-500 uppercase tracking-wider\">\n {DEFAULT_CATEGORIES[category as keyof typeof DEFAULT_CATEGORIES] || category}\n </div>\n {categoryItems.map((item, _index) => {\n const actualIndex = filteredItems.recent.length + \n filteredItems.filtered.indexOf(item)\n return (\n <CommandItemRow\n key={item.id}\n item={item}\n index={actualIndex}\n selected={selectedIndex === actualIndex}\n onClick={() => executeCommand(item)}\n />\n )\n })}\n </div>\n ))\n )}\n </>\n )}\n </div>\n \n {/* Footer - Spanish-first keyboard shortcuts */}\n <div className=\"border-t border-gray-200 px-4 py-2 flex items-center justify-between text-xs text-gray-500 bg-gray-50\">\n <div className=\"flex items-center gap-4\">\n <span className=\"flex items-center gap-1\">\n <kbd className=\"px-1.5 py-0.5 bg-white border border-gray-200 rounded text-gray-600 font-mono\">↑↓</kbd>\n Navegar\n </span>\n <span className=\"flex items-center gap-1\">\n <kbd className=\"px-1.5 py-0.5 bg-white border border-gray-200 rounded text-gray-600 font-mono\">↵</kbd>\n Seleccionar\n </span>\n </div>\n <span className=\"flex items-center gap-1\">\n <Command className=\"h-3 w-3\" />\n <kbd className=\"px-1.5 py-0.5 bg-white border border-gray-200 rounded text-gray-600 font-mono\">⌘K</kbd>\n </span>\n </div>\n </div>\n </div>\n </>\n )\n}\n\n// Individual command item row\nfunction CommandItemRow({\n item,\n index,\n selected,\n onClick\n}: {\n item: CommandItem\n index: number\n selected: boolean\n onClick: () => void\n}) {\n const Icon = item.icon\n \n return (\n <div\n data-index={index}\n className={cn(\n \"flex items-center gap-3 px-2 py-2 rounded-md cursor-pointer\",\n \"transition-colors duration-150\",\n selected \n ? \"bg-primary-100 text-primary-900\" \n : \"hover:bg-gray-100 text-gray-900\"\n )}\n onClick={onClick}\n >\n {Icon && (\n <Icon className=\"h-4 w-4 text-gray-500 flex-shrink-0\" />\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium\">{item.title}</div>\n {item.description && (\n <div className=\"text-xs text-gray-500 truncate\">\n {item.description}\n </div>\n )}\n </div>\n {item.shortcut && (\n <kbd className=\"px-2 py-1 text-xs bg-gray-200 text-gray-600 rounded border font-mono\">\n {item.shortcut}\n </kbd>\n )}\n <ChevronRight className=\"h-4 w-4 text-gray-400\" />\n </div>\n )\n}\n\n// BIRHAUS: Hook to register command palette items\nexport function useCommandPalette() {\n const [items, setItems] = React.useState<CommandItem[]>([])\n \n const registerCommand = React.useCallback((item: CommandItem) => {\n setItems(prev => [...prev, item])\n \n return () => {\n setItems(prev => prev.filter(i => i.id !== item.id))\n }\n }, [])\n \n const registerCommands = React.useCallback((newItems: CommandItem[]) => {\n setItems(prev => [...prev, ...newItems])\n \n return () => {\n setItems(prev => prev.filter(item => \n !newItems.some(newItem => newItem.id === item.id)\n ))\n }\n }, [])\n \n return {\n items,\n registerCommand,\n registerCommands\n }\n}\n\n","/**\n * BIRHAUS Constants\n * \n * Core limits and configuration values that enforce BIRHAUS principles\n */\n\nexport const BIRHAUS_LIMITS = {\n // Cognitive Load Limits (Miller's Law: 7±2)\n MAX_VISIBLE_CHOICES: 7,\n MIN_VISIBLE_CHOICES: 5,\n \n // 4-3-1 Rule (Core BIRHAUS Navigation)\n MAX_PRIMARY_NAV_ITEMS: 4,\n MAX_CONTEXTUAL_ACTIONS: 3,\n MAX_PRIMARY_ACTIONS: 1,\n \n // Form Design Limits\n MAX_FIELDS_PER_STEP: 5,\n MAX_FORM_STEPS: 4,\n \n // Performance Budgets (ms)\n MAX_TTI: 2000, // Time to Interactive\n MAX_FCP: 1000, // First Contentful Paint\n MAX_CLS: 0.1, // Cumulative Layout Shift\n \n // Table Design\n DEFAULT_TABLE_COLUMNS: 7,\n MAX_TABLE_ROWS_BEFORE_VIRTUALIZATION: 100,\n \n // Undo System\n DEFAULT_UNDO_TIMEOUT: 10000, // 10 seconds\n MAX_UNDO_ACTIONS: 5,\n \n // Accessibility\n MIN_TOUCH_TARGET: 44, // pixels (WCAG AA)\n MIN_CONTRAST_RATIO: 4.5, // WCAG AA\n \n // Animation\n DEFAULT_TRANSITION_DURATION: 150, // ms\n REDUCE_MOTION_DURATION: 0, // ms\n} as const\n\nexport const BIRHAUS_BREAKPOINTS = {\n mobile: 320,\n tablet: 768, \n desktop: 1024,\n wide: 1440,\n} as const\n\nexport const BIRHAUS_Z_INDEX = {\n dropdown: 1000,\n tooltip: 1100,\n overlay: 1200,\n modal: 1300, // Deprecated - BIRHAUS discourages modals\n toast: 1400,\n commandPalette: 1500,\n} as const\n\n/**\n * Supported Languages (Spanish-first)\n */\nexport const BIRHAUS_LANGUAGES = {\n PRIMARY: 'es', // Spanish (Paraguay)\n SECONDARY: 'en', // English (International)\n} as const\n\n/**\n * Component States for Consistent Design\n */\nexport const BIRHAUS_STATES = {\n IDLE: 'idle',\n LOADING: 'loading',\n SUCCESS: 'success',\n WARNING: 'warning', \n ERROR: 'error',\n DISABLED: 'disabled',\n} as const"]}