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,281 @@
1
+ "use client";
2
+
3
+ import { Children, useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
4
+ import { cx } from "./cx";
5
+ import { IconButton } from "./button";
6
+
7
+ // Carousel — a row of slides the user moves through: testimonials, plan
8
+ // cards, screenshots of a template. The browser's own scrolling is the
9
+ // engine (CSS scroll-snap), so a swipe, a trackpad and a scrollbar-less
10
+ // flick all work with nothing to install; the buttons, dots and arrow
11
+ // keys only ask it to scroll. Each child is one slide.
12
+ //
13
+ // <Carousel label="Customer quotes" itemsPerView={{ sm: 2, lg: 3 }}>
14
+ // {quotes.map((q) => <QuoteCard key={q.id} {...q} />)}
15
+ // </Carousel>
16
+ //
17
+ // label what a screen reader calls the region (required)
18
+ // itemsPerView slides side by side: a number, or { sm, md, lg }. Always
19
+ // 1 on a phone; a number n is min(n, 2) from sm, n from md
20
+ // indicator dots (the default) · counter ("2 / 5") · none
21
+ // loop previous on the first goes to the last, and back (off)
22
+ // autoplay ms between slides (true = 5000). Off by default; paused
23
+ // on hover and focus, while hidden, and never runs for a
24
+ // reader who prefers reduced motion. Adds a pause button.
25
+ // defaultIndex the slide it opens on
26
+ // onChange (index) → the first visible slide, after it settles
27
+ //
28
+ // A carousel hides all but one thing, so it is for things of a kind
29
+ // where seeing one at a time is fine. Content the user must compare
30
+ // (plans, options) reads better as a grid.
31
+
32
+ const GAP = "calc(var(--spacing) * 4)";
33
+ // The per-breakpoint count arrives as CSS variables; these classes pick
34
+ // the one for the window's width. Written out whole: Tailwind reads
35
+ // class strings literally.
36
+ const PER = "[--per:1] sm:[--per:var(--per-sm)] md:[--per:var(--per-md)] lg:[--per:var(--per-lg)]";
37
+
38
+ function perView(n) {
39
+ if (typeof n === "number") return { sm: Math.min(n, 2), md: n, lg: n };
40
+ const sm = n?.sm ?? 1;
41
+ const md = n?.md ?? sm;
42
+ return { sm, md, lg: n?.lg ?? md };
43
+ }
44
+
45
+ export function Carousel({
46
+ label,
47
+ itemsPerView = 1,
48
+ indicator = "dots",
49
+ loop = false,
50
+ autoplay,
51
+ defaultIndex = 0,
52
+ onChange,
53
+ className,
54
+ children,
55
+ }) {
56
+ const id = useId();
57
+ const track = useRef(null);
58
+ const slides = Children.toArray(children).filter(Boolean);
59
+ const count = slides.length;
60
+ const per = perView(itemsPerView);
61
+ const [index, setIndex] = useState(defaultIndex);
62
+ const [shown, setShown] = useState(1);
63
+ const [held, setHeld] = useState(false);
64
+ const [stopped, setStopped] = useState(false);
65
+ const [calm, setCalm] = useState(false);
66
+ const [announce, setAnnounce] = useState(false);
67
+ const reported = useRef(defaultIndex);
68
+ const last = Math.max(0, count - shown);
69
+ const interval = autoplay === true ? 5000 : typeof autoplay === "number" ? autoplay : 0;
70
+ const playing = interval > 0 && !stopped && !held && !calm;
71
+
72
+ const go = useCallback(
73
+ (i, smooth = true) => {
74
+ const t = track.current;
75
+ const el = t?.children[i];
76
+ if (!t || !el) return;
77
+ const reduce = typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
78
+ t.scrollTo({ left: el.offsetLeft, behavior: smooth && !reduce ? "smooth" : "auto" });
79
+ },
80
+ [],
81
+ );
82
+
83
+ // Where the scroll rests → the index. Read from the scroll position,
84
+ // so a swipe, a trackpad and the buttons all land in the same place.
85
+ const read = useCallback(() => {
86
+ const t = track.current;
87
+ if (!t || !t.children.length) return;
88
+ const n = Number.parseFloat(getComputedStyle(t).getPropertyValue("--per")) || 1;
89
+ setShown(n);
90
+ const end = t.scrollWidth - t.clientWidth;
91
+ const lastPos = Math.max(0, t.children.length - Math.round(n));
92
+ let i = 0;
93
+ if (end > 0 && t.scrollLeft >= end - 2) i = lastPos;
94
+ else {
95
+ let best = Infinity;
96
+ [...t.children].forEach((c, k) => {
97
+ const d = Math.abs(c.offsetLeft - t.scrollLeft);
98
+ if (d < best) {
99
+ best = d;
100
+ i = k;
101
+ }
102
+ });
103
+ }
104
+ setIndex(Math.min(i, lastPos));
105
+ }, []);
106
+
107
+ useLayoutEffect(() => {
108
+ if (defaultIndex) go(defaultIndex, false);
109
+ read();
110
+ // eslint-disable-next-line react-hooks/exhaustive-deps
111
+ }, []);
112
+
113
+ useEffect(() => {
114
+ const t = track.current;
115
+ if (!t) return;
116
+ let frame = 0;
117
+ const onScroll = () => {
118
+ cancelAnimationFrame(frame);
119
+ frame = requestAnimationFrame(read);
120
+ };
121
+ t.addEventListener("scroll", onScroll, { passive: true });
122
+ const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(read);
123
+ ro?.observe(t);
124
+ return () => {
125
+ cancelAnimationFrame(frame);
126
+ t.removeEventListener("scroll", onScroll);
127
+ ro?.disconnect();
128
+ };
129
+ }, [read]);
130
+
131
+ // onChange once the index settles, not on every frame of a swipe.
132
+ useEffect(() => {
133
+ if (index === reported.current) return;
134
+ const h = setTimeout(() => {
135
+ reported.current = index;
136
+ onChange?.(index);
137
+ }, 120);
138
+ return () => clearTimeout(h);
139
+ }, [index, onChange]);
140
+
141
+ useEffect(() => {
142
+ if (!interval || typeof matchMedia !== "function") return;
143
+ const mq = matchMedia("(prefers-reduced-motion: reduce)");
144
+ const on = () => setCalm(mq.matches || document.visibilityState === "hidden");
145
+ on();
146
+ mq.addEventListener("change", on);
147
+ document.addEventListener("visibilitychange", on);
148
+ return () => {
149
+ mq.removeEventListener("change", on);
150
+ document.removeEventListener("visibilitychange", on);
151
+ };
152
+ }, [interval]);
153
+
154
+ useEffect(() => {
155
+ if (!playing || last === 0) return;
156
+ const h = setTimeout(() => go(index >= last ? 0 : index + 1), interval);
157
+ return () => clearTimeout(h);
158
+ }, [playing, index, last, interval, go]);
159
+
160
+ const prev = () => {
161
+ setAnnounce(true);
162
+ go(index > 0 ? index - 1 : loop ? last : 0);
163
+ };
164
+ const next = () => {
165
+ setAnnounce(true);
166
+ go(index < last ? index + 1 : loop ? 0 : last);
167
+ };
168
+
169
+ function onKeyDown(e) {
170
+ if (e.target.closest("input, textarea, select, [contenteditable]")) return;
171
+ if (e.key === "ArrowLeft") prev();
172
+ else if (e.key === "ArrowRight") next();
173
+ else if (e.key === "Home") go(0);
174
+ else if (e.key === "End") go(last);
175
+ else return;
176
+ e.preventDefault();
177
+ }
178
+
179
+ if (count === 0) return null;
180
+ const positions = last + 1;
181
+
182
+ return (
183
+ <section
184
+ aria-roledescription="carousel"
185
+ aria-label={label}
186
+ onKeyDown={onKeyDown}
187
+ onPointerEnter={() => setHeld(true)}
188
+ onPointerLeave={() => setHeld(false)}
189
+ onFocus={() => setHeld(true)}
190
+ onBlur={(e) => {
191
+ if (!e.currentTarget.contains(e.relatedTarget)) setHeld(false);
192
+ }}
193
+ className={cx("grid min-w-0 gap-3", className)}
194
+ >
195
+ <div
196
+ ref={track}
197
+ id={`${id}-track`}
198
+ tabIndex={0}
199
+ aria-live={announce && !playing ? "polite" : "off"}
200
+ className={cx(
201
+ "relative flex snap-x snap-mandatory overflow-x-auto overscroll-x-contain rounded-lg outline-none",
202
+ "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
203
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
204
+ PER,
205
+ )}
206
+ style={{ gap: GAP, "--per-sm": per.sm, "--per-md": per.md, "--per-lg": per.lg }}
207
+ >
208
+ {slides.map((slide, i) => (
209
+ <div
210
+ key={slide.key ?? i}
211
+ role="group"
212
+ aria-roledescription="slide"
213
+ aria-label={`${i + 1} of ${count}`}
214
+ className="min-w-0 shrink-0 snap-start"
215
+ style={{ flexBasis: `calc((100% - (var(--per) - 1) * ${GAP}) / var(--per))` }}
216
+ >
217
+ {slide}
218
+ </div>
219
+ ))}
220
+ </div>
221
+ {positions > 1 ? (
222
+ <div className="flex items-center justify-between gap-2">
223
+ <IconButton
224
+ icon="chevron-left"
225
+ label="Previous slide"
226
+ variant="secondary"
227
+ aria-controls={`${id}-track`}
228
+ disabled={!loop && index === 0}
229
+ onClick={prev}
230
+ />
231
+ <div className="flex min-w-0 flex-1 items-center justify-center gap-1">
232
+ {indicator === "counter" || (indicator === "dots" && positions > 12) ? (
233
+ <p data-nums className="text-sm text-muted-foreground">
234
+ {index + 1} / {positions}
235
+ </p>
236
+ ) : indicator === "dots" ? (
237
+ Array.from({ length: positions }, (_, i) => (
238
+ <button
239
+ key={i}
240
+ type="button"
241
+ aria-label={`Go to slide ${i + 1}`}
242
+ aria-current={i === index ? "true" : undefined}
243
+ aria-controls={`${id}-track`}
244
+ onClick={() => {
245
+ setAnnounce(true);
246
+ go(i);
247
+ }}
248
+ className="group grid size-6 place-items-center rounded-full outline-none focus-visible:ring-2 focus-visible:ring-ring"
249
+ >
250
+ <span
251
+ className={cx(
252
+ "block h-2 rounded-full transition-[width,background-color] duration-200 motion-reduce:transition-none",
253
+ i === index ? "w-5 bg-foreground" : "w-2 bg-muted-foreground/40 group-hover:bg-muted-foreground",
254
+ )}
255
+ />
256
+ </button>
257
+ ))
258
+ ) : null}
259
+ {interval > 0 && !calm ? (
260
+ <IconButton
261
+ icon={stopped ? "play" : "pause"}
262
+ label={stopped ? "Play slides" : "Pause slides"}
263
+ size="sm"
264
+ className="ml-1"
265
+ onClick={() => setStopped((s) => !s)}
266
+ />
267
+ ) : null}
268
+ </div>
269
+ <IconButton
270
+ icon="chevron-right"
271
+ label="Next slide"
272
+ variant="secondary"
273
+ aria-controls={`${id}-track`}
274
+ disabled={!loop && index >= last}
275
+ onClick={next}
276
+ />
277
+ </div>
278
+ ) : null}
279
+ </section>
280
+ );
281
+ }
@@ -0,0 +1,208 @@
1
+ "use client";
2
+
3
+ import { useRef, useState } from "react";
4
+ import { cx } from "./cx";
5
+ import { Icon } from "./icon";
6
+
7
+ // Collapsible — a row that shows or hides what is under it: advanced
8
+ // fields, a long note, last week's runs. A native <details>/<summary>
9
+ // underneath, so the browser supplies the keyboard, the expanded state a
10
+ // screen reader announces, and find-in-page opening a closed one. The
11
+ // click is taken over so `open` can be controlled; a toggle the browser
12
+ // makes on its own (find-in-page) is reported through `onOpenChange`.
13
+ // Height animates where the browser can (::details-content) and never
14
+ // when the viewer asks for reduced motion. Never a raw <details> in a
15
+ // surface: `npm run check` refuses it.
16
+ //
17
+ // title the trigger's text (the whole row is the target)
18
+ // meta a count or a date on the right, muted
19
+ // open controlled; with `onOpenChange(next)`. Leave it out and
20
+ // `defaultOpen` sets where it starts
21
+ // variant plain (a row in the flow) · outline (a bordered panel)
22
+ // · flush (edge to edge inside a Card or any bordered
23
+ // box: 16px side padding, a rule under each row, none
24
+ // under the last — a stack of them is a divided list).
25
+ // `accordion-outline` is flush's older name; it still works
26
+ // chevron down (default: points down, turns up when open) ·
27
+ // right (the disclosure triangle: points right, turns
28
+ // down when open — a tree, a list of rows that drill in)
29
+ // disabled the row stays readable but does not toggle
30
+ //
31
+ // Accordion below is a list of them: `type` single (one open at a time)
32
+ // or multiple; `collapsible` lets the open one close when single.
33
+
34
+ const MOTION =
35
+ "[interpolate-size:allow-keywords] [&::details-content]:h-0 [&::details-content]:overflow-clip " +
36
+ "[&[open]::details-content]:h-auto [&::details-content]:transition-[height,content-visibility] " +
37
+ "[&::details-content]:transition-discrete [&::details-content]:duration-200 [&::details-content]:ease-out " +
38
+ "motion-reduce:[&::details-content]:transition-none";
39
+
40
+ const LOOKS = {
41
+ plain: { box: "", row: "-mx-2 px-2 rounded-md", body: "pb-3 pt-1" },
42
+ outline: { box: "rounded-lg border border-border bg-card text-card-foreground", row: "px-4 rounded-lg", body: "px-4 pb-4" },
43
+ // An Accordion's items: the list draws the edges.
44
+ "accordion-plain": { box: "border-b border-border", row: "-mx-2 px-2 rounded-md", body: "pb-4 pt-1" },
45
+ "accordion-outline": { box: "border-b border-border last:border-b-0", row: "px-4", body: "px-4 pb-4" },
46
+ };
47
+ LOOKS.flush = LOOKS["accordion-outline"];
48
+
49
+ // Where the chevron points: closed, then open.
50
+ const CHEVRON = {
51
+ down: { name: "chevron-down", open: "rotate-180" },
52
+ right: { name: "chevron-right", open: "rotate-90" },
53
+ };
54
+
55
+ export function Collapsible({
56
+ title,
57
+ meta,
58
+ open,
59
+ defaultOpen = false,
60
+ onOpenChange,
61
+ variant = "plain",
62
+ chevron = "down",
63
+ disabled,
64
+ className,
65
+ children,
66
+ ...rest
67
+ }) {
68
+ const [inner, setInner] = useState(defaultOpen);
69
+ const controlled = open !== undefined;
70
+ const isOpen = controlled ? open : inner;
71
+ const look = LOOKS[variant] ?? LOOKS.plain;
72
+ const turn = CHEVRON[chevron] ?? CHEVRON.down;
73
+
74
+ function set(next) {
75
+ if (!controlled) setInner(next);
76
+ onOpenChange?.(next);
77
+ }
78
+
79
+ return (
80
+ <details
81
+ open={isOpen}
82
+ onToggle={(e) => {
83
+ if (e.currentTarget.open !== isOpen) set(e.currentTarget.open);
84
+ }}
85
+ className={cx(MOTION, look.box, className)}
86
+ {...rest}
87
+ >
88
+ <summary
89
+ aria-disabled={disabled ? true : undefined}
90
+ onClick={(e) => {
91
+ e.preventDefault();
92
+ if (!disabled) set(!isOpen);
93
+ }}
94
+ className={cx(
95
+ "flex min-h-11 list-none items-center gap-3 py-2 text-sm font-medium text-foreground outline-none [&::-webkit-details-marker]:hidden",
96
+ "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
97
+ disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-accent",
98
+ look.row,
99
+ )}
100
+ >
101
+ <span className="min-w-0 flex-1 text-left">{title}</span>
102
+ {meta !== undefined && meta !== null ? (
103
+ <span data-nums className="shrink-0 text-xs font-normal text-muted-foreground">
104
+ {meta}
105
+ </span>
106
+ ) : null}
107
+ <Icon
108
+ name={turn.name}
109
+ className={cx(
110
+ "shrink-0 text-muted-foreground transition-transform duration-200 motion-reduce:transition-none",
111
+ isOpen && turn.open,
112
+ )}
113
+ />
114
+ </summary>
115
+ <div className={cx("text-sm", look.body)}>{children}</div>
116
+ </details>
117
+ );
118
+ }
119
+
120
+ /**
121
+ * A list of Collapsibles. Arrow keys move between the rows, Home/End jump.
122
+ *
123
+ * items [{ key, title, meta?, content, disabled? }]
124
+ * type single (opening one closes the rest) · multiple
125
+ * collapsible single only: the open row can close (default true)
126
+ * value controlled: a key (or null) when single, an array of keys
127
+ * when multiple; with `onChange(next)`. `defaultValue` for
128
+ * where it starts when uncontrolled
129
+ * variant plain (rows divided by rules) · outline (one bordered box)
130
+ * chevron down · right, as Collapsible
131
+ */
132
+ export function Accordion({
133
+ items,
134
+ type = "single",
135
+ collapsible = true,
136
+ value,
137
+ defaultValue,
138
+ onChange,
139
+ variant = "plain",
140
+ chevron,
141
+ className,
142
+ "aria-label": ariaLabel,
143
+ }) {
144
+ const root = useRef(null);
145
+ const multiple = type === "multiple";
146
+ const [inner, setInner] = useState(defaultValue ?? (multiple ? [] : null));
147
+ const controlled = value !== undefined;
148
+ const current = controlled ? value : inner;
149
+ const live = (items ?? []).filter(Boolean);
150
+ if (live.length === 0) return null;
151
+
152
+ const isOpen = (key) => (multiple ? (current ?? []).includes(key) : current === key);
153
+
154
+ function toggle(key, next) {
155
+ let out;
156
+ if (multiple) {
157
+ const list = current ?? [];
158
+ out = next ? [...list.filter((k) => k !== key), key] : list.filter((k) => k !== key);
159
+ } else {
160
+ if (!next && !collapsible) return;
161
+ out = next ? key : null;
162
+ }
163
+ if (!controlled) setInner(out);
164
+ onChange?.(out);
165
+ }
166
+
167
+ function onKeyDown(e) {
168
+ const heads = [...(root.current?.querySelectorAll(":scope > details > summary:not([aria-disabled='true'])") ?? [])];
169
+ const i = heads.indexOf(e.target);
170
+ if (i < 0) return;
171
+ let next = null;
172
+ if (e.key === "ArrowDown") next = (i + 1) % heads.length;
173
+ else if (e.key === "ArrowUp") next = (i - 1 + heads.length) % heads.length;
174
+ else if (e.key === "Home") next = 0;
175
+ else if (e.key === "End") next = heads.length - 1;
176
+ if (next === null) return;
177
+ e.preventDefault();
178
+ heads[next]?.focus();
179
+ }
180
+
181
+ return (
182
+ <div
183
+ ref={root}
184
+ role="group"
185
+ aria-label={ariaLabel}
186
+ onKeyDown={onKeyDown}
187
+ className={cx(
188
+ variant === "outline" ? "overflow-hidden rounded-lg border border-border bg-card text-card-foreground" : "",
189
+ className,
190
+ )}
191
+ >
192
+ {live.map((item) => (
193
+ <Collapsible
194
+ key={item.key}
195
+ title={item.title}
196
+ meta={item.meta}
197
+ disabled={item.disabled}
198
+ open={isOpen(item.key)}
199
+ onOpenChange={(next) => toggle(item.key, next)}
200
+ variant={variant === "outline" ? "flush" : "accordion-plain"}
201
+ chevron={chevron}
202
+ >
203
+ {item.content}
204
+ </Collapsible>
205
+ ))}
206
+ </div>
207
+ );
208
+ }