makersclaw 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -1
  3. package/THIRD-PARTY-NOTICES.md +180 -0
  4. package/package.json +15 -8
  5. package/r/annotate.json +62 -0
  6. package/r/approval-request.json +52 -0
  7. package/r/audio-player.json +74 -0
  8. package/r/auth-form.json +55 -0
  9. package/r/board.json +55 -0
  10. package/r/calendar-view.json +105 -0
  11. package/r/cart.json +62 -0
  12. package/r/chart.json +83 -0
  13. package/r/chat.json +95 -0
  14. package/r/code-editor.json +94 -0
  15. package/r/comment-box.json +64 -0
  16. package/r/contact-section.json +53 -0
  17. package/r/core.json +341 -0
  18. package/r/csv-import.json +63 -0
  19. package/r/data-table.json +69 -0
  20. package/r/diagram.json +74 -0
  21. package/r/doc-editor.json +82 -0
  22. package/r/doc-page.json +61 -0
  23. package/r/email-render.json +73 -0
  24. package/r/faq.json +50 -0
  25. package/r/file-upload.json +54 -0
  26. package/r/flow-canvas.json +93 -0
  27. package/r/footer.json +52 -0
  28. package/r/gantt.json +70 -0
  29. package/r/job-panel.json +56 -0
  30. package/r/json-editor.json +66 -0
  31. package/r/map.json +89 -0
  32. package/r/menubar.json +52 -0
  33. package/r/mind-map.json +67 -0
  34. package/r/navigation-menu.json +52 -0
  35. package/r/order-detail.json +54 -0
  36. package/r/org-chart.json +66 -0
  37. package/r/page-builder.json +105 -0
  38. package/r/payment-methods.json +51 -0
  39. package/r/pdf-document.json +79 -0
  40. package/r/pdf-viewer.json +88 -0
  41. package/r/product-detail.json +76 -0
  42. package/r/product-grid.json +65 -0
  43. package/r/record-form.json +67 -0
  44. package/r/record-notes.json +55 -0
  45. package/r/registry.json +3612 -0
  46. package/r/search-dialog.json +51 -0
  47. package/r/settings-list.json +66 -0
  48. package/r/setup-checklist.json +51 -0
  49. package/r/share-dialog.json +52 -0
  50. package/r/sidebar.json +69 -0
  51. package/r/signature-pad.json +72 -0
  52. package/r/sketch-canvas.json +99 -0
  53. package/r/spreadsheet.json +90 -0
  54. package/r/stat-cards.json +66 -0
  55. package/r/task-list.json +63 -0
  56. package/r/task-model.json +98 -0
  57. package/r/testimonials.json +52 -0
  58. package/r/transaction-list.json +53 -0
  59. package/r/whiteboard.json +66 -0
  60. package/registry/blocks/annotate/README.md +179 -0
  61. package/registry/blocks/annotate/annotate-data.js +250 -0
  62. package/registry/blocks/annotate/annotate.jsx +646 -0
  63. package/registry/blocks/annotate/block.json +10 -0
  64. package/registry/blocks/annotate/demo.jsx +135 -0
  65. package/registry/blocks/annotate/index.js +15 -0
  66. package/registry/blocks/approval-request/README.md +116 -0
  67. package/registry/blocks/approval-request/approval-request.jsx +386 -0
  68. package/registry/blocks/approval-request/block.json +10 -0
  69. package/registry/blocks/approval-request/demo.jsx +127 -0
  70. package/registry/blocks/approval-request/index.js +4 -0
  71. package/registry/blocks/audio-player/README.md +167 -0
  72. package/registry/blocks/audio-player/audio-player.jsx +623 -0
  73. package/registry/blocks/audio-player/block.json +14 -0
  74. package/registry/blocks/audio-player/colors.js +109 -0
  75. package/registry/blocks/audio-player/demo.jsx +209 -0
  76. package/registry/blocks/audio-player/index.js +6 -0
  77. package/registry/blocks/audio-player/time.js +67 -0
  78. package/registry/blocks/audio-player/wavesurfer.js +9 -0
  79. package/registry/blocks/auth-form/README.md +126 -0
  80. package/registry/blocks/auth-form/auth-form.jsx +568 -0
  81. package/registry/blocks/auth-form/block.json +10 -0
  82. package/registry/blocks/auth-form/demo.jsx +131 -0
  83. package/registry/blocks/auth-form/index.js +3 -0
  84. package/registry/blocks/board/README.md +64 -13
  85. package/registry/blocks/board/block.json +2 -2
  86. package/registry/blocks/board/board.jsx +237 -94
  87. package/registry/blocks/board/demo.jsx +103 -24
  88. package/registry/blocks/calendar-view/README.md +180 -0
  89. package/registry/blocks/calendar-view/agenda.jsx +147 -0
  90. package/registry/blocks/calendar-view/block.json +76 -0
  91. package/registry/blocks/calendar-view/calendar-model.js +442 -0
  92. package/registry/blocks/calendar-view/calendar.jsx +627 -0
  93. package/registry/blocks/calendar-view/demo.jsx +195 -0
  94. package/registry/blocks/calendar-view/draft.jsx +49 -0
  95. package/registry/blocks/calendar-view/index.js +39 -0
  96. package/registry/blocks/calendar-view/month.jsx +346 -0
  97. package/registry/blocks/calendar-view/paint.js +69 -0
  98. package/registry/blocks/calendar-view/time-grid.jsx +527 -0
  99. package/registry/blocks/calendar-view/tray.jsx +87 -0
  100. package/registry/blocks/cart/README.md +146 -0
  101. package/registry/blocks/cart/block.json +10 -0
  102. package/registry/blocks/cart/cart.jsx +597 -0
  103. package/registry/blocks/cart/demo.jsx +98 -0
  104. package/registry/blocks/cart/index.js +4 -0
  105. package/registry/blocks/cart/money.js +28 -0
  106. package/registry/blocks/chart/README.md +316 -0
  107. package/registry/blocks/chart/block.json +10 -0
  108. package/registry/blocks/chart/cartesian.jsx +642 -0
  109. package/registry/blocks/chart/core.jsx +262 -0
  110. package/registry/blocks/chart/demo.jsx +357 -0
  111. package/registry/blocks/chart/heatmap.jsx +336 -0
  112. package/registry/blocks/chart/index.js +8 -0
  113. package/registry/blocks/chart/pie.jsx +245 -0
  114. package/registry/blocks/chart/sparkline.jsx +88 -0
  115. package/registry/blocks/chat/README.md +273 -0
  116. package/registry/blocks/chat/attachment.jsx +95 -0
  117. package/registry/blocks/chat/block.json +10 -0
  118. package/registry/blocks/chat/chat.jsx +132 -0
  119. package/registry/blocks/chat/composer.jsx +364 -0
  120. package/registry/blocks/chat/demo.jsx +578 -0
  121. package/registry/blocks/chat/header.jsx +34 -0
  122. package/registry/blocks/chat/index.js +9 -0
  123. package/registry/blocks/chat/message.jsx +450 -0
  124. package/registry/blocks/chat/scroller.jsx +247 -0
  125. package/registry/blocks/chat/text.jsx +104 -0
  126. package/registry/blocks/code-editor/README.md +210 -0
  127. package/registry/blocks/code-editor/block.json +22 -0
  128. package/registry/blocks/code-editor/code-editor.jsx +534 -0
  129. package/registry/blocks/code-editor/codemirror.js +38 -0
  130. package/registry/blocks/code-editor/demo.jsx +205 -0
  131. package/registry/blocks/code-editor/index.js +8 -0
  132. package/registry/blocks/code-editor/json.js +317 -0
  133. package/registry/blocks/code-editor/sql.js +136 -0
  134. package/registry/blocks/code-editor/text.js +101 -0
  135. package/registry/blocks/code-editor/theme.js +186 -0
  136. package/registry/blocks/comment-box/README.md +123 -0
  137. package/registry/blocks/comment-box/block.json +10 -0
  138. package/registry/blocks/comment-box/comment-body.jsx +217 -0
  139. package/registry/blocks/comment-box/comment-box.jsx +198 -0
  140. package/registry/blocks/comment-box/comment-time.jsx +77 -0
  141. package/registry/blocks/comment-box/demo.jsx +141 -0
  142. package/registry/blocks/comment-box/index.js +8 -0
  143. package/registry/blocks/contact-section/README.md +152 -0
  144. package/registry/blocks/contact-section/block.json +11 -0
  145. package/registry/blocks/contact-section/contact-section.jsx +509 -0
  146. package/registry/blocks/contact-section/demo.jsx +93 -0
  147. package/registry/blocks/contact-section/index.js +4 -0
  148. package/registry/blocks/csv-import/README.md +133 -0
  149. package/registry/blocks/csv-import/block.json +13 -0
  150. package/registry/blocks/csv-import/csv-import.jsx +479 -0
  151. package/registry/blocks/csv-import/demo.jsx +106 -0
  152. package/registry/blocks/csv-import/import.js +200 -0
  153. package/registry/blocks/csv-import/index.js +7 -0
  154. package/registry/blocks/data-table/README.md +386 -0
  155. package/registry/blocks/data-table/block.json +10 -0
  156. package/registry/blocks/data-table/data-table.jsx +1164 -0
  157. package/registry/blocks/data-table/demo.jsx +588 -0
  158. package/registry/blocks/data-table/index.js +5 -0
  159. package/registry/blocks/data-table/model.js +169 -0
  160. package/registry/blocks/diagram/README.md +108 -0
  161. package/registry/blocks/diagram/block.json +13 -0
  162. package/registry/blocks/diagram/demo.jsx +113 -0
  163. package/registry/blocks/diagram/diagram.jsx +481 -0
  164. package/registry/blocks/diagram/index.js +7 -0
  165. package/registry/blocks/diagram/mermaid.js +52 -0
  166. package/registry/blocks/diagram/palette.js +313 -0
  167. package/registry/blocks/diagram/source.js +98 -0
  168. package/registry/blocks/doc-editor/README.md +215 -0
  169. package/registry/blocks/doc-editor/block.json +15 -0
  170. package/registry/blocks/doc-editor/demo.jsx +225 -0
  171. package/registry/blocks/doc-editor/doc-editor.jsx +291 -0
  172. package/registry/blocks/doc-editor/doc.js +309 -0
  173. package/registry/blocks/doc-editor/index.js +7 -0
  174. package/registry/blocks/doc-editor/schema.jsx +56 -0
  175. package/registry/blocks/doc-editor/shadcn-classes.js +110 -0
  176. package/registry/blocks/doc-editor/theme.js +82 -0
  177. package/registry/blocks/doc-page/README.md +119 -0
  178. package/registry/blocks/doc-page/autosave.js +104 -0
  179. package/registry/blocks/doc-page/block.json +10 -0
  180. package/registry/blocks/doc-page/demo.jsx +137 -0
  181. package/registry/blocks/doc-page/doc-page.jsx +276 -0
  182. package/registry/blocks/doc-page/index.js +4 -0
  183. package/registry/blocks/email-render/README.md +151 -0
  184. package/registry/blocks/email-render/block.json +14 -0
  185. package/registry/blocks/email-render/demo.jsx +153 -0
  186. package/registry/blocks/email-render/doc-email.jsx +210 -0
  187. package/registry/blocks/email-render/email.jsx +221 -0
  188. package/registry/blocks/email-render/index.js +10 -0
  189. package/registry/blocks/email-render/render.js +50 -0
  190. package/registry/blocks/email-render/theme.js +215 -0
  191. package/registry/blocks/faq/README.md +101 -0
  192. package/registry/blocks/faq/block.json +11 -0
  193. package/registry/blocks/faq/demo.jsx +89 -0
  194. package/registry/blocks/faq/faq.jsx +220 -0
  195. package/registry/blocks/faq/index.js +4 -0
  196. package/registry/blocks/file-upload/README.md +138 -0
  197. package/registry/blocks/file-upload/block.json +10 -0
  198. package/registry/blocks/file-upload/demo.jsx +204 -0
  199. package/registry/blocks/file-upload/file-upload.jsx +635 -0
  200. package/registry/blocks/file-upload/index.js +4 -0
  201. package/registry/blocks/flow-canvas/README.md +420 -0
  202. package/registry/blocks/flow-canvas/block.json +13 -0
  203. package/registry/blocks/flow-canvas/board.js +819 -0
  204. package/registry/blocks/flow-canvas/chrome.jsx +649 -0
  205. package/registry/blocks/flow-canvas/context.jsx +35 -0
  206. package/registry/blocks/flow-canvas/demo.jsx +249 -0
  207. package/registry/blocks/flow-canvas/edges.jsx +107 -0
  208. package/registry/blocks/flow-canvas/flow-canvas.jsx +1329 -0
  209. package/registry/blocks/flow-canvas/index.js +41 -0
  210. package/registry/blocks/flow-canvas/nodes.jsx +392 -0
  211. package/registry/blocks/flow-canvas/theme.js +174 -0
  212. package/registry/blocks/footer/README.md +133 -0
  213. package/registry/blocks/footer/block.json +11 -0
  214. package/registry/blocks/footer/demo.jsx +119 -0
  215. package/registry/blocks/footer/footer.jsx +406 -0
  216. package/registry/blocks/footer/index.js +4 -0
  217. package/registry/blocks/gantt/README.md +220 -0
  218. package/registry/blocks/gantt/block.json +10 -0
  219. package/registry/blocks/gantt/demo.jsx +148 -0
  220. package/registry/blocks/gantt/gantt.jsx +923 -0
  221. package/registry/blocks/gantt/index.js +7 -0
  222. package/registry/blocks/gantt/rows.jsx +468 -0
  223. package/registry/blocks/gantt/schedule.js +278 -0
  224. package/registry/blocks/job-panel/README.md +86 -2
  225. package/registry/blocks/job-panel/block.json +3 -3
  226. package/registry/blocks/job-panel/demo.jsx +230 -3
  227. package/registry/blocks/job-panel/job-panel.jsx +169 -3
  228. package/registry/blocks/json-editor/README.md +133 -0
  229. package/registry/blocks/json-editor/block.json +10 -0
  230. package/registry/blocks/json-editor/demo.jsx +92 -0
  231. package/registry/blocks/json-editor/index.js +7 -0
  232. package/registry/blocks/json-editor/json-editor.jsx +305 -0
  233. package/registry/blocks/json-editor/json-tree.jsx +393 -0
  234. package/registry/blocks/json-editor/tree.js +225 -0
  235. package/registry/blocks/map/README.md +221 -0
  236. package/registry/blocks/map/block.json +14 -0
  237. package/registry/blocks/map/demo.jsx +201 -0
  238. package/registry/blocks/map/geo.js +198 -0
  239. package/registry/blocks/map/index.js +8 -0
  240. package/registry/blocks/map/list.jsx +128 -0
  241. package/registry/blocks/map/map-view.jsx +715 -0
  242. package/registry/blocks/map/maplibre.js +30 -0
  243. package/registry/blocks/map/marks.jsx +146 -0
  244. package/registry/blocks/map/theme.js +142 -0
  245. package/registry/blocks/menubar/README.md +109 -0
  246. package/registry/blocks/menubar/block.json +10 -0
  247. package/registry/blocks/menubar/demo.jsx +128 -0
  248. package/registry/blocks/menubar/index.js +4 -0
  249. package/registry/blocks/menubar/menubar.jsx +199 -0
  250. package/registry/blocks/mind-map/README.md +206 -0
  251. package/registry/blocks/mind-map/block.json +10 -0
  252. package/registry/blocks/mind-map/demo.jsx +103 -0
  253. package/registry/blocks/mind-map/index.js +31 -0
  254. package/registry/blocks/mind-map/mind-map.jsx +1125 -0
  255. package/registry/blocks/mind-map/topic.jsx +143 -0
  256. package/registry/blocks/mind-map/tree.js +645 -0
  257. package/registry/blocks/navigation-menu/README.md +124 -0
  258. package/registry/blocks/navigation-menu/block.json +10 -0
  259. package/registry/blocks/navigation-menu/demo.jsx +84 -0
  260. package/registry/blocks/navigation-menu/index.js +4 -0
  261. package/registry/blocks/navigation-menu/navigation-menu.jsx +448 -0
  262. package/registry/blocks/order-detail/README.md +109 -0
  263. package/registry/blocks/order-detail/block.json +10 -0
  264. package/registry/blocks/order-detail/demo.jsx +88 -0
  265. package/registry/blocks/order-detail/index.js +4 -0
  266. package/registry/blocks/order-detail/order-detail.jsx +354 -0
  267. package/registry/blocks/org-chart/README.md +145 -0
  268. package/registry/blocks/org-chart/block.json +10 -0
  269. package/registry/blocks/org-chart/demo.jsx +94 -0
  270. package/registry/blocks/org-chart/index.js +7 -0
  271. package/registry/blocks/org-chart/org-chart.jsx +631 -0
  272. package/registry/blocks/org-chart/org.js +245 -0
  273. package/registry/blocks/org-chart/person.jsx +96 -0
  274. package/registry/blocks/page-builder/README.md +257 -0
  275. package/registry/blocks/page-builder/block.json +14 -0
  276. package/registry/blocks/page-builder/demo.jsx +145 -0
  277. package/registry/blocks/page-builder/grapes.js +18 -0
  278. package/registry/blocks/page-builder/index.js +11 -0
  279. package/registry/blocks/page-builder/page-builder.jsx +704 -0
  280. package/registry/blocks/page-builder/page-view.jsx +33 -0
  281. package/registry/blocks/page-builder/page.js +118 -0
  282. package/registry/blocks/page-builder/panels.jsx +588 -0
  283. package/registry/blocks/page-builder/sections.js +209 -0
  284. package/registry/blocks/page-builder/theme.js +87 -0
  285. package/registry/blocks/page-builder/thumbs.jsx +189 -0
  286. package/registry/blocks/page-builder/tokens.js +329 -0
  287. package/registry/blocks/payment-methods/README.md +104 -0
  288. package/registry/blocks/payment-methods/block.json +10 -0
  289. package/registry/blocks/payment-methods/demo.jsx +71 -0
  290. package/registry/blocks/payment-methods/index.js +4 -0
  291. package/registry/blocks/payment-methods/payment-methods.jsx +302 -0
  292. package/registry/blocks/pdf-document/README.md +213 -0
  293. package/registry/blocks/pdf-document/block.json +13 -0
  294. package/registry/blocks/pdf-document/demo.jsx +136 -0
  295. package/registry/blocks/pdf-document/index.js +33 -0
  296. package/registry/blocks/pdf-document/money.js +83 -0
  297. package/registry/blocks/pdf-document/pdf-document.jsx +144 -0
  298. package/registry/blocks/pdf-document/primitives.jsx +271 -0
  299. package/registry/blocks/pdf-document/quote.jsx +179 -0
  300. package/registry/blocks/pdf-document/theme.js +193 -0
  301. package/registry/blocks/pdf-viewer/README.md +191 -0
  302. package/registry/blocks/pdf-viewer/block.json +14 -0
  303. package/registry/blocks/pdf-viewer/demo.jsx +252 -0
  304. package/registry/blocks/pdf-viewer/helpers.js +270 -0
  305. package/registry/blocks/pdf-viewer/index.js +8 -0
  306. package/registry/blocks/pdf-viewer/notes.jsx +195 -0
  307. package/registry/blocks/pdf-viewer/pdf-viewer.jsx +1368 -0
  308. package/registry/blocks/pdf-viewer/pdfjs.js +37 -0
  309. package/registry/blocks/pdf-viewer/ssr-shim-end.js +6 -0
  310. package/registry/blocks/pdf-viewer/ssr-shim.js +44 -0
  311. package/registry/blocks/product-detail/README.md +217 -0
  312. package/registry/blocks/product-detail/block.json +10 -0
  313. package/registry/blocks/product-detail/demo.jsx +233 -0
  314. package/registry/blocks/product-detail/index.js +7 -0
  315. package/registry/blocks/product-detail/price.jsx +115 -0
  316. package/registry/blocks/product-detail/product-detail.jsx +348 -0
  317. package/registry/blocks/product-detail/product-media.jsx +102 -0
  318. package/registry/blocks/product-detail/product-options.jsx +144 -0
  319. package/registry/blocks/product-grid/README.md +162 -0
  320. package/registry/blocks/product-grid/block.json +10 -0
  321. package/registry/blocks/product-grid/demo.jsx +255 -0
  322. package/registry/blocks/product-grid/index.js +5 -0
  323. package/registry/blocks/product-grid/product-card.jsx +232 -0
  324. package/registry/blocks/product-grid/product-grid.jsx +235 -0
  325. package/registry/blocks/record-form/README.md +196 -0
  326. package/registry/blocks/record-form/block.json +10 -0
  327. package/registry/blocks/record-form/demo.jsx +525 -0
  328. package/registry/blocks/record-form/index.js +4 -0
  329. package/registry/blocks/record-form/record-fields.jsx +457 -0
  330. package/registry/blocks/record-form/record-form.jsx +415 -0
  331. package/registry/blocks/record-form/rules.js +81 -0
  332. package/registry/blocks/record-notes/README.md +139 -0
  333. package/registry/blocks/record-notes/block.json +10 -0
  334. package/registry/blocks/record-notes/demo.jsx +179 -0
  335. package/registry/blocks/record-notes/index.js +4 -0
  336. package/registry/blocks/record-notes/record-notes.jsx +266 -0
  337. package/registry/blocks/search-dialog/README.md +108 -0
  338. package/registry/blocks/search-dialog/block.json +10 -0
  339. package/registry/blocks/search-dialog/demo.jsx +116 -0
  340. package/registry/blocks/search-dialog/index.js +3 -0
  341. package/registry/blocks/search-dialog/search-dialog.jsx +235 -0
  342. package/registry/blocks/settings-list/README.md +171 -0
  343. package/registry/blocks/settings-list/block.json +10 -0
  344. package/registry/blocks/settings-list/demo.jsx +333 -0
  345. package/registry/blocks/settings-list/index.js +4 -0
  346. package/registry/blocks/settings-list/row-state.jsx +93 -0
  347. package/registry/blocks/settings-list/settings-list.jsx +349 -0
  348. package/registry/blocks/settings-list/settings-matrix.jsx +118 -0
  349. package/registry/blocks/setup-checklist/README.md +142 -0
  350. package/registry/blocks/setup-checklist/block.json +10 -0
  351. package/registry/blocks/setup-checklist/demo.jsx +159 -0
  352. package/registry/blocks/setup-checklist/index.js +4 -0
  353. package/registry/blocks/setup-checklist/setup-checklist.jsx +446 -0
  354. package/registry/blocks/share-dialog/README.md +113 -0
  355. package/registry/blocks/share-dialog/block.json +10 -0
  356. package/registry/blocks/share-dialog/demo.jsx +140 -0
  357. package/registry/blocks/share-dialog/index.js +3 -0
  358. package/registry/blocks/share-dialog/share-dialog.jsx +384 -0
  359. package/registry/blocks/sidebar/README.md +190 -0
  360. package/registry/blocks/sidebar/block.json +43 -0
  361. package/registry/blocks/sidebar/demo.jsx +577 -0
  362. package/registry/blocks/sidebar/index.js +4 -0
  363. package/registry/blocks/sidebar/sidebar-panel.jsx +149 -0
  364. package/registry/blocks/sidebar/sidebar.jsx +864 -0
  365. package/registry/blocks/signature-pad/README.md +137 -0
  366. package/registry/blocks/signature-pad/block.json +13 -0
  367. package/registry/blocks/signature-pad/colors.js +115 -0
  368. package/registry/blocks/signature-pad/demo.jsx +94 -0
  369. package/registry/blocks/signature-pad/index.js +6 -0
  370. package/registry/blocks/signature-pad/pad.js +7 -0
  371. package/registry/blocks/signature-pad/signature-pad.jsx +434 -0
  372. package/registry/blocks/signature-pad/signature.js +68 -0
  373. package/registry/blocks/sketch-canvas/README.md +280 -0
  374. package/registry/blocks/sketch-canvas/block.json +13 -0
  375. package/registry/blocks/sketch-canvas/demo.jsx +159 -0
  376. package/registry/blocks/sketch-canvas/excalidraw.js +40 -0
  377. package/registry/blocks/sketch-canvas/index.js +9 -0
  378. package/registry/blocks/sketch-canvas/palette.js +226 -0
  379. package/registry/blocks/sketch-canvas/sketch-canvas.jsx +1188 -0
  380. package/registry/blocks/sketch-canvas/sketch.js +179 -0
  381. package/registry/blocks/sketch-canvas/ssr-shim-end.js +6 -0
  382. package/registry/blocks/sketch-canvas/ssr-shim.js +45 -0
  383. package/registry/blocks/sketch-canvas/stamps.js +104 -0
  384. package/registry/blocks/sketch-canvas/theme.js +131 -0
  385. package/registry/blocks/spreadsheet/README.md +307 -0
  386. package/registry/blocks/spreadsheet/block.json +13 -0
  387. package/registry/blocks/spreadsheet/cells.jsx +455 -0
  388. package/registry/blocks/spreadsheet/chrome.jsx +325 -0
  389. package/registry/blocks/spreadsheet/demo.jsx +177 -0
  390. package/registry/blocks/spreadsheet/grid.js +387 -0
  391. package/registry/blocks/spreadsheet/index.js +34 -0
  392. package/registry/blocks/spreadsheet/spreadsheet.jsx +1732 -0
  393. package/registry/blocks/spreadsheet/types.js +473 -0
  394. package/registry/blocks/stat-cards/README.md +173 -0
  395. package/registry/blocks/stat-cards/block.json +10 -0
  396. package/registry/blocks/stat-cards/demo.jsx +257 -0
  397. package/registry/blocks/stat-cards/index.js +4 -0
  398. package/registry/blocks/stat-cards/stat-cards.jsx +307 -0
  399. package/registry/blocks/stat-cards/usage.jsx +243 -0
  400. package/registry/blocks/task-list/README.md +176 -0
  401. package/registry/blocks/task-list/block.json +10 -0
  402. package/registry/blocks/task-list/demo.jsx +134 -0
  403. package/registry/blocks/task-list/index.js +5 -0
  404. package/registry/blocks/task-list/task-list.jsx +907 -0
  405. package/registry/blocks/task-model/README.md +455 -0
  406. package/registry/blocks/task-model/block.json +167 -0
  407. package/registry/blocks/task-model/changes.js +89 -0
  408. package/registry/blocks/task-model/dates.js +371 -0
  409. package/registry/blocks/task-model/demo.jsx +215 -0
  410. package/registry/blocks/task-model/dnd.jsx +240 -0
  411. package/registry/blocks/task-model/index.js +97 -0
  412. package/registry/blocks/task-model/model.js +919 -0
  413. package/registry/blocks/task-model/parts.jsx +449 -0
  414. package/registry/blocks/task-model/toolbar.jsx +271 -0
  415. package/registry/blocks/testimonials/README.md +139 -0
  416. package/registry/blocks/testimonials/block.json +11 -0
  417. package/registry/blocks/testimonials/demo.jsx +137 -0
  418. package/registry/blocks/testimonials/index.js +4 -0
  419. package/registry/blocks/testimonials/testimonials.jsx +430 -0
  420. package/registry/blocks/transaction-list/README.md +126 -0
  421. package/registry/blocks/transaction-list/block.json +10 -0
  422. package/registry/blocks/transaction-list/demo.jsx +79 -0
  423. package/registry/blocks/transaction-list/index.js +4 -0
  424. package/registry/blocks/transaction-list/transaction-list.jsx +383 -0
  425. package/registry/blocks/whiteboard/README.md +179 -0
  426. package/registry/blocks/whiteboard/block.json +10 -0
  427. package/registry/blocks/whiteboard/demo.jsx +169 -0
  428. package/registry/blocks/whiteboard/index.js +6 -0
  429. package/registry/blocks/whiteboard/templates.js +150 -0
  430. package/registry/blocks/whiteboard/whiteboard.jsx +721 -0
  431. package/src/install.mjs +18 -0
  432. package/src/shadcn.mjs +171 -0
  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/parts/fixture.jsx +1 -1
  437. package/templates/next/files/components/parts/sample.js +15 -0
  438. package/templates/next/files/components/ui/avatar.jsx +141 -0
  439. package/templates/next/files/components/ui/breadcrumb.jsx +149 -0
  440. package/templates/next/files/components/ui/button-group.jsx +70 -0
  441. package/templates/next/files/components/ui/button.jsx +132 -12
  442. package/templates/next/files/components/ui/calendar.jsx +609 -0
  443. package/templates/next/files/components/ui/carousel.jsx +281 -0
  444. package/templates/next/files/components/ui/collapsible.jsx +208 -0
  445. package/templates/next/files/components/ui/combobox.jsx +608 -0
  446. package/templates/next/files/components/ui/command.jsx +577 -0
  447. package/templates/next/files/components/ui/context-menu.jsx +191 -0
  448. package/templates/next/files/components/ui/date-picker.jsx +360 -0
  449. package/templates/next/files/components/ui/distribution.jsx +117 -0
  450. package/templates/next/files/components/ui/feedback.jsx +143 -0
  451. package/templates/next/files/components/ui/field.jsx +115 -3
  452. package/templates/next/files/components/ui/file-input.jsx +234 -0
  453. package/templates/next/files/components/ui/icon.jsx +130 -8
  454. package/templates/next/files/components/ui/image.jsx +143 -0
  455. package/templates/next/files/components/ui/index.js +47 -2
  456. package/templates/next/files/components/ui/input-group.jsx +213 -0
  457. package/templates/next/files/components/ui/input-otp.jsx +170 -0
  458. package/templates/next/files/components/ui/item.jsx +206 -0
  459. package/templates/next/files/components/ui/menu.jsx +454 -82
  460. package/templates/next/files/components/ui/notice.jsx +126 -14
  461. package/templates/next/files/components/ui/pagination.jsx +156 -0
  462. package/templates/next/files/components/ui/popover.jsx +284 -0
  463. package/templates/next/files/components/ui/radio.jsx +193 -0
  464. package/templates/next/files/components/ui/rating.jsx +131 -0
  465. package/templates/next/files/components/ui/resizable.jsx +338 -0
  466. package/templates/next/files/components/ui/scroll-area.jsx +123 -0
  467. package/templates/next/files/components/ui/separator.jsx +119 -0
  468. package/templates/next/files/components/ui/sheet.jsx +96 -11
  469. package/templates/next/files/components/ui/slider.jsx +174 -0
  470. package/templates/next/files/components/ui/stat.jsx +574 -0
  471. package/templates/next/files/components/ui/steps.jsx +338 -0
  472. package/templates/next/files/components/ui/swatch.jsx +33 -0
  473. package/templates/next/files/components/ui/table.jsx +130 -0
  474. package/templates/next/files/components/ui/toast.jsx +440 -0
  475. package/templates/next/files/components/ui/toggle.jsx +195 -0
  476. package/templates/next/files/components/ui/tooltip.jsx +270 -0
  477. package/templates/next/files/lib/sample.js +4 -12
  478. package/templates/next/template.json +264 -8
@@ -0,0 +1,116 @@
1
+ "use client";
2
+
3
+ // SearchDialog over an assistant's history — the gallery's and the smoke
4
+ // test's surface. Not installed into apps: `makersclaw add search-dialog`
5
+ // lays index.js and search-dialog.jsx only. Press ⌘K (Ctrl+K) anywhere on
6
+ // the page, or the button. "Server search" answers through onSearch after
7
+ // a delay; turn on "Fail the server" to see the error.
8
+ import { useState } from "react";
9
+ import { Button, Field, Kbd, Select, Switch } from "../components/ui";
10
+ import { SearchDialog, SearchPanel } from "../components/blocks/search-dialog";
11
+
12
+ const LAST_OPENED = [
13
+ { id: "c1", kind: "chat", title: "Harbour St. lease renewal", snippet: "Counter at 4% over three years, and ask for the fit-out credit back.", date: "Today" },
14
+ { id: "c2", kind: "chat", title: "Supplier emails for the spring range", snippet: "Two follow-ups a week apart, then call the account manager.", date: "Today" },
15
+ ];
16
+
17
+ const RECENT = [
18
+ { id: "c3", kind: "chat", title: "Weekly cash position", snippet: "Runway is 14 months at the current burn; payroll moves to the 25th.", date: "Yesterday" },
19
+ { id: "c4", kind: "chat", title: "Why did March refunds spike", snippet: "Most refunds trace back to the courier switch in week two.", date: "Yesterday" },
20
+ { id: "c5", kind: "chat", title: "Draft the hiring post for a bookkeeper", snippet: "Part-time, remote, Xero experience; lead with the four-day week.", date: "Sep 18" },
21
+ { id: "c6", kind: "chat", title: "Compare three courier quotes", snippet: "Parcelwise is cheapest under 2 kg; Northline wins on next-day.", date: "Sep 15" },
22
+ { id: "c7", kind: "chat", title: "Board update outline", snippet: "Revenue, cash, the two hires, and the one risk: the lease.", date: "Sep 11" },
23
+ ];
24
+
25
+ const IMAGES = [
26
+ { id: "i1", kind: "image", title: "spring-range-lookbook.jpg", snippet: "Image", date: "Sep 19" },
27
+ { id: "i2", kind: "image", title: "shopfront-new-signage.png", snippet: "Image", date: "Sep 12" },
28
+ { id: "i3", kind: "image", title: "packaging-mockup-v3.png", snippet: "Image", date: "Sep 3" },
29
+ ];
30
+
31
+ const DOCS = [
32
+ { id: "d1", kind: "document", title: "Harbour St. lease — draft 2.pdf", snippet: "PDF", date: "Sep 20" },
33
+ { id: "d2", kind: "document", title: "Q3 cash flow.xlsx", snippet: "Spreadsheet", date: "Sep 17", icon: "chart" },
34
+ { id: "d3", kind: "document", title: "Courier contract — Parcelwise.docx", snippet: "Document", date: "Sep 9" },
35
+ { id: "d4", kind: "document", title: "Brand assets.zip", snippet: "Archive", date: "Aug 30", icon: "archive" },
36
+ ];
37
+
38
+ const PROJECTS = [
39
+ { id: "p1", kind: "project", title: "Spring range launch", snippet: "Project · 12 chats", date: "Sep 21" },
40
+ { id: "p2", kind: "project", title: "Second shop — Harbour St.", snippet: "Project · 7 chats", date: "Sep 20" },
41
+ { id: "p3", kind: "project", title: "Courier switch", snippet: "Project · 4 chats", date: "Aug 28" },
42
+ ];
43
+
44
+ const ALL = [...LAST_OPENED, ...RECENT, ...IMAGES, ...DOCS, ...PROJECTS];
45
+ const SECTIONS = [
46
+ { heading: "Last opened", results: LAST_OPENED },
47
+ { heading: "Recent chats", results: RECENT },
48
+ ];
49
+
50
+ const VARIANTS = [
51
+ { key: "local", label: "Your list, searched in the browser" },
52
+ { key: "server", label: "Server search (onSearch)" },
53
+ { key: "plain", label: "No sections, one kind" },
54
+ ];
55
+
56
+ const wait = (ms, signal) =>
57
+ new Promise((resolve, reject) => {
58
+ const t = setTimeout(resolve, ms);
59
+ signal?.addEventListener("abort", () => {
60
+ clearTimeout(t);
61
+ reject(new Error("aborted"));
62
+ });
63
+ });
64
+
65
+ export default function SearchDialogDemo() {
66
+ const [key, setKey] = useState("local");
67
+ const [open, setOpen] = useState(false);
68
+ const [fail, setFail] = useState(false);
69
+ const [picked, setPicked] = useState(null);
70
+
71
+ async function onSearch(query, { signal }) {
72
+ await wait(500, signal);
73
+ if (fail) throw new Error("The search service did not answer.");
74
+ const q = query.toLowerCase();
75
+ return ALL.filter((r) => `${r.title} ${r.snippet}`.toLowerCase().includes(q));
76
+ }
77
+
78
+ const props =
79
+ key === "server"
80
+ ? { sections: SECTIONS, onSearch, placeholder: "Search chats, images, documents and projects…" }
81
+ : key === "plain"
82
+ ? { results: PROJECTS, placeholder: "Search projects…", hint: "Type a project's name." }
83
+ : { results: ALL, sections: SECTIONS, placeholder: "Search chats, images, documents and projects…" };
84
+
85
+ const onSelect = (r) => setPicked(`${r.kind} · ${r.title}`);
86
+
87
+ return (
88
+ <div className="grid gap-6">
89
+ <div className="flex flex-wrap items-end gap-x-6 gap-y-2">
90
+ <Field id="search-variant" label="Variant" className="w-full sm:w-80">
91
+ <Select id="search-variant" value={key} onChange={(e) => setKey(e.target.value)} options={VARIANTS.map((v) => ({ value: v.key, label: v.label }))} />
92
+ </Field>
93
+ {key === "server" ? <Switch id="search-fail" label="Fail the server" checked={fail} onChange={(e) => setFail(e.target.checked)} /> : null}
94
+ </div>
95
+
96
+ <div>
97
+ <Button variant="secondary" icon="search" onClick={() => setOpen(true)} aria-keyshortcuts="Meta+K Control+K" align="start" className="w-full sm:w-72">
98
+ <span className="flex-1 text-left text-muted-foreground">Search…</span>
99
+ <span className="hidden md:inline-flex" aria-hidden="true">
100
+ <Kbd>⌘</Kbd>
101
+ <Kbd>K</Kbd>
102
+ </span>
103
+ </Button>
104
+ </div>
105
+
106
+ <SearchDialog key={key} open={open} onOpenChange={setOpen} hotkey="k" label="Global search" onSelect={onSelect} {...props} />
107
+
108
+ {/* The same box inline, so the page shows it without opening the dialog. */}
109
+ <SearchPanel key={`inline-${key}`} label="Search, inline" onSelect={onSelect} className="max-w-xl" {...props} />
110
+
111
+ <p className="min-h-5 text-xs text-muted-foreground" aria-live="polite">
112
+ {picked ? `Opened — ${picked}` : "Pick a result to see what onSelect receives."}
113
+ </p>
114
+ </div>
115
+ );
116
+ }
@@ -0,0 +1,3 @@
1
+ // The SearchDialog block — `makersclaw add search-dialog`. Fixed:
2
+ // compose it through its props (README.md beside this file).
3
+ export { SearchDialog, SearchPanel } from "./search-dialog";
@@ -0,0 +1,235 @@
1
+ "use client";
2
+
3
+ import { isValidElement, useEffect, useMemo, useRef, useState } from "react";
4
+ import { Command, IconButton, Image, Sheet, ToggleGroup, commandScore, cx } from "../../ui";
5
+
6
+ // SearchDialog — one ⌘K box over every kind of record: chats, documents,
7
+ // images, projects, people. Before anything is typed it shows your
8
+ // sections ("Last opened", "Recent"); while typing, the matches with the
9
+ // typed text marked, and kind chips (All, Chats, Images…) to narrow them.
10
+ // Built on the kit's Command (the list, keys and ARIA) inside the kit's
11
+ // Sheet. SearchPanel is the same box inline. See README.md beside this file.
12
+
13
+ const KINDS = {
14
+ chat: { label: "Chats", icon: "message-circle" },
15
+ document: { label: "Documents", icon: "file" },
16
+ image: { label: "Images", icon: "image" },
17
+ project: { label: "Projects", icon: "folder" },
18
+ person: { label: "People", icon: "user" },
19
+ company: { label: "Companies", icon: "building" },
20
+ task: { label: "Tasks", icon: "circle-check" },
21
+ page: { label: "Pages", icon: "file" },
22
+ };
23
+
24
+ const cap = (s) => String(s).charAt(0).toUpperCase() + String(s).slice(1);
25
+
26
+ function kindOf(kinds, value) {
27
+ return kinds.find((k) => k.value === value) ?? { value, label: KINDS[value]?.label ?? cap(value), icon: KINDS[value]?.icon ?? "file" };
28
+ }
29
+
30
+ /** The typed text marked inside `text`, once, ignoring case. */
31
+ function Marked({ text, needle }) {
32
+ const s = String(text ?? "");
33
+ const at = needle ? s.toLowerCase().indexOf(needle) : -1;
34
+ if (at < 0) return s;
35
+ return (
36
+ <>
37
+ {s.slice(0, at)}
38
+ <mark className="rounded-sm bg-transparent font-semibold text-foreground underline decoration-primary decoration-2 underline-offset-2">{s.slice(at, at + needle.length)}</mark>
39
+ {s.slice(at + needle.length)}
40
+ </>
41
+ );
42
+ }
43
+
44
+ function Thumb({ thumb, title }) {
45
+ if (isValidElement(thumb)) return <span className="flex size-8 shrink-0 overflow-hidden rounded-sm">{thumb}</span>;
46
+ return <Image src={thumb || undefined} alt="" ratio="square" rounded="sm" className="size-8 shrink-0" title={title} />;
47
+ }
48
+
49
+ // The best of a result's fields against the query, 0 when none match.
50
+ function score(r, q) {
51
+ return Math.max(commandScore(r.title, q), r.snippet ? commandScore(r.snippet, q) * 0.7 : 0, ...(r.keywords ?? []).map((k) => commandScore(k, q) * 0.9));
52
+ }
53
+
54
+ /** A server search: debounced, the older query aborted, failures kept. */
55
+ function useServerSearch(onSearch, query) {
56
+ const fn = useRef(onSearch);
57
+ fn.current = onSearch;
58
+ const on = Boolean(onSearch) && Boolean(query);
59
+ const [state, setState] = useState({ items: null, loading: false, error: null, query: "" });
60
+ useEffect(() => {
61
+ if (!on) return;
62
+ const ctl = new AbortController();
63
+ setState((s) => ({ ...s, loading: true, error: null }));
64
+ const timer = setTimeout(async () => {
65
+ try {
66
+ const items = await fn.current(query, { signal: ctl.signal });
67
+ if (!ctl.signal.aborted) setState({ items: items ?? [], loading: false, error: null, query });
68
+ } catch (error) {
69
+ if (!ctl.signal.aborted) setState((s) => ({ ...s, loading: false, error }));
70
+ }
71
+ }, 200);
72
+ return () => {
73
+ clearTimeout(timer);
74
+ ctl.abort();
75
+ };
76
+ }, [on, query]);
77
+ return state;
78
+ }
79
+
80
+ export function SearchPanel({
81
+ results = [],
82
+ sections,
83
+ kinds: kindsProp,
84
+ onSelect,
85
+ onSearch,
86
+ loading = false,
87
+ placeholder = "Search…",
88
+ label = "Search",
89
+ hint = "Type to search.",
90
+ showDate = true,
91
+ onClose,
92
+ autoFocus = false,
93
+ bare = false,
94
+ className,
95
+ }) {
96
+ const [query, setQuery] = useState("");
97
+ const [kind, setKind] = useState("all");
98
+ const needle = query.trim().toLowerCase();
99
+ const server = useServerSearch(onSearch, needle);
100
+
101
+ // The chips: the kinds given, or every kind the data holds, in order.
102
+ const kinds = useMemo(() => {
103
+ if (kindsProp) return kindsProp;
104
+ const seen = [];
105
+ for (const r of [...results, ...(sections ?? []).flatMap((s) => s.results ?? [])]) if (r?.kind && !seen.includes(r.kind)) seen.push(r.kind);
106
+ return seen.map((v) => kindOf([], v));
107
+ }, [kindsProp, results, sections]);
108
+
109
+ const pass = (r) => kind === "all" || r.kind === kind;
110
+
111
+ // `at` keeps values unique when one result sits in two sections.
112
+ const toItem = (r, group, at = "") => {
113
+ const k = kindOf(kinds, r.kind);
114
+ const meta = [r.snippet, showDate && needle ? r.date : null].filter(Boolean);
115
+ return {
116
+ value: `${at}${r.id}`,
117
+ label: <Marked text={r.title} needle={needle} />,
118
+ description: meta.length ? (
119
+ <>
120
+ {r.snippet ? <Marked text={r.snippet} needle={needle} /> : null}
121
+ {meta.length > 1 ? " · " : null}
122
+ {showDate && needle && r.date ? r.date : null}
123
+ </>
124
+ ) : undefined,
125
+ icon: r.kind === "image" || r.thumb ? <Thumb thumb={r.thumb} title={r.title} /> : r.icon ?? k.icon,
126
+ group,
127
+ result: r,
128
+ };
129
+ };
130
+
131
+ let items;
132
+ if (!needle) {
133
+ items = (sections ?? []).flatMap((s, n) => (s.results ?? []).filter(pass).map((r) => toItem(r, s.heading, `${n}:`)));
134
+ } else if (onSearch) {
135
+ items = (server.items ?? []).filter(pass).map((r) => toItem(r));
136
+ } else {
137
+ items = results
138
+ .map((r, i) => ({ r, i, s: pass(r) ? score(r, needle) : 0 }))
139
+ .filter((x) => x.s > 0)
140
+ .sort((a, b) => b.s - a.s || a.i - b.i)
141
+ .map((x) => toItem(x.r));
142
+ }
143
+
144
+ const busy = loading || (Boolean(onSearch) && Boolean(needle) && (server.loading || server.query !== needle) && !server.error);
145
+ const kindLabel = kind === "all" ? "" : ` in ${kindOf(kinds, kind).label.toLowerCase()}`;
146
+ const empty = server.error && needle
147
+ ? "Search failed. Check your connection and try again."
148
+ : needle
149
+ ? `No results for “${query.trim()}”${kindLabel}.`
150
+ : kind !== "all" && (sections ?? []).length
151
+ ? `Nothing recent${kindLabel}. Type to search.`
152
+ : hint;
153
+
154
+ const chips = kinds.length > 1 ? [{ value: "all", label: "All" }, ...kinds.map((k) => ({ value: k.value, label: k.label }))] : null;
155
+
156
+ return (
157
+ <div className={cx("flex min-w-0 flex-col overflow-hidden bg-popover text-popover-foreground", !bare && "rounded-lg border border-border", className)}>
158
+ <Command
159
+ bare
160
+ label={label}
161
+ placeholder={placeholder}
162
+ items={items}
163
+ filter={false}
164
+ query={query}
165
+ onQueryChange={setQuery}
166
+ loading={busy}
167
+ empty={empty}
168
+ autoFocus={autoFocus}
169
+ listClassName="max-h-[min(24rem,55dvh)]"
170
+ onSelect={(item) => onSelect?.(item.result)}
171
+ />
172
+ {chips || onClose ? (
173
+ <div className="flex items-center gap-2 border-t border-border px-2 py-1.5">
174
+ {chips ? (
175
+ <div className="min-w-0 flex-1 overflow-x-auto">
176
+ <ToggleGroup size="sm" aria-label="Show only" items={chips} value={kind} onChange={setKind} className="w-max" />
177
+ </div>
178
+ ) : (
179
+ <span className="flex-1" />
180
+ )}
181
+ {onClose ? <IconButton icon="x" label="Close search" size="sm" onClick={onClose} /> : null}
182
+ </div>
183
+ ) : null}
184
+ </div>
185
+ );
186
+ }
187
+
188
+ /** SearchPanel in the kit's Sheet: a dialog near the top of a wide window,
189
+ * a bottom sheet on a phone. `open` + `onOpenChange`, or uncontrolled
190
+ * with `defaultOpen`; `hotkey="k"` binds ⌘K / Ctrl+K to open and close
191
+ * it. Choosing a result closes it. */
192
+ export function SearchDialog({ open, defaultOpen = false, onOpenChange, hotkey, label = "Search", onSelect, className, ...panel }) {
193
+ const controlled = open !== undefined;
194
+ const [own, setOwn] = useState(defaultOpen);
195
+ const isOpen = controlled ? open : own;
196
+ const openRef = useRef(isOpen);
197
+ openRef.current = isOpen;
198
+ const changeRef = useRef(null);
199
+ changeRef.current = (next) => {
200
+ if (next === openRef.current) return;
201
+ openRef.current = next;
202
+ if (!controlled) setOwn(next);
203
+ onOpenChange?.(next);
204
+ };
205
+
206
+ useEffect(() => {
207
+ if (!hotkey) return;
208
+ function onKey(e) {
209
+ if (e.key?.toLowerCase() !== String(hotkey).toLowerCase() || !(e.metaKey || e.ctrlKey) || e.altKey || e.shiftKey) return;
210
+ e.preventDefault();
211
+ changeRef.current(!openRef.current);
212
+ }
213
+ window.addEventListener("keydown", onKey);
214
+ return () => window.removeEventListener("keydown", onKey);
215
+ }, [hotkey]);
216
+
217
+ return (
218
+ <Sheet bare label={label} open={isOpen} onClose={() => changeRef.current(false)} side="center" className={cx("sm:mt-[12dvh] sm:max-w-xl", className)}>
219
+ {/* Mounted only while open, so each opening starts empty on "All". */}
220
+ {isOpen ? (
221
+ <SearchPanel
222
+ bare
223
+ autoFocus
224
+ label={label}
225
+ onClose={() => changeRef.current(false)}
226
+ onSelect={(r) => {
227
+ changeRef.current(false);
228
+ onSelect?.(r);
229
+ }}
230
+ {...panel}
231
+ />
232
+ ) : null}
233
+ </Sheet>
234
+ );
235
+ }
@@ -0,0 +1,171 @@
1
+ # SettingsList
2
+
3
+ A card of settings, one row each: an icon, a label, a description, a few
4
+ meta lines, a badge, and the row's control. Every change saves on its own —
5
+ no Save button. A flipped switch or a new choice shows at once, a spinner
6
+ sits beside it while it saves, and when the save fails the old value comes
7
+ back with the reason and Try again, on that row only. `variant="matrix"`
8
+ is the notification grid: events down the side, channels across the top.
9
+
10
+ ```jsx
11
+ import { SettingsList } from "../components/blocks/settings-list"; // a Makersclaw app ("./blocks/settings-list" from components/)
12
+ import { SettingsList } from "@/components/makersclaw/blocks/settings-list"; // a shadcn project
13
+ ```
14
+
15
+ It is a client component: render it from a `"use client"` component, and
16
+ load the settings in the server surface (README §4).
17
+
18
+ ## The data
19
+
20
+ A row:
21
+
22
+ - `key` — unique in the list (required).
23
+ - `label` — what the setting is (required).
24
+ - `description` — a muted line under it.
25
+ - `icon` — a kit `Icon` name in a muted square; or `media`, any node (an
26
+ Avatar, a logo).
27
+ - `badge` — `"Current"` or `{ label, tone?, hue?, icon? }` beside the label.
28
+ `tone` for a status ("Recommended", success), `hue` 1–5 for a kind
29
+ ("Development").
30
+ - `value` — a line saying what is set now ("+44 7700 900 461", "Not set
31
+ up"); `valueTone: "set"` draws it in full weight with a check.
32
+ - `meta` — small lines under it: strings, or `{ icon, text }` ("globe
33
+ Lisbon", "clock Active now").
34
+ - `group` — rows with the same group sit under one heading, in the order
35
+ the groups first appear.
36
+ - `control` — one of:
37
+ - `{ type: "switch", value: true }` — saves through `onChange(row, bool)`.
38
+ - `{ type: "select", value, options: [{ value, label }] }` — saves
39
+ through `onChange(row, value)`.
40
+ - `{ type: "button", label, icon?, variant?, tone?, confirm? }` — runs
41
+ `onAction(row, "button")` (or `key` if given).
42
+ - `{ type: "actions", items: [{ key, label, icon?, tone?, confirm? }],
43
+ menu? }` — up to two buttons, or a "⋯" menu for three or more (or
44
+ `menu: true`); runs `onAction(row, item.key)`.
45
+ - `{ type: "remove", label?, confirm? }` — an × button (sign a device out,
46
+ disconnect); runs `onAction(row, "remove")`.
47
+ - none — a row that only says something.
48
+ `confirm` asks first, with the kit Confirm: `{ title, body?,
49
+ confirmLabel?, tone?, consequences?, requireText?, acknowledge? }`.
50
+ - `details` — a node, or `(row) => node`, that opens under the row from a
51
+ chevron button (the connected account, a copyable code). `defaultOpen`
52
+ starts it open.
53
+ - `disabled` — the control is shown and cannot be used.
54
+
55
+ The matrix (`variant="matrix"`) rows are events:
56
+
57
+ - `key`, `label`, `description`, `group` — as above.
58
+ - `values` — `{ email: true, push: false, sms: null }`, one per channel
59
+ key. `null` (or missing) means the event is not sent on that channel: a
60
+ dash, not a switch.
61
+ - `locked` — channel keys that cannot be turned off (`["email"]` for a
62
+ security alert): the switch shows, disabled, with a lock.
63
+
64
+ ## Props
65
+
66
+ - `rows` — the rows above. Keep them as the saved truth: when a save
67
+ succeeds, update the row (or let the server revalidate). Until the rows
68
+ change, the row shows the new value it saved.
69
+ - `onChange(row, value, channel?)` — save a switch or a select (in the
70
+ matrix, `channel` is the channel key). Return `{ ok: true }` or `{ ok:
71
+ false, error }`; a throw counts as failed. Without it, switches and
72
+ selects are shown and cannot be changed. In a Makersclaw app it is one
73
+ line over `saveSetting` (lib/actions.js):
74
+ `onChange={(row, value) => saveSetting({ source: "public.settings", key: row.key, value })}`.
75
+ - `onAction(row, actionKey)` — run a button, a menu item or a remove.
76
+ Return `{ ok }` like `onChange`. Remove the row from `rows` on success
77
+ when it is gone (a signed-out device).
78
+ - `variant` — `"list"` (default) or `"matrix"`.
79
+ - `channels` — the matrix's columns: `[{ key, label, icon? }]`.
80
+ - `title`, `description`, `icon` — the card's heading; `icon` in a muted
81
+ square before it.
82
+ - `badge` — a state beside the heading (`{ label: "On", tone: "success",
83
+ icon: "circle-check" }`).
84
+ - `actions` — nodes at the heading's end ("Add profile").
85
+ - `footer` — a node under the rows (a Notice with a tip).
86
+ - `loading` — skeleton rows.
87
+ - `error` — the settings could not be loaded: a Notice in place of the
88
+ rows; `onRetry` adds "Try again".
89
+ - `emptyTitle` (`"Nothing here yet"`) · `emptyBody` · `emptyAction` —
90
+ shown when `rows` is empty.
91
+ - `disabled` — every control shown and none usable.
92
+ - `failedText` — the reason shown when a save fails without an `error`.
93
+ - `className` — layout around it (width, margin). Never colour.
94
+
95
+ ## Example
96
+
97
+ ```jsx
98
+ // components/Preferences.jsx — client
99
+ "use client";
100
+ import { saveSetting } from "../lib/actions";
101
+ import { SettingsList } from "./blocks/settings-list";
102
+
103
+ export default function Preferences({ settings }) {
104
+ const rows = [
105
+ { key: "digest", icon: "mail", label: "Weekly digest", description: "Every Monday at 8:00.", control: { type: "switch", value: settings.digest === true } },
106
+ {
107
+ key: "currency",
108
+ icon: "dollar",
109
+ label: "Currency",
110
+ control: { type: "select", value: settings.currency ?? "usd", options: [{ value: "usd", label: "US dollar" }, { value: "eur", label: "Euro" }] },
111
+ },
112
+ ];
113
+ return (
114
+ <SettingsList
115
+ title="Preferences"
116
+ rows={rows}
117
+ onChange={(row, value) => saveSetting({ source: "public.settings", key: row.key, value })}
118
+ />
119
+ );
120
+ }
121
+ ```
122
+
123
+ Notifications per channel:
124
+
125
+ ```jsx
126
+ <SettingsList
127
+ variant="matrix"
128
+ title="Notifications"
129
+ channels={[{ key: "email", label: "Email", icon: "mail" }, { key: "push", label: "Push", icon: "smartphone" }]}
130
+ rows={[
131
+ { key: "mentions", group: "Conversations", label: "Mentions", values: { email: true, push: true } },
132
+ { key: "signin", group: "Security", label: "New sign-in", values: { email: true, push: false }, locked: ["email"] },
133
+ ]}
134
+ onChange={(row, on, channel) => saveSetting({ mode: "json", source: "public.members", column: "notify", id: me.id, key: `${row.key}.${channel}`, value: on })}
135
+ />
136
+ ```
137
+
138
+ Signed-in devices, each with sign-out:
139
+
140
+ ```jsx
141
+ <SettingsList
142
+ icon="shield-check"
143
+ title="Signed-in devices"
144
+ rows={sessions.map((s) => ({
145
+ key: s.id,
146
+ icon: s.kind === "phone" ? "smartphone" : "laptop",
147
+ label: s.device,
148
+ badge: s.current ? { label: "This device", tone: "info" } : null,
149
+ meta: [{ icon: "globe", text: s.place }, { icon: "clock", text: s.lastSeen }],
150
+ control: s.current ? null : { type: "remove", label: `Sign out ${s.device}`, confirm: { title: "Sign out this device?", confirmLabel: "Sign out" } },
151
+ }))}
152
+ onAction={(row) => deleteRow({ source: "public.sessions", id: row.key })}
153
+ />
154
+ ```
155
+
156
+ ## What it will not do
157
+
158
+ - Save several settings with one button: that is `record-form`.
159
+ - Open a setup flow: a button's `onAction` is yours — open your `Sheet`
160
+ from it and return `{ ok: true }`.
161
+ - Scroll the matrix sideways on a phone: under 768px each event's switches
162
+ stack under it, named by channel.
163
+
164
+ A settings screen it cannot be is your own component in `components/`,
165
+ built from the kit — not an edit to this block. Its files are fixed: `npm
166
+ run check` refuses a change, and `makersclaw add settings-list` restores
167
+ them.
168
+
169
+ ## Credits
170
+
171
+ Shapes from Creative Tim UI (https://github.com/creativetimofficial/ui, MIT); this is a rewrite on the Makersclaw kit.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "settings-list",
3
+ "title": "SettingsList",
4
+ "description": "A card of settings, one row each — icon, label, description, meta lines, a badge, and its control: a Switch, a Select, a Button, a remove button or a menu of actions, with optional details that open under the row. Every change saves on its own through an async callback; the row shows the new value at once, a spinner while it saves, and on failure the old value back with the reason and Try again. variant=\"matrix\" is the notification grid: events by group down the side, channels (email, push, SMS) across, a switch per cell, stacked on a phone.",
5
+ "useWhen": "An account or workspace settings screen where each setting applies the moment it is changed: preferences, two-step sign-in methods, signed-in devices, connected integrations, billing profiles, notification preferences per channel. Not for a form of fields saved together with one button (record-form).",
6
+ "tags": ["settings", "preferences", "toggle", "switch", "notifications", "channels", "matrix", "security", "sessions", "devices", "integrations", "two-factor", "billing", "account"],
7
+ "exports": ["SettingsList"],
8
+ "files": ["index.js", "settings-list.jsx", "settings-matrix.jsx", "row-state.jsx"],
9
+ "requires": []
10
+ }