react-native 0.84.0-nightly-20251117-d52b9d2f8 → 0.84.0-nightly-20251119-79b09ce9c

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 (58) 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/Components/View/ViewPropTypes.js +10 -0
  5. package/Libraries/Core/ReactNativeVersion.js +1 -1
  6. package/Libraries/NativeComponent/BaseViewConfig.android.js +12 -0
  7. package/Libraries/Types/CoreEventTypes.js +31 -0
  8. package/React/Base/RCTVersion.m +1 -1
  9. package/React/CoreModules/RCTExceptionsManager.mm +5 -2
  10. package/React/CxxModule/RCTCxxUtils.mm +1 -1
  11. package/React/FBReactNativeSpec/react/renderer/components/FBReactNativeSpec/Props.h +14 -0
  12. package/ReactAndroid/api/ReactAndroid.api +2 -14
  13. package/ReactAndroid/gradle.properties +1 -1
  14. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +0 -7
  15. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.kt +0 -10
  16. package/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +58 -2
  17. package/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.kt +0 -18
  18. package/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +0 -54
  19. package/ReactAndroid/src/main/java/com/facebook/react/modules/debug/FpsDebugFrameCallback.kt +3 -27
  20. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
  21. package/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt +0 -9
  22. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactSurfaceView.kt +52 -0
  23. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +10 -0
  24. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSKeyDispatcher.kt +65 -0
  25. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java +0 -8
  26. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +0 -8
  27. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +0 -16
  28. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/KeyDownEvent.kt +23 -0
  29. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/KeyEvent.kt +156 -0
  30. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/KeyUpEvent.kt +24 -0
  31. package/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp +98 -3
  32. package/ReactAndroid/src/main/jni/react/tracing/PerformanceTracerCxxInterop.cpp +1 -1
  33. package/ReactAndroid/src/main/res/devsupport/layout/fps_view.xml +1 -1
  34. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  35. package/ReactCommon/jsi/jsi/test/testlib.cpp +2 -2
  36. package/ReactCommon/react/renderer/animated/AnimatedModule.cpp +85 -80
  37. package/ReactCommon/react/renderer/animated/AnimatedModule.h +2 -2
  38. package/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp +11 -0
  39. package/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.h +6 -0
  40. package/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.cpp +22 -2
  41. package/ReactCommon/react/renderer/animated/nodes/InterpolationAnimatedNode.cpp +74 -4
  42. package/ReactCommon/react/renderer/animated/nodes/InterpolationAnimatedNode.h +7 -0
  43. package/ReactCommon/react/renderer/animated/tests/AnimationTestsBase.h +2 -1
  44. package/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp +1 -1
  45. package/ReactCommon/react/runtime/ReactInstance.cpp +1 -1
  46. package/index.js.flow +3 -0
  47. package/package.json +9 -9
  48. package/sdks/hermes-engine/version.properties +1 -1
  49. package/src/private/animated/NativeAnimatedValidation.js +7 -4
  50. package/types_generated/Libraries/Animated/createAnimatedComponent.d.ts +3 -2
  51. package/types_generated/Libraries/Animated/nodes/AnimatedInterpolation.d.ts +5 -3
  52. package/types_generated/Libraries/Animated/nodes/AnimatedValue.d.ts +3 -3
  53. package/types_generated/Libraries/Components/View/ViewPropTypes.d.ts +9 -3
  54. package/types_generated/Libraries/Types/CoreEventTypes.d.ts +29 -1
  55. package/types_generated/index.d.ts +2 -2
  56. package/ReactAndroid/src/main/java/com/facebook/react/bridge/NotThreadSafeBridgeIdleDebugListener.kt +0 -36
  57. package/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DidJSUpdateUiDuringFrameDetector.kt +0 -157
  58. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener.kt +0 -30
@@ -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) {
@@ -200,7 +200,7 @@ jint PerformanceTracerCxxInterop::subscribeToTracingStateChanges(
200
200
  onTracingStateChangedMethod(
201
201
  callback, static_cast<jboolean>(isTracing));
202
202
  });
203
- } catch (const std::exception& e) {
203
+ } catch (const std::exception&) {
204
204
  }
205
205
  }
206
206
  });
@@ -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-20251117-d52b9d2f8";
25
+ std::string_view Prerelease = "nightly-20251119-79b09ce9c";
26
26
  } ReactNativeVersion;
27
27
 
28
28
  } // namespace facebook::react
@@ -1455,7 +1455,7 @@ TEST_P(JSITest, MicrotasksTest) {
1455
1455
  EXPECT_EQ(
1456
1456
  rt.global().getProperty(rt, "globalValue").asString(rt).utf8(rt),
1457
1457
  "hello world");
1458
- } catch (const JSINativeException& ex) {
1458
+ } catch (const JSINativeException&) {
1459
1459
  // queueMicrotask() is unimplemented by some runtimes, ignore such failures.
1460
1460
  }
1461
1461
  }
@@ -1550,7 +1550,7 @@ TEST_P(JSITest, ArrayBufferSizeTest) {
1550
1550
  try {
1551
1551
  // Ensure we can safely write some data to the buffer.
1552
1552
  memset(ab.data(rt), 0xab, 10);
1553
- } catch (const JSINativeException& ex) {
1553
+ } catch (const JSINativeException&) {
1554
1554
  // data() is unimplemented by some runtimes, ignore such failures.
1555
1555
  }
1556
1556
 
@@ -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
 
@@ -936,7 +936,7 @@ folly::dynamic HostPlatformViewProps::getDiffProps(
936
936
 
937
937
  if (accessibilityState != oldProps->accessibilityState) {
938
938
  updateAccessibilityStateProp(
939
- result, oldProps->accessibilityState, accessibilityState);
939
+ result, accessibilityState, oldProps->accessibilityState);
940
940
  }
941
941
 
942
942
  if (accessibilityLabel != oldProps->accessibilityLabel) {
@@ -95,7 +95,7 @@ ReactInstance::ReactInstance(
95
95
  jsErrorHandler->handleError(jsiRuntime, originalError, true);
96
96
  } catch (std::exception& ex) {
97
97
  jsi::JSError error(
98
- jsiRuntime, std::string("Non-js exception: ") + ex.what());
98
+ jsiRuntime, std::string("Non-JS exception: ") + ex.what());
99
99
  jsErrorHandler->handleError(jsiRuntime, error, true);
100
100
  }
101
101
  });
package/index.js.flow CHANGED
@@ -420,6 +420,9 @@ export type {
420
420
  BlurEvent,
421
421
  FocusEvent,
422
422
  GestureResponderEvent,
423
+ KeyDownEvent,
424
+ KeyEvent,
425
+ KeyUpEvent,
423
426
  LayoutChangeEvent,
424
427
  LayoutRectangle,
425
428
  MouseEvent,