import { CSSProperties, ReactNode, useEffect, useState } from 'react' import classNames from 'classnames' import { CommonComponentProps } from '../../utils/types' import './PasswordInput.scss' export interface PasswordInputProps extends CommonComponentProps { className?: string style?: CSSProperties children?: ReactNode value?: string defaultValue?: string length?: number type?: 'border' | 'underline' gap?: number | string plainText?: boolean focused?: boolean defaultFocused?: boolean onFocused?: (focused: boolean) => void onClick?: () => void native?: boolean onChange?: (value: string) => void } export function PasswordInput(props: PasswordInputProps) { const { className, style, children, value, defaultValue, length = 6, type = 'border', gap, plainText, focused, defaultFocused, onFocused, onClick, native, onChange, ...restProps } = props const [innerValue, setInnerValue] = useState(value ?? defaultValue ?? '') const [innerFocused, setInnerFocused] = useState( focused ?? defaultFocused ?? false ) // 受控 useEffect(() => { if (value != null) { setInnerValue(value) } }, [value]) const handleClick = () => { onClick?.() } // 受控 useEffect(() => { if (focused != null) { setInnerFocused(focused) } }, [focused]) const handleChange = (event: any) => { const val = (event.target.value ?? event.detail.value).slice(0, length) // 非受控 if (value == null) { setInnerValue(val) } onChange?.(val) } const handleFocus = () => { // 非受控 if (focused == null) { setInnerFocused(true) } onFocused?.(true) } const handleBlur = () => { // 非受控 if (focused == null) { setInnerFocused(false) } onFocused?.(false) } const passwordInputClass = classNames( 's-password-input', `s-password-input-${type}`, { 's-password-input-gapless': gap === 0, }, className ) const passwordInputStyle = { ...style, gap, } return (