@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,139 @@
1
+ {
2
+ "name": "LogViewer",
3
+ "slug": "log-viewer",
4
+ "group": "instruments",
5
+ "importPath": "@cueplusplus/ui/instruments/log-viewer",
6
+ "peerDependencies": [
7
+ "@tanstack/react-virtual",
8
+ "anser"
9
+ ],
10
+ "clientOnly": true,
11
+ "description": "A virtualised log tail: ANSI colour, level filters, and stick-to-bottom.\n\nThe four things a log pane has to get right, and the reasons each one is not\noptional:\n\n- **Virtualised.** Five thousand DOM rows is a frozen tab. Rows are fixed at\n the short control rung so the virtualiser never has to measure, which is\n also what keeps the scrollbar honest while lines stream in.\n- **ANSI as data, never as HTML.** `anser` will happily hand back a markup\n string, and the moment that reaches `dangerouslySetInnerHTML` any process\n that prints a `<script>` owns the console watching it. Colour arrives here\n as spans of *text* with resolved token colours (see `_ansi.ts`).\n- **Following is a mode, not a scroll.** While pinned to the bottom the view\n follows; scroll up and it stops and starts counting, so reading something\n is never fought by the stream. The count comes back as a pill, not as a\n jump.\n- **A cap.** An unbounded buffer is a memory leak with a progress bar. The\n head is dropped past `maxLines`.\n\nShips from `@cueplusplus/ui/instruments/log-viewer`: it needs\n`@tanstack/react-virtual` and `anser`, both optional peers, and neither\nbelongs in the bundle of an app that renders no logs.",
12
+ "props": [
13
+ {
14
+ "name": "lines",
15
+ "type": "readonly LogLine[]",
16
+ "required": true,
17
+ "defaultValue": null,
18
+ "description": "The buffer, oldest first."
19
+ },
20
+ {
21
+ "name": "follow",
22
+ "type": "boolean",
23
+ "required": false,
24
+ "defaultValue": "true",
25
+ "description": "Stick to the bottom as lines arrive. Defaults to `true`."
26
+ },
27
+ {
28
+ "name": "filters",
29
+ "type": "false | readonly LogLevel[]",
30
+ "required": false,
31
+ "defaultValue": null,
32
+ "description": "Which levels get a filter chip. Defaults to the levels present in `lines`;\n`false` hides the strip entirely. Levels with no chip are always shown."
33
+ },
34
+ {
35
+ "name": "height",
36
+ "type": "number",
37
+ "required": true,
38
+ "defaultValue": null,
39
+ "description": "Viewer height in px at the 16px root."
40
+ },
41
+ {
42
+ "name": "rowHeight",
43
+ "type": "number",
44
+ "required": false,
45
+ "defaultValue": null,
46
+ "description": "Row height in px. Defaults to the short control rung at the ambient density."
47
+ },
48
+ {
49
+ "name": "maxLines",
50
+ "type": "number",
51
+ "required": false,
52
+ "defaultValue": "5000",
53
+ "description": "Cap on retained lines; the oldest are dropped. Defaults to `5000`."
54
+ },
55
+ {
56
+ "name": "formatTimestamp",
57
+ "type": "((ts: number) => string)",
58
+ "required": false,
59
+ "defaultValue": "defaultTimestamp",
60
+ "description": "Render a line's timestamp. Defaults to a local `HH:MM:SS`."
61
+ },
62
+ {
63
+ "name": "emptyLabel",
64
+ "type": "string",
65
+ "required": false,
66
+ "defaultValue": "No output",
67
+ "description": "What to say when there is nothing to show. Defaults to `\"No output\"`."
68
+ },
69
+ {
70
+ "name": "newLinesLabel",
71
+ "type": "((count: number) => string)",
72
+ "required": false,
73
+ "defaultValue": "(count) => `${count} new line${count === 1 ? \"\" : \"s\"}`",
74
+ "description": "Label for the catch-up pill. Defaults to `\"3 new lines\"`."
75
+ },
76
+ {
77
+ "name": "aria-label",
78
+ "type": "string",
79
+ "required": false,
80
+ "defaultValue": null,
81
+ "description": "Accessible name for the log region. Required in practice — name the stream."
82
+ }
83
+ ],
84
+ "typeReferences": [
85
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\" | \"onScroll\">"
86
+ ],
87
+ "subcomponents": [],
88
+ "parts": [],
89
+ "variants": {},
90
+ "defaultVariants": {},
91
+ "tokensUsed": [
92
+ "--cue-accent",
93
+ "--cue-border",
94
+ "--cue-border-overlay",
95
+ "--cue-danger",
96
+ "--cue-fg",
97
+ "--cue-fg-muted",
98
+ "--cue-fg-subtle",
99
+ "--cue-font-mono",
100
+ "--cue-info",
101
+ "--cue-ok",
102
+ "--cue-pad-row-x",
103
+ "--cue-radius-control",
104
+ "--cue-radius-surface",
105
+ "--cue-space-2",
106
+ "--cue-space-3",
107
+ "--cue-space-4",
108
+ "--cue-sunken",
109
+ "--cue-surface-1",
110
+ "--cue-surface-2",
111
+ "--cue-text-label",
112
+ "--cue-warn"
113
+ ],
114
+ "summary": "A virtualised log tail: ANSI colour, level filters, and stick-to-bottom.",
115
+ "examples": [
116
+ {
117
+ "title": "Usage",
118
+ "code": "<LogViewer aria-label=\"Build output\" height={320} lines={lines} />\n<LogViewer aria-label=\"Worker\" height={200} follow={false} filters={[\"warn\", \"error\"]} lines={lines} />",
119
+ "language": "tsx"
120
+ }
121
+ ],
122
+ "status": "todo-docs",
123
+ "url": "/docs/components/log-viewer",
124
+ "mdUrl": "/docs/components/log-viewer.md",
125
+ "jsonUrl": "/r/components/log-viewer.json",
126
+ "specimens": [
127
+ {
128
+ "title": "LogViewer",
129
+ "group": "instruments",
130
+ "components": [
131
+ "LogViewer"
132
+ ],
133
+ "code": "<div className=\"flex w-full flex-col gap-(--cue-space-5)\">\n <LogViewer lines={LOG_LINES} height={220} follow />\n <LogViewer lines={[]} height={120} emptyLabel={COPY.empty.title} />\n</div>",
134
+ "note": "Virtualised rows at the small control height, ANSI decoded to text nodes (never innerHTML), level filter chips, and a stick-to-bottom scroller that offers a `N new lines` pill once you scroll away.",
135
+ "interaction": "the filter chips are toggles; the new-lines pill is a button that returns you to the tail."
136
+ }
137
+ ],
138
+ "todo": true
139
+ }
@@ -0,0 +1,157 @@
1
+ {
2
+ "name": "Menubar",
3
+ "slug": "menubar",
4
+ "group": "overlays",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The desktop-application menu bar: a row of words, each dropping a menu.\n\nWraps Base UI's `Menubar` around the same `Menu` parts {@link DropdownMenu}\nuses, so the rows here *are* the dropdown's rows — one menu language across\nthe whole system — and the bar-level behaviour (hover to switch menus once one\nis open, arrow keys across the bar, typeahead inside a menu) is the\nprimitive's.\n\nUse it for an application shell that genuinely has a dozen-plus commands to\nfile away. A view with six actions wants a `Toolbar`; a menubar with two words\non it is a toolbar wearing a costume.",
9
+ "props": [],
10
+ "typeReferences": [],
11
+ "subcomponents": [
12
+ "Root",
13
+ "Menu",
14
+ "Trigger",
15
+ "Content"
16
+ ],
17
+ "parts": [
18
+ {
19
+ "name": "Root",
20
+ "usage": "Menubar.Root",
21
+ "description": "The bar itself: chrome-toolbar tall, hairline underneath, surface fill.\n\nSized from `--cue-chrome-toolbar` rather than the control ladder, exactly like\n`Toolbar` and `TitleBar` — a menubar is window furniture, and window furniture\nkeeps its own rung of the density scale so it stays legible when the controls\ninside the view shrink.",
22
+ "props": [
23
+ {
24
+ "name": "className",
25
+ "type": "string",
26
+ "required": false,
27
+ "defaultValue": null,
28
+ "description": "Extra classes for the bar."
29
+ }
30
+ ],
31
+ "typeReferences": [
32
+ "Omit<BaseMenubar.Props, \"className\">"
33
+ ]
34
+ },
35
+ {
36
+ "name": "Menu",
37
+ "usage": "Menubar.Menu",
38
+ "description": "One menu of the bar — its trigger and its content. Renders no element.\n\nBase UI reads the enclosing menubar from context: once one menu is open,\nhovering a sibling trigger switches to it without a second click, and the\narrow keys walk the bar. None of that needs wiring here.",
39
+ "props": [],
40
+ "typeReferences": [
41
+ "BaseMenu.Root.Props"
42
+ ]
43
+ },
44
+ {
45
+ "name": "Trigger",
46
+ "usage": "Menubar.Trigger",
47
+ "description": "A top-level word on the bar: `Show`, `Edit`, `View`.\n\nOpen is `accent-soft` plus full-strength ink, not a solid accent fill — the\nsame ruling as the active tab and the highlighted menu row. A filled block on\na bar of five words reads as a button someone left pressed.",
48
+ "props": [
49
+ {
50
+ "name": "className",
51
+ "type": "string",
52
+ "required": false,
53
+ "defaultValue": null,
54
+ "description": "Extra classes for the trigger."
55
+ }
56
+ ],
57
+ "typeReferences": [
58
+ "Omit<BaseMenu.Trigger.Props, \"className\">"
59
+ ]
60
+ },
61
+ {
62
+ "name": "Content",
63
+ "usage": "Menubar.Content",
64
+ "description": "One menu's portal, positioner and popup.\n\nAlways drops from the bottom of its word — a menubar menu that flipped\nupward would break the one spatial promise the pattern makes — and is\nportalled through {@link useCuePortalProps} so it renders at the caller's\ntheme and density.",
65
+ "props": [
66
+ {
67
+ "name": "className",
68
+ "type": "string",
69
+ "required": false,
70
+ "defaultValue": null,
71
+ "description": "Extra classes for the popup surface."
72
+ },
73
+ {
74
+ "name": "align",
75
+ "type": "\"center\" | \"end\" | \"start\"",
76
+ "required": false,
77
+ "defaultValue": "start",
78
+ "description": "Alignment along the bottom of the trigger. Defaults to `\"start\"`."
79
+ },
80
+ {
81
+ "name": "keepMounted",
82
+ "type": "boolean",
83
+ "required": false,
84
+ "defaultValue": null,
85
+ "description": "Keep the popup mounted while closed."
86
+ },
87
+ {
88
+ "name": "positionerClassName",
89
+ "type": "string",
90
+ "required": false,
91
+ "defaultValue": null,
92
+ "description": "Extra classes for the positioner that places the popup."
93
+ },
94
+ {
95
+ "name": "sideOffset",
96
+ "type": "number | OffsetFunction",
97
+ "required": false,
98
+ "defaultValue": "4",
99
+ "description": "Gap in px between trigger and popup. Defaults to `4`."
100
+ }
101
+ ],
102
+ "typeReferences": [
103
+ "Omit<BaseMenu.Popup.Props, \"className\">"
104
+ ]
105
+ }
106
+ ],
107
+ "variants": {},
108
+ "defaultVariants": {},
109
+ "tokensUsed": [
110
+ "--cue-accent",
111
+ "--cue-accent-soft",
112
+ "--cue-border",
113
+ "--cue-border-overlay",
114
+ "--cue-chrome-toolbar",
115
+ "--cue-control-sm",
116
+ "--cue-fg",
117
+ "--cue-fg-muted",
118
+ "--cue-fg-subtle",
119
+ "--cue-font-mono",
120
+ "--cue-radius-control",
121
+ "--cue-radius-overlay",
122
+ "--cue-scrim",
123
+ "--cue-space-1",
124
+ "--cue-space-2",
125
+ "--cue-space-3",
126
+ "--cue-surface-1",
127
+ "--cue-surface-2",
128
+ "--cue-text-emphasis",
129
+ "--cue-text-label",
130
+ "--cue-text-ui"
131
+ ],
132
+ "summary": "The desktop-application menu bar: a row of words, each dropping a menu.",
133
+ "examples": [
134
+ {
135
+ "title": "Usage",
136
+ "code": "<Menubar.Root>\n <Menubar.Menu>\n <Menubar.Trigger>Show</Menubar.Trigger>\n <Menubar.Content>\n <Menubar.Item onClick={newShow}>New show</Menubar.Item>\n <Menubar.Separator />\n <Menubar.Item trailing={<Kbd>⌘S</Kbd>} onClick={save}>Save</Menubar.Item>\n </Menubar.Content>\n </Menubar.Menu>\n</Menubar.Root>",
137
+ "language": "tsx"
138
+ }
139
+ ],
140
+ "status": "todo-docs",
141
+ "url": "/docs/components/menubar",
142
+ "mdUrl": "/docs/components/menubar.md",
143
+ "jsonUrl": "/r/components/menubar.json",
144
+ "specimens": [
145
+ {
146
+ "title": "Menubar",
147
+ "group": "overlays",
148
+ "components": [
149
+ "Menubar"
150
+ ],
151
+ "code": "<Menubar.Root>\n <Menubar.Menu>\n <Menubar.Trigger>File</Menubar.Trigger>\n <Menubar.Content>\n <Menubar.Item trailing={<Kbd>⌘N</Kbd>}>New show</Menubar.Item>\n <Menubar.Item trailing={<Kbd>⌘O</Kbd>}>Open</Menubar.Item>\n <Menubar.Separator />\n <Menubar.Item trailing={<Kbd>⌘S</Kbd>}>Save</Menubar.Item>\n </Menubar.Content>\n </Menubar.Menu>\n <Menubar.Menu>\n <Menubar.Trigger>View</Menubar.Trigger>\n <Menubar.Content>\n <Menubar.CheckboxItem checked={follow} onCheckedChange={setFollow}>\n Follow playhead\n </Menubar.CheckboxItem>\n <Menubar.Item>Reset zoom</Menubar.Item>\n </Menubar.Content>\n </Menubar.Menu>\n</Menubar.Root>",
152
+ "note": "The desktop bar: once one menu is open, hovering the next one opens it.",
153
+ "interaction": "left and right arrows move between menus, up and down move inside one."
154
+ }
155
+ ],
156
+ "todo": true
157
+ }
@@ -0,0 +1,100 @@
1
+ {
2
+ "name": "MessageList",
3
+ "slug": "message-list",
4
+ "group": "chat",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The transcript scroller: sticks to the bottom, and stops fighting you the\nmoment you scroll up.\n\nFollowing is a *mode*, not a scroll position. While pinned to the bottom the\nview follows new turns; scroll up to read something and it lets go and offers\na \"jump to latest\" pill instead — because a stream that yanks the viewport\nmid-sentence is the single most common reason people stop reading a chat\npane. Coming back to the bottom re-arms it.\n\nDeliberately **not** virtualised. A virtualiser needs a measurable row height\nand chat turns are variable-height by nature; the cost of getting that wrong\n(jumping scrollbars) is worse than the cost of a few hundred DOM nodes. When\na thread really is unbounded, page it — do not virtualise it.",
9
+ "props": [
10
+ {
11
+ "name": "children",
12
+ "type": "ReactNode",
13
+ "required": false,
14
+ "defaultValue": null,
15
+ "description": "The turns, oldest first — normally {@link Message }s."
16
+ },
17
+ {
18
+ "name": "follow",
19
+ "type": "boolean",
20
+ "required": false,
21
+ "defaultValue": "true",
22
+ "description": "Stick to the bottom as turns arrive. Defaults to `true`."
23
+ },
24
+ {
25
+ "name": "height",
26
+ "type": "number",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Fixed height in px at the 16px root, emitted as rem. Omit to fill the parent."
30
+ },
31
+ {
32
+ "name": "jumpLabel",
33
+ "type": "ReactNode",
34
+ "required": false,
35
+ "defaultValue": "Jump to latest",
36
+ "description": "Label on the catch-up pill. Defaults to `\"Jump to latest\"`."
37
+ },
38
+ {
39
+ "name": "emptyLabel",
40
+ "type": "ReactNode",
41
+ "required": false,
42
+ "defaultValue": "No messages yet",
43
+ "description": "What to say before the first turn. Defaults to `\"No messages yet\"`."
44
+ },
45
+ {
46
+ "name": "aria-label",
47
+ "type": "string",
48
+ "required": false,
49
+ "defaultValue": null,
50
+ "description": "Accessible name for the transcript. Required in practice — name the thread."
51
+ }
52
+ ],
53
+ "typeReferences": [
54
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"onScroll\">"
55
+ ],
56
+ "subcomponents": [],
57
+ "parts": [],
58
+ "variants": {},
59
+ "defaultVariants": {},
60
+ "tokensUsed": [
61
+ "--cue-accent",
62
+ "--cue-border-overlay",
63
+ "--cue-fg",
64
+ "--cue-fg-subtle",
65
+ "--cue-font-mono",
66
+ "--cue-icon-sm",
67
+ "--cue-radius-control",
68
+ "--cue-space-2",
69
+ "--cue-space-4",
70
+ "--cue-space-6",
71
+ "--cue-surface-2",
72
+ "--cue-text-label",
73
+ "--cue-text-ui"
74
+ ],
75
+ "summary": "The transcript scroller: sticks to the bottom, and stops fighting you the moment you scroll up.",
76
+ "examples": [
77
+ {
78
+ "title": "Usage",
79
+ "code": "<MessageList aria-label=\"Thread\" height={480}>\n {turns.map((t) => <Message key={t.id} agent={t.agent}>{t.text}</Message>)}\n</MessageList>",
80
+ "language": "tsx"
81
+ }
82
+ ],
83
+ "status": "todo-docs",
84
+ "url": "/docs/components/message-list",
85
+ "mdUrl": "/docs/components/message-list.md",
86
+ "jsonUrl": "/r/components/message-list.json",
87
+ "specimens": [
88
+ {
89
+ "title": "MessageList",
90
+ "group": "chat",
91
+ "components": [
92
+ "MessageList"
93
+ ],
94
+ "code": "<MessageList height={220} follow className=\"w-full max-w-[42rem]\">\n {Array.from({ length: 14 }, (_, index) => (\n <Message\n key={index}\n role={index % 2 === 0 ? \"user\" : \"agent\"}\n agent={index % 2 === 0 ? undefined : \"patcher\"}\n author={index % 2 === 0 ? \"Criss\" : \"Patcher\"}\n >\n Frame {index}: 512 slots at 44 Hz.\n </Message>\n ))}\n</MessageList>",
95
+ "note": "A stick-to-bottom scroller. Scroll away and it offers to jump back to the latest rather than yanking you there.",
96
+ "interaction": "the jump control is a button, and it appears only once you have actually scrolled off the tail."
97
+ }
98
+ ],
99
+ "todo": true
100
+ }
@@ -0,0 +1,116 @@
1
+ {
2
+ "name": "Message",
3
+ "slug": "message",
4
+ "group": "chat",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": false,
8
+ "description": "One turn in a conversation.\n\nContent is rendered as React nodes, verbatim: there is no markdown or HTML\npath here on purpose. Model output is untrusted text, and a component that\nquietly parsed it would make every consumer of this library one prompt away\nfrom an injection. Callers that want rich text pass their own renderer as\nchildren and own that decision.\n\nThe author line is mono micro and inked in the agent's own colour, so a\nmulti-agent thread is scannable by hue before it is readable by name.\n\nStatic markup — no `\"use client\"`; a transcript renders on the server.",
9
+ "props": [
10
+ {
11
+ "name": "role",
12
+ "type": "\"agent\" | \"user\" | \"system\"",
13
+ "required": false,
14
+ "defaultValue": "agent",
15
+ "description": "Who is speaking. Defaults to `\"agent\"`."
16
+ },
17
+ {
18
+ "name": "agent",
19
+ "type": "string",
20
+ "required": false,
21
+ "defaultValue": null,
22
+ "description": "The speaking agent's slug. Names the turn and inks the author line and the\n`--agent-color` custom property, which anything nested reads."
23
+ },
24
+ {
25
+ "name": "rootAgent",
26
+ "type": "string",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Slug of the orchestrator, so its turns take the theme accent."
30
+ },
31
+ {
32
+ "name": "author",
33
+ "type": "ReactNode",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "Author line override. Defaults to `\"You\"` for the user and to `agent` otherwise."
37
+ },
38
+ {
39
+ "name": "timestamp",
40
+ "type": "ReactNode",
41
+ "required": false,
42
+ "defaultValue": null,
43
+ "description": "Rendered opposite the author — pass a formatted time, not a `Date`."
44
+ },
45
+ {
46
+ "name": "pending",
47
+ "type": "boolean",
48
+ "required": false,
49
+ "defaultValue": "false",
50
+ "description": "The turn is still streaming: shows a caret and announces it."
51
+ },
52
+ {
53
+ "name": "footer",
54
+ "type": "ReactNode",
55
+ "required": false,
56
+ "defaultValue": null,
57
+ "description": "Slot under the body — attachments, warnings, retry actions."
58
+ },
59
+ {
60
+ "name": "children",
61
+ "type": "ReactNode",
62
+ "required": false,
63
+ "defaultValue": null,
64
+ "description": "The turn itself."
65
+ }
66
+ ],
67
+ "typeReferences": [
68
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"role\">"
69
+ ],
70
+ "subcomponents": [],
71
+ "parts": [],
72
+ "variants": {},
73
+ "defaultVariants": {},
74
+ "tokensUsed": [
75
+ "--cue-accent",
76
+ "--cue-accent-fg",
77
+ "--cue-border",
78
+ "--cue-fg",
79
+ "--cue-fg-subtle",
80
+ "--cue-font-mono",
81
+ "--cue-radius-control",
82
+ "--cue-radius-overlay",
83
+ "--cue-radius-scale",
84
+ "--cue-space-2",
85
+ "--cue-space-3",
86
+ "--cue-space-4",
87
+ "--cue-surface-1",
88
+ "--cue-text-body",
89
+ "--cue-text-micro"
90
+ ],
91
+ "summary": "One turn in a conversation.",
92
+ "examples": [
93
+ {
94
+ "title": "Usage",
95
+ "code": "<Message agent=\"researcher\" timestamp=\"14:02\">Found three references.</Message>\n<Message role=\"user\">Patch universe 3.</Message>",
96
+ "language": "tsx"
97
+ }
98
+ ],
99
+ "status": "todo-docs",
100
+ "url": "/docs/components/message",
101
+ "mdUrl": "/docs/components/message.md",
102
+ "jsonUrl": "/r/components/message.json",
103
+ "specimens": [
104
+ {
105
+ "title": "Message",
106
+ "group": "chat",
107
+ "components": [
108
+ "Message"
109
+ ],
110
+ "code": "<div className=\"flex w-full max-w-[42rem] flex-col gap-(--cue-space-4)\">\n <Message role=\"user\" author=\"Criss\" timestamp=\"18:04\">\n Patch the front truss on universe 1 and write a cue for house-to-half.\n </Message>\n <Message role=\"agent\" agent=\"patcher\" author=\"Patcher\" timestamp=\"18:04\">\n 6 fixtures patched to channels 1 to 48. Cue 1 written with a 3.0s fade.\n </Message>\n <Message role=\"agent\" agent=\"reviewer\" author=\"Reviewer\" pending>\n Checking the patch against the plot.\n </Message>\n <Message role=\"system\" timestamp=\"18:05\">\n Run paused: waiting on an answer.\n </Message>\n <Message\n role=\"agent\"\n agent=\"cue-writer\"\n author=\"Cue writer\"\n footer={<Chip tone=\"ok\">applied</Chip>}\n >\n Cue 2 follows cue 1 automatically.\n </Message>\n</div>",
111
+ "note": "Three roles. The bubble radii are asymmetric and mirrored by role, and the author line is mono micro. Nothing here parses markdown: model output is an untrusted string, and a component that rendered it as markup would make every consumer one prompt away from an injection.",
112
+ "interaction": "none. A message is a record."
113
+ }
114
+ ],
115
+ "todo": true
116
+ }
@@ -0,0 +1,114 @@
1
+ {
2
+ "name": "Meter",
3
+ "slug": "meter",
4
+ "group": "instruments",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": false,
8
+ "description": "A quota bar that shows **pace**, not just fill.\n\nA bare percentage answers \"how much is gone\" but not the question that\nactually matters: *will it last*. 93% used is fine in the last hour of a\nweekly window and an emergency on the first day. So the meter carries a\nsecond mark — how far through the window we are in time — and reads the two\ntogether: fill ahead of the tick is burning faster than the window refills.\n\nThe tick is deliberately quiet: a 1px rule, not a second bar. It annotates\nthe fill and stays ignorable when someone only wants the number.\n\nSeverity is never invented here — `tone` comes from whoever owns the\nthresholds. Likewise `provenance`: the bar changes its own texture rather\nthan letting an estimate or a missing denominator look like a measurement.\n\nThe over-pace pulse stills under `prefers-reduced-motion`; the state stays\nreadable as `data-over-pace`.\n\nStatic markup — no `\"use client\"`.",
9
+ "props": [
10
+ {
11
+ "name": "percent",
12
+ "type": "number",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "How full, 0–100. Clamped; a non-finite value reads as 0."
16
+ },
17
+ {
18
+ "name": "tone",
19
+ "type": "\"danger\" | \"busy\" | \"ok\" | \"warn\"",
20
+ "required": false,
21
+ "defaultValue": "ok",
22
+ "description": "Status colour for the fill. Defaults to `\"ok\"`."
23
+ },
24
+ {
25
+ "name": "paceTick",
26
+ "type": "number | null",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "How far through the window we are *by time*, 0–1. Drawn as a 1px rule\nacross the bar so the fill can be read against its pace: fill ahead of the\ntick means burning faster than the window refills. Pass `null` when there\nis no window."
30
+ },
31
+ {
32
+ "name": "empty",
33
+ "type": "boolean",
34
+ "required": false,
35
+ "defaultValue": "false",
36
+ "description": "Render the striped \"no data\" treatment instead of a level."
37
+ },
38
+ {
39
+ "name": "provenance",
40
+ "type": "\"none\" | \"vendor\" | \"estimated\" | \"unbounded\"",
41
+ "required": false,
42
+ "defaultValue": "vendor",
43
+ "description": "Where the ceiling came from. Defaults to `\"vendor\"`."
44
+ },
45
+ {
46
+ "name": "height",
47
+ "type": "number",
48
+ "required": false,
49
+ "defaultValue": "4",
50
+ "description": "Bar height in px at the 16px root, emitted as `rem`. Defaults to `4`."
51
+ },
52
+ {
53
+ "name": "label",
54
+ "type": "string",
55
+ "required": false,
56
+ "defaultValue": "Usage",
57
+ "description": "The accessible name. A meter is nearly always a usage readout, so that is\nthe default; override it for anything else. When there is no level to\nreport (`empty`, or an unbounded ceiling) the state is appended to it, as\nin `\"Usage: No data\"`."
58
+ }
59
+ ],
60
+ "typeReferences": [
61
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\">"
62
+ ],
63
+ "subcomponents": [],
64
+ "parts": [],
65
+ "variants": {},
66
+ "defaultVariants": {},
67
+ "tokensUsed": [
68
+ "--cue-bg",
69
+ "--cue-border",
70
+ "--cue-busy",
71
+ "--cue-danger",
72
+ "--cue-fg",
73
+ "--cue-ok",
74
+ "--cue-surface-3",
75
+ "--cue-warn"
76
+ ],
77
+ "summary": "A quota bar that shows pace, not just fill.",
78
+ "examples": [
79
+ {
80
+ "title": "Usage",
81
+ "code": "<Meter percent={72} tone=\"warn\" paceTick={0.5} />\n<Meter percent={0} empty label=\"Requests this month\" />\n<Meter percent={40} provenance=\"estimated\" />",
82
+ "language": "tsx"
83
+ }
84
+ ],
85
+ "status": "stable",
86
+ "url": "/docs/components/meter",
87
+ "mdUrl": "/docs/components/meter.md",
88
+ "jsonUrl": "/r/components/meter.json",
89
+ "whenToUse": [
90
+ "A bounded quantity against a ceiling: quota used, storage, a dimmer level.",
91
+ "When the reader needs to know whether usage is ahead of the clock. Pass `paceTick`."
92
+ ],
93
+ "whenNotToUse": [
94
+ "How far a task has got. Use `Progress`.",
95
+ "A number with no ceiling. Use `Stat`.",
96
+ "A value over time. Use `Sparkline` or `UsageChart`."
97
+ ],
98
+ "commonMistakes": [
99
+ "Passing a fraction. `percent` is 0-100, not 0-1.",
100
+ "Leaving `provenance` at `vendor` for a ceiling somebody typed. `estimated` hatches the bar, which is what keeps a guess from wearing the authority of a reported number."
101
+ ],
102
+ "specimens": [
103
+ {
104
+ "title": "Meter",
105
+ "group": "instruments",
106
+ "components": [
107
+ "Meter"
108
+ ],
109
+ "code": "<Panel className=\"w-full max-w-[36rem]\">\n {CHANNELS.map((channel) => (\n <Row key={channel.name} className=\"gap-(--cue-space-4)\">\n <span className=\"w-[7rem] shrink-0 truncate\">{channel.name}</span>\n <Meter percent={channel.level} tone={channel.tone} className=\"flex-1\" />\n <span className=\"w-[3rem] shrink-0 text-right font-mono tabular-nums\">\n {channel.level}%\n </span>\n </Row>\n ))}\n <Row className=\"gap-(--cue-space-4)\">\n <span className=\"w-[7rem] shrink-0 truncate\">Pace tick</span>\n <Meter percent={64} paceTick={50} className=\"flex-1\" label=\"64% used, 50% of period elapsed\" />\n </Row>\n <Row className=\"gap-(--cue-space-4)\">\n <span className=\"w-[7rem] shrink-0 truncate\">Estimated</span>\n <Meter percent={40} provenance=\"estimated\" className=\"flex-1\" />\n </Row>\n <Row className=\"gap-(--cue-space-4)\">\n <span className=\"w-[7rem] shrink-0 truncate\">Unbounded</span>\n <Meter percent={0} provenance=\"unbounded\" className=\"flex-1\" />\n </Row>\n <Row className=\"gap-(--cue-space-4)\">\n <span className=\"w-[7rem] shrink-0 truncate\">No data</span>\n <Meter percent={0} empty className=\"flex-1\" />\n </Row>\n</Panel>",
110
+ "note": "Never invents a number: an unbounded meter draws no percentage, an empty one draws stripes rather than a zero, and an estimated ceiling is hatched so it cannot pass for a measurement.",
111
+ "interaction": "the over-pace pulse stills under prefers-reduced-motion and stays readable as a data attribute."
112
+ }
113
+ ]
114
+ }