-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ComboBox with autofocus doesn't show its dropdown auto focused with menuTrigger='focus'
#5464
Comments
Exactly the same situation here ! Interested in any input from OP or anyone else on how to achieve this ! Thank you very much |
Could you expand on how much control over the open state you need for the ComboBox here? |
I think I would like to have something like `menuTrigger="always"` or
something like this.
Le lun. 11 déc. 2023, 18:45, Daniel Lu ***@***.***> a écrit :
… Could you expand on how much control over the open state you need for the
ComboBox here?
—
Reply to this email directly, view it on GitHub
<#5464 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AASG6H63COSDGYOYD2D25CLYI5BDVAVCNFSM6AAAAAA7XAZPECVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNJQGU3DSMZXHA>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
So would that mean the combobox is open at all times? If that is the case, I think you'd be better off using a searchfield + listbox (which I now see you've mentioned in the discussion) since the ComboBox's open overlay would hide the rest of the page from screenreaders when open. Depending on how much you'd want the experience to match ComboBox (aka would focus remain in the searchfield and up/down arrow keys move virtual focusing in the ListBox?), it would take some work extracting what you need from the hooks. It the searchfield was more of a standalone experience from the listbox (aka typing in it would simply change what the listbox displays) then it would be more straightforward since you'd simply control the searchfield's input and use that to fetch a list of items for the listbox. |
What I really find difficult with the searchfield + listbox solution is
that, being fairly new to react aria, I wouldn't know how to keep the focus
on the input yet still be able to navigate options with the arrow keys.
Also, I'm facing a bug with combobox where, with a not so large list,
typing then navigating with arrows then typing again makes the input lose
focus. I should probably open an issue with this, but I can't reproduce the
bug on a standalone page... (data is fetched from a React Context).
Le lun. 11 déc. 2023, 19:02, Daniel Lu ***@***.***> a écrit :
… So would that mean the combobox is open at all times? If that is the case,
I think you'd be better off using a searchfield + listbox (which I now see
you've mentioned in the discussion) since the ComboBox's open overlay would
hide the rest of the page from screenreaders when open. Depending on how
much you'd want the experience to match ComboBox (aka would focus remain in
the searchfield and up/down arrow keys move virtual focusing in the
ListBox?), it would take some work extracting what you need from the hooks.
It the searchfield was more of a standalone experience from the listbox
(aka typing in it would simply change what the listbox displays) then it
would be more straightforward since you'd simply control the searchfield's
input and use that to fetch a list of items for the listbox.
—
Reply to this email directly, view it on GitHub
<#5464 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AASG6H6KBG25GM4MX5IPB3LYI5DC7AVCNFSM6AAAAAA7XAZPECVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNJQGU4TQNZWGM>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
So in short, the way this is handled is via tracking the "focusedKey" in state (aka the selectionManager), modifying it via the keyboard handlers attached to the input field (also see react-spectrum/packages/@react-aria/selection/src/useSelectableCollection.ts Lines 123 to 189 in 5ce9a29
Not sure what would be causing this, definitely file an issue once you get a base reproduction! |
menuTrigger='focus'
Well thank you very much for the detailed answer and suggestions. This makes a lot of digging and internals comprehension for my use case. I'll make sure to give it a try anyways. |
Yeah, unfortunately the hooks as is come with a bit too much extra stuff, it would take some work pulling out the relevant code. Hopefully in the future we'll have a more base level |
Well that would be great ! as I believe many people must be reimplementing
this themselves ?
…On Tue, 12 Dec 2023 at 20:24, Daniel Lu ***@***.***> wrote:
Yeah, unfortunately the hooks as is come with a bit too much extra stuff,
it would take some more pulling out the relevant code. Hopefully in the
future we'll have a more base level useAutoComplete hook that only offers
the collection filtering + focus handling without all the extra overlay
open/closed state tracking
—
Reply to this email directly, view it on GitHub
<#5464 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AASG6HYFJIEQOU7WXYOP7KTYJCVPZAVCNFSM6AAAAAA7XAZPECVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNJSGY3DSNRXGA>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
So I've managed to control a ListBox using a search field like so : But I cannot get the ListBox focus to wrap even though I've passed function SearchableListBox() {
const { globalSearch, setGlobalSearch } = useState("");
const searchHistory = useState([
{ id: "a", search: "foo bar", date: new Date(), error: false },
{ id: "b", search: "foo baz", date: new Date(), error: false },
{ id: "c", search: "foo bar baz", date: new Date(), error: true },
{ id: "d", search: "bar baz", date: new Date(), error: false },
]); // replaced by data normally retrieved in IndexedDB using Dexie*/
const getSearchEntryById = (id) => searchHistory.filter((query) => id === `${query.id}`).at(0);
const listBoxItem = (query) => (
<Item key={query.id} textValue={query.search} title={query.search} query={query} />
);
const listBoxState = useSingleSelectListState({
onSelectionChange: (id) => setGlobalSearch(getSearchEntryById(id).search),
items: searchHistory.filter((query) => query.search.indexOf(globalSearch) >= 0),
children: listBoxItem,
});
// Get props for the listbox element
let listBoxRef = React.useRef(null);
let { listBoxProps } = useListBox({
label: "Search history",
shouldFocusWrap: true,
}, listBoxState, listBoxRef);
let inputRef = useRef(null);
return (
<>
<input
value={globalSearch}
onChange={(e) => setGlobalSearch(e.target.value)}
ref={inputRef}
id="searchbar"
placeholder="Search"
/>
<ListBox {...listBoxProps} listBoxRef={listBoxRef} state={listBoxState} />
</>
);
} PS : the |
Just chiming in that I haven't forgotten about this, but we're pretty busy with an upcoming release so I haven't been able to look at this in-depth. the keyboard virtual focus can be setup by doing something like react-spectrum/packages/@react-aria/combobox/src/useComboBox.ts Lines 98 to 108 in 2b05b6d
useComboBox but not having a open state to flip on/off should make that easier. I'm not sure about the shouldFocusWrap issue, would need to dig.
|
Hi! I tried to follow your suggestion and am running into an issue: it appears like the collection is always empty. It was all pretty straightforward to put together, thanks to the amazing composition API you all designed, and I feel like I'm close, but I also feel like I'm missing something. Curious if anything comes to mind with what I've documented over at #6281? |
Just to double check, the code you added in #6281 your most up to date code? When you say the collection is always empty, I assume that means the ListBox itself isn't rendering anything at all? I assume the ListBox you are using is straight from RAC or is it a modified version? EDIT: |
Correct -- that's the most up-to-date code. The ListBox does indeed render empty and the underlying collection is empty (even though I can see items going into The update to that post about copying Collection.tsx didn't solve it, and I can try your suggestion to ensure the contexts are identical. The thing is that before I reached for that, the collection was empty too. |
I take it that it should have worked as-is with the off-the-shelf RAC ListBox? Is the |
The off the shelf ListBox should at the very least be able to render to items when used standalone so if that isn't working then that is unexpected. As for using RAC to build this autocomplete experience, yes you'll need |
Discussed in #5462
Originally posted by austincrim November 22, 2023
I'm trying to build a CMD + K-like interface using a
ComboBox
inside of aDialog
. I want theListBox
options to always be visible, regardless if theInput
has been typed in or manually focused (using theComboBox
menuTrigger
prop).I couldn't find a way to do this in the docs. Any recommendations?
Here's how it looks now, but I want the list of options to be visible as soon as the dialog is opened.
Stackblitz link
CleanShot.2023-11-22.at.15.14.50.mp4
As an aside, the React Spectrum support page still links to creating a new GitHub Issue, when it looks like you've switched to Discussions.
See #5462 (reply in thread) for more info. The gist is that the collection for the ComboBox is undefined/empty when the input gets autofocused since RAC collections need two renders to fully generate.
The text was updated successfully, but these errors were encountered: