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 './ReactFiberViewTransitionComponent';
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: any);
22
+const didWarnAboutName: {[string]: boolean} = __DEV__ ? {} : (null: any);
23
+
24
+export function trackNamedViewTransition(fiber: Fiber): void {
25
+ if (__DEV__) {
26
+ const name = (fiber.memoizedProps: 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: 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
+}