@fabio.caffarello/react-design-system 3.13.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/dist/granular/ui/components/Autocomplete/Autocomplete.js +103 -86
  2. package/dist/granular/ui/components/Autocomplete/Autocomplete.js.map +1 -1
  3. package/dist/granular/ui/components/Autocomplete/AutocompleteList.js +57 -47
  4. package/dist/granular/ui/components/Autocomplete/AutocompleteList.js.map +1 -1
  5. package/dist/granular/ui/components/Autocomplete/AutocompleteOption.js +21 -20
  6. package/dist/granular/ui/components/Autocomplete/AutocompleteOption.js.map +1 -1
  7. package/dist/granular/ui/components/Breadcrumb/Breadcrumb.js.map +1 -1
  8. package/dist/granular/ui/components/ColorPicker/ColorPicker.js.map +1 -1
  9. package/dist/granular/ui/components/CommandPalette/CommandPalette.js +187 -149
  10. package/dist/granular/ui/components/CommandPalette/CommandPalette.js.map +1 -1
  11. package/dist/granular/ui/components/DataGrid/DataGrid.js +92 -92
  12. package/dist/granular/ui/components/DataGrid/DataGrid.js.map +1 -1
  13. package/dist/granular/ui/components/DatePicker/DatePickerCalendar.js +154 -139
  14. package/dist/granular/ui/components/DatePicker/DatePickerCalendar.js.map +1 -1
  15. package/dist/granular/ui/components/Dialog/AlertDialog.js +73 -40
  16. package/dist/granular/ui/components/Dialog/AlertDialog.js.map +1 -1
  17. package/dist/granular/ui/components/Dialog/DialogContent.js +54 -48
  18. package/dist/granular/ui/components/Dialog/DialogContent.js.map +1 -1
  19. package/dist/granular/ui/components/Dialog/DialogDescription.js +31 -31
  20. package/dist/granular/ui/components/Dialog/DialogDescription.js.map +1 -1
  21. package/dist/granular/ui/components/Dialog/DialogTitle.js +30 -30
  22. package/dist/granular/ui/components/Dialog/DialogTitle.js.map +1 -1
  23. package/dist/granular/ui/components/Drawer/Drawer.js.map +1 -1
  24. package/dist/granular/ui/components/Dropdown/Dropdown.js.map +1 -1
  25. package/dist/granular/ui/components/EmptyState/EmptyState.js.map +1 -1
  26. package/dist/granular/ui/components/FileUpload/FileUpload.js.map +1 -1
  27. package/dist/granular/ui/components/Form/Form.js +38 -37
  28. package/dist/granular/ui/components/Form/Form.js.map +1 -1
  29. package/dist/granular/ui/components/Form/FormField.js +28 -26
  30. package/dist/granular/ui/components/Form/FormField.js.map +1 -1
  31. package/dist/granular/ui/components/Header/Header.js.map +1 -1
  32. package/dist/granular/ui/components/Header/components/HeaderActions.js.map +1 -1
  33. package/dist/granular/ui/components/Header/components/HeaderHamburger.js.map +1 -1
  34. package/dist/granular/ui/components/Header/components/HeaderLogo.js.map +1 -1
  35. package/dist/granular/ui/components/Header/components/HeaderMobileMenu.js.map +1 -1
  36. package/dist/granular/ui/components/Header/components/HeaderNavigation.js.map +1 -1
  37. package/dist/granular/ui/components/Header/contexts/HeaderContext.js.map +1 -1
  38. package/dist/granular/ui/components/Menu/Menu.js.map +1 -1
  39. package/dist/granular/ui/components/Modal/Modal.js +98 -86
  40. package/dist/granular/ui/components/Modal/Modal.js.map +1 -1
  41. package/dist/granular/ui/components/MultiSelect/MultiSelect.js +122 -106
  42. package/dist/granular/ui/components/MultiSelect/MultiSelect.js.map +1 -1
  43. package/dist/granular/ui/components/Navigation/Navigation.js.map +1 -1
  44. package/dist/granular/ui/components/PageHeader/PageHeader.js.map +1 -1
  45. package/dist/granular/ui/components/Pagination/Pagination.js.map +1 -1
  46. package/dist/granular/ui/components/Popover/Popover.js.map +1 -1
  47. package/dist/granular/ui/components/Rating/Rating.js.map +1 -1
  48. package/dist/granular/ui/components/SearchInput/SearchInput.js.map +1 -1
  49. package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarGroup.js +82 -64
  50. package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarGroup.js.map +1 -1
  51. package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarItem.js +30 -29
  52. package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarItem.js.map +1 -1
  53. package/dist/granular/ui/components/SideNavbar/components/SideNavbarResizeHandle.js +37 -35
  54. package/dist/granular/ui/components/SideNavbar/components/SideNavbarResizeHandle.js.map +1 -1
  55. package/dist/granular/ui/components/SideNavbar/providers/SideNavbarStateProvider.js +57 -57
  56. package/dist/granular/ui/components/SideNavbar/providers/SideNavbarStateProvider.js.map +1 -1
  57. package/dist/granular/ui/components/Stepper/Stepper.js +102 -94
  58. package/dist/granular/ui/components/Stepper/Stepper.js.map +1 -1
  59. package/dist/granular/ui/components/Table/Table.js +41 -35
  60. package/dist/granular/ui/components/Table/Table.js.map +1 -1
  61. package/dist/granular/ui/components/Table/TableActions/TableActions.js.map +1 -1
  62. package/dist/granular/ui/components/Table/TableFilters/TableFilters.js +49 -46
  63. package/dist/granular/ui/components/Table/TableFilters/TableFilters.js.map +1 -1
  64. package/dist/granular/ui/components/Table/TablePagination/TablePagination.js.map +1 -1
  65. package/dist/granular/ui/components/Table/TableProvider.js +82 -80
  66. package/dist/granular/ui/components/Table/TableProvider.js.map +1 -1
  67. package/dist/granular/ui/components/Table/TableRow.js +57 -53
  68. package/dist/granular/ui/components/Table/TableRow.js.map +1 -1
  69. package/dist/granular/ui/components/Table/useColumnResizing.js +53 -53
  70. package/dist/granular/ui/components/Table/useColumnResizing.js.map +1 -1
  71. package/dist/granular/ui/components/TimePicker/TimePicker.js +149 -103
  72. package/dist/granular/ui/components/TimePicker/TimePicker.js.map +1 -1
  73. package/dist/granular/ui/components/Timeline/Timeline.js.map +1 -1
  74. package/dist/granular/ui/hooks/useFocusRestore.js +14 -15
  75. package/dist/granular/ui/hooks/useFocusRestore.js.map +1 -1
  76. package/dist/granular/ui/primitives/Badge/Badge.js.map +1 -1
  77. package/dist/granular/ui/primitives/Checkbox/Checkbox.js.map +1 -1
  78. package/dist/granular/ui/primitives/Chip/Chip.js +91 -71
  79. package/dist/granular/ui/primitives/Chip/Chip.js.map +1 -1
  80. package/dist/granular/ui/primitives/ErrorMessage/ErrorMessage.js.map +1 -1
  81. package/dist/granular/ui/primitives/Input/Input.js.map +1 -1
  82. package/dist/granular/ui/primitives/Label/Label.js.map +1 -1
  83. package/dist/granular/ui/primitives/NavLink/NavLink.js.map +1 -1
  84. package/dist/granular/ui/primitives/Radio/Radio.js.map +1 -1
  85. package/dist/granular/ui/primitives/Select/Select.js.map +1 -1
  86. package/dist/granular/ui/primitives/Separator/Separator.js.map +1 -1
  87. package/dist/granular/ui/primitives/Skeleton/Skeleton.js.map +1 -1
  88. package/dist/granular/ui/primitives/Slider/Slider.js.map +1 -1
  89. package/dist/granular/ui/primitives/Spinner/Spinner.js.map +1 -1
  90. package/dist/granular/ui/primitives/Switch/Switch.js.map +1 -1
  91. package/dist/granular/ui/primitives/Tooltip/Tooltip.js.map +1 -1
  92. package/dist/granular/ui/providers/DialogContext.js.map +1 -1
  93. package/dist/granular/ui/providers/DialogProvider.js +24 -20
  94. package/dist/granular/ui/providers/DialogProvider.js.map +1 -1
  95. package/dist/index.cjs +144 -144
  96. package/dist/index.cjs.map +1 -1
  97. package/dist/index.js +5780 -5486
  98. package/dist/index.js.map +1 -1
  99. package/dist/react-design-system.css +1 -1
  100. package/dist/server/index.cjs +7 -7
  101. package/dist/server/index.cjs.map +1 -1
  102. package/dist/server/index.js +404 -384
  103. package/dist/server/index.js.map +1 -1
  104. package/dist/ui/components/Autocomplete/AutocompleteList.d.ts +4 -0
  105. package/dist/ui/components/Autocomplete/AutocompleteOption.d.ts +8 -0
  106. package/dist/ui/components/Breadcrumb/Breadcrumb.d.ts +0 -1
  107. package/dist/ui/components/ColorPicker/ColorPicker.d.ts +0 -1
  108. package/dist/ui/components/CommandPalette/CommandPalette.d.ts +0 -1
  109. package/dist/ui/components/DataGrid/DataGrid.d.ts +0 -1
  110. package/dist/ui/components/Dialog/DialogContent.d.ts +20 -1
  111. package/dist/ui/components/Drawer/Drawer.d.ts +0 -1
  112. package/dist/ui/components/Dropdown/Dropdown.d.ts +0 -1
  113. package/dist/ui/components/EmptyState/EmptyState.d.ts +0 -1
  114. package/dist/ui/components/FileUpload/FileUpload.d.ts +0 -1
  115. package/dist/ui/components/Form/FormField.d.ts +7 -0
  116. package/dist/ui/components/Header/Header.d.ts +1 -1
  117. package/dist/ui/components/Header/components/HeaderActions.d.ts +1 -1
  118. package/dist/ui/components/Header/components/HeaderHamburger.d.ts +1 -1
  119. package/dist/ui/components/Header/components/HeaderLogo.d.ts +1 -1
  120. package/dist/ui/components/Header/components/HeaderMobileMenu.d.ts +1 -1
  121. package/dist/ui/components/Header/components/HeaderNavigation.d.ts +1 -1
  122. package/dist/ui/components/Header/contexts/HeaderContext.d.ts +1 -1
  123. package/dist/ui/components/Menu/Menu.d.ts +0 -1
  124. package/dist/ui/components/Modal/Modal.d.ts +1 -2
  125. package/dist/ui/components/Navigation/Navigation.d.ts +1 -1
  126. package/dist/ui/components/PageHeader/PageHeader.d.ts +1 -1
  127. package/dist/ui/components/Pagination/Pagination.d.ts +0 -1
  128. package/dist/ui/components/Popover/Popover.d.ts +0 -1
  129. package/dist/ui/components/Rating/Rating.d.ts +0 -1
  130. package/dist/ui/components/SearchInput/SearchInput.d.ts +0 -1
  131. package/dist/ui/components/Stepper/Stepper.d.ts +0 -1
  132. package/dist/ui/components/Table/TableActions/TableActions.d.ts +0 -1
  133. package/dist/ui/components/Table/TableFilters/TableFilters.d.ts +0 -1
  134. package/dist/ui/components/Table/TablePagination/TablePagination.d.ts +0 -1
  135. package/dist/ui/components/TimePicker/TimePicker.d.ts +0 -1
  136. package/dist/ui/components/Timeline/Timeline.d.ts +0 -1
  137. package/dist/ui/primitives/Checkbox/Checkbox.d.ts +0 -1
  138. package/dist/ui/primitives/Chip/Chip.d.ts +21 -0
  139. package/dist/ui/primitives/ErrorMessage/ErrorMessage.d.ts +0 -1
  140. package/dist/ui/primitives/Input/Input.d.ts +0 -1
  141. package/dist/ui/primitives/Label/Label.d.ts +0 -1
  142. package/dist/ui/primitives/NavLink/NavLink.d.ts +1 -1
  143. package/dist/ui/primitives/Radio/Radio.d.ts +0 -1
  144. package/dist/ui/primitives/Select/Select.d.ts +0 -1
  145. package/dist/ui/primitives/Skeleton/Skeleton.d.ts +0 -1
  146. package/dist/ui/primitives/Slider/Slider.d.ts +0 -1
  147. package/dist/ui/primitives/Switch/Switch.d.ts +0 -1
  148. package/dist/ui/primitives/Tooltip/Tooltip.d.ts +0 -1
  149. package/dist/ui/providers/DialogContext.d.ts +8 -0
  150. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"CommandPalette.js","sources":["../../../../../src/ui/components/CommandPalette/CommandPalette.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useState,\n useEffect,\n useRef,\n useCallback,\n type KeyboardEvent,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Search, Command } from \"lucide-react\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getShadowClass } from \"../../tokens/shadows\";\nimport { getZIndexClass } from \"../../tokens/z-index\";\nimport { getAnimationClass } from \"../../tokens/animations\";\nimport Input from \"../../primitives/Input/Input\";\n\nexport interface CommandItem {\n id: string;\n label: string;\n description?: string;\n icon?: React.ReactNode;\n keywords?: string[];\n group?: string;\n action: () => void;\n}\n\nexport interface CommandPaletteProps {\n items: CommandItem[];\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: React.ReactNode;\n placeholder?: string;\n emptyMessage?: string;\n className?: string;\n}\n\n/**\n * CommandPalette Component\n *\n * A command palette component for quick command search and execution.\n * Supports keyboard navigation, grouping, and filtering.\n * Follows Atomic Design principles as an Organism component.\n *\n * @example\n * ```tsx\n * <CommandPalette\n * items={[\n * { id: '1', label: 'New File', action: () => console.log('New File') },\n * { id: '2', label: 'Save', action: () => console.log('Save') },\n * ]}\n * />\n * ```\n */\nexport default function CommandPalette({\n items,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n trigger,\n placeholder = \"Type a command or search...\",\n emptyMessage = \"No commands found\",\n className = \"\",\n}: CommandPaletteProps) {\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n // Filter items based on search query\n const filteredItems = items.filter((item) => {\n if (!searchQuery) return true;\n const query = searchQuery.toLowerCase();\n const matchesLabel = item.label.toLowerCase().includes(query);\n const matchesDescription = item.description?.toLowerCase().includes(query);\n const matchesKeywords = item.keywords?.some((keyword) =>\n keyword.toLowerCase().includes(query),\n );\n return matchesLabel || matchesDescription || matchesKeywords;\n });\n\n // Group items\n const groupedItems = filteredItems.reduce(\n (acc, item) => {\n const group = item.group || \"Other\";\n if (!acc[group]) {\n acc[group] = [];\n }\n acc[group].push(item);\n return acc;\n },\n {} as Record<string, CommandItem[]>,\n );\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n if (!isControlled) {\n setInternalOpen(newOpen);\n }\n onOpenChange?.(newOpen);\n if (newOpen) {\n setSearchQuery(\"\");\n setSelectedIndex(0);\n setTimeout(() => inputRef.current?.focus(), 0);\n }\n },\n [isControlled, onOpenChange],\n );\n\n const handleSelect = (item: CommandItem) => {\n item.action();\n handleOpenChange(false);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Escape\") {\n handleOpenChange(false);\n return;\n }\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setSelectedIndex((prev) => Math.min(prev + 1, filteredItems.length - 1));\n return;\n }\n\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setSelectedIndex((prev) => Math.max(prev - 1, 0));\n return;\n }\n\n if (e.key === \"Enter\") {\n e.preventDefault();\n if (filteredItems[selectedIndex]) {\n handleSelect(filteredItems[selectedIndex]);\n }\n return;\n }\n };\n\n // Scroll selected item into view\n useEffect(() => {\n if (listRef.current && selectedIndex >= 0) {\n const selectedElement = listRef.current.querySelector(\n `[data-index=\"${selectedIndex}\"]`,\n );\n if (\n selectedElement &&\n typeof selectedElement.scrollIntoView === \"function\"\n ) {\n selectedElement.scrollIntoView({\n block: \"nearest\",\n behavior: \"smooth\",\n });\n }\n }\n }, [selectedIndex]);\n\n // Reset selected index when search changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [searchQuery]);\n\n // Keyboard shortcut (Cmd/Ctrl + K)\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"k\") {\n e.preventDefault();\n handleOpenChange(!isOpen);\n }\n };\n\n document.addEventListener(\n \"keydown\",\n handleKeyDown as unknown as EventListener,\n );\n return () =>\n document.removeEventListener(\n \"keydown\",\n handleKeyDown as unknown as EventListener,\n );\n }, [isOpen, handleOpenChange]);\n\n const commandPaletteContent = isOpen ? (\n <div\n className={`\n fixed\n inset-0\n ${getZIndexClass(\"modal-backdrop\")}\n bg-scrim\n flex\n items-start\n justify-center\n pt-[20vh]\n ${getAnimationClass(\"base\")}\n `}\n onClick={() => handleOpenChange(false)}\n >\n <div\n className={`\n w-full\n max-w-2xl\n ${getSpacingClass(\"base\", \"mx\")}\n bg-surface-overlay\n ${getRadiusClass(\"lg\")}\n ${getShadowClass(\"xl\")}\n ${getZIndexClass(\"modal\")}\n ${getAnimationClass(\"base\")}\n ${className}\n `}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Search Input */}\n <div\n className={`\n flex\n items-center\n ${getSpacingClass(\"md\", \"gap\")}\n ${getSpacingClass(\"base\", \"p\")}\n border-b\n border-line-default\n `}\n >\n <Search className=\"h-5 w-5 text-fg-secondary\" />\n <Input\n ref={inputRef}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"flex-1 border-0 focus:ring-0\"\n autoFocus\n />\n <div\n className={`\n flex\n items-center\n ${getSpacingClass(\"xs\", \"gap\")}\n ${getSpacingClass(\"sm\", \"px\")}\n ${getSpacingClass(\"xs\", \"py\")}\n ${getRadiusClass(\"sm\")}\n bg-surface-muted\n text-xs\n text-fg-tertiary\n `}\n >\n <Command className=\"h-3 w-3\" />\n <span>K</span>\n </div>\n </div>\n\n {/* Results */}\n <div\n ref={listRef}\n className={`\n max-h-96\n overflow-y-auto\n ${getSpacingClass(\"sm\", \"py\")}\n `}\n >\n {Object.keys(groupedItems).length === 0 ? (\n <div\n className={`\n ${getSpacingClass(\"lg\", \"p\")}\n text-center\n text-sm\n text-fg-secondary\n `}\n >\n {emptyMessage}\n </div>\n ) : (\n Object.entries(groupedItems).map(([group, groupItems]) => (\n <div key={group}>\n {group !== \"Other\" && (\n <div\n className={`\n ${getSpacingClass(\"sm\", \"px\")}\n ${getSpacingClass(\"xs\", \"py\")}\n text-xs\n font-semibold\n text-fg-tertiary\n uppercase\n tracking-wider\n `}\n >\n {group}\n </div>\n )}\n {groupItems.map((item, _index) => {\n const globalIndex = filteredItems.indexOf(item);\n const isSelected = globalIndex === selectedIndex;\n\n return (\n <button\n key={item.id}\n type=\"button\"\n data-index={globalIndex}\n onClick={() => handleSelect(item)}\n className={`\n w-full\n flex\n items-center\n ${getSpacingClass(\"md\", \"gap\")}\n ${getSpacingClass(\"base\", \"px\")}\n ${getSpacingClass(\"md\", \"py\")}\n text-left\n ${getAnimationClass(\"base\")}\n ${isSelected ? \"bg-surface-brand-muted\" : \"hover:bg-surface-hover\"}\n `}\n >\n {item.icon && (\n <div\n className={`\n ${\n isSelected\n ? \"text-fg-brand-emphasis\"\n : \"text-fg-secondary\"\n }\n `}\n >\n {item.icon}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div\n className={`\n text-sm\n font-medium\n ${isSelected ? \"text-fg-brand-emphasis\" : \"text-fg-primary\"}\n `}\n >\n {item.label}\n </div>\n {item.description && (\n // fg-secondary on selected: brand-muted bg drops fg-tertiary below AA;\n // caption role preserved, intensity raised for contrast.\n <div\n className={`text-xs ${isSelected ? \"text-fg-secondary\" : \"text-fg-tertiary\"} ${getSpacingClass(\"0.5\", \"mt\")}`}\n >\n {item.description}\n </div>\n )}\n </div>\n </button>\n );\n })}\n </div>\n ))\n )}\n </div>\n </div>\n </div>\n ) : null;\n\n return (\n <>\n {trigger ? (\n <div onClick={() => handleOpenChange(true)}>{trigger}</div>\n ) : null}\n {typeof window !== \"undefined\" &&\n createPortal(commandPaletteContent, document.body)}\n </>\n );\n}\n"],"names":["CommandPalette","items","controlledOpen","defaultOpen","onOpenChange","trigger","placeholder","emptyMessage","className","internalOpen","setInternalOpen","useState","searchQuery","setSearchQuery","selectedIndex","setSelectedIndex","inputRef","useRef","listRef","isControlled","isOpen","filteredItems","item","query","matchesLabel","matchesDescription","_a","matchesKeywords","_b","keyword","groupedItems","acc","group","handleOpenChange","useCallback","newOpen","handleSelect","handleKeyDown","prev","useEffect","selectedElement","e","commandPaletteContent","jsx","getZIndexClass","getAnimationClass","jsxs","getSpacingClass","getRadiusClass","getShadowClass","Search","Input","Command","groupItems","_index","globalIndex","isSelected","Fragment","createPortal"],"mappings":"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"}
1
+ {"version":3,"file":"CommandPalette.js","sources":["../../../../../src/ui/components/CommandPalette/CommandPalette.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useState,\n useEffect,\n useRef,\n useCallback,\n useId,\n type KeyboardEvent,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Search, Command } from \"lucide-react\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getShadowClass } from \"../../tokens/shadows\";\nimport { getZIndexClass } from \"../../tokens/z-index\";\nimport { getAnimationClass } from \"../../tokens/animations\";\nimport Input from \"../../primitives/Input/Input\";\nimport { useFocusTrap } from \"../../hooks/useFocusTrap\";\nimport { useFocusRestore } from \"../../hooks/useFocusRestore\";\n\nexport interface CommandItem {\n id: string;\n label: string;\n description?: string;\n icon?: React.ReactNode;\n keywords?: string[];\n group?: string;\n action: () => void;\n}\n\nexport interface CommandPaletteProps {\n items: CommandItem[];\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: React.ReactNode;\n placeholder?: string;\n emptyMessage?: string;\n className?: string;\n}\n\n/**\n * CommandPalette Component\n *\n * A command palette component for quick command search and execution.\n * Supports keyboard navigation, grouping, and filtering.\n *\n * @example\n * ```tsx\n * <CommandPalette\n * items={[\n * { id: '1', label: 'New File', action: () => console.log('New File') },\n * { id: '2', label: 'Save', action: () => console.log('Save') },\n * ]}\n * />\n * ```\n */\nexport default function CommandPalette({\n items,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n trigger,\n placeholder = \"Type a command or search...\",\n emptyMessage = \"No commands found\",\n className = \"\",\n}: CommandPaletteProps) {\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const listboxId = useId();\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n // Modal command palette: trap Tab within the panel while open and\n // return focus to whatever opened it on close (the panel renders\n // role=\"dialog\" aria-modal=\"true\" below — without these the overlay\n // leaked focus to the page behind it and stranded keyboard users).\n useFocusRestore(isOpen);\n useFocusTrap(panelRef, isOpen);\n\n // Filter items based on search query\n const filteredItems = items.filter((item) => {\n if (!searchQuery) return true;\n const query = searchQuery.toLowerCase();\n const matchesLabel = item.label.toLowerCase().includes(query);\n const matchesDescription = item.description?.toLowerCase().includes(query);\n const matchesKeywords = item.keywords?.some((keyword) =>\n keyword.toLowerCase().includes(query),\n );\n return matchesLabel || matchesDescription || matchesKeywords;\n });\n\n // Group items\n const groupedItems = filteredItems.reduce(\n (acc, item) => {\n const group = item.group || \"Other\";\n if (!acc[group]) {\n acc[group] = [];\n }\n acc[group].push(item);\n return acc;\n },\n {} as Record<string, CommandItem[]>,\n );\n\n // Flatten groups in VISUAL render order so keyboard selectedIndex and\n // the rendered order agree. filteredItems keeps original-items order,\n // which diverges from the grouped layout once groups interleave — so\n // ArrowDown/Up appeared to jump around the list.\n const orderedItems = Object.values(groupedItems).flat();\n const activeOptionId =\n isOpen && orderedItems[selectedIndex]\n ? `${listboxId}-option-${selectedIndex}`\n : undefined;\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n if (!isControlled) {\n setInternalOpen(newOpen);\n }\n onOpenChange?.(newOpen);\n if (newOpen) {\n setSearchQuery(\"\");\n setSelectedIndex(0);\n }\n },\n [isControlled, onOpenChange],\n );\n\n // Focus the search input when the palette opens. Deferred via an effect\n // (NOT the autoFocus attribute) so it runs AFTER useFocusRestore's\n // passive effect has snapshotted the opener. A synchronous autoFocus\n // fires during commit, before that snapshot, so the snapshot would\n // capture the input itself and focus restore on close would no-op.\n useEffect(() => {\n if (!isOpen) return;\n const timer = setTimeout(() => inputRef.current?.focus(), 0);\n return () => clearTimeout(timer);\n }, [isOpen]);\n\n const handleSelect = (item: CommandItem) => {\n item.action();\n handleOpenChange(false);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Escape\") {\n handleOpenChange(false);\n return;\n }\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setSelectedIndex((prev) => Math.min(prev + 1, orderedItems.length - 1));\n return;\n }\n\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setSelectedIndex((prev) => Math.max(prev - 1, 0));\n return;\n }\n\n if (e.key === \"Enter\") {\n e.preventDefault();\n if (orderedItems[selectedIndex]) {\n handleSelect(orderedItems[selectedIndex]);\n }\n return;\n }\n };\n\n // Scroll selected item into view\n useEffect(() => {\n if (listRef.current && selectedIndex >= 0) {\n const selectedElement = listRef.current.querySelector(\n `[data-index=\"${selectedIndex}\"]`,\n );\n if (\n selectedElement &&\n typeof selectedElement.scrollIntoView === \"function\"\n ) {\n selectedElement.scrollIntoView({\n block: \"nearest\",\n behavior: \"smooth\",\n });\n }\n }\n }, [selectedIndex]);\n\n // Reset selected index when search changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [searchQuery]);\n\n // Keyboard shortcut (Cmd/Ctrl + K)\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"k\") {\n e.preventDefault();\n handleOpenChange(!isOpen);\n }\n };\n\n document.addEventListener(\n \"keydown\",\n handleKeyDown as unknown as EventListener,\n );\n return () =>\n document.removeEventListener(\n \"keydown\",\n handleKeyDown as unknown as EventListener,\n );\n }, [isOpen, handleOpenChange]);\n\n const commandPaletteContent = isOpen ? (\n <div\n className={`\n fixed\n inset-0\n ${getZIndexClass(\"modal-backdrop\")}\n bg-scrim\n flex\n items-start\n justify-center\n pt-[20vh]\n ${getAnimationClass(\"base\")}\n `}\n onClick={() => handleOpenChange(false)}\n >\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command palette\"\n className={`\n w-full\n max-w-2xl\n ${getSpacingClass(\"base\", \"mx\")}\n bg-surface-overlay\n ${getRadiusClass(\"lg\")}\n ${getShadowClass(\"xl\")}\n ${getZIndexClass(\"modal\")}\n ${getAnimationClass(\"base\")}\n ${className}\n `}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Search Input */}\n <div\n className={`\n flex\n items-center\n ${getSpacingClass(\"md\", \"gap\")}\n ${getSpacingClass(\"base\", \"p\")}\n border-b\n border-line-default\n `}\n >\n <Search className=\"h-5 w-5 text-fg-secondary\" />\n <Input\n ref={inputRef}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"flex-1 border-0 focus:ring-0\"\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-controls={listboxId}\n aria-activedescendant={activeOptionId}\n aria-autocomplete=\"list\"\n aria-label={placeholder}\n />\n <div\n className={`\n flex\n items-center\n ${getSpacingClass(\"xs\", \"gap\")}\n ${getSpacingClass(\"sm\", \"px\")}\n ${getSpacingClass(\"xs\", \"py\")}\n ${getRadiusClass(\"sm\")}\n bg-surface-muted\n text-xs\n text-fg-tertiary\n `}\n >\n <Command className=\"h-3 w-3\" />\n <span>K</span>\n </div>\n </div>\n\n {/* Results */}\n <div\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Commands\"\n className={`\n max-h-96\n overflow-y-auto\n ${getSpacingClass(\"sm\", \"py\")}\n `}\n >\n {Object.entries(groupedItems).map(([group, groupItems]) => (\n <div\n key={group}\n role=\"group\"\n aria-label={group !== \"Other\" ? group : undefined}\n >\n {group !== \"Other\" && (\n <div\n aria-hidden=\"true\"\n className={`\n ${getSpacingClass(\"sm\", \"px\")}\n ${getSpacingClass(\"xs\", \"py\")}\n text-xs\n font-semibold\n text-fg-tertiary\n uppercase\n tracking-wider\n `}\n >\n {group}\n </div>\n )}\n {groupItems.map((item, _index) => {\n const globalIndex = orderedItems.indexOf(item);\n const isSelected = globalIndex === selectedIndex;\n\n return (\n <button\n key={item.id}\n type=\"button\"\n id={`${listboxId}-option-${globalIndex}`}\n role=\"option\"\n aria-selected={isSelected}\n tabIndex={-1}\n data-index={globalIndex}\n onClick={() => handleSelect(item)}\n className={`\n w-full\n flex\n items-center\n ${getSpacingClass(\"md\", \"gap\")}\n ${getSpacingClass(\"base\", \"px\")}\n ${getSpacingClass(\"md\", \"py\")}\n text-left\n ${getAnimationClass(\"base\")}\n ${isSelected ? \"bg-surface-brand-muted\" : \"hover:bg-surface-hover\"}\n `}\n >\n {item.icon && (\n <div\n className={`\n ${\n isSelected\n ? \"text-fg-brand-emphasis\"\n : \"text-fg-secondary\"\n }\n `}\n >\n {item.icon}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div\n className={`\n text-sm\n font-medium\n ${isSelected ? \"text-fg-brand-emphasis\" : \"text-fg-primary\"}\n `}\n >\n {item.label}\n </div>\n {item.description && (\n // fg-secondary on selected: brand-muted bg drops fg-tertiary below AA;\n // caption role preserved, intensity raised for contrast.\n <div\n className={`text-xs ${isSelected ? \"text-fg-secondary\" : \"text-fg-tertiary\"} ${getSpacingClass(\"0.5\", \"mt\")}`}\n >\n {item.description}\n </div>\n )}\n </div>\n </button>\n );\n })}\n </div>\n ))}\n </div>\n {/* Empty state lives OUTSIDE the listbox: a listbox whose only\n child is a message violates aria-required-children (critical),\n whereas an empty listbox is allowed. role=status announces it. */}\n {Object.keys(groupedItems).length === 0 && (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={`\n ${getSpacingClass(\"lg\", \"p\")}\n text-center\n text-sm\n text-fg-secondary\n `}\n >\n {emptyMessage}\n </div>\n )}\n </div>\n </div>\n ) : null;\n\n return (\n <>\n {trigger ? (\n <div onClick={() => handleOpenChange(true)}>{trigger}</div>\n ) : null}\n {typeof window !== \"undefined\" &&\n createPortal(commandPaletteContent, document.body)}\n </>\n );\n}\n"],"names":["CommandPalette","items","controlledOpen","defaultOpen","onOpenChange","trigger","placeholder","emptyMessage","className","internalOpen","setInternalOpen","useState","searchQuery","setSearchQuery","selectedIndex","setSelectedIndex","inputRef","useRef","listRef","panelRef","listboxId","useId","isControlled","isOpen","useFocusRestore","useFocusTrap","groupedItems","item","query","matchesLabel","matchesDescription","_a","matchesKeywords","_b","keyword","acc","group","orderedItems","activeOptionId","handleOpenChange","useCallback","newOpen","useEffect","timer","handleSelect","handleKeyDown","prev","selectedElement","e","commandPaletteContent","jsx","getZIndexClass","getAnimationClass","jsxs","getSpacingClass","getRadiusClass","getShadowClass","Search","Input","Command","groupItems","_index","globalIndex","isSelected","Fragment","createPortal"],"mappings":"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"}
@@ -1,112 +1,112 @@
1
1
  "use client";
2
- var A = Object.defineProperty, z = Object.defineProperties;
3
- var ee = Object.getOwnPropertyDescriptors;
4
- var $ = Object.getOwnPropertySymbols;
5
- var te = Object.prototype.hasOwnProperty, se = Object.prototype.propertyIsEnumerable;
6
- var U = (s, t, o) => t in s ? A(s, t, { enumerable: !0, configurable: !0, writable: !0, value: o }) : s[t] = o, g = (s, t) => {
7
- for (var o in t || (t = {}))
8
- te.call(t, o) && U(s, o, t[o]);
9
- if ($)
10
- for (var o of $(t))
11
- se.call(t, o) && U(s, o, t[o]);
12
- return s;
13
- }, h = (s, t) => z(s, ee(t));
14
- import { jsxs as x, jsx as c } from "react/jsx-runtime";
15
- import { useState as oe, useMemo as re } from "react";
16
- import { Download as ne } from "lucide-react";
17
- import ae from "../Table/Table.js";
18
- import { Button as le } from "../../primitives/Button/Button.js";
19
- import { getSpacingClass as i } from "../../tokens/spacing.js";
20
- import { getRadiusClass as ce } from "../../tokens/radius.js";
21
- function $e({
22
- columns: s,
23
- data: t,
2
+ var se = Object.defineProperty, te = Object.defineProperties;
3
+ var oe = Object.getOwnPropertyDescriptors;
4
+ var L = Object.getOwnPropertySymbols;
5
+ var ne = Object.prototype.hasOwnProperty, re = Object.prototype.propertyIsEnumerable;
6
+ var N = (t, s, o) => s in t ? se(t, s, { enumerable: !0, configurable: !0, writable: !0, value: o }) : t[s] = o, g = (t, s) => {
7
+ for (var o in s || (s = {}))
8
+ ne.call(s, o) && N(t, o, s[o]);
9
+ if (L)
10
+ for (var o of L(s))
11
+ re.call(s, o) && N(t, o, s[o]);
12
+ return t;
13
+ }, h = (t, s) => te(t, oe(s));
14
+ import { jsxs as j, jsx as m } from "react/jsx-runtime";
15
+ import { useState as le, useMemo as ae } from "react";
16
+ import { Download as ce } from "lucide-react";
17
+ import ie from "../Table/Table.js";
18
+ import { Button as me } from "../../primitives/Button/Button.js";
19
+ import { getSpacingClass as p } from "../../tokens/spacing.js";
20
+ import { getRadiusClass as pe } from "../../tokens/radius.js";
21
+ function Ne({
22
+ columns: t,
23
+ data: s,
24
24
  loading: o = !1,
25
- onSort: y,
26
- sortColumn: L,
27
- sortDirection: N,
28
- multiSort: ie = !1,
25
+ onSort: R,
26
+ sortColumn: S,
27
+ sortDirection: k,
28
+ multiSort: de = !1,
29
29
  // Grouping props are @experimental — see DataGridGroup JSDoc. Accepted
30
30
  // for forward-compatibility but not yet wired to rendering.
31
- groups: me,
32
- onGroupChange: pe,
33
- groupable: de = !1,
34
- resizable: R = !0,
35
- reorderable: ue = !1,
36
- onColumnReorder: fe,
37
- columnWidths: k,
31
+ groups: ue,
32
+ onGroupChange: fe,
33
+ groupable: be = !1,
34
+ resizable: y = !0,
35
+ reorderable: ge = !1,
36
+ onColumnReorder: he,
37
+ columnWidths: v,
38
38
  onColumnResize: d,
39
- selectable: S = !1,
40
- selectedRows: O,
41
- onSelectionChange: _,
39
+ selectable: O = !1,
40
+ selectedRows: _,
41
+ onSelectionChange: W,
42
42
  rowId: D,
43
- exportable: j = !1,
44
- onExport: v,
45
- exportFormats: W = ["csv", "xlsx", "json"],
43
+ exportable: x = !1,
44
+ onExport: u,
45
+ exportFormats: C = ["csv", "xlsx", "json"],
46
46
  pagination: B,
47
47
  filters: G,
48
48
  actions: T,
49
49
  toolbarActions: w,
50
- virtualScrolling: E = !1,
51
- virtualScrollingOptions: I,
52
- emptyMessage: J,
50
+ virtualScrolling: I = !1,
51
+ virtualScrollingOptions: J,
52
+ emptyMessage: E,
53
53
  emptyStateTitle: M,
54
54
  emptyStateMessage: V,
55
55
  emptyStateIllustration: q,
56
- emptyStateAction: F,
57
- className: H = ""
56
+ emptyStateAction: H,
57
+ className: K = ""
58
58
  }) {
59
- const [u, K] = oe(k || {}), P = re(() => s.map((e) => h(g({}, e), {
60
- width: u[e.key] || e.defaultWidth
61
- })), [s, u]), Q = (e) => {
62
- v ? v(e) : e === "csv" ? X(t, s) : e === "json" && Y(t);
63
- }, X = (e, n) => {
64
- const a = n.filter((r) => r.exportable !== !1).map((r) => r.label || r.key), m = e.map(
65
- (r) => n.filter((b) => b.exportable !== !1).map((b) => {
66
- const p = r[b.key];
67
- return typeof p == "string" && p.includes(",") ? `"${p}"` : p;
68
- })
69
- ), l = [a.join(","), ...m.map((r) => r.join(","))].join(`
70
- `), Z = new Blob([l], { type: "text/csv" }), C = URL.createObjectURL(Z), f = document.createElement("a");
71
- f.href = C, f.download = `export-${Date.now()}.csv`, f.click(), URL.revokeObjectURL(C);
72
- }, Y = (e) => {
73
- const n = JSON.stringify(e, null, 2), a = new Blob([n], { type: "application/json" }), m = URL.createObjectURL(a), l = document.createElement("a");
74
- l.href = m, l.download = `export-${Date.now()}.json`, l.click(), URL.revokeObjectURL(m);
59
+ const [P, Q] = le({}), $ = v !== void 0, f = $ ? v : P, X = ae(() => t.map((e) => h(g({}, e), {
60
+ width: f[e.key] || e.defaultWidth
61
+ })), [t, f]), Y = (e) => {
62
+ u ? u(e) : e === "csv" ? Z(s, t) : e === "json" && A(s);
63
+ }, Z = (e, r) => {
64
+ const l = (n) => {
65
+ const i = n == null ? "" : String(n);
66
+ return /[",\n\r]/.test(i) ? `"${i.replace(/"/g, '""')}"` : i;
67
+ }, a = r.filter((n) => n.exportable !== !1), c = a.map((n) => l(n.label || n.key)), F = e.map((n) => a.map((i) => l(n[i.key]))), z = [c.join(","), ...F.map((n) => n.join(","))].join(
68
+ `\r
69
+ `
70
+ ), ee = new Blob([z], { type: "text/csv" }), U = URL.createObjectURL(ee), b = document.createElement("a");
71
+ b.href = U, b.download = `export-${Date.now()}.csv`, b.click(), URL.revokeObjectURL(U);
72
+ }, A = (e) => {
73
+ const r = JSON.stringify(e, null, 2), l = new Blob([r], { type: "application/json" }), a = URL.createObjectURL(l), c = document.createElement("a");
74
+ c.href = a, c.download = `export-${Date.now()}.json`, c.click(), URL.revokeObjectURL(a);
75
75
  };
76
- return /* @__PURE__ */ x("div", { className: `${i("base", "space-y")} ${H}`, children: [
77
- (j || w) && /* @__PURE__ */ x(
76
+ return /* @__PURE__ */ j("div", { className: `${p("base", "space-y")} ${K}`, children: [
77
+ (x || w) && /* @__PURE__ */ j(
78
78
  "div",
79
79
  {
80
80
  className: `
81
81
  flex
82
82
  items-center
83
83
  justify-between
84
- ${i("base", "p")}
84
+ ${p("base", "p")}
85
85
  bg-surface-base
86
86
  border
87
87
  border-line-default
88
- ${ce("lg")}
88
+ ${pe("lg")}
89
89
  `,
90
90
  children: [
91
- /* @__PURE__ */ c(
91
+ /* @__PURE__ */ m(
92
92
  "div",
93
93
  {
94
- className: `flex items-center ${i("sm", "gap")}`
94
+ className: `flex items-center ${p("sm", "gap")}`
95
95
  }
96
96
  ),
97
- /* @__PURE__ */ x("div", { className: `flex items-center ${i("sm", "gap")}`, children: [
97
+ /* @__PURE__ */ j("div", { className: `flex items-center ${p("sm", "gap")}`, children: [
98
98
  w,
99
- j && /* @__PURE__ */ c(
99
+ x && /* @__PURE__ */ m(
100
100
  "div",
101
101
  {
102
- className: `flex items-center ${i("xs", "gap")}`,
103
- children: W.map((e) => /* @__PURE__ */ c(
104
- le,
102
+ className: `flex items-center ${p("xs", "gap")}`,
103
+ children: (u ? C : C.filter((e) => e === "csv" || e === "json")).map((e) => /* @__PURE__ */ m(
104
+ me,
105
105
  {
106
106
  variant: "outline",
107
107
  size: "sm",
108
- leftIcon: /* @__PURE__ */ c(ne, { className: "h-4 w-4" }),
109
- onClick: () => Q(e),
108
+ leftIcon: /* @__PURE__ */ m(ce, { className: "h-4 w-4" }),
109
+ onClick: () => Y(e),
110
110
  children: e.toUpperCase()
111
111
  },
112
112
  e
@@ -117,39 +117,39 @@ function $e({
117
117
  ]
118
118
  }
119
119
  ),
120
- /* @__PURE__ */ c(
121
- ae,
120
+ /* @__PURE__ */ m(
121
+ ie,
122
122
  {
123
- columns: P,
124
- data: t,
123
+ columns: X,
124
+ data: s,
125
125
  loading: o,
126
- onSort: y,
127
- sortColumn: L,
128
- sortDirection: N,
126
+ onSort: R,
127
+ sortColumn: S,
128
+ sortDirection: k,
129
129
  pagination: B,
130
130
  filters: G,
131
- selectable: S,
132
- selectedRows: O,
133
- onSelectionChange: _,
131
+ selectable: O,
132
+ selectedRows: _,
133
+ onSelectionChange: W,
134
134
  rowId: D,
135
135
  actions: T,
136
- resizable: R,
137
- columnWidths: u,
138
- onColumnResize: (e, n) => {
139
- K((a) => h(g({}, a), { [e]: n })), d == null || d(e, n);
136
+ resizable: y,
137
+ columnWidths: f,
138
+ onColumnResize: (e, r) => {
139
+ $ || Q((l) => h(g({}, l), { [e]: r })), d == null || d(e, r);
140
140
  },
141
- virtualScrolling: E,
142
- virtualScrollingOptions: I,
143
- emptyMessage: J,
141
+ virtualScrolling: I,
142
+ virtualScrollingOptions: J,
143
+ emptyMessage: E,
144
144
  emptyStateTitle: M,
145
145
  emptyStateMessage: V,
146
146
  emptyStateIllustration: q,
147
- emptyStateAction: F
147
+ emptyStateAction: H
148
148
  }
149
149
  )
150
150
  ] });
151
151
  }
152
152
  export {
153
- $e as default
153
+ Ne as default
154
154
  };
155
155
  //# sourceMappingURL=DataGrid.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataGrid.js","sources":["../../../../../src/ui/components/DataGrid/DataGrid.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, useMemo, type ReactNode } from \"react\";\nimport { Download } from \"lucide-react\";\nimport Table, { type TableColumn } from \"../Table/Table\";\nimport Button from \"../../primitives/Button/Button\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport type { TableAction } from \"../Table/TableActions/TableActions\";\nimport type {\n FilterConfig,\n FilterValue,\n} from \"../Table/TableFilters/TableFilters\";\n\nexport type DataGridColumn<T = unknown> = TableColumn<T> & {\n groupable?: boolean;\n exportable?: boolean;\n defaultWidth?: number;\n minWidth?: number;\n maxWidth?: number;\n};\n\n/**\n * @experimental Reserved for upcoming row-grouping support; not yet wired\n * to rendering. The shape is fixed for forward-compatibility, but passing\n * a `groups` array to `<DataGrid>` has no visual effect today. Tracked in\n * BACKLOG.md under \"DataGrid row grouping — props/types reserved\".\n */\nexport interface DataGridGroup {\n column: string;\n expanded?: boolean;\n}\n\nexport interface DataGridProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n> {\n columns: DataGridColumn<T>[];\n data: T[];\n loading?: boolean;\n\n // Sorting\n onSort?: (columnKey: string, direction: \"asc\" | \"desc\") => void;\n sortColumn?: string;\n sortDirection?: \"asc\" | \"desc\";\n multiSort?: boolean;\n\n // Grouping\n /**\n * @experimental Reserved for upcoming row-grouping support; not yet wired\n * to rendering. Passing this has no visual effect today — the grid renders\n * a flat table regardless. Tracked in BACKLOG.md under \"DataGrid row\n * grouping — props/types reserved\".\n */\n groups?: DataGridGroup[];\n /**\n * @experimental Reserved for upcoming row-grouping support; not yet wired.\n * The callback is never invoked today. Tracked in BACKLOG.md.\n */\n onGroupChange?: (groups: DataGridGroup[]) => void;\n /**\n * @experimental Reserved for upcoming row-grouping support; not yet wired.\n * Passing `true` has no visual effect today — the grouping toolbar button\n * was removed because it rendered but had no behaviour. Tracked in\n * BACKLOG.md.\n */\n groupable?: boolean;\n\n // Column Management\n resizable?: boolean;\n reorderable?: boolean;\n onColumnReorder?: (columns: DataGridColumn<T>[]) => void;\n columnWidths?: Record<string, number>;\n onColumnResize?: (columnKey: string, width: number) => void;\n\n // Selection\n selectable?: boolean;\n selectedRows?: string[];\n onSelectionChange?: (selected: string[]) => void;\n rowId?: (row: T) => string;\n\n // Export\n exportable?: boolean;\n onExport?: (format: \"csv\" | \"xlsx\" | \"json\") => void;\n exportFormats?: (\"csv\" | \"xlsx\" | \"json\")[];\n\n // Pagination\n pagination?: {\n page: number;\n pageSize: number;\n total: number;\n onPageChange: (page: number) => void;\n onPageSizeChange: (size: number) => void;\n pageSizeOptions?: number[];\n };\n\n // Filters\n filters?: {\n config: FilterConfig[];\n onFilter: (filters: Record<string, FilterValue>) => void;\n initialValues?: Record<string, FilterValue>;\n };\n\n // Actions\n actions?: (row: T) => TableAction<T>[];\n toolbarActions?: ReactNode;\n\n // Virtual Scrolling\n virtualScrolling?: boolean;\n virtualScrollingOptions?: {\n itemHeight?: number;\n containerHeight?: number;\n overscan?: number;\n };\n\n // Empty State\n emptyMessage?: string;\n emptyStateTitle?: string;\n emptyStateMessage?: string;\n emptyStateIllustration?: ReactNode;\n emptyStateAction?: ReactNode;\n\n className?: string;\n}\n\n/**\n * DataGrid Component\n *\n * An advanced data grid component with sorting, filtering, grouping, column management, and export.\n * Extends the Table component with additional enterprise features.\n * Follows Atomic Design principles as an Organism component.\n *\n * @example\n * ```tsx\n * <DataGrid\n * columns={columns}\n * data={data}\n * groupable\n * exportable\n * onExport={(format) => console.log('Export as', format)}\n * />\n * ```\n */\nexport default function DataGrid<\n T extends Record<string, unknown> = Record<string, unknown>,\n>({\n columns,\n data,\n loading = false,\n onSort,\n sortColumn,\n sortDirection,\n multiSort: _multiSort = false,\n // Grouping props are @experimental — see DataGridGroup JSDoc. Accepted\n // for forward-compatibility but not yet wired to rendering.\n groups: _groups,\n onGroupChange: _onGroupChange,\n groupable: _groupable = false,\n resizable = true,\n reorderable: _reorderable = false,\n onColumnReorder: _onColumnReorder,\n columnWidths,\n onColumnResize,\n selectable = false,\n selectedRows,\n onSelectionChange,\n rowId,\n exportable = false,\n onExport,\n exportFormats = [\"csv\", \"xlsx\", \"json\"],\n pagination,\n filters,\n actions,\n toolbarActions,\n virtualScrolling = false,\n virtualScrollingOptions,\n emptyMessage,\n emptyStateTitle,\n emptyStateMessage,\n emptyStateIllustration,\n emptyStateAction,\n className = \"\",\n}: DataGridProps<T>) {\n const [internalColumnWidths, setInternalColumnWidths] = useState<\n Record<string, number>\n >(columnWidths || {});\n\n // Convert DataGrid columns to Table columns\n const tableColumns: TableColumn<T>[] = useMemo(() => {\n return columns.map((col) => ({\n ...col,\n width: internalColumnWidths[col.key as string] || col.defaultWidth,\n }));\n }, [columns, internalColumnWidths]);\n\n const handleExport = (format: \"csv\" | \"xlsx\" | \"json\") => {\n if (onExport) {\n onExport(format);\n } else {\n // Default export implementation\n if (format === \"csv\") {\n exportToCSV(data, columns);\n } else if (format === \"json\") {\n exportToJSON(data);\n }\n }\n };\n\n const exportToCSV = (data: T[], cols: DataGridColumn<T>[]) => {\n const headers = cols\n .filter((c) => c.exportable !== false)\n .map((c) => c.label || c.key);\n const rows = data.map((row) =>\n cols\n .filter((c) => c.exportable !== false)\n .map((c) => {\n const value = row[c.key];\n return typeof value === \"string\" && value.includes(\",\")\n ? `\"${value}\"`\n : value;\n }),\n );\n\n const csv = [headers.join(\",\"), ...rows.map((r) => r.join(\",\"))].join(\"\\n\");\n const blob = new Blob([csv], { type: \"text/csv\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `export-${Date.now()}.csv`;\n a.click();\n URL.revokeObjectURL(url);\n };\n\n const exportToJSON = (data: T[]) => {\n const json = JSON.stringify(data, null, 2);\n const blob = new Blob([json], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `export-${Date.now()}.json`;\n a.click();\n URL.revokeObjectURL(url);\n };\n\n return (\n <div className={`${getSpacingClass(\"base\", \"space-y\")} ${className}`}>\n {/* Toolbar */}\n {(exportable || toolbarActions) && (\n <div\n className={`\n flex\n items-center\n justify-between\n ${getSpacingClass(\"base\", \"p\")}\n bg-surface-base\n border\n border-line-default\n ${getRadiusClass(\"lg\")}\n `}\n >\n {/* Left slot reserved for the grouping toolbar (currently\n @experimental — see DataGridGroup JSDoc). The empty div\n preserves the justify-between layout so toolbarActions and\n the export controls stay anchored to the right. */}\n <div\n className={`flex items-center ${getSpacingClass(\"sm\", \"gap\")}`}\n />\n\n <div className={`flex items-center ${getSpacingClass(\"sm\", \"gap\")}`}>\n {toolbarActions}\n {exportable && (\n <div\n className={`flex items-center ${getSpacingClass(\"xs\", \"gap\")}`}\n >\n {exportFormats.map((format) => (\n <Button\n key={format}\n variant=\"outline\"\n size=\"sm\"\n leftIcon={<Download className=\"h-4 w-4\" />}\n onClick={() => handleExport(format)}\n >\n {format.toUpperCase()}\n </Button>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Table */}\n <Table\n columns={tableColumns}\n data={data}\n loading={loading}\n onSort={onSort}\n sortColumn={sortColumn}\n sortDirection={sortDirection}\n pagination={pagination}\n filters={filters}\n selectable={selectable}\n selectedRows={selectedRows}\n onSelectionChange={onSelectionChange}\n rowId={rowId}\n actions={actions}\n resizable={resizable}\n columnWidths={internalColumnWidths}\n onColumnResize={(key, width) => {\n setInternalColumnWidths((prev) => ({ ...prev, [key]: width }));\n onColumnResize?.(key, width);\n }}\n virtualScrolling={virtualScrolling}\n virtualScrollingOptions={virtualScrollingOptions}\n emptyMessage={emptyMessage}\n emptyStateTitle={emptyStateTitle}\n emptyStateMessage={emptyStateMessage}\n emptyStateIllustration={emptyStateIllustration}\n emptyStateAction={emptyStateAction}\n />\n </div>\n );\n}\n"],"names":["DataGrid","columns","data","loading","onSort","sortColumn","sortDirection","_multiSort","_groups","_onGroupChange","_groupable","resizable","_reorderable","_onColumnReorder","columnWidths","onColumnResize","selectable","selectedRows","onSelectionChange","rowId","exportable","onExport","exportFormats","pagination","filters","actions","toolbarActions","virtualScrolling","virtualScrollingOptions","emptyMessage","emptyStateTitle","emptyStateMessage","emptyStateIllustration","emptyStateAction","className","internalColumnWidths","setInternalColumnWidths","useState","tableColumns","useMemo","col","__spreadProps","__spreadValues","handleExport","format","exportToCSV","exportToJSON","cols","headers","c","rows","row","value","csv","blob","url","a","json","jsxs","getSpacingClass","getRadiusClass","jsx","Button","Download","Table","key","width","prev"],"mappings":"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"}
1
+ {"version":3,"file":"DataGrid.js","sources":["../../../../../src/ui/components/DataGrid/DataGrid.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, useMemo, type ReactNode } from \"react\";\nimport { Download } from \"lucide-react\";\nimport Table, { type TableColumn } from \"../Table/Table\";\nimport Button from \"../../primitives/Button/Button\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport type { TableAction } from \"../Table/TableActions/TableActions\";\nimport type {\n FilterConfig,\n FilterValue,\n} from \"../Table/TableFilters/TableFilters\";\n\nexport type DataGridColumn<T = unknown> = TableColumn<T> & {\n groupable?: boolean;\n exportable?: boolean;\n defaultWidth?: number;\n minWidth?: number;\n maxWidth?: number;\n};\n\n/**\n * @experimental Reserved for upcoming row-grouping support; not yet wired\n * to rendering. The shape is fixed for forward-compatibility, but passing\n * a `groups` array to `<DataGrid>` has no visual effect today. Tracked in\n * BACKLOG.md under \"DataGrid row grouping — props/types reserved\".\n */\nexport interface DataGridGroup {\n column: string;\n expanded?: boolean;\n}\n\nexport interface DataGridProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n> {\n columns: DataGridColumn<T>[];\n data: T[];\n loading?: boolean;\n\n // Sorting\n onSort?: (columnKey: string, direction: \"asc\" | \"desc\") => void;\n sortColumn?: string;\n sortDirection?: \"asc\" | \"desc\";\n multiSort?: boolean;\n\n // Grouping\n /**\n * @experimental Reserved for upcoming row-grouping support; not yet wired\n * to rendering. Passing this has no visual effect today — the grid renders\n * a flat table regardless. Tracked in BACKLOG.md under \"DataGrid row\n * grouping — props/types reserved\".\n */\n groups?: DataGridGroup[];\n /**\n * @experimental Reserved for upcoming row-grouping support; not yet wired.\n * The callback is never invoked today. Tracked in BACKLOG.md.\n */\n onGroupChange?: (groups: DataGridGroup[]) => void;\n /**\n * @experimental Reserved for upcoming row-grouping support; not yet wired.\n * Passing `true` has no visual effect today — the grouping toolbar button\n * was removed because it rendered but had no behaviour. Tracked in\n * BACKLOG.md.\n */\n groupable?: boolean;\n\n // Column Management\n resizable?: boolean;\n reorderable?: boolean;\n onColumnReorder?: (columns: DataGridColumn<T>[]) => void;\n columnWidths?: Record<string, number>;\n onColumnResize?: (columnKey: string, width: number) => void;\n\n // Selection\n selectable?: boolean;\n selectedRows?: string[];\n onSelectionChange?: (selected: string[]) => void;\n rowId?: (row: T) => string;\n\n // Export\n exportable?: boolean;\n onExport?: (format: \"csv\" | \"xlsx\" | \"json\") => void;\n exportFormats?: (\"csv\" | \"xlsx\" | \"json\")[];\n\n // Pagination\n pagination?: {\n page: number;\n pageSize: number;\n total: number;\n onPageChange: (page: number) => void;\n onPageSizeChange: (size: number) => void;\n pageSizeOptions?: number[];\n };\n\n // Filters\n filters?: {\n config: FilterConfig[];\n onFilter: (filters: Record<string, FilterValue>) => void;\n initialValues?: Record<string, FilterValue>;\n };\n\n // Actions\n actions?: (row: T) => TableAction<T>[];\n toolbarActions?: ReactNode;\n\n // Virtual Scrolling\n virtualScrolling?: boolean;\n virtualScrollingOptions?: {\n itemHeight?: number;\n containerHeight?: number;\n overscan?: number;\n };\n\n // Empty State\n emptyMessage?: string;\n emptyStateTitle?: string;\n emptyStateMessage?: string;\n emptyStateIllustration?: ReactNode;\n emptyStateAction?: ReactNode;\n\n className?: string;\n}\n\n/**\n * DataGrid Component\n *\n * An advanced data grid component with sorting, filtering, grouping, column management, and export.\n * Extends the Table component with additional enterprise features.\n *\n * @example\n * ```tsx\n * <DataGrid\n * columns={columns}\n * data={data}\n * groupable\n * exportable\n * onExport={(format) => console.log('Export as', format)}\n * />\n * ```\n */\nexport default function DataGrid<\n T extends Record<string, unknown> = Record<string, unknown>,\n>({\n columns,\n data,\n loading = false,\n onSort,\n sortColumn,\n sortDirection,\n multiSort: _multiSort = false,\n // Grouping props are @experimental — see DataGridGroup JSDoc. Accepted\n // for forward-compatibility but not yet wired to rendering.\n groups: _groups,\n onGroupChange: _onGroupChange,\n groupable: _groupable = false,\n resizable = true,\n reorderable: _reorderable = false,\n onColumnReorder: _onColumnReorder,\n columnWidths,\n onColumnResize,\n selectable = false,\n selectedRows,\n onSelectionChange,\n rowId,\n exportable = false,\n onExport,\n exportFormats = [\"csv\", \"xlsx\", \"json\"],\n pagination,\n filters,\n actions,\n toolbarActions,\n virtualScrolling = false,\n virtualScrollingOptions,\n emptyMessage,\n emptyStateTitle,\n emptyStateMessage,\n emptyStateIllustration,\n emptyStateAction,\n className = \"\",\n}: DataGridProps<T>) {\n const [internalColumnWidths, setInternalColumnWidths] = useState<\n Record<string, number>\n >({});\n // Controlled when the consumer passes columnWidths; otherwise internal\n // state owns it. The old code seeded internal state from the prop ONCE\n // at mount and then ignored every later prop change.\n const isColumnWidthsControlled = columnWidths !== undefined;\n const effectiveColumnWidths = isColumnWidthsControlled\n ? columnWidths\n : internalColumnWidths;\n\n // Convert DataGrid columns to Table columns\n const tableColumns: TableColumn<T>[] = useMemo(() => {\n return columns.map((col) => ({\n ...col,\n width: effectiveColumnWidths[col.key as string] || col.defaultWidth,\n }));\n }, [columns, effectiveColumnWidths]);\n\n const handleExport = (format: \"csv\" | \"xlsx\" | \"json\") => {\n if (onExport) {\n onExport(format);\n } else {\n // Default export implementation\n if (format === \"csv\") {\n exportToCSV(data, columns);\n } else if (format === \"json\") {\n exportToJSON(data);\n }\n }\n };\n\n const exportToCSV = (data: T[], cols: DataGridColumn<T>[]) => {\n // RFC 4180: quote a field (and double its internal quotes) whenever it\n // contains a comma, a double-quote, OR a newline. The old code only\n // quoted on comma, so values with quotes/newlines produced malformed,\n // column-misaligned CSV.\n const esc = (v: unknown): string => {\n const s = v == null ? \"\" : String(v);\n return /[\",\\n\\r]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s;\n };\n const exportCols = cols.filter((c) => c.exportable !== false);\n const headers = exportCols.map((c) => esc(c.label || c.key));\n const rows = data.map((row) => exportCols.map((c) => esc(row[c.key])));\n\n const csv = [headers.join(\",\"), ...rows.map((r) => r.join(\",\"))].join(\n \"\\r\\n\",\n );\n const blob = new Blob([csv], { type: \"text/csv\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `export-${Date.now()}.csv`;\n a.click();\n URL.revokeObjectURL(url);\n };\n\n const exportToJSON = (data: T[]) => {\n const json = JSON.stringify(data, null, 2);\n const blob = new Blob([json], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `export-${Date.now()}.json`;\n a.click();\n URL.revokeObjectURL(url);\n };\n\n return (\n <div className={`${getSpacingClass(\"base\", \"space-y\")} ${className}`}>\n {/* Toolbar */}\n {(exportable || toolbarActions) && (\n <div\n className={`\n flex\n items-center\n justify-between\n ${getSpacingClass(\"base\", \"p\")}\n bg-surface-base\n border\n border-line-default\n ${getRadiusClass(\"lg\")}\n `}\n >\n {/* Left slot reserved for the grouping toolbar (currently\n @experimental — see DataGridGroup JSDoc). The empty div\n preserves the justify-between layout so toolbarActions and\n the export controls stay anchored to the right. */}\n <div\n className={`flex items-center ${getSpacingClass(\"sm\", \"gap\")}`}\n />\n\n <div className={`flex items-center ${getSpacingClass(\"sm\", \"gap\")}`}>\n {toolbarActions}\n {exportable && (\n <div\n className={`flex items-center ${getSpacingClass(\"xs\", \"gap\")}`}\n >\n {(onExport\n ? exportFormats\n : exportFormats.filter((f) => f === \"csv\" || f === \"json\")\n ).map((format) => (\n <Button\n key={format}\n variant=\"outline\"\n size=\"sm\"\n leftIcon={<Download className=\"h-4 w-4\" />}\n onClick={() => handleExport(format)}\n >\n {format.toUpperCase()}\n </Button>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Table */}\n <Table\n columns={tableColumns}\n data={data}\n loading={loading}\n onSort={onSort}\n sortColumn={sortColumn}\n sortDirection={sortDirection}\n pagination={pagination}\n filters={filters}\n selectable={selectable}\n selectedRows={selectedRows}\n onSelectionChange={onSelectionChange}\n rowId={rowId}\n actions={actions}\n resizable={resizable}\n columnWidths={effectiveColumnWidths}\n onColumnResize={(key, width) => {\n if (!isColumnWidthsControlled) {\n setInternalColumnWidths((prev) => ({ ...prev, [key]: width }));\n }\n onColumnResize?.(key, width);\n }}\n virtualScrolling={virtualScrolling}\n virtualScrollingOptions={virtualScrollingOptions}\n emptyMessage={emptyMessage}\n emptyStateTitle={emptyStateTitle}\n emptyStateMessage={emptyStateMessage}\n emptyStateIllustration={emptyStateIllustration}\n emptyStateAction={emptyStateAction}\n />\n </div>\n );\n}\n"],"names":["DataGrid","columns","data","loading","onSort","sortColumn","sortDirection","_multiSort","_groups","_onGroupChange","_groupable","resizable","_reorderable","_onColumnReorder","columnWidths","onColumnResize","selectable","selectedRows","onSelectionChange","rowId","exportable","onExport","exportFormats","pagination","filters","actions","toolbarActions","virtualScrolling","virtualScrollingOptions","emptyMessage","emptyStateTitle","emptyStateMessage","emptyStateIllustration","emptyStateAction","className","internalColumnWidths","setInternalColumnWidths","useState","isColumnWidthsControlled","effectiveColumnWidths","tableColumns","useMemo","col","__spreadProps","__spreadValues","handleExport","format","exportToCSV","exportToJSON","cols","esc","v","s","exportCols","c","headers","rows","row","csv","r","blob","url","a","json","jsxs","getSpacingClass","getRadiusClass","jsx","f","Button","Download","Table","key","width","prev"],"mappings":"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"}