@cueplusplus/ui 0.15.0 → 0.17.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 (508) hide show
  1. package/CHANGELOG.md +1083 -0
  2. package/README.md +26 -0
  3. package/dist/agent-runtime/tool-call-card.js +7 -3
  4. package/dist/brand/_chassis.d.ts +1 -1
  5. package/dist/brand/cue-mark.d.ts +1 -1
  6. package/dist/brand/cue-mark.js +1 -1
  7. package/dist/charts/ramps.js +1 -1
  8. package/dist/chat/agent-pile.js +2 -1
  9. package/dist/chat/ask-box.js +4 -3
  10. package/dist/chat/delegation-card.js +3 -2
  11. package/dist/chat/message-list.js +4 -2
  12. package/dist/chat/message.js +17 -7
  13. package/dist/chrome/_edge-scroller.js +2 -1
  14. package/dist/chrome/_status-bar.js +9 -3
  15. package/dist/chrome/_tabs-scroll.d.ts +17 -1
  16. package/dist/chrome/_tabs-scroll.js +20 -3
  17. package/dist/chrome/app-bar.js +10 -3
  18. package/dist/chrome/app-shell.js +2 -1
  19. package/dist/chrome/band.d.ts +18 -12
  20. package/dist/chrome/band.js +19 -31
  21. package/dist/chrome/eyebrow.d.ts +13 -5
  22. package/dist/chrome/eyebrow.js +18 -7
  23. package/dist/chrome/footer.d.ts +5 -0
  24. package/dist/chrome/footer.js +14 -3
  25. package/dist/chrome/navigation-menu.js +4 -2
  26. package/dist/chrome/page-shell.js +8 -5
  27. package/dist/chrome/panel.d.ts +5 -2
  28. package/dist/chrome/panel.js +9 -4
  29. package/dist/chrome/row.js +6 -3
  30. package/dist/chrome/scroll-area.js +2 -1
  31. package/dist/chrome/section-header.js +13 -4
  32. package/dist/chrome/segmented-control.js +12 -3
  33. package/dist/chrome/status-bar.js +2 -1
  34. package/dist/chrome/tabs.js +11 -3
  35. package/dist/chrome/toolbar.js +2 -1
  36. package/dist/chrome/tree.js +3 -2
  37. package/dist/color/_thumb.js +9 -3
  38. package/dist/color/color-area.js +1 -1
  39. package/dist/color/color-field.d.ts +2 -1
  40. package/dist/color/color-picker.d.ts +2 -1
  41. package/dist/color/color-swatch.js +1 -1
  42. package/dist/configurator/_overrides.js +13 -4
  43. package/dist/configurator/configurator.js +4 -1
  44. package/dist/configurator/export-dialog.js +5 -2
  45. package/dist/configurator/panel-sections.js +6 -2
  46. package/dist/configurator/token-editor.js +4 -1
  47. package/dist/date/calendar.js +12 -8
  48. package/dist/date/date-field.d.ts +2 -1
  49. package/dist/date/date-picker.d.ts +2 -1
  50. package/dist/date/date-range-picker.d.ts +2 -1
  51. package/dist/date/time-field.d.ts +2 -1
  52. package/dist/dmx/channel-matrix.js +3 -2
  53. package/dist/dmx/dmx-bar.js +1 -1
  54. package/dist/dmx/dmx-strip.js +1 -1
  55. package/dist/dmx/universe-grid.js +3 -2
  56. package/dist/elements/activity-graph.js +3 -3
  57. package/dist/elements/agent-card.js +3 -3
  58. package/dist/elements/approval-card.js +3 -3
  59. package/dist/elements/artifact-card.js +2 -2
  60. package/dist/elements/background-inbox.js +2 -2
  61. package/dist/elements/canvas-split.js +2 -2
  62. package/dist/elements/chart.js +1 -1
  63. package/dist/elements/chat-panel.js +2 -2
  64. package/dist/elements/checkpoint-history.js +2 -2
  65. package/dist/elements/clamp.js +2 -1
  66. package/dist/elements/code-diff.js +1 -1
  67. package/dist/elements/code-runner.js +1 -1
  68. package/dist/elements/command-palette.js +6 -5
  69. package/dist/elements/comparison-card.js +2 -2
  70. package/dist/elements/composer.js +9 -8
  71. package/dist/elements/computer-use.js +1 -1
  72. package/dist/elements/confidence-marker.js +2 -1
  73. package/dist/elements/connection-state.js +1 -1
  74. package/dist/elements/context-breakdown.js +1 -1
  75. package/dist/elements/context-usage.js +1 -1
  76. package/dist/elements/conversation-search.js +4 -3
  77. package/dist/elements/cost-meter.js +1 -1
  78. package/dist/elements/data-table.js +2 -2
  79. package/dist/elements/day-separator.js +1 -1
  80. package/dist/elements/diagram.js +1 -1
  81. package/dist/elements/document-reference.js +3 -3
  82. package/dist/elements/draft-restore.js +1 -1
  83. package/dist/elements/edit-message.js +4 -3
  84. package/dist/elements/elements.css +26 -5
  85. package/dist/elements/elicitation-form.js +3 -3
  86. package/dist/elements/empty-state.js +2 -1
  87. package/dist/elements/error-state.js +1 -1
  88. package/dist/elements/feedback-dialog.js +4 -3
  89. package/dist/elements/file-tree.js +2 -2
  90. package/dist/elements/flow-graph.js +2 -2
  91. package/dist/elements/guardrail-notice.js +3 -3
  92. package/dist/elements/image-generation.js +1 -1
  93. package/dist/elements/inline-citation.js +3 -3
  94. package/dist/elements/job-progress.js +3 -3
  95. package/dist/elements/launcher-bubble.js +2 -2
  96. package/dist/elements/loading-state.js +1 -1
  97. package/dist/elements/map-answer.js +3 -2
  98. package/dist/elements/markdown.js +5 -4
  99. package/dist/elements/math-block.js +1 -1
  100. package/dist/elements/mcp-server-panel.js +3 -3
  101. package/dist/elements/message-attachment.js +4 -4
  102. package/dist/elements/message-pair.js +1 -1
  103. package/dist/elements/message-queue.js +2 -2
  104. package/dist/elements/mobile-composer.js +4 -3
  105. package/dist/elements/model-picker.js +3 -3
  106. package/dist/elements/onboarding.js +2 -2
  107. package/dist/elements/permission-grant.js +2 -2
  108. package/dist/elements/permission-scopes.js +5 -4
  109. package/dist/elements/prompt-library.js +7 -6
  110. package/dist/elements/queue-dock.js +4 -3
  111. package/dist/elements/quota-banner.js +1 -1
  112. package/dist/elements/quote-reply.js +1 -1
  113. package/dist/elements/read-aloud.js +2 -2
  114. package/dist/elements/reasoning-panel.js +2 -1
  115. package/dist/elements/recommendation-card.d.ts +1 -1
  116. package/dist/elements/recommendation-card.js +2 -2
  117. package/dist/elements/regenerate-menu.js +2 -2
  118. package/dist/elements/research-report.js +1 -1
  119. package/dist/elements/retrieval-chunks.js +1 -1
  120. package/dist/elements/revert-dock.js +5 -4
  121. package/dist/elements/reviewable-diff.js +1 -1
  122. package/dist/elements/schedule-card.js +3 -3
  123. package/dist/elements/score-breakdown.js +1 -1
  124. package/dist/elements/scroll-anchor.js +2 -2
  125. package/dist/elements/settings-panel.js +3 -2
  126. package/dist/elements/shared-conversation.js +2 -2
  127. package/dist/elements/sources.js +4 -3
  128. package/dist/elements/speaker-identity.js +1 -1
  129. package/dist/elements/spec-sheet.js +1 -1
  130. package/dist/elements/streaming-text.js +1 -1
  131. package/dist/elements/subagent-list.js +2 -2
  132. package/dist/elements/suggestions.js +1 -1
  133. package/dist/elements/surfaces.d.ts +1 -1
  134. package/dist/elements/surfaces.js +2 -1
  135. package/dist/elements/tail-status.js +1 -1
  136. package/dist/elements/terminal-block.js +1 -1
  137. package/dist/elements/thread-list.js +1 -1
  138. package/dist/elements/thread-search.js +5 -4
  139. package/dist/elements/timeline.js +1 -1
  140. package/dist/elements/todo-list.js +2 -2
  141. package/dist/elements/tool-call.js +4 -3
  142. package/dist/elements/tool-error.js +2 -2
  143. package/dist/elements/tool-group.js +1 -1
  144. package/dist/elements/tool-timeline.js +4 -3
  145. package/dist/elements/trace-waterfall.js +1 -1
  146. package/dist/elements/verdict-row.js +2 -2
  147. package/dist/elements/voice-conversation.js +3 -2
  148. package/dist/elements/web-preview.js +1 -1
  149. package/dist/elements/web-search.js +2 -2
  150. package/dist/elements/work-collapse.js +2 -1
  151. package/dist/flow/node-card.js +3 -2
  152. package/dist/flow/use-flow-theme.js +2 -1
  153. package/dist/forms/_chassis-size.d.ts +22 -0
  154. package/dist/forms/_chassis.d.ts +28 -15
  155. package/dist/forms/_chassis.js +34 -8
  156. package/dist/forms/_listbox.js +8 -5
  157. package/dist/forms/autocomplete.d.ts +2 -1
  158. package/dist/forms/checkbox.js +8 -2
  159. package/dist/forms/combobox.d.ts +2 -1
  160. package/dist/forms/env-var-input.d.ts +2 -1
  161. package/dist/forms/env-var-input.js +3 -2
  162. package/dist/forms/field.d.ts +2 -1
  163. package/dist/forms/field.js +15 -4
  164. package/dist/forms/file-upload.js +3 -2
  165. package/dist/forms/index.d.ts +2 -1
  166. package/dist/forms/input-group.d.ts +2 -1
  167. package/dist/forms/input.d.ts +2 -1
  168. package/dist/forms/multi-select.d.ts +2 -1
  169. package/dist/forms/number-field.js +2 -1
  170. package/dist/forms/otp-field.d.ts +2 -1
  171. package/dist/forms/password-input.d.ts +2 -1
  172. package/dist/forms/password-input.js +4 -2
  173. package/dist/forms/radio-group.js +6 -2
  174. package/dist/forms/rating.js +2 -1
  175. package/dist/forms/scrub-input.d.ts +2 -1
  176. package/dist/forms/scrub-input.js +2 -1
  177. package/dist/forms/search-input.d.ts +2 -1
  178. package/dist/forms/search-input.js +2 -1
  179. package/dist/forms/select.d.ts +2 -1
  180. package/dist/forms/select.js +6 -2
  181. package/dist/forms/slider.js +6 -2
  182. package/dist/forms/switch.js +6 -2
  183. package/dist/forms/tags-input.d.ts +2 -1
  184. package/dist/forms/textarea.js +2 -1
  185. package/dist/forms/toggle-group.d.ts +1 -1
  186. package/dist/forms/toggle.d.ts +1 -1
  187. package/dist/forms/toggle.js +3 -1
  188. package/dist/index.d.ts +4 -3
  189. package/dist/index.js +2 -2
  190. package/dist/instruments/_data-row.js +2 -1
  191. package/dist/instruments/app-window-frame.js +1 -1
  192. package/dist/instruments/code-block.js +8 -2
  193. package/dist/instruments/group-bar.js +1 -1
  194. package/dist/instruments/ledger.js +6 -2
  195. package/dist/instruments/log-viewer.js +5 -3
  196. package/dist/instruments/progress.js +5 -2
  197. package/dist/instruments/seam-grid.js +5 -3
  198. package/dist/instruments/stat.js +10 -3
  199. package/dist/instruments/table.js +28 -10
  200. package/dist/instruments/terminal-frame.js +4 -2
  201. package/dist/instruments/usage-chart.js +1 -1
  202. package/dist/layout/_collapse.js +6 -1
  203. package/dist/layout/bento.js +7 -4
  204. package/dist/layout/breadcrumb.js +7 -3
  205. package/dist/layout/card.js +14 -6
  206. package/dist/layout/carousel.js +3 -2
  207. package/dist/layout/collapsible.js +5 -1
  208. package/dist/layout/container.js +2 -1
  209. package/dist/layout/description-list.js +4 -1
  210. package/dist/layout/frames.js +11 -5
  211. package/dist/layout/item.js +3 -2
  212. package/dist/layout/link.d.ts +16 -0
  213. package/dist/layout/link.js +22 -3
  214. package/dist/layout/pagination.js +2 -1
  215. package/dist/layout/preview.d.ts +32 -12
  216. package/dist/layout/preview.js +149 -40
  217. package/dist/layout/resizable.js +2 -1
  218. package/dist/layout/sidebar.js +11 -3
  219. package/dist/layout/stepper.js +6 -2
  220. package/dist/lib/cn.js +29 -2
  221. package/dist/midi/musical-time-input.d.ts +2 -1
  222. package/dist/midi/piano-keyboard.js +3 -2
  223. package/dist/midi/spectrum-visualizer.js +1 -1
  224. package/dist/midi/threshold-rail.js +2 -1
  225. package/dist/midi/timeline-ruler.js +1 -1
  226. package/dist/overlays/_surface.d.ts +72 -12
  227. package/dist/overlays/_surface.js +86 -12
  228. package/dist/overlays/command-palette.js +9 -5
  229. package/dist/overlays/dialog.d.ts +5 -0
  230. package/dist/overlays/dialog.js +6 -1
  231. package/dist/overlays/info-tip.js +2 -1
  232. package/dist/overlays/menubar.js +3 -1
  233. package/dist/overlays/popover.js +2 -1
  234. package/dist/overlays/toast.js +6 -2
  235. package/dist/overlays/tooltip.js +4 -1
  236. package/dist/primitives/button.d.ts +15 -0
  237. package/dist/primitives/button.js +40 -10
  238. package/dist/primitives/chip.d.ts +20 -2
  239. package/dist/primitives/chip.js +39 -17
  240. package/dist/primitives/kbd.d.ts +6 -0
  241. package/dist/primitives/kbd.js +10 -1
  242. package/dist/primitives/skeleton.js +1 -1
  243. package/dist/system/_focus-ring-field.js +29 -0
  244. package/dist/system/_focus-ring.js +125 -0
  245. package/dist/system/_paint-elevation.js +9 -0
  246. package/dist/system/_paint-glass.js +46 -0
  247. package/dist/system/_paint-glow.js +51 -0
  248. package/dist/system/_paint-ground-pattern.js +30 -0
  249. package/dist/system/_paint-rest-shade.js +32 -0
  250. package/dist/system/_paint-rim.js +59 -0
  251. package/dist/system/_paint-stroke-sunken.js +19 -0
  252. package/dist/system/_paint-stroke-surface-1.js +19 -0
  253. package/dist/system/_paint-stroke-surface-2.js +40 -0
  254. package/dist/system/_paint-texture.js +56 -0
  255. package/dist/system/_style-app-bar.js +65 -0
  256. package/dist/system/_style-band.js +57 -0
  257. package/dist/system/_style-body-leading.js +21 -0
  258. package/dist/system/_style-body-size.js +30 -0
  259. package/dist/system/_style-body-weight.js +24 -0
  260. package/dist/system/_style-body.js +27 -0
  261. package/dist/system/_style-caption.js +19 -0
  262. package/dist/system/_style-card-pad.js +43 -0
  263. package/dist/system/_style-check.js +33 -0
  264. package/dist/system/_style-chip.js +103 -0
  265. package/dist/system/_style-code.js +13 -0
  266. package/dist/system/_style-collapse.js +14 -0
  267. package/dist/system/_style-control-face.js +29 -0
  268. package/dist/system/_style-control-label.js +22 -0
  269. package/dist/system/_style-control-step.js +22 -0
  270. package/dist/system/_style-control.js +76 -0
  271. package/dist/system/_style-data-face.js +28 -0
  272. package/dist/system/_style-description.js +23 -0
  273. package/dist/system/_style-eyebrow.js +43 -0
  274. package/dist/system/_style-footer-rule.js +47 -0
  275. package/dist/system/_style-gutter.js +17 -0
  276. package/dist/system/_style-help-ink.js +14 -0
  277. package/dist/system/_style-help.js +29 -0
  278. package/dist/system/_style-input-face.js +34 -0
  279. package/dist/system/_style-kbd.js +46 -0
  280. package/dist/system/_style-label-case.js +36 -0
  281. package/dist/system/_style-label-face.js +32 -0
  282. package/dist/system/_style-label-ink.js +29 -0
  283. package/dist/system/_style-label-leading.js +14 -0
  284. package/dist/system/_style-label-size.js +36 -0
  285. package/dist/system/_style-label-tracking.js +45 -0
  286. package/dist/system/_style-label-weight.js +40 -0
  287. package/dist/system/_style-lede.js +49 -0
  288. package/dist/system/_style-link.js +46 -0
  289. package/dist/system/_style-menu.js +30 -0
  290. package/dist/system/_style-nav-item.js +41 -0
  291. package/dist/system/_style-nav-voice.js +43 -0
  292. package/dist/system/_style-option.js +42 -0
  293. package/dist/system/_style-overlay-title.js +35 -0
  294. package/dist/system/_style-page-title.js +48 -0
  295. package/dist/system/_style-popover-pad.js +13 -0
  296. package/dist/system/_style-quiet-ink.js +13 -0
  297. package/dist/system/_style-row-pad.js +13 -0
  298. package/dist/system/_style-seam.js +43 -0
  299. package/dist/system/_style-section-rule.js +26 -0
  300. package/dist/system/_style-segment.js +30 -0
  301. package/dist/system/_style-segmented-control.js +86 -0
  302. package/dist/system/_style-selected.js +36 -0
  303. package/dist/system/_style-stage-marks.js +26 -0
  304. package/dist/system/_style-tab.js +71 -0
  305. package/dist/system/_style-textarea.js +21 -0
  306. package/dist/system/_style-title.js +37 -0
  307. package/dist/system/_style-tooltip.js +17 -0
  308. package/dist/system/density.d.ts +15 -5
  309. package/dist/system/density.js +188 -25
  310. package/dist/system/index.d.ts +2 -2
  311. package/dist/system/index.js +2 -2
  312. package/dist/system/overrides.d.ts +1 -0
  313. package/dist/system/overrides.js +151 -3
  314. package/dist/system/portal.d.ts +3 -2
  315. package/dist/system/portal.js +22 -10
  316. package/dist/system/prepaint.d.ts +21 -5
  317. package/dist/system/prepaint.js +3 -1
  318. package/dist/system/published.d.ts +1 -0
  319. package/dist/system/published.js +131 -0
  320. package/dist/system/theme-provider.d.ts +168 -60
  321. package/dist/system/theme-provider.js +375 -79
  322. package/dist/system/theme-registry.d.ts +2 -1
  323. package/dist/system/theme-registry.js +27 -10
  324. package/dist/system/use-density.js +4 -3
  325. package/dist/system/use-theme.d.ts +5 -2
  326. package/dist/system/use-theme.js +7 -4
  327. package/dist/system/vocabulary.js +2 -2
  328. package/dist/theming/create-theme.js +12 -6
  329. package/dist/theming/serialize.d.ts +34 -2
  330. package/dist/theming/serialize.js +86 -4
  331. package/manifest/components/accordion.json +7 -1
  332. package/manifest/components/agent-pile.json +3 -0
  333. package/manifest/components/alert-dialog.json +38 -1
  334. package/manifest/components/app-bar.json +23 -2
  335. package/manifest/components/app-shell.json +5 -0
  336. package/manifest/components/ask-box.json +3 -1
  337. package/manifest/components/autocomplete.json +49 -1
  338. package/manifest/components/band.json +14 -3
  339. package/manifest/components/bento.json +12 -1
  340. package/manifest/components/breadcrumb.json +8 -1
  341. package/manifest/components/button.json +31 -3
  342. package/manifest/components/calendar.json +7 -0
  343. package/manifest/components/card.json +28 -1
  344. package/manifest/components/carousel.json +4 -1
  345. package/manifest/components/channel-matrix.json +40 -1
  346. package/manifest/components/chart-tooltip-content.json +38 -1
  347. package/manifest/components/chat-empty-state.json +3 -1
  348. package/manifest/components/checkbox-group.json +14 -0
  349. package/manifest/components/checkbox.json +14 -0
  350. package/manifest/components/chip.json +16 -1
  351. package/manifest/components/clamp.json +3 -1
  352. package/manifest/components/code-block.json +10 -1
  353. package/manifest/components/collapsible.json +13 -2
  354. package/manifest/components/color-area.json +4 -2
  355. package/manifest/components/color-field.json +14 -0
  356. package/manifest/components/color-picker.json +14 -0
  357. package/manifest/components/color-slider.json +3 -1
  358. package/manifest/components/colors-section.json +9 -1
  359. package/manifest/components/combobox.json +49 -1
  360. package/manifest/components/command-palette.json +37 -1
  361. package/manifest/components/composer-actions.json +3 -0
  362. package/manifest/components/composer-attach-button.json +3 -0
  363. package/manifest/components/composer-attachment-chip.json +3 -0
  364. package/manifest/components/composer-attachments.json +3 -0
  365. package/manifest/components/composer-bar.json +3 -0
  366. package/manifest/components/composer-command-item.json +3 -0
  367. package/manifest/components/composer-context.json +3 -0
  368. package/manifest/components/composer-input.json +3 -0
  369. package/manifest/components/composer-menu-item.json +3 -0
  370. package/manifest/components/composer-menu.json +3 -0
  371. package/manifest/components/composer-model-item.json +3 -0
  372. package/manifest/components/composer-model-trigger.json +3 -0
  373. package/manifest/components/composer-person-item.json +3 -0
  374. package/manifest/components/composer-send.json +3 -0
  375. package/manifest/components/composer-toolbar.json +3 -0
  376. package/manifest/components/composer-voice-button.json +3 -0
  377. package/manifest/components/composer-voice.json +3 -0
  378. package/manifest/components/composer.json +14 -0
  379. package/manifest/components/confidence-marker.json +3 -1
  380. package/manifest/components/container.json +2 -1
  381. package/manifest/components/context-menu.json +38 -1
  382. package/manifest/components/conversation-search.json +3 -1
  383. package/manifest/components/cue-mark.json +2 -2
  384. package/manifest/components/cue-portal-frame.json +1 -1
  385. package/manifest/components/data-row.json +3 -1
  386. package/manifest/components/data-tree.json +3 -1
  387. package/manifest/components/date-field.json +14 -0
  388. package/manifest/components/date-picker.json +14 -0
  389. package/manifest/components/date-range-picker.json +14 -0
  390. package/manifest/components/delegation-card.json +3 -1
  391. package/manifest/components/density.json +21 -7
  392. package/manifest/components/description-list.json +6 -1
  393. package/manifest/components/dialog.json +39 -1
  394. package/manifest/components/disclosure.json +13 -2
  395. package/manifest/components/dmx-bar.json +37 -1
  396. package/manifest/components/dmx-strip.json +37 -1
  397. package/manifest/components/drawer.json +38 -1
  398. package/manifest/components/dropdown-menu.json +38 -1
  399. package/manifest/components/edit-message.json +3 -1
  400. package/manifest/components/elements-command-palette.json +3 -1
  401. package/manifest/components/elements-composer.json +3 -0
  402. package/manifest/components/empty-state-composer.json +3 -1
  403. package/manifest/components/empty-state-greeting.json +3 -1
  404. package/manifest/components/empty-state-suggestion.json +3 -1
  405. package/manifest/components/empty-state-suggestions.json +3 -1
  406. package/manifest/components/env-var-input.json +14 -1
  407. package/manifest/components/export-dialog.json +6 -1
  408. package/manifest/components/eyebrow.json +13 -2
  409. package/manifest/components/feedback-dialog.json +3 -0
  410. package/manifest/components/field-description.json +14 -0
  411. package/manifest/components/field-error.json +14 -0
  412. package/manifest/components/field-label.json +15 -1
  413. package/manifest/components/field.json +14 -0
  414. package/manifest/components/file-upload.json +3 -0
  415. package/manifest/components/footer.json +14 -1
  416. package/manifest/components/frames.json +14 -1
  417. package/manifest/components/hover-card.json +38 -1
  418. package/manifest/components/info-tip.json +3 -0
  419. package/manifest/components/input-group.json +14 -0
  420. package/manifest/components/input.json +14 -0
  421. package/manifest/components/item.json +3 -1
  422. package/manifest/components/kbd.json +10 -1
  423. package/manifest/components/ledger.json +9 -2
  424. package/manifest/components/link.json +10 -0
  425. package/manifest/components/log-viewer.json +10 -0
  426. package/manifest/components/map-answer.json +3 -1
  427. package/manifest/components/markdown-text.json +3 -0
  428. package/manifest/components/menubar.json +41 -2
  429. package/manifest/components/message-list.json +10 -0
  430. package/manifest/components/message.json +6 -1
  431. package/manifest/components/mobile-composer.json +3 -1
  432. package/manifest/components/multi-select.json +49 -1
  433. package/manifest/components/musical-time-input.json +14 -0
  434. package/manifest/components/navigation-menu.json +41 -1
  435. package/manifest/components/node-card.json +3 -0
  436. package/manifest/components/number-field.json +14 -1
  437. package/manifest/components/otp-field.json +13 -0
  438. package/manifest/components/page-shell.json +14 -0
  439. package/manifest/components/pagination.json +3 -0
  440. package/manifest/components/panel-header.json +12 -0
  441. package/manifest/components/panel.json +13 -1
  442. package/manifest/components/password-input.json +14 -1
  443. package/manifest/components/permission-scopes.json +3 -1
  444. package/manifest/components/piano-keyboard.json +3 -0
  445. package/manifest/components/popover.json +39 -1
  446. package/manifest/components/preset-section.json +9 -1
  447. package/manifest/components/preview.json +30 -10
  448. package/manifest/components/progress.json +6 -1
  449. package/manifest/components/prompt-library.json +3 -1
  450. package/manifest/components/queue-dock.json +3 -1
  451. package/manifest/components/radio-group.json +8 -0
  452. package/manifest/components/radio.json +8 -0
  453. package/manifest/components/rating.json +4 -1
  454. package/manifest/components/reasoning-panel.json +3 -1
  455. package/manifest/components/recommendation-card.json +1 -1
  456. package/manifest/components/resizable.json +4 -1
  457. package/manifest/components/revert-dock.json +3 -1
  458. package/manifest/components/row.json +5 -1
  459. package/manifest/components/scroll-area.json +4 -2
  460. package/manifest/components/scrollable-tabs-list.json +19 -0
  461. package/manifest/components/scrub-input.json +14 -1
  462. package/manifest/components/seam-cell.json +1 -0
  463. package/manifest/components/seam-grid.json +1 -0
  464. package/manifest/components/seam-list.json +5 -1
  465. package/manifest/components/search-input.json +14 -1
  466. package/manifest/components/section-header.json +15 -2
  467. package/manifest/components/segmented-control.json +17 -0
  468. package/manifest/components/select.json +28 -0
  469. package/manifest/components/settings-panel.json +3 -0
  470. package/manifest/components/shape-section.json +9 -1
  471. package/manifest/components/sheet.json +38 -1
  472. package/manifest/components/shimmer-label.json +3 -0
  473. package/manifest/components/sidebar.json +19 -2
  474. package/manifest/components/slider.json +8 -0
  475. package/manifest/components/sources.json +3 -1
  476. package/manifest/components/stat.json +9 -0
  477. package/manifest/components/status-bar.json +4 -0
  478. package/manifest/components/stepper.json +8 -0
  479. package/manifest/components/swap-label.json +3 -0
  480. package/manifest/components/switch.json +8 -0
  481. package/manifest/components/table-scroll-region.json +20 -2
  482. package/manifest/components/table.json +20 -2
  483. package/manifest/components/tabs.json +20 -1
  484. package/manifest/components/tags-input.json +49 -1
  485. package/manifest/components/terminal-frame.json +3 -0
  486. package/manifest/components/textarea.json +16 -0
  487. package/manifest/components/theme-configurator.json +38 -1
  488. package/manifest/components/theme-provider.json +37 -19
  489. package/manifest/components/thread-search.json +3 -1
  490. package/manifest/components/threshold-rail.json +3 -0
  491. package/manifest/components/time-field.json +14 -0
  492. package/manifest/components/toast.json +39 -0
  493. package/manifest/components/toggle-group.json +1 -19
  494. package/manifest/components/toggle.json +3 -5
  495. package/manifest/components/token-editor.json +6 -1
  496. package/manifest/components/tool-call-card.json +9 -2
  497. package/manifest/components/tool-call.json +3 -1
  498. package/manifest/components/tool-timeline.json +3 -1
  499. package/manifest/components/toolbar.json +4 -1
  500. package/manifest/components/tooltip.json +40 -1
  501. package/manifest/components/tree-visibility-toggle.json +3 -0
  502. package/manifest/components/tree.json +3 -0
  503. package/manifest/components/universe-grid.json +3 -0
  504. package/manifest/components/voice-conversation.json +3 -0
  505. package/manifest/components/work-collapse.json +3 -1
  506. package/manifest/manifest.json +205 -185
  507. package/manifest/tokens.json +260 -4
  508. package/package.json +6 -6
@@ -1,3 +1,4 @@
1
+ import "./published.js";
1
2
  import * as React from "react";
2
3
  import { Paint, StyleSet } from "@cueplusplus/tokens";
3
4
  import { Density as Density$1 } from "@cueplusplus/theme-base";
@@ -9,7 +10,7 @@ interface DensityProps {
9
10
  */
10
11
  density: Density$1;
11
12
  /**
12
- * A look pack for this subtree.
13
+ * A paint pack for this subtree.
13
14
  *
14
15
  * Optional, and **absent means inherit**, exactly as `styleSet` is: an island
15
16
  * that names none stamps no `data-paint` and passes the ambient pack straight
@@ -18,7 +19,8 @@ interface DensityProps {
18
19
  */
19
20
  paint?: Paint;
20
21
  /**
21
- * A style set for this subtree: `console`, `editorial` or `marketing`.
22
+ * A style set for this subtree: `console`, `editorial`, `marketing` or
23
+ * `graphite`.
22
24
  *
23
25
  * Optional, and **absent means inherit** — an island that names none stamps no
24
26
  * `data-style` and passes the ambient set straight through, exactly as a bare
@@ -27,7 +29,7 @@ interface DensityProps {
27
29
  *
28
30
  * - `console` inside a page that is not console. That is the whole job of the
29
31
  * default set: it restates the `:root` defaults, so a subtree stamped with
30
- * it renders the ordinary look inside an editorial or marketing page.
32
+ * it renders the ordinary look inside a page under any other set.
31
33
  * - Moving the band rhythm with the rung. `--cue-band-y` is
32
34
  * `calc(var(--cue-space-7) * 2)` declared on the `[data-style]` element, and
33
35
  * a custom property's `var()` references are substituted where they are
@@ -35,6 +37,13 @@ interface DensityProps {
35
37
  * the rhythm already resolved above it. Restating the set here re-resolves
36
38
  * it against this island's rung, which is how a denser island gets a
37
39
  * proportionally tighter band instead of the outer one's.
40
+ *
41
+ * The library restates the set for you where an island changes what a set's
42
+ * values read besides the rung — the theme's inks, the pairing's faces: a
43
+ * nested `ThemeProvider` that names a theme or a mode, and a `Preview` stage
44
+ * with a theme, a mode or a pairing, stamp the set and the pack in force
45
+ * beside it. This island changes only the rung, so it does not, and the
46
+ * rhythm above stays the opt-in the second bullet describes.
38
47
  */
39
48
  styleSet?: StyleSet;
40
49
  /** Subtree that should render at `density`. */
@@ -58,7 +67,7 @@ interface DensityProps {
58
67
  * omitted where there is none. It is read by nothing this island does —
59
68
  * theme and mode are deliberately *not* re-scoped here; density was for a long
60
69
  * time the only axis an island could override (spec §6), and a named
61
- * `styleSet` is the second and last — it exists so a theme's own
70
+ * `styleSet` and a named `paint` are the other two — it exists so a theme's own
62
71
  * generated CSS can address exactly this island regardless of how many
63
72
  * *other* themed providers sit between it and the one it belongs to. A CSS
64
73
  * ancestor selector can only ask "does some ancestor carry theme `x`", never
@@ -70,7 +79,8 @@ interface DensityProps {
70
79
  * is how the axis inherits: custom properties inherit down the DOM, so an island
71
80
  * that stamped the ambient set would be restating an answer it already had, and
72
81
  * an island that stamped a *default* set would silently re-point the rhythm of
73
- * every page that nested one.
82
+ * every page that nested one. `data-paint` joins them on exactly those terms
83
+ * when a `paint` is named.
74
84
  *
75
85
  * @example
76
86
  * <Density density="ultra-compact">
@@ -1,4 +1,6 @@
1
1
  "use client";
2
+ import { useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect.js";
3
+ import { published, usePublish, useRead } from "./published.js";
2
4
  import * as React from "react";
3
5
  import { jsx } from "react/jsx-runtime";
4
6
  //#region src/system/density.tsx
@@ -14,9 +16,16 @@ const DEFAULT_DENSITY = "compact";
14
16
  * Nearest ambient density. `null` means "nothing has stamped a level yet", which
15
17
  * `useDensity()` reports as {@link DEFAULT_DENSITY}.
16
18
  *
19
+ * **Carried as a `Published`** — this and the three contexts below, like every
20
+ * context whose value the root's restore moves. A setter or a prop moves the
21
+ * context, as any context moves; the restore, which lands while a streamed
22
+ * Suspense boundary below can still be server HTML, is posted beside it
23
+ * instead, so no boundary is told anything changed. Readers go through
24
+ * {@link useRead}. See `published.ts`.
25
+ *
17
26
  * Internal: consumers read it through `useDensity()`, never directly.
18
27
  */
19
- const DensityContext = React.createContext(null);
28
+ const DensityContext = React.createContext(published(null));
20
29
  /**
21
30
  * Nearest ambient theme's name, published for exactly one reader: `Density`
22
31
  * below, which stamps it onto its island as `data-cue-theme` so a theme's
@@ -36,7 +45,7 @@ const DensityContext = React.createContext(null);
36
45
  * Internal: `Density` is the only reader. Not `useTheme()` — that throws
37
46
  * outside a provider, and this island has no reason to.
38
47
  */
39
- const AmbientThemeContext = React.createContext(null);
48
+ const AmbientThemeContext = React.createContext(published(null));
40
49
  /**
41
50
  * Nearest ambient style set. `null` means "nothing has stamped a set", which
42
51
  * every reader reports as "no style set" rather than as the default one.
@@ -55,9 +64,9 @@ const AmbientThemeContext = React.createContext(null);
55
64
  * and the portal stamp have to ask, because both leave the DOM they were
56
65
  * written in and have to carry the answer with them.
57
66
  */
58
- const StyleSetContext = React.createContext(null);
67
+ const StyleSetContext = React.createContext(published(null));
59
68
  /**
60
- * The look pack stamped around this subtree, or `null` when none is.
69
+ * The paint pack stamped around this subtree, or `null` when none is.
61
70
  *
62
71
  * The fifth axis's counterpart to {@link StyleSetContext}, and internal for the
63
72
  * same reasons: a provider publishes this and its `ThemeContext.paint` from one
@@ -70,7 +79,143 @@ const StyleSetContext = React.createContext(null);
70
79
  * pack. Collapsing the two would make every unpainted subtree override its
71
80
  * parent instead of inheriting from it.
72
81
  */
73
- const PaintContext = React.createContext(null);
82
+ const PaintContext = React.createContext(published(null));
83
+ /**
84
+ * `true` under a root provider that persists: one whose state, on the server and
85
+ * on the client's first render, is its PROPS, while `<html>` already carries
86
+ * what the visitor stored. Under such a root an island must not restate the set
87
+ * and pack in force until it has mounted — see {@link useRestateReady}.
88
+ *
89
+ * **A constant, not a flag that flips at the restore.** It used to be exactly
90
+ * that flag — `true` until the root restored, then `false` — and a context
91
+ * whose value changes in the root's first commit is an update to every
92
+ * Suspense boundary below it that has not hydrated yet. React cannot hydrate a
93
+ * streamed boundary against a changed value, so it threw the boundary's server
94
+ * HTML away and rendered it on the client: every stage and nested provider in
95
+ * a streamed boundary, on every page, for every visitor, whether or not
96
+ * anything was stored. This value is the root's `persistPreferences`, which the
97
+ * restore does not move.
98
+ *
99
+ * Here rather than in `theme-provider.tsx` for the cycle reason the contexts
100
+ * above give. Only the root provides a value; a nested provider passes it on.
101
+ *
102
+ * Internal.
103
+ */
104
+ const DeferRestateContext = React.createContext(false);
105
+ /**
106
+ * Whether an island may restate the set and pack in force on this render.
107
+ *
108
+ * Its callers are the islands that restate them — a nested `ThemeProvider` that
109
+ * names a theme or a mode, a `Preview` stage with a theme, a mode or a pairing —
110
+ * and `wants` is whether there is anything to restate at all.
111
+ *
112
+ * Under a root that does not persist, always: its props are the truth from the
113
+ * first render, the server's included. Under one that persists, only once this
114
+ * island has mounted. Its server markup and its first client render therefore
115
+ * restate nothing — they agree, and the stored set and pack inherit from
116
+ * `<html>` meanwhile — and the island's own layout effect then re-renders it
117
+ * with them, before the first paint. That update is the island's own, made
118
+ * after it has hydrated, so it reaches no boundary still waiting to; and the
119
+ * root's restore, which runs in the same layout phase when the two mount
120
+ * together, has landed by the time that render reads the contexts. With
121
+ * nothing to restate there is no second render at all.
122
+ *
123
+ * Internal.
124
+ */
125
+ function useRestateReady(wants) {
126
+ const defer = React.useContext(DeferRestateContext);
127
+ const mounted = useMountedWhen(defer && wants);
128
+ return !defer || mounted;
129
+ }
130
+ /**
131
+ * `true` once this component has committed with `wants` set, and for good after
132
+ * that: the island's own layout effect sets it, so the re-render it causes is
133
+ * this island's update, made after it hydrated and before the first paint.
134
+ * With `wants` unset there is nothing to wait for and no second render at all.
135
+ *
136
+ * Internal: the one mechanism behind {@link useRestateReady},
137
+ * {@link useFollowedAxes}, and `ThemeProvider`'s wait on the colour edit of a
138
+ * provider that names neither theme nor mode.
139
+ */
140
+ function useMountedWhen(wants) {
141
+ const [mounted, setMounted] = React.useState(false);
142
+ useIsomorphicLayoutEffect(() => {
143
+ if (wants) setMounted(true);
144
+ }, [wants]);
145
+ return mounted;
146
+ }
147
+ const ROOT_AXES = [false, true].flatMap((theme) => [false, true].flatMap((mode) => [false, true].map((density) => Object.freeze({
148
+ theme,
149
+ mode,
150
+ density
151
+ }))));
152
+ /** The one {@link RootAxes} object for these three answers. Internal. */
153
+ function rootAxes(theme, mode, density) {
154
+ return ROOT_AXES[(theme ? 4 : 0) + (mode ? 2 : 0) + (density ? 1 : 0)];
155
+ }
156
+ /** See {@link RootAxes}. None, outside a persisting root. Internal. */
157
+ const RootAxesContext = React.createContext(rootAxes(false, false, false));
158
+ const FOLLOWS_NOTHING = Object.freeze({
159
+ theme: false,
160
+ mode: false,
161
+ density: false,
162
+ marker: null
163
+ });
164
+ /**
165
+ * Which of the axes an island restates beside the one it names it must leave
166
+ * to `<html>` on this render (tracking plan F13).
167
+ *
168
+ * `restates` names the axes this island would stamp with a value it took from
169
+ * around it rather than named. A theme's light block is the compound
170
+ * `[data-theme][data-mode="light"]`, so an island that names either stamps the
171
+ * other beside it: a nested `ThemeProvider` that names a theme and no mode
172
+ * stamps the ambient mode, and the ambient rung beside that; one that names a
173
+ * mode and no theme stamps the ambient theme; a `Preview` stage does the same
174
+ * with the page's. A rung island — a provider that names only a rung, a
175
+ * `<Density>` island, a stage that names only a rung — stamps the ambient
176
+ * theme as `data-cue-theme`, which is what a theme's own rung retunes are
177
+ * addressed through.
178
+ *
179
+ * Where such an axis is the persisting root's ({@link RootAxesContext}), the
180
+ * value around the island on the server, and on the client's first render, is
181
+ * the root's PROP, while `<html>` already carries what the visitor stored. So
182
+ * until the island has mounted it stamps none of them, and carries
183
+ * `data-cue-follows` naming them instead. Every block a theme stylesheet
184
+ * writes that the settled island would match through one of those attributes
185
+ * has a twin keyed on `:root`'s value and that marker, at the same specificity,
186
+ * so the island paints the visitor's theme, mode and rung from the first frame;
187
+ * a rung node with no `data-cue-theme` is reached by the rung rules' own
188
+ * structural form, and the base rung the island inherits from the element that
189
+ * carries it. Its own layout effect then re-renders it with exactly what it
190
+ * stamped before this existed, and the marker is gone — the
191
+ * {@link useRestateReady} pattern: its server markup and its first client
192
+ * render agree, it waits on its OWN mount rather than on anything the root
193
+ * moves, and the update is its own.
194
+ *
195
+ * Why `<html>`'s value and not the nearest ancestor's is the right one, and why
196
+ * a marker rather than the attribute's absence, is argued beside the
197
+ * selectors, in `@cueplusplus/theme-tools`' `follows`.
198
+ *
199
+ * Internal.
200
+ */
201
+ function useFollowedAxes(restates) {
202
+ const around = React.useContext(RootAxesContext);
203
+ const theme = restates.theme === true && around.theme;
204
+ const mode = restates.mode === true && around.mode;
205
+ const density = restates.density === true && around.density;
206
+ const any = theme || mode || density;
207
+ if (useMountedWhen(any) || !any) return FOLLOWS_NOTHING;
208
+ return {
209
+ theme,
210
+ mode,
211
+ density,
212
+ marker: [
213
+ theme && "theme",
214
+ mode && "mode",
215
+ density && "density"
216
+ ].filter(Boolean).join(" ")
217
+ };
218
+ }
74
219
  /**
75
220
  * Re-scope any subtree to a different density level.
76
221
  *
@@ -85,7 +230,7 @@ const PaintContext = React.createContext(null);
85
230
  * omitted where there is none. It is read by nothing this island does —
86
231
  * theme and mode are deliberately *not* re-scoped here; density was for a long
87
232
  * time the only axis an island could override (spec §6), and a named
88
- * `styleSet` is the second and last — it exists so a theme's own
233
+ * `styleSet` and a named `paint` are the other two — it exists so a theme's own
89
234
  * generated CSS can address exactly this island regardless of how many
90
235
  * *other* themed providers sit between it and the one it belongs to. A CSS
91
236
  * ancestor selector can only ask "does some ancestor carry theme `x`", never
@@ -97,7 +242,8 @@ const PaintContext = React.createContext(null);
97
242
  * is how the axis inherits: custom properties inherit down the DOM, so an island
98
243
  * that stamped the ambient set would be restating an answer it already had, and
99
244
  * an island that stamped a *default* set would silently re-point the rhythm of
100
- * every page that nested one.
245
+ * every page that nested one. `data-paint` joins them on exactly those terms
246
+ * when a `paint` is named.
101
247
  *
102
248
  * @example
103
249
  * <Density density="ultra-compact">
@@ -105,27 +251,44 @@ const PaintContext = React.createContext(null);
105
251
  * </Density>
106
252
  */
107
253
  function Density({ density, styleSet, paint, children, className, style }) {
108
- const theme = React.useContext(AmbientThemeContext);
109
- const ambientStyleSet = React.useContext(StyleSetContext);
110
- const ambientPaint = React.useContext(PaintContext);
111
- return /* @__PURE__ */ jsx(DensityContext.Provider, {
112
- value: density,
113
- children: /* @__PURE__ */ jsx(StyleSetContext.Provider, {
114
- value: styleSet ?? ambientStyleSet,
115
- children: /* @__PURE__ */ jsx(PaintContext.Provider, {
116
- value: paint ?? ambientPaint,
117
- children: /* @__PURE__ */ jsx("div", {
118
- "data-density": density,
119
- "data-cue-theme": theme ?? void 0,
120
- "data-style": styleSet ?? void 0,
121
- "data-paint": paint ?? void 0,
122
- className,
123
- style,
124
- children
254
+ const theme = useRead(AmbientThemeContext);
255
+ const ambientStyleSet = useRead(StyleSetContext);
256
+ const ambientPaint = useRead(PaintContext);
257
+ const inputs = [
258
+ density,
259
+ styleSet,
260
+ paint,
261
+ React.useContext(AmbientThemeContext),
262
+ React.useContext(StyleSetContext),
263
+ React.useContext(PaintContext)
264
+ ];
265
+ const publishedDensity = usePublish(density, inputs);
266
+ const publishedStyleSet = usePublish(styleSet ?? ambientStyleSet, inputs);
267
+ const publishedPaint = usePublish(paint ?? ambientPaint, inputs);
268
+ const around = React.useContext(RootAxesContext);
269
+ const followed = useFollowedAxes({ theme: theme !== null });
270
+ return /* @__PURE__ */ jsx(RootAxesContext.Provider, {
271
+ value: rootAxes(around.theme, around.mode, false),
272
+ children: /* @__PURE__ */ jsx(DensityContext.Provider, {
273
+ value: publishedDensity,
274
+ children: /* @__PURE__ */ jsx(StyleSetContext.Provider, {
275
+ value: publishedStyleSet,
276
+ children: /* @__PURE__ */ jsx(PaintContext.Provider, {
277
+ value: publishedPaint,
278
+ children: /* @__PURE__ */ jsx("div", {
279
+ "data-density": density,
280
+ "data-cue-theme": followed.theme ? void 0 : theme ?? void 0,
281
+ "data-cue-follows": followed.marker ?? void 0,
282
+ "data-style": styleSet ?? void 0,
283
+ "data-paint": paint ?? void 0,
284
+ className,
285
+ style,
286
+ children
287
+ })
125
288
  })
126
289
  })
127
290
  })
128
291
  });
129
292
  }
130
293
  //#endregion
131
- export { AmbientThemeContext, DEFAULT_DENSITY, Density, DensityContext, PaintContext, StyleSetContext };
294
+ export { AmbientThemeContext, DEFAULT_DENSITY, DeferRestateContext, Density, DensityContext, PaintContext, RootAxesContext, StyleSetContext, rootAxes, useFollowedAxes, useMountedWhen, useRestateReady };
@@ -7,6 +7,6 @@ import { ThemeRegistry } from "./vocabulary.js";
7
7
  import { useDensities, useFonts, useThemes } from "./theme-registry.js";
8
8
  import { ControlSize, useControlHeight, useDensity } from "./use-density.js";
9
9
  import { useTheme } from "./use-theme.js";
10
- import { DEFAULT_STYLE_SET, STYLE_SETS, StyleSet } from "@cueplusplus/tokens";
10
+ import { DEFAULT_PAINT, DEFAULT_STYLE_SET, PAINTS, Paint, STYLE_SETS, StyleSet } from "@cueplusplus/tokens";
11
11
  import { Density as DensityLevel, DensityEntry, FontEntry, FontName, Mode, ThemeManifest, ThemeName } from "@cueplusplus/theme-base";
12
- export { type ControlSize, CuePortalFrame, type CuePortalFrameProps, DEFAULT_STORAGE_KEY, DEFAULT_STYLE_SET, Density, type DensityEntry, type DensityLevel, type DensityProps, type FontEntry, type FontFamilies, type FontName, type Mode, type PersistedPreferences, type PrepaintDefaults, type PrepaintOptions, type ResolvedMode, STYLE_SETS, type StyleSet, type ThemeContextValue, type ThemeManifest, type ThemeName, ThemeProvider, type ThemeProviderProps, type ThemeRegistry, type TokenOverrides, isSafeTokenValue, prepaintScript, useControlHeight, useCuePortalProps, useDensities, useDensity, useFonts, useTheme, useThemes };
12
+ export { type ControlSize, CuePortalFrame, type CuePortalFrameProps, DEFAULT_PAINT, DEFAULT_STORAGE_KEY, DEFAULT_STYLE_SET, Density, type DensityEntry, type DensityLevel, type DensityProps, type FontEntry, type FontFamilies, type FontName, type Mode, PAINTS, type Paint, type PersistedPreferences, type PrepaintDefaults, type PrepaintOptions, type ResolvedMode, STYLE_SETS, type StyleSet, type ThemeContextValue, type ThemeManifest, type ThemeName, ThemeProvider, type ThemeProviderProps, type ThemeRegistry, type TokenOverrides, isSafeTokenValue, prepaintScript, useControlHeight, useCuePortalProps, useDensities, useDensity, useFonts, useTheme, useThemes };
@@ -6,5 +6,5 @@ import { ThemeProvider } from "./theme-provider.js";
6
6
  import { CuePortalFrame, useCuePortalProps } from "./portal.js";
7
7
  import { useControlHeight, useDensity } from "./use-density.js";
8
8
  import { useTheme } from "./use-theme.js";
9
- import { DEFAULT_STYLE_SET, STYLE_SETS } from "@cueplusplus/tokens";
10
- export { CuePortalFrame, DEFAULT_STORAGE_KEY, DEFAULT_STYLE_SET, Density, STYLE_SETS, ThemeProvider, isSafeTokenValue, prepaintScript, useControlHeight, useCuePortalProps, useDensities, useDensity, useFonts, useTheme, useThemes };
9
+ import { DEFAULT_PAINT, DEFAULT_STYLE_SET, PAINTS, STYLE_SETS } from "@cueplusplus/tokens";
10
+ export { CuePortalFrame, DEFAULT_PAINT, DEFAULT_STORAGE_KEY, DEFAULT_STYLE_SET, Density, PAINTS, STYLE_SETS, ThemeProvider, isSafeTokenValue, prepaintScript, useControlHeight, useCuePortalProps, useDensities, useDensity, useFonts, useTheme, useThemes };
@@ -1,3 +1,4 @@
1
+ import "./published.js";
1
2
  import "react";
2
3
  import { ColorToken, GeometryToken, ThemeManifest } from "@cueplusplus/theme-base";
3
4
  //#region src/system/overrides.d.ts
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { published } from "./published.js";
2
3
  import { noteOnce, warnOnce } from "./vocabulary.js";
3
4
  import * as React from "react";
4
5
  import { THEME_NAME_PATTERN, resolve } from "@cueplusplus/theme-base";
@@ -57,9 +58,13 @@ const PREFIX = "--cue-";
57
58
  * `null` means "nothing to stamp" — either no provider above, or a provider
58
59
  * whose overrides publish no colour or font for this mode.
59
60
  *
61
+ * Carried as a `Published` (see `published.ts`): it moves with the resolved
62
+ * mode, which a root's restore can change while streamed boundaries below are
63
+ * still hydrating, and a context value that changes then throws them away.
64
+ *
60
65
  * Internal: consumers get this through the provider, never directly.
61
66
  */
62
- const OverridesContext = React.createContext(null);
67
+ const OverridesContext = React.createContext(published(null));
63
68
  /**
64
69
  * The inline declarations for the resolved mode: colours and fonts.
65
70
  *
@@ -188,10 +193,153 @@ function overridesCss(overrides) {
188
193
  declarations.push(`${PREFIX}${token}:${value}`);
189
194
  }
190
195
  if (declarations.length === 0) continue;
191
- rules.push(`[data-density="${rung}"][data-density="${rung}"]{${declarations.join(";")}}`);
196
+ rules.push(`:where(:root[data-density="${rung}"]) [data-cue-follows~="density"][data-cue-follows~="density"],[data-density="${rung}"][data-density="${rung}"]{${declarations.join(";")}}`);
192
197
  }
193
198
  return rules.join("\n");
194
199
  }
200
+ /** A token name that can be written into a selector's declaration block as it stands. */
201
+ const TOKEN_NAME = /^[a-z0-9-]+$/;
202
+ /** One colour block's declarations, each checked before it is written into a stylesheet. */
203
+ function colorDeclarations(block) {
204
+ const out = [];
205
+ for (const [token, value] of Object.entries(block ?? {})) {
206
+ if (value === void 0) continue;
207
+ if (!TOKEN_NAME.test(token) || !SAFE_VALUE.test(value)) {
208
+ warnOnce(`overrides: colour ${JSON.stringify(token)} ${JSON.stringify(value)} cannot be written into a stylesheet; it applies once the provider has mounted`);
209
+ continue;
210
+ }
211
+ out.push(`${PREFIX}${token}:${value}`);
212
+ }
213
+ return out;
214
+ }
215
+ /** FNV-1a over the UTF-16 units, in base 36: the same text on the server and the client. */
216
+ function digest(text) {
217
+ let hash = 2166136261;
218
+ for (let i = 0; i < text.length; i += 1) {
219
+ hash ^= text.charCodeAt(i);
220
+ hash = Math.imul(hash, 16777619);
221
+ }
222
+ return (hash >>> 0).toString(36);
223
+ }
224
+ /** Stands in for the key while the text the key is a digest of is being written. */
225
+ const KEY = "\0";
226
+ /**
227
+ * `overrides.colors` as a stylesheet keyed on `<html>`, for a provider that
228
+ * cannot know its own resolved mode on this render — or `null` when the mode
229
+ * it would resolve to is the same whatever `<html>` says, and the inline
230
+ * declarations {@link inlineOverrides} writes are already right.
231
+ *
232
+ * **Why.** Colour overrides are inline, and only the block for the resolved
233
+ * mode is written. Under a persisting root, the mode a provider resolves on the
234
+ * server — and on the client's first render, which must agree with it — is the
235
+ * root's PROP, while `<html>` already carries the visitor's stored mode: the
236
+ * persisting root itself until it has restored, and a nested provider whose
237
+ * mode (or theme) is the root's until it has mounted (`useFollowedAxes`). The
238
+ * palette under the edit is the visitor's — the root inherits `<html>`'s, and
239
+ * an island that follows carries no `data-mode` of its own — so the edit for
240
+ * the prop's mode sat on the other mode's ground: two palettes on one surface,
241
+ * an accent chosen for a dark ground on a light one, until the restore or the
242
+ * mount wrote the right block.
243
+ *
244
+ * So for those renders the colours come out of the style attribute and into
245
+ * this: one rule per state of `<html>` that resolves differently, each keyed
246
+ * on that state and carrying only the block that state resolves to — so no
247
+ * mode's edit leaks into the other's, which a fallback rule would. `system` is
248
+ * two rules under the two `prefers-color-scheme` queries; a theme with no light
249
+ * palette (where the theme is `<html>`'s, one of `darkOnly`) is dark under
250
+ * every mode. The fonts stay inline: no mode moves them.
251
+ *
252
+ * **The key.** The rules are scoped to the element by `data-cue-colors`, whose
253
+ * value is a digest of the rules themselves, so it is the same on the server
254
+ * and the client, and two elements that share a key share every rule (a
255
+ * `useId` would do, and would also move the id of every `useId` below every
256
+ * provider, which is every Base UI label in an application). The attribute is
257
+ * written twice for (0,2,0), which ties every theme block the element matches
258
+ * and wins on source order, the density layer's arithmetic ({@link overridesCss}):
259
+ * the element is in `<body>`, after every stylesheet in `<head>`.
260
+ *
261
+ * Like the density layer, this is text written into a `<style>`, so every
262
+ * value is held to the density layer's rule, and a value that fails it waits
263
+ * for the mount, inline, where the CSSOM parses it on its own. Where every
264
+ * value fails it, the stylesheet is EMPTY rather than `null`: `null` would
265
+ * tell the provider its inline block is right, and that block is the edit for
266
+ * a mode that is not `<html>`'s. Empty, the provider renders no `<style>`,
267
+ * stamps no key, and keeps only the fonts inline, as it does for a sheet.
268
+ *
269
+ * Internal.
270
+ *
271
+ * @param overrides - The prop, or `undefined`.
272
+ * @param scope - Which of the mode and the theme are `<html>`'s on this render.
273
+ * @returns The key and the stylesheet — an empty one when every value was
274
+ * refused — or `null` when there is no colour edit, or the mode it resolves
275
+ * to is the same whatever `<html>` says.
276
+ * @example
277
+ * followerColorsCss({ colors: { light: { accent: "#b35900" } } }, { mode: null, supportsLight: true, darkOnly: [] });
278
+ * // → { key: "…", css: ':where(:root[data-mode="light"]) [data-cue-colors="…"][data-cue-colors="…"]{--cue-accent:#b35900}\n…' }
279
+ */
280
+ function followerColorsCss(overrides, scope) {
281
+ const edits = (block) => Object.values(block ?? {}).some((value) => value !== void 0);
282
+ if (!edits(overrides?.colors?.dark) && !edits(overrides?.colors?.light)) return null;
283
+ const modes = scope.mode === null ? [
284
+ {
285
+ mode: "dark",
286
+ on: ":not([data-mode=\"light\"]):not([data-mode=\"system\"])"
287
+ },
288
+ {
289
+ mode: "light",
290
+ on: "[data-mode=\"light\"]"
291
+ },
292
+ {
293
+ mode: "system",
294
+ on: "[data-mode=\"system\"]"
295
+ }
296
+ ] : [{
297
+ mode: scope.mode,
298
+ on: ""
299
+ }];
300
+ const states = [];
301
+ if (scope.supportsLight === false) states.push({
302
+ on: [":root"],
303
+ mode: "dark"
304
+ });
305
+ else {
306
+ const lightCapable = scope.supportsLight === null ? scope.darkOnly.map((name) => `:not([data-theme="${name}"])`).join("") : "";
307
+ for (const { mode, on } of modes) states.push({
308
+ on: [`:root${on}${lightCapable}`],
309
+ mode
310
+ });
311
+ if (scope.supportsLight === null && scope.darkOnly.length > 0) states.push({
312
+ on: scope.darkOnly.map((name) => `:root[data-theme="${name}"]`),
313
+ mode: "dark"
314
+ });
315
+ }
316
+ const resolved = new Set(states.map((state) => state.mode));
317
+ if (resolved.size === 1 && !resolved.has("system")) return null;
318
+ const blocks = {
319
+ dark: colorDeclarations(overrides?.colors?.dark),
320
+ light: colorDeclarations(overrides?.colors?.light)
321
+ };
322
+ const element = `[data-cue-colors="${KEY}"][data-cue-colors="${KEY}"]`;
323
+ const rules = [];
324
+ const rule = (on, mode) => blocks[mode].length === 0 ? null : `:where(${on.join(", ")}) ${element}{${blocks[mode].join(";")}}`;
325
+ for (const { on, mode } of states) {
326
+ if (mode !== "system") {
327
+ const text = rule(on, mode);
328
+ if (text !== null) rules.push(text);
329
+ continue;
330
+ }
331
+ for (const scheme of ["dark", "light"]) {
332
+ const text = rule(on, scheme);
333
+ if (text !== null) rules.push(`@media (prefers-color-scheme: ${scheme}){${text}}`);
334
+ }
335
+ }
336
+ const template = rules.join("\n");
337
+ const key = digest(template);
338
+ return {
339
+ key,
340
+ css: template.replaceAll(KEY, key)
341
+ };
342
+ }
195
343
  /**
196
344
  * Measure the palette an override actually produces, and name what it broke.
197
345
  *
@@ -274,4 +422,4 @@ function reportOverrides(manifest, mode, overrides, theme) {
274
422
  for (const check of after.advisories) if (caused(check)) noteOnce(`overrides: ${check.id} at ${check.ratio.toFixed(2)}:1 misses its ${check.minimum} advisory floor under theme "${theme}"`);
275
423
  }
276
424
  //#endregion
277
- export { OverridesContext, inlineOverrides, isSafeTokenValue, overridesCss, reportOverrides };
425
+ export { OverridesContext, followerColorsCss, inlineOverrides, isSafeTokenValue, overridesCss, reportOverrides };
@@ -8,7 +8,8 @@ import * as React from "react";
8
8
  * `data-theme` / `data-density` / `data-font` / `data-mode` (plus
9
9
  * `--cue-font-scale` and any `ThemeProvider` `overrides` colour or font
10
10
  * property) copied from the nearest provider and density island, with
11
- * `data-style` when the caller is inside a style set, and with
11
+ * `data-style` when the caller is inside a style set, `data-paint` when it is
12
+ * inside a pack, and with
12
13
  * `data-cue-skin` / `data-cue-fidelity` when the caller sits inside an
13
14
  * `AgentSurface` island. The container is
14
15
  * `display: contents`, so it changes no layout and creates no containing block —
@@ -43,7 +44,7 @@ interface CuePortalFrameProps {
43
44
  *
44
45
  * Wraps `children` in a `display: contents` element carrying the same
45
46
  * `data-theme` / `data-density` / `data-font` / `data-mode` / `data-style` /
46
- * `data-cue-skin` / `data-cue-fidelity` stamp, `--cue-font-scale` and
47
+ * `data-paint` / `data-cue-skin` / `data-cue-fidelity` stamp, `--cue-font-scale` and
47
48
  * `overrides` properties as {@link useCuePortalProps}. Prefer the hook — a
48
49
  * stamped container costs one element per overlay instead of one per render
49
50
  * tree — and reach for this only when the container prop is not available.
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect.js";
3
3
  import { AgentSkinContext } from "./agent-skin.js";
4
+ import { useRead } from "./published.js";
4
5
  import { DensityContext, PaintContext, StyleSetContext } from "./density.js";
5
6
  import { OverridesContext } from "./overrides.js";
6
- import { FontFamiliesContext, FontScaleContext, ThemeContext } from "./theme-provider.js";
7
+ import { FontFamiliesContext, FontScaleContext, PairingSeedContext, ThemeContext } from "./theme-provider.js";
7
8
  import * as React from "react";
8
9
  import { jsx } from "react/jsx-runtime";
9
10
  import { DEFAULT_FONT } from "@cueplusplus/tokens";
@@ -24,14 +25,14 @@ const FONT_MONO_PROPERTY = "--cue-font-mono";
24
25
  * exactly the same reason and by the same route.
25
26
  */
26
27
  function usePortalStamp() {
27
- const theme = React.useContext(ThemeContext);
28
- const island = React.useContext(DensityContext);
28
+ const theme = useRead(ThemeContext);
29
+ const island = useRead(DensityContext);
29
30
  const fontScale = React.useContext(FontScaleContext);
30
31
  const fontFamilies = React.useContext(FontFamiliesContext);
31
- const overrides = React.useContext(OverridesContext);
32
+ const overrides = useRead(OverridesContext);
32
33
  const skin = React.useContext(AgentSkinContext);
33
- const styleSet = React.useContext(StyleSetContext);
34
- const paint = React.useContext(PaintContext);
34
+ const styleSet = useRead(StyleSetContext);
35
+ const paint = useRead(PaintContext);
35
36
  return {
36
37
  theme: theme?.theme ?? DEFAULT_THEME,
37
38
  density: island ?? theme?.density ?? "compact",
@@ -54,7 +55,8 @@ function usePortalStamp() {
54
55
  * `data-theme` / `data-density` / `data-font` / `data-mode` (plus
55
56
  * `--cue-font-scale` and any `ThemeProvider` `overrides` colour or font
56
57
  * property) copied from the nearest provider and density island, with
57
- * `data-style` when the caller is inside a style set, and with
58
+ * `data-style` when the caller is inside a style set, `data-paint` when it is
59
+ * inside a pack, and with
58
60
  * `data-cue-skin` / `data-cue-fidelity` when the caller sits inside an
59
61
  * `AgentSurface` island. The container is
60
62
  * `display: contents`, so it changes no layout and creates no containing block —
@@ -76,13 +78,16 @@ function useCuePortalProps() {
76
78
  const stamp = usePortalStamp();
77
79
  const stampRef = React.useRef(stamp);
78
80
  stampRef.current = stamp;
81
+ const seed = React.useContext(PairingSeedContext);
82
+ const seedRef = React.useRef(seed);
83
+ seedRef.current = seed;
79
84
  const [container, setContainer] = React.useState(null);
80
85
  useIsomorphicLayoutEffect(() => {
81
86
  if (typeof document === "undefined") return;
82
87
  const element = document.createElement("div");
83
88
  element.setAttribute("data-cue-portal", "");
84
89
  element.style.display = "contents";
85
- applyStamp(element, stampRef.current);
90
+ applyStamp(element, seeded(stampRef.current, seedRef.current()));
86
91
  document.body.appendChild(element);
87
92
  setContainer(element);
88
93
  return () => {
@@ -92,7 +97,7 @@ function useCuePortalProps() {
92
97
  }, []);
93
98
  useIsomorphicLayoutEffect(() => {
94
99
  if (container === null) return;
95
- applyStamp(container, stamp);
100
+ applyStamp(container, seeded(stamp, seedRef.current()));
96
101
  }, [
97
102
  container,
98
103
  stamp.theme,
@@ -127,6 +132,13 @@ function useCuePortalProps() {
127
132
  * and collected with it, which is what makes the weak reference the right one.
128
133
  */
129
134
  const stampedOverrides = /* @__PURE__ */ new WeakMap();
135
+ /** `stamp`, in the pairing `seed` names when it names one (see `PairingSeedContext`). */
136
+ function seeded(stamp, seed) {
137
+ return seed === null ? stamp : {
138
+ ...stamp,
139
+ font: seed
140
+ };
141
+ }
130
142
  /** Write a stamp onto a live element (the imperative half of the contract). */
131
143
  function applyStamp(element, stamp) {
132
144
  element.setAttribute("data-theme", stamp.theme);
@@ -162,7 +174,7 @@ function setOptionalProperty(element, property, value) {
162
174
  *
163
175
  * Wraps `children` in a `display: contents` element carrying the same
164
176
  * `data-theme` / `data-density` / `data-font` / `data-mode` / `data-style` /
165
- * `data-cue-skin` / `data-cue-fidelity` stamp, `--cue-font-scale` and
177
+ * `data-paint` / `data-cue-skin` / `data-cue-fidelity` stamp, `--cue-font-scale` and
166
178
  * `overrides` properties as {@link useCuePortalProps}. Prefer the hook — a
167
179
  * stamped container costs one element per overlay instead of one per render
168
180
  * tree — and reach for this only when the container prop is not available.