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
@@ -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);
@@ -16,6 +16,8 @@ import type {
16
16
  BlurEvent,
17
17
  FocusEvent,
18
18
  GestureResponderEvent,
19
+ KeyDownEvent,
20
+ KeyUpEvent,
19
21
  LayoutChangeEvent,
20
22
  LayoutRectangle,
21
23
  MouseEvent,
@@ -115,6 +117,13 @@ type FocusEventProps = $ReadOnly<{
115
117
  onFocusCapture?: ?(event: FocusEvent) => void,
116
118
  }>;
117
119
 
120
+ type KeyEventProps = $ReadOnly<{
121
+ onKeyDown?: ?(event: KeyDownEvent) => void,
122
+ onKeyDownCapture?: ?(event: KeyDownEvent) => void,
123
+ onKeyUp?: ?(event: KeyUpEvent) => void,
124
+ onKeyUpCapture?: ?(event: KeyUpEvent) => void,
125
+ }>;
126
+
118
127
  type TouchEventProps = $ReadOnly<{
119
128
  onTouchCancel?: ?(e: GestureResponderEvent) => void,
120
129
  onTouchCancelCapture?: ?(e: GestureResponderEvent) => void,
@@ -505,6 +514,7 @@ export type ViewProps = $ReadOnly<{
505
514
  ...MouseEventProps,
506
515
  ...PointerEventProps,
507
516
  ...FocusEventProps,
517
+ ...KeyEventProps,
508
518
  ...TouchEventProps,
509
519
  ...ViewPropsAndroid,
510
520
  ...ViewPropsIOS,
@@ -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-20251117-d52b9d2f8';
32
+ static prerelease: string | null = 'nightly-20251119-79b09ce9c';
33
33
 
34
34
  static getVersionString(): string {
35
35
  return `${this.major}.${this.minor}.${this.patch}${this.prerelease != null ? `-${this.prerelease}` : ''}`;
@@ -122,6 +122,18 @@ const bubblingEventTypes = {
122
122
  bubbled: 'onFocus',
123
123
  },
124
124
  },
125
+ topKeyDown: {
126
+ phasedRegistrationNames: {
127
+ captured: 'onKeyDownCapture',
128
+ bubbled: 'onKeyDown',
129
+ },
130
+ },
131
+ topKeyUp: {
132
+ phasedRegistrationNames: {
133
+ captured: 'onKeyUpCapture',
134
+ bubbled: 'onKeyUp',
135
+ },
136
+ },
125
137
  };
126
138
 
127
139
  const directEventTypes = {
@@ -322,3 +322,34 @@ export type MouseEvent = NativeSyntheticEvent<
322
322
  timestamp: number,
323
323
  }>,
324
324
  >;
325
+
326
+ export type KeyEvent = $ReadOnly<{
327
+ /**
328
+ * The actual key that was pressed. For example, F would be "f" or "F" depending on the shift key.
329
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
330
+ */
331
+ key: string,
332
+ /**
333
+ * The key code of the key that was pressed. For example, F would be "KeyF"
334
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code
335
+ */
336
+ code: string,
337
+ altKey: boolean,
338
+ ctrlKey: boolean,
339
+ metaKey: boolean,
340
+ shiftKey: boolean,
341
+ /**
342
+ * A boolean value that is true if the given key is being held down such that it is automatically repeating.
343
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat
344
+ */
345
+ repeat?: boolean,
346
+ /**
347
+ * Returns a boolean value indicating if the event is fired within a composition session
348
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent/isComposing
349
+ */
350
+ isComposing?: boolean,
351
+ }>;
352
+
353
+ export type KeyUpEvent = NativeSyntheticEvent<KeyEvent>;
354
+
355
+ export type KeyDownEvent = NativeSyntheticEvent<KeyEvent>;
@@ -24,7 +24,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(84),
26
26
  RCTVersionPatch: @(0),
27
- RCTVersionPrerelease: @"nightly-20251117-d52b9d2f8",
27
+ RCTVersionPrerelease: @"nightly-20251119-79b09ce9c",
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
  }
@@ -68,7 +68,7 @@ NSError *tryAndReturnError(const std::function<void()> &func)
68
68
  return nil;
69
69
  } @catch (NSException *exception) {
70
70
  return RCTErrorWithNSException(exception);
71
- } @catch (id exception) {
71
+ } @catch (id) {
72
72
  // This will catch any other ObjC exception, but no C++ exceptions
73
73
  return RCTErrorWithMessage(@"non-std ObjC Exception");
74
74
  }
@@ -75,6 +75,8 @@ static inline std::string toString(const ActivityIndicatorViewSize &value) {
75
75
  switch (value) {
76
76
  case ActivityIndicatorViewSize::Small: return "small";
77
77
  case ActivityIndicatorViewSize::Large: return "large";
78
+ default:
79
+ abort();
78
80
  }
79
81
  }
80
82
 
@@ -120,6 +122,8 @@ static inline std::string toString(const AndroidDrawerLayoutKeyboardDismissMode
120
122
  switch (value) {
121
123
  case AndroidDrawerLayoutKeyboardDismissMode::None: return "none";
122
124
  case AndroidDrawerLayoutKeyboardDismissMode::OnDrag: return "on-drag";
125
+ default:
126
+ abort();
123
127
  }
124
128
  }
125
129
 
@@ -141,6 +145,8 @@ static inline std::string toString(const AndroidDrawerLayoutDrawerPosition &valu
141
145
  switch (value) {
142
146
  case AndroidDrawerLayoutDrawerPosition::Left: return "left";
143
147
  case AndroidDrawerLayoutDrawerPosition::Right: return "right";
148
+ default:
149
+ abort();
144
150
  }
145
151
  }
146
152
 
@@ -164,6 +170,8 @@ static inline std::string toString(const AndroidDrawerLayoutDrawerLockMode &valu
164
170
  case AndroidDrawerLayoutDrawerLockMode::Unlocked: return "unlocked";
165
171
  case AndroidDrawerLayoutDrawerLockMode::LockedClosed: return "locked-closed";
166
172
  case AndroidDrawerLayoutDrawerLockMode::LockedOpen: return "locked-open";
173
+ default:
174
+ abort();
167
175
  }
168
176
  }
169
177
 
@@ -231,6 +239,8 @@ static inline std::string toString(const AndroidSwipeRefreshLayoutSize &value) {
231
239
  switch (value) {
232
240
  case AndroidSwipeRefreshLayoutSize::Default: return "default";
233
241
  case AndroidSwipeRefreshLayoutSize::Large: return "large";
242
+ default:
243
+ abort();
234
244
  }
235
245
  }
236
246
 
@@ -398,6 +408,8 @@ static inline std::string toString(const ModalHostViewAnimationType &value) {
398
408
  case ModalHostViewAnimationType::None: return "none";
399
409
  case ModalHostViewAnimationType::Slide: return "slide";
400
410
  case ModalHostViewAnimationType::Fade: return "fade";
411
+ default:
412
+ abort();
401
413
  }
402
414
  }
403
415
 
@@ -423,6 +435,8 @@ static inline std::string toString(const ModalHostViewPresentationStyle &value)
423
435
  case ModalHostViewPresentationStyle::PageSheet: return "pageSheet";
424
436
  case ModalHostViewPresentationStyle::FormSheet: return "formSheet";
425
437
  case ModalHostViewPresentationStyle::OverFullScreen: return "overFullScreen";
438
+ default:
439
+ abort();
426
440
  }
427
441
  }
428
442
 
@@ -296,7 +296,6 @@ public final class com/facebook/react/ReactInstanceManagerBuilder {
296
296
  public final fun addPackages (Ljava/util/List;)Lcom/facebook/react/ReactInstanceManagerBuilder;
297
297
  public final fun build ()Lcom/facebook/react/ReactInstanceManager;
298
298
  public final fun setApplication (Landroid/app/Application;)Lcom/facebook/react/ReactInstanceManagerBuilder;
299
- public final fun setBridgeIdleDebugListener (Lcom/facebook/react/bridge/NotThreadSafeBridgeIdleDebugListener;)Lcom/facebook/react/ReactInstanceManagerBuilder;
300
299
  public final fun setBundleAssetName (Ljava/lang/String;)Lcom/facebook/react/ReactInstanceManagerBuilder;
301
300
  public final fun setChoreographerProvider (Lcom/facebook/react/internal/ChoreographerProvider;)Lcom/facebook/react/ReactInstanceManagerBuilder;
302
301
  public final fun setCurrentActivity (Landroid/app/Activity;)Lcom/facebook/react/ReactInstanceManagerBuilder;
@@ -381,6 +380,7 @@ public class com/facebook/react/ReactRootView : android/widget/FrameLayout, com/
381
380
  public fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;)V
382
381
  public fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;I)V
383
382
  protected fun dispatchDraw (Landroid/graphics/Canvas;)V
383
+ protected fun dispatchJSKeyEvent (Landroid/view/KeyEvent;)V
384
384
  protected fun dispatchJSPointerEvent (Landroid/view/MotionEvent;Z)V
385
385
  protected fun dispatchJSTouchEvent (Landroid/view/MotionEvent;)V
386
386
  public fun dispatchKeyEvent (Landroid/view/KeyEvent;)Z
@@ -583,7 +583,6 @@ public abstract interface class com/facebook/react/bridge/Callback {
583
583
  }
584
584
 
585
585
  public abstract interface class com/facebook/react/bridge/CatalystInstance : com/facebook/react/bridge/JSBundleLoaderDelegate, com/facebook/react/bridge/JSInstance, com/facebook/react/bridge/MemoryPressureListener {
586
- public abstract fun addBridgeIdleDebugListener (Lcom/facebook/react/bridge/NotThreadSafeBridgeIdleDebugListener;)V
587
586
  public abstract fun callFunction (Ljava/lang/String;Ljava/lang/String;Lcom/facebook/react/bridge/NativeArray;)V
588
587
  public abstract fun destroy ()V
589
588
  public abstract fun extendNativeModules (Lcom/facebook/react/bridge/NativeModuleRegistry;)V
@@ -605,7 +604,6 @@ public abstract interface class com/facebook/react/bridge/CatalystInstance : com
605
604
  public abstract fun invokeCallback (ILcom/facebook/react/bridge/NativeArrayInterface;)V
606
605
  public abstract fun isDestroyed ()Z
607
606
  public abstract fun registerSegment (ILjava/lang/String;)V
608
- public abstract fun removeBridgeIdleDebugListener (Lcom/facebook/react/bridge/NotThreadSafeBridgeIdleDebugListener;)V
609
607
  public abstract fun runJSBundle ()V
610
608
  public abstract fun setFabricUIManager (Lcom/facebook/react/bridge/UIManager;)V
611
609
  public abstract fun setGlobalVariable (Ljava/lang/String;Ljava/lang/String;)V
@@ -613,7 +611,6 @@ public abstract interface class com/facebook/react/bridge/CatalystInstance : com
613
611
  }
614
612
 
615
613
  public class com/facebook/react/bridge/CatalystInstanceImpl : com/facebook/react/bridge/CatalystInstance {
616
- public fun addBridgeIdleDebugListener (Lcom/facebook/react/bridge/NotThreadSafeBridgeIdleDebugListener;)V
617
614
  public fun callFunction (Lcom/facebook/react/bridge/CatalystInstanceImpl$PendingJSCall;)V
618
615
  public fun callFunction (Ljava/lang/String;Ljava/lang/String;Lcom/facebook/react/bridge/NativeArray;)V
619
616
  public fun destroy ()V
@@ -641,7 +638,6 @@ public class com/facebook/react/bridge/CatalystInstanceImpl : com/facebook/react
641
638
  public fun loadScriptFromFile (Ljava/lang/String;Ljava/lang/String;Z)V
642
639
  public fun loadSplitBundleFromFile (Ljava/lang/String;Ljava/lang/String;)V
643
640
  public fun registerSegment (ILjava/lang/String;)V
644
- public fun removeBridgeIdleDebugListener (Lcom/facebook/react/bridge/NotThreadSafeBridgeIdleDebugListener;)V
645
641
  public fun runJSBundle ()V
646
642
  public fun setFabricUIManager (Lcom/facebook/react/bridge/UIManager;)V
647
643
  public fun setGlobalVariable (Ljava/lang/String;Ljava/lang/String;)V
@@ -970,12 +966,6 @@ public final class com/facebook/react/bridge/NoSuchKeyException : java/lang/Runt
970
966
  public fun <init> (Ljava/lang/String;)V
971
967
  }
972
968
 
973
- public abstract interface class com/facebook/react/bridge/NotThreadSafeBridgeIdleDebugListener {
974
- public abstract fun onBridgeDestroyed ()V
975
- public abstract fun onTransitionToBridgeBusy ()V
976
- public abstract fun onTransitionToBridgeIdle ()V
977
- }
978
-
979
969
  public abstract interface class com/facebook/react/bridge/PerformanceCounter {
980
970
  public abstract fun getPerformanceCounters ()Ljava/util/Map;
981
971
  public abstract fun profileNextBatch ()V
@@ -3132,6 +3122,7 @@ public final class com/facebook/react/runtime/ReactSurfaceView : com/facebook/re
3132
3122
  public fun isViewAttachedToReactInstance ()Z
3133
3123
  public fun onChildEndedNativeGesture (Landroid/view/View;Landroid/view/MotionEvent;)V
3134
3124
  public fun onChildStartedNativeGesture (Landroid/view/View;Landroid/view/MotionEvent;)V
3125
+ public fun requestChildFocus (Landroid/view/View;Landroid/view/View;)V
3135
3126
  public fun requestDisallowInterceptTouchEvent (Z)V
3136
3127
  public fun setIsFabric (Z)V
3137
3128
  }
@@ -4328,7 +4319,6 @@ public class com/facebook/react/uimanager/UIImplementation {
4328
4319
  public fun setJSResponder (IZ)V
4329
4320
  public fun setLayoutAnimationEnabledExperimental (Z)V
4330
4321
  public fun setLayoutUpdateListener (Lcom/facebook/react/uimanager/UIImplementation$LayoutUpdateListener;)V
4331
- public fun setViewHierarchyUpdateDebugListener (Lcom/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener;)V
4332
4322
  public fun setViewLocalData (ILjava/lang/Object;)V
4333
4323
  public fun synchronouslyUpdateViewOnUIThread (ILcom/facebook/react/uimanager/ReactStylesDiffMap;)V
4334
4324
  public fun updateInsetsPadding (IIIII)V
@@ -4412,7 +4402,6 @@ public class com/facebook/react/uimanager/UIManagerModule : com/facebook/react/b
4412
4402
  public fun setChildren (ILcom/facebook/react/bridge/ReadableArray;)V
4413
4403
  public fun setJSResponder (IZ)V
4414
4404
  public fun setLayoutAnimationEnabledExperimental (Z)V
4415
- public fun setViewHierarchyUpdateDebugListener (Lcom/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener;)V
4416
4405
  public fun setViewLocalData (ILjava/lang/Object;)V
4417
4406
  public fun startSurface (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/WritableMap;II)I
4418
4407
  public fun stopSurface (I)V
@@ -4460,7 +4449,6 @@ public class com/facebook/react/uimanager/UIViewOperationQueue {
4460
4449
  public fun isEmpty ()Z
4461
4450
  public fun prependUIBlock (Lcom/facebook/react/uimanager/UIBlock;)V
4462
4451
  public fun profileNextBatch ()V
4463
- public fun setViewHierarchyUpdateDebugListener (Lcom/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener;)V
4464
4452
  }
4465
4453
 
4466
4454
  public abstract interface class com/facebook/react/uimanager/UIViewOperationQueue$UIOperation {
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.84.0-nightly-20251117-d52b9d2f8
1
+ VERSION_NAME=0.84.0-nightly-20251119-79b09ce9c
2
2
  react.internal.publishingGroup=com.facebook.react
3
3
  react.internal.hermesPublishingGroup=com.facebook.hermes
4
4
 
@@ -57,7 +57,6 @@ import com.facebook.react.bridge.JSExceptionHandler;
57
57
  import com.facebook.react.bridge.JavaScriptExecutor;
58
58
  import com.facebook.react.bridge.JavaScriptExecutorFactory;
59
59
  import com.facebook.react.bridge.NativeModuleRegistry;
60
- import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener;
61
60
  import com.facebook.react.bridge.ReactApplicationContext;
62
61
  import com.facebook.react.bridge.ReactContext;
63
62
  import com.facebook.react.bridge.ReactCxxErrorHandler;
@@ -183,7 +182,6 @@ public class ReactInstanceManager {
183
182
  private final boolean mUseDeveloperSupport;
184
183
  private final boolean mRequireActivity;
185
184
  private final boolean mKeepActivity;
186
- private final @Nullable NotThreadSafeBridgeIdleDebugListener mBridgeIdleDebugListener;
187
185
  private final Object mReactContextLock = new Object();
188
186
  private @Nullable volatile ReactContext mCurrentReactContext;
189
187
  private final Context mApplicationContext;
@@ -246,7 +244,6 @@ public class ReactInstanceManager {
246
244
  DevSupportManagerFactory devSupportManagerFactory,
247
245
  boolean requireActivity,
248
246
  boolean keepActivity,
249
- @Nullable NotThreadSafeBridgeIdleDebugListener bridgeIdleDebugListener,
250
247
  LifecycleState initialLifecycleState,
251
248
  JSExceptionHandler jSExceptionHandler,
252
249
  @Nullable RedBoxHandler redBoxHandler,
@@ -292,7 +289,6 @@ public class ReactInstanceManager {
292
289
  devLoadingViewManager,
293
290
  pausedInDebuggerOverlayManager);
294
291
  Systrace.endSection(TRACE_TAG_REACT);
295
- mBridgeIdleDebugListener = bridgeIdleDebugListener;
296
292
  mLifecycleState = initialLifecycleState;
297
293
  mMemoryPressureRouter = new MemoryPressureRouter(applicationContext);
298
294
  mJSExceptionHandler = jSExceptionHandler;
@@ -1517,9 +1513,6 @@ public class ReactInstanceManager {
1517
1513
  catalystInstance.setFabricUIManager(uiManager);
1518
1514
  }
1519
1515
  }
1520
- if (mBridgeIdleDebugListener != null) {
1521
- catalystInstance.addBridgeIdleDebugListener(mBridgeIdleDebugListener);
1522
- }
1523
1516
  if (BuildConfig.ENABLE_PERFETTO || Systrace.isTracing(TRACE_TAG_REACT)) {
1524
1517
  catalystInstance.setGlobalVariable("__RCTProfileIsProfiling", "true");
1525
1518
  }
@@ -19,7 +19,6 @@ import com.facebook.react.ReactInstanceManager.initializeSoLoaderIfNecessary
19
19
  import com.facebook.react.bridge.JSBundleLoader
20
20
  import com.facebook.react.bridge.JSExceptionHandler
21
21
  import com.facebook.react.bridge.JavaScriptExecutorFactory
22
- import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener
23
22
  import com.facebook.react.bridge.UIManagerProvider
24
23
  import com.facebook.react.common.LifecycleState
25
24
  import com.facebook.react.common.SurfaceDelegateFactory
@@ -49,7 +48,6 @@ public class ReactInstanceManagerBuilder {
49
48
  private var jsBundleAssetUrl: String? = null
50
49
  private var jsBundleLoader: JSBundleLoader? = null
51
50
  private var jsMainModulePath: String? = null
52
- private var bridgeIdleDebugListener: NotThreadSafeBridgeIdleDebugListener? = null
53
51
  private var application: Application? = null
54
52
  private var useDeveloperSupport = false
55
53
  private var devSupportManagerFactory: DevSupportManagerFactory? = null
@@ -145,13 +143,6 @@ public class ReactInstanceManagerBuilder {
145
143
  return this
146
144
  }
147
145
 
148
- public fun setBridgeIdleDebugListener(
149
- bridgeIdleDebugListener: NotThreadSafeBridgeIdleDebugListener
150
- ): ReactInstanceManagerBuilder {
151
- this.bridgeIdleDebugListener = bridgeIdleDebugListener
152
- return this
153
- }
154
-
155
146
  /** Required. This must be your `Application` instance. */
156
147
  public fun setApplication(application: Application): ReactInstanceManagerBuilder {
157
148
  this.application = application
@@ -359,7 +350,6 @@ public class ReactInstanceManagerBuilder {
359
350
  devSupportManagerFactory ?: DefaultDevSupportManagerFactory(),
360
351
  requireActivity,
361
352
  keepActivity,
362
- bridgeIdleDebugListener,
363
353
  checkNotNull(initialLifecycleState) { "Initial lifecycle state was not set" },
364
354
  jsExceptionHandler,
365
355
  redBoxHandler,
@@ -57,6 +57,7 @@ import com.facebook.react.modules.appregistry.AppRegistry;
57
57
  import com.facebook.react.modules.deviceinfo.DeviceInfoModule;
58
58
  import com.facebook.react.uimanager.DisplayMetricsHolder;
59
59
  import com.facebook.react.uimanager.IllegalViewOperationException;
60
+ import com.facebook.react.uimanager.JSKeyDispatcher;
60
61
  import com.facebook.react.uimanager.JSPointerDispatcher;
61
62
  import com.facebook.react.uimanager.JSTouchDispatcher;
62
63
  import com.facebook.react.uimanager.PixelUtil;
@@ -105,6 +106,7 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
105
106
  private boolean mShouldLogContentAppeared;
106
107
  private @Nullable JSTouchDispatcher mJSTouchDispatcher;
107
108
  private @Nullable JSPointerDispatcher mJSPointerDispatcher;
109
+ private @Nullable JSKeyDispatcher mJSKeyDispatcher;
108
110
  private final ReactAndroidHWInputDeviceHelper mAndroidHWInputDeviceHelper =
109
111
  new ReactAndroidHWInputDeviceHelper();
110
112
  private boolean mWasMeasured = false;
@@ -333,10 +335,17 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
333
335
  FLog.w(TAG, "Unable to handle key event as the catalyst instance has not been attached");
334
336
  return super.dispatchKeyEvent(ev);
335
337
  }
338
+
336
339
  ReactContext context = getCurrentReactContext();
337
- if (context != null) {
338
- mAndroidHWInputDeviceHelper.handleKeyEvent(ev, context);
340
+ if (context == null) {
341
+ return super.dispatchKeyEvent(ev);
339
342
  }
343
+
344
+ mAndroidHWInputDeviceHelper.handleKeyEvent(ev, context);
345
+
346
+ // Dispatch during the capture phase before children handle the event as the focus could shift
347
+ dispatchJSKeyEvent(ev);
348
+
340
349
  return super.dispatchKeyEvent(ev);
341
350
  }
342
351
 
@@ -352,6 +361,17 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
352
361
  ReactContext context = getCurrentReactContext();
353
362
  if (context != null) {
354
363
  mAndroidHWInputDeviceHelper.clearFocus(context);
364
+
365
+ if (mJSKeyDispatcher != null && ReactNativeFeatureFlags.enableKeyEvents()) {
366
+ if (gainFocus) {
367
+ @Nullable View focusedChild = getFocusedChild();
368
+ if (focusedChild != null) {
369
+ mJSKeyDispatcher.setFocusedView(focusedChild.getId());
370
+ }
371
+ } else {
372
+ mJSKeyDispatcher.clearFocus();
373
+ }
374
+ }
355
375
  }
356
376
  super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
357
377
  }
@@ -369,6 +389,10 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
369
389
  ReactContext context = getCurrentReactContext();
370
390
  if (context != null) {
371
391
  mAndroidHWInputDeviceHelper.onFocusChanged(focused, context);
392
+
393
+ if (mJSKeyDispatcher != null && ReactNativeFeatureFlags.enableKeyEvents()) {
394
+ mJSKeyDispatcher.setFocusedView(focused.getId());
395
+ }
372
396
  }
373
397
  super.requestChildFocus(child, focused);
374
398
  }
@@ -410,6 +434,31 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
410
434
  }
411
435
  }
412
436
 
437
+ protected void dispatchJSKeyEvent(KeyEvent ev) {
438
+ if (!ReactNativeFeatureFlags.enableKeyEvents()) {
439
+ // Silently return early if key events are disabled
440
+ return;
441
+ }
442
+ if (!hasActiveReactContext() || !isViewAttachedToReactInstance()) {
443
+ FLog.w(
444
+ TAG, "Unable to dispatch key event to JS as the catalyst instance has not been attached");
445
+ return;
446
+ }
447
+ if (mJSKeyDispatcher == null) {
448
+ FLog.w(TAG, "Unable to dispatch key event to JS before the dispatcher is available");
449
+ return;
450
+ }
451
+ ReactContext context = getCurrentReactContext();
452
+ if (context != null) {
453
+ EventDispatcher eventDispatcher =
454
+ UIManagerHelper.getEventDispatcher(context, getUIManagerType());
455
+ int surfaceId = UIManagerHelper.getSurfaceId(context);
456
+ if (eventDispatcher != null) {
457
+ mJSKeyDispatcher.handleKeyEvent(ev, eventDispatcher, surfaceId);
458
+ }
459
+ }
460
+ }
461
+
413
462
  @Override
414
463
  public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
415
464
  // Override in order to still receive events to onInterceptTouchEvent even when some other
@@ -666,6 +715,10 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
666
715
  mJSPointerDispatcher = new JSPointerDispatcher(this);
667
716
  }
668
717
 
718
+ if (ReactNativeFeatureFlags.enableKeyEvents()) {
719
+ mJSKeyDispatcher = new JSKeyDispatcher();
720
+ }
721
+
669
722
  if (mRootViewEventListener != null) {
670
723
  mRootViewEventListener.onAttachedToReactInstance(this);
671
724
  }
@@ -744,6 +797,9 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
744
797
  if (ReactFeatureFlags.dispatchPointerEvents) {
745
798
  mJSPointerDispatcher = new JSPointerDispatcher(this);
746
799
  }
800
+ if (ReactNativeFeatureFlags.enableKeyEvents()) {
801
+ mJSKeyDispatcher = new JSKeyDispatcher();
802
+ }
747
803
  }
748
804
 
749
805
  @VisibleForTesting
@@ -75,24 +75,6 @@ public interface CatalystInstance : MemoryPressureListener, JSInstance, JSBundle
75
75
  */
76
76
  public fun extendNativeModules(modules: NativeModuleRegistry)
77
77
 
78
- /**
79
- * Adds a idle listener for this Catalyst instance. The listener will receive notifications
80
- * whenever the bridge transitions from idle to busy and vice-versa, where the busy state is
81
- * defined as there being some non-zero number of calls to JS that haven't resolved via a
82
- * onBatchCompleted call. The listener should be purely passive and not affect application logic.
83
- */
84
- public fun addBridgeIdleDebugListener(
85
- @Suppress("DEPRECATION") listener: NotThreadSafeBridgeIdleDebugListener
86
- )
87
-
88
- /**
89
- * Removes a NotThreadSafeBridgeIdleDebugListener previously added with
90
- * [addBridgeIdleDebugListener]
91
- */
92
- public fun removeBridgeIdleDebugListener(
93
- @Suppress("DEPRECATION") listener: NotThreadSafeBridgeIdleDebugListener
94
- )
95
-
96
78
  /** This method registers the file path of an additional JS segment by its ID. */
97
79
  public fun registerSegment(segmentId: Int, path: String)
98
80