Setting a Pressable as "disabled" from enter key press locks its internal focused
state as true
#2357
Closed
1 task done
focused
state as true
#2357
Is there an existing issue for this?
Might be a side effect of the fix for #2127
Describe the issue
If a Pressable's
onPress
function causes it to becomedisabled
, and this is triggered by tabbing in with the keyboard and triggering theonPress
function from the keyboard using the Enter key, then the Pressable's internalfocused
state becomes locked astrue
even after the actual HTML element has blurred.For example, here, the first Pressable was disabled and blurred using the Enter key and the second Pressable is the focused element, but the first Pressable thinks it is focused still.
Expected behavior
A Pressable's
focused
state should not betrue
if it is not focused, regardless of how it came to be not focused, and it should never be both disabled and focused.Steps to reproduce
Pressable
that shows its internalfocused
state visiblydisabled
state totrue
in anonPress
handlerTest case
https://codesandbox.io/s/quirky-williamson-v3r94g
https://snack.expo.dev/@alansl/amused-cheese
Additional comments
There's also a possibly-related issue described in comments in the linked example, where it's possible to programmatically focus a
disabled
Pressable just beforedisabled
is removed, and then whendisabled
is removed, the element is focused but the focused state is stuck asfalse
. Which issue occurs depends on whether mouse or keyboard events are used and timing of when the focus switch happens. Suggests the issue hinges on the timing of rerenders triggered by different event types.In the provided example, it's almost possible to work around this issue with careful timing - programmatically blurring the element after setting disabled to
false
in the target but before setting it totrue
in the trigger element. But this creates some strange timing issues when mouse clicks are used. Also, in real-life examples, this may not be an option: for example if the elements'disabled
state is controlled by oneselected
state, it may not be possible to set a moment when both are enabled.Suggested fix
It looks like all focus / blur handling is suppressed as soon as
disabled
is applied, and the timing of this relative to event handler timing varies by event type. Suggestion:disabled
flips from false to true, iffocused
is still true, it shouldn't be and the element is losing focus; so callonBlur
(including setting internal state) while it still can.disabled
flips from true to false, if the element has become actually focused in the DOM butfocused
is false, it is legitimately gaining focus but the event handlers were skipped due to event / re-render timing; so callonFocus
(including setting internal state)The text was updated successfully, but these errors were encountered: