Skip to content

Commit 51baedb

Browse files
vineethkuttanacoates-ms
authored andcommitted
[Fabric] Implementation of accessibilityDescription (microsoft#14818)
* Initial Commit for accessibilityDescription * Change files * Format Changes * Updating Snapshot
1 parent e5d7eaf commit 51baedb

File tree

13 files changed

+287
-0
lines changed

13 files changed

+287
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "[Fabric] Implementation of accessibilityDescription",
4+
"packageName": "react-native-windows",
5+
"email": "kvineeth@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ class AccessibilityBaseExample extends React.Component {
2424
style={{width: 50, height: 50, backgroundColor: 'blue'}}
2525
accessibilityLabel="A blue box"
2626
accessibilityHint="A hint for the blue box."
27+
accessibilityLevel={1}
28+
accessibilityItemType="comment"
29+
accessibilityAccessKey="accessKey"
30+
accessibilityDescription="Sample Description"
31+
accessibilityAnnotation={{
32+
typeID: 'Comment',
33+
typeName: 'Check Comment',
34+
author: 'Clint Westwood',
35+
dateTime: '3/19/2025 1:03 PM',
36+
}}
37+
testID="accessibility-base-view-1"
2738
/>
2839
<Text>The following has accessible and accessibilityLabel:</Text>
2940
<View

packages/e2e-test-app-fabric/test/__snapshots__/AccessibilityTest.test.ts.snap

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,102 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Accessibility Tests Accessibility data for Label and Level 1`] = `
4+
{
5+
"Automation Tree": {
6+
"AutomationId": "accessibility-base-view-2",
7+
"ControlType": 50026,
8+
"Level": 2,
9+
"LocalizedControlType": "group",
10+
"Name": "A hint for the red box.",
11+
},
12+
"Component Tree": {
13+
"Type": "Microsoft.ReactNative.Composition.ViewComponentView",
14+
"_Props": {
15+
"AccessibilityLabel": "A hint for the red box.",
16+
"TestId": "accessibility-base-view-2",
17+
},
18+
},
19+
"Visual Tree": {
20+
"Brush": {
21+
"Brush Type": "ColorBrush",
22+
"Color": "rgba(255, 0, 0, 255)",
23+
},
24+
"Comment": "accessibility-base-view-2",
25+
"Offset": "0, 0, 0",
26+
"Size": "50, 50",
27+
"Visual Type": "SpriteVisual",
28+
},
29+
}
30+
`;
31+
32+
exports[`Accessibility Tests Accessibility data for Label,Level and Hint 1`] = `
33+
{
34+
"Automation Tree": {
35+
"AccessKey": "accessKey",
36+
"AnnotationPattern.Author": "Clint Westwood",
37+
"AnnotationPattern.DateTime": "3/19/2025 1:03 PM",
38+
"AnnotationPattern.TypeId": 60003,
39+
"AnnotationPattern.TypeName": "Check Comment",
40+
"AutomationId": "accessibility-base-view-1",
41+
"ControlType": 50026,
42+
"Description": "Sample Description",
43+
"HelpText": "A hint for the blue box.",
44+
"ItemType": "comment",
45+
"Level": 1,
46+
"LocalizedControlType": "group",
47+
"Name": "A blue box",
48+
},
49+
"Component Tree": {
50+
"Type": "Microsoft.ReactNative.Composition.ViewComponentView",
51+
"_Props": {
52+
"AccessibilityLabel": "A blue box",
53+
"TestId": "accessibility-base-view-1",
54+
},
55+
},
56+
"Visual Tree": {
57+
"Brush": {
58+
"Brush Type": "ColorBrush",
59+
"Color": "rgba(0, 0, 255, 255)",
60+
},
61+
"Comment": "accessibility-base-view-1",
62+
"Offset": "0, 0, 0",
63+
"Size": "50, 50",
64+
"Visual Type": "SpriteVisual",
65+
},
66+
}
67+
`;
68+
69+
exports[`Accessibility Tests Accessibility data for Role, Setsize etc. 1`] = `
70+
{
71+
"Automation Tree": {
72+
"AutomationId": "accessibility-base-view-3",
73+
"ControlType": 50007,
74+
"Level": 9,
75+
"LocalizedControlType": "list item",
76+
"Name": "Aria label takes precedence",
77+
"PositionInSet": 2,
78+
"SizeofSet": 5,
79+
},
80+
"Component Tree": {
81+
"Type": "Microsoft.ReactNative.Composition.ViewComponentView",
82+
"_Props": {
83+
"AccessibilityLabel": "Aria label takes precedence",
84+
"TestId": "accessibility-base-view-3",
85+
},
86+
},
87+
"Visual Tree": {
88+
"Brush": {
89+
"Brush Type": "ColorBrush",
90+
"Color": "rgba(255, 0, 0, 255)",
91+
},
92+
"Comment": "accessibility-base-view-3",
93+
"Offset": "0, 0, 0",
94+
"Size": "50, 50",
95+
"Visual Type": "SpriteVisual",
96+
},
97+
}
98+
`;
99+
3100
exports[`Accessibility Tests Components can store range data by setting the min, max, and now of accessibilityValue 1`] = `
4101
{
5102
"Automation Tree": {

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ exports[`snapshotAllPages Accessibility Windows 1`] = `
88
The following has accessibilityLabel and accessibilityHint:
99
</Text>
1010
<View
11+
accessibilityAccessKey="accessKey"
12+
accessibilityAnnotation={
13+
{
14+
"author": "Clint Westwood",
15+
"dateTime": "3/19/2025 1:03 PM",
16+
"typeID": "Comment",
17+
"typeName": "Check Comment",
18+
}
19+
}
20+
accessibilityDescription="Sample Description"
1121
accessibilityHint="A hint for the blue box."
1222
accessibilityLabel="A blue box"
1323
style={

packages/e2e-test-app-fabric/windows/RNTesterApp-Fabric/RNTesterApp-Fabric.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,9 @@ winrt::Windows::Data::Json::JsonObject DumpUIATreeRecurse(
464464
int sizeOfSet = 0;
465465
LiveSetting liveSetting = LiveSetting::Off;
466466
BSTR itemStatus;
467+
BSTR itemType;
468+
BSTR accessKey;
469+
BSTR description = nullptr;
467470

468471
pTarget->get_CurrentAutomationId(&automationId);
469472
pTarget->get_CurrentControlType(&controlType);
@@ -481,6 +484,11 @@ winrt::Windows::Data::Json::JsonObject DumpUIATreeRecurse(
481484
pTarget4->get_CurrentLiveSetting(&liveSetting);
482485
pTarget4->Release();
483486
}
487+
IUIAutomationElement6 *pTarget6;
488+
hr = pTarget->QueryInterface(__uuidof(IUIAutomationElement6), reinterpret_cast<void **>(&pTarget6));
489+
if (SUCCEEDED(hr) && pTarget6) {
490+
pTarget6->get_CurrentFullDescription(&description);
491+
}
484492
result.Insert(L"AutomationId", winrt::Windows::Data::Json::JsonValue::CreateStringValue(automationId));
485493
result.Insert(L"ControlType", winrt::Windows::Data::Json::JsonValue::CreateNumberValue(controlType));
486494
InsertStringValueIfNotEmpty(result, L"HelpText", helpText);
@@ -493,6 +501,9 @@ winrt::Windows::Data::Json::JsonObject DumpUIATreeRecurse(
493501
InsertIntValueIfNotDefault(result, L"SizeofSet", sizeOfSet);
494502
InsertLiveSettingValueIfNotDefault(result, L"LiveSetting", liveSetting);
495503
InsertStringValueIfNotEmpty(result, L"ItemStatus", itemStatus);
504+
InsertStringValueIfNotEmpty(result, L"ItemType", itemType);
505+
InsertStringValueIfNotEmpty(result, L"AccessKey", accessKey);
506+
InsertStringValueIfNotEmpty(result, L"Description", description);
496507
DumpUIAPatternInfo(pTarget, result);
497508

498509
IUIAutomationElement *pChild;
@@ -513,6 +524,9 @@ winrt::Windows::Data::Json::JsonObject DumpUIATreeRecurse(
513524
::SysFreeString(localizedControlType);
514525
::SysFreeString(name);
515526
::SysFreeString(itemStatus);
527+
::SysFreeString(itemType);
528+
::SysFreeString(accessKey);
529+
::SysFreeString(description);
516530
return result;
517531
}
518532

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,29 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
527527
: SysAllocString(L"");
528528
break;
529529
}
530+
case UIA_LevelPropertyId: {
531+
pRetVal->vt = VT_I4;
532+
pRetVal->lVal = props->accessibilityLevel;
533+
break;
534+
}
535+
case UIA_AccessKeyPropertyId: {
536+
pRetVal->vt = VT_BSTR;
537+
auto accessKey = ::Microsoft::Common::Unicode::Utf8ToUtf16(props->accessibilityAccessKey.value_or(""));
538+
pRetVal->bstrVal = SysAllocString(accessKey.c_str());
539+
break;
540+
}
541+
case UIA_ItemTypePropertyId: {
542+
pRetVal->vt = VT_BSTR;
543+
auto itemtype = ::Microsoft::Common::Unicode::Utf8ToUtf16(props->accessibilityItemType.value_or(""));
544+
pRetVal->bstrVal = SysAllocString(itemtype.c_str());
545+
break;
546+
}
547+
case UIA_FullDescriptionPropertyId: {
548+
pRetVal->vt = VT_BSTR;
549+
auto desc = ::Microsoft::Common::Unicode::Utf8ToUtf16(props->accessibilityDescription.value_or(""));
550+
pRetVal->bstrVal = SysAllocString(desc.c_str());
551+
break;
552+
}
530553
}
531554

532555
return hr;

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,27 @@ void ComponentView::updateAccessibilityProps(
780780
oldViewProps.accessibilityLiveRegion,
781781
newViewProps.accessibilityLiveRegion);
782782

783+
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
784+
EnsureUiaProvider(), UIA_LevelPropertyId, oldViewProps.accessibilityLevel, newViewProps.accessibilityLevel);
785+
786+
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
787+
EnsureUiaProvider(),
788+
UIA_AccessKeyPropertyId,
789+
oldViewProps.accessibilityAccessKey,
790+
newViewProps.accessibilityAccessKey);
791+
792+
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
793+
EnsureUiaProvider(),
794+
UIA_ItemTypePropertyId,
795+
oldViewProps.accessibilityItemType,
796+
newViewProps.accessibilityItemType);
797+
798+
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
799+
EnsureUiaProvider(),
800+
UIA_FullDescriptionPropertyId,
801+
oldViewProps.accessibilityDescription,
802+
newViewProps.accessibilityDescription);
803+
783804
if ((oldViewProps.accessibilityState.has_value() && oldViewProps.accessibilityState->selected.has_value()) !=
784805
((newViewProps.accessibilityState.has_value() && newViewProps.accessibilityState->selected.has_value()))) {
785806
auto compProvider =

vnext/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,26 @@ HostPlatformViewProps::HostPlatformViewProps(
3939
CoreFeatures::enablePropIteratorSetter
4040
? sourceProps.accessibilitySetSize
4141
: convertRawProp(context, rawProps, "accessibilitySetSize", sourceProps.accessibilitySetSize, 0)),
42+
accessibilityLevel(
43+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
44+
? sourceProps.accessibilityLevel
45+
: convertRawProp(context, rawProps, "accessibilityLevel", sourceProps.accessibilityLevel, 0)),
46+
accessibilityItemType(
47+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
48+
? sourceProps.accessibilityItemType
49+
: convertRawProp(context, rawProps, "accessibilityItemType", sourceProps.accessibilityItemType, {})),
50+
accessibilityAccessKey(
51+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
52+
? sourceProps.accessibilityAccessKey
53+
: convertRawProp(context, rawProps, "accessibilityAccessKey", sourceProps.accessibilityAccessKey, {})),
54+
accessibilityDescription(
55+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityDescription
56+
: convertRawProp(
57+
context,
58+
rawProps,
59+
"accessibilityDescription",
60+
sourceProps.accessibilityDescription,
61+
{})),
4262
accessibilityLiveRegion(
4363
CoreFeatures::enablePropIteratorSetter ? sourceProps.accessibilityLiveRegion
4464
: convertRawProp(
@@ -83,6 +103,10 @@ void HostPlatformViewProps::setProp(
83103
RAW_SET_PROP_SWITCH_CASE_BASIC(focusable);
84104
RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilityPosInSet);
85105
RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilitySetSize);
106+
RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilityLevel);
107+
RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilityItemType);
108+
RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilityAccessKey);
109+
RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilityDescription);
86110
RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilityLiveRegion);
87111
RAW_SET_PROP_SWITCH_CASE_BASIC(keyDownEvents);
88112
RAW_SET_PROP_SWITCH_CASE_BASIC(keyUpEvents);

vnext/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ class HostPlatformViewProps : public BaseViewProps {
2727
int accessibilityPosInSet{0};
2828
int accessibilitySetSize{0};
2929
std::string accessibilityLiveRegion{"none"};
30+
int accessibilityLevel{0};
31+
std::optional<AccessibilityAnnotation> accessibilityAnnotation{};
32+
std::optional<std::string> accessibilityItemType{};
33+
std::optional<std::string> accessibilityAccessKey{};
34+
std::optional<std::string> accessibilityDescription{};
3035

3136
// std::optional<std::string> overflowAnchor{};
3237
std::optional<std::string> tooltip{};

vnext/src-win/Libraries/Components/View/View.windows.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const View: React.AbstractComponent<
3838
accessibilityLabel,
3939
accessibilityLabelledBy,
4040
accessibilityLevel, // Windows
41+
accessibilityDescription, //Windows
4142
accessibilityLiveRegion,
4243
accessibilityPosInSet, // Windows
4344
accessibilitySetSize, // Windows
@@ -49,6 +50,7 @@ const View: React.AbstractComponent<
4950
'aria-expanded': ariaExpanded,
5051
'aria-multiselectable': ariaMultiselectable, // Windows
5152
'aria-required': ariaRequired, // Windows
53+
'aria-description': ariaDescription, //Windows
5254
'aria-hidden': ariaHidden,
5355
'aria-label': ariaLabel,
5456
'aria-labelledby': ariaLabelledBy,
@@ -248,6 +250,7 @@ const View: React.AbstractComponent<
248250
}
249251
accessibilityLabel={ariaLabel ?? accessibilityLabel}
250252
accessibilityLevel={ariaLevel ?? accessibilityLevel}
253+
accessibilityDescription={ariaDescription ?? accessibilityDescription}
251254
accessibilityPosInSet={ariaPosinset ?? accessibilityPosInSet}
252255
accessibilitySetSize={ariaSetsize ?? accessibilitySetSize}
253256
focusable={_focusable}

0 commit comments

Comments
 (0)