makersclaw 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +41 -1
- package/THIRD-PARTY-NOTICES.md +180 -0
- package/package.json +15 -8
- 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 +55 -0
- 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 +341 -0
- 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 +56 -0
- 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 +3612 -0
- 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 +64 -13
- package/registry/blocks/board/block.json +2 -2
- package/registry/blocks/board/board.jsx +237 -94
- 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 +86 -2
- 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 +171 -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/parts/fixture.jsx +1 -1
- package/templates/next/files/components/parts/sample.js +15 -0
- 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/files/lib/sample.js +4 -12
- package/templates/next/template.json +264 -8
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
// The gantt's arithmetic — pure, no React, no pixels read from the DOM.
|
|
2
|
+
// The zoom levels, the window a timeline covers, its two header tiers,
|
|
3
|
+
// where a day sits in pixels, what a drag or a resize saves (and which
|
|
4
|
+
// waiting tasks it pushes along), and the elbow a dependency arrow takes.
|
|
5
|
+
// The dates are task-model's: wall-calendar strings, day numbers for math.
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
addDays,
|
|
9
|
+
descendantIds,
|
|
10
|
+
diffDays,
|
|
11
|
+
endOfMonth,
|
|
12
|
+
formatDate,
|
|
13
|
+
isWeekend,
|
|
14
|
+
shiftDates,
|
|
15
|
+
spanOf,
|
|
16
|
+
spanPatch,
|
|
17
|
+
startOfMonth,
|
|
18
|
+
startOfWeek,
|
|
19
|
+
timeScale,
|
|
20
|
+
} from "../task-model";
|
|
21
|
+
|
|
22
|
+
/** The zoom levels: how wide a day is, what the columns are, how much
|
|
23
|
+
* room the window keeps either side of the work, and its least length. */
|
|
24
|
+
export const ZOOMS = {
|
|
25
|
+
day: { key: "day", label: "Day", unit: "day", dayWidth: 36, pad: 7, min: 56, top: "month" },
|
|
26
|
+
week: { key: "week", label: "Week", unit: "week", dayWidth: 16, pad: 14, min: 150, top: "month" },
|
|
27
|
+
month: { key: "month", label: "Month", unit: "month", dayWidth: 5, pad: 45, min: 420, top: "year" },
|
|
28
|
+
quarter: { key: "quarter", label: "Quarter", unit: "quarter", dayWidth: 1.75, pad: 90, min: 900, top: "year" },
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const zoomOf = (key) => ZOOMS[key] ?? ZOOMS.week;
|
|
32
|
+
|
|
33
|
+
/** The first day of `day`'s column at `unit`. */
|
|
34
|
+
export function unitStart(day, unit, weekStartsOn = 1) {
|
|
35
|
+
if (unit === "day" || unit === "week") return startOfWeek(day, weekStartsOn);
|
|
36
|
+
if (unit === "month") return startOfMonth(day);
|
|
37
|
+
return timeScale(day, day, "quarter")[0]?.start ?? day;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The last day of `day`'s column at `unit`. */
|
|
41
|
+
export function unitEnd(day, unit, weekStartsOn = 1) {
|
|
42
|
+
if (unit === "day" || unit === "week") return addDays(startOfWeek(day, weekStartsOn), 6);
|
|
43
|
+
if (unit === "month") return endOfMonth(day);
|
|
44
|
+
return timeScale(day, day, "quarter")[0]?.end ?? day;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The window a timeline covers: every task's span and today, padded by
|
|
48
|
+
* the zoom, snapped to whole columns, at least the zoom's `min` days.
|
|
49
|
+
* → { from, to, days } */
|
|
50
|
+
export function ganttRange(tasks, zoomKey, today, { weekStartsOn = 1 } = {}) {
|
|
51
|
+
const z = zoomOf(zoomKey);
|
|
52
|
+
let lo = null;
|
|
53
|
+
let hi = null;
|
|
54
|
+
for (const t of tasks ?? []) {
|
|
55
|
+
const s = spanOf(t);
|
|
56
|
+
if (!s) continue;
|
|
57
|
+
if (lo === null || s.start < lo) lo = s.start;
|
|
58
|
+
if (hi === null || s.end > hi) hi = s.end;
|
|
59
|
+
}
|
|
60
|
+
if (today) {
|
|
61
|
+
if (lo === null || today < lo) lo = today;
|
|
62
|
+
if (hi === null || today > hi) hi = today;
|
|
63
|
+
}
|
|
64
|
+
if (lo === null) return { from: null, to: null, days: 0 };
|
|
65
|
+
let from = unitStart(addDays(lo, -z.pad), z.unit, weekStartsOn);
|
|
66
|
+
let to = unitEnd(addDays(hi, z.pad), z.unit, weekStartsOn);
|
|
67
|
+
if (diffDays(from, to) + 1 < z.min) to = unitEnd(addDays(from, z.min - 1), z.unit, weekStartsOn);
|
|
68
|
+
return { from, to, days: diffDays(from, to) + 1 };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** A day's left edge in pixels from the window's first day. */
|
|
72
|
+
export function xOf(day, from, dayWidth) {
|
|
73
|
+
const d = diffDays(from, day);
|
|
74
|
+
return d === null ? null : d * dayWidth;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** The two header tiers over [from, to], in pixels: `top` (months, or
|
|
78
|
+
* years when zoomed out) and `bottom` (the zoom's columns), each
|
|
79
|
+
* { key, start, end, x, w, label, weekend?, today? }. */
|
|
80
|
+
export function headerTiers(from, to, zoomKey, { today, weekStartsOn = 1, locale } = {}) {
|
|
81
|
+
const z = zoomOf(zoomKey);
|
|
82
|
+
const place = (start, end) => {
|
|
83
|
+
const a = start < from ? from : start;
|
|
84
|
+
const b = end > to ? to : end;
|
|
85
|
+
return { x: xOf(a, from, z.dayWidth), w: (diffDays(a, b) + 1) * z.dayWidth };
|
|
86
|
+
};
|
|
87
|
+
const bottom = timeScale(from, to, z.unit, { weekStartsOn, locale }).map((c) => {
|
|
88
|
+
let label = c.label;
|
|
89
|
+
if (z.unit === "month") label = formatDate(c.start, { month: "short" }, { locale });
|
|
90
|
+
if (z.unit === "quarter") label = c.label.split(" ")[0];
|
|
91
|
+
return {
|
|
92
|
+
key: c.key,
|
|
93
|
+
start: c.start,
|
|
94
|
+
end: c.end,
|
|
95
|
+
label,
|
|
96
|
+
weekend: z.unit === "day" && isWeekend(c.start),
|
|
97
|
+
today: Boolean(today) && c.start <= today && today <= c.end,
|
|
98
|
+
...place(c.start, c.end),
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
let top;
|
|
102
|
+
if (z.top === "month") {
|
|
103
|
+
top = timeScale(from, to, "month", { locale }).map((c) => ({
|
|
104
|
+
key: c.key,
|
|
105
|
+
start: c.start,
|
|
106
|
+
end: c.end,
|
|
107
|
+
label: formatDate(c.start, { month: "long", year: "numeric" }, { locale }),
|
|
108
|
+
...place(c.start, c.end),
|
|
109
|
+
}));
|
|
110
|
+
} else {
|
|
111
|
+
top = [];
|
|
112
|
+
for (let y = +from.slice(0, 4); y <= +to.slice(0, 4); y++) {
|
|
113
|
+
const start = `${y}-01-01`;
|
|
114
|
+
const end = `${y}-12-31`;
|
|
115
|
+
top.push({ key: String(y), start, end, label: String(y), ...place(start, end) });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return { top, bottom };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** The weekend columns of the window (day and week zoom), for shading. */
|
|
122
|
+
export function weekendBands(from, to, zoomKey, weekend) {
|
|
123
|
+
const z = zoomOf(zoomKey);
|
|
124
|
+
if (z.unit !== "day" && z.unit !== "week") return [];
|
|
125
|
+
const out = [];
|
|
126
|
+
const n = diffDays(from, to);
|
|
127
|
+
for (let i = 0; i <= n; i++) {
|
|
128
|
+
const d = addDays(from, i);
|
|
129
|
+
if (!isWeekend(d, weekend)) continue;
|
|
130
|
+
const last = out[out.length - 1];
|
|
131
|
+
if (last && last.end === addDays(d, -1)) last.end = d;
|
|
132
|
+
else out.push({ start: d, end: d });
|
|
133
|
+
}
|
|
134
|
+
return out.map((b) => ({ ...b, x: xOf(b.start, from, z.dayWidth), w: (diffDays(b.start, b.end) + 1) * z.dayWidth }));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** A milestone: a task marked `milestone: true` (or `type: "milestone"`).
|
|
138
|
+
* It sits on one day, its due date (else its start). */
|
|
139
|
+
export function isMilestone(task) {
|
|
140
|
+
return task?.milestone === true || task?.type === "milestone";
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** The span a row draws: its own, or — for a task with subtasks — the
|
|
144
|
+
* union of its own and every descendant's (a summary bar). */
|
|
145
|
+
export function summarySpan(task, tasks) {
|
|
146
|
+
let span = spanOf(task);
|
|
147
|
+
for (const id of descendantIds(tasks, task.id)) {
|
|
148
|
+
const s = spanOf(tasks.find((t) => t.id === id));
|
|
149
|
+
if (!s) continue;
|
|
150
|
+
span = span ? { start: s.start < span.start ? s.start : span.start, end: s.end > span.end ? s.end : span.end } : s;
|
|
151
|
+
}
|
|
152
|
+
return span;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** What moving or stretching a task saves, as [{ id, patch }]:
|
|
156
|
+
* - kind "move": its dates shift by `days` (its subtasks with it);
|
|
157
|
+
* - kind "start" / "end": that edge moves by `days` (never past the other);
|
|
158
|
+
* - with `push` (default), every task waiting on a moved one that would
|
|
159
|
+
* now start on or before it ends slides later just enough, keeping its
|
|
160
|
+
* length — and so on down the chain. Nothing is ever pulled earlier.
|
|
161
|
+
* `days` 0 → []. The same answer drives the live preview and the save. */
|
|
162
|
+
export function planMove(tasks, id, kind, days, { push = true } = {}) {
|
|
163
|
+
if (!days) return [];
|
|
164
|
+
const byId = new Map(tasks.map((t) => [t.id, t]));
|
|
165
|
+
const task = byId.get(id);
|
|
166
|
+
const span = spanOf(task);
|
|
167
|
+
if (!task || (!span && kind !== "move")) return [];
|
|
168
|
+
const patches = new Map();
|
|
169
|
+
const current = (tid) => ({ ...byId.get(tid), ...patches.get(tid) });
|
|
170
|
+
const set = (tid, patch) => patches.set(tid, { ...patches.get(tid), ...patch });
|
|
171
|
+
|
|
172
|
+
if (kind === "move") {
|
|
173
|
+
if (span) set(id, shiftDates(task, days));
|
|
174
|
+
for (const d of descendantIds(tasks, id)) if (spanOf(byId.get(d))) set(d, shiftDates(byId.get(d), days));
|
|
175
|
+
} else if (kind === "start") {
|
|
176
|
+
const next = addDays(span.start, days);
|
|
177
|
+
set(id, spanPatch(task, next > span.end ? span.end : next, span.end));
|
|
178
|
+
} else if (kind === "end") {
|
|
179
|
+
const next = addDays(span.end, days);
|
|
180
|
+
set(id, spanPatch(task, span.start, next < span.start ? span.start : next));
|
|
181
|
+
} else return [];
|
|
182
|
+
|
|
183
|
+
if (push) {
|
|
184
|
+
const waiting = new Map();
|
|
185
|
+
for (const t of tasks) for (const d of t.dependsOn ?? []) (waiting.get(d) ?? waiting.set(d, []).get(d)).push(t.id);
|
|
186
|
+
const queue = [...patches.keys()];
|
|
187
|
+
let guard = 0;
|
|
188
|
+
while (queue.length && guard++ < 5000) {
|
|
189
|
+
const from = queue.shift();
|
|
190
|
+
const fs = spanOf(current(from));
|
|
191
|
+
if (!fs) continue;
|
|
192
|
+
for (const to of waiting.get(from) ?? []) {
|
|
193
|
+
const ts = spanOf(current(to));
|
|
194
|
+
if (!ts || ts.start > fs.end) continue;
|
|
195
|
+
const by = diffDays(ts.start, fs.end) + 1;
|
|
196
|
+
set(to, shiftDates(current(to), by));
|
|
197
|
+
queue.push(to);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return [...patches].map(([pid, patch]) => ({ id: pid, patch }));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** The patch that starts a task the day after the last of its blockers
|
|
205
|
+
* ends, keeping its length (a date conflict's fix). null when it has no
|
|
206
|
+
* scheduled blockers or already starts after them. */
|
|
207
|
+
export function afterBlockersPatch(task, tasks) {
|
|
208
|
+
const span = spanOf(task);
|
|
209
|
+
if (!span) return null;
|
|
210
|
+
let last = null;
|
|
211
|
+
for (const d of task.dependsOn ?? []) {
|
|
212
|
+
const s = spanOf(tasks.find((t) => t.id === d));
|
|
213
|
+
if (s && (last === null || s.end > last)) last = s.end;
|
|
214
|
+
}
|
|
215
|
+
if (last === null || span.start > last) return null;
|
|
216
|
+
return shiftDates(task, diffDays(span.start, last) + 1);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** A task's length in calendar days (1 for a one-day task), null when
|
|
220
|
+
* it has no dates. */
|
|
221
|
+
export function lengthOf(span) {
|
|
222
|
+
return span ? diffDays(span.start, span.end) + 1 : null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** An SVG path through `points` ([x, y] pairs) with its corners rounded
|
|
226
|
+
* by `r` (less where a leg is short). */
|
|
227
|
+
export function roundedPath(points, r = 4) {
|
|
228
|
+
const pts = points.filter((p, i) => i === 0 || p[0] !== points[i - 1][0] || p[1] !== points[i - 1][1]);
|
|
229
|
+
if (pts.length < 2) return "";
|
|
230
|
+
const f = (n) => Math.round(n * 10) / 10;
|
|
231
|
+
let d = `M${f(pts[0][0])} ${f(pts[0][1])}`;
|
|
232
|
+
for (let i = 1; i < pts.length - 1; i++) {
|
|
233
|
+
const [px, py] = pts[i - 1];
|
|
234
|
+
const [x, y] = pts[i];
|
|
235
|
+
const [nx, ny] = pts[i + 1];
|
|
236
|
+
const inLen = Math.hypot(x - px, y - py);
|
|
237
|
+
const outLen = Math.hypot(nx - x, ny - y);
|
|
238
|
+
const k = Math.min(r, inLen / 2, outLen / 2);
|
|
239
|
+
const ax = x - ((x - px) / (inLen || 1)) * k;
|
|
240
|
+
const ay = y - ((y - py) / (inLen || 1)) * k;
|
|
241
|
+
const bx = x + ((nx - x) / (outLen || 1)) * k;
|
|
242
|
+
const by = y + ((ny - y) / (outLen || 1)) * k;
|
|
243
|
+
d += ` L${f(ax)} ${f(ay)} Q${f(x)} ${f(y)} ${f(bx)} ${f(by)}`;
|
|
244
|
+
}
|
|
245
|
+
const last = pts[pts.length - 1];
|
|
246
|
+
return `${d} L${f(last[0])} ${f(last[1])}`;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** The elbow from a finished task to the one waiting on it (finish to
|
|
250
|
+
* start). Boxes are what the rows draw: { x0, x1, y (centre) }. When the
|
|
251
|
+
* waiting task starts far enough right, the line runs out, turns and
|
|
252
|
+
* enters from the left; when it does not (or it starts too early — a
|
|
253
|
+
* conflict), it steps out, drops between the rows and comes back in.
|
|
254
|
+
* → { d, head } — the line, and the arrowhead's path at its end. */
|
|
255
|
+
export function arrowPath(a, b, { rowHeight = 36, gap = 10, radius = 4 } = {}) {
|
|
256
|
+
const sx = a.x1;
|
|
257
|
+
const sy = a.y;
|
|
258
|
+
const ex = b.x0;
|
|
259
|
+
const ey = b.y;
|
|
260
|
+
let points;
|
|
261
|
+
if (Math.abs(ey - sy) < 1) points = [[sx, sy], [ex, ey]];
|
|
262
|
+
else if (ex - gap >= sx + gap) points = [[sx, sy], [ex - gap, sy], [ex - gap, ey], [ex, ey]];
|
|
263
|
+
else {
|
|
264
|
+
const mid = sy + (ey > sy ? rowHeight / 2 : -rowHeight / 2);
|
|
265
|
+
points = [[sx, sy], [sx + gap, sy], [sx + gap, mid], [ex - gap, mid], [ex - gap, ey], [ex, ey]];
|
|
266
|
+
}
|
|
267
|
+
const f = (n) => Math.round(n * 10) / 10;
|
|
268
|
+
const head = `M${f(ex - 5)} ${f(ey - 3.5)} L${f(ex)} ${f(ey)} L${f(ex - 5)} ${f(ey + 3.5)} Z`;
|
|
269
|
+
return { d: roundedPath(points, radius), head };
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Pixels → whole days at a zoom (a drag's delta, rounded to the nearest
|
|
273
|
+
* day; never -0). */
|
|
274
|
+
export function daysFromPixels(px, dayWidth) {
|
|
275
|
+
const n = Math.round((px || 0) / dayWidth);
|
|
276
|
+
return n === 0 ? 0 : n;
|
|
277
|
+
}
|
|
278
|
+
|
|
@@ -7,16 +7,26 @@ stopped. When no job runs it renders nothing — a panel that is always
|
|
|
7
7
|
there is a monitoring console, and apps do not have one.
|
|
8
8
|
|
|
9
9
|
```jsx
|
|
10
|
-
import { JobPanel } from "../components/blocks/job-panel"; // "./blocks/job-panel" from components/
|
|
10
|
+
import { JobPanel } from "../components/blocks/job-panel"; // a Makersclaw app ("./blocks/job-panel" from components/)
|
|
11
|
+
import { JobPanel } from "@/components/makersclaw/blocks/job-panel"; // a shadcn project
|
|
11
12
|
```
|
|
12
13
|
|
|
13
14
|
A client component. It takes the object `useJob()` returns (lib/hooks.js,
|
|
14
15
|
README §5 "Commissioning work") and draws it; starting the job stays with
|
|
15
16
|
your surface.
|
|
16
17
|
|
|
18
|
+
`variant="generator"` is the panel inside a small studio: a prompt, your
|
|
19
|
+
options, Generate, the running job, and a shelf of what it made. It holds
|
|
20
|
+
no model, provider or API key: Generate hands the prompt to the app's
|
|
21
|
+
agent (`job.start`, or your `onGenerate`), the agent writes rows, and you
|
|
22
|
+
pass those rows back in as `results`.
|
|
23
|
+
|
|
17
24
|
## Props
|
|
18
25
|
|
|
19
|
-
- `job` — what `useJob()` returns. Required.
|
|
26
|
+
- `job` — what `useJob()` returns. Required. Outside Makersclaw, any
|
|
27
|
+
object of the same shape: `running`, `steps` (`[{ name, label, status:
|
|
28
|
+
"running" | "done" | "failed" }]`), `text`, `error`, `finishedAt`, and
|
|
29
|
+
`cancel()` / `reset()`.
|
|
20
30
|
- `title` — while it runs, what the agent is doing, in the founder's
|
|
21
31
|
words: `"Drafting the launch plan"`. Default `"Working on it"`.
|
|
22
32
|
- `doneTitle` — after a clean finish: `"Launch plan drafted"`.
|
|
@@ -32,6 +42,36 @@ your surface.
|
|
|
32
42
|
is what the agent says it did, never the result: the result is rows.
|
|
33
43
|
- `className` — layout around it. Never colour.
|
|
34
44
|
|
|
45
|
+
### The generator (`variant="generator"`)
|
|
46
|
+
|
|
47
|
+
Everything above (`job`, `title`, `doneTitle`, `failedTitle`, `onRetry`,
|
|
48
|
+
`autoClose`, `maxSteps`, `showText`) goes to the panel inside it. Then:
|
|
49
|
+
|
|
50
|
+
- `onGenerate(prompt)` — start the job. Build the ask from the prompt and
|
|
51
|
+
your options and call `job.start(ask)`; return what it returns, or
|
|
52
|
+
`{ ok: false, error }` and the reason shows under the prompt. Default:
|
|
53
|
+
`job.start(prompt)`. Cmd/Ctrl+Enter in the prompt presses Generate.
|
|
54
|
+
Without `onRetry`, the panel's "Try again" re-runs the last prompt.
|
|
55
|
+
- `prompt` / `onPromptChange(text)` — control the prompt; or
|
|
56
|
+
`defaultPrompt`. `promptLabel` ("What should it make?"), `placeholder`,
|
|
57
|
+
`promptHint`, `promptRows` (4).
|
|
58
|
+
- `options` — your fields, in a two-column grid under the prompt (one
|
|
59
|
+
column on a phone): a size `Select`, a style `ToggleGroup`, a `Slider`.
|
|
60
|
+
Their values are yours; read them in `onGenerate`.
|
|
61
|
+
- `generateLabel` ("Generate") · `generateIcon` ("wand") ·
|
|
62
|
+
`canGenerateEmpty` (false) · `disabled` (false).
|
|
63
|
+
- `heading` · `description` — the form card's title and line under it.
|
|
64
|
+
- `aside` — a node under the form: tips, a note on cost.
|
|
65
|
+
- `results` — what the job made, as nodes (an array of cards, say). The
|
|
66
|
+
shelf draws them in `resultsColumns` columns (1–4; fewer on a phone).
|
|
67
|
+
`resultsTitle` ("Results") and `resultsActions` (nodes beside it).
|
|
68
|
+
- `placeholderResult` — drawn at the top of the shelf while the job runs
|
|
69
|
+
(default a skeleton); the shelf is `aria-busy` meanwhile.
|
|
70
|
+
- `emptyTitle` · `emptyBody` · `emptyState` — the shelf before anything
|
|
71
|
+
is made.
|
|
72
|
+
- `layout` — `"stacked"` (default: the form, then the shelf) or
|
|
73
|
+
`"split"` (side by side from lg up; stacked on a phone).
|
|
74
|
+
|
|
35
75
|
## Example
|
|
36
76
|
|
|
37
77
|
```jsx
|
|
@@ -63,6 +103,50 @@ export default function Launches({ launches, reload }) {
|
|
|
63
103
|
The verb sits on the object list beside the manual "New" (README §5, rule
|
|
64
104
|
1), and the panel sits where the result will appear.
|
|
65
105
|
|
|
106
|
+
A generator for product photos:
|
|
107
|
+
|
|
108
|
+
```jsx
|
|
109
|
+
"use client";
|
|
110
|
+
import { useEffect, useState } from "react";
|
|
111
|
+
import { useJob } from "../lib/hooks";
|
|
112
|
+
import { Field, Image, Select } from "./ui";
|
|
113
|
+
import { JobPanel } from "./blocks/job-panel";
|
|
114
|
+
|
|
115
|
+
export default function PhotoStudio({ photos, reload }) {
|
|
116
|
+
const job = useJob();
|
|
117
|
+
const [size, setSize] = useState("square");
|
|
118
|
+
useEffect(() => { reload?.(); }, [job.progress]); // new photos appear as they land
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<JobPanel
|
|
122
|
+
variant="generator"
|
|
123
|
+
job={job}
|
|
124
|
+
heading="New product photo"
|
|
125
|
+
promptLabel="Describe the photo"
|
|
126
|
+
options={
|
|
127
|
+
<Field id="size" label="Size">
|
|
128
|
+
<Select id="size" value={size} onChange={(e) => setSize(e.target.value)}
|
|
129
|
+
options={[{ value: "square", label: "Square" }, { value: "portrait", label: "Portrait" }]} />
|
|
130
|
+
</Field>
|
|
131
|
+
}
|
|
132
|
+
onGenerate={(prompt) => job.start(`Make one ${size} product photo: ${prompt}. Save it to public.photos.`)}
|
|
133
|
+
title="Making the photo"
|
|
134
|
+
doneTitle="Photo saved"
|
|
135
|
+
results={photos.map((p) => <Image key={p.id} src={p.url} alt={p.prompt} ratio="square" rounded="lg" />)}
|
|
136
|
+
resultsColumns={3}
|
|
137
|
+
/>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
What it will not do: call a model, hold a provider or an API key, or
|
|
143
|
+
keep what was made. The agent does the work through the job; the rows
|
|
144
|
+
are the results.
|
|
145
|
+
|
|
66
146
|
Its files are fixed: `npm run check` refuses a change, and `makersclaw add
|
|
67
147
|
job-panel` restores them. A different panel is your own component in
|
|
68
148
|
`components/`, built from the kit.
|
|
149
|
+
|
|
150
|
+
## Credits
|
|
151
|
+
|
|
152
|
+
The generator variant is ported from Creative Tim UI (https://github.com/creativetimofficial/ui, ai-image-generator-01 and ai-video-generator-01, MIT), rewritten on the Makersclaw kit without its provider and API-key fields.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "job-panel",
|
|
3
3
|
"title": "JobPanel",
|
|
4
|
-
"description": "The panel that follows work the founder asked the app's agent for (useJob): each step's label as it runs, Stop, then done or the reason it stopped — and nothing on screen when no job runs.",
|
|
5
|
-
"useWhen": "A surface has a verb that asks the agent to make or find something (\"Generate a launch plan\", \"Find 20 leads\", \"Plan next sprint\") and the founder should watch it happen where the result will land.",
|
|
6
|
-
"tags": ["job", "agent", "generate", "progress", "steps", "running", "working", "commission", "ai", "stop", "status"],
|
|
4
|
+
"description": "The panel that follows work the founder asked the app's agent for (useJob): each step's label as it runs, Stop, then done or the reason it stopped — and nothing on screen when no job runs. variant=\"generator\" wraps it in a prompt, the surface's options, Generate and a results shelf, with no model, provider or API key of its own.",
|
|
5
|
+
"useWhen": "A surface has a verb that asks the agent to make or find something (\"Generate a launch plan\", \"Find 20 leads\", \"Plan next sprint\") and the founder should watch it happen where the result will land. variant=\"generator\" when the screen IS the place to ask: a prompt and a few options, the results under them (product photos, ad copy, names).",
|
|
6
|
+
"tags": ["job", "agent", "generate", "progress", "steps", "running", "working", "commission", "ai", "stop", "status", "generator", "prompt", "results", "image", "studio"],
|
|
7
7
|
"exports": ["JobPanel"],
|
|
8
8
|
"files": ["index.js", "job-panel.jsx"],
|
|
9
9
|
"requires": []
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// JobPanel driven by a pretend job — the gallery's and the smoke test's
|
|
4
|
-
// surface. Not installed into apps.
|
|
4
|
+
// surface. Not installed into apps. Three variants behind the switcher:
|
|
5
|
+
// Panel the panel under a verb; one run succeeds, one fails
|
|
6
|
+
// Photos variant="generator", stacked: a prompt, size and style, a
|
|
7
|
+
// grid of results
|
|
8
|
+
// Copy variant="generator", split: ad headlines as text results,
|
|
9
|
+
// tips beside the form
|
|
5
10
|
import { useEffect, useRef, useState } from "react";
|
|
6
|
-
import { Button } from "../components/ui";
|
|
11
|
+
import { Badge, Button, Card, Field, Icon, IconButton, Select, ToggleGroup, Switch } from "../components/ui";
|
|
7
12
|
import { JobPanel } from "../components/blocks/job-panel";
|
|
8
13
|
|
|
9
14
|
const STEPS = ["Reading the product list", "Searching the web", "Drafting the plan", "Saving 6 tasks"];
|
|
@@ -57,7 +62,7 @@ function usePretendJob() {
|
|
|
57
62
|
};
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
|
|
65
|
+
function PanelDemo() {
|
|
61
66
|
const job = usePretendJob();
|
|
62
67
|
return (
|
|
63
68
|
<div className="grid max-w-xl gap-4">
|
|
@@ -73,3 +78,225 @@ export default function JobPanelDemo() {
|
|
|
73
78
|
</div>
|
|
74
79
|
);
|
|
75
80
|
}
|
|
81
|
+
|
|
82
|
+
// A pretend job for the generators: the steps tick by, then `onDone` adds
|
|
83
|
+
// the results (the rows the agent would have written).
|
|
84
|
+
function useGeneratorJob() {
|
|
85
|
+
const [state, setState] = useState(IDLE);
|
|
86
|
+
const timers = useRef([]);
|
|
87
|
+
const clear = () => {
|
|
88
|
+
timers.current.forEach(clearTimeout);
|
|
89
|
+
timers.current = [];
|
|
90
|
+
};
|
|
91
|
+
useEffect(() => clear, []);
|
|
92
|
+
const later = (ms, fn) => timers.current.push(setTimeout(fn, ms));
|
|
93
|
+
function start(steps, { fail = false, onDone } = {}) {
|
|
94
|
+
clear();
|
|
95
|
+
setState({ ...IDLE, running: true });
|
|
96
|
+
steps.forEach((label, i) =>
|
|
97
|
+
later(650 * i + 200, () =>
|
|
98
|
+
setState((s) => ({
|
|
99
|
+
...s,
|
|
100
|
+
steps: [...s.steps.map((x) => ({ ...x, status: "done" })), { name: `step_${i}`, label, status: "running" }],
|
|
101
|
+
})),
|
|
102
|
+
),
|
|
103
|
+
);
|
|
104
|
+
later(650 * steps.length + 300, () => {
|
|
105
|
+
if (!fail) onDone?.();
|
|
106
|
+
setState((s) =>
|
|
107
|
+
fail
|
|
108
|
+
? { ...s, running: false, steps: s.steps.map((x, i) => ({ ...x, status: i === s.steps.length - 1 ? "failed" : "done" })), error: "The image service is busy. Nothing was saved." }
|
|
109
|
+
: { ...s, running: false, steps: s.steps.map((x) => ({ ...x, status: "done" })), finishedAt: new Date().toISOString(), progress: s.progress + 1 },
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
return { ok: true };
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
...state,
|
|
116
|
+
start,
|
|
117
|
+
cancel: () => {
|
|
118
|
+
clear();
|
|
119
|
+
setState((s) => ({ ...s, running: false, finishedAt: new Date().toISOString() }));
|
|
120
|
+
},
|
|
121
|
+
reset: () => {
|
|
122
|
+
clear();
|
|
123
|
+
setState(IDLE);
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const SIZES = [
|
|
129
|
+
{ value: "square", label: "Square · shop grid" },
|
|
130
|
+
{ value: "portrait", label: "Portrait · story" },
|
|
131
|
+
{ value: "wide", label: "Wide · banner" },
|
|
132
|
+
];
|
|
133
|
+
const RATIO_CLASS = { square: "aspect-square", portrait: "aspect-3/4", wide: "aspect-video" };
|
|
134
|
+
|
|
135
|
+
function PhotosDemo() {
|
|
136
|
+
const job = useGeneratorJob();
|
|
137
|
+
const [size, setSize] = useState("square");
|
|
138
|
+
const [style, setStyle] = useState("daylight");
|
|
139
|
+
const [fail, setFail] = useState(false);
|
|
140
|
+
const [photos, setPhotos] = useState([
|
|
141
|
+
{ id: "ph1", prompt: "Stoneware bowl on a linen cloth, morning window light", size: "square", style: "daylight" },
|
|
142
|
+
{ id: "ph2", prompt: "Oak wall shelf with three plants and a clay jug", size: "square", style: "studio" },
|
|
143
|
+
]);
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<div className="grid gap-3">
|
|
147
|
+
<Switch id="job-demo-fail" label="The next run fails" checked={fail} onChange={(e) => setFail(e.target.checked)} />
|
|
148
|
+
<JobPanel
|
|
149
|
+
variant="generator"
|
|
150
|
+
job={job}
|
|
151
|
+
heading="New product photo"
|
|
152
|
+
description="Pip makes it from your product photos and saves it to the catalogue."
|
|
153
|
+
promptLabel="Describe the photo"
|
|
154
|
+
placeholder="The large stoneware bowl on a kitchen table, lemons beside it…"
|
|
155
|
+
defaultPrompt="Linen apron hanging on a hook by a sunny window"
|
|
156
|
+
options={
|
|
157
|
+
<>
|
|
158
|
+
<Field id="job-demo-size" label="Size">
|
|
159
|
+
<Select id="job-demo-size" value={size} onChange={(e) => setSize(e.target.value)} options={SIZES} />
|
|
160
|
+
</Field>
|
|
161
|
+
<div className="grid gap-1.5">
|
|
162
|
+
<span id="job-demo-style" className="text-sm font-medium">
|
|
163
|
+
Light
|
|
164
|
+
</span>
|
|
165
|
+
<ToggleGroup
|
|
166
|
+
aria-label="Light"
|
|
167
|
+
value={style}
|
|
168
|
+
onChange={setStyle}
|
|
169
|
+
items={[
|
|
170
|
+
{ value: "daylight", label: "Daylight" },
|
|
171
|
+
{ value: "studio", label: "Studio" },
|
|
172
|
+
]}
|
|
173
|
+
className="w-full"
|
|
174
|
+
/>
|
|
175
|
+
</div>
|
|
176
|
+
</>
|
|
177
|
+
}
|
|
178
|
+
onGenerate={(prompt) =>
|
|
179
|
+
job.start(["Reading the product photos", "Composing the scene", "Rendering the picture", "Saving to the catalogue"], {
|
|
180
|
+
fail,
|
|
181
|
+
onDone: () => setPhotos((all) => [{ id: `ph${Date.now()}`, prompt, size, style }, ...all]),
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
title="Making the photo"
|
|
185
|
+
doneTitle="Photo saved to the catalogue"
|
|
186
|
+
failedTitle="The photo was not made"
|
|
187
|
+
resultsTitle={`Photos · ${photos.length}`}
|
|
188
|
+
resultsActions={
|
|
189
|
+
photos.length ? (
|
|
190
|
+
<Button size="sm" variant="quiet" onClick={() => setPhotos([])}>
|
|
191
|
+
Clear
|
|
192
|
+
</Button>
|
|
193
|
+
) : null
|
|
194
|
+
}
|
|
195
|
+
resultsColumns={3}
|
|
196
|
+
results={photos.map((p) => (
|
|
197
|
+
<figure key={p.id} className="grid gap-2">
|
|
198
|
+
<div className={`grid place-items-center rounded-lg border border-border bg-muted text-muted-foreground ${RATIO_CLASS[p.size]}`}>
|
|
199
|
+
<Icon name="image" size={28} />
|
|
200
|
+
</div>
|
|
201
|
+
<figcaption className="flex items-start justify-between gap-2">
|
|
202
|
+
<span className="line-clamp-2 text-xs text-muted-foreground">{p.prompt}</span>
|
|
203
|
+
<Badge>{p.style === "studio" ? "Studio" : "Daylight"}</Badge>
|
|
204
|
+
</figcaption>
|
|
205
|
+
</figure>
|
|
206
|
+
))}
|
|
207
|
+
emptyTitle="No photos yet"
|
|
208
|
+
emptyBody="Describe a photo and press Generate. It lands here and in the catalogue."
|
|
209
|
+
/>
|
|
210
|
+
</div>
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const TONES = [
|
|
215
|
+
{ value: "warm", label: "Warm and plain" },
|
|
216
|
+
{ value: "bold", label: "Short and bold" },
|
|
217
|
+
{ value: "playful", label: "Playful" },
|
|
218
|
+
];
|
|
219
|
+
const HEADLINES = {
|
|
220
|
+
warm: ["Made slowly, used every day", "Bowls for the table you actually eat at", "Clay, fire and a little patience"],
|
|
221
|
+
bold: ["Built to last. Priced to use.", "One bowl. Every meal.", "Stoneware that stays."],
|
|
222
|
+
playful: ["Soup's new favourite hangout", "Bowl-ed over yet?", "Your cereal deserves better"],
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
function CopyDemo() {
|
|
226
|
+
const job = useGeneratorJob();
|
|
227
|
+
const [tone, setTone] = useState("warm");
|
|
228
|
+
const [lines, setLines] = useState([]);
|
|
229
|
+
const [copied, setCopied] = useState(null);
|
|
230
|
+
|
|
231
|
+
return (
|
|
232
|
+
<JobPanel
|
|
233
|
+
variant="generator"
|
|
234
|
+
layout="split"
|
|
235
|
+
job={job}
|
|
236
|
+
heading="Ad headlines"
|
|
237
|
+
promptLabel="What are we advertising?"
|
|
238
|
+
placeholder="The stoneware bowl set, spring sale, 20% off…"
|
|
239
|
+
promptHint="Three headlines come back each time."
|
|
240
|
+
options={
|
|
241
|
+
<Field id="job-demo-tone" label="Tone">
|
|
242
|
+
<Select id="job-demo-tone" value={tone} onChange={(e) => setTone(e.target.value)} options={TONES} />
|
|
243
|
+
</Field>
|
|
244
|
+
}
|
|
245
|
+
generateLabel="Write headlines"
|
|
246
|
+
onGenerate={() =>
|
|
247
|
+
job.start(["Reading the product page", "Writing headlines", "Checking the length"], {
|
|
248
|
+
onDone: () => setLines((all) => [...HEADLINES[tone].map((text, i) => ({ id: `${Date.now()}-${i}`, text, tone })), ...all]),
|
|
249
|
+
})
|
|
250
|
+
}
|
|
251
|
+
title="Writing headlines"
|
|
252
|
+
doneTitle="Three headlines written"
|
|
253
|
+
aside={
|
|
254
|
+
<Card title="Tips" padding="sm">
|
|
255
|
+
<ul className="grid gap-1.5 text-sm text-muted-foreground">
|
|
256
|
+
<li>Name the product and the one reason to buy it.</li>
|
|
257
|
+
<li>Give the offer and the date it ends.</li>
|
|
258
|
+
<li>Under 40 characters fits every ad slot.</li>
|
|
259
|
+
</ul>
|
|
260
|
+
</Card>
|
|
261
|
+
}
|
|
262
|
+
resultsTitle="Headlines"
|
|
263
|
+
results={lines.map((l) => (
|
|
264
|
+
<div key={l.id} className="flex min-h-11 items-center justify-between gap-3 rounded-lg border border-border bg-card px-3 py-2">
|
|
265
|
+
<div className="min-w-0">
|
|
266
|
+
<p className="text-sm font-medium">{l.text}</p>
|
|
267
|
+
<p className="text-xs text-muted-foreground">
|
|
268
|
+
{TONES.find((t) => t.value === l.tone)?.label} · {l.text.length} characters
|
|
269
|
+
</p>
|
|
270
|
+
</div>
|
|
271
|
+
<IconButton
|
|
272
|
+
icon={copied === l.id ? "check" : "copy"}
|
|
273
|
+
label={copied === l.id ? "Copied" : "Copy headline"}
|
|
274
|
+
size="sm"
|
|
275
|
+
onClick={() => {
|
|
276
|
+
navigator.clipboard?.writeText(l.text).catch(() => {});
|
|
277
|
+
setCopied(l.id);
|
|
278
|
+
}}
|
|
279
|
+
/>
|
|
280
|
+
</div>
|
|
281
|
+
))}
|
|
282
|
+
/>
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const VARIANTS = [
|
|
287
|
+
{ value: "panel", label: "Panel" },
|
|
288
|
+
{ value: "photos", label: "Photos" },
|
|
289
|
+
{ value: "copy", label: "Copy" },
|
|
290
|
+
];
|
|
291
|
+
|
|
292
|
+
export default function JobPanelDemo() {
|
|
293
|
+
const [variant, setVariant] = useState("panel");
|
|
294
|
+
return (
|
|
295
|
+
<div className="grid gap-4">
|
|
296
|
+
<ToggleGroup size="sm" aria-label="Variant" value={variant} onChange={setVariant} items={VARIANTS} className="justify-self-start" />
|
|
297
|
+
{variant === "panel" ? <PanelDemo /> : null}
|
|
298
|
+
{variant === "photos" ? <PhotosDemo /> : null}
|
|
299
|
+
{variant === "copy" ? <CopyDemo /> : null}
|
|
300
|
+
</div>
|
|
301
|
+
);
|
|
302
|
+
}
|