From 5345aacbabe482ca1d42949fae2343a3c543ee17 Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Mon, 14 Oct 2024 13:57:07 -0700 Subject: [PATCH] Add Support for AccessibilityState:Busy (#13952) * Support AccessibilityState: Busy * Change files * Add Testing * Update Snapshots * Update for Leak --- ...tive-windows-0d909f6f-4b48-46c7-97ec-c61c5f2b8087.json | 7 +++++++ .../tester/src/js/examples/View/ViewExample.windows.js | 2 +- .../test/__snapshots__/ViewComponentTest.test.ts.snap | 1 + .../test/__snapshots__/snapshotPages.test.js.snap | 1 + .../windows/RNTesterApp-Fabric/RNTesterApp-Fabric.cpp | 8 ++++++++ .../test/__snapshots__/ViewComponentTest.test.ts.snap | 1 + .../Composition/CompositionDynamicAutomationProvider.cpp | 7 +++++++ .../Fabric/Composition/CompositionViewComponentView.cpp | 6 ++++++ 8 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 change/react-native-windows-0d909f6f-4b48-46c7-97ec-c61c5f2b8087.json diff --git a/change/react-native-windows-0d909f6f-4b48-46c7-97ec-c61c5f2b8087.json b/change/react-native-windows-0d909f6f-4b48-46c7-97ec-c61c5f2b8087.json new file mode 100644 index 00000000000..db5044f8113 --- /dev/null +++ b/change/react-native-windows-0d909f6f-4b48-46c7-97ec-c61c5f2b8087.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Support AccessibilityState: Busy", + "packageName": "react-native-windows", + "email": "34109996+chiaramooney@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/@react-native-windows/tester/src/js/examples/View/ViewExample.windows.js b/packages/@react-native-windows/tester/src/js/examples/View/ViewExample.windows.js index 8108ff7a940..1e793fc10e1 100644 --- a/packages/@react-native-windows/tester/src/js/examples/View/ViewExample.windows.js +++ b/packages/@react-native-windows/tester/src/js/examples/View/ViewExample.windows.js @@ -558,7 +558,7 @@ class AccessibilityExample extends React.Component< {name: 'expand', label: 'expand'}, {name: 'collapse', label: 'collapse'}, ]} - accessibilityState={{expanded: this.state.expanded}} + accessibilityState={{expanded: this.state.expanded, busy: true}} accessibilityPosInSet={1} accessibilitySetSize={1} accessibilityLiveRegion='polite' diff --git a/packages/e2e-test-app-fabric/test/__snapshots__/ViewComponentTest.test.ts.snap b/packages/e2e-test-app-fabric/test/__snapshots__/ViewComponentTest.test.ts.snap index 4bb568dd7e4..58a81a88a53 100644 --- a/packages/e2e-test-app-fabric/test/__snapshots__/ViewComponentTest.test.ts.snap +++ b/packages/e2e-test-app-fabric/test/__snapshots__/ViewComponentTest.test.ts.snap @@ -1097,6 +1097,7 @@ exports[`View Tests Views can have customized accessibility 1`] = ` "ExpandCollapsePattern.ExpandCollapseState": "Expanded", "HelpText": "Accessibility Hint", "IsKeyboardFocusable": true, + "ItemStatus": "Busy", "LiveSetting": "Polite", "LocalizedControlType": "button", "Name": "A View with accessibility values", diff --git a/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap b/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap index 0c2cbdfcf40..7684c69701c 100644 --- a/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap +++ b/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap @@ -77762,6 +77762,7 @@ exports[`snapshotAllPages View 22`] = ` accessibilitySetSize={1} accessibilityState={ { + "busy": true, "expanded": true, } } diff --git a/packages/e2e-test-app-fabric/windows/RNTesterApp-Fabric/RNTesterApp-Fabric.cpp b/packages/e2e-test-app-fabric/windows/RNTesterApp-Fabric/RNTesterApp-Fabric.cpp index 02b15b3254f..c258f306c22 100644 --- a/packages/e2e-test-app-fabric/windows/RNTesterApp-Fabric/RNTesterApp-Fabric.cpp +++ b/packages/e2e-test-app-fabric/windows/RNTesterApp-Fabric/RNTesterApp-Fabric.cpp @@ -411,6 +411,7 @@ winrt::Windows::Data::Json::JsonObject DumpUIATreeRecurse( int positionInSet = 0; int sizeOfSet = 0; LiveSetting liveSetting = LiveSetting::Off; + BSTR itemStatus; pTarget->get_CurrentAutomationId(&automationId); pTarget->get_CurrentControlType(&controlType); @@ -419,6 +420,7 @@ winrt::Windows::Data::Json::JsonObject DumpUIATreeRecurse( pTarget->get_CurrentIsKeyboardFocusable(&isKeyboardFocusable); pTarget->get_CurrentLocalizedControlType(&localizedControlType); pTarget->get_CurrentName(&name); + pTarget->get_CurrentItemStatus(&itemStatus); IUIAutomationElement4 *pTarget4; HRESULT hr = pTarget->QueryInterface(__uuidof(IUIAutomationElement4), reinterpret_cast(&pTarget4)); if (SUCCEEDED(hr) && pTarget4) { @@ -438,6 +440,7 @@ winrt::Windows::Data::Json::JsonObject DumpUIATreeRecurse( InsertIntValueIfNotDefault(result, L"PositionInSet", positionInSet); InsertIntValueIfNotDefault(result, L"SizeofSet", sizeOfSet); InsertLiveSettingValueIfNotDefault(result, L"LiveSetting", liveSetting); + InsertStringValueIfNotEmpty(result, L"ItemStatus", itemStatus); DumpUIAPatternInfo(pTarget, result); IUIAutomationElement *pChild; @@ -453,6 +456,11 @@ winrt::Windows::Data::Json::JsonObject DumpUIATreeRecurse( if (children.Size() > 0) { result.Insert(L"__Children", children); } + ::SysFreeString(automationId); + ::SysFreeString(helpText); + ::SysFreeString(localizedControlType); + ::SysFreeString(name); + ::SysFreeString(itemStatus); return result; } diff --git a/packages/e2e-test-app/test/__snapshots__/ViewComponentTest.test.ts.snap b/packages/e2e-test-app/test/__snapshots__/ViewComponentTest.test.ts.snap index decda6dae53..9399d081acf 100644 --- a/packages/e2e-test-app/test/__snapshots__/ViewComponentTest.test.ts.snap +++ b/packages/e2e-test-app/test/__snapshots__/ViewComponentTest.test.ts.snap @@ -363,6 +363,7 @@ exports[`ViewTests Views can have a custom nativeID 1`] = ` exports[`ViewTests Views can have accessibility customization 1`] = ` { "AccessibilityRole": "Button", + "AccessibilityStateBusy": true, "AccessibilityStateExpanded": true, "AutomationId": "accessibility", "AutomationPositionInSet": 1, diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp index 88330c1e804..2a92f6d75f5 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp @@ -370,6 +370,13 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT pRetVal->lVal = GetLiveSetting(props->accessibilityLiveRegion); break; } + case UIA_ItemStatusPropertyId: { + pRetVal->vt = VT_BSTR; + pRetVal->bstrVal = (props->accessibilityState.has_value() && props->accessibilityState->busy) + ? SysAllocString(L"Busy") + : SysAllocString(L""); + break; + } } return hr; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp index eb1f8d7d246..82d34716515 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp @@ -1321,6 +1321,12 @@ void ComponentView::updateAccessibilityProps( !(oldViewProps.accessibilityState && oldViewProps.accessibilityState->disabled), !(newViewProps.accessibilityState && newViewProps.accessibilityState->disabled)); + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( + m_uiaProvider, + UIA_IsEnabledPropertyId, + !(oldViewProps.accessibilityState && oldViewProps.accessibilityState->busy), + !(newViewProps.accessibilityState && newViewProps.accessibilityState->busy)); + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( m_uiaProvider, UIA_ControlTypePropertyId, oldViewProps.accessibilityRole, newViewProps.accessibilityRole);