Describe the bug
I'm examining how mouse and keyboard behave together in a React Native Web App, with an interest in supporting desktop browsers (where either interaction mechanism might be used).
To Reproduce
Steps to reproduce the behaviour:
Click on any FocusableComponent. This will inadvertently cause its <TouchableOpacity> child to be selected (e.g. in the same way as if you'd highlighted a text field).
Press the arrow keys to move focus to a different FocusableComponent.
Press Enter.
I'd expect the Enter-press to trigger onEnterPress on the FocusableComponent; but in practice, react-spatial-navigation performs no operation at all.
This is because the key event is absorbed by the TouchableOpacity that was clicked on earlier (as it became highlighted upon click). So instead the Enter-press results in onPress firing on the TouchableOpacity, and I believe the event stops propagating from there.
Workaround
I found that calling HTMLElement.blur() works around the problem perfectly well for my needs.
const Item = ({
item,
onClick,
focused,
stealFocus,
}) => {
const { ViewFactory, touchableStyle, source } = item;
const refObj = React.createRef<TouchableOpacity>();
return (
<TouchableOpacity
ref={refObj}
onFocus={() => {
const currentRef = refObj.current;
/* React Native Components happen to implement blur() just like
* HTMLElement does, but it's safest to check anyway. Not sure
* whether there's any harm in calling it on Native as well as
* Web – haven't tested on tvOS and Android TV. */
if(currentRef && currentRef.blur){
currentRef.blur();
}
}}
onPress={() => {
stealFocus();
onClick();
}}
style={touchableStyle}
>
<ViewFactory focused={focused} source={source} />
</TouchableOpacity>
);
};
const ItemFocusable = withFocusable()(props => <Item {...props} />);
Additional context
Note that the visual debugger blocks clicks altogether, so cannot be used to reproduce this issue.
Also: Any Enter-press performed when a TouchableOpacity is highlighted does not propagate to a keydown event listener, so I believe the browser is handling the event to some extent.
Discussion
Should this issue be left for consumers of the library to solve themselves (as I have done with my workaround), or is there any elegant way that the library could handle it? I can't think of any myself, but I'd be interested to hear your thoughts.
Either way, with this issue filing, devs will be able to see at least one way to work around it.
Describe the bug I'm examining how mouse and keyboard behave together in a React Native Web App, with an interest in supporting desktop browsers (where either interaction mechanism might be used).
To Reproduce Steps to reproduce the behaviour:
<TouchableOpacity>
child to be selected (e.g. in the same way as if you'd highlighted a text field).I'd expect the Enter-press to trigger
onEnterPress
on the FocusableComponent; but in practice,react-spatial-navigation
performs no operation at all.This is because the key event is absorbed by the TouchableOpacity that was clicked on earlier (as it became highlighted upon click). So instead the Enter-press results in
onPress
firing on the TouchableOpacity, and I believe the event stops propagating from there.Workaround
I found that calling HTMLElement.blur() works around the problem perfectly well for my needs.
Additional context Note that the visual debugger blocks clicks altogether, so cannot be used to reproduce this issue.
Also: Any Enter-press performed when a TouchableOpacity is highlighted does not propagate to a
keydown
event listener, so I believe the browser is handling the event to some extent.Discussion
Should this issue be left for consumers of the library to solve themselves (as I have done with my workaround), or is there any elegant way that the library could handle it? I can't think of any myself, but I'd be interested to hear your thoughts.
Either way, with this issue filing, devs will be able to see at least one way to work around it.