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.
- package/THIRD-PARTY-NOTICES.md +180 -0
- package/package.json +3 -2
- package/r/annotate.json +62 -0
- package/r/approval-request.json +52 -0
- package/r/audio-player.json +74 -0
- package/r/auth-form.json +55 -0
- package/r/board.json +10 -6
- package/r/calendar-view.json +105 -0
- package/r/cart.json +62 -0
- package/r/chart.json +83 -0
- package/r/chat.json +95 -0
- package/r/code-editor.json +94 -0
- package/r/comment-box.json +64 -0
- package/r/contact-section.json +53 -0
- package/r/core.json +205 -8
- package/r/csv-import.json +63 -0
- package/r/data-table.json +69 -0
- package/r/diagram.json +74 -0
- package/r/doc-editor.json +82 -0
- package/r/doc-page.json +61 -0
- package/r/email-render.json +73 -0
- package/r/faq.json +50 -0
- package/r/file-upload.json +54 -0
- package/r/flow-canvas.json +93 -0
- package/r/footer.json +52 -0
- package/r/gantt.json +70 -0
- package/r/job-panel.json +12 -7
- package/r/json-editor.json +66 -0
- package/r/map.json +89 -0
- package/r/menubar.json +52 -0
- package/r/mind-map.json +67 -0
- package/r/navigation-menu.json +52 -0
- package/r/order-detail.json +54 -0
- package/r/org-chart.json +66 -0
- package/r/page-builder.json +105 -0
- package/r/payment-methods.json +51 -0
- package/r/pdf-document.json +79 -0
- package/r/pdf-viewer.json +88 -0
- package/r/product-detail.json +76 -0
- package/r/product-grid.json +65 -0
- package/r/record-form.json +67 -0
- package/r/record-notes.json +55 -0
- package/r/registry.json +3411 -29
- package/r/search-dialog.json +51 -0
- package/r/settings-list.json +66 -0
- package/r/setup-checklist.json +51 -0
- package/r/share-dialog.json +52 -0
- package/r/sidebar.json +69 -0
- package/r/signature-pad.json +72 -0
- package/r/sketch-canvas.json +99 -0
- package/r/spreadsheet.json +90 -0
- package/r/stat-cards.json +66 -0
- package/r/task-list.json +63 -0
- package/r/task-model.json +98 -0
- package/r/testimonials.json +52 -0
- package/r/transaction-list.json +53 -0
- package/r/whiteboard.json +66 -0
- package/registry/blocks/annotate/README.md +179 -0
- package/registry/blocks/annotate/annotate-data.js +250 -0
- package/registry/blocks/annotate/annotate.jsx +646 -0
- package/registry/blocks/annotate/block.json +10 -0
- package/registry/blocks/annotate/demo.jsx +135 -0
- package/registry/blocks/annotate/index.js +15 -0
- package/registry/blocks/approval-request/README.md +116 -0
- package/registry/blocks/approval-request/approval-request.jsx +386 -0
- package/registry/blocks/approval-request/block.json +10 -0
- package/registry/blocks/approval-request/demo.jsx +127 -0
- package/registry/blocks/approval-request/index.js +4 -0
- package/registry/blocks/audio-player/README.md +167 -0
- package/registry/blocks/audio-player/audio-player.jsx +623 -0
- package/registry/blocks/audio-player/block.json +14 -0
- package/registry/blocks/audio-player/colors.js +109 -0
- package/registry/blocks/audio-player/demo.jsx +209 -0
- package/registry/blocks/audio-player/index.js +6 -0
- package/registry/blocks/audio-player/time.js +67 -0
- package/registry/blocks/audio-player/wavesurfer.js +9 -0
- package/registry/blocks/auth-form/README.md +126 -0
- package/registry/blocks/auth-form/auth-form.jsx +568 -0
- package/registry/blocks/auth-form/block.json +10 -0
- package/registry/blocks/auth-form/demo.jsx +131 -0
- package/registry/blocks/auth-form/index.js +3 -0
- package/registry/blocks/board/README.md +55 -5
- package/registry/blocks/board/block.json +2 -2
- package/registry/blocks/board/board.jsx +230 -86
- package/registry/blocks/board/demo.jsx +103 -24
- package/registry/blocks/calendar-view/README.md +180 -0
- package/registry/blocks/calendar-view/agenda.jsx +147 -0
- package/registry/blocks/calendar-view/block.json +76 -0
- package/registry/blocks/calendar-view/calendar-model.js +442 -0
- package/registry/blocks/calendar-view/calendar.jsx +627 -0
- package/registry/blocks/calendar-view/demo.jsx +195 -0
- package/registry/blocks/calendar-view/draft.jsx +49 -0
- package/registry/blocks/calendar-view/index.js +39 -0
- package/registry/blocks/calendar-view/month.jsx +346 -0
- package/registry/blocks/calendar-view/paint.js +69 -0
- package/registry/blocks/calendar-view/time-grid.jsx +527 -0
- package/registry/blocks/calendar-view/tray.jsx +87 -0
- package/registry/blocks/cart/README.md +146 -0
- package/registry/blocks/cart/block.json +10 -0
- package/registry/blocks/cart/cart.jsx +597 -0
- package/registry/blocks/cart/demo.jsx +98 -0
- package/registry/blocks/cart/index.js +4 -0
- package/registry/blocks/cart/money.js +28 -0
- package/registry/blocks/chart/README.md +316 -0
- package/registry/blocks/chart/block.json +10 -0
- package/registry/blocks/chart/cartesian.jsx +642 -0
- package/registry/blocks/chart/core.jsx +262 -0
- package/registry/blocks/chart/demo.jsx +357 -0
- package/registry/blocks/chart/heatmap.jsx +336 -0
- package/registry/blocks/chart/index.js +8 -0
- package/registry/blocks/chart/pie.jsx +245 -0
- package/registry/blocks/chart/sparkline.jsx +88 -0
- package/registry/blocks/chat/README.md +273 -0
- package/registry/blocks/chat/attachment.jsx +95 -0
- package/registry/blocks/chat/block.json +10 -0
- package/registry/blocks/chat/chat.jsx +132 -0
- package/registry/blocks/chat/composer.jsx +364 -0
- package/registry/blocks/chat/demo.jsx +578 -0
- package/registry/blocks/chat/header.jsx +34 -0
- package/registry/blocks/chat/index.js +9 -0
- package/registry/blocks/chat/message.jsx +450 -0
- package/registry/blocks/chat/scroller.jsx +247 -0
- package/registry/blocks/chat/text.jsx +104 -0
- package/registry/blocks/code-editor/README.md +210 -0
- package/registry/blocks/code-editor/block.json +22 -0
- package/registry/blocks/code-editor/code-editor.jsx +534 -0
- package/registry/blocks/code-editor/codemirror.js +38 -0
- package/registry/blocks/code-editor/demo.jsx +205 -0
- package/registry/blocks/code-editor/index.js +8 -0
- package/registry/blocks/code-editor/json.js +317 -0
- package/registry/blocks/code-editor/sql.js +136 -0
- package/registry/blocks/code-editor/text.js +101 -0
- package/registry/blocks/code-editor/theme.js +186 -0
- package/registry/blocks/comment-box/README.md +123 -0
- package/registry/blocks/comment-box/block.json +10 -0
- package/registry/blocks/comment-box/comment-body.jsx +217 -0
- package/registry/blocks/comment-box/comment-box.jsx +198 -0
- package/registry/blocks/comment-box/comment-time.jsx +77 -0
- package/registry/blocks/comment-box/demo.jsx +141 -0
- package/registry/blocks/comment-box/index.js +8 -0
- package/registry/blocks/contact-section/README.md +152 -0
- package/registry/blocks/contact-section/block.json +11 -0
- package/registry/blocks/contact-section/contact-section.jsx +509 -0
- package/registry/blocks/contact-section/demo.jsx +93 -0
- package/registry/blocks/contact-section/index.js +4 -0
- package/registry/blocks/csv-import/README.md +133 -0
- package/registry/blocks/csv-import/block.json +13 -0
- package/registry/blocks/csv-import/csv-import.jsx +479 -0
- package/registry/blocks/csv-import/demo.jsx +106 -0
- package/registry/blocks/csv-import/import.js +200 -0
- package/registry/blocks/csv-import/index.js +7 -0
- package/registry/blocks/data-table/README.md +386 -0
- package/registry/blocks/data-table/block.json +10 -0
- package/registry/blocks/data-table/data-table.jsx +1164 -0
- package/registry/blocks/data-table/demo.jsx +588 -0
- package/registry/blocks/data-table/index.js +5 -0
- package/registry/blocks/data-table/model.js +169 -0
- package/registry/blocks/diagram/README.md +108 -0
- package/registry/blocks/diagram/block.json +13 -0
- package/registry/blocks/diagram/demo.jsx +113 -0
- package/registry/blocks/diagram/diagram.jsx +481 -0
- package/registry/blocks/diagram/index.js +7 -0
- package/registry/blocks/diagram/mermaid.js +52 -0
- package/registry/blocks/diagram/palette.js +313 -0
- package/registry/blocks/diagram/source.js +98 -0
- package/registry/blocks/doc-editor/README.md +215 -0
- package/registry/blocks/doc-editor/block.json +15 -0
- package/registry/blocks/doc-editor/demo.jsx +225 -0
- package/registry/blocks/doc-editor/doc-editor.jsx +291 -0
- package/registry/blocks/doc-editor/doc.js +309 -0
- package/registry/blocks/doc-editor/index.js +7 -0
- package/registry/blocks/doc-editor/schema.jsx +56 -0
- package/registry/blocks/doc-editor/shadcn-classes.js +110 -0
- package/registry/blocks/doc-editor/theme.js +82 -0
- package/registry/blocks/doc-page/README.md +119 -0
- package/registry/blocks/doc-page/autosave.js +104 -0
- package/registry/blocks/doc-page/block.json +10 -0
- package/registry/blocks/doc-page/demo.jsx +137 -0
- package/registry/blocks/doc-page/doc-page.jsx +276 -0
- package/registry/blocks/doc-page/index.js +4 -0
- package/registry/blocks/email-render/README.md +151 -0
- package/registry/blocks/email-render/block.json +14 -0
- package/registry/blocks/email-render/demo.jsx +153 -0
- package/registry/blocks/email-render/doc-email.jsx +210 -0
- package/registry/blocks/email-render/email.jsx +221 -0
- package/registry/blocks/email-render/index.js +10 -0
- package/registry/blocks/email-render/render.js +50 -0
- package/registry/blocks/email-render/theme.js +215 -0
- package/registry/blocks/faq/README.md +101 -0
- package/registry/blocks/faq/block.json +11 -0
- package/registry/blocks/faq/demo.jsx +89 -0
- package/registry/blocks/faq/faq.jsx +220 -0
- package/registry/blocks/faq/index.js +4 -0
- package/registry/blocks/file-upload/README.md +138 -0
- package/registry/blocks/file-upload/block.json +10 -0
- package/registry/blocks/file-upload/demo.jsx +204 -0
- package/registry/blocks/file-upload/file-upload.jsx +635 -0
- package/registry/blocks/file-upload/index.js +4 -0
- package/registry/blocks/flow-canvas/README.md +420 -0
- package/registry/blocks/flow-canvas/block.json +13 -0
- package/registry/blocks/flow-canvas/board.js +819 -0
- package/registry/blocks/flow-canvas/chrome.jsx +649 -0
- package/registry/blocks/flow-canvas/context.jsx +35 -0
- package/registry/blocks/flow-canvas/demo.jsx +249 -0
- package/registry/blocks/flow-canvas/edges.jsx +107 -0
- package/registry/blocks/flow-canvas/flow-canvas.jsx +1329 -0
- package/registry/blocks/flow-canvas/index.js +41 -0
- package/registry/blocks/flow-canvas/nodes.jsx +392 -0
- package/registry/blocks/flow-canvas/theme.js +174 -0
- package/registry/blocks/footer/README.md +133 -0
- package/registry/blocks/footer/block.json +11 -0
- package/registry/blocks/footer/demo.jsx +119 -0
- package/registry/blocks/footer/footer.jsx +406 -0
- package/registry/blocks/footer/index.js +4 -0
- package/registry/blocks/gantt/README.md +220 -0
- package/registry/blocks/gantt/block.json +10 -0
- package/registry/blocks/gantt/demo.jsx +148 -0
- package/registry/blocks/gantt/gantt.jsx +923 -0
- package/registry/blocks/gantt/index.js +7 -0
- package/registry/blocks/gantt/rows.jsx +468 -0
- package/registry/blocks/gantt/schedule.js +278 -0
- package/registry/blocks/job-panel/README.md +80 -0
- package/registry/blocks/job-panel/block.json +3 -3
- package/registry/blocks/job-panel/demo.jsx +230 -3
- package/registry/blocks/job-panel/job-panel.jsx +169 -3
- package/registry/blocks/json-editor/README.md +133 -0
- package/registry/blocks/json-editor/block.json +10 -0
- package/registry/blocks/json-editor/demo.jsx +92 -0
- package/registry/blocks/json-editor/index.js +7 -0
- package/registry/blocks/json-editor/json-editor.jsx +305 -0
- package/registry/blocks/json-editor/json-tree.jsx +393 -0
- package/registry/blocks/json-editor/tree.js +225 -0
- package/registry/blocks/map/README.md +221 -0
- package/registry/blocks/map/block.json +14 -0
- package/registry/blocks/map/demo.jsx +201 -0
- package/registry/blocks/map/geo.js +198 -0
- package/registry/blocks/map/index.js +8 -0
- package/registry/blocks/map/list.jsx +128 -0
- package/registry/blocks/map/map-view.jsx +715 -0
- package/registry/blocks/map/maplibre.js +30 -0
- package/registry/blocks/map/marks.jsx +146 -0
- package/registry/blocks/map/theme.js +142 -0
- package/registry/blocks/menubar/README.md +109 -0
- package/registry/blocks/menubar/block.json +10 -0
- package/registry/blocks/menubar/demo.jsx +128 -0
- package/registry/blocks/menubar/index.js +4 -0
- package/registry/blocks/menubar/menubar.jsx +199 -0
- package/registry/blocks/mind-map/README.md +206 -0
- package/registry/blocks/mind-map/block.json +10 -0
- package/registry/blocks/mind-map/demo.jsx +103 -0
- package/registry/blocks/mind-map/index.js +31 -0
- package/registry/blocks/mind-map/mind-map.jsx +1125 -0
- package/registry/blocks/mind-map/topic.jsx +143 -0
- package/registry/blocks/mind-map/tree.js +645 -0
- package/registry/blocks/navigation-menu/README.md +124 -0
- package/registry/blocks/navigation-menu/block.json +10 -0
- package/registry/blocks/navigation-menu/demo.jsx +84 -0
- package/registry/blocks/navigation-menu/index.js +4 -0
- package/registry/blocks/navigation-menu/navigation-menu.jsx +448 -0
- package/registry/blocks/order-detail/README.md +109 -0
- package/registry/blocks/order-detail/block.json +10 -0
- package/registry/blocks/order-detail/demo.jsx +88 -0
- package/registry/blocks/order-detail/index.js +4 -0
- package/registry/blocks/order-detail/order-detail.jsx +354 -0
- package/registry/blocks/org-chart/README.md +145 -0
- package/registry/blocks/org-chart/block.json +10 -0
- package/registry/blocks/org-chart/demo.jsx +94 -0
- package/registry/blocks/org-chart/index.js +7 -0
- package/registry/blocks/org-chart/org-chart.jsx +631 -0
- package/registry/blocks/org-chart/org.js +245 -0
- package/registry/blocks/org-chart/person.jsx +96 -0
- package/registry/blocks/page-builder/README.md +257 -0
- package/registry/blocks/page-builder/block.json +14 -0
- package/registry/blocks/page-builder/demo.jsx +145 -0
- package/registry/blocks/page-builder/grapes.js +18 -0
- package/registry/blocks/page-builder/index.js +11 -0
- package/registry/blocks/page-builder/page-builder.jsx +704 -0
- package/registry/blocks/page-builder/page-view.jsx +33 -0
- package/registry/blocks/page-builder/page.js +118 -0
- package/registry/blocks/page-builder/panels.jsx +588 -0
- package/registry/blocks/page-builder/sections.js +209 -0
- package/registry/blocks/page-builder/theme.js +87 -0
- package/registry/blocks/page-builder/thumbs.jsx +189 -0
- package/registry/blocks/page-builder/tokens.js +329 -0
- package/registry/blocks/payment-methods/README.md +104 -0
- package/registry/blocks/payment-methods/block.json +10 -0
- package/registry/blocks/payment-methods/demo.jsx +71 -0
- package/registry/blocks/payment-methods/index.js +4 -0
- package/registry/blocks/payment-methods/payment-methods.jsx +302 -0
- package/registry/blocks/pdf-document/README.md +213 -0
- package/registry/blocks/pdf-document/block.json +13 -0
- package/registry/blocks/pdf-document/demo.jsx +136 -0
- package/registry/blocks/pdf-document/index.js +33 -0
- package/registry/blocks/pdf-document/money.js +83 -0
- package/registry/blocks/pdf-document/pdf-document.jsx +144 -0
- package/registry/blocks/pdf-document/primitives.jsx +271 -0
- package/registry/blocks/pdf-document/quote.jsx +179 -0
- package/registry/blocks/pdf-document/theme.js +193 -0
- package/registry/blocks/pdf-viewer/README.md +191 -0
- package/registry/blocks/pdf-viewer/block.json +14 -0
- package/registry/blocks/pdf-viewer/demo.jsx +252 -0
- package/registry/blocks/pdf-viewer/helpers.js +270 -0
- package/registry/blocks/pdf-viewer/index.js +8 -0
- package/registry/blocks/pdf-viewer/notes.jsx +195 -0
- package/registry/blocks/pdf-viewer/pdf-viewer.jsx +1368 -0
- package/registry/blocks/pdf-viewer/pdfjs.js +37 -0
- package/registry/blocks/pdf-viewer/ssr-shim-end.js +6 -0
- package/registry/blocks/pdf-viewer/ssr-shim.js +44 -0
- package/registry/blocks/product-detail/README.md +217 -0
- package/registry/blocks/product-detail/block.json +10 -0
- package/registry/blocks/product-detail/demo.jsx +233 -0
- package/registry/blocks/product-detail/index.js +7 -0
- package/registry/blocks/product-detail/price.jsx +115 -0
- package/registry/blocks/product-detail/product-detail.jsx +348 -0
- package/registry/blocks/product-detail/product-media.jsx +102 -0
- package/registry/blocks/product-detail/product-options.jsx +144 -0
- package/registry/blocks/product-grid/README.md +162 -0
- package/registry/blocks/product-grid/block.json +10 -0
- package/registry/blocks/product-grid/demo.jsx +255 -0
- package/registry/blocks/product-grid/index.js +5 -0
- package/registry/blocks/product-grid/product-card.jsx +232 -0
- package/registry/blocks/product-grid/product-grid.jsx +235 -0
- package/registry/blocks/record-form/README.md +196 -0
- package/registry/blocks/record-form/block.json +10 -0
- package/registry/blocks/record-form/demo.jsx +525 -0
- package/registry/blocks/record-form/index.js +4 -0
- package/registry/blocks/record-form/record-fields.jsx +457 -0
- package/registry/blocks/record-form/record-form.jsx +415 -0
- package/registry/blocks/record-form/rules.js +81 -0
- package/registry/blocks/record-notes/README.md +139 -0
- package/registry/blocks/record-notes/block.json +10 -0
- package/registry/blocks/record-notes/demo.jsx +179 -0
- package/registry/blocks/record-notes/index.js +4 -0
- package/registry/blocks/record-notes/record-notes.jsx +266 -0
- package/registry/blocks/search-dialog/README.md +108 -0
- package/registry/blocks/search-dialog/block.json +10 -0
- package/registry/blocks/search-dialog/demo.jsx +116 -0
- package/registry/blocks/search-dialog/index.js +3 -0
- package/registry/blocks/search-dialog/search-dialog.jsx +235 -0
- package/registry/blocks/settings-list/README.md +171 -0
- package/registry/blocks/settings-list/block.json +10 -0
- package/registry/blocks/settings-list/demo.jsx +333 -0
- package/registry/blocks/settings-list/index.js +4 -0
- package/registry/blocks/settings-list/row-state.jsx +93 -0
- package/registry/blocks/settings-list/settings-list.jsx +349 -0
- package/registry/blocks/settings-list/settings-matrix.jsx +118 -0
- package/registry/blocks/setup-checklist/README.md +142 -0
- package/registry/blocks/setup-checklist/block.json +10 -0
- package/registry/blocks/setup-checklist/demo.jsx +159 -0
- package/registry/blocks/setup-checklist/index.js +4 -0
- package/registry/blocks/setup-checklist/setup-checklist.jsx +446 -0
- package/registry/blocks/share-dialog/README.md +113 -0
- package/registry/blocks/share-dialog/block.json +10 -0
- package/registry/blocks/share-dialog/demo.jsx +140 -0
- package/registry/blocks/share-dialog/index.js +3 -0
- package/registry/blocks/share-dialog/share-dialog.jsx +384 -0
- package/registry/blocks/sidebar/README.md +190 -0
- package/registry/blocks/sidebar/block.json +43 -0
- package/registry/blocks/sidebar/demo.jsx +577 -0
- package/registry/blocks/sidebar/index.js +4 -0
- package/registry/blocks/sidebar/sidebar-panel.jsx +149 -0
- package/registry/blocks/sidebar/sidebar.jsx +864 -0
- package/registry/blocks/signature-pad/README.md +137 -0
- package/registry/blocks/signature-pad/block.json +13 -0
- package/registry/blocks/signature-pad/colors.js +115 -0
- package/registry/blocks/signature-pad/demo.jsx +94 -0
- package/registry/blocks/signature-pad/index.js +6 -0
- package/registry/blocks/signature-pad/pad.js +7 -0
- package/registry/blocks/signature-pad/signature-pad.jsx +434 -0
- package/registry/blocks/signature-pad/signature.js +68 -0
- package/registry/blocks/sketch-canvas/README.md +280 -0
- package/registry/blocks/sketch-canvas/block.json +13 -0
- package/registry/blocks/sketch-canvas/demo.jsx +159 -0
- package/registry/blocks/sketch-canvas/excalidraw.js +40 -0
- package/registry/blocks/sketch-canvas/index.js +9 -0
- package/registry/blocks/sketch-canvas/palette.js +226 -0
- package/registry/blocks/sketch-canvas/sketch-canvas.jsx +1188 -0
- package/registry/blocks/sketch-canvas/sketch.js +179 -0
- package/registry/blocks/sketch-canvas/ssr-shim-end.js +6 -0
- package/registry/blocks/sketch-canvas/ssr-shim.js +45 -0
- package/registry/blocks/sketch-canvas/stamps.js +104 -0
- package/registry/blocks/sketch-canvas/theme.js +131 -0
- package/registry/blocks/spreadsheet/README.md +307 -0
- package/registry/blocks/spreadsheet/block.json +13 -0
- package/registry/blocks/spreadsheet/cells.jsx +455 -0
- package/registry/blocks/spreadsheet/chrome.jsx +325 -0
- package/registry/blocks/spreadsheet/demo.jsx +177 -0
- package/registry/blocks/spreadsheet/grid.js +387 -0
- package/registry/blocks/spreadsheet/index.js +34 -0
- package/registry/blocks/spreadsheet/spreadsheet.jsx +1732 -0
- package/registry/blocks/spreadsheet/types.js +473 -0
- package/registry/blocks/stat-cards/README.md +173 -0
- package/registry/blocks/stat-cards/block.json +10 -0
- package/registry/blocks/stat-cards/demo.jsx +257 -0
- package/registry/blocks/stat-cards/index.js +4 -0
- package/registry/blocks/stat-cards/stat-cards.jsx +307 -0
- package/registry/blocks/stat-cards/usage.jsx +243 -0
- package/registry/blocks/task-list/README.md +176 -0
- package/registry/blocks/task-list/block.json +10 -0
- package/registry/blocks/task-list/demo.jsx +134 -0
- package/registry/blocks/task-list/index.js +5 -0
- package/registry/blocks/task-list/task-list.jsx +907 -0
- package/registry/blocks/task-model/README.md +455 -0
- package/registry/blocks/task-model/block.json +167 -0
- package/registry/blocks/task-model/changes.js +89 -0
- package/registry/blocks/task-model/dates.js +371 -0
- package/registry/blocks/task-model/demo.jsx +215 -0
- package/registry/blocks/task-model/dnd.jsx +240 -0
- package/registry/blocks/task-model/index.js +97 -0
- package/registry/blocks/task-model/model.js +919 -0
- package/registry/blocks/task-model/parts.jsx +449 -0
- package/registry/blocks/task-model/toolbar.jsx +271 -0
- package/registry/blocks/testimonials/README.md +139 -0
- package/registry/blocks/testimonials/block.json +11 -0
- package/registry/blocks/testimonials/demo.jsx +137 -0
- package/registry/blocks/testimonials/index.js +4 -0
- package/registry/blocks/testimonials/testimonials.jsx +430 -0
- package/registry/blocks/transaction-list/README.md +126 -0
- package/registry/blocks/transaction-list/block.json +10 -0
- package/registry/blocks/transaction-list/demo.jsx +79 -0
- package/registry/blocks/transaction-list/index.js +4 -0
- package/registry/blocks/transaction-list/transaction-list.jsx +383 -0
- package/registry/blocks/whiteboard/README.md +179 -0
- package/registry/blocks/whiteboard/block.json +10 -0
- package/registry/blocks/whiteboard/demo.jsx +169 -0
- package/registry/blocks/whiteboard/index.js +6 -0
- package/registry/blocks/whiteboard/templates.js +150 -0
- package/registry/blocks/whiteboard/whiteboard.jsx +721 -0
- package/src/cli.mjs +19 -6
- package/src/install.mjs +18 -0
- package/src/registry.mjs +38 -4
- package/src/shadcn.mjs +14 -1
- package/templates/next/files/README.md +145 -11
- package/templates/next/files/app/globals.css +55 -4
- package/templates/next/files/check/run.mjs +3 -3
- package/templates/next/files/components/ui/avatar.jsx +141 -0
- package/templates/next/files/components/ui/breadcrumb.jsx +149 -0
- package/templates/next/files/components/ui/button-group.jsx +70 -0
- package/templates/next/files/components/ui/button.jsx +132 -12
- package/templates/next/files/components/ui/calendar.jsx +609 -0
- package/templates/next/files/components/ui/carousel.jsx +281 -0
- package/templates/next/files/components/ui/collapsible.jsx +208 -0
- package/templates/next/files/components/ui/combobox.jsx +608 -0
- package/templates/next/files/components/ui/command.jsx +577 -0
- package/templates/next/files/components/ui/context-menu.jsx +191 -0
- package/templates/next/files/components/ui/date-picker.jsx +360 -0
- package/templates/next/files/components/ui/distribution.jsx +117 -0
- package/templates/next/files/components/ui/feedback.jsx +143 -0
- package/templates/next/files/components/ui/field.jsx +115 -3
- package/templates/next/files/components/ui/file-input.jsx +234 -0
- package/templates/next/files/components/ui/icon.jsx +130 -8
- package/templates/next/files/components/ui/image.jsx +143 -0
- package/templates/next/files/components/ui/index.js +47 -2
- package/templates/next/files/components/ui/input-group.jsx +213 -0
- package/templates/next/files/components/ui/input-otp.jsx +170 -0
- package/templates/next/files/components/ui/item.jsx +206 -0
- package/templates/next/files/components/ui/menu.jsx +454 -82
- package/templates/next/files/components/ui/notice.jsx +126 -14
- package/templates/next/files/components/ui/pagination.jsx +156 -0
- package/templates/next/files/components/ui/popover.jsx +284 -0
- package/templates/next/files/components/ui/radio.jsx +193 -0
- package/templates/next/files/components/ui/rating.jsx +131 -0
- package/templates/next/files/components/ui/resizable.jsx +338 -0
- package/templates/next/files/components/ui/scroll-area.jsx +123 -0
- package/templates/next/files/components/ui/separator.jsx +119 -0
- package/templates/next/files/components/ui/sheet.jsx +96 -11
- package/templates/next/files/components/ui/slider.jsx +174 -0
- package/templates/next/files/components/ui/stat.jsx +574 -0
- package/templates/next/files/components/ui/steps.jsx +338 -0
- package/templates/next/files/components/ui/swatch.jsx +33 -0
- package/templates/next/files/components/ui/table.jsx +130 -0
- package/templates/next/files/components/ui/toast.jsx +440 -0
- package/templates/next/files/components/ui/toggle.jsx +195 -0
- package/templates/next/files/components/ui/tooltip.jsx +270 -0
- 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
|
-
|
|
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
|
-
|
|
46
|
-
|
|
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
|
+
}
|