@scenid/react-formulator 0.3.0 → 0.4.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.
- package/.eslintignore +1 -0
- package/dist/index.cjs.js +37371 -36912
- package/dist/index.esm.js +37358 -36903
- package/firebase.json +5 -1
- package/functions/.eslintignore +1 -0
- package/functions/.eslintrc.js +29 -0
- package/functions/index.js +32 -0
- package/functions/package-lock.json +6810 -0
- package/functions/package.json +29 -0
- package/package.json +4 -2
- package/src/{HiddenData.jsx → Components/HiddenData.jsx} +0 -0
- package/src/Components/SelectOrCreate.jsx +156 -0
- package/src/Editable/FormAutocomplete/FormAutocomplete.jsx +121 -0
- package/src/Editable/FormAutocomplete/useFetchOptions.js +83 -0
- package/src/Editable/FormBoolean.jsx +1 -1
- package/src/Editable/FormCatalogType.jsx +29 -0
- package/src/Editable/FormField.jsx +5 -3
- package/src/Editable/FormRepeater.jsx +2 -1
- package/src/Editable/FormSelect.jsx +1 -0
- package/src/Editable/FormText.jsx +12 -5
- package/src/FormulatorForm.jsx +2 -2
- package/src/FormulatorFormSection.jsx +5 -5
- package/src/ReadOnly/FormReadOnlyField.jsx +1 -1
- package/src/ReadOnly/FormReadOnlyText.jsx +14 -2
- package/src/index.js +4 -0
- package/stories/CustomRenderField.jsx +3 -3
- package/stories/Forms.stories.jsx +66 -3
- package/stories/forms/types.schemas.js +132 -9
|
@@ -2,7 +2,11 @@ import React from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
4
|
import StoryBase from './StoryBase'
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
FormulatorForm,
|
|
8
|
+
FormAutocomplete
|
|
9
|
+
} from '../src/index'
|
|
6
10
|
|
|
7
11
|
import getTypesSchemas from './forms/types.schemas'
|
|
8
12
|
|
|
@@ -69,17 +73,76 @@ Template.propTypes = {
|
|
|
69
73
|
baseProps: PropTypes.object
|
|
70
74
|
}
|
|
71
75
|
|
|
76
|
+
const wait = (ms, signal) => new Promise((resolve, reject) => {
|
|
77
|
+
const timer = setTimeout(resolve, ms)
|
|
78
|
+
signal.addEventListener(
|
|
79
|
+
'abort',
|
|
80
|
+
() => {
|
|
81
|
+
clearTimeout(timer)
|
|
82
|
+
reject(new Error('aborted'))
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const catBreeds = [
|
|
88
|
+
{ entry: 'Abyssinian' },
|
|
89
|
+
{ entry: 'Bengal' },
|
|
90
|
+
{ entry: 'Birman' },
|
|
91
|
+
{ entry: 'Burmese' },
|
|
92
|
+
{ entry: 'Chartreux' },
|
|
93
|
+
{ entry: 'Egyptian Mau' },
|
|
94
|
+
{ entry: 'German Rex' },
|
|
95
|
+
{ entry: 'Khao Manee' },
|
|
96
|
+
{ entry: 'Korean Bobtail' },
|
|
97
|
+
{ entry: 'Maine Coon' },
|
|
98
|
+
{ entry: 'Nebelung' },
|
|
99
|
+
{ entry: 'Ocicat' },
|
|
100
|
+
{ entry: 'Oriental Shorthair' },
|
|
101
|
+
{ entry: 'Siamese' }
|
|
102
|
+
]
|
|
103
|
+
|
|
72
104
|
export const Types = Template.bind({})
|
|
73
105
|
Types.args = {
|
|
74
106
|
id: 'unique-form-id',
|
|
75
107
|
schema: schemas.types.validation,
|
|
76
108
|
renderSchema: schemas.types.render,
|
|
77
109
|
inputVariant: 'filled',
|
|
110
|
+
obscuredFields: ['hiddenDataInput'],
|
|
111
|
+
obscuredGroups: ['hiddenInputGroup'],
|
|
78
112
|
renderComponentMap: {
|
|
79
|
-
customRenderField: <CustomRenderField
|
|
113
|
+
customRenderField: <CustomRenderField />,
|
|
114
|
+
autocompleteField2: (
|
|
115
|
+
<FormAutocomplete
|
|
116
|
+
options={async signal => {
|
|
117
|
+
try {
|
|
118
|
+
await wait(200 + (Math.random() * 1000), signal)
|
|
119
|
+
// eslint-disable-next-line no-empty
|
|
120
|
+
} catch (e) {}
|
|
121
|
+
|
|
122
|
+
return catBreeds
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
125
|
+
),
|
|
126
|
+
autocompleteField3: (
|
|
127
|
+
<FormAutocomplete
|
|
128
|
+
options={
|
|
129
|
+
process.env.STORYBOOK_NODE_ENV === 'development'
|
|
130
|
+
? 'http://localhost:5001/scenid-cloud-dev/us-central1/catalog/cats'
|
|
131
|
+
: 'https://us-central1-scenid-cloud-dev.cloudfunctions.net/catalog/cats'
|
|
132
|
+
}
|
|
133
|
+
baererToken="THIS IS A FAKE TOKEN"
|
|
134
|
+
allowCreate
|
|
135
|
+
/>
|
|
136
|
+
)
|
|
80
137
|
},
|
|
81
138
|
translations: typesTranslations,
|
|
82
|
-
data: {
|
|
139
|
+
data: {
|
|
140
|
+
hiddenDataInput: 'Data we do not want to show in Video Calls',
|
|
141
|
+
hiddenGroupInput1: 'sensitive data',
|
|
142
|
+
hiddenGroupInput2: 'non-public information',
|
|
143
|
+
hiddenGroupInput3: 'top secret value',
|
|
144
|
+
autocompleteField1: catBreeds[5].entry
|
|
145
|
+
}
|
|
83
146
|
}
|
|
84
147
|
|
|
85
148
|
export const Markdown = Template.bind({})
|
|
@@ -25,6 +25,26 @@ const inputs = [
|
|
|
25
25
|
render: ['requiredInput'],
|
|
26
26
|
validation: { type: 'string', required: true }
|
|
27
27
|
},
|
|
28
|
+
{
|
|
29
|
+
label: 'Input with hidden data in readonly',
|
|
30
|
+
key: 'hiddenDataInput',
|
|
31
|
+
render: ['hiddenDataInput'],
|
|
32
|
+
validation: { type: 'string' }
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: 'InputGroup that is hidden in readonly',
|
|
36
|
+
key: 'hiddenInputGroup',
|
|
37
|
+
render: [
|
|
38
|
+
'hiddenGroupInput1',
|
|
39
|
+
'hiddenGroupInput2',
|
|
40
|
+
'hiddenGroupInput3'
|
|
41
|
+
],
|
|
42
|
+
validation: [
|
|
43
|
+
{ key: 'hiddenGroupInput1', value: { type: 'string' } },
|
|
44
|
+
{ key: 'hiddenGroupInput2', value: { type: 'string' } },
|
|
45
|
+
{ key: 'hiddenGroupInput3', value: { type: 'string' } }
|
|
46
|
+
]
|
|
47
|
+
},
|
|
28
48
|
{
|
|
29
49
|
label: 'Simple Boolean Switch',
|
|
30
50
|
desc: 'Checkbox vs. Switch\nhttps://uxplanet.org/checkbox-vs-toggle-switch-7fc6e83f10b8',
|
|
@@ -88,24 +108,62 @@ const inputs = [
|
|
|
88
108
|
{
|
|
89
109
|
label: 'Date',
|
|
90
110
|
key: 'dateInput',
|
|
111
|
+
desc: 'Output can be formatted using all options of [luxon\'s .toLocaleString](https://moment.github.io/luxon/#/formatting?id=tolocalestring-strings-for-humans)',
|
|
91
112
|
render: [
|
|
92
113
|
[
|
|
93
|
-
'
|
|
114
|
+
'dateInput1',
|
|
94
115
|
{ type: 'date' }
|
|
116
|
+
],
|
|
117
|
+
[
|
|
118
|
+
'dateInput2',
|
|
119
|
+
{
|
|
120
|
+
type: 'date',
|
|
121
|
+
renderFormat: 'DATE_MED_WITH_WEEKDAY'
|
|
122
|
+
}
|
|
123
|
+
],
|
|
124
|
+
[
|
|
125
|
+
'dateInput3',
|
|
126
|
+
{
|
|
127
|
+
type: 'date',
|
|
128
|
+
renderFormat: { month: 'long', day: 'numeric' }
|
|
129
|
+
}
|
|
95
130
|
]
|
|
96
131
|
],
|
|
97
|
-
validation:
|
|
132
|
+
validation: [
|
|
133
|
+
{ key: 'dateInput1', value: { type: 'string' } },
|
|
134
|
+
{ key: 'dateInput2', value: { type: 'string' } },
|
|
135
|
+
{ key: 'dateInput3', value: { type: 'string' } }
|
|
136
|
+
]
|
|
98
137
|
},
|
|
99
138
|
{
|
|
100
139
|
label: 'Local DateTime',
|
|
101
140
|
key: 'localDateTime',
|
|
141
|
+
desc: 'Output can be formatted using all options of [luxon\'s .toLocaleString](https://moment.github.io/luxon/#/formatting?id=tolocalestring-strings-for-humans)',
|
|
102
142
|
render: [
|
|
103
143
|
[
|
|
104
|
-
'
|
|
144
|
+
'localDateTime1',
|
|
105
145
|
{ type: 'datetime-local' }
|
|
146
|
+
],
|
|
147
|
+
[
|
|
148
|
+
'localDateTime2',
|
|
149
|
+
{
|
|
150
|
+
type: 'datetime-local',
|
|
151
|
+
renderFormat: 'DATETIME_MED_WITH_SECONDS'
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
[
|
|
155
|
+
'localDateTime3',
|
|
156
|
+
{
|
|
157
|
+
type: 'datetime-local',
|
|
158
|
+
renderFormat: { hour: 'numeric', minute: '2-digit' }
|
|
159
|
+
}
|
|
106
160
|
]
|
|
107
161
|
],
|
|
108
|
-
validation:
|
|
162
|
+
validation: [
|
|
163
|
+
{ key: 'localDateTime1', value: { type: 'string' } },
|
|
164
|
+
{ key: 'localDateTime2', value: { type: 'string' } },
|
|
165
|
+
{ key: 'localDateTime3', value: { type: 'string' } }
|
|
166
|
+
]
|
|
109
167
|
},
|
|
110
168
|
{
|
|
111
169
|
label: 'Array as Repeater',
|
|
@@ -113,6 +171,58 @@ const inputs = [
|
|
|
113
171
|
render: ['arrayRepeater'],
|
|
114
172
|
validation: { type: 'array' }
|
|
115
173
|
},
|
|
174
|
+
{
|
|
175
|
+
label: 'Autocomplete Field',
|
|
176
|
+
desc: 'You can supply an array of options or an async function to fetch options on the fly.',
|
|
177
|
+
key: 'autoCompleteFields',
|
|
178
|
+
render: [
|
|
179
|
+
[
|
|
180
|
+
'autocompleteField1',
|
|
181
|
+
{ autocomplete: true }
|
|
182
|
+
],
|
|
183
|
+
[
|
|
184
|
+
'@@render',
|
|
185
|
+
'autocompleteField2'
|
|
186
|
+
],
|
|
187
|
+
[
|
|
188
|
+
'@@render',
|
|
189
|
+
'autocompleteField3',
|
|
190
|
+
{ allowCreate: true }
|
|
191
|
+
]
|
|
192
|
+
],
|
|
193
|
+
validation: [
|
|
194
|
+
{
|
|
195
|
+
key: 'autocompleteField1',
|
|
196
|
+
value: {
|
|
197
|
+
type: [
|
|
198
|
+
'Abyssinian',
|
|
199
|
+
'Bengal',
|
|
200
|
+
'Birman',
|
|
201
|
+
'Burmese',
|
|
202
|
+
'Chartreux',
|
|
203
|
+
'Egyptian Mau',
|
|
204
|
+
'German Rex',
|
|
205
|
+
'Khao Manee',
|
|
206
|
+
'Korean Bobtail',
|
|
207
|
+
'Maine Coon',
|
|
208
|
+
'Nebelung',
|
|
209
|
+
'Ocicat',
|
|
210
|
+
'Oriental Shorthair',
|
|
211
|
+
'Siamese'
|
|
212
|
+
],
|
|
213
|
+
required: true
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
key: 'autocompleteField2',
|
|
218
|
+
value: {
|
|
219
|
+
type: 'string',
|
|
220
|
+
required: true
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
{ key: 'autocompleteField3', value: { type: 'string' } }
|
|
224
|
+
]
|
|
225
|
+
},
|
|
116
226
|
{
|
|
117
227
|
label: 'Custom Render Field',
|
|
118
228
|
desc: 'Try typing something, it might surprise you ;)',
|
|
@@ -144,7 +254,11 @@ export default () => {
|
|
|
144
254
|
const translations = { labels: {} }
|
|
145
255
|
|
|
146
256
|
inputs.forEach(({ key, label, desc, validation, render }) => {
|
|
147
|
-
const validationJSON =
|
|
257
|
+
const validationJSON = (
|
|
258
|
+
Array.isArray(validation)
|
|
259
|
+
? JSON.stringify(validation.reduce((l, r) => ({ ...l, [r.key]: r.value }), {}), null, ' ')
|
|
260
|
+
: JSON.stringify({ [key]: validation }, null, ' ')
|
|
261
|
+
)
|
|
148
262
|
const renderJSON = JSON.stringify(render, null, ' ')
|
|
149
263
|
|
|
150
264
|
const renderEntry = {
|
|
@@ -155,8 +269,7 @@ export default () => {
|
|
|
155
269
|
'@@markdown',
|
|
156
270
|
'mmd-id',
|
|
157
271
|
`\`\`\`json\n/* validation schema */\n${validationJSON}\n\n/* render schema */\n${renderJSON}\n\`\`\``
|
|
158
|
-
]
|
|
159
|
-
render[0]
|
|
272
|
+
]
|
|
160
273
|
]
|
|
161
274
|
}
|
|
162
275
|
|
|
@@ -168,9 +281,19 @@ export default () => {
|
|
|
168
281
|
])
|
|
169
282
|
}
|
|
170
283
|
|
|
284
|
+
if (Array.isArray(validation)) {
|
|
285
|
+
validation.forEach((e, index) => {
|
|
286
|
+
validationSchema.properties[e.key] = e.value
|
|
287
|
+
translations.labels[e.key] = e.key
|
|
288
|
+
renderEntry.fields.push(render[index])
|
|
289
|
+
})
|
|
290
|
+
} else {
|
|
291
|
+
validationSchema.properties[key] = validation
|
|
292
|
+
translations.labels[key] = label
|
|
293
|
+
renderEntry.fields.push(render[0])
|
|
294
|
+
}
|
|
295
|
+
|
|
171
296
|
renderSchema.groups.push(renderEntry)
|
|
172
|
-
validationSchema.properties[key] = validation
|
|
173
|
-
translations.labels[key] = label
|
|
174
297
|
})
|
|
175
298
|
|
|
176
299
|
return {
|