@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,119 @@
1
+ {
2
+ "name": "TerminalFrame",
3
+ "slug": "terminal-frame",
4
+ "group": "instruments",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "A recessed terminal: mono, `$`-prefixed commands, optional typed playback.\n\nRecessed rather than raised — `bg-sunken` sits the transcript *into* the page\nthe way a real console does (the snuffle convention, where the terminal\nsurface is the only thing darker than the background).\n\nThe `simulate` player is deliberately not a GIF or a video: it is text, so it\ncopies, it scales with the type ramp, it re-themes, and it costs nothing to\nload. Keystrokes are jittered from a seed so a marketing screenshot is\nreproducible, and the whole animation is replaced by its final frame under\n`prefers-reduced-motion` — with no timers scheduled at all, rather than an\nanimation that runs invisibly.",
9
+ "props": [
10
+ {
11
+ "name": "title",
12
+ "type": "ReactNode",
13
+ "required": false,
14
+ "defaultValue": null,
15
+ "description": "Name above the transcript — a log file, a host, a task."
16
+ },
17
+ {
18
+ "name": "lines",
19
+ "type": "readonly TerminalFrameLine[]",
20
+ "required": false,
21
+ "defaultValue": null,
22
+ "description": "Static transcript. Rendered as a preamble when `simulate` is also set."
23
+ },
24
+ {
25
+ "name": "prompt",
26
+ "type": "string",
27
+ "required": false,
28
+ "defaultValue": "$",
29
+ "description": "The prompt glyph in front of a command line. Defaults to `\"$\"`."
30
+ },
31
+ {
32
+ "name": "copy",
33
+ "type": "boolean",
34
+ "required": false,
35
+ "defaultValue": "false",
36
+ "description": "Show a `CopyButton` in the title bar for the commands in the transcript."
37
+ },
38
+ {
39
+ "name": "copyValue",
40
+ "type": "string",
41
+ "required": false,
42
+ "defaultValue": null,
43
+ "description": "What the copy button puts on the clipboard. Defaults to the command lines, one per line."
44
+ },
45
+ {
46
+ "name": "simulate",
47
+ "type": "TerminalScript",
48
+ "required": false,
49
+ "defaultValue": null,
50
+ "description": "Play the transcript out as a typed session.\n\nPass a stable reference (a module constant, or memoised) — the player\nrestarts whenever this prop changes identity. Under\n`prefers-reduced-motion` the finished transcript renders instantly and no\ntimer is ever scheduled."
51
+ },
52
+ {
53
+ "name": "height",
54
+ "type": "number",
55
+ "required": false,
56
+ "defaultValue": null,
57
+ "description": "Fixed body height in px at the 16px root. Leave unset to grow with the content."
58
+ },
59
+ {
60
+ "name": "children",
61
+ "type": "ReactNode",
62
+ "required": false,
63
+ "defaultValue": null,
64
+ "description": "Extra content under the transcript — an input row, a hint strip."
65
+ }
66
+ ],
67
+ "typeReferences": [
68
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"title\" | \"children\">"
69
+ ],
70
+ "subcomponents": [],
71
+ "parts": [],
72
+ "variants": {},
73
+ "defaultVariants": {},
74
+ "tokensUsed": [
75
+ "--cue-accent",
76
+ "--cue-border",
77
+ "--cue-control-md",
78
+ "--cue-danger",
79
+ "--cue-fg",
80
+ "--cue-fg-muted",
81
+ "--cue-fg-subtle",
82
+ "--cue-font-mono",
83
+ "--cue-info",
84
+ "--cue-ok",
85
+ "--cue-pad-row-x",
86
+ "--cue-radius-surface",
87
+ "--cue-space-3",
88
+ "--cue-space-5",
89
+ "--cue-sunken",
90
+ "--cue-text-label",
91
+ "--cue-text-ui",
92
+ "--cue-warn"
93
+ ],
94
+ "summary": "A recessed terminal: mono, `$`-prefixed commands, optional typed playback.",
95
+ "examples": [
96
+ {
97
+ "title": "Usage",
98
+ "code": "<TerminalFrame\n title=\"install\"\n copy\n lines={[{ text: \"pnpm add\nconst SCRIPT = { steps: [{ command: \"cue build\", pending: \"compiling\", output: [\"12 cues\"] }] };\n<TerminalFrame simulate={SCRIPT} />",
99
+ "language": "tsx"
100
+ }
101
+ ],
102
+ "status": "todo-docs",
103
+ "url": "/docs/components/terminal-frame",
104
+ "mdUrl": "/docs/components/terminal-frame.md",
105
+ "jsonUrl": "/r/components/terminal-frame.json",
106
+ "specimens": [
107
+ {
108
+ "title": "TerminalFrame",
109
+ "group": "instruments",
110
+ "components": [
111
+ "TerminalFrame"
112
+ ],
113
+ "code": "<div className=\"grid w-full gap-(--cue-space-5) lg:grid-cols-2\">\n <TerminalFrame\n title=\"install\"\n copy\n lines={[\n { text: \"pnpm add @cueplusplus/ui @cueplusplus/tokens\", command: true },\n \"+ @cueplusplus/ui\",\n \"+ @cueplusplus/tokens\",\n { text: \"done in 1.4s\", tone: \"ok\" },\n ]}\n />\n <TerminalFrame\n title=\"patch\"\n simulate={{\n seed: 7,\n keystrokeMs: 40,\n steps: [\n {\n command: \"cue patch --universe 1 --profile s4\",\n pending: \"resolving profile\",\n pendingMs: 400,\n output: [{ text: \"patched 8 channels\", tone: \"ok\" }],\n },\n ],\n }}\n />\n</div>",
114
+ "note": "A sunken mono frame with `$`-prefixed command lines and a copy affordance. `simulate` turns it into a typing player with jittered keystrokes.",
115
+ "interaction": "the reduced-motion path renders the finished transcript instantly rather than typing it."
116
+ }
117
+ ],
118
+ "todo": true
119
+ }
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "Textarea",
3
+ "slug": "textarea",
4
+ "group": "forms",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The multi-line text control.\n\nRendered through Base UI's `Field.Control`, so it joins a {@link Field } on the\nsame terms as {@link Input } — label wiring, `aria-describedby`, `data-invalid`\n— while still being a real `<textarea>`.\n\nWears the recessed chassis minus the fixed control height: a textarea's job is\nto be taller than one rung. Height comes from `rows`, and the user may drag it\ntaller (`resize-y`) but never wider, which would break the panel grid.",
9
+ "props": [
10
+ {
11
+ "name": "className",
12
+ "type": "string",
13
+ "required": false,
14
+ "defaultValue": null,
15
+ "description": "Extra classes, merged over the chassis."
16
+ },
17
+ {
18
+ "name": "rows",
19
+ "type": "number",
20
+ "required": false,
21
+ "defaultValue": "3",
22
+ "description": "Visible rows before the box starts scrolling. Defaults to `3`."
23
+ }
24
+ ],
25
+ "typeReferences": [
26
+ "React.ComponentPropsWithoutRef<\"textarea\">"
27
+ ],
28
+ "subcomponents": [],
29
+ "parts": [],
30
+ "variants": {},
31
+ "defaultVariants": {},
32
+ "tokensUsed": [
33
+ "--cue-accent",
34
+ "--cue-border",
35
+ "--cue-control-lg",
36
+ "--cue-control-md",
37
+ "--cue-control-sm",
38
+ "--cue-danger",
39
+ "--cue-fg",
40
+ "--cue-fg-subtle",
41
+ "--cue-font-mono",
42
+ "--cue-radius-control",
43
+ "--cue-space-3",
44
+ "--cue-space-4",
45
+ "--cue-space-5",
46
+ "--cue-sunken",
47
+ "--cue-text-body",
48
+ "--cue-text-label",
49
+ "--cue-text-ui"
50
+ ],
51
+ "summary": "The multi-line text control.",
52
+ "examples": [
53
+ {
54
+ "title": "Usage",
55
+ "code": "<Textarea placeholder=\"Notes for the operator\" />\n<Field><FieldLabel>Cue notes</FieldLabel><Textarea rows={6} /></Field>",
56
+ "language": "tsx"
57
+ }
58
+ ],
59
+ "status": "todo-docs",
60
+ "url": "/docs/components/textarea",
61
+ "mdUrl": "/docs/components/textarea.md",
62
+ "jsonUrl": "/r/components/textarea.json",
63
+ "specimens": [
64
+ {
65
+ "title": "Textarea",
66
+ "group": "forms",
67
+ "components": [
68
+ "Textarea"
69
+ ],
70
+ "code": "<div className=\"grid w-full gap-(--cue-space-5) lg:grid-cols-3\">\n <Textarea aria-label=\"Cue notes\" rows={3} defaultValue={\"House to half.\\nHold for VO.\"} />\n <Textarea aria-label=\"Empty notes\" rows={3} placeholder=\"Notes for the operator\" />\n <Textarea aria-label=\"Disabled notes\" rows={3} defaultValue=\"Read-only\" disabled />\n</div>",
71
+ "note": "The same chassis, grown to a block.",
72
+ "interaction": "same rim and ring as Input."
73
+ }
74
+ ],
75
+ "todo": true
76
+ }
@@ -0,0 +1,124 @@
1
+ {
2
+ "name": "ThemeConfigurator",
3
+ "slug": "theme-configurator",
4
+ "group": "configurator",
5
+ "importPath": "@cueplusplus/ui/configurator",
6
+ "peerDependencies": [
7
+ "react-aria-components"
8
+ ],
9
+ "clientOnly": true,
10
+ "description": "The floating theme configurator: the panel that edits the design system it is\ndrawn with.\n\nIt is a **component**, not a devtool bolted onto the kitchensink — mount it in\nany app behind a flag and a designer can retune that app's theme in place. The\nwhole thing rests on one rule, and the rule is what keeps it from being a toy:\n*everything it does is a `--cue-*` declaration in one stylesheet.* No inline\nstyles on the root, no parallel token vocabulary, no runtime theme engine. The\nCSS it exports is byte for byte the CSS the page is wearing, which is the only\nreason the export dialog can promise a round trip at all.\n\nWhat it owns:\n\n- **Preset, mode and density** are the provider's, driven through `useTheme()`\n so a switch restamps `<html>`, every portal, and the persisted preference.\n- **Colour, type and geometry overrides** go into\n `<style id=\"cue-configurator-overrides\">`, scoped so they win where they\n have to and lose where they should — the cascade reasoning is in\n `_overrides.ts`, and it is the interesting part of this group.\n- **Text scale and root zoom**, the two relief valves the density ladder is\n paired with.\n- **Its own placement**, furled state and every override, in `localStorage`\n under one key.\n\nRenders in place as a `position: fixed` region, so mount it inside the\nprovider — it needs the theme context — but outside any transformed ancestor,\nwhich would turn `fixed` into `absolute` and take the panel with the page.",
11
+ "props": [
12
+ {
13
+ "name": "position",
14
+ "type": "\"floating\" | \"docked-right\"",
15
+ "required": false,
16
+ "defaultValue": null,
17
+ "description": "Placement, controlled. Pair with `onPositionChange`."
18
+ },
19
+ {
20
+ "name": "defaultPosition",
21
+ "type": "\"floating\" | \"docked-right\"",
22
+ "required": false,
23
+ "defaultValue": "floating",
24
+ "description": "Initial placement. A stored one wins. Defaults to `\"floating\"`."
25
+ },
26
+ {
27
+ "name": "onPositionChange",
28
+ "type": "((position: ConfiguratorPosition) => void)",
29
+ "required": false,
30
+ "defaultValue": null,
31
+ "description": "Called when the user docks or floats the panel."
32
+ },
33
+ {
34
+ "name": "defaultCollapsed",
35
+ "type": "boolean",
36
+ "required": false,
37
+ "defaultValue": "false",
38
+ "description": "Start furled to the title bar. A stored value wins. Defaults to `false`."
39
+ },
40
+ {
41
+ "name": "storageKey",
42
+ "type": "string",
43
+ "required": false,
44
+ "defaultValue": "cue-configurator",
45
+ "description": "`localStorage` key holding the overrides, the placement and the zoom.\nDefaults to `\"cue-configurator\"`."
46
+ },
47
+ {
48
+ "name": "onChange",
49
+ "type": "((tokens: Record<string, string>) => void)",
50
+ "required": false,
51
+ "defaultValue": null,
52
+ "description": "Called with the full resolved `--cue-*` map — never a diff — whenever the\noverrides, the theme or the mode change, and once on mount."
53
+ },
54
+ {
55
+ "name": "zoomShortcuts",
56
+ "type": "boolean",
57
+ "required": false,
58
+ "defaultValue": "true",
59
+ "description": "Bind ⌘/Ctrl with `+`, `-` and `0` to the zoom valve. Defaults to `true`."
60
+ },
61
+ {
62
+ "name": "title",
63
+ "type": "ReactNode",
64
+ "required": false,
65
+ "defaultValue": "Theme",
66
+ "description": "Panel heading. Defaults to `\"Theme\"`."
67
+ },
68
+ {
69
+ "name": "className",
70
+ "type": "string",
71
+ "required": false,
72
+ "defaultValue": null,
73
+ "description": "Extra classes for the panel."
74
+ }
75
+ ],
76
+ "typeReferences": [],
77
+ "subcomponents": [],
78
+ "parts": [],
79
+ "variants": {},
80
+ "defaultVariants": {},
81
+ "tokensUsed": [
82
+ "--cue-accent",
83
+ "--cue-accent-soft",
84
+ "--cue-border",
85
+ "--cue-border-overlay",
86
+ "--cue-control-lg",
87
+ "--cue-control-sm",
88
+ "--cue-fg",
89
+ "--cue-fg-muted",
90
+ "--cue-fg-subtle",
91
+ "--cue-font-mono",
92
+ "--cue-font-pairing-mono",
93
+ "--cue-font-sans",
94
+ "--cue-font-scale",
95
+ "--cue-font-theme-mono",
96
+ "--cue-icon-sm",
97
+ "--cue-radius-control",
98
+ "--cue-radius-overlay",
99
+ "--cue-radius-scale",
100
+ "--cue-scrim",
101
+ "--cue-space-1",
102
+ "--cue-space-2",
103
+ "--cue-space-3",
104
+ "--cue-space-4",
105
+ "--cue-space-5",
106
+ "--cue-surface-2",
107
+ "--cue-text-emphasis",
108
+ "--cue-text-label",
109
+ "--cue-text-ui"
110
+ ],
111
+ "summary": "The floating theme configurator: the panel that edits the design system it is drawn with.",
112
+ "examples": [
113
+ {
114
+ "title": "Usage",
115
+ "code": "<ThemeProvider>\n <App />\n {devMode ? <ThemeConfigurator /> : null}\n</ThemeProvider>\n<ThemeConfigurator position=\"docked-right\" onChange={(tokens) => report(tokens)} />",
116
+ "language": "tsx"
117
+ }
118
+ ],
119
+ "status": "todo-docs",
120
+ "url": "/docs/components/theme-configurator",
121
+ "mdUrl": "/docs/components/theme-configurator.md",
122
+ "jsonUrl": "/r/components/theme-configurator.json",
123
+ "todo": true
124
+ }
@@ -0,0 +1,134 @@
1
+ {
2
+ "name": "ThemeProvider",
3
+ "slug": "theme-provider",
4
+ "group": "system",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "Root of the theme system: stamps `data-theme`, `data-density` and `data-mode`\nso the token layer resolves, puts `data-font` on `<html>`, publishes\n`--cue-font-scale`, and owns the persisted user preference.\n\nRendering: `<div data-cue-root data-theme data-density data-mode style={{ colorScheme, --cue-font-scale }}>`\n(or the single child when `asChild`). The `theme`/`density`/`font`/`mode` props are\n*initial* values — the provider holds the state so `setTheme` and friends can\ndrive it — but a changed prop is adopted after mount, so a controlling parent\nstill works.\n\nThe font pairing is the one axis that never lands on this element: it has no\nisland form, `<html>` is its only home, and restating it here would shadow the\npre-paint stamp for the whole page on the first frame. See the `stamp` object\nbelow.\n\nPersistence and the pre-paint contract: setters write\n`{ theme, density, font, mode }` to `localStorage[storageKey]`, which is exactly what\n{@link prepaintScript } reads to stamp `<html>` before the first paint. The\noutermost provider keeps `<html>` in sync while the app runs (and restores the\nprevious stamp on unmount) so the page ground, UA scrollbars and form controls\nfollow the theme; nested providers never touch `<html>`, and never own the\nfont pairing — `useTheme().font` and `setFont` inside one are the root's.",
9
+ "props": [
10
+ {
11
+ "name": "theme",
12
+ "type": "\"terminal\" | \"signal\" | \"cue\" | \"venu\" | \"hivehub\" | \"dusk\" | \"luma\" | \"snuffle\" | \"requestport\" | \"quotamate\"",
13
+ "required": false,
14
+ "defaultValue": "cue",
15
+ "description": "Initial theme preset. Defaults to `\"cue\"`. Changing it after mount adopts the new value."
16
+ },
17
+ {
18
+ "name": "density",
19
+ "type": "\"ultra-compact\" | \"compact\" | \"normal\" | \"large\" | \"ultra-large\"",
20
+ "required": false,
21
+ "defaultValue": "compact",
22
+ "description": "Initial density level. Defaults to `\"compact\"`."
23
+ },
24
+ {
25
+ "name": "mode",
26
+ "type": "\"system\" | \"dark\" | \"light\"",
27
+ "required": false,
28
+ "defaultValue": "dark",
29
+ "description": "Initial mode. Defaults to `\"dark\"`; `\"system\"` tracks `prefers-color-scheme`."
30
+ },
31
+ {
32
+ "name": "font",
33
+ "type": "\"source\" | \"system\" | \"geist\" | \"inter\" | \"plex\" | \"roboto\" | \"apple\" | \"office\"",
34
+ "required": false,
35
+ "defaultValue": "DEFAULT_FONT",
36
+ "description": "Initial font pairing. Defaults to `\"system\"` — the platform's own faces,\nnothing downloaded, and the theme keeps whatever monospace it authored.\n\nA pairing that needs delivering is a set of *names*: this library ships no\nfont files, and a pairing nobody delivers falls through its stack to the\nplatform rather than failing. See `FONT_PAIRINGS[font].faces` for the\ncustom properties an app assigns to make one resolve.\n\n**Root-level only.** There is no font island: a nested provider forwards\nthis axis to the root, ignores this prop, and its `setFont` drives the root.\nA page that changed face halfway down is a page with a bug, and a specimen\nthat genuinely wants one — a picker row, a docs page showing all eight —\nneeds nothing from this library but `data-font` on a `<div>`."
37
+ },
38
+ {
39
+ "name": "fontScale",
40
+ "type": "number",
41
+ "required": false,
42
+ "defaultValue": "1",
43
+ "description": "Multiplier on every text token, published as `--cue-font-scale`. Defaults to `1`."
44
+ },
45
+ {
46
+ "name": "fontFamilies",
47
+ "type": "FontFamilies",
48
+ "required": false,
49
+ "defaultValue": null,
50
+ "description": "Optional app-owned font stacks, published as inline CUE font custom properties."
51
+ },
52
+ {
53
+ "name": "storageKey",
54
+ "type": "string",
55
+ "required": false,
56
+ "defaultValue": "cue-ui",
57
+ "description": "localStorage key holding `{ theme, density, font, mode }`. Defaults to `\"cue-ui\"`.\nOnly the outermost provider reads or writes it — a nested provider is an\nisland whose explicit props are the point, not a second preference store."
58
+ },
59
+ {
60
+ "name": "persistPreferences",
61
+ "type": "boolean",
62
+ "required": false,
63
+ "defaultValue": "true",
64
+ "description": "Restore and write root preferences in localStorage. Defaults to `true`."
65
+ },
66
+ {
67
+ "name": "asChild",
68
+ "type": "boolean",
69
+ "required": false,
70
+ "defaultValue": "false",
71
+ "description": "Stamp the single child element instead of rendering a wrapper `<div>`."
72
+ },
73
+ {
74
+ "name": "className",
75
+ "type": "string",
76
+ "required": false,
77
+ "defaultValue": null,
78
+ "description": "Extra classes for the provider root."
79
+ },
80
+ {
81
+ "name": "style",
82
+ "type": "CSSProperties",
83
+ "required": false,
84
+ "defaultValue": null,
85
+ "description": "Inline styles for the provider root, merged after the token style."
86
+ },
87
+ {
88
+ "name": "children",
89
+ "type": "ReactNode",
90
+ "required": false,
91
+ "defaultValue": null,
92
+ "description": "The application subtree."
93
+ }
94
+ ],
95
+ "typeReferences": [],
96
+ "subcomponents": [],
97
+ "parts": [],
98
+ "variants": {},
99
+ "defaultVariants": {},
100
+ "tokensUsed": [
101
+ "--cue-font-mono",
102
+ "--cue-font-sans",
103
+ "--cue-font-scale"
104
+ ],
105
+ "summary": "The root that stamps theme, density and mode, and publishes the setters.",
106
+ "examples": [
107
+ {
108
+ "title": "The document root",
109
+ "code": "<html lang=\"en\" suppressHydrationWarning>\n <head>\n <script dangerouslySetInnerHTML={{ __html: prepaintScript() }} />\n </head>\n <body>\n <ThemeProvider theme=\"terminal\" density=\"normal\">\n {children}\n </ThemeProvider>\n </body>\n</html>",
110
+ "language": "tsx"
111
+ },
112
+ {
113
+ "title": "Usage",
114
+ "code": "<ThemeProvider theme=\"terminal\" density=\"ultra-compact\" font=\"plex\" mode=\"system\">\n <App />\n</ThemeProvider>",
115
+ "language": "tsx"
116
+ }
117
+ ],
118
+ "status": "stable",
119
+ "url": "/docs/components/theme-provider",
120
+ "mdUrl": "/docs/components/theme-provider.md",
121
+ "jsonUrl": "/r/components/theme-provider.json",
122
+ "whenToUse": [
123
+ "Once at the root of an app, around everything that renders a component.",
124
+ "Around a subtree that has to render in a fixed preset, such as a theme preview pane."
125
+ ],
126
+ "whenNotToUse": [
127
+ "Changing geometry for one region. Use `Density`, which stamps the density attribute and leaves colour alone.",
128
+ "Holding app state. It owns theme, density and mode, and nothing else."
129
+ ],
130
+ "commonMistakes": [
131
+ "Leaving `prepaintScript()` out of the document head, which paints the default theme for one frame and then flips.",
132
+ "Mounting two providers on the same `storageKey`, which makes them fight over the stored preference."
133
+ ]
134
+ }
@@ -0,0 +1,160 @@
1
+ {
2
+ "name": "ThresholdRail",
3
+ "slug": "threshold-rail",
4
+ "group": "midi",
5
+ "importPath": "@cueplusplus/ui/midi",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The trigger level, set by dragging it along the signal it triggers on.\n\nA threshold is a number, and a number field would hold it perfectly well —\nbut a threshold is only ever chosen *relative to a signal*, and this control\nis the one place both are visible at once: the live level fills the rail, the\npeak-hold needle marks how far it got, and the handle sits where the trigger\nfires. Unified from ableton-sync's three near-identical threshold editors.\n\nTwo thresholds make it a window rather than a floor: supply `lower` and the\nrail arms *between* the handles, which is how a band-triggered cue avoids\nfiring on a peak it was never meant to catch.\n\nWhat the ports did not have is a keyboard. Their handles moved on `mousedown`\nplus a document listener, so a threshold could not be set by anyone not using\na mouse, and no screen reader was ever told what the number was. Here each\nhandle is a `role=\"slider\"` announcing a percentage, arrow keys step, page\nkeys jump, and Home/End go to the limits — the drag is the fast path, not the\nonly path.\n\nThe `onChange`/`onCommit` split is the same undo-coalescing contract as\n`Slider` and `ScrubInput`: one drag is one undo entry.",
9
+ "props": [
10
+ {
11
+ "name": "value",
12
+ "type": "number",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "The (upper) threshold, `0`–`1`. Always controlled."
16
+ },
17
+ {
18
+ "name": "onChange",
19
+ "type": "(value: number) => void",
20
+ "required": true,
21
+ "defaultValue": null,
22
+ "description": "Called with the next upper threshold."
23
+ },
24
+ {
25
+ "name": "lower",
26
+ "type": "number",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "The lower threshold. Supplying it turns the rail into a window."
30
+ },
31
+ {
32
+ "name": "onLowerChange",
33
+ "type": "((value: number) => void)",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "Called with the next lower threshold."
37
+ },
38
+ {
39
+ "name": "onCommit",
40
+ "type": "((thresholds: { upper: number; lower?: number; }) => void)",
41
+ "required": false,
42
+ "defaultValue": null,
43
+ "description": "Called once per finished gesture with both thresholds: pointer-up after a\ndrag, or each key step. Hang undo entries and network writes here —\n`onChange` fires on every frame of a drag."
44
+ },
45
+ {
46
+ "name": "level",
47
+ "type": "number",
48
+ "required": false,
49
+ "defaultValue": null,
50
+ "description": "Live signal level, `0`–`1`, drawn as a fill. Absent draws no fill."
51
+ },
52
+ {
53
+ "name": "peak",
54
+ "type": "number | null",
55
+ "required": false,
56
+ "defaultValue": null,
57
+ "description": "Peak-hold position, `0`–`1`. `null` or absent draws no needle."
58
+ },
59
+ {
60
+ "name": "step",
61
+ "type": "number",
62
+ "required": false,
63
+ "defaultValue": "0.01",
64
+ "description": "Grid the handles snap to. Defaults to `0.01`."
65
+ },
66
+ {
67
+ "name": "minGap",
68
+ "type": "number",
69
+ "required": false,
70
+ "defaultValue": "0.01",
71
+ "description": "Closest the two handles may get. Defaults to `0.01`."
72
+ },
73
+ {
74
+ "name": "belowTone",
75
+ "type": "\"accent\" | \"danger\" | \"busy\" | \"ok\" | \"warn\" | \"info\"",
76
+ "required": false,
77
+ "defaultValue": "danger",
78
+ "description": "Ink for the zones outside the window. Defaults to `\"danger\"`."
79
+ },
80
+ {
81
+ "name": "aboveTone",
82
+ "type": "\"accent\" | \"danger\" | \"busy\" | \"ok\" | \"warn\" | \"info\"",
83
+ "required": false,
84
+ "defaultValue": "ok",
85
+ "description": "Ink for the armed zone. Defaults to `\"ok\"`."
86
+ },
87
+ {
88
+ "name": "disabled",
89
+ "type": "boolean",
90
+ "required": false,
91
+ "defaultValue": "false",
92
+ "description": "Refuse every gesture."
93
+ },
94
+ {
95
+ "name": "label",
96
+ "type": "string",
97
+ "required": false,
98
+ "defaultValue": "Threshold",
99
+ "description": "What is being thresholded. Names the handles. Defaults to `\"Threshold\"`."
100
+ },
101
+ {
102
+ "name": "formatValue",
103
+ "type": "((value: number) => string)",
104
+ "required": false,
105
+ "defaultValue": "(fraction) => `${Math.round(fraction * 100)}%`",
106
+ "description": "Format a value for the handle's spoken text. Defaults to `\"62%\"`."
107
+ }
108
+ ],
109
+ "typeReferences": [
110
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"onChange\" | \"defaultValue\">"
111
+ ],
112
+ "subcomponents": [],
113
+ "parts": [],
114
+ "variants": {},
115
+ "defaultVariants": {},
116
+ "tokensUsed": [
117
+ "--cue-accent",
118
+ "--cue-accent-soft",
119
+ "--cue-bg",
120
+ "--cue-border",
121
+ "--cue-busy",
122
+ "--cue-busy-soft",
123
+ "--cue-control-sm",
124
+ "--cue-danger",
125
+ "--cue-danger-soft",
126
+ "--cue-fg",
127
+ "--cue-info",
128
+ "--cue-info-soft",
129
+ "--cue-ok",
130
+ "--cue-ok-soft",
131
+ "--cue-sunken",
132
+ "--cue-warn",
133
+ "--cue-warn-soft"
134
+ ],
135
+ "summary": "The trigger level, set by dragging it along the signal it triggers on.",
136
+ "examples": [
137
+ {
138
+ "title": "Usage",
139
+ "code": "<ThresholdRail value={threshold} onChange={setThreshold} level={rms} peak={peak} />\n<ThresholdRail value={high} lower={low} onChange={setHigh} onLowerChange={setLow} />",
140
+ "language": "tsx"
141
+ }
142
+ ],
143
+ "status": "todo-docs",
144
+ "url": "/docs/components/threshold-rail",
145
+ "mdUrl": "/docs/components/threshold-rail.md",
146
+ "jsonUrl": "/r/components/threshold-rail.json",
147
+ "specimens": [
148
+ {
149
+ "title": "ThresholdRail",
150
+ "group": "midi",
151
+ "components": [
152
+ "ThresholdRail"
153
+ ],
154
+ "code": "<div className=\"flex w-full flex-col gap-(--cue-space-6)\">\n <ThresholdRail\n value={upper}\n onChange={setUpper}\n lower={lower}\n onLowerChange={setLower}\n level={0.58}\n peak={0.81}\n label=\"Trigger thresholds\"\n />\n <ThresholdRail\n value={upper}\n onChange={setUpper}\n level={0.34}\n belowTone=\"info\"\n aboveTone=\"danger\"\n label=\"Single threshold\"\n />\n <ThresholdRail value={0.6} onChange={() => {}} disabled label=\"Threshold, locked\" />\n</div>",
155
+ "note": "A dual-handle rail with tone zones below and above, a level bar and a peak-hold needle.",
156
+ "interaction": "each handle is a slider with its own name; both scale up while dragging, and `onCommit` fires once on release."
157
+ }
158
+ ],
159
+ "todo": true
160
+ }