39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
import { useState } from 'react';
|
|
import { Eye, EyeOff } from 'lucide-react';
|
|
import type { UseFormRegisterReturn } from 'react-hook-form';
|
|
import { Input } from '@/components/ui/input';
|
|
|
|
interface PasswordFieldProps extends UseFormRegisterReturn {
|
|
id: string;
|
|
placeholder?: string;
|
|
autoComplete?: string;
|
|
}
|
|
|
|
export function PasswordField({ id, placeholder, autoComplete = 'new-password', ...register }: PasswordFieldProps) {
|
|
const [show, setShow] = useState(false);
|
|
|
|
return (
|
|
<div className="relative">
|
|
<Input
|
|
{...register}
|
|
id={id}
|
|
type={show ? 'text' : 'password'}
|
|
placeholder={placeholder}
|
|
autoComplete={autoComplete}
|
|
data-testid={`${id}-input`}
|
|
className="pr-10"
|
|
/>
|
|
<button
|
|
type="button"
|
|
onClick={() => setShow((prev) => !prev)}
|
|
data-testid={`${id}-toggle`}
|
|
aria-label={show ? 'Hide password' : 'Show password'}
|
|
className="absolute inset-y-0 right-0 flex items-center px-3 text-muted-foreground hover:text-foreground"
|
|
tabIndex={-1}
|
|
>
|
|
{show ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|