-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Accessibility
This Wiki page holds the documentation for the Accessibility feature area for React Native for Windows. This document focuses on the new Fabric architecture.
Canonical GitHub issue for Accessibility support on Fabric
Most of our accessibility implementation on the new architecture is housed withing CompositionDynamicAutomationProvider.h/cpp.
Additional helper methods can be found within UiaHelpers.h/cpp.
If accessibility work needs additional helper methods that must be implemented on a per component basis or if a method requires information from a component that is not available through its original public API surface, additional methods can be added to *ComponentView.h/cpp files. For example, the DefaultControlType() method.
On Paper (old architecture) we relied on WinUI for supporting native Windows controls. These WinUI controls already had built-in accessibility support, so React Native didn't need to do much additional accessibility work to ensure the platform's controls were accessibility compliant. On Fabric, we are now building controls from scratch using Windows Composition. As a result, we now need to add accessibility support for the new native controls we have created.
To implement accessibility support for a particular control the control must support a few things:
- The control should implement the IRawElementProviderFragment interface which contains methods for navigation, bounding rectangles, and focus.
- The control should implement the IRawElementProviderSimple2 interface which contains methods for property values and provider information (more explanation on providers below).
- The control should implement the relevant provider interfaces given the control's functionality. For example, clickable controls should implement the IInvokeProvider or scrollable controls should implement the IScrollProvider. For more information on providers and under what conditions to implement them visit the following resources:
Most of the implementation of the above interfaces can be found within CompositionDynamicAutomationProvider.h/cpp. ITextProvider and ITextRangeProvider are implemented in separate files, CompositionTextProvider.h/cpp and CompositionTextRangeProvider.h/cpp respectively. ITextProvider was implemented in a separate file because some of its APIs are identical to other provider interfaces; the interface implementation was separated to avoid conflicts. ITextRangeProvider was implemented in a separate file because this provider is a child provider of ITextProvider; its instantiation is different from other providers like ITextProvider or IScrollProvider.
Any action method from an accessibility provider (i.e. a method which does have a get_* name) should include a call to DispatchAccessibilityAction(m_view, "methodName")
. This call is used for the accessibilityAction prop. The implementation of the method can be found here.
Every *ComponentView has an instance of CompositionDynamicAutomationProvider. This instance is created during calls to the EnsureUiaProvider method.
We currently have automated validation for most of our accessibility support on Fabric. We use snapshots tests to catch accessibility regressions in the platform. For more information on how snapshot tests work, visit the E2E Testing (Fabric) Wiki page.
Snapshot information for accessibility is dumped within the DumpUIATreeHelper
method. DumpUIATreeHelper
calls DumpUIATreeRecurse
. This method dumps property information for the UIA tree of a particular control. It also calls DumpUIAPatternInfo
which dumps the pattern provider information of a particular control in the UIA tree.
Here is a complete list of the accessibility information captured in the UIA tree dumps during snapshots tests:
- AutomationId
- ControlType
- HelpText
- IsEnabled
- IsKeyboardFocusable
- LocalizedControlType
- Name
- ItemStatus
- PositionInSet
- SizeOfSet
- LiveSetting
- ValuePattern.IsReadOnly (if implemented)
- ValuePattern.Value (if implemented)
- RangeValuePattern.Value (if implemented)
- RangeValuePattern.Minimum (if implemented)
- RangeValuePattern.Maximum (if implemented)
- RangeValuePattern.IsReadOnly (if implemented)
- TogglePattern.ToggleState (if implemented)
- ExpandCollapsePattern.ExpandCollapseState (if implemented)
- SelectionItemPattern.IsSelected (if implemented)
- SelectionPattern.CanSelectMultiple (if implemented)
- SelecttionPattern.IsSelectionRequired (if implemented)
- TextRangePattern.GetText (if implemented)
For many of these properties if the value matches the default, it is not added to the UIA dump to avoid clutter.
Any snapshot test that calls dumpVisualTree
dumps both the visual and UIA tree for the control.
To verify that accessibility code is working as expected we use a tool called Accessibility Insights.
- Simply run a sample app like playground-composition and then launch Accessibility Insights.
- When you hover over a control in the app you should see Accessibility Insights navigate to its Live Inspect tab.
- The app should show where the control you are hovering over sits within the UIA tree.
- The app should also show the "Properties" view which lists out property information for the control.
- If there's a property you want to inspect that isn't showing up in the list of property information, click on the settings icon and adjust which properties you want to be shown.
- Finally, the app shows the "Patterns" view which lists out which patterns are implemented for the control. Some patterns had a drop down with more information about the pattern. Some patterns have actions associated with them. To run an action, click on the "Actions" button beside the pattern. This will open a new window with the available actions. You can then run whichever action you are looking to debug through this window.
To debug accessibility code:
- Set a breakpoint within the section of the native code you are interested in debugging. Most likely this will be inside CompositionDynamicAutomationPeer.cpp or UiaHelpers.cpp.
- Open Accessibility Insights. Depending on where you set your breakpoint, your app may hit the breakpoint immediately after the Assistive Technology launches.
- If testing a particular control/scenario, hover over the desired control or run the desired pattern action. The code should hit your breakpoint at this time.