You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently in the process of moving a projects code over from an 'internal' ui library to a project specific ui set. So far it's been going well, but I am really caught up on the ComboBox. I cannot for the life of me figure out what the deal is with this component, it seems like I am having issues at every turn.
Questions if anyone has answers:
Is it possible to use Select instead of ComboBox? I want the searchable/autocomplete but ComboBox seems to lack multi-select.
In the old component, tabbing to the Input and then pressing tab again would open it, and pressing tab again would enter the popover. Based on what I am reading, this appears to be bad from an accessibility standpoint. That said, people have been using this tool for 5 years and have muscle memory. Is there an easy way to preserve this tab functionality?
Currently, setting the defaultSelectedKey is working but is visually not showing the selectedKey. Any ideas why?
Is there an easy way to translate the solution to this issue to react-aria-components? Or should I just transition to useComboBox?
Ensure popover closes when focus is elsewhere?
All help/suggestions is appreciated, thank you.
importReactfrom'react';import{ComboBox,ListBox,Key}from'react-aria-components';import{useListData}from'react-stately';importAMPSelectPopoverfrom'@/amp-ui/AMPDynamicSelect/AMPSelectPopover';importAMPSelectItemfrom'@/amp-ui/AMPDynamicSelect/AMPSelectItem';importAMPLabelfrom'@/amp-ui/AMPLabel';importAMPInputfrom'@/amp-ui/AMPInput';import{MagnifyingGlassIcon}from'@radix-ui/react-icons';typeDynamicOptions<TPropertyNameextendsstring,TPropertyIDextendsstring>=Record<TPropertyName|TPropertyID,string>;interfaceAMPDynamicSelectProps<TPropertyNameextendsstring,TPropertyIDextendsstring>{label: string;options: DynamicOptions<TPropertyName,TPropertyID>[];propertyName: TPropertyName;propertyID: TPropertyID;selectedItem?: DynamicOptions<TPropertyName,TPropertyID>[TPropertyID];onChange?: (key: string)=>any;onSelect?: (item: DynamicOptions<TPropertyName,TPropertyID>)=>any;disabled?: boolean;'aria-label'?: string;}/** * @description Select for a dynamic list of items * * @link https://react-spectrum.adobe.com/react-aria/ComboBox.html */exportfunctionAMPDynamicSearch<TPropertyNameextendsstring,TPropertyIDextendsstring>({
label,
options,
propertyName,
propertyID,
selectedItem,
onChange,
onSelect,
disabled,
...props}: AMPDynamicSelectProps<TPropertyName,TPropertyID>){constlist=useListData({initialItems: options,getKey: (item)=>item[propertyID],initialSelectedKeys: selectedItem ? [selectedItem] : [],filter: (item,filterText)=>filterText===''||item[propertyName].toLowerCase().includes(filterText.toLowerCase())});letonSelectionChange=(key: Key)=>{constitem=list.getItem(key);letitemText=item ? item[propertyName] : '';list.setSelectedKeys(newSet([key]));list.setFilterText(itemText);onSelect&&onSelect(item);onChange&&onChange(item[propertyID]);};letonInputChange=(value: string): void=>{// Clear key if user deletes all text in the fieldif(value===''){list.setSelectedKeys(newSet([]));}list.setFilterText(value);};return(<ComboBox<DynamicOptions<TPropertyName,TPropertyID>>className='relative w-full'onSelectionChange={onSelectionChange}onInputChange={onInputChange}inputValue={list.filterText}items={list.items}defaultSelectedKey={selectedItem}shouldFocusWrap={true}menuTrigger='input'isDisabled={disabled}aria-label={props['aria-label']||label||undefined}><AMPLabelclassName='text-muted-foreground text-sm antialiased inline-flex items-center align-middle absolute -mt-6'><spanclassName='flex items-center'>{label}</span></AMPLabel><AMPInputattachLeft={<MagnifyingGlassIcon/>}/><AMPSelectPopover><spanclassName='absolute text-xs text-muted-foreground right-0 mr-2 z-10'>{list.items.length}results</span><ListBox<DynamicOptions<TPropertyName,TPropertyID>>className='p-1 overflow-y-auto max-h-40'>{(item)=>(<AMPSelectItemkey={item[propertyID]}id={item[propertyID]}textValue={item[propertyName]}className='relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[focused]:bg-accent data-[focused]:text-accent-foreground data-[disabled]:opacity-50'>{item[propertyName]}</AMPSelectItem>)}</ListBox></AMPSelectPopover></ComboBox>);}
Do you know of any examples for ComboBox and TagGroup being used together? Wondering how to best handle a user accidentally selecting an item and needing to delete it quickly.
That may be what I end up doing
I ripped out the useListData portion of my code which seems to have fixed it. Sadly I then need to reimplement the filter to show the number of results (see stackblitz on number 5). If you know of a better solution I am all ears.
autoFocus seems to be what I would want, but it doesn't appear to work consistently. If I set the ComboBox to open on focus then it doesn't work. If I press space (there are options with a space) then it doesn't work. If there is a prefilled value, it doesn't work. Maybe bugs? Maybe I'm doing it wrong.
I haven't used these tools before and a lot of this data is dependent upon a bunch of other stuff so sorry for the incompleteness of it: stackblitz You can see that when you get the dropdown to appear (press down arrow or type something) it doesn't vanish when you click somewhere else.
As for 4, I would avoid trying to autofocus any of the items in the dropdown without first verifying that NVDA doesn't have an issue with announcing the input field's text edits as the user types. If NVDA no longer has that issue, the best place to implement that would be in the hooks themselves, I don't think autoFocus on the ListBox will work here since it is typically used for initial render.
I'm not exactly sure what is happening for number 5, but if you add another input element as a sibling it closes the popover when clicking on it. Will have to compare between the docs version and this implementation since it works in the docs
I really only want an autoFocus when one result remains, it's a bit silly (in my opinion) that you can type exactly what you want and for it to be valid just to hit enter and the input be cleared. Maybe there is a different solution than an autoFocus?
It does look like the autoclose works when I add an invisible button. That is interesting
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Currently in the process of moving a projects code over from an 'internal' ui library to a project specific ui set. So far it's been going well, but I am really caught up on the ComboBox. I cannot for the life of me figure out what the deal is with this component, it seems like I am having issues at every turn.
Questions if anyone has answers:
All help/suggestions is appreciated, thank you.
Beta Was this translation helpful? Give feedback.
All reactions