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,30 @@
1
+ // The one door to MapLibre (maplibre-gl, BSD-3-Clause) and its React
2
+ // binding (react-map-gl, MIT). Every file in this block reaches them
3
+ // through here, and the blocks built on this one reach them through
4
+ // MapView — never the packages directly.
5
+ //
6
+ // No server shim is needed: maplibre-gl 6 and react-map-gl 8 touch no
7
+ // browser global while their modules load (checked in node), and the map
8
+ // itself mounts only after the first effect (MapView's mount guard).
9
+ //
10
+ // Two things are passed explicitly instead of left to the libraries:
11
+ //
12
+ // mapLib react-map-gl would otherwise load maplibre-gl with an
13
+ // import() of its own. Handing it the module we import here
14
+ // keeps the app one static bundle.
15
+ // WORKER_URL maplibre-gl 6 draws tiles in a Web Worker that it loads
16
+ // from a file beside its own module (import.meta.url). Inside
17
+ // an app bundle that URL is a build-time file:// path, so the
18
+ // worker would never load. It is loaded from jsDelivr instead,
19
+ // at exactly the version installed (getVersion()), so the
20
+ // worker and the page always match. A map already fetches its
21
+ // style, tiles and fonts at run time; this is one more file.
22
+ // Self-host it with MapView's `workerUrl` prop.
23
+ import "maplibre-gl/dist/maplibre-gl.css";
24
+ import * as maplibregl from "maplibre-gl";
25
+ import { AttributionControl, Layer, Map as GLMap, Marker, Popup, Source } from "react-map-gl/maplibre";
26
+
27
+ export const MAPLIBRE_VERSION = maplibregl.getVersion();
28
+ export const WORKER_URL = `https://cdn.jsdelivr.net/npm/maplibre-gl@${MAPLIBRE_VERSION}/dist/maplibre-gl-worker.mjs`;
29
+
30
+ export { AttributionControl, GLMap, Layer, Marker, Popup, Source, maplibregl };
@@ -0,0 +1,146 @@
1
+ "use client";
2
+
3
+ // What sits ON the map: a place's marker, a cluster, the popup card, the
4
+ // list of places that share one spot. React in kit tokens — maplibre only
5
+ // positions them (react-map-gl's Marker and Popup portal them in).
6
+ import { IconButton, Item, cx } from "../../ui";
7
+ import { DOT } from "./theme";
8
+
9
+ // A soft halo behind the selected dot, one class per tone.
10
+ const HALO = {
11
+ primary: "bg-primary/20",
12
+ success: "bg-success/20",
13
+ warning: "bg-warning/20",
14
+ destructive: "bg-destructive/20",
15
+ info: "bg-info/20",
16
+ "chart-1": "bg-chart-1/20",
17
+ "chart-2": "bg-chart-2/20",
18
+ "chart-3": "bg-chart-3/20",
19
+ "chart-4": "bg-chart-4/20",
20
+ "chart-5": "bg-chart-5/20",
21
+ muted: "bg-muted-foreground/20",
22
+ };
23
+
24
+ /** A place: a dot in its tone (or the caller's own content), its name in
25
+ * a small label on hover and when it is selected without a popup. */
26
+ export function PointMark({ title, tone, selected, hovered, showLabel, focusable, custom, onHover }) {
27
+ // Its click is handled by the Marker around it (a native listener that
28
+ // runs before maplibre's map click); this button gives it a name, focus
29
+ // and Enter / Space.
30
+ const lifted = selected || hovered;
31
+ return (
32
+ // raw: a map marker is a hit target positioned on the canvas by
33
+ // maplibre; no kit part is a pin. Kit Button would force 44px boxes
34
+ // that hide the map under them.
35
+ <button
36
+ type="button"
37
+ tabIndex={focusable ? 0 : -1}
38
+ aria-label={title}
39
+ aria-pressed={selected}
40
+ data-lifted={lifted ? "" : undefined}
41
+ onMouseEnter={() => onHover(true)}
42
+ onMouseLeave={() => onHover(false)}
43
+ onFocus={() => onHover(true)}
44
+ onBlur={() => onHover(false)}
45
+ className={cx(
46
+ "group relative grid cursor-pointer place-items-center rounded-full outline-none focus-visible:ring-2 focus-visible:ring-ring",
47
+ custom ? "min-h-7 min-w-7" : "size-7",
48
+ )}
49
+ >
50
+ {custom ?? (
51
+ <>
52
+ <span
53
+ aria-hidden="true"
54
+ className={cx(
55
+ "absolute inset-0 rounded-full transition-[transform,opacity] duration-150 motion-reduce:transition-none",
56
+ HALO[tone],
57
+ selected ? "scale-100 opacity-100" : "scale-50 opacity-0",
58
+ )}
59
+ />
60
+ <span
61
+ aria-hidden="true"
62
+ className={cx(
63
+ "relative block size-3.5 rounded-full shadow-sm ring-2 ring-background transition-transform duration-150 motion-reduce:transition-none",
64
+ DOT[tone],
65
+ selected ? "scale-125" : "group-hover:scale-125",
66
+ )}
67
+ />
68
+ </>
69
+ )}
70
+ {showLabel ? (
71
+ <span
72
+ aria-hidden="true"
73
+ className="pointer-events-none absolute bottom-full left-1/2 mb-1 max-w-48 -translate-x-1/2 truncate whitespace-nowrap rounded-md border border-border bg-popover px-2 py-1 text-xs font-medium text-popover-foreground shadow-sm"
74
+ >
75
+ {title}
76
+ </span>
77
+ ) : null}
78
+ </button>
79
+ );
80
+ }
81
+
82
+ /** Several places too close to tell apart at this zoom: a count. */
83
+ export function ClusterMark({ count, label, holdsSelected }) {
84
+ const size = Math.round(32 + Math.min(20, Math.log2(count) * 4));
85
+ return (
86
+ // raw: a cluster is a positioned hit target on the canvas (see PointMark).
87
+ <button
88
+ type="button"
89
+ tabIndex={-1}
90
+ aria-label={label}
91
+ data-lifted={holdsSelected ? "" : undefined}
92
+ style={{ width: size, height: size }}
93
+ className={cx(
94
+ "grid cursor-pointer place-items-center rounded-full bg-primary text-xs font-semibold tabular-nums text-primary-foreground shadow-md",
95
+ "ring-4 ring-primary/20 outline-none transition-[box-shadow,transform] duration-150 hover:scale-105 hover:ring-primary/30",
96
+ "focus-visible:ring-ring motion-reduce:transition-none motion-reduce:hover:scale-100",
97
+ holdsSelected && "outline-2 outline-offset-2 outline-primary",
98
+ )}
99
+ >
100
+ {count > 999 ? `${Math.floor(count / 1000)}k` : count}
101
+ </button>
102
+ );
103
+ }
104
+
105
+ /** The popup's box: a kit-looking card with a close button. */
106
+ export function PopupCard({ onClose, closeLabel = "Close", children }) {
107
+ return (
108
+ <div className="relative w-64 max-w-[calc(100vw-3rem)] rounded-lg border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg">
109
+ <IconButton icon="x" label={closeLabel} size="sm" onClick={onClose} className="absolute right-1 top-1 text-muted-foreground" />
110
+ {children}
111
+ </div>
112
+ );
113
+ }
114
+
115
+ /** The popup's words when the caller brings none: name, meta line, aside. */
116
+ export function DefaultPopup({ title, meta, aside }) {
117
+ return (
118
+ <div className="grid gap-1 pr-8">
119
+ <p className="font-medium leading-5">{title}</p>
120
+ {meta ? <div className="text-muted-foreground">{meta}</div> : null}
121
+ {aside ? <div className="pt-1">{aside}</div> : null}
122
+ </div>
123
+ );
124
+ }
125
+
126
+ /** Places that share one spot (a building, a campus): pick one. */
127
+ export function StackList({ rows, plural, onPick }) {
128
+ return (
129
+ <div className="grid gap-1">
130
+ <p className="pr-8 text-xs text-muted-foreground">
131
+ {rows.length} {plural} at this spot
132
+ </p>
133
+ <div className="-mx-1 max-h-56 overflow-y-auto">
134
+ {rows.map((r) => (
135
+ <Item key={r.id} size="sm" title={r.title} media={<Dot tone={r.tone} />} onClick={() => onPick(r.id)} className="rounded-md" />
136
+ ))}
137
+ </div>
138
+ </div>
139
+ );
140
+ }
141
+
142
+ /** The tone dot the list rows and cards lead with. */
143
+ export function Dot({ tone, missing }) {
144
+ if (missing) return <span aria-hidden="true" className="block size-3 shrink-0 rounded-full border border-dashed border-muted-foreground" />;
145
+ return <span aria-hidden="true" className={cx("block size-3 shrink-0 rounded-full", DOT[tone])} />;
146
+ }
@@ -0,0 +1,142 @@
1
+ // The map in the workspace theme — the one place its look is mapped.
2
+ //
3
+ // Three layers of look, three answers:
4
+ //
5
+ // the tiles a style URL. The default is OpenFreeMap (free, no key,
6
+ // OpenStreetMap data): "positron" in a light scheme,
7
+ // "dark" in a dark one, chosen from the scheme in effect
8
+ // where the map sits and swapped when it changes.
9
+ // our marks markers, clusters, popups, the list and the controls are
10
+ // React, in the kit, in token classes — they follow the
11
+ // theme like any other part of the page.
12
+ // areas polygons drawn BY maplibre need concrete colours, so a
13
+ // tone ("primary", "chart-2") is resolved from the CSS
14
+ // variable at run time (resolveTones) and again when the
15
+ // scheme changes — the sketch-canvas palette trick.
16
+ //
17
+ // maplibre's own chrome (the popup's box and tip, the attribution line,
18
+ // the canvas focus ring) comes from its unlayered stylesheet, which beats
19
+ // any Tailwind utility; the classes in CHROME end in `!` for that reason
20
+ // (the same fix as sketch-canvas/theme.js).
21
+
22
+ /** OpenFreeMap's styles (https://openfreemap.org), checked 2026-09-23. */
23
+ export const MAP_STYLES = {
24
+ positron: "https://tiles.openfreemap.org/styles/positron",
25
+ liberty: "https://tiles.openfreemap.org/styles/liberty",
26
+ bright: "https://tiles.openfreemap.org/styles/bright",
27
+ "dark": "https://tiles.openfreemap.org/styles/dark",
28
+ fiord: "https://tiles.openfreemap.org/styles/fiord",
29
+ };
30
+
31
+ /** What `styleUrl` defaults to: a light and a dark style. */
32
+ export const DEFAULT_STYLE = { "light": MAP_STYLES.positron, "dark": MAP_STYLES.dark }; // keys quoted: the block lint reads `dark:` as a Tailwind variant
33
+
34
+ /** The URL for a scheme, from a string (one style for both) or { light, dark }. */
35
+ export function styleFor(styleUrl, scheme) {
36
+ if (typeof styleUrl === "string" && styleUrl) return styleUrl;
37
+ const s = styleUrl && typeof styleUrl === "object" ? styleUrl : DEFAULT_STYLE;
38
+ return (scheme === "dark" ? s.dark ?? s.light : s.light ?? s.dark) ?? DEFAULT_STYLE[scheme === "dark" ? "dark" : "light"];
39
+ }
40
+
41
+ /** The tones a marker, cluster or area may take: token names, never colours. */
42
+ export const TONES = ["primary", "success", "warning", "destructive", "info", "chart-1", "chart-2", "chart-3", "chart-4", "chart-5", "muted"];
43
+
44
+ // Tailwind needs whole class names in the source: one per tone.
45
+ export const DOT = {
46
+ primary: "bg-primary",
47
+ success: "bg-success",
48
+ warning: "bg-warning",
49
+ destructive: "bg-destructive",
50
+ info: "bg-info",
51
+ "chart-1": "bg-chart-1",
52
+ "chart-2": "bg-chart-2",
53
+ "chart-3": "bg-chart-3",
54
+ "chart-4": "bg-chart-4",
55
+ "chart-5": "bg-chart-5",
56
+ muted: "bg-muted-foreground",
57
+ };
58
+
59
+ export const toneOrDefault = (tone) => (Object.hasOwn(DOT, tone ?? "") ? tone : "primary");
60
+
61
+ /** maplibre's chrome, pointed at tokens. */
62
+ export const CHROME = [
63
+ // the canvas: our focus ring, no browser outline
64
+ "[&_.maplibregl-canvas]:outline-none!",
65
+ "[&_.maplibregl-canvas-container:has(.maplibregl-canvas:focus-visible)]:ring-2!",
66
+ "[&_.maplibregl-canvas-container:has(.maplibregl-canvas:focus-visible)]:ring-inset!",
67
+ "[&_.maplibregl-canvas-container:has(.maplibregl-canvas:focus-visible)]:ring-ring!",
68
+ // popups: the box and tip are ours (MapPopup draws a kit card)
69
+ "[&_.maplibregl-popup-content]:bg-transparent!",
70
+ "[&_.maplibregl-popup-content]:p-0!",
71
+ "[&_.maplibregl-popup-content]:shadow-none!",
72
+ "[&_.maplibregl-popup-content]:rounded-none!",
73
+ "[&_.maplibregl-popup-tip]:hidden!",
74
+ "[&_.maplibregl-popup]:z-10!",
75
+ // the attribution line (OpenStreetMap's licence asks for it: it stays)
76
+ "[&_.maplibregl-ctrl-attrib]:bg-background/80!",
77
+ "[&_.maplibregl-ctrl-attrib]:text-muted-foreground!",
78
+ "[&_.maplibregl-ctrl-attrib]:text-[10px]!",
79
+ "[&_.maplibregl-ctrl-attrib]:leading-4!",
80
+ "[&_.maplibregl-ctrl-attrib]:rounded-tl-md!",
81
+ "[&_.maplibregl-ctrl-attrib]:px-1.5!",
82
+ "[&_.maplibregl-ctrl-attrib_a]:text-muted-foreground!",
83
+ "[&_.maplibregl-ctrl-attrib_a:hover]:text-foreground!",
84
+ "[&_.maplibregl-ctrl-bottom-right]:z-[1]!",
85
+ // markers sit above the canvas, the hovered/selected one above the rest
86
+ "[&_.maplibregl-marker:has([data-lifted])]:z-[2]!",
87
+ ].join(" ");
88
+
89
+ // ---- the browser half -------------------------------------------------------
90
+
91
+ /** The workspace's light or dark where `root` sits: a data-theme on an
92
+ * ancestor, else the computed color-scheme, else the OS setting. */
93
+ export function schemeOf(root) {
94
+ if (typeof window === "undefined" || !root) return "light";
95
+ const scoped = root.closest?.("[data-theme]")?.getAttribute("data-theme");
96
+ if (scoped === "light" || scoped === "dark") return scoped;
97
+ const cs = getComputedStyle(root).colorScheme || "";
98
+ if (/\bdark\b/.test(cs) && !/\blight\b/.test(cs)) return "dark";
99
+ if (/\blight\b/.test(cs) && !/\bdark\b/.test(cs)) return "light";
100
+ return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
101
+ }
102
+
103
+ const byte = (n) => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, "0");
104
+
105
+ /** Each tone → a concrete colour ("#rrggbb"), read from the CSS variables
106
+ * in effect at `root`. A probe takes `color: var(--color-<token>)`; the
107
+ * browser resolves var(), light-dark() and color-mix(); a 1×1 canvas
108
+ * turns whatever syntax comes back into bytes. */
109
+ export function resolveTones(root, tones = TONES) {
110
+ const out = {};
111
+ if (typeof document === "undefined" || !root) return out;
112
+ const probe = document.createElement("span");
113
+ probe.setAttribute("aria-hidden", "true");
114
+ probe.style.cssText = "position:absolute;visibility:hidden;pointer-events:none";
115
+ root.appendChild(probe);
116
+ const canvas = document.createElement("canvas");
117
+ canvas.width = 1;
118
+ canvas.height = 1;
119
+ const ctx = canvas.getContext("2d", { willReadFrequently: true });
120
+ try {
121
+ for (const tone of tones) {
122
+ probe.style.color = "";
123
+ probe.style.color = `var(--color-${tone === "muted" ? "muted-foreground" : tone})`;
124
+ const computed = getComputedStyle(probe).color;
125
+ if (!computed || !ctx) continue;
126
+ ctx.clearRect(0, 0, 1, 1);
127
+ ctx.fillStyle = "transparent";
128
+ ctx.fillStyle = computed;
129
+ ctx.fillRect(0, 0, 1, 1);
130
+ const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data;
131
+ if (a) out[tone] = "#" + byte(r) + byte(g) + byte(b);
132
+ }
133
+ } finally {
134
+ probe.remove();
135
+ }
136
+ return out;
137
+ }
138
+
139
+ /** Does the viewer ask for less motion? Camera moves then jump. */
140
+ export function prefersReducedMotion() {
141
+ return typeof window !== "undefined" && Boolean(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches);
142
+ }
@@ -0,0 +1,109 @@
1
+ # Menubar
2
+
3
+ A desktop app's menu bar: File, Edit, View, Help. Each menu is the kit's
4
+ Menu panel, so it takes the same `items` — actions with shortcuts,
5
+ checkboxes, radio groups, labelled groups, separators and submenus. Click
6
+ a menu to open it; once one is open, hovering another switches to it.
7
+ ArrowLeft and ArrowRight move along the bar, and open the neighbour when
8
+ a menu is open. ArrowDown, Enter or Space open a menu at its first item.
9
+ Escape closes it and puts focus back on its name. The bar is one Tab
10
+ stop (roving focus), with the `menubar` and `menuitem` roles. Below the
11
+ `md` breakpoint the bar is one menu button; each menu is a submenu in it
12
+ that unfolds in place.
13
+
14
+ ```jsx
15
+ import { Menubar } from "../components/blocks/menubar"; // a Makersclaw app ("./blocks/menubar" from components/)
16
+ import { Menubar } from "@/components/makersclaw/blocks/menubar"; // a shadcn project
17
+ ```
18
+
19
+ It is a client component: render it from a `"use client"` component.
20
+
21
+ ## The data
22
+
23
+ `menus` is the bar, in order:
24
+
25
+ ```js
26
+ {
27
+ label: "View", // the name in the bar
28
+ items: [ … ], // the menu: exactly Menu's `items` (components/ui/menu.jsx)
29
+ icon?: "eye", // shown beside the name in the phone menu only
30
+ key?: "view", // default: made from the position and label
31
+ }
32
+ ```
33
+
34
+ `items` entries, any mix:
35
+
36
+ ```js
37
+ { label: "Save", onSelect, shortcut: "⌘S", icon?, tone?: "danger", disabled?, description? } // an action: closes the menu
38
+ { type: "checkbox", label: "Show ruler", checked, onCheckedChange(next) } // stays open
39
+ { type: "radio", label: "Zoom", value, onValueChange(value), options: ["75%", "100%"] } // stays open
40
+ { group: "Share", items: [ … ] } // a labelled group
41
+ { type: "separator" }
42
+ { label: "Export", items: [ … ] } // a submenu
43
+ ```
44
+
45
+ A falsy entry is skipped, so `cond && { … }` works. A menu with no items
46
+ is left out of the bar. A shortcut is only drawn: the app binds the key
47
+ itself.
48
+
49
+ ## Props
50
+
51
+ - `menus` — the bar, as above.
52
+ - `label` — what a screen reader calls the bar, default `"Menu bar"`.
53
+ Name it after what it drives: `"Document"`.
54
+ - `menuLabel` — the phone's menu button, default `"Menu"`.
55
+ - `className` — layout around it (width, margin). Never colour.
56
+
57
+ ## Example
58
+
59
+ ```jsx
60
+ // components/Editor.jsx — client: the bar over the document
61
+ "use client";
62
+ import { useState } from "react";
63
+ import { toast } from "./ui";
64
+ import { Menubar } from "./blocks/menubar";
65
+
66
+ export default function Editor({ doc, onSave }) {
67
+ const [ruler, setRuler] = useState(true);
68
+ const [zoom, setZoom] = useState("100%");
69
+ return (
70
+ <div className="grid gap-4">
71
+ <Menubar
72
+ label="Document"
73
+ menus={[
74
+ {
75
+ label: "File",
76
+ items: [
77
+ { label: "Save", shortcut: "⌘S", onSelect: async () => ((await onSave(doc)).ok ? toast.success("Saved") : toast.error("Could not save")) },
78
+ { label: "Export", items: [{ label: "PDF", onSelect: () => {} }, { label: "Markdown", onSelect: () => {} }] },
79
+ ],
80
+ },
81
+ {
82
+ label: "View",
83
+ items: [
84
+ { type: "checkbox", label: "Show ruler", checked: ruler, onCheckedChange: setRuler },
85
+ { type: "separator" },
86
+ { type: "radio", label: "Zoom", value: zoom, onValueChange: setZoom, options: ["75%", "100%", "150%"] },
87
+ ],
88
+ },
89
+ ]}
90
+ />
91
+ {/* the document */}
92
+ </div>
93
+ );
94
+ }
95
+ ```
96
+
97
+ ## What it will not do
98
+
99
+ - Bind shortcuts: `shortcut` is a hint drawn in the menu. Listen for the
100
+ key in your component when it should work without the menu.
101
+ - Hold state: checkboxes and radios are controlled — keep `checked` and
102
+ `value` in your component, as above.
103
+ - Be a site's navigation: links belong in the navigation-menu block.
104
+ - Open on hover before a click: like a desktop app, the first menu opens
105
+ on a click or a key.
106
+
107
+ A menubar it cannot be is your own component in `components/`, built from
108
+ the kit — not an edit to this block. Its files are fixed: `npm run check`
109
+ refuses a change, and `makersclaw add menubar` restores them.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "menubar",
3
+ "title": "Menubar",
4
+ "description": "A desktop app's menu bar — File, Edit, View, Help — each a menu of actions with shortcuts, checkboxes, radio groups and submenus; click to open, hover to switch, arrow keys along the bar; one menu button on a phone.",
5
+ "useWhen": "A document-style tool with many commands grouped by kind: an editor, a canvas, a spreadsheet, an admin console that mimics a desktop app. Not for a site's navigation (a navigation menu) or one record's actions (a menu on the row).",
6
+ "tags": ["menubar", "menu bar", "menu", "file menu", "edit menu", "view menu", "commands", "shortcuts", "editor", "toolbar", "desktop", "dropdown"],
7
+ "exports": ["Menubar"],
8
+ "files": ["index.js", "menubar.jsx"],
9
+ "requires": []
10
+ }
@@ -0,0 +1,128 @@
1
+ "use client";
2
+
3
+ // The Menubar over a document editor — the gallery's and the smoke test's
4
+ // surface. Not installed into apps: `makersclaw add menubar` lays index.js
5
+ // and menubar.jsx only. Commands only report themselves under the page;
6
+ // "Show ruler", "Word count" and "Zoom" change the page for real.
7
+ import { useState } from "react";
8
+ import { Badge, Card } from "../components/ui";
9
+ import { Menubar } from "../components/blocks/menubar";
10
+
11
+ const TEXT = [
12
+ "Northwind closed the quarter at 118% of plan, carried by three enterprise renewals and a pricing change that lifted average contract value by a fifth.",
13
+ "For Q4 we propose two hires in customer success, a partner programme with the two agencies already reselling us, and a freeze on new paid channels until payback drops under nine months.",
14
+ ];
15
+ const WORDS = TEXT.join(" ").split(/\s+/).length;
16
+ const ZOOMS = ["75%", "100%", "125%", "150%"];
17
+
18
+ export default function MenubarDemo() {
19
+ const [ruler, setRuler] = useState(true);
20
+ const [count, setCount] = useState(false);
21
+ const [zoom, setZoom] = useState("100%");
22
+ const [last, setLast] = useState(null);
23
+ const run = (name) => () => setLast(name);
24
+
25
+ const menus = [
26
+ {
27
+ label: "File",
28
+ icon: "file",
29
+ items: [
30
+ { label: "New document", shortcut: "⌘N", onSelect: run("New document") },
31
+ { label: "Open…", shortcut: "⌘O", onSelect: run("Open") },
32
+ {
33
+ label: "Open recent",
34
+ items: [
35
+ { label: "Q3 board memo", onSelect: run("Open Q3 board memo") },
36
+ { label: "Hiring plan 2027", onSelect: run("Open Hiring plan 2027") },
37
+ { label: "Pricing page draft", onSelect: run("Open Pricing page draft") },
38
+ ],
39
+ },
40
+ { type: "separator" },
41
+ { label: "Save", shortcut: "⌘S", onSelect: run("Save") },
42
+ { label: "Save as…", shortcut: "⇧⌘S", onSelect: run("Save as") },
43
+ {
44
+ label: "Export",
45
+ icon: "download",
46
+ items: [
47
+ { label: "PDF", onSelect: run("Export as PDF") },
48
+ { label: "Word (.docx)", onSelect: run("Export as Word") },
49
+ { label: "Markdown", onSelect: run("Export as Markdown") },
50
+ ],
51
+ },
52
+ { type: "separator" },
53
+ { label: "Print…", shortcut: "⌘P", onSelect: run("Print") },
54
+ { label: "Move to trash", icon: "trash", tone: "danger", onSelect: run("Move to trash") },
55
+ ],
56
+ },
57
+ {
58
+ label: "Edit",
59
+ icon: "pencil",
60
+ items: [
61
+ { label: "Undo", shortcut: "⌘Z", onSelect: run("Undo") },
62
+ { label: "Redo", shortcut: "⇧⌘Z", onSelect: run("Redo") },
63
+ { type: "separator" },
64
+ { label: "Cut", shortcut: "⌘X", onSelect: run("Cut") },
65
+ { label: "Copy", shortcut: "⌘C", onSelect: run("Copy") },
66
+ { label: "Paste", shortcut: "⌘V", onSelect: run("Paste") },
67
+ { label: "Paste without formatting", shortcut: "⌥⇧⌘V", onSelect: run("Paste without formatting"), disabled: true },
68
+ { type: "separator" },
69
+ { label: "Find and replace", shortcut: "⌘F", onSelect: run("Find and replace") },
70
+ { label: "Select all", shortcut: "⌘A", onSelect: run("Select all") },
71
+ ],
72
+ },
73
+ {
74
+ label: "View",
75
+ icon: "eye",
76
+ items: [
77
+ { type: "checkbox", label: "Show ruler", checked: ruler, onCheckedChange: setRuler, shortcut: "⌘R" },
78
+ { type: "checkbox", label: "Word count", checked: count, onCheckedChange: setCount, shortcut: "⇧⌘C" },
79
+ { type: "separator" },
80
+ { type: "radio", label: "Zoom", value: zoom, onValueChange: setZoom, options: ZOOMS },
81
+ { type: "separator" },
82
+ { label: "Full screen", shortcut: "⌃⌘F", onSelect: run("Full screen") },
83
+ ],
84
+ },
85
+ {
86
+ label: "Help",
87
+ icon: "info",
88
+ items: [
89
+ { label: "Keyboard shortcuts", shortcut: "⌘/", onSelect: run("Keyboard shortcuts") },
90
+ { label: "What's new", onSelect: run("What's new") },
91
+ { type: "separator" },
92
+ { label: "Contact support", icon: "mail", onSelect: run("Contact support") },
93
+ ],
94
+ },
95
+ ];
96
+
97
+ return (
98
+ <div className="grid gap-4">
99
+ <Menubar menus={menus} label="Document" />
100
+ <Card className="overflow-hidden p-0">
101
+ {ruler ? (
102
+ <div aria-hidden="true" className="flex h-6 items-end border-b border-border bg-muted px-6">
103
+ {Array.from({ length: 24 }, (_, i) => (
104
+ <span key={i} className={i % 4 === 0 ? "h-3 flex-1 border-l border-muted-foreground pl-0.5 text-2xs leading-none text-muted-foreground" : "h-1.5 flex-1 border-l border-border"}>
105
+ {i % 4 === 0 ? i / 4 : null}
106
+ </span>
107
+ ))}
108
+ </div>
109
+ ) : null}
110
+ <article className="grid gap-3 p-6" style={{ fontSize: zoom }}>
111
+ <h2 className="text-[1.25em] font-semibold leading-tight">Q3 board memo</h2>
112
+ {TEXT.map((p) => (
113
+ <p key={p} className="text-[0.875em] leading-relaxed text-muted-foreground">
114
+ {p}
115
+ </p>
116
+ ))}
117
+ </article>
118
+ <div className="flex flex-wrap items-center gap-2 border-t border-border px-6 py-2 text-xs text-muted-foreground">
119
+ <Badge>{zoom}</Badge>
120
+ {count ? <span data-nums>{WORDS} words</span> : null}
121
+ <span className="ml-auto" aria-live="polite">
122
+ {last ? `Ran: ${last}` : "Pick a command from the bar"}
123
+ </span>
124
+ </div>
125
+ </Card>
126
+ </div>
127
+ );
128
+ }
@@ -0,0 +1,4 @@
1
+ // The Menubar block — `makersclaw add menubar`. Fixed: compose it through
2
+ // its props (README.md beside this file); a menubar it cannot be is your
3
+ // own component in components/.
4
+ export { Menubar } from "./menubar";