@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,236 @@
|
|
|
1
|
+
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo, createElement } from "react";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { Icon } from "./Icon.js";
|
|
5
|
+
import { TreeNode } from "./TreeNode.js";
|
|
6
|
+
function countTreeEdges(roots, getChildren) {
|
|
7
|
+
let total = 0;
|
|
8
|
+
const stack = [...roots];
|
|
9
|
+
while (stack.length > 0) {
|
|
10
|
+
const node = stack.pop();
|
|
11
|
+
const children = getChildren(node) ?? [];
|
|
12
|
+
total += children.length;
|
|
13
|
+
stack.push(...children);
|
|
14
|
+
}
|
|
15
|
+
return total;
|
|
16
|
+
}
|
|
17
|
+
function collectTreeSearchText(value, excluded = /* @__PURE__ */ new Set(), seen = /* @__PURE__ */ new Set()) {
|
|
18
|
+
if (value == null || excluded.has(value)) return "";
|
|
19
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
20
|
+
return String(value);
|
|
21
|
+
}
|
|
22
|
+
if (typeof value !== "object") return "";
|
|
23
|
+
if (seen.has(value)) return "";
|
|
24
|
+
seen.add(value);
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
return value.map((entry) => collectTreeSearchText(entry, excluded, seen)).filter(Boolean).join(" ");
|
|
27
|
+
}
|
|
28
|
+
const preferredKeys = ["label", "name", "title", "text", "plain", "id", "content"];
|
|
29
|
+
const record = value;
|
|
30
|
+
const chunks = [];
|
|
31
|
+
for (const key of preferredKeys) {
|
|
32
|
+
if (!(key in record)) continue;
|
|
33
|
+
const text = collectTreeSearchText(record[key], excluded, seen);
|
|
34
|
+
if (text) chunks.push(text);
|
|
35
|
+
}
|
|
36
|
+
for (const [key, entry] of Object.entries(record)) {
|
|
37
|
+
if (key === "children" || preferredKeys.includes(key)) continue;
|
|
38
|
+
const text = collectTreeSearchText(entry, excluded, seen);
|
|
39
|
+
if (text) chunks.push(text);
|
|
40
|
+
}
|
|
41
|
+
return chunks.join(" ");
|
|
42
|
+
}
|
|
43
|
+
function nodeSearchText(node, children) {
|
|
44
|
+
const excluded = /* @__PURE__ */ new Set();
|
|
45
|
+
if (children) excluded.add(children);
|
|
46
|
+
return collectTreeSearchText(node, excluded).trim().toLowerCase();
|
|
47
|
+
}
|
|
48
|
+
function filterTreeRoots(roots, getChildren, getKey, query, isSecondary, getSearchText) {
|
|
49
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
50
|
+
if (!normalizedQuery) {
|
|
51
|
+
return {
|
|
52
|
+
roots,
|
|
53
|
+
filteredChildren: null,
|
|
54
|
+
forcedOpenKeys: null
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const filteredChildren = /* @__PURE__ */ new Map();
|
|
58
|
+
const forcedOpenKeys = /* @__PURE__ */ new Set();
|
|
59
|
+
function matchText(node, children) {
|
|
60
|
+
if (getSearchText) return getSearchText(node).trim().toLowerCase();
|
|
61
|
+
const searchChildren = children.filter((c) => !(isSecondary == null ? void 0 : isSecondary(c)));
|
|
62
|
+
return nodeSearchText(node, searchChildren);
|
|
63
|
+
}
|
|
64
|
+
function visit(node) {
|
|
65
|
+
if (isSecondary == null ? void 0 : isSecondary(node)) return false;
|
|
66
|
+
const key = getKey(node);
|
|
67
|
+
const children = getChildren(node) ?? [];
|
|
68
|
+
const childrenAllSecondary = children.length > 0 && children.every((child) => isSecondary == null ? void 0 : isSecondary(child));
|
|
69
|
+
const matches = matchText(node, children).includes(normalizedQuery);
|
|
70
|
+
const visibleChildren = [];
|
|
71
|
+
for (const child of children) {
|
|
72
|
+
if (visit(child)) visibleChildren.push(child);
|
|
73
|
+
}
|
|
74
|
+
if (matches) {
|
|
75
|
+
if (children.length > 0) {
|
|
76
|
+
filteredChildren.set(key, children);
|
|
77
|
+
if (!childrenAllSecondary) forcedOpenKeys.add(key);
|
|
78
|
+
}
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
if (visibleChildren.length > 0) {
|
|
82
|
+
filteredChildren.set(key, visibleChildren);
|
|
83
|
+
forcedOpenKeys.add(key);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
roots: roots.filter((root) => visit(root)),
|
|
90
|
+
filteredChildren,
|
|
91
|
+
forcedOpenKeys
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function Tree({
|
|
95
|
+
roots,
|
|
96
|
+
empty,
|
|
97
|
+
className,
|
|
98
|
+
showControls = true,
|
|
99
|
+
expandAll: controlledExpandAll,
|
|
100
|
+
onExpandAllChange,
|
|
101
|
+
toolbarClassName,
|
|
102
|
+
getSearchText,
|
|
103
|
+
...nodeProps
|
|
104
|
+
}) {
|
|
105
|
+
const [internalExpandAll, setInternalExpandAll] = useState(null);
|
|
106
|
+
const [filterQuery, setFilterQuery] = useState("");
|
|
107
|
+
const basePaddingPx = nodeProps.basePaddingPx ?? 8;
|
|
108
|
+
const isControlled = onExpandAllChange !== void 0;
|
|
109
|
+
const expandAll = isControlled ? controlledExpandAll ?? null : internalExpandAll;
|
|
110
|
+
const totalEdges = useMemo(
|
|
111
|
+
() => countTreeEdges(roots, nodeProps.getChildren),
|
|
112
|
+
[roots, nodeProps.getChildren]
|
|
113
|
+
);
|
|
114
|
+
const showFilter = totalEdges > 20;
|
|
115
|
+
const activeFilter = showFilter ? filterQuery : "";
|
|
116
|
+
const filteredTree = useMemo(
|
|
117
|
+
() => filterTreeRoots(
|
|
118
|
+
roots,
|
|
119
|
+
nodeProps.getChildren,
|
|
120
|
+
nodeProps.getKey,
|
|
121
|
+
activeFilter,
|
|
122
|
+
nodeProps.isSecondary,
|
|
123
|
+
getSearchText
|
|
124
|
+
),
|
|
125
|
+
[
|
|
126
|
+
roots,
|
|
127
|
+
nodeProps.getChildren,
|
|
128
|
+
nodeProps.getKey,
|
|
129
|
+
activeFilter,
|
|
130
|
+
nodeProps.isSecondary,
|
|
131
|
+
getSearchText
|
|
132
|
+
]
|
|
133
|
+
);
|
|
134
|
+
const treeRoots = filteredTree.roots;
|
|
135
|
+
const filteredChildren = filteredTree.filteredChildren;
|
|
136
|
+
const forcedOpenKeys = filteredTree.forcedOpenKeys;
|
|
137
|
+
const effectiveGetChildren = filteredChildren ? (node) => filteredChildren.get(nodeProps.getKey(node)) ?? [] : nodeProps.getChildren;
|
|
138
|
+
const effectiveExpandAll = expandAll;
|
|
139
|
+
const effectiveEmpty = activeFilter.trim() ? /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-sm text-muted-foreground", children: "No matching tree nodes." }) : empty;
|
|
140
|
+
const showControlButtons = showControls && roots.length > 0;
|
|
141
|
+
const showVirtualRow = showFilter || showControlButtons;
|
|
142
|
+
const setExpandAll = (next) => {
|
|
143
|
+
if (isControlled) onExpandAllChange == null ? void 0 : onExpandAllChange(next);
|
|
144
|
+
else setInternalExpandAll(next);
|
|
145
|
+
};
|
|
146
|
+
if (treeRoots.length === 0 && !showVirtualRow) return /* @__PURE__ */ jsx(Fragment, { children: effectiveEmpty ?? null });
|
|
147
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col min-h-0", className), children: /* @__PURE__ */ jsxs("div", { role: "tree", className: "min-h-0 flex-1 overflow-auto", children: [
|
|
148
|
+
showVirtualRow && /* @__PURE__ */ jsxs(
|
|
149
|
+
"div",
|
|
150
|
+
{
|
|
151
|
+
role: "presentation",
|
|
152
|
+
className: cn(
|
|
153
|
+
"sticky top-0 z-10 flex items-center gap-1.5 border-b border-border/70 bg-background/95 py-1 pr-2 text-sm backdrop-blur supports-[backdrop-filter]:bg-background/80",
|
|
154
|
+
toolbarClassName
|
|
155
|
+
),
|
|
156
|
+
style: { paddingLeft: `${basePaddingPx}px` },
|
|
157
|
+
children: [
|
|
158
|
+
showFilter ? /* @__PURE__ */ jsx(Icon, { name: "codicon:search", className: "w-3 shrink-0 text-xs text-muted-foreground" }) : /* @__PURE__ */ jsx("span", { className: "w-3 shrink-0", "aria-hidden": true }),
|
|
159
|
+
showFilter ? /* @__PURE__ */ jsxs("label", { className: "flex min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground shadow-sm", children: [
|
|
160
|
+
/* @__PURE__ */ jsx(
|
|
161
|
+
"input",
|
|
162
|
+
{
|
|
163
|
+
type: "search",
|
|
164
|
+
value: filterQuery,
|
|
165
|
+
onChange: (event) => setFilterQuery(event.target.value),
|
|
166
|
+
placeholder: "Filter tree",
|
|
167
|
+
className: "h-5 w-full border-0 bg-transparent p-0 text-xs outline-none placeholder:text-muted-foreground",
|
|
168
|
+
"aria-label": "Filter tree nodes"
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
filterQuery && /* @__PURE__ */ jsx(
|
|
172
|
+
"button",
|
|
173
|
+
{
|
|
174
|
+
type: "button",
|
|
175
|
+
onClick: () => setFilterQuery(""),
|
|
176
|
+
className: "inline-flex items-center rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
177
|
+
"aria-label": "Clear tree filter",
|
|
178
|
+
title: "Clear tree filter",
|
|
179
|
+
children: /* @__PURE__ */ jsx(Icon, { name: "codicon:close", className: "text-xs" })
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
] }) : /* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
183
|
+
showControlButtons && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
184
|
+
/* @__PURE__ */ jsx(
|
|
185
|
+
"button",
|
|
186
|
+
{
|
|
187
|
+
type: "button",
|
|
188
|
+
onClick: () => setExpandAll(true),
|
|
189
|
+
"aria-pressed": effectiveExpandAll === true,
|
|
190
|
+
"aria-label": "Expand all",
|
|
191
|
+
title: "Expand all",
|
|
192
|
+
disabled: activeFilter.trim().length > 0,
|
|
193
|
+
className: cn(
|
|
194
|
+
"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
195
|
+
effectiveExpandAll === true && "bg-accent text-accent-foreground"
|
|
196
|
+
),
|
|
197
|
+
children: /* @__PURE__ */ jsx(Icon, { name: "codicon:expand-all", className: "text-sm" })
|
|
198
|
+
}
|
|
199
|
+
),
|
|
200
|
+
/* @__PURE__ */ jsx(
|
|
201
|
+
"button",
|
|
202
|
+
{
|
|
203
|
+
type: "button",
|
|
204
|
+
onClick: () => setExpandAll(false),
|
|
205
|
+
"aria-pressed": effectiveExpandAll === false,
|
|
206
|
+
"aria-label": "Collapse all",
|
|
207
|
+
title: "Collapse all",
|
|
208
|
+
disabled: activeFilter.trim().length > 0,
|
|
209
|
+
className: cn(
|
|
210
|
+
"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
211
|
+
effectiveExpandAll === false && "bg-accent text-accent-foreground"
|
|
212
|
+
),
|
|
213
|
+
children: /* @__PURE__ */ jsx(Icon, { name: "codicon:collapse-all", className: "text-sm" })
|
|
214
|
+
}
|
|
215
|
+
)
|
|
216
|
+
] })
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
),
|
|
220
|
+
treeRoots.length === 0 ? effectiveEmpty ?? null : /* @__PURE__ */ jsx(Fragment, { children: treeRoots.map((root) => /* @__PURE__ */ createElement(
|
|
221
|
+
TreeNode,
|
|
222
|
+
{
|
|
223
|
+
...nodeProps,
|
|
224
|
+
key: nodeProps.getKey(root),
|
|
225
|
+
node: root,
|
|
226
|
+
expandAll: effectiveExpandAll,
|
|
227
|
+
forcedOpenKeys,
|
|
228
|
+
getChildren: effectiveGetChildren
|
|
229
|
+
}
|
|
230
|
+
)) })
|
|
231
|
+
] }) });
|
|
232
|
+
}
|
|
233
|
+
export {
|
|
234
|
+
Tree
|
|
235
|
+
};
|
|
236
|
+
//# sourceMappingURL=Tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tree.js","sources":["../../src/data/Tree.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"./Icon\";\nimport { TreeNode, type TreeNodeProps } from \"./TreeNode\";\n\nexport type TreeProps<T> = Omit<\n TreeNodeProps<T>,\n \"node\" | \"depth\" | \"expandAll\" | \"forcedOpenKeys\"\n> & {\n roots: T[];\n empty?: ReactNode;\n className?: string;\n /**\n * Render the Expand all / Collapse all toolbar above the tree. Enabled by\n * default. Set to false to suppress when the tree is tiny or the controls\n * are owned externally.\n */\n showControls?: boolean;\n /**\n * Externally controlled expand-all state. When provided together with\n * `onExpandAllChange`, the tree is controlled; otherwise it manages the\n * toolbar state internally.\n */\n expandAll?: boolean | null;\n onExpandAllChange?: (next: boolean | null) => void;\n toolbarClassName?: string;\n /**\n * Override the text the filter matches against for a given node.\n * Defaults to a recursive walk of the node's own fields (excluding\n * its `children` and any secondary children), which works for\n * plain-shape trees but leaks text from nested domain objects —\n * e.g. a SQL Table's Field rows are marked secondary, yet the\n * parent record still carries `record.fields[].field` strings that\n * the default walker would collect. Callers that need precise\n * control over search behaviour should return only the text they\n * want surfaced (the node's own display label / id / type).\n */\n getSearchText?: (node: T) => string;\n};\n\nfunction countTreeEdges<T>(roots: T[], getChildren: TreeProps<T>[\"getChildren\"]) {\n let total = 0;\n const stack = [...roots];\n\n while (stack.length > 0) {\n const node = stack.pop()!;\n const children = getChildren(node) ?? [];\n total += children.length;\n stack.push(...children);\n }\n\n return total;\n}\n\nfunction collectTreeSearchText(\n value: unknown,\n excluded = new Set<unknown>(),\n seen = new Set<unknown>(),\n): string {\n if (value == null || excluded.has(value)) return \"\";\n\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n typeof value === \"bigint\"\n ) {\n return String(value);\n }\n\n if (typeof value !== \"object\") return \"\";\n if (seen.has(value)) return \"\";\n seen.add(value);\n\n if (Array.isArray(value)) {\n return value\n .map((entry) => collectTreeSearchText(entry, excluded, seen))\n .filter(Boolean)\n .join(\" \");\n }\n\n const preferredKeys = [\"label\", \"name\", \"title\", \"text\", \"plain\", \"id\", \"content\"];\n const record = value as Record<string, unknown>;\n const chunks: string[] = [];\n\n for (const key of preferredKeys) {\n if (!(key in record)) continue;\n const text = collectTreeSearchText(record[key], excluded, seen);\n if (text) chunks.push(text);\n }\n\n for (const [key, entry] of Object.entries(record)) {\n if (key === \"children\" || preferredKeys.includes(key)) continue;\n const text = collectTreeSearchText(entry, excluded, seen);\n if (text) chunks.push(text);\n }\n\n return chunks.join(\" \");\n}\n\nfunction nodeSearchText<T>(node: T, children: ReturnType<TreeProps<T>[\"getChildren\"]>) {\n const excluded = new Set<unknown>();\n if (children) excluded.add(children);\n return collectTreeSearchText(node, excluded).trim().toLowerCase();\n}\n\nfunction filterTreeRoots<T>(\n roots: T[],\n getChildren: TreeProps<T>[\"getChildren\"],\n getKey: TreeProps<T>[\"getKey\"],\n query: string,\n isSecondary?: (node: T) => boolean,\n getSearchText?: (node: T) => string,\n) {\n const normalizedQuery = query.trim().toLowerCase();\n if (!normalizedQuery) {\n return {\n roots,\n filteredChildren: null as Map<string | number, T[]> | null,\n forcedOpenKeys: null as Set<string | number> | null,\n };\n }\n\n const filteredChildren = new Map<string | number, T[]>();\n const forcedOpenKeys = new Set<string | number>();\n\n function matchText(node: T, children: T[]): string {\n // Honour the caller-supplied text extractor first — it's the\n // only way to get precise control over what the filter sees when\n // the node carries domain data whose fields would otherwise leak\n // into the default walker.\n if (getSearchText) return getSearchText(node).trim().toLowerCase();\n // Match-text skips secondary children so e.g. a Table's search\n // text only draws from the Table itself, not from its Field\n // rows. The Table is primary, so its own text still counts.\n const searchChildren = children.filter((c) => !isSecondary?.(c));\n return nodeSearchText(node, searchChildren);\n }\n\n function visit(node: T): boolean {\n // A secondary node never drives a filter match — it's\n // effectively invisible to search. Still rendered when the\n // caller opens the parent manually. This is what lets a 28k-row\n // field tree stay searchable at the record level without \"field\n // name contains 'x'\" matches spamming the results.\n if (isSecondary?.(node)) return false;\n\n const key = getKey(node);\n const children = getChildren(node) ?? [];\n const childrenAllSecondary =\n children.length > 0 && children.every((child) => isSecondary?.(child));\n const matches = matchText(node, children).includes(normalizedQuery);\n const visibleChildren: T[] = [];\n\n for (const child of children) {\n if (visit(child)) visibleChildren.push(child);\n }\n\n if (matches) {\n if (children.length > 0) {\n filteredChildren.set(key, children);\n if (!childrenAllSecondary) forcedOpenKeys.add(key);\n }\n return true;\n }\n\n if (visibleChildren.length > 0) {\n filteredChildren.set(key, visibleChildren);\n forcedOpenKeys.add(key);\n return true;\n }\n\n return false;\n }\n\n return {\n roots: roots.filter((root) => visit(root)),\n filteredChildren,\n forcedOpenKeys,\n };\n}\n\nexport function Tree<T>({\n roots,\n empty,\n className,\n showControls = true,\n expandAll: controlledExpandAll,\n onExpandAllChange,\n toolbarClassName,\n getSearchText,\n ...nodeProps\n}: TreeProps<T>) {\n const [internalExpandAll, setInternalExpandAll] = useState<boolean | null>(null);\n const [filterQuery, setFilterQuery] = useState(\"\");\n const basePaddingPx = nodeProps.basePaddingPx ?? 8;\n const isControlled = onExpandAllChange !== undefined;\n const expandAll = isControlled ? (controlledExpandAll ?? null) : internalExpandAll;\n const totalEdges = useMemo(\n () => countTreeEdges(roots, nodeProps.getChildren),\n [roots, nodeProps.getChildren],\n );\n const showFilter = totalEdges > 20;\n const activeFilter = showFilter ? filterQuery : \"\";\n const filteredTree = useMemo(\n () =>\n filterTreeRoots(\n roots,\n nodeProps.getChildren,\n nodeProps.getKey,\n activeFilter,\n nodeProps.isSecondary,\n getSearchText,\n ),\n [\n roots,\n nodeProps.getChildren,\n nodeProps.getKey,\n activeFilter,\n nodeProps.isSecondary,\n getSearchText,\n ],\n );\n const treeRoots = filteredTree.roots;\n const filteredChildren = filteredTree.filteredChildren;\n const forcedOpenKeys = filteredTree.forcedOpenKeys;\n const effectiveGetChildren = filteredChildren\n ? (node: T) => filteredChildren.get(nodeProps.getKey(node)) ?? []\n : nodeProps.getChildren;\n const effectiveExpandAll = expandAll;\n const effectiveEmpty = activeFilter.trim() ? (\n <div className=\"px-3 py-4 text-sm text-muted-foreground\">No matching tree nodes.</div>\n ) : (\n empty\n );\n const showControlButtons = showControls && roots.length > 0;\n const showVirtualRow = showFilter || showControlButtons;\n const setExpandAll = (next: boolean | null) => {\n if (isControlled) onExpandAllChange?.(next);\n else setInternalExpandAll(next);\n };\n\n if (treeRoots.length === 0 && !showVirtualRow) return <>{effectiveEmpty ?? null}</>;\n\n return (\n <div className={cn(\"flex flex-col min-h-0\", className)}>\n <div role=\"tree\" className=\"min-h-0 flex-1 overflow-auto\">\n {showVirtualRow && (\n <div\n role=\"presentation\"\n className={cn(\n \"sticky top-0 z-10 flex items-center gap-1.5 border-b border-border/70 bg-background/95 py-1 pr-2 text-sm backdrop-blur supports-[backdrop-filter]:bg-background/80\",\n toolbarClassName,\n )}\n style={{ paddingLeft: `${basePaddingPx}px` }}\n >\n {showFilter ? (\n <Icon name=\"codicon:search\" className=\"w-3 shrink-0 text-xs text-muted-foreground\" />\n ) : (\n <span className=\"w-3 shrink-0\" aria-hidden />\n )}\n\n {showFilter ? (\n <label className=\"flex min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground shadow-sm\">\n <input\n type=\"search\"\n value={filterQuery}\n onChange={(event) => setFilterQuery(event.target.value)}\n placeholder=\"Filter tree\"\n className=\"h-5 w-full border-0 bg-transparent p-0 text-xs outline-none placeholder:text-muted-foreground\"\n aria-label=\"Filter tree nodes\"\n />\n {filterQuery && (\n <button\n type=\"button\"\n onClick={() => setFilterQuery(\"\")}\n className=\"inline-flex items-center rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n aria-label=\"Clear tree filter\"\n title=\"Clear tree filter\"\n >\n <Icon name=\"codicon:close\" className=\"text-xs\" />\n </button>\n )}\n </label>\n ) : (\n <span className=\"flex-1\" />\n )}\n\n {showControlButtons && (\n <div className=\"ml-auto flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => setExpandAll(true)}\n aria-pressed={effectiveExpandAll === true}\n aria-label=\"Expand all\"\n title=\"Expand all\"\n disabled={activeFilter.trim().length > 0}\n className={cn(\n \"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n effectiveExpandAll === true && \"bg-accent text-accent-foreground\",\n )}\n >\n <Icon name=\"codicon:expand-all\" className=\"text-sm\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setExpandAll(false)}\n aria-pressed={effectiveExpandAll === false}\n aria-label=\"Collapse all\"\n title=\"Collapse all\"\n disabled={activeFilter.trim().length > 0}\n className={cn(\n \"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n effectiveExpandAll === false && \"bg-accent text-accent-foreground\",\n )}\n >\n <Icon name=\"codicon:collapse-all\" className=\"text-sm\" />\n </button>\n </div>\n )}\n </div>\n )}\n\n {treeRoots.length === 0 ? (\n (effectiveEmpty ?? null)\n ) : (\n <>\n {treeRoots.map((root) => (\n <TreeNode<T>\n {...nodeProps}\n key={nodeProps.getKey(root)}\n node={root}\n expandAll={effectiveExpandAll}\n forcedOpenKeys={forcedOpenKeys}\n getChildren={effectiveGetChildren}\n />\n ))}\n </>\n )}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type TreeGroupHeaderProps = {
|
|
3
|
+
title: ReactNode;
|
|
4
|
+
open: boolean;
|
|
5
|
+
onToggle: () => void;
|
|
6
|
+
icon?: string;
|
|
7
|
+
count?: number;
|
|
8
|
+
className?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function TreeGroupHeader({ title, open, onToggle, icon, count, className, }: TreeGroupHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=TreeGroupHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeGroupHeader.d.ts","sourceRoot":"","sources":["../../src/data/TreeGroupHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,SAAS,GACV,EAAE,oBAAoB,2CAqBtB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { Icon } from "./Icon.js";
|
|
4
|
+
function TreeGroupHeader({
|
|
5
|
+
title,
|
|
6
|
+
open,
|
|
7
|
+
onToggle,
|
|
8
|
+
icon,
|
|
9
|
+
count,
|
|
10
|
+
className
|
|
11
|
+
}) {
|
|
12
|
+
return /* @__PURE__ */ jsxs(
|
|
13
|
+
"button",
|
|
14
|
+
{
|
|
15
|
+
type: "button",
|
|
16
|
+
onClick: onToggle,
|
|
17
|
+
"aria-expanded": open,
|
|
18
|
+
className: cn(
|
|
19
|
+
"w-full flex items-center gap-2 px-3 py-2 border-b border-border select-none",
|
|
20
|
+
"hover:bg-accent transition-colors text-left",
|
|
21
|
+
className
|
|
22
|
+
),
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ jsx(
|
|
25
|
+
Icon,
|
|
26
|
+
{
|
|
27
|
+
name: open ? "codicon:chevron-down" : "codicon:chevron-right",
|
|
28
|
+
className: "text-muted-foreground text-xs"
|
|
29
|
+
}
|
|
30
|
+
),
|
|
31
|
+
icon && /* @__PURE__ */ jsx(Icon, { name: icon, className: "text-base" }),
|
|
32
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-sm flex-1 truncate", children: title }),
|
|
33
|
+
count !== void 0 && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: count })
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
TreeGroupHeader
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=TreeGroupHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeGroupHeader.js","sources":["../../src/data/TreeGroupHeader.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"./Icon\";\n\nexport type TreeGroupHeaderProps = {\n title: ReactNode;\n open: boolean;\n onToggle: () => void;\n icon?: string;\n count?: number;\n className?: string;\n};\n\nexport function TreeGroupHeader({\n title,\n open,\n onToggle,\n icon,\n count,\n className,\n}: TreeGroupHeaderProps) {\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={open}\n className={cn(\n \"w-full flex items-center gap-2 px-3 py-2 border-b border-border select-none\",\n \"hover:bg-accent transition-colors text-left\",\n className,\n )}\n >\n <Icon\n name={open ? \"codicon:chevron-down\" : \"codicon:chevron-right\"}\n className=\"text-muted-foreground text-xs\"\n />\n {icon && <Icon name={icon} className=\"text-base\" />}\n <span className=\"font-medium text-sm flex-1 truncate\">{title}</span>\n {count !== undefined && <span className=\"text-xs text-muted-foreground\">{count}</span>}\n </button>\n );\n}\n"],"names":[],"mappings":";;;AAaO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,iBAAe;AAAA,MACf,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM,OAAO,yBAAyB;AAAA,YACtC,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEX,QAAQ,oBAAC,MAAA,EAAK,MAAM,MAAM,WAAU,aAAY;AAAA,QACjD,oBAAC,QAAA,EAAK,WAAU,uCAAuC,UAAA,OAAM;AAAA,QAC5D,UAAU,UAAa,oBAAC,QAAA,EAAK,WAAU,iCAAiC,UAAA,MAAA,CAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGrF;"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type TreeRowContext<T> = {
|
|
3
|
+
node: T;
|
|
4
|
+
depth: number;
|
|
5
|
+
open: boolean;
|
|
6
|
+
selected: boolean;
|
|
7
|
+
hasChildren: boolean;
|
|
8
|
+
toggle: () => void;
|
|
9
|
+
};
|
|
10
|
+
export type TreeNodeProps<T> = {
|
|
11
|
+
node: T;
|
|
12
|
+
depth?: number;
|
|
13
|
+
expandAll?: boolean | null;
|
|
14
|
+
forcedOpenKeys?: Set<string | number> | null;
|
|
15
|
+
selected?: T | null;
|
|
16
|
+
defaultOpen?: (node: T, depth: number) => boolean;
|
|
17
|
+
getChildren: (node: T) => T[] | undefined;
|
|
18
|
+
getKey: (node: T) => string | number;
|
|
19
|
+
onSelect?: (node: T) => void;
|
|
20
|
+
renderRow: (ctx: TreeRowContext<T>) => ReactNode;
|
|
21
|
+
rowClass?: (node: T, selected: boolean) => string;
|
|
22
|
+
indentPx?: number;
|
|
23
|
+
basePaddingPx?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Marks a node as a **secondary child** of its parent. Secondary
|
|
26
|
+
* children keep the full tree structure (they render, they can be
|
|
27
|
+
* opened manually) but opt out of the bulk behaviours a caller
|
|
28
|
+
* typically wants when they click the toolbar:
|
|
29
|
+
*
|
|
30
|
+
* - Tree-wide filter: their text is skipped during match detection
|
|
31
|
+
* so typing in the search box never surfaces a row because one
|
|
32
|
+
* of its secondary children happened to match.
|
|
33
|
+
* - Expand all: secondary nodes stay at their default-open state
|
|
34
|
+
* instead of being forced open, preventing 28k field rows from
|
|
35
|
+
* flooding the viewport when an operator hits the button on a
|
|
36
|
+
* schema with hundreds of tables.
|
|
37
|
+
*
|
|
38
|
+
* Default: every node is primary (returns false).
|
|
39
|
+
*/
|
|
40
|
+
isSecondary?: (node: T) => boolean;
|
|
41
|
+
};
|
|
42
|
+
export declare function TreeNode<T>({ node, depth, expandAll, forcedOpenKeys, selected, defaultOpen, getChildren, getKey, onSelect, renderRow, rowClass, indentPx, basePaddingPx, isSecondary, }: TreeNodeProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
//# sourceMappingURL=TreeNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeNode.d.ts","sourceRoot":"","sources":["../../src/data/TreeNode.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIpE,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAClD,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,SAAS,CAAC;IAC1C,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;IACjD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,KAAK,MAAM,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;CACpC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAC1B,IAAI,EACJ,KAAS,EACT,SAAgB,EAChB,cAAqB,EACrB,QAAe,EACf,WAAW,EACX,WAAW,EACX,MAAM,EACN,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,QAAa,EACb,aAAiB,EACjB,WAAW,GACZ,EAAE,aAAa,CAAC,CAAC,CAAC,2CA4FlB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useRef, useEffect } from "react";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { Icon } from "./Icon.js";
|
|
5
|
+
function TreeNode({
|
|
6
|
+
node,
|
|
7
|
+
depth = 0,
|
|
8
|
+
expandAll = null,
|
|
9
|
+
forcedOpenKeys = null,
|
|
10
|
+
selected = null,
|
|
11
|
+
defaultOpen,
|
|
12
|
+
getChildren,
|
|
13
|
+
getKey,
|
|
14
|
+
onSelect,
|
|
15
|
+
renderRow,
|
|
16
|
+
rowClass,
|
|
17
|
+
indentPx = 16,
|
|
18
|
+
basePaddingPx = 8,
|
|
19
|
+
isSecondary
|
|
20
|
+
}) {
|
|
21
|
+
const children = getChildren(node);
|
|
22
|
+
const hasChildren = ((children == null ? void 0 : children.length) ?? 0) > 0;
|
|
23
|
+
const initialOpen = defaultOpen ? defaultOpen(node, depth) : depth < 1;
|
|
24
|
+
const [open, setOpen] = useState(initialOpen);
|
|
25
|
+
const prevExpandAll = useRef(expandAll);
|
|
26
|
+
const isSelected = selected === node;
|
|
27
|
+
const key = getKey(node);
|
|
28
|
+
const isForcedOpen = (forcedOpenKeys == null ? void 0 : forcedOpenKeys.has(key)) ?? false;
|
|
29
|
+
const isOpen = isForcedOpen || open;
|
|
30
|
+
const secondaryNode = (isSecondary == null ? void 0 : isSecondary(node)) ?? false;
|
|
31
|
+
const childrenAllSecondary = hasChildren && isSecondary != null && children.every((c) => isSecondary(c));
|
|
32
|
+
const skipExpandAll = secondaryNode || childrenAllSecondary;
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (expandAll !== null && expandAll !== prevExpandAll.current && !skipExpandAll) {
|
|
35
|
+
setOpen(expandAll);
|
|
36
|
+
}
|
|
37
|
+
prevExpandAll.current = expandAll;
|
|
38
|
+
}, [expandAll, skipExpandAll]);
|
|
39
|
+
function toggle() {
|
|
40
|
+
if (hasChildren) setOpen((o) => !o);
|
|
41
|
+
}
|
|
42
|
+
const defaultRowBg = isSelected ? "bg-primary/10 border-l-2 border-primary" : "hover:bg-accent";
|
|
43
|
+
const rowClassName = rowClass ? rowClass(node, isSelected) : defaultRowBg;
|
|
44
|
+
return /* @__PURE__ */ jsxs(
|
|
45
|
+
"div",
|
|
46
|
+
{
|
|
47
|
+
role: "treeitem",
|
|
48
|
+
"aria-expanded": hasChildren ? isOpen : void 0,
|
|
49
|
+
"aria-selected": isSelected,
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ jsxs(
|
|
52
|
+
"div",
|
|
53
|
+
{
|
|
54
|
+
className: cn("flex items-center gap-1.5 py-1 px-2 cursor-pointer text-sm", rowClassName),
|
|
55
|
+
style: { paddingLeft: `${depth * indentPx + basePaddingPx}px` },
|
|
56
|
+
onClick: (e) => {
|
|
57
|
+
e.stopPropagation();
|
|
58
|
+
onSelect == null ? void 0 : onSelect(node);
|
|
59
|
+
toggle();
|
|
60
|
+
},
|
|
61
|
+
children: [
|
|
62
|
+
hasChildren ? /* @__PURE__ */ jsx(
|
|
63
|
+
Icon,
|
|
64
|
+
{
|
|
65
|
+
name: isOpen ? "codicon:chevron-down" : "codicon:chevron-right",
|
|
66
|
+
className: "text-muted-foreground text-xs w-3"
|
|
67
|
+
}
|
|
68
|
+
) : /* @__PURE__ */ jsx("span", { className: "w-3 shrink-0", "aria-hidden": true }),
|
|
69
|
+
renderRow({ node, depth, open: isOpen, selected: isSelected, hasChildren, toggle })
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
),
|
|
73
|
+
isOpen && hasChildren && /* @__PURE__ */ jsx("div", { role: "group", children: children.map((child) => /* @__PURE__ */ jsx(
|
|
74
|
+
TreeNode,
|
|
75
|
+
{
|
|
76
|
+
node: child,
|
|
77
|
+
depth: depth + 1,
|
|
78
|
+
expandAll,
|
|
79
|
+
forcedOpenKeys,
|
|
80
|
+
selected,
|
|
81
|
+
getChildren,
|
|
82
|
+
getKey,
|
|
83
|
+
renderRow,
|
|
84
|
+
indentPx,
|
|
85
|
+
basePaddingPx,
|
|
86
|
+
...defaultOpen ? { defaultOpen } : {},
|
|
87
|
+
...onSelect ? { onSelect } : {},
|
|
88
|
+
...rowClass ? { rowClass } : {},
|
|
89
|
+
...isSecondary ? { isSecondary } : {}
|
|
90
|
+
},
|
|
91
|
+
getKey(child)
|
|
92
|
+
)) })
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
TreeNode
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=TreeNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeNode.js","sources":["../../src/data/TreeNode.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"./Icon\";\n\nexport type TreeRowContext<T> = {\n node: T;\n depth: number;\n open: boolean;\n selected: boolean;\n hasChildren: boolean;\n toggle: () => void;\n};\n\nexport type TreeNodeProps<T> = {\n node: T;\n depth?: number;\n expandAll?: boolean | null;\n forcedOpenKeys?: Set<string | number> | null;\n selected?: T | null;\n defaultOpen?: (node: T, depth: number) => boolean;\n getChildren: (node: T) => T[] | undefined;\n getKey: (node: T) => string | number;\n onSelect?: (node: T) => void;\n renderRow: (ctx: TreeRowContext<T>) => ReactNode;\n rowClass?: (node: T, selected: boolean) => string;\n indentPx?: number;\n basePaddingPx?: number;\n /**\n * Marks a node as a **secondary child** of its parent. Secondary\n * children keep the full tree structure (they render, they can be\n * opened manually) but opt out of the bulk behaviours a caller\n * typically wants when they click the toolbar:\n *\n * - Tree-wide filter: their text is skipped during match detection\n * so typing in the search box never surfaces a row because one\n * of its secondary children happened to match.\n * - Expand all: secondary nodes stay at their default-open state\n * instead of being forced open, preventing 28k field rows from\n * flooding the viewport when an operator hits the button on a\n * schema with hundreds of tables.\n *\n * Default: every node is primary (returns false).\n */\n isSecondary?: (node: T) => boolean;\n};\n\nexport function TreeNode<T>({\n node,\n depth = 0,\n expandAll = null,\n forcedOpenKeys = null,\n selected = null,\n defaultOpen,\n getChildren,\n getKey,\n onSelect,\n renderRow,\n rowClass,\n indentPx = 16,\n basePaddingPx = 8,\n isSecondary,\n}: TreeNodeProps<T>) {\n const children = getChildren(node);\n const hasChildren = (children?.length ?? 0) > 0;\n const initialOpen = defaultOpen ? defaultOpen(node, depth) : depth < 1;\n const [open, setOpen] = useState(initialOpen);\n const prevExpandAll = useRef(expandAll);\n const isSelected = selected === node;\n const key = getKey(node);\n const isForcedOpen = forcedOpenKeys?.has(key) ?? false;\n const isOpen = isForcedOpen || open;\n // A node opts out of bulk expand-all in two distinct cases:\n //\n // 1. The node itself is secondary (its edge from the parent is\n // secondary) — rare at the root, but the rule is symmetric.\n // 2. All of the node's children are secondary — the common case.\n // This is what keeps an \"Expand all\" on a schema tree from\n // flooding the viewport with every table's field rows: the\n // table opens to nothing structural worth seeing in bulk, so\n // we leave it closed until the operator clicks it manually.\n //\n // In both cases the manual toggle still works, and filter matches\n // still force the row open via forcedOpenKeys, so users never\n // lose access — they just don't get auto-flooded.\n const secondaryNode = isSecondary?.(node) ?? false;\n const childrenAllSecondary =\n hasChildren && isSecondary != null && children!.every((c) => isSecondary(c));\n const skipExpandAll = secondaryNode || childrenAllSecondary;\n\n useEffect(() => {\n if (expandAll !== null && expandAll !== prevExpandAll.current && !skipExpandAll) {\n setOpen(expandAll);\n }\n prevExpandAll.current = expandAll;\n }, [expandAll, skipExpandAll]);\n\n function toggle() {\n if (hasChildren) setOpen((o) => !o);\n }\n\n const defaultRowBg = isSelected ? \"bg-primary/10 border-l-2 border-primary\" : \"hover:bg-accent\";\n const rowClassName = rowClass ? rowClass(node, isSelected) : defaultRowBg;\n\n return (\n <div\n role=\"treeitem\"\n aria-expanded={hasChildren ? isOpen : undefined}\n aria-selected={isSelected}\n >\n <div\n className={cn(\"flex items-center gap-1.5 py-1 px-2 cursor-pointer text-sm\", rowClassName)}\n style={{ paddingLeft: `${depth * indentPx + basePaddingPx}px` }}\n onClick={(e) => {\n e.stopPropagation();\n onSelect?.(node);\n toggle();\n }}\n >\n {hasChildren ? (\n <Icon\n name={isOpen ? \"codicon:chevron-down\" : \"codicon:chevron-right\"}\n className=\"text-muted-foreground text-xs w-3\"\n />\n ) : (\n <span className=\"w-3 shrink-0\" aria-hidden />\n )}\n {renderRow({ node, depth, open: isOpen, selected: isSelected, hasChildren, toggle })}\n </div>\n {isOpen && hasChildren && (\n <div role=\"group\">\n {children!.map((child) => (\n <TreeNode\n key={getKey(child)}\n node={child}\n depth={depth + 1}\n expandAll={expandAll}\n forcedOpenKeys={forcedOpenKeys}\n selected={selected}\n getChildren={getChildren}\n getKey={getKey}\n renderRow={renderRow}\n indentPx={indentPx}\n basePaddingPx={basePaddingPx}\n {...(defaultOpen ? { defaultOpen } : {})}\n {...(onSelect ? { onSelect } : {})}\n {...(rowClass ? { rowClass } : {})}\n {...(isSecondary ? { isSecondary } : {})}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;AA8CO,SAAS,SAAY;AAAA,EAC1B;AAAA,EACA,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB;AACF,GAAqB;AACnB,QAAM,WAAW,YAAY,IAAI;AACjC,QAAM,gBAAe,qCAAU,WAAU,KAAK;AAC9C,QAAM,cAAc,cAAc,YAAY,MAAM,KAAK,IAAI,QAAQ;AACrE,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,WAAW;AAC5C,QAAM,gBAAgB,OAAO,SAAS;AACtC,QAAM,aAAa,aAAa;AAChC,QAAM,MAAM,OAAO,IAAI;AACvB,QAAM,gBAAe,iDAAgB,IAAI,SAAQ;AACjD,QAAM,SAAS,gBAAgB;AAc/B,QAAM,iBAAgB,2CAAc,UAAS;AAC7C,QAAM,uBACJ,eAAe,eAAe,QAAQ,SAAU,MAAM,CAAC,MAAM,YAAY,CAAC,CAAC;AAC7E,QAAM,gBAAgB,iBAAiB;AAEvC,YAAU,MAAM;AACd,QAAI,cAAc,QAAQ,cAAc,cAAc,WAAW,CAAC,eAAe;AAC/E,cAAQ,SAAS;AAAA,IACnB;AACA,kBAAc,UAAU;AAAA,EAC1B,GAAG,CAAC,WAAW,aAAa,CAAC;AAE7B,WAAS,SAAS;AAChB,QAAI,YAAa,SAAQ,CAAC,MAAM,CAAC,CAAC;AAAA,EACpC;AAEA,QAAM,eAAe,aAAa,4CAA4C;AAC9E,QAAM,eAAe,WAAW,SAAS,MAAM,UAAU,IAAI;AAE7D,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,iBAAe,cAAc,SAAS;AAAA,MACtC,iBAAe;AAAA,MAEf,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW,GAAG,8DAA8D,YAAY;AAAA,YACxF,OAAO,EAAE,aAAa,GAAG,QAAQ,WAAW,aAAa,KAAA;AAAA,YACzD,SAAS,CAAC,MAAM;AACd,gBAAE,gBAAA;AACF,mDAAW;AACX,qBAAA;AAAA,YACF;AAAA,YAEC,UAAA;AAAA,cAAA,cACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAM,SAAS,yBAAyB;AAAA,kBACxC,WAAU;AAAA,gBAAA;AAAA,cAAA,IAGZ,oBAAC,QAAA,EAAK,WAAU,gBAAe,eAAW,MAAC;AAAA,cAE5C,UAAU,EAAE,MAAM,OAAO,MAAM,QAAQ,UAAU,YAAY,aAAa,OAAA,CAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAEpF,UAAU,eACT,oBAAC,OAAA,EAAI,MAAK,SACP,UAAA,SAAU,IAAI,CAAC,UACd;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,MAAM;AAAA,YACN,OAAO,QAAQ;AAAA,YACf;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACC,GAAI,cAAc,EAAE,YAAA,IAAgB,CAAA;AAAA,YACpC,GAAI,WAAW,EAAE,SAAA,IAAa,CAAA;AAAA,YAC9B,GAAI,WAAW,EAAE,SAAA,IAAa,CAAA;AAAA,YAC9B,GAAI,cAAc,EAAE,gBAAgB,CAAA;AAAA,UAAC;AAAA,UAdjC,OAAO,KAAK;AAAA,QAAA,CAgBpB,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BadgeStatus } from '../Badge';
|
|
2
|
+
export type StatusDotSize = "xs" | "sm" | "md";
|
|
3
|
+
export type StatusDotProps = {
|
|
4
|
+
status: BadgeStatus;
|
|
5
|
+
size?: StatusDotSize;
|
|
6
|
+
label?: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function StatusDot({ status, size, label, title, className }: StatusDotProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=StatusDot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusDot.d.ts","sourceRoot":"","sources":["../../../src/data/cells/StatusDot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAe/C,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,IAAW,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,cAAc,2CAezF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
const DOT_COLOR = {
|
|
4
|
+
success: "bg-emerald-500",
|
|
5
|
+
error: "bg-rose-500",
|
|
6
|
+
warning: "bg-amber-500",
|
|
7
|
+
info: "bg-sky-500"
|
|
8
|
+
};
|
|
9
|
+
const DOT_SIZE = {
|
|
10
|
+
xs: "h-1.5 w-1.5",
|
|
11
|
+
sm: "h-2 w-2",
|
|
12
|
+
md: "h-2.5 w-2.5"
|
|
13
|
+
};
|
|
14
|
+
function StatusDot({ status, size = "sm", label, title, className }) {
|
|
15
|
+
const tooltip = title ?? label ?? status;
|
|
16
|
+
return /* @__PURE__ */ jsxs(
|
|
17
|
+
"span",
|
|
18
|
+
{
|
|
19
|
+
className: cn("inline-flex items-center gap-1.5 align-middle", className),
|
|
20
|
+
title: tooltip,
|
|
21
|
+
children: [
|
|
22
|
+
/* @__PURE__ */ jsx(
|
|
23
|
+
"span",
|
|
24
|
+
{
|
|
25
|
+
role: "img",
|
|
26
|
+
"aria-label": label ?? status,
|
|
27
|
+
className: cn("inline-block shrink-0 rounded-full", DOT_COLOR[status], DOT_SIZE[size])
|
|
28
|
+
}
|
|
29
|
+
),
|
|
30
|
+
label && /* @__PURE__ */ jsx("span", { className: "truncate text-xs", children: label })
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
StatusDot
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=StatusDot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusDot.js","sources":["../../../src/data/cells/StatusDot.tsx"],"sourcesContent":["import { cn } from \"../../lib/utils\";\nimport type { BadgeStatus } from \"../Badge\";\n\nexport type StatusDotSize = \"xs\" | \"sm\" | \"md\";\n\nconst DOT_COLOR: Record<BadgeStatus, string> = {\n success: \"bg-emerald-500\",\n error: \"bg-rose-500\",\n warning: \"bg-amber-500\",\n info: \"bg-sky-500\",\n};\n\nconst DOT_SIZE: Record<StatusDotSize, string> = {\n xs: \"h-1.5 w-1.5\",\n sm: \"h-2 w-2\",\n md: \"h-2.5 w-2.5\",\n};\n\nexport type StatusDotProps = {\n status: BadgeStatus;\n size?: StatusDotSize;\n label?: string;\n title?: string;\n className?: string;\n};\n\nexport function StatusDot({ status, size = \"sm\", label, title, className }: StatusDotProps) {\n const tooltip = title ?? label ?? status;\n return (\n <span\n className={cn(\"inline-flex items-center gap-1.5 align-middle\", className)}\n title={tooltip}\n >\n <span\n role=\"img\"\n aria-label={label ?? status}\n className={cn(\"inline-block shrink-0 rounded-full\", DOT_COLOR[status], DOT_SIZE[size])}\n />\n {label && <span className=\"truncate text-xs\">{label}</span>}\n </span>\n );\n}\n"],"names":[],"mappings":";;AAKA,MAAM,YAAyC;AAAA,EAC7C,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AACR;AAEA,MAAM,WAA0C;AAAA,EAC9C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAUO,SAAS,UAAU,EAAE,QAAQ,OAAO,MAAM,OAAO,OAAO,aAA6B;AAC1F,QAAM,UAAU,SAAS,SAAS;AAClC,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,GAAG,iDAAiD,SAAS;AAAA,MACxE,OAAO;AAAA,MAEP,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,cAAY,SAAS;AAAA,YACrB,WAAW,GAAG,sCAAsC,UAAU,MAAM,GAAG,SAAS,IAAI,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA,QAEtF,SAAS,oBAAC,QAAA,EAAK,WAAU,oBAAoB,UAAA,MAAA,CAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG1D;"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { FilterMode } from '../FilterPill';
|
|
2
|
+
export type TagInput = string | {
|
|
3
|
+
key: string;
|
|
4
|
+
value: string;
|
|
5
|
+
} | {
|
|
6
|
+
name: string;
|
|
7
|
+
value: string;
|
|
8
|
+
};
|
|
9
|
+
export type NormalizedTag = {
|
|
10
|
+
key?: string;
|
|
11
|
+
value: string;
|
|
12
|
+
display: string;
|
|
13
|
+
token: string;
|
|
14
|
+
};
|
|
15
|
+
export type TagsValue = TagInput[] | Record<string, string | number | boolean | null> | null | undefined;
|
|
16
|
+
export type TagsOptions = {
|
|
17
|
+
maxVisible?: number;
|
|
18
|
+
separator?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function normalizeTags(value: TagsValue, separator?: string): NormalizedTag[];
|
|
21
|
+
export declare function tagFilterTokens(value: TagsValue, separator?: string): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Splits a token previously produced by `normalizeTags`/`tagFilterTokens`
|
|
24
|
+
* back into its key and value parts using the same separator. Tokens
|
|
25
|
+
* without a separator (bare tags) return `{ key: "", value: token }`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function splitTagToken(token: string, separator?: string): {
|
|
28
|
+
key: string;
|
|
29
|
+
value: string;
|
|
30
|
+
};
|
|
31
|
+
export type TagFilterMode = Extract<FilterMode, "include" | "exclude">;
|
|
32
|
+
export type TagActionsContextValue = {
|
|
33
|
+
/** Returns the current mode for a token; "neutral" if the user hasn't acted on it. */
|
|
34
|
+
getMode: (token: string) => FilterMode;
|
|
35
|
+
/** Toggle include for this token (off → include → off). */
|
|
36
|
+
toggleInclude: (token: string) => void;
|
|
37
|
+
/** Toggle exclude for this token (off → exclude → off). */
|
|
38
|
+
toggleExclude: (token: string) => void;
|
|
39
|
+
};
|
|
40
|
+
export declare function TagActionsProvider({ value, children, }: {
|
|
41
|
+
value: TagActionsContextValue;
|
|
42
|
+
children: React.ReactNode;
|
|
43
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
export declare function useTagActions(): TagActionsContextValue;
|
|
45
|
+
export type TagListProps = {
|
|
46
|
+
tags: NormalizedTag[];
|
|
47
|
+
maxVisible?: number;
|
|
48
|
+
className?: string;
|
|
49
|
+
actions?: "hover" | "inline";
|
|
50
|
+
};
|
|
51
|
+
export declare function TagList({ tags, maxVisible, className, actions }: TagListProps): import("react/jsx-runtime").JSX.Element;
|
|
52
|
+
/**
|
|
53
|
+
* Builds a TagActionsContextValue from a flat record-of-modes (the same
|
|
54
|
+
* shape used by FilterBar's multi/nested-multi filters). Useful when
|
|
55
|
+
* connecting DataTable's multiFilters state to the in-cell + / − buttons.
|
|
56
|
+
*/
|
|
57
|
+
export declare function tagActionsFromRecord(value: Record<string, TagFilterMode>, onChange: (next: Record<string, TagFilterMode>) => void): TagActionsContextValue;
|
|
58
|
+
export declare function useTagActionsValue(value: Record<string, TagFilterMode>, onChange: (next: Record<string, TagFilterMode>) => void): TagActionsContextValue;
|
|
59
|
+
//# sourceMappingURL=TagList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagList.d.ts","sourceRoot":"","sources":["../../../src/data/cells/TagList.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjG,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,SAAS,GACjB,QAAQ,EAAE,GACV,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,GAChD,IAAI,GACJ,SAAS,CAAC;AAEd,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,SAAM,GAAG,aAAa,EAAE,CAwBhF;AA+CD,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,SAAM,GAAG,MAAM,EAAE,CAE3E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAI5F;AAID,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;AAEvE,MAAM,MAAM,sBAAsB,GAAG;IACnC,sFAAsF;IACtF,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,UAAU,CAAC;IACvC,2DAA2D;IAC3D,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,2DAA2D;IAC3D,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,CAAC;AAUF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,sBAAsB,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAEA;AAED,wBAAgB,aAAa,IAAI,sBAAsB,CAEtD;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC9B,CAAC;AAuJF,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,UAAc,EAAE,SAAS,EAAE,OAAiB,EAAE,EAAE,YAAY,2CAgC3F;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EACpC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,IAAI,GACtD,sBAAsB,CAgBxB;AAID,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EACpC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,IAAI,GACtD,sBAAsB,CAExB"}
|