@tangle-network/sandbox-ui 0.139.1 → 0.140.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.
@@ -334,7 +334,7 @@ function VaultTree({ root, selectedPath, activeFolder, onSelect, onFolderToggle,
334
334
  className: [
335
335
  "group flex min-h-8 w-full cursor-pointer select-none items-center gap-1.5 rounded-md pr-2 text-sm transition-colors [@media(pointer:coarse)]:min-h-10",
336
336
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
337
- selected ? "bg-[var(--accent-surface-soft)] font-medium text-[var(--accent-text)]" : active ? "bg-muted font-medium text-foreground" : "text-foreground hover:bg-muted"
337
+ selected ? "bg-[var(--ix-sel-bg)] font-medium text-[var(--accent-text)]" : active ? "bg-muted font-medium text-foreground" : "text-foreground hover:bg-[var(--ix-hover-bg)]"
338
338
  ].join(" "),
339
339
  children: [
340
340
  /* @__PURE__ */ jsx("span", {
@@ -1 +1 @@
1
- export { r as VAULT_TREE_CHILD_PAGE, i as VaultTree, t as fileTreeFromPaths, n as filterFileNodes } from "./tree-data-Dmiu8aMf.js";
1
+ export { r as VAULT_TREE_CHILD_PAGE, i as VaultTree, t as fileTreeFromPaths, n as filterFileNodes } from "./tree-data-D57M2idS.js";
@@ -1,4 +1,4 @@
1
- import { C as ChangedFile, D as SandboxArtifactTerminal, E as SandboxArtifactPaneProps, S as ArtifactView, T as SandboxArtifact, _ as PillTabItem, a as PreviewViewProps, b as ChangesPane, c as FileBreadcrumb, d as GitStatusBadge, f as PanelHeader, g as computeDiffStats, h as buildUnifiedPatch, i as PreviewView, l as FileBreadcrumbProps, m as DiffStats, n as CodeSurface, o as CodeView, p as PanelHeaderProps, r as CodeSurfaceProps, s as CodeViewProps, t as CODE_THEME, u as DiffStatsBadge, v as PillTabs, w as ChangesPaneProps, x as SandboxArtifactPane, y as PillTabsProps } from "./index-CvtEhIpk.js";
1
+ import { C as ChangedFile, D as SandboxArtifactTerminal, E as SandboxArtifactPaneProps, S as ArtifactView, T as SandboxArtifact, _ as PillTabItem, a as PreviewViewProps, b as ChangesPane, c as FileBreadcrumb, d as GitStatusBadge, f as PanelHeader, g as computeDiffStats, h as buildUnifiedPatch, i as PreviewView, l as FileBreadcrumbProps, m as DiffStats, n as CodeSurface, o as CodeView, p as PanelHeaderProps, r as CodeSurfaceProps, s as CodeViewProps, t as CODE_THEME, u as DiffStatsBadge, v as PillTabs, w as ChangesPaneProps, x as SandboxArtifactPane, y as PillTabsProps } from "./index-BLCi13uK.js";
2
2
  import { n as DiffViewProps, t as DiffView } from "./diff-view-DDHWtR6X.js";
3
3
  import { a as PreviewReadiness, i as PreviewAccess, n as EmbeddedAppView, r as EmbeddedAppViewProps, t as EmbeddedApp } from "./embedded-app-view-Ta5GI4hx.js";
4
4
  export { type ArtifactView, CODE_THEME, type ChangedFile, ChangesPane, type ChangesPaneProps, CodeSurface, type CodeSurfaceProps, CodeView, type CodeViewProps, type DiffStats, DiffStatsBadge, DiffView, type DiffViewProps, type EmbeddedApp, EmbeddedAppView, type EmbeddedAppViewProps, FileBreadcrumb, type FileBreadcrumbProps, GitStatusBadge, PanelHeader, type PanelHeaderProps, type PillTabItem, PillTabs, type PillTabsProps, type PreviewAccess, type PreviewReadiness, PreviewView, type PreviewViewProps, type SandboxArtifact, SandboxArtifactPane, type SandboxArtifactPaneProps, type SandboxArtifactTerminal, buildUnifiedPatch, computeDiffStats };
@@ -1,8 +1,8 @@
1
1
  import { t as cn$1 } from "./utils-BER_bdgE.js";
2
2
  import { r as ShellHeader } from "./shell-header-CwqDzC4I.js";
3
3
  import { t as MOTION_CONTROL } from "./motion-Bn7ESHrj.js";
4
- import { i as VaultTree, n as filterFileNodes, t as fileTreeFromPaths } from "./tree-data-Dmiu8aMf.js";
5
- import { ArtifactPane, ArtifactPane as ArtifactPane$1, Button, EmptyState, Input, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@tangle-network/ui/primitives";
4
+ import { i as VaultTree, n as filterFileNodes, t as fileTreeFromPaths } from "./tree-data-D57M2idS.js";
5
+ import { ArtifactPane, ArtifactPane as ArtifactPane$1, Button, EmptyState, Input, SegmentedControl, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@tangle-network/ui/primitives";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
7
  import { Markdown } from "@tangle-network/ui/markdown";
8
8
  import { useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from "react";
@@ -10,7 +10,7 @@ import { createPortal } from "react-dom";
10
10
  import * as DialogPrimitive from "@radix-ui/react-dialog";
11
11
  import { AlertCircle, AlertTriangle, ArrowLeft, Binary, Bot, Boxes, CheckCircle, ChevronDown, ChevronUp, FileCode2, FileText, FolderOpen, FolderTree, LayoutPanelTop, Loader2, Maximize2, MessageSquareText, Minimize2, PanelBottomClose, PanelBottomOpen, PanelLeftClose, PanelLeftOpen, PanelRightClose, PanelRightOpen, Plus, RefreshCw, Search, Settings, ShieldCheck, Sparkles, Terminal, TerminalSquare, Upload, Wifi, X, Zap } from "lucide-react";
12
12
  import { focusField, focusRing, focusRingInset } from "@tangle-network/ui/utils";
13
- import { FileArtifactPane, FileTree, filterFileTree } from "@tangle-network/ui/files";
13
+ import { FileArtifactPane, FileTabs, FileTree, filterFileTree } from "@tangle-network/ui/files";
14
14
  import { useNavbarSessions } from "@tangle-network/ui/stores";
15
15
  import { ChatContainer } from "@tangle-network/ui/chat";
16
16
  import { OpenUIArtifactRenderer } from "@tangle-network/ui/openui";
@@ -1620,11 +1620,12 @@ function createShellShouldRevalidate(options = {}) {
1620
1620
  */
1621
1621
  const shellShouldRevalidate = createShellShouldRevalidate();
1622
1622
  // src/workspace/workspace-artifact-view.tsx
1623
- /** The shared technical renderer for workspace files and generated artifacts. */
1623
+ /** The shared technical renderer for workspace files and generated artifacts. It paints no plane, so it sits on the pane that holds it. */
1624
1624
  function WorkspaceArtifactView({ artifact, hideTitleBlock }) {
1625
1625
  switch (artifact.kind) {
1626
1626
  case "file": return /* @__PURE__ */ jsx(FileArtifactPane, {
1627
1627
  path: artifact.path === artifact.filename ? void 0 : artifact.path,
1628
+ className: "bg-transparent",
1628
1629
  filename: artifact.filename,
1629
1630
  content: artifact.content,
1630
1631
  blobUrl: artifact.blobUrl,
@@ -1642,6 +1643,7 @@ function WorkspaceArtifactView({ artifact, hideTitleBlock }) {
1642
1643
  });
1643
1644
  case "markdown": return /* @__PURE__ */ jsx(ArtifactPane, {
1644
1645
  hideTitleBlock,
1646
+ className: "bg-transparent",
1645
1647
  eyebrow: artifact.eyebrow ?? "Document",
1646
1648
  title: artifact.title,
1647
1649
  subtitle: artifact.subtitle,
@@ -1659,6 +1661,7 @@ function WorkspaceArtifactView({ artifact, hideTitleBlock }) {
1659
1661
  });
1660
1662
  case "openui": return /* @__PURE__ */ jsx(ArtifactPane, {
1661
1663
  hideTitleBlock,
1664
+ className: "bg-transparent",
1662
1665
  eyebrow: artifact.eyebrow ?? "Structured Artifact",
1663
1666
  title: artifact.title,
1664
1667
  subtitle: artifact.subtitle,
@@ -1673,6 +1676,7 @@ function WorkspaceArtifactView({ artifact, hideTitleBlock }) {
1673
1676
  });
1674
1677
  case "custom": return /* @__PURE__ */ jsx(ArtifactPane, {
1675
1678
  hideTitleBlock,
1679
+ className: "bg-transparent",
1676
1680
  eyebrow: artifact.eyebrow ?? "Artifact",
1677
1681
  title: artifact.title,
1678
1682
  subtitle: artifact.subtitle,
@@ -2532,9 +2536,17 @@ function useSidebarWidth(key, containerWidth) {
2532
2536
  reset: () => save(SIDEBAR_DEFAULT_PX)
2533
2537
  };
2534
2538
  }
2535
- /** Drag, arrow keys (Shift for larger steps), Home/End, or double-click to reset the sidebar width. */
2539
+ /**
2540
+ * The tree's and the open file's header rows: one height and one chrome plane (the page, a step under the card), so
2541
+ * they read as one strip with one baseline. Fields in it take the card plane, as the active tab does.
2542
+ */
2543
+ const HEADER_ROW = "flex h-11 shrink-0 pointer-coarse:h-14 items-center bg-background shadow-[inset_0_-1px_0_hsl(var(--border))] [--field-surface:hsl(var(--card))]";
2544
+ /**
2545
+ * A 1px line below the header row with a 9px invisible hit area. Its negative margin cancels its width, so the header row stays one strip.
2546
+ * Drag, arrow keys (Shift for larger steps), Home/End, or double-click to reset the sidebar width.
2547
+ */
2536
2548
  function SidebarResizer({ sidebar, label }) {
2537
- return /* @__PURE__ */ jsx("div", {
2549
+ return /* @__PURE__ */ jsxs("div", {
2538
2550
  role: "separator",
2539
2551
  "aria-orientation": "vertical",
2540
2552
  "aria-label": `Resize ${label.toLowerCase()} sidebar`,
@@ -2565,11 +2577,14 @@ function SidebarResizer({ sidebar, label }) {
2565
2577
  handle.addEventListener("pointermove", move);
2566
2578
  handle.addEventListener("pointerup", up);
2567
2579
  },
2568
- className: "group relative w-1.5 shrink-0 cursor-col-resize touch-none outline-none",
2569
- children: /* @__PURE__ */ jsx("span", {
2580
+ className: "group relative z-10 -mr-px w-px shrink-0 cursor-col-resize touch-none outline-none",
2581
+ children: [/* @__PURE__ */ jsx("span", {
2570
2582
  "aria-hidden": true,
2571
- className: "absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-border transition-colors group-hover:bg-primary group-focus-visible:bg-primary"
2572
- })
2583
+ className: "absolute bottom-0 left-0 top-11 w-px pointer-coarse:top-14 bg-border transition-colors group-hover:bg-ring group-focus-visible:bg-ring"
2584
+ }), /* @__PURE__ */ jsx("span", {
2585
+ "aria-hidden": true,
2586
+ className: "absolute bottom-0 -left-1 top-11 w-[9px] pointer-coarse:top-14"
2587
+ })]
2573
2588
  });
2574
2589
  }
2575
2590
  function indexNodes(nodes) {
@@ -2589,8 +2604,11 @@ function activeElementWithin(element) {
2589
2604
  }
2590
2605
  /**
2591
2606
  * Compact file navigation shared by workspace companions and standalone panes.
2592
- * The tree sits in its own surface: folders start collapsed, expansion is
2593
- * remembered under `expansionKey`, and a preview replaces the tree until Back.
2607
+ * One card holds the tree and the open file. Both columns start with a header
2608
+ * row of one height on the chrome plane, so the search field and the open-file
2609
+ * tabs share one baseline; every inset reads `--files-inset`. Folders start
2610
+ * collapsed, expansion is remembered under `expansionKey`, and in the stacked
2611
+ * layout a preview replaces the tree until Back.
2594
2612
  */
2595
2613
  function WorkspaceFilesPane({ root, paths, selectedPath, onSelect, preview, onBack, emptyState, expansionKey, search = true, label = "Files", headerActions, surface = "card", layout = "split", tabs = true, expandable = true, className, style }) {
2596
2614
  const plain = surface === "plain";
@@ -2633,6 +2651,7 @@ function WorkspaceFilesPane({ root, paths, selectedPath, onSelect, preview, onBa
2633
2651
  const wasPreviewRef = useRef(false);
2634
2652
  const hasPreview = preview !== void 0;
2635
2653
  const isEmpty = nodes.length === 0;
2654
+ const searchable = search && !isEmpty;
2636
2655
  const normalizedSelection = selectedPath?.replace(/^(\.\/|\/)+/, "").replace(/\/+$/, "");
2637
2656
  const mountedRef = useRef(false);
2638
2657
  const openedByReaderRef = useRef(false);
@@ -2659,7 +2678,7 @@ function WorkspaceFilesPane({ root, paths, selectedPath, onSelect, preview, onBa
2659
2678
  ref: rootRef,
2660
2679
  "data-workspace-files-layout": split ? "split" : "stack",
2661
2680
  "data-expanded": expanded ? "" : void 0,
2662
- className: cn$1("flex h-full min-h-0 min-w-0", split ? "flex-row" : "flex-col", expanded && "fixed inset-0 z-50 h-auto bg-background p-2", className),
2681
+ className: cn$1("flex h-full min-h-0 min-w-0 overflow-hidden bg-card text-card-foreground [--files-inset:0.75rem]", split ? "flex-row" : "flex-col", !plain && "rounded-[var(--radius-lg)] border border-border shadow-[var(--edge-highlight),var(--shadow-card)]", className, expanded && "fixed inset-0 z-50 h-auto max-h-none w-auto max-w-none rounded-none border-0"),
2663
2682
  style: expanded ? void 0 : style,
2664
2683
  children: [
2665
2684
  /* @__PURE__ */ jsx("div", {
@@ -2669,77 +2688,68 @@ function WorkspaceFilesPane({ root, paths, selectedPath, onSelect, preview, onBa
2669
2688
  role: "region",
2670
2689
  "aria-label": "Workspace files",
2671
2690
  style: split ? { width: sidebar.width } : void 0,
2672
- className: cn$1("flex min-h-0 flex-col", split ? "shrink-0" : "flex-1", !plain && "p-2", !split && hasPreview && "hidden"),
2691
+ className: cn$1("flex min-h-0 flex-col outline-none", split ? "shrink-0" : "flex-1", !split && hasPreview && "hidden"),
2673
2692
  children: /* @__PURE__ */ jsxs("section", {
2674
2693
  "aria-labelledby": headingId,
2675
2694
  "data-workspace-files-surface": surface,
2676
- className: cn$1("flex min-h-0 flex-1 flex-col overflow-hidden", !plain && "rounded-xl border border-border bg-card text-card-foreground shadow-sm"),
2677
- children: [
2678
- plain ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("h2", {
2679
- id: headingId,
2680
- className: "sr-only",
2681
- children: label
2682
- }), headerActions && /* @__PURE__ */ jsx("div", {
2683
- className: "flex shrink-0 items-center justify-end gap-1 px-3 pt-3",
2684
- children: headerActions
2685
- })] }) : /* @__PURE__ */ jsxs("div", {
2686
- className: "flex shrink-0 items-center gap-2 px-3 pb-2 pt-3",
2687
- children: [/* @__PURE__ */ jsx("h2", {
2695
+ className: "flex min-h-0 flex-1 flex-col",
2696
+ children: [/* @__PURE__ */ jsxs("div", {
2697
+ className: cn$1(HEADER_ROW, "gap-2 px-[var(--files-inset)]"),
2698
+ children: [
2699
+ /* @__PURE__ */ jsx("h2", {
2688
2700
  id: headingId,
2689
- className: "min-w-0 flex-1 truncate text-sm font-semibold text-foreground",
2701
+ className: cn$1("min-w-0 flex-1 truncate text-sm font-medium text-foreground", (plain || searchable) && "sr-only"),
2690
2702
  children: label
2691
- }), headerActions && /* @__PURE__ */ jsx("div", {
2692
- className: "flex shrink-0 items-center gap-1",
2693
- children: headerActions
2694
- })]
2695
- }),
2696
- search && !isEmpty && /* @__PURE__ */ jsx("div", {
2697
- className: cn$1("shrink-0 px-3 pb-2", plain && "pt-3"),
2698
- children: /* @__PURE__ */ jsx(Input, {
2703
+ }),
2704
+ searchable && /* @__PURE__ */ jsx(Input, {
2699
2705
  type: "search",
2700
2706
  size: "sm",
2701
2707
  value: query,
2702
2708
  onChange: (event) => setQuery(event.target.value),
2703
2709
  placeholder: `Search ${label.toLowerCase()}…`,
2704
- "aria-label": `Search ${label.toLowerCase()}`
2705
- })
2706
- }),
2707
- /* @__PURE__ */ jsx("div", {
2708
- className: cn$1("min-h-0 flex-1 overflow-y-auto px-1.5 py-1.5", (!plain || search && !isEmpty) && "border-t border-border"),
2709
- children: isEmpty ? emptyState !== void 0 ? emptyState : /* @__PURE__ */ jsx(EmptyState, {
2710
- icon: /* @__PURE__ */ jsx(FolderOpen, { className: "h-6 w-6" }),
2711
- title: "No files yet"
2712
- }) : visible.length === 0 ? /* @__PURE__ */ jsxs("div", {
2713
- className: "flex flex-col items-center gap-3 p-6 text-center",
2714
- children: [/* @__PURE__ */ jsxs("p", {
2715
- className: "max-w-xs break-words text-xs text-muted-foreground",
2716
- children: [
2717
- "No files match “",
2718
- query.trim(),
2719
- "”."
2720
- ]
2721
- }), /* @__PURE__ */ jsx(Button, {
2722
- type: "button",
2723
- variant: "outline",
2724
- size: "sm",
2725
- onClick: () => setQuery(""),
2726
- children: "Clear search"
2727
- })]
2728
- }) : /* @__PURE__ */ jsx(VaultTree, {
2729
- root: treeRoot,
2730
- selectedPath: normalizedSelection,
2731
- onSelect: (path) => {
2732
- if (treeRef.current) returnFocusRef.current = activeElementWithin(treeRef.current);
2733
- openedByReaderRef.current = true;
2734
- onSelect?.(path, index.get(path));
2735
- },
2736
- onFolderSelect: (path) => onSelect?.(`${path}/`, index.get(path)),
2737
- storageKey: expansionKey,
2738
- expandAll: query.trim().length > 0,
2739
- label
2710
+ "aria-label": `Search ${label.toLowerCase()}`,
2711
+ className: "min-w-0 flex-1"
2712
+ }),
2713
+ headerActions && /* @__PURE__ */ jsx("div", {
2714
+ className: "ml-auto flex shrink-0 items-center gap-1",
2715
+ children: headerActions
2740
2716
  })
2717
+ ]
2718
+ }), /* @__PURE__ */ jsx("div", {
2719
+ className: "min-h-0 flex-1 overflow-y-auto px-[calc(var(--files-inset)_-_0.25rem)] py-2",
2720
+ children: isEmpty ? emptyState !== void 0 ? emptyState : /* @__PURE__ */ jsx(EmptyState, {
2721
+ icon: /* @__PURE__ */ jsx(FolderOpen, { className: "h-6 w-6" }),
2722
+ title: "No files yet"
2723
+ }) : visible.length === 0 ? /* @__PURE__ */ jsxs("div", {
2724
+ className: "flex flex-col items-center gap-3 p-6 text-center",
2725
+ children: [/* @__PURE__ */ jsxs("p", {
2726
+ className: "max-w-xs break-words text-xs text-muted-foreground",
2727
+ children: [
2728
+ "No files match “",
2729
+ query.trim(),
2730
+ "”."
2731
+ ]
2732
+ }), /* @__PURE__ */ jsx(Button, {
2733
+ type: "button",
2734
+ variant: "outline",
2735
+ size: "sm",
2736
+ onClick: () => setQuery(""),
2737
+ children: "Clear search"
2738
+ })]
2739
+ }) : /* @__PURE__ */ jsx(VaultTree, {
2740
+ root: treeRoot,
2741
+ selectedPath: normalizedSelection,
2742
+ onSelect: (path) => {
2743
+ if (treeRef.current) returnFocusRef.current = activeElementWithin(treeRef.current);
2744
+ openedByReaderRef.current = true;
2745
+ onSelect?.(path, index.get(path));
2746
+ },
2747
+ onFolderSelect: (path) => onSelect?.(`${path}/`, index.get(path)),
2748
+ storageKey: expansionKey,
2749
+ expandAll: query.trim().length > 0,
2750
+ label
2741
2751
  })
2742
- ]
2752
+ })]
2743
2753
  })
2744
2754
  }),
2745
2755
  split && /* @__PURE__ */ jsx(SidebarResizer, {
@@ -2786,63 +2796,44 @@ function FilesViewer({ preview, split, tabs, empty, backRef, onBack, onOpen, exp
2786
2796
  return /* @__PURE__ */ jsxs("div", {
2787
2797
  className: "flex min-h-0 min-w-0 flex-1 flex-col",
2788
2798
  children: [/* @__PURE__ */ jsxs("div", {
2789
- className: "sticky top-0 z-10 flex min-h-10 shrink-0 items-center gap-2 border-b border-border bg-background px-2",
2799
+ className: cn$1(HEADER_ROW, "sticky top-0 z-10 gap-2 pr-[var(--files-inset)]", !(tabs && open.length > 0) && "pl-[var(--files-inset)]", !split && "h-auto min-h-11 flex-wrap py-1.5 pointer-coarse:h-auto"),
2790
2800
  children: [
2791
2801
  onBack && !split && preview && /* @__PURE__ */ jsxs(Button, {
2792
2802
  ref: backRef,
2793
2803
  type: "button",
2794
- variant: "bare",
2804
+ variant: "ghost",
2805
+ size: "sm",
2795
2806
  onClick: onBack,
2796
- className: "inline-flex shrink-0 items-center gap-1 rounded-md px-1 py-1 text-sm text-muted-foreground hover:text-foreground",
2797
- children: [/* @__PURE__ */ jsx(ArrowLeft, {
2798
- "aria-hidden": "true",
2799
- className: "h-3.5 w-3.5"
2800
- }), "Back to files"]
2807
+ className: "-ml-2 shrink-0 gap-1 px-2 text-muted-foreground",
2808
+ children: [/* @__PURE__ */ jsx(ArrowLeft, { "aria-hidden": "true" }), "Back to files"]
2801
2809
  }),
2802
- tabs && open.length > 0 ? /* @__PURE__ */ jsx("div", {
2803
- role: "tablist",
2804
- "aria-label": "Open files",
2805
- className: "flex min-w-0 flex-1 items-end self-stretch overflow-x-auto",
2806
- children: open.map((entry) => {
2807
- const selected = entry === path;
2808
- return /* @__PURE__ */ jsxs("div", {
2809
- title: entry,
2810
- className: cn$1("group flex h-full shrink-0 items-center border-b-2 text-sm", selected ? "border-primary text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"),
2811
- children: [/* @__PURE__ */ jsx("button", {
2812
- type: "button",
2813
- role: "tab",
2814
- "aria-selected": selected,
2815
- onClick: () => onOpen(entry),
2816
- className: "max-w-48 truncate py-2 pl-3 pr-1 outline-none focus-visible:underline",
2817
- children: baseName(entry)
2818
- }), /* @__PURE__ */ jsx("button", {
2819
- type: "button",
2820
- "aria-label": `Close ${baseName(entry)}`,
2821
- onClick: () => close(entry),
2822
- className: cn$1("mr-1 rounded p-1 hover:bg-muted", !selected && "opacity-0 group-hover:opacity-100 focus-visible:opacity-100"),
2823
- children: /* @__PURE__ */ jsx(X, {
2824
- "aria-hidden": true,
2825
- className: "h-3 w-3"
2826
- })
2827
- })]
2828
- }, entry);
2829
- })
2810
+ tabs && open.length > 0 ? /* @__PURE__ */ jsx(FileTabs, {
2811
+ tabs: open.map((entry) => ({
2812
+ id: entry,
2813
+ name: baseName(entry),
2814
+ path: entry
2815
+ })),
2816
+ activeId: path,
2817
+ onSelect: onOpen,
2818
+ onClose: close,
2819
+ className: "h-full flex-1 px-[var(--files-inset)]"
2830
2820
  }) : /* @__PURE__ */ jsx("span", {
2831
- className: "min-w-0 flex-1 truncate px-1 text-sm text-muted-foreground",
2821
+ className: "min-w-0 flex-1 truncate text-sm text-foreground",
2832
2822
  title: path,
2833
- children: path
2823
+ children: path && baseName(path)
2834
2824
  }),
2835
- compare && /* @__PURE__ */ jsx("div", {
2836
- role: "group",
2825
+ compare && /* @__PURE__ */ jsx(SegmentedControl, {
2837
2826
  "aria-label": "View",
2838
- className: "flex shrink-0 rounded-md border border-border p-0.5 text-xs",
2839
- children: ["file", "diff"].map((value) => /* @__PURE__ */ jsx("button", {
2840
- type: "button",
2841
- "aria-pressed": mode === value,
2842
- onClick: () => setMode(value),
2843
- className: cn$1("rounded px-2 py-1", mode === value ? "bg-muted text-foreground" : "text-muted-foreground hover:text-foreground"),
2844
- children: value === "file" ? "File" : `Diff vs ${compare.label}`
2845
- }, value))
2827
+ value: mode,
2828
+ onValueChange: setMode,
2829
+ options: [{
2830
+ value: "file",
2831
+ label: "File"
2832
+ }, {
2833
+ value: "diff",
2834
+ label: `Diff vs ${compare.label}`
2835
+ }],
2836
+ className: cn$1("shrink-0 p-0.5 [&>button]:py-1", !split && "order-last")
2846
2837
  }),
2847
2838
  preview?.actions && /* @__PURE__ */ jsx("div", {
2848
2839
  className: "flex shrink-0 items-center gap-2",
@@ -2850,16 +2841,14 @@ function FilesViewer({ preview, split, tabs, empty, backRef, onBack, onOpen, exp
2850
2841
  }),
2851
2842
  expand && /* @__PURE__ */ jsx(Button, {
2852
2843
  type: "button",
2853
- variant: "bare",
2844
+ variant: "ghost",
2845
+ size: "icon-sm",
2854
2846
  onClick: expand.toggle,
2855
2847
  "aria-pressed": expand.expanded,
2856
2848
  "aria-label": expand.expanded ? "Exit full screen" : "Full screen",
2857
2849
  title: expand.expanded ? "Exit full screen (Esc)" : "Full screen",
2858
- className: "shrink-0 rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground",
2859
- children: /* @__PURE__ */ jsx(ExpandIcon, {
2860
- "aria-hidden": true,
2861
- className: "h-4 w-4"
2862
- })
2850
+ className: "shrink-0 text-muted-foreground",
2851
+ children: /* @__PURE__ */ jsx(ExpandIcon, { "aria-hidden": true })
2863
2852
  })
2864
2853
  ]
2865
2854
  }), preview ? /* @__PURE__ */ jsx("div", {
@@ -1,2 +1,2 @@
1
- import { $ as StatusBar, A as createShellShouldRevalidate, B as SessionSidebarVariant, C as SandboxWorkbenchLayoutOptions, D as SandboxWorkbenchSessionProps, E as SandboxWorkbenchProps, F as SessionSidebarFilter, G as dispatchSessionCreated, H as SessionCreatedDetail, I as SessionSidebarGroupBy, J as RuntimePaneProps, K as useOptimisticSessionItems, L as SessionSidebarItem, M as formatRelativeAge, N as SessionSidebar, O as ShellShouldRevalidateArgs, P as SessionSidebarBadge, Q as ContextBadge, R as SessionSidebarLink, S as SandboxWorkbenchFileArtifact, T as SandboxWorkbenchOpenUIArtifact, U as SessionOptimisticController, V as SESSION_CREATED_EVENT, W as UseOptimisticSessionItemsOptions, X as TerminalPanel, Y as TerminalLine, Z as TerminalProps, _ as TaskBoardItem, _t as WorkspaceSurfaceTitle, a as WorkspaceFilesPane, at as DirectoryPaneProps, b as SandboxWorkbenchArtifact, bt as WorkspaceLayoutProps, c as ApprovalConfidenceStat, ct as ShellHeader, d as ApprovalQueueProps, dt as WorkspacePaneHeaderProps, et as StatusBarProps, f as CalendarEvent, ft as WorkspaceSurface, g as TaskBoardColumn, gt as WorkspaceSurfaceProps, h as TaskBoard, ht as WorkspaceSurfaceHeadingLevel, i as WorkspaceArtifactViewProps, it as DirectoryPane, j as shellShouldRevalidate, k as ShellShouldRevalidateOptions, l as ApprovalItem, lt as ShellHeaderProps, m as CalendarViewProps, mt as WorkspaceSurfaceFrameProps, n as ArtifactPaneProps, nt as StatusBanner, o as WorkspaceFilesPaneProps, ot as SHELL_HEADER_HEIGHT, p as CalendarView, pt as WorkspaceSurfaceFrame, q as RuntimePane, r as WorkspaceArtifactView, rt as StatusBannerProps, s as WorkspaceFilesPreview, st as SHELL_INSET_GUTTER, t as ArtifactPane, tt as BannerType, u as ApprovalQueue, ut as WorkspacePaneHeader, v as TaskBoardProps, vt as WorkspaceSurfaceTitleProps, w as SandboxWorkbenchMarkdownArtifact, x as SandboxWorkbenchCustomArtifact, y as SandboxWorkbench, yt as WorkspaceLayout, z as SessionSidebarProps } from "./index-F42BOxUM.js";
1
+ import { $ as StatusBar, A as createShellShouldRevalidate, B as SessionSidebarVariant, C as SandboxWorkbenchLayoutOptions, D as SandboxWorkbenchSessionProps, E as SandboxWorkbenchProps, F as SessionSidebarFilter, G as dispatchSessionCreated, H as SessionCreatedDetail, I as SessionSidebarGroupBy, J as RuntimePaneProps, K as useOptimisticSessionItems, L as SessionSidebarItem, M as formatRelativeAge, N as SessionSidebar, O as ShellShouldRevalidateArgs, P as SessionSidebarBadge, Q as ContextBadge, R as SessionSidebarLink, S as SandboxWorkbenchFileArtifact, T as SandboxWorkbenchOpenUIArtifact, U as SessionOptimisticController, V as SESSION_CREATED_EVENT, W as UseOptimisticSessionItemsOptions, X as TerminalPanel, Y as TerminalLine, Z as TerminalProps, _ as TaskBoardItem, _t as WorkspaceSurfaceTitle, a as WorkspaceFilesPane, at as DirectoryPaneProps, b as SandboxWorkbenchArtifact, bt as WorkspaceLayoutProps, c as ApprovalConfidenceStat, ct as ShellHeader, d as ApprovalQueueProps, dt as WorkspacePaneHeaderProps, et as StatusBarProps, f as CalendarEvent, ft as WorkspaceSurface, g as TaskBoardColumn, gt as WorkspaceSurfaceProps, h as TaskBoard, ht as WorkspaceSurfaceHeadingLevel, i as WorkspaceArtifactViewProps, it as DirectoryPane, j as shellShouldRevalidate, k as ShellShouldRevalidateOptions, l as ApprovalItem, lt as ShellHeaderProps, m as CalendarViewProps, mt as WorkspaceSurfaceFrameProps, n as ArtifactPaneProps, nt as StatusBanner, o as WorkspaceFilesPaneProps, ot as SHELL_HEADER_HEIGHT, p as CalendarView, pt as WorkspaceSurfaceFrame, q as RuntimePane, r as WorkspaceArtifactView, rt as StatusBannerProps, s as WorkspaceFilesPreview, st as SHELL_INSET_GUTTER, t as ArtifactPane, tt as BannerType, u as ApprovalQueue, ut as WorkspacePaneHeader, v as TaskBoardProps, vt as WorkspaceSurfaceTitleProps, w as SandboxWorkbenchMarkdownArtifact, x as SandboxWorkbenchCustomArtifact, y as SandboxWorkbench, yt as WorkspaceLayout, z as SessionSidebarProps } from "./index-e2GF6seB.js";
2
2
  export { type ApprovalConfidenceStat, type ApprovalItem, ApprovalQueue, type ApprovalQueueProps, ArtifactPane, type ArtifactPaneProps, type BannerType, type CalendarEvent, CalendarView, type CalendarViewProps, type ContextBadge, DirectoryPane, type DirectoryPaneProps, RuntimePane, type RuntimePaneProps, SESSION_CREATED_EVENT, SHELL_HEADER_HEIGHT, SHELL_INSET_GUTTER, SandboxWorkbench, type SandboxWorkbenchArtifact, type SandboxWorkbenchCustomArtifact, type SandboxWorkbenchFileArtifact, type SandboxWorkbenchLayoutOptions, type SandboxWorkbenchMarkdownArtifact, type SandboxWorkbenchOpenUIArtifact, type SandboxWorkbenchProps, type SandboxWorkbenchSessionProps, type SessionCreatedDetail, type SessionOptimisticController, SessionSidebar, type SessionSidebarBadge, type SessionSidebarFilter, type SessionSidebarGroupBy, type SessionSidebarItem, type SessionSidebarLink, type SessionSidebarProps, type SessionSidebarVariant, ShellHeader, type ShellHeaderProps, type ShellShouldRevalidateArgs, type ShellShouldRevalidateOptions, StatusBanner, type StatusBannerProps, StatusBar, type StatusBarProps, TaskBoard, type TaskBoardColumn, type TaskBoardItem, type TaskBoardProps, type TerminalLine, TerminalPanel, type TerminalProps, type UseOptimisticSessionItemsOptions, WorkspaceArtifactView, type WorkspaceArtifactViewProps, WorkspaceFilesPane, type WorkspaceFilesPaneProps, type WorkspaceFilesPreview, WorkspaceLayout, type WorkspaceLayoutProps, WorkspacePaneHeader, type WorkspacePaneHeaderProps, WorkspaceSurface, WorkspaceSurfaceFrame, type WorkspaceSurfaceFrameProps, type WorkspaceSurfaceHeadingLevel, type WorkspaceSurfaceProps, WorkspaceSurfaceTitle, type WorkspaceSurfaceTitleProps, createShellShouldRevalidate, dispatchSessionCreated, formatRelativeAge, shellShouldRevalidate, useOptimisticSessionItems };
package/dist/workspace.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { i as WorkspacePaneHeader, n as SHELL_INSET_GUTTER, r as ShellHeader, t as SHELL_HEADER_HEIGHT } from "./shell-header-CwqDzC4I.js";
2
- import { C as WorkspaceSurfaceTitle, S as WorkspaceSurfaceFrame, _ as StatusBar, a as TaskBoard, b as WorkspaceLayout, c as createShellShouldRevalidate, d as SESSION_CREATED_EVENT, f as dispatchSessionCreated, g as TerminalPanel, h as RuntimePane, i as CalendarView, l as shellShouldRevalidate, m as formatRelativeAge, n as WorkspaceFilesPane, o as SandboxWorkbench, p as useOptimisticSessionItems, r as ApprovalQueue, s as WorkspaceArtifactView, t as ArtifactPane, u as SessionSidebar, v as StatusBanner, x as WorkspaceSurface, y as DirectoryPane } from "./workspace-C9TH6A2O.js";
2
+ import { C as WorkspaceSurfaceTitle, S as WorkspaceSurfaceFrame, _ as StatusBar, a as TaskBoard, b as WorkspaceLayout, c as createShellShouldRevalidate, d as SESSION_CREATED_EVENT, f as dispatchSessionCreated, g as TerminalPanel, h as RuntimePane, i as CalendarView, l as shellShouldRevalidate, m as formatRelativeAge, n as WorkspaceFilesPane, o as SandboxWorkbench, p as useOptimisticSessionItems, r as ApprovalQueue, s as WorkspaceArtifactView, t as ArtifactPane, u as SessionSidebar, v as StatusBanner, x as WorkspaceSurface, y as DirectoryPane } from "./workspace-Cis6jAGl.js";
3
3
  export { ApprovalQueue, ArtifactPane, CalendarView, DirectoryPane, RuntimePane, SESSION_CREATED_EVENT, SHELL_HEADER_HEIGHT, SHELL_INSET_GUTTER, SandboxWorkbench, SessionSidebar, ShellHeader, StatusBanner, StatusBar, TaskBoard, TerminalPanel, WorkspaceArtifactView, WorkspaceFilesPane, WorkspaceLayout, WorkspacePaneHeader, WorkspaceSurface, WorkspaceSurfaceFrame, WorkspaceSurfaceTitle, createShellShouldRevalidate, dispatchSessionCreated, formatRelativeAge, shellShouldRevalidate, useOptimisticSessionItems };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.139.1",
3
+ "version": "0.140.0",
4
4
  "license": "MIT",
5
5
  "description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
6
6
  "repository": {
@@ -137,9 +137,9 @@
137
137
  "@hocuspocus/provider": ">=2.15.0 <5.0.0",
138
138
  "@nanostores/react": ">=0.8.4 <2.0.0",
139
139
  "@tangle-network/agent-interface": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^5.2.0",
140
- "@tangle-network/brand": "^1.27.1",
140
+ "@tangle-network/brand": "^1.29.0",
141
141
  "@tangle-network/charts": "^0.21.4",
142
- "@tangle-network/ui": "^11.44.1",
142
+ "@tangle-network/ui": "^11.45.0",
143
143
  "@tanstack/react-query": "^5.0.0",
144
144
  "@tiptap/core": ">=3.20.4 <4.0.0",
145
145
  "@tiptap/extension-collaboration": ">=3.20.4 <4.0.0",
@@ -216,7 +216,7 @@
216
216
  "@radix-ui/react-dialog": "^1.3.1",
217
217
  "@radix-ui/react-dropdown-menu": "^2.2.1",
218
218
  "@radix-ui/react-select": "^2.4.1",
219
- "@tangle-network/ui": "^11.44.1",
219
+ "@tangle-network/ui": "^11.45.0",
220
220
  "diff": "^9.0.0",
221
221
  "eventsource-parser": "4.1.2",
222
222
  "lucide-react": "^1.61.0",
@@ -236,7 +236,7 @@
236
236
  "@storybook/react-vite": "^10.6.3",
237
237
  "@tailwindcss/postcss": "^4.3.3",
238
238
  "@tangle-network/agent-interface": "5.7.1",
239
- "@tangle-network/brand": "1.27.1",
239
+ "@tangle-network/brand": "1.29.0",
240
240
  "@tangle-network/charts": "^0.21.4",
241
241
  "@tanstack/react-query": "^5.104.5",
242
242
  "@testing-library/dom": "^10.4.2",
@@ -1,2 +0,0 @@
1
- import { CSV_PREVIEW_ROW_LIMIT, FileArtifactPane as FileArtifactPane$1, FileArtifactPaneProps, FileCard, FileCardProps, FileDetails, FileFormat, FileList, FileListItem, FileListProps, FileNode as FileNode$1, FilePreview, FilePreviewKind, FilePreviewProps, FileTabData as FileTabData$1, FileTabs, FileTabsProps, FileTree as FileTree$1, FileTreeProps, FileTreeVisibilityOptions as FileTreeVisibilityOptions$1, FileUploader, PdfViewer, PdfViewerConfig, PdfViewerProps, RichFileTree, RichFileTreeGitEntry, RichFileTreeGitStatus, RichFileTreeProps, RichFileTreeThemeVars, configurePdfViewer, detectFileFormat, fileExtension, filterFileTree as filterFileTree$1, getCodeLanguage, getFormatLabel, getSyntaxLanguage, parseCsv, resolveFilePreviewKind } from "@tangle-network/ui/files";
2
- export { configurePdfViewer as A, PdfViewerConfig as C, RichFileTreeGitStatus as D, RichFileTreeGitEntry as E, getFormatLabel as F, getSyntaxLanguage as I, parseCsv as L, fileExtension as M, filterFileTree$1 as N, RichFileTreeProps as O, getCodeLanguage as P, resolveFilePreviewKind as R, PdfViewer as S, RichFileTree as T, FileTabsProps as _, FileCardProps as a, FileTreeVisibilityOptions$1 as b, FileList as c, FileNode$1 as d, FilePreview as f, FileTabs as g, FileTabData$1 as h, FileCard as i, detectFileFormat as j, RichFileTreeThemeVars as k, FileListItem as l, FilePreviewProps as m, FileArtifactPane$1 as n, FileDetails as o, FilePreviewKind as p, FileArtifactPaneProps as r, FileFormat as s, CSV_PREVIEW_ROW_LIMIT as t, FileListProps as u, FileTree$1 as v, PdfViewerProps as w, FileUploader as x, FileTreeProps as y };