makersclaw 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (475) hide show
  1. package/THIRD-PARTY-NOTICES.md +180 -0
  2. package/package.json +3 -2
  3. package/r/annotate.json +62 -0
  4. package/r/approval-request.json +52 -0
  5. package/r/audio-player.json +74 -0
  6. package/r/auth-form.json +55 -0
  7. package/r/board.json +10 -6
  8. package/r/calendar-view.json +105 -0
  9. package/r/cart.json +62 -0
  10. package/r/chart.json +83 -0
  11. package/r/chat.json +95 -0
  12. package/r/code-editor.json +94 -0
  13. package/r/comment-box.json +64 -0
  14. package/r/contact-section.json +53 -0
  15. package/r/core.json +205 -8
  16. package/r/csv-import.json +63 -0
  17. package/r/data-table.json +69 -0
  18. package/r/diagram.json +74 -0
  19. package/r/doc-editor.json +82 -0
  20. package/r/doc-page.json +61 -0
  21. package/r/email-render.json +73 -0
  22. package/r/faq.json +50 -0
  23. package/r/file-upload.json +54 -0
  24. package/r/flow-canvas.json +93 -0
  25. package/r/footer.json +52 -0
  26. package/r/gantt.json +70 -0
  27. package/r/job-panel.json +12 -7
  28. package/r/json-editor.json +66 -0
  29. package/r/map.json +89 -0
  30. package/r/menubar.json +52 -0
  31. package/r/mind-map.json +67 -0
  32. package/r/navigation-menu.json +52 -0
  33. package/r/order-detail.json +54 -0
  34. package/r/org-chart.json +66 -0
  35. package/r/page-builder.json +105 -0
  36. package/r/payment-methods.json +51 -0
  37. package/r/pdf-document.json +79 -0
  38. package/r/pdf-viewer.json +88 -0
  39. package/r/product-detail.json +76 -0
  40. package/r/product-grid.json +65 -0
  41. package/r/record-form.json +67 -0
  42. package/r/record-notes.json +55 -0
  43. package/r/registry.json +3411 -29
  44. package/r/search-dialog.json +51 -0
  45. package/r/settings-list.json +66 -0
  46. package/r/setup-checklist.json +51 -0
  47. package/r/share-dialog.json +52 -0
  48. package/r/sidebar.json +69 -0
  49. package/r/signature-pad.json +72 -0
  50. package/r/sketch-canvas.json +99 -0
  51. package/r/spreadsheet.json +90 -0
  52. package/r/stat-cards.json +66 -0
  53. package/r/task-list.json +63 -0
  54. package/r/task-model.json +98 -0
  55. package/r/testimonials.json +52 -0
  56. package/r/transaction-list.json +53 -0
  57. package/r/whiteboard.json +66 -0
  58. package/registry/blocks/annotate/README.md +179 -0
  59. package/registry/blocks/annotate/annotate-data.js +250 -0
  60. package/registry/blocks/annotate/annotate.jsx +646 -0
  61. package/registry/blocks/annotate/block.json +10 -0
  62. package/registry/blocks/annotate/demo.jsx +135 -0
  63. package/registry/blocks/annotate/index.js +15 -0
  64. package/registry/blocks/approval-request/README.md +116 -0
  65. package/registry/blocks/approval-request/approval-request.jsx +386 -0
  66. package/registry/blocks/approval-request/block.json +10 -0
  67. package/registry/blocks/approval-request/demo.jsx +127 -0
  68. package/registry/blocks/approval-request/index.js +4 -0
  69. package/registry/blocks/audio-player/README.md +167 -0
  70. package/registry/blocks/audio-player/audio-player.jsx +623 -0
  71. package/registry/blocks/audio-player/block.json +14 -0
  72. package/registry/blocks/audio-player/colors.js +109 -0
  73. package/registry/blocks/audio-player/demo.jsx +209 -0
  74. package/registry/blocks/audio-player/index.js +6 -0
  75. package/registry/blocks/audio-player/time.js +67 -0
  76. package/registry/blocks/audio-player/wavesurfer.js +9 -0
  77. package/registry/blocks/auth-form/README.md +126 -0
  78. package/registry/blocks/auth-form/auth-form.jsx +568 -0
  79. package/registry/blocks/auth-form/block.json +10 -0
  80. package/registry/blocks/auth-form/demo.jsx +131 -0
  81. package/registry/blocks/auth-form/index.js +3 -0
  82. package/registry/blocks/board/README.md +55 -5
  83. package/registry/blocks/board/block.json +2 -2
  84. package/registry/blocks/board/board.jsx +230 -86
  85. package/registry/blocks/board/demo.jsx +103 -24
  86. package/registry/blocks/calendar-view/README.md +180 -0
  87. package/registry/blocks/calendar-view/agenda.jsx +147 -0
  88. package/registry/blocks/calendar-view/block.json +76 -0
  89. package/registry/blocks/calendar-view/calendar-model.js +442 -0
  90. package/registry/blocks/calendar-view/calendar.jsx +627 -0
  91. package/registry/blocks/calendar-view/demo.jsx +195 -0
  92. package/registry/blocks/calendar-view/draft.jsx +49 -0
  93. package/registry/blocks/calendar-view/index.js +39 -0
  94. package/registry/blocks/calendar-view/month.jsx +346 -0
  95. package/registry/blocks/calendar-view/paint.js +69 -0
  96. package/registry/blocks/calendar-view/time-grid.jsx +527 -0
  97. package/registry/blocks/calendar-view/tray.jsx +87 -0
  98. package/registry/blocks/cart/README.md +146 -0
  99. package/registry/blocks/cart/block.json +10 -0
  100. package/registry/blocks/cart/cart.jsx +597 -0
  101. package/registry/blocks/cart/demo.jsx +98 -0
  102. package/registry/blocks/cart/index.js +4 -0
  103. package/registry/blocks/cart/money.js +28 -0
  104. package/registry/blocks/chart/README.md +316 -0
  105. package/registry/blocks/chart/block.json +10 -0
  106. package/registry/blocks/chart/cartesian.jsx +642 -0
  107. package/registry/blocks/chart/core.jsx +262 -0
  108. package/registry/blocks/chart/demo.jsx +357 -0
  109. package/registry/blocks/chart/heatmap.jsx +336 -0
  110. package/registry/blocks/chart/index.js +8 -0
  111. package/registry/blocks/chart/pie.jsx +245 -0
  112. package/registry/blocks/chart/sparkline.jsx +88 -0
  113. package/registry/blocks/chat/README.md +273 -0
  114. package/registry/blocks/chat/attachment.jsx +95 -0
  115. package/registry/blocks/chat/block.json +10 -0
  116. package/registry/blocks/chat/chat.jsx +132 -0
  117. package/registry/blocks/chat/composer.jsx +364 -0
  118. package/registry/blocks/chat/demo.jsx +578 -0
  119. package/registry/blocks/chat/header.jsx +34 -0
  120. package/registry/blocks/chat/index.js +9 -0
  121. package/registry/blocks/chat/message.jsx +450 -0
  122. package/registry/blocks/chat/scroller.jsx +247 -0
  123. package/registry/blocks/chat/text.jsx +104 -0
  124. package/registry/blocks/code-editor/README.md +210 -0
  125. package/registry/blocks/code-editor/block.json +22 -0
  126. package/registry/blocks/code-editor/code-editor.jsx +534 -0
  127. package/registry/blocks/code-editor/codemirror.js +38 -0
  128. package/registry/blocks/code-editor/demo.jsx +205 -0
  129. package/registry/blocks/code-editor/index.js +8 -0
  130. package/registry/blocks/code-editor/json.js +317 -0
  131. package/registry/blocks/code-editor/sql.js +136 -0
  132. package/registry/blocks/code-editor/text.js +101 -0
  133. package/registry/blocks/code-editor/theme.js +186 -0
  134. package/registry/blocks/comment-box/README.md +123 -0
  135. package/registry/blocks/comment-box/block.json +10 -0
  136. package/registry/blocks/comment-box/comment-body.jsx +217 -0
  137. package/registry/blocks/comment-box/comment-box.jsx +198 -0
  138. package/registry/blocks/comment-box/comment-time.jsx +77 -0
  139. package/registry/blocks/comment-box/demo.jsx +141 -0
  140. package/registry/blocks/comment-box/index.js +8 -0
  141. package/registry/blocks/contact-section/README.md +152 -0
  142. package/registry/blocks/contact-section/block.json +11 -0
  143. package/registry/blocks/contact-section/contact-section.jsx +509 -0
  144. package/registry/blocks/contact-section/demo.jsx +93 -0
  145. package/registry/blocks/contact-section/index.js +4 -0
  146. package/registry/blocks/csv-import/README.md +133 -0
  147. package/registry/blocks/csv-import/block.json +13 -0
  148. package/registry/blocks/csv-import/csv-import.jsx +479 -0
  149. package/registry/blocks/csv-import/demo.jsx +106 -0
  150. package/registry/blocks/csv-import/import.js +200 -0
  151. package/registry/blocks/csv-import/index.js +7 -0
  152. package/registry/blocks/data-table/README.md +386 -0
  153. package/registry/blocks/data-table/block.json +10 -0
  154. package/registry/blocks/data-table/data-table.jsx +1164 -0
  155. package/registry/blocks/data-table/demo.jsx +588 -0
  156. package/registry/blocks/data-table/index.js +5 -0
  157. package/registry/blocks/data-table/model.js +169 -0
  158. package/registry/blocks/diagram/README.md +108 -0
  159. package/registry/blocks/diagram/block.json +13 -0
  160. package/registry/blocks/diagram/demo.jsx +113 -0
  161. package/registry/blocks/diagram/diagram.jsx +481 -0
  162. package/registry/blocks/diagram/index.js +7 -0
  163. package/registry/blocks/diagram/mermaid.js +52 -0
  164. package/registry/blocks/diagram/palette.js +313 -0
  165. package/registry/blocks/diagram/source.js +98 -0
  166. package/registry/blocks/doc-editor/README.md +215 -0
  167. package/registry/blocks/doc-editor/block.json +15 -0
  168. package/registry/blocks/doc-editor/demo.jsx +225 -0
  169. package/registry/blocks/doc-editor/doc-editor.jsx +291 -0
  170. package/registry/blocks/doc-editor/doc.js +309 -0
  171. package/registry/blocks/doc-editor/index.js +7 -0
  172. package/registry/blocks/doc-editor/schema.jsx +56 -0
  173. package/registry/blocks/doc-editor/shadcn-classes.js +110 -0
  174. package/registry/blocks/doc-editor/theme.js +82 -0
  175. package/registry/blocks/doc-page/README.md +119 -0
  176. package/registry/blocks/doc-page/autosave.js +104 -0
  177. package/registry/blocks/doc-page/block.json +10 -0
  178. package/registry/blocks/doc-page/demo.jsx +137 -0
  179. package/registry/blocks/doc-page/doc-page.jsx +276 -0
  180. package/registry/blocks/doc-page/index.js +4 -0
  181. package/registry/blocks/email-render/README.md +151 -0
  182. package/registry/blocks/email-render/block.json +14 -0
  183. package/registry/blocks/email-render/demo.jsx +153 -0
  184. package/registry/blocks/email-render/doc-email.jsx +210 -0
  185. package/registry/blocks/email-render/email.jsx +221 -0
  186. package/registry/blocks/email-render/index.js +10 -0
  187. package/registry/blocks/email-render/render.js +50 -0
  188. package/registry/blocks/email-render/theme.js +215 -0
  189. package/registry/blocks/faq/README.md +101 -0
  190. package/registry/blocks/faq/block.json +11 -0
  191. package/registry/blocks/faq/demo.jsx +89 -0
  192. package/registry/blocks/faq/faq.jsx +220 -0
  193. package/registry/blocks/faq/index.js +4 -0
  194. package/registry/blocks/file-upload/README.md +138 -0
  195. package/registry/blocks/file-upload/block.json +10 -0
  196. package/registry/blocks/file-upload/demo.jsx +204 -0
  197. package/registry/blocks/file-upload/file-upload.jsx +635 -0
  198. package/registry/blocks/file-upload/index.js +4 -0
  199. package/registry/blocks/flow-canvas/README.md +420 -0
  200. package/registry/blocks/flow-canvas/block.json +13 -0
  201. package/registry/blocks/flow-canvas/board.js +819 -0
  202. package/registry/blocks/flow-canvas/chrome.jsx +649 -0
  203. package/registry/blocks/flow-canvas/context.jsx +35 -0
  204. package/registry/blocks/flow-canvas/demo.jsx +249 -0
  205. package/registry/blocks/flow-canvas/edges.jsx +107 -0
  206. package/registry/blocks/flow-canvas/flow-canvas.jsx +1329 -0
  207. package/registry/blocks/flow-canvas/index.js +41 -0
  208. package/registry/blocks/flow-canvas/nodes.jsx +392 -0
  209. package/registry/blocks/flow-canvas/theme.js +174 -0
  210. package/registry/blocks/footer/README.md +133 -0
  211. package/registry/blocks/footer/block.json +11 -0
  212. package/registry/blocks/footer/demo.jsx +119 -0
  213. package/registry/blocks/footer/footer.jsx +406 -0
  214. package/registry/blocks/footer/index.js +4 -0
  215. package/registry/blocks/gantt/README.md +220 -0
  216. package/registry/blocks/gantt/block.json +10 -0
  217. package/registry/blocks/gantt/demo.jsx +148 -0
  218. package/registry/blocks/gantt/gantt.jsx +923 -0
  219. package/registry/blocks/gantt/index.js +7 -0
  220. package/registry/blocks/gantt/rows.jsx +468 -0
  221. package/registry/blocks/gantt/schedule.js +278 -0
  222. package/registry/blocks/job-panel/README.md +80 -0
  223. package/registry/blocks/job-panel/block.json +3 -3
  224. package/registry/blocks/job-panel/demo.jsx +230 -3
  225. package/registry/blocks/job-panel/job-panel.jsx +169 -3
  226. package/registry/blocks/json-editor/README.md +133 -0
  227. package/registry/blocks/json-editor/block.json +10 -0
  228. package/registry/blocks/json-editor/demo.jsx +92 -0
  229. package/registry/blocks/json-editor/index.js +7 -0
  230. package/registry/blocks/json-editor/json-editor.jsx +305 -0
  231. package/registry/blocks/json-editor/json-tree.jsx +393 -0
  232. package/registry/blocks/json-editor/tree.js +225 -0
  233. package/registry/blocks/map/README.md +221 -0
  234. package/registry/blocks/map/block.json +14 -0
  235. package/registry/blocks/map/demo.jsx +201 -0
  236. package/registry/blocks/map/geo.js +198 -0
  237. package/registry/blocks/map/index.js +8 -0
  238. package/registry/blocks/map/list.jsx +128 -0
  239. package/registry/blocks/map/map-view.jsx +715 -0
  240. package/registry/blocks/map/maplibre.js +30 -0
  241. package/registry/blocks/map/marks.jsx +146 -0
  242. package/registry/blocks/map/theme.js +142 -0
  243. package/registry/blocks/menubar/README.md +109 -0
  244. package/registry/blocks/menubar/block.json +10 -0
  245. package/registry/blocks/menubar/demo.jsx +128 -0
  246. package/registry/blocks/menubar/index.js +4 -0
  247. package/registry/blocks/menubar/menubar.jsx +199 -0
  248. package/registry/blocks/mind-map/README.md +206 -0
  249. package/registry/blocks/mind-map/block.json +10 -0
  250. package/registry/blocks/mind-map/demo.jsx +103 -0
  251. package/registry/blocks/mind-map/index.js +31 -0
  252. package/registry/blocks/mind-map/mind-map.jsx +1125 -0
  253. package/registry/blocks/mind-map/topic.jsx +143 -0
  254. package/registry/blocks/mind-map/tree.js +645 -0
  255. package/registry/blocks/navigation-menu/README.md +124 -0
  256. package/registry/blocks/navigation-menu/block.json +10 -0
  257. package/registry/blocks/navigation-menu/demo.jsx +84 -0
  258. package/registry/blocks/navigation-menu/index.js +4 -0
  259. package/registry/blocks/navigation-menu/navigation-menu.jsx +448 -0
  260. package/registry/blocks/order-detail/README.md +109 -0
  261. package/registry/blocks/order-detail/block.json +10 -0
  262. package/registry/blocks/order-detail/demo.jsx +88 -0
  263. package/registry/blocks/order-detail/index.js +4 -0
  264. package/registry/blocks/order-detail/order-detail.jsx +354 -0
  265. package/registry/blocks/org-chart/README.md +145 -0
  266. package/registry/blocks/org-chart/block.json +10 -0
  267. package/registry/blocks/org-chart/demo.jsx +94 -0
  268. package/registry/blocks/org-chart/index.js +7 -0
  269. package/registry/blocks/org-chart/org-chart.jsx +631 -0
  270. package/registry/blocks/org-chart/org.js +245 -0
  271. package/registry/blocks/org-chart/person.jsx +96 -0
  272. package/registry/blocks/page-builder/README.md +257 -0
  273. package/registry/blocks/page-builder/block.json +14 -0
  274. package/registry/blocks/page-builder/demo.jsx +145 -0
  275. package/registry/blocks/page-builder/grapes.js +18 -0
  276. package/registry/blocks/page-builder/index.js +11 -0
  277. package/registry/blocks/page-builder/page-builder.jsx +704 -0
  278. package/registry/blocks/page-builder/page-view.jsx +33 -0
  279. package/registry/blocks/page-builder/page.js +118 -0
  280. package/registry/blocks/page-builder/panels.jsx +588 -0
  281. package/registry/blocks/page-builder/sections.js +209 -0
  282. package/registry/blocks/page-builder/theme.js +87 -0
  283. package/registry/blocks/page-builder/thumbs.jsx +189 -0
  284. package/registry/blocks/page-builder/tokens.js +329 -0
  285. package/registry/blocks/payment-methods/README.md +104 -0
  286. package/registry/blocks/payment-methods/block.json +10 -0
  287. package/registry/blocks/payment-methods/demo.jsx +71 -0
  288. package/registry/blocks/payment-methods/index.js +4 -0
  289. package/registry/blocks/payment-methods/payment-methods.jsx +302 -0
  290. package/registry/blocks/pdf-document/README.md +213 -0
  291. package/registry/blocks/pdf-document/block.json +13 -0
  292. package/registry/blocks/pdf-document/demo.jsx +136 -0
  293. package/registry/blocks/pdf-document/index.js +33 -0
  294. package/registry/blocks/pdf-document/money.js +83 -0
  295. package/registry/blocks/pdf-document/pdf-document.jsx +144 -0
  296. package/registry/blocks/pdf-document/primitives.jsx +271 -0
  297. package/registry/blocks/pdf-document/quote.jsx +179 -0
  298. package/registry/blocks/pdf-document/theme.js +193 -0
  299. package/registry/blocks/pdf-viewer/README.md +191 -0
  300. package/registry/blocks/pdf-viewer/block.json +14 -0
  301. package/registry/blocks/pdf-viewer/demo.jsx +252 -0
  302. package/registry/blocks/pdf-viewer/helpers.js +270 -0
  303. package/registry/blocks/pdf-viewer/index.js +8 -0
  304. package/registry/blocks/pdf-viewer/notes.jsx +195 -0
  305. package/registry/blocks/pdf-viewer/pdf-viewer.jsx +1368 -0
  306. package/registry/blocks/pdf-viewer/pdfjs.js +37 -0
  307. package/registry/blocks/pdf-viewer/ssr-shim-end.js +6 -0
  308. package/registry/blocks/pdf-viewer/ssr-shim.js +44 -0
  309. package/registry/blocks/product-detail/README.md +217 -0
  310. package/registry/blocks/product-detail/block.json +10 -0
  311. package/registry/blocks/product-detail/demo.jsx +233 -0
  312. package/registry/blocks/product-detail/index.js +7 -0
  313. package/registry/blocks/product-detail/price.jsx +115 -0
  314. package/registry/blocks/product-detail/product-detail.jsx +348 -0
  315. package/registry/blocks/product-detail/product-media.jsx +102 -0
  316. package/registry/blocks/product-detail/product-options.jsx +144 -0
  317. package/registry/blocks/product-grid/README.md +162 -0
  318. package/registry/blocks/product-grid/block.json +10 -0
  319. package/registry/blocks/product-grid/demo.jsx +255 -0
  320. package/registry/blocks/product-grid/index.js +5 -0
  321. package/registry/blocks/product-grid/product-card.jsx +232 -0
  322. package/registry/blocks/product-grid/product-grid.jsx +235 -0
  323. package/registry/blocks/record-form/README.md +196 -0
  324. package/registry/blocks/record-form/block.json +10 -0
  325. package/registry/blocks/record-form/demo.jsx +525 -0
  326. package/registry/blocks/record-form/index.js +4 -0
  327. package/registry/blocks/record-form/record-fields.jsx +457 -0
  328. package/registry/blocks/record-form/record-form.jsx +415 -0
  329. package/registry/blocks/record-form/rules.js +81 -0
  330. package/registry/blocks/record-notes/README.md +139 -0
  331. package/registry/blocks/record-notes/block.json +10 -0
  332. package/registry/blocks/record-notes/demo.jsx +179 -0
  333. package/registry/blocks/record-notes/index.js +4 -0
  334. package/registry/blocks/record-notes/record-notes.jsx +266 -0
  335. package/registry/blocks/search-dialog/README.md +108 -0
  336. package/registry/blocks/search-dialog/block.json +10 -0
  337. package/registry/blocks/search-dialog/demo.jsx +116 -0
  338. package/registry/blocks/search-dialog/index.js +3 -0
  339. package/registry/blocks/search-dialog/search-dialog.jsx +235 -0
  340. package/registry/blocks/settings-list/README.md +171 -0
  341. package/registry/blocks/settings-list/block.json +10 -0
  342. package/registry/blocks/settings-list/demo.jsx +333 -0
  343. package/registry/blocks/settings-list/index.js +4 -0
  344. package/registry/blocks/settings-list/row-state.jsx +93 -0
  345. package/registry/blocks/settings-list/settings-list.jsx +349 -0
  346. package/registry/blocks/settings-list/settings-matrix.jsx +118 -0
  347. package/registry/blocks/setup-checklist/README.md +142 -0
  348. package/registry/blocks/setup-checklist/block.json +10 -0
  349. package/registry/blocks/setup-checklist/demo.jsx +159 -0
  350. package/registry/blocks/setup-checklist/index.js +4 -0
  351. package/registry/blocks/setup-checklist/setup-checklist.jsx +446 -0
  352. package/registry/blocks/share-dialog/README.md +113 -0
  353. package/registry/blocks/share-dialog/block.json +10 -0
  354. package/registry/blocks/share-dialog/demo.jsx +140 -0
  355. package/registry/blocks/share-dialog/index.js +3 -0
  356. package/registry/blocks/share-dialog/share-dialog.jsx +384 -0
  357. package/registry/blocks/sidebar/README.md +190 -0
  358. package/registry/blocks/sidebar/block.json +43 -0
  359. package/registry/blocks/sidebar/demo.jsx +577 -0
  360. package/registry/blocks/sidebar/index.js +4 -0
  361. package/registry/blocks/sidebar/sidebar-panel.jsx +149 -0
  362. package/registry/blocks/sidebar/sidebar.jsx +864 -0
  363. package/registry/blocks/signature-pad/README.md +137 -0
  364. package/registry/blocks/signature-pad/block.json +13 -0
  365. package/registry/blocks/signature-pad/colors.js +115 -0
  366. package/registry/blocks/signature-pad/demo.jsx +94 -0
  367. package/registry/blocks/signature-pad/index.js +6 -0
  368. package/registry/blocks/signature-pad/pad.js +7 -0
  369. package/registry/blocks/signature-pad/signature-pad.jsx +434 -0
  370. package/registry/blocks/signature-pad/signature.js +68 -0
  371. package/registry/blocks/sketch-canvas/README.md +280 -0
  372. package/registry/blocks/sketch-canvas/block.json +13 -0
  373. package/registry/blocks/sketch-canvas/demo.jsx +159 -0
  374. package/registry/blocks/sketch-canvas/excalidraw.js +40 -0
  375. package/registry/blocks/sketch-canvas/index.js +9 -0
  376. package/registry/blocks/sketch-canvas/palette.js +226 -0
  377. package/registry/blocks/sketch-canvas/sketch-canvas.jsx +1188 -0
  378. package/registry/blocks/sketch-canvas/sketch.js +179 -0
  379. package/registry/blocks/sketch-canvas/ssr-shim-end.js +6 -0
  380. package/registry/blocks/sketch-canvas/ssr-shim.js +45 -0
  381. package/registry/blocks/sketch-canvas/stamps.js +104 -0
  382. package/registry/blocks/sketch-canvas/theme.js +131 -0
  383. package/registry/blocks/spreadsheet/README.md +307 -0
  384. package/registry/blocks/spreadsheet/block.json +13 -0
  385. package/registry/blocks/spreadsheet/cells.jsx +455 -0
  386. package/registry/blocks/spreadsheet/chrome.jsx +325 -0
  387. package/registry/blocks/spreadsheet/demo.jsx +177 -0
  388. package/registry/blocks/spreadsheet/grid.js +387 -0
  389. package/registry/blocks/spreadsheet/index.js +34 -0
  390. package/registry/blocks/spreadsheet/spreadsheet.jsx +1732 -0
  391. package/registry/blocks/spreadsheet/types.js +473 -0
  392. package/registry/blocks/stat-cards/README.md +173 -0
  393. package/registry/blocks/stat-cards/block.json +10 -0
  394. package/registry/blocks/stat-cards/demo.jsx +257 -0
  395. package/registry/blocks/stat-cards/index.js +4 -0
  396. package/registry/blocks/stat-cards/stat-cards.jsx +307 -0
  397. package/registry/blocks/stat-cards/usage.jsx +243 -0
  398. package/registry/blocks/task-list/README.md +176 -0
  399. package/registry/blocks/task-list/block.json +10 -0
  400. package/registry/blocks/task-list/demo.jsx +134 -0
  401. package/registry/blocks/task-list/index.js +5 -0
  402. package/registry/blocks/task-list/task-list.jsx +907 -0
  403. package/registry/blocks/task-model/README.md +455 -0
  404. package/registry/blocks/task-model/block.json +167 -0
  405. package/registry/blocks/task-model/changes.js +89 -0
  406. package/registry/blocks/task-model/dates.js +371 -0
  407. package/registry/blocks/task-model/demo.jsx +215 -0
  408. package/registry/blocks/task-model/dnd.jsx +240 -0
  409. package/registry/blocks/task-model/index.js +97 -0
  410. package/registry/blocks/task-model/model.js +919 -0
  411. package/registry/blocks/task-model/parts.jsx +449 -0
  412. package/registry/blocks/task-model/toolbar.jsx +271 -0
  413. package/registry/blocks/testimonials/README.md +139 -0
  414. package/registry/blocks/testimonials/block.json +11 -0
  415. package/registry/blocks/testimonials/demo.jsx +137 -0
  416. package/registry/blocks/testimonials/index.js +4 -0
  417. package/registry/blocks/testimonials/testimonials.jsx +430 -0
  418. package/registry/blocks/transaction-list/README.md +126 -0
  419. package/registry/blocks/transaction-list/block.json +10 -0
  420. package/registry/blocks/transaction-list/demo.jsx +79 -0
  421. package/registry/blocks/transaction-list/index.js +4 -0
  422. package/registry/blocks/transaction-list/transaction-list.jsx +383 -0
  423. package/registry/blocks/whiteboard/README.md +179 -0
  424. package/registry/blocks/whiteboard/block.json +10 -0
  425. package/registry/blocks/whiteboard/demo.jsx +169 -0
  426. package/registry/blocks/whiteboard/index.js +6 -0
  427. package/registry/blocks/whiteboard/templates.js +150 -0
  428. package/registry/blocks/whiteboard/whiteboard.jsx +721 -0
  429. package/src/cli.mjs +19 -6
  430. package/src/install.mjs +18 -0
  431. package/src/registry.mjs +38 -4
  432. package/src/shadcn.mjs +14 -1
  433. package/templates/next/files/README.md +145 -11
  434. package/templates/next/files/app/globals.css +55 -4
  435. package/templates/next/files/check/run.mjs +3 -3
  436. package/templates/next/files/components/ui/avatar.jsx +141 -0
  437. package/templates/next/files/components/ui/breadcrumb.jsx +149 -0
  438. package/templates/next/files/components/ui/button-group.jsx +70 -0
  439. package/templates/next/files/components/ui/button.jsx +132 -12
  440. package/templates/next/files/components/ui/calendar.jsx +609 -0
  441. package/templates/next/files/components/ui/carousel.jsx +281 -0
  442. package/templates/next/files/components/ui/collapsible.jsx +208 -0
  443. package/templates/next/files/components/ui/combobox.jsx +608 -0
  444. package/templates/next/files/components/ui/command.jsx +577 -0
  445. package/templates/next/files/components/ui/context-menu.jsx +191 -0
  446. package/templates/next/files/components/ui/date-picker.jsx +360 -0
  447. package/templates/next/files/components/ui/distribution.jsx +117 -0
  448. package/templates/next/files/components/ui/feedback.jsx +143 -0
  449. package/templates/next/files/components/ui/field.jsx +115 -3
  450. package/templates/next/files/components/ui/file-input.jsx +234 -0
  451. package/templates/next/files/components/ui/icon.jsx +130 -8
  452. package/templates/next/files/components/ui/image.jsx +143 -0
  453. package/templates/next/files/components/ui/index.js +47 -2
  454. package/templates/next/files/components/ui/input-group.jsx +213 -0
  455. package/templates/next/files/components/ui/input-otp.jsx +170 -0
  456. package/templates/next/files/components/ui/item.jsx +206 -0
  457. package/templates/next/files/components/ui/menu.jsx +454 -82
  458. package/templates/next/files/components/ui/notice.jsx +126 -14
  459. package/templates/next/files/components/ui/pagination.jsx +156 -0
  460. package/templates/next/files/components/ui/popover.jsx +284 -0
  461. package/templates/next/files/components/ui/radio.jsx +193 -0
  462. package/templates/next/files/components/ui/rating.jsx +131 -0
  463. package/templates/next/files/components/ui/resizable.jsx +338 -0
  464. package/templates/next/files/components/ui/scroll-area.jsx +123 -0
  465. package/templates/next/files/components/ui/separator.jsx +119 -0
  466. package/templates/next/files/components/ui/sheet.jsx +96 -11
  467. package/templates/next/files/components/ui/slider.jsx +174 -0
  468. package/templates/next/files/components/ui/stat.jsx +574 -0
  469. package/templates/next/files/components/ui/steps.jsx +338 -0
  470. package/templates/next/files/components/ui/swatch.jsx +33 -0
  471. package/templates/next/files/components/ui/table.jsx +130 -0
  472. package/templates/next/files/components/ui/toast.jsx +440 -0
  473. package/templates/next/files/components/ui/toggle.jsx +195 -0
  474. package/templates/next/files/components/ui/tooltip.jsx +270 -0
  475. package/templates/next/template.json +264 -8
@@ -0,0 +1,333 @@
1
+ "use client";
2
+
3
+ // SettingsList in each of its shapes — the gallery's and the smoke test's
4
+ // surface. Not installed into apps. Saves are pretend: pick whether they
5
+ // succeed or fail, and watch the row that changed.
6
+ import { useState } from "react";
7
+ import { Button, Field, InputGroup, Notice, Select, toast } from "../components/ui";
8
+ import { SettingsList } from "../components/blocks/settings-list";
9
+
10
+ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
11
+
12
+ const PREFERENCES = [
13
+ { key: "digest", icon: "mail", label: "Weekly digest", description: "A summary of the week's numbers, every Monday at 8:00.", control: { type: "switch", value: true } },
14
+ { key: "sounds", icon: "bell", label: "Sounds", description: "Play a sound when a message arrives.", control: { type: "switch", value: false } },
15
+ {
16
+ key: "theme",
17
+ icon: "palette",
18
+ label: "Appearance",
19
+ description: "How the app looks on this device.",
20
+ control: {
21
+ type: "select",
22
+ value: "system",
23
+ options: [
24
+ { value: "system", label: "Match the system" },
25
+ { value: "light", label: "Light" },
26
+ { value: "dark", label: "Dark" },
27
+ ],
28
+ },
29
+ },
30
+ {
31
+ key: "week",
32
+ icon: "calendar",
33
+ label: "Week starts on",
34
+ control: {
35
+ type: "select",
36
+ value: "mon",
37
+ options: [
38
+ { value: "mon", label: "Monday" },
39
+ { value: "sun", label: "Sunday" },
40
+ { value: "sat", label: "Saturday" },
41
+ ],
42
+ },
43
+ },
44
+ { key: "export", icon: "download", label: "Export your data", description: "Everything you own, as a zip of CSV files.", control: { type: "button", label: "Export", icon: "download" } },
45
+ ];
46
+
47
+ const METHODS = [
48
+ {
49
+ key: "keys",
50
+ icon: "key",
51
+ label: "Security keys",
52
+ badge: { label: "Recommended", tone: "success" },
53
+ description: "A hardware key you touch to sign in. The strongest option.",
54
+ value: "No keys added",
55
+ control: { type: "button", label: "Add", variant: "primary" },
56
+ },
57
+ {
58
+ key: "app",
59
+ icon: "smartphone",
60
+ label: "Authenticator app",
61
+ badge: { label: "Recommended", tone: "success" },
62
+ description: "Six-digit codes from an app on your phone.",
63
+ value: "Not set up",
64
+ control: { type: "button", label: "Set up", variant: "primary" },
65
+ },
66
+ {
67
+ key: "sms",
68
+ icon: "message-square",
69
+ label: "Text message",
70
+ description: "Codes sent to your phone by SMS.",
71
+ value: "+44 7700 900 461",
72
+ valueTone: "set",
73
+ control: { type: "button", label: "Edit" },
74
+ },
75
+ ];
76
+
77
+ const SESSIONS = [
78
+ { key: "s1", icon: "laptop", label: "MacBook Pro", badge: { label: "This device", tone: "info" }, meta: [{ icon: "globe", text: "Lisbon, Portugal" }, { icon: "clock", text: "Active now" }, "Safari 18 on macOS 15"] },
79
+ {
80
+ key: "s2",
81
+ icon: "smartphone",
82
+ label: "iPhone 15",
83
+ meta: [{ icon: "globe", text: "Porto, Portugal" }, { icon: "clock", text: "Yesterday, 18:40" }, "Makersclaw for iOS"],
84
+ control: { type: "remove", label: "Sign out iPhone 15", confirm: { title: "Sign out this iPhone?", body: "It will need your password to come back.", confirmLabel: "Sign out" } },
85
+ },
86
+ {
87
+ key: "s3",
88
+ icon: "monitor",
89
+ label: "Windows desktop",
90
+ meta: [{ icon: "globe", text: "Madrid, Spain" }, { icon: "clock", text: "3 days ago" }, "Firefox 131 on Windows 11"],
91
+ control: { type: "remove", label: "Sign out Windows desktop", confirm: { title: "Sign out this desktop?", body: "It will need your password to come back.", confirmLabel: "Sign out" } },
92
+ },
93
+ ];
94
+
95
+ const INTEGRATIONS = [
96
+ { key: "github", icon: "github", label: "GitHub", badge: { label: "Development", hue: 1 }, description: "Link commits and pull requests to tasks.", control: { type: "switch", value: false } },
97
+ {
98
+ key: "slack",
99
+ icon: "message-square",
100
+ label: "Slack",
101
+ badge: { label: "Messaging", hue: 2 },
102
+ description: "Post a note to a channel when a deal moves.",
103
+ control: { type: "switch", value: true },
104
+ connected: { account: "ops@quillhouse.com", code: "QH-4417-208" },
105
+ },
106
+ { key: "google", icon: "google", label: "Google Calendar", badge: { label: "Calendar", hue: 3 }, description: "Put booked calls on your calendar.", control: { type: "switch", value: false } },
107
+ ];
108
+
109
+ const BILLING = [
110
+ {
111
+ key: "b1",
112
+ icon: "building",
113
+ label: "Harbourline Ltd",
114
+ description: "Main account",
115
+ meta: ["Contact: Tomas Kowalski", "tomas@harbourline.co", "VAT GB 204 1187 63"],
116
+ control: { type: "actions", items: [{ key: "edit", label: "Edit", icon: "pencil" }, { key: "delete", label: "Delete", icon: "trash", tone: "danger", confirm: { title: "Delete this billing profile?", body: "Invoices already sent keep it.", confirmLabel: "Delete" } }] },
117
+ },
118
+ {
119
+ key: "b2",
120
+ icon: "building",
121
+ label: "Harbourline GmbH",
122
+ description: "Germany",
123
+ meta: ["Contact: Lena Vogt", "lena@harbourline.de", "VAT DE 318 552 904"],
124
+ control: { type: "actions", items: [{ key: "edit", label: "Edit", icon: "pencil" }, { key: "delete", label: "Delete", icon: "trash", tone: "danger", confirm: { title: "Delete this billing profile?", body: "Invoices already sent keep it.", confirmLabel: "Delete" } }] },
125
+ },
126
+ ];
127
+
128
+ const CHANNELS = [
129
+ { key: "email", label: "Email", icon: "mail" },
130
+ { key: "push", label: "Push", icon: "smartphone" },
131
+ { key: "sms", label: "SMS", icon: "message-square" },
132
+ ];
133
+
134
+ const EVENTS = [
135
+ { key: "mentions", group: "Conversations", label: "Mentions", description: "Someone mentions you in a comment.", values: { email: true, push: true, sms: false } },
136
+ { key: "replies", group: "Conversations", label: "Replies", description: "Someone answers a thread you are in.", values: { email: true, push: false, sms: false } },
137
+ { key: "signin", group: "Security", label: "New sign-in", description: "Your account is used on a new device.", values: { email: true, push: true, sms: true }, locked: ["email"] },
138
+ { key: "password", group: "Security", label: "Password changed", description: "Sent the moment it happens.", values: { email: true, push: true, sms: false }, locked: ["email"] },
139
+ { key: "product", group: "Product", label: "What's new", description: "New features, once a month.", values: { email: false, push: false, sms: null } },
140
+ ];
141
+
142
+ const VARIANTS = {
143
+ preferences: { label: "Preferences" },
144
+ methods: { label: "Two-step sign-in" },
145
+ sessions: { label: "Signed-in devices" },
146
+ integrations: { label: "Integrations" },
147
+ details: { label: "Billing profiles" },
148
+ matrix: { label: "Notifications" },
149
+ };
150
+
151
+ /** Rows in memory with a pretend save that honours the chosen outcome. */
152
+ function useRows(initial, outcome) {
153
+ const [rows, setRows] = useState(initial);
154
+ async function save(fn) {
155
+ await wait(800);
156
+ if (outcome === "fail") return { ok: false, error: "The server did not answer." };
157
+ fn?.();
158
+ return { ok: true };
159
+ }
160
+ return { rows, setRows, save };
161
+ }
162
+
163
+ function setControl(rows, key, value) {
164
+ return rows.map((r) => (r.key === key ? { ...r, control: { ...r.control, value } } : r));
165
+ }
166
+
167
+ export default function SettingsListDemo() {
168
+ const [variant, setVariant] = useState("preferences");
169
+ const [outcome, setOutcome] = useState("ok");
170
+ const [state, setState] = useState("ready");
171
+
172
+ const prefs = useRows(PREFERENCES, outcome);
173
+ const methods = useRows(METHODS, outcome);
174
+ const sessions = useRows(SESSIONS, outcome);
175
+ const integrations = useRows(INTEGRATIONS, outcome);
176
+ const billing = useRows(BILLING, outcome);
177
+ const events = useRows(EVENTS, outcome);
178
+
179
+ const common = {
180
+ loading: state === "loading",
181
+ error: state === "error" ? "The settings service is not answering." : undefined,
182
+ onRetry: () => setState("ready"),
183
+ };
184
+ const pick = (rows) => (state === "empty" ? [] : rows);
185
+
186
+ let list;
187
+ if (variant === "preferences") {
188
+ list = (
189
+ <SettingsList
190
+ {...common}
191
+ title="Preferences"
192
+ description="Saved as you change them."
193
+ rows={pick(prefs.rows)}
194
+ onChange={(row, value) => prefs.save(() => prefs.setRows((rs) => setControl(rs, row.key, value)))}
195
+ onAction={() => prefs.save(() => toast("Your export is on its way by email."))}
196
+ />
197
+ );
198
+ } else if (variant === "methods") {
199
+ list = (
200
+ <SettingsList
201
+ {...common}
202
+ icon="shield"
203
+ title="Two-step sign-in"
204
+ description="A second step after your password, so a leaked password is not enough."
205
+ badge={{ label: "On", tone: "success", icon: "circle-check" }}
206
+ rows={pick(methods.rows)}
207
+ onAction={(row) => methods.save(() => toast(`${row.label}: the setup would open here.`))}
208
+ footer={<Notice tone="info">Keep at least two methods, so losing a phone never locks you out.</Notice>}
209
+ />
210
+ );
211
+ } else if (variant === "sessions") {
212
+ list = (
213
+ <SettingsList
214
+ {...common}
215
+ icon="shield-check"
216
+ title="Signed-in devices"
217
+ description="Where your account is open now. Sign out anything you do not recognise."
218
+ rows={pick(sessions.rows)}
219
+ onAction={(row) => sessions.save(() => sessions.setRows((rs) => rs.filter((r) => r.key !== row.key)))}
220
+ emptyTitle="No other devices"
221
+ footer={<Notice tone="warning" title="Something you don't recognise?">Sign it out, then change your password.</Notice>}
222
+ />
223
+ );
224
+ } else if (variant === "integrations") {
225
+ list = (
226
+ <SettingsList
227
+ {...common}
228
+ icon="layers"
229
+ title="Integrations"
230
+ description="Tools this workspace talks to."
231
+ rows={pick(integrations.rows).map((r) => ({
232
+ ...r,
233
+ details: r.control.value
234
+ ? () => (
235
+ <div className="grid gap-3">
236
+ <p>
237
+ Connected as <span className="font-medium">{r.connected?.account ?? "ops@quillhouse.com"}</span>
238
+ </p>
239
+ <Field id={`code-${r.key}`} label="Verification code" hint="Paste it in the other tool to finish linking.">
240
+ <InputGroup
241
+ id={`code-${r.key}`}
242
+ readOnly
243
+ value={r.connected?.code ?? "QH-0000-000"}
244
+ action={{
245
+ label: "Copy",
246
+ icon: "copy",
247
+ onClick: () => {
248
+ navigator.clipboard?.writeText(r.connected?.code ?? "").catch(() => {});
249
+ toast("Copied");
250
+ },
251
+ }}
252
+ />
253
+ </Field>
254
+ </div>
255
+ )
256
+ : undefined,
257
+ }))}
258
+ onChange={(row, value) => integrations.save(() => integrations.setRows((rs) => setControl(rs, row.key, value)))}
259
+ />
260
+ );
261
+ } else if (variant === "details") {
262
+ list = (
263
+ <SettingsList
264
+ {...common}
265
+ title="Billing profiles"
266
+ description="Who invoices are addressed to."
267
+ actions={
268
+ <Button size="sm" icon="plus" onClick={() => toast("A billing form would open here.")}>
269
+ Add profile
270
+ </Button>
271
+ }
272
+ rows={pick(billing.rows)}
273
+ onAction={(row, action) =>
274
+ billing.save(() => {
275
+ if (action === "delete") billing.setRows((rs) => rs.filter((r) => r.key !== row.key));
276
+ else toast(`Editing ${row.label}`);
277
+ })
278
+ }
279
+ emptyTitle="No billing profiles"
280
+ emptyBody="Add one so invoices carry your company's details."
281
+ />
282
+ );
283
+ } else {
284
+ list = (
285
+ <SettingsList
286
+ {...common}
287
+ variant="matrix"
288
+ title="Notifications"
289
+ description="Choose where each kind of news reaches you. Security emails always go out."
290
+ channels={CHANNELS}
291
+ rows={pick(events.rows)}
292
+ onChange={(row, value, channel) =>
293
+ events.save(() => events.setRows((rs) => rs.map((r) => (r.key === row.key ? { ...r, values: { ...r.values, [channel]: value } } : r))))
294
+ }
295
+ />
296
+ );
297
+ }
298
+
299
+ return (
300
+ <div className="grid max-w-3xl gap-4">
301
+ <div className="grid gap-3 sm:grid-cols-3">
302
+ <Field id="sl-variant" label="Shape">
303
+ <Select id="sl-variant" value={variant} onChange={(e) => setVariant(e.target.value)} options={Object.entries(VARIANTS).map(([value, v]) => ({ value, label: v.label }))} />
304
+ </Field>
305
+ <Field id="sl-outcome" label="Saving">
306
+ <Select
307
+ id="sl-outcome"
308
+ value={outcome}
309
+ onChange={(e) => setOutcome(e.target.value)}
310
+ options={[
311
+ { value: "ok", label: "Succeeds" },
312
+ { value: "fail", label: "Fails" },
313
+ ]}
314
+ />
315
+ </Field>
316
+ <Field id="sl-state" label="State">
317
+ <Select
318
+ id="sl-state"
319
+ value={state}
320
+ onChange={(e) => setState(e.target.value)}
321
+ options={[
322
+ { value: "ready", label: "Loaded" },
323
+ { value: "loading", label: "Loading" },
324
+ { value: "error", label: "Load failed" },
325
+ { value: "empty", label: "Empty" },
326
+ ]}
327
+ />
328
+ </Field>
329
+ </div>
330
+ {list}
331
+ </div>
332
+ );
333
+ }
@@ -0,0 +1,4 @@
1
+ // The SettingsList block — `makersclaw add settings-list`. Fixed: compose
2
+ // it through its props (README.md beside this file); a settings screen it
3
+ // cannot be is your own component in components/.
4
+ export { SettingsList } from "./settings-list";
@@ -0,0 +1,93 @@
1
+ "use client";
2
+
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { Button, Icon, Spinner } from "../../ui";
5
+
6
+ // Each control in a SettingsList saves on its own. This keeps, per control
7
+ // (a row, or a row × channel in the matrix), what it shows while its save
8
+ // runs (the new value, at once), that it is saving, and why its last save
9
+ // failed — with the attempt kept so "Try again" repeats it.
10
+
11
+ /** Run `save()` → { ok } | { ok: false, error }; a throw counts as failed. */
12
+ async function attempt(save) {
13
+ try {
14
+ const res = await save();
15
+ return res?.ok ? { ok: true } : { ok: false, error: res?.error };
16
+ } catch (e) {
17
+ return { ok: false, error: e?.message };
18
+ }
19
+ }
20
+
21
+ function sameValue(a, b) {
22
+ return a === b || (a == null && b == null);
23
+ }
24
+
25
+ export function useSaves(failedText = "Not saved.") {
26
+ const [shown, setShown] = useState({}); // key → { value, from }: the new value, over the stored `from`
27
+ const [busy, setBusy] = useState({}); // key → true
28
+ const [failed, setFailed] = useState({}); // key → { error, retry }
29
+ const alive = useRef(true);
30
+ useEffect(() => {
31
+ alive.current = true;
32
+ return () => {
33
+ alive.current = false;
34
+ };
35
+ }, []);
36
+
37
+ const drop = (setter, key) =>
38
+ setter((m) => {
39
+ if (!(key in m)) return m;
40
+ const { [key]: _gone, ...rest } = m;
41
+ return rest;
42
+ });
43
+
44
+ /** Save `key`: show `value` (optional; `stored` is what the rows hold
45
+ * now) at once, run `save`, put the stored value back on failure.
46
+ * `fallback` words a failure that came back without an error. */
47
+ async function run(key, save, { value, stored, fallback } = {}) {
48
+ const retry = () => run(key, save, { value, stored, fallback });
49
+ if (value !== undefined) setShown((m) => ({ ...m, [key]: { value, from: stored } }));
50
+ setBusy((m) => ({ ...m, [key]: true }));
51
+ drop(setFailed, key);
52
+ const res = await attempt(save);
53
+ if (!alive.current) return res;
54
+ drop(setBusy, key);
55
+ // Good: the new value stays on screen until the rows catch up (see
56
+ // valueOf). Bad: the stored one returns.
57
+ if (!res.ok) {
58
+ drop(setShown, key);
59
+ setFailed((m) => ({ ...m, [key]: { error: res.error || fallback || failedText, retry } }));
60
+ }
61
+ return res;
62
+ }
63
+
64
+ return {
65
+ run,
66
+ // The new value while the rows still hold what they held before the
67
+ // save; once they change (the save landed, or anything else moved
68
+ // them) the rows are the truth again.
69
+ valueOf: (key, stored) => (key in shown && sameValue(shown[key].from, stored) ? shown[key].value : stored),
70
+ isBusy: (key) => Boolean(busy[key]),
71
+ failure: (key) => failed[key] ?? null,
72
+ dismiss: (key) => drop(setFailed, key),
73
+ };
74
+ }
75
+
76
+ /** The line under a row whose save failed: why, and Try again. */
77
+ export function Failure({ failure, id, className }) {
78
+ if (!failure) return null;
79
+ return (
80
+ <p id={id} role="alert" className={className ?? "flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-destructive"}>
81
+ <Icon name="warning" size={14} className="shrink-0" />
82
+ <span className="min-w-0">{failure.error}</span>
83
+ <Button variant="link" size="sm" onClick={failure.retry}>
84
+ Try again
85
+ </Button>
86
+ </p>
87
+ );
88
+ }
89
+
90
+ /** A small spinner that says what is happening. */
91
+ export function Saving({ label = "Saving" }) {
92
+ return <Spinner size="sm" label={label} className="text-muted-foreground" />;
93
+ }