@@ -82,7 +82,8 @@ winrt::Microsoft::ReactNative::ComponentView RootComponentView::GetFocusedCompon
8282
8383void RootComponentView::SetFocusedComponent (
8484 const winrt::Microsoft::ReactNative::ComponentView &value,
85- winrt::Microsoft::ReactNative::FocusNavigationDirection direction) noexcept {
85+ winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
86+ winrt::Microsoft::ReactNative::FocusState focusState) noexcept {
8687 if (m_focusedComponent == value)
8788 return ;
8889
@@ -97,11 +98,26 @@ void RootComponentView::SetFocusedComponent(
9798 winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->TrySetFocus ();
9899 }
99100 m_focusedComponent = value;
101+ if (focusState == winrt::Microsoft::ReactNative::FocusState::Programmatic) {
102+ focusState =
103+ (!m_useKeyboardForProgrammaticFocus || m_focusState == winrt::Microsoft::ReactNative::FocusState::Pointer)
104+ ? winrt::Microsoft::ReactNative::FocusState::Pointer
105+ : winrt::Microsoft::ReactNative::FocusState::Keyboard;
106+ }
107+ m_focusState = focusState;
100108 auto args = winrt::make<winrt::Microsoft::ReactNative::implementation::GotFocusEventArgs>(value, direction);
101109 winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(value)->onGotFocus (args);
102110 }
103111}
104112
113+ winrt::Microsoft::ReactNative::FocusState RootComponentView::focusState () const noexcept {
114+ return m_focusState;
115+ }
116+
117+ void RootComponentView::UseKeyboardForProgrammaticFocus (bool value) noexcept {
118+ m_useKeyboardForProgrammaticFocus = value;
119+ }
120+
105121bool RootComponentView::NavigateFocus (const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept {
106122 if (request.Reason () == winrt::Microsoft::ReactNative::FocusNavigationReason::Restore) {
107123 if (m_focusedComponent)
@@ -116,14 +132,16 @@ bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::Focus
116132 view,
117133 request.Reason () == winrt::Microsoft::ReactNative::FocusNavigationReason::First
118134 ? winrt::Microsoft::ReactNative::FocusNavigationDirection::First
119- : winrt::Microsoft::ReactNative::FocusNavigationDirection::Last);
135+ : winrt::Microsoft::ReactNative::FocusNavigationDirection::Last,
136+ winrt::Microsoft::ReactNative::FocusState::Programmatic);
120137 }
121138 return view != nullptr ;
122139}
123140
124141bool RootComponentView::TrySetFocusedComponent (
125142 const winrt::Microsoft::ReactNative::ComponentView &view,
126143 winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
144+ winrt::Microsoft::ReactNative::FocusState focusState,
127145 bool forceNoSelectionIfCannotMove /* = false*/ ) noexcept {
128146 auto target = view;
129147 auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(target);
@@ -157,23 +175,24 @@ bool RootComponentView::TrySetFocusedComponent(
157175
158176 winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(losingFocusArgs.NewFocusedComponent ())
159177 ->rootComponentView ()
160- ->SetFocusedComponent (gettingFocusArgs.NewFocusedComponent (), direction);
178+ ->SetFocusedComponent (gettingFocusArgs.NewFocusedComponent (), direction, focusState );
161179 } else {
162- SetFocusedComponent (nullptr , direction);
180+ SetFocusedComponent (nullptr , direction, focusState );
163181 }
164182
165183 return true ;
166184}
167185
168- bool RootComponentView::TryMoveFocus (bool next) noexcept {
186+ bool RootComponentView::TryMoveFocus (bool next, winrt::Microsoft::ReactNative::FocusState focusState ) noexcept {
169187 if (!m_focusedComponent) {
170188 return NavigateFocus (winrt::Microsoft::ReactNative::FocusNavigationRequest (
171189 next ? winrt::Microsoft::ReactNative::FocusNavigationReason::First
172190 : winrt::Microsoft::ReactNative::FocusNavigationReason::Last));
173191 }
174192
175193 Mso::Functor<bool (const winrt::Microsoft::ReactNative::ComponentView &)> fn =
176- [currentlyFocused = m_focusedComponent, next](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
194+ [currentlyFocused = m_focusedComponent, next, focusState](
195+ const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
177196 if (view == currentlyFocused)
178197 return false ;
179198 auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view);
@@ -185,7 +204,8 @@ bool RootComponentView::TryMoveFocus(bool next) noexcept {
185204 ->TrySetFocusedComponent (
186205 view,
187206 next ? winrt::Microsoft::ReactNative::FocusNavigationDirection::Next
188- : winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous);
207+ : winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous,
208+ focusState);
189209 };
190210
191211 if (winrt::Microsoft::ReactNative::implementation::walkTree (m_focusedComponent, next, fn)) {
@@ -249,7 +269,10 @@ void RootComponentView::start(const winrt::Microsoft::ReactNative::ReactNativeIs
249269}
250270
251271void RootComponentView::stop () noexcept {
252- SetFocusedComponent (nullptr , winrt::Microsoft::ReactNative::FocusNavigationDirection::None);
272+ SetFocusedComponent (
273+ nullptr ,
274+ winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
275+ winrt::Microsoft::ReactNative::FocusState::Programmatic);
253276 if (m_visualAddedToIsland) {
254277 if (auto rootView = m_wkRootView.get ()) {
255278 winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->RemoveRenderedVisual (
0 commit comments