makersclaw 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -1
  3. package/THIRD-PARTY-NOTICES.md +180 -0
  4. package/package.json +15 -8
  5. package/r/annotate.json +62 -0
  6. package/r/approval-request.json +52 -0
  7. package/r/audio-player.json +74 -0
  8. package/r/auth-form.json +55 -0
  9. package/r/board.json +55 -0
  10. package/r/calendar-view.json +105 -0
  11. package/r/cart.json +62 -0
  12. package/r/chart.json +83 -0
  13. package/r/chat.json +95 -0
  14. package/r/code-editor.json +94 -0
  15. package/r/comment-box.json +64 -0
  16. package/r/contact-section.json +53 -0
  17. package/r/core.json +341 -0
  18. package/r/csv-import.json +63 -0
  19. package/r/data-table.json +69 -0
  20. package/r/diagram.json +74 -0
  21. package/r/doc-editor.json +82 -0
  22. package/r/doc-page.json +61 -0
  23. package/r/email-render.json +73 -0
  24. package/r/faq.json +50 -0
  25. package/r/file-upload.json +54 -0
  26. package/r/flow-canvas.json +93 -0
  27. package/r/footer.json +52 -0
  28. package/r/gantt.json +70 -0
  29. package/r/job-panel.json +56 -0
  30. package/r/json-editor.json +66 -0
  31. package/r/map.json +89 -0
  32. package/r/menubar.json +52 -0
  33. package/r/mind-map.json +67 -0
  34. package/r/navigation-menu.json +52 -0
  35. package/r/order-detail.json +54 -0
  36. package/r/org-chart.json +66 -0
  37. package/r/page-builder.json +105 -0
  38. package/r/payment-methods.json +51 -0
  39. package/r/pdf-document.json +79 -0
  40. package/r/pdf-viewer.json +88 -0
  41. package/r/product-detail.json +76 -0
  42. package/r/product-grid.json +65 -0
  43. package/r/record-form.json +67 -0
  44. package/r/record-notes.json +55 -0
  45. package/r/registry.json +3612 -0
  46. package/r/search-dialog.json +51 -0
  47. package/r/settings-list.json +66 -0
  48. package/r/setup-checklist.json +51 -0
  49. package/r/share-dialog.json +52 -0
  50. package/r/sidebar.json +69 -0
  51. package/r/signature-pad.json +72 -0
  52. package/r/sketch-canvas.json +99 -0
  53. package/r/spreadsheet.json +90 -0
  54. package/r/stat-cards.json +66 -0
  55. package/r/task-list.json +63 -0
  56. package/r/task-model.json +98 -0
  57. package/r/testimonials.json +52 -0
  58. package/r/transaction-list.json +53 -0
  59. package/r/whiteboard.json +66 -0
  60. package/registry/blocks/annotate/README.md +179 -0
  61. package/registry/blocks/annotate/annotate-data.js +250 -0
  62. package/registry/blocks/annotate/annotate.jsx +646 -0
  63. package/registry/blocks/annotate/block.json +10 -0
  64. package/registry/blocks/annotate/demo.jsx +135 -0
  65. package/registry/blocks/annotate/index.js +15 -0
  66. package/registry/blocks/approval-request/README.md +116 -0
  67. package/registry/blocks/approval-request/approval-request.jsx +386 -0
  68. package/registry/blocks/approval-request/block.json +10 -0
  69. package/registry/blocks/approval-request/demo.jsx +127 -0
  70. package/registry/blocks/approval-request/index.js +4 -0
  71. package/registry/blocks/audio-player/README.md +167 -0
  72. package/registry/blocks/audio-player/audio-player.jsx +623 -0
  73. package/registry/blocks/audio-player/block.json +14 -0
  74. package/registry/blocks/audio-player/colors.js +109 -0
  75. package/registry/blocks/audio-player/demo.jsx +209 -0
  76. package/registry/blocks/audio-player/index.js +6 -0
  77. package/registry/blocks/audio-player/time.js +67 -0
  78. package/registry/blocks/audio-player/wavesurfer.js +9 -0
  79. package/registry/blocks/auth-form/README.md +126 -0
  80. package/registry/blocks/auth-form/auth-form.jsx +568 -0
  81. package/registry/blocks/auth-form/block.json +10 -0
  82. package/registry/blocks/auth-form/demo.jsx +131 -0
  83. package/registry/blocks/auth-form/index.js +3 -0
  84. package/registry/blocks/board/README.md +64 -13
  85. package/registry/blocks/board/block.json +2 -2
  86. package/registry/blocks/board/board.jsx +237 -94
  87. package/registry/blocks/board/demo.jsx +103 -24
  88. package/registry/blocks/calendar-view/README.md +180 -0
  89. package/registry/blocks/calendar-view/agenda.jsx +147 -0
  90. package/registry/blocks/calendar-view/block.json +76 -0
  91. package/registry/blocks/calendar-view/calendar-model.js +442 -0
  92. package/registry/blocks/calendar-view/calendar.jsx +627 -0
  93. package/registry/blocks/calendar-view/demo.jsx +195 -0
  94. package/registry/blocks/calendar-view/draft.jsx +49 -0
  95. package/registry/blocks/calendar-view/index.js +39 -0
  96. package/registry/blocks/calendar-view/month.jsx +346 -0
  97. package/registry/blocks/calendar-view/paint.js +69 -0
  98. package/registry/blocks/calendar-view/time-grid.jsx +527 -0
  99. package/registry/blocks/calendar-view/tray.jsx +87 -0
  100. package/registry/blocks/cart/README.md +146 -0
  101. package/registry/blocks/cart/block.json +10 -0
  102. package/registry/blocks/cart/cart.jsx +597 -0
  103. package/registry/blocks/cart/demo.jsx +98 -0
  104. package/registry/blocks/cart/index.js +4 -0
  105. package/registry/blocks/cart/money.js +28 -0
  106. package/registry/blocks/chart/README.md +316 -0
  107. package/registry/blocks/chart/block.json +10 -0
  108. package/registry/blocks/chart/cartesian.jsx +642 -0
  109. package/registry/blocks/chart/core.jsx +262 -0
  110. package/registry/blocks/chart/demo.jsx +357 -0
  111. package/registry/blocks/chart/heatmap.jsx +336 -0
  112. package/registry/blocks/chart/index.js +8 -0
  113. package/registry/blocks/chart/pie.jsx +245 -0
  114. package/registry/blocks/chart/sparkline.jsx +88 -0
  115. package/registry/blocks/chat/README.md +273 -0
  116. package/registry/blocks/chat/attachment.jsx +95 -0
  117. package/registry/blocks/chat/block.json +10 -0
  118. package/registry/blocks/chat/chat.jsx +132 -0
  119. package/registry/blocks/chat/composer.jsx +364 -0
  120. package/registry/blocks/chat/demo.jsx +578 -0
  121. package/registry/blocks/chat/header.jsx +34 -0
  122. package/registry/blocks/chat/index.js +9 -0
  123. package/registry/blocks/chat/message.jsx +450 -0
  124. package/registry/blocks/chat/scroller.jsx +247 -0
  125. package/registry/blocks/chat/text.jsx +104 -0
  126. package/registry/blocks/code-editor/README.md +210 -0
  127. package/registry/blocks/code-editor/block.json +22 -0
  128. package/registry/blocks/code-editor/code-editor.jsx +534 -0
  129. package/registry/blocks/code-editor/codemirror.js +38 -0
  130. package/registry/blocks/code-editor/demo.jsx +205 -0
  131. package/registry/blocks/code-editor/index.js +8 -0
  132. package/registry/blocks/code-editor/json.js +317 -0
  133. package/registry/blocks/code-editor/sql.js +136 -0
  134. package/registry/blocks/code-editor/text.js +101 -0
  135. package/registry/blocks/code-editor/theme.js +186 -0
  136. package/registry/blocks/comment-box/README.md +123 -0
  137. package/registry/blocks/comment-box/block.json +10 -0
  138. package/registry/blocks/comment-box/comment-body.jsx +217 -0
  139. package/registry/blocks/comment-box/comment-box.jsx +198 -0
  140. package/registry/blocks/comment-box/comment-time.jsx +77 -0
  141. package/registry/blocks/comment-box/demo.jsx +141 -0
  142. package/registry/blocks/comment-box/index.js +8 -0
  143. package/registry/blocks/contact-section/README.md +152 -0
  144. package/registry/blocks/contact-section/block.json +11 -0
  145. package/registry/blocks/contact-section/contact-section.jsx +509 -0
  146. package/registry/blocks/contact-section/demo.jsx +93 -0
  147. package/registry/blocks/contact-section/index.js +4 -0
  148. package/registry/blocks/csv-import/README.md +133 -0
  149. package/registry/blocks/csv-import/block.json +13 -0
  150. package/registry/blocks/csv-import/csv-import.jsx +479 -0
  151. package/registry/blocks/csv-import/demo.jsx +106 -0
  152. package/registry/blocks/csv-import/import.js +200 -0
  153. package/registry/blocks/csv-import/index.js +7 -0
  154. package/registry/blocks/data-table/README.md +386 -0
  155. package/registry/blocks/data-table/block.json +10 -0
  156. package/registry/blocks/data-table/data-table.jsx +1164 -0
  157. package/registry/blocks/data-table/demo.jsx +588 -0
  158. package/registry/blocks/data-table/index.js +5 -0
  159. package/registry/blocks/data-table/model.js +169 -0
  160. package/registry/blocks/diagram/README.md +108 -0
  161. package/registry/blocks/diagram/block.json +13 -0
  162. package/registry/blocks/diagram/demo.jsx +113 -0
  163. package/registry/blocks/diagram/diagram.jsx +481 -0
  164. package/registry/blocks/diagram/index.js +7 -0
  165. package/registry/blocks/diagram/mermaid.js +52 -0
  166. package/registry/blocks/diagram/palette.js +313 -0
  167. package/registry/blocks/diagram/source.js +98 -0
  168. package/registry/blocks/doc-editor/README.md +215 -0
  169. package/registry/blocks/doc-editor/block.json +15 -0
  170. package/registry/blocks/doc-editor/demo.jsx +225 -0
  171. package/registry/blocks/doc-editor/doc-editor.jsx +291 -0
  172. package/registry/blocks/doc-editor/doc.js +309 -0
  173. package/registry/blocks/doc-editor/index.js +7 -0
  174. package/registry/blocks/doc-editor/schema.jsx +56 -0
  175. package/registry/blocks/doc-editor/shadcn-classes.js +110 -0
  176. package/registry/blocks/doc-editor/theme.js +82 -0
  177. package/registry/blocks/doc-page/README.md +119 -0
  178. package/registry/blocks/doc-page/autosave.js +104 -0
  179. package/registry/blocks/doc-page/block.json +10 -0
  180. package/registry/blocks/doc-page/demo.jsx +137 -0
  181. package/registry/blocks/doc-page/doc-page.jsx +276 -0
  182. package/registry/blocks/doc-page/index.js +4 -0
  183. package/registry/blocks/email-render/README.md +151 -0
  184. package/registry/blocks/email-render/block.json +14 -0
  185. package/registry/blocks/email-render/demo.jsx +153 -0
  186. package/registry/blocks/email-render/doc-email.jsx +210 -0
  187. package/registry/blocks/email-render/email.jsx +221 -0
  188. package/registry/blocks/email-render/index.js +10 -0
  189. package/registry/blocks/email-render/render.js +50 -0
  190. package/registry/blocks/email-render/theme.js +215 -0
  191. package/registry/blocks/faq/README.md +101 -0
  192. package/registry/blocks/faq/block.json +11 -0
  193. package/registry/blocks/faq/demo.jsx +89 -0
  194. package/registry/blocks/faq/faq.jsx +220 -0
  195. package/registry/blocks/faq/index.js +4 -0
  196. package/registry/blocks/file-upload/README.md +138 -0
  197. package/registry/blocks/file-upload/block.json +10 -0
  198. package/registry/blocks/file-upload/demo.jsx +204 -0
  199. package/registry/blocks/file-upload/file-upload.jsx +635 -0
  200. package/registry/blocks/file-upload/index.js +4 -0
  201. package/registry/blocks/flow-canvas/README.md +420 -0
  202. package/registry/blocks/flow-canvas/block.json +13 -0
  203. package/registry/blocks/flow-canvas/board.js +819 -0
  204. package/registry/blocks/flow-canvas/chrome.jsx +649 -0
  205. package/registry/blocks/flow-canvas/context.jsx +35 -0
  206. package/registry/blocks/flow-canvas/demo.jsx +249 -0
  207. package/registry/blocks/flow-canvas/edges.jsx +107 -0
  208. package/registry/blocks/flow-canvas/flow-canvas.jsx +1329 -0
  209. package/registry/blocks/flow-canvas/index.js +41 -0
  210. package/registry/blocks/flow-canvas/nodes.jsx +392 -0
  211. package/registry/blocks/flow-canvas/theme.js +174 -0
  212. package/registry/blocks/footer/README.md +133 -0
  213. package/registry/blocks/footer/block.json +11 -0
  214. package/registry/blocks/footer/demo.jsx +119 -0
  215. package/registry/blocks/footer/footer.jsx +406 -0
  216. package/registry/blocks/footer/index.js +4 -0
  217. package/registry/blocks/gantt/README.md +220 -0
  218. package/registry/blocks/gantt/block.json +10 -0
  219. package/registry/blocks/gantt/demo.jsx +148 -0
  220. package/registry/blocks/gantt/gantt.jsx +923 -0
  221. package/registry/blocks/gantt/index.js +7 -0
  222. package/registry/blocks/gantt/rows.jsx +468 -0
  223. package/registry/blocks/gantt/schedule.js +278 -0
  224. package/registry/blocks/job-panel/README.md +86 -2
  225. package/registry/blocks/job-panel/block.json +3 -3
  226. package/registry/blocks/job-panel/demo.jsx +230 -3
  227. package/registry/blocks/job-panel/job-panel.jsx +169 -3
  228. package/registry/blocks/json-editor/README.md +133 -0
  229. package/registry/blocks/json-editor/block.json +10 -0
  230. package/registry/blocks/json-editor/demo.jsx +92 -0
  231. package/registry/blocks/json-editor/index.js +7 -0
  232. package/registry/blocks/json-editor/json-editor.jsx +305 -0
  233. package/registry/blocks/json-editor/json-tree.jsx +393 -0
  234. package/registry/blocks/json-editor/tree.js +225 -0
  235. package/registry/blocks/map/README.md +221 -0
  236. package/registry/blocks/map/block.json +14 -0
  237. package/registry/blocks/map/demo.jsx +201 -0
  238. package/registry/blocks/map/geo.js +198 -0
  239. package/registry/blocks/map/index.js +8 -0
  240. package/registry/blocks/map/list.jsx +128 -0
  241. package/registry/blocks/map/map-view.jsx +715 -0
  242. package/registry/blocks/map/maplibre.js +30 -0
  243. package/registry/blocks/map/marks.jsx +146 -0
  244. package/registry/blocks/map/theme.js +142 -0
  245. package/registry/blocks/menubar/README.md +109 -0
  246. package/registry/blocks/menubar/block.json +10 -0
  247. package/registry/blocks/menubar/demo.jsx +128 -0
  248. package/registry/blocks/menubar/index.js +4 -0
  249. package/registry/blocks/menubar/menubar.jsx +199 -0
  250. package/registry/blocks/mind-map/README.md +206 -0
  251. package/registry/blocks/mind-map/block.json +10 -0
  252. package/registry/blocks/mind-map/demo.jsx +103 -0
  253. package/registry/blocks/mind-map/index.js +31 -0
  254. package/registry/blocks/mind-map/mind-map.jsx +1125 -0
  255. package/registry/blocks/mind-map/topic.jsx +143 -0
  256. package/registry/blocks/mind-map/tree.js +645 -0
  257. package/registry/blocks/navigation-menu/README.md +124 -0
  258. package/registry/blocks/navigation-menu/block.json +10 -0
  259. package/registry/blocks/navigation-menu/demo.jsx +84 -0
  260. package/registry/blocks/navigation-menu/index.js +4 -0
  261. package/registry/blocks/navigation-menu/navigation-menu.jsx +448 -0
  262. package/registry/blocks/order-detail/README.md +109 -0
  263. package/registry/blocks/order-detail/block.json +10 -0
  264. package/registry/blocks/order-detail/demo.jsx +88 -0
  265. package/registry/blocks/order-detail/index.js +4 -0
  266. package/registry/blocks/order-detail/order-detail.jsx +354 -0
  267. package/registry/blocks/org-chart/README.md +145 -0
  268. package/registry/blocks/org-chart/block.json +10 -0
  269. package/registry/blocks/org-chart/demo.jsx +94 -0
  270. package/registry/blocks/org-chart/index.js +7 -0
  271. package/registry/blocks/org-chart/org-chart.jsx +631 -0
  272. package/registry/blocks/org-chart/org.js +245 -0
  273. package/registry/blocks/org-chart/person.jsx +96 -0
  274. package/registry/blocks/page-builder/README.md +257 -0
  275. package/registry/blocks/page-builder/block.json +14 -0
  276. package/registry/blocks/page-builder/demo.jsx +145 -0
  277. package/registry/blocks/page-builder/grapes.js +18 -0
  278. package/registry/blocks/page-builder/index.js +11 -0
  279. package/registry/blocks/page-builder/page-builder.jsx +704 -0
  280. package/registry/blocks/page-builder/page-view.jsx +33 -0
  281. package/registry/blocks/page-builder/page.js +118 -0
  282. package/registry/blocks/page-builder/panels.jsx +588 -0
  283. package/registry/blocks/page-builder/sections.js +209 -0
  284. package/registry/blocks/page-builder/theme.js +87 -0
  285. package/registry/blocks/page-builder/thumbs.jsx +189 -0
  286. package/registry/blocks/page-builder/tokens.js +329 -0
  287. package/registry/blocks/payment-methods/README.md +104 -0
  288. package/registry/blocks/payment-methods/block.json +10 -0
  289. package/registry/blocks/payment-methods/demo.jsx +71 -0
  290. package/registry/blocks/payment-methods/index.js +4 -0
  291. package/registry/blocks/payment-methods/payment-methods.jsx +302 -0
  292. package/registry/blocks/pdf-document/README.md +213 -0
  293. package/registry/blocks/pdf-document/block.json +13 -0
  294. package/registry/blocks/pdf-document/demo.jsx +136 -0
  295. package/registry/blocks/pdf-document/index.js +33 -0
  296. package/registry/blocks/pdf-document/money.js +83 -0
  297. package/registry/blocks/pdf-document/pdf-document.jsx +144 -0
  298. package/registry/blocks/pdf-document/primitives.jsx +271 -0
  299. package/registry/blocks/pdf-document/quote.jsx +179 -0
  300. package/registry/blocks/pdf-document/theme.js +193 -0
  301. package/registry/blocks/pdf-viewer/README.md +191 -0
  302. package/registry/blocks/pdf-viewer/block.json +14 -0
  303. package/registry/blocks/pdf-viewer/demo.jsx +252 -0
  304. package/registry/blocks/pdf-viewer/helpers.js +270 -0
  305. package/registry/blocks/pdf-viewer/index.js +8 -0
  306. package/registry/blocks/pdf-viewer/notes.jsx +195 -0
  307. package/registry/blocks/pdf-viewer/pdf-viewer.jsx +1368 -0
  308. package/registry/blocks/pdf-viewer/pdfjs.js +37 -0
  309. package/registry/blocks/pdf-viewer/ssr-shim-end.js +6 -0
  310. package/registry/blocks/pdf-viewer/ssr-shim.js +44 -0
  311. package/registry/blocks/product-detail/README.md +217 -0
  312. package/registry/blocks/product-detail/block.json +10 -0
  313. package/registry/blocks/product-detail/demo.jsx +233 -0
  314. package/registry/blocks/product-detail/index.js +7 -0
  315. package/registry/blocks/product-detail/price.jsx +115 -0
  316. package/registry/blocks/product-detail/product-detail.jsx +348 -0
  317. package/registry/blocks/product-detail/product-media.jsx +102 -0
  318. package/registry/blocks/product-detail/product-options.jsx +144 -0
  319. package/registry/blocks/product-grid/README.md +162 -0
  320. package/registry/blocks/product-grid/block.json +10 -0
  321. package/registry/blocks/product-grid/demo.jsx +255 -0
  322. package/registry/blocks/product-grid/index.js +5 -0
  323. package/registry/blocks/product-grid/product-card.jsx +232 -0
  324. package/registry/blocks/product-grid/product-grid.jsx +235 -0
  325. package/registry/blocks/record-form/README.md +196 -0
  326. package/registry/blocks/record-form/block.json +10 -0
  327. package/registry/blocks/record-form/demo.jsx +525 -0
  328. package/registry/blocks/record-form/index.js +4 -0
  329. package/registry/blocks/record-form/record-fields.jsx +457 -0
  330. package/registry/blocks/record-form/record-form.jsx +415 -0
  331. package/registry/blocks/record-form/rules.js +81 -0
  332. package/registry/blocks/record-notes/README.md +139 -0
  333. package/registry/blocks/record-notes/block.json +10 -0
  334. package/registry/blocks/record-notes/demo.jsx +179 -0
  335. package/registry/blocks/record-notes/index.js +4 -0
  336. package/registry/blocks/record-notes/record-notes.jsx +266 -0
  337. package/registry/blocks/search-dialog/README.md +108 -0
  338. package/registry/blocks/search-dialog/block.json +10 -0
  339. package/registry/blocks/search-dialog/demo.jsx +116 -0
  340. package/registry/blocks/search-dialog/index.js +3 -0
  341. package/registry/blocks/search-dialog/search-dialog.jsx +235 -0
  342. package/registry/blocks/settings-list/README.md +171 -0
  343. package/registry/blocks/settings-list/block.json +10 -0
  344. package/registry/blocks/settings-list/demo.jsx +333 -0
  345. package/registry/blocks/settings-list/index.js +4 -0
  346. package/registry/blocks/settings-list/row-state.jsx +93 -0
  347. package/registry/blocks/settings-list/settings-list.jsx +349 -0
  348. package/registry/blocks/settings-list/settings-matrix.jsx +118 -0
  349. package/registry/blocks/setup-checklist/README.md +142 -0
  350. package/registry/blocks/setup-checklist/block.json +10 -0
  351. package/registry/blocks/setup-checklist/demo.jsx +159 -0
  352. package/registry/blocks/setup-checklist/index.js +4 -0
  353. package/registry/blocks/setup-checklist/setup-checklist.jsx +446 -0
  354. package/registry/blocks/share-dialog/README.md +113 -0
  355. package/registry/blocks/share-dialog/block.json +10 -0
  356. package/registry/blocks/share-dialog/demo.jsx +140 -0
  357. package/registry/blocks/share-dialog/index.js +3 -0
  358. package/registry/blocks/share-dialog/share-dialog.jsx +384 -0
  359. package/registry/blocks/sidebar/README.md +190 -0
  360. package/registry/blocks/sidebar/block.json +43 -0
  361. package/registry/blocks/sidebar/demo.jsx +577 -0
  362. package/registry/blocks/sidebar/index.js +4 -0
  363. package/registry/blocks/sidebar/sidebar-panel.jsx +149 -0
  364. package/registry/blocks/sidebar/sidebar.jsx +864 -0
  365. package/registry/blocks/signature-pad/README.md +137 -0
  366. package/registry/blocks/signature-pad/block.json +13 -0
  367. package/registry/blocks/signature-pad/colors.js +115 -0
  368. package/registry/blocks/signature-pad/demo.jsx +94 -0
  369. package/registry/blocks/signature-pad/index.js +6 -0
  370. package/registry/blocks/signature-pad/pad.js +7 -0
  371. package/registry/blocks/signature-pad/signature-pad.jsx +434 -0
  372. package/registry/blocks/signature-pad/signature.js +68 -0
  373. package/registry/blocks/sketch-canvas/README.md +280 -0
  374. package/registry/blocks/sketch-canvas/block.json +13 -0
  375. package/registry/blocks/sketch-canvas/demo.jsx +159 -0
  376. package/registry/blocks/sketch-canvas/excalidraw.js +40 -0
  377. package/registry/blocks/sketch-canvas/index.js +9 -0
  378. package/registry/blocks/sketch-canvas/palette.js +226 -0
  379. package/registry/blocks/sketch-canvas/sketch-canvas.jsx +1188 -0
  380. package/registry/blocks/sketch-canvas/sketch.js +179 -0
  381. package/registry/blocks/sketch-canvas/ssr-shim-end.js +6 -0
  382. package/registry/blocks/sketch-canvas/ssr-shim.js +45 -0
  383. package/registry/blocks/sketch-canvas/stamps.js +104 -0
  384. package/registry/blocks/sketch-canvas/theme.js +131 -0
  385. package/registry/blocks/spreadsheet/README.md +307 -0
  386. package/registry/blocks/spreadsheet/block.json +13 -0
  387. package/registry/blocks/spreadsheet/cells.jsx +455 -0
  388. package/registry/blocks/spreadsheet/chrome.jsx +325 -0
  389. package/registry/blocks/spreadsheet/demo.jsx +177 -0
  390. package/registry/blocks/spreadsheet/grid.js +387 -0
  391. package/registry/blocks/spreadsheet/index.js +34 -0
  392. package/registry/blocks/spreadsheet/spreadsheet.jsx +1732 -0
  393. package/registry/blocks/spreadsheet/types.js +473 -0
  394. package/registry/blocks/stat-cards/README.md +173 -0
  395. package/registry/blocks/stat-cards/block.json +10 -0
  396. package/registry/blocks/stat-cards/demo.jsx +257 -0
  397. package/registry/blocks/stat-cards/index.js +4 -0
  398. package/registry/blocks/stat-cards/stat-cards.jsx +307 -0
  399. package/registry/blocks/stat-cards/usage.jsx +243 -0
  400. package/registry/blocks/task-list/README.md +176 -0
  401. package/registry/blocks/task-list/block.json +10 -0
  402. package/registry/blocks/task-list/demo.jsx +134 -0
  403. package/registry/blocks/task-list/index.js +5 -0
  404. package/registry/blocks/task-list/task-list.jsx +907 -0
  405. package/registry/blocks/task-model/README.md +455 -0
  406. package/registry/blocks/task-model/block.json +167 -0
  407. package/registry/blocks/task-model/changes.js +89 -0
  408. package/registry/blocks/task-model/dates.js +371 -0
  409. package/registry/blocks/task-model/demo.jsx +215 -0
  410. package/registry/blocks/task-model/dnd.jsx +240 -0
  411. package/registry/blocks/task-model/index.js +97 -0
  412. package/registry/blocks/task-model/model.js +919 -0
  413. package/registry/blocks/task-model/parts.jsx +449 -0
  414. package/registry/blocks/task-model/toolbar.jsx +271 -0
  415. package/registry/blocks/testimonials/README.md +139 -0
  416. package/registry/blocks/testimonials/block.json +11 -0
  417. package/registry/blocks/testimonials/demo.jsx +137 -0
  418. package/registry/blocks/testimonials/index.js +4 -0
  419. package/registry/blocks/testimonials/testimonials.jsx +430 -0
  420. package/registry/blocks/transaction-list/README.md +126 -0
  421. package/registry/blocks/transaction-list/block.json +10 -0
  422. package/registry/blocks/transaction-list/demo.jsx +79 -0
  423. package/registry/blocks/transaction-list/index.js +4 -0
  424. package/registry/blocks/transaction-list/transaction-list.jsx +383 -0
  425. package/registry/blocks/whiteboard/README.md +179 -0
  426. package/registry/blocks/whiteboard/block.json +10 -0
  427. package/registry/blocks/whiteboard/demo.jsx +169 -0
  428. package/registry/blocks/whiteboard/index.js +6 -0
  429. package/registry/blocks/whiteboard/templates.js +150 -0
  430. package/registry/blocks/whiteboard/whiteboard.jsx +721 -0
  431. package/src/install.mjs +18 -0
  432. package/src/shadcn.mjs +171 -0
  433. package/templates/next/files/README.md +145 -11
  434. package/templates/next/files/app/globals.css +55 -4
  435. package/templates/next/files/check/run.mjs +3 -3
  436. package/templates/next/files/components/parts/fixture.jsx +1 -1
  437. package/templates/next/files/components/parts/sample.js +15 -0
  438. package/templates/next/files/components/ui/avatar.jsx +141 -0
  439. package/templates/next/files/components/ui/breadcrumb.jsx +149 -0
  440. package/templates/next/files/components/ui/button-group.jsx +70 -0
  441. package/templates/next/files/components/ui/button.jsx +132 -12
  442. package/templates/next/files/components/ui/calendar.jsx +609 -0
  443. package/templates/next/files/components/ui/carousel.jsx +281 -0
  444. package/templates/next/files/components/ui/collapsible.jsx +208 -0
  445. package/templates/next/files/components/ui/combobox.jsx +608 -0
  446. package/templates/next/files/components/ui/command.jsx +577 -0
  447. package/templates/next/files/components/ui/context-menu.jsx +191 -0
  448. package/templates/next/files/components/ui/date-picker.jsx +360 -0
  449. package/templates/next/files/components/ui/distribution.jsx +117 -0
  450. package/templates/next/files/components/ui/feedback.jsx +143 -0
  451. package/templates/next/files/components/ui/field.jsx +115 -3
  452. package/templates/next/files/components/ui/file-input.jsx +234 -0
  453. package/templates/next/files/components/ui/icon.jsx +130 -8
  454. package/templates/next/files/components/ui/image.jsx +143 -0
  455. package/templates/next/files/components/ui/index.js +47 -2
  456. package/templates/next/files/components/ui/input-group.jsx +213 -0
  457. package/templates/next/files/components/ui/input-otp.jsx +170 -0
  458. package/templates/next/files/components/ui/item.jsx +206 -0
  459. package/templates/next/files/components/ui/menu.jsx +454 -82
  460. package/templates/next/files/components/ui/notice.jsx +126 -14
  461. package/templates/next/files/components/ui/pagination.jsx +156 -0
  462. package/templates/next/files/components/ui/popover.jsx +284 -0
  463. package/templates/next/files/components/ui/radio.jsx +193 -0
  464. package/templates/next/files/components/ui/rating.jsx +131 -0
  465. package/templates/next/files/components/ui/resizable.jsx +338 -0
  466. package/templates/next/files/components/ui/scroll-area.jsx +123 -0
  467. package/templates/next/files/components/ui/separator.jsx +119 -0
  468. package/templates/next/files/components/ui/sheet.jsx +96 -11
  469. package/templates/next/files/components/ui/slider.jsx +174 -0
  470. package/templates/next/files/components/ui/stat.jsx +574 -0
  471. package/templates/next/files/components/ui/steps.jsx +338 -0
  472. package/templates/next/files/components/ui/swatch.jsx +33 -0
  473. package/templates/next/files/components/ui/table.jsx +130 -0
  474. package/templates/next/files/components/ui/toast.jsx +440 -0
  475. package/templates/next/files/components/ui/toggle.jsx +195 -0
  476. package/templates/next/files/components/ui/tooltip.jsx +270 -0
  477. package/templates/next/files/lib/sample.js +4 -12
  478. package/templates/next/template.json +264 -8
@@ -0,0 +1,642 @@
1
+ "use client";
2
+
3
+ import { useId, useMemo, useState } from "react";
4
+ import { cx } from "../../ui";
5
+ import {
6
+ ChartEmpty,
7
+ ChartLegend,
8
+ DataTable,
9
+ TooltipBox,
10
+ defaultFormat,
11
+ humanize,
12
+ idFrom,
13
+ niceTicks,
14
+ num,
15
+ textWidth,
16
+ tone,
17
+ toneOf,
18
+ useReveal,
19
+ useWidth,
20
+ } from "./core";
21
+
22
+ // LineChart, AreaChart and BarChart — one drawing, three marks. Rows in,
23
+ // one x key, the series to draw; the block owns the rest: the scale and its
24
+ // round ticks, gridlines, labels thinned to fit, a width that follows the
25
+ // container, the tooltip and crosshair under a pointer or the arrow keys,
26
+ // the legend that hides a series, the reveal (none with reduced motion),
27
+ // and the words and table a screen reader gets instead of the picture.
28
+
29
+ // ---- paths -------------------------------------------------------------------
30
+
31
+ const f = (n) => Math.round(n * 100) / 100;
32
+
33
+ function linear(pts) {
34
+ return pts.map(([x, y], i) => `${i ? "L" : "M"}${f(x)},${f(y)}`).join("");
35
+ }
36
+
37
+ function step(pts) {
38
+ let d = `M${f(pts[0][0])},${f(pts[0][1])}`;
39
+ for (let i = 1; i < pts.length; i++) {
40
+ const mid = (pts[i - 1][0] + pts[i][0]) / 2;
41
+ d += `H${f(mid)}V${f(pts[i][1])}H${f(pts[i][0])}`;
42
+ }
43
+ return d;
44
+ }
45
+
46
+ // Monotone cubic (Fritsch–Carlson): smooth, and never overshoots a point,
47
+ // so a curve does not invent a dip below zero or a peak that was not there.
48
+ function monotone(pts) {
49
+ const n = pts.length;
50
+ if (n < 3) return linear(pts);
51
+ const dx = [];
52
+ const m = [];
53
+ for (let i = 0; i < n - 1; i++) {
54
+ dx[i] = pts[i + 1][0] - pts[i][0];
55
+ m[i] = dx[i] === 0 ? 0 : (pts[i + 1][1] - pts[i][1]) / dx[i];
56
+ }
57
+ const t = new Array(n);
58
+ t[0] = m[0];
59
+ t[n - 1] = m[n - 2];
60
+ for (let i = 1; i < n - 1; i++) {
61
+ t[i] = m[i - 1] * m[i] <= 0 ? 0 : (3 * (dx[i - 1] + dx[i])) / ((2 * dx[i] + dx[i - 1]) / m[i - 1] + (dx[i] + 2 * dx[i - 1]) / m[i]);
62
+ }
63
+ let d = `M${f(pts[0][0])},${f(pts[0][1])}`;
64
+ for (let i = 0; i < n - 1; i++) {
65
+ const h = dx[i] / 3;
66
+ d += `C${f(pts[i][0] + h)},${f(pts[i][1] + t[i] * h)} ${f(pts[i + 1][0] - h)},${f(pts[i + 1][1] - t[i + 1] * h)} ${f(pts[i + 1][0])},${f(pts[i + 1][1])}`;
67
+ }
68
+ return d;
69
+ }
70
+
71
+ function curvePath(pts, curve) {
72
+ if (!pts.length) return "";
73
+ if (curve === "step") return step(pts);
74
+ if (curve === "linear") return linear(pts);
75
+ return monotone(pts);
76
+ }
77
+
78
+ // A bar with its outer end rounded (the end away from zero).
79
+ function barPath(x, y, w, h, r, side) {
80
+ const q = Math.max(0, Math.min(r, w / 2, h / 2));
81
+ if (!q || !side) return `M${f(x)},${f(y)}h${f(w)}v${f(h)}h${f(-w)}Z`;
82
+ const X = f(x);
83
+ const Y = f(y);
84
+ if (side === "top") return `M${X},${f(y + h)}V${f(y + q)}Q${X},${Y} ${f(x + q)},${Y}H${f(x + w - q)}Q${f(x + w)},${Y} ${f(x + w)},${f(y + q)}V${f(y + h)}Z`;
85
+ if (side === "bottom") return `M${X},${Y}V${f(y + h - q)}Q${X},${f(y + h)} ${f(x + q)},${f(y + h)}H${f(x + w - q)}Q${f(x + w)},${f(y + h)} ${f(x + w)},${f(y + h - q)}V${Y}Z`;
86
+ if (side === "right") return `M${X},${Y}H${f(x + w - q)}Q${f(x + w)},${Y} ${f(x + w)},${f(y + q)}V${f(y + h - q)}Q${f(x + w)},${f(y + h)} ${f(x + w - q)},${f(y + h)}H${X}Z`;
87
+ return `M${f(x + w)},${Y}H${f(x + q)}Q${X},${Y} ${X},${f(y + q)}V${f(y + h - q)}Q${X},${f(y + h)} ${f(x + q)},${f(y + h)}H${f(x + w)}Z`;
88
+ }
89
+
90
+ // ---- the chart ----------------------------------------------------------------
91
+
92
+ function Cartesian({
93
+ kind,
94
+ data,
95
+ x,
96
+ series,
97
+ format = defaultFormat,
98
+ formatAxis,
99
+ formatX = (v) => (v == null ? "" : String(v)),
100
+ label = "Chart",
101
+ description,
102
+ xLabel,
103
+ height = 240,
104
+ stacked = false,
105
+ orientation = "vertical",
106
+ valueLabels = false,
107
+ track = false,
108
+ curve = "monotone",
109
+ dots = false,
110
+ grid = true,
111
+ xAxis = true,
112
+ yAxis = true,
113
+ legend,
114
+ tooltip = true,
115
+ onSelect,
116
+ emptyLabel = "No data yet",
117
+ emptyBody,
118
+ className,
119
+ }) {
120
+ const uid = idFrom(useId());
121
+ const fmt = (v) => (v == null ? "—" : format(v));
122
+ const [boxRef, width] = useWidth();
123
+ const [hidden, setHidden] = useState(() => new Set());
124
+ const [active, setActive] = useState(null);
125
+ const [keyed, setKeyed] = useState(false);
126
+
127
+ const rows = Array.isArray(data) ? data : [];
128
+ // A `muted` series with no tone of its own is the grey: a comparison
129
+ // (last period) that sits behind the series it is compared with.
130
+ const all = useMemo(
131
+ () => (series ?? []).map((s, i) => ({ ...s, label: s.label ?? humanize(s.key), tone: s.muted && s.tone == null ? "muted" : toneOf(s, i) })),
132
+ [series],
133
+ );
134
+ const live = all.filter((s) => !hidden.has(s.key));
135
+ // Lines and areas draw muted series first, so they sit underneath.
136
+ const order = live.map((_, j) => j).sort((a, b) => Number(Boolean(live[b].muted)) - Number(Boolean(live[a].muted)));
137
+ const horizontal = kind === "bar" && orientation === "horizontal";
138
+ const stack = stacked && kind !== "line";
139
+ const axisFormat = formatAxis ?? format;
140
+ const showLegend = legend ?? all.length > 1;
141
+ const shown = useReveal(width > 0);
142
+
143
+ // Each series' [from, to] per row: stacked marks start where the one
144
+ // below ended (positives up, negatives down); the rest start at zero.
145
+ const spans = useMemo(() => {
146
+ const up = rows.map(() => 0);
147
+ const down = rows.map(() => 0);
148
+ return live.map((s) =>
149
+ rows.map((r, i) => {
150
+ const v = num(r?.[s.key]);
151
+ if (v == null) return null;
152
+ if (!stack) return [0, v];
153
+ if (v >= 0) {
154
+ const from = up[i];
155
+ up[i] += v;
156
+ return [from, up[i]];
157
+ }
158
+ const from = down[i];
159
+ down[i] += v;
160
+ return [from, down[i]];
161
+ }),
162
+ );
163
+ }, [rows, live, stack]); // eslint-disable-line react-hooks/exhaustive-deps
164
+
165
+ let lo = 0;
166
+ let hi = 0;
167
+ for (const s of spans) for (const p of s) if (p) (lo = Math.min(lo, p[0], p[1])), (hi = Math.max(hi, p[0], p[1]));
168
+ const valueLen = horizontal ? Math.max(0, width - 16) : height - 32;
169
+ const ticks = niceTicks(lo, hi, Math.max(2, Math.min(6, Math.floor(valueLen / (horizontal ? 80 : 48)))));
170
+ const vMin = ticks[0];
171
+ const vMax = ticks[ticks.length - 1];
172
+
173
+ const xNames = rows.map((r) => formatX(r?.[x], r));
174
+ const tickNames = ticks.map((t) => axisFormat(t));
175
+
176
+ // BarChart's value labels: one at the outer end of every bar, or of every
177
+ // stack (its total). [{ i, j, v, text }]; j is the series (-1: a stack).
178
+ const barLabels = [];
179
+ if (kind === "bar" && valueLabels && live.length) {
180
+ const say = (v, row, key) => (typeof valueLabels === "function" ? valueLabels(v, row, key) : fmt(v));
181
+ rows.forEach((row, i) => {
182
+ if (stack) {
183
+ const vals = live.map((s) => num(row?.[s.key])).filter((v) => v != null);
184
+ if (!vals.length) return;
185
+ const v = vals.reduce((a, b) => a + b, 0);
186
+ barLabels.push({ i, j: -1, v, text: say(v, row, null) });
187
+ } else {
188
+ live.forEach((s, j) => {
189
+ const v = num(row?.[s.key]);
190
+ if (v != null) barLabels.push({ i, j, v, text: say(v, row, s.key) });
191
+ });
192
+ }
193
+ });
194
+ }
195
+ const labelRoom = barLabels.length ? Math.max(...barLabels.map((l) => textWidth(l.text))) + 6 : 0;
196
+
197
+ // Margins from what the labels need.
198
+ const catW = horizontal && yAxis ? Math.min(Math.max(...xNames.map(textWidth), 24) + 8, width * 0.4) : 0;
199
+ const valW = !horizontal && yAxis ? Math.max(...tickNames.map(textWidth)) + 8 : 0;
200
+ const m = {
201
+ top: barLabels.length && !horizontal ? 22 : 8,
202
+ right: horizontal ? Math.max(8, textWidth(tickNames[tickNames.length - 1]) / 2, labelRoom) : 8,
203
+ bottom: xAxis ? 24 : 4,
204
+ left: horizontal ? catW : valW,
205
+ };
206
+ // Points sit on the plot's edges (bars sit inside their band), so the
207
+ // first and last x labels, centred on them, need room outside it.
208
+ if (kind !== "bar" && xAxis && rows.length) {
209
+ m.left = Math.max(m.left, textWidth(xNames[0]) / 2);
210
+ m.right = Math.max(m.right, textWidth(xNames[xNames.length - 1]) / 2);
211
+ }
212
+ const plotW = Math.max(0, width - m.left - m.right);
213
+ const plotH = Math.max(0, height - m.top - m.bottom);
214
+ const n = rows.length;
215
+
216
+ // Value → pixel along the value axis; index → pixel along the category axis.
217
+ const vPos = (v) => (horizontal ? m.left + ((v - vMin) / (vMax - vMin || 1)) * plotW : m.top + plotH - ((v - vMin) / (vMax - vMin || 1)) * plotH);
218
+ const band = (horizontal ? plotH : plotW) / Math.max(1, n);
219
+ const cPos =
220
+ kind === "bar"
221
+ ? (i) => (horizontal ? m.top : m.left) + band * (i + 0.5)
222
+ : (i) => m.left + (n === 1 ? plotW / 2 : (i * plotW) / (n - 1));
223
+ const zero = vPos(Math.max(vMin, Math.min(0, vMax)));
224
+
225
+ // Category labels thinned so they never collide.
226
+ const labelEvery = horizontal
227
+ ? Math.max(1, Math.ceil(16 / Math.max(1, band)))
228
+ : Math.max(1, Math.ceil((Math.max(...xNames.map(textWidth), 0) + 12) / Math.max(1, kind === "bar" ? band : plotW / Math.max(1, n - 1))));
229
+
230
+ function indexAt(e) {
231
+ const rect = e.currentTarget.getBoundingClientRect();
232
+ const p = horizontal ? e.clientY - rect.top : e.clientX - rect.left;
233
+ if (kind === "bar") return Math.max(0, Math.min(n - 1, Math.floor((p - (horizontal ? m.top : m.left)) / band)));
234
+ if (n === 1) return 0;
235
+ return Math.max(0, Math.min(n - 1, Math.round(((p - m.left) / plotW) * (n - 1))));
236
+ }
237
+
238
+ function onKeyDown(e) {
239
+ if (!n) return;
240
+ const back = horizontal ? "ArrowUp" : "ArrowLeft";
241
+ const fwd = horizontal ? "ArrowDown" : "ArrowRight";
242
+ let next = null;
243
+ if (e.key === fwd || e.key === (horizontal ? "ArrowRight" : "ArrowDown")) next = active == null ? 0 : Math.min(n - 1, active + 1);
244
+ else if (e.key === back || e.key === (horizontal ? "ArrowLeft" : "ArrowUp")) next = active == null ? n - 1 : Math.max(0, active - 1);
245
+ else if (e.key === "Home") next = 0;
246
+ else if (e.key === "End") next = n - 1;
247
+ else if (e.key === "Escape") {
248
+ setActive(null);
249
+ return;
250
+ } else if ((e.key === "Enter" || e.key === " ") && onSelect && active != null) {
251
+ e.preventDefault();
252
+ onSelect(rows[active], active);
253
+ return;
254
+ }
255
+ if (next == null) return;
256
+ e.preventDefault();
257
+ setKeyed(true);
258
+ setActive(next);
259
+ }
260
+
261
+ // ---- words -------------------------------------------------------------------
262
+
263
+ const summary = useMemo(() => {
264
+ if (!n || !live.length) return "";
265
+ const parts = live.map((s) => {
266
+ const vals = rows.map((r) => num(r?.[s.key]));
267
+ const idx = vals.reduce((best, v, i) => (v != null && (best < 0 || v > vals[best]) ? i : best), -1);
268
+ const first = vals.find((v) => v != null);
269
+ const last = [...vals].reverse().find((v) => v != null);
270
+ return `${s.label}: ${kind === "bar" ? "" : `from ${fmt(first)} to ${fmt(last)}, `}highest ${fmt(vals[idx])} at ${xNames[idx]}`;
271
+ });
272
+ return `${n} ${n === 1 ? "point" : "points"}, ${xNames[0]} to ${xNames[n - 1]}. ${parts.join("; ")}.`;
273
+ }, [rows, live, n]); // eslint-disable-line react-hooks/exhaustive-deps
274
+
275
+ const tipRows =
276
+ active == null
277
+ ? []
278
+ : live.map((s) => ({ key: s.key, label: s.label, tone: s.tone, dashed: s.dashed, value: fmt(num(rows[active]?.[s.key])) }));
279
+ const total = active == null ? null : live.reduce((sum, s) => sum + (num(rows[active]?.[s.key]) ?? 0), 0);
280
+ const announce = active == null ? "" : `${xNames[active]}: ${tipRows.map((r) => `${r.label} ${r.value}`).join(", ")}`;
281
+
282
+ const legendNode = showLegend ? (
283
+ <ChartLegend
284
+ items={all}
285
+ hidden={hidden}
286
+ onToggle={(key) =>
287
+ setHidden((h) => {
288
+ const next = new Set(h);
289
+ if (next.has(key)) next.delete(key);
290
+ else next.add(key);
291
+ return next;
292
+ })
293
+ }
294
+ label={`${label}: series`}
295
+ />
296
+ ) : null;
297
+
298
+ if (!n) {
299
+ return (
300
+ <div className={cx("grid gap-3", className)}>
301
+ <ChartEmpty height={height} title={emptyLabel} body={emptyBody} />
302
+ </div>
303
+ );
304
+ }
305
+
306
+ // ---- marks -------------------------------------------------------------------
307
+
308
+ const tipAt =
309
+ active == null || !tooltip
310
+ ? null
311
+ : horizontal
312
+ ? { x: Math.min(width - 12, Math.max(...live.map((_, k) => vPos(spans[k][active]?.[1] ?? 0)), zero)), y: cPos(active), flip: false, middle: true }
313
+ : { x: cPos(active), y: m.top, flip: cPos(active) > width / 2 };
314
+ if (tipAt && horizontal) tipAt.flip = tipAt.x > width * 0.6;
315
+
316
+ const revealStyle = (axis) => ({
317
+ transform: shown ? "none" : axis === "x" ? "scaleX(0)" : "scaleY(0)",
318
+ transformOrigin: axis === "x" ? `${zero}px 0` : `0 ${zero}px`,
319
+ });
320
+
321
+ let marks = null;
322
+ if (kind === "bar") {
323
+ const k = live.length;
324
+ const groupW = Math.min(band * (stack ? 0.62 : 0.8), stack ? 56 : 28 * Math.max(1, k) + 4 * (k - 1));
325
+ const gap = k > 1 && !stack ? Math.min(4, groupW * 0.06) : 0;
326
+ const barW = stack ? groupW : Math.max(1, (groupW - gap * (k - 1)) / Math.max(1, k));
327
+ const r = Math.min(4, barW / 3);
328
+ // Which series ends each stack (its outer end is the rounded one).
329
+ const outer = rows.map((_, i) => {
330
+ let top = -1;
331
+ let bottom = -1;
332
+ live.forEach((s, j) => {
333
+ const p = spans[j][i];
334
+ if (!p || p[1] === p[0]) return;
335
+ if (p[1] > p[0]) top = j;
336
+ else bottom = j;
337
+ });
338
+ return { top, bottom };
339
+ });
340
+ // Where the stacked total ends: the far end of the stack on its side.
341
+ const stackEnd = (i, v) => {
342
+ let end = 0;
343
+ live.forEach((_, j) => {
344
+ const p = spans[j][i];
345
+ if (p) end = v >= 0 ? Math.max(end, p[1]) : Math.min(end, p[1]);
346
+ });
347
+ return end;
348
+ };
349
+ const tracks = track ? (
350
+ <g aria-hidden="true" className="fill-accent">
351
+ {rows.map((_, i) => {
352
+ const c = cPos(i) - groupW / 2;
353
+ return horizontal ? (
354
+ <rect key={i} x={m.left} y={c} width={plotW} height={groupW} rx={r} />
355
+ ) : (
356
+ <rect key={i} x={c} y={m.top} width={groupW} height={plotH} rx={r} />
357
+ );
358
+ })}
359
+ </g>
360
+ ) : null;
361
+ const labels = barLabels.length ? (
362
+ <g
363
+ aria-hidden="true"
364
+ className="fill-foreground text-2xs font-medium motion-safe:transition-opacity motion-safe:duration-500"
365
+ style={{ opacity: shown ? 1 : 0 }}
366
+ data-nums
367
+ >
368
+ {barLabels.map(({ i, j, v, text }) => {
369
+ const end = vPos(j < 0 ? stackEnd(i, v) : v);
370
+ const c = cPos(i) + (j < 0 ? 0 : -groupW / 2 + j * (barW + gap) + barW / 2);
371
+ const up = v >= 0;
372
+ return horizontal ? (
373
+ <text key={`${i}-${j}`} x={end + (up ? 6 : -6)} y={c} dy="0.32em" textAnchor={up ? "start" : "end"}>
374
+ {text}
375
+ </text>
376
+ ) : (
377
+ <text key={`${i}-${j}`} x={c} y={end + (up ? -6 : 12)} textAnchor="middle">
378
+ {text}
379
+ </text>
380
+ );
381
+ })}
382
+ </g>
383
+ ) : null;
384
+ marks = (
385
+ <>
386
+ {tracks}
387
+ <g style={revealStyle(horizontal ? "x" : "y")} className="motion-safe:transition-transform motion-safe:duration-500 motion-safe:ease-out">
388
+ {live.map((s, j) => (
389
+ <g key={s.key} className={tone(s.tone, "fill")}>
390
+ {rows.map((_, i) => {
391
+ const p = spans[j][i];
392
+ if (!p || p[0] === p[1]) return null;
393
+ const a = vPos(p[0]);
394
+ const b = vPos(p[1]);
395
+ const offset = stack ? -groupW / 2 : -groupW / 2 + j * (barW + gap);
396
+ const c = cPos(i) + offset;
397
+ const positive = p[1] > p[0];
398
+ const isOuter = !stack || (positive ? outer[i].top === j : outer[i].bottom === j);
399
+ const side = !isOuter ? null : horizontal ? (positive ? "right" : "left") : positive ? "top" : "bottom";
400
+ const d = horizontal
401
+ ? barPath(Math.min(a, b), c, Math.abs(b - a), barW, r, side)
402
+ : barPath(c, Math.min(a, b), barW, Math.abs(b - a), r, side);
403
+ return <path key={i} d={d} className={cx(active != null && active !== i && "opacity-60", "motion-safe:transition-opacity")} />;
404
+ })}
405
+ </g>
406
+ ))}
407
+ </g>
408
+ {labels}
409
+ </>
410
+ );
411
+ } else {
412
+ const clip = `${uid}-clip`;
413
+ const fade = `${uid}-fade`;
414
+ marks = (
415
+ <>
416
+ <defs>
417
+ <clipPath id={clip}>
418
+ <rect
419
+ x={m.left - 4}
420
+ y={0}
421
+ width={plotW + 8}
422
+ height={height}
423
+ style={{ transform: shown ? "none" : "scaleX(0)", transformOrigin: `${m.left}px 0` }}
424
+ className="motion-safe:transition-transform motion-safe:duration-700 motion-safe:ease-out"
425
+ />
426
+ </clipPath>
427
+ {/* An alpha mask, not a colour: the area fades toward zero. */}
428
+ <linearGradient id={`${fade}-g`} x1="0" y1="0" x2="0" y2="1">
429
+ <stop offset="0" stopOpacity="1" />
430
+ <stop offset="1" stopOpacity="0.15" />
431
+ </linearGradient>
432
+ <mask id={fade} style={{ maskType: "alpha" }} maskUnits="userSpaceOnUse" x={0} y={0} width={width} height={height}>
433
+ <rect x={0} y={m.top} width={width} height={plotH} fill={`url(#${fade}-g)`} />
434
+ </mask>
435
+ </defs>
436
+ <g clipPath={`url(#${clip})`}>
437
+ {kind === "area"
438
+ ? order.map((j) => {
439
+ const s = live[j];
440
+ // A dashed series is a line only: a comparison has no fill.
441
+ if (s.dashed && !stack) return null;
442
+ const top = [];
443
+ const base = [];
444
+ spans[j].forEach((p, i) => {
445
+ top.push([cPos(i), vPos(p ? p[1] : stack ? 0 : 0)]);
446
+ base.push([cPos(i), vPos(p ? p[0] : 0)]);
447
+ });
448
+ const back = curvePath([...base].reverse(), curve).replace(/^M/, "L");
449
+ return (
450
+ <path
451
+ key={s.key}
452
+ d={`${curvePath(top, curve)}${back}Z`}
453
+ className={tone(s.tone, "fill")}
454
+ fillOpacity={stack ? 0.4 : s.muted ? 0.2 : 0.45}
455
+ mask={stack ? undefined : `url(#${fade})`}
456
+ />
457
+ );
458
+ })
459
+ : null}
460
+ {order.map((j) => {
461
+ const s = live[j];
462
+ // A line breaks where a value is missing.
463
+ const segs = [];
464
+ let cur = [];
465
+ spans[j].forEach((p, i) => {
466
+ if (!p && kind === "line") {
467
+ if (cur.length) segs.push(cur);
468
+ cur = [];
469
+ return;
470
+ }
471
+ cur.push([cPos(i), vPos(p ? p[1] : 0)]);
472
+ });
473
+ if (cur.length) segs.push(cur);
474
+ return (
475
+ <g
476
+ key={s.key}
477
+ className={tone(s.tone, "stroke")}
478
+ fill="none"
479
+ strokeWidth={s.muted ? 1.5 : 2}
480
+ strokeDasharray={s.dashed ? "5 4" : undefined}
481
+ strokeLinejoin="round"
482
+ strokeLinecap={s.dashed ? "butt" : "round"}
483
+ >
484
+ {segs.map((seg, k) => (
485
+ <path key={k} d={curvePath(seg, curve)} />
486
+ ))}
487
+ {dots
488
+ ? spans[j].map((p, i) =>
489
+ p ? <circle key={i} cx={cPos(i)} cy={vPos(p[1])} r={3} className={cx(tone(s.tone, "fill"), "stroke-card")} strokeWidth={1.5} strokeDasharray="none" /> : null,
490
+ )
491
+ : null}
492
+ </g>
493
+ );
494
+ })}
495
+ </g>
496
+ </>
497
+ );
498
+ }
499
+
500
+ const cursor =
501
+ active == null
502
+ ? null
503
+ : kind === "bar"
504
+ ? horizontal
505
+ ? <rect x={m.left} y={m.top + band * active} width={plotW} height={band} className="fill-muted" />
506
+ : <rect x={m.left + band * active} y={m.top} width={band} height={plotH} className="fill-muted" />
507
+ : <line x1={cPos(active)} x2={cPos(active)} y1={m.top} y2={m.top + plotH} className="stroke-muted-foreground" strokeDasharray="3 3" strokeWidth={1} />;
508
+
509
+ const activeDots =
510
+ active == null || kind === "bar"
511
+ ? null
512
+ : live.map((s, j) => {
513
+ const p = spans[j][active];
514
+ if (!p) return null;
515
+ return <circle key={s.key} cx={cPos(active)} cy={vPos(p[1])} r={4.5} className={cx(tone(s.tone, "fill"), "stroke-card")} strokeWidth={2} />;
516
+ });
517
+
518
+ return (
519
+ <div className={cx("grid min-w-0 gap-3", className)}>
520
+ <div
521
+ ref={boxRef}
522
+ tabIndex={0}
523
+ role="group"
524
+ aria-label={`${label}. Arrow keys read each value.`}
525
+ onKeyDown={onKeyDown}
526
+ onFocus={(e) => {
527
+ if (e.currentTarget.matches(":focus-visible") && active == null) {
528
+ setKeyed(true);
529
+ setActive(0);
530
+ }
531
+ }}
532
+ onBlur={() => {
533
+ setKeyed(false);
534
+ setActive(null);
535
+ }}
536
+ className="relative min-w-0 rounded-md outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
537
+ style={{ height }}
538
+ >
539
+ {width > 0 ? (
540
+ <svg
541
+ role="img"
542
+ aria-label={`${label}. ${description ?? summary}`}
543
+ width={width}
544
+ height={height}
545
+ viewBox={`0 0 ${width} ${height}`}
546
+ className={cx("block touch-pan-y select-none overflow-visible", onSelect && "cursor-pointer")}
547
+ onPointerMove={(e) => {
548
+ setKeyed(false);
549
+ setActive(indexAt(e));
550
+ }}
551
+ onPointerDown={(e) => setActive(indexAt(e))}
552
+ onPointerLeave={() => !keyed && setActive(null)}
553
+ onClick={(e) => onSelect?.(rows[indexAt(e)], indexAt(e))}
554
+ >
555
+ {/* raw: an SVG drawing — no kit part draws a chart. */}
556
+ {cursor}
557
+ {grid
558
+ ? ticks.map((t) => {
559
+ const p = f(vPos(t));
560
+ return horizontal ? (
561
+ <line key={t} x1={p} x2={p} y1={m.top} y2={m.top + plotH} className="stroke-border" strokeDasharray={t === 0 ? undefined : "3 3"} />
562
+ ) : (
563
+ <line key={t} x1={m.left} x2={m.left + plotW} y1={p} y2={p} className="stroke-border" strokeDasharray={t === 0 ? undefined : "3 3"} />
564
+ );
565
+ })
566
+ : null}
567
+ {marks}
568
+ {activeDots}
569
+ <g aria-hidden="true" className="fill-muted-foreground text-2xs" data-nums>
570
+ {/* The value axis. */}
571
+ {(horizontal ? xAxis : yAxis)
572
+ ? ticks.map((t, i) =>
573
+ horizontal ? (
574
+ <text key={t} x={vPos(t)} y={height - 6} textAnchor="middle">
575
+ {tickNames[i]}
576
+ </text>
577
+ ) : (
578
+ <text key={t} x={m.left - 8} y={vPos(t)} dy="0.32em" textAnchor="end">
579
+ {tickNames[i]}
580
+ </text>
581
+ ),
582
+ )
583
+ : null}
584
+ {/* The category axis. */}
585
+ {(horizontal ? yAxis : xAxis)
586
+ ? xNames.map((name, i) => {
587
+ if (i % labelEvery !== 0) return null;
588
+ if (horizontal) {
589
+ return (
590
+ <text key={i} x={m.left - 8} y={cPos(i)} dy="0.32em" textAnchor="end">
591
+ {name}
592
+ </text>
593
+ );
594
+ }
595
+ return (
596
+ <text key={i} x={cPos(i)} y={height - 6} textAnchor="middle">
597
+ {name}
598
+ </text>
599
+ );
600
+ })
601
+ : null}
602
+ </g>
603
+ </svg>
604
+ ) : null}
605
+ {tipAt ? (
606
+ <TooltipBox
607
+ at={tipAt}
608
+ title={xNames[active]}
609
+ rows={tipRows}
610
+ footer={stack && live.length > 1 ? { label: "Total", value: fmt(total) } : null}
611
+ />
612
+ ) : null}
613
+ <div className="sr-only" aria-live="polite">
614
+ {keyed ? announce : ""}
615
+ </div>
616
+ </div>
617
+ {live.length === 0 ? <p className="text-center text-xs text-muted-foreground">Every series is hidden. Press one below to show it.</p> : null}
618
+ {legendNode}
619
+ <DataTable
620
+ caption={label}
621
+ head={[xLabel ?? humanize(x), ...all.map((s) => s.label)]}
622
+ body={rows.map((r, i) => [xNames[i], ...all.map((s) => fmt(num(r?.[s.key])))])}
623
+ />
624
+ </div>
625
+ );
626
+ }
627
+
628
+ /** Values over an ordered x (time): lines, optionally curved or stepped. */
629
+ export function LineChart(props) {
630
+ return <Cartesian {...props} kind="line" />;
631
+ }
632
+
633
+ /** Lines filled to zero; `stacked` piles the series into a total. */
634
+ export function AreaChart(props) {
635
+ return <Cartesian {...props} kind="area" />;
636
+ }
637
+
638
+ /** Bars per category: grouped side by side, or `stacked`; columns
639
+ * (`orientation="vertical"`, the default) or bars (`"horizontal"`). */
640
+ export function BarChart(props) {
641
+ return <Cartesian {...props} kind="bar" />;
642
+ }