1 import type { ForwardRefRenderFunction } from 'react';
2 import { forwardRef, useState } from 'react';
4 import { type FieldProps } from 'formik';
6 import type { Input } from '@proton/atoms';
7 import { InputFieldTwo } from '@proton/components';
8 import { type InputFieldProps } from '@proton/components/components/v2/field/InputField';
9 import { pipe } from '@proton/pass/utils/fp/pipe';
10 import { isEmptyString } from '@proton/pass/utils/string/is-empty-string';
11 import clsx from '@proton/utils/clsx';
12 import identity from '@proton/utils/identity';
14 import { useFieldControl } from '../../../hooks/useFieldControl';
15 import { useMaxLengthLimiter } from '../../../hooks/useMaxLengthLimiter';
16 import { usePasteLengthLimiter } from '../../../hooks/usePasteLengthLimiter';
17 import { FieldBox, type FieldBoxProps } from './Layout/FieldBox';
19 export type BaseTextFieldProps = FieldProps &
20 InputFieldProps<typeof Input> & {
23 lengthLimiters?: boolean;
26 const BaseTextFieldRender: ForwardRefRenderFunction<HTMLInputElement, BaseTextFieldProps> = (
34 labelContainerClassName,
35 lengthLimiters = false,
43 const { onBlur, value } = field;
44 const { error } = useFieldControl({ field, form, meta });
45 const [focused, setFocused] = useState<boolean>(false);
46 const hide = hidden && !isEmptyString(value) && !focused;
47 const pasteLengthLimiter = usePasteLengthLimiter();
48 const maxLengthLimiter = useMaxLengthLimiter();
49 const defaultHiddenValue = '••••••••••••';
54 assistContainerClassName="empty:hidden"
56 inputClassName={clsx('p-0 rounded-none', props.disabled ? 'color-disabled' : 'color-norm', inputClassName)}
57 labelContainerClassName={clsx(
58 'm-0 text-normal text-sm',
59 error ? 'color-danger' : 'color-weak',
60 labelContainerClassName
64 onBlur={pipe(onBlur, () => setFocused(false))}
65 onFocus={pipe(onFocus, () => setFocused(true))}
66 onKeyDown={lengthLimiters && props.maxLength ? maxLengthLimiter(props.maxLength, onKeyDown) : onKeyDown}
67 onPaste={lengthLimiters && props.maxLength ? pasteLengthLimiter(props.maxLength, onPaste) : onPaste}
70 value={hide ? (hiddenValue ?? defaultHiddenValue) : value}
75 export const BaseTextField = forwardRef(BaseTextFieldRender);
77 export type TextFieldProps = FieldBoxProps & BaseTextFieldProps;
79 export const TextFieldRender: ForwardRefRenderFunction<HTMLInputElement, TextFieldProps> = (
80 { actions, actionsContainerClassName, className, icon, ...rest },
86 actionsContainerClassName={actionsContainerClassName}
90 <BaseTextField {...rest} ref={ref} />
95 export const TextField = forwardRef(TextFieldRender);