react-native-reanimated 2.3.0-alpha.3 → 2.3.0-beta.4

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 (264) hide show
  1. package/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp +15 -8
  2. package/Common/cpp/NativeModules/NativeReanimatedModule.cpp +176 -154
  3. package/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp +49 -33
  4. package/Common/cpp/Registries/EventHandlerRegistry.cpp +14 -7
  5. package/Common/cpp/Registries/MapperRegistry.cpp +24 -20
  6. package/Common/cpp/Registries/WorkletsCache.cpp +19 -9
  7. package/Common/cpp/SharedItems/FrozenObject.cpp +17 -8
  8. package/Common/cpp/SharedItems/MutableValue.cpp +38 -25
  9. package/Common/cpp/SharedItems/MutableValueSetterProxy.cpp +11 -7
  10. package/Common/cpp/SharedItems/RemoteObject.cpp +9 -5
  11. package/Common/cpp/SharedItems/ShareableValue.cpp +211 -160
  12. package/Common/cpp/Tools/FeaturesConfig.cpp +5 -0
  13. package/Common/cpp/Tools/JSIStoreValueUser.cpp +25 -6
  14. package/Common/cpp/Tools/Mapper.cpp +30 -30
  15. package/Common/cpp/Tools/RuntimeDecorator.cpp +124 -86
  16. package/Common/cpp/Tools/Scheduler.cpp +6 -5
  17. package/Common/cpp/Tools/WorkletEventHandler.cpp +4 -2
  18. package/Common/cpp/headers/LayoutAnimations/LayoutAnimationsProxy.h +12 -11
  19. package/Common/cpp/headers/NativeModules/NativeReanimatedModule.h +50 -31
  20. package/Common/cpp/headers/NativeModules/NativeReanimatedModuleSpec.h +34 -16
  21. package/Common/cpp/headers/Registries/EventHandlerRegistry.h +15 -8
  22. package/Common/cpp/headers/Registries/MapperRegistry.h +5 -4
  23. package/Common/cpp/headers/Registries/WorkletsCache.h +9 -7
  24. package/Common/cpp/headers/SharedItems/FrozenObject.h +19 -11
  25. package/Common/cpp/headers/SharedItems/HostFunctionHandler.h +8 -4
  26. package/Common/cpp/headers/SharedItems/MutableValue.h +23 -12
  27. package/Common/cpp/headers/SharedItems/MutableValueSetterProxy.h +12 -7
  28. package/Common/cpp/headers/SharedItems/RemoteObject.h +19 -8
  29. package/Common/cpp/headers/SharedItems/RuntimeManager.h +26 -25
  30. package/Common/cpp/headers/SharedItems/ShareableValue.h +32 -27
  31. package/Common/cpp/headers/SharedItems/SharedParent.h +10 -7
  32. package/Common/cpp/headers/SharedItems/ValueWrapper.h +95 -72
  33. package/Common/cpp/headers/SpecTools/ErrorHandler.h +18 -19
  34. package/Common/cpp/headers/Tools/FeaturesConfig.h +19 -0
  35. package/Common/cpp/headers/Tools/JSIStoreValueUser.h +13 -16
  36. package/Common/cpp/headers/Tools/Mapper.h +19 -16
  37. package/Common/cpp/headers/Tools/PlatformDepMethodsHolder.h +17 -7
  38. package/Common/cpp/headers/Tools/ReanimatedHiddenHeaders.h +7 -11
  39. package/Common/cpp/headers/Tools/RuntimeDecorator.h +36 -27
  40. package/Common/cpp/headers/Tools/Scheduler.h +30 -35
  41. package/Common/cpp/headers/Tools/WorkletEventHandler.h +11 -8
  42. package/Common/cpp/hidden_headers/Logger.h +14 -14
  43. package/Common/cpp/hidden_headers/LoggerInterface.h +8 -9
  44. package/Common/cpp/hidden_headers/SpeedChecker.h +7 -8
  45. package/README.md +1 -1
  46. package/RNReanimated.podspec +24 -6
  47. package/android/build.gradle +38 -29
  48. package/android/react-native-reanimated-63-hermes.aar +0 -0
  49. package/android/react-native-reanimated-63-jsc.aar +0 -0
  50. package/android/react-native-reanimated-64-hermes.aar +0 -0
  51. package/android/react-native-reanimated-64-jsc.aar +0 -0
  52. package/android/react-native-reanimated-65-hermes.aar +0 -0
  53. package/android/react-native-reanimated-65-jsc.aar +0 -0
  54. package/android/react-native-reanimated-66-hermes.aar +0 -0
  55. package/android/react-native-reanimated-66-jsc.aar +0 -0
  56. package/android/react-native-reanimated-67-hermes.aar +0 -0
  57. package/android/react-native-reanimated-67-jsc.aar +0 -0
  58. package/ios/LayoutReanimation/REAAnimationsManager.h +10 -8
  59. package/ios/LayoutReanimation/REAAnimationsManager.m +91 -87
  60. package/ios/LayoutReanimation/REASnapshot.h +2 -2
  61. package/ios/LayoutReanimation/REASnapshot.m +8 -7
  62. package/ios/LayoutReanimation/REAUIManager.h +4 -4
  63. package/ios/LayoutReanimation/REAUIManager.mm +116 -70
  64. package/ios/Nodes/REAAlwaysNode.m +14 -15
  65. package/ios/Nodes/REABezierNode.m +8 -7
  66. package/ios/Nodes/REABlockNode.m +1 -1
  67. package/ios/Nodes/REACallFuncNode.h +0 -1
  68. package/ios/Nodes/REACallFuncNode.m +10 -8
  69. package/ios/Nodes/REAClockNodes.m +22 -20
  70. package/ios/Nodes/REAConcatNode.h +0 -1
  71. package/ios/Nodes/REAConcatNode.m +2 -2
  72. package/ios/Nodes/REACondNode.m +7 -5
  73. package/ios/Nodes/READebugNode.m +5 -4
  74. package/ios/Nodes/REAEventNode.m +1 -1
  75. package/ios/Nodes/REAFunctionNode.h +0 -1
  76. package/ios/Nodes/REAFunctionNode.m +2 -2
  77. package/ios/Nodes/REAJSCallNode.m +4 -5
  78. package/ios/Nodes/REANode.h +3 -4
  79. package/ios/Nodes/REANode.m +9 -11
  80. package/ios/Nodes/REAOperatorNode.m +68 -67
  81. package/ios/Nodes/REAParamNode.h +1 -3
  82. package/ios/Nodes/REAParamNode.m +15 -17
  83. package/ios/Nodes/REAPropsNode.h +1 -3
  84. package/ios/Nodes/REAPropsNode.m +19 -22
  85. package/ios/Nodes/REASetNode.h +0 -1
  86. package/ios/Nodes/REASetNode.m +7 -5
  87. package/ios/Nodes/REAStyleNode.h +0 -1
  88. package/ios/Nodes/REAStyleNode.m +2 -4
  89. package/ios/Nodes/REATransformNode.h +0 -1
  90. package/ios/Nodes/REATransformNode.m +3 -5
  91. package/ios/Nodes/REAValueNode.m +5 -7
  92. package/ios/REAEventDispatcher.m +4 -4
  93. package/ios/REAModule.h +0 -2
  94. package/ios/REAModule.m +29 -38
  95. package/ios/REANodesManager.h +11 -19
  96. package/ios/REANodesManager.m +106 -130
  97. package/ios/REAUtils.h +5 -3
  98. package/ios/RNGestureHandlerStateManager.h +5 -0
  99. package/ios/Transitioning/RCTConvert+REATransition.m +45 -29
  100. package/ios/Transitioning/REAAllTransitions.h +2 -2
  101. package/ios/Transitioning/REAAllTransitions.m +14 -25
  102. package/ios/Transitioning/REATransition.h +8 -7
  103. package/ios/Transitioning/REATransition.m +19 -16
  104. package/ios/Transitioning/REATransitionAnimation.h +1 -1
  105. package/ios/Transitioning/REATransitionAnimation.m +2 -3
  106. package/ios/Transitioning/REATransitionManager.m +3 -3
  107. package/ios/native/NativeMethods.h +20 -5
  108. package/ios/native/NativeMethods.mm +14 -6
  109. package/ios/native/NativeProxy.h +4 -2
  110. package/ios/native/NativeProxy.mm +84 -63
  111. package/ios/native/REAIOSErrorHandler.h +13 -10
  112. package/ios/native/REAIOSErrorHandler.mm +19 -15
  113. package/ios/native/REAIOSLogger.h +8 -8
  114. package/ios/native/REAIOSLogger.mm +10 -6
  115. package/ios/native/REAIOSScheduler.h +5 -5
  116. package/ios/native/REAIOSScheduler.mm +17 -10
  117. package/ios/native/REAInitializer.h +5 -7
  118. package/ios/native/REAInitializer.mm +43 -31
  119. package/ios/native/UIResponder+Reanimated.mm +2 -2
  120. package/lib/Animated.js +9 -1
  121. package/lib/ConfigHelper.js +121 -138
  122. package/lib/ReanimatedEventEmitter.js +0 -1
  123. package/lib/ReanimatedModule.js +0 -1
  124. package/lib/ReanimatedModule.macos.js +0 -1
  125. package/lib/ReanimatedModule.native.js +5 -6
  126. package/lib/ReanimatedModule.windows.js +0 -1
  127. package/lib/ReanimatedModuleCompat.js +64 -35
  128. package/lib/createAnimatedComponent.js +468 -487
  129. package/lib/index.js +9 -1
  130. package/lib/reanimated2/NativeMethods.js +7 -12
  131. package/lib/reanimated2/NativeReanimated/NativeReanimated.js +37 -0
  132. package/lib/reanimated2/NativeReanimated/index.js +15 -0
  133. package/lib/reanimated2/PropAdapters.js +0 -1
  134. package/lib/reanimated2/UpdateProps.js +6 -7
  135. package/lib/reanimated2/ViewDescriptorsSet.js +4 -4
  136. package/lib/reanimated2/WorkletEventHandler.js +15 -13
  137. package/lib/reanimated2/animation/delay.js +8 -2
  138. package/lib/reanimated2/animation/spring.js +2 -0
  139. package/lib/reanimated2/animation/styleAnimation.js +7 -3
  140. package/lib/reanimated2/animation/util.js +25 -2
  141. package/lib/reanimated2/core.js +41 -17
  142. package/lib/reanimated2/globals.d.ts +21 -1
  143. package/lib/reanimated2/hook/useAnimatedRef.js +1 -1
  144. package/lib/reanimated2/hook/useAnimatedStyle.js +3 -3
  145. package/lib/reanimated2/index.js +1 -0
  146. package/lib/reanimated2/interpolation.js +95 -87
  147. package/lib/reanimated2/js-reanimated/JSReanimated.js +13 -10
  148. package/lib/reanimated2/js-reanimated/Mapper.js +4 -3
  149. package/lib/reanimated2/js-reanimated/MapperRegistry.js +3 -6
  150. package/lib/reanimated2/js-reanimated/MutableValue.js +0 -2
  151. package/lib/reanimated2/js-reanimated/index.js +10 -8
  152. package/lib/reanimated2/layoutReanimation/LayoutAnimationRepository.js +33 -2
  153. package/lib/reanimated2/layoutReanimation/animationBuilder/BaseAnimationBuilder.js +27 -124
  154. package/lib/reanimated2/layoutReanimation/animationBuilder/ComplexAnimationBuilder.js +125 -0
  155. package/lib/reanimated2/layoutReanimation/animationBuilder/index.js +1 -2
  156. package/lib/reanimated2/layoutReanimation/defaultAnimations/Bounce.js +115 -45
  157. package/lib/reanimated2/layoutReanimation/defaultAnimations/Default.js +7 -2
  158. package/lib/reanimated2/layoutReanimation/defaultAnimations/Fade.js +21 -21
  159. package/lib/reanimated2/layoutReanimation/defaultAnimations/Flip.js +25 -25
  160. package/lib/reanimated2/layoutReanimation/defaultAnimations/Lightspeed.js +19 -17
  161. package/lib/reanimated2/layoutReanimation/defaultAnimations/Pinwheel.js +5 -5
  162. package/lib/reanimated2/layoutReanimation/defaultAnimations/Roll.js +9 -9
  163. package/lib/reanimated2/layoutReanimation/defaultAnimations/Rotate.js +17 -17
  164. package/lib/reanimated2/layoutReanimation/defaultAnimations/Slide.js +19 -19
  165. package/lib/reanimated2/layoutReanimation/defaultAnimations/Stretch.js +9 -9
  166. package/lib/reanimated2/layoutReanimation/defaultAnimations/Zoom.js +33 -33
  167. package/lib/reanimated2/layoutReanimation/defaultTransitions/CurvedTransition.js +78 -0
  168. package/lib/reanimated2/layoutReanimation/defaultTransitions/EntryExitTransition.js +128 -0
  169. package/lib/reanimated2/layoutReanimation/defaultTransitions/FadingTransition.js +37 -0
  170. package/lib/reanimated2/layoutReanimation/defaultTransitions/JumpingTransition.js +41 -0
  171. package/lib/reanimated2/layoutReanimation/defaultTransitions/LinearTransition.js +34 -0
  172. package/lib/reanimated2/layoutReanimation/defaultTransitions/SequencedTransition.js +46 -0
  173. package/lib/reanimated2/layoutReanimation/defaultTransitions/index.js +6 -0
  174. package/lib/reanimated2/layoutReanimation/index.js +1 -0
  175. package/lib/reanimated2/mock.js +3 -1
  176. package/lib/reanimated2/utils.js +9 -0
  177. package/lib/setAndForwardRef.js +14 -48
  178. package/libSo/fbjni/jni/arm64-v8a/libfbjni.so +0 -0
  179. package/libSo/fbjni/jni/armeabi-v7a/libfbjni.so +0 -0
  180. package/libSo/fbjni/jni/x86/libfbjni.so +0 -0
  181. package/libSo/fbjni/jni/x86_64/libfbjni.so +0 -0
  182. package/mock.js +1 -1
  183. package/package.json +28 -17
  184. package/plugin.js +220 -39
  185. package/react-native-reanimated.d.ts +542 -547
  186. package/src/Animated.js +9 -1
  187. package/src/{ConfigHelper.js → ConfigHelper.ts} +15 -7
  188. package/src/{ReanimatedEventEmitter.js → ReanimatedEventEmitter.ts} +0 -0
  189. package/src/{ReanimatedModule.js → ReanimatedModule.macos.ts} +0 -0
  190. package/src/{ReanimatedModule.native.js → ReanimatedModule.native.ts} +0 -0
  191. package/src/{ReanimatedModule.macos.js → ReanimatedModule.ts} +0 -0
  192. package/src/{ReanimatedModule.windows.js → ReanimatedModule.windows.ts} +0 -0
  193. package/src/ReanimatedModuleCompat.ts +51 -0
  194. package/src/{createAnimatedComponent.js → createAnimatedComponent.tsx} +285 -126
  195. package/src/reanimated2/NativeMethods.ts +34 -13
  196. package/src/reanimated2/NativeReanimated/NativeReanimated.ts +72 -0
  197. package/src/reanimated2/NativeReanimated/index.ts +18 -0
  198. package/src/reanimated2/PropAdapters.ts +0 -1
  199. package/src/reanimated2/UpdateProps.ts +31 -15
  200. package/src/reanimated2/ViewDescriptorsSet.ts +15 -12
  201. package/src/reanimated2/WorkletEventHandler.ts +41 -23
  202. package/src/reanimated2/animation/commonTypes.ts +4 -4
  203. package/src/reanimated2/animation/decay.ts +2 -2
  204. package/src/reanimated2/animation/delay.ts +11 -5
  205. package/src/reanimated2/animation/index.ts +7 -7
  206. package/src/reanimated2/animation/repeat.ts +4 -4
  207. package/src/reanimated2/animation/sequence.ts +2 -2
  208. package/src/reanimated2/animation/spring.ts +6 -5
  209. package/src/reanimated2/animation/styleAnimation.ts +27 -15
  210. package/src/reanimated2/animation/timing.ts +5 -5
  211. package/src/reanimated2/animation/util.ts +47 -8
  212. package/src/reanimated2/commonTypes.ts +3 -0
  213. package/src/reanimated2/core.ts +80 -34
  214. package/src/reanimated2/globals.d.ts +21 -1
  215. package/src/reanimated2/hook/useAnimatedGestureHandler.ts +1 -1
  216. package/src/reanimated2/hook/useAnimatedRef.ts +13 -15
  217. package/src/reanimated2/hook/useAnimatedScrollHandler.ts +3 -3
  218. package/src/reanimated2/hook/useAnimatedStyle.ts +7 -7
  219. package/src/reanimated2/hook/utils.ts +4 -3
  220. package/src/reanimated2/index.ts +1 -0
  221. package/src/reanimated2/interpolation.ts +170 -103
  222. package/src/reanimated2/js-reanimated/JSReanimated.ts +37 -23
  223. package/src/reanimated2/js-reanimated/Mapper.ts +22 -9
  224. package/src/reanimated2/js-reanimated/MapperRegistry.ts +22 -19
  225. package/src/reanimated2/js-reanimated/MutableValue.ts +11 -11
  226. package/src/reanimated2/js-reanimated/index.ts +31 -14
  227. package/src/reanimated2/layoutReanimation/LayoutAnimationRepository.ts +75 -0
  228. package/src/reanimated2/layoutReanimation/animationBuilder/BaseAnimationBuilder.ts +29 -159
  229. package/src/reanimated2/layoutReanimation/animationBuilder/ComplexAnimationBuilder.ts +169 -0
  230. package/src/reanimated2/layoutReanimation/animationBuilder/Keyframe.ts +2 -2
  231. package/src/reanimated2/layoutReanimation/animationBuilder/commonTypes.ts +3 -9
  232. package/src/reanimated2/layoutReanimation/animationBuilder/index.ts +1 -5
  233. package/src/reanimated2/layoutReanimation/defaultAnimations/Bounce.ts +162 -82
  234. package/src/reanimated2/layoutReanimation/defaultAnimations/Default.ts +7 -2
  235. package/src/reanimated2/layoutReanimation/defaultAnimations/Fade.ts +32 -32
  236. package/src/reanimated2/layoutReanimation/defaultAnimations/Flip.ts +38 -38
  237. package/src/reanimated2/layoutReanimation/defaultAnimations/Lightspeed.ts +34 -32
  238. package/src/reanimated2/layoutReanimation/defaultAnimations/Pinwheel.ts +8 -8
  239. package/src/reanimated2/layoutReanimation/defaultAnimations/Roll.ts +14 -14
  240. package/src/reanimated2/layoutReanimation/defaultAnimations/Rotate.ts +26 -26
  241. package/src/reanimated2/layoutReanimation/defaultAnimations/Slide.ts +28 -28
  242. package/src/reanimated2/layoutReanimation/defaultAnimations/Stretch.ts +14 -14
  243. package/src/reanimated2/layoutReanimation/defaultAnimations/Zoom.ts +50 -50
  244. package/src/reanimated2/layoutReanimation/defaultTransitions/CurvedTransition.ts +104 -0
  245. package/src/reanimated2/layoutReanimation/defaultTransitions/EntryExitTransition.ts +213 -0
  246. package/src/reanimated2/layoutReanimation/defaultTransitions/FadingTransition.ts +60 -0
  247. package/src/reanimated2/layoutReanimation/defaultTransitions/JumpingTransition.ts +58 -0
  248. package/src/reanimated2/layoutReanimation/defaultTransitions/LinearTransition.ts +41 -0
  249. package/src/reanimated2/layoutReanimation/defaultTransitions/SequencedTransition.ts +78 -0
  250. package/src/reanimated2/layoutReanimation/defaultTransitions/index.ts +6 -0
  251. package/src/reanimated2/layoutReanimation/index.ts +1 -0
  252. package/src/reanimated2/mock.ts +3 -1
  253. package/src/reanimated2/utils.ts +21 -0
  254. package/src/{setAndForwardRef.js → setAndForwardRef.ts} +12 -2
  255. package/android/react-native-reanimated-62-hermes.aar +0 -0
  256. package/android/react-native-reanimated-62-jsc.aar +0 -0
  257. package/lib/reanimated2/NativeReanimated.js +0 -48
  258. package/lib/reanimated2/layoutReanimation/animationBuilder/BaseBounceAnimationBuilder.js +0 -55
  259. package/lib/reanimated2/layoutReanimation/animationBuilder/LayoutAnimationBuilder.js +0 -165
  260. package/src/ReanimatedModuleCompat.js +0 -37
  261. package/src/reanimated2/NativeReanimated.ts +0 -70
  262. package/src/reanimated2/layoutReanimation/LayoutAnimationRepository.tsx +0 -41
  263. package/src/reanimated2/layoutReanimation/animationBuilder/BaseBounceAnimationBuilder.ts +0 -82
  264. package/src/reanimated2/layoutReanimation/animationBuilder/LayoutAnimationBuilder.ts +0 -217
@@ -1,10 +1,14 @@
1
- import React from 'react';
1
+ import React, { Component, ComponentType, MutableRefObject, Ref } from 'react';
2
2
  import { findNodeHandle, Platform, StyleSheet } from 'react-native';
3
3
  import ReanimatedEventEmitter from './ReanimatedEventEmitter';
4
4
 
5
+ // @ts-ignore JS file
5
6
  import AnimatedEvent from './reanimated1/core/AnimatedEvent';
7
+ // @ts-ignore JS file
6
8
  import AnimatedNode from './reanimated1/core/AnimatedNode';
9
+ // @ts-ignore JS file
7
10
  import AnimatedValue from './reanimated1/core/AnimatedValue';
11
+ // @ts-ignore JS file
8
12
  import { createOrReusePropsNode } from './reanimated1/core/AnimatedProps';
9
13
  import WorkletEventHandler from './reanimated2/WorkletEventHandler';
10
14
  import setAndForwardRef from './setAndForwardRef';
@@ -13,17 +17,41 @@ import './reanimated2/layoutReanimation/LayoutAnimationRepository';
13
17
  import invariant from 'invariant';
14
18
  import { adaptViewConfig } from './ConfigHelper';
15
19
  import { RNRenderer } from './reanimated2/platform-specific/RNRenderer';
16
- import { makeMutable, runOnUI } from './reanimated2/core';
20
+ import {
21
+ makeMutable,
22
+ runOnUI,
23
+ enableLayoutAnimations,
24
+ } from './reanimated2/core';
17
25
  import {
18
26
  DefaultEntering,
19
27
  DefaultExiting,
20
28
  DefaultLayout,
21
29
  } from './reanimated2/layoutReanimation/defaultAnimations/Default';
22
- import { isJest, isChromeDebugger } from './reanimated2/PlatformChecker';
30
+ import {
31
+ isJest,
32
+ isChromeDebugger,
33
+ shouldBeUseWeb,
34
+ } from './reanimated2/PlatformChecker';
35
+ import { initialUpdaterRun } from './reanimated2/animation';
36
+ import {
37
+ BaseAnimationBuilder,
38
+ EntryExitAnimationFunction,
39
+ LayoutAnimationFunction,
40
+ } from './reanimated2/layoutReanimation';
41
+ import { SharedValue, StyleProps } from './reanimated2/commonTypes';
42
+ import {
43
+ ViewDescriptorsSet,
44
+ ViewRefSet,
45
+ } from './reanimated2/ViewDescriptorsSet';
23
46
 
24
47
  const NODE_MAPPING = new Map();
25
48
 
26
- function listener(data) {
49
+ interface ListenerData {
50
+ viewTag: number;
51
+ props: StyleProps;
52
+ }
53
+
54
+ function listener(data: ListenerData) {
27
55
  const component = NODE_MAPPING.get(data.viewTag);
28
56
  component && component._updateFromNative(data.props);
29
57
  }
@@ -33,7 +61,7 @@ function dummyListener() {
33
61
  // event is used.
34
62
  }
35
63
 
36
- function hasAnimatedNodes(value) {
64
+ function hasAnimatedNodes(value: unknown): boolean {
37
65
  if (value instanceof AnimatedNode) {
38
66
  return true;
39
67
  }
@@ -41,18 +69,21 @@ function hasAnimatedNodes(value) {
41
69
  return value.some((item) => hasAnimatedNodes(item));
42
70
  }
43
71
  if (value && typeof value === 'object') {
44
- return Object.keys(value).some((key) => hasAnimatedNodes(value[key]));
72
+ return Object.keys(value).some((key) =>
73
+ hasAnimatedNodes((value as Record<string, unknown>)[key])
74
+ );
45
75
  }
46
76
  return false;
47
77
  }
48
78
 
49
- function flattenArray(array) {
79
+ type NestedArray<T> = T | NestedArray<T>[];
80
+ function flattenArray<T>(array: NestedArray<T>): T[] {
50
81
  if (!Array.isArray(array)) {
51
82
  return [array];
52
83
  }
53
- const resultArr = [];
84
+ const resultArr: T[] = [];
54
85
 
55
- const _flattenArray = (arr) => {
86
+ const _flattenArray = (arr: NestedArray<T>[]): void => {
56
87
  arr.forEach((item) => {
57
88
  if (Array.isArray(item)) {
58
89
  _flattenArray(item);
@@ -65,7 +96,83 @@ function flattenArray(array) {
65
96
  return resultArr;
66
97
  }
67
98
 
68
- export default function createAnimatedComponent(Component, options = {}) {
99
+ function onlyAnimatedStyles(styles: StyleProps[]) {
100
+ return styles.filter((style) => style?.viewDescriptors);
101
+ }
102
+
103
+ function isSameAnimatedStyle(style1: StyleProps, style2: StyleProps): boolean {
104
+ // We cannot use equality check to compare useAnimatedStyle outputs directly.
105
+ // Instead, we can compare its viewsRefs.
106
+ return style1.viewsRef === style2.viewsRef;
107
+ }
108
+
109
+ const has = <K extends string>(
110
+ key: K,
111
+ x: unknown
112
+ ): x is { [key in K]: unknown } => {
113
+ if (typeof x === 'function' || typeof x === 'object') {
114
+ if (x === null || x === undefined) {
115
+ return false;
116
+ } else {
117
+ return key in x;
118
+ }
119
+ }
120
+ return false;
121
+ };
122
+
123
+ interface AnimatedProps extends Record<string, unknown> {
124
+ viewDescriptors?: ViewDescriptorsSet;
125
+ viewsRef?: ViewRefSet<unknown>;
126
+ initial?: SharedValue<StyleProps>;
127
+ }
128
+
129
+ export type AnimatedComponentProps<P extends Record<string, unknown>> = P & {
130
+ forwardedRef?: Ref<Component>;
131
+ style?: NestedArray<StyleProps>;
132
+ animatedProps?: Partial<AnimatedComponentProps<AnimatedProps>>;
133
+ animatedStyle?: StyleProps;
134
+ layout?:
135
+ | BaseAnimationBuilder
136
+ | LayoutAnimationFunction
137
+ | typeof BaseAnimationBuilder;
138
+ entering?:
139
+ | BaseAnimationBuilder
140
+ | typeof BaseAnimationBuilder
141
+ | EntryExitAnimationFunction
142
+ | Keyframe;
143
+ exiting?:
144
+ | BaseAnimationBuilder
145
+ | typeof BaseAnimationBuilder
146
+ | EntryExitAnimationFunction
147
+ | Keyframe;
148
+ };
149
+
150
+ type Options<P> = {
151
+ setNativeProps: (ref: ComponentRef, props: P) => void;
152
+ };
153
+
154
+ interface ComponentRef extends Component {
155
+ setNativeProps?: (props: Record<string, unknown>) => void;
156
+ getScrollableNode?: () => ComponentRef;
157
+ }
158
+
159
+ interface InitialComponentProps extends Record<string, unknown> {
160
+ ref?: Ref<Component>;
161
+ collapsable?: boolean;
162
+ }
163
+
164
+ interface PropsAnimated {
165
+ __onEvaluate: () => StyleProps;
166
+ __detach: () => void;
167
+ __getValue: () => StyleProps;
168
+ update: () => void;
169
+ setNativeView: (view: Component) => void;
170
+ }
171
+
172
+ export default function createAnimatedComponent(
173
+ Component: ComponentType<InitialComponentProps>,
174
+ options?: Options<InitialComponentProps>
175
+ ): ComponentType<AnimatedComponentProps<InitialComponentProps>> {
69
176
  invariant(
70
177
  typeof Component !== 'function' ||
71
178
  (Component.prototype && Component.prototype.isReactComponent),
@@ -73,12 +180,21 @@ export default function createAnimatedComponent(Component, options = {}) {
73
180
  'use a class component instead.'
74
181
  );
75
182
 
76
- class AnimatedComponent extends React.Component {
183
+ class AnimatedComponent extends React.Component<
184
+ AnimatedComponentProps<InitialComponentProps>
185
+ > {
77
186
  _invokeAnimatedPropsCallbackOnMount = false;
78
- _styles = null;
187
+ _styles: StyleProps[] | null = null;
188
+ _animatedProps?: Partial<AnimatedComponentProps<AnimatedProps>>;
79
189
  _viewTag = -1;
80
-
81
- constructor(props) {
190
+ _isFirstRender = true;
191
+ animatedStyle: { value: StyleProps } = { value: {} };
192
+ sv: SharedValue<null | Record<string, unknown>> | null;
193
+ _propsAnimated?: PropsAnimated;
194
+ _component: ComponentRef | null = null;
195
+ static displayName: string;
196
+
197
+ constructor(props: AnimatedComponentProps<InitialComponentProps>) {
82
198
  super(props);
83
199
  this._attachProps(this.props);
84
200
  if (isJest()) {
@@ -101,7 +217,9 @@ export default function createAnimatedComponent(Component, options = {}) {
101
217
  this._animatedPropsCallback();
102
218
  }
103
219
 
104
- this._propsAnimated && this._propsAnimated.setNativeView(this._component);
220
+ this._propsAnimated &&
221
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
222
+ this._propsAnimated.setNativeView(this._component!);
105
223
  this._attachNativeEvents();
106
224
  this._attachPropUpdater();
107
225
  this._attachAnimatedStyles();
@@ -110,23 +228,23 @@ export default function createAnimatedComponent(Component, options = {}) {
110
228
  _getEventViewRef() {
111
229
  // Make sure to get the scrollable node for components that implement
112
230
  // `ScrollResponder.Mixin`.
113
- return this._component.getScrollableNode
231
+ return this._component?.getScrollableNode
114
232
  ? this._component.getScrollableNode()
115
233
  : this._component;
116
234
  }
117
235
 
118
236
  _attachNativeEvents() {
119
237
  const node = this._getEventViewRef();
120
- const viewTag = findNodeHandle(options.setNativeProps ? this : node);
238
+ const viewTag = findNodeHandle(options?.setNativeProps ? this : node);
121
239
  for (const key in this.props) {
122
240
  const prop = this.props[key];
123
241
  if (prop instanceof AnimatedEvent) {
124
- prop.attachEvent(node, key);
242
+ (prop as AnimatedEvent).attachEvent(node, key);
125
243
  } else if (
126
- prop?.current &&
244
+ has('current', prop) &&
127
245
  prop.current instanceof WorkletEventHandler
128
246
  ) {
129
- prop.current.registerForEvents(viewTag, key);
247
+ prop.current.registerForEvents(viewTag as number, key);
130
248
  }
131
249
  }
132
250
  }
@@ -137,9 +255,9 @@ export default function createAnimatedComponent(Component, options = {}) {
137
255
  for (const key in this.props) {
138
256
  const prop = this.props[key];
139
257
  if (prop instanceof AnimatedEvent) {
140
- prop.detachEvent(node, key);
258
+ (prop as AnimatedEvent).detachEvent(node, key);
141
259
  } else if (
142
- prop?.current &&
260
+ has('current', prop) &&
143
261
  prop.current instanceof WorkletEventHandler
144
262
  ) {
145
263
  prop.current.unregisterFromEvents();
@@ -148,17 +266,15 @@ export default function createAnimatedComponent(Component, options = {}) {
148
266
  }
149
267
 
150
268
  _detachStyles() {
151
- if (Platform.OS === 'web') {
269
+ if (Platform.OS === 'web' && this._styles !== null) {
152
270
  for (const style of this._styles) {
153
- if (style.viewsRef) {
271
+ if (style?.viewsRef) {
154
272
  style.viewsRef.remove(this);
155
273
  }
156
274
  }
157
- } else if (this._viewTag !== -1) {
275
+ } else if (this._viewTag !== -1 && this._styles !== null) {
158
276
  for (const style of this._styles) {
159
- if (style?.viewDescriptors) {
160
- style.viewDescriptors.remove(this._viewTag);
161
- }
277
+ style.viewDescriptors.remove(this._viewTag);
162
278
  }
163
279
  if (this.props.animatedProps?.viewDescriptors) {
164
280
  this.props.animatedProps.viewDescriptors.remove(this._viewTag);
@@ -166,18 +282,20 @@ export default function createAnimatedComponent(Component, options = {}) {
166
282
  }
167
283
  }
168
284
 
169
- _reattachNativeEvents(prevProps) {
285
+ _reattachNativeEvents(
286
+ prevProps: AnimatedComponentProps<InitialComponentProps>
287
+ ) {
170
288
  const node = this._getEventViewRef();
171
289
  const attached = new Set();
172
290
  const nextEvts = new Set();
173
- let viewTag;
291
+ let viewTag: number | undefined;
174
292
 
175
293
  for (const key in this.props) {
176
294
  const prop = this.props[key];
177
295
  if (prop instanceof AnimatedEvent) {
178
- nextEvts.add(prop.__nodeID);
296
+ nextEvts.add((prop as AnimatedEvent).__nodeID);
179
297
  } else if (
180
- prop?.current &&
298
+ has('current', prop) &&
181
299
  prop.current instanceof WorkletEventHandler
182
300
  ) {
183
301
  if (viewTag === undefined) {
@@ -188,15 +306,15 @@ export default function createAnimatedComponent(Component, options = {}) {
188
306
  for (const key in prevProps) {
189
307
  const prop = this.props[key];
190
308
  if (prop instanceof AnimatedEvent) {
191
- if (!nextEvts.has(prop.__nodeID)) {
309
+ if (!nextEvts.has((prop as AnimatedEvent).__nodeID)) {
192
310
  // event was in prev props but not in current props, we detach
193
- prop.detachEvent(node, key);
311
+ (prop as AnimatedEvent).detachEvent(node, key);
194
312
  } else {
195
313
  // event was in prev and is still in current props
196
- attached.add(prop.__nodeID);
314
+ attached.add((prop as AnimatedEvent).__nodeID);
197
315
  }
198
316
  } else if (
199
- prop?.current &&
317
+ has('current', prop) &&
200
318
  prop.current instanceof WorkletEventHandler &&
201
319
  prop.current.reattachNeeded
202
320
  ) {
@@ -206,15 +324,19 @@ export default function createAnimatedComponent(Component, options = {}) {
206
324
 
207
325
  for (const key in this.props) {
208
326
  const prop = this.props[key];
209
- if (prop instanceof AnimatedEvent && !attached.has(prop.__nodeID)) {
327
+ if (
328
+ prop instanceof AnimatedEvent &&
329
+ !attached.has((prop as AnimatedEvent).__nodeID)
330
+ ) {
210
331
  // not yet attached
211
- prop.attachEvent(node, key);
332
+ (prop as AnimatedEvent).attachEvent(node, key);
212
333
  } else if (
213
- prop?.current &&
334
+ has('current', prop) &&
214
335
  prop.current instanceof WorkletEventHandler &&
215
336
  prop.current.reattachNeeded
216
337
  ) {
217
- prop.current.registerForEvents(viewTag, key);
338
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
339
+ prop.current.registerForEvents(viewTag!, key);
218
340
  prop.current.reattachNeeded = false;
219
341
  }
220
342
  }
@@ -236,11 +358,12 @@ export default function createAnimatedComponent(Component, options = {}) {
236
358
  } else if (typeof this._component.setNativeProps !== 'function') {
237
359
  this.forceUpdate();
238
360
  } else {
239
- this._component.setNativeProps(this._propsAnimated.__getValue());
361
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
362
+ this._component.setNativeProps(this._propsAnimated!.__getValue());
240
363
  }
241
364
  };
242
365
 
243
- _attachProps(nextProps) {
366
+ _attachProps(nextProps: StyleProps) {
244
367
  const oldPropsAnimated = this._propsAnimated;
245
368
 
246
369
  this._propsAnimated = createOrReusePropsNode(
@@ -262,12 +385,13 @@ export default function createAnimatedComponent(Component, options = {}) {
262
385
  }
263
386
  }
264
387
 
265
- _updateFromNative(props) {
266
- if (options.setNativeProps) {
267
- options.setNativeProps(this._component, props);
388
+ _updateFromNative(props: StyleProps) {
389
+ if (options?.setNativeProps) {
390
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
391
+ options.setNativeProps(this._component!, props);
268
392
  } else {
269
393
  // eslint-disable-next-line no-unused-expressions
270
- this._component.setNativeProps?.(props);
394
+ this._component?.setNativeProps?.(props);
271
395
  }
272
396
  }
273
397
 
@@ -280,9 +404,17 @@ export default function createAnimatedComponent(Component, options = {}) {
280
404
  }
281
405
 
282
406
  _attachAnimatedStyles() {
283
- const styles = flattenArray(this.props.style);
407
+ const styles = this.props.style
408
+ ? onlyAnimatedStyles(flattenArray<StyleProps>(this.props.style))
409
+ : [];
410
+ const prevStyles = this._styles;
284
411
  this._styles = styles;
285
- let viewTag, viewName;
412
+
413
+ const prevAnimatedProps = this._animatedProps;
414
+ this._animatedProps = this.props.animatedProps;
415
+
416
+ let viewTag: number | null;
417
+ let viewName: string | null;
286
418
  if (Platform.OS === 'web') {
287
419
  viewTag = findNodeHandle(this);
288
420
  viewName = null;
@@ -302,58 +434,68 @@ export default function createAnimatedComponent(Component, options = {}) {
302
434
  */
303
435
  viewName = hostInstance?.viewConfig?.uiViewClassName;
304
436
  // update UI props whitelist for this view
305
- if (
306
- hostInstance &&
307
- this._hasReanimated2Props(styles) &&
308
- hostInstance.viewConfig
309
- ) {
437
+ const hasReanimated2Props =
438
+ this.props.animatedProps?.viewDescriptors || styles.length;
439
+ if (hasReanimated2Props && hostInstance?.viewConfig) {
310
440
  adaptViewConfig(hostInstance.viewConfig);
311
441
  }
312
442
  }
313
- this._viewTag = viewTag;
443
+ this._viewTag = viewTag as number;
444
+
445
+ // remove old styles
446
+ if (prevStyles) {
447
+ // in most of the cases, views have only a single animated style and it remains unchanged
448
+ const hasOneSameStyle =
449
+ styles.length === 1 &&
450
+ prevStyles.length === 1 &&
451
+ isSameAnimatedStyle(styles[0], prevStyles[0]);
452
+
453
+ if (!hasOneSameStyle) {
454
+ // otherwise, remove each style that is not present in new styles
455
+ for (const prevStyle of prevStyles) {
456
+ const isPresent = styles.some((style) =>
457
+ isSameAnimatedStyle(style, prevStyle)
458
+ );
459
+ if (!isPresent) {
460
+ prevStyle.viewDescriptors.remove(viewTag);
461
+ }
462
+ }
463
+ }
464
+ }
314
465
 
315
466
  styles.forEach((style) => {
316
- if (style?.viewDescriptors) {
317
- style.viewDescriptors.add({ tag: viewTag, name: viewName });
318
- if (isJest()) {
319
- /**
320
- * We need to connect Jest's TestObject instance whose contains just props object
321
- * with the updateProps() function where we update the properties of the component.
322
- * We can't update props object directly because TestObject contains a copy of props - look at render function:
323
- * const props = this._filterNonAnimatedProps(this.props);
324
- */
325
- this.animatedStyle.value = {
326
- ...this.animatedStyle.value,
327
- ...style.initial.value,
328
- };
329
- style.animatedStyle.current = this.animatedStyle;
330
- }
467
+ style.viewDescriptors.add({ tag: viewTag, name: viewName });
468
+ if (isJest()) {
469
+ /**
470
+ * We need to connect Jest's TestObject instance whose contains just props object
471
+ * with the updateProps() function where we update the properties of the component.
472
+ * We can't update props object directly because TestObject contains a copy of props - look at render function:
473
+ * const props = this._filterNonAnimatedProps(this.props);
474
+ */
475
+ this.animatedStyle.value = {
476
+ ...this.animatedStyle.value,
477
+ ...style.initial.value,
478
+ };
479
+ style.animatedStyle.current = this.animatedStyle;
331
480
  }
332
481
  });
482
+
483
+ // detach old animatedProps
484
+ if (prevAnimatedProps && prevAnimatedProps !== this.props.animatedProps) {
485
+ prevAnimatedProps.viewDescriptors!.remove(viewTag as number);
486
+ }
487
+
333
488
  // attach animatedProps property
334
489
  if (this.props.animatedProps?.viewDescriptors) {
335
490
  this.props.animatedProps.viewDescriptors.add({
336
- tag: viewTag,
337
- name: viewName,
491
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
492
+ tag: viewTag!,
493
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
494
+ name: viewName!,
338
495
  });
339
496
  }
340
497
  }
341
498
 
342
- _hasReanimated2Props(flattenStyles) {
343
- if (this.props.animatedProps?.viewDescriptors) {
344
- return true;
345
- }
346
- if (this.props.style) {
347
- for (const style of flattenStyles) {
348
- // eslint-disable-next-line no-prototype-builtins
349
- if (style?.hasOwnProperty('viewDescriptors')) {
350
- return true;
351
- }
352
- }
353
- }
354
- return false;
355
- }
356
-
357
499
  _detachPropUpdater() {
358
500
  const viewTag = findNodeHandle(this);
359
501
  NODE_MAPPING.delete(viewTag);
@@ -362,16 +504,23 @@ export default function createAnimatedComponent(Component, options = {}) {
362
504
  }
363
505
  }
364
506
 
365
- componentDidUpdate(prevProps) {
507
+ componentDidUpdate(
508
+ prevProps: AnimatedComponentProps<InitialComponentProps>
509
+ ) {
366
510
  this._attachProps(this.props);
367
511
  this._reattachNativeEvents(prevProps);
368
512
 
369
- this._propsAnimated && this._propsAnimated.setNativeView(this._component);
513
+ this._propsAnimated &&
514
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
515
+ this._propsAnimated.setNativeView(this._component!);
370
516
  this._attachAnimatedStyles();
371
517
  }
372
518
 
373
- _setComponentRef = setAndForwardRef({
374
- getForwardedRef: () => this.props.forwardedRef,
519
+ _setComponentRef = setAndForwardRef<Component>({
520
+ getForwardedRef: () =>
521
+ this.props.forwardedRef as MutableRefObject<
522
+ Component<Record<string, unknown>, Record<string, unknown>, unknown>
523
+ >,
375
524
  setLocalRef: (ref) => {
376
525
  // TODO update config
377
526
  const tag = findNodeHandle(ref);
@@ -379,6 +528,9 @@ export default function createAnimatedComponent(Component, options = {}) {
379
528
  (this.props.layout || this.props.entering || this.props.exiting) &&
380
529
  tag != null
381
530
  ) {
531
+ if (!shouldBeUseWeb()) {
532
+ enableLayoutAnimations(true, false);
533
+ }
382
534
  let layout = this.props.layout ? this.props.layout : DefaultLayout;
383
535
  let entering = this.props.entering
384
536
  ? this.props.entering
@@ -387,16 +539,16 @@ export default function createAnimatedComponent(Component, options = {}) {
387
539
  ? this.props.exiting
388
540
  : DefaultExiting;
389
541
 
390
- if (layout.build) {
542
+ if (has('build', layout)) {
391
543
  layout = layout.build();
392
544
  }
393
545
 
394
- if (entering.build) {
395
- entering = entering.build();
546
+ if (has('build', entering)) {
547
+ entering = entering.build() as EntryExitAnimationFunction;
396
548
  }
397
549
 
398
- if (exiting.build) {
399
- exiting = exiting.build();
550
+ if (has('build', exiting)) {
551
+ exiting = exiting.build() as EntryExitAnimationFunction;
400
552
  }
401
553
 
402
554
  const config = {
@@ -414,25 +566,11 @@ export default function createAnimatedComponent(Component, options = {}) {
414
566
  if (ref !== this._component) {
415
567
  this._component = ref;
416
568
  }
417
-
418
- // TODO: Delete this after React Native also deletes this deprecation helper.
419
- if (ref != null && ref.getNode == null) {
420
- ref.getNode = () => {
421
- console.warn(
422
- '%s: Calling %s on the ref of an Animated component ' +
423
- 'is no longer necessary. You can now directly use the ref ' +
424
- 'instead. This method will be removed in a future release.',
425
- ref.constructor.name ?? '<<anonymous>>',
426
- 'getNode()'
427
- );
428
- return ref;
429
- };
430
- }
431
569
  },
432
570
  });
433
571
 
434
- _filterNonAnimatedStyle(inputStyle) {
435
- const style = {};
572
+ _filterNonAnimatedStyle(inputStyle: StyleProps) {
573
+ const style: StyleProps = {};
436
574
  for (const key in inputStyle) {
437
575
  const value = inputStyle[key];
438
576
  if (!hasAnimatedNodes(value)) {
@@ -446,17 +584,27 @@ export default function createAnimatedComponent(Component, options = {}) {
446
584
  return style;
447
585
  }
448
586
 
449
- _filterNonAnimatedProps(inputProps) {
450
- const props = {};
587
+ _filterNonAnimatedProps(
588
+ inputProps: AnimatedComponentProps<InitialComponentProps>
589
+ ): Record<string, unknown> {
590
+ const props: Record<string, unknown> = {};
451
591
  for (const key in inputProps) {
452
592
  const value = inputProps[key];
453
593
  if (key === 'style') {
454
- const styles = flattenArray(value);
455
- const processedStyle = styles.map((style) => {
594
+ const styleProp = inputProps.style;
595
+ const styles = flattenArray<StyleProps>(styleProp ?? []);
596
+ const processedStyle: StyleProps = styles.map((style) => {
456
597
  if (style && style.viewDescriptors) {
457
598
  // this is how we recognize styles returned by useAnimatedStyle
458
599
  style.viewsRef.add(this);
459
- return style.initial.value;
600
+ if (this._isFirstRender) {
601
+ return {
602
+ ...style.initial.value,
603
+ ...initialUpdaterRun<StyleProps>(style.initial.updater),
604
+ };
605
+ } else {
606
+ return style.initial.value;
607
+ }
460
608
  } else {
461
609
  return style;
462
610
  }
@@ -465,10 +613,15 @@ export default function createAnimatedComponent(Component, options = {}) {
465
613
  StyleSheet.flatten(processedStyle)
466
614
  );
467
615
  } else if (key === 'animatedProps') {
468
- Object.keys(value.initial.value).forEach((key) => {
469
- props[key] = value.initial.value[key];
470
- value.viewsRef.add(this);
471
- });
616
+ const animatedProp = inputProps.animatedProps as Partial<
617
+ AnimatedComponentProps<AnimatedProps>
618
+ >;
619
+ if (animatedProp.initial !== undefined) {
620
+ Object.keys(animatedProp.initial.value).forEach((key) => {
621
+ props[key] = animatedProp.initial?.value[key];
622
+ animatedProp.viewsRef?.add(this);
623
+ });
624
+ }
472
625
  } else if (value instanceof AnimatedEvent) {
473
626
  // we cannot filter out event listeners completely as some components
474
627
  // rely on having a callback registered in order to generate events
@@ -476,13 +629,15 @@ export default function createAnimatedComponent(Component, options = {}) {
476
629
  // native event dispatcher to hijack events.
477
630
  props[key] = dummyListener;
478
631
  } else if (
479
- value?.current &&
632
+ has('current', value) &&
480
633
  value.current instanceof WorkletEventHandler
481
634
  ) {
482
635
  if (value.current.eventNames.length > 0) {
483
636
  value.current.eventNames.forEach((eventName) => {
484
- props[eventName] = value.current.listeners
485
- ? value.current.listeners[eventName]
637
+ props[eventName] = has('listeners', value.current)
638
+ ? (value.current.listeners as Record<string, unknown>)[
639
+ eventName
640
+ ]
486
641
  : dummyListener;
487
642
  });
488
643
  } else {
@@ -495,7 +650,7 @@ export default function createAnimatedComponent(Component, options = {}) {
495
650
  } else if (value instanceof AnimatedValue) {
496
651
  // if any prop in animated component is set directly to the `Value` we set those props to the first value of `Value` node in order
497
652
  // to avoid default values for a short moment when `Value` is being asynchrounously sent via bridge and initialized in the native side.
498
- props[key] = value._startingValue;
653
+ props[key] = (value as AnimatedValue)._startingValue;
499
654
  }
500
655
  }
501
656
  return props;
@@ -507,6 +662,10 @@ export default function createAnimatedComponent(Component, options = {}) {
507
662
  props.animatedStyle = this.animatedStyle;
508
663
  }
509
664
 
665
+ if (this._isFirstRender) {
666
+ this._isFirstRender = false;
667
+ }
668
+
510
669
  const platformProps = Platform.select({
511
670
  web: {},
512
671
  default: { collapsable: false },
@@ -521,11 +680,11 @@ export default function createAnimatedComponent(Component, options = {}) {
521
680
  Component.displayName || Component.name || 'Component'
522
681
  })`;
523
682
 
524
- return React.forwardRef(function AnimatedComponentWrapper(props, ref) {
683
+ return React.forwardRef<Component>((props, ref) => {
525
684
  return (
526
685
  <AnimatedComponent
527
686
  {...props}
528
- {...(ref == null ? null : { forwardedRef: ref })}
687
+ {...(ref === null ? null : { forwardedRef: ref })}
529
688
  />
530
689
  );
531
690
  });