main
js 92 lines 2.91 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 {ViewTransitionClass, ViewTransitionProps} from 'shared/ReactTypes';
11 import type {FiberRoot} from './ReactInternalTypes';
12 import type {ViewTransitionInstance, Instance} from './ReactFiberConfig';
13
14 import {
15 getCommittingRoot,
16 getPendingTransitionTypes,
17 } from './ReactFiberWorkLoop';
18
19 export type ViewTransitionState = {
20 autoName: null | string, // the view-transition-name to use when an explicit one is not specified
21 paired: null | ViewTransitionState, // a temporary state during the commit phase if we have paired this with another instance
22 clones: null | Array<Instance>, // a temporary state during the apply gesture phase if we cloned this boundary
23 ref: null | ViewTransitionInstance, // the current ref instance. This can change through the lifetime of the instance.
24 };
25
26 let globalClientIdCounter: number = 0;
27
28 export function getViewTransitionName(
29 props: ViewTransitionProps,
30 instance: ViewTransitionState,
31 ): string {
32 if (props.name != null && props.name !== 'auto') {
33 return props.name;
34 }
35 if (instance.autoName !== null) {
36 return instance.autoName;
37 }
38
39 // We assume we always call this in the commit phase.
40 const root = getCommittingRoot() as any as FiberRoot;
41 const identifierPrefix = root.identifierPrefix;
42 const globalClientId = globalClientIdCounter++;
43 const name =
44 '_' + identifierPrefix + 't_' + globalClientId.toString(32) + '_';
45 instance.autoName = name;
46 return name;
47 }
48
49 function getClassNameByType(classByType: ?ViewTransitionClass): ?string {
50 if (classByType == null || typeof classByType === 'string') {
51 return classByType;
52 }
53 let className: ?string = null;
54 const activeTypes = getPendingTransitionTypes();
55 if (activeTypes !== null) {
56 for (let i = 0; i < activeTypes.length; i++) {
57 const match = classByType[activeTypes[i]];
58 if (match != null) {
59 if (match === 'none') {
60 // If anything matches "none" that takes precedence over any other
61 // type that also matches.
62 return 'none';
63 }
64 if (className == null) {
65 className = match;
66 } else {
67 className += ' ' + match;
68 }
69 }
70 }
71 }
72 if (className == null) {
73 // We had no other matches. Match the default for this configuration.
74 return classByType.default;
75 }
76 return className;
77 }
78
79 export function getViewTransitionClassName(
80 defaultClass: ?ViewTransitionClass,
81 eventClass: ?ViewTransitionClass,
82 ): ?string {
83 const className: ?string = getClassNameByType(defaultClass);
84 const eventClassName: ?string = getClassNameByType(eventClass);
85 if (eventClassName == null) {
86 return className === 'auto' ? null : className;
87 }
88 if (eventClassName === 'auto') {
89 return null;
90 }
91 return eventClassName;
92 }