react-native-windows 0.76.8 → 0.76.10

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 (128) hide show
  1. package/Libraries/Components/Button.windows.js +9 -0
  2. package/Libraries/Components/Pressable/Pressable.windows.js +9 -0
  3. package/Libraries/Components/TextInput/TextInput.windows.js +11 -1
  4. package/Libraries/Components/Touchable/TouchableBounce.windows.js +229 -0
  5. package/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js +373 -0
  6. package/Libraries/Components/Touchable/TouchableOpacity.windows.js +7 -0
  7. package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +8 -0
  8. package/Libraries/Components/View/View.windows.js +11 -1
  9. package/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
  10. package/Libraries/Components/View/ViewAccessibility.windows.js +3 -0
  11. package/Libraries/Components/View/ViewPropTypes.windows.js +3 -0
  12. package/Libraries/Image/Image.windows.js +7 -0
  13. package/Libraries/Modal/Modal.windows.js +4 -1
  14. package/Libraries/Text/Text.windows.js +14 -1
  15. package/Libraries/Text/TextProps.windows.js +3 -0
  16. package/Microsoft.ReactNative/CompositionComponentView.idl +13 -1
  17. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.cpp +97 -0
  18. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.h +53 -0
  19. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +160 -17
  20. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +8 -10
  21. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -2
  22. package/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +0 -5
  23. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +428 -39
  24. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +39 -1
  25. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +55 -33
  26. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +5 -3
  27. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +43 -5
  28. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +2 -1
  29. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.cpp +115 -0
  30. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.h +41 -0
  31. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.cpp +298 -0
  32. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.h +59 -0
  33. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +106 -56
  34. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
  35. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +163 -10
  36. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +17 -1
  37. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +4 -2
  38. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +9 -1
  39. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +348 -316
  40. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +3 -61
  41. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.cpp +78 -0
  42. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.h +52 -0
  43. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +22 -0
  44. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +7 -5
  45. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +99 -37
  46. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +12 -6
  47. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +81 -22
  48. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +21 -2
  49. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +6 -1
  50. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +41 -37
  51. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +76 -33
  52. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +8 -2
  53. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +1 -6
  54. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +0 -3
  55. package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +0 -2
  56. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +5 -8
  57. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorParser.h +1 -2
  58. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorUtils.cpp +1 -1
  59. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +15 -1
  60. package/Microsoft.ReactNative/IReactContext.cpp +2 -2
  61. package/Microsoft.ReactNative/IReactContext.h +1 -1
  62. package/Microsoft.ReactNative/IReactContext.idl +2 -2
  63. package/Microsoft.ReactNative/IReactPackageBuilder.idl +3 -3
  64. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +97 -87
  65. package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +4 -0
  66. package/Microsoft.ReactNative/Modules/AlertModule.cpp +9 -4
  67. package/Microsoft.ReactNative/Modules/Animated/NativeAnimatedNodeManager.cpp +1 -1
  68. package/Microsoft.ReactNative/Modules/Animated/PropsAnimatedNode.cpp +32 -35
  69. package/Microsoft.ReactNative/Modules/Animated/PropsAnimatedNode.h +7 -4
  70. package/Microsoft.ReactNative/Modules/AppStateModule.cpp +1 -1
  71. package/Microsoft.ReactNative/Modules/AppThemeModuleUwp.cpp +2 -2
  72. package/Microsoft.ReactNative/Modules/AppearanceModule.cpp +2 -2
  73. package/Microsoft.ReactNative/Modules/ClipboardModule.cpp +1 -1
  74. package/Microsoft.ReactNative/Modules/ClipboardModule.h +1 -1
  75. package/Microsoft.ReactNative/Modules/DeviceInfoModule.cpp +3 -3
  76. package/Microsoft.ReactNative/Modules/I18nManagerModule.cpp +1 -1
  77. package/Microsoft.ReactNative/Modules/LogBoxModule.cpp +7 -5
  78. package/Microsoft.ReactNative/Modules/LogBoxModule.h +2 -1
  79. package/Microsoft.ReactNative/Modules/Timing.cpp +2 -2
  80. package/Microsoft.ReactNative/ReactHost/IReactInstance.h +5 -0
  81. package/Microsoft.ReactNative/ReactHost/React.h +0 -3
  82. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +36 -12
  83. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
  84. package/Microsoft.ReactNative/ReactNativeHost.cpp +9 -4
  85. package/Microsoft.ReactNative/ReactNativeIsland.idl +5 -1
  86. package/Microsoft.ReactNative/ReactPackageBuilder.cpp +3 -3
  87. package/Microsoft.ReactNative/ReactPackageBuilder.h +4 -4
  88. package/Microsoft.ReactNative/Utils/Helpers.cpp +0 -2
  89. package/Microsoft.ReactNative/Views/DevMenu.cpp +6 -6
  90. package/Microsoft.ReactNative/Views/DevMenu.h +1 -1
  91. package/Microsoft.ReactNative/XamlUIService.cpp +13 -7
  92. package/Microsoft.ReactNative/XamlUIService.h +4 -1
  93. package/Microsoft.ReactNative/XamlUIService.idl +2 -0
  94. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +6 -2
  95. package/Microsoft.ReactNative.Cxx/NativeModules.h +29 -0
  96. package/Microsoft.ReactNative.Cxx/ReactContext.h +1 -1
  97. package/Microsoft.ReactNative.Cxx/XamlUtils.h +12 -0
  98. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  99. package/PropertySheets/React.Cpp.props +3 -0
  100. package/PropertySheets/WebView2.props +1 -1
  101. package/PropertySheets/WinUI.props +5 -4
  102. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h +253 -0
  103. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h +799 -0
  104. package/Shared/InspectorPackagerConnection.cpp +2 -5
  105. package/Shared/InspectorPackagerConnection.h +2 -2
  106. package/Shared/Networking/WinRTWebSocketResource.cpp +369 -7
  107. package/Shared/Networking/WinRTWebSocketResource.h +118 -0
  108. package/Shared/Shared.vcxitems +12 -5
  109. package/Shared/Shared.vcxitems.filters +11 -4
  110. package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +212 -0
  111. package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +295 -0
  112. package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +200 -0
  113. package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +224 -0
  114. package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +250 -0
  115. package/codegen/react/components/rnwcore/AndroidSwitch.g.h +267 -0
  116. package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +234 -0
  117. package/codegen/react/components/rnwcore/InputAccessory.g.h +200 -0
  118. package/codegen/react/components/rnwcore/ModalHostView.g.h +279 -0
  119. package/codegen/react/components/rnwcore/PullToRefreshView.g.h +246 -0
  120. package/codegen/react/components/rnwcore/SafeAreaView.g.h +197 -0
  121. package/codegen/react/components/rnwcore/Switch.g.h +263 -0
  122. package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +200 -0
  123. package/just-task.js +1 -1
  124. package/package.json +6 -6
  125. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +0 -191
  126. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentDescriptor.h +0 -39
  127. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.cpp +0 -18
  128. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.h +0 -39
@@ -235,6 +235,13 @@ class TouchableOpacity extends React.Component<Props, State> {
235
235
  this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded,
236
236
  selected:
237
237
  this.props['aria-selected'] ?? this.props.accessibilityState?.selected,
238
+ readOnly:
239
+ this.props['aria-readonly'] ?? this.props.accessibilityState?.readOnly, // Windows
240
+ multiselectable:
241
+ this.props['aria-multiselectable'] ??
242
+ this.props.accessibilityState?.multiselectable, // Windows
243
+ required:
244
+ this.props['aria-required'] ?? this.props.accessibilityState?.required, // Windows
238
245
  };
239
246
 
240
247
  _accessibilityState =
@@ -59,6 +59,9 @@ type Props = $ReadOnly<{|
59
59
  'aria-disabled'?: ?boolean,
60
60
  'aria-expanded'?: ?boolean,
61
61
  'aria-selected'?: ?boolean,
62
+ 'aria-readonly'?: ?boolean, // Windows
63
+ 'aria-multiselectable'?: ?boolean, // Windows
64
+ 'aria-required'?: ?boolean, // Windows
62
65
  'aria-hidden'?: ?boolean,
63
66
  'aria-live'?: ?('polite' | 'assertive' | 'off'),
64
67
  'aria-label'?: ?Stringish,
@@ -221,6 +224,11 @@ const TouchableWithoutFeedback: React.AbstractComponent<
221
224
  disabled: props['aria-disabled'] ?? props.accessibilityState?.disabled,
222
225
  expanded: props['aria-expanded'] ?? props.accessibilityState?.expanded,
223
226
  selected: props['aria-selected'] ?? props.accessibilityState?.selected,
227
+ readonly: props['aria-readonly'] ?? props.accessibilityState?.readOnly, // Windows
228
+ multiselectable:
229
+ props['aria-multiselectable'] ??
230
+ props.accessibilityState?.multiselectable, // Windows
231
+ required: props['aria-required'] ?? props.accessibilityState?.required, // Windows
224
232
  };
225
233
 
226
234
  // BACKWARD-COMPATIBILITY: Focus and blur events were never supported before
@@ -76,12 +76,15 @@ const View: React.AbstractComponent<
76
76
  'aria-checked': ariaChecked,
77
77
  'aria-disabled': ariaDisabled,
78
78
  'aria-expanded': ariaExpanded,
79
+ 'aria-multiselectable': ariaMultiselectable, // Windows
80
+ 'aria-required': ariaRequired, // Windows
79
81
  'aria-hidden': ariaHidden,
80
82
  'aria-label': ariaLabel,
81
83
  'aria-labelledby': ariaLabelledBy,
82
84
  'aria-level': ariaLevel,
83
85
  'aria-live': ariaLive,
84
86
  'aria-posinset': ariaPosinset, // Windows
87
+ 'aria-readonly': ariaReadOnly, // Windows
85
88
  'aria-selected': ariaSelected,
86
89
  'aria-setsize': ariaSetsize, // Windows
87
90
  'aria-valuemax': ariaValueMax,
@@ -108,7 +111,10 @@ const View: React.AbstractComponent<
108
111
  ariaChecked != null ||
109
112
  ariaDisabled != null ||
110
113
  ariaExpanded != null ||
111
- ariaSelected != null
114
+ ariaSelected != null ||
115
+ ariaReadOnly != null || // Windows
116
+ ariaMultiselectable != null || // Windows
117
+ ariaRequired != null // Windows
112
118
  ) {
113
119
  _accessibilityState = {
114
120
  busy: ariaBusy ?? accessibilityState?.busy,
@@ -116,6 +122,10 @@ const View: React.AbstractComponent<
116
122
  disabled: ariaDisabled ?? accessibilityState?.disabled,
117
123
  expanded: ariaExpanded ?? accessibilityState?.expanded,
118
124
  selected: ariaSelected ?? accessibilityState?.selected,
125
+ readOnly: ariaReadOnly ?? accessibilityState?.readOnly, // Windows
126
+ multiselectable:
127
+ ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows
128
+ required: ariaRequired ?? accessibilityState?.required, // Windows
119
129
  };
120
130
  }
121
131
  let _accessibilityValue;
@@ -183,6 +183,21 @@ export interface AccessibilityState {
183
183
  * When present, informs accessible tools the element is expanded or collapsed
184
184
  */
185
185
  expanded?: boolean | undefined;
186
+ /**
187
+ * When present, informs accessible tools the element is read only
188
+ * @platform windows
189
+ */
190
+ readOnly?: boolean | undefined;
191
+ /**
192
+ * When present, informs accessible tools the element can have multiple items selected
193
+ * @platform windows
194
+ */
195
+ multiselectable?: boolean | undefined;
196
+ /**
197
+ * When present, informs accessible tools the element requires selection
198
+ * @platform windows
199
+ */
200
+ required?: boolean | undefined;
186
201
  }
187
202
 
188
203
  export interface AccessibilityValue {
@@ -181,6 +181,9 @@ export type AccessibilityState = {
181
181
  checked?: ?boolean | 'mixed',
182
182
  busy?: ?boolean,
183
183
  expanded?: ?boolean,
184
+ readOnly?: ?boolean, // Windows
185
+ multiselectable?: ?boolean, // Windows
186
+ required?: ?boolean, // Windows
184
187
  ...
185
188
  };
186
189
 
@@ -620,12 +620,15 @@ export type ViewProps = $ReadOnly<{|
620
620
  'aria-disabled'?: ?boolean,
621
621
  'aria-expanded'?: ?boolean,
622
622
  'aria-selected'?: ?boolean,
623
+ 'aria-readonly'?: ?boolean, // Windows
623
624
  /** A value indicating whether the accessibility elements contained within
624
625
  * this accessibility element are hidden.
625
626
  *
626
627
  * See https://reactnative.dev/docs/view#aria-hidden
627
628
  */
628
629
  'aria-hidden'?: ?boolean,
630
+ 'aria-multiselectable'?: ?boolean, // Windows
631
+ 'aria-required'?: ?boolean, // Windows
629
632
 
630
633
  /**
631
634
  * Views that are only used to layout their children or otherwise don't draw
@@ -147,6 +147,9 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => {
147
147
  'aria-disabled': ariaDisabled,
148
148
  'aria-expanded': ariaExpanded,
149
149
  'aria-selected': ariaSelected,
150
+ 'aria-readonly': ariaReadOnly, // Windows
151
+ 'aria-multiselectable': ariaMultiselectable, // Windows
152
+ 'aria-required': ariaRequired, // Windows
150
153
  height,
151
154
  src,
152
155
  width,
@@ -159,6 +162,10 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => {
159
162
  disabled: ariaDisabled ?? props.accessibilityState?.disabled,
160
163
  expanded: ariaExpanded ?? props.accessibilityState?.expanded,
161
164
  selected: ariaSelected ?? props.accessibilityState?.selected,
165
+ readOnly: ariaReadOnly ?? props.accessibilityState?.readOnly, // Windows
166
+ multiselectable:
167
+ ariaMultiselectable ?? props.accessibilityState?.multiselectable, // Windows
168
+ required: ariaRequired ?? props.accessibilityState?.required, // Windows
162
169
  };
163
170
  const accessibilityLabel = props['aria-label'] ?? props.accessibilityLabel;
164
171
 
@@ -274,8 +274,11 @@ class Modal extends React.Component<Props, State> {
274
274
  }
275
275
  }
276
276
 
277
+ // [Windows] - apply empty rootViewStyle to AppContainer to prevent modal from always expanding to fill available space
277
278
  const innerChildren = __DEV__ ? (
278
- <AppContainer rootTag={this.context}>{this.props.children}</AppContainer>
279
+ <AppContainer rootTag={this.context} rootViewStyle={{}}>
280
+ {this.props.children}
281
+ </AppContainer>
279
282
  ) : (
280
283
  this.props.children
281
284
  );
@@ -51,11 +51,14 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
51
51
  'aria-checked': ariaChecked,
52
52
  'aria-disabled': ariaDisabled,
53
53
  'aria-expanded': ariaExpanded,
54
+ 'aria-multiselectable': ariaMultiselectable, // Windows
55
+ 'aria-required': ariaRequired, // Windows
54
56
  'aria-label': ariaLabel,
55
57
  'aria-level': ariaLevel, // Windows
56
58
  'aria-posinset': ariaPosinset, // Windows
57
59
  'aria-setsize': ariaSetsize, // Windows
58
60
  'aria-selected': ariaSelected,
61
+ 'aria-readonly': ariaReadOnly, //Windows
59
62
  children,
60
63
  ellipsizeMode,
61
64
  disabled,
@@ -93,7 +96,10 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
93
96
  ariaChecked != null ||
94
97
  ariaDisabled != null ||
95
98
  ariaExpanded != null ||
96
- ariaSelected != null
99
+ ariaSelected != null ||
100
+ ariaReadOnly != null || // Windows
101
+ ariaMultiselectable != null || // Windows
102
+ ariaRequired != null // Windows
97
103
  ) {
98
104
  if (_accessibilityState != null) {
99
105
  _accessibilityState = {
@@ -102,6 +108,10 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
102
108
  disabled: ariaDisabled ?? _accessibilityState.disabled,
103
109
  expanded: ariaExpanded ?? _accessibilityState.expanded,
104
110
  selected: ariaSelected ?? _accessibilityState.selected,
111
+ readOnly: ariaReadOnly ?? _accessibilityState.readOnly, // Windows
112
+ multiselectable:
113
+ ariaMultiselectable ?? _accessibilityState.multiselectable, // Windows
114
+ required: ariaRequired ?? _accessibilityState.required, // Windows
105
115
  };
106
116
  } else {
107
117
  _accessibilityState = {
@@ -110,6 +120,9 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
110
120
  disabled: ariaDisabled,
111
121
  expanded: ariaExpanded,
112
122
  selected: ariaSelected,
123
+ readOnly: ariaReadOnly, // Windows
124
+ multiselectable: ariaMultiselectable, // Windows
125
+ required: ariaRequired, // Windows
113
126
  };
114
127
  }
115
128
  }
@@ -97,6 +97,9 @@ export type TextProps = $ReadOnly<{
97
97
  'aria-posinset'?: ?number, // Windows
98
98
  'aria-setsize'?: ?number, // Windows
99
99
  'aria-level'?: ?number, // Windows
100
+ 'aria-readonly'?: ?boolean, // Windows
101
+ 'aria-multiselectable'?: ?boolean, // Windows
102
+ 'aria-required'?: ?boolean, // Windows
100
103
 
101
104
  /**
102
105
  * Represents the nativeID of the associated label text. When the assistive technology focuses on the component with this props, the text is read aloud.
@@ -7,6 +7,7 @@ import "ViewProps.idl";
7
7
  import "Composition.Input.idl";
8
8
  import "CompositionSwitcher.idl";
9
9
  import "IReactContext.idl";
10
+ import "ReactNativeIsland.idl";
10
11
 
11
12
  #include "DocString.h"
12
13
 
@@ -110,8 +111,19 @@ namespace Microsoft.ReactNative.Composition
110
111
  [default_interface]
111
112
  runtimeclass RootComponentView : ViewComponentView {
112
113
  Microsoft.ReactNative.ComponentView GetFocusedComponent();
114
+ Microsoft.ReactNative.ReactNativeIsland ReactNativeIsland { get; };
115
+ DOC_STRING("Is non-null if this RootComponentView is the content of a portal")
116
+ PortalComponentView Portal { get; };
113
117
  };
114
-
118
+
119
+ [experimental]
120
+ [webhosthidden]
121
+ [default_interface]
122
+ DOC_STRING("Used to implement UI that is hosted outside the main UI tree, such as modal.")
123
+ runtimeclass PortalComponentView : Microsoft.ReactNative.ComponentView {
124
+ RootComponentView ContentRoot { get; };
125
+ };
126
+
115
127
  [experimental]
116
128
  [webhosthidden]
117
129
  [default_interface]
@@ -0,0 +1,97 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "AbiPortalShadowNode.h"
5
+
6
+ #include <Fabric/Composition/ReactCompositionViewComponentBuilder.h>
7
+ #include <react/debug/react_native_assert.h>
8
+ #include <react/renderer/core/LayoutConstraints.h>
9
+ #include <react/renderer/core/LayoutContext.h>
10
+ #include <react/renderer/core/conversions.h>
11
+
12
+ #include <utility>
13
+
14
+ namespace Microsoft::ReactNative {
15
+
16
+ extern const char AbiPortalComponentName[] = "AbiPortal";
17
+
18
+ facebook::react::Size AbiPortalShadowNode::measureContent(
19
+ const facebook::react::LayoutContext &layoutContext,
20
+ const facebook::react::LayoutConstraints &layoutConstraints) const {
21
+ return {0, 0}; // The portal placeholder node shouldn't take up any space
22
+ }
23
+
24
+ void AbiPortalShadowNode::layout(facebook::react::LayoutContext layoutContext) {
25
+ ensureUnsealed();
26
+ auto layoutMetrics = getLayoutMetrics();
27
+
28
+ auto portalOwningShadowNode = ShadowNode::Unshared{};
29
+
30
+ if (getChildren().empty()) {
31
+ return;
32
+ }
33
+
34
+ // A Portal should only have a single child
35
+ react_native_assert(getChildren().size() == 1);
36
+
37
+ const auto &childNode = getChildren()[0];
38
+
39
+ auto clonedShadowNode = ShadowNode::Unshared{};
40
+
41
+ portalOwningShadowNode = cloneTree(childNode->getFamily(), [&](const ShadowNode &oldShadowNode) {
42
+ clonedShadowNode = oldShadowNode.clone({});
43
+ return clonedShadowNode;
44
+ });
45
+ auto portalShadowNode = static_cast<AbiPortalShadowNode *>(portalOwningShadowNode.get());
46
+
47
+ auto &layoutableShadowNode = dynamic_cast<LayoutableShadowNode &>(*clonedShadowNode);
48
+
49
+ auto &state = getStateData();
50
+
51
+ facebook::react::LayoutConstraints layoutConstraints;
52
+ layoutConstraints.layoutDirection = layoutMetrics.layoutDirection;
53
+
54
+ if (state.userdata) {
55
+ // If the portal component set a state of type IPortalStateData,
56
+ // extract constraint information from it, and use that for layout
57
+ if (auto portalState = state.userdata.try_as<winrt::Microsoft::ReactNative::Composition::IPortalStateData>()) {
58
+ auto stateConstraints = portalState.LayoutConstraints();
59
+
60
+ layoutConstraints.minimumSize = {stateConstraints.MinimumSize.Width, stateConstraints.MinimumSize.Height};
61
+ layoutConstraints.maximumSize = {stateConstraints.MaximumSize.Width, stateConstraints.MaximumSize.Height};
62
+ if (stateConstraints.LayoutDirection == winrt::Microsoft::ReactNative::LayoutDirection::LeftToRight) {
63
+ layoutConstraints.layoutDirection = facebook::react::LayoutDirection::LeftToRight;
64
+ } else if (stateConstraints.LayoutDirection == winrt::Microsoft::ReactNative::LayoutDirection::RightToLeft) {
65
+ layoutConstraints.layoutDirection = facebook::react::LayoutDirection::RightToLeft;
66
+ }
67
+ }
68
+ }
69
+
70
+ // Laying out the `ShadowNode` and the subtree starting from it.
71
+ layoutableShadowNode.layoutTree(layoutContext, layoutConstraints);
72
+
73
+ auto childLayoutMetrics = layoutableShadowNode.getLayoutMetrics();
74
+ childLayoutMetrics.frame.origin = {0, 0};
75
+ layoutableShadowNode.setLayoutMetrics(childLayoutMetrics);
76
+
77
+ // Update the list of children to reflect the changes that we made.
78
+ this->children_ = static_cast<AbiPortalShadowNode *>(portalOwningShadowNode.get())->children_;
79
+ }
80
+
81
+ void AbiPortalShadowNode::Builder(winrt::Microsoft::ReactNative::IReactViewComponentBuilder builder) noexcept {
82
+ m_builder = builder;
83
+ }
84
+
85
+ winrt::Microsoft::ReactNative::IReactViewComponentBuilder AbiPortalShadowNode::Builder() const noexcept {
86
+ return m_builder;
87
+ }
88
+
89
+ void AbiPortalShadowNode::Proxy(winrt::Microsoft::ReactNative::ShadowNode proxy) noexcept {
90
+ m_proxy = proxy;
91
+ }
92
+
93
+ winrt::Microsoft::ReactNative::ShadowNode AbiPortalShadowNode::Proxy() const noexcept {
94
+ return m_proxy;
95
+ }
96
+
97
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,53 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <react/components/rnwcore/EventEmitters.h>
7
+ #include <unordered_map>
8
+ #include "AbiShadowNode.h"
9
+ #include "AbiState.h"
10
+ #include "AbiViewProps.h"
11
+
12
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
13
+ #include <react/renderer/core/LayoutContext.h>
14
+
15
+ namespace Microsoft::ReactNative {
16
+
17
+ extern const char AbiPortalComponentName[];
18
+
19
+ class AbiPortalShadowNode final : public facebook::react::ConcreteViewShadowNode<
20
+ AbiPortalComponentName,
21
+ AbiViewProps,
22
+ facebook::react::ViewEventEmitter,
23
+ Microsoft::ReactNative::AbiStateData> {
24
+ public:
25
+ using ConcreteViewShadowNode::ConcreteViewShadowNode;
26
+
27
+ static facebook::react::ShadowNodeTraits BaseTraits() {
28
+ auto traits = facebook::react::ShadowNode::BaseTraits();
29
+ traits.set(facebook::react::ShadowNodeTraits::Trait::FormsStackingContext);
30
+ traits.set(facebook::react::ShadowNodeTraits::Trait::FormsView);
31
+ traits.set(facebook::react::ShadowNodeTraits::Trait::RootNodeKind);
32
+ traits.set(facebook::react::ShadowNodeTraits::Trait::LeafYogaNode);
33
+ traits.set(facebook::react::ShadowNodeTraits::Trait::MeasurableYogaNode);
34
+ return traits;
35
+ }
36
+
37
+ facebook::react::Size measureContent(
38
+ const facebook::react::LayoutContext &layoutContext,
39
+ const facebook::react::LayoutConstraints &layoutConstraints) const override;
40
+ void layout(facebook::react::LayoutContext layoutContext) override;
41
+
42
+ void OnClone(const facebook::react::ShadowNode &sourceShadowNode) noexcept;
43
+ void Builder(winrt::Microsoft::ReactNative::IReactViewComponentBuilder builder) noexcept;
44
+ winrt::Microsoft::ReactNative::IReactViewComponentBuilder Builder() const noexcept;
45
+ void Proxy(winrt::Microsoft::ReactNative::ShadowNode handle) noexcept;
46
+ winrt::Microsoft::ReactNative::ShadowNode Proxy() const noexcept;
47
+
48
+ private:
49
+ winrt::Microsoft::ReactNative::ShadowNode m_proxy{nullptr};
50
+ winrt::Microsoft::ReactNative::IReactViewComponentBuilder m_builder{nullptr};
51
+ };
52
+
53
+ } // namespace Microsoft::ReactNative
@@ -3,16 +3,22 @@
3
3
 
4
4
  #pragma once
5
5
 
6
+ #include <Fabric/Composition/ReactCompositionViewComponentBuilder.h>
7
+ #include <Fabric/WindowsComponentDescriptorRegistry.h>
8
+ #include <ReactContext.h>
6
9
  #include <react/renderer/components/view/ConcreteViewShadowNode.h>
7
10
  #include <react/renderer/core/ComponentDescriptor.h>
11
+ #include "AbiPortalShadowNode.h"
8
12
  #include "AbiViewProps.h"
9
13
  #include "AbiViewShadowNode.h"
14
+ #include "DynamicReader.h"
10
15
  #include "winrt/Microsoft.ReactNative.h"
11
16
 
12
17
  namespace Microsoft::ReactNative {
13
18
 
14
- class AbiViewComponentDescriptor : public facebook::react::ComponentDescriptor {
15
- using ShadowNodeT = AbiViewShadowNode;
19
+ template <typename ShadowNodeT>
20
+ class ConcreteAbiViewComponentDescriptor : public facebook::react::ComponentDescriptor {
21
+ protected:
16
22
  using SharedShadowNodeT = std::shared_ptr<const ShadowNodeT>;
17
23
 
18
24
  public:
@@ -24,34 +30,142 @@ class AbiViewComponentDescriptor : public facebook::react::ComponentDescriptor {
24
30
  using ConcreteState = typename ShadowNodeT::ConcreteState;
25
31
  using ConcreteStateData = typename ShadowNodeT::ConcreteState::Data;
26
32
 
27
- AbiViewComponentDescriptor(facebook::react::ComponentDescriptorParameters const &parameters);
33
+ ConcreteAbiViewComponentDescriptor(facebook::react::ComponentDescriptorParameters const &parameters)
34
+ : ComponentDescriptor(parameters) {
35
+ auto flavor = std::static_pointer_cast<std::string const>(this->flavor_);
36
+ m_builder = WindowsComponentDescriptorRegistry::FromProperties(
37
+ parameters.contextContainer->at<winrt::Microsoft::ReactNative::ReactContext>("MSRN.ReactContext")
38
+ .Properties())
39
+ ->GetDescriptor(flavor);
40
+
41
+ rawPropsParser_.prepare<ConcreteProps>();
42
+ }
43
+ facebook::react::ComponentHandle getComponentHandle() const override {
44
+ return reinterpret_cast<facebook::react::ComponentHandle>(getComponentName());
45
+ }
46
+
47
+ facebook::react::ComponentName getComponentName() const override {
48
+ return std::static_pointer_cast<std::string const>(this->flavor_)->c_str();
49
+ }
50
+
51
+ facebook::react::ShadowNodeTraits getTraits() const override {
52
+ auto traits = ShadowNodeT::BaseTraits();
53
+ if (winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
54
+ ->MeasureContentHandler()) {
55
+ traits.set(facebook::react::ShadowNodeTraits::LeafYogaNode);
56
+ traits.set(facebook::react::ShadowNodeTraits::MeasurableYogaNode);
57
+ }
58
+ return traits;
59
+ }
28
60
 
29
- facebook::react::ComponentHandle getComponentHandle() const override;
30
- facebook::react::ComponentName getComponentName() const override;
31
- facebook::react::ShadowNodeTraits getTraits() const override;
32
61
  std::shared_ptr<facebook::react::ShadowNode> createShadowNode(
33
62
  const facebook::react::ShadowNodeFragment &fragment,
34
- facebook::react::ShadowNodeFamily::Shared const &family) const override;
63
+ facebook::react::ShadowNodeFamily::Shared const &family) const override {
64
+ auto shadowNode = std::make_shared<ShadowNodeT>(fragment, family, getTraits());
65
+ shadowNode->Proxy(winrt::make<winrt::Microsoft::ReactNative::implementation::YogaLayoutableShadowNode>(shadowNode));
66
+ winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
67
+ ->CreateShadowNode(shadowNode->Proxy());
68
+
69
+ adopt(*shadowNode);
70
+ return shadowNode;
71
+ }
72
+
35
73
  facebook::react::ShadowNode::Unshared cloneShadowNode(
36
74
  const facebook::react::ShadowNode &sourceShadowNode,
37
- const facebook::react::ShadowNodeFragment &fragment) const override;
75
+ const facebook::react::ShadowNodeFragment &fragment) const override {
76
+ auto shadowNode = std::make_shared<ShadowNodeT>(sourceShadowNode, fragment);
77
+ shadowNode->Proxy(winrt::make<winrt::Microsoft::ReactNative::implementation::YogaLayoutableShadowNode>(shadowNode));
78
+ winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
79
+ ->CloneShadowNode(shadowNode->Proxy(), static_cast<const ShadowNodeT &>(sourceShadowNode).Proxy());
80
+
81
+ adopt(*shadowNode);
82
+ return shadowNode;
83
+ }
38
84
 
39
85
  void appendChild(
40
86
  const facebook::react::ShadowNode::Shared &parentShadowNode,
41
- const facebook::react::ShadowNode::Shared &childShadowNode) const override;
87
+ const facebook::react::ShadowNode::Shared &childShadowNode) const override {
88
+ auto concreteParentShadowNode = std::static_pointer_cast<const ShadowNodeT>(parentShadowNode);
89
+ auto concreteNonConstParentShadowNode = std::const_pointer_cast<ShadowNodeT>(concreteParentShadowNode);
90
+ concreteNonConstParentShadowNode->appendChild(childShadowNode);
91
+ }
92
+
42
93
  virtual facebook::react::Props::Shared cloneProps(
43
94
  const facebook::react::PropsParserContext &context,
44
95
  const facebook::react::Props::Shared &props,
45
- facebook::react::RawProps rawProps) const override;
96
+ facebook::react::RawProps rawProps) const override {
97
+ // Optimization:
98
+ // Quite often nodes are constructed with default/empty props: the base
99
+ // `props` object is `null` (there no base because it's not cloning) and the
100
+ // `rawProps` is empty. In this case, we can return the default props object
101
+ // of a concrete type entirely bypassing parsing.
102
+ if (!props && rawProps.isEmpty()) {
103
+ return ShadowNodeT::defaultSharedProps();
104
+ }
105
+
106
+ if constexpr (facebook::react::RawPropsFilterable<ShadowNodeT>) {
107
+ ShadowNodeT::filterRawProps(rawProps);
108
+ }
109
+
110
+ rawProps.parse(rawPropsParser_);
111
+
112
+ // Call old-style constructor
113
+ // auto shadowNodeProps = std::make_shared<ShadowNodeT::Props>(context, rawProps, props);
114
+ auto shadowNodeProps = std::make_shared<AbiViewProps>(
115
+ context, props ? static_cast<AbiViewProps const &>(*props) : *ShadowNodeT::defaultSharedProps(), rawProps);
116
+ auto viewProps =
117
+ winrt::make<winrt::Microsoft::ReactNative::implementation::ViewProps>(shadowNodeProps, false /*holdRef*/);
118
+ auto userProps =
119
+ winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
120
+ ->CreateProps(viewProps, props ? static_cast<AbiViewProps const &>(*props).UserProps() : nullptr);
121
+ shadowNodeProps->SetUserProps(userProps, viewProps);
122
+
123
+ const auto &dynamic = static_cast<folly::dynamic>(rawProps);
124
+ for (const auto &pair : dynamic.items()) {
125
+ const auto &propName = pair.first.getString();
126
+ auto hash = RAW_PROPS_KEY_HASH(propName);
127
+ shadowNodeProps.get()->setProp(context, hash, propName.c_str(), facebook::react::RawValue(pair.second));
128
+ userProps.SetProp(
129
+ hash, winrt::to_hstring(propName), winrt::make<winrt::Microsoft::ReactNative::DynamicReader>(pair.second));
130
+ }
131
+ return shadowNodeProps;
132
+ }
133
+
46
134
  virtual facebook::react::State::Shared createInitialState(
47
135
  facebook::react::Props::Shared const &props,
48
- facebook::react::ShadowNodeFamily::Shared const &family) const override;
136
+ facebook::react::ShadowNodeFamily::Shared const &family) const override {
137
+ if (std::is_same<ConcreteStateData, facebook::react::StateData>::value) {
138
+ // Default case: Returning `null` for nodes that don't use `State`.
139
+ return nullptr;
140
+ }
141
+
142
+ return std::make_shared<ConcreteState>(
143
+ std::make_shared<ConcreteStateData const>(
144
+ ConcreteAbiViewComponentDescriptor<ShadowNodeT>::initialStateData(props, family, *this)),
145
+ family);
146
+ }
147
+
49
148
  virtual facebook::react::State::Shared createState(
50
149
  facebook::react::ShadowNodeFamily const &family,
51
- facebook::react::StateData::Shared const &data) const override;
150
+ facebook::react::StateData::Shared const &data) const override {
151
+ if (std::is_same<ConcreteStateData, facebook::react::StateData>::value) {
152
+ // Default case: Returning `null` for nodes that don't use `State`.
153
+ return nullptr;
154
+ }
155
+
156
+ react_native_assert(data && "Provided `data` is nullptr.");
157
+
158
+ return std::make_shared<ConcreteState const>(
159
+ std::static_pointer_cast<ConcreteStateData const>(data), *family.getMostRecentState());
160
+ }
52
161
 
53
162
  facebook::react::ShadowNodeFamily::Shared createFamily(
54
- facebook::react::ShadowNodeFamilyFragment const &fragment) const override;
163
+ facebook::react::ShadowNodeFamilyFragment const &fragment) const override {
164
+ auto eventEmitter = std::make_shared<const ConcreteEventEmitter>(
165
+ std::make_shared<facebook::react::EventTarget>(fragment.instanceHandle, fragment.surfaceId), eventDispatcher_);
166
+ return std::make_shared<facebook::react::ShadowNodeFamily>(
167
+ fragment, std::move(eventEmitter), eventDispatcher_, *this);
168
+ }
55
169
 
56
170
  protected:
57
171
  /*
@@ -66,15 +180,44 @@ class AbiViewComponentDescriptor : public facebook::react::ComponentDescriptor {
66
180
  * - Set `ShadowNode`'s size from state in
67
181
  * `ModalHostViewComponentDescriptor`.
68
182
  */
69
- virtual void adopt(facebook::react::ShadowNode &shadowNode) const;
183
+ virtual void adopt(facebook::react::ShadowNode &shadowNode) const {
184
+ react_native_assert(shadowNode.getComponentHandle() == getComponentHandle());
185
+
186
+ auto &abiViewShadowNode = static_cast<AbiViewShadowNode &>(shadowNode);
187
+
188
+ abiViewShadowNode.Builder(m_builder);
189
+
190
+ if (winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
191
+ ->MeasureContentHandler()) {
192
+ abiViewShadowNode.dirtyLayout();
193
+ abiViewShadowNode.enableMeasurement();
194
+ }
195
+ }
70
196
 
71
197
  private:
72
198
  static ConcreteStateData initialStateData(
73
- const facebook::react::Props::Shared & /*props*/,
199
+ const facebook::react::Props::Shared &props,
74
200
  const facebook::react::ShadowNodeFamily::Shared & /*family*/,
75
- const facebook::react::ComponentDescriptor & /*componentDescriptor*/) noexcept;
201
+ const facebook::react::ComponentDescriptor &componentDescriptor) noexcept {
202
+ return {winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(
203
+ static_cast<const ConcreteAbiViewComponentDescriptor<ShadowNodeT> &>(componentDescriptor).m_builder)
204
+ ->InitialStateData(std::static_pointer_cast<AbiViewProps const>(props)->UserProps())};
205
+ return {};
206
+ }
76
207
 
77
- winrt::Microsoft::ReactNative::IReactViewComponentBuilder m_builder;
208
+ winrt::Microsoft::ReactNative::IReactViewComponentBuilder m_builder{nullptr};
209
+ };
210
+
211
+ class AbiViewComponentDescriptor : public ConcreteAbiViewComponentDescriptor<AbiViewShadowNode> {
212
+ public:
213
+ AbiViewComponentDescriptor(facebook::react::ComponentDescriptorParameters const &parameters)
214
+ : ConcreteAbiViewComponentDescriptor<AbiViewShadowNode>(parameters) {}
215
+ };
216
+
217
+ class AbiPortalComponentDescriptor : public ConcreteAbiViewComponentDescriptor<AbiPortalShadowNode> {
218
+ public:
219
+ AbiPortalComponentDescriptor(facebook::react::ComponentDescriptorParameters const &parameters)
220
+ : ConcreteAbiViewComponentDescriptor<AbiPortalShadowNode>(parameters) {}
78
221
  };
79
222
 
80
223
  } // namespace Microsoft::ReactNative
@@ -77,14 +77,12 @@ winrt::Microsoft::ReactNative::Color Color::ReadValue(
77
77
  switch (reader.ValueType()) {
78
78
  case JSValueType::Int64: {
79
79
  auto argb = reader.GetInt64();
80
- return winrt::make<Color>(facebook::react::Color{
81
- /*m_isDefined*/ true,
82
- /*color*/
83
- {static_cast<uint8_t>((argb >> 24) & 0xFF),
84
- static_cast<uint8_t>((argb >> 16) & 0xFF),
85
- static_cast<uint8_t>((argb >> 8) & 0xFF),
86
- static_cast<uint8_t>(argb & 0xFF)},
87
- {}});
80
+ return winrt::make<Color>(facebook::react::Color{/*color*/
81
+ {static_cast<uint8_t>((argb >> 24) & 0xFF),
82
+ static_cast<uint8_t>((argb >> 16) & 0xFF),
83
+ static_cast<uint8_t>((argb >> 8) & 0xFF),
84
+ static_cast<uint8_t>(argb & 0xFF)},
85
+ {}});
88
86
  }
89
87
  case JSValueType::Object: {
90
88
  std::vector<std::string> platformColors;
@@ -96,10 +94,10 @@ winrt::Microsoft::ReactNative::Color Color::ReadValue(
96
94
  SkipValue<JSValue>(reader); // Skip this property
97
95
  }
98
96
  }
99
- return winrt::make<Color>(facebook::react::Color{/*m_isDefined*/ true, /*color*/ {}, std::move(platformColors)});
97
+ return winrt::make<Color>(facebook::react::Color{/*color*/ {}, std::move(platformColors)});
100
98
  }
101
99
  default:
102
- return winrt::make<Color>(facebook::react::Color{/*m_isDefined*/ false, /*color*/ {0, 0, 0, 0}, {}});
100
+ return winrt::make<Color>(facebook::react::Color{/*color*/ {0, 0, 0, 0}, {}});
103
101
  }
104
102
  }
105
103