@scenid/react-formulator 0.5.2 → 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 (64) hide show
  1. package/dist/index.cjs.js +34 -19
  2. package/dist/index.esm.js +34 -19
  3. package/package.json +4 -1
  4. package/.babelrc +0 -30
  5. package/.eslintignore +0 -22
  6. package/.eslintrc +0 -70
  7. package/.firebaserc +0 -5
  8. package/.storybook/main.js +0 -12
  9. package/.storybook/preview.js +0 -9
  10. package/firebase.json +0 -22
  11. package/functions/.eslintignore +0 -1
  12. package/functions/.eslintrc.js +0 -29
  13. package/functions/index.js +0 -32
  14. package/functions/package-lock.json +0 -6810
  15. package/functions/package.json +0 -29
  16. package/rollup.config.js +0 -40
  17. package/src/Components/HiddenData.jsx +0 -24
  18. package/src/Components/SelectOrCreate.jsx +0 -156
  19. package/src/Editable/FormAutocomplete/FormAutocomplete.jsx +0 -164
  20. package/src/Editable/FormAutocomplete/useFetchOptions.js +0 -83
  21. package/src/Editable/FormBoolean.jsx +0 -46
  22. package/src/Editable/FormCatalogType.jsx +0 -29
  23. package/src/Editable/FormField.jsx +0 -231
  24. package/src/Editable/FormNumber.jsx +0 -36
  25. package/src/Editable/FormRepeater.jsx +0 -218
  26. package/src/Editable/FormSelect.jsx +0 -52
  27. package/src/Editable/FormText.jsx +0 -20
  28. package/src/FormGroupHeader.jsx +0 -85
  29. package/src/FormHelpers.js +0 -191
  30. package/src/FormSectionBlock.jsx +0 -71
  31. package/src/FormSectionCard.jsx +0 -62
  32. package/src/FormulatorForm.jsx +0 -539
  33. package/src/FormulatorFormSection.jsx +0 -457
  34. package/src/ReadOnly/FormReadOnlyBoolean.jsx +0 -36
  35. package/src/ReadOnly/FormReadOnlyField.jsx +0 -126
  36. package/src/ReadOnly/FormReadOnlyMarkdown.jsx +0 -20
  37. package/src/ReadOnly/FormReadOnlyNumber.jsx +0 -17
  38. package/src/ReadOnly/FormReadOnlyRepeater.jsx +0 -36
  39. package/src/ReadOnly/FormReadOnlySelect.jsx +0 -18
  40. package/src/ReadOnly/FormReadOnlyText.jsx +0 -41
  41. package/src/helpers.js +0 -13
  42. package/src/index.js +0 -20
  43. package/stories/CustomRenderField.jsx +0 -46
  44. package/stories/Forms.stories.jsx +0 -267
  45. package/stories/Introduction.stories.mdx +0 -206
  46. package/stories/StoryBase.jsx +0 -35
  47. package/stories/assets/code-brackets.svg +0 -1
  48. package/stories/assets/colors.svg +0 -1
  49. package/stories/assets/comments.svg +0 -1
  50. package/stories/assets/direction.svg +0 -1
  51. package/stories/assets/flow.svg +0 -1
  52. package/stories/assets/plugin.svg +0 -1
  53. package/stories/assets/repo.svg +0 -1
  54. package/stories/assets/stackalt.svg +0 -1
  55. package/stories/forms/login.render.schema.json +0 -23
  56. package/stories/forms/login.validation.schema.json +0 -29
  57. package/stories/forms/markdown.render.schema.json +0 -30
  58. package/stories/forms/markdown.validation.schema.json +0 -18
  59. package/stories/forms/register.render.schema.json +0 -32
  60. package/stories/forms/register.validation.schema.json +0 -34
  61. package/stories/forms/rlp.render.schema.json +0 -153
  62. package/stories/forms/rlp.translations.json +0 -883
  63. package/stories/forms/rlp.validation.schema.json +0 -1631
  64. 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