Skip to content

Commit 60e5d3d

Browse files
acoates-msTatianaKaposchiaramooney
authored
[0.74] Cherry pick changes (#14415)
* Components do not lose hover state if pointer leaves window before it leaves the component (#14375) * Components do not lost hover state if pointer leaves window before it leaves the component * format * Change files --------- Co-authored-by: Tatiana Kapos <tatianakapos@microsoft.com> * [Fabric] Add Support for Role Prop (#14352) * Add Support for Role Prop * Change files * Format * Update Tests --------- Co-authored-by: Tatiana Kapos <tatianakapos@microsoft.com> * Fix bool operator on transparent colors returning false (#14413) * Fix crash loading logbox * Fix bool operator on transparent colors returning false * Change files * format * update change files --------- Co-authored-by: Tatiana Kapos <tatianakapos@microsoft.com> Co-authored-by: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com>
1 parent 311bbc7 commit 60e5d3d

File tree

10 files changed

+179
-13
lines changed

10 files changed

+179
-13
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Add Support for Role Prop",
4+
"packageName": "react-native-windows",
5+
"email": "34109996+chiaramooney@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Components do not lost hover state if pointer leaves window before it leaves the component",
4+
"packageName": "react-native-windows",
5+
"email": "30809111+acoates-ms@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Fix bool operator on transparent colors returning false",
4+
"packageName": "react-native-windows",
5+
"email": "30809111+acoates-ms@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}

packages/@react-native-windows/tester/src/js/examples-win/Accessibility/AccessibilityExampleWindows.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ class AccessibilityStateExamples extends React.Component {
475475
accessibilityValue={{
476476
text: this.state.viewValueText,
477477
}}
478-
accessibilityRole="combobox"
478+
role="combobox"
479479
testID="accessibilityValue-text"
480480
accessible
481481
aria-readonly>

packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,14 +751,14 @@ exports[`snapshotAllPages Accessibility Windows 4`] = `
751751
The following View exposes the accessibilityValue.Text field
752752
</Text>
753753
<View
754-
accessibilityRole="combobox"
755754
accessibilityValue={
756755
{
757756
"text": "testText",
758757
}
759758
}
760759
accessible={true}
761760
aria-readonly={true}
761+
role="combobox"
762762
style={
763763
{
764764
"backgroundColor": "gray",

vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
260260
return S_OK;
261261
}
262262

263-
long GetControlType(const std::string &role) noexcept {
263+
long GetControlTypeFromString(const std::string &role) noexcept {
264264
if (role == "adjustable") {
265265
return UIA_SliderControlTypeId;
266266
} else if (role == "group" || role == "search" || role == "radiogroup" || role == "timer" || role.empty()) {
@@ -323,6 +323,96 @@ long GetControlType(const std::string &role) noexcept {
323323
return UIA_GroupControlTypeId;
324324
}
325325

326+
long GetControlTypeFromRole(const facebook::react::Role &role) noexcept {
327+
switch (role) {
328+
case facebook::react::Role::Alert:
329+
return UIA_TextControlTypeId;
330+
case facebook::react::Role::Application:
331+
return UIA_WindowControlTypeId;
332+
case facebook::react::Role::Button:
333+
return UIA_ButtonControlTypeId;
334+
case facebook::react::Role::Checkbox:
335+
return UIA_CheckBoxControlTypeId;
336+
case facebook::react::Role::Columnheader:
337+
return UIA_HeaderControlTypeId;
338+
case facebook::react::Role::Combobox:
339+
return UIA_ComboBoxControlTypeId;
340+
case facebook::react::Role::Document:
341+
return UIA_DocumentControlTypeId;
342+
case facebook::react::Role::Grid:
343+
return UIA_GroupControlTypeId;
344+
case facebook::react::Role::Group:
345+
return UIA_GroupControlTypeId;
346+
case facebook::react::Role::Heading:
347+
return UIA_TextControlTypeId;
348+
case facebook::react::Role::Img:
349+
return UIA_ImageControlTypeId;
350+
case facebook::react::Role::Link:
351+
return UIA_HyperlinkControlTypeId;
352+
case facebook::react::Role::List:
353+
return UIA_ListControlTypeId;
354+
case facebook::react::Role::Listitem:
355+
return UIA_ListItemControlTypeId;
356+
case facebook::react::Role::Menu:
357+
return UIA_MenuControlTypeId;
358+
case facebook::react::Role::Menubar:
359+
return UIA_MenuBarControlTypeId;
360+
case facebook::react::Role::Menuitem:
361+
return UIA_MenuItemControlTypeId;
362+
case facebook::react::Role::None:
363+
return UIA_GroupControlTypeId;
364+
case facebook::react::Role::Presentation:
365+
return UIA_GroupControlTypeId;
366+
case facebook::react::Role::Progressbar:
367+
return UIA_ProgressBarControlTypeId;
368+
case facebook::react::Role::Radio:
369+
return UIA_RadioButtonControlTypeId;
370+
case facebook::react::Role::Radiogroup:
371+
return UIA_GroupControlTypeId;
372+
case facebook::react::Role::Rowgroup:
373+
return UIA_GroupControlTypeId;
374+
case facebook::react::Role::Rowheader:
375+
return UIA_HeaderControlTypeId;
376+
case facebook::react::Role::Scrollbar:
377+
return UIA_ScrollBarControlTypeId;
378+
case facebook::react::Role::Searchbox:
379+
return UIA_EditControlTypeId;
380+
case facebook::react::Role::Separator:
381+
return UIA_SeparatorControlTypeId;
382+
case facebook::react::Role::Slider:
383+
return UIA_SliderControlTypeId;
384+
case facebook::react::Role::Spinbutton:
385+
return UIA_SpinnerControlTypeId;
386+
case facebook::react::Role::Status:
387+
return UIA_StatusBarControlTypeId;
388+
case facebook::react::Role::Summary:
389+
return UIA_GroupControlTypeId;
390+
case facebook::react::Role::Switch:
391+
return UIA_ButtonControlTypeId;
392+
case facebook::react::Role::Tab:
393+
return UIA_TabItemControlTypeId;
394+
case facebook::react::Role::Table:
395+
return UIA_TableControlTypeId;
396+
case facebook::react::Role::Tablist:
397+
return UIA_TabControlTypeId;
398+
case facebook::react::Role::Tabpanel:
399+
return UIA_TabControlTypeId;
400+
case facebook::react::Role::Timer:
401+
return UIA_ButtonControlTypeId;
402+
case facebook::react::Role::Toolbar:
403+
return UIA_ToolBarControlTypeId;
404+
case facebook::react::Role::Tooltip:
405+
return UIA_ToolTipControlTypeId;
406+
case facebook::react::Role::Tree:
407+
return UIA_TreeControlTypeId;
408+
case facebook::react::Role::Treegrid:
409+
return UIA_TreeControlTypeId;
410+
case facebook::react::Role::Treeitem:
411+
return UIA_TreeItemControlTypeId;
412+
}
413+
return UIA_GroupControlTypeId;
414+
}
415+
326416
HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERTYID propertyId, VARIANT *pRetVal) {
327417
if (pRetVal == nullptr)
328418
return E_POINTER;
@@ -348,8 +438,10 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
348438
switch (propertyId) {
349439
case UIA_ControlTypePropertyId: {
350440
pRetVal->vt = VT_I4;
351-
auto role = props->accessibilityRole.empty() ? compositionView->DefaultControlType() : props->accessibilityRole;
352-
pRetVal->lVal = GetControlType(role);
441+
pRetVal->lVal = props->role == facebook::react::Role::None ? props->accessibilityRole.empty()
442+
? GetControlTypeFromString(compositionView->DefaultControlType())
443+
: GetControlTypeFromString(props->accessibilityRole)
444+
: GetControlTypeFromRole(props->role);
353445
break;
354446
}
355447
case UIA_AutomationIdPropertyId: {
@@ -389,12 +481,18 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
389481
}
390482
case UIA_IsContentElementPropertyId: {
391483
pRetVal->vt = VT_BOOL;
392-
pRetVal->boolVal = (props->accessible && props->accessibilityRole != "none") ? VARIANT_TRUE : VARIANT_FALSE;
484+
pRetVal->boolVal =
485+
(props->accessible && (props->accessibilityRole != "none" || props->role != facebook::react::Role::None))
486+
? VARIANT_TRUE
487+
: VARIANT_FALSE;
393488
break;
394489
}
395490
case UIA_IsControlElementPropertyId: {
396491
pRetVal->vt = VT_BOOL;
397-
pRetVal->boolVal = (props->accessible && props->accessibilityRole != "none") ? VARIANT_TRUE : VARIANT_FALSE;
492+
pRetVal->boolVal =
493+
(props->accessible && (props->accessibilityRole != "none" || props->role != facebook::react::Role::None))
494+
? VARIANT_TRUE
495+
: VARIANT_FALSE;
398496
break;
399497
}
400498
case UIA_IsOffscreenPropertyId: {
@@ -541,7 +639,6 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_IsReadOnly(BOOL *pRe
541639
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
542640
if (props == nullptr)
543641
return UIA_E_ELEMENTNOTAVAILABLE;
544-
auto accessibilityRole = props->accessibilityRole;
545642
if (props->accessibilityState.has_value() && props->accessibilityState->readOnly.has_value()) {
546643
*pRetVal = props->accessibilityState->readOnly.value();
547644
} else {

vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,20 @@ void CompositionEventHandler::Initialize() noexcept {
197197
}
198198
});
199199

200+
m_pointerExitedToken = pointerSource.PointerExited([wkThis = weak_from_this()](
201+
winrt::Microsoft::UI::Input::InputPointerSource const &,
202+
winrt::Microsoft::UI::Input::PointerEventArgs const &args) {
203+
if (auto strongThis = wkThis.lock()) {
204+
if (auto strongRootView = strongThis->m_wkRootView.get()) {
205+
if (strongThis->SurfaceId() == -1)
206+
return;
207+
auto pp = winrt::make<winrt::Microsoft::ReactNative::Composition::Input::implementation::PointerPoint>(
208+
args.CurrentPoint(), strongRootView.ScaleFactor());
209+
strongThis->onPointerExited(pp, args.KeyModifiers());
210+
}
211+
}
212+
});
213+
200214
m_pointerCaptureLostToken =
201215
pointerSource.PointerCaptureLost([wkThis = weak_from_this()](
202216
winrt::Microsoft::UI::Input::InputPointerSource const &,
@@ -1068,6 +1082,34 @@ void CompositionEventHandler::onPointerMoved(
10681082
}
10691083
}
10701084

1085+
void CompositionEventHandler::onPointerExited(
1086+
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
1087+
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
1088+
if (SurfaceId() == -1)
1089+
return;
1090+
1091+
int pointerId = pointerPoint.PointerId();
1092+
auto position = pointerPoint.Position();
1093+
1094+
if (std::shared_ptr<FabricUIManager> fabricuiManager =
1095+
::Microsoft::ReactNative::FabricUIManager::FromProperties(m_context.Properties())) {
1096+
facebook::react::Tag tag = -1;
1097+
facebook::react::Point ptLocal, ptScaled;
1098+
getTargetPointerArgs(fabricuiManager, pointerPoint, tag, ptScaled, ptLocal);
1099+
1100+
tag = -1;
1101+
1102+
auto args = winrt::make<winrt::Microsoft::ReactNative::Composition::Input::implementation::PointerRoutedEventArgs>(
1103+
m_context, tag, pointerPoint, keyModifiers);
1104+
1105+
facebook::react::PointerEvent pointerEvent = CreatePointerEventFromIncompleteHoverData(ptScaled, ptLocal);
1106+
1107+
auto handler = [](std::vector<winrt::Microsoft::ReactNative::ComponentView> &eventPathViews) {};
1108+
1109+
HandleIncomingPointerEvent(pointerEvent, nullptr, pointerPoint, keyModifiers, handler);
1110+
}
1111+
}
1112+
10711113
void CompositionEventHandler::onPointerPressed(
10721114
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
10731115
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {

vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ class CompositionEventHandler : public std::enable_shared_from_this<CompositionE
5757
void onPointerMoved(
5858
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
5959
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept;
60+
void onPointerExited(
61+
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
62+
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept;
6063
void onPointerWheelChanged(
6164
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
6265
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept;
@@ -169,6 +172,7 @@ class CompositionEventHandler : public std::enable_shared_from_this<CompositionE
169172
winrt::event_token m_pointerMovedToken;
170173
winrt::event_token m_pointerWheelChangedToken;
171174
winrt::event_token m_pointerCaptureLostToken;
175+
winrt::event_token m_pointerExitedToken;
172176
winrt::event_token m_keyDownToken;
173177
winrt::event_token m_keyUpToken;
174178
winrt::event_token m_characterReceivedToken;

vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -972,10 +972,10 @@ ReactNativeIsland::GetComponentView() noexcept {
972972

973973
if (auto fabricuiManager = ::Microsoft::ReactNative::FabricUIManager::FromProperties(
974974
winrt::Microsoft::ReactNative::ReactPropertyBag(m_context.Properties()))) {
975-
auto rootComponentViewDescriptor = fabricuiManager->GetViewRegistry().componentViewDescriptorWithTag(
976-
static_cast<facebook::react::SurfaceId>(m_rootTag));
977-
return rootComponentViewDescriptor.view
978-
.as<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>();
975+
if (auto view = fabricuiManager->GetViewRegistry().findComponentViewWithTag(
976+
static_cast<facebook::react::SurfaceId>(m_rootTag))) {
977+
return view.as<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>();
978+
}
979979
}
980980
return nullptr;
981981
}

vnext/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ struct Color {
3838
};
3939

4040
namespace HostPlatformColor {
41-
static const facebook::react::Color UndefinedColor{{0, 0, 0, 0} /*Black*/, {} /*Empty PlatformColors*/};
41+
static const facebook::react::Color UndefinedColor{
42+
{0, 0, 0, 0} /*Black*/,
43+
{"__undefinedColor"} /*Empty PlatformColors*/};
4244
} // namespace HostPlatformColor
4345

4446
inline Color hostPlatformColorFromComponents(ColorComponents components) {

0 commit comments

Comments
 (0)