@office-iss/react-native-win32 0.77.0 → 0.78.0-preview.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/.flowconfig +1 -1
  2. package/CHANGELOG.json +114 -27
  3. package/CHANGELOG.md +46 -15
  4. package/Libraries/Animated/animations/Animation.js +22 -1
  5. package/Libraries/Animated/animations/DecayAnimation.js +1 -0
  6. package/Libraries/Animated/animations/SpringAnimation.js +1 -0
  7. package/Libraries/Animated/animations/TimingAnimation.js +1 -0
  8. package/Libraries/Animated/nodes/AnimatedAddition.js +9 -2
  9. package/Libraries/Animated/nodes/AnimatedColor.js +4 -1
  10. package/Libraries/Animated/nodes/AnimatedDiffClamp.js +10 -2
  11. package/Libraries/Animated/nodes/AnimatedDivision.js +9 -2
  12. package/Libraries/Animated/nodes/AnimatedInterpolation.js +5 -1
  13. package/Libraries/Animated/nodes/AnimatedModulo.js +5 -2
  14. package/Libraries/Animated/nodes/AnimatedMultiplication.js +9 -2
  15. package/Libraries/Animated/nodes/AnimatedNode.js +25 -46
  16. package/Libraries/Animated/nodes/AnimatedObject.js +9 -2
  17. package/Libraries/Animated/nodes/AnimatedProps.js +5 -1
  18. package/Libraries/Animated/nodes/AnimatedStyle.js +5 -1
  19. package/Libraries/Animated/nodes/AnimatedSubtraction.js +9 -2
  20. package/Libraries/Animated/nodes/AnimatedTracking.js +5 -1
  21. package/Libraries/Animated/nodes/AnimatedTransform.js +5 -1
  22. package/Libraries/Animated/nodes/AnimatedValue.js +63 -4
  23. package/Libraries/Animated/nodes/AnimatedValueXY.js +3 -1
  24. package/Libraries/Animated/useAnimatedProps.js +14 -56
  25. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.d.ts +1 -1
  26. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.js +4 -1
  27. package/Libraries/Components/LayoutConformance/LayoutConformance.d.ts +21 -0
  28. package/Libraries/Components/LayoutConformance/LayoutConformance.js +59 -0
  29. package/Libraries/Components/LayoutConformance/LayoutConformanceNativeComponent.js +29 -0
  30. package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +1 -0
  31. package/Libraries/Components/TextInput/TextInput.d.ts +5 -0
  32. package/Libraries/Components/TextInput/TextInput.flow.js +6 -0
  33. package/Libraries/Components/TextInput/TextInput.js +6 -0
  34. package/Libraries/Components/TextInput/TextInput.win32.js +6 -0
  35. package/Libraries/Components/View/ViewPropTypes.d.ts +0 -7
  36. package/Libraries/Components/View/ViewPropTypes.js +0 -9
  37. package/Libraries/Components/View/ViewPropTypes.win32.js +0 -9
  38. package/Libraries/Core/ReactNativeVersion.js +2 -2
  39. package/Libraries/Core/setUpBatchedBridge.js +1 -16
  40. package/Libraries/EventEmitter/RCTEventEmitter.js +2 -6
  41. package/Libraries/Image/AssetSourceResolver.js +11 -0
  42. package/Libraries/Inspector/BorderBox.js +26 -14
  43. package/Libraries/Inspector/BoxInspector.js +60 -42
  44. package/Libraries/Inspector/ElementBox.js +55 -48
  45. package/Libraries/Inspector/StyleInspector.js +36 -30
  46. package/Libraries/LayoutAnimation/LayoutAnimation.js +2 -2
  47. package/Libraries/Lists/FlatList.d.ts +1 -1
  48. package/Libraries/Modal/Modal.js +2 -0
  49. package/Libraries/NativeComponent/BaseViewConfig.android.js +0 -2
  50. package/Libraries/NativeComponent/BaseViewConfig.ios.js +0 -2
  51. package/Libraries/NativeComponent/BaseViewConfig.win32.js +0 -2
  52. package/Libraries/Network/RCTNetworking.android.js +24 -16
  53. package/Libraries/Network/RCTNetworking.ios.js +1 -46
  54. package/Libraries/Network/RCTNetworking.win32.js +1 -46
  55. package/Libraries/Network/RCTNetworkingEventDefinitions.flow.js +57 -0
  56. package/Libraries/PersonaCoin/PersonaCoin.js +1 -0
  57. package/Libraries/PersonaCoin/PersonaCoin.js.map +1 -1
  58. package/Libraries/ReactNative/UIManagerProperties.js +3 -1
  59. package/Libraries/Renderer/implementations/ReactFabric-dev.js +15828 -26461
  60. package/Libraries/Renderer/implementations/ReactFabric-prod.js +3907 -2560
  61. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +4399 -2878
  62. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +16102 -26908
  63. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +4034 -2695
  64. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +4535 -3045
  65. package/Libraries/Renderer/shims/ReactNativeTypes.js +5 -6
  66. package/Libraries/StyleSheet/processTransform.js +6 -0
  67. package/Libraries/Text/Text.d.ts +6 -1
  68. package/Libraries/Text/TextProps.js +2 -2
  69. package/Libraries/Text/TextProps.win32.js +2 -2
  70. package/Libraries/Utilities/BackHandler.android.js +5 -4
  71. package/Libraries/Utilities/BackHandler.ios.js +4 -5
  72. package/Libraries/Utilities/BackHandler.win32.js +5 -4
  73. package/index.js +5 -0
  74. package/index.win32.js +5 -0
  75. package/overrides.json +14 -14
  76. package/package.json +22 -23
  77. package/src/private/animated/NativeAnimatedValidation.js +1 -1
  78. package/src/private/featureflags/ReactNativeFeatureFlags.js +33 -27
  79. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +5 -5
  80. package/src/private/renderer/errorhandling/ErrorHandlers.js +12 -55
  81. package/src/private/specs/modules/{NativeJSCSamplingProfiler.js → NativeCPUTime.js} +7 -2
  82. package/src/private/specs/modules/NativeFantom.js +37 -0
  83. package/src/private/utilities/ensureInstance.js +21 -0
  84. package/src/private/webapis/dom/nodes/ReactNativeElement.js +49 -6
  85. package/src/private/webapis/dom/nodes/ReadOnlyNode.js +17 -9
  86. package/src/private/webapis/intersectionobserver/IntersectionObserver.js +11 -11
  87. package/src/private/webapis/intersectionobserver/IntersectionObserverEntry.js +1 -1
  88. package/src/private/webapis/intersectionobserver/IntersectionObserverManager.js +1 -1
  89. package/src/private/webapis/intersectionobserver/specs/NativeIntersectionObserver.js +1 -0
  90. package/src/private/webapis/performance/Performance.js +0 -12
  91. package/src/private/webapis/performance/specs/NativePerformance.js +0 -11
  92. package/src-win/Libraries/Components/View/ViewPropTypes.d.ts +0 -7
  93. package/src-win/Libraries/PersonaCoin/PersonaCoin.tsx +1 -0
  94. package/src-win/Libraries/Text/Text.d.ts +6 -1
  95. package/types/index.d.ts +1 -0
  96. package/Libraries/HeapCapture/HeapCapture.js +0 -29
  97. package/Libraries/HeapCapture/NativeJSCHeapCapture.js +0 -13
  98. package/Libraries/Performance/NativeJSCSamplingProfiler.js +0 -13
  99. package/Libraries/Performance/SamplingProfiler.js +0 -39
  100. package/Libraries/ReactNative/__mocks__/FabricUIManager.js +0 -334
  101. package/src/private/webapis/dom/nodes/specs/__mocks__/NativeDOMMock.js +0 -413
  102. package/src/private/webapis/intersectionobserver/specs/__mocks__/NativeIntersectionObserver.js +0 -181
  103. package/src/private/webapis/mutationobserver/specs/__mocks__/NativeMutationObserver.js +0 -327
@@ -8,17 +8,17 @@
8
8
  * @format
9
9
  */
10
10
 
11
- import type {EventSubscription} from '../../vendor/emitter/EventEmitter';
12
11
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
13
12
 
14
13
  import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
15
14
  import invariant from 'invariant';
16
15
 
17
- const {startListeningToAnimatedNodeValue, stopListeningToAnimatedNodeValue} =
18
- NativeAnimatedHelper.API;
19
-
20
16
  type ValueListenerCallback = (state: {value: number, ...}) => mixed;
21
17
 
18
+ export type AnimatedNodeConfig = $ReadOnly<{
19
+ debugID?: string,
20
+ }>;
21
+
22
22
  let _uniqueId = 1;
23
23
  let _assertNativeAnimatedModule: ?() => void = () => {
24
24
  NativeAnimatedHelper.assertNativeAnimatedModule();
@@ -29,9 +29,20 @@ let _assertNativeAnimatedModule: ?() => void = () => {
29
29
 
30
30
  export default class AnimatedNode {
31
31
  #listeners: Map<string, ValueListenerCallback> = new Map();
32
- #updateSubscription: ?EventSubscription = null;
33
32
 
34
33
  _platformConfig: ?PlatformConfig = undefined;
34
+
35
+ constructor(
36
+ config?: ?$ReadOnly<{
37
+ ...AnimatedNodeConfig,
38
+ ...
39
+ }>,
40
+ ) {
41
+ if (__DEV__) {
42
+ this.__debugID = config?.debugID;
43
+ }
44
+ }
45
+
35
46
  __attach(): void {}
36
47
  __detach(): void {
37
48
  this.removeAllListeners();
@@ -62,9 +73,6 @@ export default class AnimatedNode {
62
73
  );
63
74
 
64
75
  this._platformConfig = platformConfig;
65
- if (this.#listeners.size > 0) {
66
- this.#ensureUpdateSubscriptionExists();
67
- }
68
76
  }
69
77
 
70
78
  /**
@@ -77,9 +85,6 @@ export default class AnimatedNode {
77
85
  addListener(callback: (value: any) => mixed): string {
78
86
  const id = String(_uniqueId++);
79
87
  this.#listeners.set(id, callback);
80
- if (this.__isNative) {
81
- this.#ensureUpdateSubscriptionExists();
82
- }
83
88
  return id;
84
89
  }
85
90
 
@@ -91,9 +96,6 @@ export default class AnimatedNode {
91
96
  */
92
97
  removeListener(id: string): void {
93
98
  this.#listeners.delete(id);
94
- if (this.__isNative && this.#listeners.size === 0) {
95
- this.#updateSubscription?.remove();
96
- }
97
99
  }
98
100
 
99
101
  /**
@@ -103,44 +105,12 @@ export default class AnimatedNode {
103
105
  */
104
106
  removeAllListeners(): void {
105
107
  this.#listeners.clear();
106
- if (this.__isNative) {
107
- this.#updateSubscription?.remove();
108
- }
109
108
  }
110
109
 
111
110
  hasListeners(): boolean {
112
111
  return this.#listeners.size > 0;
113
112
  }
114
113
 
115
- #ensureUpdateSubscriptionExists(): void {
116
- if (this.#updateSubscription != null) {
117
- return;
118
- }
119
- const nativeTag = this.__getNativeTag();
120
- startListeningToAnimatedNodeValue(nativeTag);
121
- const subscription: EventSubscription =
122
- NativeAnimatedHelper.nativeEventEmitter.addListener(
123
- 'onAnimatedValueUpdate',
124
- data => {
125
- if (data.tag === nativeTag) {
126
- this.__onAnimatedValueUpdateReceived(data.value);
127
- }
128
- },
129
- );
130
-
131
- this.#updateSubscription = {
132
- remove: () => {
133
- // Only this function assigns to `this.#updateSubscription`.
134
- if (this.#updateSubscription == null) {
135
- return;
136
- }
137
- this.#updateSubscription = null;
138
- subscription.remove();
139
- stopListeningToAnimatedNodeValue(nativeTag);
140
- },
141
- };
142
- }
143
-
144
114
  __onAnimatedValueUpdateReceived(value: number): void {
145
115
  this.__callListeners(value);
146
116
  }
@@ -197,4 +167,13 @@ export default class AnimatedNode {
197
167
  toJSON(): mixed {
198
168
  return this.__getValue();
199
169
  }
170
+
171
+ __debugID: ?string = undefined;
172
+
173
+ __getDebugID(): ?string {
174
+ if (__DEV__) {
175
+ return this.__debugID;
176
+ }
177
+ return undefined;
178
+ }
200
179
  }
@@ -12,6 +12,7 @@
12
12
  'use strict';
13
13
 
14
14
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
15
+ import type {AnimatedNodeConfig} from './AnimatedNode';
15
16
 
16
17
  import AnimatedNode from './AnimatedNode';
17
18
  import AnimatedWithChildren from './AnimatedWithChildren';
@@ -99,8 +100,12 @@ export default class AnimatedObject extends AnimatedWithChildren {
99
100
  /**
100
101
  * Should only be called by `AnimatedObject.from`.
101
102
  */
102
- constructor(nodes: $ReadOnlyArray<AnimatedNode>, value: mixed) {
103
- super();
103
+ constructor(
104
+ nodes: $ReadOnlyArray<AnimatedNode>,
105
+ value: mixed,
106
+ config?: ?AnimatedNodeConfig,
107
+ ) {
108
+ super(config);
104
109
  this.#nodes = nodes;
105
110
  this._value = value;
106
111
  }
@@ -131,6 +136,7 @@ export default class AnimatedObject extends AnimatedWithChildren {
131
136
  const node = nodes[ii];
132
137
  node.__addChild(this);
133
138
  }
139
+ super.__attach();
134
140
  }
135
141
 
136
142
  __detach(): void {
@@ -157,6 +163,7 @@ export default class AnimatedObject extends AnimatedWithChildren {
157
163
  value: mapAnimatedNodes(this._value, node => {
158
164
  return {nodeTag: node.__getNativeTag()};
159
165
  }),
166
+ debugID: this.__getDebugID(),
160
167
  };
161
168
  }
162
169
  }
@@ -9,6 +9,7 @@
9
9
  */
10
10
 
11
11
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
12
+ import type {AnimatedNodeConfig} from './AnimatedNode';
12
13
  import type {AnimatedStyleAllowlist} from './AnimatedStyle';
13
14
 
14
15
  import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
@@ -84,8 +85,9 @@ export default class AnimatedProps extends AnimatedNode {
84
85
  inputProps: {[string]: mixed},
85
86
  callback: () => void,
86
87
  allowlist?: ?AnimatedPropsAllowlist,
88
+ config?: ?AnimatedNodeConfig,
87
89
  ) {
88
- super();
90
+ super(config);
89
91
  const [nodeKeys, nodes, props] = createAnimatedProps(inputProps, allowlist);
90
92
  this.#nodeKeys = nodeKeys;
91
93
  this.#nodes = nodes;
@@ -158,6 +160,7 @@ export default class AnimatedProps extends AnimatedNode {
158
160
  const node = nodes[ii];
159
161
  node.__addChild(this);
160
162
  }
163
+ super.__attach();
161
164
  }
162
165
 
163
166
  __detach(): void {
@@ -268,6 +271,7 @@ export default class AnimatedProps extends AnimatedNode {
268
271
  return {
269
272
  type: 'props',
270
273
  props: propsConfig,
274
+ debugID: this.__getDebugID(),
271
275
  };
272
276
  }
273
277
  }
@@ -9,6 +9,7 @@
9
9
  */
10
10
 
11
11
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
12
+ import type {AnimatedNodeConfig} from './AnimatedNode';
12
13
 
13
14
  import {validateStyles} from '../../../src/private/animated/NativeAnimatedValidation';
14
15
  import * as ReactNativeFeatureFlags from '../../../src/private/featureflags/ReactNativeFeatureFlags';
@@ -112,8 +113,9 @@ export default class AnimatedStyle extends AnimatedWithChildren {
112
113
  nodes: $ReadOnlyArray<AnimatedNode>,
113
114
  style: {[string]: mixed},
114
115
  inputStyle: any,
116
+ config?: ?AnimatedNodeConfig,
115
117
  ) {
116
- super();
118
+ super(config);
117
119
  this.#nodeKeys = nodeKeys;
118
120
  this.#nodes = nodes;
119
121
  this.#style = style;
@@ -199,6 +201,7 @@ export default class AnimatedStyle extends AnimatedWithChildren {
199
201
  const node = nodes[ii];
200
202
  node.__addChild(this);
201
203
  }
204
+ super.__attach();
202
205
  }
203
206
 
204
207
  __detach(): void {
@@ -238,6 +241,7 @@ export default class AnimatedStyle extends AnimatedWithChildren {
238
241
  return {
239
242
  type: 'style',
240
243
  style: styleConfig,
244
+ debugID: this.__getDebugID(),
241
245
  };
242
246
  }
243
247
  }
@@ -13,6 +13,7 @@
13
13
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
14
14
  import type {InterpolationConfigType} from './AnimatedInterpolation';
15
15
  import type AnimatedNode from './AnimatedNode';
16
+ import type {AnimatedNodeConfig} from './AnimatedNode';
16
17
 
17
18
  import AnimatedInterpolation from './AnimatedInterpolation';
18
19
  import AnimatedValue from './AnimatedValue';
@@ -22,8 +23,12 @@ export default class AnimatedSubtraction extends AnimatedWithChildren {
22
23
  _a: AnimatedNode;
23
24
  _b: AnimatedNode;
24
25
 
25
- constructor(a: AnimatedNode | number, b: AnimatedNode | number) {
26
- super();
26
+ constructor(
27
+ a: AnimatedNode | number,
28
+ b: AnimatedNode | number,
29
+ config?: ?AnimatedNodeConfig,
30
+ ) {
31
+ super(config);
27
32
  this._a = typeof a === 'number' ? new AnimatedValue(a) : a;
28
33
  this._b = typeof b === 'number' ? new AnimatedValue(b) : b;
29
34
  }
@@ -47,6 +52,7 @@ export default class AnimatedSubtraction extends AnimatedWithChildren {
47
52
  __attach(): void {
48
53
  this._a.__addChild(this);
49
54
  this._b.__addChild(this);
55
+ super.__attach();
50
56
  }
51
57
 
52
58
  __detach(): void {
@@ -59,6 +65,7 @@ export default class AnimatedSubtraction extends AnimatedWithChildren {
59
65
  return {
60
66
  type: 'subtraction',
61
67
  input: [this._a.__getNativeTag(), this._b.__getNativeTag()],
68
+ debugID: this.__getDebugID(),
62
69
  };
63
70
  }
64
71
  }
@@ -12,6 +12,7 @@
12
12
 
13
13
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
14
14
  import type {EndCallback} from '../animations/Animation';
15
+ import type {AnimatedNodeConfig} from './AnimatedNode';
15
16
  import type AnimatedValue from './AnimatedValue';
16
17
 
17
18
  import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
@@ -31,8 +32,9 @@ export default class AnimatedTracking extends AnimatedNode {
31
32
  animationClass: any,
32
33
  animationConfig: Object,
33
34
  callback?: ?EndCallback,
35
+ config?: ?AnimatedNodeConfig,
34
36
  ) {
35
- super();
37
+ super(config);
36
38
  this._value = value;
37
39
  this._parent = parent;
38
40
  this._animationClass = animationClass;
@@ -65,6 +67,7 @@ export default class AnimatedTracking extends AnimatedNode {
65
67
  let {platformConfig} = this._animationConfig;
66
68
  this.__makeNative(platformConfig);
67
69
  }
70
+ super.__attach();
68
71
  }
69
72
 
70
73
  __detach(): void {
@@ -95,6 +98,7 @@ export default class AnimatedTracking extends AnimatedNode {
95
98
  animationConfig,
96
99
  toValue: this._parent.__getNativeTag(),
97
100
  value: this._value.__getNativeTag(),
101
+ debugID: this.__getDebugID(),
98
102
  };
99
103
  }
100
104
  }
@@ -11,6 +11,7 @@
11
11
  'use strict';
12
12
 
13
13
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
14
+ import type {AnimatedNodeConfig} from './AnimatedNode';
14
15
 
15
16
  import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
16
17
  import {validateTransform} from '../../../src/private/animated/NativeAnimatedValidation';
@@ -70,8 +71,9 @@ export default class AnimatedTransform extends AnimatedWithChildren {
70
71
  constructor(
71
72
  nodes: $ReadOnlyArray<AnimatedNode>,
72
73
  transforms: $ReadOnlyArray<Transform<>>,
74
+ config?: ?AnimatedNodeConfig,
73
75
  ) {
74
- super();
76
+ super(config);
75
77
  this.#nodes = nodes;
76
78
  this._transforms = transforms;
77
79
  }
@@ -115,6 +117,7 @@ export default class AnimatedTransform extends AnimatedWithChildren {
115
117
  const node = nodes[ii];
116
118
  node.__addChild(this);
117
119
  }
120
+ super.__attach();
118
121
  }
119
122
 
120
123
  __detach(): void {
@@ -160,6 +163,7 @@ export default class AnimatedTransform extends AnimatedWithChildren {
160
163
  return {
161
164
  type: 'transform',
162
165
  transforms: transformsConfig,
166
+ debugID: this.__getDebugID(),
163
167
  };
164
168
  }
165
169
  }
@@ -8,11 +8,12 @@
8
8
  * @format
9
9
  */
10
10
 
11
- 'use strict';
12
-
11
+ import type {EventSubscription} from '../../vendor/emitter/EventEmitter';
12
+ import type {PlatformConfig} from '../AnimatedPlatformConfig';
13
13
  import type Animation, {EndCallback} from '../animations/Animation';
14
14
  import type {InterpolationConfigType} from './AnimatedInterpolation';
15
15
  import type AnimatedNode from './AnimatedNode';
16
+ import type {AnimatedNodeConfig} from './AnimatedNode';
16
17
  import type AnimatedTracking from './AnimatedTracking';
17
18
 
18
19
  import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
@@ -21,6 +22,7 @@ import AnimatedInterpolation from './AnimatedInterpolation';
21
22
  import AnimatedWithChildren from './AnimatedWithChildren';
22
23
 
23
24
  export type AnimatedValueConfig = $ReadOnly<{
25
+ ...AnimatedNodeConfig,
24
26
  useNativeDriver: boolean,
25
27
  }>;
26
28
 
@@ -83,6 +85,9 @@ function _executeAsAnimatedBatch(id: string, operation: () => void) {
83
85
  * See https://reactnative.dev/docs/animatedvalue
84
86
  */
85
87
  export default class AnimatedValue extends AnimatedWithChildren {
88
+ #attached: boolean = false;
89
+ #updateSubscription: ?EventSubscription = null;
90
+
86
91
  _value: number;
87
92
  _startingValue: number;
88
93
  _offset: number;
@@ -90,7 +95,7 @@ export default class AnimatedValue extends AnimatedWithChildren {
90
95
  _tracking: ?AnimatedTracking;
91
96
 
92
97
  constructor(value: number, config?: ?AnimatedValueConfig) {
93
- super();
98
+ super(config);
94
99
  if (typeof value !== 'number') {
95
100
  throw new Error('AnimatedValue: Attempting to set value to undefined');
96
101
  }
@@ -102,20 +107,73 @@ export default class AnimatedValue extends AnimatedWithChildren {
102
107
  }
103
108
  }
104
109
 
105
- __detach() {
110
+ __attach(): void {
111
+ this.#attached = true;
112
+ this.#ensureUpdateSubscriptionExists();
113
+ }
114
+
115
+ __detach(): void {
106
116
  if (this.__isNative) {
117
+ this.#updateSubscription?.remove();
107
118
  NativeAnimatedAPI.getValue(this.__getNativeTag(), value => {
108
119
  this._value = value - this._offset;
109
120
  });
110
121
  }
111
122
  this.stopAnimation();
112
123
  super.__detach();
124
+ this.#attached = false;
113
125
  }
114
126
 
115
127
  __getValue(): number {
116
128
  return this._value + this._offset;
117
129
  }
118
130
 
131
+ __makeNative(platformConfig: ?PlatformConfig): void {
132
+ super.__makeNative(platformConfig);
133
+ this.#ensureUpdateSubscriptionExists();
134
+ }
135
+
136
+ /**
137
+ * NOTE: In theory, we should only need to call this when any listeners
138
+ * are added. However, there is a global `onUserDrivenAnimationEnded`
139
+ * listener that relies on `onAnimatedValueUpdate` having fired to update
140
+ * the values in JavaScript. If that listener is removed, this could be
141
+ * re-optimized.
142
+ */
143
+ #ensureUpdateSubscriptionExists(): void {
144
+ if (this.#updateSubscription != null) {
145
+ return;
146
+ }
147
+ // The order in which `__attach` and `__makeNative` are called is not
148
+ // deterministic, and we only want to do this when both have occurred.
149
+ if (!this.#attached || !this.__isNative) {
150
+ return;
151
+ }
152
+ const nativeTag = this.__getNativeTag();
153
+ NativeAnimatedAPI.startListeningToAnimatedNodeValue(nativeTag);
154
+ const subscription: EventSubscription =
155
+ NativeAnimatedHelper.nativeEventEmitter.addListener(
156
+ 'onAnimatedValueUpdate',
157
+ data => {
158
+ if (data.tag === nativeTag) {
159
+ this.__onAnimatedValueUpdateReceived(data.value);
160
+ }
161
+ },
162
+ );
163
+
164
+ this.#updateSubscription = {
165
+ remove: () => {
166
+ // Only this function assigns to `this.#updateSubscription`.
167
+ if (this.#updateSubscription == null) {
168
+ return;
169
+ }
170
+ this.#updateSubscription = null;
171
+ subscription.remove();
172
+ NativeAnimatedAPI.stopListeningToAnimatedNodeValue(nativeTag);
173
+ },
174
+ };
175
+ }
176
+
119
177
  /**
120
178
  * Directly set the value. This will stop any animations running on the value
121
179
  * and update all the bound properties.
@@ -298,6 +356,7 @@ export default class AnimatedValue extends AnimatedWithChildren {
298
356
  type: 'value',
299
357
  value: this._value,
300
358
  offset: this._offset,
359
+ debugID: this.__getDebugID(),
301
360
  };
302
361
  }
303
362
  }
@@ -11,12 +11,14 @@
11
11
  'use strict';
12
12
 
13
13
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
14
+ import type {AnimatedNodeConfig} from './AnimatedNode';
14
15
 
15
16
  import AnimatedValue from './AnimatedValue';
16
17
  import AnimatedWithChildren from './AnimatedWithChildren';
17
18
  import invariant from 'invariant';
18
19
 
19
20
  export type AnimatedValueXYConfig = $ReadOnly<{
21
+ ...AnimatedNodeConfig,
20
22
  useNativeDriver: boolean,
21
23
  }>;
22
24
  type ValueXYListenerCallback = (value: {x: number, y: number, ...}) => mixed;
@@ -49,7 +51,7 @@ export default class AnimatedValueXY extends AnimatedWithChildren {
49
51
  },
50
52
  config?: ?AnimatedValueXYConfig,
51
53
  ) {
52
- super();
54
+ super(config);
53
55
  const value: any = valueIn || {x: 0, y: 0}; // @flowfixme: shouldn't need `: any`
54
56
  if (typeof value.x === 'number' && typeof value.y === 'number') {
55
57
  this.x = new AnimatedValue(value.x);
@@ -17,9 +17,7 @@ import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNa
17
17
  import {isPublicInstance as isFabricPublicInstance} from '../ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstanceUtils';
18
18
  import useRefEffect from '../Utilities/useRefEffect';
19
19
  import {AnimatedEvent} from './AnimatedEvent';
20
- import AnimatedNode from './nodes/AnimatedNode';
21
20
  import AnimatedProps from './nodes/AnimatedProps';
22
- import AnimatedValue from './nodes/AnimatedValue';
23
21
  import {
24
22
  useCallback,
25
23
  useEffect,
@@ -39,11 +37,6 @@ type CallbackRef<T> = T => mixed;
39
37
 
40
38
  type UpdateCallback = () => void;
41
39
 
42
- type AnimatedValueListeners = Array<{
43
- propValue: AnimatedValue,
44
- listenerId: string,
45
- }>;
46
-
47
40
  const useMemoOrAnimatedPropsMemo =
48
41
  ReactNativeFeatureFlags.enableAnimatedPropsMemo()
49
42
  ? useAnimatedPropsMemo
@@ -169,7 +162,6 @@ export default function useAnimatedProps<TProps: {...}, TInstance>(
169
162
 
170
163
  const target = getEventTarget(instance);
171
164
  const events = [];
172
- const animatedValueListeners: AnimatedValueListeners = [];
173
165
 
174
166
  for (const propName in props) {
175
167
  // $FlowFixMe[invalid-computed-prop]
@@ -177,8 +169,6 @@ export default function useAnimatedProps<TProps: {...}, TInstance>(
177
169
  if (propValue instanceof AnimatedEvent && propValue.__isNative) {
178
170
  propValue.__attach(target, propName);
179
171
  events.push([propName, propValue]);
180
- // $FlowFixMe[incompatible-call] - the `addListenersToPropsValue` drills down the propValue.
181
- addListenersToPropsValue(propValue, animatedValueListeners);
182
172
  }
183
173
  }
184
174
 
@@ -188,10 +178,6 @@ export default function useAnimatedProps<TProps: {...}, TInstance>(
188
178
  for (const [propName, propValue] of events) {
189
179
  propValue.__detach(target, propName);
190
180
  }
191
-
192
- for (const {propValue, listenerId} of animatedValueListeners) {
193
- propValue.removeListener(listenerId);
194
- }
195
181
  };
196
182
  },
197
183
  [node, useNativePropsInFabric, props],
@@ -215,35 +201,6 @@ function reduceAnimatedProps<TProps>(
215
201
  };
216
202
  }
217
203
 
218
- function addListenersToPropsValue(
219
- propValue: AnimatedValue,
220
- accumulator: AnimatedValueListeners,
221
- ) {
222
- // propValue can be a scalar value, an array or an object.
223
- if (propValue instanceof AnimatedValue) {
224
- const listenerId = propValue.addListener(() => {});
225
- accumulator.push({propValue, listenerId});
226
- } else if (Array.isArray(propValue)) {
227
- // An array can be an array of scalar values, arrays of arrays, or arrays of objects
228
- for (const prop of propValue) {
229
- addListenersToPropsValue(prop, accumulator);
230
- }
231
- } else if (propValue instanceof Object) {
232
- addAnimatedValuesListenersToProps(propValue, accumulator);
233
- }
234
- }
235
-
236
- function addAnimatedValuesListenersToProps(
237
- props: AnimatedNode,
238
- accumulator: AnimatedValueListeners,
239
- ) {
240
- for (const propName in props) {
241
- // $FlowFixMe[prop-missing] - This is an object contained in a prop, but we don't know the exact type.
242
- const propValue = props[propName];
243
- addListenersToPropsValue(propValue, accumulator);
244
- }
245
- }
246
-
247
204
  /**
248
205
  * Manages the lifecycle of the supplied `AnimatedProps` by invoking `__attach`
249
206
  * and `__detach`. However, this is more complicated because `AnimatedProps`
@@ -319,6 +276,20 @@ function useAnimatedPropsLifecycle_insertionEffects(node: AnimatedProps): void {
319
276
  // if the queue is empty. When multiple animated components are mounted at
320
277
  // the same time. Only first component flushes the queue and the others will noop.
321
278
  NativeAnimatedHelper.API.flushQueue();
279
+ let drivenAnimationEndedListener: ?EventSubscription = null;
280
+ if (node.__isNative) {
281
+ drivenAnimationEndedListener =
282
+ NativeAnimatedHelper.nativeEventEmitter.addListener(
283
+ 'onUserDrivenAnimationEnded',
284
+ data => {
285
+ node.update();
286
+ },
287
+ );
288
+ }
289
+
290
+ return () => {
291
+ drivenAnimationEndedListener?.remove();
292
+ };
322
293
  });
323
294
 
324
295
  useInsertionEffect(() => {
@@ -330,17 +301,6 @@ function useAnimatedPropsLifecycle_insertionEffects(node: AnimatedProps): void {
330
301
 
331
302
  useInsertionEffect(() => {
332
303
  node.__attach();
333
- let drivenAnimationEndedListener: ?EventSubscription = null;
334
-
335
- if (node.__isNative) {
336
- drivenAnimationEndedListener =
337
- NativeAnimatedHelper.nativeEventEmitter.addListener(
338
- 'onUserDrivenAnimationEnded',
339
- data => {
340
- node.update();
341
- },
342
- );
343
- }
344
304
  if (prevNodeRef.current != null) {
345
305
  const prevNode = prevNodeRef.current;
346
306
  // TODO: Stop restoring default values (unless `reset` is called).
@@ -355,8 +315,6 @@ function useAnimatedPropsLifecycle_insertionEffects(node: AnimatedProps): void {
355
315
  } else {
356
316
  prevNodeRef.current = node;
357
317
  }
358
-
359
- drivenAnimationEndedListener?.remove();
360
318
  };
361
319
  }, [node]);
362
320
  }
@@ -105,7 +105,7 @@ export interface DrawerLayoutAndroidProps extends ViewProps {
105
105
  * The navigation view that will be rendered to the side of the
106
106
  * screen and can be pulled in.
107
107
  */
108
- renderNavigationView: () => JSX.Element;
108
+ renderNavigationView: () => React.JSX.Element;
109
109
 
110
110
  /**
111
111
  * Make the drawer take the entire screen and draw the background of
@@ -10,5 +10,8 @@
10
10
 
11
11
  'use strict';
12
12
 
13
+ // $FlowFixMe[cannot-resolve-module]
14
+ import typeof DrawerLayoutAndroid from './DrawerLayoutAndroid.android';
15
+
13
16
  module.exports =
14
- require('../UnimplementedViews/UnimplementedView') as $FlowFixMe;
17
+ require('../UnimplementedViews/UnimplementedView') as $FlowFixMe as DrawerLayoutAndroid;
@@ -0,0 +1,21 @@
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
+ * @format
8
+ */
9
+
10
+ import type * as React from 'react';
11
+
12
+ type LayoutConformanceProps = {
13
+ /**
14
+ * strict: Layout in accordance with W3C spec, even when breaking
15
+ * compatibility: Layout with the same behavior as previous versions of React Native
16
+ */
17
+ mode: 'strict' | 'compatibility';
18
+ children: React.ReactNode;
19
+ };
20
+
21
+ export const experimental_LayoutConformance: React.ComponentType<LayoutConformanceProps>;