@ultraviolet/form 2.0.0-next.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -12
- package/dist/components/CheckboxField/index.js +19 -20
- package/dist/components/CheckboxGroupField/index.js +13 -14
- package/dist/components/DateField/index.js +19 -20
- package/dist/components/Form/index.js +8 -9
- package/dist/components/NumberInputField/index.js +19 -20
- package/dist/components/RadioField/index.js +16 -17
- package/dist/components/RadioGroupField/index.js +14 -15
- package/dist/components/SelectInputField/index.js +46 -48
- package/dist/components/SelectableCardField/index.js +32 -21
- package/dist/components/Submit/index.js +13 -14
- package/dist/components/SubmitErrorAlert/index.js +3 -4
- package/dist/components/TagInputField/index.js +15 -14
- package/dist/components/TextInputField/index.js +50 -49
- package/dist/components/TimeField/index.js +24 -25
- package/dist/components/ToggleField/index.js +16 -17
- package/dist/hooks/useOnFieldChange.js +1 -4
- package/dist/index.d.ts +27 -27
- package/dist/providers/ErrorContext/index.js +4 -5
- package/package.json +10 -9
- package/dist/components/FormSpy/index.js +0 -23
- package/dist/helpers/pickValidators.js +0 -8
- package/dist/hooks/useFormField.js +0 -75
- package/dist/hooks/useValidation.js +0 -25
- package/dist/validators/index.js +0 -21
- package/dist/validators/max.js +0 -6
- package/dist/validators/maxLength.js +0 -6
- package/dist/validators/min.js +0 -6
- package/dist/validators/minLength.js +0 -6
- package/dist/validators/regex.js +0 -6
- package/dist/validators/required.js +0 -6
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://badge.fury.io/js/%40ultraviolet%2Fform)
|
|
4
4
|
|
|
5
5
|
Ultraviolet Form is an extension of Ultraviolet UI including everything to build forms using React.
|
|
6
|
-
It is using [React
|
|
6
|
+
It is using [React Hook Form](https://react-hook-form.com/) under the hood.
|
|
7
7
|
|
|
8
8
|
## Installation
|
|
9
9
|
|
|
@@ -19,11 +19,13 @@ To use the library you need to put a `ThemeProvider` from `@emotion/react` with
|
|
|
19
19
|
import { ThemeProvider } from '@emotion/react'
|
|
20
20
|
import { Form, TextInputField } from '@ultraviolet/form'
|
|
21
21
|
import { theme } from '@ultraviolet/ui'
|
|
22
|
+
import { useForm } from '@ultraviolet/form'
|
|
22
23
|
|
|
23
24
|
export default function App() {
|
|
25
|
+
const methods = useForm()
|
|
24
26
|
return (
|
|
25
27
|
<ThemeProvider theme={theme}>
|
|
26
|
-
<Form>
|
|
28
|
+
<Form methods={methods}>
|
|
27
29
|
<TextInputField name="example" />
|
|
28
30
|
</Form>
|
|
29
31
|
</ThemeProvider>
|
|
@@ -31,16 +33,6 @@ export default function App() {
|
|
|
31
33
|
}
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
## Contribute
|
|
35
|
-
|
|
36
|
-
### Add a validator
|
|
37
|
-
|
|
38
|
-
- Create a file under `src/validators/` folder
|
|
39
|
-
- Export a default function with a type : (arg: unknown) => ValidatorObject
|
|
40
|
-
- Export it into `src/validators/index.ts`
|
|
41
|
-
- Add the key into the `ValidatorProps` type in `src/types.ts`
|
|
42
|
-
- Add tests into `src/validators/__tests__` folder
|
|
43
|
-
|
|
44
36
|
## Documentation
|
|
45
37
|
|
|
46
38
|
Checkout our [documentation website](https://storybook.ultraviolet.scaleway.com/).
|
|
@@ -3,26 +3,25 @@ import { useController } from 'react-hook-form';
|
|
|
3
3
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
4
4
|
import { useErrors } from '../../providers/ErrorContext/index.js';
|
|
5
5
|
|
|
6
|
-
const CheckboxField =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} = _ref;
|
|
6
|
+
const CheckboxField = ({
|
|
7
|
+
name,
|
|
8
|
+
label,
|
|
9
|
+
size,
|
|
10
|
+
progress,
|
|
11
|
+
disabled,
|
|
12
|
+
required,
|
|
13
|
+
className,
|
|
14
|
+
children,
|
|
15
|
+
onChange,
|
|
16
|
+
onBlur,
|
|
17
|
+
onFocus,
|
|
18
|
+
rules,
|
|
19
|
+
helper,
|
|
20
|
+
tooltip,
|
|
21
|
+
'data-testid': dataTestId,
|
|
22
|
+
value,
|
|
23
|
+
shouldUnregister = false
|
|
24
|
+
}) => {
|
|
26
25
|
const {
|
|
27
26
|
getError
|
|
28
27
|
} = useErrors();
|
|
@@ -3,20 +3,19 @@ import { useController } from 'react-hook-form';
|
|
|
3
3
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
4
4
|
import { useErrors } from '../../providers/ErrorContext/index.js';
|
|
5
5
|
|
|
6
|
-
const CheckboxGroupField =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} = _ref;
|
|
6
|
+
const CheckboxGroupField = ({
|
|
7
|
+
legend,
|
|
8
|
+
className,
|
|
9
|
+
helper,
|
|
10
|
+
direction,
|
|
11
|
+
children,
|
|
12
|
+
onChange,
|
|
13
|
+
label = '',
|
|
14
|
+
error: customError,
|
|
15
|
+
name,
|
|
16
|
+
required = false,
|
|
17
|
+
shouldUnregister = false
|
|
18
|
+
}) => {
|
|
20
19
|
const {
|
|
21
20
|
getError
|
|
22
21
|
} = useErrors();
|
|
@@ -7,26 +7,25 @@ import { useErrors } from '../../providers/ErrorContext/index.js';
|
|
|
7
7
|
|
|
8
8
|
const parseDate = value => typeof value === 'string' ? new Date(value) : value;
|
|
9
9
|
const isEmpty = value => typeof value === 'string' ? value === '' : value === undefined;
|
|
10
|
-
const DateField =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} = _ref;
|
|
10
|
+
const DateField = ({
|
|
11
|
+
required,
|
|
12
|
+
name,
|
|
13
|
+
label = '',
|
|
14
|
+
format,
|
|
15
|
+
locale,
|
|
16
|
+
maxDate,
|
|
17
|
+
minDate,
|
|
18
|
+
disabled,
|
|
19
|
+
onChange,
|
|
20
|
+
onBlur,
|
|
21
|
+
onFocus,
|
|
22
|
+
rules,
|
|
23
|
+
autoFocus = false,
|
|
24
|
+
excludeDates,
|
|
25
|
+
selectsRange,
|
|
26
|
+
'data-testid': dataTestId,
|
|
27
|
+
shouldUnregister = false
|
|
28
|
+
}) => {
|
|
30
29
|
const {
|
|
31
30
|
getError
|
|
32
31
|
} = useErrors();
|
|
@@ -6,15 +6,14 @@ import { jsx } from '@emotion/react/jsx-runtime';
|
|
|
6
6
|
import { ErrorProvider } from '../../providers/ErrorContext/index.js';
|
|
7
7
|
|
|
8
8
|
const FormSubmitContext = /*#__PURE__*/React.createContext({});
|
|
9
|
-
const Form =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} = _ref;
|
|
9
|
+
const Form = ({
|
|
10
|
+
children,
|
|
11
|
+
methods: methodsProp,
|
|
12
|
+
initialValues,
|
|
13
|
+
errors,
|
|
14
|
+
onRawSubmit,
|
|
15
|
+
name
|
|
16
|
+
}) => {
|
|
18
17
|
const methodsHook = useForm({
|
|
19
18
|
defaultValues: initialValues,
|
|
20
19
|
mode: 'onChange'
|
|
@@ -3,26 +3,25 @@ import { useController } from 'react-hook-form';
|
|
|
3
3
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
4
4
|
import { useErrors } from '../../providers/ErrorContext/index.js';
|
|
5
5
|
|
|
6
|
-
const NumberInputField =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} = _ref;
|
|
6
|
+
const NumberInputField = ({
|
|
7
|
+
disabled,
|
|
8
|
+
maxValue,
|
|
9
|
+
minValue,
|
|
10
|
+
name,
|
|
11
|
+
onChange,
|
|
12
|
+
onBlur,
|
|
13
|
+
onFocus,
|
|
14
|
+
onMaxCrossed,
|
|
15
|
+
onMinCrossed,
|
|
16
|
+
required,
|
|
17
|
+
size,
|
|
18
|
+
step,
|
|
19
|
+
text,
|
|
20
|
+
rules,
|
|
21
|
+
className,
|
|
22
|
+
label,
|
|
23
|
+
shouldUnregister = false
|
|
24
|
+
}) => {
|
|
26
25
|
const {
|
|
27
26
|
getError
|
|
28
27
|
} = useErrors();
|
|
@@ -3,23 +3,22 @@ import { useController } from 'react-hook-form';
|
|
|
3
3
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
4
4
|
import { useErrors } from '../../providers/ErrorContext/index.js';
|
|
5
5
|
|
|
6
|
-
const RadioField =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
} = _ref;
|
|
6
|
+
const RadioField = ({
|
|
7
|
+
className,
|
|
8
|
+
'data-testid': dataTestId,
|
|
9
|
+
disabled,
|
|
10
|
+
id,
|
|
11
|
+
name,
|
|
12
|
+
onBlur,
|
|
13
|
+
label = '',
|
|
14
|
+
onChange,
|
|
15
|
+
onFocus,
|
|
16
|
+
required,
|
|
17
|
+
value,
|
|
18
|
+
rules,
|
|
19
|
+
tooltip,
|
|
20
|
+
shouldUnregister = false
|
|
21
|
+
}) => {
|
|
23
22
|
const {
|
|
24
23
|
getError
|
|
25
24
|
} = useErrors();
|
|
@@ -3,21 +3,20 @@ import { useController } from 'react-hook-form';
|
|
|
3
3
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
4
4
|
import { useErrors } from '../../providers/ErrorContext/index.js';
|
|
5
5
|
|
|
6
|
-
const RadioGroupField =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} = _ref;
|
|
6
|
+
const RadioGroupField = ({
|
|
7
|
+
className,
|
|
8
|
+
legend = '',
|
|
9
|
+
name,
|
|
10
|
+
onChange,
|
|
11
|
+
required,
|
|
12
|
+
rules,
|
|
13
|
+
children,
|
|
14
|
+
label = '',
|
|
15
|
+
error: customError,
|
|
16
|
+
helper,
|
|
17
|
+
direction,
|
|
18
|
+
shouldUnregister = false
|
|
19
|
+
}) => {
|
|
21
20
|
const {
|
|
22
21
|
getError
|
|
23
22
|
} = useErrors();
|
|
@@ -7,54 +7,51 @@ import { useErrors } from '../../providers/ErrorContext/index.js';
|
|
|
7
7
|
const identity = x => x;
|
|
8
8
|
// const identity = <T,>(x: T) => x
|
|
9
9
|
|
|
10
|
-
const SelectInputField =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const options = useMemo(() => optionsProp || Children.toArray(children).flat().filter(Boolean).map(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
label: labelChild
|
|
56
|
-
};
|
|
57
|
-
}), [optionsProp, children]);
|
|
10
|
+
const SelectInputField = ({
|
|
11
|
+
animation,
|
|
12
|
+
animationDuration,
|
|
13
|
+
animationOnChange,
|
|
14
|
+
children,
|
|
15
|
+
className,
|
|
16
|
+
disabled,
|
|
17
|
+
// error: errorProp,
|
|
18
|
+
format: formatProp = identity,
|
|
19
|
+
// formatOnBlur,
|
|
20
|
+
id,
|
|
21
|
+
inputId,
|
|
22
|
+
isClearable,
|
|
23
|
+
isLoading,
|
|
24
|
+
isSearchable,
|
|
25
|
+
label = '',
|
|
26
|
+
maxLength,
|
|
27
|
+
menuPortalTarget,
|
|
28
|
+
minLength,
|
|
29
|
+
multiple,
|
|
30
|
+
name,
|
|
31
|
+
onBlur,
|
|
32
|
+
onChange,
|
|
33
|
+
onFocus,
|
|
34
|
+
options: optionsProp,
|
|
35
|
+
parse: parseProp = identity,
|
|
36
|
+
placeholder,
|
|
37
|
+
readOnly,
|
|
38
|
+
required,
|
|
39
|
+
rules,
|
|
40
|
+
noTopLabel,
|
|
41
|
+
noOptionsMessage,
|
|
42
|
+
customStyle,
|
|
43
|
+
shouldUnregister = false,
|
|
44
|
+
'data-testid': dataTestId
|
|
45
|
+
}) => {
|
|
46
|
+
const options = useMemo(() => optionsProp || Children.toArray(children).flat().filter(Boolean).map(({
|
|
47
|
+
props: {
|
|
48
|
+
children: labelChild,
|
|
49
|
+
...option
|
|
50
|
+
}
|
|
51
|
+
}) => ({
|
|
52
|
+
...option,
|
|
53
|
+
label: labelChild
|
|
54
|
+
})), [optionsProp, children]);
|
|
58
55
|
const parse = useMemo(() => multiple ? parseProp : option => parseProp(option?.value ?? null, name), [multiple, parseProp, name]);
|
|
59
56
|
const format = useCallback(val => {
|
|
60
57
|
if (multiple) return formatProp(val, name);
|
|
@@ -126,6 +123,7 @@ const SelectInputField = _ref => {
|
|
|
126
123
|
required: required,
|
|
127
124
|
value: format(field.value),
|
|
128
125
|
noOptionsMessage: noOptionsMessage,
|
|
126
|
+
"data-testid": dataTestId,
|
|
129
127
|
children: children
|
|
130
128
|
});
|
|
131
129
|
};
|
|
@@ -2,25 +2,25 @@ import { SelectableCard } from '@ultraviolet/ui';
|
|
|
2
2
|
import { useController } from 'react-hook-form';
|
|
3
3
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
4
4
|
|
|
5
|
-
const SelectableCardField =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
5
|
+
const SelectableCardField = ({
|
|
6
|
+
name,
|
|
7
|
+
value,
|
|
8
|
+
onChange,
|
|
9
|
+
showTick,
|
|
10
|
+
type,
|
|
11
|
+
disabled,
|
|
12
|
+
children,
|
|
13
|
+
className,
|
|
14
|
+
onFocus,
|
|
15
|
+
onBlur,
|
|
16
|
+
required,
|
|
17
|
+
tooltip,
|
|
18
|
+
id,
|
|
19
|
+
label,
|
|
20
|
+
rules,
|
|
21
|
+
shouldUnregister = false,
|
|
22
|
+
'data-testid': dataTestId
|
|
23
|
+
}) => {
|
|
24
24
|
const {
|
|
25
25
|
field,
|
|
26
26
|
fieldState: {
|
|
@@ -34,14 +34,24 @@ const SelectableCardField = _ref => {
|
|
|
34
34
|
...rules
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
|
+
const isChecked = type === 'checkbox' && Array.isArray(field.value) && value ? (field.value ?? []).includes(value) : field.value === value;
|
|
37
38
|
return jsx(SelectableCard, {
|
|
38
39
|
isError: !!error,
|
|
39
40
|
showTick: showTick,
|
|
40
|
-
checked:
|
|
41
|
+
checked: isChecked,
|
|
41
42
|
className: className,
|
|
42
43
|
disabled: disabled,
|
|
43
44
|
onChange: event => {
|
|
44
|
-
|
|
45
|
+
if (type === 'checkbox') {
|
|
46
|
+
const fieldValue = field.value ?? [];
|
|
47
|
+
if (fieldValue?.includes(event.currentTarget.value)) {
|
|
48
|
+
field.onChange(fieldValue?.filter(currentValue => currentValue !== event.currentTarget.value));
|
|
49
|
+
} else {
|
|
50
|
+
field.onChange([...fieldValue, event.currentTarget.value]);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
field.onChange(event);
|
|
54
|
+
}
|
|
45
55
|
onChange?.(event);
|
|
46
56
|
},
|
|
47
57
|
onBlur: event => {
|
|
@@ -57,6 +67,7 @@ const SelectableCardField = _ref => {
|
|
|
57
67
|
label: label,
|
|
58
68
|
value: value ?? '',
|
|
59
69
|
name: field.name,
|
|
70
|
+
"data-testid": dataTestId,
|
|
60
71
|
children: children
|
|
61
72
|
});
|
|
62
73
|
};
|
|
@@ -2,20 +2,19 @@ import { Button } from '@ultraviolet/ui';
|
|
|
2
2
|
import { useFormState } from 'react-hook-form';
|
|
3
3
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
4
4
|
|
|
5
|
-
const Submit =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
} = _ref;
|
|
5
|
+
const Submit = ({
|
|
6
|
+
children,
|
|
7
|
+
className,
|
|
8
|
+
disabled = false,
|
|
9
|
+
icon,
|
|
10
|
+
iconPosition,
|
|
11
|
+
size,
|
|
12
|
+
variant = 'filled',
|
|
13
|
+
sentiment = 'primary',
|
|
14
|
+
tooltip,
|
|
15
|
+
fullWidth,
|
|
16
|
+
onClick
|
|
17
|
+
}) => {
|
|
19
18
|
const {
|
|
20
19
|
isSubmitting,
|
|
21
20
|
isValid
|
|
@@ -2,10 +2,9 @@ import { Alert } from '@ultraviolet/ui';
|
|
|
2
2
|
import { useFormState } from 'react-hook-form';
|
|
3
3
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
4
4
|
|
|
5
|
-
const SubmitErrorAlert =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} = _ref;
|
|
5
|
+
const SubmitErrorAlert = ({
|
|
6
|
+
className
|
|
7
|
+
}) => {
|
|
9
8
|
const {
|
|
10
9
|
errors
|
|
11
10
|
} = useFormState();
|
|
@@ -2,19 +2,19 @@ import { TagInput } from '@ultraviolet/ui';
|
|
|
2
2
|
import { useController } from 'react-hook-form';
|
|
3
3
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
4
4
|
|
|
5
|
-
const TagInputField =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
const TagInputField = ({
|
|
6
|
+
className,
|
|
7
|
+
disabled,
|
|
8
|
+
id,
|
|
9
|
+
name,
|
|
10
|
+
onChange,
|
|
11
|
+
placeholder,
|
|
12
|
+
required,
|
|
13
|
+
rules,
|
|
14
|
+
variant,
|
|
15
|
+
shouldUnregister = false,
|
|
16
|
+
'data-testid': dataTestId
|
|
17
|
+
}) => {
|
|
18
18
|
const {
|
|
19
19
|
field
|
|
20
20
|
} = useController({
|
|
@@ -36,7 +36,8 @@ const TagInputField = _ref => {
|
|
|
36
36
|
},
|
|
37
37
|
placeholder: placeholder,
|
|
38
38
|
variant: variant,
|
|
39
|
-
tags: field.value
|
|
39
|
+
tags: field.value,
|
|
40
|
+
"data-testid": dataTestId
|
|
40
41
|
});
|
|
41
42
|
};
|
|
42
43
|
|