@scenid/react-formulator 0.1.14 → 0.2.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.
@@ -50,7 +50,7 @@ const FormControlField = ({
50
50
  onChange
51
51
  }
52
52
 
53
- const isRender = type === 'render'
53
+ const isRender = type === '@@render'
54
54
 
55
55
  if (validating) {
56
56
  finalProps.endAdornment = [(
@@ -62,29 +62,36 @@ const FormControlField = ({
62
62
 
63
63
  let control
64
64
  if (isRender) {
65
- control = React.cloneElement(
66
- component,
67
- {
68
- variant,
69
- ...finalProps,
70
- label,
71
- hasErrors,
72
- errors,
73
- dirty
74
- }
75
- )
65
+ try {
66
+ control = React.cloneElement(
67
+ component,
68
+ {
69
+ variant,
70
+ ...finalProps,
71
+ label,
72
+ hasErrors,
73
+ errors,
74
+ dirty
75
+ }
76
+ )
77
+ } catch (e) {
78
+ throw new Error(`error creating control for field "${name}": ${e.message}`)
79
+ }
76
80
  } else {
77
- control = React.createElement(
78
- component,
79
- {
80
- variant,
81
- ...finalProps
82
- }
83
- )
81
+ try {
82
+ control = React.createElement(
83
+ component,
84
+ {
85
+ variant,
86
+ ...finalProps
87
+ }
88
+ )
89
+ } catch (e) {
90
+ throw new Error(`error creating control for field "${name}": ${e.message}`)
91
+ }
84
92
  }
85
-
86
93
  const isSwitch = type === 'boolean'
87
- const isRepeater = type === 'array' && !isRender
94
+ const isRepeater = type === 'array'
88
95
 
89
96
  if (isRepeater || isRender) {
90
97
  return control
@@ -182,7 +182,7 @@ const FormRepeater = ({ variant, name, value, catalog, onChange }) => {
182
182
  FormRepeater.propTypes = {
183
183
  variant: PropTypes.oneOf(['standard', 'filled', 'outlined']),
184
184
  name: PropTypes.string.isRequired,
185
- value: PropTypes.any.isRequired,
185
+ value: PropTypes.any,
186
186
  catalog: PropTypes.object,
187
187
  onChange: PropTypes.func.isRequired
188
188
  }
@@ -1,7 +1,8 @@
1
1
  import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
 
4
- import { Box, makeStyles } from '@material-ui/core'
4
+ import { Box } from '@material-ui/core'
5
+ import { makeStyles } from '@material-ui/core/styles'
5
6
 
6
7
  import FormGroupHeader from './FormGroupHeader'
7
8
 
@@ -64,18 +64,8 @@ class FormulatorFormSection extends React.Component {
64
64
  renderComponentMap
65
65
  } = this.props
66
66
 
67
- let field = fieldEntry, specialProps = {}
67
+ let field = fieldEntry, isRender = false, specialProps = {}
68
68
  if (Array.isArray(fieldEntry)) {
69
- if (fieldEntry[0] === '@@render') {
70
- field = fieldEntry[1]
71
- return ({
72
- type: 'render',
73
- name: field,
74
- component: renderComponentMap[field],
75
- componentProps: fieldEntry[2] || {}
76
- })
77
- }
78
-
79
69
  if (fieldEntry[0] === '@@markdown') {
80
70
  return ({
81
71
  type: 'markdown',
@@ -87,10 +77,16 @@ class FormulatorFormSection extends React.Component {
87
77
  })
88
78
  }
89
79
 
90
-
91
- field = fieldEntry[0]
92
- if (!fieldEntry[1]) throw new Error(`field "${field}" is defined in an array, but has no props definition`)
93
- specialProps = fieldEntry[1]
80
+ if (fieldEntry[0] === '@@render') {
81
+ if (!fieldEntry[1]) throw new Error(`render field "${field}" has no name`)
82
+ field = fieldEntry[1]
83
+ specialProps = fieldEntry[2] || {}
84
+ isRender = true
85
+ } else {
86
+ field = fieldEntry[0]
87
+ if (!fieldEntry[1]) throw new Error(`field "${field}" is defined in an array, but has no props definition`)
88
+ specialProps = fieldEntry[1]
89
+ }
94
90
  }
95
91
 
96
92
  const { hidden, hideLabel, ...extraProps } = specialProps
@@ -104,13 +100,14 @@ class FormulatorFormSection extends React.Component {
104
100
  const { type, default: defaultValue } = schema.properties[field]
105
101
 
106
102
  let mapKey
107
- if (componentMap[field] !== undefined) mapKey = field
103
+ if (isRender) mapKey = '@@render'
104
+ else if (componentMap[field] !== undefined) mapKey = field
108
105
  else if (typeof type === 'string' && componentMap[type] !== undefined) mapKey = type
109
106
  else if (Array.isArray(type)) mapKey = 'select'
110
107
  else if (componentMap.default !== undefined) mapKey = 'default'
111
108
  else throw new Error(`Could not find a Component to render for "${field}"`)
112
109
 
113
- const mapEntry = componentMap[mapKey]
110
+ const mapEntry = isRender ? renderComponentMap[field] : componentMap[mapKey]
114
111
  let component = mapEntry, props = {}
115
112
 
116
113
  if (mapKey === 'select') {
@@ -133,8 +130,10 @@ class FormulatorFormSection extends React.Component {
133
130
  /* eslint-enable prefer-destructuring */
134
131
  }
135
132
 
133
+ if (!component) throw new Error(`could not find component for field "${field}"`)
134
+
136
135
  return {
137
- type: mapKey,
136
+ type: isRender ? '@@render' : mapKey,
138
137
  name: field,
139
138
  label: hideLabel !== true && ((translations.labels && translations.labels[field]) || field),
140
139
  defaultValue,
@@ -193,60 +192,6 @@ class FormulatorFormSection extends React.Component {
193
192
  fields.map((fieldEntry, fieldIndex) => {
194
193
  if (fieldEntry === false) return false
195
194
 
196
- if (Array.isArray(fieldEntry) && fieldEntry[0] === '@@render') {
197
- const cKey = fieldEntry[1]
198
- const component = renderComponentMap && renderComponentMap[cKey]
199
- if (!component) throw new Error(`Could not find Component for render field "${cKey}"`)
200
-
201
- const fieldProps = this.getFieldProps(fieldEntry)
202
-
203
- const {
204
- type,
205
- name,
206
- componentProps,
207
- label,
208
- value,
209
- required,
210
- hasErrors,
211
- errors,
212
- validating,
213
- dirty
214
- } = fieldProps
215
-
216
- if (readOnly) {
217
- if (!value) return false
218
- if (Array.isArray(obscuredFields) && obscuredFields.includes(name)) {
219
- return <HiddenData subject="Das Feld" label={label} />
220
- }
221
- }
222
-
223
- return React.createElement(
224
- readOnly ? FormReadOnlyField : FormField,
225
- {
226
- key: `form-render-component-${cKey}`,
227
- variant: inputVariant,
228
- name,
229
- type,
230
- label,
231
- value,
232
- required,
233
- hasErrors,
234
- errors,
235
- validating,
236
- dirty,
237
- component,
238
- componentProps,
239
- disabled,
240
- readOnly,
241
- fields,
242
- results,
243
- data,
244
- fieldStates,
245
- onChange
246
- }
247
- )
248
- }
249
-
250
195
  if (typeof fieldEntry !== 'string' && !Array.isArray(fieldEntry)) {
251
196
  return (
252
197
  <FormulatorFormSection
@@ -437,10 +382,10 @@ class FormulatorFormSection extends React.Component {
437
382
  return (
438
383
  <FormSectionBlock
439
384
  key={`form-section-${sectionId}`}
440
- label={groupLabel}
441
- labelVariant={groupLabelVariant}
442
- desc={groupDesc}
443
- descVariant={groupDescVariant}
385
+ label={label}
386
+ labelVariant={labelVariant}
387
+ desc={desc}
388
+ descVariant={descVariant}
444
389
  textAlign={textAlign}
445
390
  >
446
391
  {sectionContent}
@@ -28,7 +28,7 @@ const FormControlField = ({
28
28
  }
29
29
 
30
30
  let control
31
- if (type === 'render') control = React.cloneElement(component, finalProps)
31
+ if (type === '@@render') control = React.cloneElement(component, finalProps);
32
32
  else control = React.createElement(component, finalProps)
33
33
 
34
34
  return (
@@ -0,0 +1,30 @@
1
+ import React, { useState } from 'react'
2
+ import PropTypes from 'prop-types'
3
+
4
+ import { TextField } from '@material-ui/core'
5
+ import { makeStyles } from '@material-ui/core/styles'
6
+
7
+ const CustomRenderField = ({ name, value, onChange, ...props }) => {
8
+ const [deg, setDeg] = useState(value || '')
9
+
10
+ const handleChange = e => {
11
+ onChange({ target: { name, value: e.target.value } })
12
+ }
13
+
14
+ return (
15
+ <TextField
16
+ // eslint-disable-next-line react/jsx-props-no-spreading
17
+ {...props}
18
+ type="text"
19
+ onChange={handleChange}
20
+ />
21
+ )
22
+ }
23
+
24
+ CustomRenderField.propTypes = {
25
+ name: PropTypes.string.isRequired,
26
+ value: PropTypes.string,
27
+ onChange: PropTypes.func.isRequired
28
+ }
29
+
30
+ export default CustomRenderField
@@ -1,11 +1,10 @@
1
1
  import React from 'react'
2
-
3
- import ReactMarkdown from 'react-markdown'
2
+ import PropTypes from 'prop-types'
4
3
 
5
4
  import StoryBase from './StoryBase'
6
5
  import { FormulatorForm } from '../src/index'
7
6
 
8
- import getTypesSchemas from './forms/types.schemas.js'
7
+ import getTypesSchemas from './forms/types.schemas'
9
8
 
10
9
  import markdownValidation from './forms/markdown.validation.schema.json'
11
10
  import markdownRender from './forms/markdown.render.schema.json'
@@ -20,6 +19,8 @@ import rlpValidation from './forms/rlp.validation.schema.json'
20
19
  import rlpRender from './forms/rlp.render.schema.json'
21
20
  import rlpTranslations from './forms/rlp.translations.json'
22
21
 
22
+ import CustomRenderField from './CustomRenderField'
23
+
23
24
  const {
24
25
  validation: typesValidation,
25
26
  render: typesRender,
@@ -53,17 +54,21 @@ const schemas = {
53
54
  export default {
54
55
  title: 'Formulator/Forms',
55
56
  component: FormulatorForm,
56
- parameters: {
57
- layout: 'fullscreen'
58
- }
57
+ parameters: { layout: 'fullscreen' }
59
58
  }
60
59
 
61
60
  const Template = ({ baseProps, ...props }) => (
61
+ // eslint-disable-next-line react/jsx-props-no-spreading
62
62
  <StoryBase {...baseProps}>
63
+ {/* eslint-disable-next-line react/jsx-props-no-spreading */}
63
64
  <FormulatorForm {...props} />
64
65
  </StoryBase>
65
66
  )
66
67
 
68
+ Template.propTypes = {
69
+ baseProps: PropTypes.object
70
+ }
71
+
67
72
  export const Types = Template.bind({})
68
73
  Types.args = {
69
74
  id: 'unique-form-id',
@@ -71,7 +76,7 @@ Types.args = {
71
76
  renderSchema: schemas.types.render,
72
77
  inputVariant: 'filled',
73
78
  renderComponentMap: {
74
- intro: ReactMarkdown
79
+ customRenderField: <CustomRenderField />
75
80
  },
76
81
  translations: typesTranslations,
77
82
  data: {}
@@ -128,9 +133,7 @@ Register.args = {
128
133
  passwordConfirm: 'Passwort bestätigen'
129
134
  }
130
135
  },
131
- errorMessages: {
132
- Email: 'Ungültige E-Mail-Adresse'
133
- },
136
+ errorMessages: { Email: 'Ungültige E-Mail-Adresse' },
134
137
  data: {}
135
138
  }
136
139
 
@@ -147,14 +150,14 @@ RLP.args = {
147
150
  required: 'Pflichtfeld',
148
151
  IBAN: 'IBAN bitte ohne Sonder- und Trennzeichen angeben',
149
152
  Int: 'Bitte geben Sie ein gültige Zahl ein',
150
- URL: "Ungültiger Link",
151
- Email: "Ungültige E-Mail Adresse",
152
- Date: "Ungültiges Datum",
153
- Length: "Länge muss zwischen {{min}} und {{max}} liegen",
154
- RegExp: "Ungültiges Format oder Zeichen",
155
- 'invalid-email': "Ungültige E-Mail Adresse",
156
- 'invalid-phone': "Ungültige Telefonnummer",
157
- 'invalid-fax': "Ungültige Faxnummer"
153
+ URL: 'Ungültiger Link',
154
+ Email: 'Ungültige E-Mail Adresse',
155
+ Date: 'Ungültiges Datum',
156
+ Length: 'Länge muss zwischen {{min}} und {{max}} liegen',
157
+ RegExp: 'Ungültiges Format oder Zeichen',
158
+ 'invalid-email': 'Ungültige E-Mail Adresse',
159
+ 'invalid-phone': 'Ungültige Telefonnummer',
160
+ 'invalid-fax': 'Ungültige Faxnummer'
158
161
  },
159
162
  obscuredFields: [
160
163
  'reportingPin',
@@ -174,19 +177,19 @@ RLP.args = {
174
177
  // reporterId: <FormUnique entityType="ou" />,
175
178
  // iknr: <FormUnique entityType="ou" />,
176
179
  // bsnr: <FormUnique entityType="ou" excludeInactive />,
177
- contacts: <div/>,
178
- reporterId: <div/>,
179
- iknr: <div/>,
180
- bsnr: <div/>,
181
- productOwner: <div />,
182
- inheritedIKNR: <div />,
183
- inheritedBSNR: <div />,
184
- reportingCodesTrigger: (
185
- <div className="action-group right">
186
- {/* <Button onClick={() => {}}>
187
- Automatisch generieren
188
- </Button> */}
189
- </div>
190
- )
180
+ contacts: <div />,
181
+ reporterId: <div />,
182
+ iknr: <div />,
183
+ bsnr: <div />
184
+ // productOwner: <div />,
185
+ // inheritedIKNR: <div />,
186
+ // inheritedBSNR: <div />,
187
+ // reportingCodesTrigger: (
188
+ // <div className="action-group right">
189
+ // <Button onClick={() => {}}>
190
+ // Automatisch generieren
191
+ // </Button>
192
+ // </div>
193
+ // )
191
194
  }
192
195
  }
@@ -15,7 +15,7 @@ const inputs = [
15
15
  multiline: true,
16
16
  minRows: 5
17
17
  }
18
- ],
18
+ ]
19
19
  ],
20
20
  validation: { type: 'string' }
21
21
  },
@@ -83,9 +83,7 @@ const inputs = [
83
83
  desc: 'Values are automatically sorted with [localeCompare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare).',
84
84
  key: 'simpleSelect',
85
85
  render: ['simpleSelect'],
86
- validation: {
87
- type: ['Citrus', 'Banana', 'Apple', 'Date']
88
- }
86
+ validation: { type: ['Citrus', 'Banana', 'Apple', 'Date'] }
89
87
  },
90
88
  {
91
89
  label: 'Date',
@@ -114,6 +112,17 @@ const inputs = [
114
112
  key: 'arrayRepeater',
115
113
  render: ['arrayRepeater'],
116
114
  validation: { type: 'array' }
115
+ },
116
+ {
117
+ label: 'Custom Render Field',
118
+ key: 'customRenderField',
119
+ render: [
120
+ [
121
+ '@@render',
122
+ 'customRenderField'
123
+ ]
124
+ ],
125
+ validation: { type: 'string' }
117
126
  }
118
127
  ]
119
128
 
@@ -142,8 +151,8 @@ export default () => {
142
151
  label,
143
152
  fields: [
144
153
  [
145
- "@@markdown",
146
- "mmd-id",
154
+ '@@markdown',
155
+ 'mmd-id',
147
156
  `\`\`\`json\n/* validation schema */\n${validationJSON}\n\n/* render schema */\n${renderJSON}\n\`\`\``
148
157
  ],
149
158
  render[0]
@@ -152,8 +161,8 @@ export default () => {
152
161
 
153
162
  if (desc) {
154
163
  renderEntry.fields.unshift([
155
- "@@markdown",
156
- "mmd-desc-id",
164
+ '@@markdown',
165
+ 'mmd-desc-id',
157
166
  desc
158
167
  ])
159
168
  }