All files / src/components PasswordInput.tsx

100% Statements 4/4
100% Branches 13/13
100% Functions 2/2
100% Lines 4/4

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52                                    2x         75x   75x                     2x                              
// 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>
  );
};