Skip to content

Commit

Permalink
Implementing remaining RN60 accessibilityState values, #2575 (#2756)
Browse files Browse the repository at this point in the history
* Implementing remainin RN60 accessibility state values
* `busy`, `expanded`, and `collapsed` are now used by the DynamicAutomationPeer
* Added missing TransferProperties in FrameworkElementAutomationPeer
* Added missing examples to RNTester
* Added check for accessibilityState presence
  • Loading branch information
jonthysell committed Jul 12, 2019
1 parent ecc454a commit e87bc2e
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 15 deletions.
108 changes: 105 additions & 3 deletions vnext/ReactUWP/Views/DynamicAutomationPeer.cpp
Expand Up @@ -113,14 +113,25 @@ winrt::IInspectable DynamicAutomationPeer::GetPatternCore(
accessibilityRole == winrt::react::uwp::AccessibilityRoles::Radio)) {
return *this;
} else if (
patternInterface == winrt::PatternInterface::Selection ||
patternInterface == winrt::PatternInterface::SelectionItem) {
(patternInterface == winrt::PatternInterface::Selection ||
patternInterface == winrt::PatternInterface::SelectionItem) &&
HasAccessibilityState(winrt::react::uwp::AccessibilityStates::Selected)) {
return *this;
} else if (
patternInterface == winrt::PatternInterface::Toggle &&
(accessibilityRole == winrt::react::uwp::AccessibilityRoles::CheckBox ||
accessibilityRole == winrt::react::uwp::AccessibilityRoles::Switch ||
accessibilityRole == winrt::react::uwp::AccessibilityRoles::Radio)) {
accessibilityRole == winrt::react::uwp::AccessibilityRoles::Radio) &&
(HasAccessibilityState(winrt::react::uwp::AccessibilityStates::Checked) ||
HasAccessibilityState(
winrt::react::uwp::AccessibilityStates::Unchecked))) {
return *this;
} else if (
patternInterface == winrt::PatternInterface::ExpandCollapse &&
(HasAccessibilityState(
winrt::react::uwp::AccessibilityStates::Expanded) ||
HasAccessibilityState(
winrt::react::uwp::AccessibilityStates::Collapsed))) {
return *this;
}

Expand All @@ -129,10 +140,24 @@ winrt::IInspectable DynamicAutomationPeer::GetPatternCore(

bool DynamicAutomationPeer::IsEnabledCore() const {
bool disabled =
HasAccessibilityState(winrt::react::uwp::AccessibilityStates::Disabled) &&
GetAccessibilityState(winrt::react::uwp::AccessibilityStates::Disabled);
return !disabled && Super::IsEnabledCore();
}

winrt::hstring DynamicAutomationPeer::GetItemStatusCore() const {
winrt::hstring itemStatus = Super::GetItemStatusCore();

if (itemStatus.empty()) {
if (HasAccessibilityState(winrt::react::uwp::AccessibilityStates::Busy) &&
GetAccessibilityState(winrt::react::uwp::AccessibilityStates::Busy)) {
itemStatus = L"Busy";
}
}

return itemStatus;
}

// IInvokeProvider

void DynamicAutomationPeer::Invoke() const {
Expand Down Expand Up @@ -204,6 +229,35 @@ void DynamicAutomationPeer::Toggle() const {
}
}

// IExpandCollapseProvider

winrt::ExpandCollapseState DynamicAutomationPeer::ExpandCollapseState() const {
bool expandedState =
GetAccessibilityState(winrt::react::uwp::AccessibilityStates::Expanded);
bool collapsedState =
GetAccessibilityState(winrt::react::uwp::AccessibilityStates::Collapsed);

if (!expandedState && collapsedState) {
return winrt::ExpandCollapseState::Collapsed;
} else if (expandedState && !collapsedState) {
return winrt::ExpandCollapseState::Expanded;
} else if (expandedState && collapsedState) {
return winrt::ExpandCollapseState::PartiallyExpanded;
}

return winrt::ExpandCollapseState::LeafNode;
}

void DynamicAutomationPeer::Expand() const {
// Right now RN does not have "expand" events, so this is a no-op
}

void DynamicAutomationPeer::Collapse() const {
// Right now RN does not have "collapse" events, so this is a no-op
}

// Private Methods

winrt::hstring DynamicAutomationPeer::GetContentName() const {
winrt::hstring name = L"";

Expand Down Expand Up @@ -242,6 +296,54 @@ DynamicAutomationPeer::GetAccessibilityRole() const {
return winrt::react::uwp::AccessibilityRoles::None;
}

bool DynamicAutomationPeer::HasAccessibilityState(
winrt::react::uwp::AccessibilityStates state) const {
try {
if (auto const &owner = Owner()) {
winrt::IInspectable value = nullptr;
switch (state) {
case winrt::react::uwp::AccessibilityStates::Selected:
value =
owner.ReadLocalValue(DynamicAutomationProperties::
AccessibilityStateSelectedProperty());
break;
case winrt::react::uwp::AccessibilityStates::Disabled:
value =
owner.ReadLocalValue(DynamicAutomationProperties::
AccessibilityStateDisabledProperty());
break;
case winrt::react::uwp::AccessibilityStates::Checked:
value = owner.ReadLocalValue(
DynamicAutomationProperties::AccessibilityStateCheckedProperty());
break;
case winrt::react::uwp::AccessibilityStates::Unchecked:
value =
owner.ReadLocalValue(DynamicAutomationProperties::
AccessibilityStateUncheckedProperty());
break;
case winrt::react::uwp::AccessibilityStates::Busy:
value = owner.ReadLocalValue(
DynamicAutomationProperties::AccessibilityStateBusyProperty());
break;
case winrt::react::uwp::AccessibilityStates::Expanded:
value =
owner.ReadLocalValue(DynamicAutomationProperties::
AccessibilityStateExpandedProperty());
break;
case winrt::react::uwp::AccessibilityStates::Collapsed:
value =
owner.ReadLocalValue(DynamicAutomationProperties::
AccessibilityStateCollapsedProperty());
break;
}
return (value != winrt::DependencyProperty::UnsetValue());
}
} catch (...) {
}

return false;
}

bool DynamicAutomationPeer::GetAccessibilityState(
winrt::react::uwp::AccessibilityStates state) const {
try {
Expand Down
10 changes: 10 additions & 0 deletions vnext/ReactUWP/Views/DynamicAutomationPeer.h
Expand Up @@ -37,6 +37,8 @@ struct DynamicAutomationPeer : DynamicAutomationPeerT<DynamicAutomationPeer> {

bool IsEnabledCore() const;

winrt::hstring GetItemStatusCore() const;

// IInvokeProvider
void Invoke() const;

Expand All @@ -63,9 +65,17 @@ struct DynamicAutomationPeer : DynamicAutomationPeerT<DynamicAutomationPeer> {
winrt::Windows::UI::Xaml::Automation::ToggleState ToggleState() const;
void Toggle() const;

// IExpandCollapseProvider
winrt::Windows::UI::Xaml::Automation::ExpandCollapseState
ExpandCollapseState() const;
void Expand() const;
void Collapse() const;

private:
winrt::hstring GetContentName() const;
winrt::react::uwp::AccessibilityRoles GetAccessibilityRole() const;
bool HasAccessibilityState(
winrt::react::uwp::AccessibilityStates state) const;
bool GetAccessibilityState(
winrt::react::uwp::AccessibilityStates state) const;
winrt::react::uwp::AccessibilityInvokeEventHandler
Expand Down
22 changes: 21 additions & 1 deletion vnext/ReactUWP/Views/FrameworkElementViewManager.cpp
Expand Up @@ -86,14 +86,34 @@ void FrameworkElementViewManager::TransferProperties(
oldView,
newView,
DynamicAutomationProperties::AccessibilityRoleProperty());
TransferProperty(
oldView,
newView,
DynamicAutomationProperties::AccessibilityStateSelectedProperty());
TransferProperty(
oldView,
newView,
DynamicAutomationProperties::AccessibilityStateDisabledProperty());
TransferProperty(
oldView,
newView,
DynamicAutomationProperties::AccessibilityStateSelectedProperty());
DynamicAutomationProperties::AccessibilityStateCheckedProperty());
TransferProperty(
oldView,
newView,
DynamicAutomationProperties::AccessibilityStateUncheckedProperty());
TransferProperty(
oldView,
newView,
DynamicAutomationProperties::AccessibilityStateBusyProperty());
TransferProperty(
oldView,
newView,
DynamicAutomationProperties::AccessibilityStateExpandedProperty());
TransferProperty(
oldView,
newView,
DynamicAutomationProperties::AccessibilityStateCollapsedProperty());
TransferProperty(
oldView,
newView,
Expand Down
2 changes: 1 addition & 1 deletion vnext/ReactUWP/Views/cppwinrt/DynamicAutomationPeer.g.h
Expand Up @@ -14,7 +14,7 @@
namespace winrt::react::uwp::implementation {

template <typename D, typename... I>
struct WINRT_EBO DynamicAutomationPeer_base : implements<D, react::uwp::IDynamicAutomationPeer, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides2, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides3, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides4, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides5, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides6, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides8, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides9, Windows::UI::Xaml::Automation::Provider::IInvokeProvider, Windows::UI::Xaml::Automation::Provider::ISelectionItemProvider, Windows::UI::Xaml::Automation::Provider::ISelectionProvider, Windows::UI::Xaml::Automation::Provider::IToggleProvider, composing, I...>,
struct WINRT_EBO DynamicAutomationPeer_base : implements<D, react::uwp::IDynamicAutomationPeer, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides2, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides3, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides4, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides5, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides6, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides8, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides9, Windows::UI::Xaml::Automation::Provider::IExpandCollapseProvider, Windows::UI::Xaml::Automation::Provider::IInvokeProvider, Windows::UI::Xaml::Automation::Provider::ISelectionItemProvider, Windows::UI::Xaml::Automation::Provider::ISelectionProvider, Windows::UI::Xaml::Automation::Provider::IToggleProvider, composing, I...>,
impl::require<D, Windows::UI::Xaml::Automation::Peers::IAutomationPeer, Windows::UI::Xaml::Automation::Peers::IAutomationPeer2, Windows::UI::Xaml::Automation::Peers::IAutomationPeer3, Windows::UI::Xaml::Automation::Peers::IAutomationPeer4, Windows::UI::Xaml::Automation::Peers::IAutomationPeer5, Windows::UI::Xaml::Automation::Peers::IAutomationPeer6, Windows::UI::Xaml::Automation::Peers::IAutomationPeer7, Windows::UI::Xaml::Automation::Peers::IAutomationPeer8, Windows::UI::Xaml::Automation::Peers::IAutomationPeer9, Windows::UI::Xaml::Automation::Peers::IAutomationPeerProtected, Windows::UI::Xaml::Automation::Peers::IFrameworkElementAutomationPeer, Windows::UI::Xaml::IDependencyObject, Windows::UI::Xaml::IDependencyObject2>,
impl::base<D, Windows::UI::Xaml::Automation::Peers::FrameworkElementAutomationPeer, Windows::UI::Xaml::Automation::Peers::AutomationPeer, Windows::UI::Xaml::DependencyObject>,
Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverridesT<D>, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides2T<D>, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides3T<D>, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides4T<D>, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides5T<D>, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides6T<D>, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides8T<D>, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides9T<D>
Expand Down
3 changes: 2 additions & 1 deletion vnext/ReactUWP/Views/cppwinrt/DynamicAutomationPeer.idl
Expand Up @@ -106,7 +106,8 @@ namespace react.uwp
Windows.UI.Xaml.Automation.Provider.IInvokeProvider,
Windows.UI.Xaml.Automation.Provider.ISelectionProvider,
Windows.UI.Xaml.Automation.Provider.ISelectionItemProvider,
Windows.UI.Xaml.Automation.Provider.IToggleProvider
Windows.UI.Xaml.Automation.Provider.IToggleProvider,
Windows.UI.Xaml.Automation.Provider.IExpandCollapseProvider
{
DynamicAutomationPeer(Windows.UI.Xaml.FrameworkElement owner);
}
Expand Down
1 change: 1 addition & 0 deletions vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.0.h
Expand Up @@ -14,6 +14,7 @@ struct UIElement;

WINRT_EXPORT namespace winrt::Windows::UI::Xaml::Automation {

enum class ExpandCollapseState;
enum class ToggleState;

}
Expand Down
2 changes: 1 addition & 1 deletion vnext/ReactUWP/Views/cppwinrt/winrt/impl/react.uwp.2.h
Expand Up @@ -34,7 +34,7 @@ WINRT_EXPORT namespace winrt::react::uwp {
struct WINRT_EBO DynamicAutomationPeer :
react::uwp::IDynamicAutomationPeer,
impl::base<DynamicAutomationPeer, Windows::UI::Xaml::Automation::Peers::FrameworkElementAutomationPeer, Windows::UI::Xaml::Automation::Peers::AutomationPeer, Windows::UI::Xaml::DependencyObject>,
impl::require<DynamicAutomationPeer, Windows::UI::Xaml::Automation::Peers::IAutomationPeer, Windows::UI::Xaml::Automation::Peers::IAutomationPeer2, Windows::UI::Xaml::Automation::Peers::IAutomationPeer3, Windows::UI::Xaml::Automation::Peers::IAutomationPeer4, Windows::UI::Xaml::Automation::Peers::IAutomationPeer5, Windows::UI::Xaml::Automation::Peers::IAutomationPeer6, Windows::UI::Xaml::Automation::Peers::IAutomationPeer7, Windows::UI::Xaml::Automation::Peers::IAutomationPeer8, Windows::UI::Xaml::Automation::Peers::IAutomationPeer9, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides2, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides3, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides4, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides5, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides6, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides8, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides9, Windows::UI::Xaml::Automation::Peers::IAutomationPeerProtected, Windows::UI::Xaml::Automation::Peers::IFrameworkElementAutomationPeer, Windows::UI::Xaml::Automation::Provider::IInvokeProvider, Windows::UI::Xaml::Automation::Provider::ISelectionItemProvider, Windows::UI::Xaml::Automation::Provider::ISelectionProvider, Windows::UI::Xaml::Automation::Provider::IToggleProvider, Windows::UI::Xaml::IDependencyObject, Windows::UI::Xaml::IDependencyObject2>
impl::require<DynamicAutomationPeer, Windows::UI::Xaml::Automation::Peers::IAutomationPeer, Windows::UI::Xaml::Automation::Peers::IAutomationPeer2, Windows::UI::Xaml::Automation::Peers::IAutomationPeer3, Windows::UI::Xaml::Automation::Peers::IAutomationPeer4, Windows::UI::Xaml::Automation::Peers::IAutomationPeer5, Windows::UI::Xaml::Automation::Peers::IAutomationPeer6, Windows::UI::Xaml::Automation::Peers::IAutomationPeer7, Windows::UI::Xaml::Automation::Peers::IAutomationPeer8, Windows::UI::Xaml::Automation::Peers::IAutomationPeer9, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides2, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides3, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides4, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides5, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides6, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides8, Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides9, Windows::UI::Xaml::Automation::Peers::IAutomationPeerProtected, Windows::UI::Xaml::Automation::Peers::IFrameworkElementAutomationPeer, Windows::UI::Xaml::Automation::Provider::IExpandCollapseProvider, Windows::UI::Xaml::Automation::Provider::IInvokeProvider, Windows::UI::Xaml::Automation::Provider::ISelectionItemProvider, Windows::UI::Xaml::Automation::Provider::ISelectionProvider, Windows::UI::Xaml::Automation::Provider::IToggleProvider, Windows::UI::Xaml::IDependencyObject, Windows::UI::Xaml::IDependencyObject2>
{
DynamicAutomationPeer(std::nullptr_t) noexcept {}
DynamicAutomationPeer(Windows::UI::Xaml::FrameworkElement const& owner);
Expand Down
19 changes: 18 additions & 1 deletion vnext/ReactUWP/Views/cppwinrt/winrt/react.uwp.h
Expand Up @@ -1745,6 +1745,23 @@ struct property_react_uwp_IViewPanelStatics

struct property_react_uwp_DynamicAutomationPeer
{ struct named {
struct ExpandCollapseState
{
struct name { static constexpr std::wstring_view value{ L"ExpandCollapseState"sv }; };
using property_type = winrt::Windows::UI::Xaml::Automation::ExpandCollapseState;
using target_type = winrt::react::uwp::DynamicAutomationPeer;

using is_readable = std::true_type;
using is_writable = std::false_type;
using is_static = std::false_type;
struct getter
{
auto operator()(target_type const& target) const
{
return target.ExpandCollapseState();
}
};
};
struct IsSelected
{
struct name { static constexpr std::wstring_view value{ L"IsSelected"sv }; };
Expand Down Expand Up @@ -1830,7 +1847,7 @@ struct property_react_uwp_DynamicAutomationPeer
}
};
};};
struct list { using type = impl::typelist<named::IsSelected, named::SelectionContainer, named::CanSelectMultiple, named::IsSelectionRequired, named::ToggleState>; };
struct list { using type = impl::typelist<named::ExpandCollapseState, named::IsSelected, named::SelectionContainer, named::CanSelectMultiple, named::IsSelectionRequired, named::ToggleState>; };
};

struct property_react_uwp_DynamicAutomationProperties
Expand Down

0 comments on commit e87bc2e

Please sign in to comment.