1717#include < WindowsNumerics.h>
1818#include < winrt/Windows.Foundation.h>
1919
20+ #include < UI.Xaml.Automation.Peers.h>
2021#include < UI.Xaml.Automation.h>
2122#include < UI.Xaml.Controls.h>
2223#include " Utils/PropertyHandlerUtils.h"
@@ -416,20 +417,61 @@ bool FrameworkElementViewManager::UpdateProperty(
416417 const std::string &innerName = pair.first ;
417418 const auto &innerValue = pair.second ;
418419
419- if (innerName == " selected" )
420+ auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement (element);
421+
422+ if (innerName == " selected" ) {
420423 states[static_cast <int32_t >(winrt::Microsoft::ReactNative::AccessibilityStates::Selected)] =
421424 innerValue.AsBoolean ();
422- else if (innerName == " disabled" )
425+ const auto prevSelectedState = DynamicAutomationProperties::GetAccessibilityStateSelected (element);
426+ if (peer != nullptr && prevSelectedState != innerValue.AsBoolean ()) {
427+ peer.RaisePropertyChangedEvent (
428+ winrt::SelectionItemPatternIdentifiers::IsSelectedProperty (),
429+ winrt::box_value (prevSelectedState),
430+ winrt::box_value (innerValue.AsBoolean ()));
431+ }
432+ } else if (innerName == " disabled" ) {
423433 states[static_cast <int32_t >(winrt::Microsoft::ReactNative::AccessibilityStates::Disabled)] =
424434 innerValue.AsBoolean ();
425- else if (innerName == " checked" ) {
435+ const auto prevDisabledState = DynamicAutomationProperties::GetAccessibilityStateDisabled (element);
436+
437+ if (peer != nullptr && prevDisabledState != innerValue.AsBoolean ()) {
438+ peer.RaisePropertyChangedEvent (
439+ winrt::AutomationElementIdentifiers::IsEnabledProperty (),
440+ winrt::box_value (!prevDisabledState),
441+ winrt::box_value (!innerValue.AsBoolean ()));
442+ }
443+ } else if (innerName == " checked" ) {
426444 states[static_cast <int32_t >(winrt::Microsoft::ReactNative::AccessibilityStates::Checked)] =
427445 innerValue.Type () == winrt::Microsoft::ReactNative::JSValueType::Boolean && innerValue.AsBoolean ();
428446 states[static_cast <int32_t >(winrt::Microsoft::ReactNative::AccessibilityStates::Unchecked)] =
429447 innerValue.Type () == winrt::Microsoft::ReactNative::JSValueType::Boolean && !innerValue.AsBoolean ();
430448 // If the state is "mixed" we'll just set both Checked and Unchecked to false,
431449 // then later in the IToggleProvider implementation it will return the Intermediate state
432450 // due to both being set to false (see DynamicAutomationPeer::ToggleState()).
451+ const auto prevCheckedState = DynamicAutomationProperties::GetAccessibilityStateChecked (element);
452+ const auto prevUncheckedState = DynamicAutomationProperties::GetAccessibilityStateUnchecked (element);
453+
454+ if (peer != nullptr ) {
455+ if (prevCheckedState !=
456+ states[static_cast <int32_t >(winrt::Microsoft::ReactNative::AccessibilityStates::Checked)] ||
457+ prevUncheckedState !=
458+ states[static_cast <int32_t >(winrt::Microsoft::ReactNative::AccessibilityStates::Unchecked)]) {
459+ // Checking if either state has changed here to catch changes involving "mixed" state.
460+ const auto oldValue = prevCheckedState ? winrt::ToggleState::On : winrt::ToggleState::Off;
461+ if (innerValue.Type () != winrt::Microsoft::ReactNative::JSValueType::Boolean) {
462+ peer.RaisePropertyChangedEvent (
463+ winrt::TogglePatternIdentifiers::ToggleStateProperty (),
464+ winrt::box_value (oldValue),
465+ winrt::box_value (winrt::ToggleState::Indeterminate));
466+ } else {
467+ const auto newValue = innerValue.AsBoolean () ? winrt::ToggleState::On : winrt::ToggleState::Off;
468+ peer.RaisePropertyChangedEvent (
469+ winrt::TogglePatternIdentifiers::ToggleStateProperty (),
470+ winrt::box_value (oldValue),
471+ winrt::box_value (newValue));
472+ }
473+ }
474+ }
433475 } else if (innerName == " busy" )
434476 states[static_cast <int32_t >(winrt::Microsoft::ReactNative::AccessibilityStates::Busy)] =
435477 !innerValue.IsNull () && innerValue.AsBoolean ();
@@ -438,6 +480,19 @@ bool FrameworkElementViewManager::UpdateProperty(
438480 !innerValue.IsNull () && innerValue.AsBoolean ();
439481 states[static_cast <int32_t >(winrt::Microsoft::ReactNative::AccessibilityStates::Collapsed)] =
440482 innerValue.IsNull () || !innerValue.AsBoolean ();
483+
484+ const auto prevExpandedState = DynamicAutomationProperties::GetAccessibilityStateExpanded (element);
485+
486+ if (peer != nullptr && prevExpandedState != innerValue.AsBoolean ()) {
487+ const auto newValue =
488+ innerValue.AsBoolean () ? winrt::ExpandCollapseState::Expanded : winrt::ExpandCollapseState::Collapsed;
489+ const auto oldValue =
490+ prevExpandedState ? winrt::ExpandCollapseState::Expanded : winrt::ExpandCollapseState::Collapsed;
491+ peer.RaisePropertyChangedEvent (
492+ winrt::ExpandCollapsePatternIdentifiers::ExpandCollapseStateProperty (),
493+ winrt::box_value (oldValue),
494+ winrt::box_value (newValue));
495+ }
441496 }
442497 }
443498 }
0 commit comments