Skip to content

Commit 206db95

Browse files
committed
feat: add component for password field
1 parent c649c42 commit 206db95

File tree

5 files changed

+114
-9
lines changed

5 files changed

+114
-9
lines changed

src/Assets/Icon/ic-visibility-off.svg

Lines changed: 19 additions & 0 deletions
Loading

src/Assets/Icon/ic-visibility-on.svg

Lines changed: 20 additions & 0 deletions
Loading
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { useState } from 'react'
2+
import { DEFAULT_SECRET_PLACEHOLDER } from '@Shared/constants'
3+
import { ReactComponent as ICVisibilityOn } from '@Icons/ic-visibility-on.svg'
4+
import { ReactComponent as ICVisibilityOff } from '@Icons/ic-visibility-off.svg'
5+
import CustomInput from './CustomInput'
6+
import { CustomInputProps, PasswordFieldProps } from './types'
7+
8+
const PasswordField = ({ onFocus, onBlur, shouldShowDefaultPlaceholderOnBlur, ...props }: PasswordFieldProps) => {
9+
const [fieldType, setFieldType] = useState<CustomInputProps['type']>('password')
10+
11+
const isFieldTypePassword = fieldType === 'password'
12+
13+
const handleFocus: CustomInputProps['onFocus'] = (event) => {
14+
if (event.target.value === DEFAULT_SECRET_PLACEHOLDER) {
15+
// eslint-disable-next-line no-param-reassign
16+
event.target.value = ''
17+
}
18+
19+
onFocus?.(event)
20+
}
21+
22+
const handleBlur: CustomInputProps['onBlur'] = (event) => {
23+
if (shouldShowDefaultPlaceholderOnBlur && event.target.value === '') {
24+
// eslint-disable-next-line no-param-reassign
25+
event.target.value = DEFAULT_SECRET_PLACEHOLDER
26+
}
27+
setFieldType('password')
28+
onBlur?.(event)
29+
}
30+
31+
return (
32+
<CustomInput
33+
{...props}
34+
onFocus={handleFocus}
35+
onBlur={handleBlur}
36+
type={fieldType}
37+
endIconButtonConfig={
38+
props.value && props.value !== DEFAULT_SECRET_PLACEHOLDER
39+
? {
40+
icon: isFieldTypePassword ? <ICVisibilityOn /> : <ICVisibilityOff />,
41+
onClick: () => {
42+
setFieldType((prevFieldType) => (prevFieldType === 'password' ? 'text' : 'password'))
43+
},
44+
ariaLabel: isFieldTypePassword ? 'Show password' : 'Hide password',
45+
}
46+
: null
47+
}
48+
/>
49+
)
50+
}
51+
52+
export default PasswordField

src/Shared/Components/CustomInput/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515
*/
1616

1717
export { default as CustomInput } from './CustomInput'
18-
export type { CustomInputProps } from './types'
18+
export { default as PasswordField } from './PasswordField'
19+
export type { CustomInputProps, PasswordFieldProps } from './types'

src/Shared/Components/CustomInput/types.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ import { ButtonComponentType, ButtonProps } from '../Button'
2121

2222
export interface CustomInputProps
2323
extends Omit<FormFieldWrapperProps, 'children' | 'inputId'>,
24-
Pick<
25-
InputHTMLAttributes<HTMLInputElement>,
26-
'onBlur' | 'disabled' | 'autoFocus' | 'onFocus' | 'type' | 'onKeyDown'
27-
>,
24+
Pick<InputHTMLAttributes<HTMLInputElement>, 'onBlur' | 'disabled' | 'autoFocus' | 'onFocus' | 'onKeyDown'>,
2825
Required<Pick<InputHTMLAttributes<HTMLInputElement>, 'placeholder' | 'onChange' | 'value' | 'name'>> {
2926
/**
3027
* If false, the input is not trimmed on blur
@@ -38,8 +35,24 @@ export interface CustomInputProps
3835
* @default ComponentSizeType.large
3936
*/
4037
size?: Extract<ComponentSizeType, ComponentSizeType.medium | ComponentSizeType.large>
41-
endIconButtonConfig?: Pick<
42-
ButtonProps<ButtonComponentType.button>,
43-
'icon' | 'onClick' | 'disabled' | 'ariaLabel' | 'showAriaLabelInTippy' | 'style'
44-
>
38+
/**
39+
* Type for the input
40+
*
41+
* Note: For password field, use PasswordField component
42+
*
43+
* @default 'text'
44+
*/
45+
type?: Exclude<InputHTMLAttributes<HTMLInputElement>['type'], 'password'>
46+
/**
47+
* End icon button configuration
48+
*/
49+
endIconButtonConfig?: Required<Pick<ButtonProps<ButtonComponentType.button>, 'icon' | 'onClick' | 'ariaLabel'>> &
50+
Pick<ButtonProps<ButtonComponentType.button>, 'disabled' | 'showAriaLabelInTippy' | 'style'>
51+
}
52+
53+
export interface PasswordFieldProps extends Omit<CustomInputProps, 'endIconButtonConfig' | 'type'> {
54+
/**
55+
* If true, the value is cleared & default placeholder is shown on blur
56+
*/
57+
shouldShowDefaultPlaceholderOnBlur: boolean
4558
}

0 commit comments

Comments
 (0)