react-native-windows 0.83.0-preview.0 → 0.83.0-preview.2
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/ComponentView.idl +9 -1
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -2
- package/Microsoft.ReactNative/Fabric/ComponentView.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +61 -3
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +10 -4
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +31 -8
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +10 -2
- package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +7 -2
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +4 -1
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +4 -0
- package/PropertySheets/Generated/PackageVersion.g.props +4 -4
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/BaseViewProps.cpp +664 -0
- package/package.json +4 -4
|
@@ -43,6 +43,14 @@ namespace Microsoft.ReactNative
|
|
|
43
43
|
Last,
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
+
enum FocusState
|
|
47
|
+
{
|
|
48
|
+
Unfocused = 0,
|
|
49
|
+
Pointer,
|
|
50
|
+
Keyboard,
|
|
51
|
+
Programmatic,
|
|
52
|
+
};
|
|
53
|
+
|
|
46
54
|
[webhosthidden]
|
|
47
55
|
[experimental]
|
|
48
56
|
interface IComponentState
|
|
@@ -99,7 +107,7 @@ namespace Microsoft.ReactNative
|
|
|
99
107
|
LayoutMetrics LayoutMetrics { get; };
|
|
100
108
|
IInspectable UserData;
|
|
101
109
|
|
|
102
|
-
Boolean TryFocus();
|
|
110
|
+
Boolean TryFocus(FocusState focusState);
|
|
103
111
|
|
|
104
112
|
DOC_STRING("Used to handle key down events when this component is focused, or if a child component did not handle the key down")
|
|
105
113
|
event Windows.Foundation.EventHandler<Microsoft.ReactNative.Composition.Input.KeyRoutedEventArgs> KeyDown;
|
|
@@ -283,6 +283,7 @@ void ComponentView::parent(const winrt::Microsoft::ReactNative::ComponentView &p
|
|
|
283
283
|
oldRootView->TrySetFocusedComponent(
|
|
284
284
|
oldParent,
|
|
285
285
|
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
286
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic,
|
|
286
287
|
true /*forceNoSelectionIfCannotMove*/);
|
|
287
288
|
}
|
|
288
289
|
}
|
|
@@ -431,9 +432,10 @@ void ComponentView::GotFocus(winrt::event_token const &token) noexcept {
|
|
|
431
432
|
m_gotFocusEvent.remove(token);
|
|
432
433
|
}
|
|
433
434
|
|
|
434
|
-
bool ComponentView::TryFocus() noexcept {
|
|
435
|
+
bool ComponentView::TryFocus(winrt::Microsoft::ReactNative::FocusState focusState) noexcept {
|
|
435
436
|
if (auto root = rootComponentView()) {
|
|
436
|
-
return root->TrySetFocusedComponent(
|
|
437
|
+
return root->TrySetFocusedComponent(
|
|
438
|
+
*get_strong(), winrt::Microsoft::ReactNative::FocusNavigationDirection::None, focusState);
|
|
437
439
|
}
|
|
438
440
|
|
|
439
441
|
return false;
|
|
@@ -201,7 +201,7 @@ struct ComponentView
|
|
|
201
201
|
|
|
202
202
|
LayoutMetrics LayoutMetrics() const noexcept;
|
|
203
203
|
|
|
204
|
-
bool TryFocus() noexcept;
|
|
204
|
+
bool TryFocus(winrt::Microsoft::ReactNative::FocusState focusState) noexcept;
|
|
205
205
|
|
|
206
206
|
virtual bool focusable() const noexcept;
|
|
207
207
|
virtual facebook::react::SharedViewEventEmitter eventEmitterAtPoint(facebook::react::Point pt) noexcept;
|
|
@@ -608,6 +608,8 @@ int64_t CompositionEventHandler::SendMessage(HWND hwnd, uint32_t msg, uint64_t w
|
|
|
608
608
|
|
|
609
609
|
void CompositionEventHandler::onKeyDown(
|
|
610
610
|
const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept {
|
|
611
|
+
RootComponentView().UseKeyboardForProgrammaticFocus(true);
|
|
612
|
+
|
|
611
613
|
if (auto focusedComponent = RootComponentView().GetFocusedComponent()) {
|
|
612
614
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(focusedComponent)->OnKeyDown(args);
|
|
613
615
|
|
|
@@ -631,7 +633,7 @@ void CompositionEventHandler::onKeyDown(
|
|
|
631
633
|
}
|
|
632
634
|
|
|
633
635
|
if (!fCtrl && args.Key() == winrt::Windows::System::VirtualKey::Tab) {
|
|
634
|
-
if (RootComponentView().TryMoveFocus(!fShift)) {
|
|
636
|
+
if (RootComponentView().TryMoveFocus(!fShift, winrt::Microsoft::ReactNative::FocusState::Keyboard)) {
|
|
635
637
|
args.Handled(true);
|
|
636
638
|
}
|
|
637
639
|
|
|
@@ -641,6 +643,8 @@ void CompositionEventHandler::onKeyDown(
|
|
|
641
643
|
|
|
642
644
|
void CompositionEventHandler::onKeyUp(
|
|
643
645
|
const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept {
|
|
646
|
+
RootComponentView().UseKeyboardForProgrammaticFocus(true);
|
|
647
|
+
|
|
644
648
|
if (auto focusedComponent = RootComponentView().GetFocusedComponent()) {
|
|
645
649
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(focusedComponent)->OnKeyUp(args);
|
|
646
650
|
|
|
@@ -1173,6 +1177,8 @@ void CompositionEventHandler::onPointerPressed(
|
|
|
1173
1177
|
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
|
|
1174
1178
|
namespace Composition = winrt::Microsoft::ReactNative::Composition;
|
|
1175
1179
|
|
|
1180
|
+
RootComponentView().UseKeyboardForProgrammaticFocus(false);
|
|
1181
|
+
|
|
1176
1182
|
// Clears any active text selection when left pointer is pressed
|
|
1177
1183
|
if (pointerPoint.Properties().PointerUpdateKind() != Composition::Input::PointerUpdateKind::RightButtonPressed) {
|
|
1178
1184
|
RootComponentView().ClearCurrentTextSelection();
|
|
@@ -1210,6 +1216,30 @@ void CompositionEventHandler::onPointerPressed(
|
|
|
1210
1216
|
ActiveTouch activeTouch{0};
|
|
1211
1217
|
activeTouch.touchType = UITouchType::Mouse;
|
|
1212
1218
|
|
|
1219
|
+
// Map PointerUpdateKind to W3C button value
|
|
1220
|
+
// https://developer.mozilla.org/docs/Web/API/MouseEvent/button
|
|
1221
|
+
auto updateKind = pointerPoint.Properties().PointerUpdateKind();
|
|
1222
|
+
switch (updateKind) {
|
|
1223
|
+
case Composition::Input::PointerUpdateKind::LeftButtonPressed:
|
|
1224
|
+
activeTouch.button = 0;
|
|
1225
|
+
break;
|
|
1226
|
+
case Composition::Input::PointerUpdateKind::MiddleButtonPressed:
|
|
1227
|
+
activeTouch.button = 1;
|
|
1228
|
+
break;
|
|
1229
|
+
case Composition::Input::PointerUpdateKind::RightButtonPressed:
|
|
1230
|
+
activeTouch.button = 2;
|
|
1231
|
+
break;
|
|
1232
|
+
case Composition::Input::PointerUpdateKind::XButton1Pressed:
|
|
1233
|
+
activeTouch.button = 3;
|
|
1234
|
+
break;
|
|
1235
|
+
case Composition::Input::PointerUpdateKind::XButton2Pressed:
|
|
1236
|
+
activeTouch.button = 4;
|
|
1237
|
+
break;
|
|
1238
|
+
default:
|
|
1239
|
+
activeTouch.button = -1;
|
|
1240
|
+
break;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1213
1243
|
while (targetComponentView) {
|
|
1214
1244
|
if (auto eventEmitter =
|
|
1215
1245
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(targetComponentView)
|
|
@@ -1245,6 +1275,8 @@ void CompositionEventHandler::onPointerReleased(
|
|
|
1245
1275
|
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
|
|
1246
1276
|
int pointerId = pointerPoint.PointerId();
|
|
1247
1277
|
|
|
1278
|
+
RootComponentView().UseKeyboardForProgrammaticFocus(false);
|
|
1279
|
+
|
|
1248
1280
|
auto activeTouch = std::find_if(m_activeTouches.begin(), m_activeTouches.end(), [pointerId](const auto &pair) {
|
|
1249
1281
|
return pair.second.touch.identifier == pointerId;
|
|
1250
1282
|
});
|
|
@@ -1394,8 +1426,34 @@ facebook::react::PointerEvent CompositionEventHandler::CreatePointerEventFromAct
|
|
|
1394
1426
|
|
|
1395
1427
|
event.detail = 0;
|
|
1396
1428
|
|
|
1397
|
-
|
|
1398
|
-
|
|
1429
|
+
event.button = activeTouch.button;
|
|
1430
|
+
|
|
1431
|
+
// Build W3C buttons bitmask from the active button
|
|
1432
|
+
// https://developer.mozilla.org/docs/Web/API/MouseEvent/buttons
|
|
1433
|
+
if (IsEndishEventType(eventType)) {
|
|
1434
|
+
event.buttons = 0;
|
|
1435
|
+
} else {
|
|
1436
|
+
switch (activeTouch.button) {
|
|
1437
|
+
case 0:
|
|
1438
|
+
event.buttons = 1;
|
|
1439
|
+
break; // primary
|
|
1440
|
+
case 1:
|
|
1441
|
+
event.buttons = 4;
|
|
1442
|
+
break; // auxiliary (middle)
|
|
1443
|
+
case 2:
|
|
1444
|
+
event.buttons = 2;
|
|
1445
|
+
break; // secondary (right)
|
|
1446
|
+
case 3:
|
|
1447
|
+
event.buttons = 8;
|
|
1448
|
+
break; // X1
|
|
1449
|
+
case 4:
|
|
1450
|
+
event.buttons = 16;
|
|
1451
|
+
break; // X2
|
|
1452
|
+
default:
|
|
1453
|
+
event.buttons = 0;
|
|
1454
|
+
break;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1399
1457
|
|
|
1400
1458
|
// UpdatePointerEventModifierFlags(event, activeTouch.modifierFlags);
|
|
1401
1459
|
|
|
@@ -373,7 +373,8 @@ void ComponentView::onGotFocus(
|
|
|
373
373
|
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
374
374
|
if (args.OriginalSource() == Tag()) {
|
|
375
375
|
m_eventEmitter->onFocus();
|
|
376
|
-
if (viewProps()->enableFocusRing
|
|
376
|
+
if (viewProps()->enableFocusRing &&
|
|
377
|
+
rootComponentView()->focusState() == winrt::Microsoft::ReactNative::FocusState::Keyboard) {
|
|
377
378
|
facebook::react::Rect focusRect = m_layoutMetrics.frame;
|
|
378
379
|
focusRect.origin.x -= (FOCUS_VISUAL_WIDTH * 2);
|
|
379
380
|
focusRect.origin.y -= (FOCUS_VISUAL_WIDTH * 2);
|
|
@@ -426,15 +427,20 @@ void ComponentView::HandleCommand(const winrt::Microsoft::ReactNative::HandleCom
|
|
|
426
427
|
auto commandName = args.CommandName();
|
|
427
428
|
if (commandName == L"focus") {
|
|
428
429
|
if (auto root = rootComponentView()) {
|
|
429
|
-
root->TrySetFocusedComponent(
|
|
430
|
+
root->TrySetFocusedComponent(
|
|
431
|
+
*get_strong(),
|
|
432
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
433
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
430
434
|
}
|
|
431
435
|
return;
|
|
432
436
|
}
|
|
433
437
|
if (commandName == L"blur") {
|
|
434
438
|
if (auto root = rootComponentView()) {
|
|
435
439
|
root->TrySetFocusedComponent(
|
|
436
|
-
nullptr,
|
|
437
|
-
|
|
440
|
+
nullptr,
|
|
441
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
442
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic); // Todo store this component as
|
|
443
|
+
// previously focused element
|
|
438
444
|
}
|
|
439
445
|
return;
|
|
440
446
|
}
|
|
@@ -82,7 +82,7 @@ void ContentIslandComponentView::ConnectInternal() noexcept {
|
|
|
82
82
|
m_navigationHost.DepartFocusRequested([wkThis = get_weak()](const auto &, const auto &args) {
|
|
83
83
|
if (auto strongThis = wkThis.get()) {
|
|
84
84
|
const bool next = (args.Request().Reason() != winrt::Microsoft::UI::Input::FocusNavigationReason::Last);
|
|
85
|
-
strongThis->rootComponentView()->TryMoveFocus(next);
|
|
85
|
+
strongThis->rootComponentView()->TryMoveFocus(next, winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
86
86
|
args.Result(winrt::Microsoft::UI::Input::FocusNavigationResult::Moved);
|
|
87
87
|
}
|
|
88
88
|
});
|
|
@@ -622,7 +622,10 @@ void ParagraphComponentView::OnPointerPressed(
|
|
|
622
622
|
|
|
623
623
|
// Focuses so we receive onLostFocus when clicking elsewhere
|
|
624
624
|
if (auto root = rootComponentView()) {
|
|
625
|
-
root->TrySetFocusedComponent(
|
|
625
|
+
root->TrySetFocusedComponent(
|
|
626
|
+
*get_strong(),
|
|
627
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
628
|
+
winrt::Microsoft::ReactNative::FocusState::Pointer);
|
|
626
629
|
}
|
|
627
630
|
|
|
628
631
|
args.Handled(true);
|
|
@@ -82,7 +82,8 @@ winrt::Microsoft::ReactNative::ComponentView RootComponentView::GetFocusedCompon
|
|
|
82
82
|
|
|
83
83
|
void RootComponentView::SetFocusedComponent(
|
|
84
84
|
const winrt::Microsoft::ReactNative::ComponentView &value,
|
|
85
|
-
winrt::Microsoft::ReactNative::FocusNavigationDirection direction
|
|
85
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
|
|
86
|
+
winrt::Microsoft::ReactNative::FocusState focusState) noexcept {
|
|
86
87
|
if (m_focusedComponent == value)
|
|
87
88
|
return;
|
|
88
89
|
|
|
@@ -97,11 +98,26 @@ void RootComponentView::SetFocusedComponent(
|
|
|
97
98
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->TrySetFocus();
|
|
98
99
|
}
|
|
99
100
|
m_focusedComponent = value;
|
|
101
|
+
if (focusState == winrt::Microsoft::ReactNative::FocusState::Programmatic) {
|
|
102
|
+
focusState =
|
|
103
|
+
(!m_useKeyboardForProgrammaticFocus || m_focusState == winrt::Microsoft::ReactNative::FocusState::Pointer)
|
|
104
|
+
? winrt::Microsoft::ReactNative::FocusState::Pointer
|
|
105
|
+
: winrt::Microsoft::ReactNative::FocusState::Keyboard;
|
|
106
|
+
}
|
|
107
|
+
m_focusState = focusState;
|
|
100
108
|
auto args = winrt::make<winrt::Microsoft::ReactNative::implementation::GotFocusEventArgs>(value, direction);
|
|
101
109
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(value)->onGotFocus(args);
|
|
102
110
|
}
|
|
103
111
|
}
|
|
104
112
|
|
|
113
|
+
winrt::Microsoft::ReactNative::FocusState RootComponentView::focusState() const noexcept {
|
|
114
|
+
return m_focusState;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
void RootComponentView::UseKeyboardForProgrammaticFocus(bool value) noexcept {
|
|
118
|
+
m_useKeyboardForProgrammaticFocus = value;
|
|
119
|
+
}
|
|
120
|
+
|
|
105
121
|
bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept {
|
|
106
122
|
if (request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::Restore) {
|
|
107
123
|
if (m_focusedComponent)
|
|
@@ -116,7 +132,8 @@ bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::Focus
|
|
|
116
132
|
view,
|
|
117
133
|
request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::First
|
|
118
134
|
? winrt::Microsoft::ReactNative::FocusNavigationDirection::First
|
|
119
|
-
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Last
|
|
135
|
+
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Last,
|
|
136
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
120
137
|
}
|
|
121
138
|
return view != nullptr;
|
|
122
139
|
}
|
|
@@ -124,6 +141,7 @@ bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::Focus
|
|
|
124
141
|
bool RootComponentView::TrySetFocusedComponent(
|
|
125
142
|
const winrt::Microsoft::ReactNative::ComponentView &view,
|
|
126
143
|
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
|
|
144
|
+
winrt::Microsoft::ReactNative::FocusState focusState,
|
|
127
145
|
bool forceNoSelectionIfCannotMove /*= false*/) noexcept {
|
|
128
146
|
auto target = view;
|
|
129
147
|
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(target);
|
|
@@ -157,15 +175,15 @@ bool RootComponentView::TrySetFocusedComponent(
|
|
|
157
175
|
|
|
158
176
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(losingFocusArgs.NewFocusedComponent())
|
|
159
177
|
->rootComponentView()
|
|
160
|
-
->SetFocusedComponent(gettingFocusArgs.NewFocusedComponent(), direction);
|
|
178
|
+
->SetFocusedComponent(gettingFocusArgs.NewFocusedComponent(), direction, focusState);
|
|
161
179
|
} else {
|
|
162
|
-
SetFocusedComponent(nullptr, direction);
|
|
180
|
+
SetFocusedComponent(nullptr, direction, focusState);
|
|
163
181
|
}
|
|
164
182
|
|
|
165
183
|
return true;
|
|
166
184
|
}
|
|
167
185
|
|
|
168
|
-
bool RootComponentView::TryMoveFocus(bool next) noexcept {
|
|
186
|
+
bool RootComponentView::TryMoveFocus(bool next, winrt::Microsoft::ReactNative::FocusState focusState) noexcept {
|
|
169
187
|
if (!m_focusedComponent) {
|
|
170
188
|
return NavigateFocus(winrt::Microsoft::ReactNative::FocusNavigationRequest(
|
|
171
189
|
next ? winrt::Microsoft::ReactNative::FocusNavigationReason::First
|
|
@@ -173,7 +191,8 @@ bool RootComponentView::TryMoveFocus(bool next) noexcept {
|
|
|
173
191
|
}
|
|
174
192
|
|
|
175
193
|
Mso::Functor<bool(const winrt::Microsoft::ReactNative::ComponentView &)> fn =
|
|
176
|
-
[currentlyFocused = m_focusedComponent, next](
|
|
194
|
+
[currentlyFocused = m_focusedComponent, next, focusState](
|
|
195
|
+
const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
|
|
177
196
|
if (view == currentlyFocused)
|
|
178
197
|
return false;
|
|
179
198
|
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view);
|
|
@@ -185,7 +204,8 @@ bool RootComponentView::TryMoveFocus(bool next) noexcept {
|
|
|
185
204
|
->TrySetFocusedComponent(
|
|
186
205
|
view,
|
|
187
206
|
next ? winrt::Microsoft::ReactNative::FocusNavigationDirection::Next
|
|
188
|
-
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous
|
|
207
|
+
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous,
|
|
208
|
+
focusState);
|
|
189
209
|
};
|
|
190
210
|
|
|
191
211
|
if (winrt::Microsoft::ReactNative::implementation::walkTree(m_focusedComponent, next, fn)) {
|
|
@@ -249,7 +269,10 @@ void RootComponentView::start(const winrt::Microsoft::ReactNative::ReactNativeIs
|
|
|
249
269
|
}
|
|
250
270
|
|
|
251
271
|
void RootComponentView::stop() noexcept {
|
|
252
|
-
SetFocusedComponent(
|
|
272
|
+
SetFocusedComponent(
|
|
273
|
+
nullptr,
|
|
274
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
275
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
253
276
|
if (m_visualAddedToIsland) {
|
|
254
277
|
if (auto rootView = m_wkRootView.get()) {
|
|
255
278
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->RemoveRenderedVisual(
|
|
@@ -30,15 +30,17 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
|
|
|
30
30
|
winrt::Microsoft::ReactNative::ComponentView GetFocusedComponent() noexcept;
|
|
31
31
|
void SetFocusedComponent(
|
|
32
32
|
const winrt::Microsoft::ReactNative::ComponentView &value,
|
|
33
|
-
winrt::Microsoft::ReactNative::FocusNavigationDirection direction
|
|
33
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
|
|
34
|
+
winrt::Microsoft::ReactNative::FocusState focusState) noexcept;
|
|
34
35
|
bool TrySetFocusedComponent(
|
|
35
36
|
const winrt::Microsoft::ReactNative::ComponentView &view,
|
|
36
37
|
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
|
|
38
|
+
winrt::Microsoft::ReactNative::FocusState focusState,
|
|
37
39
|
bool forceNoSelectionIfCannotMove = false) noexcept;
|
|
38
40
|
|
|
39
41
|
bool NavigateFocus(const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept;
|
|
40
42
|
|
|
41
|
-
bool TryMoveFocus(bool next) noexcept;
|
|
43
|
+
bool TryMoveFocus(bool next, winrt::Microsoft::ReactNative::FocusState focusState) noexcept;
|
|
42
44
|
|
|
43
45
|
RootComponentView *rootComponentView() const noexcept override;
|
|
44
46
|
|
|
@@ -90,14 +92,20 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
|
|
|
90
92
|
void ClearCurrentTextSelection() noexcept;
|
|
91
93
|
void SetViewWithTextSelection(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
92
94
|
|
|
95
|
+
winrt::Microsoft::ReactNative::FocusState focusState() const noexcept;
|
|
96
|
+
|
|
97
|
+
void UseKeyboardForProgrammaticFocus(bool value) noexcept;
|
|
98
|
+
|
|
93
99
|
private:
|
|
94
100
|
// should this be a ReactTaggedView? - It shouldn't actually matter since if the view is going away it should always
|
|
95
101
|
// be clearing its focus But being a reactTaggedView might make it easier to identify cases where that isn't
|
|
96
102
|
// happening.
|
|
97
103
|
winrt::Microsoft::ReactNative::ComponentView m_focusedComponent{nullptr};
|
|
104
|
+
winrt::Microsoft::ReactNative::FocusState m_focusState{winrt::Microsoft::ReactNative::FocusState::Unfocused};
|
|
98
105
|
winrt::weak_ref<winrt::Microsoft::ReactNative::ReactNativeIsland> m_wkRootView{nullptr};
|
|
99
106
|
winrt::weak_ref<winrt::Microsoft::ReactNative::Composition::PortalComponentView> m_wkPortal{nullptr};
|
|
100
107
|
bool m_visualAddedToIsland{false};
|
|
108
|
+
bool m_useKeyboardForProgrammaticFocus{true};
|
|
101
109
|
|
|
102
110
|
::Microsoft::ReactNative::ReactTaggedView m_viewWithTextSelection{
|
|
103
111
|
winrt::Microsoft::ReactNative::ComponentView{nullptr}};
|
|
@@ -271,7 +271,10 @@ void SwitchComponentView::OnPointerPressed(
|
|
|
271
271
|
m_supressAnimationForNextFrame = true;
|
|
272
272
|
|
|
273
273
|
if (auto root = rootComponentView()) {
|
|
274
|
-
root->TrySetFocusedComponent(
|
|
274
|
+
root->TrySetFocusedComponent(
|
|
275
|
+
*get_strong(),
|
|
276
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
277
|
+
winrt::Microsoft::ReactNative::FocusState::Pointer);
|
|
275
278
|
}
|
|
276
279
|
|
|
277
280
|
updateVisuals();
|
package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp
CHANGED
|
@@ -233,7 +233,9 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
|
|
|
233
233
|
winrt::check_hresult(
|
|
234
234
|
m_outer->QueryInterface(winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(view)));
|
|
235
235
|
m_outer->rootComponentView()->TrySetFocusedComponent(
|
|
236
|
-
view,
|
|
236
|
+
view,
|
|
237
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
238
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
237
239
|
// assert(false);
|
|
238
240
|
// TODO focus
|
|
239
241
|
}
|
|
@@ -1469,7 +1471,10 @@ void WindowsTextInputComponentView::onMounted() noexcept {
|
|
|
1469
1471
|
// Handle autoFocus property - focus the component when mounted if autoFocus is true
|
|
1470
1472
|
if (windowsTextInputProps().autoFocus) {
|
|
1471
1473
|
if (auto root = rootComponentView()) {
|
|
1472
|
-
root->TrySetFocusedComponent(
|
|
1474
|
+
root->TrySetFocusedComponent(
|
|
1475
|
+
*get_strong(),
|
|
1476
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
1477
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
1473
1478
|
}
|
|
1474
1479
|
}
|
|
1475
1480
|
}
|
|
@@ -141,7 +141,10 @@ HRESULT UiaSetFocusHelper(::Microsoft::ReactNative::ReactTaggedView &view) noexc
|
|
|
141
141
|
if (rootCV == nullptr)
|
|
142
142
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
143
143
|
|
|
144
|
-
return rootCV->TrySetFocusedComponent(
|
|
144
|
+
return rootCV->TrySetFocusedComponent(
|
|
145
|
+
strongView,
|
|
146
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
147
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic)
|
|
145
148
|
? S_OK
|
|
146
149
|
: E_FAIL;
|
|
147
150
|
}
|
|
@@ -266,6 +266,10 @@ class ReactNativeWindowsFeatureFlags : public facebook::react::ReactNativeFeatur
|
|
|
266
266
|
return true;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
bool enableImperativeFocus() override {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
|
|
269
273
|
bool fuseboxEnabledRelease() override {
|
|
270
274
|
return true; // Enable Fusebox (modern CDP backend) by default for React Native Windows
|
|
271
275
|
}
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.
|
|
13
|
+
<ReactNativeWindowsVersion>0.83.0-preview.2</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
|
-
<ReactNativeWindowsMinor>
|
|
15
|
+
<ReactNativeWindowsMinor>83</ReactNativeWindowsMinor>
|
|
16
16
|
<ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
|
|
17
|
-
<ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
17
|
+
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
+
<ReactNativeWindowsCommitId>d89154d68c6b2f5f1a2355042d166f9dac8f1ba3</ReactNativeWindowsCommitId>
|
|
19
19
|
</PropertyGroup>
|
|
20
20
|
</Project>
|
package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/BaseViewProps.cpp
ADDED
|
@@ -0,0 +1,664 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "BaseViewProps.h"
|
|
9
|
+
|
|
10
|
+
#include <algorithm>
|
|
11
|
+
|
|
12
|
+
#include <react/featureflags/ReactNativeFeatureFlags.h>
|
|
13
|
+
#include <react/renderer/components/view/BackgroundImagePropsConversions.h>
|
|
14
|
+
#include <react/renderer/components/view/BoxShadowPropsConversions.h>
|
|
15
|
+
#include <react/renderer/components/view/FilterPropsConversions.h>
|
|
16
|
+
#include <react/renderer/components/view/conversions.h>
|
|
17
|
+
#include <react/renderer/components/view/primitives.h>
|
|
18
|
+
#include <react/renderer/components/view/propsConversions.h>
|
|
19
|
+
#include <react/renderer/core/graphicsConversions.h>
|
|
20
|
+
#include <react/renderer/core/propsConversions.h>
|
|
21
|
+
#include <react/renderer/debug/debugStringConvertibleUtils.h>
|
|
22
|
+
#include <react/renderer/graphics/ValueUnit.h>
|
|
23
|
+
|
|
24
|
+
namespace facebook::react {
|
|
25
|
+
|
|
26
|
+
namespace {
|
|
27
|
+
|
|
28
|
+
std::array<float, 3> getTranslateForTransformOrigin(
|
|
29
|
+
float viewWidth,
|
|
30
|
+
float viewHeight,
|
|
31
|
+
TransformOrigin transformOrigin) {
|
|
32
|
+
float viewCenterX = viewWidth / 2;
|
|
33
|
+
float viewCenterY = viewHeight / 2;
|
|
34
|
+
|
|
35
|
+
std::array<float, 3> origin = {viewCenterX, viewCenterY, transformOrigin.z};
|
|
36
|
+
|
|
37
|
+
for (size_t i = 0; i < transformOrigin.xy.size(); ++i) {
|
|
38
|
+
auto& currentOrigin = transformOrigin.xy[i];
|
|
39
|
+
if (currentOrigin.unit == UnitType::Point) {
|
|
40
|
+
origin[i] = currentOrigin.value;
|
|
41
|
+
} else if (currentOrigin.unit == UnitType::Percent) {
|
|
42
|
+
origin[i] =
|
|
43
|
+
((i == 0) ? viewWidth : viewHeight) * currentOrigin.value / 100.0f;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
float newTranslateX = -viewCenterX + origin[0];
|
|
48
|
+
float newTranslateY = -viewCenterY + origin[1];
|
|
49
|
+
float newTranslateZ = origin[2];
|
|
50
|
+
|
|
51
|
+
return std::array{newTranslateX, newTranslateY, newTranslateZ};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
} // namespace
|
|
55
|
+
|
|
56
|
+
BaseViewProps::BaseViewProps(
|
|
57
|
+
const PropsParserContext& context,
|
|
58
|
+
const BaseViewProps& sourceProps,
|
|
59
|
+
const RawProps& rawProps,
|
|
60
|
+
const std::function<bool(const std::string&)>& filterObjectKeys)
|
|
61
|
+
: YogaStylableProps(context, sourceProps, rawProps, filterObjectKeys),
|
|
62
|
+
AccessibilityProps(context, sourceProps, rawProps),
|
|
63
|
+
opacity(
|
|
64
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
65
|
+
? sourceProps.opacity
|
|
66
|
+
: convertRawProp(
|
|
67
|
+
context,
|
|
68
|
+
rawProps,
|
|
69
|
+
"opacity",
|
|
70
|
+
sourceProps.opacity,
|
|
71
|
+
(Float)1.0)),
|
|
72
|
+
backgroundColor(
|
|
73
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
74
|
+
? sourceProps.backgroundColor
|
|
75
|
+
: convertRawProp(
|
|
76
|
+
context,
|
|
77
|
+
rawProps,
|
|
78
|
+
"backgroundColor",
|
|
79
|
+
sourceProps.backgroundColor,
|
|
80
|
+
{})),
|
|
81
|
+
borderRadii(
|
|
82
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
83
|
+
? sourceProps.borderRadii
|
|
84
|
+
: convertRawProp(
|
|
85
|
+
context,
|
|
86
|
+
rawProps,
|
|
87
|
+
"border",
|
|
88
|
+
"Radius",
|
|
89
|
+
sourceProps.borderRadii,
|
|
90
|
+
{})),
|
|
91
|
+
borderColors(
|
|
92
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
93
|
+
? sourceProps.borderColors
|
|
94
|
+
: convertRawProp(
|
|
95
|
+
context,
|
|
96
|
+
rawProps,
|
|
97
|
+
"border",
|
|
98
|
+
"Color",
|
|
99
|
+
sourceProps.borderColors,
|
|
100
|
+
{})),
|
|
101
|
+
borderCurves(
|
|
102
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
103
|
+
? sourceProps.borderCurves
|
|
104
|
+
: convertRawProp(
|
|
105
|
+
context,
|
|
106
|
+
rawProps,
|
|
107
|
+
"border",
|
|
108
|
+
"Curve",
|
|
109
|
+
sourceProps.borderCurves,
|
|
110
|
+
{})),
|
|
111
|
+
borderStyles(
|
|
112
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
113
|
+
? sourceProps.borderStyles
|
|
114
|
+
: convertRawProp(
|
|
115
|
+
context,
|
|
116
|
+
rawProps,
|
|
117
|
+
"border",
|
|
118
|
+
"Style",
|
|
119
|
+
sourceProps.borderStyles,
|
|
120
|
+
{})),
|
|
121
|
+
outlineColor(
|
|
122
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
123
|
+
? sourceProps.outlineColor
|
|
124
|
+
: convertRawProp(
|
|
125
|
+
context,
|
|
126
|
+
rawProps,
|
|
127
|
+
"outlineColor",
|
|
128
|
+
sourceProps.outlineColor,
|
|
129
|
+
{})),
|
|
130
|
+
outlineOffset(
|
|
131
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
132
|
+
? sourceProps.outlineOffset
|
|
133
|
+
: convertRawProp(
|
|
134
|
+
context,
|
|
135
|
+
rawProps,
|
|
136
|
+
"outlineOffset",
|
|
137
|
+
sourceProps.outlineOffset,
|
|
138
|
+
{})),
|
|
139
|
+
outlineStyle(
|
|
140
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
141
|
+
? sourceProps.outlineStyle
|
|
142
|
+
: convertRawProp(
|
|
143
|
+
context,
|
|
144
|
+
rawProps,
|
|
145
|
+
"outlineStyle",
|
|
146
|
+
sourceProps.outlineStyle,
|
|
147
|
+
{})),
|
|
148
|
+
outlineWidth(
|
|
149
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
150
|
+
? sourceProps.outlineWidth
|
|
151
|
+
: convertRawProp(
|
|
152
|
+
context,
|
|
153
|
+
rawProps,
|
|
154
|
+
"outlineWidth",
|
|
155
|
+
sourceProps.outlineWidth,
|
|
156
|
+
{})),
|
|
157
|
+
shadowColor(
|
|
158
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
159
|
+
? sourceProps.shadowColor
|
|
160
|
+
: convertRawProp(
|
|
161
|
+
context,
|
|
162
|
+
rawProps,
|
|
163
|
+
"shadowColor",
|
|
164
|
+
sourceProps.shadowColor,
|
|
165
|
+
{})),
|
|
166
|
+
shadowOffset(
|
|
167
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
168
|
+
? sourceProps.shadowOffset
|
|
169
|
+
: convertRawProp(
|
|
170
|
+
context,
|
|
171
|
+
rawProps,
|
|
172
|
+
"shadowOffset",
|
|
173
|
+
sourceProps.shadowOffset,
|
|
174
|
+
{})),
|
|
175
|
+
shadowOpacity(
|
|
176
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
177
|
+
? sourceProps.shadowOpacity
|
|
178
|
+
: convertRawProp(
|
|
179
|
+
context,
|
|
180
|
+
rawProps,
|
|
181
|
+
"shadowOpacity",
|
|
182
|
+
sourceProps.shadowOpacity,
|
|
183
|
+
{})),
|
|
184
|
+
shadowRadius(
|
|
185
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
186
|
+
? sourceProps.shadowRadius
|
|
187
|
+
: convertRawProp(
|
|
188
|
+
context,
|
|
189
|
+
rawProps,
|
|
190
|
+
"shadowRadius",
|
|
191
|
+
sourceProps.shadowRadius,
|
|
192
|
+
{})),
|
|
193
|
+
cursor(
|
|
194
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
195
|
+
? sourceProps.cursor
|
|
196
|
+
: convertRawProp(
|
|
197
|
+
context,
|
|
198
|
+
rawProps,
|
|
199
|
+
"cursor",
|
|
200
|
+
sourceProps.cursor,
|
|
201
|
+
{})),
|
|
202
|
+
boxShadow(
|
|
203
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
204
|
+
? sourceProps.boxShadow
|
|
205
|
+
: convertRawProp(
|
|
206
|
+
context,
|
|
207
|
+
rawProps,
|
|
208
|
+
"boxShadow",
|
|
209
|
+
sourceProps.boxShadow,
|
|
210
|
+
{})),
|
|
211
|
+
filter(
|
|
212
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
213
|
+
? sourceProps.filter
|
|
214
|
+
: convertRawProp(
|
|
215
|
+
context,
|
|
216
|
+
rawProps,
|
|
217
|
+
"filter",
|
|
218
|
+
sourceProps.filter,
|
|
219
|
+
{})),
|
|
220
|
+
backgroundImage(
|
|
221
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
222
|
+
? sourceProps.backgroundImage
|
|
223
|
+
: convertRawProp(
|
|
224
|
+
context,
|
|
225
|
+
rawProps,
|
|
226
|
+
"experimental_backgroundImage",
|
|
227
|
+
sourceProps.backgroundImage,
|
|
228
|
+
{})),
|
|
229
|
+
backgroundSize(
|
|
230
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
231
|
+
? sourceProps.backgroundSize
|
|
232
|
+
: convertRawProp(
|
|
233
|
+
context,
|
|
234
|
+
rawProps,
|
|
235
|
+
"experimental_backgroundSize",
|
|
236
|
+
sourceProps.backgroundSize,
|
|
237
|
+
{})),
|
|
238
|
+
backgroundPosition(
|
|
239
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
240
|
+
? sourceProps.backgroundPosition
|
|
241
|
+
: convertRawProp(
|
|
242
|
+
context,
|
|
243
|
+
rawProps,
|
|
244
|
+
"experimental_backgroundPosition",
|
|
245
|
+
sourceProps.backgroundPosition,
|
|
246
|
+
{})),
|
|
247
|
+
backgroundRepeat(
|
|
248
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
249
|
+
? sourceProps.backgroundRepeat
|
|
250
|
+
: convertRawProp(
|
|
251
|
+
context,
|
|
252
|
+
rawProps,
|
|
253
|
+
"experimental_backgroundRepeat",
|
|
254
|
+
sourceProps.backgroundRepeat,
|
|
255
|
+
{})),
|
|
256
|
+
mixBlendMode(
|
|
257
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
258
|
+
? sourceProps.mixBlendMode
|
|
259
|
+
: convertRawProp(
|
|
260
|
+
context,
|
|
261
|
+
rawProps,
|
|
262
|
+
"mixBlendMode",
|
|
263
|
+
sourceProps.mixBlendMode,
|
|
264
|
+
{})),
|
|
265
|
+
isolation(
|
|
266
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
267
|
+
? sourceProps.isolation
|
|
268
|
+
: convertRawProp(
|
|
269
|
+
context,
|
|
270
|
+
rawProps,
|
|
271
|
+
"isolation",
|
|
272
|
+
sourceProps.isolation,
|
|
273
|
+
{})),
|
|
274
|
+
transform(
|
|
275
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
276
|
+
? sourceProps.transform
|
|
277
|
+
: convertRawProp(
|
|
278
|
+
context,
|
|
279
|
+
rawProps,
|
|
280
|
+
"transform",
|
|
281
|
+
sourceProps.transform,
|
|
282
|
+
{})),
|
|
283
|
+
transformOrigin(
|
|
284
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
285
|
+
? sourceProps.transformOrigin
|
|
286
|
+
: convertRawProp(
|
|
287
|
+
context,
|
|
288
|
+
rawProps,
|
|
289
|
+
"transformOrigin",
|
|
290
|
+
sourceProps.transformOrigin,
|
|
291
|
+
{})),
|
|
292
|
+
backfaceVisibility(
|
|
293
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
294
|
+
? sourceProps.backfaceVisibility
|
|
295
|
+
: convertRawProp(
|
|
296
|
+
context,
|
|
297
|
+
rawProps,
|
|
298
|
+
"backfaceVisibility",
|
|
299
|
+
sourceProps.backfaceVisibility,
|
|
300
|
+
{})),
|
|
301
|
+
shouldRasterize(
|
|
302
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
303
|
+
? sourceProps.shouldRasterize
|
|
304
|
+
: convertRawProp(
|
|
305
|
+
context,
|
|
306
|
+
rawProps,
|
|
307
|
+
"shouldRasterizeIOS",
|
|
308
|
+
sourceProps.shouldRasterize,
|
|
309
|
+
{})),
|
|
310
|
+
zIndex(
|
|
311
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
312
|
+
? sourceProps.zIndex
|
|
313
|
+
: convertRawProp(
|
|
314
|
+
context,
|
|
315
|
+
rawProps,
|
|
316
|
+
"zIndex",
|
|
317
|
+
sourceProps.zIndex,
|
|
318
|
+
{})),
|
|
319
|
+
pointerEvents(
|
|
320
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
321
|
+
? sourceProps.pointerEvents
|
|
322
|
+
: convertRawProp(
|
|
323
|
+
context,
|
|
324
|
+
rawProps,
|
|
325
|
+
"pointerEvents",
|
|
326
|
+
sourceProps.pointerEvents,
|
|
327
|
+
{})),
|
|
328
|
+
hitSlop(
|
|
329
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
330
|
+
? sourceProps.hitSlop
|
|
331
|
+
: convertRawProp(
|
|
332
|
+
context,
|
|
333
|
+
rawProps,
|
|
334
|
+
"hitSlop",
|
|
335
|
+
sourceProps.hitSlop,
|
|
336
|
+
{})),
|
|
337
|
+
onLayout(
|
|
338
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
339
|
+
? sourceProps.onLayout
|
|
340
|
+
: convertRawProp(
|
|
341
|
+
context,
|
|
342
|
+
rawProps,
|
|
343
|
+
"onLayout",
|
|
344
|
+
sourceProps.onLayout,
|
|
345
|
+
{})),
|
|
346
|
+
events(
|
|
347
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
348
|
+
? sourceProps.events
|
|
349
|
+
: convertRawProp(context, rawProps, sourceProps.events, {})),
|
|
350
|
+
collapsable(
|
|
351
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
352
|
+
? sourceProps.collapsable
|
|
353
|
+
: convertRawProp(
|
|
354
|
+
context,
|
|
355
|
+
rawProps,
|
|
356
|
+
"collapsable",
|
|
357
|
+
sourceProps.collapsable,
|
|
358
|
+
true)),
|
|
359
|
+
collapsableChildren(
|
|
360
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
361
|
+
? sourceProps.collapsableChildren
|
|
362
|
+
: convertRawProp(
|
|
363
|
+
context,
|
|
364
|
+
rawProps,
|
|
365
|
+
"collapsableChildren",
|
|
366
|
+
sourceProps.collapsableChildren,
|
|
367
|
+
true)),
|
|
368
|
+
removeClippedSubviews(
|
|
369
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
370
|
+
? sourceProps.removeClippedSubviews
|
|
371
|
+
: convertRawProp(
|
|
372
|
+
context,
|
|
373
|
+
rawProps,
|
|
374
|
+
"removeClippedSubviews",
|
|
375
|
+
sourceProps.removeClippedSubviews,
|
|
376
|
+
false)) {}
|
|
377
|
+
|
|
378
|
+
#define VIEW_EVENT_CASE(eventType) \
|
|
379
|
+
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
|
|
380
|
+
const auto offset = ViewEvents::Offset::eventType; \
|
|
381
|
+
ViewEvents defaultViewEvents{}; \
|
|
382
|
+
bool res = defaultViewEvents[offset]; \
|
|
383
|
+
if (value.hasValue()) { \
|
|
384
|
+
fromRawValue(context, value, res); \
|
|
385
|
+
} \
|
|
386
|
+
events[offset] = res; \
|
|
387
|
+
return; \
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
void BaseViewProps::setProp(
|
|
391
|
+
const PropsParserContext& context,
|
|
392
|
+
RawPropsPropNameHash hash,
|
|
393
|
+
const char* propName,
|
|
394
|
+
const RawValue& value) {
|
|
395
|
+
// All Props structs setProp methods must always, unconditionally,
|
|
396
|
+
// call all super::setProp methods, since multiple structs may
|
|
397
|
+
// reuse the same values.
|
|
398
|
+
YogaStylableProps::setProp(context, hash, propName, value);
|
|
399
|
+
AccessibilityProps::setProp(context, hash, propName, value);
|
|
400
|
+
|
|
401
|
+
static auto defaults = BaseViewProps{};
|
|
402
|
+
|
|
403
|
+
switch (hash) {
|
|
404
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(opacity);
|
|
405
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(backgroundColor);
|
|
406
|
+
RAW_SET_PROP_SWITCH_CASE(backgroundImage, "experimental_backgroundImage");
|
|
407
|
+
RAW_SET_PROP_SWITCH_CASE(backgroundSize, "experimental_backgroundSize");
|
|
408
|
+
RAW_SET_PROP_SWITCH_CASE(
|
|
409
|
+
backgroundPosition, "experimental_backgroundPosition");
|
|
410
|
+
RAW_SET_PROP_SWITCH_CASE(backgroundRepeat, "experimental_backgroundRepeat");
|
|
411
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(shadowColor);
|
|
412
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(shadowOffset);
|
|
413
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(shadowOpacity);
|
|
414
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(shadowRadius);
|
|
415
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(transform);
|
|
416
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(backfaceVisibility);
|
|
417
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(shouldRasterize);
|
|
418
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(zIndex);
|
|
419
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(pointerEvents);
|
|
420
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(isolation);
|
|
421
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(hitSlop);
|
|
422
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(onLayout);
|
|
423
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
|
|
424
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsableChildren);
|
|
425
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
|
|
426
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(cursor);
|
|
427
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineColor);
|
|
428
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
|
|
429
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineStyle);
|
|
430
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineWidth);
|
|
431
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(filter);
|
|
432
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(boxShadow);
|
|
433
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(mixBlendMode);
|
|
434
|
+
// events field
|
|
435
|
+
VIEW_EVENT_CASE(PointerEnter);
|
|
436
|
+
VIEW_EVENT_CASE(PointerEnterCapture);
|
|
437
|
+
VIEW_EVENT_CASE(PointerMove);
|
|
438
|
+
VIEW_EVENT_CASE(PointerMoveCapture);
|
|
439
|
+
VIEW_EVENT_CASE(PointerLeave);
|
|
440
|
+
VIEW_EVENT_CASE(PointerLeaveCapture);
|
|
441
|
+
VIEW_EVENT_CASE(PointerOver);
|
|
442
|
+
VIEW_EVENT_CASE(PointerOverCapture);
|
|
443
|
+
VIEW_EVENT_CASE(PointerOut);
|
|
444
|
+
VIEW_EVENT_CASE(PointerOutCapture);
|
|
445
|
+
// [Windows
|
|
446
|
+
VIEW_EVENT_CASE(Click);
|
|
447
|
+
VIEW_EVENT_CASE(ClickCapture);
|
|
448
|
+
VIEW_EVENT_CASE(PointerDown);
|
|
449
|
+
VIEW_EVENT_CASE(PointerDownCapture);
|
|
450
|
+
VIEW_EVENT_CASE(PointerUp);
|
|
451
|
+
VIEW_EVENT_CASE(PointerUpCapture);
|
|
452
|
+
VIEW_EVENT_CASE(GotPointerCapture);
|
|
453
|
+
VIEW_EVENT_CASE(LostPointerCapture);
|
|
454
|
+
// Windows]
|
|
455
|
+
VIEW_EVENT_CASE(MoveShouldSetResponder);
|
|
456
|
+
VIEW_EVENT_CASE(MoveShouldSetResponderCapture);
|
|
457
|
+
VIEW_EVENT_CASE(StartShouldSetResponder);
|
|
458
|
+
VIEW_EVENT_CASE(StartShouldSetResponderCapture);
|
|
459
|
+
VIEW_EVENT_CASE(ResponderGrant);
|
|
460
|
+
VIEW_EVENT_CASE(ResponderReject);
|
|
461
|
+
VIEW_EVENT_CASE(ResponderStart);
|
|
462
|
+
VIEW_EVENT_CASE(ResponderEnd);
|
|
463
|
+
VIEW_EVENT_CASE(ResponderRelease);
|
|
464
|
+
VIEW_EVENT_CASE(ResponderMove);
|
|
465
|
+
VIEW_EVENT_CASE(ResponderTerminate);
|
|
466
|
+
VIEW_EVENT_CASE(ResponderTerminationRequest);
|
|
467
|
+
VIEW_EVENT_CASE(ShouldBlockNativeResponder);
|
|
468
|
+
VIEW_EVENT_CASE(TouchStart);
|
|
469
|
+
VIEW_EVENT_CASE(TouchMove);
|
|
470
|
+
VIEW_EVENT_CASE(TouchEnd);
|
|
471
|
+
VIEW_EVENT_CASE(TouchCancel);
|
|
472
|
+
// BorderRadii
|
|
473
|
+
SET_CASCADED_RECTANGLE_CORNERS(borderRadii, "border", "Radius", value);
|
|
474
|
+
SET_CASCADED_RECTANGLE_EDGES(borderColors, "border", "Color", value);
|
|
475
|
+
SET_CASCADED_RECTANGLE_EDGES(borderStyles, "border", "Style", value);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
#pragma mark - Convenience Methods
|
|
480
|
+
|
|
481
|
+
static BorderRadii ensureNoOverlap(const BorderRadii& radii, const Size& size) {
|
|
482
|
+
// "Corner curves must not overlap: When the sum of any two adjacent border
|
|
483
|
+
// radii exceeds the size of the border box, UAs must proportionally reduce
|
|
484
|
+
// the used values of all border radii until none of them overlap."
|
|
485
|
+
// Source: https://www.w3.org/TR/css-backgrounds-3/#corner-overlap
|
|
486
|
+
|
|
487
|
+
float leftEdgeRadii = radii.topLeft.vertical + radii.bottomLeft.vertical;
|
|
488
|
+
float topEdgeRadii = radii.topLeft.horizontal + radii.topRight.horizontal;
|
|
489
|
+
float rightEdgeRadii = radii.topRight.vertical + radii.bottomRight.vertical;
|
|
490
|
+
float bottomEdgeRadii =
|
|
491
|
+
radii.bottomLeft.horizontal + radii.bottomRight.horizontal;
|
|
492
|
+
|
|
493
|
+
float leftEdgeRadiiScale =
|
|
494
|
+
(leftEdgeRadii > 0) ? std::min(size.height / leftEdgeRadii, (Float)1) : 0;
|
|
495
|
+
float topEdgeRadiiScale =
|
|
496
|
+
(topEdgeRadii > 0) ? std::min(size.width / topEdgeRadii, (Float)1) : 0;
|
|
497
|
+
float rightEdgeRadiiScale = (rightEdgeRadii > 0)
|
|
498
|
+
? std::min(size.height / rightEdgeRadii, (Float)1)
|
|
499
|
+
: 0;
|
|
500
|
+
float bottomEdgeRadiiScale = (bottomEdgeRadii > 0)
|
|
501
|
+
? std::min(size.width / bottomEdgeRadii, (Float)1)
|
|
502
|
+
: 0;
|
|
503
|
+
|
|
504
|
+
return BorderRadii{
|
|
505
|
+
.topLeft =
|
|
506
|
+
{static_cast<float>(
|
|
507
|
+
radii.topLeft.vertical *
|
|
508
|
+
std::min(topEdgeRadiiScale, leftEdgeRadiiScale)),
|
|
509
|
+
static_cast<float>(
|
|
510
|
+
radii.topLeft.horizontal *
|
|
511
|
+
std::min(topEdgeRadiiScale, leftEdgeRadiiScale))},
|
|
512
|
+
.topRight =
|
|
513
|
+
{static_cast<float>(
|
|
514
|
+
radii.topRight.vertical *
|
|
515
|
+
std::min(topEdgeRadiiScale, rightEdgeRadiiScale)),
|
|
516
|
+
static_cast<float>(
|
|
517
|
+
radii.topRight.horizontal *
|
|
518
|
+
std::min(topEdgeRadiiScale, rightEdgeRadiiScale))},
|
|
519
|
+
.bottomLeft =
|
|
520
|
+
{static_cast<float>(
|
|
521
|
+
radii.bottomLeft.vertical *
|
|
522
|
+
std::min(bottomEdgeRadiiScale, leftEdgeRadiiScale)),
|
|
523
|
+
static_cast<float>(
|
|
524
|
+
radii.bottomLeft.horizontal *
|
|
525
|
+
std::min(bottomEdgeRadiiScale, leftEdgeRadiiScale))},
|
|
526
|
+
.bottomRight =
|
|
527
|
+
{static_cast<float>(
|
|
528
|
+
radii.bottomRight.vertical *
|
|
529
|
+
std::min(bottomEdgeRadiiScale, rightEdgeRadiiScale)),
|
|
530
|
+
static_cast<float>(
|
|
531
|
+
radii.bottomRight.horizontal *
|
|
532
|
+
std::min(bottomEdgeRadiiScale, rightEdgeRadiiScale))},
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
static BorderRadii radiiPercentToPoint(
|
|
537
|
+
const RectangleCorners<ValueUnit>& radii,
|
|
538
|
+
const Size& size) {
|
|
539
|
+
return BorderRadii{
|
|
540
|
+
.topLeft =
|
|
541
|
+
{radii.topLeft.resolve(size.height),
|
|
542
|
+
radii.topLeft.resolve(size.width)},
|
|
543
|
+
.topRight =
|
|
544
|
+
{radii.topRight.resolve(size.height),
|
|
545
|
+
radii.topRight.resolve(size.width)},
|
|
546
|
+
.bottomLeft =
|
|
547
|
+
{radii.bottomLeft.resolve(size.height),
|
|
548
|
+
radii.bottomLeft.resolve(size.width)},
|
|
549
|
+
.bottomRight =
|
|
550
|
+
{radii.bottomRight.resolve(size.height),
|
|
551
|
+
radii.bottomRight.resolve(size.width)},
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
CascadedBorderWidths BaseViewProps::getBorderWidths() const {
|
|
556
|
+
return CascadedBorderWidths{
|
|
557
|
+
.left = optionalFloatFromYogaValue(yogaStyle.border(yoga::Edge::Left)),
|
|
558
|
+
.top = optionalFloatFromYogaValue(yogaStyle.border(yoga::Edge::Top)),
|
|
559
|
+
.right = optionalFloatFromYogaValue(yogaStyle.border(yoga::Edge::Right)),
|
|
560
|
+
.bottom =
|
|
561
|
+
optionalFloatFromYogaValue(yogaStyle.border(yoga::Edge::Bottom)),
|
|
562
|
+
.start = optionalFloatFromYogaValue(yogaStyle.border(yoga::Edge::Start)),
|
|
563
|
+
.end = optionalFloatFromYogaValue(yogaStyle.border(yoga::Edge::End)),
|
|
564
|
+
.horizontal =
|
|
565
|
+
optionalFloatFromYogaValue(yogaStyle.border(yoga::Edge::Horizontal)),
|
|
566
|
+
.vertical =
|
|
567
|
+
optionalFloatFromYogaValue(yogaStyle.border(yoga::Edge::Vertical)),
|
|
568
|
+
.all = optionalFloatFromYogaValue(yogaStyle.border(yoga::Edge::All)),
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
BorderMetrics BaseViewProps::resolveBorderMetrics(
|
|
573
|
+
const LayoutMetrics& layoutMetrics) const {
|
|
574
|
+
auto isRTL =
|
|
575
|
+
bool{layoutMetrics.layoutDirection == LayoutDirection::RightToLeft};
|
|
576
|
+
|
|
577
|
+
auto borderWidths = getBorderWidths();
|
|
578
|
+
|
|
579
|
+
BorderRadii radii = radiiPercentToPoint(
|
|
580
|
+
borderRadii.resolve(isRTL, ValueUnit{0.0f, UnitType::Point}),
|
|
581
|
+
layoutMetrics.frame.size);
|
|
582
|
+
|
|
583
|
+
return {
|
|
584
|
+
.borderColors = borderColors.resolve(isRTL, {}),
|
|
585
|
+
.borderWidths = borderWidths.resolve(isRTL, 0),
|
|
586
|
+
.borderRadii = ensureNoOverlap(radii, layoutMetrics.frame.size),
|
|
587
|
+
.borderCurves = borderCurves.resolve(isRTL, BorderCurve::Circular),
|
|
588
|
+
.borderStyles = borderStyles.resolve(isRTL, BorderStyle::Solid),
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
Transform BaseViewProps::resolveTransform(
|
|
593
|
+
const LayoutMetrics& layoutMetrics) const {
|
|
594
|
+
const auto& frameSize = layoutMetrics.frame.size;
|
|
595
|
+
return resolveTransform(frameSize, transform, transformOrigin);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
Transform BaseViewProps::resolveTransform(
|
|
599
|
+
const Size& frameSize,
|
|
600
|
+
const Transform& transform,
|
|
601
|
+
const TransformOrigin& transformOrigin) {
|
|
602
|
+
auto transformMatrix = Transform{};
|
|
603
|
+
|
|
604
|
+
// transform is matrix
|
|
605
|
+
if (transform.operations.size() == 1 &&
|
|
606
|
+
transform.operations[0].type == TransformOperationType::Arbitrary) {
|
|
607
|
+
transformMatrix = transform;
|
|
608
|
+
} else {
|
|
609
|
+
for (const auto& operation : transform.operations) {
|
|
610
|
+
transformMatrix = transformMatrix *
|
|
611
|
+
Transform::FromTransformOperation(operation, frameSize, transform);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
if (transformOrigin.isSet()) {
|
|
616
|
+
std::array<float, 3> translateOffsets = getTranslateForTransformOrigin(
|
|
617
|
+
frameSize.width, frameSize.height, transformOrigin);
|
|
618
|
+
transformMatrix =
|
|
619
|
+
Transform::Translate(
|
|
620
|
+
translateOffsets[0], translateOffsets[1], translateOffsets[2]) *
|
|
621
|
+
transformMatrix *
|
|
622
|
+
Transform::Translate(
|
|
623
|
+
-translateOffsets[0], -translateOffsets[1], -translateOffsets[2]);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
return transformMatrix;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
bool BaseViewProps::getClipsContentToBounds() const {
|
|
630
|
+
return yogaStyle.overflow() != yoga::Overflow::Visible;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
#pragma mark - DebugStringConvertible
|
|
634
|
+
|
|
635
|
+
#if RN_DEBUG_STRING_CONVERTIBLE
|
|
636
|
+
SharedDebugStringConvertibleList BaseViewProps::getDebugProps() const {
|
|
637
|
+
const auto& defaultBaseViewProps = BaseViewProps();
|
|
638
|
+
|
|
639
|
+
return AccessibilityProps::getDebugProps() +
|
|
640
|
+
YogaStylableProps::getDebugProps() +
|
|
641
|
+
SharedDebugStringConvertibleList{
|
|
642
|
+
debugStringConvertibleItem(
|
|
643
|
+
"opacity", opacity, defaultBaseViewProps.opacity),
|
|
644
|
+
debugStringConvertibleItem(
|
|
645
|
+
"backgroundColor",
|
|
646
|
+
backgroundColor,
|
|
647
|
+
defaultBaseViewProps.backgroundColor),
|
|
648
|
+
debugStringConvertibleItem(
|
|
649
|
+
"zIndex", zIndex, defaultBaseViewProps.zIndex.value_or(0)),
|
|
650
|
+
debugStringConvertibleItem(
|
|
651
|
+
"pointerEvents",
|
|
652
|
+
pointerEvents,
|
|
653
|
+
defaultBaseViewProps.pointerEvents),
|
|
654
|
+
debugStringConvertibleItem(
|
|
655
|
+
"transform", transform, defaultBaseViewProps.transform),
|
|
656
|
+
debugStringConvertibleItem(
|
|
657
|
+
"backgroundImage",
|
|
658
|
+
backgroundImage,
|
|
659
|
+
defaultBaseViewProps.backgroundImage),
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
#endif
|
|
663
|
+
|
|
664
|
+
} // namespace facebook::react
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-windows",
|
|
3
|
-
"version": "0.83.0-preview.
|
|
3
|
+
"version": "0.83.0-preview.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@react-native-community/cli": "20.0.0",
|
|
27
27
|
"@react-native-community/cli-platform-android": "20.0.0",
|
|
28
28
|
"@react-native-community/cli-platform-ios": "20.0.0",
|
|
29
|
-
"@react-native-windows/cli": "0.83.0-preview.
|
|
29
|
+
"@react-native-windows/cli": "0.83.0-preview.1",
|
|
30
30
|
"@react-native/assets": "1.0.0",
|
|
31
31
|
"@react-native/assets-registry": "0.83.0-rc.5",
|
|
32
32
|
"@react-native/codegen": "0.83.0-rc.5",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"yargs": "^17.6.2"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@react-native-windows/codegen": "0.83.0-preview.
|
|
72
|
+
"@react-native-windows/codegen": "0.83.0-preview.1",
|
|
73
73
|
"@react-native/metro-config": "0.83.0-rc.5",
|
|
74
74
|
"@rnw-scripts/babel-react-native-config": "0.0.0",
|
|
75
75
|
"@rnw-scripts/eslint-config": "1.2.38",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"prettier": "2.8.8",
|
|
87
87
|
"react": "19.2.0",
|
|
88
88
|
"react-native": "0.83.0-rc.5",
|
|
89
|
-
"react-native-platform-override": "0.83.0-preview.
|
|
89
|
+
"react-native-platform-override": "0.83.0-preview.1",
|
|
90
90
|
"react-refresh": "^0.14.0",
|
|
91
91
|
"typescript": "5.0.4"
|
|
92
92
|
},
|