@scenid/react-formulator 0.5.3 → 0.5.4

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 (62) hide show
  1. package/package.json +4 -1
  2. package/.babelrc +0 -30
  3. package/.eslintignore +0 -22
  4. package/.eslintrc +0 -70
  5. package/.firebaserc +0 -5
  6. package/.storybook/main.js +0 -12
  7. package/.storybook/preview.js +0 -9
  8. package/firebase.json +0 -22
  9. package/functions/.eslintignore +0 -1
  10. package/functions/.eslintrc.js +0 -29
  11. package/functions/index.js +0 -32
  12. package/functions/package-lock.json +0 -6810
  13. package/functions/package.json +0 -29
  14. package/rollup.config.js +0 -40
  15. package/src/Components/HiddenData.jsx +0 -24
  16. package/src/Components/SelectOrCreate.jsx +0 -156
  17. package/src/Editable/FormAutocomplete/FormAutocomplete.jsx +0 -155
  18. package/src/Editable/FormAutocomplete/useFetchOptions.js +0 -83
  19. package/src/Editable/FormBoolean.jsx +0 -46
  20. package/src/Editable/FormCatalogType.jsx +0 -29
  21. package/src/Editable/FormField.jsx +0 -231
  22. package/src/Editable/FormNumber.jsx +0 -36
  23. package/src/Editable/FormRepeater.jsx +0 -218
  24. package/src/Editable/FormSelect.jsx +0 -52
  25. package/src/Editable/FormText.jsx +0 -20
  26. package/src/FormGroupHeader.jsx +0 -85
  27. package/src/FormHelpers.js +0 -191
  28. package/src/FormSectionBlock.jsx +0 -71
  29. package/src/FormSectionCard.jsx +0 -62
  30. package/src/FormulatorForm.jsx +0 -539
  31. package/src/FormulatorFormSection.jsx +0 -456
  32. package/src/ReadOnly/FormReadOnlyBoolean.jsx +0 -36
  33. package/src/ReadOnly/FormReadOnlyField.jsx +0 -126
  34. package/src/ReadOnly/FormReadOnlyMarkdown.jsx +0 -20
  35. package/src/ReadOnly/FormReadOnlyNumber.jsx +0 -17
  36. package/src/ReadOnly/FormReadOnlyRepeater.jsx +0 -52
  37. package/src/ReadOnly/FormReadOnlySelect.jsx +0 -18
  38. package/src/ReadOnly/FormReadOnlyText.jsx +0 -45
  39. package/src/helpers.js +0 -13
  40. package/src/index.js +0 -20
  41. package/stories/CustomRenderField.jsx +0 -46
  42. package/stories/Forms.stories.jsx +0 -283
  43. package/stories/Introduction.stories.mdx +0 -206
  44. package/stories/StoryBase.jsx +0 -35
  45. package/stories/assets/code-brackets.svg +0 -1
  46. package/stories/assets/colors.svg +0 -1
  47. package/stories/assets/comments.svg +0 -1
  48. package/stories/assets/direction.svg +0 -1
  49. package/stories/assets/flow.svg +0 -1
  50. package/stories/assets/plugin.svg +0 -1
  51. package/stories/assets/repo.svg +0 -1
  52. package/stories/assets/stackalt.svg +0 -1
  53. package/stories/forms/login.render.schema.json +0 -23
  54. package/stories/forms/login.validation.schema.json +0 -29
  55. package/stories/forms/markdown.render.schema.json +0 -30
  56. package/stories/forms/markdown.validation.schema.json +0 -18
  57. package/stories/forms/register.render.schema.json +0 -32
  58. package/stories/forms/register.validation.schema.json +0 -34
  59. package/stories/forms/rlp.render.schema.json +0 -153
  60. package/stories/forms/rlp.translations.json +0 -883
  61. package/stories/forms/rlp.validation.schema.json +0 -1631
  62. package/stories/forms/types.schemas.js +0 -319
@@ -1,231 +0,0 @@
1
- import React from 'react'
2
- import PropTypes from 'prop-types'
3
- import cx from 'classnames'
4
-
5
- import isEqual from 'fast-deep-equal'
6
-
7
- import {
8
- FormControl,
9
- FormHelperText,
10
- InputAdornment,
11
- FormControlLabel,
12
- FormGroup
13
- } from '@material-ui/core'
14
-
15
- import { makeStyles } from '@material-ui/styles'
16
-
17
- import AutorenewIcon from '@material-ui/icons/Autorenew'
18
-
19
- const useStyles = makeStyles(theme => ({ error: { color: theme.palette.error.main } }))
20
-
21
- const FormControlField = ({
22
- variant,
23
- type,
24
- name,
25
- label,
26
- component,
27
- componentProps,
28
- defaultValue,
29
- value,
30
- options,
31
- hasErrors,
32
- errors,
33
- required,
34
- disabled,
35
- validating,
36
- dirty,
37
- onChange
38
- }) => {
39
- const styles = useStyles()
40
-
41
- const finalProps = {
42
- name,
43
- label,
44
- defaultValue,
45
- value,
46
- options,
47
- required,
48
- disabled,
49
- ...componentProps,
50
- onChange
51
- }
52
-
53
- const isRender = type === '@@render'
54
-
55
- if (validating) {
56
- finalProps.endAdornment = [(
57
- <InputAdornment position="end">
58
- <AutorenewIcon />
59
- </InputAdornment>
60
- )]
61
- }
62
-
63
- let control
64
- if (isRender) {
65
- try {
66
- const oldProps = component.props || {}
67
- control = React.cloneElement(
68
- component,
69
- {
70
- ...finalProps,
71
- ...oldProps,
72
- variant,
73
- label,
74
- hasErrors,
75
- errors,
76
- dirty
77
- }
78
- )
79
- } catch (e) {
80
- throw new Error(`error creating control for field "${name}": ${e.message}`)
81
- }
82
- } else {
83
- try {
84
- control = React.createElement(
85
- component,
86
- {
87
- variant,
88
- ...finalProps
89
- }
90
- )
91
- } catch (e) {
92
- throw new Error(`error creating control for field "${name}": ${e.message}`)
93
- }
94
- }
95
- const isSwitch = type === 'boolean'
96
- const isRepeater = type === 'array'
97
-
98
- if (isRepeater || isRender) {
99
- return control
100
- }
101
-
102
- return (
103
- <FormControl
104
- className="data-card-field"
105
- error={dirty && hasErrors}
106
- variant={variant}
107
- margin="dense"
108
- fullWidth
109
- required={required}
110
- >
111
- {
112
- isSwitch
113
- && (
114
- <FormControlLabel
115
- className={cx({ [styles.error]: dirty && hasErrors })}
116
- control={control}
117
- label={label}
118
- labelPlacement={finalProps.labelPlacement || 'end'}
119
- />
120
- )
121
- }
122
- {
123
- (!isSwitch && !isRepeater && !isRender)
124
- && control
125
- }
126
- {
127
- (dirty && !disabled && hasErrors)
128
- && (
129
- <FormHelperText>
130
- {errors.map(e => e.message).join('. ')}
131
- </FormHelperText>
132
- )
133
- }
134
- </FormControl>
135
- )
136
- }
137
-
138
- FormControlField.propTypes = {
139
- variant: PropTypes.oneOf(['standard', 'filled', 'outlined']),
140
- component: PropTypes.any.isRequired,
141
- componentProps: PropTypes.object,
142
- type: PropTypes.string.isRequired,
143
- name: PropTypes.string.isRequired,
144
- label: PropTypes.oneOfType([
145
- PropTypes.string,
146
- PropTypes.bool
147
- ]),
148
- defaultValue: PropTypes.oneOfType([
149
- PropTypes.string,
150
- PropTypes.number,
151
- PropTypes.bool,
152
- PropTypes.array,
153
- PropTypes.object
154
- ]),
155
- value: PropTypes.oneOfType([
156
- PropTypes.string,
157
- PropTypes.number,
158
- PropTypes.bool,
159
- PropTypes.array,
160
- PropTypes.object
161
- ]),
162
- options: PropTypes.arrayOf(PropTypes.shape({
163
- label: PropTypes.string.isRequired,
164
- value: PropTypes.any
165
- })),
166
- hasErrors: PropTypes.bool,
167
- errors: PropTypes.array,
168
- validating: PropTypes.bool,
169
- dirty: PropTypes.bool,
170
- required: PropTypes.bool,
171
- disabled: PropTypes.bool,
172
- onChange: PropTypes.func.isRequired
173
- }
174
-
175
- const FormField = ({
176
- prepend,
177
- append,
178
- componentProps,
179
- ...fieldProps
180
- }) => {
181
- const finalProps = {
182
- componentProps,
183
- ...fieldProps
184
- }
185
-
186
- if (componentProps?.type === 'hidden') {
187
- return <input type="hidden" name={fieldProps.name} value={fieldProps.value} />
188
- }
189
-
190
- return (
191
- <FormGroup>
192
- {prepend}
193
- {/* eslint-disable-next-line react/jsx-props-no-spreading */}
194
- <FormControlField {...finalProps} />
195
- {append}
196
- </FormGroup>
197
- )
198
- }
199
-
200
- FormField.propTypes = {
201
- variant: PropTypes.oneOf(['standard', 'filled', 'outlined']),
202
- component: PropTypes.any.isRequired,
203
- componentProps: PropTypes.object,
204
- type: PropTypes.string.isRequired,
205
- name: PropTypes.string.isRequired,
206
- label: PropTypes.oneOfType([
207
- PropTypes.string,
208
- PropTypes.bool
209
- ]),
210
- value: PropTypes.oneOfType([
211
- PropTypes.string,
212
- PropTypes.number,
213
- PropTypes.bool,
214
- PropTypes.array,
215
- PropTypes.object
216
- ]),
217
- options: PropTypes.arrayOf(PropTypes.shape({
218
- label: PropTypes.string.isRequired,
219
- value: PropTypes.any
220
- })),
221
- prepend: PropTypes.array,
222
- append: PropTypes.array,
223
- hasErrors: PropTypes.bool,
224
- errors: PropTypes.array,
225
- validating: PropTypes.bool,
226
- required: PropTypes.bool,
227
- dirty: PropTypes.bool,
228
- onChange: PropTypes.func.isRequired
229
- }
230
-
231
- export default React.memo(FormField, (prevProps, nextProps) => isEqual(prevProps, nextProps))
@@ -1,36 +0,0 @@
1
- import React from 'react'
2
- import PropTypes from 'prop-types'
3
-
4
- import { TextField } from '@material-ui/core'
5
-
6
- import { castToNumber } from '../helpers'
7
-
8
- const FormNumber = ({ name, value, min, max, step, onChange, ...props }) => (
9
- <TextField
10
- name={name}
11
- type="number"
12
- value={castToNumber(value, step)}
13
- inputProps={{ min, max, step }}
14
- onChange={e => onChange({
15
- target: {
16
- name,
17
- value: castToNumber(e.target.value, step)
18
- }
19
- })}
20
- {...props}
21
- />
22
- )
23
-
24
- FormNumber.propTypes = {
25
- name: PropTypes.string.isRequired,
26
- min: PropTypes.number,
27
- max: PropTypes.number,
28
- step: PropTypes.number,
29
- value: PropTypes.oneOfType([
30
- PropTypes.number,
31
- PropTypes.string
32
- ]),
33
- onChange: PropTypes.func.isRequired
34
- }
35
-
36
- export default FormNumber
@@ -1,218 +0,0 @@
1
- import React, { useState, useEffect } from 'react'
2
- import PropTypes from 'prop-types'
3
-
4
- import {
5
- Box,
6
- TextField,
7
- Button,
8
- List,
9
- ListItem,
10
- ListItemText,
11
- ListItemSecondaryAction,
12
- IconButton,
13
- InputAdornment,
14
- FormControl,
15
- Typography,
16
- MenuItem,
17
- ClickAwayListener
18
- } from '@material-ui/core'
19
-
20
- import {
21
- Delete as DeleteIcon,
22
- Clear as ClearIcon,
23
- Save as SaveIcon
24
- } from '@material-ui/icons'
25
-
26
- const getValue = (value, catalog) => {
27
- if (catalog && catalog[value] !== undefined) return catalog[value]
28
- return value
29
- }
30
-
31
- const FormRepeater = ({ variant, name, label, value, options, onChange }) => {
32
- const [entries, setEntries] = useState(value || [])
33
- const [inEdit, setInEdit] = useState(false)
34
- const [inputValue, setInputValue] = useState('')
35
- const [catalogSelectValue, setCatalogSelectValue] = useState('')
36
-
37
- const handleEntryAdd = () => {
38
- if (inputValue.length > 0) {
39
- setEntries([...entries, inputValue])
40
- setInputValue('')
41
- }
42
- }
43
-
44
- const handleCancelNewEntry = () => {
45
- setInEdit(false)
46
- setInputValue('')
47
- setCatalogSelectValue('')
48
- }
49
-
50
- const handleEntryDel = delIndex => {
51
- const newEntries = [...entries]
52
- newEntries.splice(delIndex, 1)
53
- setEntries(newEntries)
54
- }
55
-
56
- useEffect(() => {
57
- const newValue = entries.length > 0 ? entries : undefined
58
- onChange({ target: { name, value: newValue } })
59
- }, [entries])
60
-
61
- let blockedOptions = []
62
- if (options) {
63
- blockedOptions = Object.entries(options).filter(e => Array.isArray(value) && value.includes(e[0])).map(e => e[0])
64
- }
65
-
66
- return (
67
- <Box>
68
- <Typography variant="body1">
69
- {label}
70
- </Typography>
71
- {
72
- (!entries || entries?.length === 0)
73
- && (
74
- <Box mt={1} pl={2}>
75
- <Typography variant="body2" color="textSecondary">
76
- Keine Einträge vorhanden
77
- </Typography>
78
- </Box>
79
- )
80
- }
81
- <List dense>
82
- {
83
- entries.map((entry, index) => (
84
- // eslint-disable-next-line react/no-array-index-key
85
- <ListItem key={`entry-${index}`}>
86
- <ListItemText primary={getValue(entry, options)} />
87
- <ListItemSecondaryAction>
88
- <IconButton
89
- edge="end"
90
- aria-label="delete"
91
- size="small"
92
- onClick={() => handleEntryDel(index)}
93
- >
94
- <DeleteIcon fontSize="small" />
95
- </IconButton>
96
- </ListItemSecondaryAction>
97
- </ListItem>
98
- ))
99
- }
100
- </List>
101
- {
102
- !inEdit
103
- && (
104
- <Box>
105
- <Button
106
- color="primary"
107
- variant="outlined"
108
- onClick={() => setInEdit(true)}
109
- >
110
- Einträge hinzufügen
111
- </Button>
112
- </Box>
113
- )
114
- }
115
- {
116
- (inEdit && !options)
117
- && (
118
- <Box
119
- width="100%"
120
- display="flex"
121
- alignItems="center"
122
- >
123
- <ClickAwayListener
124
- onClickAway={() => {
125
- if (inputValue === '') {
126
- setInEdit(false)
127
- }
128
- }}
129
- >
130
- <FormControl
131
- variant="filled"
132
- fullWidth
133
- >
134
- <TextField
135
- label="Neuer Eintrag"
136
- variant={variant}
137
- value={inputValue}
138
- InputProps={{
139
- endAdornment: (
140
- <InputAdornment position="end">
141
- <Box mr={1}>
142
- <IconButton size="small" onClick={handleEntryAdd}>
143
- <SaveIcon fontSize="small" />
144
- </IconButton>
145
- </Box>
146
- <IconButton size="small" onClick={handleCancelNewEntry}>
147
- <ClearIcon fontSize="small" />
148
- </IconButton>
149
- </InputAdornment>
150
- )
151
- }}
152
- onKeyDown={e => {
153
- if (e.key === 'Enter') handleEntryAdd()
154
- if (e.key === 'Escape') handleCancelNewEntry()
155
- }}
156
- onChange={e => setInputValue(e.target.value)}
157
- />
158
- </FormControl>
159
- </ClickAwayListener>
160
- </Box>
161
- )
162
- }
163
- {
164
- (inEdit && options)
165
- && (
166
- <Box
167
- width="100%"
168
- display="flex"
169
- alignItems="center"
170
- >
171
- <FormControl
172
- variant="filled"
173
- fullWidth
174
- >
175
- <TextField
176
- label="Eintrag auswählen"
177
- select
178
- variant={variant}
179
- value={catalogSelectValue}
180
- onBlur={handleCancelNewEntry}
181
- onChange={e => {
182
- setCatalogSelectValue('')
183
- setEntries([...entries, e.target.value])
184
- }}
185
- >
186
- {
187
- Object
188
- .entries(options)
189
- .sort((a, b) => a[1].localeCompare(b[1]))
190
- .map(e => (
191
- <MenuItem
192
- key={`option-${e[0]}`}
193
- value={e[0]}
194
- disabled={blockedOptions.includes(e[0])}
195
- >
196
- {e[1]}
197
- </MenuItem>
198
- ))
199
- }
200
- </TextField>
201
- </FormControl>
202
- </Box>
203
- )
204
- }
205
- </Box>
206
- )
207
- }
208
-
209
- FormRepeater.propTypes = {
210
- variant: PropTypes.oneOf(['standard', 'filled', 'outlined']),
211
- name: PropTypes.string,
212
- label: PropTypes.string,
213
- value: PropTypes.any,
214
- options: PropTypes.object,
215
- onChange: PropTypes.func.isRequired
216
- }
217
-
218
- export default FormRepeater
@@ -1,52 +0,0 @@
1
- import React from 'react'
2
- import PropTypes from 'prop-types'
3
-
4
- import { TextField, MenuItem } from '@material-ui/core'
5
-
6
- const FormSelect = ({ options, required, value, ...props }) => {
7
- let unselectOption = []
8
-
9
- if (!required) {
10
- unselectOption = [{ label: 'Auswahl löschen', value: undefined }]
11
- }
12
-
13
- const allOptions = [
14
- ...unselectOption,
15
- ...options.sort((l, r) => l.label.localeCompare(r.label))
16
- ]
17
-
18
- return (
19
- <TextField
20
- select
21
- required={required}
22
- value={value === undefined ? '' : value}
23
- // eslint-disable-next-line react/jsx-props-no-spreading
24
- {...props}
25
- >
26
- {
27
- allOptions
28
- .map(({ label: itemLabel, value: itemValue }) => (
29
- <MenuItem
30
- key={itemLabel}
31
- value={itemValue}
32
- >
33
- {itemLabel}
34
- </MenuItem>
35
- ))
36
- }
37
- </TextField>
38
- )
39
- }
40
-
41
- FormSelect.propTypes = {
42
- name: PropTypes.string.isRequired,
43
- value: PropTypes.string,
44
- options: PropTypes.arrayOf(PropTypes.shape({
45
- label: PropTypes.string.isRequired,
46
- value: PropTypes.any
47
- })).isRequired,
48
- required: PropTypes.bool,
49
- onChange: PropTypes.func.isRequired
50
- }
51
-
52
- export default FormSelect
@@ -1,20 +0,0 @@
1
- import React from 'react'
2
- import PropTypes from 'prop-types'
3
-
4
- import { TextField } from '@material-ui/core'
5
-
6
- const FormText = props => {
7
- const { type } = props
8
- const finalProps = { ...props }
9
-
10
- if (type === 'date' || type === 'datetime-local') {
11
- finalProps.InputLabelProps = { shrink: true }
12
- }
13
-
14
- // eslint-disable-next-line react/jsx-props-no-spreading
15
- return <TextField type={type} {...finalProps} />
16
- }
17
-
18
- FormText.propTypes = { type: PropTypes.string }
19
-
20
- export default FormText
@@ -1,85 +0,0 @@
1
- import React from 'react'
2
- import PropTypes from 'prop-types'
3
-
4
- import { Box, Typography } from '@material-ui/core'
5
-
6
- const FormGroupHeader = ({ label, labelVariant, desc, descVariant, textAlign }) => (
7
- <Box
8
- style={{
9
- width: '100%',
10
- display: 'flex',
11
- flexDirection: 'column'
12
- }}
13
- >
14
- {
15
- label
16
- && (
17
- <Box mb={2}>
18
- <Typography
19
- variant={labelVariant}
20
- align={textAlign}
21
- >
22
- {label}
23
- </Typography>
24
- </Box>
25
- )
26
- }
27
- {
28
- desc
29
- && (
30
- <Box mb={2}>
31
- <Typography
32
- variant={descVariant}
33
- align={textAlign}
34
- >
35
- {desc}
36
- </Typography>
37
- </Box>
38
- )
39
- }
40
- </Box>
41
- )
42
-
43
- FormGroupHeader.propTypes = {
44
- label: PropTypes.string,
45
- labelVariant: PropTypes.oneOf([
46
- 'h1',
47
- 'h2',
48
- 'h3',
49
- 'h4',
50
- 'h5',
51
- 'h6',
52
- 'subtitle1',
53
- 'subtitle2',
54
- 'body1',
55
- 'body2',
56
- 'button',
57
- 'caption',
58
- 'overline'
59
- ]),
60
- text: PropTypes.string,
61
- textVariant: PropTypes.oneOf([
62
- 'h1',
63
- 'h2',
64
- 'h3',
65
- 'h4',
66
- 'h5',
67
- 'h6',
68
- 'subtitle1',
69
- 'subtitle2',
70
- 'body1',
71
- 'body2',
72
- 'button',
73
- 'caption',
74
- 'overline'
75
- ]),
76
- textAlign: PropTypes.oneOf(['left', 'center', 'right'])
77
- }
78
-
79
- FormGroupHeader.defaultProps = {
80
- labelVariant: 'h5',
81
- textVariant: 'body2',
82
- textAlign: 'left'
83
- }
84
-
85
- export default FormGroupHeader