Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / pass / components / Form / Field / ExtraFieldGroup / ExtraFieldGroup.tsx
blob1cbf1622c16e6e286215e3f2de20388380799c28
1 import { useSelector } from 'react-redux';
3 import type { FormikErrors, FormikProps } from 'formik';
4 import { FieldArray } from 'formik';
6 import { selectExtraFieldLimits } from '@proton/pass/store/selectors';
7 import type { ExtraFieldGroupValues, ExtraFieldType, UnsafeItemExtraField } from '@proton/pass/types';
8 import { autofocusInput } from '@proton/pass/utils/dom/input';
10 import { Field } from '../Field';
11 import { FieldsetCluster } from '../Layout/FieldsetCluster';
12 import { AddExtraFieldDropdown } from './AddExtraFieldDropdown';
13 import { ExtraFieldComponent } from './ExtraField';
15 export type ExtraFieldGroupProps<V extends ExtraFieldGroupValues> = { form: FormikProps<V> };
17 export const createExtraField = <T extends ExtraFieldType>(type: T): UnsafeItemExtraField => {
18     switch (type) {
19         case 'text':
20         case 'hidden':
21             return { type, fieldName: '', data: { content: '' } };
22         case 'totp':
23             return { type, fieldName: '', data: { totpUri: '' } };
24         default:
25             throw new Error('Unsupported field type');
26     }
29 export const ExtraFieldGroup = <T extends ExtraFieldGroupValues>({ form }: ExtraFieldGroupProps<T>) => {
30     const { needsUpgrade } = useSelector(selectExtraFieldLimits);
32     return (
33         <FieldArray
34             name="extraFields"
35             render={(helpers) => {
36                 const addCustomField = (type: ExtraFieldType) => {
37                     helpers.push(createExtraField(type));
38                     autofocusInput(`extraFields[${form.values.extraFields.length}]`);
39                 };
41                 return (
42                     <>
43                         {Boolean(form.values.extraFields.length) && (
44                             <FieldsetCluster>
45                                 {form.values.extraFields.map(({ type }, index) => (
46                                     <Field
47                                         key={index}
48                                         component={ExtraFieldComponent}
49                                         onDelete={() => helpers.remove(index)}
50                                         name={`extraFields[${index}]`}
51                                         type={type}
52                                         /* Formik TS type are wrong for FormikTouched */
53                                         touched={(form.touched.extraFields as unknown as boolean[])?.[index]}
54                                         error={form.errors.extraFields?.[index] as FormikErrors<UnsafeItemExtraField>}
55                                     />
56                                 ))}
57                             </FieldsetCluster>
58                         )}
60                         {!needsUpgrade && <AddExtraFieldDropdown onAdd={addCustomField} />}
61                     </>
62                 );
63             }}
64         />
65     );