@cardstack/boxel-cli 0.11.0-unstable.1 → 0.11.0-unstable.3
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/bundled-realms/pretui/components/agent-mark.gts +98 -0
- package/bundled-realms/pretui/components/agent-question.gts +340 -37
- package/bundled-realms/pretui/components/answer-footer.gts +249 -0
- package/bundled-realms/pretui/components/card-embed.gts +523 -0
- package/bundled-realms/pretui/components/card-pills.gts +725 -0
- package/bundled-realms/pretui/components/code-block.gts +87 -45
- package/bundled-realms/pretui/components/collapsed-turn.gts +133 -12
- package/bundled-realms/pretui/components/compaction-chip.gts +81 -67
- package/bundled-realms/pretui/components/composer-cap.gts +516 -0
- package/bundled-realms/pretui/components/context-ring.gts +108 -0
- package/bundled-realms/pretui/components/diff-block.gts +1002 -31
- package/bundled-realms/pretui/components/diff-stat.gts +102 -0
- package/bundled-realms/pretui/components/jump-chip.gts +86 -53
- package/bundled-realms/pretui/components/markdown-stream.gts +799 -0
- package/bundled-realms/pretui/components/markdown-surface.gts +71 -0
- package/bundled-realms/pretui/components/plan-mark.gts +147 -0
- package/bundled-realms/pretui/components/prose.gts +185 -8
- package/bundled-realms/pretui/components/prose.md +6 -8
- package/bundled-realms/pretui/components/quick-look.gts +377 -0
- package/bundled-realms/pretui/components/reactions.gts +136 -0
- package/bundled-realms/pretui/components/recommendation.gts +67 -36
- package/bundled-realms/pretui/components/result-card.gts +58 -22
- package/bundled-realms/pretui/components/segmented-control.gts +13 -8
- package/bundled-realms/pretui/components/session-prep.gts +12 -11
- package/bundled-realms/pretui/components/sliding-highlight.gts +8 -3
- package/bundled-realms/pretui/components/speaker-label.gts +132 -0
- package/bundled-realms/pretui/components/state-glyph.gts +121 -0
- package/bundled-realms/pretui/components/step-list.gts +62 -60
- package/bundled-realms/pretui/components/stick-to-bottom.gts +1150 -0
- package/bundled-realms/pretui/components/system-line.gts +143 -0
- package/bundled-realms/pretui/components/task-checklist.gts +184 -0
- package/bundled-realms/pretui/components/thinking.gts +63 -94
- package/bundled-realms/pretui/components/tool-change-table.gts +285 -0
- package/bundled-realms/pretui/components/tool-gate.gts +462 -0
- package/bundled-realms/pretui/components/tool-group.gts +920 -0
- package/bundled-realms/pretui/components/tool-icon.ts +64 -0
- package/bundled-realms/pretui/components/tool-meta.gts +82 -0
- package/bundled-realms/pretui/components/tool-plan.gts +197 -0
- package/bundled-realms/pretui/components/tool-row.gts +2087 -0
- package/bundled-realms/pretui/components/turn-changes.gts +227 -0
- package/bundled-realms/pretui/components/user-bubble.gts +575 -0
- package/bundled-realms/pretui/components/work-item.gts +185 -48
- package/bundled-realms/pretui/docs/scroll-anchoring-protocol.md +136 -0
- package/bundled-realms/pretui/internal/markdown-projection.ts +438 -0
- package/bundled-realms/pretui/internal/mount-queue.ts +79 -0
- package/bundled-realms/pretui/internal/tool-phrases.ts +168 -0
- package/bundled-realms/pretui/package.json +2 -1
- package/bundled-test-harness/assets/{ai-module-creation-test-beRNwH-e.js → ai-module-creation-test-B6FQKqIl.js} +1 -1
- package/bundled-test-harness/assets/{app-QAuw0l8v.js → app-KpPqdyX3.js} +4 -4
- package/bundled-test-harness/assets/{binary-upload-dedupe-test-bI8T0QLl.js → binary-upload-dedupe-test-DN00y1tM.js} +1 -1
- package/bundled-test-harness/assets/{can-invoke-test-DVaU_yRT.js → can-invoke-test-Bl-EUFM3.js} +1 -1
- package/bundled-test-harness/assets/{card-chooser-paging-test-DnxMnXKR.js → card-chooser-paging-test-BNuZRHX3.js} +1 -1
- package/bundled-test-harness/assets/{card-chooser-test-DUSnLr-u.js → card-chooser-test-wKfPOOT4.js} +1 -1
- package/bundled-test-harness/assets/{card-def-field-def-relationships-test-GBUr3tFK.js → card-def-field-def-relationships-test-CduQ6zan.js} +1 -1
- package/bundled-test-harness/assets/{card-delete-test-CQveO1VC.js → card-delete-test-DKxolj5o.js} +1 -1
- package/bundled-test-harness/assets/{check-correctness-test-D2M2p66N.js → check-correctness-test-B-kgHztp.js} +1 -1
- package/bundled-test-harness/assets/choreo-BEHW-NOc.js +2 -0
- package/bundled-test-harness/assets/{choreo-CJfBb_EY.js → choreo-C2cpCfhA.js} +164 -13
- package/bundled-test-harness/assets/{choreo-feature-reel-test-D2OrygZv.js → choreo-feature-reel-test-CPI_6nkT.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-w07xqtO-.js → choreo-gallery-BxA9cyzF.js} +3 -3
- package/bundled-test-harness/assets/{choreo-gallery-build-order-test-yQg4JER6.js → choreo-gallery-build-order-test-CLVoseAJ.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-compositor-test-C2THCXJN.js → choreo-gallery-compositor-test-BpT5Ia6B.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-cover-test-D4T_Tk4s.js → choreo-gallery-cover-test-DL_fdSsh.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-crossing-stage-test-tHUPJ-Hy.js → choreo-gallery-crossing-stage-test-BcKHhpOK.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-demos-alive-test-BOtBOnEZ.js → choreo-gallery-demos-alive-test-KufLhXG8.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-drift-test-D_6U1Z2c.js → choreo-gallery-drift-test-Cx58rYIA.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-escort-test-DDBU0n4C.js → choreo-gallery-escort-test-Wz-emmID.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-films-test-CgW1NSdr.js → choreo-gallery-films-test-BFrVs5WW.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-filter-test-DUIsNwdO.js → choreo-gallery-filter-test-DCKQkhwe.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-fold-test-Chzlxvdr.js → choreo-gallery-fold-test-UtpDgpG9.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-guide-pages-test-DOWnqALT.js → choreo-gallery-guide-pages-test-rXDU9JLM.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-guides-test-Dra2J4LJ.js → choreo-gallery-guides-test-DfVFdIuU.js} +3 -3
- package/bundled-test-harness/assets/{choreo-gallery-hang-test-zzn1eiB-.js → choreo-gallery-hang-test-Cj7MbkFf.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-highlight-test-CW99hncQ.js → choreo-gallery-highlight-test-D6CF3IYZ.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-inline-edit-test-CYFm1kUz.js → choreo-gallery-inline-edit-test-LfHWsbqc.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-interruption-test-CYIBrKV9.js → choreo-gallery-interruption-test-CvQQAgTp.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-lone-stack-test-DL8R3SG7.js → choreo-gallery-lone-stack-test-D7Zci7fm.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-navigation-test-Dcv04kDx.js → choreo-gallery-navigation-test-DB1EnBEW.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-playhead-transport-test-Cfz7GsXl.js → choreo-gallery-playhead-transport-test-CtBlc6AJ.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-poplayout-subtree-test-CwoklBkW.js → choreo-gallery-poplayout-subtree-test-BQbmjsvI.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-presence-modes-test-BDCIZzJ0.js → choreo-gallery-presence-modes-test-CIdXVG1K.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-presentation-test-DlyiHwFf.js → choreo-gallery-presentation-test-C_rPFp29.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-reduced-motion-test-DVz5SKNR.js → choreo-gallery-reduced-motion-test-CH5w8Lw-.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-sheet-standalone-test-CpD_-BvS.js → choreo-gallery-sheet-standalone-test-CDgI4mGX.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-sheet-test-BjvAKHDL.js → choreo-gallery-sheet-test-5lsFX7Rk.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-site-test-oq_7y_PN.js → choreo-gallery-site-test-DbMa2xeC.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-stage-Bzr4_8Xd.js → choreo-gallery-stage-b3Sk86hp.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-stage-keyboard-test-a83d2euJ.js → choreo-gallery-stage-keyboard-test-ds6fT5Eg.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-stages-test-C9Sl1kH6.js → choreo-gallery-stages-test-ahioKCct.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-subdivision-test-BVVnkOwk.js → choreo-gallery-subdivision-test-g7anTDhT.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-table-plan-test-B0YdYEA0.js → choreo-gallery-table-plan-test-Bozc4uUf.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-theater-test-BLA147xw.js → choreo-gallery-theater-test-kE535d-b.js} +3 -3
- package/bundled-test-harness/assets/{choreo-gallery-tuning-test-DSXiNzCh.js → choreo-gallery-tuning-test-6rHkQBnZ.js} +1 -1
- package/bundled-test-harness/assets/{choreo-gallery-widget-room-test-BI574PdO.js → choreo-gallery-widget-room-test-0Vq-uTo1.js} +2 -2
- package/bundled-test-harness/assets/{choreo-gallery-wires-test-B6Mz2WZl.js → choreo-gallery-wires-test-CdtnAWYO.js} +1 -1
- package/bundled-test-harness/assets/clip-BLfuHi8g.js +2 -0
- package/bundled-test-harness/assets/{clip-C_pXjVvY.js → clip-q1QE5f73.js} +1 -1
- package/bundled-test-harness/assets/{codeblocks-test-AdolhdCA.js → codeblocks-test-BDD7qK_V.js} +1 -1
- package/bundled-test-harness/assets/{compaction-test-DvyAQq56.js → compaction-test-BweolkhG.js} +1 -1
- package/bundled-test-harness/assets/{container-DIF_9lZ9.css → container-B5B6u-xm.css} +29 -22
- package/bundled-test-harness/assets/{container-DvvqmNpg.js → container-BnJjIM6J.js} +9 -6
- package/bundled-test-harness/assets/{create-listing-modal-test-D95JfQab.js → create-listing-modal-test-FvcAKpIa.js} +1 -1
- package/bundled-test-harness/assets/{debug-message-test-BcNtj7Wr.js → debug-message-test-CJ18Evt7.js} +1 -1
- package/bundled-test-harness/assets/{externals-6ZWftYIb.js → externals-BWjhmCD4.js} +12 -12
- package/bundled-test-harness/assets/{fallback-banner-live-delete-test-5lnN1pv2.js → fallback-banner-live-delete-test-C2H3BrT-.js} +1 -1
- package/bundled-test-harness/assets/{fallback-banner-test-DFb_m_Kq.js → fallback-banner-test-C10aYjkj.js} +1 -1
- package/bundled-test-harness/assets/{fallback-models-test-p3YIwj1L.js → fallback-models-test-BxoPiaGF.js} +1 -1
- package/bundled-test-harness/assets/{file-attachment-test-CmyjNWRR.js → file-attachment-test-DeKyzYaz.js} +1 -1
- package/bundled-test-harness/assets/film-B68PjRlr.js +2 -0
- package/bundled-test-harness/assets/{film-D7vtJO5q.js → film-CeUpnHN_.js} +6 -6
- package/bundled-test-harness/assets/{film-DN0A8JHx.js → film-DBZqyqW4.js} +6 -6
- package/bundled-test-harness/assets/{general-test-CX-TFDuX.js → general-test-BewzrpoB.js} +1 -1
- package/bundled-test-harness/assets/{glimmer-motion-and-choreo-in-cards-test-BHte2t9G.js → glimmer-motion-and-choreo-in-cards-test-HA-INN3d.js} +14 -14
- package/bundled-test-harness/assets/{glimmer-motion-and-choreo-test-BPNVeIio.js → glimmer-motion-and-choreo-test-BZ0ZuuAw.js} +3 -3
- package/bundled-test-harness/assets/{index-query-engine-test-Dz7Q4Xmk.js → index-query-engine-test-BtI8Y2LR.js} +1 -1
- package/bundled-test-harness/assets/{instance-filter-matcher-test-BoLU3bVg.js → instance-filter-matcher-test-BHXHGHjE.js} +1 -1
- package/bundled-test-harness/assets/{main-Dlgp8c7v.js → main-CqAHZ2kK.js} +1 -1
- package/bundled-test-harness/assets/{message-tool-test-CfjRSJvt.js → message-tool-test-NMaPJFsd.js} +1 -1
- package/bundled-test-harness/assets/{model-cost-tier-test-mZG84Uso.js → model-cost-tier-test-BgbfN2LH.js} +1 -1
- package/bundled-test-harness/assets/{operation-lowering-test-B0KpI1xu.js → operation-lowering-test-C4IaOjsA.js} +1 -1
- package/bundled-test-harness/assets/{operator-mode-card-chooser-test-KWS8lq16.js → operator-mode-card-chooser-test-Bwe47Rn7.js} +1 -1
- package/bundled-test-harness/assets/{operator-mode-links-test-CViFt0Ws.js → operator-mode-links-test-BU4jkC-B.js} +1 -1
- package/bundled-test-harness/assets/{operator-mode-test-D0gZM2yw.js → operator-mode-test-Bh0rGM9z.js} +1 -1
- package/bundled-test-harness/assets/{operator-mode-ui-test-CEvHJ9DS.js → operator-mode-ui-test-whgUw0ju.js} +1 -1
- package/bundled-test-harness/assets/{overlay-menu-items-test-Pw80RXsr.js → overlay-menu-items-test-Cwn1vr8q.js} +1 -1
- package/bundled-test-harness/assets/{overlays-BnOM360u.js → overlays-BOzLbVDK.js} +1 -1
- package/bundled-test-harness/assets/{overlays-kBVfa4i8.js → overlays-C_PuGDGh.js} +1 -1
- package/bundled-test-harness/assets/{past-sessions-test-CW0-Bjav.js → past-sessions-test-Bh24N-Kz.js} +1 -1
- package/bundled-test-harness/assets/{permission-checking-realm-test-D5uXQypS.js → permission-checking-realm-test-DKnnAy0f.js} +1 -1
- package/bundled-test-harness/assets/{plate-CFvCDv2t.js → plate-BL7UtyKE.js} +1 -1
- package/bundled-test-harness/assets/plate-CqG3igCJ.js +2 -0
- package/bundled-test-harness/assets/player-BJfsgdSI.js +2 -0
- package/bundled-test-harness/assets/{player-DzuYjrTU.js → player-Da_CIsp_.js} +1 -1
- package/bundled-test-harness/assets/{realm-config-policy-standing-test-Btatheni.js → realm-config-policy-standing-test-DngdYypq.js} +1 -1
- package/bundled-test-harness/assets/{realm-config-routing-rule-edit-test-Dh5zW13o.js → realm-config-routing-rule-edit-test-_rkFU8SN.js} +1 -1
- package/bundled-test-harness/assets/{realm-config-settings-test-BJa8gv_C.js → realm-config-settings-test-CR9NH0Zn.js} +1 -1
- package/bundled-test-harness/assets/{reasoning-test-2Zp37cQB.js → reasoning-test-0lH10kRl.js} +1 -1
- package/bundled-test-harness/assets/{room-message-test-BsrON13e.js → room-message-test-C-PddE4Y.js} +1 -1
- package/bundled-test-harness/assets/{run-BMyvn_UL.js → run-D4n4LPcK.js} +96 -6
- package/bundled-test-harness/assets/{run-realm-code-BxktQf6R.js → run-realm-code-C8N7DtN-.js} +1 -1
- package/bundled-test-harness/assets/{run-realm-code-test-7grpTos-.js → run-realm-code-test-DBdp147q.js} +1 -1
- package/bundled-test-harness/assets/{schema-generation-test-CM9ggQji.js → schema-generation-test-CB1Hb7GQ.js} +1 -1
- package/bundled-test-harness/assets/{scrolling-test-BER00htB.js → scrolling-test-3PhVin8h.js} +1 -1
- package/bundled-test-harness/assets/{searchable-option-test-BBr5BPow.js → searchable-option-test-BAdOiL4U.js} +1 -1
- package/bundled-test-harness/assets/{sending-test-BJGobs2E.js → sending-test-KSmu1tSJ.js} +1 -1
- package/bundled-test-harness/assets/{skills-test-GPOsHRN6.js → skills-test-D-dlcFpd.js} +1 -1
- package/bundled-test-harness/assets/{src-Df148w_b.js → src-B_DEhPze.js} +4 -4
- package/bundled-test-harness/assets/{src-Cf2wv-Le.js → src-BoTgwqUA.js} +2 -2
- package/bundled-test-harness/assets/{store-test-QvvHimzH.js → store-test-CEW7xQjZ.js} +1 -1
- package/bundled-test-harness/assets/{test-support-rNHuieEc.js → test-support-FXDPpIl3.js} +1 -1
- package/bundled-test-harness/assets/{test-support-C6N_2X-l.js → test-support-VX6ukQNR.js} +1 -1
- package/bundled-test-harness/assets/{tests-CmsQ-Z_3.js → tests-QYqqa6nv.js} +84 -84
- package/bundled-test-harness/assets/{text-input-validator-test-CYYH2N0L.js → text-input-validator-test-D8iNOWep.js} +1 -1
- package/bundled-test-harness/assets/{titles-B1pTaIfP.js → titles-DFJj5O0E.js} +1 -1
- package/bundled-test-harness/assets/titles-xGlgu7ys.js +2 -0
- package/bundled-test-harness/assets/{to-device-streaming-test-Ctqa0bVp.js → to-device-streaming-test-trCX-505.js} +1 -1
- package/bundled-test-harness/assets/{token-usage-test-BQVbK3X0.js → token-usage-test-C6sULooH.js} +1 -1
- package/bundled-test-harness/assets/{tools-DU8Rc15s.js → tools-UJfD-_al.js} +1 -1
- package/bundled-test-harness/assets/{tools-test-B13yvEKE.js → tools-test-Brav31AV.js} +1 -1
- package/bundled-test-harness/assets/{worker-DHBEBihX.js → worker-9ph9_Lpv.js} +31 -26
- package/bundled-test-harness/index.html +8 -8
- package/bundled-test-harness/tests/index.html +8 -8
- package/bundled-types/choreo/beacons.ts +16 -4
- package/bundled-types/choreo/changeset.ts +25 -5
- package/bundled-types/choreo/choreo.gts +245 -3
- package/bundled-types/choreo/far.ts +39 -0
- package/bundled-types/choreo/index.ts +2 -0
- package/bundled-types/choreo/run.ts +104 -1
- package/bundled-types/host-app/lib/realm-runner/worker.ts +8 -51
- package/bundled-types/runtime-common/realm-runner-script.d.ts +3 -0
- package/package.json +1 -1
- package/bundled-test-harness/assets/choreo-B3Z9QhDH.js +0 -2
- package/bundled-test-harness/assets/clip-BjcXuTwN.js +0 -2
- package/bundled-test-harness/assets/film-DMDPP7ma.js +0 -2
- package/bundled-test-harness/assets/plate-66qnQ-M9.js +0 -2
- package/bundled-test-harness/assets/player-pygg1PwA.js +0 -2
- package/bundled-test-harness/assets/titles-Ccpcl-jq.js +0 -2
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Pretui — DiffStat: a change's size at a glance: +added −removed and a five-block bar.
|
|
2
|
+
import Component from '@glimmer/component';
|
|
3
|
+
|
|
4
|
+
export interface DiffStatSignature {
|
|
5
|
+
Args: {
|
|
6
|
+
added: number;
|
|
7
|
+
removed: number;
|
|
8
|
+
/** blocks in the bar. Default 5; 0 hides it */
|
|
9
|
+
blocks?: number;
|
|
10
|
+
};
|
|
11
|
+
Element: HTMLSpanElement;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* "+24 −7 ▮▮▮▮▯": the counts, and a bar whose blocks split the change
|
|
16
|
+
* between additions and removals, as a code host's file list draws it.
|
|
17
|
+
*/
|
|
18
|
+
export class DiffStat extends Component<DiffStatSignature> {
|
|
19
|
+
get bar(): ('add' | 'del' | 'none')[] {
|
|
20
|
+
let n = this.args.blocks ?? 5;
|
|
21
|
+
let { added, removed } = this.args;
|
|
22
|
+
let total = added + removed;
|
|
23
|
+
// a side with any change gets at least one block; together they never
|
|
24
|
+
// exceed the bar
|
|
25
|
+
let adds = total
|
|
26
|
+
? Math.max(added ? 1 : 0, Math.round((added / total) * n))
|
|
27
|
+
: 0;
|
|
28
|
+
let dels = total
|
|
29
|
+
? Math.max(removed ? 1 : 0, Math.round((removed / total) * n))
|
|
30
|
+
: 0;
|
|
31
|
+
while (adds + dels > n) {
|
|
32
|
+
adds > dels ? adds-- : dels--;
|
|
33
|
+
}
|
|
34
|
+
return Array.from({ length: n }, (_u, i) =>
|
|
35
|
+
i < adds ? 'add' : i < adds + dels ? 'del' : 'none',
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
get label(): string {
|
|
39
|
+
return `${this.args.added} added, ${this.args.removed} removed`;
|
|
40
|
+
}
|
|
41
|
+
<template>
|
|
42
|
+
<span
|
|
43
|
+
class='pretui-diffstat'
|
|
44
|
+
role='img'
|
|
45
|
+
aria-label={{this.label}}
|
|
46
|
+
data-test-pretui-diff-stat
|
|
47
|
+
...attributes
|
|
48
|
+
>
|
|
49
|
+
<span
|
|
50
|
+
class='pretui-diffstat-n'
|
|
51
|
+
data-op='add'
|
|
52
|
+
aria-hidden='true'
|
|
53
|
+
>+{{@added}}</span>
|
|
54
|
+
<span
|
|
55
|
+
class='pretui-diffstat-n'
|
|
56
|
+
data-op='del'
|
|
57
|
+
aria-hidden='true'
|
|
58
|
+
>−{{@removed}}</span>
|
|
59
|
+
{{#if this.bar.length}}<span
|
|
60
|
+
class='pretui-diffstat-bar'
|
|
61
|
+
aria-hidden='true'
|
|
62
|
+
>{{#each this.bar as |block|}}<span
|
|
63
|
+
class='pretui-diffstat-block'
|
|
64
|
+
data-op={{block}}
|
|
65
|
+
></span>{{/each}}</span>{{/if}}
|
|
66
|
+
</span>
|
|
67
|
+
<style scoped>
|
|
68
|
+
@layer PretComponent {
|
|
69
|
+
.pretui-diffstat {
|
|
70
|
+
display: inline-flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
gap: var(--boxel-sp-3xs);
|
|
73
|
+
font-family: var(--font-mono);
|
|
74
|
+
font-size: var(--boxel-font-size-2xs);
|
|
75
|
+
font-variant-numeric: tabular-nums;
|
|
76
|
+
}
|
|
77
|
+
.pretui-diffstat-n[data-op='add'] {
|
|
78
|
+
color: var(--success-ink);
|
|
79
|
+
}
|
|
80
|
+
.pretui-diffstat-n[data-op='del'] {
|
|
81
|
+
color: var(--destructive-ink);
|
|
82
|
+
}
|
|
83
|
+
.pretui-diffstat-bar {
|
|
84
|
+
display: inline-flex;
|
|
85
|
+
gap: 1px;
|
|
86
|
+
}
|
|
87
|
+
.pretui-diffstat-block {
|
|
88
|
+
width: 0.4375rem;
|
|
89
|
+
height: 0.4375rem;
|
|
90
|
+
border-radius: var(--boxel-border-radius-2xs);
|
|
91
|
+
background-color: var(--border-strong);
|
|
92
|
+
}
|
|
93
|
+
.pretui-diffstat-block[data-op='add'] {
|
|
94
|
+
background-color: var(--success);
|
|
95
|
+
}
|
|
96
|
+
.pretui-diffstat-block[data-op='del'] {
|
|
97
|
+
background-color: var(--destructive);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
</style>
|
|
101
|
+
</template>
|
|
102
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// Pretui — JumpChip: scroll orientation for a growing stream, plus the scrollEdge measurement modifier it pairs with.
|
|
2
2
|
import Component from '@glimmer/component';
|
|
3
|
+
import ArrowDownIcon from '@cardstack/boxel-icons/arrow-down';
|
|
3
4
|
import { on } from '@ember/modifier';
|
|
4
5
|
import { modifier } from 'ember-modifier';
|
|
6
|
+
import { VisuallyHidden } from './visually-hidden';
|
|
5
7
|
|
|
6
8
|
// ── scrollEdge ───────────────────────────────────────────────────────────
|
|
7
9
|
// The measurement JumpChip needs, and the reason the chip is not merely
|
|
@@ -38,7 +40,13 @@ export const scrollEdge = modifier(
|
|
|
38
40
|
// ── JumpChip ─────────────────────────────────────────────────────────────
|
|
39
41
|
// Scroll orientation for a stream that grows while you are reading it. Two
|
|
40
42
|
// jobs in one control, distinguished by whether anything arrived: "3 new
|
|
41
|
-
// messages" when it did, "Back to bottom" when it did not.
|
|
43
|
+
// messages" when it did, "Back to bottom" when it did not. The news is also
|
|
44
|
+
// said once through a polite status region, since a chip that appears at
|
|
45
|
+
// the edge of the frame is easy to miss and invisible to a screen reader.
|
|
46
|
+
//
|
|
47
|
+
// A reader who takes the jump from the keyboard keeps their focus: when the
|
|
48
|
+
// caller hides the chip in answer, it stays reachable (not inert) until
|
|
49
|
+
// focus leaves it, so focus never drops to the page body.
|
|
42
50
|
//
|
|
43
51
|
// Presentational by contract — the caller owns the scroller and decides when
|
|
44
52
|
// the chip is warranted (`scrollEdge` above is the measurement, offered
|
|
@@ -51,8 +59,10 @@ export interface JumpChipSignature {
|
|
|
51
59
|
/** whether the chip is offered at all */
|
|
52
60
|
visible?: boolean;
|
|
53
61
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
62
|
+
* messages that arrived while the reader was away: count messages, not
|
|
63
|
+
* transcript rows (a tool call or a system line is not a message).
|
|
64
|
+
* Non-zero switches the chip to its "new messages" voice and shows the
|
|
65
|
+
* count.
|
|
56
66
|
*/
|
|
57
67
|
count?: number;
|
|
58
68
|
/** override the derived label entirely */
|
|
@@ -65,6 +75,35 @@ export interface JumpChipSignature {
|
|
|
65
75
|
Element: HTMLDivElement;
|
|
66
76
|
}
|
|
67
77
|
|
|
78
|
+
const PLURAL = new Intl.PluralRules('en');
|
|
79
|
+
const COUNT = new Intl.NumberFormat('en');
|
|
80
|
+
|
|
81
|
+
/** "1 new message", "3 new messages", "1,204 new messages" */
|
|
82
|
+
function newMessages(count: number): string {
|
|
83
|
+
let noun = PLURAL.select(count) === 'one' ? 'message' : 'messages';
|
|
84
|
+
return `${COUNT.format(count)} new ${noun}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// A hidden chip is inert, except while it holds keyboard focus: then inert
|
|
88
|
+
// waits for focus to leave, because putting it on the focused button would
|
|
89
|
+
// drop focus to the page body. Pointer focus does not hold it (the reader's
|
|
90
|
+
// next action is not on the chip).
|
|
91
|
+
const inertWhileHidden = modifier((el: HTMLElement, [visible]: [boolean]) => {
|
|
92
|
+
if (visible) {
|
|
93
|
+
el.inert = false;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!el.querySelector(':focus-visible')) {
|
|
97
|
+
el.inert = true;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
let release = () => {
|
|
101
|
+
el.inert = true;
|
|
102
|
+
};
|
|
103
|
+
el.addEventListener('focusout', release, { once: true });
|
|
104
|
+
return () => el.removeEventListener('focusout', release);
|
|
105
|
+
});
|
|
106
|
+
|
|
68
107
|
export class JumpChip extends Component<JumpChipSignature> {
|
|
69
108
|
get count(): number {
|
|
70
109
|
return this.args.count ?? 0;
|
|
@@ -83,10 +122,15 @@ export class JumpChip extends Component<JumpChipSignature> {
|
|
|
83
122
|
return this.args.label;
|
|
84
123
|
}
|
|
85
124
|
if (this.isNews) {
|
|
86
|
-
return this.count
|
|
125
|
+
return newMessages(this.count);
|
|
87
126
|
}
|
|
88
127
|
return this.direction === 'up' ? 'Back to top' : 'Back to bottom';
|
|
89
128
|
}
|
|
129
|
+
/** what the status region says: the news while the chip offers it,
|
|
130
|
+
* nothing otherwise */
|
|
131
|
+
get announcement(): string {
|
|
132
|
+
return this.visible && this.isNews ? this.label : '';
|
|
133
|
+
}
|
|
90
134
|
|
|
91
135
|
jump = () => this.args.onJump?.();
|
|
92
136
|
|
|
@@ -96,29 +140,26 @@ export class JumpChip extends Component<JumpChipSignature> {
|
|
|
96
140
|
data-visible={{if this.visible 'true'}}
|
|
97
141
|
data-direction={{this.direction}}
|
|
98
142
|
data-news={{if this.isNews 'true'}}
|
|
99
|
-
|
|
143
|
+
{{inertWhileHidden this.visible}}
|
|
100
144
|
data-test-pretui-jump-chip
|
|
101
145
|
...attributes
|
|
102
146
|
>
|
|
103
147
|
<button
|
|
104
148
|
type='button'
|
|
105
149
|
class='pretui-jump-btn'
|
|
106
|
-
data-test-pretui-jump-chip-button
|
|
107
150
|
{{on 'click' this.jump}}
|
|
151
|
+
data-test-pretui-jump-chip-button
|
|
108
152
|
>
|
|
109
|
-
<
|
|
110
|
-
<path
|
|
111
|
-
d='M12 5v14M6 13l6 6 6-6'
|
|
112
|
-
fill='none'
|
|
113
|
-
stroke='currentColor'
|
|
114
|
-
stroke-width='2.2'
|
|
115
|
-
stroke-linecap='round'
|
|
116
|
-
stroke-linejoin='round'
|
|
117
|
-
/>
|
|
118
|
-
</svg>
|
|
153
|
+
<ArrowDownIcon width='13' height='13' aria-hidden='true' />
|
|
119
154
|
<span>{{this.label}}</span>
|
|
120
155
|
</button>
|
|
121
156
|
</div>
|
|
157
|
+
{{! outside the chip, which is inert while hidden: an inert region is
|
|
158
|
+
not in the accessibility tree, so its change would not be heard }}
|
|
159
|
+
<VisuallyHidden
|
|
160
|
+
role='status'
|
|
161
|
+
data-test-pretui-jump-chip-status
|
|
162
|
+
>{{this.announcement}}</VisuallyHidden>
|
|
122
163
|
|
|
123
164
|
<style scoped>
|
|
124
165
|
@layer PretComponent {
|
|
@@ -127,7 +168,7 @@ export class JumpChip extends Component<JumpChipSignature> {
|
|
|
127
168
|
.pretui-jump {
|
|
128
169
|
position: absolute;
|
|
129
170
|
inset-inline: 0;
|
|
130
|
-
bottom: var(--pretui-jump-offset,
|
|
171
|
+
bottom: var(--pretui-jump-offset, var(--boxel-sp-sm));
|
|
131
172
|
display: flex;
|
|
132
173
|
justify-content: center;
|
|
133
174
|
pointer-events: none;
|
|
@@ -135,41 +176,47 @@ export class JumpChip extends Component<JumpChipSignature> {
|
|
|
135
176
|
}
|
|
136
177
|
.pretui-jump[data-direction='up'] {
|
|
137
178
|
bottom: auto;
|
|
138
|
-
top: var(--pretui-jump-offset,
|
|
179
|
+
top: var(--pretui-jump-offset, var(--boxel-sp-sm));
|
|
139
180
|
}
|
|
140
181
|
.pretui-jump-btn {
|
|
141
182
|
display: inline-flex;
|
|
142
183
|
align-items: center;
|
|
143
|
-
gap:
|
|
144
|
-
min-height:
|
|
145
|
-
padding: 0
|
|
184
|
+
gap: var(--boxel-sp-3xs);
|
|
185
|
+
min-height: 1.75rem;
|
|
186
|
+
padding: 0 var(--boxel-sp-sm);
|
|
146
187
|
border: 0;
|
|
147
|
-
border-radius:
|
|
148
|
-
background: var(--card);
|
|
188
|
+
border-radius: var(--boxel-border-radius-sm);
|
|
189
|
+
background-color: var(--card);
|
|
149
190
|
box-shadow: var(
|
|
150
191
|
--pretui-shadow-overlay,
|
|
151
192
|
0 0 0 1px var(--border),
|
|
152
|
-
|
|
193
|
+
var(--shadow-lg)
|
|
153
194
|
);
|
|
154
|
-
font: inherit;
|
|
155
|
-
font-size: var(--
|
|
156
|
-
|
|
195
|
+
font-family: inherit;
|
|
196
|
+
font-size: var(--boxel-ui-label-font-size);
|
|
197
|
+
line-height: var(--boxel-ui-label-line-height);
|
|
198
|
+
font-weight: 600;
|
|
199
|
+
font-variant-numeric: tabular-nums;
|
|
200
|
+
white-space: nowrap;
|
|
157
201
|
color: var(--foreground);
|
|
158
202
|
cursor: pointer;
|
|
159
203
|
pointer-events: auto;
|
|
160
204
|
opacity: 0;
|
|
161
|
-
transform: translateY(
|
|
205
|
+
transform: translateY(0.5rem) scale(0.96);
|
|
162
206
|
transition:
|
|
163
207
|
opacity 180ms ease-out,
|
|
164
208
|
transform 220ms
|
|
165
209
|
var(--pretui-ease-enter, cubic-bezier(0.22, 0.61, 0.25, 1));
|
|
166
210
|
}
|
|
167
|
-
|
|
211
|
+
/* shown while offered, and while it holds the keyboard focus a jump
|
|
212
|
+
left on it, so a focused control never vanishes under the reader */
|
|
213
|
+
.pretui-jump[data-visible] .pretui-jump-btn,
|
|
214
|
+
.pretui-jump:focus-within .pretui-jump-btn {
|
|
168
215
|
opacity: 1;
|
|
169
216
|
transform: none;
|
|
170
217
|
}
|
|
171
218
|
/* hidden means hidden: no pointer events, no tab stop, no hit area */
|
|
172
|
-
.pretui-jump:not([data-visible]) .pretui-jump-btn {
|
|
219
|
+
.pretui-jump:not([data-visible]):not(:focus-within) .pretui-jump-btn {
|
|
173
220
|
pointer-events: none;
|
|
174
221
|
visibility: hidden;
|
|
175
222
|
transition:
|
|
@@ -177,45 +224,31 @@ export class JumpChip extends Component<JumpChipSignature> {
|
|
|
177
224
|
transform 220ms ease-out,
|
|
178
225
|
visibility 0s linear 220ms;
|
|
179
226
|
}
|
|
227
|
+
/* --hover is translucent, so it lays over the card face rather than
|
|
228
|
+
replacing it: the chip floats over the transcript */
|
|
180
229
|
.pretui-jump-btn:hover {
|
|
181
|
-
background: var(--hover, var(--
|
|
230
|
+
background-image: linear-gradient(var(--hover), var(--hover));
|
|
182
231
|
}
|
|
183
232
|
.pretui-jump-btn:focus-visible {
|
|
184
233
|
outline: 2px solid var(--ring);
|
|
185
234
|
outline-offset: 2px;
|
|
186
235
|
}
|
|
187
236
|
.pretui-jump-btn > svg {
|
|
188
|
-
width: 13px;
|
|
189
|
-
height: 13px;
|
|
190
237
|
flex: none;
|
|
191
|
-
color: var(--
|
|
238
|
+
color: var(--subtle-foreground);
|
|
192
239
|
}
|
|
193
240
|
.pretui-jump[data-direction='up'] .pretui-jump-btn > svg {
|
|
194
241
|
transform: rotate(180deg);
|
|
195
242
|
}
|
|
196
|
-
/* news is never colour alone — the count is in the label
|
|
197
|
-
|
|
198
|
-
background: color-mix(
|
|
199
|
-
in oklch,
|
|
200
|
-
var(--primary) 12%,
|
|
201
|
-
var(--card)
|
|
202
|
-
);
|
|
203
|
-
box-shadow:
|
|
204
|
-
0 0 0 1px
|
|
205
|
-
color-mix(in oklch, var(--primary) 45%, var(--border)),
|
|
206
|
-
0 8px 28px rgb(0 0 0 / 0.18);
|
|
207
|
-
}
|
|
243
|
+
/* news is never colour alone — the count is in the label; the
|
|
244
|
+
arrow (the mark) takes the live state, the chip stays the card */
|
|
208
245
|
.pretui-jump[data-news] .pretui-jump-btn > svg {
|
|
209
|
-
color:
|
|
210
|
-
in oklch,
|
|
211
|
-
var(--foreground) 18%,
|
|
212
|
-
var(--primary)
|
|
213
|
-
);
|
|
246
|
+
color: var(--primary-ink);
|
|
214
247
|
}
|
|
215
248
|
@media (any-pointer: coarse) {
|
|
216
249
|
.pretui-jump-btn {
|
|
217
|
-
min-height:
|
|
218
|
-
padding: 0
|
|
250
|
+
min-height: 2.75rem;
|
|
251
|
+
padding: 0 var(--boxel-sp);
|
|
219
252
|
}
|
|
220
253
|
}
|
|
221
254
|
@media (prefers-reduced-motion: reduce) {
|