@tangle-network/sandbox-ui 0.116.8 → 0.117.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.
@@ -282,6 +282,7 @@ function ProviderIcon({ id, iconUrl, displayName, size = 24, className }) {
282
282
  }
283
283
  const initial = (displayName ?? id).trim().charAt(0).toUpperCase() || "?";
284
284
  const src = candidates[index];
285
+ const usesDefaultGithubMark = !iconUrl && normalizeProviderId(id) === "github";
285
286
  if (!src) return /* @__PURE__ */ jsx("span", {
286
287
  className: `flex shrink-0 items-center justify-center font-semibold text-white ${className ?? ""}`,
287
288
  style: {
@@ -299,7 +300,7 @@ function ProviderIcon({ id, iconUrl, displayName, size = 24, className }) {
299
300
  width: size,
300
301
  height: size,
301
302
  loading: "lazy",
302
- className: `shrink-0 object-contain ${className ?? ""}`,
303
+ className: `shrink-0 object-contain ${usesDefaultGithubMark ? "dark:invert [[data-sandbox-theme='']_&]:invert" : ""} ${className ?? ""}`,
303
304
  style: {
304
305
  width: size,
305
306
  height: size
package/dist/styles.css CHANGED
@@ -109,6 +109,7 @@
109
109
  --color-accent: hsl(var(--accent));
110
110
  --color-accent-foreground: hsl(var(--accent-foreground));
111
111
  --color-destructive: hsl(var(--destructive));
112
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
112
113
  --color-border: hsl(var(--border));
113
114
  --color-input: hsl(var(--input));
114
115
  --color-ring: hsl(var(--ring));
@@ -482,6 +483,9 @@
482
483
  .col-span-12 {
483
484
  grid-column: span 12 / span 12;
484
485
  }
486
+ .col-span-full {
487
+ grid-column: 1 / -1;
488
+ }
485
489
  .col-start-1 {
486
490
  grid-column-start: 1;
487
491
  }
@@ -968,6 +972,9 @@
968
972
  .max-h-\[70vh\] {
969
973
  max-height: 70vh;
970
974
  }
975
+ .max-h-\[90dvh\] {
976
+ max-height: 90dvh;
977
+ }
971
978
  .max-h-\[90vh\] {
972
979
  max-height: 90vh;
973
980
  }
@@ -995,9 +1002,15 @@
995
1002
  .min-h-8 {
996
1003
  min-height: calc(var(--spacing) * 8);
997
1004
  }
1005
+ .min-h-9 {
1006
+ min-height: calc(var(--spacing) * 9);
1007
+ }
998
1008
  .min-h-10 {
999
1009
  min-height: calc(var(--spacing) * 10);
1000
1010
  }
1011
+ .min-h-11 {
1012
+ min-height: calc(var(--spacing) * 11);
1013
+ }
1001
1014
  .min-h-24 {
1002
1015
  min-height: calc(var(--spacing) * 24);
1003
1016
  }
@@ -1169,6 +1182,9 @@
1169
1182
  .w-32 {
1170
1183
  width: calc(var(--spacing) * 32);
1171
1184
  }
1185
+ .w-36 {
1186
+ width: calc(var(--spacing) * 36);
1187
+ }
1172
1188
  .w-40 {
1173
1189
  width: calc(var(--spacing) * 40);
1174
1190
  }
@@ -1322,27 +1338,9 @@
1322
1338
  .max-w-6xl {
1323
1339
  max-width: var(--container-6xl);
1324
1340
  }
1325
- .max-w-26 {
1326
- max-width: calc(var(--spacing) * 26);
1327
- }
1328
- .max-w-28 {
1329
- max-width: calc(var(--spacing) * 28);
1330
- }
1331
- .max-w-36 {
1332
- max-width: calc(var(--spacing) * 36);
1333
- }
1334
1341
  .max-w-40 {
1335
1342
  max-width: calc(var(--spacing) * 40);
1336
1343
  }
1337
- .max-w-44 {
1338
- max-width: calc(var(--spacing) * 44);
1339
- }
1340
- .max-w-48 {
1341
- max-width: calc(var(--spacing) * 48);
1342
- }
1343
- .max-w-64 {
1344
- max-width: calc(var(--spacing) * 64);
1345
- }
1346
1344
  .max-w-80 {
1347
1345
  max-width: calc(var(--spacing) * 80);
1348
1346
  }
@@ -1508,6 +1506,9 @@
1508
1506
  .min-w-10 {
1509
1507
  min-width: calc(var(--spacing) * 10);
1510
1508
  }
1509
+ .min-w-11 {
1510
+ min-width: calc(var(--spacing) * 11);
1511
+ }
1511
1512
  .min-w-14 {
1512
1513
  min-width: calc(var(--spacing) * 14);
1513
1514
  }
@@ -1577,6 +1578,9 @@
1577
1578
  .basis-1\/3 {
1578
1579
  flex-basis: calc(1 / 3 * 100%);
1579
1580
  }
1581
+ .table-fixed {
1582
+ table-layout: fixed;
1583
+ }
1580
1584
  .caption-bottom {
1581
1585
  caption-side: bottom;
1582
1586
  }
@@ -1948,6 +1952,9 @@
1948
1952
  .overflow-x-auto {
1949
1953
  overflow-x: auto;
1950
1954
  }
1955
+ .overflow-x-hidden {
1956
+ overflow-x: hidden;
1957
+ }
1951
1958
  .overflow-y-auto {
1952
1959
  overflow-y: auto;
1953
1960
  }
@@ -2226,12 +2233,6 @@
2226
2233
  border-color: color-mix(in oklab, var(--color-destructive) 40%, transparent);
2227
2234
  }
2228
2235
  }
2229
- .border-destructive\/50 {
2230
- border-color: color-mix(in srgb, hsl(var(--destructive)) 50%, transparent);
2231
- @supports (color: color-mix(in lab, red, red)) {
2232
- border-color: color-mix(in oklab, var(--color-destructive) 50%, transparent);
2233
- }
2234
- }
2235
2236
  .border-emerald-500\/30 {
2236
2237
  border-color: color-mix(in srgb, oklch(69.6% 0.17 162.48) 30%, transparent);
2237
2238
  @supports (color: color-mix(in lab, red, red)) {
@@ -3530,6 +3531,9 @@
3530
3531
  .text-destructive {
3531
3532
  color: var(--color-destructive);
3532
3533
  }
3534
+ .text-destructive-foreground {
3535
+ color: var(--color-destructive-foreground);
3536
+ }
3533
3537
  .text-emerald-400 {
3534
3538
  color: var(--color-emerald-400);
3535
3539
  }
@@ -4017,6 +4021,9 @@
4017
4021
  background-color: color-mix(in oklab, var(--color-primary) 20%, transparent);
4018
4022
  }
4019
4023
  }
4024
+ .group-hover\:text-\[var\(--accent-text\)\]:is(:where(.group):hover *) {
4025
+ color: var(--accent-text);
4026
+ }
4020
4027
  .group-hover\:text-foreground:is(:where(.group):hover *) {
4021
4028
  color: var(--color-foreground);
4022
4029
  }
@@ -4845,6 +4852,9 @@
4845
4852
  .sm\:w-auto {
4846
4853
  width: auto;
4847
4854
  }
4855
+ .sm\:shrink-0 {
4856
+ flex-shrink: 0;
4857
+ }
4848
4858
  .sm\:grid-cols-2 {
4849
4859
  grid-template-columns: repeat(2, minmax(0, 1fr));
4850
4860
  }
@@ -4860,6 +4870,9 @@
4860
4870
  .sm\:flex-row {
4861
4871
  flex-direction: row;
4862
4872
  }
4873
+ .sm\:flex-wrap {
4874
+ flex-wrap: wrap;
4875
+ }
4863
4876
  .sm\:items-center {
4864
4877
  align-items: center;
4865
4878
  }
@@ -4888,6 +4901,9 @@
4888
4901
  text-overflow: ellipsis;
4889
4902
  white-space: nowrap;
4890
4903
  }
4904
+ .sm\:p-4 {
4905
+ padding: calc(var(--spacing) * 4);
4906
+ }
4891
4907
  .sm\:p-5 {
4892
4908
  padding: calc(var(--spacing) * 5);
4893
4909
  }
@@ -4960,9 +4976,6 @@
4960
4976
  .md\:grid-cols-5 {
4961
4977
  grid-template-columns: repeat(5, minmax(0, 1fr));
4962
4978
  }
4963
- .md\:flex-row {
4964
- flex-direction: row;
4965
- }
4966
4979
  .md\:items-center {
4967
4980
  align-items: center;
4968
4981
  }
@@ -5039,15 +5052,39 @@
5039
5052
  .xl\:col-span-8 {
5040
5053
  grid-column: span 8 / span 8;
5041
5054
  }
5055
+ .xl\:hidden {
5056
+ display: none;
5057
+ }
5058
+ .xl\:table-cell {
5059
+ display: table-cell;
5060
+ }
5061
+ .xl\:w-36 {
5062
+ width: calc(var(--spacing) * 36);
5063
+ }
5064
+ .xl\:w-72 {
5065
+ width: calc(var(--spacing) * 72);
5066
+ }
5042
5067
  .xl\:grid-cols-2 {
5043
5068
  grid-template-columns: repeat(2, minmax(0, 1fr));
5044
5069
  }
5070
+ .xl\:grid-cols-3 {
5071
+ grid-template-columns: repeat(3, minmax(0, 1fr));
5072
+ }
5045
5073
  .xl\:grid-cols-4 {
5046
5074
  grid-template-columns: repeat(4, minmax(0, 1fr));
5047
5075
  }
5048
5076
  .xl\:grid-cols-5 {
5049
5077
  grid-template-columns: repeat(5, minmax(0, 1fr));
5050
5078
  }
5079
+ .xl\:px-4 {
5080
+ padding-inline: calc(var(--spacing) * 4);
5081
+ }
5082
+ .xl\:px-6 {
5083
+ padding-inline: calc(var(--spacing) * 6);
5084
+ }
5085
+ .xl\:py-5 {
5086
+ padding-block: calc(var(--spacing) * 5);
5087
+ }
5051
5088
  }
5052
5089
  @media (prefers-color-scheme: dark) {
5053
5090
  .dark\:text-neutral-500 {
@@ -5064,6 +5101,10 @@
5064
5101
  color: color-mix(in oklab, var(--color-white) 50%, transparent);
5065
5102
  }
5066
5103
  }
5104
+ .dark\:invert {
5105
+ --tw-invert: invert(100%);
5106
+ filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
5107
+ }
5067
5108
  @media (hover: hover) {
5068
5109
  .dark\:hover\:text-white\/50:hover {
5069
5110
  color: color-mix(in srgb, #fff 50%, transparent);
@@ -5097,12 +5138,6 @@
5097
5138
  .\[\&_svg\]\:shrink-0 svg {
5098
5139
  flex-shrink: 0;
5099
5140
  }
5100
- .\[\&_td\]\:px-4 td {
5101
- padding-inline: calc(var(--spacing) * 4);
5102
- }
5103
- .\[\&_th\]\:px-4 th {
5104
- padding-inline: calc(var(--spacing) * 4);
5105
- }
5106
5141
  .\[\&_tr\]\:border-b tr {
5107
5142
  border-bottom-style: var(--tw-border-style);
5108
5143
  border-bottom-width: 1px;
@@ -5189,6 +5224,10 @@
5189
5224
  border-bottom-style: var(--tw-border-style);
5190
5225
  border-bottom-width: 0px;
5191
5226
  }
5227
+ [data-sandbox-theme=''] .\[\[data-sandbox-theme\=\'\'\]_\&\]\:invert {
5228
+ --tw-invert: invert(100%);
5229
+ filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
5230
+ }
5192
5231
  }
5193
5232
  :root,
5194
5233
  [data-sandbox-ui],
@@ -1,5 +1,5 @@
1
1
  import { t as cn$1 } from "./utils-DzWbktWG.js";
2
- import { o as PortsList } from "./dashboard-DJQFB7iZ.js";
2
+ import { o as PortsList } from "./dashboard-euyfLroA.js";
3
3
  import { n as TerminalView } from "./terminal-DmSUfGha.js";
4
4
  import { RichFileTree } from "./files.js";
5
5
  import { n as PreviewView } from "./embedded-app-view-CoiS_kfY.js";
@@ -7515,7 +7515,6 @@ const DIFF_OPTIONS = {
7515
7515
  dark: "github-dark",
7516
7516
  light: "github-light"
7517
7517
  },
7518
- themeType: "dark",
7519
7518
  stickyHeader: true
7520
7519
  };
7521
7520
  const DIFF_CONTAINER_TAG = "diffs-container";
@@ -7525,7 +7524,7 @@ const DIFF_CONTAINER_TAG = "diffs-container";
7525
7524
  * shadow content. Wrapping is a renderer option, not a CSS patch into its shadow
7526
7525
  * root; the plain patch disclosure is the accessible, engine-independent view.
7527
7526
  */
7528
- function DiffView({ filename, baseline, current, showFileHeader = true, defaultWrap = true, className }) {
7527
+ function DiffView({ filename, baseline, current, showFileHeader = true, defaultWrap = true, themeType = "dark", className }) {
7529
7528
  const patch = React$1.useMemo(() => buildUnifiedPatch(filename, baseline, current), [
7530
7529
  filename,
7531
7530
  baseline,
@@ -7534,6 +7533,12 @@ function DiffView({ filename, baseline, current, showFileHeader = true, defaultW
7534
7533
  const [wrap, setWrap] = React$1.useState(defaultWrap);
7535
7534
  const hintId = React$1.useId();
7536
7535
  const hostRef = React$1.useRef(null);
7536
+ const instanceRef = React$1.useRef(null);
7537
+ const latestThemeType = React$1.useRef(themeType);
7538
+ const appliedThemeType = React$1.useRef(themeType);
7539
+ React$1.useLayoutEffect(() => {
7540
+ latestThemeType.current = themeType;
7541
+ }, [themeType]);
7537
7542
  React$1.useLayoutEffect(() => {
7538
7543
  const host = hostRef.current;
7539
7544
  if (host == null || !patch) return;
@@ -7545,14 +7550,18 @@ function DiffView({ filename, baseline, current, showFileHeader = true, defaultW
7545
7550
  host.appendChild(container);
7546
7551
  const instance = new FileDiff({
7547
7552
  ...DIFF_OPTIONS,
7553
+ themeType: latestThemeType.current,
7548
7554
  overflow: wrap ? "wrap" : "scroll",
7549
7555
  disableFileHeader: !showFileHeader
7550
7556
  }, void 0, false);
7557
+ instanceRef.current = instance;
7558
+ appliedThemeType.current = latestThemeType.current;
7551
7559
  instance.hydrate({
7552
7560
  fileDiff: getSingularPatch(patch),
7553
7561
  fileContainer: container
7554
7562
  });
7555
7563
  return () => {
7564
+ if (instanceRef.current === instance) instanceRef.current = null;
7556
7565
  instance.cleanUp();
7557
7566
  container.remove();
7558
7567
  };
@@ -7561,6 +7570,11 @@ function DiffView({ filename, baseline, current, showFileHeader = true, defaultW
7561
7570
  showFileHeader,
7562
7571
  wrap
7563
7572
  ]);
7573
+ React$1.useLayoutEffect(() => {
7574
+ if (appliedThemeType.current === themeType) return;
7575
+ instanceRef.current?.setThemeType(themeType);
7576
+ appliedThemeType.current = themeType;
7577
+ }, [themeType]);
7564
7578
  if (!patch) return /* @__PURE__ */ jsx("div", {
7565
7579
  className: cn$1("flex h-full min-w-0 items-center justify-center bg-surface-container", className),
7566
7580
  children: /* @__PURE__ */ jsx("p", {
@@ -1,3 +1,3 @@
1
- import { A as SandboxArtifactTerminal, C as ChangesPane, D as ChangesPaneProps, E as ChangedFile, O as SandboxArtifact, S as PillTabsProps, T as ArtifactView, _ as DiffStats, a as PreviewView, b as PillTabItem, c as DiffViewProps, d as FileBreadcrumb, f as FileBreadcrumbProps, g as PanelHeaderProps, h as PanelHeader, i as resolveLanguage, k as SandboxArtifactPaneProps, l as CodeView, m as GitStatusBadge, n as CodeSurface, o as PreviewViewProps, p as DiffStatsBadge, r as CodeSurfaceProps, s as DiffView, t as BRAND_PRISM_THEME, u as CodeViewProps, v as buildUnifiedPatch, w as SandboxArtifactPane, x as PillTabs, y as computeDiffStats } from "./index-l96iy93N.js";
1
+ import { A as SandboxArtifactTerminal, C as ChangesPane, D as ChangesPaneProps, E as ChangedFile, O as SandboxArtifact, S as PillTabsProps, T as ArtifactView, _ as DiffStats, a as PreviewView, b as PillTabItem, c as DiffViewProps, d as FileBreadcrumb, f as FileBreadcrumbProps, g as PanelHeaderProps, h as PanelHeader, i as resolveLanguage, k as SandboxArtifactPaneProps, l as CodeView, m as GitStatusBadge, n as CodeSurface, o as PreviewViewProps, p as DiffStatsBadge, r as CodeSurfaceProps, s as DiffView, t as BRAND_PRISM_THEME, u as CodeViewProps, v as buildUnifiedPatch, w as SandboxArtifactPane, x as PillTabs, y as computeDiffStats } from "./index-z_zNuZHm.js";
2
2
  import { a as PreviewReadiness, i as PreviewAccess, n as EmbeddedAppView, r as EmbeddedAppViewProps, t as EmbeddedApp } from "./embedded-app-view-B_vMTtJn.js";
3
3
  export { type ArtifactView, BRAND_PRISM_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, resolveLanguage };
package/dist/workbench.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as computeDiffStats, c as BRAND_PRISM_THEME, d as DiffStatsBadge, f as GitStatusBadge, i as buildUnifiedPatch, l as CodeSurface, m as PillTabs, n as SandboxArtifactPane, o as CodeView, p as PanelHeader, r as DiffView, s as FileBreadcrumb, t as ChangesPane, u as resolveLanguage } from "./workbench-DVOVERx0.js";
1
+ import { a as computeDiffStats, c as BRAND_PRISM_THEME, d as DiffStatsBadge, f as GitStatusBadge, i as buildUnifiedPatch, l as CodeSurface, m as PillTabs, n as SandboxArtifactPane, o as CodeView, p as PanelHeader, r as DiffView, s as FileBreadcrumb, t as ChangesPane, u as resolveLanguage } from "./workbench-B1UltdHQ.js";
2
2
  import { n as PreviewView, t as EmbeddedAppView } from "./embedded-app-view-CoiS_kfY.js";
3
3
  export { BRAND_PRISM_THEME, ChangesPane, CodeSurface, CodeView, DiffStatsBadge, DiffView, EmbeddedAppView, FileBreadcrumb, GitStatusBadge, PanelHeader, PillTabs, PreviewView, SandboxArtifactPane, buildUnifiedPatch, computeDiffStats, resolveLanguage };
package/dist/workflows.js CHANGED
@@ -30,7 +30,7 @@ function retryImport(factory, retries = 2, delayMs = 350) {
30
30
  });
31
31
  }
32
32
  function lazyWorkflowGraph() {
33
- return lazy(() => retryImport(() => import("./WorkflowGraph-B-NsdYz_.js").then((m) => ({ default: m.WorkflowGraph }))));
33
+ return lazy(() => retryImport(() => import("./WorkflowGraph-CzWs8P7y.js").then((m) => ({ default: m.WorkflowGraph }))));
34
34
  }
35
35
  var GraphErrorBoundary = class extends Component {
36
36
  state = { hasError: false };
@@ -6,6 +6,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from "react";
7
7
  import { focusField, focusRing, focusRingInset } from "@tangle-network/ui/utils";
8
8
  import { Markdown } from "@tangle-network/ui/markdown";
9
+ import { createPortal } from "react-dom";
9
10
  import * as DialogPrimitive from "@radix-ui/react-dialog";
10
11
  import { Activity, AlertCircle, AlertTriangle, ArrowLeft, Binary, Bot, Boxes, CheckCircle, ChevronDown, ChevronRight, ChevronUp, FileCode2, FileText, FolderTree, LayoutPanelTop, Loader2, LoaderCircle, MessageSquareText, PanelBottomClose, PanelBottomOpen, PanelLeftClose, PanelLeftOpen, PanelRightClose, PanelRightOpen, Plus, RefreshCw, Search, Settings, Shield, ShieldCheck, Sparkles, Terminal, TerminalSquare, Upload, Wifi, X, XCircle, Zap } from "lucide-react";
11
12
  import { FileArtifactPane, FileTree, filterFileTree } from "@tangle-network/ui/files";
@@ -179,7 +180,7 @@ function MobileDrawer({ side, title, header, onClose, onReturnFocus, theme, dens
179
180
  })] })
180
181
  });
181
182
  }
182
- function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter, right, rightHeader, bottom, bottomHeader, defaultLeftOpen = true, defaultRightOpen = false, defaultBottomOpen = false, defaultLeftWidth = 280, defaultRightWidth = 480, defaultBottomHeight = 224, minLeftWidth = 220, maxLeftWidth = 420, minRightWidth = 320, maxRightWidth = 720, minCenterWidth = 400, minBottomHeight = 100, maxBottomHeight = 500, persistenceKey, resizable = true, theme, density = "comfortable", leftLabel = "Left workspace panel", rightLabel = "Right workspace panel", bottomLabel = "Bottom runtime panel", leftOpen: leftOpenProp, onLeftOpenChange, rightOpen: rightOpenProp, onRightOpenChange, keyboardShortcuts = false, leftCollapsedControl, leftContentClassName, rightContentClassName, centerHeaderVisibility = "auto", className }) {
183
+ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter, right, rightHeader, bottom, bottomHeader, defaultLeftOpen = true, defaultRightOpen = false, defaultBottomOpen = false, defaultLeftWidth = 280, defaultRightWidth = 480, defaultBottomHeight = 224, minLeftWidth = 220, maxLeftWidth = 420, minRightWidth = 320, maxRightWidth = 720, minCenterWidth = 400, minBottomHeight = 100, maxBottomHeight = 500, persistenceKey, resizable = true, theme, density = "comfortable", leftLabel = "Left workspace panel", rightLabel = "Right workspace panel", bottomLabel = "Bottom runtime panel", leftOpen: leftOpenProp, onLeftOpenChange, rightOpen: rightOpenProp, onRightOpenChange, keyboardShortcuts = false, leftCollapsedControl, leftContentClassName, rightContentClassName, keepRightMounted = false, collapsedControlsPlacement = "edge", centerHeaderVisibility = "auto", className }) {
183
184
  const desktop = useDesktopMediaQuery(DESKTOP_BREAKPOINT);
184
185
  const dragStateRef = useRef(null);
185
186
  const storedLayout = useMemo(() => persistenceKey ? readStoredLayout(persistenceKey) : null, [persistenceKey]);
@@ -199,6 +200,30 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
199
200
  }, [rightControlled, onRightOpenChange]);
200
201
  const hasLeft = Boolean(left);
201
202
  const hasRight = Boolean(right);
203
+ const [rightVisited, setRightVisited] = useState(false);
204
+ const rightParkingRef = useRef(null);
205
+ const rightHost = useMemo(() => {
206
+ if (!keepRightMounted || typeof document === "undefined") return null;
207
+ const host = document.createElement("div");
208
+ host.className = "flex h-full min-h-0 min-w-0 flex-col";
209
+ return host;
210
+ }, [keepRightMounted]);
211
+ useEffect(() => {
212
+ if (keepRightMounted && rightOpen && hasRight) setRightVisited(true);
213
+ }, [
214
+ keepRightMounted,
215
+ rightOpen,
216
+ hasRight
217
+ ]);
218
+ const mountRightHost = useCallback((node) => {
219
+ if (!rightHost) return;
220
+ const destination = node ?? rightParkingRef.current;
221
+ if (destination) destination.appendChild(rightHost);
222
+ }, [rightHost]);
223
+ const rightContent = keepRightMounted ? /* @__PURE__ */ jsx("div", {
224
+ ref: mountRightHost,
225
+ className: "flex h-full min-h-0 min-w-0 flex-1 flex-col"
226
+ }) : right;
202
227
  const [bottomOpen, setBottomOpen] = useState(storedLayout?.bottomOpen ?? defaultBottomOpen);
203
228
  const [leftWidth, setLeftWidth] = useState(clamp(storedLayout?.leftWidth ?? defaultLeftWidth, minLeftWidth, maxLeftWidth));
204
229
  const [rightWidth, setRightWidth] = useState(clamp(storedLayout?.rightWidth ?? defaultRightWidth, minRightWidth, maxRightWidth));
@@ -238,7 +263,9 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
238
263
  rightWidth,
239
264
  bottomHeight
240
265
  };
241
- window.localStorage.setItem(persistenceKey, JSON.stringify(payload));
266
+ try {
267
+ window.localStorage.setItem(persistenceKey, JSON.stringify(payload));
268
+ } catch {}
242
269
  }, [
243
270
  bottomHeight,
244
271
  bottomOpen,
@@ -428,7 +455,7 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
428
455
  onStep: stepLeftWidth
429
456
  })] }),
430
457
  /* @__PURE__ */ jsxs("main", {
431
- className: "flex min-w-0 flex-1 flex-col",
458
+ className: "relative flex min-w-0 flex-1 flex-col",
432
459
  children: [
433
460
  showCenterHeader && /* @__PURE__ */ jsxs(WorkspacePaneHeader, {
434
461
  className: "gap-2",
@@ -451,11 +478,11 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
451
478
  ]
452
479
  }),
453
480
  /* @__PURE__ */ jsxs("div", {
454
- className: "flex min-h-0 flex-1",
481
+ className: "relative flex min-h-0 flex-1",
455
482
  children: [
456
483
  !showCenterHeader && leftReopenControl && /* @__PURE__ */ jsx("div", {
457
484
  ref: leftReopenRef,
458
- className: "shrink-0 pt-2",
485
+ className: cn$1("shrink-0 pt-2", collapsedControlsPlacement === "overlay" && "absolute left-2 top-2 z-20 pt-0"),
459
486
  children: leftReopenControl
460
487
  }),
461
488
  /* @__PURE__ */ jsx("div", {
@@ -463,7 +490,7 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
463
490
  children: center
464
491
  }),
465
492
  !showCenterHeader && (bottomReopenControl || rightReopenControl) && /* @__PURE__ */ jsxs("div", {
466
- className: "flex shrink-0 flex-col gap-1 pt-2",
493
+ className: cn$1("flex shrink-0 flex-col gap-1 pt-2", collapsedControlsPlacement === "overlay" && "absolute right-2 top-2 z-20 pt-0"),
467
494
  children: [bottomReopenControl, rightReopenControl && /* @__PURE__ */ jsx("div", {
468
495
  ref: rightReopenRef,
469
496
  children: rightReopenControl
@@ -536,11 +563,17 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
536
563
  })]
537
564
  }), /* @__PURE__ */ jsx("div", {
538
565
  className: cn$1("min-h-0 flex-1 overflow-auto", rightContentClassName),
539
- children: right
566
+ children: rightContent
540
567
  })]
541
568
  })] })
542
569
  ]
543
570
  }),
571
+ keepRightMounted && /* @__PURE__ */ jsx("div", {
572
+ hidden: true,
573
+ ref: rightParkingRef,
574
+ "aria-hidden": "true",
575
+ children: rightHost && (rightOpen || rightVisited) && hasRight ? createPortal(right, rightHost) : null
576
+ }),
544
577
  !desktop && left && leftOpen && !(right && rightOpen) && /* @__PURE__ */ jsx(MobileDrawer, {
545
578
  side: "left",
546
579
  title: leftLabel,
@@ -559,7 +592,7 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
559
592
  onReturnFocus: () => focusSideControl("right"),
560
593
  theme,
561
594
  density,
562
- children: right
595
+ children: rightContent
563
596
  })
564
597
  ]
565
598
  });
@@ -1,2 +1,2 @@
1
- import { $ as TerminalProps, A as ShellShouldRevalidateArgs, B as SessionSidebarLink, C as SandboxWorkbenchLayoutOptions, D as SandboxWorkbenchSessionProps, E as SandboxWorkbenchProps, F as SessionSidebar, G as SessionOptimisticController, H as SessionSidebarVariant, I as SessionSidebarBadge, J as useOptimisticSessionItems, K as UseOptimisticSessionItemsOptions, L as SessionSidebarFilter, M as createShellShouldRevalidate, N as shellShouldRevalidate, O as SessionActivityMonitor, P as formatRelativeAge, Q as TerminalPanel, R as SessionSidebarGroupBy, S as SandboxWorkbenchFileArtifact, T as SandboxWorkbenchOpenUIArtifact, U as SESSION_CREATED_EVENT, V as SessionSidebarProps, W as SessionCreatedDetail, X as RuntimePaneProps, Y as RuntimePane, Z as TerminalLine, _ as FormAudit, a as ApprovalQueue, at as StatusBannerProps, b as SandboxWorkbenchArtifact, c as CalendarView, ct as WorkspacePaneHeader, d as TaskBoardColumn, dt as WorkspaceLayoutProps, et as ContextBadge, f as TaskBoardItem, g as AuditResultsProps, h as AuditResults, i as ApprovalItem, it as StatusBanner, j as ShellShouldRevalidateOptions, k as SessionActivityMonitorProps, l as CalendarViewProps, lt as WorkspacePaneHeaderProps, m as AuditCheck, n as ArtifactPaneProps, nt as StatusBarProps, o as ApprovalQueueProps, ot as DirectoryPane, p as TaskBoardProps, q as dispatchSessionCreated, r as ApprovalConfidenceStat, rt as BannerType, s as CalendarEvent, st as DirectoryPaneProps, t as ArtifactPane, tt as StatusBar, u as TaskBoard, ut as WorkspaceLayout, v as AgentWorkbench, w as SandboxWorkbenchMarkdownArtifact, x as SandboxWorkbenchCustomArtifact, y as SandboxWorkbench, z as SessionSidebarItem } from "./index-iDiLnSoo.js";
1
+ import { $ as TerminalProps, A as ShellShouldRevalidateArgs, B as SessionSidebarLink, C as SandboxWorkbenchLayoutOptions, D as SandboxWorkbenchSessionProps, E as SandboxWorkbenchProps, F as SessionSidebar, G as SessionOptimisticController, H as SessionSidebarVariant, I as SessionSidebarBadge, J as useOptimisticSessionItems, K as UseOptimisticSessionItemsOptions, L as SessionSidebarFilter, M as createShellShouldRevalidate, N as shellShouldRevalidate, O as SessionActivityMonitor, P as formatRelativeAge, Q as TerminalPanel, R as SessionSidebarGroupBy, S as SandboxWorkbenchFileArtifact, T as SandboxWorkbenchOpenUIArtifact, U as SESSION_CREATED_EVENT, V as SessionSidebarProps, W as SessionCreatedDetail, X as RuntimePaneProps, Y as RuntimePane, Z as TerminalLine, _ as FormAudit, a as ApprovalQueue, at as StatusBannerProps, b as SandboxWorkbenchArtifact, c as CalendarView, ct as WorkspacePaneHeader, d as TaskBoardColumn, dt as WorkspaceLayoutProps, et as ContextBadge, f as TaskBoardItem, g as AuditResultsProps, h as AuditResults, i as ApprovalItem, it as StatusBanner, j as ShellShouldRevalidateOptions, k as SessionActivityMonitorProps, l as CalendarViewProps, lt as WorkspacePaneHeaderProps, m as AuditCheck, n as ArtifactPaneProps, nt as StatusBarProps, o as ApprovalQueueProps, ot as DirectoryPane, p as TaskBoardProps, q as dispatchSessionCreated, r as ApprovalConfidenceStat, rt as BannerType, s as CalendarEvent, st as DirectoryPaneProps, t as ArtifactPane, tt as StatusBar, u as TaskBoard, ut as WorkspaceLayout, v as AgentWorkbench, w as SandboxWorkbenchMarkdownArtifact, x as SandboxWorkbenchCustomArtifact, y as SandboxWorkbench, z as SessionSidebarItem } from "./index-CcbhfDa-.js";
2
2
  export { AgentWorkbench, type ApprovalConfidenceStat, type ApprovalItem, ApprovalQueue, type ApprovalQueueProps, ArtifactPane, type ArtifactPaneProps, type AuditCheck, AuditResults, type AuditResultsProps, type BannerType, type CalendarEvent, CalendarView, type CalendarViewProps, type ContextBadge, DirectoryPane, type DirectoryPaneProps, type FormAudit, RuntimePane, type RuntimePaneProps, SESSION_CREATED_EVENT, SandboxWorkbench, type SandboxWorkbenchArtifact, type SandboxWorkbenchCustomArtifact, type SandboxWorkbenchFileArtifact, type SandboxWorkbenchLayoutOptions, type SandboxWorkbenchMarkdownArtifact, type SandboxWorkbenchOpenUIArtifact, type SandboxWorkbenchProps, type SandboxWorkbenchSessionProps, SessionActivityMonitor, type SessionActivityMonitorProps, type SessionCreatedDetail, type SessionOptimisticController, SessionSidebar, type SessionSidebarBadge, type SessionSidebarFilter, type SessionSidebarGroupBy, type SessionSidebarItem, type SessionSidebarLink, type SessionSidebarProps, type SessionSidebarVariant, type ShellShouldRevalidateArgs, type ShellShouldRevalidateOptions, StatusBanner, type StatusBannerProps, StatusBar, type StatusBarProps, TaskBoard, type TaskBoardColumn, type TaskBoardItem, type TaskBoardProps, type TerminalLine, TerminalPanel, type TerminalProps, type UseOptimisticSessionItemsOptions, WorkspaceLayout, type WorkspaceLayoutProps, WorkspacePaneHeader, type WorkspacePaneHeaderProps, createShellShouldRevalidate, dispatchSessionCreated, formatRelativeAge, shellShouldRevalidate, useOptimisticSessionItems };
package/dist/workspace.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { t as WorkspacePaneHeader } from "./workspace-pane-header-Bg1cCcHX.js";
2
- import { _ as TerminalPanel, a as AuditResults, b as DirectoryPane, c as SessionActivityMonitor, d as SessionSidebar, f as SESSION_CREATED_EVENT, g as RuntimePane, h as formatRelativeAge, i as TaskBoard, l as createShellShouldRevalidate, m as useOptimisticSessionItems, n as ApprovalQueue, o as AgentWorkbench, p as dispatchSessionCreated, r as CalendarView, s as SandboxWorkbench, t as ArtifactPane, u as shellShouldRevalidate, v as StatusBar, x as WorkspaceLayout, y as StatusBanner } from "./workspace-Pq-koOTW.js";
2
+ import { _ as TerminalPanel, a as AuditResults, b as DirectoryPane, c as SessionActivityMonitor, d as SessionSidebar, f as SESSION_CREATED_EVENT, g as RuntimePane, h as formatRelativeAge, i as TaskBoard, l as createShellShouldRevalidate, m as useOptimisticSessionItems, n as ApprovalQueue, o as AgentWorkbench, p as dispatchSessionCreated, r as CalendarView, s as SandboxWorkbench, t as ArtifactPane, u as shellShouldRevalidate, v as StatusBar, x as WorkspaceLayout, y as StatusBanner } from "./workspace-fIHRXmWT.js";
3
3
  export { AgentWorkbench, ApprovalQueue, ArtifactPane, AuditResults, CalendarView, DirectoryPane, RuntimePane, SESSION_CREATED_EVENT, SandboxWorkbench, SessionActivityMonitor, SessionSidebar, StatusBanner, StatusBar, TaskBoard, TerminalPanel, WorkspaceLayout, WorkspacePaneHeader, 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.116.8",
3
+ "version": "0.117.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",
@@ -78,6 +78,10 @@
78
78
  "import": "./dist/integrations.js",
79
79
  "types": "./dist/integrations.d.ts"
80
80
  },
81
+ "./connections": {
82
+ "import": "./dist/connections.js",
83
+ "types": "./dist/connections.d.ts"
84
+ },
81
85
  "./connectors": {
82
86
  "import": "./dist/connectors.js",
83
87
  "types": "./dist/connectors.d.ts"
@@ -2,9 +2,9 @@ import { t as cn$1 } from "./utils-DzWbktWG.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React$1 from "react";
4
4
  import { focusField, focusRing } from "@tangle-network/ui/utils";
5
+ import { createPortal } from "react-dom";
5
6
  import { Bot, Brain, Check, ChevronDown, Lock, Pencil, Plus, Send, Sparkles, Square, Trash2, X } from "lucide-react";
6
7
  import { AgentTimeline, ChatContainer as ChatContainer$1, ChatMessage, ChatMessage as ChatMessage$1, MessageList, ThinkingIndicator, UserMessage } from "@tangle-network/ui/chat";
7
- import { createPortal } from "react-dom";
8
8
  import { modelProvider, reasoningLadder, snapHarnessToModel } from "@tangle-network/agent-interface";
9
9
  import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
10
10
  //#region src/chat/reasoning-level-picker.tsx