@digigov/form 2.0.0-d57821ba → 2.0.0-daaf7bdf
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/Field/FieldBase/index.js +1 -0
- package/Field/FieldBase.js.map +2 -2
- package/Field/FieldBaseContainer/index.js +1 -1
- package/Field/FieldBaseContainer.js.map +2 -2
- package/Field/FieldConditional/index.js +7 -3
- package/Field/FieldConditional.js.map +2 -2
- package/Field/index.js +5 -2
- package/Field/index.js.map +2 -2
- package/Field/types.d.ts +4 -1
- package/Field/utils/index.d.ts +1 -0
- package/Field/utils/index.js +18 -1
- package/Field/utils/index.js.map +2 -2
- package/FieldArray/index.d.ts +1 -0
- package/FieldArray/index.js +3 -1
- package/FieldArray/index.js.map +2 -2
- package/FieldObject/index.d.ts +2 -0
- package/FieldObject/index.js +7 -3
- package/FieldObject/index.js.map +2 -2
- package/Fieldset/types.d.ts +0 -1
- package/FormBuilder/index.d.ts +8 -2
- package/FormBuilder/index.js +150 -6
- package/FormBuilder/index.js.map +3 -3
- package/MultiplicityField/add-objects/index.js +3 -1
- package/MultiplicityField/add-objects.js.map +2 -2
- package/MultiplicityField/index.js +4 -2
- package/MultiplicityField/index.js.map +2 -2
- package/Questions/QuestionsContext.d.ts +0 -1
- package/Questions/Step/StepContext.d.ts +0 -1
- package/Questions/Step/types.d.ts +0 -1
- package/Questions/types.d.ts +0 -1
- package/cjs/Field/FieldBase/index.js +1 -0
- package/cjs/Field/FieldBase.js.map +2 -2
- package/cjs/Field/FieldBaseContainer/index.js +3 -3
- package/cjs/Field/FieldBaseContainer.js.map +3 -3
- package/cjs/Field/FieldConditional/index.js +7 -3
- package/cjs/Field/FieldConditional.js.map +2 -2
- package/cjs/Field/index.js +5 -2
- package/cjs/Field/index.js.map +2 -2
- package/cjs/Field/types.js.map +1 -1
- package/cjs/Field/utils/index.js +18 -0
- package/cjs/Field/utils/index.js.map +2 -2
- package/cjs/FieldArray/index.js +3 -1
- package/cjs/FieldArray/index.js.map +2 -2
- package/cjs/FieldObject/index.js +7 -3
- package/cjs/FieldObject/index.js.map +2 -2
- package/cjs/FormBuilder/index.js +165 -5
- package/cjs/FormBuilder/index.js.map +3 -3
- package/cjs/MultiplicityField/add-objects/index.js +3 -1
- package/cjs/MultiplicityField/add-objects.js.map +2 -2
- package/cjs/MultiplicityField/index.js +4 -2
- package/cjs/MultiplicityField/index.js.map +2 -2
- package/cjs/index.js +11 -155
- package/cjs/index.js.map +4 -4
- package/cjs/inputs/AutoCompleteInput/__stories__/Multiple/index.js +0 -1
- package/cjs/inputs/AutoCompleteInput/__stories__/Multiple.js.map +2 -2
- package/cjs/inputs/AutoCompleteInput/index.js +5 -3
- package/cjs/inputs/AutoCompleteInput/index.js.map +2 -2
- package/cjs/inputs/Checkboxes/index.js +1 -1
- package/cjs/inputs/Checkboxes/index.js.map +2 -2
- package/cjs/inputs/ImageInput/ImageInput.stories/index.js +4 -4
- package/cjs/inputs/ImageInput/ImageInput.stories.js.map +2 -2
- package/cjs/inputs/ImageInput/__stories__/MaxSize/index.js +69 -0
- package/cjs/inputs/ImageInput/__stories__/MaxSize.js.map +7 -0
- package/cjs/inputs/ImageInput/index.js +3 -2
- package/cjs/inputs/ImageInput/index.js.map +2 -2
- package/cjs/inputs/Input/index.js +18 -5
- package/cjs/inputs/Input/index.js.map +3 -3
- package/cjs/inputs/Radio/__stories__/Conditional.js.map +2 -2
- package/cjs/inputs/Radio/index.js +52 -4
- package/cjs/inputs/Radio/index.js.map +2 -2
- package/cjs/inputs/inputsScenarios/index.js +0 -1
- package/cjs/inputs/inputsScenarios.js.map +2 -2
- package/cjs/lazy/index.js +4 -2
- package/cjs/lazy.js.map +2 -2
- package/cjs/types.js.map +1 -1
- package/cjs/validators/utils/file/index.js +1 -1
- package/cjs/validators/utils/file.js.map +2 -2
- package/index.d.ts +5 -8
- package/index.js +9 -152
- package/index.js.map +4 -4
- package/inputs/AutoCompleteInput/__stories__/Multiple/index.js +0 -1
- package/inputs/AutoCompleteInput/__stories__/Multiple.js.map +2 -2
- package/inputs/AutoCompleteInput/index.js +5 -3
- package/inputs/AutoCompleteInput/index.js.map +2 -2
- package/inputs/Checkboxes/index.js +1 -1
- package/inputs/Checkboxes/index.js.map +2 -2
- package/inputs/ImageInput/ImageInput.stories/index.js +2 -2
- package/inputs/ImageInput/ImageInput.stories.d.ts +1 -1
- package/inputs/ImageInput/ImageInput.stories.js.map +2 -2
- package/inputs/ImageInput/__stories__/MaxSize/index.js +36 -0
- package/inputs/ImageInput/__stories__/MaxSize/package.json +6 -0
- package/inputs/ImageInput/__stories__/MaxSize.d.ts +3 -0
- package/inputs/ImageInput/__stories__/MaxSize.js.map +7 -0
- package/inputs/ImageInput/index.js +3 -2
- package/inputs/ImageInput/index.js.map +2 -2
- package/inputs/Input/index.js +16 -3
- package/inputs/Input/index.js.map +3 -3
- package/inputs/Radio/__stories__/Conditional.js.map +2 -2
- package/inputs/Radio/index.d.ts +4 -0
- package/inputs/Radio/index.js +51 -4
- package/inputs/Radio/index.js.map +2 -2
- package/inputs/inputsScenarios/index.js +0 -1
- package/inputs/inputsScenarios.d.ts +0 -42
- package/inputs/inputsScenarios.js.map +2 -2
- package/lazy/index.js +4 -2
- package/lazy.d.ts +13 -8
- package/lazy.js.map +2 -2
- package/package.json +4 -4
- package/src/Field/FieldBase.tsx +1 -0
- package/src/Field/FieldBaseContainer.tsx +1 -1
- package/src/Field/FieldConditional.tsx +4 -0
- package/src/Field/index.tsx +4 -1
- package/src/Field/types.tsx +23 -20
- package/src/Field/utils/index.ts +18 -1
- package/src/FieldArray/index.tsx +6 -3
- package/src/FieldObject/index.tsx +6 -0
- package/src/FormBuilder/index.tsx +179 -7
- package/src/FormBuilder/scenarios.test.tsx +2 -2
- package/src/MultiplicityField/add-objects.tsx +2 -0
- package/src/MultiplicityField/index.tsx +2 -0
- package/src/index.ts +6 -0
- package/src/inputs/AutoCompleteInput/__stories__/Multiple.tsx +0 -1
- package/src/inputs/AutoCompleteInput/index.tsx +6 -4
- package/src/inputs/Checkboxes/index.test.tsx +16 -17
- package/src/inputs/Checkboxes/index.tsx +22 -22
- package/src/inputs/ImageInput/ImageInput.stories.js +2 -1
- package/src/inputs/ImageInput/__stories__/MaxSize.tsx +37 -0
- package/src/inputs/ImageInput/index.test.tsx +4 -0
- package/src/inputs/ImageInput/index.tsx +3 -3
- package/src/inputs/Input/index.tsx +24 -29
- package/src/inputs/Radio/__stories__/Conditional.tsx +2 -1
- package/src/inputs/Radio/index.tsx +69 -5
- package/src/inputs/inputsScenarios.ts +147 -148
- package/src/lazy.js +4 -2
- package/src/types.tsx +1 -0
- package/src/validators/utils/file.ts +1 -1
- package/types.d.ts +1 -1
- package/types.js.map +1 -1
- package/validators/utils/file/index.js +1 -1
- package/validators/utils/file.js.map +2 -2
- package/src/index.tsx +0 -178
|
@@ -1,8 +1,180 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import React, { useCallback, useContext, useRef } from 'react';
|
|
3
|
+
import { useForm } from 'react-hook-form';
|
|
4
|
+
import Field from '@digigov/form/Field';
|
|
5
|
+
import { CONTROLLED_FIELD_COMPONENTS } from '@digigov/form/Field/utils';
|
|
6
|
+
import Fieldset from '@digigov/form/Fieldset';
|
|
7
|
+
import { FormContext } from '@digigov/form/FormContext';
|
|
8
|
+
import { FormBaseProps, FormData, FormBuilderProps } from '@digigov/form/types';
|
|
9
|
+
import { yupResolver } from '@digigov/form/utils';
|
|
10
|
+
import { useValidationSchema } from '@digigov/form/validators';
|
|
11
|
+
import { Form } from '@digigov/react-core/Form';
|
|
12
|
+
import { Button } from '@digigov/ui/form/Button';
|
|
13
|
+
|
|
14
|
+
const FormBase = React.forwardRef(function FormBase(
|
|
15
|
+
{
|
|
16
|
+
onSubmit,
|
|
17
|
+
children,
|
|
18
|
+
registerField,
|
|
19
|
+
fieldsMap,
|
|
20
|
+
fieldsetsMap,
|
|
21
|
+
resolver,
|
|
22
|
+
mode,
|
|
23
|
+
initial,
|
|
24
|
+
reValidateMode,
|
|
25
|
+
shouldFocusError,
|
|
26
|
+
criteriaMode,
|
|
27
|
+
componentRegistry,
|
|
28
|
+
grid,
|
|
29
|
+
...props
|
|
30
|
+
}: FormBaseProps,
|
|
31
|
+
ref: React.Ref<HTMLFormElement>
|
|
32
|
+
) {
|
|
33
|
+
const form = useForm({
|
|
34
|
+
resolver,
|
|
35
|
+
mode,
|
|
36
|
+
defaultValues: initial,
|
|
37
|
+
reValidateMode,
|
|
38
|
+
shouldFocusError,
|
|
39
|
+
criteriaMode,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const handleSubmit = useCallback(
|
|
43
|
+
(data: FormData): void => {
|
|
44
|
+
onSubmit && onSubmit(data);
|
|
45
|
+
},
|
|
46
|
+
[onSubmit]
|
|
47
|
+
);
|
|
48
|
+
const submit = form.handleSubmit(handleSubmit);
|
|
49
|
+
const ctx = {
|
|
50
|
+
fieldsMap,
|
|
51
|
+
fieldsetsMap,
|
|
52
|
+
control: form.control,
|
|
53
|
+
register: form.register,
|
|
54
|
+
watch: form.watch,
|
|
55
|
+
resetField: form.resetField,
|
|
56
|
+
registerField: registerField,
|
|
57
|
+
errors: form.formState.errors,
|
|
58
|
+
formState: form.formState,
|
|
59
|
+
reset: form.reset,
|
|
60
|
+
trigger: form.trigger,
|
|
61
|
+
getFieldState: form.getFieldState,
|
|
62
|
+
setValue: form.setValue,
|
|
63
|
+
clearErrors: form.clearErrors,
|
|
64
|
+
getValues: form.getValues,
|
|
65
|
+
unregister: form.unregister,
|
|
66
|
+
componentRegistry,
|
|
67
|
+
setError: form.setError,
|
|
68
|
+
formRef: ref,
|
|
69
|
+
submit,
|
|
70
|
+
};
|
|
71
|
+
return (
|
|
72
|
+
<FormContext.Provider value={ctx}>
|
|
73
|
+
<Form grid={grid} onSubmit={submit} ref={ref} {...props}>
|
|
74
|
+
{children}
|
|
75
|
+
</Form>
|
|
76
|
+
</FormContext.Provider>
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const useFormContext = () => {
|
|
81
|
+
return useContext(FormContext);
|
|
82
|
+
};
|
|
83
|
+
const useFormValues = () => {
|
|
84
|
+
const ctx = useFormContext();
|
|
85
|
+
return ctx.getValues();
|
|
86
|
+
};
|
|
87
|
+
const FormBuilder = React.forwardRef(function FormBuilder(
|
|
88
|
+
{
|
|
89
|
+
fields = [],
|
|
90
|
+
fieldsets,
|
|
91
|
+
initial = {},
|
|
92
|
+
onSubmit,
|
|
93
|
+
children,
|
|
94
|
+
reValidateMode = 'onSubmit',
|
|
95
|
+
mode = 'onSubmit',
|
|
96
|
+
shouldFocusError = true,
|
|
97
|
+
criteriaMode = 'all',
|
|
98
|
+
auto = false,
|
|
99
|
+
validatorRegistry,
|
|
100
|
+
componentRegistry,
|
|
101
|
+
grid = false,
|
|
102
|
+
...props
|
|
103
|
+
}: FormBuilderProps,
|
|
104
|
+
ref: React.Ref<HTMLFormElement>
|
|
105
|
+
): React.ReactElement {
|
|
106
|
+
const fieldsState = useRef(fields);
|
|
107
|
+
const setFieldsState = useCallback((newFields) => {
|
|
108
|
+
fieldsState.current = newFields;
|
|
109
|
+
}, []);
|
|
110
|
+
const schema = useValidationSchema(fieldsState, validatorRegistry);
|
|
111
|
+
const registerField = useCallback((field) => {
|
|
112
|
+
const fieldIndex = fieldsState.current.findIndex(
|
|
113
|
+
(f) => f.key === field.key
|
|
114
|
+
);
|
|
115
|
+
if (fieldIndex > -1) {
|
|
116
|
+
fieldsState.current[fieldIndex] = field;
|
|
117
|
+
} else {
|
|
118
|
+
fieldsState.current.push(field);
|
|
119
|
+
}
|
|
120
|
+
setFieldsState(fieldsState.current);
|
|
121
|
+
}, []);
|
|
122
|
+
let resolver;
|
|
123
|
+
let fieldsMap;
|
|
124
|
+
let fieldsetsMap;
|
|
125
|
+
let fieldChildren;
|
|
126
|
+
if (schema) {
|
|
127
|
+
resolver = yupResolver(schema);
|
|
128
|
+
fieldsMap = fields
|
|
129
|
+
? fields.reduce((map, field) => ({ ...map, [field.key]: field }), {})
|
|
130
|
+
: {};
|
|
131
|
+
fieldsetsMap =
|
|
132
|
+
fieldsets &&
|
|
133
|
+
fieldsets.reduce(
|
|
134
|
+
(map, fieldset) => ({ ...map, [fieldset.key]: fieldset }),
|
|
135
|
+
{}
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (auto) {
|
|
139
|
+
if (fieldsets) {
|
|
140
|
+
fieldChildren = fieldsets.map((fieldset) => (
|
|
141
|
+
<Fieldset key={fieldset.key} />
|
|
142
|
+
));
|
|
143
|
+
} else if (fields) {
|
|
144
|
+
fieldChildren = fields.map((field) => (
|
|
145
|
+
<Field key={field.key} name={field.key} />
|
|
146
|
+
));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return (
|
|
151
|
+
<FormBase
|
|
152
|
+
resolver={resolver}
|
|
153
|
+
fieldsetsMap={fieldsetsMap}
|
|
154
|
+
fieldsMap={fieldsMap}
|
|
155
|
+
registerField={registerField}
|
|
156
|
+
initial={initial}
|
|
157
|
+
reValidateMode={reValidateMode}
|
|
158
|
+
mode={mode}
|
|
159
|
+
shouldFocusError={shouldFocusError}
|
|
160
|
+
criteriaMode={criteriaMode}
|
|
161
|
+
onSubmit={onSubmit}
|
|
162
|
+
componentRegistry={componentRegistry}
|
|
163
|
+
ref={ref}
|
|
164
|
+
grid={grid}
|
|
165
|
+
{...props}
|
|
166
|
+
>
|
|
167
|
+
{fieldChildren}
|
|
168
|
+
{auto && <Button type="submit">Συνέχεια</Button>}
|
|
169
|
+
{children}
|
|
170
|
+
</FormBase>
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
export const ControlledFormBuilder = (props) => {
|
|
174
|
+
return (
|
|
175
|
+
<FormBuilder {...props} componentRegistry={CONTROLLED_FIELD_COMPONENTS} />
|
|
176
|
+
);
|
|
177
|
+
};
|
|
8
178
|
export default FormBuilder;
|
|
179
|
+
|
|
180
|
+
export { useFormContext, useFormValues, FormBase };
|
|
@@ -1120,7 +1120,7 @@ const inputsScenarios = [
|
|
|
1120
1120
|
args: {
|
|
1121
1121
|
maxSizeToMb: 0.0003,
|
|
1122
1122
|
},
|
|
1123
|
-
text: el.form.error.
|
|
1123
|
+
text: el.form.error.image_size,
|
|
1124
1124
|
},
|
|
1125
1125
|
{
|
|
1126
1126
|
type: 'error',
|
|
@@ -1847,7 +1847,7 @@ for (const scenario of scenarios) {
|
|
|
1847
1847
|
test(scenario.title, async ({ mount, page }) => {
|
|
1848
1848
|
const formBuilder = await mount(
|
|
1849
1849
|
// @ts-ignore
|
|
1850
|
-
<FormBuilder auto={true} fields={scenario.fields} onSubmit={() => {}} />
|
|
1850
|
+
<FormBuilder auto={true} fields={scenario.fields} onSubmit={() => { }} />
|
|
1851
1851
|
);
|
|
1852
1852
|
await fillFields(page, formBuilder, scenario);
|
|
1853
1853
|
await submitForm(formBuilder);
|
|
@@ -51,6 +51,7 @@ export const AddObjects: React.FC<AddObjectsProps> = ({
|
|
|
51
51
|
getValues,
|
|
52
52
|
onStash,
|
|
53
53
|
error,
|
|
54
|
+
Field
|
|
54
55
|
}) => {
|
|
55
56
|
const currentIndex = fields.length > 0 ? fields.length - 1 : fields.length;
|
|
56
57
|
const currentName = `${name}.${currentIndex}`;
|
|
@@ -186,6 +187,7 @@ export const AddObjects: React.FC<AddObjectsProps> = ({
|
|
|
186
187
|
control={control}
|
|
187
188
|
register={register}
|
|
188
189
|
reset={reset}
|
|
190
|
+
Field={Field}
|
|
189
191
|
error={
|
|
190
192
|
extra?.max - stashedObjects.length === 0 ||
|
|
191
193
|
extra?.length - stashedObjects.length === 0
|
|
@@ -30,6 +30,7 @@ export const Multiplicity: React.FC<MultiplicityProps> = ({
|
|
|
30
30
|
setValue,
|
|
31
31
|
getValues,
|
|
32
32
|
unregister,
|
|
33
|
+
Field,
|
|
33
34
|
}) => {
|
|
34
35
|
const { fields, append, remove } = useFieldArray({
|
|
35
36
|
control,
|
|
@@ -96,6 +97,7 @@ export const Multiplicity: React.FC<MultiplicityProps> = ({
|
|
|
96
97
|
unregister={unregister}
|
|
97
98
|
trigger={trigger}
|
|
98
99
|
clearErrors={clearErrors}
|
|
100
|
+
Field={Field}
|
|
99
101
|
/>
|
|
100
102
|
</FieldContainer>
|
|
101
103
|
);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as Field } from '@digigov/form/Field';
|
|
2
|
+
export { default as Fieldset } from '@digigov/form/Fieldset';
|
|
3
|
+
export * from '@digigov/form/inputs/Label';
|
|
4
|
+
import FormBuilder from '@digigov/form/FormBuilder';
|
|
5
|
+
export * from '@digigov/form/types';
|
|
6
|
+
export default FormBuilder;
|
|
@@ -5,6 +5,7 @@ import { Hint } from '@digigov/react-core/Hint';
|
|
|
5
5
|
import UIAutoComplete, {
|
|
6
6
|
AutoCompleteProps as UIAutoCompleteProps,
|
|
7
7
|
} from '@digigov/ui/form/AutoComplete';
|
|
8
|
+
import { Base } from '@digigov/react-core/Base';
|
|
8
9
|
|
|
9
10
|
export interface AutoCompleteInputExtra
|
|
10
11
|
extends Omit<
|
|
@@ -28,7 +29,8 @@ export interface AutoCompleteInputProps
|
|
|
28
29
|
|
|
29
30
|
export const AutoCompleteInput: React.FC<AutoCompleteInputProps> = ({
|
|
30
31
|
name,
|
|
31
|
-
|
|
32
|
+
type,
|
|
33
|
+
extra: { options },
|
|
32
34
|
onChange,
|
|
33
35
|
value,
|
|
34
36
|
error,
|
|
@@ -55,7 +57,7 @@ export const AutoCompleteInput: React.FC<AutoCompleteInputProps> = ({
|
|
|
55
57
|
|
|
56
58
|
return (
|
|
57
59
|
<UIAutoComplete
|
|
58
|
-
multiple={multiple}
|
|
60
|
+
multiple={type === 'choice:multiple' ? true : false}
|
|
59
61
|
source={suggest}
|
|
60
62
|
onConfirm={(value) => {
|
|
61
63
|
if (Array.isArray(value)) {
|
|
@@ -68,10 +70,10 @@ export const AutoCompleteInput: React.FC<AutoCompleteInputProps> = ({
|
|
|
68
70
|
templates={{
|
|
69
71
|
suggestion({ label, value }) {
|
|
70
72
|
return (
|
|
71
|
-
<div>
|
|
73
|
+
<Base as="div">
|
|
72
74
|
{(label && label.primary && label.primary) || value}
|
|
73
75
|
{label && label.secondary && <Hint>{label.secondary}</Hint>}
|
|
74
|
-
</
|
|
76
|
+
</Base>
|
|
75
77
|
);
|
|
76
78
|
},
|
|
77
79
|
inputValue: (option) => {
|
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { test, expect } from '@playwright/experimental-ct-react';
|
|
3
|
+
import TestVariant from '@digigov/ui/utils/TestVariant'
|
|
3
4
|
import { Conditional } from '@digigov/form/inputs/Checkboxes/__stories__/Conditional';
|
|
4
5
|
import { Default } from '@digigov/form/inputs/Checkboxes/__stories__/Default';
|
|
5
6
|
import { WithDivider } from '@digigov/form/inputs/Checkboxes/__stories__/WithDivider';
|
|
6
|
-
import TestVariant from '@digigov/ui/utils/TestVariant';
|
|
7
7
|
|
|
8
8
|
test('renders the All Checkboxes variants', async ({ mount, page }) => {
|
|
9
9
|
await mount(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
</
|
|
21
|
-
|
|
10
|
+
|
|
11
|
+
<div>
|
|
12
|
+
<TestVariant title="Conditional">
|
|
13
|
+
<Conditional />
|
|
14
|
+
</TestVariant>
|
|
15
|
+
<TestVariant title="Default">
|
|
16
|
+
<Default />
|
|
17
|
+
</TestVariant>
|
|
18
|
+
<TestVariant title="WithDivider">
|
|
19
|
+
<WithDivider />
|
|
20
|
+
</TestVariant>
|
|
21
|
+
</div>
|
|
22
|
+
)
|
|
22
23
|
await page.evaluate(() => document.fonts.ready);
|
|
23
24
|
|
|
24
|
-
const screenshot = await page.screenshot({
|
|
25
|
-
fullPage: true,
|
|
26
|
-
animations: 'disabled',
|
|
27
|
-
});
|
|
25
|
+
const screenshot = await page.screenshot({ fullPage: true, animations: 'disabled' });
|
|
28
26
|
expect(screenshot).toMatchSnapshot();
|
|
29
27
|
});
|
|
28
|
+
|
|
@@ -23,34 +23,34 @@ export const Checkboxes: React.FC<CheckboxesProps> = ({
|
|
|
23
23
|
value,
|
|
24
24
|
extra: { options, className },
|
|
25
25
|
disabled,
|
|
26
|
-
|
|
26
|
+
Field,
|
|
27
27
|
...props
|
|
28
28
|
}) => {
|
|
29
29
|
if (!value) value = [];
|
|
30
30
|
const handleChange =
|
|
31
31
|
(optionValue, idx, show) =>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
32
|
+
(evt): void => {
|
|
33
|
+
let newValue;
|
|
34
|
+
if (evt.currentTarget.checked) {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
newValue = value.concat([optionValue]);
|
|
38
|
+
} else {
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
newValue = value.filter((val) => val !== optionValue);
|
|
42
|
+
}
|
|
43
|
+
if (show && show.length > 0) {
|
|
44
|
+
setChecked((items) =>
|
|
45
|
+
items.map((item, index) => (index === idx ? !item : item))
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
// reset value to undefined instead of an empty array
|
|
50
|
+
// so the error state mechanism can throw validation errors
|
|
51
|
+
if (newValue.length === 0) newValue = undefined;
|
|
52
|
+
onChange(newValue);
|
|
53
|
+
};
|
|
54
54
|
const { t } = useTranslation();
|
|
55
55
|
const [checked, setChecked] = useState(
|
|
56
56
|
Array<boolean>(options.length).fill(false)
|
|
@@ -5,5 +5,6 @@ export default {
|
|
|
5
5
|
displayName: 'ImageInput',
|
|
6
6
|
};
|
|
7
7
|
export { Default } from '@digigov/form/inputs/ImageInput/__stories__/Default';
|
|
8
|
-
export { WithInvalidImageSize } from '@digigov/form/inputs/ImageInput/__stories__/WithInvalidImageSize';
|
|
9
8
|
export { WithInvalidImageDimension } from '@digigov/form/inputs/ImageInput/__stories__/WithInvalidImageDimension';
|
|
9
|
+
export { MaxSize } from '@digigov/form/inputs/ImageInput/__stories__/MaxSize';
|
|
10
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import FormBuilder, { Field, Fieldset } from '@digigov/form';
|
|
3
|
+
import { FieldSpec } from '@digigov/form/types';
|
|
4
|
+
import { Button } from '@digigov/ui/form/Button';
|
|
5
|
+
const FIELDS: FieldSpec[] = [
|
|
6
|
+
{
|
|
7
|
+
key: 'image',
|
|
8
|
+
type: 'image',
|
|
9
|
+
required: true,
|
|
10
|
+
label: {
|
|
11
|
+
primary: 'Ανέβασμα φωτογραφίας',
|
|
12
|
+
secondary: 'Μέγιστο μέγεθος φωτογραφίας: 10KB.',
|
|
13
|
+
},
|
|
14
|
+
extra: {
|
|
15
|
+
limit: {
|
|
16
|
+
maxSize: 1000,
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export const MaxSize = () => (
|
|
23
|
+
<FormBuilder
|
|
24
|
+
fields={FIELDS}
|
|
25
|
+
onSubmit={(data) => {
|
|
26
|
+
console.log(data);
|
|
27
|
+
}}
|
|
28
|
+
>
|
|
29
|
+
<Fieldset>
|
|
30
|
+
{FIELDS.map((field) => (
|
|
31
|
+
<Field key={field.key} name={field.key} />
|
|
32
|
+
))}
|
|
33
|
+
</Fieldset>
|
|
34
|
+
<Button type="submit">Συνέχεια</Button>
|
|
35
|
+
</FormBuilder>
|
|
36
|
+
);
|
|
37
|
+
export default MaxSize;
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { test, expect } from '@playwright/experimental-ct-react';
|
|
3
3
|
import TestVariant from '@digigov/ui/utils/TestVariant'
|
|
4
4
|
import { Default } from '@digigov/form/inputs/ImageInput/__stories__/Default';
|
|
5
|
+
import { MaxSize } from '@digigov/form/inputs/ImageInput/__stories__/MaxSize';
|
|
5
6
|
import { WithInvalidImageDimension } from '@digigov/form/inputs/ImageInput/__stories__/WithInvalidImageDimension';
|
|
6
7
|
import { WithInvalidImageSize } from '@digigov/form/inputs/ImageInput/__stories__/WithInvalidImageSize';
|
|
7
8
|
|
|
@@ -12,6 +13,9 @@ test('renders the All ImageInput variants', async ({ mount, page }) => {
|
|
|
12
13
|
<TestVariant title="Default">
|
|
13
14
|
<Default />
|
|
14
15
|
</TestVariant>
|
|
16
|
+
<TestVariant title="MaxSize">
|
|
17
|
+
<MaxSize />
|
|
18
|
+
</TestVariant>
|
|
15
19
|
<TestVariant title="WithInvalidImageDimension">
|
|
16
20
|
<WithInvalidImageDimension />
|
|
17
21
|
</TestVariant>
|
|
@@ -6,7 +6,7 @@ import CoreHint from '@digigov/react-core/Hint';
|
|
|
6
6
|
import Button, { ButtonGroup } from '@digigov/ui/form/Button';
|
|
7
7
|
import { useTranslation } from '@digigov/ui/i18n';
|
|
8
8
|
import Paragraph from '@digigov/ui/typography/Paragraph';
|
|
9
|
-
|
|
9
|
+
import { Base } from '@digigov/react-core/Base';
|
|
10
10
|
export interface ImageProps {
|
|
11
11
|
src?: any;
|
|
12
12
|
}
|
|
@@ -20,7 +20,7 @@ export interface Limit {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const Image: React.FC<ImageProps> = React.memo(function Image({ src }) {
|
|
23
|
-
return <img src={src} className="ds-image--ratio" />;
|
|
23
|
+
return <Base as='img' src={src} className="ds-image--ratio" />;
|
|
24
24
|
});
|
|
25
25
|
export interface ImageInputProps extends Omit<UncontrolledFieldProps, 'extra'> {
|
|
26
26
|
extra?: {
|
|
@@ -72,7 +72,7 @@ export const ImageInput: React.FC<ImageInputProps> = React.forwardRef(
|
|
|
72
72
|
{selectedImage !== null ? (
|
|
73
73
|
<>
|
|
74
74
|
<Paragraph>
|
|
75
|
-
<b>{t('upload.image')}:</
|
|
75
|
+
<Base as='b'>{t('upload.image')}:</Base> {`${selectedImage?.name}`}
|
|
76
76
|
</Paragraph>
|
|
77
77
|
</>
|
|
78
78
|
) : (
|
|
@@ -2,10 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import { useWatch } from 'react-hook-form';
|
|
3
3
|
import { UncontrolledFieldProps } from '@digigov/form/Field/types';
|
|
4
4
|
import { Hint } from '@digigov/react-core/Hint';
|
|
5
|
-
import TextArea from '@digigov/react-core/TextArea';
|
|
6
|
-
import TextInput from '@digigov/react-core/TextInput';
|
|
5
|
+
import { TextArea } from '@digigov/react-core/TextArea';
|
|
6
|
+
import { TextInput } from '@digigov/react-core/TextInput';
|
|
7
7
|
import { useTranslation } from '@digigov/ui/i18n';
|
|
8
|
-
|
|
9
8
|
const TYPES_MAP = {
|
|
10
9
|
string: 'text',
|
|
11
10
|
int: 'text',
|
|
@@ -40,6 +39,21 @@ export const Input: React.ExoticComponent<InputProps> = React.forwardRef(
|
|
|
40
39
|
const fieldType = TYPES_MAP[type || 'text'] || 'text';
|
|
41
40
|
const { t } = useTranslation();
|
|
42
41
|
const currentValue: string | '' = useWatch({ control, name });
|
|
42
|
+
|
|
43
|
+
const getRemainingChars = (currentValue, limit) => {
|
|
44
|
+
if (currentValue) {
|
|
45
|
+
return limit?.max - currentValue.length
|
|
46
|
+
}
|
|
47
|
+
return limit?.max;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const constructRemainingText = (currentValue, limit) => {
|
|
51
|
+
const remainingChars = getRemainingChars(currentValue, limit);
|
|
52
|
+
let remainingText = Math.abs(remainingChars) === 1 ? t('form.info.text.character') : t('form.info.text.characters');
|
|
53
|
+
remainingText += remainingChars > 0 ? ` ${t('form.info.text.remaining')}.` : ` ${t('form.info.text.too_many')}.`;
|
|
54
|
+
return remainingText;
|
|
55
|
+
}
|
|
56
|
+
|
|
43
57
|
if (multiline === true) {
|
|
44
58
|
return (
|
|
45
59
|
<>
|
|
@@ -56,32 +70,12 @@ export const Input: React.ExoticComponent<InputProps> = React.forwardRef(
|
|
|
56
70
|
}}
|
|
57
71
|
/>
|
|
58
72
|
{limit?.max && (
|
|
59
|
-
<Hint>
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
currentValue
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<b>
|
|
66
|
-
{!currentValue
|
|
67
|
-
? limit.max
|
|
68
|
-
: limit?.max - currentValue?.length}
|
|
69
|
-
</b>{' '}
|
|
70
|
-
{currentValue && limit?.max - currentValue?.length === 1
|
|
71
|
-
? `${t('form.info.text.character')}`
|
|
72
|
-
: `${t('form.info.text.characters')}`}{' '}
|
|
73
|
-
{t('form.info.text.remaining')}.
|
|
74
|
-
</span>
|
|
75
|
-
) : (
|
|
76
|
-
<span style={{ color: '#b60202' }}>
|
|
77
|
-
{t('form.info.text.you_have')}{' '}
|
|
78
|
-
<b>{currentValue && currentValue?.length - limit?.max}</b>{' '}
|
|
79
|
-
{currentValue?.length - limit?.max === 1
|
|
80
|
-
? `${t('form.info.text.character')}`
|
|
81
|
-
: `${t('form.info.text.characters')}`}{' '}
|
|
82
|
-
{t('form.info.text.too_many')}.
|
|
83
|
-
</span>
|
|
84
|
-
)}
|
|
73
|
+
<Hint display={'flex'}>
|
|
74
|
+
{t('form.info.text.you_have')}
|
|
75
|
+
<Hint fontWeight='bold'>
|
|
76
|
+
{`${Math.abs(getRemainingChars(currentValue, limit))}`}
|
|
77
|
+
</Hint>
|
|
78
|
+
{constructRemainingText(currentValue, limit)}
|
|
85
79
|
</Hint>
|
|
86
80
|
)}
|
|
87
81
|
</>
|
|
@@ -91,6 +85,7 @@ export const Input: React.ExoticComponent<InputProps> = React.forwardRef(
|
|
|
91
85
|
<TextInput
|
|
92
86
|
name={name}
|
|
93
87
|
type={fieldType}
|
|
88
|
+
data-type={type}
|
|
94
89
|
className={className}
|
|
95
90
|
ref={ref}
|
|
96
91
|
{...{ ...props, reset: undefined, required: undefined }}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import FormBuilder, { Field
|
|
2
|
+
import FormBuilder, { Field } from '@digigov/form';
|
|
3
|
+
import { FieldSpec } from '@digigov/form/types';
|
|
3
4
|
import { Button } from '@digigov/ui/form/Button';
|
|
4
5
|
|
|
5
6
|
const fields: FieldSpec[] = [
|