makersclaw 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/install.mjs +18 -0
- package/src/shadcn.mjs +8 -0
- 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,109 @@
|
|
|
1
|
+
// The waveform's colours are the workspace's tokens.
|
|
2
|
+
//
|
|
3
|
+
// wavesurfer.js paints a <canvas>, and a canvas needs a concrete colour —
|
|
4
|
+
// it cannot read var(--color-primary). So the colours are read from the
|
|
5
|
+
// CSS variables in effect where the player sits, at run time, and read
|
|
6
|
+
// again when the theme or the scheme changes (the player watches for
|
|
7
|
+
// that). No colour value is written in this file: every one comes from
|
|
8
|
+
// the page. Same method as sketch-canvas's palette.js.
|
|
9
|
+
//
|
|
10
|
+
// Everything but readTokens() is a plain function, so it runs in node.
|
|
11
|
+
|
|
12
|
+
const byte = (n) => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, "0");
|
|
13
|
+
|
|
14
|
+
/** [r, g, b, a(0-255)] → "#rrggbb", or "#rrggbbaa" when not opaque. */
|
|
15
|
+
export function toHex([r, g, b, a = 255]) {
|
|
16
|
+
return "#" + byte(r) + byte(g) + byte(b) + (a >= 255 ? "" : byte(a));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** The same colour at `alpha` (0-1) of its own opacity. */
|
|
20
|
+
export function withAlpha(rgba, alpha) {
|
|
21
|
+
if (!rgba) return null;
|
|
22
|
+
const [r, g, b, a = 255] = rgba;
|
|
23
|
+
return toHex([r, g, b, a * Math.max(0, Math.min(1, alpha))]);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** The waveform's colours from the slots read off the page. */
|
|
27
|
+
export function waveColours(slots) {
|
|
28
|
+
const fg = slots?.foreground;
|
|
29
|
+
const muted = slots?.["muted-foreground"] ?? fg;
|
|
30
|
+
const primary = slots?.primary ?? fg;
|
|
31
|
+
return {
|
|
32
|
+
waveColor: withAlpha(muted, 0.55),
|
|
33
|
+
progressColor: primary ? toHex(primary) : null,
|
|
34
|
+
cursorColor: primary ? toHex(primary) : null,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ---- the browser half -------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
/** Read `slots` (token names: "primary", "muted-foreground"…) from the CSS
|
|
41
|
+
* variables in effect at `root`, as [r, g, b, a] bytes. A probe takes
|
|
42
|
+
* `color: var(--color-<slot>)`; the browser resolves var(), color-mix()
|
|
43
|
+
* and light-dark() into its computed colour, and a 1×1 canvas turns that
|
|
44
|
+
* into bytes whatever syntax it came back in. */
|
|
45
|
+
export function readTokens(root, slots) {
|
|
46
|
+
const out = {};
|
|
47
|
+
if (typeof document === "undefined" || !root) return out;
|
|
48
|
+
const probe = document.createElement("span");
|
|
49
|
+
probe.setAttribute("aria-hidden", "true");
|
|
50
|
+
probe.style.position = "absolute";
|
|
51
|
+
probe.style.visibility = "hidden";
|
|
52
|
+
probe.style.pointerEvents = "none";
|
|
53
|
+
root.appendChild(probe);
|
|
54
|
+
const canvas = document.createElement("canvas");
|
|
55
|
+
canvas.width = 1;
|
|
56
|
+
canvas.height = 1;
|
|
57
|
+
const ctx = canvas.getContext("2d", { willReadFrequently: true });
|
|
58
|
+
try {
|
|
59
|
+
for (const slot of slots) {
|
|
60
|
+
probe.style.color = "";
|
|
61
|
+
probe.style.color = `var(--color-${slot})`;
|
|
62
|
+
const computed = getComputedStyle(probe).color;
|
|
63
|
+
if (!computed || !ctx) continue;
|
|
64
|
+
ctx.clearRect(0, 0, 1, 1);
|
|
65
|
+
ctx.fillStyle = "transparent";
|
|
66
|
+
ctx.fillStyle = computed;
|
|
67
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
68
|
+
const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data;
|
|
69
|
+
if (a === 0) continue;
|
|
70
|
+
out[slot] = [r, g, b, a];
|
|
71
|
+
}
|
|
72
|
+
} finally {
|
|
73
|
+
probe.remove();
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Call `fn` (soon, once) whenever something that sets the tokens may have
|
|
79
|
+
* changed: a data-theme / class / style on <html> or the nearest themed
|
|
80
|
+
* ancestor, a stylesheet added to <head>, the OS scheme. Returns the
|
|
81
|
+
* cleanup. */
|
|
82
|
+
export function watchTheme(root, fn) {
|
|
83
|
+
if (typeof document === "undefined") return () => {};
|
|
84
|
+
let t = 0;
|
|
85
|
+
const soon = () => {
|
|
86
|
+
clearTimeout(t);
|
|
87
|
+
t = setTimeout(fn, 30);
|
|
88
|
+
};
|
|
89
|
+
const obs = new MutationObserver((records) => {
|
|
90
|
+
for (const r of records) for (const n of r.addedNodes ?? []) if (n.tagName === "LINK") n.addEventListener("load", soon, { once: true });
|
|
91
|
+
soon();
|
|
92
|
+
});
|
|
93
|
+
const attrs = { attributes: true, attributeFilter: ["data-theme", "class", "style"] };
|
|
94
|
+
obs.observe(document.documentElement, attrs);
|
|
95
|
+
obs.observe(document.head, { childList: true });
|
|
96
|
+
const scoped = root?.closest?.("[data-theme]");
|
|
97
|
+
if (scoped && scoped !== document.documentElement) {
|
|
98
|
+
obs.observe(scoped, attrs);
|
|
99
|
+
obs.observe(scoped, { childList: true });
|
|
100
|
+
}
|
|
101
|
+
const mq = typeof matchMedia !== "undefined" ? matchMedia("(prefers-color-scheme: dark)") : null;
|
|
102
|
+
mq?.addEventListener("change", soon);
|
|
103
|
+
soon();
|
|
104
|
+
return () => {
|
|
105
|
+
clearTimeout(t);
|
|
106
|
+
obs.disconnect();
|
|
107
|
+
mq?.removeEventListener("change", soon);
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// AudioPlayer three ways — the gallery's and the smoke test's surface. Not
|
|
4
|
+
// installed into apps.
|
|
5
|
+
// Call a short sales call with topics (regions) and moments
|
|
6
|
+
// (markers); add a marker, drag to mark a clip (a switch makes
|
|
7
|
+
// the saves fail); beside it, the topic playing now and the
|
|
8
|
+
// moments as a list that jumps through the handle.
|
|
9
|
+
// Voice note the player bare: no title, no regions, one line.
|
|
10
|
+
// States nothing to play yet, and a file that will not decode.
|
|
11
|
+
//
|
|
12
|
+
// The audio is made here, in memory: a 45-second WAV synthesised from two
|
|
13
|
+
// "voices" (harmonic tones in syllable-shaped bursts, one lower, one
|
|
14
|
+
// higher, taking turns) at 8 kHz. No file ships with the demo.
|
|
15
|
+
import { useCallback, useMemo, useState } from "react";
|
|
16
|
+
import { Badge, Button, Switch, TabPanel, Tabs } from "../components/ui";
|
|
17
|
+
import { AudioPlayer, formatTime, useAudioPlayer } from "../components/blocks/audio-player";
|
|
18
|
+
|
|
19
|
+
// Who speaks when, in seconds: [start, end, voice]. Voice 0 is lower.
|
|
20
|
+
const TURNS = [
|
|
21
|
+
[0.4, 6.4, 0],
|
|
22
|
+
[7.0, 11.8, 1],
|
|
23
|
+
[12.6, 15.0, 0],
|
|
24
|
+
[15.6, 25.4, 1],
|
|
25
|
+
[26.0, 32.8, 0],
|
|
26
|
+
[33.5, 37.0, 1],
|
|
27
|
+
[37.6, 44.2, 0],
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
/** A mono 16-bit PCM WAV of two voices taking turns, as an ArrayBuffer. */
|
|
31
|
+
function synthCall(seconds = 45, rate = 8000) {
|
|
32
|
+
const n = Math.round(seconds * rate);
|
|
33
|
+
const out = new Float32Array(n);
|
|
34
|
+
let seed = 7;
|
|
35
|
+
const rnd = () => (seed = (seed * 16807) % 2147483647) / 2147483647;
|
|
36
|
+
for (const [start, end, voice] of TURNS) {
|
|
37
|
+
const base = voice ? 205 : 132;
|
|
38
|
+
let t = start;
|
|
39
|
+
while (t < end) {
|
|
40
|
+
const len = 0.11 + rnd() * 0.17;
|
|
41
|
+
const amp = 0.22 + rnd() * 0.38;
|
|
42
|
+
const pitch = base * (0.92 + rnd() * 0.16);
|
|
43
|
+
const s0 = Math.round(t * rate);
|
|
44
|
+
const s1 = Math.min(n, Math.round(Math.min(t + len, end) * rate));
|
|
45
|
+
let phase = 0;
|
|
46
|
+
for (let i = s0; i < s1; i++) {
|
|
47
|
+
const x = (i - s0) / (s1 - s0);
|
|
48
|
+
const env = Math.pow(Math.sin(Math.PI * x), 0.8);
|
|
49
|
+
const f = pitch * (1 + 0.05 * Math.sin(2 * Math.PI * 4 * (i / rate)));
|
|
50
|
+
phase += (2 * Math.PI * f) / rate;
|
|
51
|
+
let v = 0;
|
|
52
|
+
for (let h = 1; h <= 5; h++) v += Math.sin(h * phase) / h;
|
|
53
|
+
out[i] += amp * env * v * 0.45;
|
|
54
|
+
}
|
|
55
|
+
t += len + (rnd() < 0.18 ? 0.22 + rnd() * 0.2 : 0.03 + rnd() * 0.08);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const buf = new ArrayBuffer(44 + n * 2);
|
|
59
|
+
const v = new DataView(buf);
|
|
60
|
+
const str = (o, s) => [...s].forEach((c, i) => v.setUint8(o + i, c.charCodeAt(0)));
|
|
61
|
+
str(0, "RIFF");
|
|
62
|
+
v.setUint32(4, 36 + n * 2, true);
|
|
63
|
+
str(8, "WAVE");
|
|
64
|
+
str(12, "fmt ");
|
|
65
|
+
v.setUint32(16, 16, true);
|
|
66
|
+
v.setUint16(20, 1, true); // PCM
|
|
67
|
+
v.setUint16(22, 1, true); // mono
|
|
68
|
+
v.setUint32(24, rate, true);
|
|
69
|
+
v.setUint32(28, rate * 2, true);
|
|
70
|
+
v.setUint16(32, 2, true);
|
|
71
|
+
v.setUint16(34, 16, true);
|
|
72
|
+
str(36, "data");
|
|
73
|
+
v.setUint32(40, n * 2, true);
|
|
74
|
+
for (let i = 0; i < n; i++) {
|
|
75
|
+
const s = Math.max(-1, Math.min(1, out[i] + (rnd() - 0.5) * 0.01));
|
|
76
|
+
v.setInt16(44 + i * 2, s * 32767, true);
|
|
77
|
+
}
|
|
78
|
+
return buf;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const TOPICS = [
|
|
82
|
+
{ id: "intro", start: 0, end: 12.2, label: "Introductions", tone: "chart-2" },
|
|
83
|
+
{ id: "pricing", start: 12.4, end: 25.6, label: "Pricing and SSO", tone: "chart-3" },
|
|
84
|
+
{ id: "security", start: 25.8, end: 33.2, label: "Security review", tone: "chart-5" },
|
|
85
|
+
{ id: "next", start: 33.4, end: 44.5, label: "Next steps", tone: "chart-4" },
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
const MOMENTS = [
|
|
89
|
+
{ id: "m1", time: 17.2, label: "Asked whether SSO is on every plan", tone: "warning" },
|
|
90
|
+
{ id: "m2", time: 23.8, label: "Budget confirmed: 40 seats", tone: "success" },
|
|
91
|
+
{ id: "m3", time: 40.5, label: "Send the security questionnaire", tone: "primary" },
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
95
|
+
|
|
96
|
+
function CallDemo({ audio }) {
|
|
97
|
+
const player = useAudioPlayer();
|
|
98
|
+
const [markers, setMarkers] = useState(MOMENTS);
|
|
99
|
+
const [regions, setRegions] = useState(TOPICS);
|
|
100
|
+
const [now, setNow] = useState(null);
|
|
101
|
+
const [fail, setFail] = useState(false);
|
|
102
|
+
|
|
103
|
+
// Optimistic in the parent too: add, save, take back if the save fails.
|
|
104
|
+
const addMarker = useCallback(
|
|
105
|
+
async ({ time }) => {
|
|
106
|
+
await wait(500);
|
|
107
|
+
if (fail) return { ok: false, error: "The server didn't answer." };
|
|
108
|
+
setMarkers((m) => [...m, { id: `m-${Date.now()}`, time, label: `Note at ${formatTime(time)}`, tone: "primary" }]);
|
|
109
|
+
return { ok: true };
|
|
110
|
+
},
|
|
111
|
+
[fail],
|
|
112
|
+
);
|
|
113
|
+
const addClip = useCallback(
|
|
114
|
+
async ({ start, end }) => {
|
|
115
|
+
await wait(500);
|
|
116
|
+
if (fail) return { ok: false, error: "The server didn't answer." };
|
|
117
|
+
setRegions((r) => [...r, { id: `c-${Date.now()}`, start, end, label: "Clip", tone: "primary" }]);
|
|
118
|
+
return { ok: true };
|
|
119
|
+
},
|
|
120
|
+
[fail],
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<div className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_16rem]">
|
|
125
|
+
<AudioPlayer
|
|
126
|
+
src={audio}
|
|
127
|
+
title="Discovery call · Northwind Logistics"
|
|
128
|
+
description="Maya Chen and Leo Park · Sep 18"
|
|
129
|
+
regions={regions}
|
|
130
|
+
markers={markers}
|
|
131
|
+
onAddMarker={addMarker}
|
|
132
|
+
onRegionCreate={addClip}
|
|
133
|
+
onActiveRegionChange={setNow}
|
|
134
|
+
playerRef={player}
|
|
135
|
+
/>
|
|
136
|
+
<div className="grid min-w-0 content-start gap-4 rounded-lg border border-border bg-card p-4">
|
|
137
|
+
<div>
|
|
138
|
+
<p className="text-xs text-muted-foreground">Playing now</p>
|
|
139
|
+
<p className="mt-1 truncate text-sm font-medium">{now ? now.label : "Between topics"}</p>
|
|
140
|
+
</div>
|
|
141
|
+
<div>
|
|
142
|
+
<p className="text-xs text-muted-foreground">Moments</p>
|
|
143
|
+
<ul className="mt-1 grid gap-0.5">
|
|
144
|
+
{[...markers]
|
|
145
|
+
.sort((a, b) => a.time - b.time)
|
|
146
|
+
.map((m) => (
|
|
147
|
+
<li key={m.id} className="min-w-0">
|
|
148
|
+
<Button variant="nav" size="sm" className="w-full min-w-0" onClick={() => player.current?.seek(m.time)}>
|
|
149
|
+
<span className="w-9 shrink-0 text-xs text-muted-foreground tabular-nums">{formatTime(m.time)}</span>
|
|
150
|
+
<span className="min-w-0 truncate">{m.label}</span>
|
|
151
|
+
</Button>
|
|
152
|
+
</li>
|
|
153
|
+
))}
|
|
154
|
+
</ul>
|
|
155
|
+
</div>
|
|
156
|
+
<Switch id="audio-fail" checked={fail} onChange={(e) => setFail(e.target.checked)} label="Make saves fail" />
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export default function AudioPlayerDemo() {
|
|
163
|
+
const [tab, setTab] = useState("call");
|
|
164
|
+
// One recording for the whole page, made once (on the server too: the
|
|
165
|
+
// player renders its skeleton until the browser has decoded it).
|
|
166
|
+
const audio = useMemo(() => new Blob([synthCall()], { type: "audio/wav" }), []);
|
|
167
|
+
|
|
168
|
+
return (
|
|
169
|
+
<div>
|
|
170
|
+
<Tabs
|
|
171
|
+
id="audio-demo"
|
|
172
|
+
value={tab}
|
|
173
|
+
onChange={setTab}
|
|
174
|
+
tabs={[
|
|
175
|
+
{ key: "call", label: "Call" },
|
|
176
|
+
{ key: "note", label: "Voice note" },
|
|
177
|
+
{ key: "states", label: "States" },
|
|
178
|
+
]}
|
|
179
|
+
/>
|
|
180
|
+
<TabPanel id="audio-demo" tab="call" value={tab}>
|
|
181
|
+
<CallDemo audio={audio} />
|
|
182
|
+
</TabPanel>
|
|
183
|
+
<TabPanel id="audio-demo" tab="note" value={tab}>
|
|
184
|
+
<div className="max-w-xl">
|
|
185
|
+
<div className="mb-2 flex items-center gap-2">
|
|
186
|
+
<p className="text-sm font-medium">Voicemail from Priya Raman</p>
|
|
187
|
+
<Badge variant="soft" tone="info">
|
|
188
|
+
New
|
|
189
|
+
</Badge>
|
|
190
|
+
</div>
|
|
191
|
+
<AudioPlayer src={audio} rates={[1, 1.5, 2]} defaultRate={1.5} />
|
|
192
|
+
</div>
|
|
193
|
+
</TabPanel>
|
|
194
|
+
<TabPanel id="audio-demo" tab="states" value={tab}>
|
|
195
|
+
<div className="grid gap-4 lg:grid-cols-2">
|
|
196
|
+
<AudioPlayer
|
|
197
|
+
title="Onboarding call · Halden & Co"
|
|
198
|
+
emptyAction={
|
|
199
|
+
<Button size="sm" variant="secondary" icon="upload">
|
|
200
|
+
Upload a recording
|
|
201
|
+
</Button>
|
|
202
|
+
}
|
|
203
|
+
/>
|
|
204
|
+
<AudioPlayer src="data:audio/wav;base64,AAAAAAAA" title="Renewal call · Brightline" description="Sep 12" />
|
|
205
|
+
</div>
|
|
206
|
+
</TabPanel>
|
|
207
|
+
</div>
|
|
208
|
+
);
|
|
209
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// The AudioPlayer block — `makersclaw add audio-player`. Fixed: compose it
|
|
2
|
+
// through its props (README.md beside this file). The blocks built on this
|
|
3
|
+
// one (call-review…) import it, never wavesurfer.js directly. The time
|
|
4
|
+
// helpers are plain functions and work on the server.
|
|
5
|
+
export { AudioPlayer, useAudioPlayer } from "./audio-player";
|
|
6
|
+
export { formatTime, formatRange, spokenTime, regionAt, TONES, RATES } from "./time";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Plain helpers for the player: time labels, where a moment falls, the
|
|
2
|
+
// tones a region or a marker can wear. No DOM, so they run anywhere (a
|
|
3
|
+
// server surface formatting a timestamp, a transcript lining up with the
|
|
4
|
+
// audio).
|
|
5
|
+
|
|
6
|
+
/** Seconds → "0:07", "12:03", "1:02:09". Negative and NaN read as 0. */
|
|
7
|
+
export function formatTime(seconds) {
|
|
8
|
+
const s = Number.isFinite(seconds) && seconds > 0 ? Math.floor(seconds) : 0;
|
|
9
|
+
const h = Math.floor(s / 3600);
|
|
10
|
+
const m = Math.floor((s % 3600) / 60);
|
|
11
|
+
const r = String(s % 60).padStart(2, "0");
|
|
12
|
+
return h ? `${h}:${String(m).padStart(2, "0")}:${r}` : `${m}:${r}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** "0:14–0:26" */
|
|
16
|
+
export const formatRange = (start, end) => `${formatTime(start)}–${formatTime(end)}`;
|
|
17
|
+
|
|
18
|
+
/** "1 minute 24 seconds" — what a screen reader says for a time. */
|
|
19
|
+
export function spokenTime(seconds) {
|
|
20
|
+
const s = Number.isFinite(seconds) && seconds > 0 ? Math.floor(seconds) : 0;
|
|
21
|
+
const h = Math.floor(s / 3600);
|
|
22
|
+
const m = Math.floor((s % 3600) / 60);
|
|
23
|
+
const r = s % 60;
|
|
24
|
+
const part = (n, w) => (n ? `${n} ${w}${n === 1 ? "" : "s"}` : "");
|
|
25
|
+
return [part(h, "hour"), part(m, "minute"), part(r, "second")].filter(Boolean).join(" ") || "0 seconds";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));
|
|
29
|
+
|
|
30
|
+
/** The region playing at `time`: the one that started last among those
|
|
31
|
+
* that hold it (so a short region inside a long one wins). Null if none. */
|
|
32
|
+
export function regionAt(regions, time) {
|
|
33
|
+
let hit = null;
|
|
34
|
+
for (const r of regions ?? []) {
|
|
35
|
+
if (!(time >= r.start && time < r.end)) continue;
|
|
36
|
+
if (!hit || r.start >= hit.start) hit = r;
|
|
37
|
+
}
|
|
38
|
+
return hit;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Regions and markers as given, cleaned: numbers, end after start,
|
|
42
|
+
* inside the audio when its length is known, sorted by time. */
|
|
43
|
+
export function cleanRegions(regions, duration) {
|
|
44
|
+
const max = duration > 0 ? duration : Infinity;
|
|
45
|
+
return (regions ?? [])
|
|
46
|
+
.filter((r) => r && Number.isFinite(+r.start) && Number.isFinite(+r.end))
|
|
47
|
+
.map((r) => ({ ...r, start: clamp(+r.start, 0, max), end: clamp(+r.end, 0, max) }))
|
|
48
|
+
.filter((r) => r.end > r.start)
|
|
49
|
+
.sort((a, b) => a.start - b.start);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function cleanMarkers(markers, duration) {
|
|
53
|
+
const max = duration > 0 ? duration : Infinity;
|
|
54
|
+
return (markers ?? [])
|
|
55
|
+
.filter((m) => m && Number.isFinite(+m.time))
|
|
56
|
+
.map((m) => ({ ...m, time: clamp(+m.time, 0, max) }))
|
|
57
|
+
.sort((a, b) => a.time - b.time);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The tones a region or a marker can wear: theme tokens, never colours. */
|
|
61
|
+
export const TONES = ["primary", "chart-2", "chart-3", "chart-4", "chart-5", "success", "warning", "info", "destructive", "muted"];
|
|
62
|
+
|
|
63
|
+
/** The default playback speeds. */
|
|
64
|
+
export const RATES = [0.75, 1, 1.25, 1.5, 2];
|
|
65
|
+
|
|
66
|
+
/** "1.25×" */
|
|
67
|
+
export const formatRate = (r) => `${r}×`;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// The one door to wavesurfer.js (BSD-3-Clause) and its React hook
|
|
2
|
+
// (@wavesurfer/react, BSD-3-Clause). Every file in this block reaches the
|
|
3
|
+
// library through here, and the blocks built on this one (call-review…)
|
|
4
|
+
// reach it through AudioPlayer — never the packages directly.
|
|
5
|
+
//
|
|
6
|
+
// No shim is needed: both packages load on the server without touching
|
|
7
|
+
// `window` (checked in node); the instance is only created in an effect,
|
|
8
|
+
// so nothing runs until the browser.
|
|
9
|
+
export { useWavesurfer } from "@wavesurfer/react";
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# AuthForm
|
|
2
|
+
|
|
3
|
+
The screens around an account, as one form: sign in, sign up, a magic
|
|
4
|
+
link, a password-reset link, and changing a password. It draws the
|
|
5
|
+
fields, provider buttons, links and states, and holds what is typed. The
|
|
6
|
+
auth is yours: each submit goes out through an async callback that
|
|
7
|
+
returns `{ ok: true }` or `{ ok: false, error }`, and the form shows the
|
|
8
|
+
error under the fields. It never signs anyone in by itself.
|
|
9
|
+
|
|
10
|
+
```jsx
|
|
11
|
+
import { AuthForm } from "../components/blocks/auth-form"; // a Makersclaw app ("./blocks/auth-form" from components/)
|
|
12
|
+
import { AuthForm } from "@/components/makersclaw/blocks/auth-form"; // a shadcn project
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
A client component: render it from a `"use client"` component.
|
|
16
|
+
|
|
17
|
+
## Modes
|
|
18
|
+
|
|
19
|
+
- `sign-in` — email and password (or email only with `password={false}`),
|
|
20
|
+
"Forgot password?" beside the password label when `links.reset` is set,
|
|
21
|
+
optional "Remember me".
|
|
22
|
+
- `sign-up` — your `fields` (default: full name), email, password and a
|
|
23
|
+
confirm, optional news and terms checkboxes, optional password `rules`.
|
|
24
|
+
- `magic-link` — email only. After `{ ok: true }` it shows "Check your
|
|
25
|
+
email" with the address, and "Use a different email".
|
|
26
|
+
- `reset` — email only; the same "Check your email" screen after it
|
|
27
|
+
sends. It never says whether the account exists.
|
|
28
|
+
- `change-password` — current, new and confirm, with the rules as a live
|
|
29
|
+
checklist beside them (under them on a phone). On `{ ok: true }` the
|
|
30
|
+
fields clear and a success line shows.
|
|
31
|
+
|
|
32
|
+
## Props
|
|
33
|
+
|
|
34
|
+
- `mode` — one of the modes above. Default `"sign-in"`.
|
|
35
|
+
- `onSubmit(values, mode)` — async; return `{ ok: true }` or
|
|
36
|
+
`{ ok: false, error }` (a throw counts as failed, its message shown).
|
|
37
|
+
`values` holds only what this mode asks: `email`, `password`,
|
|
38
|
+
`remember`, each of your `fields` by `name`, `newsletter`, `terms`,
|
|
39
|
+
`currentPassword`, `newPassword`. The form is busy (spinner, fields
|
|
40
|
+
off) until it answers.
|
|
41
|
+
- `providers` — buttons for other ways in: `"google"`, `"github"`,
|
|
42
|
+
`"apple"`, `"microsoft"`, `"sso"`, or `{ id, label, icon }` for another
|
|
43
|
+
one (`icon` a kit Icon name). Default none.
|
|
44
|
+
- `onProvider(id)` — async, same `{ ok, error }` answer. Start your OAuth
|
|
45
|
+
redirect here.
|
|
46
|
+
- `providersFirst` — the buttons above the form ("or with email" under
|
|
47
|
+
them) instead of under it. Two of them sit side by side from 640px.
|
|
48
|
+
- `password` — `false`: sign in by email only. Default `true`.
|
|
49
|
+
- `remember` — `true` ("Remember me") or your label ("Remember me for 30
|
|
50
|
+
days"). Sign in only. Default off.
|
|
51
|
+
- `fields` — sign up's extra fields, before the email:
|
|
52
|
+
`[{ name, label, type?, options?, placeholder?, autoComplete?, required?, hint?, half? }]`.
|
|
53
|
+
`type` is an input type or `"select"` (with `options: [{ value, label }]`);
|
|
54
|
+
`half` puts two side by side from 640px. Default one field, `name`
|
|
55
|
+
("Full name").
|
|
56
|
+
- `confirm` — ask for the new password twice. Default `true`.
|
|
57
|
+
- `rules` — what a new password must meet: `[{ label, test(value) }]`.
|
|
58
|
+
Default: none on sign up, `PASSWORD_RULES` on change password (8
|
|
59
|
+
characters, upper, lower, a number, a symbol). `false` turns them off.
|
|
60
|
+
Submit is held, with a message, until each one passes.
|
|
61
|
+
- `requireCurrent` — change password asks for the current one. Default
|
|
62
|
+
`true`; `false` for the page a reset link opens.
|
|
63
|
+
- `acceptTerms` — sign up needs a ticked "I agree to the Terms of
|
|
64
|
+
Service and Privacy Policy" box. Default off.
|
|
65
|
+
- `newsletter` — sign up shows an opt-in box: `true`, or your label.
|
|
66
|
+
- `links` — where the small links go, each an href or a function
|
|
67
|
+
(switch screens in place): `"sign-in"`, `"sign-up"`, `reset`,
|
|
68
|
+
`"magic-link"`, `terms`, `privacy`. A link shows only when it is given.
|
|
69
|
+
With `terms` or `privacy` and no `acceptTerms`, a "By continuing…" line
|
|
70
|
+
sits at the foot.
|
|
71
|
+
- `onCancel` — change password gets a Cancel button.
|
|
72
|
+
- `logo` — a node above the title (your mark).
|
|
73
|
+
- `title`, `description` — override the mode's words. `description={null}`
|
|
74
|
+
drops the line.
|
|
75
|
+
- `submitLabel` — the main button's words.
|
|
76
|
+
- `layout` — `card` (default, a 384px card) · `plain` (no card: your own
|
|
77
|
+
column) · `page` (the card centred in the window, for a route of its
|
|
78
|
+
own). Change password with rules is 768px wide.
|
|
79
|
+
- `defaultEmail` — prefill the email.
|
|
80
|
+
- `tips` — change password: short lines under the rules ("Use a password
|
|
81
|
+
manager").
|
|
82
|
+
- `className` — on the outer box.
|
|
83
|
+
|
|
84
|
+
`PASSWORD_RULES` is exported too, to extend: `rules={[...PASSWORD_RULES, { label: "Not your email", test: (v) => !v.includes("@") }]}`.
|
|
85
|
+
|
|
86
|
+
## Example
|
|
87
|
+
|
|
88
|
+
```jsx
|
|
89
|
+
"use client";
|
|
90
|
+
import { useRouter } from "next/navigation";
|
|
91
|
+
import { AuthForm } from "../components/blocks/auth-form";
|
|
92
|
+
|
|
93
|
+
export function SignIn({ signIn, startOAuth }) {
|
|
94
|
+
const router = useRouter();
|
|
95
|
+
return (
|
|
96
|
+
<AuthForm
|
|
97
|
+
mode="sign-in"
|
|
98
|
+
layout="page"
|
|
99
|
+
providers={["google", "github"]}
|
|
100
|
+
providersFirst
|
|
101
|
+
remember
|
|
102
|
+
links={{ "sign-up": "/sign-up", reset: "/reset", terms: "/terms", privacy: "/privacy" }}
|
|
103
|
+
onSubmit={async ({ email, password, remember }) => {
|
|
104
|
+
const r = await signIn(email, password, remember); // your server action
|
|
105
|
+
if (r.ok) router.push("/");
|
|
106
|
+
return r; // { ok: false, error: "Wrong email or password." } shows under the form
|
|
107
|
+
}}
|
|
108
|
+
onProvider={(id) => startOAuth(id)}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## What it will not do
|
|
115
|
+
|
|
116
|
+
- Authenticate. No session, no token, no OAuth: those are the callbacks'.
|
|
117
|
+
- Rate-limit, add a CAPTCHA or hide whether an email is registered — the
|
|
118
|
+
server does that (reset already says "if an account exists").
|
|
119
|
+
- Send the email. `magic-link` and `reset` only show that it went.
|
|
120
|
+
- Two-step codes: put the kit's `InputOTP` on the next screen.
|
|
121
|
+
- Draw a colourful brand logo: provider marks are the kit's one-colour
|
|
122
|
+
icons, in the text colour.
|
|
123
|
+
|
|
124
|
+
## Credits
|
|
125
|
+
|
|
126
|
+
Ported from blocks.so (https://blocks.so, login 01–09, MIT) and Creative Tim UI (https://github.com/creativetimofficial/ui, account-change-password-01, MIT), rewritten on the Makersclaw kit.
|