@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.
Files changed (141) hide show
  1. package/Field/FieldBase/index.js +1 -0
  2. package/Field/FieldBase.js.map +2 -2
  3. package/Field/FieldBaseContainer/index.js +1 -1
  4. package/Field/FieldBaseContainer.js.map +2 -2
  5. package/Field/FieldConditional/index.js +7 -3
  6. package/Field/FieldConditional.js.map +2 -2
  7. package/Field/index.js +5 -2
  8. package/Field/index.js.map +2 -2
  9. package/Field/types.d.ts +4 -1
  10. package/Field/utils/index.d.ts +1 -0
  11. package/Field/utils/index.js +18 -1
  12. package/Field/utils/index.js.map +2 -2
  13. package/FieldArray/index.d.ts +1 -0
  14. package/FieldArray/index.js +3 -1
  15. package/FieldArray/index.js.map +2 -2
  16. package/FieldObject/index.d.ts +2 -0
  17. package/FieldObject/index.js +7 -3
  18. package/FieldObject/index.js.map +2 -2
  19. package/Fieldset/types.d.ts +0 -1
  20. package/FormBuilder/index.d.ts +8 -2
  21. package/FormBuilder/index.js +150 -6
  22. package/FormBuilder/index.js.map +3 -3
  23. package/MultiplicityField/add-objects/index.js +3 -1
  24. package/MultiplicityField/add-objects.js.map +2 -2
  25. package/MultiplicityField/index.js +4 -2
  26. package/MultiplicityField/index.js.map +2 -2
  27. package/Questions/QuestionsContext.d.ts +0 -1
  28. package/Questions/Step/StepContext.d.ts +0 -1
  29. package/Questions/Step/types.d.ts +0 -1
  30. package/Questions/types.d.ts +0 -1
  31. package/cjs/Field/FieldBase/index.js +1 -0
  32. package/cjs/Field/FieldBase.js.map +2 -2
  33. package/cjs/Field/FieldBaseContainer/index.js +3 -3
  34. package/cjs/Field/FieldBaseContainer.js.map +3 -3
  35. package/cjs/Field/FieldConditional/index.js +7 -3
  36. package/cjs/Field/FieldConditional.js.map +2 -2
  37. package/cjs/Field/index.js +5 -2
  38. package/cjs/Field/index.js.map +2 -2
  39. package/cjs/Field/types.js.map +1 -1
  40. package/cjs/Field/utils/index.js +18 -0
  41. package/cjs/Field/utils/index.js.map +2 -2
  42. package/cjs/FieldArray/index.js +3 -1
  43. package/cjs/FieldArray/index.js.map +2 -2
  44. package/cjs/FieldObject/index.js +7 -3
  45. package/cjs/FieldObject/index.js.map +2 -2
  46. package/cjs/FormBuilder/index.js +165 -5
  47. package/cjs/FormBuilder/index.js.map +3 -3
  48. package/cjs/MultiplicityField/add-objects/index.js +3 -1
  49. package/cjs/MultiplicityField/add-objects.js.map +2 -2
  50. package/cjs/MultiplicityField/index.js +4 -2
  51. package/cjs/MultiplicityField/index.js.map +2 -2
  52. package/cjs/index.js +11 -155
  53. package/cjs/index.js.map +4 -4
  54. package/cjs/inputs/AutoCompleteInput/__stories__/Multiple/index.js +0 -1
  55. package/cjs/inputs/AutoCompleteInput/__stories__/Multiple.js.map +2 -2
  56. package/cjs/inputs/AutoCompleteInput/index.js +5 -3
  57. package/cjs/inputs/AutoCompleteInput/index.js.map +2 -2
  58. package/cjs/inputs/Checkboxes/index.js +1 -1
  59. package/cjs/inputs/Checkboxes/index.js.map +2 -2
  60. package/cjs/inputs/ImageInput/ImageInput.stories/index.js +4 -4
  61. package/cjs/inputs/ImageInput/ImageInput.stories.js.map +2 -2
  62. package/cjs/inputs/ImageInput/__stories__/MaxSize/index.js +69 -0
  63. package/cjs/inputs/ImageInput/__stories__/MaxSize.js.map +7 -0
  64. package/cjs/inputs/ImageInput/index.js +3 -2
  65. package/cjs/inputs/ImageInput/index.js.map +2 -2
  66. package/cjs/inputs/Input/index.js +18 -5
  67. package/cjs/inputs/Input/index.js.map +3 -3
  68. package/cjs/inputs/Radio/__stories__/Conditional.js.map +2 -2
  69. package/cjs/inputs/Radio/index.js +52 -4
  70. package/cjs/inputs/Radio/index.js.map +2 -2
  71. package/cjs/inputs/inputsScenarios/index.js +0 -1
  72. package/cjs/inputs/inputsScenarios.js.map +2 -2
  73. package/cjs/lazy/index.js +4 -2
  74. package/cjs/lazy.js.map +2 -2
  75. package/cjs/types.js.map +1 -1
  76. package/cjs/validators/utils/file/index.js +1 -1
  77. package/cjs/validators/utils/file.js.map +2 -2
  78. package/index.d.ts +5 -8
  79. package/index.js +9 -152
  80. package/index.js.map +4 -4
  81. package/inputs/AutoCompleteInput/__stories__/Multiple/index.js +0 -1
  82. package/inputs/AutoCompleteInput/__stories__/Multiple.js.map +2 -2
  83. package/inputs/AutoCompleteInput/index.js +5 -3
  84. package/inputs/AutoCompleteInput/index.js.map +2 -2
  85. package/inputs/Checkboxes/index.js +1 -1
  86. package/inputs/Checkboxes/index.js.map +2 -2
  87. package/inputs/ImageInput/ImageInput.stories/index.js +2 -2
  88. package/inputs/ImageInput/ImageInput.stories.d.ts +1 -1
  89. package/inputs/ImageInput/ImageInput.stories.js.map +2 -2
  90. package/inputs/ImageInput/__stories__/MaxSize/index.js +36 -0
  91. package/inputs/ImageInput/__stories__/MaxSize/package.json +6 -0
  92. package/inputs/ImageInput/__stories__/MaxSize.d.ts +3 -0
  93. package/inputs/ImageInput/__stories__/MaxSize.js.map +7 -0
  94. package/inputs/ImageInput/index.js +3 -2
  95. package/inputs/ImageInput/index.js.map +2 -2
  96. package/inputs/Input/index.js +16 -3
  97. package/inputs/Input/index.js.map +3 -3
  98. package/inputs/Radio/__stories__/Conditional.js.map +2 -2
  99. package/inputs/Radio/index.d.ts +4 -0
  100. package/inputs/Radio/index.js +51 -4
  101. package/inputs/Radio/index.js.map +2 -2
  102. package/inputs/inputsScenarios/index.js +0 -1
  103. package/inputs/inputsScenarios.d.ts +0 -42
  104. package/inputs/inputsScenarios.js.map +2 -2
  105. package/lazy/index.js +4 -2
  106. package/lazy.d.ts +13 -8
  107. package/lazy.js.map +2 -2
  108. package/package.json +4 -4
  109. package/src/Field/FieldBase.tsx +1 -0
  110. package/src/Field/FieldBaseContainer.tsx +1 -1
  111. package/src/Field/FieldConditional.tsx +4 -0
  112. package/src/Field/index.tsx +4 -1
  113. package/src/Field/types.tsx +23 -20
  114. package/src/Field/utils/index.ts +18 -1
  115. package/src/FieldArray/index.tsx +6 -3
  116. package/src/FieldObject/index.tsx +6 -0
  117. package/src/FormBuilder/index.tsx +179 -7
  118. package/src/FormBuilder/scenarios.test.tsx +2 -2
  119. package/src/MultiplicityField/add-objects.tsx +2 -0
  120. package/src/MultiplicityField/index.tsx +2 -0
  121. package/src/index.ts +6 -0
  122. package/src/inputs/AutoCompleteInput/__stories__/Multiple.tsx +0 -1
  123. package/src/inputs/AutoCompleteInput/index.tsx +6 -4
  124. package/src/inputs/Checkboxes/index.test.tsx +16 -17
  125. package/src/inputs/Checkboxes/index.tsx +22 -22
  126. package/src/inputs/ImageInput/ImageInput.stories.js +2 -1
  127. package/src/inputs/ImageInput/__stories__/MaxSize.tsx +37 -0
  128. package/src/inputs/ImageInput/index.test.tsx +4 -0
  129. package/src/inputs/ImageInput/index.tsx +3 -3
  130. package/src/inputs/Input/index.tsx +24 -29
  131. package/src/inputs/Radio/__stories__/Conditional.tsx +2 -1
  132. package/src/inputs/Radio/index.tsx +69 -5
  133. package/src/inputs/inputsScenarios.ts +147 -148
  134. package/src/lazy.js +4 -2
  135. package/src/types.tsx +1 -0
  136. package/src/validators/utils/file.ts +1 -1
  137. package/types.d.ts +1 -1
  138. package/types.js.map +1 -1
  139. package/validators/utils/file/index.js +1 -1
  140. package/validators/utils/file.js.map +2 -2
  141. package/src/index.tsx +0 -178
@@ -1,8 +1,180 @@
1
- import {
2
- FormBuilder,
3
- useFormContext,
4
- useFormValues,
5
- FormBase,
6
- } from '@digigov/form';
7
- export { useFormContext, useFormValues, FormBase };
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.file_size,
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;
@@ -20,7 +20,6 @@ const fields: FieldSpec[] = [
20
20
  type: 'choice:multiple',
21
21
  extra: {
22
22
  component: 'AutoComplete',
23
- multiple: true,
24
23
  options: results.map((r) => {
25
24
  return {
26
25
  label: {
@@ -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
- extra: { options, multiple },
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
- </div>
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
- <div>
11
- <TestVariant title="Conditional">
12
- <Conditional />
13
- </TestVariant>
14
- <TestVariant title="Default">
15
- <Default />
16
- </TestVariant>
17
- <TestVariant title="WithDivider">
18
- <WithDivider />
19
- </TestVariant>
20
- </div>
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
- fieldComponent: Field,
26
+ Field,
27
27
  ...props
28
28
  }) => {
29
29
  if (!value) value = [];
30
30
  const handleChange =
31
31
  (optionValue, idx, show) =>
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
- }
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
- // 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
- };
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')}:</b> {`${selectedImage?.name}`}
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
- {currentValue === undefined ||
61
- (currentValue?.length >= 0 &&
62
- currentValue?.length <= limit?.max) ? (
63
- <span>
64
- {t('form.info.text.you_have')}{' '}
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
+ &nbsp;{`${Math.abs(getRemainingChars(currentValue, limit))}`}&nbsp;
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, FieldSpec } from '@digigov/form';
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[] = [