Skip to content

feat(native): view transitions with a named pair of screens - #7

Closed
mateo-m wants to merge 8 commits into
fix/selection-remount-automationfrom
feat/view-transitions
Closed

mateo-m wants to merge 8 commits into
fix/selection-remount-automationfrom
feat/view-transitions

Conversation

@mateo-m

@mateo-m mateo-m commented Aug 27, 2026

Copy link
Copy Markdown
Owner

Stacked on #5 (fix/selection-remount-automation). Review only the last commit.

What this adds

The View Transitions API. startViewTransition(renderer, update, options) captures every element that carries a viewTransitionName style, applies the React update synchronously, and animates each name from its old place to its new one.

  • The renderer clones the named subtrees before the update. It paints the frozen copies over the live tree while the transition runs. So the leaving screen stays visible under, or over, the arriving one.
  • Options take a duration, a delay, and an ease per name, plus translateX, translateY and opacity ranges for the old side and the new side. Percent lengths resolve against the size of the named element, so translateX: ["100%", "0%"] slides a screen in from the right at any width.
  • A name with no options crossfades. A name that only enters animates against its own bounds.
  • The new side moves through the motion channel at prepaint, so the hitboxes move with the pixels and input lands where the screen paints.
  • A frozen copy takes fresh ids where the live tree still uses them, so a surviving element and its copy never share GPUI element state. Ids of destroyed elements stay, so their scroll offsets survive the swap.

Demo

The Navigation panel in examples/demo is the push and pop of the iOS Settings app. A click on General slides its screen in from the right while Settings slides 30% of its width to the left. The back button runs the same move backwards with the leaving screen on top.

Limits in this version

  • A name that only leaves paints nothing.
  • The frozen copy takes no input.

Tests

  • packages/react/src/__tests__/view-transitions.test.tsx: the push pair, the default crossfade, an enter-only name, a restart mid-flight, an update in place, and a renderer without the native methods. 6 tests.
  • examples/demo.test.tsx: a real click drives the push, the screen starts 318px to the right, and the pop returns to the root screen.
  • Full suites: packages/react 439 passed, examples 56 passed, cargo test ok.

@mateo-m
mateo-m force-pushed the feat/view-transitions branch from aeed9a0 to a8f5756 Compare August 29, 2026 16:30
@mateo-m

mateo-m commented Sep 4, 2026

Copy link
Copy Markdown
Owner Author

Moved to remorses#55.

@mateo-m mateo-m closed this Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant