react-native 0.72.0-rc.0 → 0.72.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/Libraries/Components/View/ReactNativeStyleAttributes.js +0 -7
  2. package/Libraries/Core/ReactNativeVersion.js +1 -1
  3. package/Libraries/Core/ReactNativeVersionCheck.js +5 -1
  4. package/Libraries/NativeComponent/BaseViewConfig.android.js +0 -8
  5. package/Libraries/NativeComponent/BaseViewConfig.ios.js +0 -8
  6. package/Libraries/ReactNative/UIManager.js +27 -1
  7. package/Libraries/Renderer/implementations/ReactFabric-dev.js +26 -3
  8. package/Libraries/Renderer/implementations/ReactFabric-prod.js +13 -1
  9. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +13 -1
  10. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +0 -7
  11. package/Libraries/StyleSheet/StyleSheetTypes.js +0 -74
  12. package/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.m +3 -3
  13. package/React/Base/RCTVersion.m +1 -1
  14. package/React/CoreModules/RCTDevMenu.mm +3 -3
  15. package/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropCoordinatorAdapter.mm +1 -1
  16. package/ReactAndroid/gradle.properties +1 -1
  17. package/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java +40 -1
  18. package/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java +22 -7
  19. package/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +10 -0
  20. package/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +29 -0
  21. package/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManagerListener.java +25 -2
  22. package/ReactAndroid/src/main/java/com/facebook/react/bridge/interop/InteropModuleRegistry.java +56 -0
  23. package/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +11 -0
  24. package/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultNewArchitectureEntryPoint.kt +1 -0
  25. package/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactActivityDelegate.kt +4 -0
  26. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +26 -8
  27. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +21 -0
  28. package/ReactAndroid/src/main/java/com/facebook/react/fabric/interop/InteropEvent.java +41 -0
  29. package/ReactAndroid/src/main/java/com/facebook/react/fabric/interop/InteropEventEmitter.java +65 -0
  30. package/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java +9 -0
  31. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
  32. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java +1 -0
  33. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java +32 -0
  34. package/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java +19 -0
  35. package/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLetterSpacingSpan.java +4 -0
  36. package/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java +4 -0
  37. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java +1 -5
  38. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +190 -134
  39. package/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +23 -10
  40. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java +5 -0
  41. package/ReactAndroid/src/main/jni/react/fabric/Binding.cpp +3 -0
  42. package/ReactCommon/React-rncore.podspec +12 -4
  43. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  44. package/ReactCommon/react/config/ReactNativeConfig.cpp +3 -0
  45. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.h +4 -1
  46. package/ReactCommon/react/renderer/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm +49 -2
  47. package/ReactCommon/react/renderer/components/text/ParagraphLayoutManager.cpp +30 -5
  48. package/ReactCommon/react/renderer/components/text/ParagraphLayoutManager.h +12 -0
  49. package/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +0 -21
  50. package/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +0 -49
  51. package/ReactCommon/react/renderer/components/view/YogaStylableProps.h +0 -9
  52. package/ReactCommon/react/renderer/core/CoreFeatures.cpp +1 -0
  53. package/ReactCommon/react/renderer/core/CoreFeatures.h +5 -0
  54. package/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp +5 -1
  55. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm +112 -83
  56. package/build.gradle.kts +17 -0
  57. package/gradle.properties +1 -0
  58. package/package.json +8 -8
  59. package/scripts/cocoapods/__tests__/codegen_utils-test.rb +9 -1
  60. package/scripts/cocoapods/__tests__/jsengine-test.rb +6 -2
  61. package/scripts/cocoapods/__tests__/test_utils/podSpy.rb +2 -1
  62. package/scripts/cocoapods/codegen_utils.rb +1 -1
  63. package/scripts/cocoapods/jsengine.rb +6 -1
  64. package/sdks/hermesc/linux64-bin/hermesc +0 -0
  65. package/sdks/hermesc/osx-bin/hermesc +0 -0
  66. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  67. package/settings.gradle.kts +30 -0
  68. package/template/android/app/build.gradle +7 -2
  69. package/template/metro.config.js +7 -13
  70. package/template/package.json +5 -3
  71. package/types/index.d.ts +4 -0
@@ -46,13 +46,6 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
46
46
  flexWrap: true,
47
47
  gap: true,
48
48
  height: true,
49
- inset: true,
50
- insetBlock: true,
51
- insetBlockEnd: true,
52
- insetBlockStart: true,
53
- insetInline: true,
54
- insetInlineEnd: true,
55
- insetInlineStart: true,
56
49
  justifyContent: true,
57
50
  left: true,
58
51
  margin: true,
@@ -13,5 +13,5 @@ exports.version = {
13
13
  major: 0,
14
14
  minor: 72,
15
15
  patch: 0,
16
- prerelease: 'rc.0',
16
+ prerelease: 'rc.2',
17
17
  };
@@ -39,8 +39,12 @@ exports.checkVersions = function checkVersions(): void {
39
39
  }
40
40
  };
41
41
 
42
+ // Note: in OSS, the prerelease version is usually 0.Y.0-rc.W, so it is a string and not a number
43
+ // Then we need to keep supporting that object shape.
42
44
  function _formatVersion(
43
- version: (typeof Platform)['constants']['reactNativeVersion'],
45
+ version:
46
+ | (typeof Platform)['constants']['reactNativeVersion']
47
+ | {major: number, minor: number, patch: number, prerelease: ?string},
44
48
  ): string {
45
49
  return (
46
50
  `${version.major}.${version.minor}.${version.patch}` +
@@ -258,14 +258,6 @@ const validAttributesForNonEventProps = {
258
258
  top: true,
259
259
  bottom: true,
260
260
 
261
- inset: true,
262
- insetBlock: true,
263
- insetBlockEnd: true,
264
- insetBlockStart: true,
265
- insetInline: true,
266
- insetInlineEnd: true,
267
- insetInlineStart: true,
268
-
269
261
  position: true,
270
262
 
271
263
  style: ReactNativeStyleAttributes,
@@ -236,14 +236,6 @@ const validAttributesForNonEventProps = {
236
236
  bottom: true,
237
237
  left: true,
238
238
 
239
- inset: true,
240
- insetBlock: true,
241
- insetBlockEnd: true,
242
- insetBlockStart: true,
243
- insetInline: true,
244
- insetInlineEnd: true,
245
- insetInlineStart: true,
246
-
247
239
  width: true,
248
240
  height: true,
249
241
 
@@ -9,7 +9,6 @@
9
9
  */
10
10
 
11
11
  import type {RootTag} from '../Types/RootTagTypes';
12
- import type {Spec as FabricUIManagerSpec} from './FabricUIManager';
13
12
  import type {Spec} from './NativeUIManager';
14
13
 
15
14
  import {getFabricUIManager} from './FabricUIManager';
@@ -175,6 +174,33 @@ const UIManager = {
175
174
  );
176
175
  }
177
176
  },
177
+
178
+ dispatchViewManagerCommand(
179
+ reactTag: number,
180
+ commandName: number | string,
181
+ commandArgs: any[],
182
+ ) {
183
+ if (isFabricReactTag(reactTag)) {
184
+ const FabricUIManager = nullthrows(getFabricUIManager());
185
+ const shadowNode =
186
+ FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag);
187
+ if (shadowNode) {
188
+ // Transform the accidental CommandID into a CommandName which is the stringified number.
189
+ // The interop layer knows how to convert this number into the right method name.
190
+ // Stringify a string is a no-op, so it's safe.
191
+ commandName = `${commandName}`;
192
+ FabricUIManager.dispatchCommand(shadowNode, commandName, commandArgs);
193
+ }
194
+ } else {
195
+ UIManagerImpl.dispatchViewManagerCommand(
196
+ reactTag,
197
+ // We have some legacy components that are actually already using strings. ¯\_(ツ)_/¯
198
+ // $FlowFixMe[incompatible-call]
199
+ commandName,
200
+ commandArgs,
201
+ );
202
+ }
203
+ },
178
204
  };
179
205
 
180
206
  module.exports = UIManager;
@@ -3419,6 +3419,23 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) {
3419
3419
  return callback.apply(context, arguments);
3420
3420
  };
3421
3421
  }
3422
+ function warnForStyleProps(props, validAttributes) {
3423
+ {
3424
+ for (var key in validAttributes.style) {
3425
+ if (!(validAttributes[key] || props[key] === undefined)) {
3426
+ error(
3427
+ "You are setting the style `{ %s" +
3428
+ ": ... }` as a prop. You " +
3429
+ "should nest it in a style object. " +
3430
+ "E.g. `{ style: { %s" +
3431
+ ": ... } }`",
3432
+ key,
3433
+ key
3434
+ );
3435
+ }
3436
+ }
3437
+ }
3438
+ }
3422
3439
 
3423
3440
  // Modules provided by RN:
3424
3441
  var emptyObject = {};
@@ -5100,7 +5117,8 @@ var _nativeFabricUIManage = nativeFabricUIManager,
5100
5117
  FabricDefaultPriority = _nativeFabricUIManage.unstable_DefaultEventPriority,
5101
5118
  FabricDiscretePriority = _nativeFabricUIManage.unstable_DiscreteEventPriority,
5102
5119
  fabricGetCurrentEventPriority =
5103
- _nativeFabricUIManage.unstable_getCurrentEventPriority;
5120
+ _nativeFabricUIManage.unstable_getCurrentEventPriority,
5121
+ _setNativeProps = _nativeFabricUIManage.setNativeProps;
5104
5122
  var getViewConfigForType =
5105
5123
  ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views.
5106
5124
  // % 10 === 1 means it is a rootTag.
@@ -5199,10 +5217,15 @@ var ReactFabricHostComponent = /*#__PURE__*/ (function() {
5199
5217
 
5200
5218
  _proto.setNativeProps = function setNativeProps(nativeProps) {
5201
5219
  {
5202
- error("Warning: setNativeProps is not currently supported in Fabric");
5220
+ warnForStyleProps(nativeProps, this.viewConfig.validAttributes);
5203
5221
  }
5204
5222
 
5205
- return;
5223
+ var updatePayload = create(nativeProps, this.viewConfig.validAttributes);
5224
+ var stateNode = this._internalInstanceHandle.stateNode;
5225
+
5226
+ if (stateNode != null && updatePayload != null) {
5227
+ _setNativeProps(stateNode.node, updatePayload);
5228
+ }
5206
5229
  }; // This API (addEventListener, removeEventListener) attempts to adhere to the
5207
5230
  // w3 Level2 Events spec as much as possible, treating HostComponent as a DOM node.
5208
5231
  //
@@ -1922,6 +1922,7 @@ var _nativeFabricUIManage = nativeFabricUIManager,
1922
1922
  FabricDiscretePriority = _nativeFabricUIManage.unstable_DiscreteEventPriority,
1923
1923
  fabricGetCurrentEventPriority =
1924
1924
  _nativeFabricUIManage.unstable_getCurrentEventPriority,
1925
+ _setNativeProps = _nativeFabricUIManage.setNativeProps,
1925
1926
  getViewConfigForType =
1926
1927
  ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get,
1927
1928
  nextReactTag = 2;
@@ -1979,7 +1980,18 @@ var ReactFabricHostComponent = (function() {
1979
1980
  );
1980
1981
  }
1981
1982
  };
1982
- _proto.setNativeProps = function() {};
1983
+ _proto.setNativeProps = function(nativeProps) {
1984
+ nativeProps = diffProperties(
1985
+ null,
1986
+ emptyObject,
1987
+ nativeProps,
1988
+ this.viewConfig.validAttributes
1989
+ );
1990
+ var stateNode = this._internalInstanceHandle.stateNode;
1991
+ null != stateNode &&
1992
+ null != nativeProps &&
1993
+ _setNativeProps(stateNode.node, nativeProps);
1994
+ };
1983
1995
  _proto.addEventListener_unstable = function(eventType, listener, options) {
1984
1996
  if ("string" !== typeof eventType)
1985
1997
  throw Error("addEventListener_unstable eventType must be a string");
@@ -1981,6 +1981,7 @@ var _nativeFabricUIManage = nativeFabricUIManager,
1981
1981
  FabricDiscretePriority = _nativeFabricUIManage.unstable_DiscreteEventPriority,
1982
1982
  fabricGetCurrentEventPriority =
1983
1983
  _nativeFabricUIManage.unstable_getCurrentEventPriority,
1984
+ _setNativeProps = _nativeFabricUIManage.setNativeProps,
1984
1985
  getViewConfigForType =
1985
1986
  ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get,
1986
1987
  nextReactTag = 2;
@@ -2038,7 +2039,18 @@ var ReactFabricHostComponent = (function() {
2038
2039
  );
2039
2040
  }
2040
2041
  };
2041
- _proto.setNativeProps = function() {};
2042
+ _proto.setNativeProps = function(nativeProps) {
2043
+ nativeProps = diffProperties(
2044
+ null,
2045
+ emptyObject,
2046
+ nativeProps,
2047
+ this.viewConfig.validAttributes
2048
+ );
2049
+ var stateNode = this._internalInstanceHandle.stateNode;
2050
+ null != stateNode &&
2051
+ null != nativeProps &&
2052
+ _setNativeProps(stateNode.node, nativeProps);
2053
+ };
2042
2054
  _proto.addEventListener_unstable = function(eventType, listener, options) {
2043
2055
  if ("string" !== typeof eventType)
2044
2056
  throw Error("addEventListener_unstable eventType must be a string");
@@ -69,13 +69,6 @@ export interface FlexStyle {
69
69
  flexShrink?: number | undefined;
70
70
  flexWrap?: 'wrap' | 'nowrap' | 'wrap-reverse' | undefined;
71
71
  height?: DimensionValue | undefined;
72
- inset?: DimensionValue | undefined;
73
- insetBlock?: DimensionValue | undefined;
74
- insetBlockEnd?: DimensionValue | undefined;
75
- insetBlockStart?: DimensionValue | undefined;
76
- insetInline?: DimensionValue | undefined;
77
- insetInlineEnd?: DimensionValue | undefined;
78
- insetInlineStart?: DimensionValue | undefined;
79
72
  justifyContent?:
80
73
  | 'flex-start'
81
74
  | 'flex-end'
@@ -134,80 +134,6 @@ type ____LayoutStyle_Internal = $ReadOnly<{
134
134
  */
135
135
  top?: DimensionValue,
136
136
 
137
- /** `inset` is a shorthand that corresponds to the top, right, bottom, and/or left properties.
138
- *
139
- * It works similarly to `inset` in CSS, but in React Native you
140
- * must use points or percentages. Ems and other units are not supported.
141
- *
142
- * See https://developer.mozilla.org/en-US/docs/Web/CSS/inset
143
- * for more details of how `inset` affects layout.
144
- */
145
- inset?: DimensionValue,
146
-
147
- /** `insetBlock` is a shorthand that corresponds to the `insetBlockStart` and `insetBlockEnd` properties.
148
- *
149
- * It works similarly to `inset-block` in CSS, but in React Native you
150
- * must use points or percentages. Ems and other units are not supported.
151
- *
152
- * See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-block
153
- * for more details of how `inset-block` affects layout.
154
- */
155
- insetBlock?: DimensionValue,
156
-
157
- /** `insetBlockEnd` is a logical property that sets the length that an
158
- * element is offset in the block direction from its ending edge.
159
- *
160
- * It works similarly to `inset-block-end` in CSS, but in React Native you
161
- * must use points or percentages. Ems and other units are not supported.
162
- *
163
- * See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-block-end
164
- * for more details of how `inset-block-end` affects layout.
165
- */
166
- insetBlockEnd?: DimensionValue,
167
-
168
- /** `insetBlockStart` is a logical property that sets the length that an
169
- * element is offset in the block direction from its starting edge.
170
- *
171
- * It works similarly to `inset-block-start` in CSS, but in React Native you
172
- * must use points or percentages. Ems and other units are not supported.
173
- *
174
- * See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-block-start
175
- * for more details of how `inset-block-start` affects layout.
176
- */
177
- insetBlockStart?: DimensionValue,
178
-
179
- /** `insetInline` is a shorthand that corresponds to the `insetInlineStart` and `insetInlineEnd` properties.
180
- *
181
- * It works similarly to `inset-inline` in CSS, but in React Native you
182
- * must use points or percentages. Ems and other units are not supported.
183
- *
184
- * See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-inline
185
- * for more details of how `inset-inline` affects layout.
186
- */
187
- insetInline?: DimensionValue,
188
-
189
- /** `insetInlineEnd` is a logical property that sets the length that an
190
- * element is offset in the starting inline direction.
191
- *
192
- * It works similarly to `inset-inline-end` in CSS, but in React Native you
193
- * must use points or percentages. Ems and other units are not supported.
194
- *
195
- * See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-inline-end
196
- * for more details of how `inset-inline-end` affects layout.
197
- */
198
- insetInlineEnd?: DimensionValue,
199
-
200
- /** `insetInlineStart` is a logical property that sets the length that an
201
- * element is offset in the starting inline direction.
202
- *
203
- * It works similarly to `inset-inline-start` in CSS, but in React Native you
204
- * must use points or percentages. Ems and other units are not supported.
205
- *
206
- * See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-inline-start
207
- * for more details of how `inset-inline-start` affects layout.
208
- */
209
- insetInlineStart?: DimensionValue,
210
-
211
137
  /** `minWidth` is the minimum width for this component, in logical pixels.
212
138
  *
213
139
  * It works similarly to `min-width` in CSS, but in React Native you
@@ -256,21 +256,21 @@ static void *TextFieldSelectionObservingContext = &TextFieldSelectionObservingCo
256
256
 
257
257
  - (void)textViewDidChange:(__unused UITextView *)textView
258
258
  {
259
- if (_ignoreNextTextInputCall && [_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
259
+ if (_ignoreNextTextInputCall) {
260
260
  _ignoreNextTextInputCall = NO;
261
261
  return;
262
262
  }
263
- _lastStringStateWasUpdatedWith = _backedTextInputView.attributedText;
264
263
  _textDidChangeIsComing = NO;
265
264
  [_backedTextInputView.textInputDelegate textInputDidChange];
266
265
  }
267
266
 
268
267
  - (void)textViewDidChangeSelection:(__unused UITextView *)textView
269
268
  {
270
- if (![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
269
+ if (_lastStringStateWasUpdatedWith && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
271
270
  [self textViewDidChange:_backedTextInputView];
272
271
  _ignoreNextTextInputCall = YES;
273
272
  }
273
+ _lastStringStateWasUpdatedWith = _backedTextInputView.attributedText;
274
274
  [self textViewProbablyDidChangeSelection];
275
275
  }
276
276
 
@@ -24,7 +24,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(72),
26
26
  RCTVersionPatch: @(0),
27
- RCTVersionPrerelease: @"rc.0",
27
+ RCTVersionPrerelease: @"rc.2",
28
28
  };
29
29
  });
30
30
  return __rnVersion;
@@ -428,10 +428,10 @@ RCT_EXPORT_METHOD(show)
428
428
  ? UIAlertControllerStyleActionSheet
429
429
  : UIAlertControllerStyleAlert;
430
430
 
431
- NSString *debugMenuType = self.bridge ? @"Bridge" : @"Bridgeless";
432
- NSString *debugMenuTitle = [NSString stringWithFormat:@"React Native Debug Menu (%@)", debugMenuType];
431
+ NSString *devMenuType = self.bridge ? @"Bridge" : @"Bridgeless";
432
+ NSString *devMenuTitle = [NSString stringWithFormat:@"React Native Dev Menu (%@)", devMenuType];
433
433
 
434
- _actionSheet = [UIAlertController alertControllerWithTitle:debugMenuTitle message:description preferredStyle:style];
434
+ _actionSheet = [UIAlertController alertControllerWithTitle:devMenuTitle message:description preferredStyle:style];
435
435
 
436
436
  NSArray<RCTDevMenuItem *> *items = [self _menuItemsToPresent];
437
437
  for (RCTDevMenuItem *item in items) {
@@ -50,7 +50,7 @@
50
50
 
51
51
  - (void)handleCommand:(NSString *)commandName args:(NSArray *)args
52
52
  {
53
- [_coordinator handleCommand:commandName args:args reactTag:_tag];
53
+ [_coordinator handleCommand:commandName args:args reactTag:_tag paperView:self.paperView];
54
54
  }
55
55
 
56
56
  @end
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.72.0-rc.0
1
+ VERSION_NAME=0.72.0-rc.2
2
2
  GROUP=com.facebook.react
3
3
 
4
4
  # JVM Versions
@@ -11,6 +11,7 @@ import android.app.Activity;
11
11
  import android.content.Intent;
12
12
  import android.os.Bundle;
13
13
  import android.view.KeyEvent;
14
+ import androidx.annotation.NonNull;
14
15
  import androidx.annotation.Nullable;
15
16
  import com.facebook.infer.annotation.Assertions;
16
17
  import com.facebook.react.devsupport.DoubleTapReloadRecognizer;
@@ -33,6 +34,8 @@ public class ReactDelegate {
33
34
 
34
35
  private ReactNativeHost mReactNativeHost;
35
36
 
37
+ private boolean mFabricEnabled = false;
38
+
36
39
  public ReactDelegate(
37
40
  Activity activity,
38
41
  ReactNativeHost reactNativeHost,
@@ -45,6 +48,20 @@ public class ReactDelegate {
45
48
  mReactNativeHost = reactNativeHost;
46
49
  }
47
50
 
51
+ public ReactDelegate(
52
+ Activity activity,
53
+ ReactNativeHost reactNativeHost,
54
+ @Nullable String appKey,
55
+ @Nullable Bundle launchOptions,
56
+ boolean fabricEnabled) {
57
+ mActivity = activity;
58
+ mMainComponentName = appKey;
59
+ mLaunchOptions = composeLaunchOptions(launchOptions);
60
+ mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer();
61
+ mReactNativeHost = reactNativeHost;
62
+ mFabricEnabled = fabricEnabled;
63
+ }
64
+
48
65
  public void onHostResume() {
49
66
  if (getReactNativeHost().hasInstance()) {
50
67
  if (mActivity instanceof DefaultHardwareBackBtnHandler) {
@@ -109,7 +126,9 @@ public class ReactDelegate {
109
126
  }
110
127
 
111
128
  protected ReactRootView createRootView() {
112
- return new ReactRootView(mActivity);
129
+ ReactRootView reactRootView = new ReactRootView(mActivity);
130
+ reactRootView.setIsFabric(isFabricEnabled());
131
+ return reactRootView;
113
132
  }
114
133
 
115
134
  /**
@@ -144,4 +163,24 @@ public class ReactDelegate {
144
163
  public ReactInstanceManager getReactInstanceManager() {
145
164
  return getReactNativeHost().getReactInstanceManager();
146
165
  }
166
+
167
+ /**
168
+ * Override this method if you wish to selectively toggle Fabric for a specific surface. This will
169
+ * also control if Concurrent Root (React 18) should be enabled or not.
170
+ *
171
+ * @return true if Fabric is enabled for this Activity, false otherwise.
172
+ */
173
+ protected boolean isFabricEnabled() {
174
+ return mFabricEnabled;
175
+ }
176
+
177
+ private @NonNull Bundle composeLaunchOptions(Bundle composedLaunchOptions) {
178
+ if (isFabricEnabled()) {
179
+ if (composedLaunchOptions == null) {
180
+ composedLaunchOptions = new Bundle();
181
+ }
182
+ composedLaunchOptions.putBoolean("concurrentRoot", true);
183
+ }
184
+ return composedLaunchOptions;
185
+ }
147
186
  }
@@ -16,6 +16,7 @@ import android.view.KeyEvent;
16
16
  import android.view.LayoutInflater;
17
17
  import android.view.View;
18
18
  import android.view.ViewGroup;
19
+ import androidx.annotation.NonNull;
19
20
  import androidx.annotation.Nullable;
20
21
  import androidx.fragment.app.Fragment;
21
22
  import com.facebook.react.modules.core.PermissionAwareActivity;
@@ -29,6 +30,7 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
29
30
 
30
31
  protected static final String ARG_COMPONENT_NAME = "arg_component_name";
31
32
  protected static final String ARG_LAUNCH_OPTIONS = "arg_launch_options";
33
+ protected static final String ARG_FABRIC_ENABLED = "arg_fabric_enabled";
32
34
 
33
35
  private ReactDelegate mReactDelegate;
34
36
 
@@ -40,13 +42,16 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
40
42
 
41
43
  /**
42
44
  * @param componentName The name of the react native component
45
+ * @param fabricEnabled Flag to enable Fabric for ReactFragment
43
46
  * @return A new instance of fragment ReactFragment.
44
47
  */
45
- private static ReactFragment newInstance(String componentName, Bundle launchOptions) {
48
+ private static ReactFragment newInstance(
49
+ String componentName, Bundle launchOptions, Boolean fabricEnabled) {
46
50
  ReactFragment fragment = new ReactFragment();
47
51
  Bundle args = new Bundle();
48
52
  args.putString(ARG_COMPONENT_NAME, componentName);
49
53
  args.putBundle(ARG_LAUNCH_OPTIONS, launchOptions);
54
+ args.putBoolean(ARG_FABRIC_ENABLED, fabricEnabled);
50
55
  fragment.setArguments(args);
51
56
  return fragment;
52
57
  }
@@ -57,15 +62,18 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
57
62
  super.onCreate(savedInstanceState);
58
63
  String mainComponentName = null;
59
64
  Bundle launchOptions = null;
65
+ Boolean fabricEnabled = null;
60
66
  if (getArguments() != null) {
61
67
  mainComponentName = getArguments().getString(ARG_COMPONENT_NAME);
62
68
  launchOptions = getArguments().getBundle(ARG_LAUNCH_OPTIONS);
69
+ fabricEnabled = getArguments().getBoolean(ARG_FABRIC_ENABLED);
63
70
  }
64
71
  if (mainComponentName == null) {
65
72
  throw new IllegalStateException("Cannot loadApp if component name is null");
66
73
  }
67
74
  mReactDelegate =
68
- new ReactDelegate(getActivity(), getReactNativeHost(), mainComponentName, launchOptions);
75
+ new ReactDelegate(
76
+ getActivity(), getReactNativeHost(), mainComponentName, launchOptions, fabricEnabled);
69
77
  }
70
78
 
71
79
  /**
@@ -85,7 +93,7 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
85
93
 
86
94
  @Override
87
95
  public View onCreateView(
88
- LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
96
+ @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
89
97
  mReactDelegate.loadApp();
90
98
  return mReactDelegate.getReactRootView();
91
99
  }
@@ -140,7 +148,7 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
140
148
 
141
149
  @Override
142
150
  public void onRequestPermissionsResult(
143
- int requestCode, String[] permissions, int[] grantResults) {
151
+ int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
144
152
  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
145
153
  if (mPermissionListener != null
146
154
  && mPermissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
@@ -170,12 +178,14 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
170
178
  /** Builder class to help instantiate a ReactFragment */
171
179
  public static class Builder {
172
180
 
173
- String mComponentName;
174
- Bundle mLaunchOptions;
181
+ @Nullable String mComponentName;
182
+ @Nullable Bundle mLaunchOptions;
183
+ @Nullable Boolean mFabricEnabled;
175
184
 
176
185
  public Builder() {
177
186
  mComponentName = null;
178
187
  mLaunchOptions = null;
188
+ mFabricEnabled = null;
179
189
  }
180
190
 
181
191
  /**
@@ -201,7 +211,12 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
201
211
  }
202
212
 
203
213
  public ReactFragment build() {
204
- return ReactFragment.newInstance(mComponentName, mLaunchOptions);
214
+ return ReactFragment.newInstance(mComponentName, mLaunchOptions, mFabricEnabled);
215
+ }
216
+
217
+ public Builder setFabricEnabled(boolean fabricEnabled) {
218
+ mFabricEnabled = fabricEnabled;
219
+ return this;
205
220
  }
206
221
  }
207
222
  }
@@ -295,6 +295,16 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
295
295
  mCurrentFrameNumber++;
296
296
  }
297
297
 
298
+ @Override
299
+ public void willMountItems(UIManager uiManager) {
300
+ // noop
301
+ }
302
+
303
+ @Override
304
+ public void didMountItems(UIManager uiManager) {
305
+ // noop
306
+ }
307
+
298
308
  // For FabricUIManager only
299
309
  @Override
300
310
  @UiThread
@@ -21,6 +21,7 @@ import com.facebook.common.logging.FLog;
21
21
  import com.facebook.infer.annotation.Assertions;
22
22
  import com.facebook.infer.annotation.ThreadConfined;
23
23
  import com.facebook.proguard.annotations.DoNotStrip;
24
+ import com.facebook.react.bridge.interop.InteropModuleRegistry;
24
25
  import com.facebook.react.bridge.queue.MessageQueueThread;
25
26
  import com.facebook.react.bridge.queue.ReactQueueConfiguration;
26
27
  import com.facebook.react.common.LifecycleState;
@@ -69,6 +70,8 @@ public class ReactContext extends ContextWrapper {
69
70
  private @Nullable JSExceptionHandler mJSExceptionHandler;
70
71
  private @Nullable JSExceptionHandler mExceptionHandlerWrapper;
71
72
  private @Nullable WeakReference<Activity> mCurrentActivity;
73
+
74
+ private @Nullable InteropModuleRegistry mInteropModuleRegistry;
72
75
  private boolean mIsInitialized = false;
73
76
 
74
77
  public ReactContext(Context base) {
@@ -93,6 +96,7 @@ public class ReactContext extends ContextWrapper {
93
96
 
94
97
  ReactQueueConfiguration queueConfig = catalystInstance.getReactQueueConfiguration();
95
98
  initializeMessageQueueThreads(queueConfig);
99
+ initializeInteropModules();
96
100
  }
97
101
 
98
102
  /** Initialize message queue threads using a ReactQueueConfiguration. */
@@ -120,6 +124,14 @@ public class ReactContext extends ContextWrapper {
120
124
  mIsInitialized = true;
121
125
  }
122
126
 
127
+ protected void initializeInteropModules() {
128
+ mInteropModuleRegistry = new InteropModuleRegistry();
129
+ }
130
+
131
+ protected void initializeInteropModules(ReactContext reactContext) {
132
+ mInteropModuleRegistry = reactContext.mInteropModuleRegistry;
133
+ }
134
+
123
135
  public void resetPerfStats() {
124
136
  if (mNativeModulesMessageQueueThread != null) {
125
137
  mNativeModulesMessageQueueThread.resetPerfStats();
@@ -163,6 +175,10 @@ public class ReactContext extends ContextWrapper {
163
175
  }
164
176
  throw new IllegalStateException(EARLY_JS_ACCESS_EXCEPTION_MESSAGE);
165
177
  }
178
+ if (mInteropModuleRegistry != null
179
+ && mInteropModuleRegistry.shouldReturnInteropModule(jsInterface)) {
180
+ return mInteropModuleRegistry.getInteropModule(jsInterface);
181
+ }
166
182
  return mCatalystInstance.getJSModule(jsInterface);
167
183
  }
168
184
 
@@ -546,4 +562,17 @@ public class ReactContext extends ContextWrapper {
546
562
  Assertions.assertNotNull(mCatalystInstance).registerSegment(segmentId, path);
547
563
  Assertions.assertNotNull(callback).invoke();
548
564
  }
565
+
566
+ /**
567
+ * Register a {@link JavaScriptModule} within the Interop Layer so that can be consumed whenever
568
+ * getJSModule is invoked.
569
+ *
570
+ * <p>This method is internal to React Native and should not be used externally.
571
+ */
572
+ public <T extends JavaScriptModule> void internal_registerInteropModule(
573
+ Class<T> interopModuleInterface, Object interopModule) {
574
+ if (mInteropModuleRegistry != null) {
575
+ mInteropModuleRegistry.registerInteropModule(interopModuleInterface, interopModule);
576
+ }
577
+ }
549
578
  }