makersclaw 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD-PARTY-NOTICES.md +180 -0
- package/package.json +3 -2
- package/r/annotate.json +62 -0
- package/r/approval-request.json +52 -0
- package/r/audio-player.json +74 -0
- package/r/auth-form.json +55 -0
- package/r/board.json +10 -6
- package/r/calendar-view.json +105 -0
- package/r/cart.json +62 -0
- package/r/chart.json +83 -0
- package/r/chat.json +95 -0
- package/r/code-editor.json +94 -0
- package/r/comment-box.json +64 -0
- package/r/contact-section.json +53 -0
- package/r/core.json +205 -8
- package/r/csv-import.json +63 -0
- package/r/data-table.json +69 -0
- package/r/diagram.json +74 -0
- package/r/doc-editor.json +82 -0
- package/r/doc-page.json +61 -0
- package/r/email-render.json +73 -0
- package/r/faq.json +50 -0
- package/r/file-upload.json +54 -0
- package/r/flow-canvas.json +93 -0
- package/r/footer.json +52 -0
- package/r/gantt.json +70 -0
- package/r/job-panel.json +12 -7
- package/r/json-editor.json +66 -0
- package/r/map.json +89 -0
- package/r/menubar.json +52 -0
- package/r/mind-map.json +67 -0
- package/r/navigation-menu.json +52 -0
- package/r/order-detail.json +54 -0
- package/r/org-chart.json +66 -0
- package/r/page-builder.json +105 -0
- package/r/payment-methods.json +51 -0
- package/r/pdf-document.json +79 -0
- package/r/pdf-viewer.json +88 -0
- package/r/product-detail.json +76 -0
- package/r/product-grid.json +65 -0
- package/r/record-form.json +67 -0
- package/r/record-notes.json +55 -0
- package/r/registry.json +3411 -29
- package/r/search-dialog.json +51 -0
- package/r/settings-list.json +66 -0
- package/r/setup-checklist.json +51 -0
- package/r/share-dialog.json +52 -0
- package/r/sidebar.json +69 -0
- package/r/signature-pad.json +72 -0
- package/r/sketch-canvas.json +99 -0
- package/r/spreadsheet.json +90 -0
- package/r/stat-cards.json +66 -0
- package/r/task-list.json +63 -0
- package/r/task-model.json +98 -0
- package/r/testimonials.json +52 -0
- package/r/transaction-list.json +53 -0
- package/r/whiteboard.json +66 -0
- package/registry/blocks/annotate/README.md +179 -0
- package/registry/blocks/annotate/annotate-data.js +250 -0
- package/registry/blocks/annotate/annotate.jsx +646 -0
- package/registry/blocks/annotate/block.json +10 -0
- package/registry/blocks/annotate/demo.jsx +135 -0
- package/registry/blocks/annotate/index.js +15 -0
- package/registry/blocks/approval-request/README.md +116 -0
- package/registry/blocks/approval-request/approval-request.jsx +386 -0
- package/registry/blocks/approval-request/block.json +10 -0
- package/registry/blocks/approval-request/demo.jsx +127 -0
- package/registry/blocks/approval-request/index.js +4 -0
- package/registry/blocks/audio-player/README.md +167 -0
- package/registry/blocks/audio-player/audio-player.jsx +623 -0
- package/registry/blocks/audio-player/block.json +14 -0
- package/registry/blocks/audio-player/colors.js +109 -0
- package/registry/blocks/audio-player/demo.jsx +209 -0
- package/registry/blocks/audio-player/index.js +6 -0
- package/registry/blocks/audio-player/time.js +67 -0
- package/registry/blocks/audio-player/wavesurfer.js +9 -0
- package/registry/blocks/auth-form/README.md +126 -0
- package/registry/blocks/auth-form/auth-form.jsx +568 -0
- package/registry/blocks/auth-form/block.json +10 -0
- package/registry/blocks/auth-form/demo.jsx +131 -0
- package/registry/blocks/auth-form/index.js +3 -0
- package/registry/blocks/board/README.md +55 -5
- package/registry/blocks/board/block.json +2 -2
- package/registry/blocks/board/board.jsx +230 -86
- package/registry/blocks/board/demo.jsx +103 -24
- package/registry/blocks/calendar-view/README.md +180 -0
- package/registry/blocks/calendar-view/agenda.jsx +147 -0
- package/registry/blocks/calendar-view/block.json +76 -0
- package/registry/blocks/calendar-view/calendar-model.js +442 -0
- package/registry/blocks/calendar-view/calendar.jsx +627 -0
- package/registry/blocks/calendar-view/demo.jsx +195 -0
- package/registry/blocks/calendar-view/draft.jsx +49 -0
- package/registry/blocks/calendar-view/index.js +39 -0
- package/registry/blocks/calendar-view/month.jsx +346 -0
- package/registry/blocks/calendar-view/paint.js +69 -0
- package/registry/blocks/calendar-view/time-grid.jsx +527 -0
- package/registry/blocks/calendar-view/tray.jsx +87 -0
- package/registry/blocks/cart/README.md +146 -0
- package/registry/blocks/cart/block.json +10 -0
- package/registry/blocks/cart/cart.jsx +597 -0
- package/registry/blocks/cart/demo.jsx +98 -0
- package/registry/blocks/cart/index.js +4 -0
- package/registry/blocks/cart/money.js +28 -0
- package/registry/blocks/chart/README.md +316 -0
- package/registry/blocks/chart/block.json +10 -0
- package/registry/blocks/chart/cartesian.jsx +642 -0
- package/registry/blocks/chart/core.jsx +262 -0
- package/registry/blocks/chart/demo.jsx +357 -0
- package/registry/blocks/chart/heatmap.jsx +336 -0
- package/registry/blocks/chart/index.js +8 -0
- package/registry/blocks/chart/pie.jsx +245 -0
- package/registry/blocks/chart/sparkline.jsx +88 -0
- package/registry/blocks/chat/README.md +273 -0
- package/registry/blocks/chat/attachment.jsx +95 -0
- package/registry/blocks/chat/block.json +10 -0
- package/registry/blocks/chat/chat.jsx +132 -0
- package/registry/blocks/chat/composer.jsx +364 -0
- package/registry/blocks/chat/demo.jsx +578 -0
- package/registry/blocks/chat/header.jsx +34 -0
- package/registry/blocks/chat/index.js +9 -0
- package/registry/blocks/chat/message.jsx +450 -0
- package/registry/blocks/chat/scroller.jsx +247 -0
- package/registry/blocks/chat/text.jsx +104 -0
- package/registry/blocks/code-editor/README.md +210 -0
- package/registry/blocks/code-editor/block.json +22 -0
- package/registry/blocks/code-editor/code-editor.jsx +534 -0
- package/registry/blocks/code-editor/codemirror.js +38 -0
- package/registry/blocks/code-editor/demo.jsx +205 -0
- package/registry/blocks/code-editor/index.js +8 -0
- package/registry/blocks/code-editor/json.js +317 -0
- package/registry/blocks/code-editor/sql.js +136 -0
- package/registry/blocks/code-editor/text.js +101 -0
- package/registry/blocks/code-editor/theme.js +186 -0
- package/registry/blocks/comment-box/README.md +123 -0
- package/registry/blocks/comment-box/block.json +10 -0
- package/registry/blocks/comment-box/comment-body.jsx +217 -0
- package/registry/blocks/comment-box/comment-box.jsx +198 -0
- package/registry/blocks/comment-box/comment-time.jsx +77 -0
- package/registry/blocks/comment-box/demo.jsx +141 -0
- package/registry/blocks/comment-box/index.js +8 -0
- package/registry/blocks/contact-section/README.md +152 -0
- package/registry/blocks/contact-section/block.json +11 -0
- package/registry/blocks/contact-section/contact-section.jsx +509 -0
- package/registry/blocks/contact-section/demo.jsx +93 -0
- package/registry/blocks/contact-section/index.js +4 -0
- package/registry/blocks/csv-import/README.md +133 -0
- package/registry/blocks/csv-import/block.json +13 -0
- package/registry/blocks/csv-import/csv-import.jsx +479 -0
- package/registry/blocks/csv-import/demo.jsx +106 -0
- package/registry/blocks/csv-import/import.js +200 -0
- package/registry/blocks/csv-import/index.js +7 -0
- package/registry/blocks/data-table/README.md +386 -0
- package/registry/blocks/data-table/block.json +10 -0
- package/registry/blocks/data-table/data-table.jsx +1164 -0
- package/registry/blocks/data-table/demo.jsx +588 -0
- package/registry/blocks/data-table/index.js +5 -0
- package/registry/blocks/data-table/model.js +169 -0
- package/registry/blocks/diagram/README.md +108 -0
- package/registry/blocks/diagram/block.json +13 -0
- package/registry/blocks/diagram/demo.jsx +113 -0
- package/registry/blocks/diagram/diagram.jsx +481 -0
- package/registry/blocks/diagram/index.js +7 -0
- package/registry/blocks/diagram/mermaid.js +52 -0
- package/registry/blocks/diagram/palette.js +313 -0
- package/registry/blocks/diagram/source.js +98 -0
- package/registry/blocks/doc-editor/README.md +215 -0
- package/registry/blocks/doc-editor/block.json +15 -0
- package/registry/blocks/doc-editor/demo.jsx +225 -0
- package/registry/blocks/doc-editor/doc-editor.jsx +291 -0
- package/registry/blocks/doc-editor/doc.js +309 -0
- package/registry/blocks/doc-editor/index.js +7 -0
- package/registry/blocks/doc-editor/schema.jsx +56 -0
- package/registry/blocks/doc-editor/shadcn-classes.js +110 -0
- package/registry/blocks/doc-editor/theme.js +82 -0
- package/registry/blocks/doc-page/README.md +119 -0
- package/registry/blocks/doc-page/autosave.js +104 -0
- package/registry/blocks/doc-page/block.json +10 -0
- package/registry/blocks/doc-page/demo.jsx +137 -0
- package/registry/blocks/doc-page/doc-page.jsx +276 -0
- package/registry/blocks/doc-page/index.js +4 -0
- package/registry/blocks/email-render/README.md +151 -0
- package/registry/blocks/email-render/block.json +14 -0
- package/registry/blocks/email-render/demo.jsx +153 -0
- package/registry/blocks/email-render/doc-email.jsx +210 -0
- package/registry/blocks/email-render/email.jsx +221 -0
- package/registry/blocks/email-render/index.js +10 -0
- package/registry/blocks/email-render/render.js +50 -0
- package/registry/blocks/email-render/theme.js +215 -0
- package/registry/blocks/faq/README.md +101 -0
- package/registry/blocks/faq/block.json +11 -0
- package/registry/blocks/faq/demo.jsx +89 -0
- package/registry/blocks/faq/faq.jsx +220 -0
- package/registry/blocks/faq/index.js +4 -0
- package/registry/blocks/file-upload/README.md +138 -0
- package/registry/blocks/file-upload/block.json +10 -0
- package/registry/blocks/file-upload/demo.jsx +204 -0
- package/registry/blocks/file-upload/file-upload.jsx +635 -0
- package/registry/blocks/file-upload/index.js +4 -0
- package/registry/blocks/flow-canvas/README.md +420 -0
- package/registry/blocks/flow-canvas/block.json +13 -0
- package/registry/blocks/flow-canvas/board.js +819 -0
- package/registry/blocks/flow-canvas/chrome.jsx +649 -0
- package/registry/blocks/flow-canvas/context.jsx +35 -0
- package/registry/blocks/flow-canvas/demo.jsx +249 -0
- package/registry/blocks/flow-canvas/edges.jsx +107 -0
- package/registry/blocks/flow-canvas/flow-canvas.jsx +1329 -0
- package/registry/blocks/flow-canvas/index.js +41 -0
- package/registry/blocks/flow-canvas/nodes.jsx +392 -0
- package/registry/blocks/flow-canvas/theme.js +174 -0
- package/registry/blocks/footer/README.md +133 -0
- package/registry/blocks/footer/block.json +11 -0
- package/registry/blocks/footer/demo.jsx +119 -0
- package/registry/blocks/footer/footer.jsx +406 -0
- package/registry/blocks/footer/index.js +4 -0
- package/registry/blocks/gantt/README.md +220 -0
- package/registry/blocks/gantt/block.json +10 -0
- package/registry/blocks/gantt/demo.jsx +148 -0
- package/registry/blocks/gantt/gantt.jsx +923 -0
- package/registry/blocks/gantt/index.js +7 -0
- package/registry/blocks/gantt/rows.jsx +468 -0
- package/registry/blocks/gantt/schedule.js +278 -0
- package/registry/blocks/job-panel/README.md +80 -0
- package/registry/blocks/job-panel/block.json +3 -3
- package/registry/blocks/job-panel/demo.jsx +230 -3
- package/registry/blocks/job-panel/job-panel.jsx +169 -3
- package/registry/blocks/json-editor/README.md +133 -0
- package/registry/blocks/json-editor/block.json +10 -0
- package/registry/blocks/json-editor/demo.jsx +92 -0
- package/registry/blocks/json-editor/index.js +7 -0
- package/registry/blocks/json-editor/json-editor.jsx +305 -0
- package/registry/blocks/json-editor/json-tree.jsx +393 -0
- package/registry/blocks/json-editor/tree.js +225 -0
- package/registry/blocks/map/README.md +221 -0
- package/registry/blocks/map/block.json +14 -0
- package/registry/blocks/map/demo.jsx +201 -0
- package/registry/blocks/map/geo.js +198 -0
- package/registry/blocks/map/index.js +8 -0
- package/registry/blocks/map/list.jsx +128 -0
- package/registry/blocks/map/map-view.jsx +715 -0
- package/registry/blocks/map/maplibre.js +30 -0
- package/registry/blocks/map/marks.jsx +146 -0
- package/registry/blocks/map/theme.js +142 -0
- package/registry/blocks/menubar/README.md +109 -0
- package/registry/blocks/menubar/block.json +10 -0
- package/registry/blocks/menubar/demo.jsx +128 -0
- package/registry/blocks/menubar/index.js +4 -0
- package/registry/blocks/menubar/menubar.jsx +199 -0
- package/registry/blocks/mind-map/README.md +206 -0
- package/registry/blocks/mind-map/block.json +10 -0
- package/registry/blocks/mind-map/demo.jsx +103 -0
- package/registry/blocks/mind-map/index.js +31 -0
- package/registry/blocks/mind-map/mind-map.jsx +1125 -0
- package/registry/blocks/mind-map/topic.jsx +143 -0
- package/registry/blocks/mind-map/tree.js +645 -0
- package/registry/blocks/navigation-menu/README.md +124 -0
- package/registry/blocks/navigation-menu/block.json +10 -0
- package/registry/blocks/navigation-menu/demo.jsx +84 -0
- package/registry/blocks/navigation-menu/index.js +4 -0
- package/registry/blocks/navigation-menu/navigation-menu.jsx +448 -0
- package/registry/blocks/order-detail/README.md +109 -0
- package/registry/blocks/order-detail/block.json +10 -0
- package/registry/blocks/order-detail/demo.jsx +88 -0
- package/registry/blocks/order-detail/index.js +4 -0
- package/registry/blocks/order-detail/order-detail.jsx +354 -0
- package/registry/blocks/org-chart/README.md +145 -0
- package/registry/blocks/org-chart/block.json +10 -0
- package/registry/blocks/org-chart/demo.jsx +94 -0
- package/registry/blocks/org-chart/index.js +7 -0
- package/registry/blocks/org-chart/org-chart.jsx +631 -0
- package/registry/blocks/org-chart/org.js +245 -0
- package/registry/blocks/org-chart/person.jsx +96 -0
- package/registry/blocks/page-builder/README.md +257 -0
- package/registry/blocks/page-builder/block.json +14 -0
- package/registry/blocks/page-builder/demo.jsx +145 -0
- package/registry/blocks/page-builder/grapes.js +18 -0
- package/registry/blocks/page-builder/index.js +11 -0
- package/registry/blocks/page-builder/page-builder.jsx +704 -0
- package/registry/blocks/page-builder/page-view.jsx +33 -0
- package/registry/blocks/page-builder/page.js +118 -0
- package/registry/blocks/page-builder/panels.jsx +588 -0
- package/registry/blocks/page-builder/sections.js +209 -0
- package/registry/blocks/page-builder/theme.js +87 -0
- package/registry/blocks/page-builder/thumbs.jsx +189 -0
- package/registry/blocks/page-builder/tokens.js +329 -0
- package/registry/blocks/payment-methods/README.md +104 -0
- package/registry/blocks/payment-methods/block.json +10 -0
- package/registry/blocks/payment-methods/demo.jsx +71 -0
- package/registry/blocks/payment-methods/index.js +4 -0
- package/registry/blocks/payment-methods/payment-methods.jsx +302 -0
- package/registry/blocks/pdf-document/README.md +213 -0
- package/registry/blocks/pdf-document/block.json +13 -0
- package/registry/blocks/pdf-document/demo.jsx +136 -0
- package/registry/blocks/pdf-document/index.js +33 -0
- package/registry/blocks/pdf-document/money.js +83 -0
- package/registry/blocks/pdf-document/pdf-document.jsx +144 -0
- package/registry/blocks/pdf-document/primitives.jsx +271 -0
- package/registry/blocks/pdf-document/quote.jsx +179 -0
- package/registry/blocks/pdf-document/theme.js +193 -0
- package/registry/blocks/pdf-viewer/README.md +191 -0
- package/registry/blocks/pdf-viewer/block.json +14 -0
- package/registry/blocks/pdf-viewer/demo.jsx +252 -0
- package/registry/blocks/pdf-viewer/helpers.js +270 -0
- package/registry/blocks/pdf-viewer/index.js +8 -0
- package/registry/blocks/pdf-viewer/notes.jsx +195 -0
- package/registry/blocks/pdf-viewer/pdf-viewer.jsx +1368 -0
- package/registry/blocks/pdf-viewer/pdfjs.js +37 -0
- package/registry/blocks/pdf-viewer/ssr-shim-end.js +6 -0
- package/registry/blocks/pdf-viewer/ssr-shim.js +44 -0
- package/registry/blocks/product-detail/README.md +217 -0
- package/registry/blocks/product-detail/block.json +10 -0
- package/registry/blocks/product-detail/demo.jsx +233 -0
- package/registry/blocks/product-detail/index.js +7 -0
- package/registry/blocks/product-detail/price.jsx +115 -0
- package/registry/blocks/product-detail/product-detail.jsx +348 -0
- package/registry/blocks/product-detail/product-media.jsx +102 -0
- package/registry/blocks/product-detail/product-options.jsx +144 -0
- package/registry/blocks/product-grid/README.md +162 -0
- package/registry/blocks/product-grid/block.json +10 -0
- package/registry/blocks/product-grid/demo.jsx +255 -0
- package/registry/blocks/product-grid/index.js +5 -0
- package/registry/blocks/product-grid/product-card.jsx +232 -0
- package/registry/blocks/product-grid/product-grid.jsx +235 -0
- package/registry/blocks/record-form/README.md +196 -0
- package/registry/blocks/record-form/block.json +10 -0
- package/registry/blocks/record-form/demo.jsx +525 -0
- package/registry/blocks/record-form/index.js +4 -0
- package/registry/blocks/record-form/record-fields.jsx +457 -0
- package/registry/blocks/record-form/record-form.jsx +415 -0
- package/registry/blocks/record-form/rules.js +81 -0
- package/registry/blocks/record-notes/README.md +139 -0
- package/registry/blocks/record-notes/block.json +10 -0
- package/registry/blocks/record-notes/demo.jsx +179 -0
- package/registry/blocks/record-notes/index.js +4 -0
- package/registry/blocks/record-notes/record-notes.jsx +266 -0
- package/registry/blocks/search-dialog/README.md +108 -0
- package/registry/blocks/search-dialog/block.json +10 -0
- package/registry/blocks/search-dialog/demo.jsx +116 -0
- package/registry/blocks/search-dialog/index.js +3 -0
- package/registry/blocks/search-dialog/search-dialog.jsx +235 -0
- package/registry/blocks/settings-list/README.md +171 -0
- package/registry/blocks/settings-list/block.json +10 -0
- package/registry/blocks/settings-list/demo.jsx +333 -0
- package/registry/blocks/settings-list/index.js +4 -0
- package/registry/blocks/settings-list/row-state.jsx +93 -0
- package/registry/blocks/settings-list/settings-list.jsx +349 -0
- package/registry/blocks/settings-list/settings-matrix.jsx +118 -0
- package/registry/blocks/setup-checklist/README.md +142 -0
- package/registry/blocks/setup-checklist/block.json +10 -0
- package/registry/blocks/setup-checklist/demo.jsx +159 -0
- package/registry/blocks/setup-checklist/index.js +4 -0
- package/registry/blocks/setup-checklist/setup-checklist.jsx +446 -0
- package/registry/blocks/share-dialog/README.md +113 -0
- package/registry/blocks/share-dialog/block.json +10 -0
- package/registry/blocks/share-dialog/demo.jsx +140 -0
- package/registry/blocks/share-dialog/index.js +3 -0
- package/registry/blocks/share-dialog/share-dialog.jsx +384 -0
- package/registry/blocks/sidebar/README.md +190 -0
- package/registry/blocks/sidebar/block.json +43 -0
- package/registry/blocks/sidebar/demo.jsx +577 -0
- package/registry/blocks/sidebar/index.js +4 -0
- package/registry/blocks/sidebar/sidebar-panel.jsx +149 -0
- package/registry/blocks/sidebar/sidebar.jsx +864 -0
- package/registry/blocks/signature-pad/README.md +137 -0
- package/registry/blocks/signature-pad/block.json +13 -0
- package/registry/blocks/signature-pad/colors.js +115 -0
- package/registry/blocks/signature-pad/demo.jsx +94 -0
- package/registry/blocks/signature-pad/index.js +6 -0
- package/registry/blocks/signature-pad/pad.js +7 -0
- package/registry/blocks/signature-pad/signature-pad.jsx +434 -0
- package/registry/blocks/signature-pad/signature.js +68 -0
- package/registry/blocks/sketch-canvas/README.md +280 -0
- package/registry/blocks/sketch-canvas/block.json +13 -0
- package/registry/blocks/sketch-canvas/demo.jsx +159 -0
- package/registry/blocks/sketch-canvas/excalidraw.js +40 -0
- package/registry/blocks/sketch-canvas/index.js +9 -0
- package/registry/blocks/sketch-canvas/palette.js +226 -0
- package/registry/blocks/sketch-canvas/sketch-canvas.jsx +1188 -0
- package/registry/blocks/sketch-canvas/sketch.js +179 -0
- package/registry/blocks/sketch-canvas/ssr-shim-end.js +6 -0
- package/registry/blocks/sketch-canvas/ssr-shim.js +45 -0
- package/registry/blocks/sketch-canvas/stamps.js +104 -0
- package/registry/blocks/sketch-canvas/theme.js +131 -0
- package/registry/blocks/spreadsheet/README.md +307 -0
- package/registry/blocks/spreadsheet/block.json +13 -0
- package/registry/blocks/spreadsheet/cells.jsx +455 -0
- package/registry/blocks/spreadsheet/chrome.jsx +325 -0
- package/registry/blocks/spreadsheet/demo.jsx +177 -0
- package/registry/blocks/spreadsheet/grid.js +387 -0
- package/registry/blocks/spreadsheet/index.js +34 -0
- package/registry/blocks/spreadsheet/spreadsheet.jsx +1732 -0
- package/registry/blocks/spreadsheet/types.js +473 -0
- package/registry/blocks/stat-cards/README.md +173 -0
- package/registry/blocks/stat-cards/block.json +10 -0
- package/registry/blocks/stat-cards/demo.jsx +257 -0
- package/registry/blocks/stat-cards/index.js +4 -0
- package/registry/blocks/stat-cards/stat-cards.jsx +307 -0
- package/registry/blocks/stat-cards/usage.jsx +243 -0
- package/registry/blocks/task-list/README.md +176 -0
- package/registry/blocks/task-list/block.json +10 -0
- package/registry/blocks/task-list/demo.jsx +134 -0
- package/registry/blocks/task-list/index.js +5 -0
- package/registry/blocks/task-list/task-list.jsx +907 -0
- package/registry/blocks/task-model/README.md +455 -0
- package/registry/blocks/task-model/block.json +167 -0
- package/registry/blocks/task-model/changes.js +89 -0
- package/registry/blocks/task-model/dates.js +371 -0
- package/registry/blocks/task-model/demo.jsx +215 -0
- package/registry/blocks/task-model/dnd.jsx +240 -0
- package/registry/blocks/task-model/index.js +97 -0
- package/registry/blocks/task-model/model.js +919 -0
- package/registry/blocks/task-model/parts.jsx +449 -0
- package/registry/blocks/task-model/toolbar.jsx +271 -0
- package/registry/blocks/testimonials/README.md +139 -0
- package/registry/blocks/testimonials/block.json +11 -0
- package/registry/blocks/testimonials/demo.jsx +137 -0
- package/registry/blocks/testimonials/index.js +4 -0
- package/registry/blocks/testimonials/testimonials.jsx +430 -0
- package/registry/blocks/transaction-list/README.md +126 -0
- package/registry/blocks/transaction-list/block.json +10 -0
- package/registry/blocks/transaction-list/demo.jsx +79 -0
- package/registry/blocks/transaction-list/index.js +4 -0
- package/registry/blocks/transaction-list/transaction-list.jsx +383 -0
- package/registry/blocks/whiteboard/README.md +179 -0
- package/registry/blocks/whiteboard/block.json +10 -0
- package/registry/blocks/whiteboard/demo.jsx +169 -0
- package/registry/blocks/whiteboard/index.js +6 -0
- package/registry/blocks/whiteboard/templates.js +150 -0
- package/registry/blocks/whiteboard/whiteboard.jsx +721 -0
- package/src/cli.mjs +19 -6
- package/src/install.mjs +18 -0
- package/src/registry.mjs +38 -4
- package/src/shadcn.mjs +14 -1
- package/templates/next/files/README.md +145 -11
- package/templates/next/files/app/globals.css +55 -4
- package/templates/next/files/check/run.mjs +3 -3
- package/templates/next/files/components/ui/avatar.jsx +141 -0
- package/templates/next/files/components/ui/breadcrumb.jsx +149 -0
- package/templates/next/files/components/ui/button-group.jsx +70 -0
- package/templates/next/files/components/ui/button.jsx +132 -12
- package/templates/next/files/components/ui/calendar.jsx +609 -0
- package/templates/next/files/components/ui/carousel.jsx +281 -0
- package/templates/next/files/components/ui/collapsible.jsx +208 -0
- package/templates/next/files/components/ui/combobox.jsx +608 -0
- package/templates/next/files/components/ui/command.jsx +577 -0
- package/templates/next/files/components/ui/context-menu.jsx +191 -0
- package/templates/next/files/components/ui/date-picker.jsx +360 -0
- package/templates/next/files/components/ui/distribution.jsx +117 -0
- package/templates/next/files/components/ui/feedback.jsx +143 -0
- package/templates/next/files/components/ui/field.jsx +115 -3
- package/templates/next/files/components/ui/file-input.jsx +234 -0
- package/templates/next/files/components/ui/icon.jsx +130 -8
- package/templates/next/files/components/ui/image.jsx +143 -0
- package/templates/next/files/components/ui/index.js +47 -2
- package/templates/next/files/components/ui/input-group.jsx +213 -0
- package/templates/next/files/components/ui/input-otp.jsx +170 -0
- package/templates/next/files/components/ui/item.jsx +206 -0
- package/templates/next/files/components/ui/menu.jsx +454 -82
- package/templates/next/files/components/ui/notice.jsx +126 -14
- package/templates/next/files/components/ui/pagination.jsx +156 -0
- package/templates/next/files/components/ui/popover.jsx +284 -0
- package/templates/next/files/components/ui/radio.jsx +193 -0
- package/templates/next/files/components/ui/rating.jsx +131 -0
- package/templates/next/files/components/ui/resizable.jsx +338 -0
- package/templates/next/files/components/ui/scroll-area.jsx +123 -0
- package/templates/next/files/components/ui/separator.jsx +119 -0
- package/templates/next/files/components/ui/sheet.jsx +96 -11
- package/templates/next/files/components/ui/slider.jsx +174 -0
- package/templates/next/files/components/ui/stat.jsx +574 -0
- package/templates/next/files/components/ui/steps.jsx +338 -0
- package/templates/next/files/components/ui/swatch.jsx +33 -0
- package/templates/next/files/components/ui/table.jsx +130 -0
- package/templates/next/files/components/ui/toast.jsx +440 -0
- package/templates/next/files/components/ui/toggle.jsx +195 -0
- package/templates/next/files/components/ui/tooltip.jsx +270 -0
- package/templates/next/template.json +264 -8
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// Diagram — Mermaid text drawn in the workspace theme, with zoom and pan.
|
|
4
|
+
//
|
|
5
|
+
// Client only, one static bundle: Mermaid needs the DOM to measure text,
|
|
6
|
+
// and the app's check refuses import() (so no next/dynamic). The modules
|
|
7
|
+
// load with the page; the drawing happens after the first effect (the
|
|
8
|
+
// mount guard). Until then — on the server and in the first client paint —
|
|
9
|
+
// the frame shows the Mermaid text itself, so the HTML already says what
|
|
10
|
+
// the diagram is.
|
|
11
|
+
//
|
|
12
|
+
// Colours: the tokens are read from the page at run time (palette.js) and
|
|
13
|
+
// handed to Mermaid as its theme; a change of workspace theme or of
|
|
14
|
+
// light/dark reads them again and redraws.
|
|
15
|
+
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
16
|
+
import { Button, Empty, Icon, IconButton, Menu, Notice, Skeleton, ToggleGroup, cx, toast } from "../../ui";
|
|
17
|
+
import { renderMermaid } from "./mermaid";
|
|
18
|
+
import { mermaidTheme, paletteKey, resolvePalette } from "./palette";
|
|
19
|
+
import { diagramKind, diagramTitle } from "./source";
|
|
20
|
+
|
|
21
|
+
const PAD = 24;
|
|
22
|
+
const MIN_K = 0.2;
|
|
23
|
+
const MAX_K = 4;
|
|
24
|
+
const px = (v) => (typeof v === "number" ? `${v}px` : v);
|
|
25
|
+
const clamp = (v, a, b) => Math.max(a, Math.min(b, v));
|
|
26
|
+
|
|
27
|
+
// The layout effect runs only in the browser; on the server it would warn.
|
|
28
|
+
const useIsoLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
29
|
+
|
|
30
|
+
export function Diagram(props) {
|
|
31
|
+
const [mounted, setMounted] = useState(false);
|
|
32
|
+
useEffect(() => setMounted(true), []);
|
|
33
|
+
if (!mounted) return <DiagramPlaceholder {...props} />;
|
|
34
|
+
return <LiveDiagram {...props} />;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const FRAME = "flex min-w-0 flex-col overflow-hidden rounded-lg border border-border bg-card text-card-foreground";
|
|
38
|
+
|
|
39
|
+
function heading(source, title) {
|
|
40
|
+
return title ?? diagramTitle(source) ?? diagramKind(source) ?? "Diagram";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** What the server renders: the frame, its heading, and the Mermaid text. */
|
|
44
|
+
function DiagramPlaceholder({ source = "", title, height, minHeight = 160, toolbar = true, className }) {
|
|
45
|
+
const kind = diagramKind(source);
|
|
46
|
+
return (
|
|
47
|
+
<figure className={cx(FRAME, className)} aria-busy="true">
|
|
48
|
+
{toolbar ? (
|
|
49
|
+
<figcaption className="flex min-h-12 items-center gap-2 border-b border-border ps-4 pe-2">
|
|
50
|
+
<span className="truncate text-sm font-medium">{heading(source, title)}</span>
|
|
51
|
+
{kind && title ? <span className="truncate text-xs text-muted-foreground max-sm:hidden">{kind}</span> : null}
|
|
52
|
+
</figcaption>
|
|
53
|
+
) : null}
|
|
54
|
+
<pre className="overflow-hidden px-4 py-3 font-mono text-xs leading-relaxed text-muted-foreground" style={height != null ? { height: px(height) } : { minHeight: px(minHeight), maxHeight: px(minHeight * 2) }}>
|
|
55
|
+
{source}
|
|
56
|
+
</pre>
|
|
57
|
+
</figure>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function LiveDiagram({ source = "", title, label, height, minHeight = 160, maxHeight = 560, toolbar = true, look = "classic", onRender, className }) {
|
|
62
|
+
const frame = useRef(null);
|
|
63
|
+
const viewport = useRef(null);
|
|
64
|
+
const content = useRef(null);
|
|
65
|
+
const [palette, setPalette] = useState(null);
|
|
66
|
+
const [result, setResult] = useState(null);
|
|
67
|
+
const [good, setGood] = useState(null);
|
|
68
|
+
const [size, setSize] = useState(null);
|
|
69
|
+
const [box, setBox] = useState({ w: 0, h: 0 });
|
|
70
|
+
const [t, setT] = useState({ k: 1, x: 0, y: 0 });
|
|
71
|
+
const [pristine, setPristine] = useState(true);
|
|
72
|
+
const [smooth, setSmooth] = useState(false);
|
|
73
|
+
const [tab, setTab] = useState("diagram");
|
|
74
|
+
const [dragging, setDragging] = useState(false);
|
|
75
|
+
const onRenderRef = useRef(onRender);
|
|
76
|
+
onRenderRef.current = onRender;
|
|
77
|
+
|
|
78
|
+
// The tokens, read now and again whenever the theme may have changed.
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const el = frame.current;
|
|
81
|
+
let raf = 0;
|
|
82
|
+
const read = () => {
|
|
83
|
+
cancelAnimationFrame(raf);
|
|
84
|
+
raf = requestAnimationFrame(() => {
|
|
85
|
+
const p = resolvePalette(el);
|
|
86
|
+
setPalette((prev) => (prev && paletteKey(prev) === paletteKey(p) ? prev : p));
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
read();
|
|
90
|
+
const mo = new MutationObserver(read);
|
|
91
|
+
const attrs = { attributes: true, attributeFilter: ["class", "style", "data-theme"] };
|
|
92
|
+
mo.observe(document.documentElement, attrs);
|
|
93
|
+
mo.observe(document.head, { childList: true });
|
|
94
|
+
const themed = el.parentElement?.closest("[data-theme]");
|
|
95
|
+
if (themed) mo.observe(themed, attrs);
|
|
96
|
+
const mq = window.matchMedia?.("(prefers-color-scheme: dark)");
|
|
97
|
+
mq?.addEventListener?.("change", read);
|
|
98
|
+
// A theme stylesheet that finishes loading changes the tokens too.
|
|
99
|
+
const onLoad = (e) => {
|
|
100
|
+
if (e.target?.tagName === "LINK") read();
|
|
101
|
+
};
|
|
102
|
+
document.addEventListener("load", onLoad, true);
|
|
103
|
+
return () => {
|
|
104
|
+
cancelAnimationFrame(raf);
|
|
105
|
+
mo.disconnect();
|
|
106
|
+
mq?.removeEventListener?.("change", read);
|
|
107
|
+
document.removeEventListener("load", onLoad, true);
|
|
108
|
+
};
|
|
109
|
+
}, []);
|
|
110
|
+
|
|
111
|
+
// Draw: after the text rests for a moment (someone may be typing it).
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (!palette) return;
|
|
114
|
+
if (!source.trim()) {
|
|
115
|
+
setResult(null);
|
|
116
|
+
setGood(null);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
let live = true;
|
|
120
|
+
const timer = setTimeout(() => {
|
|
121
|
+
const font = getComputedStyle(frame.current).fontFamily;
|
|
122
|
+
renderMermaid(source, { themeVariables: mermaidTheme(palette, { fontFamily: font }), look, fontFamily: font }).then((r) => {
|
|
123
|
+
if (!live) return;
|
|
124
|
+
setResult(r);
|
|
125
|
+
if (r.ok) setGood(r.svg);
|
|
126
|
+
onRenderRef.current?.(r);
|
|
127
|
+
});
|
|
128
|
+
}, result ? 150 : 0);
|
|
129
|
+
return () => {
|
|
130
|
+
live = false;
|
|
131
|
+
clearTimeout(timer);
|
|
132
|
+
};
|
|
133
|
+
// `result` only picks the delay; it must not redraw.
|
|
134
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
135
|
+
}, [source, palette, look]);
|
|
136
|
+
|
|
137
|
+
// The drawing's own size, once it is in the page; Mermaid's width="100%"
|
|
138
|
+
// and max-width are taken off so zoom is ours.
|
|
139
|
+
useIsoLayoutEffect(() => {
|
|
140
|
+
const svg = content.current?.querySelector("svg");
|
|
141
|
+
if (!svg) return;
|
|
142
|
+
const vb = svg.viewBox?.baseVal;
|
|
143
|
+
let w = vb?.width || 0;
|
|
144
|
+
let h = vb?.height || 0;
|
|
145
|
+
if (!w || !h) {
|
|
146
|
+
const r = svg.getBoundingClientRect();
|
|
147
|
+
w = r.width || 400;
|
|
148
|
+
h = r.height || 300;
|
|
149
|
+
}
|
|
150
|
+
svg.style.maxWidth = "none";
|
|
151
|
+
svg.setAttribute("width", String(w));
|
|
152
|
+
svg.setAttribute("height", String(h));
|
|
153
|
+
svg.setAttribute("aria-hidden", "true");
|
|
154
|
+
setSize((s) => (s && s.w === w && s.h === h ? s : { w, h }));
|
|
155
|
+
}, [good, tab]);
|
|
156
|
+
|
|
157
|
+
// The viewport's size.
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
const el = viewport.current;
|
|
160
|
+
if (!el) return;
|
|
161
|
+
const measure = () => setBox((b) => (b.w === el.clientWidth && b.h === el.clientHeight ? b : { w: el.clientWidth, h: el.clientHeight }));
|
|
162
|
+
measure();
|
|
163
|
+
const ro = new ResizeObserver(measure);
|
|
164
|
+
ro.observe(el);
|
|
165
|
+
return () => ro.disconnect();
|
|
166
|
+
}, [tab, good]);
|
|
167
|
+
|
|
168
|
+
// How tall the canvas is: `height`, else the drawing at the width's fit.
|
|
169
|
+
const autoH = size && box.w ? size.h * Math.min(1, (box.w - 2 * PAD) / size.w) + 2 * PAD : minHeight;
|
|
170
|
+
const canvasH = height != null ? px(height) : `${Math.round(clamp(autoH, minHeight, maxHeight))}px`;
|
|
171
|
+
|
|
172
|
+
const fitted = () => {
|
|
173
|
+
if (!size || !box.w || !box.h) return null;
|
|
174
|
+
const k = clamp(Math.min(1, (box.w - 2 * PAD) / size.w, (box.h - 2 * PAD) / size.h), MIN_K, MAX_K);
|
|
175
|
+
return { k, x: (box.w - size.w * k) / 2, y: (box.h - size.h * k) / 2 };
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// Untouched, the drawing follows the frame (a resize, a new drawing).
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
if (!pristine) return;
|
|
181
|
+
const f = fitted();
|
|
182
|
+
if (f) setT(f);
|
|
183
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
184
|
+
}, [size, box.w, box.h, pristine]);
|
|
185
|
+
|
|
186
|
+
const glide = () => {
|
|
187
|
+
setSmooth(true);
|
|
188
|
+
setTimeout(() => setSmooth(false), 180);
|
|
189
|
+
};
|
|
190
|
+
const zoomAt = (factor, cx0 = box.w / 2, cy0 = box.h / 2, animate = true) => {
|
|
191
|
+
setPristine(false);
|
|
192
|
+
if (animate) glide();
|
|
193
|
+
setT((cur) => {
|
|
194
|
+
const k = clamp(cur.k * factor, MIN_K, MAX_K);
|
|
195
|
+
return { k, x: cx0 - ((cx0 - cur.x) * k) / cur.k, y: cy0 - ((cy0 - cur.y) * k) / cur.k };
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
const fit = () => {
|
|
199
|
+
glide();
|
|
200
|
+
setPristine(true);
|
|
201
|
+
const f = fitted();
|
|
202
|
+
if (f) setT(f);
|
|
203
|
+
};
|
|
204
|
+
const actual = () => {
|
|
205
|
+
if (!size) return;
|
|
206
|
+
glide();
|
|
207
|
+
setPristine(false);
|
|
208
|
+
setT({ k: 1, x: (box.w - size.w) / 2, y: (box.h - size.h) / 2 });
|
|
209
|
+
};
|
|
210
|
+
const pan = (dx, dy) => {
|
|
211
|
+
setPristine(false);
|
|
212
|
+
setT((cur) => ({ ...cur, x: cur.x + dx, y: cur.y + dy }));
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// Pointer: drag pans; two fingers pinch; Cmd/Ctrl+wheel (and a trackpad
|
|
216
|
+
// pinch) zooms at the pointer. A plain wheel scrolls the page, as it should.
|
|
217
|
+
const pointers = useRef(new Map());
|
|
218
|
+
const gesture = useRef(null);
|
|
219
|
+
const local = (e) => {
|
|
220
|
+
const r = viewport.current.getBoundingClientRect();
|
|
221
|
+
return { x: e.clientX - r.left, y: e.clientY - r.top };
|
|
222
|
+
};
|
|
223
|
+
const onPointerDown = (e) => {
|
|
224
|
+
if (e.button !== 0 || !good) return;
|
|
225
|
+
viewport.current.setPointerCapture?.(e.pointerId);
|
|
226
|
+
pointers.current.set(e.pointerId, local(e));
|
|
227
|
+
const pts = [...pointers.current.values()];
|
|
228
|
+
gesture.current = pts.length === 2 ? { pinch: Math.hypot(pts[0].x - pts[1].x, pts[0].y - pts[1].y), t } : { from: local(e), t };
|
|
229
|
+
setDragging(true);
|
|
230
|
+
};
|
|
231
|
+
const onPointerMove = (e) => {
|
|
232
|
+
if (!pointers.current.has(e.pointerId) || !gesture.current) return;
|
|
233
|
+
pointers.current.set(e.pointerId, local(e));
|
|
234
|
+
const pts = [...pointers.current.values()];
|
|
235
|
+
const g = gesture.current;
|
|
236
|
+
setPristine(false);
|
|
237
|
+
if (pts.length === 2 && g.pinch) {
|
|
238
|
+
const d = Math.hypot(pts[0].x - pts[1].x, pts[0].y - pts[1].y);
|
|
239
|
+
const mid = { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 };
|
|
240
|
+
const k = clamp(g.t.k * (d / g.pinch), MIN_K, MAX_K);
|
|
241
|
+
setT({ k, x: mid.x - ((mid.x - g.t.x) * k) / g.t.k, y: mid.y - ((mid.y - g.t.y) * k) / g.t.k });
|
|
242
|
+
} else if (g.from) {
|
|
243
|
+
const p = local(e);
|
|
244
|
+
setT({ ...g.t, x: g.t.x + p.x - g.from.x, y: g.t.y + p.y - g.from.y });
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
const onPointerUp = (e) => {
|
|
248
|
+
pointers.current.delete(e.pointerId);
|
|
249
|
+
const pts = [...pointers.current.values()];
|
|
250
|
+
gesture.current = pts.length === 1 ? { from: pts[0], t } : null;
|
|
251
|
+
if (!pts.length) setDragging(false);
|
|
252
|
+
};
|
|
253
|
+
useEffect(() => {
|
|
254
|
+
const el = viewport.current;
|
|
255
|
+
if (!el) return;
|
|
256
|
+
const onWheel = (e) => {
|
|
257
|
+
if (!(e.ctrlKey || e.metaKey)) return;
|
|
258
|
+
e.preventDefault();
|
|
259
|
+
const r = el.getBoundingClientRect();
|
|
260
|
+
zoomAt(Math.exp(-e.deltaY * 0.01), e.clientX - r.left, e.clientY - r.top, false);
|
|
261
|
+
};
|
|
262
|
+
el.addEventListener("wheel", onWheel, { passive: false });
|
|
263
|
+
return () => el.removeEventListener("wheel", onWheel);
|
|
264
|
+
});
|
|
265
|
+
const onKeyDown = (e) => {
|
|
266
|
+
const step = e.shiftKey ? 160 : 48;
|
|
267
|
+
const keys = {
|
|
268
|
+
"+": () => zoomAt(1.25),
|
|
269
|
+
"=": () => zoomAt(1.25),
|
|
270
|
+
"-": () => zoomAt(0.8),
|
|
271
|
+
_: () => zoomAt(0.8),
|
|
272
|
+
0: fit,
|
|
273
|
+
1: actual,
|
|
274
|
+
ArrowLeft: () => pan(step, 0),
|
|
275
|
+
ArrowRight: () => pan(-step, 0),
|
|
276
|
+
ArrowUp: () => pan(0, step),
|
|
277
|
+
ArrowDown: () => pan(0, -step),
|
|
278
|
+
};
|
|
279
|
+
const fn = keys[e.key];
|
|
280
|
+
if (!fn || e.metaKey || e.ctrlKey || e.altKey) return;
|
|
281
|
+
e.preventDefault();
|
|
282
|
+
fn();
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
async function copy(text, what) {
|
|
286
|
+
try {
|
|
287
|
+
await navigator.clipboard.writeText(text);
|
|
288
|
+
toast.success(`Copied ${what}`);
|
|
289
|
+
} catch {
|
|
290
|
+
toast.error("Could not reach the clipboard");
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const download = () => {
|
|
294
|
+
const blob = new Blob([good], { type: "image/svg+xml" });
|
|
295
|
+
const url = URL.createObjectURL(blob);
|
|
296
|
+
const a = document.createElement("a");
|
|
297
|
+
a.href = url;
|
|
298
|
+
a.download = `${(title ?? diagramTitle(source) ?? diagramKind(source) ?? "diagram").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "diagram"}.svg`;
|
|
299
|
+
a.click();
|
|
300
|
+
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
const kind = diagramKind(source);
|
|
304
|
+
const error = result && !result.ok ? result.error : null;
|
|
305
|
+
const empty = !source.trim();
|
|
306
|
+
const name = label ?? `${heading(source, title)}${kind && title ? `, ${kind.toLowerCase()}` : ""}`;
|
|
307
|
+
|
|
308
|
+
return (
|
|
309
|
+
<figure ref={frame} className={cx(FRAME, className)}>
|
|
310
|
+
{toolbar ? (
|
|
311
|
+
<figcaption className="flex min-h-12 items-center gap-2 border-b border-border py-1.5 ps-4 pe-1.5">
|
|
312
|
+
<div className="me-auto flex min-w-0 items-baseline gap-2">
|
|
313
|
+
<span className="truncate text-sm font-medium">{heading(source, title)}</span>
|
|
314
|
+
{kind && title ? <span className="truncate text-xs text-muted-foreground max-sm:hidden">{kind}</span> : null}
|
|
315
|
+
</div>
|
|
316
|
+
<ToggleGroup
|
|
317
|
+
size="sm"
|
|
318
|
+
aria-label="Show"
|
|
319
|
+
value={tab}
|
|
320
|
+
onChange={setTab}
|
|
321
|
+
items={[
|
|
322
|
+
{ value: "diagram", label: "Diagram" },
|
|
323
|
+
{ value: "source", label: "Source" },
|
|
324
|
+
]}
|
|
325
|
+
/>
|
|
326
|
+
<Menu
|
|
327
|
+
label="Diagram actions"
|
|
328
|
+
items={[
|
|
329
|
+
{ label: "Copy Mermaid source", icon: "copy", disabled: empty, onSelect: () => copy(source, "the Mermaid source") },
|
|
330
|
+
{ label: "Copy SVG", icon: "code", disabled: !good, onSelect: () => copy(good, "the SVG") },
|
|
331
|
+
{ label: "Download SVG", icon: "download", disabled: !good, onSelect: download },
|
|
332
|
+
{ type: "separator" },
|
|
333
|
+
{ label: "Fit to view", icon: "maximize", shortcut: "0", disabled: !good || tab !== "diagram", onSelect: fit },
|
|
334
|
+
{ label: "Actual size", icon: "search", shortcut: "1", disabled: !good || tab !== "diagram", onSelect: actual },
|
|
335
|
+
]}
|
|
336
|
+
/>
|
|
337
|
+
</figcaption>
|
|
338
|
+
) : null}
|
|
339
|
+
|
|
340
|
+
{tab === "source" ? (
|
|
341
|
+
<SourceView source={source} errorLine={error?.line} height={height != null ? px(height) : canvasH} onCopy={() => copy(source, "the Mermaid source")} />
|
|
342
|
+
) : empty ? (
|
|
343
|
+
<div className="p-3">
|
|
344
|
+
<Empty icon="git-branch" title="No diagram yet" body="When there is Mermaid text — a flowchart, a sequence, a timeline — it is drawn here." />
|
|
345
|
+
</div>
|
|
346
|
+
) : (
|
|
347
|
+
// raw: the canvas — a focusable surface that pans and zooms with the
|
|
348
|
+
// pointer, wheel and keys; no kit part is a zoomable viewport.
|
|
349
|
+
<div
|
|
350
|
+
ref={viewport}
|
|
351
|
+
role="img"
|
|
352
|
+
aria-label={name}
|
|
353
|
+
aria-roledescription="diagram"
|
|
354
|
+
tabIndex={good ? 0 : -1}
|
|
355
|
+
onKeyDown={onKeyDown}
|
|
356
|
+
onPointerDown={onPointerDown}
|
|
357
|
+
onPointerMove={onPointerMove}
|
|
358
|
+
onPointerUp={onPointerUp}
|
|
359
|
+
onPointerCancel={onPointerUp}
|
|
360
|
+
onDoubleClick={(e) => {
|
|
361
|
+
if (!good) return;
|
|
362
|
+
const p = local(e);
|
|
363
|
+
zoomAt(e.shiftKey ? 0.5 : 2, p.x, p.y);
|
|
364
|
+
}}
|
|
365
|
+
className={cx(
|
|
366
|
+
"relative touch-none overflow-hidden outline-none select-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
|
|
367
|
+
"bg-[radial-gradient(var(--color-border)_1px,transparent_1px)] [background-size:16px_16px]",
|
|
368
|
+
good && (dragging ? "cursor-grabbing" : "cursor-grab"),
|
|
369
|
+
)}
|
|
370
|
+
style={{ height: canvasH }}
|
|
371
|
+
>
|
|
372
|
+
{good ? (
|
|
373
|
+
<div
|
|
374
|
+
ref={content}
|
|
375
|
+
className={cx("absolute left-0 top-0 origin-top-left will-change-transform", smooth && "transition-transform duration-150 ease-out motion-reduce:transition-none", error && "opacity-40")}
|
|
376
|
+
style={{ transform: `translate(${t.x}px, ${t.y}px) scale(${t.k})`, visibility: size ? "visible" : "hidden" }}
|
|
377
|
+
dangerouslySetInnerHTML={{ __html: good }}
|
|
378
|
+
/>
|
|
379
|
+
) : null}
|
|
380
|
+
|
|
381
|
+
{!result && !good ? (
|
|
382
|
+
<div className="absolute inset-0 grid place-items-center p-6" aria-busy="true">
|
|
383
|
+
<Skeleton shape="rect" className="h-full max-h-64 w-full max-w-md" />
|
|
384
|
+
<span className="sr-only">Drawing the diagram</span>
|
|
385
|
+
</div>
|
|
386
|
+
) : null}
|
|
387
|
+
|
|
388
|
+
{error && !good ? <ErrorPanel error={error} source={source} onShow={() => setTab("source")} /> : null}
|
|
389
|
+
|
|
390
|
+
{error && good ? (
|
|
391
|
+
<div className="absolute inset-x-3 top-3" onPointerDown={(e) => e.stopPropagation()}>
|
|
392
|
+
<Notice
|
|
393
|
+
tone="warning"
|
|
394
|
+
title={`${error.message} — showing the last version that worked`}
|
|
395
|
+
action={
|
|
396
|
+
<Button size="sm" variant="quiet" onClick={() => setTab("source")}>
|
|
397
|
+
Show source
|
|
398
|
+
</Button>
|
|
399
|
+
}
|
|
400
|
+
>
|
|
401
|
+
{error.detail}
|
|
402
|
+
</Notice>
|
|
403
|
+
</div>
|
|
404
|
+
) : null}
|
|
405
|
+
|
|
406
|
+
{good ? (
|
|
407
|
+
// raw: a floating cluster (the map-style zoom pill); its buttons are kit parts.
|
|
408
|
+
<div
|
|
409
|
+
className="absolute bottom-3 right-3 flex items-center gap-0.5 rounded-md border border-border bg-popover p-0.5 text-popover-foreground shadow-sm"
|
|
410
|
+
onPointerDown={(e) => e.stopPropagation()}
|
|
411
|
+
onDoubleClick={(e) => e.stopPropagation()}
|
|
412
|
+
>
|
|
413
|
+
<IconButton icon="minus" size="sm" label="Zoom out" onClick={() => zoomAt(0.8)} disabled={t.k <= MIN_K} />
|
|
414
|
+
<Button variant="quiet" size="sm" onClick={actual} className="tabular-nums max-sm:hidden" title="Actual size (1)">
|
|
415
|
+
{Math.round(t.k * 100)}%
|
|
416
|
+
</Button>
|
|
417
|
+
<IconButton icon="plus" size="sm" label="Zoom in" onClick={() => zoomAt(1.25)} disabled={t.k >= MAX_K} />
|
|
418
|
+
<IconButton icon="maximize" size="sm" label="Fit to view (0)" onClick={fit} />
|
|
419
|
+
</div>
|
|
420
|
+
) : null}
|
|
421
|
+
</div>
|
|
422
|
+
)}
|
|
423
|
+
</figure>
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/** A mistake with nothing drawn yet: what, where, and the lines around it. */
|
|
428
|
+
function ErrorPanel({ error, source, onShow }) {
|
|
429
|
+
const lines = source.split("\n");
|
|
430
|
+
const at = error.line ?? null;
|
|
431
|
+
const from = at ? Math.max(1, at - 2) : 1;
|
|
432
|
+
const to = at ? Math.min(lines.length, at + 2) : Math.min(lines.length, 5);
|
|
433
|
+
return (
|
|
434
|
+
<div className="absolute inset-0 overflow-auto p-4" onPointerDown={(e) => e.stopPropagation()}>
|
|
435
|
+
<div role="alert" className="mx-auto grid max-w-xl gap-3">
|
|
436
|
+
<div className="flex items-start gap-3">
|
|
437
|
+
<Icon name="warning" className="mt-0.5 shrink-0 text-destructive" />
|
|
438
|
+
<div className="min-w-0">
|
|
439
|
+
<p className="text-sm font-medium">{error.message}</p>
|
|
440
|
+
{error.detail ? <p className="mt-1 text-sm text-muted-foreground">{error.detail}</p> : null}
|
|
441
|
+
</div>
|
|
442
|
+
</div>
|
|
443
|
+
<pre className="overflow-x-auto rounded-md border border-border bg-background py-2 font-mono text-xs leading-relaxed">
|
|
444
|
+
{lines.slice(from - 1, to).map((l, i) => {
|
|
445
|
+
const n = from + i;
|
|
446
|
+
const bad = n === at;
|
|
447
|
+
return (
|
|
448
|
+
<div key={n} className={cx("flex pe-3", bad && "bg-destructive/10")}>
|
|
449
|
+
<span className={cx("w-10 shrink-0 pe-3 text-right tabular-nums select-none", bad ? "text-destructive" : "text-muted-foreground")}>{n}</span>
|
|
450
|
+
<span className="whitespace-pre">{l || " "}</span>
|
|
451
|
+
</div>
|
|
452
|
+
);
|
|
453
|
+
})}
|
|
454
|
+
</pre>
|
|
455
|
+
<div>
|
|
456
|
+
<Button size="sm" icon="code" onClick={onShow}>
|
|
457
|
+
Show source
|
|
458
|
+
</Button>
|
|
459
|
+
</div>
|
|
460
|
+
</div>
|
|
461
|
+
</div>
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/** The Mermaid text, numbered, the mistake's line marked. */
|
|
466
|
+
function SourceView({ source, errorLine, height, onCopy }) {
|
|
467
|
+
const lines = source.split("\n");
|
|
468
|
+
return (
|
|
469
|
+
<div className="relative">
|
|
470
|
+
<pre className="overflow-auto py-3 font-mono text-xs leading-relaxed" style={{ height }} tabIndex={0} aria-label="Mermaid source">
|
|
471
|
+
{lines.map((l, i) => (
|
|
472
|
+
<div key={i} className={cx("flex pe-12", errorLine === i + 1 && "bg-destructive/10")}>
|
|
473
|
+
<span className={cx("w-12 shrink-0 pe-3 text-right tabular-nums select-none", errorLine === i + 1 ? "text-destructive" : "text-muted-foreground")}>{i + 1}</span>
|
|
474
|
+
<span className="whitespace-pre">{l || " "}</span>
|
|
475
|
+
</div>
|
|
476
|
+
))}
|
|
477
|
+
</pre>
|
|
478
|
+
<IconButton icon="copy" size="sm" label="Copy source" onClick={onCopy} className="absolute right-2 top-2" />
|
|
479
|
+
</div>
|
|
480
|
+
);
|
|
481
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// The Diagram block — `makersclaw add diagram`. Fixed: compose it through
|
|
2
|
+
// its props (README.md beside this file). The helpers read Mermaid text
|
|
3
|
+
// anywhere, the server included; blocks built on this one draw through
|
|
4
|
+
// <Diagram>, never mermaid directly.
|
|
5
|
+
export { Diagram } from "./diagram";
|
|
6
|
+
export { diagramKind, diagramTitle, describeError } from "./source";
|
|
7
|
+
export { mermaidTheme } from "./palette";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// The one door to Mermaid (MIT). Every file in this block reaches it
|
|
2
|
+
// through here; a block built on this one renders through <Diagram>.
|
|
3
|
+
//
|
|
4
|
+
// Mermaid is one object for the whole page and its settings are global,
|
|
5
|
+
// so renders go through a queue: each one sets the theme it was asked
|
|
6
|
+
// for and draws, and the next waits. Mermaid loads on the server too (it
|
|
7
|
+
// touches no browser global while it loads — checked in node); it only
|
|
8
|
+
// ever renders in the browser, after the mount guard.
|
|
9
|
+
import mermaid from "mermaid";
|
|
10
|
+
import { describeError } from "./source";
|
|
11
|
+
|
|
12
|
+
let queue = Promise.resolve();
|
|
13
|
+
let seq = 0;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Draw Mermaid text. Resolves { ok: true, svg } or { ok: false, error:
|
|
17
|
+
* { line, message, detail } } — never rejects.
|
|
18
|
+
* themeVariables from mermaidTheme (palette.js)
|
|
19
|
+
* look "classic" (default) · "neo" · "handDrawn"
|
|
20
|
+
*/
|
|
21
|
+
export function renderMermaid(source, { themeVariables = {}, look = "classic", fontFamily } = {}) {
|
|
22
|
+
const job = queue.then(async () => {
|
|
23
|
+
const id = `mc-diagram-${Date.now().toString(36)}-${++seq}`;
|
|
24
|
+
try {
|
|
25
|
+
mermaid.initialize({
|
|
26
|
+
startOnLoad: false,
|
|
27
|
+
securityLevel: "strict",
|
|
28
|
+
theme: "base",
|
|
29
|
+
look,
|
|
30
|
+
themeVariables,
|
|
31
|
+
fontFamily: fontFamily || themeVariables.fontFamily,
|
|
32
|
+
suppressErrorRendering: true,
|
|
33
|
+
htmlLabels: true,
|
|
34
|
+
flowchart: { curve: "basis", padding: 12 },
|
|
35
|
+
sequence: { mirrorActors: false },
|
|
36
|
+
});
|
|
37
|
+
await mermaid.parse(source);
|
|
38
|
+
const { svg } = await mermaid.render(id, source);
|
|
39
|
+
return { ok: true, svg };
|
|
40
|
+
} catch (e) {
|
|
41
|
+
return { ok: false, error: describeError(e, source) };
|
|
42
|
+
} finally {
|
|
43
|
+
// A failed render can leave its scratch element in the body.
|
|
44
|
+
if (typeof document !== "undefined") {
|
|
45
|
+
document.getElementById(`d${id}`)?.remove();
|
|
46
|
+
document.getElementById(id)?.remove();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
queue = job.catch(() => {});
|
|
51
|
+
return job;
|
|
52
|
+
}
|