makersclaw 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (475) hide show
  1. package/THIRD-PARTY-NOTICES.md +180 -0
  2. package/package.json +3 -2
  3. package/r/annotate.json +62 -0
  4. package/r/approval-request.json +52 -0
  5. package/r/audio-player.json +74 -0
  6. package/r/auth-form.json +55 -0
  7. package/r/board.json +10 -6
  8. package/r/calendar-view.json +105 -0
  9. package/r/cart.json +62 -0
  10. package/r/chart.json +83 -0
  11. package/r/chat.json +95 -0
  12. package/r/code-editor.json +94 -0
  13. package/r/comment-box.json +64 -0
  14. package/r/contact-section.json +53 -0
  15. package/r/core.json +205 -8
  16. package/r/csv-import.json +63 -0
  17. package/r/data-table.json +69 -0
  18. package/r/diagram.json +74 -0
  19. package/r/doc-editor.json +82 -0
  20. package/r/doc-page.json +61 -0
  21. package/r/email-render.json +73 -0
  22. package/r/faq.json +50 -0
  23. package/r/file-upload.json +54 -0
  24. package/r/flow-canvas.json +93 -0
  25. package/r/footer.json +52 -0
  26. package/r/gantt.json +70 -0
  27. package/r/job-panel.json +12 -7
  28. package/r/json-editor.json +66 -0
  29. package/r/map.json +89 -0
  30. package/r/menubar.json +52 -0
  31. package/r/mind-map.json +67 -0
  32. package/r/navigation-menu.json +52 -0
  33. package/r/order-detail.json +54 -0
  34. package/r/org-chart.json +66 -0
  35. package/r/page-builder.json +105 -0
  36. package/r/payment-methods.json +51 -0
  37. package/r/pdf-document.json +79 -0
  38. package/r/pdf-viewer.json +88 -0
  39. package/r/product-detail.json +76 -0
  40. package/r/product-grid.json +65 -0
  41. package/r/record-form.json +67 -0
  42. package/r/record-notes.json +55 -0
  43. package/r/registry.json +3411 -29
  44. package/r/search-dialog.json +51 -0
  45. package/r/settings-list.json +66 -0
  46. package/r/setup-checklist.json +51 -0
  47. package/r/share-dialog.json +52 -0
  48. package/r/sidebar.json +69 -0
  49. package/r/signature-pad.json +72 -0
  50. package/r/sketch-canvas.json +99 -0
  51. package/r/spreadsheet.json +90 -0
  52. package/r/stat-cards.json +66 -0
  53. package/r/task-list.json +63 -0
  54. package/r/task-model.json +98 -0
  55. package/r/testimonials.json +52 -0
  56. package/r/transaction-list.json +53 -0
  57. package/r/whiteboard.json +66 -0
  58. package/registry/blocks/annotate/README.md +179 -0
  59. package/registry/blocks/annotate/annotate-data.js +250 -0
  60. package/registry/blocks/annotate/annotate.jsx +646 -0
  61. package/registry/blocks/annotate/block.json +10 -0
  62. package/registry/blocks/annotate/demo.jsx +135 -0
  63. package/registry/blocks/annotate/index.js +15 -0
  64. package/registry/blocks/approval-request/README.md +116 -0
  65. package/registry/blocks/approval-request/approval-request.jsx +386 -0
  66. package/registry/blocks/approval-request/block.json +10 -0
  67. package/registry/blocks/approval-request/demo.jsx +127 -0
  68. package/registry/blocks/approval-request/index.js +4 -0
  69. package/registry/blocks/audio-player/README.md +167 -0
  70. package/registry/blocks/audio-player/audio-player.jsx +623 -0
  71. package/registry/blocks/audio-player/block.json +14 -0
  72. package/registry/blocks/audio-player/colors.js +109 -0
  73. package/registry/blocks/audio-player/demo.jsx +209 -0
  74. package/registry/blocks/audio-player/index.js +6 -0
  75. package/registry/blocks/audio-player/time.js +67 -0
  76. package/registry/blocks/audio-player/wavesurfer.js +9 -0
  77. package/registry/blocks/auth-form/README.md +126 -0
  78. package/registry/blocks/auth-form/auth-form.jsx +568 -0
  79. package/registry/blocks/auth-form/block.json +10 -0
  80. package/registry/blocks/auth-form/demo.jsx +131 -0
  81. package/registry/blocks/auth-form/index.js +3 -0
  82. package/registry/blocks/board/README.md +55 -5
  83. package/registry/blocks/board/block.json +2 -2
  84. package/registry/blocks/board/board.jsx +230 -86
  85. package/registry/blocks/board/demo.jsx +103 -24
  86. package/registry/blocks/calendar-view/README.md +180 -0
  87. package/registry/blocks/calendar-view/agenda.jsx +147 -0
  88. package/registry/blocks/calendar-view/block.json +76 -0
  89. package/registry/blocks/calendar-view/calendar-model.js +442 -0
  90. package/registry/blocks/calendar-view/calendar.jsx +627 -0
  91. package/registry/blocks/calendar-view/demo.jsx +195 -0
  92. package/registry/blocks/calendar-view/draft.jsx +49 -0
  93. package/registry/blocks/calendar-view/index.js +39 -0
  94. package/registry/blocks/calendar-view/month.jsx +346 -0
  95. package/registry/blocks/calendar-view/paint.js +69 -0
  96. package/registry/blocks/calendar-view/time-grid.jsx +527 -0
  97. package/registry/blocks/calendar-view/tray.jsx +87 -0
  98. package/registry/blocks/cart/README.md +146 -0
  99. package/registry/blocks/cart/block.json +10 -0
  100. package/registry/blocks/cart/cart.jsx +597 -0
  101. package/registry/blocks/cart/demo.jsx +98 -0
  102. package/registry/blocks/cart/index.js +4 -0
  103. package/registry/blocks/cart/money.js +28 -0
  104. package/registry/blocks/chart/README.md +316 -0
  105. package/registry/blocks/chart/block.json +10 -0
  106. package/registry/blocks/chart/cartesian.jsx +642 -0
  107. package/registry/blocks/chart/core.jsx +262 -0
  108. package/registry/blocks/chart/demo.jsx +357 -0
  109. package/registry/blocks/chart/heatmap.jsx +336 -0
  110. package/registry/blocks/chart/index.js +8 -0
  111. package/registry/blocks/chart/pie.jsx +245 -0
  112. package/registry/blocks/chart/sparkline.jsx +88 -0
  113. package/registry/blocks/chat/README.md +273 -0
  114. package/registry/blocks/chat/attachment.jsx +95 -0
  115. package/registry/blocks/chat/block.json +10 -0
  116. package/registry/blocks/chat/chat.jsx +132 -0
  117. package/registry/blocks/chat/composer.jsx +364 -0
  118. package/registry/blocks/chat/demo.jsx +578 -0
  119. package/registry/blocks/chat/header.jsx +34 -0
  120. package/registry/blocks/chat/index.js +9 -0
  121. package/registry/blocks/chat/message.jsx +450 -0
  122. package/registry/blocks/chat/scroller.jsx +247 -0
  123. package/registry/blocks/chat/text.jsx +104 -0
  124. package/registry/blocks/code-editor/README.md +210 -0
  125. package/registry/blocks/code-editor/block.json +22 -0
  126. package/registry/blocks/code-editor/code-editor.jsx +534 -0
  127. package/registry/blocks/code-editor/codemirror.js +38 -0
  128. package/registry/blocks/code-editor/demo.jsx +205 -0
  129. package/registry/blocks/code-editor/index.js +8 -0
  130. package/registry/blocks/code-editor/json.js +317 -0
  131. package/registry/blocks/code-editor/sql.js +136 -0
  132. package/registry/blocks/code-editor/text.js +101 -0
  133. package/registry/blocks/code-editor/theme.js +186 -0
  134. package/registry/blocks/comment-box/README.md +123 -0
  135. package/registry/blocks/comment-box/block.json +10 -0
  136. package/registry/blocks/comment-box/comment-body.jsx +217 -0
  137. package/registry/blocks/comment-box/comment-box.jsx +198 -0
  138. package/registry/blocks/comment-box/comment-time.jsx +77 -0
  139. package/registry/blocks/comment-box/demo.jsx +141 -0
  140. package/registry/blocks/comment-box/index.js +8 -0
  141. package/registry/blocks/contact-section/README.md +152 -0
  142. package/registry/blocks/contact-section/block.json +11 -0
  143. package/registry/blocks/contact-section/contact-section.jsx +509 -0
  144. package/registry/blocks/contact-section/demo.jsx +93 -0
  145. package/registry/blocks/contact-section/index.js +4 -0
  146. package/registry/blocks/csv-import/README.md +133 -0
  147. package/registry/blocks/csv-import/block.json +13 -0
  148. package/registry/blocks/csv-import/csv-import.jsx +479 -0
  149. package/registry/blocks/csv-import/demo.jsx +106 -0
  150. package/registry/blocks/csv-import/import.js +200 -0
  151. package/registry/blocks/csv-import/index.js +7 -0
  152. package/registry/blocks/data-table/README.md +386 -0
  153. package/registry/blocks/data-table/block.json +10 -0
  154. package/registry/blocks/data-table/data-table.jsx +1164 -0
  155. package/registry/blocks/data-table/demo.jsx +588 -0
  156. package/registry/blocks/data-table/index.js +5 -0
  157. package/registry/blocks/data-table/model.js +169 -0
  158. package/registry/blocks/diagram/README.md +108 -0
  159. package/registry/blocks/diagram/block.json +13 -0
  160. package/registry/blocks/diagram/demo.jsx +113 -0
  161. package/registry/blocks/diagram/diagram.jsx +481 -0
  162. package/registry/blocks/diagram/index.js +7 -0
  163. package/registry/blocks/diagram/mermaid.js +52 -0
  164. package/registry/blocks/diagram/palette.js +313 -0
  165. package/registry/blocks/diagram/source.js +98 -0
  166. package/registry/blocks/doc-editor/README.md +215 -0
  167. package/registry/blocks/doc-editor/block.json +15 -0
  168. package/registry/blocks/doc-editor/demo.jsx +225 -0
  169. package/registry/blocks/doc-editor/doc-editor.jsx +291 -0
  170. package/registry/blocks/doc-editor/doc.js +309 -0
  171. package/registry/blocks/doc-editor/index.js +7 -0
  172. package/registry/blocks/doc-editor/schema.jsx +56 -0
  173. package/registry/blocks/doc-editor/shadcn-classes.js +110 -0
  174. package/registry/blocks/doc-editor/theme.js +82 -0
  175. package/registry/blocks/doc-page/README.md +119 -0
  176. package/registry/blocks/doc-page/autosave.js +104 -0
  177. package/registry/blocks/doc-page/block.json +10 -0
  178. package/registry/blocks/doc-page/demo.jsx +137 -0
  179. package/registry/blocks/doc-page/doc-page.jsx +276 -0
  180. package/registry/blocks/doc-page/index.js +4 -0
  181. package/registry/blocks/email-render/README.md +151 -0
  182. package/registry/blocks/email-render/block.json +14 -0
  183. package/registry/blocks/email-render/demo.jsx +153 -0
  184. package/registry/blocks/email-render/doc-email.jsx +210 -0
  185. package/registry/blocks/email-render/email.jsx +221 -0
  186. package/registry/blocks/email-render/index.js +10 -0
  187. package/registry/blocks/email-render/render.js +50 -0
  188. package/registry/blocks/email-render/theme.js +215 -0
  189. package/registry/blocks/faq/README.md +101 -0
  190. package/registry/blocks/faq/block.json +11 -0
  191. package/registry/blocks/faq/demo.jsx +89 -0
  192. package/registry/blocks/faq/faq.jsx +220 -0
  193. package/registry/blocks/faq/index.js +4 -0
  194. package/registry/blocks/file-upload/README.md +138 -0
  195. package/registry/blocks/file-upload/block.json +10 -0
  196. package/registry/blocks/file-upload/demo.jsx +204 -0
  197. package/registry/blocks/file-upload/file-upload.jsx +635 -0
  198. package/registry/blocks/file-upload/index.js +4 -0
  199. package/registry/blocks/flow-canvas/README.md +420 -0
  200. package/registry/blocks/flow-canvas/block.json +13 -0
  201. package/registry/blocks/flow-canvas/board.js +819 -0
  202. package/registry/blocks/flow-canvas/chrome.jsx +649 -0
  203. package/registry/blocks/flow-canvas/context.jsx +35 -0
  204. package/registry/blocks/flow-canvas/demo.jsx +249 -0
  205. package/registry/blocks/flow-canvas/edges.jsx +107 -0
  206. package/registry/blocks/flow-canvas/flow-canvas.jsx +1329 -0
  207. package/registry/blocks/flow-canvas/index.js +41 -0
  208. package/registry/blocks/flow-canvas/nodes.jsx +392 -0
  209. package/registry/blocks/flow-canvas/theme.js +174 -0
  210. package/registry/blocks/footer/README.md +133 -0
  211. package/registry/blocks/footer/block.json +11 -0
  212. package/registry/blocks/footer/demo.jsx +119 -0
  213. package/registry/blocks/footer/footer.jsx +406 -0
  214. package/registry/blocks/footer/index.js +4 -0
  215. package/registry/blocks/gantt/README.md +220 -0
  216. package/registry/blocks/gantt/block.json +10 -0
  217. package/registry/blocks/gantt/demo.jsx +148 -0
  218. package/registry/blocks/gantt/gantt.jsx +923 -0
  219. package/registry/blocks/gantt/index.js +7 -0
  220. package/registry/blocks/gantt/rows.jsx +468 -0
  221. package/registry/blocks/gantt/schedule.js +278 -0
  222. package/registry/blocks/job-panel/README.md +80 -0
  223. package/registry/blocks/job-panel/block.json +3 -3
  224. package/registry/blocks/job-panel/demo.jsx +230 -3
  225. package/registry/blocks/job-panel/job-panel.jsx +169 -3
  226. package/registry/blocks/json-editor/README.md +133 -0
  227. package/registry/blocks/json-editor/block.json +10 -0
  228. package/registry/blocks/json-editor/demo.jsx +92 -0
  229. package/registry/blocks/json-editor/index.js +7 -0
  230. package/registry/blocks/json-editor/json-editor.jsx +305 -0
  231. package/registry/blocks/json-editor/json-tree.jsx +393 -0
  232. package/registry/blocks/json-editor/tree.js +225 -0
  233. package/registry/blocks/map/README.md +221 -0
  234. package/registry/blocks/map/block.json +14 -0
  235. package/registry/blocks/map/demo.jsx +201 -0
  236. package/registry/blocks/map/geo.js +198 -0
  237. package/registry/blocks/map/index.js +8 -0
  238. package/registry/blocks/map/list.jsx +128 -0
  239. package/registry/blocks/map/map-view.jsx +715 -0
  240. package/registry/blocks/map/maplibre.js +30 -0
  241. package/registry/blocks/map/marks.jsx +146 -0
  242. package/registry/blocks/map/theme.js +142 -0
  243. package/registry/blocks/menubar/README.md +109 -0
  244. package/registry/blocks/menubar/block.json +10 -0
  245. package/registry/blocks/menubar/demo.jsx +128 -0
  246. package/registry/blocks/menubar/index.js +4 -0
  247. package/registry/blocks/menubar/menubar.jsx +199 -0
  248. package/registry/blocks/mind-map/README.md +206 -0
  249. package/registry/blocks/mind-map/block.json +10 -0
  250. package/registry/blocks/mind-map/demo.jsx +103 -0
  251. package/registry/blocks/mind-map/index.js +31 -0
  252. package/registry/blocks/mind-map/mind-map.jsx +1125 -0
  253. package/registry/blocks/mind-map/topic.jsx +143 -0
  254. package/registry/blocks/mind-map/tree.js +645 -0
  255. package/registry/blocks/navigation-menu/README.md +124 -0
  256. package/registry/blocks/navigation-menu/block.json +10 -0
  257. package/registry/blocks/navigation-menu/demo.jsx +84 -0
  258. package/registry/blocks/navigation-menu/index.js +4 -0
  259. package/registry/blocks/navigation-menu/navigation-menu.jsx +448 -0
  260. package/registry/blocks/order-detail/README.md +109 -0
  261. package/registry/blocks/order-detail/block.json +10 -0
  262. package/registry/blocks/order-detail/demo.jsx +88 -0
  263. package/registry/blocks/order-detail/index.js +4 -0
  264. package/registry/blocks/order-detail/order-detail.jsx +354 -0
  265. package/registry/blocks/org-chart/README.md +145 -0
  266. package/registry/blocks/org-chart/block.json +10 -0
  267. package/registry/blocks/org-chart/demo.jsx +94 -0
  268. package/registry/blocks/org-chart/index.js +7 -0
  269. package/registry/blocks/org-chart/org-chart.jsx +631 -0
  270. package/registry/blocks/org-chart/org.js +245 -0
  271. package/registry/blocks/org-chart/person.jsx +96 -0
  272. package/registry/blocks/page-builder/README.md +257 -0
  273. package/registry/blocks/page-builder/block.json +14 -0
  274. package/registry/blocks/page-builder/demo.jsx +145 -0
  275. package/registry/blocks/page-builder/grapes.js +18 -0
  276. package/registry/blocks/page-builder/index.js +11 -0
  277. package/registry/blocks/page-builder/page-builder.jsx +704 -0
  278. package/registry/blocks/page-builder/page-view.jsx +33 -0
  279. package/registry/blocks/page-builder/page.js +118 -0
  280. package/registry/blocks/page-builder/panels.jsx +588 -0
  281. package/registry/blocks/page-builder/sections.js +209 -0
  282. package/registry/blocks/page-builder/theme.js +87 -0
  283. package/registry/blocks/page-builder/thumbs.jsx +189 -0
  284. package/registry/blocks/page-builder/tokens.js +329 -0
  285. package/registry/blocks/payment-methods/README.md +104 -0
  286. package/registry/blocks/payment-methods/block.json +10 -0
  287. package/registry/blocks/payment-methods/demo.jsx +71 -0
  288. package/registry/blocks/payment-methods/index.js +4 -0
  289. package/registry/blocks/payment-methods/payment-methods.jsx +302 -0
  290. package/registry/blocks/pdf-document/README.md +213 -0
  291. package/registry/blocks/pdf-document/block.json +13 -0
  292. package/registry/blocks/pdf-document/demo.jsx +136 -0
  293. package/registry/blocks/pdf-document/index.js +33 -0
  294. package/registry/blocks/pdf-document/money.js +83 -0
  295. package/registry/blocks/pdf-document/pdf-document.jsx +144 -0
  296. package/registry/blocks/pdf-document/primitives.jsx +271 -0
  297. package/registry/blocks/pdf-document/quote.jsx +179 -0
  298. package/registry/blocks/pdf-document/theme.js +193 -0
  299. package/registry/blocks/pdf-viewer/README.md +191 -0
  300. package/registry/blocks/pdf-viewer/block.json +14 -0
  301. package/registry/blocks/pdf-viewer/demo.jsx +252 -0
  302. package/registry/blocks/pdf-viewer/helpers.js +270 -0
  303. package/registry/blocks/pdf-viewer/index.js +8 -0
  304. package/registry/blocks/pdf-viewer/notes.jsx +195 -0
  305. package/registry/blocks/pdf-viewer/pdf-viewer.jsx +1368 -0
  306. package/registry/blocks/pdf-viewer/pdfjs.js +37 -0
  307. package/registry/blocks/pdf-viewer/ssr-shim-end.js +6 -0
  308. package/registry/blocks/pdf-viewer/ssr-shim.js +44 -0
  309. package/registry/blocks/product-detail/README.md +217 -0
  310. package/registry/blocks/product-detail/block.json +10 -0
  311. package/registry/blocks/product-detail/demo.jsx +233 -0
  312. package/registry/blocks/product-detail/index.js +7 -0
  313. package/registry/blocks/product-detail/price.jsx +115 -0
  314. package/registry/blocks/product-detail/product-detail.jsx +348 -0
  315. package/registry/blocks/product-detail/product-media.jsx +102 -0
  316. package/registry/blocks/product-detail/product-options.jsx +144 -0
  317. package/registry/blocks/product-grid/README.md +162 -0
  318. package/registry/blocks/product-grid/block.json +10 -0
  319. package/registry/blocks/product-grid/demo.jsx +255 -0
  320. package/registry/blocks/product-grid/index.js +5 -0
  321. package/registry/blocks/product-grid/product-card.jsx +232 -0
  322. package/registry/blocks/product-grid/product-grid.jsx +235 -0
  323. package/registry/blocks/record-form/README.md +196 -0
  324. package/registry/blocks/record-form/block.json +10 -0
  325. package/registry/blocks/record-form/demo.jsx +525 -0
  326. package/registry/blocks/record-form/index.js +4 -0
  327. package/registry/blocks/record-form/record-fields.jsx +457 -0
  328. package/registry/blocks/record-form/record-form.jsx +415 -0
  329. package/registry/blocks/record-form/rules.js +81 -0
  330. package/registry/blocks/record-notes/README.md +139 -0
  331. package/registry/blocks/record-notes/block.json +10 -0
  332. package/registry/blocks/record-notes/demo.jsx +179 -0
  333. package/registry/blocks/record-notes/index.js +4 -0
  334. package/registry/blocks/record-notes/record-notes.jsx +266 -0
  335. package/registry/blocks/search-dialog/README.md +108 -0
  336. package/registry/blocks/search-dialog/block.json +10 -0
  337. package/registry/blocks/search-dialog/demo.jsx +116 -0
  338. package/registry/blocks/search-dialog/index.js +3 -0
  339. package/registry/blocks/search-dialog/search-dialog.jsx +235 -0
  340. package/registry/blocks/settings-list/README.md +171 -0
  341. package/registry/blocks/settings-list/block.json +10 -0
  342. package/registry/blocks/settings-list/demo.jsx +333 -0
  343. package/registry/blocks/settings-list/index.js +4 -0
  344. package/registry/blocks/settings-list/row-state.jsx +93 -0
  345. package/registry/blocks/settings-list/settings-list.jsx +349 -0
  346. package/registry/blocks/settings-list/settings-matrix.jsx +118 -0
  347. package/registry/blocks/setup-checklist/README.md +142 -0
  348. package/registry/blocks/setup-checklist/block.json +10 -0
  349. package/registry/blocks/setup-checklist/demo.jsx +159 -0
  350. package/registry/blocks/setup-checklist/index.js +4 -0
  351. package/registry/blocks/setup-checklist/setup-checklist.jsx +446 -0
  352. package/registry/blocks/share-dialog/README.md +113 -0
  353. package/registry/blocks/share-dialog/block.json +10 -0
  354. package/registry/blocks/share-dialog/demo.jsx +140 -0
  355. package/registry/blocks/share-dialog/index.js +3 -0
  356. package/registry/blocks/share-dialog/share-dialog.jsx +384 -0
  357. package/registry/blocks/sidebar/README.md +190 -0
  358. package/registry/blocks/sidebar/block.json +43 -0
  359. package/registry/blocks/sidebar/demo.jsx +577 -0
  360. package/registry/blocks/sidebar/index.js +4 -0
  361. package/registry/blocks/sidebar/sidebar-panel.jsx +149 -0
  362. package/registry/blocks/sidebar/sidebar.jsx +864 -0
  363. package/registry/blocks/signature-pad/README.md +137 -0
  364. package/registry/blocks/signature-pad/block.json +13 -0
  365. package/registry/blocks/signature-pad/colors.js +115 -0
  366. package/registry/blocks/signature-pad/demo.jsx +94 -0
  367. package/registry/blocks/signature-pad/index.js +6 -0
  368. package/registry/blocks/signature-pad/pad.js +7 -0
  369. package/registry/blocks/signature-pad/signature-pad.jsx +434 -0
  370. package/registry/blocks/signature-pad/signature.js +68 -0
  371. package/registry/blocks/sketch-canvas/README.md +280 -0
  372. package/registry/blocks/sketch-canvas/block.json +13 -0
  373. package/registry/blocks/sketch-canvas/demo.jsx +159 -0
  374. package/registry/blocks/sketch-canvas/excalidraw.js +40 -0
  375. package/registry/blocks/sketch-canvas/index.js +9 -0
  376. package/registry/blocks/sketch-canvas/palette.js +226 -0
  377. package/registry/blocks/sketch-canvas/sketch-canvas.jsx +1188 -0
  378. package/registry/blocks/sketch-canvas/sketch.js +179 -0
  379. package/registry/blocks/sketch-canvas/ssr-shim-end.js +6 -0
  380. package/registry/blocks/sketch-canvas/ssr-shim.js +45 -0
  381. package/registry/blocks/sketch-canvas/stamps.js +104 -0
  382. package/registry/blocks/sketch-canvas/theme.js +131 -0
  383. package/registry/blocks/spreadsheet/README.md +307 -0
  384. package/registry/blocks/spreadsheet/block.json +13 -0
  385. package/registry/blocks/spreadsheet/cells.jsx +455 -0
  386. package/registry/blocks/spreadsheet/chrome.jsx +325 -0
  387. package/registry/blocks/spreadsheet/demo.jsx +177 -0
  388. package/registry/blocks/spreadsheet/grid.js +387 -0
  389. package/registry/blocks/spreadsheet/index.js +34 -0
  390. package/registry/blocks/spreadsheet/spreadsheet.jsx +1732 -0
  391. package/registry/blocks/spreadsheet/types.js +473 -0
  392. package/registry/blocks/stat-cards/README.md +173 -0
  393. package/registry/blocks/stat-cards/block.json +10 -0
  394. package/registry/blocks/stat-cards/demo.jsx +257 -0
  395. package/registry/blocks/stat-cards/index.js +4 -0
  396. package/registry/blocks/stat-cards/stat-cards.jsx +307 -0
  397. package/registry/blocks/stat-cards/usage.jsx +243 -0
  398. package/registry/blocks/task-list/README.md +176 -0
  399. package/registry/blocks/task-list/block.json +10 -0
  400. package/registry/blocks/task-list/demo.jsx +134 -0
  401. package/registry/blocks/task-list/index.js +5 -0
  402. package/registry/blocks/task-list/task-list.jsx +907 -0
  403. package/registry/blocks/task-model/README.md +455 -0
  404. package/registry/blocks/task-model/block.json +167 -0
  405. package/registry/blocks/task-model/changes.js +89 -0
  406. package/registry/blocks/task-model/dates.js +371 -0
  407. package/registry/blocks/task-model/demo.jsx +215 -0
  408. package/registry/blocks/task-model/dnd.jsx +240 -0
  409. package/registry/blocks/task-model/index.js +97 -0
  410. package/registry/blocks/task-model/model.js +919 -0
  411. package/registry/blocks/task-model/parts.jsx +449 -0
  412. package/registry/blocks/task-model/toolbar.jsx +271 -0
  413. package/registry/blocks/testimonials/README.md +139 -0
  414. package/registry/blocks/testimonials/block.json +11 -0
  415. package/registry/blocks/testimonials/demo.jsx +137 -0
  416. package/registry/blocks/testimonials/index.js +4 -0
  417. package/registry/blocks/testimonials/testimonials.jsx +430 -0
  418. package/registry/blocks/transaction-list/README.md +126 -0
  419. package/registry/blocks/transaction-list/block.json +10 -0
  420. package/registry/blocks/transaction-list/demo.jsx +79 -0
  421. package/registry/blocks/transaction-list/index.js +4 -0
  422. package/registry/blocks/transaction-list/transaction-list.jsx +383 -0
  423. package/registry/blocks/whiteboard/README.md +179 -0
  424. package/registry/blocks/whiteboard/block.json +10 -0
  425. package/registry/blocks/whiteboard/demo.jsx +169 -0
  426. package/registry/blocks/whiteboard/index.js +6 -0
  427. package/registry/blocks/whiteboard/templates.js +150 -0
  428. package/registry/blocks/whiteboard/whiteboard.jsx +721 -0
  429. package/src/cli.mjs +19 -6
  430. package/src/install.mjs +18 -0
  431. package/src/registry.mjs +38 -4
  432. package/src/shadcn.mjs +14 -1
  433. package/templates/next/files/README.md +145 -11
  434. package/templates/next/files/app/globals.css +55 -4
  435. package/templates/next/files/check/run.mjs +3 -3
  436. package/templates/next/files/components/ui/avatar.jsx +141 -0
  437. package/templates/next/files/components/ui/breadcrumb.jsx +149 -0
  438. package/templates/next/files/components/ui/button-group.jsx +70 -0
  439. package/templates/next/files/components/ui/button.jsx +132 -12
  440. package/templates/next/files/components/ui/calendar.jsx +609 -0
  441. package/templates/next/files/components/ui/carousel.jsx +281 -0
  442. package/templates/next/files/components/ui/collapsible.jsx +208 -0
  443. package/templates/next/files/components/ui/combobox.jsx +608 -0
  444. package/templates/next/files/components/ui/command.jsx +577 -0
  445. package/templates/next/files/components/ui/context-menu.jsx +191 -0
  446. package/templates/next/files/components/ui/date-picker.jsx +360 -0
  447. package/templates/next/files/components/ui/distribution.jsx +117 -0
  448. package/templates/next/files/components/ui/feedback.jsx +143 -0
  449. package/templates/next/files/components/ui/field.jsx +115 -3
  450. package/templates/next/files/components/ui/file-input.jsx +234 -0
  451. package/templates/next/files/components/ui/icon.jsx +130 -8
  452. package/templates/next/files/components/ui/image.jsx +143 -0
  453. package/templates/next/files/components/ui/index.js +47 -2
  454. package/templates/next/files/components/ui/input-group.jsx +213 -0
  455. package/templates/next/files/components/ui/input-otp.jsx +170 -0
  456. package/templates/next/files/components/ui/item.jsx +206 -0
  457. package/templates/next/files/components/ui/menu.jsx +454 -82
  458. package/templates/next/files/components/ui/notice.jsx +126 -14
  459. package/templates/next/files/components/ui/pagination.jsx +156 -0
  460. package/templates/next/files/components/ui/popover.jsx +284 -0
  461. package/templates/next/files/components/ui/radio.jsx +193 -0
  462. package/templates/next/files/components/ui/rating.jsx +131 -0
  463. package/templates/next/files/components/ui/resizable.jsx +338 -0
  464. package/templates/next/files/components/ui/scroll-area.jsx +123 -0
  465. package/templates/next/files/components/ui/separator.jsx +119 -0
  466. package/templates/next/files/components/ui/sheet.jsx +96 -11
  467. package/templates/next/files/components/ui/slider.jsx +174 -0
  468. package/templates/next/files/components/ui/stat.jsx +574 -0
  469. package/templates/next/files/components/ui/steps.jsx +338 -0
  470. package/templates/next/files/components/ui/swatch.jsx +33 -0
  471. package/templates/next/files/components/ui/table.jsx +130 -0
  472. package/templates/next/files/components/ui/toast.jsx +440 -0
  473. package/templates/next/files/components/ui/toggle.jsx +195 -0
  474. package/templates/next/files/components/ui/tooltip.jsx +270 -0
  475. package/templates/next/template.json +264 -8
@@ -0,0 +1,143 @@
1
+ import { cx } from "./cx";
2
+
3
+ // Waiting signals: a spinner, a skeleton, a progress bar. Server-safe (no
4
+ // hooks). Each says to a screen reader what the eye sees — a spinner is
5
+ // a status, a skeleton is nothing (the real content announces itself), a
6
+ // bar is a progressbar with a name. Motion respects the reader's
7
+ // prefers-reduced-motion: the spinner slows, the skeleton and the
8
+ // indeterminate bar stop moving.
9
+
10
+ const SPINNER_SIZES = { sm: 16, md: 24, lg: 36 };
11
+
12
+ /**
13
+ * A turning arc in the text colour around it (currentColor), so it takes
14
+ * the tone of whatever holds it.
15
+ *
16
+ * size sm (16px, inline with text and in a Button) · md (24) · lg (36)
17
+ * label what a screen reader hears, default "Loading"; null when the
18
+ * container already says it (a Button with `loading`, aria-busy)
19
+ */
20
+ export function Spinner({ size = "md", label = "Loading", className }) {
21
+ const px = SPINNER_SIZES[size] ?? SPINNER_SIZES.md;
22
+ return (
23
+ <svg
24
+ width={px}
25
+ height={px}
26
+ viewBox="0 0 24 24"
27
+ fill="none"
28
+ stroke="currentColor"
29
+ strokeWidth="2.5"
30
+ strokeLinecap="round"
31
+ role={label ? "status" : undefined}
32
+ aria-label={label || undefined}
33
+ aria-hidden={label ? undefined : true}
34
+ className={cx("shrink-0 animate-spin motion-reduce:[animation-duration:2.4s]", className)}
35
+ >
36
+ <circle cx="12" cy="12" r="9" className="opacity-20" />
37
+ <path d="M21 12a9 9 0 0 0-9-9" />
38
+ </svg>
39
+ );
40
+ }
41
+
42
+ const SKELETON_SHAPES = {
43
+ line: "h-[1em] rounded-sm",
44
+ circle: "aspect-square rounded-full",
45
+ rect: "rounded-lg",
46
+ };
47
+
48
+ /**
49
+ * Where content will be, drawn before it arrives — the size of the real
50
+ * thing, so nothing jumps when it lands. Hidden from screen readers; put
51
+ * aria-busy on the region it stands in for.
52
+ *
53
+ * shape line (text height; give a width: w-2/3) · circle (give
54
+ * one side: size-10) · rect (give both: h-32 w-full)
55
+ * className the size, and nothing else
56
+ */
57
+ export function Skeleton({ shape = "line", className }) {
58
+ return (
59
+ <span
60
+ aria-hidden="true"
61
+ className={cx(
62
+ "block animate-pulse bg-accent motion-reduce:animate-none",
63
+ SKELETON_SHAPES[shape] ?? SKELETON_SHAPES.line,
64
+ className,
65
+ )}
66
+ />
67
+ );
68
+ }
69
+
70
+ const PROGRESS_TONES = {
71
+ neutral: "bg-primary",
72
+ success: "bg-success",
73
+ warning: "bg-warning",
74
+ danger: "bg-destructive",
75
+ info: "bg-info",
76
+ };
77
+
78
+ // The indeterminate sweep. Tailwind ships no such keyframes and the kit
79
+ // does not edit globals.css, so the bar carries its own; identical copies
80
+ // are harmless.
81
+ const SWEEP = "@keyframes kit-progress-sweep{from{transform:translateX(-100%)}to{transform:translateX(250%)}}";
82
+
83
+ /**
84
+ * How far along a known job is (value of max), or that an unknown one is
85
+ * running (value omitted). A role=progressbar the browser and screen
86
+ * readers understand, drawn from tokens — the native <progress> cannot be
87
+ * themed the same way in every engine.
88
+ *
89
+ * value 0…max; null/undefined → indeterminate (a sweeping bar)
90
+ * max default 100
91
+ * label the bar's name, shown above it and read to a screen reader
92
+ * valueText what the right side says and a reader hears ("3 of 5
93
+ * steps"); default the percent. Omitted when indeterminate
94
+ * tone neutral · success · warning · danger · info — status only
95
+ */
96
+ export function Progress({ value, max = 100, label, valueText, tone = "neutral", className, ...rest }) {
97
+ const known = typeof value === "number" && Number.isFinite(value);
98
+ const pct = known && max > 0 ? Math.min(100, Math.max(0, (value / max) * 100)) : 0;
99
+ const text = known ? valueText ?? `${Math.round(pct)}%` : undefined;
100
+ const fill = PROGRESS_TONES[tone] ?? PROGRESS_TONES.neutral;
101
+ return (
102
+ <div className={cx("grid gap-1.5", className)}>
103
+ {label ? (
104
+ <div aria-hidden="true" className="flex items-baseline justify-between gap-3 text-sm">
105
+ <span className="min-w-0 truncate font-medium text-foreground">{label}</span>
106
+ {text ? (
107
+ <span data-nums className="shrink-0 text-xs text-muted-foreground">
108
+ {text}
109
+ </span>
110
+ ) : null}
111
+ </div>
112
+ ) : null}
113
+ <div
114
+ role="progressbar"
115
+ aria-label={label}
116
+ aria-valuemin={0}
117
+ aria-valuemax={known ? max : undefined}
118
+ aria-valuenow={known ? value : undefined}
119
+ aria-valuetext={text}
120
+ className="relative h-2 w-full overflow-hidden rounded-full bg-accent"
121
+ {...rest}
122
+ >
123
+ {known ? (
124
+ <div
125
+ className={cx("h-full rounded-full transition-[width] duration-300 ease-out motion-reduce:transition-none", fill)}
126
+ style={{ width: `${pct}%` }}
127
+ />
128
+ ) : (
129
+ <>
130
+ <style>{SWEEP}</style>
131
+ <div
132
+ className={cx(
133
+ "h-full w-2/5 rounded-full animate-[kit-progress-sweep_1.4s_ease-in-out_infinite]",
134
+ "motion-reduce:w-full motion-reduce:animate-pulse",
135
+ fill,
136
+ )}
137
+ />
138
+ </>
139
+ )}
140
+ </div>
141
+ </div>
142
+ );
143
+ }
@@ -1,3 +1,6 @@
1
+ "use client";
2
+
3
+ import { useCallback, useLayoutEffect, useRef } from "react";
1
4
  import { cx } from "./cx";
2
5
 
3
6
  // Form parts. Each is the native element with the workspace's look and a
@@ -39,12 +42,121 @@ export function Input({ className, invalid, ...rest }) {
39
42
  return <input className={cx(CONTROL, className)} aria-invalid={invalid ? true : undefined} {...rest} />;
40
43
  }
41
44
 
42
- export function Textarea({ className, invalid, rows = 4, ...rest }) {
45
+ /**
46
+ * A time of day: the native <input type="time"> (the browser's segments,
47
+ * keyboard and picker; `value` is "HH:MM", or "HH:MM:SS" with `step` under
48
+ * 60), in the workspace's look. The browser's own clock button is drawn
49
+ * by the engine in its own grey and ignores the theme, so it is laid
50
+ * invisibly over the kit's clock glyph: the glyph is what shows, the
51
+ * native button is what a press opens. min, max, step, required and every
52
+ * other prop go to the input.
53
+ */
54
+ export function TimeInput({ className, invalid, ...rest }) {
55
+ return (
56
+ <span className="relative block">
57
+ <input
58
+ type="time"
59
+ className={cx(
60
+ CONTROL,
61
+ "appearance-none pr-10 tabular-nums [&::-webkit-date-and-time-value]:text-left",
62
+ "[&::-webkit-calendar-picker-indicator]:absolute [&::-webkit-calendar-picker-indicator]:right-3 [&::-webkit-calendar-picker-indicator]:top-1/2",
63
+ "[&::-webkit-calendar-picker-indicator]:size-5 [&::-webkit-calendar-picker-indicator]:-translate-y-1/2 [&::-webkit-calendar-picker-indicator]:m-0",
64
+ "[&::-webkit-calendar-picker-indicator]:cursor-pointer [&::-webkit-calendar-picker-indicator]:opacity-0",
65
+ className,
66
+ )}
67
+ aria-invalid={invalid ? true : undefined}
68
+ {...rest}
69
+ />
70
+ <svg
71
+ aria-hidden="true"
72
+ className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground"
73
+ width="16"
74
+ height="16"
75
+ viewBox="0 0 24 24"
76
+ fill="none"
77
+ stroke="currentColor"
78
+ strokeWidth="1.8"
79
+ strokeLinecap="round"
80
+ strokeLinejoin="round"
81
+ >
82
+ <path d="M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Zm0 4v5l3 3" />
83
+ </svg>
84
+ </span>
85
+ );
86
+ }
87
+
88
+ /**
89
+ * Keeps a <textarea> as tall as its text, between `minRows` and `maxRows`
90
+ * lines; past `maxRows` it scrolls. Returns the ref callback to put on the
91
+ * textarea (it also sets `outer`, a ref of the caller's). It measures on
92
+ * every value change, typed or set (a composer clearing after send), and
93
+ * when the width changes the wrapping. Textarea autoGrow and InputGroup
94
+ * multiline use it; it is not a surface's tool.
95
+ */
96
+ export function useAutoGrow({ enabled = true, minRows = 1, maxRows = 8, value, outer }) {
97
+ const node = useRef(null);
98
+
99
+ const fit = useCallback(() => {
100
+ const el = node.current;
101
+ if (!el || !enabled) return;
102
+ const cs = getComputedStyle(el);
103
+ const line = parseFloat(cs.lineHeight) || parseFloat(cs.fontSize) * 1.5 || 20;
104
+ const frame =
105
+ parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom) +
106
+ (cs.boxSizing === "border-box" ? parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth) : 0);
107
+ const low = line * Math.max(1, minRows) + frame;
108
+ const high = Number.isFinite(maxRows) && maxRows > 0 ? line * Math.max(minRows, maxRows) + frame : Infinity;
109
+ el.style.height = "auto";
110
+ const content = el.scrollHeight + (cs.boxSizing === "border-box" ? parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth) : 0);
111
+ el.style.height = `${Math.min(Math.max(content, low), high)}px`;
112
+ el.style.overflowY = content > high ? "auto" : "hidden";
113
+ }, [enabled, minRows, maxRows]);
114
+
115
+ useLayoutEffect(fit, [fit, value]);
116
+
117
+ // A width change re-wraps the text; a height change is our own doing.
118
+ useLayoutEffect(() => {
119
+ const el = node.current;
120
+ if (!el || !enabled || typeof ResizeObserver === "undefined") return;
121
+ let width = el.clientWidth;
122
+ const ro = new ResizeObserver(() => {
123
+ if (el.clientWidth === width) return;
124
+ width = el.clientWidth;
125
+ fit();
126
+ });
127
+ ro.observe(el);
128
+ return () => ro.disconnect();
129
+ }, [enabled, fit]);
130
+
131
+ const ref = useCallback(
132
+ (el) => {
133
+ node.current = el;
134
+ if (typeof outer === "function") return outer(el);
135
+ if (outer) outer.current = el;
136
+ },
137
+ [outer],
138
+ );
139
+ return { ref, fit };
140
+ }
141
+
142
+ /**
143
+ * The native <textarea>. `rows` sets its height (default 4) and it
144
+ * resizes by its corner. `autoGrow` makes it as tall as its text instead:
145
+ * from `minRows` (default 1) to `maxRows` (default 8) lines, then it
146
+ * scrolls; no resize corner.
147
+ */
148
+ export function Textarea({ className, invalid, rows = 4, autoGrow = false, minRows = 1, maxRows = 8, onInput, ref, ...rest }) {
149
+ const grow = useAutoGrow({ enabled: autoGrow, minRows, maxRows, value: rest.value, outer: ref });
43
150
  return (
44
151
  <textarea
45
- rows={rows}
46
- className={cx(CONTROL, "min-h-24 resize-y py-2.5 leading-normal", className)}
152
+ ref={grow.ref}
153
+ rows={autoGrow ? minRows : rows}
154
+ className={cx(CONTROL, autoGrow ? "resize-none py-2.5 leading-normal" : "min-h-24 resize-y py-2.5 leading-normal", className)}
47
155
  aria-invalid={invalid ? true : undefined}
156
+ onInput={(e) => {
157
+ if (autoGrow) grow.fit();
158
+ onInput?.(e);
159
+ }}
48
160
  {...rest}
49
161
  />
50
162
  );
@@ -0,0 +1,234 @@
1
+ "use client";
2
+
3
+ import { useId, useRef, useState } from "react";
4
+ import { cx } from "./cx";
5
+ import { Button, IconButton } from "./button";
6
+ import { Icon } from "./icon";
7
+
8
+ // FileInput and FileDrop — how files come in. Both are a real hidden
9
+ // <input type=file> underneath, so the picker is the browser's own (the
10
+ // camera roll on a phone, the Finder on a Mac); the kit draws the door.
11
+ // Neither uploads: the chosen files go out through `onFiles(files)` (an
12
+ // array of File) and the upload is yours.
13
+ //
14
+ // FileInput — a Button that opens the picker.
15
+ // children the button's text ("Upload a CSV"); without children it is
16
+ // an IconButton and `label` (required then) is what a reader
17
+ // says ("Attach files")
18
+ // icon the glyph (upload; paperclip for a composer)
19
+ // variant, size as Button
20
+ //
21
+ // FileDrop — a drop zone: drag files onto it, or press it (click, Enter,
22
+ // Space) for the picker. It lights up while files are dragged over it.
23
+ // label the line inside it ("Drop files here or browse")
24
+ // hint the muted line under it ("PNG or JPG, up to 10 MB")
25
+ // size md (a tall box; the default) · sm (one row)
26
+ // children replaces the icon, label and hint inside the zone
27
+ // invalid marks the zone red (a rejected file, a required one missing)
28
+ //
29
+ // Both:
30
+ // accept as the input's ("image/*", ".csv,text/csv"). The picker
31
+ // greys out the rest; a drop is filtered the same way and what
32
+ // does not match goes to `onReject(files)`
33
+ // multiple more than one file (a drop of several with multiple off
34
+ // keeps the first)
35
+ // disabled no picker, no drop
36
+ // onFiles (files) — never called with an empty array
37
+ //
38
+ // Choosing the same file twice in a row fires onFiles twice: the input is
39
+ // emptied after every pick.
40
+
41
+ /** Does `file` match an accept string ("image/*,.pdf,text/csv")? */
42
+ export function fileMatches(file, accept) {
43
+ if (!accept) return true;
44
+ const name = (file.name ?? "").toLowerCase();
45
+ const type = (file.type ?? "").toLowerCase();
46
+ return accept
47
+ .split(",")
48
+ .map((a) => a.trim().toLowerCase())
49
+ .filter(Boolean)
50
+ .some((a) => {
51
+ if (a.startsWith(".")) return name.endsWith(a);
52
+ if (a.endsWith("/*")) return type.startsWith(a.slice(0, -1));
53
+ return type === a;
54
+ });
55
+ }
56
+
57
+ function split(list, accept, multiple) {
58
+ const all = Array.from(list ?? []);
59
+ const ok = all.filter((f) => fileMatches(f, accept));
60
+ const no = all.filter((f) => !fileMatches(f, accept));
61
+ return { ok: multiple ? ok : ok.slice(0, 1), no };
62
+ }
63
+
64
+ function Hidden({ input, accept, multiple, disabled, capture, onPick }) {
65
+ return (
66
+ <input
67
+ ref={input}
68
+ type="file"
69
+ hidden
70
+ tabIndex={-1}
71
+ aria-hidden="true"
72
+ accept={accept}
73
+ multiple={multiple}
74
+ disabled={disabled}
75
+ capture={capture}
76
+ onChange={(e) => {
77
+ const list = Array.from(e.target.files ?? []);
78
+ e.target.value = "";
79
+ onPick(list);
80
+ }}
81
+ />
82
+ );
83
+ }
84
+
85
+ export function FileInput({
86
+ onFiles,
87
+ onReject,
88
+ accept,
89
+ multiple = false,
90
+ disabled = false,
91
+ capture,
92
+ icon = "upload",
93
+ label,
94
+ variant,
95
+ size,
96
+ className,
97
+ children,
98
+ ...rest
99
+ }) {
100
+ const input = useRef(null);
101
+ const pick = (list) => {
102
+ const { ok, no } = split(list, accept, multiple);
103
+ if (no.length) onReject?.(no);
104
+ if (ok.length) onFiles?.(ok);
105
+ };
106
+ const open = () => {
107
+ if (!disabled) input.current?.click();
108
+ };
109
+ return (
110
+ <>
111
+ <Hidden input={input} accept={accept} multiple={multiple} disabled={disabled} capture={capture} onPick={pick} />
112
+ {children ? (
113
+ <Button icon={icon} variant={variant} size={size} disabled={disabled} onClick={open} className={className} {...rest}>
114
+ {children}
115
+ </Button>
116
+ ) : (
117
+ <IconButton icon={icon} label={label ?? "Choose files"} variant={variant} size={size} disabled={disabled} onClick={open} className={className} {...rest} />
118
+ )}
119
+ </>
120
+ );
121
+ }
122
+
123
+ const ZONE_SIZES = {
124
+ md: "min-h-40 flex-col justify-center gap-2 px-6 py-8 text-center",
125
+ sm: "min-h-11 flex-row justify-start gap-3 px-3 py-2.5 text-left",
126
+ };
127
+
128
+ export function FileDrop({
129
+ onFiles,
130
+ onReject,
131
+ accept,
132
+ multiple = false,
133
+ disabled = false,
134
+ label = "Drop files here or browse",
135
+ hint,
136
+ size = "md",
137
+ invalid = false,
138
+ className,
139
+ children,
140
+ "aria-label": ariaLabel,
141
+ ...rest
142
+ }) {
143
+ const input = useRef(null);
144
+ const id = useId();
145
+ const [over, setOver] = useState(false);
146
+ const depth = useRef(0);
147
+
148
+ const pick = (list) => {
149
+ const { ok, no } = split(list, accept, multiple);
150
+ if (no.length) onReject?.(no);
151
+ if (ok.length) onFiles?.(ok);
152
+ };
153
+ const open = () => {
154
+ if (!disabled) input.current?.click();
155
+ };
156
+ const hasFiles = (e) => Array.from(e.dataTransfer?.types ?? []).includes("Files");
157
+
158
+ return (
159
+ <div
160
+ role="button"
161
+ tabIndex={disabled ? -1 : 0}
162
+ aria-disabled={disabled || undefined}
163
+ aria-invalid={invalid || undefined}
164
+ aria-label={ariaLabel}
165
+ aria-describedby={hint && !children ? `${id}-hint` : undefined}
166
+ data-dragging={over ? "" : undefined}
167
+ onClick={(e) => {
168
+ if (e.target.closest("button, a, input")) return;
169
+ open();
170
+ }}
171
+ onKeyDown={(e) => {
172
+ if (e.target !== e.currentTarget) return;
173
+ if (e.key === "Enter" || e.key === " ") {
174
+ e.preventDefault();
175
+ open();
176
+ }
177
+ }}
178
+ onDragEnter={(e) => {
179
+ if (disabled || !hasFiles(e)) return;
180
+ e.preventDefault();
181
+ depth.current += 1;
182
+ setOver(true);
183
+ }}
184
+ onDragOver={(e) => {
185
+ if (disabled || !hasFiles(e)) return;
186
+ e.preventDefault();
187
+ e.dataTransfer.dropEffect = "copy";
188
+ }}
189
+ onDragLeave={() => {
190
+ depth.current = Math.max(0, depth.current - 1);
191
+ if (depth.current === 0) setOver(false);
192
+ }}
193
+ onDrop={(e) => {
194
+ if (disabled) return;
195
+ e.preventDefault();
196
+ depth.current = 0;
197
+ setOver(false);
198
+ pick(e.dataTransfer?.files);
199
+ }}
200
+ className={cx(
201
+ "flex w-full cursor-pointer items-center rounded-lg border border-dashed bg-background text-sm transition-colors",
202
+ "outline-none focus-visible:ring-2 focus-visible:ring-ring",
203
+ "hover:bg-accent data-[dragging]:border-solid data-[dragging]:border-primary data-[dragging]:bg-accent",
204
+ invalid ? "border-destructive" : "border-input",
205
+ disabled && "pointer-events-none cursor-not-allowed opacity-50",
206
+ ZONE_SIZES[size] ?? ZONE_SIZES.md,
207
+ className,
208
+ )}
209
+ {...rest}
210
+ >
211
+ <Hidden input={input} accept={accept} multiple={multiple} disabled={disabled} onPick={pick} />
212
+ {children ?? (
213
+ <>
214
+ <span
215
+ className={cx(
216
+ "flex shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground",
217
+ size === "sm" ? "size-8" : "size-10",
218
+ )}
219
+ >
220
+ <Icon name="upload" size={size === "sm" ? 16 : 18} />
221
+ </span>
222
+ <span className="grid min-w-0 gap-0.5">
223
+ <span className="font-medium text-foreground">{over ? (multiple ? "Drop to add them" : "Drop to add it") : label}</span>
224
+ {hint ? (
225
+ <span id={`${id}-hint`} className={cx("text-xs", invalid ? "text-destructive" : "text-muted-foreground")}>
226
+ {hint}
227
+ </span>
228
+ ) : null}
229
+ </span>
230
+ </>
231
+ )}
232
+ </div>
233
+ );
234
+ }