Files
react/components/input/password.tsx
witt 7facec3849 feat(scaleable): add scaleable props to each component (#531)
* feat(scaleable): add scaleable props to each component

* chore(scaleable): update the exported type

* feat: apply scaleable to components

chore: remove with-default

test: improve testcase for scaleable

chore: resolve test warning

ci: upgrade nodejs to latest lts

docs: fix type error in document site

* docs: update documents to be compatible with scaleable

chore: fix build errors

* chore: remove all size-related attributes

docs: improve guide document

* docs: add scaleable documentation

test: update snapshots

chore: remove unused

* feat: add scaleable to grid components

* docs: improve docs

* test: update snapshots

* fix(grid): fix basic component props
2021-08-13 17:10:57 +08:00

68 lines
1.7 KiB
TypeScript

import React, { useImperativeHandle, useMemo, useRef, useState } from 'react'
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 & NativeAttrs
const InputPassword = React.forwardRef<
HTMLInputElement,
React.PropsWithChildren<InputPasswordProps>
>(
(
{
hideToggle,
children,
...props
}: React.PropsWithChildren<InputPasswordProps> & typeof defaultProps,
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,
htmlType: 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>
)
},
)
InputPassword.defaultProps = passwordDefaultProps
InputPassword.displayName = 'GeistInputPassword'
export default InputPassword