Files
flyer-crawler.projectium.com/src/components/PasswordInput.tsx
Torben Sorensen 05e3f8a61c
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 12m10s
minor fix
2025-12-27 21:29:37 -08:00

52 lines
1.9 KiB
TypeScript

// src/components/PasswordInput.tsx
import React, { useState } from 'react';
import { EyeIcon } from './icons/EyeIcon';
import { EyeSlashIcon } from './icons/EyeSlashIcon';
import { PasswordStrengthIndicator } from './PasswordStrengthIndicator';
/**
* Props for the PasswordInput component.
* It extends standard HTML input attributes and adds a custom prop to show a strength indicator.
*/
interface PasswordInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
showStrength?: boolean;
}
/**
* A reusable password input component with a show/hide toggle
* and an optional password strength indicator.
*/
export const PasswordInput: React.FC<PasswordInputProps> = ({
showStrength = false,
className,
...props
}) => {
const [showPassword, setShowPassword] = useState(false);
return (
<div>
<div className="relative">
<input
{...props}
type={showPassword ? 'text' : 'password'}
// Combine passed classNames with default styling
className={`block w-full px-3 py-2 pr-10 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-brand-primary focus:border-brand-primary sm:text-sm ${className || ''}`}
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200"
aria-label={showPassword ? 'Hide password' : 'Show password'}
>
{showPassword ? <EyeSlashIcon className="h-5 w-5" /> : <EyeIcon className="h-5 w-5" />}
</button>
</div>
{showStrength && typeof props.value === 'string' && props.value.length > 0 && (
<div className="pt-2">
<PasswordStrengthIndicator password={props.value} />
</div>
)}
</div>
);
};