@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,76 @@
1
+ {
2
+ "name": "Sparkline",
3
+ "slug": "sparkline",
4
+ "group": "instruments",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": false,
8
+ "description": "A tiny unlabelled trace: \"is this climbing, or did it just reset?\".\n\nDeliberately answers nothing else — the numbers belong to the `Stat` or the\nrow above it. Two rules make it trustworthy at 72×14:\n\n1. **The scale is always 0–100.** A trace auto-scaled to its own range makes\n a flat 3% look identical to a flat 95%, which is the exact misreading a\n sparkline is supposed to prevent.\n2. **The stroke tone comes from the last value**, not from the shape, so the\n colour agrees with the `Chip` or `Meter` sitting next to it.\n\nUnder two points there is no line to draw, so it renders an empty box of the\nsame size rather than nothing: a row of sparklines keeps its column even\nwhile some series are still filling up.\n\nStatic markup — no `\"use client\"`.",
9
+ "props": [
10
+ {
11
+ "name": "values",
12
+ "type": "readonly number[]",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "The series, as percentages. Clamped to 0–100; never rescaled."
16
+ },
17
+ {
18
+ "name": "width",
19
+ "type": "number",
20
+ "required": false,
21
+ "defaultValue": "72",
22
+ "description": "Box width in px at the 16px root, emitted as `rem`. Defaults to `72`."
23
+ },
24
+ {
25
+ "name": "height",
26
+ "type": "number",
27
+ "required": false,
28
+ "defaultValue": "14",
29
+ "description": "Box height in px at the 16px root, emitted as `rem`. Defaults to `14`."
30
+ },
31
+ {
32
+ "name": "label",
33
+ "type": "string",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "The accessible name. Defaults to a sentence naming the latest value, which\nis the only number a trace this small can honestly report."
37
+ }
38
+ ],
39
+ "typeReferences": [
40
+ "Omit<React.SVGProps<SVGSVGElement>, \"values\" | \"width\" | \"height\" | \"children\" | \"ref\">"
41
+ ],
42
+ "subcomponents": [],
43
+ "parts": [],
44
+ "variants": {},
45
+ "defaultVariants": {},
46
+ "tokensUsed": [
47
+ "--cue-accent",
48
+ "--cue-danger",
49
+ "--cue-warn"
50
+ ],
51
+ "summary": "A tiny unlabelled trace: \"is this climbing, or did it just reset?\".",
52
+ "examples": [
53
+ {
54
+ "title": "Usage",
55
+ "code": "<Sparkline values={[12, 18, 30, 44, 61, 58, 72]} />",
56
+ "language": "tsx"
57
+ }
58
+ ],
59
+ "status": "todo-docs",
60
+ "url": "/docs/components/sparkline",
61
+ "mdUrl": "/docs/components/sparkline.md",
62
+ "jsonUrl": "/r/components/sparkline.json",
63
+ "specimens": [
64
+ {
65
+ "title": "Sparkline",
66
+ "group": "instruments",
67
+ "components": [
68
+ "Sparkline"
69
+ ],
70
+ "code": "<Specimens>\n <Specimen label=\"default\">\n <Sparkline values={[...TREND]} label=\"Output trend\" />\n </Specimen>\n <Specimen label=\"wide\">\n <Sparkline values={[...TREND]} width={220} height={32} label=\"Output trend, wide\" />\n </Specimen>\n <Specimen label=\"flat\">\n <Sparkline values={[40, 40, 40, 40, 40]} label=\"Flat\" />\n </Specimen>\n</Specimens>",
71
+ "note": "A trend at row height, drawn as one path with no axes and no tooltip. When it needs either, reach for UsageChart.",
72
+ "interaction": "none."
73
+ }
74
+ ],
75
+ "todo": true
76
+ }
@@ -0,0 +1,115 @@
1
+ {
2
+ "name": "SpectrumVisualizer",
3
+ "slug": "spectrum-visualizer",
4
+ "group": "midi",
5
+ "importPath": "@cueplusplus/ui/midi",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The FFT, drawn: one bar per frequency band, or one line across all of them.\n\nPorted from ableton-sync's analyser, with the colours taken off the caller's\nhands. The original asked for a `color` per band and defaulted to `#00FF00`\nwhen it did not get one, which is how an audio tool ends up with two\ndifferent greens for the same band in two different panels. Here the bands\n*are* the ramp — the same `BANDS_7`/`BANDS_10`/`BANDS_16`/`BANDS_31` the\n`/charts` subpath publishes — so bass is the same red in the analyser, in the\nlegend and in any chart of the same data.\n\nThose ramps are deliberately theme-independent (see `charts/ramps.tsx`): a\nlistener who has learnt \"bass is red\" must not have to relearn it because the\nconsole switched to a different accent. Everything *around* the data — the\ngrid, the line trace — does read tokens, and is resolved at paint time so a\ntheme switch needs no subscription.\n\nSelection dims rather than hides. A band that vanished when deselected would\nchange the shape of the spectrum, and the shape is the reading.",
9
+ "props": [
10
+ {
11
+ "name": "levels",
12
+ "type": "readonly number[] | Float32Array<ArrayBufferLike>",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "One level per band, `0`–`1`, in the ramp's own order.\n\nPositional rather than keyed by band id: an FFT hands back an array forty\ntimes a second, and building a lookup per frame to match it up is work for\nno information."
16
+ },
17
+ {
18
+ "name": "ramp",
19
+ "type": "readonly FrequencyBand[] | \"bands-7\" | \"bands-10\" | \"bands-16\" | \"bands-31\"",
20
+ "required": false,
21
+ "defaultValue": "bands-7",
22
+ "description": "The bands: a ramp from `/charts` by name, or a band list. Defaults to `\"bands-7\"`."
23
+ },
24
+ {
25
+ "name": "mode",
26
+ "type": "\"line\" | \"bars\"",
27
+ "required": false,
28
+ "defaultValue": "bars",
29
+ "description": "Bars or a line trace. Defaults to `\"bars\"`."
30
+ },
31
+ {
32
+ "name": "thresholds",
33
+ "type": "number | readonly number[]",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "Trigger levels to rule, one per band or one for all of them."
37
+ },
38
+ {
39
+ "name": "selected",
40
+ "type": "readonly string[]",
41
+ "required": false,
42
+ "defaultValue": null,
43
+ "description": "Band ids to keep bright. Empty or absent means every band is bright."
44
+ },
45
+ {
46
+ "name": "sensitivity",
47
+ "type": "number",
48
+ "required": false,
49
+ "defaultValue": "1",
50
+ "description": "Display gain applied to every level before drawing. Defaults to `1`."
51
+ },
52
+ {
53
+ "name": "height",
54
+ "type": "number",
55
+ "required": false,
56
+ "defaultValue": "96",
57
+ "description": "Graph height in px at the 16px root, emitted as `rem`. Defaults to `96`."
58
+ },
59
+ {
60
+ "name": "labels",
61
+ "type": "boolean",
62
+ "required": false,
63
+ "defaultValue": "true",
64
+ "description": "List the band names under the graph. Defaults to `true`."
65
+ },
66
+ {
67
+ "name": "label",
68
+ "type": "string",
69
+ "required": false,
70
+ "defaultValue": "Spectrum",
71
+ "description": "What is being analysed. Defaults to `\"Spectrum\"`."
72
+ }
73
+ ],
74
+ "typeReferences": [
75
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\">"
76
+ ],
77
+ "subcomponents": [],
78
+ "parts": [],
79
+ "variants": {},
80
+ "defaultVariants": {},
81
+ "tokensUsed": [
82
+ "--cue-accent",
83
+ "--cue-border",
84
+ "--cue-data-ground",
85
+ "--cue-font-mono",
86
+ "--cue-radius-control",
87
+ "--cue-space-1",
88
+ "--cue-text-micro"
89
+ ],
90
+ "summary": "The FFT, drawn: one bar per frequency band, or one line across all of them.",
91
+ "examples": [
92
+ {
93
+ "title": "Usage",
94
+ "code": "<SpectrumVisualizer levels={fft} ramp=\"bands-31\" thresholds={0.7} />",
95
+ "language": "tsx"
96
+ }
97
+ ],
98
+ "status": "todo-docs",
99
+ "url": "/docs/components/spectrum-visualizer",
100
+ "mdUrl": "/docs/components/spectrum-visualizer.md",
101
+ "jsonUrl": "/r/components/spectrum-visualizer.json",
102
+ "specimens": [
103
+ {
104
+ "title": "SpectrumVisualizer",
105
+ "group": "midi",
106
+ "components": [
107
+ "SpectrumVisualizer"
108
+ ],
109
+ "code": "<div className=\"flex w-full flex-col gap-(--cue-space-5)\">\n <SpectrumVisualizer levels={LEVELS} height={140} label=\"Seven-band analyser\" />\n <SpectrumVisualizer\n levels={LEVELS}\n mode=\"line\"\n thresholds={0.5}\n height={120}\n label=\"Seven-band analyser, line mode\"\n />\n <SpectrumVisualizer\n levels={LEVELS_31}\n ramp=\"bands-31\"\n selected={[\"sub\", \"bass\"]}\n labels={false}\n height={120}\n label=\"31-band analyser, bass selected\"\n />\n</div>",
110
+ "note": "Bars or line, with band colours taken from the /charts ramps. Those are literals on purpose: a listener who has learnt `bass is red` must not relearn it because the console switched accent.",
111
+ "interaction": "a selection dims the bands outside it rather than hiding them; thresholds are dashed rules per band."
112
+ }
113
+ ],
114
+ "todo": true
115
+ }
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "Spinner",
3
+ "slug": "spinner",
4
+ "group": "primitives",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "An indeterminate progress ring, drawn in CSS only — no SVG, no animation\nlibrary, one element.\n\nThe ring is a conic gradient masked to a hairline annulus, inked with\n`currentColor`, so it inherits whatever text colour surrounds it (a spinner\ninside a `danger` button is red without being told). Under\n`prefers-reduced-motion` the rotation stops and the ring stays as a static\narc rather than disappearing.",
9
+ "props": [
10
+ {
11
+ "name": "size",
12
+ "type": "\"sm\" | \"md\"",
13
+ "required": false,
14
+ "defaultValue": "md",
15
+ "description": "Rung of the density icon ladder to draw at. Defaults to `\"md\"`."
16
+ },
17
+ {
18
+ "name": "label",
19
+ "type": "string",
20
+ "required": false,
21
+ "defaultValue": "Loading",
22
+ "description": "Accessible label announced while the spinner is on screen. Defaults to `\"Loading\"`."
23
+ }
24
+ ],
25
+ "typeReferences": [
26
+ "Omit<React.ComponentPropsWithoutRef<\"span\">, \"children\">"
27
+ ],
28
+ "subcomponents": [],
29
+ "parts": [],
30
+ "variants": {},
31
+ "defaultVariants": {},
32
+ "tokensUsed": [
33
+ "--cue-icon-md",
34
+ "--cue-icon-sm"
35
+ ],
36
+ "summary": "An indeterminate progress ring, drawn in CSS only — no SVG, no animation library, one element.",
37
+ "examples": [
38
+ {
39
+ "title": "Usage",
40
+ "code": "<Spinner size=\"sm\" />\n<Button disabled><Spinner /> Rendering…</Button>",
41
+ "language": "tsx"
42
+ }
43
+ ],
44
+ "status": "todo-docs",
45
+ "url": "/docs/components/spinner",
46
+ "mdUrl": "/docs/components/spinner.md",
47
+ "jsonUrl": "/r/components/spinner.json",
48
+ "specimens": [
49
+ {
50
+ "title": "Spinner",
51
+ "group": "primitives",
52
+ "components": [
53
+ "Spinner"
54
+ ],
55
+ "code": "<Specimens>\n <Specimen label=\"sm\">\n <Spinner size=\"sm\" />\n </Specimen>\n <Specimen label=\"md\">\n <Spinner />\n </Specimen>\n <Specimen label=\"labelled\">\n <Spinner label=\"Reading show file\" />\n </Specimen>\n</Specimens>",
56
+ "note": "Two sizes. Carries a visually hidden label so a screen reader is told the wait, not left with a spinning div.",
57
+ "interaction": "stills under prefers-reduced-motion."
58
+ }
59
+ ],
60
+ "todo": true
61
+ }
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "Stack",
3
+ "slug": "stack",
4
+ "group": "layout",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": false,
8
+ "description": "One-dimensional layout: the flex row or column, with the gap tokenised.\n\nExists so that spacing between siblings is a density decision rather than a\nper-call-site guess. A `Stack gap={4}` is 8px at normal density and 6px at\nultra-compact without touching the markup, which is the whole point of the\ndensity system — and something `flex gap-2` written by hand quietly opts out\nof.\n\nStatic markup — no `\"use client\"`.",
9
+ "props": [
10
+ {
11
+ "name": "direction",
12
+ "type": "\"row\" | \"column\"",
13
+ "required": false,
14
+ "defaultValue": "column",
15
+ "description": "`\"column\"` (default) or `\"row\"`."
16
+ },
17
+ {
18
+ "name": "gap",
19
+ "type": "0 | 4 | 8 | 1 | 2 | 3 | 5 | 6 | 7",
20
+ "required": false,
21
+ "defaultValue": "4",
22
+ "description": "Which rung of the density space ladder to spend between children. Defaults to `4`."
23
+ },
24
+ {
25
+ "name": "align",
26
+ "type": "\"center\" | \"end\" | \"baseline\" | \"start\" | \"stretch\"",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Cross-axis alignment. Omit to inherit the flex default (`stretch`)."
30
+ },
31
+ {
32
+ "name": "justify",
33
+ "type": "\"center\" | \"end\" | \"start\" | \"between\"",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "Main-axis distribution. Omit to inherit the flex default (`start`)."
37
+ },
38
+ {
39
+ "name": "wrap",
40
+ "type": "boolean",
41
+ "required": false,
42
+ "defaultValue": "false",
43
+ "description": "Let a row wrap onto more lines."
44
+ },
45
+ {
46
+ "name": "inline",
47
+ "type": "boolean",
48
+ "required": false,
49
+ "defaultValue": "false",
50
+ "description": "Lay out as `inline-flex`, so the stack sits in a line of text."
51
+ }
52
+ ],
53
+ "typeReferences": [
54
+ "React.ComponentPropsWithoutRef<\"div\">"
55
+ ],
56
+ "subcomponents": [],
57
+ "parts": [],
58
+ "variants": {},
59
+ "defaultVariants": {},
60
+ "tokensUsed": [
61
+ "--cue-space-",
62
+ "--cue-space-1",
63
+ "--cue-space-2",
64
+ "--cue-space-3",
65
+ "--cue-space-4",
66
+ "--cue-space-5",
67
+ "--cue-space-6",
68
+ "--cue-space-7",
69
+ "--cue-space-8"
70
+ ],
71
+ "summary": "One-dimensional layout: the flex row or column, with the gap tokenised.",
72
+ "examples": [
73
+ {
74
+ "title": "Usage",
75
+ "code": "<Stack gap={5}><Panel /><Panel /></Stack>\n<Stack direction=\"row\" gap={2} align=\"center\"><StatusDot tone=\"ok\" />Online</Stack>",
76
+ "language": "tsx"
77
+ }
78
+ ],
79
+ "status": "todo-docs",
80
+ "url": "/docs/components/stack",
81
+ "mdUrl": "/docs/components/stack.md",
82
+ "jsonUrl": "/r/components/stack.json",
83
+ "specimens": [
84
+ {
85
+ "title": "Stack",
86
+ "group": "layout",
87
+ "components": [
88
+ "Stack"
89
+ ],
90
+ "code": "<Specimens>\n <Specimen label=\"row, gap 3\">\n <Stack direction=\"row\" gap={3}>\n <Chip>one</Chip>\n <Chip>two</Chip>\n <Chip>three</Chip>\n </Stack>\n </Specimen>\n <Specimen label=\"column, gap 5\">\n <Stack gap={5}>\n <Chip>one</Chip>\n <Chip>two</Chip>\n </Stack>\n </Specimen>\n <Specimen label=\"row, between\">\n <Stack direction=\"row\" justify=\"between\" className=\"w-[14rem]\">\n <Chip>left</Chip>\n <Chip>right</Chip>\n </Stack>\n </Specimen>\n</Specimens>",
91
+ "note": "Flex with the gap taken from a rung of the density ladder, never a length. That is what makes a layout tighten with the rest of the console.",
92
+ "interaction": "none."
93
+ }
94
+ ],
95
+ "todo": true
96
+ }
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "Stat",
3
+ "slug": "stat",
4
+ "group": "instruments",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": false,
8
+ "description": "One number, named: the console's KPI tile.\n\nReads label-first (micro, uppercase, tracked) so a row of tiles scans as a\nlist of captions with the readings underneath, and the value is set in\n`tabular-nums` mono so a changing number does not shuffle the layout under\nthe reader.\n\nOnly the value takes the tone. Tinting the caption too would make a red tile\nwhere the intent is a red *number* — the label is not the alarm.\n\nStatic markup — no `\"use client\"`.",
9
+ "props": [
10
+ {
11
+ "name": "label",
12
+ "type": "ReactNode",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "What is being measured. Rendered as a micro uppercase caption."
16
+ },
17
+ {
18
+ "name": "value",
19
+ "type": "ReactNode",
20
+ "required": true,
21
+ "defaultValue": null,
22
+ "description": "The reading itself — the one thing the eye should land on."
23
+ },
24
+ {
25
+ "name": "detail",
26
+ "type": "ReactNode",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Optional second line: a delta, a window, a unit."
30
+ },
31
+ {
32
+ "name": "tone",
33
+ "type": "\"accent\" | \"danger\" | \"busy\" | \"neutral\" | \"ok\" | \"warn\" | \"info\"",
34
+ "required": false,
35
+ "defaultValue": "neutral",
36
+ "description": "Tints the value only. Defaults to `\"neutral\"`."
37
+ }
38
+ ],
39
+ "typeReferences": [
40
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\">"
41
+ ],
42
+ "subcomponents": [],
43
+ "parts": [],
44
+ "variants": {},
45
+ "defaultVariants": {},
46
+ "tokensUsed": [
47
+ "--cue-accent",
48
+ "--cue-busy",
49
+ "--cue-danger",
50
+ "--cue-fg",
51
+ "--cue-fg-muted",
52
+ "--cue-fg-subtle",
53
+ "--cue-font-mono",
54
+ "--cue-info",
55
+ "--cue-ok",
56
+ "--cue-space-2",
57
+ "--cue-text-label",
58
+ "--cue-text-micro",
59
+ "--cue-text-title",
60
+ "--cue-warn"
61
+ ],
62
+ "summary": "One number, named: the console's KPI tile.",
63
+ "examples": [
64
+ {
65
+ "title": "Usage",
66
+ "code": "<Stat label=\"Universes\" value=\"512\" />\n<Stat label=\"Dropped frames\" value=\"12\" detail=\"last hour\" tone=\"danger\" />",
67
+ "language": "tsx"
68
+ }
69
+ ],
70
+ "status": "todo-docs",
71
+ "url": "/docs/components/stat",
72
+ "mdUrl": "/docs/components/stat.md",
73
+ "jsonUrl": "/r/components/stat.json",
74
+ "specimens": [
75
+ {
76
+ "title": "Stat",
77
+ "group": "instruments",
78
+ "components": [
79
+ "Stat"
80
+ ],
81
+ "code": "<div className=\"grid w-full gap-(--cue-space-4) sm:grid-cols-2 lg:grid-cols-4\">\n <Stat label=\"Universes\" value=\"4\" detail=\"of 8 patched\" />\n <Stat label=\"Latency\" value=\"7 ms\" detail=\"art-net\" tone=\"ok\" />\n <Stat label=\"Dropped\" value=\"0.4%\" detail=\"last hour\" tone=\"warn\" />\n <Stat label=\"Faults\" value=\"2\" detail=\"since 18:00\" tone=\"danger\" />\n</div>",
82
+ "note": "A label, a figure and a detail line. Figures are mono `tabular-nums`, so a changing digit never shifts the column.",
83
+ "interaction": "none."
84
+ }
85
+ ],
86
+ "todo": true
87
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "StatusBar",
3
+ "slug": "status-bar",
4
+ "group": "chrome",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": false,
8
+ "description": "The quiet strip along the bottom of a window.\n\nThe smallest type in the system in the subtlest ink: a status bar is read\nwhen you go looking for it and ignored otherwise, so it must never compete\nwith the work above it. Height comes from `--cue-chrome-statusbar`.\n\nNot a live region — a status bar changes constantly (frame counters, DMX\noutput), and announcing every change would make the app unusable with a\nscreen reader. Put anything that genuinely must be announced in a `Toast`.\n\nStatic markup — no `\"use client\"`.",
9
+ "props": [],
10
+ "typeReferences": [],
11
+ "subcomponents": [],
12
+ "parts": [],
13
+ "variants": {},
14
+ "defaultVariants": {},
15
+ "tokensUsed": [
16
+ "--cue-accent",
17
+ "--cue-border",
18
+ "--cue-busy",
19
+ "--cue-chrome-statusbar",
20
+ "--cue-danger",
21
+ "--cue-fg-subtle",
22
+ "--cue-font-mono",
23
+ "--cue-icon-sm",
24
+ "--cue-info",
25
+ "--cue-ok",
26
+ "--cue-pad-row-x",
27
+ "--cue-space-2",
28
+ "--cue-space-4",
29
+ "--cue-surface-1",
30
+ "--cue-text-label",
31
+ "--cue-warn"
32
+ ],
33
+ "summary": "The quiet strip along the bottom of a window.",
34
+ "examples": [
35
+ {
36
+ "title": "Usage",
37
+ "code": "<StatusBar>\n <StatusBar.Item icon={Plug} tone=\"ok\">Art-Net connected</StatusBar.Item>\n <StatusBar.Item push>512 channels</StatusBar.Item>\n</StatusBar>",
38
+ "language": "tsx"
39
+ }
40
+ ],
41
+ "status": "todo-docs",
42
+ "url": "/docs/components/status-bar",
43
+ "mdUrl": "/docs/components/status-bar.md",
44
+ "jsonUrl": "/r/components/status-bar.json",
45
+ "specimens": [
46
+ {
47
+ "title": "StatusBar",
48
+ "group": "chrome",
49
+ "components": [
50
+ "StatusBar"
51
+ ],
52
+ "code": "<div className=\"w-full overflow-hidden rounded-(--radius-surface) border border-border\">\n <StatusBar>\n <StatusBar.Item>universe 1</StatusBar.Item>\n <StatusBar.Item tone=\"ok\">44 Hz</StatusBar.Item>\n <StatusBar.Item tone=\"warn\">2 conflicts</StatusBar.Item>\n <StatusBar.Item push>10.0.0.42</StatusBar.Item>\n <StatusBar.Item tone=\"info\">art-net</StatusBar.Item>\n </StatusBar>\n</div>",
53
+ "note": "The bottom strip: tone-inked items, and a `push` item that takes the remaining space.",
54
+ "interaction": "none by default; items are plain readouts."
55
+ }
56
+ ],
57
+ "todo": true
58
+ }
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "StatusDot",
3
+ "slug": "status-dot",
4
+ "group": "primitives",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": false,
8
+ "description": "A 6px state dot — the densest possible status indicator.\n\nColour alone never carries meaning here: the dot is `aria-hidden` and the\ncomponent always emits an `sr-only` label inside a `role=\"status\"` wrapper,\nso the state is announced as well as shown (WCAG 1.4.1).\n\nThe wrapper is `relative` for that label's sake and no other reason.\n`.sr-only` is `position: absolute`; without a positioned ancestor its\ncontaining block is the initial one, so its scrollable overflow lands on\n`<html>` rather than on whatever scroller it is nested in. One dot is\nharmless and a table of two thousand rows is a document several thousand\npixels taller than anything visible on it.\n\nStatic markup — no `\"use client\"`.",
9
+ "props": [
10
+ {
11
+ "name": "tone",
12
+ "type": "\"idle\" | \"danger\" | \"busy\" | \"ok\" | \"warn\"",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "Which state to paint. `idle` renders a hollow ring."
16
+ },
17
+ {
18
+ "name": "pulse",
19
+ "type": "boolean",
20
+ "required": false,
21
+ "defaultValue": "false",
22
+ "description": "Pulse the dot to signal live activity. Automatically stilled under\n`prefers-reduced-motion`."
23
+ },
24
+ {
25
+ "name": "size",
26
+ "type": "number",
27
+ "required": false,
28
+ "defaultValue": "6",
29
+ "description": "Diameter in px at the default 16px root font size. Emitted as `rem`, so it\nscales with browser zoom and the user's font size. Defaults to `6`."
30
+ },
31
+ {
32
+ "name": "label",
33
+ "type": "string",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "Screen-reader text. Defaults to the tone name, which is usually the honest\nanswer; pass something specific when the surrounding row does not say it."
37
+ }
38
+ ],
39
+ "typeReferences": [
40
+ "Omit<React.ComponentPropsWithoutRef<\"span\">, \"children\">"
41
+ ],
42
+ "subcomponents": [],
43
+ "parts": [],
44
+ "variants": {},
45
+ "defaultVariants": {},
46
+ "tokensUsed": [
47
+ "--cue-busy",
48
+ "--cue-danger",
49
+ "--cue-fg-subtle",
50
+ "--cue-ok",
51
+ "--cue-warn"
52
+ ],
53
+ "summary": "A 6px state dot — the densest possible status indicator.",
54
+ "examples": [
55
+ {
56
+ "title": "Usage",
57
+ "code": "<StatusDot tone=\"ok\" />\n<StatusDot tone=\"busy\" pulse label=\"Rendering preview\" size={8} />",
58
+ "language": "tsx"
59
+ }
60
+ ],
61
+ "status": "todo-docs",
62
+ "url": "/docs/components/status-dot",
63
+ "mdUrl": "/docs/components/status-dot.md",
64
+ "jsonUrl": "/r/components/status-dot.json",
65
+ "specimens": [
66
+ {
67
+ "title": "StatusDot",
68
+ "group": "primitives",
69
+ "components": [
70
+ "StatusDot"
71
+ ],
72
+ "code": "<Specimens>\n {STATUS_TONES.map((tone) => (\n <Specimen key={tone} label={tone}>\n <StatusDot tone={tone} label={tone} />\n </Specimen>\n ))}\n <Specimen label=\"pulse\">\n <StatusDot tone=\"busy\" pulse label=\"Cueing\" />\n </Specimen>\n <Specimen label=\"size 10\">\n <StatusDot tone=\"ok\" size={10} label=\"Online\" />\n </Specimen>\n</Specimens>",
73
+ "note": "Five states, and the pulse that means work is in flight. The label is the accessible name, not decoration.",
74
+ "interaction": "none. A dot is a readout."
75
+ }
76
+ ],
77
+ "todo": true
78
+ }
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "Stepper",
3
+ "slug": "stepper",
4
+ "group": "layout",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The step trail: `1 target · 2 preview · 3 apply`.\n\nDeliberately a line of mono text rather than the usual row of numbered discs\njoined by rules. A stepper drawn as circles-and-lines is 60px tall and says\nexactly as much as one line of 9px type — and in a console that vertical\nspace belongs to the thing being configured, not to the wizard chrome around\nit. Only the numbers carry the accent, so the trail reads as one sentence\nwith the position marked, which is what a progress indicator is for.\n\nForward steps are never buttons: a step you have not reached is not a place\nyou can go, and offering it as a control is a promise the flow cannot keep.",
9
+ "props": [
10
+ {
11
+ "name": "steps",
12
+ "type": "readonly StepperStep[]",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "The steps, in order."
16
+ },
17
+ {
18
+ "name": "current",
19
+ "type": "string",
20
+ "required": true,
21
+ "defaultValue": null,
22
+ "description": "The `id` of the step in progress. An unknown id leaves every step upcoming."
23
+ },
24
+ {
25
+ "name": "onStepChange",
26
+ "type": "((id: string) => void)",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Called with the `id` of a step the user asked to go back to. Passing it\nturns the finished steps into buttons; leaving it off keeps the trail\nstatic, which is the honest rendering when the earlier steps cannot be\nrevisited."
30
+ },
31
+ {
32
+ "name": "separator",
33
+ "type": "ReactNode",
34
+ "required": false,
35
+ "defaultValue": "·",
36
+ "description": "What sits between steps. Defaults to `\"·\"`."
37
+ },
38
+ {
39
+ "name": "label",
40
+ "type": "string",
41
+ "required": false,
42
+ "defaultValue": "Progress",
43
+ "description": "The nav's accessible name. Defaults to `\"Progress\"`."
44
+ }
45
+ ],
46
+ "typeReferences": [
47
+ "Omit<React.ComponentPropsWithoutRef<\"nav\">, \"children\" | \"onChange\">"
48
+ ],
49
+ "subcomponents": [],
50
+ "parts": [],
51
+ "variants": {},
52
+ "defaultVariants": {},
53
+ "tokensUsed": [
54
+ "--cue-accent",
55
+ "--cue-fg",
56
+ "--cue-fg-muted",
57
+ "--cue-fg-subtle",
58
+ "--cue-font-mono",
59
+ "--cue-radius-control",
60
+ "--cue-space-2",
61
+ "--cue-space-3",
62
+ "--cue-text-label"
63
+ ],
64
+ "summary": "The step trail: `1 target · 2 preview · 3 apply`.",
65
+ "examples": [
66
+ {
67
+ "title": "Usage",
68
+ "code": "<Stepper steps={[{ id: \"target\", label: \"target\" }, { id: \"preview\", label: \"preview\" }]} current=\"preview\" />\n<Stepper steps={steps} current={step} onStepChange={setStep} />",
69
+ "language": "tsx"
70
+ }
71
+ ],
72
+ "status": "todo-docs",
73
+ "url": "/docs/components/stepper",
74
+ "mdUrl": "/docs/components/stepper.md",
75
+ "jsonUrl": "/r/components/stepper.json",
76
+ "specimens": [
77
+ {
78
+ "title": "Stepper",
79
+ "group": "layout",
80
+ "components": [
81
+ "Stepper"
82
+ ],
83
+ "code": "<Stepper steps={STEPS} current={step} onStepChange={setStep} />",
84
+ "note": "The step trail: `1 target · 2 preview · 3 apply`, with reached steps tinted rather than filled.",
85
+ "interaction": "a reached step is a button; an upcoming one is not."
86
+ }
87
+ ],
88
+ "todo": true
89
+ }