Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"comment": "Fixing heading level for accessibility",
"type": "prerelease",
"packageName": "react-native-windows",
"email": "protikbiswas100@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <Fabric/Composition/SwitchComponentView.h>
#include <Fabric/Composition/TextInput/WindowsTextInputComponentView.h>
#include <Unicode.h>
#include <react/renderer/components/view/HostPlatformViewProps.h>
#include <winrt/Microsoft.UI.Content.h>
#include "RootComponentView.h"
#include "UiaHelpers.h"
Expand Down Expand Up @@ -480,10 +481,21 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
if (baseView == nullptr)
return UIA_E_ELEMENTNOTAVAILABLE;

auto props = std::static_pointer_cast<const facebook::react::ViewProps>(baseView->props());
// Try to cast to HostPlatformViewProps first for Windows-specific properties
auto hostProps = std::dynamic_pointer_cast<const facebook::react::HostPlatformViewProps>(baseView->props());

// If that fails, fall back to ViewProps for basic accessibility properties
auto props = hostProps ? hostProps : std::static_pointer_cast<const facebook::react::ViewProps>(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<const facebook::react::HostPlatformViewProps>(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<winrt::Microsoft::ReactNative::Composition::implementation::ComponentView>();
if (compositionView == nullptr)
return UIA_E_ELEMENTNOTAVAILABLE;
Expand Down Expand Up @@ -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: {
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <Utils/ValueUtils.h>
#include <Views/FrameworkElementTransferProperties.h>
#include <atlcomcli.h>
#include <react/renderer/components/view/HostPlatformViewProps.h>
#include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
#include <winrt/Microsoft.UI.Input.h>
#include <winrt/Windows.UI.Composition.h>
Expand Down Expand Up @@ -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<const facebook::react::HostPlatformViewProps *>(&oldViewProps);
auto newHostProps = dynamic_cast<const facebook::react::HostPlatformViewProps *>(&newViewProps);

winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
EnsureUiaProvider(), UIA_IsKeyboardFocusablePropertyId, oldViewProps.focusable, newViewProps.focusable);

Expand Down Expand Up @@ -786,55 +791,58 @@ 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(),
UIA_ValueValuePropertyId,
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() &&
Expand Down
Loading