@cueplusplus/ui 0.1.0 → 0.3.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.
Files changed (246) hide show
  1. package/CHANGELOG.md +705 -0
  2. package/dist/brand/_chassis.d.ts +54 -0
  3. package/dist/brand/_chassis.js +81 -0
  4. package/dist/brand/_geometry.js +41 -0
  5. package/dist/brand/cue-logotype.d.ts +29 -0
  6. package/dist/brand/cue-logotype.js +60 -0
  7. package/dist/brand/cue-mark.d.ts +30 -0
  8. package/dist/brand/cue-mark.js +61 -0
  9. package/dist/brand/index.d.ts +5 -0
  10. package/dist/brand/plussie.d.ts +67 -0
  11. package/dist/brand/plussie.js +125 -0
  12. package/dist/chat/agent-pile.js +1 -1
  13. package/dist/chat/ask-box.js +2 -2
  14. package/dist/chat/delegation-card.js +1 -1
  15. package/dist/chat/message.js +2 -2
  16. package/dist/chrome/_edge-scroller.d.ts +45 -0
  17. package/dist/chrome/_edge-scroller.js +149 -0
  18. package/dist/chrome/_glyphs.js +19 -1
  19. package/dist/chrome/_tabs-scroll.d.ts +13 -8
  20. package/dist/chrome/_tabs-scroll.js +13 -8
  21. package/dist/chrome/app-bar.d.ts +103 -0
  22. package/dist/chrome/app-bar.js +175 -0
  23. package/dist/chrome/app-shell.d.ts +125 -0
  24. package/dist/chrome/app-shell.js +167 -0
  25. package/dist/chrome/footer.d.ts +75 -0
  26. package/dist/chrome/footer.js +68 -0
  27. package/dist/chrome/index.d.ts +5 -1
  28. package/dist/chrome/index.js +4 -1
  29. package/dist/chrome/navigation-menu.js +1 -1
  30. package/dist/chrome/page-shell.d.ts +1 -1
  31. package/dist/chrome/page-shell.js +15 -5
  32. package/dist/chrome/segmented-control.d.ts +19 -0
  33. package/dist/chrome/segmented-control.js +40 -21
  34. package/dist/chrome/tabs.js +21 -65
  35. package/dist/chrome/toolbar.d.ts +22 -0
  36. package/dist/chrome/toolbar.js +26 -5
  37. package/dist/configurator/_overrides.js +22 -8
  38. package/dist/configurator/configurator.js +1 -1
  39. package/dist/configurator/panel-sections.js +10 -4
  40. package/dist/dmx/channel-matrix.js +1 -1
  41. package/dist/forms/otp-field.js +1 -1
  42. package/dist/index.d.ts +18 -9
  43. package/dist/index.js +16 -10
  44. package/dist/instruments/data-table.js +1 -1
  45. package/dist/instruments/index.d.ts +2 -2
  46. package/dist/instruments/index.js +2 -2
  47. package/dist/instruments/table.d.ts +14 -1
  48. package/dist/instruments/table.js +20 -1
  49. package/dist/layout/carousel.js +1 -1
  50. package/dist/layout/container.d.ts +1 -1
  51. package/dist/layout/container.js +6 -3
  52. package/dist/layout/index.d.ts +3 -3
  53. package/dist/layout/index.js +3 -3
  54. package/dist/layout/pagination.js +1 -1
  55. package/dist/layout/sidebar.d.ts +23 -3
  56. package/dist/layout/sidebar.js +18 -7
  57. package/dist/midi/spectrum-visualizer.js +1 -1
  58. package/dist/midi/timeline-ruler.js +1 -1
  59. package/dist/overlays/command-palette.js +1 -1
  60. package/dist/overlays/dialog.js +1 -1
  61. package/dist/overlays/dropdown-menu.js +2 -2
  62. package/dist/overlays/hover-card.js +1 -1
  63. package/dist/overlays/index.js +1 -1
  64. package/dist/overlays/popover.js +1 -1
  65. package/dist/overlays/sheet.js +1 -1
  66. package/dist/overlays/toast.js +1 -1
  67. package/dist/primitives/chip.d.ts +1 -1
  68. package/dist/primitives/index.d.ts +1 -1
  69. package/dist/primitives/index.js +1 -1
  70. package/dist/primitives/status-dot.d.ts +7 -0
  71. package/dist/primitives/status-dot.js +8 -1
  72. package/dist/styles.css +58 -2
  73. package/dist/system/density.d.ts +4 -1
  74. package/dist/system/density.js +12 -4
  75. package/dist/system/index.d.ts +4 -4
  76. package/dist/system/portal.d.ts +5 -5
  77. package/dist/system/portal.js +30 -11
  78. package/dist/system/prepaint.d.ts +34 -9
  79. package/dist/system/prepaint.js +48 -25
  80. package/dist/system/theme-provider.d.ts +48 -11
  81. package/dist/system/theme-provider.js +109 -35
  82. package/dist/system/use-density.d.ts +3 -3
  83. package/dist/system/use-density.js +16 -6
  84. package/dist/system/use-theme.d.ts +4 -2
  85. package/dist/system/use-theme.js +4 -2
  86. package/dist/theming/_presets.js +133 -5
  87. package/dist/theming/create-theme.d.ts +2 -2
  88. package/dist/theming/create-theme.js +37 -19
  89. package/dist/theming/serialize.d.ts +1 -1
  90. package/dist/theming/serialize.js +25 -1
  91. package/manifest/components/accordion.json +154 -0
  92. package/manifest/components/agent-pile.json +116 -0
  93. package/manifest/components/alert-dialog.json +190 -0
  94. package/manifest/components/app-bar.json +244 -0
  95. package/manifest/components/app-shell.json +291 -0
  96. package/manifest/components/app-window-frame.json +102 -0
  97. package/manifest/components/ask-box.json +209 -0
  98. package/manifest/components/autocomplete.json +197 -0
  99. package/manifest/components/avatar-group.json +72 -0
  100. package/manifest/components/avatar.json +95 -0
  101. package/manifest/components/breadcrumb.json +74 -0
  102. package/manifest/components/button-group.json +74 -0
  103. package/manifest/components/button.json +125 -0
  104. package/manifest/components/calendar.json +65 -0
  105. package/manifest/components/card.json +140 -0
  106. package/manifest/components/carousel.json +200 -0
  107. package/manifest/components/channel-matrix.json +173 -0
  108. package/manifest/components/chart-container.json +111 -0
  109. package/manifest/components/chart-ramp.json +72 -0
  110. package/manifest/components/chart-swatch.json +65 -0
  111. package/manifest/components/chart-tooltip-content.json +114 -0
  112. package/manifest/components/checkbox-group.json +68 -0
  113. package/manifest/components/checkbox.json +93 -0
  114. package/manifest/components/chip.json +132 -0
  115. package/manifest/components/collapsible.json +120 -0
  116. package/manifest/components/color-area.json +59 -0
  117. package/manifest/components/color-field.json +79 -0
  118. package/manifest/components/color-picker.json +175 -0
  119. package/manifest/components/color-slider.json +75 -0
  120. package/manifest/components/color-swatch.json +68 -0
  121. package/manifest/components/colors-section.json +66 -0
  122. package/manifest/components/combobox.json +198 -0
  123. package/manifest/components/command-palette.json +177 -0
  124. package/manifest/components/composer.json +176 -0
  125. package/manifest/components/container.json +60 -0
  126. package/manifest/components/context-menu.json +121 -0
  127. package/manifest/components/copy-button.json +93 -0
  128. package/manifest/components/cue-logotype.json +96 -0
  129. package/manifest/components/cue-mark.json +97 -0
  130. package/manifest/components/cue-portal-frame.json +55 -0
  131. package/manifest/components/data-table-pagination.json +83 -0
  132. package/manifest/components/data-table-toolbar.json +104 -0
  133. package/manifest/components/date-field.json +80 -0
  134. package/manifest/components/date-picker.json +191 -0
  135. package/manifest/components/date-range-picker.json +191 -0
  136. package/manifest/components/delegation-card.json +144 -0
  137. package/manifest/components/density.json +58 -0
  138. package/manifest/components/description-list.json +84 -0
  139. package/manifest/components/dialog.json +198 -0
  140. package/manifest/components/disclosure.json +109 -0
  141. package/manifest/components/dmx-bar.json +94 -0
  142. package/manifest/components/dmx-strip.json +101 -0
  143. package/manifest/components/drawer.json +179 -0
  144. package/manifest/components/dropdown-menu.json +229 -0
  145. package/manifest/components/empty-state.json +90 -0
  146. package/manifest/components/env-var-input.json +150 -0
  147. package/manifest/components/export-dialog.json +84 -0
  148. package/manifest/components/eyebrow.json +56 -0
  149. package/manifest/components/field-description.json +63 -0
  150. package/manifest/components/field-error.json +77 -0
  151. package/manifest/components/field-label.json +63 -0
  152. package/manifest/components/field.json +79 -0
  153. package/manifest/components/file-upload.json +159 -0
  154. package/manifest/components/flow-background.json +50 -0
  155. package/manifest/components/flow-controls.json +50 -0
  156. package/manifest/components/footer.json +112 -0
  157. package/manifest/components/grid.json +81 -0
  158. package/manifest/components/group-bar.json +102 -0
  159. package/manifest/components/hover-card.json +151 -0
  160. package/manifest/components/icon-button.json +88 -0
  161. package/manifest/components/info-tip.json +98 -0
  162. package/manifest/components/input-group.json +91 -0
  163. package/manifest/components/input.json +89 -0
  164. package/manifest/components/item.json +129 -0
  165. package/manifest/components/kbd.json +52 -0
  166. package/manifest/components/link.json +81 -0
  167. package/manifest/components/log-viewer.json +139 -0
  168. package/manifest/components/menubar.json +157 -0
  169. package/manifest/components/message-list.json +100 -0
  170. package/manifest/components/message.json +116 -0
  171. package/manifest/components/meter.json +114 -0
  172. package/manifest/components/multi-select.json +190 -0
  173. package/manifest/components/musical-time-input.json +113 -0
  174. package/manifest/components/navigation-menu.json +226 -0
  175. package/manifest/components/node-card.json +109 -0
  176. package/manifest/components/node-handle.json +69 -0
  177. package/manifest/components/number-field.json +107 -0
  178. package/manifest/components/otp-field.json +128 -0
  179. package/manifest/components/page-shell.json +96 -0
  180. package/manifest/components/pagination.json +92 -0
  181. package/manifest/components/panel-header.json +77 -0
  182. package/manifest/components/panel.json +71 -0
  183. package/manifest/components/password-input.json +119 -0
  184. package/manifest/components/piano-keyboard.json +120 -0
  185. package/manifest/components/plussie.json +111 -0
  186. package/manifest/components/popover.json +193 -0
  187. package/manifest/components/preset-section.json +73 -0
  188. package/manifest/components/progress.json +95 -0
  189. package/manifest/components/radio-group.json +73 -0
  190. package/manifest/components/radio.json +80 -0
  191. package/manifest/components/rating.json +141 -0
  192. package/manifest/components/resizable.json +88 -0
  193. package/manifest/components/row.json +109 -0
  194. package/manifest/components/scroll-area.json +91 -0
  195. package/manifest/components/scrollable-tabs-list.json +83 -0
  196. package/manifest/components/scrub-input.json +200 -0
  197. package/manifest/components/seam-cell.json +75 -0
  198. package/manifest/components/seam-grid.json +75 -0
  199. package/manifest/components/seam-list.json +56 -0
  200. package/manifest/components/search-input.json +134 -0
  201. package/manifest/components/section-header.json +112 -0
  202. package/manifest/components/segmented-control.json +138 -0
  203. package/manifest/components/select.json +194 -0
  204. package/manifest/components/separator.json +53 -0
  205. package/manifest/components/shape-section.json +66 -0
  206. package/manifest/components/sheet.json +186 -0
  207. package/manifest/components/sidebar.json +198 -0
  208. package/manifest/components/signal-edge.json +56 -0
  209. package/manifest/components/skeleton.json +46 -0
  210. package/manifest/components/slider.json +89 -0
  211. package/manifest/components/sparkline.json +76 -0
  212. package/manifest/components/spectrum-visualizer.json +115 -0
  213. package/manifest/components/spinner.json +61 -0
  214. package/manifest/components/stack.json +96 -0
  215. package/manifest/components/stat.json +87 -0
  216. package/manifest/components/status-bar.json +58 -0
  217. package/manifest/components/status-dot.json +78 -0
  218. package/manifest/components/stepper.json +89 -0
  219. package/manifest/components/switch.json +87 -0
  220. package/manifest/components/table-scroll-region.json +69 -0
  221. package/manifest/components/table.json +155 -0
  222. package/manifest/components/tabs.json +145 -0
  223. package/manifest/components/tags-input.json +190 -0
  224. package/manifest/components/terminal-frame.json +119 -0
  225. package/manifest/components/textarea.json +76 -0
  226. package/manifest/components/theme-configurator.json +124 -0
  227. package/manifest/components/theme-provider.json +134 -0
  228. package/manifest/components/threshold-rail.json +160 -0
  229. package/manifest/components/time-field.json +80 -0
  230. package/manifest/components/timeline-ruler.json +139 -0
  231. package/manifest/components/timeline.json +115 -0
  232. package/manifest/components/title-bar.json +82 -0
  233. package/manifest/components/toast.json +130 -0
  234. package/manifest/components/toggle-group.json +106 -0
  235. package/manifest/components/toggle.json +109 -0
  236. package/manifest/components/token-editor.json +90 -0
  237. package/manifest/components/toolbar.json +163 -0
  238. package/manifest/components/tooltip.json +164 -0
  239. package/manifest/components/tree-visibility-toggle.json +84 -0
  240. package/manifest/components/tree.json +140 -0
  241. package/manifest/components/two-step-button.json +113 -0
  242. package/manifest/components/universe-grid.json +127 -0
  243. package/manifest/components/usage-chart.json +124 -0
  244. package/manifest/manifest.json +2142 -0
  245. package/manifest/tokens.json +138 -0
  246. package/package.json +13 -5
@@ -0,0 +1,291 @@
1
+ {
2
+ "name": "AppShell",
3
+ "slug": "app-shell",
4
+ "group": "chrome",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The console frame: title bar, navigation, work area, status bar — one\nviewport tall, with exactly one thing scrolling.\n\nEvery console screen in this system is the same five parts in the same\narrangement, and the value here is not the parts (they already exist as\n`TitleBar`, `Sidebar`, `Toolbar` and `StatusBar`) but the arithmetic between\nthem: `h-dvh` on the frame rather than `min-h-dvh`, an unbroken `min-h-0`\nchain from the frame down to the scroller, `min-w-0` on the content column,\nand a scroller that is not the document. Get one of those wrong and the\nstatus bar leaves the screen or the navigation column gets shoved off the\nside; the shell exists so no page has to get them right again.\n\nThe bars are ordinary children — `TitleBar` and `StatusBar` are already\n`shrink-0` and need no wrapper — so a shell reads as the page's outline.\n\nThis is also the only component in the library with a viewport breakpoint:\nbelow `md` the navigation column becomes a drawer and a trigger appears in\nthe bar. See {@link AppShellSidebar} for the ruling.",
9
+ "props": [],
10
+ "typeReferences": [],
11
+ "subcomponents": [
12
+ "Root",
13
+ "Body",
14
+ "Sidebar",
15
+ "NavTrigger",
16
+ "Content",
17
+ "Scroller",
18
+ "Aside"
19
+ ],
20
+ "parts": [
21
+ {
22
+ "name": "Root",
23
+ "usage": "AppShell.Root",
24
+ "description": "The frame: one viewport tall, a column, and the only element on the page that\nknows how tall the window is.\n\n`h-dvh`, not `min-h-dvh`. A console is a fixed frame with a scrolling middle;\na shell that grows past the viewport puts the status bar below the fold, where\na status bar is worthless. Everything under here is either `shrink-0` (the\nbars) or `min-h-0 flex-1` (the middle), which is what keeps the document\nitself from ever scrolling.\n\n`relative overflow-clip` is the other half of that promise, and it took a\nbrowser to find. The flex arithmetic only governs boxes *in the flow*: an\nabsolutely positioned descendant is laid out against its containing block,\nand a frame that is neither positioned nor clipping is not one — so the\ninitial containing block is, and the descendant's scrollable overflow lands\non `<html>`. `.sr-only` is the everyday case (it is `position: absolute`, and\nmost emitters give it no positioned ancestor), which is how a page carrying\na few thousand visually-hidden labels made the document 46,760px tall inside\na frame exactly one viewport high, with every visible box still on screen:\na browser scrollbar that scrolled nothing.\n\n`relative` makes the frame that containing block; the clip is then the\nguarantee, whatever any descendant leaks. `overflow-clip` rather than\n`overflow-hidden` on purpose — `hidden` makes the frame a *scroll container*,\nso a focus ring or a `scrollIntoView()` on something just outside it can\nscroll the whole console sideways with no scrollbar to put it back. `clip`\ncannot be scrolled at all, which is what a frame wants.",
25
+ "props": [
26
+ {
27
+ "name": "navOpen",
28
+ "type": "boolean",
29
+ "required": false,
30
+ "defaultValue": null,
31
+ "description": "Whether the mobile navigation drawer is open, when controlled. Pass with `onNavOpenChange`."
32
+ },
33
+ {
34
+ "name": "defaultNavOpen",
35
+ "type": "boolean",
36
+ "required": false,
37
+ "defaultValue": "false",
38
+ "description": "Initial open state of the mobile navigation drawer when uncontrolled. Defaults to `false`."
39
+ },
40
+ {
41
+ "name": "onNavOpenChange",
42
+ "type": "((open: boolean) => void)",
43
+ "required": false,
44
+ "defaultValue": null,
45
+ "description": "Called with the next open state whenever the drawer is opened or dismissed."
46
+ }
47
+ ],
48
+ "typeReferences": [
49
+ "React.ComponentPropsWithoutRef<\"div\">"
50
+ ]
51
+ },
52
+ {
53
+ "name": "Body",
54
+ "usage": "AppShell.Body",
55
+ "description": "The middle row: navigation column, content column, and anything else that\nsits beside them.\n\n`min-h-0` is the whole point. A flex child defaults to `min-height: auto`,\nwhich refuses to shrink below its content, so without it the first table\ntaller than the frame pushes the status bar off the bottom of the screen.\n`min-w-0` is the same argument one axis over, for the row that holds it.",
56
+ "props": [],
57
+ "typeReferences": [
58
+ "React.ComponentPropsWithoutRef<\"div\">"
59
+ ]
60
+ },
61
+ {
62
+ "name": "Sidebar",
63
+ "usage": "AppShell.Sidebar",
64
+ "description": "The navigation, in both of its shapes: a column on a wide viewport and a\ndrawer on a narrow one, from one set of children.\n\n**This part carries the only viewport breakpoint in `@cueplusplus/ui`, and it\nis deliberate.** The rest of the library is intrinsically responsive —\n`min()` clamps, `auto-fill` grids, overflow scrollers — and density is never\nviewport-driven. Navigation shape is the one decision that cannot be made\nthat way: `Sidebar.Root` is 14rem wide, a phone is 390px, and no amount of\nclamping turns a column into a drawer. So the switch is Tailwind's stock\n`md` (48rem), used **only** here and in {@link AppShellNavTrigger}, for\nnav shape and nothing else. Anything beyond nav shape stays intrinsic; a\nlater component that wants a breakpoint is a new decision, not a precedent\nthis one set.\n\nIt is a CSS-only dual render: both shapes are in the markup and one is hidden\nper viewport. No `useMediaQuery`, no hook, no JavaScript branch — so the\nfirst server-rendered frame is already correct and there is nothing to flash.\n\n`children` is rendered into both, so a console has one navigation definition\nand two presentations. Inside the drawer the items are not wrapped in a\n`Sidebar.Root`, which is what makes their labels stay visible there even when\nthe desktop column is collapsed to its rail — collapse is a property of the\ncolumn, not of the navigation, and the rail is drawn by the shell rather than\ntaken as a child for exactly that reason.\n\n**Both halves announce as the same landmark**, from the one `landmark` prop:\nthe same navigation cannot be `navigation` on a phone and `complementary` on\na laptop, and until the prop existed it was, because the drawer was a `<nav>`\nand `Sidebar.Root` was an `<aside>`. `\"navigation\"` is the default, which is\nwhat a shell's primary column nearly always is.",
65
+ "props": [
66
+ {
67
+ "name": "drawerTitle",
68
+ "type": "ReactNode",
69
+ "required": false,
70
+ "defaultValue": "Navigation",
71
+ "description": "The drawer's heading, and its accessible name. Defaults to `\"Navigation\"`."
72
+ },
73
+ {
74
+ "name": "closeLabel",
75
+ "type": "string",
76
+ "required": false,
77
+ "defaultValue": "Close navigation",
78
+ "description": "Accessible name for the drawer's close affordance. Defaults to `\"Close navigation\"`."
79
+ },
80
+ {
81
+ "name": "drawerClassName",
82
+ "type": "string",
83
+ "required": false,
84
+ "defaultValue": null,
85
+ "description": "Extra classes for the drawer's popup surface."
86
+ },
87
+ {
88
+ "name": "collapsible",
89
+ "type": "boolean",
90
+ "required": false,
91
+ "defaultValue": "true",
92
+ "description": "Draw the column's collapse rail. Defaults to `true`.\n\nThe shell renders the `Sidebar.Rail` itself rather than taking one in\n`children`, because collapsing is a property of the *column* and the same\nchildren are also the drawer's: a rail passed as a child would be laid out\ninside the overlay, where there is nothing to collapse."
93
+ },
94
+ {
95
+ "name": "landmark",
96
+ "type": "\"complementary\" | \"navigation\"",
97
+ "required": false,
98
+ "defaultValue": "navigation",
99
+ "description": "Which landmark **both** shapes announce as. Defaults to `\"navigation\"`.\n\nOne prop rather than two, because the column and the drawer are one\nnavigation wearing two shapes: the answer cannot differ by viewport."
100
+ },
101
+ {
102
+ "name": "collapsed",
103
+ "type": "boolean",
104
+ "required": false,
105
+ "defaultValue": null,
106
+ "description": "Collapsed state when controlled. Pass with `onCollapsedChange`."
107
+ },
108
+ {
109
+ "name": "defaultCollapsed",
110
+ "type": "boolean",
111
+ "required": false,
112
+ "defaultValue": "false",
113
+ "description": "Initial collapsed state when uncontrolled. Defaults to `false`."
114
+ },
115
+ {
116
+ "name": "onCollapsedChange",
117
+ "type": "((collapsed: boolean) => void)",
118
+ "required": false,
119
+ "defaultValue": null,
120
+ "description": "Called with the new collapsed state whenever the rail is pressed."
121
+ },
122
+ {
123
+ "name": "width",
124
+ "type": "string",
125
+ "required": false,
126
+ "defaultValue": "14rem",
127
+ "description": "Width while expanded. Any CSS length. Defaults to `\"14rem\"`."
128
+ },
129
+ {
130
+ "name": "collapsedWidth",
131
+ "type": "string",
132
+ "required": false,
133
+ "defaultValue": "3rem",
134
+ "description": "Width while collapsed. Any CSS length. Defaults to `\"3rem\"`."
135
+ }
136
+ ],
137
+ "typeReferences": [
138
+ "SidebarRootProps"
139
+ ]
140
+ },
141
+ {
142
+ "name": "NavTrigger",
143
+ "usage": "AppShell.NavTrigger",
144
+ "description": "The control that opens the navigation drawer. Put it in the shell's bar.\n\nPresent only below the same `md` breakpoint {@link AppShellSidebar} switches\non — above it the column is right there and a trigger would open a drawer\nduplicating navigation the reader can already see. That is the second and\nlast of the library's two viewport variants.\n\nIt is the one piece of window furniture in this library that defaults to\n`size=\"md\"` rather than `\"sm\"`, and the breakpoint above is the whole reason:\na control that only ever renders on a touch screen has to clear WCAG 2.5.8's\n24×24 floor, and `sm` is 20px.",
145
+ "props": [
146
+ {
147
+ "name": "label",
148
+ "type": "string",
149
+ "required": false,
150
+ "defaultValue": "Open navigation",
151
+ "description": "Accessible name for the control. Defaults to `\"Open navigation\"`."
152
+ },
153
+ {
154
+ "name": "icon",
155
+ "type": "ElementType<any, keyof IntrinsicElements>",
156
+ "required": false,
157
+ "defaultValue": "MenuGlyph",
158
+ "description": "The icon it draws. Defaults to the shell's own three-stroke glyph."
159
+ },
160
+ {
161
+ "name": "size",
162
+ "type": "\"sm\" | \"md\" | \"lg\"",
163
+ "required": false,
164
+ "defaultValue": "md",
165
+ "description": "Which rung of the control ladder the button takes. Defaults to `\"md\"`.\n\nThe rest of the window furniture in this library is built at `\"sm\"`, and\nthat is right for a mouse — but this control renders *only* below the `md`\nbreakpoint, which is to say only on a touch screen, where `sm` (20px at\nnormal density) is under the 24×24 CSS-pixel floor WCAG 2.2 SC 2.5.8 sets.\n`\"md\"` is 24px at normal and large, and the token layer's\n`@media (pointer: coarse)` rule lifts ultra-compact to the same 24px, so\nthe default clears the floor at every density a finger can reach it at."
166
+ }
167
+ ],
168
+ "typeReferences": [
169
+ "Omit<React.ComponentPropsWithoutRef<\"button\">, \"children\">"
170
+ ]
171
+ },
172
+ {
173
+ "name": "Content",
174
+ "usage": "AppShell.Content",
175
+ "description": "The content column beside the navigation, and the page's `<main>` landmark.\n\nA column rather than a scroller: a toolbar, a composer or a transport strip\nbelongs to the work area but must not move when it scrolls, so they are\nsiblings of {@link AppShellScroller} inside here. `min-w-0` is what stops a\ntable wider than the frame from shoving the navigation column off the screen.\n\nExactly one per shell.",
176
+ "props": [
177
+ {
178
+ "name": "main",
179
+ "type": "boolean",
180
+ "required": false,
181
+ "defaultValue": "true",
182
+ "description": "Render the `<main>` landmark. Defaults to `true`.\n\nSet it `false` when the shell is embedded in a document that already has a\n`<main>` — a specimen, a screenshot, a shell shown inside a device frame on\na page of prose. A document may have only one, and a nested one is a defect\nrather than a nicety."
183
+ }
184
+ ],
185
+ "typeReferences": [
186
+ "React.ComponentPropsWithoutRef<\"main\">"
187
+ ]
188
+ },
189
+ {
190
+ "name": "Scroller",
191
+ "usage": "AppShell.Scroller",
192
+ "description": "The one scroller on the page.\n\nNot the document. That is what keeps `TitleBar`, `Toolbar` and `StatusBar`\nwhere they are without a single `sticky`, and it is why the shell can promise\nthat the status bar is always on screen.",
193
+ "props": [
194
+ {
195
+ "name": "padded",
196
+ "type": "boolean",
197
+ "required": false,
198
+ "defaultValue": "true",
199
+ "description": "Draw the standard work-area gutters. Defaults to `true`."
200
+ }
201
+ ],
202
+ "typeReferences": [
203
+ "React.ComponentPropsWithoutRef<\"div\">"
204
+ ]
205
+ },
206
+ {
207
+ "name": "Aside",
208
+ "usage": "AppShell.Aside",
209
+ "description": "A secondary column on the trailing edge: an inspector, an agent roster, an\nanalyser.\n\nIts own scroller, deliberately. Reading the panel beside the work area must\nnever move the work area, which is the defect a shared scroller ships with.",
210
+ "props": [
211
+ {
212
+ "name": "width",
213
+ "type": "string",
214
+ "required": false,
215
+ "defaultValue": "18rem",
216
+ "description": "Width of the column. Any CSS length. Defaults to `\"18rem\"`."
217
+ }
218
+ ],
219
+ "typeReferences": [
220
+ "React.ComponentPropsWithoutRef<\"aside\">"
221
+ ]
222
+ }
223
+ ],
224
+ "variants": {},
225
+ "defaultVariants": {},
226
+ "tokensUsed": [
227
+ "--cue-bg",
228
+ "--cue-border",
229
+ "--cue-fg",
230
+ "--cue-space-3",
231
+ "--cue-space-4",
232
+ "--cue-space-5",
233
+ "--cue-surface-1"
234
+ ],
235
+ "summary": "The console frame: title bar, navigation, work area and status bar, one viewport tall with exactly one thing scrolling.",
236
+ "examples": [
237
+ {
238
+ "title": "The five parts",
239
+ "code": "<AppShell.Root>\n <TitleBar center=\"main-stage.cue\" actions={<Chip tone=\"ok\">live</Chip>}>\n <AppShell.NavTrigger />\n <Eyebrow>CUE++</Eyebrow>\n </TitleBar>\n\n <AppShell.Body>\n <AppShell.Sidebar aria-label=\"Console\" drawerTitle=\"Console\">\n <Sidebar.Section label=\"Show\">\n <Sidebar.Item icon={List} active>Cues</Sidebar.Item>\n <Sidebar.Item icon={Lightbulb} badge={<Chip>48</Chip>}>Fixtures</Sidebar.Item>\n </Sidebar.Section>\n </AppShell.Sidebar>\n\n <AppShell.Content>\n <Toolbar.Root aria-label=\"Playback\">\n <Toolbar.Button icon={Play}>Go</Toolbar.Button>\n </Toolbar.Root>\n <AppShell.Scroller>\n <Panel>…</Panel>\n </AppShell.Scroller>\n </AppShell.Content>\n\n <AppShell.Aside aria-label=\"Inspector\">…</AppShell.Aside>\n </AppShell.Body>\n\n <StatusBar>\n <StatusBar.Item tone=\"ok\">Art-Net 10.0.0.42</StatusBar.Item>\n <StatusBar.Item push>Cue 4</StatusBar.Item>\n </StatusBar>\n</AppShell.Root>",
240
+ "language": "tsx"
241
+ },
242
+ {
243
+ "title": "Where the footer goes",
244
+ "code": "<AppShell.Content>\n <AppShell.Scroller className=\"flex flex-col\">\n <div className=\"flex-1\">{children}</div>\n <Footer meta={…}>…</Footer>\n </AppShell.Scroller>\n</AppShell.Content>",
245
+ "language": "tsx"
246
+ },
247
+ {
248
+ "title": "The one breakpoint",
249
+ "code": "// One definition, two presentations. Nothing below is written twice.\n<AppShell.Sidebar aria-label=\"Console\" drawerTitle=\"Console\">\n <Sidebar.Section label=\"Show\">\n <Sidebar.Item icon={List} active>Cues</Sidebar.Item>\n </Sidebar.Section>\n</AppShell.Sidebar>",
250
+ "language": "tsx"
251
+ },
252
+ {
253
+ "title": "Usage",
254
+ "code": "<AppShell.Root>\n <TitleBar center=\"main-stage.cue\" actions={<Chip tone=\"ok\">live</Chip>}>\n <AppShell.NavTrigger />\n <Eyebrow>CUE++</Eyebrow>\n </TitleBar>\n <AppShell.Body>\n <AppShell.Sidebar aria-label=\"Console\" drawerTitle=\"Console\">\n <Sidebar.Section label=\"Show\">\n <Sidebar.Item icon={List} active>Cues</Sidebar.Item>\n </Sidebar.Section>\n </AppShell.Sidebar>\n <AppShell.Content>\n <Toolbar.Root aria-label=\"Playback\"><Toolbar.Button icon={Play}>Go</Toolbar.Button></Toolbar.Root>\n <AppShell.Scroller><Panel>…</Panel></AppShell.Scroller>\n </AppShell.Content>\n <AppShell.Aside aria-label=\"Inspector\">…</AppShell.Aside>\n </AppShell.Body>\n <StatusBar><StatusBar.Item tone=\"ok\">Art-Net</StatusBar.Item></StatusBar>\n</AppShell.Root>",
255
+ "language": "tsx"
256
+ }
257
+ ],
258
+ "status": "stable",
259
+ "url": "/docs/components/app-shell",
260
+ "mdUrl": "/docs/components/app-shell.md",
261
+ "jsonUrl": "/r/components/app-shell.json",
262
+ "whenToUse": [
263
+ "Any screen that fills the window and keeps its chrome on screen: a console, an editor, an agent run, a monitor wall.",
264
+ "Whenever a page needs a navigation column that has to survive a phone. `AppShell.Sidebar` renders the column and the drawer from one set of children.",
265
+ "As the frame around a full-bleed canvas — a graph, a timeline, a video wall — with no navigation column and no scroller at all."
266
+ ],
267
+ "whenNotToUse": [
268
+ "A page of prose, a form, or a table that reads better centred. That is `PageShell` (or `Container`), which sets a measure and lets the document scroll.",
269
+ "A depiction of an application inside another page — a hero image, a marketing screenshot. `AppWindowFrame` is the picture of a window; this is the window.",
270
+ "A single panel that happens to be tall. A shell that wraps one `Panel` is four wrappers doing the job of `h-full`."
271
+ ],
272
+ "commonMistakes": [
273
+ "Putting `Sidebar.Rail` in `AppShell.Sidebar`'s children. The shell draws the rail itself, into the column only — the same children are also the drawer's, where there is nothing to collapse.",
274
+ "Adding a second scroller. `AppShell.Scroller` is the only element that may scroll; giving `AppShell.Content` an `overflow-y-auto` too puts a scrollbar inside a scrollbar and detaches the toolbar from the work area.",
275
+ "Nesting a shell inside a page that already has a `<main>`. Pass `main={false}` on `AppShell.Content` — a document may have only one.",
276
+ "Reaching for a viewport variant of your own because the shell has one. The `md` switch is licensed for navigation shape and nothing else; everything else in this system is intrinsically responsive.",
277
+ "Ending the page with a `Footer` after `AppShell.Body`. A footer belongs to the content column — the last child of `AppShell.Scroller` — or it stretches under the navigation and pretends to be part of the frame."
278
+ ],
279
+ "specimens": [
280
+ {
281
+ "title": "AppShell",
282
+ "group": "chrome",
283
+ "components": [
284
+ "AppShell"
285
+ ],
286
+ "code": "<div className=\"w-full overflow-hidden rounded-(--radius-surface) border border-border\">\n {/* `h-[26rem]` overrides the shell's own `h-dvh`, and `main={false}`\n * keeps it from emitting a second `<main>` inside the page already\n * wrapping this corpus. Both are what embedding a whole-screen\n * component in a bench costs. */}\n <AppShell.Root className=\"h-[26rem]\">\n <TitleBar center=\"main-stage.cue\" actions={<Chip tone=\"ok\">live</Chip>}>\n <AppShell.NavTrigger />\n <Eyebrow>CUE++</Eyebrow>\n </TitleBar>\n\n <AppShell.Body>\n <AppShell.Sidebar aria-label=\"Console\" drawerTitle=\"Console\">\n <Sidebar.Section label=\"Show\">\n <Sidebar.Item icon={List} active>\n Cues\n </Sidebar.Item>\n <Sidebar.Item icon={Lightbulb} badge={<Chip>48</Chip>}>\n Fixtures\n </Sidebar.Item>\n </Sidebar.Section>\n </AppShell.Sidebar>\n\n <AppShell.Content main={false}>\n <Toolbar.Root aria-label=\"Cue list\">\n <Toolbar.Button icon={Plus}>Add cue</Toolbar.Button>\n <Toolbar.Separator />\n <Toolbar.Button icon={Monitor}>Live</Toolbar.Button>\n </Toolbar.Root>\n\n <AppShell.Scroller>\n <Panel>\n <PanelHeader title=\"Cue stack\" actions={<Chip tone=\"ok\">live</Chip>} />\n {CUES.map((cue) => (\n <Row key={cue.id}>\n <span className=\"w-[2rem] shrink-0 font-mono tabular-nums\">{cue.id}</span>\n <span className=\"flex-1 truncate\">{cue.label}</span>\n <span className=\"font-mono tabular-nums text-fg-muted\">{cue.time}</span>\n </Row>\n ))}\n </Panel>\n </AppShell.Scroller>\n </AppShell.Content>\n\n <AppShell.Aside aria-label=\"Inspector\" width=\"11rem\">\n <SectionHeader label=\"Selected\" />\n <p className=\"font-mono text-(length:--cue-text-ui) text-fg-muted\">\n Its own scroller, so reading it never moves the work area.\n </p>\n </AppShell.Aside>\n </AppShell.Body>\n\n <StatusBar>\n <StatusBar.Item tone=\"ok\">Art-Net</StatusBar.Item>\n <StatusBar.Item push>Cue 4</StatusBar.Item>\n </StatusBar>\n </AppShell.Root>\n</div>",
287
+ "note": "The console frame, and the arithmetic that holds it up: one viewport tall, an unbroken min-h-0 chain, and exactly one thing scrolling. Boxed to 26rem here — a bench has no viewport to give it.",
288
+ "interaction": "the 4px rail on the column's edge collapses it. Below 48rem the column is not rendered at all and the trigger in the title bar opens the same navigation as a drawer — the library's only viewport breakpoint, and it decides nothing but nav shape."
289
+ }
290
+ ]
291
+ }
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "AppWindowFrame",
3
+ "slug": "app-window-frame",
4
+ "group": "instruments",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": false,
8
+ "description": "A screenshot of your own app, built out of your own components.\n\nThe marketing device: title bar, optional toolbar, canvas, status bar — the\nshape of a desktop window, wrapped around real markup. Because the contents\nare components rather than a PNG, the hero image re-themes with the site, is\nlegible at any zoom, and cannot go stale the week after a redesign.\n\nBuilt from the real `TitleBar` and `StatusBar`, so the depiction and the\nproduct share one set of geometry tokens and can never drift apart.\n\nStatic markup — no `\"use client\"`.",
9
+ "props": [
10
+ {
11
+ "name": "title",
12
+ "type": "ReactNode",
13
+ "required": false,
14
+ "defaultValue": null,
15
+ "description": "The document name, centred in the title bar."
16
+ },
17
+ {
18
+ "name": "traffic",
19
+ "type": "boolean",
20
+ "required": false,
21
+ "defaultValue": "true",
22
+ "description": "Draw the three window lights. Defaults to `true`."
23
+ },
24
+ {
25
+ "name": "toolbar",
26
+ "type": "ReactNode",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Contents of the toolbar row under the title bar. Omit for no toolbar."
30
+ },
31
+ {
32
+ "name": "statusBar",
33
+ "type": "ReactNode",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "Contents of the status bar along the bottom. Omit for no status bar."
37
+ },
38
+ {
39
+ "name": "elevated",
40
+ "type": "boolean",
41
+ "required": false,
42
+ "defaultValue": "true",
43
+ "description": "Float the frame off the page with a drop shadow. Defaults to `true`.\n\nThis is the one flat-design exception in the kit, and it is not really an\nexception: the component *depicts a floating window*, which is exactly the\ncase the overlay shadow rule already carves out. Set it `false` when the\nframe is inlined into a page that is already a window."
44
+ },
45
+ {
46
+ "name": "children",
47
+ "type": "ReactNode",
48
+ "required": false,
49
+ "defaultValue": null,
50
+ "description": "What is inside the window."
51
+ }
52
+ ],
53
+ "typeReferences": [
54
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"title\">"
55
+ ],
56
+ "subcomponents": [],
57
+ "parts": [],
58
+ "variants": {},
59
+ "defaultVariants": {},
60
+ "tokensUsed": [
61
+ "--cue-bg",
62
+ "--cue-border",
63
+ "--cue-chrome-toolbar",
64
+ "--cue-danger",
65
+ "--cue-fg-muted",
66
+ "--cue-font-mono",
67
+ "--cue-ok",
68
+ "--cue-pad-row-x",
69
+ "--cue-radius-surface",
70
+ "--cue-space-2",
71
+ "--cue-space-3",
72
+ "--cue-space-6",
73
+ "--cue-surface-1",
74
+ "--cue-text-label",
75
+ "--cue-warn"
76
+ ],
77
+ "summary": "A screenshot of your own app, built out of your own components.",
78
+ "examples": [
79
+ {
80
+ "title": "Usage",
81
+ "code": "<AppWindowFrame\n title=\"main-stage.cue\"\n toolbar={<><Chip>File</Chip><Chip tone=\"ok\">Live</Chip></>}\n statusBar={<><StatusBar.Item tone=\"ok\">LIVE</StatusBar.Item><StatusBar.Item>30 pps</StatusBar.Item></>}\n>\n <SeamGrid columns={3}>{cells}</SeamGrid>\n</AppWindowFrame>",
82
+ "language": "tsx"
83
+ }
84
+ ],
85
+ "status": "todo-docs",
86
+ "url": "/docs/components/app-window-frame",
87
+ "mdUrl": "/docs/components/app-window-frame.md",
88
+ "jsonUrl": "/r/components/app-window-frame.json",
89
+ "specimens": [
90
+ {
91
+ "title": "AppWindowFrame",
92
+ "group": "instruments",
93
+ "components": [
94
+ "AppWindowFrame"
95
+ ],
96
+ "code": "<AppWindowFrame\n title=\"dmxhub — universe 1\"\n traffic\n elevated\n toolbar={\n <div className=\"flex items-center gap-(--cue-space-3)\">\n <Button size=\"sm\" icon={Play}>\n Go\n </Button>\n <Chip tone=\"ok\">44 Hz</Chip>\n <span className=\"flex-1\" />\n <IconButton aria-label=\"More\" icon={MoreVertical} size=\"sm\" variant=\"ghost\" />\n </div>\n }\n statusBar={\n <StatusBar>\n <StatusBar.Item tone=\"ok\">connected</StatusBar.Item>\n <StatusBar.Item push>10.0.0.42</StatusBar.Item>\n </StatusBar>\n }\n className=\"w-full max-w-[40rem]\"\n>\n <div className=\"p-(--cue-space-5)\">\n <Eyebrow>output</Eyebrow>\n <div className=\"mt-(--cue-space-4) flex flex-col gap-(--cue-space-3)\">\n {CHANNELS.map((channel) => (\n <Meter key={channel.name} percent={channel.level} tone={channel.tone} />\n ))}\n </div>\n </div>\n</AppWindowFrame>",
97
+ "note": "The marketing device: a window with traffic lights, a toolbar slot and a status bar slot, so a screenshot of a product looks like a product.",
98
+ "interaction": "none. The frame is scenery."
99
+ }
100
+ ],
101
+ "todo": true
102
+ }
@@ -0,0 +1,209 @@
1
+ {
2
+ "name": "AskBox",
3
+ "slug": "ask-box",
4
+ "group": "chat",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The human-in-the-loop question: an agent stops, asks, and waits.\n\nControlled by design. The box holds the *draft* answer while the user is\nchoosing, but it never holds the fact of having answered — that comes back as\nthe `answer` prop once the host has recorded it. Anything else and a\ncomponent's local state becomes the source of truth for a decision the run\ndepends on, which survives exactly until the pane unmounts.\n\nAnswered questions collapse to `question · answer ✓` and expand on click, so\na long thread reads as a decision log rather than a wall of settled forms.\n\nThe prompt is rendered verbatim, never parsed as markup: an approval prompt\ninterpolates model-controlled text, and a `![](url)` in a consent statement\nis an exfiltration channel.",
9
+ "props": [
10
+ {
11
+ "name": "question",
12
+ "type": "ReactNode",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "The question, as text or nodes. Rendered verbatim — never parsed."
16
+ },
17
+ {
18
+ "name": "kind",
19
+ "type": "\"number\" | \"boolean\" | \"text\" | \"single\" | \"multi\"",
20
+ "required": false,
21
+ "defaultValue": "text",
22
+ "description": "Which widget to offer. Defaults to `\"text\"`."
23
+ },
24
+ {
25
+ "name": "options",
26
+ "type": "readonly AskOption[]",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Choices for a `single` or `multi` question."
30
+ },
31
+ {
32
+ "name": "onAnswer",
33
+ "type": "(value: AskAnswer) => void",
34
+ "required": true,
35
+ "defaultValue": null,
36
+ "description": "Fired once with the answer. The host is responsible for resuming the run."
37
+ },
38
+ {
39
+ "name": "answer",
40
+ "type": "AskAnswer",
41
+ "required": false,
42
+ "defaultValue": null,
43
+ "description": "The answer, once there is one. Present means answered: the box collapses to\na one-line summary and stops accepting input."
44
+ },
45
+ {
46
+ "name": "asker",
47
+ "type": "string",
48
+ "required": false,
49
+ "defaultValue": null,
50
+ "description": "Slug of the agent asking, for the byline and the box's colour."
51
+ },
52
+ {
53
+ "name": "rootAgent",
54
+ "type": "string",
55
+ "required": false,
56
+ "defaultValue": null,
57
+ "description": "Slug of the orchestrator, so its questions take the theme accent."
58
+ },
59
+ {
60
+ "name": "tool",
61
+ "type": "string",
62
+ "required": false,
63
+ "defaultValue": null,
64
+ "description": "Tool this question is approving, if it is an approval."
65
+ },
66
+ {
67
+ "name": "danger",
68
+ "type": "\"low\" | \"high\" | \"critical\"",
69
+ "required": false,
70
+ "defaultValue": null,
71
+ "description": "Risk rating for the tool call. Omit for a plain question."
72
+ },
73
+ {
74
+ "name": "defaultValue",
75
+ "type": "AskAnswer",
76
+ "required": false,
77
+ "defaultValue": null,
78
+ "description": "Initial widget value. A string for `text`/`single`, an array for `multi`, a number for `number`."
79
+ },
80
+ {
81
+ "name": "placeholder",
82
+ "type": "string",
83
+ "required": false,
84
+ "defaultValue": null,
85
+ "description": "Placeholder for the `text` widget."
86
+ },
87
+ {
88
+ "name": "min",
89
+ "type": "number",
90
+ "required": false,
91
+ "defaultValue": null,
92
+ "description": "Lower bound for the `number` widget."
93
+ },
94
+ {
95
+ "name": "max",
96
+ "type": "number",
97
+ "required": false,
98
+ "defaultValue": null,
99
+ "description": "Upper bound for the `number` widget."
100
+ },
101
+ {
102
+ "name": "step",
103
+ "type": "number",
104
+ "required": false,
105
+ "defaultValue": null,
106
+ "description": "Increment the `number` widget's stepper moves by."
107
+ },
108
+ {
109
+ "name": "unit",
110
+ "type": "string",
111
+ "required": false,
112
+ "defaultValue": null,
113
+ "description": "Unit shown beside a number, and in the answered summary."
114
+ },
115
+ {
116
+ "name": "confirmLabel",
117
+ "type": "string",
118
+ "required": false,
119
+ "defaultValue": "Confirm",
120
+ "description": "Label on the affirmative half of a `boolean`. Defaults to `\"Confirm\"`."
121
+ },
122
+ {
123
+ "name": "rejectLabel",
124
+ "type": "string",
125
+ "required": false,
126
+ "defaultValue": "Reject",
127
+ "description": "Label on the negative half of a `boolean`. Defaults to `\"Reject\"`."
128
+ },
129
+ {
130
+ "name": "submitLabel",
131
+ "type": "ReactNode",
132
+ "required": false,
133
+ "defaultValue": "Submit",
134
+ "description": "Label on the submit button. Defaults to `\"Submit\"`."
135
+ },
136
+ {
137
+ "name": "busy",
138
+ "type": "boolean",
139
+ "required": false,
140
+ "defaultValue": "false",
141
+ "description": "The answer is in flight: locks the widget and says so."
142
+ },
143
+ {
144
+ "name": "defaultOpen",
145
+ "type": "boolean",
146
+ "required": false,
147
+ "defaultValue": "false",
148
+ "description": "Expand the answered summary from the start. Defaults to `false`."
149
+ },
150
+ {
151
+ "name": "aria-label",
152
+ "type": "string",
153
+ "required": false,
154
+ "defaultValue": null,
155
+ "description": "Accessible name for the widget when `question` is not plain text."
156
+ }
157
+ ],
158
+ "typeReferences": [
159
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"onSubmit\" | \"defaultValue\">"
160
+ ],
161
+ "subcomponents": [],
162
+ "parts": [],
163
+ "variants": {},
164
+ "defaultVariants": {},
165
+ "tokensUsed": [
166
+ "--cue-accent",
167
+ "--cue-border",
168
+ "--cue-fg",
169
+ "--cue-fg-muted",
170
+ "--cue-fg-subtle",
171
+ "--cue-font-mono",
172
+ "--cue-icon-sm",
173
+ "--cue-ok",
174
+ "--cue-radius-surface",
175
+ "--cue-space-2",
176
+ "--cue-space-3",
177
+ "--cue-space-4",
178
+ "--cue-surface-1",
179
+ "--cue-text-body",
180
+ "--cue-text-label",
181
+ "--cue-text-micro",
182
+ "--cue-text-ui"
183
+ ],
184
+ "summary": "The human-in-the-loop question: an agent stops, asks, and waits.",
185
+ "examples": [
186
+ {
187
+ "title": "Usage",
188
+ "code": "<AskBox question=\"Which merge mode?\" kind=\"single\" options={modes} onAnswer={resume} />\n<AskBox question=\"Delete the rig?\" kind=\"boolean\" tool=\"rig.delete\" danger=\"critical\" onAnswer={resume} />",
189
+ "language": "tsx"
190
+ }
191
+ ],
192
+ "status": "todo-docs",
193
+ "url": "/docs/components/ask-box",
194
+ "mdUrl": "/docs/components/ask-box.md",
195
+ "jsonUrl": "/r/components/ask-box.json",
196
+ "specimens": [
197
+ {
198
+ "title": "AskBox",
199
+ "group": "chat",
200
+ "components": [
201
+ "AskBox"
202
+ ],
203
+ "code": "<div className=\"grid w-full gap-(--cue-space-5) lg:grid-cols-2\">\n <AskBox\n question=\"Name the cue\"\n kind=\"text\"\n asker=\"cue-writer\"\n placeholder=\"e.g. House to half\"\n onAnswer={answer(\"text\")}\n answer={answers[\"text\"]}\n />\n <AskBox\n question=\"Which protocol should the bridge use?\"\n kind=\"single\"\n options={ASK_OPTIONS}\n asker=\"patcher\"\n onAnswer={answer(\"single\")}\n answer={answers[\"single\"]}\n />\n <AskBox\n question=\"Which universes should the archivist capture?\"\n kind=\"multi\"\n options={[\n { value: \"1\", label: \"Universe 1\" },\n { value: \"2\", label: \"Universe 2\" },\n { value: \"3\", label: \"Universe 3\" },\n ]}\n asker=\"archivist\"\n onAnswer={answer(\"multi\")}\n answer={answers[\"multi\"]}\n />\n <AskBox\n question=\"Unpatch every fixture on universe 4?\"\n kind=\"boolean\"\n danger=\"critical\"\n tool=\"unpatch\"\n asker=\"patcher\"\n confirmLabel=\"Unpatch\"\n rejectLabel=\"Keep\"\n onAnswer={answer(\"boolean\")}\n answer={answers[\"boolean\"]}\n />\n <AskBox\n question=\"Fade time for cue 4\"\n kind=\"number\"\n min={0}\n max={60}\n step={0.5}\n unit=\"s\"\n defaultValue={12}\n danger=\"low\"\n asker=\"cue-writer\"\n onAnswer={answer(\"number\")}\n answer={answers[\"number\"]}\n />\n <AskBox\n question=\"Overwrite the show file?\"\n kind=\"boolean\"\n danger=\"high\"\n busy\n asker=\"archivist\"\n onAnswer={answer(\"busy\")}\n />\n</div>",
204
+ "note": "The HITL question widget: five kinds, three danger levels, and a collapsed `question · answer ✓` summary once it is answered. Controlled through `onAnswer`, because the host owns the run.",
205
+ "interaction": "the danger chip is text as well as colour; an answered box collapses but stays expandable."
206
+ }
207
+ ],
208
+ "todo": true
209
+ }