Closed salvan13 closed 4 years ago
Would it be a solution to mark focusable component as “border” that will stop any navigation outside of it? I mean before propagating the navigation up to the parent we could check this boolean prop that will restrict the up-tree propagation?
I have the same use-case. Currently it's quite fiddly to solve.
I'm using React Navigation as my navigation library, so components can listen for didFocus
and didBlur
navigation events. Upon receiving either of these events, I set this.state.screenIsFocused
accordingly, and grab focus to one of the focusables on my screen, e.g.:
navigation.addListener('didFocus', () => {
this.setState(
{ screenIsFocused: true },
() => {
spatialNavigation.setFocus("Modal/Dismiss");
}
);
});
Additionally, for every single focusable on each of my screens, I couple the value of focusable
to this.state.screenIsFocused
(and also this.state.modalVisible
, just in case).
<NavigatorBackButtonFocusable
focusKey={"MainScreen/BackButton"}
/* The `this.state.modalVisible` check is redundant, but I've added for peace of mind
* in case React Navigation has any race conditions that I don't understand. */
focusable={this.state.screenIsFocused && !this.state.modalVisible}
/>
Would it be a solution to mark focusable component as “border” that will stop any navigation outside of it?
@asgvard I think that would be a potential solution. Would a "border" focusable component itself be focusable?
There are edge-cases to consider if we think beyond up-down-left-right spatial navigation, though (if using this library as a cross-platform solution, where more interaction methods are possible):
tab
to manually move the browser's highlight focus to another focusable element outside of the border?There is a valid argument though that these edge cases are out of scope of the library and that such cases need to be guarded against by the developer instead.
Another potential option would be to restrict navigation to within a certain namespace.
I'm currently namespacing each of my focusKey
s (e.g. for <Sidebar>
components on my "MainMenu" and "Synopsis" screens, I'd use the focus keys MainMenu/Sidebar
and Synopsis/Sidebar
; for multiple items in a carousel, I'd use MainMenu/Category-0/Item-0
). So, for example, smart navigation would be unable to navigate from MainMenu to Synopsis.
This idea would need some deeper thought to cover all sorts of use-cases, however.
Is your feature request related to a problem? Please describe. We need to create a modal popup who goes on top of the other content, the focus should be bound in the modal and not go outside
Describe the solution you'd like A way to keep the focus in a container, or disable other containers
Additional context Another problem to keep in mind is when the focus is set async (after a delay or request) it can be lost by the current container/element
eg: this library is implementing sections, maybe it can be used as reference https://github.com/luke-chang/js-spatial-navigation/