Skip to content

sandbox(motion-lab): Outline's marker on transform, at reading pace and at a scroll rate - #8610

Open
cixzhang wants to merge 3 commits into
mainfrom
sandbox/motion-lab-outline-transform
Open

cixzhang wants to merge 3 commits into
mainfrom
sandbox/motion-lab-outline-transform

Conversation

@cixzhang

@cixzhang cixzhang commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

User impact

The motion lab now shows Outline's reading-position marker the way it should move, beside how it moves today, at reading pace and at the rate a fast scroll drives it. Sandbox only: Outline itself is unchanged.

  • Today: the marker animates top and height, so every frame re-lays-out the whole list. On a scroll-linked page that's every scroll frame.
  • Proposed: the marker animates transform only (a 1 px marker on translateY and scaleY), so the list never re-lays-out. The new pace switch (1.7 s or 0.25 s) shows the difference at scroll rate.
  • The card notes that keeping the marker's velocity through an interrupted move needs Astryx's animator, which the sandbox can use only once it has a public API. The sandbox uses public APIs only.

Change

  • previews/page.tsx: an "Outline marker" card with the pace switch.
  • LabDemos.tsx: OutlineMarkerRig takes intervalMs (default 1700), and its items stack one per row, so the marker moves on every step.
  • LabPrimitives.tsx: useLoop takes an optional floor (default 700 ms); the scroll rate lowers it, so it really steps every 250 ms.
  • previewPlan.ts: the Outline row describes the pace switch and the useAnimator note.
  • MotionLab.module.css: the marker reads --color-accent. It read --color-brand, which the sandbox never defines, so on main both markers were transparent.

No Core or Lab code changes, and there's no changeset (sandbox only).

Evidence

Real Chrome 156 (headless, FaaS), from the built sandbox (vite build plus prerender) at this head, 320d671.

Desktop, 1280 px. Today's marker transitions top, height (0.31 s); the proposed one transitions transform only (0.31 s). At the scroll rate the marker moves every 250 ms (10 moves in 2.6 s, gaps 247–253 ms), once per item.

Reading pace Scroll rate
Reading pace Scroll rate

Reduce Motion, rail on Delete. Both markers move at once (0 s), and the proposed one still moves on transform.

Reduce Motion, Delete

Phone, 390 px. The same card and the marker on transform. At 390 px the lab's own section rail (on main) still takes the left of the page and squeezes every card; that's not this change.

Phone 390

Raw measurements: notes.json, rate.json.

…nd at a scroll rate

An Outline marker card on the live previews page: today's marker animates top
and height, the proposal transform only, with a pace switch (1.7 s reading
pace, 0.25 s scroll rate) that shows why a scroll-linked marker must stay off
layout. The card notes that keeping the marker's velocity through an
interrupted move (animator retargeting) lands with the public useAnimator.
OutlineMarkerRig takes the interval; the preview plan's Outline row says so.
Sandbox only, public APIs only.

Co-authored-by: Ernest <5867373+ernestt@users.noreply.github.com>
@vercel

vercel Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Oct 27, 2026 12:32am UTC

Request Review

@astracat-bot

astracat-bot Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Oct 27, 2026, 12:53 AM UTC

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR

🧪 Sandbox Preview

View Sandbox for this PR

No new or modified components detected.

Bundle Size Summary

No component packages changed.

Accessibility Audit

Status: No accessibility violations detected.

Visual Regression

55 of 502 shot(s) changed.

A change here is a question, not a failure: check whether the after is the
picture you intended. Record that review on the PR. Baseline maintenance is an
explicit dispatch of CI; this report never rewrites the baseline or adds a release gate.

component story theme mode pixels
Selector Indicator Space Bottom Sheet Narrow End RTL neutral light 753,933
Selector Indicator Space Bottom Sheet Wide Start neutral light 740,072
RichTextEditor Markdown parity: side by side probe dark 558,840
RichTextEditor Markdown parity: side by side probe light 540,756
Chat Full AI Chat probe light 230,823
Chat Full AI Chat probe dark 229,805
AppShell With Mobile Nav probe light 217,010
AppShell With Mobile Nav probe dark 216,960
Collapsible Dividers probe dark 66,445
Collapsible Dividers probe light 66,445
AppShell Playground neutral dark 65,198
AppShell Playground neutral light 63,788
Chat Default neutral dark 36,304
Chat Default neutral light 35,767
Chat Empty State probe light 23,531
Chat Empty State probe dark 22,622
ChatAutoScroll Scroll Behavior Comparison neutral dark 15,378
ChatAutoScroll Scroll Behavior Comparison neutral light 14,107
Chat With Attachments probe light 13,406
Chat With Attachments probe dark 11,232

and 35 more.


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

…so it shows

The marker read --color-brand, which the sandbox never defines, so both
markers were transparent. It now reads Astryx's --color-accent.

Co-authored-by: Ernest <5867373+ernestt@users.noreply.github.com>

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sandbox preview needs an engineering-owner decision and two fixes before it can be approved. The card and the preview-plan row say animator retargeting "lands with the public useAnimator", but no spec on main provides a public useAnimator (the runtime architecture keeps the animator internal, and spec:AST-107 is still a proposal in #8600), so approval needs an engineering owner to identify the governing spec for that announcement or to accept it now by commenting /approve-spec <full head SHA> on this pull request (the author may do so if they are an engineering owner); otherwise the sentence should wait until that spec lands.

  • Scroll rate asks for 250 ms, but useLoop floors every period at 700 ms (LabPrimitives.tsx:606), so the marker steps every 0.7 s and its automatic moves never interrupt one another at 1×.
  • The outline items are inline buttons that share rows, so the marker stays still between items on the same row (2 of every 6 steps in the card); stacking them (display: 'block') lets it follow each item.

[Automated review]

*/
function OutlinePreview() {
const [pace, setPace] = useState<'reading' | 'scroll'>('reading');
const intervalMs = pace === 'reading' ? 1700 : 250;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

250 never reaches the browser: useLoop schedules Math.max(700, periodMs) (LabPrimitives.tsx:606), so Scroll rate steps every 0.7 s (690–700 ms between moves in Chromium). With a 0.31 s move, the automatic steps then never interrupt one another at 1×. An optional floor on useLoop (default 700) that this card lowers, or a label giving the rate it actually runs at, would fix it.

{
tone: 'before',
label: 'Today — top and height',
content: <OutlineMarkerRig mode="before" intervalMs={intervalMs} />,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rig's items are inline buttons (sx.outlineItem in LabDemos.tsx sets no display), so in these panes "Semantic tokens" shares a row with "The rubric" and "Library compatibility" with "Risks". The marker stays put between them, 2 of every 6 steps. Stacking the items (display: 'block', width: '100%', textAlign: 'start') lets it follow each item.

Comment on lines +361 to +363
starts mid-slide begins from where the marker is. Keeping its velocity
through an interrupted move (animator retargeting) lands with the
public useAnimator.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No spec on main provides a public useAnimator: architecture:react-component-runtime INV13 keeps the animator an internal module, and the public hook is only proposed as spec:AST-107 FR3 in #8600. An engineering owner decides whether the sandbox may announce it before that spec lands; otherwise this sentence, and the matching text in previewPlan.ts, should drop the reference.

…ne items stack, and the card claims no public animator

- useLoop takes an optional floor (default 700 ms); the Outline card lowers
  it, so the scroll rate steps every 250 ms instead of 700.
- The outline rig's items are one per row, so the marker moves on every step.
- The card and the plan say velocity through an interrupted move waits for a
  public animator API, instead of naming an unlanded hook.

Co-authored-by: Ernest <5867373+ernestt@users.noreply.github.com>
cixzhang added a commit to cixzhang/astryx that referenced this pull request Oct 27, 2026
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 27, 2026

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good: in the sandbox motion lab, the Outline marker card now steps every 250 ms at Scroll rate, the stacked items keep the marker on every step, and the marker paints in the accent colour on both pages that use it. The reworded animator note matches the current runtime architecture, which keeps the animator internal with no public entry, so no spec decision is needed. No changes are needed from you.

[Automated review]

This branch was successfully deployed

1 active deployment
Preview — 320d6713 Deployed Oct 27, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant