@pareto-engineering/design-system 4.2.0 → 4.2.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.
Files changed (63) hide show
  1. package/dist/cjs/a/XMLEditor/XMLEditor.js +3 -15
  2. package/dist/cjs/f/fields/EditorInput/EditorInput.js +6 -21
  3. package/dist/cjs/f/fields/EditorInput/common/StopPropagationPlugin.js +2 -7
  4. package/dist/cjs/f/fields/SelectInput/common/Menu/Menu.js +1 -1
  5. package/dist/cjs/f/fields/SelectInput/common/Multiple/Multiple.js +1 -1
  6. package/dist/cjs/f/fields/SelectInput/styles.scss +1 -1
  7. package/dist/cjs/g/FormBuilder/FormBuilder.js +38 -5
  8. package/dist/cjs/g/FormBuilder/common/Builder/Builder.js +62 -25
  9. package/dist/cjs/g/FormBuilder/common/Builder/common/ActionsContainer/ActionsContainer.js +80 -0
  10. package/dist/cjs/g/FormBuilder/common/Builder/common/ActionsContainer/index.js +13 -0
  11. package/dist/cjs/g/FormBuilder/common/Builder/common/ActionsContainer/styles.scss +59 -0
  12. package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +19 -45
  13. package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +0 -49
  14. package/dist/cjs/g/FormBuilder/common/Builder/common/Section/Section.js +14 -3
  15. package/dist/cjs/g/FormBuilder/common/Builder/common/Section/styles.scss +61 -0
  16. package/dist/cjs/g/FormBuilder/common/Builder/common/index.js +8 -1
  17. package/dist/cjs/g/FormBuilder/common/Builder/styles.scss +5 -48
  18. package/dist/cjs/g/FormBuilder/common/Renderer/Renderer.js +76 -33
  19. package/dist/cjs/g/FormBuilder/common/Renderer/common/Section/Section.js +8 -3
  20. package/dist/cjs/g/FormBuilder/common/Renderer/styles.scss +12 -1
  21. package/dist/es/a/XMLEditor/XMLEditor.js +3 -15
  22. package/dist/es/f/fields/EditorInput/EditorInput.js +7 -22
  23. package/dist/es/f/fields/EditorInput/common/StopPropagationPlugin.js +2 -6
  24. package/dist/es/f/fields/SelectInput/common/Menu/Menu.js +1 -1
  25. package/dist/es/f/fields/SelectInput/common/Multiple/Multiple.js +1 -1
  26. package/dist/es/f/fields/SelectInput/styles.scss +1 -1
  27. package/dist/es/g/FormBuilder/FormBuilder.js +38 -5
  28. package/dist/es/g/FormBuilder/common/Builder/Builder.js +56 -20
  29. package/dist/es/g/FormBuilder/common/Builder/common/ActionsContainer/ActionsContainer.js +70 -0
  30. package/dist/es/g/FormBuilder/common/Builder/common/ActionsContainer/index.js +2 -0
  31. package/dist/es/g/FormBuilder/common/Builder/common/ActionsContainer/styles.scss +59 -0
  32. package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +21 -47
  33. package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +0 -49
  34. package/dist/es/g/FormBuilder/common/Builder/common/Section/Section.js +14 -3
  35. package/dist/es/g/FormBuilder/common/Builder/common/Section/styles.scss +61 -0
  36. package/dist/es/g/FormBuilder/common/Builder/common/index.js +2 -1
  37. package/dist/es/g/FormBuilder/common/Builder/styles.scss +5 -48
  38. package/dist/es/g/FormBuilder/common/Renderer/Renderer.js +76 -34
  39. package/dist/es/g/FormBuilder/common/Renderer/common/Section/Section.js +8 -3
  40. package/dist/es/g/FormBuilder/common/Renderer/styles.scss +12 -1
  41. package/package.json +4 -4
  42. package/src/stories/g/FormBuilder.stories.jsx +116 -21
  43. package/src/ui/a/XMLEditor/XMLEditor.jsx +1 -15
  44. package/src/ui/f/fields/EditorInput/EditorInput.jsx +7 -23
  45. package/src/ui/f/fields/EditorInput/common/StopPropagationPlugin.jsx +2 -6
  46. package/src/ui/f/fields/SelectInput/common/Menu/Menu.jsx +1 -0
  47. package/src/ui/f/fields/SelectInput/common/Multiple/Multiple.jsx +1 -1
  48. package/src/ui/f/fields/SelectInput/styles.scss +1 -1
  49. package/src/ui/g/FormBuilder/FormBuilder.jsx +50 -3
  50. package/src/ui/g/FormBuilder/common/Builder/Builder.jsx +56 -18
  51. package/src/ui/g/FormBuilder/common/Builder/common/ActionsContainer/ActionsContainer.jsx +97 -0
  52. package/src/ui/g/FormBuilder/common/Builder/common/ActionsContainer/index.js +2 -0
  53. package/src/ui/g/FormBuilder/common/Builder/common/ActionsContainer/styles.scss +59 -0
  54. package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.jsx +40 -60
  55. package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +0 -49
  56. package/src/ui/g/FormBuilder/common/Builder/common/Section/Section.jsx +26 -4
  57. package/src/ui/g/FormBuilder/common/Builder/common/Section/styles.scss +61 -0
  58. package/src/ui/g/FormBuilder/common/Builder/common/index.js +1 -0
  59. package/src/ui/g/FormBuilder/common/Builder/styles.scss +5 -48
  60. package/src/ui/g/FormBuilder/common/Renderer/Renderer.jsx +84 -33
  61. package/src/ui/g/FormBuilder/common/Renderer/common/Section/Section.jsx +3 -2
  62. package/src/ui/g/FormBuilder/common/Renderer/styles.scss +12 -1
  63. package/tests/__snapshots__/Storyshots.test.js.snap +395 -133
@@ -1,2 +1,3 @@
1
1
  export { Section } from './Section'
2
2
  export { InputBuilder } from './InputBuilder'
3
+ export { ActionsContainer } from './ActionsContainer'
@@ -49,56 +49,13 @@ $default-margin: 1rem;
49
49
  flex: .4;
50
50
  gap: var(--gap);
51
51
 
52
- > .#{bem.$base}.select-input {
53
- flex: auto;
52
+ /* stylelint-disable-next-line selector-max-compound-selectors -- required */
53
+ > span {
54
+ white-space: nowrap;
54
55
  }
55
- }
56
- }
57
- > .#{bem.$base}.section {
58
- border-bottom: var(--theme-default-border-style) var(--on-background-inputs);
59
-
60
- > .#{bem.$base}.editor-input {
61
- margin-top: $default-margin;
62
- }
63
56
 
64
- > form {
65
- /* stylelint-disable selector-max-compound-selectors -- required */
66
- > .add-question-cta {
67
- align-items: center;
68
- background-color: transparent;
69
- border: 0;
70
- color: var(--hard-interactive);
71
- cursor: pointer;
72
- display: flex;
73
- gap: var(--gap);
74
- margin-block: calc($default-margin * 1.5);
75
- margin-left: auto;
76
- padding: 0;
77
- transition: all .2s;
78
-
79
- /* stylelint-disable-next-line max-nesting-depth -- required */
80
- &:hover {
81
- color: var(--interactive);
82
-
83
- /* stylelint-disable max-nesting-depth -- required */
84
- > .icon-container {
85
- background-color: var(--interactive);
86
- }
87
- }
88
-
89
- > .icon-container {
90
- align-items: center;
91
- background-color: var(--hard-interactive);
92
- border-radius: 50%;
93
- display: flex;
94
- height: 1.6rem;
95
- justify-content: center;
96
- width: 1.6rem;
97
-
98
- > .icon {
99
- color: var(--on-interactive);
100
- }
101
- }
57
+ > .#{bem.$base}.select-input {
58
+ flex: auto;
102
59
  }
103
60
  }
104
61
  }
@@ -1,9 +1,9 @@
1
1
  /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
2
2
  import * as React from 'react'
3
3
 
4
- import { Formik, Form } from 'formik'
4
+ import { useState, useEffect } from 'react'
5
5
 
6
- import { useState } from 'react'
6
+ import { Formik, Form } from 'formik'
7
7
 
8
8
  import PropTypes from 'prop-types'
9
9
 
@@ -21,6 +21,30 @@ const baseClassName = styleNames.base
21
21
 
22
22
  const componentClassName = 'renderer'
23
23
 
24
+ const reconstructFormDataWithValues = (formData, values) => {
25
+ const newData = { ...formData }
26
+ Object.keys(values).forEach((key) => {
27
+ const [sectionIdx, inputIdx] = key.match(/\d+/g).map(Number)
28
+ newData.sections[sectionIdx].inputs[inputIdx].value = values[key]
29
+ })
30
+ return newData
31
+ }
32
+
33
+ const validate = (values) => {
34
+ const errors = {}
35
+
36
+ const hasAtLeastOneValue = Object.keys(values).some((valueKey) => {
37
+ const inputValue = values[valueKey]
38
+ return inputValue && inputValue !== ''
39
+ })
40
+
41
+ if (!hasAtLeastOneValue) {
42
+ errors.message = 'At least one input must have a value'
43
+ }
44
+
45
+ return errors
46
+ }
47
+
24
48
  /**
25
49
  * This is the component description.
26
50
  */
@@ -29,32 +53,41 @@ const Renderer = ({
29
53
  className:userClassName,
30
54
  style,
31
55
  formData,
56
+ readOnly,
32
57
  onSave,
58
+ onError,
59
+ shouldSubmit,
33
60
  // ...otherProps
34
61
  }) => {
35
62
  const [currentSectionIndex, setCurrentSectionIndex] = useState(0)
36
63
  const [sectionHistory, setSectionHistory] = useState([])
64
+ const [updatedFormData, setUpdatedFormData] = useState(formData)
37
65
 
38
- const initialValues = formData.sections.reduce((acc, section) => {
39
- section.inputs.forEach((input) => {
40
- acc[input.name] = ''
66
+ useEffect(() => {
67
+ setUpdatedFormData(formData)
68
+ }, [formData])
69
+
70
+ const initialValues = formData.sections.reduce((acc, section, sectionIndex) => {
71
+ section.inputs.forEach((input, inputIndex) => {
72
+ const inputName = `section_${sectionIndex}_input_${inputIndex}`
73
+ acc[inputName] = input.value || ''
41
74
  })
42
75
  return acc
43
76
  }, {})
44
77
 
45
78
  const handleSubmit = (values) => {
46
- const currentSection = formData.sections[currentSectionIndex]
79
+ const currentSection = updatedFormData.sections[currentSectionIndex]
47
80
  // by default, 'next' section is the immediate section after the current one
48
81
  let nextSectionIndex = currentSectionIndex + 1
49
82
 
50
83
  // Any other value is either submit or an index to a section
51
84
  if (currentSection.navigation.nextSection !== 'next') {
52
85
  nextSectionIndex = currentSection.navigation.nextSection === 'submit'
53
- ? formData.sections.length // submit
86
+ ? updatedFormData.sections.length // submit
54
87
  : parseInt(currentSection.navigation.nextSection, 10) // go to specific section
55
88
  }
56
89
 
57
- if (nextSectionIndex >= formData.sections.length) {
90
+ if (nextSectionIndex >= updatedFormData.sections.length) {
58
91
  // submit
59
92
  onSave(values)
60
93
  } else {
@@ -75,6 +108,9 @@ const Renderer = ({
75
108
  }
76
109
  }
77
110
 
111
+ const isSubmit = currentSectionIndex === updatedFormData.sections.length - 1
112
+ || updatedFormData.sections[currentSectionIndex].navigation.nextSection === 'submit'
113
+
78
114
  return (
79
115
  <div
80
116
  id={id}
@@ -91,22 +127,46 @@ const Renderer = ({
91
127
  <Formik
92
128
  initialValues={initialValues}
93
129
  onSubmit={handleSubmit}
130
+ validate={validate}
94
131
  >
95
- <Form>
96
- {formData.sections.map((section, sectionIndex) => (
97
- sectionIndex === currentSectionIndex && (
98
- <Section key={`${section.title}`} {...section} />
99
- )
100
- ))}
101
- <div className="navigator-container">
102
- <Button color="interactive" isGradient isGhost onClick={handlePrevious} disabled={sectionHistory.length === 0}>
103
- Previous
104
- </Button>
105
- <Button color="interactive" isGradient type="submit">
106
- {formData.sections[currentSectionIndex].navigation.nextSection === 'submit' ? 'Submit' : 'Next'}
107
- </Button>
108
- </div>
109
- </Form>
132
+ {({ values, errors }) => {
133
+ useEffect(() => {
134
+ const formDataWithValues = reconstructFormDataWithValues(updatedFormData, values)
135
+ setUpdatedFormData(formDataWithValues)
136
+ onSave?.(formDataWithValues)
137
+ }, [values])
138
+
139
+ useEffect(() => {
140
+ onError?.({ errors, values })
141
+ }, [errors, values])
142
+
143
+ return (
144
+ <Form>
145
+ {updatedFormData.sections.map((section, sectionIndex) => (
146
+ sectionIndex === currentSectionIndex && (
147
+ <Section key={`${section.title}`} {...section} readOnly={readOnly} />
148
+ )
149
+ ))}
150
+ <div className="navigator-container">
151
+ <Button
152
+ color="interactive"
153
+ isGradient
154
+ isCompact
155
+ isGhost
156
+ onClick={handlePrevious}
157
+ disabled={sectionHistory.length === 0}
158
+ >
159
+ Previous
160
+ </Button>
161
+ {(!isSubmit || shouldSubmit) && (
162
+ <Button color="interactive" isGradient type="submit">
163
+ {isSubmit ? 'Submit' : 'Next'}
164
+ </Button>
165
+ )}
166
+ </div>
167
+ </Form>
168
+ )
169
+ }}
110
170
  </Formik>
111
171
  </div>
112
172
  )
@@ -127,19 +187,10 @@ Renderer.propTypes = {
127
187
  * The React-written, css properties for this element.
128
188
  */
129
189
  style:PropTypes.objectOf(PropTypes.string),
130
-
131
- /**
132
- * The children JSX
133
- */
134
- formData:PropTypes.shape({
135
- formTitle :PropTypes.string.isRequired,
136
- formDescription:PropTypes.string.isRequired,
137
- sections :PropTypes.arrayOf(PropTypes.objectOf(PropTypes.any)),
138
- }),
139
190
  }
140
191
 
141
192
  Renderer.defaultProps = {
142
- // someProp:false
193
+ // someProp: false,
143
194
  }
144
195
 
145
196
  export default Renderer
@@ -25,6 +25,7 @@ const Section = ({
25
25
  title,
26
26
  description,
27
27
  inputs,
28
+ readOnly,
28
29
  // ...otherProps
29
30
  }) => (
30
31
  <div
@@ -40,13 +41,13 @@ const Section = ({
40
41
  .join(' ')}
41
42
  style={style}
42
43
  >
43
- <h3>{title}</h3>
44
+ <p className="h3">{title}</p>
44
45
  <ExpandableLexicalPreview
45
46
  nodes={description}
46
47
  name="instructions"
47
48
  />
48
49
  {inputs.map((input) => (
49
- <FormInput key={input.name} {...input} />
50
+ <FormInput key={input.name} {...input} disabled={readOnly} />
50
51
  ))}
51
52
  </div>
52
53
  )
@@ -6,10 +6,21 @@ $default-margin: 1rem;
6
6
 
7
7
  .#{bem.$base}.renderer {
8
8
  > form {
9
+ > .#{bem.$base}.section {
10
+ margin-bottom: calc($default-margin * 2);
11
+
12
+ > p {
13
+ margin: 0;
14
+ }
15
+ > .#{bem.$base}.expandable-lexical-preview {
16
+ margin-bottom: $default-margin;
17
+ }
18
+ }
19
+
9
20
  > .navigator-container {
10
21
  display: flex;
11
22
  gap: var(--gap);
12
- margin-top: $default-margin;
23
+ justify-content: space-between;
13
24
  }
14
25
  }
15
26
  }