@pareto-engineering/design-system 4.8.2 → 4.9.1

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.
@@ -36,7 +36,6 @@ $default-height: var(--notification-height, 5rem);
36
36
  > .message {
37
37
  font-size: calc(var(--s0) * 1rem);
38
38
  margin-left: calc($default-margin / 2);
39
- text-transform: capitalize;
40
39
  }
41
40
 
42
41
  > span {
@@ -135,7 +135,8 @@ const FileUpload = _ref => {
135
135
  fileIndex: indx,
136
136
  identifier: file?.id || file.name
137
137
  }),
138
- uploadStatus: uploadStatus?.[file?.name]
138
+ uploadStatus: uploadStatus?.[file?.name]?.status,
139
+ uploadProgress: uploadStatus?.[file?.name]?.progress
139
140
  })))));
140
141
  };
141
142
  FileUpload.propTypes = {
@@ -45,11 +45,10 @@ const Preview = _ref => {
45
45
  } = _ref;
46
46
  const isFileObject = file instanceof File;
47
47
  const type = isFileObject ? (0, _utils.getFileType)(file) : (0, _utils.getFileTypeFromUrl)(file?.url);
48
- const status = uploadStatus?.status;
49
- const statusColor = statusColorMap[status] ?? color;
50
- const isPending = status === 'pending';
48
+ const statusColor = statusColorMap[uploadStatus] ?? color;
49
+ const isPending = uploadStatus === 'pending';
51
50
  // isPreview means the file is uploaded and previewed while other files can still be uploaded
52
- const isSuccess = status === 'success' || file?.isPreview;
51
+ const isSuccess = uploadStatus === 'success' || file?.isPreview;
53
52
  const handlePreview = () => {
54
53
  if (!isFileObject) {
55
54
  window.open(file.url, '_blank');
@@ -124,6 +123,6 @@ Preview.propTypes = {
124
123
  };
125
124
  Preview.defaultProps = {
126
125
  color: 'green',
127
- uploadProgress: 45
126
+ uploadProgress: 0
128
127
  };
129
128
  var _default = exports.default = Preview;
@@ -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
  }
@@ -36,7 +36,6 @@ $default-height: var(--notification-height, 5rem);
36
36
  > .message {
37
37
  font-size: calc(var(--s0) * 1rem);
38
38
  margin-left: calc($default-margin / 2);
39
- text-transform: capitalize;
40
39
  }
41
40
 
42
41
  > span {
@@ -124,7 +124,8 @@ const FileUpload = ({
124
124
  fileIndex: indx,
125
125
  identifier: file?.id || file.name
126
126
  }),
127
- uploadStatus: uploadStatus?.[file?.name]
127
+ uploadStatus: uploadStatus?.[file?.name]?.status,
128
+ uploadProgress: uploadStatus?.[file?.name]?.progress
128
129
  })))));
129
130
  };
130
131
  FileUpload.propTypes = {
@@ -35,11 +35,10 @@ const Preview = ({
35
35
  }) => {
36
36
  const isFileObject = file instanceof File;
37
37
  const type = isFileObject ? getFileType(file) : getFileTypeFromUrl(file?.url);
38
- const status = uploadStatus?.status;
39
- const statusColor = statusColorMap[status] ?? color;
40
- const isPending = status === 'pending';
38
+ const statusColor = statusColorMap[uploadStatus] ?? color;
39
+ const isPending = uploadStatus === 'pending';
41
40
  // isPreview means the file is uploaded and previewed while other files can still be uploaded
42
- const isSuccess = status === 'success' || file?.isPreview;
41
+ const isSuccess = uploadStatus === 'success' || file?.isPreview;
43
42
  const handlePreview = () => {
44
43
  if (!isFileObject) {
45
44
  window.open(file.url, '_blank');
@@ -114,6 +113,6 @@ Preview.propTypes = {
114
113
  };
115
114
  Preview.defaultProps = {
116
115
  color: 'green',
117
- uploadProgress: 45
116
+ uploadProgress: 0
118
117
  };
119
118
  export default Preview;
@@ -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.8.2",
3
+ "version": "4.9.1",
4
4
  "description": "",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/es/index.js",
@@ -59,7 +59,7 @@
59
59
  "@lexical/selection": "0.12.2",
60
60
  "@lexical/table": "0.12.2",
61
61
  "@lexical/utils": "0.12.2",
62
- "@pareto-engineering/assets": "^4.2.3",
62
+ "@pareto-engineering/assets": "^4.9.0",
63
63
  "@pareto-engineering/bem": "^4.8.1",
64
64
  "@pareto-engineering/styles": "^4.2.0",
65
65
  "@pareto-engineering/utils": "^4.0.0",
@@ -82,5 +82,5 @@
82
82
  "relay-test-utils": "^15.0.0"
83
83
  },
84
84
  "browserslist": "> 2%",
85
- "gitHead": "1eea7b1c3085e7c568568baad8f77c76cbcba46f"
85
+ "gitHead": "eb386a252643ab5658f474ec7cc42c3d4e645f02"
86
86
  }
@@ -36,7 +36,6 @@ $default-height: var(--notification-height, 5rem);
36
36
  > .message {
37
37
  font-size: calc(var(--s0) * 1rem);
38
38
  margin-left: calc($default-margin / 2);
39
- text-transform: capitalize;
40
39
  }
41
40
 
42
41
  > span {
@@ -152,7 +152,8 @@ const FileUpload = ({
152
152
  fileIndex :indx,
153
153
  identifier:file?.id || file.name,
154
154
  })}
155
- uploadStatus={uploadStatus?.[file?.name]}
155
+ uploadStatus={uploadStatus?.[file?.name]?.status}
156
+ uploadProgress={uploadStatus?.[file?.name]?.progress}
156
157
  />
157
158
  ))}
158
159
  </div>
@@ -45,12 +45,11 @@ const Preview = ({
45
45
  const isFileObject = file instanceof File
46
46
  const type = isFileObject ? getFileType(file) : getFileTypeFromUrl(file?.url)
47
47
 
48
- const status = uploadStatus?.status
49
- const statusColor = statusColorMap[status] ?? color
48
+ const statusColor = statusColorMap[uploadStatus] ?? color
50
49
 
51
- const isPending = status === 'pending'
50
+ const isPending = uploadStatus === 'pending'
52
51
  // isPreview means the file is uploaded and previewed while other files can still be uploaded
53
- const isSuccess = status === 'success' || file?.isPreview
52
+ const isSuccess = uploadStatus === 'success' || file?.isPreview
54
53
 
55
54
  const handlePreview = () => {
56
55
  if (!isFileObject) {
@@ -179,7 +178,7 @@ Preview.propTypes = {
179
178
 
180
179
  Preview.defaultProps = {
181
180
  color :'green',
182
- uploadProgress:45,
181
+ uploadProgress:0,
183
182
  }
184
183
 
185
184
  export default 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
  }
@@ -33258,16 +33258,7 @@ exports[`Storyshots g/FormBuilder Renderer 1`] = `
33258
33258
  </div>
33259
33259
  <div
33260
33260
  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>
33261
+ />
33271
33262
  </form>
33272
33263
  </div>
33273
33264
  </div>,
@@ -33366,16 +33357,7 @@ exports[`Storyshots g/FormBuilder Renderer With Disabled 1`] = `
33366
33357
  </div>
33367
33358
  <div
33368
33359
  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>
33360
+ />
33379
33361
  </form>
33380
33362
  </div>
33381
33363
  </div>,
@@ -33475,14 +33457,6 @@ exports[`Storyshots g/FormBuilder Renderer With Submit 1`] = `
33475
33457
  <div
33476
33458
  className="navigator-container"
33477
33459
  >
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
33460
  <button
33487
33461
  className="base button x-interactive modifierGradient"
33488
33462
  type="submit"