From 526c851a1458d1776408213241b21b1b46b1139b Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Fri, 13 Feb 2026 21:17:17 -0500 Subject: [PATCH 1/6] Expand ViewTransition callback props reference documentation Document the full callback signatures with ViewTransitionInstance and types arguments, cleanup function return values, instance properties (group, imagePair, old, new), and per-callback behavior. --- src/content/reference/react/ViewTransition.md | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/content/reference/react/ViewTransition.md b/src/content/reference/react/ViewTransition.md index 9f451eddc9d..d7de2026822 100644 --- a/src/content/reference/react/ViewTransition.md +++ b/src/content/reference/react/ViewTransition.md @@ -84,16 +84,38 @@ By default, `` animates with a smooth cross-fade. You can custom #### Callback {/*events*/} -These callbacks allow you to adjust the animation imperatively using the [animate](https://developer.mozilla.org/en-US/docs/Web/API/Element/animate) APIs: +These callbacks allow you to control the animation imperatively using the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API). React calls them after the View Transition's [`ready`](https://developer.mozilla.org/en-US/docs/Web/API/ViewTransition/ready) Promise resolves, once built-in default animations have already been computed. Only one callback fires per `` per Transition. -* **optional** `onEnter`: A function. React calls `onEnter` after an "enter" animation. -* **optional** `onExit`: A function. React calls `onExit` after an "exit" animation. -* **optional** `onShare`: A function. React calls `onShare` after a "share" animation. -* **optional** `onUpdate`: A function. React calls `onUpdate` after an "update" animation. +* **optional** `onEnter`: `(instance, types) => void | (() => void)`. Called when this `` is inserted during a Transition without a matching named pair. Use this to animate the entering element imperatively. +* **optional** `onExit`: `(instance, types) => void | (() => void)`. Called when this `` is removed during a Transition without a matching named pair. Use this to animate the exiting element imperatively. +* **optional** `onShare`: `(instance, types) => void | (() => void)`. Called when this `` is part of a shared element Transition—where a named `` is deleted and another with the same name is inserted. Takes precedence over `onEnter` and `onExit`. Use this to animate the shared element Transition imperatively. +* **optional** `onUpdate`: `(instance, types) => void | (() => void)`. Called when this `` has DOM mutations inside it, or when the boundary itself changes size or position due to a sibling change. Use this to animate content updates imperatively. -Each callback receives as arguments: -- `element`: The DOM element that was animated. -- `types`: The [Transition Types](/reference/react/addTransitionType) included in the animation. +Each callback receives two arguments: + +* `instance`: A View Transition instance object that provides access to the view transition [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#the_view_transition_process). Call `instance.old.animate(keyframes, options)` and `instance.new.animate(keyframes, options)` to imperatively control the animation. The instance has these properties: + * `name`: The `view-transition-name` string for this boundary. + * `group`: The `::view-transition-group` pseudo-element. Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. + * `imagePair`: The `::view-transition-image-pair` pseudo-element. Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. + * `old`: The `::view-transition-old` pseudo-element (the snapshot of the previous state). Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. + * `new`: The `::view-transition-new` pseudo-element (the live representation of the new state). Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. +* `types`: An `Array` of [Transition Types](/reference/react/addTransitionType) included in the animation. Empty array if no types were specified. + +Each callback can optionally return a **cleanup function**. The cleanup function is called when the View Transition finishes, allowing you to cancel any manually started animations: + +```js + { + const anim = instance.new.animate( + [{ opacity: 0 }, { opacity: 1 }], + { duration: 500 } + ); + return () => anim.cancel(); + }} +> +
...
+
+``` ### View Transition Class {/*view-transition-class*/} From ddad7476b89c48da3f534a9ba67f39ba64693ab9 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Fri, 13 Feb 2026 21:18:43 -0500 Subject: [PATCH 2/6] Add usage section for imperative animations with ViewTransition callbacks Add "Animating imperatively with callbacks" usage section with Sandpack example showing onEnter/onExit with instance.new.animate() and cleanup functions. Includes addTransitionType integration example. --- src/content/reference/react/ViewTransition.md | 677 +++++++++++------- 1 file changed, 434 insertions(+), 243 deletions(-) diff --git a/src/content/reference/react/ViewTransition.md b/src/content/reference/react/ViewTransition.md index d7de2026822..f84726ccf78 100644 --- a/src/content/reference/react/ViewTransition.md +++ b/src/content/reference/react/ViewTransition.md @@ -5,7 +5,7 @@ version: canary -**The `` API is currently only available in React’s Canary and Experimental channels.** +**The `` API is currently only available in React’s Canary and Experimental channels.** [Learn more about React’s release channels here.](/community/versioning-policy#all-release-channels) @@ -15,13 +15,12 @@ version: canary `` lets you animate elements that update inside a Transition. - ```js import {ViewTransition} from 'react';
...
-
+
; ``` @@ -30,9 +29,9 @@ import {ViewTransition} from 'react'; --- -## Reference {/*reference*/} +## Reference {/* reference */} -### `` {/*viewtransition*/} +### `` {/* viewtransition */} Wrap elements in `` to animate them when they update inside a [Transition](/reference/react/useTransition). React uses the following heuristics to determine if a View Transition activates for an animation: @@ -41,11 +40,11 @@ Wrap elements in `` to animate them when they update inside a [T - `update`: If a `ViewTransition` has any DOM mutations inside it that React is doing (such as a prop changing) or if the `ViewTransition` boundary itself changes size or position due to an immediate sibling. If there are nested` ViewTransition` then the mutation applies to them and not the parent. - `share`: If a named `ViewTransition` is inside a deleted subtree and another named `ViewTransition` with the same name is part of an inserted subtree in the same Transition, they form a Shared Element Transition, and it animates from the deleted one to the inserted one. -By default, `` animates with a smooth cross-fade (the browser default view transition). You can customize the animation by providing a [View Transition Class](#view-transition-class) to the `` component. You can customize animations for each kind of trigger (see [Styling View Transitions](#styling-view-transitions)). +By default, `` animates with a smooth cross-fade (the browser default view transition). You can customize the animation by providing a [View Transition Class](#view-transition-class) to the `` component. You can customize animations for each kind of trigger (see [Styling View Transitions](#styling-view-transitions)). -#### How does `` work? {/*how-does-viewtransition-work*/} +#### How does `` work? {/* how-does-viewtransition-work */} Under the hood, React applies `view-transition-name` to inline styles of the nearest DOM node nested inside the `` component. If there are multiple sibling DOM nodes like `
` then React adds a suffix to the name to make each unique but conceptually they're part of the same one. React doesn't apply these eagerly but only at the time that boundary should participate in an animation. @@ -71,61 +70,60 @@ After the finished Promise of the `startViewTransition` is resolved, React will -#### Props {/*props*/} +#### Props {/* props */} By default, `` animates with a smooth cross-fade. You can customize the animation, or specify a shared element transition, with these props: -* **optional** `enter`: A string or object. The [View Transition Class](#view-transition-class) to apply when enter is activated. -* **optional** `exit`: A string or object. The [View Transition Class](#view-transition-class) to apply when exit is activated. -* **optional** `update`: A string or object. The [View Transition Class](#view-transition-class) to apply when an update is activated. -* **optional** `share`: A string or object. The [View Transition Class](#view-transition-class) to apply when a shared element is activated. -* **optional** `default`: A string or object. The [View Transition Class](#view-transition-class) used when no other matching activation prop is found. -* **optional** `name`: A string or object. The name of the View Transition used for shared element transitions. If not provided, React will use a unique name for each View Transition to prevent unexpected animations. +- **optional** `enter`: A string or object. The [View Transition Class](#view-transition-class) to apply when enter is activated. +- **optional** `exit`: A string or object. The [View Transition Class](#view-transition-class) to apply when exit is activated. +- **optional** `update`: A string or object. The [View Transition Class](#view-transition-class) to apply when an update is activated. +- **optional** `share`: A string or object. The [View Transition Class](#view-transition-class) to apply when a shared element is activated. +- **optional** `default`: A string or object. The [View Transition Class](#view-transition-class) used when no other matching activation prop is found. +- **optional** `name`: A string or object. The name of the View Transition used for shared element transitions. If not provided, React will use a unique name for each View Transition to prevent unexpected animations. -#### Callback {/*events*/} +#### Callback {/* events */} These callbacks allow you to control the animation imperatively using the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API). React calls them after the View Transition's [`ready`](https://developer.mozilla.org/en-US/docs/Web/API/ViewTransition/ready) Promise resolves, once built-in default animations have already been computed. Only one callback fires per `` per Transition. -* **optional** `onEnter`: `(instance, types) => void | (() => void)`. Called when this `` is inserted during a Transition without a matching named pair. Use this to animate the entering element imperatively. -* **optional** `onExit`: `(instance, types) => void | (() => void)`. Called when this `` is removed during a Transition without a matching named pair. Use this to animate the exiting element imperatively. -* **optional** `onShare`: `(instance, types) => void | (() => void)`. Called when this `` is part of a shared element Transition—where a named `` is deleted and another with the same name is inserted. Takes precedence over `onEnter` and `onExit`. Use this to animate the shared element Transition imperatively. -* **optional** `onUpdate`: `(instance, types) => void | (() => void)`. Called when this `` has DOM mutations inside it, or when the boundary itself changes size or position due to a sibling change. Use this to animate content updates imperatively. +- **optional** `onEnter`: `(instance, types) => void | (() => void)`. Called when this `` is inserted during a Transition without a matching named pair. Use this to animate the entering element imperatively. +- **optional** `onExit`: `(instance, types) => void | (() => void)`. Called when this `` is removed during a Transition without a matching named pair. Use this to animate the exiting element imperatively. +- **optional** `onShare`: `(instance, types) => void | (() => void)`. Called when this `` is part of a shared element Transition—where a named `` is deleted and another with the same name is inserted. Takes precedence over `onEnter` and `onExit`. Use this to animate the shared element Transition imperatively. +- **optional** `onUpdate`: `(instance, types) => void | (() => void)`. Called when this `` has DOM mutations inside it, or when the boundary itself changes size or position due to a sibling change. Use this to animate content updates imperatively. Each callback receives two arguments: -* `instance`: A View Transition instance object that provides access to the view transition [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#the_view_transition_process). Call `instance.old.animate(keyframes, options)` and `instance.new.animate(keyframes, options)` to imperatively control the animation. The instance has these properties: - * `name`: The `view-transition-name` string for this boundary. - * `group`: The `::view-transition-group` pseudo-element. Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. - * `imagePair`: The `::view-transition-image-pair` pseudo-element. Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. - * `old`: The `::view-transition-old` pseudo-element (the snapshot of the previous state). Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. - * `new`: The `::view-transition-new` pseudo-element (the live representation of the new state). Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. -* `types`: An `Array` of [Transition Types](/reference/react/addTransitionType) included in the animation. Empty array if no types were specified. +- `instance`: A View Transition instance object that provides access to the view transition [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#the_view_transition_process). Call `instance.old.animate(keyframes, options)` and `instance.new.animate(keyframes, options)` to imperatively control the animation. The instance has these properties: + - `name`: The `view-transition-name` string for this boundary. + - `group`: The `::view-transition-group` pseudo-element. Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. + - `imagePair`: The `::view-transition-image-pair` pseudo-element. Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. + - `old`: The `::view-transition-old` pseudo-element (the snapshot of the previous state). Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. + - `new`: The `::view-transition-new` pseudo-element (the live representation of the new state). Supports `.animate()`, `.getAnimations()`, and `.getComputedStyle()`. +- `types`: An `Array` of [Transition Types](/reference/react/addTransitionType) included in the animation. Empty array if no types were specified. Each callback can optionally return a **cleanup function**. The cleanup function is called when the View Transition finishes, allowing you to cancel any manually started animations: ```js { - const anim = instance.new.animate( - [{ opacity: 0 }, { opacity: 1 }], - { duration: 500 } - ); + const anim = instance.new.animate([{opacity: 0}, {opacity: 1}], { + duration: 500, + }); return () => anim.cancel(); - }} -> + }}>
...
``` -### View Transition Class {/*view-transition-class*/} +### View Transition Class {/* view-transition-class */} The View Transition Class is the CSS class name(s) applied by React during the transition when the ViewTransition activates. It can be a string or an object. + - `string`: the `class` added on the child elements when activated. If `'none'` is provided, no class will be added. - `object`: the class added on the child elements will be the key matching View Transition type added with `addTransitionType`. The object can also specify a `default` to use if no matching type is found. The value `'none'` can be used to prevent a View Transition from activating for a specific trigger. -### Styling View Transitions {/*styling-view-transitions*/} +### Styling View Transitions {/* styling-view-transitions */} @@ -137,7 +135,6 @@ To customize the animation for a `` you can provide a View Trans For example, to customize an "enter" animation, provide a class name to the `enter` prop: - ```js ``` @@ -146,18 +143,16 @@ When the `` activates an "enter" animation, React will add the c ```css ::view-transition-group(.slide-in) { - } ::view-transition-old(.slide-in) { - } ::view-transition-new(.slide-in) { - } ``` + In the future, CSS libraries may add built-in animations using View Transition Classes to make this easier to use. -#### Caveats {/*caveats*/} +#### Caveats {/* caveats */} - By default, `setState` updates immediately and does not activate ``, only updates wrapped in a [Transition](/reference/react/useTransition). You can also use [``](/reference/react/Suspense) to opt-in to a Transition to [reveal content](/reference/react/Suspense#revealing-content-together-at-once). - `` creates an image that can be moved around, scaled and cross-faded. Unlike Layout Animations you may have seen in React Native or Motion, this means that not every individual Element inside of it animates its position. This can lead to better performance and a more continuous feeling, smooth animation compared to animating every individual piece. However, it can also lose continuity in things that should be moving by themselves. So you might have to add more `` boundaries manually as a result. @@ -166,10 +161,9 @@ In the future, CSS libraries may add built-in animations using View Transition C --- +## Usage {/* usage */} -## Usage {/*usage*/} - -### Animating an element on enter/exit {/*animating-an-element-on-enter*/} +### Animating an element on enter/exit {/* animating-an-element-on-enter */} Enter/Exit Transitions trigger when a `` is added or removed by a component in a transition: @@ -191,14 +185,14 @@ function Parent() { } ``` -When `setShow` is called, `show` switches to `true` and the `Child` component is rendered. When `setShow` is called inside `startTransition`, and `Child` renders a `ViewTransition` before any other DOM nodes, an `enter` animation is triggered. +When `setShow` is called, `show` switches to `true` and the `Child` component is rendered. When `setShow` is called inside `startTransition`, and `Child` renders a `ViewTransition` before any other DOM nodes, an `enter` animation is triggered. When `show` switches back to `false`, an `exit` animation is triggered. ```js src/Video.js hidden -function Thumbnail({ video, children }) { +function Thumbnail({video, children}) { return (