@@ -141,12 +141,21 @@ void FrameworkElementViewManager::TransferProperties(XamlView oldView, XamlView
141141 }
142142}
143143
144+ static folly::dynamic GetAccessibilityStateProps () {
145+ folly::dynamic props = folly::dynamic::object ();
146+
147+ props.update (folly::dynamic::object (" selected" , " boolean" )(" disabled" , " boolean" )(" checked" , " string" )(
148+ " busy" , " boolean" )(" expanded" , " boolean" ));
149+ return props;
150+ }
151+
144152folly::dynamic FrameworkElementViewManager::GetNativeProps () const {
145153 folly::dynamic props = Super::GetNativeProps ();
146154 props.update (folly::dynamic::object (" accessible" , " boolean" )(" accessibilityRole" , " string" )(
147- " accessibilityStates" , " array" )(" accessibilityHint" , " string" )(" accessibilityLabel" , " string" )(
148- " accessibilityPosInSet" , " number" )(" accessibilitySetSize" , " number" )(" testID" , " string" )(" tooltip" , " string" )(
149- " accessibilityActions" , " array" )(" accessibilityLiveRegion" , " string" ));
155+ " accessibilityStates" , " array" )(" accessibilityState" , GetAccessibilityStateProps ())(
156+ " accessibilityHint" , " string" )(" accessibilityLabel" , " string" )(" accessibilityPosInSet" , " number" )(
157+ " accessibilitySetSize" , " number" )(" testID" , " string" )(" tooltip" , " string" )(" accessibilityActions" , " array" )(
158+ " accessibilityLiveRegion" , " string" ));
150159 return props;
151160}
152161
@@ -156,7 +165,7 @@ void FrameworkElementViewManager::UpdateProperties(ShadowNodeBase *nodeToUpdate,
156165 for (const auto &pair : reactDiffMap.items ()) {
157166 const std::string &propertyName = pair.first .getString ();
158167 const folly::dynamic &propertyValue = pair.second ;
159-
168+
160169 if (propertyName == " opacity" ) {
161170 if (propertyValue.isNumber ()) {
162171 double opacity = propertyValue.asDouble ();
@@ -436,6 +445,49 @@ void FrameworkElementViewManager::UpdateProperties(ShadowNodeBase *nodeToUpdate,
436445 element, states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Expanded)]);
437446 DynamicAutomationProperties::SetAccessibilityStateCollapsed (
438447 element, states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Collapsed)]);
448+ } else if (propertyName == " accessibilityState" ) {
449+ bool states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::CountStates)] = {};
450+
451+ if (propertyValue.isObject ()) {
452+ for (const auto &pair : propertyValue.items ()) {
453+ const std::string &innerName = pair.first .getString ();
454+ const folly::dynamic &innerValue = pair.second ;
455+
456+ if (innerName == " selected" )
457+ states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Selected)] = innerValue.getBool ();
458+ else if (innerName == " disabled" )
459+ states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Disabled)] = innerValue.getBool ();
460+ else if (innerName == " checked" ) {
461+ states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Checked)] =
462+ innerValue.isBool () && innerValue.getBool ();
463+ states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Unchecked)] =
464+ innerValue.isBool () && !innerValue.getBool ();
465+ // If the state is "mixed" we'll just set both Checked and Unchecked to false,
466+ // then later in the IToggleProvider implementation it will return the Intermediate state
467+ // due to both being set to false (see DynamicAutomationPeer::ToggleState()).
468+ } else if (innerName == " busy" )
469+ states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Busy)] = innerValue.getBool ();
470+ else if (innerName == " expanded" ) {
471+ states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Expanded)] = innerValue.getBool ();
472+ states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Collapsed)] = !innerValue.getBool ();
473+ }
474+ }
475+ }
476+
477+ DynamicAutomationProperties::SetAccessibilityStateSelected (
478+ element, states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Selected)]);
479+ DynamicAutomationProperties::SetAccessibilityStateDisabled (
480+ element, states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Disabled)]);
481+ DynamicAutomationProperties::SetAccessibilityStateChecked (
482+ element, states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Checked)]);
483+ DynamicAutomationProperties::SetAccessibilityStateUnchecked (
484+ element, states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Unchecked)]);
485+ DynamicAutomationProperties::SetAccessibilityStateBusy (
486+ element, states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Busy)]);
487+ DynamicAutomationProperties::SetAccessibilityStateExpanded (
488+ element, states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Expanded)]);
489+ DynamicAutomationProperties::SetAccessibilityStateCollapsed (
490+ element, states[static_cast <int32_t >(winrt::react::uwp::AccessibilityStates::Collapsed)]);
439491 } else if (propertyName == " testID" ) {
440492 if (propertyValue.isString ()) {
441493 auto value = react::uwp::asHstring (propertyValue);
0 commit comments