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,41 @@
|
|
|
1
|
+
// The FlowCanvas block — `makersclaw add flow-canvas`. Fixed: compose it
|
|
2
|
+
// through its props (README.md beside this file). The board helpers are
|
|
3
|
+
// plain functions and work anywhere, the server included. The canvas
|
|
4
|
+
// blocks built on this one (account-map, process-map, journey-map,
|
|
5
|
+
// idea-board…) import it, never @xyflow/react directly.
|
|
6
|
+
export { FlowCanvas, useFlowCanvas } from "./flow-canvas";
|
|
7
|
+
export { useCanvas } from "./context";
|
|
8
|
+
export { NodeShell, NodeHandles, EditableText } from "./nodes";
|
|
9
|
+
export { Palette, StickySwatch, ColorDot, ShapeGlyph } from "./chrome";
|
|
10
|
+
export { colorClasses } from "./theme";
|
|
11
|
+
export {
|
|
12
|
+
GRID,
|
|
13
|
+
COLORS,
|
|
14
|
+
STICKY_COLORS,
|
|
15
|
+
COLOR_NAMES,
|
|
16
|
+
SHAPES,
|
|
17
|
+
emptyBoard,
|
|
18
|
+
createNode,
|
|
19
|
+
createEdge,
|
|
20
|
+
cleanBoard,
|
|
21
|
+
readBoard,
|
|
22
|
+
boardToText,
|
|
23
|
+
boardToMarkdown,
|
|
24
|
+
describeNode,
|
|
25
|
+
nodeText,
|
|
26
|
+
autoLayout,
|
|
27
|
+
alignNodes,
|
|
28
|
+
distributeNodes,
|
|
29
|
+
duplicateNodes,
|
|
30
|
+
removeNodes,
|
|
31
|
+
frameContents,
|
|
32
|
+
frameOf,
|
|
33
|
+
nodeRect,
|
|
34
|
+
boardBounds,
|
|
35
|
+
snapPoint,
|
|
36
|
+
snapToCell,
|
|
37
|
+
fitFontSize,
|
|
38
|
+
historyInit,
|
|
39
|
+
historyReducer,
|
|
40
|
+
starterTemplates,
|
|
41
|
+
} from "./board";
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// The built-in node types — sticky, shape, text, frame, card, image — and
|
|
4
|
+
// the two pieces a block's own node types are made from:
|
|
5
|
+
//
|
|
6
|
+
// NodeShell the chrome every node wears: the selection box, the four
|
|
7
|
+
// connection dots that show on hover, the resize handles,
|
|
8
|
+
// the lock mark, and the whole-card drop target while a
|
|
9
|
+
// connector is being dragged. Wrap your node's body in it.
|
|
10
|
+
// EditableText words that edit in place, laid out the same way shown and
|
|
11
|
+
// edited so nothing jumps when a double-click starts typing.
|
|
12
|
+
//
|
|
13
|
+
// Colours are token names in the node's data (theme.js turns them into
|
|
14
|
+
// classes); nothing here holds a colour of its own.
|
|
15
|
+
import { useEffect, useLayoutEffect, useRef } from "react";
|
|
16
|
+
import { Handle, NodeResizer, Position } from "@xyflow/react";
|
|
17
|
+
import { Badge, Icon, Image, cx } from "../../ui";
|
|
18
|
+
import { TEXT_SIZE_PX, fitFontSize } from "./board";
|
|
19
|
+
import { useCanvas } from "./context";
|
|
20
|
+
import { EDGE, FILL, SOLID, STROKE, TINT, WASH, tone } from "./theme";
|
|
21
|
+
|
|
22
|
+
// The dots sit just outside each side, so they never cover the words.
|
|
23
|
+
const DOT =
|
|
24
|
+
"size-3! min-w-0! min-h-0! rounded-full! border-2! border-primary! bg-background! opacity-0 transition-[opacity,scale] duration-150 motion-reduce:transition-none " +
|
|
25
|
+
"hover:scale-125 group-hover/node:opacity-100 [[data-connecting=true]_&]:opacity-100 [[data-tool=connector]_&]:opacity-100";
|
|
26
|
+
const SIDES = [
|
|
27
|
+
[Position.Top, "top", "-top-2!"],
|
|
28
|
+
[Position.Right, "right", "-right-2!"],
|
|
29
|
+
[Position.Bottom, "bottom", "-bottom-2!"],
|
|
30
|
+
[Position.Left, "left", "-left-2!"],
|
|
31
|
+
];
|
|
32
|
+
// While a connector is in the air (or the connector tool is on), the whole
|
|
33
|
+
// card is one big invisible handle: drop anywhere on it to connect.
|
|
34
|
+
const BODY =
|
|
35
|
+
"absolute! inset-0! top-0! left-0! size-full! min-w-0! min-h-0! [transform:none]! rounded-none! border-0! bg-transparent! opacity-0! z-10";
|
|
36
|
+
|
|
37
|
+
/** The four connection dots. NodeShell draws them; a node that does not
|
|
38
|
+
* use NodeShell must draw these, or connectors cannot reach it. */
|
|
39
|
+
export function NodeHandles() {
|
|
40
|
+
return SIDES.map(([pos, id, place]) => <Handle key={id} type="source" id={id} position={pos} className={cx(DOT, place)} />);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The chrome around a node. Props:
|
|
45
|
+
* id, selected from the node's props (React Flow passes them)
|
|
46
|
+
* locked data.locked: no resize, a lock mark when selected
|
|
47
|
+
* resizable true (default) · false; minWidth/minHeight (default
|
|
48
|
+
* 40/30), keepAspectRatio
|
|
49
|
+
* autoHeight the node's height follows its content (text, cards)
|
|
50
|
+
* handles false: nothing connects to this node
|
|
51
|
+
* ring false: no selection box (draw your own)
|
|
52
|
+
* className the body's layout (never colour)
|
|
53
|
+
*/
|
|
54
|
+
export function NodeShell({
|
|
55
|
+
id,
|
|
56
|
+
selected,
|
|
57
|
+
locked = false,
|
|
58
|
+
resizable = true,
|
|
59
|
+
minWidth = 40,
|
|
60
|
+
minHeight = 30,
|
|
61
|
+
keepAspectRatio = false,
|
|
62
|
+
autoHeight = false,
|
|
63
|
+
handles = true,
|
|
64
|
+
ring = true,
|
|
65
|
+
className,
|
|
66
|
+
children,
|
|
67
|
+
}) {
|
|
68
|
+
const { api, tool, readOnly, connecting } = useCanvas();
|
|
69
|
+
return (
|
|
70
|
+
<div className={cx("group/node relative", autoHeight ? "w-full" : "size-full", className)}>
|
|
71
|
+
{children}
|
|
72
|
+
{ring ? (
|
|
73
|
+
<span
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
className={cx(
|
|
76
|
+
"pointer-events-none absolute -inset-1 rounded-md transition-shadow duration-150 motion-reduce:transition-none",
|
|
77
|
+
selected ? "ring-2 ring-primary" : "ring-0 group-hover/node:ring-1 group-hover/node:ring-primary/50",
|
|
78
|
+
)}
|
|
79
|
+
/>
|
|
80
|
+
) : null}
|
|
81
|
+
{resizable && !readOnly ? (
|
|
82
|
+
<NodeResizer
|
|
83
|
+
isVisible={Boolean(selected) && !locked}
|
|
84
|
+
minWidth={minWidth}
|
|
85
|
+
minHeight={minHeight}
|
|
86
|
+
keepAspectRatio={keepAspectRatio}
|
|
87
|
+
onResizeEnd={() => api?.commit("resize", [id])}
|
|
88
|
+
/>
|
|
89
|
+
) : null}
|
|
90
|
+
{handles && !readOnly ? <NodeHandles /> : null}
|
|
91
|
+
{handles && !readOnly && (connecting || tool === "connector") ? <Handle type="source" id="body" position={Position.Top} className={BODY} /> : null}
|
|
92
|
+
{locked && selected ? (
|
|
93
|
+
<span className="pointer-events-none absolute -top-3 -right-3 grid size-6 place-items-center rounded-full border border-border bg-background text-muted-foreground shadow-sm">
|
|
94
|
+
<Icon name="lock" size={12} label="Locked" />
|
|
95
|
+
</span>
|
|
96
|
+
) : null}
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Words that edit in place. Shown and edited in the same box, with the
|
|
103
|
+
* same classes, so starting to type moves nothing.
|
|
104
|
+
* value, editing the words; true while being edited
|
|
105
|
+
* onChange(text) every keystroke (update the node's data)
|
|
106
|
+
* onDone() Esc, a click away, Enter (singleLine), ⌘Enter
|
|
107
|
+
* placeholder shown while empty (and while editing)
|
|
108
|
+
* singleLine Enter finishes (a title, a label)
|
|
109
|
+
* label the field's accessible name
|
|
110
|
+
*/
|
|
111
|
+
export function EditableText({ value, editing, onChange, onDone, placeholder, singleLine = false, label, className, style }) {
|
|
112
|
+
const ref = useRef(null);
|
|
113
|
+
useLayoutEffect(() => {
|
|
114
|
+
const el = ref.current;
|
|
115
|
+
if (!editing || !el) return;
|
|
116
|
+
el.innerText = value ?? "";
|
|
117
|
+
el.focus({ preventScroll: true });
|
|
118
|
+
// The caret at the end of the words, not the start.
|
|
119
|
+
const range = document.createRange();
|
|
120
|
+
range.selectNodeContents(el);
|
|
121
|
+
range.collapse(false);
|
|
122
|
+
const sel = window.getSelection();
|
|
123
|
+
sel?.removeAllRanges();
|
|
124
|
+
sel?.addRange(range);
|
|
125
|
+
// Only when editing starts: typing must not reset the caret.
|
|
126
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
127
|
+
}, [editing]);
|
|
128
|
+
|
|
129
|
+
if (!editing) {
|
|
130
|
+
return (
|
|
131
|
+
<div className={className} style={style}>
|
|
132
|
+
{value ? value : placeholder ? <span className="text-muted-foreground">{placeholder}</span> : null}
|
|
133
|
+
</div>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
return (
|
|
137
|
+
// raw: a contentEditable box, not the kit's Textarea — the words keep
|
|
138
|
+
// the exact size, place and wrapping they have on the card while they
|
|
139
|
+
// are typed (a field would add its own border, padding and height).
|
|
140
|
+
<div
|
|
141
|
+
ref={ref}
|
|
142
|
+
role="textbox"
|
|
143
|
+
aria-label={label}
|
|
144
|
+
aria-multiline={!singleLine}
|
|
145
|
+
contentEditable="plaintext-only"
|
|
146
|
+
suppressContentEditableWarning
|
|
147
|
+
data-placeholder={placeholder ?? ""}
|
|
148
|
+
className={cx(
|
|
149
|
+
className,
|
|
150
|
+
"nodrag nopan nowheel cursor-text select-text outline-none",
|
|
151
|
+
"empty:before:text-muted-foreground empty:before:content-[attr(data-placeholder)]",
|
|
152
|
+
)}
|
|
153
|
+
style={style}
|
|
154
|
+
onInput={(e) => onChange?.(e.currentTarget.innerText.replace(/\n$/, ""))}
|
|
155
|
+
onPaste={(e) => {
|
|
156
|
+
// Plain text only, in browsers without plaintext-only.
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
const text = e.clipboardData.getData("text/plain");
|
|
159
|
+
document.execCommand("insertText", false, singleLine ? text.replace(/\s*\n\s*/g, " ") : text);
|
|
160
|
+
}}
|
|
161
|
+
onKeyDown={(e) => {
|
|
162
|
+
e.stopPropagation();
|
|
163
|
+
if (e.nativeEvent.isComposing) return;
|
|
164
|
+
if (e.key === "Escape" || (e.key === "Enter" && (singleLine || e.metaKey || e.ctrlKey))) {
|
|
165
|
+
e.preventDefault();
|
|
166
|
+
e.currentTarget.blur();
|
|
167
|
+
}
|
|
168
|
+
}}
|
|
169
|
+
onBlur={() => onDone?.()}
|
|
170
|
+
onPointerDown={(e) => e.stopPropagation()}
|
|
171
|
+
/>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Editing helpers shared by the built-in nodes.
|
|
176
|
+
function useWords(id, key = "text") {
|
|
177
|
+
const { api, editingNode, readOnly } = useCanvas();
|
|
178
|
+
const editing = !readOnly && editingNode === id;
|
|
179
|
+
return {
|
|
180
|
+
editing,
|
|
181
|
+
onChange: (text) => api?.updateNodeData(id, { [key]: text }, { commit: false }),
|
|
182
|
+
onDone: () => api?.stopEditing(id),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ── sticky ───────────────────────────────────────────────────────────────
|
|
187
|
+
|
|
188
|
+
export function StickyNode({ id, data, selected, width, height }) {
|
|
189
|
+
const w = width ?? 200;
|
|
190
|
+
const h = height ?? 200;
|
|
191
|
+
const words = useWords(id);
|
|
192
|
+
const hasMeta = Boolean(data?.meta);
|
|
193
|
+
const size = fitFontSize(data?.text, w - 28, h - 28 - (hasMeta ? 18 : 0), { max: Math.min(30, Math.round(h / 5)) });
|
|
194
|
+
const badge = data?.badge != null && data.badge !== "" ? data.badge : null;
|
|
195
|
+
return (
|
|
196
|
+
<NodeShell id={id} selected={selected} locked={data?.locked} minWidth={80} minHeight={80}>
|
|
197
|
+
<div className="relative size-full overflow-hidden rounded-sm bg-card shadow-md transition-[box-shadow,translate] duration-150 group-hover/node:shadow-lg motion-reduce:transition-none">
|
|
198
|
+
<div aria-hidden="true" className={cx("absolute inset-0", tone(TINT, data?.color, "warning"))} />
|
|
199
|
+
<div className={cx("relative flex size-full items-center justify-center px-3.5", hasMeta ? "pt-3.5 pb-7" : "py-3.5")}>
|
|
200
|
+
<EditableText
|
|
201
|
+
{...words}
|
|
202
|
+
value={data?.text}
|
|
203
|
+
label="Sticky note"
|
|
204
|
+
placeholder={selected || words.editing ? "Type something" : ""}
|
|
205
|
+
className="max-h-full w-full overflow-hidden text-center leading-tight break-words whitespace-pre-wrap text-foreground"
|
|
206
|
+
style={{ fontSize: size }}
|
|
207
|
+
/>
|
|
208
|
+
</div>
|
|
209
|
+
{badge !== null ? (
|
|
210
|
+
<Badge variant="soft" className="absolute top-2 right-2 tabular-nums">
|
|
211
|
+
{badge}
|
|
212
|
+
</Badge>
|
|
213
|
+
) : null}
|
|
214
|
+
{hasMeta ? <span className="absolute right-3 bottom-2 left-3 truncate text-2xs text-muted-foreground">{data.meta}</span> : null}
|
|
215
|
+
</div>
|
|
216
|
+
</NodeShell>
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ── shape ────────────────────────────────────────────────────────────────
|
|
221
|
+
|
|
222
|
+
function Outline({ kind, w, h, className }) {
|
|
223
|
+
const i = 1;
|
|
224
|
+
if (kind === "ellipse") return <ellipse cx={w / 2} cy={h / 2} rx={w / 2 - i} ry={h / 2 - i} className={className} />;
|
|
225
|
+
if (kind === "diamond") return <polygon points={`${w / 2},${i} ${w - i},${h / 2} ${w / 2},${h - i} ${i},${h / 2}`} className={className} />;
|
|
226
|
+
const r = kind === "pill" ? (h - 2 * i) / 2 : Math.min(10, h / 6);
|
|
227
|
+
return <rect x={i} y={i} width={w - 2 * i} height={h - 2 * i} rx={r} className={className} />;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function ShapeNode({ id, data, selected, width, height }) {
|
|
231
|
+
const w = width ?? 160;
|
|
232
|
+
const h = height ?? 100;
|
|
233
|
+
const kind = data?.shape ?? "rect";
|
|
234
|
+
const words = useWords(id);
|
|
235
|
+
// A diamond's words live in its middle; an ellipse's a little inside.
|
|
236
|
+
const inset = kind === "diamond" ? { x: w * 0.22, y: h * 0.22 } : kind === "ellipse" ? { x: w * 0.12, y: h * 0.12 } : { x: 12, y: 8 };
|
|
237
|
+
const max = TEXT_SIZE_PX[data?.textSize] ?? TEXT_SIZE_PX.md;
|
|
238
|
+
const size = fitFontSize(data?.text, w - inset.x * 2, h - inset.y * 2, { max, min: 10 });
|
|
239
|
+
const color = data?.color ?? "muted";
|
|
240
|
+
return (
|
|
241
|
+
<NodeShell id={id} selected={selected} locked={data?.locked} minWidth={40} minHeight={30}>
|
|
242
|
+
{/* raw: the outline is geometry on a canvas (a diamond, an ellipse), which no kit part draws. */}
|
|
243
|
+
<svg width={w} height={h} className="absolute inset-0 overflow-visible drop-shadow-sm" aria-hidden="true">
|
|
244
|
+
<Outline kind={kind} w={w} h={h} className="fill-card" />
|
|
245
|
+
<Outline
|
|
246
|
+
kind={kind}
|
|
247
|
+
w={w}
|
|
248
|
+
h={h}
|
|
249
|
+
className={cx(tone(FILL, color), tone(STROKE, color), "[stroke-width:1.5] transition-[fill,stroke] duration-150 motion-reduce:transition-none")}
|
|
250
|
+
/>
|
|
251
|
+
</svg>
|
|
252
|
+
<div className="relative flex size-full items-center justify-center" style={{ padding: `${inset.y}px ${inset.x}px` }}>
|
|
253
|
+
<EditableText
|
|
254
|
+
{...words}
|
|
255
|
+
value={data?.text}
|
|
256
|
+
label={`${kind} text`}
|
|
257
|
+
placeholder={words.editing ? "Type something" : ""}
|
|
258
|
+
className="max-h-full w-full overflow-hidden text-center font-medium leading-tight break-words whitespace-pre-wrap text-foreground"
|
|
259
|
+
style={{ fontSize: size }}
|
|
260
|
+
/>
|
|
261
|
+
</div>
|
|
262
|
+
</NodeShell>
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ── text ─────────────────────────────────────────────────────────────────
|
|
267
|
+
|
|
268
|
+
const ALIGN = { left: "text-left", center: "text-center", right: "text-right" };
|
|
269
|
+
|
|
270
|
+
export function TextNode({ id, data, selected, height }) {
|
|
271
|
+
const words = useWords(id);
|
|
272
|
+
const size = TEXT_SIZE_PX[data?.textSize] ?? TEXT_SIZE_PX.md;
|
|
273
|
+
return (
|
|
274
|
+
<NodeShell id={id} selected={selected} locked={data?.locked} autoHeight={!height} minWidth={60} minHeight={20}>
|
|
275
|
+
<EditableText
|
|
276
|
+
{...words}
|
|
277
|
+
value={data?.text}
|
|
278
|
+
label="Text"
|
|
279
|
+
placeholder={words.editing ? "Type something" : "Empty text"}
|
|
280
|
+
className={cx(
|
|
281
|
+
"w-full px-1 py-0.5 leading-snug break-words whitespace-pre-wrap text-foreground",
|
|
282
|
+
ALIGN[data?.align] ?? ALIGN.left,
|
|
283
|
+
(data?.textSize === "lg" || data?.textSize === "xl") && "font-semibold tracking-tight",
|
|
284
|
+
)}
|
|
285
|
+
style={{ fontSize: size }}
|
|
286
|
+
/>
|
|
287
|
+
</NodeShell>
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// ── frame ────────────────────────────────────────────────────────────────
|
|
292
|
+
|
|
293
|
+
export function FrameNode({ id, data, selected }) {
|
|
294
|
+
const words = useWords(id, "title");
|
|
295
|
+
const color = data?.color;
|
|
296
|
+
return (
|
|
297
|
+
<NodeShell id={id} selected={selected} locked={data?.locked} minWidth={120} minHeight={80} ring={false}>
|
|
298
|
+
<div
|
|
299
|
+
aria-hidden="true"
|
|
300
|
+
className={cx(
|
|
301
|
+
"absolute inset-0 rounded-lg border-2 transition-colors duration-150 motion-reduce:transition-none",
|
|
302
|
+
color ? cx(tone(WASH, color), tone(EDGE, color)) : "border-border bg-card/70",
|
|
303
|
+
selected ? "border-primary!" : "",
|
|
304
|
+
)}
|
|
305
|
+
/>
|
|
306
|
+
{/* The edges take the pointer (drag the frame by its edge); the inside does not. */}
|
|
307
|
+
<span aria-hidden="true" className="pointer-events-auto absolute inset-x-0 -top-1 h-2" />
|
|
308
|
+
<span aria-hidden="true" className="pointer-events-auto absolute inset-x-0 -bottom-1 h-2" />
|
|
309
|
+
<span aria-hidden="true" className="pointer-events-auto absolute inset-y-0 -left-1 w-2" />
|
|
310
|
+
<span aria-hidden="true" className="pointer-events-auto absolute inset-y-0 -right-1 w-2" />
|
|
311
|
+
<div className="pointer-events-auto absolute -top-8 left-0 flex max-w-full items-center gap-1.5 rounded-md px-1 py-1 text-sm font-medium text-muted-foreground transition-colors duration-150 hover:text-foreground">
|
|
312
|
+
{color ? <span aria-hidden="true" className={cx("size-2.5 shrink-0 rounded-full", tone(SOLID, color))} /> : <Icon name="frame" size={14} />}
|
|
313
|
+
<EditableText {...words} singleLine value={data?.title} label="Frame title" placeholder="Untitled frame" className="min-w-8 truncate" />
|
|
314
|
+
</div>
|
|
315
|
+
</NodeShell>
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// ── card ─────────────────────────────────────────────────────────────────
|
|
320
|
+
|
|
321
|
+
/** The card a block fills: `renderCard(node, ctx)` on FlowCanvas draws its
|
|
322
|
+
* inside (kit parts: Avatar, Badge…); without it, a title and a body. */
|
|
323
|
+
export function CardNode({ id, type, data, selected, width, height }) {
|
|
324
|
+
const { renderCard, api } = useCanvas();
|
|
325
|
+
const words = useWords(id, "title");
|
|
326
|
+
const node = { id, type, data: data ?? {}, width, height };
|
|
327
|
+
const inner = renderCard
|
|
328
|
+
? renderCard(node, {
|
|
329
|
+
selected: Boolean(selected),
|
|
330
|
+
editing: words.editing,
|
|
331
|
+
update: (patch) => api?.updateNodeData(id, patch),
|
|
332
|
+
api,
|
|
333
|
+
})
|
|
334
|
+
: undefined;
|
|
335
|
+
const custom = inner !== undefined && inner !== null;
|
|
336
|
+
// A card the app draws has no words of ours to edit: hand editing back.
|
|
337
|
+
useEffect(() => {
|
|
338
|
+
if (custom && words.editing) api?.stopEditing(id);
|
|
339
|
+
}, [custom, words.editing, api, id]);
|
|
340
|
+
return (
|
|
341
|
+
<NodeShell id={id} selected={selected} locked={data?.locked} autoHeight={!height} minWidth={140} minHeight={60}>
|
|
342
|
+
<div
|
|
343
|
+
className={cx(
|
|
344
|
+
"w-full overflow-hidden rounded-lg border border-border bg-card text-card-foreground shadow-sm transition-shadow duration-150 group-hover/node:shadow-md motion-reduce:transition-none",
|
|
345
|
+
height ? "h-full" : "",
|
|
346
|
+
)}
|
|
347
|
+
>
|
|
348
|
+
{data?.color ? <div aria-hidden="true" className={cx("h-1", tone(SOLID, data.color))} /> : null}
|
|
349
|
+
{custom ? (
|
|
350
|
+
inner
|
|
351
|
+
) : (
|
|
352
|
+
<div className="grid gap-1 p-3">
|
|
353
|
+
<div className="flex items-start gap-2">
|
|
354
|
+
{data?.icon ? <Icon name={data.icon} size={16} className="mt-0.5 shrink-0 text-muted-foreground" /> : null}
|
|
355
|
+
<EditableText
|
|
356
|
+
{...words}
|
|
357
|
+
singleLine
|
|
358
|
+
value={data?.title}
|
|
359
|
+
label="Card title"
|
|
360
|
+
placeholder="Untitled"
|
|
361
|
+
className="min-w-0 flex-1 text-sm font-medium leading-snug break-words"
|
|
362
|
+
/>
|
|
363
|
+
{data?.badge ? <Badge variant="soft">{data.badge}</Badge> : null}
|
|
364
|
+
</div>
|
|
365
|
+
{data?.body ? <p className="text-sm leading-snug text-muted-foreground break-words whitespace-pre-wrap">{data.body}</p> : null}
|
|
366
|
+
</div>
|
|
367
|
+
)}
|
|
368
|
+
</div>
|
|
369
|
+
</NodeShell>
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// ── image ────────────────────────────────────────────────────────────────
|
|
374
|
+
|
|
375
|
+
export function ImageNode({ id, data, selected }) {
|
|
376
|
+
return (
|
|
377
|
+
<NodeShell id={id} selected={selected} locked={data?.locked} keepAspectRatio minWidth={60} minHeight={40}>
|
|
378
|
+
<div className="size-full overflow-hidden rounded-md bg-card shadow-md">
|
|
379
|
+
<Image src={data?.src || undefined} alt={data?.alt ?? ""} fit="cover" rounded="md" loading="eager" className="size-full" draggable={false} />
|
|
380
|
+
</div>
|
|
381
|
+
</NodeShell>
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export const BUILT_IN_NODES = {
|
|
386
|
+
sticky: StickyNode,
|
|
387
|
+
shape: ShapeNode,
|
|
388
|
+
text: TextNode,
|
|
389
|
+
frame: FrameNode,
|
|
390
|
+
card: CardNode,
|
|
391
|
+
image: ImageNode,
|
|
392
|
+
};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// React Flow in the workspace theme — the one place its look is mapped.
|
|
2
|
+
//
|
|
3
|
+
// React Flow paints itself from CSS variables (--xy-background-pattern-
|
|
4
|
+
// color, --xy-selection-border…) and a few fixed rules in its stylesheet
|
|
5
|
+
// (@xyflow/react/dist/style.css, imported by flow-canvas.jsx). Each one is
|
|
6
|
+
// pointed at a token here, as Tailwind arbitrary properties on the flow's
|
|
7
|
+
// root. Every class ends in `!`: the library's stylesheet is unlayered, and
|
|
8
|
+
// an unlayered rule beats any Tailwind utility (those live in @layer
|
|
9
|
+
// utilities) whatever its specificity; `!important` inside a layer is the
|
|
10
|
+
// one thing that outranks it. Our own nodes and connectors draw with
|
|
11
|
+
// token classes directly (nodes.jsx, edges.jsx), so the library's node and
|
|
12
|
+
// edge colours are never seen.
|
|
13
|
+
export const THEME = [
|
|
14
|
+
// the canvas: the page's background with dots in the muted ink
|
|
15
|
+
"[--xy-background-color:transparent]!",
|
|
16
|
+
"[--xy-background-pattern-color:var(--color-muted-foreground)]!",
|
|
17
|
+
"[&_.react-flow__background]:opacity-35!",
|
|
18
|
+
// the marquee, and the box around a multi-selection
|
|
19
|
+
"[&_.react-flow__selection]:bg-primary/8!",
|
|
20
|
+
"[&_.react-flow__selection]:border!",
|
|
21
|
+
"[&_.react-flow__selection]:border-solid!",
|
|
22
|
+
"[&_.react-flow__selection]:border-primary/70!",
|
|
23
|
+
"[&_.react-flow__selection]:rounded-sm!",
|
|
24
|
+
"[&_.react-flow__nodesselection-rect]:bg-transparent!",
|
|
25
|
+
"[&_.react-flow__nodesselection-rect]:border!",
|
|
26
|
+
"[&_.react-flow__nodesselection-rect]:border-dashed!",
|
|
27
|
+
"[&_.react-flow__nodesselection-rect]:border-primary/60!",
|
|
28
|
+
"[&_.react-flow__nodesselection-rect]:rounded-sm!",
|
|
29
|
+
// the line drawn while a connector is being dragged out
|
|
30
|
+
"[&_.react-flow__connection-path]:stroke-primary!",
|
|
31
|
+
"[&_.react-flow__connection-path]:[stroke-width:2]!",
|
|
32
|
+
// cursors that match the tool (flow-canvas.jsx sets data-tool on the root)
|
|
33
|
+
"[&_.react-flow__pane.selection]:cursor-default!",
|
|
34
|
+
"[&_.react-flow__node.draggable]:cursor-default!",
|
|
35
|
+
"[&_.react-flow__node.draggable.dragging]:cursor-grabbing!",
|
|
36
|
+
"data-[tool=hand]:[&_.react-flow__pane]:cursor-grab!",
|
|
37
|
+
"data-[tool=hand]:[&_.react-flow__pane.dragging]:cursor-grabbing!",
|
|
38
|
+
"data-[tool=hand]:[&_.react-flow__node]:cursor-grab!",
|
|
39
|
+
"data-[tool=place]:[&_.react-flow__pane]:cursor-crosshair!",
|
|
40
|
+
"data-[tool=text]:[&_.react-flow__pane]:cursor-text!",
|
|
41
|
+
"data-[tool=connector]:[&_.react-flow__node]:cursor-crosshair!",
|
|
42
|
+
// keyboard focus on a card: a visible ring (the library turns it off)
|
|
43
|
+
"[&_.react-flow__node:focus-visible]:outline-2!",
|
|
44
|
+
"[&_.react-flow__node:focus-visible]:outline-offset-4!",
|
|
45
|
+
"[&_.react-flow__node:focus-visible]:outline-ring!",
|
|
46
|
+
"[&_.react-flow__node:focus-visible]:[outline-style:solid]!",
|
|
47
|
+
// frames: only their title and edge take the pointer, so a double-click
|
|
48
|
+
// or a marquee inside one lands on the canvas (nodes.jsx)
|
|
49
|
+
"[&_.react-flow__node-frame]:pointer-events-none!",
|
|
50
|
+
// the resize handles on a selected card
|
|
51
|
+
"[&_.react-flow__resize-control.handle]:size-2.5!",
|
|
52
|
+
"[&_.react-flow__resize-control.handle]:rounded-xs!",
|
|
53
|
+
"[&_.react-flow__resize-control.handle]:border-primary!",
|
|
54
|
+
"[&_.react-flow__resize-control.handle]:bg-background!",
|
|
55
|
+
"[&_.react-flow__resize-control.handle]:pointer-events-auto!",
|
|
56
|
+
"[&_.react-flow__resize-control.line]:border-primary/0!",
|
|
57
|
+
"[&_.react-flow__resize-control.line]:pointer-events-auto!",
|
|
58
|
+
"[&_.react-flow__resize-control.line.left]:w-2!",
|
|
59
|
+
"[&_.react-flow__resize-control.line.right]:w-2!",
|
|
60
|
+
"[&_.react-flow__resize-control.line.top]:h-2!",
|
|
61
|
+
"[&_.react-flow__resize-control.line.bottom]:h-2!",
|
|
62
|
+
// the minimap: a card with the board in muted ink
|
|
63
|
+
"[--xy-minimap-background-color:var(--color-card)]!",
|
|
64
|
+
"[--xy-minimap-node-background-color:var(--color-muted-foreground)]!",
|
|
65
|
+
"[--xy-minimap-mask-background-color:var(--color-muted)]!",
|
|
66
|
+
"[&_.react-flow__minimap]:rounded-lg!",
|
|
67
|
+
"[&_.react-flow__minimap]:border!",
|
|
68
|
+
"[&_.react-flow__minimap]:border-border!",
|
|
69
|
+
"[&_.react-flow__minimap]:shadow-md!",
|
|
70
|
+
"[&_.react-flow__minimap]:overflow-hidden!",
|
|
71
|
+
"[&_.react-flow__minimap-node]:opacity-50!",
|
|
72
|
+
"[&_.react-flow__minimap-mask]:opacity-70!",
|
|
73
|
+
// React Flow's credit: kept (they ask for it), in the muted ink
|
|
74
|
+
"[&_.react-flow__attribution]:bg-transparent!",
|
|
75
|
+
"[&_.react-flow__attribution_a]:text-muted-foreground!",
|
|
76
|
+
// panels: ours sit in the corners with our own spacing
|
|
77
|
+
"[&_.react-flow__panel]:m-3!",
|
|
78
|
+
].join(" ");
|
|
79
|
+
|
|
80
|
+
// Colour TOKENS → classes, written out whole so Tailwind generates them. A
|
|
81
|
+
// board stores the token name ("chart-3", "warning"); these turn it into
|
|
82
|
+
// paint. A sticky is the card surface with the hue laid over it, so it
|
|
83
|
+
// reads the same on a light or a dark workspace.
|
|
84
|
+
export const TINT = {
|
|
85
|
+
warning: "bg-warning/35",
|
|
86
|
+
"chart-1": "bg-chart-1/25",
|
|
87
|
+
"chart-2": "bg-chart-2/30",
|
|
88
|
+
"chart-3": "bg-chart-3/30",
|
|
89
|
+
"chart-4": "bg-chart-4/30",
|
|
90
|
+
"chart-5": "bg-chart-5/30",
|
|
91
|
+
success: "bg-success/30",
|
|
92
|
+
info: "bg-info/30",
|
|
93
|
+
destructive: "bg-destructive/25",
|
|
94
|
+
muted: "bg-muted",
|
|
95
|
+
};
|
|
96
|
+
/** A full-strength dot of the colour: the palette's swatches. */
|
|
97
|
+
export const SOLID = {
|
|
98
|
+
warning: "bg-warning",
|
|
99
|
+
"chart-1": "bg-chart-1",
|
|
100
|
+
"chart-2": "bg-chart-2",
|
|
101
|
+
"chart-3": "bg-chart-3",
|
|
102
|
+
"chart-4": "bg-chart-4",
|
|
103
|
+
"chart-5": "bg-chart-5",
|
|
104
|
+
success: "bg-success",
|
|
105
|
+
info: "bg-info",
|
|
106
|
+
destructive: "bg-destructive",
|
|
107
|
+
muted: "bg-muted-foreground/40",
|
|
108
|
+
};
|
|
109
|
+
/** Shapes (svg): a tinted fill over the card surface, the hue as the edge. */
|
|
110
|
+
export const FILL = {
|
|
111
|
+
warning: "fill-warning/35",
|
|
112
|
+
"chart-1": "fill-chart-1/25",
|
|
113
|
+
"chart-2": "fill-chart-2/30",
|
|
114
|
+
"chart-3": "fill-chart-3/30",
|
|
115
|
+
"chart-4": "fill-chart-4/30",
|
|
116
|
+
"chart-5": "fill-chart-5/30",
|
|
117
|
+
success: "fill-success/30",
|
|
118
|
+
info: "fill-info/30",
|
|
119
|
+
destructive: "fill-destructive/25",
|
|
120
|
+
muted: "fill-muted",
|
|
121
|
+
};
|
|
122
|
+
export const STROKE = {
|
|
123
|
+
warning: "stroke-warning",
|
|
124
|
+
"chart-1": "stroke-chart-1",
|
|
125
|
+
"chart-2": "stroke-chart-2",
|
|
126
|
+
"chart-3": "stroke-chart-3",
|
|
127
|
+
"chart-4": "stroke-chart-4",
|
|
128
|
+
"chart-5": "stroke-chart-5",
|
|
129
|
+
success: "stroke-success",
|
|
130
|
+
info: "stroke-info",
|
|
131
|
+
destructive: "stroke-destructive",
|
|
132
|
+
muted: "stroke-border",
|
|
133
|
+
};
|
|
134
|
+
/** A frame's faint wash of its colour (none: the plain card surface). */
|
|
135
|
+
export const WASH = {
|
|
136
|
+
warning: "bg-warning/8",
|
|
137
|
+
"chart-1": "bg-chart-1/8",
|
|
138
|
+
"chart-2": "bg-chart-2/8",
|
|
139
|
+
"chart-3": "bg-chart-3/8",
|
|
140
|
+
"chart-4": "bg-chart-4/8",
|
|
141
|
+
"chart-5": "bg-chart-5/8",
|
|
142
|
+
success: "bg-success/8",
|
|
143
|
+
info: "bg-info/8",
|
|
144
|
+
destructive: "bg-destructive/8",
|
|
145
|
+
muted: "bg-muted/60",
|
|
146
|
+
};
|
|
147
|
+
/** A frame's edge in its colour. */
|
|
148
|
+
export const EDGE = {
|
|
149
|
+
warning: "border-warning/60",
|
|
150
|
+
"chart-1": "border-chart-1/60",
|
|
151
|
+
"chart-2": "border-chart-2/60",
|
|
152
|
+
"chart-3": "border-chart-3/60",
|
|
153
|
+
"chart-4": "border-chart-4/60",
|
|
154
|
+
"chart-5": "border-chart-5/60",
|
|
155
|
+
success: "border-success/60",
|
|
156
|
+
info: "border-info/60",
|
|
157
|
+
destructive: "border-destructive/60",
|
|
158
|
+
muted: "border-border",
|
|
159
|
+
};
|
|
160
|
+
/** An unknown token falls back to this. */
|
|
161
|
+
export const tone = (map, token, fallback = "muted") => map[token] ?? map[fallback];
|
|
162
|
+
|
|
163
|
+
/** Every class for one colour token, for a block's own node types:
|
|
164
|
+
* colorClasses("chart-3").tint → "bg-chart-3/30". */
|
|
165
|
+
export function colorClasses(token) {
|
|
166
|
+
return {
|
|
167
|
+
tint: tone(TINT, token),
|
|
168
|
+
solid: tone(SOLID, token),
|
|
169
|
+
fill: tone(FILL, token),
|
|
170
|
+
stroke: tone(STROKE, token),
|
|
171
|
+
wash: tone(WASH, token),
|
|
172
|
+
edge: tone(EDGE, token),
|
|
173
|
+
};
|
|
174
|
+
}
|