- Wrap password state setters to auto-clear passwordError on input change,
so stale validation errors don't persist after user corrects the fields
- Add clearable prop to Select component (default true for back-compat)
- Pass clearable={false} to audio quality dropdown so users cannot clear
it to an empty/invalid state
Fixes: Settings bugs #17, #20
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
78 lines
1.8 KiB
TypeScript
78 lines
1.8 KiB
TypeScript
import { Dropdown } from '../dropdown';
|
|
import { SelectTrigger } from './SelectTrigger';
|
|
import { SelectDropdownContent } from './SelectDropdownContent';
|
|
import { useSelect } from './useSelect';
|
|
import type { SelectProps } from './types';
|
|
|
|
export function Select({
|
|
placeholder = 'Select an option...',
|
|
name,
|
|
clearable = true,
|
|
'aria-label': ariaLabel,
|
|
'aria-labelledby': ariaLabelledBy,
|
|
className,
|
|
...props
|
|
}: SelectProps) {
|
|
const {
|
|
open,
|
|
setOpen,
|
|
search,
|
|
setSearch,
|
|
searchInputRef,
|
|
filteredOptions,
|
|
displayValue,
|
|
isSelected,
|
|
handleSelect,
|
|
handleClear,
|
|
} = useSelect({ ...props, placeholder });
|
|
|
|
const trigger = (
|
|
<SelectTrigger
|
|
displayValue={displayValue}
|
|
placeholder={placeholder}
|
|
value={props.value}
|
|
multiple={props.multiple ?? false}
|
|
disabled={props.disabled ?? false}
|
|
open={open}
|
|
className={className}
|
|
ariaLabel={ariaLabel}
|
|
ariaLabelledBy={ariaLabelledBy}
|
|
clearable={clearable}
|
|
onClear={handleClear}
|
|
/>
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<Dropdown
|
|
trigger={trigger}
|
|
align="left"
|
|
onOpenChange={setOpen}
|
|
className="w-full"
|
|
>
|
|
<SelectDropdownContent
|
|
searchable={props.searchable ?? false}
|
|
search={search}
|
|
onSearchChange={setSearch}
|
|
searchInputRef={searchInputRef}
|
|
filteredOptions={filteredOptions}
|
|
multiple={props.multiple ?? false}
|
|
isSelected={isSelected}
|
|
onSelect={handleSelect}
|
|
ariaLabel={ariaLabel}
|
|
name={name}
|
|
placeholder={placeholder}
|
|
/>
|
|
</Dropdown>
|
|
{name && (
|
|
<input
|
|
type="hidden"
|
|
name={name}
|
|
value={
|
|
Array.isArray(props.value) ? props.value.join(',') : props.value ?? ''
|
|
}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|