react-native-windows 0.74.22 → 0.74.24
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/Microsoft.ReactNative/CompositionComponentView.idl +2 -1
- package/Microsoft.ReactNative/Fabric/AbiComponentDescriptor.cpp +4 -1
- package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +7 -0
- package/Microsoft.ReactNative/Fabric/AbiViewProps.h +2 -0
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +11 -4
- package/Microsoft.ReactNative/Fabric/ComponentView.h +3 -2
- package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.cpp +926 -0
- package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.h +76 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +31 -13
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +27 -3
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +3 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +193 -892
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +17 -22
- package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +129 -122
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +14 -8
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +34 -20
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +5 -3
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +40 -2
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +9 -0
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +31 -3
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +8 -8
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +31 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +4 -0
- package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +9 -3
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +11 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +2 -0
- package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +1 -0
- package/Microsoft.ReactNative/IReactViewComponentBuilder.idl +1 -1
- package/Microsoft.ReactNative/ReactNativeAppBuilder.cpp +25 -129
- package/Microsoft.ReactNative/ReactNativeAppBuilder.h +5 -13
- package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +13 -34
- package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -2
- package/Microsoft.ReactNative/ReactNativeWin32App.cpp +129 -18
- package/Microsoft.ReactNative/ReactNativeWin32App.h +14 -5
- package/Microsoft.ReactNative/ViewProps.idl +2 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Shared.vcxitems +3 -10
- package/Shared/Shared.vcxitems.filters +1 -0
- package/package.json +3 -3
- package/templates/cpp-app/template.config.js +1 -1
- package/templates/cpp-app/windows/MyApp/MyApp.cpp +46 -130
- package/templates/cpp-lib/template.config.js +1 -1
- package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.cpp +0 -59
- package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.h +0 -23
|
@@ -127,6 +127,20 @@ ReactNativeIsland::ReactNativeIsland(const winrt::Microsoft::UI::Composition::Co
|
|
|
127
127
|
InitTextScaleMultiplier();
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
// Constructor to initialize ReactNativeIsland with context and componentView
|
|
131
|
+
ReactNativeIsland::ReactNativeIsland(
|
|
132
|
+
const winrt::Microsoft::UI::Composition::Compositor &compositor,
|
|
133
|
+
winrt::Microsoft::ReactNative::IReactContext context,
|
|
134
|
+
winrt::Microsoft::ReactNative::ComponentView componentView) noexcept
|
|
135
|
+
: m_compositor(compositor),
|
|
136
|
+
m_context(context),
|
|
137
|
+
m_layoutConstraints({{0, 0}, {0, 0}, winrt::Microsoft::ReactNative::LayoutDirection::Undefined}),
|
|
138
|
+
m_isFragment(true) {
|
|
139
|
+
m_rootTag = componentView.Tag();
|
|
140
|
+
InitTextScaleMultiplier();
|
|
141
|
+
AddFragmentCompositionEventHandler(context, componentView);
|
|
142
|
+
}
|
|
143
|
+
|
|
130
144
|
ReactNativeIsland::ReactNativeIsland() noexcept : ReactNativeIsland(nullptr) {}
|
|
131
145
|
|
|
132
146
|
ReactNativeIsland::~ReactNativeIsland() noexcept {
|
|
@@ -152,6 +166,7 @@ ReactNative::IReactViewHost ReactNativeIsland::ReactViewHost() noexcept {
|
|
|
152
166
|
}
|
|
153
167
|
|
|
154
168
|
void ReactNativeIsland::ReactViewHost(winrt::Microsoft::ReactNative::IReactViewHost const &value) noexcept {
|
|
169
|
+
assert(!m_isFragment); // make sure this isn't a FragmentIsalnd
|
|
155
170
|
if (m_reactViewHost == value) {
|
|
156
171
|
return;
|
|
157
172
|
}
|
|
@@ -404,7 +419,7 @@ void ReactNativeIsland::InitRootView(
|
|
|
404
419
|
|
|
405
420
|
m_context = winrt::Microsoft::ReactNative::ReactContext(std::move(context));
|
|
406
421
|
m_reactViewOptions = std::move(viewOptions);
|
|
407
|
-
m_CompositionEventHandler = std::make_shared<::Microsoft::ReactNative::CompositionEventHandler>(m_context, *this);
|
|
422
|
+
m_CompositionEventHandler = std::make_shared<::Microsoft::ReactNative::CompositionEventHandler>(m_context, *this, -1);
|
|
408
423
|
m_CompositionEventHandler->Initialize();
|
|
409
424
|
|
|
410
425
|
UpdateRootViewInternal();
|
|
@@ -412,6 +427,27 @@ void ReactNativeIsland::InitRootView(
|
|
|
412
427
|
m_isInitialized = true;
|
|
413
428
|
}
|
|
414
429
|
|
|
430
|
+
void ReactNativeIsland::AddFragmentCompositionEventHandler(
|
|
431
|
+
winrt::Microsoft::ReactNative::IReactContext context,
|
|
432
|
+
winrt::Microsoft::ReactNative::ComponentView componentView) noexcept {
|
|
433
|
+
m_uiDispatcher = context.Properties()
|
|
434
|
+
.Get(winrt::Microsoft::ReactNative::ReactDispatcherHelper::UIDispatcherProperty())
|
|
435
|
+
.try_as<IReactDispatcher>();
|
|
436
|
+
VerifyElseCrash(m_uiDispatcher.HasThreadAccess());
|
|
437
|
+
VerifyElseCrash(m_rootTag != -1);
|
|
438
|
+
auto uiManager = ::Microsoft::ReactNative::FabricUIManager::FromProperties(
|
|
439
|
+
winrt::Microsoft::ReactNative::ReactPropertyBag(context.Properties()));
|
|
440
|
+
|
|
441
|
+
if (!m_CompositionEventHandler) {
|
|
442
|
+
// Create CompositionEventHandler if not already created
|
|
443
|
+
m_context = winrt::Microsoft::ReactNative::ReactContext(context);
|
|
444
|
+
m_CompositionEventHandler =
|
|
445
|
+
std::make_shared<::Microsoft::ReactNative::CompositionEventHandler>(m_context, *this, componentView.Tag());
|
|
446
|
+
m_CompositionEventHandler->Initialize();
|
|
447
|
+
m_isInitialized = true;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
415
451
|
void ReactNativeIsland::UpdateRootView() noexcept {
|
|
416
452
|
VerifyElseCrash(m_uiDispatcher.HasThreadAccess());
|
|
417
453
|
VerifyElseCrash(m_isInitialized);
|
|
@@ -827,7 +863,9 @@ void ReactNativeIsland::OnMounted() noexcept {
|
|
|
827
863
|
return;
|
|
828
864
|
m_mounted = true;
|
|
829
865
|
if (auto componentView = GetComponentView()) {
|
|
830
|
-
componentView->
|
|
866
|
+
if (!componentView->isMounted()) {
|
|
867
|
+
componentView->onMounted();
|
|
868
|
+
}
|
|
831
869
|
}
|
|
832
870
|
}
|
|
833
871
|
|
|
@@ -48,6 +48,10 @@ struct ReactNativeIsland
|
|
|
48
48
|
~ReactNativeIsland() noexcept;
|
|
49
49
|
|
|
50
50
|
ReactNativeIsland(const winrt::Microsoft::UI::Composition::Compositor &compositor) noexcept;
|
|
51
|
+
ReactNativeIsland(
|
|
52
|
+
const winrt::Microsoft::UI::Composition::Compositor &compositor,
|
|
53
|
+
winrt::Microsoft::ReactNative::IReactContext context,
|
|
54
|
+
winrt::Microsoft::ReactNative::ComponentView componentView) noexcept;
|
|
51
55
|
winrt::Microsoft::UI::Content::ContentIsland Island();
|
|
52
56
|
|
|
53
57
|
// property ReactViewHost
|
|
@@ -117,6 +121,10 @@ struct ReactNativeIsland
|
|
|
117
121
|
const winrt::Microsoft::ReactNative::Composition::Input::Pointer &pointer,
|
|
118
122
|
facebook::react::Tag tag) noexcept;
|
|
119
123
|
|
|
124
|
+
void AddFragmentCompositionEventHandler(
|
|
125
|
+
winrt::Microsoft::ReactNative::IReactContext context,
|
|
126
|
+
winrt::Microsoft::ReactNative::ComponentView componentView) noexcept;
|
|
127
|
+
|
|
120
128
|
public: // IReactViewInstance UI-thread implementation
|
|
121
129
|
void InitRootView(
|
|
122
130
|
winrt::Microsoft::ReactNative::IReactContext &&context,
|
|
@@ -136,6 +144,7 @@ struct ReactNativeIsland
|
|
|
136
144
|
#endif
|
|
137
145
|
|
|
138
146
|
HWND m_hwnd{0};
|
|
147
|
+
bool m_isFragment{false};
|
|
139
148
|
bool m_isInitialized{false};
|
|
140
149
|
bool m_isJSViewAttached{false};
|
|
141
150
|
bool m_hasRenderedVisual{false};
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
#include "RootComponentView.h"
|
|
8
8
|
|
|
9
9
|
#include <Fabric/FabricUIManagerModule.h>
|
|
10
|
+
#include <winrt/Microsoft.UI.Input.h>
|
|
10
11
|
#include "CompositionRootAutomationProvider.h"
|
|
11
12
|
#include "ReactNativeIsland.h"
|
|
12
13
|
#include "Theme.h"
|
|
@@ -24,7 +25,7 @@ RootComponentView::RootComponentView(
|
|
|
24
25
|
reactContext,
|
|
25
26
|
ComponentViewFeatures::Default &
|
|
26
27
|
~(ComponentViewFeatures::Background | ComponentViewFeatures::ShadowProps |
|
|
27
|
-
ComponentViewFeatures::NativeBorder)) {}
|
|
28
|
+
ComponentViewFeatures::NativeBorder | ComponentViewFeatures::FocusVisual)) {}
|
|
28
29
|
|
|
29
30
|
RootComponentView::~RootComponentView() {
|
|
30
31
|
if (auto rootView = m_wkRootView.get()) {
|
|
@@ -106,7 +107,10 @@ bool RootComponentView::TrySetFocusedComponent(
|
|
|
106
107
|
auto target = view;
|
|
107
108
|
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(target);
|
|
108
109
|
if (selfView && !selfView->focusable()) {
|
|
109
|
-
target =
|
|
110
|
+
target = (direction == winrt::Microsoft::ReactNative::FocusNavigationDirection::Last ||
|
|
111
|
+
direction == winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous)
|
|
112
|
+
? FocusManager::FindLastFocusableElement(target)
|
|
113
|
+
: FocusManager::FindFirstFocusableElement(target);
|
|
110
114
|
if (!target)
|
|
111
115
|
return false;
|
|
112
116
|
selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(target);
|
|
@@ -147,6 +151,9 @@ bool RootComponentView::TryMoveFocus(bool next) noexcept {
|
|
|
147
151
|
[currentlyFocused = m_focusedComponent, next](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
|
|
148
152
|
if (view == currentlyFocused)
|
|
149
153
|
return false;
|
|
154
|
+
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view);
|
|
155
|
+
if (!selfView->focusable())
|
|
156
|
+
return false;
|
|
150
157
|
|
|
151
158
|
return winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view)
|
|
152
159
|
->rootComponentView()
|
|
@@ -156,7 +163,28 @@ bool RootComponentView::TryMoveFocus(bool next) noexcept {
|
|
|
156
163
|
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous);
|
|
157
164
|
};
|
|
158
165
|
|
|
159
|
-
|
|
166
|
+
if (winrt::Microsoft::ReactNative::implementation::walkTree(m_focusedComponent, next, fn)) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// We reached the end of the focus loop. Notify the island in case the host wants to move focus somewhere outside the
|
|
171
|
+
// island.
|
|
172
|
+
auto island = parentContentIsland();
|
|
173
|
+
if (island) {
|
|
174
|
+
auto focusController = winrt::Microsoft::UI::Input::InputFocusController::GetForIsland(island);
|
|
175
|
+
auto request = winrt::Microsoft::UI::Input::FocusNavigationRequest::Create(
|
|
176
|
+
next ? winrt::Microsoft::UI::Input::FocusNavigationReason::Last
|
|
177
|
+
: winrt::Microsoft::UI::Input::FocusNavigationReason::First);
|
|
178
|
+
auto result = focusController.DepartFocus(request);
|
|
179
|
+
if (result == winrt::Microsoft::UI::Input::FocusNavigationResult::Moved) {
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Wrap focus around if nothing outside the island takes focus
|
|
185
|
+
return NavigateFocus(winrt::Microsoft::ReactNative::FocusNavigationRequest(
|
|
186
|
+
next ? winrt::Microsoft::ReactNative::FocusNavigationReason::First
|
|
187
|
+
: winrt::Microsoft::ReactNative::FocusNavigationReason::Last));
|
|
160
188
|
}
|
|
161
189
|
|
|
162
190
|
HRESULT RootComponentView::GetFragmentRoot(IRawElementProviderFragmentRoot **pRetVal) noexcept {
|
|
@@ -1108,9 +1108,9 @@ void ScrollViewComponentView::StartBringIntoView(
|
|
|
1108
1108
|
options.TargetRect->origin.y > m_scrollVisual.ScrollPosition().y) {
|
|
1109
1109
|
needsScroll = true;
|
|
1110
1110
|
if (options.TargetRect->size.height > viewerHeight) {
|
|
1111
|
-
scrollToVertical = options.TargetRect->origin.y + options.VerticalOffset;
|
|
1111
|
+
scrollToVertical = options.TargetRect->origin.y + options.VerticalOffset * m_layoutMetrics.pointScaleFactor;
|
|
1112
1112
|
} else {
|
|
1113
|
-
scrollToVertical = (targetBottom - viewerHeight) + options.VerticalOffset;
|
|
1113
|
+
scrollToVertical = (targetBottom - viewerHeight) + options.VerticalOffset * m_layoutMetrics.pointScaleFactor;
|
|
1114
1114
|
}
|
|
1115
1115
|
// Scroll Up
|
|
1116
1116
|
} else if (
|
|
@@ -1118,9 +1118,9 @@ void ScrollViewComponentView::StartBringIntoView(
|
|
|
1118
1118
|
targetBottom < (m_scrollVisual.ScrollPosition().y + viewerHeight)) {
|
|
1119
1119
|
needsScroll = true;
|
|
1120
1120
|
if (options.TargetRect->size.height > viewerHeight) {
|
|
1121
|
-
scrollToVertical = targetBottom - viewerHeight - options.VerticalOffset;
|
|
1121
|
+
scrollToVertical = targetBottom - viewerHeight - options.VerticalOffset * m_layoutMetrics.pointScaleFactor;
|
|
1122
1122
|
} else {
|
|
1123
|
-
scrollToVertical = options.TargetRect->origin.y - options.VerticalOffset;
|
|
1123
|
+
scrollToVertical = options.TargetRect->origin.y - options.VerticalOffset * m_layoutMetrics.pointScaleFactor;
|
|
1124
1124
|
}
|
|
1125
1125
|
}
|
|
1126
1126
|
} else {
|
|
@@ -1134,9 +1134,9 @@ void ScrollViewComponentView::StartBringIntoView(
|
|
|
1134
1134
|
options.TargetRect->origin.x > m_scrollVisual.ScrollPosition().x) {
|
|
1135
1135
|
needsScroll = true;
|
|
1136
1136
|
if (options.TargetRect->size.width > viewerWidth) {
|
|
1137
|
-
scrollToHorizontal = options.TargetRect->origin.x + options.HorizontalOffset;
|
|
1137
|
+
scrollToHorizontal = options.TargetRect->origin.x + options.HorizontalOffset * m_layoutMetrics.pointScaleFactor;
|
|
1138
1138
|
} else {
|
|
1139
|
-
scrollToHorizontal = (targetRight - viewerWidth) + options.HorizontalOffset;
|
|
1139
|
+
scrollToHorizontal = (targetRight - viewerWidth) + options.HorizontalOffset * m_layoutMetrics.pointScaleFactor;
|
|
1140
1140
|
}
|
|
1141
1141
|
// Scroll Left
|
|
1142
1142
|
} else if (
|
|
@@ -1144,9 +1144,9 @@ void ScrollViewComponentView::StartBringIntoView(
|
|
|
1144
1144
|
targetRight < (m_scrollVisual.ScrollPosition().x + viewerWidth)) {
|
|
1145
1145
|
needsScroll = true;
|
|
1146
1146
|
if (options.TargetRect->size.width > viewerWidth) {
|
|
1147
|
-
scrollToHorizontal = targetRight - viewerWidth - options.HorizontalOffset;
|
|
1147
|
+
scrollToHorizontal = targetRight - viewerWidth - options.HorizontalOffset * m_layoutMetrics.pointScaleFactor;
|
|
1148
1148
|
} else {
|
|
1149
|
-
scrollToHorizontal = options.TargetRect->origin.x - options.HorizontalOffset;
|
|
1149
|
+
scrollToHorizontal = options.TargetRect->origin.x - options.HorizontalOffset * m_layoutMetrics.pointScaleFactor;
|
|
1150
1150
|
}
|
|
1151
1151
|
}
|
|
1152
1152
|
} else {
|
package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp
CHANGED
|
@@ -870,6 +870,7 @@ void WindowsTextInputComponentView::OnCharacterReceived(
|
|
|
870
870
|
emitter->onKeyPress(onKeyPressArgs);
|
|
871
871
|
|
|
872
872
|
WPARAM wParam = static_cast<WPARAM>(args.KeyCode());
|
|
873
|
+
|
|
873
874
|
LPARAM lParam = 0;
|
|
874
875
|
lParam = args.KeyStatus().RepeatCount; // bits 0-15
|
|
875
876
|
lParam |= args.KeyStatus().ScanCode << 16; // bits 16-23
|
|
@@ -1022,6 +1023,10 @@ void WindowsTextInputComponentView::updateProps(
|
|
|
1022
1023
|
m_submitKeyEvents.clear();
|
|
1023
1024
|
}
|
|
1024
1025
|
|
|
1026
|
+
if (oldTextInputProps.autoCapitalize != newTextInputProps.autoCapitalize) {
|
|
1027
|
+
autoCapitalizeOnUpdateProps(oldTextInputProps.autoCapitalize, newTextInputProps.autoCapitalize);
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1025
1030
|
UpdatePropertyBits();
|
|
1026
1031
|
}
|
|
1027
1032
|
|
|
@@ -1476,4 +1481,29 @@ winrt::Microsoft::ReactNative::ComponentView WindowsTextInputComponentView::Crea
|
|
|
1476
1481
|
return winrt::make<WindowsTextInputComponentView>(compContext, tag, reactContext);
|
|
1477
1482
|
}
|
|
1478
1483
|
|
|
1479
|
-
|
|
1484
|
+
// This function assumes that previous and new capitalization types are different.
|
|
1485
|
+
void WindowsTextInputComponentView::autoCapitalizeOnUpdateProps(
|
|
1486
|
+
const std::string &previousCapitalizationType,
|
|
1487
|
+
const std::string &newCapitalizationType) noexcept {
|
|
1488
|
+
/*
|
|
1489
|
+
Possible values are:
|
|
1490
|
+
Characters - All characters.
|
|
1491
|
+
Words - First letter of each word.
|
|
1492
|
+
Sentences - First letter of each sentence.
|
|
1493
|
+
None - Do not autocapitalize anything.
|
|
1494
|
+
|
|
1495
|
+
For now, only characters and none are supported.
|
|
1496
|
+
*/
|
|
1497
|
+
|
|
1498
|
+
if (previousCapitalizationType == "characters") {
|
|
1499
|
+
winrt::check_hresult(m_textServices->TxSendMessage(
|
|
1500
|
+
EM_SETEDITSTYLE, 0 /* disable */, SES_UPPERCASE /* flag affected */, nullptr /* LRESULT */));
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
if (newCapitalizationType == "characters") {
|
|
1504
|
+
winrt::check_hresult(m_textServices->TxSendMessage(
|
|
1505
|
+
EM_SETEDITSTYLE, SES_UPPERCASE /* enable */, SES_UPPERCASE /* flag affected */, nullptr /* LRESULT */));
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -104,6 +104,10 @@ struct WindowsTextInputComponentView
|
|
|
104
104
|
void InternalFinalize() noexcept;
|
|
105
105
|
void UpdatePropertyBits() noexcept;
|
|
106
106
|
|
|
107
|
+
void autoCapitalizeOnUpdateProps(
|
|
108
|
+
const std::string &previousCapitalizationType,
|
|
109
|
+
const std::string &newcapitalizationType) noexcept;
|
|
110
|
+
|
|
107
111
|
winrt::Windows::UI::Composition::CompositionSurfaceBrush m_brush{nullptr};
|
|
108
112
|
winrt::Microsoft::ReactNative::Composition::Experimental::ICaretVisual m_caretVisual{nullptr};
|
|
109
113
|
winrt::Microsoft::ReactNative::Composition::Experimental::IDrawingSurfaceBrush m_drawingSurface{nullptr};
|
|
@@ -330,7 +330,9 @@ bool Theme::TryGetPlatformColor(const std::string &platformColor, winrt::Windows
|
|
|
330
330
|
{"AcrylicInAppFillColorDefault", {0x9E, 0xFF, 0xFF, 0xFF}},
|
|
331
331
|
{"SystemChromeMediumLowColor", {0xFF, 0xF2, 0xF2, 0xF2}},
|
|
332
332
|
{"SystemControlForegroundBaseHighColor", {0xFF, 0x00, 0x00, 0x00}},
|
|
333
|
-
{"SystemControlTransientBorderColor", {0x24, 0x00, 0x00, 0x00}}
|
|
333
|
+
{"SystemControlTransientBorderColor", {0x24, 0x00, 0x00, 0x00}},
|
|
334
|
+
{"FocusVisualPrimary", {0xFF, 0x00, 0x00, 0x00}},
|
|
335
|
+
{"FocusVisualSecondary", {0x99, 0xFF, 0xFF, 0xFF}}};
|
|
334
336
|
|
|
335
337
|
static std::unordered_map<std::string, winrt::Windows::UI::Color, std::hash<std::string_view>, std::equal_to<>>
|
|
336
338
|
s_darkColors = {
|
|
@@ -362,7 +364,9 @@ bool Theme::TryGetPlatformColor(const std::string &platformColor, winrt::Windows
|
|
|
362
364
|
{"AcrylicInAppFillColorDefault", {0x9E, 0x00, 0x00, 0x00}},
|
|
363
365
|
{"SystemChromeMediumLowColor", {0xFF, 0x2B, 0x2B, 0x2B}},
|
|
364
366
|
{"SystemControlForegroundBaseHighColor", {0xFF, 0xFF, 0xFF, 0xFF}},
|
|
365
|
-
{"SystemControlTransientBorderColor", {0x5C, 0x00, 0x00, 0x00}}
|
|
367
|
+
{"SystemControlTransientBorderColor", {0x5C, 0x00, 0x00, 0x00}},
|
|
368
|
+
{"FocusVisualPrimary", {0xFF, 0xFF, 0xFF, 0xFF}},
|
|
369
|
+
{"FocusVisualSecondary", {0x99, 0x00, 0x00, 0x00F}}};
|
|
366
370
|
|
|
367
371
|
static std::unordered_map<
|
|
368
372
|
std::string,
|
|
@@ -399,7 +403,9 @@ bool Theme::TryGetPlatformColor(const std::string &platformColor, winrt::Windows
|
|
|
399
403
|
{"ControlStrongFillColorDisabled", {winrt::Windows::UI::ViewManagement::UIElementType::ButtonFace, {}}},
|
|
400
404
|
{"SystemChromeMediumLowColor", {winrt::Windows::UI::ViewManagement::UIElementType::ButtonFace, {}}},
|
|
401
405
|
{"SystemControlForegroundBaseHighColor", {winrt::Windows::UI::ViewManagement::UIElementType::ButtonText, {}}},
|
|
402
|
-
{"SystemControlTransientBorderColor", {winrt::Windows::UI::ViewManagement::UIElementType::ButtonText, {}}}
|
|
406
|
+
{"SystemControlTransientBorderColor", {winrt::Windows::UI::ViewManagement::UIElementType::ButtonText, {}}},
|
|
407
|
+
{"FocusVisualPrimary", {winrt::Windows::UI::ViewManagement::UIElementType::ButtonText, {}}},
|
|
408
|
+
{"FocusVisualSecondary", {winrt::Windows::UI::ViewManagement::UIElementType::ButtonFace, {}}}};
|
|
403
409
|
|
|
404
410
|
auto alias = s_xamlAliasedColors.find(platformColor);
|
|
405
411
|
if (alias != s_xamlAliasedColors.end()) {
|
|
@@ -214,4 +214,15 @@ ExpandCollapseState GetExpandCollapseState(const bool &expanded) noexcept {
|
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
ToggleState GetToggleState(const std::optional<facebook::react::AccessibilityState> &state) noexcept {
|
|
218
|
+
if (state.has_value()) {
|
|
219
|
+
if (state->checked == facebook::react::AccessibilityState::Checked) {
|
|
220
|
+
return ToggleState::ToggleState_On;
|
|
221
|
+
} else if (state->checked == facebook::react::AccessibilityState::Mixed) {
|
|
222
|
+
return ToggleState::ToggleState_Indeterminate;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return ToggleState::ToggleState_Off;
|
|
226
|
+
}
|
|
227
|
+
|
|
217
228
|
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
@@ -36,4 +36,6 @@ std::string extractAccessibilityValue(const facebook::react::AccessibilityValue
|
|
|
36
36
|
void DispatchAccessibilityAction(::Microsoft::ReactNative::ReactTaggedView &view, const std::string &action) noexcept;
|
|
37
37
|
|
|
38
38
|
ExpandCollapseState GetExpandCollapseState(const bool &expanded) noexcept;
|
|
39
|
+
|
|
40
|
+
ToggleState GetToggleState(const std::optional<facebook::react::AccessibilityState> &state) noexcept;
|
|
39
41
|
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
@@ -33,6 +33,7 @@ namespace Microsoft.ReactNative.Composition
|
|
|
33
33
|
void SetViewComponentViewInitializer(ViewComponentViewInitializer initializer);
|
|
34
34
|
void SetContentIslandComponentViewInitializer(ComponentIslandComponentViewInitializer initializer);
|
|
35
35
|
void SetCreateVisualHandler(CreateVisualDelegate impl);
|
|
36
|
+
void SetViewFeatures(ComponentViewFeatures viewFeatures);
|
|
36
37
|
};
|
|
37
38
|
|
|
38
39
|
} // namespace Microsoft.ReactNative
|
|
@@ -56,7 +56,7 @@ namespace Microsoft.ReactNative
|
|
|
56
56
|
|
|
57
57
|
[experimental]
|
|
58
58
|
DOC_STRING("A delegate that creates a @IComponentProps object for an instance of @ViewProps. See @IReactViewComponentBuilder.SetCreateProps")
|
|
59
|
-
delegate IComponentProps ViewPropsFactory(ViewProps props);
|
|
59
|
+
delegate IComponentProps ViewPropsFactory(ViewProps props, IComponentProps cloneFrom);
|
|
60
60
|
|
|
61
61
|
[experimental]
|
|
62
62
|
delegate Windows.Foundation.Size MeasureContentHandler(ShadowNode shadowNode, LayoutContext layoutContext, LayoutConstraints layoutConstraints);
|
|
@@ -1,43 +1,17 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
1
4
|
#include "pch.h"
|
|
2
5
|
#include "ReactNativeAppBuilder.h"
|
|
3
6
|
#include "ReactNativeAppBuilder.g.cpp"
|
|
4
|
-
|
|
5
|
-
#include "ReactNativeHost.h"
|
|
7
|
+
|
|
6
8
|
#include "ReactNativeWin32App.h"
|
|
9
|
+
|
|
10
|
+
#include "winrt/Microsoft.ReactNative.h"
|
|
7
11
|
#include "winrt/Microsoft.UI.Composition.h"
|
|
8
12
|
#include "winrt/Microsoft.UI.Dispatching.h"
|
|
13
|
+
#include "winrt/Microsoft.UI.Interop.h"
|
|
9
14
|
#include "winrt/Microsoft.UI.Windowing.h"
|
|
10
|
-
#include "winrt/microsoft.UI.Interop.h"
|
|
11
|
-
|
|
12
|
-
// Scaling factor for the window's content based on the DPI of the display where the window is located.
|
|
13
|
-
float ScaleFactor(HWND hwnd) noexcept {
|
|
14
|
-
return GetDpiForWindow(hwnd) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
void UpdateRootViewSizeToAppWindow(
|
|
18
|
-
winrt::Microsoft::ReactNative::ReactNativeIsland const &rootView,
|
|
19
|
-
winrt::Microsoft::UI::Windowing::AppWindow const &window) {
|
|
20
|
-
auto hwnd = winrt::Microsoft::UI::GetWindowFromWindowId(window.Id());
|
|
21
|
-
auto scaleFactor = ScaleFactor(hwnd);
|
|
22
|
-
winrt::Windows::Foundation::Size size{
|
|
23
|
-
window.ClientSize().Width / scaleFactor, window.ClientSize().Height / scaleFactor};
|
|
24
|
-
// Do not relayout when minimized
|
|
25
|
-
if (window.Presenter().as<winrt::Microsoft::UI::Windowing::OverlappedPresenter>().State() !=
|
|
26
|
-
winrt::Microsoft::UI::Windowing::OverlappedPresenterState::Minimized) {
|
|
27
|
-
winrt::Microsoft::ReactNative::LayoutConstraints constraints;
|
|
28
|
-
constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
|
|
29
|
-
constraints.MaximumSize = constraints.MinimumSize = size;
|
|
30
|
-
rootView.Arrange(constraints, {0, 0});
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
namespace winrt::ReactNative {
|
|
35
|
-
using namespace winrt::Microsoft::ReactNative;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
namespace winrt::UI {
|
|
39
|
-
using namespace winrt::Microsoft::UI;
|
|
40
|
-
}
|
|
41
15
|
|
|
42
16
|
namespace winrt::Microsoft::ReactNative::implementation {
|
|
43
17
|
ReactNativeAppBuilder::ReactNativeAppBuilder() {
|
|
@@ -46,133 +20,55 @@ ReactNativeAppBuilder::ReactNativeAppBuilder() {
|
|
|
46
20
|
|
|
47
21
|
ReactNativeAppBuilder::~ReactNativeAppBuilder() {}
|
|
48
22
|
|
|
49
|
-
winrt::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::
|
|
50
|
-
winrt::
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
m_reactNativeWin32App.ReactNativeHost().PackageProviders().Append(provider);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return *this;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
winrt::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetReactInstanceSettings(
|
|
60
|
-
winrt::Microsoft::ReactNative::ReactInstanceSettings const &settings) {
|
|
61
|
-
m_reactNativeWin32App.ReactNativeHost().InstanceSettings(settings);
|
|
62
|
-
|
|
23
|
+
winrt::Microsoft::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetDispatcherQueueController(
|
|
24
|
+
winrt::Microsoft::UI::Dispatching::DispatcherQueueController const &dispatcherQueueController) {
|
|
25
|
+
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->DispatcherQueueController(
|
|
26
|
+
dispatcherQueueController);
|
|
63
27
|
return *this;
|
|
64
28
|
}
|
|
65
29
|
|
|
66
|
-
winrt::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetCompositor(
|
|
30
|
+
winrt::Microsoft::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetCompositor(
|
|
67
31
|
winrt::Microsoft::UI::Composition::Compositor const &compositor) {
|
|
68
32
|
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor(compositor);
|
|
69
33
|
return *this;
|
|
70
34
|
}
|
|
71
35
|
|
|
72
|
-
winrt::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetAppWindow(
|
|
36
|
+
winrt::Microsoft::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetAppWindow(
|
|
73
37
|
winrt::Microsoft::UI::Windowing::AppWindow const &appWindow) {
|
|
74
38
|
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->AppWindow(appWindow);
|
|
75
39
|
|
|
76
40
|
return *this;
|
|
77
41
|
}
|
|
78
42
|
|
|
79
|
-
winrt::Microsoft::ReactNative::
|
|
80
|
-
|
|
81
|
-
|
|
43
|
+
winrt::Microsoft::ReactNative::ReactNativeWin32App ReactNativeAppBuilder::Build() {
|
|
44
|
+
// Create the DispatcherQueueController if the app developer doesn't provide one
|
|
45
|
+
if (m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->DispatcherQueueController() == nullptr) {
|
|
46
|
+
assert(m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor() == nullptr);
|
|
82
47
|
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
winrt::ReactNative::ReactNativeWin32App ReactNativeAppBuilder::Build() {
|
|
87
|
-
if (m_reactNativeWin32App.Compositor() == nullptr) {
|
|
88
|
-
// Create a DispatcherQueue for this thread. This is needed for Composition, Content, and
|
|
89
|
-
// Input APIs.
|
|
48
|
+
// Create a DispatcherQueue for this thread. This is needed for Composition, Content, and Input APIs.
|
|
90
49
|
auto dispatcherQueueController =
|
|
91
50
|
winrt::Microsoft::UI::Dispatching::DispatcherQueueController::CreateOnCurrentThread();
|
|
92
51
|
|
|
93
|
-
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->
|
|
52
|
+
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->DispatcherQueueController(
|
|
94
53
|
dispatcherQueueController);
|
|
54
|
+
}
|
|
95
55
|
|
|
96
|
-
|
|
56
|
+
// Create the Compositor if the app developer doesn't provide one
|
|
57
|
+
if (m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor() == nullptr) {
|
|
58
|
+
// Create the compositor on behalf of the App Developer.
|
|
97
59
|
auto compositor = winrt::Microsoft::UI::Composition::Compositor();
|
|
98
60
|
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor(compositor);
|
|
99
61
|
}
|
|
100
62
|
|
|
101
|
-
// Create the AppWindow if the developer doesn't provide one
|
|
63
|
+
// Create the AppWindow if the app developer doesn't provide one
|
|
102
64
|
if (m_reactNativeWin32App.AppWindow() == nullptr) {
|
|
103
65
|
auto appWindow = winrt::Microsoft::UI::Windowing::AppWindow::Create();
|
|
104
|
-
appWindow.Title(L"
|
|
66
|
+
appWindow.Title(L"ReactNativeWin32App");
|
|
105
67
|
appWindow.Resize({1000, 1000});
|
|
106
|
-
appWindow.Show();
|
|
107
68
|
|
|
108
69
|
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->AppWindow(appWindow);
|
|
109
70
|
}
|
|
110
71
|
|
|
111
|
-
// Currently set the property to use current thread dispatcher as a default UI dispatcher.
|
|
112
|
-
// TODO: Provision for setting dispatcher based on the thread dispatcherQueueController is created.
|
|
113
|
-
m_reactNativeWin32App.ReactNativeHost().InstanceSettings().Properties().Set(
|
|
114
|
-
ReactDispatcherHelper::UIDispatcherProperty(), ReactDispatcherHelper::UIThreadDispatcher());
|
|
115
|
-
|
|
116
|
-
auto hwnd{winrt::UI::GetWindowFromWindowId(m_reactNativeWin32App.AppWindow().Id())};
|
|
117
|
-
|
|
118
|
-
winrt::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
|
|
119
|
-
m_reactNativeWin32App.ReactNativeHost().InstanceSettings().Properties(), reinterpret_cast<uint64_t>(hwnd));
|
|
120
|
-
|
|
121
|
-
winrt::ReactNative::Composition::CompositionUIService::SetCompositor(
|
|
122
|
-
m_reactNativeWin32App.ReactNativeHost().InstanceSettings(), m_reactNativeWin32App.Compositor());
|
|
123
|
-
|
|
124
|
-
// Start the react-native instance, which will create a JavaScript runtime and load the applications bundle.
|
|
125
|
-
m_reactNativeWin32App.ReactNativeHost().ReloadInstance();
|
|
126
|
-
|
|
127
|
-
// Create a RootView which will present a react-native component
|
|
128
|
-
auto reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland(m_reactNativeWin32App.Compositor());
|
|
129
|
-
reactNativeIsland.ReactViewHost(winrt::Microsoft::ReactNative::ReactCoreInjection::MakeViewHost(
|
|
130
|
-
m_reactNativeWin32App.ReactNativeHost(), m_reactViewOptions));
|
|
131
|
-
|
|
132
|
-
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->ReactNativeIsland(
|
|
133
|
-
std::move(reactNativeIsland));
|
|
134
|
-
|
|
135
|
-
// Update the size of the RootView when the AppWindow changes size
|
|
136
|
-
m_reactNativeWin32App.AppWindow().Changed(
|
|
137
|
-
[wkRootView = winrt::make_weak(m_reactNativeWin32App.ReactNativeIsland())](
|
|
138
|
-
winrt::Microsoft::UI::Windowing::AppWindow const &window,
|
|
139
|
-
winrt::Microsoft::UI::Windowing::AppWindowChangedEventArgs const &args) {
|
|
140
|
-
if (args.DidSizeChange() || args.DidVisibilityChange()) {
|
|
141
|
-
if (auto rootView = wkRootView.get()) {
|
|
142
|
-
UpdateRootViewSizeToAppWindow(rootView, window);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// Quit application when main window is closed
|
|
148
|
-
m_reactNativeWin32App.AppWindow().Destroying([this](
|
|
149
|
-
winrt::Microsoft::UI::Windowing::AppWindow const &window,
|
|
150
|
-
winrt::Windows::Foundation::IInspectable const & /*args*/) {
|
|
151
|
-
// Before we shutdown the application - unload the ReactNativeHost to give the javascript a chance to save any
|
|
152
|
-
// state
|
|
153
|
-
auto async = m_reactNativeWin32App.ReactNativeHost().UnloadInstance();
|
|
154
|
-
async.Completed([this](auto asyncInfo, winrt::Windows::Foundation::AsyncStatus asyncStatus) {
|
|
155
|
-
assert(asyncStatus == winrt::Windows::Foundation::AsyncStatus::Completed);
|
|
156
|
-
m_reactNativeWin32App.ReactNativeHost().InstanceSettings().UIDispatcher().Post([]() { PostQuitMessage(0); });
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// DesktopChildSiteBridge create a ContentSite that can host the RootView ContentIsland
|
|
161
|
-
auto desktopChildSiteBridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
|
|
162
|
-
m_reactNativeWin32App.Compositor(), m_reactNativeWin32App.AppWindow().Id());
|
|
163
|
-
|
|
164
|
-
desktopChildSiteBridge.Connect(m_reactNativeWin32App.ReactNativeIsland().Island());
|
|
165
|
-
|
|
166
|
-
desktopChildSiteBridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
|
|
167
|
-
|
|
168
|
-
auto scaleFactor = ScaleFactor(hwnd);
|
|
169
|
-
m_reactNativeWin32App.ReactNativeIsland().ScaleFactor(scaleFactor);
|
|
170
|
-
|
|
171
|
-
UpdateRootViewSizeToAppWindow(reactNativeIsland, m_reactNativeWin32App.AppWindow());
|
|
172
|
-
|
|
173
|
-
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->DesktopChildSiteBridge(
|
|
174
|
-
std::move(desktopChildSiteBridge));
|
|
175
|
-
|
|
176
72
|
return m_reactNativeWin32App;
|
|
177
73
|
}
|
|
178
74
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
1
3
|
#pragma once
|
|
4
|
+
|
|
2
5
|
#include "ReactNativeAppBuilder.g.h"
|
|
3
|
-
#include <winrt/Microsoft.UI.Content.h>
|
|
4
6
|
|
|
5
7
|
namespace winrt::Microsoft::ReactNative::implementation {
|
|
6
8
|
struct ReactNativeAppBuilder : ReactNativeAppBuilderT<ReactNativeAppBuilder> {
|
|
@@ -8,25 +10,15 @@ struct ReactNativeAppBuilder : ReactNativeAppBuilderT<ReactNativeAppBuilder> {
|
|
|
8
10
|
|
|
9
11
|
~ReactNativeAppBuilder();
|
|
10
12
|
|
|
11
|
-
winrt::Microsoft::ReactNative::ReactNativeAppBuilder
|
|
12
|
-
winrt::
|
|
13
|
-
&packageProviders);
|
|
14
|
-
winrt::Microsoft::ReactNative::ReactNativeAppBuilder SetReactInstanceSettings(
|
|
15
|
-
winrt::Microsoft::ReactNative::ReactInstanceSettings const &settings);
|
|
16
|
-
|
|
17
|
-
// TODO: Currently, SetCompositor API is not exposed to the developer.
|
|
18
|
-
// Compositor depends on the DispatcherQueue created by DispatcherQueueController on a current thread
|
|
19
|
-
// or dedicated thread. So we also have to make a provision for setting DispatcherQueueController.
|
|
13
|
+
winrt::Microsoft::ReactNative::ReactNativeAppBuilder SetDispatcherQueueController(
|
|
14
|
+
winrt::Microsoft::UI::Dispatching::DispatcherQueueController const &dispatcherQueueController);
|
|
20
15
|
winrt::Microsoft::ReactNative::ReactNativeAppBuilder SetCompositor(
|
|
21
16
|
winrt::Microsoft::UI::Composition::Compositor const &compositor);
|
|
22
17
|
winrt::Microsoft::ReactNative::ReactNativeAppBuilder SetAppWindow(
|
|
23
18
|
winrt::Microsoft::UI::Windowing::AppWindow const &appWindow);
|
|
24
|
-
winrt::Microsoft::ReactNative::ReactNativeAppBuilder SetReactViewOptions(
|
|
25
|
-
winrt::Microsoft::ReactNative::ReactViewOptions const &reactViewOptions);
|
|
26
19
|
winrt::Microsoft::ReactNative::ReactNativeWin32App Build();
|
|
27
20
|
|
|
28
21
|
private:
|
|
29
|
-
winrt::Microsoft::ReactNative::ReactViewOptions m_reactViewOptions{};
|
|
30
22
|
winrt::Microsoft::ReactNative::ReactNativeWin32App m_reactNativeWin32App{nullptr};
|
|
31
23
|
};
|
|
32
24
|
} // namespace winrt::Microsoft::ReactNative::implementation
|