Files
react/components/input/password.tsx
unix 3a8dd34010 chore: upgrade deps
style(prettier): format code style
2020-05-06 14:51:15 +08:00

58 lines
1.6 KiB
TypeScript

import React, { useImperativeHandle, useMemo, useRef, useState } from 'react'
import withDefaults from '../utils/with-defaults'
import { Props, defaultProps } from './input-props'
import PasswordIcon from './password-icon'
import Input from './input'
interface PasswordProps extends Props {
hideToggle?: boolean
}
const passwordDefaultProps = {
...defaultProps,
hideToggle: false,
}
type NativeAttrs = Omit<React.InputHTMLAttributes<any>, keyof PasswordProps>
export type InputPasswordProps = PasswordProps & typeof passwordDefaultProps & NativeAttrs
const InputPassword = React.forwardRef<
HTMLInputElement,
React.PropsWithChildren<InputPasswordProps>
>(({ hideToggle, children, ...props }, ref: React.Ref<HTMLInputElement | null>) => {
const inputRef = useRef<HTMLInputElement>(null)
const [visible, setVisible] = useState<boolean>(false)
useImperativeHandle(ref, () => inputRef.current)
const iconClickHandler = () => {
setVisible(v => !v)
/* istanbul ignore next */
if (inputRef && inputRef.current) {
inputRef.current.focus()
}
}
const inputProps = useMemo(
() => ({
...props,
ref: inputRef,
iconClickable: true,
onIconClick: iconClickHandler,
type: visible ? 'text' : 'password',
}),
[props, iconClickHandler, visible, inputRef],
)
const icon = useMemo(() => {
if (hideToggle) return null
return <PasswordIcon visible={visible} />
}, [hideToggle, visible])
return (
<Input iconRight={icon} {...inputProps}>
{children}
</Input>
)
})
export default withDefaults(InputPassword, passwordDefaultProps)