Skip to content

Commit 38127b2

Browse files
authored
[Fiber] Support only View Transitions v2 (facebook#31996)
Stacked on facebook#31975. We're going to recommend that the primary way you style a View Transition is using a View Transition Class (and/or Type). These are only available in the View Transitions v2 spec. When they're not available it's better to fallback to just not animating instead of animating with the wrong styling rules applied. This is already widely supported in Chrome and Safari 18.2. Safari 18.2 usage is still somewhat low but it's rolling out quickly as we speak. A way to detect this is by just passing the object form to `startViewTransition` which throws if it's an earlier version. The object form is required for `types` but luckily classes rolled out at the same time. Therefore we're only indirectly detecting class support. This means that in practice Safari 18.0 and 18.1 won't animate. We could try to only apply the feature detection if you're actually using classes or types, but that would create an unfortunate ecosystem burden to try to support names. It also leads to flaky effects when only some animations work. Better to just disable them all. Firefox has yet to ship anything. We'll have to look out for how the feature detection happens there and if they roll things out in different order but if you ship late, you deal with web compat as the ball lies.
1 parent 3a5496b commit 38127b2

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js

+20-11
Original file line numberDiff line numberDiff line change
@@ -1209,19 +1209,28 @@ export function startViewTransition(
12091209
rootContainer.nodeType === DOCUMENT_NODE
12101210
? rootContainer
12111211
: rootContainer.ownerDocument;
1212-
// $FlowFixMe[prop-missing]
1213-
if (typeof ownerDocument.startViewTransition !== 'function') {
1212+
try {
1213+
// $FlowFixMe[prop-missing]
1214+
const transition = ownerDocument.startViewTransition({
1215+
update() {
1216+
mutationCallback();
1217+
// TODO: Wait for fonts.
1218+
afterMutationCallback();
1219+
},
1220+
types: null, // TODO: Provide types.
1221+
});
1222+
transition.ready.then(layoutCallback, layoutCallback);
1223+
transition.finished.then(passiveCallback);
1224+
return true;
1225+
} catch (x) {
1226+
// We use the error as feature detection.
1227+
// The only thing that should throw is if startViewTransition is missing
1228+
// or if it doesn't accept the object form. Other errors are async.
1229+
// I.e. it's before the View Transitions v2 spec. We only support View
1230+
// Transitions v2 otherwise we fallback to not animating to ensure that
1231+
// we're not animating with the wrong animation mapped.
12141232
return false;
12151233
}
1216-
// $FlowFixMe[incompatible-use]
1217-
const transition = ownerDocument.startViewTransition(() => {
1218-
mutationCallback();
1219-
// TODO: Wait for fonts.
1220-
afterMutationCallback();
1221-
});
1222-
transition.ready.then(layoutCallback, layoutCallback);
1223-
transition.finished.then(passiveCallback);
1224-
return true;
12251234
}
12261235

12271236
export function clearContainer(container: Container): void {

0 commit comments

Comments
 (0)