veza/apps/web/src/components/ui/select/Select.tsx
senke 178c4b340c fix(settings): fix password error persistence and audio quality clearable
- 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>
2026-03-25 23:43:45 +01:00

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 ?? ''
}
/>
)}
</>
);
}