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>
This commit is contained in:
parent
c1f3503a82
commit
178c4b340c
5 changed files with 23 additions and 4 deletions
|
|
@ -7,6 +7,7 @@ import type { SelectProps } from './types';
|
|||
export function Select({
|
||||
placeholder = 'Select an option...',
|
||||
name,
|
||||
clearable = true,
|
||||
'aria-label': ariaLabel,
|
||||
'aria-labelledby': ariaLabelledBy,
|
||||
className,
|
||||
|
|
@ -36,6 +37,7 @@ export function Select({
|
|||
className={className}
|
||||
ariaLabel={ariaLabel}
|
||||
ariaLabelledBy={ariaLabelledBy}
|
||||
clearable={clearable}
|
||||
onClear={handleClear}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ interface SelectTriggerProps {
|
|||
multiple: boolean;
|
||||
disabled: boolean;
|
||||
open: boolean;
|
||||
clearable?: boolean;
|
||||
className?: string;
|
||||
ariaLabel?: string;
|
||||
ariaLabelledBy?: string;
|
||||
|
|
@ -22,6 +23,7 @@ export function SelectTrigger({
|
|||
multiple,
|
||||
disabled,
|
||||
open,
|
||||
clearable = true,
|
||||
className,
|
||||
ariaLabel,
|
||||
ariaLabelledBy,
|
||||
|
|
@ -49,7 +51,7 @@ export function SelectTrigger({
|
|||
>
|
||||
<span className="truncate">{showPlaceholder ? placeholder : displayValue}</span>
|
||||
<div className="flex items-center gap-1 ml-2">
|
||||
{hasValue && (
|
||||
{hasValue && clearable && (
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export interface SelectProps {
|
|||
searchable?: boolean;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
clearable?: boolean;
|
||||
className?: string;
|
||||
name?: string;
|
||||
'aria-label'?: string;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ export function PlaybackSettings({
|
|||
onChange={handleQualityChange}
|
||||
placeholder="Select audio quality"
|
||||
name="quality"
|
||||
clearable={false}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Higher quality uses more bandwidth
|
||||
|
|
|
|||
|
|
@ -13,11 +13,24 @@ export function useAccountSettings() {
|
|||
const [isDeletingAccount, setIsDeletingAccount] = useState(false);
|
||||
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
||||
|
||||
const [currentPassword, setCurrentPassword] = useState('');
|
||||
const [newPassword, setNewPassword] = useState('');
|
||||
const [confirmPassword, setConfirmPassword] = useState('');
|
||||
const [currentPassword, setCurrentPasswordRaw] = useState('');
|
||||
const [newPassword, setNewPasswordRaw] = useState('');
|
||||
const [confirmPassword, setConfirmPasswordRaw] = useState('');
|
||||
const [passwordError, setPasswordError] = useState('');
|
||||
|
||||
const setCurrentPassword = useCallback((v: string) => {
|
||||
setCurrentPasswordRaw(v);
|
||||
if (passwordError) setPasswordError('');
|
||||
}, [passwordError]);
|
||||
const setNewPassword = useCallback((v: string) => {
|
||||
setNewPasswordRaw(v);
|
||||
if (passwordError) setPasswordError('');
|
||||
}, [passwordError]);
|
||||
const setConfirmPassword = useCallback((v: string) => {
|
||||
setConfirmPasswordRaw(v);
|
||||
if (passwordError) setPasswordError('');
|
||||
}, [passwordError]);
|
||||
|
||||
const [deletePassword, setDeletePassword] = useState('');
|
||||
const [deleteReason, setDeleteReason] = useState('');
|
||||
const [deleteConfirmText, setDeleteConfirmText] = useState('');
|
||||
|
|
|
|||
Loading…
Reference in a new issue