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,33 @@
1
+ // The PdfDocument block — `makersclaw add pdf-document`. Fixed: compose it
2
+ // through its props (README.md beside this file). Themed PDF primitives,
3
+ // a ready invoice/quote layout, and renderPdf(doc) → Blob. The blocks that
4
+ // print (quote-builder, proposal-accept…) import this one, never
5
+ // @react-pdf/renderer directly. The sums and formatters in money.js and
6
+ // the theme maths in theme.js run anywhere, the server included.
7
+ export { renderPdf, usePdf, PdfDownloadButton, downloadBlob, registerPdfFont } from "./pdf-document";
8
+ export {
9
+ PdfDocument,
10
+ PdfStack,
11
+ PdfRow,
12
+ PdfCol,
13
+ PdfText,
14
+ PdfHeading,
15
+ PdfLabel,
16
+ PdfField,
17
+ PdfDivider,
18
+ PdfCallout,
19
+ PdfBadge,
20
+ PdfTable,
21
+ PdfTotals,
22
+ PdfLines,
23
+ PdfView,
24
+ PdfRawText,
25
+ PdfImage,
26
+ PdfLink,
27
+ PdfThemeProvider,
28
+ usePdfTheme,
29
+ PDF_TYPE,
30
+ } from "./primitives";
31
+ export { QuoteDocument } from "./quote";
32
+ export { quoteTotals, lineAmount, round2, formatMoney, formatQuantity, formatPdfDate } from "./money";
33
+ export { resolvePdfTheme, buildPdfTheme, DEFAULT_PDF_THEME } from "./theme";
@@ -0,0 +1,83 @@
1
+ // Quote and invoice sums — plain functions, so a server action, a test or
2
+ // the quote builder's live preview all get the same numbers the PDF prints.
3
+ //
4
+ // Amounts are in the currency's major unit (dollars, not cents) and every
5
+ // sum is rounded to the cent line by line, the way an accountant writes
6
+ // it: each line's amount is rounded, then added.
7
+
8
+ /** Round to 2 decimals without the 1.005 → 1.00 float trap. */
9
+ export const round2 = (n) => Math.round((Number(n) + Number.EPSILON) * 100) / 100;
10
+
11
+ const num = (v) => {
12
+ const n = typeof v === "string" ? Number(v.replace(/[, ]/g, "")) : Number(v);
13
+ return Number.isFinite(n) ? n : 0;
14
+ };
15
+
16
+ /** One line's amount: quantity × unit price, less its own discount (%). */
17
+ export function lineAmount(item) {
18
+ const gross = num(item?.quantity ?? 1) * num(item?.unitPrice);
19
+ const off = item?.discountPercent ? (gross * num(item.discountPercent)) / 100 : 0;
20
+ return round2(gross - off);
21
+ }
22
+
23
+ /** The sums of a quote or invoice.
24
+ *
25
+ * items [{ description, quantity, unitPrice, discountPercent?,
26
+ * taxable? (default true) }]
27
+ * discount { percent } or { amount } off the subtotal (optional)
28
+ * taxRate percent, on the taxable lines after the discount (optional)
29
+ * paid what has already been paid (an invoice's deposit)
30
+ *
31
+ * → { lines: [amount…], subtotal, discount, tax, total, paid, due } */
32
+ export function quoteTotals({ items = [], discount, taxRate, paid } = {}) {
33
+ const lines = items.map(lineAmount);
34
+ const subtotal = round2(lines.reduce((s, a) => s + a, 0));
35
+ const taxableBase = round2(lines.reduce((s, a, i) => (items[i]?.taxable === false ? s : s + a), 0));
36
+ let off = 0;
37
+ if (discount?.percent) off = round2((subtotal * num(discount.percent)) / 100);
38
+ else if (discount?.amount) off = round2(Math.min(num(discount.amount), subtotal));
39
+ // The discount is shared across lines in proportion, so tax falls on
40
+ // what is actually charged for the taxable ones.
41
+ const share = subtotal > 0 ? taxableBase / subtotal : 0;
42
+ const tax = taxRate ? round2(((taxableBase - off * share) * num(taxRate)) / 100) : 0;
43
+ const total = round2(subtotal - off + tax);
44
+ const already = round2(num(paid));
45
+ return { lines, subtotal, discount: off, tax, total, paid: already, due: round2(total - already) };
46
+ }
47
+
48
+ // Characters the PDF's built-in faces (WinAnsi) cannot draw, which Intl
49
+ // puts in some locales' numbers: narrow and no-break spaces, the Unicode
50
+ // minus. Swapped for their plain forms.
51
+ const PLAIN = [
52
+ [/[   ]/g, " "],
53
+ [/−/g, "-"],
54
+ ];
55
+
56
+ /** 1234.5 → "$1,234.50" in `currency` and `locale`, drawable by the PDF's
57
+ * built-in fonts. A bad currency code falls back to the plain number. */
58
+ export function formatMoney(amount, currency = "USD", locale = "en-US") {
59
+ let out;
60
+ try {
61
+ out = new Intl.NumberFormat(locale, { style: "currency", currency, minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(num(amount));
62
+ } catch {
63
+ out = `${num(amount).toFixed(2)} ${currency ?? ""}`.trim();
64
+ }
65
+ for (const [re, to] of PLAIN) out = out.replace(re, to);
66
+ return out;
67
+ }
68
+
69
+ /** A quantity as people write it: 3, 1.5, 0.25 — no trailing zeros. */
70
+ export function formatQuantity(q, locale = "en-US") {
71
+ const out = new Intl.NumberFormat(locale, { maximumFractionDigits: 3 }).format(num(q));
72
+ return PLAIN.reduce((s, [re, to]) => s.replace(re, to), out);
73
+ }
74
+
75
+ /** "2026-09-23" (or a Date) → "23 Sep 2026" in `locale`; "" when empty.
76
+ * A bare date string is read as that calendar day, not as UTC midnight. */
77
+ export function formatPdfDate(value, locale = "en-GB") {
78
+ if (!value) return "";
79
+ const d = value instanceof Date ? value : /^\d{4}-\d{2}-\d{2}$/.test(String(value)) ? new Date(`${value}T12:00:00`) : new Date(value);
80
+ if (Number.isNaN(d.getTime())) return String(value);
81
+ const out = new Intl.DateTimeFormat(locale, { day: "numeric", month: "short", year: "numeric" }).format(d);
82
+ return PLAIN.reduce((s, [re, to]) => s.replace(re, to), out);
83
+ }
@@ -0,0 +1,144 @@
1
+ "use client";
2
+
3
+ // Making the PDF: renderPdf turns a document (the primitives, or
4
+ // QuoteDocument) into a Blob in the workspace's theme; usePdf keeps one
5
+ // fresh while its data changes (a live preview); PdfDownloadButton is the
6
+ // "Download PDF" a screen puts beside it.
7
+ //
8
+ // The theme is read from the page at the moment of rendering (./theme.js):
9
+ // a PDF cannot read CSS variables, so its colours are written in as values.
10
+ // @react-pdf/renderer lays the document out in JS (no browser print, no
11
+ // server), in the browser or in node alike.
12
+ import { useCallback, useEffect, useRef, useState } from "react";
13
+ import { Font, pdf } from "@react-pdf/renderer";
14
+ import { Button, toast } from "../../ui";
15
+ import { PdfThemeProvider } from "./primitives";
16
+ import { buildPdfTheme, resolvePdfTheme } from "./theme";
17
+
18
+ let hyphenationOff = false;
19
+
20
+ /** Render a PDF document to a Blob.
21
+ *
22
+ * doc a <PdfDocument>…</PdfDocument> or <QuoteDocument … /> element
23
+ * options theme a theme from resolvePdfTheme/buildPdfTheme (default:
24
+ * read from the page now; the fallback on the server)
25
+ * root the element whose theme to read (default <body>)
26
+ * scheme "paper" (default: white paper, the theme's accent)
27
+ * or "theme" (the workspace's own background and ink)
28
+ *
29
+ * Resolves to a Blob of type application/pdf; rejects when the document
30
+ * cannot be laid out (a broken image URL, a font that will not load). */
31
+ export async function renderPdf(doc, { theme, root, scheme = "paper" } = {}) {
32
+ if (!hyphenationOff) {
33
+ // Whole words only: a business document never splits "invoice" as
34
+ // "in-voice" at a line end.
35
+ Font.registerHyphenationCallback((word) => [word]);
36
+ hyphenationOff = true;
37
+ }
38
+ const t = theme ?? (typeof document === "undefined" ? buildPdfTheme({}, { scheme }) : resolvePdfTheme(root, { scheme }));
39
+ return pdf(<PdfThemeProvider theme={t}>{doc}</PdfThemeProvider>).toBlob();
40
+ }
41
+
42
+ /** Use a brand face in PDFs: registerPdfFont({ family: "Inter", regular:
43
+ * url, bold: url }) — TTF or WOFF files the browser can fetch — then pass
44
+ * `font: { family: "Inter", bold: "Inter-Bold" }` to buildPdfTheme, or
45
+ * let renderPdf's theme carry it. Without one, PDFs use Helvetica, which
46
+ * every reader has built in (it draws Latin text; for other scripts or
47
+ * symbols like ₹, register a font that has them). */
48
+ export function registerPdfFont({ family, regular, bold }) {
49
+ if (!family || !regular) return null;
50
+ Font.register({ family, src: regular });
51
+ if (bold) Font.register({ family: `${family}-Bold`, src: bold });
52
+ return { family, bold: bold ? `${family}-Bold` : family };
53
+ }
54
+
55
+ /** Keep a PDF of `build()` up to date: a live preview.
56
+ *
57
+ * const { url, blob, loading, error, refresh } = usePdf(() => <QuoteDocument {...q} />, [q]);
58
+ *
59
+ * Re-renders `delay` ms (default 400) after the deps settle, so typing in
60
+ * a form does not lay out a PDF per key. `url` is an object URL for the
61
+ * current Blob (revoked when it is replaced); `error` is the last
62
+ * failure, cleared by the next success. `options` go to renderPdf. */
63
+ export function usePdf(build, deps = [], { delay = 400, enabled = true, ...options } = {}) {
64
+ const [state, setState] = useState({ blob: null, url: null, loading: enabled, error: null });
65
+ const buildRef = useRef(build);
66
+ buildRef.current = build;
67
+ const optsRef = useRef(options);
68
+ optsRef.current = options;
69
+ const urlRef = useRef(null);
70
+ const run = useRef(0);
71
+ const [tick, setTick] = useState(0);
72
+
73
+ useEffect(() => {
74
+ if (!enabled) return undefined;
75
+ const id = ++run.current;
76
+ setState((s) => ({ ...s, loading: true }));
77
+ const timer = setTimeout(async () => {
78
+ try {
79
+ const blob = await renderPdf(buildRef.current(), optsRef.current);
80
+ if (id !== run.current) return;
81
+ const url = URL.createObjectURL(blob);
82
+ if (urlRef.current) URL.revokeObjectURL(urlRef.current);
83
+ urlRef.current = url;
84
+ setState({ blob, url, loading: false, error: null });
85
+ } catch (error) {
86
+ if (id !== run.current) return;
87
+ setState((s) => ({ ...s, loading: false, error }));
88
+ }
89
+ }, delay);
90
+ return () => clearTimeout(timer);
91
+ // eslint-disable-next-line react-hooks/exhaustive-deps
92
+ }, [enabled, delay, tick, ...deps]);
93
+
94
+ useEffect(
95
+ () => () => {
96
+ run.current++;
97
+ if (urlRef.current) URL.revokeObjectURL(urlRef.current);
98
+ },
99
+ [],
100
+ );
101
+
102
+ const refresh = useCallback(() => setTick((n) => n + 1), []);
103
+ return { ...state, refresh };
104
+ }
105
+
106
+ /** Save a Blob as a file, the way a download link would. */
107
+ export function downloadBlob(blob, fileName = "document.pdf") {
108
+ if (typeof document === "undefined" || !blob) return;
109
+ const url = URL.createObjectURL(blob);
110
+ // raw: an <a download> is how a browser saves a Blob; it is never shown.
111
+ const a = document.createElement("a");
112
+ a.href = url;
113
+ a.download = fileName;
114
+ a.rel = "noopener";
115
+ document.body.appendChild(a);
116
+ a.click();
117
+ a.remove();
118
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
119
+ }
120
+
121
+ /** A "Download PDF" button: renders `document` (an element, or a function
122
+ * returning one) when pressed, then saves it as `fileName`. Busy while it
123
+ * renders; a failure says so in a toast and the button is ready again.
124
+ * Other props (variant, size, icon, label, disabled) are the kit
125
+ * Button's; `options` go to renderPdf. */
126
+ export function PdfDownloadButton({ document: doc, fileName = "document.pdf", label = "Download PDF", icon = "download", variant = "secondary", size = "md", options, disabled, className }) {
127
+ const [busy, setBusy] = useState(false);
128
+ const onClick = async () => {
129
+ setBusy(true);
130
+ try {
131
+ const blob = await renderPdf(typeof doc === "function" ? doc() : doc, options);
132
+ downloadBlob(blob, fileName);
133
+ } catch (e) {
134
+ toast.error("Couldn't make the PDF", { description: e?.message ? `${e.message}. Try again in a moment.` : "Try again in a moment." });
135
+ } finally {
136
+ setBusy(false);
137
+ }
138
+ };
139
+ return (
140
+ <Button variant={variant} size={size} icon={icon} loading={busy} disabled={disabled || !doc} onClick={onClick} className={className}>
141
+ {label}
142
+ </Button>
143
+ );
144
+ }
@@ -0,0 +1,271 @@
1
+ "use client";
2
+
3
+ // The PDF primitives: a small set of parts that draw a clean business
4
+ // document in the workspace's theme. They render INSIDE a PDF (the
5
+ // @react-pdf/renderer tree), never into the page: compose them into a
6
+ // document and pass it to renderPdf (./pdf-document) or PdfDownloadButton.
7
+ //
8
+ // Every colour comes from the theme in context (./theme.js — resolved from
9
+ // the workspace's CSS variables when the PDF is made); a part takes a
10
+ // `tone` name, never a colour. Type is one family (Helvetica, built into
11
+ // every PDF reader, unless a brand font is registered) at a few fixed
12
+ // sizes, on a 4pt rhythm.
13
+ import { createContext, useContext } from "react";
14
+ import { Document, Image, Link, Page, Text, View } from "@react-pdf/renderer";
15
+ import { DEFAULT_PDF_THEME } from "./theme";
16
+
17
+ const ThemeContext = createContext(DEFAULT_PDF_THEME);
18
+
19
+ /** Wraps a PDF tree in a theme; renderPdf does this for you. */
20
+ export function PdfThemeProvider({ theme, children }) {
21
+ return <ThemeContext.Provider value={theme ?? DEFAULT_PDF_THEME}>{children}</ThemeContext.Provider>;
22
+ }
23
+
24
+ /** The theme the PDF is being drawn with (./theme.js buildPdfTheme). */
25
+ export function usePdfTheme() {
26
+ return useContext(ThemeContext);
27
+ }
28
+
29
+ /** The type scale, in points. Body is 9.5pt: a business document is read
30
+ * at arm's length, and this is the size a good invoice uses. */
31
+ export const PDF_TYPE = { xs: 7.5, sm: 8.5, md: 9.5, lg: 12, xl: 16, xxl: 24 };
32
+
33
+ const TONE = (t, tone) =>
34
+ ({ default: t.ink, muted: t.muted, accent: t.accentInk, success: t.success, warning: t.warning, danger: t.danger, info: t.info, onAccent: t.onAccent })[tone] ?? t.ink;
35
+
36
+ // Body leading, set on each text (a leading on the page is measured wrong
37
+ // by the layout and lines overlap).
38
+ const LEADING = 1.4; // always with an explicit fontSize: the leading is read against it
39
+
40
+ const MARGINS = { compact: 36, normal: 48, roomy: 64 };
41
+
42
+ /** The document: one flowing page (it breaks onto more by itself), the
43
+ * brand's accent bar along the top edge, and a footer with the page
44
+ * count on every page.
45
+ *
46
+ * title, author, subject the PDF's properties (a reader shows title)
47
+ * size "A4" (default) · "LETTER" · "LEGAL" · [width, height] pt
48
+ * landscape false
49
+ * margin compact (36pt) · normal (48pt, default) · roomy (64pt)
50
+ * accentBar true: a 4pt bar of the accent along the top of each page
51
+ * footer a line at the foot of each page (left); the page count
52
+ * sits at the right. null: no footer at all. */
53
+ export function PdfDocument({ title, author, subject, size = "A4", landscape = false, margin = "normal", accentBar = true, footer, children }) {
54
+ const t = usePdfTheme();
55
+ const m = MARGINS[margin] ?? MARGINS.normal;
56
+ return (
57
+ <Document title={title} author={author} subject={subject} creator={author} producer={author}>
58
+ <Page
59
+ size={size}
60
+ orientation={landscape ? "landscape" : "portrait"}
61
+ style={{ paddingTop: m, paddingBottom: m + (footer === null ? 0 : 20), paddingHorizontal: m, backgroundColor: t.paper, color: t.ink, fontFamily: t.font, fontSize: PDF_TYPE.md }}
62
+ >
63
+ {accentBar ? <View fixed style={{ position: "absolute", top: 0, left: 0, right: 0, height: 4, backgroundColor: t.accent }} /> : null}
64
+ {children}
65
+ {footer === null ? null : (
66
+ <View fixed style={{ position: "absolute", bottom: m - 16, left: m, right: m, flexDirection: "row", justifyContent: "space-between", fontSize: PDF_TYPE.xs, color: t.muted }}>
67
+ <Text>{footer ?? ""}</Text>
68
+ <Text render={({ pageNumber, totalPages }) => (totalPages > 1 ? `Page ${pageNumber} of ${totalPages}` : "")} />
69
+ </View>
70
+ )}
71
+ </Page>
72
+ </Document>
73
+ );
74
+ }
75
+
76
+ /** A column with a gap between its children (pt). */
77
+ export function PdfStack({ gap = 8, style, children, wrap, break: pageBreak }) {
78
+ return (
79
+ <View wrap={wrap} break={pageBreak} style={[{ flexDirection: "column", gap }, style ?? {}]}>
80
+ {children}
81
+ </View>
82
+ );
83
+ }
84
+
85
+ /** A row. `justify` start · between · end; `align` start · center · end ·
86
+ * baseline. Children share the width by their own `flex` (see PdfCol). */
87
+ export function PdfRow({ gap = 16, justify = "start", align = "start", style, children, wrap }) {
88
+ const J = { start: "flex-start", between: "space-between", end: "flex-end", center: "center" };
89
+ const A = { start: "flex-start", center: "center", end: "flex-end", baseline: "baseline", stretch: "stretch" };
90
+ return (
91
+ <View wrap={wrap} style={[{ flexDirection: "row", gap, justifyContent: J[justify] ?? J.start, alignItems: A[align] ?? A.start }, style ?? {}]}>
92
+ {children}
93
+ </View>
94
+ );
95
+ }
96
+
97
+ /** One column of a PdfRow: `flex` its share (default 1), or `width` pt. */
98
+ export function PdfCol({ flex = 1, width, style, children }) {
99
+ const size = width ? { width } : flex === 0 ? { flexGrow: 0, flexShrink: 0 } : { flexGrow: flex, flexShrink: 1, flexBasis: 0, minWidth: 0 };
100
+ return <View style={[size, style ?? {}]}>{children}</View>;
101
+ }
102
+
103
+ /** Text. size xs · sm · md (default) · lg · xl · xxl; tone default · muted
104
+ * · accent · success · warning · danger · info; bold; align. */
105
+ export function PdfText({ size = "md", tone = "default", bold = false, align, style, children, ...rest }) {
106
+ const t = usePdfTheme();
107
+ return (
108
+ <Text
109
+ {...rest}
110
+ style={[{ fontSize: PDF_TYPE[size] ?? PDF_TYPE.md, lineHeight: LEADING, color: TONE(t, tone), fontFamily: bold ? t.fontBold : t.font, textAlign: align }, style ?? {}]}
111
+ >
112
+ {children}
113
+ </Text>
114
+ );
115
+ }
116
+
117
+ /** A heading: level 1 (24pt, the document's name) · 2 (12pt, a section)
118
+ * · 3 (9.5pt bold, a group inside one). Tight leading, never all caps. */
119
+ export function PdfHeading({ level = 2, tone = "default", align, style, children }) {
120
+ const t = usePdfTheme();
121
+ const L = {
122
+ 1: { fontSize: PDF_TYPE.xxl, lineHeight: 1.15, letterSpacing: -0.4 },
123
+ 2: { fontSize: PDF_TYPE.lg, lineHeight: 1.3 },
124
+ 3: { fontSize: PDF_TYPE.md, lineHeight: 1.4 },
125
+ };
126
+ return <Text style={[{ fontFamily: t.fontBold, color: TONE(t, tone), textAlign: align }, L[level] ?? L[2], style ?? {}]}>{children}</Text>;
127
+ }
128
+
129
+ /** The small muted line above a value: "Billed to", "Due". */
130
+ export function PdfLabel({ align, style, children }) {
131
+ const t = usePdfTheme();
132
+ return <Text style={[{ fontSize: PDF_TYPE.sm, color: t.muted, marginBottom: 3, textAlign: align }, style ?? {}]}>{children}</Text>;
133
+ }
134
+
135
+ /** A label over a value, the unit of a document's header. */
136
+ export function PdfField({ label, align, strong = false, tone, children }) {
137
+ return (
138
+ <View>
139
+ <PdfLabel align={align}>{label}</PdfLabel>
140
+ <PdfText bold={strong} tone={tone} align={align} size={strong ? "lg" : "md"}>
141
+ {children}
142
+ </PdfText>
143
+ </View>
144
+ );
145
+ }
146
+
147
+ /** A hairline rule. `space` is the room above and below it (pt). */
148
+ export function PdfDivider({ space = 16, strong = false }) {
149
+ const t = usePdfTheme();
150
+ return <View style={{ height: strong ? 1 : 0.75, backgroundColor: strong ? t.ink : t.rule, marginVertical: space }} />;
151
+ }
152
+
153
+ /** A soft box: a note, a callout, payment details. tone accent (default,
154
+ * the accent's tint with a bar at its edge) · neutral (the faint band). */
155
+ export function PdfCallout({ tone = "accent", title, style, children }) {
156
+ const t = usePdfTheme();
157
+ const accent = tone === "accent";
158
+ return (
159
+ <View
160
+ wrap={false}
161
+ style={[
162
+ { backgroundColor: accent ? t.accentSoft : t.band, borderLeftWidth: accent ? 2 : 0, borderLeftColor: t.accent, paddingVertical: 10, paddingHorizontal: 12, borderRadius: 3 },
163
+ style ?? {},
164
+ ]}
165
+ >
166
+ {title ? <PdfHeading level={3} style={{ marginBottom: 3 }}>{title}</PdfHeading> : null}
167
+ {typeof children === "string" ? <PdfText>{children}</PdfText> : children}
168
+ </View>
169
+ );
170
+ }
171
+
172
+ /** A small pill: "Paid", "Accepted". tone accent · success · warning ·
173
+ * danger · neutral. An outline, so it prints well in black and white. */
174
+ export function PdfBadge({ tone = "accent", children }) {
175
+ const t = usePdfTheme();
176
+ const c = { accent: t.accentInk, success: t.success, warning: t.warning, danger: t.danger, neutral: t.muted }[tone] ?? t.accentInk;
177
+ return (
178
+ <View style={{ alignSelf: "flex-start", borderWidth: 1, borderColor: c, borderRadius: 3, paddingHorizontal: 6, paddingVertical: 2 }}>
179
+ <Text style={{ fontSize: PDF_TYPE.sm, fontFamily: t.fontBold, color: c }}>{children}</Text>
180
+ </View>
181
+ );
182
+ }
183
+
184
+ /** A table: a quiet header on the faint band, hairlines between rows, the
185
+ * header repeated on every page it runs onto, a row never split.
186
+ *
187
+ * columns [{ key, label, flex? (default 1) | width? (pt), align?:
188
+ * "left" | "right" | "center", render?(row) → string | node }]
189
+ * rows [{ … }]; a row's `detail` (string) prints as a muted second
190
+ * line under the FIRST column
191
+ * empty what to print when there are no rows */
192
+ export function PdfTable({ columns = [], rows = [], empty = "Nothing here.", style }) {
193
+ const t = usePdfTheme();
194
+ const cell = (c) => [c.width ? { width: c.width } : { flex: c.flex ?? 1, minWidth: 0 }, { paddingHorizontal: 6, textAlign: c.align ?? "left" }];
195
+ return (
196
+ <View style={style}>
197
+ <View fixed style={{ flexDirection: "row", backgroundColor: t.band, borderRadius: 3, paddingVertical: 6 }}>
198
+ {columns.map((c) => (
199
+ <Text key={c.key} style={[...cell(c), { fontSize: PDF_TYPE.sm, color: t.muted }]}>
200
+ {c.label}
201
+ </Text>
202
+ ))}
203
+ </View>
204
+ {rows.length === 0 ? (
205
+ <Text style={{ paddingVertical: 12, paddingHorizontal: 6, color: t.muted }}>{empty}</Text>
206
+ ) : (
207
+ rows.map((row, i) => (
208
+ <View key={row.id ?? i} wrap={false} style={{ flexDirection: "row", paddingVertical: 8, borderBottomWidth: 0.75, borderBottomColor: t.rule }}>
209
+ {columns.map((c, j) => {
210
+ const value = c.render ? c.render(row, i) : row[c.key];
211
+ return (
212
+ <View key={c.key} style={cell(c)}>
213
+ {typeof value === "string" || typeof value === "number" ? (
214
+ <Text style={{ textAlign: c.align ?? "left", fontFamily: j === 0 ? t.fontBold : t.font }}>{String(value)}</Text>
215
+ ) : (
216
+ value ?? null
217
+ )}
218
+ {j === 0 && row.detail ? <Text style={{ color: t.muted, fontSize: PDF_TYPE.sm, lineHeight: LEADING, marginTop: 2 }}>{row.detail}</Text> : null}
219
+ </View>
220
+ );
221
+ })}
222
+ </View>
223
+ ))
224
+ )}
225
+ </View>
226
+ );
227
+ }
228
+
229
+ /** The sums under a table, flush right: label and value per line, the
230
+ * last `strong` line set larger over a rule.
231
+ *
232
+ * rows [{ label, value, strong?, tone? }]
233
+ * width the block's width (pt, default 220) */
234
+ export function PdfTotals({ rows = [], width = 220 }) {
235
+ const t = usePdfTheme();
236
+ return (
237
+ <View wrap={false} style={{ alignSelf: "flex-end", width, marginTop: 12 }}>
238
+ {rows.filter(Boolean).map((r, i) => (
239
+ <View
240
+ key={r.label ?? i}
241
+ style={[
242
+ { flexDirection: "row", justifyContent: "space-between", paddingVertical: 3, paddingHorizontal: 6 },
243
+ r.strong ? { borderTopWidth: 1, borderTopColor: t.ink, marginTop: 6, paddingTop: 8 } : {},
244
+ ]}
245
+ >
246
+ <Text style={{ color: r.strong ? t.ink : t.muted, fontFamily: r.strong ? t.fontBold : t.font, fontSize: r.strong ? PDF_TYPE.lg : PDF_TYPE.md }}>{r.label}</Text>
247
+ <Text style={{ color: TONE(t, r.tone ?? "default"), fontFamily: r.strong ? t.fontBold : t.font, fontSize: r.strong ? PDF_TYPE.lg : PDF_TYPE.md }}>{r.value}</Text>
248
+ </View>
249
+ ))}
250
+ </View>
251
+ );
252
+ }
253
+
254
+ /** Lines of plain text (an address): each on its own line, muted after
255
+ * the first unless `muted` is false. Empty lines are dropped. */
256
+ export function PdfLines({ lines = [], first = true, muted = true, align }) {
257
+ const t = usePdfTheme();
258
+ return (
259
+ <View>
260
+ {lines.filter(Boolean).map((line, i) => (
261
+ <Text key={i} style={{ fontSize: PDF_TYPE.md, lineHeight: LEADING, textAlign: align, color: muted && !(first && i === 0) ? t.muted : t.ink, fontFamily: first && i === 0 ? t.fontBold : t.font }}>
262
+ {line}
263
+ </Text>
264
+ ))}
265
+ </View>
266
+ );
267
+ }
268
+
269
+ // The rest of @react-pdf/renderer's parts, under our names, so a block
270
+ // built on this one never imports the library itself.
271
+ export { View as PdfView, Text as PdfRawText, Image as PdfImage, Link as PdfLink };