@tangle-network/sandbox-ui 0.113.1 → 0.113.3

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.
@@ -6,13 +6,7 @@ import {
6
6
  } from "./chunk-EI44GEQ5.js";
7
7
 
8
8
  // src/workspace/workspace-layout.tsx
9
- import {
10
- useCallback,
11
- useEffect,
12
- useMemo,
13
- useRef,
14
- useState
15
- } from "react";
9
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
16
10
  import {
17
11
  PanelBottomClose,
18
12
  PanelBottomOpen,
@@ -215,6 +209,7 @@ function WorkspaceLayout({
215
209
  maxLeftWidth = 420,
216
210
  minRightWidth = 320,
217
211
  maxRightWidth = 720,
212
+ minCenterWidth = 400,
218
213
  minBottomHeight = 100,
219
214
  maxBottomHeight = 500,
220
215
  persistenceKey,
@@ -332,8 +327,35 @@ function WorkspaceLayout({
332
327
  window.removeEventListener("pointercancel", handlePointerUp);
333
328
  };
334
329
  }, [desktop, maxBottomHeight, maxLeftWidth, maxRightWidth, minBottomHeight, minLeftWidth, minRightWidth]);
335
- const leftStyle = useMemo(() => ({ width: `${leftWidth}px` }), [leftWidth]);
336
- const rightStyle = useMemo(() => ({ width: `${rightWidth}px` }), [rightWidth]);
330
+ const shellRef = useRef(null);
331
+ const [shellWidth, setShellWidth] = useState(null);
332
+ useEffect(() => {
333
+ const shell = shellRef.current;
334
+ if (!shell || typeof ResizeObserver === "undefined") return;
335
+ const observer = new ResizeObserver((entries) => {
336
+ const width = entries[0]?.contentRect.width;
337
+ if (typeof width === "number") setShellWidth(width);
338
+ });
339
+ observer.observe(shell);
340
+ return () => observer.disconnect();
341
+ }, []);
342
+ const { leftPx, rightPx } = useMemo(() => {
343
+ const leftShown = desktop && hasLeft && leftOpen;
344
+ const rightShown = desktop && hasRight && rightOpen;
345
+ let leftPx2 = leftWidth;
346
+ let rightPx2 = rightWidth;
347
+ if (shellWidth === null) return { leftPx: leftPx2, rightPx: rightPx2 };
348
+ const room = () => shellWidth - (leftShown ? leftPx2 : 0) - (rightShown ? rightPx2 : 0);
349
+ if (rightShown && room() < minCenterWidth) {
350
+ rightPx2 = Math.max(minRightWidth, rightPx2 - (minCenterWidth - room()));
351
+ }
352
+ if (leftShown && room() < minCenterWidth) {
353
+ leftPx2 = Math.max(minLeftWidth, leftPx2 - (minCenterWidth - room()));
354
+ }
355
+ return { leftPx: leftPx2, rightPx: rightPx2 };
356
+ }, [desktop, hasLeft, hasRight, leftOpen, leftWidth, minCenterWidth, minLeftWidth, minRightWidth, rightOpen, rightWidth, shellWidth]);
357
+ const leftStyle = useMemo(() => ({ width: `${leftPx}px` }), [leftPx]);
358
+ const rightStyle = useMemo(() => ({ width: `${rightPx}px` }), [rightPx]);
337
359
  const startResize = (side, pointerStartX) => {
338
360
  dragStateRef.current = {
339
361
  side,
@@ -371,7 +393,7 @@ function WorkspaceLayout({
371
393
  className
372
394
  ),
373
395
  children: [
374
- /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1", children: [
396
+ /* @__PURE__ */ jsxs("div", { ref: shellRef, className: "flex min-h-0 flex-1", children: [
375
397
  desktop && left && leftOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
376
398
  /* @__PURE__ */ jsxs(
377
399
  "aside",
@@ -1860,7 +1882,7 @@ function SandboxWorkbench({
1860
1882
  children: transcript
1861
1883
  }
1862
1884
  );
1863
- const artifactPanel = artifacts.length > 0 ? /* @__PURE__ */ jsxs9("section", { className: "flex h-full min-h-0 flex-col bg-surface-container", children: [
1885
+ const artifactPanel = artifacts.length > 0 || emptyArtifactState ? /* @__PURE__ */ jsxs9("section", { className: "flex h-full min-h-0 flex-col bg-surface-container", children: [
1864
1886
  /* @__PURE__ */ jsx10(
1865
1887
  ArtifactTabs,
1866
1888
  {
@@ -1880,7 +1902,7 @@ function SandboxWorkbench({
1880
1902
  ) }) })
1881
1903
  ] }) : null;
1882
1904
  const directoryPlacement = layout?.directoryPlacement ?? (directory ? "left" : "hidden");
1883
- const artifactPlacement = layout?.artifactPlacement ?? (artifacts.length > 0 ? "right" : "hidden");
1905
+ const artifactPlacement = layout?.artifactPlacement ?? (artifactPanel ? "right" : "hidden");
1884
1906
  const runtimePlacement = layout?.runtimePlacement ?? (runtime ? "bottom" : "hidden");
1885
1907
  const regionSections = {
1886
1908
  left: [],
@@ -7796,7 +7796,7 @@ function ChangesPane({
7796
7796
  showFileHeader: false,
7797
7797
  className: "flex-1"
7798
7798
  }
7799
- ) : /* @__PURE__ */ jsx10("p", { className: "px-3 py-3 text-xs text-muted-foreground", role: "status", children: "Loading diff\u2026" })
7799
+ ) : selected.loadError ? /* @__PURE__ */ jsx10("p", { className: "px-3 py-3 text-xs text-destructive", role: "alert", children: selected.loadError }) : /* @__PURE__ */ jsx10("p", { className: "px-3 py-3 text-xs text-muted-foreground", role: "status", children: "Loading diff\u2026" })
7800
7800
  ] }) : showList && /* @__PURE__ */ jsx10("p", { className: "px-3 py-3 text-xs text-muted-foreground", children: "Select a file to read its diff." }) }),
7801
7801
  (onCommit || onPush) && /* @__PURE__ */ jsxs7("div", { className: cn("shrink-0 space-y-2 border-t bg-surface-container-low p-3", BORDER), children: [
7802
7802
  onCommit && /* @__PURE__ */ jsx10(
package/dist/index.js CHANGED
@@ -133,7 +133,7 @@ import {
133
133
  formatRelativeAge,
134
134
  shellShouldRevalidate,
135
135
  useOptimisticSessionItems
136
- } from "./chunk-2Q3KDQX7.js";
136
+ } from "./chunk-JZCRK2BJ.js";
137
137
  import {
138
138
  BRAND_PRISM_THEME,
139
139
  ChangesPane,
@@ -150,7 +150,7 @@ import {
150
150
  buildUnifiedPatch,
151
151
  computeDiffStats,
152
152
  resolveLanguage
153
- } from "./chunk-VEK3EZIW.js";
153
+ } from "./chunk-RDUYWQQ7.js";
154
154
  import {
155
155
  FileArtifactPane,
156
156
  FilePreview,
@@ -87,6 +87,11 @@ interface ChangedFile {
87
87
  /** Present once the consumer has resolved contents for the selected file. */
88
88
  baseline?: string;
89
89
  current?: string;
90
+ /**
91
+ * Why the sides could not be resolved. Shown under the file's header in
92
+ * place of the loading line, so a failed read never looks like a slow one.
93
+ */
94
+ loadError?: string;
90
95
  }
91
96
  interface ChangesPaneProps {
92
97
  /** Current branch; `null` when the tree has no commits yet or is not a repository. */
package/dist/workbench.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  buildUnifiedPatch,
15
15
  computeDiffStats,
16
16
  resolveLanguage
17
- } from "./chunk-VEK3EZIW.js";
17
+ } from "./chunk-RDUYWQQ7.js";
18
18
  import "./chunk-PZVUIUUW.js";
19
19
  import "./chunk-K4Q4E7D7.js";
20
20
  import "./chunk-OMUIPJQZ.js";
@@ -46,6 +46,12 @@ interface WorkspaceLayoutProps {
46
46
  minRightWidth?: number;
47
47
  /** Maximum right panel width in px */
48
48
  maxRightWidth?: number;
49
+ /**
50
+ * Width in px the center column keeps on desktop. When the shell is too
51
+ * narrow for the stored pane widths, the right pane yields down to its
52
+ * minimum first, then the left; the stored widths return when room does.
53
+ */
54
+ minCenterWidth?: number;
49
55
  /** Minimum bottom panel height in px */
50
56
  minBottomHeight?: number;
51
57
  /** Maximum bottom panel height in px */
@@ -99,7 +105,7 @@ interface WorkspaceLayoutProps {
99
105
  centerHeaderVisibility?: "always" | "auto";
100
106
  className?: string;
101
107
  }
102
- declare function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter, right, rightHeader, bottom, bottomHeader, defaultLeftOpen, defaultRightOpen, defaultBottomOpen, defaultLeftWidth, defaultRightWidth, defaultBottomHeight, minLeftWidth, maxLeftWidth, minRightWidth, maxRightWidth, minBottomHeight, maxBottomHeight, persistenceKey, resizable, theme, density, leftLabel, rightLabel, bottomLabel, leftOpen: leftOpenProp, onLeftOpenChange, rightOpen: rightOpenProp, onRightOpenChange, keyboardShortcuts, leftCollapsedControl, leftContentClassName, rightContentClassName, centerHeaderVisibility, className, }: WorkspaceLayoutProps): React$1.JSX.Element;
108
+ declare function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter, right, rightHeader, bottom, bottomHeader, defaultLeftOpen, defaultRightOpen, defaultBottomOpen, defaultLeftWidth, defaultRightWidth, defaultBottomHeight, minLeftWidth, maxLeftWidth, minRightWidth, maxRightWidth, minCenterWidth, minBottomHeight, maxBottomHeight, persistenceKey, resizable, theme, density, leftLabel, rightLabel, bottomLabel, leftOpen: leftOpenProp, onLeftOpenChange, rightOpen: rightOpenProp, onRightOpenChange, keyboardShortcuts, leftCollapsedControl, leftContentClassName, rightContentClassName, centerHeaderVisibility, className, }: WorkspaceLayoutProps): React$1.JSX.Element;
103
109
 
104
110
  type WorkspacePaneHeaderProps = HTMLAttributes<HTMLDivElement>;
105
111
  /**
@@ -573,6 +579,10 @@ interface SandboxWorkbenchProps {
573
579
  onArtifactClose?: (artifactId: string) => void;
574
580
  runtime?: RuntimePaneProps;
575
581
  layout?: SandboxWorkbenchLayoutOptions;
582
+ /**
583
+ * Shown in the artifact region while no artifact is selected. When given,
584
+ * the region renders before the first artifact exists.
585
+ */
576
586
  emptyArtifactState?: ReactNode;
577
587
  className?: string;
578
588
  }
package/dist/workspace.js CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  formatRelativeAge,
22
22
  shellShouldRevalidate,
23
23
  useOptimisticSessionItems
24
- } from "./chunk-2Q3KDQX7.js";
24
+ } from "./chunk-JZCRK2BJ.js";
25
25
  import "./chunk-BGVEHENC.js";
26
26
  import "./chunk-EI44GEQ5.js";
27
27
  import "./chunk-CZ7CSFO4.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.113.1",
3
+ "version": "0.113.3",
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",