segmentio / evergreen

🌲 Evergreen React UI Framework by Segment
https://evergreen.segment.com
MIT License
12.39k stars 832 forks source link

Ability to disable autofocus logic in Overlay component #1404

Closed brandongregoryscott closed 2 years ago

brandongregoryscott commented 2 years ago

On more than one occasion, the autofocus behavior in <Overlay /> has been more obstructive than helpful when trying to properly set focus in a Dialog or SideSheet which are built on-top of it.

This is the autofocus logic as it stands today: https://github.com/segmentio/evergreen/blob/0ba8a87b70c029febac59b57277336a8f45fe5cd/src/overlay/src/Overlay.js#L157-L168

CodeSandbox example of the current default behavior (focuses the Submit button despite other input/interactive elements appearing prior)

For a specific example, if you have a SideSheet that has multiple input elements that should naturally take focus on open and there's an element that has a tabIndex manually set for accessibility purposes - it will prioritize focusing that element first, which probably doesn't make sense. CodeSandbox

One other thing to note is that the current behavior may not even be correct without a manually set tabIndex. For example, if you have a SideSheet that is rendering our Combobox component, it will focus the dropdown button instead of the input element that comes before it. CodeSandbox

This forces consumers to either accept incorrect focusing behavior, or wire up some unfortunate workarounds such as an invisible TextInput that has autoFocus={true}.

While a longer-term solution might be updating the autofocus priority to be a little smarter (or controlled by the consumer if desired), I think a good middle-ground is retaining the current behavior but adding a prop that can disable it entirely.