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,430 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { Avatar, Button, Carousel, Empty, Icon, Image, Kicker, Rating, Skeleton, Stat, StatGroup, cx } from "../../ui";
5
+
6
+ // Testimonials — a marketing section of customer quotes: who said it
7
+ // (name, role, company, face or logo), the quote, an optional star
8
+ // rating, an optional "see it on X" source, and optional headline
9
+ // numbers beside them. Five layouts over the same rows: a grid of cards,
10
+ // one large quote, a switcher (press a face to swap the quote), a
11
+ // carousel (swipe, arrows, dots), and a carousel over a picture.
12
+ //
13
+ // <Testimonials title="Loved by small teams" items={quotes}
14
+ // stats={[{ label: "Teams", value: "4,200+" }]} />
15
+ //
16
+ // README.md beside this file lists every prop.
17
+
18
+ const COLUMNS = {
19
+ 1: "grid-cols-1",
20
+ 2: "grid-cols-1 sm:grid-cols-2",
21
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
22
+ 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
23
+ };
24
+
25
+ const LOOKS = {
26
+ card: "rounded-lg border border-border bg-card text-card-foreground p-6",
27
+ raised: "rounded-lg border border-border bg-card text-card-foreground p-6 shadow-lg",
28
+ plain: "",
29
+ };
30
+
31
+ // A network's name and the brand glyph drawn for it.
32
+ const NETWORKS = {
33
+ x: { label: "X", icon: "x-logo" },
34
+ linkedin: { label: "LinkedIn", icon: "linkedin" },
35
+ instagram: { label: "Instagram", icon: "instagram" },
36
+ youtube: { label: "YouTube", icon: "youtube" },
37
+ facebook: { label: "Facebook", icon: "facebook" },
38
+ github: { label: "GitHub", icon: "github" },
39
+ google: { label: "Google", icon: "google" },
40
+ };
41
+
42
+ const keyOf = (item, i) => item.id ?? `${i}-${item.name ?? ""}`;
43
+ const roleLine = (item) => [item.role, item.company].filter(Boolean).join(", ");
44
+
45
+ function Header({ kicker, title, description, align, action }) {
46
+ if (!kicker && !title && !description && !action) return null;
47
+ const center = align === "center";
48
+ return (
49
+ <div className={cx("grid gap-3", center ? "mx-auto max-w-2xl justify-items-center text-center" : "max-w-2xl")}>
50
+ {kicker ? <Kicker>{kicker}</Kicker> : null}
51
+ {title ? <h2 className="text-balance text-3xl font-semibold tracking-tight sm:text-4xl">{title}</h2> : null}
52
+ {description ? <p className="text-pretty text-base text-muted-foreground sm:text-lg">{description}</p> : null}
53
+ {action ? <div className="mt-2">{action}</div> : null}
54
+ </div>
55
+ );
56
+ }
57
+
58
+ function ActionButton({ action, className }) {
59
+ if (!action) return null;
60
+ return (
61
+ <Button variant="secondary" href={action.href} onClick={action.onClick} icon={action.icon ?? "plus"} className={className}>
62
+ {action.label}
63
+ </Button>
64
+ );
65
+ }
66
+
67
+ // Name (with a verified mark), then role and company, or the date.
68
+ function Byline({ item, size = "md", center, avatar = true }) {
69
+ const sub = roleLine(item);
70
+ return (
71
+ <figcaption className={cx("flex min-w-0 gap-3", center ? "flex-col items-center text-center" : "items-center")}>
72
+ {avatar ? <Avatar name={item.name} src={item.avatar} size={size === "lg" ? "lg" : "md"} /> : null}
73
+ <div className="min-w-0">
74
+ <p className={cx("flex items-center gap-1.5 font-semibold", center && "justify-center")}>
75
+ <span className="min-w-0 truncate">{item.name}</span>
76
+ {item.verified ? (
77
+ <span className="inline-flex shrink-0 text-primary">
78
+ <Icon name="circle-check" size={16} />
79
+ <span className="sr-only">Verified customer</span>
80
+ </span>
81
+ ) : null}
82
+ </p>
83
+ {sub ? <p className="text-sm text-muted-foreground">{sub}</p> : null}
84
+ {item.date && !item.source ? <p className="text-sm text-muted-foreground">{item.date}</p> : null}
85
+ </div>
86
+ </figcaption>
87
+ );
88
+ }
89
+
90
+ function Stars({ item, center }) {
91
+ if (item.rating == null) return null;
92
+ return (
93
+ <div className={cx("flex", center && "justify-center")}>
94
+ <Rating value={item.rating} size="sm" label={`${item.name}'s rating`} />
95
+ </div>
96
+ );
97
+ }
98
+
99
+ // "View on X" and the date, under a quote that was posted somewhere.
100
+ function Source({ item }) {
101
+ const s = item.source;
102
+ if (!s) return null;
103
+ const net = NETWORKS[s.network] ?? { label: s.label ?? "the source", icon: "external" };
104
+ return (
105
+ <div className="flex flex-wrap items-center justify-between gap-x-4 gap-y-1 border-t border-border pt-4 text-sm">
106
+ {s.href ? (
107
+ <Button variant="link" size="sm" href={s.href} tone="muted">
108
+ View on {s.label ?? net.label} <Icon name={net.icon} size={14} />
109
+ </Button>
110
+ ) : (
111
+ <span className="inline-flex items-center gap-1.5 text-muted-foreground">
112
+ On {s.label ?? net.label} <Icon name={net.icon} size={14} />
113
+ </span>
114
+ )}
115
+ {item.date ? <span className="text-muted-foreground">{item.date}</span> : null}
116
+ </div>
117
+ );
118
+ }
119
+
120
+ function QuoteCard({ item, look, center, bylineTop, quoteMark }) {
121
+ const byline = <Byline item={item} center={center} size={bylineTop && center ? "lg" : "md"} />;
122
+ return (
123
+ <figure
124
+ className={cx(
125
+ "flex h-full min-w-0 flex-col gap-4",
126
+ LOOKS[look] ?? LOOKS.card,
127
+ item.highlight && look !== "plain" && "border-primary ring-1 ring-primary",
128
+ center && "items-center text-center",
129
+ )}
130
+ >
131
+ {item.logo ? <div className={cx("flex min-h-10 items-center", center && "justify-center")}>{item.logo}</div> : null}
132
+ {bylineTop ? byline : null}
133
+ {!bylineTop ? <Stars item={item} center={center} /> : null}
134
+ {quoteMark ? <Icon name="quote" size={28} className="text-muted-foreground/50" /> : null}
135
+ <blockquote className={cx("text-pretty leading-relaxed", look === "plain" ? "text-muted-foreground" : "text-foreground")}>
136
+ {item.quote}
137
+ </blockquote>
138
+ <div className={cx("mt-auto grid gap-4", center && "justify-items-center")}>
139
+ {bylineTop ? <Stars item={item} center={center} /> : byline}
140
+ {item.href ? (
141
+ <Button variant="link" size="sm" href={item.href}>
142
+ {item.hrefLabel ?? "Read the story"} <Icon name="arrow-right" size={14} />
143
+ </Button>
144
+ ) : null}
145
+ <Source item={item} />
146
+ </div>
147
+ </figure>
148
+ );
149
+ }
150
+
151
+ function StatsStrip({ stats, center, className }) {
152
+ if (!stats?.length) return null;
153
+ return (
154
+ <StatGroup variant="divided" label="In numbers" className={cx(center && "mx-auto w-full max-w-3xl", className)}>
155
+ {stats.map((s, i) => (
156
+ <Stat key={s.label ?? i} label={s.label} value={s.value} unit={s.unit} caption={s.caption} size="lg" />
157
+ ))}
158
+ </StatGroup>
159
+ );
160
+ }
161
+
162
+ function Loading({ columns }) {
163
+ return (
164
+ <div aria-busy="true" aria-label="Loading testimonials" className={cx("grid gap-6", COLUMNS[columns] ?? COLUMNS[3])}>
165
+ {[0, 1, 2].map((i) => (
166
+ <div key={i} className="grid gap-4 rounded-lg border border-border bg-card p-6">
167
+ <Skeleton className="w-24" />
168
+ <Skeleton className="w-full" />
169
+ <Skeleton className="w-5/6" />
170
+ <Skeleton className="w-2/3" />
171
+ <div className="flex items-center gap-3 pt-2">
172
+ <Skeleton shape="circle" className="size-10" />
173
+ <div className="grid flex-1 gap-2">
174
+ <Skeleton className="w-1/2" />
175
+ <Skeleton className="w-1/3" />
176
+ </div>
177
+ </div>
178
+ </div>
179
+ ))}
180
+ </div>
181
+ );
182
+ }
183
+
184
+ function Grid({ items, columns, look, center, bylineTop, quoteMark, focusOnHover, action }) {
185
+ return (
186
+ <div
187
+ className={cx(
188
+ "grid gap-6",
189
+ COLUMNS[columns] ?? COLUMNS[3],
190
+ // One card lit, the rest dimmed, while the pointer is over one.
191
+ focusOnHover && "[&:has(>*:hover)>*:not(:hover)]:opacity-50 [&>*]:transition-opacity motion-reduce:[&>*]:transition-none",
192
+ )}
193
+ >
194
+ {items.map((item, i) => (
195
+ <div key={keyOf(item, i)} className={cx("min-w-0", item.wide && "sm:col-span-full")}>
196
+ <QuoteCard item={item} look={look} center={center} bylineTop={bylineTop} quoteMark={quoteMark} />
197
+ </div>
198
+ ))}
199
+ {action ? (
200
+ <div className="grid min-h-48 min-w-0">
201
+ <Button
202
+ variant="secondary"
203
+ href={action.href}
204
+ onClick={action.onClick}
205
+ className="h-full w-full flex-col gap-3 rounded-lg border-dashed"
206
+ >
207
+ <span className="grid size-14 place-items-center rounded-full bg-muted">
208
+ <Icon name={action.icon ?? "plus"} size={24} />
209
+ </span>
210
+ {action.label}
211
+ </Button>
212
+ </div>
213
+ ) : null}
214
+ </div>
215
+ );
216
+ }
217
+
218
+ // One quote, large: a picture or a logo on one side, the words on the
219
+ // other; with `stats`, the numbers take the picture's place.
220
+ function Single({ item, kicker, title, description, stats, look, action }) {
221
+ const heading = item.title ?? title;
222
+ const media = item.image ? (
223
+ <Image src={item.image} alt={item.imageAlt ?? ""} ratio="square" rounded="lg" className="w-full max-w-sm" />
224
+ ) : item.logo && look === "plain" ? (
225
+ <div className="grid min-h-40 place-items-center rounded-lg bg-muted p-8 text-2xl">{item.logo}</div>
226
+ ) : null;
227
+ const body = (
228
+ <div className="grid min-w-0 gap-5">
229
+ {kicker ? <Kicker>{kicker}</Kicker> : null}
230
+ {heading ? <h2 className="text-balance text-3xl font-semibold tracking-tight sm:text-4xl">{heading}</h2> : null}
231
+ {description && !heading ? <p className="text-muted-foreground">{description}</p> : null}
232
+ <Stars item={item} />
233
+ <blockquote className="text-pretty text-lg leading-relaxed text-foreground sm:text-xl">
234
+ <Icon name="quote" size={24} className="mb-3 block text-muted-foreground/50" />
235
+ {item.quote}
236
+ </blockquote>
237
+ <div className="flex flex-wrap items-center justify-between gap-4">
238
+ <Byline item={item} size="lg" />
239
+ {item.logo && look !== "plain" ? <div className="shrink-0">{item.logo}</div> : null}
240
+ </div>
241
+ {item.href ? (
242
+ <div>
243
+ <Button variant="link" href={item.href}>
244
+ {item.hrefLabel ?? "Read the story"} <Icon name="arrow-right" size={14} />
245
+ </Button>
246
+ </div>
247
+ ) : null}
248
+ {action ? (
249
+ <div>
250
+ <ActionButton action={action} />
251
+ </div>
252
+ ) : null}
253
+ </div>
254
+ );
255
+ const side = stats?.length ? (
256
+ <div className="grid content-center gap-6 sm:grid-cols-3 md:grid-cols-1 md:border-l md:border-border md:pl-10">
257
+ {stats.map((s, i) => (
258
+ <Stat key={s.label ?? i} label={s.label} value={s.value} unit={s.unit} caption={s.caption} size="lg" />
259
+ ))}
260
+ </div>
261
+ ) : media;
262
+ return (
263
+ <figure
264
+ className={cx(
265
+ "grid items-center gap-8",
266
+ side && "md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)]",
267
+ stats?.length && "md:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]",
268
+ look !== "plain" && "rounded-xl border border-border bg-card p-6 text-card-foreground sm:p-10",
269
+ )}
270
+ >
271
+ {stats?.length ? body : side}
272
+ {stats?.length ? side : body}
273
+ </figure>
274
+ );
275
+ }
276
+
277
+ // Press a face to show that person's quote.
278
+ function Switcher({ items, title, index, onIndex }) {
279
+ const item = items[index] ?? items[0];
280
+ return (
281
+ <div className="grid items-center gap-8 md:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]">
282
+ <div className="grid min-w-0 gap-5">
283
+ {title ? <h2 className="text-balance text-3xl font-semibold tracking-tight sm:text-4xl">{title}</h2> : null}
284
+ <figure className="grid gap-5" aria-live="polite">
285
+ <Stars item={item} />
286
+ <blockquote className="max-w-2xl text-pretty text-lg leading-relaxed text-muted-foreground">{item.quote}</blockquote>
287
+ <Byline item={item} avatar={false} />
288
+ </figure>
289
+ <div role="group" aria-label="Choose a customer" className="flex flex-wrap items-center gap-2">
290
+ {items.map((it, i) => (
291
+ <Button
292
+ key={keyOf(it, i)}
293
+ variant="quiet"
294
+ iconOnly
295
+ aria-pressed={i === index}
296
+ aria-label={`${it.name}${it.company ? `, ${it.company}` : ""}`}
297
+ onClick={() => onIndex(i)}
298
+ className={cx("rounded-lg transition-opacity", i === index ? "ring-2 ring-primary" : "opacity-60 hover:opacity-100")}
299
+ >
300
+ <Avatar name={it.name} src={it.avatar} shape="square" size="md" label="" />
301
+ </Button>
302
+ ))}
303
+ </div>
304
+ </div>
305
+ <div className="hidden justify-center md:flex">
306
+ {item.image ? (
307
+ <Image src={item.image} alt={item.imageAlt ?? item.name} ratio="portrait" rounded="lg" className="w-full max-w-72" />
308
+ ) : (
309
+ <div className="grid aspect-[3/4] w-full max-w-72 place-items-center rounded-lg bg-muted">
310
+ <Avatar name={item.name} src={item.avatar} size="lg" className="scale-150" />
311
+ </div>
312
+ )}
313
+ </div>
314
+ </div>
315
+ );
316
+ }
317
+
318
+ function Slide({ item }) {
319
+ return (
320
+ <figure className="mx-auto grid max-w-3xl justify-items-center gap-6 px-2 py-6 text-center sm:px-12">
321
+ {item.logo ? <div className="flex min-h-10 items-center justify-center text-xl">{item.logo}</div> : null}
322
+ <Stars item={item} center />
323
+ <blockquote className="text-pretty text-lg font-medium leading-relaxed sm:text-2xl">&ldquo;{item.quote}&rdquo;</blockquote>
324
+ <Byline item={item} center />
325
+ </figure>
326
+ );
327
+ }
328
+
329
+ function Slides({ items, look, background, backgroundAlt, onIndex }) {
330
+ const carousel = (
331
+ <Carousel label="Customer quotes" loop onChange={onIndex}>
332
+ {items.map((item, i) => (
333
+ <Slide key={keyOf(item, i)} item={item} />
334
+ ))}
335
+ </Carousel>
336
+ );
337
+ if (!background && look === "plain") return carousel;
338
+ if (!background)
339
+ return <div className={cx(LOOKS[look] ?? LOOKS.card, "rounded-xl px-2 py-6 sm:px-8")}>{carousel}</div>;
340
+ return (
341
+ <div className="relative isolate overflow-hidden rounded-xl border border-border">
342
+ <div className="absolute inset-0 -z-10">
343
+ <Image src={background} alt={backgroundAlt ?? ""} rounded="none" className="h-full w-full" />
344
+ </div>
345
+ <div className="bg-background/85 px-4 py-8 backdrop-blur-sm sm:px-10 sm:py-12">{carousel}</div>
346
+ </div>
347
+ );
348
+ }
349
+
350
+ export function Testimonials({
351
+ items,
352
+ layout = "grid",
353
+ kicker,
354
+ title,
355
+ description,
356
+ align,
357
+ stats,
358
+ columns = 3,
359
+ look = "card",
360
+ cardAlign = "start",
361
+ byline = "bottom",
362
+ quoteMark = false,
363
+ focusOnHover = false,
364
+ action,
365
+ background,
366
+ backgroundAlt,
367
+ defaultIndex = 0,
368
+ onIndexChange,
369
+ loading = false,
370
+ empty,
371
+ label,
372
+ className,
373
+ }) {
374
+ const list = (items ?? []).filter((it) => it && it.quote);
375
+ const [index, setIndex] = useState(Math.min(defaultIndex, Math.max(0, list.length - 1)));
376
+ const pick = (i) => {
377
+ setIndex(i);
378
+ onIndexChange?.(i);
379
+ };
380
+ const headAlign = align ?? (layout === "switcher" || layout === "single" ? "start" : "center");
381
+ const singleOwnsHeader = layout === "single" || layout === "switcher";
382
+
383
+ let body;
384
+ if (loading) body = <Loading columns={columns} />;
385
+ else if (list.length === 0)
386
+ body = (
387
+ <Empty
388
+ icon="quote"
389
+ title={empty?.title ?? "No reviews yet"}
390
+ body={empty?.body ?? "What customers say about you will show here."}
391
+ action={action ? <ActionButton action={action} /> : null}
392
+ />
393
+ );
394
+ else if (layout === "single")
395
+ body = <Single item={list[index] ?? list[0]} kicker={kicker} title={title} description={description} stats={stats} look={look} action={action} />;
396
+ else if (layout === "switcher") body = <Switcher items={list} title={title} index={Math.min(index, list.length - 1)} onIndex={pick} />;
397
+ else if (layout === "carousel") body = <Slides items={list} look={look} background={background} backgroundAlt={backgroundAlt} onIndex={onIndexChange} />;
398
+ else
399
+ body = (
400
+ <Grid
401
+ items={list}
402
+ columns={columns}
403
+ look={look}
404
+ center={cardAlign === "center"}
405
+ bylineTop={byline === "top"}
406
+ quoteMark={quoteMark}
407
+ focusOnHover={focusOnHover}
408
+ action={action}
409
+ />
410
+ );
411
+
412
+ const showHeader = !singleOwnsHeader || loading || list.length === 0;
413
+ return (
414
+ <section aria-label={label ?? (typeof title === "string" ? title : "Testimonials")} className={cx("px-4 py-16 sm:px-6 sm:py-20", className)}>
415
+ <div className="mx-auto grid w-full max-w-6xl gap-10 sm:gap-12">
416
+ {showHeader ? (
417
+ <Header
418
+ kicker={kicker}
419
+ title={title}
420
+ description={description}
421
+ align={headAlign}
422
+ action={list.length && layout === "carousel" ? <ActionButton action={action} /> : null}
423
+ />
424
+ ) : null}
425
+ {!loading && list.length && layout !== "single" ? <StatsStrip stats={stats} center={headAlign === "center"} /> : null}
426
+ {body}
427
+ </div>
428
+ </section>
429
+ );
430
+ }
@@ -0,0 +1,126 @@
1
+ # TransactionList
2
+
3
+ Money records as a plain list in a card. There are two variants:
4
+
5
+ - `history` (the default) — payments in and out, grouped by month. Each
6
+ row has a mark (received, paid, pending, failed, refunded), the name,
7
+ the date and a signed amount.
8
+ - `invoices` — one row per invoice: its number and date, a badge (Paid,
9
+ Due in 12 days, Due today, 3 days overdue, Void), the amount and a
10
+ download button.
11
+
12
+ The header can hold a date-range filter and an Export button. It is a
13
+ list, not a table: there are no columns and no sorting, so the rows show
14
+ in the order they come in (newest first, usually).
15
+
16
+ ```jsx
17
+ import { TransactionList } from "../components/blocks/transaction-list"; // a Makersclaw app ("./blocks/transaction-list" from components/)
18
+ import { TransactionList } from "@/components/makersclaw/blocks/transaction-list"; // a shadcn project
19
+ ```
20
+
21
+ It is a client component: render it from a `"use client"` component, and
22
+ load the rows in the server surface (README §4).
23
+
24
+ ## The data
25
+
26
+ A history row:
27
+
28
+ ```js
29
+ { id: "tx_1", name: "Northwind Ltd", date: "2026-09-21T12:30:00Z", amount: 2500, direction: "in", status: "completed", description: "Invoice #1042" }
30
+ ```
31
+
32
+ - `date` — `"YYYY-MM-DD"`, or an ISO timestamp (then the time shows too).
33
+ Months group by its first seven characters.
34
+ - `amount` — a number in the currency's major unit. The sign is drawn
35
+ from `direction` (`"in"` · `"out"`); without one, a negative amount is
36
+ money out.
37
+ - `status` — `completed` (the default), `pending`, `failed` (struck
38
+ through), `refunded`.
39
+ - `description` — a short line before the date. `currency` — per row,
40
+ over the `currency` prop.
41
+
42
+ An invoice row:
43
+
44
+ ```js
45
+ { id: "inv_24", number: "INV-0024", date: "2026-09-15", dueDate: "2026-10-15", amount: 2500, status: "open" }
46
+ ```
47
+
48
+ - `status` — `paid`, `open` (then the badge counts the days to or past
49
+ `dueDate`), `overdue` (when there is no due date), `void`, `draft`,
50
+ `cancelled`.
51
+ - `name` — who it is for; shown before the date when `number` is set.
52
+
53
+ ## Props
54
+
55
+ - `rows` — the records, in the order to show.
56
+ - `variant` — `"history"` (default) or `"invoices"`.
57
+ - `currency` — default `"USD"`. `locale` — money and dates, default the
58
+ reader's.
59
+ - `groupBy` — `"month"` (the default for history) or `"none"` (the
60
+ default for invoices).
61
+ - `title` · `description` — the card's heading; default "Transactions" or
62
+ "Invoices".
63
+ - `dateFilter` — `true` shows a date-range picker in the header (with
64
+ presets). The block hides rows outside the range itself; `range` +
65
+ `onRangeChange(range)` control it (`{ from, to }` or `null`) when the
66
+ surface loads by date instead.
67
+ - `onExport(rows, range)` — an Export button; it gets the rows on screen.
68
+ Return `{ ok: false, error }` to say why it failed.
69
+ - `onDownload(row)` — a download button on each row (make the PDF, open
70
+ it); same return, the reason shows under the row. Or
71
+ `downloadHref(row)` — a link instead (return `null` for a row with none).
72
+ - `onOpen(row)` — the row's name becomes a button (open your `Sheet`).
73
+ - `loading` — skeleton rows. `error` — a line above the list.
74
+ - `emptyTitle` · `emptyBody` — the empty state's words.
75
+ - `today` — `"YYYY-MM-DD"`, the day an invoice's due date is counted
76
+ from; default today.
77
+ - `className` — layout around it (width, margin). Never colour.
78
+
79
+ ## Example
80
+
81
+ ```jsx
82
+ // components/Billing.jsx — client
83
+ "use client";
84
+ import { TransactionList } from "./blocks/transaction-list";
85
+
86
+ export default function Billing({ invoices, payments, error }) {
87
+ return (
88
+ <div className="grid gap-6 lg:grid-cols-2">
89
+ <TransactionList
90
+ variant="invoices"
91
+ rows={invoices}
92
+ error={error}
93
+ description="Every invoice we have sent you."
94
+ downloadHref={(inv) => inv.pdfUrl}
95
+ />
96
+ <TransactionList
97
+ rows={payments}
98
+ dateFilter
99
+ description="Money in and out of the account."
100
+ onExport={async (rows) => {
101
+ const csv = rows.map((r) => [r.date, r.name, r.amount].join(",")).join("\n");
102
+ const url = URL.createObjectURL(new Blob([csv], { type: "text/csv" }));
103
+ Object.assign(document.createElement("a"), { href: url, download: "payments.csv" }).click();
104
+ return { ok: true };
105
+ }}
106
+ />
107
+ </div>
108
+ );
109
+ }
110
+ ```
111
+
112
+ ## What it will not do
113
+
114
+ - Sort, page, or filter by column: rows come in ordered, and a record set
115
+ that needs those is a `data-table`.
116
+ - Total the rows: put a `Stat` above it if a sum matters.
117
+ - Make the invoice PDF or the export file: `onDownload` and `onExport`
118
+ are the app's.
119
+
120
+ A list it cannot be is your own component in `components/`, built from
121
+ the kit — not an edit to this block. Its files are fixed: `npm run check`
122
+ refuses a change, and `makersclaw add transaction-list` restores them.
123
+
124
+ ## Credits
125
+
126
+ Shape and behaviour from Creative Tim UI (https://github.com/creativetimofficial/ui), MIT; this is a rewrite on the Makersclaw kit.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "transaction-list",
3
+ "title": "TransactionList",
4
+ "description": "Money records as a plain list, in two variants: history (payments in and out, grouped by month, a received / paid / pending / failed mark and a signed amount) and invoices (number, date, a Paid / Due in N days / N days overdue badge, amount, download). Optional date-range filter, Export and per-row download. Empty, loading and error states built in.",
5
+ "useWhen": "A billing page's invoices, an account's payment history, a wallet's recent activity: records read top to bottom, newest first. Not for records the founder sorts, filters by column or totals (data-table), or for one order (order-detail).",
6
+ "tags": ["transactions", "payments", "history", "invoices", "billing", "receipts", "money", "ledger", "activity", "statement", "download", "export", "finance"],
7
+ "exports": ["TransactionList"],
8
+ "files": ["index.js", "transaction-list.jsx"],
9
+ "requires": []
10
+ }
@@ -0,0 +1,79 @@
1
+ "use client";
2
+
3
+ // TransactionList with rows in memory — the gallery's and the smoke
4
+ // test's surface. Not installed into apps.
5
+ import { useState } from "react";
6
+ import { Switch, ToggleGroup } from "../components/ui";
7
+ import { TransactionList } from "../components/blocks/transaction-list";
8
+
9
+ const HISTORY = [
10
+ { id: "tx_1", name: "Northwind Ltd", description: "Invoice INV-0024", date: "2026-09-21T12:30:00Z", amount: 2500, direction: "in" },
11
+ { id: "tx_2", name: "Figma", description: "Team plan", date: "2026-09-19T09:05:00Z", amount: 180, direction: "out" },
12
+ { id: "tx_3", name: "Globex Corp", description: "Invoice INV-0023", date: "2026-09-16T15:45:00Z", amount: 1750, direction: "in", status: "pending" },
13
+ { id: "tx_4", name: "Vercel", description: "Pro", date: "2026-09-02T07:00:00Z", amount: 20, direction: "out", status: "failed" },
14
+ { id: "tx_5", name: "Initech", description: "Invoice INV-0021", date: "2026-08-28T11:20:00Z", amount: 2990, direction: "in" },
15
+ { id: "tx_6", name: "Google Workspace", description: "6 seats", date: "2026-08-14T08:00:00Z", amount: 84, direction: "out" },
16
+ { id: "tx_7", name: "Acme Ltd", description: "Overpayment", date: "2026-08-03T16:10:00Z", amount: 250, direction: "out", status: "refunded" },
17
+ ];
18
+
19
+ const INVOICES = [
20
+ { id: "inv_24", number: "INV-0024", name: "Northwind Ltd", date: "2026-09-15", dueDate: "2026-10-15", amount: 2500, status: "paid" },
21
+ { id: "inv_23", number: "INV-0023", name: "Globex Corp", date: "2026-09-10", dueDate: "2026-10-10", amount: 1750, status: "open" },
22
+ { id: "inv_22", number: "INV-0022", name: "Umbrella", date: "2026-09-01", dueDate: "2026-09-23", amount: 1500, status: "open" },
23
+ { id: "inv_21", number: "INV-0021", name: "Initech", date: "2026-08-20", dueDate: "2026-09-20", amount: 2990, status: "open" },
24
+ { id: "inv_20", number: "INV-0020", name: "Hooli", date: "2026-08-15", dueDate: "2026-09-14", amount: 3500, status: "void" },
25
+ ];
26
+
27
+ const VIEWS = [
28
+ { value: "history", label: "History" },
29
+ { value: "invoices", label: "Invoices" },
30
+ { value: "empty", label: "Empty" },
31
+ { value: "loading", label: "Loading" },
32
+ ];
33
+
34
+ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
35
+
36
+ export default function TransactionListDemo() {
37
+ const [view, setView] = useState("history");
38
+ const [failing, setFailing] = useState(false);
39
+ const [said, setSaid] = useState(null);
40
+
41
+ const act = (what) => async (arg) => {
42
+ await wait(500);
43
+ if (failing) return { ok: false, error: "The file could not be made. Try again." };
44
+ setSaid(`${what} was called${Array.isArray(arg) ? ` with ${arg.length} rows` : arg?.name ? ` for ${arg.number ?? arg.name}` : ""}.`);
45
+ return { ok: true };
46
+ };
47
+
48
+ const invoices = view === "invoices";
49
+
50
+ return (
51
+ <div className="grid gap-6">
52
+ <div className="flex flex-wrap items-center justify-between gap-3">
53
+ <ToggleGroup items={VIEWS} value={view} onChange={setView} size="sm" aria-label="Which list to show" />
54
+ <Switch id="tx-fail" checked={failing} onChange={(e) => setFailing(e.target.checked)} label="Make actions fail" />
55
+ </div>
56
+ {said ? (
57
+ <p role="status" className="text-sm text-muted-foreground">
58
+ {said}
59
+ </p>
60
+ ) : null}
61
+ <div className="max-w-2xl">
62
+ <TransactionList
63
+ key={view}
64
+ variant={invoices ? "invoices" : "history"}
65
+ rows={view === "empty" ? [] : invoices ? INVOICES : HISTORY}
66
+ loading={view === "loading"}
67
+ currency="USD"
68
+ locale="en-US"
69
+ today="2026-09-23"
70
+ description={invoices ? "Every invoice sent this quarter." : "Money in and out of the account."}
71
+ dateFilter={!invoices}
72
+ onExport={act("onExport")}
73
+ onDownload={act("onDownload")}
74
+ onOpen={(row) => setSaid(`onOpen was called for ${row.number ?? row.name}.`)}
75
+ />
76
+ </div>
77
+ </div>
78
+ );
79
+ }
@@ -0,0 +1,4 @@
1
+ // The TransactionList block — `makersclaw add transaction-list`. Fixed:
2
+ // compose it through its props (README.md beside this file); a list it
3
+ // cannot be is your own component in components/.
4
+ export { TransactionList } from "./transaction-list";