makersclaw 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (475) hide show
  1. package/THIRD-PARTY-NOTICES.md +180 -0
  2. package/package.json +3 -2
  3. package/r/annotate.json +62 -0
  4. package/r/approval-request.json +52 -0
  5. package/r/audio-player.json +74 -0
  6. package/r/auth-form.json +55 -0
  7. package/r/board.json +10 -6
  8. package/r/calendar-view.json +105 -0
  9. package/r/cart.json +62 -0
  10. package/r/chart.json +83 -0
  11. package/r/chat.json +95 -0
  12. package/r/code-editor.json +94 -0
  13. package/r/comment-box.json +64 -0
  14. package/r/contact-section.json +53 -0
  15. package/r/core.json +205 -8
  16. package/r/csv-import.json +63 -0
  17. package/r/data-table.json +69 -0
  18. package/r/diagram.json +74 -0
  19. package/r/doc-editor.json +82 -0
  20. package/r/doc-page.json +61 -0
  21. package/r/email-render.json +73 -0
  22. package/r/faq.json +50 -0
  23. package/r/file-upload.json +54 -0
  24. package/r/flow-canvas.json +93 -0
  25. package/r/footer.json +52 -0
  26. package/r/gantt.json +70 -0
  27. package/r/job-panel.json +12 -7
  28. package/r/json-editor.json +66 -0
  29. package/r/map.json +89 -0
  30. package/r/menubar.json +52 -0
  31. package/r/mind-map.json +67 -0
  32. package/r/navigation-menu.json +52 -0
  33. package/r/order-detail.json +54 -0
  34. package/r/org-chart.json +66 -0
  35. package/r/page-builder.json +105 -0
  36. package/r/payment-methods.json +51 -0
  37. package/r/pdf-document.json +79 -0
  38. package/r/pdf-viewer.json +88 -0
  39. package/r/product-detail.json +76 -0
  40. package/r/product-grid.json +65 -0
  41. package/r/record-form.json +67 -0
  42. package/r/record-notes.json +55 -0
  43. package/r/registry.json +3411 -29
  44. package/r/search-dialog.json +51 -0
  45. package/r/settings-list.json +66 -0
  46. package/r/setup-checklist.json +51 -0
  47. package/r/share-dialog.json +52 -0
  48. package/r/sidebar.json +69 -0
  49. package/r/signature-pad.json +72 -0
  50. package/r/sketch-canvas.json +99 -0
  51. package/r/spreadsheet.json +90 -0
  52. package/r/stat-cards.json +66 -0
  53. package/r/task-list.json +63 -0
  54. package/r/task-model.json +98 -0
  55. package/r/testimonials.json +52 -0
  56. package/r/transaction-list.json +53 -0
  57. package/r/whiteboard.json +66 -0
  58. package/registry/blocks/annotate/README.md +179 -0
  59. package/registry/blocks/annotate/annotate-data.js +250 -0
  60. package/registry/blocks/annotate/annotate.jsx +646 -0
  61. package/registry/blocks/annotate/block.json +10 -0
  62. package/registry/blocks/annotate/demo.jsx +135 -0
  63. package/registry/blocks/annotate/index.js +15 -0
  64. package/registry/blocks/approval-request/README.md +116 -0
  65. package/registry/blocks/approval-request/approval-request.jsx +386 -0
  66. package/registry/blocks/approval-request/block.json +10 -0
  67. package/registry/blocks/approval-request/demo.jsx +127 -0
  68. package/registry/blocks/approval-request/index.js +4 -0
  69. package/registry/blocks/audio-player/README.md +167 -0
  70. package/registry/blocks/audio-player/audio-player.jsx +623 -0
  71. package/registry/blocks/audio-player/block.json +14 -0
  72. package/registry/blocks/audio-player/colors.js +109 -0
  73. package/registry/blocks/audio-player/demo.jsx +209 -0
  74. package/registry/blocks/audio-player/index.js +6 -0
  75. package/registry/blocks/audio-player/time.js +67 -0
  76. package/registry/blocks/audio-player/wavesurfer.js +9 -0
  77. package/registry/blocks/auth-form/README.md +126 -0
  78. package/registry/blocks/auth-form/auth-form.jsx +568 -0
  79. package/registry/blocks/auth-form/block.json +10 -0
  80. package/registry/blocks/auth-form/demo.jsx +131 -0
  81. package/registry/blocks/auth-form/index.js +3 -0
  82. package/registry/blocks/board/README.md +55 -5
  83. package/registry/blocks/board/block.json +2 -2
  84. package/registry/blocks/board/board.jsx +230 -86
  85. package/registry/blocks/board/demo.jsx +103 -24
  86. package/registry/blocks/calendar-view/README.md +180 -0
  87. package/registry/blocks/calendar-view/agenda.jsx +147 -0
  88. package/registry/blocks/calendar-view/block.json +76 -0
  89. package/registry/blocks/calendar-view/calendar-model.js +442 -0
  90. package/registry/blocks/calendar-view/calendar.jsx +627 -0
  91. package/registry/blocks/calendar-view/demo.jsx +195 -0
  92. package/registry/blocks/calendar-view/draft.jsx +49 -0
  93. package/registry/blocks/calendar-view/index.js +39 -0
  94. package/registry/blocks/calendar-view/month.jsx +346 -0
  95. package/registry/blocks/calendar-view/paint.js +69 -0
  96. package/registry/blocks/calendar-view/time-grid.jsx +527 -0
  97. package/registry/blocks/calendar-view/tray.jsx +87 -0
  98. package/registry/blocks/cart/README.md +146 -0
  99. package/registry/blocks/cart/block.json +10 -0
  100. package/registry/blocks/cart/cart.jsx +597 -0
  101. package/registry/blocks/cart/demo.jsx +98 -0
  102. package/registry/blocks/cart/index.js +4 -0
  103. package/registry/blocks/cart/money.js +28 -0
  104. package/registry/blocks/chart/README.md +316 -0
  105. package/registry/blocks/chart/block.json +10 -0
  106. package/registry/blocks/chart/cartesian.jsx +642 -0
  107. package/registry/blocks/chart/core.jsx +262 -0
  108. package/registry/blocks/chart/demo.jsx +357 -0
  109. package/registry/blocks/chart/heatmap.jsx +336 -0
  110. package/registry/blocks/chart/index.js +8 -0
  111. package/registry/blocks/chart/pie.jsx +245 -0
  112. package/registry/blocks/chart/sparkline.jsx +88 -0
  113. package/registry/blocks/chat/README.md +273 -0
  114. package/registry/blocks/chat/attachment.jsx +95 -0
  115. package/registry/blocks/chat/block.json +10 -0
  116. package/registry/blocks/chat/chat.jsx +132 -0
  117. package/registry/blocks/chat/composer.jsx +364 -0
  118. package/registry/blocks/chat/demo.jsx +578 -0
  119. package/registry/blocks/chat/header.jsx +34 -0
  120. package/registry/blocks/chat/index.js +9 -0
  121. package/registry/blocks/chat/message.jsx +450 -0
  122. package/registry/blocks/chat/scroller.jsx +247 -0
  123. package/registry/blocks/chat/text.jsx +104 -0
  124. package/registry/blocks/code-editor/README.md +210 -0
  125. package/registry/blocks/code-editor/block.json +22 -0
  126. package/registry/blocks/code-editor/code-editor.jsx +534 -0
  127. package/registry/blocks/code-editor/codemirror.js +38 -0
  128. package/registry/blocks/code-editor/demo.jsx +205 -0
  129. package/registry/blocks/code-editor/index.js +8 -0
  130. package/registry/blocks/code-editor/json.js +317 -0
  131. package/registry/blocks/code-editor/sql.js +136 -0
  132. package/registry/blocks/code-editor/text.js +101 -0
  133. package/registry/blocks/code-editor/theme.js +186 -0
  134. package/registry/blocks/comment-box/README.md +123 -0
  135. package/registry/blocks/comment-box/block.json +10 -0
  136. package/registry/blocks/comment-box/comment-body.jsx +217 -0
  137. package/registry/blocks/comment-box/comment-box.jsx +198 -0
  138. package/registry/blocks/comment-box/comment-time.jsx +77 -0
  139. package/registry/blocks/comment-box/demo.jsx +141 -0
  140. package/registry/blocks/comment-box/index.js +8 -0
  141. package/registry/blocks/contact-section/README.md +152 -0
  142. package/registry/blocks/contact-section/block.json +11 -0
  143. package/registry/blocks/contact-section/contact-section.jsx +509 -0
  144. package/registry/blocks/contact-section/demo.jsx +93 -0
  145. package/registry/blocks/contact-section/index.js +4 -0
  146. package/registry/blocks/csv-import/README.md +133 -0
  147. package/registry/blocks/csv-import/block.json +13 -0
  148. package/registry/blocks/csv-import/csv-import.jsx +479 -0
  149. package/registry/blocks/csv-import/demo.jsx +106 -0
  150. package/registry/blocks/csv-import/import.js +200 -0
  151. package/registry/blocks/csv-import/index.js +7 -0
  152. package/registry/blocks/data-table/README.md +386 -0
  153. package/registry/blocks/data-table/block.json +10 -0
  154. package/registry/blocks/data-table/data-table.jsx +1164 -0
  155. package/registry/blocks/data-table/demo.jsx +588 -0
  156. package/registry/blocks/data-table/index.js +5 -0
  157. package/registry/blocks/data-table/model.js +169 -0
  158. package/registry/blocks/diagram/README.md +108 -0
  159. package/registry/blocks/diagram/block.json +13 -0
  160. package/registry/blocks/diagram/demo.jsx +113 -0
  161. package/registry/blocks/diagram/diagram.jsx +481 -0
  162. package/registry/blocks/diagram/index.js +7 -0
  163. package/registry/blocks/diagram/mermaid.js +52 -0
  164. package/registry/blocks/diagram/palette.js +313 -0
  165. package/registry/blocks/diagram/source.js +98 -0
  166. package/registry/blocks/doc-editor/README.md +215 -0
  167. package/registry/blocks/doc-editor/block.json +15 -0
  168. package/registry/blocks/doc-editor/demo.jsx +225 -0
  169. package/registry/blocks/doc-editor/doc-editor.jsx +291 -0
  170. package/registry/blocks/doc-editor/doc.js +309 -0
  171. package/registry/blocks/doc-editor/index.js +7 -0
  172. package/registry/blocks/doc-editor/schema.jsx +56 -0
  173. package/registry/blocks/doc-editor/shadcn-classes.js +110 -0
  174. package/registry/blocks/doc-editor/theme.js +82 -0
  175. package/registry/blocks/doc-page/README.md +119 -0
  176. package/registry/blocks/doc-page/autosave.js +104 -0
  177. package/registry/blocks/doc-page/block.json +10 -0
  178. package/registry/blocks/doc-page/demo.jsx +137 -0
  179. package/registry/blocks/doc-page/doc-page.jsx +276 -0
  180. package/registry/blocks/doc-page/index.js +4 -0
  181. package/registry/blocks/email-render/README.md +151 -0
  182. package/registry/blocks/email-render/block.json +14 -0
  183. package/registry/blocks/email-render/demo.jsx +153 -0
  184. package/registry/blocks/email-render/doc-email.jsx +210 -0
  185. package/registry/blocks/email-render/email.jsx +221 -0
  186. package/registry/blocks/email-render/index.js +10 -0
  187. package/registry/blocks/email-render/render.js +50 -0
  188. package/registry/blocks/email-render/theme.js +215 -0
  189. package/registry/blocks/faq/README.md +101 -0
  190. package/registry/blocks/faq/block.json +11 -0
  191. package/registry/blocks/faq/demo.jsx +89 -0
  192. package/registry/blocks/faq/faq.jsx +220 -0
  193. package/registry/blocks/faq/index.js +4 -0
  194. package/registry/blocks/file-upload/README.md +138 -0
  195. package/registry/blocks/file-upload/block.json +10 -0
  196. package/registry/blocks/file-upload/demo.jsx +204 -0
  197. package/registry/blocks/file-upload/file-upload.jsx +635 -0
  198. package/registry/blocks/file-upload/index.js +4 -0
  199. package/registry/blocks/flow-canvas/README.md +420 -0
  200. package/registry/blocks/flow-canvas/block.json +13 -0
  201. package/registry/blocks/flow-canvas/board.js +819 -0
  202. package/registry/blocks/flow-canvas/chrome.jsx +649 -0
  203. package/registry/blocks/flow-canvas/context.jsx +35 -0
  204. package/registry/blocks/flow-canvas/demo.jsx +249 -0
  205. package/registry/blocks/flow-canvas/edges.jsx +107 -0
  206. package/registry/blocks/flow-canvas/flow-canvas.jsx +1329 -0
  207. package/registry/blocks/flow-canvas/index.js +41 -0
  208. package/registry/blocks/flow-canvas/nodes.jsx +392 -0
  209. package/registry/blocks/flow-canvas/theme.js +174 -0
  210. package/registry/blocks/footer/README.md +133 -0
  211. package/registry/blocks/footer/block.json +11 -0
  212. package/registry/blocks/footer/demo.jsx +119 -0
  213. package/registry/blocks/footer/footer.jsx +406 -0
  214. package/registry/blocks/footer/index.js +4 -0
  215. package/registry/blocks/gantt/README.md +220 -0
  216. package/registry/blocks/gantt/block.json +10 -0
  217. package/registry/blocks/gantt/demo.jsx +148 -0
  218. package/registry/blocks/gantt/gantt.jsx +923 -0
  219. package/registry/blocks/gantt/index.js +7 -0
  220. package/registry/blocks/gantt/rows.jsx +468 -0
  221. package/registry/blocks/gantt/schedule.js +278 -0
  222. package/registry/blocks/job-panel/README.md +80 -0
  223. package/registry/blocks/job-panel/block.json +3 -3
  224. package/registry/blocks/job-panel/demo.jsx +230 -3
  225. package/registry/blocks/job-panel/job-panel.jsx +169 -3
  226. package/registry/blocks/json-editor/README.md +133 -0
  227. package/registry/blocks/json-editor/block.json +10 -0
  228. package/registry/blocks/json-editor/demo.jsx +92 -0
  229. package/registry/blocks/json-editor/index.js +7 -0
  230. package/registry/blocks/json-editor/json-editor.jsx +305 -0
  231. package/registry/blocks/json-editor/json-tree.jsx +393 -0
  232. package/registry/blocks/json-editor/tree.js +225 -0
  233. package/registry/blocks/map/README.md +221 -0
  234. package/registry/blocks/map/block.json +14 -0
  235. package/registry/blocks/map/demo.jsx +201 -0
  236. package/registry/blocks/map/geo.js +198 -0
  237. package/registry/blocks/map/index.js +8 -0
  238. package/registry/blocks/map/list.jsx +128 -0
  239. package/registry/blocks/map/map-view.jsx +715 -0
  240. package/registry/blocks/map/maplibre.js +30 -0
  241. package/registry/blocks/map/marks.jsx +146 -0
  242. package/registry/blocks/map/theme.js +142 -0
  243. package/registry/blocks/menubar/README.md +109 -0
  244. package/registry/blocks/menubar/block.json +10 -0
  245. package/registry/blocks/menubar/demo.jsx +128 -0
  246. package/registry/blocks/menubar/index.js +4 -0
  247. package/registry/blocks/menubar/menubar.jsx +199 -0
  248. package/registry/blocks/mind-map/README.md +206 -0
  249. package/registry/blocks/mind-map/block.json +10 -0
  250. package/registry/blocks/mind-map/demo.jsx +103 -0
  251. package/registry/blocks/mind-map/index.js +31 -0
  252. package/registry/blocks/mind-map/mind-map.jsx +1125 -0
  253. package/registry/blocks/mind-map/topic.jsx +143 -0
  254. package/registry/blocks/mind-map/tree.js +645 -0
  255. package/registry/blocks/navigation-menu/README.md +124 -0
  256. package/registry/blocks/navigation-menu/block.json +10 -0
  257. package/registry/blocks/navigation-menu/demo.jsx +84 -0
  258. package/registry/blocks/navigation-menu/index.js +4 -0
  259. package/registry/blocks/navigation-menu/navigation-menu.jsx +448 -0
  260. package/registry/blocks/order-detail/README.md +109 -0
  261. package/registry/blocks/order-detail/block.json +10 -0
  262. package/registry/blocks/order-detail/demo.jsx +88 -0
  263. package/registry/blocks/order-detail/index.js +4 -0
  264. package/registry/blocks/order-detail/order-detail.jsx +354 -0
  265. package/registry/blocks/org-chart/README.md +145 -0
  266. package/registry/blocks/org-chart/block.json +10 -0
  267. package/registry/blocks/org-chart/demo.jsx +94 -0
  268. package/registry/blocks/org-chart/index.js +7 -0
  269. package/registry/blocks/org-chart/org-chart.jsx +631 -0
  270. package/registry/blocks/org-chart/org.js +245 -0
  271. package/registry/blocks/org-chart/person.jsx +96 -0
  272. package/registry/blocks/page-builder/README.md +257 -0
  273. package/registry/blocks/page-builder/block.json +14 -0
  274. package/registry/blocks/page-builder/demo.jsx +145 -0
  275. package/registry/blocks/page-builder/grapes.js +18 -0
  276. package/registry/blocks/page-builder/index.js +11 -0
  277. package/registry/blocks/page-builder/page-builder.jsx +704 -0
  278. package/registry/blocks/page-builder/page-view.jsx +33 -0
  279. package/registry/blocks/page-builder/page.js +118 -0
  280. package/registry/blocks/page-builder/panels.jsx +588 -0
  281. package/registry/blocks/page-builder/sections.js +209 -0
  282. package/registry/blocks/page-builder/theme.js +87 -0
  283. package/registry/blocks/page-builder/thumbs.jsx +189 -0
  284. package/registry/blocks/page-builder/tokens.js +329 -0
  285. package/registry/blocks/payment-methods/README.md +104 -0
  286. package/registry/blocks/payment-methods/block.json +10 -0
  287. package/registry/blocks/payment-methods/demo.jsx +71 -0
  288. package/registry/blocks/payment-methods/index.js +4 -0
  289. package/registry/blocks/payment-methods/payment-methods.jsx +302 -0
  290. package/registry/blocks/pdf-document/README.md +213 -0
  291. package/registry/blocks/pdf-document/block.json +13 -0
  292. package/registry/blocks/pdf-document/demo.jsx +136 -0
  293. package/registry/blocks/pdf-document/index.js +33 -0
  294. package/registry/blocks/pdf-document/money.js +83 -0
  295. package/registry/blocks/pdf-document/pdf-document.jsx +144 -0
  296. package/registry/blocks/pdf-document/primitives.jsx +271 -0
  297. package/registry/blocks/pdf-document/quote.jsx +179 -0
  298. package/registry/blocks/pdf-document/theme.js +193 -0
  299. package/registry/blocks/pdf-viewer/README.md +191 -0
  300. package/registry/blocks/pdf-viewer/block.json +14 -0
  301. package/registry/blocks/pdf-viewer/demo.jsx +252 -0
  302. package/registry/blocks/pdf-viewer/helpers.js +270 -0
  303. package/registry/blocks/pdf-viewer/index.js +8 -0
  304. package/registry/blocks/pdf-viewer/notes.jsx +195 -0
  305. package/registry/blocks/pdf-viewer/pdf-viewer.jsx +1368 -0
  306. package/registry/blocks/pdf-viewer/pdfjs.js +37 -0
  307. package/registry/blocks/pdf-viewer/ssr-shim-end.js +6 -0
  308. package/registry/blocks/pdf-viewer/ssr-shim.js +44 -0
  309. package/registry/blocks/product-detail/README.md +217 -0
  310. package/registry/blocks/product-detail/block.json +10 -0
  311. package/registry/blocks/product-detail/demo.jsx +233 -0
  312. package/registry/blocks/product-detail/index.js +7 -0
  313. package/registry/blocks/product-detail/price.jsx +115 -0
  314. package/registry/blocks/product-detail/product-detail.jsx +348 -0
  315. package/registry/blocks/product-detail/product-media.jsx +102 -0
  316. package/registry/blocks/product-detail/product-options.jsx +144 -0
  317. package/registry/blocks/product-grid/README.md +162 -0
  318. package/registry/blocks/product-grid/block.json +10 -0
  319. package/registry/blocks/product-grid/demo.jsx +255 -0
  320. package/registry/blocks/product-grid/index.js +5 -0
  321. package/registry/blocks/product-grid/product-card.jsx +232 -0
  322. package/registry/blocks/product-grid/product-grid.jsx +235 -0
  323. package/registry/blocks/record-form/README.md +196 -0
  324. package/registry/blocks/record-form/block.json +10 -0
  325. package/registry/blocks/record-form/demo.jsx +525 -0
  326. package/registry/blocks/record-form/index.js +4 -0
  327. package/registry/blocks/record-form/record-fields.jsx +457 -0
  328. package/registry/blocks/record-form/record-form.jsx +415 -0
  329. package/registry/blocks/record-form/rules.js +81 -0
  330. package/registry/blocks/record-notes/README.md +139 -0
  331. package/registry/blocks/record-notes/block.json +10 -0
  332. package/registry/blocks/record-notes/demo.jsx +179 -0
  333. package/registry/blocks/record-notes/index.js +4 -0
  334. package/registry/blocks/record-notes/record-notes.jsx +266 -0
  335. package/registry/blocks/search-dialog/README.md +108 -0
  336. package/registry/blocks/search-dialog/block.json +10 -0
  337. package/registry/blocks/search-dialog/demo.jsx +116 -0
  338. package/registry/blocks/search-dialog/index.js +3 -0
  339. package/registry/blocks/search-dialog/search-dialog.jsx +235 -0
  340. package/registry/blocks/settings-list/README.md +171 -0
  341. package/registry/blocks/settings-list/block.json +10 -0
  342. package/registry/blocks/settings-list/demo.jsx +333 -0
  343. package/registry/blocks/settings-list/index.js +4 -0
  344. package/registry/blocks/settings-list/row-state.jsx +93 -0
  345. package/registry/blocks/settings-list/settings-list.jsx +349 -0
  346. package/registry/blocks/settings-list/settings-matrix.jsx +118 -0
  347. package/registry/blocks/setup-checklist/README.md +142 -0
  348. package/registry/blocks/setup-checklist/block.json +10 -0
  349. package/registry/blocks/setup-checklist/demo.jsx +159 -0
  350. package/registry/blocks/setup-checklist/index.js +4 -0
  351. package/registry/blocks/setup-checklist/setup-checklist.jsx +446 -0
  352. package/registry/blocks/share-dialog/README.md +113 -0
  353. package/registry/blocks/share-dialog/block.json +10 -0
  354. package/registry/blocks/share-dialog/demo.jsx +140 -0
  355. package/registry/blocks/share-dialog/index.js +3 -0
  356. package/registry/blocks/share-dialog/share-dialog.jsx +384 -0
  357. package/registry/blocks/sidebar/README.md +190 -0
  358. package/registry/blocks/sidebar/block.json +43 -0
  359. package/registry/blocks/sidebar/demo.jsx +577 -0
  360. package/registry/blocks/sidebar/index.js +4 -0
  361. package/registry/blocks/sidebar/sidebar-panel.jsx +149 -0
  362. package/registry/blocks/sidebar/sidebar.jsx +864 -0
  363. package/registry/blocks/signature-pad/README.md +137 -0
  364. package/registry/blocks/signature-pad/block.json +13 -0
  365. package/registry/blocks/signature-pad/colors.js +115 -0
  366. package/registry/blocks/signature-pad/demo.jsx +94 -0
  367. package/registry/blocks/signature-pad/index.js +6 -0
  368. package/registry/blocks/signature-pad/pad.js +7 -0
  369. package/registry/blocks/signature-pad/signature-pad.jsx +434 -0
  370. package/registry/blocks/signature-pad/signature.js +68 -0
  371. package/registry/blocks/sketch-canvas/README.md +280 -0
  372. package/registry/blocks/sketch-canvas/block.json +13 -0
  373. package/registry/blocks/sketch-canvas/demo.jsx +159 -0
  374. package/registry/blocks/sketch-canvas/excalidraw.js +40 -0
  375. package/registry/blocks/sketch-canvas/index.js +9 -0
  376. package/registry/blocks/sketch-canvas/palette.js +226 -0
  377. package/registry/blocks/sketch-canvas/sketch-canvas.jsx +1188 -0
  378. package/registry/blocks/sketch-canvas/sketch.js +179 -0
  379. package/registry/blocks/sketch-canvas/ssr-shim-end.js +6 -0
  380. package/registry/blocks/sketch-canvas/ssr-shim.js +45 -0
  381. package/registry/blocks/sketch-canvas/stamps.js +104 -0
  382. package/registry/blocks/sketch-canvas/theme.js +131 -0
  383. package/registry/blocks/spreadsheet/README.md +307 -0
  384. package/registry/blocks/spreadsheet/block.json +13 -0
  385. package/registry/blocks/spreadsheet/cells.jsx +455 -0
  386. package/registry/blocks/spreadsheet/chrome.jsx +325 -0
  387. package/registry/blocks/spreadsheet/demo.jsx +177 -0
  388. package/registry/blocks/spreadsheet/grid.js +387 -0
  389. package/registry/blocks/spreadsheet/index.js +34 -0
  390. package/registry/blocks/spreadsheet/spreadsheet.jsx +1732 -0
  391. package/registry/blocks/spreadsheet/types.js +473 -0
  392. package/registry/blocks/stat-cards/README.md +173 -0
  393. package/registry/blocks/stat-cards/block.json +10 -0
  394. package/registry/blocks/stat-cards/demo.jsx +257 -0
  395. package/registry/blocks/stat-cards/index.js +4 -0
  396. package/registry/blocks/stat-cards/stat-cards.jsx +307 -0
  397. package/registry/blocks/stat-cards/usage.jsx +243 -0
  398. package/registry/blocks/task-list/README.md +176 -0
  399. package/registry/blocks/task-list/block.json +10 -0
  400. package/registry/blocks/task-list/demo.jsx +134 -0
  401. package/registry/blocks/task-list/index.js +5 -0
  402. package/registry/blocks/task-list/task-list.jsx +907 -0
  403. package/registry/blocks/task-model/README.md +455 -0
  404. package/registry/blocks/task-model/block.json +167 -0
  405. package/registry/blocks/task-model/changes.js +89 -0
  406. package/registry/blocks/task-model/dates.js +371 -0
  407. package/registry/blocks/task-model/demo.jsx +215 -0
  408. package/registry/blocks/task-model/dnd.jsx +240 -0
  409. package/registry/blocks/task-model/index.js +97 -0
  410. package/registry/blocks/task-model/model.js +919 -0
  411. package/registry/blocks/task-model/parts.jsx +449 -0
  412. package/registry/blocks/task-model/toolbar.jsx +271 -0
  413. package/registry/blocks/testimonials/README.md +139 -0
  414. package/registry/blocks/testimonials/block.json +11 -0
  415. package/registry/blocks/testimonials/demo.jsx +137 -0
  416. package/registry/blocks/testimonials/index.js +4 -0
  417. package/registry/blocks/testimonials/testimonials.jsx +430 -0
  418. package/registry/blocks/transaction-list/README.md +126 -0
  419. package/registry/blocks/transaction-list/block.json +10 -0
  420. package/registry/blocks/transaction-list/demo.jsx +79 -0
  421. package/registry/blocks/transaction-list/index.js +4 -0
  422. package/registry/blocks/transaction-list/transaction-list.jsx +383 -0
  423. package/registry/blocks/whiteboard/README.md +179 -0
  424. package/registry/blocks/whiteboard/block.json +10 -0
  425. package/registry/blocks/whiteboard/demo.jsx +169 -0
  426. package/registry/blocks/whiteboard/index.js +6 -0
  427. package/registry/blocks/whiteboard/templates.js +150 -0
  428. package/registry/blocks/whiteboard/whiteboard.jsx +721 -0
  429. package/src/cli.mjs +19 -6
  430. package/src/install.mjs +18 -0
  431. package/src/registry.mjs +38 -4
  432. package/src/shadcn.mjs +14 -1
  433. package/templates/next/files/README.md +145 -11
  434. package/templates/next/files/app/globals.css +55 -4
  435. package/templates/next/files/check/run.mjs +3 -3
  436. package/templates/next/files/components/ui/avatar.jsx +141 -0
  437. package/templates/next/files/components/ui/breadcrumb.jsx +149 -0
  438. package/templates/next/files/components/ui/button-group.jsx +70 -0
  439. package/templates/next/files/components/ui/button.jsx +132 -12
  440. package/templates/next/files/components/ui/calendar.jsx +609 -0
  441. package/templates/next/files/components/ui/carousel.jsx +281 -0
  442. package/templates/next/files/components/ui/collapsible.jsx +208 -0
  443. package/templates/next/files/components/ui/combobox.jsx +608 -0
  444. package/templates/next/files/components/ui/command.jsx +577 -0
  445. package/templates/next/files/components/ui/context-menu.jsx +191 -0
  446. package/templates/next/files/components/ui/date-picker.jsx +360 -0
  447. package/templates/next/files/components/ui/distribution.jsx +117 -0
  448. package/templates/next/files/components/ui/feedback.jsx +143 -0
  449. package/templates/next/files/components/ui/field.jsx +115 -3
  450. package/templates/next/files/components/ui/file-input.jsx +234 -0
  451. package/templates/next/files/components/ui/icon.jsx +130 -8
  452. package/templates/next/files/components/ui/image.jsx +143 -0
  453. package/templates/next/files/components/ui/index.js +47 -2
  454. package/templates/next/files/components/ui/input-group.jsx +213 -0
  455. package/templates/next/files/components/ui/input-otp.jsx +170 -0
  456. package/templates/next/files/components/ui/item.jsx +206 -0
  457. package/templates/next/files/components/ui/menu.jsx +454 -82
  458. package/templates/next/files/components/ui/notice.jsx +126 -14
  459. package/templates/next/files/components/ui/pagination.jsx +156 -0
  460. package/templates/next/files/components/ui/popover.jsx +284 -0
  461. package/templates/next/files/components/ui/radio.jsx +193 -0
  462. package/templates/next/files/components/ui/rating.jsx +131 -0
  463. package/templates/next/files/components/ui/resizable.jsx +338 -0
  464. package/templates/next/files/components/ui/scroll-area.jsx +123 -0
  465. package/templates/next/files/components/ui/separator.jsx +119 -0
  466. package/templates/next/files/components/ui/sheet.jsx +96 -11
  467. package/templates/next/files/components/ui/slider.jsx +174 -0
  468. package/templates/next/files/components/ui/stat.jsx +574 -0
  469. package/templates/next/files/components/ui/steps.jsx +338 -0
  470. package/templates/next/files/components/ui/swatch.jsx +33 -0
  471. package/templates/next/files/components/ui/table.jsx +130 -0
  472. package/templates/next/files/components/ui/toast.jsx +440 -0
  473. package/templates/next/files/components/ui/toggle.jsx +195 -0
  474. package/templates/next/files/components/ui/tooltip.jsx +270 -0
  475. package/templates/next/template.json +264 -8
@@ -0,0 +1,245 @@
1
+ // The org chart's data and layout — plain functions, no React, no DOM.
2
+ // They run anywhere (the server, an agent's tool, a test).
3
+ //
4
+ // People come in flat, the way a table holds them: each row names its
5
+ // manager. buildOrg turns them into a tree; layoutOrg places the tree top
6
+ // down, managers centred over their reports, and a manager whose reports
7
+ // have no reports of their own gets them as a compact column (a wide row
8
+ // of twelve cards reads worse than a list).
9
+
10
+ /** Department (or any group) colours, in order: chart hues, which every
11
+ * theme derives from its own primary. As hue numbers for Legend/Badge. */
12
+ export const GROUP_HUES = [2, 3, 4, 5, 1];
13
+
14
+ export const CARD = { width: 248, height: 72 };
15
+ const GAP_X = 20; // between side-by-side teams
16
+ const GAP_Y = 52; // between a manager and the row of reports
17
+ const STACK_INDENT = 32; // a column of reports sits this far in
18
+ const STACK_GAP = 10;
19
+ const ROOT_GAP = 64; // between separate trees
20
+ /** A manager's reports stack as a column when there are at least this
21
+ * many and none of them manages anyone. */
22
+ export const STACK_FROM = 3;
23
+
24
+ /**
25
+ * Flat people → a tree. Returns { roots, byId }; each node is
26
+ * { id, person, parentId, depth, children, total } (total: everyone under
27
+ * them). Someone whose manager is missing, or whose chain of managers
28
+ * loops, becomes a root.
29
+ *
30
+ * managerKey the field naming the manager's id (default "managerId")
31
+ */
32
+ export function buildOrg(people, { managerKey = "managerId" } = {}) {
33
+ const list = Array.isArray(people) ? people.filter((p) => p && p.id != null) : [];
34
+ const byId = new Map();
35
+ for (const p of list) {
36
+ const id = String(p.id);
37
+ if (!byId.has(id)) byId.set(id, { id, person: p, parentId: null, depth: 0, children: [], total: 0 });
38
+ }
39
+ const managerOf = (id) => {
40
+ const m = byId.get(id)?.person?.[managerKey];
41
+ return m != null && byId.has(String(m)) && String(m) !== id ? String(m) : null;
42
+ };
43
+ // A chain that comes back to itself: whoever closes the loop is a root.
44
+ const loops = new Set();
45
+ for (const id of byId.keys()) {
46
+ const seen = new Set([id]);
47
+ let cur = managerOf(id);
48
+ while (cur) {
49
+ if (seen.has(cur)) {
50
+ if (cur === id) loops.add(id);
51
+ break;
52
+ }
53
+ seen.add(cur);
54
+ cur = managerOf(cur);
55
+ }
56
+ }
57
+ const roots = [];
58
+ for (const n of byId.values()) {
59
+ const m = loops.has(n.id) ? null : managerOf(n.id);
60
+ if (m && !loops.has(n.id)) {
61
+ n.parentId = m;
62
+ byId.get(m).children.push(n);
63
+ } else roots.push(n);
64
+ }
65
+ // Anyone still unreached sits in a loop not broken above: a root too.
66
+ const reached = new Set();
67
+ const walk = (n, depth) => {
68
+ if (reached.has(n.id)) return 0;
69
+ reached.add(n.id);
70
+ n.depth = depth;
71
+ n.total = n.children.reduce((s, c) => s + 1 + walk(c, depth + 1), 0);
72
+ return n.total;
73
+ };
74
+ for (const r of roots) walk(r, 0);
75
+ for (const n of byId.values()) {
76
+ if (reached.has(n.id)) continue;
77
+ if (n.parentId) byId.get(n.parentId).children = byId.get(n.parentId).children.filter((c) => c.id !== n.id);
78
+ n.parentId = null;
79
+ roots.push(n);
80
+ walk(n, 0);
81
+ }
82
+ return { roots, byId };
83
+ }
84
+
85
+ /** [root, …, the person's node] — their chain of managers, top first. */
86
+ export function chainOf(byId, id) {
87
+ const out = [];
88
+ let n = byId.get(String(id));
89
+ const seen = new Set();
90
+ while (n && !seen.has(n.id)) {
91
+ seen.add(n.id);
92
+ out.unshift(n);
93
+ n = n.parentId ? byId.get(n.parentId) : null;
94
+ }
95
+ return out;
96
+ }
97
+
98
+ /** The colour group of each value of `key` ("department"): the first
99
+ * seen gets the first hue. Map(value → hue number 1..5). */
100
+ export function groupHues(people, key) {
101
+ const out = new Map();
102
+ if (!key) return out;
103
+ for (const p of people ?? []) {
104
+ const v = typeof key === "function" ? key(p) : p?.[key];
105
+ if (v == null || v === "" || out.has(v)) continue;
106
+ out.set(v, GROUP_HUES[out.size % GROUP_HUES.length]);
107
+ }
108
+ return out;
109
+ }
110
+
111
+ // Rounded right-angle lines through points (a corner radius r).
112
+ export function elbowPath(points, r = 8) {
113
+ if (points.length < 2) return "";
114
+ let d = `M${points[0].x},${points[0].y}`;
115
+ for (let i = 1; i < points.length - 1; i++) {
116
+ const a = points[i - 1];
117
+ const b = points[i];
118
+ const c = points[i + 1];
119
+ const r1 = Math.min(r, Math.hypot(b.x - a.x, b.y - a.y) / 2, Math.hypot(c.x - b.x, c.y - b.y) / 2);
120
+ const u = { x: Math.sign(b.x - a.x), y: Math.sign(b.y - a.y) };
121
+ const v = { x: Math.sign(c.x - b.x), y: Math.sign(c.y - b.y) };
122
+ d += ` L${b.x - u.x * r1},${b.y - u.y * r1} Q${b.x},${b.y} ${b.x + v.x * r1},${b.y + v.y * r1}`;
123
+ }
124
+ const z = points[points.length - 1];
125
+ return `${d} L${z.x},${z.y}`;
126
+ }
127
+
128
+ /**
129
+ * Where every visible card goes. Top down; a manager centred over the
130
+ * cards of their reports; a folded manager's team hidden; separate trees
131
+ * side by side.
132
+ *
133
+ * collapsed(node) → true when the node's team is folded
134
+ * stack true (default): reports with no reports of their own
135
+ * become a column once there are STACK_FROM of them
136
+ *
137
+ * Returns { items, bounds }. Each item: { id, node, x, y, width, height,
138
+ * depth, parentId, folded, link } — `link` the line up to the manager, as
139
+ * points in board px ([] for a root).
140
+ */
141
+ export function layoutOrg(roots, { collapsed = () => false, stack = true, card = CARD } = {}) {
142
+ const W = card.width;
143
+ const H = card.height;
144
+ const info = new Map();
145
+ const shown = (n) => (collapsed(n) ? [] : n.children);
146
+ const measure = (n) => {
147
+ const kids = shown(n);
148
+ let mode = "none";
149
+ let width = W;
150
+ if (kids.length) {
151
+ for (const k of kids) measure(k);
152
+ if (stack && kids.length >= STACK_FROM && kids.every((k) => !k.children.length)) {
153
+ mode = "stack";
154
+ width = STACK_INDENT + W;
155
+ } else {
156
+ mode = "row";
157
+ const total = kids.reduce((s, k) => s + info.get(k.id).width, 0) + GAP_X * (kids.length - 1);
158
+ width = Math.max(W, total);
159
+ }
160
+ }
161
+ info.set(n.id, { mode, width });
162
+ };
163
+
164
+ const items = [];
165
+ const place = (n, left, top, parent) => {
166
+ const { mode, width } = info.get(n.id);
167
+ const kids = shown(n);
168
+ const me = { id: n.id, node: n, x: left, y: top, width: W, height: H, depth: n.depth, parentId: parent?.id ?? null, folded: kids.length === 0 && n.children.length > 0, link: [] };
169
+ items.push(me);
170
+ if (mode === "none") {
171
+ me.x = left + (width - W) / 2;
172
+ return me;
173
+ }
174
+ if (mode === "stack") {
175
+ me.x = left;
176
+ let y = top + H + GAP_Y / 2 + 6;
177
+ const spine = me.x + STACK_INDENT / 2;
178
+ for (const k of kids) {
179
+ const c = place(k, left + STACK_INDENT, y, me);
180
+ c.link = [
181
+ { x: spine, y: top + H },
182
+ { x: spine, y: y + H / 2 },
183
+ { x: c.x, y: y + H / 2 },
184
+ ];
185
+ y += H + STACK_GAP;
186
+ }
187
+ return me;
188
+ }
189
+ const total = kids.reduce((s, k) => s + info.get(k.id).width, 0) + GAP_X * (kids.length - 1);
190
+ let x = left + (width - total) / 2;
191
+ const placed = [];
192
+ for (const k of kids) {
193
+ placed.push(place(k, x, top + H + GAP_Y, me));
194
+ x += info.get(k.id).width + GAP_X;
195
+ }
196
+ const a = placed[0].x + W / 2;
197
+ const b = placed[placed.length - 1].x + W / 2;
198
+ me.x = (a + b) / 2 - W / 2;
199
+ const mid = top + H + GAP_Y / 2;
200
+ for (const c of placed) {
201
+ c.link = [
202
+ { x: me.x + W / 2, y: top + H },
203
+ { x: me.x + W / 2, y: mid },
204
+ { x: c.x + W / 2, y: mid },
205
+ { x: c.x + W / 2, y: c.y },
206
+ ];
207
+ // Straight down: two points are enough.
208
+ if (Math.abs(c.link[0].x - c.link[3].x) < 0.5) c.link = [c.link[0], c.link[3]];
209
+ }
210
+ return me;
211
+ };
212
+
213
+ for (const r of roots) measure(r);
214
+ let x = 0;
215
+ for (const r of roots) {
216
+ place(r, x, 0, null);
217
+ x += info.get(r.id).width + ROOT_GAP;
218
+ }
219
+
220
+ let x1 = Infinity;
221
+ let y1 = Infinity;
222
+ let x2 = -Infinity;
223
+ let y2 = -Infinity;
224
+ for (const it of items) {
225
+ x1 = Math.min(x1, it.x);
226
+ y1 = Math.min(y1, it.y);
227
+ x2 = Math.max(x2, it.x + it.width);
228
+ y2 = Math.max(y2, it.y + it.height);
229
+ }
230
+ return { items, bounds: items.length ? { x: x1, y: y1, width: x2 - x1, height: y2 - y1 } : { x: 0, y: 0, width: 0, height: 0 } };
231
+ }
232
+
233
+ /** The org as plain text, one person a line, indented under their
234
+ * manager: "Maya Chen — VP Engineering (12)". For an agent or search. */
235
+ export function orgToText(people, opts) {
236
+ const { roots } = buildOrg(people, opts);
237
+ const out = [];
238
+ const walk = (n, depth) => {
239
+ const p = n.person;
240
+ out.push(`${" ".repeat(depth)}${depth ? "- " : ""}${p.name ?? n.id}${p.title ? ` — ${p.title}` : ""}${n.total ? ` (${n.total})` : ""}`);
241
+ for (const c of n.children) walk(c, depth + 1);
242
+ };
243
+ for (const r of roots) walk(r, 0);
244
+ return out.join("\n");
245
+ }
@@ -0,0 +1,96 @@
1
+ "use client";
2
+
3
+ // One person on the chart, as a FlowCanvas node type: a card (face, name,
4
+ // title, a strip in their group's colour), the line up to their manager
5
+ // (an SVG reaching outside the card, so the canvas needs no connectors),
6
+ // and — for a manager — the chip at the card's foot that folds the team
7
+ // and says how big it is.
8
+ //
9
+ // What the chart knows (the selection, the chain being lit, a drag in
10
+ // progress, what a click does) comes from OrgContext, which OrgChart
11
+ // provides around the canvas.
12
+ import { createContext, useContext } from "react";
13
+ import { Avatar, Icon, cx } from "../../ui";
14
+ import { elbowPath } from "./org";
15
+
16
+ export const OrgContext = createContext(null);
17
+
18
+ // Group hue → the strip's class, written out whole so Tailwind makes them.
19
+ const STRIP = { 1: "bg-chart-1", 2: "bg-chart-2", 3: "bg-chart-3", 4: "bg-chart-4", 5: "bg-chart-5" };
20
+
21
+ export function PersonNode({ id, data }) {
22
+ const o = useContext(OrgContext);
23
+ if (!o) return null;
24
+ const { name, title, avatar, hue, direct = 0, total = 0, folded = false, link, parentId } = data ?? {};
25
+ const selected = o.selectedId === id;
26
+ const lit = o.chain.has(id) && parentId && o.chain.has(parentId);
27
+ const isDrop = o.dropId === id;
28
+ const dragged = o.dragId === id;
29
+
30
+ return (
31
+ <div data-person={id} className="group/person relative size-full">
32
+ {link ? (
33
+ <svg aria-hidden="true" width="1" height="1" className="pointer-events-none absolute top-0 left-0 overflow-visible">
34
+ <path d={elbowPath(link)} className={cx("fill-none transition-[stroke] duration-150 motion-reduce:transition-none", lit ? "stroke-primary" : "stroke-border")} strokeWidth={lit ? 2 : 1.5} strokeLinecap="round" strokeLinejoin="round" />
35
+ </svg>
36
+ ) : null}
37
+ {/* raw: the person's card on the canvas — it takes the pointer
38
+ (a click selects, a click on the selected card opens it, a drag
39
+ moves them to a new manager); the keys arrive through OrgChart's
40
+ handler on the canvas. */}
41
+ <div
42
+ className={cx(
43
+ "relative flex size-full items-center gap-3 overflow-hidden rounded-xl border border-border bg-card py-2 pr-3 pl-4 text-card-foreground shadow-xs",
44
+ "transition-[box-shadow,opacity,outline-color] duration-150 hover:shadow-md motion-reduce:transition-none",
45
+ o.coarse ? "" : "nopan",
46
+ o.draggable ? "cursor-grab" : "cursor-pointer",
47
+ selected && "ring-2 ring-primary ring-offset-2 ring-offset-background",
48
+ isDrop && "outline-2 outline-offset-4 outline-primary [outline-style:dashed]",
49
+ dragged && "opacity-40",
50
+ )}
51
+ onPointerDown={(e) => {
52
+ if (e.button === 0) o.onCardPointerDown(e, id);
53
+ }}
54
+ >
55
+ {hue ? <span aria-hidden="true" className={cx("absolute inset-y-0 left-0 w-1", STRIP[hue])} /> : null}
56
+ <Avatar name={name} src={avatar} size="md" />
57
+ <div className="min-w-0 flex-1">
58
+ <p className="truncate text-sm font-medium" title={name}>
59
+ {name || "Unnamed"}
60
+ </p>
61
+ <p className="truncate text-xs text-muted-foreground" title={title}>
62
+ {title || " "}
63
+ </p>
64
+ </div>
65
+ </div>
66
+
67
+ {direct > 0 ? (
68
+ // raw: a 22px chip on the card's foot, smaller than any kit button
69
+ // — the canvas is zoomed out on a big org, and a 36px button would
70
+ // cover the line to the team. Out of the tab order: Space folds.
71
+ <button
72
+ type="button"
73
+ tabIndex={-1}
74
+ aria-label={`${folded ? "Show" : "Hide"} ${name}'s team: ${direct} direct, ${total} in all`}
75
+ title={`${direct} direct report${direct === 1 ? "" : "s"}${total > direct ? ` · ${total} in the team` : ""} — ${folded ? "show" : "hide"}`}
76
+ onMouseDown={(e) => e.preventDefault()}
77
+ onPointerDown={(e) => e.stopPropagation()}
78
+ onClick={(e) => {
79
+ e.stopPropagation();
80
+ o.toggle(id);
81
+ }}
82
+ className={cx(
83
+ "nodrag nopan absolute top-full left-1/2 z-10 flex h-[22px] -translate-x-1/2 -translate-y-1/2 items-center gap-0.5 rounded-full border px-2 text-[11px] leading-none font-medium tabular-nums shadow-xs",
84
+ "transition-colors duration-150 motion-reduce:transition-none",
85
+ folded ? "border-primary/50 bg-card text-foreground hover:bg-accent" : "border-border bg-card text-muted-foreground hover:text-foreground",
86
+ )}
87
+ >
88
+ {folded ? `+${total}` : direct}
89
+ <Icon name={folded ? "chevron-down" : "chevron-up"} size={12} />
90
+ </button>
91
+ ) : null}
92
+ </div>
93
+ );
94
+ }
95
+
96
+ export const NODE_TYPES = { person: PersonNode };
@@ -0,0 +1,257 @@
1
+ # PageBuilder
2
+
3
+ A visual page editor in the workspace theme, calm like Webflow's canvas
4
+ without its cockpit. The page sits in the middle at desktop, tablet or
5
+ phone width. On the left, **Add** lists blocks as small wireframes —
6
+ sections (hero, features, logos, quote, pricing, questions, call to action,
7
+ footer) and basics (heading, text, button, image, two columns, list,
8
+ divider, space). Click one to add it below the selection, or drag it onto
9
+ the page. **Layers** shows the page as a tree: select, fold, hide while
10
+ editing. On the right, **Design** changes the selected element's look,
11
+ limited to the theme's choices: text colour, background, text size,
12
+ weight, typeface, alignment, spacing, width, corners and border. It also
13
+ edits a link's address or a picture's source and description, and moves,
14
+ duplicates or deletes the element. The top bar has the save state, the
15
+ device toggle, undo and redo, Preview and Save. A new page opens on a
16
+ friendly empty state with starter templates. On a narrow screen the
17
+ panels move to a bottom bar and open as sheets.
18
+
19
+ It is [GrapesJS](https://github.com/GrapesJS/grapesjs) (BSD-3-Clause, the
20
+ free core — never the commercial Studio SDK) with its React wrapper
21
+ [@grapesjs/react](https://github.com/GrapesJS/react) (MIT). GrapesJS does
22
+ the page model, the canvas, selection, drag and drop, text editing, undo
23
+ and the export. The panels, the top bar, the empty state and the Design
24
+ choices are ours, built from the kit. GrapesJS's own panels, style manager,
25
+ trait manager, asset modal and code viewer are never created. The blocks
26
+ built on this one — `landing-builder` first — import it, never `grapesjs`
27
+ directly.
28
+
29
+ ```jsx
30
+ import { PageBuilder, PageView } from "../components/blocks/page-builder"; // a Makersclaw app ("./blocks/page-builder" from components/)
31
+ import { PageBuilder, PageView } from "@/components/makersclaw/blocks/page-builder"; // a shadcn project
32
+ ```
33
+
34
+ `PageBuilder` is a client component: render it from a `"use client"`
35
+ component. `PageView` and the helpers (`pageDocument`, `cleanHtml`,
36
+ `cleanCss`, `isPageEmpty`, `projectSections`…) work on the server too.
37
+
38
+ `makersclaw add page-builder` adds `grapesjs` and `@grapesjs/react`
39
+ (pinned, exact) to package.json: run `npm install` after. They load with
40
+ the page, with no `import()`. The editor is created after the first render.
41
+ Until then, and on the server, the frame shows a skeleton.
42
+
43
+ ## The data
44
+
45
+ The builder hands out a page as three things. You get it from `onSave`,
46
+ from `onChange`, and from the handle's `getPage()`:
47
+
48
+ ```js
49
+ {
50
+ html: "<section class=\"pb-section pb-center\" …>…</section>…", // the body's content, cleaned
51
+ css: ".pb-section{padding:88px 24px;background-color:var(--color-background);…}#i4kd{…}",
52
+ project: { pages: [ … ], styles: [ … ], assets: [], … }, // GrapesJS project JSON
53
+ }
54
+ ```
55
+
56
+ - **Store `project`** (a `jsonb` column). It is what reopens the page for
57
+ editing: pass it back as `page={{ project }}`.
58
+ - **Show `html` + `css`** with `PageView`, or publish them. They are the
59
+ source of truth for what visitors see. They are derived from `project`
60
+ at save time, so store them next to it instead of recomputing them.
61
+ - `page={{ html, css }}` also opens, as a fresh project. This is how a
62
+ template, an import or an agent-written page starts.
63
+ - The HTML is cleaned: no `<script>`, no `on*` handlers, no `javascript:`
64
+ links. The CSS has no `body`, `html` or `*` rules. Only rules the page
65
+ uses are exported.
66
+
67
+ ### Pages keep the theme
68
+
69
+ **A page never holds a colour. It names theme tokens, so it repaints when
70
+ the theme changes.** Every Design choice writes a CSS variable:
71
+ `var(--color-primary)`, `var(--color-muted-foreground)`,
72
+ `var(--theme-font-display)`, `var(--theme-radius)`. These are the same
73
+ variables the app's Tailwind utilities read. The built-in blocks' CSS
74
+ (`BASE_CSS`, `pb-` classes) uses them too. Sizes and spacing are plain
75
+ `rem`/`px` steps.
76
+
77
+ - **In the editor**, the canvas is an iframe that cannot see the app's
78
+ stylesheet. The builder resolves each token where it sits (its light or
79
+ dark scheme and any `[data-theme]` scope) and writes the values into the
80
+ frame. It does this again when the theme changes. It also copies the
81
+ app's `@font-face` rules, so the page uses the theme's typefaces.
82
+ - **In the app**, `PageView` shows the page. The tokens resolve to the
83
+ workspace theme. Tailwind emits a theme variable only when some source
84
+ names it, so this block names every token a page may use
85
+ (`KEEP_TOKENS`). Installing the block is enough.
86
+ - **Outside the app** (a download, a static host),
87
+ `standaloneDocument(page, { root })` returns a full HTML document with
88
+ the tokens resolved and inlined. `pageDocument(page, { tokens })` is the
89
+ same function for the server, if you pass it the `:root{…}` string
90
+ yourself.
91
+
92
+ ## Props
93
+
94
+ | Prop | Default | |
95
+ | --- | --- | --- |
96
+ | `page` | empty | The page to open: `{ project }` or `{ html, css }`. Read once, when the editor is created. To open another page, change the component's `key` or call the handle's `setPage`. |
97
+ | `onSave` | — | `async (page) => ({ ok, error? })`. Called by Save and ⌘/Ctrl+S with `{ html, css, project }`. On `{ ok: false }`, the page stays unsaved and a toast shows your `error` with "Try again". The top bar says "Not saved". |
98
+ | `onChange` | — | `(page) => void`, 500 ms after the last edit. Use it for autosave or a live preview elsewhere. |
99
+ | `title` | `"Untitled page"` | The name in the top bar. |
100
+ | `blocks` | `[]` | Your own blocks, added after the built-ins. See "Your own sections". |
101
+ | `builtIns` | `true` | Which built-in blocks to offer: `true` (sections and basics), `"sections"`, `"basics"` or `false`. |
102
+ | `templates` | `STARTER_TEMPLATES` | Whole pages offered in the empty state and in "Start from a template". Pass `[]` for none. |
103
+ | `styles` | `STYLE_GROUPS` | The Design panel's choices. See "The Design choices". |
104
+ | `onUploadImage` | — | `async (file) => ({ ok, url, error? })`. When given, a picture's field gets an Upload button. Without it, people paste an address. |
105
+ | `actions` | — | Extra top-bar controls before Save, such as landing-builder's Publish. Use kit `Button`s at `size="sm"`. |
106
+ | `saveLabel` | `"Save"` | The Save button's words. |
107
+ | `builderRef` | — | A ref from `usePageBuilder()`. It receives the handle. |
108
+ | `height` | `720` | The builder's height: a number (px) or any CSS length (`"min(760px, 88dvh)"`). It fills its width. |
109
+ | `className` | — | Added to the frame. |
110
+
111
+ ### The handle
112
+
113
+ ```jsx
114
+ const builder = usePageBuilder();
115
+ <PageBuilder builderRef={builder} … />
116
+ builder.current?.getPage(); // { html, css, project }
117
+ ```
118
+
119
+ `getPage()` · `save()` (runs `onSave`, returns its result) ·
120
+ `addBlock(id)` · `loadTemplate(idOrTemplate)` · `setPage({ html, css } |
121
+ { project })` · `undo()` · `redo()` · `setDevice("desktop" | "tablet" |
122
+ "mobile")` · `preview(on = true)` · `editor` (the GrapesJS editor, for what
123
+ this block does not wrap; changes made through it are yours to keep
124
+ token-only).
125
+
126
+ ## Your own sections
127
+
128
+ This is how `landing-builder` builds on this block. A block is plain data:
129
+
130
+ ```js
131
+ const HERO_WAITLIST = {
132
+ id: "hero-waitlist", // unique across built-ins and yours
133
+ label: "Waitlist hero", // the tile's name
134
+ category: "Hero", // the Add panel's group heading
135
+ thumb: "split", // a wireframe from THUMB_NAMES
136
+ description: "Headline, one line and an email button.", // the tile's tooltip
137
+ level: "section", // "section": added between top-level sections ·
138
+ // "element": added inside the selected box
139
+ // (default: "section" when category is "Sections")
140
+ html: `<section class="lb-hero" data-gjs-name="Waitlist hero">…</section>`,
141
+ css: `.lb-hero{padding:96px 24px;background-color:var(--color-muted);color:var(--color-foreground)}`,
142
+ };
143
+ <PageBuilder blocks={[HERO_WAITLIST]} builtIns="basics" templates={LANDING_TEMPLATES} />
144
+ ```
145
+
146
+ - `html` is the markup, or use `content`, a GrapesJS component definition,
147
+ in its place. `data-gjs-name` names the element in Layers. Any
148
+ `data-gjs-*` attribute sets that GrapesJS property: for example,
149
+ `data-gjs-draggable="false"` or `data-gjs-removable="false"` lock a part.
150
+ - `css` is added to the page once, when the editor opens. **Name only
151
+ tokens for colour** (`var(--color-…)`, from `COLOR_TOKENS`) and
152
+ `--theme-font-*` / `--theme-radius` for faces and corners. Then your
153
+ sections repaint with the theme. Prefix your classes (`lb-`), and reuse
154
+ the built-in `pb-` classes (`pb-button`, `pb-h2`, `pb-lead`,
155
+ `pb-container`…) when they fit. Add an `@media (max-width: 768px)` rule
156
+ for the phone layout. The canvas's phone width is a real narrow frame,
157
+ so media queries work there.
158
+ - Several blocks may share one `css` string. The same rule added twice is
159
+ one rule.
160
+
161
+ A **template** is a whole page:
162
+ `{ id, label, description?, thumbs?: ["hero", "features", "cta"], html, css? }`
163
+ or `{ id, label, project }`. `thumbs` draws its card, up to four sections
164
+ tall. Picking a template replaces the page. A toast offers Undo when there
165
+ was something to replace.
166
+
167
+ `BlockThumb` and `PageThumb` draw the same wireframes elsewhere, for
168
+ example in a landing-builder gallery of templates.
169
+
170
+ ## The Design choices
171
+
172
+ `STYLE_GROUPS` is a list of groups. Each group is one row of choices:
173
+
174
+ ```js
175
+ {
176
+ id: "fill", label: "Background", kind: "swatch" | "segmented" | "select",
177
+ for: ["link", "box"], // which elements show it: text · link · image · box (all if left out)
178
+ match: "background-color", // the property read back to show the current choice
179
+ options: [
180
+ { value: "", label: "Default", css: { "background-color": "" } }, // "" = reset: the block's own CSS applies
181
+ { value: "primary", label: "Primary", css: { "background-color": "var(--color-primary)" } },
182
+ ],
183
+ }
184
+ ```
185
+
186
+ Picking an option writes its `css` onto that element only (an `#id`
187
+ rule). Any property another option of the group sets is cleared. "Reset"
188
+ beside a group removes the group's properties. "Clear this element's
189
+ style" removes all of them. To offer fewer or different choices, pass
190
+ your own list, filtered from or modelled on `STYLE_GROUPS`. A swatch
191
+ option's `value` is the token name it paints (`primary` →
192
+ `var(--color-primary)`). `groupsFor`, `currentOption` and `patchFor` are
193
+ the helpers the panel uses.
194
+
195
+ ## Mouse, keyboard and touch
196
+
197
+ - Click an element to select it. Double-click text to edit the words
198
+ (bold, italic and link in the small toolbar). Double-click a picture to
199
+ jump to its field. Drag the selected element's handle to move it.
200
+ - ⌘/Ctrl+S saves. ⌘/Ctrl+Z undoes, ⇧⌘Z redoes. Backspace or Delete
201
+ removes the selection (with Undo in a toast when done from the panel).
202
+ Esc leaves Preview.
203
+ - The block tiles, the layer tree (↑ ↓ to move, ← → to fold), the swatches
204
+ (arrow keys) and every control are reachable by keyboard. A tile adds
205
+ on Enter.
206
+ - On a phone, tap a tile to add it. Dragging is for a mouse.
207
+
208
+ ## Example
209
+
210
+ ```jsx
211
+ "use client";
212
+ import { useState } from "react";
213
+ import { PageBuilder, PageView } from "../components/blocks/page-builder";
214
+ import { saveRow } from "../lib/db";
215
+
216
+ export function LandingEditor({ row }) {
217
+ return (
218
+ <PageBuilder
219
+ key={row.id}
220
+ title={row.title}
221
+ page={row.project ? { project: row.project } : { html: row.html, css: row.css }}
222
+ onSave={async ({ html, css, project }) => {
223
+ const res = await saveRow("pages", row.id, { html, css, project });
224
+ return res.ok ? { ok: true } : { ok: false, error: "The page was not saved. Check your connection and try again." };
225
+ }}
226
+ />
227
+ );
228
+ }
229
+
230
+ // the public page, on the server:
231
+ export function LandingPage({ row }) {
232
+ return <PageView page={row} label={row.title} />;
233
+ }
234
+ ```
235
+
236
+ ## What it will not do
237
+
238
+ - No live multiplayer. Two people editing the same page is last save wins.
239
+ - No free colour picker, hex field or arbitrary CSS. The Design panel
240
+ offers the theme's choices only, by design. A block's own `css` is where
241
+ a fixed design lives.
242
+ - Styles apply at every width. The canvas's device toggle previews the
243
+ page's own media queries. It does not keep per-device overrides.
244
+ - No forms that submit, and no scripts. The HTML is cleaned of them. A
245
+ signup form belongs to the app (a block beside `PageView`), not to the
246
+ page.
247
+ - No asset library. Pictures are an address, or an upload through
248
+ `onUploadImage`.
249
+ - No publishing, domains or SEO fields. Those belong to `landing-builder`
250
+ and the app.
251
+
252
+ ## Credits
253
+
254
+ GrapesJS © Artur Arseniev, BSD-3-Clause. @grapesjs/react © Artur
255
+ Arseniev, MIT. Both are used unmodified, as npm dependencies. The block
256
+ ships none of their code. GrapesJS's stylesheet is imported from the
257
+ package and repainted with the workspace's tokens.
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "page-builder",
3
+ "title": "PageBuilder",
4
+ "description": "A visual page editor (GrapesJS core) in the workspace theme: our own clean panels instead of GrapesJS's chrome — an Add panel of section and basic blocks (click or drag), a Layers tree, a Design panel limited to theme-token choices (colours, type, spacing, width, corners, borders), a device toggle (desktop, tablet, phone), undo/redo, preview, and a friendly empty state with starter templates. Pages style with CSS variables, so a saved page repaints with the theme. Saves out as { html, css, project }; PageView shows a saved page in an app.",
5
+ "useWhen": "A screen where someone builds or edits a web page visually: a landing page, a waitlist or launch page, a simple site section, an announcement page. landing-builder is built on it (section templates, publishing). Not for rich text in a document (doc-editor), an email body (newsletter-builder), a form of fields (record-form) or a freeform drawing (sketch-canvas).",
6
+ "tags": ["page builder", "website builder", "landing page", "grapesjs", "visual editor", "drag and drop", "sections", "templates", "wysiwyg", "html", "css", "no-code", "web page", "layers"],
7
+ "exports": ["PageBuilder", "usePageBuilder", "readPage", "DEVICES", "PageView", "standaloneDocument", "BlockThumb", "PageThumb", "THUMB_NAMES", "BASE_CSS", "SECTION_BLOCKS", "BASIC_BLOCKS", "STARTER_TEMPLATES", "STYLE_GROUPS", "COLOR_TOKENS", "groupsFor", "currentOption", "patchFor", "tokenCss", "fontFaceCss", "fontLinks", "PAGE_BASE_CSS", "emptyPage", "isPageEmpty", "cleanHtml", "cleanCss", "normalizeBlock", "templatePage", "pageDocument", "projectSections"],
8
+ "files": ["index.js", "page-builder.jsx", "panels.jsx", "page-view.jsx", "thumbs.jsx", "grapes.js", "theme.js", "tokens.js", "sections.js", "page.js"],
9
+ "requires": [],
10
+ "dependencies": {
11
+ "grapesjs": "0.22.16",
12
+ "@grapesjs/react": "2.0.0"
13
+ }
14
+ }