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,37 @@
1
+ // The one door to react-pdf (MIT) and pdf.js (pdfjs-dist, Apache-2.0).
2
+ // Every file in this block reaches them through here, and the blocks built
3
+ // on this one reach them through PdfViewer — never the packages directly.
4
+ //
5
+ // The order of the imports is the point: the text and annotation layers'
6
+ // stylesheets, then ssr-shim.js (stand-ins for the browser globals pdf.js
7
+ // reads while it loads — only on the server, where they are missing),
8
+ // react-pdf, then ssr-shim-end.js, which takes them away again. Keep them
9
+ // together and in this order.
10
+ //
11
+ // THE WORKER. pdf.js parses PDFs in a Web Worker, and must be told the
12
+ // worker script's URL. The usual answers are a file copied into public/
13
+ // (a file the app has to own and keep in step with the package) or a CDN
14
+ // (a runtime fetch from someone else's server, blocked by a strict CSP).
15
+ // Neither: `new URL("pdfjs-dist/build/pdf.worker.min.mjs", import.meta.url)`
16
+ // is a pattern the bundler (webpack in Next, and Turbopack, Vite, Parcel
17
+ // alike) recognises at BUILD time: it resolves the package's worker file,
18
+ // emits it as a hashed asset under /_next/static/media/, and replaces the
19
+ // expression with that asset's URL (the app's base path included). So the
20
+ // worker ships with the app, is always the same version as the pdf.js that
21
+ // calls it, and is served from the app's own origin. No import(), so the
22
+ // app's one-static-bundle check is happy.
23
+ //
24
+ // It is set here, after react-pdf has loaded, because react-pdf sets its
25
+ // own default when it loads and the later assignment must win. Only in the
26
+ // browser: the server never parses a PDF.
27
+ import "react-pdf/dist/Page/TextLayer.css";
28
+ import "react-pdf/dist/Page/AnnotationLayer.css";
29
+ import "./ssr-shim";
30
+ import { Document, Page, pdfjs } from "react-pdf";
31
+ import "./ssr-shim-end";
32
+
33
+ if (typeof window !== "undefined") {
34
+ pdfjs.GlobalWorkerOptions.workerSrc = new URL("pdfjs-dist/build/pdf.worker.min.mjs", import.meta.url).toString();
35
+ }
36
+
37
+ export { Document, Page, pdfjs };
@@ -0,0 +1,6 @@
1
+ // Server only: removes the stand-ins ssr-shim.js laid, right after
2
+ // react-pdf and pdf.js have loaded (see ssr-shim.js). Does nothing in the
3
+ // browser.
4
+ import { removeShim } from "./ssr-shim";
5
+
6
+ removeShim();
@@ -0,0 +1,44 @@
1
+ // Server only: stand-ins for the few browser globals pdf.js's viewer
2
+ // module reads WHILE IT LOADS. See pdfjs.js for why this exists.
3
+ //
4
+ // react-pdf imports pdfjs-dist/web/pdf_viewer.mjs (for its link service),
5
+ // and that module runs browser code at the top level:
6
+ // window.requestAnimationFrame, document.documentElement.style,
7
+ // document.createElement("div") (a CSS feature probe), and react-pdf reads
8
+ // window.location. On the server those throw "window is not defined" and
9
+ // the page fails to render — though the viewer itself only ever renders in
10
+ // the browser (the mount guard). The app is one static bundle (no
11
+ // import(), no next/dynamic), so the module cannot be kept off the server;
12
+ // it is let load against these stand-ins instead — the same trick as
13
+ // sketch-canvas's ssr-shim.js.
14
+ //
15
+ // They live only for that load: pdfjs.js imports this file, then
16
+ // react-pdf, then ssr-shim-end.js, which removes them — module evaluation
17
+ // is synchronous, so no other code runs in between. If the load throws,
18
+ // the microtask below removes them anyway, so a global `window` never
19
+ // outlives it. In the browser `window` exists and this file does nothing.
20
+ const G = globalThis;
21
+ const SET = [];
22
+
23
+ function stand(name, value) {
24
+ if (typeof G[name] !== "undefined") return;
25
+ G[name] = value;
26
+ SET.push(name);
27
+ }
28
+
29
+ if (typeof window === "undefined") {
30
+ const element = () => ({ style: {}, dataset: {}, classList: { add() {}, remove() {}, toggle() {} }, setAttribute() {}, appendChild() {} });
31
+ stand("window", { location: { protocol: "", href: "", origin: "" }, devicePixelRatio: 1, requestAnimationFrame: () => 0 });
32
+ stand("document", { createElement: element, documentElement: element(), head: element(), body: element() });
33
+ G.__pdfViewerShim = SET;
34
+ queueMicrotask(() => {
35
+ if (G.__pdfViewerShim === SET) removeShim();
36
+ });
37
+ }
38
+
39
+ export function removeShim() {
40
+ const set = G.__pdfViewerShim;
41
+ if (!set) return;
42
+ for (const name of set) delete G[name];
43
+ delete G.__pdfViewerShim;
44
+ }
@@ -0,0 +1,217 @@
1
+ # Product detail
2
+
3
+ One product on its own page: its pictures, name, price, rating, the
4
+ options a customer picks (size, colour, plan), how many, and **Add to
5
+ cart**. The add goes out through `onAddToCart(line)`; while it runs the
6
+ button spins, when it fails the block says why and nothing else changes,
7
+ when it works it says what was added. Details (description, care,
8
+ shipping) sit under the buy box in an accordion or tabs.
9
+
10
+ ```jsx
11
+ import { ProductDetail } from "../components/blocks/product-detail"; // a Makersclaw app ("./blocks/product-detail" from components/)
12
+ import { ProductDetail } from "@/components/makersclaw/blocks/product-detail"; // a shadcn project
13
+ ```
14
+
15
+ It is a client component: render it from a `"use client"` component, and
16
+ load the product in the server surface (README §4).
17
+
18
+ ## The data
19
+
20
+ A **product** is one plain object. Only `id`, `name` and `price` are
21
+ needed; everything else draws a part when it is there.
22
+
23
+ ```js
24
+ {
25
+ id: "tee-linen", // required
26
+ name: "Linen camp shirt", // required
27
+ price: 68, // required: a number in the currency's major unit (68 = $68.00)
28
+ compareAt: 85, // the old price, struck through, with "20% off"
29
+ currency: "USD", // else the block's `currency`
30
+ image: "https://…", // one picture, or:
31
+ images: ["https://…", { src: "https://…", alt: "The back" }],
32
+ brand: "Harbor & Pine", // a small line over the name
33
+ badge: "New", // an outlined label beside it
34
+ description: "…",
35
+ rating: 4.6, reviews: 214, // stars (halves) and the count
36
+ href: "/shop/tee-linen", // where the product lives (carried into the cart line)
37
+ available: false, // sold out: the button says so and is off
38
+ stock: 3, // the quantity control stops here
39
+ options: [ // what the customer picks, in order
40
+ { key: "size", label: "Size", values: ["S", "M", "L", { value: "XL", disabled: true }] },
41
+ { key: "color", label: "Colour", values: [{ value: "sand", label: "Sand", color: "#d8c8a8" }] },
42
+ ],
43
+ selected: { size: "M" }, // the first choices (else the first open value of each)
44
+ details: [{ key: "care", title: "Care", content: "Cold wash…" }], // content: text or a node
45
+ perks: [{ icon: "truck", label: "Free shipping over $100" }],
46
+ stats: [{ value: "1,234", label: "sales" }],
47
+ scene: "https://…", // gallery="overlay": the wide picture the buy box floats on
48
+ }
49
+ ```
50
+
51
+ An option's **values** are strings or `{ value, label?, color?, price?,
52
+ compareAt?, per?, description?, badge?, disabled? }`. How an option is
53
+ drawn follows its values (or its `display`):
54
+
55
+ - `color` on the values → **swatches** (colour squares; the chosen name
56
+ in the heading). The colour is data, drawn by the kit's `Swatch`.
57
+ - up to 6 short values → **buttons**, a segmented row (sizes).
58
+ - more, or longer → **select**, the native one.
59
+ - `price` or `description` on the values → **plans**, a card each. The
60
+ chosen value's `price` replaces the product's (a licence, a bigger box).
61
+
62
+ `disabled: true` on a value marks it sold out: struck through, not
63
+ choosable.
64
+
65
+ ### The cart line
66
+
67
+ `onAddToCart` and `onBuyNow` get one **line**, the same shape the `cart`
68
+ block takes as an item, so a surface can push it straight into its cart
69
+ rows:
70
+
71
+ ```js
72
+ {
73
+ id: "tee-linen",
74
+ key: "tee-linen:size=M:color=sand", // one cart row per product + choices
75
+ name: "Linen camp shirt",
76
+ price: 68, compareAt: 85, currency: "USD",
77
+ image: "https://…",
78
+ href: "/shop/tee-linen",
79
+ quantity: 2,
80
+ selected: { size: "M", color: "sand" }, // machine values, for your order row
81
+ variant: "M · Sand", // what the cart prints under the name
82
+ }
83
+ ```
84
+
85
+ `cartLine(product, selected, quantity, currency)` builds the same line
86
+ anywhere else (a grid's quick add).
87
+
88
+ ## Props
89
+
90
+ - `product` — the product above. `null` (and not loading) shows "No
91
+ product here".
92
+ - `onAddToCart(line)` — put the line in the cart; return `{ ok: true }` or
93
+ `{ ok: false, error }` (a throw counts as failed, its message shown).
94
+ Without it the button is off.
95
+ - `gallery` — how the pictures sit: `"thumbs"` (default: one large, a
96
+ row of thumbnails under it) · `"rail"` (thumbnails in a column beside
97
+ it from lg up) · `"carousel"` (one at a time, swipe, arrows, dots) ·
98
+ `"stack"` (every picture, the buy box sticky beside them) ·
99
+ `"overlay"` (one wide `scene` picture with the buy box floating over it
100
+ from lg up; under it on a phone).
101
+ - `details` — `"accordion"` (default; the first section open) or `"tabs"`.
102
+ - `onBuyNow(line)` — a second button that goes straight to checkout
103
+ (open Paddle there); `{ ok }` as above. Absent: no button.
104
+ - `onFavorite(product, next)` — shows a heart toggle; `next` is true to
105
+ save, false to remove. It flips at once and flips back, with the
106
+ error, when the save fails. `favorite` — its starting state.
107
+ - `onViewCart()` — a "View cart" button in the added message.
108
+ - `breadcrumb` — `[{ label, href? }]`, drawn above with the kit's
109
+ `Breadcrumb`.
110
+ - `perks` — `[{ icon, label }]` under the buttons (else `product.perks`).
111
+ `icon` is a kit `Icon` name: `truck`, `refresh`, `shield-check`, `package`.
112
+ - `quantity` — `false` hides the quantity control (a download); default
113
+ `true`. `maxQuantity` — the most at once (10; `product.stock` caps it).
114
+ - `currency` — default `"USD"`. `locale` — for prices and counts
115
+ (default: the reader's).
116
+ - `imageFit` — `"cover"` (default, cropped to the square) or `"contain"`
117
+ (the whole picture, on a muted fill: packshots on white, screenshots).
118
+ - `loading` — skeletons in the page's shape. `error` (a string) — the
119
+ load failed; `onRetry` adds "Try again".
120
+ - `addLabel` (`"Add to cart"`) · `buyLabel` (`"Buy now"`) — the words.
121
+ - `headingLevel` — the name's heading, `2` by default; `1` when the block
122
+ IS the page.
123
+ - `className` — layout around it (width, margin). Never colour.
124
+
125
+ The parts are exported for a page of your own: `ProductMedia({ product,
126
+ layout, fit })`, `OptionPicker({ option, value, onChange })`,
127
+ `QuantityControl({ value, onChange, min, max })`, `Price({ price,
128
+ compareAt, currency })`, `formatPrice(amount, currency, locale)`.
129
+
130
+ ## Example
131
+
132
+ ```jsx
133
+ // surfaces/product.jsx — server: load, hand over
134
+ import { loadRow } from "../lib/data";
135
+ import ProductPage from "../components/ProductPage";
136
+
137
+ export default async function ProductSurface({ params }) {
138
+ const { row, error } = await loadRow({ source: "public.products", id: params.id });
139
+ return <ProductPage product={row} error={error} />;
140
+ }
141
+ ```
142
+
143
+ ```jsx
144
+ // components/ProductPage.jsx — client: the page, the cart write
145
+ "use client";
146
+ import { insertRow } from "../lib/actions";
147
+ import { ProductDetail } from "./blocks/product-detail";
148
+
149
+ export default function ProductPage({ product, error }) {
150
+ return (
151
+ <ProductDetail
152
+ product={product}
153
+ error={error}
154
+ breadcrumb={[{ label: "Shop", href: "/shop" }, { label: product?.name ?? "Product" }]}
155
+ perks={[
156
+ { icon: "truck", label: "Free shipping over $100" },
157
+ { icon: "refresh", label: "30-day returns" },
158
+ ]}
159
+ onAddToCart={(line) =>
160
+ insertRow({
161
+ source: "public.cart_items",
162
+ values: { product_id: line.id, line_key: line.key, quantity: line.quantity, selected: line.selected },
163
+ detail: `${line.quantity} × ${line.name}`,
164
+ })
165
+ }
166
+ />
167
+ );
168
+ }
169
+ ```
170
+
171
+ A digital product with plans, no quantity, and a straight-to-checkout
172
+ button:
173
+
174
+ ```jsx
175
+ <ProductDetail
176
+ product={{
177
+ id: "ui-kit",
178
+ name: "Dashboard UI kit",
179
+ price: 49,
180
+ images: ["https://…/cover.png"],
181
+ rating: 4.9,
182
+ reviews: 127,
183
+ stats: [{ value: "1,234", label: "sales" }],
184
+ options: [{
185
+ key: "licence",
186
+ label: "Licence",
187
+ values: [
188
+ { value: "solo", label: "Solo", price: 49, description: "One maker, unlimited projects." },
189
+ { value: "team", label: "Team", price: 149, badge: "Popular", description: "Up to 10 seats." },
190
+ ],
191
+ }],
192
+ }}
193
+ quantity={false}
194
+ imageFit="contain"
195
+ onAddToCart={addToCart}
196
+ onBuyNow={(line) => openPaddleCheckout(line)}
197
+ />
198
+ ```
199
+
200
+ ## What it will not do
201
+
202
+ - Take payment. "Buy now" hands the line to `onBuyNow`; checkout is
203
+ Paddle's, and no card field is ever drawn here.
204
+ - Keep the cart. It hands over one line; the cart's rows, totals and
205
+ merging live in your data and the `cart` block.
206
+ - Show similar products or reviews in full: put a `ProductGrid` (the
207
+ `product-grid` block) and your review list under it.
208
+ - Colour itself: swatch colours are data; everything else is the theme.
209
+
210
+ A product page it cannot be is your own component in `components/`, built
211
+ from the kit (and this block's exported parts) — not an edit to this
212
+ block. Its files are fixed: `npm run check` refuses a change, and
213
+ `makersclaw add product-detail` restores them.
214
+
215
+ ## Credits
216
+
217
+ Ported from Creative Tim UI (https://github.com/creativetimofficial/ui), MIT — a rewrite on the Makersclaw kit, none of its code, copy or pictures.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "product-detail",
3
+ "title": "Product detail",
4
+ "description": "One product on its own page: pictures (thumbnails, a side rail, a carousel, a tall stack, or one scene with the buy box floating over it), brand, name, price with the old price struck through, star rating and review count, options (sizes as a segmented row, colours as swatches, long lists as a select, plans as cards with their own price), a quantity control, add to cart through an async callback that may fail, buy now, save to favourites, perks, and details in an accordion or tabs. Loading, error, not-found and sold-out states.",
5
+ "useWhen": "Selling one thing a customer looks at before buying: a product page, a template or digital download with plans, a merch item, a booking add-on. Not for many products at once (product-grid), the cart itself (cart), or a plan comparison table.",
6
+ "tags": ["product", "shop", "store", "ecommerce", "commerce", "buy", "add to cart", "price", "rating", "size", "colour", "variant", "quantity", "gallery", "carousel", "plans", "favourite", "pdp"],
7
+ "exports": ["ProductDetail", "ProductMedia", "OptionPicker", "QuantityControl", "Price", "formatPrice", "cartLine"],
8
+ "files": ["index.js", "product-detail.jsx", "product-media.jsx", "product-options.jsx", "price.jsx"],
9
+ "requires": []
10
+ }
@@ -0,0 +1,233 @@
1
+ "use client";
2
+
3
+ // The product page with its data in memory — the gallery's and the smoke
4
+ // test's surface. Not installed into apps: `makersclaw add product-detail`
5
+ // lays the block's files only. Every variant (each a source layout it was
6
+ // ported from) is one choice in the switcher.
7
+ import { useState } from "react";
8
+ import { Field, Select, ToggleGroup } from "../components/ui";
9
+ import { ProductDetail } from "../components/blocks/product-detail";
10
+
11
+ const pic = (seed, w = 900, h = 900) => `https://picsum.photos/seed/${seed}/${w}/${h}`;
12
+
13
+ const SHIRT = {
14
+ id: "camp-shirt",
15
+ name: "Linen camp shirt",
16
+ brand: "Harbor & Pine",
17
+ price: 68,
18
+ rating: 4.5,
19
+ reviews: 214,
20
+ description: "Washed linen with a relaxed collar and a straight hem, cut to wear open over a tee or buttoned on its own.",
21
+ images: [pic("mc-shirt-1"), pic("mc-shirt-2"), pic("mc-shirt-3"), pic("mc-shirt-4")],
22
+ options: [
23
+ { key: "size", label: "Size", values: ["XS", "S", "M", "L", "XL", { value: "XXL", disabled: true }] },
24
+ {
25
+ key: "color",
26
+ label: "Colour",
27
+ values: [
28
+ { value: "sand", label: "Sand", color: "tan" },
29
+ { value: "white", label: "Chalk", color: "whitesmoke" },
30
+ { value: "olive", label: "Olive", color: "darkolivegreen" },
31
+ ],
32
+ },
33
+ ],
34
+ selected: { size: "M" },
35
+ details: [
36
+ { key: "about", title: "About the shirt", content: "Mid-weight European linen, garment washed so it is soft from the first wear. Corozo buttons, a single chest pocket, and a back pleat for room across the shoulders." },
37
+ { key: "delivery", title: "Delivery and returns", content: "Free standard delivery on orders over $100, usually in three to five working days. Return anything unworn within 30 days." },
38
+ { key: "help", title: "Questions", content: "Write to help@harborpine.example and a person replies within a working day." },
39
+ ],
40
+ };
41
+
42
+ const COAT = {
43
+ id: "wool-overcoat",
44
+ name: "Double-faced wool overcoat",
45
+ brand: "Northfold",
46
+ badge: "Limited run",
47
+ price: 420,
48
+ rating: 4,
49
+ reviews: 88,
50
+ description: "A single-breasted overcoat in double-faced wool: no lining, so it drapes, and warm enough for a city winter.",
51
+ images: [pic("mc-coat-1"), pic("mc-coat-2"), pic("mc-coat-3"), pic("mc-coat-4")],
52
+ options: [
53
+ {
54
+ key: "color",
55
+ label: "Colour",
56
+ values: [
57
+ { value: "charcoal", label: "Charcoal", color: "dimgray" },
58
+ { value: "camel", label: "Camel", color: "peru" },
59
+ { value: "navy", label: "Navy", color: "midnightblue" },
60
+ ],
61
+ },
62
+ { key: "size", label: "Size", values: ["34", "36", "38", "40", "42", "44", "46"] },
63
+ ],
64
+ perks: [
65
+ { icon: "truck", label: "Free shipping over $150" },
66
+ { icon: "refresh", label: "30-day returns" },
67
+ { icon: "shield-check", label: "Two-year guarantee" },
68
+ { icon: "package", label: "Ships in recycled card" },
69
+ ],
70
+ details: [
71
+ { key: "features", title: "Features", content: "Hand-finished edges, a two-button front, welt pockets and an inside pocket sized for a phone." },
72
+ { key: "care", title: "Care", content: "Dry clean only. Brush after wearing and hang on a shaped hanger to keep the shoulders." },
73
+ { key: "shipping", title: "Shipping and returns", content: "Ships in two working days. Returns are free within 30 days in original condition." },
74
+ { key: "warranty", title: "Warranty", content: "Seams and buttons are covered for two years. Write to us with a photo and we repair or replace it." },
75
+ ],
76
+ };
77
+
78
+ const JUG = {
79
+ id: "stoneware-jug",
80
+ name: "Stoneware water jug",
81
+ brand: "Kiln Street",
82
+ badge: "New",
83
+ price: 54,
84
+ compareAt: 72,
85
+ rating: 5,
86
+ reviews: 127,
87
+ description: "Thrown by hand and glazed inside and out, with a pinched spout that pours without a drip.",
88
+ images: [pic("mc-jug-1"), pic("mc-jug-2"), pic("mc-jug-3")],
89
+ scene: pic("mc-jug-room", 1600, 900),
90
+ perks: [{ icon: "truck", label: "Free shipping on orders over $100" }],
91
+ details: [
92
+ { key: "features", title: "Features", content: "Holds 1.2 litres. Dishwasher safe; the unglazed foot is sanded smooth so it will not mark a table." },
93
+ { key: "care", title: "Care", content: "Rinse after use. A little vinegar lifts limescale from the inside." },
94
+ { key: "shipping", title: "Shipping", content: "Double boxed. If it arrives chipped, send a photo and we send another." },
95
+ ],
96
+ };
97
+
98
+ const BAG = {
99
+ id: "crossbody-bag",
100
+ name: "Vegetable-tanned crossbody",
101
+ brand: "Atelier Rue",
102
+ badge: "Trending",
103
+ price: 185,
104
+ rating: 4.7,
105
+ reviews: 342,
106
+ description: "A small bag in vegetable-tanned leather that darkens as it is used. A magnetic flap, one inside zip pocket, and a strap that adjusts.",
107
+ images: [pic("mc-bag-1"), pic("mc-bag-2"), pic("mc-bag-3"), pic("mc-bag-4"), pic("mc-bag-5")],
108
+ options: [
109
+ {
110
+ key: "color",
111
+ label: "Colour",
112
+ values: [
113
+ { value: "black", label: "Black", color: "black" },
114
+ { value: "tan", label: "Tan", color: "sienna" },
115
+ { value: "forest", label: "Forest", color: "seagreen" },
116
+ { value: "stone", label: "Stone", color: "silver", disabled: true },
117
+ ],
118
+ },
119
+ ],
120
+ perks: [
121
+ { icon: "package", label: "Full-grain leather" },
122
+ { icon: "pin", label: "Made in Portugal" },
123
+ ],
124
+ details: [{ key: "more", title: "More information", content: "23 × 17 × 7 cm. The strap drops 50 to 60 cm. Wipe with a dry cloth; condition twice a year." }],
125
+ };
126
+
127
+ const KIT = {
128
+ id: "admin-kit",
129
+ name: "Admin dashboard kit",
130
+ badge: "Best seller",
131
+ price: 49,
132
+ rating: 4.9,
133
+ reviews: 127,
134
+ description: "Sixty screens and the components behind them, ready to drop into a project: tables, charts, settings and sign-in.",
135
+ images: [pic("mc-kit-1", 1200, 900), pic("mc-kit-2", 1200, 900)],
136
+ stats: [
137
+ { value: "4.9/5", label: "rating" },
138
+ { value: "1,234", label: "sales" },
139
+ ],
140
+ options: [
141
+ {
142
+ key: "licence",
143
+ label: "Choose your licence",
144
+ values: [
145
+ { value: "html", label: "HTML", price: 39, per: "one-time", description: "Static pages with the styles compiled." },
146
+ { value: "react", label: "React", price: 49, per: "one-time", badge: "Popular", description: "Components with props and typed data." },
147
+ { value: "team", label: "Team", price: 149, per: "one-time", description: "React, for up to ten people." },
148
+ ],
149
+ },
150
+ ],
151
+ selected: { licence: "react" },
152
+ };
153
+
154
+ const VARIANTS = [
155
+ { value: "simple", label: "Simple — thumbs, accordion", product: SHIRT, props: { gallery: "thumbs" } },
156
+ { value: "description", label: "Description — selects, perks", product: COAT, props: { gallery: "thumbs", breadcrumb: [{ label: "Shop", href: "#shop" }, { label: "Outerwear", href: "#outerwear" }, { label: COAT.name }] } },
157
+ { value: "carousel", label: "Carousel", product: SHIRT, props: { gallery: "carousel", breadcrumb: [{ label: "Shop", href: "#shop" }, { label: SHIRT.name }] } },
158
+ { value: "complex", label: "Complex — side rail, long details", product: COAT, props: { gallery: "rail", onBuyNow: true } },
159
+ { value: "tabs", label: "Tabs — sale price", product: JUG, props: { gallery: "thumbs", details: "tabs" } },
160
+ { value: "stack", label: "Stack — sticky buy box", product: BAG, props: { gallery: "stack", onBuyNow: true, quantity: false } },
161
+ { value: "plans", label: "Digital — plans", product: KIT, props: { gallery: "thumbs", imageFit: "contain", quantity: false, onBuyNow: true } },
162
+ { value: "overlay", label: "Overlay — room scene", product: JUG, props: { gallery: "overlay" } },
163
+ ];
164
+
165
+ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
166
+
167
+ export default function ProductDetailDemo() {
168
+ const [variant, setVariant] = useState("simple");
169
+ const [state, setState] = useState("ready");
170
+ const [cart, setCart] = useState([]);
171
+ const v = VARIANTS.find((x) => x.value === variant) ?? VARIANTS[0];
172
+ const failing = state === "fails";
173
+
174
+ async function addToCart(line) {
175
+ await wait(700);
176
+ if (failing) return { ok: false, error: "The cart is not answering. Nothing was added — try again." };
177
+ setCart((all) => {
178
+ const hit = all.find((l) => l.key === line.key);
179
+ return hit ? all.map((l) => (l.key === line.key ? { ...l, quantity: l.quantity + line.quantity } : l)) : [...all, line];
180
+ });
181
+ return { ok: true };
182
+ }
183
+ async function buyNow() {
184
+ await wait(700);
185
+ return failing ? { ok: false, error: "Checkout did not open. Try again in a moment." } : { ok: true };
186
+ }
187
+ async function favorite() {
188
+ await wait(400);
189
+ return failing ? { ok: false, error: "Favourites are not saving right now." } : { ok: true };
190
+ }
191
+
192
+ const { onBuyNow, ...props } = v.props;
193
+ const count = cart.reduce((n, l) => n + l.quantity, 0);
194
+
195
+ return (
196
+ <div className="grid gap-6">
197
+ <div className="flex flex-wrap items-end gap-3">
198
+ <Field id="pd-variant" label="Layout" className="w-full sm:w-72">
199
+ <Select id="pd-variant" value={variant} onChange={(e) => setVariant(e.target.value)} options={VARIANTS.map(({ value, label }) => ({ value, label }))} />
200
+ </Field>
201
+ <ToggleGroup
202
+ size="sm"
203
+ aria-label="Demo state"
204
+ value={state}
205
+ onChange={setState}
206
+ items={[
207
+ { value: "ready", label: "Ready" },
208
+ { value: "fails", label: "Fails" },
209
+ { value: "loading", label: "Loading" },
210
+ { value: "error", label: "Error" },
211
+ { value: "missing", label: "Gone" },
212
+ ]}
213
+ />
214
+ <p data-nums className="text-sm text-muted-foreground sm:ml-auto">
215
+ Cart: {count} {count === 1 ? "item" : "items"}
216
+ </p>
217
+ </div>
218
+
219
+ <ProductDetail
220
+ key={variant}
221
+ product={state === "missing" ? null : v.product}
222
+ loading={state === "loading"}
223
+ error={state === "error" ? "The shop's database did not answer." : undefined}
224
+ onRetry={() => setState("ready")}
225
+ onAddToCart={addToCart}
226
+ onBuyNow={onBuyNow ? buyNow : undefined}
227
+ onFavorite={favorite}
228
+ onViewCart={() => {}}
229
+ {...props}
230
+ />
231
+ </div>
232
+ );
233
+ }
@@ -0,0 +1,7 @@
1
+ // The Product detail block — `makersclaw add product-detail`. Fixed:
2
+ // compose it through its props (README.md beside this file); a product
3
+ // page it cannot be is your own component in components/.
4
+ export { ProductDetail } from "./product-detail";
5
+ export { ProductMedia } from "./product-media";
6
+ export { OptionPicker, QuantityControl } from "./product-options";
7
+ export { Price, formatPrice, cartLine } from "./price";