MaskedInput.tsx 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import type { ChangeEvent } from 'react';
  2. import { useState, type JSX } from 'react';
  3. import type { UseFormRegister } from 'react-hook-form';
  4. import styles from './MaskedInput.module.scss';
  5. type Props = {
  6. name?: string
  7. readOnly: boolean
  8. value?: string
  9. onChange?: (e: ChangeEvent<HTMLInputElement>) => void
  10. tabIndex?: number | undefined
  11. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  12. register?: UseFormRegister<any>
  13. fieldName?: string
  14. };
  15. export default function MaskedInput(props: Props): JSX.Element {
  16. const [passwordShown, setPasswordShown] = useState(false);
  17. const togglePassword = () => {
  18. setPasswordShown(!passwordShown);
  19. };
  20. const {
  21. name, readOnly, value, onChange, tabIndex, register, fieldName,
  22. } = props;
  23. // Use register if provided, otherwise use value/onChange
  24. const inputProps = register && fieldName
  25. ? register(fieldName)
  26. : {
  27. name,
  28. value,
  29. onChange,
  30. };
  31. return (
  32. <div className={styles.MaskedInput}>
  33. <input
  34. className="form-control"
  35. type={passwordShown ? 'text' : 'password'}
  36. readOnly={readOnly}
  37. tabIndex={tabIndex}
  38. {...inputProps}
  39. />
  40. <span onClick={togglePassword} className={styles.PasswordReveal}>
  41. {passwordShown ? (
  42. <span className="material-symbols-outlined">visibility</span>
  43. ) : (
  44. <span className="material-symbols-outlined">visibility_off</span>
  45. )}
  46. </span>
  47. </div>
  48. );
  49. }