@tangle-network/sandbox-ui 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,109 @@
1
+ // src/files/rich-file-tree.tsx
2
+ import {
3
+ FileTree as PierreFileTree,
4
+ useFileTree as usePierreFileTree
5
+ } from "@pierre/trees/react";
6
+ import { useEffect, useMemo } from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+ function cssVarFromToken(name) {
9
+ return `var(${name})`;
10
+ }
11
+ var DEFAULT_THEME = {
12
+ selectedBg: cssVarFromToken("--accent-surface-soft"),
13
+ selectedFg: cssVarFromToken("--accent-text"),
14
+ fg: cssVarFromToken("--foreground"),
15
+ hoverBg: cssVarFromToken("--muted"),
16
+ border: cssVarFromToken("--border"),
17
+ mutedFg: cssVarFromToken("--muted-foreground")
18
+ };
19
+ function flattenFileNode(node, out = []) {
20
+ if (node.type === "file" && node.path) {
21
+ out.push(node.path);
22
+ return out;
23
+ }
24
+ if (node.type === "directory") {
25
+ if (node.children?.length) {
26
+ for (const child of node.children) {
27
+ flattenFileNode(child, out);
28
+ }
29
+ return out;
30
+ }
31
+ if (node.path) out.push(`${node.path}/`);
32
+ }
33
+ return out;
34
+ }
35
+ function RichFileTree({
36
+ root,
37
+ paths,
38
+ selectedPath,
39
+ onSelect,
40
+ search = true,
41
+ initialExpansion = "open",
42
+ gitStatus,
43
+ renderContextMenu,
44
+ header,
45
+ themeOverrides,
46
+ className,
47
+ style,
48
+ height
49
+ }) {
50
+ if (root && paths) {
51
+ throw new Error("RichFileTree: pass `root` or `paths`, not both");
52
+ }
53
+ const flatPaths = useMemo(() => {
54
+ if (paths) return Array.from(paths);
55
+ if (root) return flattenFileNode(root);
56
+ return [];
57
+ }, [paths, root]);
58
+ const { model } = usePierreFileTree({
59
+ paths: flatPaths,
60
+ search,
61
+ initialExpansion,
62
+ onSelectionChange: (selected) => {
63
+ const next = selected[0];
64
+ if (next && next !== selectedPath) onSelect?.(next);
65
+ }
66
+ });
67
+ useEffect(() => {
68
+ if (!gitStatus) return;
69
+ model.setGitStatus(gitStatus);
70
+ }, [model, gitStatus]);
71
+ useEffect(() => {
72
+ model.resetPaths(flatPaths);
73
+ }, [model, flatPaths]);
74
+ useEffect(() => {
75
+ if (!selectedPath) return;
76
+ const current = model.getSelectedPaths();
77
+ if (current.length === 1 && current[0] === selectedPath) return;
78
+ const m = model;
79
+ m.setSelectedPaths?.([selectedPath]);
80
+ }, [model, selectedPath]);
81
+ const theme = { ...DEFAULT_THEME, ...themeOverrides };
82
+ const themeStyle = useMemo(
83
+ () => ({
84
+ ["--trees-selected-bg-override"]: theme.selectedBg,
85
+ ["--trees-selected-fg-override"]: theme.selectedFg,
86
+ ["--trees-fg-override"]: theme.fg,
87
+ ["--trees-hover-bg-override"]: theme.hoverBg,
88
+ ["--trees-border-color-override"]: theme.border,
89
+ ["--trees-muted-fg-override"]: theme.mutedFg,
90
+ height: height ?? "100%",
91
+ ...style
92
+ }),
93
+ [theme, height, style]
94
+ );
95
+ return /* @__PURE__ */ jsx(
96
+ PierreFileTree,
97
+ {
98
+ model,
99
+ header,
100
+ renderContextMenu,
101
+ className,
102
+ style: themeStyle
103
+ }
104
+ );
105
+ }
106
+
107
+ export {
108
+ RichFileTree
109
+ };
package/dist/files.d.ts CHANGED
@@ -1,12 +1,72 @@
1
- import { a as FileTabData } from './file-tabs-BLfxfmAH.js';
2
- export { F as FileNode, b as FileTabs, c as FileTabsProps, d as FileTree, e as FileTreeProps, f as FileTreeVisibilityOptions, g as filterFileTree } from './file-tabs-BLfxfmAH.js';
1
+ import { F as FileNode, a as FileTabData } from './file-tabs-BLfxfmAH.js';
2
+ export { b as FileTabs, c as FileTabsProps, d as FileTree, e as FileTreeProps, f as FileTreeVisibilityOptions, g as filterFileTree } from './file-tabs-BLfxfmAH.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { GitStatusEntry, ContextMenuItem, ContextMenuOpenContext, GitStatus } from '@pierre/trees';
5
+ import { ReactNode, CSSProperties } from 'react';
4
6
  import { b as DocumentEditorMode, D as DocumentEditorBackend, d as DocumentEditorPaneCollaborationConfig } from './document-editor-pane-A70-EhdQ.js';
5
7
  import { A as ArtifactPaneProps } from './artifact-pane-Bh45Ssco.js';
6
- import 'react';
7
8
  import '@hocuspocus/provider';
8
9
  import 'yjs';
9
10
 
11
+ /**
12
+ * Re-export Pierre's git-status union under a stable name so consumers
13
+ * don't import directly from the dep. If we ever swap the underlying
14
+ * implementation, only this file changes.
15
+ */
16
+ type RichFileTreeGitStatus = GitStatus;
17
+ type RichFileTreeGitEntry = GitStatusEntry;
18
+ interface RichFileTreeProps {
19
+ /**
20
+ * Either a recursive `FileNode` tree (matches the existing FileTree
21
+ * input) or a flat list of canonical paths. Pass exactly one.
22
+ */
23
+ root?: FileNode;
24
+ paths?: ReadonlyArray<string>;
25
+ /** Currently-selected path. Pierre supports multi-select internally; the
26
+ * wrapper exposes a single string for parity with FileTree. */
27
+ selectedPath?: string;
28
+ /** Called whenever the selection changes (single-select fan-out). */
29
+ onSelect?: (path: string) => void;
30
+ /** Show the inline search input. Defaults to true. */
31
+ search?: boolean;
32
+ /** Open / closed initial expansion. Defaults to "open" — match FileTree. */
33
+ initialExpansion?: "open" | "closed";
34
+ /** Optional git-status decorations per path. */
35
+ gitStatus?: ReadonlyArray<RichFileTreeGitEntry>;
36
+ /**
37
+ * Right-click / button-lane menu content. Receives the row and the
38
+ * trigger context (which interaction opened the menu).
39
+ */
40
+ renderContextMenu?: (item: ContextMenuItem, context: ContextMenuOpenContext) => ReactNode;
41
+ /** Optional header rendered above the tree rows. */
42
+ header?: ReactNode;
43
+ /**
44
+ * Theme override map for shadow-DOM CSS variables. Most consumers can
45
+ * leave this — defaults derive from the host element's computed
46
+ * tokens via `cssVarFromToken()`.
47
+ */
48
+ themeOverrides?: Partial<RichFileTreeThemeVars>;
49
+ className?: string;
50
+ style?: CSSProperties;
51
+ /** Inline height (or set via `style.height`). Defaults to 100% of parent. */
52
+ height?: number | string;
53
+ }
54
+ interface RichFileTreeThemeVars {
55
+ /** Selected-row background. */
56
+ selectedBg: string;
57
+ /** Selected-row foreground. */
58
+ selectedFg: string;
59
+ /** Default row foreground. */
60
+ fg: string;
61
+ /** Hover background. */
62
+ hoverBg: string;
63
+ /** Border / divider color. */
64
+ border: string;
65
+ /** Muted (parent path, breadcrumb) foreground. */
66
+ mutedFg: string;
67
+ }
68
+ declare function RichFileTree({ root, paths, selectedPath, onSelect, search, initialExpansion, gitStatus, renderContextMenu, header, themeOverrides, className, style, height, }: RichFileTreeProps): react_jsx_runtime.JSX.Element;
69
+
10
70
  /**
11
71
  * FilePreview — universal file renderer.
12
72
  *
@@ -66,4 +126,4 @@ interface FileArtifactPaneProps extends Omit<FilePreviewProps, "className"> {
66
126
  */
67
127
  declare function FileArtifactPane({ filename, content, blobUrl, mimeType, onClose, onDownload, path, tabs, activeTabId, onTabSelect, onTabClose, eyebrow, meta, toolbar, footer, className, editor, }: FileArtifactPaneProps): react_jsx_runtime.JSX.Element;
68
128
 
69
- export { FileArtifactPane, type FileArtifactPaneProps, FilePreview, type FilePreviewProps, FileTabData };
129
+ export { FileArtifactPane, type FileArtifactPaneProps, FileNode, FilePreview, type FilePreviewProps, FileTabData, RichFileTree, type RichFileTreeGitEntry, type RichFileTreeGitStatus, type RichFileTreeProps, type RichFileTreeThemeVars };
package/dist/files.js CHANGED
@@ -1,3 +1,6 @@
1
+ import {
2
+ RichFileTree
3
+ } from "./chunk-LQNEZDRM.js";
1
4
  import {
2
5
  FileArtifactPane,
3
6
  FilePreview,
@@ -13,5 +16,6 @@ export {
13
16
  FilePreview,
14
17
  FileTabs,
15
18
  FileTree,
19
+ RichFileTree,
16
20
  filterFileTree
17
21
  };
package/dist/globals.css CHANGED
@@ -1082,6 +1082,9 @@
1082
1082
  .h-\[380px\] {
1083
1083
  height: 380px;
1084
1084
  }
1085
+ .h-\[480px\] {
1086
+ height: 480px;
1087
+ }
1085
1088
  .h-\[500px\] {
1086
1089
  height: 500px;
1087
1090
  }
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ import * as React$1 from 'react';
14
14
  import { b as ToolPart } from './parts-CyGkM6Fp.js';
15
15
  export { R as ReasoningPart, S as SessionMessage, a as SessionPart, T as TextPart, c as ToolState, d as ToolStatus, e as ToolTime } from './parts-CyGkM6Fp.js';
16
16
  export { F as FileNode, a as FileTabData, b as FileTabs, c as FileTabsProps, d as FileTree, e as FileTreeProps, f as FileTreeVisibilityOptions, g as filterFileTree } from './file-tabs-BLfxfmAH.js';
17
- export { FileArtifactPane, FileArtifactPaneProps, FilePreview, FilePreviewProps } from './files.js';
17
+ export { FileArtifactPane, FileArtifactPaneProps, FilePreview, FilePreviewProps, RichFileTree, RichFileTreeGitEntry, RichFileTreeGitStatus, RichFileTreeProps, RichFileTreeThemeVars } from './files.js';
18
18
  export { B as Backend, a as BackendSelector, b as BackendSelectorProps, C as ClusterStatusBar, c as ClusterStatusBarProps, d as ClusterStatusItem, e as CreditBalance, f as CreditBalanceProps, D as DashboardLayout, g as DashboardLayoutProps, h as DashboardUser, H as HARNESS_OPTIONS, i as HarnessPicker, j as HarnessPickerProps, k as HarnessType, I as Invoice, l as InvoiceTable, m as InvoiceTableProps, M as ModelInfo, n as ModelPicker, o as ModelPickerProps, p as ModelPickerVariant, q as ModelPreset, N as NavItem, r as NewSandboxCard, s as NewSandboxCardProps, P as PanelConfig, t as PlanCardData, u as PlanCards, v as PlanCardsProps, w as ProductVariant, x as ProfileAvatar, y as ProfileAvatarProps, z as ProfileComparison, A as ProfileComparisonProps, E as ProfileSelector, F as ProfileSelectorProps, R as RailButton, G as RailButtonProps, J as RailModeButton, K as RailModeButtonProps, L as RailSeparator, O as RailSeparatorProps, Q as ResourceMeter, S as ResourceMeterProps, T as SIDEBAR_MOBILE_WIDTH, U as SIDEBAR_PANEL_WIDTH, V as SIDEBAR_RAIL_WIDTH, W as SIDEBAR_TOTAL_WIDTH, X as SandboxCard, Y as SandboxCardData, Z as SandboxCardProps, _ as SandboxStatus, $ as SandboxTable, a0 as SandboxTableProps, a1 as Sidebar, a2 as SidebarContent, a3 as SidebarContentProps, a4 as SidebarPanel, a5 as SidebarPanelContent, a6 as SidebarPanelContentProps, a7 as SidebarPanelHeader, a8 as SidebarPanelHeaderProps, a9 as SidebarPanelProps, aa as SidebarProps, ab as SidebarProvider, ac as SidebarProviderProps, ad as SidebarRail, ae as SidebarRailFooter, af as SidebarRailFooterProps, ag as SidebarRailHeader, ah as SidebarRailHeaderProps, ai as SidebarRailNav, aj as SidebarRailNavProps, ak as SidebarRailProps, al as SidebarUser, am as TopNavLink, an as VariantList, ao as VariantListProps, ap as canonicalModelId, aq as formatContext, ar as formatPricing, as as useSidebar } from './variant-list-BrHYcBCk.js';
19
19
  export { c as BillingDashboard, d as BillingDashboardProps, e as PricingCards, f as PricingPageProps, g as UsageChart, h as UsageChartProps, U as UsageDataPoint } from './usage-chart-CPTcNlGs.js';
20
20
  export { AuthHeader, GitHubLoginButton, LoginLayout, LoginLayoutProps, UserMenu } from './auth.js';
@@ -40,6 +40,7 @@ import '@radix-ui/react-label';
40
40
  import '@hocuspocus/provider';
41
41
  import 'yjs';
42
42
  import '@tiptap/react';
43
+ import '@pierre/trees';
43
44
  import 'nanostores';
44
45
  import 'clsx';
45
46
 
package/dist/index.js CHANGED
@@ -169,6 +169,9 @@ import {
169
169
  TableHeader,
170
170
  TableRow
171
171
  } from "./chunk-34I7UFSX.js";
172
+ import {
173
+ RichFileTree
174
+ } from "./chunk-LQNEZDRM.js";
172
175
  import {
173
176
  FileArtifactPane,
174
177
  FilePreview,
@@ -461,6 +464,7 @@ export {
461
464
  RailSeparator,
462
465
  RealtimeSessionRegistry,
463
466
  ResourceMeter,
467
+ RichFileTree,
464
468
  RunGroup,
465
469
  RuntimePane,
466
470
  SIDEBAR_MOBILE_WIDTH,
package/dist/styles.css CHANGED
@@ -1082,6 +1082,9 @@
1082
1082
  .h-\[380px\] {
1083
1083
  height: 380px;
1084
1084
  }
1085
+ .h-\[480px\] {
1086
+ height: 480px;
1087
+ }
1085
1088
  .h-\[500px\] {
1086
1089
  height: 500px;
1087
1090
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -151,6 +151,7 @@
151
151
  },
152
152
  "dependencies": {
153
153
  "@nanostores/react": "^1.1.0",
154
+ "@pierre/trees": "1.0.0-beta.3",
154
155
  "@radix-ui/react-avatar": "^1.1.0",
155
156
  "@radix-ui/react-collapsible": "^1.1.0",
156
157
  "@radix-ui/react-dialog": "^1.1.0",