Skip to content

Commit ad17235

Browse files
authored
Allow portals to have independent layout constraints and scale factor (#14315)
* Allow portals to have independent layout constraints and scale factor * format * change files * fix
1 parent a95adab commit ad17235

32 files changed

+477
-246
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Fix UpdateState on generated base class",
4+
"packageName": "@react-native-windows/codegen",
5+
"email": "30809111+acoates-ms@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Allow portals to have independent layout constraints and scale factor",
4+
"packageName": "react-native-windows",
5+
"email": "30809111+acoates-ms@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}

packages/@react-native-windows/codegen/src/generators/GenerateComponentWindows.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ void Register::_COMPONENT_NAME_::NativeComponent(
200200
builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
201201
const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
202202
auto userData = view.UserData().as<TUserData>();
203-
userData->member(view, newState);
203+
userData->UpdateState(view, newState);
204204
});
205205
}
206206

packages/@react-native-windows/tester/src/js/examples/Modal/ModalPresentation.windows.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ const styles = StyleSheet.create({
348348
marginTop: 6,
349349
},
350350
modalContainer: {
351-
flex: 1,
351+
//flex: 1, // [Windows] - This will cause the modal to stretch to be as tall as the availiable space given to it.
352352
justifyContent: 'center',
353353
padding: 20,
354354
},

packages/sample-custom-component/windows/SampleCustomComponent/codegen/react/components/SampleCustomComponent/CalendarView.g.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ void RegisterCalendarViewNativeComponent(
170170
builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
171171
const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
172172
auto userData = view.UserData().as<TUserData>();
173-
userData->member(view, newState);
173+
userData->UpdateState(view, newState);
174174
});
175175
}
176176

packages/sample-custom-component/windows/SampleCustomComponent/codegen/react/components/SampleCustomComponent/DrawingIsland.g.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ void RegisterDrawingIslandNativeComponent(
150150
builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
151151
const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
152152
auto userData = view.UserData().as<TUserData>();
153-
userData->member(view, newState);
153+
userData->UpdateState(view, newState);
154154
});
155155
}
156156

packages/sample-custom-component/windows/SampleCustomComponent/codegen/react/components/SampleCustomComponent/MovingLight.g.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ void RegisterMovingLightNativeComponent(
203203
builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view,
204204
const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept {
205205
auto userData = view.UserData().as<TUserData>();
206-
userData->member(view, newState);
206+
userData->UpdateState(view, newState);
207207
});
208208
}
209209

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

0 commit comments

Comments
 (0)