@flanksource/clicky-ui 0.1.0 → 0.2.2
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/README.md +29 -2
- package/dist/api-explorer.d.ts +5 -0
- package/dist/api-explorer.d.ts.map +1 -0
- package/dist/api-explorer.js +25 -0
- package/dist/api-explorer.js.map +1 -0
- package/dist/clicky.d.ts +2 -0
- package/dist/clicky.d.ts.map +1 -0
- package/dist/clicky.js +5 -0
- package/dist/clicky.js.map +1 -0
- package/dist/components/DatePicker.d.ts +18 -0
- package/dist/components/DatePicker.d.ts.map +1 -0
- package/dist/components/DatePicker.js +63 -0
- package/dist/components/DatePicker.js.map +1 -0
- package/dist/components/DateTimePicker.d.ts +18 -0
- package/dist/components/DateTimePicker.d.ts.map +1 -0
- package/dist/components/DateTimePicker.js +84 -0
- package/dist/components/DateTimePicker.js.map +1 -0
- package/dist/components/FilterBar.d.ts +180 -0
- package/dist/components/FilterBar.d.ts.map +1 -0
- package/dist/components/FilterBar.js +1685 -0
- package/dist/components/FilterBar.js.map +1 -0
- package/dist/components/MultiSelect.d.ts +19 -0
- package/dist/components/MultiSelect.d.ts.map +1 -0
- package/dist/components/MultiSelect.js +143 -0
- package/dist/components/MultiSelect.js.map +1 -0
- package/dist/components/RangeSlider.d.ts +16 -0
- package/dist/components/RangeSlider.d.ts.map +1 -0
- package/dist/components/RangeSlider.js +92 -0
- package/dist/components/RangeSlider.js.map +1 -0
- package/dist/components/button.d.ts +21 -0
- package/dist/components/button.d.ts.map +1 -0
- package/dist/components/button.js +126 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/density-switcher.d.ts +7 -0
- package/dist/components/density-switcher.d.ts.map +1 -0
- package/dist/components/density-switcher.js +32 -0
- package/dist/components/density-switcher.js.map +1 -0
- package/dist/components/icon-menu-picker.d.ts +23 -0
- package/dist/components/icon-menu-picker.d.ts.map +1 -0
- package/dist/components/icon-menu-picker.js +192 -0
- package/dist/components/icon-menu-picker.js.map +1 -0
- package/dist/components/select.d.ts +15 -0
- package/dist/components/select.d.ts.map +1 -0
- package/dist/components/select.js +39 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/theme-switcher.d.ts +7 -0
- package/dist/components/theme-switcher.d.ts.map +1 -0
- package/dist/components/theme-switcher.js +42 -0
- package/dist/components/theme-switcher.js.map +1 -0
- package/dist/components.d.ts +15 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +33 -0
- package/dist/components.js.map +1 -0
- package/dist/data/AnsiHtml.d.ts +7 -0
- package/dist/data/AnsiHtml.d.ts.map +1 -0
- package/dist/data/AnsiHtml.js +71 -0
- package/dist/data/AnsiHtml.js.map +1 -0
- package/dist/data/Avatar.d.ts +32 -0
- package/dist/data/Avatar.d.ts.map +1 -0
- package/dist/data/Avatar.js +201 -0
- package/dist/data/Avatar.js.map +1 -0
- package/dist/data/AvatarBadge.d.ts +26 -0
- package/dist/data/AvatarBadge.d.ts.map +1 -0
- package/dist/data/AvatarBadge.js +104 -0
- package/dist/data/AvatarBadge.js.map +1 -0
- package/dist/data/Badge.d.ts +44 -0
- package/dist/data/Badge.d.ts.map +1 -0
- package/dist/data/Badge.js +667 -0
- package/dist/data/Badge.js.map +1 -0
- package/dist/data/Clicky.d.ts +147 -0
- package/dist/data/Clicky.d.ts.map +1 -0
- package/dist/data/Clicky.fixtures.d.ts +3 -0
- package/dist/data/Clicky.fixtures.d.ts.map +1 -0
- package/dist/data/Clicky.js +1960 -0
- package/dist/data/Clicky.js.map +1 -0
- package/dist/data/DataTable.d.ts +95 -0
- package/dist/data/DataTable.d.ts.map +1 -0
- package/dist/data/DataTable.js +1464 -0
- package/dist/data/DataTable.js.map +1 -0
- package/dist/data/FilterPill.d.ts +29 -0
- package/dist/data/FilterPill.d.ts.map +1 -0
- package/dist/data/FilterPill.js +153 -0
- package/dist/data/FilterPill.js.map +1 -0
- package/dist/data/Gauge.d.ts +15 -0
- package/dist/data/Gauge.d.ts.map +1 -0
- package/dist/data/Gauge.js +63 -0
- package/dist/data/Gauge.js.map +1 -0
- package/dist/data/Icon.d.ts +53 -0
- package/dist/data/Icon.d.ts.map +1 -0
- package/dist/data/Icon.js +115 -0
- package/dist/data/Icon.js.map +1 -0
- package/dist/data/JsonView.d.ts +8 -0
- package/dist/data/JsonView.d.ts.map +1 -0
- package/dist/data/JsonView.js +74 -0
- package/dist/data/JsonView.js.map +1 -0
- package/dist/data/KeyValueList.d.ts +17 -0
- package/dist/data/KeyValueList.d.ts.map +1 -0
- package/dist/data/KeyValueList.js +33 -0
- package/dist/data/KeyValueList.js.map +1 -0
- package/dist/data/LogViewer.d.ts +10 -0
- package/dist/data/LogViewer.d.ts.map +1 -0
- package/dist/data/LogViewer.js +46 -0
- package/dist/data/LogViewer.js.map +1 -0
- package/dist/data/LogsTable.d.ts +27 -0
- package/dist/data/LogsTable.d.ts.map +1 -0
- package/dist/data/LogsTable.js +580 -0
- package/dist/data/LogsTable.js.map +1 -0
- package/dist/data/Markdown.d.ts +6 -0
- package/dist/data/Markdown.d.ts.map +1 -0
- package/dist/data/Markdown.js +59 -0
- package/dist/data/Markdown.js.map +1 -0
- package/dist/data/MatrixTable.d.ts +22 -0
- package/dist/data/MatrixTable.d.ts.map +1 -0
- package/dist/data/MatrixTable.js +164 -0
- package/dist/data/MatrixTable.js.map +1 -0
- package/dist/data/MethodBadge.d.ts +6 -0
- package/dist/data/MethodBadge.d.ts.map +1 -0
- package/dist/data/MethodBadge.js +18 -0
- package/dist/data/MethodBadge.js.map +1 -0
- package/dist/data/ProgressBar.d.ts +13 -0
- package/dist/data/ProgressBar.d.ts.map +1 -0
- package/dist/data/ProgressBar.js +34 -0
- package/dist/data/ProgressBar.js.map +1 -0
- package/dist/data/SortableHeader.d.ts +12 -0
- package/dist/data/SortableHeader.d.ts.map +1 -0
- package/dist/data/SortableHeader.js +33 -0
- package/dist/data/SortableHeader.js.map +1 -0
- package/dist/data/TabButton.d.ts +12 -0
- package/dist/data/TabButton.d.ts.map +1 -0
- package/dist/data/TabButton.js +45 -0
- package/dist/data/TabButton.js.map +1 -0
- package/dist/data/Tree.d.ts +35 -0
- package/dist/data/Tree.d.ts.map +1 -0
- package/dist/data/Tree.js +236 -0
- package/dist/data/Tree.js.map +1 -0
- package/dist/data/TreeGroupHeader.d.ts +11 -0
- package/dist/data/TreeGroupHeader.d.ts.map +1 -0
- package/dist/data/TreeGroupHeader.js +41 -0
- package/dist/data/TreeGroupHeader.js.map +1 -0
- package/dist/data/TreeNode.d.ts +43 -0
- package/dist/data/TreeNode.d.ts.map +1 -0
- package/dist/data/TreeNode.js +100 -0
- package/dist/data/TreeNode.js.map +1 -0
- package/dist/data/cells/StatusDot.d.ts +11 -0
- package/dist/data/cells/StatusDot.d.ts.map +1 -0
- package/dist/data/cells/StatusDot.js +38 -0
- package/dist/data/cells/StatusDot.js.map +1 -0
- package/dist/data/cells/TagList.d.ts +59 -0
- package/dist/data/cells/TagList.d.ts.map +1 -0
- package/dist/data/cells/TagList.js +257 -0
- package/dist/data/cells/TagList.js.map +1 -0
- package/dist/data/cells/Timestamp.d.ts +46 -0
- package/dist/data/cells/Timestamp.d.ts.map +1 -0
- package/dist/data/cells/Timestamp.js +146 -0
- package/dist/data/cells/Timestamp.js.map +1 -0
- package/dist/data/cells/status-mapping.d.ts +8 -0
- package/dist/data/cells/status-mapping.d.ts.map +1 -0
- package/dist/data/cells/status-mapping.js +44 -0
- package/dist/data/cells/status-mapping.js.map +1 -0
- package/dist/data/code-highlight.d.ts +12 -0
- package/dist/data/code-highlight.d.ts.map +1 -0
- package/dist/data/code-highlight.js +28 -0
- package/dist/data/code-highlight.js.map +1 -0
- package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts +9 -0
- package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -0
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js +445 -0
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -0
- package/dist/data/diagnostics/DiagnosticsTree.d.ts +9 -0
- package/dist/data/diagnostics/DiagnosticsTree.d.ts.map +1 -0
- package/dist/data/diagnostics/DiagnosticsTree.js +78 -0
- package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -0
- package/dist/data/diagnostics/ErrorDetails.d.ts +20 -0
- package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -0
- package/dist/data/diagnostics/ErrorDetails.js +157 -0
- package/dist/data/diagnostics/ErrorDetails.js.map +1 -0
- package/dist/data/diagnostics/GoroutineCard.d.ts +10 -0
- package/dist/data/diagnostics/GoroutineCard.d.ts.map +1 -0
- package/dist/data/diagnostics/GoroutineCard.js +75 -0
- package/dist/data/diagnostics/GoroutineCard.js.map +1 -0
- package/dist/data/diagnostics/JvmStackTrace.d.ts +11 -0
- package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -0
- package/dist/data/diagnostics/JvmStackTrace.js +26 -0
- package/dist/data/diagnostics/JvmStackTrace.js.map +1 -0
- package/dist/data/diagnostics/RenderedStackTrace.d.ts +18 -0
- package/dist/data/diagnostics/RenderedStackTrace.d.ts.map +1 -0
- package/dist/data/diagnostics/RenderedStackTrace.js +235 -0
- package/dist/data/diagnostics/RenderedStackTrace.js.map +1 -0
- package/dist/data/diagnostics/ThreadCard.d.ts +10 -0
- package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -0
- package/dist/data/diagnostics/ThreadCard.js +78 -0
- package/dist/data/diagnostics/ThreadCard.js.map +1 -0
- package/dist/data/diagnostics/error-diagnostics.d.ts +26 -0
- package/dist/data/diagnostics/error-diagnostics.d.ts.map +1 -0
- package/dist/data/diagnostics/error-diagnostics.js +108 -0
- package/dist/data/diagnostics/error-diagnostics.js.map +1 -0
- package/dist/data/diagnostics/fixtures.d.ts +3 -0
- package/dist/data/diagnostics/fixtures.d.ts.map +1 -0
- package/dist/data/diagnostics/jvm-stacktrace.d.ts +34 -0
- package/dist/data/diagnostics/jvm-stacktrace.d.ts.map +1 -0
- package/dist/data/diagnostics/jvm-stacktrace.js +190 -0
- package/dist/data/diagnostics/jvm-stacktrace.js.map +1 -0
- package/dist/data/diagnostics/stacktrace-parse.d.ts +11 -0
- package/dist/data/diagnostics/stacktrace-parse.d.ts.map +1 -0
- package/dist/data/diagnostics/stacktrace-parse.js +87 -0
- package/dist/data/diagnostics/stacktrace-parse.js.map +1 -0
- package/dist/data/diagnostics/stacktrace.d.ts +38 -0
- package/dist/data/diagnostics/stacktrace.d.ts.map +1 -0
- package/dist/data/diagnostics/stacktrace.js +119 -0
- package/dist/data/diagnostics/stacktrace.js.map +1 -0
- package/dist/data/diagnostics/types.d.ts +30 -0
- package/dist/data/diagnostics/types.d.ts.map +1 -0
- package/dist/data/diagnostics/utils.d.ts +8 -0
- package/dist/data/diagnostics/utils.d.ts.map +1 -0
- package/dist/data/diagnostics/utils.js +59 -0
- package/dist/data/diagnostics/utils.js.map +1 -0
- package/dist/data/har/HarPanel.d.ts +9 -0
- package/dist/data/har/HarPanel.d.ts.map +1 -0
- package/dist/data/har/HarPanel.js +175 -0
- package/dist/data/har/HarPanel.js.map +1 -0
- package/dist/data/har/fixtures.d.ts +3 -0
- package/dist/data/har/fixtures.d.ts.map +1 -0
- package/dist/data/har/types.d.ts +47 -0
- package/dist/data/har/types.d.ts.map +1 -0
- package/dist/data.d.ts +39 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +109 -0
- package/dist/data.js.map +1 -0
- package/dist/hooks/use-density.d.ts +22 -0
- package/dist/hooks/use-density.d.ts.map +1 -0
- package/dist/hooks/use-density.js +54 -0
- package/dist/hooks/use-density.js.map +1 -0
- package/dist/hooks/use-history-route.d.ts +6 -0
- package/dist/hooks/use-history-route.d.ts.map +1 -0
- package/dist/hooks/use-history-route.js +31 -0
- package/dist/hooks/use-history-route.js.map +1 -0
- package/dist/hooks/use-sort.d.ts +17 -0
- package/dist/hooks/use-sort.d.ts.map +1 -0
- package/dist/hooks/use-sort.js +42 -0
- package/dist/hooks/use-sort.js.map +1 -0
- package/dist/hooks/use-theme.d.ts +17 -0
- package/dist/hooks/use-theme.d.ts.map +1 -0
- package/dist/hooks/use-theme.js +68 -0
- package/dist/hooks/use-theme.js.map +1 -0
- package/dist/hooks.d.ts +5 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +14 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +195 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/Section.d.ts +23 -0
- package/dist/layout/Section.d.ts.map +1 -0
- package/dist/layout/Section.js +73 -0
- package/dist/layout/Section.js.map +1 -0
- package/dist/layout/SplitPane.d.ts +13 -0
- package/dist/layout/SplitPane.d.ts.map +1 -0
- package/dist/layout/SplitPane.js +72 -0
- package/dist/layout/SplitPane.js.map +1 -0
- package/dist/lib/palette.d.ts +4 -0
- package/dist/lib/palette.d.ts.map +1 -0
- package/dist/lib/palette.js +35 -0
- package/dist/lib/palette.js.map +1 -0
- package/dist/lib/size.d.ts +6 -0
- package/dist/lib/size.d.ts.map +1 -0
- package/dist/lib/size.js +14 -0
- package/dist/lib/size.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/overlay/HoverCard.d.ts +13 -0
- package/dist/overlay/HoverCard.d.ts.map +1 -0
- package/dist/overlay/HoverCard.js +170 -0
- package/dist/overlay/HoverCard.js.map +1 -0
- package/dist/overlay/Modal.d.ts +17 -0
- package/dist/overlay/Modal.d.ts.map +1 -0
- package/dist/overlay/Modal.js +91 -0
- package/dist/overlay/Modal.js.map +1 -0
- package/dist/rpc/AcceptPicker.d.ts +52 -0
- package/dist/rpc/AcceptPicker.d.ts.map +1 -0
- package/dist/rpc/AcceptPicker.js +126 -0
- package/dist/rpc/AcceptPicker.js.map +1 -0
- package/dist/rpc/ApiExplorer.d.ts +11 -0
- package/dist/rpc/ApiExplorer.d.ts.map +1 -0
- package/dist/rpc/ApiExplorer.js +37 -0
- package/dist/rpc/ApiExplorer.js.map +1 -0
- package/dist/rpc/CommandForm.d.ts +15 -0
- package/dist/rpc/CommandForm.d.ts.map +1 -0
- package/dist/rpc/CommandForm.js +356 -0
- package/dist/rpc/CommandForm.js.map +1 -0
- package/dist/rpc/CommandOutput.d.ts +11 -0
- package/dist/rpc/CommandOutput.d.ts.map +1 -0
- package/dist/rpc/CommandOutput.js +195 -0
- package/dist/rpc/CommandOutput.js.map +1 -0
- package/dist/rpc/EndpointList.d.ts +18 -0
- package/dist/rpc/EndpointList.d.ts.map +1 -0
- package/dist/rpc/EndpointList.js +56 -0
- package/dist/rpc/EndpointList.js.map +1 -0
- package/dist/rpc/EntityExplorerApp.d.ts +15 -0
- package/dist/rpc/EntityExplorerApp.d.ts.map +1 -0
- package/dist/rpc/EntityExplorerApp.js +282 -0
- package/dist/rpc/EntityExplorerApp.js.map +1 -0
- package/dist/rpc/ExecutionResult.d.ts +14 -0
- package/dist/rpc/ExecutionResult.d.ts.map +1 -0
- package/dist/rpc/ExecutionResult.js +51 -0
- package/dist/rpc/ExecutionResult.js.map +1 -0
- package/dist/rpc/FilterForm.d.ts +22 -0
- package/dist/rpc/FilterForm.d.ts.map +1 -0
- package/dist/rpc/FilterForm.js +392 -0
- package/dist/rpc/FilterForm.js.map +1 -0
- package/dist/rpc/InlineError.d.ts +7 -0
- package/dist/rpc/InlineError.d.ts.map +1 -0
- package/dist/rpc/InlineError.js +54 -0
- package/dist/rpc/InlineError.js.map +1 -0
- package/dist/rpc/OperationActionDialog.d.ts +12 -0
- package/dist/rpc/OperationActionDialog.d.ts.map +1 -0
- package/dist/rpc/OperationActionDialog.js +105 -0
- package/dist/rpc/OperationActionDialog.js.map +1 -0
- package/dist/rpc/OperationCatalog.d.ts +21 -0
- package/dist/rpc/OperationCatalog.d.ts.map +1 -0
- package/dist/rpc/OperationCatalog.js +339 -0
- package/dist/rpc/OperationCatalog.js.map +1 -0
- package/dist/rpc/OperationCommandPage.d.ts +22 -0
- package/dist/rpc/OperationCommandPage.d.ts.map +1 -0
- package/dist/rpc/OperationCommandPage.js +484 -0
- package/dist/rpc/OperationCommandPage.js.map +1 -0
- package/dist/rpc/OperationEntityPage.d.ts +23 -0
- package/dist/rpc/OperationEntityPage.d.ts.map +1 -0
- package/dist/rpc/OperationEntityPage.js +218 -0
- package/dist/rpc/OperationEntityPage.js.map +1 -0
- package/dist/rpc/classify.d.ts +8 -0
- package/dist/rpc/classify.d.ts.map +1 -0
- package/dist/rpc/classify.js +76 -0
- package/dist/rpc/classify.js.map +1 -0
- package/dist/rpc/clickyMetadata.d.ts +12 -0
- package/dist/rpc/clickyMetadata.d.ts.map +1 -0
- package/dist/rpc/clickyMetadata.js +71 -0
- package/dist/rpc/clickyMetadata.js.map +1 -0
- package/dist/rpc/formMetadata.d.ts +27 -0
- package/dist/rpc/formMetadata.d.ts.map +1 -0
- package/dist/rpc/formMetadata.js +250 -0
- package/dist/rpc/formMetadata.js.map +1 -0
- package/dist/rpc/types.d.ts +109 -0
- package/dist/rpc/types.d.ts.map +1 -0
- package/dist/rpc/types.js +8 -0
- package/dist/rpc/types.js.map +1 -0
- package/dist/rpc/useOperations.d.ts +346 -0
- package/dist/rpc/useOperations.d.ts.map +1 -0
- package/dist/rpc/useOperations.js +31 -0
- package/dist/rpc/useOperations.js.map +1 -0
- package/dist/rpc.d.ts +14 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +37 -0
- package/dist/rpc.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/styles.d.ts +1 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +2 -0
- package/dist/styles.js.map +1 -0
- package/dist/tailwind-preset.d.ts +4 -0
- package/dist/tailwind-preset.d.ts.map +1 -0
- package/dist/tailwind-preset.js +69 -0
- package/dist/tailwind-preset.js.map +1 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +12 -0
- package/dist/utils.js.map +1 -0
- package/package.json +83 -40
- package/dist/index.d.mts +0 -834
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -2918
- package/dist/index.mjs.map +0 -1
- package/dist/tailwind-preset.d.mts +0 -7
- package/dist/tailwind-preset.d.mts.map +0 -1
- package/dist/tailwind-preset.mjs +0 -64
- package/dist/tailwind-preset.mjs.map +0 -1
- package/src/styles/tokens.css +0 -78
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTable.js","sources":["../../src/data/DataTable.tsx"],"sourcesContent":["import {\n Fragment,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n type TdHTMLAttributes,\n} from \"react\";\nimport { useSort, type SortDir } from \"../hooks/use-sort\";\nimport type { Density } from \"../hooks/use-density\";\nimport { cn } from \"../lib/utils\";\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} from \"../components/FilterBar\";\nimport type { MultiSelectOption } from \"../components/MultiSelect\";\nimport { Icon } from \"./Icon\";\nimport { SortableHeader } from \"./SortableHeader\";\nimport {\n Timestamp,\n chooseTimestampFormat,\n modeToFormat,\n parseTimestamp,\n resolveDateMath,\n type TimestampFormat,\n type TimestampOptions,\n} from \"./cells/Timestamp\";\nimport {\n TagActionsProvider,\n TagList,\n normalizeTags,\n splitTagToken,\n tagActionsFromRecord,\n tagFilterTokens,\n type TagActionsContextValue,\n type TagFilterMode,\n type TagsOptions,\n type TagsValue,\n} from \"./cells/TagList\";\nimport { StatusDot } from \"./cells/StatusDot\";\nimport { normalizeStatus } from \"./cells/status-mapping\";\nimport type { BadgeStatus } from \"./Badge\";\n\nexport type { TimestampOptions, TagsOptions };\n\nexport type DataTableColumnKind = \"timestamp\" | \"tags\" | \"status\";\n\nexport type StatusOptions<T extends Record<string, unknown> = Record<string, unknown>> = {\n map?: (raw: unknown, row: T) => BadgeStatus | null;\n showLabel?: boolean;\n title?: (raw: unknown, row: T) => string;\n};\n\ntype FilterValue = string | number | boolean | null | undefined | Array<string | number | boolean>;\n\ntype InternalRow<T> = {\n id: string;\n row: T;\n};\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 COLUMN_WIDTH_STORAGE_PREFIX = \"clicky-ui-data-table-column-widths\";\nconst COLUMN_VISIBILITY_STORAGE_PREFIX = \"clicky-ui-data-table-column-visibility\";\nconst DENSITY_STORAGE_PREFIX = \"clicky-ui-data-table-density\";\n\nconst DENSITY_OPTIONS: Array<{ value: Density; icon: string; label: string }> = [\n { value: \"compact\", icon: \"ph:rows\", label: \"Compact\" },\n { value: \"comfortable\", icon: \"ph:list\", label: \"Comfortable\" },\n { value: \"spacious\", icon: \"ph:list-dashes\", 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<T extends Record<string, unknown> = Record<string, unknown>> =\n {\n columns: DataTableColumn<T>[];\n visibleColumns: DataTableColumn<T>[];\n tagActionsByColumn: 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<T extends Record<string, unknown> = Record<string, unknown>> = {\n key: string;\n label: ReactNode;\n sortable?: boolean;\n filterable?: boolean;\n grow?: boolean;\n shrink?: boolean;\n resizable?: boolean;\n hideable?: boolean;\n minWidth?: number;\n maxWidth?: number;\n align?: \"left\" | \"center\" | \"right\";\n render?: (value: unknown, row: T) => ReactNode;\n sortValue?: (value: unknown, row: T) => unknown;\n filterValue?: (value: unknown, row: T) => FilterValue;\n cellClassName?: string;\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<T extends Record<string, unknown> = Record<string, unknown>> =\n | DataTableColumn<T>\n | string;\n\nexport type DataTableProps<T extends Record<string, unknown> = Record<string, unknown>> = {\n data: T[];\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 emptyMessage?: string;\n className?: string;\n autoFilter?: boolean;\n showGlobalFilter?: boolean;\n globalFilter?: string;\n onGlobalFilterChange?: (value: string) => void;\n globalFilterPlaceholder?: string;\n defaultSort?: { key: string; dir?: SortDir };\n filterBarProps?: Omit<FilterBarProps, \"search\" | \"filters\">;\n getRowId?: (row: T, index: number) => string;\n onRowClick?: (row: T) => void;\n isRowClickable?: (row: T) => boolean;\n getRowHref?: (row: T) => string | undefined;\n renderExpandedRow?: (row: T, context: DataTableRowDetailContext<T>) => ReactNode;\n resizableColumns?: boolean;\n persistColumnWidths?: boolean;\n columnResizeStorageKey?: string;\n hideableColumns?: boolean;\n persistColumnVisibility?: boolean;\n columnVisibilityStorageKey?: string;\n density?: Density;\n defaultDensity?: Density;\n onDensityChange?: (density: Density | undefined) => void;\n persistDensity?: boolean;\n densityStorageKey?: string;\n showDensityControl?: boolean;\n showHeaderFilters?: boolean;\n};\n\nexport function DataTable<T extends Record<string, unknown>>({\n data,\n columns: columnsInput,\n emptyMessage: _emptyMessage = \"No data\",\n className,\n autoFilter = false,\n showGlobalFilter = true,\n globalFilter,\n onGlobalFilterChange,\n globalFilterPlaceholder = \"Search all columns…\",\n defaultSort,\n filterBarProps,\n getRowId,\n onRowClick,\n isRowClickable,\n getRowHref,\n renderExpandedRow,\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 showHeaderFilters = true,\n}: DataTableProps<T>) {\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 ?? `${COLUMN_WIDTH_STORAGE_PREFIX}:${columnKeysSignature}`;\n const resolvedColumnVisibilityStorageKey =\n columnVisibilityStorageKey ?? `${COLUMN_VISIBILITY_STORAGE_PREFIX}:${columnKeysSignature}`;\n const resolvedDensityStorageKey =\n densityStorageKey ?? `${DENSITY_STORAGE_PREFIX}:${columnKeysSignature}`;\n const [columnWidths, setColumnWidths] = useState<Record<string, number>>(() =>\n persistColumnWidths ? readStoredColumnWidths(resolvedColumnResizeStorageKey, columns) : {},\n );\n const [hiddenColumns, setHiddenColumns] = useState<Record<string, boolean>>(() =>\n persistColumnVisibility\n ? readStoredHiddenColumns(resolvedColumnVisibilityStorageKey, columns)\n : {},\n );\n const densityControlled = density !== undefined;\n const [localDensityOverride, setLocalDensityOverride] = useState<Density | undefined>(() => {\n if (densityControlled) return density;\n if (persistDensity)\n return readStoredDensityOverride(resolvedDensityStorageKey) ?? defaultDensity;\n return defaultDensity;\n });\n const [columnMenu, setColumnMenu] = useState<ColumnMenuState | null>(null);\n const [headerFilterMenu, setHeaderFilterMenu] = 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<Record<string, FilterBarNumberValue>>({});\n const [expandedRows, setExpandedRows] = useState<Record<string, boolean>>({});\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 }, [columnKeysSignature, persistColumnWidths, resolvedColumnResizeStorageKey]);\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 }, [columnKeysSignature, persistColumnVisibility, resolvedColumnVisibilityStorageKey]);\n\n useEffect(() => {\n if (!persistColumnVisibility) return;\n writeStoredHiddenColumns(resolvedColumnVisibilityStorageKey, hiddenColumns);\n }, [hiddenColumns, persistColumnVisibility, resolvedColumnVisibilityStorageKey]);\n\n useEffect(() => {\n if (densityControlled) return;\n setLocalDensityOverride(\n persistDensity\n ? (readStoredDensityOverride(resolvedDensityStorageKey) ?? defaultDensity)\n : defaultDensity,\n );\n }, [defaultDensity, densityControlled, persistDensity, resolvedDensityStorageKey]);\n\n useEffect(() => {\n if (densityControlled || !persistDensity) return;\n writeStoredDensityOverride(resolvedDensityStorageKey, localDensityOverride);\n }, [densityControlled, localDensityOverride, persistDensity, resolvedDensityStorageKey]);\n\n useEffect(() => {\n if (!columnMenu && !headerFilterMenu) return;\n\n const close = () => {\n setColumnMenu(null);\n setHeaderFilterMenu(null);\n };\n const closeOnEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") close();\n };\n\n document.addEventListener(\"click\", close);\n document.addEventListener(\"keydown\", closeOnEscape);\n return () => {\n document.removeEventListener(\"click\", close);\n document.removeEventListener(\"keydown\", closeOnEscape);\n };\n }, [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 = resolvePath(row, column.key);\n const parsed = parseTimestamp(raw);\n if (parsed) dates.push(parsed);\n }\n const dataFormat = chooseTimestampFormat(dates);\n out[column.key] = modeToFormat(column.timestamp?.mode ?? \"auto\", dataFormat);\n }\n return out;\n }, [columns, data]);\n\n const effectiveColumns = useMemo<DataTableColumn<T>[]>(\n () => columns.map((column) => applyKindDefaults<T>(column, timestampFormats[column.key])),\n [columns, timestampFormats],\n );\n\n const visibleColumns = useMemo(() => {\n if (!hideableColumns) return effectiveColumns;\n const next = effectiveColumns.filter((column) => !hiddenColumns[column.key]);\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 = hideableColumns && hideableColumnCount > 1;\n const resolvedShowDensityControl = showDensityControl ?? showColumnVisibilityControl;\n const showTablePreferencesControl = showColumnVisibilityControl || resolvedShowDensityControl;\n const densityOverride = densityControlled ? density : localDensityOverride;\n\n // For each kind:\"tags\" column, expose a TagActions value backed by this\n // table's multiFilters slot. The + / − icons inside each tag mutate the\n // same Record<token, mode> shape that the filter-bar dropdown uses, so\n // the existing filter pipeline picks up the change without changes.\n const tagActionsByColumn = useMemo(() => {\n const out: Record<string, TagActionsContextValue> = {};\n for (const column of visibleColumns) {\n if (column.kind !== \"tags\") continue;\n const columnKey = column.key;\n const current = (multiFilters[columnKey] ?? {}) as Record<string, TagFilterMode>;\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 }, [multiFilters, visibleColumns]);\n\n // The first kind:\"timestamp\" column (with autoRangeFilter not disabled) gets\n // the auto-mounted FilterBar time-range picker. The user can override by\n // supplying their own filterBarProps.timeRange.\n const timeRangeColumn = useMemo(() => {\n if (filterBarProps?.timeRange) return null;\n return (\n visibleColumns.find(\n (column) =>\n column.kind === \"timestamp\" &&\n column.filterable !== false &&\n column.timestamp?.autoRangeFilter !== false,\n ) ?? null\n );\n }, [filterBarProps?.timeRange, visibleColumns]);\n\n const filterableColumns = useMemo(\n () =>\n visibleColumns.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 [visibleColumns],\n );\n\n const generatedFilters = useMemo<GeneratedFilter<T>[]>(() => {\n if (!autoFilter) 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) => left.localeCompare(right, undefined, { numeric: true }))\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, rows]);\n\n useEffect(() => {\n setTextFilters((current) => pruneTextFilterState(current, generatedFilters));\n setMultiFilters((current) => pruneMultiFilterState(current, generatedFilters));\n setNumberFilters((current) => pruneNumberFilterState(current, generatedFilters));\n }, [generatedFilters]);\n\n const globalFilterControlled = globalFilter !== undefined;\n const effectiveGlobalFilter = globalFilterControlled ? globalFilter : 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) => updateFilterRecord(current, columnKey, next)),\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) => updateFilterRecord(current, columnKey, next)),\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) => updateNumberFilterValue(current, columnKey, next)),\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) => updateFilterValue(current, columnKey, next)),\n };\n }),\n [generatedFilters, multiFilters, numberFilters, textFilters],\n );\n const nativeFilterByColumn = useMemo(\n () => new Map(nativeFilters.map((filter) => [filter.key, filter])),\n [nativeFilters],\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 (!autoFilter || !timeRangeColumn) return null;\n return {\n from: timeRangeFilter.from,\n to: timeRangeFilter.to,\n onApply: (from, to) => setTimeRangeFilter({ from, to }),\n presets: timeRangeColumn.timestamp?.rangePresets ?? TIMESTAMP_RANGE_PRESETS,\n fromPlaceholder: \"now-24h\",\n toPlaceholder: \"now\",\n emptyLabel: \"Any time\",\n };\n }, [autoFilter, timeRangeColumn, timeRangeFilter.from, timeRangeFilter.to]);\n const showFilterBar =\n (autoFilter && (showGlobalFilter || nativeFilters.length > 0 || !!autoTimeRange)) ||\n hasCustomFilterBarContent ||\n showTablePreferencesControl;\n const setDensityOverride = (next: Density | undefined) => {\n if (!densityControlled) setLocalDensityOverride(next);\n onDensityChange?.(next);\n };\n const filterBarTrailing = showTablePreferencesControl ? (\n <>\n {filterBarProps?.trailing}\n <ColumnVisibilityTrigger onOpen={(event) => setColumnMenu(menuStateFromTrigger(event))} />\n </>\n ) : (\n filterBarProps?.trailing\n );\n const showHeaderFilterControls = autoFilter && showHeaderFilters;\n\n const filteredRows = useMemo(() => {\n const globalNeedle = effectiveGlobalFilter.trim().toLowerCase();\n const now = new Date();\n const rangeFromDate = timeRangeColumn ? resolveDateMath(timeRangeFilter.from, now) : null;\n const rangeToDate = timeRangeColumn ? resolveDateMath(timeRangeFilter.to, now) : null;\n const rangeColumnKey = timeRangeColumn?.key;\n\n return rows.filter(({ row }) => {\n if (rangeColumnKey && (rangeFromDate || rangeToDate)) {\n const raw = resolvePath(row, rangeColumnKey);\n const ts = parseTimestamp(raw);\n if (!ts) return false;\n if (rangeFromDate && ts.getTime() < rangeFromDate.getTime()) 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] ?? \"\").trim().toLowerCase();\n if (needle && !tokens.some((token) => token.toLowerCase().includes(needle))) {\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) => (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 (include.length > 0 && !tokens.some((token) => include.includes(token))) {\n return false;\n }\n\n if (exclude.length > 0 && tokens.some((token) => exclude.includes(token))) {\n return false;\n }\n }\n }\n\n return true;\n });\n }, [\n effectiveGlobalFilter,\n filterableColumns,\n generatedFilters,\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 { sorted, sort, toggle } = useSort(filteredRows, {\n defaultDir: defaultSort?.dir ?? \"asc\",\n resolvers: sortResolvers,\n ...(defaultSort?.key ? { defaultKey: defaultSort.key } : {}),\n });\n\n const startColumnResize = (event: ReactMouseEvent<HTMLElement>, column: DataTableColumn<T>) => {\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 = measuredWidth || columnWidths[column.key] || defaultColumnWidth(column);\n\n const onMove = (moveEvent: MouseEvent) => {\n const nextWidth = clampColumnWidth(column, startWidth + moveEvent.clientX - startX);\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 = (event: ReactMouseEvent<HTMLElement>, column: DataTableColumn<T>) => {\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(header.parentElement?.children ?? []).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 = (event: ReactMouseEvent<HTMLElement>, columnKey: string) => {\n event.preventDefault();\n event.stopPropagation();\n setHeaderFilterMenu(menuStateFromTrigger(event, columnKey));\n };\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-3\", className)} data-density={densityOverride}>\n {showFilterBar && (\n <FilterBar\n {...filterBarProps}\n {...(autoFilter && showGlobalFilter\n ? {\n search: {\n value: effectiveGlobalFilter,\n onChange: setEffectiveGlobalFilter,\n placeholder: globalFilterPlaceholder,\n },\n }\n : {})}\n {...(autoTimeRange ? { timeRange: autoTimeRange } : {})}\n trailing={filterBarTrailing}\n filters={nativeFilters}\n />\n )}\n\n <div className=\"min-h-0 flex-1 overflow-auto rounded-md border border-border\">\n <table className=\"w-max table-auto text-left text-sm\">\n <colgroup>\n {visibleColumns.map((column) => (\n <col\n key={column.key}\n style={columnStyle(column, columnWidths)}\n className={column.shrink && !column.grow ? \"w-px\" : undefined}\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 {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 && column.resizable !== false && \"select-none\",\n column.headerClassName,\n )}\n onContextMenu={(event) => openHeaderColumnMenu(event, column)}\n >\n <div\n className={cn(\n \"flex min-w-0 items-center gap-1\",\n headerAlignmentClass(column.align),\n resizableColumns && column.resizable !== false && \"pr-2\",\n )}\n >\n <span className=\"min-w-0\">\n {column.sortable === false ? (\n <span>{column.label}</span>\n ) : (\n <SortableHeader\n active={sort?.key === column.key}\n {...(sort?.key === column.key ? { dir: sort.dir } : {})}\n {...(column.align ? { align: column.align } : {})}\n onClick={() => toggle(column.key)}\n >\n {column.label}\n </SortableHeader>\n )}\n </span>\n {showHeaderFilterControls &&\n (nativeFilterByColumn.has(column.key) ||\n (autoTimeRange && timeRangeColumn?.key === column.key)) && (\n <HeaderFilterButton\n column={column}\n active={\n nativeFilterByColumn.has(column.key)\n ? isFilterBarFilterActive(nativeFilterByColumn.get(column.key)!)\n : Boolean(timeRangeFilter.from || timeRangeFilter.to)\n }\n onOpen={(event) => openHeaderFilterMenu(event, column.key)}\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 flex 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\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onDoubleClick={(event) => autoFitColumn(event, column)}\n onMouseDown={(event) => startColumnResize(event, column)}\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 {sorted.map((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 tagActionsByColumn,\n }) ?? null;\n const expandable = expandedContent !== null;\n const rowClickEnabled = isRowClickable?.(record.row) ?? !!onRowClick;\n const clickable = !!href || rowClickEnabled || expandable;\n\n return (\n <Fragment key={record.id}>\n <tr\n className={cn(\n \"border-b border-border/60 align-top\",\n clickable && \"cursor-pointer hover:bg-accent/40\",\n )}\n onClick={() => {\n if (expandable) {\n setExpandedRows((current) => ({\n ...current,\n [record.id]: !current[record.id],\n }));\n }\n if (rowClickEnabled) {\n onRowClick?.(record.row);\n }\n }}\n >\n {visibleColumns.map((column, index) => {\n const rawValue = resolvePath(record.row, column.key);\n let content: ReactNode = column.render\n ? column.render(rawValue, record.row)\n : formatCell(rawValue);\n\n // Tag cells get the + / − filter affordance via\n // context; copy-to-clipboard works without it too.\n if (column.kind === \"tags\" && tagActionsByColumn[column.key]) {\n content = (\n <TagActionsProvider value={tagActionsByColumn[column.key]!}>\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 >\n <CellContent\n column={column}\n {...(columnWidths[column.key] !== undefined\n ? { width: columnWidths[column.key] }\n : {})}\n >\n {href && index === 0 ? (\n <a href={href} className=\"hover:underline\">\n {content}\n </a>\n ) : (\n content\n )}\n </CellContent>\n </td>\n );\n })}\n </tr>\n {expanded && expandedContent && (\n <tr>\n <td colSpan={visibleColumns.length} className=\"bg-muted/40 p-density-3\">\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 </tbody>\n </table>\n </div>\n\n <div className=\"px-1 text-xs text-muted-foreground\">\n {sorted.length} of {data.length} row{data.length === 1 ? \"\" : \"s\"}\n </div>\n {columnMenu && showTablePreferencesControl && (\n <ColumnVisibilityMenu\n columns={effectiveColumns}\n hiddenColumns={hiddenColumns}\n anchor={columnMenu}\n showColumnVisibilityControl={showColumnVisibilityControl}\n showDensityControl={resolvedShowDensityControl}\n densityOverride={densityOverride}\n visibleHideableColumnCount={visibleHideableColumnCount}\n onToggle={toggleColumnVisibility}\n onShowAll={showAllColumns}\n onDensityChange={setDensityOverride}\n onClose={() => setColumnMenu(null)}\n />\n )}\n {headerFilterMenu && (\n <HeaderFilterMenu\n filter={nativeFilterByColumn.get(headerFilterMenu.columnKey ?? \"\")}\n {...(autoTimeRange && timeRangeColumn?.key === headerFilterMenu.columnKey\n ? { timeRange: autoTimeRange }\n : {})}\n anchor={headerFilterMenu}\n onClose={() => setHeaderFilterMenu(null)}\n />\n )}\n </div>\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 <Icon name=\"codicon:filter\" className=\"text-xs\" />\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 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 name=\"codicon:close\" 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 && <FilterBarRangePanel kind=\"time\" label=\"Time range\" {...timeRange} />}\n </div>\n </div>\n );\n}\n\nfunction clearFilterBarFilter(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n filter.onChange(\"\");\n return;\n }\n\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n filter.onChange([]);\n return;\n }\n\n if (filter.kind === \"number\") {\n filter.onChange({});\n return;\n }\n\n if (filter.kind === \"boolean\") {\n filter.onChange(false);\n return;\n }\n\n filter.onChange({});\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-[34px] w-[34px] 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 name=\"codicon:ellipsis\" className=\"text-sm\" />\n </button>\n );\n}\n\nfunction ColumnVisibilityMenu<T extends Record<string, unknown>>({\n columns,\n hiddenColumns,\n anchor,\n showColumnVisibilityControl,\n showDensityControl,\n densityOverride,\n visibleHideableColumnCount,\n onToggle,\n onShowAll,\n onDensityChange,\n onClose,\n}: {\n columns: DataTableColumn<T>[];\n hiddenColumns: Record<string, boolean>;\n anchor: ColumnMenuState;\n showColumnVisibilityControl: boolean;\n showDensityControl: boolean;\n densityOverride: Density | undefined;\n visibleHideableColumnCount: number;\n onToggle: (column: DataTableColumn<T>) => void;\n onShowAll: () => void;\n onDensityChange: (density: Density | undefined) => 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 && isColumnHideable(activeColumn) && visibleHideableColumnCount > 1;\n\n return (\n <div\n role=\"menu\"\n aria-label=\"Column menu\"\n className=\"fixed z-50 min-w-[16rem] 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 name=\"codicon:eye-closed\" className=\"text-sm text-muted-foreground\" />\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 = !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 </div>\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\">Density</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 name=\"ph:arrows-in-line-vertical\" className=\"text-sm text-muted-foreground\" />\n <span className=\"min-w-0 flex-1 truncate\">Use page density</span>\n {current === \"inherit\" ? (\n <Icon name=\"ph:check\" 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 name={option.icon} className=\"text-sm text-muted-foreground\" />\n <span className=\"min-w-0 flex-1 truncate\">{option.label}</span>\n {active ? (\n <Icon name=\"ph:check\" 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\nfunction CellContent<T extends Record<string, unknown>>({\n column,\n width,\n children,\n}: {\n column: DataTableColumn<T>;\n width?: number;\n children: ReactNode;\n}) {\n return (\n <div\n className={cn(cellContentClassName(column, width), alignmentClass(column.align))}\n style={cellContentStyle(width)}\n >\n {children}\n </div>\n );\n}\n\nfunction getSortValue<T extends Record<string, unknown>>(row: T, column: DataTableColumn<T>) {\n const rawValue = resolvePath(row, column.key);\n return column.sortValue ? column.sortValue(rawValue, row) : rawValue;\n}\n\nfunction getFilterCandidate<T extends Record<string, unknown>>(row: T, column: DataTableColumn<T>) {\n const rawValue = resolvePath(row, column.key);\n return column.filterValue ? column.filterValue(rawValue, row) : rawValue;\n}\n\nfunction getFilterTokens<T extends Record<string, unknown>>(row: T, column: DataTableColumn<T>) {\n return normalizeTokens(getFilterCandidate(row, column));\n}\n\nfunction getFilterNumbers<T extends Record<string, unknown>>(row: T, column: DataTableColumn<T>) {\n return normalizeNumbers(getFilterCandidate(row, column));\n}\n\nfunction normalizeTokens(value: FilterValue | unknown): string[] {\n if (Array.isArray(value)) {\n return value.flatMap((item) => normalizeTokens(item)).filter(Boolean);\n }\n\n if (value == null) return [];\n if (typeof value === \"object\") return [JSON.stringify(value)];\n\n const token = String(value).trim();\n return token ? [token] : [];\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(state: Record<string, string>, key: string, nextValue: string) {\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(state: Record<string, string>, filters: GeneratedFilter<any>[]) {\n return pruneFilterState(state, filters, \"text\", (value) => !String(value ?? \"\").trim());\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((filter) => filter.kind === \"multi\" || filter.kind === \"nested-multi\")\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) => !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.filter((filter) => filter.kind === kind).map((filter) => filter.column.key),\n );\n return Object.fromEntries(\n Object.entries(state).filter(([key, value]) => allowed.has(key) && !isEmpty(value)),\n ) as Record<string, T>;\n}\n\nfunction resolvePath(obj: unknown, path: string): unknown {\n return path.split(\".\").reduce<unknown>((current, key) => {\n if (current && typeof current === \"object\") {\n return (current as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\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: column.sortValue ?? ((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 ?? ((value) => tagFilterTokens(value as TagsValue, separator)),\n sortValue:\n column.sortValue ?? ((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 ? (typeof value === \"string\" ? value : status) : undefined;\n const title =\n opts?.title?.(value, row) ?? (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 prettifyKey(key: string) {\n return key\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/[_-]/g, \" \")\n .replace(/\\b\\w/g, (value) => value.toUpperCase())\n .trim();\n}\n\nfunction labelText<T extends Record<string, unknown>>(column: DataTableColumn<T>) {\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>>(column: DataTableColumn<T>) {\n return column.hideable !== false;\n}\n\nfunction isFilterBarFilterActive(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n return String(filter.value ?? \"\").trim() !== \"\";\n }\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n return filter.value.length > 0;\n }\n if (filter.kind === \"number\") {\n return (\n String(filter.value.min ?? \"\").trim() !== \"\" || String(filter.value.max ?? \"\").trim() !== \"\"\n );\n }\n if (filter.kind === \"boolean\") return filter.value;\n return Object.keys(filter.value).length > 0;\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 = 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(padding, Math.min(event.clientX, viewportWidth - width - padding)),\n y: Math.max(padding, Math.min(event.clientY, viewportHeight - height - padding)),\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 = typeof window === \"undefined\" ? rect.right + width : window.innerWidth;\n const viewportHeight = typeof window === \"undefined\" ? rect.bottom + height : window.innerHeight;\n\n const position = {\n x: Math.max(padding, Math.min(rect.right - width, viewportWidth - width - padding)),\n y: Math.max(padding, Math.min(rect.bottom + 6, viewportHeight - height - padding)),\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 && cell.cellIndex === columnIndex && 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 parseCssPixelValue(styles.paddingLeft) + parseCssPixelValue(styles.paddingRight);\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)) return {};\n\n return pruneColumnWidths(parsed as Record<string, unknown>, columns);\n } catch {\n return {};\n }\n}\n\nfunction writeStoredColumnWidths(storageKey: string, widths: Record<string, number>) {\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)) return {};\n\n return pruneHiddenColumns(parsed as Record<string, unknown>, columns);\n } catch {\n return {};\n }\n}\n\nfunction writeStoredHiddenColumns(storageKey: string, hiddenColumns: Record<string, boolean>) {\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(storageKey: string, density: Density | undefined) {\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)) 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((column) => next[column.key] !== true).length;\n if (hideable.length > 0 && visibleHideableCount === 0) {\n delete next[hideable[0]!.key];\n }\n\n return next;\n}\n\nfunction sameColumnWidths(left: Record<string, number>, right: Record<string, number>) {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every(\n (key) => Object.prototype.hasOwnProperty.call(right, key) && left[key] === right[key],\n )\n );\n}\n\nfunction sameHiddenColumns(left: Record<string, boolean>, right: Record<string, boolean>) {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every(\n (key) => Object.prototype.hasOwnProperty.call(right, key) && left[key] === right[key],\n )\n );\n}\n\nfunction defaultColumnWidth<T extends Record<string, unknown>>(column: DataTableColumn<T>) {\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) ? Math.max(1, minWidth) : DEFAULT_COLUMN_MIN_WIDTH;\n const maximum =\n maxWidth != null && Number.isFinite(maxWidth) ? Math.max(minimum, maxWidth) : 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 cellContentStyle(width: number | undefined): CSSProperties | undefined {\n return width ? { maxWidth: `${width}px` } : undefined;\n}\n\nfunction cellContentClassName<T extends Record<string, unknown>>(\n column: DataTableColumn<T>,\n width?: number,\n): TdHTMLAttributes<HTMLTableCellElement>[\"className\"] {\n const resized = width !== undefined;\n const base = \"w-full truncate\";\n if (column.grow) return cn(base, resized ? \"min-w-0\" : \"min-w-56 max-w-[36rem]\");\n if (column.shrink) return cn(base, \"min-w-0 whitespace-nowrap\", !resized && \"max-w-[16rem]\");\n return cn(base, \"min-w-0\", !resized && \"max-w-[18rem]\");\n}\n\nexport function inferColumns<T extends Record<string, unknown>>(data: T[]): DataTableColumn<T>[] {\n if (data.length === 0) return [];\n\n const keys = new Set<string>();\n for (const row of data.slice(0, 20)) {\n Object.keys(row)\n .filter((key) => !key.startsWith(\"_\"))\n .forEach((key) => keys.add(key));\n }\n\n return Array.from(keys).map((key) => ({\n key,\n label: prettifyKey(key),\n sortable: true,\n filterable: true,\n }));\n}\n"],"names":["_a","Fragment"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type FilterMode = "active" | "neutral" | "include" | "exclude";
|
|
3
|
+
export type FilterPillProps = {
|
|
4
|
+
mode?: FilterMode;
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
count?: number;
|
|
7
|
+
icon?: string;
|
|
8
|
+
badge?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Tri-state handler. When provided the pill renders as a toggle with a left
|
|
11
|
+
* minus (exclude) and right plus (include) region. Clicking a side toggles
|
|
12
|
+
* that state against "neutral"; clicking the label cycles neutral → include
|
|
13
|
+
* → exclude → neutral.
|
|
14
|
+
*/
|
|
15
|
+
onModeChange?: (next: FilterMode) => void;
|
|
16
|
+
/** Legacy single-click handler, used when onModeChange is not provided. */
|
|
17
|
+
onClick?: () => void;
|
|
18
|
+
title?: string;
|
|
19
|
+
togglePosition?: "left" | "right";
|
|
20
|
+
className?: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function FilterPill({ mode, label, count, icon, badge, onModeChange, onClick, title, togglePosition, className, }: FilterPillProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export type FilterPillGroupProps = {
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
className?: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function FilterPillGroup({ children, className }: FilterPillGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export declare function FilterSeparator(): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
//# sourceMappingURL=FilterPill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterPill.d.ts","sourceRoot":"","sources":["../../src/data/FilterPill.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAC1C,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA2EF,wBAAgB,UAAU,CAAC,EACzB,IAAgB,EAChB,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,YAAY,EACZ,OAAO,EACP,KAAK,EACL,cAAuB,EACvB,SAAS,GACV,EAAE,eAAe,2CAiEjB;AAeD,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,oBAAoB,2CAE5E;AAED,wBAAgB,eAAe,4CAM9B"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { Icon } from "./Icon.js";
|
|
4
|
+
function bodyClasses(mode) {
|
|
5
|
+
switch (mode) {
|
|
6
|
+
case "active":
|
|
7
|
+
return "bg-primary/10 border-primary/40 text-primary font-medium";
|
|
8
|
+
case "include":
|
|
9
|
+
return "bg-green-500/10 border-green-500/50 text-green-700 dark:text-green-400 font-medium";
|
|
10
|
+
case "exclude":
|
|
11
|
+
return "bg-red-500/10 border-red-500/50 text-red-700 dark:text-red-400 font-medium";
|
|
12
|
+
case "neutral":
|
|
13
|
+
default:
|
|
14
|
+
return "border-border text-muted-foreground hover:bg-accent";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const SLOT_TRANSLATE = {
|
|
18
|
+
exclude: "translate-x-0",
|
|
19
|
+
neutral: "translate-x-4",
|
|
20
|
+
include: "translate-x-8"
|
|
21
|
+
};
|
|
22
|
+
function TristateSwitch({
|
|
23
|
+
mode,
|
|
24
|
+
onChange,
|
|
25
|
+
ariaLabel
|
|
26
|
+
}) {
|
|
27
|
+
const slot = mode === "exclude" ? "exclude" : mode === "include" ? "include" : "neutral";
|
|
28
|
+
const bg = slot === "exclude" ? "bg-red-500/80" : slot === "include" ? "bg-green-500/80" : "bg-muted";
|
|
29
|
+
return /* @__PURE__ */ jsx(
|
|
30
|
+
"button",
|
|
31
|
+
{
|
|
32
|
+
type: "button",
|
|
33
|
+
"aria-label": ariaLabel,
|
|
34
|
+
title: ariaLabel,
|
|
35
|
+
onClick: (event) => {
|
|
36
|
+
event.preventDefault();
|
|
37
|
+
event.stopPropagation();
|
|
38
|
+
onChange(nextTriStateMode(mode));
|
|
39
|
+
},
|
|
40
|
+
className: cn(
|
|
41
|
+
"relative inline-flex h-5 w-[52px] shrink-0 overflow-hidden rounded-full transition-colors duration-200",
|
|
42
|
+
bg
|
|
43
|
+
),
|
|
44
|
+
children: /* @__PURE__ */ jsx(
|
|
45
|
+
"span",
|
|
46
|
+
{
|
|
47
|
+
"aria-hidden": true,
|
|
48
|
+
className: cn(
|
|
49
|
+
"pointer-events-none absolute left-0.5 top-0.5 z-20 flex size-4 items-center justify-center rounded-full bg-white shadow-sm transition-transform duration-150",
|
|
50
|
+
SLOT_TRANSLATE[slot]
|
|
51
|
+
),
|
|
52
|
+
children: slot !== "neutral" && /* @__PURE__ */ jsx(
|
|
53
|
+
Icon,
|
|
54
|
+
{
|
|
55
|
+
name: slot === "exclude" ? "codicon:close" : "codicon:check",
|
|
56
|
+
className: cn(
|
|
57
|
+
"text-[10px]",
|
|
58
|
+
slot === "exclude" && "text-red-600",
|
|
59
|
+
slot === "include" && "text-green-600"
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
function FilterPill({
|
|
69
|
+
mode = "neutral",
|
|
70
|
+
label,
|
|
71
|
+
count,
|
|
72
|
+
icon,
|
|
73
|
+
badge,
|
|
74
|
+
onModeChange,
|
|
75
|
+
onClick,
|
|
76
|
+
title,
|
|
77
|
+
togglePosition = "left",
|
|
78
|
+
className
|
|
79
|
+
}) {
|
|
80
|
+
const triState = !!onModeChange;
|
|
81
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
82
|
+
count !== void 0 && /* @__PURE__ */ jsx(
|
|
83
|
+
"span",
|
|
84
|
+
{
|
|
85
|
+
className: cn(
|
|
86
|
+
"inline-flex items-center justify-center min-w-[16px] h-[16px] px-1 rounded-full text-[10px] font-bold text-white",
|
|
87
|
+
badge ?? "bg-muted-foreground"
|
|
88
|
+
),
|
|
89
|
+
children: count
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
icon && /* @__PURE__ */ jsx(Icon, { name: icon, className: "text-sm" }),
|
|
93
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: label })
|
|
94
|
+
] });
|
|
95
|
+
if (triState) {
|
|
96
|
+
const control = /* @__PURE__ */ jsx(
|
|
97
|
+
TristateSwitch,
|
|
98
|
+
{
|
|
99
|
+
mode,
|
|
100
|
+
onChange: onModeChange,
|
|
101
|
+
...title ? { ariaLabel: title } : {}
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
const labelContent = /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-0 items-center gap-1.5 text-xs text-foreground", children: content });
|
|
105
|
+
return /* @__PURE__ */ jsx("span", { className: cn("inline-flex items-center gap-1.5 select-none", className), title, children: togglePosition === "right" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
106
|
+
labelContent,
|
|
107
|
+
control
|
|
108
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
109
|
+
control,
|
|
110
|
+
labelContent
|
|
111
|
+
] }) });
|
|
112
|
+
}
|
|
113
|
+
return /* @__PURE__ */ jsxs(
|
|
114
|
+
"button",
|
|
115
|
+
{
|
|
116
|
+
type: "button",
|
|
117
|
+
onClick,
|
|
118
|
+
title,
|
|
119
|
+
className: cn(
|
|
120
|
+
"inline-flex items-center gap-1.5 text-xs px-2 py-0.5 rounded-full border transition-colors",
|
|
121
|
+
bodyClasses(mode),
|
|
122
|
+
className
|
|
123
|
+
),
|
|
124
|
+
children: [
|
|
125
|
+
/* @__PURE__ */ jsx(LegacyMarker, { mode }),
|
|
126
|
+
content
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
function LegacyMarker({ mode }) {
|
|
132
|
+
if (mode === "include") return /* @__PURE__ */ jsx(Icon, { name: "codicon:add", className: "text-xs" });
|
|
133
|
+
if (mode === "exclude") return /* @__PURE__ */ jsx(Icon, { name: "codicon:remove", className: "text-xs" });
|
|
134
|
+
if (mode === "active") return /* @__PURE__ */ jsx("span", { className: "w-2 h-2 rounded-full bg-current" });
|
|
135
|
+
return /* @__PURE__ */ jsx("span", { className: "w-2 h-2 rounded-full bg-current opacity-30" });
|
|
136
|
+
}
|
|
137
|
+
function nextTriStateMode(mode) {
|
|
138
|
+
if (mode === "include") return "exclude";
|
|
139
|
+
if (mode === "exclude") return "neutral";
|
|
140
|
+
return "include";
|
|
141
|
+
}
|
|
142
|
+
function FilterPillGroup({ children, className }) {
|
|
143
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-1.5 flex-wrap", className), children });
|
|
144
|
+
}
|
|
145
|
+
function FilterSeparator() {
|
|
146
|
+
return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-border mx-0.5", children: "|" });
|
|
147
|
+
}
|
|
148
|
+
export {
|
|
149
|
+
FilterPill,
|
|
150
|
+
FilterPillGroup,
|
|
151
|
+
FilterSeparator
|
|
152
|
+
};
|
|
153
|
+
//# sourceMappingURL=FilterPill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterPill.js","sources":["../../src/data/FilterPill.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"./Icon\";\n\nexport type FilterMode = \"active\" | \"neutral\" | \"include\" | \"exclude\";\n\nexport type FilterPillProps = {\n mode?: FilterMode;\n label: ReactNode;\n count?: number;\n icon?: string;\n badge?: string;\n /**\n * Tri-state handler. When provided the pill renders as a toggle with a left\n * minus (exclude) and right plus (include) region. Clicking a side toggles\n * that state against \"neutral\"; clicking the label cycles neutral → include\n * → exclude → neutral.\n */\n onModeChange?: (next: FilterMode) => void;\n /** Legacy single-click handler, used when onModeChange is not provided. */\n onClick?: () => void;\n title?: string;\n togglePosition?: \"left\" | \"right\";\n className?: string;\n};\n\nfunction bodyClasses(mode: FilterMode): string {\n switch (mode) {\n case \"active\":\n return \"bg-primary/10 border-primary/40 text-primary font-medium\";\n case \"include\":\n return \"bg-green-500/10 border-green-500/50 text-green-700 dark:text-green-400 font-medium\";\n case \"exclude\":\n return \"bg-red-500/10 border-red-500/50 text-red-700 dark:text-red-400 font-medium\";\n case \"neutral\":\n default:\n return \"border-border text-muted-foreground hover:bg-accent\";\n }\n}\n\ntype SlotMode = \"exclude\" | \"neutral\" | \"include\";\n\nconst SLOT_TRANSLATE: Record<SlotMode, string> = {\n exclude: \"translate-x-0\",\n neutral: \"translate-x-4\",\n include: \"translate-x-8\",\n};\n\nfunction TristateSwitch({\n mode,\n onChange,\n ariaLabel,\n}: {\n mode: FilterMode;\n onChange: (next: FilterMode) => void;\n ariaLabel?: string;\n}) {\n const slot: SlotMode =\n mode === \"exclude\" ? \"exclude\" : mode === \"include\" ? \"include\" : \"neutral\";\n const bg =\n slot === \"exclude\" ? \"bg-red-500/80\" : slot === \"include\" ? \"bg-green-500/80\" : \"bg-muted\";\n\n return (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n title={ariaLabel}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onChange(nextTriStateMode(mode));\n }}\n className={cn(\n \"relative inline-flex h-5 w-[52px] shrink-0 overflow-hidden rounded-full transition-colors duration-200\",\n bg,\n )}\n >\n <span\n aria-hidden\n className={cn(\n \"pointer-events-none absolute left-0.5 top-0.5 z-20 flex size-4 items-center justify-center rounded-full bg-white shadow-sm transition-transform duration-150\",\n SLOT_TRANSLATE[slot],\n )}\n >\n {slot !== \"neutral\" && (\n <Icon\n name={slot === \"exclude\" ? \"codicon:close\" : \"codicon:check\"}\n className={cn(\n \"text-[10px]\",\n slot === \"exclude\" && \"text-red-600\",\n slot === \"include\" && \"text-green-600\",\n )}\n />\n )}\n </span>\n </button>\n );\n}\n\nexport function FilterPill({\n mode = \"neutral\",\n label,\n count,\n icon,\n badge,\n onModeChange,\n onClick,\n title,\n togglePosition = \"left\",\n className,\n}: FilterPillProps) {\n const triState = !!onModeChange;\n const content = (\n <>\n {count !== undefined && (\n <span\n className={cn(\n \"inline-flex items-center justify-center min-w-[16px] h-[16px] px-1 rounded-full text-[10px] font-bold text-white\",\n badge ?? \"bg-muted-foreground\",\n )}\n >\n {count}\n </span>\n )}\n {icon && <Icon name={icon} className=\"text-sm\" />}\n <span className=\"truncate\">{label}</span>\n </>\n );\n\n if (triState) {\n const control = (\n <TristateSwitch\n mode={mode}\n onChange={onModeChange!}\n {...(title ? { ariaLabel: title } : {})}\n />\n );\n const labelContent = (\n <span className=\"inline-flex min-w-0 items-center gap-1.5 text-xs text-foreground\">\n {content}\n </span>\n );\n\n return (\n <span className={cn(\"inline-flex items-center gap-1.5 select-none\", className)} title={title}>\n {togglePosition === \"right\" ? (\n <>\n {labelContent}\n {control}\n </>\n ) : (\n <>\n {control}\n {labelContent}\n </>\n )}\n </span>\n );\n }\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n title={title}\n className={cn(\n \"inline-flex items-center gap-1.5 text-xs px-2 py-0.5 rounded-full border transition-colors\",\n bodyClasses(mode),\n className,\n )}\n >\n <LegacyMarker mode={mode} />\n {content}\n </button>\n );\n}\n\nfunction LegacyMarker({ mode }: { mode: FilterMode }) {\n if (mode === \"include\") return <Icon name=\"codicon:add\" className=\"text-xs\" />;\n if (mode === \"exclude\") return <Icon name=\"codicon:remove\" className=\"text-xs\" />;\n if (mode === \"active\") return <span className=\"w-2 h-2 rounded-full bg-current\" />;\n return <span className=\"w-2 h-2 rounded-full bg-current opacity-30\" />;\n}\n\nfunction nextTriStateMode(mode: FilterMode): FilterMode {\n if (mode === \"include\") return \"exclude\";\n if (mode === \"exclude\") return \"neutral\";\n return \"include\";\n}\n\nexport type FilterPillGroupProps = {\n children: ReactNode;\n className?: string;\n};\n\nexport function FilterPillGroup({ children, className }: FilterPillGroupProps) {\n return <div className={cn(\"flex items-center gap-1.5 flex-wrap\", className)}>{children}</div>;\n}\n\nexport function FilterSeparator() {\n return (\n <span aria-hidden className=\"text-border mx-0.5\">\n |\n </span>\n );\n}\n"],"names":[],"mappings":";;;AA0BA,SAAS,YAAY,MAA0B;AAC7C,UAAQ,MAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EAAA;AAEb;AAIA,MAAM,iBAA2C;AAAA,EAC/C,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,OACJ,SAAS,YAAY,YAAY,SAAS,YAAY,YAAY;AACpE,QAAM,KACJ,SAAS,YAAY,kBAAkB,SAAS,YAAY,oBAAoB;AAElF,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY;AAAA,MACZ,OAAO;AAAA,MACP,SAAS,CAAC,UAAU;AAClB,cAAM,eAAA;AACN,cAAM,gBAAA;AACN,iBAAS,iBAAiB,IAAI,CAAC;AAAA,MACjC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAW;AAAA,UACX,WAAW;AAAA,YACT;AAAA,YACA,eAAe,IAAI;AAAA,UAAA;AAAA,UAGpB,mBAAS,aACR;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM,SAAS,YAAY,kBAAkB;AAAA,cAC7C,WAAW;AAAA,gBACT;AAAA,gBACA,SAAS,aAAa;AAAA,gBACtB,SAAS,aAAa;AAAA,cAAA;AAAA,YACxB;AAAA,UAAA;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA;AAGN;AAEO,SAAS,WAAW;AAAA,EACzB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AACF,GAAoB;AAClB,QAAM,WAAW,CAAC,CAAC;AACnB,QAAM,UACJ,qBAAA,UAAA,EACG,UAAA;AAAA,IAAA,UAAU,UACT;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,SAAS;AAAA,QAAA;AAAA,QAGV,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGJ,QAAQ,oBAAC,MAAA,EAAK,MAAM,MAAM,WAAU,WAAU;AAAA,IAC/C,oBAAC,QAAA,EAAK,WAAU,YAAY,UAAA,MAAA,CAAM;AAAA,EAAA,GACpC;AAGF,MAAI,UAAU;AACZ,UAAM,UACJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,UAAU;AAAA,QACT,GAAI,QAAQ,EAAE,WAAW,UAAU,CAAA;AAAA,MAAC;AAAA,IAAA;AAGzC,UAAM,eACJ,oBAAC,QAAA,EAAK,WAAU,oEACb,UAAA,SACH;AAGF,WACE,oBAAC,QAAA,EAAK,WAAW,GAAG,gDAAgD,SAAS,GAAG,OAC7E,UAAA,mBAAmB,UAClB,qBAAA,UAAA,EACG,UAAA;AAAA,MAAA;AAAA,MACA;AAAA,IAAA,EAAA,CACH,IAEA,qBAAA,UAAA,EACG,UAAA;AAAA,MAAA;AAAA,MACA;AAAA,IAAA,EAAA,CACH,EAAA,CAEJ;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,YAAY,IAAI;AAAA,QAChB;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA,oBAAC,gBAAa,MAAY;AAAA,QACzB;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAEA,SAAS,aAAa,EAAE,QAA8B;AACpD,MAAI,SAAS,UAAW,QAAO,oBAAC,QAAK,MAAK,eAAc,WAAU,WAAU;AAC5E,MAAI,SAAS,UAAW,QAAO,oBAAC,QAAK,MAAK,kBAAiB,WAAU,WAAU;AAC/E,MAAI,SAAS,SAAU,QAAO,oBAAC,QAAA,EAAK,WAAU,mCAAkC;AAChF,SAAO,oBAAC,QAAA,EAAK,WAAU,6CAAA,CAA6C;AACtE;AAEA,SAAS,iBAAiB,MAA8B;AACtD,MAAI,SAAS,UAAW,QAAO;AAC/B,MAAI,SAAS,UAAW,QAAO;AAC/B,SAAO;AACT;AAOO,SAAS,gBAAgB,EAAE,UAAU,aAAmC;AAC7E,6BAAQ,OAAA,EAAI,WAAW,GAAG,uCAAuC,SAAS,GAAI,UAAS;AACzF;AAEO,SAAS,kBAAkB;AAChC,6BACG,QAAA,EAAK,eAAW,MAAC,WAAU,sBAAqB,UAAA,KAEjD;AAEJ;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type GaugeTone = "neutral" | "success" | "warning" | "danger" | "info";
|
|
3
|
+
export type GaugeProps = {
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
value: number;
|
|
6
|
+
max?: number;
|
|
7
|
+
tone?: GaugeTone;
|
|
8
|
+
suffix?: string;
|
|
9
|
+
icon?: string | ReactNode;
|
|
10
|
+
subtitle?: ReactNode;
|
|
11
|
+
meta?: ReactNode;
|
|
12
|
+
className?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function Gauge({ label, value, max, tone, suffix, icon, subtitle, meta, className, }: GaugeProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=Gauge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gauge.d.ts","sourceRoot":"","sources":["../../src/data/Gauge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9E,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAUF,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,KAAK,EACL,GAAS,EACT,IAAgB,EAChB,MAAY,EACZ,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,SAAS,GACV,EAAE,UAAU,2CA4BZ"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { Icon } from "./Icon.js";
|
|
4
|
+
const toneClass = {
|
|
5
|
+
neutral: "text-foreground",
|
|
6
|
+
success: "text-green-600 dark:text-green-400",
|
|
7
|
+
warning: "text-yellow-600 dark:text-yellow-400",
|
|
8
|
+
danger: "text-red-600 dark:text-red-400",
|
|
9
|
+
info: "text-blue-600 dark:text-blue-400"
|
|
10
|
+
};
|
|
11
|
+
function Gauge({
|
|
12
|
+
label,
|
|
13
|
+
value,
|
|
14
|
+
max = 100,
|
|
15
|
+
tone = "neutral",
|
|
16
|
+
suffix = "%",
|
|
17
|
+
icon,
|
|
18
|
+
subtitle,
|
|
19
|
+
meta,
|
|
20
|
+
className
|
|
21
|
+
}) {
|
|
22
|
+
const pct = max > 0 ? Math.round(value / max * 100) : 0;
|
|
23
|
+
const displayValue = max === 100 ? value : pct;
|
|
24
|
+
return /* @__PURE__ */ jsxs(
|
|
25
|
+
"div",
|
|
26
|
+
{
|
|
27
|
+
className: cn(
|
|
28
|
+
"flex min-h-28 w-[15.5rem] shrink-0 flex-col rounded-lg border border-border bg-card p-3",
|
|
29
|
+
className
|
|
30
|
+
),
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 text-xs text-muted-foreground", children: [
|
|
33
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-0 items-center gap-1.5", children: [
|
|
34
|
+
icon ? /* @__PURE__ */ jsx(GaugeIcon, { icon }) : null,
|
|
35
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: label })
|
|
36
|
+
] }),
|
|
37
|
+
meta ? /* @__PURE__ */ jsx("span", { className: "shrink-0 truncate", children: meta }) : null
|
|
38
|
+
] }),
|
|
39
|
+
/* @__PURE__ */ jsxs(
|
|
40
|
+
"span",
|
|
41
|
+
{
|
|
42
|
+
className: cn("mt-2 text-2xl font-semibold tabular-nums tracking-tight", toneClass[tone]),
|
|
43
|
+
children: [
|
|
44
|
+
displayValue,
|
|
45
|
+
suffix ? /* @__PURE__ */ jsx("span", { className: "ml-0.5 text-sm opacity-60", children: suffix }) : null
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
subtitle ? /* @__PURE__ */ jsx("span", { className: "mt-1 truncate text-xs text-muted-foreground", children: subtitle }) : null
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
function GaugeIcon({ icon }) {
|
|
55
|
+
if (typeof icon === "string") {
|
|
56
|
+
return /* @__PURE__ */ jsx(Icon, { name: icon, width: 16, height: 16, className: "text-muted-foreground" });
|
|
57
|
+
}
|
|
58
|
+
return /* @__PURE__ */ jsx("span", { className: "inline-flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground [&>svg]:h-4 [&>svg]:w-4", children: icon });
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
Gauge
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=Gauge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gauge.js","sources":["../../src/data/Gauge.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"./Icon\";\n\nexport type GaugeTone = \"neutral\" | \"success\" | \"warning\" | \"danger\" | \"info\";\n\nexport type GaugeProps = {\n label: ReactNode;\n value: number;\n max?: number;\n tone?: GaugeTone;\n suffix?: string;\n icon?: string | ReactNode;\n subtitle?: ReactNode;\n meta?: ReactNode;\n className?: string;\n};\n\nconst toneClass: Record<GaugeTone, string> = {\n neutral: \"text-foreground\",\n success: \"text-green-600 dark:text-green-400\",\n warning: \"text-yellow-600 dark:text-yellow-400\",\n danger: \"text-red-600 dark:text-red-400\",\n info: \"text-blue-600 dark:text-blue-400\",\n};\n\nexport function Gauge({\n label,\n value,\n max = 100,\n tone = \"neutral\",\n suffix = \"%\",\n icon,\n subtitle,\n meta,\n className,\n}: GaugeProps) {\n const pct = max > 0 ? Math.round((value / max) * 100) : 0;\n const displayValue = max === 100 ? value : pct;\n return (\n <div\n className={cn(\n \"flex min-h-28 w-[15.5rem] shrink-0 flex-col rounded-lg border border-border bg-card p-3\",\n className,\n )}\n >\n <div className=\"flex items-center justify-between gap-2 text-xs text-muted-foreground\">\n <span className=\"inline-flex min-w-0 items-center gap-1.5\">\n {icon ? <GaugeIcon icon={icon} /> : null}\n <span className=\"truncate\">{label}</span>\n </span>\n {meta ? <span className=\"shrink-0 truncate\">{meta}</span> : null}\n </div>\n <span\n className={cn(\"mt-2 text-2xl font-semibold tabular-nums tracking-tight\", toneClass[tone])}\n >\n {displayValue}\n {suffix ? <span className=\"ml-0.5 text-sm opacity-60\">{suffix}</span> : null}\n </span>\n {subtitle ? (\n <span className=\"mt-1 truncate text-xs text-muted-foreground\">{subtitle}</span>\n ) : null}\n </div>\n );\n}\n\nfunction GaugeIcon({ icon }: { icon: string | ReactNode }) {\n if (typeof icon === \"string\") {\n return <Icon name={icon} width={16} height={16} className=\"text-muted-foreground\" />;\n }\n\n return (\n <span className=\"inline-flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground [&>svg]:h-4 [&>svg]:w-4\">\n {icon}\n </span>\n );\n}\n"],"names":[],"mappings":";;;AAkBA,MAAM,YAAuC;AAAA,EAC3C,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AACR;AAEO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAe;AACb,QAAM,MAAM,MAAM,IAAI,KAAK,MAAO,QAAQ,MAAO,GAAG,IAAI;AACxD,QAAM,eAAe,QAAQ,MAAM,QAAQ;AAC3C,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA,qBAAC,OAAA,EAAI,WAAU,yEACb,UAAA;AAAA,UAAA,qBAAC,QAAA,EAAK,WAAU,4CACb,UAAA;AAAA,YAAA,OAAO,oBAAC,WAAA,EAAU,KAAA,CAAY,IAAK;AAAA,YACpC,oBAAC,QAAA,EAAK,WAAU,YAAY,UAAA,MAAA,CAAM;AAAA,UAAA,GACpC;AAAA,UACC,OAAO,oBAAC,QAAA,EAAK,WAAU,qBAAqB,gBAAK,IAAU;AAAA,QAAA,GAC9D;AAAA,QACA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW,GAAG,2DAA2D,UAAU,IAAI,CAAC;AAAA,YAEvF,UAAA;AAAA,cAAA;AAAA,cACA,SAAS,oBAAC,QAAA,EAAK,WAAU,6BAA6B,kBAAO,IAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAEzE,WACC,oBAAC,QAAA,EAAK,WAAU,+CAA+C,oBAAS,IACtE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,SAAS,UAAU,EAAE,QAAsC;AACzD,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,oBAAC,QAAK,MAAM,MAAM,OAAO,IAAI,QAAQ,IAAI,WAAU,wBAAA,CAAwB;AAAA,EACpF;AAEA,SACE,oBAAC,QAAA,EAAK,WAAU,0GACb,UAAA,MACH;AAEJ;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { SizeToken } from '../lib/size';
|
|
3
|
+
export type IconStyle = "plain" | "badge";
|
|
4
|
+
export type IconTone = "emerald" | "amber" | "rose" | "slate" | "sky" | "violet" | "neutral";
|
|
5
|
+
export type IconProps = {
|
|
6
|
+
name: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
width?: string | number;
|
|
9
|
+
height?: string | number;
|
|
10
|
+
rotate?: string | number;
|
|
11
|
+
flip?: string;
|
|
12
|
+
inline?: boolean;
|
|
13
|
+
title?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Presentation style. `plain` (default) renders the icon inline.
|
|
16
|
+
* `badge` wraps the icon in a circular chip (white background, ring, shadow)
|
|
17
|
+
* sized by `size` — use in stage/approval cells so the chip scales with a
|
|
18
|
+
* neighbouring avatar.
|
|
19
|
+
*/
|
|
20
|
+
style?: IconStyle;
|
|
21
|
+
/**
|
|
22
|
+
* Named size token (xxs..xxl). Drives the badge diameter and glyph. The
|
|
23
|
+
* glyph is always ~50% of the badge diameter so it scales consistently
|
|
24
|
+
* across sizes. For `style="plain"` it sets width/height when neither is
|
|
25
|
+
* provided.
|
|
26
|
+
*/
|
|
27
|
+
size?: SizeToken;
|
|
28
|
+
/** Semantic color for `style="badge"`. Ignored for plain icons. */
|
|
29
|
+
tone?: IconTone;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Optional secondary icon provider. Consumers can plug in a component
|
|
33
|
+
* (e.g. `Icon` from `@flanksource/icons/icon`) to supply glyphs that the
|
|
34
|
+
* iconify registry doesn't know about (brand logos, k8s resource icons,
|
|
35
|
+
* etc.). Clicky-ui never imports the package directly so consumers that
|
|
36
|
+
* don't need it avoid the dependency entirely.
|
|
37
|
+
*/
|
|
38
|
+
export type FallbackIconProps = {
|
|
39
|
+
name?: string;
|
|
40
|
+
className?: string;
|
|
41
|
+
size?: string | number;
|
|
42
|
+
alt?: string;
|
|
43
|
+
};
|
|
44
|
+
type FallbackIconComponent = ComponentType<FallbackIconProps>;
|
|
45
|
+
/**
|
|
46
|
+
* Register a secondary glyph provider. Pass the flanksource Icon (or any
|
|
47
|
+
* compatible component) to resolve names that `@iconify/react` hasn't
|
|
48
|
+
* loaded. Call this once at app bootstrap.
|
|
49
|
+
*/
|
|
50
|
+
export declare function setFallbackIconProvider(component: FallbackIconComponent | null): void;
|
|
51
|
+
export declare function Icon({ name, className, width, height, rotate, flip, inline, title, style, size, tone, }: IconProps): import("react/jsx-runtime").JSX.Element;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=Icon.d.ts.map
|