makersclaw 0.7.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.
Files changed (419) hide show
  1. package/README.md +17 -4
  2. package/package.json +1 -1
  3. package/r/activity-log.json +52 -0
  4. package/r/agent-changes.json +51 -0
  5. package/r/agent-chat.json +53 -0
  6. package/r/agent-column.json +85 -0
  7. package/r/agent-dock.json +57 -0
  8. package/r/agent-kit.json +49 -0
  9. package/r/agent-marks.json +49 -0
  10. package/r/agent-pane.json +93 -0
  11. package/r/ai-action.json +56 -0
  12. package/r/annotate.json +4 -4
  13. package/r/approval-request.json +2 -2
  14. package/r/approval.json +54 -0
  15. package/r/ask-bar.json +50 -0
  16. package/r/audio-player.json +2 -2
  17. package/r/auth-form.json +2 -2
  18. package/r/automation-editor.json +66 -0
  19. package/r/automation-list.json +57 -0
  20. package/r/automation-model.json +118 -0
  21. package/r/automations-screen.json +71 -0
  22. package/r/board.json +2 -2
  23. package/r/calendar-view.json +3 -3
  24. package/r/cart.json +2 -2
  25. package/r/chart.json +5 -5
  26. package/r/chat-pane.json +84 -0
  27. package/r/chat.json +3 -3
  28. package/r/code-editor.json +2 -2
  29. package/r/comment-box.json +3 -3
  30. package/r/connect-card.json +51 -0
  31. package/r/contact-section.json +2 -2
  32. package/r/core.json +18 -6
  33. package/r/cost.json +51 -0
  34. package/r/csv-import.json +3 -3
  35. package/r/data-picker.json +60 -0
  36. package/r/data-table.json +2 -2
  37. package/r/diagram.json +2 -2
  38. package/r/doc-editor.json +2 -2
  39. package/r/doc-page.json +3 -3
  40. package/r/email-render.json +2 -2
  41. package/r/faq.json +2 -2
  42. package/r/file-upload.json +2 -2
  43. package/r/first-run.json +63 -0
  44. package/r/fix-note.json +57 -0
  45. package/r/flow-canvas.json +3 -3
  46. package/r/flow-editor.json +79 -0
  47. package/r/footer.json +3 -3
  48. package/r/gantt.json +3 -3
  49. package/r/job-panel.json +2 -2
  50. package/r/json-editor.json +3 -3
  51. package/r/library-shelf.json +56 -0
  52. package/r/map.json +2 -2
  53. package/r/margin-notes.json +67 -0
  54. package/r/menubar.json +2 -2
  55. package/r/mind-map.json +4 -4
  56. package/r/navigation-menu.json +2 -2
  57. package/r/needs-you.json +55 -0
  58. package/r/order-detail.json +2 -2
  59. package/r/org-chart.json +4 -4
  60. package/r/pace-bar.json +69 -0
  61. package/r/page-builder.json +3 -3
  62. package/r/payment-methods.json +2 -2
  63. package/r/pdf-document.json +2 -2
  64. package/r/pdf-viewer.json +3 -3
  65. package/r/product-detail.json +2 -2
  66. package/r/product-grid.json +3 -3
  67. package/r/record-form.json +2 -2
  68. package/r/record-grid.json +52 -0
  69. package/r/record-notes.json +4 -4
  70. package/r/registry.json +4089 -1510
  71. package/r/run-history.json +52 -0
  72. package/r/run-view.json +80 -0
  73. package/r/schedule-card.json +54 -0
  74. package/r/schedule-engine.json +79 -0
  75. package/r/schedule-gantt.json +83 -0
  76. package/r/schedule-ruler.json +64 -0
  77. package/r/search-dialog.json +2 -2
  78. package/r/settings-list.json +2 -2
  79. package/r/setup-checklist.json +2 -2
  80. package/r/share-dialog.json +2 -2
  81. package/r/sidebar.json +3 -3
  82. package/r/signature-pad.json +2 -2
  83. package/r/sketch-canvas.json +3 -3
  84. package/r/source-receipt.json +52 -0
  85. package/r/spreadsheet.json +3 -3
  86. package/r/stat-cards.json +3 -3
  87. package/r/step-picker.json +53 -0
  88. package/r/step-settings.json +72 -0
  89. package/r/suggestion.json +58 -0
  90. package/r/sum-bar.json +64 -0
  91. package/r/task-list.json +3 -3
  92. package/r/task-model.json +2 -2
  93. package/r/testimonials.json +2 -2
  94. package/r/tier-map.json +67 -0
  95. package/r/time-grid.json +73 -0
  96. package/r/time-strip.json +64 -0
  97. package/r/top-bar.json +66 -0
  98. package/r/transaction-list.json +2 -2
  99. package/r/trigger-picker.json +61 -0
  100. package/r/whiteboard.json +4 -4
  101. package/r/workflow-view.json +55 -0
  102. package/registry/blocks/activity-log/README.md +112 -0
  103. package/registry/blocks/activity-log/activity-log.jsx +351 -0
  104. package/registry/blocks/activity-log/block.json +33 -0
  105. package/registry/blocks/activity-log/demo.jsx +48 -0
  106. package/registry/blocks/activity-log/index.js +4 -0
  107. package/registry/blocks/agent-changes/README.md +94 -0
  108. package/registry/blocks/agent-changes/agent-changes.jsx +118 -0
  109. package/registry/blocks/agent-changes/block.json +28 -0
  110. package/registry/blocks/agent-changes/demo.jsx +39 -0
  111. package/registry/blocks/agent-changes/index.js +3 -0
  112. package/registry/blocks/agent-chat/README.md +145 -0
  113. package/registry/blocks/agent-chat/agent-chat.jsx +415 -0
  114. package/registry/blocks/agent-chat/block.json +30 -0
  115. package/registry/blocks/agent-chat/demo.jsx +165 -0
  116. package/registry/blocks/agent-chat/index.js +3 -0
  117. package/registry/blocks/agent-column/README.md +197 -0
  118. package/registry/blocks/agent-column/agent-column.jsx +492 -0
  119. package/registry/blocks/agent-column/block.json +67 -0
  120. package/registry/blocks/agent-column/column-picker.jsx +163 -0
  121. package/registry/blocks/agent-column/demo.jsx +50 -0
  122. package/registry/blocks/agent-column/index.js +7 -0
  123. package/registry/blocks/agent-column/model.js +164 -0
  124. package/registry/blocks/agent-column/receipt.jsx +483 -0
  125. package/registry/blocks/agent-column/spreadsheet-type.jsx +24 -0
  126. package/registry/blocks/agent-dock/README.md +210 -0
  127. package/registry/blocks/agent-dock/agent-dock.jsx +356 -0
  128. package/registry/blocks/agent-dock/block.json +47 -0
  129. package/registry/blocks/agent-dock/demo.jsx +153 -0
  130. package/registry/blocks/agent-dock/dock-model.js +118 -0
  131. package/registry/blocks/agent-dock/index.js +5 -0
  132. package/registry/blocks/agent-kit/README.md +73 -0
  133. package/registry/blocks/agent-kit/agent-kit.jsx +86 -0
  134. package/registry/blocks/agent-kit/block.json +10 -0
  135. package/registry/blocks/agent-kit/demo.jsx +35 -0
  136. package/registry/blocks/agent-kit/index.js +3 -0
  137. package/registry/blocks/agent-marks/README.md +80 -0
  138. package/registry/blocks/agent-marks/agent-marks.jsx +133 -0
  139. package/registry/blocks/agent-marks/block.json +27 -0
  140. package/registry/blocks/agent-marks/demo.jsx +49 -0
  141. package/registry/blocks/agent-marks/index.js +3 -0
  142. package/registry/blocks/agent-pane/README.md +225 -0
  143. package/registry/blocks/agent-pane/agent-pane.jsx +244 -0
  144. package/registry/blocks/agent-pane/block.json +41 -0
  145. package/registry/blocks/agent-pane/composer.jsx +6 -0
  146. package/registry/blocks/agent-pane/demo.jsx +233 -0
  147. package/registry/blocks/agent-pane/dock-context.js +10 -0
  148. package/registry/blocks/agent-pane/index.js +4 -0
  149. package/registry/blocks/agent-pane/prose.jsx +84 -0
  150. package/registry/blocks/agent-pane/questions.jsx +134 -0
  151. package/registry/blocks/agent-pane/transcript.jsx +268 -0
  152. package/registry/blocks/agent-pane/work.jsx +368 -0
  153. package/registry/blocks/ai-action/README.md +94 -0
  154. package/registry/blocks/ai-action/ai-action.jsx +188 -0
  155. package/registry/blocks/ai-action/block.json +34 -0
  156. package/registry/blocks/ai-action/demo.jsx +93 -0
  157. package/registry/blocks/ai-action/index.js +3 -0
  158. package/registry/blocks/annotate/README.md +14 -11
  159. package/registry/blocks/approval/README.md +145 -0
  160. package/registry/blocks/approval/approval.jsx +163 -0
  161. package/registry/blocks/approval/block.json +31 -0
  162. package/registry/blocks/approval/demo.jsx +121 -0
  163. package/registry/blocks/approval/index.js +3 -0
  164. package/registry/blocks/ask-bar/README.md +105 -0
  165. package/registry/blocks/ask-bar/ask-bar.jsx +166 -0
  166. package/registry/blocks/ask-bar/block.json +26 -0
  167. package/registry/blocks/ask-bar/demo.jsx +78 -0
  168. package/registry/blocks/ask-bar/index.js +3 -0
  169. package/registry/blocks/automation-editor/README.md +291 -0
  170. package/registry/blocks/automation-editor/automation-editor.jsx +656 -0
  171. package/registry/blocks/automation-editor/block.json +39 -0
  172. package/registry/blocks/automation-editor/demo.jsx +284 -0
  173. package/registry/blocks/automation-editor/index.js +4 -0
  174. package/registry/blocks/automation-editor/run-inputs.jsx +82 -0
  175. package/registry/blocks/automation-list/README.md +129 -0
  176. package/registry/blocks/automation-list/automation-list.jsx +476 -0
  177. package/registry/blocks/automation-list/block.json +35 -0
  178. package/registry/blocks/automation-list/demo.jsx +67 -0
  179. package/registry/blocks/automation-list/index.js +3 -0
  180. package/registry/blocks/automation-model/README.md +109 -0
  181. package/registry/blocks/automation-model/block.json +135 -0
  182. package/registry/blocks/automation-model/catalog.js +256 -0
  183. package/registry/blocks/automation-model/check.js +161 -0
  184. package/registry/blocks/automation-model/demo.jsx +42 -0
  185. package/registry/blocks/automation-model/edit.js +262 -0
  186. package/registry/blocks/automation-model/fixes.js +287 -0
  187. package/registry/blocks/automation-model/glyph.jsx +13 -0
  188. package/registry/blocks/automation-model/graph.js +410 -0
  189. package/registry/blocks/automation-model/index.js +33 -0
  190. package/registry/blocks/automation-model/overlay.js +175 -0
  191. package/registry/blocks/automation-model/parts.jsx +94 -0
  192. package/registry/blocks/automation-model/schedule.js +53 -0
  193. package/registry/blocks/automation-model/templates.js +128 -0
  194. package/registry/blocks/automation-model/values.js +29 -0
  195. package/registry/blocks/automation-model/words.js +439 -0
  196. package/registry/blocks/automations-screen/README.md +207 -0
  197. package/registry/blocks/automations-screen/automations-screen.jsx +452 -0
  198. package/registry/blocks/automations-screen/block.json +47 -0
  199. package/registry/blocks/automations-screen/demo.jsx +364 -0
  200. package/registry/blocks/automations-screen/index.js +4 -0
  201. package/registry/blocks/automations-screen/screen-model.js +129 -0
  202. package/registry/blocks/chart/cartesian.jsx +1 -1
  203. package/registry/blocks/chart/core.jsx +33 -23
  204. package/registry/blocks/chart/pie.jsx +1 -1
  205. package/registry/blocks/chat/README.md +4 -1
  206. package/registry/blocks/chat/demo.jsx +2 -2
  207. package/registry/blocks/chat-pane/README.md +143 -0
  208. package/registry/blocks/chat-pane/block.json +48 -0
  209. package/registry/blocks/chat-pane/chat-attach.js +166 -0
  210. package/registry/blocks/chat-pane/chat-composer.jsx +195 -0
  211. package/registry/blocks/chat-pane/chat-context.js +17 -0
  212. package/registry/blocks/chat-pane/chat-model.js +43 -0
  213. package/registry/blocks/chat-pane/chat-pane.jsx +398 -0
  214. package/registry/blocks/chat-pane/chats-list.jsx +52 -0
  215. package/registry/blocks/chat-pane/demo.jsx +103 -0
  216. package/registry/blocks/chat-pane/index.js +9 -0
  217. package/registry/blocks/connect-card/README.md +99 -0
  218. package/registry/blocks/connect-card/block.json +10 -0
  219. package/registry/blocks/connect-card/connect-card.jsx +103 -0
  220. package/registry/blocks/connect-card/demo.jsx +49 -0
  221. package/registry/blocks/connect-card/index.js +3 -0
  222. package/registry/blocks/cost/README.md +115 -0
  223. package/registry/blocks/cost/block.json +10 -0
  224. package/registry/blocks/cost/cost.jsx +176 -0
  225. package/registry/blocks/cost/demo.jsx +66 -0
  226. package/registry/blocks/cost/index.js +3 -0
  227. package/registry/blocks/data-picker/README.md +81 -0
  228. package/registry/blocks/data-picker/block.json +38 -0
  229. package/registry/blocks/data-picker/data-picker.jsx +210 -0
  230. package/registry/blocks/data-picker/demo.jsx +34 -0
  231. package/registry/blocks/data-picker/fields.js +89 -0
  232. package/registry/blocks/data-picker/index.js +4 -0
  233. package/registry/blocks/data-table/demo.jsx +1 -1
  234. package/registry/blocks/first-run/README.md +118 -0
  235. package/registry/blocks/first-run/block.json +11 -0
  236. package/registry/blocks/first-run/demo.jsx +88 -0
  237. package/registry/blocks/first-run/first-run-model.js +51 -0
  238. package/registry/blocks/first-run/first-run.jsx +156 -0
  239. package/registry/blocks/first-run/index.js +5 -0
  240. package/registry/blocks/first-run/probe-rules.js +26 -0
  241. package/registry/blocks/fix-note/README.md +79 -0
  242. package/registry/blocks/fix-note/block.json +35 -0
  243. package/registry/blocks/fix-note/demo.jsx +30 -0
  244. package/registry/blocks/fix-note/fix-note.jsx +235 -0
  245. package/registry/blocks/fix-note/index.js +3 -0
  246. package/registry/blocks/flow-canvas/README.md +15 -8
  247. package/registry/blocks/flow-editor/README.md +108 -0
  248. package/registry/blocks/flow-editor/block.json +44 -0
  249. package/registry/blocks/flow-editor/demo.jsx +115 -0
  250. package/registry/blocks/flow-editor/flow-canvas.jsx +568 -0
  251. package/registry/blocks/flow-editor/flow-editor.jsx +154 -0
  252. package/registry/blocks/flow-editor/index.js +6 -0
  253. package/registry/blocks/flow-editor/minimap.jsx +78 -0
  254. package/registry/blocks/flow-editor/outline.jsx +134 -0
  255. package/registry/blocks/footer/README.md +3 -2
  256. package/registry/blocks/library-shelf/README.md +117 -0
  257. package/registry/blocks/library-shelf/block.json +28 -0
  258. package/registry/blocks/library-shelf/demo.jsx +68 -0
  259. package/registry/blocks/library-shelf/index.js +3 -0
  260. package/registry/blocks/library-shelf/library-shelf.jsx +211 -0
  261. package/registry/blocks/library-shelf/probe-rules.js +15 -0
  262. package/registry/blocks/margin-notes/README.md +222 -0
  263. package/registry/blocks/margin-notes/block.json +10 -0
  264. package/registry/blocks/margin-notes/demo.jsx +144 -0
  265. package/registry/blocks/margin-notes/index.js +20 -0
  266. package/registry/blocks/margin-notes/margin-model.js +224 -0
  267. package/registry/blocks/margin-notes/margin-notes.jsx +465 -0
  268. package/registry/blocks/mind-map/README.md +4 -2
  269. package/registry/blocks/needs-you/README.md +177 -0
  270. package/registry/blocks/needs-you/block.json +34 -0
  271. package/registry/blocks/needs-you/demo.jsx +143 -0
  272. package/registry/blocks/needs-you/index.js +3 -0
  273. package/registry/blocks/needs-you/needs-you.jsx +441 -0
  274. package/registry/blocks/org-chart/README.md +4 -2
  275. package/registry/blocks/pace-bar/README.md +230 -0
  276. package/registry/blocks/pace-bar/block.json +10 -0
  277. package/registry/blocks/pace-bar/demo.jsx +255 -0
  278. package/registry/blocks/pace-bar/index.js +22 -0
  279. package/registry/blocks/pace-bar/pace-bar.jsx +461 -0
  280. package/registry/blocks/pace-bar/pace-model.js +288 -0
  281. package/registry/blocks/page-builder/README.md +1 -1
  282. package/registry/blocks/page-builder/demo.jsx +3 -3
  283. package/registry/blocks/pdf-viewer/README.md +4 -1
  284. package/registry/blocks/record-grid/README.md +100 -0
  285. package/registry/blocks/record-grid/block.json +28 -0
  286. package/registry/blocks/record-grid/demo.jsx +43 -0
  287. package/registry/blocks/record-grid/index.js +3 -0
  288. package/registry/blocks/record-grid/record-grid.jsx +251 -0
  289. package/registry/blocks/run-history/README.md +138 -0
  290. package/registry/blocks/run-history/block.json +10 -0
  291. package/registry/blocks/run-history/demo.jsx +74 -0
  292. package/registry/blocks/run-history/index.js +3 -0
  293. package/registry/blocks/run-history/run-history.jsx +218 -0
  294. package/registry/blocks/run-view/README.md +174 -0
  295. package/registry/blocks/run-view/block.json +50 -0
  296. package/registry/blocks/run-view/demo.jsx +286 -0
  297. package/registry/blocks/run-view/index.js +5 -0
  298. package/registry/blocks/run-view/run-controls.jsx +266 -0
  299. package/registry/blocks/run-view/run-view.jsx +236 -0
  300. package/registry/blocks/run-view/runs-list.jsx +99 -0
  301. package/registry/blocks/schedule-card/README.md +121 -0
  302. package/registry/blocks/schedule-card/block.json +10 -0
  303. package/registry/blocks/schedule-card/demo.jsx +82 -0
  304. package/registry/blocks/schedule-card/index.js +3 -0
  305. package/registry/blocks/schedule-card/schedule-card.jsx +136 -0
  306. package/registry/blocks/schedule-engine/README.md +137 -0
  307. package/registry/blocks/schedule-engine/block.json +10 -0
  308. package/registry/blocks/schedule-engine/demo.jsx +82 -0
  309. package/registry/blocks/schedule-engine/engine.js +769 -0
  310. package/registry/blocks/schedule-engine/index.js +9 -0
  311. package/registry/blocks/schedule-engine/ops.js +71 -0
  312. package/registry/blocks/schedule-engine/place.js +294 -0
  313. package/registry/blocks/schedule-engine/tree.js +79 -0
  314. package/registry/blocks/schedule-engine/waits.js +80 -0
  315. package/registry/blocks/schedule-gantt/README.md +159 -0
  316. package/registry/blocks/schedule-gantt/block.json +10 -0
  317. package/registry/blocks/schedule-gantt/demo.jsx +223 -0
  318. package/registry/blocks/schedule-gantt/gantt-model.js +219 -0
  319. package/registry/blocks/schedule-gantt/geometry.js +176 -0
  320. package/registry/blocks/schedule-gantt/index.js +26 -0
  321. package/registry/blocks/schedule-gantt/schedule-gantt.jsx +882 -0
  322. package/registry/blocks/schedule-gantt/sheet.jsx +372 -0
  323. package/registry/blocks/schedule-gantt/track.jsx +190 -0
  324. package/registry/blocks/schedule-ruler/README.md +148 -0
  325. package/registry/blocks/schedule-ruler/block.json +10 -0
  326. package/registry/blocks/schedule-ruler/demo.jsx +181 -0
  327. package/registry/blocks/schedule-ruler/index.js +21 -0
  328. package/registry/blocks/schedule-ruler/ruler-model.js +239 -0
  329. package/registry/blocks/schedule-ruler/schedule-ruler.jsx +548 -0
  330. package/registry/blocks/sidebar/README.md +23 -13
  331. package/registry/blocks/sketch-canvas/README.md +15 -9
  332. package/registry/blocks/source-receipt/README.md +97 -0
  333. package/registry/blocks/source-receipt/block.json +30 -0
  334. package/registry/blocks/source-receipt/demo.jsx +71 -0
  335. package/registry/blocks/source-receipt/index.js +3 -0
  336. package/registry/blocks/source-receipt/source-receipt.jsx +107 -0
  337. package/registry/blocks/spreadsheet/spreadsheet.jsx +15 -1
  338. package/registry/blocks/step-picker/README.md +78 -0
  339. package/registry/blocks/step-picker/block.json +31 -0
  340. package/registry/blocks/step-picker/demo.jsx +23 -0
  341. package/registry/blocks/step-picker/index.js +3 -0
  342. package/registry/blocks/step-picker/step-picker.jsx +144 -0
  343. package/registry/blocks/step-settings/README.md +100 -0
  344. package/registry/blocks/step-settings/block.json +44 -0
  345. package/registry/blocks/step-settings/demo.jsx +93 -0
  346. package/registry/blocks/step-settings/fields.jsx +58 -0
  347. package/registry/blocks/step-settings/flow-settings.jsx +115 -0
  348. package/registry/blocks/step-settings/index.js +5 -0
  349. package/registry/blocks/step-settings/step-settings.jsx +290 -0
  350. package/registry/blocks/suggestion/README.md +171 -0
  351. package/registry/blocks/suggestion/block.json +40 -0
  352. package/registry/blocks/suggestion/demo.jsx +91 -0
  353. package/registry/blocks/suggestion/index.js +3 -0
  354. package/registry/blocks/suggestion/suggestion.jsx +436 -0
  355. package/registry/blocks/sum-bar/README.md +122 -0
  356. package/registry/blocks/sum-bar/block.json +10 -0
  357. package/registry/blocks/sum-bar/demo.jsx +110 -0
  358. package/registry/blocks/sum-bar/index.js +5 -0
  359. package/registry/blocks/sum-bar/sum-bar.jsx +209 -0
  360. package/registry/blocks/sum-bar/sum-model.js +126 -0
  361. package/registry/blocks/tier-map/README.md +217 -0
  362. package/registry/blocks/tier-map/block.json +10 -0
  363. package/registry/blocks/tier-map/demo.jsx +222 -0
  364. package/registry/blocks/tier-map/index.js +24 -0
  365. package/registry/blocks/tier-map/tier-map.jsx +574 -0
  366. package/registry/blocks/tier-map/tier-model.js +318 -0
  367. package/registry/blocks/time-grid/README.md +305 -0
  368. package/registry/blocks/time-grid/block.json +10 -0
  369. package/registry/blocks/time-grid/demo.jsx +279 -0
  370. package/registry/blocks/time-grid/grid-model.js +322 -0
  371. package/registry/blocks/time-grid/index.js +25 -0
  372. package/registry/blocks/time-grid/time-grid.jsx +1325 -0
  373. package/registry/blocks/time-strip/README.md +141 -0
  374. package/registry/blocks/time-strip/block.json +10 -0
  375. package/registry/blocks/time-strip/demo.jsx +129 -0
  376. package/registry/blocks/time-strip/index.js +19 -0
  377. package/registry/blocks/time-strip/strip-model.js +178 -0
  378. package/registry/blocks/time-strip/time-strip.jsx +260 -0
  379. package/registry/blocks/top-bar/README.md +149 -0
  380. package/registry/blocks/top-bar/block.json +35 -0
  381. package/registry/blocks/top-bar/demo.jsx +78 -0
  382. package/registry/blocks/top-bar/index.js +5 -0
  383. package/registry/blocks/top-bar/probe-rules.js +74 -0
  384. package/registry/blocks/top-bar/top-bar-model.js +152 -0
  385. package/registry/blocks/top-bar/top-bar.jsx +244 -0
  386. package/registry/blocks/trigger-picker/README.md +98 -0
  387. package/registry/blocks/trigger-picker/block.json +38 -0
  388. package/registry/blocks/trigger-picker/demo.jsx +59 -0
  389. package/registry/blocks/trigger-picker/index.js +3 -0
  390. package/registry/blocks/trigger-picker/trigger-picker.jsx +374 -0
  391. package/registry/blocks/whiteboard/README.md +20 -14
  392. package/registry/blocks/workflow-view/README.md +123 -0
  393. package/registry/blocks/workflow-view/block.json +10 -0
  394. package/registry/blocks/workflow-view/demo.jsx +90 -0
  395. package/registry/blocks/workflow-view/index.js +3 -0
  396. package/registry/blocks/workflow-view/workflow-view.jsx +203 -0
  397. package/src/cli.mjs +2 -2
  398. package/src/install.mjs +100 -22
  399. package/src/registry.mjs +37 -3
  400. package/templates/next/browser/lib/data.js +6 -1
  401. package/templates/next/files/README.md +909 -26
  402. package/templates/next/files/app/shell.jsx +54 -37
  403. package/templates/next/files/check/automation-format.ts +2103 -0
  404. package/templates/next/files/check/automation-package.ts +142 -0
  405. package/templates/next/files/check/run.mjs +1043 -12
  406. package/templates/next/files/components/ui/field.jsx +17 -4
  407. package/templates/next/files/components/ui/icon.jsx +13 -0
  408. package/templates/next/files/components/ui/index.js +3 -1
  409. package/templates/next/files/components/ui/layout.jsx +382 -0
  410. package/templates/next/files/components/ui/notice.jsx +70 -0
  411. package/templates/next/files/components/ui/page.jsx +124 -0
  412. package/templates/next/files/components/ui/stat.jsx +22 -7
  413. package/templates/next/files/components/ui/toast.jsx +6 -3
  414. package/templates/next/files/lib/automations.js +660 -0
  415. package/templates/next/files/lib/claw.js +244 -5
  416. package/templates/next/files/lib/door.js +92 -0
  417. package/templates/next/files/lib/hooks.js +1694 -6
  418. package/templates/next/files/lib/platform.js +611 -14
  419. package/templates/next/template.json +22 -3
@@ -0,0 +1,436 @@
1
+ "use client";
2
+
3
+ // A value the agent proposes, drawn in pencil: dashed while it is a
4
+ // proposal, solid once kept (the app kit, D15; grown in the CRM as
5
+ // field-suggestion, 0.7.0). Five shapes, one idea — the source is always
6
+ // shown, and a person keeps or drops it:
7
+ //
8
+ // FieldSuggestion under a field, with what it holds now
9
+ // InlineSuggestion found in place: a dashed chip in the cell it would fill
10
+ // TextSuggestion a span of text struck, its replacement beside it
11
+ // Pencil the dashed frame for a whole record ("pencil to ink")
12
+ // SuggestionGroup the head over several: Keep all, Drop all
13
+ //
14
+ // The verbs are props (Keep/Drop, Apply/Dismiss, Accept/Decline). A keep
15
+ // calls your callback, which runs the app's own declared action, so a
16
+ // keep is the same write the agent would make. Props in, callbacks out;
17
+ // the block never reads a database. Tokens only.
18
+
19
+ import { useState } from "react";
20
+ import { Button, Icon, IconButton, cx } from "../../ui";
21
+
22
+ /** "her email signature, Sat 12 Sep" from { from, at }. `at` is a
23
+ * "YYYY-MM-DD" day (or anything Date reads); `format(date)` words it,
24
+ * default "Sat 12 Sep". */
25
+ export function suggestionSource({ from, at } = {}, format) {
26
+ if (!from && !at) return "";
27
+ let when = "";
28
+ if (at) {
29
+ const d = typeof at === "string" && /^\d{4}-\d{2}-\d{2}$/.test(at) ? new Date(`${at}T12:00:00Z`) : new Date(at);
30
+ if (!Number.isNaN(d.getTime())) {
31
+ when = format ? format(d) : d.toLocaleDateString("en-GB", { weekday: "short", day: "numeric", month: "short", timeZone: "UTC" }).replace(",", "");
32
+ }
33
+ }
34
+ return [from, when].filter(Boolean).join(", ");
35
+ }
36
+
37
+ const FRAME = {
38
+ pencil: "border-[1.5px] border-dashed border-foreground/35 bg-card",
39
+ kept: "border-[1.5px] border-solid border-success/60 bg-card",
40
+ failed: "border-[1.5px] border-dashed border-destructive/60 bg-card",
41
+ };
42
+
43
+ /** The dashed frame for any proposal: a kicker ("A NEW DEAL"), a title,
44
+ * the reason, your content, your actions. `state` "pencil" (default),
45
+ * "kept" (solid) or "failed" (with `error`). */
46
+ export function Pencil({ kicker, title, reason, state = "pencil", error, actions, label, className, children }) {
47
+ return (
48
+ <section
49
+ aria-label={label ?? (typeof title === "string" ? `Suggested: ${title}` : "A suggestion")}
50
+ className={cx("grid grid-cols-1 min-w-0 gap-2 rounded-lg p-3", FRAME[state] ?? FRAME.pencil, className)}
51
+ >
52
+ {kicker ? <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">{kicker}</p> : null}
53
+ {title ? <div className="min-w-0 text-[15px] font-semibold leading-snug">{title}</div> : null}
54
+ {children}
55
+ {reason ? <p className="text-sm text-muted-foreground">{reason}</p> : null}
56
+ {state === "failed" && error ? (
57
+ <p role="alert" className="text-sm text-destructive">
58
+ {error}
59
+ </p>
60
+ ) : null}
61
+ {actions ? <div className="flex flex-wrap items-center gap-2">{actions}</div> : null}
62
+ </section>
63
+ );
64
+ }
65
+
66
+ /**
67
+ * One proposed value for one field.
68
+ *
69
+ * label the field's name ("Job title")
70
+ * current what it holds now; empty → "empty now"
71
+ * value the proposed value (text or a node)
72
+ * source { from, at } or a string: where it came from
73
+ * onKeep() async → { ok } | { ok: false, error }
74
+ * onDrop() async → { ok } | { ok: false, error }
75
+ * compact icon Keep/Drop at the row's end (a list of several)
76
+ * showLabel false when the field's label is drawn by you above it
77
+ * keepLabel · dropLabel · keptLabel the verbs ("Apply", "Dismiss", "Applied")
78
+ */
79
+ export function FieldSuggestion({
80
+ label,
81
+ current,
82
+ value,
83
+ source,
84
+ onKeep,
85
+ onDrop,
86
+ compact = false,
87
+ showLabel = true,
88
+ keepLabel = "Keep",
89
+ dropLabel = "Drop",
90
+ keptLabel = "Kept",
91
+ formatDate,
92
+ className,
93
+ }) {
94
+ const [busy, setBusy] = useState(null);
95
+ const [state, setState] = useState("pencil");
96
+ const [error, setError] = useState(null);
97
+ const from = typeof source === "string" ? source : suggestionSource(source, formatDate);
98
+ const empty = current == null || current === "";
99
+
100
+ async function run(which, fn) {
101
+ if (!fn || busy) return;
102
+ setBusy(which);
103
+ setError(null);
104
+ let r;
105
+ try {
106
+ r = await fn();
107
+ } catch (e) {
108
+ r = { ok: false, error: e?.message ?? String(e) };
109
+ }
110
+ setBusy(null);
111
+ if (r && r.ok === false) {
112
+ setState("failed");
113
+ setError(r.error || `Couldn't ${(which === "keep" ? keepLabel : dropLabel).toLowerCase()} it. Try again.`);
114
+ return;
115
+ }
116
+ setState(which === "keep" ? "kept" : "dropped");
117
+ }
118
+
119
+ if (state === "dropped") return null;
120
+ const name = typeof label === "string" ? label.toLowerCase() : "this";
121
+ return (
122
+ <div className={cx("@container grid grid-cols-1 min-w-0 gap-1", className)}>
123
+ {showLabel && label ? (
124
+ <p className="text-xs text-muted-foreground">
125
+ {label}
126
+ {state === "kept" ? ` · ${keptLabel.toLowerCase()}` : empty ? " · empty now" : ` · now ${typeof current === "string" ? current : ""}`}
127
+ </p>
128
+ ) : null}
129
+ <div
130
+ role="group"
131
+ aria-label={`Suggested ${name}`}
132
+ className={cx(
133
+ "grid min-w-0 gap-2 rounded-md px-3 py-2",
134
+ // Side by side from 22rem of its own width; under it the
135
+ // buttons go below the value. Compact icons always fit beside.
136
+ compact ? "grid-cols-[minmax(0,1fr)_auto] items-center gap-3" : "grid-cols-1 @[22rem]:grid-cols-[minmax(0,1fr)_auto] @[22rem]:items-center @[22rem]:gap-3",
137
+ FRAME[state] ?? FRAME.pencil,
138
+ )}
139
+ >
140
+ <div className="grid grid-cols-1 min-w-0 gap-0.5">
141
+ {compact && label ? <span className="text-xs text-muted-foreground">{label}</span> : null}
142
+ <span className="min-w-0 break-words text-sm font-semibold">{value}</span>
143
+ {from ? <span className="text-xs text-muted-foreground">{from}</span> : null}
144
+ {state === "failed" && error ? (
145
+ <span role="alert" className="text-xs text-destructive">
146
+ {error}
147
+ </span>
148
+ ) : null}
149
+ </div>
150
+ {state === "kept" ? (
151
+ <span className="inline-flex items-center gap-1 text-xs font-medium text-success">
152
+ <Icon name="check" size={14} />
153
+ {keptLabel}
154
+ </span>
155
+ ) : compact ? (
156
+ <span className="flex items-center gap-1">
157
+ <IconButton icon="check" size="sm" variant="secondary" label={`${keepLabel} ${name}`} disabled={Boolean(busy)} onClick={() => run("keep", onKeep)} />
158
+ <IconButton icon="x" size="sm" label={`${dropLabel} ${name}`} disabled={Boolean(busy)} onClick={() => run("drop", onDrop)} />
159
+ </span>
160
+ ) : (
161
+ <span className="flex flex-wrap items-center gap-1">
162
+ <Button size="sm" variant="primary" loading={busy === "keep"} disabled={Boolean(busy)} onClick={() => run("keep", onKeep)} aria-label={`${keepLabel} ${name}`}>
163
+ {keepLabel}
164
+ </Button>
165
+ <Button size="sm" variant="quiet" loading={busy === "drop"} disabled={Boolean(busy)} onClick={() => run("drop", onDrop)} aria-label={`${dropLabel} ${name}`}>
166
+ {dropLabel}
167
+ </Button>
168
+ </span>
169
+ )}
170
+ </div>
171
+ </div>
172
+ );
173
+ }
174
+
175
+ /** The header for several suggestions on one record: what was found and
176
+ * where from, Keep all and Drop all. */
177
+ export function SuggestionGroup({ title, description, count, onKeepAll, onDropAll, keepAllLabel, dropAllLabel = "Drop all", className, children }) {
178
+ const [busy, setBusy] = useState(null);
179
+ const [error, setError] = useState(null);
180
+ async function run(which, fn) {
181
+ if (!fn || busy) return;
182
+ setBusy(which);
183
+ setError(null);
184
+ let r;
185
+ try {
186
+ r = await fn();
187
+ } catch (e) {
188
+ r = { ok: false, error: e?.message ?? String(e) };
189
+ }
190
+ setBusy(null);
191
+ if (r && r.ok === false) setError(r.error || "That didn't work. Try again.");
192
+ }
193
+ return (
194
+ <div className={cx("grid grid-cols-1 min-w-0 gap-3", className)}>
195
+ <div role="status" className={cx("flex min-w-0 flex-wrap items-center gap-3 rounded-lg px-4 py-3", FRAME.pencil)}>
196
+ <Icon name="sparkles" className="text-muted-foreground" />
197
+ <div className="grid min-w-0 flex-1 basis-56 grid-cols-1 gap-0.5">
198
+ <p className="text-sm font-semibold">{title}</p>
199
+ {description ? <p className="text-sm text-muted-foreground">{description}</p> : null}
200
+ {error ? (
201
+ <p role="alert" className="text-sm text-destructive">
202
+ {error}
203
+ </p>
204
+ ) : null}
205
+ </div>
206
+ <span className="flex flex-wrap items-center gap-2">
207
+ {onKeepAll ? (
208
+ <Button size="sm" variant="primary" loading={busy === "keep"} disabled={Boolean(busy)} onClick={() => run("keep", onKeepAll)}>
209
+ {keepAllLabel ?? (count ? `Keep all ${count}` : "Keep all")}
210
+ </Button>
211
+ ) : null}
212
+ {onDropAll ? (
213
+ <Button size="sm" variant="quiet" loading={busy === "drop"} disabled={Boolean(busy)} onClick={() => run("drop", onDropAll)}>
214
+ {dropAllLabel}
215
+ </Button>
216
+ ) : null}
217
+ </span>
218
+ </div>
219
+ {children}
220
+ </div>
221
+ );
222
+ }
223
+
224
+ /**
225
+ * Found in place: the proposed value inside the cell or field it would
226
+ * fill, as a small dashed chip in the agent's tone, with where it came
227
+ * from and a tick to keep and a cross to drop (0.7.0, the CRM's v2
228
+ * signature). Same callbacks as FieldSuggestion.
229
+ *
230
+ * value the proposed value
231
+ * source { from, at } or a string ("her email signature, Sat 12 Sep")
232
+ * label the field's name, for the buttons ("Keep job title")
233
+ * onKeep() · onDrop() async → { ok } | { ok: false, error }
234
+ * keepLabel · dropLabel the verbs the buttons say to a reader
235
+ */
236
+ export function InlineSuggestion({ value, source, label, onKeep, onDrop, keepLabel = "Keep", dropLabel = "Drop", formatDate, className }) {
237
+ const [busy, setBusy] = useState(null);
238
+ const [state, setState] = useState("pencil");
239
+ const [error, setError] = useState(null);
240
+ const from = typeof source === "string" ? source : suggestionSource(source, formatDate);
241
+ const name = typeof label === "string" ? label.toLowerCase() : "this";
242
+ async function run(which, fn) {
243
+ if (!fn || busy) return;
244
+ setBusy(which);
245
+ setError(null);
246
+ let r;
247
+ try {
248
+ r = await fn();
249
+ } catch (e) {
250
+ r = { ok: false, error: e?.message ?? String(e) };
251
+ }
252
+ setBusy(null);
253
+ if (r && r.ok === false) {
254
+ setState("failed");
255
+ setError(r.error || "That didn't work. Try again.");
256
+ return;
257
+ }
258
+ setState(which === "keep" ? "kept" : "dropped");
259
+ }
260
+ if (state === "dropped") return null;
261
+ return (
262
+ <span
263
+ role="group"
264
+ aria-label={`Suggested ${name}: ${typeof value === "string" ? value : ""}`}
265
+ title={error ?? (from ? `Found by the agent: ${from}` : undefined)}
266
+ className={cx(
267
+ "inline-flex h-[22px] min-w-0 max-w-full items-center gap-1.5 whitespace-nowrap rounded-[4px] border border-dashed pl-[7px] pr-[3px] align-middle text-[13px] text-foreground",
268
+ state === "kept" ? "border-solid border-success" : state === "failed" ? "border-destructive" : "border-info",
269
+ className,
270
+ )}
271
+ >
272
+ <span className="min-w-0 truncate">{value}</span>
273
+ {from ? <span className="min-w-0 truncate text-[11.5px] text-muted-foreground">{from}</span> : null}
274
+ {state === "kept" ? (
275
+ <Icon name="check" size={12} className="shrink-0 text-success" label="Kept" />
276
+ ) : (
277
+ <>
278
+ <button
279
+ type="button"
280
+ aria-label={`${keepLabel} ${name}`}
281
+ disabled={Boolean(busy)}
282
+ onClick={(e) => {
283
+ e.stopPropagation();
284
+ run("keep", onKeep);
285
+ }}
286
+ className="grid grid-cols-1 size-[18px] shrink-0 place-items-center rounded-[3px] text-success outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50"
287
+ >
288
+ <Icon name="check" size={12} />
289
+ </button>
290
+ <button
291
+ type="button"
292
+ aria-label={`${dropLabel} ${name}`}
293
+ disabled={Boolean(busy)}
294
+ onClick={(e) => {
295
+ e.stopPropagation();
296
+ run("drop", onDrop);
297
+ }}
298
+ className="grid grid-cols-1 size-[18px] shrink-0 place-items-center rounded-[3px] text-muted-foreground outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50"
299
+ >
300
+ <Icon name="x" size={12} />
301
+ </button>
302
+ </>
303
+ )}
304
+ {state === "failed" && error ? <span className="sr-only" role="alert">{error}</span> : null}
305
+ </span>
306
+ );
307
+ }
308
+
309
+ /** "Looking…" in the agent's tone, where a value is still being found. */
310
+ export function Looking({ children = "Looking…", className }) {
311
+ return (
312
+ <span className={cx("inline-flex items-center gap-[5px] text-[13px] text-info motion-safe:animate-pulse", className)}>
313
+ <Icon name="sparkles" size={12} />
314
+ {children}
315
+ </span>
316
+ );
317
+ }
318
+
319
+ /**
320
+ * A change to a span of text, as an editor's proof mark: the old words
321
+ * struck, the new beside them, why, and where from (Writing Review's proof
322
+ * marks; Notes, Landing Page Reviewer). Kept, the new words stand alone in
323
+ * a solid frame; dropped, it goes.
324
+ *
325
+ * before the words now (struck); empty for an insertion
326
+ * after the words proposed; empty for a cut
327
+ * lead · tail a few words around the span, muted, so it reads in place
328
+ * reason why, one line ("“your” is the owner's, “you're” is “you are”")
329
+ * source { from, at } or a string: what it leans on (a style guide, a page)
330
+ * onKeep() · onDrop() async → { ok } | { ok: false, error }
331
+ * keepLabel · dropLabel · keptLabel default "Keep", "Drop", "Kept"
332
+ */
333
+ export function TextSuggestion({
334
+ before,
335
+ after,
336
+ lead,
337
+ tail,
338
+ reason,
339
+ source,
340
+ onKeep,
341
+ onDrop,
342
+ keepLabel = "Keep",
343
+ dropLabel = "Drop",
344
+ keptLabel = "Kept",
345
+ formatDate,
346
+ className,
347
+ }) {
348
+ const [busy, setBusy] = useState(null);
349
+ const [state, setState] = useState("pencil");
350
+ const [error, setError] = useState(null);
351
+ const from = typeof source === "string" ? source : suggestionSource(source, formatDate);
352
+ const cut = after == null || after === "";
353
+ const insert = before == null || before === "";
354
+
355
+ async function run(which, fn) {
356
+ if (!fn || busy) return;
357
+ setBusy(which);
358
+ setError(null);
359
+ let r;
360
+ try {
361
+ r = await fn();
362
+ } catch (e) {
363
+ r = { ok: false, error: e?.message ?? String(e) };
364
+ }
365
+ setBusy(null);
366
+ if (r && r.ok === false) {
367
+ setState("failed");
368
+ setError(r.error || `Couldn't ${(which === "keep" ? keepLabel : dropLabel).toLowerCase()} it. Try again.`);
369
+ return;
370
+ }
371
+ setState(which === "keep" ? "kept" : "dropped");
372
+ }
373
+
374
+ if (state === "dropped") return null;
375
+ const kept = state === "kept";
376
+ const what = cut ? "Cut" : insert ? "Add" : "Change";
377
+ return (
378
+ <div
379
+ role="group"
380
+ aria-label={`Suggested ${what.toLowerCase()}${typeof after === "string" && after ? `: ${after}` : ""}`}
381
+ className={cx("@container grid grid-cols-1 min-w-0 gap-2 rounded-md px-3 py-2 text-sm", FRAME[state] ?? FRAME.pencil, className)}
382
+ >
383
+ <p className="min-w-0 break-words leading-relaxed">
384
+ {lead ? <span className="text-muted-foreground">{lead}</span> : null}
385
+ {kept ? (
386
+ cut ? null : <span className="font-semibold">{after}</span>
387
+ ) : (
388
+ <>
389
+ {insert ? null : (
390
+ <del className="text-muted-foreground decoration-foreground decoration-[1.5px]">
391
+ <span className="sr-only">Remove: </span>
392
+ {before}
393
+ </del>
394
+ )}
395
+ {!insert && !cut ? (
396
+ <Icon name="arrow-right" size={12} className="mx-1 inline-block align-[-0.1em] text-muted-foreground" />
397
+ ) : null}
398
+ {cut ? null : (
399
+ <ins className="font-semibold no-underline">
400
+ <span className="sr-only">Add: </span>
401
+ {after}
402
+ </ins>
403
+ )}
404
+ </>
405
+ )}
406
+ {tail ? <span className="text-muted-foreground">{tail}</span> : null}
407
+ </p>
408
+ {reason && !kept ? <p className="text-xs text-muted-foreground">{reason}</p> : null}
409
+ {from && !kept ? <p className="text-xs text-muted-foreground">{from}</p> : null}
410
+ {state === "failed" && error ? (
411
+ <p role="alert" className="text-xs text-destructive">
412
+ {error}
413
+ </p>
414
+ ) : null}
415
+ {kept ? (
416
+ <span className="inline-flex items-center gap-1 text-xs font-medium text-success">
417
+ <Icon name="check" size={14} />
418
+ {keptLabel}
419
+ </span>
420
+ ) : onKeep || onDrop ? (
421
+ <span className="flex flex-wrap items-center gap-1">
422
+ {onKeep ? (
423
+ <Button size="sm" variant="primary" loading={busy === "keep"} disabled={Boolean(busy)} onClick={() => run("keep", onKeep)}>
424
+ {keepLabel}
425
+ </Button>
426
+ ) : null}
427
+ {onDrop ? (
428
+ <Button size="sm" variant="quiet" loading={busy === "drop"} disabled={Boolean(busy)} onClick={() => run("drop", onDrop)}>
429
+ {dropLabel}
430
+ </Button>
431
+ ) : null}
432
+ </span>
433
+ ) : null}
434
+ </div>
435
+ );
436
+ }
@@ -0,0 +1,122 @@
1
+ # SumBar
2
+
3
+ A total with its parts cut out of it, so a number can be checked, not trusted.
4
+
5
+ A health score of 35 says little. "100, less 22 for the schedule, 25 for the
6
+ budget, 5 late, 8 blocked, 5 quiet client" says everything. This block draws
7
+ that sum to scale:
8
+
9
+ - **The bar** runs from 0 to the total (100). What is left is solid, with its
10
+ number in it.
11
+ - **Each part is a hatched block cut from the top end downward**, in the tone
12
+ of its part (`warning`, `danger`, `info`, `neutral`), its cost written in it
13
+ and its name under it. A part can be pressed.
14
+ - **A rule that holds the result down** (a cap) is a **post** standing on the
15
+ bar with a flag above it. When the cap bites, the stretch between the sum
16
+ and the result is dotted and the receipt says so.
17
+ - **Bands** under the bar name the ranges (off track, at risk, on track).
18
+ - **The receipt** writes the sum out: `100 − 22 − 25 − 5 − 8 − 0 − 5 = 35`,
19
+ or `100 − 44 = 56, held at 49`.
20
+
21
+ It draws a result the app has already worked out. It scores nothing and
22
+ changes no number. For a total split into shares use the kit's `Distribution`;
23
+ for progress against a clock use `pace-bar`.
24
+
25
+ Born in a project monitor's score sheet ("57% done, 88% of the time gone" is
26
+ `pace-bar`; the 35 it costs is this). Fits any app that scores out of 100 and
27
+ must show its working.
28
+
29
+ ```jsx
30
+ import { SumBar, receiptOf, resultOf, sumWords } from "../components/blocks/sum-bar"; // a Makersclaw app ("./blocks/sum-bar" from components/)
31
+ import { SumBar } from "@/components/makersclaw/blocks/sum-bar"; // a shadcn project
32
+ ```
33
+
34
+ A client component. No other block, no npm package. Positions are percentages
35
+ of the total, so a server render and a browser render agree.
36
+
37
+ ## Props
38
+
39
+ - `total`: the whole (default `100`).
40
+ - `parts`: `[{ id, label, cost, tone, note }]`, taken off in the order given,
41
+ from the top end of the bar. `cost` is a number (0 or more; anything else
42
+ counts as 0). A part that costs nothing is no block on the bar but is a term
43
+ in the receipt. `tone`: `neutral` (default), `info`, `warning`, `danger`.
44
+ - `result`: the number after a rule held it down. Left out, it is the total
45
+ less the costs. Lower than that, the difference is "held" (dotted).
46
+ - `posts`: `[{ at, label, tone }]`: a dashed post at `at` (0 to the total),
47
+ with a flag above. `tone: "danger"` draws it in the danger colour.
48
+ - `bands`: `[{ from, to, tone, label }]`: a thin coloured strip under the bar
49
+ and a label centred under each band. `tone`: `success`, `warning`, `danger`,
50
+ `info`, `neutral`.
51
+ - `selected`, `onSelect(part)`: with `onSelect` every cut is a button; the
52
+ selected one is ringed. Without it the cuts are read-only.
53
+ - `size`: `sm` (24 px), `md` (36 px, default), `lg` (48 px).
54
+ - `names`: the names under the cuts (default `true`). They show from 32rem of
55
+ the block's own width, and only under cuts wide enough to hold a name.
56
+ - `legend`: a list of every part and its cost under the bar (default `false`).
57
+ - `receipt`: the written sum (default `true`).
58
+ - `unit`: appended to the receipt (`"points"`). `noun`: what a screen reader
59
+ calls one unit (default `"point"`).
60
+ - `label`: what a screen reader calls the whole (default "Score sheet").
61
+ - `status`: `ready` (default), `loading` (a skeleton), `failed` (a danger
62
+ notice with `error` and a Try again when `onRetry` is given).
63
+ - `className`: layout around it. Never colour.
64
+
65
+ ## The sums (plain functions, no React)
66
+
67
+ - `resultOf({ total, parts, result })` → `{ total, lost, kept, result, held, raised }`
68
+ - `cutsOf({ total, parts })` → each part with `from`, `to`, `leftPct`, `widthPct`, `cut`
69
+ - `postsOf({ total, posts })`, `bandsOf({ total, bands })`: placed, out-of-range ones dropped
70
+ - `receiptOf({ total, parts, result, unit })` → `{ …resultOf, terms, text }`
71
+ - `sumWords({ total, parts, result, posts, noun })`: the whole bar in a sentence
72
+ - `costOf(value)`, `totalOf(total)`, `lostOf(parts)`, `labelledCuts(cuts, minPct)`
73
+
74
+ ## Example
75
+
76
+ ```jsx
77
+ // A project's score: 100 less what each signal cost, held at 49 by two reds.
78
+ <SumBar
79
+ label="Website rebuild, score sheet"
80
+ parts={[
81
+ { id: "schedule", label: "Schedule", cost: 22, tone: "danger" },
82
+ { id: "budget", label: "Budget", cost: 25, tone: "danger" },
83
+ { id: "late", label: "Late work", cost: 5, tone: "warning" },
84
+ { id: "blocked", label: "Blocked", cost: 8, tone: "warning" },
85
+ { id: "activity", label: "Activity", cost: 0 },
86
+ { id: "client", label: "Client", cost: 5, tone: "warning" },
87
+ ]}
88
+ result={35}
89
+ posts={[{ at: 74, label: "cap 74 · one red" }, { at: 49, label: "cap 49 · two reds" }]}
90
+ bands={[
91
+ { from: 0, to: 50, tone: "danger", label: "off track" },
92
+ { from: 50, to: 75, tone: "warning", label: "at risk" },
93
+ { from: 75, to: 100, tone: "success", label: "on track" },
94
+ ]}
95
+ unit="points"
96
+ onSelect={(part) => scrollToSignal(part.id)}
97
+ />
98
+ ```
99
+
100
+ ## States drawn in the demo
101
+
102
+ - **Nothing taken off**: a full solid bar, the receipt `100 = 100`.
103
+ - **One part, many parts**, a part that costs nothing (in the receipt, not on
104
+ the bar).
105
+ - **Held by a rule**: the sum above the result, the dotted stretch, the receipt
106
+ "held at 49".
107
+ - **Posts and bands**; **pressable** (a selected part, arrow keys by Tab).
108
+ - **Very small cuts** (under 5% wide: no cost written in the block, still in the
109
+ tooltip and the receipt).
110
+ - **Odd input**: a negative cost, a cost past the total, text for a cost, a
111
+ zero total.
112
+ - **Narrow** (a 320 px container: names under the cuts give way to the legend
113
+ you ask for), **wide**, **loading**, **failed**.
114
+
115
+ ## Notes for the app that places it
116
+
117
+ - Colour is a signal. Tone a cut `danger` or `warning` only when its signal is
118
+ in the red or a warning; a neutral cut is a cost that is not a problem.
119
+ - Never rely on tone alone: the cost is written in the cut, in the tooltip and
120
+ in the receipt.
121
+ - Put the same numbers in words beside it (the rows of the sum). The bar is a
122
+ picture of them.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "sum-bar",
3
+ "title": "SumBar",
4
+ "description": "A total with its parts cut out of it, drawn to scale. The bar runs from 0 to the total (100 by default); what is left is solid with its number, each part's cost is a hatched block cut from the top end downward in the tone of its part (warning, danger, info, neutral) with its cost written in it and its name under it, and a part can be pressed. When a rule holds the result below the sum, the stretch between them is dotted and says so. Posts stand on the bar where a rule applies (a cap at 74, a cap at 49), each with a flag above. Coloured bands under the bar name the ranges (off track under 50, at risk to 75, on track). Under it the sum is written out so no number is taken on trust: \"100 − 22 − 25 − 5 − 8 − 0 − 5 = 35\", or \"100 − 44 = 56, held at 49\". Positions are percentages, so it draws the same on the server; a screen reader hears the whole bar as one sentence; loading, failed and nothing-taken-off are drawn; the sums (resultOf, cutsOf, postsOf, bandsOf, receiptOf, sumWords) are exported as plain functions.",
5
+ "useWhen": "Any screen where a number is a total with things taken off it and the member should be able to check the arithmetic: a health score of 100 points less what each signal cost, a risk score, a quote's price less its discounts, a budget less what each line spent, a credit balance less each charge, a grade out of 100 less each lost mark. It draws a result the app has already worked out and changes no number. Not a total split into shares (Distribution, breakdown), progress against a clock (pace-bar), a meter against a limit (Meter), or a time series (chart).",
6
+ "tags": ["sum", "score", "total", "points", "cost", "deduction", "receipt", "arithmetic", "cap", "ceiling", "threshold", "health", "risk", "budget", "breakdown", "waterfall", "bar", "hatched"],
7
+ "exports": ["SumBar", "bandsOf", "costOf", "cutsOf", "labelledCuts", "lostOf", "postsOf", "receiptOf", "resultOf", "sumWords", "totalOf"],
8
+ "files": ["index.js", "sum-bar.jsx", "sum-model.js"],
9
+ "requires": []
10
+ }