diff --git a/change/react-native-windows-48182af8-4e3f-46a5-a980-f041f56ff6ce.json b/change/react-native-windows-48182af8-4e3f-46a5-a980-f041f56ff6ce.json new file mode 100644 index 00000000000..113c1045905 --- /dev/null +++ b/change/react-native-windows-48182af8-4e3f-46a5-a980-f041f56ff6ce.json @@ -0,0 +1,7 @@ +{ + "comment": "Fixing heading level for accessibility", + "type": "prerelease", + "packageName": "react-native-windows", + "email": "protikbiswas100@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp index 5e34404bd31..a3f42150305 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "RootComponentView.h" #include "UiaHelpers.h" @@ -480,10 +481,21 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT if (baseView == nullptr) return UIA_E_ELEMENTNOTAVAILABLE; - auto props = std::static_pointer_cast(baseView->props()); + // Try to cast to HostPlatformViewProps first for Windows-specific properties + auto hostProps = std::dynamic_pointer_cast(baseView->props()); + + // If that fails, fall back to ViewProps for basic accessibility properties + auto props = hostProps ? hostProps : std::static_pointer_cast(baseView->props()); if (props == nullptr) return UIA_E_ELEMENTNOTAVAILABLE; + // Cast to HostPlatformViewProps to access Windows-specific properties like accessibilityLevel + auto hostProps = std::dynamic_pointer_cast(baseView->props()); + if (hostProps == nullptr) { + // If hostProps is needed later, handle the null case appropriately. + // For now, we just proceed; add error handling if hostProps is dereferenced below. + } + auto compositionView = strongView.try_as(); if (compositionView == nullptr) return UIA_E_ELEMENTNOTAVAILABLE; @@ -597,17 +609,17 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT } case UIA_PositionInSetPropertyId: { pRetVal->vt = VT_I4; - pRetVal->lVal = props->accessibilityPosInSet; + pRetVal->lVal = hostProps ? hostProps->accessibilityPosInSet : 0; break; } case UIA_SizeOfSetPropertyId: { pRetVal->vt = VT_I4; - pRetVal->lVal = props->accessibilitySetSize; + pRetVal->lVal = hostProps ? hostProps->accessibilitySetSize : 0; break; } case UIA_LiveSettingPropertyId: { pRetVal->vt = VT_I4; - pRetVal->lVal = GetLiveSetting(props->accessibilityLiveRegion); + pRetVal->lVal = GetLiveSetting(hostProps ? hostProps->accessibilityLiveRegion : "none"); break; } case UIA_ItemStatusPropertyId: { @@ -619,24 +631,27 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT } case UIA_LevelPropertyId: { pRetVal->vt = VT_I4; - pRetVal->lVal = props->accessibilityLevel; + pRetVal->lVal = hostProps ? hostProps->accessibilityLevel : 0; break; } case UIA_AccessKeyPropertyId: { pRetVal->vt = VT_BSTR; - auto accessKey = ::Microsoft::Common::Unicode::Utf8ToUtf16(props->accessibilityAccessKey.value_or("")); + auto accessKey = + ::Microsoft::Common::Unicode::Utf8ToUtf16(hostProps ? hostProps->accessibilityAccessKey.value_or("") : ""); pRetVal->bstrVal = SysAllocString(accessKey.c_str()); break; } case UIA_ItemTypePropertyId: { pRetVal->vt = VT_BSTR; - auto itemtype = ::Microsoft::Common::Unicode::Utf8ToUtf16(props->accessibilityItemType.value_or("")); + auto itemtype = + ::Microsoft::Common::Unicode::Utf8ToUtf16(hostProps ? hostProps->accessibilityItemType.value_or("") : ""); pRetVal->bstrVal = SysAllocString(itemtype.c_str()); break; } case UIA_FullDescriptionPropertyId: { pRetVal->vt = VT_BSTR; - auto desc = ::Microsoft::Common::Unicode::Utf8ToUtf16(props->accessibilityDescription.value_or("")); + auto desc = + ::Microsoft::Common::Unicode::Utf8ToUtf16(hostProps ? hostProps->accessibilityDescription.value_or("") : ""); pRetVal->bstrVal = SysAllocString(desc.c_str()); break; } diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp index b53b7057344..c2e72f44bcc 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -747,6 +748,10 @@ void ComponentView::updateAccessibilityProps( if (!UiaClientsAreListening()) return; + // Try to safely cast to HostPlatformViewProps to access Windows-specific properties + auto oldHostProps = dynamic_cast(&oldViewProps); + auto newHostProps = dynamic_cast(&newViewProps); + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( EnsureUiaProvider(), UIA_IsKeyboardFocusablePropertyId, oldViewProps.focusable, newViewProps.focusable); @@ -786,44 +791,51 @@ void ComponentView::updateAccessibilityProps( winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( EnsureUiaProvider(), UIA_HelpTextPropertyId, oldViewProps.accessibilityHint, newViewProps.accessibilityHint); - winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( - EnsureUiaProvider(), - UIA_PositionInSetPropertyId, - oldViewProps.accessibilityPosInSet, - newViewProps.accessibilityPosInSet); + // Only update Windows-specific properties if we have HostPlatformViewProps + if (oldHostProps && newHostProps) { + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( + EnsureUiaProvider(), + UIA_PositionInSetPropertyId, + oldHostProps->accessibilityPosInSet, + newHostProps->accessibilityPosInSet); - winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( - EnsureUiaProvider(), - UIA_SizeOfSetPropertyId, - oldViewProps.accessibilitySetSize, - newViewProps.accessibilitySetSize); + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( + EnsureUiaProvider(), + UIA_SizeOfSetPropertyId, + oldHostProps->accessibilitySetSize, + newHostProps->accessibilitySetSize); - winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( - EnsureUiaProvider(), - UIA_LiveSettingPropertyId, - oldViewProps.accessibilityLiveRegion, - newViewProps.accessibilityLiveRegion); + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( + EnsureUiaProvider(), + UIA_LiveSettingPropertyId, + oldHostProps->accessibilityLiveRegion, + newHostProps->accessibilityLiveRegion); - winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( - EnsureUiaProvider(), UIA_LevelPropertyId, oldViewProps.accessibilityLevel, newViewProps.accessibilityLevel); + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( + EnsureUiaProvider(), UIA_LevelPropertyId, oldHostProps->accessibilityLevel, newHostProps->accessibilityLevel); - winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( - EnsureUiaProvider(), - UIA_AccessKeyPropertyId, - oldViewProps.accessibilityAccessKey, - newViewProps.accessibilityAccessKey); + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( + EnsureUiaProvider(), + UIA_AccessKeyPropertyId, + oldHostProps->accessibilityAccessKey, + newHostProps->accessibilityAccessKey); - winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( - EnsureUiaProvider(), - UIA_ItemTypePropertyId, - oldViewProps.accessibilityItemType, - newViewProps.accessibilityItemType); + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( + EnsureUiaProvider(), + UIA_ItemTypePropertyId, + oldHostProps->accessibilityItemType, + newHostProps->accessibilityItemType); - winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( - EnsureUiaProvider(), - UIA_FullDescriptionPropertyId, - oldViewProps.accessibilityDescription, - newViewProps.accessibilityDescription); + winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( + EnsureUiaProvider(), + UIA_FullDescriptionPropertyId, + oldHostProps->accessibilityDescription, + newHostProps->accessibilityDescription); + + // Handle annotation properties with single call + winrt::Microsoft::ReactNative::implementation::UpdateUiaPropertiesForAnnotation( + EnsureUiaProvider(), oldHostProps->accessibilityAnnotation, newHostProps->accessibilityAnnotation); + } winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty( EnsureUiaProvider(), @@ -831,10 +843,6 @@ void ComponentView::updateAccessibilityProps( oldViewProps.accessibilityValue.text, newViewProps.accessibilityValue.text); - // Handle annotation properties with single call - winrt::Microsoft::ReactNative::implementation::UpdateUiaPropertiesForAnnotation( - EnsureUiaProvider(), oldViewProps.accessibilityAnnotation, newViewProps.accessibilityAnnotation); - // Handle expand/collapse state changes if (oldViewProps.accessibilityState.has_value() != newViewProps.accessibilityState.has_value() || (oldViewProps.accessibilityState.has_value() && newViewProps.accessibilityState.has_value() &&