unovue / radix-vue

Vue port of Radix UI Primitives. An open-source UI component library for building high-quality, accessible design systems and web apps.
https://radix-vue.com
MIT License
3.69k stars 228 forks source link

[Bug]: Combobox using portal Input not clickable/focusable when within a dialog portal #1170

Open timmaier opened 3 months ago

timmaier commented 3 months ago

Environment

Node version: 20.15.1
Radix Vue version: 2.9.2
Vue version: 3.2.32

Please see stackblitz

Link to minimal reproduction

https://stackblitz.com/edit/ptivtd?file=src%2FApp.vue

Steps to reproduce

Add a Combobox input that uses ComboboxPortal. Add a ComboboxInput within the ComboboxViewport. Place this component within a Dialog.

Describe the bug

The ComboboxInput is not focusable and cannot accept any keyboard input.

Expected behavior

The ComboboxInput should be focusable and searchable when placed within a Dialog.

Context & Screenshots (if applicable)

Screenshot 2024-07-30 at 11 29 34 AM
zernonia commented 3 months ago

It's related to FocusScope within Dialog component. If element were teleported out from the scope, you cannot focus on it.

As a temporary solution you can remove ComboboxPortal and let it render inline, this way the ComboboxInput will stay within the scope.

kilobyte2007 commented 3 months ago

Thanks a lot @zernonia! Your solution seems to work well, but feels more like a hack (hence you said temporary). What would be a natural solution? If I understand correctly we'd need to give priority to the Combobox focus over the Dialog's FocusScope somehow.

timmaier commented 3 months ago

Yes I've removed the portal in our use case for now too. This prevents the ability to use position popper though with prevent collision.

kilobyte2007 commented 1 month ago

Hi @zernonia, is this planned for v2 or will it be left for later? Thanks!

timmaier commented 1 day ago

What we ended up doing is moving our dialog to use headlessui dialog instead. That way we can continue to use portal rendering strategy in modals.