@tangle-network/sandbox-ui 0.113.4 → 0.113.6

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 CHANGED
@@ -10,13 +10,15 @@
10
10
 
11
11
  React component library for [Tangle Sandbox](https://sandbox.tangle.tools) — a shadcn-style primitive layer plus higher-order sandbox surfaces for agent chat, files, runtime state, artifacts, and dashboard views.
12
12
 
13
+ [Browse the live Storybook](https://sandbox-ui-storybook.pages.dev/) to inspect component states in dark and light themes at desktop and mobile widths.
14
+
13
15
  ## Install
14
16
 
15
17
  ```bash
16
18
  npm install @tangle-network/sandbox-ui
17
19
  ```
18
20
 
19
- **Required peers:** `react` and `react-dom` 18 or 19, `@tangle-network/agent-interface ^1.0.0 || ^2.0.0`, `@tangle-network/brand ^1.5.0`, and `@tangle-network/ui ^11.6.0`.
21
+ **Required peers:** `react` and `react-dom` 18 or 19, `@tangle-network/agent-interface ^1.0.0 || ^2.0.0`, `@tangle-network/brand ^1.6.0`, and `@tangle-network/ui ^11.10.0`.
20
22
  Optional peers are required only by the subpaths that use them; see [package.json](./package.json). `/editor` needs its tiptap, `yjs` and `@hocuspocus/provider` peers only when it renders an editor, and the `@tangle-network/ui` README holds the table of which surface needs which.
21
23
 
22
24
  ## Usage
package/dist/chat.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  createFetchTransport,
14
14
  modelProvider,
15
15
  snapHarnessToModel
16
- } from "./chunk-EKYA6AFY.js";
16
+ } from "./chunk-TADGS4Q7.js";
17
17
  import "./chunk-EI44GEQ5.js";
18
18
  import "./chunk-CZ7CSFO4.js";
19
19
  export {
@@ -36,6 +36,7 @@ function WorkspacePaneHeader({
36
36
  }
37
37
 
38
38
  // src/workspace/workspace-layout.tsx
39
+ import { focusRing } from "@tangle-network/ui/utils";
39
40
  import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
40
41
  var DESKTOP_BREAKPOINT = "(min-width: 1024px)";
41
42
  function clamp(value, min, max) {
@@ -104,7 +105,7 @@ function ResizeHandle({ label, onDragStart, onStep, className }) {
104
105
  className: cn(
105
106
  "relative hidden w-3 shrink-0 cursor-col-resize lg:flex",
106
107
  "items-stretch justify-center bg-transparent touch-none",
107
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60",
108
+ focusRing,
108
109
  className
109
110
  ),
110
111
  children: [
@@ -141,7 +142,7 @@ function HorizontalResizeHandle({ label, onDragStart, onStep, className }) {
141
142
  className: cn(
142
143
  "relative hidden h-3 shrink-0 cursor-row-resize lg:flex",
143
144
  "items-center justify-center bg-transparent touch-none w-full",
144
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60",
145
+ focusRing,
145
146
  className
146
147
  ),
147
148
  children: [
@@ -178,7 +179,7 @@ function MobileDrawer({ side, title, header, onClose, children }) {
178
179
  type: "button",
179
180
  "aria-label": `Close ${title}`,
180
181
  onClick: onClose,
181
- className: "rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
182
+ className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
182
183
  children: /* @__PURE__ */ jsx2(X, { className: "h-4 w-4" })
183
184
  }
184
185
  )
@@ -410,7 +411,7 @@ function WorkspaceLayout({
410
411
  type: "button",
411
412
  "aria-label": "Collapse left panel",
412
413
  onClick: () => setLeftOpen(false),
413
- className: "rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
414
+ className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
414
415
  children: /* @__PURE__ */ jsx2(PanelLeftClose, { className: "h-4 w-4" })
415
416
  }
416
417
  )
@@ -436,7 +437,7 @@ function WorkspaceLayout({
436
437
  type: "button",
437
438
  "aria-label": "Open left panel",
438
439
  onClick: () => setLeftOpen(true),
439
- className: "rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
440
+ className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
440
441
  children: /* @__PURE__ */ jsx2(PanelLeftOpen, { className: "h-4 w-4" })
441
442
  }
442
443
  )),
@@ -447,7 +448,7 @@ function WorkspaceLayout({
447
448
  type: "button",
448
449
  "aria-label": "Open bottom panel",
449
450
  onClick: () => setBottomOpen(true),
450
- className: "rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
451
+ className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
451
452
  children: /* @__PURE__ */ jsx2(PanelBottomOpen, { className: "h-4 w-4" })
452
453
  }
453
454
  ),
@@ -457,7 +458,7 @@ function WorkspaceLayout({
457
458
  type: "button",
458
459
  "aria-label": "Open right panel",
459
460
  onClick: () => setRightOpen(true),
460
- className: "rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
461
+ className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
461
462
  children: /* @__PURE__ */ jsx2(PanelRightOpen, { className: "h-4 w-4" })
462
463
  }
463
464
  )
@@ -487,7 +488,7 @@ function WorkspaceLayout({
487
488
  type: "button",
488
489
  "aria-label": "Collapse bottom panel",
489
490
  onClick: () => setBottomOpen(false),
490
- className: "rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
491
+ className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
491
492
  children: /* @__PURE__ */ jsx2(PanelBottomClose, { className: "h-4 w-4" })
492
493
  }
493
494
  )
@@ -523,7 +524,7 @@ function WorkspaceLayout({
523
524
  type: "button",
524
525
  "aria-label": "Collapse right panel",
525
526
  onClick: () => setRightOpen(false),
526
- className: "rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
527
+ className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
527
528
  children: /* @__PURE__ */ jsx2(PanelRightClose, { className: "h-4 w-4" })
528
529
  }
529
530
  )
@@ -572,6 +573,7 @@ import {
572
573
  } from "@tangle-network/ui/files";
573
574
  import { EmptyState } from "@tangle-network/ui/primitives";
574
575
  import { Input } from "@tangle-network/ui/primitives";
576
+ import { focusRing as focusRing2 } from "@tangle-network/ui/utils";
575
577
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
576
578
  function countNodes(node) {
577
579
  if (node.type === "file") {
@@ -647,7 +649,7 @@ function DirectoryPane({
647
649
  type: "button",
648
650
  "aria-label": "Refresh directory",
649
651
  onClick: onRefresh,
650
- className: "rounded-[2px] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
652
+ className: `rounded-[2px] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing2}`,
651
653
  children: /* @__PURE__ */ jsx3(RefreshCw, { className: "h-4 w-4" })
652
654
  }
653
655
  ),
@@ -657,7 +659,7 @@ function DirectoryPane({
657
659
  type: "button",
658
660
  "aria-label": "Upload files",
659
661
  onClick: onUpload,
660
- className: "rounded-[2px] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
662
+ className: `rounded-[2px] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing2}`,
661
663
  children: /* @__PURE__ */ jsx3(Upload, { className: "h-4 w-4" })
662
664
  }
663
665
  )
@@ -819,8 +821,9 @@ function StatusBar({
819
821
  }
820
822
 
821
823
  // src/workspace/terminal-panel.tsx
822
- import { useRef as useRef2, useEffect as useEffect2 } from "react";
824
+ import { useRef as useRef2, useEffect as useEffect2, useId } from "react";
823
825
  import { Terminal as TerminalIcon, ChevronDown, ChevronUp, X as X3 } from "lucide-react";
826
+ import { focusRing as focusRing3 } from "@tangle-network/ui/utils";
824
827
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
825
828
  var LINE_COLORS = {
826
829
  command: "text-[var(--code-function)]",
@@ -844,33 +847,48 @@ function TerminalPanel({
844
847
  className
845
848
  }) {
846
849
  const scrollRef = useRef2(null);
850
+ const contentId = useId();
847
851
  useEffect2(() => {
848
852
  if (!isCollapsed && scrollRef.current) {
849
853
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
850
854
  }
851
855
  }, [lines, isCollapsed]);
852
856
  return /* @__PURE__ */ jsxs5("div", { className: cn("border-t border-[var(--md3-outline-variant)] bg-surface-container", className), children: [
857
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center px-1", children: [
858
+ /* @__PURE__ */ jsxs5(
859
+ "button",
860
+ {
861
+ type: "button",
862
+ onClick: onToggle,
863
+ disabled: !onToggle,
864
+ "aria-expanded": !isCollapsed,
865
+ "aria-controls": contentId,
866
+ className: `flex min-w-0 flex-1 items-center gap-2 rounded px-2 py-1.5 text-left text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-default ${focusRing3}`,
867
+ children: [
868
+ /* @__PURE__ */ jsx6(TerminalIcon, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
869
+ /* @__PURE__ */ jsx6("span", { className: "font-medium", children: title }),
870
+ lines.length > 0 && /* @__PURE__ */ jsx6("span", { className: "rounded-full bg-surface-container-high px-1.5 py-0.5 text-[10px] tabular-nums", children: lines.length }),
871
+ /* @__PURE__ */ jsx6("span", { className: "flex-1" }),
872
+ isCollapsed ? /* @__PURE__ */ jsx6(ChevronUp, { className: "h-3 w-3", "aria-hidden": "true" }) : /* @__PURE__ */ jsx6(ChevronDown, { className: "h-3 w-3", "aria-hidden": "true" })
873
+ ]
874
+ }
875
+ ),
876
+ onClose && /* @__PURE__ */ jsx6(
877
+ "button",
878
+ {
879
+ type: "button",
880
+ "aria-label": `Close ${title}`,
881
+ onClick: onClose,
882
+ className: `rounded p-1.5 text-muted-foreground transition-colors hover:text-foreground ${focusRing3}`,
883
+ children: /* @__PURE__ */ jsx6(X3, { className: "h-3 w-3", "aria-hidden": "true" })
884
+ }
885
+ )
886
+ ] }),
853
887
  /* @__PURE__ */ jsxs5(
854
- "button",
855
- {
856
- onClick: onToggle,
857
- className: "flex items-center gap-2 w-full px-3 py-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors",
858
- children: [
859
- /* @__PURE__ */ jsx6(TerminalIcon, { className: "h-3.5 w-3.5" }),
860
- /* @__PURE__ */ jsx6("span", { className: "font-medium", children: title }),
861
- lines.length > 0 && /* @__PURE__ */ jsx6("span", { className: "px-1.5 py-0.5 rounded-full bg-surface-container-high text-[10px] tabular-nums", children: lines.length }),
862
- /* @__PURE__ */ jsx6("div", { className: "flex-1" }),
863
- onClose && /* @__PURE__ */ jsx6(X3, { className: "h-3 w-3 hover:text-foreground", onClick: (e) => {
864
- e.stopPropagation();
865
- onClose();
866
- } }),
867
- isCollapsed ? /* @__PURE__ */ jsx6(ChevronUp, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx6(ChevronDown, { className: "h-3 w-3" })
868
- ]
869
- }
870
- ),
871
- !isCollapsed && /* @__PURE__ */ jsxs5(
872
888
  "div",
873
889
  {
890
+ id: contentId,
891
+ hidden: isCollapsed,
874
892
  ref: scrollRef,
875
893
  className: "overflow-auto px-3 pb-2 font-mono text-xs leading-[1.6] bg-surface-container-lowest",
876
894
  style: { maxHeight },
@@ -1019,6 +1037,7 @@ function useOptimisticSessionItems(items, options = {}) {
1019
1037
  }
1020
1038
 
1021
1039
  // src/workspace/session-sidebar.tsx
1040
+ import { focusField, focusRing as focusRing4 } from "@tangle-network/ui/utils";
1022
1041
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1023
1042
  var NO_CONTROLLER = {
1024
1043
  add: () => {
@@ -1405,7 +1424,7 @@ function SessionSidebar({
1405
1424
  placeholder: searchPlaceholder,
1406
1425
  "aria-label": searchPlaceholder,
1407
1426
  className: cn(
1408
- quiet ? "h-8 w-full rounded-md border-0 bg-transparent pl-7 pr-2 text-sm text-foreground placeholder:text-muted-foreground transition-colors focus-visible:bg-surface-container focus-visible:outline-none" : "h-8 w-full rounded-[var(--radius-sm)] border border-[var(--md3-outline-variant)] bg-surface-container-lowest pl-7 pr-2 text-sm text-foreground placeholder:text-muted-foreground transition-colors focus-visible:border-[var(--border-accent)] focus-visible:bg-transparent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--border-accent)]",
1427
+ quiet ? `h-8 w-full rounded-md border-0 bg-transparent pl-7 pr-2 text-sm text-foreground placeholder:text-muted-foreground transition-colors focus-visible:bg-surface-container ${focusRing4}` : `h-8 w-full rounded-[var(--radius-sm)] border bg-surface-container-lowest pl-7 pr-2 text-sm text-foreground placeholder:text-muted-foreground ${focusField}`,
1409
1428
  MOTION_CONTROL
1410
1429
  )
1411
1430
  }
@@ -1604,7 +1623,7 @@ function SessionActivityMonitor({
1604
1623
  }
1605
1624
 
1606
1625
  // src/workspace/sandbox-workbench.tsx
1607
- import { useEffect as useEffect4, useMemo as useMemo4, useState as useState5 } from "react";
1626
+ import { useEffect as useEffect4, useId as useId2, useMemo as useMemo4, useRef as useRef5, useState as useState5 } from "react";
1608
1627
  import {
1609
1628
  Bot,
1610
1629
  Boxes,
@@ -1621,6 +1640,7 @@ import { ChatContainer } from "@tangle-network/ui/chat";
1621
1640
  import { FileArtifactPane } from "@tangle-network/ui/files";
1622
1641
  import { OpenUIArtifactRenderer } from "@tangle-network/ui/openui";
1623
1642
  import { ArtifactPane as ArtifactPane2 } from "@tangle-network/ui/primitives";
1643
+ import { focusRing as focusRing5, focusRingInset } from "@tangle-network/ui/utils";
1624
1644
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1625
1645
  function getArtifactTabIcon(kind) {
1626
1646
  switch (kind) {
@@ -1650,10 +1670,13 @@ function ArtifactTabs({
1650
1670
  artifacts,
1651
1671
  activeArtifactId,
1652
1672
  onSelect,
1653
- onClose
1673
+ onClose,
1674
+ tabIdPrefix,
1675
+ panelId
1654
1676
  }) {
1677
+ const tabRefs = useRef5(/* @__PURE__ */ new Map());
1655
1678
  if (artifacts.length === 0) return null;
1656
- return /* @__PURE__ */ jsx10("div", { className: "flex items-center overflow-x-auto border-b border-[var(--md3-outline-variant)] bg-surface-container-high", children: artifacts.map((artifact) => {
1679
+ return /* @__PURE__ */ jsx10("div", { role: "tablist", "aria-label": "Artifacts", className: "flex items-center overflow-x-auto border-b border-[var(--md3-outline-variant)] bg-surface-container-high", children: artifacts.map((artifact) => {
1657
1680
  const Icon = artifact.icon ?? getArtifactTabIcon(artifact.kind);
1658
1681
  const isActive = artifact.id === activeArtifactId;
1659
1682
  return /* @__PURE__ */ jsxs9(
@@ -1668,8 +1691,41 @@ function ArtifactTabs({
1668
1691
  "button",
1669
1692
  {
1670
1693
  type: "button",
1694
+ ref: (element) => {
1695
+ if (element) tabRefs.current.set(artifact.id, element);
1696
+ else tabRefs.current.delete(artifact.id);
1697
+ },
1698
+ id: `${tabIdPrefix}-${artifact.id}`,
1699
+ role: "tab",
1700
+ "aria-controls": panelId,
1701
+ "aria-selected": isActive,
1702
+ tabIndex: isActive ? 0 : -1,
1671
1703
  onClick: () => onSelect(artifact.id),
1672
- className: "flex min-w-0 items-center gap-2 px-3 py-2 text-[12px] uppercase tracking-wider font-medium transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary/60",
1704
+ onKeyDown: (event) => {
1705
+ const index = artifacts.findIndex((entry) => entry.id === artifact.id);
1706
+ let nextIndex;
1707
+ switch (event.key) {
1708
+ case "ArrowRight":
1709
+ nextIndex = (index + 1) % artifacts.length;
1710
+ break;
1711
+ case "ArrowLeft":
1712
+ nextIndex = (index - 1 + artifacts.length) % artifacts.length;
1713
+ break;
1714
+ case "Home":
1715
+ nextIndex = 0;
1716
+ break;
1717
+ case "End":
1718
+ nextIndex = artifacts.length - 1;
1719
+ break;
1720
+ default:
1721
+ return;
1722
+ }
1723
+ event.preventDefault();
1724
+ const next = artifacts[nextIndex];
1725
+ onSelect(next.id);
1726
+ tabRefs.current.get(next.id)?.focus();
1727
+ },
1728
+ className: `flex min-w-0 items-center gap-2 px-3 py-2 text-[12px] uppercase tracking-wider font-medium transition-colors hover:text-foreground ${focusRingInset}`,
1673
1729
  children: [
1674
1730
  /* @__PURE__ */ jsx10(Icon, { className: "h-3.5 w-3.5 shrink-0" }),
1675
1731
  /* @__PURE__ */ jsx10("span", { className: "max-w-[14rem] truncate", children: artifactTabLabel(artifact) })
@@ -1681,8 +1737,9 @@ function ArtifactTabs({
1681
1737
  {
1682
1738
  type: "button",
1683
1739
  "aria-label": `Close ${artifactTabLabel(artifact)}`,
1740
+ tabIndex: isActive ? 0 : -1,
1684
1741
  onClick: () => onClose(artifact.id),
1685
- className: "mr-1 rounded-[2px] p-1 opacity-0 transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60 group-hover:opacity-100",
1742
+ className: `mr-1 rounded-[2px] p-1 opacity-0 transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100 ${focusRing5}`,
1686
1743
  children: /* @__PURE__ */ jsx10(X4, { className: "h-3 w-3" })
1687
1744
  }
1688
1745
  )
@@ -1818,6 +1875,8 @@ function SandboxWorkbench({
1818
1875
  className
1819
1876
  }) {
1820
1877
  const artifacts = useMemo4(() => sortPinnedFirst(artifactsProp), [artifactsProp]);
1878
+ const artifactTabsId = useId2();
1879
+ const artifactPanelId = `${artifactTabsId}-panel`;
1821
1880
  const [uncontrolledArtifactId, setUncontrolledArtifactId] = useState5(
1822
1881
  activeArtifactId ?? artifacts[0]?.id
1823
1882
  );
@@ -1889,17 +1948,30 @@ function SandboxWorkbench({
1889
1948
  artifacts,
1890
1949
  activeArtifactId: resolvedArtifactId,
1891
1950
  onSelect: handleArtifactChange,
1892
- onClose: onArtifactClose
1951
+ onClose: onArtifactClose,
1952
+ tabIdPrefix: artifactTabsId,
1953
+ panelId: artifactPanelId
1893
1954
  }
1894
1955
  ),
1895
- /* @__PURE__ */ jsx10("div", { className: "min-h-0 flex-1 overflow-auto bg-surface-container", children: activeArtifact ? renderArtifact(activeArtifact) : /* @__PURE__ */ jsx10("div", { className: "flex h-full items-center justify-center p-6", children: emptyArtifactState ?? /* @__PURE__ */ jsx10(
1896
- EmptyState2,
1956
+ /* @__PURE__ */ jsx10(
1957
+ "div",
1897
1958
  {
1898
- icon: /* @__PURE__ */ jsx10(Boxes, { className: "h-8 w-8" }),
1899
- title: "No artifact selected",
1900
- description: "Select a generated artifact, file preview, or OpenUI panel to inspect it here."
1959
+ id: artifactPanelId,
1960
+ role: "tabpanel",
1961
+ "aria-labelledby": activeArtifact ? `${artifactTabsId}-${activeArtifact.id}` : void 0,
1962
+ "aria-label": activeArtifact ? void 0 : "Artifact content",
1963
+ tabIndex: 0,
1964
+ className: `min-h-0 flex-1 overflow-auto bg-surface-container ${focusRingInset}`,
1965
+ children: activeArtifact ? renderArtifact(activeArtifact) : /* @__PURE__ */ jsx10("div", { className: "flex h-full items-center justify-center p-6", children: emptyArtifactState ?? /* @__PURE__ */ jsx10(
1966
+ EmptyState2,
1967
+ {
1968
+ icon: /* @__PURE__ */ jsx10(Boxes, { className: "h-8 w-8" }),
1969
+ title: "No artifact selected",
1970
+ description: "Select a generated artifact, file preview, or OpenUI panel to inspect it here."
1971
+ }
1972
+ ) })
1901
1973
  }
1902
- ) }) })
1974
+ )
1903
1975
  ] }) : null;
1904
1976
  const directoryPlacement = layout?.directoryPlacement ?? (directory ? "left" : "hidden");
1905
1977
  const artifactPlacement = layout?.artifactPlacement ?? (artifactPanel ? "right" : "hidden");
@@ -2380,6 +2452,7 @@ function CalendarView({
2380
2452
 
2381
2453
  // src/workspace/approval-queue.tsx
2382
2454
  import { useState as useState8, useMemo as useMemo7 } from "react";
2455
+ import { focusField as focusField2 } from "@tangle-network/ui/utils";
2383
2456
  import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
2384
2457
  function ApprovalQueue({
2385
2458
  items,
@@ -2498,7 +2571,7 @@ function ApprovalQueue({
2498
2571
  placeholder: "Why are you rejecting this?",
2499
2572
  value: rejectReason,
2500
2573
  onChange: (e) => setRejectReason(e.target.value),
2501
- className: "w-full rounded-md border border-[var(--md3-outline-variant)] bg-surface-container-low px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary/40 mb-2",
2574
+ className: `w-full rounded-md border bg-surface-container-low px-3 py-2 text-sm placeholder:text-muted-foreground mb-2 ${focusField2}`,
2502
2575
  rows: 2
2503
2576
  }
2504
2577
  ),