main
js 71 lines 2.64 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import type {Fiber} from './ReactInternalTypes';
11 import type {ViewTransitionProps} from 'shared/ReactTypes';
12 import {runWithFiberInDEV} from './ReactCurrentFiber';
13
14 // Use in DEV to track mounted named ViewTransitions. This is used to warn for
15 // duplicate names. This should technically be tracked per Document because you could
16 // have two different documents that can have separate namespaces, but to keep things
17 // simple we just use a global Map. Technically it should also include any manually
18 // assigned view-transition-name outside React too.
19 const mountedNamedViewTransitions: Map<string, Fiber> = __DEV__
20 ? new Map()
21 : (null as any);
22 const didWarnAboutName: {[string]: boolean} = __DEV__ ? {} : (null as any);
23
24 export function trackNamedViewTransition(fiber: Fiber): void {
25 if (__DEV__) {
26 const name = (fiber.memoizedProps as ViewTransitionProps).name;
27 if (name != null && name !== 'auto') {
28 const existing = mountedNamedViewTransitions.get(name);
29 if (existing !== undefined) {
30 if (existing !== fiber && existing !== fiber.alternate) {
31 if (!didWarnAboutName[name]) {
32 didWarnAboutName[name] = true;
33 const stringifiedName = JSON.stringify(name);
34 runWithFiberInDEV(fiber, () => {
35 console.error(
36 'There are two <ViewTransition name=%s> components with the same name mounted ' +
37 'at the same time. This is not supported and will cause View Transitions ' +
38 'to error. Try to use a more unique name e.g. by using a namespace prefix ' +
39 'and adding the id of an item to the name.',
40 stringifiedName,
41 );
42 });
43 runWithFiberInDEV(existing, () => {
44 console.error(
45 'The existing <ViewTransition name=%s> duplicate has this stack trace.',
46 stringifiedName,
47 );
48 });
49 }
50 }
51 } else {
52 mountedNamedViewTransitions.set(name, fiber);
53 }
54 }
55 }
56 }
57
58 export function untrackNamedViewTransition(fiber: Fiber): void {
59 if (__DEV__) {
60 const name = (fiber.memoizedProps as ViewTransitionProps).name;
61 if (name != null && name !== 'auto') {
62 const existing = mountedNamedViewTransitions.get(name);
63 if (
64 existing !== undefined &&
65 (existing === fiber || existing === fiber.alternate)
66 ) {
67 mountedNamedViewTransitions.delete(name);
68 }
69 }
70 }
71 }