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,455 @@
|
|
|
1
|
+
# Task model
|
|
2
|
+
|
|
3
|
+
The shared model every view of work reads: one task shape, one context
|
|
4
|
+
(statuses, people, projects, custom fields, today), the arithmetic every
|
|
5
|
+
view repeats (search, filter, group, sort, subtasks, dates, capacity,
|
|
6
|
+
dependencies), the Change a view sends when the founder moves something,
|
|
7
|
+
the small parts every view draws the same way, the toolbar above them, and
|
|
8
|
+
the drag primitives on @dnd-kit. List, board, table, calendar, gantt,
|
|
9
|
+
workload, portfolio and roadmap all run through it, so a task filtered out
|
|
10
|
+
of one is filtered out of all, and one `onChange` saves every view.
|
|
11
|
+
|
|
12
|
+
```jsx
|
|
13
|
+
import { createTaskContext, applyView, ViewToolbar, useTaskChanges } from "../components/blocks/task-model"; // a Makersclaw app
|
|
14
|
+
import { createTaskContext, applyView, ViewToolbar, useTaskChanges } from "@/components/makersclaw/blocks/task-model"; // a shadcn project
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
A surface rarely renders it alone: `task-list` (and calendar, gantt,
|
|
18
|
+
workload, work-views…) are built on it. A view built on it `requires`
|
|
19
|
+
task-model and imports @dnd-kit only through it. `model.js` and
|
|
20
|
+
`dates.js` are pure (no React): they run on the server too.
|
|
21
|
+
|
|
22
|
+
## The data
|
|
23
|
+
|
|
24
|
+
### A task
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
{
|
|
28
|
+
id: "t1", // string (numbers are stringified)
|
|
29
|
+
title: "Write the launch email",
|
|
30
|
+
status: "todo", // a status id
|
|
31
|
+
assignees: ["maya"], // person ids; [] when unassigned
|
|
32
|
+
start: "2026-09-22", // optional; a day, or "2026-09-22T09:30"
|
|
33
|
+
due: "2026-09-24T17:00", // optional; same forms
|
|
34
|
+
estimate: 4, // optional, hours
|
|
35
|
+
progress: 40, // optional, 0–100 (else from status / subtasks)
|
|
36
|
+
priority: "high", // optional: urgent · high · medium · low
|
|
37
|
+
parentId: "t0", // optional: a subtask of t0
|
|
38
|
+
dependsOn: ["t7"], // optional: t7 must finish first
|
|
39
|
+
location: { lat, lng, label }, // optional, for a map view
|
|
40
|
+
tags: ["copy"], // []
|
|
41
|
+
project: "site", // optional, a project id
|
|
42
|
+
order: 2048, // optional: the hand-made order (see placeChange)
|
|
43
|
+
…extra // any other key is kept and passed through
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`normalizeTask(t)` makes the lists lists and the id a string (it also
|
|
48
|
+
takes `name` for `title` and a single `assignee`); every helper does this
|
|
49
|
+
for you. Dates are wall-calendar strings, never Date objects: they compare
|
|
50
|
+
in order, survive JSON and a `date` column, and mean the same day in every
|
|
51
|
+
timezone. A time is local wall time, no zone.
|
|
52
|
+
|
|
53
|
+
### The context
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
const ctx = useMemo(() => createTaskContext({
|
|
57
|
+
statuses: [{ id: "todo", label: "To do", tone: "neutral" }, …, { id: "done", label: "Done", tone: "success", done: true }],
|
|
58
|
+
people: [{ id: "maya", name: "Maya Chen", src?, capacity?: 6 }], // capacity: hours a day (default 8)
|
|
59
|
+
projects: [{ id: "site", name: "Website relaunch", hue?: 1 }], // hue 1–5 = chart-1…5
|
|
60
|
+
fields: [{ key: "channel", label: "Channel", kind: "select", options: ["Email", "Social"] }],
|
|
61
|
+
today: "2026-09-23", // fix it in a demo; default the browser's today
|
|
62
|
+
weekStartsOn: 1, // 0 Sunday … 6; default Monday
|
|
63
|
+
weekend: [0, 6], holidays: ["2026-12-25"], // for working-day math
|
|
64
|
+
}), [statuses, people, projects]);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
A status's `tone` is neutral · info · warning · success · danger · primary
|
|
68
|
+
(or `hue` 1–5 for a category-like status). `done: true` marks the done
|
|
69
|
+
statuses (several may be). Without `statuses` you get `DEFAULT_STATUSES`
|
|
70
|
+
(To do, In progress, In review, Done). Custom field kinds: text · number ·
|
|
71
|
+
select · date · checkbox. Every helper takes `ctx` (or the plain options
|
|
72
|
+
object, built on the fly — build it once instead).
|
|
73
|
+
|
|
74
|
+
What `ctx` holds: `statuses`, `people`, `projects`, `fields` (built-in +
|
|
75
|
+
custom, see `TASK_FIELDS`), `statusById` / `personById` / `projectById`
|
|
76
|
+
(Maps; a status also has its `index`), `doneIds` (Set), `today`,
|
|
77
|
+
`weekStartsOn`, `weekend`, `holidays`.
|
|
78
|
+
|
|
79
|
+
### A view
|
|
80
|
+
|
|
81
|
+
What a view remembers, and what work-views saves per tab:
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
DEFAULT_VIEW = { search: "", filters: {}, groupBy: "status", sort: [], fields: ["assignees", "due", "priority"], hideDone: false }
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
- `filters` — `{ status: ["todo", "doing"], assignees: ["maya", NONE], due: ["overdue", "today"] }`:
|
|
88
|
+
any value within a field, every field. `NONE` (`"__none"`) is
|
|
89
|
+
"Unassigned / No date / No project…". Date fields filter by due bucket.
|
|
90
|
+
- `groupBy` — any field key, or `"none"`.
|
|
91
|
+
- `sort` — `[{ key, dir: "asc" | "desc" }]`; `[]` is the manual order
|
|
92
|
+
(`order`). Keys: any field, or `"manual"`.
|
|
93
|
+
- `fields` — which fields a row shows (the list's "Fields" menu).
|
|
94
|
+
|
|
95
|
+
### A change — how a view reports what the founder did
|
|
96
|
+
|
|
97
|
+
A view never edits tasks. It builds a Change and commits it:
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
{ type: "create", task } or { type: "create", tasks: [...] }
|
|
101
|
+
{ type: "update", id, patch } or { type: "update", ids: [...], patch }
|
|
102
|
+
{ type: "delete", id } or { type: "delete", ids: [...] }
|
|
103
|
+
{ type: "batch", changes: [...] } // several at once (a renumber, an undo)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The page answers every change through ONE async callback,
|
|
107
|
+
`onChange(change) → { ok: true } | { ok: false, error }` (a throw counts as
|
|
108
|
+
failed; `{ ok: true, id }` may return a create's database id). In a
|
|
109
|
+
Makersclaw app it is a loop over `changeWrites(change)`:
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
const COLUMNS = ["id", "title", "status", "assignees", "due", "priority", "parentId", "order"]; // your table's
|
|
113
|
+
|
|
114
|
+
async function onChange(change) {
|
|
115
|
+
for (const w of changeWrites(change, { columns: COLUMNS, keepNewIds: false })) {
|
|
116
|
+
const r = w.op === "insert" ? await insertRow({ source: "public.tasks", values: w.values })
|
|
117
|
+
: w.op === "update" ? await updateRow({ source: "public.tasks", id: w.id, patch: w.patch })
|
|
118
|
+
: await deleteRow({ source: "public.tasks", id: w.id });
|
|
119
|
+
if (r.ok === false) return r;
|
|
120
|
+
}
|
|
121
|
+
return { ok: true };
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Props
|
|
126
|
+
|
|
127
|
+
task-model has no one component; these are its exports, grouped by what
|
|
128
|
+
a view builder needs. Every one is importable from the block's index.
|
|
129
|
+
|
|
130
|
+
### Views: search, filter, group, sort
|
|
131
|
+
|
|
132
|
+
- `applyView(tasks, view, ctx)` → `{ tasks, groups, total }` — the whole
|
|
133
|
+
pipeline: normalise, hide done (`hideDone`), search, filter, sort, group.
|
|
134
|
+
Use this and you match every other view.
|
|
135
|
+
- `searchTasks(tasks, query, ctx)` — every word must appear in the
|
|
136
|
+
title, tags, people's names, project, status label, description or a
|
|
137
|
+
custom text field. `searchText(task, ctx)` is that haystack.
|
|
138
|
+
- `filterTasks(tasks, filters, ctx)` · `activeFilterCount(view)`.
|
|
139
|
+
- `sortTasks(tasks, sort, ctx)` — stable, blanks last either way; status
|
|
140
|
+
sorts in the statuses' order, priority urgent → low, people by name,
|
|
141
|
+
dates by day then time. `sortOptions(ctx)` for a menu.
|
|
142
|
+
- `groupTasks(tasks, by, ctx, { showEmpty? })` →
|
|
143
|
+
`[{ key, label, tone?, hue?, option, tasks }]` in the field's order,
|
|
144
|
+
the "none" group last. A task with two assignees (or tags) is in both
|
|
145
|
+
groups. Empty groups are kept for status and priority (somewhere to
|
|
146
|
+
drop) or with `showEmpty: true`. `groupOptions(ctx)` for a menu.
|
|
147
|
+
- `valuesOf(task, key, ctx)` — the group keys a task is filed under
|
|
148
|
+
(`["maya", "leo"]`, `["overdue"]`, `[NONE]`).
|
|
149
|
+
- `optionsOf(key, ctx, tasks?)` → `[{ id, label, tone?, hue?, person?, project?, none? }]`
|
|
150
|
+
— a field's choices in order; `labelOf(key, value, ctx)` — one's words.
|
|
151
|
+
- `movePatch(task, by, fromKey, toKey, ctx)` — the patch that moves a task
|
|
152
|
+
between groups of `by`: a new status; one assignee swapped for another
|
|
153
|
+
(the rest stay); a due date for a due bucket (a start moves with it,
|
|
154
|
+
the length kept); `null` when the target is not a place to drop
|
|
155
|
+
(Overdue). Board columns, list groups, workload rows all use it.
|
|
156
|
+
- `fieldOf(key, ctx)` · `TASK_FIELDS` · `PRIORITIES` · `NONE` ·
|
|
157
|
+
`DEFAULT_STATUSES` · `DEFAULT_VIEW`.
|
|
158
|
+
- `isDone(task, ctx)` · `doneStatusId(ctx)` · `openStatusId(ctx)` ·
|
|
159
|
+
`toggleDoneChange(task, ctx)` (the completion checkbox's change).
|
|
160
|
+
|
|
161
|
+
### Manual order
|
|
162
|
+
|
|
163
|
+
- `orderOf(task)` — its `order`, or null.
|
|
164
|
+
- `rankBetween(a, b)` — a number between two orders (either may be null).
|
|
165
|
+
- `placeChange(list, task, index, patch?)` — the Change that puts `task` at
|
|
166
|
+
`index` of `list` (the target group's tasks as shown, without the task),
|
|
167
|
+
with `patch` (its new group) merged in: a midpoint `order` when there is
|
|
168
|
+
room, else one `batch` that renumbers the list. Drag-to-reorder is this
|
|
169
|
+
one call.
|
|
170
|
+
- `draftTask(title, ctx, patch?, { after? })` — a new task for a quick-add:
|
|
171
|
+
a client id (`newTaskId()`), the first open status, an order after
|
|
172
|
+
`after`, the group's patch.
|
|
173
|
+
|
|
174
|
+
### Subtasks
|
|
175
|
+
|
|
176
|
+
- `flattenTree(tasks, { collapsed? })` → `[{ task, depth, childCount, hasChildren, collapsed }]`
|
|
177
|
+
in reading order; a task whose parent is not in `tasks` is a root.
|
|
178
|
+
- `buildTree(tasks)` → `[{ task, depth, children }]` · `childrenMap(tasks)`.
|
|
179
|
+
- `descendantIds(tasks, id)` · `ancestorIds(tasks, id)`.
|
|
180
|
+
- `subtaskCounts(tasks, ctx)` → Map id → `{ total, done }` (a row's "2/5").
|
|
181
|
+
- `rollup(tasks, id, ctx)` → `{ count, done, estimate, progress }`;
|
|
182
|
+
`progressOf(task, tasks, ctx)` → 0–100 (its own, else 100 if done, else
|
|
183
|
+
from its subtasks weighted by estimate).
|
|
184
|
+
- `deleteChange(tasks, ids)` — a delete that takes the subtasks too.
|
|
185
|
+
|
|
186
|
+
### Dates (dates.js — the calendar, gantt and workload math)
|
|
187
|
+
|
|
188
|
+
Days are `"YYYY-MM-DD"`, optionally `"…THH:mm"`.
|
|
189
|
+
|
|
190
|
+
- Reading: `isDay(v)` · `dayOf(v)` (a day, from a datetime or a Date) ·
|
|
191
|
+
`minutesOf(v)` (minutes after midnight, null for all-day) ·
|
|
192
|
+
`withTime(day, minutes)` · `todayDay()` · `dayNumber(day)` /
|
|
193
|
+
`fromDayNumber(n)` (integer days, for pixel math: `x = (dayNumber(d) - dayNumber(start)) * dayWidth`).
|
|
194
|
+
- Arithmetic: `addDays` · `diffDays(a, b)` (b − a) · `addMonths` (clamps
|
|
195
|
+
to the month's end) · `weekdayOf` (0 Sunday) · `startOfWeek(day, ws)` ·
|
|
196
|
+
`endOfWeek` · `weekDays(day, ws)` (7 days) · `startOfMonth` ·
|
|
197
|
+
`endOfMonth` · `daysBetween(a, b)` (inclusive list).
|
|
198
|
+
- Grids: `monthGrid("2026-09", { weekStartsOn, fixedWeeks })` → weeks of
|
|
199
|
+
7 days (mute the days whose `slice(0, 7)` is not the month) ·
|
|
200
|
+
`timeScale(from, to, unit, { weekStartsOn, locale })` → columns
|
|
201
|
+
`{ key, start, end, label }` for unit day · week · month · quarter (a
|
|
202
|
+
gantt header, workload columns, a roadmap's quarters) ·
|
|
203
|
+
`rangeOfTasks(tasks, { pad, fallback })` → the window all tasks fit in.
|
|
204
|
+
- Working days: `WEEKEND` · `isWeekend` · `isWorkingDay(day, { weekend, holidays })` ·
|
|
205
|
+
`workingDaysBetween(a, b, opts)` · `addWorkingDays(day, n, opts)`.
|
|
206
|
+
- Spans: `spanOf(task)` → `{ start, end }` (one date → a one-day span;
|
|
207
|
+
none → null = unscheduled) · `spansOverlap(a, b)` ·
|
|
208
|
+
`tasksInRange(tasks, from, to)` · `tasksOnDay(tasks, day)`.
|
|
209
|
+
- Patches a drag saves: `shiftDates(task, n)` (move by n days, keeping
|
|
210
|
+
length and times) · `spanPatch(task, start, end)` (a resize).
|
|
211
|
+
- Words: `formatDay(day, today)` ("Today", "Tomorrow", "Yesterday", "Fri",
|
|
212
|
+
"Oct 30", "Jan 3, 2027") · `formatTime(v)` ("2:30 PM") ·
|
|
213
|
+
`formatDate(day, intlOptions)`.
|
|
214
|
+
- Due buckets: `dueBucket(due, today, { done, weekStartsOn })` → overdue ·
|
|
215
|
+
today · tomorrow · this-week · next-week · later · past (a done task's
|
|
216
|
+
old date) · none; `DUE_BUCKETS` (their words and tones) ·
|
|
217
|
+
`dayForBucket(bucket, today)` (the day a drop into a bucket sets).
|
|
218
|
+
|
|
219
|
+
The kit's own `addDays` / `startOfMonth` / `formatDate` exist too, with
|
|
220
|
+
the same string dates; import one or the other in a file, not both.
|
|
221
|
+
|
|
222
|
+
### Capacity
|
|
223
|
+
|
|
224
|
+
- `workload(tasks, ctx, { from, to, unit: "day" | "week", defaultCapacity: 8, includeDone })`
|
|
225
|
+
→ `{ rows: [{ person, total, capacity, buckets: [{ key, start, end, hours, capacity, over, tasks: [{ task, hours }] }] }], buckets, unassigned, unscheduled }`.
|
|
226
|
+
A task's estimate is spread evenly over the working days of its span and
|
|
227
|
+
split between its assignees; a bucket's capacity is the person's hours a
|
|
228
|
+
day × its working days. `over` is load past capacity.
|
|
229
|
+
- `hoursPerDay(task, ctx)` · `sumOf(tasks, key = "estimate")`.
|
|
230
|
+
|
|
231
|
+
### Dependencies
|
|
232
|
+
|
|
233
|
+
- `dependencyEdges(tasks)` → `[{ from, to }]` (`to` waits on `from`).
|
|
234
|
+
- `blockersOf(task, tasks, ctx)` — what it waits on that is not done.
|
|
235
|
+
- `wouldCycle(tasks, fromId, toId)` — refuse a link that loops.
|
|
236
|
+
- `dateConflicts(tasks)` — edges whose `to` starts before `from` ends.
|
|
237
|
+
- `criticalPath(tasks)` → Set of ids on the longest dependent chain.
|
|
238
|
+
|
|
239
|
+
### Changes
|
|
240
|
+
|
|
241
|
+
- `useTaskChanges(tasks, onChange)` → `{ tasks, commit, error, clearError, saving }`
|
|
242
|
+
— the hook every view uses. `commit(change, { label?, undo? })` shows
|
|
243
|
+
the change at once, calls `onChange`, and on `{ ok: false }` takes it
|
|
244
|
+
back and sets `error` ("“Write brief” was not saved: … It is back as it
|
|
245
|
+
was.") — show it in a `Notice`. `undo: "Deleted “Write brief”"` also
|
|
246
|
+
shows a toast with Undo (it commits the inverse; deleted tasks come back
|
|
247
|
+
with their ids). It returns the page's answer. Example rows
|
|
248
|
+
(`useFixture`, `_sample`) change on screen and are never sent. The
|
|
249
|
+
change stays on screen until the page's `tasks` move on, so nothing
|
|
250
|
+
flickers back between the save and the re-read.
|
|
251
|
+
- `applyChange(tasks, change)` · `invertChange(tasksBefore, change)` ·
|
|
252
|
+
`changedIds(change)`.
|
|
253
|
+
- `changeWrites(change, { columns?, keepNewIds? })` — the change as plain
|
|
254
|
+
`{ op: "insert", values } | { op: "update", id, patch } | { op: "delete", id }`
|
|
255
|
+
rows. `columns` keeps only your table's keys (a new task carries empty
|
|
256
|
+
`tags` and `dependsOn` lists your table may not have); `keepNewIds:
|
|
257
|
+
false` drops a created task's client id (`new-…`, see `isNewId`) so the
|
|
258
|
+
table makes its own. Keep it (the default) when your id column is text
|
|
259
|
+
and the client id may stand.
|
|
260
|
+
|
|
261
|
+
### Adapters for the existing blocks
|
|
262
|
+
|
|
263
|
+
Drive `board` and `data-table` from tasks without touching them:
|
|
264
|
+
|
|
265
|
+
```jsx
|
|
266
|
+
const b = toBoard(visibleTasks, { groupBy: "status", ctx }); // or "assignees", "priority", "due"…
|
|
267
|
+
<Board rows={b.rows} groupBy={b.groupBy} columns={b.columns} otherLabel={b.otherLabel}
|
|
268
|
+
onMove={(row, to, from) => commit(b.moveChange(row, to, from), { label: `“${row.title}”` })}
|
|
269
|
+
titleOf={(t) => t.title}
|
|
270
|
+
renderDetails={(t) => <><DueLabel value={t.due} ctx={ctx} /><AssigneeStack ids={t.assignees} ctx={ctx} /></>} />
|
|
271
|
+
|
|
272
|
+
<DataTable rows={toTableRows(visibleTasks, ctx)}
|
|
273
|
+
columns={taskColumns(ctx, { keys: ["title", "status", "assignees", "due", "priority"], onChange: commit })}
|
|
274
|
+
facets={taskFacets(ctx)} noun="task" />
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
- `toBoard(tasks, { groupBy, ctx })` → `{ rows, groupBy: "__group", columns, otherLabel, moveChange(row, to, from) }`
|
|
278
|
+
— one card per task, under its first value; `moveChange` is
|
|
279
|
+
`movePatch` as an update (null when the column refuses it). Overdue is
|
|
280
|
+
not a column when grouped by due date.
|
|
281
|
+
- `toTableRows(tasks, ctx)` → the tasks plus `statusLabel`, `statusIndex`,
|
|
282
|
+
`assigneeNames`, `projectName`, `priorityLabel`, `priorityRank`,
|
|
283
|
+
`dueDay`, `dueBucket`, `parentTitle`, `subtasks` ("2/5"), `done`.
|
|
284
|
+
- `taskColumns(ctx, { keys?, onChange? })` — DataTable columns (title,
|
|
285
|
+
status, assignees, due, start, priority, project, estimate, progress,
|
|
286
|
+
tags), sortable, drawn with the parts; with `onChange` the status,
|
|
287
|
+
people, due and priority cells are pickers that send an update Change.
|
|
288
|
+
- `taskFacets(ctx, { keys? })` — facets for status, assignee, priority,
|
|
289
|
+
project.
|
|
290
|
+
|
|
291
|
+
### Parts every view shares
|
|
292
|
+
|
|
293
|
+
Each is a label; with `onChange` it becomes a picker (a kit Menu or
|
|
294
|
+
Popover) and hands the picked value back — you wrap it in a Change.
|
|
295
|
+
|
|
296
|
+
- `<StatusPill status ctx onChange?(id) size?="sm"|"md" hideLabel? />` — dot + words.
|
|
297
|
+
- `<CompleteToggle done onToggle label size?="md"|"sm" />` — the round
|
|
298
|
+
completion check (not the square selection Checkbox).
|
|
299
|
+
- `<AssigneeStack ids ctx onChange?(ids) max?=3 size?="xs" />` — faces,
|
|
300
|
+
or a dashed "assign" circle; the picker ticks people (stays open).
|
|
301
|
+
- `<PersonLabel id ctx />` — face + name ("Unassigned" for NONE).
|
|
302
|
+
- `<DueLabel value done? ctx onChange?(day|null) quiet?=true placeholder? />`
|
|
303
|
+
— "Today" / "Fri" / "Oct 30", danger when overdue, warning today; the
|
|
304
|
+
picker is quick picks (Today, Tomorrow, Next week) + a calendar + Remove.
|
|
305
|
+
`quiet` hides an empty one's words until its row (`group/row`) is hovered.
|
|
306
|
+
- `<PriorityFlag value onChange?(id|null) showLabel? />` — a flag in the
|
|
307
|
+
priority's tone.
|
|
308
|
+
- `<TagList tags max?=2 />` · `<SubtaskCount done total />` ·
|
|
309
|
+
`<ProgressLine value />` (0–100).
|
|
310
|
+
- `<TaskChip task ctx onOpen? showTime? showPeople? dragging? lifted? dragProps? />`
|
|
311
|
+
— a task on one compact line (status dot, time, title, first face, the
|
|
312
|
+
project's hue on its leading edge): a calendar day's item, a gantt
|
|
313
|
+
label, a workload cell.
|
|
314
|
+
- `<GroupLabel group by ctx />` — a group heading's face for any field.
|
|
315
|
+
- `TONE_TEXT` · `HUE_EDGE` · `HUE_BG` — the token classes those use
|
|
316
|
+
(tone → `text-…`, hue 1–5 → `border-s-chart-N` / `bg-chart-N`).
|
|
317
|
+
|
|
318
|
+
Rows that host pickers should carry the `group/row` class: the quiet
|
|
319
|
+
parts (an empty due date, an empty priority, a drag handle) appear when
|
|
320
|
+
the row is hovered or focused, and always on touch.
|
|
321
|
+
|
|
322
|
+
### ViewToolbar
|
|
323
|
+
|
|
324
|
+
```jsx
|
|
325
|
+
<ViewToolbar view={view} onViewChange={setView} ctx={ctx} tasks={allTasks}
|
|
326
|
+
count={shown.tasks.length} extra={<Button variant="primary" size="sm" icon="plus">Add task</Button>} />
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Search (Escape clears), Filter (a popover of every filterable field with
|
|
330
|
+
counts, and "Hide done tasks"), Group by, Sort (field + direction), Fields
|
|
331
|
+
(which fields rows show), your `extra` at the end; active filters as
|
|
332
|
+
chips underneath, each with ×, and "Clear filters". On a phone the search
|
|
333
|
+
takes the first line and the controls are icons.
|
|
334
|
+
|
|
335
|
+
- `view` · `onViewChange(nextView)` — controlled; a view object as above.
|
|
336
|
+
- `ctx` · `tasks` (the counts in the filter menu).
|
|
337
|
+
- `controls` — default `["search", "filter", "group", "sort", "fields"]`;
|
|
338
|
+
a calendar might pass `["search", "filter"]`.
|
|
339
|
+
- `filterFields` · `groupFields` · `showableFields` — limit the choices.
|
|
340
|
+
- `count` — "12 tasks" beside the controls (from 768px).
|
|
341
|
+
- `searchPlaceholder` (default "Search tasks") · `extra` · `className`.
|
|
342
|
+
|
|
343
|
+
### Drag primitives (@dnd-kit, never imported directly)
|
|
344
|
+
|
|
345
|
+
One interaction model everywhere: a mouse drags after 5px, a finger after
|
|
346
|
+
a short press (so lists still scroll), the keyboard picks up with Space
|
|
347
|
+
or Enter, moves with the arrows, drops with Space, cancels with Escape;
|
|
348
|
+
screen readers hear what was picked up and where it is.
|
|
349
|
+
|
|
350
|
+
```jsx
|
|
351
|
+
<TaskDragProvider
|
|
352
|
+
onDragEnd={({ active, over }) => { /* active.data / over.data are what you attached */ }}
|
|
353
|
+
overlay={(active) => <div className={LIFTED}><TaskChip task={active.data.task} ctx={ctx} /></div>}
|
|
354
|
+
collision="list">
|
|
355
|
+
<SortableGroup ids={ids}>…rows using useSortableTask…</SortableGroup>
|
|
356
|
+
…cells using useDropTarget, chips using useDraggableTask…
|
|
357
|
+
</TaskDragProvider>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
- `<TaskDragProvider onDragStart? onDragOver? onDragEnd? onDragCancel? overlay? collision? describe? place? disabled? />`
|
|
361
|
+
— callbacks get `{ active: { id, data }, over: { id, data } | null, delta }`.
|
|
362
|
+
`overlay(active)` draws the lifted copy (tilted 1°, 150ms drop; flat
|
|
363
|
+
and instant under reduced motion). `collision`: `"list"` (default: the
|
|
364
|
+
item under the pointer, else the group under it, else — keyboard — the
|
|
365
|
+
closest) · `"closest"` · `"pointer"` (grids and calendars) · `"rect"` ·
|
|
366
|
+
a function. `describe(active)` / `place(over)` word the announcements
|
|
367
|
+
(default `data.task.title`, `data.label`).
|
|
368
|
+
- `<SortableGroup ids layout?="vertical"|"horizontal"|"grid">` — items that
|
|
369
|
+
reorder among themselves.
|
|
370
|
+
- `useSortableTask(id, data, { disabled })` → `{ setNodeRef, setHandleRef, style, handle, isDragging, isOver }`
|
|
371
|
+
— `setNodeRef` + `style` on the item, `handle` spread on its grip.
|
|
372
|
+
- `useDraggableTask(id, data)` → `{ setNodeRef, setHandleRef, handle, style, transform, isDragging }`
|
|
373
|
+
— a free item dropped on targets (a calendar chip, a gantt bar; use
|
|
374
|
+
`delta` in onDragEnd for a resize or a pixel shift).
|
|
375
|
+
- `useDropTarget(id, data)` → `{ setNodeRef, isOver, active }` — a group,
|
|
376
|
+
a day cell, a person's week.
|
|
377
|
+
- `<DragHandle handle handleRef? label alwaysVisible? />` — the grip, shown
|
|
378
|
+
on row hover (always on touch). `<DropLine />` — a landing line.
|
|
379
|
+
- `LIFTED` — the lifted-card classes · `useReducedMotion()` · `arrayMove`.
|
|
380
|
+
|
|
381
|
+
How a drop becomes a save: read `over.data` (a group key, a day, a
|
|
382
|
+
person), build the patch (`movePatch`, `shiftDates`, `spanPatch`, or
|
|
383
|
+
`placeChange` for an order), `commit` it.
|
|
384
|
+
|
|
385
|
+
## Example
|
|
386
|
+
|
|
387
|
+
A minimal view on the model — search, filter and group from the toolbar,
|
|
388
|
+
tasks as chips, drag a chip to another status:
|
|
389
|
+
|
|
390
|
+
```jsx
|
|
391
|
+
"use client";
|
|
392
|
+
import { useMemo, useState } from "react";
|
|
393
|
+
import { Notice } from "./ui";
|
|
394
|
+
import {
|
|
395
|
+
DEFAULT_VIEW, TaskChip, TaskDragProvider, ViewToolbar, applyView, createTaskContext,
|
|
396
|
+
movePatch, useDraggableTask, useDropTarget, useTaskChanges, LIFTED,
|
|
397
|
+
} from "./blocks/task-model";
|
|
398
|
+
|
|
399
|
+
export default function StatusLanes({ tasks, statuses, people, onChange }) {
|
|
400
|
+
const ctx = useMemo(() => createTaskContext({ statuses, people }), [statuses, people]);
|
|
401
|
+
const { tasks: live, commit, error, clearError } = useTaskChanges(tasks, onChange);
|
|
402
|
+
const [view, setView] = useState({ ...DEFAULT_VIEW, groupBy: "status" });
|
|
403
|
+
const { groups } = applyView(live, view, ctx);
|
|
404
|
+
return (
|
|
405
|
+
<div className="grid gap-3">
|
|
406
|
+
<ViewToolbar view={view} onViewChange={setView} ctx={ctx} tasks={live} controls={["search", "filter"]} />
|
|
407
|
+
{error ? <Notice tone="danger" onDismiss={clearError}>{error}</Notice> : null}
|
|
408
|
+
<TaskDragProvider collision="pointer"
|
|
409
|
+
overlay={(a) => <div className={LIFTED}><TaskChip task={a.data.task} ctx={ctx} /></div>}
|
|
410
|
+
onDragEnd={({ active, over }) => {
|
|
411
|
+
if (!over) return;
|
|
412
|
+
const patch = movePatch(active.data.task, "status", active.data.group, over.data.group, ctx);
|
|
413
|
+
if (patch && over.data.group !== active.data.group) commit({ type: "update", id: active.data.task.id, patch });
|
|
414
|
+
}}>
|
|
415
|
+
{groups.map((g) => <Lane key={g.key} group={g} ctx={ctx} />)}
|
|
416
|
+
</TaskDragProvider>
|
|
417
|
+
</div>
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function Lane({ group, ctx }) {
|
|
422
|
+
const drop = useDropTarget(`lane-${group.key}`, { group: group.key, label: group.label });
|
|
423
|
+
return (
|
|
424
|
+
<section ref={drop.setNodeRef} className={drop.isOver ? "rounded-lg bg-accent p-2" : "rounded-lg p-2"}>
|
|
425
|
+
<h3 className="text-sm font-semibold">{group.label}</h3>
|
|
426
|
+
<ul className="mt-2 grid gap-1">{group.tasks.map((t) => <Chip key={t.id} task={t} group={group.key} ctx={ctx} />)}</ul>
|
|
427
|
+
</section>
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function Chip({ task, group, ctx }) {
|
|
432
|
+
const d = useDraggableTask(task.id, { task, group });
|
|
433
|
+
return <li ref={d.setNodeRef}><TaskChip task={task} ctx={ctx} dragging={d.isDragging} dragProps={d.handle} /></li>;
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## What it will not do
|
|
438
|
+
|
|
439
|
+
- Draw a whole view: that is `task-list`, `board` (through `toBoard`),
|
|
440
|
+
`data-table` (through `toTableRows`), and the calendar / gantt /
|
|
441
|
+
workload blocks built on this one.
|
|
442
|
+
- Fetch or save: tasks come in as props, changes go out through the
|
|
443
|
+
page's `onChange`.
|
|
444
|
+
- Recurring tasks, time zones, or time tracking: a date is a wall-calendar
|
|
445
|
+
day (and time); a repeat is the page's to create.
|
|
446
|
+
- Sync between people live: the page re-reads.
|
|
447
|
+
|
|
448
|
+
Its files are fixed: `npm run check` refuses a change, and `makersclaw
|
|
449
|
+
add task-model` restores them. A view it cannot be is your own component
|
|
450
|
+
built from these exports.
|
|
451
|
+
|
|
452
|
+
## Credits
|
|
453
|
+
|
|
454
|
+
The drag primitives wrap @dnd-kit (MIT, https://dndkit.com): core 6.3.1,
|
|
455
|
+
sortable 10.0.0, utilities 3.2.2.
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "task-model",
|
|
3
|
+
"title": "Task model",
|
|
4
|
+
"description": "The shared work-item model every task view reads: one task shape (status, assignees, start/due, estimate, progress, priority, parent, dependencies, location, tags, project, extra fields) with statuses, people and projects; pure helpers to search, filter, group by any field, sort, nest subtasks, do date math (week and month grids, working days, overlaps, time scales), sum capacity per person, follow dependencies and the critical path, and apply, undo and persist changes; the shared parts (StatusPill, AssigneeStack, DueLabel, PriorityFlag, TaskChip, CompleteToggle), the ViewToolbar (search, filter chips, group by, sort, show fields), drag primitives on @dnd-kit, a hook for optimistic saves with rollback and undo, and adapters that drive the Board and DataTable blocks from tasks.",
|
|
5
|
+
"useWhen": "You are building a view of work items \u2014 a list, calendar, gantt, workload, roadmap or a switcher between them \u2014 or driving Board / DataTable from tasks. Views import it; a surface rarely renders it alone. Not for records that are not work (use data-table or board directly).",
|
|
6
|
+
"tags": [
|
|
7
|
+
"tasks",
|
|
8
|
+
"task",
|
|
9
|
+
"work items",
|
|
10
|
+
"project management",
|
|
11
|
+
"model",
|
|
12
|
+
"filter",
|
|
13
|
+
"group",
|
|
14
|
+
"sort",
|
|
15
|
+
"subtasks",
|
|
16
|
+
"dates",
|
|
17
|
+
"calendar math",
|
|
18
|
+
"workload",
|
|
19
|
+
"capacity",
|
|
20
|
+
"dependencies",
|
|
21
|
+
"critical path",
|
|
22
|
+
"toolbar",
|
|
23
|
+
"drag",
|
|
24
|
+
"drop",
|
|
25
|
+
"dnd-kit",
|
|
26
|
+
"optimistic",
|
|
27
|
+
"undo",
|
|
28
|
+
"clickup",
|
|
29
|
+
"linear",
|
|
30
|
+
"asana"
|
|
31
|
+
],
|
|
32
|
+
"exports": [
|
|
33
|
+
"NONE",
|
|
34
|
+
"PRIORITIES",
|
|
35
|
+
"DEFAULT_STATUSES",
|
|
36
|
+
"TASK_FIELDS",
|
|
37
|
+
"DEFAULT_VIEW",
|
|
38
|
+
"normalizeTask",
|
|
39
|
+
"normalizeTasks",
|
|
40
|
+
"createTaskContext",
|
|
41
|
+
"fieldOf",
|
|
42
|
+
"isDone",
|
|
43
|
+
"doneStatusId",
|
|
44
|
+
"openStatusId",
|
|
45
|
+
"toggleDoneChange",
|
|
46
|
+
"newTaskId",
|
|
47
|
+
"draftTask",
|
|
48
|
+
"valuesOf",
|
|
49
|
+
"optionsOf",
|
|
50
|
+
"labelOf",
|
|
51
|
+
"searchText",
|
|
52
|
+
"searchTasks",
|
|
53
|
+
"filterTasks",
|
|
54
|
+
"orderOf",
|
|
55
|
+
"sortTasks",
|
|
56
|
+
"sortOptions",
|
|
57
|
+
"groupTasks",
|
|
58
|
+
"groupOptions",
|
|
59
|
+
"movePatch",
|
|
60
|
+
"applyView",
|
|
61
|
+
"activeFilterCount",
|
|
62
|
+
"rankBetween",
|
|
63
|
+
"placeChange",
|
|
64
|
+
"childrenMap",
|
|
65
|
+
"buildTree",
|
|
66
|
+
"flattenTree",
|
|
67
|
+
"descendantIds",
|
|
68
|
+
"ancestorIds",
|
|
69
|
+
"subtaskCounts",
|
|
70
|
+
"rollup",
|
|
71
|
+
"progressOf",
|
|
72
|
+
"dependencyEdges",
|
|
73
|
+
"blockersOf",
|
|
74
|
+
"wouldCycle",
|
|
75
|
+
"dateConflicts",
|
|
76
|
+
"criticalPath",
|
|
77
|
+
"hoursPerDay",
|
|
78
|
+
"workload",
|
|
79
|
+
"sumOf",
|
|
80
|
+
"applyChange",
|
|
81
|
+
"invertChange",
|
|
82
|
+
"changeWrites",
|
|
83
|
+
"changedIds",
|
|
84
|
+
"deleteChange",
|
|
85
|
+
"toBoard",
|
|
86
|
+
"toTableRows",
|
|
87
|
+
"taskFacets",
|
|
88
|
+
"StatusPill",
|
|
89
|
+
"CompleteToggle",
|
|
90
|
+
"AssigneeStack",
|
|
91
|
+
"PersonLabel",
|
|
92
|
+
"DueLabel",
|
|
93
|
+
"PriorityFlag",
|
|
94
|
+
"TagList",
|
|
95
|
+
"SubtaskCount",
|
|
96
|
+
"ProgressLine",
|
|
97
|
+
"TaskChip",
|
|
98
|
+
"GroupLabel",
|
|
99
|
+
"taskColumns",
|
|
100
|
+
"TONE_TEXT",
|
|
101
|
+
"HUE_EDGE",
|
|
102
|
+
"HUE_BG",
|
|
103
|
+
"TaskDragProvider",
|
|
104
|
+
"SortableGroup",
|
|
105
|
+
"useSortableTask",
|
|
106
|
+
"useDraggableTask",
|
|
107
|
+
"useDropTarget",
|
|
108
|
+
"DragHandle",
|
|
109
|
+
"DropLine",
|
|
110
|
+
"LIFTED",
|
|
111
|
+
"useReducedMotion",
|
|
112
|
+
"arrayMove",
|
|
113
|
+
"isDay",
|
|
114
|
+
"dayNumber",
|
|
115
|
+
"fromDayNumber",
|
|
116
|
+
"dayOf",
|
|
117
|
+
"minutesOf",
|
|
118
|
+
"withTime",
|
|
119
|
+
"todayDay",
|
|
120
|
+
"addDays",
|
|
121
|
+
"diffDays",
|
|
122
|
+
"weekdayOf",
|
|
123
|
+
"startOfWeek",
|
|
124
|
+
"endOfWeek",
|
|
125
|
+
"weekDays",
|
|
126
|
+
"startOfMonth",
|
|
127
|
+
"endOfMonth",
|
|
128
|
+
"addMonths",
|
|
129
|
+
"daysBetween",
|
|
130
|
+
"monthGrid",
|
|
131
|
+
"WEEKEND",
|
|
132
|
+
"isWeekend",
|
|
133
|
+
"isWorkingDay",
|
|
134
|
+
"workingDaysBetween",
|
|
135
|
+
"addWorkingDays",
|
|
136
|
+
"spanOf",
|
|
137
|
+
"spansOverlap",
|
|
138
|
+
"tasksInRange",
|
|
139
|
+
"tasksOnDay",
|
|
140
|
+
"shiftDates",
|
|
141
|
+
"spanPatch",
|
|
142
|
+
"dueBucket",
|
|
143
|
+
"DUE_BUCKETS",
|
|
144
|
+
"dayForBucket",
|
|
145
|
+
"formatDay",
|
|
146
|
+
"formatTime",
|
|
147
|
+
"formatDate",
|
|
148
|
+
"timeScale",
|
|
149
|
+
"rangeOfTasks",
|
|
150
|
+
"isNewId"
|
|
151
|
+
],
|
|
152
|
+
"files": [
|
|
153
|
+
"index.js",
|
|
154
|
+
"model.js",
|
|
155
|
+
"dates.js",
|
|
156
|
+
"changes.js",
|
|
157
|
+
"parts.jsx",
|
|
158
|
+
"toolbar.jsx",
|
|
159
|
+
"dnd.jsx"
|
|
160
|
+
],
|
|
161
|
+
"requires": [],
|
|
162
|
+
"dependencies": {
|
|
163
|
+
"@dnd-kit/core": "6.3.1",
|
|
164
|
+
"@dnd-kit/sortable": "10.0.0",
|
|
165
|
+
"@dnd-kit/utilities": "3.2.2"
|
|
166
|
+
}
|
|
167
|
+
}
|