makersclaw 0.8.0 → 0.8.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/README.md +9 -3
- package/package.json +1 -1
- package/r/activity-log.json +52 -0
- package/r/agent-changes.json +51 -0
- package/r/agent-chat.json +53 -0
- package/r/agent-column.json +85 -0
- package/r/agent-dock.json +57 -0
- package/r/agent-kit.json +49 -0
- package/r/agent-marks.json +49 -0
- package/r/agent-pane.json +93 -0
- package/r/ai-action.json +56 -0
- package/r/annotate.json +3 -3
- package/r/approval-request.json +2 -2
- package/r/approval.json +54 -0
- package/r/ask-bar.json +50 -0
- package/r/audio-player.json +2 -2
- package/r/auth-form.json +2 -2
- package/r/automation-editor.json +66 -0
- package/r/automation-list.json +57 -0
- package/r/automation-model.json +118 -0
- package/r/automations-screen.json +71 -0
- package/r/board.json +2 -2
- package/r/calendar-view.json +3 -3
- package/r/cart.json +2 -2
- package/r/chart.json +2 -2
- package/r/chat-pane.json +84 -0
- package/r/chat.json +2 -2
- package/r/code-editor.json +2 -2
- package/r/comment-box.json +3 -3
- package/r/connect-card.json +51 -0
- package/r/contact-section.json +2 -2
- package/r/core.json +13 -7
- package/r/cost.json +51 -0
- package/r/csv-import.json +3 -3
- package/r/data-picker.json +60 -0
- package/r/data-table.json +2 -2
- package/r/diagram.json +2 -2
- package/r/doc-editor.json +2 -2
- package/r/doc-page.json +3 -3
- package/r/email-render.json +2 -2
- package/r/faq.json +2 -2
- package/r/file-upload.json +2 -2
- package/r/first-run.json +63 -0
- package/r/fix-note.json +57 -0
- package/r/flow-canvas.json +2 -2
- package/r/flow-editor.json +79 -0
- package/r/footer.json +2 -2
- package/r/gantt.json +3 -3
- package/r/job-panel.json +2 -2
- package/r/json-editor.json +3 -3
- package/r/library-shelf.json +56 -0
- package/r/map.json +2 -2
- package/r/margin-notes.json +67 -0
- package/r/menubar.json +2 -2
- package/r/mind-map.json +3 -3
- package/r/navigation-menu.json +2 -2
- package/r/needs-you.json +55 -0
- package/r/order-detail.json +2 -2
- package/r/org-chart.json +3 -3
- package/r/pace-bar.json +69 -0
- package/r/page-builder.json +2 -2
- package/r/payment-methods.json +2 -2
- package/r/pdf-document.json +2 -2
- package/r/pdf-viewer.json +2 -2
- package/r/product-detail.json +2 -2
- package/r/product-grid.json +3 -3
- package/r/record-form.json +2 -2
- package/r/record-grid.json +52 -0
- package/r/record-notes.json +4 -4
- package/r/registry.json +4086 -1512
- package/r/run-history.json +52 -0
- package/r/run-view.json +80 -0
- package/r/schedule-card.json +54 -0
- package/r/schedule-engine.json +79 -0
- package/r/schedule-gantt.json +83 -0
- package/r/schedule-ruler.json +64 -0
- package/r/search-dialog.json +2 -2
- package/r/settings-list.json +2 -2
- package/r/setup-checklist.json +2 -2
- package/r/share-dialog.json +2 -2
- package/r/sidebar.json +2 -2
- package/r/signature-pad.json +2 -2
- package/r/sketch-canvas.json +2 -2
- package/r/source-receipt.json +52 -0
- package/r/spreadsheet.json +3 -3
- package/r/stat-cards.json +3 -3
- package/r/step-picker.json +53 -0
- package/r/step-settings.json +72 -0
- package/r/suggestion.json +58 -0
- package/r/sum-bar.json +64 -0
- package/r/task-list.json +3 -3
- package/r/task-model.json +2 -2
- package/r/testimonials.json +2 -2
- package/r/tier-map.json +67 -0
- package/r/time-grid.json +73 -0
- package/r/time-strip.json +64 -0
- package/r/top-bar.json +66 -0
- package/r/transaction-list.json +2 -2
- package/r/trigger-picker.json +61 -0
- package/r/whiteboard.json +3 -3
- package/r/workflow-view.json +55 -0
- package/registry/blocks/activity-log/README.md +112 -0
- package/registry/blocks/activity-log/activity-log.jsx +351 -0
- package/registry/blocks/activity-log/block.json +33 -0
- package/registry/blocks/activity-log/demo.jsx +48 -0
- package/registry/blocks/activity-log/index.js +4 -0
- package/registry/blocks/agent-changes/README.md +94 -0
- package/registry/blocks/agent-changes/agent-changes.jsx +118 -0
- package/registry/blocks/agent-changes/block.json +28 -0
- package/registry/blocks/agent-changes/demo.jsx +39 -0
- package/registry/blocks/agent-changes/index.js +3 -0
- package/registry/blocks/agent-chat/README.md +145 -0
- package/registry/blocks/agent-chat/agent-chat.jsx +415 -0
- package/registry/blocks/agent-chat/block.json +30 -0
- package/registry/blocks/agent-chat/demo.jsx +165 -0
- package/registry/blocks/agent-chat/index.js +3 -0
- package/registry/blocks/agent-column/README.md +197 -0
- package/registry/blocks/agent-column/agent-column.jsx +492 -0
- package/registry/blocks/agent-column/block.json +67 -0
- package/registry/blocks/agent-column/column-picker.jsx +163 -0
- package/registry/blocks/agent-column/demo.jsx +50 -0
- package/registry/blocks/agent-column/index.js +7 -0
- package/registry/blocks/agent-column/model.js +164 -0
- package/registry/blocks/agent-column/receipt.jsx +483 -0
- package/registry/blocks/agent-column/spreadsheet-type.jsx +24 -0
- package/registry/blocks/agent-dock/README.md +210 -0
- package/registry/blocks/agent-dock/agent-dock.jsx +356 -0
- package/registry/blocks/agent-dock/block.json +47 -0
- package/registry/blocks/agent-dock/demo.jsx +153 -0
- package/registry/blocks/agent-dock/dock-model.js +118 -0
- package/registry/blocks/agent-dock/index.js +5 -0
- package/registry/blocks/agent-kit/README.md +73 -0
- package/registry/blocks/agent-kit/agent-kit.jsx +86 -0
- package/registry/blocks/agent-kit/block.json +10 -0
- package/registry/blocks/agent-kit/demo.jsx +35 -0
- package/registry/blocks/agent-kit/index.js +3 -0
- package/registry/blocks/agent-marks/README.md +80 -0
- package/registry/blocks/agent-marks/agent-marks.jsx +133 -0
- package/registry/blocks/agent-marks/block.json +27 -0
- package/registry/blocks/agent-marks/demo.jsx +49 -0
- package/registry/blocks/agent-marks/index.js +3 -0
- package/registry/blocks/agent-pane/README.md +225 -0
- package/registry/blocks/agent-pane/agent-pane.jsx +244 -0
- package/registry/blocks/agent-pane/block.json +41 -0
- package/registry/blocks/agent-pane/composer.jsx +6 -0
- package/registry/blocks/agent-pane/demo.jsx +233 -0
- package/registry/blocks/agent-pane/dock-context.js +10 -0
- package/registry/blocks/agent-pane/index.js +4 -0
- package/registry/blocks/agent-pane/prose.jsx +84 -0
- package/registry/blocks/agent-pane/questions.jsx +134 -0
- package/registry/blocks/agent-pane/transcript.jsx +268 -0
- package/registry/blocks/agent-pane/work.jsx +368 -0
- package/registry/blocks/ai-action/README.md +94 -0
- package/registry/blocks/ai-action/ai-action.jsx +188 -0
- package/registry/blocks/ai-action/block.json +34 -0
- package/registry/blocks/ai-action/demo.jsx +93 -0
- package/registry/blocks/ai-action/index.js +3 -0
- package/registry/blocks/approval/README.md +145 -0
- package/registry/blocks/approval/approval.jsx +163 -0
- package/registry/blocks/approval/block.json +31 -0
- package/registry/blocks/approval/demo.jsx +121 -0
- package/registry/blocks/approval/index.js +3 -0
- package/registry/blocks/ask-bar/README.md +105 -0
- package/registry/blocks/ask-bar/ask-bar.jsx +166 -0
- package/registry/blocks/ask-bar/block.json +26 -0
- package/registry/blocks/ask-bar/demo.jsx +78 -0
- package/registry/blocks/ask-bar/index.js +3 -0
- package/registry/blocks/automation-editor/README.md +291 -0
- package/registry/blocks/automation-editor/automation-editor.jsx +656 -0
- package/registry/blocks/automation-editor/block.json +39 -0
- package/registry/blocks/automation-editor/demo.jsx +284 -0
- package/registry/blocks/automation-editor/index.js +4 -0
- package/registry/blocks/automation-editor/run-inputs.jsx +82 -0
- package/registry/blocks/automation-list/README.md +129 -0
- package/registry/blocks/automation-list/automation-list.jsx +476 -0
- package/registry/blocks/automation-list/block.json +35 -0
- package/registry/blocks/automation-list/demo.jsx +67 -0
- package/registry/blocks/automation-list/index.js +3 -0
- package/registry/blocks/automation-model/README.md +109 -0
- package/registry/blocks/automation-model/block.json +135 -0
- package/registry/blocks/automation-model/catalog.js +256 -0
- package/registry/blocks/automation-model/check.js +161 -0
- package/registry/blocks/automation-model/demo.jsx +42 -0
- package/registry/blocks/automation-model/edit.js +262 -0
- package/registry/blocks/automation-model/fixes.js +287 -0
- package/registry/blocks/automation-model/glyph.jsx +13 -0
- package/registry/blocks/automation-model/graph.js +410 -0
- package/registry/blocks/automation-model/index.js +33 -0
- package/registry/blocks/automation-model/overlay.js +175 -0
- package/registry/blocks/automation-model/parts.jsx +94 -0
- package/registry/blocks/automation-model/schedule.js +53 -0
- package/registry/blocks/automation-model/templates.js +128 -0
- package/registry/blocks/automation-model/values.js +29 -0
- package/registry/blocks/automation-model/words.js +439 -0
- package/registry/blocks/automations-screen/README.md +207 -0
- package/registry/blocks/automations-screen/automations-screen.jsx +452 -0
- package/registry/blocks/automations-screen/block.json +47 -0
- package/registry/blocks/automations-screen/demo.jsx +364 -0
- package/registry/blocks/automations-screen/index.js +4 -0
- package/registry/blocks/automations-screen/screen-model.js +129 -0
- package/registry/blocks/chat-pane/README.md +143 -0
- package/registry/blocks/chat-pane/block.json +48 -0
- package/registry/blocks/chat-pane/chat-attach.js +166 -0
- package/registry/blocks/chat-pane/chat-composer.jsx +195 -0
- package/registry/blocks/chat-pane/chat-context.js +17 -0
- package/registry/blocks/chat-pane/chat-model.js +43 -0
- package/registry/blocks/chat-pane/chat-pane.jsx +398 -0
- package/registry/blocks/chat-pane/chats-list.jsx +52 -0
- package/registry/blocks/chat-pane/demo.jsx +103 -0
- package/registry/blocks/chat-pane/index.js +9 -0
- package/registry/blocks/connect-card/README.md +99 -0
- package/registry/blocks/connect-card/block.json +10 -0
- package/registry/blocks/connect-card/connect-card.jsx +103 -0
- package/registry/blocks/connect-card/demo.jsx +49 -0
- package/registry/blocks/connect-card/index.js +3 -0
- package/registry/blocks/cost/README.md +115 -0
- package/registry/blocks/cost/block.json +10 -0
- package/registry/blocks/cost/cost.jsx +176 -0
- package/registry/blocks/cost/demo.jsx +66 -0
- package/registry/blocks/cost/index.js +3 -0
- package/registry/blocks/data-picker/README.md +81 -0
- package/registry/blocks/data-picker/block.json +38 -0
- package/registry/blocks/data-picker/data-picker.jsx +210 -0
- package/registry/blocks/data-picker/demo.jsx +34 -0
- package/registry/blocks/data-picker/fields.js +89 -0
- package/registry/blocks/data-picker/index.js +4 -0
- package/registry/blocks/data-table/demo.jsx +1 -1
- package/registry/blocks/first-run/README.md +118 -0
- package/registry/blocks/first-run/block.json +11 -0
- package/registry/blocks/first-run/demo.jsx +88 -0
- package/registry/blocks/first-run/first-run-model.js +51 -0
- package/registry/blocks/first-run/first-run.jsx +156 -0
- package/registry/blocks/first-run/index.js +5 -0
- package/registry/blocks/first-run/probe-rules.js +26 -0
- package/registry/blocks/fix-note/README.md +79 -0
- package/registry/blocks/fix-note/block.json +35 -0
- package/registry/blocks/fix-note/demo.jsx +30 -0
- package/registry/blocks/fix-note/fix-note.jsx +235 -0
- package/registry/blocks/fix-note/index.js +3 -0
- package/registry/blocks/flow-editor/README.md +108 -0
- package/registry/blocks/flow-editor/block.json +44 -0
- package/registry/blocks/flow-editor/demo.jsx +115 -0
- package/registry/blocks/flow-editor/flow-canvas.jsx +568 -0
- package/registry/blocks/flow-editor/flow-editor.jsx +154 -0
- package/registry/blocks/flow-editor/index.js +6 -0
- package/registry/blocks/flow-editor/minimap.jsx +78 -0
- package/registry/blocks/flow-editor/outline.jsx +134 -0
- package/registry/blocks/library-shelf/README.md +117 -0
- package/registry/blocks/library-shelf/block.json +28 -0
- package/registry/blocks/library-shelf/demo.jsx +68 -0
- package/registry/blocks/library-shelf/index.js +3 -0
- package/registry/blocks/library-shelf/library-shelf.jsx +211 -0
- package/registry/blocks/library-shelf/probe-rules.js +15 -0
- package/registry/blocks/margin-notes/README.md +222 -0
- package/registry/blocks/margin-notes/block.json +10 -0
- package/registry/blocks/margin-notes/demo.jsx +144 -0
- package/registry/blocks/margin-notes/index.js +20 -0
- package/registry/blocks/margin-notes/margin-model.js +224 -0
- package/registry/blocks/margin-notes/margin-notes.jsx +465 -0
- package/registry/blocks/needs-you/README.md +177 -0
- package/registry/blocks/needs-you/block.json +34 -0
- package/registry/blocks/needs-you/demo.jsx +143 -0
- package/registry/blocks/needs-you/index.js +3 -0
- package/registry/blocks/needs-you/needs-you.jsx +441 -0
- package/registry/blocks/pace-bar/README.md +230 -0
- package/registry/blocks/pace-bar/block.json +10 -0
- package/registry/blocks/pace-bar/demo.jsx +255 -0
- package/registry/blocks/pace-bar/index.js +22 -0
- package/registry/blocks/pace-bar/pace-bar.jsx +461 -0
- package/registry/blocks/pace-bar/pace-model.js +288 -0
- package/registry/blocks/record-grid/README.md +100 -0
- package/registry/blocks/record-grid/block.json +28 -0
- package/registry/blocks/record-grid/demo.jsx +43 -0
- package/registry/blocks/record-grid/index.js +3 -0
- package/registry/blocks/record-grid/record-grid.jsx +251 -0
- package/registry/blocks/run-history/README.md +138 -0
- package/registry/blocks/run-history/block.json +10 -0
- package/registry/blocks/run-history/demo.jsx +74 -0
- package/registry/blocks/run-history/index.js +3 -0
- package/registry/blocks/run-history/run-history.jsx +218 -0
- package/registry/blocks/run-view/README.md +174 -0
- package/registry/blocks/run-view/block.json +50 -0
- package/registry/blocks/run-view/demo.jsx +286 -0
- package/registry/blocks/run-view/index.js +5 -0
- package/registry/blocks/run-view/run-controls.jsx +266 -0
- package/registry/blocks/run-view/run-view.jsx +236 -0
- package/registry/blocks/run-view/runs-list.jsx +99 -0
- package/registry/blocks/schedule-card/README.md +121 -0
- package/registry/blocks/schedule-card/block.json +10 -0
- package/registry/blocks/schedule-card/demo.jsx +82 -0
- package/registry/blocks/schedule-card/index.js +3 -0
- package/registry/blocks/schedule-card/schedule-card.jsx +136 -0
- package/registry/blocks/schedule-engine/README.md +137 -0
- package/registry/blocks/schedule-engine/block.json +10 -0
- package/registry/blocks/schedule-engine/demo.jsx +82 -0
- package/registry/blocks/schedule-engine/engine.js +769 -0
- package/registry/blocks/schedule-engine/index.js +9 -0
- package/registry/blocks/schedule-engine/ops.js +71 -0
- package/registry/blocks/schedule-engine/place.js +294 -0
- package/registry/blocks/schedule-engine/tree.js +79 -0
- package/registry/blocks/schedule-engine/waits.js +80 -0
- package/registry/blocks/schedule-gantt/README.md +159 -0
- package/registry/blocks/schedule-gantt/block.json +10 -0
- package/registry/blocks/schedule-gantt/demo.jsx +223 -0
- package/registry/blocks/schedule-gantt/gantt-model.js +219 -0
- package/registry/blocks/schedule-gantt/geometry.js +176 -0
- package/registry/blocks/schedule-gantt/index.js +26 -0
- package/registry/blocks/schedule-gantt/schedule-gantt.jsx +882 -0
- package/registry/blocks/schedule-gantt/sheet.jsx +372 -0
- package/registry/blocks/schedule-gantt/track.jsx +190 -0
- package/registry/blocks/schedule-ruler/README.md +148 -0
- package/registry/blocks/schedule-ruler/block.json +10 -0
- package/registry/blocks/schedule-ruler/demo.jsx +181 -0
- package/registry/blocks/schedule-ruler/index.js +21 -0
- package/registry/blocks/schedule-ruler/ruler-model.js +239 -0
- package/registry/blocks/schedule-ruler/schedule-ruler.jsx +548 -0
- package/registry/blocks/source-receipt/README.md +97 -0
- package/registry/blocks/source-receipt/block.json +30 -0
- package/registry/blocks/source-receipt/demo.jsx +71 -0
- package/registry/blocks/source-receipt/index.js +3 -0
- package/registry/blocks/source-receipt/source-receipt.jsx +107 -0
- package/registry/blocks/spreadsheet/spreadsheet.jsx +15 -1
- package/registry/blocks/step-picker/README.md +78 -0
- package/registry/blocks/step-picker/block.json +31 -0
- package/registry/blocks/step-picker/demo.jsx +23 -0
- package/registry/blocks/step-picker/index.js +3 -0
- package/registry/blocks/step-picker/step-picker.jsx +144 -0
- package/registry/blocks/step-settings/README.md +100 -0
- package/registry/blocks/step-settings/block.json +44 -0
- package/registry/blocks/step-settings/demo.jsx +93 -0
- package/registry/blocks/step-settings/fields.jsx +58 -0
- package/registry/blocks/step-settings/flow-settings.jsx +115 -0
- package/registry/blocks/step-settings/index.js +5 -0
- package/registry/blocks/step-settings/step-settings.jsx +290 -0
- package/registry/blocks/suggestion/README.md +171 -0
- package/registry/blocks/suggestion/block.json +40 -0
- package/registry/blocks/suggestion/demo.jsx +91 -0
- package/registry/blocks/suggestion/index.js +3 -0
- package/registry/blocks/suggestion/suggestion.jsx +436 -0
- package/registry/blocks/sum-bar/README.md +122 -0
- package/registry/blocks/sum-bar/block.json +10 -0
- package/registry/blocks/sum-bar/demo.jsx +110 -0
- package/registry/blocks/sum-bar/index.js +5 -0
- package/registry/blocks/sum-bar/sum-bar.jsx +209 -0
- package/registry/blocks/sum-bar/sum-model.js +126 -0
- package/registry/blocks/tier-map/README.md +217 -0
- package/registry/blocks/tier-map/block.json +10 -0
- package/registry/blocks/tier-map/demo.jsx +222 -0
- package/registry/blocks/tier-map/index.js +24 -0
- package/registry/blocks/tier-map/tier-map.jsx +574 -0
- package/registry/blocks/tier-map/tier-model.js +318 -0
- package/registry/blocks/time-grid/README.md +305 -0
- package/registry/blocks/time-grid/block.json +10 -0
- package/registry/blocks/time-grid/demo.jsx +279 -0
- package/registry/blocks/time-grid/grid-model.js +322 -0
- package/registry/blocks/time-grid/index.js +25 -0
- package/registry/blocks/time-grid/time-grid.jsx +1325 -0
- package/registry/blocks/time-strip/README.md +141 -0
- package/registry/blocks/time-strip/block.json +10 -0
- package/registry/blocks/time-strip/demo.jsx +129 -0
- package/registry/blocks/time-strip/index.js +19 -0
- package/registry/blocks/time-strip/strip-model.js +178 -0
- package/registry/blocks/time-strip/time-strip.jsx +260 -0
- package/registry/blocks/top-bar/README.md +149 -0
- package/registry/blocks/top-bar/block.json +35 -0
- package/registry/blocks/top-bar/demo.jsx +78 -0
- package/registry/blocks/top-bar/index.js +5 -0
- package/registry/blocks/top-bar/probe-rules.js +74 -0
- package/registry/blocks/top-bar/top-bar-model.js +152 -0
- package/registry/blocks/top-bar/top-bar.jsx +244 -0
- package/registry/blocks/trigger-picker/README.md +98 -0
- package/registry/blocks/trigger-picker/block.json +38 -0
- package/registry/blocks/trigger-picker/demo.jsx +59 -0
- package/registry/blocks/trigger-picker/index.js +3 -0
- package/registry/blocks/trigger-picker/trigger-picker.jsx +374 -0
- package/registry/blocks/workflow-view/README.md +123 -0
- package/registry/blocks/workflow-view/block.json +10 -0
- package/registry/blocks/workflow-view/demo.jsx +90 -0
- package/registry/blocks/workflow-view/index.js +3 -0
- package/registry/blocks/workflow-view/workflow-view.jsx +203 -0
- package/src/install.mjs +77 -16
- package/src/registry.mjs +3 -0
- package/templates/next/browser/lib/data.js +6 -1
- package/templates/next/files/README.md +627 -24
- package/templates/next/files/check/automation-format.ts +2103 -0
- package/templates/next/files/check/automation-package.ts +142 -0
- package/templates/next/files/check/run.mjs +968 -9
- package/templates/next/files/components/ui/field.jsx +17 -4
- package/templates/next/files/components/ui/icon.jsx +13 -0
- package/templates/next/files/components/ui/index.js +2 -1
- package/templates/next/files/components/ui/layout.jsx +77 -2
- package/templates/next/files/components/ui/notice.jsx +70 -0
- package/templates/next/files/components/ui/page.jsx +124 -0
- package/templates/next/files/components/ui/stat.jsx +22 -7
- package/templates/next/files/components/ui/toast.jsx +6 -3
- package/templates/next/files/lib/automations.js +660 -0
- package/templates/next/files/lib/claw.js +241 -5
- package/templates/next/files/lib/door.js +92 -0
- package/templates/next/files/lib/hooks.js +1627 -8
- package/templates/next/files/lib/platform.js +529 -21
- package/templates/next/template.json +13 -3
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# PaceBar
|
|
2
|
+
|
|
3
|
+
Progress against a clock: how far along, and how far along it should be by now.
|
|
4
|
+
|
|
5
|
+
"58%" alone says little. 58% with the mark at 91% says *behind*. This block
|
|
6
|
+
draws that, four ways:
|
|
7
|
+
|
|
8
|
+
- **PaceBar**: one bar, filled to its value, with a hard upright tick where it
|
|
9
|
+
should be by now. The stretch between the fill and the tick is hatched, so
|
|
10
|
+
"behind" is a shape you see, not a sum you do.
|
|
11
|
+
- **PaceList**: many bars on **one axis**. The period's month names and a tick
|
|
12
|
+
each Monday run above. **One today line runs unbroken through the whole
|
|
13
|
+
list**, group headings included. Each row says its percent, who last moved it
|
|
14
|
+
and the gap in weeks ("4 wk behind").
|
|
15
|
+
- **PaceRuler**: that axis alone, with a flag for today ("Today · 92% gone").
|
|
16
|
+
- **WeekStrip**: the period as its weeks in one row, with a mark on each week a
|
|
17
|
+
check-in was made.
|
|
18
|
+
|
|
19
|
+
It draws a result the app has already worked out. It collects no check-ins, it
|
|
20
|
+
changes no number. For a chain of dated phases with gates use `schedule-ruler`;
|
|
21
|
+
for a plain meter with no clock use the kit's `Progress`.
|
|
22
|
+
|
|
23
|
+
Born in two store apps that each drew it by hand: a goals tracker's today line
|
|
24
|
+
down a whole quarter, and a project monitor's "57% done, 88% of the time gone".
|
|
25
|
+
|
|
26
|
+
```jsx
|
|
27
|
+
import { PaceBar, PaceList, PaceRuler, WeekStrip, PaceMark, paceOf, paceWords, paceSentence } from "../components/blocks/pace-bar"; // a Makersclaw app ("./blocks/pace-bar" from components/)
|
|
28
|
+
// shadcn project: import { PaceList } from "@/components/makersclaw/blocks/pace-bar"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
A client component. It needs the `agent-marks` block (the agent's mark) and no
|
|
32
|
+
npm package. Dates are `'YYYY-MM-DD'` strings and are days, never times, so the
|
|
33
|
+
server and the browser draw the same picture. Positions are percentages;
|
|
34
|
+
nothing is measured.
|
|
35
|
+
|
|
36
|
+
## The clock
|
|
37
|
+
|
|
38
|
+
Give a **period** (`start`, `end`, both days included) and **today**. The
|
|
39
|
+
pace is the share of the period that has gone, **today counted**: on Wed 23 Sep
|
|
40
|
+
a quarter that began 1 Jul and ends 30 Sep has 85 of its 92 days gone, so the
|
|
41
|
+
pace is 92%.
|
|
42
|
+
|
|
43
|
+
Or skip the period and give `pace` yourself (0 to 1): a bar needs no dates.
|
|
44
|
+
|
|
45
|
+
The block never reads the clock. `today` always comes in as a prop, so a
|
|
46
|
+
server render and a browser render agree.
|
|
47
|
+
|
|
48
|
+
## Props: PaceBar
|
|
49
|
+
|
|
50
|
+
- `value`: how far along, 0 to 1 (clamped). `null`: not known.
|
|
51
|
+
- `pace`: where it should be by now, 0 to 1. Left out, it is worked out from
|
|
52
|
+
`start`, `end` and `today`. `null` on purpose: no tick, pace not judged.
|
|
53
|
+
- `start`, `end`, `today`: the period.
|
|
54
|
+
- `kind`: `"progress"` (default; short of the pace is the gap) or `"spend"`
|
|
55
|
+
(over the pace is the gap: hours burned against time gone, a budget used).
|
|
56
|
+
- `tone`: `ink` (default), `quiet`, `info`, `success`, `warning`, `danger`,
|
|
57
|
+
or `auto` (ink while on pace or ahead, warning at 10 points behind, danger at
|
|
58
|
+
25; success when done; quiet when not judged yet). A tone is a status: leave
|
|
59
|
+
it `ink` when nothing needs attention.
|
|
60
|
+
- `size`: `lg` (14 px), `md` (10 px, default), `sm` (6 px).
|
|
61
|
+
- `hatch`: draw the gap between the fill and the tick (default true).
|
|
62
|
+
- `animate`: fill from zero on first paint (CSS only), off under reduced
|
|
63
|
+
motion. `delay`: milliseconds before it starts, to stagger a list (capped
|
|
64
|
+
at 540).
|
|
65
|
+
- `tolerance`, `graceDays`, `graceFraction`: see "How it judges" below.
|
|
66
|
+
- `words`: the app's vocabulary (below).
|
|
67
|
+
- `label`: what a screen reader calls it. It reads the sum as words
|
|
68
|
+
(`role="meter"`): "62% done, 92% of the time gone. 4 wk behind".
|
|
69
|
+
- `className`: layout (width, margin). Never colour.
|
|
70
|
+
|
|
71
|
+
## Props: PaceList
|
|
72
|
+
|
|
73
|
+
- `rows`: `[{ id, label, sub, value, pace, kind, tone, by, byLabel, meta, note, group, unit }]`
|
|
74
|
+
- `label`, `sub`: the name and the small line under it.
|
|
75
|
+
- `value`: 0 to 1. `pace`: only when this row has a clock of its own (it
|
|
76
|
+
gets its own tick); otherwise the shared line is its pace.
|
|
77
|
+
- `tone`: as above; default `auto`.
|
|
78
|
+
- `by`: who last moved it: `"person"` (a filled dot), `"agent"` (the agent's
|
|
79
|
+
mark) or nothing. `byLabel`: what a screen reader hears (default "A
|
|
80
|
+
person", "The agent").
|
|
81
|
+
- `meta`: anything to put in the meta column (an owner's avatar, a count).
|
|
82
|
+
Needs `metaWidth`.
|
|
83
|
+
- `note`: replaces the gap words ("1 wk behind · Likely").
|
|
84
|
+
- `group`: the `id` of a group.
|
|
85
|
+
- `groups`: `[{ id, label, sub, note, empty }]` in the order to draw. A heading
|
|
86
|
+
row carries the today line too. `empty` is the line shown when the group has
|
|
87
|
+
no rows. A row whose `group` is not listed goes last, with no heading.
|
|
88
|
+
- `start`, `end`, `today`: the period. They draw the ruler and the line.
|
|
89
|
+
- `pace`: with no period, the shared line's place (0 to 1).
|
|
90
|
+
- `kind`, `tolerance`, `graceDays`, `graceFraction`, `unit`, `warnAt`, `dangerAt`: how rows are
|
|
91
|
+
judged (below). A row's own `kind` or `unit` wins.
|
|
92
|
+
- `heads`: `{ label, meta, pct, gap }`: the column heads, shown from 42rem of
|
|
93
|
+
the container's width.
|
|
94
|
+
- `ruler`: draw the axis above the rows (default true).
|
|
95
|
+
- `weekStartsOn`: weekday the week begins on, 0 = Monday (default).
|
|
96
|
+
- `metaWidth`: a CSS length ("8rem") adds a meta column. Without it there is none.
|
|
97
|
+
- `trackWidth` (default `"24rem"`, the most the bar takes), `gapWidth` (`"9rem"`).
|
|
98
|
+
- `size`: bar thickness (default `sm`).
|
|
99
|
+
- `selected`: the `id` of the row to mark as current.
|
|
100
|
+
- `onOpen(row)`: makes each row a button. Leave it out for a read-only list.
|
|
101
|
+
- `loading`, `error`, `onRetry`, `empty`, `emptyAction`: the other states: a
|
|
102
|
+
skeleton; a danger notice with "Try again"; and, with no rows, an empty panel
|
|
103
|
+
titled `empty`.
|
|
104
|
+
- `label`, `className`.
|
|
105
|
+
|
|
106
|
+
Every row is one grid with the same columns, so the bars of all rows start and
|
|
107
|
+
end at the same x: that is the shared axis. Under 42rem of its own width a row is
|
|
108
|
+
its name on one line and its bar and percent under it.
|
|
109
|
+
|
|
110
|
+
## Props: PaceRuler
|
|
111
|
+
|
|
112
|
+
`start`, `end`, `today`, `weekStartsOn`, `words`, `showToday` (default true),
|
|
113
|
+
`label`, `className`. It is 44px tall and as wide as its parent: put it in the
|
|
114
|
+
column your own rows share, and draw the line down from it with your rows'
|
|
115
|
+
today position (`axisOf(...).todayAt`).
|
|
116
|
+
|
|
117
|
+
## Props: WeekStrip
|
|
118
|
+
|
|
119
|
+
- `start`, `end`, `today`, `weekStartsOn`.
|
|
120
|
+
- `marks`: `[{ id, date, by, label }]`. A mark lands on the week its date falls
|
|
121
|
+
in (before the first week: the first; after the last: the last). `by`:
|
|
122
|
+
`"person"`, `"agent"`, or nothing (a hollow ring). More than three marks in a
|
|
123
|
+
week show "+n".
|
|
124
|
+
- `missed`: put a dashed ring on a past week with no mark at all.
|
|
125
|
+
- `onOpen(week)`: makes each week a button (`{ n, from, to, state, marks }`).
|
|
126
|
+
- `words`: `{ week: "Week" }`. `label`, `className`.
|
|
127
|
+
|
|
128
|
+
The strip keeps each week at least 1.5rem wide and scrolls sideways when the
|
|
129
|
+
period has too many weeks for the container (focusable, so the keyboard scrolls
|
|
130
|
+
it).
|
|
131
|
+
|
|
132
|
+
## PaceMark
|
|
133
|
+
|
|
134
|
+
`<PaceMark by="person" | "agent" label empty missed size />`. Nothing for no
|
|
135
|
+
one; `empty` draws a hollow ring (a mark made by no one), `missed` a dashed one
|
|
136
|
+
(a mark that should be there).
|
|
137
|
+
|
|
138
|
+
## How it judges
|
|
139
|
+
|
|
140
|
+
`paceOf({ value, pace, start, end, today, kind, tolerance, graceDays, graceFraction, unit })`
|
|
141
|
+
(also exported, pure) returns the state:
|
|
142
|
+
|
|
143
|
+
- `done`: progress at 100% or more.
|
|
144
|
+
- `unjudged`: no value, no pace, the period has not started, or it is inside
|
|
145
|
+
`graceDays` of the start (default 0; a quarterly tracker passes 14), or
|
|
146
|
+
inside `graceFraction` of the period from its start (0..1; `0.2` is the
|
|
147
|
+
first fifth, 19 days of a 92-day quarter). The longer of the two counts.
|
|
148
|
+
- `on`: the gap is within `tolerance` whole points of the period (default 5).
|
|
149
|
+
- `worse` / `better`: behind or ahead (progress); over or under (spend).
|
|
150
|
+
|
|
151
|
+
The gap is said in whole weeks, **at least 1**, from the period's length:
|
|
152
|
+
62% against a pace of 92% in a 92-day quarter is `30` points, 27.6 days, "4 wk
|
|
153
|
+
behind". `unit` is `"week"` (default when there is a period), `"day"` or
|
|
154
|
+
`"point"` (no period: "30 pts behind").
|
|
155
|
+
|
|
156
|
+
## Words
|
|
157
|
+
|
|
158
|
+
Every string is the app's to change. `words` merges over these:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
on: "On pace" unjudged: "Not judged yet" done: "Done"
|
|
162
|
+
today: "Today" before: "Not started" after: "Ended"
|
|
163
|
+
units: { week: "wk", day: "d", point: "pts" }
|
|
164
|
+
behind(n, unit) "4 wk behind" ahead(n, unit) "2 wk ahead"
|
|
165
|
+
over(n, unit) "34 pts over" under(n, unit) "17 pts under"
|
|
166
|
+
sentence({ done, gone }) "57% done, 88% of the time gone"
|
|
167
|
+
spendSentence({ done, gone }) "91% used, 57% of the time gone"
|
|
168
|
+
gone(n) "92% gone"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Also exported, pure and without React, for a screen that wants the same numbers
|
|
172
|
+
in a sentence: `paceOf`, `paceWords(state, words)`, `paceSentence(state,
|
|
173
|
+
words)`, `toneOf(state, { warnAt, dangerAt })`, `periodOf`, `axisOf`,
|
|
174
|
+
`weeksOf`, `marksOnWeeks`, `groupRows`, `dayNumber`, `isoOf`, `dayName`,
|
|
175
|
+
`shortDay`, `percent`, `WORDS`.
|
|
176
|
+
|
|
177
|
+
## Example
|
|
178
|
+
|
|
179
|
+
```jsx
|
|
180
|
+
<PaceList
|
|
181
|
+
label="Q3 goals"
|
|
182
|
+
start="2026-07-01"
|
|
183
|
+
end="2026-09-30"
|
|
184
|
+
today="2026-09-23"
|
|
185
|
+
graceDays={14}
|
|
186
|
+
heads={{ label: "Goal", pct: "Done", gap: "Against today" }}
|
|
187
|
+
metaWidth="7rem"
|
|
188
|
+
groups={[{ id: "sales", label: "Sales", sub: "2 goals" }, { id: "eng", label: "Engineering", sub: "1 goal" }]}
|
|
189
|
+
rows={[
|
|
190
|
+
{ id: "a", group: "sales", label: "Close the enterprise gap", value: 0.62, by: "person", meta: owner("Priya") },
|
|
191
|
+
{ id: "b", group: "sales", label: "Turn demos into a motion", value: 0.87 },
|
|
192
|
+
{ id: "c", group: "eng", label: "Keep the rate API fast", value: 0.9, by: "agent" },
|
|
193
|
+
]}
|
|
194
|
+
onOpen={(row) => router.push(`?goal=${row.id}`)}
|
|
195
|
+
/>
|
|
196
|
+
|
|
197
|
+
<WeekStrip start="2026-07-01" end="2026-09-30" today="2026-09-23" missed
|
|
198
|
+
marks={[{ id: "m1", date: "2026-09-14", by: "person" }, { id: "m2", date: "2026-09-21", by: "agent" }]} />
|
|
199
|
+
|
|
200
|
+
// "57% done, 88% of the time gone"
|
|
201
|
+
<p>{paceSentence(paceOf({ value: 0.57, pace: 0.88 }))}</p>
|
|
202
|
+
|
|
203
|
+
// A budget: 91% of the hours used with 57% of the time gone
|
|
204
|
+
<PaceBar kind="spend" value={0.91} pace={0.57} tone="danger" label="Hours" />
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## States drawn
|
|
208
|
+
|
|
209
|
+
- **Empty**: a panel with what to do. With groups and no rows, each heading says
|
|
210
|
+
its `empty` line.
|
|
211
|
+
- **One row**, **many rows**, **grouped**.
|
|
212
|
+
- **Very long names**: the name wraps (rows grow); the bar's column is unchanged.
|
|
213
|
+
- **Narrow** (a 320px container): a row is its name above its bar and percent;
|
|
214
|
+
the ruler is under the column heads.
|
|
215
|
+
- **Wide**: the bar column keeps its `trackWidth`; the name takes the rest.
|
|
216
|
+
- **On pace, behind, ahead, done, not judged yet, before the period, after it.**
|
|
217
|
+
- **Spend**: over the pace hatches from the tick to the fill.
|
|
218
|
+
- **Loading**, **failed** (with Try again), **read-only** (no `onOpen`).
|
|
219
|
+
- Reduced motion: nothing moves unless `animate` is set, and then not under it.
|
|
220
|
+
|
|
221
|
+
## Notes for the app that places it
|
|
222
|
+
|
|
223
|
+
- It is a picture. Put the numbers in words beside it (the list does: the
|
|
224
|
+
percent and the gap words are in every row).
|
|
225
|
+
- Colour is a signal. The fill is ink unless a row is behind (warning, danger)
|
|
226
|
+
or done (success). Do not tint rows for any other reason.
|
|
227
|
+
- For a goals list, give each group a `note` such as "2 need attention" and
|
|
228
|
+
compute it from `paceOf(...).state` yourself; the block does not know your
|
|
229
|
+
words for "needs attention".
|
|
230
|
+
- A row with `by` shows who last moved it; keep the dates in your detail view.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pace-bar",
|
|
3
|
+
"title": "PaceBar",
|
|
4
|
+
"description": "Progress against a clock. PaceBar is one bar filled to its value with a hard upright tick where it should be by now (the share of a period that has gone), and the stretch between them hatched, so behind is a shape you see; a spend (hours burned against time gone) hatches the other way. PaceList puts many bars on ONE axis: the period's month names and a tick each Monday above, one today line running unbroken through the whole list and its group headings, each row's percent, who last moved it (a person's dot, the agent's mark, or none) and the gap said in weeks (\"4 wk behind\", \"On pace\", \"Not judged yet\", \"Done\"); rows sit in optional groups and a row can be pressed. PaceRuler is the axis alone, with a flag for today (\"Today · 92% gone\"). WeekStrip is the period as its weeks in one row: weeks gone filled, this one marked, a mark on each week a check-in was made (person, agent, none), a dashed ring on a past week with none. The sums are exported as plain functions (paceOf, paceWords, paceSentence: \"57% done, 88% of the time gone\"). Positions are percentages, so it draws the same on the server; narrow, a list row is its name above its bar. Loading, failed and empty states are drawn.",
|
|
5
|
+
"useWhen": "Any screen where progress belongs to a period and the question is 'are we on pace': a quarter's goals and their key results, a project's work done against its days gone, hours burned against hours sold, a sprint, a savings or budget target, a course or a reading plan, a campaign's delivery against its flight dates, a weekly check-in cadence. Draws a result the app has already worked out; it does not collect check-ins. Not for a chain of dated phases with gates (schedule-ruler), editable bars with dependencies (gantt), a plain meter with no clock (Progress in the kit), or a time series (chart).",
|
|
6
|
+
"tags": ["pace", "progress", "bar", "target", "behind", "ahead", "on track", "today line", "quarter", "okr", "goals", "key results", "burn", "budget", "spend", "sprint", "weeks behind", "check-in", "cadence", "deadline", "ruler", "agent"],
|
|
7
|
+
"exports": ["PaceBar", "PaceList", "PaceRuler", "WeekStrip", "PaceMark", "WORDS", "atDay", "axisOf", "dayName", "dayNumber", "groupRows", "isoOf", "marksOnWeeks", "paceOf", "paceSentence", "paceWords", "percent", "periodOf", "shortDay", "toneOf", "weeksOf"],
|
|
8
|
+
"files": ["index.js", "pace-bar.jsx", "pace-model.js"],
|
|
9
|
+
"requires": ["agent-marks"]
|
|
10
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// PaceBar in every state — the gallery's and the smoke test's surface. Not
|
|
4
|
+
// installed into apps: `makersclaw add pace-bar` lays index.js, pace-bar.jsx
|
|
5
|
+
// and pace-model.js only.
|
|
6
|
+
// One bar the tones, the sizes, ahead and behind, a spend, no pace,
|
|
7
|
+
// the fill growing in.
|
|
8
|
+
// A list twelve weeks into a quarter: groups, a person's dot and the
|
|
9
|
+
// agent's mark, a meta column, a press on a row, the gap in
|
|
10
|
+
// weeks, "Not judged yet" and "Done".
|
|
11
|
+
// Not judged the first days of a period.
|
|
12
|
+
// Long words a very long name and note.
|
|
13
|
+
// Narrow a 320 px container: the bar under the name.
|
|
14
|
+
// Wide a container well past 1000 px.
|
|
15
|
+
// Read-only no onOpen: nothing is pressable.
|
|
16
|
+
// Empty groups, plain empty, loading, failed.
|
|
17
|
+
// The ruler before, in, and after the period.
|
|
18
|
+
// WeekStrip marks by a person, the agent and no one; missed weeks;
|
|
19
|
+
// a press on a week; many weeks.
|
|
20
|
+
import { useState } from "react";
|
|
21
|
+
import { Avatar, Notice } from "../components/ui";
|
|
22
|
+
import { PaceBar, PaceList, PaceMark, PaceRuler, WeekStrip, paceOf, paceSentence } from "../components/blocks/pace-bar";
|
|
23
|
+
|
|
24
|
+
const Q = { start: "2026-07-01", end: "2026-09-30" };
|
|
25
|
+
const TODAY = "2026-09-23";
|
|
26
|
+
|
|
27
|
+
const GROUPS = [
|
|
28
|
+
{ id: "sales", label: "Sales", sub: "3 goals", note: "2 need attention" },
|
|
29
|
+
{ id: "product", label: "Product", sub: "2 goals" },
|
|
30
|
+
{ id: "ops", label: "Operations", sub: "", empty: "No goals this quarter" },
|
|
31
|
+
];
|
|
32
|
+
const owner = (name) => (
|
|
33
|
+
<span className="flex min-w-0 items-center gap-1.5 text-xs">
|
|
34
|
+
<Avatar name={name} size="xs" />
|
|
35
|
+
<span className="truncate">{name.split(" ")[0]}</span>
|
|
36
|
+
</span>
|
|
37
|
+
);
|
|
38
|
+
const ROWS = [
|
|
39
|
+
{ id: "g1", group: "sales", label: "Close the enterprise gap before the October price change", sub: "3 key results", value: 0.62, by: "person", meta: owner("Priya Raman") },
|
|
40
|
+
{ id: "g2", group: "sales", label: "Turn inbound demos into a repeatable motion", sub: "2 key results", value: 0.87, by: "agent", meta: owner("Marcus Reyes") },
|
|
41
|
+
{ id: "g3", group: "sales", label: "Win back the lapsed accounts", sub: "1 key result", value: 0.75, meta: owner("Hannah Cole"), note: "2 wk behind · Unsure" },
|
|
42
|
+
{ id: "g4", group: "product", label: "Make onboarding self-serve for new merchants", sub: "3 key results", value: 0.86, by: "person", meta: owner("Lena Vogel") },
|
|
43
|
+
{ id: "g5", group: "product", label: "Ship the rate API v2", sub: "Closed 18 Sep", value: 1, by: "person", meta: owner("Daniel Brandt") },
|
|
44
|
+
];
|
|
45
|
+
const LONG = [
|
|
46
|
+
{
|
|
47
|
+
id: "l1",
|
|
48
|
+
label: "An exceptionally long name for a goal that nobody had the heart to shorten, which goes on and on past the end of any sensible line",
|
|
49
|
+
sub: "and a long small line under it that also keeps going well past where it should have stopped",
|
|
50
|
+
value: 0.31,
|
|
51
|
+
by: "agent",
|
|
52
|
+
note: "A very long note about why this one is where it is and what the owner said on Monday",
|
|
53
|
+
},
|
|
54
|
+
{ id: "l2", label: "Short", value: 0.93 },
|
|
55
|
+
];
|
|
56
|
+
const EARLY_ROWS = ROWS.slice(0, 3).map((r) => ({ ...r, value: 0.04 }));
|
|
57
|
+
|
|
58
|
+
const MARKS = [
|
|
59
|
+
{ id: "a", date: "2026-07-13", by: "person" },
|
|
60
|
+
{ id: "b", date: "2026-07-20", by: "person" },
|
|
61
|
+
{ id: "c", date: "2026-07-27", by: "agent" },
|
|
62
|
+
{ id: "d", date: "2026-08-10", by: "person" },
|
|
63
|
+
{ id: "e", date: "2026-08-10", by: "agent" },
|
|
64
|
+
{ id: "f", date: "2026-08-11", by: "person" },
|
|
65
|
+
{ id: "g", date: "2026-08-12" },
|
|
66
|
+
{ id: "h", date: "2026-08-24", by: "agent" },
|
|
67
|
+
{ id: "i", date: "2026-09-07", by: "person" },
|
|
68
|
+
{ id: "j", date: "2026-09-14", by: "person" },
|
|
69
|
+
{ id: "k", date: "2026-09-21", by: "agent" },
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
function Section({ title, note, children }) {
|
|
73
|
+
return (
|
|
74
|
+
<section className="grid min-w-0 gap-2">
|
|
75
|
+
<h2 className="text-sm font-semibold">{title}</h2>
|
|
76
|
+
{note ? <p className="text-xs text-muted-foreground">{note}</p> : null}
|
|
77
|
+
{children}
|
|
78
|
+
</section>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function Line({ label, children }) {
|
|
83
|
+
return (
|
|
84
|
+
<div className="grid grid-cols-[minmax(0,12rem)_minmax(0,1fr)] items-center gap-4">
|
|
85
|
+
<span className="truncate text-xs text-muted-foreground">{label}</span>
|
|
86
|
+
{children}
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export default function Demo() {
|
|
92
|
+
const [pressed, setPressed] = useState(null);
|
|
93
|
+
const [week, setWeek] = useState(null);
|
|
94
|
+
const [grown, setGrown] = useState(0);
|
|
95
|
+
const sum = paceOf({ value: 0.57, pace: 0.88 });
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<div className="grid min-w-0 gap-8 p-6">
|
|
99
|
+
<Section title="One bar" note="Fill to the value, a tick at the pace, the stretch between hatched. Here the pace is 91%.">
|
|
100
|
+
<div className="grid max-w-xl gap-4">
|
|
101
|
+
<Line label="Behind, warning">
|
|
102
|
+
<PaceBar value={0.58} pace={0.91} tone="warning" size="lg" label="Behind" />
|
|
103
|
+
</Line>
|
|
104
|
+
<Line label="Far behind, danger">
|
|
105
|
+
<PaceBar value={0.3} pace={0.91} tone="danger" label="Far behind" />
|
|
106
|
+
</Line>
|
|
107
|
+
<Line label="On pace, ink">
|
|
108
|
+
<PaceBar value={0.89} pace={0.91} label="On pace" />
|
|
109
|
+
</Line>
|
|
110
|
+
<Line label="Ahead, info">
|
|
111
|
+
<PaceBar value={0.97} pace={0.91} tone="info" size="sm" label="Ahead" />
|
|
112
|
+
</Line>
|
|
113
|
+
<Line label="Done, success">
|
|
114
|
+
<PaceBar value={1} pace={0.91} tone="success" label="Done" />
|
|
115
|
+
</Line>
|
|
116
|
+
<Line label="Quiet row">
|
|
117
|
+
<PaceBar value={0.4} pace={0.91} tone="quiet" size="sm" label="Quiet" />
|
|
118
|
+
</Line>
|
|
119
|
+
<Line label="No pace (not judged)">
|
|
120
|
+
<PaceBar value={0.22} pace={null} tone="quiet" label="No pace" />
|
|
121
|
+
</Line>
|
|
122
|
+
<Line label="Auto tone, from a period">
|
|
123
|
+
<PaceBar {...Q} today={TODAY} value={0.62} tone="auto" label="Auto" />
|
|
124
|
+
</Line>
|
|
125
|
+
<Line label="A spend, over the pace">
|
|
126
|
+
<PaceBar kind="spend" value={0.91} pace={0.57} tone="danger" label="Hours used" />
|
|
127
|
+
</Line>
|
|
128
|
+
<Line label="A spend, under the pace">
|
|
129
|
+
<PaceBar kind="spend" value={0.4} pace={0.57} label="Hours used, under" />
|
|
130
|
+
</Line>
|
|
131
|
+
<Line label="Nothing yet, not known">
|
|
132
|
+
<div className="grid gap-3">
|
|
133
|
+
<PaceBar value={0} pace={0.5} label="Nothing yet" />
|
|
134
|
+
<PaceBar value={null} pace={0.5} label="Not known" />
|
|
135
|
+
</div>
|
|
136
|
+
</Line>
|
|
137
|
+
</div>
|
|
138
|
+
<p className="font-mono text-xs text-muted-foreground">{paceSentence(sum)}</p>
|
|
139
|
+
</Section>
|
|
140
|
+
|
|
141
|
+
<Section title="The fill grows in" note="animate and delay: press to run it again. Nothing moves under reduced motion.">
|
|
142
|
+
<button type="button" onClick={() => setGrown((n) => n + 1)} className="w-fit rounded-sm border border-border px-2 py-1 text-xs hover:bg-muted">
|
|
143
|
+
Run again
|
|
144
|
+
</button>
|
|
145
|
+
<div key={grown} className="grid max-w-xl gap-3">
|
|
146
|
+
{[0.62, 0.75, 0.86, 0.9].map((v, i) => (
|
|
147
|
+
<PaceBar key={v} value={v} pace={0.92} tone="warning" animate delay={i * 120} label={`Row ${i + 1}`} />
|
|
148
|
+
))}
|
|
149
|
+
</div>
|
|
150
|
+
</Section>
|
|
151
|
+
|
|
152
|
+
<Section title="A list" note="Twelve weeks into the quarter. One today line through the groups; the gap in weeks. Press a row.">
|
|
153
|
+
<div className="rounded-md border border-border">
|
|
154
|
+
<PaceList
|
|
155
|
+
label="Q3 goals"
|
|
156
|
+
{...Q}
|
|
157
|
+
today={TODAY}
|
|
158
|
+
graceDays={14}
|
|
159
|
+
heads={{ label: "Goal", meta: "Owner", pct: "Done", gap: "Against today" }}
|
|
160
|
+
metaWidth="7rem"
|
|
161
|
+
groups={GROUPS}
|
|
162
|
+
rows={ROWS}
|
|
163
|
+
selected={pressed?.id}
|
|
164
|
+
onOpen={setPressed}
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
<p aria-live="polite" className="font-mono text-xs text-muted-foreground">
|
|
168
|
+
{pressed ? `Pressed: ${pressed.label}` : "Nothing pressed yet"}
|
|
169
|
+
</p>
|
|
170
|
+
</Section>
|
|
171
|
+
|
|
172
|
+
<Section title="Not judged yet" note="The second day of a quarter: every row shows its number, none a status. The line is still there.">
|
|
173
|
+
<div className="rounded-md border border-border">
|
|
174
|
+
<PaceList label="Q4 goals" start="2026-10-01" end="2026-12-31" today="2026-10-06" graceDays={14} heads={{ label: "Goal", pct: "Done", gap: "Against today" }} rows={EARLY_ROWS} />
|
|
175
|
+
</div>
|
|
176
|
+
</Section>
|
|
177
|
+
|
|
178
|
+
<Section title="Long words" note="Names and notes wrap; the bar column does not move.">
|
|
179
|
+
<div className="rounded-md border border-border">
|
|
180
|
+
<PaceList label="Long" {...Q} today={TODAY} rows={LONG} />
|
|
181
|
+
</div>
|
|
182
|
+
</Section>
|
|
183
|
+
|
|
184
|
+
<Section title="Narrow, 320 px" note="A row is its name, then its bar and percent, then the gap in words.">
|
|
185
|
+
<div className="w-[320px] max-w-full rounded-md border border-border">
|
|
186
|
+
<PaceList label="Narrow" {...Q} today={TODAY} groups={GROUPS.slice(0, 2)} rows={ROWS} />
|
|
187
|
+
</div>
|
|
188
|
+
</Section>
|
|
189
|
+
|
|
190
|
+
<Section title="Wide">
|
|
191
|
+
<div className="w-[1200px] max-w-none rounded-md border border-border">
|
|
192
|
+
<PaceList
|
|
193
|
+
label="Wide"
|
|
194
|
+
{...Q}
|
|
195
|
+
today={TODAY}
|
|
196
|
+
heads={{ label: "Goal", meta: "Owner", pct: "Done", gap: "Against today" }}
|
|
197
|
+
metaWidth="8rem"
|
|
198
|
+
trackWidth="32rem"
|
|
199
|
+
groups={GROUPS}
|
|
200
|
+
rows={ROWS}
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
</Section>
|
|
204
|
+
|
|
205
|
+
<Section title="Read-only, no groups, a pace and no period" note="No onOpen: nothing is a button. No dates: the line stands where `pace` says (60%).">
|
|
206
|
+
<div className="rounded-md border border-border">
|
|
207
|
+
<PaceList label="Read-only" pace={0.6} ruler={false} rows={[{ id: "r1", label: "Reading plan", value: 0.4 }, { id: "r2", label: "Savings", value: 0.72, tone: "success" }]} />
|
|
208
|
+
</div>
|
|
209
|
+
</Section>
|
|
210
|
+
|
|
211
|
+
<Section title="After the period, and before it">
|
|
212
|
+
<div className="grid gap-4 rounded-md border border-border py-2">
|
|
213
|
+
<PaceList label="Ended" {...Q} today="2026-10-12" rows={ROWS.slice(0, 2)} />
|
|
214
|
+
<PaceList label="Not started" {...Q} today="2026-06-15" rows={ROWS.slice(0, 2)} />
|
|
215
|
+
</div>
|
|
216
|
+
</Section>
|
|
217
|
+
|
|
218
|
+
<Section title="Empty, loading, failed">
|
|
219
|
+
<PaceList label="Empty" empty="No goals yet. Start from a template." />
|
|
220
|
+
<PaceList label="Loading" loading />
|
|
221
|
+
<PaceList label="Goals" error="The goals could not be read. Check the connection." onRetry={() => setPressed({ id: "retry", label: "Try again" })} />
|
|
222
|
+
</Section>
|
|
223
|
+
|
|
224
|
+
<Section title="PaceRuler alone" note="Before, in, and after the period.">
|
|
225
|
+
<div className="grid max-w-2xl gap-3">
|
|
226
|
+
<PaceRuler {...Q} today={TODAY} />
|
|
227
|
+
<PaceRuler {...Q} today="2026-07-12" />
|
|
228
|
+
<PaceRuler {...Q} today="2026-06-20" />
|
|
229
|
+
<PaceRuler {...Q} today="2026-10-12" />
|
|
230
|
+
</div>
|
|
231
|
+
</Section>
|
|
232
|
+
|
|
233
|
+
<Section title="WeekStrip" note="A person's dot, the agent's mark, a hollow ring for a mark by no one, a dashed ring for a week with none. Press a week.">
|
|
234
|
+
<div className="grid max-w-2xl gap-4">
|
|
235
|
+
<WeekStrip {...Q} today={TODAY} marks={MARKS} missed onOpen={setWeek} />
|
|
236
|
+
<p aria-live="polite" className="font-mono text-xs text-muted-foreground">
|
|
237
|
+
{week ? `Week ${week.n}, ${week.marks.length} marks` : "No week pressed yet"}
|
|
238
|
+
</p>
|
|
239
|
+
<div className="w-[320px] max-w-full">
|
|
240
|
+
<WeekStrip {...Q} today={TODAY} marks={MARKS} label="Narrow weeks" />
|
|
241
|
+
</div>
|
|
242
|
+
<WeekStrip start="2026-01-01" end="2026-12-31" today={TODAY} label="A year" />
|
|
243
|
+
<div className="flex items-center gap-4 text-xs text-muted-foreground">
|
|
244
|
+
<span className="flex items-center gap-1.5"><PaceMark by="person" /> a person</span>
|
|
245
|
+
<span className="flex items-center gap-1.5"><PaceMark by="agent" /> the agent</span>
|
|
246
|
+
<span className="flex items-center gap-1.5"><PaceMark empty /> no one</span>
|
|
247
|
+
<span className="flex items-center gap-1.5"><PaceMark missed /> missed</span>
|
|
248
|
+
</div>
|
|
249
|
+
</div>
|
|
250
|
+
</Section>
|
|
251
|
+
|
|
252
|
+
<Notice tone="info">Every date is a day, never a time: 2026-09-23 means the same day on the server and in the browser.</Notice>
|
|
253
|
+
</div>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// The PaceBar block — `makersclaw add pace-bar`. Fixed: compose it through
|
|
2
|
+
// its props (README.md beside this file). The model's helpers are plain
|
|
3
|
+
// functions; they work on the server too.
|
|
4
|
+
export { PaceBar, PaceList, PaceRuler, WeekStrip, PaceMark } from "./pace-bar";
|
|
5
|
+
export {
|
|
6
|
+
WORDS,
|
|
7
|
+
atDay,
|
|
8
|
+
axisOf,
|
|
9
|
+
dayName,
|
|
10
|
+
dayNumber,
|
|
11
|
+
groupRows,
|
|
12
|
+
isoOf,
|
|
13
|
+
marksOnWeeks,
|
|
14
|
+
paceOf,
|
|
15
|
+
paceSentence,
|
|
16
|
+
paceWords,
|
|
17
|
+
percent,
|
|
18
|
+
periodOf,
|
|
19
|
+
shortDay,
|
|
20
|
+
toneOf,
|
|
21
|
+
weeksOf,
|
|
22
|
+
} from "./pace-model";
|