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.
- package/Libraries/Modal/Modal.windows.js +4 -1
- package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.cpp +97 -0
- package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.h +53 -0
- package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +160 -17
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +182 -14
- package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.cpp +12 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +16 -14
- package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +10 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Networking/WinRTWebSocketResource.cpp +5 -0
- package/Shared/Shared.vcxitems +3 -3
- package/Shared/Shared.vcxitems.filters +1 -1
- package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +1 -1
- package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +1 -1
- package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +1 -1
- package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +1 -1
- package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +1 -1
- package/codegen/react/components/rnwcore/AndroidSwitch.g.h +1 -1
- package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +1 -1
- package/codegen/react/components/rnwcore/InputAccessory.g.h +1 -1
- package/codegen/react/components/rnwcore/ModalHostView.g.h +1 -1
- package/codegen/react/components/rnwcore/PullToRefreshView.g.h +1 -1
- package/codegen/react/components/rnwcore/SafeAreaView.g.h +1 -1
- package/codegen/react/components/rnwcore/Switch.g.h +1 -1
- package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +1 -1
- package/package.json +3 -3
- 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}
|
|
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
|
-
|
|
15
|
-
|
|
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
|
-
|
|
33
|
+
ConcreteAbiViewComponentDescriptor(facebook::react::ComponentDescriptorParameters const ¶meters)
|
|
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 &
|
|
199
|
+
const facebook::react::Props::Shared &props,
|
|
74
200
|
const facebook::react::ShadowNodeFamily::Shared & /*family*/,
|
|
75
|
-
const facebook::react::ComponentDescriptor &
|
|
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 ¶meters)
|
|
214
|
+
: ConcreteAbiViewComponentDescriptor<AbiViewShadowNode>(parameters) {}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
class AbiPortalComponentDescriptor : public ConcreteAbiViewComponentDescriptor<AbiPortalShadowNode> {
|
|
218
|
+
public:
|
|
219
|
+
AbiPortalComponentDescriptor(facebook::react::ComponentDescriptorParameters const ¶meters)
|
|
220
|
+
: ConcreteAbiViewComponentDescriptor<AbiPortalShadowNode>(parameters) {}
|
|
78
221
|
};
|
|
79
222
|
|
|
80
223
|
} // namespace Microsoft::ReactNative
|
package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp
CHANGED
|
@@ -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
|
|
69
|
-
const winrt::Microsoft::ReactNative::ComponentView &view
|
|
70
|
-
const winrt::Microsoft::ReactNative::
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
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::
|
|
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
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
pThis
|
|
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
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
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.
|
|
13
|
+
<ReactNativeWindowsVersion>0.78.4</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>78</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>4</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<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
|
}
|
package/Shared/Shared.vcxitems
CHANGED
|
@@ -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->
|
|
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->
|
|
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->
|
|
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->
|
|
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->
|
|
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->
|
|
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->
|
|
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->
|
|
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->
|
|
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->
|
|
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->
|
|
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->
|
|
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->
|
|
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
|
+
"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.
|
|
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.
|
|
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 ¶meters)
|
|
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
|