@scenid/react-formulator 0.1.14 → 0.3.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,46 @@
1
+ import React, { useState, useEffect } from 'react'
2
+ import PropTypes from 'prop-types'
3
+
4
+ import { TextField, InputAdornment } from '@material-ui/core'
5
+ import { AccountCircle } from '@material-ui/icons'
6
+
7
+ const CustomRenderField = ({ name, value, onChange, ...props }) => {
8
+ const [deg, setDeg] = useState(-10)
9
+
10
+ const handleChange = e => {
11
+ onChange({ target: { name, value: e.target.value } })
12
+ }
13
+
14
+ useEffect(() => {
15
+ setDeg(value?.length * 10)
16
+ }, [value])
17
+
18
+ return (
19
+ <TextField
20
+ // eslint-disable-next-line react/jsx-props-no-spreading
21
+ {...props}
22
+ type="text"
23
+ InputProps={{
24
+ startAdornment: (
25
+ <InputAdornment position="start">
26
+ <AccountCircle
27
+ style={{
28
+ transform: `rotate(${deg}deg)`,
29
+ transition: 'transform 400ms ease-out'
30
+ }}
31
+ />
32
+ </InputAdornment>
33
+ )
34
+ }}
35
+ onChange={handleChange}
36
+ />
37
+ )
38
+ }
39
+
40
+ CustomRenderField.propTypes = {
41
+ name: PropTypes.string.isRequired,
42
+ value: PropTypes.string,
43
+ onChange: PropTypes.func.isRequired
44
+ }
45
+
46
+ 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,18 @@ const inputs = [
114
112
  key: 'arrayRepeater',
115
113
  render: ['arrayRepeater'],
116
114
  validation: { type: 'array' }
115
+ },
116
+ {
117
+ label: 'Custom Render Field',
118
+ desc: 'Try typing something, it might surprise you ;)',
119
+ key: 'customRenderField',
120
+ render: [
121
+ [
122
+ '@@render',
123
+ 'customRenderField'
124
+ ]
125
+ ],
126
+ validation: { type: 'string' }
117
127
  }
118
128
  ]
119
129
 
@@ -142,8 +152,8 @@ export default () => {
142
152
  label,
143
153
  fields: [
144
154
  [
145
- "@@markdown",
146
- "mmd-id",
155
+ '@@markdown',
156
+ 'mmd-id',
147
157
  `\`\`\`json\n/* validation schema */\n${validationJSON}\n\n/* render schema */\n${renderJSON}\n\`\`\``
148
158
  ],
149
159
  render[0]
@@ -152,8 +162,8 @@ export default () => {
152
162
 
153
163
  if (desc) {
154
164
  renderEntry.fields.unshift([
155
- "@@markdown",
156
- "mmd-desc-id",
165
+ '@@markdown',
166
+ 'mmd-desc-id',
157
167
  desc
158
168
  ])
159
169
  }
@@ -1,38 +0,0 @@
1
- 0.30cf261b.iframe.bundle.js.LICENSE.txt,1650758653059,f9da571f65af27492a7a1ee487706907c7b6899f383a145f72f5a8c694ae7184
2
- 0.30cf261b.iframe.bundle.js.map,1650758653059,a48ec794bff02fde310b6ed25bf77db4ba97d110637f3c28c8d62bd2a15772a3
3
- 2.8bdf0833.iframe.bundle.js,1650758653057,547ebe6978844ffb0a96e885dbe47aba567e984eb7a8d9040ba8da6420d3e0a7
4
- 4.22c1589ae6a16d994bda.manager.bundle.js.LICENSE.txt,1650758635106,f9da571f65af27492a7a1ee487706907c7b6899f383a145f72f5a8c694ae7184
5
- 6.af50beb244be1ebcf013.manager.bundle.js.LICENSE.txt,1650758635106,386dc29e2b99977dc9bf6bde1b4ff988501e2bcbed3472812c96aaeed1239771
6
- 7.35efa10296610e53757f.manager.bundle.js,1650758635105,7bd0a44dd25ead0eed6b74d0e6027a22d8b79edad411aa003a0ae1914c40e99d
7
- 7.49dd62a5.iframe.bundle.js.LICENSE.txt,1650758653059,386dc29e2b99977dc9bf6bde1b4ff988501e2bcbed3472812c96aaeed1239771
8
- 7.49dd62a5.iframe.bundle.js.map,1650758653060,a4f3652c5fb2115c80617f2fb37a4a20838e7b229602f1de62ead5a4e368b4c1
9
- 5.097ed3d7ddfe40e67431.manager.bundle.js,1650758635105,223f1efa99720c08d4e2d9119af961ab6d0e4606ca8d69148a872b521de68983
10
- 8.d406d7f000addb30d4e0.manager.bundle.js,1650758635106,8925083a74886d9bf9721f8683c54aac3ee066d1cc3525ea110365670b38fd20
11
- 8.57245307.iframe.bundle.js,1650758653059,a9d5f6a9de58ee42cade902b2fa448a8f5695b88b8c0025832ce7e5d9c7a07b5
12
- iframe.html,1650758653060,2e1653e6befc88b53297632b8fed7a38bab4db3973339602b369cb2423723cc0
13
- 6.6833fdce.iframe.bundle.js,1650758653057,007594b283e6b4234cef2c6497dc000b75008cf004f734934689285e4cd3ad48
14
- index.html,1650758635107,ede1185540d8d6c574eaf4fcd4afa3ca92356f81be64ff6d52ba1de69a914626
15
- main.c7b486ba9ea0b717c1a9.manager.bundle.js,1650758635105,cdf24a07048056f0704b1d741bc717ea537ebe722ed67053a0539a0b7e891b2d
16
- runtime~main.e45f2034.iframe.bundle.js,1650758653057,1680cfe289badbf27f1d4f8370dbf879b9d04e50975b1c448660d96d8cb6f954
17
- runtime~main.f72c3eba52b27c705b1b.manager.bundle.js,1650758635105,9b2cfba4d9650202626b777ee39ccfd645a768c1a52b8103a9e7b975b583192e
18
- vendors~main.648257276d60166dc011.manager.bundle.js.LICENSE.txt,1650758635107,1391a0dac6e18cfc0ec57c845f17090cc7a3d298834c44b42492ebf4288f6642
19
- vendors~main.bbc5b166.iframe.bundle.js.LICENSE.txt,1650758653060,5e04e39e3fecc594f1f5d179c8854c324dfc301c08f41f663a95fced8df4b4a9
20
- vendors~main.bbc5b166.iframe.bundle.js.map,1650758653060,1f9aac87df453020d66224b1e41bcea6e5d475770257ce32fb75ae1ea3ecbcab
21
- favicon.ico,1650629697114,31d363f88b939628a597c9b1de09cdb8d64b9887bbb2193a5b9652256441f27b
22
- static/media/code-brackets.2e1112d7.svg,1650758653059,8e6163f5cb88abca1e76b7ed502379b31305d265ef9f27870b508b9890bcca1d
23
- static/media/comments.a3859089.svg,1650758653060,b8ec0d30db42fd6470c738394adfa24c67acd0c88be88fcf6b7ef258a4b63491
24
- static/media/direction.b770f9af.svg,1650758653060,38acefd300753751fa57bf231634db5775d68be9d4aeab3af1751cb7a21d58fa
25
- static/media/flow.edad2ac1.svg,1650758653060,8f3a687b8fb2b8d0c4264d89037db18159769751c3118a61ff995cf4192460d3
26
- static/media/colors.a4bd0486.svg,1650758653060,321be1fea0c4db8a6e167b05afcc9882e71b3d3b6726006870ed625d4ac0c17c
27
- static/media/plugin.d494b228.svg,1650758653060,8f4f3adff36d058d7100d15590a2f4ff49e06a55b7eb7f50c39d9ac59ebe72a0
28
- static/media/repo.6d496322.svg,1650758653060,2f62b0a6f0366cb63c770bf3828b529cf842c917bba0dd4b35fa567baa97abdb
29
- static/media/stackalt.dba9fbb3.svg,1650758653060,a4bcbb37eb457a804cf3d45676dcbe58ab1ca636ebaabc1c71396302a0ad1c13
30
- 0.28a7a8d757f3710b1952.manager.bundle.js,1650758635105,1946210453dcde037ffec246a8ca427bcebf7de590ab4e7ee491a25896f890eb
31
- 1.88405ac3.iframe.bundle.js,1650758653057,2e93175c88e22597ed016f8279a508278a8ea1254f0393c748bb0c2ccf7a8c43
32
- 4.22c1589ae6a16d994bda.manager.bundle.js,1650758635105,7712bc4557061ff9602d6697c882cc751d55de2cb8302fc8671c8704ec75ef79
33
- 0.30cf261b.iframe.bundle.js,1650758653057,d05b1d0e2cc1dbbdd7ee4e30ee877be8b17b2ae374029d6085b84d6dbf708411
34
- main.ed4711a7.iframe.bundle.js,1650758653057,ea74d6de2d4a4a2de08cf0c45719326b7664ab2e4cd903b694ffed2e502a622f
35
- 6.af50beb244be1ebcf013.manager.bundle.js,1650758635105,3dfb0be00594c7fd8ca8b04ccb0e9af596ca74c418dfdef8d9450e81262b11e1
36
- 7.49dd62a5.iframe.bundle.js,1650758653059,fb8169a5cd94403bb02ce68a001e1b2df1171a7da03b9479f610a35a2b66fbb5
37
- vendors~main.648257276d60166dc011.manager.bundle.js,1650758635106,1fdadbdd3cef9bb1186e9da8f098eb517f746c63096885709cedf8b88b627d32
38
- vendors~main.bbc5b166.iframe.bundle.js,1650758653059,6b06f83d45311766f85ed6a6397f693a7988451d1d254593ee60d979d1398c20