@office-iss/react-native-win32 0.76.2 → 0.77.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 (249) hide show
  1. package/.eslintignore +1 -1
  2. package/.flowconfig +5 -1
  3. package/CHANGELOG.json +179 -53
  4. package/CHANGELOG.md +82 -28
  5. package/Libraries/ActionSheetIOS/ActionSheetIOS.d.ts +1 -0
  6. package/Libraries/ActionSheetIOS/ActionSheetIOS.js +13 -0
  7. package/Libraries/Animated/AnimatedEvent.js +1 -1
  8. package/Libraries/Animated/AnimatedImplementation.js +2 -2
  9. package/Libraries/Animated/NativeAnimatedAllowlist.js +20 -9
  10. package/Libraries/Animated/animations/Animation.js +60 -25
  11. package/Libraries/Animated/animations/DecayAnimation.js +26 -38
  12. package/Libraries/Animated/animations/SpringAnimation.js +33 -39
  13. package/Libraries/Animated/animations/TimingAnimation.js +34 -42
  14. package/Libraries/Animated/components/AnimatedFlatList.js +1 -1
  15. package/Libraries/Animated/components/AnimatedSectionList.js +3 -1
  16. package/Libraries/Animated/createAnimatedComponent.js +60 -33
  17. package/Libraries/Animated/nodes/AnimatedColor.js +1 -1
  18. package/Libraries/Animated/nodes/AnimatedInterpolation.js +1 -1
  19. package/Libraries/Animated/nodes/AnimatedNode.js +39 -45
  20. package/Libraries/Animated/nodes/AnimatedObject.js +13 -3
  21. package/Libraries/Animated/nodes/AnimatedProps.js +104 -46
  22. package/Libraries/Animated/nodes/AnimatedStyle.js +116 -39
  23. package/Libraries/Animated/nodes/AnimatedTransform.js +56 -23
  24. package/Libraries/Animated/nodes/AnimatedValue.js +1 -1
  25. package/Libraries/Animated/nodes/AnimatedWithChildren.js +1 -3
  26. package/Libraries/Animated/useAnimatedProps.js +41 -35
  27. package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts +19 -3
  28. package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js +77 -5
  29. package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.win32.js +82 -5
  30. package/Libraries/Components/ActivityIndicator/ActivityIndicator.js +4 -4
  31. package/Libraries/Components/Button.js +9 -4
  32. package/Libraries/Components/Button.win32.js +12 -4
  33. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.js +3 -1
  34. package/Libraries/Components/Keyboard/KeyboardAvoidingView.js +7 -0
  35. package/Libraries/Components/Pressable/Pressable.js +4 -4
  36. package/Libraries/Components/Pressable/Pressable.win32.js +4 -4
  37. package/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js +13 -7
  38. package/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js +3 -2
  39. package/Libraries/Components/SafeAreaView/SafeAreaView.js +4 -4
  40. package/Libraries/Components/SafeAreaView/SafeAreaView.win32.js +4 -4
  41. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +0 -1
  42. package/Libraries/Components/ScrollView/ScrollView.js +49 -88
  43. package/Libraries/Components/ScrollView/ScrollViewCommands.js +1 -1
  44. package/Libraries/Components/ScrollView/ScrollViewContext.js +2 -0
  45. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +0 -2
  46. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +8 -9
  47. package/Libraries/Components/Switch/Switch.js +8 -6
  48. package/Libraries/Components/TextInput/InputAccessoryView.js +1 -1
  49. package/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +4 -4
  50. package/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +6 -4
  51. package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +2 -1
  52. package/Libraries/Components/TextInput/TextInput.d.ts +27 -4
  53. package/Libraries/Components/TextInput/TextInput.flow.js +36 -19
  54. package/Libraries/Components/TextInput/TextInput.js +37 -13
  55. package/Libraries/Components/TextInput/TextInput.win32.js +40 -15
  56. package/Libraries/Components/TextInput/TextInputState.js +11 -13
  57. package/Libraries/Components/TextInput/TextInputState.win32.js +13 -16
  58. package/Libraries/Components/TextInput/Win32TextInputNativeComponent.js +3 -0
  59. package/Libraries/Components/Touchable/BoundingDimensions.js +11 -3
  60. package/Libraries/Components/Touchable/Position.js +7 -2
  61. package/Libraries/Components/Touchable/Touchable.js +4 -0
  62. package/Libraries/Components/Touchable/Touchable.win32.js +4 -0
  63. package/Libraries/Components/Touchable/TouchableBounce.js +6 -2
  64. package/Libraries/Components/Touchable/TouchableHighlight.js +5 -5
  65. package/Libraries/Components/Touchable/TouchableOpacity.js +6 -5
  66. package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +1 -2
  67. package/Libraries/Components/View/ReactNativeStyleAttributes.js +6 -1
  68. package/Libraries/Components/View/View.js +4 -4
  69. package/Libraries/Components/View/View.win32.js +4 -4
  70. package/Libraries/Components/View/ViewNativeComponent.js +6 -98
  71. package/Libraries/Components/View/ViewPropTypes.d.ts +7 -0
  72. package/Libraries/Components/View/ViewPropTypes.js +0 -3
  73. package/Libraries/Components/View/ViewPropTypes.win32.js +0 -3
  74. package/Libraries/Components/View/ViewWin32.js +1 -0
  75. package/Libraries/Core/ExceptionsManager.js +50 -29
  76. package/Libraries/Core/ReactNativeVersion.js +3 -3
  77. package/Libraries/Core/__mocks__/NativeExceptionsManager.js +0 -1
  78. package/Libraries/Core/setUpBatchedBridge.js +1 -10
  79. package/Libraries/Core/setUpDeveloperTools.js +1 -5
  80. package/Libraries/Core/setUpErrorHandling.js +20 -18
  81. package/Libraries/Core/setUpReactDevTools.js +107 -8
  82. package/Libraries/Core/setUpSegmentFetcher.js +1 -0
  83. package/Libraries/Core/setUpTimers.js +21 -18
  84. package/Libraries/Debugging/DebuggingOverlay.js +4 -5
  85. package/Libraries/Image/AssetSourceResolver.js +12 -1
  86. package/Libraries/Image/Image.android.js +1 -5
  87. package/Libraries/Image/Image.d.ts +20 -29
  88. package/Libraries/Image/Image.ios.js +0 -2
  89. package/Libraries/Image/Image.win32.js +0 -2
  90. package/Libraries/Image/ImageBackground.js +2 -5
  91. package/Libraries/Image/ImageProps.js +7 -6
  92. package/Libraries/Image/ImageResizeMode.d.ts +8 -1
  93. package/Libraries/Image/ImageResizeMode.js +4 -1
  94. package/Libraries/Image/ImageSource.d.ts +0 -2
  95. package/Libraries/Image/ImageSource.js +0 -2
  96. package/Libraries/Image/ImageTypes.flow.js +11 -9
  97. package/Libraries/Image/ImageUtils.js +6 -3
  98. package/Libraries/Image/ImageViewNativeComponent.js +5 -3
  99. package/Libraries/Inspector/Inspector.js +1 -0
  100. package/Libraries/Inspector/Inspector.win32.js +2 -1
  101. package/Libraries/Inspector/NetworkOverlay.js +4 -0
  102. package/Libraries/Inspector/ReactDevToolsOverlay.js +8 -14
  103. package/Libraries/Inspector/getInspectorDataForViewAtPoint.js +3 -5
  104. package/Libraries/Interaction/InteractionManager.js +6 -1
  105. package/Libraries/Interaction/InteractionManagerStub.js +176 -0
  106. package/Libraries/Interaction/TouchHistoryMath.js +22 -19
  107. package/Libraries/JSInspector/NetworkAgent.js +1 -1
  108. package/Libraries/Lists/FlatList.d.ts +1 -2
  109. package/Libraries/Lists/FlatList.js +2 -2
  110. package/Libraries/Lists/SectionListModern.js +7 -7
  111. package/Libraries/Lists/__flowtests__/FlatList-flowtest.js +2 -2
  112. package/Libraries/Lists/__flowtests__/SectionList-flowtest.js +1 -1
  113. package/Libraries/LogBox/Data/LogBoxData.js +3 -3
  114. package/Libraries/LogBox/LogBox.js +18 -5
  115. package/Libraries/LogBox/LogBoxInspectorContainer.js +1 -1
  116. package/Libraries/LogBox/LogBoxNotificationContainer.js +2 -2
  117. package/Libraries/LogBox/UI/AnsiHighlight.js +26 -17
  118. package/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js +6 -1
  119. package/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.win32.js +6 -1
  120. package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +1 -1
  121. package/Libraries/LogBox/UI/LogBoxInspectorHeader.win32.js +1 -1
  122. package/Libraries/LogBox/UI/LogBoxInspectorStackFrames.js +1 -1
  123. package/Libraries/LogBox/UI/LogBoxMessage.js +2 -2
  124. package/Libraries/Modal/Modal.d.ts +12 -0
  125. package/Libraries/Modal/Modal.js +31 -4
  126. package/Libraries/NativeComponent/BaseViewConfig.android.js +72 -1
  127. package/Libraries/NativeComponent/BaseViewConfig.ios.js +2 -1
  128. package/Libraries/NativeComponent/BaseViewConfig.win32.js +3 -11
  129. package/Libraries/NativeComponent/NativeComponentRegistry.js +3 -3
  130. package/Libraries/NativeComponent/StaticViewConfigValidator.js +0 -1
  131. package/Libraries/Network/FormData.js +11 -3
  132. package/Libraries/Network/XHRInterceptor.js +63 -14
  133. package/Libraries/Network/XMLHttpRequest.js +26 -1
  134. package/Libraries/NewAppScreen/components/HermesBadge.js +1 -1
  135. package/Libraries/PermissionsAndroid/PermissionsAndroid.d.ts +49 -2
  136. package/Libraries/PermissionsAndroid/PermissionsAndroid.js +4 -4
  137. package/Libraries/Pressability/HoverState.js +2 -0
  138. package/Libraries/Pressability/HoverState.win32.js +2 -0
  139. package/Libraries/Pressability/Pressability.js +2 -3
  140. package/Libraries/Pressability/Pressability.win32.js +2 -3
  141. package/Libraries/Pressability/usePressability.js +4 -1
  142. package/Libraries/ReactNative/AppContainer.js +1 -1
  143. package/Libraries/ReactNative/AppRegistry.js +1 -11
  144. package/Libraries/ReactNative/DisplayMode.js +1 -1
  145. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent.js +2 -3
  146. package/Libraries/ReactNative/RendererImplementation.js +18 -17
  147. package/Libraries/ReactNative/getCachedComponentWithDebugName.js +1 -3
  148. package/Libraries/ReactNative/renderApplication.js +9 -8
  149. package/Libraries/ReactNative/requireNativeComponent.js +5 -2
  150. package/Libraries/Renderer/shims/ReactFabric.js +3 -3
  151. package/Libraries/Renderer/shims/ReactFeatureFlags.js +2 -2
  152. package/Libraries/Renderer/shims/ReactNative.js +3 -3
  153. package/Libraries/Renderer/shims/ReactNativeTypes.js +22 -35
  154. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +5 -6
  155. package/Libraries/Renderer/shims/createReactNativeComponentClass.js +2 -2
  156. package/Libraries/StyleSheet/StyleSheet.js +7 -1
  157. package/Libraries/StyleSheet/StyleSheet.win32.js +7 -1
  158. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +13 -2
  159. package/Libraries/StyleSheet/StyleSheetTypes.js +24 -6
  160. package/Libraries/StyleSheet/processBackgroundImage.js +87 -110
  161. package/Libraries/StyleSheet/processTransform.js +3 -34
  162. package/Libraries/Text/Text.js +248 -249
  163. package/Libraries/Text/Text.win32.js +282 -295
  164. package/Libraries/Text/TextNativeComponent.js +0 -1
  165. package/Libraries/TurboModule/TurboModuleRegistry.js +5 -5
  166. package/Libraries/Types/CoreEventTypes.d.ts +3 -10
  167. package/Libraries/Types/CoreEventTypes.js +4 -6
  168. package/Libraries/Types/CoreEventTypes.win32.js +4 -6
  169. package/Libraries/Utilities/Appearance.js +3 -1
  170. package/Libraries/Utilities/BackHandler.android.js +6 -18
  171. package/Libraries/Utilities/BackHandler.d.ts +0 -4
  172. package/Libraries/Utilities/BackHandler.ios.js +0 -7
  173. package/Libraries/Utilities/BackHandler.win32.js +6 -18
  174. package/Libraries/Utilities/FocusManager.win32.js +1 -1
  175. package/Libraries/Utilities/HMRClient.js +3 -4
  176. package/Libraries/Utilities/Platform.flow.js +2 -2
  177. package/Libraries/Utilities/Platform.flow.win32.js +3 -2
  178. package/Libraries/Utilities/__mocks__/BackHandler.js +3 -8
  179. package/Libraries/Utilities/codegenNativeComponent.js +1 -1
  180. package/Libraries/Utilities/useMergeRefs.js +26 -7
  181. package/Libraries/WebSocket/WebSocketEvent.js +4 -1
  182. package/Libraries/WebSocket/WebSocketInterceptor.js +31 -13
  183. package/Libraries/__flowtests__/ReactNativeTypes-flowtest.js +6 -5
  184. package/Libraries/promiseRejectionTrackingOptions.js +1 -1
  185. package/index.js +10 -3
  186. package/index.win32.js +10 -3
  187. package/jest/setup.js +36 -1
  188. package/overrides.json +37 -37
  189. package/package.json +20 -20
  190. package/src/private/animated/NativeAnimatedHelper.js +18 -16
  191. package/src/private/animated/NativeAnimatedHelper.win32.js +18 -15
  192. package/src/private/animated/useAnimatedPropsMemo.js +356 -0
  193. package/src/private/components/HScrollViewNativeComponents.js +1 -27
  194. package/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js +11 -8
  195. package/src/private/components/VScrollViewNativeComponents.js +2 -25
  196. package/src/private/debugging/ReactDevToolsSettingsManager.android.js +20 -0
  197. package/src/private/debugging/ReactDevToolsSettingsManager.ios.js +30 -0
  198. package/src/private/debugging/ReactDevToolsSettingsManager.win32.js +20 -0
  199. package/src/private/{fusebox → debugging}/setUpFuseboxReactDevToolsDispatcher.js +6 -0
  200. package/src/private/devmenu/DevMenu.d.ts +20 -0
  201. package/src/private/devmenu/DevMenu.js +31 -0
  202. package/src/private/featureflags/ReactNativeFeatureFlags.js +95 -86
  203. package/src/private/featureflags/ReactNativeFeatureFlagsBase.js +8 -2
  204. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +17 -19
  205. package/src/private/fusebox/specs/NativeReactDevToolsRuntimeSettingsModule.js +34 -0
  206. package/src/private/setup/setUpDOM.js +14 -6
  207. package/src/private/setup/setUpMutationObserver.js +5 -0
  208. package/src/private/specs/components/AndroidHorizontalScrollContentViewNativeComponent.js +1 -0
  209. package/src/private/specs/components/RCTModalHostViewNativeComponent.js +8 -0
  210. package/src/private/specs/modules/NativeAccessibilityInfo.js +9 -0
  211. package/src/private/specs/modules/NativeAccessibilityInfoWin32.js +9 -0
  212. package/src/private/specs/modules/NativeAccessibilityManager.js +4 -0
  213. package/src/private/specs/modules/NativeActionSheetManager.js +2 -0
  214. package/src/private/specs/modules/NativeAppearance.js +4 -10
  215. package/src/private/specs/modules/NativeExceptionsManager.js +0 -12
  216. package/src/private/specs/modules/{NativeDevToolsSettingsManager.js → NativeReactDevToolsSettingsManager.js} +3 -5
  217. package/src/private/webapis/dom/geometry/DOMRect.js +2 -2
  218. package/src/private/webapis/dom/geometry/DOMRectReadOnly.js +2 -2
  219. package/src/private/webapis/dom/nodes/ReactNativeElement.js +2 -3
  220. package/src/private/webapis/intersectionobserver/IntersectionObserver.js +102 -11
  221. package/src/private/webapis/intersectionobserver/IntersectionObserverEntry.js +26 -0
  222. package/src/private/webapis/intersectionobserver/IntersectionObserverManager.js +1 -0
  223. package/src/private/webapis/intersectionobserver/specs/NativeIntersectionObserver.js +1 -0
  224. package/src/private/webapis/intersectionobserver/specs/__mocks__/NativeIntersectionObserver.js +9 -0
  225. package/src/private/webapis/performance/EventTiming.js +13 -8
  226. package/src/private/webapis/performance/Performance.js +66 -73
  227. package/src/private/webapis/performance/PerformanceEntry.js +2 -5
  228. package/src/private/webapis/performance/PerformanceObserver.js +65 -164
  229. package/src/private/webapis/performance/RawPerformanceEntry.js +1 -1
  230. package/src/private/webapis/performance/UserTiming.js +11 -7
  231. package/src/private/webapis/performance/Utilities.js +18 -0
  232. package/src/private/webapis/performance/specs/NativePerformance.js +71 -2
  233. package/src/private/webapis/performance/specs/__mocks__/NativePerformanceMock.js +267 -0
  234. package/src-win/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts +19 -3
  235. package/src-win/Libraries/Components/View/ViewPropTypes.d.ts +7 -0
  236. package/types/index.d.ts +1 -1
  237. package/types/public/ReactNativeTypes.d.ts +4 -8
  238. package/Libraries/DevToolsSettings/DevToolsSettingsManager.android.js +0 -35
  239. package/Libraries/DevToolsSettings/DevToolsSettingsManager.d.ts +0 -20
  240. package/Libraries/DevToolsSettings/DevToolsSettingsManager.ios.js +0 -49
  241. package/Libraries/DevToolsSettings/DevToolsSettingsManager.win32.js +0 -35
  242. package/Libraries/DevToolsSettings/NativeDevToolsSettingsManager.js +0 -13
  243. package/Libraries/ReactNative/ReactFabricInternals.js +0 -17
  244. package/src/private/components/useSyncOnScroll.js +0 -48
  245. package/src/private/webapis/performance/specs/NativePerformanceObserver.js +0 -61
  246. package/src/private/webapis/performance/specs/__mocks__/NativePerformance.js +0 -67
  247. package/src/private/webapis/performance/specs/__mocks__/NativePerformanceObserver.js +0 -127
  248. package/types/experimental.d.ts +0 -59
  249. /package/src/private/{fusebox → debugging}/FuseboxSessionObserver.js +0 -0
@@ -8,42 +8,44 @@
8
8
  * @format
9
9
  */
10
10
 
11
- 'use strict';
12
-
13
11
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
12
+ import type {AnimatedStyleAllowlist} from './AnimatedStyle';
14
13
 
14
+ import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
15
15
  import {findNodeHandle} from '../../ReactNative/RendererProxy';
16
16
  import {AnimatedEvent} from '../AnimatedEvent';
17
- import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
18
17
  import AnimatedNode from './AnimatedNode';
19
18
  import AnimatedObject from './AnimatedObject';
20
19
  import AnimatedStyle from './AnimatedStyle';
21
20
  import invariant from 'invariant';
22
21
 
22
+ export type AnimatedPropsAllowlist = $ReadOnly<{
23
+ style?: ?AnimatedStyleAllowlist,
24
+ [string]: true,
25
+ }>;
26
+
23
27
  function createAnimatedProps(
24
- inputProps: Object,
25
- ): [$ReadOnlyArray<string>, $ReadOnlyArray<AnimatedNode>, Object] {
28
+ inputProps: {[string]: mixed},
29
+ allowlist: ?AnimatedPropsAllowlist,
30
+ ): [$ReadOnlyArray<string>, $ReadOnlyArray<AnimatedNode>, {[string]: mixed}] {
26
31
  const nodeKeys: Array<string> = [];
27
32
  const nodes: Array<AnimatedNode> = [];
28
- const props: Object = {};
33
+ const props: {[string]: mixed} = {};
29
34
 
30
35
  const keys = Object.keys(inputProps);
31
36
  for (let ii = 0, length = keys.length; ii < length; ii++) {
32
37
  const key = keys[ii];
33
38
  const value = inputProps[key];
34
39
 
35
- if (key === 'style') {
36
- const node = new AnimatedStyle(value);
37
- nodeKeys.push(key);
38
- nodes.push(node);
39
- props[key] = node;
40
- } else if (value instanceof AnimatedNode) {
41
- const node = value;
42
- nodeKeys.push(key);
43
- nodes.push(node);
44
- props[key] = node;
45
- } else {
46
- const node = AnimatedObject.from(value);
40
+ if (allowlist == null || hasOwn(allowlist, key)) {
41
+ let node;
42
+ if (key === 'style') {
43
+ node = AnimatedStyle.from(value, allowlist?.style);
44
+ } else if (value instanceof AnimatedNode) {
45
+ node = value;
46
+ } else {
47
+ node = AnimatedObject.from(value);
48
+ }
47
49
  if (node == null) {
48
50
  props[key] = value;
49
51
  } else {
@@ -51,6 +53,20 @@ function createAnimatedProps(
51
53
  nodes.push(node);
52
54
  props[key] = node;
53
55
  }
56
+ } else {
57
+ if (__DEV__) {
58
+ // WARNING: This is a potentially expensive check that we should only
59
+ // do in development. Without this check in development, it might be
60
+ // difficult to identify which props need to be allowlisted.
61
+ if (AnimatedObject.from(inputProps[key]) != null) {
62
+ console.error(
63
+ `AnimatedProps: ${key} is not allowlisted for animation, but it ` +
64
+ 'contains AnimatedNode values; props allowing animation: ',
65
+ allowlist,
66
+ );
67
+ }
68
+ }
69
+ props[key] = value;
54
70
  }
55
71
  }
56
72
 
@@ -58,29 +74,32 @@ function createAnimatedProps(
58
74
  }
59
75
 
60
76
  export default class AnimatedProps extends AnimatedNode {
77
+ #animatedView: any = null;
78
+ #callback: () => void;
61
79
  #nodeKeys: $ReadOnlyArray<string>;
62
80
  #nodes: $ReadOnlyArray<AnimatedNode>;
81
+ #props: {[string]: mixed};
63
82
 
64
- _animatedView: any = null;
65
- _props: Object;
66
- _callback: () => void;
67
-
68
- constructor(inputProps: Object, callback: () => void) {
83
+ constructor(
84
+ inputProps: {[string]: mixed},
85
+ callback: () => void,
86
+ allowlist?: ?AnimatedPropsAllowlist,
87
+ ) {
69
88
  super();
70
- const [nodeKeys, nodes, props] = createAnimatedProps(inputProps);
89
+ const [nodeKeys, nodes, props] = createAnimatedProps(inputProps, allowlist);
71
90
  this.#nodeKeys = nodeKeys;
72
91
  this.#nodes = nodes;
73
- this._props = props;
74
- this._callback = callback;
92
+ this.#props = props;
93
+ this.#callback = callback;
75
94
  }
76
95
 
77
96
  __getValue(): Object {
78
- const props: {[string]: any | ((...args: any) => void)} = {};
97
+ const props: {[string]: mixed} = {};
79
98
 
80
- const keys = Object.keys(this._props);
99
+ const keys = Object.keys(this.#props);
81
100
  for (let ii = 0, length = keys.length; ii < length; ii++) {
82
101
  const key = keys[ii];
83
- const value = this._props[key];
102
+ const value = this.#props[key];
84
103
 
85
104
  if (value instanceof AnimatedNode) {
86
105
  props[key] = value.__getValue();
@@ -94,8 +113,33 @@ export default class AnimatedProps extends AnimatedNode {
94
113
  return props;
95
114
  }
96
115
 
116
+ /**
117
+ * Creates a new `props` object that contains the same props as the supplied
118
+ * `staticProps` object, except with animated nodes for any props that were
119
+ * created by this `AnimatedProps` instance.
120
+ */
121
+ __getValueWithStaticProps(staticProps: Object): Object {
122
+ const props: {[string]: mixed} = {...staticProps};
123
+
124
+ const keys = Object.keys(staticProps);
125
+ for (let ii = 0, length = keys.length; ii < length; ii++) {
126
+ const key = keys[ii];
127
+ const maybeNode = this.#props[key];
128
+
129
+ if (key === 'style' && maybeNode instanceof AnimatedStyle) {
130
+ props[key] = maybeNode.__getValueWithStaticStyle(staticProps.style);
131
+ } else if (maybeNode instanceof AnimatedNode) {
132
+ props[key] = maybeNode.__getValue();
133
+ } else if (maybeNode instanceof AnimatedEvent) {
134
+ props[key] = maybeNode.__getHandler();
135
+ }
136
+ }
137
+
138
+ return props;
139
+ }
140
+
97
141
  __getAnimatedValue(): Object {
98
- const props: {[string]: any} = {};
142
+ const props: {[string]: mixed} = {};
99
143
 
100
144
  const nodeKeys = this.#nodeKeys;
101
145
  const nodes = this.#nodes;
@@ -117,10 +161,10 @@ export default class AnimatedProps extends AnimatedNode {
117
161
  }
118
162
 
119
163
  __detach(): void {
120
- if (this.__isNative && this._animatedView) {
164
+ if (this.__isNative && this.#animatedView) {
121
165
  this.__disconnectAnimatedView();
122
166
  }
123
- this._animatedView = null;
167
+ this.#animatedView = null;
124
168
 
125
169
  const nodes = this.#nodes;
126
170
  for (let ii = 0, length = nodes.length; ii < length; ii++) {
@@ -132,7 +176,7 @@ export default class AnimatedProps extends AnimatedNode {
132
176
  }
133
177
 
134
178
  update(): void {
135
- this._callback();
179
+ this.#callback();
136
180
  }
137
181
 
138
182
  __makeNative(platformConfig: ?PlatformConfig): void {
@@ -150,17 +194,17 @@ export default class AnimatedProps extends AnimatedNode {
150
194
  // where it will be needed to traverse the graph of attached values.
151
195
  super.__setPlatformConfig(platformConfig);
152
196
 
153
- if (this._animatedView) {
197
+ if (this.#animatedView) {
154
198
  this.__connectAnimatedView();
155
199
  }
156
200
  }
157
201
  }
158
202
 
159
203
  setNativeView(animatedView: any): void {
160
- if (this._animatedView === animatedView) {
204
+ if (this.#animatedView === animatedView) {
161
205
  return;
162
206
  }
163
- this._animatedView = animatedView;
207
+ this.#animatedView = animatedView;
164
208
  if (this.__isNative) {
165
209
  this.__connectAnimatedView();
166
210
  }
@@ -168,11 +212,14 @@ export default class AnimatedProps extends AnimatedNode {
168
212
 
169
213
  __connectAnimatedView(): void {
170
214
  invariant(this.__isNative, 'Expected node to be marked as "native"');
171
- const nativeViewTag: ?number = findNodeHandle(this._animatedView);
172
- invariant(
173
- nativeViewTag != null,
174
- 'Unable to locate attached view in the native tree',
175
- );
215
+ let nativeViewTag: ?number = findNodeHandle(this.#animatedView);
216
+ if (nativeViewTag == null) {
217
+ if (process.env.NODE_ENV === 'test') {
218
+ nativeViewTag = -1;
219
+ } else {
220
+ throw new Error('Unable to locate attached view in the native tree');
221
+ }
222
+ }
176
223
  NativeAnimatedHelper.API.connectAnimatedNodeToView(
177
224
  this.__getNativeTag(),
178
225
  nativeViewTag,
@@ -181,11 +228,14 @@ export default class AnimatedProps extends AnimatedNode {
181
228
 
182
229
  __disconnectAnimatedView(): void {
183
230
  invariant(this.__isNative, 'Expected node to be marked as "native"');
184
- const nativeViewTag: ?number = findNodeHandle(this._animatedView);
185
- invariant(
186
- nativeViewTag != null,
187
- 'Unable to locate attached view in the native tree',
188
- );
231
+ let nativeViewTag: ?number = findNodeHandle(this.#animatedView);
232
+ if (nativeViewTag == null) {
233
+ if (process.env.NODE_ENV === 'test') {
234
+ nativeViewTag = -1;
235
+ } else {
236
+ throw new Error('Unable to locate attached view in the native tree');
237
+ }
238
+ }
189
239
  NativeAnimatedHelper.API.disconnectAnimatedNodeFromView(
190
240
  this.__getNativeTag(),
191
241
  nativeViewTag,
@@ -221,3 +271,11 @@ export default class AnimatedProps extends AnimatedNode {
221
271
  };
222
272
  }
223
273
  }
274
+
275
+ // Supported versions of JSC do not implement the newer Object.hasOwn. Remove
276
+ // this shim when they do.
277
+ // $FlowIgnore[method-unbinding]
278
+ const _hasOwnProp = Object.prototype.hasOwnProperty;
279
+ const hasOwn: (obj: $ReadOnly<{...}>, prop: string) => boolean =
280
+ // $FlowIgnore[method-unbinding]
281
+ Object.hasOwn ?? ((obj, prop) => _hasOwnProp.call(obj, prop));
@@ -8,8 +8,6 @@
8
8
  * @format
9
9
  */
10
10
 
11
- 'use strict';
12
-
13
11
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
14
12
 
15
13
  import {validateStyles} from '../../../src/private/animated/NativeAnimatedValidation';
@@ -21,24 +19,34 @@ import AnimatedObject from './AnimatedObject';
21
19
  import AnimatedTransform from './AnimatedTransform';
22
20
  import AnimatedWithChildren from './AnimatedWithChildren';
23
21
 
22
+ export type AnimatedStyleAllowlist = $ReadOnly<{[string]: true}>;
23
+
24
24
  function createAnimatedStyle(
25
25
  inputStyle: {[string]: mixed},
26
+ allowlist: ?AnimatedStyleAllowlist,
26
27
  keepUnanimatedValues: boolean,
27
- ): [$ReadOnlyArray<string>, $ReadOnlyArray<AnimatedNode>, Object] {
28
+ ): [$ReadOnlyArray<string>, $ReadOnlyArray<AnimatedNode>, {[string]: mixed}] {
28
29
  const nodeKeys: Array<string> = [];
29
30
  const nodes: Array<AnimatedNode> = [];
30
- const style: {[string]: any} = {};
31
+ const style: {[string]: mixed} = {};
31
32
 
32
33
  const keys = Object.keys(inputStyle);
33
34
  for (let ii = 0, length = keys.length; ii < length; ii++) {
34
35
  const key = keys[ii];
35
36
  const value = inputStyle[key];
36
37
 
37
- if (value != null && key === 'transform') {
38
- const node = ReactNativeFeatureFlags.shouldUseAnimatedObjectForTransform()
39
- ? AnimatedObject.from(value)
40
- : // $FlowFixMe[incompatible-call] - `value` is mixed.
41
- new AnimatedTransform(value);
38
+ if (allowlist == null || hasOwn(allowlist, key)) {
39
+ let node;
40
+ if (value != null && key === 'transform') {
41
+ node = ReactNativeFeatureFlags.shouldUseAnimatedObjectForTransform()
42
+ ? AnimatedObject.from(value)
43
+ : // $FlowFixMe[incompatible-call] - `value` is mixed.
44
+ AnimatedTransform.from(value);
45
+ } else if (value instanceof AnimatedNode) {
46
+ node = value;
47
+ } else {
48
+ node = AnimatedObject.from(value);
49
+ }
42
50
  if (node == null) {
43
51
  if (keepUnanimatedValues) {
44
52
  style[key] = value;
@@ -48,21 +56,21 @@ function createAnimatedStyle(
48
56
  nodes.push(node);
49
57
  style[key] = node;
50
58
  }
51
- } else if (value instanceof AnimatedNode) {
52
- const node = value;
53
- nodeKeys.push(key);
54
- nodes.push(node);
55
- style[key] = value;
56
59
  } else {
57
- const node = AnimatedObject.from(value);
58
- if (node == null) {
59
- if (keepUnanimatedValues) {
60
- style[key] = value;
60
+ if (__DEV__) {
61
+ // WARNING: This is a potentially expensive check that we should only
62
+ // do in development. Without this check in development, it might be
63
+ // difficult to identify which styles need to be allowlisted.
64
+ if (AnimatedObject.from(inputStyle[key]) != null) {
65
+ console.error(
66
+ `AnimatedStyle: ${key} is not allowlisted for animation, but it ` +
67
+ 'contains AnimatedNode values; styles allowing animation: ',
68
+ allowlist,
69
+ );
61
70
  }
62
- } else {
63
- nodeKeys.push(key);
64
- nodes.push(node);
65
- style[key] = node;
71
+ }
72
+ if (keepUnanimatedValues) {
73
+ style[key] = value;
66
74
  }
67
75
  }
68
76
  }
@@ -71,34 +79,54 @@ function createAnimatedStyle(
71
79
  }
72
80
 
73
81
  export default class AnimatedStyle extends AnimatedWithChildren {
82
+ #inputStyle: any;
74
83
  #nodeKeys: $ReadOnlyArray<string>;
75
84
  #nodes: $ReadOnlyArray<AnimatedNode>;
76
-
77
- _inputStyle: any;
78
- _style: {[string]: any};
79
-
80
- constructor(inputStyle: any) {
81
- super();
82
- this._inputStyle = inputStyle;
85
+ #style: {[string]: mixed};
86
+
87
+ /**
88
+ * Creates an `AnimatedStyle` if `value` contains `AnimatedNode` instances.
89
+ * Otherwise, returns `null`.
90
+ */
91
+ static from(
92
+ inputStyle: any,
93
+ allowlist: ?AnimatedStyleAllowlist,
94
+ ): ?AnimatedStyle {
95
+ const flatStyle = flattenStyle(inputStyle);
96
+ if (flatStyle == null) {
97
+ return null;
98
+ }
83
99
  const [nodeKeys, nodes, style] = createAnimatedStyle(
84
- // NOTE: This null check should not be necessary, but the types are not
85
- // strong nor enforced as of this writing. This check should be hoisted
86
- // to instantiation sites.
87
- flattenStyle(inputStyle) ?? {},
100
+ flatStyle,
101
+ allowlist,
88
102
  Platform.OS !== 'web',
89
103
  );
104
+ if (nodes.length === 0) {
105
+ return null;
106
+ }
107
+ return new AnimatedStyle(nodeKeys, nodes, style, inputStyle);
108
+ }
109
+
110
+ constructor(
111
+ nodeKeys: $ReadOnlyArray<string>,
112
+ nodes: $ReadOnlyArray<AnimatedNode>,
113
+ style: {[string]: mixed},
114
+ inputStyle: any,
115
+ ) {
116
+ super();
90
117
  this.#nodeKeys = nodeKeys;
91
118
  this.#nodes = nodes;
92
- this._style = style;
119
+ this.#style = style;
120
+ this.#inputStyle = inputStyle;
93
121
  }
94
122
 
95
123
  __getValue(): Object | Array<Object> {
96
- const style: {[string]: any} = {};
124
+ const style: {[string]: mixed} = {};
97
125
 
98
- const keys = Object.keys(this._style);
126
+ const keys = Object.keys(this.#style);
99
127
  for (let ii = 0, length = keys.length; ii < length; ii++) {
100
128
  const key = keys[ii];
101
- const value = this._style[key];
129
+ const value = this.#style[key];
102
130
 
103
131
  if (value instanceof AnimatedNode) {
104
132
  style[key] = value.__getValue();
@@ -107,11 +135,52 @@ export default class AnimatedStyle extends AnimatedWithChildren {
107
135
  }
108
136
  }
109
137
 
110
- return Platform.OS === 'web' ? [this._inputStyle, style] : style;
138
+ /* $FlowFixMe[incompatible-type] Error found due to incomplete typing of
139
+ * Platform.flow.js */
140
+ return Platform.OS === 'web' ? [this.#inputStyle, style] : style;
141
+ }
142
+
143
+ /**
144
+ * Creates a new `style` object that contains the same style properties as
145
+ * the supplied `staticStyle` object, except with animated nodes for any
146
+ * style properties that were created by this `AnimatedStyle` instance.
147
+ */
148
+ __getValueWithStaticStyle(staticStyle: Object): Object | Array<Object> {
149
+ const flatStaticStyle = flattenStyle(staticStyle);
150
+ const style: {[string]: mixed} =
151
+ flatStaticStyle == null
152
+ ? {}
153
+ : flatStaticStyle === staticStyle
154
+ ? // Copy the input style, since we'll mutate it below.
155
+ {...flatStaticStyle}
156
+ : // Reuse `flatStaticStyle` if it is a newly created object.
157
+ flatStaticStyle;
158
+
159
+ const keys = Object.keys(style);
160
+ for (let ii = 0, length = keys.length; ii < length; ii++) {
161
+ const key = keys[ii];
162
+ const maybeNode = this.#style[key];
163
+
164
+ if (key === 'transform' && maybeNode instanceof AnimatedTransform) {
165
+ style[key] = maybeNode.__getValueWithStaticTransforms(
166
+ // NOTE: This check should not be necessary, but the types are not
167
+ // enforced as of this writing.
168
+ Array.isArray(style[key]) ? style[key] : [],
169
+ );
170
+ } else if (maybeNode instanceof AnimatedObject) {
171
+ style[key] = maybeNode.__getValueWithStaticObject(style[key]);
172
+ } else if (maybeNode instanceof AnimatedNode) {
173
+ style[key] = maybeNode.__getValue();
174
+ }
175
+ }
176
+
177
+ /* $FlowFixMe[incompatible-type] Error found due to incomplete typing of
178
+ * Platform.flow.js */
179
+ return Platform.OS === 'web' ? [this.#inputStyle, style] : style;
111
180
  }
112
181
 
113
182
  __getAnimatedValue(): Object {
114
- const style: {[string]: any} = {};
183
+ const style: {[string]: mixed} = {};
115
184
 
116
185
  const nodeKeys = this.#nodeKeys;
117
186
  const nodes = this.#nodes;
@@ -172,3 +241,11 @@ export default class AnimatedStyle extends AnimatedWithChildren {
172
241
  };
173
242
  }
174
243
  }
244
+
245
+ // Supported versions of JSC do not implement the newer Object.hasOwn. Remove
246
+ // this shim when they do.
247
+ // $FlowIgnore[method-unbinding]
248
+ const _hasOwnProp = Object.prototype.hasOwnProperty;
249
+ const hasOwn: (obj: $ReadOnly<{...}>, prop: string) => boolean =
250
+ // $FlowIgnore[method-unbinding]
251
+ Object.hasOwn ?? ((obj, prop) => _hasOwnProp.call(obj, prop));
@@ -12,8 +12,8 @@
12
12
 
13
13
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
14
14
 
15
- import {validateTransform} from '../../../src/private/animated/NativeAnimatedValidation';
16
15
  import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
16
+ import {validateTransform} from '../../../src/private/animated/NativeAnimatedValidation';
17
17
  import AnimatedNode from './AnimatedNode';
18
18
  import AnimatedWithChildren from './AnimatedWithChildren';
19
19
 
@@ -26,37 +26,58 @@ type Transform<T = AnimatedNode> = {
26
26
  | {[string]: number | string | T},
27
27
  };
28
28
 
29
+ function flatAnimatedNodes(
30
+ transforms: $ReadOnlyArray<Transform<>>,
31
+ ): Array<AnimatedNode> {
32
+ const nodes = [];
33
+ for (let ii = 0, length = transforms.length; ii < length; ii++) {
34
+ const transform = transforms[ii];
35
+ // There should be exactly one property in `transform`.
36
+ for (const key in transform) {
37
+ const value = transform[key];
38
+ if (value instanceof AnimatedNode) {
39
+ nodes.push(value);
40
+ }
41
+ }
42
+ }
43
+ return nodes;
44
+ }
45
+
29
46
  export default class AnimatedTransform extends AnimatedWithChildren {
30
47
  // NOTE: For potentially historical reasons, some operations only operate on
31
48
  // the first level of AnimatedNode instances. This optimizes that bevavior.
32
- #shallowNodes: $ReadOnlyArray<AnimatedNode>;
49
+ #nodes: $ReadOnlyArray<AnimatedNode>;
33
50
 
34
51
  _transforms: $ReadOnlyArray<Transform<>>;
35
52
 
36
- constructor(transforms: $ReadOnlyArray<Transform<>>) {
53
+ /**
54
+ * Creates an `AnimatedTransform` if `transforms` contains `AnimatedNode`
55
+ * instances. Otherwise, returns `null`.
56
+ */
57
+ static from(transforms: $ReadOnlyArray<Transform<>>): ?AnimatedTransform {
58
+ const nodes = flatAnimatedNodes(
59
+ // NOTE: This check should not be necessary, but the types are not
60
+ // enforced as of this writing. This check should be hoisted to
61
+ // instantiation sites.
62
+ Array.isArray(transforms) ? transforms : [],
63
+ );
64
+ if (nodes.length === 0) {
65
+ return null;
66
+ }
67
+ return new AnimatedTransform(nodes, transforms);
68
+ }
69
+
70
+ constructor(
71
+ nodes: $ReadOnlyArray<AnimatedNode>,
72
+ transforms: $ReadOnlyArray<Transform<>>,
73
+ ) {
37
74
  super();
75
+ this.#nodes = nodes;
38
76
  this._transforms = transforms;
39
-
40
- const shallowNodes = [];
41
- // NOTE: This check should not be necessary, but the types are not enforced
42
- // as of this writing. This check should be hoisted to instantiation sites.
43
- if (Array.isArray(transforms)) {
44
- for (let ii = 0, length = transforms.length; ii < length; ii++) {
45
- const transform = transforms[ii];
46
- // There should be exactly one property in `transform`.
47
- for (const key in transform) {
48
- const value = transform[key];
49
- if (value instanceof AnimatedNode) {
50
- shallowNodes.push(value);
51
- }
52
- }
53
- }
54
- }
55
- this.#shallowNodes = shallowNodes;
56
77
  }
57
78
 
58
79
  __makeNative(platformConfig: ?PlatformConfig) {
59
- const nodes = this.#shallowNodes;
80
+ const nodes = this.#nodes;
60
81
  for (let ii = 0, length = nodes.length; ii < length; ii++) {
61
82
  const node = nodes[ii];
62
83
  node.__makeNative(platformConfig);
@@ -70,6 +91,18 @@ export default class AnimatedTransform extends AnimatedWithChildren {
70
91
  );
71
92
  }
72
93
 
94
+ __getValueWithStaticTransforms(
95
+ staticTransforms: $ReadOnlyArray<Object>,
96
+ ): $ReadOnlyArray<Object> {
97
+ const values = [];
98
+ mapTransforms(this._transforms, node => {
99
+ values.push(node.__getValue());
100
+ });
101
+ // NOTE: We can depend on `this._transforms` and `staticTransforms` sharing
102
+ // a structure because of `useAnimatedPropsMemo`.
103
+ return mapTransforms(staticTransforms, () => values.shift());
104
+ }
105
+
73
106
  __getAnimatedValue(): $ReadOnlyArray<Transform<any>> {
74
107
  return mapTransforms(this._transforms, animatedNode =>
75
108
  animatedNode.__getAnimatedValue(),
@@ -77,7 +110,7 @@ export default class AnimatedTransform extends AnimatedWithChildren {
77
110
  }
78
111
 
79
112
  __attach(): void {
80
- const nodes = this.#shallowNodes;
113
+ const nodes = this.#nodes;
81
114
  for (let ii = 0, length = nodes.length; ii < length; ii++) {
82
115
  const node = nodes[ii];
83
116
  node.__addChild(this);
@@ -85,7 +118,7 @@ export default class AnimatedTransform extends AnimatedWithChildren {
85
118
  }
86
119
 
87
120
  __detach(): void {
88
- const nodes = this.#shallowNodes;
121
+ const nodes = this.#nodes;
89
122
  for (let ii = 0, length = nodes.length; ii < length; ii++) {
90
123
  const node = nodes[ii];
91
124
  node.__removeChild(this);
@@ -15,8 +15,8 @@ import type {InterpolationConfigType} from './AnimatedInterpolation';
15
15
  import type AnimatedNode from './AnimatedNode';
16
16
  import type AnimatedTracking from './AnimatedTracking';
17
17
 
18
- import InteractionManager from '../../Interaction/InteractionManager';
19
18
  import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
19
+ import InteractionManager from '../../Interaction/InteractionManager';
20
20
  import AnimatedInterpolation from './AnimatedInterpolation';
21
21
  import AnimatedWithChildren from './AnimatedWithChildren';
22
22
 
@@ -28,12 +28,10 @@ export default class AnimatedWithChildren extends AnimatedNode {
28
28
  const children = this._children;
29
29
  let length = children.length;
30
30
  if (length > 0) {
31
- const nativeTag = this.__getNativeTag();
32
-
33
31
  for (let ii = 0; ii < length; ii++) {
34
32
  const child = children[ii];
35
33
  child.__makeNative(platformConfig);
36
- connectAnimatedNodes(nativeTag, child.__getNativeTag());
34
+ connectAnimatedNodes(this.__getNativeTag(), child.__getNativeTag());
37
35
  }
38
36
  }
39
37
  }