@pareto-engineering/design-system 4.2.0 → 4.2.1-alpha.0

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 (48) hide show
  1. package/dist/cjs/f/fields/EditorInput/EditorInput.js +4 -6
  2. package/dist/cjs/g/FormBuilder/FormBuilder.js +38 -5
  3. package/dist/cjs/g/FormBuilder/common/Builder/Builder.js +62 -25
  4. package/dist/cjs/g/FormBuilder/common/Builder/common/ActionsContainer/ActionsContainer.js +80 -0
  5. package/dist/cjs/g/FormBuilder/common/Builder/common/ActionsContainer/index.js +13 -0
  6. package/dist/cjs/g/FormBuilder/common/Builder/common/ActionsContainer/styles.scss +59 -0
  7. package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +19 -45
  8. package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +0 -49
  9. package/dist/cjs/g/FormBuilder/common/Builder/common/Section/Section.js +14 -3
  10. package/dist/cjs/g/FormBuilder/common/Builder/common/Section/styles.scss +61 -0
  11. package/dist/cjs/g/FormBuilder/common/Builder/common/index.js +8 -1
  12. package/dist/cjs/g/FormBuilder/common/Builder/styles.scss +5 -48
  13. package/dist/cjs/g/FormBuilder/common/Renderer/Renderer.js +76 -33
  14. package/dist/cjs/g/FormBuilder/common/Renderer/common/Section/Section.js +8 -3
  15. package/dist/cjs/g/FormBuilder/common/Renderer/styles.scss +12 -1
  16. package/dist/es/f/fields/EditorInput/EditorInput.js +5 -7
  17. package/dist/es/g/FormBuilder/FormBuilder.js +38 -5
  18. package/dist/es/g/FormBuilder/common/Builder/Builder.js +56 -20
  19. package/dist/es/g/FormBuilder/common/Builder/common/ActionsContainer/ActionsContainer.js +70 -0
  20. package/dist/es/g/FormBuilder/common/Builder/common/ActionsContainer/index.js +2 -0
  21. package/dist/es/g/FormBuilder/common/Builder/common/ActionsContainer/styles.scss +59 -0
  22. package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +21 -47
  23. package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +0 -49
  24. package/dist/es/g/FormBuilder/common/Builder/common/Section/Section.js +14 -3
  25. package/dist/es/g/FormBuilder/common/Builder/common/Section/styles.scss +61 -0
  26. package/dist/es/g/FormBuilder/common/Builder/common/index.js +2 -1
  27. package/dist/es/g/FormBuilder/common/Builder/styles.scss +5 -48
  28. package/dist/es/g/FormBuilder/common/Renderer/Renderer.js +76 -34
  29. package/dist/es/g/FormBuilder/common/Renderer/common/Section/Section.js +8 -3
  30. package/dist/es/g/FormBuilder/common/Renderer/styles.scss +12 -1
  31. package/package.json +3 -3
  32. package/src/stories/g/FormBuilder.stories.jsx +116 -21
  33. package/src/ui/f/fields/EditorInput/EditorInput.jsx +6 -8
  34. package/src/ui/g/FormBuilder/FormBuilder.jsx +50 -3
  35. package/src/ui/g/FormBuilder/common/Builder/Builder.jsx +56 -18
  36. package/src/ui/g/FormBuilder/common/Builder/common/ActionsContainer/ActionsContainer.jsx +97 -0
  37. package/src/ui/g/FormBuilder/common/Builder/common/ActionsContainer/index.js +2 -0
  38. package/src/ui/g/FormBuilder/common/Builder/common/ActionsContainer/styles.scss +59 -0
  39. package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.jsx +40 -60
  40. package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +0 -49
  41. package/src/ui/g/FormBuilder/common/Builder/common/Section/Section.jsx +26 -4
  42. package/src/ui/g/FormBuilder/common/Builder/common/Section/styles.scss +61 -0
  43. package/src/ui/g/FormBuilder/common/Builder/common/index.js +1 -0
  44. package/src/ui/g/FormBuilder/common/Builder/styles.scss +5 -48
  45. package/src/ui/g/FormBuilder/common/Renderer/Renderer.jsx +84 -33
  46. package/src/ui/g/FormBuilder/common/Renderer/common/Section/Section.jsx +3 -2
  47. package/src/ui/g/FormBuilder/common/Renderer/styles.scss +12 -1
  48. package/tests/__snapshots__/Storyshots.test.js.snap +395 -133
@@ -1,7 +1,7 @@
1
1
  /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
2
2
  import * as React from 'react'
3
3
 
4
- import { useState, useRef } from 'react'
4
+ import { useState } from 'react'
5
5
 
6
6
  import PropTypes from 'prop-types'
7
7
 
@@ -11,14 +11,14 @@ import styleNames from '@pareto-engineering/bem/exports'
11
11
 
12
12
  import { SelectInput, TextInput } from 'ui/f'
13
13
 
14
- import { ToggleSwitch, Popover } from 'ui/a'
15
-
16
- import { useOutsideClick } from 'ui/utils'
14
+ import { ToggleSwitch } from 'ui/a'
17
15
 
18
16
  import './styles.scss'
19
17
 
20
18
  // Local Definitions
21
19
 
20
+ import { ActionsContainer } from '../ActionsContainer'
21
+
22
22
  const baseClassName = styleNames.base
23
23
 
24
24
  const componentClassName = 'input-builder'
@@ -34,14 +34,13 @@ const InputBuilder = ({
34
34
  inputIndex,
35
35
  onDelete,
36
36
  // onCopy,
37
- preferredPopoverOrder,
38
37
  // ...otherProps
39
38
  }) => {
40
39
  const { values, setFieldValue } = useFormikContext()
41
- const input = values.sections[sectionIndex].inputs[inputIndex]
40
+ const input = values.sections[sectionIndex]?.inputs[inputIndex]
42
41
 
43
42
  const handleToggleRequired = () => {
44
- setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.required`, !input.required)
43
+ setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.required`, !input?.required)
45
44
  }
46
45
 
47
46
  const toggleSwitchStyles = {
@@ -53,17 +52,15 @@ const InputBuilder = ({
53
52
  ),
54
53
  }
55
54
 
56
- const parentRef = useRef(null)
57
- const [isOpen, setIsOpen] = useState(false)
58
- useOutsideClick(parentRef, () => setIsOpen(false))
59
-
60
55
  const [hasDescription, setHasDescription] = useState(false)
61
56
 
62
- const handleToggleConditionalNavigation = () => {
63
- setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.conditionalNavigation`, !input.conditionalNavigation)
64
- }
57
+ // TODO: handle nav logic
58
+ // const handleToggleConditionalNavigation = () => {
59
+ // setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.conditionalNavigation`,
60
+ // !input?.conditionalNavigation)
61
+ // }
65
62
 
66
- const availableSections = values.sections.map((section, idx) => ({
63
+ const availableSections = values?.sections?.map((section, idx) => ({
67
64
  value:idx,
68
65
  label:`Go to ${section.title || `Untitled Section ${idx + 1}`}`,
69
66
  }))
@@ -116,10 +113,6 @@ const InputBuilder = ({
116
113
  value:'select',
117
114
  label:'Dropdown select',
118
115
  },
119
- {
120
- value:'editor',
121
- label:'Editor input',
122
- },
123
116
  {
124
117
  value:'multiple',
125
118
  label:'Checkboxes',
@@ -149,39 +142,32 @@ const InputBuilder = ({
149
142
  inputId={`sections_${sectionIndex}_inputs.${inputIndex}_toggle`}
150
143
  />
151
144
  </div>
152
- <div className="actions" ref={parentRef}>
153
- <button type="button" onClick={() => setIsOpen(!isOpen)}>
154
- <span className="icon x-ui-icons c-x">!</span>
155
- </button>
156
- <Popover
157
- isOpen={isOpen}
158
- parentRef={parentRef}
159
- preferredPrimaryOrder={preferredPopoverOrder}
160
- >
161
- <p>Show</p>
162
- <ul>
163
- <li className={`option ${hasDescription ? 'with-check-mark' : ''}`}>
164
- {hasDescription
145
+ <ActionsContainer>
146
+ <p>Show</p>
147
+ <ul>
148
+ <li className={`option ${hasDescription ? 'with-check-mark' : ''}`}>
149
+ {hasDescription
165
150
  && <span className="x-ui-icons c-x icon">I</span>}
166
- <button
167
- onClick={() => setHasDescription(!hasDescription)}
168
- type="button"
169
- >
170
- Description
171
- </button>
172
- </li>
173
- <li className={`option ${input?.conditionalNavigation ? 'with-check-mark' : ''}`}>
174
- {input?.conditionalNavigation && <span className="x-ui-icons c-x icon">I</span>}
175
- <button
176
- onClick={handleToggleConditionalNavigation}
177
- type="button"
178
- >
179
- Go to section based on answer
180
- </button>
181
- </li>
182
- </ul>
183
- </Popover>
184
- </div>
151
+ <button
152
+ onClick={() => setHasDescription(!hasDescription)}
153
+ type="button"
154
+ >
155
+ Description
156
+ </button>
157
+ </li>
158
+ {/* TODO: implement logic */}
159
+ {/*
160
+ <li className={`option ${input?.conditionalNavigation ? 'with-check-mark' : ''}`}>
161
+ {input?.conditionalNavigation && <span className="x-ui-icons c-x icon">I</span>}
162
+ <button
163
+ onClick={handleToggleConditionalNavigation}
164
+ type="button"
165
+ >
166
+ Go to section based on answer
167
+ </button>
168
+ </li> */}
169
+ </ul>
170
+ </ActionsContainer>
185
171
  </div>
186
172
  </div>
187
173
  <div className="input-name-description">
@@ -205,7 +191,7 @@ const InputBuilder = ({
205
191
  <p>Options</p>
206
192
  {input?.options.map((option, optionIndex) => (
207
193
  <div key={option.key} className="option-container">
208
- {input.type !== 'select' && <div className={`input-icon-sample ${input.type}`} />}
194
+ {input?.type !== 'select' && <div className={`input-icon-sample ${input?.type}`} />}
209
195
 
210
196
  <TextInput
211
197
  name={`sections.${sectionIndex}.inputs.${inputIndex}.options.${optionIndex}.value`}
@@ -228,7 +214,7 @@ const InputBuilder = ({
228
214
  className="add-option-cta"
229
215
  type="button"
230
216
  onClick={() => push({
231
- key :`sections-${sectionIndex}-inputs-${inputIndex}-options-${input.options.length - 1}`,
217
+ key :`sections-${sectionIndex}-inputs-${inputIndex}-options-${input?.options.length - 1}`,
232
218
  value :'',
233
219
  label :'',
234
220
  nextSection:'',
@@ -264,16 +250,10 @@ InputBuilder.propTypes = {
264
250
  * The React-written, css properties for this element.
265
251
  */
266
252
  style:PropTypes.objectOf(PropTypes.string),
267
-
268
- /**
269
- * The preferred primary order of the popover
270
- */
271
- preferredPopoverOrder:PropTypes.arrayOf(PropTypes.string),
272
-
273
253
  }
274
254
 
275
255
  InputBuilder.defaultProps = {
276
- preferredPopoverOrder:['right', 'bottom', 'left', 'top'],
256
+ // some properties
277
257
  }
278
258
 
279
259
  export default InputBuilder
@@ -54,55 +54,6 @@ $default-list-width: var(--action-button-width, 18rem);
54
54
  font-size: calc(var(--s1) * 1rem);
55
55
  }
56
56
  }
57
-
58
- > .actions {
59
- position: relative;
60
-
61
- > button {
62
- background-color: transparent;
63
- border: 0;
64
- cursor: pointer;
65
- }
66
-
67
- > .#{bem.$base}.popover {
68
- background-color: var(--background-cards);
69
- border: var(--theme-default-border-style) var(--main2);
70
- border-radius: calc(var(--theme-default-border-radius) / 2);
71
- cursor: default;
72
- padding: $default-padding;
73
- width: $default-list-width;
74
-
75
- > p {
76
- margin: 0;
77
- }
78
-
79
- > ul {
80
- list-style: none;
81
- margin: 0;
82
- padding: 0;
83
- white-space: nowrap;
84
-
85
- > .option {
86
- cursor: pointer;
87
- padding-block: calc($default-padding / 4);
88
-
89
- &:not(.with-check-mark) {
90
- padding-inline: $default-padding;
91
- }
92
-
93
- > button {
94
- background: transparent;
95
- border: 0;
96
- color: var(--paragraph);
97
- cursor: pointer;
98
- font-size: calc(var(--s0) * .875rem);
99
- text-align: left;
100
- width: 100%;
101
- }
102
- }
103
- }
104
- }
105
- }
106
57
  }
107
58
  }
108
59
 
@@ -19,9 +19,13 @@ import { DragAndDrop } from 'ui/g'
19
19
 
20
20
  import { InputBuilder } from '../InputBuilder'
21
21
 
22
+ import { ActionsContainer } from '../ActionsContainer'
23
+
24
+ import './styles.scss'
25
+
22
26
  const baseClassName = styleNames.base
23
27
 
24
- const componentClassName = 'section'
28
+ const componentClassName = 'builder-section'
25
29
 
26
30
  /**
27
31
  * This is the component description.
@@ -31,6 +35,7 @@ const Section = ({
31
35
  className:userClassName,
32
36
  style,
33
37
  index,
38
+ handleDeleteSection,
34
39
  // ...otherProps
35
40
  }) => {
36
41
  const { values, setFieldValue } = useFormikContext()
@@ -84,9 +89,26 @@ const Section = ({
84
89
  .join(' ')}
85
90
  style={style}
86
91
  >
87
- <p className="h4">
88
- {index === 0 ? 'Form title' : `Section ${index + 1}`}
89
- </p>
92
+ <div className="section-header">
93
+ <p className="h4">
94
+ {index === 0 ? 'Form title' : `Section ${index + 1}`}
95
+ </p>
96
+ {index !== 0 && (
97
+ <ActionsContainer>
98
+ <ul>
99
+ <li className="option">
100
+ <button
101
+ type="button"
102
+ className="remove-section-cta"
103
+ onClick={handleDeleteSection}
104
+ >
105
+ Delete Section
106
+ </button>
107
+ </li>
108
+ </ul>
109
+ </ActionsContainer>
110
+ )}
111
+ </div>
90
112
  <TextInput
91
113
  name={`sections.${index}.title`}
92
114
  placeholder={`Title of the ${index === 0 ? 'form' : 'section'}`}
@@ -0,0 +1,61 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
2
+
3
+ @use "@pareto-engineering/bem";
4
+
5
+ $default-margin: 1rem;
6
+
7
+ .#{bem.$base}.builder-section {
8
+ border-bottom: var(--theme-default-border-style) var(--on-background-inputs);
9
+
10
+
11
+ > .section-header {
12
+ align-items: center;
13
+ display: flex;
14
+ justify-content: space-between;
15
+ }
16
+
17
+ > .#{bem.$base}.editor-input {
18
+ margin-top: $default-margin;
19
+ }
20
+
21
+ > form {
22
+ /* stylelint-disable selector-max-compound-selectors -- required */
23
+ > .add-question-cta {
24
+ align-items: center;
25
+ background-color: transparent;
26
+ border: 0;
27
+ color: var(--hard-interactive);
28
+ cursor: pointer;
29
+ display: flex;
30
+ gap: var(--gap);
31
+ margin-block: calc($default-margin * 1.5);
32
+ margin-left: auto;
33
+ padding: 0;
34
+ transition: all .2s;
35
+
36
+ &:hover {
37
+ color: var(--interactive);
38
+
39
+ > .icon-container {
40
+ background-color: var(--interactive);
41
+ }
42
+ }
43
+
44
+ > .icon-container {
45
+ align-items: center;
46
+ background-color: var(--hard-interactive);
47
+ border-radius: 50%;
48
+ display: flex;
49
+ height: 1.6rem;
50
+ justify-content: center;
51
+ width: 1.6rem;
52
+
53
+ > .icon {
54
+ color: var(--on-interactive);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+
@@ -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
  }