Skip to content

fix(web): the composer footer collapses one item at a time, in a fixed order - #31401

Open
flamboh wants to merge 4 commits into
pingdotgg:maria/redesign/2-composer-timelinefrom
flamboh:t3/redesign-fix-composer-footer-collapse
Open

flamboh wants to merge 4 commits into
pingdotgg:maria/redesign/2-composer-timelinefrom
flamboh:t3/redesign-fix-composer-footer-collapse

Conversation

@flamboh

@flamboh flamboh commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Note

🤖 Claude Opus 5.5 on behalf of Oliver

Fix for the redesign stack, targets layer 2 (#28840).

Dragging a pane narrower or wider made the composer footer jump around. Labels collapsed in a different order depending on the width and the direction. Some came back while earlier ones stayed collapsed, and some widths flipped several at once. A collapsed environment chip also left a wider gap before the next chip than the chips around it.

Why it happened

The footer had three separate collapse rules that didn't know about each other:

  • The strip (env, workspace and branch chips) collapsed its labels with 16px of hysteresis.
  • The controls (model, effort and mode) collapsed theirs from whatever width was left over, with 1px of hysteresis. When the strip collapsed and freed space, the controls grew their labels back.
  • Below a 440px composer, CSS forced all three control labels to icons in one step, whatever the fitters had decided.

Fix

The footer now collapses in one fixed order. Going narrower, one item changes at a time:

  1. Mode label (Auto)
  2. Effort label (High)
  3. Environment and workspace labels
  4. Model label (Opus 5.5)
  5. Branch truncates
  6. Controls move into the overflow menu (unchanged)

Going wider reverses the same steps. Hysteresis only shifts where a step happens. It never changes the order.

Why this order: mode and effort are the least informative labels and keep a recognizable icon. Which machine you run on matters more, but the env icon and tooltip still say it. The model name is the label people check most, and the branch is the last thing worth cutting.

How it works:

  • The strip decides its state from the controls' width at the last step allowed beside that state, not from their full width.
  • The controls read the strip's state and stay inside its range of steps. While the strip is fully expanded they can't go past effort, and while its labels are collapsed they can't bring effort back.
  • Effort now collapses as its own step, separate from the model.
  • The 440px CSS override is gone. The fitter handles narrow composers the same way it handles everything else.
  • The controls wait for the strip's 180ms label animation before measuring. Before, a widening strip briefly showed the controls extra room, and their labels flashed on and back off.
  • The icon-only model chip keeps its 6px inset, but through a 2px negative margin instead of a smaller padding. Its labeled width now measures the same in both states. Before, it measured 4px short while icon-only, so the model label flipped on and off within a 3px band.
  • A collapsed label pulls back by one flex gap, so the env icon sits as close to the branch chip as the other chips sit to each other (22px icon to icon, was 27px). The locked env chip's gap is now 6px like the other chips, not 5px.

Measuring still happens once per resize, mutation or font load, never on every frame.

Before / after

Before (layer 2) After
Wide footer and long branch, before Wide footer and long branch, after
Narrow footer and environment gap, before Narrow footer and environment gap, after
Narrowing and widening sequence, before Narrowing and widening sequence, after

Same browser fixture at 1000 → 380 → 1000 px, dark theme, long branch, and environment chip forced visible. Uses the existing 6 Astra / Medium / Full access labels; no provider turns were started. The after capture gives the branch the free footer width and keeps the model label whole while it is visible.

Before, 1×

https://gh-file-drop-api-prod-galwoqjslzlnws6s.oliver-boorstein.workers.dev/f/7374e7ec9f6a868e/31401-before.mp4

After, 1×

https://gh-file-drop-api-prod-galwoqjslzlnws6s.oliver-boorstein.workers.dev/f/21db757ca81bd34c/31401-after.mp4

Before, 4× slower playback

https://gh-file-drop-api-prod-galwoqjslzlnws6s.oliver-boorstein.workers.dev/f/5e8d33695c25644f/31401-before-slow.mp4

After, 4× slower playback

https://gh-file-drop-api-prod-galwoqjslzlnws6s.oliver-boorstein.workers.dev/f/d67f55824f78676a/31401-after-slow.mp4

Validation

  • composerFooterLayout.test.ts: a new case runs both fitters together over every width from 700px down to 200px and back. It checks that collapsed items are always a prefix of the order above, and that each direction steps through 0→6 and 6→0 one item at a time. Run against this layer's logic, the same sweep collapses env, then branch, then mode, then model and effort together.
  • Local dev server (Replay only, long branch name, env chip shown), headless Chromium, composer width changed every frame from 900px to 380px and back, checking state each frame:
    • Layer 2: 20+ frames out of order, steps go back and forth (1→2→1→2→3→2…), and jump two steps at once at 438px.
    • This branch: no frame out of order. Steps go 0→1→2→3→4→5 narrowing and back in reverse widening. No control passes the composer edge.
  • vp run check:changed origin/maria/redesign/2-composer-timeline: format, lint, knip, typecheck, tests and React compiler all pass.

Made with Claude Opus 5.5 in Claude Code.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Nov 5, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 5, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 0212e3f

Macroscope's review found this PR approvable — The composer footer now collapses controls and context labels in a fixed, width-driven order. The changes are limited to responsive presentation, without changing selections, stored data or external operations.

You can add or adjust custom eligibility rules. Learn more.

The context strip measured each chip from its HTML children, so a chip's SVG icon,
gap, padding and border went uncounted. The env chip read 36px narrower than it
was, the strip kept its labels while the row no longer fit, and the model chip
shrank to an ellipsis instead.

Chips that do not grow are now measured by their own box. The model chip and the
env chip no longer shrink, so the branch is the only label that can ellipsize,
and the unused squeezed-picker minimum width is gone.

Made with Claude Opus 5.5 in Claude Code.
@macroscopeapp
macroscopeapp Bot dismissed their stale review November 5, 2026 11:02

Dismissing prior approval to re-evaluate 1917496

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 5, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant