makersclaw 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. package/THIRD-PARTY-NOTICES.md +180 -0
  2. package/package.json +3 -2
  3. package/r/annotate.json +62 -0
  4. package/r/approval-request.json +52 -0
  5. package/r/audio-player.json +74 -0
  6. package/r/auth-form.json +55 -0
  7. package/r/board.json +10 -6
  8. package/r/calendar-view.json +105 -0
  9. package/r/cart.json +62 -0
  10. package/r/chart.json +83 -0
  11. package/r/chat.json +95 -0
  12. package/r/code-editor.json +94 -0
  13. package/r/comment-box.json +64 -0
  14. package/r/contact-section.json +53 -0
  15. package/r/core.json +205 -8
  16. package/r/csv-import.json +63 -0
  17. package/r/data-table.json +69 -0
  18. package/r/diagram.json +74 -0
  19. package/r/doc-editor.json +82 -0
  20. package/r/doc-page.json +61 -0
  21. package/r/email-render.json +73 -0
  22. package/r/faq.json +50 -0
  23. package/r/file-upload.json +54 -0
  24. package/r/flow-canvas.json +93 -0
  25. package/r/footer.json +52 -0
  26. package/r/gantt.json +70 -0
  27. package/r/job-panel.json +12 -7
  28. package/r/json-editor.json +66 -0
  29. package/r/map.json +89 -0
  30. package/r/menubar.json +52 -0
  31. package/r/mind-map.json +67 -0
  32. package/r/navigation-menu.json +52 -0
  33. package/r/order-detail.json +54 -0
  34. package/r/org-chart.json +66 -0
  35. package/r/page-builder.json +105 -0
  36. package/r/payment-methods.json +51 -0
  37. package/r/pdf-document.json +79 -0
  38. package/r/pdf-viewer.json +88 -0
  39. package/r/product-detail.json +76 -0
  40. package/r/product-grid.json +65 -0
  41. package/r/record-form.json +67 -0
  42. package/r/record-notes.json +55 -0
  43. package/r/registry.json +3411 -29
  44. package/r/search-dialog.json +51 -0
  45. package/r/settings-list.json +66 -0
  46. package/r/setup-checklist.json +51 -0
  47. package/r/share-dialog.json +52 -0
  48. package/r/sidebar.json +69 -0
  49. package/r/signature-pad.json +72 -0
  50. package/r/sketch-canvas.json +99 -0
  51. package/r/spreadsheet.json +90 -0
  52. package/r/stat-cards.json +66 -0
  53. package/r/task-list.json +63 -0
  54. package/r/task-model.json +98 -0
  55. package/r/testimonials.json +52 -0
  56. package/r/transaction-list.json +53 -0
  57. package/r/whiteboard.json +66 -0
  58. package/registry/blocks/annotate/README.md +179 -0
  59. package/registry/blocks/annotate/annotate-data.js +250 -0
  60. package/registry/blocks/annotate/annotate.jsx +646 -0
  61. package/registry/blocks/annotate/block.json +10 -0
  62. package/registry/blocks/annotate/demo.jsx +135 -0
  63. package/registry/blocks/annotate/index.js +15 -0
  64. package/registry/blocks/approval-request/README.md +116 -0
  65. package/registry/blocks/approval-request/approval-request.jsx +386 -0
  66. package/registry/blocks/approval-request/block.json +10 -0
  67. package/registry/blocks/approval-request/demo.jsx +127 -0
  68. package/registry/blocks/approval-request/index.js +4 -0
  69. package/registry/blocks/audio-player/README.md +167 -0
  70. package/registry/blocks/audio-player/audio-player.jsx +623 -0
  71. package/registry/blocks/audio-player/block.json +14 -0
  72. package/registry/blocks/audio-player/colors.js +109 -0
  73. package/registry/blocks/audio-player/demo.jsx +209 -0
  74. package/registry/blocks/audio-player/index.js +6 -0
  75. package/registry/blocks/audio-player/time.js +67 -0
  76. package/registry/blocks/audio-player/wavesurfer.js +9 -0
  77. package/registry/blocks/auth-form/README.md +126 -0
  78. package/registry/blocks/auth-form/auth-form.jsx +568 -0
  79. package/registry/blocks/auth-form/block.json +10 -0
  80. package/registry/blocks/auth-form/demo.jsx +131 -0
  81. package/registry/blocks/auth-form/index.js +3 -0
  82. package/registry/blocks/board/README.md +55 -5
  83. package/registry/blocks/board/block.json +2 -2
  84. package/registry/blocks/board/board.jsx +230 -86
  85. package/registry/blocks/board/demo.jsx +103 -24
  86. package/registry/blocks/calendar-view/README.md +180 -0
  87. package/registry/blocks/calendar-view/agenda.jsx +147 -0
  88. package/registry/blocks/calendar-view/block.json +76 -0
  89. package/registry/blocks/calendar-view/calendar-model.js +442 -0
  90. package/registry/blocks/calendar-view/calendar.jsx +627 -0
  91. package/registry/blocks/calendar-view/demo.jsx +195 -0
  92. package/registry/blocks/calendar-view/draft.jsx +49 -0
  93. package/registry/blocks/calendar-view/index.js +39 -0
  94. package/registry/blocks/calendar-view/month.jsx +346 -0
  95. package/registry/blocks/calendar-view/paint.js +69 -0
  96. package/registry/blocks/calendar-view/time-grid.jsx +527 -0
  97. package/registry/blocks/calendar-view/tray.jsx +87 -0
  98. package/registry/blocks/cart/README.md +146 -0
  99. package/registry/blocks/cart/block.json +10 -0
  100. package/registry/blocks/cart/cart.jsx +597 -0
  101. package/registry/blocks/cart/demo.jsx +98 -0
  102. package/registry/blocks/cart/index.js +4 -0
  103. package/registry/blocks/cart/money.js +28 -0
  104. package/registry/blocks/chart/README.md +316 -0
  105. package/registry/blocks/chart/block.json +10 -0
  106. package/registry/blocks/chart/cartesian.jsx +642 -0
  107. package/registry/blocks/chart/core.jsx +262 -0
  108. package/registry/blocks/chart/demo.jsx +357 -0
  109. package/registry/blocks/chart/heatmap.jsx +336 -0
  110. package/registry/blocks/chart/index.js +8 -0
  111. package/registry/blocks/chart/pie.jsx +245 -0
  112. package/registry/blocks/chart/sparkline.jsx +88 -0
  113. package/registry/blocks/chat/README.md +273 -0
  114. package/registry/blocks/chat/attachment.jsx +95 -0
  115. package/registry/blocks/chat/block.json +10 -0
  116. package/registry/blocks/chat/chat.jsx +132 -0
  117. package/registry/blocks/chat/composer.jsx +364 -0
  118. package/registry/blocks/chat/demo.jsx +578 -0
  119. package/registry/blocks/chat/header.jsx +34 -0
  120. package/registry/blocks/chat/index.js +9 -0
  121. package/registry/blocks/chat/message.jsx +450 -0
  122. package/registry/blocks/chat/scroller.jsx +247 -0
  123. package/registry/blocks/chat/text.jsx +104 -0
  124. package/registry/blocks/code-editor/README.md +210 -0
  125. package/registry/blocks/code-editor/block.json +22 -0
  126. package/registry/blocks/code-editor/code-editor.jsx +534 -0
  127. package/registry/blocks/code-editor/codemirror.js +38 -0
  128. package/registry/blocks/code-editor/demo.jsx +205 -0
  129. package/registry/blocks/code-editor/index.js +8 -0
  130. package/registry/blocks/code-editor/json.js +317 -0
  131. package/registry/blocks/code-editor/sql.js +136 -0
  132. package/registry/blocks/code-editor/text.js +101 -0
  133. package/registry/blocks/code-editor/theme.js +186 -0
  134. package/registry/blocks/comment-box/README.md +123 -0
  135. package/registry/blocks/comment-box/block.json +10 -0
  136. package/registry/blocks/comment-box/comment-body.jsx +217 -0
  137. package/registry/blocks/comment-box/comment-box.jsx +198 -0
  138. package/registry/blocks/comment-box/comment-time.jsx +77 -0
  139. package/registry/blocks/comment-box/demo.jsx +141 -0
  140. package/registry/blocks/comment-box/index.js +8 -0
  141. package/registry/blocks/contact-section/README.md +152 -0
  142. package/registry/blocks/contact-section/block.json +11 -0
  143. package/registry/blocks/contact-section/contact-section.jsx +509 -0
  144. package/registry/blocks/contact-section/demo.jsx +93 -0
  145. package/registry/blocks/contact-section/index.js +4 -0
  146. package/registry/blocks/csv-import/README.md +133 -0
  147. package/registry/blocks/csv-import/block.json +13 -0
  148. package/registry/blocks/csv-import/csv-import.jsx +479 -0
  149. package/registry/blocks/csv-import/demo.jsx +106 -0
  150. package/registry/blocks/csv-import/import.js +200 -0
  151. package/registry/blocks/csv-import/index.js +7 -0
  152. package/registry/blocks/data-table/README.md +386 -0
  153. package/registry/blocks/data-table/block.json +10 -0
  154. package/registry/blocks/data-table/data-table.jsx +1164 -0
  155. package/registry/blocks/data-table/demo.jsx +588 -0
  156. package/registry/blocks/data-table/index.js +5 -0
  157. package/registry/blocks/data-table/model.js +169 -0
  158. package/registry/blocks/diagram/README.md +108 -0
  159. package/registry/blocks/diagram/block.json +13 -0
  160. package/registry/blocks/diagram/demo.jsx +113 -0
  161. package/registry/blocks/diagram/diagram.jsx +481 -0
  162. package/registry/blocks/diagram/index.js +7 -0
  163. package/registry/blocks/diagram/mermaid.js +52 -0
  164. package/registry/blocks/diagram/palette.js +313 -0
  165. package/registry/blocks/diagram/source.js +98 -0
  166. package/registry/blocks/doc-editor/README.md +215 -0
  167. package/registry/blocks/doc-editor/block.json +15 -0
  168. package/registry/blocks/doc-editor/demo.jsx +225 -0
  169. package/registry/blocks/doc-editor/doc-editor.jsx +291 -0
  170. package/registry/blocks/doc-editor/doc.js +309 -0
  171. package/registry/blocks/doc-editor/index.js +7 -0
  172. package/registry/blocks/doc-editor/schema.jsx +56 -0
  173. package/registry/blocks/doc-editor/shadcn-classes.js +110 -0
  174. package/registry/blocks/doc-editor/theme.js +82 -0
  175. package/registry/blocks/doc-page/README.md +119 -0
  176. package/registry/blocks/doc-page/autosave.js +104 -0
  177. package/registry/blocks/doc-page/block.json +10 -0
  178. package/registry/blocks/doc-page/demo.jsx +137 -0
  179. package/registry/blocks/doc-page/doc-page.jsx +276 -0
  180. package/registry/blocks/doc-page/index.js +4 -0
  181. package/registry/blocks/email-render/README.md +151 -0
  182. package/registry/blocks/email-render/block.json +14 -0
  183. package/registry/blocks/email-render/demo.jsx +153 -0
  184. package/registry/blocks/email-render/doc-email.jsx +210 -0
  185. package/registry/blocks/email-render/email.jsx +221 -0
  186. package/registry/blocks/email-render/index.js +10 -0
  187. package/registry/blocks/email-render/render.js +50 -0
  188. package/registry/blocks/email-render/theme.js +215 -0
  189. package/registry/blocks/faq/README.md +101 -0
  190. package/registry/blocks/faq/block.json +11 -0
  191. package/registry/blocks/faq/demo.jsx +89 -0
  192. package/registry/blocks/faq/faq.jsx +220 -0
  193. package/registry/blocks/faq/index.js +4 -0
  194. package/registry/blocks/file-upload/README.md +138 -0
  195. package/registry/blocks/file-upload/block.json +10 -0
  196. package/registry/blocks/file-upload/demo.jsx +204 -0
  197. package/registry/blocks/file-upload/file-upload.jsx +635 -0
  198. package/registry/blocks/file-upload/index.js +4 -0
  199. package/registry/blocks/flow-canvas/README.md +420 -0
  200. package/registry/blocks/flow-canvas/block.json +13 -0
  201. package/registry/blocks/flow-canvas/board.js +819 -0
  202. package/registry/blocks/flow-canvas/chrome.jsx +649 -0
  203. package/registry/blocks/flow-canvas/context.jsx +35 -0
  204. package/registry/blocks/flow-canvas/demo.jsx +249 -0
  205. package/registry/blocks/flow-canvas/edges.jsx +107 -0
  206. package/registry/blocks/flow-canvas/flow-canvas.jsx +1329 -0
  207. package/registry/blocks/flow-canvas/index.js +41 -0
  208. package/registry/blocks/flow-canvas/nodes.jsx +392 -0
  209. package/registry/blocks/flow-canvas/theme.js +174 -0
  210. package/registry/blocks/footer/README.md +133 -0
  211. package/registry/blocks/footer/block.json +11 -0
  212. package/registry/blocks/footer/demo.jsx +119 -0
  213. package/registry/blocks/footer/footer.jsx +406 -0
  214. package/registry/blocks/footer/index.js +4 -0
  215. package/registry/blocks/gantt/README.md +220 -0
  216. package/registry/blocks/gantt/block.json +10 -0
  217. package/registry/blocks/gantt/demo.jsx +148 -0
  218. package/registry/blocks/gantt/gantt.jsx +923 -0
  219. package/registry/blocks/gantt/index.js +7 -0
  220. package/registry/blocks/gantt/rows.jsx +468 -0
  221. package/registry/blocks/gantt/schedule.js +278 -0
  222. package/registry/blocks/job-panel/README.md +80 -0
  223. package/registry/blocks/job-panel/block.json +3 -3
  224. package/registry/blocks/job-panel/demo.jsx +230 -3
  225. package/registry/blocks/job-panel/job-panel.jsx +169 -3
  226. package/registry/blocks/json-editor/README.md +133 -0
  227. package/registry/blocks/json-editor/block.json +10 -0
  228. package/registry/blocks/json-editor/demo.jsx +92 -0
  229. package/registry/blocks/json-editor/index.js +7 -0
  230. package/registry/blocks/json-editor/json-editor.jsx +305 -0
  231. package/registry/blocks/json-editor/json-tree.jsx +393 -0
  232. package/registry/blocks/json-editor/tree.js +225 -0
  233. package/registry/blocks/map/README.md +221 -0
  234. package/registry/blocks/map/block.json +14 -0
  235. package/registry/blocks/map/demo.jsx +201 -0
  236. package/registry/blocks/map/geo.js +198 -0
  237. package/registry/blocks/map/index.js +8 -0
  238. package/registry/blocks/map/list.jsx +128 -0
  239. package/registry/blocks/map/map-view.jsx +715 -0
  240. package/registry/blocks/map/maplibre.js +30 -0
  241. package/registry/blocks/map/marks.jsx +146 -0
  242. package/registry/blocks/map/theme.js +142 -0
  243. package/registry/blocks/menubar/README.md +109 -0
  244. package/registry/blocks/menubar/block.json +10 -0
  245. package/registry/blocks/menubar/demo.jsx +128 -0
  246. package/registry/blocks/menubar/index.js +4 -0
  247. package/registry/blocks/menubar/menubar.jsx +199 -0
  248. package/registry/blocks/mind-map/README.md +206 -0
  249. package/registry/blocks/mind-map/block.json +10 -0
  250. package/registry/blocks/mind-map/demo.jsx +103 -0
  251. package/registry/blocks/mind-map/index.js +31 -0
  252. package/registry/blocks/mind-map/mind-map.jsx +1125 -0
  253. package/registry/blocks/mind-map/topic.jsx +143 -0
  254. package/registry/blocks/mind-map/tree.js +645 -0
  255. package/registry/blocks/navigation-menu/README.md +124 -0
  256. package/registry/blocks/navigation-menu/block.json +10 -0
  257. package/registry/blocks/navigation-menu/demo.jsx +84 -0
  258. package/registry/blocks/navigation-menu/index.js +4 -0
  259. package/registry/blocks/navigation-menu/navigation-menu.jsx +448 -0
  260. package/registry/blocks/order-detail/README.md +109 -0
  261. package/registry/blocks/order-detail/block.json +10 -0
  262. package/registry/blocks/order-detail/demo.jsx +88 -0
  263. package/registry/blocks/order-detail/index.js +4 -0
  264. package/registry/blocks/order-detail/order-detail.jsx +354 -0
  265. package/registry/blocks/org-chart/README.md +145 -0
  266. package/registry/blocks/org-chart/block.json +10 -0
  267. package/registry/blocks/org-chart/demo.jsx +94 -0
  268. package/registry/blocks/org-chart/index.js +7 -0
  269. package/registry/blocks/org-chart/org-chart.jsx +631 -0
  270. package/registry/blocks/org-chart/org.js +245 -0
  271. package/registry/blocks/org-chart/person.jsx +96 -0
  272. package/registry/blocks/page-builder/README.md +257 -0
  273. package/registry/blocks/page-builder/block.json +14 -0
  274. package/registry/blocks/page-builder/demo.jsx +145 -0
  275. package/registry/blocks/page-builder/grapes.js +18 -0
  276. package/registry/blocks/page-builder/index.js +11 -0
  277. package/registry/blocks/page-builder/page-builder.jsx +704 -0
  278. package/registry/blocks/page-builder/page-view.jsx +33 -0
  279. package/registry/blocks/page-builder/page.js +118 -0
  280. package/registry/blocks/page-builder/panels.jsx +588 -0
  281. package/registry/blocks/page-builder/sections.js +209 -0
  282. package/registry/blocks/page-builder/theme.js +87 -0
  283. package/registry/blocks/page-builder/thumbs.jsx +189 -0
  284. package/registry/blocks/page-builder/tokens.js +329 -0
  285. package/registry/blocks/payment-methods/README.md +104 -0
  286. package/registry/blocks/payment-methods/block.json +10 -0
  287. package/registry/blocks/payment-methods/demo.jsx +71 -0
  288. package/registry/blocks/payment-methods/index.js +4 -0
  289. package/registry/blocks/payment-methods/payment-methods.jsx +302 -0
  290. package/registry/blocks/pdf-document/README.md +213 -0
  291. package/registry/blocks/pdf-document/block.json +13 -0
  292. package/registry/blocks/pdf-document/demo.jsx +136 -0
  293. package/registry/blocks/pdf-document/index.js +33 -0
  294. package/registry/blocks/pdf-document/money.js +83 -0
  295. package/registry/blocks/pdf-document/pdf-document.jsx +144 -0
  296. package/registry/blocks/pdf-document/primitives.jsx +271 -0
  297. package/registry/blocks/pdf-document/quote.jsx +179 -0
  298. package/registry/blocks/pdf-document/theme.js +193 -0
  299. package/registry/blocks/pdf-viewer/README.md +191 -0
  300. package/registry/blocks/pdf-viewer/block.json +14 -0
  301. package/registry/blocks/pdf-viewer/demo.jsx +252 -0
  302. package/registry/blocks/pdf-viewer/helpers.js +270 -0
  303. package/registry/blocks/pdf-viewer/index.js +8 -0
  304. package/registry/blocks/pdf-viewer/notes.jsx +195 -0
  305. package/registry/blocks/pdf-viewer/pdf-viewer.jsx +1368 -0
  306. package/registry/blocks/pdf-viewer/pdfjs.js +37 -0
  307. package/registry/blocks/pdf-viewer/ssr-shim-end.js +6 -0
  308. package/registry/blocks/pdf-viewer/ssr-shim.js +44 -0
  309. package/registry/blocks/product-detail/README.md +217 -0
  310. package/registry/blocks/product-detail/block.json +10 -0
  311. package/registry/blocks/product-detail/demo.jsx +233 -0
  312. package/registry/blocks/product-detail/index.js +7 -0
  313. package/registry/blocks/product-detail/price.jsx +115 -0
  314. package/registry/blocks/product-detail/product-detail.jsx +348 -0
  315. package/registry/blocks/product-detail/product-media.jsx +102 -0
  316. package/registry/blocks/product-detail/product-options.jsx +144 -0
  317. package/registry/blocks/product-grid/README.md +162 -0
  318. package/registry/blocks/product-grid/block.json +10 -0
  319. package/registry/blocks/product-grid/demo.jsx +255 -0
  320. package/registry/blocks/product-grid/index.js +5 -0
  321. package/registry/blocks/product-grid/product-card.jsx +232 -0
  322. package/registry/blocks/product-grid/product-grid.jsx +235 -0
  323. package/registry/blocks/record-form/README.md +196 -0
  324. package/registry/blocks/record-form/block.json +10 -0
  325. package/registry/blocks/record-form/demo.jsx +525 -0
  326. package/registry/blocks/record-form/index.js +4 -0
  327. package/registry/blocks/record-form/record-fields.jsx +457 -0
  328. package/registry/blocks/record-form/record-form.jsx +415 -0
  329. package/registry/blocks/record-form/rules.js +81 -0
  330. package/registry/blocks/record-notes/README.md +139 -0
  331. package/registry/blocks/record-notes/block.json +10 -0
  332. package/registry/blocks/record-notes/demo.jsx +179 -0
  333. package/registry/blocks/record-notes/index.js +4 -0
  334. package/registry/blocks/record-notes/record-notes.jsx +266 -0
  335. package/registry/blocks/search-dialog/README.md +108 -0
  336. package/registry/blocks/search-dialog/block.json +10 -0
  337. package/registry/blocks/search-dialog/demo.jsx +116 -0
  338. package/registry/blocks/search-dialog/index.js +3 -0
  339. package/registry/blocks/search-dialog/search-dialog.jsx +235 -0
  340. package/registry/blocks/settings-list/README.md +171 -0
  341. package/registry/blocks/settings-list/block.json +10 -0
  342. package/registry/blocks/settings-list/demo.jsx +333 -0
  343. package/registry/blocks/settings-list/index.js +4 -0
  344. package/registry/blocks/settings-list/row-state.jsx +93 -0
  345. package/registry/blocks/settings-list/settings-list.jsx +349 -0
  346. package/registry/blocks/settings-list/settings-matrix.jsx +118 -0
  347. package/registry/blocks/setup-checklist/README.md +142 -0
  348. package/registry/blocks/setup-checklist/block.json +10 -0
  349. package/registry/blocks/setup-checklist/demo.jsx +159 -0
  350. package/registry/blocks/setup-checklist/index.js +4 -0
  351. package/registry/blocks/setup-checklist/setup-checklist.jsx +446 -0
  352. package/registry/blocks/share-dialog/README.md +113 -0
  353. package/registry/blocks/share-dialog/block.json +10 -0
  354. package/registry/blocks/share-dialog/demo.jsx +140 -0
  355. package/registry/blocks/share-dialog/index.js +3 -0
  356. package/registry/blocks/share-dialog/share-dialog.jsx +384 -0
  357. package/registry/blocks/sidebar/README.md +190 -0
  358. package/registry/blocks/sidebar/block.json +43 -0
  359. package/registry/blocks/sidebar/demo.jsx +577 -0
  360. package/registry/blocks/sidebar/index.js +4 -0
  361. package/registry/blocks/sidebar/sidebar-panel.jsx +149 -0
  362. package/registry/blocks/sidebar/sidebar.jsx +864 -0
  363. package/registry/blocks/signature-pad/README.md +137 -0
  364. package/registry/blocks/signature-pad/block.json +13 -0
  365. package/registry/blocks/signature-pad/colors.js +115 -0
  366. package/registry/blocks/signature-pad/demo.jsx +94 -0
  367. package/registry/blocks/signature-pad/index.js +6 -0
  368. package/registry/blocks/signature-pad/pad.js +7 -0
  369. package/registry/blocks/signature-pad/signature-pad.jsx +434 -0
  370. package/registry/blocks/signature-pad/signature.js +68 -0
  371. package/registry/blocks/sketch-canvas/README.md +280 -0
  372. package/registry/blocks/sketch-canvas/block.json +13 -0
  373. package/registry/blocks/sketch-canvas/demo.jsx +159 -0
  374. package/registry/blocks/sketch-canvas/excalidraw.js +40 -0
  375. package/registry/blocks/sketch-canvas/index.js +9 -0
  376. package/registry/blocks/sketch-canvas/palette.js +226 -0
  377. package/registry/blocks/sketch-canvas/sketch-canvas.jsx +1188 -0
  378. package/registry/blocks/sketch-canvas/sketch.js +179 -0
  379. package/registry/blocks/sketch-canvas/ssr-shim-end.js +6 -0
  380. package/registry/blocks/sketch-canvas/ssr-shim.js +45 -0
  381. package/registry/blocks/sketch-canvas/stamps.js +104 -0
  382. package/registry/blocks/sketch-canvas/theme.js +131 -0
  383. package/registry/blocks/spreadsheet/README.md +307 -0
  384. package/registry/blocks/spreadsheet/block.json +13 -0
  385. package/registry/blocks/spreadsheet/cells.jsx +455 -0
  386. package/registry/blocks/spreadsheet/chrome.jsx +325 -0
  387. package/registry/blocks/spreadsheet/demo.jsx +177 -0
  388. package/registry/blocks/spreadsheet/grid.js +387 -0
  389. package/registry/blocks/spreadsheet/index.js +34 -0
  390. package/registry/blocks/spreadsheet/spreadsheet.jsx +1732 -0
  391. package/registry/blocks/spreadsheet/types.js +473 -0
  392. package/registry/blocks/stat-cards/README.md +173 -0
  393. package/registry/blocks/stat-cards/block.json +10 -0
  394. package/registry/blocks/stat-cards/demo.jsx +257 -0
  395. package/registry/blocks/stat-cards/index.js +4 -0
  396. package/registry/blocks/stat-cards/stat-cards.jsx +307 -0
  397. package/registry/blocks/stat-cards/usage.jsx +243 -0
  398. package/registry/blocks/task-list/README.md +176 -0
  399. package/registry/blocks/task-list/block.json +10 -0
  400. package/registry/blocks/task-list/demo.jsx +134 -0
  401. package/registry/blocks/task-list/index.js +5 -0
  402. package/registry/blocks/task-list/task-list.jsx +907 -0
  403. package/registry/blocks/task-model/README.md +455 -0
  404. package/registry/blocks/task-model/block.json +167 -0
  405. package/registry/blocks/task-model/changes.js +89 -0
  406. package/registry/blocks/task-model/dates.js +371 -0
  407. package/registry/blocks/task-model/demo.jsx +215 -0
  408. package/registry/blocks/task-model/dnd.jsx +240 -0
  409. package/registry/blocks/task-model/index.js +97 -0
  410. package/registry/blocks/task-model/model.js +919 -0
  411. package/registry/blocks/task-model/parts.jsx +449 -0
  412. package/registry/blocks/task-model/toolbar.jsx +271 -0
  413. package/registry/blocks/testimonials/README.md +139 -0
  414. package/registry/blocks/testimonials/block.json +11 -0
  415. package/registry/blocks/testimonials/demo.jsx +137 -0
  416. package/registry/blocks/testimonials/index.js +4 -0
  417. package/registry/blocks/testimonials/testimonials.jsx +430 -0
  418. package/registry/blocks/transaction-list/README.md +126 -0
  419. package/registry/blocks/transaction-list/block.json +10 -0
  420. package/registry/blocks/transaction-list/demo.jsx +79 -0
  421. package/registry/blocks/transaction-list/index.js +4 -0
  422. package/registry/blocks/transaction-list/transaction-list.jsx +383 -0
  423. package/registry/blocks/whiteboard/README.md +179 -0
  424. package/registry/blocks/whiteboard/block.json +10 -0
  425. package/registry/blocks/whiteboard/demo.jsx +169 -0
  426. package/registry/blocks/whiteboard/index.js +6 -0
  427. package/registry/blocks/whiteboard/templates.js +150 -0
  428. package/registry/blocks/whiteboard/whiteboard.jsx +721 -0
  429. package/src/install.mjs +18 -0
  430. package/src/shadcn.mjs +8 -0
  431. package/templates/next/files/README.md +145 -11
  432. package/templates/next/files/app/globals.css +55 -4
  433. package/templates/next/files/check/run.mjs +3 -3
  434. package/templates/next/files/components/ui/avatar.jsx +141 -0
  435. package/templates/next/files/components/ui/breadcrumb.jsx +149 -0
  436. package/templates/next/files/components/ui/button-group.jsx +70 -0
  437. package/templates/next/files/components/ui/button.jsx +132 -12
  438. package/templates/next/files/components/ui/calendar.jsx +609 -0
  439. package/templates/next/files/components/ui/carousel.jsx +281 -0
  440. package/templates/next/files/components/ui/collapsible.jsx +208 -0
  441. package/templates/next/files/components/ui/combobox.jsx +608 -0
  442. package/templates/next/files/components/ui/command.jsx +577 -0
  443. package/templates/next/files/components/ui/context-menu.jsx +191 -0
  444. package/templates/next/files/components/ui/date-picker.jsx +360 -0
  445. package/templates/next/files/components/ui/distribution.jsx +117 -0
  446. package/templates/next/files/components/ui/feedback.jsx +143 -0
  447. package/templates/next/files/components/ui/field.jsx +115 -3
  448. package/templates/next/files/components/ui/file-input.jsx +234 -0
  449. package/templates/next/files/components/ui/icon.jsx +130 -8
  450. package/templates/next/files/components/ui/image.jsx +143 -0
  451. package/templates/next/files/components/ui/index.js +47 -2
  452. package/templates/next/files/components/ui/input-group.jsx +213 -0
  453. package/templates/next/files/components/ui/input-otp.jsx +170 -0
  454. package/templates/next/files/components/ui/item.jsx +206 -0
  455. package/templates/next/files/components/ui/menu.jsx +454 -82
  456. package/templates/next/files/components/ui/notice.jsx +126 -14
  457. package/templates/next/files/components/ui/pagination.jsx +156 -0
  458. package/templates/next/files/components/ui/popover.jsx +284 -0
  459. package/templates/next/files/components/ui/radio.jsx +193 -0
  460. package/templates/next/files/components/ui/rating.jsx +131 -0
  461. package/templates/next/files/components/ui/resizable.jsx +338 -0
  462. package/templates/next/files/components/ui/scroll-area.jsx +123 -0
  463. package/templates/next/files/components/ui/separator.jsx +119 -0
  464. package/templates/next/files/components/ui/sheet.jsx +96 -11
  465. package/templates/next/files/components/ui/slider.jsx +174 -0
  466. package/templates/next/files/components/ui/stat.jsx +574 -0
  467. package/templates/next/files/components/ui/steps.jsx +338 -0
  468. package/templates/next/files/components/ui/swatch.jsx +33 -0
  469. package/templates/next/files/components/ui/table.jsx +130 -0
  470. package/templates/next/files/components/ui/toast.jsx +440 -0
  471. package/templates/next/files/components/ui/toggle.jsx +195 -0
  472. package/templates/next/files/components/ui/tooltip.jsx +270 -0
  473. package/templates/next/template.json +264 -8
package/src/install.mjs CHANGED
@@ -147,6 +147,7 @@ function lay(dir, tpl, before) {
147
147
  }
148
148
 
149
149
  const blocks = {};
150
+ const blockDeps = {};
150
151
  const known = loadBlocks();
151
152
  for (const [name, from] of Object.entries(before.manifest?.blocks ?? {})) {
152
153
  if (!existsSync(join(dir, BLOCK_DIR, name))) {
@@ -170,6 +171,20 @@ function lay(dir, tpl, before) {
170
171
  pins[f.to] = hash;
171
172
  }
172
173
  blocks[name] = v;
174
+ Object.assign(blockDeps, block.dependencies);
175
+ }
176
+
177
+ // The blocks' npm packages, at the versions this release pins them to
178
+ // (block.json `dependencies`): a block's files and its packages move
179
+ // together, or an update would lay files the installed package cannot run.
180
+ if (Object.keys(blockDeps).length && existsSync(join(dir, "package.json"))) {
181
+ const path = join(dir, "package.json");
182
+ const { out, changes } = mergePackage(readJson(path, {}), { dependencies: blockDeps });
183
+ if (changes.length) {
184
+ writeJson(path, out);
185
+ if (!written.includes("package.json")) written.push("package.json");
186
+ pkg = [...pkg, ...changes];
187
+ }
173
188
  }
174
189
 
175
190
  for (const p of Object.keys(before.pins)) {
@@ -446,6 +461,9 @@ export function diff(dir) {
446
461
  const pkgPath = join(dir, "package.json");
447
462
  const tplPkg = tpl.files.find((f) => f.class === "merged");
448
463
  const pkg = existsSync(pkgPath) && tplPkg ? mergePackage(readJson(pkgPath), readJson(tplPkg.from)).changes : [];
464
+ // …and the installed blocks' npm packages, which update lays with them.
465
+ const blockDeps = Object.assign({}, ...Object.keys(manifest.blocks ?? {}).map((n) => known.find((b) => b.name === n)?.dependencies ?? {}));
466
+ if (existsSync(pkgPath) && Object.keys(blockDeps).length) pkg.push(...mergePackage(readJson(pkgPath), { dependencies: blockDeps }).changes);
449
467
  return {
450
468
  from: manifest.version,
451
469
  to: v,
package/src/shadcn.mjs CHANGED
@@ -40,6 +40,14 @@ const CSS_VARS = {
40
40
  theme: {
41
41
  "text-2xs": "0.6875rem",
42
42
  "text-2xs--line-height": "1rem",
43
+ // The chart block's series colours. A shadcn theme already defines
44
+ // --chart-1…5 (light and dark); this only makes sure the utilities
45
+ // (fill-chart-1, stroke-chart-2…) read them.
46
+ "color-chart-1": "var(--chart-1)",
47
+ "color-chart-2": "var(--chart-2)",
48
+ "color-chart-3": "var(--chart-3)",
49
+ "color-chart-4": "var(--chart-4)",
50
+ "color-chart-5": "var(--chart-5)",
43
51
  },
44
52
  light: {
45
53
  success: "oklch(0.627 0.194 149.214)",
@@ -129,28 +129,162 @@ rarely does. `npm run check` refuses a raw `<select>`, `<dialog>`,
129
129
  `<svg>`, `role="tab"`, `popover` or `window.confirm()` outside the kit.
130
130
 
131
131
  ```jsx
132
- import { Button, IconButton, Card, Field, Input, Textarea, Select, Switch, Checkbox,
133
- Sheet, Confirm, Tabs, TabPanel, Menu, Notice, Badge, Kicker, Empty, Icon, cx }
132
+ import { Button, IconButton, ButtonGroup, ButtonGroupSeparator, Toggle, ToggleGroup,
133
+ Field, Input, TimeInput, Textarea, Select, Switch, Checkbox, RadioGroup, Radio, Rating,
134
+ InputGroup, PasswordInput, InputOTP, Slider, Image, FileInput, FileDrop, fileMatches, Combobox, Command, CommandDialog, Calendar, DatePicker, DateInput, DATE_PRESETS,
135
+ parseDate, isDateString, toDateString, todayString, addDays, addMonths,
136
+ startOfMonth, endOfMonth, dayOfWeek, formatDate, firstDayOfWeek,
137
+ Card, Notice, Badge, Kicker, Empty, Item, ItemGroup, Avatar, AvatarGroup,
138
+ Sheet, Confirm, Tabs, TabPanel, Menu, ContextMenu, Popover, Tooltip, HoverCard,
139
+ Breadcrumb, Pagination, Collapsible, Accordion, Carousel, ScrollArea,
140
+ ResizablePanelGroup, ResizablePanel, ResizableHandle,
141
+ Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption,
142
+ Spinner, Skeleton, Progress, Separator, Kbd, KbdGroup, AspectRatio,
143
+ Stat, StatGroup, Delta, StatusDot, Legend, Meter, Distribution, Swatch, Steps,
144
+ toast, Toaster, Depiction, Icon, ICON_NAMES, usePopoverPosition, panelClass, cx }
134
145
  from "../components/ui"; // "./ui" from a component
135
146
  import { RecordSwitcher, useFixture, FixtureNotice, isSample } from "../components/parts";
136
147
  ```
137
148
 
138
149
  - `Button` — `variant` primary (one per surface) · secondary · quiet ·
139
- danger · link; `size` md (44px) · sm; `icon="plus"`; `href` for a link.
140
- `IconButton` for an icon alone (`label` required).
150
+ danger · link (inline text: no padding or height, wraps and truncates
151
+ with its sentence; `size="inherit"` takes the sentence's size;
152
+ `tone="muted"` for a secondary link) · nav (a full-width navigation row, start-aligned, normal
153
+ weight, filled by `aria-current="page"`); `size` md (44px) · sm;
154
+ `align` center · start; `icon="plus"`; `href` for a link.
155
+ `IconButton` for an icon alone (`label` required). `loading` while its
156
+ action runs: a spinner, the same width, `aria-busy`, disabled.
141
157
  - `Field` wraps `Input`, `Textarea`, `Select`, `Switch`, `Checkbox` with
142
158
  its label, hint and error. `Select` with empty `options` renders a
143
- muted line, never a disabled dropdown.
159
+ muted line, never a disabled dropdown. `TimeInput` — a time of day
160
+ ("HH:MM"; `min max step`), the kit's clock in place of the browser's.
161
+ - `Rating` — stars: read-only `value` of `max` (halves drawn, "4.5 out
162
+ of 5" to a reader), or with `onChange` a radio-group input; `size`, `label`.
163
+ - `InputGroup` — an input with `icon`, `prefix` ("https://"), `suffix`
164
+ ("USD"), `kbd` and an `action` button (copy, search, show password);
165
+ one border, focus ring and `invalid` for the whole group; `multiline`
166
+ is the chat composer (a growing textarea, `minRows` `maxRows`, `tools`
167
+ and the action in a bar under it, `above` for attached files).
168
+ `PasswordInput` — the password field with a show/hide toggle
169
+ (`autoComplete` passes through; "new-password" on sign-up).
170
+ `Textarea autoGrow` grows with its text the same way. `InputOTP` —
171
+ a one-time code in boxes (`length` or `groups={[3, 3]}`, `digitsOnly`,
172
+ `onComplete(code)`, `invalid`; paste and SMS autofill fill every box).
173
+ `Slider` — a number, or a range with `value={[low, high]}`; `min max
174
+ step`, `showValue` + `format`. A number someone will type is an Input.
175
+ - `Combobox` — pick one or many from a searchable list (`options` with
176
+ `icon`, `description`, `group`, `count` at the right; `multiple` →
177
+ chips; `creatable`; `open` + `onOpenChange` or `defaultOpen`;
178
+ `onSearch` async; `clearable`; in a `Field` by `id`; a bottom sheet on a
179
+ phone). `searchable={false}` is the rich Select (icons, descriptions)
180
+ — a plain list of words stays the native `Select`. `Command` — a
181
+ searchable list of actions (`items` with `icon`, `shortcut`, `keywords`,
182
+ `group`, `onSelect`); `CommandDialog hotkey="k"` is the ⌘K palette.
144
183
  - `Sheet` — the one overlay, a rail beside the work (`side="end"`), a
145
- dialog (`center`) or a bottom sheet; on a narrow window every side
146
- becomes a bottom sheet. `Confirm` is the "delete this?" case.
184
+ navigation drawer (`start`), a dialog (`center`) or a bottom sheet; on a narrow window every side
185
+ becomes a bottom sheet; `bare` + `label` for a panel that draws its own
186
+ top (no header, flush body). `Confirm` is the "delete this?" case;
187
+ `consequences`, `requireText` and `acknowledge` hold it until met.
188
+ - `Image src alt ratio fit rounded` — a picture of a thing (thumbnail,
189
+ cover): Skeleton while it loads, a glyph when it fails, lazy, `alt`
190
+ required. Never a raw `<img>`; a face is an `Avatar`.
191
+ - `FileInput onFiles accept multiple` (a Button that opens the picker;
192
+ only a `label` → an IconButton) and `FileDrop` (a drop zone, `label`
193
+ `hint` `size` sm · md; a drop is filtered by `accept`, the rest go to
194
+ `onReject`). Never a raw `<input type="file">`.
147
195
  - `Tabs` + `TabPanel` — views of ONE thing (a record's notes | history).
148
196
  Never for the app's surfaces; those are the shell's nav.
149
- - `Menu` — the "…" of a row. Empty `items` render nothing: a menu is
150
- earned by having actions.
151
- - `Card`, `Notice` (tone neutral · info · success · warning · danger),
152
- `Badge`, `Kicker` (the small line above a heading), `Empty` (a filter
197
+ - `Menu` — the "…" of a row, a View or Account dropdown. `items` are
198
+ data: actions (`icon`, `tone`, `shortcut`, `description`), `{ group,
199
+ items }`, `{ type: "separator" }`, `{ type: "checkbox", checked,
200
+ onCheckedChange }`, `{ type: "radio", value, onValueChange, options }`
201
+ (choices keep it open) and submenus `{ label, items }`; `side` +
202
+ `align`; `size` sm (36px, default) · md (44px trigger). Empty `items` render nothing: a menu is earned by having
203
+ actions. `ContextMenu` opens the same `items` on a region's right-click,
204
+ long press or Shift+F10 — a shortcut, never the only door.
205
+ - `Popover` (a panel beside its `trigger`; `side`, `align`, `width`;
206
+ flips at the window's edge; `open` + `onOpenChange` or uncontrolled),
207
+ `Tooltip` (a short text `label` on hover or keyboard focus; never on
208
+ touch, so it only repeats what is visible) and `HoverCard` (a preview
209
+ of what a link points at; may hold links). `usePopoverPosition` is the
210
+ placement alone, for a floating part of your own.
211
+ - `DatePicker` (a field that opens a Calendar; `mode` single · range,
212
+ `presets`, `clearable`, `min max disabled`; in a `Field` with the same
213
+ `id`), `Calendar` (the grid inline; `mode` single · multiple · range,
214
+ `numberOfMonths`, `captionLayout` dropdown · none (you show and move a
215
+ controlled `month`), `showWeekNumbers`, `weekStartsOn`, `marked` with
216
+ `emphasizeMarked` and `onlyMarked`) and
217
+ `DateInput` (a typed date with the Calendar a button away). Dates are
218
+ `"YYYY-MM-DD"` strings in and out — never a Date — and `addDays`,
219
+ `addMonths`, `formatDate`… do the arithmetic.
220
+ - `RadioGroup` (`options` or `<Radio>` children, each with a
221
+ `description`; `variant` list · card; `orientation`; in a `Field` with
222
+ the same `id`), `Toggle` (`pressed` + `onPressedChange`, aria-pressed),
223
+ `ToggleGroup` (the segmented control; `type` single · multiple) and
224
+ `ButtonGroup` (buttons, icon buttons and a `Menu` joined into one
225
+ piece; `ButtonGroupSeparator` between primary or quiet ones).
226
+ - `Avatar name src size shape status` (initials while loading and when
227
+ the image fails) and `AvatarGroup people max` ("+N" past `max`);
228
+ `Breadcrumb items={[{ label, href }]}` (last is this page; the middle
229
+ folds into "…"; the current page takes the rest of the row); `Pagination page pageCount` with `hrefFor(page)` or
230
+ `onPageChange` (compact on a phone; `pageSize` + `onPageSizeChange`).
231
+ - `Collapsible` (title, meta, `open` + `onOpenChange` or `defaultOpen`;
232
+ `variant` plain · outline · flush for edge-to-edge rows inside a Card;
233
+ `chevron` down · right, the disclosure triangle that turns down)
234
+ and `Accordion` (`items`, `type` single · multiple) — show and hide,
235
+ never a raw `<details>`. `Item` / `ItemGroup` — the list row (media or
236
+ icon, title, description, meta, actions; `href` or `onClick` makes the
237
+ whole row the target; `aria-current`, `onClick`, `target`, `rel` reach
238
+ that link or button). `Table` + `TableHeader`, `TableBody`, `TableRow`
239
+ (`selected`), `TableHead` (`sort` + `onSort`; `sortIndex` when several
240
+ are sorted), `TableCell` (`numeric`)
241
+ — a table that scrolls inside itself on a phone.
242
+ - `Card` (`padding` md · sm · none — none for a table or rows that run
243
+ to the border, never `p-0!`; `titleSize` md · lg for a 20px title),
244
+ `Notice` (tone neutral · info · success · warning · danger),
245
+ `Badge` (tone neutral · primary · success · warning · danger · info;
246
+ `variant` label — small caps · soft — the case as written, every tone
247
+ tinted, primary too · outline — the case as written, a hairline, no
248
+ fill · code — a version tag or a commit hash in the mono face; `hue`
249
+ 1..5 for a KIND of thing — a platform, a content type — never a state:
250
+ tone is status, hue is category), `Kicker` (the small line above a heading), `Empty` (a filter
153
251
  or search with no matches — not the landing state, that is the fixture).
252
+ - `Spinner` (size sm · md · lg), `Skeleton` (shape line · circle · rect,
253
+ sized by className), `Progress` (`value` of `max`, no value for
254
+ indeterminate; tone; `label`) — waiting, never a hand-drawn loader.
255
+ - `Steps steps={[{ label, description, status, meta }]}` (or `current`)
256
+ — where a staged job has got: `variant` dots · bar (rollout phases);
257
+ status complete · current · pending · failed · skipped; `orientation`
258
+ horizontal · vertical; `pulse`; `label` + `valueText`;
259
+ `hideStepLabels` for bare dots (still pass every label: it is what a
260
+ reader hears); `onSelect`
261
+ only when a step opens something. Never a hand-drawn stepper.
262
+ - `Stat label value unit caption tone delta invert size` (sm · md · lg)
263
+ in a `StatGroup` (the 2–4 summary strip; card · divided · bare);
264
+ `Delta value suffix invert` (coloured by sign; zero is neutral);
265
+ `StatusDot tone pulse label`; `Legend items={[{ tone, label, count }]}`;
266
+ `Meter value max unit target thresholds` (a role=meter; over the limit
267
+ turns danger; `direction` higher · lower picks the tone against the
268
+ target; `valueTone`; `targetMark={false}`; tone `muted` for a plain
269
+ grey share) — numbers and states, never a hand-drawn tile or bar.
270
+ `Delta hideValue` is the arrow alone; `StatusDot` and Legend items take
271
+ `hue` (1..5) for a category. `Distribution segments={[{ label, value,
272
+ tone, hue }]} legend label size` (thin · md) — parts of one whole as
273
+ one stacked bar, a hue per segment, a tone for sentiment. `Swatch color
274
+ label size` — a colour that comes from data; the only inline colour.
275
+ - `Separator` (horizontal · vertical; `decorative={false}` for a real
276
+ one), `Kbd` / `KbdGroup keys={["⌘", "K"]}`, `AspectRatio ratio="video"`
277
+ (its child fills it), `ScrollArea` (a bounded scroller with themed
278
+ scrollbars, `fade`, keyboard-focusable while it overflows; `ref` is the
279
+ scrolling element, for a list that sets its own scrollTop).
280
+ - `toast("Saved")`, `toast.success/.error/.info/.warning(title, {
281
+ description, action, duration })`, `toast.promise(p, { loading,
282
+ success, error })` — nothing to mount; `<Toaster position />` only to
283
+ move the stack. A toast is never the only record of an error.
284
+ - `Carousel label itemsPerView` (scroll-snap; 1 on a phone; dots ·
285
+ counter; `loop`, `autoplay` only when asked), `ResizablePanelGroup`
286
+ + `ResizablePanel defaultSize minSize` + `ResizableHandle grip`
287
+ (`storageKey` remembers; a horizontal group stacks below md).
154
288
  - `Icon name="…"` — one sprite, `ICON_NAMES` lists it. Missing one? Add
155
289
  the glyph to `components/ui/icon.jsx`; never an `<svg>` in a surface.
156
290
  - `RecordSwitcher` — pick a saved record or make a new one. With nothing
@@ -100,6 +100,41 @@
100
100
  border: 0;
101
101
  background: transparent;
102
102
  }
103
+
104
+ /* Status tones when the preset does not pin them (@theme below reads
105
+ these). The plain fallbacks there are for a dark canvas and read faint
106
+ on a light one, so a light page gets darker ones: by color-scheme (the
107
+ preset's), through light-dark(), where the browser has it; by
108
+ data-theme=light where it does not. Every one reads at 4.5:1 or more
109
+ as text on the Daylight background and card. */
110
+ [data-theme=light] {
111
+ --scheme-success: #15703a;
112
+ --scheme-warning: #9a4a06;
113
+ --scheme-info: #1d4ed8;
114
+ --scheme-destructive: #c01c1c;
115
+ }
116
+ @supports (color: light-dark(red, red)) {
117
+ :root,
118
+ [data-theme] {
119
+ --scheme-success: light-dark(#15703a, #4ade80);
120
+ --scheme-warning: light-dark(#9a4a06, #ffbd38);
121
+ --scheme-info: light-dark(#1d4ed8, #60a5fa);
122
+ --scheme-destructive: light-dark(#c01c1c, #fb2c36);
123
+ }
124
+ }
125
+
126
+ /* Chart series 2-5, derived with relative colour (oklch(from …)), which
127
+ Chrome before 119 and Safari before 16.4 lack. Set only where it
128
+ parses; elsewhere @theme falls back to plain colours that still stay
129
+ apart, rather than to no colour at all. */
130
+ @supports (color: oklch(from red l c h)) {
131
+ :root {
132
+ --chart-derived-2: oklch(from var(--primary, var(--midground-base)) clamp(0.55, l, 0.8) clamp(0.12, c, 0.2) calc(h + 144));
133
+ --chart-derived-3: oklch(from var(--primary, var(--midground-base)) clamp(0.55, l, 0.8) clamp(0.12, c, 0.2) calc(h + 288));
134
+ --chart-derived-4: oklch(from var(--primary, var(--midground-base)) clamp(0.55, l, 0.8) clamp(0.12, c, 0.2) calc(h + 72));
135
+ --chart-derived-5: oklch(from var(--primary, var(--midground-base)) clamp(0.55, l, 0.8) clamp(0.12, c, 0.2) calc(h + 216));
136
+ }
137
+ }
103
138
  }
104
139
 
105
140
  /* The boundary where the workspace theme stops: a depiction (README §3c),
@@ -150,16 +185,32 @@
150
185
  --color-accent: var(--accent, color-mix(in srgb, var(--midground-base) 12%, var(--background-base)));
151
186
  --color-accent-foreground: var(--accent-foreground, var(--midground-base));
152
187
 
153
- --color-destructive: var(--destructive, #fb2c36);
188
+ --color-destructive: var(--destructive, var(--scheme-destructive, #fb2c36));
154
189
  --color-destructive-foreground: var(--destructive-foreground, #ffffff);
155
- --color-success: var(--success, #4ade80);
156
- --color-warning: var(--warning, #ffbd38);
157
- --color-info: var(--info, #60a5fa);
190
+ --color-success: var(--success, var(--scheme-success, #4ade80));
191
+ --color-warning: var(--warning, var(--scheme-warning, #ffbd38));
192
+ --color-info: var(--info, var(--scheme-info, #60a5fa));
158
193
 
159
194
  --color-border: var(--border, color-mix(in srgb, var(--midground-base) 15%, transparent));
160
195
  --color-input: var(--input, color-mix(in srgb, var(--midground-base) 15%, transparent));
161
196
  --color-ring: var(--ring, var(--midground-base));
162
197
 
198
+ /* Chart series (fill-chart-1, stroke-chart-2, bg-chart-3…), for the chart
199
+ block: several colours that must stay apart in every theme. A preset
200
+ (or a shadcn theme) may pin --chart-N. Otherwise chart-1 is the primary
201
+ and the others turn its hue round the wheel, 144° a step so neighbours
202
+ never sit close, keeping its lightness (the primary already reads on
203
+ this canvas) with a floor on chroma so a grey or pastel theme still
204
+ gets colours. Not success/warning/info: those are status, and a theme's
205
+ primary is often one of them (amber, mint, blue). The turn is worked
206
+ out in the base layer (--chart-derived-N); the hex after it is for a
207
+ browser without relative colour. */
208
+ --color-chart-1: var(--chart-1, var(--primary, var(--midground-base)));
209
+ --color-chart-2: var(--chart-2, var(--chart-derived-2, #14b8a6));
210
+ --color-chart-3: var(--chart-3, var(--chart-derived-3, #a78bfa));
211
+ --color-chart-4: var(--chart-4, var(--chart-derived-4, #f472b6));
212
+ --color-chart-5: var(--chart-5, var(--chart-derived-5, #38bdf8));
213
+
163
214
  --radius-sm: calc(var(--theme-radius) - 4px);
164
215
  --radius-md: calc(var(--theme-radius) - 2px);
165
216
  --radius-lg: var(--theme-radius);
@@ -48,7 +48,7 @@ const STATIC_ONLY = process.argv.includes("--static");
48
48
  // update` lays both folders again.
49
49
  // Exact names AND extensions: Next resolves .js before .jsx, so a
50
50
  // components/ui/depiction.js beside depiction.jsx would win unseen.
51
- const KIT = /^components\/(?:ui\/(?:cx|index)\.js|ui\/(?:button|depiction|field|icon|menu|notice|sheet|tabs)\.jsx|parts\/(?:index|sample)\.js|parts\/(?:fixture|record-switcher)\.jsx)$/;
51
+ const KIT = /^components\/(?:ui\/(?:cx|index)\.js|ui\/(?:radio|toggle|button-group|avatar|breadcrumb|pagination|button|collapsible|item|table|depiction|feedback|stat|distribution|swatch|steps|separator|scroll-area|field|icon|menu|context-menu|popover|calendar|date-picker|tooltip|notice|sheet|tabs|slider|input-group|image|file-input|input-otp|command|combobox|rating|toast|carousel|resizable)\.jsx|parts\/(?:index|sample)\.js|parts\/(?:fixture|record-switcher)\.jsx)$/;
52
52
 
53
53
  // The pins: sha256 of every fixed file, written by `makersclaw init` and
54
54
  // `makersclaw add` (check/pins.json). Read first, because a BLOCK is
@@ -209,11 +209,11 @@ const ATTRS = String.raw`(?:"[^"]*"|'[^']*'|\{(?:[^{}]|\{[^{}]*\})*\}|[^>"'{])*`
209
209
  const RULES = [
210
210
  [/<select\b/, "Select from components/ui, or RecordSwitcher from components/parts", files],
211
211
  [/<dialog\b/, "Sheet or Confirm from components/ui", files],
212
- [/<details\b/, "Menu or Sheet from components/ui", files],
212
+ [/<details\b/, "Collapsible or Accordion from components/ui", files],
213
213
  [/role=["']tab(?:list)?["']/, "Tabs from components/ui", files],
214
214
  [/role=["']menu(?:item)?["']/, "Menu from components/ui", files],
215
215
  [/role=["']dialog["']/, "Sheet from components/ui", files],
216
- [/\bpopover=/, "Menu from components/ui", files],
216
+ [/\bpopover=/, "Popover, Tooltip, HoverCard or Menu from components/ui", files],
217
217
  [/window\.confirm\(/, "Confirm from components/ui", files],
218
218
  [/<svg\b/, "Icon from components/ui (add a glyph there if it is missing)", appFiles],
219
219
  ];
@@ -0,0 +1,141 @@
1
+ "use client";
2
+
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { cx } from "./cx";
5
+ import { Icon } from "./icon";
6
+
7
+ // Avatar — a person's face, or their initials while it loads and when it
8
+ // fails. The initials are always drawn; the image lays over them only
9
+ // once it has loaded, so a slow, missing or broken `src` never shows a
10
+ // hole or the browser's broken-image glyph. No name either: a user icon.
11
+ //
12
+ // name "Jane Cooper" → JC; also the accessible name
13
+ // src the image; optional
14
+ // size xs (24px) · sm (32px) · md (40px) · lg (56px)
15
+ // shape round · square (a company, a bot, a workspace)
16
+ // status online · away · busy · offline — a dot, named to a reader
17
+ // label overrides what a screen reader says
18
+ //
19
+ // AvatarGroup below is the overlapping stack with "+N" after `max`.
20
+
21
+ const SIZES = {
22
+ xs: { box: "h-6 w-6 text-2xs", dot: "h-1.5 w-1.5", icon: 12, overlap: "-space-x-1.5" },
23
+ sm: { box: "h-8 w-8 text-xs", dot: "h-2 w-2", icon: 14, overlap: "-space-x-2" },
24
+ md: { box: "h-10 w-10 text-sm", dot: "h-2.5 w-2.5", icon: 18, overlap: "-space-x-2.5" },
25
+ lg: { box: "h-14 w-14 text-lg", dot: "h-3.5 w-3.5", icon: 24, overlap: "-space-x-3" },
26
+ };
27
+
28
+ const SHAPES = { round: "rounded-full", square: "rounded-md" };
29
+
30
+ // Colour is the signal: the status tones are the workspace's status tokens.
31
+ const STATUS = {
32
+ online: { dot: "bg-success", say: "online" },
33
+ away: { dot: "bg-warning", say: "away" },
34
+ busy: { dot: "bg-destructive", say: "busy" },
35
+ offline: { dot: "bg-muted-foreground", say: "offline" },
36
+ };
37
+
38
+ /** "Jane Cooper" → "JC", "jane@acme.com" → "J", "Priya" → "P". First and
39
+ * last word, by code point, so an accented or non-Latin name survives. */
40
+ function initials(name) {
41
+ const words = String(name ?? "").split("@")[0].trim().split(/[\s._-]+/).filter(Boolean);
42
+ if (words.length === 0) return "";
43
+ const first = Array.from(words[0])[0] ?? "";
44
+ const last = words.length > 1 ? Array.from(words[words.length - 1])[0] ?? "" : "";
45
+ return (first + last).toUpperCase();
46
+ }
47
+
48
+ export function Avatar({ name, src, size = "md", shape = "round", status, label, className }) {
49
+ const s = SIZES[size] ?? SIZES.md;
50
+ const round = SHAPES[shape] ?? SHAPES.round;
51
+ const st = STATUS[status];
52
+ const img = useRef(null);
53
+ // Both hold the src they are about, so a new src starts fresh unreset.
54
+ const [loaded, setLoaded] = useState(null);
55
+ const [failed, setFailed] = useState(null);
56
+
57
+ // A server-rendered <img> can load or fail before React is listening.
58
+ useEffect(() => {
59
+ const i = img.current;
60
+ if (!i || !src || !i.complete) return;
61
+ if (i.naturalWidth > 0) setLoaded(src);
62
+ else setFailed(src);
63
+ }, [src]);
64
+
65
+ const text = initials(name);
66
+ const said = label ?? ([name, st?.say].filter(Boolean).join(", ") || undefined);
67
+ const showImg = src && failed !== src;
68
+
69
+ return (
70
+ <span
71
+ role={said ? "img" : undefined}
72
+ aria-label={said}
73
+ aria-hidden={said ? undefined : true}
74
+ title={name || undefined}
75
+ className={cx("relative inline-flex shrink-0 select-none", round, s.box, className)}
76
+ >
77
+ <span className={cx("relative flex h-full w-full items-center justify-center overflow-hidden bg-muted font-medium text-muted-foreground", round)}>
78
+ {/* Hidden, not removed, once the image is in: a transparent PNG must not show letters through it. */}
79
+ <span aria-hidden="true" className={cx("inline-flex leading-none", loaded === src && showImg && "invisible")}>
80
+ {text || <Icon name="user" size={s.icon} />}
81
+ </span>
82
+ {showImg ? (
83
+ <img
84
+ ref={img}
85
+ src={src}
86
+ alt=""
87
+ onLoad={() => setLoaded(src)}
88
+ onError={() => setFailed(src)}
89
+ className={cx("absolute inset-0 h-full w-full object-cover", loaded === src ? "opacity-100" : "opacity-0")}
90
+ />
91
+ ) : null}
92
+ </span>
93
+ {st ? (
94
+ <span
95
+ aria-hidden="true"
96
+ className={cx(
97
+ "absolute rounded-full ring-2 ring-background",
98
+ shape === "square" ? "-bottom-0.5 -right-0.5" : "bottom-0 right-0",
99
+ s.dot,
100
+ st.dot,
101
+ )}
102
+ />
103
+ ) : null}
104
+ </span>
105
+ );
106
+ }
107
+
108
+ /** Faces overlapping, the first `max` of `people`, then "+N" naming the
109
+ * rest on hover and to a reader. No status dots: the next face covers
110
+ * them. Empty `people` renders nothing.
111
+ *
112
+ * people [{ name, src? }]
113
+ * max how many faces before "+N" (default 4)
114
+ */
115
+ export function AvatarGroup({ people, max = 4, size = "sm", shape = "round", label, className }) {
116
+ const list = (people ?? []).filter(Boolean);
117
+ if (list.length === 0) return null;
118
+ const s = SIZES[size] ?? SIZES.sm;
119
+ const round = SHAPES[shape] ?? SHAPES.round;
120
+ const shown = list.slice(0, Math.max(1, max));
121
+ const rest = list.slice(shown.length);
122
+ const restNames = rest.map((p) => p.name).filter(Boolean).join(", ");
123
+
124
+ return (
125
+ <div role="group" aria-label={label ?? `${list.length} people`} className={cx("flex items-center", s.overlap, className)}>
126
+ {shown.map((p, i) => (
127
+ <Avatar key={i} name={p.name} src={p.src} size={size} shape={shape} className="ring-2 ring-background" />
128
+ ))}
129
+ {rest.length > 0 ? (
130
+ <span
131
+ role="img"
132
+ aria-label={`and ${rest.length} more${restNames ? `: ${restNames}` : ""}`}
133
+ title={restNames || undefined}
134
+ className={cx("relative inline-flex shrink-0 items-center justify-center bg-muted font-medium text-muted-foreground ring-2 ring-background", round, s.box)}
135
+ >
136
+ <span data-nums aria-hidden="true" className="leading-none">+{rest.length}</span>
137
+ </span>
138
+ ) : null}
139
+ </div>
140
+ );
141
+ }
@@ -0,0 +1,149 @@
1
+ "use client";
2
+
3
+ import { useId, useRef } from "react";
4
+ import Link from "next/link";
5
+ import { cx } from "./cx";
6
+ import { Icon } from "./icon";
7
+ import { usePopoverPosition } from "./popover";
8
+
9
+ // Breadcrumb — where this page sits: Deals › Acme Corp › Renewal. Items
10
+ // are data; each with an `href` is a next/link (base path applied), the
11
+ // last is the page you are on (aria-current) and is never a link.
12
+ // A client part (a server surface renders it as it is; items are plain
13
+ // data): the "…" that stands in for the middle is a native popover
14
+ // (popovertarget), kept under its button by usePopoverPosition — CSS
15
+ // anchoring where the browser has it, measured where it does not.
16
+ //
17
+ // items [{ label, href? }] — first is the root, last is this page
18
+ // max how many slots on a wide window before the middle folds
19
+ // into "…" (default 4, the "…" counts as one); a narrow
20
+ // window shows first › … › last once there are four or more
21
+ // separator chevron (default) · slash
22
+ //
23
+ // Long labels truncate, the full text on hover. Earlier crumbs are capped
24
+ // (max-w-40, 56 on sm+); the current page takes the rest of the row. One item or none: nothing
25
+ // to place the page within, so nothing is drawn.
26
+
27
+ const SEP = {
28
+ chevron: <Icon name="chevron-right" size={14} />,
29
+ slash: <span className="px-0.5">/</span>,
30
+ };
31
+
32
+ // Shown at one width and not the other: the "…", each crumb, each entry
33
+ // in the popover. Whole class names, so Tailwind sees them.
34
+ const SHOW = {
35
+ flex: { both: "flex", narrow: "flex sm:hidden", wide: "hidden sm:flex", none: "hidden" },
36
+ block: { both: "block", narrow: "block sm:hidden", wide: "hidden sm:block", none: "hidden" },
37
+ };
38
+
39
+ // Every crumb truncates; only the earlier ones carry a cap. The current
40
+ // page is the one worth reading, so it takes whatever the row has left
41
+ // and cuts off only when the row really runs out. It is clamped to one
42
+ // line rather than kept on one (nowrap), so its narrowest size is a
43
+ // letter, not the whole title: a card or grid cell sized by its content
44
+ // still shrinks to the window instead of being pushed wide by the title.
45
+ const CRUMB = "min-w-0 rounded-sm outline-none focus-visible:ring-2 focus-visible:ring-ring";
46
+ const CAP = "block max-w-40 truncate sm:max-w-56";
47
+ const REST = "line-clamp-1 [overflow-wrap:anywhere]";
48
+
49
+ export function Breadcrumb({ items, max = 4, separator = "chevron", label = "Breadcrumb", className }) {
50
+ const auto = useId();
51
+ const more = useRef(null);
52
+ const panel = useRef(null);
53
+ usePopoverPosition(more, panel, { side: "bottom", align: "start", offset: 4 });
54
+ const list = (items ?? []).filter(Boolean);
55
+ if (list.length < 2) return null;
56
+
57
+ const id = `crumbs-${auto.replace(/[^a-zA-Z0-9]/g, "")}`;
58
+ const n = list.length;
59
+ const keep = Math.max(1, max - 2); // trailing items kept beside the first and the "…"
60
+ // Middle item i folds on a wide window when there are more than `max`;
61
+ // on a narrow one every middle item folds once there are four or more
62
+ // (three fit, truncated).
63
+ const foldsWide = (i) => n > max && i > 0 && i < n - keep;
64
+ const foldsNarrow = n > 3;
65
+ const middle = list.slice(1, -1).map((item, k) => ({ item, i: k + 1 }));
66
+ const wideFold = middle.some(({ i }) => foldsWide(i));
67
+ const at = (narrow, wide, display = "flex") => SHOW[display][narrow ? (wide ? "both" : "narrow") : wide ? "wide" : "none"];
68
+ const sep = (
69
+ <span aria-hidden="true" className="shrink-0 text-muted-foreground/70">
70
+ {SEP[separator] ?? SEP.chevron}
71
+ </span>
72
+ );
73
+
74
+ const crumb = (item, current) =>
75
+ current || !item.href ? (
76
+ <span aria-current={current ? "page" : undefined} title={item.label} className={cx(CRUMB, current ? cx(REST, "font-medium text-foreground") : CAP)}>
77
+ {item.label}
78
+ </span>
79
+ ) : (
80
+ <Link href={item.href} title={item.label} className={cx(CRUMB, CAP, "transition-colors hover:text-foreground")}>
81
+ {item.label}
82
+ </Link>
83
+ );
84
+
85
+ return (
86
+ <nav aria-label={label} className={cx("min-w-0", className)}>
87
+ <ol className="flex min-w-0 items-center gap-1.5 text-sm text-muted-foreground">
88
+ <li className="flex min-w-0 items-center">{crumb(list[0], false)}</li>
89
+
90
+ {middle.length > 0 ? (
91
+ <li className={cx("shrink-0 items-center gap-1.5", at(foldsNarrow, wideFold))}>
92
+ {sep}
93
+ <button
94
+ type="button"
95
+ ref={more}
96
+ popoverTarget={id}
97
+ aria-label="Show the full path"
98
+ title="Show the full path"
99
+ className="-mx-1 inline-flex h-8 w-8 items-center justify-center rounded-md outline-none hover:bg-accent hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring"
100
+ >
101
+ <Icon name="more" size={18} />
102
+ </button>
103
+ {/* Keyed by the page, so a client navigation lands with it closed. */}
104
+ <div
105
+ key={list[n - 1].href ?? list[n - 1].label}
106
+ ref={panel}
107
+ id={id}
108
+ popover="auto"
109
+ className="min-w-44 max-w-[calc(100vw-2rem)] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg"
110
+ >
111
+ <ul>
112
+ {middle.map(({ item, i }) => (
113
+ <li key={i} className={at(foldsNarrow, foldsWide(i), "block")}>
114
+ {item.href ? (
115
+ <Link
116
+ href={item.href}
117
+ className="flex min-h-10 items-center rounded-sm px-2 text-sm outline-none hover:bg-accent focus-visible:bg-accent"
118
+ >
119
+ <span className="truncate">{item.label}</span>
120
+ </Link>
121
+ ) : (
122
+ <span className="flex min-h-10 items-center px-2 text-sm text-muted-foreground">
123
+ <span className="truncate">{item.label}</span>
124
+ </span>
125
+ )}
126
+ </li>
127
+ ))}
128
+ </ul>
129
+ </div>
130
+ </li>
131
+ ) : null}
132
+
133
+ {middle.map(({ item, i }) => (
134
+ <li key={i} className={cx("min-w-0 items-center gap-1.5", at(!foldsNarrow, !foldsWide(i)))}>
135
+ {sep}
136
+ {crumb(item, false)}
137
+ </li>
138
+ ))}
139
+
140
+ {/* The rest of the row, and never less than 10rem (or half a narrow
141
+ row): long earlier crumbs give way before this page's title. */}
142
+ <li className="flex min-w-[min(10rem,50%)] flex-1 items-center gap-1.5">
143
+ {sep}
144
+ {crumb(list[n - 1], true)}
145
+ </li>
146
+ </ol>
147
+ </nav>
148
+ );
149
+ }