@lostgradient/cinder 0.1.1 → 0.2.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 (551) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +163 -0
  3. package/components.json +390 -3
  4. package/dist/_internal/chart/chart-focus-ring.d.ts +57 -0
  5. package/dist/_internal/chart/chart-utilities.d.ts +2 -0
  6. package/dist/_internal/chart/heatmap-utilities.d.ts +60 -0
  7. package/dist/components/accordion/index.js +14 -1
  8. package/dist/components/alert/alert.schema.js +3 -3
  9. package/dist/components/alert/alert.types.d.ts +3 -2
  10. package/dist/components/alert/index.js +3 -2
  11. package/dist/components/alert-dialog/index.js +11 -2
  12. package/dist/components/area-chart/area-chart.css +57 -7
  13. package/dist/components/area-chart/index.js +283 -40
  14. package/dist/components/avatar-group/avatar-group.css +2 -3
  15. package/dist/components/badge/badge.css +17 -0
  16. package/dist/components/badge/badge.schema.js +6 -1
  17. package/dist/components/badge/badge.types.d.ts +7 -0
  18. package/dist/components/badge/index.js +4 -2
  19. package/dist/components/bar-chart/bar-chart.css +57 -7
  20. package/dist/components/bar-chart/index.js +233 -45
  21. package/dist/components/button/button.css +5 -3
  22. package/dist/components/button/index.js +11 -2
  23. package/dist/components/capability-gate/capability-gate.css +131 -0
  24. package/dist/components/capability-gate/capability-gate.schema.d.ts +3 -0
  25. package/dist/components/capability-gate/capability-gate.schema.js +128 -0
  26. package/dist/components/capability-gate/capability-gate.svelte.d.ts +19 -0
  27. package/dist/components/capability-gate/capability-gate.types.d.ts +70 -0
  28. package/dist/components/capability-gate/capability-gate.variables.d.ts +2 -0
  29. package/dist/components/capability-gate/capability-gate.variables.js +61 -0
  30. package/dist/components/capability-gate/index.d.ts +5 -0
  31. package/dist/components/capability-gate/index.js +285 -0
  32. package/dist/components/card/card.css +4 -0
  33. package/dist/components/card/card.schema.js +5 -1
  34. package/dist/components/card/card.svelte.d.ts +1 -1
  35. package/dist/components/card/card.types.d.ts +4 -0
  36. package/dist/components/card/index.d.ts +1 -1
  37. package/dist/components/card/index.js +8 -4
  38. package/dist/components/chat/index.css +2 -2
  39. package/dist/components/chat/index.js +159 -81
  40. package/dist/components/choice-grid/choice-grid-context.d.ts +23 -0
  41. package/dist/components/choice-grid/choice-grid.css +27 -0
  42. package/dist/components/choice-grid/choice-grid.schema.d.ts +3 -0
  43. package/dist/components/choice-grid/choice-grid.schema.js +121 -0
  44. package/dist/components/choice-grid/choice-grid.svelte.d.ts +20 -0
  45. package/dist/components/choice-grid/choice-grid.types.d.ts +122 -0
  46. package/dist/components/choice-grid/choice-grid.variables.d.ts +2 -0
  47. package/dist/components/choice-grid/choice-grid.variables.js +61 -0
  48. package/dist/components/choice-grid/index.d.ts +13 -0
  49. package/dist/components/choice-grid/index.js +466 -0
  50. package/dist/components/choice-grid-item/choice-grid-item.css +139 -0
  51. package/dist/components/choice-grid-item/choice-grid-item.schema.d.ts +3 -0
  52. package/dist/components/choice-grid-item/choice-grid-item.schema.js +93 -0
  53. package/dist/components/choice-grid-item/choice-grid-item.svelte.d.ts +17 -0
  54. package/dist/components/choice-grid-item/choice-grid-item.types.d.ts +24 -0
  55. package/dist/components/choice-grid-item/choice-grid-item.variables.d.ts +2 -0
  56. package/dist/components/choice-grid-item/choice-grid-item.variables.js +61 -0
  57. package/dist/components/choice-grid-item/index.d.ts +5 -0
  58. package/dist/components/choice-grid-item/index.js +203 -0
  59. package/dist/components/color-field/color-field.css +6 -9
  60. package/dist/components/color-picker/color-picker.css +31 -24
  61. package/dist/components/color-swatch-picker/color-swatch-picker.css +6 -9
  62. package/dist/components/confirm-dialog/index.js +11 -2
  63. package/dist/components/context-menu/index.js +114 -43
  64. package/dist/components/context-menu-trigger/index.js +6 -4
  65. package/dist/components/data-table/data-table.css +30 -0
  66. package/dist/components/data-table/data-table.schema.d.ts +3 -0
  67. package/dist/components/data-table/data-table.schema.js +103 -0
  68. package/dist/components/data-table/data-table.svelte.d.ts +39 -0
  69. package/dist/components/data-table/data-table.types.d.ts +86 -0
  70. package/dist/components/data-table/data-table.variables.d.ts +2 -0
  71. package/dist/components/data-table/data-table.variables.js +61 -0
  72. package/dist/components/data-table/index.d.ts +5 -0
  73. package/dist/components/data-table/index.js +591 -0
  74. package/dist/components/diff-viewer/index.js +14 -3
  75. package/dist/components/dropdown/index.js +115 -46
  76. package/dist/components/dropdown-item/dropdown-item.schema.js +13 -1
  77. package/dist/components/dropdown-item/dropdown-item.svelte.d.ts +1 -1
  78. package/dist/components/dropdown-item/dropdown-item.types.d.ts +46 -2
  79. package/dist/components/dropdown-item/index.d.ts +1 -1
  80. package/dist/components/dropdown-item/index.js +97 -28
  81. package/dist/components/floating-action-button/floating-action-button.css +4 -2
  82. package/dist/components/json-schema-editor/index.js +29 -4
  83. package/dist/components/keyboard-shortcuts/index.d.ts +5 -0
  84. package/dist/components/keyboard-shortcuts/index.js +238 -0
  85. package/dist/components/keyboard-shortcuts/keyboard-shortcuts.css +84 -0
  86. package/dist/components/keyboard-shortcuts/keyboard-shortcuts.schema.d.ts +3 -0
  87. package/dist/components/keyboard-shortcuts/keyboard-shortcuts.schema.js +87 -0
  88. package/dist/components/keyboard-shortcuts/keyboard-shortcuts.svelte.d.ts +17 -0
  89. package/dist/components/keyboard-shortcuts/keyboard-shortcuts.types.d.ts +42 -0
  90. package/dist/components/keyboard-shortcuts/keyboard-shortcuts.variables.d.ts +2 -0
  91. package/dist/components/keyboard-shortcuts/keyboard-shortcuts.variables.js +61 -0
  92. package/dist/components/line-chart/index.js +283 -40
  93. package/dist/components/line-chart/line-chart.css +57 -8
  94. package/dist/components/markdown-editor/index.js +129 -51
  95. package/dist/components/matrix-chart/index.d.ts +5 -0
  96. package/dist/components/matrix-chart/index.js +1232 -0
  97. package/dist/components/matrix-chart/matrix-chart.css +50 -0
  98. package/dist/components/matrix-chart/matrix-chart.schema.d.ts +3 -0
  99. package/dist/components/matrix-chart/matrix-chart.schema.js +123 -0
  100. package/dist/components/matrix-chart/matrix-chart.svelte.d.ts +20 -0
  101. package/dist/components/matrix-chart/matrix-chart.types.d.ts +52 -0
  102. package/dist/components/matrix-chart/matrix-chart.variables.d.ts +2 -0
  103. package/dist/components/matrix-chart/matrix-chart.variables.js +61 -0
  104. package/dist/components/media-controls/index.d.ts +5 -0
  105. package/dist/components/media-controls/index.js +338 -0
  106. package/dist/components/media-controls/media-controls.css +112 -0
  107. package/dist/components/media-controls/media-controls.schema.d.ts +3 -0
  108. package/dist/components/media-controls/media-controls.schema.js +125 -0
  109. package/dist/components/media-controls/media-controls.svelte.d.ts +18 -0
  110. package/dist/components/media-controls/media-controls.types.d.ts +77 -0
  111. package/dist/components/media-controls/media-controls.variables.d.ts +2 -0
  112. package/dist/components/media-controls/media-controls.variables.js +61 -0
  113. package/dist/components/navigation-bar/navigation-bar.schema.js +5 -5
  114. package/dist/components/navigation-bar/navigation-bar.types.d.ts +2 -1
  115. package/dist/components/pricing-card/index.d.ts +5 -0
  116. package/dist/components/pricing-card/index.js +406 -0
  117. package/dist/components/pricing-card/pricing-card.css +173 -0
  118. package/dist/components/pricing-card/pricing-card.schema.d.ts +3 -0
  119. package/dist/components/pricing-card/pricing-card.schema.js +100 -0
  120. package/dist/components/pricing-card/pricing-card.svelte.d.ts +18 -0
  121. package/dist/components/pricing-card/pricing-card.types.d.ts +47 -0
  122. package/dist/components/pricing-card/pricing-card.variables.d.ts +2 -0
  123. package/dist/components/pricing-card/pricing-card.variables.js +61 -0
  124. package/dist/components/review-editor/index.js +212 -132
  125. package/dist/components/share-card/index.d.ts +5 -0
  126. package/dist/components/share-card/index.js +446 -0
  127. package/dist/components/share-card/share-card.css +115 -0
  128. package/dist/components/share-card/share-card.schema.d.ts +3 -0
  129. package/dist/components/share-card/share-card.schema.js +113 -0
  130. package/dist/components/share-card/share-card.svelte.d.ts +18 -0
  131. package/dist/components/share-card/share-card.types.d.ts +66 -0
  132. package/dist/components/share-card/share-card.variables.d.ts +2 -0
  133. package/dist/components/share-card/share-card.variables.js +61 -0
  134. package/dist/components/shortcut-hint/index.d.ts +5 -0
  135. package/dist/components/shortcut-hint/index.js +197 -0
  136. package/dist/components/shortcut-hint/shortcut-hint.css +26 -0
  137. package/dist/components/shortcut-hint/shortcut-hint.schema.d.ts +3 -0
  138. package/dist/components/shortcut-hint/shortcut-hint.schema.js +96 -0
  139. package/dist/components/shortcut-hint/shortcut-hint.svelte.d.ts +17 -0
  140. package/dist/components/shortcut-hint/shortcut-hint.types.d.ts +33 -0
  141. package/dist/components/shortcut-hint/shortcut-hint.variables.d.ts +2 -0
  142. package/dist/components/shortcut-hint/shortcut-hint.variables.js +61 -0
  143. package/dist/components/skip-link/index.d.ts +4 -0
  144. package/dist/components/skip-link/index.js +180 -0
  145. package/dist/components/skip-link/skip-link.schema.d.ts +3 -0
  146. package/dist/components/skip-link/skip-link.schema.js +76 -0
  147. package/dist/components/skip-link/skip-link.svelte.d.ts +19 -0
  148. package/dist/components/skip-link/skip-link.types.d.ts +38 -0
  149. package/dist/components/skip-link/skip-link.variables.d.ts +2 -0
  150. package/dist/components/skip-link/skip-link.variables.js +61 -0
  151. package/dist/components/spectrogram/index.d.ts +5 -0
  152. package/dist/components/spectrogram/index.js +1156 -0
  153. package/dist/components/spectrogram/spectrogram.css +43 -0
  154. package/dist/components/spectrogram/spectrogram.schema.d.ts +3 -0
  155. package/dist/components/spectrogram/spectrogram.schema.js +103 -0
  156. package/dist/components/spectrogram/spectrogram.svelte.d.ts +21 -0
  157. package/dist/components/spectrogram/spectrogram.types.d.ts +60 -0
  158. package/dist/components/spectrogram/spectrogram.variables.d.ts +2 -0
  159. package/dist/components/spectrogram/spectrogram.variables.js +61 -0
  160. package/dist/components/spectrum-chart/index.d.ts +5 -0
  161. package/dist/components/spectrum-chart/index.js +1056 -0
  162. package/dist/components/spectrum-chart/spectrum-chart.css +49 -0
  163. package/dist/components/spectrum-chart/spectrum-chart.schema.d.ts +3 -0
  164. package/dist/components/spectrum-chart/spectrum-chart.schema.js +97 -0
  165. package/dist/components/spectrum-chart/spectrum-chart.svelte.d.ts +21 -0
  166. package/dist/components/spectrum-chart/spectrum-chart.types.d.ts +41 -0
  167. package/dist/components/spectrum-chart/spectrum-chart.variables.d.ts +2 -0
  168. package/dist/components/spectrum-chart/spectrum-chart.variables.js +61 -0
  169. package/dist/components/status-dot/status-dot.css +8 -0
  170. package/dist/components/status-dot/status-dot.schema.js +3 -3
  171. package/dist/components/status-dot/status-dot.types.d.ts +5 -2
  172. package/dist/components/subscription-badge/index.d.ts +5 -0
  173. package/dist/components/subscription-badge/index.js +383 -0
  174. package/dist/components/subscription-badge/subscription-badge.css +18 -0
  175. package/dist/components/subscription-badge/subscription-badge.schema.d.ts +3 -0
  176. package/dist/components/subscription-badge/subscription-badge.schema.js +77 -0
  177. package/dist/components/subscription-badge/subscription-badge.svelte.d.ts +19 -0
  178. package/dist/components/subscription-badge/subscription-badge.types.d.ts +28 -0
  179. package/dist/components/subscription-badge/subscription-badge.variables.d.ts +2 -0
  180. package/dist/components/subscription-badge/subscription-badge.variables.js +61 -0
  181. package/dist/components/tab/index.js +14 -1
  182. package/dist/components/table/index.js +26 -17
  183. package/dist/components/table-cell/index.js +18 -9
  184. package/dist/components/table-cell/table-cell.schema.js +5 -1
  185. package/dist/components/table-cell/table-cell.types.d.ts +16 -1
  186. package/dist/components/tabs/index.js +14 -1
  187. package/dist/components/waveform/index.d.ts +5 -0
  188. package/dist/components/waveform/index.js +1075 -0
  189. package/dist/components/waveform/waveform.css +53 -0
  190. package/dist/components/waveform/waveform.schema.d.ts +3 -0
  191. package/dist/components/waveform/waveform.schema.js +98 -0
  192. package/dist/components/waveform/waveform.svelte.d.ts +20 -0
  193. package/dist/components/waveform/waveform.types.d.ts +42 -0
  194. package/dist/components/waveform/waveform.variables.d.ts +2 -0
  195. package/dist/components/waveform/waveform.variables.js +61 -0
  196. package/dist/index.d.ts +33 -2
  197. package/dist/index.js +144 -115
  198. package/dist/server/components/accordion/index.js +14 -1
  199. package/dist/server/components/alert/alert.schema.js +3 -3
  200. package/dist/server/components/alert/index.js +3 -2
  201. package/dist/server/components/alert-dialog/index.js +12 -3
  202. package/dist/server/components/area-chart/index.css +50 -3
  203. package/dist/server/components/area-chart/index.js +181 -2
  204. package/dist/server/components/avatar-group/index.css +1 -1
  205. package/dist/server/components/badge/badge.schema.js +6 -1
  206. package/dist/server/components/badge/index.css +4 -0
  207. package/dist/server/components/badge/index.js +3 -1
  208. package/dist/server/components/bar-chart/index.css +50 -3
  209. package/dist/server/components/bar-chart/index.js +166 -2
  210. package/dist/server/components/button/index.css +1 -1
  211. package/dist/server/components/button/index.js +12 -3
  212. package/dist/server/components/capability-gate/capability-gate.schema.js +110 -0
  213. package/dist/server/components/capability-gate/capability-gate.variables.js +43 -0
  214. package/dist/server/components/capability-gate/index.css +121 -0
  215. package/dist/server/components/capability-gate/index.js +168 -0
  216. package/dist/server/components/card/card.schema.js +5 -1
  217. package/dist/server/components/card/index.css +9 -1
  218. package/dist/server/components/card/index.js +3 -2
  219. package/dist/server/components/chat/index.css +2 -2
  220. package/dist/server/components/chat/index.js +78 -19
  221. package/dist/server/components/choice-grid/choice-grid.schema.js +103 -0
  222. package/dist/server/components/choice-grid/choice-grid.variables.js +43 -0
  223. package/dist/server/components/choice-grid/index.css +103 -0
  224. package/dist/server/components/choice-grid/index.js +383 -0
  225. package/dist/server/components/choice-grid-item/choice-grid-item.schema.js +75 -0
  226. package/dist/server/components/choice-grid-item/choice-grid-item.variables.js +43 -0
  227. package/dist/server/components/choice-grid-item/index.css +86 -0
  228. package/dist/server/components/choice-grid-item/index.js +139 -0
  229. package/dist/server/components/color-field/index.css +2 -4
  230. package/dist/server/components/color-picker/index.css +14 -10
  231. package/dist/server/components/color-swatch-picker/index.css +2 -4
  232. package/dist/server/components/confirm-dialog/index.js +12 -3
  233. package/dist/server/components/context-menu/index.js +72 -20
  234. package/dist/server/components/context-menu-trigger/index.js +6 -4
  235. package/dist/server/components/data-table/data-table.schema.js +85 -0
  236. package/dist/server/components/data-table/data-table.variables.js +43 -0
  237. package/dist/server/components/data-table/index.css +182 -0
  238. package/dist/server/components/data-table/index.js +469 -0
  239. package/dist/server/components/diff-viewer/index.js +14 -3
  240. package/dist/server/components/dropdown/index.js +67 -17
  241. package/dist/server/components/dropdown-item/dropdown-item.schema.js +13 -1
  242. package/dist/server/components/dropdown-item/index.js +67 -17
  243. package/dist/server/components/floating-action-button/index.css +1 -1
  244. package/dist/server/components/json-schema-editor/index.js +29 -4
  245. package/dist/server/components/keyboard-shortcuts/index.css +86 -0
  246. package/dist/server/components/keyboard-shortcuts/index.js +149 -0
  247. package/dist/server/components/keyboard-shortcuts/keyboard-shortcuts.schema.js +69 -0
  248. package/dist/server/components/keyboard-shortcuts/keyboard-shortcuts.variables.js +43 -0
  249. package/dist/server/components/line-chart/index.css +50 -3
  250. package/dist/server/components/line-chart/index.js +181 -2
  251. package/dist/server/components/markdown-editor/index.js +78 -19
  252. package/dist/server/components/matrix-chart/index.css +52 -0
  253. package/dist/server/components/matrix-chart/index.js +1026 -0
  254. package/dist/server/components/matrix-chart/matrix-chart.schema.js +105 -0
  255. package/dist/server/components/matrix-chart/matrix-chart.variables.js +43 -0
  256. package/dist/server/components/media-controls/index.css +109 -0
  257. package/dist/server/components/media-controls/index.js +192 -0
  258. package/dist/server/components/media-controls/media-controls.schema.js +107 -0
  259. package/dist/server/components/media-controls/media-controls.variables.js +43 -0
  260. package/dist/server/components/navigation-bar/navigation-bar.schema.js +5 -5
  261. package/dist/server/components/pricing-card/index.css +131 -0
  262. package/dist/server/components/pricing-card/index.js +258 -0
  263. package/dist/server/components/pricing-card/pricing-card.schema.js +82 -0
  264. package/dist/server/components/pricing-card/pricing-card.variables.js +43 -0
  265. package/dist/server/components/review-editor/index.css +2 -2
  266. package/dist/server/components/review-editor/index.js +80 -19
  267. package/dist/server/components/share-card/index.css +113 -0
  268. package/dist/server/components/share-card/index.js +270 -0
  269. package/dist/server/components/share-card/share-card.schema.js +95 -0
  270. package/dist/server/components/share-card/share-card.variables.js +43 -0
  271. package/dist/server/components/shortcut-hint/index.css +28 -0
  272. package/dist/server/components/shortcut-hint/index.js +134 -0
  273. package/dist/server/components/shortcut-hint/shortcut-hint.schema.js +78 -0
  274. package/dist/server/components/shortcut-hint/shortcut-hint.variables.js +43 -0
  275. package/dist/server/components/skip-link/index.js +141 -0
  276. package/dist/server/components/skip-link/skip-link.schema.js +58 -0
  277. package/dist/server/components/skip-link/skip-link.variables.js +43 -0
  278. package/dist/server/components/spectrogram/index.css +45 -0
  279. package/dist/server/components/spectrogram/index.js +970 -0
  280. package/dist/server/components/spectrogram/spectrogram.schema.js +85 -0
  281. package/dist/server/components/spectrogram/spectrogram.variables.js +43 -0
  282. package/dist/server/components/spectrum-chart/index.css +51 -0
  283. package/dist/server/components/spectrum-chart/index.js +871 -0
  284. package/dist/server/components/spectrum-chart/spectrum-chart.schema.js +79 -0
  285. package/dist/server/components/spectrum-chart/spectrum-chart.variables.js +43 -0
  286. package/dist/server/components/status-dot/index.css +8 -0
  287. package/dist/server/components/status-dot/status-dot.schema.js +3 -3
  288. package/dist/server/components/subscription-badge/index.css +2 -0
  289. package/dist/server/components/subscription-badge/index.js +339 -0
  290. package/dist/server/components/subscription-badge/subscription-badge.schema.js +59 -0
  291. package/dist/server/components/subscription-badge/subscription-badge.variables.js +43 -0
  292. package/dist/server/components/tab/index.js +14 -1
  293. package/dist/server/components/table/index.js +13 -8
  294. package/dist/server/components/table-cell/index.js +13 -8
  295. package/dist/server/components/table-cell/table-cell.schema.js +5 -1
  296. package/dist/server/components/tabs/index.js +14 -1
  297. package/dist/server/components/waveform/index.css +55 -0
  298. package/dist/server/components/waveform/index.js +907 -0
  299. package/dist/server/components/waveform/waveform.schema.js +80 -0
  300. package/dist/server/components/waveform/waveform.variables.js +43 -0
  301. package/dist/server/index.css +1137 -55
  302. package/dist/server/index.js +4225 -1750
  303. package/package.json +380 -2
  304. package/src/_internal/chart/chart-focus-ring.ts +209 -0
  305. package/src/_internal/chart/chart-utilities.ts +4 -0
  306. package/src/_internal/chart/heatmap-utilities.ts +159 -0
  307. package/src/components/accordion/accordion.examples.json +1 -0
  308. package/src/components/alert/README.md +5 -5
  309. package/src/components/alert/alert.schema.json +2 -2
  310. package/src/components/alert/alert.schema.ts +3 -2
  311. package/src/components/alert/alert.svelte +5 -1
  312. package/src/components/alert/alert.types.ts +3 -2
  313. package/src/components/area-chart/README.md +62 -0
  314. package/src/components/area-chart/area-chart.css +57 -7
  315. package/src/components/area-chart/area-chart.svelte +128 -10
  316. package/src/components/avatar-group/avatar-group.css +2 -3
  317. package/src/components/avatar-group/avatar-group.examples.json +1 -0
  318. package/src/components/backdrop/README.md +56 -0
  319. package/src/components/badge/README.md +6 -5
  320. package/src/components/badge/badge.css +17 -0
  321. package/src/components/badge/badge.schema.json +5 -0
  322. package/src/components/badge/badge.schema.ts +6 -0
  323. package/src/components/badge/badge.svelte +2 -0
  324. package/src/components/badge/badge.types.ts +7 -0
  325. package/src/components/bar-chart/README.md +65 -0
  326. package/src/components/bar-chart/bar-chart.css +57 -7
  327. package/src/components/bar-chart/bar-chart.svelte +94 -13
  328. package/src/components/button/button.css +5 -3
  329. package/src/components/button/button.examples.json +1 -0
  330. package/src/components/button/button.svelte +15 -0
  331. package/src/components/capability-gate/README.md +60 -0
  332. package/src/components/capability-gate/capability-gate.css +131 -0
  333. package/src/components/capability-gate/capability-gate.examples.json +19 -0
  334. package/src/components/capability-gate/capability-gate.schema.json +68 -0
  335. package/src/components/capability-gate/capability-gate.schema.ts +72 -0
  336. package/src/components/capability-gate/capability-gate.svelte +186 -0
  337. package/src/components/capability-gate/capability-gate.types.ts +83 -0
  338. package/src/components/capability-gate/capability-gate.variables.json +1 -0
  339. package/src/components/capability-gate/capability-gate.variables.ts +3 -0
  340. package/src/components/capability-gate/index.ts +10 -0
  341. package/src/components/card/README.md +1 -0
  342. package/src/components/card/card.css +4 -0
  343. package/src/components/card/card.examples.json +6 -0
  344. package/src/components/card/card.schema.json +4 -0
  345. package/src/components/card/card.schema.ts +5 -0
  346. package/src/components/card/card.svelte +9 -2
  347. package/src/components/card/card.types.ts +4 -0
  348. package/src/components/card/index.ts +1 -1
  349. package/src/components/chat/README.md +81 -0
  350. package/src/components/chat/container/chat-jump-controls.svelte +12 -9
  351. package/src/components/chat/input/chat-input.svelte +7 -8
  352. package/src/components/chat/message/chat-message.svelte +15 -20
  353. package/src/components/chat/message/tool-call-group.svelte +10 -4
  354. package/src/components/choice-grid/README.md +66 -0
  355. package/src/components/choice-grid/choice-grid-context.ts +30 -0
  356. package/src/components/choice-grid/choice-grid.css +27 -0
  357. package/src/components/choice-grid/choice-grid.examples.json +31 -0
  358. package/src/components/choice-grid/choice-grid.schema.json +61 -0
  359. package/src/components/choice-grid/choice-grid.schema.ts +70 -0
  360. package/src/components/choice-grid/choice-grid.svelte +272 -0
  361. package/src/components/choice-grid/choice-grid.types.ts +152 -0
  362. package/src/components/choice-grid/choice-grid.variables.json +1 -0
  363. package/src/components/choice-grid/choice-grid.variables.ts +3 -0
  364. package/src/components/choice-grid/index.ts +22 -0
  365. package/src/components/choice-grid-item/README.md +41 -0
  366. package/src/components/choice-grid-item/choice-grid-item.css +139 -0
  367. package/src/components/choice-grid-item/choice-grid-item.schema.json +32 -0
  368. package/src/components/choice-grid-item/choice-grid-item.schema.ts +38 -0
  369. package/src/components/choice-grid-item/choice-grid-item.svelte +139 -0
  370. package/src/components/choice-grid-item/choice-grid-item.types.ts +30 -0
  371. package/src/components/choice-grid-item/choice-grid-item.variables.json +1 -0
  372. package/src/components/choice-grid-item/choice-grid-item.variables.ts +3 -0
  373. package/src/components/choice-grid-item/index.ts +6 -0
  374. package/src/components/click-away-listener/README.md +50 -0
  375. package/src/components/color-field/color-field.css +6 -9
  376. package/src/components/color-picker/color-picker.css +31 -24
  377. package/src/components/color-swatch-picker/color-swatch-picker.css +6 -9
  378. package/src/components/command-menu/README.md +61 -0
  379. package/src/components/confirm-dialog/confirm-dialog.examples.json +6 -0
  380. package/src/components/context-menu/README.md +55 -0
  381. package/src/components/context-menu-trigger/README.md +50 -0
  382. package/src/components/context-menu-trigger/context-menu-trigger.svelte +5 -3
  383. package/src/components/data-table/README.md +67 -0
  384. package/src/components/data-table/data-table.css +30 -0
  385. package/src/components/data-table/data-table.examples.json +19 -0
  386. package/src/components/data-table/data-table.schema.json +43 -0
  387. package/src/components/data-table/data-table.schema.ts +50 -0
  388. package/src/components/data-table/data-table.svelte +106 -0
  389. package/src/components/data-table/data-table.types.ts +89 -0
  390. package/src/components/data-table/data-table.variables.json +1 -0
  391. package/src/components/data-table/data-table.variables.ts +3 -0
  392. package/src/components/data-table/index.ts +6 -0
  393. package/src/components/diff-viewer/README.md +59 -0
  394. package/src/components/diff-viewer/front-matter-header.svelte +20 -4
  395. package/src/components/dropdown-group/README.md +52 -0
  396. package/src/components/dropdown-item/README.md +10 -7
  397. package/src/components/dropdown-item/dropdown-item.schema.json +12 -0
  398. package/src/components/dropdown-item/dropdown-item.schema.ts +14 -0
  399. package/src/components/dropdown-item/dropdown-item.svelte +108 -25
  400. package/src/components/dropdown-item/dropdown-item.types.ts +58 -2
  401. package/src/components/dropdown-item/index.ts +6 -1
  402. package/src/components/floating-action-button/README.md +53 -0
  403. package/src/components/floating-action-button/floating-action-button.css +4 -2
  404. package/src/components/form-section/form-section.examples.json +6 -0
  405. package/src/components/hover-card/README.md +60 -0
  406. package/src/components/json-schema-editor/README.md +59 -0
  407. package/src/components/kanban-board/README.md +62 -0
  408. package/src/components/keyboard-shortcuts/README.md +51 -0
  409. package/src/components/keyboard-shortcuts/index.ts +10 -0
  410. package/src/components/keyboard-shortcuts/keyboard-shortcuts.css +84 -0
  411. package/src/components/keyboard-shortcuts/keyboard-shortcuts.examples.json +13 -0
  412. package/src/components/keyboard-shortcuts/keyboard-shortcuts.schema.json +27 -0
  413. package/src/components/keyboard-shortcuts/keyboard-shortcuts.schema.ts +31 -0
  414. package/src/components/keyboard-shortcuts/keyboard-shortcuts.svelte +91 -0
  415. package/src/components/keyboard-shortcuts/keyboard-shortcuts.types.ts +46 -0
  416. package/src/components/keyboard-shortcuts/keyboard-shortcuts.variables.json +1 -0
  417. package/src/components/keyboard-shortcuts/keyboard-shortcuts.variables.ts +3 -0
  418. package/src/components/line-chart/README.md +61 -0
  419. package/src/components/line-chart/line-chart.css +57 -8
  420. package/src/components/line-chart/line-chart.svelte +128 -10
  421. package/src/components/link/README.md +55 -0
  422. package/src/components/markdown-editor/README.md +70 -0
  423. package/src/components/markdown-editor/editor-toolbar/toolbar-button.svelte +9 -4
  424. package/src/components/markdown-editor/editor-toolbar/toolbar-dropdown.svelte +9 -4
  425. package/src/components/markdown-editor/prosemirror.css +4 -2
  426. package/src/components/matrix-chart/README.md +61 -0
  427. package/src/components/matrix-chart/index.ts +10 -0
  428. package/src/components/matrix-chart/matrix-chart.css +50 -0
  429. package/src/components/matrix-chart/matrix-chart.examples.json +19 -0
  430. package/src/components/matrix-chart/matrix-chart.schema.json +63 -0
  431. package/src/components/matrix-chart/matrix-chart.schema.ts +67 -0
  432. package/src/components/matrix-chart/matrix-chart.svelte +336 -0
  433. package/src/components/matrix-chart/matrix-chart.types.ts +56 -0
  434. package/src/components/matrix-chart/matrix-chart.variables.json +1 -0
  435. package/src/components/matrix-chart/matrix-chart.variables.ts +3 -0
  436. package/src/components/media-controls/README.md +60 -0
  437. package/src/components/media-controls/index.ts +6 -0
  438. package/src/components/media-controls/media-controls.css +112 -0
  439. package/src/components/media-controls/media-controls.examples.json +19 -0
  440. package/src/components/media-controls/media-controls.schema.json +65 -0
  441. package/src/components/media-controls/media-controls.schema.ts +69 -0
  442. package/src/components/media-controls/media-controls.svelte +238 -0
  443. package/src/components/media-controls/media-controls.types.ts +80 -0
  444. package/src/components/media-controls/media-controls.variables.json +1 -0
  445. package/src/components/media-controls/media-controls.variables.ts +3 -0
  446. package/src/components/menu-bar/README.md +53 -0
  447. package/src/components/navigation-bar/README.md +1 -1
  448. package/src/components/navigation-bar/navigation-bar.schema.json +4 -4
  449. package/src/components/navigation-bar/navigation-bar.schema.ts +4 -4
  450. package/src/components/navigation-bar/navigation-bar.types.ts +2 -1
  451. package/src/components/pricing-card/README.md +55 -0
  452. package/src/components/pricing-card/index.ts +6 -0
  453. package/src/components/pricing-card/pricing-card.css +173 -0
  454. package/src/components/pricing-card/pricing-card.examples.json +19 -0
  455. package/src/components/pricing-card/pricing-card.schema.json +40 -0
  456. package/src/components/pricing-card/pricing-card.schema.ts +44 -0
  457. package/src/components/pricing-card/pricing-card.svelte +70 -0
  458. package/src/components/pricing-card/pricing-card.types.ts +49 -0
  459. package/src/components/pricing-card/pricing-card.variables.json +1 -0
  460. package/src/components/pricing-card/pricing-card.variables.ts +3 -0
  461. package/src/components/review-editor/README.md +64 -0
  462. package/src/components/review-editor/comment-composer.svelte +8 -8
  463. package/src/components/review-editor/comment-list.svelte +10 -1
  464. package/src/components/search-field/search-field.examples.json +13 -0
  465. package/src/components/segment/README.md +55 -0
  466. package/src/components/share-card/README.md +58 -0
  467. package/src/components/share-card/index.ts +6 -0
  468. package/src/components/share-card/share-card.css +115 -0
  469. package/src/components/share-card/share-card.examples.json +19 -0
  470. package/src/components/share-card/share-card.schema.json +53 -0
  471. package/src/components/share-card/share-card.schema.ts +57 -0
  472. package/src/components/share-card/share-card.svelte +330 -0
  473. package/src/components/share-card/share-card.types.ts +69 -0
  474. package/src/components/share-card/share-card.variables.json +1 -0
  475. package/src/components/share-card/share-card.variables.ts +3 -0
  476. package/src/components/shortcut-hint/README.md +52 -0
  477. package/src/components/shortcut-hint/index.ts +6 -0
  478. package/src/components/shortcut-hint/shortcut-hint.css +26 -0
  479. package/src/components/shortcut-hint/shortcut-hint.examples.json +13 -0
  480. package/src/components/shortcut-hint/shortcut-hint.schema.json +36 -0
  481. package/src/components/shortcut-hint/shortcut-hint.schema.ts +40 -0
  482. package/src/components/shortcut-hint/shortcut-hint.svelte +62 -0
  483. package/src/components/shortcut-hint/shortcut-hint.types.ts +35 -0
  484. package/src/components/shortcut-hint/shortcut-hint.variables.json +1 -0
  485. package/src/components/shortcut-hint/shortcut-hint.variables.ts +3 -0
  486. package/src/components/side-navigation/side-navigation.examples.json +6 -0
  487. package/src/components/skip-link/README.md +50 -0
  488. package/src/components/skip-link/index.ts +5 -0
  489. package/src/components/skip-link/skip-link.examples.json +13 -0
  490. package/src/components/skip-link/skip-link.schema.json +16 -0
  491. package/src/components/skip-link/skip-link.schema.ts +20 -0
  492. package/src/components/skip-link/skip-link.svelte +86 -0
  493. package/src/components/skip-link/skip-link.types.ts +40 -0
  494. package/src/components/skip-link/skip-link.variables.json +1 -0
  495. package/src/components/skip-link/skip-link.variables.ts +3 -0
  496. package/src/components/spectrogram/README.md +58 -0
  497. package/src/components/spectrogram/index.ts +10 -0
  498. package/src/components/spectrogram/spectrogram.css +43 -0
  499. package/src/components/spectrogram/spectrogram.examples.json +13 -0
  500. package/src/components/spectrogram/spectrogram.schema.json +43 -0
  501. package/src/components/spectrogram/spectrogram.schema.ts +47 -0
  502. package/src/components/spectrogram/spectrogram.svelte +284 -0
  503. package/src/components/spectrogram/spectrogram.types.ts +63 -0
  504. package/src/components/spectrogram/spectrogram.variables.json +1 -0
  505. package/src/components/spectrogram/spectrogram.variables.ts +3 -0
  506. package/src/components/spectrum-chart/README.md +57 -0
  507. package/src/components/spectrum-chart/index.ts +10 -0
  508. package/src/components/spectrum-chart/spectrum-chart.css +49 -0
  509. package/src/components/spectrum-chart/spectrum-chart.examples.json +13 -0
  510. package/src/components/spectrum-chart/spectrum-chart.schema.json +37 -0
  511. package/src/components/spectrum-chart/spectrum-chart.schema.ts +41 -0
  512. package/src/components/spectrum-chart/spectrum-chart.svelte +247 -0
  513. package/src/components/spectrum-chart/spectrum-chart.types.ts +44 -0
  514. package/src/components/spectrum-chart/spectrum-chart.variables.json +1 -0
  515. package/src/components/spectrum-chart/spectrum-chart.variables.ts +3 -0
  516. package/src/components/status-dot/README.md +7 -7
  517. package/src/components/status-dot/status-dot.css +8 -0
  518. package/src/components/status-dot/status-dot.schema.json +2 -2
  519. package/src/components/status-dot/status-dot.schema.ts +3 -2
  520. package/src/components/status-dot/status-dot.types.ts +13 -2
  521. package/src/components/subscription-badge/README.md +50 -0
  522. package/src/components/subscription-badge/index.ts +6 -0
  523. package/src/components/subscription-badge/subscription-badge.css +18 -0
  524. package/src/components/subscription-badge/subscription-badge.examples.json +19 -0
  525. package/src/components/subscription-badge/subscription-badge.schema.json +16 -0
  526. package/src/components/subscription-badge/subscription-badge.schema.ts +21 -0
  527. package/src/components/subscription-badge/subscription-badge.svelte +69 -0
  528. package/src/components/subscription-badge/subscription-badge.types.ts +37 -0
  529. package/src/components/subscription-badge/subscription-badge.variables.json +1 -0
  530. package/src/components/subscription-badge/subscription-badge.variables.ts +3 -0
  531. package/src/components/table-cell/README.md +6 -5
  532. package/src/components/table-cell/table-cell.schema.json +4 -0
  533. package/src/components/table-cell/table-cell.schema.ts +5 -0
  534. package/src/components/table-cell/table-cell.svelte +9 -3
  535. package/src/components/table-cell/table-cell.types.ts +16 -1
  536. package/src/components/tag-input/README.md +75 -0
  537. package/src/components/typography/README.md +51 -0
  538. package/src/components/waveform/README.md +57 -0
  539. package/src/components/waveform/index.ts +6 -0
  540. package/src/components/waveform/waveform.css +53 -0
  541. package/src/components/waveform/waveform.examples.json +19 -0
  542. package/src/components/waveform/waveform.schema.json +38 -0
  543. package/src/components/waveform/waveform.schema.ts +42 -0
  544. package/src/components/waveform/waveform.svelte +286 -0
  545. package/src/components/waveform/waveform.types.ts +45 -0
  546. package/src/components/waveform/waveform.variables.json +1 -0
  547. package/src/components/waveform/waveform.variables.ts +3 -0
  548. package/src/index.ts +85 -2
  549. package/src/styles/components.css +13 -0
  550. package/src/styles/shell.css +3 -0
  551. package/src/styles/tokens-base.css +59 -22
@@ -182,10 +182,16 @@
182
182
  /* Focus: ring travels via box-shadow, not outline, so it sits inside the
183
183
  * card's colored border instead of doubling up on top of it. */
184
184
  .tool-call-header:focus-visible {
185
- /* cinder-focus-ring-owner: parent — this header self-owns its inset
186
- box-shadow ring; the outline is intentionally suppressed. */
187
- outline: none;
188
- box-shadow: inset 0 0 0 var(--cinder-ring-width) var(--cinder-ring-color);
185
+ outline: var(--cinder-ring-width) solid transparent;
186
+ box-shadow: inset 0 0 0 var(--cinder-ring-width)
187
+ var(--_cinder-tool-call-header-ring, var(--cinder-ring-color));
188
+ }
189
+
190
+ @media (forced-colors: active) {
191
+ .tool-call-header:focus-visible {
192
+ outline: var(--cinder-ring-width) solid ButtonText;
193
+ outline-offset: calc(var(--cinder-ring-width) * -1);
194
+ }
189
195
  }
190
196
 
191
197
  .tool-call-icon {
@@ -0,0 +1,66 @@
1
+ # ChoiceGrid
2
+
3
+ Responsive grid of large selectable choices with roving keyboard focus, selection state, and optional correct/incorrect/pending feedback for quiz and assessment surfaces.
4
+
5
+ ## Usage
6
+
7
+ ```svelte
8
+ <script lang="ts">
9
+ import { ChoiceGrid } from '@lostgradient/cinder/choice-grid';
10
+
11
+ let selected = $state<string | null>(null);
12
+ </script>
13
+
14
+ <ChoiceGrid ariaLabel="Choose a difficulty" bind:value={selected}>
15
+ <ChoiceGrid.Item value="easy">Easy</ChoiceGrid.Item>
16
+ <ChoiceGrid.Item value="medium">Medium</ChoiceGrid.Item>
17
+ <ChoiceGrid.Item value="hard">Hard</ChoiceGrid.Item>
18
+ </ChoiceGrid>
19
+ ```
20
+
21
+ ## Guidance
22
+
23
+ ### Use When
24
+
25
+ - Presenting a small fixed set of large selectable answers where all options should stay visible (quiz or assessment surfaces).
26
+ - Building a touch-friendly selector grid with stable cell dimensions that must not shift when feedback states are applied.
27
+
28
+ ### Avoid When
29
+
30
+ - Selecting from a long dynamic list — use combobox or select instead.
31
+ - Choosing one of two to five short values in a compact inline context — use segmented-control instead.
32
+
33
+ ## Props
34
+
35
+ <!-- generated:props:start -->
36
+
37
+ | Prop | Type | Required | Default | Description |
38
+ | ---------------- | ------------------------------------------ | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
39
+ | `ariaLabel` | `string` | no | — | Accessible label for the grid (required unless `ariaLabelledby` is set). |
40
+ | `ariaLabelledby` | `string` | no | — | Id of an external element that labels this grid. |
41
+ | `columns` | `"responsive"` \| `1` \| `2` \| `3` \| `4` | no | — | Column layout. - `'responsive'` — `auto-fill` at a minimum cell width (default). - `1 \| 2 \| 3 \| 4` — fixed number of columns. |
42
+ | `disabled` | `boolean` | no | — | Disables all items in the grid. |
43
+ | `minColumnWidth` | `string` | no | — | Minimum cell width for `columns="responsive"`. Accepts any CSS `<length>` (e.g. `"12rem"`, `"200px"`). Default: `"10rem"`. |
44
+ | `multiple` | `boolean` | no | — | When true the grid allows multiple simultaneous selections and reads/writes `values` instead of `value`. The ARIA role switches to `group` (items become `checkbox`); single-select uses `radiogroup` (items become `radio`). |
45
+ | `value` | `string` \| `null` | no | — | The currently selected value (single-select mode). Bindable. Pass `null` or omit to start with no selection. |
46
+ | `values` | `string`[] | no | — | Currently selected values (multi-select mode). Bindable. Only used when `multiple` is `true` — set `multiple` explicitly to switch modes; binding `values` alone does NOT enable multi-select. |
47
+ | `children` | `(opaque)` | no | — | A function or snippet prop. Its shape is not captured by the JSON schema; see the component types for the exact signature. |
48
+ | `class` | `(opaque)` | no | — | A prop whose shape is not captured by the JSON schema; see the component types for the exact signature. |
49
+
50
+ <!-- generated:props:end -->
51
+
52
+ ## CSS Variables
53
+
54
+ <!-- generated:variables:start -->
55
+
56
+ This component does not declare any local CSS variables.
57
+
58
+ <!-- generated:variables:end -->
59
+
60
+ ## Subcomponents
61
+
62
+ <!-- generated:subcomponents:start -->
63
+
64
+ None.
65
+
66
+ <!-- generated:subcomponents:end -->
@@ -0,0 +1,30 @@
1
+ import { createContext } from 'svelte';
2
+
3
+ import type { ChoiceGridContext } from './choice-grid.types.ts';
4
+
5
+ export type { ChoiceGridContext };
6
+
7
+ /**
8
+ * Context published by `<ChoiceGrid>` for descendant `<ChoiceGridItem>` children.
9
+ *
10
+ * All members are getter properties on the context object so reads stay
11
+ * reactive — when a consumer reads `context.value` inside a `$derived`,
12
+ * the read flows through the getter which returns a value recomputed from
13
+ * ChoiceGrid's `$derived` internals. Destructuring breaks reactivity;
14
+ * getter reads preserve it.
15
+ *
16
+ * The context is *required* — a `<ChoiceGridItem>` outside a `<ChoiceGrid>` is a
17
+ * programmer error. The `getChoiceGridContext` getter therefore throws
18
+ * (via Svelte 5's `createContext`) when no provider exists.
19
+ */
20
+
21
+ const [getChoiceGridContextStrict, setChoiceGridContext] = createContext<ChoiceGridContext>();
22
+
23
+ export { setChoiceGridContext };
24
+
25
+ /**
26
+ * Read the enclosing `<ChoiceGrid>` context. Throws via Svelte 5's
27
+ * `createContext` when no provider exists — a `<ChoiceGridItem>` rendered
28
+ * outside a `<ChoiceGrid>` is a programmer error.
29
+ */
30
+ export const getChoiceGridContext = getChoiceGridContextStrict;
@@ -0,0 +1,27 @@
1
+ @layer cinder.tokens, cinder.foundation, cinder.components, cinder.utilities;
2
+
3
+ @import '../choice-grid-item/choice-grid-item.css';
4
+
5
+ @layer cinder.components {
6
+ /* ========================================
7
+ * CHOICE GRID — parent container
8
+ * ======================================== */
9
+
10
+ .cinder-choice-grid {
11
+ /* Default grid layout: responsive auto-fill. Overridden by the
12
+ * --cinder-choice-grid-columns inline style set from the `columns` prop. */
13
+ display: grid;
14
+ grid-template-columns: var(
15
+ --cinder-choice-grid-columns,
16
+ repeat(auto-fill, minmax(min(10rem, 100%), 1fr))
17
+ );
18
+ gap: var(--cinder-space-3);
19
+ inline-size: 100%;
20
+ }
21
+
22
+ /* Disabled grid dims every item. Individual item disabled states also apply. */
23
+ .cinder-choice-grid[data-cinder-disabled] {
24
+ opacity: 0.6;
25
+ pointer-events: none;
26
+ }
27
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "../../schemas/examples.schema.json",
3
+ "component": "choice-grid",
4
+ "import": "@lostgradient/cinder/choice-grid",
5
+ "examples": [
6
+ {
7
+ "id": "basic",
8
+ "title": "Basic single-select",
9
+ "description": "A simple quiz question with four answer options and roving keyboard focus.",
10
+ "code": "<script lang=\"ts\">\n import { ChoiceGrid } from '@lostgradient/cinder/choice-grid';\n\n let selected = $state<string | null>(null);\n</script>\n\n<ChoiceGrid ariaLabel=\"What is the capital of France?\" bind:value={selected}>\n <ChoiceGrid.Item value=\"london\">London</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"berlin\">Berlin</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"paris\">Paris</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"madrid\">Madrid</ChoiceGrid.Item>\n</ChoiceGrid>\n\n{#if selected}\n <p style=\"margin-top: 1rem; color: var(--cinder-text-muted); font-size: var(--cinder-text-sm);\">\n Selected: {selected}\n </p>\n{/if}\n"
11
+ },
12
+ {
13
+ "id": "dense-layout",
14
+ "title": "Dense phone layout",
15
+ "description": "Fixed 2-column grid with compact cells — suitable for narrow mobile viewports.",
16
+ "code": "<script lang=\"ts\">\n import { ChoiceGrid } from '@lostgradient/cinder/choice-grid';\n\n let selected = $state<string | null>(null);\n</script>\n\n<div style=\"max-width: 20rem; margin: 0 auto;\">\n <ChoiceGrid ariaLabel=\"Choose a difficulty\" bind:value={selected} columns={2}>\n <ChoiceGrid.Item value=\"easy\">Easy</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"medium\">Medium</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"hard\">Hard</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"expert\">Expert</ChoiceGrid.Item>\n </ChoiceGrid>\n</div>\n"
17
+ },
18
+ {
19
+ "id": "feedback-states",
20
+ "title": "Feedback states",
21
+ "description": "Correct, incorrect, and pending states for quiz and assessment surfaces. Cell dimensions stay stable across states.",
22
+ "code": "<script lang=\"ts\">\n import { Button } from '@lostgradient/cinder/button';\n import { ChoiceGrid } from '@lostgradient/cinder/choice-grid';\n import type { ChoiceGridItemState } from '@lostgradient/cinder/choice-grid';\n\n let selected = $state<string | null>(null);\n let revealed = $state(false);\n\n const correctAnswer = 'paris';\n\n function getState(value: string): ChoiceGridItemState {\n if (!revealed || selected === null) return 'neutral';\n if (value === correctAnswer) return 'correct';\n if (value === selected && value !== correctAnswer) return 'incorrect';\n return 'neutral';\n }\n</script>\n\n<ChoiceGrid ariaLabel=\"What is the capital of France?\" bind:value={selected}>\n <ChoiceGrid.Item value=\"london\" state={getState('london')}>London</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"berlin\" state={getState('berlin')}>Berlin</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"paris\" state={getState('paris')}>Paris</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"madrid\" state={getState('madrid')}>Madrid</ChoiceGrid.Item>\n</ChoiceGrid>\n\n<div style=\"margin-top: 1rem; display: flex; gap: 0.5rem; flex-wrap: wrap;\">\n <Button variant=\"secondary\" onclick={() => (revealed = !revealed)}>\n {revealed ? 'Hide feedback' : 'Reveal answer'}\n </Button>\n <Button\n variant=\"ghost\"\n onclick={() => {\n selected = null;\n revealed = false;\n }}\n >\n Reset\n </Button>\n</div>\n"
23
+ },
24
+ {
25
+ "id": "multi-select",
26
+ "title": "Multi-select",
27
+ "description": "Toggle multiple answers simultaneously — useful for checkboxes presented as large tiles.",
28
+ "code": "<script lang=\"ts\">\n import { ChoiceGrid } from '@lostgradient/cinder/choice-grid';\n\n let selected = $state<string[]>([]);\n</script>\n\n<ChoiceGrid multiple ariaLabel=\"Which topics interest you?\" bind:values={selected} columns={2}>\n <ChoiceGrid.Item value=\"design\">Design</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"engineering\">Engineering</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"product\">Product</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"data\">Data</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"marketing\">Marketing</ChoiceGrid.Item>\n <ChoiceGrid.Item value=\"leadership\">Leadership</ChoiceGrid.Item>\n</ChoiceGrid>\n\n{#if selected.length > 0}\n <p style=\"margin-top: 1rem; color: var(--cinder-text-muted); font-size: var(--cinder-text-sm);\">\n Selected: {selected.join(', ')}\n </p>\n{/if}\n"
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,61 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "type": "object",
4
+ "properties": {
5
+ "value": {
6
+ "anyOf": [
7
+ {
8
+ "type": "string"
9
+ },
10
+ {
11
+ "type": "null"
12
+ }
13
+ ],
14
+ "description": "The currently selected value (single-select mode). Bindable.\nPass `null` or omit to start with no selection."
15
+ },
16
+ "values": {
17
+ "type": "array",
18
+ "items": {
19
+ "type": "string"
20
+ },
21
+ "description": "Currently selected values (multi-select mode). Bindable. Only used when\n`multiple` is `true` — set `multiple` explicitly to switch modes; binding\n`values` alone does NOT enable multi-select."
22
+ },
23
+ "multiple": {
24
+ "type": "boolean",
25
+ "description": "When true the grid allows multiple simultaneous selections and reads/writes\n`values` instead of `value`. The ARIA role switches to `group` (items become\n`checkbox`); single-select uses `radiogroup` (items become `radio`)."
26
+ },
27
+ "columns": {
28
+ "enum": ["responsive", 1, 2, 3, 4],
29
+ "description": "Column layout.\n- `'responsive'` — `auto-fill` at a minimum cell width (default).\n- `1 | 2 | 3 | 4` — fixed number of columns."
30
+ },
31
+ "minColumnWidth": {
32
+ "type": "string",
33
+ "description": "Minimum cell width for `columns=\"responsive\"`. Accepts any CSS\n`<length>` (e.g. `\"12rem\"`, `\"200px\"`). Default: `\"10rem\"`."
34
+ },
35
+ "ariaLabel": {
36
+ "type": "string",
37
+ "description": "Accessible label for the grid (required unless `ariaLabelledby` is set)."
38
+ },
39
+ "ariaLabelledby": {
40
+ "type": "string",
41
+ "description": "Id of an external element that labels this grid."
42
+ },
43
+ "disabled": {
44
+ "type": "boolean",
45
+ "description": "Disables all items in the grid."
46
+ }
47
+ },
48
+ "additionalProperties": false,
49
+ "metadata": {
50
+ "unsupportedProps": [
51
+ {
52
+ "name": "children",
53
+ "reason": "function-or-snippet"
54
+ },
55
+ {
56
+ "name": "class",
57
+ "reason": "unknown-shape"
58
+ }
59
+ ]
60
+ }
61
+ }
@@ -0,0 +1,70 @@
1
+ import type { ComponentSchema } from '../../schema-types';
2
+
3
+ const schema = {
4
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
5
+ type: 'object',
6
+ properties: {
7
+ value: {
8
+ anyOf: [
9
+ {
10
+ type: 'string',
11
+ },
12
+ {
13
+ type: 'null',
14
+ },
15
+ ],
16
+ description:
17
+ 'The currently selected value (single-select mode). Bindable.\nPass `null` or omit to start with no selection.',
18
+ },
19
+ values: {
20
+ type: 'array',
21
+ items: {
22
+ type: 'string',
23
+ },
24
+ description:
25
+ 'Currently selected values (multi-select mode). Bindable. Only used when\n`multiple` is `true` — set `multiple` explicitly to switch modes; binding\n`values` alone does NOT enable multi-select.',
26
+ },
27
+ multiple: {
28
+ type: 'boolean',
29
+ description:
30
+ 'When true the grid allows multiple simultaneous selections and reads/writes\n`values` instead of `value`. The ARIA role switches to `group` (items become\n`checkbox`); single-select uses `radiogroup` (items become `radio`).',
31
+ },
32
+ columns: {
33
+ enum: ['responsive', 1, 2, 3, 4],
34
+ description:
35
+ "Column layout.\n- `'responsive'` — `auto-fill` at a minimum cell width (default).\n- `1 | 2 | 3 | 4` — fixed number of columns.",
36
+ },
37
+ minColumnWidth: {
38
+ type: 'string',
39
+ description:
40
+ 'Minimum cell width for `columns="responsive"`. Accepts any CSS\n`<length>` (e.g. `"12rem"`, `"200px"`). Default: `"10rem"`.',
41
+ },
42
+ ariaLabel: {
43
+ type: 'string',
44
+ description: 'Accessible label for the grid (required unless `ariaLabelledby` is set).',
45
+ },
46
+ ariaLabelledby: {
47
+ type: 'string',
48
+ description: 'Id of an external element that labels this grid.',
49
+ },
50
+ disabled: {
51
+ type: 'boolean',
52
+ description: 'Disables all items in the grid.',
53
+ },
54
+ },
55
+ additionalProperties: false,
56
+ metadata: {
57
+ unsupportedProps: [
58
+ {
59
+ name: 'children',
60
+ reason: 'function-or-snippet',
61
+ },
62
+ {
63
+ name: 'class',
64
+ reason: 'unknown-shape',
65
+ },
66
+ ],
67
+ },
68
+ } satisfies ComponentSchema;
69
+
70
+ export default schema as ComponentSchema;
@@ -0,0 +1,272 @@
1
+ <script lang="ts" module>
2
+ /**
3
+ * @cinder
4
+ * @category form
5
+ * @status alpha
6
+ * @purpose Responsive grid of large selectable choices with roving keyboard focus, selection state, and optional correct/incorrect/pending feedback for quiz and assessment surfaces.
7
+ * @tag form
8
+ * @tag selection
9
+ * @tag quiz
10
+ * @tag assessment
11
+ * @useWhen Presenting a small fixed set of large selectable answers where all options should stay visible (quiz or assessment surfaces).
12
+ * @useWhen Building a touch-friendly selector grid with stable cell dimensions that must not shift when feedback states are applied.
13
+ * @avoidWhen Selecting from a long dynamic list — use combobox or select instead.
14
+ * @avoidWhen Choosing one of two to five short values in a compact inline context — use segmented-control instead.
15
+ * @related choice-grid-item, segmented-control, radio-group, checkbox-group
16
+ */
17
+ export type {
18
+ ChoiceGridColumns,
19
+ ChoiceGridContext,
20
+ ChoiceGridItemState,
21
+ ChoiceGridProps,
22
+ } from './choice-grid.types.ts';
23
+ </script>
24
+
25
+ <script lang="ts">
26
+ import type { ChoiceGridProps } from './choice-grid.types.ts';
27
+ import { setChoiceGridContext } from './choice-grid-context.ts';
28
+ import { classNames } from '../../utilities/class-names.ts';
29
+ import { createSingleSelection, createMultiSelection } from '../../_internal/collection.ts';
30
+ import { handleRovingKeydown } from '../../utilities/roving-tabindex.ts';
31
+ import { devWarn } from '../../utilities/dev-warn.ts';
32
+
33
+ let {
34
+ value = $bindable(null),
35
+ values = $bindable([]),
36
+ multiple = false,
37
+ columns = 'responsive',
38
+ minColumnWidth = '10rem',
39
+ ariaLabel,
40
+ ariaLabelledby,
41
+ disabled = false,
42
+ class: className,
43
+ children,
44
+ ...rest
45
+ }: ChoiceGridProps = $props();
46
+
47
+ // Registry of items keyed by value. Insertion order determines navigation
48
+ // order (linear roving through the visual grid). `disabled` is tracked so both
49
+ // the roving-tabindex computation and arrow-key navigation skip disabled items.
50
+ type RegisteredItem = { element: HTMLElement; disabled: boolean };
51
+ const items: Map<string, RegisteredItem> = new Map();
52
+ let version = $state(0);
53
+
54
+ const singleSelection = $derived(
55
+ createSingleSelection(
56
+ () => value ?? null,
57
+ (next) => {
58
+ value = next;
59
+ },
60
+ ),
61
+ );
62
+
63
+ const multiSelection = $derived(
64
+ createMultiSelection(
65
+ () => values,
66
+ (next) => {
67
+ values = next;
68
+ },
69
+ ),
70
+ );
71
+
72
+ function isSelected(candidate: string): boolean {
73
+ if (multiple) {
74
+ return multiSelection.isSelected(candidate);
75
+ }
76
+ return singleSelection.isSelected(candidate);
77
+ }
78
+
79
+ function select(candidate: string): void {
80
+ // Refuse to activate when the grid is disabled OR the specific item is
81
+ // disabled — items forward keydown unconditionally (so navigation isn't
82
+ // trapped), which means Space/Enter can reach here for a disabled item.
83
+ if (isItemDisabled(candidate)) return;
84
+ if (multiple) {
85
+ multiSelection.toggle(candidate);
86
+ } else {
87
+ singleSelection.select(candidate);
88
+ }
89
+ }
90
+
91
+ function isItemDisabled(candidate: string): boolean {
92
+ if (disabled) return true;
93
+ return items.get(candidate)?.disabled ?? false;
94
+ }
95
+
96
+ // Item values ordered by their RENDERED DOM position, not Map-insertion order.
97
+ // Reordering keyed `{#each}` children reorders the DOM without re-registering,
98
+ // so roving navigation and the default tabindex target must follow the visual
99
+ // order — otherwise focus moves along the wrong sequence.
100
+ function orderedKeys(): string[] {
101
+ return [...items.entries()]
102
+ .sort(([, a], [, b]) => {
103
+ const position = a.element.compareDocumentPosition(b.element);
104
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
105
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1;
106
+ return 0;
107
+ })
108
+ .map(([key]) => key);
109
+ }
110
+
111
+ // The single ENABLED value that should hold `tabindex="0"`. Disabled items are
112
+ // never focusable: prefer the (enabled) selected value, else the first enabled
113
+ // registered item. Returns null when every item is disabled.
114
+ const focusableValue = $derived.by(() => {
115
+ void version;
116
+ void value;
117
+ void values;
118
+ const ordered = orderedKeys();
119
+ if (ordered.length === 0) return null;
120
+
121
+ if (!multiple && value !== null && value !== undefined) {
122
+ if (items.has(value) && !isItemDisabled(value)) return value;
123
+ }
124
+ if (multiple && values.length > 0) {
125
+ for (const selected of values) {
126
+ if (items.has(selected) && !isItemDisabled(selected)) return selected;
127
+ }
128
+ }
129
+ // First enabled item in DOM order.
130
+ for (const key of ordered) {
131
+ if (!isItemDisabled(key)) return key;
132
+ }
133
+ return null;
134
+ });
135
+
136
+ function isFocusable(candidate: string): boolean {
137
+ // Subscribe to reactive inputs so this stays current inside $derived.
138
+ void version;
139
+ void value;
140
+ void values;
141
+ return focusableValue === candidate;
142
+ }
143
+
144
+ function register(itemValue: string, element: HTMLElement, itemDisabled: boolean): void {
145
+ items.set(itemValue, { element, disabled: itemDisabled });
146
+ version += 1;
147
+ }
148
+
149
+ function setItemDisabled(itemValue: string, itemDisabled: boolean): void {
150
+ const existing = items.get(itemValue);
151
+ if (existing && existing.disabled !== itemDisabled) {
152
+ items.set(itemValue, { element: existing.element, disabled: itemDisabled });
153
+ version += 1;
154
+ }
155
+ }
156
+
157
+ function unregister(itemValue: string): void {
158
+ if (items.delete(itemValue)) {
159
+ version += 1;
160
+ }
161
+ }
162
+
163
+ function handleKeydown(event: KeyboardEvent): void {
164
+ const keys = orderedKeys();
165
+ const currentIndex = keys.findIndex((key) => {
166
+ const entry = items.get(key);
167
+ return entry?.element === event.currentTarget || entry?.element === event.target;
168
+ });
169
+
170
+ if (currentIndex === -1) return;
171
+
172
+ // Space/Enter: activate the currently focused item.
173
+ if (event.key === ' ' || event.key === 'Enter') {
174
+ event.preventDefault();
175
+ const focusedValue = keys[currentIndex];
176
+ if (focusedValue !== undefined) {
177
+ select(focusedValue);
178
+ }
179
+ return;
180
+ }
181
+
182
+ // Arrow keys: LINEAR roving through the visual grid in DOM order (the
183
+ // responsive column count is layout-dependent, so v1 uses linear roving
184
+ // rather than measured 2D movement). Disabled items are skipped.
185
+ const nextIndex = handleRovingKeydown(event, currentIndex, keys.length, {
186
+ horizontal: true,
187
+ vertical: true,
188
+ isDisabled: (index) => {
189
+ const key = keys[index];
190
+ return key === undefined ? true : isItemDisabled(key);
191
+ },
192
+ });
193
+
194
+ if (nextIndex === null || nextIndex === currentIndex) return;
195
+ event.preventDefault();
196
+
197
+ const nextValue = keys[nextIndex];
198
+ if (nextValue === undefined) return;
199
+ items.get(nextValue)?.element.focus();
200
+
201
+ // WAI-ARIA radiogroup pattern: arrow navigation also moves the selection in
202
+ // single-select mode. Multi-select (checkbox semantics) only moves focus —
203
+ // selection toggles on Space/Enter/click.
204
+ if (!multiple) {
205
+ select(nextValue);
206
+ }
207
+ }
208
+
209
+ setChoiceGridContext({
210
+ get value() {
211
+ return value ?? null;
212
+ },
213
+ get multiple() {
214
+ return multiple;
215
+ },
216
+ get disabled() {
217
+ return disabled;
218
+ },
219
+ isSelected,
220
+ select,
221
+ register,
222
+ setItemDisabled,
223
+ unregister,
224
+ isFocusable,
225
+ handleKeydown,
226
+ });
227
+
228
+ // Empty strings are normalized to `undefined` so `aria-label=""` does not
229
+ // suppress the accessible-name fallback and leave the group unnamed.
230
+ const resolvedAriaLabel = $derived(ariaLabel?.trim() ? ariaLabel : undefined);
231
+ const resolvedAriaLabelledby = $derived(ariaLabelledby?.trim() ? ariaLabelledby : undefined);
232
+
233
+ // Dev-time guardrails for the two easy-to-miss API contracts.
234
+ $effect(() => {
235
+ if (values.length > 0 && !multiple) {
236
+ devWarn(
237
+ 'ChoiceGrid: `values` was provided without `multiple`. Binding `values` does not enable multi-select — set `multiple` explicitly. The grid is operating in single-select mode and ignoring `values`.',
238
+ );
239
+ }
240
+ // Check the resolved (non-empty) names so `ariaLabel=""` / `ariaLabelledby=""`
241
+ // still warn — an empty string leaves the control unnamed.
242
+ if (!resolvedAriaLabel && !resolvedAriaLabelledby) {
243
+ devWarn(
244
+ 'ChoiceGrid: no `ariaLabel` or `ariaLabelledby` provided. The radiogroup/group has no accessible name — pass one.',
245
+ );
246
+ }
247
+ });
248
+
249
+ // Grid template columns CSS.
250
+ const gridTemplateColumns = $derived(
251
+ columns === 'responsive'
252
+ ? `repeat(auto-fill, minmax(min(${minColumnWidth}, 100%), 1fr))`
253
+ : `repeat(${columns}, 1fr)`,
254
+ );
255
+
256
+ // ARIA role: radiogroup for single-select, group for multi-select.
257
+ const role = $derived(multiple ? 'group' : 'radiogroup');
258
+ </script>
259
+
260
+ <div
261
+ {...rest}
262
+ {role}
263
+ class={classNames('cinder-choice-grid', className)}
264
+ aria-label={resolvedAriaLabel}
265
+ aria-labelledby={resolvedAriaLabelledby}
266
+ aria-disabled={disabled || undefined}
267
+ data-cinder-multiple={multiple || undefined}
268
+ data-cinder-disabled={disabled || undefined}
269
+ style:--cinder-choice-grid-columns={gridTemplateColumns}
270
+ >
271
+ {@render children()}
272
+ </div>