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,37 @@
|
|
|
1
|
+
// The one door to react-pdf (MIT) and pdf.js (pdfjs-dist, Apache-2.0).
|
|
2
|
+
// Every file in this block reaches them through here, and the blocks built
|
|
3
|
+
// on this one reach them through PdfViewer — never the packages directly.
|
|
4
|
+
//
|
|
5
|
+
// The order of the imports is the point: the text and annotation layers'
|
|
6
|
+
// stylesheets, then ssr-shim.js (stand-ins for the browser globals pdf.js
|
|
7
|
+
// reads while it loads — only on the server, where they are missing),
|
|
8
|
+
// react-pdf, then ssr-shim-end.js, which takes them away again. Keep them
|
|
9
|
+
// together and in this order.
|
|
10
|
+
//
|
|
11
|
+
// THE WORKER. pdf.js parses PDFs in a Web Worker, and must be told the
|
|
12
|
+
// worker script's URL. The usual answers are a file copied into public/
|
|
13
|
+
// (a file the app has to own and keep in step with the package) or a CDN
|
|
14
|
+
// (a runtime fetch from someone else's server, blocked by a strict CSP).
|
|
15
|
+
// Neither: `new URL("pdfjs-dist/build/pdf.worker.min.mjs", import.meta.url)`
|
|
16
|
+
// is a pattern the bundler (webpack in Next, and Turbopack, Vite, Parcel
|
|
17
|
+
// alike) recognises at BUILD time: it resolves the package's worker file,
|
|
18
|
+
// emits it as a hashed asset under /_next/static/media/, and replaces the
|
|
19
|
+
// expression with that asset's URL (the app's base path included). So the
|
|
20
|
+
// worker ships with the app, is always the same version as the pdf.js that
|
|
21
|
+
// calls it, and is served from the app's own origin. No import(), so the
|
|
22
|
+
// app's one-static-bundle check is happy.
|
|
23
|
+
//
|
|
24
|
+
// It is set here, after react-pdf has loaded, because react-pdf sets its
|
|
25
|
+
// own default when it loads and the later assignment must win. Only in the
|
|
26
|
+
// browser: the server never parses a PDF.
|
|
27
|
+
import "react-pdf/dist/Page/TextLayer.css";
|
|
28
|
+
import "react-pdf/dist/Page/AnnotationLayer.css";
|
|
29
|
+
import "./ssr-shim";
|
|
30
|
+
import { Document, Page, pdfjs } from "react-pdf";
|
|
31
|
+
import "./ssr-shim-end";
|
|
32
|
+
|
|
33
|
+
if (typeof window !== "undefined") {
|
|
34
|
+
pdfjs.GlobalWorkerOptions.workerSrc = new URL("pdfjs-dist/build/pdf.worker.min.mjs", import.meta.url).toString();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { Document, Page, pdfjs };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Server only: stand-ins for the few browser globals pdf.js's viewer
|
|
2
|
+
// module reads WHILE IT LOADS. See pdfjs.js for why this exists.
|
|
3
|
+
//
|
|
4
|
+
// react-pdf imports pdfjs-dist/web/pdf_viewer.mjs (for its link service),
|
|
5
|
+
// and that module runs browser code at the top level:
|
|
6
|
+
// window.requestAnimationFrame, document.documentElement.style,
|
|
7
|
+
// document.createElement("div") (a CSS feature probe), and react-pdf reads
|
|
8
|
+
// window.location. On the server those throw "window is not defined" and
|
|
9
|
+
// the page fails to render — though the viewer itself only ever renders in
|
|
10
|
+
// the browser (the mount guard). The app is one static bundle (no
|
|
11
|
+
// import(), no next/dynamic), so the module cannot be kept off the server;
|
|
12
|
+
// it is let load against these stand-ins instead — the same trick as
|
|
13
|
+
// sketch-canvas's ssr-shim.js.
|
|
14
|
+
//
|
|
15
|
+
// They live only for that load: pdfjs.js imports this file, then
|
|
16
|
+
// react-pdf, then ssr-shim-end.js, which removes them — module evaluation
|
|
17
|
+
// is synchronous, so no other code runs in between. If the load throws,
|
|
18
|
+
// the microtask below removes them anyway, so a global `window` never
|
|
19
|
+
// outlives it. In the browser `window` exists and this file does nothing.
|
|
20
|
+
const G = globalThis;
|
|
21
|
+
const SET = [];
|
|
22
|
+
|
|
23
|
+
function stand(name, value) {
|
|
24
|
+
if (typeof G[name] !== "undefined") return;
|
|
25
|
+
G[name] = value;
|
|
26
|
+
SET.push(name);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof window === "undefined") {
|
|
30
|
+
const element = () => ({ style: {}, dataset: {}, classList: { add() {}, remove() {}, toggle() {} }, setAttribute() {}, appendChild() {} });
|
|
31
|
+
stand("window", { location: { protocol: "", href: "", origin: "" }, devicePixelRatio: 1, requestAnimationFrame: () => 0 });
|
|
32
|
+
stand("document", { createElement: element, documentElement: element(), head: element(), body: element() });
|
|
33
|
+
G.__pdfViewerShim = SET;
|
|
34
|
+
queueMicrotask(() => {
|
|
35
|
+
if (G.__pdfViewerShim === SET) removeShim();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function removeShim() {
|
|
40
|
+
const set = G.__pdfViewerShim;
|
|
41
|
+
if (!set) return;
|
|
42
|
+
for (const name of set) delete G[name];
|
|
43
|
+
delete G.__pdfViewerShim;
|
|
44
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Product detail
|
|
2
|
+
|
|
3
|
+
One product on its own page: its pictures, name, price, rating, the
|
|
4
|
+
options a customer picks (size, colour, plan), how many, and **Add to
|
|
5
|
+
cart**. The add goes out through `onAddToCart(line)`; while it runs the
|
|
6
|
+
button spins, when it fails the block says why and nothing else changes,
|
|
7
|
+
when it works it says what was added. Details (description, care,
|
|
8
|
+
shipping) sit under the buy box in an accordion or tabs.
|
|
9
|
+
|
|
10
|
+
```jsx
|
|
11
|
+
import { ProductDetail } from "../components/blocks/product-detail"; // a Makersclaw app ("./blocks/product-detail" from components/)
|
|
12
|
+
import { ProductDetail } from "@/components/makersclaw/blocks/product-detail"; // a shadcn project
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
It is a client component: render it from a `"use client"` component, and
|
|
16
|
+
load the product in the server surface (README §4).
|
|
17
|
+
|
|
18
|
+
## The data
|
|
19
|
+
|
|
20
|
+
A **product** is one plain object. Only `id`, `name` and `price` are
|
|
21
|
+
needed; everything else draws a part when it is there.
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
{
|
|
25
|
+
id: "tee-linen", // required
|
|
26
|
+
name: "Linen camp shirt", // required
|
|
27
|
+
price: 68, // required: a number in the currency's major unit (68 = $68.00)
|
|
28
|
+
compareAt: 85, // the old price, struck through, with "20% off"
|
|
29
|
+
currency: "USD", // else the block's `currency`
|
|
30
|
+
image: "https://…", // one picture, or:
|
|
31
|
+
images: ["https://…", { src: "https://…", alt: "The back" }],
|
|
32
|
+
brand: "Harbor & Pine", // a small line over the name
|
|
33
|
+
badge: "New", // an outlined label beside it
|
|
34
|
+
description: "…",
|
|
35
|
+
rating: 4.6, reviews: 214, // stars (halves) and the count
|
|
36
|
+
href: "/shop/tee-linen", // where the product lives (carried into the cart line)
|
|
37
|
+
available: false, // sold out: the button says so and is off
|
|
38
|
+
stock: 3, // the quantity control stops here
|
|
39
|
+
options: [ // what the customer picks, in order
|
|
40
|
+
{ key: "size", label: "Size", values: ["S", "M", "L", { value: "XL", disabled: true }] },
|
|
41
|
+
{ key: "color", label: "Colour", values: [{ value: "sand", label: "Sand", color: "#d8c8a8" }] },
|
|
42
|
+
],
|
|
43
|
+
selected: { size: "M" }, // the first choices (else the first open value of each)
|
|
44
|
+
details: [{ key: "care", title: "Care", content: "Cold wash…" }], // content: text or a node
|
|
45
|
+
perks: [{ icon: "truck", label: "Free shipping over $100" }],
|
|
46
|
+
stats: [{ value: "1,234", label: "sales" }],
|
|
47
|
+
scene: "https://…", // gallery="overlay": the wide picture the buy box floats on
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
An option's **values** are strings or `{ value, label?, color?, price?,
|
|
52
|
+
compareAt?, per?, description?, badge?, disabled? }`. How an option is
|
|
53
|
+
drawn follows its values (or its `display`):
|
|
54
|
+
|
|
55
|
+
- `color` on the values → **swatches** (colour squares; the chosen name
|
|
56
|
+
in the heading). The colour is data, drawn by the kit's `Swatch`.
|
|
57
|
+
- up to 6 short values → **buttons**, a segmented row (sizes).
|
|
58
|
+
- more, or longer → **select**, the native one.
|
|
59
|
+
- `price` or `description` on the values → **plans**, a card each. The
|
|
60
|
+
chosen value's `price` replaces the product's (a licence, a bigger box).
|
|
61
|
+
|
|
62
|
+
`disabled: true` on a value marks it sold out: struck through, not
|
|
63
|
+
choosable.
|
|
64
|
+
|
|
65
|
+
### The cart line
|
|
66
|
+
|
|
67
|
+
`onAddToCart` and `onBuyNow` get one **line**, the same shape the `cart`
|
|
68
|
+
block takes as an item, so a surface can push it straight into its cart
|
|
69
|
+
rows:
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
{
|
|
73
|
+
id: "tee-linen",
|
|
74
|
+
key: "tee-linen:size=M:color=sand", // one cart row per product + choices
|
|
75
|
+
name: "Linen camp shirt",
|
|
76
|
+
price: 68, compareAt: 85, currency: "USD",
|
|
77
|
+
image: "https://…",
|
|
78
|
+
href: "/shop/tee-linen",
|
|
79
|
+
quantity: 2,
|
|
80
|
+
selected: { size: "M", color: "sand" }, // machine values, for your order row
|
|
81
|
+
variant: "M · Sand", // what the cart prints under the name
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`cartLine(product, selected, quantity, currency)` builds the same line
|
|
86
|
+
anywhere else (a grid's quick add).
|
|
87
|
+
|
|
88
|
+
## Props
|
|
89
|
+
|
|
90
|
+
- `product` — the product above. `null` (and not loading) shows "No
|
|
91
|
+
product here".
|
|
92
|
+
- `onAddToCart(line)` — put the line in the cart; return `{ ok: true }` or
|
|
93
|
+
`{ ok: false, error }` (a throw counts as failed, its message shown).
|
|
94
|
+
Without it the button is off.
|
|
95
|
+
- `gallery` — how the pictures sit: `"thumbs"` (default: one large, a
|
|
96
|
+
row of thumbnails under it) · `"rail"` (thumbnails in a column beside
|
|
97
|
+
it from lg up) · `"carousel"` (one at a time, swipe, arrows, dots) ·
|
|
98
|
+
`"stack"` (every picture, the buy box sticky beside them) ·
|
|
99
|
+
`"overlay"` (one wide `scene` picture with the buy box floating over it
|
|
100
|
+
from lg up; under it on a phone).
|
|
101
|
+
- `details` — `"accordion"` (default; the first section open) or `"tabs"`.
|
|
102
|
+
- `onBuyNow(line)` — a second button that goes straight to checkout
|
|
103
|
+
(open Paddle there); `{ ok }` as above. Absent: no button.
|
|
104
|
+
- `onFavorite(product, next)` — shows a heart toggle; `next` is true to
|
|
105
|
+
save, false to remove. It flips at once and flips back, with the
|
|
106
|
+
error, when the save fails. `favorite` — its starting state.
|
|
107
|
+
- `onViewCart()` — a "View cart" button in the added message.
|
|
108
|
+
- `breadcrumb` — `[{ label, href? }]`, drawn above with the kit's
|
|
109
|
+
`Breadcrumb`.
|
|
110
|
+
- `perks` — `[{ icon, label }]` under the buttons (else `product.perks`).
|
|
111
|
+
`icon` is a kit `Icon` name: `truck`, `refresh`, `shield-check`, `package`.
|
|
112
|
+
- `quantity` — `false` hides the quantity control (a download); default
|
|
113
|
+
`true`. `maxQuantity` — the most at once (10; `product.stock` caps it).
|
|
114
|
+
- `currency` — default `"USD"`. `locale` — for prices and counts
|
|
115
|
+
(default: the reader's).
|
|
116
|
+
- `imageFit` — `"cover"` (default, cropped to the square) or `"contain"`
|
|
117
|
+
(the whole picture, on a muted fill: packshots on white, screenshots).
|
|
118
|
+
- `loading` — skeletons in the page's shape. `error` (a string) — the
|
|
119
|
+
load failed; `onRetry` adds "Try again".
|
|
120
|
+
- `addLabel` (`"Add to cart"`) · `buyLabel` (`"Buy now"`) — the words.
|
|
121
|
+
- `headingLevel` — the name's heading, `2` by default; `1` when the block
|
|
122
|
+
IS the page.
|
|
123
|
+
- `className` — layout around it (width, margin). Never colour.
|
|
124
|
+
|
|
125
|
+
The parts are exported for a page of your own: `ProductMedia({ product,
|
|
126
|
+
layout, fit })`, `OptionPicker({ option, value, onChange })`,
|
|
127
|
+
`QuantityControl({ value, onChange, min, max })`, `Price({ price,
|
|
128
|
+
compareAt, currency })`, `formatPrice(amount, currency, locale)`.
|
|
129
|
+
|
|
130
|
+
## Example
|
|
131
|
+
|
|
132
|
+
```jsx
|
|
133
|
+
// surfaces/product.jsx — server: load, hand over
|
|
134
|
+
import { loadRow } from "../lib/data";
|
|
135
|
+
import ProductPage from "../components/ProductPage";
|
|
136
|
+
|
|
137
|
+
export default async function ProductSurface({ params }) {
|
|
138
|
+
const { row, error } = await loadRow({ source: "public.products", id: params.id });
|
|
139
|
+
return <ProductPage product={row} error={error} />;
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```jsx
|
|
144
|
+
// components/ProductPage.jsx — client: the page, the cart write
|
|
145
|
+
"use client";
|
|
146
|
+
import { insertRow } from "../lib/actions";
|
|
147
|
+
import { ProductDetail } from "./blocks/product-detail";
|
|
148
|
+
|
|
149
|
+
export default function ProductPage({ product, error }) {
|
|
150
|
+
return (
|
|
151
|
+
<ProductDetail
|
|
152
|
+
product={product}
|
|
153
|
+
error={error}
|
|
154
|
+
breadcrumb={[{ label: "Shop", href: "/shop" }, { label: product?.name ?? "Product" }]}
|
|
155
|
+
perks={[
|
|
156
|
+
{ icon: "truck", label: "Free shipping over $100" },
|
|
157
|
+
{ icon: "refresh", label: "30-day returns" },
|
|
158
|
+
]}
|
|
159
|
+
onAddToCart={(line) =>
|
|
160
|
+
insertRow({
|
|
161
|
+
source: "public.cart_items",
|
|
162
|
+
values: { product_id: line.id, line_key: line.key, quantity: line.quantity, selected: line.selected },
|
|
163
|
+
detail: `${line.quantity} × ${line.name}`,
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
A digital product with plans, no quantity, and a straight-to-checkout
|
|
172
|
+
button:
|
|
173
|
+
|
|
174
|
+
```jsx
|
|
175
|
+
<ProductDetail
|
|
176
|
+
product={{
|
|
177
|
+
id: "ui-kit",
|
|
178
|
+
name: "Dashboard UI kit",
|
|
179
|
+
price: 49,
|
|
180
|
+
images: ["https://…/cover.png"],
|
|
181
|
+
rating: 4.9,
|
|
182
|
+
reviews: 127,
|
|
183
|
+
stats: [{ value: "1,234", label: "sales" }],
|
|
184
|
+
options: [{
|
|
185
|
+
key: "licence",
|
|
186
|
+
label: "Licence",
|
|
187
|
+
values: [
|
|
188
|
+
{ value: "solo", label: "Solo", price: 49, description: "One maker, unlimited projects." },
|
|
189
|
+
{ value: "team", label: "Team", price: 149, badge: "Popular", description: "Up to 10 seats." },
|
|
190
|
+
],
|
|
191
|
+
}],
|
|
192
|
+
}}
|
|
193
|
+
quantity={false}
|
|
194
|
+
imageFit="contain"
|
|
195
|
+
onAddToCart={addToCart}
|
|
196
|
+
onBuyNow={(line) => openPaddleCheckout(line)}
|
|
197
|
+
/>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## What it will not do
|
|
201
|
+
|
|
202
|
+
- Take payment. "Buy now" hands the line to `onBuyNow`; checkout is
|
|
203
|
+
Paddle's, and no card field is ever drawn here.
|
|
204
|
+
- Keep the cart. It hands over one line; the cart's rows, totals and
|
|
205
|
+
merging live in your data and the `cart` block.
|
|
206
|
+
- Show similar products or reviews in full: put a `ProductGrid` (the
|
|
207
|
+
`product-grid` block) and your review list under it.
|
|
208
|
+
- Colour itself: swatch colours are data; everything else is the theme.
|
|
209
|
+
|
|
210
|
+
A product page it cannot be is your own component in `components/`, built
|
|
211
|
+
from the kit (and this block's exported parts) — not an edit to this
|
|
212
|
+
block. Its files are fixed: `npm run check` refuses a change, and
|
|
213
|
+
`makersclaw add product-detail` restores them.
|
|
214
|
+
|
|
215
|
+
## Credits
|
|
216
|
+
|
|
217
|
+
Ported from Creative Tim UI (https://github.com/creativetimofficial/ui), MIT — a rewrite on the Makersclaw kit, none of its code, copy or pictures.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "product-detail",
|
|
3
|
+
"title": "Product detail",
|
|
4
|
+
"description": "One product on its own page: pictures (thumbnails, a side rail, a carousel, a tall stack, or one scene with the buy box floating over it), brand, name, price with the old price struck through, star rating and review count, options (sizes as a segmented row, colours as swatches, long lists as a select, plans as cards with their own price), a quantity control, add to cart through an async callback that may fail, buy now, save to favourites, perks, and details in an accordion or tabs. Loading, error, not-found and sold-out states.",
|
|
5
|
+
"useWhen": "Selling one thing a customer looks at before buying: a product page, a template or digital download with plans, a merch item, a booking add-on. Not for many products at once (product-grid), the cart itself (cart), or a plan comparison table.",
|
|
6
|
+
"tags": ["product", "shop", "store", "ecommerce", "commerce", "buy", "add to cart", "price", "rating", "size", "colour", "variant", "quantity", "gallery", "carousel", "plans", "favourite", "pdp"],
|
|
7
|
+
"exports": ["ProductDetail", "ProductMedia", "OptionPicker", "QuantityControl", "Price", "formatPrice", "cartLine"],
|
|
8
|
+
"files": ["index.js", "product-detail.jsx", "product-media.jsx", "product-options.jsx", "price.jsx"],
|
|
9
|
+
"requires": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// The product page with its data in memory — the gallery's and the smoke
|
|
4
|
+
// test's surface. Not installed into apps: `makersclaw add product-detail`
|
|
5
|
+
// lays the block's files only. Every variant (each a source layout it was
|
|
6
|
+
// ported from) is one choice in the switcher.
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { Field, Select, ToggleGroup } from "../components/ui";
|
|
9
|
+
import { ProductDetail } from "../components/blocks/product-detail";
|
|
10
|
+
|
|
11
|
+
const pic = (seed, w = 900, h = 900) => `https://picsum.photos/seed/${seed}/${w}/${h}`;
|
|
12
|
+
|
|
13
|
+
const SHIRT = {
|
|
14
|
+
id: "camp-shirt",
|
|
15
|
+
name: "Linen camp shirt",
|
|
16
|
+
brand: "Harbor & Pine",
|
|
17
|
+
price: 68,
|
|
18
|
+
rating: 4.5,
|
|
19
|
+
reviews: 214,
|
|
20
|
+
description: "Washed linen with a relaxed collar and a straight hem, cut to wear open over a tee or buttoned on its own.",
|
|
21
|
+
images: [pic("mc-shirt-1"), pic("mc-shirt-2"), pic("mc-shirt-3"), pic("mc-shirt-4")],
|
|
22
|
+
options: [
|
|
23
|
+
{ key: "size", label: "Size", values: ["XS", "S", "M", "L", "XL", { value: "XXL", disabled: true }] },
|
|
24
|
+
{
|
|
25
|
+
key: "color",
|
|
26
|
+
label: "Colour",
|
|
27
|
+
values: [
|
|
28
|
+
{ value: "sand", label: "Sand", color: "tan" },
|
|
29
|
+
{ value: "white", label: "Chalk", color: "whitesmoke" },
|
|
30
|
+
{ value: "olive", label: "Olive", color: "darkolivegreen" },
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
selected: { size: "M" },
|
|
35
|
+
details: [
|
|
36
|
+
{ key: "about", title: "About the shirt", content: "Mid-weight European linen, garment washed so it is soft from the first wear. Corozo buttons, a single chest pocket, and a back pleat for room across the shoulders." },
|
|
37
|
+
{ key: "delivery", title: "Delivery and returns", content: "Free standard delivery on orders over $100, usually in three to five working days. Return anything unworn within 30 days." },
|
|
38
|
+
{ key: "help", title: "Questions", content: "Write to help@harborpine.example and a person replies within a working day." },
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const COAT = {
|
|
43
|
+
id: "wool-overcoat",
|
|
44
|
+
name: "Double-faced wool overcoat",
|
|
45
|
+
brand: "Northfold",
|
|
46
|
+
badge: "Limited run",
|
|
47
|
+
price: 420,
|
|
48
|
+
rating: 4,
|
|
49
|
+
reviews: 88,
|
|
50
|
+
description: "A single-breasted overcoat in double-faced wool: no lining, so it drapes, and warm enough for a city winter.",
|
|
51
|
+
images: [pic("mc-coat-1"), pic("mc-coat-2"), pic("mc-coat-3"), pic("mc-coat-4")],
|
|
52
|
+
options: [
|
|
53
|
+
{
|
|
54
|
+
key: "color",
|
|
55
|
+
label: "Colour",
|
|
56
|
+
values: [
|
|
57
|
+
{ value: "charcoal", label: "Charcoal", color: "dimgray" },
|
|
58
|
+
{ value: "camel", label: "Camel", color: "peru" },
|
|
59
|
+
{ value: "navy", label: "Navy", color: "midnightblue" },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{ key: "size", label: "Size", values: ["34", "36", "38", "40", "42", "44", "46"] },
|
|
63
|
+
],
|
|
64
|
+
perks: [
|
|
65
|
+
{ icon: "truck", label: "Free shipping over $150" },
|
|
66
|
+
{ icon: "refresh", label: "30-day returns" },
|
|
67
|
+
{ icon: "shield-check", label: "Two-year guarantee" },
|
|
68
|
+
{ icon: "package", label: "Ships in recycled card" },
|
|
69
|
+
],
|
|
70
|
+
details: [
|
|
71
|
+
{ key: "features", title: "Features", content: "Hand-finished edges, a two-button front, welt pockets and an inside pocket sized for a phone." },
|
|
72
|
+
{ key: "care", title: "Care", content: "Dry clean only. Brush after wearing and hang on a shaped hanger to keep the shoulders." },
|
|
73
|
+
{ key: "shipping", title: "Shipping and returns", content: "Ships in two working days. Returns are free within 30 days in original condition." },
|
|
74
|
+
{ key: "warranty", title: "Warranty", content: "Seams and buttons are covered for two years. Write to us with a photo and we repair or replace it." },
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const JUG = {
|
|
79
|
+
id: "stoneware-jug",
|
|
80
|
+
name: "Stoneware water jug",
|
|
81
|
+
brand: "Kiln Street",
|
|
82
|
+
badge: "New",
|
|
83
|
+
price: 54,
|
|
84
|
+
compareAt: 72,
|
|
85
|
+
rating: 5,
|
|
86
|
+
reviews: 127,
|
|
87
|
+
description: "Thrown by hand and glazed inside and out, with a pinched spout that pours without a drip.",
|
|
88
|
+
images: [pic("mc-jug-1"), pic("mc-jug-2"), pic("mc-jug-3")],
|
|
89
|
+
scene: pic("mc-jug-room", 1600, 900),
|
|
90
|
+
perks: [{ icon: "truck", label: "Free shipping on orders over $100" }],
|
|
91
|
+
details: [
|
|
92
|
+
{ key: "features", title: "Features", content: "Holds 1.2 litres. Dishwasher safe; the unglazed foot is sanded smooth so it will not mark a table." },
|
|
93
|
+
{ key: "care", title: "Care", content: "Rinse after use. A little vinegar lifts limescale from the inside." },
|
|
94
|
+
{ key: "shipping", title: "Shipping", content: "Double boxed. If it arrives chipped, send a photo and we send another." },
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const BAG = {
|
|
99
|
+
id: "crossbody-bag",
|
|
100
|
+
name: "Vegetable-tanned crossbody",
|
|
101
|
+
brand: "Atelier Rue",
|
|
102
|
+
badge: "Trending",
|
|
103
|
+
price: 185,
|
|
104
|
+
rating: 4.7,
|
|
105
|
+
reviews: 342,
|
|
106
|
+
description: "A small bag in vegetable-tanned leather that darkens as it is used. A magnetic flap, one inside zip pocket, and a strap that adjusts.",
|
|
107
|
+
images: [pic("mc-bag-1"), pic("mc-bag-2"), pic("mc-bag-3"), pic("mc-bag-4"), pic("mc-bag-5")],
|
|
108
|
+
options: [
|
|
109
|
+
{
|
|
110
|
+
key: "color",
|
|
111
|
+
label: "Colour",
|
|
112
|
+
values: [
|
|
113
|
+
{ value: "black", label: "Black", color: "black" },
|
|
114
|
+
{ value: "tan", label: "Tan", color: "sienna" },
|
|
115
|
+
{ value: "forest", label: "Forest", color: "seagreen" },
|
|
116
|
+
{ value: "stone", label: "Stone", color: "silver", disabled: true },
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
perks: [
|
|
121
|
+
{ icon: "package", label: "Full-grain leather" },
|
|
122
|
+
{ icon: "pin", label: "Made in Portugal" },
|
|
123
|
+
],
|
|
124
|
+
details: [{ key: "more", title: "More information", content: "23 × 17 × 7 cm. The strap drops 50 to 60 cm. Wipe with a dry cloth; condition twice a year." }],
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const KIT = {
|
|
128
|
+
id: "admin-kit",
|
|
129
|
+
name: "Admin dashboard kit",
|
|
130
|
+
badge: "Best seller",
|
|
131
|
+
price: 49,
|
|
132
|
+
rating: 4.9,
|
|
133
|
+
reviews: 127,
|
|
134
|
+
description: "Sixty screens and the components behind them, ready to drop into a project: tables, charts, settings and sign-in.",
|
|
135
|
+
images: [pic("mc-kit-1", 1200, 900), pic("mc-kit-2", 1200, 900)],
|
|
136
|
+
stats: [
|
|
137
|
+
{ value: "4.9/5", label: "rating" },
|
|
138
|
+
{ value: "1,234", label: "sales" },
|
|
139
|
+
],
|
|
140
|
+
options: [
|
|
141
|
+
{
|
|
142
|
+
key: "licence",
|
|
143
|
+
label: "Choose your licence",
|
|
144
|
+
values: [
|
|
145
|
+
{ value: "html", label: "HTML", price: 39, per: "one-time", description: "Static pages with the styles compiled." },
|
|
146
|
+
{ value: "react", label: "React", price: 49, per: "one-time", badge: "Popular", description: "Components with props and typed data." },
|
|
147
|
+
{ value: "team", label: "Team", price: 149, per: "one-time", description: "React, for up to ten people." },
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
selected: { licence: "react" },
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const VARIANTS = [
|
|
155
|
+
{ value: "simple", label: "Simple — thumbs, accordion", product: SHIRT, props: { gallery: "thumbs" } },
|
|
156
|
+
{ value: "description", label: "Description — selects, perks", product: COAT, props: { gallery: "thumbs", breadcrumb: [{ label: "Shop", href: "#shop" }, { label: "Outerwear", href: "#outerwear" }, { label: COAT.name }] } },
|
|
157
|
+
{ value: "carousel", label: "Carousel", product: SHIRT, props: { gallery: "carousel", breadcrumb: [{ label: "Shop", href: "#shop" }, { label: SHIRT.name }] } },
|
|
158
|
+
{ value: "complex", label: "Complex — side rail, long details", product: COAT, props: { gallery: "rail", onBuyNow: true } },
|
|
159
|
+
{ value: "tabs", label: "Tabs — sale price", product: JUG, props: { gallery: "thumbs", details: "tabs" } },
|
|
160
|
+
{ value: "stack", label: "Stack — sticky buy box", product: BAG, props: { gallery: "stack", onBuyNow: true, quantity: false } },
|
|
161
|
+
{ value: "plans", label: "Digital — plans", product: KIT, props: { gallery: "thumbs", imageFit: "contain", quantity: false, onBuyNow: true } },
|
|
162
|
+
{ value: "overlay", label: "Overlay — room scene", product: JUG, props: { gallery: "overlay" } },
|
|
163
|
+
];
|
|
164
|
+
|
|
165
|
+
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
166
|
+
|
|
167
|
+
export default function ProductDetailDemo() {
|
|
168
|
+
const [variant, setVariant] = useState("simple");
|
|
169
|
+
const [state, setState] = useState("ready");
|
|
170
|
+
const [cart, setCart] = useState([]);
|
|
171
|
+
const v = VARIANTS.find((x) => x.value === variant) ?? VARIANTS[0];
|
|
172
|
+
const failing = state === "fails";
|
|
173
|
+
|
|
174
|
+
async function addToCart(line) {
|
|
175
|
+
await wait(700);
|
|
176
|
+
if (failing) return { ok: false, error: "The cart is not answering. Nothing was added — try again." };
|
|
177
|
+
setCart((all) => {
|
|
178
|
+
const hit = all.find((l) => l.key === line.key);
|
|
179
|
+
return hit ? all.map((l) => (l.key === line.key ? { ...l, quantity: l.quantity + line.quantity } : l)) : [...all, line];
|
|
180
|
+
});
|
|
181
|
+
return { ok: true };
|
|
182
|
+
}
|
|
183
|
+
async function buyNow() {
|
|
184
|
+
await wait(700);
|
|
185
|
+
return failing ? { ok: false, error: "Checkout did not open. Try again in a moment." } : { ok: true };
|
|
186
|
+
}
|
|
187
|
+
async function favorite() {
|
|
188
|
+
await wait(400);
|
|
189
|
+
return failing ? { ok: false, error: "Favourites are not saving right now." } : { ok: true };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const { onBuyNow, ...props } = v.props;
|
|
193
|
+
const count = cart.reduce((n, l) => n + l.quantity, 0);
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<div className="grid gap-6">
|
|
197
|
+
<div className="flex flex-wrap items-end gap-3">
|
|
198
|
+
<Field id="pd-variant" label="Layout" className="w-full sm:w-72">
|
|
199
|
+
<Select id="pd-variant" value={variant} onChange={(e) => setVariant(e.target.value)} options={VARIANTS.map(({ value, label }) => ({ value, label }))} />
|
|
200
|
+
</Field>
|
|
201
|
+
<ToggleGroup
|
|
202
|
+
size="sm"
|
|
203
|
+
aria-label="Demo state"
|
|
204
|
+
value={state}
|
|
205
|
+
onChange={setState}
|
|
206
|
+
items={[
|
|
207
|
+
{ value: "ready", label: "Ready" },
|
|
208
|
+
{ value: "fails", label: "Fails" },
|
|
209
|
+
{ value: "loading", label: "Loading" },
|
|
210
|
+
{ value: "error", label: "Error" },
|
|
211
|
+
{ value: "missing", label: "Gone" },
|
|
212
|
+
]}
|
|
213
|
+
/>
|
|
214
|
+
<p data-nums className="text-sm text-muted-foreground sm:ml-auto">
|
|
215
|
+
Cart: {count} {count === 1 ? "item" : "items"}
|
|
216
|
+
</p>
|
|
217
|
+
</div>
|
|
218
|
+
|
|
219
|
+
<ProductDetail
|
|
220
|
+
key={variant}
|
|
221
|
+
product={state === "missing" ? null : v.product}
|
|
222
|
+
loading={state === "loading"}
|
|
223
|
+
error={state === "error" ? "The shop's database did not answer." : undefined}
|
|
224
|
+
onRetry={() => setState("ready")}
|
|
225
|
+
onAddToCart={addToCart}
|
|
226
|
+
onBuyNow={onBuyNow ? buyNow : undefined}
|
|
227
|
+
onFavorite={favorite}
|
|
228
|
+
onViewCart={() => {}}
|
|
229
|
+
{...props}
|
|
230
|
+
/>
|
|
231
|
+
</div>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// The Product detail block — `makersclaw add product-detail`. Fixed:
|
|
2
|
+
// compose it through its props (README.md beside this file); a product
|
|
3
|
+
// page it cannot be is your own component in components/.
|
|
4
|
+
export { ProductDetail } from "./product-detail";
|
|
5
|
+
export { ProductMedia } from "./product-media";
|
|
6
|
+
export { OptionPicker, QuantityControl } from "./product-options";
|
|
7
|
+
export { Price, formatPrice, cartLine } from "./price";
|