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,30 @@
|
|
|
1
|
+
// The one door to MapLibre (maplibre-gl, BSD-3-Clause) and its React
|
|
2
|
+
// binding (react-map-gl, MIT). Every file in this block reaches them
|
|
3
|
+
// through here, and the blocks built on this one reach them through
|
|
4
|
+
// MapView — never the packages directly.
|
|
5
|
+
//
|
|
6
|
+
// No server shim is needed: maplibre-gl 6 and react-map-gl 8 touch no
|
|
7
|
+
// browser global while their modules load (checked in node), and the map
|
|
8
|
+
// itself mounts only after the first effect (MapView's mount guard).
|
|
9
|
+
//
|
|
10
|
+
// Two things are passed explicitly instead of left to the libraries:
|
|
11
|
+
//
|
|
12
|
+
// mapLib react-map-gl would otherwise load maplibre-gl with an
|
|
13
|
+
// import() of its own. Handing it the module we import here
|
|
14
|
+
// keeps the app one static bundle.
|
|
15
|
+
// WORKER_URL maplibre-gl 6 draws tiles in a Web Worker that it loads
|
|
16
|
+
// from a file beside its own module (import.meta.url). Inside
|
|
17
|
+
// an app bundle that URL is a build-time file:// path, so the
|
|
18
|
+
// worker would never load. It is loaded from jsDelivr instead,
|
|
19
|
+
// at exactly the version installed (getVersion()), so the
|
|
20
|
+
// worker and the page always match. A map already fetches its
|
|
21
|
+
// style, tiles and fonts at run time; this is one more file.
|
|
22
|
+
// Self-host it with MapView's `workerUrl` prop.
|
|
23
|
+
import "maplibre-gl/dist/maplibre-gl.css";
|
|
24
|
+
import * as maplibregl from "maplibre-gl";
|
|
25
|
+
import { AttributionControl, Layer, Map as GLMap, Marker, Popup, Source } from "react-map-gl/maplibre";
|
|
26
|
+
|
|
27
|
+
export const MAPLIBRE_VERSION = maplibregl.getVersion();
|
|
28
|
+
export const WORKER_URL = `https://cdn.jsdelivr.net/npm/maplibre-gl@${MAPLIBRE_VERSION}/dist/maplibre-gl-worker.mjs`;
|
|
29
|
+
|
|
30
|
+
export { AttributionControl, GLMap, Layer, Marker, Popup, Source, maplibregl };
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// What sits ON the map: a place's marker, a cluster, the popup card, the
|
|
4
|
+
// list of places that share one spot. React in kit tokens — maplibre only
|
|
5
|
+
// positions them (react-map-gl's Marker and Popup portal them in).
|
|
6
|
+
import { IconButton, Item, cx } from "../../ui";
|
|
7
|
+
import { DOT } from "./theme";
|
|
8
|
+
|
|
9
|
+
// A soft halo behind the selected dot, one class per tone.
|
|
10
|
+
const HALO = {
|
|
11
|
+
primary: "bg-primary/20",
|
|
12
|
+
success: "bg-success/20",
|
|
13
|
+
warning: "bg-warning/20",
|
|
14
|
+
destructive: "bg-destructive/20",
|
|
15
|
+
info: "bg-info/20",
|
|
16
|
+
"chart-1": "bg-chart-1/20",
|
|
17
|
+
"chart-2": "bg-chart-2/20",
|
|
18
|
+
"chart-3": "bg-chart-3/20",
|
|
19
|
+
"chart-4": "bg-chart-4/20",
|
|
20
|
+
"chart-5": "bg-chart-5/20",
|
|
21
|
+
muted: "bg-muted-foreground/20",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/** A place: a dot in its tone (or the caller's own content), its name in
|
|
25
|
+
* a small label on hover and when it is selected without a popup. */
|
|
26
|
+
export function PointMark({ title, tone, selected, hovered, showLabel, focusable, custom, onHover }) {
|
|
27
|
+
// Its click is handled by the Marker around it (a native listener that
|
|
28
|
+
// runs before maplibre's map click); this button gives it a name, focus
|
|
29
|
+
// and Enter / Space.
|
|
30
|
+
const lifted = selected || hovered;
|
|
31
|
+
return (
|
|
32
|
+
// raw: a map marker is a hit target positioned on the canvas by
|
|
33
|
+
// maplibre; no kit part is a pin. Kit Button would force 44px boxes
|
|
34
|
+
// that hide the map under them.
|
|
35
|
+
<button
|
|
36
|
+
type="button"
|
|
37
|
+
tabIndex={focusable ? 0 : -1}
|
|
38
|
+
aria-label={title}
|
|
39
|
+
aria-pressed={selected}
|
|
40
|
+
data-lifted={lifted ? "" : undefined}
|
|
41
|
+
onMouseEnter={() => onHover(true)}
|
|
42
|
+
onMouseLeave={() => onHover(false)}
|
|
43
|
+
onFocus={() => onHover(true)}
|
|
44
|
+
onBlur={() => onHover(false)}
|
|
45
|
+
className={cx(
|
|
46
|
+
"group relative grid cursor-pointer place-items-center rounded-full outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
47
|
+
custom ? "min-h-7 min-w-7" : "size-7",
|
|
48
|
+
)}
|
|
49
|
+
>
|
|
50
|
+
{custom ?? (
|
|
51
|
+
<>
|
|
52
|
+
<span
|
|
53
|
+
aria-hidden="true"
|
|
54
|
+
className={cx(
|
|
55
|
+
"absolute inset-0 rounded-full transition-[transform,opacity] duration-150 motion-reduce:transition-none",
|
|
56
|
+
HALO[tone],
|
|
57
|
+
selected ? "scale-100 opacity-100" : "scale-50 opacity-0",
|
|
58
|
+
)}
|
|
59
|
+
/>
|
|
60
|
+
<span
|
|
61
|
+
aria-hidden="true"
|
|
62
|
+
className={cx(
|
|
63
|
+
"relative block size-3.5 rounded-full shadow-sm ring-2 ring-background transition-transform duration-150 motion-reduce:transition-none",
|
|
64
|
+
DOT[tone],
|
|
65
|
+
selected ? "scale-125" : "group-hover:scale-125",
|
|
66
|
+
)}
|
|
67
|
+
/>
|
|
68
|
+
</>
|
|
69
|
+
)}
|
|
70
|
+
{showLabel ? (
|
|
71
|
+
<span
|
|
72
|
+
aria-hidden="true"
|
|
73
|
+
className="pointer-events-none absolute bottom-full left-1/2 mb-1 max-w-48 -translate-x-1/2 truncate whitespace-nowrap rounded-md border border-border bg-popover px-2 py-1 text-xs font-medium text-popover-foreground shadow-sm"
|
|
74
|
+
>
|
|
75
|
+
{title}
|
|
76
|
+
</span>
|
|
77
|
+
) : null}
|
|
78
|
+
</button>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Several places too close to tell apart at this zoom: a count. */
|
|
83
|
+
export function ClusterMark({ count, label, holdsSelected }) {
|
|
84
|
+
const size = Math.round(32 + Math.min(20, Math.log2(count) * 4));
|
|
85
|
+
return (
|
|
86
|
+
// raw: a cluster is a positioned hit target on the canvas (see PointMark).
|
|
87
|
+
<button
|
|
88
|
+
type="button"
|
|
89
|
+
tabIndex={-1}
|
|
90
|
+
aria-label={label}
|
|
91
|
+
data-lifted={holdsSelected ? "" : undefined}
|
|
92
|
+
style={{ width: size, height: size }}
|
|
93
|
+
className={cx(
|
|
94
|
+
"grid cursor-pointer place-items-center rounded-full bg-primary text-xs font-semibold tabular-nums text-primary-foreground shadow-md",
|
|
95
|
+
"ring-4 ring-primary/20 outline-none transition-[box-shadow,transform] duration-150 hover:scale-105 hover:ring-primary/30",
|
|
96
|
+
"focus-visible:ring-ring motion-reduce:transition-none motion-reduce:hover:scale-100",
|
|
97
|
+
holdsSelected && "outline-2 outline-offset-2 outline-primary",
|
|
98
|
+
)}
|
|
99
|
+
>
|
|
100
|
+
{count > 999 ? `${Math.floor(count / 1000)}k` : count}
|
|
101
|
+
</button>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** The popup's box: a kit-looking card with a close button. */
|
|
106
|
+
export function PopupCard({ onClose, closeLabel = "Close", children }) {
|
|
107
|
+
return (
|
|
108
|
+
<div className="relative w-64 max-w-[calc(100vw-3rem)] rounded-lg border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg">
|
|
109
|
+
<IconButton icon="x" label={closeLabel} size="sm" onClick={onClose} className="absolute right-1 top-1 text-muted-foreground" />
|
|
110
|
+
{children}
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** The popup's words when the caller brings none: name, meta line, aside. */
|
|
116
|
+
export function DefaultPopup({ title, meta, aside }) {
|
|
117
|
+
return (
|
|
118
|
+
<div className="grid gap-1 pr-8">
|
|
119
|
+
<p className="font-medium leading-5">{title}</p>
|
|
120
|
+
{meta ? <div className="text-muted-foreground">{meta}</div> : null}
|
|
121
|
+
{aside ? <div className="pt-1">{aside}</div> : null}
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Places that share one spot (a building, a campus): pick one. */
|
|
127
|
+
export function StackList({ rows, plural, onPick }) {
|
|
128
|
+
return (
|
|
129
|
+
<div className="grid gap-1">
|
|
130
|
+
<p className="pr-8 text-xs text-muted-foreground">
|
|
131
|
+
{rows.length} {plural} at this spot
|
|
132
|
+
</p>
|
|
133
|
+
<div className="-mx-1 max-h-56 overflow-y-auto">
|
|
134
|
+
{rows.map((r) => (
|
|
135
|
+
<Item key={r.id} size="sm" title={r.title} media={<Dot tone={r.tone} />} onClick={() => onPick(r.id)} className="rounded-md" />
|
|
136
|
+
))}
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** The tone dot the list rows and cards lead with. */
|
|
143
|
+
export function Dot({ tone, missing }) {
|
|
144
|
+
if (missing) return <span aria-hidden="true" className="block size-3 shrink-0 rounded-full border border-dashed border-muted-foreground" />;
|
|
145
|
+
return <span aria-hidden="true" className={cx("block size-3 shrink-0 rounded-full", DOT[tone])} />;
|
|
146
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// The map in the workspace theme — the one place its look is mapped.
|
|
2
|
+
//
|
|
3
|
+
// Three layers of look, three answers:
|
|
4
|
+
//
|
|
5
|
+
// the tiles a style URL. The default is OpenFreeMap (free, no key,
|
|
6
|
+
// OpenStreetMap data): "positron" in a light scheme,
|
|
7
|
+
// "dark" in a dark one, chosen from the scheme in effect
|
|
8
|
+
// where the map sits and swapped when it changes.
|
|
9
|
+
// our marks markers, clusters, popups, the list and the controls are
|
|
10
|
+
// React, in the kit, in token classes — they follow the
|
|
11
|
+
// theme like any other part of the page.
|
|
12
|
+
// areas polygons drawn BY maplibre need concrete colours, so a
|
|
13
|
+
// tone ("primary", "chart-2") is resolved from the CSS
|
|
14
|
+
// variable at run time (resolveTones) and again when the
|
|
15
|
+
// scheme changes — the sketch-canvas palette trick.
|
|
16
|
+
//
|
|
17
|
+
// maplibre's own chrome (the popup's box and tip, the attribution line,
|
|
18
|
+
// the canvas focus ring) comes from its unlayered stylesheet, which beats
|
|
19
|
+
// any Tailwind utility; the classes in CHROME end in `!` for that reason
|
|
20
|
+
// (the same fix as sketch-canvas/theme.js).
|
|
21
|
+
|
|
22
|
+
/** OpenFreeMap's styles (https://openfreemap.org), checked 2026-09-23. */
|
|
23
|
+
export const MAP_STYLES = {
|
|
24
|
+
positron: "https://tiles.openfreemap.org/styles/positron",
|
|
25
|
+
liberty: "https://tiles.openfreemap.org/styles/liberty",
|
|
26
|
+
bright: "https://tiles.openfreemap.org/styles/bright",
|
|
27
|
+
"dark": "https://tiles.openfreemap.org/styles/dark",
|
|
28
|
+
fiord: "https://tiles.openfreemap.org/styles/fiord",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** What `styleUrl` defaults to: a light and a dark style. */
|
|
32
|
+
export const DEFAULT_STYLE = { "light": MAP_STYLES.positron, "dark": MAP_STYLES.dark }; // keys quoted: the block lint reads `dark:` as a Tailwind variant
|
|
33
|
+
|
|
34
|
+
/** The URL for a scheme, from a string (one style for both) or { light, dark }. */
|
|
35
|
+
export function styleFor(styleUrl, scheme) {
|
|
36
|
+
if (typeof styleUrl === "string" && styleUrl) return styleUrl;
|
|
37
|
+
const s = styleUrl && typeof styleUrl === "object" ? styleUrl : DEFAULT_STYLE;
|
|
38
|
+
return (scheme === "dark" ? s.dark ?? s.light : s.light ?? s.dark) ?? DEFAULT_STYLE[scheme === "dark" ? "dark" : "light"];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The tones a marker, cluster or area may take: token names, never colours. */
|
|
42
|
+
export const TONES = ["primary", "success", "warning", "destructive", "info", "chart-1", "chart-2", "chart-3", "chart-4", "chart-5", "muted"];
|
|
43
|
+
|
|
44
|
+
// Tailwind needs whole class names in the source: one per tone.
|
|
45
|
+
export const DOT = {
|
|
46
|
+
primary: "bg-primary",
|
|
47
|
+
success: "bg-success",
|
|
48
|
+
warning: "bg-warning",
|
|
49
|
+
destructive: "bg-destructive",
|
|
50
|
+
info: "bg-info",
|
|
51
|
+
"chart-1": "bg-chart-1",
|
|
52
|
+
"chart-2": "bg-chart-2",
|
|
53
|
+
"chart-3": "bg-chart-3",
|
|
54
|
+
"chart-4": "bg-chart-4",
|
|
55
|
+
"chart-5": "bg-chart-5",
|
|
56
|
+
muted: "bg-muted-foreground",
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const toneOrDefault = (tone) => (Object.hasOwn(DOT, tone ?? "") ? tone : "primary");
|
|
60
|
+
|
|
61
|
+
/** maplibre's chrome, pointed at tokens. */
|
|
62
|
+
export const CHROME = [
|
|
63
|
+
// the canvas: our focus ring, no browser outline
|
|
64
|
+
"[&_.maplibregl-canvas]:outline-none!",
|
|
65
|
+
"[&_.maplibregl-canvas-container:has(.maplibregl-canvas:focus-visible)]:ring-2!",
|
|
66
|
+
"[&_.maplibregl-canvas-container:has(.maplibregl-canvas:focus-visible)]:ring-inset!",
|
|
67
|
+
"[&_.maplibregl-canvas-container:has(.maplibregl-canvas:focus-visible)]:ring-ring!",
|
|
68
|
+
// popups: the box and tip are ours (MapPopup draws a kit card)
|
|
69
|
+
"[&_.maplibregl-popup-content]:bg-transparent!",
|
|
70
|
+
"[&_.maplibregl-popup-content]:p-0!",
|
|
71
|
+
"[&_.maplibregl-popup-content]:shadow-none!",
|
|
72
|
+
"[&_.maplibregl-popup-content]:rounded-none!",
|
|
73
|
+
"[&_.maplibregl-popup-tip]:hidden!",
|
|
74
|
+
"[&_.maplibregl-popup]:z-10!",
|
|
75
|
+
// the attribution line (OpenStreetMap's licence asks for it: it stays)
|
|
76
|
+
"[&_.maplibregl-ctrl-attrib]:bg-background/80!",
|
|
77
|
+
"[&_.maplibregl-ctrl-attrib]:text-muted-foreground!",
|
|
78
|
+
"[&_.maplibregl-ctrl-attrib]:text-[10px]!",
|
|
79
|
+
"[&_.maplibregl-ctrl-attrib]:leading-4!",
|
|
80
|
+
"[&_.maplibregl-ctrl-attrib]:rounded-tl-md!",
|
|
81
|
+
"[&_.maplibregl-ctrl-attrib]:px-1.5!",
|
|
82
|
+
"[&_.maplibregl-ctrl-attrib_a]:text-muted-foreground!",
|
|
83
|
+
"[&_.maplibregl-ctrl-attrib_a:hover]:text-foreground!",
|
|
84
|
+
"[&_.maplibregl-ctrl-bottom-right]:z-[1]!",
|
|
85
|
+
// markers sit above the canvas, the hovered/selected one above the rest
|
|
86
|
+
"[&_.maplibregl-marker:has([data-lifted])]:z-[2]!",
|
|
87
|
+
].join(" ");
|
|
88
|
+
|
|
89
|
+
// ---- the browser half -------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
/** The workspace's light or dark where `root` sits: a data-theme on an
|
|
92
|
+
* ancestor, else the computed color-scheme, else the OS setting. */
|
|
93
|
+
export function schemeOf(root) {
|
|
94
|
+
if (typeof window === "undefined" || !root) return "light";
|
|
95
|
+
const scoped = root.closest?.("[data-theme]")?.getAttribute("data-theme");
|
|
96
|
+
if (scoped === "light" || scoped === "dark") return scoped;
|
|
97
|
+
const cs = getComputedStyle(root).colorScheme || "";
|
|
98
|
+
if (/\bdark\b/.test(cs) && !/\blight\b/.test(cs)) return "dark";
|
|
99
|
+
if (/\blight\b/.test(cs) && !/\bdark\b/.test(cs)) return "light";
|
|
100
|
+
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const byte = (n) => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, "0");
|
|
104
|
+
|
|
105
|
+
/** Each tone → a concrete colour ("#rrggbb"), read from the CSS variables
|
|
106
|
+
* in effect at `root`. A probe takes `color: var(--color-<token>)`; the
|
|
107
|
+
* browser resolves var(), light-dark() and color-mix(); a 1×1 canvas
|
|
108
|
+
* turns whatever syntax comes back into bytes. */
|
|
109
|
+
export function resolveTones(root, tones = TONES) {
|
|
110
|
+
const out = {};
|
|
111
|
+
if (typeof document === "undefined" || !root) return out;
|
|
112
|
+
const probe = document.createElement("span");
|
|
113
|
+
probe.setAttribute("aria-hidden", "true");
|
|
114
|
+
probe.style.cssText = "position:absolute;visibility:hidden;pointer-events:none";
|
|
115
|
+
root.appendChild(probe);
|
|
116
|
+
const canvas = document.createElement("canvas");
|
|
117
|
+
canvas.width = 1;
|
|
118
|
+
canvas.height = 1;
|
|
119
|
+
const ctx = canvas.getContext("2d", { willReadFrequently: true });
|
|
120
|
+
try {
|
|
121
|
+
for (const tone of tones) {
|
|
122
|
+
probe.style.color = "";
|
|
123
|
+
probe.style.color = `var(--color-${tone === "muted" ? "muted-foreground" : tone})`;
|
|
124
|
+
const computed = getComputedStyle(probe).color;
|
|
125
|
+
if (!computed || !ctx) continue;
|
|
126
|
+
ctx.clearRect(0, 0, 1, 1);
|
|
127
|
+
ctx.fillStyle = "transparent";
|
|
128
|
+
ctx.fillStyle = computed;
|
|
129
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
130
|
+
const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data;
|
|
131
|
+
if (a) out[tone] = "#" + byte(r) + byte(g) + byte(b);
|
|
132
|
+
}
|
|
133
|
+
} finally {
|
|
134
|
+
probe.remove();
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Does the viewer ask for less motion? Camera moves then jump. */
|
|
140
|
+
export function prefersReducedMotion() {
|
|
141
|
+
return typeof window !== "undefined" && Boolean(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches);
|
|
142
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Menubar
|
|
2
|
+
|
|
3
|
+
A desktop app's menu bar: File, Edit, View, Help. Each menu is the kit's
|
|
4
|
+
Menu panel, so it takes the same `items` — actions with shortcuts,
|
|
5
|
+
checkboxes, radio groups, labelled groups, separators and submenus. Click
|
|
6
|
+
a menu to open it; once one is open, hovering another switches to it.
|
|
7
|
+
ArrowLeft and ArrowRight move along the bar, and open the neighbour when
|
|
8
|
+
a menu is open. ArrowDown, Enter or Space open a menu at its first item.
|
|
9
|
+
Escape closes it and puts focus back on its name. The bar is one Tab
|
|
10
|
+
stop (roving focus), with the `menubar` and `menuitem` roles. Below the
|
|
11
|
+
`md` breakpoint the bar is one menu button; each menu is a submenu in it
|
|
12
|
+
that unfolds in place.
|
|
13
|
+
|
|
14
|
+
```jsx
|
|
15
|
+
import { Menubar } from "../components/blocks/menubar"; // a Makersclaw app ("./blocks/menubar" from components/)
|
|
16
|
+
import { Menubar } from "@/components/makersclaw/blocks/menubar"; // a shadcn project
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
It is a client component: render it from a `"use client"` component.
|
|
20
|
+
|
|
21
|
+
## The data
|
|
22
|
+
|
|
23
|
+
`menus` is the bar, in order:
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
{
|
|
27
|
+
label: "View", // the name in the bar
|
|
28
|
+
items: [ … ], // the menu: exactly Menu's `items` (components/ui/menu.jsx)
|
|
29
|
+
icon?: "eye", // shown beside the name in the phone menu only
|
|
30
|
+
key?: "view", // default: made from the position and label
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`items` entries, any mix:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
{ label: "Save", onSelect, shortcut: "⌘S", icon?, tone?: "danger", disabled?, description? } // an action: closes the menu
|
|
38
|
+
{ type: "checkbox", label: "Show ruler", checked, onCheckedChange(next) } // stays open
|
|
39
|
+
{ type: "radio", label: "Zoom", value, onValueChange(value), options: ["75%", "100%"] } // stays open
|
|
40
|
+
{ group: "Share", items: [ … ] } // a labelled group
|
|
41
|
+
{ type: "separator" }
|
|
42
|
+
{ label: "Export", items: [ … ] } // a submenu
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
A falsy entry is skipped, so `cond && { … }` works. A menu with no items
|
|
46
|
+
is left out of the bar. A shortcut is only drawn: the app binds the key
|
|
47
|
+
itself.
|
|
48
|
+
|
|
49
|
+
## Props
|
|
50
|
+
|
|
51
|
+
- `menus` — the bar, as above.
|
|
52
|
+
- `label` — what a screen reader calls the bar, default `"Menu bar"`.
|
|
53
|
+
Name it after what it drives: `"Document"`.
|
|
54
|
+
- `menuLabel` — the phone's menu button, default `"Menu"`.
|
|
55
|
+
- `className` — layout around it (width, margin). Never colour.
|
|
56
|
+
|
|
57
|
+
## Example
|
|
58
|
+
|
|
59
|
+
```jsx
|
|
60
|
+
// components/Editor.jsx — client: the bar over the document
|
|
61
|
+
"use client";
|
|
62
|
+
import { useState } from "react";
|
|
63
|
+
import { toast } from "./ui";
|
|
64
|
+
import { Menubar } from "./blocks/menubar";
|
|
65
|
+
|
|
66
|
+
export default function Editor({ doc, onSave }) {
|
|
67
|
+
const [ruler, setRuler] = useState(true);
|
|
68
|
+
const [zoom, setZoom] = useState("100%");
|
|
69
|
+
return (
|
|
70
|
+
<div className="grid gap-4">
|
|
71
|
+
<Menubar
|
|
72
|
+
label="Document"
|
|
73
|
+
menus={[
|
|
74
|
+
{
|
|
75
|
+
label: "File",
|
|
76
|
+
items: [
|
|
77
|
+
{ label: "Save", shortcut: "⌘S", onSelect: async () => ((await onSave(doc)).ok ? toast.success("Saved") : toast.error("Could not save")) },
|
|
78
|
+
{ label: "Export", items: [{ label: "PDF", onSelect: () => {} }, { label: "Markdown", onSelect: () => {} }] },
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
label: "View",
|
|
83
|
+
items: [
|
|
84
|
+
{ type: "checkbox", label: "Show ruler", checked: ruler, onCheckedChange: setRuler },
|
|
85
|
+
{ type: "separator" },
|
|
86
|
+
{ type: "radio", label: "Zoom", value: zoom, onValueChange: setZoom, options: ["75%", "100%", "150%"] },
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
]}
|
|
90
|
+
/>
|
|
91
|
+
{/* the document */}
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## What it will not do
|
|
98
|
+
|
|
99
|
+
- Bind shortcuts: `shortcut` is a hint drawn in the menu. Listen for the
|
|
100
|
+
key in your component when it should work without the menu.
|
|
101
|
+
- Hold state: checkboxes and radios are controlled — keep `checked` and
|
|
102
|
+
`value` in your component, as above.
|
|
103
|
+
- Be a site's navigation: links belong in the navigation-menu block.
|
|
104
|
+
- Open on hover before a click: like a desktop app, the first menu opens
|
|
105
|
+
on a click or a key.
|
|
106
|
+
|
|
107
|
+
A menubar it cannot be is your own component in `components/`, built from
|
|
108
|
+
the kit — not an edit to this block. Its files are fixed: `npm run check`
|
|
109
|
+
refuses a change, and `makersclaw add menubar` restores them.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "menubar",
|
|
3
|
+
"title": "Menubar",
|
|
4
|
+
"description": "A desktop app's menu bar — File, Edit, View, Help — each a menu of actions with shortcuts, checkboxes, radio groups and submenus; click to open, hover to switch, arrow keys along the bar; one menu button on a phone.",
|
|
5
|
+
"useWhen": "A document-style tool with many commands grouped by kind: an editor, a canvas, a spreadsheet, an admin console that mimics a desktop app. Not for a site's navigation (a navigation menu) or one record's actions (a menu on the row).",
|
|
6
|
+
"tags": ["menubar", "menu bar", "menu", "file menu", "edit menu", "view menu", "commands", "shortcuts", "editor", "toolbar", "desktop", "dropdown"],
|
|
7
|
+
"exports": ["Menubar"],
|
|
8
|
+
"files": ["index.js", "menubar.jsx"],
|
|
9
|
+
"requires": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// The Menubar over a document editor — the gallery's and the smoke test's
|
|
4
|
+
// surface. Not installed into apps: `makersclaw add menubar` lays index.js
|
|
5
|
+
// and menubar.jsx only. Commands only report themselves under the page;
|
|
6
|
+
// "Show ruler", "Word count" and "Zoom" change the page for real.
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { Badge, Card } from "../components/ui";
|
|
9
|
+
import { Menubar } from "../components/blocks/menubar";
|
|
10
|
+
|
|
11
|
+
const TEXT = [
|
|
12
|
+
"Northwind closed the quarter at 118% of plan, carried by three enterprise renewals and a pricing change that lifted average contract value by a fifth.",
|
|
13
|
+
"For Q4 we propose two hires in customer success, a partner programme with the two agencies already reselling us, and a freeze on new paid channels until payback drops under nine months.",
|
|
14
|
+
];
|
|
15
|
+
const WORDS = TEXT.join(" ").split(/\s+/).length;
|
|
16
|
+
const ZOOMS = ["75%", "100%", "125%", "150%"];
|
|
17
|
+
|
|
18
|
+
export default function MenubarDemo() {
|
|
19
|
+
const [ruler, setRuler] = useState(true);
|
|
20
|
+
const [count, setCount] = useState(false);
|
|
21
|
+
const [zoom, setZoom] = useState("100%");
|
|
22
|
+
const [last, setLast] = useState(null);
|
|
23
|
+
const run = (name) => () => setLast(name);
|
|
24
|
+
|
|
25
|
+
const menus = [
|
|
26
|
+
{
|
|
27
|
+
label: "File",
|
|
28
|
+
icon: "file",
|
|
29
|
+
items: [
|
|
30
|
+
{ label: "New document", shortcut: "⌘N", onSelect: run("New document") },
|
|
31
|
+
{ label: "Open…", shortcut: "⌘O", onSelect: run("Open") },
|
|
32
|
+
{
|
|
33
|
+
label: "Open recent",
|
|
34
|
+
items: [
|
|
35
|
+
{ label: "Q3 board memo", onSelect: run("Open Q3 board memo") },
|
|
36
|
+
{ label: "Hiring plan 2027", onSelect: run("Open Hiring plan 2027") },
|
|
37
|
+
{ label: "Pricing page draft", onSelect: run("Open Pricing page draft") },
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{ type: "separator" },
|
|
41
|
+
{ label: "Save", shortcut: "⌘S", onSelect: run("Save") },
|
|
42
|
+
{ label: "Save as…", shortcut: "⇧⌘S", onSelect: run("Save as") },
|
|
43
|
+
{
|
|
44
|
+
label: "Export",
|
|
45
|
+
icon: "download",
|
|
46
|
+
items: [
|
|
47
|
+
{ label: "PDF", onSelect: run("Export as PDF") },
|
|
48
|
+
{ label: "Word (.docx)", onSelect: run("Export as Word") },
|
|
49
|
+
{ label: "Markdown", onSelect: run("Export as Markdown") },
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
{ type: "separator" },
|
|
53
|
+
{ label: "Print…", shortcut: "⌘P", onSelect: run("Print") },
|
|
54
|
+
{ label: "Move to trash", icon: "trash", tone: "danger", onSelect: run("Move to trash") },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
label: "Edit",
|
|
59
|
+
icon: "pencil",
|
|
60
|
+
items: [
|
|
61
|
+
{ label: "Undo", shortcut: "⌘Z", onSelect: run("Undo") },
|
|
62
|
+
{ label: "Redo", shortcut: "⇧⌘Z", onSelect: run("Redo") },
|
|
63
|
+
{ type: "separator" },
|
|
64
|
+
{ label: "Cut", shortcut: "⌘X", onSelect: run("Cut") },
|
|
65
|
+
{ label: "Copy", shortcut: "⌘C", onSelect: run("Copy") },
|
|
66
|
+
{ label: "Paste", shortcut: "⌘V", onSelect: run("Paste") },
|
|
67
|
+
{ label: "Paste without formatting", shortcut: "⌥⇧⌘V", onSelect: run("Paste without formatting"), disabled: true },
|
|
68
|
+
{ type: "separator" },
|
|
69
|
+
{ label: "Find and replace", shortcut: "⌘F", onSelect: run("Find and replace") },
|
|
70
|
+
{ label: "Select all", shortcut: "⌘A", onSelect: run("Select all") },
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
label: "View",
|
|
75
|
+
icon: "eye",
|
|
76
|
+
items: [
|
|
77
|
+
{ type: "checkbox", label: "Show ruler", checked: ruler, onCheckedChange: setRuler, shortcut: "⌘R" },
|
|
78
|
+
{ type: "checkbox", label: "Word count", checked: count, onCheckedChange: setCount, shortcut: "⇧⌘C" },
|
|
79
|
+
{ type: "separator" },
|
|
80
|
+
{ type: "radio", label: "Zoom", value: zoom, onValueChange: setZoom, options: ZOOMS },
|
|
81
|
+
{ type: "separator" },
|
|
82
|
+
{ label: "Full screen", shortcut: "⌃⌘F", onSelect: run("Full screen") },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
label: "Help",
|
|
87
|
+
icon: "info",
|
|
88
|
+
items: [
|
|
89
|
+
{ label: "Keyboard shortcuts", shortcut: "⌘/", onSelect: run("Keyboard shortcuts") },
|
|
90
|
+
{ label: "What's new", onSelect: run("What's new") },
|
|
91
|
+
{ type: "separator" },
|
|
92
|
+
{ label: "Contact support", icon: "mail", onSelect: run("Contact support") },
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<div className="grid gap-4">
|
|
99
|
+
<Menubar menus={menus} label="Document" />
|
|
100
|
+
<Card className="overflow-hidden p-0">
|
|
101
|
+
{ruler ? (
|
|
102
|
+
<div aria-hidden="true" className="flex h-6 items-end border-b border-border bg-muted px-6">
|
|
103
|
+
{Array.from({ length: 24 }, (_, i) => (
|
|
104
|
+
<span key={i} className={i % 4 === 0 ? "h-3 flex-1 border-l border-muted-foreground pl-0.5 text-2xs leading-none text-muted-foreground" : "h-1.5 flex-1 border-l border-border"}>
|
|
105
|
+
{i % 4 === 0 ? i / 4 : null}
|
|
106
|
+
</span>
|
|
107
|
+
))}
|
|
108
|
+
</div>
|
|
109
|
+
) : null}
|
|
110
|
+
<article className="grid gap-3 p-6" style={{ fontSize: zoom }}>
|
|
111
|
+
<h2 className="text-[1.25em] font-semibold leading-tight">Q3 board memo</h2>
|
|
112
|
+
{TEXT.map((p) => (
|
|
113
|
+
<p key={p} className="text-[0.875em] leading-relaxed text-muted-foreground">
|
|
114
|
+
{p}
|
|
115
|
+
</p>
|
|
116
|
+
))}
|
|
117
|
+
</article>
|
|
118
|
+
<div className="flex flex-wrap items-center gap-2 border-t border-border px-6 py-2 text-xs text-muted-foreground">
|
|
119
|
+
<Badge>{zoom}</Badge>
|
|
120
|
+
{count ? <span data-nums>{WORDS} words</span> : null}
|
|
121
|
+
<span className="ml-auto" aria-live="polite">
|
|
122
|
+
{last ? `Ran: ${last}` : "Pick a command from the bar"}
|
|
123
|
+
</span>
|
|
124
|
+
</div>
|
|
125
|
+
</Card>
|
|
126
|
+
</div>
|
|
127
|
+
);
|
|
128
|
+
}
|