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,198 @@
1
+ "use client";
2
+
3
+ // CommentBox — a minimal rich comment field (DocEditor in minimal mode)
4
+ // with @mentions and Cmd/Ctrl+Enter to post, and, when `comments` is
5
+ // given, the thread above it. CommentComposer is the field alone: record-
6
+ // notes uses it to add a note and to edit one in place.
7
+ //
8
+ // A post goes out through an async callback that answers { ok }. While it
9
+ // runs the box is locked and Post spins; a refusal (or a throw) keeps the
10
+ // draft and says why under the box. Only a post that came back ok clears.
11
+ import { useEffect, useId, useRef, useState } from "react";
12
+ import { Avatar, Button, KbdGroup, cx } from "../../ui";
13
+ import { DocEditor, isDocEmpty, useDocEditor } from "../doc-editor";
14
+ import { CommentBody } from "./comment-body";
15
+ import { CommentTime } from "./comment-time";
16
+
17
+ const nameOf = (author) => (typeof author === "string" ? author : author?.name) || "Someone";
18
+ const srcOf = (author) => (typeof author === "object" && author ? author.src : undefined);
19
+
20
+ /** ⌘ on a Mac, Ctrl elsewhere — known only in the browser. */
21
+ function useModKey() {
22
+ const [mac, setMac] = useState(null);
23
+ useEffect(() => {
24
+ const p = navigator.userAgentData?.platform || navigator.platform || "";
25
+ setMac(/mac|iphone|ipad/i.test(p));
26
+ }, []);
27
+ return mac === null ? null : mac ? "⌘" : "Ctrl";
28
+ }
29
+
30
+ export function CommentComposer({
31
+ onSubmit,
32
+ author,
33
+ mentions,
34
+ defaultValue,
35
+ placeholder = "Write a comment…",
36
+ submitLabel = "Post",
37
+ submitIcon = "send",
38
+ busyLabel,
39
+ failedText = "Couldn't post. Your comment is still here; try again.",
40
+ onCancel,
41
+ cancelLabel = "Cancel",
42
+ label = "Comment",
43
+ autoFocus = false,
44
+ disabled = false,
45
+ clearOnSubmit = true,
46
+ className,
47
+ }) {
48
+ const box = useDocEditor();
49
+ const [draft, setDraft] = useState(defaultValue ?? null);
50
+ const [busy, setBusy] = useState(false);
51
+ const [error, setError] = useState(null);
52
+ const running = useRef(false);
53
+ const mod = useModKey();
54
+ const errorId = useId();
55
+ const empty = !draft || isDocEmpty(draft);
56
+
57
+ async function submit(doc) {
58
+ if (running.current || disabled || !doc || isDocEmpty(doc)) return;
59
+ running.current = true;
60
+ setBusy(true);
61
+ setError(null);
62
+ let res;
63
+ try {
64
+ res = await onSubmit?.(doc);
65
+ } catch (e) {
66
+ res = { ok: false, error: e?.message };
67
+ }
68
+ running.current = false;
69
+ setBusy(false);
70
+ if (res && res.ok === false) {
71
+ setError(res.error || failedText);
72
+ box.current?.focus();
73
+ return;
74
+ }
75
+ if (clearOnSubmit) {
76
+ box.current?.clear();
77
+ setDraft(null);
78
+ }
79
+ box.current?.focus();
80
+ }
81
+
82
+ return (
83
+ <div className={cx("flex items-start gap-3", className)}>
84
+ {author ? (
85
+ <div className="mt-1 hidden shrink-0 sm:block">
86
+ <Avatar name={nameOf(author)} src={srcOf(author)} size="sm" />
87
+ </div>
88
+ ) : null}
89
+ <div className="min-w-0 flex-1">
90
+ <div
91
+ className={cx(
92
+ "rounded-md border bg-background px-3 py-2 focus-within:ring-2 focus-within:ring-ring",
93
+ error ? "border-destructive" : "border-input",
94
+ (busy || disabled) && "opacity-60",
95
+ )}
96
+ aria-describedby={error ? errorId : undefined}
97
+ >
98
+ <DocEditor
99
+ minimal
100
+ editorRef={box}
101
+ defaultValue={defaultValue}
102
+ onChange={(d) => {
103
+ setDraft(d);
104
+ if (error) setError(null);
105
+ }}
106
+ onSubmit={submit}
107
+ mentions={mentions}
108
+ placeholder={placeholder}
109
+ label={label}
110
+ autoFocus={autoFocus}
111
+ editable={!busy && !disabled}
112
+ />
113
+ </div>
114
+ {error ? (
115
+ <p id={errorId} role="alert" className="mt-1.5 text-xs text-destructive">
116
+ {error}
117
+ </p>
118
+ ) : null}
119
+ <div className="mt-2 flex flex-wrap items-center justify-end gap-2">
120
+ {mod ? (
121
+ <span className="me-auto hidden items-center gap-1.5 text-xs text-muted-foreground sm:inline-flex">
122
+ <KbdGroup keys={[mod, "Enter"]} />
123
+ <span>to {submitLabel.toLowerCase()}</span>
124
+ </span>
125
+ ) : null}
126
+ {onCancel ? (
127
+ <Button variant="quiet" onClick={onCancel} disabled={busy}>
128
+ {cancelLabel}
129
+ </Button>
130
+ ) : null}
131
+ <Button variant="primary" icon={submitIcon || undefined} loading={busy} disabled={empty || disabled} onClick={() => submit(box.current?.getDoc() ?? draft)}>
132
+ {busy && busyLabel ? busyLabel : submitLabel}
133
+ </Button>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ );
138
+ }
139
+
140
+ /** One comment in the thread: avatar, name, time, the body. */
141
+ function CommentItem({ comment }) {
142
+ const name = nameOf(comment.author);
143
+ return (
144
+ <li className="flex gap-3">
145
+ <Avatar name={name} src={srcOf(comment.author)} size="sm" className="shrink-0" />
146
+ <div className="min-w-0 flex-1">
147
+ <p className="flex flex-wrap items-baseline gap-x-2 text-sm">
148
+ <span className="font-medium">{name}</span>
149
+ <CommentTime date={comment.createdAt} />
150
+ {comment.edited ? <span className="text-xs text-muted-foreground">(edited)</span> : null}
151
+ </p>
152
+ <CommentBody doc={comment.body} className="mt-0.5 text-foreground" />
153
+ </div>
154
+ </li>
155
+ );
156
+ }
157
+
158
+ export function CommentBox({
159
+ onPost,
160
+ comments,
161
+ author,
162
+ mentions,
163
+ placeholder = "Write a comment…",
164
+ postLabel = "Post",
165
+ label = "Comment",
166
+ emptyText = "No comments yet.",
167
+ threadLabel = "Comments",
168
+ autoFocus = false,
169
+ disabled = false,
170
+ className,
171
+ }) {
172
+ const list = Array.isArray(comments) ? comments : null;
173
+ return (
174
+ <div className={cx("grid gap-4", className)}>
175
+ {list ? (
176
+ list.length ? (
177
+ <ul aria-label={threadLabel} className="grid gap-4">
178
+ {list.map((c, i) => (
179
+ <CommentItem key={c.id ?? i} comment={c} />
180
+ ))}
181
+ </ul>
182
+ ) : (
183
+ <p className="text-sm text-muted-foreground">{emptyText}</p>
184
+ )
185
+ ) : null}
186
+ <CommentComposer
187
+ onSubmit={onPost}
188
+ author={author}
189
+ mentions={mentions}
190
+ placeholder={placeholder}
191
+ submitLabel={postLabel}
192
+ label={label}
193
+ autoFocus={autoFocus}
194
+ disabled={disabled}
195
+ />
196
+ </div>
197
+ );
198
+ }
@@ -0,0 +1,77 @@
1
+ "use client";
2
+
3
+ // CommentTime — when a comment was written, as a <time>.
4
+ //
5
+ // Relative words ("5 min ago") need the clock, and the server's clock and
6
+ // time zone are not the reader's. So the server and the first paint show
7
+ // the absolute date; after mount it turns relative, and one shared minute
8
+ // tick (not a timer per comment) keeps every label current. The full date
9
+ // is always in the title.
10
+ import { useEffect, useState } from "react";
11
+ import { cx } from "../../ui";
12
+
13
+ const listeners = new Set();
14
+ let timer = null;
15
+ function subscribe(fn) {
16
+ listeners.add(fn);
17
+ if (!timer) timer = setInterval(() => listeners.forEach((l) => l(Date.now())), 60_000);
18
+ return () => {
19
+ listeners.delete(fn);
20
+ if (!listeners.size && timer) {
21
+ clearInterval(timer);
22
+ timer = null;
23
+ }
24
+ };
25
+ }
26
+
27
+ /** Date.now(), refreshed each minute — null until mounted. */
28
+ export function useNow() {
29
+ const [now, setNow] = useState(null);
30
+ useEffect(() => {
31
+ setNow(Date.now());
32
+ return subscribe(setNow);
33
+ }, []);
34
+ return now;
35
+ }
36
+
37
+ export const toDate = (v) => {
38
+ if (v === undefined || v === null || v === "") return null;
39
+ const d = v instanceof Date ? v : new Date(v);
40
+ return Number.isNaN(d.getTime()) ? null : d;
41
+ };
42
+
43
+ const fmt = (opts) => new Intl.DateTimeFormat(undefined, opts);
44
+ const TIME = { hour: "numeric", minute: "2-digit" };
45
+ const startOfDay = (ms) => {
46
+ const d = new Date(ms);
47
+ d.setHours(0, 0, 0, 0);
48
+ return d.getTime();
49
+ };
50
+
51
+ /** "12 Sep 2026, 14:05" — the title, and the label before mount. */
52
+ export function fullDate(d) {
53
+ return fmt({ day: "numeric", month: "short", year: "numeric", ...TIME }).format(d);
54
+ }
55
+
56
+ /** "just now" · "5 min ago" · "3 h ago" (today) · "Yesterday, 14:05" · "12 Sep, 14:05" · "12 Sep 2025". */
57
+ export function relativeDate(d, now) {
58
+ const diff = now - d.getTime();
59
+ if (diff < 45_000 && diff > -60_000) return "just now";
60
+ const today = startOfDay(now);
61
+ if (diff > 0 && diff < 60 * 60_000) return `${Math.round(diff / 60_000)} min ago`;
62
+ if (d.getTime() >= today && diff > 0) return `${Math.floor(diff / 3_600_000)} h ago`;
63
+ if (d.getTime() >= today - 86_400_000 && d.getTime() < today) return `Yesterday, ${fmt(TIME).format(d)}`;
64
+ if (new Date(d).getFullYear() === new Date(now).getFullYear()) return fmt({ day: "numeric", month: "short", ...TIME }).format(d);
65
+ return fmt({ day: "numeric", month: "short", year: "numeric" }).format(d);
66
+ }
67
+
68
+ export function CommentTime({ date, className }) {
69
+ const now = useNow();
70
+ const d = toDate(date);
71
+ if (!d) return null;
72
+ return (
73
+ <time dateTime={d.toISOString()} title={fullDate(d)} suppressHydrationWarning className={cx("text-xs text-muted-foreground", className)}>
74
+ {now === null ? fullDate(d) : relativeDate(d, now)}
75
+ </time>
76
+ );
77
+ }
@@ -0,0 +1,141 @@
1
+ "use client";
2
+
3
+ // CommentBox three ways — the gallery's and the smoke test's surface. Not
4
+ // installed into apps. Posts are pretend: a switch makes them fail.
5
+ // Thread comments on a design review, the box under them.
6
+ // Field alone no thread: a reply field that reports what it posted.
7
+ // Empty a thread with nothing in it yet, and a locked box.
8
+ import { useState } from "react";
9
+ import { Card, Switch, TabPanel, Tabs } from "../components/ui";
10
+ import { CommentBox } from "../components/blocks/comment-box";
11
+ import { docToText } from "../components/blocks/doc-editor";
12
+
13
+ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
14
+ const ago = (min) => new Date(Date.now() - min * 60_000).toISOString();
15
+
16
+ const TEAM = [
17
+ { id: "u-priya", label: "Priya Raman", description: "Design" },
18
+ { id: "u-tomas", label: "Tomás Ortega", description: "Engineering" },
19
+ { id: "u-june", label: "June Okafor", description: "Growth" },
20
+ { id: "u-lena", label: "Lena Fischer", description: "Sales" },
21
+ ];
22
+ const findPeople = async (query) => {
23
+ const q = query.toLowerCase();
24
+ return TEAM.filter((p) => p.label.toLowerCase().includes(q));
25
+ };
26
+ const ME = { id: "u-june", name: "June Okafor" };
27
+
28
+ const t = (text, styles = {}) => ({ type: "text", text, styles });
29
+ const at = (id) => ({ type: "mention", props: { id, label: TEAM.find((p) => p.id === id).label } });
30
+
31
+ const REVIEW_THREAD = [
32
+ {
33
+ id: "c1",
34
+ author: { id: "u-priya", name: "Priya Raman" },
35
+ createdAt: ago(60 * 26),
36
+ body: [
37
+ { type: "paragraph", content: [t("New pricing page is up for review. Two open questions:")] },
38
+ { type: "numberedListItem", content: [t("Do we show the "), t("annual", { bold: true }), t(" price first?")] },
39
+ { type: "numberedListItem", content: [t("Is the comparison table too long on a phone?")] },
40
+ ],
41
+ },
42
+ {
43
+ id: "c2",
44
+ author: { id: "u-tomas", name: "Tomás Ortega" },
45
+ createdAt: ago(95),
46
+ edited: true,
47
+ body: [
48
+ { type: "paragraph", content: [at("u-priya"), t(" annual first, monthly as the toggle. The table collapses to cards under 640px already.")] },
49
+ ],
50
+ },
51
+ {
52
+ id: "c3",
53
+ author: { id: "u-lena", name: "Lena Fischer" },
54
+ createdAt: ago(12),
55
+ body: [{ type: "paragraph", content: [t("From sales: people ask about "), t("seats", { italic: true }), t(" before price. Can the seat line go above the fold?")] }],
56
+ },
57
+ ];
58
+
59
+ function ThreadDemo() {
60
+ const [comments, setComments] = useState(REVIEW_THREAD);
61
+ const [failing, setFailing] = useState(false);
62
+ const post = async (doc) => {
63
+ await wait(700);
64
+ if (failing) return { ok: false, error: "The server is not answering. Your comment is still here; try again." };
65
+ setComments((c) => [...c, { id: `c${c.length + 1}`, author: ME, body: doc, createdAt: new Date().toISOString() }]);
66
+ return { ok: true };
67
+ };
68
+ return (
69
+ <Card
70
+ title="Pricing page review"
71
+ description="Type @ to mention someone. ⌘/Ctrl+Enter posts."
72
+ actions={<Switch id="cb-fail" label="Posts fail" checked={failing} onChange={(e) => setFailing(e.target.checked)} />}
73
+ className="max-w-2xl"
74
+ >
75
+ <CommentBox comments={comments} onPost={post} author={ME} mentions={findPeople} />
76
+ </Card>
77
+ );
78
+ }
79
+
80
+ function FieldDemo() {
81
+ const [last, setLast] = useState(null);
82
+ const post = async (doc) => {
83
+ await wait(400);
84
+ setLast(docToText(doc));
85
+ return { ok: true };
86
+ };
87
+ return (
88
+ <Card title="Reply" description="The field alone: no thread above it." className="max-w-2xl">
89
+ <CommentBox onPost={post} mentions={findPeople} postLabel="Reply" placeholder="Reply to Lena…" label="Reply" />
90
+ {last !== null ? (
91
+ <p className="mt-3 whitespace-pre-wrap break-words rounded-md bg-muted p-3 text-sm text-muted-foreground">Posted as text: {last}</p>
92
+ ) : null}
93
+ </Card>
94
+ );
95
+ }
96
+
97
+ function EmptyDemo() {
98
+ const [comments, setComments] = useState([]);
99
+ const [locked, setLocked] = useState(false);
100
+ const post = async (doc) => {
101
+ await wait(400);
102
+ setComments((c) => [...c, { id: `e${c.length + 1}`, author: ME, body: doc, createdAt: new Date().toISOString() }]);
103
+ return { ok: true };
104
+ };
105
+ return (
106
+ <Card
107
+ title="Q4 onboarding email"
108
+ actions={<Switch id="cb-lock" label="Locked" checked={locked} onChange={(e) => setLocked(e.target.checked)} />}
109
+ className="max-w-2xl"
110
+ >
111
+ <CommentBox comments={comments} onPost={post} author={ME} mentions={findPeople} disabled={locked} emptyText="No comments yet. Start the conversation." />
112
+ </Card>
113
+ );
114
+ }
115
+
116
+ export default function CommentBoxDemo() {
117
+ const [tab, setTab] = useState("thread");
118
+ return (
119
+ <div className="grid gap-4">
120
+ <Tabs
121
+ aria-label="CommentBox variants"
122
+ value={tab}
123
+ onChange={setTab}
124
+ tabs={[
125
+ { key: "thread", label: "Thread" },
126
+ { key: "field", label: "Field alone" },
127
+ { key: "empty", label: "Empty" },
128
+ ]}
129
+ />
130
+ <TabPanel tab="thread" value={tab}>
131
+ <ThreadDemo />
132
+ </TabPanel>
133
+ <TabPanel tab="field" value={tab}>
134
+ <FieldDemo />
135
+ </TabPanel>
136
+ <TabPanel tab="empty" value={tab}>
137
+ <EmptyDemo />
138
+ </TabPanel>
139
+ </div>
140
+ );
141
+ }
@@ -0,0 +1,8 @@
1
+ // The CommentBox block — `makersclaw add comment-box`. Fixed: compose it
2
+ // through its props (README.md beside this file). CommentComposer is the
3
+ // field alone, CommentBody draws a posted doc, CommentTime a timestamp;
4
+ // record-notes is built from them. The editor is doc-editor's, in its
5
+ // minimal mode.
6
+ export { CommentBox, CommentComposer } from "./comment-box";
7
+ export { CommentBody } from "./comment-body";
8
+ export { CommentTime } from "./comment-time";
@@ -0,0 +1,152 @@
1
+ # Contact Section
2
+
3
+ A public "contact us" section. It holds a form, the ways to reach you, or
4
+ both. The form asks for a name, an email and a message, and optionally a
5
+ phone, a company, a subject, a topic (chips or radios) and a consent box.
6
+ The ways to reach you are details (email, phone, address, hours) and
7
+ offices.
8
+
9
+ Three layouts:
10
+ - **form** — the form alone, with the details on one line above it, or
11
+ a picture beside or behind it;
12
+ - **split** — the form beside an info panel (plain, or filled with the
13
+ primary colour);
14
+ - **cards** — the details as icon cards, alone, above the form or beside
15
+ it.
16
+
17
+ The form checks itself as it is sent. A missing or malformed field gets
18
+ its message under it, and the focus moves to the first one. It then
19
+ calls `onSubmit(values)`, which is async and returns `{ ok }`. While it
20
+ runs, the button spins and a second press does nothing. `{ ok: false,
21
+ error }` (or a throw) shows the error above the button and keeps
22
+ everything typed. `{ ok: true }` replaces the form with a "Message
23
+ sent" notice and a "Send another" button. It is a full-width section: it
24
+ pads itself and centres its content.
25
+
26
+ ```jsx
27
+ import { ContactSection } from "../components/blocks/contact-section"; // a Makersclaw app ("./blocks/contact-section" from components/)
28
+ import { ContactSection } from "@/components/makersclaw/blocks/contact-section"; // a shadcn project
29
+ ```
30
+
31
+ It is a client component: render it from a `"use client"` component.
32
+
33
+ ## The data
34
+
35
+ `details` is the ways to reach you:
36
+
37
+ ```js
38
+ {
39
+ icon: "mail", // a name from the kit's Icon
40
+ label: "Email", // what it is ("Call sales" on a card)
41
+ value: "hello@fieldline.io", // what is shown
42
+ href?: "mailto:hello@fieldline.io", // a link: mailto:, tel:, a map, a page
43
+ description?: "A person replies within a working day.", // a card's and a panel row's second line
44
+ }
45
+ ```
46
+
47
+ `offices` (split only): `[{ name: "Lisbon", lines: ["Rua da Prata 88", …], icon? }]`.
48
+
49
+ `onSubmit` receives the values, trimmed:
50
+
51
+ ```js
52
+ {
53
+ firstName, lastName, // or `name` with nameFields="one"
54
+ email, message,
55
+ phone?, company?, subject?, // the ones named in `fields`
56
+ topic?, // the chosen option's value, "" for none
57
+ consent?, // true: it was required and ticked
58
+ }
59
+ ```
60
+
61
+ ## Props
62
+
63
+ - `onSubmit(values)` — async, returns `{ ok: true }` or `{ ok: false,
64
+ error? }`. Without it there is no form (a cards-only or panel-only
65
+ section).
66
+ - `layout` — `split` (default) · `form` · `cards`.
67
+ - `kicker`, `title`, `description` — the header. `title` defaults to
68
+ "Get in touch".
69
+ - `align` — the header, and the cards' content: `center` (default for
70
+ form and cards) · `start` (default for split).
71
+ - `details` — the ways to reach you, as above. A panel's rows in
72
+ `split`, one line above the form in `form`, the cards in `cards`.
73
+ - `offices` — `split`: the offices, under the details in the panel.
74
+ - `panel` — `split`: `plain` (default, a quiet bordered box) · `filled`
75
+ (the primary colour).
76
+ - `panelTitle`, `panelBody` — `split`: the panel's heading and a line
77
+ under it.
78
+ - `cardsPosition` — `cards` with a form: `above` (default) · `beside`
79
+ (the cards stacked in a column beside the form from `lg` up).
80
+ - `cardColumns` — `cards`: `1` · `2` · `3` · `4`. Default the number of
81
+ cards, at most 3.
82
+ - `image`, `imageAlt` — `form`: a picture. `imageAlt` defaults to ""
83
+ (decoration).
84
+ - `imagePosition` — `side` (default: beside the form from `md` up,
85
+ hidden on a phone) · `background` (behind the form card, under a veil
86
+ of the background colour).
87
+ - `nameFields` — `split` (default: first name, required, and last name)
88
+ · `one` (a single "Name").
89
+ - `fields` — the optional fields to add: any of `"phone"`, `"company"`,
90
+ `"subject"`. Phone and company are marked optional; subject is not
91
+ required either.
92
+ - `topics` — `{ label?, options, style?, required? }`: `options` are
93
+ strings or `{ value, label }`; `style` `chips` (default: pressable
94
+ chips above the name) · `radio` (a radio row after the email).
95
+ - `consent` — the label of a consent checkbox (a string or a node with
96
+ your policy link). When given, it must be ticked to send.
97
+ - `messageLabel` — default "Message". `messageRows` — default `5`.
98
+ - `submitLabel` — default "Send message".
99
+ - `sent` — `{ title?, body? }` for the sent notice.
100
+ - `defaultValues` — values to start with (a signed-in visitor's name and
101
+ email).
102
+ - `labels` — override field labels: `{ firstName, lastName, name, email,
103
+ phone, company, subject }`.
104
+ - `label` — what a screen reader calls the section. Default the title.
105
+ - `className` — the section's spacing and width. Never colour.
106
+
107
+ ## Example
108
+
109
+ ```jsx
110
+ // components/Contact.jsx
111
+ "use client";
112
+ import { ContactSection } from "./blocks/contact-section";
113
+ import { sendContactMessage } from "../lib/actions"; // your server action
114
+
115
+ export default function Contact() {
116
+ return (
117
+ <ContactSection
118
+ title="Talk to a person"
119
+ description="We reply within one working day."
120
+ details={[
121
+ { icon: "mail", label: "Email", value: "hello@fieldline.io", href: "mailto:hello@fieldline.io" },
122
+ { icon: "phone", label: "Phone", value: "+44 20 7946 0321", href: "tel:+442079460321" },
123
+ { icon: "clock", label: "Hours", value: "Mon–Fri, 9:00–18:00 GMT" },
124
+ ]}
125
+ topics={{ options: ["Sales", "Support", "Partnerships"], required: true }}
126
+ consent="I agree to the privacy policy."
127
+ onSubmit={async (values) => {
128
+ const res = await sendContactMessage(values);
129
+ return res.ok ? { ok: true } : { ok: false, error: res.error };
130
+ }}
131
+ />
132
+ );
133
+ }
134
+ ```
135
+
136
+ ## What it will not do
137
+
138
+ - Send anything: `onSubmit` is yours (save a row, email the team).
139
+ - Stop spam: add a captcha or a honeypot in your own `onSubmit` path.
140
+ - Upload files, or take a card number.
141
+ - Draw a map: link the address (`href`) to one.
142
+
143
+ A section it cannot be is your own component in `components/`, built
144
+ from the kit — not an edit to this block. Its files are fixed: `npm run
145
+ check` refuses a change, and `makersclaw add contact-section` restores
146
+ them.
147
+
148
+ ## Credits
149
+
150
+ Layouts ported from Creative Tim UI's contact-section blocks
151
+ (https://github.com/creativetimofficial/ui, MIT), rewritten on the
152
+ Makersclaw kit.
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "contact-section",
3
+ "title": "Contact Section",
4
+ "description": "A public \"contact us\" section: a form (name, email, message; optional phone, company, subject, a topic as chips or radios, a consent box) and/or the ways to reach you (email, phone, address, hours, offices). The form alone, beside an info panel (plain or filled), or with info cards above or beside it; an optional picture beside or behind the form. Validates in place, submits through an async onSubmit that returns { ok }, and shows the failure or a sent state.",
5
+ "useWhen": "The contact page or contact section of a public site: sales enquiries, support requests, a studio's \"start a project\" form. Not for a signed-in user's support inbox or ticket thread, or a general-purpose record form (use a form of your own from the kit).",
6
+ "tags": ["contact", "contact us", "form", "enquiry", "support", "get in touch", "email", "phone", "address", "offices", "marketing", "landing page", "lead"],
7
+ "exports": ["ContactSection"],
8
+ "files": ["index.js", "contact-section.jsx"],
9
+ "requires": [],
10
+ "frame": "bleed"
11
+ }