@ctrl-ui/react 0.9.5 → 0.9.8

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.
Files changed (165) hide show
  1. package/README.md +38 -2
  2. package/dist/action-bar.js +16 -8
  3. package/dist/activity.d.ts +4 -2
  4. package/dist/activity.js +5 -2
  5. package/dist/audio-visualizer.js +1 -1
  6. package/dist/blocks/agent-run-clock.d.ts +5 -0
  7. package/dist/blocks/agent-run-clock.js +52 -0
  8. package/dist/blocks/agent-run-sidebar.d.ts +13 -0
  9. package/dist/blocks/agent-run-sidebar.js +101 -0
  10. package/dist/blocks/agent-run-status.d.ts +32 -0
  11. package/dist/blocks/agent-run-status.js +27 -0
  12. package/dist/blocks/agent-run.d.ts +82 -0
  13. package/dist/blocks/agent-run.js +262 -0
  14. package/dist/blocks/coding-agent.d.ts +1 -1
  15. package/dist/blocks/coding-agent.js +50 -69
  16. package/dist/blocks/design-canvas-data.d.ts +1 -1
  17. package/dist/blocks/design-canvas-inspector.js +1 -1
  18. package/dist/blocks/design-canvas.d.ts +2 -1
  19. package/dist/blocks/design-canvas.js +56 -42
  20. package/dist/blocks/discussion.js +1 -1
  21. package/dist/blocks/file-explorer.js +66 -47
  22. package/dist/blocks/settings.js +37 -41
  23. package/dist/blocks/team-chat.js +2 -1
  24. package/dist/blocks/theme-toggle.d.ts +2 -1
  25. package/dist/blocks/theme-toggle.js +13 -4
  26. package/dist/chat-message.js +33 -39
  27. package/dist/hooks/use-mobile.d.ts +1 -1
  28. package/dist/hooks/use-mobile.js +1 -1
  29. package/dist/knob-contracts/badge-knobs.d.ts +1 -1
  30. package/dist/knob-contracts/badge-knobs.js +3 -1
  31. package/dist/knob-contracts/button-knobs.d.ts +1 -1
  32. package/dist/knob-contracts/button-knobs.js +1 -0
  33. package/dist/knob-contracts/calendar-knobs.d.ts +1 -1
  34. package/dist/knob-contracts/calendar-knobs.js +9 -1
  35. package/dist/knob-contracts/card-knobs.d.ts +1 -1
  36. package/dist/knob-contracts/card-knobs.js +5 -1
  37. package/dist/knob-contracts/choice-knobs.d.ts +1 -1
  38. package/dist/knob-contracts/choice-knobs.js +1 -0
  39. package/dist/knob-contracts/collapsible-knobs.d.ts +1 -1
  40. package/dist/knob-contracts/collapsible-knobs.js +5 -1
  41. package/dist/knob-contracts/emoji-picker-knobs.d.ts +1 -1
  42. package/dist/knob-contracts/emoji-picker-knobs.js +3 -1
  43. package/dist/knob-contracts/field-knobs.d.ts +1 -1
  44. package/dist/knob-contracts/field-knobs.js +17 -1
  45. package/dist/knob-contracts/infinite-canvas-knobs.d.ts +1 -1
  46. package/dist/knob-contracts/infinite-canvas-knobs.js +1 -7
  47. package/dist/knob-contracts/item-knobs.d.ts +1 -1
  48. package/dist/knob-contracts/item-knobs.js +5 -1
  49. package/dist/knob-contracts/kbd-knobs.d.ts +1 -1
  50. package/dist/knob-contracts/kbd-knobs.js +4 -1
  51. package/dist/knob-contracts/page-layout-knobs.d.ts +1 -1
  52. package/dist/knob-contracts/page-layout-knobs.js +1 -0
  53. package/dist/knob-contracts/pagination-knobs.d.ts +1 -1
  54. package/dist/knob-contracts/pagination-knobs.js +2 -1
  55. package/dist/knob-contracts/popup-knobs.d.ts +1 -1
  56. package/dist/knob-contracts/popup-knobs.js +9 -0
  57. package/dist/knob-contracts/range-knobs.d.ts +1 -1
  58. package/dist/knob-contracts/range-knobs.js +2 -0
  59. package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
  60. package/dist/knob-contracts/sidebar-knobs.js +2 -0
  61. package/dist/knob-contracts/swap-knobs.d.ts +4 -0
  62. package/dist/knob-contracts/swap-knobs.js +9 -0
  63. package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
  64. package/dist/knob-contracts/tabs-knobs.js +3 -0
  65. package/dist/knob-contracts/timeline-knobs.d.ts +1 -1
  66. package/dist/knob-contracts/timeline-knobs.js +5 -1
  67. package/dist/knob-contracts/tool-approval-knobs.d.ts +4 -0
  68. package/dist/knob-contracts/tool-approval-knobs.js +32 -0
  69. package/dist/knob-contracts/tree-knobs.d.ts +1 -1
  70. package/dist/knob-contracts/tree-knobs.js +3 -1
  71. package/dist/lib/infinite-canvas-camera-store.d.ts +65 -0
  72. package/dist/lib/infinite-canvas-camera-store.js +233 -0
  73. package/dist/lib/infinite-canvas-camera.d.ts +33 -0
  74. package/dist/lib/infinite-canvas-camera.js +98 -0
  75. package/dist/lib/infinite-canvas-navigation.d.ts +19 -0
  76. package/dist/lib/infinite-canvas-navigation.js +395 -0
  77. package/dist/markdown-editor/bubble-menu.d.ts +6 -0
  78. package/dist/markdown-editor/bubble-menu.js +45 -0
  79. package/dist/markdown-editor/toolbar.d.ts +17 -1
  80. package/dist/markdown-editor/toolbar.js +103 -81
  81. package/dist/skin.d.ts +2 -0
  82. package/dist/styles/index.css +11 -10
  83. package/dist/styles/recipes/activity.css +12 -0
  84. package/dist/styles/recipes/avatar.css +1 -1
  85. package/dist/styles/recipes/badge.css +17 -0
  86. package/dist/styles/recipes/button-group.css +12 -6
  87. package/dist/styles/recipes/button.css +20 -3
  88. package/dist/styles/recipes/calendar.css +82 -6
  89. package/dist/styles/recipes/card.css +40 -5
  90. package/dist/styles/recipes/chat-message-edit.css +6 -21
  91. package/dist/styles/recipes/choice.css +9 -2
  92. package/dist/styles/recipes/collapsible.css +8 -1
  93. package/dist/styles/recipes/color-picker-values.css +4 -0
  94. package/dist/styles/recipes/emoji-picker.css +29 -8
  95. package/dist/styles/recipes/field-parts.css +80 -5
  96. package/dist/styles/recipes/field.css +113 -40
  97. package/dist/styles/recipes/infinite-canvas.css +17 -57
  98. package/dist/styles/recipes/item.css +33 -5
  99. package/dist/styles/recipes/kbd.css +26 -6
  100. package/dist/styles/recipes/markdown-editor.css +12 -0
  101. package/dist/styles/recipes/morphing-panel.css +1 -1
  102. package/dist/styles/recipes/page-layout.css +18 -2
  103. package/dist/styles/recipes/pagination.css +8 -0
  104. package/dist/styles/recipes/popup-controls.css +9 -0
  105. package/dist/styles/recipes/popup-drawer.css +1 -0
  106. package/dist/styles/recipes/popup-lists.css +55 -6
  107. package/dist/styles/recipes/popup-motion.css +7 -1
  108. package/dist/styles/recipes/popup.css +10 -0
  109. package/dist/styles/recipes/range.css +16 -2
  110. package/dist/styles/recipes/sidebar-mobile.css +1 -1
  111. package/dist/styles/recipes/sidebar-parts.css +17 -1
  112. package/dist/styles/recipes/sidebar.css +11 -0
  113. package/dist/styles/recipes/swap.css +143 -0
  114. package/dist/styles/recipes/tabs.css +41 -8
  115. package/dist/styles/recipes/timeline.css +36 -2
  116. package/dist/styles/recipes/tool-approval.css +267 -0
  117. package/dist/styles/recipes/track-highlight.css +19 -6
  118. package/dist/styles/recipes/tree.css +33 -0
  119. package/dist/styles/theme.css +17 -6
  120. package/dist/tool-approval.d.ts +49 -0
  121. package/dist/tool-approval.js +260 -0
  122. package/dist/ui/alert-dialog.js +1 -1
  123. package/dist/ui/badge.js +1 -1
  124. package/dist/ui/calendar.js +9 -4
  125. package/dist/ui/card.d.ts +3 -1
  126. package/dist/ui/card.js +2 -1
  127. package/dist/ui/code.js +13 -3
  128. package/dist/ui/command.js +1 -0
  129. package/dist/ui/dialog.js +1 -1
  130. package/dist/ui/dropdown-menu.d.ts +1 -1
  131. package/dist/ui/dropdown-menu.js +23 -6
  132. package/dist/ui/dropzone.js +10 -11
  133. package/dist/ui/field.d.ts +6 -2
  134. package/dist/ui/field.js +4 -2
  135. package/dist/ui/infinite-canvas.d.ts +19 -22
  136. package/dist/ui/infinite-canvas.js +264 -325
  137. package/dist/ui/morphing-panel.d.ts +5 -1
  138. package/dist/ui/morphing-panel.js +4 -2
  139. package/dist/ui/rich-tooltip.d.ts +2 -1
  140. package/dist/ui/rich-tooltip.js +32 -29
  141. package/dist/ui/select.js +2 -2
  142. package/dist/ui/sidebar-mobile.js +1 -1
  143. package/dist/ui/sidebar-provider.d.ts +3 -1
  144. package/dist/ui/sidebar-provider.js +3 -2
  145. package/dist/ui/sidebar-resize-rail.js +1 -1
  146. package/dist/ui/sidebar.d.ts +6 -5
  147. package/dist/ui/sidebar.js +10 -9
  148. package/dist/ui/swap.d.ts +14 -0
  149. package/dist/ui/swap.js +69 -0
  150. package/dist/ui/tabs.d.ts +1 -1
  151. package/dist/ui/tabs.js +2 -13
  152. package/dist/ui/timeline.d.ts +1 -1
  153. package/dist/ui/timeline.js +2 -2
  154. package/dist/ui/typography.d.ts +11 -5
  155. package/dist/ui/typography.js +18 -6
  156. package/dist/user-ask.js +1 -1
  157. package/lint/biome-preset.json +3 -0
  158. package/lint/class-policy.mjs +17 -0
  159. package/lint/eslint-plugin.mjs +87 -0
  160. package/lint/grit-rules.mjs +40 -0
  161. package/lint/no-component-style-classes.grit +16 -0
  162. package/lint/no-raw-type-classes.grit +3 -4
  163. package/lint/write-grit-rules.mjs +19 -0
  164. package/package.json +12 -3
  165. package/dist/styles/type-scale.css +0 -72
@@ -7,12 +7,12 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/
7
7
  import { Drawer, DrawerContent, DrawerTitle } from "../ui/drawer.js";
8
8
  import { createDesignCanvasLayer, designCanvasFillColor, drawnDesignCanvasBounds } from "./design-canvas-data.js";
9
9
  import { DesignCanvasInspector } from "./design-canvas-inspector.js";
10
+ import { Toolbar, ToolbarButton, ToolbarGroup, ToolbarSeparator } from "../ui/toolbar.js";
10
11
  import { InfiniteCanvas, InfiniteCanvasContent, InfiniteCanvasControls, InfiniteCanvasItem } from "../ui/infinite-canvas.js";
11
12
  import { ResizableFloatingPanel } from "../ui/resizable.js";
12
- import { Toolbar, ToolbarButton, ToolbarGroup, ToolbarSeparator } from "../ui/toolbar.js";
13
13
  import { useRef, useState } from "react";
14
- import { jsx, jsxs } from "react/jsx-runtime";
15
- import { CircleIcon, FrameIcon, LayersIcon, MousePointer2Icon, SlidersHorizontalIcon, SquareIcon, TypeIcon } from "lucide-react";
14
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
15
+ import { CircleIcon, FrameIcon, HandIcon, LayersIcon, MousePointer2Icon, SlidersHorizontalIcon, SquareIcon, TypeIcon } from "lucide-react";
16
16
  //#region src/blocks/design-canvas.tsx
17
17
  const TOOLS = [
18
18
  {
@@ -21,6 +21,12 @@ const TOOLS = [
21
21
  shortcut: "V",
22
22
  icon: /* @__PURE__ */ jsx(MousePointer2Icon, {})
23
23
  },
24
+ {
25
+ tool: "hand",
26
+ label: "Hand",
27
+ shortcut: "H",
28
+ icon: /* @__PURE__ */ jsx(HandIcon, {})
29
+ },
24
30
  {
25
31
  tool: "frame",
26
32
  label: "Frame",
@@ -47,10 +53,10 @@ const TOOLS = [
47
53
  }
48
54
  ];
49
55
  const LAYER_ICONS = {
50
- frame: /* @__PURE__ */ jsx(FrameIcon, {}),
51
- rectangle: /* @__PURE__ */ jsx(SquareIcon, {}),
52
- ellipse: /* @__PURE__ */ jsx(CircleIcon, {}),
53
- text: /* @__PURE__ */ jsx(TypeIcon, {})
56
+ frame: /* @__PURE__ */ jsx(FrameIcon, { className: "text-muted-foreground" }),
57
+ rectangle: /* @__PURE__ */ jsx(SquareIcon, { className: "text-muted-foreground" }),
58
+ ellipse: /* @__PURE__ */ jsx(CircleIcon, { className: "text-muted-foreground" }),
59
+ text: /* @__PURE__ */ jsx(TypeIcon, { className: "text-muted-foreground" })
54
60
  };
55
61
  const NUDGE_DIRECTIONS = {
56
62
  ArrowLeft: {
@@ -99,6 +105,7 @@ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selecte
99
105
  const currentLayers = layers ?? internalLayers;
100
106
  const currentSelectedLayerId = selectedLayerId === void 0 ? internalSelectedLayerId : selectedLayerId;
101
107
  const selectedLayer = currentLayers.find((layer) => layer.id === currentSelectedLayerId);
108
+ const drawingKind = tool === "move" || tool === "hand" ? null : tool;
102
109
  function changeLayers(next) {
103
110
  if (layers === void 0) setInternalLayers(next);
104
111
  onLayersChange?.(next);
@@ -139,7 +146,7 @@ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selecte
139
146
  }
140
147
  function beginDrawOrDeselect(event) {
141
148
  if (event.defaultPrevented || event.target !== event.currentTarget) return;
142
- if (tool === "move") {
149
+ if (!drawingKind) {
143
150
  selectLayer(null);
144
151
  return;
145
152
  }
@@ -148,7 +155,7 @@ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selecte
148
155
  event.currentTarget.setPointerCapture(event.pointerId);
149
156
  const point = worldPointAt(event);
150
157
  setDraft({
151
- kind: tool,
158
+ kind: drawingKind,
152
159
  pointerId: event.pointerId,
153
160
  start: point,
154
161
  end: point,
@@ -200,7 +207,7 @@ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selecte
200
207
  setDraft(null);
201
208
  setTool("move");
202
209
  selectLayer(null);
203
- } else if (event.key === "Enter" && tool !== "move" && event.target === event.currentTarget) addLayerAtViewportCenter(tool, event.currentTarget);
210
+ } else if (event.key === "Enter" && drawingKind && event.target === event.currentTarget) addLayerAtViewportCenter(drawingKind, event.currentTarget);
204
211
  else if (!selectedLayer || !editLayerWithKey(selectedLayer, event)) return;
205
212
  event.preventDefault();
206
213
  }
@@ -226,7 +233,8 @@ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selecte
226
233
  transformRef.current = next;
227
234
  },
228
235
  "data-tool": tool,
229
- className: cn("size-full", tool !== "move" && "cursor-crosshair"),
236
+ panOnDrag: tool === "hand" ? "anywhere" : "background",
237
+ className: cn("size-full", drawingKind && "cursor-crosshair"),
230
238
  style: {
231
239
  "--cui-infinite-canvas-radius": "0px",
232
240
  "--cui-infinite-canvas-border-color": "transparent",
@@ -238,7 +246,7 @@ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selecte
238
246
  onPointerCancel: cancelDraft,
239
247
  onKeyDown: handleShortcut,
240
248
  children: [/* @__PURE__ */ jsxs(InfiniteCanvasContent, {
241
- className: cn(tool !== "move" && "[&>*]:pointer-events-none"),
249
+ className: cn(tool !== "move" && "pointer-events-none"),
242
250
  children: [currentLayers.map((layer) => /* @__PURE__ */ jsx(DesignCanvasLayerNode, {
243
251
  layer,
244
252
  selected: layer.id === currentSelectedLayerId,
@@ -280,7 +288,6 @@ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selecte
280
288
  onOpenChange: setLayersOpen,
281
289
  children: /* @__PURE__ */ jsx(DrawerContent, {
282
290
  side: "left",
283
- className: "gap-0 p-0",
284
291
  children: /* @__PURE__ */ jsx(DesignCanvasPanel, {
285
292
  label: layersLabel,
286
293
  title: layersLabel,
@@ -295,7 +302,6 @@ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selecte
295
302
  onOpenChange: setPropertiesOpen,
296
303
  children: /* @__PURE__ */ jsx(DrawerContent, {
297
304
  side: "right",
298
- className: "gap-0 p-0",
299
305
  children: /* @__PURE__ */ jsx(DesignCanvasPanel, {
300
306
  label: propertiesLabel,
301
307
  title: propertiesTitle,
@@ -345,24 +351,27 @@ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selecte
345
351
  });
346
352
  }
347
353
  function DesignCanvasPanel({ label, title, inDrawer = false, children }) {
348
- const titleClassName = "flex h-11 shrink-0 items-center border-b px-3";
349
- const titleText = /* @__PURE__ */ jsx("span", {
350
- className: "truncate",
351
- title,
352
- children: title
353
- });
354
354
  return /* @__PURE__ */ jsxs("aside", {
355
355
  "aria-label": label,
356
356
  className: "flex min-h-0 flex-1 flex-col",
357
- children: [inDrawer ? /* @__PURE__ */ jsx(DrawerTitle, {
358
- className: `${titleClassName} text-caption font-medium`,
359
- children: titleText
360
- }) : /* @__PURE__ */ jsx(Heading, {
361
- level: 2,
362
- size: "caption",
363
- weight: "medium",
364
- className: titleClassName,
365
- children: titleText
357
+ children: [/* @__PURE__ */ jsx("div", {
358
+ className: "flex h-11 shrink-0 items-center border-b px-3",
359
+ children: inDrawer ? /* @__PURE__ */ jsx(DrawerTitle, {
360
+ className: "truncate",
361
+ title,
362
+ style: {
363
+ "--cui-popup-title-font-size": "var(--text-caption)",
364
+ "--cui-popup-title-font-weight": "var(--font-weight-medium)"
365
+ },
366
+ children: title
367
+ }) : /* @__PURE__ */ jsx(Heading, {
368
+ level: 2,
369
+ size: "caption",
370
+ weight: "medium",
371
+ className: "truncate",
372
+ title,
373
+ children: title
374
+ })
366
375
  }), /* @__PURE__ */ jsx(ScrollArea, {
367
376
  className: "min-h-0 flex-1",
368
377
  children
@@ -377,7 +386,8 @@ function DesignCanvasLayerList({ layers, selectedLayerId, onSelect }) {
377
386
  size: "sm",
378
387
  active: layer.id === selectedLayerId,
379
388
  "aria-pressed": layer.id === selectedLayerId,
380
- className: "w-full justify-start [&_svg]:size-3.5 [&_svg]:text-muted-foreground",
389
+ className: "w-full justify-start",
390
+ style: { "--cui-button-icon": "calc(var(--spacing) * 3.5)" },
381
391
  onClick: () => onSelect(layer.id),
382
392
  children: [LAYER_ICONS[layer.kind], /* @__PURE__ */ jsx("span", {
383
393
  className: "truncate",
@@ -399,7 +409,6 @@ function DesignCanvasLayerNode({ layer, selected, onSelect, onKeyDown, onLayerCh
399
409
  "aria-pressed": interactive ? selected : void 0,
400
410
  "aria-keyshortcuts": interactive ? LAYER_KEY_SHORTCUTS : void 0,
401
411
  "data-selected": selected || void 0,
402
- className: "outline-primary data-selected:outline-2",
403
412
  style: {
404
413
  width: layer.width,
405
414
  height: layer.height,
@@ -434,15 +443,21 @@ function DesignCanvasLayerNode({ layer, selected, onSelect, onKeyDown, onLayerCh
434
443
  borderRadius: layer.kind === "ellipse" ? "50%" : layer.cornerRadius
435
444
  }
436
445
  }),
437
- selected ? /* @__PURE__ */ jsxs(Text, {
438
- size: "micro",
439
- className: "absolute inset-x-0 top-full mx-auto mt-1.5 w-max rounded-sm bg-primary px-1 whitespace-nowrap text-primary-foreground tabular-nums",
440
- children: [
441
- layer.width,
442
- " × ",
443
- layer.height
444
- ]
445
- }) : null
446
+ selected ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
447
+ "aria-hidden": "true",
448
+ className: "absolute inset-0 outline-2 outline-primary"
449
+ }), /* @__PURE__ */ jsx("span", {
450
+ className: "absolute inset-x-0 top-full mx-auto mt-1.5 flex w-max rounded-sm bg-primary px-1 whitespace-nowrap text-primary-foreground",
451
+ children: /* @__PURE__ */ jsxs(Text, {
452
+ size: "micro",
453
+ numeric: true,
454
+ children: [
455
+ layer.width,
456
+ " × ",
457
+ layer.height
458
+ ]
459
+ })
460
+ })] }) : null
446
461
  ]
447
462
  });
448
463
  }
@@ -452,8 +467,7 @@ function DesignCanvasToolbarButton({ label, hint, pressed, children, ...props })
452
467
  ...props,
453
468
  "aria-label": label,
454
469
  iconOnly: true,
455
- "aria-pressed": pressed,
456
- "data-pressed": pressed ? "" : void 0
470
+ "aria-pressed": pressed
457
471
  }),
458
472
  children
459
473
  }), /* @__PURE__ */ jsx(TooltipContent, { children: hint })] });
@@ -70,7 +70,7 @@ function DiscussionComposer({ label, placeholder, submitLabel = "Post", secondar
70
70
  error ? /* @__PURE__ */ jsx(Text, {
71
71
  as: "p",
72
72
  role: "alert",
73
- className: "px-3",
73
+ className: "mx-3",
74
74
  children: error
75
75
  }) : null,
76
76
  /* @__PURE__ */ jsxs(ChatComposerToolbar, { children: [/* @__PURE__ */ jsx(Text, {
@@ -70,7 +70,8 @@ function FileExplorerBlock({ locations, activeLocationId, defaultActiveLocationI
70
70
  layout,
71
71
  persistOpen,
72
72
  keyboardShortcut,
73
- className: cn("bg-background text-foreground", !contained && "h-svh overflow-hidden", className),
73
+ surface: "background",
74
+ className: cn(!contained && "h-svh overflow-hidden", className),
74
75
  style: providerStyle,
75
76
  ...props,
76
77
  children: [/* @__PURE__ */ jsx(FileExplorerSidebar, {
@@ -147,7 +148,7 @@ function FileExplorerSidebar({ locations, activeLocationId, sidebarTop, sidebarF
147
148
  collapsible: "offcanvas",
148
149
  children: [
149
150
  sidebarTop ? /* @__PURE__ */ jsx(SidebarHeader, {
150
- className: "min-h-11 justify-center px-3",
151
+ className: "min-h-11 justify-center",
151
152
  children: sidebarTop
152
153
  }) : null,
153
154
  /* @__PURE__ */ jsx(SidebarContent, { children: groups.map((group) => /* @__PURE__ */ jsxs(SidebarGroup, { children: [group.label ? /* @__PURE__ */ jsx(SidebarGroupLabel, { children: group.label }) : null, /* @__PURE__ */ jsx(SidebarMenu, { children: group.items.map((location) => /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(SidebarMenuButton, {
@@ -214,13 +215,10 @@ function FileExplorerHeader({ location, headingLevel, breadcrumbs, query, search
214
215
  size: "sm",
215
216
  className: "flex-[0_1_9rem] @xl/explorer:flex-[0_0_12rem]",
216
217
  children: [
217
- /* @__PURE__ */ jsx(InputGroupAddon, {
218
- className: "ps-2",
219
- children: /* @__PURE__ */ jsx(SearchIcon, {
220
- className: "size-3.5",
221
- "aria-hidden": "true"
222
- })
223
- }),
218
+ /* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(SearchIcon, {
219
+ className: "size-3.5",
220
+ "aria-hidden": "true"
221
+ }) }),
224
222
  /* @__PURE__ */ jsx(Input, {
225
223
  type: "search",
226
224
  "aria-label": searchLabel,
@@ -388,7 +386,7 @@ function FileExplorerColumns({ columns, selectedEntry, selectedPath, headingLeve
388
386
  }) : /* @__PURE__ */ jsx(Text, {
389
387
  size: "label",
390
388
  weight: "medium",
391
- className: "min-w-0 truncate px-1",
389
+ className: "mx-1 min-w-0 truncate",
392
390
  children: activeColumn?.label
393
391
  }), /* @__PURE__ */ jsxs(Drawer, { children: [/* @__PURE__ */ jsx(DrawerTrigger, {
394
392
  render: /* @__PURE__ */ jsx(Button, {
@@ -401,7 +399,11 @@ function FileExplorerColumns({ columns, selectedEntry, selectedPath, headingLeve
401
399
  }), /* @__PURE__ */ jsx(DrawerContent, { children: selectedEntry ? /* @__PURE__ */ jsx(DrawerBody, { children: /* @__PURE__ */ jsx(FileExplorerPreviewContent, {
402
400
  entry: selectedEntry,
403
401
  title: /* @__PURE__ */ jsx(DrawerTitle, {
404
- className: "mt-4 max-w-full truncate text-heading-4",
402
+ className: "mt-4 max-w-full truncate",
403
+ style: {
404
+ "--cui-popup-title-font-size": "var(--text-heading-4)",
405
+ "--cui-popup-title-line-height": "var(--text-heading-4--line-height)"
406
+ },
405
407
  children: selectedEntry.name
406
408
  })
407
409
  }) }) : null })] })]
@@ -457,7 +459,8 @@ function FileExplorerColumnView({ column, optionRef, onSelect, onOpen, onOptionK
457
459
  const groups = groupFileExplorerItems(column.entries);
458
460
  const tabStopId = column.selectedId ?? groups[0]?.items[0]?.id;
459
461
  if (column.entries.length === 0) return /* @__PURE__ */ jsx(Empty, {
460
- className: "h-full rounded-none",
462
+ className: "h-full",
463
+ style: { "--cui-empty-radius": "0px" },
461
464
  children: /* @__PURE__ */ jsxs(EmptyHeader, { children: [
462
465
  /* @__PURE__ */ jsx(EmptyMedia, { children: /* @__PURE__ */ jsx(FolderIcon, {}) }),
463
466
  /* @__PURE__ */ jsx(EmptyTitle, { children: "Empty folder" }),
@@ -483,7 +486,7 @@ function FileExplorerColumnView({ column, optionRef, onSelect, onOpen, onOptionK
483
486
  variant: "quiet",
484
487
  size: "sm",
485
488
  active: isSelected,
486
- className: "w-full justify-start gap-2 px-2 text-start",
489
+ className: "w-full justify-start gap-2 text-start",
487
490
  title: entry.name,
488
491
  onClick: () => onSelect(entry),
489
492
  onDoubleClick: () => onOpen(entry),
@@ -515,7 +518,7 @@ function FileExplorerColumnView({ column, optionRef, onSelect, onOpen, onOptionK
515
518
  size: "caption",
516
519
  weight: "semibold",
517
520
  tone: "muted",
518
- className: "mb-1 px-2",
521
+ className: "mx-2 mb-1",
519
522
  children: group.label
520
523
  }), options]
521
524
  }, group.label) : /* @__PURE__ */ jsx("div", {
@@ -529,7 +532,8 @@ function FileExplorerColumnView({ column, optionRef, onSelect, onOpen, onOptionK
529
532
  }
530
533
  function FileExplorerPreview({ entry, headingLevel }) {
531
534
  if (!entry) return /* @__PURE__ */ jsx(Empty, {
532
- className: "h-full rounded-none",
535
+ className: "h-full",
536
+ style: { "--cui-empty-radius": "0px" },
533
537
  children: /* @__PURE__ */ jsxs(EmptyHeader, { children: [
534
538
  /* @__PURE__ */ jsx(EmptyMedia, { children: /* @__PURE__ */ jsx(FileIcon, {}) }),
535
539
  /* @__PURE__ */ jsx(EmptyTitle, { children: "Select an item" }),
@@ -569,14 +573,19 @@ function FileExplorerPreviewContent({ entry, title, className }) {
569
573
  children: entry.description
570
574
  }) : null,
571
575
  entry.details && entry.details.length > 0 ? /* @__PURE__ */ jsx("dl", {
572
- className: "mt-6 grid w-full grid-cols-[auto_1fr] gap-x-4 gap-y-2 border-t border-border/70 pt-4 text-start text-caption",
576
+ className: "mt-6 grid w-full grid-cols-[auto_1fr] gap-x-4 gap-y-2 border-t border-border/70 pt-4 text-start",
573
577
  children: entry.details.map((detail) => /* @__PURE__ */ jsxs("div", {
574
578
  className: "contents",
575
- children: [/* @__PURE__ */ jsx("dt", {
576
- className: "text-muted-foreground",
579
+ children: [/* @__PURE__ */ jsx(Text, {
580
+ as: "dt",
581
+ size: "caption",
582
+ tone: "muted",
577
583
  children: detail.label
578
- }), /* @__PURE__ */ jsx("dd", {
579
- className: "min-w-0 truncate text-end text-foreground",
584
+ }), /* @__PURE__ */ jsx(Text, {
585
+ as: "dd",
586
+ size: "caption",
587
+ tone: "foreground",
588
+ className: "min-w-0 truncate text-end",
580
589
  children: detail.value
581
590
  })]
582
591
  }, detail.label))
@@ -593,7 +602,8 @@ function FileExplorerSearchResults({ label, status, clearSearchLabel, results, o
593
602
  const [activeIndex, setActiveIndex] = useState(0);
594
603
  const tabStop = Math.min(activeIndex, results.length - 1);
595
604
  if (results.length === 0) return /* @__PURE__ */ jsxs(Empty, {
596
- className: "h-full rounded-none",
605
+ className: "h-full",
606
+ style: { "--cui-empty-radius": "0px" },
597
607
  children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
598
608
  /* @__PURE__ */ jsx(EmptyMedia, { children: /* @__PURE__ */ jsx(SearchIcon, {}) }),
599
609
  /* @__PURE__ */ jsx(EmptyTitle, { children: status }),
@@ -632,7 +642,8 @@ function FileExplorerSearchResults({ label, status, clearSearchLabel, results, o
632
642
  as: "div",
633
643
  size: "caption",
634
644
  tone: "muted",
635
- className: "mb-2 px-2 tabular-nums",
645
+ numeric: true,
646
+ className: "mx-2 mb-2",
636
647
  children: status
637
648
  }), /* @__PURE__ */ jsx("div", {
638
649
  role: "listbox",
@@ -647,7 +658,7 @@ function FileExplorerSearchResults({ label, status, clearSearchLabel, results, o
647
658
  tabIndex: index === tabStop ? 0 : -1,
648
659
  variant: "quiet",
649
660
  size: "lg",
650
- className: "h-auto w-full justify-start gap-3 px-3 py-2 text-start",
661
+ className: "h-auto min-h-12 w-full justify-start gap-3 text-start",
651
662
  onClick: () => onSelect(result),
652
663
  onDoubleClick: () => onOpen(result.entry, result.path),
653
664
  onFocus: () => setActiveIndex(index),
@@ -679,39 +690,47 @@ function FileExplorerStatusBar({ breadcrumbs, selectedEntry }) {
679
690
  const itemCount = selectedEntry?.children?.length ?? 0;
680
691
  const itemLabel = itemCount === 1 ? "1 item" : `${itemCount} items`;
681
692
  return /* @__PURE__ */ jsxs("footer", {
682
- className: "flex h-8 shrink-0 items-center gap-3 border-t border-border/70 px-3 text-micro text-muted-foreground",
683
- children: [/* @__PURE__ */ jsx("span", {
693
+ className: "flex h-8 shrink-0 items-center gap-3 border-t border-border/70 px-3",
694
+ children: [/* @__PURE__ */ jsx(Text, {
695
+ size: "micro",
696
+ tone: "muted",
684
697
  className: "min-w-0 flex-1 truncate",
685
698
  title: path,
686
699
  children: path
687
- }), /* @__PURE__ */ jsx("span", {
688
- className: "shrink-0 tabular-nums",
700
+ }), /* @__PURE__ */ jsx(Text, {
701
+ size: "micro",
702
+ tone: "muted",
703
+ numeric: true,
704
+ className: "shrink-0",
689
705
  children: selectedEntry?.kind === "folder" ? itemLabel : selectedEntry?.name ?? "No selection"
690
706
  })]
691
707
  });
692
708
  }
693
709
  function FileExplorerAddressBar({ breadcrumbs, onSelect }) {
694
- return /* @__PURE__ */ jsx(Breadcrumb, {
695
- "aria-label": "Current folder",
710
+ return /* @__PURE__ */ jsx("div", {
696
711
  className: "min-w-0 overflow-hidden px-1",
697
- children: /* @__PURE__ */ jsx(BreadcrumbList, {
698
- className: "min-w-0 flex-nowrap overflow-hidden",
699
- children: breadcrumbs.map((breadcrumb, index) => {
700
- const isCurrent = index === breadcrumbs.length - 1;
701
- return /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 ? /* @__PURE__ */ jsx(BreadcrumbSeparator, {}) : null, /* @__PURE__ */ jsx(BreadcrumbItem, {
702
- className: "min-w-0",
703
- children: isCurrent ? /* @__PURE__ */ jsx(BreadcrumbPage, {
704
- className: "min-w-0 truncate",
705
- title: breadcrumb.label,
706
- children: breadcrumb.label
707
- }) : /* @__PURE__ */ jsx(BreadcrumbLink, {
708
- render: /* @__PURE__ */ jsx("button", { type: "button" }),
709
- className: "min-w-0 truncate",
710
- title: breadcrumb.label,
711
- onClick: () => onSelect(breadcrumb),
712
- children: breadcrumb.label
713
- })
714
- })] }, `${breadcrumb.id}:${breadcrumb.path.join("/")}`);
712
+ children: /* @__PURE__ */ jsx(Breadcrumb, {
713
+ "aria-label": "Current folder",
714
+ className: "min-w-0",
715
+ children: /* @__PURE__ */ jsx(BreadcrumbList, {
716
+ className: "min-w-0 flex-nowrap overflow-hidden",
717
+ children: breadcrumbs.map((breadcrumb, index) => {
718
+ const isCurrent = index === breadcrumbs.length - 1;
719
+ return /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 ? /* @__PURE__ */ jsx(BreadcrumbSeparator, {}) : null, /* @__PURE__ */ jsx(BreadcrumbItem, {
720
+ className: "min-w-0",
721
+ children: isCurrent ? /* @__PURE__ */ jsx(BreadcrumbPage, {
722
+ className: "min-w-0 truncate",
723
+ title: breadcrumb.label,
724
+ children: breadcrumb.label
725
+ }) : /* @__PURE__ */ jsx(BreadcrumbLink, {
726
+ render: /* @__PURE__ */ jsx("button", { type: "button" }),
727
+ className: "min-w-0 truncate",
728
+ title: breadcrumb.label,
729
+ onClick: () => onSelect(breadcrumb),
730
+ children: breadcrumb.label
731
+ })
732
+ })] }, `${breadcrumb.id}:${breadcrumb.path.join("/")}`);
733
+ })
715
734
  })
716
735
  })
717
736
  });
@@ -12,7 +12,7 @@ import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
12
12
  import { Input } from "../ui/input.js";
13
13
  import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "../ui/empty.js";
14
14
  import { searchSettings } from "./settings-data.js";
15
- import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet } from "../ui/field.js";
15
+ import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel, FieldLegend, FieldSet } from "../ui/field.js";
16
16
  import { useEffect, useId, useState } from "react";
17
17
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
18
18
  import { ArrowLeftIcon, SearchIcon, XIcon } from "lucide-react";
@@ -35,7 +35,8 @@ function SettingsBlock({ pages, activePageId, defaultActivePageId, onActivePageC
35
35
  };
36
36
  return /* @__PURE__ */ jsx(SidebarProvider, {
37
37
  layout,
38
- className: cn("bg-background text-foreground", layout === "viewport" && "h-svh overflow-hidden", className),
38
+ surface: "background",
39
+ className: cn(layout === "viewport" && "h-svh overflow-hidden", className),
39
40
  style: providerStyle,
40
41
  ...props,
41
42
  children: /* @__PURE__ */ jsx(SettingsShell, {
@@ -95,7 +96,8 @@ function SettingsShell({ pages, currentPage, query, results, backAction, searchP
95
96
  /* @__PURE__ */ jsxs(Sidebar, {
96
97
  collapsible: "offcanvas",
97
98
  children: [/* @__PURE__ */ jsxs(SidebarHeader, {
98
- className: "gap-3 border-b border-sidebar-border p-3",
99
+ divider: true,
100
+ className: "gap-3",
99
101
  children: [backAction ? /* @__PURE__ */ jsx("div", {
100
102
  className: "min-w-0",
101
103
  children: backAction
@@ -144,13 +146,10 @@ function SettingsSearch({ value, label, placeholder, onValueChange }) {
144
146
  return /* @__PURE__ */ jsxs(InputGroup, {
145
147
  size: "sm",
146
148
  children: [
147
- /* @__PURE__ */ jsx(InputGroupAddon, {
148
- className: "ps-2.5",
149
- children: /* @__PURE__ */ jsx(SearchIcon, {
150
- className: "size-3.5",
151
- "aria-hidden": "true"
152
- })
153
- }),
149
+ /* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(SearchIcon, {
150
+ className: "size-3.5",
151
+ "aria-hidden": "true"
152
+ }) }),
154
153
  /* @__PURE__ */ jsx(Input, {
155
154
  type: "search",
156
155
  "aria-label": label,
@@ -203,7 +202,6 @@ function SettingsSearchNavigation({ results, onSelect, onClear }) {
203
202
  }
204
203
  return /* @__PURE__ */ jsx(Fragment$1, { children: [...groups.values()].map((group) => /* @__PURE__ */ jsxs(SidebarGroup, { children: [/* @__PURE__ */ jsxs(SidebarGroupLabel, { children: [group.page.icon, /* @__PURE__ */ jsx("span", { children: group.page.title })] }), /* @__PURE__ */ jsx(SidebarMenu, { children: group.results.map((result) => /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(SidebarMenuButton, {
205
204
  size: "sm",
206
- className: "h-auto min-h-(--control-h-sm) py-1.5",
207
205
  onClick: () => onSelect(result),
208
206
  children: /* @__PURE__ */ jsx("span", {
209
207
  title: result.setting.title,
@@ -222,58 +220,56 @@ function SettingsPage({ page, instanceId }) {
222
220
  }), page.sections.map((section) => /* @__PURE__ */ jsxs(FieldSet, {
223
221
  className: "gap-3",
224
222
  children: [/* @__PURE__ */ jsx(FieldLegend, {
225
- className: "text-body font-semibold",
223
+ variant: "section",
226
224
  children: section.title
227
225
  }), /* @__PURE__ */ jsx(FieldGroup, {
228
- className: "gap-0 overflow-hidden rounded-[var(--radius-lg)] border bg-card",
229
- children: section.settings.map((setting, index) => /* @__PURE__ */ jsx(SettingsRow, {
226
+ variant: "card",
227
+ children: section.settings.map((setting) => /* @__PURE__ */ jsx(SettingsRow, {
230
228
  pageId: page.id,
231
229
  sectionId: section.id,
232
230
  setting,
233
- instanceId,
234
- separated: index > 0
231
+ instanceId
235
232
  }, setting.id))
236
233
  })]
237
234
  }, section.id))]
238
235
  });
239
236
  }
240
- function SettingsRow({ pageId, sectionId, setting, instanceId, separated }) {
237
+ function SettingsRow({ pageId, sectionId, setting, instanceId }) {
241
238
  const ids = settingDomIds(instanceId, pageId, sectionId, setting.id);
242
239
  const controlProps = {
243
240
  id: ids.control,
244
241
  "aria-labelledby": ids.label,
245
242
  "aria-describedby": setting.description ? ids.description : void 0
246
243
  };
247
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [separated ? /* @__PURE__ */ jsx(FieldSeparator, {}) : null, /* @__PURE__ */ jsxs(Field, {
244
+ return /* @__PURE__ */ jsx("div", {
248
245
  id: ids.row,
249
- orientation: "responsive",
250
246
  tabIndex: -1,
251
- className: "scroll-m-8 gap-3 p-4 outline-none transition-colors duration-[var(--duration-fast)] focus:bg-foreground/4 focus-within:bg-foreground/4",
252
- children: [/* @__PURE__ */ jsxs(FieldContent, { children: [/* @__PURE__ */ jsx(FieldLabel, {
253
- id: ids.label,
254
- htmlFor: ids.control,
255
- className: "leading-snug",
256
- children: setting.title
257
- }), setting.description ? /* @__PURE__ */ jsx(FieldDescription, {
258
- id: ids.description,
259
- children: setting.description
260
- }) : null] }), /* @__PURE__ */ jsx("div", {
261
- className: "flex shrink-0 items-center",
262
- children: setting.renderControl(controlProps)
263
- })]
264
- })] });
247
+ className: "scroll-m-8 outline-none transition-colors duration-[var(--duration-fast)] focus:bg-foreground/4 focus-within:bg-foreground/4",
248
+ children: /* @__PURE__ */ jsxs(Field, {
249
+ orientation: "responsive",
250
+ className: "gap-3",
251
+ children: [/* @__PURE__ */ jsxs(FieldContent, { children: [/* @__PURE__ */ jsx(FieldLabel, {
252
+ id: ids.label,
253
+ htmlFor: ids.control,
254
+ children: setting.title
255
+ }), setting.description ? /* @__PURE__ */ jsx(FieldDescription, {
256
+ id: ids.description,
257
+ children: setting.description
258
+ }) : null] }), /* @__PURE__ */ jsx("div", {
259
+ className: "flex shrink-0 items-center",
260
+ children: setting.renderControl(controlProps)
261
+ })]
262
+ })
263
+ });
265
264
  }
266
265
  function SettingsEmpty({ title, description, action }) {
267
266
  return /* @__PURE__ */ jsxs(Empty, {
268
- className: "min-h-40 gap-3 p-4",
267
+ className: "min-h-40",
269
268
  children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
270
- /* @__PURE__ */ jsx(EmptyMedia, {
271
- className: "mb-0 size-8",
272
- children: /* @__PURE__ */ jsx(SearchIcon, {
273
- className: "size-4",
274
- "aria-hidden": "true"
275
- })
276
- }),
269
+ /* @__PURE__ */ jsx(EmptyMedia, { children: /* @__PURE__ */ jsx(SearchIcon, {
270
+ className: "size-4",
271
+ "aria-hidden": "true"
272
+ }) }),
277
273
  /* @__PURE__ */ jsx(EmptyTitle, { children: title }),
278
274
  /* @__PURE__ */ jsx(EmptyDescription, { children: description })
279
275
  ] }), action ? /* @__PURE__ */ jsx(EmptyContent, { children: action }) : null]
@@ -7,7 +7,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
7
7
  function TeamChatBlock({ sidebar, children, thread, threadLabel = "Thread", className, ...props }) {
8
8
  const threadIsOpen = thread !== void 0 && thread !== null;
9
9
  return /* @__PURE__ */ jsxs(SidebarProvider, {
10
- className: cn("bg-background text-foreground", className),
10
+ surface: "background",
11
+ className,
11
12
  ...props,
12
13
  children: [sidebar, /* @__PURE__ */ jsxs(SidebarInset, {
13
14
  className: "@container/team-chat flex h-full min-h-0 min-w-0 flex-row",
@@ -31,12 +31,13 @@ export type ThemeSwitchProps = Omit<ComponentProps<typeof Switch>, "checked" | "
31
31
  export type ThemeSegmentedSwitchProps = Omit<ComponentProps<"div">, "onChange"> & ThemeControlProps & {
32
32
  name?: string;
33
33
  showLabels?: boolean;
34
+ disabled?: boolean;
34
35
  };
35
36
  export type ThemeDropdownProps = Omit<ComponentProps<typeof DropdownMenuTrigger>, "children" | "value" | "onChange"> & ThemeControlProps & {
36
37
  label?: string;
37
38
  };
38
39
  export declare function ThemeSwitch({ value, onValueChange, onValue, offValue, checkedIcon, uncheckedIcon, "aria-label": ariaLabel, ...props }: ThemeSwitchProps): import("react").JSX.Element;
39
- export declare function ThemeSegmentedSwitch({ value, onValueChange, options, showLabels, name, className, style, "aria-label": ariaLabel, ...props }: ThemeSegmentedSwitchProps): import("react").JSX.Element;
40
+ export declare function ThemeSegmentedSwitch({ value, onValueChange, options, showLabels, disabled, name, className, style, "aria-label": ariaLabel, ...props }: ThemeSegmentedSwitchProps): import("react").JSX.Element;
40
41
  export declare function ThemeToggle({ value, onValueChange, options, showLabel, showLabels, className, onClick, "aria-label": ariaLabel, ...props }: ThemeToggleProps): import("react").JSX.Element;
41
42
  export declare function ThemeDropdown({ value, onValueChange, options, label, className, "aria-label": ariaLabel, ...props }: ThemeDropdownProps): import("react").JSX.Element;
42
43
  //#endregion