59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
import { useState } from "react";
|
|
import AccessibleInput from "../../components/AccessibleInput";
|
|
import { Eye, EyeOff, LockKeyhole, UserRound, X } from "lucide-react";
|
|
|
|
export interface StarterPasswordInputProps {
|
|
value: string;
|
|
onChange: (value: string) => void;
|
|
placeholder: string;
|
|
ariaLabel: string;
|
|
autocomplete?: string;
|
|
disabled?: boolean;
|
|
ariaInvalid?: boolean;
|
|
ariaDescribedby?: string;
|
|
}
|
|
|
|
/** Starter-style password field with clear and show/hide affordances. */
|
|
export function StarterPasswordInput({
|
|
value,
|
|
onChange,
|
|
placeholder,
|
|
ariaLabel,
|
|
autocomplete,
|
|
disabled = false,
|
|
ariaInvalid,
|
|
ariaDescribedby,
|
|
}: StarterPasswordInputProps) {
|
|
const [visible, setVisible] = useState(false);
|
|
const toggle = () => setVisible((current) => !current);
|
|
|
|
return (
|
|
<AccessibleInput
|
|
inputAriaLabel={ariaLabel}
|
|
inputAriaInvalid={ariaInvalid}
|
|
inputAriaDescribedby={ariaDescribedby}
|
|
size="large"
|
|
value={value}
|
|
onChange={(next) => onChange(String(next))}
|
|
type={visible ? "text" : "password"}
|
|
disabled={disabled}
|
|
autocomplete={autocomplete}
|
|
prefixIcon={<LockKeyhole className="tn-login-input-icon" size={18} />}
|
|
// A defined (empty) suffix prevents TDesign's password icon from being
|
|
// added in addition to the Starter-style control below.
|
|
suffixIcon={<span className="tn-login-suffix-placeholder" aria-hidden="true" />}
|
|
suffix={<span className="tn-login-suffix-actions">
|
|
{value && <button type="button" className="tn-login-clear" aria-label="清空密码" onMouseDown={(event) => event.preventDefault()} onClick={() => onChange("")}><X size={15} /></button>}
|
|
<button type="button" className="tn-login-password-toggle" aria-label={visible ? "隐藏密码" : "显示密码"} aria-pressed={visible} onMouseDown={(event) => event.preventDefault()} onClick={toggle}>
|
|
{visible ? <Eye size={17} /> : <EyeOff size={17} />}
|
|
</button>
|
|
</span>}
|
|
placeholder={placeholder}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function LoginUserIcon() {
|
|
return <UserRound className="tn-login-prefix-icon" aria-hidden="true" size={18} />;
|
|
}
|