@pareto-engineering/design-system 4.9.0 → 4.9.2

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.
@@ -101,6 +101,7 @@ const FileUpload = _ref => {
101
101
  });
102
102
  };
103
103
  const acceptOptions = Array.isArray(accept) ? accept?.join(',') : accept;
104
+ const isAnyFileUploading = Object.values(uploadStatus ?? {})?.map(e => e?.status)?.some(status => status === 'pending');
104
105
  return /*#__PURE__*/React.createElement("div", {
105
106
  id: id,
106
107
  className: [baseClassName, componentClassName, userClassName, `preview-${filePreviewAlignment}`, `y-${color}`].filter(e => e).join(' '),
@@ -119,7 +120,7 @@ const FileUpload = _ref => {
119
120
  type: "file",
120
121
  accept: acceptOptions,
121
122
  multiple: multiple || maxCount && maxCount > 0,
122
- disabled: disabled,
123
+ disabled: disabled || isAnyFileUploading,
123
124
  onChange: handleChange
124
125
  }), /*#__PURE__*/React.createElement("span", {
125
126
  className: "ai-icon"
@@ -226,7 +227,8 @@ FileUpload.defaultProps = {
226
227
  disabled: false,
227
228
  color: 'paragraph',
228
229
  filePreviewAlignment: 'bottom',
229
- viewOnly: false
230
+ viewOnly: false,
231
+ multiple: true
230
232
  };
231
233
  FileUpload.Preview = _common.Preview;
232
234
  var _default = exports.default = FileUpload;
@@ -141,7 +141,7 @@ const InputBuilder = _ref => {
141
141
  name: `sections.${sectionIndex}.inputs.${inputIndex}.label`,
142
142
  placeholder: "Question"
143
143
  }), hasDescription && /*#__PURE__*/React.createElement(_f.TextInput, {
144
- label: "Description(optional)",
144
+ label: "Description (optional)",
145
145
  name: `sections.${sectionIndex}.inputs.${inputIndex}.description`,
146
146
  placeholder: "Describe details for the question"
147
147
  })), shouldRenderOptions && /*#__PURE__*/React.createElement(_formik.FieldArray, {
@@ -22,7 +22,7 @@ const reconstructFormDataWithValues = (formData, values) => {
22
22
  const valuesMap = {};
23
23
  Object.keys(values).forEach(async key => {
24
24
  if (key.includes('files')) {
25
- const files = values[key].map(file => URL.createObjectURL(file));
25
+ const files = values[key].map(file => file instanceof File ? URL.createObjectURL(file) : file);
26
26
  valuesMap[key] = files;
27
27
  } else {
28
28
  valuesMap[key] = values[key];
@@ -34,13 +34,13 @@ const reconstructFormDataWithValues = (formData, values) => {
34
34
  ...section,
35
35
  inputs: section.inputs.map(input => ({
36
36
  ...input,
37
- value: valuesMap[input.name] || input.value
37
+ value: valuesMap[input.name] !== undefined ? valuesMap[input.name] : input.value
38
38
  }))
39
39
  }))
40
40
  };
41
41
  return newData;
42
42
  };
43
- const validate = values => {
43
+ const validate = (currentSectionIndex, formData, values) => {
44
44
  const errors = {};
45
45
  const hasAtLeastOneValue = Object.keys(values).some(valueKey => {
46
46
  const inputValue = values[valueKey];
@@ -49,6 +49,13 @@ const validate = values => {
49
49
  if (!hasAtLeastOneValue) {
50
50
  errors.message = 'At least one input must have a value';
51
51
  }
52
+
53
+ // Check required fields for current section
54
+ formData.sections[currentSectionIndex].inputs.forEach(input => {
55
+ if (input.required && !values[input.name]) {
56
+ errors[input.name] = 'This field is required';
57
+ }
58
+ });
52
59
  return errors;
53
60
  };
54
61
 
@@ -118,7 +125,7 @@ const Renderer = _ref => {
118
125
  }, /*#__PURE__*/React.createElement(_formik.Formik, {
119
126
  initialValues: initialValues,
120
127
  onSubmit: handleSubmit,
121
- validate: validate
128
+ validate: values => validate(currentSectionIndex, formData, values)
122
129
  }, _ref2 => {
123
130
  let {
124
131
  values,
@@ -135,6 +142,7 @@ const Renderer = _ref => {
135
142
  values
136
143
  });
137
144
  }, [errors, values]);
145
+ const hasErrors = Object.keys(errors).length > 0;
138
146
  return /*#__PURE__*/React.createElement(_formik.Form, null, updatedFormData.sections.map((section, sectionIndex) => sectionIndex === currentSectionIndex && /*#__PURE__*/React.createElement(_common.Section, _extends({
139
147
  key: `${section.title}`
140
148
  }, section, {
@@ -144,7 +152,8 @@ const Renderer = _ref => {
144
152
  handleFileDelete: handleFileDelete
145
153
  }))), /*#__PURE__*/React.createElement("div", {
146
154
  className: "navigator-container"
147
- }, /*#__PURE__*/React.createElement(_b.Button, {
155
+ }, updatedFormData.sections.length > 1 && /*#__PURE__*/React.createElement(_b.Button, {
156
+ className: "previous-button",
148
157
  color: "interactive",
149
158
  isGradient: true,
150
159
  isCompact: true,
@@ -154,7 +163,8 @@ const Renderer = _ref => {
154
163
  }, "Previous"), (!isSubmit || shouldSubmit) && /*#__PURE__*/React.createElement(_b.Button, {
155
164
  color: "interactive",
156
165
  isGradient: true,
157
- type: "submit"
166
+ type: "submit",
167
+ disabled: hasErrors
158
168
  }, isSubmit ? 'Submit' : 'Next')));
159
169
  }));
160
170
  };
@@ -21,6 +21,10 @@ $default-margin: 1rem;
21
21
  display: flex;
22
22
  gap: var(--gap);
23
23
  justify-content: space-between;
24
+
25
+ > .previous-button {
26
+ align-items: center;
27
+ }
24
28
  }
25
29
  }
26
30
  }
@@ -90,6 +90,7 @@ const FileUpload = ({
90
90
  });
91
91
  };
92
92
  const acceptOptions = Array.isArray(accept) ? accept?.join(',') : accept;
93
+ const isAnyFileUploading = Object.values(uploadStatus ?? {})?.map(e => e?.status)?.some(status => status === 'pending');
93
94
  return /*#__PURE__*/React.createElement("div", {
94
95
  id: id,
95
96
  className: [baseClassName, componentClassName, userClassName, `preview-${filePreviewAlignment}`, `y-${color}`].filter(e => e).join(' '),
@@ -108,7 +109,7 @@ const FileUpload = ({
108
109
  type: "file",
109
110
  accept: acceptOptions,
110
111
  multiple: multiple || maxCount && maxCount > 0,
111
- disabled: disabled,
112
+ disabled: disabled || isAnyFileUploading,
112
113
  onChange: handleChange
113
114
  }), /*#__PURE__*/React.createElement("span", {
114
115
  className: "ai-icon"
@@ -215,7 +216,8 @@ FileUpload.defaultProps = {
215
216
  disabled: false,
216
217
  color: 'paragraph',
217
218
  filePreviewAlignment: 'bottom',
218
- viewOnly: false
219
+ viewOnly: false,
220
+ multiple: true
219
221
  };
220
222
  FileUpload.Preview = Preview;
221
223
  export default FileUpload;
@@ -131,7 +131,7 @@ const InputBuilder = ({
131
131
  name: `sections.${sectionIndex}.inputs.${inputIndex}.label`,
132
132
  placeholder: "Question"
133
133
  }), hasDescription && /*#__PURE__*/React.createElement(TextInput, {
134
- label: "Description(optional)",
134
+ label: "Description (optional)",
135
135
  name: `sections.${sectionIndex}.inputs.${inputIndex}.description`,
136
136
  placeholder: "Describe details for the question"
137
137
  })), shouldRenderOptions && /*#__PURE__*/React.createElement(FieldArray, {
@@ -17,7 +17,7 @@ const reconstructFormDataWithValues = (formData, values) => {
17
17
  const valuesMap = {};
18
18
  Object.keys(values).forEach(async key => {
19
19
  if (key.includes('files')) {
20
- const files = values[key].map(file => URL.createObjectURL(file));
20
+ const files = values[key].map(file => file instanceof File ? URL.createObjectURL(file) : file);
21
21
  valuesMap[key] = files;
22
22
  } else {
23
23
  valuesMap[key] = values[key];
@@ -29,13 +29,13 @@ const reconstructFormDataWithValues = (formData, values) => {
29
29
  ...section,
30
30
  inputs: section.inputs.map(input => ({
31
31
  ...input,
32
- value: valuesMap[input.name] || input.value
32
+ value: valuesMap[input.name] !== undefined ? valuesMap[input.name] : input.value
33
33
  }))
34
34
  }))
35
35
  };
36
36
  return newData;
37
37
  };
38
- const validate = values => {
38
+ const validate = (currentSectionIndex, formData, values) => {
39
39
  const errors = {};
40
40
  const hasAtLeastOneValue = Object.keys(values).some(valueKey => {
41
41
  const inputValue = values[valueKey];
@@ -44,6 +44,13 @@ const validate = values => {
44
44
  if (!hasAtLeastOneValue) {
45
45
  errors.message = 'At least one input must have a value';
46
46
  }
47
+
48
+ // Check required fields for current section
49
+ formData.sections[currentSectionIndex].inputs.forEach(input => {
50
+ if (input.required && !values[input.name]) {
51
+ errors[input.name] = 'This field is required';
52
+ }
53
+ });
47
54
  return errors;
48
55
  };
49
56
 
@@ -112,7 +119,7 @@ const Renderer = ({
112
119
  }, /*#__PURE__*/React.createElement(Formik, {
113
120
  initialValues: initialValues,
114
121
  onSubmit: handleSubmit,
115
- validate: validate
122
+ validate: values => validate(currentSectionIndex, formData, values)
116
123
  }, ({
117
124
  values,
118
125
  errors
@@ -128,6 +135,7 @@ const Renderer = ({
128
135
  values
129
136
  });
130
137
  }, [errors, values]);
138
+ const hasErrors = Object.keys(errors).length > 0;
131
139
  return /*#__PURE__*/React.createElement(Form, null, updatedFormData.sections.map((section, sectionIndex) => sectionIndex === currentSectionIndex && /*#__PURE__*/React.createElement(Section, _extends({
132
140
  key: `${section.title}`
133
141
  }, section, {
@@ -137,7 +145,8 @@ const Renderer = ({
137
145
  handleFileDelete: handleFileDelete
138
146
  }))), /*#__PURE__*/React.createElement("div", {
139
147
  className: "navigator-container"
140
- }, /*#__PURE__*/React.createElement(Button, {
148
+ }, updatedFormData.sections.length > 1 && /*#__PURE__*/React.createElement(Button, {
149
+ className: "previous-button",
141
150
  color: "interactive",
142
151
  isGradient: true,
143
152
  isCompact: true,
@@ -147,7 +156,8 @@ const Renderer = ({
147
156
  }, "Previous"), (!isSubmit || shouldSubmit) && /*#__PURE__*/React.createElement(Button, {
148
157
  color: "interactive",
149
158
  isGradient: true,
150
- type: "submit"
159
+ type: "submit",
160
+ disabled: hasErrors
151
161
  }, isSubmit ? 'Submit' : 'Next')));
152
162
  }));
153
163
  };
@@ -21,6 +21,10 @@ $default-margin: 1rem;
21
21
  display: flex;
22
22
  gap: var(--gap);
23
23
  justify-content: space-between;
24
+
25
+ > .previous-button {
26
+ align-items: center;
27
+ }
24
28
  }
25
29
  }
26
30
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pareto-engineering/design-system",
3
- "version": "4.9.0",
3
+ "version": "4.9.2",
4
4
  "description": "",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/es/index.js",
@@ -82,5 +82,5 @@
82
82
  "relay-test-utils": "^15.0.0"
83
83
  },
84
84
  "browserslist": "> 2%",
85
- "gitHead": "198830358910af7c44d657ad846d3c7ce0967181"
85
+ "gitHead": "d7034652bbfb7fa7362d9cedaa04ae23fc8323ad"
86
86
  }
@@ -98,6 +98,8 @@ const FileUpload = ({
98
98
 
99
99
  const acceptOptions = Array.isArray(accept) ? accept?.join(',') : accept
100
100
 
101
+ const isAnyFileUploading = Object.values(uploadStatus ?? {})?.map((e) => e?.status)?.some((status) => status === 'pending')
102
+
101
103
  return (
102
104
  <div
103
105
  id={id}
@@ -128,7 +130,7 @@ const FileUpload = ({
128
130
  type="file"
129
131
  accept={acceptOptions}
130
132
  multiple={multiple || (maxCount && maxCount > 0)}
131
- disabled={disabled}
133
+ disabled={disabled || isAnyFileUploading}
132
134
  onChange={handleChange}
133
135
  />
134
136
  <span className="ai-icon">
@@ -270,6 +272,7 @@ FileUpload.defaultProps = {
270
272
  color :'paragraph',
271
273
  filePreviewAlignment:'bottom',
272
274
  viewOnly :false,
275
+ multiple :true,
273
276
  }
274
277
 
275
278
  FileUpload.Preview = Preview
@@ -191,7 +191,7 @@ const InputBuilder = ({
191
191
  />
192
192
  {hasDescription && (
193
193
  <TextInput
194
- label="Description(optional)"
194
+ label="Description (optional)"
195
195
  name={`sections.${sectionIndex}.inputs.${inputIndex}.description`}
196
196
  placeholder="Describe details for the question"
197
197
  />
@@ -25,7 +25,9 @@ const reconstructFormDataWithValues = (formData, values) => {
25
25
  const valuesMap = {}
26
26
  Object.keys(values).forEach(async (key) => {
27
27
  if (key.includes('files')) {
28
- const files = values[key].map((file) => URL.createObjectURL(file))
28
+ const files = values[key].map((file) => (
29
+ file instanceof File ? URL.createObjectURL(file) : file
30
+ ))
29
31
  valuesMap[key] = files
30
32
  } else {
31
33
  valuesMap[key] = values[key]
@@ -37,14 +39,14 @@ const reconstructFormDataWithValues = (formData, values) => {
37
39
  ...section,
38
40
  inputs:section.inputs.map((input) => ({
39
41
  ...input,
40
- value:valuesMap[input.name] || input.value,
42
+ value:valuesMap[input.name] !== undefined ? valuesMap[input.name] : input.value,
41
43
  })),
42
44
  })),
43
45
  }
44
46
  return newData
45
47
  }
46
48
 
47
- const validate = (values) => {
49
+ const validate = (currentSectionIndex, formData, values) => {
48
50
  const errors = {}
49
51
 
50
52
  const hasAtLeastOneValue = Object.keys(values).some((valueKey) => {
@@ -56,6 +58,13 @@ const validate = (values) => {
56
58
  errors.message = 'At least one input must have a value'
57
59
  }
58
60
 
61
+ // Check required fields for current section
62
+ formData.sections[currentSectionIndex].inputs.forEach((input) => {
63
+ if (input.required && !values[input.name]) {
64
+ errors[input.name] = 'This field is required'
65
+ }
66
+ })
67
+
59
68
  return errors
60
69
  }
61
70
 
@@ -142,7 +151,7 @@ const Renderer = ({
142
151
  <Formik
143
152
  initialValues={initialValues}
144
153
  onSubmit={handleSubmit}
145
- validate={validate}
154
+ validate={(values) => validate(currentSectionIndex, formData, values)}
146
155
  >
147
156
  {({ values, errors }) => {
148
157
  useEffect(() => {
@@ -155,6 +164,8 @@ const Renderer = ({
155
164
  onError?.({ errors, values })
156
165
  }, [errors, values])
157
166
 
167
+ const hasErrors = Object.keys(errors).length > 0
168
+
158
169
  return (
159
170
  <Form>
160
171
  {updatedFormData.sections.map((section, sectionIndex) => (
@@ -170,20 +181,25 @@ const Renderer = ({
170
181
  )
171
182
  ))}
172
183
  <div className="navigator-container">
173
- <Button
174
- color="interactive"
175
- isGradient
176
- isCompact
177
- isGhost
178
- onClick={handlePrevious}
179
- disabled={sectionHistory.length === 0}
180
- >
181
- Previous
182
- </Button>
184
+ {
185
+ updatedFormData.sections.length > 1 && (
186
+ <Button
187
+ className="previous-button"
188
+ color="interactive"
189
+ isGradient
190
+ isCompact
191
+ isGhost
192
+ onClick={handlePrevious}
193
+ disabled={sectionHistory.length === 0}
194
+ >
195
+ Previous
196
+ </Button>
197
+ )
198
+ }
183
199
  {(!isSubmit || shouldSubmit) && (
184
- <Button color="interactive" isGradient type="submit">
185
- {isSubmit ? 'Submit' : 'Next'}
186
- </Button>
200
+ <Button color="interactive" isGradient type="submit" disabled={hasErrors}>
201
+ {isSubmit ? 'Submit' : 'Next'}
202
+ </Button>
187
203
  )}
188
204
  </div>
189
205
  </Form>
@@ -21,6 +21,10 @@ $default-margin: 1rem;
21
21
  display: flex;
22
22
  gap: var(--gap);
23
23
  justify-content: space-between;
24
+
25
+ > .previous-button {
26
+ align-items: center;
27
+ }
24
28
  }
25
29
  }
26
30
  }
@@ -27888,6 +27888,7 @@ exports[`Storyshots f/fields/FileUpload Base 1`] = `
27888
27888
  className="file"
27889
27889
  disabled={false}
27890
27890
  id="section_0_input_0"
27891
+ multiple={true}
27891
27892
  onChange={[Function]}
27892
27893
  type="file"
27893
27894
  />
@@ -33258,16 +33259,7 @@ exports[`Storyshots g/FormBuilder Renderer 1`] = `
33258
33259
  </div>
33259
33260
  <div
33260
33261
  className="navigator-container"
33261
- >
33262
- <button
33263
- className="base button x-interactive modifierGhost modifierCompact modifierGradient"
33264
- disabled={true}
33265
- onClick={[Function]}
33266
- type="button"
33267
- >
33268
- Previous
33269
- </button>
33270
- </div>
33262
+ />
33271
33263
  </form>
33272
33264
  </div>
33273
33265
  </div>,
@@ -33366,16 +33358,7 @@ exports[`Storyshots g/FormBuilder Renderer With Disabled 1`] = `
33366
33358
  </div>
33367
33359
  <div
33368
33360
  className="navigator-container"
33369
- >
33370
- <button
33371
- className="base button x-interactive modifierGhost modifierCompact modifierGradient"
33372
- disabled={true}
33373
- onClick={[Function]}
33374
- type="button"
33375
- >
33376
- Previous
33377
- </button>
33378
- </div>
33361
+ />
33379
33362
  </form>
33380
33363
  </div>
33381
33364
  </div>,
@@ -33475,14 +33458,6 @@ exports[`Storyshots g/FormBuilder Renderer With Submit 1`] = `
33475
33458
  <div
33476
33459
  className="navigator-container"
33477
33460
  >
33478
- <button
33479
- className="base button x-interactive modifierGhost modifierCompact modifierGradient"
33480
- disabled={true}
33481
- onClick={[Function]}
33482
- type="button"
33483
- >
33484
- Previous
33485
- </button>
33486
33461
  <button
33487
33462
  className="base button x-interactive modifierGradient"
33488
33463
  type="submit"