PasswordInput.tsx 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. "use client";
  2. import React, {useState} from "react";
  3. import clsx from "clsx";
  4. type InputType = 'text' | 'password';
  5. function PasswordInput({
  6. placeholder,
  7. onChange,
  8. onBlur,
  9. name,
  10. error,
  11. ref
  12. }: {
  13. // 用于react-hook-form时,推荐使用useForm的 defaultValues 对整个表单设置默认值
  14. placeholder: string;
  15. // 用于react-hook-form时,React 事件处理器类型定义中的“双变(bivariance)”特性 和返回值void的兼容性,使typescript没有提示类型错误
  16. onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
  17. onBlur: (e: React.ChangeEvent<HTMLInputElement>) => void;
  18. name: string;
  19. error?: string;
  20. ref?: React.Ref<HTMLInputElement>;
  21. }) {
  22. const [inputType, setInputType] = useState<InputType>('password');
  23. const changeType = () => {
  24. if(inputType === 'text') {
  25. setInputType('password');
  26. }
  27. if(inputType === 'password') {
  28. setInputType('text');
  29. }
  30. };
  31. return (
  32. <div className="w-full">
  33. <div className="relative w-full">
  34. <input className="ly-input w-full"
  35. type={inputType}
  36. placeholder={placeholder}
  37. onChange={onChange}
  38. onBlur={onBlur}
  39. name={name}
  40. ref={ref}
  41. />
  42. <div className="absolute top-1/2 right-3 -translate-y-1/2 w-4 h-4" onClick={changeType}>
  43. <svg className={clsx("block w-full h-full icon-eyehide",{
  44. "hidden": inputType !== 'password'
  45. })} xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16" fill="none">
  46. <path fill="none" stroke="#000000" strokeWidth="1.5" strokeLinecap="round" d="M3.28587 6C2.07945 7 1.33325 8 1.33325 8C1.33325 8 4.31802 12 7.99992 12C8.45655 12 8.90245 11.9385 9.33325 11.8307M6.67719 4.16667C7.10472 4.06053 7.54705 4 7.99992 4C11.6818 4 14.6666 8 14.6666 8C14.6666 8 13.9204 9 12.714 10">
  47. </path>
  48. <path fill="none" stroke="#000000" strokeWidth="1.3333333333333333" strokeLinejoin="round" strokeLinecap="round" d="M6.77132 6.87372C6.49929 7.17032 6.33325 7.56575 6.33325 7.99995C6.33325 8.92042 7.07945 9.66662 7.99992 9.66662C8.45415 9.66662 8.86595 9.48489 9.16658 9.19018">
  49. </path>
  50. <path fill="none" stroke="#000000"strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" d="M14 14L2 2">
  51. </path>
  52. </svg>
  53. <svg className={clsx("block w-full h-full icon-eyeshow",{
  54. "hidden": inputType !== 'text'
  55. })} xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16" fill="none">
  56. <path stroke="#000000" d="M7.99992 12C11.6818 12 14.6666 8 14.6666 8C14.6666 8 11.6818 4 7.99992 4C4.31802 4 1.33325 8 1.33325 8C1.33325 8 4.31802 12 7.99992 12Z" fill="none" strokeWidth="1.5">
  57. </path>
  58. <path stroke="#000000" d="M7.99992 9.66665C8.92039 9.66665 9.66658 8.92045 9.66658 7.99998C9.66658 7.07951 8.92039 6.33331 7.99992 6.33331C7.07945 6.33331 6.33325 7.07951 6.33325 7.99998C6.33325 8.92045 7.07945 9.66665 7.99992 9.66665Z" fill="none" strokeWidth="1.5" strokeLinejoin="round">
  59. </path>
  60. </svg>
  61. </div>
  62. </div>
  63. {error && <p className="text-red-500 text-ly-12">{error}</p>}
  64. </div>
  65. );
  66. }
  67. // 设置 displayName,便于调试
  68. PasswordInput.displayName = 'PasswordInput';
  69. export default PasswordInput;