pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
at main 85 lines 2.1 kB view raw
1import classNames from "classnames"; 2import { forwardRef, useState } from "react"; 3 4import { Icon, Icons } from "../Icon"; 5 6export interface TextInputControlPropsNoLabel { 7 onChange?: (data: string) => void; 8 onUnFocus?: () => void; 9 onFocus?: () => void; 10 value?: string; 11 name?: string; 12 autoComplete?: string; 13 placeholder?: string; 14 className?: string; 15 passwordToggleable?: boolean; 16} 17 18export interface TextInputControlProps extends TextInputControlPropsNoLabel { 19 label?: string; 20} 21 22export const TextInputControl = forwardRef< 23 HTMLInputElement, 24 TextInputControlProps 25>( 26 ( 27 { 28 onChange, 29 onUnFocus, 30 value, 31 label, 32 name, 33 autoComplete, 34 className, 35 placeholder, 36 onFocus, 37 passwordToggleable, 38 }, 39 ref, 40 ) => { 41 let inputType = "text"; 42 const [showPassword, setShowPassword] = useState(true); 43 if (passwordToggleable) inputType = showPassword ? "password" : "text"; 44 45 const input = ( 46 <div className="relative"> 47 <input 48 type={inputType} 49 ref={ref} 50 className={classNames(className, passwordToggleable && "pr-12")} 51 placeholder={placeholder} 52 onChange={(e) => onChange && onChange(e.target.value)} 53 value={value} 54 name={name} 55 autoComplete={autoComplete} 56 onBlur={() => onUnFocus && onUnFocus()} 57 onFocus={() => onFocus?.()} 58 onKeyDown={(e) => 59 e.key === "Enter" ? (e.target as HTMLInputElement).blur() : null 60 } 61 /> 62 {passwordToggleable ? ( 63 <button 64 type="button" 65 className="absolute top-1/2 -translate-y-1/2 right-1 text-xl p-3" 66 onClick={() => setShowPassword(!showPassword)} 67 > 68 <Icon icon={showPassword ? Icons.EYE : Icons.EYE_SLASH} /> 69 </button> 70 ) : null} 71 </div> 72 ); 73 74 if (label) { 75 return ( 76 <label> 77 <span>{label}</span> 78 {input} 79 </label> 80 ); 81 } 82 83 return input; 84 }, 85);