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,109 @@
1
+ # OrderDetail
2
+
3
+ One placed order on a page. The header says the order's number, its
4
+ status and when it was placed, with an Invoice action. Under it: the items,
5
+ where the order is going and who hears about it, a timeline from placed to
6
+ delivered, and the totals with a Track order action.
7
+
8
+ It only shows. The actions are the app's: links, or callbacks that may
9
+ return `{ ok: false, error }` and have the reason shown under the button.
10
+
11
+ ```jsx
12
+ import { OrderDetail } from "../components/blocks/order-detail"; // a Makersclaw app ("./blocks/order-detail" from components/)
13
+ import { OrderDetail } from "@/components/makersclaw/blocks/order-detail"; // a shadcn project
14
+ ```
15
+
16
+ It is a client component: render it from a `"use client"` component, and
17
+ load the order in the server surface (README §4).
18
+
19
+ ## The data
20
+
21
+ One order:
22
+
23
+ ```js
24
+ {
25
+ number: "#10482", // or `id`
26
+ status: "Shipped", // the badge's words
27
+ stage: "shipped", // the timeline stage it has reached
28
+ placedAt: "2026-09-18", // a date or an ISO timestamp
29
+ estimatedDelivery: "2026-09-24",
30
+ items: [{ id, name, image, price, quantity, variant }],
31
+ address: ["Maya Chen", "18 Harbour Street", "Leith, Edinburgh EH6 6PU", "United Kingdom"],
32
+ contact: { email: "maya@northwind.co", phone: "+44 7700 900123" },
33
+ shipping: 0, tax: 21.4, discount: { code: "WELCOME10", amount: 18.4 },
34
+ currency: "GBP",
35
+ paidWith: "Visa ending 4242",
36
+ timeline: [{ key: "placed", label: "Order placed", date: "2026-09-18" }, …],
37
+ }
38
+ ```
39
+
40
+ - `items` use the line-item shape `cart` uses: `price` is one unit, in the
41
+ currency's major unit.
42
+ - `address` is lines, or one string with line breaks.
43
+ - `shipping` · `tax` — a number (0 shipping reads "Free") or words
44
+ ("Included"). Leave one out and its row is not drawn.
45
+ - `subtotal` · `total` — worked out from the items and charges when left
46
+ out; pass them when the stored numbers are the truth.
47
+ - `timeline` — the stages in order, `{ key, label, date?, note?, status? }`.
48
+ Default: Order placed → Confirmed → Shipped → Delivered (keys `placed`,
49
+ `confirmed`, `shipped`, `delivered`). Stages before `stage` are
50
+ complete, `stage` is current (complete when it is the last), later ones
51
+ pending; a stage's own `status` (`failed`, `skipped`…) wins. A
52
+ `status` of "Cancelled" marks the reached stage failed and the rest
53
+ skipped. A stage shows its `date`, or its `note`; the last pending one
54
+ shows the expected delivery.
55
+ - `statusTone` — the badge's tone when the status word is not one it knows
56
+ (placed, confirmed, processing, shipped, in transit, delivered,
57
+ cancelled, refunded, returned).
58
+
59
+ ## Props
60
+
61
+ - `order` — the order above. `null` (and not loading) shows "Order not
62
+ found".
63
+ - `loading` — skeletons. `error` — a line under the header (the order
64
+ loaded but something did not), or above the not-found state.
65
+ - `currency` — used when the order has no `currency`; default `"USD"`.
66
+ `locale` — for money and dates, default the reader's.
67
+ - `onTrack()` or `trackHref` — Track order, in the summary. `trackLabel`
68
+ renames it.
69
+ - `onInvoice()` or `invoiceHref` — Invoice, in the header.
70
+ `invoiceLabel` renames it.
71
+ - `onEditContact()` — an Edit contact button under the contact details
72
+ (open your `Sheet`).
73
+ - `emptyTitle` · `emptyBody` — the not-found state's words.
74
+ - `className` — layout around it (width, margin). Never colour.
75
+
76
+ ## Example
77
+
78
+ ```jsx
79
+ // components/OrderPage.jsx — client
80
+ "use client";
81
+ import { OrderDetail } from "./blocks/order-detail";
82
+
83
+ export default function OrderPage({ order, error }) {
84
+ return (
85
+ <OrderDetail
86
+ order={order}
87
+ error={error}
88
+ trackHref={order?.trackingUrl}
89
+ invoiceHref={order ? `/api/invoices/${order.id}` : undefined}
90
+ />
91
+ );
92
+ }
93
+ ```
94
+
95
+ ## What it will not do
96
+
97
+ - Change the order: cancelling, returning or editing items is your own
98
+ screen, reached from `onEditContact` or a button beside it.
99
+ - Fetch tracking: pass `stage` and the stage dates in, or link out with
100
+ `trackHref`.
101
+ - List orders: that is a `data-table`.
102
+
103
+ An order page it cannot be is your own component in `components/`, built
104
+ from the kit — not an edit to this block. Its files are fixed: `npm run
105
+ check` refuses a change, and `makersclaw add order-detail` restores them.
106
+
107
+ ## Credits
108
+
109
+ 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": "order-detail",
3
+ "title": "OrderDetail",
4
+ "description": "One placed order on a page: its number, status and date, the items, the delivery address and contact, a timeline from placed to delivered (Steps), and the totals, with Track order and Invoice actions. Loading, error and not-found states built in.",
5
+ "useWhen": "A buyer or an operator opens one order: \"where is my order\", an order confirmation page, a support view of a purchase. Not for a list of orders (data-table) or for a basket before paying (cart).",
6
+ "tags": ["order", "order detail", "purchase", "receipt", "tracking", "delivery", "shipping", "timeline", "status", "invoice", "ecommerce", "commerce", "shop", "store"],
7
+ "exports": ["OrderDetail"],
8
+ "files": ["index.js", "order-detail.jsx"],
9
+ "requires": []
10
+ }
@@ -0,0 +1,88 @@
1
+ "use client";
2
+
3
+ // OrderDetail with an order 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 { OrderDetail } from "../components/blocks/order-detail";
8
+
9
+ const photo = (id) => `https://images.unsplash.com/${id}?w=320&h=320&fit=crop&auto=format&q=70`;
10
+
11
+ const ORDER = {
12
+ number: "#10482",
13
+ status: "Shipped",
14
+ stage: "shipped",
15
+ placedAt: "2026-09-18",
16
+ estimatedDelivery: "2026-09-24",
17
+ currency: "GBP",
18
+ items: [
19
+ { id: "li_1", name: "Field jacket", image: photo("photo-1591047139829-d91aecb6caea"), price: 164, quantity: 1, variant: "Olive · M" },
20
+ { id: "li_2", name: "Merino crew socks", image: photo("photo-1586350977771-b3b0abd50c82"), price: 16, quantity: 2, variant: "Charcoal · 3 pack" },
21
+ ],
22
+ address: ["Maya Chen", "18 Harbour Street", "Leith, Edinburgh EH6 6PU", "United Kingdom"],
23
+ contact: { email: "maya@northwind.co", phone: "+44 7700 900123" },
24
+ shipping: 0,
25
+ tax: "Included",
26
+ discount: { code: "WELCOME10", amount: 19.6 },
27
+ paidWith: "Visa ending 4242",
28
+ timeline: [
29
+ { key: "placed", label: "Order placed", date: "2026-09-18" },
30
+ { key: "confirmed", label: "Confirmed", date: "2026-09-18" },
31
+ { key: "shipped", label: "Shipped", date: "2026-09-20" },
32
+ { key: "delivered", label: "Delivered" },
33
+ ],
34
+ };
35
+
36
+ const DELIVERED = {
37
+ ...ORDER,
38
+ status: "Delivered",
39
+ stage: "delivered",
40
+ timeline: ORDER.timeline.map((s) => (s.key === "delivered" ? { ...s, date: "2026-09-23" } : s)),
41
+ };
42
+
43
+ const CANCELLED = { ...ORDER, number: "#10477", status: "Cancelled", stage: "confirmed", estimatedDelivery: null };
44
+
45
+ const VIEWS = [
46
+ { value: "shipped", label: "Shipped" },
47
+ { value: "delivered", label: "Delivered" },
48
+ { value: "cancelled", label: "Cancelled" },
49
+ { value: "missing", label: "Missing" },
50
+ { value: "loading", label: "Loading" },
51
+ ];
52
+
53
+ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
54
+
55
+ export default function OrderDetailDemo() {
56
+ const [view, setView] = useState("shipped");
57
+ const [failing, setFailing] = useState(false);
58
+ const [said, setSaid] = useState(null);
59
+ const order = { shipped: ORDER, delivered: DELIVERED, cancelled: CANCELLED }[view] ?? null;
60
+
61
+ const act = (what) => async () => {
62
+ await wait(400);
63
+ if (failing) return { ok: false, error: "The carrier did not answer. Try again." };
64
+ setSaid(what);
65
+ return { ok: true };
66
+ };
67
+
68
+ return (
69
+ <div className="grid gap-6">
70
+ <div className="flex flex-wrap items-center justify-between gap-3">
71
+ <ToggleGroup items={VIEWS} value={view} onChange={setView} size="sm" aria-label="Which order to show" className="overflow-x-auto" />
72
+ <Switch id="order-fail" checked={failing} onChange={(e) => setFailing(e.target.checked)} label="Make actions fail" />
73
+ </div>
74
+ {said ? (
75
+ <p role="status" className="text-sm text-muted-foreground">
76
+ {said} was called.
77
+ </p>
78
+ ) : null}
79
+ <OrderDetail
80
+ order={order}
81
+ loading={view === "loading"}
82
+ onTrack={act("onTrack")}
83
+ onInvoice={act("onInvoice")}
84
+ onEditContact={act("onEditContact")}
85
+ />
86
+ </div>
87
+ );
88
+ }
@@ -0,0 +1,4 @@
1
+ // The OrderDetail block — `makersclaw add order-detail`. Fixed: compose
2
+ // it through its props (README.md beside this file); an order page it
3
+ // cannot be is your own component in components/.
4
+ export { OrderDetail } from "./order-detail";
@@ -0,0 +1,354 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+ import { Badge, Button, Card, Empty, Icon, Image, Notice, Skeleton, Steps, cx, formatDate } from "../../ui";
5
+
6
+ // One placed order: its number and status, the items, where it goes and
7
+ // who hears about it, a timeline from placed to delivered, and the
8
+ // totals. Read-only; the actions (track, invoice, edit contact) are the
9
+ // app's through callbacks or links.
10
+
11
+ // Server and browser may differ in locale, time zone and even the day:
12
+ // the first render uses fixed ones (en-US, UTC) so it matches the server's
13
+ // HTML, then the reader's own take over.
14
+ function useHydrated() {
15
+ const [hydrated, setHydrated] = useState(false);
16
+ useEffect(() => setHydrated(true), []);
17
+ return hydrated;
18
+ }
19
+
20
+ const DEFAULT_STAGES = [
21
+ { key: "placed", label: "Order placed" },
22
+ { key: "confirmed", label: "Confirmed" },
23
+ { key: "shipped", label: "Shipped" },
24
+ { key: "delivered", label: "Delivered" },
25
+ ];
26
+
27
+ const STATUS_TONE = {
28
+ placed: "info",
29
+ confirmed: "info",
30
+ processing: "info",
31
+ shipped: "primary",
32
+ "in transit": "primary",
33
+ delivered: "success",
34
+ cancelled: "danger",
35
+ refunded: "warning",
36
+ returned: "warning",
37
+ };
38
+
39
+ const formats = new Map();
40
+ function money(amount, currency = "USD", locale) {
41
+ const key = `${locale ?? ""}|${currency}`;
42
+ let f = formats.get(key);
43
+ if (!f) {
44
+ try {
45
+ f = new Intl.NumberFormat(locale, { style: "currency", currency });
46
+ } catch {
47
+ f = new Intl.NumberFormat(locale, { style: "currency", currency: "USD" });
48
+ }
49
+ formats.set(key, f);
50
+ }
51
+ return f.format(Number(amount) || 0);
52
+ }
53
+
54
+ // "2026-09-21" or a full ISO timestamp → "Sep 21, 2026".
55
+ function day(value, locale, timeZone) {
56
+ if (!value) return "";
57
+ if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value)) return formatDate(value, { dateStyle: "medium" }, locale);
58
+ const d = new Date(value);
59
+ return Number.isNaN(d.getTime()) ? String(value) : new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeZone }).format(d);
60
+ }
61
+
62
+ const num = (v) => (typeof v === "number" && Number.isFinite(v) ? v : 0);
63
+
64
+ // The stages as Steps: before the reached one complete, the reached one
65
+ // current (complete when it is the last), after it pending. A stage may
66
+ // carry its own status (a failed delivery). A cancelled order stops where
67
+ // it was and says so.
68
+ function timeline(order, locale, timeZone) {
69
+ const stages = order.timeline?.length ? order.timeline : DEFAULT_STAGES;
70
+ const reached = Math.max(0, stages.findIndex((s) => s.key === order.stage));
71
+ const cancelled = String(order.status ?? "").toLowerCase() === "cancelled";
72
+ const steps = stages.map((s, i) => {
73
+ let status = s.status;
74
+ if (!status) {
75
+ if (i < reached) status = "complete";
76
+ else if (i === reached) status = cancelled ? "failed" : i === stages.length - 1 ? "complete" : "current";
77
+ else status = cancelled ? "skipped" : "pending";
78
+ }
79
+ const when = s.date ? day(s.date, locale, timeZone) : null;
80
+ const description = s.note ?? (when ? when : status === "pending" && i === stages.length - 1 && order.estimatedDelivery ? `Expected ${day(order.estimatedDelivery, locale, timeZone)}` : undefined);
81
+ return { key: s.key ?? String(i), label: s.label, description, status };
82
+ });
83
+ return steps;
84
+ }
85
+
86
+ function Loading() {
87
+ return (
88
+ <div aria-busy="true" aria-label="Loading the order" className="grid gap-4">
89
+ <Skeleton className="h-7 w-48" />
90
+ <Skeleton className="w-64" />
91
+ <Card>
92
+ <div className="flex gap-4">
93
+ <Skeleton shape="rect" className="size-20" />
94
+ <div className="grid flex-1 content-start gap-2">
95
+ <Skeleton className="w-1/2" />
96
+ <Skeleton className="w-1/4" />
97
+ </div>
98
+ </div>
99
+ </Card>
100
+ <Card>
101
+ <div className="grid gap-3">
102
+ <Skeleton className="w-full" />
103
+ <Skeleton className="w-full" />
104
+ <Skeleton className="w-2/3" />
105
+ </div>
106
+ </Card>
107
+ </div>
108
+ );
109
+ }
110
+
111
+ function Detail({ icon, title, action, children }) {
112
+ return (
113
+ <div className="grid content-start gap-2">
114
+ <div className="flex items-center gap-2">
115
+ <span className="grid size-8 shrink-0 place-items-center rounded-full bg-primary/10 text-primary">
116
+ <Icon name={icon} size={16} />
117
+ </span>
118
+ <h3 className="text-sm font-semibold">{title}</h3>
119
+ </div>
120
+ <div className="text-sm text-muted-foreground">{children}</div>
121
+ {action}
122
+ </div>
123
+ );
124
+ }
125
+
126
+ function ActionButton({ label, icon, href, onAction, variant = "secondary", size = "md" }) {
127
+ const [busy, setBusy] = useState(false);
128
+ const [error, setError] = useState(null);
129
+ async function run() {
130
+ setBusy(true);
131
+ setError(null);
132
+ try {
133
+ const res = await onAction();
134
+ if (res && res.ok === false) setError(res.error || "That did not work.");
135
+ } catch (e) {
136
+ setError(e?.message || "That did not work.");
137
+ }
138
+ setBusy(false);
139
+ }
140
+ return (
141
+ <span className="grid justify-items-start gap-1">
142
+ <Button variant={variant} size={size} icon={icon} href={href} onClick={href ? undefined : run} loading={busy}>
143
+ {label}
144
+ </Button>
145
+ {error ? (
146
+ <span role="alert" className="text-xs text-destructive">
147
+ {error}
148
+ </span>
149
+ ) : null}
150
+ </span>
151
+ );
152
+ }
153
+
154
+ export function OrderDetail({
155
+ order,
156
+ currency: currencyProp,
157
+ locale: localeProp,
158
+ loading = false,
159
+ error,
160
+ onTrack,
161
+ trackHref,
162
+ trackLabel = "Track order",
163
+ onInvoice,
164
+ invoiceHref,
165
+ invoiceLabel = "Invoice",
166
+ onEditContact,
167
+ emptyTitle = "Order not found",
168
+ emptyBody = "It may have been removed, or the link is out of date.",
169
+ className,
170
+ }) {
171
+ const hydrated = useHydrated();
172
+ const locale = localeProp ?? (hydrated ? undefined : "en-US");
173
+ const timeZone = hydrated ? undefined : "UTC";
174
+ if (loading) return <Loading />;
175
+ if (!order) {
176
+ return (
177
+ <div className={cx("grid gap-4", className)}>
178
+ {error ? <Notice tone="danger">{error}</Notice> : null}
179
+ <Empty icon="package" title={emptyTitle} body={emptyBody} />
180
+ </div>
181
+ );
182
+ }
183
+
184
+ const currency = order.currency ?? currencyProp ?? "USD";
185
+ const items = (order.items ?? []).filter(Boolean);
186
+ const count = items.reduce((n, i) => n + (Number(i.quantity) || 0), 0);
187
+ const subtotal = order.subtotal ?? items.reduce((s, i) => s + (Number(i.price) || 0) * (Number(i.quantity) || 0), 0);
188
+ const discount = order.discount ? Math.abs(num(order.discount.amount ?? order.discount)) : 0;
189
+ const total = order.total ?? Math.max(0, subtotal - discount + num(order.shipping) + num(order.tax));
190
+ const status = order.status ? String(order.status) : null;
191
+ const tone = order.statusTone ?? STATUS_TONE[status?.toLowerCase()] ?? "neutral";
192
+ const address = Array.isArray(order.address) ? order.address : order.address ? String(order.address).split("\n") : [];
193
+ const contact = order.contact ?? {};
194
+ const canTrack = Boolean(onTrack || trackHref);
195
+
196
+ const chargeRow = (label, v, freeLabel) =>
197
+ v === undefined || v === null ? null : (
198
+ <div className="flex justify-between gap-3">
199
+ <dt className="text-muted-foreground">{label}</dt>
200
+ <dd className={cx("font-medium tabular-nums", v === 0 && freeLabel && "text-success")}>
201
+ {typeof v === "string" ? v : v === 0 && freeLabel ? freeLabel : money(v, currency, locale)}
202
+ </dd>
203
+ </div>
204
+ );
205
+
206
+ return (
207
+ <div className={cx("grid gap-5", className)}>
208
+ <header className="flex flex-wrap items-start justify-between gap-4">
209
+ <div className="grid min-w-0 gap-1.5">
210
+ <div className="flex flex-wrap items-center gap-2">
211
+ <h2 className="text-xl font-semibold">Order {order.number ?? order.id}</h2>
212
+ {status ? (
213
+ <Badge tone={tone} variant="soft">
214
+ {status}
215
+ </Badge>
216
+ ) : null}
217
+ </div>
218
+ <p className="flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground">
219
+ {order.placedAt ? (
220
+ <span className="inline-flex items-center gap-1.5">
221
+ <Icon name="clock" size={14} />
222
+ Placed {day(order.placedAt, locale, timeZone)}
223
+ </span>
224
+ ) : null}
225
+ <span className="inline-flex items-center gap-1.5">
226
+ <Icon name="package" size={14} />
227
+ {count} {count === 1 ? "item" : "items"}
228
+ </span>
229
+ </p>
230
+ </div>
231
+ {onInvoice || invoiceHref ? (
232
+ <ActionButton label={invoiceLabel} icon="receipt" href={invoiceHref} onAction={onInvoice} />
233
+ ) : null}
234
+ </header>
235
+
236
+ {error ? <Notice tone="danger">{error}</Notice> : null}
237
+
238
+ <Card padding="none">
239
+ <div className="grid gap-6 p-4 sm:p-6 md:grid-cols-2">
240
+ <ul aria-label="Items in this order" className="grid content-start gap-4">
241
+ {items.map((item) => (
242
+ <li key={item.id} className="flex gap-3 sm:gap-4">
243
+ <Image src={item.image} alt="" ratio="square" fit="cover" className="size-20 shrink-0 sm:size-24" />
244
+ <div className="grid min-w-0 flex-1 content-start gap-1">
245
+ <p className="font-medium leading-snug">{item.name}</p>
246
+ {item.variant ? <p className="text-sm text-muted-foreground">{item.variant}</p> : null}
247
+ <div className="mt-1 flex flex-wrap items-baseline justify-between gap-2">
248
+ <span className="text-sm text-muted-foreground">Qty {item.quantity}</span>
249
+ <span className="font-semibold tabular-nums">
250
+ {money((Number(item.price) || 0) * (Number(item.quantity) || 0), currency, locale)}
251
+ </span>
252
+ </div>
253
+ </div>
254
+ </li>
255
+ ))}
256
+ {!items.length ? <li className="text-sm text-muted-foreground">No items on this order.</li> : null}
257
+ </ul>
258
+
259
+ <div className="grid content-start gap-6 sm:grid-cols-2">
260
+ {address.length ? (
261
+ <Detail icon="map" title="Delivery address">
262
+ <address className="not-italic leading-relaxed">
263
+ {address.map((line, i) => (
264
+ <span key={i} className="block">
265
+ {line}
266
+ </span>
267
+ ))}
268
+ </address>
269
+ </Detail>
270
+ ) : null}
271
+ {contact.email || contact.phone ? (
272
+ <Detail
273
+ icon="mail"
274
+ title="Updates go to"
275
+ action={
276
+ onEditContact ? (
277
+ <ActionButton label="Edit contact" size="sm" onAction={onEditContact} />
278
+ ) : null
279
+ }
280
+ >
281
+ <div className="grid gap-1">
282
+ {contact.email ? (
283
+ <span className="inline-flex min-w-0 items-center gap-1.5">
284
+ <Icon name="mail" size={14} className="shrink-0" />
285
+ <span className="truncate">{contact.email}</span>
286
+ </span>
287
+ ) : null}
288
+ {contact.phone ? (
289
+ <span className="inline-flex items-center gap-1.5">
290
+ <Icon name="phone" size={14} className="shrink-0" />
291
+ {contact.phone}
292
+ </span>
293
+ ) : null}
294
+ </div>
295
+ </Detail>
296
+ ) : null}
297
+ </div>
298
+ </div>
299
+
300
+ <div className="grid gap-6 border-t border-border p-4 sm:p-6 lg:grid-cols-[1fr_20rem] lg:gap-10">
301
+ <div className="grid content-start gap-4">
302
+ <h3 className="font-semibold">Timeline</h3>
303
+ <Steps steps={timeline(order, locale, timeZone)} orientation="vertical" label="Order progress" hideLabel />
304
+ </div>
305
+
306
+ <div className="grid content-start gap-4 rounded-lg border border-border bg-muted/40 p-4">
307
+ <h3 className="font-semibold">Summary</h3>
308
+ <dl className="grid gap-2.5 text-sm">
309
+ {chargeRow("Subtotal", subtotal)}
310
+ {discount ? (
311
+ <div className="flex justify-between gap-3">
312
+ <dt className="text-muted-foreground">
313
+ Discount{order.discount?.code ? ` (${order.discount.code})` : ""}
314
+ </dt>
315
+ <dd className="font-medium tabular-nums text-success">−{money(discount, currency, locale)}</dd>
316
+ </div>
317
+ ) : null}
318
+ {chargeRow("Shipping", order.shipping, "Free")}
319
+ {chargeRow("Tax", order.tax)}
320
+ <div className="mt-1.5 flex items-baseline justify-between gap-3 border-t border-border pt-3">
321
+ <dt className="text-base font-semibold">Total</dt>
322
+ <dd className="text-xl font-semibold tabular-nums">{money(total, currency, locale)}</dd>
323
+ </div>
324
+ </dl>
325
+ {order.paidWith ? (
326
+ <p className="flex items-center gap-1.5 text-xs text-muted-foreground">
327
+ <Icon name="credit-card" size={14} />
328
+ Paid with {order.paidWith}
329
+ </p>
330
+ ) : null}
331
+ {canTrack || order.estimatedDelivery ? (
332
+ <div className="grid gap-3 rounded-md bg-primary/10 p-3">
333
+ <div className="flex items-start gap-2">
334
+ <Icon name="truck" size={16} className="mt-0.5 shrink-0 text-primary" />
335
+ <div className="text-sm">
336
+ <p className="font-medium">
337
+ {order.stage === "delivered" ? "Delivered" : order.estimatedDelivery ? "On its way" : "Tracking"}
338
+ </p>
339
+ {order.estimatedDelivery && order.stage !== "delivered" ? (
340
+ <p className="text-xs text-muted-foreground">Expected {day(order.estimatedDelivery, locale, timeZone)}</p>
341
+ ) : null}
342
+ </div>
343
+ </div>
344
+ {canTrack ? (
345
+ <ActionButton label={trackLabel} icon="external" href={trackHref} onAction={onTrack} size="sm" />
346
+ ) : null}
347
+ </div>
348
+ ) : null}
349
+ </div>
350
+ </div>
351
+ </Card>
352
+ </div>
353
+ );
354
+ }