react-native 0.84.0-nightly-20251116-d52b9d2f8 → 0.84.0-nightly-20251118-d314e5f4e

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 (24) hide show
  1. package/Libraries/Animated/createAnimatedComponent.js +2 -0
  2. package/Libraries/Animated/nodes/AnimatedInterpolation.js +40 -4
  3. package/Libraries/Animated/nodes/AnimatedValue.js +5 -2
  4. package/Libraries/Core/ReactNativeVersion.js +1 -1
  5. package/React/Base/RCTVersion.m +1 -1
  6. package/React/CoreModules/RCTExceptionsManager.mm +5 -2
  7. package/ReactAndroid/gradle.properties +1 -1
  8. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
  9. package/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp +98 -3
  10. package/ReactAndroid/src/main/res/devsupport/layout/fps_view.xml +1 -1
  11. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  12. package/ReactCommon/react/renderer/animated/AnimatedModule.cpp +85 -80
  13. package/ReactCommon/react/renderer/animated/AnimatedModule.h +2 -2
  14. package/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp +11 -0
  15. package/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.h +6 -0
  16. package/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.cpp +22 -2
  17. package/ReactCommon/react/renderer/animated/nodes/InterpolationAnimatedNode.cpp +74 -4
  18. package/ReactCommon/react/renderer/animated/nodes/InterpolationAnimatedNode.h +7 -0
  19. package/ReactCommon/react/renderer/animated/tests/AnimationTestsBase.h +2 -1
  20. package/package.json +8 -8
  21. package/src/private/animated/NativeAnimatedValidation.js +7 -4
  22. package/types_generated/Libraries/Animated/createAnimatedComponent.d.ts +3 -2
  23. package/types_generated/Libraries/Animated/nodes/AnimatedInterpolation.d.ts +5 -3
  24. package/types_generated/Libraries/Animated/nodes/AnimatedValue.d.ts +3 -3
@@ -8,6 +8,7 @@
8
8
  * @format
9
9
  */
10
10
 
11
+ import type {NativeColorValue} from '../StyleSheet/StyleSheetTypes';
11
12
  import type AnimatedAddition from './nodes/AnimatedAddition';
12
13
  import type AnimatedDiffClamp from './nodes/AnimatedDiffClamp';
13
14
  import type AnimatedDivision from './nodes/AnimatedDivision';
@@ -46,6 +47,7 @@ export type WithAnimatedValue<+T> = T extends Builtin | Nullable
46
47
  | AnimatedInterpolation<number | string>
47
48
  | AnimatedInterpolation<number>
48
49
  | AnimatedInterpolation<string>
50
+ | AnimatedInterpolation<NativeColorValue>
49
51
  : T extends $ReadOnlyArray<infer P>
50
52
  ? $ReadOnlyArray<WithAnimatedValue<P>>
51
53
  : T extends {...}
@@ -12,6 +12,7 @@
12
12
 
13
13
  'use strict';
14
14
 
15
+ import type {NativeColorValue} from '../../StyleSheet/StyleSheetTypes';
15
16
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
16
17
  import type AnimatedNode from './AnimatedNode';
17
18
  import type {AnimatedNodeConfig} from './AnimatedNode';
@@ -26,7 +27,14 @@ import invariant from 'invariant';
26
27
 
27
28
  type ExtrapolateType = 'extend' | 'identity' | 'clamp';
28
29
 
29
- export type InterpolationConfigType<OutputT: number | string> = $ReadOnly<{
30
+ export type InterpolationConfigSupportedOutputType =
31
+ | number
32
+ | string
33
+ | NativeColorValue;
34
+
35
+ export type InterpolationConfigType<
36
+ OutputT: InterpolationConfigSupportedOutputType,
37
+ > = $ReadOnly<{
30
38
  ...AnimatedNodeConfig,
31
39
  inputRange: $ReadOnlyArray<number>,
32
40
  outputRange: $ReadOnlyArray<OutputT>,
@@ -82,6 +90,28 @@ function createNumericInterpolation(
82
90
  };
83
91
  }
84
92
 
93
+ function createPlatformColorInterpolation(
94
+ config: InterpolationConfigType<NativeColorValue>,
95
+ ): (input: number) => NativeColorValue {
96
+ const outputRange = config.outputRange;
97
+ const outputRangeIndices = Array.from(Array(outputRange.length).keys());
98
+ const interpolateIndex = createNumericInterpolation({
99
+ ...config,
100
+ inputRange: config.inputRange,
101
+ outputRange: outputRangeIndices,
102
+ });
103
+
104
+ return input => {
105
+ const interpolateResult = interpolateIndex(input);
106
+ if (!Number.isInteger(interpolateResult)) {
107
+ console.warn(
108
+ 'PlatformColor interpolation should happen natively, here we fallback to the closest color',
109
+ );
110
+ }
111
+ return outputRange[Math.floor(interpolateResult)];
112
+ };
113
+ }
114
+
85
115
  function interpolate(
86
116
  input: number,
87
117
  inputMin: number,
@@ -277,7 +307,7 @@ function findRange(input: number, inputRange: $ReadOnlyArray<number>) {
277
307
  return i - 1;
278
308
  }
279
309
 
280
- function checkValidRanges<OutputT: number | string>(
310
+ function checkValidRanges<OutputT: InterpolationConfigSupportedOutputType>(
281
311
  inputRange: $ReadOnlyArray<number>,
282
312
  outputRange: $ReadOnlyArray<OutputT>,
283
313
  ) {
@@ -304,7 +334,7 @@ function checkValidInputRange(arr: $ReadOnlyArray<number>) {
304
334
  }
305
335
  }
306
336
 
307
- function checkInfiniteRange<OutputT: number | string>(
337
+ function checkInfiniteRange<OutputT: InterpolationConfigSupportedOutputType>(
308
338
  name: string,
309
339
  arr: $ReadOnlyArray<OutputT>,
310
340
  ) {
@@ -322,7 +352,7 @@ function checkInfiniteRange<OutputT: number | string>(
322
352
  }
323
353
 
324
354
  export default class AnimatedInterpolation<
325
- OutputT: number | string,
355
+ OutputT: InterpolationConfigSupportedOutputType,
326
356
  > extends AnimatedWithChildren {
327
357
  _parent: AnimatedNode;
328
358
  _config: InterpolationConfigType<OutputT>;
@@ -347,6 +377,10 @@ export default class AnimatedInterpolation<
347
377
  const config = this._config;
348
378
  if (config.outputRange && typeof config.outputRange[0] === 'string') {
349
379
  this._interpolation = (createStringInterpolation((config: any)): any);
380
+ } else if (typeof config.outputRange[0] === 'object') {
381
+ this._interpolation = (createPlatformColorInterpolation(
382
+ (config: any),
383
+ ): any);
350
384
  } else {
351
385
  this._interpolation = (createNumericInterpolation((config: any)): any);
352
386
  }
@@ -403,6 +437,8 @@ export default class AnimatedInterpolation<
403
437
  return NativeAnimatedHelper.transformDataType(value);
404
438
  }
405
439
  }): any);
440
+ } else if (typeof outputRange[0] === 'object') {
441
+ outputType = 'platform_color';
406
442
  }
407
443
 
408
444
  return {
@@ -12,7 +12,10 @@ import type {EventSubscription} from '../../vendor/emitter/EventEmitter';
12
12
  import type {PlatformConfig} from '../AnimatedPlatformConfig';
13
13
  import type Animation from '../animations/Animation';
14
14
  import type {EndCallback} from '../animations/Animation';
15
- import type {InterpolationConfigType} from './AnimatedInterpolation';
15
+ import type {
16
+ InterpolationConfigSupportedOutputType,
17
+ InterpolationConfigType,
18
+ } from './AnimatedInterpolation';
16
19
  import type AnimatedNode from './AnimatedNode';
17
20
  import type {AnimatedNodeConfig} from './AnimatedNode';
18
21
  import type AnimatedTracking from './AnimatedTracking';
@@ -298,7 +301,7 @@ export default class AnimatedValue extends AnimatedWithChildren {
298
301
  * Interpolates the value before updating the property, e.g. mapping 0-1 to
299
302
  * 0-10.
300
303
  */
301
- interpolate<OutputT: number | string>(
304
+ interpolate<OutputT: InterpolationConfigSupportedOutputType>(
302
305
  config: InterpolationConfigType<OutputT>,
303
306
  ): AnimatedInterpolation<OutputT> {
304
307
  return new AnimatedInterpolation(this, config);
@@ -29,7 +29,7 @@ export default class ReactNativeVersion {
29
29
  static major: number = 0;
30
30
  static minor: number = 84;
31
31
  static patch: number = 0;
32
- static prerelease: string | null = 'nightly-20251116-d52b9d2f8';
32
+ static prerelease: string | null = 'nightly-20251118-d314e5f4e';
33
33
 
34
34
  static getVersionString(): string {
35
35
  return `${this.major}.${this.minor}.${this.patch}${this.prerelease != null ? `-${this.prerelease}` : ''}`;
@@ -24,7 +24,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(84),
26
26
  RCTVersionPatch: @(0),
27
- RCTVersionPrerelease: @"nightly-20251116-d52b9d2f8",
27
+ RCTVersionPrerelease: @"nightly-20251118-d314e5f4e",
28
28
  };
29
29
  });
30
30
  return __rnVersion;
@@ -77,8 +77,11 @@ RCT_EXPORT_MODULE()
77
77
  RCTTriggerReloadCommandListeners(@"JS Crash Reload");
78
78
  } else if (!RCT_DEV) {
79
79
  NSString *description = [@"Unhandled JS Exception: " stringByAppendingString:message];
80
- NSDictionary *errorInfo =
81
- @{NSLocalizedDescriptionKey : description, RCTJSStackTraceKey : stack, RCTJSExtraDataKey : extraDataAsJSON};
80
+ NSDictionary *errorInfo = @{
81
+ NSLocalizedDescriptionKey : description,
82
+ RCTJSStackTraceKey : stack == nil ? (id)kCFNull : stack,
83
+ RCTJSExtraDataKey : extraDataAsJSON == nil ? (id)kCFNull : extraDataAsJSON
84
+ };
82
85
  RCTFatal([NSError errorWithDomain:RCTErrorDomain code:0 userInfo:errorInfo]);
83
86
  }
84
87
  }
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.84.0-nightly-20251116-d52b9d2f8
1
+ VERSION_NAME=0.84.0-nightly-20251118-d314e5f4e
2
2
  react.internal.publishingGroup=com.facebook.react
3
3
  react.internal.hermesPublishingGroup=com.facebook.hermes
4
4
 
@@ -15,6 +15,6 @@ public object ReactNativeVersion {
15
15
  "major" to 0,
16
16
  "minor" to 84,
17
17
  "patch" to 0,
18
- "prerelease" to "nightly-20251116-d52b9d2f8"
18
+ "prerelease" to "nightly-20251118-d314e5f4e"
19
19
  )
20
20
  }
@@ -24,9 +24,9 @@
24
24
  #include <fbjni/fbjni.h>
25
25
  #include <glog/logging.h>
26
26
 
27
+ #include <algorithm>
27
28
  #include <cfenv>
28
29
  #include <cmath>
29
- #include <unordered_set>
30
30
  #include <vector>
31
31
 
32
32
  namespace facebook::react {
@@ -54,6 +54,80 @@ void FabricMountingManager::onSurfaceStop(SurfaceId surfaceId) {
54
54
 
55
55
  namespace {
56
56
 
57
+ #ifdef REACT_NATIVE_DEBUG
58
+ // List of layout-only props extracted from ViewProps.kt used to filter out
59
+ // component props from Props 1.5 to validate the Props 2.0 output
60
+ inline bool isLayoutOnlyProp(const std::string& propName) {
61
+ static const std::vector<std::string> layoutOnlyProps = {
62
+ // Flexbox Alignment
63
+ "alignItems",
64
+ "alignSelf",
65
+ "alignContent",
66
+
67
+ // Flexbox Properties
68
+ "flex",
69
+ "flexBasis",
70
+ "flexDirection",
71
+ "flexGrow",
72
+ "flexShrink",
73
+ "flexWrap",
74
+ "justifyContent",
75
+
76
+ // Gaps
77
+ "rowGap",
78
+ "columnGap",
79
+ "gap",
80
+
81
+ // Display & Position
82
+ "display",
83
+ "position",
84
+
85
+ // Positioning
86
+ "right",
87
+ "top",
88
+ "bottom",
89
+ "left",
90
+ "start",
91
+ "end",
92
+
93
+ // Dimensions
94
+ "width",
95
+ "height",
96
+ "minWidth",
97
+ "maxWidth",
98
+ "minHeight",
99
+ "maxHeight",
100
+
101
+ // Margins
102
+ "margin",
103
+ "marginVertical",
104
+ "marginHorizontal",
105
+ "marginLeft",
106
+ "marginRight",
107
+ "marginTop",
108
+ "marginBottom",
109
+ "marginStart",
110
+ "marginEnd",
111
+
112
+ // Paddings
113
+ "padding",
114
+ "paddingVertical",
115
+ "paddingHorizontal",
116
+ "paddingLeft",
117
+ "paddingRight",
118
+ "paddingTop",
119
+ "paddingBottom",
120
+ "paddingStart",
121
+ "paddingEnd",
122
+
123
+ // Other
124
+ "collapsable",
125
+ };
126
+ return std::find(layoutOnlyProps.begin(), layoutOnlyProps.end(), propName) !=
127
+ layoutOnlyProps.end();
128
+ }
129
+ #endif
130
+
57
131
  inline int getIntBufferSizeForType(CppMountItem::Type mountItemType) {
58
132
  switch (mountItemType) {
59
133
  case CppMountItem::Type::Create:
@@ -232,8 +306,29 @@ jni::local_ref<jobject> getProps(
232
306
  strcmp(
233
307
  newShadowView.componentName,
234
308
  newProps->getDiffPropsImplementationTarget()) == 0) {
235
- return ReadableNativeMap::newObjectCxxArgs(
236
- newProps->getDiffProps(oldProps));
309
+ auto diff = newProps->getDiffProps(oldProps);
310
+
311
+ #ifdef REACT_NATIVE_DEBUG
312
+ if (oldProps != nullptr) {
313
+ auto controlDiff =
314
+ diffDynamicProps(oldProps->rawProps, newProps->rawProps);
315
+
316
+ for (const auto& [prop, value] : controlDiff.items()) {
317
+ if (diff.count(prop) == 0) {
318
+ // Skip layout-only props since they are not included in Props 2.0
319
+ if (!isLayoutOnlyProp(prop.asString())) {
320
+ LOG(ERROR) << "Props diff validation failed: Props 1.5 has prop '"
321
+ << prop.asString()
322
+ << "' = " << (value != nullptr ? value : "NULL")
323
+ << " that Props 2.0 doesn't have for component "
324
+ << newShadowView.componentName;
325
+ }
326
+ }
327
+ }
328
+ }
329
+ #endif
330
+
331
+ return ReadableNativeMap::newObjectCxxArgs(std::move(diff));
237
332
  }
238
333
  if (ReactNativeFeatureFlags::enableAccumulatedUpdatesInRawPropsAndroid()) {
239
334
  if (oldProps == nullptr) {
@@ -8,9 +8,9 @@
8
8
  android:layout_width="wrap_content"
9
9
  android:layout_height="wrap_content"
10
10
  android:layout_margin="3dp"
11
+ android:layout_gravity="top|right"
11
12
  android:background="#a4141823"
12
13
  android:gravity="right"
13
- android:layout_gravity="top|right"
14
14
  android:padding="3dp"
15
15
  android:textColor="@android:color/white"
16
16
  android:textSize="11sp"
@@ -22,7 +22,7 @@ constexpr struct {
22
22
  int32_t Major = 0;
23
23
  int32_t Minor = 84;
24
24
  int32_t Patch = 0;
25
- std::string_view Prerelease = "nightly-20251116-d52b9d2f8";
25
+ std::string_view Prerelease = "nightly-20251118-d314e5f4e";
26
26
  } ReactNativeVersion;
27
27
 
28
28
  } // namespace facebook::react
@@ -27,17 +27,18 @@ void AnimatedModule::finishOperationBatch(jsi::Runtime& /*rt*/) {
27
27
  std::swap(preOperations_, preOperations);
28
28
  std::swap(operations_, operations);
29
29
 
30
- if (nodesManager_) {
30
+ if (auto nodesManager = nodesManager_.lock()) {
31
31
  // TODO: nodesManager_ must exist at all times. But without this check
32
32
  // AnimatedProps-itest.js fails.
33
- nodesManager_->scheduleOnUI([this,
34
- preOperations = std::move(preOperations),
35
- operations = std::move(operations)]() {
33
+ nodesManager->scheduleOnUI([this,
34
+ preOperations = std::move(preOperations),
35
+ operations = std::move(operations),
36
+ nodesManager = nodesManager_]() {
36
37
  for (auto& preOperation : preOperations) {
37
- executeOperation(preOperation);
38
+ executeOperation(preOperation, nodesManager);
38
39
  }
39
40
  for (auto& operation : operations) {
40
- executeOperation(operation);
41
+ executeOperation(operation, nodesManager);
41
42
  }
42
43
  });
43
44
  }
@@ -50,8 +51,8 @@ void AnimatedModule::createAnimatedNode(
50
51
  auto configDynamic = dynamicFromValue(rt, jsi::Value(rt, config));
51
52
  if (auto it = configDynamic.find("disableBatchingForNativeCreate");
52
53
  it != configDynamic.items().end() && it->second == true) {
53
- if (nodesManager_) {
54
- nodesManager_->createAnimatedNodeAsync(tag, configDynamic);
54
+ if (auto nodesManager = nodesManager_.lock()) {
55
+ nodesManager->createAnimatedNodeAsync(tag, configDynamic);
55
56
  }
56
57
  } else {
57
58
  operations_.emplace_back(
@@ -220,79 +221,83 @@ void AnimatedModule::queueAndExecuteBatchedOperations(
220
221
  // TODO(T225953475): missing implementation
221
222
  }
222
223
 
223
- void AnimatedModule::executeOperation(const Operation& operation) {
224
- if (nodesManager_ == nullptr) {
225
- return;
226
- }
227
- std::visit(
228
- [&](const auto& op) {
229
- using T = std::decay_t<decltype(op)>;
230
-
231
- if constexpr (std::is_same_v<T, CreateAnimatedNodeOp>) {
232
- nodesManager_->createAnimatedNode(op.tag, op.config);
233
- } else if constexpr (std::is_same_v<T, GetValueOp>) {
234
- auto animValue = nodesManager_->getValue(op.tag);
235
- if (animValue) {
236
- op.callback.call(animValue.value());
224
+ void AnimatedModule::executeOperation(
225
+ const Operation& operation,
226
+ std::weak_ptr<NativeAnimatedNodesManager> nodesManagerWeak) {
227
+ if (auto nodesManager = nodesManagerWeak.lock()) {
228
+ std::visit(
229
+ [&](const auto& op) {
230
+ using T = std::decay_t<decltype(op)>;
231
+
232
+ if constexpr (std::is_same_v<T, CreateAnimatedNodeOp>) {
233
+ nodesManager->createAnimatedNode(op.tag, op.config);
234
+ } else if constexpr (std::is_same_v<T, GetValueOp>) {
235
+ auto animValue = nodesManager->getValue(op.tag);
236
+ if (animValue) {
237
+ op.callback.call(animValue.value());
238
+ }
239
+ } else if constexpr (std::is_same_v<
240
+ T,
241
+ StartListeningToAnimatedNodeValueOp>) {
242
+ nodesManager->startListeningToAnimatedNodeValue(
243
+ op.tag, [this, tag = op.tag](double value) {
244
+ emitDeviceEvent(
245
+ "onAnimatedValueUpdate",
246
+ [tag, value](
247
+ jsi::Runtime& rt, std::vector<jsi::Value>& args) {
248
+ auto arg = jsi::Object(rt);
249
+ arg.setProperty(rt, "tag", jsi::Value(tag));
250
+ arg.setProperty(rt, "value", jsi::Value(value));
251
+ args.emplace_back(rt, arg);
252
+ });
253
+ });
254
+ } else if constexpr (std::is_same_v<
255
+ T,
256
+ StopListeningToAnimatedNodeValueOp>) {
257
+ nodesManager->stopListeningToAnimatedNodeValue(op.tag);
258
+ } else if constexpr (std::is_same_v<T, ConnectAnimatedNodesOp>) {
259
+ nodesManager->connectAnimatedNodes(op.parentTag, op.childTag);
260
+ } else if constexpr (std::is_same_v<T, DisconnectAnimatedNodesOp>) {
261
+ nodesManager->disconnectAnimatedNodes(op.parentTag, op.childTag);
262
+ } else if constexpr (std::is_same_v<T, StartAnimatingNodeOp>) {
263
+ nodesManager->startAnimatingNode(
264
+ op.animationId,
265
+ op.nodeTag,
266
+ std::move(op.config),
267
+ std::move(op.endCallback));
268
+ } else if constexpr (std::is_same_v<T, StopAnimationOp>) {
269
+ nodesManager->stopAnimation(op.animationId, false);
270
+ } else if constexpr (std::is_same_v<T, SetAnimatedNodeValueOp>) {
271
+ nodesManager->setAnimatedNodeValue(op.nodeTag, op.value);
272
+ } else if constexpr (std::is_same_v<T, SetAnimatedNodeOffsetOp>) {
273
+ nodesManager->setAnimatedNodeOffset(op.nodeTag, op.offset);
274
+ } else if constexpr (std::is_same_v<T, FlattenAnimatedNodeOffsetOp>) {
275
+ nodesManager->flattenAnimatedNodeOffset(op.nodeTag);
276
+ } else if constexpr (std::is_same_v<T, ExtractAnimatedNodeOffsetOp>) {
277
+ nodesManager->extractAnimatedNodeOffsetOp(op.nodeTag);
278
+ } else if constexpr (std::is_same_v<T, ConnectAnimatedNodeToViewOp>) {
279
+ nodesManager->connectAnimatedNodeToView(op.nodeTag, op.viewTag);
280
+ } else if constexpr (std::is_same_v<
281
+ T,
282
+ DisconnectAnimatedNodeFromViewOp>) {
283
+ nodesManager->disconnectAnimatedNodeFromView(
284
+ op.nodeTag, op.viewTag);
285
+ } else if constexpr (std::is_same_v<T, RestoreDefaultValuesOp>) {
286
+ nodesManager->restoreDefaultValues(op.nodeTag);
287
+ } else if constexpr (std::is_same_v<T, DropAnimatedNodeOp>) {
288
+ nodesManager->dropAnimatedNode(op.tag);
289
+ } else if constexpr (std::is_same_v<T, AddAnimatedEventToViewOp>) {
290
+ nodesManager->addAnimatedEventToView(
291
+ op.viewTag, op.eventName, op.eventMapping);
292
+ } else if constexpr (std::is_same_v<
293
+ T,
294
+ RemoveAnimatedEventFromViewOp>) {
295
+ nodesManager->removeAnimatedEventFromView(
296
+ op.viewTag, op.eventName, op.animatedNodeTag);
237
297
  }
238
- } else if constexpr (std::is_same_v<
239
- T,
240
- StartListeningToAnimatedNodeValueOp>) {
241
- nodesManager_->startListeningToAnimatedNodeValue(
242
- op.tag, [this, tag = op.tag](double value) {
243
- emitDeviceEvent(
244
- "onAnimatedValueUpdate",
245
- [tag, value](
246
- jsi::Runtime& rt, std::vector<jsi::Value>& args) {
247
- auto arg = jsi::Object(rt);
248
- arg.setProperty(rt, "tag", jsi::Value(tag));
249
- arg.setProperty(rt, "value", jsi::Value(value));
250
- args.emplace_back(rt, arg);
251
- });
252
- });
253
- } else if constexpr (std::is_same_v<
254
- T,
255
- StopListeningToAnimatedNodeValueOp>) {
256
- nodesManager_->stopListeningToAnimatedNodeValue(op.tag);
257
- } else if constexpr (std::is_same_v<T, ConnectAnimatedNodesOp>) {
258
- nodesManager_->connectAnimatedNodes(op.parentTag, op.childTag);
259
- } else if constexpr (std::is_same_v<T, DisconnectAnimatedNodesOp>) {
260
- nodesManager_->disconnectAnimatedNodes(op.parentTag, op.childTag);
261
- } else if constexpr (std::is_same_v<T, StartAnimatingNodeOp>) {
262
- nodesManager_->startAnimatingNode(
263
- op.animationId,
264
- op.nodeTag,
265
- std::move(op.config),
266
- std::move(op.endCallback));
267
- } else if constexpr (std::is_same_v<T, StopAnimationOp>) {
268
- nodesManager_->stopAnimation(op.animationId, false);
269
- } else if constexpr (std::is_same_v<T, SetAnimatedNodeValueOp>) {
270
- nodesManager_->setAnimatedNodeValue(op.nodeTag, op.value);
271
- } else if constexpr (std::is_same_v<T, SetAnimatedNodeOffsetOp>) {
272
- nodesManager_->setAnimatedNodeOffset(op.nodeTag, op.offset);
273
- } else if constexpr (std::is_same_v<T, FlattenAnimatedNodeOffsetOp>) {
274
- nodesManager_->flattenAnimatedNodeOffset(op.nodeTag);
275
- } else if constexpr (std::is_same_v<T, ExtractAnimatedNodeOffsetOp>) {
276
- nodesManager_->extractAnimatedNodeOffsetOp(op.nodeTag);
277
- } else if constexpr (std::is_same_v<T, ConnectAnimatedNodeToViewOp>) {
278
- nodesManager_->connectAnimatedNodeToView(op.nodeTag, op.viewTag);
279
- } else if constexpr (std::is_same_v<
280
- T,
281
- DisconnectAnimatedNodeFromViewOp>) {
282
- nodesManager_->disconnectAnimatedNodeFromView(op.nodeTag, op.viewTag);
283
- } else if constexpr (std::is_same_v<T, RestoreDefaultValuesOp>) {
284
- nodesManager_->restoreDefaultValues(op.nodeTag);
285
- } else if constexpr (std::is_same_v<T, DropAnimatedNodeOp>) {
286
- nodesManager_->dropAnimatedNode(op.tag);
287
- } else if constexpr (std::is_same_v<T, AddAnimatedEventToViewOp>) {
288
- nodesManager_->addAnimatedEventToView(
289
- op.viewTag, op.eventName, op.eventMapping);
290
- } else if constexpr (std::is_same_v<T, RemoveAnimatedEventFromViewOp>) {
291
- nodesManager_->removeAnimatedEventFromView(
292
- op.viewTag, op.eventName, op.animatedNodeTag);
293
- }
294
- },
295
- operation);
298
+ },
299
+ operation);
300
+ }
296
301
  }
297
302
 
298
303
  void AnimatedModule::installJSIBindingsWithRuntime(jsi::Runtime& runtime) {
@@ -194,11 +194,11 @@ class AnimatedModule : public NativeAnimatedModuleCxxSpec<AnimatedModule>, publi
194
194
 
195
195
  private:
196
196
  std::shared_ptr<NativeAnimatedNodesManagerProvider> nodesManagerProvider_;
197
- std::shared_ptr<NativeAnimatedNodesManager> nodesManager_;
197
+ std::weak_ptr<NativeAnimatedNodesManager> nodesManager_;
198
198
  std::vector<Operation> preOperations_;
199
199
  std::vector<Operation> operations_;
200
200
 
201
- void executeOperation(const Operation &operation);
201
+ void executeOperation(const Operation &operation, std::weak_ptr<NativeAnimatedNodesManager> nodesManagerWeak);
202
202
  void installJSIBindingsWithRuntime(jsi::Runtime &runtime) override;
203
203
  };
204
204
 
@@ -73,11 +73,13 @@ thread_local bool NativeAnimatedNodesManager::isOnRenderThread_{false};
73
73
  NativeAnimatedNodesManager::NativeAnimatedNodesManager(
74
74
  DirectManipulationCallback&& directManipulationCallback,
75
75
  FabricCommitCallback&& fabricCommitCallback,
76
+ ResolvePlatformColor&& resolvePlatformColor,
76
77
  StartOnRenderCallback&& startOnRenderCallback,
77
78
  StopOnRenderCallback&& stopOnRenderCallback,
78
79
  FrameRateListenerCallback&& frameRateListenerCallback) noexcept
79
80
  : directManipulationCallback_(std::move(directManipulationCallback)),
80
81
  fabricCommitCallback_(std::move(fabricCommitCallback)),
82
+ resolvePlatformColor_(std::move(resolvePlatformColor)),
81
83
  startOnRenderCallback_(std::move(startOnRenderCallback)),
82
84
  stopOnRenderCallback_(std::move(stopOnRenderCallback)),
83
85
  frameRateListenerCallback_(std::move(frameRateListenerCallback)) {
@@ -847,6 +849,15 @@ bool NativeAnimatedNodesManager::isOnRenderThread() const noexcept {
847
849
  return isOnRenderThread_;
848
850
  }
849
851
 
852
+ void NativeAnimatedNodesManager::resolvePlatformColor(
853
+ SurfaceId surfaceId,
854
+ const RawValue& value,
855
+ SharedColor& result) const {
856
+ if (resolvePlatformColor_) {
857
+ resolvePlatformColor_(surfaceId, value, result);
858
+ }
859
+ }
860
+
850
861
  #pragma mark - Listeners
851
862
 
852
863
  void NativeAnimatedNodesManager::startListeningToAnimatedNodeValue(
@@ -58,10 +58,12 @@ class NativeAnimatedNodesManager {
58
58
  using StartOnRenderCallback = std::function<void(std::function<void()> &&, bool isAsync)>;
59
59
  using StopOnRenderCallback = std::function<void(bool isAsync)>;
60
60
  using FrameRateListenerCallback = std::function<void(bool /* shouldEnableListener */)>;
61
+ using ResolvePlatformColor = std::function<void(SurfaceId surfaceId, const RawValue &value, SharedColor &result)>;
61
62
 
62
63
  explicit NativeAnimatedNodesManager(
63
64
  DirectManipulationCallback &&directManipulationCallback,
64
65
  FabricCommitCallback &&fabricCommitCallback,
66
+ ResolvePlatformColor &&resolvePlatformColor,
65
67
  StartOnRenderCallback &&startOnRenderCallback = nullptr,
66
68
  StopOnRenderCallback &&stopOnRenderCallback = nullptr,
67
69
  FrameRateListenerCallback &&frameRateListenerCallback = nullptr) noexcept;
@@ -185,6 +187,8 @@ class NativeAnimatedNodesManager {
185
187
 
186
188
  bool isOnRenderThread() const noexcept;
187
189
 
190
+ void resolvePlatformColor(SurfaceId surfaceId, const RawValue &value, SharedColor &result) const;
191
+
188
192
  private:
189
193
  void stopRenderCallbackIfNeeded(bool isAsync) noexcept;
190
194
 
@@ -233,6 +237,8 @@ class NativeAnimatedNodesManager {
233
237
  const DirectManipulationCallback directManipulationCallback_;
234
238
  const FabricCommitCallback fabricCommitCallback_;
235
239
 
240
+ const ResolvePlatformColor resolvePlatformColor_;
241
+
236
242
  /*
237
243
  * Tracks whether the render callback loop for animations is currently active.
238
244
  */
@@ -14,6 +14,9 @@
14
14
  #ifdef RN_USE_ANIMATION_BACKEND
15
15
  #include <react/renderer/animationbackend/AnimationBackend.h>
16
16
  #endif
17
+ #include <react/renderer/animated/internal/primitives.h>
18
+ #include <react/renderer/components/view/conversions.h>
19
+ #include <react/renderer/scheduler/Scheduler.h>
17
20
  #include <react/renderer/uimanager/UIManagerBinding.h>
18
21
 
19
22
  namespace facebook::react {
@@ -70,6 +73,24 @@ NativeAnimatedNodesManagerProvider::getOrCreate(
70
73
  uiManager->synchronouslyUpdateViewOnUIThread(viewTag, props);
71
74
  };
72
75
 
76
+ // TODO: remove force casting.
77
+ auto* scheduler = (Scheduler*)uiManager->getDelegate();
78
+ auto resolvePlatformColor = [scheduler, uiManager](
79
+ SurfaceId surfaceId,
80
+ const RawValue& value,
81
+ SharedColor& result) {
82
+ if (uiManager) {
83
+ if (surfaceId != animated::undefinedAnimatedNodeIdentifier) {
84
+ PropsParserContext propsParserContext{
85
+ surfaceId, *scheduler->getContextContainer()};
86
+ fromRawValue(propsParserContext, value, result);
87
+ } else {
88
+ LOG(ERROR)
89
+ << "Cannot resolve platformColor because surfaceId is unavailable.";
90
+ }
91
+ }
92
+ };
93
+
73
94
  if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
74
95
  #ifdef RN_USE_ANIMATION_BACKEND
75
96
  // TODO: this should be initialized outside of animated, but for now it
@@ -95,6 +116,7 @@ NativeAnimatedNodesManagerProvider::getOrCreate(
95
116
  std::make_shared<NativeAnimatedNodesManager>(
96
117
  std::move(directManipulationCallback),
97
118
  std::move(fabricCommitCallback),
119
+ std::move(resolvePlatformColor),
98
120
  std::move(startOnRenderCallback_),
99
121
  std::move(stopOnRenderCallback_),
100
122
  std::move(frameRateListenerCallback_));
@@ -128,8 +150,6 @@ NativeAnimatedNodesManagerProvider::getOrCreate(
128
150
 
129
151
  uiManager->setNativeAnimatedDelegate(nativeAnimatedDelegate_);
130
152
 
131
- // TODO: remove force casting.
132
- auto* scheduler = (Scheduler*)uiManager->getDelegate();
133
153
  animatedMountingOverrideDelegate_ =
134
154
  std::make_shared<AnimatedMountingOverrideDelegate>(
135
155
  *nativeAnimatedNodesManager_, *scheduler);
@@ -29,13 +29,19 @@ InterpolationAnimatedNode::InterpolationAnimatedNode(
29
29
  inputRanges_.push_back(rangeValue.asDouble());
30
30
  }
31
31
 
32
- const bool isColorOutput = nodeConfig["outputType"].isString() &&
33
- nodeConfig["outputType"].asString() == "color";
34
- if (isColorOutput) {
32
+ const auto outputType = nodeConfig["outputType"].isString()
33
+ ? nodeConfig["outputType"].asString()
34
+ : "";
35
+ outputType_ = outputType;
36
+ if (outputType == "color") {
35
37
  isColorValue_ = true;
36
38
  for (const auto& rangeValue : nodeConfig["outputRange"]) {
37
39
  colorOutputRanges_.push_back(static_cast<int>(rangeValue.asInt()));
38
40
  }
41
+ } else if (outputType == "platform_color") {
42
+ for (const auto& rangeValue : nodeConfig["outputRange"]) {
43
+ platformColorOutputRanges_.push_back(rangeValue);
44
+ }
39
45
  } else {
40
46
  for (const auto& rangeValue : nodeConfig["outputRange"]) {
41
47
  defaultOutputRanges_.push_back(rangeValue.asDouble());
@@ -53,8 +59,10 @@ void InterpolationAnimatedNode::update() {
53
59
 
54
60
  if (const auto node =
55
61
  manager_->getAnimatedNode<ValueAnimatedNode>(parentTag_)) {
56
- if (isColorValue_) {
62
+ if (outputType_ == "color") {
57
63
  setRawValue(interpolateColor(node->getValue()));
64
+ } else if (outputType_ == "platform_color") {
65
+ setRawValue(interpolatePlatformColor(node->getValue()));
58
66
  } else {
59
67
  setRawValue(interpolateValue(node->getValue()));
60
68
  }
@@ -141,4 +149,66 @@ double InterpolationAnimatedNode::interpolateColor(double value) {
141
149
  static_cast<uint8_t>(outputValueA)));
142
150
  }
143
151
 
152
+ double InterpolationAnimatedNode::interpolatePlatformColor(double value) {
153
+ // Compute range index
154
+ size_t index = 1;
155
+ for (; index < inputRanges_.size() - 1; ++index) {
156
+ if (inputRanges_[index] >= value) {
157
+ break;
158
+ }
159
+ }
160
+ index--;
161
+ SharedColor outputMinSharedColor;
162
+ SharedColor outputMaxSharedColor;
163
+ if (manager_ != nullptr) {
164
+ manager_->resolvePlatformColor(
165
+ connectedRootTag_,
166
+ RawValue(platformColorOutputRanges_[index]),
167
+ outputMinSharedColor);
168
+ manager_->resolvePlatformColor(
169
+ connectedRootTag_,
170
+ RawValue(platformColorOutputRanges_[index + 1]),
171
+ outputMaxSharedColor);
172
+ }
173
+ auto outputMin = *outputMinSharedColor;
174
+ auto outputMax = *outputMaxSharedColor;
175
+
176
+ if (outputMin == outputMax) {
177
+ return outputMin;
178
+ }
179
+
180
+ const auto inputMin = inputRanges_[index];
181
+ const auto inputMax = inputRanges_[index + 1];
182
+ if (inputMin == inputMax) {
183
+ if (value <= inputMin) {
184
+ return static_cast<int32_t>(outputMin);
185
+ } else {
186
+ return static_cast<int32_t>(outputMax);
187
+ }
188
+ }
189
+
190
+ auto ratio = (value - inputMin) / (inputMax - inputMin);
191
+
192
+ auto outputMinA = alphaFromHostPlatformColor(outputMin);
193
+ auto outputMinR = redFromHostPlatformColor(outputMin);
194
+ auto outputMinG = greenFromHostPlatformColor(outputMin);
195
+ auto outputMinB = blueFromHostPlatformColor(outputMin);
196
+
197
+ auto outputMaxA = alphaFromHostPlatformColor(outputMax);
198
+ auto outputMaxR = redFromHostPlatformColor(outputMax);
199
+ auto outputMaxG = greenFromHostPlatformColor(outputMax);
200
+ auto outputMaxB = blueFromHostPlatformColor(outputMax);
201
+
202
+ auto outputValueA = ratio * (outputMaxA - outputMinA) + outputMinA;
203
+ auto outputValueR = ratio * (outputMaxR - outputMinR) + outputMinR;
204
+ auto outputValueG = ratio * (outputMaxG - outputMinG) + outputMinG;
205
+ auto outputValueB = ratio * (outputMaxB - outputMinB) + outputMinB;
206
+
207
+ return static_cast<int32_t>(hostPlatformColorFromRGBA(
208
+ static_cast<uint8_t>(outputValueR),
209
+ static_cast<uint8_t>(outputValueG),
210
+ static_cast<uint8_t>(outputValueB),
211
+ static_cast<uint8_t>(outputValueA)));
212
+ }
213
+
144
214
  } // namespace facebook::react
@@ -29,13 +29,20 @@ class InterpolationAnimatedNode final : public ValueAnimatedNode {
29
29
  private:
30
30
  double interpolateValue(double value);
31
31
  double interpolateColor(double value);
32
+ double interpolatePlatformColor(double value);
32
33
 
33
34
  std::vector<double> inputRanges_;
34
35
  std::vector<double> defaultOutputRanges_;
35
36
  std::vector<Color> colorOutputRanges_;
37
+ std::vector<folly::dynamic> platformColorOutputRanges_;
36
38
  std::string extrapolateLeft_;
37
39
  std::string extrapolateRight_;
38
40
 
41
+ std::string outputType_;
42
+
39
43
  Tag parentTag_{animated::undefinedAnimatedNodeIdentifier};
44
+
45
+ // Needed for PlatformColor resolver
46
+ SurfaceId connectedRootTag_{animated::undefinedAnimatedNodeIdentifier};
40
47
  };
41
48
  } // namespace facebook::react
@@ -35,7 +35,8 @@ class AnimationTestsBase : public testing::Test {
35
35
  lastUpdatedNodeTag = nodesProps.begin()->first;
36
36
  lastCommittedProps = nodesProps.begin()->second;
37
37
  }
38
- });
38
+ },
39
+ nullptr);
39
40
  NativeAnimatedNodesManager::isOnRenderThread_ = true;
40
41
  }
41
42
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native",
3
- "version": "0.84.0-nightly-20251116-d52b9d2f8",
3
+ "version": "0.84.0-nightly-20251118-d314e5f4e",
4
4
  "description": "A framework for building native apps using React",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -160,13 +160,13 @@
160
160
  },
161
161
  "dependencies": {
162
162
  "@jest/create-cache-key-function": "^29.7.0",
163
- "@react-native/assets-registry": "0.84.0-nightly-20251116-d52b9d2f8",
164
- "@react-native/codegen": "0.84.0-nightly-20251116-d52b9d2f8",
165
- "@react-native/community-cli-plugin": "0.84.0-nightly-20251116-d52b9d2f8",
166
- "@react-native/gradle-plugin": "0.84.0-nightly-20251116-d52b9d2f8",
167
- "@react-native/js-polyfills": "0.84.0-nightly-20251116-d52b9d2f8",
168
- "@react-native/normalize-colors": "0.84.0-nightly-20251116-d52b9d2f8",
169
- "@react-native/virtualized-lists": "0.84.0-nightly-20251116-d52b9d2f8",
163
+ "@react-native/assets-registry": "0.84.0-nightly-20251118-d314e5f4e",
164
+ "@react-native/codegen": "0.84.0-nightly-20251118-d314e5f4e",
165
+ "@react-native/community-cli-plugin": "0.84.0-nightly-20251118-d314e5f4e",
166
+ "@react-native/gradle-plugin": "0.84.0-nightly-20251118-d314e5f4e",
167
+ "@react-native/js-polyfills": "0.84.0-nightly-20251118-d314e5f4e",
168
+ "@react-native/normalize-colors": "0.84.0-nightly-20251118-d314e5f4e",
169
+ "@react-native/virtualized-lists": "0.84.0-nightly-20251118-d314e5f4e",
170
170
  "abort-controller": "^3.0.0",
171
171
  "anser": "^1.4.9",
172
172
  "ansi-regex": "^5.0.0",
@@ -8,7 +8,10 @@
8
8
  * @format
9
9
  */
10
10
 
11
- import type {InterpolationConfigType} from '../../../Libraries/Animated/nodes/AnimatedInterpolation';
11
+ import type {
12
+ InterpolationConfigSupportedOutputType,
13
+ InterpolationConfigType,
14
+ } from '../../../Libraries/Animated/nodes/AnimatedInterpolation';
12
15
 
13
16
  import {
14
17
  isSupportedInterpolationParam,
@@ -16,9 +19,9 @@ import {
16
19
  isSupportedTransformProp,
17
20
  } from '../../../Libraries/Animated/NativeAnimatedAllowlist';
18
21
 
19
- export function validateInterpolation<OutputT: number | string>(
20
- config: InterpolationConfigType<OutputT>,
21
- ): void {
22
+ export function validateInterpolation<
23
+ OutputT: InterpolationConfigSupportedOutputType,
24
+ >(config: InterpolationConfigType<OutputT>): void {
22
25
  for (const key in config) {
23
26
  if (key !== 'debugID' && !isSupportedInterpolationParam(key)) {
24
27
  console.error(
@@ -4,12 +4,13 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @generated SignedSource<<008486b075d25ce1531e33736e20f9f9>>
7
+ * @generated SignedSource<<e8e5c16b1838a7cb9e45118d291d537a>>
8
8
  *
9
9
  * This file was translated from Flow by scripts/js-api/build-types/index.js.
10
10
  * Original file: packages/react-native/Libraries/Animated/createAnimatedComponent.js
11
11
  */
12
12
 
13
+ import type { NativeColorValue } from "../StyleSheet/StyleSheetTypes";
13
14
  import type AnimatedAddition from "./nodes/AnimatedAddition";
14
15
  import type AnimatedDiffClamp from "./nodes/AnimatedDiffClamp";
15
16
  import type AnimatedDivision from "./nodes/AnimatedDivision";
@@ -25,7 +26,7 @@ import * as React from "react";
25
26
  type Nullable = void | null;
26
27
  type Primitive = string | number | boolean | symbol | void;
27
28
  type Builtin = (...$$REST$$: ReadonlyArray<never>) => unknown | Date | Error | RegExp;
28
- export type WithAnimatedValue<T> = T extends Builtin | Nullable ? T : T extends Primitive ? T | AnimatedNode | AnimatedAddition | AnimatedSubtraction | AnimatedDivision | AnimatedMultiplication | AnimatedModulo | AnimatedDiffClamp | AnimatedValue | AnimatedInterpolation<number | string> | AnimatedInterpolation<number> | AnimatedInterpolation<string> : T extends ReadonlyArray<infer P> ? ReadonlyArray<WithAnimatedValue<P>> : T extends {} ? { readonly [K in keyof T]: WithAnimatedValue<T[K]> } : T;
29
+ export type WithAnimatedValue<T> = T extends Builtin | Nullable ? T : T extends Primitive ? T | AnimatedNode | AnimatedAddition | AnimatedSubtraction | AnimatedDivision | AnimatedMultiplication | AnimatedModulo | AnimatedDiffClamp | AnimatedValue | AnimatedInterpolation<number | string> | AnimatedInterpolation<number> | AnimatedInterpolation<string> | AnimatedInterpolation<NativeColorValue> : T extends ReadonlyArray<infer P> ? ReadonlyArray<WithAnimatedValue<P>> : T extends {} ? { readonly [K in keyof T]: WithAnimatedValue<T[K]> } : T;
29
30
  type NonAnimatedProps = "ref" | "innerViewRef" | "scrollViewRef" | "testID" | "disabled" | "accessibilityLabel";
30
31
  type PassThroughProps = Readonly<{
31
32
  passthroughAnimatedPropExplicitValues?: ViewProps | null;
@@ -4,17 +4,19 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @generated SignedSource<<8004cbd7a5bde7225d523c5cf91c7139>>
7
+ * @generated SignedSource<<b3b35ccf34137c8b1fafd02a35fcd5df>>
8
8
  *
9
9
  * This file was translated from Flow by scripts/js-api/build-types/index.js.
10
10
  * Original file: packages/react-native/Libraries/Animated/nodes/AnimatedInterpolation.js
11
11
  */
12
12
 
13
+ import type { NativeColorValue } from "../../StyleSheet/StyleSheetTypes";
13
14
  import type AnimatedNode from "./AnimatedNode";
14
15
  import type { AnimatedNodeConfig } from "./AnimatedNode";
15
16
  import AnimatedWithChildren from "./AnimatedWithChildren";
16
17
  type ExtrapolateType = "extend" | "identity" | "clamp";
17
- export type InterpolationConfigType<OutputT extends number | string> = Readonly<Omit<AnimatedNodeConfig, keyof {
18
+ export type InterpolationConfigSupportedOutputType = number | string | NativeColorValue;
19
+ export type InterpolationConfigType<OutputT extends InterpolationConfigSupportedOutputType> = Readonly<Omit<AnimatedNodeConfig, keyof {
18
20
  inputRange: ReadonlyArray<number>;
19
21
  outputRange: ReadonlyArray<OutputT>;
20
22
  easing?: (input: number) => number;
@@ -29,7 +31,7 @@ export type InterpolationConfigType<OutputT extends number | string> = Readonly<
29
31
  extrapolateLeft?: ExtrapolateType;
30
32
  extrapolateRight?: ExtrapolateType;
31
33
  }>;
32
- declare class AnimatedInterpolation<OutputT extends number | string> extends AnimatedWithChildren {
34
+ declare class AnimatedInterpolation<OutputT extends InterpolationConfigSupportedOutputType> extends AnimatedWithChildren {
33
35
  constructor(parent: AnimatedNode, config: InterpolationConfigType<OutputT>);
34
36
  interpolate<NewOutputT extends number | string>(config: InterpolationConfigType<NewOutputT>): AnimatedInterpolation<NewOutputT>;
35
37
  }
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @generated SignedSource<<6fab0eee6ece82d62f97bc6a633c866a>>
7
+ * @generated SignedSource<<86c68bbde8f6c0e6e87b258087714ffc>>
8
8
  *
9
9
  * This file was translated from Flow by scripts/js-api/build-types/index.js.
10
10
  * Original file: packages/react-native/Libraries/Animated/nodes/AnimatedValue.js
@@ -12,7 +12,7 @@
12
12
 
13
13
  import type Animation from "../animations/Animation";
14
14
  import type { EndCallback } from "../animations/Animation";
15
- import type { InterpolationConfigType } from "./AnimatedInterpolation";
15
+ import type { InterpolationConfigSupportedOutputType, InterpolationConfigType } from "./AnimatedInterpolation";
16
16
  import type AnimatedNode from "./AnimatedNode";
17
17
  import type { AnimatedNodeConfig } from "./AnimatedNode";
18
18
  import type AnimatedTracking from "./AnimatedTracking";
@@ -106,7 +106,7 @@ declare class AnimatedValue extends AnimatedWithChildren {
106
106
  * Interpolates the value before updating the property, e.g. mapping 0-1 to
107
107
  * 0-10.
108
108
  */
109
- interpolate<OutputT extends number | string>(config: InterpolationConfigType<OutputT>): AnimatedInterpolation<OutputT>;
109
+ interpolate<OutputT extends InterpolationConfigSupportedOutputType>(config: InterpolationConfigType<OutputT>): AnimatedInterpolation<OutputT>;
110
110
  /**
111
111
  * Typically only used internally, but could be used by a custom Animation
112
112
  * class.