@flanksource/clicky-ui 0.3.26 → 0.3.28
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.
- package/NOTICE.md +14 -0
- package/dist/ai.cjs +52 -6
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +53 -7
- package/dist/ai.js.map +1 -1
- package/dist/comments/CommentCard.cjs +24 -39
- package/dist/comments/CommentCard.cjs.map +1 -1
- package/dist/comments/CommentCard.d.ts +9 -2
- package/dist/comments/CommentCard.d.ts.map +1 -1
- package/dist/comments/CommentCard.js +24 -39
- package/dist/comments/CommentCard.js.map +1 -1
- package/dist/comments/CommentProvider.cjs +4 -3
- package/dist/comments/CommentProvider.cjs.map +1 -1
- package/dist/comments/CommentProvider.d.ts +6 -1
- package/dist/comments/CommentProvider.d.ts.map +1 -1
- package/dist/comments/CommentProvider.js +4 -3
- package/dist/comments/CommentProvider.js.map +1 -1
- package/dist/comments/CommentSidePanel.cjs +65 -52
- package/dist/comments/CommentSidePanel.cjs.map +1 -1
- package/dist/comments/CommentSidePanel.d.ts.map +1 -1
- package/dist/comments/CommentSidePanel.js +67 -54
- package/dist/comments/CommentSidePanel.js.map +1 -1
- package/dist/comments/CommentThread.cjs +2 -2
- package/dist/comments/CommentThread.cjs.map +1 -1
- package/dist/comments/CommentThread.d.ts +3 -3
- package/dist/comments/CommentThread.d.ts.map +1 -1
- package/dist/comments/CommentThread.js +2 -2
- package/dist/comments/CommentThread.js.map +1 -1
- package/dist/comments/CommentThreadList.cjs +85 -37
- package/dist/comments/CommentThreadList.cjs.map +1 -1
- package/dist/comments/CommentThreadList.d.ts +3 -3
- package/dist/comments/CommentThreadList.d.ts.map +1 -1
- package/dist/comments/CommentThreadList.js +86 -38
- package/dist/comments/CommentThreadList.js.map +1 -1
- package/dist/comments/comment-utils.cjs +26 -0
- package/dist/comments/comment-utils.cjs.map +1 -1
- package/dist/comments/comment-utils.d.ts +11 -0
- package/dist/comments/comment-utils.d.ts.map +1 -1
- package/dist/comments/comment-utils.js +26 -0
- package/dist/comments/comment-utils.js.map +1 -1
- package/dist/comments.cjs +2 -0
- package/dist/comments.cjs.map +1 -1
- package/dist/comments.js +3 -1
- package/dist/components/AccordionList.cjs +3 -0
- package/dist/components/AccordionList.cjs.map +1 -1
- package/dist/components/AccordionList.d.ts +3 -1
- package/dist/components/AccordionList.d.ts.map +1 -1
- package/dist/components/AccordionList.js +3 -0
- package/dist/components/AccordionList.js.map +1 -1
- package/dist/components/CopyButton.cjs +35 -0
- package/dist/components/CopyButton.cjs.map +1 -0
- package/dist/components/CopyButton.d.ts +20 -0
- package/dist/components/CopyButton.d.ts.map +1 -0
- package/dist/components/CopyButton.js +35 -0
- package/dist/components/CopyButton.js.map +1 -0
- package/dist/components/FilterBar.cjs +29 -6
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +10 -1
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +29 -6
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/ListMenu.cjs +4 -1
- package/dist/components/ListMenu.cjs.map +1 -1
- package/dist/components/ListMenu.d.ts +5 -1
- package/dist/components/ListMenu.d.ts.map +1 -1
- package/dist/components/ListMenu.js +4 -1
- package/dist/components/ListMenu.js.map +1 -1
- package/dist/components/SegmentedControl.cjs +4 -2
- package/dist/components/SegmentedControl.cjs.map +1 -1
- package/dist/components/SegmentedControl.d.ts +4 -0
- package/dist/components/SegmentedControl.d.ts.map +1 -1
- package/dist/components/SegmentedControl.js +4 -2
- package/dist/components/SegmentedControl.js.map +1 -1
- package/dist/components/clipboard.cjs +60 -0
- package/dist/components/clipboard.cjs.map +1 -0
- package/dist/components/clipboard.d.ts +13 -0
- package/dist/components/clipboard.d.ts.map +1 -0
- package/dist/components/clipboard.js +60 -0
- package/dist/components/clipboard.js.map +1 -0
- package/dist/components/json-schema-form-array.cjs +15 -1
- package/dist/components/json-schema-form-array.cjs.map +1 -1
- package/dist/components/json-schema-form-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-array.js +15 -1
- package/dist/components/json-schema-form-array.js.map +1 -1
- package/dist/components/json-schema-form-list-array.cjs +113 -0
- package/dist/components/json-schema-form-list-array.cjs.map +1 -0
- package/dist/components/json-schema-form-list-array.d.ts +7 -0
- package/dist/components/json-schema-form-list-array.d.ts.map +1 -0
- package/dist/components/json-schema-form-list-array.js +113 -0
- package/dist/components/json-schema-form-list-array.js.map +1 -0
- package/dist/components/json-schema-form-resolve.cjs +1 -1
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +1 -1
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +1 -1
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components.cjs +5 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +2 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +5 -0
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +4 -1
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.js +4 -1
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/DataTable.cjs +202 -40
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +163 -3
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +202 -40
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/FixtureEditor/FixtureFrontmatterDialog.cjs +1 -1
- package/dist/data/FixtureEditor/FixtureFrontmatterDialog.cjs.map +1 -1
- package/dist/data/FixtureEditor/FixtureFrontmatterDialog.js +1 -1
- package/dist/data/FixtureEditor/FixtureFrontmatterDialog.js.map +1 -1
- package/dist/data/FixtureEditor/fixture-frontmatter.cjs +8 -6
- package/dist/data/FixtureEditor/fixture-frontmatter.cjs.map +1 -1
- package/dist/data/FixtureEditor/fixture-frontmatter.js +8 -6
- package/dist/data/FixtureEditor/fixture-frontmatter.js.map +1 -1
- package/dist/data/SelectionActionBar.cjs +242 -0
- package/dist/data/SelectionActionBar.cjs.map +1 -0
- package/dist/data/SelectionActionBar.d.ts +28 -0
- package/dist/data/SelectionActionBar.d.ts.map +1 -0
- package/dist/data/SelectionActionBar.js +242 -0
- package/dist/data/SelectionActionBar.js.map +1 -0
- package/dist/data/TaskManager.cjs +34 -12
- package/dist/data/TaskManager.cjs.map +1 -1
- package/dist/data/TaskManager.d.ts.map +1 -1
- package/dist/data/TaskManager.js +34 -12
- package/dist/data/TaskManager.js.map +1 -1
- package/dist/data/TaskManagerButton.cjs +11 -7
- package/dist/data/TaskManagerButton.cjs.map +1 -1
- package/dist/data/TaskManagerButton.d.ts.map +1 -1
- package/dist/data/TaskManagerButton.js +11 -7
- package/dist/data/TaskManagerButton.js.map +1 -1
- package/dist/data/TaskProgress.cjs +55 -11
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.d.ts.map +1 -1
- package/dist/data/TaskProgress.js +53 -9
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +2 -4
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.js +2 -4
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.cjs +1 -2
- package/dist/data/ai/ChatWindow.runtime.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.js +1 -2
- package/dist/data/ai/ChatWindow.runtime.js.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptCatalogTable.cjs +262 -0
- package/dist/data/ai/PromptCatalog/PromptCatalogTable.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptCatalogTable.d.ts +16 -0
- package/dist/data/ai/PromptCatalog/PromptCatalogTable.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptCatalogTable.js +262 -0
- package/dist/data/ai/PromptCatalog/PromptCatalogTable.js.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.cjs +77 -0
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.d.ts +8 -0
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.js +77 -0
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.js.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPage.cjs +332 -0
- package/dist/data/ai/PromptCatalog/PromptPage.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPage.d.ts +17 -0
- package/dist/data/ai/PromptCatalog/PromptPage.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPage.js +332 -0
- package/dist/data/ai/PromptCatalog/PromptPage.js.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPageEditor.cjs +102 -0
- package/dist/data/ai/PromptCatalog/PromptPageEditor.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPageEditor.d.ts +16 -0
- package/dist/data/ai/PromptCatalog/PromptPageEditor.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPageEditor.js +102 -0
- package/dist/data/ai/PromptCatalog/PromptPageEditor.js.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPageHeader.cjs +102 -0
- package/dist/data/ai/PromptCatalog/PromptPageHeader.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPageHeader.d.ts +10 -0
- package/dist/data/ai/PromptCatalog/PromptPageHeader.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPageHeader.js +102 -0
- package/dist/data/ai/PromptCatalog/PromptPageHeader.js.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPagePreview.cjs +90 -0
- package/dist/data/ai/PromptCatalog/PromptPagePreview.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPagePreview.d.ts +8 -0
- package/dist/data/ai/PromptCatalog/PromptPagePreview.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPagePreview.js +90 -0
- package/dist/data/ai/PromptCatalog/PromptPagePreview.js.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.cjs +168 -0
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.d.ts +17 -0
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.js +168 -0
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.js.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptSourceBadge.cjs +36 -0
- package/dist/data/ai/PromptCatalog/PromptSourceBadge.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptSourceBadge.d.ts +7 -0
- package/dist/data/ai/PromptCatalog/PromptSourceBadge.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/PromptSourceBadge.js +36 -0
- package/dist/data/ai/PromptCatalog/PromptSourceBadge.js.map +1 -0
- package/dist/data/ai/PromptCatalog/index.d.ts +9 -0
- package/dist/data/ai/PromptCatalog/index.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/prompt-catalog-model.cjs +137 -0
- package/dist/data/ai/PromptCatalog/prompt-catalog-model.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/prompt-catalog-model.d.ts +28 -0
- package/dist/data/ai/PromptCatalog/prompt-catalog-model.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/prompt-catalog-model.js +137 -0
- package/dist/data/ai/PromptCatalog/prompt-catalog-model.js.map +1 -0
- package/dist/data/ai/PromptCatalog/prompt-page-model.cjs +114 -0
- package/dist/data/ai/PromptCatalog/prompt-page-model.cjs.map +1 -0
- package/dist/data/ai/PromptCatalog/prompt-page-model.d.ts +45 -0
- package/dist/data/ai/PromptCatalog/prompt-page-model.d.ts.map +1 -0
- package/dist/data/ai/PromptCatalog/prompt-page-model.js +114 -0
- package/dist/data/ai/PromptCatalog/prompt-page-model.js.map +1 -0
- package/dist/data/ai/PromptCatalog/types.d.ts +70 -0
- package/dist/data/ai/PromptCatalog/types.d.ts.map +1 -0
- package/dist/data/ai/PromptPicker/PromptPicker.cjs +9 -12
- package/dist/data/ai/PromptPicker/PromptPicker.cjs.map +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.js +9 -12
- package/dist/data/ai/PromptPicker/PromptPicker.js.map +1 -1
- package/dist/data/ai/PromptPicker/index.d.ts +1 -1
- package/dist/data/ai/PromptPicker/index.d.ts.map +1 -1
- package/dist/data/ai/PromptPicker/types.cjs.map +1 -1
- package/dist/data/ai/PromptPicker/types.d.ts +9 -0
- package/dist/data/ai/PromptPicker/types.d.ts.map +1 -1
- package/dist/data/ai/PromptPicker/types.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.cjs +4 -5
- package/dist/data/ai/PromptRunEditor/index.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.js +5 -6
- package/dist/data/ai/PromptRunEditor/index.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/model.cjs +1 -1
- package/dist/data/ai/PromptRunEditor/model.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/model.d.ts +1 -1
- package/dist/data/ai/PromptRunEditor/model.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/model.js +1 -1
- package/dist/data/ai/PromptRunEditor/model.js.map +1 -1
- package/dist/data/ai/RuntimeModePicker.cjs +25 -14
- package/dist/data/ai/RuntimeModePicker.cjs.map +1 -1
- package/dist/data/ai/RuntimeModePicker.d.ts.map +1 -1
- package/dist/data/ai/RuntimeModePicker.js +26 -15
- package/dist/data/ai/RuntimeModePicker.js.map +1 -1
- package/dist/data/ai/SessionInspector.collection-types.d.ts +1 -1
- package/dist/data/ai/SessionInspector.collection-types.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.collection.cjs +3 -3
- package/dist/data/ai/SessionInspector.collection.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.collection.js +3 -3
- package/dist/data/ai/SessionInspector.collection.js.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.cjs +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.js +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.js.map +1 -1
- package/dist/data/ai/SessionInspector.model.cjs +3 -3
- package/dist/data/ai/SessionInspector.model.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.model.d.ts +1 -1
- package/dist/data/ai/SessionInspector.model.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.model.js +3 -3
- package/dist/data/ai/SessionInspector.model.js.map +1 -1
- package/dist/data/ai/SessionInspector.panels.cjs +1 -1
- package/dist/data/ai/SessionInspector.panels.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.panels.js +1 -1
- package/dist/data/ai/SessionInspector.panels.js.map +1 -1
- package/dist/data/ai/SessionInspector.summary.cjs +3 -3
- package/dist/data/ai/SessionInspector.summary.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.summary.js +3 -3
- package/dist/data/ai/SessionInspector.summary.js.map +1 -1
- package/dist/data/ai/SessionViewer.fixtures.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.unified.d.ts +3 -2
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.cjs +18 -30
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.js +19 -31
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/EnvironmentSection.cjs +71 -86
- package/dist/data/ai/SpecRuntimeEditor/EnvironmentSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/EnvironmentSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/EnvironmentSection.js +72 -87
- package/dist/data/ai/SpecRuntimeEditor/EnvironmentSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelContextAdvanced.cjs +99 -0
- package/dist/data/ai/SpecRuntimeEditor/ModelContextAdvanced.cjs.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/ModelContextAdvanced.d.ts +13 -0
- package/dist/data/ai/SpecRuntimeEditor/ModelContextAdvanced.d.ts.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/ModelContextAdvanced.js +99 -0
- package/dist/data/ai/SpecRuntimeEditor/ModelContextAdvanced.js.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.cjs +37 -21
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.d.ts +6 -2
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.js +38 -22
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PermissionModeField.cjs +114 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionModeField.cjs.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionModeField.d.ts +10 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionModeField.d.ts.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionModeField.js +114 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionModeField.js.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionPolicyList.cjs +160 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionPolicyList.cjs.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionPolicyList.d.ts +9 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionPolicyList.d.ts.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionPolicyList.js +160 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionPolicyList.js.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/PermissionsSection.cjs +27 -241
- package/dist/data/ai/SpecRuntimeEditor/PermissionsSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PermissionsSection.d.ts +5 -6
- package/dist/data/ai/SpecRuntimeEditor/PermissionsSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PermissionsSection.js +25 -239
- package/dist/data/ai/SpecRuntimeEditor/PermissionsSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs +21 -8
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.d.ts +4 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.js +22 -9
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/SandboxSection.cjs +207 -164
- package/dist/data/ai/SpecRuntimeEditor/SandboxSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/SandboxSection.d.ts +4 -3
- package/dist/data/ai/SpecRuntimeEditor/SandboxSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/SandboxSection.js +210 -167
- package/dist/data/ai/SpecRuntimeEditor/SandboxSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/SectionCard.cjs +15 -15
- package/dist/data/ai/SpecRuntimeEditor/SectionCard.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/SectionCard.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/SectionCard.js +15 -15
- package/dist/data/ai/SpecRuntimeEditor/SectionCard.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.cjs +120 -42
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.d.ts +4 -1
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.js +123 -45
- package/dist/data/ai/SpecRuntimeEditor/WorkspaceSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/env-model.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/env-model.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/env-model.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.cjs +136 -48
- package/dist/data/ai/SpecRuntimeEditor/index.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.d.ts +13 -3
- package/dist/data/ai/SpecRuntimeEditor/index.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.js +137 -49
- package/dist/data/ai/SpecRuntimeEditor/index.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.cjs +93 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.cjs.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.d.ts +6 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.d.ts.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.js +93 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.js.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-preset-storage.cjs +35 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-preset-storage.cjs.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-preset-storage.d.ts +5 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-preset-storage.d.ts.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-preset-storage.js +35 -0
- package/dist/data/ai/SpecRuntimeEditor/permission-preset-storage.js.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor/presets.cjs +2 -9
- package/dist/data/ai/SpecRuntimeEditor/presets.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/presets.d.ts +1 -2
- package/dist/data/ai/SpecRuntimeEditor/presets.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/presets.js +2 -9
- package/dist/data/ai/SpecRuntimeEditor/presets.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.d.ts +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/types.cjs +2 -7
- package/dist/data/ai/SpecRuntimeEditor/types.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/types.d.ts +0 -1
- package/dist/data/ai/SpecRuntimeEditor/types.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/types.js +3 -8
- package/dist/data/ai/SpecRuntimeEditor/types.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.cjs +43 -33
- package/dist/data/ai/SpecRuntimeEditor/update.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.d.ts +7 -13
- package/dist/data/ai/SpecRuntimeEditor/update.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.js +43 -33
- package/dist/data/ai/SpecRuntimeEditor/update.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.cjs +33 -45
- package/dist/data/ai/SpecRuntimeEditor.model.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.d.ts +54 -29
- package/dist/data/ai/SpecRuntimeEditor.model.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.js +33 -44
- package/dist/data/ai/SpecRuntimeEditor.model.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.sandbox-model.cjs +276 -0
- package/dist/data/ai/SpecRuntimeEditor.sandbox-model.cjs.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor.sandbox-model.d.ts +58 -0
- package/dist/data/ai/SpecRuntimeEditor.sandbox-model.d.ts.map +1 -0
- package/dist/data/ai/SpecRuntimeEditor.sandbox-model.js +276 -0
- package/dist/data/ai/SpecRuntimeEditor.sandbox-model.js.map +1 -0
- package/dist/data/ai/ThreadPicker.cjs +55 -42
- package/dist/data/ai/ThreadPicker.cjs.map +1 -1
- package/dist/data/ai/ThreadPicker.d.ts.map +1 -1
- package/dist/data/ai/ThreadPicker.js +56 -43
- package/dist/data/ai/ThreadPicker.js.map +1 -1
- package/dist/data/ai/ToolPreferences.cjs +9 -1
- package/dist/data/ai/ToolPreferences.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.js +9 -1
- package/dist/data/ai/ToolPreferences.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.cjs +41 -487
- package/dist/data/ai/ToolSchemaBrowser.cjs.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.d.ts +7 -2
- package/dist/data/ai/ToolSchemaBrowser.d.ts.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.detail.cjs +238 -0
- package/dist/data/ai/ToolSchemaBrowser.detail.cjs.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.detail.d.ts +8 -0
- package/dist/data/ai/ToolSchemaBrowser.detail.d.ts.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.detail.js +238 -0
- package/dist/data/ai/ToolSchemaBrowser.detail.js.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.directory-header.cjs +57 -0
- package/dist/data/ai/ToolSchemaBrowser.directory-header.cjs.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.directory-header.d.ts +9 -0
- package/dist/data/ai/ToolSchemaBrowser.directory-header.d.ts.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.directory-header.js +57 -0
- package/dist/data/ai/ToolSchemaBrowser.directory-header.js.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.js +42 -488
- package/dist/data/ai/ToolSchemaBrowser.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.model.cjs +130 -0
- package/dist/data/ai/ToolSchemaBrowser.model.cjs.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.model.d.ts +35 -0
- package/dist/data/ai/ToolSchemaBrowser.model.d.ts.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.model.js +130 -0
- package/dist/data/ai/ToolSchemaBrowser.model.js.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.cjs +57 -0
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.cjs.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.d.ts +7 -0
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.d.ts.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.js +57 -0
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.js.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.sidebar.cjs +389 -0
- package/dist/data/ai/ToolSchemaBrowser.sidebar.cjs.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.sidebar.d.ts +23 -0
- package/dist/data/ai/ToolSchemaBrowser.sidebar.d.ts.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.sidebar.js +389 -0
- package/dist/data/ai/ToolSchemaBrowser.sidebar.js.map +1 -0
- package/dist/data/ai/agent-action-icons.cjs +14 -6
- package/dist/data/ai/agent-action-icons.cjs.map +1 -1
- package/dist/data/ai/agent-action-icons.d.ts.map +1 -1
- package/dist/data/ai/agent-action-icons.js +14 -6
- package/dist/data/ai/agent-action-icons.js.map +1 -1
- package/dist/data/ai/examples/sessions/claude-complete.cjs +17 -9
- package/dist/data/ai/examples/sessions/claude-complete.cjs.map +1 -1
- package/dist/data/ai/examples/sessions/claude-complete.d.ts.map +1 -1
- package/dist/data/ai/examples/sessions/claude-complete.js +17 -9
- package/dist/data/ai/examples/sessions/claude-complete.js.map +1 -1
- package/dist/data/ai/examples/sessions/claude.cjs +7 -4
- package/dist/data/ai/examples/sessions/claude.cjs.map +1 -1
- package/dist/data/ai/examples/sessions/claude.d.ts.map +1 -1
- package/dist/data/ai/examples/sessions/claude.js +7 -4
- package/dist/data/ai/examples/sessions/claude.js.map +1 -1
- package/dist/data/ai/examples/sessions/codex-complete.cjs +17 -10
- package/dist/data/ai/examples/sessions/codex-complete.cjs.map +1 -1
- package/dist/data/ai/examples/sessions/codex-complete.d.ts.map +1 -1
- package/dist/data/ai/examples/sessions/codex-complete.js +17 -10
- package/dist/data/ai/examples/sessions/codex-complete.js.map +1 -1
- package/dist/data/ai/examples/sessions/codex.cjs +7 -4
- package/dist/data/ai/examples/sessions/codex.cjs.map +1 -1
- package/dist/data/ai/examples/sessions/codex.d.ts.map +1 -1
- package/dist/data/ai/examples/sessions/codex.js +7 -4
- package/dist/data/ai/examples/sessions/codex.js.map +1 -1
- package/dist/data/ai/index.d.ts +6 -3
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/runtime-profile.cjs +93 -0
- package/dist/data/ai/runtime-profile.cjs.map +1 -0
- package/dist/data/ai/runtime-profile.d.ts +73 -0
- package/dist/data/ai/runtime-profile.d.ts.map +1 -0
- package/dist/data/ai/runtime-profile.js +93 -0
- package/dist/data/ai/runtime-profile.js.map +1 -0
- package/dist/data/ai/sandbox-kind-meta.cjs +38 -4
- package/dist/data/ai/sandbox-kind-meta.cjs.map +1 -1
- package/dist/data/ai/sandbox-kind-meta.d.ts +3 -0
- package/dist/data/ai/sandbox-kind-meta.d.ts.map +1 -1
- package/dist/data/ai/sandbox-kind-meta.js +38 -4
- package/dist/data/ai/sandbox-kind-meta.js.map +1 -1
- package/dist/data/chat/Chat.cjs +17 -5
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.d.ts.map +1 -1
- package/dist/data/chat/Chat.fixtures.cjs +3 -3
- package/dist/data/chat/Chat.fixtures.cjs.map +1 -1
- package/dist/data/chat/Chat.fixtures.js +3 -3
- package/dist/data/chat/Chat.fixtures.js.map +1 -1
- package/dist/data/chat/Chat.js +18 -6
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/Chat.runtime.cjs +15 -9
- package/dist/data/chat/Chat.runtime.cjs.map +1 -1
- package/dist/data/chat/Chat.runtime.d.ts.map +1 -1
- package/dist/data/chat/Chat.runtime.js +16 -10
- package/dist/data/chat/Chat.runtime.js.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.cjs +5 -5
- package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.js +5 -5
- package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
- package/dist/data/chat/ContextMeter.cjs +3 -3
- package/dist/data/chat/ContextMeter.cjs.map +1 -1
- package/dist/data/chat/ContextMeter.d.ts +3 -3
- package/dist/data/chat/ContextMeter.d.ts.map +1 -1
- package/dist/data/chat/ContextMeter.js +3 -3
- package/dist/data/chat/ContextMeter.js.map +1 -1
- package/dist/data/chat/approval.cjs.map +1 -1
- package/dist/data/chat/approval.d.ts +21 -1
- package/dist/data/chat/approval.d.ts.map +1 -1
- package/dist/data/chat/approval.js.map +1 -1
- package/dist/data/chat/clickyOperationsToTools.cjs +5 -0
- package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -1
- package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -1
- package/dist/data/chat/clickyOperationsToTools.js +5 -0
- package/dist/data/chat/clickyOperationsToTools.js.map +1 -1
- package/dist/data/chat/types.cjs.map +1 -1
- package/dist/data/chat/types.d.ts +7 -5
- package/dist/data/chat/types.d.ts.map +1 -1
- package/dist/data/chat/types.js.map +1 -1
- package/dist/data/chat/usage-snapshot.cjs +21 -1
- package/dist/data/chat/usage-snapshot.cjs.map +1 -1
- package/dist/data/chat/usage-snapshot.d.ts +2 -0
- package/dist/data/chat/usage-snapshot.d.ts.map +1 -1
- package/dist/data/chat/usage-snapshot.js +22 -2
- package/dist/data/chat/usage-snapshot.js.map +1 -1
- package/dist/data/runtime/RuntimeBar.cjs +49 -51
- package/dist/data/runtime/RuntimeBar.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.d.ts +10 -2
- package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.js +51 -53
- package/dist/data/runtime/RuntimeBar.js.map +1 -1
- package/dist/data/runtime/RuntimeBar.model.cjs +55 -0
- package/dist/data/runtime/RuntimeBar.model.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.model.d.ts +11 -3
- package/dist/data/runtime/RuntimeBar.model.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.model.js +55 -0
- package/dist/data/runtime/RuntimeBar.model.js.map +1 -1
- package/dist/data/runtime/RuntimeBarCombo.cjs +11 -6
- package/dist/data/runtime/RuntimeBarCombo.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarCombo.d.ts +3 -1
- package/dist/data/runtime/RuntimeBarCombo.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarCombo.js +11 -6
- package/dist/data/runtime/RuntimeBarCombo.js.map +1 -1
- package/dist/data/runtime/RuntimeBarSegments.cjs +7 -5
- package/dist/data/runtime/RuntimeBarSegments.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarSegments.d.ts +4 -2
- package/dist/data/runtime/RuntimeBarSegments.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarSegments.js +7 -5
- package/dist/data/runtime/RuntimeBarSegments.js.map +1 -1
- package/dist/data/runtime/model-capabilities.cjs +6 -6
- package/dist/data/runtime/model-capabilities.cjs.map +1 -1
- package/dist/data/runtime/model-capabilities.d.ts +5 -1
- package/dist/data/runtime/model-capabilities.d.ts.map +1 -1
- package/dist/data/runtime/model-capabilities.js +6 -6
- package/dist/data/runtime/model-capabilities.js.map +1 -1
- package/dist/data/runtime/provider-status.cjs +1 -1
- package/dist/data/runtime/provider-status.cjs.map +1 -1
- package/dist/data/runtime/provider-status.js +1 -1
- package/dist/data/runtime/provider-status.js.map +1 -1
- package/dist/data/runtime/runtime-field-support.cjs +63 -0
- package/dist/data/runtime/runtime-field-support.cjs.map +1 -0
- package/dist/data/runtime/runtime-field-support.d.ts +13 -0
- package/dist/data/runtime/runtime-field-support.d.ts.map +1 -0
- package/dist/data/runtime/runtime-field-support.js +63 -0
- package/dist/data/runtime/runtime-field-support.js.map +1 -0
- package/dist/data/runtime/runtime-mode.cjs +170 -111
- package/dist/data/runtime/runtime-mode.cjs.map +1 -1
- package/dist/data/runtime/runtime-mode.d.ts +58 -14
- package/dist/data/runtime/runtime-mode.d.ts.map +1 -1
- package/dist/data/runtime/runtime-mode.js +170 -111
- package/dist/data/runtime/runtime-mode.js.map +1 -1
- package/dist/data/selectionActionSplit.cjs +33 -0
- package/dist/data/selectionActionSplit.cjs.map +1 -0
- package/dist/data/selectionActionSplit.d.ts +36 -0
- package/dist/data/selectionActionSplit.d.ts.map +1 -0
- package/dist/data/selectionActionSplit.js +33 -0
- package/dist/data/selectionActionSplit.js.map +1 -0
- package/dist/data/task-copy.cjs +76 -0
- package/dist/data/task-copy.cjs.map +1 -0
- package/dist/data/task-copy.d.ts +12 -0
- package/dist/data/task-copy.d.ts.map +1 -0
- package/dist/data/task-copy.js +76 -0
- package/dist/data/task-copy.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +34 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +4 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +34 -0
- package/dist/data.js.map +1 -1
- package/dist/hooks/use-task-run.cjs +24 -17
- package/dist/hooks/use-task-run.cjs.map +1 -1
- package/dist/hooks/use-task-run.d.ts +3 -1
- package/dist/hooks/use-task-run.d.ts.map +1 -1
- package/dist/hooks/use-task-run.js +25 -18
- package/dist/hooks/use-task-run.js.map +1 -1
- package/dist/icons/components/UiCalendarCheck.cjs +15 -0
- package/dist/icons/components/UiCalendarCheck.cjs.map +1 -0
- package/dist/icons/components/UiCalendarCheck.d.ts +15 -0
- package/dist/icons/components/UiCalendarCheck.d.ts.map +1 -0
- package/dist/icons/components/UiCalendarCheck.js +15 -0
- package/dist/icons/components/UiCalendarCheck.js.map +1 -0
- package/dist/icons/components/UiChartLineUp.cjs +15 -0
- package/dist/icons/components/UiChartLineUp.cjs.map +1 -0
- package/dist/icons/components/UiChartLineUp.d.ts +15 -0
- package/dist/icons/components/UiChartLineUp.d.ts.map +1 -0
- package/dist/icons/components/UiChartLineUp.js +15 -0
- package/dist/icons/components/UiChartLineUp.js.map +1 -0
- package/dist/icons/components/UiClockCountdown.cjs +15 -0
- package/dist/icons/components/UiClockCountdown.cjs.map +1 -0
- package/dist/icons/components/UiClockCountdown.d.ts +15 -0
- package/dist/icons/components/UiClockCountdown.d.ts.map +1 -0
- package/dist/icons/components/UiClockCountdown.js +15 -0
- package/dist/icons/components/UiClockCountdown.js.map +1 -0
- package/dist/icons/components/UiFactory.cjs +15 -0
- package/dist/icons/components/UiFactory.cjs.map +1 -0
- package/dist/icons/components/UiFactory.d.ts +15 -0
- package/dist/icons/components/UiFactory.d.ts.map +1 -0
- package/dist/icons/components/UiFactory.js +15 -0
- package/dist/icons/components/UiFactory.js.map +1 -0
- package/dist/icons/components/UiHandCoins.cjs +15 -0
- package/dist/icons/components/UiHandCoins.cjs.map +1 -0
- package/dist/icons/components/UiHandCoins.d.ts +15 -0
- package/dist/icons/components/UiHandCoins.d.ts.map +1 -0
- package/dist/icons/components/UiHandCoins.js +15 -0
- package/dist/icons/components/UiHandCoins.js.map +1 -0
- package/dist/icons/components/UiInvoice.cjs +15 -0
- package/dist/icons/components/UiInvoice.cjs.map +1 -0
- package/dist/icons/components/UiInvoice.d.ts +15 -0
- package/dist/icons/components/UiInvoice.d.ts.map +1 -0
- package/dist/icons/components/UiInvoice.js +15 -0
- package/dist/icons/components/UiInvoice.js.map +1 -0
- package/dist/icons/components/UiTax.cjs +15 -0
- package/dist/icons/components/UiTax.cjs.map +1 -0
- package/dist/icons/components/UiTax.d.ts +15 -0
- package/dist/icons/components/UiTax.d.ts.map +1 -0
- package/dist/icons/components/UiTax.js +15 -0
- package/dist/icons/components/UiTax.js.map +1 -0
- package/dist/icons/index.d.ts +14 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/registry.cjs +14 -0
- package/dist/icons/registry.cjs.map +1 -1
- package/dist/icons/registry.d.ts.map +1 -1
- package/dist/icons/registry.js +14 -0
- package/dist/icons/registry.js.map +1 -1
- package/dist/icons.cjs +21 -0
- package/dist/icons.cjs.map +1 -1
- package/dist/icons.js +21 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +43 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +44 -1
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.cjs +17 -3
- package/dist/layout/AppShell.cjs.map +1 -1
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/AppShell.js +17 -3
- package/dist/layout/AppShell.js.map +1 -1
- package/dist/overlay/DropdownMenu.cjs +46 -35
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.js +46 -35
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/rpc/FilterForm.cjs +26 -11
- package/dist/rpc/FilterForm.cjs.map +1 -1
- package/dist/rpc/FilterForm.d.ts +4 -1
- package/dist/rpc/FilterForm.d.ts.map +1 -1
- package/dist/rpc/FilterForm.js +26 -11
- package/dist/rpc/FilterForm.js.map +1 -1
- package/dist/rpc/FilterFormFields.cjs +3 -2
- package/dist/rpc/FilterFormFields.cjs.map +1 -1
- package/dist/rpc/FilterFormFields.d.ts +2 -1
- package/dist/rpc/FilterFormFields.d.ts.map +1 -1
- package/dist/rpc/FilterFormFields.js +3 -2
- package/dist/rpc/FilterFormFields.js.map +1 -1
- package/dist/rpc/OperationActionBar.cjs +67 -15
- package/dist/rpc/OperationActionBar.cjs.map +1 -1
- package/dist/rpc/OperationActionBar.d.ts +11 -3
- package/dist/rpc/OperationActionBar.d.ts.map +1 -1
- package/dist/rpc/OperationActionBar.js +68 -16
- package/dist/rpc/OperationActionBar.js.map +1 -1
- package/dist/rpc/OperationCatalog.cjs +69 -76
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts +3 -1
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +69 -76
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/OperationCatalogActions.cjs +69 -0
- package/dist/rpc/OperationCatalogActions.cjs.map +1 -0
- package/dist/rpc/OperationCatalogActions.d.ts +17 -0
- package/dist/rpc/OperationCatalogActions.d.ts.map +1 -0
- package/dist/rpc/OperationCatalogActions.js +69 -0
- package/dist/rpc/OperationCatalogActions.js.map +1 -0
- package/dist/rpc/OperationEntityContextPicker.cjs +129 -116
- package/dist/rpc/OperationEntityContextPicker.cjs.map +1 -1
- package/dist/rpc/OperationEntityContextPicker.d.ts +18 -1
- package/dist/rpc/OperationEntityContextPicker.d.ts.map +1 -1
- package/dist/rpc/OperationEntityContextPicker.js +130 -117
- package/dist/rpc/OperationEntityContextPicker.js.map +1 -1
- package/dist/rpc/OperationResultView.cjs +7 -4
- package/dist/rpc/OperationResultView.cjs.map +1 -1
- package/dist/rpc/OperationResultView.d.ts +4 -2
- package/dist/rpc/OperationResultView.d.ts.map +1 -1
- package/dist/rpc/OperationResultView.js +7 -4
- package/dist/rpc/OperationResultView.js.map +1 -1
- package/dist/rpc/operationCatalogUrl.cjs +28 -0
- package/dist/rpc/operationCatalogUrl.cjs.map +1 -0
- package/dist/rpc/operationCatalogUrl.d.ts +3 -0
- package/dist/rpc/operationCatalogUrl.d.ts.map +1 -0
- package/dist/rpc/operationCatalogUrl.js +28 -0
- package/dist/rpc/operationCatalogUrl.js.map +1 -0
- package/dist/rpc/rowNavigation.cjs +4 -3
- package/dist/rpc/rowNavigation.cjs.map +1 -1
- package/dist/rpc/rowNavigation.d.ts +1 -1
- package/dist/rpc/rowNavigation.d.ts.map +1 -1
- package/dist/rpc/rowNavigation.js +4 -3
- package/dist/rpc/rowNavigation.js.map +1 -1
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +2 -2
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/rpc.cjs +2 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +2 -1
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -0
- package/dist/rpc.js.map +1 -1
- package/dist/runtime-profile.cjs +7 -0
- package/dist/runtime-profile.cjs.map +1 -0
- package/dist/runtime-profile.d.ts +2 -0
- package/dist/runtime-profile.d.ts.map +1 -0
- package/dist/runtime-profile.js +7 -0
- package/dist/runtime-profile.js.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +6 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.js","sources":["../../src/data/DataTable.tsx"],"sourcesContent":["import {\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n type RefObject,\n type TdHTMLAttributes,\n} from \"react\";\nimport { useSort, type SortDir, type SortState } from \"../hooks/use-sort\";\nimport { type Density } from \"../hooks/use-density\";\nimport { DensityValueProvider } from \"../hooks/density-provider\";\nimport { useResolvedTheme, type Theme } from \"../hooks/use-theme\";\nimport { cn } from \"../lib/utils\";\nimport { LoadingBar } from \"../components/loading\";\nimport { useRouter } from \"../rpc/router\";\nimport { Modal, type ModalSize } from \"../overlay/Modal\";\nimport { useEscapeLayer } from \"../overlay/modalStack\";\nimport {\n FilterBar,\n FilterBarFilterPanel,\n FilterBarRangePanel,\n type FilterBarFilter,\n type FilterBarMultiFilterMode,\n type FilterBarNumberValue,\n type FilterBarProps,\n type FilterBarRangePreset,\n type FilterBarRangeProps,\n type FilterBarSearchProps,\n} from \"../components/FilterBar\";\nimport {\n clearFilterBarFilter,\n dateRangeFilterProps,\n isFilterBarFilterActive,\n} from \"../components/filter-bar-utils\";\nimport {\n getFilterCandidate,\n getFilterTokens,\n prettifyKey,\n resolveColumnValue,\n} from \"./data-table-utils\";\nimport { assertDataTableFilterProps } from \"./data-table-server-filters\";\nimport { useInfiniteRows } from \"./use-infinite-rows\";\nimport type { MultiSelectOption } from \"../components/MultiSelect\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport {\n UiChevronDown,\n UiChevronRight,\n UiClose,\n UiEllipsis,\n UiEyeClosed,\n UiFilterFilled,\n UiFilter,\n UiFullscreen,\n UiResizeVertical,\n UiCheck,\n UiDesktop,\n UiListDashes,\n UiListFlat,\n UiMoon,\n UiArrowLeft,\n UiArrowRight,\n UiRows,\n UiSun,\n} from \"../icons\";\nimport { SortableHeader } from \"./SortableHeader\";\nimport { Timestamp } from \"./cells/Timestamp\";\nimport {\n chooseTimestampFormat,\n modeToFormat,\n parseTimestamp,\n resolveDateMath,\n type TimestampFormat,\n type TimestampOptions,\n} from \"./cells/timestamp-format\";\nimport { TagActionsProvider, TagList } from \"./cells/TagList\";\nimport {\n CellFilterActions,\n type CellFilterChange,\n type CellFilterMode,\n} from \"./cells/CellFilterActions\";\nimport {\n normalizeTags,\n splitTagToken,\n tagActionsFromRecord,\n tagFilterTokens,\n type TagActionsContextValue,\n type TagFilterMode,\n type TagsOptions,\n type TagsValue,\n} from \"./cells/tag-utils\";\nimport { StatusDot } from \"./cells/StatusDot\";\nimport { normalizeStatus } from \"./cells/status-mapping\";\nimport type { BadgeStatus } from \"./Badge\";\nimport {\n dataTableGroupKey,\n dataTableGroupLabel,\n groupRecords,\n isGroupCollapsedByDefault,\n type DataTableGrouping,\n type DataTableGroupingMode,\n type DataTableGroupMetaAlign,\n} from \"./DataTable.grouping\";\nimport { DataTableGroupingControls } from \"./DataTableGroupingControls\";\n\nexport type { TimestampOptions, TagsOptions };\n\nexport type DataTableColumnKind = \"timestamp\" | \"tags\" | \"status\";\n\nexport type StatusOptions<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Maps the raw cell value to a badge status. Return null to fall back to text. */\n map?: (raw: unknown, row: T) => BadgeStatus | null;\n /** Show the normalized status label next to the dot. */\n showLabel?: boolean;\n /** Tooltip text for the status cell. */\n title?: (raw: unknown, row: T) => string;\n};\n\ntype FilterValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | Array<string | number | boolean>;\n\ntype InternalRow<T> = {\n id: string;\n row: T;\n};\n\ntype ResolvedGroup<T> = {\n key: string;\n records: InternalRow<T>[];\n rows: T[];\n label: ReactNode;\n meta: ReactNode;\n collapsed: boolean;\n};\n\ntype GroupCollapseState = {\n all?: boolean;\n groups: Record<string, boolean>;\n};\n\ntype RowStreamItem<T> =\n | { kind: \"group\"; group: ResolvedGroup<T> }\n | { kind: \"row\"; record: InternalRow<T> };\n\ntype GeneratedFilter<T extends Record<string, unknown>> = {\n column: DataTableColumn<T>;\n kind: \"text\" | \"multi\" | \"nested-multi\" | \"number\";\n options: MultiSelectOption[];\n groups?: Array<{\n groupKey: string;\n label?: string;\n options: MultiSelectOption[];\n }>;\n numberBounds?: {\n min: number;\n max: number;\n step: number;\n };\n};\n\nconst DEFAULT_COLUMN_MIN_WIDTH = 64;\nconst DEFAULT_COLUMN_WIDTH = 160;\nconst DEFAULT_GROW_COLUMN_WIDTH = 224;\nconst DEFAULT_SHRINK_COLUMN_WIDTH = 96;\nconst DEFAULT_CELL_MAX_WIDTH = 288;\nconst DEFAULT_SHRINK_CELL_MAX_WIDTH = 256;\nconst COLUMN_WIDTH_STORAGE_PREFIX = \"clicky-ui-data-table-column-widths\";\nconst COLUMN_VISIBILITY_STORAGE_PREFIX =\n \"clicky-ui-data-table-column-visibility\";\nconst DENSITY_STORAGE_PREFIX = \"clicky-ui-data-table-density\";\n\nconst DENSITY_OPTIONS: Array<{\n value: Density;\n icon: StaticIconComponent;\n label: string;\n}> = [\n { value: \"compact\", icon: UiRows, label: \"Compact\" },\n { value: \"comfortable\", icon: UiListFlat, label: \"Comfortable\" },\n { value: \"spacious\", icon: UiListDashes, label: \"Spacious\" },\n];\n\nconst DATA_TABLE_HEADER_DENSITY_CLASS =\n \"px-2.5 py-1.5 density-compact:px-2 density-compact:py-1 density-comfortable:px-2.5 density-comfortable:py-1.5 density-spacious:px-4 density-spacious:py-3\";\nconst DATA_TABLE_CELL_DENSITY_CLASS =\n \"px-2.5 py-1.5 density-compact:px-2 density-compact:py-0.5 density-comfortable:px-2.5 density-comfortable:py-1.5 density-spacious:px-4 density-spacious:py-3\";\n\ntype ColumnMenuState = {\n x: number;\n y: number;\n columnKey?: string;\n};\n\nexport type DataTableRowDetailContext<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n columns: DataTableColumn<T>[];\n visibleColumns: DataTableColumn<T>[];\n filterActionsByColumn: Record<string, TagActionsContextValue>;\n};\n\n// Mirrors the preset list used by the trace UI's TraceFilters so log/trace\n// tables share the same vocabulary out of the box.\nconst TIMESTAMP_RANGE_PRESETS: FilterBarRangePreset[] = [\n { label: \"Last 5 minutes\", from: \"now-5m\", to: \"now\" },\n { label: \"Last 15 minutes\", from: \"now-15m\", to: \"now\" },\n { label: \"Last 1 hour\", from: \"now-1h\", to: \"now\" },\n { label: \"Last 6 hours\", from: \"now-6h\", to: \"now\" },\n { label: \"Last 24 hours\", from: \"now-24h\", to: \"now\" },\n { label: \"Last 7 days\", from: \"now-7d\", to: \"now\" },\n { label: \"Last 30 days\", from: \"now-30d\", to: \"now\" },\n];\n\nexport type DataTableColumn<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Field path or stable column id. Dotted paths read nested row values. */\n key: string;\n /** Header label. */\n label: ReactNode;\n /**\n * Reads the cell value from the row. When set, it is used for rendering,\n * sorting, and filtering instead of resolving `key` as a (possibly nested)\n * path. Use this for arbitrary SQL columns whose names are empty, contain\n * dots (\"a.b\" as a literal key, not a nested path), or collide — the `key`\n * then only needs to be a stable, unique column id.\n */\n accessor?: (row: T) => unknown;\n /** Enables header click sorting for this column. */\n sortable?: boolean;\n /** Enables a generated column filter when `autoFilter` is true. */\n filterable?: boolean;\n /** Native server-filter parameter associated with this rendered column. */\n filterKey?: string;\n /** Converts the raw cell value to the exact scalar sent to the native server filter. */\n serverFilterValue?: (value: unknown, row: T) => unknown;\n /** Converts the raw cell value to the label shown by server-filter actions. */\n serverFilterLabel?: (value: unknown, row: T) => string;\n /** Prefer allocating extra width to this column. */\n grow?: boolean;\n /** Prefer keeping this column compact. */\n shrink?: boolean;\n /** Allows users to drag the column separator. */\n resizable?: boolean;\n /** Allows the column to be toggled from the column menu. */\n hideable?: boolean;\n /** Minimum column width in pixels. */\n minWidth?: number;\n /** Maximum column width in pixels. */\n maxWidth?: number;\n /** Cell and header text alignment. */\n align?: \"left\" | \"center\" | \"right\";\n /** Custom cell renderer. */\n render?: (value: unknown, row: T) => ReactNode;\n /** Sort key derived from the raw value and row. */\n sortValue?: (value: unknown, row: T) => unknown;\n /** Filter token or tokens derived from the raw value and row. */\n filterValue?: (value: unknown, row: T) => FilterValue;\n /** Classes applied to cells in this column. */\n cellClassName?: string;\n /** Classes applied to the header cell. */\n headerClassName?: string;\n /**\n * Built-in cell kind. When set, DataTable supplies a default renderer,\n * a default `sortValue` and a default `filterValue` (all overridable).\n * - \"timestamp\": adaptive format (relative / time / short / iso) chosen\n * from the spread of values in `data`.\n * - \"tags\": chip list with `+N` overflow; auto-multi-filter on tag tokens.\n * - \"status\": colored dot with the standard error/warning/success palette\n * (token-mapped — \"ERROR\", \"failed\", \"fatal\" all collapse to \"error\").\n */\n kind?: DataTableColumnKind;\n timestamp?: TimestampOptions;\n tags?: TagsOptions;\n status?: StatusOptions<T>;\n};\n\nexport type DataTableColumnInput<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = DataTableColumn<T> | string;\n\n/**\n * Server-side pagination control surfaced as a footer strip below the table.\n * The DataTable never slices data itself; callers refetch when the page or\n * pageSize changes.\n */\nexport type DataTablePagination = {\n /** Current zero-indexed page. */\n page: number;\n /** Number of rows requested per page. */\n pageSize: number;\n /** Total row count if known; enables \"Page X of Y\". */\n total?: number;\n /**\n * Whether `total` is a count (\"eq\") or a lower bound (\"gte\"). A backend that\n * stops counting past a threshold reports a bound, and rendering it as a\n * count would state a number nobody promised.\n */\n totalRelation?: \"eq\" | \"gte\";\n /**\n * The server's answer for whether rows follow this page. Preferred over\n * inferring the end of the data from a short page: the two are different\n * facts, and only the server knows which one happened.\n */\n hasMore?: boolean;\n /**\n * Called when the user moves to another page. Absent when the surface cannot\n * name a position past its first page — an operation with no offset or cursor\n * parameter. Such a table still counts and still resizes; it just has nowhere\n * to step to, so the step controls are not rendered.\n */\n onPageChange?: (page: number) => void;\n /** Called when the page size select changes. */\n onPageSizeChange: (pageSize: number) => void;\n /** Available page sizes. Defaults to [25, 50, 100, 200]. */\n pageSizeOptions?: number[];\n /**\n * Cursor paging. When present the footer steps through the cursors the\n * server minted instead of by page number — a cursor names a position in an\n * ordered result, so there is no cursor for a page nobody has visited and\n * the page-number jump is not offered.\n */\n cursor?: DataTableCursorPagination;\n};\n\n/**\n * DataTableCursorPagination is the caller's half of a cursor walk. The tokens\n * are opaque: they are handed back unchanged and never parsed.\n */\nexport type DataTableCursorPagination = {\n /** The cursor this page was fetched with; undefined on the first page. */\n current?: string;\n /** The cursor that resumes after this page; absent when the data is exhausted. */\n next?: string;\n /** Fetch the page at this cursor; undefined returns to the first page. */\n onCursorChange: (cursor: string | undefined) => void;\n};\n\n/**\n * DataTableInfinite turns a server-paged table into one continuous list: the\n * caller accumulates the pages it has fetched and hands the whole run in as\n * `data`, and the table asks for the next one as the reader reaches the end.\n *\n * It is distinct from `clientReveal`, which windows rows the caller already\n * holds. Here the rows do not exist yet, so the two facts that matter are the\n * server's — whether more follow, and whether the request for them is already\n * in flight. Inferring either from `data.length` is what turns a slow page into\n * a duplicate request, and the end of the data into a spinner that never stops.\n *\n * Passing this alongside `pagination` is the normal case rather than a\n * conflict: the footer keeps reporting the count and page size, and only the\n * step controls are withdrawn, because a position nobody can step back to is\n * not one worth rendering a button for.\n */\nexport type DataTableInfinite = {\n /** The server's answer for whether rows follow what has been loaded. */\n hasMore: boolean;\n /** A request for the next page is in flight; the table must not ask again. */\n loading: boolean;\n /** Fetch and append the next page. */\n onLoadMore: () => void;\n};\n\nexport type DataTableMenuAction = {\n id: string;\n label: ReactNode;\n description?: ReactNode;\n icon?: StaticIconComponent;\n iconClassName?: string;\n disabled?: boolean;\n /** Heading the action is grouped under in the overflow menu. Actions with\n * the same section render together below one label; defaults to \"Download\"\n * so existing download actions keep their heading. An empty string groups\n * without a heading, for a short list where one would only add noise. */\n section?: string;\n /**\n * Nested actions. An action that has them is a submenu trigger: it opens a\n * flyout of its children and its own `onSelect` never runs. This is what\n * keeps a menu of a dozen formats to one row.\n */\n children?: DataTableMenuAction[];\n onSelect: () => void;\n};\n\nexport type DataTableRowSelection<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Controlled set of selected row ids, resolved through `getRowId`. */\n selectedRowIds: readonly string[];\n /** Called with the next ids and the matching rows currently loaded. */\n onSelectionChange: (selectedRowIds: string[], selectedRows: T[]) => void;\n /** Optional predicate for rows that cannot be selected. */\n isRowSelectable?: (row: T) => boolean;\n /** Toggle selection when the user clicks anywhere on a selectable row. */\n toggleOnRowClick?: boolean;\n};\n\n/** Passed to `selectionActions` while rows are selected. */\nexport type DataTableSelectionContext<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n selectedRowIds: string[];\n /** The selected rows currently loaded, in render order. */\n selectedRows: T[];\n /** Empties the selection through the same `onSelectionChange` callback. */\n clearSelection: () => void;\n};\n\n/** Passed to a `footer` render function. */\nexport type DataTableFooterContext = {\n /** Rows left after filtering — what the table is showing. */\n visibleRowCount: number;\n /** Rows handed to the table before filtering. */\n totalRowCount: number;\n loading: boolean;\n};\n\ntype DataTableInnerProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Rows to render. The table does not fetch or mutate row data. */\n data: T[];\n /** Error content rendered as an accessible full-width row in the table body. */\n error?: ReactNode;\n /**\n * Column descriptors. Pass a bare string for a default column —\n * `\"foo\"` is equivalent to `{ key: \"foo\", label: \"foo\" }` — handy for\n * ad-hoc query results where the column metadata is just a list of names.\n * Mix and match strings with full descriptors as needed.\n */\n columns: Array<DataTableColumnInput<T>>;\n /** Shows skeleton/loading rows instead of data rows. */\n loading?: boolean;\n /** Message shown while `loading` is true. */\n loadingMessage?: ReactNode;\n /** Number of skeleton rows to render while loading. */\n loadingRowCount?: number;\n /** Message used when there are no rows after filtering. */\n emptyMessage?: string;\n /**\n * Client-side incremental reveal (infinite scroll). When set — and no server\n * `pagination` is provided — the table renders `batchSize` rows at a time and\n * grows by `batchSize` as a trailing sentinel scrolls into view. Use for\n * large in-memory result sets (e.g. ad-hoc SQL output) to keep the first\n * paint cheap without paginating.\n */\n clientReveal?: { batchSize: number };\n /** Classes applied to the table shell. */\n className?: string;\n /**\n * Classes for the scrollable table region. Defaults to `min-h-0 flex-1`\n * (fills a bounded flex parent). Pass e.g. `max-h-[26rem]` to cap height.\n */\n scrollContainerClassName?: string;\n /** Generate filters from filterable columns. */\n autoFilter?: boolean;\n /**\n * Show the built-in global search input. Defaults to `autoFilter` — the box\n * narrows rows client-side, so it only mounts by default where DataTable\n * already owns filtering. Set it explicitly to search a table that generates\n * no column filters; combine with `manualFilter` plus `globalFilter` /\n * `onGlobalFilterChange` (or use `externalSearch`) to drive a source query.\n */\n showGlobalFilter?: boolean;\n /** Controlled global search value. */\n globalFilter?: string;\n /** Called when the global search changes. */\n onGlobalFilterChange?: (value: string) => void;\n /** Placeholder for the global search input. */\n globalFilterPlaceholder?: string;\n /** Initial sort state. */\n defaultSort?: { key: string; dir?: SortDir };\n /** Controlled sort state, for server-backed tables. */\n sort?: SortState | null;\n /** Called when a sortable header changes the controlled sort state. */\n onSortChange?: (sort: SortState | null) => void;\n /** When true, header sorting updates state but does not reorder `data`. */\n manualSort?: boolean;\n /**\n * When true, filters update state but do NOT narrow `data`. The mirror of\n * `manualSort`: the source owns filtering and DataTable only renders the\n * controls. Suppresses the client-side filter pass, the built-in search's row\n * narrowing, and the column-derived time range.\n */\n manualFilter?: boolean;\n /** Extra props forwarded to the internal FilterBar. */\n filterBarProps?: Omit<FilterBarProps, \"search\" | \"filters\">;\n /**\n * Caller-owned search input rendered in the FilterBar's search slot. Unlike\n * `globalFilter`, this does NOT filter rows client-side — it is a controlled\n * input the caller wires to a server-side query (e.g., an operation's `q`\n * parameter). Takes precedence over the built-in global filter input.\n */\n externalSearch?: FilterBarSearchProps;\n /**\n * Caller-owned time-range control rendered in the FilterBar. Like\n * `externalSearch`/`externalFilters`, it does NOT filter rows client-side —\n * the caller wires it to a server-side query (e.g. an operation's\n * `time-from`/`time-to` parameters). Takes precedence over any\n * column-derived time range.\n */\n externalTimeRange?: FilterBarRangeProps;\n /**\n * Extra filter pills supplied by the caller (e.g., operation query\n * parameters surfaced via parametersToFormConfig) that should appear in the\n * FilterBar alongside the column-derived filters. Rendered before the\n * column filters so the caller's natural ordering wins.\n */\n externalFilters?: FilterBarFilter[];\n /** Current modes for native server-backed cell filters. */\n cellFilters?: Record<string, Record<string, CellFilterMode>>;\n /** Called when a cell's include/exclude hover action changes. */\n onCellFilterChange?: (change: CellFilterChange) => void;\n /**\n * Server-side pagination footer. When provided, a small page-size / prev /\n * next strip is rendered below the table; the DataTable does NOT slice\n * `data` itself, callers are expected to refetch when `onPageChange` or\n * `onPageSizeChange` fires.\n */\n pagination?: DataTablePagination;\n /**\n * Server-driven infinite scroll. The caller owns the accumulated rows; this\n * only says when to ask for more. Combines with `pagination` — see\n * DataTableInfinite.\n */\n infinite?: DataTableInfinite;\n /**\n * Handle on the scrollable table region, for a caller that has to drive the\n * scroll position itself — pinning a live tail to the bottom, say. The table\n * never writes through it; it is exposed because a follow mode has to be able\n * to keep the newest row in view, and nothing outside the component can reach\n * that element otherwise.\n */\n scrollContainerRef?: RefObject<HTMLDivElement | null>;\n /** Stable row id extractor. Defaults to the row index. */\n getRowId?: (row: T, index: number) => string;\n /** Controlled checkbox selection for entity/bulk-action tables. */\n rowSelection?: DataTableRowSelection<T>;\n /**\n * Bulk action bar, pinned to the bottom of the table shell while\n * `rowSelection` holds a non-empty selection. Ignored without `rowSelection`.\n */\n selectionActions?: (context: DataTableSelectionContext<T>) => ReactNode;\n /**\n * Extra classes for a row's `<tr>`, applied last so tailwind-merge lets the\n * caller override the built-in hover / selected backgrounds.\n */\n getRowClassName?: (row: T) => string | undefined;\n /**\n * Replaces the default \"N of M rows\" strip below the table. When\n * `pagination` is also set, this renders directly above the pager instead.\n */\n footer?: ReactNode | ((context: DataTableFooterContext) => ReactNode);\n /**\n * Splits the rendered rows into collapsible groups, each introduced by a\n * full-width header row. Grouping presents what is already on screen: it\n * runs after filtering, sorting and pagination, so it never reorders rows\n * within a group and never pulls in rows from another page.\n */\n grouping?: DataTableGrouping<T>;\n /** Selectable grouping strategies rendered in the native FilterBar picker. */\n groupingModes?: Array<DataTableGroupingMode<T>>;\n /** Controlled grouping-mode value. Requires `onGroupingModeChange`. */\n groupingMode?: string;\n /** Initial grouping mode when DataTable owns the picker state. */\n defaultGroupingMode?: string;\n /** Called when the native grouping picker changes. */\n onGroupingModeChange?: (value: string) => void;\n /** Called when a clickable row is selected. */\n onRowClick?: (row: T) => void;\n /** Predicate controlling whether a row is clickable. */\n isRowClickable?: (row: T) => boolean;\n /** Optional href for row link affordances. */\n getRowHref?: (row: T) => string | undefined;\n /** Detail content rendered for expanded rows or dialog details. */\n renderExpandedRow?: (\n row: T,\n context: DataTableRowDetailContext<T>,\n ) => ReactNode;\n /**\n * How `renderExpandedRow` detail is surfaced when a row is clicked.\n * - \"row\" (default): expands an inline detail row beneath the clicked row.\n * Multiple rows can be open at once.\n * - \"dialog\": opens the detail content in a centered modal; one row at a\n * time. The same `renderExpandedRow` (and its context) drives both styles.\n */\n detailStyle?: \"row\" | \"dialog\";\n /**\n * Title for the detail dialog (detailStyle=\"dialog\"). Pass a function to\n * derive a per-row title, e.g. `(row) => \\`Session ${row.sessionId}\\``.\n */\n detailDialogTitle?: ReactNode | ((row: T) => ReactNode);\n /** Modal size for the detail dialog. Defaults to \"lg\". */\n detailDialogSize?: ModalSize;\n /** Enables column drag resize handles. */\n resizableColumns?: boolean;\n /** Persists column widths to localStorage. */\n persistColumnWidths?: boolean;\n /** Storage key for persisted column widths. */\n columnResizeStorageKey?: string;\n /** Enables column visibility controls. */\n hideableColumns?: boolean;\n /** Persists column visibility to localStorage. */\n persistColumnVisibility?: boolean;\n /** Storage key for persisted column visibility. */\n columnVisibilityStorageKey?: string;\n /** Controlled row density. */\n density?: Density;\n /** Initial row density for uncontrolled usage. */\n defaultDensity?: Density;\n /** Called when density changes. */\n onDensityChange?: (density: Density | undefined) => void;\n /** Persists density to localStorage. */\n persistDensity?: boolean;\n /** Storage key for persisted density. */\n densityStorageKey?: string;\n /** Shows density controls in the column menu. */\n showDensityControl?: boolean;\n /**\n * Current value of the theme menu shown in the column / preferences popover.\n * The inner DataTable does not apply this value itself — it's the menu's\n * displayed selection. The outer `DataTable` wrapper manages this state and\n * paints a wrapper-level `data-theme`.\n */\n themeMenuValue?: Theme;\n onThemeChange?: (theme: Theme) => void;\n /** Shows theme controls in the column menu. */\n showThemeControl?: boolean;\n /** Shows per-column filter buttons in table headers. */\n showHeaderFilters?: boolean;\n /** Extra actions rendered in the table preferences menu. */\n menuActions?: DataTableMenuAction[];\n};\n\nexport type DataTableProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = Omit<DataTableInnerProps<T>, \"themeMenuValue\"> & {\n /**\n * Initial / controlled theme value for the column-menu Theme section.\n * When `onThemeChange` is omitted, the DataTable manages this internally\n * (seeded from `theme`) and applies `data-theme` to its root so the table\n * reflects the choice without requiring an enclosing `<ThemeProvider>`.\n */\n theme?: Theme;\n /**\n * Render a fullscreen-toggle button in the FilterBar's trailing slot\n * (just before the column-menu trigger). When clicked, the table re-renders\n * inside a full-viewport `<Modal>`. Defaults to `false`.\n */\n showFullscreenControl?: boolean;\n /** Title shown in the fullscreen modal. */\n fullscreenTitle?: ReactNode;\n /**\n * `aria-label` and `title` for the fullscreen toggle button. Defaults to\n * \"Open table full screen\". LogsTable overrides to \"Open logs full screen\".\n */\n fullscreenButtonLabel?: string;\n};\n\nfunction assertDataTableGroupingProps<T>({\n grouping,\n groupingModes,\n groupingMode,\n defaultGroupingMode,\n onGroupingModeChange,\n}: {\n grouping: DataTableGrouping<T> | undefined;\n groupingModes: Array<DataTableGroupingMode<T>> | undefined;\n groupingMode: string | undefined;\n defaultGroupingMode: string | undefined;\n onGroupingModeChange: ((value: string) => void) | undefined;\n}) {\n if (grouping && groupingModes) {\n throw new Error(\"DataTable accepts grouping or groupingModes, not both\");\n }\n if (!groupingModes) {\n if (groupingMode !== undefined || defaultGroupingMode !== undefined) {\n throw new Error(\"DataTable groupingMode values require groupingModes\");\n }\n return;\n }\n if (groupingModes.length === 0) {\n throw new Error(\"DataTable groupingModes must not be empty\");\n }\n const values = new Set(groupingModes.map((mode) => mode.value));\n if (values.size !== groupingModes.length) {\n throw new Error(\"DataTable groupingModes values must be unique\");\n }\n if (groupingMode !== undefined && !onGroupingModeChange) {\n throw new Error(\n \"DataTable controlled groupingMode requires onGroupingModeChange\",\n );\n }\n if (groupingMode !== undefined && defaultGroupingMode !== undefined) {\n throw new Error(\n \"DataTable cannot combine groupingMode with defaultGroupingMode\",\n );\n }\n const selected = groupingMode ?? defaultGroupingMode;\n if (selected !== undefined && !values.has(selected)) {\n throw new Error(`DataTable grouping mode \"${selected}\" does not exist`);\n }\n}\n\nfunction DataTableInner<T extends Record<string, unknown>>({\n data,\n error,\n columns: columnsInput,\n loading = false,\n loadingMessage = \"Loading results…\",\n loadingRowCount = 8,\n emptyMessage = \"No data\",\n clientReveal,\n className,\n scrollContainerClassName,\n autoFilter = false,\n showGlobalFilter,\n manualFilter = false,\n globalFilter,\n onGlobalFilterChange,\n globalFilterPlaceholder = \"Search all columns…\",\n defaultSort,\n sort: controlledSort,\n onSortChange,\n manualSort = false,\n filterBarProps,\n externalSearch,\n externalTimeRange,\n externalFilters,\n cellFilters,\n onCellFilterChange,\n pagination,\n infinite,\n scrollContainerRef,\n getRowId,\n rowSelection,\n selectionActions,\n getRowClassName,\n footer,\n grouping,\n groupingModes,\n groupingMode,\n defaultGroupingMode,\n onGroupingModeChange,\n onRowClick,\n isRowClickable,\n getRowHref,\n renderExpandedRow,\n detailStyle = \"row\",\n detailDialogTitle,\n detailDialogSize = \"lg\",\n resizableColumns = true,\n persistColumnWidths = true,\n columnResizeStorageKey,\n hideableColumns = true,\n persistColumnVisibility = true,\n columnVisibilityStorageKey,\n density,\n defaultDensity,\n onDensityChange,\n persistDensity = true,\n densityStorageKey,\n showDensityControl,\n themeMenuValue,\n onThemeChange,\n showThemeControl = false,\n showHeaderFilters = true,\n menuActions,\n}: DataTableInnerProps<T>) {\n assertDataTableGroupingProps({\n grouping,\n groupingModes,\n groupingMode,\n defaultGroupingMode,\n onGroupingModeChange,\n });\n const columns = useMemo<DataTableColumn<T>[]>(\n () =>\n columnsInput.map((column) =>\n typeof column === \"string\" ? { key: column, label: column } : column,\n ),\n [columnsInput],\n );\n const columnKeysSignature = useMemo(\n () => columns.map((column) => column.key).join(\"|\"),\n [columns],\n );\n const resolvedColumnResizeStorageKey =\n columnResizeStorageKey ??\n `${COLUMN_WIDTH_STORAGE_PREFIX}:${columnKeysSignature}`;\n const resolvedColumnVisibilityStorageKey =\n columnVisibilityStorageKey ??\n `${COLUMN_VISIBILITY_STORAGE_PREFIX}:${columnKeysSignature}`;\n const resolvedDensityStorageKey =\n densityStorageKey ?? `${DENSITY_STORAGE_PREFIX}:${columnKeysSignature}`;\n const [columnWidths, setColumnWidths] = useState<Record<string, number>>(\n () =>\n persistColumnWidths\n ? readStoredColumnWidths(resolvedColumnResizeStorageKey, columns)\n : {},\n );\n const [hiddenColumns, setHiddenColumns] = useState<Record<string, boolean>>(\n () =>\n persistColumnVisibility\n ? readStoredHiddenColumns(resolvedColumnVisibilityStorageKey, columns)\n : {},\n );\n const densityControlled = density !== undefined;\n const [localDensityOverride, setLocalDensityOverride] = useState<\n Density | undefined\n >(() => {\n if (densityControlled) return density;\n if (persistDensity)\n return (\n readStoredDensityOverride(resolvedDensityStorageKey) ?? defaultDensity\n );\n return defaultDensity;\n });\n const [columnMenu, setColumnMenu] = useState<ColumnMenuState | null>(null);\n const [headerFilterMenu, setHeaderFilterMenu] =\n useState<ColumnMenuState | null>(null);\n const [textFilters, setTextFilters] = useState<Record<string, string>>({});\n const [multiFilters, setMultiFilters] = useState<\n Record<string, Record<string, FilterBarMultiFilterMode>>\n >({});\n const [numberFilters, setNumberFilters] = useState<\n Record<string, FilterBarNumberValue>\n >({});\n const [expandedRows, setExpandedRows] = useState<Record<string, boolean>>({});\n const [detailRow, setDetailRow] = useState<InternalRow<T> | null>(null);\n const [localGroupingMode, setLocalGroupingMode] = useState<\n string | undefined\n >(defaultGroupingMode);\n const [localGlobalFilter, setLocalGlobalFilter] = useState(\"\");\n const [timeRangeFilter, setTimeRangeFilter] = useState<{\n from: string;\n to: string;\n }>(() => {\n const seed = columns.find(\n (column) => column.kind === \"timestamp\" && column.timestamp?.defaultRange,\n );\n return {\n from: seed?.timestamp?.defaultRange?.from ?? \"\",\n to: seed?.timestamp?.defaultRange?.to ?? \"\",\n };\n });\n\n useEffect(() => {\n setColumnWidths((current) => {\n const stored = persistColumnWidths\n ? readStoredColumnWidths(resolvedColumnResizeStorageKey, columns)\n : {};\n const next = pruneColumnWidths({ ...stored, ...current }, columns);\n return sameColumnWidths(current, next) ? current : next;\n });\n }, [\n columnKeysSignature,\n persistColumnWidths,\n resolvedColumnResizeStorageKey,\n ]);\n\n useEffect(() => {\n if (!persistColumnWidths) return;\n writeStoredColumnWidths(resolvedColumnResizeStorageKey, columnWidths);\n }, [columnWidths, persistColumnWidths, resolvedColumnResizeStorageKey]);\n\n useEffect(() => {\n setHiddenColumns((current) => {\n const stored = persistColumnVisibility\n ? readStoredHiddenColumns(resolvedColumnVisibilityStorageKey, columns)\n : {};\n const next = pruneHiddenColumns({ ...stored, ...current }, columns);\n return sameHiddenColumns(current, next) ? current : next;\n });\n }, [\n columnKeysSignature,\n persistColumnVisibility,\n resolvedColumnVisibilityStorageKey,\n ]);\n\n useEffect(() => {\n if (!persistColumnVisibility) return;\n writeStoredHiddenColumns(resolvedColumnVisibilityStorageKey, hiddenColumns);\n }, [\n hiddenColumns,\n persistColumnVisibility,\n resolvedColumnVisibilityStorageKey,\n ]);\n\n useEffect(() => {\n if (densityControlled) return;\n setLocalDensityOverride(\n persistDensity\n ? (readStoredDensityOverride(resolvedDensityStorageKey) ??\n defaultDensity)\n : defaultDensity,\n );\n }, [\n defaultDensity,\n densityControlled,\n persistDensity,\n resolvedDensityStorageKey,\n ]);\n\n useEffect(() => {\n if (densityControlled || !persistDensity) return;\n writeStoredDensityOverride(resolvedDensityStorageKey, localDensityOverride);\n }, [\n densityControlled,\n localDensityOverride,\n persistDensity,\n resolvedDensityStorageKey,\n ]);\n\n const closeFloatingMenus = useCallback(() => {\n setColumnMenu(null);\n setHeaderFilterMenu(null);\n }, []);\n\n useEscapeLayer(Boolean(columnMenu || headerFilterMenu), closeFloatingMenus);\n\n useEffect(() => {\n if (!columnMenu && !headerFilterMenu) return;\n document.addEventListener(\"click\", closeFloatingMenus);\n return () => {\n document.removeEventListener(\"click\", closeFloatingMenus);\n };\n }, [closeFloatingMenus, columnMenu, headerFilterMenu]);\n\n const rows = useMemo<InternalRow<T>[]>(\n () =>\n data.map((row, index) => ({\n id: getRowId?.(row, index) ?? String(index),\n row,\n })),\n [data, getRowId],\n );\n\n const timestampFormats = useMemo<Record<string, TimestampFormat>>(() => {\n const out: Record<string, TimestampFormat> = {};\n for (const column of columns) {\n if (column.kind !== \"timestamp\") continue;\n const dates: Date[] = [];\n for (const row of data) {\n const raw = resolveColumnValue(row, column);\n const parsed = parseTimestamp(raw);\n if (parsed) dates.push(parsed);\n }\n const dataFormat = chooseTimestampFormat(dates);\n out[column.key] = modeToFormat(\n column.timestamp?.mode ?? \"auto\",\n dataFormat,\n );\n }\n return out;\n }, [columns, data]);\n\n const effectiveColumns = useMemo<DataTableColumn<T>[]>(\n () =>\n columns.map((column) =>\n applyKindDefaults<T>(column, timestampFormats[column.key]),\n ),\n [columns, timestampFormats],\n );\n const activeGroupingModeValue =\n groupingMode ??\n localGroupingMode ??\n defaultGroupingMode ??\n groupingModes?.[0]?.value;\n const activeGroupingMode = groupingModes?.find(\n (mode) => mode.value === activeGroupingModeValue,\n );\n const effectiveGrouping = useMemo<DataTableGrouping<T> | undefined>(() => {\n if (!activeGroupingMode) return grouping;\n if (activeGroupingMode.type === \"none\") return undefined;\n if (activeGroupingMode.type === \"custom\") return activeGroupingMode;\n\n const column = effectiveColumns.find(\n (candidate) => candidate.key === activeGroupingMode.columnKey,\n );\n if (!column) {\n throw new Error(\n `DataTable grouping mode \"${activeGroupingMode.value}\" references missing column \"${activeGroupingMode.columnKey}\"`,\n );\n }\n return {\n ...activeGroupingMode,\n getGroupKey: (row) => dataTableGroupKey(resolveColumnValue(row, column)),\n // `emptyGroupLabel` is a header label, never a key — resolving it here\n // keeps rows with no value apart from rows whose value happens to read\n // like the label.\n getGroupLabel: (key, rows) => {\n const custom = activeGroupingMode.getGroupLabel?.(key, rows);\n return custom !== undefined\n ? custom\n : dataTableGroupLabel(key, activeGroupingMode.emptyGroupLabel);\n },\n };\n }, [activeGroupingMode, effectiveColumns, grouping]);\n\n const visibleColumns = useMemo(() => {\n if (!hideableColumns) return effectiveColumns;\n const next = effectiveColumns.filter(\n (column) => !hiddenColumns[column.key],\n );\n return next.length > 0 ? next : effectiveColumns;\n }, [effectiveColumns, hiddenColumns, hideableColumns]);\n\n const hideableColumnCount = useMemo(\n () => effectiveColumns.filter(isColumnHideable).length,\n [effectiveColumns],\n );\n\n const visibleHideableColumnCount = useMemo(\n () => visibleColumns.filter(isColumnHideable).length,\n [visibleColumns],\n );\n\n const showColumnVisibilityControl =\n hideableColumns && hideableColumnCount > 1;\n const resolvedShowDensityControl =\n showDensityControl ?? showColumnVisibilityControl;\n const hasMenuActions = Boolean(menuActions && menuActions.length > 0);\n const showTablePreferencesControl =\n showColumnVisibilityControl ||\n resolvedShowDensityControl ||\n showThemeControl ||\n hasMenuActions;\n const densityOverride = densityControlled ? density : localDensityOverride;\n\n // The first kind:\"timestamp\" column (with autoRangeFilter not disabled) owns\n // the FilterBar's trailing range slot — filled either by the column's own\n // server filter or, when nothing backs it, by a locally narrowed picker.\n const rangeCapableColumn = useMemo(\n () =>\n effectiveColumns.find(\n (column) =>\n column.kind === \"timestamp\" &&\n column.filterable !== false &&\n column.timestamp?.autoRangeFilter !== false,\n ) ?? null,\n [effectiveColumns],\n );\n // The auto range narrows rows here, so it only mounts where DataTable owns\n // filtering. On a source-filtered table the picker would re-filter rows the\n // source already answered with — and the timestamp cell it reads is often a\n // rendered node rather than a value, so it would silently empty the table.\n const timeRangeColumn = useMemo(() => {\n if (!autoFilter || manualFilter || externalTimeRange || filterBarProps?.timeRange) {\n return null;\n }\n return rangeCapableColumn;\n }, [\n autoFilter,\n externalTimeRange,\n filterBarProps?.timeRange,\n manualFilter,\n rangeCapableColumn,\n ]);\n\n const filterableColumns = useMemo(\n () =>\n effectiveColumns.filter((column) => {\n if (column.filterable === false) return false;\n // Timestamp columns are filtered through the time-range picker, not\n // a per-column text/multi filter. Skip them in auto-filter generation.\n if (column.kind === \"timestamp\") return false;\n return true;\n }),\n [effectiveColumns],\n );\n\n const generatedFilters = useMemo<GeneratedFilter<T>[]>(() => {\n if (!autoFilter || loading) return [];\n\n return filterableColumns.map((column) => {\n const numberBounds = getNumericFilterBounds(rows, column);\n if (numberBounds) {\n return {\n column,\n kind: \"number\" as const,\n options: [],\n numberBounds,\n };\n }\n\n const values = new Set<string>();\n\n for (const record of rows) {\n for (const token of getFilterTokens(record.row, column)) {\n if (token) values.add(token);\n }\n }\n\n const options = Array.from(values)\n .sort((left, right) =>\n left.localeCompare(right, undefined, { numeric: true }),\n )\n .map((value) => ({ value, label: value }));\n\n // Tag columns naturally have higher cardinality (e.g. infra labels);\n // we let the multi-filter scale to 50 distinct values before falling\n // back to free-text search.\n const multiCap = column.kind === \"tags\" ? 50 : 20;\n\n const fitsMulti = options.length >= 2 && options.length <= multiCap;\n\n // For tag columns we group tokens by their key so the filter renders\n // as a two-level submenu (env → prod/staging, tier → edge/core, …).\n // Falls back to a flat multi when there's only one key (or none).\n if (column.kind === \"tags\" && fitsMulti) {\n const separator = column.tags?.separator ?? \"=\";\n const groups = groupTagOptions(options, separator);\n if (groups.length >= 2) {\n return {\n column,\n kind: \"nested-multi\" as const,\n options,\n groups,\n };\n }\n }\n\n return {\n column,\n kind: fitsMulti ? \"multi\" : \"text\",\n options,\n };\n });\n }, [autoFilter, filterableColumns, loading, rows]);\n\n // For every multi / nested-multi column (which includes kind:\"tags\"), expose a\n // TagActions value backed by this table's multiFilters slot. The + / − icons in\n // tag cells and in expanded-row details mutate the same Record<token, mode>\n // shape the filter-bar dropdown uses, so the existing filter pipeline picks up\n // the change. Built from generatedFilters so it stays in lockstep with\n // pruneMultiFilterState (only multi/nested-multi columns honor multiFilters).\n const filterActionsByColumn = useMemo(() => {\n const out: Record<string, TagActionsContextValue> = {};\n for (const filter of generatedFilters) {\n if (filter.kind !== \"multi\" && filter.kind !== \"nested-multi\") continue;\n const columnKey = filter.column.key;\n const current = (multiFilters[columnKey] ?? {}) as Record<\n string,\n TagFilterMode\n >;\n const handler = (next: Record<string, TagFilterMode>) =>\n setMultiFilters((state) => updateFilterRecord(state, columnKey, next));\n out[columnKey] = tagActionsFromRecord(current, handler);\n }\n return out;\n }, [generatedFilters, multiFilters]);\n\n useEffect(() => {\n setTextFilters((current) =>\n pruneTextFilterState(current, generatedFilters),\n );\n setMultiFilters((current) =>\n pruneMultiFilterState(current, generatedFilters),\n );\n setNumberFilters((current) =>\n pruneNumberFilterState(current, generatedFilters),\n );\n }, [generatedFilters]);\n\n const globalFilterControlled = globalFilter !== undefined;\n const effectiveGlobalFilter = globalFilterControlled\n ? globalFilter\n : localGlobalFilter;\n const setEffectiveGlobalFilter = globalFilterControlled\n ? (onGlobalFilterChange ?? (() => {}))\n : setLocalGlobalFilter;\n const nativeFilters = useMemo<FilterBarFilter[]>(\n () =>\n generatedFilters.map((filter): FilterBarFilter => {\n const columnKey = filter.column.key;\n if (filter.kind === \"multi\") {\n return {\n key: columnKey,\n kind: \"multi\",\n label: labelText(filter.column),\n value: multiFilters[columnKey] ?? {},\n onChange: (next) =>\n setMultiFilters((current) =>\n updateFilterRecord(current, columnKey, next),\n ),\n options: filter.options,\n };\n }\n if (filter.kind === \"nested-multi\") {\n return {\n key: columnKey,\n kind: \"nested-multi\",\n label: labelText(filter.column),\n value: multiFilters[columnKey] ?? {},\n onChange: (next) =>\n setMultiFilters((current) =>\n updateFilterRecord(current, columnKey, next),\n ),\n groups: filter.groups ?? [],\n };\n }\n if (filter.kind === \"number\") {\n const numberFilter: Extract<FilterBarFilter, { kind: \"number\" }> = {\n key: columnKey,\n kind: \"number\",\n label: labelText(filter.column),\n value: numberFilters[columnKey] ?? {},\n onChange: (next: FilterBarNumberValue) =>\n setNumberFilters((current) =>\n updateNumberFilterValue(current, columnKey, next),\n ),\n };\n if (filter.numberBounds?.min !== undefined) {\n numberFilter.domainMin = filter.numberBounds.min;\n }\n if (filter.numberBounds?.max !== undefined) {\n numberFilter.domainMax = filter.numberBounds.max;\n }\n if (filter.numberBounds?.step !== undefined) {\n numberFilter.step = filter.numberBounds.step;\n }\n return numberFilter;\n }\n return {\n key: columnKey,\n kind: \"text\",\n label: labelText(filter.column),\n value: textFilters[columnKey] ?? \"\",\n onChange: (next: string) =>\n setTextFilters((current) =>\n updateFilterValue(current, columnKey, next),\n ),\n };\n }),\n [generatedFilters, multiFilters, numberFilters, textFilters],\n );\n const serverFilterByKey = useMemo(\n () => new Map((externalFilters ?? []).map((filter) => [filter.key, filter])),\n [externalFilters],\n );\n // The timestamp column's own bound, when the caller supplies one, IS the\n // bar's range — so it is hoisted out of the filter list into the trailing\n // slot. Leaving it among the chips and mounting the column-derived picker\n // beside it would put two controls on one filter, and only one of them\n // reaches the source.\n //\n // Keyed on the FilterBar kind rather than any upstream control name: a\n // whole-day bound (\"day-range\" on the wire) is normalized to the same\n // \"date-range\" kind with timeEnabled off, and belongs in the same slot.\n const serverTimeRangeFilter = useMemo(() => {\n const key = rangeCapableColumn?.filterKey;\n const filter = key ? serverFilterByKey.get(key) : undefined;\n return filter?.kind === \"date-range\" ? filter : null;\n }, [rangeCapableColumn, serverFilterByKey]);\n // A header filter button comes from whichever pipeline owns the column:\n // autoFilter's generated filter (keyed by column.key) or a caller-supplied\n // server filter bound through the column's `filterKey` — the same key\n // `cellFilters` is already indexed by, so the include/exclude cell actions\n // and the header popover address one filter rather than two.\n const headerFilterByColumn = useMemo(() => {\n const bound = new Map<string, FilterBarFilter>();\n for (const column of effectiveColumns) {\n const native = nativeFilters.find((filter) => filter.key === column.key);\n if (native) {\n bound.set(column.key, native);\n continue;\n }\n const server = column.filterKey ? serverFilterByKey.get(column.filterKey) : undefined;\n // The hoisted range is rendered as a range in this column's header, not\n // as a chip, so it must not be bound here as well.\n if (server && server !== serverTimeRangeFilter) bound.set(column.key, server);\n }\n return bound;\n }, [effectiveColumns, nativeFilters, serverFilterByKey, serverTimeRangeFilter]);\n const hasCustomFilterBarContent = Boolean(\n filterBarProps?.leading ||\n filterBarProps?.children ||\n filterBarProps?.trailing ||\n filterBarProps?.timeRange ||\n filterBarProps?.dateRange,\n );\n const autoTimeRange = useMemo<FilterBarRangeProps | null>(() => {\n if (!timeRangeColumn) return null;\n const next: FilterBarRangeProps = {\n from: timeRangeFilter.from,\n to: timeRangeFilter.to,\n onApply: (from, to) => setTimeRangeFilter({ from, to }),\n presets:\n timeRangeColumn.timestamp?.rangePresets ?? TIMESTAMP_RANGE_PRESETS,\n fromPlaceholder: \"now-24h\",\n toPlaceholder: \"now\",\n emptyLabel: \"Any time\",\n };\n if (timeRangeColumn.timestamp?.timeEnabled !== undefined) {\n next.timeEnabled = timeRangeColumn.timestamp.timeEnabled;\n }\n if (timeRangeColumn.timestamp?.timeZone) {\n next.timeZone = timeRangeColumn.timestamp.timeZone;\n }\n if (timeRangeColumn.timestamp?.timeZones) {\n next.timeZones = timeRangeColumn.timestamp.timeZones;\n }\n return next;\n }, [timeRangeColumn, timeRangeFilter.from, timeRangeFilter.to]);\n // The one range a column owns, and which column's header renders it. The\n // hoisted server bound wins over the local picker; a caller-supplied range\n // belongs to no column and so wins over both, in the bar only.\n const columnTimeRange = useMemo<{\n key: string;\n range: FilterBarRangeProps;\n } | null>(() => {\n if (serverTimeRangeFilter && rangeCapableColumn) {\n return {\n key: rangeCapableColumn.key,\n range: dateRangeFilterProps(serverTimeRangeFilter),\n };\n }\n if (autoTimeRange && timeRangeColumn) {\n return { key: timeRangeColumn.key, range: autoTimeRange };\n }\n return null;\n }, [autoTimeRange, rangeCapableColumn, serverTimeRangeFilter, timeRangeColumn]);\n const barTimeRange = externalTimeRange ?? columnTimeRange?.range ?? null;\n const barFilters = useMemo(() => {\n const external = (externalFilters ?? []).filter(\n (filter) => filter !== serverTimeRangeFilter,\n );\n return external.length > 0 ? [...external, ...nativeFilters] : nativeFilters;\n }, [externalFilters, nativeFilters, serverTimeRangeFilter]);\n // The built-in search narrows rows here, so it mounts by default only where\n // DataTable already owns filtering. An explicit value still wins, which is\n // what lets a source-filtered table search its own page.\n const resolvedShowGlobalFilter = showGlobalFilter ?? autoFilter;\n assertDataTableFilterProps({\n autoFilter,\n manualFilter,\n showGlobalFilter: resolvedShowGlobalFilter,\n globalFilterControlled: globalFilter !== undefined || onGlobalFilterChange !== undefined,\n hasExternalSearch: externalSearch !== undefined,\n });\n const showFilterBar =\n resolvedShowGlobalFilter ||\n nativeFilters.length > 0 ||\n !!barTimeRange ||\n !!externalSearch ||\n (externalFilters && externalFilters.length > 0) ||\n hasCustomFilterBarContent ||\n !!groupingModes ||\n showTablePreferencesControl;\n const setDensityOverride = (next: Density | undefined) => {\n if (!densityControlled) setLocalDensityOverride(next);\n onDensityChange?.(next);\n };\n const showHeaderFilterControls =\n showHeaderFilters && (headerFilterByColumn.size > 0 || !!columnTimeRange);\n\n const filteredRows = useMemo(() => {\n // The source already applied every filter, so applying them again here\n // would narrow rows a second time and show fewer than were asked for.\n if (manualFilter) return rows;\n const globalNeedle = effectiveGlobalFilter.trim().toLowerCase();\n const now = new Date();\n const rangeFromDate = timeRangeColumn\n ? resolveDateMath(timeRangeFilter.from, now)\n : null;\n const rangeToDate = timeRangeColumn\n ? resolveDateMath(timeRangeFilter.to, now)\n : null;\n return rows.filter(({ row }) => {\n if (timeRangeColumn && (rangeFromDate || rangeToDate)) {\n // Through the column, not the raw path: a cell is often a rendered\n // node (clicky results address `cells.<name>` and carry a ClickyNode\n // there), which parses to null and would drop every row.\n const ts = parseTimestamp(getFilterCandidate(row, timeRangeColumn));\n if (!ts) return false;\n if (rangeFromDate && ts.getTime() < rangeFromDate.getTime())\n return false;\n if (rangeToDate && ts.getTime() > rangeToDate.getTime()) return false;\n }\n\n if (globalNeedle) {\n const haystack = filterableColumns\n .flatMap((column) => getFilterTokens(row, column))\n .join(\" \")\n .toLowerCase();\n\n if (!haystack.includes(globalNeedle)) {\n return false;\n }\n }\n\n for (const filter of generatedFilters) {\n const tokens = getFilterTokens(row, filter.column);\n\n if (filter.kind === \"text\") {\n const needle = (textFilters[filter.column.key] ?? \"\")\n .trim()\n .toLowerCase();\n if (\n needle &&\n !tokens.some((token) => token.toLowerCase().includes(needle))\n ) {\n return false;\n }\n } else if (filter.kind === \"number\") {\n const range = numberFilters[filter.column.key] ?? {};\n const min = parseNumberInput(range.min);\n const max = parseNumberInput(range.max);\n const hasMin = String(range.min ?? \"\").trim() !== \"\";\n const hasMax = String(range.max ?? \"\").trim() !== \"\";\n\n if (hasMin || hasMax) {\n const values = getFilterNumbers(row, filter.column);\n const matches = values.some(\n (value) =>\n (min == null || value >= min) && (max == null || value <= max),\n );\n\n if (!matches) {\n return false;\n }\n }\n } else {\n const selected = multiFilters[filter.column.key] ?? {};\n const include = Object.entries(selected)\n .filter(([, mode]) => mode === \"include\")\n .map(([value]) => value);\n const exclude = Object.entries(selected)\n .filter(([, mode]) => mode === \"exclude\")\n .map(([value]) => value);\n\n if (\n include.length > 0 &&\n !tokens.some((token) => include.includes(token))\n ) {\n return false;\n }\n\n if (\n exclude.length > 0 &&\n tokens.some((token) => exclude.includes(token))\n ) {\n return false;\n }\n }\n }\n\n return true;\n });\n }, [\n effectiveGlobalFilter,\n filterableColumns,\n generatedFilters,\n manualFilter,\n multiFilters,\n numberFilters,\n rows,\n textFilters,\n timeRangeColumn,\n timeRangeFilter.from,\n timeRangeFilter.to,\n ]);\n\n const sortResolvers = useMemo(\n () =>\n Object.fromEntries(\n effectiveColumns.map((column) => [\n column.key,\n (record: InternalRow<T>) => getSortValue(record.row, column),\n ]),\n ) as Record<string, (record: InternalRow<T>) => unknown>,\n [effectiveColumns],\n );\n\n const { renderLink } = useRouter();\n\n const { sorted, sort, toggle } = useSort(filteredRows, {\n defaultDir: defaultSort?.dir ?? \"asc\",\n manual: manualSort,\n resolvers: sortResolvers,\n ...(controlledSort !== undefined ? { sort: controlledSort } : {}),\n ...(onSortChange ? { onSortChange } : {}),\n ...(defaultSort?.key ? { defaultKey: defaultSort.key } : {}),\n });\n\n // Sorting one page of a server-paged result reorders that page and nothing\n // else, which reads as a sort of the whole table and is not one. Under server\n // paging the header therefore goes inert unless the caller wired the sort\n // through to the server, where the whole result set actually lives.\n const pageLocalSort = !!pagination && !onSortChange;\n\n // Client-side incremental reveal: when `clientReveal` is set (and the caller\n // is not doing server pagination), only the first `visibleCount` sorted rows\n // are rendered; a trailing sentinel grows the window as it scrolls into view.\n // `infinite` is the same gesture aimed at the server rather than at memory, so\n // it takes the sentinel outright: windowing rows the caller just paid a\n // request for would hide them again the moment they arrived.\n const revealEnabled = !!clientReveal && !pagination && !infinite;\n const revealBatchSize = clientReveal?.batchSize ?? 0;\n const [visibleCount, setVisibleCount] = useState(revealBatchSize);\n const revealObserver = useRef<IntersectionObserver | null>(null);\n\n useEffect(() => {\n // Reset the window whenever the filtered/sorted set or batch size changes\n // so a new query starts from the top rather than mid-scroll.\n if (revealEnabled) setVisibleCount(revealBatchSize);\n }, [revealEnabled, revealBatchSize, sorted]);\n\n const visibleSorted = revealEnabled ? sorted.slice(0, visibleCount) : sorted;\n const hasMoreRows = revealEnabled && visibleCount < sorted.length;\n\n // Server-driven infinite scroll shares the sentinel and the observer with\n // `clientReveal`; only what an intersection means differs. Unlike the reveal\n // window it is not gated on `pagination` — a table paging the server is\n // precisely the one that has more to fetch — and it has no window to reset,\n // because the caller owns the accumulation and it only ever grows.\n const requestMoreRows = useInfiniteRows(infinite, data.length);\n const infiniteEnabled = !!infinite;\n const sentinelActive = infinite ? infinite.hasMore : hasMoreRows;\n // The sentinel names what it is waiting on. Client reveal holds the rows and\n // only has to paint them, so it is always mid-load; the server variant sits\n // idle until the reader reaches it, and announcing a fetch that has not\n // started reads as a table that is permanently busy.\n const sentinelLabel =\n !infinite || infinite.loading ? \"Loading more…\" : \"Scroll to load more…\";\n const selectedRowIDs = useMemo(\n () => new Set(rowSelection?.selectedRowIds ?? []),\n [rowSelection?.selectedRowIds],\n );\n const selectableVisibleRows = useMemo(\n () =>\n visibleSorted.filter(\n (record) => rowSelection?.isRowSelectable?.(record.row) ?? true,\n ),\n [rowSelection, visibleSorted],\n );\n const selectedVisibleCount = selectableVisibleRows.filter((record) =>\n selectedRowIDs.has(record.id),\n ).length;\n const allVisibleSelected =\n selectableVisibleRows.length > 0 &&\n selectedVisibleCount === selectableVisibleRows.length;\n const someVisibleSelected = selectedVisibleCount > 0 && !allVisibleSelected;\n const selectAllRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (selectAllRef.current) {\n selectAllRef.current.indeterminate = someVisibleSelected;\n }\n }, [someVisibleSelected]);\n\n const notifySelection = useCallback(\n (nextIDs: Set<string>) => {\n if (!rowSelection) return;\n rowSelection.onSelectionChange(\n Array.from(nextIDs),\n rows\n .filter((record) => nextIDs.has(record.id))\n .map((record) => record.row),\n );\n },\n [rowSelection, rows],\n );\n\n const toggleRowSelection = useCallback(\n (record: InternalRow<T>) => {\n if (!rowSelection) return;\n if (rowSelection.isRowSelectable?.(record.row) === false) return;\n const next = new Set(selectedRowIDs);\n if (next.has(record.id)) next.delete(record.id);\n else next.add(record.id);\n notifySelection(next);\n },\n [notifySelection, rowSelection, selectedRowIDs],\n );\n\n const toggleVisibleSelection = useCallback(() => {\n if (!rowSelection) return;\n const next = new Set(selectedRowIDs);\n if (allVisibleSelected) {\n for (const record of selectableVisibleRows) next.delete(record.id);\n } else {\n for (const record of selectableVisibleRows) next.add(record.id);\n }\n notifySelection(next);\n }, [\n allVisibleSelected,\n notifySelection,\n rowSelection,\n selectableVisibleRows,\n selectedRowIDs,\n ]);\n\n const selectionBar = useMemo(() => {\n if (!rowSelection || !selectionActions) return null;\n const selected = rows.filter((record) => selectedRowIDs.has(record.id));\n if (selected.length === 0) return null;\n return selectionActions({\n selectedRowIds: selected.map((record) => record.id),\n selectedRows: selected.map((record) => record.row),\n clearSelection: () => notifySelection(new Set()),\n });\n }, [notifySelection, rowSelection, rows, selectedRowIDs, selectionActions]);\n\n const renderedFooter =\n error != null\n ? null\n : footer !== undefined\n ? typeof footer === \"function\"\n ? footer({\n visibleRowCount: sorted.length,\n totalRowCount: data.length,\n loading,\n })\n : footer\n : pagination\n ? null\n : loading && sorted.length === 0\n ? loadingMessage\n : `${sorted.length} of ${data.length} row${data.length === 1 ? \"\" : \"s\"}`;\n\n const [collapseStateByMode, setCollapseStateByMode] = useState<\n Record<string, GroupCollapseState>\n >({});\n const collapseStateKey = activeGroupingMode\n ? `mode:${activeGroupingMode.value}`\n : \"fixed\";\n const collapseState = collapseStateByMode[collapseStateKey];\n const groups = useMemo(() => {\n if (!effectiveGrouping) return null;\n const buckets = groupRecords(visibleSorted, (record) =>\n effectiveGrouping.getGroupKey(record.row),\n );\n const resolved = buckets.map((bucket) => ({\n key: bucket.key,\n records: bucket.rows,\n rows: bucket.rows.map((record) => record.row),\n }));\n if (effectiveGrouping.compareGroups) {\n resolved.sort((a, b) => effectiveGrouping.compareGroups!(a, b));\n }\n return resolved.map((group) => ({\n ...group,\n label:\n effectiveGrouping.getGroupLabel?.(group.key, group.rows) ?? group.key,\n meta: effectiveGrouping.getGroupMeta?.(group.key, group.rows),\n collapsed:\n collapseState?.groups[group.key] ??\n collapseState?.all ??\n isGroupCollapsedByDefault(group, effectiveGrouping.defaultCollapsed),\n }));\n }, [collapseState, effectiveGrouping, visibleSorted]);\n\n const hasGroups = !!groups?.length;\n const allGroupsExpanded =\n hasGroups && groups.every((group) => !group.collapsed);\n const allGroupsCollapsed =\n hasGroups && groups.every((group) => group.collapsed);\n const setAllGroupsCollapsed = (collapsed: boolean) => {\n setCollapseStateByMode((current) => ({\n ...current,\n [collapseStateKey]: { all: collapsed, groups: {} },\n }));\n };\n const filterBarTrailing =\n filterBarProps?.trailing || groupingModes || showTablePreferencesControl ? (\n <>\n {filterBarProps?.trailing}\n {groupingModes ? (\n <DataTableGroupingControls\n modes={groupingModes}\n value={activeGroupingModeValue!}\n hasGroups={hasGroups}\n allExpanded={allGroupsExpanded}\n allCollapsed={allGroupsCollapsed}\n onModeChange={(value) => {\n if (groupingMode === undefined) setLocalGroupingMode(value);\n onGroupingModeChange?.(value);\n }}\n onExpandAll={() => setAllGroupsCollapsed(false)}\n onCollapseAll={() => setAllGroupsCollapsed(true)}\n />\n ) : null}\n {showTablePreferencesControl ? (\n <ColumnVisibilityTrigger\n onOpen={(event) => setColumnMenu(menuStateFromTrigger(event))}\n />\n ) : null}\n </>\n ) : undefined;\n\n // Group headers and data rows share one flat stream so the <tbody> keeps a\n // single row renderer whether or not grouping is on.\n const rowStream = useMemo<Array<RowStreamItem<T>>>(() => {\n if (!groups) {\n return visibleSorted.map((record) => ({ kind: \"row\", record }) as const);\n }\n return groups.flatMap((group) => [\n { kind: \"group\", group } as const,\n ...(group.collapsed\n ? []\n : group.records.map((record) => ({ kind: \"row\", record }) as const)),\n ]);\n }, [groups, visibleSorted]);\n\n const toggleGroupSelection = useCallback(\n (records: InternalRow<T>[]) => {\n if (!rowSelection) return;\n const selectable = records.filter(\n (record) => rowSelection.isRowSelectable?.(record.row) ?? true,\n );\n const next = new Set(selectedRowIDs);\n const allSelected =\n selectable.length > 0 &&\n selectable.every((record) => next.has(record.id));\n for (const record of selectable) {\n if (allSelected) next.delete(record.id);\n else next.add(record.id);\n }\n notifySelection(next);\n },\n [notifySelection, rowSelection, selectedRowIDs],\n );\n\n const revealSentinelRef = useCallback(\n (node: HTMLTableRowElement | null) => {\n if (revealObserver.current) revealObserver.current.disconnect();\n if (!node || !sentinelActive) return;\n revealObserver.current = new IntersectionObserver(\n (entries) => {\n if (!entries[0]?.isIntersecting) return;\n if (infiniteEnabled) {\n requestMoreRows();\n return;\n }\n setVisibleCount((current) =>\n Math.min(current + revealBatchSize, sorted.length),\n );\n },\n { rootMargin: \"200px\" },\n );\n revealObserver.current.observe(node);\n },\n [\n infiniteEnabled,\n requestMoreRows,\n revealBatchSize,\n sentinelActive,\n sorted.length,\n ],\n );\n\n const startColumnResize = (\n event: ReactMouseEvent<HTMLElement>,\n column: DataTableColumn<T>,\n ) => {\n event.preventDefault();\n event.stopPropagation();\n\n const startX = event.clientX;\n const header = event.currentTarget.closest(\"th\");\n const measuredWidth = header?.getBoundingClientRect().width ?? 0;\n const startWidth =\n measuredWidth || columnWidths[column.key] || defaultColumnWidth(column);\n\n const onMove = (moveEvent: MouseEvent) => {\n const nextWidth = clampColumnWidth(\n column,\n startWidth + moveEvent.clientX - startX,\n );\n setColumnWidths((current) => ({\n ...current,\n [column.key]: nextWidth,\n }));\n };\n\n const onUp = () => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n };\n\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n };\n\n const autoFitColumn = (\n event: ReactMouseEvent<HTMLElement>,\n column: DataTableColumn<T>,\n ) => {\n event.preventDefault();\n event.stopPropagation();\n\n const header = event.currentTarget.closest(\"th\");\n const table = event.currentTarget.closest(\"table\");\n if (!header || !table) return;\n\n const columnIndex = Array.from(\n header.parentElement?.children ?? [],\n ).indexOf(header);\n if (columnIndex < 0) return;\n\n const width = measureColumnContentWidth(table, columnIndex, column);\n setColumnWidths((current) => ({\n ...current,\n [column.key]: width,\n }));\n };\n\n const toggleColumnVisibility = (column: DataTableColumn<T>) => {\n if (!isColumnHideable(column)) return;\n\n setHiddenColumns((current) => {\n const hidden = current[column.key] === true;\n if (!hidden && visibleHideableColumnCount <= 1) return current;\n\n const next = { ...current };\n if (hidden) {\n delete next[column.key];\n } else {\n next[column.key] = true;\n }\n\n return pruneHiddenColumns(next, columns);\n });\n };\n\n const showAllColumns = () => setHiddenColumns({});\n\n const openHeaderColumnMenu = (\n event: ReactMouseEvent<HTMLTableCellElement>,\n column: DataTableColumn<T>,\n ) => {\n if (!showColumnVisibilityControl) return;\n event.preventDefault();\n setColumnMenu(menuStateFromPointer(event, column.key));\n };\n\n const openHeaderFilterMenu = (\n event: ReactMouseEvent<HTMLElement>,\n columnKey: string,\n ) => {\n event.preventDefault();\n event.stopPropagation();\n setHeaderFilterMenu(menuStateFromTrigger(event, columnKey));\n };\n\n return (\n <DensityValueProvider density={densityOverride ?? \"comfortable\"}>\n <div\n className={cn(\"flex min-h-0 min-w-0 flex-1 flex-col gap-1\", className)}\n data-density={densityOverride}\n >\n {showFilterBar && (\n <FilterBar\n {...filterBarProps}\n {...(externalSearch\n ? { search: externalSearch }\n : resolvedShowGlobalFilter\n ? {\n search: {\n value: effectiveGlobalFilter,\n onChange: setEffectiveGlobalFilter,\n placeholder: globalFilterPlaceholder,\n },\n }\n : {})}\n {...(barTimeRange ? { timeRange: barTimeRange } : {})}\n trailing={filterBarTrailing}\n filters={barFilters}\n />\n )}\n\n <div className=\"relative flex min-h-0 max-w-full flex-1 flex-col\">\n {loading && error == null ? (\n <LoadingBar data-testid=\"data-table-loading-bar\" className=\"rounded-t-md\" />\n ) : null}\n <div\n // The prop is spelled the React 19 way — RefObject<T | null>, which\n // is what useRef<T | null>(null) returns there — while the package\n // still type-checks against @types/react 18, where RefObject's\n // parameter is compared by variance rather than structurally. The\n // two shapes are the same object; the cast is what says so.\n ref={scrollContainerRef as RefObject<HTMLDivElement> | undefined}\n className={cn(\n \"min-h-0 max-w-full flex-1 overflow-auto overscroll-x-contain rounded-md border border-border bg-background\",\n scrollContainerClassName,\n )}\n aria-busy={(loading && error == null) || undefined}\n >\n <table className=\"w-max min-w-full table-auto text-left text-sm\">\n <colgroup>\n {rowSelection && error == null ? (\n <col className=\"w-10\" />\n ) : null}\n {visibleColumns.map((column) => (\n <col\n key={column.key}\n // An error row spans every column and is the only body content\n // there is, so the column widths have nothing left to size.\n // Keeping them stretches the table far past the viewport and\n // carries the error's own controls — copy, expand — out with\n // it, reachable only by scrolling sideways.\n style={\n error == null\n ? columnStyle(column, columnWidths)\n : undefined\n }\n className={\n column.shrink && !column.grow && error == null\n ? \"w-px\"\n : undefined\n }\n />\n ))}\n </colgroup>\n <thead className=\"sticky top-0 z-10 bg-muted shadow-[0_1px_0_0_var(--tw-shadow-color)] shadow-border\">\n <tr className=\"border-b border-border text-xs text-muted-foreground\">\n {rowSelection && error == null ? (\n <th\n className={cn(\n \"w-10 text-center\",\n DATA_TABLE_HEADER_DENSITY_CLASS,\n )}\n >\n <input\n ref={selectAllRef}\n type=\"checkbox\"\n aria-label=\"Select all visible rows\"\n checked={allVisibleSelected}\n disabled={selectableVisibleRows.length === 0}\n onChange={toggleVisibleSelection}\n className=\"size-3.5 rounded border-border accent-primary\"\n />\n </th>\n ) : null}\n {visibleColumns.map((column) => (\n <th\n key={column.key}\n className={cn(\n \"group/header relative whitespace-nowrap font-medium\",\n DATA_TABLE_HEADER_DENSITY_CLASS,\n alignmentClass(column.align),\n resizableColumns &&\n column.resizable !== false &&\n \"select-none\",\n column.headerClassName,\n )}\n onContextMenu={(event) =>\n openHeaderColumnMenu(event, column)\n }\n >\n <div\n className={cn(\n \"flex min-w-0 items-center gap-1\",\n headerAlignmentClass(column.align),\n resizableColumns &&\n column.resizable !== false &&\n \"pr-2\",\n )}\n >\n <span className=\"min-w-0\">\n {column.sortable === false || pageLocalSort ? (\n <span\n {...(pageLocalSort && column.sortable !== false\n ? {\n title:\n \"Sorting is served by the query while this table is paged by the server\",\n }\n : {})}\n >\n {column.label}\n </span>\n ) : (\n <SortableHeader\n active={sort?.key === column.key}\n {...(sort?.key === column.key\n ? { dir: sort.dir }\n : {})}\n {...(column.align ? { align: column.align } : {})}\n onClick={() => toggle(column.key)}\n >\n {column.label}\n </SortableHeader>\n )}\n </span>\n {showHeaderFilterControls &&\n (headerFilterByColumn.has(column.key) ||\n columnTimeRange?.key === column.key) && (\n <HeaderFilterButton\n column={column}\n active={\n headerFilterByColumn.has(column.key)\n ? isFilterBarFilterActive(\n headerFilterByColumn.get(column.key)!,\n )\n : Boolean(\n columnTimeRange?.range.from ||\n columnTimeRange?.range.to,\n )\n }\n onOpen={(event) =>\n openHeaderFilterMenu(event, column.key)\n }\n />\n )}\n </div>\n {resizableColumns && column.resizable !== false && (\n <span\n role=\"separator\"\n aria-label={`Resize ${labelText(column)} column`}\n aria-orientation=\"vertical\"\n className=\"absolute right-0 top-0 hidden h-full w-3 cursor-col-resize touch-none items-center justify-center border-r border-border/70 bg-gradient-to-l from-border/30 to-transparent transition-colors hover:border-primary hover:from-primary/20 md:flex\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onDoubleClick={(event) =>\n autoFitColumn(event, column)\n }\n onMouseDown={(event) =>\n startColumnResize(event, column)\n }\n >\n <span\n aria-hidden\n className=\"h-4 w-0.5 rounded-full bg-border transition-colors group-hover/header:bg-primary/70\"\n />\n </span>\n )}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {error != null ? (\n <DataTableErrorRow\n colSpan={visibleColumns.length}\n error={error}\n />\n ) : loading && visibleSorted.length === 0 ? (\n <DataTableLoadingRows\n columns={visibleColumns}\n rowCount={loadingRowCount}\n message={loadingMessage}\n selection={!!rowSelection}\n />\n ) : filteredRows.length === 0 ? (\n <tr>\n <td\n colSpan={visibleColumns.length + (rowSelection ? 1 : 0)}\n className=\"px-4 py-10 text-center text-sm text-muted-foreground\"\n >\n {emptyMessage}\n </td>\n </tr>\n ) : (\n rowStream.map((item) => {\n if (item.kind === \"group\") {\n return (\n <DataTableGroupHeaderRow\n key={`group:${item.group.key}`}\n label={item.group.label}\n meta={item.group.meta}\n metaAlign={effectiveGrouping?.metaAlign ?? \"end\"}\n {...(effectiveGrouping?.metaClassName\n ? { metaClassName: effectiveGrouping.metaClassName }\n : {})}\n count={item.group.records.length}\n colSpan={\n visibleColumns.length + (rowSelection ? 1 : 0)\n }\n collapsed={item.group.collapsed}\n onToggleCollapsed={() =>\n setCollapseStateByMode((current) => ({\n ...current,\n [collapseStateKey]: {\n ...current[collapseStateKey],\n groups: {\n ...current[collapseStateKey]?.groups,\n [item.group.key]: !item.group.collapsed,\n },\n },\n }))\n }\n {...(rowSelection\n ? {\n selection: {\n selectableCount: item.group.records.filter(\n (record) =>\n rowSelection.isRowSelectable?.(\n record.row,\n ) ?? true,\n ).length,\n selectedCount: item.group.records.filter(\n (record) => selectedRowIDs.has(record.id),\n ).length,\n onToggle: () =>\n toggleGroupSelection(item.group.records),\n },\n }\n : {})}\n />\n );\n }\n const record = item.record;\n const href = getRowHref?.(record.row);\n const expanded = expandedRows[record.id] ?? false;\n const expandedContent =\n renderExpandedRow?.(record.row, {\n columns: effectiveColumns,\n visibleColumns,\n filterActionsByColumn,\n }) ?? null;\n const expandable = expandedContent !== null;\n const expandsInline = expandable && detailStyle === \"row\";\n const opensDialog = expandable && detailStyle === \"dialog\";\n const rowClickEnabled =\n isRowClickable?.(record.row) ?? !!onRowClick;\n const rowSelectable =\n rowSelection?.isRowSelectable?.(record.row) ?? true;\n const selectionClickEnabled =\n !!rowSelection?.toggleOnRowClick && rowSelectable;\n const clickable =\n !!href ||\n rowClickEnabled ||\n expandable ||\n selectionClickEnabled;\n\n return (\n <Fragment key={record.id}>\n <tr\n className={cn(\n \"relative border-b border-border/60 align-top\",\n clickable && \"cursor-pointer hover:bg-accent/40\",\n selectedRowIDs.has(record.id) && \"bg-accent/50\",\n getRowClassName?.(record.row),\n )}\n onClick={() => {\n if (selectionClickEnabled)\n toggleRowSelection(record);\n if (expandsInline) {\n setExpandedRows((current) => ({\n ...current,\n [record.id]: !current[record.id],\n }));\n }\n if (opensDialog) {\n setDetailRow(record);\n }\n if (rowClickEnabled) {\n onRowClick?.(record.row);\n }\n }}\n >\n {rowSelection ? (\n <td\n className={cn(\n // relative z-10 keeps the checkbox above the row's\n // stretched-link overlay so it stays clickable.\n \"relative z-10 w-10 text-center\",\n DATA_TABLE_CELL_DENSITY_CLASS,\n )}\n onClick={(event) => event.stopPropagation()}\n >\n <input\n type=\"checkbox\"\n aria-label={`Select row ${record.id}`}\n checked={selectedRowIDs.has(record.id)}\n disabled={!rowSelectable}\n onChange={() => toggleRowSelection(record)}\n className=\"size-3.5 rounded border-border accent-primary\"\n />\n </td>\n ) : null}\n {visibleColumns.map((column, index) => {\n const rawValue = resolveColumnValue(\n record.row,\n column,\n );\n let content: ReactNode = column.render\n ? column.render(rawValue, record.row)\n : formatCell(rawValue);\n\n const serverFilterValue = resolveServerFilterValue(\n rawValue,\n record.row,\n column,\n );\n const serverFilterDisplayValue =\n resolveCellFilterDisplayValue(\n rawValue,\n record.row,\n column,\n );\n const hasCellFilterActions =\n !!column.filterKey &&\n !!onCellFilterChange &&\n serverFilterValue !== undefined;\n if (\n column.filterKey &&\n onCellFilterChange &&\n serverFilterValue !== undefined\n ) {\n const filterKey = column.filterKey;\n content = (\n <CellFilterActions\n value={serverFilterValue}\n {...(serverFilterDisplayValue !== undefined\n ? { displayValue: serverFilterDisplayValue }\n : {})}\n mode={\n cellFilters?.[filterKey]?.[\n serverFilterValue\n ]\n }\n onChange={(mode) =>\n onCellFilterChange({\n key: filterKey,\n value: serverFilterValue,\n mode,\n })\n }\n >\n {content}\n </CellFilterActions>\n );\n }\n\n // Tag cells get the + / − filter affordance via\n // context; copy-to-clipboard works without it too.\n if (\n column.kind === \"tags\" &&\n filterActionsByColumn[column.key]\n ) {\n content = (\n <TagActionsProvider\n value={filterActionsByColumn[column.key]!}\n >\n {content}\n </TagActionsProvider>\n );\n }\n\n return (\n <td\n key={column.key}\n className={cn(\n DATA_TABLE_CELL_DENSITY_CLASS,\n alignmentClass(column.align),\n column.cellClassName,\n )}\n style={cellSizingStyle(\n column,\n columnWidths[column.key],\n )}\n >\n <CellContent column={column}>\n {href && index === 0\n ? // One real <a href> per row whose ::after\n // overlay stretches across the whole (relative)\n // row: right/middle-click give native \"open in\n // new tab\", plain left-click routes client-side.\n // The overlay paints over the cell, so a cell\n // with filter actions lifts them above it —\n // otherwise the link swallows the hover that\n // reveals the include/exclude buttons.\n renderLink({\n to: href,\n className:\n \"hover:underline after:absolute after:inset-0 after:content-['']\",\n children: hasCellFilterActions ? (\n <span className=\"relative z-10 inline-flex min-w-0 items-center\">\n {content}\n </span>\n ) : (\n content\n ),\n })\n : content}\n </CellContent>\n </td>\n );\n })}\n </tr>\n {expandsInline && expanded && expandedContent && (\n <tr>\n <td\n colSpan={\n visibleColumns.length + (rowSelection ? 1 : 0)\n }\n className=\"bg-muted/40 p-density-3\"\n >\n <div className=\"rounded-md border border-border bg-background p-density-3\">\n {expandedContent}\n </div>\n </td>\n </tr>\n )}\n </Fragment>\n );\n })\n )}\n {error == null && sentinelActive && (\n <tr ref={revealSentinelRef} aria-hidden>\n <td\n colSpan={visibleColumns.length + (rowSelection ? 1 : 0)}\n className=\"p-density-2 text-center text-xs text-muted-foreground\"\n >\n {sentinelLabel}\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n </div>\n\n {error == null && selectionBar ? (\n <div\n data-testid=\"data-table-selection-actions\"\n className=\"sticky bottom-2 z-10 flex shrink-0 items-center justify-between gap-density-3 rounded-md border border-border bg-card p-density-2 shadow-md\"\n >\n {selectionBar}\n </div>\n ) : null}\n\n {renderedFooter !== null && (\n <div className=\"shrink-0 px-1 text-xs text-muted-foreground\">\n {renderedFooter}\n </div>\n )}\n\n {error == null && pagination ? (\n <DataTablePaginationFooter\n pagination={pagination}\n visibleRowCount={sorted.length}\n infinite={infiniteEnabled}\n />\n ) : null}\n {detailStyle === \"dialog\" && renderExpandedRow && (\n <Modal\n open={detailRow !== null}\n onClose={() => setDetailRow(null)}\n size={detailDialogSize}\n {...(detailRow\n ? {\n title:\n typeof detailDialogTitle === \"function\"\n ? detailDialogTitle(detailRow.row)\n : detailDialogTitle,\n }\n : {})}\n >\n {detailRow\n ? renderExpandedRow(detailRow.row, {\n columns: effectiveColumns,\n visibleColumns,\n filterActionsByColumn,\n })\n : null}\n </Modal>\n )}\n {columnMenu && showTablePreferencesControl && (\n <ColumnVisibilityMenu\n columns={effectiveColumns}\n hiddenColumns={hiddenColumns}\n anchor={columnMenu}\n actions={menuActions ?? []}\n showColumnVisibilityControl={showColumnVisibilityControl}\n showDensityControl={resolvedShowDensityControl}\n showThemeControl={showThemeControl}\n themeMenuValue={themeMenuValue}\n densityOverride={densityOverride}\n visibleHideableColumnCount={visibleHideableColumnCount}\n onToggle={toggleColumnVisibility}\n onShowAll={showAllColumns}\n onDensityChange={setDensityOverride}\n {...(onThemeChange ? { onThemeChange } : {})}\n onClose={() => setColumnMenu(null)}\n />\n )}\n {headerFilterMenu && (\n <HeaderFilterMenu\n filter={headerFilterByColumn.get(headerFilterMenu.columnKey ?? \"\")}\n {...(columnTimeRange && columnTimeRange.key === headerFilterMenu.columnKey\n ? { timeRange: columnTimeRange.range }\n : {})}\n anchor={headerFilterMenu}\n onClose={() => setHeaderFilterMenu(null)}\n />\n )}\n </div>\n </DensityValueProvider>\n );\n}\n\nfunction resolveServerFilterValue<T extends Record<string, unknown>>(\n rawValue: unknown,\n row: T,\n column: DataTableColumn<T>,\n): string | undefined {\n const value = column.serverFilterValue\n ? column.serverFilterValue(rawValue, row)\n : rawValue;\n switch (typeof value) {\n case \"string\":\n return value || undefined;\n case \"number\":\n case \"boolean\":\n return String(value);\n default:\n return undefined;\n }\n}\n\nfunction resolveCellFilterDisplayValue<T extends Record<string, unknown>>(\n rawValue: unknown,\n row: T,\n column: DataTableColumn<T>,\n): string | undefined {\n const value = column.serverFilterLabel\n ? column.serverFilterLabel(rawValue, row)\n : rawValue;\n switch (typeof value) {\n case \"string\":\n return value || undefined;\n case \"number\":\n case \"boolean\":\n return String(value);\n default:\n return undefined;\n }\n}\n\nconst DEFAULT_PAGE_SIZE_OPTIONS = [5, 10, 25, 50, 100, 200];\n\n// useCursorTrail remembers the cursors used to reach each page, which is what\n// makes a cursor walk steppable backwards at all: a cursor points forward only,\n// so \"the previous page\" is a position the client already visited rather than\n// one it can ask the server to compute.\n//\n// The position is derived from the cursor the caller is currently on rather\n// than tracked alongside it, so a filter change — which clears the cursor and\n// invalidates every token minted under the old query — lands back on the first\n// page with no stale entry left for Previous to walk into. The trail behind it\n// is discarded by the next push, which slices at the derived index.\n//\n// A cursor the trail has never seen (one restored from a URL, say) is a page\n// the client cannot number: it counts as one page in, and Previous returns to\n// the start rather than guessing at a position it was not there for.\nfunction useCursorTrail(cursor: DataTableCursorPagination | undefined) {\n const [trail, setTrail] = useState<string[]>([]);\n const current = cursor?.current;\n const index = current == null ? 0 : Math.max(trail.indexOf(current) + 1, 1);\n\n return {\n page: index,\n push: (next: string) => setTrail((previous) => [...previous.slice(0, index), next]),\n previous: () => (index <= 1 ? undefined : trail[index - 2]),\n };\n}\n\n// DataTablePaginationFooter renders a small page-size selector and prev/next\n// controls below the table. Pure presentation: every interaction routes\n// straight to the caller-supplied callbacks so the data layer (which lives in\n// CommandOutput / OperationCommandPage) stays the source of truth for which\n// rows are visible.\nfunction DataTablePaginationFooter({\n pagination,\n visibleRowCount,\n infinite = false,\n}: {\n pagination: DataTablePagination;\n visibleRowCount: number;\n /** Infinite scroll owns the paging; see `steppable` and `rangeStart` below. */\n infinite?: boolean;\n}) {\n const { page, pageSize, total, totalRelation, cursor, onPageChange, onPageSizeChange } =\n pagination;\n const options = Array.from(\n new Set([\n ...(pagination.pageSizeOptions ?? DEFAULT_PAGE_SIZE_OPTIONS),\n pageSize,\n ]),\n ).sort((a, b) => a - b);\n const trail = useCursorTrail(cursor);\n const safePage = cursor ? trail.page : Math.max(0, page);\n const approximate = totalRelation === \"gte\";\n // A page count derived from a lower bound is a lower bound too, and offering\n // it as \"of N\" invites a jump to a page that may not exist. A cursor walk has\n // no page numbers to jump between at all.\n const totalPages =\n total != null && pageSize > 0 && !approximate && !cursor\n ? Math.max(1, Math.ceil(total / pageSize))\n : undefined;\n const atFirst = safePage === 0;\n const atLast = cursor\n ? cursor.next == null\n : pagination.hasMore != null\n ? !pagination.hasMore\n : totalPages != null\n ? safePage >= totalPages - 1\n : visibleRowCount < pageSize;\n const hasVisibleRows = visibleRowCount > 0;\n // Under infinite scroll every page fetched so far is stacked on screen, so the\n // run starts at the first row rather than at the offset the most recent\n // request happened to use — quoting that offset would report a window the\n // reader is not looking at.\n const rangeStart =\n total === 0 || !hasVisibleRows ? 0 : infinite ? 1 : safePage * pageSize + 1;\n const rangeEnd =\n total != null && hasVisibleRows\n ? Math.min(\n approximate ? Infinity : total,\n rangeStart + Math.max(visibleRowCount - 1, 0),\n )\n : visibleRowCount;\n const rangeLabel =\n total != null\n ? `${rangeStart}-${rangeEnd} of ${approximate ? `~${total}+` : total}`\n : `${visibleRowCount} row${visibleRowCount === 1 ? \"\" : \"s\"}`;\n\n // A surface with neither a page callback nor a cursor has no second page to\n // offer. It still reports what it is showing and still resizes — a count is a\n // fact about the result, not a paging control. Infinite scroll lands in the\n // same place from the other direction: the pages are all still on screen, and\n // a position nobody can step back to is not worth a button.\n const steppable = !infinite && (cursor != null || onPageChange != null);\n\n const goPrevious = () => {\n if (!cursor) {\n onPageChange?.(Math.max(0, safePage - 1));\n return;\n }\n cursor.onCursorChange(trail.previous());\n };\n const goNext = () => {\n if (!cursor) {\n onPageChange?.(safePage + 1);\n return;\n }\n if (cursor.next == null) return;\n trail.push(cursor.next);\n cursor.onCursorChange(cursor.next);\n };\n\n return (\n <div className=\"flex min-h-9 shrink-0 flex-row items-stretch gap-3 border-t border-border/70 px-1 pt-2 text-xs text-muted-foreground sm:flex-row sm:flex-wrap sm:items-center sm:justify-between\">\n <div aria-live=\"polite\">{rangeLabel}</div>\n <div className=\"flex flex-wrap items-center gap-2 sm:gap-3\">\n <label className=\"flex items-center gap-1.5\">\n <span>Rows per page</span>\n <select\n className=\"h-7 rounded-md border border-border bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n value={pageSize}\n onChange={(event) => onPageSizeChange(Number(event.target.value))}\n >\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n </label>\n {steppable ? (\n <>\n <span className=\"min-w-20 text-center\">\n Page {safePage + 1}\n {totalPages != null ? ` of ${totalPages}` : \"\"}\n </span>\n <button\n type=\"button\"\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border bg-background text-foreground hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label=\"Previous page\"\n title=\"Previous page\"\n disabled={atFirst}\n onClick={goPrevious}\n >\n <Icon icon={UiArrowLeft} />\n </button>\n <button\n type=\"button\"\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border bg-background text-foreground hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label=\"Next page\"\n title=\"Next page\"\n disabled={atLast}\n onClick={goNext}\n >\n <Icon icon={UiArrowRight} />\n </button>\n </>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction DataTableGroupHeaderRow({\n label,\n meta,\n metaAlign,\n metaClassName,\n count,\n colSpan,\n collapsed,\n onToggleCollapsed,\n selection,\n}: {\n label: ReactNode;\n meta: ReactNode;\n metaAlign: DataTableGroupMetaAlign;\n metaClassName?: string;\n count: number;\n colSpan: number;\n collapsed: boolean;\n onToggleCollapsed: () => void;\n selection?: {\n selectableCount: number;\n selectedCount: number;\n onToggle: () => void;\n };\n}) {\n const allSelected =\n !!selection &&\n selection.selectableCount > 0 &&\n selection.selectedCount === selection.selectableCount;\n const someSelected =\n !!selection && selection.selectedCount > 0 && !allSelected;\n const checkboxRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (checkboxRef.current) checkboxRef.current.indeterminate = someSelected;\n }, [someSelected]);\n\n return (\n <tr className=\"border-b border-border/60 bg-muted/40\">\n <td colSpan={colSpan} className=\"px-density-2 py-density-1\">\n <div className=\"flex items-center gap-2\">\n {selection ? (\n <input\n ref={checkboxRef}\n type=\"checkbox\"\n aria-label={`Select group ${typeof label === \"string\" ? label : count}`}\n checked={allSelected}\n disabled={selection.selectableCount === 0}\n onChange={selection.onToggle}\n className=\"size-3.5 rounded border-border accent-primary\"\n />\n ) : null}\n <button\n type=\"button\"\n aria-expanded={!collapsed}\n onClick={onToggleCollapsed}\n className={cn(\n \"flex min-w-0 items-center gap-1.5 text-left text-sm font-semibold text-foreground hover:text-primary\",\n // `flex-1` is what pushes the meta to the trailing edge. Dropping\n // it lets the meta sit right after the count instead.\n metaAlign === \"end\" && \"flex-1\",\n )}\n >\n <Icon\n icon={collapsed ? UiChevronRight : UiChevronDown}\n className=\"shrink-0 text-muted-foreground\"\n />\n <span className=\"truncate\">{label}</span>\n <span className=\"shrink-0 font-normal text-muted-foreground\">\n {count}\n </span>\n </button>\n {meta ? (\n <div\n className={cn(\n \"shrink-0 text-sm text-muted-foreground\",\n metaClassName,\n )}\n >\n {meta}\n </div>\n ) : null}\n </div>\n </td>\n </tr>\n );\n}\n\nfunction DataTableLoadingRows<T extends Record<string, unknown>>({\n columns,\n rowCount,\n message,\n selection,\n}: {\n columns: DataTableColumn<T>[];\n rowCount: number;\n message: ReactNode;\n selection: boolean;\n}) {\n const safeRowCount = Math.max(1, rowCount);\n const safeColumnCount = Math.max(1, columns.length + (selection ? 1 : 0));\n\n return (\n <>\n <tr className=\"border-b border-border/60 bg-muted/20\">\n <td\n colSpan={safeColumnCount}\n className={cn(DATA_TABLE_CELL_DENSITY_CLASS, \"p-0\")}\n >\n <div className=\"h-0.5 w-full overflow-hidden bg-muted\">\n <div className=\"h-full w-1/2 animate-pulse rounded-full bg-primary/70\" />\n </div>\n <div className=\"flex items-center gap-2 px-3 py-2 text-xs text-muted-foreground\">\n <span\n aria-hidden\n className=\"h-3 w-3 animate-spin rounded-full border-2 border-primary/30 border-t-primary\"\n />\n <span>{message}</span>\n </div>\n </td>\n </tr>\n {Array.from({ length: safeRowCount }).map((_, rowIndex) => (\n <tr key={rowIndex} className=\"border-b border-border/60\">\n {selection ? (\n <td className={cn(\"w-10\", DATA_TABLE_CELL_DENSITY_CLASS)}>\n <span className=\"mx-auto block size-3.5 animate-pulse rounded bg-muted\" />\n </td>\n ) : null}\n {columns.map((column, columnIndex) => (\n <td\n key={column.key}\n className={cn(\n DATA_TABLE_CELL_DENSITY_CLASS,\n alignmentClass(column.align),\n column.cellClassName,\n )}\n style={cellSizingStyle(column, undefined)}\n >\n <CellContent column={column}>\n <span\n aria-hidden\n className={cn(\n \"block h-3 animate-pulse rounded-full bg-muted\",\n loadingSkeletonWidth(columnIndex),\n )}\n />\n </CellContent>\n </td>\n ))}\n </tr>\n ))}\n </>\n );\n}\n\nfunction DataTableErrorRow({\n colSpan,\n error,\n}: {\n colSpan: number;\n error: ReactNode;\n}) {\n return (\n <tr className=\"border-b border-border/60\">\n <td\n colSpan={Math.max(1, colSpan)}\n className={cn(DATA_TABLE_CELL_DENSITY_CLASS, \"p-density-3\")}\n >\n {/*\n w-0 min-w-full keeps the error out of the table's width calculation:\n a cell sizes to its content, so an error carrying a long unbroken\n line — a response body, a SQL statement — would widen the table\n itself and push its own copy and expand controls off-screen.\n */}\n <div role=\"alert\" className=\"w-0 min-w-full overflow-hidden\">\n {error}\n </div>\n </td>\n </tr>\n );\n}\n\nfunction HeaderFilterButton<T extends Record<string, unknown>>({\n column,\n active,\n onOpen,\n}: {\n column: DataTableColumn<T>;\n active: boolean;\n onOpen: (event: ReactMouseEvent<HTMLButtonElement>) => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={`Open ${labelText(column)} column filter`}\n aria-haspopup=\"dialog\"\n aria-pressed={active}\n className={cn(\n \"inline-flex h-5 w-5 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active && \"bg-accent text-foreground\",\n )}\n onClick={onOpen}\n >\n <span\n data-filter-icon-state={active ? \"filled\" : \"outline\"}\n className=\"inline-flex\"\n >\n <Icon icon={active ? UiFilterFilled : UiFilter} className=\"text-xs\" />\n </span>\n </button>\n );\n}\n\nfunction HeaderFilterMenu({\n filter,\n timeRange,\n anchor,\n onClose,\n}: {\n filter: FilterBarFilter | undefined;\n timeRange?: FilterBarRangeProps;\n anchor: ColumnMenuState;\n onClose: () => void;\n}) {\n if (!filter && !timeRange) return null;\n\n const label = filter?.label ?? \"Time range\";\n const timeRangeActive = Boolean(timeRange?.from || timeRange?.to);\n\n return (\n <div\n role=\"dialog\"\n aria-label={`${label} column filter`}\n className=\"fixed z-50 max-h-[calc(100vh-1rem)] max-w-[calc(100vw-1rem)] overflow-auto rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-lg shadow-black/5\"\n style={{ left: anchor.x, top: anchor.y }}\n onClick={(event) => event.stopPropagation()}\n onContextMenu={(event) => event.preventDefault()}\n >\n <div className=\"mb-2 flex items-center justify-between gap-3\">\n <div className=\"truncate text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <div className=\"flex items-center gap-1\">\n {filter && (\n <button\n type=\"button\"\n className=\"rounded px-1.5 py-0.5 text-xs text-primary transition-colors hover:bg-accent focus:bg-accent focus:outline-none disabled:text-muted-foreground\"\n onClick={() => clearFilterBarFilter(filter)}\n disabled={!isFilterBarFilterActive(filter)}\n >\n Clear all\n </button>\n )}\n {timeRange && (\n <button\n type=\"button\"\n className=\"rounded px-1.5 py-0.5 text-xs text-primary transition-colors hover:bg-accent focus:bg-accent focus:outline-none disabled:text-muted-foreground\"\n onClick={() => timeRange.onApply(\"\", \"\")}\n disabled={!timeRangeActive}\n >\n Clear all\n </button>\n )}\n <button\n type=\"button\"\n aria-label=\"Close column filter\"\n title=\"Close\"\n className=\"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\"\n onClick={onClose}\n >\n <Icon icon={UiClose} className=\"text-sm\" />\n </button>\n </div>\n </div>\n <div className=\"flex flex-col gap-2\">\n {filter && <FilterBarFilterPanel filter={filter} chrome=\"embedded\" />}\n {timeRange && (\n <FilterBarRangePanel kind=\"time\" label=\"Time range\" {...timeRange} />\n )}\n </div>\n </div>\n );\n}\n\nfunction ColumnVisibilityTrigger({\n onOpen,\n}: {\n onOpen: (event: ReactMouseEvent<HTMLButtonElement>) => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label=\"Open column menu\"\n aria-haspopup=\"menu\"\n className=\"inline-flex h-8 w-8 items-center justify-center rounded-md border border-input bg-background text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n onClick={(event) => {\n event.stopPropagation();\n onOpen(event);\n }}\n >\n <Icon icon={UiEllipsis} className=\"text-sm\" />\n </button>\n );\n}\n\nfunction ColumnVisibilityMenu<T extends Record<string, unknown>>({\n columns,\n hiddenColumns,\n anchor,\n actions,\n showColumnVisibilityControl,\n showDensityControl,\n showThemeControl,\n themeMenuValue,\n densityOverride,\n visibleHideableColumnCount,\n onToggle,\n onShowAll,\n onDensityChange,\n onThemeChange,\n onClose,\n}: {\n columns: DataTableColumn<T>[];\n hiddenColumns: Record<string, boolean>;\n anchor: ColumnMenuState;\n actions: DataTableMenuAction[];\n showColumnVisibilityControl: boolean;\n showDensityControl: boolean;\n showThemeControl: boolean;\n themeMenuValue: Theme | undefined;\n densityOverride: Density | undefined;\n visibleHideableColumnCount: number;\n onToggle: (column: DataTableColumn<T>) => void;\n onShowAll: () => void;\n onDensityChange: (density: Density | undefined) => void;\n onThemeChange?: (theme: Theme) => void;\n onClose: () => void;\n}) {\n const activeColumn = anchor.columnKey\n ? columns.find((column) => column.key === anchor.columnKey)\n : undefined;\n const canHideActiveColumn =\n activeColumn &&\n isColumnHideable(activeColumn) &&\n visibleHideableColumnCount > 1;\n const hasActions = actions.length > 0;\n\n return (\n <div\n role=\"menu\"\n aria-label=\"Column menu\"\n className=\"fixed z-50 max-h-[calc(100vh-1rem)] min-w-[16rem] max-w-[calc(100vw-1rem)] overflow-auto rounded-md border border-border bg-popover p-1.5 text-popover-foreground shadow-lg shadow-black/5\"\n style={{ left: anchor.x, top: anchor.y }}\n onClick={(event) => event.stopPropagation()}\n onContextMenu={(event) => event.preventDefault()}\n >\n {showColumnVisibilityControl && (\n <>\n <div className=\"flex items-center justify-between gap-3 px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n <span>Columns</span>\n <button\n type=\"button\"\n className=\"rounded px-1.5 py-0.5 text-xs text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\"\n onClick={onShowAll}\n >\n Show all\n </button>\n </div>\n\n {activeColumn && (\n <>\n <button\n type=\"button\"\n role=\"menuitem\"\n disabled={!canHideActiveColumn}\n className={cn(\n \"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\",\n !canHideActiveColumn && \"cursor-not-allowed opacity-50\",\n )}\n onClick={() => {\n if (!canHideActiveColumn) return;\n onToggle(activeColumn);\n onClose();\n }}\n >\n <Icon\n icon={UiEyeClosed}\n className=\"text-sm text-muted-foreground\"\n />\n <span>Hide {labelText(activeColumn)}</span>\n </button>\n <div className=\"my-1 h-px bg-border\" />\n </>\n )}\n\n <div className=\"max-h-72 overflow-auto\">\n {columns.map((column) => {\n const hideable = isColumnHideable(column);\n const visible = hiddenColumns[column.key] !== true;\n const disabled =\n !hideable || (visible && visibleHideableColumnCount <= 1);\n return (\n <label\n key={column.key}\n className={cn(\n \"flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-accent hover:text-accent-foreground\",\n disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n <input\n type=\"checkbox\"\n className=\"h-4 w-4 rounded border-border\"\n checked={visible}\n disabled={disabled}\n onChange={() => onToggle(column)}\n />\n <span className=\"truncate\">{labelText(column)}</span>\n </label>\n );\n })}\n </div>\n </>\n )}\n\n {showDensityControl && (\n <DensityMenuSection\n densityOverride={densityOverride}\n separated={showColumnVisibilityControl}\n onDensityChange={onDensityChange}\n />\n )}\n\n {hasActions && (\n <MenuActionSection\n actions={actions}\n separated={showColumnVisibilityControl || showDensityControl}\n onClose={onClose}\n />\n )}\n\n {showThemeControl && onThemeChange && (\n <ThemeMenuSection\n value={themeMenuValue ?? \"system\"}\n separated={\n showColumnVisibilityControl || showDensityControl || hasActions\n }\n onChange={onThemeChange}\n />\n )}\n </div>\n );\n}\n\n// Groups menu actions by their `section` heading, preserving the order each\n// section first appears. Actions without a section fall under \"Download\" so the\n// existing download menu is unchanged.\nfunction groupMenuActions(\n actions: DataTableMenuAction[],\n): { section: string; actions: DataTableMenuAction[] }[] {\n const groups: { section: string; actions: DataTableMenuAction[] }[] = [];\n for (const action of actions) {\n const section = action.section ?? \"Download\";\n let group = groups.find((g) => g.section === section);\n if (!group) {\n group = { section, actions: [] };\n groups.push(group);\n }\n group.actions.push(action);\n }\n return groups;\n}\n\nfunction MenuActionSection({\n actions,\n separated,\n onClose,\n}: {\n actions: DataTableMenuAction[];\n separated: boolean;\n onClose: () => void;\n}) {\n const groups = groupMenuActions(actions);\n // Which submenu is open, if any. One at a time: hovering a sibling takes the\n // flyout with it, which is what every menu does and what stops two levels\n // from being open over each other.\n const [openSubmenu, setOpenSubmenu] = useState<{\n id: string;\n x: number;\n y: number;\n } | null>(null);\n\n return (\n <>\n {groups.map((group, index) => (\n <div\n key={group.section}\n className={cn(\n (separated || index > 0) && \"mt-1 border-t border-border pt-1\",\n )}\n >\n {group.section && (\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {group.section}\n </div>\n )}\n {group.actions.map((action) => (\n <MenuActionItem\n key={action.id}\n action={action}\n submenu={openSubmenu?.id === action.id ? openSubmenu : null}\n onOpenSubmenu={setOpenSubmenu}\n onClose={onClose}\n />\n ))}\n </div>\n ))}\n </>\n );\n}\n\nfunction MenuActionItem({\n action,\n submenu,\n onOpenSubmenu,\n onClose,\n}: {\n action: DataTableMenuAction;\n submenu: { id: string; x: number; y: number } | null;\n onOpenSubmenu: (state: { id: string; x: number; y: number } | null) => void;\n onClose: () => void;\n}) {\n const hasDescription = Boolean(action.description);\n const children = action.children ?? [];\n const isSubmenu = children.length > 0;\n\n const openFrom = (element: HTMLElement) => {\n const rect = element.getBoundingClientRect();\n // Flip to the left when the flyout would run off the right edge, using the\n // same minimum width the panel below is given.\n const width = 224;\n const x =\n rect.right + width > window.innerWidth ? rect.left - width : rect.right;\n onOpenSubmenu({ id: action.id, x, y: rect.top });\n };\n\n return (\n <>\n <button\n type=\"button\"\n role=\"menuitem\"\n aria-haspopup={isSubmenu ? \"menu\" : undefined}\n aria-expanded={isSubmenu ? submenu != null : undefined}\n disabled={action.disabled}\n className={cn(\n \"flex w-full gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\",\n hasDescription ? \"items-start\" : \"items-center\",\n action.disabled && \"cursor-not-allowed opacity-50\",\n submenu && \"bg-accent text-accent-foreground\",\n )}\n onClick={(event) => {\n if (action.disabled) return;\n // Click, never hover: a flyout that opens on the way past is one the\n // user did not ask for, and it covers the rows they were reaching for.\n if (isSubmenu) {\n if (submenu) onOpenSubmenu(null);\n else openFrom(event.currentTarget);\n return;\n }\n action.onSelect();\n onClose();\n }}\n >\n {action.icon && (\n <Icon\n icon={action.icon}\n className={cn(\n \"shrink-0 text-sm\",\n hasDescription && \"mt-0.5\",\n action.iconClassName ?? \"text-muted-foreground\",\n )}\n />\n )}\n <span className=\"min-w-0 flex-1\">\n <span className={cn(hasDescription && \"font-medium\")}>\n {action.label}\n </span>\n {action.description && (\n <span className=\"mt-0.5 block text-xs text-muted-foreground\">\n {action.description}\n </span>\n )}\n </span>\n {isSubmenu && (\n <Icon\n icon={UiChevronRight}\n className=\"shrink-0 text-sm text-muted-foreground\"\n />\n )}\n </button>\n\n {isSubmenu && submenu && (\n <div\n role=\"menu\"\n aria-label={typeof action.label === \"string\" ? action.label : \"Submenu\"}\n className=\"fixed z-50 max-h-[calc(100vh-1rem)] min-w-[14rem] max-w-[calc(100vw-1rem)] overflow-auto rounded-md border border-border bg-popover p-1.5 text-popover-foreground shadow-lg shadow-black/5\"\n style={{ left: submenu.x, top: submenu.y }}\n >\n {children.map((child) => (\n <MenuActionItem\n key={child.id}\n action={child}\n submenu={null}\n onOpenSubmenu={onOpenSubmenu}\n onClose={onClose}\n />\n ))}\n </div>\n )}\n </>\n );\n}\n\nfunction DensityMenuSection({\n densityOverride,\n separated,\n onDensityChange,\n}: {\n densityOverride: Density | undefined;\n separated: boolean;\n onDensityChange: (density: Density | undefined) => void;\n}) {\n const current = densityOverride ?? \"inherit\";\n\n return (\n <div className={cn(separated && \"mt-1 border-t border-border pt-1\")}>\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n Density\n </div>\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={current === \"inherit\"}\n className={densityMenuItemClassName(current === \"inherit\")}\n onClick={() => onDensityChange(undefined)}\n >\n <Icon\n icon={UiResizeVertical}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 flex-1 truncate\">Use page density</span>\n {current === \"inherit\" ? (\n <Icon icon={UiCheck} className=\"text-sm text-foreground\" />\n ) : (\n <span className=\"inline-block h-4 w-4\" aria-hidden />\n )}\n </button>\n {DENSITY_OPTIONS.map((option) => {\n const active = current === option.value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n className={densityMenuItemClassName(active)}\n onClick={() => onDensityChange(option.value)}\n >\n <Icon\n icon={option.icon}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 flex-1 truncate\">{option.label}</span>\n {active ? (\n <Icon icon={UiCheck} className=\"text-sm text-foreground\" />\n ) : (\n <span className=\"inline-block h-4 w-4\" aria-hidden />\n )}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction densityMenuItemClassName(active: boolean) {\n return cn(\n \"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\",\n active && \"text-foreground\",\n );\n}\n\nconst THEME_MENU_OPTIONS: Array<{\n value: Theme;\n icon: StaticIconComponent;\n label: string;\n}> = [\n { value: \"system\", icon: UiDesktop, label: \"Use system theme\" },\n { value: \"light\", icon: UiSun, label: \"Light\" },\n { value: \"dark\", icon: UiMoon, label: \"Dark\" },\n];\n\nfunction ThemeMenuSection({\n value,\n separated,\n onChange,\n}: {\n value: Theme;\n separated: boolean;\n onChange: (theme: Theme) => void;\n}) {\n return (\n <div className={cn(separated && \"mt-1 border-t border-border pt-1\")}>\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n Theme\n </div>\n {THEME_MENU_OPTIONS.map((option) => {\n const active = value === option.value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n className={densityMenuItemClassName(active)}\n onClick={() => onChange(option.value)}\n >\n <Icon\n icon={option.icon}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 flex-1 truncate\">{option.label}</span>\n {active ? (\n <Icon icon={UiCheck} className=\"text-sm text-foreground\" />\n ) : (\n <span className=\"inline-block h-4 w-4\" aria-hidden />\n )}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction CellContent<T extends Record<string, unknown>>({\n column,\n children,\n}: {\n column: DataTableColumn<T>;\n children: ReactNode;\n}) {\n return (\n <div\n className={cn(cellContentClassName(column), alignmentClass(column.align))}\n >\n {children}\n </div>\n );\n}\n\nfunction getSortValue<T extends Record<string, unknown>>(\n row: T,\n column: DataTableColumn<T>,\n) {\n const rawValue = resolveColumnValue(row, column);\n return column.sortValue ? column.sortValue(rawValue, row) : rawValue;\n}\n\nfunction getFilterNumbers<T extends Record<string, unknown>>(\n row: T,\n column: DataTableColumn<T>,\n) {\n return normalizeNumbers(getFilterCandidate(row, column));\n}\n\nfunction normalizeNumbers(value: FilterValue | unknown): number[] {\n if (Array.isArray(value)) {\n return value.flatMap((item) => normalizeNumbers(item));\n }\n\n const parsed = parseNumberInput(value);\n return parsed == null ? [] : [parsed];\n}\n\nfunction updateFilterValue(\n state: Record<string, string>,\n key: string,\n nextValue: string,\n) {\n const next = { ...state };\n\n if (nextValue.trim()) {\n next[key] = nextValue;\n } else {\n delete next[key];\n }\n\n return next;\n}\n\nfunction updateFilterRecord(\n state: Record<string, Record<string, FilterBarMultiFilterMode>>,\n key: string,\n nextValue: Record<string, FilterBarMultiFilterMode>,\n) {\n const next = { ...state };\n\n if (Object.keys(nextValue).length > 0) {\n next[key] = nextValue;\n } else {\n delete next[key];\n }\n\n return next;\n}\n\nfunction updateNumberFilterValue(\n state: Record<string, FilterBarNumberValue>,\n key: string,\n nextValue: FilterBarNumberValue,\n) {\n const next = { ...state };\n const hasMin = String(nextValue.min ?? \"\").trim() !== \"\";\n const hasMax = String(nextValue.max ?? \"\").trim() !== \"\";\n\n if (hasMin || hasMax) {\n next[key] = nextValue;\n } else {\n delete next[key];\n }\n\n return next;\n}\n\nfunction pruneTextFilterState(\n state: Record<string, string>,\n filters: GeneratedFilter<any>[],\n) {\n return pruneFilterState(\n state,\n filters,\n \"text\",\n (value) => !String(value ?? \"\").trim(),\n );\n}\n\nfunction pruneMultiFilterState(\n state: Record<string, Record<string, FilterBarMultiFilterMode>>,\n filters: GeneratedFilter<any>[],\n) {\n // multi and nested-multi share the same state slot; allow either kind to\n // keep the entry alive.\n const allowed = new Set(\n filters\n .filter(\n (filter) => filter.kind === \"multi\" || filter.kind === \"nested-multi\",\n )\n .map((filter) => filter.column.key),\n );\n return Object.fromEntries(\n Object.entries(state).filter(\n ([key, value]) => allowed.has(key) && Object.keys(value).length > 0,\n ),\n );\n}\n\nfunction pruneNumberFilterState(\n state: Record<string, FilterBarNumberValue>,\n filters: GeneratedFilter<any>[],\n) {\n return pruneFilterState(\n state,\n filters,\n \"number\",\n (value) =>\n !String(value.min ?? \"\").trim() && !String(value.max ?? \"\").trim(),\n );\n}\n\nfunction pruneFilterState<T>(\n state: Record<string, T>,\n filters: GeneratedFilter<any>[],\n kind: GeneratedFilter<any>[\"kind\"],\n isEmpty: (value: T) => boolean,\n) {\n const allowed = new Set(\n filters\n .filter((filter) => filter.kind === kind)\n .map((filter) => filter.column.key),\n );\n return Object.fromEntries(\n Object.entries(state).filter(\n ([key, value]) => allowed.has(key) && !isEmpty(value),\n ),\n ) as Record<string, T>;\n}\n\nfunction formatCell(value: unknown): ReactNode {\n if (value == null || value === \"\") {\n return <span className=\"text-muted-foreground\">—</span>;\n }\n if (typeof value === \"boolean\") return value ? \"True\" : \"False\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n// Groups flat key=value tokens by key for the nested-multi tag filter.\n// Tokens without a separator land in a synthetic \"\" group rendered as\n// \"Other\" by the filter UI.\nfunction groupTagOptions(\n options: MultiSelectOption[],\n separator: string,\n): Array<{ groupKey: string; label?: string; options: MultiSelectOption[] }> {\n const byKey = new Map<string, MultiSelectOption[]>();\n for (const option of options) {\n const { key } = splitTagToken(option.value, separator);\n const list = byKey.get(key) ?? [];\n list.push(option);\n byKey.set(key, list);\n }\n return Array.from(byKey.entries())\n .sort(([a], [b]) => {\n // Bare-tag bucket sinks to the bottom; otherwise alphabetical.\n if (a === \"\" && b !== \"\") return 1;\n if (b === \"\" && a !== \"\") return -1;\n return a.localeCompare(b);\n })\n .map(([groupKey, groupOptions]) => ({\n groupKey,\n label: groupKey === \"\" ? \"Other\" : groupKey,\n options: groupOptions,\n }));\n}\n\nfunction applyKindDefaults<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n timestampFormat: TimestampFormat | undefined,\n): DataTableColumn<T> {\n if (!column.kind) return column;\n\n if (column.kind === \"timestamp\") {\n const format = timestampFormat ?? \"iso\";\n return {\n ...column,\n render:\n column.render ??\n ((value) => (\n <Timestamp\n value={value}\n format={format}\n showTitleOnHover={column.timestamp?.alwaysShowFullOnHover !== false}\n />\n )),\n sortValue:\n column.sortValue ??\n ((value) => parseTimestamp(value)?.getTime() ?? null),\n filterValue:\n column.filterValue ??\n ((value) => {\n const parsed = parseTimestamp(value);\n return parsed ? parsed.toISOString() : \"\";\n }),\n };\n }\n\n if (column.kind === \"tags\") {\n const opts = column.tags;\n const separator = opts?.separator ?? \"=\";\n return {\n ...column,\n render:\n column.render ??\n ((value) => (\n <TagList\n tags={normalizeTags(value as TagsValue, separator)}\n maxVisible={opts?.maxVisible ?? 3}\n />\n )),\n filterValue:\n column.filterValue ??\n ((value) => tagFilterTokens(value as TagsValue, separator)),\n sortValue:\n column.sortValue ??\n ((value) => tagFilterTokens(value as TagsValue, separator).length),\n };\n }\n\n if (column.kind === \"status\") {\n const opts = column.status;\n const map = opts?.map ?? ((raw) => normalizeStatus(raw));\n return {\n ...column,\n render:\n column.render ??\n ((value, row) => {\n const status = map(value, row);\n if (!status) return <span className=\"text-muted-foreground\">—</span>;\n const label = opts?.showLabel\n ? typeof value === \"string\"\n ? value\n : status\n : undefined;\n const title =\n opts?.title?.(value, row) ??\n (typeof value === \"string\" ? value : undefined);\n return (\n <StatusDot\n status={status}\n {...(label ? { label } : {})}\n {...(title ? { title } : {})}\n />\n );\n }),\n filterValue:\n column.filterValue ??\n ((value, row) => {\n const status = map(value, row);\n return status ?? \"\";\n }),\n sortValue: column.sortValue ?? ((value, row) => map(value, row) ?? \"\"),\n };\n }\n\n return column;\n}\n\nfunction labelText<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n) {\n if (typeof column.label === \"string\") return column.label;\n return prettifyKey(column.key.split(\".\").at(-1) ?? column.key);\n}\n\nfunction isColumnHideable<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n) {\n return column.hideable !== false;\n}\n\nfunction menuStateFromPointer(\n event: ReactMouseEvent<HTMLElement>,\n columnKey?: string,\n): ColumnMenuState {\n const padding = 8;\n const width = 256;\n const height = 320;\n const viewportWidth =\n typeof window === \"undefined\" ? event.clientX + width : window.innerWidth;\n const viewportHeight =\n typeof window === \"undefined\" ? event.clientY + height : window.innerHeight;\n\n const position = {\n x: Math.max(\n padding,\n Math.min(event.clientX, viewportWidth - width - padding),\n ),\n y: Math.max(\n padding,\n Math.min(event.clientY, viewportHeight - height - padding),\n ),\n };\n return columnKey ? { ...position, columnKey } : position;\n}\n\nfunction menuStateFromTrigger(\n event: ReactMouseEvent<HTMLElement>,\n columnKey?: string,\n): ColumnMenuState {\n const rect = event.currentTarget.getBoundingClientRect();\n const padding = 8;\n const width = 256;\n const height = 320;\n const viewportWidth =\n typeof window === \"undefined\" ? rect.right + width : window.innerWidth;\n const viewportHeight =\n typeof window === \"undefined\" ? rect.bottom + height : window.innerHeight;\n\n const position = {\n x: Math.max(\n padding,\n Math.min(rect.right - width, viewportWidth - width - padding),\n ),\n y: Math.max(\n padding,\n Math.min(rect.bottom + 6, viewportHeight - height - padding),\n ),\n };\n return columnKey ? { ...position, columnKey } : position;\n}\n\nfunction columnStyle<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n widths: Record<string, number>,\n): CSSProperties | undefined {\n const width = widths[column.key];\n return width ? { width: `${width}px` } : undefined;\n}\n\nfunction measureColumnContentWidth<T extends Record<string, unknown>>(\n table: HTMLTableElement,\n columnIndex: number,\n column: DataTableColumn<T>,\n) {\n const cells = Array.from(table.querySelectorAll(\"th, td\")).filter(\n (cell): cell is HTMLTableCellElement =>\n cell instanceof HTMLTableCellElement &&\n cell.cellIndex === columnIndex &&\n cell.colSpan === 1,\n );\n\n const measured = cells.reduce((current, cell) => {\n const horizontalPadding = getHorizontalPadding(cell);\n const contentWidths = Array.from(cell.children).map((child) =>\n child instanceof HTMLElement ? child.scrollWidth + horizontalPadding : 0,\n );\n return Math.max(current, cell.scrollWidth, ...contentWidths);\n }, 0);\n\n return clampColumnWidth(column, measured || defaultColumnWidth(column));\n}\n\nfunction getHorizontalPadding(element: HTMLElement) {\n if (typeof window === \"undefined\") return 0;\n const styles = window.getComputedStyle(element);\n return (\n parseCssPixelValue(styles.paddingLeft) +\n parseCssPixelValue(styles.paddingRight)\n );\n}\n\nfunction parseCssPixelValue(value: string) {\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction readStoredColumnWidths<T extends Record<string, unknown>>(\n storageKey: string,\n columns: DataTableColumn<T>[],\n): Record<string, number> {\n if (typeof window === \"undefined\") return {};\n\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (!raw) return {};\n\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed))\n return {};\n\n return pruneColumnWidths(parsed as Record<string, unknown>, columns);\n } catch {\n return {};\n }\n}\n\nfunction writeStoredColumnWidths(\n storageKey: string,\n widths: Record<string, number>,\n) {\n if (typeof window === \"undefined\") return;\n\n try {\n if (Object.keys(widths).length === 0) {\n window.localStorage.removeItem(storageKey);\n } else {\n window.localStorage.setItem(storageKey, JSON.stringify(widths));\n }\n } catch {}\n}\n\nfunction readStoredHiddenColumns<T extends Record<string, unknown>>(\n storageKey: string,\n columns: DataTableColumn<T>[],\n): Record<string, boolean> {\n if (typeof window === \"undefined\") return {};\n\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (!raw) return {};\n\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed))\n return {};\n\n return pruneHiddenColumns(parsed as Record<string, unknown>, columns);\n } catch {\n return {};\n }\n}\n\nfunction writeStoredHiddenColumns(\n storageKey: string,\n hiddenColumns: Record<string, boolean>,\n) {\n if (typeof window === \"undefined\") return;\n\n try {\n if (Object.keys(hiddenColumns).length === 0) {\n window.localStorage.removeItem(storageKey);\n } else {\n window.localStorage.setItem(storageKey, JSON.stringify(hiddenColumns));\n }\n } catch {}\n}\n\nfunction readStoredDensityOverride(storageKey: string): Density | undefined {\n if (typeof window === \"undefined\") return undefined;\n\n try {\n const raw = window.localStorage.getItem(storageKey);\n return isDensity(raw) ? raw : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeStoredDensityOverride(\n storageKey: string,\n density: Density | undefined,\n) {\n if (typeof window === \"undefined\") return;\n\n try {\n if (density) {\n window.localStorage.setItem(storageKey, density);\n } else {\n window.localStorage.removeItem(storageKey);\n }\n } catch {}\n}\n\nfunction isDensity(value: unknown): value is Density {\n return value === \"compact\" || value === \"comfortable\" || value === \"spacious\";\n}\n\nfunction pruneColumnWidths<T extends Record<string, unknown>>(\n widths: Record<string, unknown>,\n columns: DataTableColumn<T>[],\n): Record<string, number> {\n const byKey = new Map(columns.map((column) => [column.key, column]));\n const next: Record<string, number> = {};\n\n for (const [key, width] of Object.entries(widths)) {\n const column = byKey.get(key);\n if (!column || typeof width !== \"number\" || !Number.isFinite(width))\n continue;\n\n next[key] = clampColumnWidth(column, width);\n }\n\n return next;\n}\n\nfunction pruneHiddenColumns<T extends Record<string, unknown>>(\n hiddenColumns: Record<string, unknown>,\n columns: DataTableColumn<T>[],\n): Record<string, boolean> {\n const byKey = new Map(columns.map((column) => [column.key, column]));\n const next: Record<string, boolean> = {};\n\n for (const [key, hidden] of Object.entries(hiddenColumns)) {\n const column = byKey.get(key);\n if (!column || hidden !== true || !isColumnHideable(column)) continue;\n\n next[key] = true;\n }\n\n const hideable = columns.filter(isColumnHideable);\n const visibleHideableCount = hideable.filter(\n (column) => next[column.key] !== true,\n ).length;\n if (hideable.length > 0 && visibleHideableCount === 0) {\n delete next[hideable[0]!.key];\n }\n\n return next;\n}\n\nfunction sameColumnWidths(\n left: Record<string, number>,\n right: Record<string, number>,\n) {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every(\n (key) =>\n Object.prototype.hasOwnProperty.call(right, key) &&\n left[key] === right[key],\n )\n );\n}\n\nfunction sameHiddenColumns(\n left: Record<string, boolean>,\n right: Record<string, boolean>,\n) {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every(\n (key) =>\n Object.prototype.hasOwnProperty.call(right, key) &&\n left[key] === right[key],\n )\n );\n}\n\nfunction defaultColumnWidth<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n) {\n if (column.grow) return DEFAULT_GROW_COLUMN_WIDTH;\n if (column.shrink) return DEFAULT_SHRINK_COLUMN_WIDTH;\n return DEFAULT_COLUMN_WIDTH;\n}\n\nfunction clampColumnWidth<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n width: number,\n) {\n const minWidth = column.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const maxWidth = column.maxWidth;\n const minimum = Number.isFinite(minWidth)\n ? Math.max(1, minWidth)\n : DEFAULT_COLUMN_MIN_WIDTH;\n const maximum =\n maxWidth != null && Number.isFinite(maxWidth)\n ? Math.max(minimum, maxWidth)\n : Infinity;\n\n return Math.round(Math.max(minimum, Math.min(maximum, width)));\n}\n\nfunction getNumericFilterBounds<T extends Record<string, unknown>>(\n rows: InternalRow<T>[],\n column: DataTableColumn<T>,\n) {\n const values = rows.flatMap((record) =>\n collectFilterValues(getFilterCandidate(record.row, column)),\n );\n const populated = values.filter(hasFilterValue);\n const numericValues = populated\n .map((value) => parseNumberInput(value))\n .filter((value) => value != null);\n\n if (populated.length === 0 || numericValues.length !== populated.length) {\n return null;\n }\n\n return {\n min: Math.min(...numericValues),\n max: Math.max(...numericValues),\n step: inferNumericStep(numericValues),\n };\n}\n\nfunction collectFilterValues(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value.flatMap((item) => collectFilterValues(item));\n }\n\n return [value];\n}\n\nfunction hasFilterValue(value: unknown) {\n return value != null && !(typeof value === \"string\" && value.trim() === \"\");\n}\n\nfunction parseNumberInput(value: unknown): number | null {\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : null;\n }\n\n if (typeof value !== \"string\") {\n return null;\n }\n\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n const parsed = Number(trimmed);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction inferNumericStep(values: number[]) {\n if (values.every(Number.isInteger)) {\n return 1;\n }\n\n const maxFractionDigits = values.reduce((current, value) => {\n const [, fraction = \"\"] = String(value).split(\".\");\n return Math.max(current, fraction.length);\n }, 0);\n\n return 10 ** -Math.min(maxFractionDigits || 2, 6);\n}\n\nfunction alignmentClass(align?: DataTableColumn[\"align\"]) {\n if (align === \"right\") return \"text-right\";\n if (align === \"center\") return \"text-center\";\n return \"text-left\";\n}\n\nfunction headerAlignmentClass(align?: DataTableColumn[\"align\"]) {\n if (align === \"right\") return \"justify-end\";\n if (align === \"center\") return \"justify-center\";\n return \"justify-start\";\n}\n\nfunction loadingSkeletonWidth(index: number) {\n return [\"w-24\", \"w-40\", \"w-28\", \"w-56\", \"w-32\", \"w-48\"][index % 6];\n}\n\n// An auto-layout column is only ever as wide as its widest cell, so the width a\n// cell is allowed to ask for has to be bounded somewhere or one long value\n// pins the column to its own text and pushes the table sideways. It belongs on\n// the cell rather than on the content: max-width bounds what a column asks for\n// without clipping what it is finally given, so the content can fill a column\n// that leftover space made wider instead of truncating with room to spare.\n// A grow column asks for nothing and lives on the leftovers, with the minimum\n// keeping it from collapsing when the other columns already fill the table.\nfunction cellSizingStyle<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n width: number | undefined,\n): CSSProperties {\n if (width !== undefined) return { maxWidth: `${width}px` };\n if (column.grow) {\n return {\n maxWidth: \"0px\",\n minWidth: column.minWidth ?? DEFAULT_GROW_COLUMN_WIDTH,\n };\n }\n return {\n maxWidth:\n column.maxWidth ??\n (column.shrink ? DEFAULT_SHRINK_CELL_MAX_WIDTH : DEFAULT_CELL_MAX_WIDTH),\n };\n}\n\nfunction cellContentClassName<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n): TdHTMLAttributes<HTMLTableCellElement>[\"className\"] {\n return cn(\"w-full min-w-0 truncate\", column.shrink && \"whitespace-nowrap\");\n}\n\nexport function DataTable<T extends Record<string, unknown>>({\n theme: themeProp = \"system\",\n onThemeChange,\n showThemeControl = false,\n showFullscreenControl = false,\n fullscreenTitle = \"Table\",\n fullscreenButtonLabel = \"Open table full screen\",\n className,\n filterBarProps,\n scrollContainerRef,\n ...inner\n}: DataTableProps<T>) {\n const themeControlled = onThemeChange !== undefined;\n const [internalTheme, setInternalTheme] = useState<Theme>(themeProp);\n const themeValue = themeControlled ? themeProp : internalTheme;\n const resolvedTheme = useResolvedTheme(themeValue);\n const handleThemeChange = (next: Theme) => {\n if (!themeControlled) setInternalTheme(next);\n onThemeChange?.(next);\n };\n const [fullscreenOpen, setFullscreenOpen] = useState(false);\n\n const renderTable = ({ inFullscreen }: { inFullscreen: boolean }) => {\n const showFullscreenButton = showFullscreenControl && !inFullscreen;\n const callerTrailing = filterBarProps?.trailing;\n const mergedFilterBarProps = showFullscreenButton\n ? {\n ...filterBarProps,\n trailing: (\n <>\n {callerTrailing}\n <FullscreenButton\n label={fullscreenButtonLabel}\n onClick={() => setFullscreenOpen(true)}\n />\n </>\n ),\n }\n : filterBarProps;\n // Both copies stay mounted while the modal is open, so exactly one of them\n // may hold the caller's scroll ref: handing it to both makes the last one\n // mounted the winner and nulls it when the modal unmounts, which leaves a\n // caller pinning a live tail writing to an element nobody is looking at.\n // The visible copy is the fullscreen one precisely when the modal is open.\n const ownsScroll = inFullscreen === fullscreenOpen;\n return (\n <DataTableInner\n {...(inner as DataTableInnerProps<T>)}\n {...(ownsScroll && scrollContainerRef ? { scrollContainerRef } : {})}\n {...(mergedFilterBarProps\n ? { filterBarProps: mergedFilterBarProps }\n : {})}\n themeMenuValue={themeValue}\n showThemeControl={showThemeControl}\n onThemeChange={handleThemeChange}\n />\n );\n };\n\n return (\n <div\n data-theme={resolvedTheme}\n className={cn(\"flex min-h-0 flex-col text-foreground\", className)}\n >\n {renderTable({ inFullscreen: false })}\n {showFullscreenControl && (\n <Modal\n open={fullscreenOpen}\n onClose={() => setFullscreenOpen(false)}\n title={fullscreenTitle}\n size=\"full\"\n className=\"h-[95vh]\"\n >\n <div\n data-theme={resolvedTheme}\n className=\"flex h-full min-h-0 flex-col bg-background text-foreground\"\n >\n {renderTable({ inFullscreen: true })}\n </div>\n </Modal>\n )}\n </div>\n );\n}\n\nfunction FullscreenButton({\n label,\n onClick,\n}: {\n label: string;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n className=\"inline-flex h-8 w-8 items-center justify-center rounded-md border border-input bg-background text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n onClick={onClick}\n >\n <Icon icon={UiFullscreen} className=\"text-sm\" />\n </button>\n );\n}\n"],"names":["_a","rows","groups","record","Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataTable.js","sources":["../../src/data/DataTable.tsx"],"sourcesContent":["import {\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n type RefObject,\n type TdHTMLAttributes,\n} from \"react\";\nimport { useSort, type SortDir, type SortState } from \"../hooks/use-sort\";\nimport { type Density } from \"../hooks/use-density\";\nimport { DensityValueProvider } from \"../hooks/density-provider\";\nimport { useResolvedTheme, type Theme } from \"../hooks/use-theme\";\nimport { cn } from \"../lib/utils\";\nimport { LoadingBar } from \"../components/loading\";\nimport { useRouter } from \"../rpc/router\";\nimport { Modal, type ModalSize } from \"../overlay/Modal\";\nimport { useEscapeLayer } from \"../overlay/modalStack\";\nimport {\n FilterBar,\n FilterBarFilterPanel,\n FilterBarRangePanel,\n type FilterBarFilter,\n type FilterBarMultiFilterMode,\n type FilterBarNumberValue,\n type FilterBarProps,\n type FilterBarRangePreset,\n type FilterBarRangeProps,\n type FilterBarSearchProps,\n} from \"../components/FilterBar\";\nimport {\n clearFilterBarFilter,\n dateRangeFilterProps,\n isFilterBarFilterActive,\n} from \"../components/filter-bar-utils\";\nimport {\n getFilterCandidate,\n getFilterTokens,\n prettifyKey,\n resolveColumnValue,\n} from \"./data-table-utils\";\nimport { assertDataTableFilterProps } from \"./data-table-server-filters\";\nimport { useInfiniteRows } from \"./use-infinite-rows\";\nimport type { MultiSelectOption } from \"../components/MultiSelect\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport {\n UiChevronDown,\n UiChevronRight,\n UiClose,\n UiEllipsis,\n UiEyeClosed,\n UiFilterFilled,\n UiFilter,\n UiFullscreen,\n UiResizeVertical,\n UiCheck,\n UiDesktop,\n UiListDashes,\n UiListFlat,\n UiMoon,\n UiArrowLeft,\n UiArrowRight,\n UiRows,\n UiSun,\n} from \"../icons\";\nimport { SortableHeader } from \"./SortableHeader\";\nimport { Timestamp } from \"./cells/Timestamp\";\nimport {\n chooseTimestampFormat,\n modeToFormat,\n parseTimestamp,\n resolveDateMath,\n type TimestampFormat,\n type TimestampOptions,\n} from \"./cells/timestamp-format\";\nimport { TagActionsProvider, TagList } from \"./cells/TagList\";\nimport {\n CellFilterActions,\n type CellFilterChange,\n type CellFilterMode,\n} from \"./cells/CellFilterActions\";\nimport {\n normalizeTags,\n splitTagToken,\n tagActionsFromRecord,\n tagFilterTokens,\n type TagActionsContextValue,\n type TagFilterMode,\n type TagsOptions,\n type TagsValue,\n} from \"./cells/tag-utils\";\nimport { StatusDot } from \"./cells/StatusDot\";\nimport { normalizeStatus } from \"./cells/status-mapping\";\nimport type { BadgeStatus } from \"./Badge\";\nimport {\n dataTableGroupKey,\n dataTableGroupLabel,\n groupRecords,\n isGroupCollapsedByDefault,\n type DataTableGrouping,\n type DataTableGroupingMode,\n type DataTableGroupMetaAlign,\n} from \"./DataTable.grouping\";\nimport { DataTableGroupingControls } from \"./DataTableGroupingControls\";\nimport { SelectionActionBar } from \"./SelectionActionBar\";\n\nexport type { TimestampOptions, TagsOptions };\n\nexport type DataTableColumnKind = \"timestamp\" | \"tags\" | \"status\";\n\nexport type StatusOptions<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Maps the raw cell value to a badge status. Return null to fall back to text. */\n map?: (raw: unknown, row: T) => BadgeStatus | null;\n /** Show the normalized status label next to the dot. */\n showLabel?: boolean;\n /** Tooltip text for the status cell. */\n title?: (raw: unknown, row: T) => string;\n};\n\ntype FilterValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | Array<string | number | boolean>;\n\ntype InternalRow<T> = {\n id: string;\n row: T;\n};\n\ntype ResolvedGroup<T> = {\n key: string;\n records: InternalRow<T>[];\n rows: T[];\n label: ReactNode;\n meta: ReactNode;\n collapsed: boolean;\n};\n\ntype GroupCollapseState = {\n all?: boolean;\n groups: Record<string, boolean>;\n};\n\ntype RowStreamItem<T> =\n | { kind: \"group\"; group: ResolvedGroup<T> }\n | { kind: \"row\"; record: InternalRow<T> };\n\ntype GeneratedFilter<T extends Record<string, unknown>> = {\n column: DataTableColumn<T>;\n kind: \"text\" | \"multi\" | \"nested-multi\" | \"number\";\n options: MultiSelectOption[];\n groups?: Array<{\n groupKey: string;\n label?: string;\n options: MultiSelectOption[];\n }>;\n numberBounds?: {\n min: number;\n max: number;\n step: number;\n };\n};\n\nconst DEFAULT_COLUMN_MIN_WIDTH = 64;\nconst DEFAULT_COLUMN_WIDTH = 160;\nconst DEFAULT_GROW_COLUMN_WIDTH = 224;\nconst DEFAULT_SHRINK_COLUMN_WIDTH = 96;\nconst DEFAULT_CELL_MAX_WIDTH = 288;\nconst DEFAULT_SHRINK_CELL_MAX_WIDTH = 256;\nconst COLUMN_WIDTH_STORAGE_PREFIX = \"clicky-ui-data-table-column-widths\";\nconst COLUMN_VISIBILITY_STORAGE_PREFIX =\n \"clicky-ui-data-table-column-visibility\";\nconst DENSITY_STORAGE_PREFIX = \"clicky-ui-data-table-density\";\n\nconst DENSITY_OPTIONS: Array<{\n value: Density;\n icon: StaticIconComponent;\n label: string;\n}> = [\n { value: \"compact\", icon: UiRows, label: \"Compact\" },\n { value: \"comfortable\", icon: UiListFlat, label: \"Comfortable\" },\n { value: \"spacious\", icon: UiListDashes, label: \"Spacious\" },\n];\n\nconst DATA_TABLE_HEADER_DENSITY_CLASS =\n \"px-2.5 py-1.5 density-compact:px-2 density-compact:py-1 density-comfortable:px-2.5 density-comfortable:py-1.5 density-spacious:px-4 density-spacious:py-3\";\nconst DATA_TABLE_CELL_DENSITY_CLASS =\n \"px-2.5 py-1.5 density-compact:px-2 density-compact:py-0.5 density-comfortable:px-2.5 density-comfortable:py-1.5 density-spacious:px-4 density-spacious:py-3\";\n\ntype ColumnMenuState = {\n x: number;\n y: number;\n columnKey?: string;\n};\n\nexport type DataTableRowDetailContext<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n columns: DataTableColumn<T>[];\n visibleColumns: DataTableColumn<T>[];\n filterActionsByColumn: Record<string, TagActionsContextValue>;\n};\n\n// Mirrors the preset list used by the trace UI's TraceFilters so log/trace\n// tables share the same vocabulary out of the box.\nconst TIMESTAMP_RANGE_PRESETS: FilterBarRangePreset[] = [\n { label: \"Last 5 minutes\", from: \"now-5m\", to: \"now\" },\n { label: \"Last 15 minutes\", from: \"now-15m\", to: \"now\" },\n { label: \"Last 1 hour\", from: \"now-1h\", to: \"now\" },\n { label: \"Last 6 hours\", from: \"now-6h\", to: \"now\" },\n { label: \"Last 24 hours\", from: \"now-24h\", to: \"now\" },\n { label: \"Last 7 days\", from: \"now-7d\", to: \"now\" },\n { label: \"Last 30 days\", from: \"now-30d\", to: \"now\" },\n];\n\nexport type DataTableColumn<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Field path or stable column id. Dotted paths read nested row values. */\n key: string;\n /** Header label. */\n label: ReactNode;\n /**\n * Reads the cell value from the row. When set, it is used for rendering,\n * sorting, and filtering instead of resolving `key` as a (possibly nested)\n * path. Use this for arbitrary SQL columns whose names are empty, contain\n * dots (\"a.b\" as a literal key, not a nested path), or collide — the `key`\n * then only needs to be a stable, unique column id.\n */\n accessor?: (row: T) => unknown;\n /** Enables header click sorting for this column. */\n sortable?: boolean;\n /** Enables a generated column filter when `autoFilter` is true. */\n filterable?: boolean;\n /** Native server-filter parameter associated with this rendered column. */\n filterKey?: string;\n /** Converts the raw cell value to the exact scalar sent to the native server filter. */\n serverFilterValue?: (value: unknown, row: T) => unknown;\n /** Converts the raw cell value to the label shown by server-filter actions. */\n serverFilterLabel?: (value: unknown, row: T) => string;\n /** Prefer allocating extra width to this column. */\n grow?: boolean;\n /** Prefer keeping this column compact. */\n shrink?: boolean;\n /** Allows users to drag the column separator. */\n resizable?: boolean;\n /** Allows the column to be toggled from the column menu. */\n hideable?: boolean;\n /** Minimum column width in pixels. */\n minWidth?: number;\n /** Maximum column width in pixels. */\n maxWidth?: number;\n /** Cell and header text alignment. */\n align?: \"left\" | \"center\" | \"right\";\n /** Custom cell renderer. */\n render?: (value: unknown, row: T) => ReactNode;\n /** Sort key derived from the raw value and row. */\n sortValue?: (value: unknown, row: T) => unknown;\n /** Filter token or tokens derived from the raw value and row. */\n filterValue?: (value: unknown, row: T) => FilterValue;\n /** Classes applied to cells in this column. */\n cellClassName?: string;\n /** Classes applied to the header cell. */\n headerClassName?: string;\n /**\n * Built-in cell kind. When set, DataTable supplies a default renderer,\n * a default `sortValue` and a default `filterValue` (all overridable).\n * - \"timestamp\": adaptive format (relative / time / short / iso) chosen\n * from the spread of values in `data`.\n * - \"tags\": chip list with `+N` overflow; auto-multi-filter on tag tokens.\n * - \"status\": colored dot with the standard error/warning/success palette\n * (token-mapped — \"ERROR\", \"failed\", \"fatal\" all collapse to \"error\").\n */\n kind?: DataTableColumnKind;\n timestamp?: TimestampOptions;\n tags?: TagsOptions;\n status?: StatusOptions<T>;\n};\n\nexport type DataTableColumnInput<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = DataTableColumn<T> | string;\n\n/**\n * Server-side pagination control surfaced as a footer strip below the table.\n * The DataTable never slices data itself; callers refetch when the page or\n * pageSize changes.\n */\nexport type DataTablePagination = {\n /** Current zero-indexed page. */\n page: number;\n /** Number of rows requested per page. */\n pageSize: number;\n /** Total row count if known; enables \"Page X of Y\". */\n total?: number;\n /**\n * Whether `total` is a count (\"eq\") or a lower bound (\"gte\"). A backend that\n * stops counting past a threshold reports a bound, and rendering it as a\n * count would state a number nobody promised.\n */\n totalRelation?: \"eq\" | \"gte\";\n /**\n * The server's answer for whether rows follow this page. Preferred over\n * inferring the end of the data from a short page: the two are different\n * facts, and only the server knows which one happened.\n */\n hasMore?: boolean;\n /**\n * Called when the user moves to another page. Absent when the surface cannot\n * name a position past its first page — an operation with no offset or cursor\n * parameter. Such a table still counts and still resizes; it just has nowhere\n * to step to, so the step controls are not rendered.\n */\n onPageChange?: (page: number) => void;\n /** Called when the page size select changes. */\n onPageSizeChange: (pageSize: number) => void;\n /** Available page sizes. Defaults to [25, 50, 100, 200]. */\n pageSizeOptions?: number[];\n /**\n * Cursor paging. When present the footer steps through the cursors the\n * server minted instead of by page number — a cursor names a position in an\n * ordered result, so there is no cursor for a page nobody has visited and\n * the page-number jump is not offered.\n */\n cursor?: DataTableCursorPagination;\n};\n\n/**\n * DataTableCursorPagination is the caller's half of a cursor walk. The tokens\n * are opaque: they are handed back unchanged and never parsed.\n */\nexport type DataTableCursorPagination = {\n /** The cursor this page was fetched with; undefined on the first page. */\n current?: string;\n /** The cursor that resumes after this page; absent when the data is exhausted. */\n next?: string;\n /** Fetch the page at this cursor; undefined returns to the first page. */\n onCursorChange: (cursor: string | undefined) => void;\n};\n\n/**\n * isSinglePage reports whether the rows on screen are the whole result.\n *\n * It is the question a client-side sort turns on. Sorting one page of many\n * reorders that page and nothing else, which reads as a sort of the table and is\n * not one — but when there is no page after this one, sorting these rows *is*\n * sorting the table, and withholding the header helps nobody.\n *\n * `hasMore` is preferred over inferring the end of the data from a short page:\n * the two are different facts and only the server knows which one happened. A\n * lower-bound total says nothing about the end, so it is not read as one; the\n * short-page inference is the last resort, and matches what the footer already\n * falls back to.\n */\nfunction isSinglePage(\n pagination: DataTablePagination | undefined,\n visibleRowCount: number,\n): boolean {\n if (!pagination) return true;\n if (pagination.cursor) {\n return (\n pagination.cursor.current === undefined &&\n pagination.cursor.next === undefined\n );\n }\n if (pagination.page !== 0) return false;\n if (pagination.hasMore != null) return !pagination.hasMore;\n if (pagination.total != null && pagination.totalRelation !== \"gte\") {\n return pagination.total <= pagination.pageSize;\n }\n return visibleRowCount < pagination.pageSize;\n}\n\n/**\n * DataTableInfinite turns a server-paged table into one continuous list: the\n * caller accumulates the pages it has fetched and hands the whole run in as\n * `data`, and the table asks for the next one as the reader reaches the end.\n *\n * It is distinct from `clientReveal`, which windows rows the caller already\n * holds. Here the rows do not exist yet, so the two facts that matter are the\n * server's — whether more follow, and whether the request for them is already\n * in flight. Inferring either from `data.length` is what turns a slow page into\n * a duplicate request, and the end of the data into a spinner that never stops.\n *\n * Passing this alongside `pagination` is the normal case rather than a\n * conflict: the footer keeps reporting the count and page size, and only the\n * step controls are withdrawn, because a position nobody can step back to is\n * not one worth rendering a button for.\n */\nexport type DataTableInfinite = {\n /** The server's answer for whether rows follow what has been loaded. */\n hasMore: boolean;\n /** A request for the next page is in flight; the table must not ask again. */\n loading: boolean;\n /** Fetch and append the next page. */\n onLoadMore: () => void;\n};\n\nexport type DataTableMenuAction = {\n id: string;\n label: ReactNode;\n description?: ReactNode;\n icon?: StaticIconComponent;\n iconClassName?: string;\n disabled?: boolean;\n /** Heading the action is grouped under in the overflow menu. Actions with\n * the same section render together below one label; defaults to \"Download\"\n * so existing download actions keep their heading. An empty string groups\n * without a heading, for a short list where one would only add noise. */\n section?: string;\n /**\n * Nested actions. An action that has them is a submenu trigger: it opens a\n * flyout of its children and its own `onSelect` never runs. This is what\n * keeps a menu of a dozen formats to one row.\n */\n children?: DataTableMenuAction[];\n onSelect: () => void;\n};\n\nexport type DataTableRowSelection<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Controlled set of selected row ids, resolved through `getRowId`. */\n selectedRowIds: readonly string[];\n /** Called with the next ids and the matching rows currently loaded. */\n onSelectionChange: (selectedRowIds: string[], selectedRows: T[]) => void;\n /** Optional predicate for rows that cannot be selected. */\n isRowSelectable?: (row: T) => boolean;\n /** Toggle selection when the user clicks anywhere on a selectable row. */\n toggleOnRowClick?: boolean;\n /**\n * Extends the selection past the loaded page. Without it the header checkbox\n * is the whole story and it only reaches rows the table is holding, which\n * reads as \"select all\" but stops at the page boundary.\n */\n selectAllPages?: DataTableSelectAllPages;\n};\n\n/**\n * The caller's half of a cross-page selection. The table knows how many rows it\n * has and how many are selected; it cannot know the rows it never fetched, so\n * resolving them stays with whoever owns the query.\n */\nexport type DataTableSelectAllPages = {\n /**\n * What the selection can widen to, narrowest first. A table showing one\n * group of a larger result offers that group before the whole match, so\n * \"select all\" means the rows in front of the reader before it means every\n * row the filters allow. One scope is the ordinary case.\n */\n scopes: readonly DataTableSelectAllScope[];\n /** True while a scope is still resolving. */\n loading?: boolean;\n /** Plural noun for the rows, used in the notice. Defaults to \"rows\". */\n noun?: string;\n};\n\nexport type DataTableSelectAllScope = {\n /** Rows this scope covers. Defaults to `pagination.total`. */\n total?: number;\n /**\n * Selects every row in the scope, adding to whatever is already selected.\n * Usually async, since the caller has to fetch the pages it has not loaded\n * before it can hand their ids back through `onSelectionChange`.\n */\n onSelectAll: () => void;\n /** Button label. Defaults to `Select all ${total} ${noun}`. */\n label?: string;\n};\n\n/** Passed to `selectionActions` while rows are selected. */\nexport type DataTableSelectionContext<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n selectedRowIds: string[];\n /** The selected rows currently loaded, in render order. */\n selectedRows: T[];\n /** Empties the selection through the same `onSelectionChange` callback. */\n clearSelection: () => void;\n};\n\n/**\n * Copy for the prompt a bulk action puts in front of itself. The count is the\n * one number that makes a bulk confirmation worth stopping for, and the table\n * is the only side that knows it — so `message` can be a function of the\n * selection rather than a fixed string the caller has to keep in sync.\n */\nexport type DataTableSelectionConfirm<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Heading of the prompt. Defaults to the action's own label. */\n title?: ReactNode;\n message?: ReactNode | ((context: DataTableSelectionContext<T>) => ReactNode);\n /** Label of the button that proceeds. Defaults to the action's label. */\n confirmLabel?: string;\n /** Label of the button that backs out. Defaults to \"Cancel\". */\n cancelLabel?: string;\n};\n\n/**\n * A bulk action the table renders for itself, rather than markup the caller\n * assembles. It is a `DataTableMenuAction` with the selection wired in: the\n * same id / label / icon / section / children shape, so the overflow menu keeps\n * one renderer and one set of submenu rules, and an `onSelect` that is handed\n * the rows it acts on.\n *\n * Everything it adds is something a bulk action has and a preferences entry\n * does not. A bulk action is a request against real rows, so it can be slow\n * (`onSelect` may return a promise), it can be the reason the reader ticked the\n * boxes at all (`primary`), it can be the one nobody meant to click\n * (`variant: \"destructive\"`), and it can be the one that deserves to be asked\n * about twice (`confirm`).\n */\n/** Where a bulk action renders on the selection bar. */\nexport type SelectionActionDisplay = \"button\" | \"menu\" | \"overflow\";\n\n/** Handed to an action's custom `menu` body. */\nexport type DataTableSelectionMenuContext<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** The selection the action will act on. */\n context: DataTableSelectionContext<T>;\n /** Dismisses the dropdown. */\n close: () => void;\n /** True while any action on this bar is in flight; disable your controls. */\n busy: boolean;\n /**\n * Runs work through the bar's own plumbing — this action's pending spinner,\n * the sibling lock, the confirm prompt. Call it instead of the mutation\n * directly, or the bar has no idea anything is running.\n */\n run: (task: {\n pendingLabel?: ReactNode;\n confirm?: boolean | DataTableSelectionConfirm<T>;\n onSelect: (context: DataTableSelectionContext<T>) => void | Promise<void>;\n }) => void;\n};\n\nexport type DataTableSelectionAction<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = Omit<DataTableMenuAction, \"onSelect\" | \"children\"> & {\n /**\n * Runs the action against the current selection. Returning a promise puts\n * this button in a pending state and locks the rest of the cluster until it\n * settles: the slow half of a bulk call is also the half that can be fired\n * twice, and the rows it is rewriting are already under the reader's cursor.\n */\n onSelect: (context: DataTableSelectionContext<T>) => void | Promise<void>;\n /**\n * Nested actions. As in the preferences menu, a parent that has them is a\n * submenu trigger and its own `onSelect` never runs. Inline, the parent is a\n * named dropdown of its children — \"Status ▾\" over the statuses it can set;\n * in the overflow menu it is a submenu.\n */\n children?: DataTableSelectionAction<T>[];\n /**\n * How the bar renders this action, overriding what it would otherwise infer:\n *\n * \"button\" — its own toolbar button.\n * \"menu\" — a named inline dropdown (\"Status ▾\"), bodied by `menu` if\n * given and by `children` otherwise. Never collapses: naming a\n * dropdown is the caller saying the row has space for it.\n * \"overflow\" — an item in the trailing ⋯ menu.\n *\n * Left unset, an action with `menu` is a dropdown, one with `children` or a\n * `section` is overflow (a flyout needs an anchor, a heading needs a menu),\n * and anything else is a button subject to `primary` and the cap.\n */\n display?: SelectionActionDisplay;\n /**\n * A menu body that is not a list of commands — a filterable, tri-state set of\n * labels, say, applied as one edit when the menu closes. Handed straight to\n * DropdownMenu's own render prop, so this adds a body, not a second menu.\n *\n * Implies `display: \"menu\"`, and like `children` it makes the action a\n * trigger: its `onSelect` never runs. The body routes work back through\n * `run` so the bar still owns the pending spinner and the sibling lock.\n */\n menu?: (menu: DataTableSelectionMenuContext<T>) => ReactNode;\n /**\n * Keeps the action on the toolbar as its own button. Once any action claims\n * `primary` the ones that do not fall into the overflow menu, because a\n * caller that has named its important action has already said what the\n * toolbar is for. With none claimed, position decides.\n */\n primary?: boolean;\n /** Button styling. \"destructive\" is the only one that changes what the\n * action means rather than how loudly it says it. */\n variant?: \"default\" | \"outline\" | \"ghost\" | \"destructive\";\n /** Ask before running. `true` uses the default copy. */\n confirm?: boolean | DataTableSelectionConfirm<T>;\n /** Label shown while `onSelect` is in flight. Defaults to the normal label. */\n pendingLabel?: ReactNode;\n};\n\n/** Passed to a `footer` render function. */\nexport type DataTableFooterContext = {\n /** Rows left after filtering — what the table is showing. */\n visibleRowCount: number;\n /** Rows handed to the table before filtering. */\n totalRowCount: number;\n loading: boolean;\n};\n\ntype DataTableInnerProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** Rows to render. The table does not fetch or mutate row data. */\n data: T[];\n /** Error content rendered as an accessible full-width row in the table body. */\n error?: ReactNode;\n /**\n * Column descriptors. Pass a bare string for a default column —\n * `\"foo\"` is equivalent to `{ key: \"foo\", label: \"foo\" }` — handy for\n * ad-hoc query results where the column metadata is just a list of names.\n * Mix and match strings with full descriptors as needed.\n */\n columns: Array<DataTableColumnInput<T>>;\n /** Shows skeleton/loading rows instead of data rows. */\n loading?: boolean;\n /** Message shown while `loading` is true. */\n loadingMessage?: ReactNode;\n /** Number of skeleton rows to render while loading. */\n loadingRowCount?: number;\n /** Message used when there are no rows after filtering. */\n emptyMessage?: string;\n /**\n * Client-side incremental reveal (infinite scroll). When set — and no server\n * `pagination` is provided — the table renders `batchSize` rows at a time and\n * grows by `batchSize` as a trailing sentinel scrolls into view. Use for\n * large in-memory result sets (e.g. ad-hoc SQL output) to keep the first\n * paint cheap without paginating.\n */\n clientReveal?: { batchSize: number };\n /** Classes applied to the table shell. */\n className?: string;\n /**\n * Classes for the scrollable table region. Defaults to `min-h-0 flex-1`\n * (fills a bounded flex parent). Pass e.g. `max-h-[26rem]` to cap height.\n */\n scrollContainerClassName?: string;\n /** Generate filters from filterable columns. */\n autoFilter?: boolean;\n /**\n * Show the built-in global search input. Defaults to `autoFilter` — the box\n * narrows rows client-side, so it only mounts by default where DataTable\n * already owns filtering. Set it explicitly to search a table that generates\n * no column filters; combine with `manualFilter` plus `globalFilter` /\n * `onGlobalFilterChange` (or use `externalSearch`) to drive a source query.\n */\n showGlobalFilter?: boolean;\n /** Controlled global search value. */\n globalFilter?: string;\n /** Called when the global search changes. */\n onGlobalFilterChange?: (value: string) => void;\n /** Placeholder for the global search input. */\n globalFilterPlaceholder?: string;\n /** Initial sort state. */\n defaultSort?: { key: string; dir?: SortDir };\n /** Controlled sort state, for server-backed tables. */\n sort?: SortState | null;\n /** Called when a sortable header changes the controlled sort state. */\n onSortChange?: (sort: SortState | null) => void;\n /** When true, header sorting updates state but does not reorder `data`. */\n manualSort?: boolean;\n /**\n * When true, filters update state but do NOT narrow `data`. The mirror of\n * `manualSort`: the source owns filtering and DataTable only renders the\n * controls. Suppresses the client-side filter pass, the built-in search's row\n * narrowing, and the column-derived time range.\n */\n manualFilter?: boolean;\n /** Extra props forwarded to the internal FilterBar. */\n filterBarProps?: Omit<FilterBarProps, \"search\" | \"filters\">;\n /**\n * Caller-owned search input rendered in the FilterBar's search slot. Unlike\n * `globalFilter`, this does NOT filter rows client-side — it is a controlled\n * input the caller wires to a server-side query (e.g., an operation's `q`\n * parameter). Takes precedence over the built-in global filter input.\n */\n externalSearch?: FilterBarSearchProps;\n /**\n * Caller-owned time-range control rendered in the FilterBar. Like\n * `externalSearch`/`externalFilters`, it does NOT filter rows client-side —\n * the caller wires it to a server-side query (e.g. an operation's\n * `time-from`/`time-to` parameters). Takes precedence over any\n * column-derived time range.\n */\n externalTimeRange?: FilterBarRangeProps;\n /**\n * Extra filter pills supplied by the caller (e.g., operation query\n * parameters surfaced via parametersToFormConfig) that should appear in the\n * FilterBar alongside the column-derived filters. Rendered before the\n * column filters so the caller's natural ordering wins.\n */\n externalFilters?: FilterBarFilter[];\n /** Current modes for native server-backed cell filters. */\n cellFilters?: Record<string, Record<string, CellFilterMode>>;\n /** Called when a cell's include/exclude hover action changes. */\n onCellFilterChange?: (change: CellFilterChange) => void;\n /**\n * Server-side pagination footer. When provided, a small page-size / prev /\n * next strip is rendered below the table; the DataTable does NOT slice\n * `data` itself, callers are expected to refetch when `onPageChange` or\n * `onPageSizeChange` fires.\n */\n pagination?: DataTablePagination;\n /**\n * Server-driven infinite scroll. The caller owns the accumulated rows; this\n * only says when to ask for more. Combines with `pagination` — see\n * DataTableInfinite.\n */\n infinite?: DataTableInfinite;\n /**\n * Handle on the scrollable table region, for a caller that has to drive the\n * scroll position itself — pinning a live tail to the bottom, say. The table\n * never writes through it; it is exposed because a follow mode has to be able\n * to keep the newest row in view, and nothing outside the component can reach\n * that element otherwise.\n */\n scrollContainerRef?: RefObject<HTMLDivElement | null>;\n /** Stable row id extractor. Defaults to the row index. */\n getRowId?: (row: T, index: number) => string;\n /** Controlled checkbox selection for entity/bulk-action tables. */\n rowSelection?: DataTableRowSelection<T>;\n /**\n * Bulk actions, rendered in the toolbar beside the table menu while\n * `rowSelection` holds a non-empty selection — next to what the selection\n * covers, and above the rows it acts on. Ignored without `rowSelection`.\n *\n * A list is the form to reach for: the table renders the buttons, the count,\n * the Clear, the overflow menu, the pending state while an async action is in\n * flight, and the prompt in front of a destructive one — the same way it\n * renders `menuActions`. The render-prop form stays for the cluster that is\n * genuinely bespoke (a running total, a bar with its own layout) and hands\n * back the plumbing only.\n */\n selectionActions?:\n | DataTableSelectionAction<T>[]\n | ((context: DataTableSelectionContext<T>) => ReactNode);\n /**\n * Where the bulk cluster goes while rows are selected.\n *\n * \"takeover\" — it replaces the filter row in place: the filters stay\n * mounted behind it and come back when the selection clears, so nothing\n * below the bar moves. Only honoured for the descriptor (array) form of\n * `selectionActions`; a render-prop cluster is the caller's own markup\n * and the table cannot claim the row on its behalf.\n * \"toolbar\" (the default) — the cluster rides in the filter bar's trailing\n * slot beside the table menu, sharing the row with the filters.\n */\n selectionBar?: \"takeover\" | \"toolbar\";\n /**\n * Extra classes for a row's `<tr>`, applied last so tailwind-merge lets the\n * caller override the built-in hover / selected backgrounds.\n */\n getRowClassName?: (row: T) => string | undefined;\n /**\n * Replaces the default \"N of M rows\" strip below the table. When\n * `pagination` is also set, this renders directly above the pager instead.\n */\n footer?: ReactNode | ((context: DataTableFooterContext) => ReactNode);\n /**\n * Splits the rendered rows into collapsible groups, each introduced by a\n * full-width header row. Grouping presents what is already on screen: it\n * runs after filtering, sorting and pagination, so it never reorders rows\n * within a group and never pulls in rows from another page.\n */\n grouping?: DataTableGrouping<T>;\n /** Selectable grouping strategies rendered in the native FilterBar picker. */\n groupingModes?: Array<DataTableGroupingMode<T>>;\n /** Controlled grouping-mode value. Requires `onGroupingModeChange`. */\n groupingMode?: string;\n /** Initial grouping mode when DataTable owns the picker state. */\n defaultGroupingMode?: string;\n /** Called when the native grouping picker changes. */\n onGroupingModeChange?: (value: string) => void;\n /** Called when a clickable row is selected. */\n onRowClick?: (row: T) => void;\n /** Predicate controlling whether a row is clickable. */\n isRowClickable?: (row: T) => boolean;\n /** Optional href for row link affordances. */\n getRowHref?: (row: T) => string | undefined;\n /** Detail content rendered for expanded rows or dialog details. */\n renderExpandedRow?: (\n row: T,\n context: DataTableRowDetailContext<T>,\n ) => ReactNode;\n /**\n * How `renderExpandedRow` detail is surfaced when a row is clicked.\n * - \"row\" (default): expands an inline detail row beneath the clicked row.\n * Multiple rows can be open at once.\n * - \"dialog\": opens the detail content in a centered modal; one row at a\n * time. The same `renderExpandedRow` (and its context) drives both styles.\n */\n detailStyle?: \"row\" | \"dialog\";\n /**\n * Title for the detail dialog (detailStyle=\"dialog\"). Pass a function to\n * derive a per-row title, e.g. `(row) => \\`Session ${row.sessionId}\\``.\n */\n detailDialogTitle?: ReactNode | ((row: T) => ReactNode);\n /** Modal size for the detail dialog. Defaults to \"lg\". */\n detailDialogSize?: ModalSize;\n /** Enables column drag resize handles. */\n resizableColumns?: boolean;\n /** Persists column widths to localStorage. */\n persistColumnWidths?: boolean;\n /** Storage key for persisted column widths. */\n columnResizeStorageKey?: string;\n /** Enables column visibility controls. */\n hideableColumns?: boolean;\n /** Persists column visibility to localStorage. */\n persistColumnVisibility?: boolean;\n /** Storage key for persisted column visibility. */\n columnVisibilityStorageKey?: string;\n /** Controlled row density. */\n density?: Density;\n /** Initial row density for uncontrolled usage. */\n defaultDensity?: Density;\n /** Called when density changes. */\n onDensityChange?: (density: Density | undefined) => void;\n /** Persists density to localStorage. */\n persistDensity?: boolean;\n /** Storage key for persisted density. */\n densityStorageKey?: string;\n /** Shows density controls in the column menu. */\n showDensityControl?: boolean;\n /**\n * Current value of the theme menu shown in the column / preferences popover.\n * The inner DataTable does not apply this value itself — it's the menu's\n * displayed selection. The outer `DataTable` wrapper manages this state and\n * paints a wrapper-level `data-theme`.\n */\n themeMenuValue?: Theme;\n onThemeChange?: (theme: Theme) => void;\n /** Shows theme controls in the column menu. */\n showThemeControl?: boolean;\n /** Shows per-column filter buttons in table headers. */\n showHeaderFilters?: boolean;\n /** Extra actions rendered in the table preferences menu. */\n menuActions?: DataTableMenuAction[];\n};\n\nexport type DataTableProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = Omit<DataTableInnerProps<T>, \"themeMenuValue\"> & {\n /**\n * Initial / controlled theme value for the column-menu Theme section.\n * When `onThemeChange` is omitted, the DataTable manages this internally\n * (seeded from `theme`) and applies `data-theme` to its root so the table\n * reflects the choice without requiring an enclosing `<ThemeProvider>`.\n */\n theme?: Theme;\n /**\n * Render a fullscreen-toggle button in the FilterBar's trailing slot\n * (just before the column-menu trigger). When clicked, the table re-renders\n * inside a full-viewport `<Modal>`. Defaults to `false`.\n */\n showFullscreenControl?: boolean;\n /** Title shown in the fullscreen modal. */\n fullscreenTitle?: ReactNode;\n /**\n * `aria-label` and `title` for the fullscreen toggle button. Defaults to\n * \"Open table full screen\". LogsTable overrides to \"Open logs full screen\".\n */\n fullscreenButtonLabel?: string;\n};\n\nfunction assertDataTableGroupingProps<T>({\n grouping,\n groupingModes,\n groupingMode,\n defaultGroupingMode,\n onGroupingModeChange,\n}: {\n grouping: DataTableGrouping<T> | undefined;\n groupingModes: Array<DataTableGroupingMode<T>> | undefined;\n groupingMode: string | undefined;\n defaultGroupingMode: string | undefined;\n onGroupingModeChange: ((value: string) => void) | undefined;\n}) {\n if (grouping && groupingModes) {\n throw new Error(\"DataTable accepts grouping or groupingModes, not both\");\n }\n if (!groupingModes) {\n if (groupingMode !== undefined || defaultGroupingMode !== undefined) {\n throw new Error(\"DataTable groupingMode values require groupingModes\");\n }\n return;\n }\n if (groupingModes.length === 0) {\n throw new Error(\"DataTable groupingModes must not be empty\");\n }\n const values = new Set(groupingModes.map((mode) => mode.value));\n if (values.size !== groupingModes.length) {\n throw new Error(\"DataTable groupingModes values must be unique\");\n }\n if (groupingMode !== undefined && !onGroupingModeChange) {\n throw new Error(\n \"DataTable controlled groupingMode requires onGroupingModeChange\",\n );\n }\n if (groupingMode !== undefined && defaultGroupingMode !== undefined) {\n throw new Error(\n \"DataTable cannot combine groupingMode with defaultGroupingMode\",\n );\n }\n const selected = groupingMode ?? defaultGroupingMode;\n if (selected !== undefined && !values.has(selected)) {\n throw new Error(`DataTable grouping mode \"${selected}\" does not exist`);\n }\n}\n\nfunction DataTableInner<T extends Record<string, unknown>>({\n data,\n error,\n columns: columnsInput,\n loading = false,\n loadingMessage = \"Loading results…\",\n loadingRowCount = 8,\n emptyMessage = \"No data\",\n clientReveal,\n className,\n scrollContainerClassName,\n autoFilter = false,\n showGlobalFilter,\n manualFilter = false,\n globalFilter,\n onGlobalFilterChange,\n globalFilterPlaceholder = \"Search all columns…\",\n defaultSort,\n sort: controlledSort,\n onSortChange,\n manualSort = false,\n filterBarProps,\n externalSearch,\n externalTimeRange,\n externalFilters,\n cellFilters,\n onCellFilterChange,\n pagination,\n infinite,\n scrollContainerRef,\n getRowId,\n rowSelection,\n selectionActions,\n selectionBar: selectionBarPlacement = \"toolbar\",\n getRowClassName,\n footer,\n grouping,\n groupingModes,\n groupingMode,\n defaultGroupingMode,\n onGroupingModeChange,\n onRowClick,\n isRowClickable,\n getRowHref,\n renderExpandedRow,\n detailStyle = \"row\",\n detailDialogTitle,\n detailDialogSize = \"lg\",\n resizableColumns = true,\n persistColumnWidths = true,\n columnResizeStorageKey,\n hideableColumns = true,\n persistColumnVisibility = true,\n columnVisibilityStorageKey,\n density,\n defaultDensity,\n onDensityChange,\n persistDensity = true,\n densityStorageKey,\n showDensityControl,\n themeMenuValue,\n onThemeChange,\n showThemeControl = false,\n showHeaderFilters = true,\n menuActions,\n}: DataTableInnerProps<T>) {\n assertDataTableGroupingProps({\n grouping,\n groupingModes,\n groupingMode,\n defaultGroupingMode,\n onGroupingModeChange,\n });\n const columns = useMemo<DataTableColumn<T>[]>(\n () =>\n columnsInput.map((column) =>\n typeof column === \"string\" ? { key: column, label: column } : column,\n ),\n [columnsInput],\n );\n const columnKeysSignature = useMemo(\n () => columns.map((column) => column.key).join(\"|\"),\n [columns],\n );\n const resolvedColumnResizeStorageKey =\n columnResizeStorageKey ??\n `${COLUMN_WIDTH_STORAGE_PREFIX}:${columnKeysSignature}`;\n const resolvedColumnVisibilityStorageKey =\n columnVisibilityStorageKey ??\n `${COLUMN_VISIBILITY_STORAGE_PREFIX}:${columnKeysSignature}`;\n const resolvedDensityStorageKey =\n densityStorageKey ?? `${DENSITY_STORAGE_PREFIX}:${columnKeysSignature}`;\n const [columnWidths, setColumnWidths] = useState<Record<string, number>>(\n () =>\n persistColumnWidths\n ? readStoredColumnWidths(resolvedColumnResizeStorageKey, columns)\n : {},\n );\n const [hiddenColumns, setHiddenColumns] = useState<Record<string, boolean>>(\n () =>\n persistColumnVisibility\n ? readStoredHiddenColumns(resolvedColumnVisibilityStorageKey, columns)\n : {},\n );\n const densityControlled = density !== undefined;\n const [localDensityOverride, setLocalDensityOverride] = useState<\n Density | undefined\n >(() => {\n if (densityControlled) return density;\n if (persistDensity)\n return (\n readStoredDensityOverride(resolvedDensityStorageKey) ?? defaultDensity\n );\n return defaultDensity;\n });\n const [columnMenu, setColumnMenu] = useState<ColumnMenuState | null>(null);\n const [headerFilterMenu, setHeaderFilterMenu] =\n useState<ColumnMenuState | null>(null);\n const [textFilters, setTextFilters] = useState<Record<string, string>>({});\n const [multiFilters, setMultiFilters] = useState<\n Record<string, Record<string, FilterBarMultiFilterMode>>\n >({});\n const [numberFilters, setNumberFilters] = useState<\n Record<string, FilterBarNumberValue>\n >({});\n const [expandedRows, setExpandedRows] = useState<Record<string, boolean>>({});\n const [detailRow, setDetailRow] = useState<InternalRow<T> | null>(null);\n const [localGroupingMode, setLocalGroupingMode] = useState<\n string | undefined\n >(defaultGroupingMode);\n const [localGlobalFilter, setLocalGlobalFilter] = useState(\"\");\n const [timeRangeFilter, setTimeRangeFilter] = useState<{\n from: string;\n to: string;\n }>(() => {\n const seed = columns.find(\n (column) => column.kind === \"timestamp\" && column.timestamp?.defaultRange,\n );\n return {\n from: seed?.timestamp?.defaultRange?.from ?? \"\",\n to: seed?.timestamp?.defaultRange?.to ?? \"\",\n };\n });\n\n useEffect(() => {\n setColumnWidths((current) => {\n const stored = persistColumnWidths\n ? readStoredColumnWidths(resolvedColumnResizeStorageKey, columns)\n : {};\n const next = pruneColumnWidths({ ...stored, ...current }, columns);\n return sameColumnWidths(current, next) ? current : next;\n });\n }, [\n columnKeysSignature,\n persistColumnWidths,\n resolvedColumnResizeStorageKey,\n ]);\n\n useEffect(() => {\n if (!persistColumnWidths) return;\n writeStoredColumnWidths(resolvedColumnResizeStorageKey, columnWidths);\n }, [columnWidths, persistColumnWidths, resolvedColumnResizeStorageKey]);\n\n useEffect(() => {\n setHiddenColumns((current) => {\n const stored = persistColumnVisibility\n ? readStoredHiddenColumns(resolvedColumnVisibilityStorageKey, columns)\n : {};\n const next = pruneHiddenColumns({ ...stored, ...current }, columns);\n return sameHiddenColumns(current, next) ? current : next;\n });\n }, [\n columnKeysSignature,\n persistColumnVisibility,\n resolvedColumnVisibilityStorageKey,\n ]);\n\n useEffect(() => {\n if (!persistColumnVisibility) return;\n writeStoredHiddenColumns(resolvedColumnVisibilityStorageKey, hiddenColumns);\n }, [\n hiddenColumns,\n persistColumnVisibility,\n resolvedColumnVisibilityStorageKey,\n ]);\n\n useEffect(() => {\n if (densityControlled) return;\n setLocalDensityOverride(\n persistDensity\n ? (readStoredDensityOverride(resolvedDensityStorageKey) ??\n defaultDensity)\n : defaultDensity,\n );\n }, [\n defaultDensity,\n densityControlled,\n persistDensity,\n resolvedDensityStorageKey,\n ]);\n\n useEffect(() => {\n if (densityControlled || !persistDensity) return;\n writeStoredDensityOverride(resolvedDensityStorageKey, localDensityOverride);\n }, [\n densityControlled,\n localDensityOverride,\n persistDensity,\n resolvedDensityStorageKey,\n ]);\n\n const closeFloatingMenus = useCallback(() => {\n setColumnMenu(null);\n setHeaderFilterMenu(null);\n }, []);\n\n useEscapeLayer(Boolean(columnMenu || headerFilterMenu), closeFloatingMenus);\n\n useEffect(() => {\n if (!columnMenu && !headerFilterMenu) return;\n document.addEventListener(\"click\", closeFloatingMenus);\n return () => {\n document.removeEventListener(\"click\", closeFloatingMenus);\n };\n }, [closeFloatingMenus, columnMenu, headerFilterMenu]);\n\n const rows = useMemo<InternalRow<T>[]>(\n () =>\n data.map((row, index) => ({\n id: getRowId?.(row, index) ?? String(index),\n row,\n })),\n [data, getRowId],\n );\n\n const timestampFormats = useMemo<Record<string, TimestampFormat>>(() => {\n const out: Record<string, TimestampFormat> = {};\n for (const column of columns) {\n if (column.kind !== \"timestamp\") continue;\n const dates: Date[] = [];\n for (const row of data) {\n const raw = resolveColumnValue(row, column);\n const parsed = parseTimestamp(raw);\n if (parsed) dates.push(parsed);\n }\n const dataFormat = chooseTimestampFormat(dates);\n out[column.key] = modeToFormat(\n column.timestamp?.mode ?? \"auto\",\n dataFormat,\n );\n }\n return out;\n }, [columns, data]);\n\n const effectiveColumns = useMemo<DataTableColumn<T>[]>(\n () =>\n columns.map((column) =>\n applyKindDefaults<T>(column, timestampFormats[column.key]),\n ),\n [columns, timestampFormats],\n );\n const activeGroupingModeValue =\n groupingMode ??\n localGroupingMode ??\n defaultGroupingMode ??\n groupingModes?.[0]?.value;\n const activeGroupingMode = groupingModes?.find(\n (mode) => mode.value === activeGroupingModeValue,\n );\n const effectiveGrouping = useMemo<DataTableGrouping<T> | undefined>(() => {\n if (!activeGroupingMode) return grouping;\n if (activeGroupingMode.type === \"none\") return undefined;\n if (activeGroupingMode.type === \"custom\") return activeGroupingMode;\n\n const column = effectiveColumns.find(\n (candidate) => candidate.key === activeGroupingMode.columnKey,\n );\n if (!column) {\n throw new Error(\n `DataTable grouping mode \"${activeGroupingMode.value}\" references missing column \"${activeGroupingMode.columnKey}\"`,\n );\n }\n return {\n ...activeGroupingMode,\n getGroupKey: (row) => dataTableGroupKey(resolveColumnValue(row, column)),\n // `emptyGroupLabel` is a header label, never a key — resolving it here\n // keeps rows with no value apart from rows whose value happens to read\n // like the label.\n getGroupLabel: (key, rows) => {\n const custom = activeGroupingMode.getGroupLabel?.(key, rows);\n return custom !== undefined\n ? custom\n : dataTableGroupLabel(key, activeGroupingMode.emptyGroupLabel);\n },\n };\n }, [activeGroupingMode, effectiveColumns, grouping]);\n\n const visibleColumns = useMemo(() => {\n if (!hideableColumns) return effectiveColumns;\n const next = effectiveColumns.filter(\n (column) => !hiddenColumns[column.key],\n );\n return next.length > 0 ? next : effectiveColumns;\n }, [effectiveColumns, hiddenColumns, hideableColumns]);\n\n const hideableColumnCount = useMemo(\n () => effectiveColumns.filter(isColumnHideable).length,\n [effectiveColumns],\n );\n\n const visibleHideableColumnCount = useMemo(\n () => visibleColumns.filter(isColumnHideable).length,\n [visibleColumns],\n );\n\n const showColumnVisibilityControl =\n hideableColumns && hideableColumnCount > 1;\n const resolvedShowDensityControl =\n showDensityControl ?? showColumnVisibilityControl;\n const hasMenuActions = Boolean(menuActions && menuActions.length > 0);\n const showTablePreferencesControl =\n showColumnVisibilityControl ||\n resolvedShowDensityControl ||\n showThemeControl ||\n hasMenuActions;\n const densityOverride = densityControlled ? density : localDensityOverride;\n\n // The first kind:\"timestamp\" column (with autoRangeFilter not disabled) owns\n // the FilterBar's trailing range slot — filled either by the column's own\n // server filter or, when nothing backs it, by a locally narrowed picker.\n const rangeCapableColumn = useMemo(\n () =>\n effectiveColumns.find(\n (column) =>\n column.kind === \"timestamp\" &&\n column.filterable !== false &&\n column.timestamp?.autoRangeFilter !== false,\n ) ?? null,\n [effectiveColumns],\n );\n // The auto range narrows rows here, so it only mounts where DataTable owns\n // filtering. On a source-filtered table the picker would re-filter rows the\n // source already answered with — and the timestamp cell it reads is often a\n // rendered node rather than a value, so it would silently empty the table.\n const timeRangeColumn = useMemo(() => {\n if (\n !autoFilter ||\n manualFilter ||\n externalTimeRange ||\n filterBarProps?.timeRange\n ) {\n return null;\n }\n return rangeCapableColumn;\n }, [\n autoFilter,\n externalTimeRange,\n filterBarProps?.timeRange,\n manualFilter,\n rangeCapableColumn,\n ]);\n\n const filterableColumns = useMemo(\n () =>\n effectiveColumns.filter((column) => {\n if (column.filterable === false) return false;\n // Timestamp columns are filtered through the time-range picker, not\n // a per-column text/multi filter. Skip them in auto-filter generation.\n if (column.kind === \"timestamp\") return false;\n return true;\n }),\n [effectiveColumns],\n );\n\n const generatedFilters = useMemo<GeneratedFilter<T>[]>(() => {\n if (!autoFilter || loading) return [];\n\n return filterableColumns.map((column) => {\n const numberBounds = getNumericFilterBounds(rows, column);\n if (numberBounds) {\n return {\n column,\n kind: \"number\" as const,\n options: [],\n numberBounds,\n };\n }\n\n const values = new Set<string>();\n\n for (const record of rows) {\n for (const token of getFilterTokens(record.row, column)) {\n if (token) values.add(token);\n }\n }\n\n const options = Array.from(values)\n .sort((left, right) =>\n left.localeCompare(right, undefined, { numeric: true }),\n )\n .map((value) => ({ value, label: value }));\n\n // Tag columns naturally have higher cardinality (e.g. infra labels);\n // we let the multi-filter scale to 50 distinct values before falling\n // back to free-text search.\n const multiCap = column.kind === \"tags\" ? 50 : 20;\n\n const fitsMulti = options.length >= 2 && options.length <= multiCap;\n\n // For tag columns we group tokens by their key so the filter renders\n // as a two-level submenu (env → prod/staging, tier → edge/core, …).\n // Falls back to a flat multi when there's only one key (or none).\n if (column.kind === \"tags\" && fitsMulti) {\n const separator = column.tags?.separator ?? \"=\";\n const groups = groupTagOptions(options, separator);\n if (groups.length >= 2) {\n return {\n column,\n kind: \"nested-multi\" as const,\n options,\n groups,\n };\n }\n }\n\n return {\n column,\n kind: fitsMulti ? \"multi\" : \"text\",\n options,\n };\n });\n }, [autoFilter, filterableColumns, loading, rows]);\n\n // For every multi / nested-multi column (which includes kind:\"tags\"), expose a\n // TagActions value backed by this table's multiFilters slot. The + / − icons in\n // tag cells and in expanded-row details mutate the same Record<token, mode>\n // shape the filter-bar dropdown uses, so the existing filter pipeline picks up\n // the change. Built from generatedFilters so it stays in lockstep with\n // pruneMultiFilterState (only multi/nested-multi columns honor multiFilters).\n const filterActionsByColumn = useMemo(() => {\n const out: Record<string, TagActionsContextValue> = {};\n for (const filter of generatedFilters) {\n if (filter.kind !== \"multi\" && filter.kind !== \"nested-multi\") continue;\n const columnKey = filter.column.key;\n const current = (multiFilters[columnKey] ?? {}) as Record<\n string,\n TagFilterMode\n >;\n const handler = (next: Record<string, TagFilterMode>) =>\n setMultiFilters((state) => updateFilterRecord(state, columnKey, next));\n out[columnKey] = tagActionsFromRecord(current, handler);\n }\n return out;\n }, [generatedFilters, multiFilters]);\n\n useEffect(() => {\n setTextFilters((current) =>\n pruneTextFilterState(current, generatedFilters),\n );\n setMultiFilters((current) =>\n pruneMultiFilterState(current, generatedFilters),\n );\n setNumberFilters((current) =>\n pruneNumberFilterState(current, generatedFilters),\n );\n }, [generatedFilters]);\n\n const globalFilterControlled = globalFilter !== undefined;\n const effectiveGlobalFilter = globalFilterControlled\n ? globalFilter\n : localGlobalFilter;\n const setEffectiveGlobalFilter = globalFilterControlled\n ? (onGlobalFilterChange ?? (() => {}))\n : setLocalGlobalFilter;\n const nativeFilters = useMemo<FilterBarFilter[]>(\n () =>\n generatedFilters.map((filter): FilterBarFilter => {\n const columnKey = filter.column.key;\n if (filter.kind === \"multi\") {\n return {\n key: columnKey,\n kind: \"multi\",\n label: labelText(filter.column),\n value: multiFilters[columnKey] ?? {},\n onChange: (next) =>\n setMultiFilters((current) =>\n updateFilterRecord(current, columnKey, next),\n ),\n options: filter.options,\n };\n }\n if (filter.kind === \"nested-multi\") {\n return {\n key: columnKey,\n kind: \"nested-multi\",\n label: labelText(filter.column),\n value: multiFilters[columnKey] ?? {},\n onChange: (next) =>\n setMultiFilters((current) =>\n updateFilterRecord(current, columnKey, next),\n ),\n groups: filter.groups ?? [],\n };\n }\n if (filter.kind === \"number\") {\n const numberFilter: Extract<FilterBarFilter, { kind: \"number\" }> = {\n key: columnKey,\n kind: \"number\",\n label: labelText(filter.column),\n value: numberFilters[columnKey] ?? {},\n onChange: (next: FilterBarNumberValue) =>\n setNumberFilters((current) =>\n updateNumberFilterValue(current, columnKey, next),\n ),\n };\n if (filter.numberBounds?.min !== undefined) {\n numberFilter.domainMin = filter.numberBounds.min;\n }\n if (filter.numberBounds?.max !== undefined) {\n numberFilter.domainMax = filter.numberBounds.max;\n }\n if (filter.numberBounds?.step !== undefined) {\n numberFilter.step = filter.numberBounds.step;\n }\n return numberFilter;\n }\n return {\n key: columnKey,\n kind: \"text\",\n label: labelText(filter.column),\n value: textFilters[columnKey] ?? \"\",\n onChange: (next: string) =>\n setTextFilters((current) =>\n updateFilterValue(current, columnKey, next),\n ),\n };\n }),\n [generatedFilters, multiFilters, numberFilters, textFilters],\n );\n const serverFilterByKey = useMemo(\n () =>\n new Map((externalFilters ?? []).map((filter) => [filter.key, filter])),\n [externalFilters],\n );\n // The timestamp column's own bound, when the caller supplies one, IS the\n // bar's range — so it is hoisted out of the filter list into the trailing\n // slot. Leaving it among the chips and mounting the column-derived picker\n // beside it would put two controls on one filter, and only one of them\n // reaches the source.\n //\n // Keyed on the FilterBar kind rather than any upstream control name: a\n // whole-day bound (\"day-range\" on the wire) is normalized to the same\n // \"date-range\" kind with timeEnabled off, and belongs in the same slot.\n const serverTimeRangeFilter = useMemo(() => {\n const key = rangeCapableColumn?.filterKey;\n const filter = key ? serverFilterByKey.get(key) : undefined;\n return filter?.kind === \"date-range\" ? filter : null;\n }, [rangeCapableColumn, serverFilterByKey]);\n // A header filter button comes from whichever pipeline owns the column:\n // autoFilter's generated filter (keyed by column.key) or a caller-supplied\n // server filter bound through the column's `filterKey` — the same key\n // `cellFilters` is already indexed by, so the include/exclude cell actions\n // and the header popover address one filter rather than two.\n const headerFilterByColumn = useMemo(() => {\n const bound = new Map<string, FilterBarFilter>();\n for (const column of effectiveColumns) {\n const native = nativeFilters.find((filter) => filter.key === column.key);\n if (native) {\n bound.set(column.key, native);\n continue;\n }\n const server = column.filterKey\n ? serverFilterByKey.get(column.filterKey)\n : undefined;\n // The hoisted range is rendered as a range in this column's header, not\n // as a chip, so it must not be bound here as well.\n if (server && server !== serverTimeRangeFilter)\n bound.set(column.key, server);\n }\n return bound;\n }, [\n effectiveColumns,\n nativeFilters,\n serverFilterByKey,\n serverTimeRangeFilter,\n ]);\n const hasCustomFilterBarContent = Boolean(\n filterBarProps?.leading ||\n filterBarProps?.children ||\n filterBarProps?.trailing ||\n filterBarProps?.timeRange ||\n filterBarProps?.dateRange,\n );\n const autoTimeRange = useMemo<FilterBarRangeProps | null>(() => {\n if (!timeRangeColumn) return null;\n const next: FilterBarRangeProps = {\n from: timeRangeFilter.from,\n to: timeRangeFilter.to,\n onApply: (from, to) => setTimeRangeFilter({ from, to }),\n presets:\n timeRangeColumn.timestamp?.rangePresets ?? TIMESTAMP_RANGE_PRESETS,\n fromPlaceholder: \"now-24h\",\n toPlaceholder: \"now\",\n emptyLabel: \"Any time\",\n };\n if (timeRangeColumn.timestamp?.timeEnabled !== undefined) {\n next.timeEnabled = timeRangeColumn.timestamp.timeEnabled;\n }\n if (timeRangeColumn.timestamp?.timeZone) {\n next.timeZone = timeRangeColumn.timestamp.timeZone;\n }\n if (timeRangeColumn.timestamp?.timeZones) {\n next.timeZones = timeRangeColumn.timestamp.timeZones;\n }\n return next;\n }, [timeRangeColumn, timeRangeFilter.from, timeRangeFilter.to]);\n // The one range a column owns, and which column's header renders it. The\n // hoisted server bound wins over the local picker; a caller-supplied range\n // belongs to no column and so wins over both, in the bar only.\n const columnTimeRange = useMemo<{\n key: string;\n range: FilterBarRangeProps;\n } | null>(() => {\n if (serverTimeRangeFilter && rangeCapableColumn) {\n return {\n key: rangeCapableColumn.key,\n range: dateRangeFilterProps(serverTimeRangeFilter),\n };\n }\n if (autoTimeRange && timeRangeColumn) {\n return { key: timeRangeColumn.key, range: autoTimeRange };\n }\n return null;\n }, [\n autoTimeRange,\n rangeCapableColumn,\n serverTimeRangeFilter,\n timeRangeColumn,\n ]);\n const barTimeRange = externalTimeRange ?? columnTimeRange?.range ?? null;\n const barFilters = useMemo(() => {\n const external = (externalFilters ?? []).filter(\n (filter) => filter !== serverTimeRangeFilter,\n );\n return external.length > 0\n ? [...external, ...nativeFilters]\n : nativeFilters;\n }, [externalFilters, nativeFilters, serverTimeRangeFilter]);\n // The built-in search narrows rows here, so it mounts by default only where\n // DataTable already owns filtering. An explicit value still wins, which is\n // what lets a source-filtered table search its own page.\n const resolvedShowGlobalFilter = showGlobalFilter ?? autoFilter;\n assertDataTableFilterProps({\n autoFilter,\n manualFilter,\n showGlobalFilter: resolvedShowGlobalFilter,\n globalFilterControlled:\n globalFilter !== undefined || onGlobalFilterChange !== undefined,\n hasExternalSearch: externalSearch !== undefined,\n });\n const showFilterBar =\n resolvedShowGlobalFilter ||\n nativeFilters.length > 0 ||\n !!barTimeRange ||\n !!externalSearch ||\n (externalFilters && externalFilters.length > 0) ||\n hasCustomFilterBarContent ||\n !!groupingModes ||\n showTablePreferencesControl;\n const setDensityOverride = (next: Density | undefined) => {\n if (!densityControlled) setLocalDensityOverride(next);\n onDensityChange?.(next);\n };\n const showHeaderFilterControls =\n showHeaderFilters && (headerFilterByColumn.size > 0 || !!columnTimeRange);\n\n const filteredRows = useMemo(() => {\n // The source already applied every filter, so applying them again here\n // would narrow rows a second time and show fewer than were asked for.\n if (manualFilter) return rows;\n const globalNeedle = effectiveGlobalFilter.trim().toLowerCase();\n const now = new Date();\n const rangeFromDate = timeRangeColumn\n ? resolveDateMath(timeRangeFilter.from, now)\n : null;\n const rangeToDate = timeRangeColumn\n ? resolveDateMath(timeRangeFilter.to, now)\n : null;\n return rows.filter(({ row }) => {\n if (timeRangeColumn && (rangeFromDate || rangeToDate)) {\n // Through the column, not the raw path: a cell is often a rendered\n // node (clicky results address `cells.<name>` and carry a ClickyNode\n // there), which parses to null and would drop every row.\n const ts = parseTimestamp(getFilterCandidate(row, timeRangeColumn));\n if (!ts) return false;\n if (rangeFromDate && ts.getTime() < rangeFromDate.getTime())\n return false;\n if (rangeToDate && ts.getTime() > rangeToDate.getTime()) return false;\n }\n\n if (globalNeedle) {\n const haystack = filterableColumns\n .flatMap((column) => getFilterTokens(row, column))\n .join(\" \")\n .toLowerCase();\n\n if (!haystack.includes(globalNeedle)) {\n return false;\n }\n }\n\n for (const filter of generatedFilters) {\n const tokens = getFilterTokens(row, filter.column);\n\n if (filter.kind === \"text\") {\n const needle = (textFilters[filter.column.key] ?? \"\")\n .trim()\n .toLowerCase();\n if (\n needle &&\n !tokens.some((token) => token.toLowerCase().includes(needle))\n ) {\n return false;\n }\n } else if (filter.kind === \"number\") {\n const range = numberFilters[filter.column.key] ?? {};\n const min = parseNumberInput(range.min);\n const max = parseNumberInput(range.max);\n const hasMin = String(range.min ?? \"\").trim() !== \"\";\n const hasMax = String(range.max ?? \"\").trim() !== \"\";\n\n if (hasMin || hasMax) {\n const values = getFilterNumbers(row, filter.column);\n const matches = values.some(\n (value) =>\n (min == null || value >= min) && (max == null || value <= max),\n );\n\n if (!matches) {\n return false;\n }\n }\n } else {\n const selected = multiFilters[filter.column.key] ?? {};\n const include = Object.entries(selected)\n .filter(([, mode]) => mode === \"include\")\n .map(([value]) => value);\n const exclude = Object.entries(selected)\n .filter(([, mode]) => mode === \"exclude\")\n .map(([value]) => value);\n\n if (\n include.length > 0 &&\n !tokens.some((token) => include.includes(token))\n ) {\n return false;\n }\n\n if (\n exclude.length > 0 &&\n tokens.some((token) => exclude.includes(token))\n ) {\n return false;\n }\n }\n }\n\n return true;\n });\n }, [\n effectiveGlobalFilter,\n filterableColumns,\n generatedFilters,\n manualFilter,\n multiFilters,\n numberFilters,\n rows,\n textFilters,\n timeRangeColumn,\n timeRangeFilter.from,\n timeRangeFilter.to,\n ]);\n\n const sortResolvers = useMemo(\n () =>\n Object.fromEntries(\n effectiveColumns.map((column) => [\n column.key,\n (record: InternalRow<T>) => getSortValue(record.row, column),\n ]),\n ) as Record<string, (record: InternalRow<T>) => unknown>,\n [effectiveColumns],\n );\n\n const { renderLink } = useRouter();\n\n const { sorted, sort, toggle } = useSort(filteredRows, {\n defaultDir: defaultSort?.dir ?? \"asc\",\n manual: manualSort,\n resolvers: sortResolvers,\n ...(controlledSort !== undefined ? { sort: controlledSort } : {}),\n ...(onSortChange ? { onSortChange } : {}),\n ...(defaultSort?.key ? { defaultKey: defaultSort.key } : {}),\n });\n\n // Sorting one page of a server-paged result reorders that page and nothing\n // else, which reads as a sort of the whole table and is not one. Under server\n // paging the header therefore goes inert unless the caller wired the sort\n // through to the server, where the whole result set actually lives.\n //\n // Unless there is no other page. A single page holds the entire result, so\n // sorting it is sorting the table and the objection does not apply. Infinite\n // scroll is the same question asked of the run so far: rows still to be\n // fetched are rows this sort would not have seen.\n const pageLocalSort =\n !!pagination &&\n !onSortChange &&\n !(isSinglePage(pagination, data.length) && !infinite?.hasMore);\n\n // Client-side incremental reveal: when `clientReveal` is set (and the caller\n // is not doing server pagination), only the first `visibleCount` sorted rows\n // are rendered; a trailing sentinel grows the window as it scrolls into view.\n // `infinite` is the same gesture aimed at the server rather than at memory, so\n // it takes the sentinel outright: windowing rows the caller just paid a\n // request for would hide them again the moment they arrived.\n const revealEnabled = !!clientReveal && !pagination && !infinite;\n const revealBatchSize = clientReveal?.batchSize ?? 0;\n const [visibleCount, setVisibleCount] = useState(revealBatchSize);\n const revealObserver = useRef<IntersectionObserver | null>(null);\n\n useEffect(() => {\n // Reset the window whenever the filtered/sorted set or batch size changes\n // so a new query starts from the top rather than mid-scroll.\n if (revealEnabled) setVisibleCount(revealBatchSize);\n }, [revealEnabled, revealBatchSize, sorted]);\n\n const visibleSorted = revealEnabled ? sorted.slice(0, visibleCount) : sorted;\n const hasMoreRows = revealEnabled && visibleCount < sorted.length;\n\n // Server-driven infinite scroll shares the sentinel and the observer with\n // `clientReveal`; only what an intersection means differs. Unlike the reveal\n // window it is not gated on `pagination` — a table paging the server is\n // precisely the one that has more to fetch — and it has no window to reset,\n // because the caller owns the accumulation and it only ever grows.\n const requestMoreRows = useInfiniteRows(infinite, data.length);\n const infiniteEnabled = !!infinite;\n const sentinelActive = infinite ? infinite.hasMore : hasMoreRows;\n // The sentinel names what it is waiting on. Client reveal holds the rows and\n // only has to paint them, so it is always mid-load; the server variant sits\n // idle until the reader reaches it, and announcing a fetch that has not\n // started reads as a table that is permanently busy.\n const sentinelLabel =\n !infinite || infinite.loading ? \"Loading more…\" : \"Scroll to load more…\";\n const selectedRowIDs = useMemo(\n () => new Set(rowSelection?.selectedRowIds ?? []),\n [rowSelection?.selectedRowIds],\n );\n const selectableVisibleRows = useMemo(\n () =>\n visibleSorted.filter(\n (record) => rowSelection?.isRowSelectable?.(record.row) ?? true,\n ),\n [rowSelection, visibleSorted],\n );\n const selectedVisibleCount = selectableVisibleRows.filter((record) =>\n selectedRowIDs.has(record.id),\n ).length;\n const allVisibleSelected =\n selectableVisibleRows.length > 0 &&\n selectedVisibleCount === selectableVisibleRows.length;\n const someVisibleSelected = selectedVisibleCount > 0 && !allVisibleSelected;\n const selectAllRef = useRef<HTMLInputElement>(null);\n const selectAllPages = rowSelection?.selectAllPages;\n // Scopes resolved against the pager, then read as a ladder: the sentence\n // measures the selection against the widest scope, and the button offers the\n // narrowest one the selection has not covered yet.\n const selectAllScopes = useMemo(\n () =>\n (selectAllPages?.scopes ?? []).flatMap((scope) => {\n const total = scope.total ?? pagination?.total;\n return total != null ? [{ ...scope, total }] : [];\n }),\n [pagination?.total, selectAllPages?.scopes],\n );\n const widestScope = selectAllScopes[selectAllScopes.length - 1];\n // The offer waits until the whole page is selected: \"select all 3,706\" beside\n // three ticked rows invites a click nobody meant to make. The count itself\n // shows for any selection, so the actions never have to restate it.\n const nextScope = allVisibleSelected\n ? selectAllScopes.find((scope) => scope.total > selectedRowIDs.size)\n : undefined;\n const showSelectionScope = !!widestScope && selectedRowIDs.size > 0;\n\n useEffect(() => {\n if (selectAllRef.current) {\n selectAllRef.current.indeterminate = someVisibleSelected;\n }\n }, [someVisibleSelected]);\n\n const notifySelection = useCallback(\n (nextIDs: Set<string>) => {\n if (!rowSelection) return;\n rowSelection.onSelectionChange(\n Array.from(nextIDs),\n rows\n .filter((record) => nextIDs.has(record.id))\n .map((record) => record.row),\n );\n },\n [rowSelection, rows],\n );\n\n const toggleRowSelection = useCallback(\n (record: InternalRow<T>) => {\n if (!rowSelection) return;\n if (rowSelection.isRowSelectable?.(record.row) === false) return;\n const next = new Set(selectedRowIDs);\n if (next.has(record.id)) next.delete(record.id);\n else next.add(record.id);\n notifySelection(next);\n },\n [notifySelection, rowSelection, selectedRowIDs],\n );\n\n const toggleVisibleSelection = useCallback(() => {\n if (!rowSelection) return;\n const next = new Set(selectedRowIDs);\n if (allVisibleSelected) {\n for (const record of selectableVisibleRows) next.delete(record.id);\n } else {\n for (const record of selectableVisibleRows) next.add(record.id);\n }\n notifySelection(next);\n }, [\n allVisibleSelected,\n notifySelection,\n rowSelection,\n selectableVisibleRows,\n selectedRowIDs,\n ]);\n\n const selectionContext = useMemo<DataTableSelectionContext<T> | null>(() => {\n if (!rowSelection || selectedRowIDs.size === 0) return null;\n return {\n // The ids are the caller's, not the page's. A cross-page selection covers\n // rows this table never fetched, and an action about to say what it will\n // touch needs all of them; `selectedRows` is only the ones on hand.\n // Filtering the ids down to loaded rows instead would make the whole\n // cluster vanish at the moment the selection got big enough to matter.\n selectedRowIds: Array.from(selectedRowIDs),\n selectedRows: rows\n .filter((record) => selectedRowIDs.has(record.id))\n .map((record) => record.row),\n clearSelection: () => notifySelection(new Set()),\n };\n }, [notifySelection, rowSelection, rows, selectedRowIDs]);\n\n // The render-prop form keeps its own path: it is the caller's markup, and the\n // table has nothing to add to it.\n const selectionBar = useMemo(() => {\n if (!selectionContext || typeof selectionActions !== \"function\")\n return null;\n return selectionActions(selectionContext);\n }, [selectionActions, selectionContext]);\n\n const descriptorSelectionActions = Array.isArray(selectionActions)\n ? selectionActions\n : null;\n\n // Requiring the descriptor form is what makes the takeover safe to default\n // on for anyone who asks for it: a table with only `selectAllPages`, and\n // every render-prop caller, keeps the toolbar placement untouched.\n const selectionTakeover =\n error == null &&\n selectionBarPlacement === \"takeover\" &&\n !!selectionContext &&\n !!descriptorSelectionActions;\n\n const selectionCluster =\n selectionContext && descriptorSelectionActions ? (\n <SelectionActionBar\n actions={descriptorSelectionActions}\n context={selectionContext}\n // The scope notice already carries the count and the Clear; two of each\n // in one row reads as two selections.\n showCount={!showSelectionScope}\n className=\"flex flex-wrap items-center gap-density-2\"\n />\n ) : (\n selectionBar\n );\n\n const renderedFooter =\n error != null\n ? null\n : footer !== undefined\n ? typeof footer === \"function\"\n ? footer({\n visibleRowCount: sorted.length,\n totalRowCount: data.length,\n loading,\n })\n : footer\n : pagination\n ? null\n : loading && sorted.length === 0\n ? loadingMessage\n : `${sorted.length} of ${data.length} row${data.length === 1 ? \"\" : \"s\"}`;\n\n const [collapseStateByMode, setCollapseStateByMode] = useState<\n Record<string, GroupCollapseState>\n >({});\n const collapseStateKey = activeGroupingMode\n ? `mode:${activeGroupingMode.value}`\n : \"fixed\";\n const collapseState = collapseStateByMode[collapseStateKey];\n const groups = useMemo(() => {\n if (!effectiveGrouping) return null;\n const buckets = groupRecords(visibleSorted, (record) =>\n effectiveGrouping.getGroupKey(record.row),\n );\n const resolved = buckets.map((bucket) => ({\n key: bucket.key,\n records: bucket.rows,\n rows: bucket.rows.map((record) => record.row),\n }));\n if (effectiveGrouping.compareGroups) {\n resolved.sort((a, b) => effectiveGrouping.compareGroups!(a, b));\n }\n return resolved.map((group) => ({\n ...group,\n label:\n effectiveGrouping.getGroupLabel?.(group.key, group.rows) ?? group.key,\n meta: effectiveGrouping.getGroupMeta?.(group.key, group.rows),\n collapsed:\n collapseState?.groups[group.key] ??\n collapseState?.all ??\n isGroupCollapsedByDefault(group, effectiveGrouping.defaultCollapsed),\n }));\n }, [collapseState, effectiveGrouping, visibleSorted]);\n\n const hasGroups = !!groups?.length;\n const allGroupsExpanded =\n hasGroups && groups.every((group) => !group.collapsed);\n const allGroupsCollapsed =\n hasGroups && groups.every((group) => group.collapsed);\n const setAllGroupsCollapsed = (collapsed: boolean) => {\n setCollapseStateByMode((current) => ({\n ...current,\n [collapseStateKey]: { all: collapsed, groups: {} },\n }));\n };\n // The selection cluster rides in the toolbar beside the table menu: it is\n // about the rows in this table, and a reader who has just ticked a box is\n // already looking at the top of it. Scope first, then the caller's actions,\n // then the table's own controls.\n const selectionToolbar =\n !selectionTakeover &&\n error == null &&\n (showSelectionScope || selectionCluster) ? (\n <div\n data-testid=\"data-table-selection-actions\"\n className=\"flex flex-wrap items-center gap-density-2\"\n >\n {showSelectionScope && widestScope ? (\n <SelectionScopeNotice\n noun={selectAllPages?.noun ?? \"rows\"}\n {...(selectAllPages?.loading ? { loading: true } : {})}\n total={widestScope.total}\n selectedCount={selectedRowIDs.size}\n {...(nextScope ? { nextScope } : {})}\n onClear={() => notifySelection(new Set())}\n />\n ) : null}\n {selectionCluster}\n </div>\n ) : null;\n // The table's own view controls — grouping, columns, and whatever the caller\n // put in `trailing` (the fullscreen button among them). They follow the bar\n // into a takeover rather than being hidden with the filters: regrouping does\n // not invalidate an id-keyed selection, and losing fullscreen the moment a\n // box is ticked is a regression, not a simplification. It is the *filters*\n // that go quiet, because those are what would change what \"select all\n // matching\" means underneath the reader.\n const tableControls =\n filterBarProps?.trailing || groupingModes || showTablePreferencesControl ? (\n <>\n {filterBarProps?.trailing}\n {groupingModes ? (\n <DataTableGroupingControls\n modes={groupingModes}\n value={activeGroupingModeValue!}\n hasGroups={hasGroups}\n allExpanded={allGroupsExpanded}\n allCollapsed={allGroupsCollapsed}\n onModeChange={(value) => {\n if (groupingMode === undefined) setLocalGroupingMode(value);\n onGroupingModeChange?.(value);\n }}\n onExpandAll={() => setAllGroupsCollapsed(false)}\n onCollapseAll={() => setAllGroupsCollapsed(true)}\n />\n ) : null}\n {showTablePreferencesControl ? (\n <ColumnVisibilityTrigger\n onOpen={(event) => setColumnMenu(menuStateFromTrigger(event))}\n />\n ) : null}\n </>\n ) : undefined;\n\n const filterBarTrailing =\n selectionToolbar || tableControls ? (\n <>\n {selectionToolbar}\n {tableControls}\n </>\n ) : undefined;\n\n // The bar that stands in for the filter row while a selection exists. It\n // carries the table's view controls at its far end, so the takeover costs\n // the reader nothing but the filters.\n const selectionBarNode = selectionTakeover ? (\n <div\n data-testid=\"data-table-selection-actions\"\n className=\"flex min-w-0 flex-1 flex-wrap items-center gap-density-2\"\n >\n {showSelectionScope && widestScope ? (\n <SelectionScopeNotice\n noun={selectAllPages?.noun ?? \"rows\"}\n {...(selectAllPages?.loading ? { loading: true } : {})}\n total={widestScope.total}\n selectedCount={selectedRowIDs.size}\n {...(nextScope ? { nextScope } : {})}\n onClear={() => notifySelection(new Set())}\n />\n ) : null}\n <SelectionActionBar\n actions={descriptorSelectionActions!}\n context={selectionContext!}\n showCount={!showSelectionScope}\n className=\"flex flex-wrap items-center gap-density-2\"\n />\n {tableControls ? (\n <div className=\"ml-auto flex shrink-0 flex-wrap items-center gap-2\">\n {tableControls}\n </div>\n ) : null}\n </div>\n ) : null;\n\n // Group headers and data rows share one flat stream so the <tbody> keeps a\n // single row renderer whether or not grouping is on.\n const rowStream = useMemo<Array<RowStreamItem<T>>>(() => {\n if (!groups) {\n return visibleSorted.map((record) => ({ kind: \"row\", record }) as const);\n }\n return groups.flatMap((group) => [\n { kind: \"group\", group } as const,\n ...(group.collapsed\n ? []\n : group.records.map((record) => ({ kind: \"row\", record }) as const)),\n ]);\n }, [groups, visibleSorted]);\n\n const toggleGroupSelection = useCallback(\n (records: InternalRow<T>[]) => {\n if (!rowSelection) return;\n const selectable = records.filter(\n (record) => rowSelection.isRowSelectable?.(record.row) ?? true,\n );\n const next = new Set(selectedRowIDs);\n const allSelected =\n selectable.length > 0 &&\n selectable.every((record) => next.has(record.id));\n for (const record of selectable) {\n if (allSelected) next.delete(record.id);\n else next.add(record.id);\n }\n notifySelection(next);\n },\n [notifySelection, rowSelection, selectedRowIDs],\n );\n\n const revealSentinelRef = useCallback(\n (node: HTMLTableRowElement | null) => {\n if (revealObserver.current) revealObserver.current.disconnect();\n if (!node || !sentinelActive) return;\n revealObserver.current = new IntersectionObserver(\n (entries) => {\n if (!entries[0]?.isIntersecting) return;\n if (infiniteEnabled) {\n requestMoreRows();\n return;\n }\n setVisibleCount((current) =>\n Math.min(current + revealBatchSize, sorted.length),\n );\n },\n { rootMargin: \"200px\" },\n );\n revealObserver.current.observe(node);\n },\n [\n infiniteEnabled,\n requestMoreRows,\n revealBatchSize,\n sentinelActive,\n sorted.length,\n ],\n );\n\n const startColumnResize = (\n event: ReactMouseEvent<HTMLElement>,\n column: DataTableColumn<T>,\n ) => {\n event.preventDefault();\n event.stopPropagation();\n\n const startX = event.clientX;\n const header = event.currentTarget.closest(\"th\");\n const measuredWidth = header?.getBoundingClientRect().width ?? 0;\n const startWidth =\n measuredWidth || columnWidths[column.key] || defaultColumnWidth(column);\n\n const onMove = (moveEvent: MouseEvent) => {\n const nextWidth = clampColumnWidth(\n column,\n startWidth + moveEvent.clientX - startX,\n );\n setColumnWidths((current) => ({\n ...current,\n [column.key]: nextWidth,\n }));\n };\n\n const onUp = () => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n };\n\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n };\n\n const autoFitColumn = (\n event: ReactMouseEvent<HTMLElement>,\n column: DataTableColumn<T>,\n ) => {\n event.preventDefault();\n event.stopPropagation();\n\n const header = event.currentTarget.closest(\"th\");\n const table = event.currentTarget.closest(\"table\");\n if (!header || !table) return;\n\n const columnIndex = Array.from(\n header.parentElement?.children ?? [],\n ).indexOf(header);\n if (columnIndex < 0) return;\n\n const width = measureColumnContentWidth(table, columnIndex, column);\n setColumnWidths((current) => ({\n ...current,\n [column.key]: width,\n }));\n };\n\n const toggleColumnVisibility = (column: DataTableColumn<T>) => {\n if (!isColumnHideable(column)) return;\n\n setHiddenColumns((current) => {\n const hidden = current[column.key] === true;\n if (!hidden && visibleHideableColumnCount <= 1) return current;\n\n const next = { ...current };\n if (hidden) {\n delete next[column.key];\n } else {\n next[column.key] = true;\n }\n\n return pruneHiddenColumns(next, columns);\n });\n };\n\n const showAllColumns = () => setHiddenColumns({});\n\n const openHeaderColumnMenu = (\n event: ReactMouseEvent<HTMLTableCellElement>,\n column: DataTableColumn<T>,\n ) => {\n if (!showColumnVisibilityControl) return;\n event.preventDefault();\n setColumnMenu(menuStateFromPointer(event, column.key));\n };\n\n const openHeaderFilterMenu = (\n event: ReactMouseEvent<HTMLElement>,\n columnKey: string,\n ) => {\n event.preventDefault();\n event.stopPropagation();\n setHeaderFilterMenu(menuStateFromTrigger(event, columnKey));\n };\n\n return (\n <DensityValueProvider density={densityOverride ?? \"comfortable\"}>\n <div\n className={cn(\"flex min-h-0 min-w-0 flex-1 flex-col gap-1\", className)}\n data-density={densityOverride}\n >\n {(showFilterBar || selectionToolbar || selectionBarNode) && (\n <FilterBar\n {...filterBarProps}\n {...(selectionBarNode ? { overlay: selectionBarNode } : {})}\n {...(externalSearch\n ? { search: externalSearch }\n : resolvedShowGlobalFilter\n ? {\n search: {\n value: effectiveGlobalFilter,\n onChange: setEffectiveGlobalFilter,\n placeholder: globalFilterPlaceholder,\n },\n }\n : {})}\n {...(barTimeRange ? { timeRange: barTimeRange } : {})}\n trailing={filterBarTrailing}\n filters={barFilters}\n />\n )}\n\n <div className=\"relative flex min-h-0 max-w-full flex-1 flex-col\">\n {loading && error == null ? (\n <LoadingBar\n data-testid=\"data-table-loading-bar\"\n className=\"rounded-t-md\"\n />\n ) : null}\n <div\n // The prop is spelled the React 19 way — RefObject<T | null>, which\n // is what useRef<T | null>(null) returns there — while the package\n // still type-checks against @types/react 18, where RefObject's\n // parameter is compared by variance rather than structurally. The\n // two shapes are the same object; the cast is what says so.\n ref={scrollContainerRef as RefObject<HTMLDivElement> | undefined}\n className={cn(\n \"min-h-0 max-w-full flex-1 overflow-auto overscroll-x-contain rounded-md border border-border bg-background\",\n scrollContainerClassName,\n )}\n aria-busy={(loading && error == null) || undefined}\n >\n <table className=\"w-max min-w-full table-auto text-left text-sm\">\n <colgroup>\n {rowSelection && error == null ? (\n <col className=\"w-10\" />\n ) : null}\n {visibleColumns.map((column) => (\n <col\n key={column.key}\n // An error row spans every column and is the only body content\n // there is, so the column widths have nothing left to size.\n // Keeping them stretches the table far past the viewport and\n // carries the error's own controls — copy, expand — out with\n // it, reachable only by scrolling sideways.\n style={\n error == null\n ? columnStyle(column, columnWidths)\n : undefined\n }\n className={\n column.shrink && !column.grow && error == null\n ? \"w-px\"\n : undefined\n }\n />\n ))}\n </colgroup>\n <thead className=\"sticky top-0 z-10 bg-muted shadow-[0_1px_0_0_var(--tw-shadow-color)] shadow-border\">\n <tr className=\"border-b border-border text-xs text-muted-foreground\">\n {rowSelection && error == null ? (\n <th\n className={cn(\n \"w-10 text-center\",\n DATA_TABLE_HEADER_DENSITY_CLASS,\n )}\n >\n <input\n ref={selectAllRef}\n type=\"checkbox\"\n aria-label=\"Select all visible rows\"\n checked={allVisibleSelected}\n disabled={selectableVisibleRows.length === 0}\n onChange={toggleVisibleSelection}\n className=\"size-3.5 rounded border-border accent-primary\"\n />\n </th>\n ) : null}\n {visibleColumns.map((column) => (\n <th\n key={column.key}\n className={cn(\n \"group/header relative whitespace-nowrap font-medium\",\n DATA_TABLE_HEADER_DENSITY_CLASS,\n alignmentClass(column.align),\n resizableColumns &&\n column.resizable !== false &&\n \"select-none\",\n column.headerClassName,\n )}\n onContextMenu={(event) =>\n openHeaderColumnMenu(event, column)\n }\n >\n <div\n className={cn(\n \"flex min-w-0 items-center gap-1\",\n headerAlignmentClass(column.align),\n resizableColumns &&\n column.resizable !== false &&\n \"pr-2\",\n )}\n >\n <span className=\"min-w-0\">\n {column.sortable === false || pageLocalSort ? (\n <span\n {...(pageLocalSort && column.sortable !== false\n ? {\n title:\n \"Sorting is served by the query while this table is paged by the server\",\n }\n : {})}\n >\n {column.label}\n </span>\n ) : (\n <SortableHeader\n active={sort?.key === column.key}\n {...(sort?.key === column.key\n ? { dir: sort.dir }\n : {})}\n {...(column.align ? { align: column.align } : {})}\n onClick={() => toggle(column.key)}\n >\n {column.label}\n </SortableHeader>\n )}\n </span>\n {showHeaderFilterControls &&\n (headerFilterByColumn.has(column.key) ||\n columnTimeRange?.key === column.key) && (\n <HeaderFilterButton\n column={column}\n active={\n headerFilterByColumn.has(column.key)\n ? isFilterBarFilterActive(\n headerFilterByColumn.get(column.key)!,\n )\n : Boolean(\n columnTimeRange?.range.from ||\n columnTimeRange?.range.to,\n )\n }\n onOpen={(event) =>\n openHeaderFilterMenu(event, column.key)\n }\n />\n )}\n </div>\n {resizableColumns && column.resizable !== false && (\n <span\n role=\"separator\"\n aria-label={`Resize ${labelText(column)} column`}\n aria-orientation=\"vertical\"\n className=\"absolute right-0 top-0 hidden h-full w-3 cursor-col-resize touch-none items-center justify-center border-r border-border/70 bg-gradient-to-l from-border/30 to-transparent transition-colors hover:border-primary hover:from-primary/20 md:flex\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onDoubleClick={(event) =>\n autoFitColumn(event, column)\n }\n onMouseDown={(event) =>\n startColumnResize(event, column)\n }\n >\n <span\n aria-hidden\n className=\"h-4 w-0.5 rounded-full bg-border transition-colors group-hover/header:bg-primary/70\"\n />\n </span>\n )}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {error != null ? (\n <DataTableErrorRow\n colSpan={visibleColumns.length}\n error={error}\n />\n ) : loading && visibleSorted.length === 0 ? (\n <DataTableLoadingRows\n columns={visibleColumns}\n rowCount={loadingRowCount}\n message={loadingMessage}\n selection={!!rowSelection}\n />\n ) : filteredRows.length === 0 ? (\n <tr>\n <td\n colSpan={visibleColumns.length + (rowSelection ? 1 : 0)}\n className=\"px-4 py-10 text-center text-sm text-muted-foreground\"\n >\n {emptyMessage}\n </td>\n </tr>\n ) : (\n rowStream.map((item) => {\n if (item.kind === \"group\") {\n return (\n <DataTableGroupHeaderRow\n key={`group:${item.group.key}`}\n label={item.group.label}\n meta={item.group.meta}\n metaAlign={effectiveGrouping?.metaAlign ?? \"end\"}\n {...(effectiveGrouping?.metaClassName\n ? { metaClassName: effectiveGrouping.metaClassName }\n : {})}\n count={item.group.records.length}\n colSpan={\n visibleColumns.length + (rowSelection ? 1 : 0)\n }\n collapsed={item.group.collapsed}\n onToggleCollapsed={() =>\n setCollapseStateByMode((current) => ({\n ...current,\n [collapseStateKey]: {\n ...current[collapseStateKey],\n groups: {\n ...current[collapseStateKey]?.groups,\n [item.group.key]: !item.group.collapsed,\n },\n },\n }))\n }\n {...(rowSelection\n ? {\n selection: {\n selectableCount: item.group.records.filter(\n (record) =>\n rowSelection.isRowSelectable?.(\n record.row,\n ) ?? true,\n ).length,\n selectedCount: item.group.records.filter(\n (record) => selectedRowIDs.has(record.id),\n ).length,\n onToggle: () =>\n toggleGroupSelection(item.group.records),\n },\n }\n : {})}\n />\n );\n }\n const record = item.record;\n const href = getRowHref?.(record.row);\n const expanded = expandedRows[record.id] ?? false;\n const expandedContent =\n renderExpandedRow?.(record.row, {\n columns: effectiveColumns,\n visibleColumns,\n filterActionsByColumn,\n }) ?? null;\n const expandable = expandedContent !== null;\n const expandsInline = expandable && detailStyle === \"row\";\n const opensDialog = expandable && detailStyle === \"dialog\";\n const rowClickEnabled =\n isRowClickable?.(record.row) ?? !!onRowClick;\n const rowSelectable =\n rowSelection?.isRowSelectable?.(record.row) ?? true;\n const selectionClickEnabled =\n !!rowSelection?.toggleOnRowClick && rowSelectable;\n const clickable =\n !!href ||\n rowClickEnabled ||\n expandable ||\n selectionClickEnabled;\n const activateRow = () => {\n if (selectionClickEnabled) toggleRowSelection(record);\n if (expandsInline) {\n setExpandedRows((current) => ({\n ...current,\n [record.id]: !current[record.id],\n }));\n }\n if (opensDialog) setDetailRow(record);\n if (rowClickEnabled) onRowClick?.(record.row);\n };\n\n return (\n <Fragment key={record.id}>\n <tr\n className={cn(\n \"relative border-b border-border/60 align-top\",\n clickable && \"cursor-pointer hover:bg-accent/40\",\n clickable &&\n !href &&\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\",\n selectedRowIDs.has(record.id) && \"bg-accent/50\",\n getRowClassName?.(record.row),\n )}\n tabIndex={clickable && !href ? 0 : undefined}\n onClick={activateRow}\n onKeyDown={(event) => {\n if (href || event.target !== event.currentTarget)\n return;\n if (event.key !== \"Enter\" && event.key !== \" \")\n return;\n event.preventDefault();\n activateRow();\n }}\n >\n {rowSelection ? (\n <td\n className={cn(\n // relative z-10 keeps the checkbox above the row's\n // stretched-link overlay so it stays clickable.\n \"relative z-10 w-10 text-center\",\n DATA_TABLE_CELL_DENSITY_CLASS,\n )}\n onClick={(event) => event.stopPropagation()}\n >\n <input\n type=\"checkbox\"\n aria-label={`Select row ${record.id}`}\n checked={selectedRowIDs.has(record.id)}\n disabled={!rowSelectable}\n onChange={() => toggleRowSelection(record)}\n className=\"size-3.5 rounded border-border accent-primary\"\n />\n </td>\n ) : null}\n {visibleColumns.map((column, index) => {\n const rawValue = resolveColumnValue(\n record.row,\n column,\n );\n let content: ReactNode = column.render\n ? column.render(rawValue, record.row)\n : formatCell(rawValue);\n\n const serverFilterValue = resolveServerFilterValue(\n rawValue,\n record.row,\n column,\n );\n const serverFilterDisplayValue =\n resolveCellFilterDisplayValue(\n rawValue,\n record.row,\n column,\n );\n const hasCellFilterActions =\n !!column.filterKey &&\n !!onCellFilterChange &&\n serverFilterValue !== undefined;\n if (\n column.filterKey &&\n onCellFilterChange &&\n serverFilterValue !== undefined\n ) {\n const filterKey = column.filterKey;\n content = (\n <CellFilterActions\n value={serverFilterValue}\n {...(serverFilterDisplayValue !== undefined\n ? { displayValue: serverFilterDisplayValue }\n : {})}\n mode={\n cellFilters?.[filterKey]?.[\n serverFilterValue\n ]\n }\n onChange={(mode) =>\n onCellFilterChange({\n key: filterKey,\n value: serverFilterValue,\n mode,\n })\n }\n >\n {content}\n </CellFilterActions>\n );\n }\n\n // Tag cells get the + / − filter affordance via\n // context; copy-to-clipboard works without it too.\n if (\n column.kind === \"tags\" &&\n filterActionsByColumn[column.key]\n ) {\n content = (\n <TagActionsProvider\n value={filterActionsByColumn[column.key]!}\n >\n {content}\n </TagActionsProvider>\n );\n }\n\n return (\n <td\n key={column.key}\n className={cn(\n DATA_TABLE_CELL_DENSITY_CLASS,\n alignmentClass(column.align),\n column.cellClassName,\n )}\n style={cellSizingStyle(\n column,\n columnWidths[column.key],\n )}\n >\n <CellContent column={column}>\n {href && index === 0\n ? // One real <a href> per row whose ::after\n // overlay stretches across the whole (relative)\n // row: right/middle-click give native \"open in\n // new tab\", plain left-click routes client-side.\n // The overlay paints over the cell, so a cell\n // with filter actions lifts them above it —\n // otherwise the link swallows the hover that\n // reveals the include/exclude buttons.\n renderLink({\n to: href,\n className:\n \"hover:underline after:absolute after:inset-0 after:content-['']\",\n children: hasCellFilterActions ? (\n <span className=\"relative z-10 inline-flex min-w-0 items-center\">\n {content}\n </span>\n ) : (\n content\n ),\n })\n : content}\n </CellContent>\n </td>\n );\n })}\n </tr>\n {expandsInline && expanded && expandedContent && (\n <tr>\n <td\n colSpan={\n visibleColumns.length + (rowSelection ? 1 : 0)\n }\n className=\"bg-muted/40 p-density-3\"\n >\n <div className=\"rounded-md border border-border bg-background p-density-3\">\n {expandedContent}\n </div>\n </td>\n </tr>\n )}\n </Fragment>\n );\n })\n )}\n {error == null && sentinelActive && (\n <tr ref={revealSentinelRef} aria-hidden>\n <td\n colSpan={visibleColumns.length + (rowSelection ? 1 : 0)}\n className=\"p-density-2 text-center text-xs text-muted-foreground\"\n >\n {sentinelLabel}\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n </div>\n\n {renderedFooter !== null && (\n <div className=\"shrink-0 px-1 text-xs text-muted-foreground\">\n {renderedFooter}\n </div>\n )}\n\n {error == null && pagination ? (\n <DataTablePaginationFooter\n pagination={pagination}\n visibleRowCount={sorted.length}\n infinite={infiniteEnabled}\n />\n ) : null}\n {detailStyle === \"dialog\" && renderExpandedRow && (\n <Modal\n open={detailRow !== null}\n onClose={() => setDetailRow(null)}\n size={detailDialogSize}\n {...(detailRow\n ? {\n title:\n typeof detailDialogTitle === \"function\"\n ? detailDialogTitle(detailRow.row)\n : detailDialogTitle,\n }\n : {})}\n >\n {detailRow\n ? renderExpandedRow(detailRow.row, {\n columns: effectiveColumns,\n visibleColumns,\n filterActionsByColumn,\n })\n : null}\n </Modal>\n )}\n {columnMenu && showTablePreferencesControl && (\n <ColumnVisibilityMenu\n columns={effectiveColumns}\n hiddenColumns={hiddenColumns}\n anchor={columnMenu}\n actions={menuActions ?? []}\n showColumnVisibilityControl={showColumnVisibilityControl}\n showDensityControl={resolvedShowDensityControl}\n showThemeControl={showThemeControl}\n themeMenuValue={themeMenuValue}\n densityOverride={densityOverride}\n visibleHideableColumnCount={visibleHideableColumnCount}\n onToggle={toggleColumnVisibility}\n onShowAll={showAllColumns}\n onDensityChange={setDensityOverride}\n {...(onThemeChange ? { onThemeChange } : {})}\n onClose={() => setColumnMenu(null)}\n />\n )}\n {headerFilterMenu && (\n <HeaderFilterMenu\n filter={headerFilterByColumn.get(headerFilterMenu.columnKey ?? \"\")}\n {...(columnTimeRange &&\n columnTimeRange.key === headerFilterMenu.columnKey\n ? { timeRange: columnTimeRange.range }\n : {})}\n anchor={headerFilterMenu}\n onClose={() => setHeaderFilterMenu(null)}\n />\n )}\n </div>\n </DensityValueProvider>\n );\n}\n\nfunction resolveServerFilterValue<T extends Record<string, unknown>>(\n rawValue: unknown,\n row: T,\n column: DataTableColumn<T>,\n): string | undefined {\n const value = column.serverFilterValue\n ? column.serverFilterValue(rawValue, row)\n : rawValue;\n switch (typeof value) {\n case \"string\":\n return value || undefined;\n case \"number\":\n case \"boolean\":\n return String(value);\n default:\n return undefined;\n }\n}\n\nfunction resolveCellFilterDisplayValue<T extends Record<string, unknown>>(\n rawValue: unknown,\n row: T,\n column: DataTableColumn<T>,\n): string | undefined {\n const value = column.serverFilterLabel\n ? column.serverFilterLabel(rawValue, row)\n : rawValue;\n switch (typeof value) {\n case \"string\":\n return value || undefined;\n case \"number\":\n case \"boolean\":\n return String(value);\n default:\n return undefined;\n }\n}\n\nconst DEFAULT_PAGE_SIZE_OPTIONS = [5, 10, 25, 50, 100, 200];\n\n// useCursorTrail remembers the cursors used to reach each page, which is what\n// makes a cursor walk steppable backwards at all: a cursor points forward only,\n// so \"the previous page\" is a position the client already visited rather than\n// one it can ask the server to compute.\n//\n// The position is derived from the cursor the caller is currently on rather\n// than tracked alongside it, so a filter change — which clears the cursor and\n// invalidates every token minted under the old query — lands back on the first\n// page with no stale entry left for Previous to walk into. The trail behind it\n// is discarded by the next push, which slices at the derived index.\n//\n// A cursor the trail has never seen (one restored from a URL, say) is a page\n// the client cannot number: it counts as one page in, and Previous returns to\n// the start rather than guessing at a position it was not there for.\nfunction useCursorTrail(cursor: DataTableCursorPagination | undefined) {\n const [trail, setTrail] = useState<string[]>([]);\n const current = cursor?.current;\n const index = current == null ? 0 : Math.max(trail.indexOf(current) + 1, 1);\n\n return {\n page: index,\n push: (next: string) =>\n setTrail((previous) => [...previous.slice(0, index), next]),\n previous: () => (index <= 1 ? undefined : trail[index - 2]),\n };\n}\n\n/**\n * Says what a selection actually covers once it can outgrow the page, and\n * offers the one step the header checkbox cannot take. Once the selection\n * spans the matched set it stops offering and starts reporting, because the\n * only thing left to do with it is let it go.\n */\nfunction SelectionScopeNotice({\n noun,\n loading,\n total,\n selectedCount,\n nextScope,\n onClear,\n}: {\n noun: string;\n loading?: boolean;\n /** The widest scope, which is what the count is measured against. */\n total: number;\n selectedCount: number;\n /** The narrowest scope the selection has not covered, if any is left. */\n nextScope?: DataTableSelectAllScope & { total: number };\n onClear: () => void;\n}) {\n return (\n <div\n role=\"status\"\n data-testid=\"data-table-selection-scope\"\n className=\"flex flex-wrap items-center gap-density-2 text-xs text-muted-foreground\"\n >\n <span>\n {selectedCount >= total\n ? `All ${total.toLocaleString()} ${noun} selected.`\n : `${selectedCount.toLocaleString()} of ${total.toLocaleString()} ${noun} selected.`}\n </span>\n {nextScope ? (\n <button\n type=\"button\"\n className=\"rounded-md border border-border bg-background px-2 py-0.5 font-medium text-foreground hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={loading}\n onClick={nextScope.onSelectAll}\n >\n {loading\n ? \"Selecting…\"\n : (nextScope.label ??\n `Select all ${nextScope.total.toLocaleString()} ${noun}`)}\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"rounded-md border border-border bg-background px-2 py-0.5 font-medium text-foreground hover:bg-accent\"\n onClick={onClear}\n >\n Clear selection\n </button>\n </div>\n );\n}\n\n// DataTablePaginationFooter renders a small page-size selector and prev/next\n// controls below the table. Pure presentation: every interaction routes\n// straight to the caller-supplied callbacks so the data layer (which lives in\n// CommandOutput / OperationCommandPage) stays the source of truth for which\n// rows are visible.\nfunction DataTablePaginationFooter({\n pagination,\n visibleRowCount,\n infinite = false,\n}: {\n pagination: DataTablePagination;\n visibleRowCount: number;\n /** Infinite scroll owns the paging; see `steppable` and `rangeStart` below. */\n infinite?: boolean;\n}) {\n const {\n page,\n pageSize,\n total,\n totalRelation,\n cursor,\n onPageChange,\n onPageSizeChange,\n } = pagination;\n const options = Array.from(\n new Set([\n ...(pagination.pageSizeOptions ?? DEFAULT_PAGE_SIZE_OPTIONS),\n pageSize,\n ]),\n ).sort((a, b) => a - b);\n const trail = useCursorTrail(cursor);\n const safePage = cursor ? trail.page : Math.max(0, page);\n const approximate = totalRelation === \"gte\";\n // A page count derived from a lower bound is a lower bound too, and offering\n // it as \"of N\" invites a jump to a page that may not exist. A cursor walk has\n // no page numbers to jump between at all.\n const totalPages =\n total != null && pageSize > 0 && !approximate && !cursor\n ? Math.max(1, Math.ceil(total / pageSize))\n : undefined;\n const atFirst = safePage === 0;\n const atLast = cursor\n ? cursor.next == null\n : pagination.hasMore != null\n ? !pagination.hasMore\n : totalPages != null\n ? safePage >= totalPages - 1\n : visibleRowCount < pageSize;\n const hasVisibleRows = visibleRowCount > 0;\n // Under infinite scroll every page fetched so far is stacked on screen, so the\n // run starts at the first row rather than at the offset the most recent\n // request happened to use — quoting that offset would report a window the\n // reader is not looking at.\n const rangeStart =\n total === 0 || !hasVisibleRows ? 0 : infinite ? 1 : safePage * pageSize + 1;\n const rangeEnd =\n total != null && hasVisibleRows\n ? Math.min(\n approximate ? Infinity : total,\n rangeStart + Math.max(visibleRowCount - 1, 0),\n )\n : visibleRowCount;\n const rangeLabel =\n total != null\n ? `${rangeStart}-${rangeEnd} of ${approximate ? `~${total}+` : total}`\n : `${visibleRowCount} row${visibleRowCount === 1 ? \"\" : \"s\"}`;\n\n // A surface with neither a page callback nor a cursor has no second page to\n // offer. It still reports what it is showing and still resizes — a count is a\n // fact about the result, not a paging control. Infinite scroll lands in the\n // same place from the other direction: the pages are all still on screen, and\n // a position nobody can step back to is not worth a button.\n const steppable = !infinite && (cursor != null || onPageChange != null);\n\n const goPrevious = () => {\n if (!cursor) {\n onPageChange?.(Math.max(0, safePage - 1));\n return;\n }\n cursor.onCursorChange(trail.previous());\n };\n const goNext = () => {\n if (!cursor) {\n onPageChange?.(safePage + 1);\n return;\n }\n if (cursor.next == null) return;\n trail.push(cursor.next);\n cursor.onCursorChange(cursor.next);\n };\n\n return (\n <div className=\"flex min-h-9 shrink-0 flex-row items-stretch gap-3 border-t border-border/70 px-1 pt-2 text-xs text-muted-foreground sm:flex-row sm:flex-wrap sm:items-center sm:justify-between\">\n <div aria-live=\"polite\">{rangeLabel}</div>\n <div className=\"flex flex-wrap items-center gap-2 sm:gap-3\">\n <label className=\"flex items-center gap-1.5\">\n <span>Rows per page</span>\n <select\n className=\"h-7 rounded-md border border-border bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n value={pageSize}\n onChange={(event) => onPageSizeChange(Number(event.target.value))}\n >\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n </label>\n {steppable ? (\n <>\n <span className=\"min-w-20 text-center\">\n Page {safePage + 1}\n {totalPages != null ? ` of ${totalPages}` : \"\"}\n </span>\n <button\n type=\"button\"\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border bg-background text-foreground hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label=\"Previous page\"\n title=\"Previous page\"\n disabled={atFirst}\n onClick={goPrevious}\n >\n <Icon icon={UiArrowLeft} />\n </button>\n <button\n type=\"button\"\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md border border-border bg-background text-foreground hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label=\"Next page\"\n title=\"Next page\"\n disabled={atLast}\n onClick={goNext}\n >\n <Icon icon={UiArrowRight} />\n </button>\n </>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction DataTableGroupHeaderRow({\n label,\n meta,\n metaAlign,\n metaClassName,\n count,\n colSpan,\n collapsed,\n onToggleCollapsed,\n selection,\n}: {\n label: ReactNode;\n meta: ReactNode;\n metaAlign: DataTableGroupMetaAlign;\n metaClassName?: string;\n count: number;\n colSpan: number;\n collapsed: boolean;\n onToggleCollapsed: () => void;\n selection?: {\n selectableCount: number;\n selectedCount: number;\n onToggle: () => void;\n };\n}) {\n const allSelected =\n !!selection &&\n selection.selectableCount > 0 &&\n selection.selectedCount === selection.selectableCount;\n const someSelected =\n !!selection && selection.selectedCount > 0 && !allSelected;\n const checkboxRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (checkboxRef.current) checkboxRef.current.indeterminate = someSelected;\n }, [someSelected]);\n\n return (\n <tr className=\"border-b border-border/60 bg-muted/40\">\n <td colSpan={colSpan} className=\"px-density-2 py-density-1\">\n <div className=\"flex items-center gap-2\">\n {selection ? (\n <input\n ref={checkboxRef}\n type=\"checkbox\"\n aria-label={`Select group ${typeof label === \"string\" ? label : count}`}\n checked={allSelected}\n disabled={selection.selectableCount === 0}\n onChange={selection.onToggle}\n className=\"size-3.5 rounded border-border accent-primary\"\n />\n ) : null}\n <button\n type=\"button\"\n aria-expanded={!collapsed}\n onClick={onToggleCollapsed}\n className={cn(\n \"flex min-w-0 items-center gap-1.5 text-left text-sm font-semibold text-foreground hover:text-primary\",\n // `flex-1` is what pushes the meta to the trailing edge. Dropping\n // it lets the meta sit right after the count instead.\n metaAlign === \"end\" && \"flex-1\",\n )}\n >\n <Icon\n icon={collapsed ? UiChevronRight : UiChevronDown}\n className=\"shrink-0 text-muted-foreground\"\n />\n <span className=\"truncate\">{label}</span>\n <span className=\"shrink-0 font-normal text-muted-foreground\">\n {count}\n </span>\n </button>\n {meta ? (\n <div\n className={cn(\n \"shrink-0 text-sm text-muted-foreground\",\n metaClassName,\n )}\n >\n {meta}\n </div>\n ) : null}\n </div>\n </td>\n </tr>\n );\n}\n\nfunction DataTableLoadingRows<T extends Record<string, unknown>>({\n columns,\n rowCount,\n message,\n selection,\n}: {\n columns: DataTableColumn<T>[];\n rowCount: number;\n message: ReactNode;\n selection: boolean;\n}) {\n const safeRowCount = Math.max(1, rowCount);\n const safeColumnCount = Math.max(1, columns.length + (selection ? 1 : 0));\n\n return (\n <>\n <tr className=\"border-b border-border/60 bg-muted/20\">\n <td\n colSpan={safeColumnCount}\n className={cn(DATA_TABLE_CELL_DENSITY_CLASS, \"p-0\")}\n >\n <div className=\"h-0.5 w-full overflow-hidden bg-muted\">\n <div className=\"h-full w-1/2 animate-pulse rounded-full bg-primary/70\" />\n </div>\n <div className=\"flex items-center gap-2 px-3 py-2 text-xs text-muted-foreground\">\n <span\n aria-hidden\n className=\"h-3 w-3 animate-spin rounded-full border-2 border-primary/30 border-t-primary\"\n />\n <span>{message}</span>\n </div>\n </td>\n </tr>\n {Array.from({ length: safeRowCount }).map((_, rowIndex) => (\n <tr key={rowIndex} className=\"border-b border-border/60\">\n {selection ? (\n <td className={cn(\"w-10\", DATA_TABLE_CELL_DENSITY_CLASS)}>\n <span className=\"mx-auto block size-3.5 animate-pulse rounded bg-muted\" />\n </td>\n ) : null}\n {columns.map((column, columnIndex) => (\n <td\n key={column.key}\n className={cn(\n DATA_TABLE_CELL_DENSITY_CLASS,\n alignmentClass(column.align),\n column.cellClassName,\n )}\n style={cellSizingStyle(column, undefined)}\n >\n <CellContent column={column}>\n <span\n aria-hidden\n className={cn(\n \"block h-3 animate-pulse rounded-full bg-muted\",\n loadingSkeletonWidth(columnIndex),\n )}\n />\n </CellContent>\n </td>\n ))}\n </tr>\n ))}\n </>\n );\n}\n\nfunction DataTableErrorRow({\n colSpan,\n error,\n}: {\n colSpan: number;\n error: ReactNode;\n}) {\n return (\n <tr className=\"border-b border-border/60\">\n <td\n colSpan={Math.max(1, colSpan)}\n className={cn(DATA_TABLE_CELL_DENSITY_CLASS, \"p-density-3\")}\n >\n {/*\n w-0 min-w-full keeps the error out of the table's width calculation:\n a cell sizes to its content, so an error carrying a long unbroken\n line — a response body, a SQL statement — would widen the table\n itself and push its own copy and expand controls off-screen.\n */}\n <div role=\"alert\" className=\"w-0 min-w-full overflow-hidden\">\n {error}\n </div>\n </td>\n </tr>\n );\n}\n\nfunction HeaderFilterButton<T extends Record<string, unknown>>({\n column,\n active,\n onOpen,\n}: {\n column: DataTableColumn<T>;\n active: boolean;\n onOpen: (event: ReactMouseEvent<HTMLButtonElement>) => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={`Open ${labelText(column)} column filter`}\n aria-haspopup=\"dialog\"\n aria-pressed={active}\n className={cn(\n \"inline-flex h-5 w-5 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active && \"bg-accent text-foreground\",\n )}\n onClick={onOpen}\n >\n <span\n data-filter-icon-state={active ? \"filled\" : \"outline\"}\n className=\"inline-flex\"\n >\n <Icon icon={active ? UiFilterFilled : UiFilter} className=\"text-xs\" />\n </span>\n </button>\n );\n}\n\nfunction HeaderFilterMenu({\n filter,\n timeRange,\n anchor,\n onClose,\n}: {\n filter: FilterBarFilter | undefined;\n timeRange?: FilterBarRangeProps;\n anchor: ColumnMenuState;\n onClose: () => void;\n}) {\n if (!filter && !timeRange) return null;\n\n const label = filter?.label ?? \"Time range\";\n const timeRangeActive = Boolean(timeRange?.from || timeRange?.to);\n\n return (\n <div\n role=\"dialog\"\n aria-label={`${label} column filter`}\n className=\"fixed z-50 max-h-[calc(100vh-1rem)] max-w-[calc(100vw-1rem)] overflow-auto rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-lg shadow-black/5\"\n style={{ left: anchor.x, top: anchor.y }}\n onClick={(event) => event.stopPropagation()}\n onContextMenu={(event) => event.preventDefault()}\n >\n <div className=\"mb-2 flex items-center justify-between gap-3\">\n <div className=\"truncate text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <div className=\"flex items-center gap-1\">\n {filter && (\n <button\n type=\"button\"\n className=\"rounded px-1.5 py-0.5 text-xs text-primary transition-colors hover:bg-accent focus:bg-accent focus:outline-none disabled:text-muted-foreground\"\n onClick={() => clearFilterBarFilter(filter)}\n disabled={!isFilterBarFilterActive(filter)}\n >\n Clear all\n </button>\n )}\n {timeRange && (\n <button\n type=\"button\"\n className=\"rounded px-1.5 py-0.5 text-xs text-primary transition-colors hover:bg-accent focus:bg-accent focus:outline-none disabled:text-muted-foreground\"\n onClick={() => timeRange.onApply(\"\", \"\")}\n disabled={!timeRangeActive}\n >\n Clear all\n </button>\n )}\n <button\n type=\"button\"\n aria-label=\"Close column filter\"\n title=\"Close\"\n className=\"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\"\n onClick={onClose}\n >\n <Icon icon={UiClose} className=\"text-sm\" />\n </button>\n </div>\n </div>\n <div className=\"flex flex-col gap-2\">\n {filter && <FilterBarFilterPanel filter={filter} chrome=\"embedded\" />}\n {timeRange && (\n <FilterBarRangePanel kind=\"time\" label=\"Time range\" {...timeRange} />\n )}\n </div>\n </div>\n );\n}\n\nfunction ColumnVisibilityTrigger({\n onOpen,\n}: {\n onOpen: (event: ReactMouseEvent<HTMLButtonElement>) => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label=\"Open column menu\"\n aria-haspopup=\"menu\"\n className=\"inline-flex h-8 w-8 items-center justify-center rounded-md border border-input bg-background text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n onClick={(event) => {\n event.stopPropagation();\n onOpen(event);\n }}\n >\n <Icon icon={UiEllipsis} className=\"text-sm\" />\n </button>\n );\n}\n\nfunction ColumnVisibilityMenu<T extends Record<string, unknown>>({\n columns,\n hiddenColumns,\n anchor,\n actions,\n showColumnVisibilityControl,\n showDensityControl,\n showThemeControl,\n themeMenuValue,\n densityOverride,\n visibleHideableColumnCount,\n onToggle,\n onShowAll,\n onDensityChange,\n onThemeChange,\n onClose,\n}: {\n columns: DataTableColumn<T>[];\n hiddenColumns: Record<string, boolean>;\n anchor: ColumnMenuState;\n actions: DataTableMenuAction[];\n showColumnVisibilityControl: boolean;\n showDensityControl: boolean;\n showThemeControl: boolean;\n themeMenuValue: Theme | undefined;\n densityOverride: Density | undefined;\n visibleHideableColumnCount: number;\n onToggle: (column: DataTableColumn<T>) => void;\n onShowAll: () => void;\n onDensityChange: (density: Density | undefined) => void;\n onThemeChange?: (theme: Theme) => void;\n onClose: () => void;\n}) {\n const activeColumn = anchor.columnKey\n ? columns.find((column) => column.key === anchor.columnKey)\n : undefined;\n const canHideActiveColumn =\n activeColumn &&\n isColumnHideable(activeColumn) &&\n visibleHideableColumnCount > 1;\n const hasActions = actions.length > 0;\n\n return (\n <div\n role=\"menu\"\n aria-label=\"Column menu\"\n className=\"fixed z-50 max-h-[calc(100vh-1rem)] min-w-[16rem] max-w-[calc(100vw-1rem)] overflow-auto rounded-md border border-border bg-popover p-1.5 text-popover-foreground shadow-lg shadow-black/5\"\n style={{ left: anchor.x, top: anchor.y }}\n onClick={(event) => event.stopPropagation()}\n onContextMenu={(event) => event.preventDefault()}\n >\n {showColumnVisibilityControl && (\n <>\n <div className=\"flex items-center justify-between gap-3 px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n <span>Columns</span>\n <button\n type=\"button\"\n className=\"rounded px-1.5 py-0.5 text-xs text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\"\n onClick={onShowAll}\n >\n Show all\n </button>\n </div>\n\n {activeColumn && (\n <>\n <button\n type=\"button\"\n role=\"menuitem\"\n disabled={!canHideActiveColumn}\n className={cn(\n \"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\",\n !canHideActiveColumn && \"cursor-not-allowed opacity-50\",\n )}\n onClick={() => {\n if (!canHideActiveColumn) return;\n onToggle(activeColumn);\n onClose();\n }}\n >\n <Icon\n icon={UiEyeClosed}\n className=\"text-sm text-muted-foreground\"\n />\n <span>Hide {labelText(activeColumn)}</span>\n </button>\n <div className=\"my-1 h-px bg-border\" />\n </>\n )}\n\n <div className=\"max-h-72 overflow-auto\">\n {columns.map((column) => {\n const hideable = isColumnHideable(column);\n const visible = hiddenColumns[column.key] !== true;\n const disabled =\n !hideable || (visible && visibleHideableColumnCount <= 1);\n return (\n <label\n key={column.key}\n className={cn(\n \"flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-accent hover:text-accent-foreground\",\n disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n <input\n type=\"checkbox\"\n className=\"h-4 w-4 rounded border-border\"\n checked={visible}\n disabled={disabled}\n onChange={() => onToggle(column)}\n />\n <span className=\"truncate\">{labelText(column)}</span>\n </label>\n );\n })}\n </div>\n </>\n )}\n\n {showDensityControl && (\n <DensityMenuSection\n densityOverride={densityOverride}\n separated={showColumnVisibilityControl}\n onDensityChange={onDensityChange}\n />\n )}\n\n {hasActions && (\n <MenuActionSection\n actions={actions}\n separated={showColumnVisibilityControl || showDensityControl}\n onClose={onClose}\n />\n )}\n\n {showThemeControl && onThemeChange && (\n <ThemeMenuSection\n value={themeMenuValue ?? \"system\"}\n separated={\n showColumnVisibilityControl || showDensityControl || hasActions\n }\n onChange={onThemeChange}\n />\n )}\n </div>\n );\n}\n\n// Groups menu actions by their `section` heading, preserving the order each\n// section first appears. Actions without a section fall under \"Download\" so the\n// existing download menu is unchanged.\nfunction groupMenuActions(\n actions: DataTableMenuAction[],\n): { section: string; actions: DataTableMenuAction[] }[] {\n const groups: { section: string; actions: DataTableMenuAction[] }[] = [];\n for (const action of actions) {\n const section = action.section ?? \"Download\";\n let group = groups.find((g) => g.section === section);\n if (!group) {\n group = { section, actions: [] };\n groups.push(group);\n }\n group.actions.push(action);\n }\n return groups;\n}\n\nfunction MenuActionSection({\n actions,\n separated,\n onClose,\n}: {\n actions: DataTableMenuAction[];\n separated: boolean;\n onClose: () => void;\n}) {\n const groups = groupMenuActions(actions);\n // Which submenu is open, if any. One at a time: hovering a sibling takes the\n // flyout with it, which is what every menu does and what stops two levels\n // from being open over each other.\n const [openSubmenu, setOpenSubmenu] = useState<{\n id: string;\n x: number;\n y: number;\n } | null>(null);\n\n return (\n <>\n {groups.map((group, index) => (\n <div\n key={group.section}\n className={cn(\n (separated || index > 0) && \"mt-1 border-t border-border pt-1\",\n )}\n >\n {group.section && (\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {group.section}\n </div>\n )}\n {group.actions.map((action) => (\n <MenuActionItem\n key={action.id}\n action={action}\n submenu={openSubmenu?.id === action.id ? openSubmenu : null}\n onOpenSubmenu={setOpenSubmenu}\n onClose={onClose}\n />\n ))}\n </div>\n ))}\n </>\n );\n}\n\nfunction MenuActionItem({\n action,\n submenu,\n onOpenSubmenu,\n onClose,\n}: {\n action: DataTableMenuAction;\n submenu: { id: string; x: number; y: number } | null;\n onOpenSubmenu: (state: { id: string; x: number; y: number } | null) => void;\n onClose: () => void;\n}) {\n const hasDescription = Boolean(action.description);\n const children = action.children ?? [];\n const isSubmenu = children.length > 0;\n\n const openFrom = (element: HTMLElement) => {\n const rect = element.getBoundingClientRect();\n // Flip to the left when the flyout would run off the right edge, using the\n // same minimum width the panel below is given.\n const width = 224;\n const x =\n rect.right + width > window.innerWidth ? rect.left - width : rect.right;\n onOpenSubmenu({ id: action.id, x, y: rect.top });\n };\n\n return (\n <>\n <button\n type=\"button\"\n role=\"menuitem\"\n aria-haspopup={isSubmenu ? \"menu\" : undefined}\n aria-expanded={isSubmenu ? submenu != null : undefined}\n disabled={action.disabled}\n className={cn(\n \"flex w-full gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\",\n hasDescription ? \"items-start\" : \"items-center\",\n action.disabled && \"cursor-not-allowed opacity-50\",\n submenu && \"bg-accent text-accent-foreground\",\n )}\n onClick={(event) => {\n if (action.disabled) return;\n // Click, never hover: a flyout that opens on the way past is one the\n // user did not ask for, and it covers the rows they were reaching for.\n if (isSubmenu) {\n if (submenu) onOpenSubmenu(null);\n else openFrom(event.currentTarget);\n return;\n }\n action.onSelect();\n onClose();\n }}\n >\n {action.icon && (\n <Icon\n icon={action.icon}\n className={cn(\n \"shrink-0 text-sm\",\n hasDescription && \"mt-0.5\",\n action.iconClassName ?? \"text-muted-foreground\",\n )}\n />\n )}\n <span className=\"min-w-0 flex-1\">\n <span className={cn(hasDescription && \"font-medium\")}>\n {action.label}\n </span>\n {action.description && (\n <span className=\"mt-0.5 block text-xs text-muted-foreground\">\n {action.description}\n </span>\n )}\n </span>\n {isSubmenu && (\n <Icon\n icon={UiChevronRight}\n className=\"shrink-0 text-sm text-muted-foreground\"\n />\n )}\n </button>\n\n {isSubmenu && submenu && (\n <div\n role=\"menu\"\n aria-label={\n typeof action.label === \"string\" ? action.label : \"Submenu\"\n }\n className=\"fixed z-50 max-h-[calc(100vh-1rem)] min-w-[14rem] max-w-[calc(100vw-1rem)] overflow-auto rounded-md border border-border bg-popover p-1.5 text-popover-foreground shadow-lg shadow-black/5\"\n style={{ left: submenu.x, top: submenu.y }}\n >\n {children.map((child) => (\n <MenuActionItem\n key={child.id}\n action={child}\n submenu={null}\n onOpenSubmenu={onOpenSubmenu}\n onClose={onClose}\n />\n ))}\n </div>\n )}\n </>\n );\n}\n\nfunction DensityMenuSection({\n densityOverride,\n separated,\n onDensityChange,\n}: {\n densityOverride: Density | undefined;\n separated: boolean;\n onDensityChange: (density: Density | undefined) => void;\n}) {\n const current = densityOverride ?? \"inherit\";\n\n return (\n <div className={cn(separated && \"mt-1 border-t border-border pt-1\")}>\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n Density\n </div>\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={current === \"inherit\"}\n className={densityMenuItemClassName(current === \"inherit\")}\n onClick={() => onDensityChange(undefined)}\n >\n <Icon\n icon={UiResizeVertical}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 flex-1 truncate\">Use page density</span>\n {current === \"inherit\" ? (\n <Icon icon={UiCheck} className=\"text-sm text-foreground\" />\n ) : (\n <span className=\"inline-block h-4 w-4\" aria-hidden />\n )}\n </button>\n {DENSITY_OPTIONS.map((option) => {\n const active = current === option.value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n className={densityMenuItemClassName(active)}\n onClick={() => onDensityChange(option.value)}\n >\n <Icon\n icon={option.icon}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 flex-1 truncate\">{option.label}</span>\n {active ? (\n <Icon icon={UiCheck} className=\"text-sm text-foreground\" />\n ) : (\n <span className=\"inline-block h-4 w-4\" aria-hidden />\n )}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction densityMenuItemClassName(active: boolean) {\n return cn(\n \"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none\",\n active && \"text-foreground\",\n );\n}\n\nconst THEME_MENU_OPTIONS: Array<{\n value: Theme;\n icon: StaticIconComponent;\n label: string;\n}> = [\n { value: \"system\", icon: UiDesktop, label: \"Use system theme\" },\n { value: \"light\", icon: UiSun, label: \"Light\" },\n { value: \"dark\", icon: UiMoon, label: \"Dark\" },\n];\n\nfunction ThemeMenuSection({\n value,\n separated,\n onChange,\n}: {\n value: Theme;\n separated: boolean;\n onChange: (theme: Theme) => void;\n}) {\n return (\n <div className={cn(separated && \"mt-1 border-t border-border pt-1\")}>\n <div className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n Theme\n </div>\n {THEME_MENU_OPTIONS.map((option) => {\n const active = value === option.value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n className={densityMenuItemClassName(active)}\n onClick={() => onChange(option.value)}\n >\n <Icon\n icon={option.icon}\n className=\"text-sm text-muted-foreground\"\n />\n <span className=\"min-w-0 flex-1 truncate\">{option.label}</span>\n {active ? (\n <Icon icon={UiCheck} className=\"text-sm text-foreground\" />\n ) : (\n <span className=\"inline-block h-4 w-4\" aria-hidden />\n )}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction CellContent<T extends Record<string, unknown>>({\n column,\n children,\n}: {\n column: DataTableColumn<T>;\n children: ReactNode;\n}) {\n return (\n <div\n className={cn(cellContentClassName(column), alignmentClass(column.align))}\n >\n {children}\n </div>\n );\n}\n\nfunction getSortValue<T extends Record<string, unknown>>(\n row: T,\n column: DataTableColumn<T>,\n) {\n const rawValue = resolveColumnValue(row, column);\n return column.sortValue ? column.sortValue(rawValue, row) : rawValue;\n}\n\nfunction getFilterNumbers<T extends Record<string, unknown>>(\n row: T,\n column: DataTableColumn<T>,\n) {\n return normalizeNumbers(getFilterCandidate(row, column));\n}\n\nfunction normalizeNumbers(value: FilterValue | unknown): number[] {\n if (Array.isArray(value)) {\n return value.flatMap((item) => normalizeNumbers(item));\n }\n\n const parsed = parseNumberInput(value);\n return parsed == null ? [] : [parsed];\n}\n\nfunction updateFilterValue(\n state: Record<string, string>,\n key: string,\n nextValue: string,\n) {\n const next = { ...state };\n\n if (nextValue.trim()) {\n next[key] = nextValue;\n } else {\n delete next[key];\n }\n\n return next;\n}\n\nfunction updateFilterRecord(\n state: Record<string, Record<string, FilterBarMultiFilterMode>>,\n key: string,\n nextValue: Record<string, FilterBarMultiFilterMode>,\n) {\n const next = { ...state };\n\n if (Object.keys(nextValue).length > 0) {\n next[key] = nextValue;\n } else {\n delete next[key];\n }\n\n return next;\n}\n\nfunction updateNumberFilterValue(\n state: Record<string, FilterBarNumberValue>,\n key: string,\n nextValue: FilterBarNumberValue,\n) {\n const next = { ...state };\n const hasMin = String(nextValue.min ?? \"\").trim() !== \"\";\n const hasMax = String(nextValue.max ?? \"\").trim() !== \"\";\n\n if (hasMin || hasMax) {\n next[key] = nextValue;\n } else {\n delete next[key];\n }\n\n return next;\n}\n\nfunction pruneTextFilterState(\n state: Record<string, string>,\n filters: GeneratedFilter<any>[],\n) {\n return pruneFilterState(\n state,\n filters,\n \"text\",\n (value) => !String(value ?? \"\").trim(),\n );\n}\n\nfunction pruneMultiFilterState(\n state: Record<string, Record<string, FilterBarMultiFilterMode>>,\n filters: GeneratedFilter<any>[],\n) {\n // multi and nested-multi share the same state slot; allow either kind to\n // keep the entry alive.\n const allowed = new Set(\n filters\n .filter(\n (filter) => filter.kind === \"multi\" || filter.kind === \"nested-multi\",\n )\n .map((filter) => filter.column.key),\n );\n return Object.fromEntries(\n Object.entries(state).filter(\n ([key, value]) => allowed.has(key) && Object.keys(value).length > 0,\n ),\n );\n}\n\nfunction pruneNumberFilterState(\n state: Record<string, FilterBarNumberValue>,\n filters: GeneratedFilter<any>[],\n) {\n return pruneFilterState(\n state,\n filters,\n \"number\",\n (value) =>\n !String(value.min ?? \"\").trim() && !String(value.max ?? \"\").trim(),\n );\n}\n\nfunction pruneFilterState<T>(\n state: Record<string, T>,\n filters: GeneratedFilter<any>[],\n kind: GeneratedFilter<any>[\"kind\"],\n isEmpty: (value: T) => boolean,\n) {\n const allowed = new Set(\n filters\n .filter((filter) => filter.kind === kind)\n .map((filter) => filter.column.key),\n );\n return Object.fromEntries(\n Object.entries(state).filter(\n ([key, value]) => allowed.has(key) && !isEmpty(value),\n ),\n ) as Record<string, T>;\n}\n\nfunction formatCell(value: unknown): ReactNode {\n if (value == null || value === \"\") {\n return <span className=\"text-muted-foreground\">—</span>;\n }\n if (typeof value === \"boolean\") return value ? \"True\" : \"False\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n// Groups flat key=value tokens by key for the nested-multi tag filter.\n// Tokens without a separator land in a synthetic \"\" group rendered as\n// \"Other\" by the filter UI.\nfunction groupTagOptions(\n options: MultiSelectOption[],\n separator: string,\n): Array<{ groupKey: string; label?: string; options: MultiSelectOption[] }> {\n const byKey = new Map<string, MultiSelectOption[]>();\n for (const option of options) {\n const { key } = splitTagToken(option.value, separator);\n const list = byKey.get(key) ?? [];\n list.push(option);\n byKey.set(key, list);\n }\n return Array.from(byKey.entries())\n .sort(([a], [b]) => {\n // Bare-tag bucket sinks to the bottom; otherwise alphabetical.\n if (a === \"\" && b !== \"\") return 1;\n if (b === \"\" && a !== \"\") return -1;\n return a.localeCompare(b);\n })\n .map(([groupKey, groupOptions]) => ({\n groupKey,\n label: groupKey === \"\" ? \"Other\" : groupKey,\n options: groupOptions,\n }));\n}\n\nfunction applyKindDefaults<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n timestampFormat: TimestampFormat | undefined,\n): DataTableColumn<T> {\n if (!column.kind) return column;\n\n if (column.kind === \"timestamp\") {\n const format = timestampFormat ?? \"iso\";\n return {\n ...column,\n render:\n column.render ??\n ((value) => (\n <Timestamp\n value={value}\n format={format}\n showTitleOnHover={column.timestamp?.alwaysShowFullOnHover !== false}\n />\n )),\n sortValue:\n column.sortValue ??\n ((value) => parseTimestamp(value)?.getTime() ?? null),\n filterValue:\n column.filterValue ??\n ((value) => {\n const parsed = parseTimestamp(value);\n return parsed ? parsed.toISOString() : \"\";\n }),\n };\n }\n\n if (column.kind === \"tags\") {\n const opts = column.tags;\n const separator = opts?.separator ?? \"=\";\n return {\n ...column,\n render:\n column.render ??\n ((value) => (\n <TagList\n tags={normalizeTags(value as TagsValue, separator)}\n maxVisible={opts?.maxVisible ?? 3}\n />\n )),\n filterValue:\n column.filterValue ??\n ((value) => tagFilterTokens(value as TagsValue, separator)),\n sortValue:\n column.sortValue ??\n ((value) => tagFilterTokens(value as TagsValue, separator).length),\n };\n }\n\n if (column.kind === \"status\") {\n const opts = column.status;\n const map = opts?.map ?? ((raw) => normalizeStatus(raw));\n return {\n ...column,\n render:\n column.render ??\n ((value, row) => {\n const status = map(value, row);\n if (!status) return <span className=\"text-muted-foreground\">—</span>;\n const label = opts?.showLabel\n ? typeof value === \"string\"\n ? value\n : status\n : undefined;\n const title =\n opts?.title?.(value, row) ??\n (typeof value === \"string\" ? value : undefined);\n return (\n <StatusDot\n status={status}\n {...(label ? { label } : {})}\n {...(title ? { title } : {})}\n />\n );\n }),\n filterValue:\n column.filterValue ??\n ((value, row) => {\n const status = map(value, row);\n return status ?? \"\";\n }),\n sortValue: column.sortValue ?? ((value, row) => map(value, row) ?? \"\"),\n };\n }\n\n return column;\n}\n\nfunction labelText<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n) {\n if (typeof column.label === \"string\") return column.label;\n return prettifyKey(column.key.split(\".\").at(-1) ?? column.key);\n}\n\nfunction isColumnHideable<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n) {\n return column.hideable !== false;\n}\n\nfunction menuStateFromPointer(\n event: ReactMouseEvent<HTMLElement>,\n columnKey?: string,\n): ColumnMenuState {\n const padding = 8;\n const width = 256;\n const height = 320;\n const viewportWidth =\n typeof window === \"undefined\" ? event.clientX + width : window.innerWidth;\n const viewportHeight =\n typeof window === \"undefined\" ? event.clientY + height : window.innerHeight;\n\n const position = {\n x: Math.max(\n padding,\n Math.min(event.clientX, viewportWidth - width - padding),\n ),\n y: Math.max(\n padding,\n Math.min(event.clientY, viewportHeight - height - padding),\n ),\n };\n return columnKey ? { ...position, columnKey } : position;\n}\n\nfunction menuStateFromTrigger(\n event: ReactMouseEvent<HTMLElement>,\n columnKey?: string,\n): ColumnMenuState {\n const rect = event.currentTarget.getBoundingClientRect();\n const padding = 8;\n const width = 256;\n const height = 320;\n const viewportWidth =\n typeof window === \"undefined\" ? rect.right + width : window.innerWidth;\n const viewportHeight =\n typeof window === \"undefined\" ? rect.bottom + height : window.innerHeight;\n\n const position = {\n x: Math.max(\n padding,\n Math.min(rect.right - width, viewportWidth - width - padding),\n ),\n y: Math.max(\n padding,\n Math.min(rect.bottom + 6, viewportHeight - height - padding),\n ),\n };\n return columnKey ? { ...position, columnKey } : position;\n}\n\nfunction columnStyle<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n widths: Record<string, number>,\n): CSSProperties | undefined {\n const width = widths[column.key];\n return width ? { width: `${width}px` } : undefined;\n}\n\nfunction measureColumnContentWidth<T extends Record<string, unknown>>(\n table: HTMLTableElement,\n columnIndex: number,\n column: DataTableColumn<T>,\n) {\n const cells = Array.from(table.querySelectorAll(\"th, td\")).filter(\n (cell): cell is HTMLTableCellElement =>\n cell instanceof HTMLTableCellElement &&\n cell.cellIndex === columnIndex &&\n cell.colSpan === 1,\n );\n\n const measured = cells.reduce((current, cell) => {\n const horizontalPadding = getHorizontalPadding(cell);\n const contentWidths = Array.from(cell.children).map((child) =>\n child instanceof HTMLElement ? child.scrollWidth + horizontalPadding : 0,\n );\n return Math.max(current, cell.scrollWidth, ...contentWidths);\n }, 0);\n\n return clampColumnWidth(column, measured || defaultColumnWidth(column));\n}\n\nfunction getHorizontalPadding(element: HTMLElement) {\n if (typeof window === \"undefined\") return 0;\n const styles = window.getComputedStyle(element);\n return (\n parseCssPixelValue(styles.paddingLeft) +\n parseCssPixelValue(styles.paddingRight)\n );\n}\n\nfunction parseCssPixelValue(value: string) {\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction readStoredColumnWidths<T extends Record<string, unknown>>(\n storageKey: string,\n columns: DataTableColumn<T>[],\n): Record<string, number> {\n if (typeof window === \"undefined\") return {};\n\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (!raw) return {};\n\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed))\n return {};\n\n return pruneColumnWidths(parsed as Record<string, unknown>, columns);\n } catch {\n return {};\n }\n}\n\nfunction writeStoredColumnWidths(\n storageKey: string,\n widths: Record<string, number>,\n) {\n if (typeof window === \"undefined\") return;\n\n try {\n if (Object.keys(widths).length === 0) {\n window.localStorage.removeItem(storageKey);\n } else {\n window.localStorage.setItem(storageKey, JSON.stringify(widths));\n }\n } catch {}\n}\n\nfunction readStoredHiddenColumns<T extends Record<string, unknown>>(\n storageKey: string,\n columns: DataTableColumn<T>[],\n): Record<string, boolean> {\n if (typeof window === \"undefined\") return {};\n\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (!raw) return {};\n\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed))\n return {};\n\n return pruneHiddenColumns(parsed as Record<string, unknown>, columns);\n } catch {\n return {};\n }\n}\n\nfunction writeStoredHiddenColumns(\n storageKey: string,\n hiddenColumns: Record<string, boolean>,\n) {\n if (typeof window === \"undefined\") return;\n\n try {\n if (Object.keys(hiddenColumns).length === 0) {\n window.localStorage.removeItem(storageKey);\n } else {\n window.localStorage.setItem(storageKey, JSON.stringify(hiddenColumns));\n }\n } catch {}\n}\n\nfunction readStoredDensityOverride(storageKey: string): Density | undefined {\n if (typeof window === \"undefined\") return undefined;\n\n try {\n const raw = window.localStorage.getItem(storageKey);\n return isDensity(raw) ? raw : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeStoredDensityOverride(\n storageKey: string,\n density: Density | undefined,\n) {\n if (typeof window === \"undefined\") return;\n\n try {\n if (density) {\n window.localStorage.setItem(storageKey, density);\n } else {\n window.localStorage.removeItem(storageKey);\n }\n } catch {}\n}\n\nfunction isDensity(value: unknown): value is Density {\n return value === \"compact\" || value === \"comfortable\" || value === \"spacious\";\n}\n\nfunction pruneColumnWidths<T extends Record<string, unknown>>(\n widths: Record<string, unknown>,\n columns: DataTableColumn<T>[],\n): Record<string, number> {\n const byKey = new Map(columns.map((column) => [column.key, column]));\n const next: Record<string, number> = {};\n\n for (const [key, width] of Object.entries(widths)) {\n const column = byKey.get(key);\n if (!column || typeof width !== \"number\" || !Number.isFinite(width))\n continue;\n\n next[key] = clampColumnWidth(column, width);\n }\n\n return next;\n}\n\nfunction pruneHiddenColumns<T extends Record<string, unknown>>(\n hiddenColumns: Record<string, unknown>,\n columns: DataTableColumn<T>[],\n): Record<string, boolean> {\n const byKey = new Map(columns.map((column) => [column.key, column]));\n const next: Record<string, boolean> = {};\n\n for (const [key, hidden] of Object.entries(hiddenColumns)) {\n const column = byKey.get(key);\n if (!column || hidden !== true || !isColumnHideable(column)) continue;\n\n next[key] = true;\n }\n\n const hideable = columns.filter(isColumnHideable);\n const visibleHideableCount = hideable.filter(\n (column) => next[column.key] !== true,\n ).length;\n if (hideable.length > 0 && visibleHideableCount === 0) {\n delete next[hideable[0]!.key];\n }\n\n return next;\n}\n\nfunction sameColumnWidths(\n left: Record<string, number>,\n right: Record<string, number>,\n) {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every(\n (key) =>\n Object.prototype.hasOwnProperty.call(right, key) &&\n left[key] === right[key],\n )\n );\n}\n\nfunction sameHiddenColumns(\n left: Record<string, boolean>,\n right: Record<string, boolean>,\n) {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every(\n (key) =>\n Object.prototype.hasOwnProperty.call(right, key) &&\n left[key] === right[key],\n )\n );\n}\n\nfunction defaultColumnWidth<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n) {\n if (column.grow) return DEFAULT_GROW_COLUMN_WIDTH;\n if (column.shrink) return DEFAULT_SHRINK_COLUMN_WIDTH;\n return DEFAULT_COLUMN_WIDTH;\n}\n\nfunction clampColumnWidth<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n width: number,\n) {\n const minWidth = column.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const maxWidth = column.maxWidth;\n const minimum = Number.isFinite(minWidth)\n ? Math.max(1, minWidth)\n : DEFAULT_COLUMN_MIN_WIDTH;\n const maximum =\n maxWidth != null && Number.isFinite(maxWidth)\n ? Math.max(minimum, maxWidth)\n : Infinity;\n\n return Math.round(Math.max(minimum, Math.min(maximum, width)));\n}\n\nfunction getNumericFilterBounds<T extends Record<string, unknown>>(\n rows: InternalRow<T>[],\n column: DataTableColumn<T>,\n) {\n const values = rows.flatMap((record) =>\n collectFilterValues(getFilterCandidate(record.row, column)),\n );\n const populated = values.filter(hasFilterValue);\n const numericValues = populated\n .map((value) => parseNumberInput(value))\n .filter((value) => value != null);\n\n if (populated.length === 0 || numericValues.length !== populated.length) {\n return null;\n }\n\n return {\n min: Math.min(...numericValues),\n max: Math.max(...numericValues),\n step: inferNumericStep(numericValues),\n };\n}\n\nfunction collectFilterValues(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value.flatMap((item) => collectFilterValues(item));\n }\n\n return [value];\n}\n\nfunction hasFilterValue(value: unknown) {\n return value != null && !(typeof value === \"string\" && value.trim() === \"\");\n}\n\nfunction parseNumberInput(value: unknown): number | null {\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : null;\n }\n\n if (typeof value !== \"string\") {\n return null;\n }\n\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n const parsed = Number(trimmed);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction inferNumericStep(values: number[]) {\n if (values.every(Number.isInteger)) {\n return 1;\n }\n\n const maxFractionDigits = values.reduce((current, value) => {\n const [, fraction = \"\"] = String(value).split(\".\");\n return Math.max(current, fraction.length);\n }, 0);\n\n return 10 ** -Math.min(maxFractionDigits || 2, 6);\n}\n\nfunction alignmentClass(align?: DataTableColumn[\"align\"]) {\n if (align === \"right\") return \"text-right\";\n if (align === \"center\") return \"text-center\";\n return \"text-left\";\n}\n\nfunction headerAlignmentClass(align?: DataTableColumn[\"align\"]) {\n if (align === \"right\") return \"justify-end\";\n if (align === \"center\") return \"justify-center\";\n return \"justify-start\";\n}\n\nfunction loadingSkeletonWidth(index: number) {\n return [\"w-24\", \"w-40\", \"w-28\", \"w-56\", \"w-32\", \"w-48\"][index % 6];\n}\n\n// An auto-layout column is only ever as wide as its widest cell, so the width a\n// cell is allowed to ask for has to be bounded somewhere or one long value\n// pins the column to its own text and pushes the table sideways. It belongs on\n// the cell rather than on the content: max-width bounds what a column asks for\n// without clipping what it is finally given, so the content can fill a column\n// that leftover space made wider instead of truncating with room to spare.\n// A grow column asks for nothing and lives on the leftovers, with the minimum\n// keeping it from collapsing when the other columns already fill the table.\nfunction cellSizingStyle<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n width: number | undefined,\n): CSSProperties {\n if (width !== undefined) return { maxWidth: `${width}px` };\n if (column.grow) {\n return {\n maxWidth: \"0px\",\n minWidth: column.minWidth ?? DEFAULT_GROW_COLUMN_WIDTH,\n };\n }\n return {\n maxWidth:\n column.maxWidth ??\n (column.shrink ? DEFAULT_SHRINK_CELL_MAX_WIDTH : DEFAULT_CELL_MAX_WIDTH),\n };\n}\n\nfunction cellContentClassName<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n): TdHTMLAttributes<HTMLTableCellElement>[\"className\"] {\n return cn(\"w-full min-w-0 truncate\", column.shrink && \"whitespace-nowrap\");\n}\n\nexport function DataTable<T extends Record<string, unknown>>({\n theme: themeProp = \"system\",\n onThemeChange,\n showThemeControl = false,\n showFullscreenControl = false,\n fullscreenTitle = \"Table\",\n fullscreenButtonLabel = \"Open table full screen\",\n className,\n filterBarProps,\n scrollContainerRef,\n ...inner\n}: DataTableProps<T>) {\n const themeControlled = onThemeChange !== undefined;\n const [internalTheme, setInternalTheme] = useState<Theme>(themeProp);\n const themeValue = themeControlled ? themeProp : internalTheme;\n const resolvedTheme = useResolvedTheme(themeValue);\n const handleThemeChange = (next: Theme) => {\n if (!themeControlled) setInternalTheme(next);\n onThemeChange?.(next);\n };\n const [fullscreenOpen, setFullscreenOpen] = useState(false);\n\n const renderTable = ({ inFullscreen }: { inFullscreen: boolean }) => {\n const showFullscreenButton = showFullscreenControl && !inFullscreen;\n const callerTrailing = filterBarProps?.trailing;\n const mergedFilterBarProps = showFullscreenButton\n ? {\n ...filterBarProps,\n trailing: (\n <>\n {callerTrailing}\n <FullscreenButton\n label={fullscreenButtonLabel}\n onClick={() => setFullscreenOpen(true)}\n />\n </>\n ),\n }\n : filterBarProps;\n // Both copies stay mounted while the modal is open, so exactly one of them\n // may hold the caller's scroll ref: handing it to both makes the last one\n // mounted the winner and nulls it when the modal unmounts, which leaves a\n // caller pinning a live tail writing to an element nobody is looking at.\n // The visible copy is the fullscreen one precisely when the modal is open.\n const ownsScroll = inFullscreen === fullscreenOpen;\n return (\n <DataTableInner\n {...(inner as DataTableInnerProps<T>)}\n {...(ownsScroll && scrollContainerRef ? { scrollContainerRef } : {})}\n {...(mergedFilterBarProps\n ? { filterBarProps: mergedFilterBarProps }\n : {})}\n themeMenuValue={themeValue}\n showThemeControl={showThemeControl}\n onThemeChange={handleThemeChange}\n />\n );\n };\n\n return (\n <div\n data-theme={resolvedTheme}\n className={cn(\"flex min-h-0 flex-col text-foreground\", className)}\n >\n {renderTable({ inFullscreen: false })}\n {showFullscreenControl && (\n <Modal\n open={fullscreenOpen}\n onClose={() => setFullscreenOpen(false)}\n title={fullscreenTitle}\n size=\"full\"\n className=\"h-[95vh]\"\n >\n <div\n data-theme={resolvedTheme}\n className=\"flex h-full min-h-0 flex-col bg-background text-foreground\"\n >\n {renderTable({ inFullscreen: true })}\n </div>\n </Modal>\n )}\n </div>\n );\n}\n\nfunction FullscreenButton({\n label,\n onClick,\n}: {\n label: string;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n className=\"inline-flex h-8 w-8 items-center justify-center rounded-md border border-input bg-background text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n onClick={onClick}\n >\n <Icon icon={UiFullscreen} className=\"text-sm\" />\n </button>\n );\n}\n"],"names":["_a","rows","groups","record","Fragment"],"mappings":"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"}
|