huntabyte / bits-ui

The headless components for Svelte.
https://bits-ui.com
MIT License
968 stars 70 forks source link

Change Dialog focus behavior on open? #427

Open ellicodan opened 7 months ago

ellicodan commented 7 months ago

Change Type

Addition

Proposed Changes

When a Dialog is opened, it automatically focuses on the first input element. On mobile, this causes the virtual keyboard to open immediately. Is there a way to change the focus behavior for Dialogs? I've tried passing openFocus={null} to the root of the Dialog but it did not work. I am not sure if I'm using it correctly.

austerj commented 7 months ago

I had the same issue and for now have been using this hacky workaround inside Dialog.Content until I find something better:

<!-- svelte-ignore a11y-autofocus -->
<input class="fixed left-0 top-0 h-0 w-0" type="checkbox" autofocus={true} />

It's not the prettiest, so would also be happy to find a more direct way of doing this. I also found that the layout shift is not always very well-behaved (e.g. sometimes the keyboard will open without the dialog shifting and hide the content from the user underneath the keyboard), but not sure how much of this is dictated by browser behavior...

huntabyte commented 7 months ago

So because there's a focus trap in the dialog when open if you truly didn't focus anything at all, keyboard users would be trapped with no way to navigate through the component.

I do however think that we probably shouldn't focus automatically when opened via a touch or click event, rather only when the user presses tab for the first time which would solve this issue with mobile devices.

I will investigate further this weekend, thanks for raising the issue!

Dayno commented 4 months ago

Hi, is this still being investigated?

devjume commented 2 months ago

I used following prevent autofocus on the input element, which caused the virtual keyboard to open immediately on mobile.

Workaround / Fix

Set the focus to be on content div via elements id.
This focuses on the parent div and not input element.

<Dialog.Root openFocus={"#content-div"}>
  <Dialog.Content id="content-div">
    <input type="text"/>
  <Dialog.Content/>
</Dialog.Root>

See my comment for more details on melt-ui #1007

vcheeze commented 2 weeks ago

@devjume interestingly, this does not seem to work for the Drawer component. Any ideas on how to get around auto focus for Drawers?