makersclaw 0.2.0 → 0.3.1

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 (475) 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/cli.mjs +19 -6
  430. package/src/install.mjs +18 -0
  431. package/src/registry.mjs +38 -4
  432. package/src/shadcn.mjs +14 -1
  433. package/templates/next/files/README.md +145 -11
  434. package/templates/next/files/app/globals.css +55 -4
  435. package/templates/next/files/check/run.mjs +3 -3
  436. package/templates/next/files/components/ui/avatar.jsx +141 -0
  437. package/templates/next/files/components/ui/breadcrumb.jsx +149 -0
  438. package/templates/next/files/components/ui/button-group.jsx +70 -0
  439. package/templates/next/files/components/ui/button.jsx +132 -12
  440. package/templates/next/files/components/ui/calendar.jsx +609 -0
  441. package/templates/next/files/components/ui/carousel.jsx +281 -0
  442. package/templates/next/files/components/ui/collapsible.jsx +208 -0
  443. package/templates/next/files/components/ui/combobox.jsx +608 -0
  444. package/templates/next/files/components/ui/command.jsx +577 -0
  445. package/templates/next/files/components/ui/context-menu.jsx +191 -0
  446. package/templates/next/files/components/ui/date-picker.jsx +360 -0
  447. package/templates/next/files/components/ui/distribution.jsx +117 -0
  448. package/templates/next/files/components/ui/feedback.jsx +143 -0
  449. package/templates/next/files/components/ui/field.jsx +115 -3
  450. package/templates/next/files/components/ui/file-input.jsx +234 -0
  451. package/templates/next/files/components/ui/icon.jsx +130 -8
  452. package/templates/next/files/components/ui/image.jsx +143 -0
  453. package/templates/next/files/components/ui/index.js +47 -2
  454. package/templates/next/files/components/ui/input-group.jsx +213 -0
  455. package/templates/next/files/components/ui/input-otp.jsx +170 -0
  456. package/templates/next/files/components/ui/item.jsx +206 -0
  457. package/templates/next/files/components/ui/menu.jsx +454 -82
  458. package/templates/next/files/components/ui/notice.jsx +126 -14
  459. package/templates/next/files/components/ui/pagination.jsx +156 -0
  460. package/templates/next/files/components/ui/popover.jsx +284 -0
  461. package/templates/next/files/components/ui/radio.jsx +193 -0
  462. package/templates/next/files/components/ui/rating.jsx +131 -0
  463. package/templates/next/files/components/ui/resizable.jsx +338 -0
  464. package/templates/next/files/components/ui/scroll-area.jsx +123 -0
  465. package/templates/next/files/components/ui/separator.jsx +119 -0
  466. package/templates/next/files/components/ui/sheet.jsx +96 -11
  467. package/templates/next/files/components/ui/slider.jsx +174 -0
  468. package/templates/next/files/components/ui/stat.jsx +574 -0
  469. package/templates/next/files/components/ui/steps.jsx +338 -0
  470. package/templates/next/files/components/ui/swatch.jsx +33 -0
  471. package/templates/next/files/components/ui/table.jsx +130 -0
  472. package/templates/next/files/components/ui/toast.jsx +440 -0
  473. package/templates/next/files/components/ui/toggle.jsx +195 -0
  474. package/templates/next/files/components/ui/tooltip.jsx +270 -0
  475. package/templates/next/template.json +264 -8
package/src/cli.mjs CHANGED
@@ -3,9 +3,9 @@
3
3
  // agent reading a terminal: short lines, what changed, what to run next.
4
4
  // --json is the same result as one object, for the platform.
5
5
 
6
- import { resolve } from "node:path";
6
+ import { delimiter, resolve } from "node:path";
7
7
  import { CliError, add, diff, init, remove, update } from "./install.mjs";
8
- import { loadItems, loadTemplate, packageInfo, readmeOf, searchItems, suggest, templateNames } from "./registry.mjs";
8
+ import { loadItems, loadTemplate, packageInfo, readmeOf, searchItems, suggest, templateNames, useExtraBlockRoots } from "./registry.mjs";
9
9
 
10
10
  const COMMANDS = {
11
11
  init: "init",
@@ -139,8 +139,10 @@ function addText(r) {
139
139
  return lines.join("\n");
140
140
  }
141
141
 
142
+ const kind = (item) => (item.tier === "premium" ? "premium" : item.type);
143
+
142
144
  function itemLine(item) {
143
- return ` ${item.name.padEnd(18)} ${item.type.padEnd(10)} ${clip(item.description, 72)}`;
145
+ return ` ${item.name.padEnd(18)} ${kind(item).padEnd(10)} ${clip(item.description, 72)}`;
144
146
  }
145
147
 
146
148
  function searchText(query, matches) {
@@ -155,7 +157,7 @@ function searchText(query, matches) {
155
157
 
156
158
  function viewText(item, readme) {
157
159
  const { version } = packageInfo();
158
- const head = `${item.name} · ${item.type} · makersclaw ${version}`;
160
+ const head = `${item.name} · ${item.type}${item.tier === "premium" ? " · premium" : ""} · makersclaw ${version}`;
159
161
  if (readme) return `${head}\n\n${readme.trimEnd()}`;
160
162
  const folder = item.type === "part" ? "parts" : "ui";
161
163
  return [
@@ -179,7 +181,7 @@ function listText(items) {
179
181
  const of = items.filter((i) => i.type === type);
180
182
  if (!of.length) continue;
181
183
  lines.push("", label);
182
- for (const i of of) lines.push(` ${i.name.padEnd(18)} ${clip(i.description, 80)}`);
184
+ for (const i of of) lines.push(` ${i.name.padEnd(18)} ${i.tier === "premium" ? "premium · " : ""}${clip(i.description, 80)}`);
183
185
  }
184
186
  return lines.join("\n");
185
187
  }
@@ -271,6 +273,7 @@ function summary(item) {
271
273
  return {
272
274
  name: item.name,
273
275
  type: item.type,
276
+ tier: item.tier,
274
277
  title: item.title,
275
278
  description: item.description,
276
279
  useWhen: item.useWhen || undefined,
@@ -281,7 +284,17 @@ function summary(item) {
281
284
  };
282
285
  }
283
286
 
284
- export function main(argv, { stdout = process.stdout, stderr = process.stderr } = {}) {
287
+ /** The block roots the platform names beside the package's own
288
+ * (MAKERSCLAW_BLOCKS_DIR, folders joined like PATH). */
289
+ export function blockRootsFromEnv(env = process.env) {
290
+ return String(env.MAKERSCLAW_BLOCKS_DIR ?? "")
291
+ .split(delimiter)
292
+ .map((d) => d.trim())
293
+ .filter(Boolean);
294
+ }
295
+
296
+ export function main(argv, { stdout = process.stdout, stderr = process.stderr, env = process.env } = {}) {
297
+ useExtraBlockRoots(blockRootsFromEnv(env));
285
298
  let opts = { json: argv.includes("--json") };
286
299
  try {
287
300
  opts = parseArgs(argv);
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/registry.mjs CHANGED
@@ -7,6 +7,12 @@
7
7
  // app has one until `add` puts it there, so the agent searches for what
8
8
  // it needs and installs just that. Everything here ships inside this
9
9
  // package, so the version you run is the version you get.
10
+ //
11
+ // One exception: extra block roots. The platform lays its premium blocks
12
+ // (never on npm) into the sandbox and names their folder; the CLI's entry
13
+ // point hands it to useExtraBlockRoots() from MAKERSCLAW_BLOCKS_DIR. Only
14
+ // that entry point does: the shadcn registry builder never calls it, so
15
+ // no environment variable can put a premium block into the npm package.
10
16
 
11
17
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
12
18
  import { join } from "node:path";
@@ -79,13 +85,40 @@ export function loadTemplate(name) {
79
85
  return { name, title: meta.title ?? name, description: meta.description ?? "", root, files, components };
80
86
  }
81
87
 
88
+ let extraRoots = [];
89
+
90
+ /** Block folders outside this package (the platform's premium blocks),
91
+ * read after the package's own. Same shape as registry/blocks/. */
92
+ export function useExtraBlockRoots(dirs) {
93
+ extraRoots = (dirs ?? []).filter((d) => d && existsSync(d) && statSync(d).isDirectory());
94
+ }
95
+
96
+ export function extraBlockRoots() {
97
+ return [...extraRoots];
98
+ }
99
+
82
100
  export function loadBlocks() {
83
- if (!existsSync(BLOCKS)) return [];
84
- return readdirSync(BLOCKS)
85
- .filter((n) => statSync(join(BLOCKS, n)).isDirectory())
101
+ const blocks = [];
102
+ const seen = new Map();
103
+ for (const root of [BLOCKS, ...extraRoots]) {
104
+ for (const block of loadBlocksFrom(root, root === BLOCKS ? "free" : "premium")) {
105
+ if (seen.has(block.name)) {
106
+ throw new Error(`block ${block.name}: in both ${seen.get(block.name)} and ${root} — a block name is used once`);
107
+ }
108
+ seen.set(block.name, root);
109
+ blocks.push(block);
110
+ }
111
+ }
112
+ return blocks;
113
+ }
114
+
115
+ function loadBlocksFrom(root, defaultTier) {
116
+ if (!existsSync(root)) return [];
117
+ return readdirSync(root)
118
+ .filter((n) => statSync(join(root, n)).isDirectory())
86
119
  .sort()
87
120
  .map((folder) => {
88
- const dir = join(BLOCKS, folder);
121
+ const dir = join(root, folder);
89
122
  const meta = readJson(join(dir, "block.json"));
90
123
  if (!meta) throw new Error(`block ${folder}: no block.json`);
91
124
  if (meta.name !== folder || !NAME.test(folder)) throw new Error(`block ${folder}: name must be the folder's, lowercase and dashed`);
@@ -98,6 +131,7 @@ export function loadBlocks() {
98
131
  return {
99
132
  name: folder,
100
133
  type: "block",
134
+ tier: meta.tier === "premium" || defaultTier === "premium" ? "premium" : "free",
101
135
  title: meta.title ?? folder,
102
136
  description: meta.description ?? "",
103
137
  tags: meta.tags ?? [],
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)",
@@ -142,7 +150,12 @@ function blockItem(block, base, version) {
142
150
  /** Every item, with its files' content, and the index shadcn's `list` and
143
151
  * `search` read (the same items, without content). */
144
152
  export function buildRegistry({ base = defaultBase(), version = packageInfo().version } = {}) {
145
- const items = [coreItem(), ...loadBlocks().map((b) => blockItem(b, base, version))];
153
+ // Free blocks only. Extra roots are set by the CLI's entry point, never
154
+ // here — this refusal is the second lock on premium code reaching npm.
155
+ const blocks = loadBlocks();
156
+ const premium = blocks.filter((b) => b.tier === "premium").map((b) => b.name);
157
+ if (premium.length) throw new Error(`the public registry would carry premium blocks (${premium.join(", ")}) — build it without extra block roots`);
158
+ const items = [coreItem(), ...blocks.map((b) => blockItem(b, base, version))];
146
159
  const index = {
147
160
  $schema: INDEX_SCHEMA,
148
161
  name: "makersclaw",
@@ -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
+ }