Skip to content

Commit dea9967

Browse files
[Fabric] Implement announceForAccessibility in AccessibilityInfo Module (#14995)
* Implementation of announce for accessibility for fabric * Build fix * Removed Debug Message * Yarn Change * Copilot Suggestions * Review Changes * Storing the weak_ref island in property to avoid circular ref * Adding deleted Change Files
1 parent 0257055 commit dea9967

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-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] Implement announceForAccessibility in AccessibilityInfo Module",
4+
"packageName": "react-native-windows",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@
4040

4141
namespace winrt::Microsoft::ReactNative::implementation {
4242

43+
ReactPropertyId<winrt::Microsoft::ReactNative::ReactNonAbiValue<
44+
winrt::weak_ref<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>>>
45+
ReactNativeIsland::LastFocusedReactNativeIslandProperty() noexcept {
46+
static const ReactPropertyId<winrt::Microsoft::ReactNative::ReactNonAbiValue<
47+
winrt::weak_ref<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>>>
48+
prop{L"ReactNative.Composition", L"ReactNativeIsland"};
49+
return prop;
50+
}
4351
constexpr float loadingActivitySize = 12.0f;
4452
constexpr float loadingActivityHorizontalOffset = 16.0f;
4553
constexpr float loadingBarHeight = 36.0f;
@@ -861,6 +869,20 @@ winrt::Microsoft::UI::Content::ContentIsland ReactNativeIsland::Island() {
861869
}
862870
}
863871
});
872+
focusController.GotFocus(
873+
[weakThis = get_weak()](const auto &sender, const winrt::Microsoft::UI::Input::FocusChangedEventArgs &args) {
874+
if (auto pThis = weakThis.get()) {
875+
// Set the island to React context so it can be accessed by native modules
876+
if (pThis->m_context && pThis->m_island) {
877+
auto properties = pThis->m_context.Properties();
878+
properties.Set(
879+
ReactNativeIsland::LastFocusedReactNativeIslandProperty(),
880+
winrt::Microsoft::ReactNative::ReactNonAbiValue<
881+
winrt::weak_ref<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>>{
882+
std::in_place, weakThis});
883+
}
884+
}
885+
});
864886

865887
// ContentIsland does not support weak_ref, so we cannot use auto_revoke for these events
866888
m_islandAutomationProviderRequestedToken = m_island.AutomationProviderRequested(

vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ struct ReactNativeIsland
4949
~ReactNativeIsland() noexcept;
5050

5151
ReactNativeIsland(const winrt::Microsoft::UI::Composition::Compositor &compositor) noexcept;
52+
static ReactPropertyId<winrt::Microsoft::ReactNative::ReactNonAbiValue<
53+
winrt::weak_ref<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>>>
54+
LastFocusedReactNativeIslandProperty() noexcept;
5255
ReactNativeIsland(const winrt::Microsoft::ReactNative::Composition::PortalComponentView &portal) noexcept;
5356

5457
static winrt::Microsoft::ReactNative::ReactNativeIsland CreatePortal(

vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <UI.Xaml.Automation.Peers.h>
88
#include <UI.Xaml.Controls.h>
99
#include <XamlUtils.h>
10+
#else
11+
#include <Fabric/Composition/ReactNativeIsland.h>
1012
#endif
1113
#include <uiautomationcore.h>
1214
#include <uiautomationcoreapi.h>
@@ -79,6 +81,33 @@ void AccessibilityInfo::announceForAccessibility(std::wstring announcement) noex
7981
xaml::Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent,
8082
hstr,
8183
hstr);
84+
#else
85+
if (auto weakIslandWrapper = context.Properties().Get(
86+
winrt::Microsoft::ReactNative::implementation::ReactNativeIsland::LastFocusedReactNativeIslandProperty())) {
87+
if (auto weakIsland = weakIslandWrapper.Value()) {
88+
if (auto reactNativeIsland = weakIsland.get()) {
89+
if (auto uiaprovider = reactNativeIsland->GetUiaProvider()) {
90+
if (auto rawProvider = uiaprovider.try_as<IRawElementProviderSimple>()) {
91+
// Convert announcement to BSTR for UIA
92+
winrt::hstring hstrAnnouncement{announcement};
93+
auto bstrAnnouncement = SysAllocString(hstrAnnouncement.c_str());
94+
if (bstrAnnouncement) {
95+
// Raise the UIA notification event
96+
HRESULT hr = UiaRaiseNotificationEvent(
97+
rawProvider.get(),
98+
NotificationKind_Other,
99+
NotificationProcessing_ImportantMostRecent,
100+
bstrAnnouncement,
101+
bstrAnnouncement);
102+
// Clean up BSTRs
103+
SysFreeString(bstrAnnouncement);
104+
}
105+
}
106+
}
107+
}
108+
}
109+
}
110+
82111
#endif
83112
});
84113
}

0 commit comments

Comments
 (0)