react-native-windows 0.78.3 → 0.78.4

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 (29) hide show
  1. package/Libraries/Modal/Modal.windows.js +4 -1
  2. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.cpp +97 -0
  3. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.h +53 -0
  4. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +160 -17
  5. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +182 -14
  6. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.cpp +12 -0
  7. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +2 -1
  8. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +0 -1
  9. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +16 -14
  10. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +10 -1
  11. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  12. package/Shared/Networking/WinRTWebSocketResource.cpp +5 -0
  13. package/Shared/Shared.vcxitems +3 -3
  14. package/Shared/Shared.vcxitems.filters +1 -1
  15. package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +1 -1
  16. package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +1 -1
  17. package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +1 -1
  18. package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +1 -1
  19. package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +1 -1
  20. package/codegen/react/components/rnwcore/AndroidSwitch.g.h +1 -1
  21. package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +1 -1
  22. package/codegen/react/components/rnwcore/InputAccessory.g.h +1 -1
  23. package/codegen/react/components/rnwcore/ModalHostView.g.h +1 -1
  24. package/codegen/react/components/rnwcore/PullToRefreshView.g.h +1 -1
  25. package/codegen/react/components/rnwcore/SafeAreaView.g.h +1 -1
  26. package/codegen/react/components/rnwcore/Switch.g.h +1 -1
  27. package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +1 -1
  28. package/package.json +3 -3
  29. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +0 -191
@@ -290,8 +290,11 @@ class Modal extends React.Component<Props, State> {
290
290
  }
291
291
  }
292
292
 
293
+ // [Windows] - apply empty rootViewStyle to AppContainer to prevent modal from always expanding to fill available space
293
294
  const innerChildren = __DEV__ ? (
294
- <AppContainer rootTag={this.context}>{this.props.children}</AppContainer>
295
+ <AppContainer rootTag={this.context} rootViewStyle={{}}>
296
+ {this.props.children}
297
+ </AppContainer>
295
298
  ) : (
296
299
  this.props.children
297
300
  );
@@ -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
@@ -14,6 +14,24 @@
14
14
 
15
15
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
16
16
 
17
+ struct ModalHostState
18
+ : winrt::implements<ModalHostState, winrt::Microsoft::ReactNative::Composition::IPortalStateData> {
19
+ ModalHostState(winrt::Microsoft::ReactNative::LayoutConstraints layoutConstraints, float scaleFactor)
20
+ : m_layoutConstraints(layoutConstraints), m_pointScaleFactor(scaleFactor) {}
21
+
22
+ winrt::Microsoft::ReactNative::LayoutConstraints LayoutConstraints() const noexcept {
23
+ return m_layoutConstraints;
24
+ }
25
+
26
+ float PointScaleFactor() const noexcept {
27
+ return m_pointScaleFactor;
28
+ }
29
+
30
+ private:
31
+ float m_pointScaleFactor{1.0f};
32
+ winrt::Microsoft::ReactNative::LayoutConstraints m_layoutConstraints;
33
+ };
34
+
17
35
  struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::Foundation::IInspectable>,
18
36
  ::Microsoft::ReactNativeSpecs::BaseModalHostView<ModalHostView> {
19
37
  ~ModalHostView() {
@@ -37,6 +55,13 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
37
55
  m_window.Destroy();
38
56
  m_window = nullptr;
39
57
  }
58
+
59
+ #ifdef USE_EXPERIMENTAL_WINUI3
60
+ if (m_popUp) {
61
+ m_popUp.Close();
62
+ m_popUp = nullptr;
63
+ }
64
+ #endif
40
65
  }
41
66
 
42
67
  void InitializePortalViewComponent(
@@ -65,13 +90,32 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
65
90
  ::Microsoft::ReactNativeSpecs::BaseModalHostView<ModalHostView>::UpdateProps(view, newProps, oldProps);
66
91
  }
67
92
 
68
- void UpdateLayoutMetrics(
69
- const winrt::Microsoft::ReactNative::ComponentView &view,
70
- const winrt::Microsoft::ReactNative::LayoutMetrics &newLayoutMetrics,
71
- const winrt::Microsoft::ReactNative::LayoutMetrics & /*oldLayoutMetrics*/) noexcept override {
72
- if (m_window) {
73
- AdjustWindowSize(newLayoutMetrics);
74
- }
93
+ void UpdateState(
94
+ const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
95
+ const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept override {
96
+ m_state = newState;
97
+ }
98
+
99
+ void MountChildComponentView(
100
+ const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
101
+ const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &args) noexcept override {
102
+ AdjustWindowSize(args.Child().LayoutMetrics());
103
+ assert(!m_childLayoutMetricsToken);
104
+ m_childLayoutMetricsToken = args.Child().LayoutMetricsChanged(
105
+ [wkThis = get_weak()](
106
+ auto &sender, const winrt::Microsoft::ReactNative::LayoutMetricsChangedArgs &layoutMetricsChangedArgs) {
107
+ if (auto strongThis = wkThis.get()) {
108
+ strongThis->AdjustWindowSize(layoutMetricsChangedArgs.NewLayoutMetrics());
109
+ }
110
+ });
111
+ }
112
+
113
+ void UnmountChildComponentView(
114
+ const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
115
+ const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &args) noexcept override {
116
+ assert(m_childLayoutMetricsToken);
117
+ args.Child().LayoutMetricsChanged(m_childLayoutMetricsToken);
118
+ m_childLayoutMetricsToken.value = 0;
75
119
  }
76
120
 
77
121
  void FinalizeUpdate(
@@ -85,7 +129,6 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
85
129
  private:
86
130
  void OnMounted(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
87
131
  m_mounted = true;
88
-
89
132
  if (m_showQueued) {
90
133
  ShowOnUIThread(view);
91
134
  }
@@ -96,6 +139,14 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
96
139
  }
97
140
 
98
141
  void AdjustWindowSize(const winrt::Microsoft::ReactNative::LayoutMetrics &layoutMetrics) noexcept {
142
+ #ifdef USE_EXPERIMENTAL_WINUI3
143
+ if (!m_popUp) {
144
+ #else
145
+ if (!m_window) {
146
+ #endif
147
+ return;
148
+ }
149
+
99
150
  if (layoutMetrics.Frame.Width == 0 && layoutMetrics.Frame.Height == 0) {
100
151
  return;
101
152
  }
@@ -108,11 +159,23 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
108
159
  int32_t yCor = static_cast<int32_t>(
109
160
  (parentRC.top + parentRC.bottom - layoutMetrics.Frame.Height * layoutMetrics.PointScaleFactor) / 2);
110
161
 
162
+ #ifdef USE_EXPERIMENTAL_WINUI3
163
+ winrt::Windows::Graphics::RectInt32 rect2{
164
+ (int)xCor,
165
+ (int)yCor,
166
+ static_cast<int32_t>(layoutMetrics.Frame.Width * (layoutMetrics.PointScaleFactor)),
167
+ static_cast<int32_t>(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor))};
168
+ m_popUp.MoveAndResize(rect2);
169
+ #else
170
+ // Fix for https://github.com/microsoft/microsoft-ui-xaml/issues/9529
171
+ auto titleBarHeight = m_window.TitleBar().Height();
172
+
111
173
  // Adjust window position and size
112
174
  m_window.ResizeClient(
113
175
  {static_cast<int32_t>(layoutMetrics.Frame.Width * (layoutMetrics.PointScaleFactor)),
114
- static_cast<int32_t>(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor))});
176
+ static_cast<int32_t>(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor)) - titleBarHeight});
115
177
  m_window.Move({xCor, yCor});
178
+ #endif
116
179
  };
117
180
 
118
181
  void ShowOnUIThread(const winrt::Microsoft::ReactNative::ComponentView &view) {
@@ -122,6 +185,24 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
122
185
  m_showQueued = false;
123
186
  EnsureModalCreated(view);
124
187
 
188
+ #ifdef USE_EXPERIMENTAL_WINUI3
189
+ if (m_popUp) {
190
+ m_bridge.Enable();
191
+ m_popUp.Show();
192
+
193
+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(
194
+ m_popUp.as<winrt::Microsoft::UI::Content::IContentSiteBridge>());
195
+ auto result = navHost.NavigateFocus(winrt::Microsoft::UI::Input::FocusNavigationRequest::Create(
196
+ winrt::Microsoft::UI::Input::FocusNavigationReason::First));
197
+
198
+ // dispatch onShow event
199
+ if (auto eventEmitter = EventEmitter()) {
200
+ ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnShow eventArgs;
201
+ eventEmitter->onShow(eventArgs);
202
+ }
203
+ }
204
+ #endif
205
+
125
206
  if (m_window && !m_window.IsVisible()) {
126
207
  m_bridge.Enable();
127
208
  m_window.Show(true);
@@ -146,6 +227,12 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
146
227
  m_window.Hide();
147
228
  }
148
229
 
230
+ #ifdef USE_EXPERIMENTAL_WINUI3
231
+ if (m_popUp) {
232
+ m_popUp.Hide();
233
+ }
234
+ #endif
235
+
149
236
  // dispatch onDismiss event
150
237
  if (auto eventEmitter = EventEmitter()) {
151
238
  ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnDismiss eventArgs;
@@ -168,6 +255,11 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
168
255
  return;
169
256
  }
170
257
 
258
+ #ifdef USE_EXPERIMENTAL_WINUI3
259
+ if (m_popUp) {
260
+ return;
261
+ }
262
+ #endif
171
263
  // get the root hwnd
172
264
  m_prevWindowID =
173
265
  winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(view.ReactContext().Properties());
@@ -175,6 +267,34 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
175
267
  m_parentHwnd =
176
268
  view.as<::Microsoft::ReactNative::Composition::Experimental::IComponentViewInterop>()->GetHwndForParenting();
177
269
 
270
+ auto portal = view.as<winrt::Microsoft::ReactNative::Composition::PortalComponentView>();
271
+
272
+ #ifdef USE_EXPERIMENTAL_WINUI3
273
+ m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
274
+ view.Parent().as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Compositor(),
275
+ winrt::Microsoft::UI::GetWindowIdFromWindow(m_parentHwnd));
276
+ m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal(portal);
277
+ auto contentIsland = m_reactNativeIsland.Island();
278
+
279
+ m_popUp = m_bridge.TryCreatePopupSiteBridge();
280
+ m_popUp.Connect(contentIsland);
281
+
282
+ // set the top-level windows as the new hwnd
283
+ winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
284
+ view.ReactContext().Properties(),
285
+ reinterpret_cast<uint64_t>(winrt::Microsoft::UI::GetWindowFromWindowId(m_popUp.WindowId())));
286
+
287
+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(
288
+ m_popUp.as<winrt::Microsoft::UI::Content::IContentSiteBridge>());
289
+ m_departFocusToken = navHost.DepartFocusRequested(
290
+ [wkView = winrt::make_weak(view)](
291
+ const auto &sender, const winrt::Microsoft::UI::Input::FocusNavigationRequestEventArgs &args) {
292
+ if (auto strongView = wkView.get()) {
293
+ TrySetFocus(strongView.Parent());
294
+ }
295
+ });
296
+
297
+ #else
178
298
  auto presenter = winrt::Microsoft::UI::Windowing::OverlappedPresenter::CreateForDialog();
179
299
  presenter.SetBorderAndTitleBar(true, false);
180
300
  presenter.IsModal(true);
@@ -190,8 +310,7 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
190
310
  // create a react native island - code taken from CompositionHwndHost
191
311
  m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
192
312
  view.Parent().as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Compositor(), m_window.Id());
193
- m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal(
194
- view.as<winrt::Microsoft::ReactNative::Composition::PortalComponentView>());
313
+ m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal(portal);
195
314
  auto contentIsland = m_reactNativeIsland.Island();
196
315
 
197
316
  auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(m_bridge);
@@ -202,13 +321,56 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
202
321
  TrySetFocus(strongView.Parent());
203
322
  }
204
323
  });
205
-
206
- m_bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
207
324
  m_bridge.Connect(contentIsland);
208
- AdjustWindowSize(view.LayoutMetrics());
325
+ #endif
326
+ m_bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
327
+
328
+ m_islandStateChangedToken =
329
+ contentIsland.StateChanged([weakThis = get_weak()](
330
+ winrt::Microsoft::UI::Content::ContentIsland const &island,
331
+ winrt::Microsoft::UI::Content::ContentIslandStateChangedEventArgs const &args) {
332
+ if (auto pThis = weakThis.get()) {
333
+ if (args.DidRasterizationScaleChange() || args.DidLayoutDirectionChange()) {
334
+ pThis->UpdateConstraints();
335
+ }
336
+ }
337
+ });
338
+
339
+ UpdateConstraints();
340
+
341
+ if (portal.ContentRoot().Children().Size()) {
342
+ AdjustWindowSize(portal.ContentRoot().Children().GetAt(0).LayoutMetrics());
343
+ }
209
344
  m_bridge.Show();
210
345
  }
211
346
 
347
+ void UpdateConstraints() noexcept {
348
+ auto displayArea = winrt::Microsoft::UI::Windowing::DisplayArea::GetFromDisplayId(
349
+ m_bridge.SiteView().EnvironmentView().DisplayId());
350
+ auto workArea = displayArea.WorkArea();
351
+
352
+ float scale = m_reactNativeIsland.Island().RasterizationScale();
353
+
354
+ winrt::Microsoft::ReactNative::LayoutConstraints constraints;
355
+ constraints.MinimumSize = {0, 0};
356
+ // Constrain the size of the modal to 90% of the screen size
357
+ constraints.MaximumSize = {
358
+ static_cast<float>((workArea.Width / scale) * 0.9), static_cast<float>((workArea.Height / scale) * 0.9)};
359
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
360
+
361
+ auto layoutDirection = m_reactNativeIsland.Island().LayoutDirection();
362
+ if (layoutDirection == winrt::Microsoft::UI::Content::ContentLayoutDirection::LeftToRight)
363
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::LeftToRight;
364
+ else if (layoutDirection == winrt::Microsoft::UI::Content::ContentLayoutDirection::RightToLeft)
365
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::RightToLeft;
366
+
367
+ // By setting a custom contraint here the behavior of the modal slightly changes.
368
+ // When no constraint is set (maxSize is std::numeric_limits<Float>::infinity()), yoga will layout the content to a
369
+ // desired size If we provide a specific max size, then contents with a flex:1 will expand to fill that size. We
370
+ // might want to provide a windows specific property to control this behavior.
371
+ m_state.UpdateState(winrt::make<ModalHostState>(constraints, m_reactNativeIsland.Island().RasterizationScale()));
372
+ }
373
+
212
374
  static void TrySetFocus(const winrt::Microsoft::ReactNative::ComponentView &view) {
213
375
  auto focusController = winrt::Microsoft::UI::Input::InputFocusController::GetForIsland(
214
376
  view.as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Root().ReactNativeIsland().Island());
@@ -222,10 +384,16 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
222
384
  bool m_showTitleBar{false};
223
385
  bool m_showQueued{false};
224
386
  bool m_mounted{false};
387
+ winrt::event_token m_islandStateChangedToken;
225
388
  winrt::Microsoft::UI::Input::InputFocusNavigationHost::DepartFocusRequested_revoker m_departFocusRevoker;
226
389
  winrt::event_token m_departFocusToken;
390
+ winrt::event_token m_childLayoutMetricsToken;
391
+ winrt::Microsoft::ReactNative::IComponentState m_state{nullptr};
227
392
  winrt::Microsoft::UI::Content::DesktopChildSiteBridge m_bridge{nullptr};
228
393
  winrt::Microsoft::ReactNative::ReactNativeIsland m_reactNativeIsland{nullptr};
394
+ #ifdef USE_EXPERIMENTAL_WINUI3
395
+ winrt::Microsoft::UI::Content::PopupWindowSiteBridge m_popUp{nullptr};
396
+ #endif
229
397
  };
230
398
 
231
399
  void RegisterWindowsModalHostNativeComponent(
@@ -30,11 +30,23 @@ void PortalComponentView::MountChildComponentView(
30
30
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
31
31
  uint32_t index) noexcept {
32
32
  m_rootComponentView->MountChildComponentView(childComponentView, index);
33
+ if (m_builder && m_builder->MountChildComponentViewHandler()) {
34
+ m_builder->MountChildComponentViewHandler()(
35
+ *this,
36
+ winrt::make<winrt::Microsoft::ReactNative::implementation::MountChildComponentViewArgs>(
37
+ childComponentView, index));
38
+ }
33
39
  }
34
40
 
35
41
  void PortalComponentView::UnmountChildComponentView(
36
42
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
37
43
  uint32_t index) noexcept {
44
+ if (m_builder && m_builder->UnmountChildComponentViewHandler()) {
45
+ m_builder->UnmountChildComponentViewHandler()(
46
+ *this,
47
+ winrt::make<winrt::Microsoft::ReactNative::implementation::UnmountChildComponentViewArgs>(
48
+ childComponentView, index));
49
+ }
38
50
  m_rootComponentView->UnmountChildComponentView(childComponentView, index);
39
51
  }
40
52
 
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include "pch.h"
5
5
  #include "ReactCompositionViewComponentBuilder.h"
6
+ #include <Fabric/AbiViewComponentDescriptor.h>
6
7
  #include <Fabric/Composition/CompositionViewComponentView.h>
7
8
  #include <Fabric/Composition/ContentIslandComponentView.h>
8
9
  #include <Fabric/Composition/PortalComponentView.h>
@@ -128,7 +129,7 @@ void ReactCompositionViewComponentBuilder::SetPortalComponentViewInitializer(
128
129
  };
129
130
  m_descriptorConstructorFactory = []() {
130
131
  return &facebook::react::concreteComponentDescriptorConstructor<
131
- ::Microsoft::ReactNative::AbiViewComponentDescriptor>;
132
+ ::Microsoft::ReactNative::AbiPortalComponentDescriptor>;
132
133
  };
133
134
  }
134
135
 
@@ -3,7 +3,6 @@
3
3
  // Licensed under the MIT License.
4
4
 
5
5
  #include <Fabric/AbiComponentDescriptor.h>
6
- #include <Fabric/AbiViewComponentDescriptor.h>
7
6
  #include <react/renderer/componentregistry/ComponentDescriptorProvider.h>
8
7
  #include <react/renderer/core/ReactPrimitives.h>
9
8
  #include "winrt/Microsoft.ReactNative.Composition.Experimental.h"
@@ -913,21 +913,23 @@ winrt::Microsoft::UI::Content::ContentIsland ReactNativeIsland::Island() {
913
913
  }
914
914
  });
915
915
  #ifdef USE_EXPERIMENTAL_WINUI3
916
- m_islandConnectedToken = m_island.Connected(
917
- [weakThis = get_weak()](
918
- winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) {
919
- if (auto pThis = weakThis.get()) {
920
- pThis->OnMounted();
921
- }
922
- });
916
+ if (!m_isFragment) {
917
+ m_islandConnectedToken = m_island.Connected(
918
+ [weakThis = get_weak()](
919
+ winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) {
920
+ if (auto pThis = weakThis.get()) {
921
+ pThis->OnMounted();
922
+ }
923
+ });
923
924
 
924
- m_islandDisconnectedToken = m_island.Disconnected(
925
- [weakThis = get_weak()](
926
- winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) {
927
- if (auto pThis = weakThis.get()) {
928
- pThis->OnUnmounted();
929
- }
930
- });
925
+ m_islandDisconnectedToken = m_island.Disconnected(
926
+ [weakThis = get_weak()](
927
+ winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) {
928
+ if (auto pThis = weakThis.get()) {
929
+ pThis->OnUnmounted();
930
+ }
931
+ });
932
+ }
931
933
  #endif
932
934
  }
933
935
  return m_island;
@@ -52,6 +52,15 @@ namespace Microsoft.ReactNative.Composition
52
52
  };
53
53
  }
54
54
 
55
+ [webhosthidden]
56
+ [experimental]
57
+ DOC_STRING("StateData type to be used with a PortalComponentView. The LayoutConstraints and PointScaleFactor will be used to layout the content of the Portal")
58
+ interface IPortalStateData
59
+ {
60
+ Microsoft.ReactNative.LayoutConstraints LayoutConstraints { get; };
61
+ Single PointScaleFactor { get; };
62
+ };
63
+
55
64
  [webhosthidden]
56
65
  [experimental]
57
66
  DOC_STRING(".")
@@ -66,4 +75,4 @@ namespace Microsoft.ReactNative.Composition
66
75
  void SetVisualToMountChildrenIntoHandler(VisualToMountChildrenIntoDelegate impl);
67
76
  };
68
77
 
69
- } // namespace Microsoft.ReactNative
78
+ } // namespace Microsoft.ReactNative.Composition
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.78.3</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.78.4</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>78</ReactNativeWindowsMinor>
16
- <ReactNativeWindowsPatch>3</ReactNativeWindowsPatch>
16
+ <ReactNativeWindowsPatch>4</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>04930ad6dce2cbc6d2e5d79760b13b77443912e4</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>91955927907b66ed843ba6be7b9a0af891fd8305</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
@@ -290,6 +290,10 @@ fire_and_forget WinRTWebSocketResource2::PerformWrite(string &&message, bool isB
290
290
  }
291
291
 
292
292
  IAsyncAction WinRTWebSocketResource2::SendPendingMessages() noexcept {
293
+ // Enforcing execution in the background queue.
294
+ // Awaiting of this coroutine will schedule its execution in the thread pool, ignoring the intended dispatch queue.
295
+ co_await resume_in_queue(m_backgroundQueue);
296
+
293
297
  auto self = shared_from_this();
294
298
 
295
299
  while (!self->m_outgoingMessages.empty()) {
@@ -334,6 +338,7 @@ IAsyncAction WinRTWebSocketResource2::SendPendingMessages() noexcept {
334
338
  auto result = async.ErrorCode();
335
339
  if (result < 0) {
336
340
  Fail(std::move(result), ErrorType::Send);
341
+ co_return;
337
342
  }
338
343
  }
339
344
  }
@@ -168,9 +168,6 @@
168
168
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiComponentDescriptor.cpp">
169
169
  <ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
170
170
  </ClCompile>
171
- <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiViewComponentDescriptor.cpp">
172
- <ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
173
- </ClCompile>
174
171
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiEventEmitter.cpp">
175
172
  <ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
176
173
  </ClCompile>
@@ -180,6 +177,9 @@
180
177
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiShadowNode.cpp">
181
178
  <ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
182
179
  </ClCompile>
180
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiPortalShadowNode.cpp">
181
+ <ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
182
+ </ClCompile>
183
183
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiViewShadowNode.cpp">
184
184
  <ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
185
185
  </ClCompile>
@@ -239,7 +239,6 @@
239
239
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\PortalComponentView.cpp" />
240
240
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\RootComponentView.cpp" />
241
241
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\UnimplementedNativeViewComponentView.cpp" />
242
- <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiViewComponentDescriptor.cpp" />
243
242
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiViewProps.cpp" />
244
243
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\WindowsComponentDescriptorRegistry.cpp" />
245
244
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\UiaHelpers.cpp" />
@@ -293,6 +292,7 @@
293
292
  <ClCompile Include="$(ReactNativeDir)\ReactCommon\react\renderer\runtimescheduler\Task.cpp" />
294
293
  <ClCompile Include="$(ReactNativeDir)\ReactCommon\react\renderer\components\scrollview\ScrollEvent.cpp" />
295
294
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\platform\react\renderer\graphics\PlatformColorUtils.cpp" />
295
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiPortalShadowNode.cpp" />
296
296
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiViewShadowNode.cpp" />
297
297
  <ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiState.cpp" />
298
298
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Utils\ThemeUtils.cpp" />
@@ -165,7 +165,7 @@ void RegisterActivityIndicatorViewNativeComponent(
165
165
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
166
166
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
167
167
  auto userData = view.UserData().as<TUserData>();
168
- userData->member(view, newState);
168
+ userData->UpdateState(view, newState);
169
169
  });
170
170
  }
171
171
 
@@ -242,7 +242,7 @@ void RegisterAndroidDrawerLayoutNativeComponent(
242
242
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
243
243
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
244
244
  auto userData = view.UserData().as<TUserData>();
245
- userData->member(view, newState);
245
+ userData->UpdateState(view, newState);
246
246
  });
247
247
  }
248
248
 
@@ -153,7 +153,7 @@ void RegisterAndroidHorizontalScrollContentViewNativeComponent(
153
153
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
154
154
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
155
155
  auto userData = view.UserData().as<TUserData>();
156
- userData->member(view, newState);
156
+ userData->UpdateState(view, newState);
157
157
  });
158
158
  }
159
159
 
@@ -177,7 +177,7 @@ void RegisterAndroidProgressBarNativeComponent(
177
177
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
178
178
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
179
179
  auto userData = view.UserData().as<TUserData>();
180
- userData->member(view, newState);
180
+ userData->UpdateState(view, newState);
181
181
  });
182
182
  }
183
183
 
@@ -197,7 +197,7 @@ void RegisterAndroidSwipeRefreshLayoutNativeComponent(
197
197
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
198
198
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
199
199
  auto userData = view.UserData().as<TUserData>();
200
- userData->member(view, newState);
200
+ userData->UpdateState(view, newState);
201
201
  });
202
202
  }
203
203
 
@@ -214,7 +214,7 @@ void RegisterAndroidSwitchNativeComponent(
214
214
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
215
215
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
216
216
  auto userData = view.UserData().as<TUserData>();
217
- userData->member(view, newState);
217
+ userData->UpdateState(view, newState);
218
218
  });
219
219
  }
220
220
 
@@ -181,7 +181,7 @@ void RegisterDebuggingOverlayNativeComponent(
181
181
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
182
182
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
183
183
  auto userData = view.UserData().as<TUserData>();
184
- userData->member(view, newState);
184
+ userData->UpdateState(view, newState);
185
185
  });
186
186
  }
187
187
 
@@ -153,7 +153,7 @@ void RegisterInputAccessoryNativeComponent(
153
153
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
154
154
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
155
155
  auto userData = view.UserData().as<TUserData>();
156
- userData->member(view, newState);
156
+ userData->UpdateState(view, newState);
157
157
  });
158
158
  }
159
159
 
@@ -236,7 +236,7 @@ void RegisterModalHostViewNativeComponent(
236
236
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
237
237
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
238
238
  auto userData = view.UserData().as<TUserData>();
239
- userData->member(view, newState);
239
+ userData->UpdateState(view, newState);
240
240
  });
241
241
  }
242
242
 
@@ -193,7 +193,7 @@ void RegisterPullToRefreshViewNativeComponent(
193
193
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
194
194
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
195
195
  auto userData = view.UserData().as<TUserData>();
196
- userData->member(view, newState);
196
+ userData->UpdateState(view, newState);
197
197
  });
198
198
  }
199
199
 
@@ -150,7 +150,7 @@ void RegisterSafeAreaViewNativeComponent(
150
150
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
151
151
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
152
152
  auto userData = view.UserData().as<TUserData>();
153
- userData->member(view, newState);
153
+ userData->UpdateState(view, newState);
154
154
  });
155
155
  }
156
156
 
@@ -210,7 +210,7 @@ void RegisterSwitchNativeComponent(
210
210
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
211
211
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
212
212
  auto userData = view.UserData().as<TUserData>();
213
- userData->member(view, newState);
213
+ userData->UpdateState(view, newState);
214
214
  });
215
215
  }
216
216
 
@@ -153,7 +153,7 @@ void RegisterUnimplementedNativeViewNativeComponent(
153
153
  builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
154
154
  const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
155
155
  auto userData = view.UserData().as<TUserData>();
156
- userData->member(view, newState);
156
+ userData->UpdateState(view, newState);
157
157
  });
158
158
  }
159
159
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.78.3",
3
+ "version": "0.78.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "@react-native-community/cli": "^15.0.0",
27
27
  "@react-native-community/cli-platform-android": "^15.0.0",
28
28
  "@react-native-community/cli-platform-ios": "^15.0.0",
29
- "@react-native-windows/cli": "0.78.1",
29
+ "@react-native-windows/cli": "0.78.2",
30
30
  "@react-native/assets": "1.0.0",
31
31
  "@react-native/assets-registry": "0.78.0",
32
32
  "@react-native/codegen": "0.78.0",
@@ -68,7 +68,7 @@
68
68
  "yargs": "^17.6.2"
69
69
  },
70
70
  "devDependencies": {
71
- "@react-native-windows/codegen": "0.78.0",
71
+ "@react-native-windows/codegen": "0.78.1",
72
72
  "@react-native/metro-config": "0.78.0-nightly-20241231-a3c8e2137",
73
73
  "@rnw-scripts/babel-react-native-config": "0.0.0",
74
74
  "@rnw-scripts/eslint-config": "1.2.32",
@@ -1,191 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
-
4
- #include "pch.h"
5
-
6
- #include "AbiViewComponentDescriptor.h"
7
-
8
- #include <Fabric/WindowsComponentDescriptorRegistry.h>
9
- #include <ReactContext.h>
10
- #include <react/renderer/components/view/ViewPropsInterpolation.h>
11
- #include <type_traits>
12
- #include "DynamicReader.h"
13
-
14
- namespace Microsoft::ReactNative {
15
-
16
- AbiViewComponentDescriptor::AbiViewComponentDescriptor(facebook::react::ComponentDescriptorParameters const &parameters)
17
- : ComponentDescriptor(parameters) {
18
- auto flavor = std::static_pointer_cast<std::string const>(this->flavor_);
19
- m_builder = WindowsComponentDescriptorRegistry::FromProperties(
20
- parameters.contextContainer->at<winrt::Microsoft::ReactNative::ReactContext>("MSRN.ReactContext")
21
- .Properties())
22
- ->GetDescriptor(flavor);
23
-
24
- rawPropsParser_.prepare<ConcreteProps>();
25
- }
26
-
27
- facebook::react::ComponentHandle AbiViewComponentDescriptor::getComponentHandle() const {
28
- return reinterpret_cast<facebook::react::ComponentHandle>(getComponentName());
29
- }
30
-
31
- facebook::react::ComponentName AbiViewComponentDescriptor::getComponentName() const {
32
- return std::static_pointer_cast<std::string const>(this->flavor_)->c_str();
33
- }
34
-
35
- facebook::react::ShadowNodeTraits AbiViewComponentDescriptor::getTraits() const {
36
- auto traits = ShadowNodeT::BaseTraits();
37
- if (winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
38
- ->MeasureContentHandler()) {
39
- traits.set(facebook::react::ShadowNodeTraits::LeafYogaNode);
40
- traits.set(facebook::react::ShadowNodeTraits::MeasurableYogaNode);
41
- }
42
- return traits;
43
- }
44
-
45
- std::shared_ptr<facebook::react::ShadowNode> AbiViewComponentDescriptor::createShadowNode(
46
- const facebook::react::ShadowNodeFragment &fragment,
47
- facebook::react::ShadowNodeFamily::Shared const &family) const {
48
- auto shadowNode = std::make_shared<ShadowNodeT>(fragment, family, getTraits());
49
-
50
- shadowNode->Proxy(winrt::make<winrt::Microsoft::ReactNative::implementation::YogaLayoutableShadowNode>(shadowNode));
51
- winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
52
- ->CreateShadowNode(shadowNode->Proxy());
53
-
54
- adopt(*shadowNode);
55
- return shadowNode;
56
- }
57
-
58
- facebook::react::ShadowNode::Unshared AbiViewComponentDescriptor::cloneShadowNode(
59
- const facebook::react::ShadowNode &sourceShadowNode,
60
- const facebook::react::ShadowNodeFragment &fragment) const {
61
- auto shadowNode = std::make_shared<ShadowNodeT>(sourceShadowNode, fragment);
62
-
63
- shadowNode->Proxy(winrt::make<winrt::Microsoft::ReactNative::implementation::YogaLayoutableShadowNode>(shadowNode));
64
- winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
65
- ->CloneShadowNode(shadowNode->Proxy(), static_cast<const ShadowNodeT &>(sourceShadowNode).Proxy());
66
-
67
- adopt(*shadowNode);
68
- return shadowNode;
69
- }
70
-
71
- void AbiViewComponentDescriptor::appendChild(
72
- const facebook::react::ShadowNode::Shared &parentShadowNode,
73
- const facebook::react::ShadowNode::Shared &childShadowNode) const {
74
- auto concreteParentShadowNode = std::static_pointer_cast<const ShadowNodeT>(parentShadowNode);
75
- auto concreteNonConstParentShadowNode = std::const_pointer_cast<ShadowNodeT>(concreteParentShadowNode);
76
- concreteNonConstParentShadowNode->appendChild(childShadowNode);
77
- }
78
-
79
- facebook::react::Props::Shared AbiViewComponentDescriptor::cloneProps(
80
- const facebook::react::PropsParserContext &context,
81
- const facebook::react::Props::Shared &props,
82
- facebook::react::RawProps rawProps) const {
83
- // Optimization:
84
- // Quite often nodes are constructed with default/empty props: the base
85
- // `props` object is `null` (there no base because it's not cloning) and the
86
- // `rawProps` is empty. In this case, we can return the default props object
87
- // of a concrete type entirely bypassing parsing.
88
- if (!props && rawProps.isEmpty()) {
89
- return ShadowNodeT::defaultSharedProps();
90
- }
91
-
92
- if constexpr (facebook::react::RawPropsFilterable<ShadowNodeT>) {
93
- ShadowNodeT::filterRawProps(rawProps);
94
- }
95
-
96
- rawProps.parse(rawPropsParser_);
97
-
98
- // Call old-style constructor
99
- // auto shadowNodeProps = std::make_shared<ShadowNodeT::Props>(context, rawProps, props);
100
- auto shadowNodeProps = std::make_shared<AbiViewProps>(
101
- context, props ? static_cast<AbiViewProps const &>(*props) : *ShadowNodeT::defaultSharedProps(), rawProps);
102
- auto viewProps =
103
- winrt::make<winrt::Microsoft::ReactNative::implementation::ViewProps>(shadowNodeProps, false /*holdRef*/);
104
- auto userProps =
105
- winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
106
- ->CreateProps(viewProps, props ? static_cast<AbiViewProps const &>(*props).UserProps() : nullptr);
107
- shadowNodeProps->SetUserProps(userProps, viewProps);
108
-
109
- const auto &dynamic = static_cast<folly::dynamic>(rawProps);
110
- for (const auto &pair : dynamic.items()) {
111
- const auto &propName = pair.first.getString();
112
- auto hash = RAW_PROPS_KEY_HASH(propName);
113
- shadowNodeProps.get()->setProp(context, hash, propName.c_str(), facebook::react::RawValue(pair.second));
114
- userProps.SetProp(
115
- hash, winrt::to_hstring(propName), winrt::make<winrt::Microsoft::ReactNative::DynamicReader>(pair.second));
116
- }
117
-
118
- return shadowNodeProps;
119
- };
120
-
121
- AbiViewComponentDescriptor::ConcreteStateData AbiViewComponentDescriptor::initialStateData(
122
- const facebook::react::Props::Shared &props,
123
- const facebook::react::ShadowNodeFamily::Shared & /*family*/,
124
- const facebook::react::ComponentDescriptor &componentDescriptor) noexcept {
125
- return {winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(
126
- static_cast<const AbiViewComponentDescriptor &>(componentDescriptor).m_builder)
127
- ->InitialStateData(std::static_pointer_cast<AbiViewProps const>(props)->UserProps())};
128
- }
129
-
130
- facebook::react::State::Shared AbiViewComponentDescriptor::createInitialState(
131
- facebook::react::Props::Shared const &props,
132
- facebook::react::ShadowNodeFamily::Shared const &family) const {
133
- if (std::is_same<ConcreteStateData, facebook::react::StateData>::value) {
134
- // Default case: Returning `null` for nodes that don't use `State`.
135
- return nullptr;
136
- }
137
-
138
- return std::make_shared<ConcreteState>(
139
- std::make_shared<ConcreteStateData const>(AbiViewComponentDescriptor::initialStateData(props, family, *this)),
140
- family);
141
- }
142
-
143
- facebook::react::State::Shared AbiViewComponentDescriptor::createState(
144
- facebook::react::ShadowNodeFamily const &family,
145
- facebook::react::StateData::Shared const &data) const {
146
- if (std::is_same<ConcreteStateData, facebook::react::StateData>::value) {
147
- // Default case: Returning `null` for nodes that don't use `State`.
148
- return nullptr;
149
- }
150
-
151
- react_native_assert(data && "Provided `data` is nullptr.");
152
-
153
- return std::make_shared<ConcreteState const>(
154
- std::static_pointer_cast<ConcreteStateData const>(data), *family.getMostRecentState());
155
- }
156
-
157
- facebook::react::ShadowNodeFamily::Shared AbiViewComponentDescriptor::createFamily(
158
- facebook::react::ShadowNodeFamilyFragment const &fragment) const {
159
- auto eventEmitter = std::make_shared<const ConcreteEventEmitter>(
160
- std::make_shared<facebook::react::EventTarget>(fragment.instanceHandle, fragment.surfaceId), eventDispatcher_);
161
- return std::make_shared<facebook::react::ShadowNodeFamily>(
162
- fragment, std::move(eventEmitter), eventDispatcher_, *this);
163
- }
164
-
165
- /*
166
- * Called immediately after `ShadowNode` is created or cloned.
167
- *
168
- * Override this method to pass information from custom `ComponentDescriptor`
169
- * to new instance of `ShadowNode`.
170
- *
171
- * Example usages:
172
- * - Inject image manager to `ImageShadowNode` in
173
- * `ImageComponentDescriptor`.
174
- * - Set `ShadowNode`'s size from state in
175
- * `ModalHostViewComponentDescriptor`.
176
- */
177
- void AbiViewComponentDescriptor::adopt(facebook::react::ShadowNode &shadowNode) const {
178
- react_native_assert(shadowNode.getComponentHandle() == getComponentHandle());
179
-
180
- auto &abiViewShadowNode = static_cast<AbiViewShadowNode &>(shadowNode);
181
-
182
- abiViewShadowNode.Builder(m_builder);
183
-
184
- if (winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
185
- ->MeasureContentHandler()) {
186
- abiViewShadowNode.dirtyLayout();
187
- abiViewShadowNode.enableMeasurement();
188
- }
189
- }
190
-
191
- } // namespace Microsoft::ReactNative