@rjsf/core 5.0.0-beta.11 → 5.0.0-beta.12
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/dist/core.cjs.development.js +241 -534
- package/dist/core.cjs.development.js.map +1 -1
- package/dist/core.cjs.production.min.js +1 -1
- package/dist/core.cjs.production.min.js.map +1 -1
- package/dist/core.esm.js +240 -533
- package/dist/core.esm.js.map +1 -1
- package/dist/core.umd.development.js +244 -537
- package/dist/core.umd.development.js.map +1 -1
- package/dist/core.umd.production.min.js +1 -1
- package/dist/core.umd.production.min.js.map +1 -1
- package/dist/index.d.ts +32 -33
- package/package.json +15 -14
package/dist/core.esm.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { Component, useState, useCallback, useEffect, useReducer, useMemo, forwardRef } from 'react';
|
|
2
2
|
import { isFixedItems, allowAdditionalItems, ITEMS_KEY, getUiOptions, getTemplate, isCustomWidget, getWidget, optionsList, guessType, deepEquals, asNumber, REF_KEY, orderProperties, PROPERTIES_KEY, ADDITIONAL_PROPERTY_FLAG, mergeObjects, getSchemaType, ID_KEY, hasWidget, getInputProps, getSubmitButtonOptions, canExpand, parseDateString, toDateString, pad, schemaRequiresTrueValue, utcToLocal, localToUTC, dataURItoBlob, processSelectValue, isObject as isObject$1, createSchemaUtils, shouldRender, RJSF_ADDITONAL_PROPERTIES_FLAG, NAME_KEY } from '@rjsf/utils';
|
|
3
|
-
import _pick from 'lodash-es/pick';
|
|
4
3
|
import get from 'lodash-es/get';
|
|
5
4
|
import _isEmpty from 'lodash-es/isEmpty';
|
|
5
|
+
import _pick from 'lodash-es/pick';
|
|
6
6
|
import isObject from 'lodash-es/isObject';
|
|
7
7
|
import set from 'lodash-es/set';
|
|
8
8
|
import { nanoid } from 'nanoid';
|
|
@@ -11,7 +11,6 @@ import has from 'lodash-es/has';
|
|
|
11
11
|
import omit from 'lodash-es/omit';
|
|
12
12
|
|
|
13
13
|
/** Used to generate a unique ID for an element in a row */
|
|
14
|
-
|
|
15
14
|
function generateRowId() {
|
|
16
15
|
return nanoid();
|
|
17
16
|
}
|
|
@@ -20,8 +19,6 @@ function generateRowId() {
|
|
|
20
19
|
* @param formData - The data for the form
|
|
21
20
|
* @returns - The `formData` converted into a `KeyedFormDataType` element
|
|
22
21
|
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
22
|
function generateKeyedFormData(formData) {
|
|
26
23
|
return !Array.isArray(formData) ? [] : formData.map(item => {
|
|
27
24
|
return {
|
|
@@ -35,20 +32,15 @@ function generateKeyedFormData(formData) {
|
|
|
35
32
|
* @param keyedFormData - The `KeyedFormDataType` to be converted
|
|
36
33
|
* @returns - The inner `formData` item(s) in the `keyedFormData`
|
|
37
34
|
*/
|
|
38
|
-
|
|
39
|
-
|
|
40
35
|
function keyedToPlainFormData(keyedFormData) {
|
|
41
36
|
if (Array.isArray(keyedFormData)) {
|
|
42
37
|
return keyedFormData.map(keyedItem => keyedItem.item);
|
|
43
38
|
}
|
|
44
|
-
|
|
45
39
|
return [];
|
|
46
40
|
}
|
|
47
41
|
/** The `ArrayField` component is used to render a field in the schema that is of type `array`. It supports both normal
|
|
48
42
|
* and fixed array, allowing user to add and remove elements from the array data.
|
|
49
43
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
52
44
|
class ArrayField extends Component {
|
|
53
45
|
/** Constructs an `ArrayField` from the `props`, generating the initial keyed data from the `formData`
|
|
54
46
|
*
|
|
@@ -56,7 +48,6 @@ class ArrayField extends Component {
|
|
|
56
48
|
*/
|
|
57
49
|
constructor(props) {
|
|
58
50
|
super(props);
|
|
59
|
-
|
|
60
51
|
this._getNewFormDataRow = () => {
|
|
61
52
|
const {
|
|
62
53
|
schema,
|
|
@@ -66,20 +57,16 @@ class ArrayField extends Component {
|
|
|
66
57
|
schemaUtils
|
|
67
58
|
} = registry;
|
|
68
59
|
let itemSchema = schema.items;
|
|
69
|
-
|
|
70
60
|
if (isFixedItems(schema) && allowAdditionalItems(schema)) {
|
|
71
61
|
itemSchema = schema.additionalItems;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
62
|
+
}
|
|
63
|
+
// Cast this as a T to work around schema utils being for T[] caused by the FieldProps<T[], S, F> call on the class
|
|
75
64
|
return schemaUtils.getDefaultFormState(itemSchema);
|
|
76
65
|
};
|
|
77
|
-
|
|
78
66
|
this.onAddClick = event => {
|
|
79
67
|
if (event) {
|
|
80
68
|
event.preventDefault();
|
|
81
69
|
}
|
|
82
|
-
|
|
83
70
|
const {
|
|
84
71
|
onChange
|
|
85
72
|
} = this.props;
|
|
@@ -96,13 +83,11 @@ class ArrayField extends Component {
|
|
|
96
83
|
updatedKeyedFormData: true
|
|
97
84
|
}, () => onChange(keyedToPlainFormData(newKeyedFormData)));
|
|
98
85
|
};
|
|
99
|
-
|
|
100
86
|
this.onAddIndexClick = index => {
|
|
101
87
|
return event => {
|
|
102
88
|
if (event) {
|
|
103
89
|
event.preventDefault();
|
|
104
90
|
}
|
|
105
|
-
|
|
106
91
|
const {
|
|
107
92
|
onChange
|
|
108
93
|
} = this.props;
|
|
@@ -121,29 +106,24 @@ class ArrayField extends Component {
|
|
|
121
106
|
}, () => onChange(keyedToPlainFormData(newKeyedFormData)));
|
|
122
107
|
};
|
|
123
108
|
};
|
|
124
|
-
|
|
125
109
|
this.onDropIndexClick = index => {
|
|
126
110
|
return event => {
|
|
127
111
|
if (event) {
|
|
128
112
|
event.preventDefault();
|
|
129
113
|
}
|
|
130
|
-
|
|
131
114
|
const {
|
|
132
115
|
onChange,
|
|
133
116
|
errorSchema
|
|
134
117
|
} = this.props;
|
|
135
118
|
const {
|
|
136
119
|
keyedFormData
|
|
137
|
-
} = this.state;
|
|
138
|
-
|
|
120
|
+
} = this.state;
|
|
121
|
+
// refs #195: revalidate to ensure properly reindexing errors
|
|
139
122
|
let newErrorSchema;
|
|
140
|
-
|
|
141
123
|
if (errorSchema) {
|
|
142
124
|
newErrorSchema = {};
|
|
143
|
-
|
|
144
125
|
for (const idx in errorSchema) {
|
|
145
126
|
const i = parseInt(idx);
|
|
146
|
-
|
|
147
127
|
if (i < index) {
|
|
148
128
|
set(newErrorSchema, [i], errorSchema[idx]);
|
|
149
129
|
} else if (i > index) {
|
|
@@ -151,7 +131,6 @@ class ArrayField extends Component {
|
|
|
151
131
|
}
|
|
152
132
|
}
|
|
153
133
|
}
|
|
154
|
-
|
|
155
134
|
const newKeyedFormData = keyedFormData.filter((_, i) => i !== index);
|
|
156
135
|
this.setState({
|
|
157
136
|
keyedFormData: newKeyedFormData,
|
|
@@ -159,26 +138,21 @@ class ArrayField extends Component {
|
|
|
159
138
|
}, () => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema));
|
|
160
139
|
};
|
|
161
140
|
};
|
|
162
|
-
|
|
163
141
|
this.onReorderClick = (index, newIndex) => {
|
|
164
142
|
return event => {
|
|
165
143
|
if (event) {
|
|
166
144
|
event.preventDefault();
|
|
167
145
|
event.currentTarget.blur();
|
|
168
146
|
}
|
|
169
|
-
|
|
170
147
|
const {
|
|
171
148
|
onChange,
|
|
172
149
|
errorSchema
|
|
173
150
|
} = this.props;
|
|
174
151
|
let newErrorSchema;
|
|
175
|
-
|
|
176
152
|
if (this.props.errorSchema) {
|
|
177
153
|
newErrorSchema = {};
|
|
178
|
-
|
|
179
154
|
for (const idx in errorSchema) {
|
|
180
155
|
const i = parseInt(idx);
|
|
181
|
-
|
|
182
156
|
if (i == index) {
|
|
183
157
|
set(newErrorSchema, [newIndex], errorSchema[index]);
|
|
184
158
|
} else if (i == newIndex) {
|
|
@@ -188,30 +162,23 @@ class ArrayField extends Component {
|
|
|
188
162
|
}
|
|
189
163
|
}
|
|
190
164
|
}
|
|
191
|
-
|
|
192
165
|
const {
|
|
193
166
|
keyedFormData
|
|
194
167
|
} = this.state;
|
|
195
|
-
|
|
196
168
|
function reOrderArray() {
|
|
197
169
|
// Copy item
|
|
198
|
-
const _newKeyedFormData = keyedFormData.slice();
|
|
199
|
-
|
|
200
|
-
|
|
170
|
+
const _newKeyedFormData = keyedFormData.slice();
|
|
171
|
+
// Moves item from index to newIndex
|
|
201
172
|
_newKeyedFormData.splice(index, 1);
|
|
202
|
-
|
|
203
173
|
_newKeyedFormData.splice(newIndex, 0, keyedFormData[index]);
|
|
204
|
-
|
|
205
174
|
return _newKeyedFormData;
|
|
206
175
|
}
|
|
207
|
-
|
|
208
176
|
const newKeyedFormData = reOrderArray();
|
|
209
177
|
this.setState({
|
|
210
178
|
keyedFormData: newKeyedFormData
|
|
211
179
|
}, () => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema));
|
|
212
180
|
};
|
|
213
181
|
};
|
|
214
|
-
|
|
215
182
|
this.onChangeForIndex = index => {
|
|
216
183
|
return (value, newErrorSchema, id) => {
|
|
217
184
|
const {
|
|
@@ -226,12 +193,12 @@ class ArrayField extends Component {
|
|
|
226
193
|
const jsonValue = typeof value === "undefined" ? null : value;
|
|
227
194
|
return index === i ? jsonValue : item;
|
|
228
195
|
});
|
|
229
|
-
onChange(newFormData, errorSchema && errorSchema && {
|
|
196
|
+
onChange(newFormData, errorSchema && errorSchema && {
|
|
197
|
+
...errorSchema,
|
|
230
198
|
[index]: newErrorSchema
|
|
231
199
|
}, id);
|
|
232
200
|
};
|
|
233
201
|
};
|
|
234
|
-
|
|
235
202
|
this.onSelectChange = value => {
|
|
236
203
|
const {
|
|
237
204
|
onChange,
|
|
@@ -239,13 +206,10 @@ class ArrayField extends Component {
|
|
|
239
206
|
} = this.props;
|
|
240
207
|
onChange(value, undefined, idSchema && idSchema.$id);
|
|
241
208
|
};
|
|
242
|
-
|
|
243
209
|
const {
|
|
244
210
|
formData: _formData = []
|
|
245
211
|
} = props;
|
|
246
|
-
|
|
247
212
|
const _keyedFormData = generateKeyedFormData(_formData);
|
|
248
|
-
|
|
249
213
|
this.state = {
|
|
250
214
|
keyedFormData: _keyedFormData,
|
|
251
215
|
updatedKeyedFormData: false
|
|
@@ -257,8 +221,6 @@ class ArrayField extends Component {
|
|
|
257
221
|
* @param nextProps - The next set of props data
|
|
258
222
|
* @param prevState - The previous set of state data
|
|
259
223
|
*/
|
|
260
|
-
|
|
261
|
-
|
|
262
224
|
static getDerivedStateFromProps(nextProps, prevState) {
|
|
263
225
|
// Don't call getDerivedStateFromProps if keyed formdata was just updated.
|
|
264
226
|
if (prevState.updatedKeyedFormData) {
|
|
@@ -266,7 +228,6 @@ class ArrayField extends Component {
|
|
|
266
228
|
updatedKeyedFormData: false
|
|
267
229
|
};
|
|
268
230
|
}
|
|
269
|
-
|
|
270
231
|
const nextFormData = Array.isArray(nextProps.formData) ? nextProps.formData : [];
|
|
271
232
|
const previousKeyedFormData = prevState.keyedFormData || [];
|
|
272
233
|
const newKeyedFormData = nextFormData.length === previousKeyedFormData.length ? previousKeyedFormData.map((previousKeyedFormDatum, index) => {
|
|
@@ -282,8 +243,6 @@ class ArrayField extends Component {
|
|
|
282
243
|
/** Returns the appropriate title for an item by getting first the title from the schema.items, then falling back to
|
|
283
244
|
* the description from the schema.items, and finally the string "Item"
|
|
284
245
|
*/
|
|
285
|
-
|
|
286
|
-
|
|
287
246
|
get itemTitle() {
|
|
288
247
|
const {
|
|
289
248
|
schema
|
|
@@ -296,16 +255,13 @@ class ArrayField extends Component {
|
|
|
296
255
|
* @param itemSchema - The schema for the item
|
|
297
256
|
* @return - True if the item schema type does not contain the "null" type
|
|
298
257
|
*/
|
|
299
|
-
|
|
300
|
-
|
|
301
258
|
isItemRequired(itemSchema) {
|
|
302
259
|
if (Array.isArray(itemSchema.type)) {
|
|
303
260
|
// While we don't yet support composite/nullable jsonschema types, it's
|
|
304
261
|
// future-proof to check for requirement against these.
|
|
305
262
|
return !itemSchema.type.includes("null");
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
|
|
263
|
+
}
|
|
264
|
+
// All non-null array item types are inherently required by design
|
|
309
265
|
return itemSchema.type !== "null";
|
|
310
266
|
}
|
|
311
267
|
/** Determines whether more items can be added to the array. If the uiSchema indicates the array doesn't allow adding
|
|
@@ -315,8 +271,6 @@ class ArrayField extends Component {
|
|
|
315
271
|
* @param formItems - The list of items in the form
|
|
316
272
|
* @returns - True if the item is addable otherwise false
|
|
317
273
|
*/
|
|
318
|
-
|
|
319
|
-
|
|
320
274
|
canAddItem(formItems) {
|
|
321
275
|
const {
|
|
322
276
|
schema,
|
|
@@ -325,7 +279,6 @@ class ArrayField extends Component {
|
|
|
325
279
|
let {
|
|
326
280
|
addable
|
|
327
281
|
} = getUiOptions(uiSchema);
|
|
328
|
-
|
|
329
282
|
if (addable !== false) {
|
|
330
283
|
// if ui:options.addable was not explicitly set to false, we can add
|
|
331
284
|
// another item if we have not exceeded maxItems yet
|
|
@@ -335,14 +288,12 @@ class ArrayField extends Component {
|
|
|
335
288
|
addable = true;
|
|
336
289
|
}
|
|
337
290
|
}
|
|
338
|
-
|
|
339
291
|
return addable;
|
|
340
292
|
}
|
|
341
293
|
/** Returns the default form information for an item based on the schema for that item. Deals with the possibility
|
|
342
294
|
* that the schema is fixed and allows additional items.
|
|
343
295
|
*/
|
|
344
296
|
|
|
345
|
-
|
|
346
297
|
/** Renders the `ArrayField` depending on the specific needs of the schema and uischema elements
|
|
347
298
|
*/
|
|
348
299
|
render() {
|
|
@@ -355,7 +306,6 @@ class ArrayField extends Component {
|
|
|
355
306
|
const {
|
|
356
307
|
schemaUtils
|
|
357
308
|
} = registry;
|
|
358
|
-
|
|
359
309
|
if (!(ITEMS_KEY in schema)) {
|
|
360
310
|
const uiOptions = getUiOptions(uiSchema);
|
|
361
311
|
const UnsupportedFieldTemplate = getTemplate("UnsupportedFieldTemplate", registry, uiOptions);
|
|
@@ -366,30 +316,23 @@ class ArrayField extends Component {
|
|
|
366
316
|
registry: registry
|
|
367
317
|
});
|
|
368
318
|
}
|
|
369
|
-
|
|
370
319
|
if (schemaUtils.isMultiSelect(schema)) {
|
|
371
320
|
// If array has enum or uniqueItems set to true, call renderMultiSelect() to render the default multiselect widget or a custom widget, if specified.
|
|
372
321
|
return this.renderMultiSelect();
|
|
373
322
|
}
|
|
374
|
-
|
|
375
323
|
if (isCustomWidget(uiSchema)) {
|
|
376
324
|
return this.renderCustomWidget();
|
|
377
325
|
}
|
|
378
|
-
|
|
379
326
|
if (isFixedItems(schema)) {
|
|
380
327
|
return this.renderFixedArray();
|
|
381
328
|
}
|
|
382
|
-
|
|
383
329
|
if (schemaUtils.isFilesArray(schema, uiSchema)) {
|
|
384
330
|
return this.renderFiles();
|
|
385
331
|
}
|
|
386
|
-
|
|
387
332
|
return this.renderNormalArray();
|
|
388
333
|
}
|
|
389
334
|
/** Renders a normal array without any limitations of length
|
|
390
335
|
*/
|
|
391
|
-
|
|
392
|
-
|
|
393
336
|
renderNormalArray() {
|
|
394
337
|
const {
|
|
395
338
|
schema,
|
|
@@ -417,9 +360,7 @@ class ArrayField extends Component {
|
|
|
417
360
|
formContext
|
|
418
361
|
} = registry;
|
|
419
362
|
const uiOptions = getUiOptions(uiSchema);
|
|
420
|
-
|
|
421
363
|
const _schemaItems = isObject(schema.items) ? schema.items : {};
|
|
422
|
-
|
|
423
364
|
const itemsSchema = schemaUtils.retrieveSchema(_schemaItems);
|
|
424
365
|
const formData = keyedToPlainFormData(this.state.keyedFormData);
|
|
425
366
|
const arrayProps = {
|
|
@@ -428,8 +369,8 @@ class ArrayField extends Component {
|
|
|
428
369
|
const {
|
|
429
370
|
key,
|
|
430
371
|
item
|
|
431
|
-
} = keyedItem;
|
|
432
|
-
|
|
372
|
+
} = keyedItem;
|
|
373
|
+
// While we are actually dealing with a single item of type T, the types require a T[], so cast
|
|
433
374
|
const itemCast = item;
|
|
434
375
|
const itemSchema = schemaUtils.retrieveSchema(_schemaItems, itemCast);
|
|
435
376
|
const itemErrorSchema = errorSchema ? errorSchema[index] : undefined;
|
|
@@ -438,10 +379,10 @@ class ArrayField extends Component {
|
|
|
438
379
|
return this.renderArrayFieldItem({
|
|
439
380
|
key,
|
|
440
381
|
index,
|
|
441
|
-
name: name && name
|
|
382
|
+
name: name && `${name}-${index}`,
|
|
442
383
|
canMoveUp: index > 0,
|
|
443
384
|
canMoveDown: index < formData.length - 1,
|
|
444
|
-
itemSchema
|
|
385
|
+
itemSchema,
|
|
445
386
|
itemIdSchema,
|
|
446
387
|
itemErrorSchema,
|
|
447
388
|
itemData: itemCast,
|
|
@@ -452,7 +393,7 @@ class ArrayField extends Component {
|
|
|
452
393
|
rawErrors
|
|
453
394
|
});
|
|
454
395
|
}),
|
|
455
|
-
className:
|
|
396
|
+
className: `field field-array field-array-of-${itemsSchema.type}`,
|
|
456
397
|
disabled,
|
|
457
398
|
idSchema,
|
|
458
399
|
uiSchema,
|
|
@@ -467,13 +408,12 @@ class ArrayField extends Component {
|
|
|
467
408
|
registry
|
|
468
409
|
};
|
|
469
410
|
const Template = getTemplate("ArrayFieldTemplate", registry, uiOptions);
|
|
470
|
-
return /*#__PURE__*/React.createElement(Template, {
|
|
411
|
+
return /*#__PURE__*/React.createElement(Template, {
|
|
412
|
+
...arrayProps
|
|
471
413
|
});
|
|
472
414
|
}
|
|
473
415
|
/** Renders an array using the custom widget provided by the user in the `uiSchema`
|
|
474
416
|
*/
|
|
475
|
-
|
|
476
|
-
|
|
477
417
|
renderCustomWidget() {
|
|
478
418
|
const {
|
|
479
419
|
schema,
|
|
@@ -526,8 +466,6 @@ class ArrayField extends Component {
|
|
|
526
466
|
}
|
|
527
467
|
/** Renders an array as a set of checkboxes
|
|
528
468
|
*/
|
|
529
|
-
|
|
530
|
-
|
|
531
469
|
renderMultiSelect() {
|
|
532
470
|
const {
|
|
533
471
|
schema,
|
|
@@ -564,7 +502,8 @@ class ArrayField extends Component {
|
|
|
564
502
|
onChange: this.onSelectChange,
|
|
565
503
|
onBlur: onBlur,
|
|
566
504
|
onFocus: onFocus,
|
|
567
|
-
options: {
|
|
505
|
+
options: {
|
|
506
|
+
...options,
|
|
568
507
|
enumOptions
|
|
569
508
|
},
|
|
570
509
|
schema: schema,
|
|
@@ -583,8 +522,6 @@ class ArrayField extends Component {
|
|
|
583
522
|
}
|
|
584
523
|
/** Renders an array of files using the `FileWidget`
|
|
585
524
|
*/
|
|
586
|
-
|
|
587
|
-
|
|
588
525
|
renderFiles() {
|
|
589
526
|
const {
|
|
590
527
|
schema,
|
|
@@ -634,8 +571,6 @@ class ArrayField extends Component {
|
|
|
634
571
|
}
|
|
635
572
|
/** Renders an array that has a maximum limit of items
|
|
636
573
|
*/
|
|
637
|
-
|
|
638
|
-
|
|
639
574
|
renderFixedArray() {
|
|
640
575
|
const {
|
|
641
576
|
schema,
|
|
@@ -667,20 +602,15 @@ class ArrayField extends Component {
|
|
|
667
602
|
schemaUtils,
|
|
668
603
|
formContext
|
|
669
604
|
} = registry;
|
|
670
|
-
|
|
671
605
|
const _schemaItems = isObject(schema.items) ? schema.items : [];
|
|
672
|
-
|
|
673
606
|
const itemSchemas = _schemaItems.map((item, index) => schemaUtils.retrieveSchema(item, formData[index]));
|
|
674
|
-
|
|
675
607
|
const additionalSchema = isObject(schema.additionalItems) ? schemaUtils.retrieveSchema(schema.additionalItems, formData) : null;
|
|
676
|
-
|
|
677
608
|
if (!items || items.length < itemSchemas.length) {
|
|
678
609
|
// to make sure at least all fixed items are generated
|
|
679
610
|
items = items || [];
|
|
680
611
|
items = items.concat(new Array(itemSchemas.length - items.length));
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
|
|
612
|
+
}
|
|
613
|
+
// These are the props passed into the render function
|
|
684
614
|
const arrayProps = {
|
|
685
615
|
canAdd: this.canAddItem(items) && !!additionalSchema,
|
|
686
616
|
className: "field field-array field-array-fixed-items",
|
|
@@ -691,8 +621,8 @@ class ArrayField extends Component {
|
|
|
691
621
|
const {
|
|
692
622
|
key,
|
|
693
623
|
item
|
|
694
|
-
} = keyedItem;
|
|
695
|
-
|
|
624
|
+
} = keyedItem;
|
|
625
|
+
// While we are actually dealing with a single item of type T, the types require a T[], so cast
|
|
696
626
|
const itemCast = item;
|
|
697
627
|
const additional = index >= itemSchemas.length;
|
|
698
628
|
const itemSchema = additional && isObject(schema.additionalItems) ? schemaUtils.retrieveSchema(schema.additionalItems, itemCast) : itemSchemas[index];
|
|
@@ -703,7 +633,7 @@ class ArrayField extends Component {
|
|
|
703
633
|
return this.renderArrayFieldItem({
|
|
704
634
|
key,
|
|
705
635
|
index,
|
|
706
|
-
name: name && name
|
|
636
|
+
name: name && `${name}-${index}`,
|
|
707
637
|
canRemove: additional,
|
|
708
638
|
canMoveUp: index >= itemSchemas.length + 1,
|
|
709
639
|
canMoveDown: additional && index < items.length - 1,
|
|
@@ -729,7 +659,8 @@ class ArrayField extends Component {
|
|
|
729
659
|
rawErrors
|
|
730
660
|
};
|
|
731
661
|
const Template = getTemplate("ArrayFieldTemplate", registry, uiOptions);
|
|
732
|
-
return /*#__PURE__*/React.createElement(Template, {
|
|
662
|
+
return /*#__PURE__*/React.createElement(Template, {
|
|
663
|
+
...arrayProps
|
|
733
664
|
});
|
|
734
665
|
}
|
|
735
666
|
/** Renders the individual array item using a `SchemaField` along with the additional properties required to be send
|
|
@@ -737,8 +668,6 @@ class ArrayField extends Component {
|
|
|
737
668
|
*
|
|
738
669
|
* @param props - The props for the individual array item to be rendered
|
|
739
670
|
*/
|
|
740
|
-
|
|
741
|
-
|
|
742
671
|
renderArrayFieldItem(props) {
|
|
743
672
|
const {
|
|
744
673
|
key,
|
|
@@ -824,7 +753,6 @@ class ArrayField extends Component {
|
|
|
824
753
|
uiSchema: itemUiSchema
|
|
825
754
|
};
|
|
826
755
|
}
|
|
827
|
-
|
|
828
756
|
}
|
|
829
757
|
|
|
830
758
|
/** The `BooleanField` component is used to render a field in the schema is boolean. It constructs `enumOptions` for the
|
|
@@ -832,7 +760,6 @@ class ArrayField extends Component {
|
|
|
832
760
|
*
|
|
833
761
|
* @param props - The `FieldProps` for this template
|
|
834
762
|
*/
|
|
835
|
-
|
|
836
763
|
function BooleanField(props) {
|
|
837
764
|
const {
|
|
838
765
|
schema,
|
|
@@ -863,27 +790,22 @@ function BooleanField(props) {
|
|
|
863
790
|
} = getUiOptions(uiSchema);
|
|
864
791
|
const Widget = getWidget(schema, widget, widgets);
|
|
865
792
|
let enumOptions;
|
|
866
|
-
|
|
867
793
|
if (Array.isArray(schema.oneOf)) {
|
|
868
794
|
enumOptions = optionsList({
|
|
869
795
|
oneOf: schema.oneOf.map(option => {
|
|
870
796
|
if (isObject(option)) {
|
|
871
|
-
return {
|
|
797
|
+
return {
|
|
798
|
+
...option,
|
|
872
799
|
title: option.title || (option.const === true ? "Yes" : "No")
|
|
873
800
|
};
|
|
874
801
|
}
|
|
875
|
-
|
|
876
802
|
return undefined;
|
|
877
803
|
}).filter(o => o) // cast away the error that typescript can't grok is fixed
|
|
878
|
-
|
|
879
804
|
});
|
|
880
805
|
} else {
|
|
881
|
-
var _schema$enum;
|
|
882
|
-
|
|
883
806
|
// We deprecated enumNames in v5. It's intentionally omitted from RSJFSchema type, so we need to cast here.
|
|
884
807
|
const schemaWithEnumNames = schema;
|
|
885
|
-
const enums =
|
|
886
|
-
|
|
808
|
+
const enums = schema.enum ?? [true, false];
|
|
887
809
|
if (!schemaWithEnumNames.enumNames && enums.length === 2 && enums.every(v => typeof v === "boolean")) {
|
|
888
810
|
enumOptions = [{
|
|
889
811
|
value: enums[0],
|
|
@@ -900,9 +822,9 @@ function BooleanField(props) {
|
|
|
900
822
|
});
|
|
901
823
|
}
|
|
902
824
|
}
|
|
903
|
-
|
|
904
825
|
return /*#__PURE__*/React.createElement(Widget, {
|
|
905
|
-
options: {
|
|
826
|
+
options: {
|
|
827
|
+
...options,
|
|
906
828
|
enumOptions
|
|
907
829
|
},
|
|
908
830
|
schema: schema,
|
|
@@ -928,7 +850,6 @@ function BooleanField(props) {
|
|
|
928
850
|
*
|
|
929
851
|
* @param props - The `FieldProps` for this template
|
|
930
852
|
*/
|
|
931
|
-
|
|
932
853
|
class AnyOfField extends Component {
|
|
933
854
|
/** Constructs an `AnyOfField` with the given `props` to initialize the initially selected option in state
|
|
934
855
|
*
|
|
@@ -936,7 +857,6 @@ class AnyOfField extends Component {
|
|
|
936
857
|
*/
|
|
937
858
|
constructor(props) {
|
|
938
859
|
super(props);
|
|
939
|
-
|
|
940
860
|
this.onOptionChange = option => {
|
|
941
861
|
const selectedOption = parseInt(option, 10);
|
|
942
862
|
const {
|
|
@@ -948,16 +868,15 @@ class AnyOfField extends Component {
|
|
|
948
868
|
const {
|
|
949
869
|
schemaUtils
|
|
950
870
|
} = registry;
|
|
951
|
-
const newOption = schemaUtils.retrieveSchema(options[selectedOption], formData);
|
|
871
|
+
const newOption = schemaUtils.retrieveSchema(options[selectedOption], formData);
|
|
872
|
+
// If the new option is of type object and the current data is an object,
|
|
952
873
|
// discard properties added using the old option.
|
|
953
|
-
|
|
954
874
|
let newFormData = undefined;
|
|
955
|
-
|
|
956
875
|
if (guessType(formData) === "object" && (newOption.type === "object" || newOption.properties)) {
|
|
957
876
|
newFormData = Object.assign({}, formData);
|
|
958
877
|
const optionsToDiscard = options.slice();
|
|
959
|
-
optionsToDiscard.splice(selectedOption, 1);
|
|
960
|
-
|
|
878
|
+
optionsToDiscard.splice(selectedOption, 1);
|
|
879
|
+
// Discard any data added using other options
|
|
961
880
|
for (const option of optionsToDiscard) {
|
|
962
881
|
if (option.properties) {
|
|
963
882
|
for (const key in option.properties) {
|
|
@@ -967,15 +886,13 @@ class AnyOfField extends Component {
|
|
|
967
886
|
}
|
|
968
887
|
}
|
|
969
888
|
}
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
|
|
889
|
+
}
|
|
890
|
+
// Call getDefaultFormState to make sure defaults are populated on change.
|
|
973
891
|
onChange(schemaUtils.getDefaultFormState(options[selectedOption], newFormData), undefined, this.getFieldId());
|
|
974
892
|
this.setState({
|
|
975
893
|
selectedOption: parseInt(option, 10)
|
|
976
894
|
});
|
|
977
895
|
};
|
|
978
|
-
|
|
979
896
|
const {
|
|
980
897
|
formData: _formData,
|
|
981
898
|
options: _options
|
|
@@ -990,8 +907,6 @@ class AnyOfField extends Component {
|
|
|
990
907
|
* @param prevProps - The previous `FieldProps` for this template
|
|
991
908
|
* @param prevState - The previous `AnyOfFieldState` for this template
|
|
992
909
|
*/
|
|
993
|
-
|
|
994
|
-
|
|
995
910
|
componentDidUpdate(prevProps, prevState) {
|
|
996
911
|
const {
|
|
997
912
|
formData,
|
|
@@ -1001,14 +916,11 @@ class AnyOfField extends Component {
|
|
|
1001
916
|
const {
|
|
1002
917
|
selectedOption
|
|
1003
918
|
} = this.state;
|
|
1004
|
-
|
|
1005
919
|
if (!deepEquals(formData, prevProps.formData) && idSchema.$id === prevProps.idSchema.$id) {
|
|
1006
920
|
const matchingOption = this.getMatchingOption(selectedOption, formData, options);
|
|
1007
|
-
|
|
1008
921
|
if (!prevState || matchingOption === selectedOption) {
|
|
1009
922
|
return;
|
|
1010
923
|
}
|
|
1011
|
-
|
|
1012
924
|
this.setState({
|
|
1013
925
|
selectedOption: matchingOption
|
|
1014
926
|
});
|
|
@@ -1020,20 +932,16 @@ class AnyOfField extends Component {
|
|
|
1020
932
|
* @param options - The list of options to choose from
|
|
1021
933
|
* @return - The index of the `option` that best matches the `formData`
|
|
1022
934
|
*/
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
935
|
getMatchingOption(selectedOption, formData, options) {
|
|
1026
936
|
const {
|
|
1027
937
|
schemaUtils
|
|
1028
938
|
} = this.props.registry;
|
|
1029
939
|
const option = schemaUtils.getMatchingOption(formData, options);
|
|
1030
|
-
|
|
1031
940
|
if (option !== 0) {
|
|
1032
941
|
return option;
|
|
1033
|
-
}
|
|
942
|
+
}
|
|
943
|
+
// If the form data matches none of the options, use the currently selected
|
|
1034
944
|
// option, assuming it's available; otherwise use the first option
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
945
|
return selectedOption || 0;
|
|
1038
946
|
}
|
|
1039
947
|
/** Callback handler to remember what the currently selected option is. In addition to that the `formData` is updated
|
|
@@ -1043,18 +951,15 @@ class AnyOfField extends Component {
|
|
|
1043
951
|
* @param option -
|
|
1044
952
|
*/
|
|
1045
953
|
|
|
1046
|
-
|
|
1047
954
|
getFieldId() {
|
|
1048
955
|
const {
|
|
1049
956
|
idSchema,
|
|
1050
957
|
schema
|
|
1051
958
|
} = this.props;
|
|
1052
|
-
return
|
|
959
|
+
return `${idSchema.$id}${schema.oneOf ? "__oneof_select" : "__anyof_select"}`;
|
|
1053
960
|
}
|
|
1054
961
|
/** Renders the `AnyOfField` selector along with a `SchemaField` for the value of the `formData`
|
|
1055
962
|
*/
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
963
|
render() {
|
|
1059
964
|
const {
|
|
1060
965
|
name,
|
|
@@ -1094,7 +999,6 @@ class AnyOfField extends Component {
|
|
|
1094
999
|
}, widget, widgets);
|
|
1095
1000
|
const option = options[selectedOption] || null;
|
|
1096
1001
|
let optionSchema;
|
|
1097
|
-
|
|
1098
1002
|
if (option) {
|
|
1099
1003
|
// If the subschema doesn't declare a type, infer the type from the
|
|
1100
1004
|
// parent schema
|
|
@@ -1102,9 +1006,8 @@ class AnyOfField extends Component {
|
|
|
1102
1006
|
type: baseType
|
|
1103
1007
|
});
|
|
1104
1008
|
}
|
|
1105
|
-
|
|
1106
1009
|
const enumOptions = options.map((option, index) => ({
|
|
1107
|
-
label: option.title ||
|
|
1010
|
+
label: option.title || `Option ${index + 1}`,
|
|
1108
1011
|
value: index
|
|
1109
1012
|
}));
|
|
1110
1013
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -1147,18 +1050,17 @@ class AnyOfField extends Component {
|
|
|
1147
1050
|
hideError: hideError
|
|
1148
1051
|
}));
|
|
1149
1052
|
}
|
|
1150
|
-
|
|
1151
1053
|
}
|
|
1152
1054
|
|
|
1055
|
+
// Matches a string that ends in a . character, optionally followed by a sequence of
|
|
1153
1056
|
// digits followed by any number of 0 characters up until the end of the line.
|
|
1154
1057
|
// Ensuring that there is at least one prefixed character is important so that
|
|
1155
1058
|
// you don't incorrectly match against "0".
|
|
1156
|
-
|
|
1157
|
-
|
|
1059
|
+
const trailingCharMatcherWithPrefix = /\.([0-9]*0)*$/;
|
|
1060
|
+
// This is used for trimming the trailing 0 and . characters without affecting
|
|
1158
1061
|
// the rest of the string. Its possible to use one RegEx with groups for this
|
|
1159
1062
|
// functionality, but it is fairly complex compared to simply defining two
|
|
1160
1063
|
// different matchers.
|
|
1161
|
-
|
|
1162
1064
|
const trailingCharMatcher = /[0.]0*$/;
|
|
1163
1065
|
/**
|
|
1164
1066
|
* The NumberField class has some special handling for dealing with trailing
|
|
@@ -1177,7 +1079,6 @@ const trailingCharMatcher = /[0.]0*$/;
|
|
|
1177
1079
|
* value cached in the state. If it matches the cached value, the cached
|
|
1178
1080
|
* value is passed to the input instead of the formData value
|
|
1179
1081
|
*/
|
|
1180
|
-
|
|
1181
1082
|
function NumberField(props) {
|
|
1182
1083
|
const {
|
|
1183
1084
|
registry,
|
|
@@ -1194,36 +1095,33 @@ function NumberField(props) {
|
|
|
1194
1095
|
*
|
|
1195
1096
|
* @param value - The current value for the change occurring
|
|
1196
1097
|
*/
|
|
1197
|
-
|
|
1198
1098
|
const handleChange = useCallback(value => {
|
|
1199
1099
|
// Cache the original value in component state
|
|
1200
|
-
setLastValue(value);
|
|
1100
|
+
setLastValue(value);
|
|
1101
|
+
// Normalize decimals that don't start with a zero character in advance so
|
|
1201
1102
|
// that the rest of the normalization logic is simpler
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1103
|
+
if (`${value}`.charAt(0) === ".") {
|
|
1104
|
+
value = `0${value}`;
|
|
1105
|
+
}
|
|
1106
|
+
// Check that the value is a string (this can happen if the widget used is a
|
|
1206
1107
|
// <select>, due to an enum declaration etc) then, if the value ends in a
|
|
1207
1108
|
// trailing decimal point or multiple zeroes, strip the trailing values
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
1109
|
const processed = typeof value === "string" && value.match(trailingCharMatcherWithPrefix) ? asNumber(value.replace(trailingCharMatcher, "")) : asNumber(value);
|
|
1211
1110
|
onChange(processed);
|
|
1212
1111
|
}, [onChange]);
|
|
1213
|
-
|
|
1214
1112
|
if (typeof lastValue === "string" && typeof value === "number") {
|
|
1215
1113
|
// Construct a regular expression that checks for a string that consists
|
|
1216
1114
|
// of the formData value suffixed with zero or one '.' characters and zero
|
|
1217
1115
|
// or more '0' characters
|
|
1218
|
-
const re = new RegExp(
|
|
1116
|
+
const re = new RegExp(`${value}`.replace(".", "\\.") + "\\.?0*$");
|
|
1117
|
+
// If the cached "lastValue" is a match, use that instead of the formData
|
|
1219
1118
|
// value to prevent the input value from changing in the UI
|
|
1220
|
-
|
|
1221
1119
|
if (lastValue.match(re)) {
|
|
1222
1120
|
value = lastValue;
|
|
1223
1121
|
}
|
|
1224
1122
|
}
|
|
1225
|
-
|
|
1226
|
-
|
|
1123
|
+
return /*#__PURE__*/React.createElement(StringField, {
|
|
1124
|
+
...props,
|
|
1227
1125
|
formData: value,
|
|
1228
1126
|
onChange: handleChange
|
|
1229
1127
|
});
|
|
@@ -1234,30 +1132,25 @@ function NumberField(props) {
|
|
|
1234
1132
|
*
|
|
1235
1133
|
* @param props - The `FieldProps` for this template
|
|
1236
1134
|
*/
|
|
1237
|
-
|
|
1238
1135
|
class ObjectField extends Component {
|
|
1239
1136
|
constructor() {
|
|
1240
1137
|
var _this;
|
|
1241
|
-
|
|
1242
1138
|
super(...arguments);
|
|
1243
1139
|
_this = this;
|
|
1244
1140
|
this.state = {
|
|
1245
1141
|
wasPropertyKeyModified: false,
|
|
1246
1142
|
additionalProperties: {}
|
|
1247
1143
|
};
|
|
1248
|
-
|
|
1249
1144
|
this.onPropertyChange = function (name, addedByAdditionalProperties) {
|
|
1250
1145
|
if (addedByAdditionalProperties === void 0) {
|
|
1251
1146
|
addedByAdditionalProperties = false;
|
|
1252
1147
|
}
|
|
1253
|
-
|
|
1254
1148
|
return (value, newErrorSchema, id) => {
|
|
1255
1149
|
const {
|
|
1256
1150
|
formData,
|
|
1257
1151
|
onChange,
|
|
1258
1152
|
errorSchema
|
|
1259
1153
|
} = _this.props;
|
|
1260
|
-
|
|
1261
1154
|
if (value === undefined && addedByAdditionalProperties) {
|
|
1262
1155
|
// Don't set value = undefined for fields added by
|
|
1263
1156
|
// additionalProperties. Doing so removes them from the
|
|
@@ -1268,16 +1161,16 @@ class ObjectField extends Component {
|
|
|
1268
1161
|
// set empty values to the empty string.
|
|
1269
1162
|
value = "";
|
|
1270
1163
|
}
|
|
1271
|
-
|
|
1272
|
-
|
|
1164
|
+
const newFormData = {
|
|
1165
|
+
...formData,
|
|
1273
1166
|
[name]: value
|
|
1274
1167
|
};
|
|
1275
|
-
onChange(newFormData, errorSchema && errorSchema && {
|
|
1168
|
+
onChange(newFormData, errorSchema && errorSchema && {
|
|
1169
|
+
...errorSchema,
|
|
1276
1170
|
[name]: newErrorSchema
|
|
1277
1171
|
}, id);
|
|
1278
1172
|
};
|
|
1279
1173
|
};
|
|
1280
|
-
|
|
1281
1174
|
this.onDropPropertyClick = key => {
|
|
1282
1175
|
return event => {
|
|
1283
1176
|
event.preventDefault();
|
|
@@ -1285,13 +1178,13 @@ class ObjectField extends Component {
|
|
|
1285
1178
|
onChange,
|
|
1286
1179
|
formData
|
|
1287
1180
|
} = this.props;
|
|
1288
|
-
const copiedFormData = {
|
|
1181
|
+
const copiedFormData = {
|
|
1182
|
+
...formData
|
|
1289
1183
|
};
|
|
1290
1184
|
unset(copiedFormData, key);
|
|
1291
1185
|
onChange(copiedFormData);
|
|
1292
1186
|
};
|
|
1293
1187
|
};
|
|
1294
|
-
|
|
1295
1188
|
this.getAvailableKey = (preferredKey, formData) => {
|
|
1296
1189
|
const {
|
|
1297
1190
|
uiSchema
|
|
@@ -1301,27 +1194,24 @@ class ObjectField extends Component {
|
|
|
1301
1194
|
} = getUiOptions(uiSchema);
|
|
1302
1195
|
let index = 0;
|
|
1303
1196
|
let newKey = preferredKey;
|
|
1304
|
-
|
|
1305
1197
|
while (newKey in formData) {
|
|
1306
|
-
newKey =
|
|
1198
|
+
newKey = `${preferredKey}${duplicateKeySuffixSeparator}${++index}`;
|
|
1307
1199
|
}
|
|
1308
|
-
|
|
1309
1200
|
return newKey;
|
|
1310
1201
|
};
|
|
1311
|
-
|
|
1312
1202
|
this.onKeyChange = oldValue => {
|
|
1313
1203
|
return (value, newErrorSchema) => {
|
|
1314
1204
|
if (oldValue === value) {
|
|
1315
1205
|
return;
|
|
1316
1206
|
}
|
|
1317
|
-
|
|
1318
1207
|
const {
|
|
1319
1208
|
formData,
|
|
1320
1209
|
onChange,
|
|
1321
1210
|
errorSchema
|
|
1322
1211
|
} = this.props;
|
|
1323
1212
|
value = this.getAvailableKey(value, formData);
|
|
1324
|
-
const newFormData = {
|
|
1213
|
+
const newFormData = {
|
|
1214
|
+
...formData
|
|
1325
1215
|
};
|
|
1326
1216
|
const newKeys = {
|
|
1327
1217
|
[oldValue]: value
|
|
@@ -1336,29 +1226,27 @@ class ObjectField extends Component {
|
|
|
1336
1226
|
this.setState({
|
|
1337
1227
|
wasPropertyKeyModified: true
|
|
1338
1228
|
});
|
|
1339
|
-
onChange(renamedObj, errorSchema && errorSchema && {
|
|
1229
|
+
onChange(renamedObj, errorSchema && errorSchema && {
|
|
1230
|
+
...errorSchema,
|
|
1340
1231
|
[value]: newErrorSchema
|
|
1341
1232
|
});
|
|
1342
1233
|
};
|
|
1343
1234
|
};
|
|
1344
|
-
|
|
1345
1235
|
this.handleAddClick = schema => () => {
|
|
1346
1236
|
if (!schema.additionalProperties) {
|
|
1347
1237
|
return;
|
|
1348
1238
|
}
|
|
1349
|
-
|
|
1350
1239
|
const {
|
|
1351
1240
|
formData,
|
|
1352
1241
|
onChange,
|
|
1353
1242
|
registry
|
|
1354
1243
|
} = this.props;
|
|
1355
|
-
const newFormData = {
|
|
1244
|
+
const newFormData = {
|
|
1245
|
+
...formData
|
|
1356
1246
|
};
|
|
1357
1247
|
let type = undefined;
|
|
1358
|
-
|
|
1359
1248
|
if (isObject(schema.additionalProperties)) {
|
|
1360
1249
|
type = schema.additionalProperties.type;
|
|
1361
|
-
|
|
1362
1250
|
if (REF_KEY in schema.additionalProperties) {
|
|
1363
1251
|
const {
|
|
1364
1252
|
schemaUtils
|
|
@@ -1369,14 +1257,12 @@ class ObjectField extends Component {
|
|
|
1369
1257
|
type = refSchema.type;
|
|
1370
1258
|
}
|
|
1371
1259
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1260
|
+
const newKey = this.getAvailableKey("newKey", newFormData);
|
|
1261
|
+
// Cast this to make the `set` work properly
|
|
1375
1262
|
set(newFormData, newKey, this.getDefaultValue(type));
|
|
1376
1263
|
onChange(newFormData);
|
|
1377
1264
|
};
|
|
1378
1265
|
}
|
|
1379
|
-
|
|
1380
1266
|
/** Returns a flag indicating whether the `name` field is required in the object schema
|
|
1381
1267
|
*
|
|
1382
1268
|
* @param name - The name of the field to check for required-ness
|
|
@@ -1397,7 +1283,6 @@ class ObjectField extends Component {
|
|
|
1397
1283
|
* @returns - The onPropertyChange callback for the `name` property
|
|
1398
1284
|
*/
|
|
1399
1285
|
|
|
1400
|
-
|
|
1401
1286
|
/** Returns a default value to be used for a new additional schema property of the given `type`
|
|
1402
1287
|
*
|
|
1403
1288
|
* @param type - The type of the new additional schema property
|
|
@@ -1406,22 +1291,16 @@ class ObjectField extends Component {
|
|
|
1406
1291
|
switch (type) {
|
|
1407
1292
|
case "string":
|
|
1408
1293
|
return "New Value";
|
|
1409
|
-
|
|
1410
1294
|
case "array":
|
|
1411
1295
|
return [];
|
|
1412
|
-
|
|
1413
1296
|
case "boolean":
|
|
1414
1297
|
return false;
|
|
1415
|
-
|
|
1416
1298
|
case "null":
|
|
1417
1299
|
return null;
|
|
1418
|
-
|
|
1419
1300
|
case "number":
|
|
1420
1301
|
return 0;
|
|
1421
|
-
|
|
1422
1302
|
case "object":
|
|
1423
1303
|
return {};
|
|
1424
|
-
|
|
1425
1304
|
default:
|
|
1426
1305
|
// We don't have a datatype for some reason (perhaps additionalProperties was true)
|
|
1427
1306
|
return "New Value";
|
|
@@ -1433,7 +1312,6 @@ class ObjectField extends Component {
|
|
|
1433
1312
|
* @param schema - The schema element to which the new property is being added
|
|
1434
1313
|
*/
|
|
1435
1314
|
|
|
1436
|
-
|
|
1437
1315
|
/** Renders the `ObjectField` from the given props
|
|
1438
1316
|
*/
|
|
1439
1317
|
render() {
|
|
@@ -1470,7 +1348,6 @@ class ObjectField extends Component {
|
|
|
1470
1348
|
const title = schema.title === undefined ? name : schema.title;
|
|
1471
1349
|
const description = uiOptions.description || schema.description;
|
|
1472
1350
|
let orderedProperties;
|
|
1473
|
-
|
|
1474
1351
|
try {
|
|
1475
1352
|
const properties = Object.keys(schemaProperties);
|
|
1476
1353
|
orderedProperties = orderProperties(properties, uiOptions.order);
|
|
@@ -1482,7 +1359,6 @@ class ObjectField extends Component {
|
|
|
1482
1359
|
}
|
|
1483
1360
|
}, "Invalid ", name || "root", " object field configuration:", /*#__PURE__*/React.createElement("em", null, err.message), "."), /*#__PURE__*/React.createElement("pre", null, JSON.stringify(schema)));
|
|
1484
1361
|
}
|
|
1485
|
-
|
|
1486
1362
|
const Template = getTemplate("ObjectFieldTemplate", registry, uiOptions);
|
|
1487
1363
|
const templateProps = {
|
|
1488
1364
|
title: uiOptions.title || title,
|
|
@@ -1533,15 +1409,14 @@ class ObjectField extends Component {
|
|
|
1533
1409
|
formContext,
|
|
1534
1410
|
registry
|
|
1535
1411
|
};
|
|
1536
|
-
return /*#__PURE__*/React.createElement(Template, {
|
|
1412
|
+
return /*#__PURE__*/React.createElement(Template, {
|
|
1413
|
+
...templateProps,
|
|
1537
1414
|
onAddClick: this.handleAddClick
|
|
1538
1415
|
});
|
|
1539
1416
|
}
|
|
1540
|
-
|
|
1541
1417
|
}
|
|
1542
1418
|
|
|
1543
1419
|
/** The map of component type to FieldName */
|
|
1544
|
-
|
|
1545
1420
|
const COMPONENT_TYPES = {
|
|
1546
1421
|
array: "ArrayField",
|
|
1547
1422
|
boolean: "BooleanField",
|
|
@@ -1561,36 +1436,31 @@ const COMPONENT_TYPES = {
|
|
|
1561
1436
|
* @param registry - The registry from which fields and templates are obtained
|
|
1562
1437
|
* @returns - The `Field` component that is used to render the actual field data
|
|
1563
1438
|
*/
|
|
1564
|
-
|
|
1565
1439
|
function getFieldComponent(schema, uiOptions, idSchema, registry) {
|
|
1566
1440
|
const field = uiOptions.field;
|
|
1567
1441
|
const {
|
|
1568
1442
|
fields
|
|
1569
1443
|
} = registry;
|
|
1570
|
-
|
|
1571
1444
|
if (typeof field === "function") {
|
|
1572
1445
|
return field;
|
|
1573
1446
|
}
|
|
1574
|
-
|
|
1575
1447
|
if (typeof field === "string" && field in fields) {
|
|
1576
1448
|
return fields[field];
|
|
1577
1449
|
}
|
|
1578
|
-
|
|
1579
1450
|
const schemaType = getSchemaType(schema);
|
|
1580
1451
|
const type = Array.isArray(schemaType) ? schemaType[0] : schemaType || "";
|
|
1581
|
-
const componentName = COMPONENT_TYPES[type];
|
|
1452
|
+
const componentName = COMPONENT_TYPES[type];
|
|
1453
|
+
// If the type is not defined and the schema uses 'anyOf' or 'oneOf', don't
|
|
1582
1454
|
// render a field and let the MultiSchemaField component handle the form display
|
|
1583
|
-
|
|
1584
1455
|
if (!componentName && (schema.anyOf || schema.oneOf)) {
|
|
1585
1456
|
return () => null;
|
|
1586
1457
|
}
|
|
1587
|
-
|
|
1588
1458
|
return componentName in fields ? fields[componentName] : () => {
|
|
1589
1459
|
const UnsupportedFieldTemplate = getTemplate("UnsupportedFieldTemplate", registry, uiOptions);
|
|
1590
1460
|
return /*#__PURE__*/React.createElement(UnsupportedFieldTemplate, {
|
|
1591
1461
|
schema: schema,
|
|
1592
1462
|
idSchema: idSchema,
|
|
1593
|
-
reason:
|
|
1463
|
+
reason: `Unknown field type ${schema.type}`,
|
|
1594
1464
|
registry: registry
|
|
1595
1465
|
});
|
|
1596
1466
|
};
|
|
@@ -1601,8 +1471,6 @@ function getFieldComponent(schema, uiOptions, idSchema, registry) {
|
|
|
1601
1471
|
*
|
|
1602
1472
|
* @param props - The `FieldProps` for this component
|
|
1603
1473
|
*/
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
1474
|
function SchemaFieldRender(props) {
|
|
1607
1475
|
const {
|
|
1608
1476
|
schema: _schema,
|
|
@@ -1635,7 +1503,6 @@ function SchemaFieldRender(props) {
|
|
|
1635
1503
|
/** Intermediary `onChange` handler for field components that will inject the `id` of the current field into the
|
|
1636
1504
|
* `onChange` chain if it is not already being provided from a deeper level in the hierarchy
|
|
1637
1505
|
*/
|
|
1638
|
-
|
|
1639
1506
|
const handleFieldComponentChange = React.useCallback((formData, newErrorSchema, id) => {
|
|
1640
1507
|
const theId = id || fieldId;
|
|
1641
1508
|
return onChange(formData, newErrorSchema, theId);
|
|
@@ -1643,28 +1510,25 @@ function SchemaFieldRender(props) {
|
|
|
1643
1510
|
const FieldComponent = getFieldComponent(schema, uiOptions, idSchema, registry);
|
|
1644
1511
|
const disabled = Boolean(props.disabled || uiOptions.disabled);
|
|
1645
1512
|
const readonly = Boolean(props.readonly || uiOptions.readonly || props.schema.readOnly || schema.readOnly);
|
|
1646
|
-
const uiSchemaHideError = uiOptions.hideError;
|
|
1647
|
-
|
|
1513
|
+
const uiSchemaHideError = uiOptions.hideError;
|
|
1514
|
+
// Set hideError to the value provided in the uiSchema, otherwise stick with the prop to propagate to children
|
|
1648
1515
|
const hideError = uiSchemaHideError === undefined ? props.hideError : Boolean(uiSchemaHideError);
|
|
1649
1516
|
const autofocus = Boolean(props.autofocus || uiOptions.autofocus);
|
|
1650
|
-
|
|
1651
1517
|
if (Object.keys(schema).length === 0) {
|
|
1652
1518
|
return null;
|
|
1653
1519
|
}
|
|
1654
|
-
|
|
1655
1520
|
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema);
|
|
1656
1521
|
const {
|
|
1657
1522
|
__errors,
|
|
1658
1523
|
...fieldErrorSchema
|
|
1659
|
-
} = errorSchema || {};
|
|
1660
|
-
|
|
1524
|
+
} = errorSchema || {};
|
|
1525
|
+
// See #439: uiSchema: Don't pass consumed class names to child components
|
|
1661
1526
|
const fieldUiSchema = omit(uiSchema, ["ui:classNames", "classNames"]);
|
|
1662
|
-
|
|
1663
1527
|
if ("ui:options" in fieldUiSchema) {
|
|
1664
1528
|
fieldUiSchema["ui:options"] = omit(fieldUiSchema["ui:options"], ["classNames"]);
|
|
1665
1529
|
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1530
|
+
const field = /*#__PURE__*/React.createElement(FieldComponent, {
|
|
1531
|
+
...props,
|
|
1668
1532
|
onChange: handleFieldComponentChange,
|
|
1669
1533
|
idSchema: idSchema,
|
|
1670
1534
|
schema: schema,
|
|
@@ -1677,37 +1541,30 @@ function SchemaFieldRender(props) {
|
|
|
1677
1541
|
formContext: formContext,
|
|
1678
1542
|
rawErrors: __errors
|
|
1679
1543
|
});
|
|
1680
|
-
const id = idSchema[ID_KEY];
|
|
1681
|
-
|
|
1544
|
+
const id = idSchema[ID_KEY];
|
|
1545
|
+
// If this schema has a title defined, but the user has set a new key/label, retain their input.
|
|
1682
1546
|
let label;
|
|
1683
|
-
|
|
1684
1547
|
if (wasPropertyKeyModified) {
|
|
1685
1548
|
label = name;
|
|
1686
1549
|
} else {
|
|
1687
1550
|
label = ADDITIONAL_PROPERTY_FLAG in schema ? name : uiOptions.title || props.schema.title || schema.title || name;
|
|
1688
1551
|
}
|
|
1689
|
-
|
|
1690
1552
|
const description = uiOptions.description || props.schema.description || schema.description || "";
|
|
1691
1553
|
const help = uiOptions.help;
|
|
1692
1554
|
const hidden = uiOptions.widget === "hidden";
|
|
1693
|
-
const classNames = ["form-group", "field",
|
|
1694
|
-
|
|
1555
|
+
const classNames = ["form-group", "field", `field-${schema.type}`];
|
|
1695
1556
|
if (!hideError && __errors && __errors.length > 0) {
|
|
1696
1557
|
classNames.push("field-error has-error has-danger");
|
|
1697
1558
|
}
|
|
1698
|
-
|
|
1699
1559
|
if (uiSchema !== null && uiSchema !== void 0 && uiSchema.classNames) {
|
|
1700
1560
|
if (process.env.NODE_ENV !== "production") {
|
|
1701
1561
|
console.warn("'uiSchema.classNames' is deprecated and may be removed in a major release; Use 'ui:classNames' instead.");
|
|
1702
1562
|
}
|
|
1703
|
-
|
|
1704
1563
|
classNames.push(uiSchema.classNames);
|
|
1705
1564
|
}
|
|
1706
|
-
|
|
1707
1565
|
if (uiOptions.classNames) {
|
|
1708
1566
|
classNames.push(uiOptions.classNames);
|
|
1709
1567
|
}
|
|
1710
|
-
|
|
1711
1568
|
const helpComponent = /*#__PURE__*/React.createElement(FieldHelpTemplate, {
|
|
1712
1569
|
help: help,
|
|
1713
1570
|
idSchema: idSchema,
|
|
@@ -1726,7 +1583,7 @@ function SchemaFieldRender(props) {
|
|
|
1726
1583
|
});
|
|
1727
1584
|
const fieldProps = {
|
|
1728
1585
|
description: /*#__PURE__*/React.createElement(DescriptionFieldTemplate, {
|
|
1729
|
-
id: id
|
|
1586
|
+
id: `${id}__description`,
|
|
1730
1587
|
description: description,
|
|
1731
1588
|
schema: schema,
|
|
1732
1589
|
uiSchema: uiSchema,
|
|
@@ -1757,7 +1614,8 @@ function SchemaFieldRender(props) {
|
|
|
1757
1614
|
};
|
|
1758
1615
|
const _AnyOfField = registry.fields.AnyOfField;
|
|
1759
1616
|
const _OneOfField = registry.fields.OneOfField;
|
|
1760
|
-
return /*#__PURE__*/React.createElement(FieldTemplate, {
|
|
1617
|
+
return /*#__PURE__*/React.createElement(FieldTemplate, {
|
|
1618
|
+
...fieldProps
|
|
1761
1619
|
}, /*#__PURE__*/React.createElement(React.Fragment, null, field, schema.anyOf && !(uiSchema !== null && uiSchema !== void 0 && uiSchema["ui:field"]) && !schemaUtils.isSelect(schema) && /*#__PURE__*/React.createElement(_AnyOfField, {
|
|
1762
1620
|
name: name,
|
|
1763
1621
|
disabled: disabled,
|
|
@@ -1801,25 +1659,21 @@ function SchemaFieldRender(props) {
|
|
|
1801
1659
|
/** The `SchemaField` component determines whether it is necessary to rerender the component based on any props changes
|
|
1802
1660
|
* and if so, calls the `SchemaFieldRender` component with the props.
|
|
1803
1661
|
*/
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
1662
|
class SchemaField extends React.Component {
|
|
1807
1663
|
shouldComponentUpdate(nextProps) {
|
|
1808
1664
|
return !deepEquals(this.props, nextProps);
|
|
1809
1665
|
}
|
|
1810
|
-
|
|
1811
1666
|
render() {
|
|
1812
|
-
return /*#__PURE__*/React.createElement(SchemaFieldRender, {
|
|
1667
|
+
return /*#__PURE__*/React.createElement(SchemaFieldRender, {
|
|
1668
|
+
...this.props
|
|
1813
1669
|
});
|
|
1814
1670
|
}
|
|
1815
|
-
|
|
1816
1671
|
}
|
|
1817
1672
|
|
|
1818
1673
|
/** The `StringField` component is used to render a schema field that represents a string type
|
|
1819
1674
|
*
|
|
1820
1675
|
* @param props - The `FieldProps` for this template
|
|
1821
1676
|
*/
|
|
1822
|
-
|
|
1823
1677
|
function StringField(props) {
|
|
1824
1678
|
const {
|
|
1825
1679
|
schema,
|
|
@@ -1848,11 +1702,9 @@ function StringField(props) {
|
|
|
1848
1702
|
} = registry;
|
|
1849
1703
|
const enumOptions = schemaUtils.isSelect(schema) ? optionsList(schema) : undefined;
|
|
1850
1704
|
let defaultWidget = enumOptions ? "select" : "text";
|
|
1851
|
-
|
|
1852
1705
|
if (format && hasWidget(schema, format, widgets)) {
|
|
1853
1706
|
defaultWidget = format;
|
|
1854
1707
|
}
|
|
1855
|
-
|
|
1856
1708
|
const {
|
|
1857
1709
|
widget = defaultWidget,
|
|
1858
1710
|
placeholder = "",
|
|
@@ -1860,7 +1712,8 @@ function StringField(props) {
|
|
|
1860
1712
|
} = getUiOptions(uiSchema);
|
|
1861
1713
|
const Widget = getWidget(schema, widget, widgets);
|
|
1862
1714
|
return /*#__PURE__*/React.createElement(Widget, {
|
|
1863
|
-
options: {
|
|
1715
|
+
options: {
|
|
1716
|
+
...options,
|
|
1864
1717
|
enumOptions
|
|
1865
1718
|
},
|
|
1866
1719
|
schema: schema,
|
|
@@ -1887,7 +1740,6 @@ function StringField(props) {
|
|
|
1887
1740
|
*
|
|
1888
1741
|
* @param props - The `FieldProps` for this template
|
|
1889
1742
|
*/
|
|
1890
|
-
|
|
1891
1743
|
function NullField(props) {
|
|
1892
1744
|
const {
|
|
1893
1745
|
formData,
|
|
@@ -1901,25 +1753,26 @@ function NullField(props) {
|
|
|
1901
1753
|
return null;
|
|
1902
1754
|
}
|
|
1903
1755
|
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1756
|
+
function fields() {
|
|
1757
|
+
return {
|
|
1758
|
+
AnyOfField: AnyOfField,
|
|
1759
|
+
ArrayField: ArrayField,
|
|
1760
|
+
// ArrayField falls back to SchemaField if ArraySchemaField is not defined, which it isn't by default
|
|
1761
|
+
BooleanField,
|
|
1762
|
+
NumberField,
|
|
1763
|
+
ObjectField,
|
|
1764
|
+
OneOfField: AnyOfField,
|
|
1765
|
+
SchemaField,
|
|
1766
|
+
StringField,
|
|
1767
|
+
NullField
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1916
1770
|
|
|
1917
1771
|
/** The `ArrayFieldDescriptionTemplate` component renders a `DescriptionFieldTemplate` with an `id` derived from
|
|
1918
1772
|
* the `idSchema`.
|
|
1919
1773
|
*
|
|
1920
1774
|
* @param props - The `ArrayFieldDescriptionProps` for the component
|
|
1921
1775
|
*/
|
|
1922
|
-
|
|
1923
1776
|
function ArrayFieldDescriptionTemplate(props) {
|
|
1924
1777
|
const {
|
|
1925
1778
|
idSchema,
|
|
@@ -1932,13 +1785,11 @@ function ArrayFieldDescriptionTemplate(props) {
|
|
|
1932
1785
|
const {
|
|
1933
1786
|
label: displayLabel = true
|
|
1934
1787
|
} = options;
|
|
1935
|
-
|
|
1936
1788
|
if (!description || !displayLabel) {
|
|
1937
1789
|
return null;
|
|
1938
1790
|
}
|
|
1939
|
-
|
|
1940
1791
|
const DescriptionFieldTemplate = getTemplate("DescriptionFieldTemplate", registry, options);
|
|
1941
|
-
const id = idSchema.$id
|
|
1792
|
+
const id = `${idSchema.$id}__description`;
|
|
1942
1793
|
return /*#__PURE__*/React.createElement(DescriptionFieldTemplate, {
|
|
1943
1794
|
id: id,
|
|
1944
1795
|
description: description,
|
|
@@ -1952,7 +1803,6 @@ function ArrayFieldDescriptionTemplate(props) {
|
|
|
1952
1803
|
*
|
|
1953
1804
|
* @param props - The `ArrayFieldTemplateItemType` props for the component
|
|
1954
1805
|
*/
|
|
1955
|
-
|
|
1956
1806
|
function ArrayFieldItemTemplate(props) {
|
|
1957
1807
|
const {
|
|
1958
1808
|
children,
|
|
@@ -2014,7 +1864,6 @@ function ArrayFieldItemTemplate(props) {
|
|
|
2014
1864
|
*
|
|
2015
1865
|
* @param props - The `ArrayFieldTemplateItemType` props for the component
|
|
2016
1866
|
*/
|
|
2017
|
-
|
|
2018
1867
|
function ArrayFieldTemplate(props) {
|
|
2019
1868
|
const {
|
|
2020
1869
|
canAdd,
|
|
@@ -2033,8 +1882,8 @@ function ArrayFieldTemplate(props) {
|
|
|
2033
1882
|
const uiOptions = getUiOptions(uiSchema);
|
|
2034
1883
|
const ArrayFieldDescriptionTemplate = getTemplate("ArrayFieldDescriptionTemplate", registry, uiOptions);
|
|
2035
1884
|
const ArrayFieldItemTemplate = getTemplate("ArrayFieldItemTemplate", registry, uiOptions);
|
|
2036
|
-
const ArrayFieldTitleTemplate = getTemplate("ArrayFieldTitleTemplate", registry, uiOptions);
|
|
2037
|
-
|
|
1885
|
+
const ArrayFieldTitleTemplate = getTemplate("ArrayFieldTitleTemplate", registry, uiOptions);
|
|
1886
|
+
// Button templates are not overridden in the uiSchema
|
|
2038
1887
|
const {
|
|
2039
1888
|
ButtonTemplates: {
|
|
2040
1889
|
AddButton
|
|
@@ -2080,7 +1929,6 @@ function ArrayFieldTemplate(props) {
|
|
|
2080
1929
|
*
|
|
2081
1930
|
* @param props - The `ArrayFieldTitleProps` for the component
|
|
2082
1931
|
*/
|
|
2083
|
-
|
|
2084
1932
|
function ArrayFieldTitleTemplate(props) {
|
|
2085
1933
|
const {
|
|
2086
1934
|
idSchema,
|
|
@@ -2094,13 +1942,11 @@ function ArrayFieldTitleTemplate(props) {
|
|
|
2094
1942
|
const {
|
|
2095
1943
|
label: displayLabel = true
|
|
2096
1944
|
} = options;
|
|
2097
|
-
|
|
2098
1945
|
if (!title || !displayLabel) {
|
|
2099
1946
|
return null;
|
|
2100
1947
|
}
|
|
2101
|
-
|
|
2102
1948
|
const TitleFieldTemplate = getTemplate("TitleFieldTemplate", registry, options);
|
|
2103
|
-
const id = idSchema.$id
|
|
1949
|
+
const id = `${idSchema.$id}__title`;
|
|
2104
1950
|
return /*#__PURE__*/React.createElement(TitleFieldTemplate, {
|
|
2105
1951
|
id: id,
|
|
2106
1952
|
title: title,
|
|
@@ -2117,7 +1963,6 @@ function ArrayFieldTitleTemplate(props) {
|
|
|
2117
1963
|
*
|
|
2118
1964
|
* @param props - The `WidgetProps` for this template
|
|
2119
1965
|
*/
|
|
2120
|
-
|
|
2121
1966
|
function BaseInputTemplate(props) {
|
|
2122
1967
|
const {
|
|
2123
1968
|
id,
|
|
@@ -2136,25 +1981,23 @@ function BaseInputTemplate(props) {
|
|
|
2136
1981
|
rawErrors,
|
|
2137
1982
|
type,
|
|
2138
1983
|
...rest
|
|
2139
|
-
} = props;
|
|
1984
|
+
} = props;
|
|
1985
|
+
// Note: since React 15.2.0 we can't forward unknown element attributes, so we
|
|
2140
1986
|
// exclude the "options" and "schema" ones here.
|
|
2141
|
-
|
|
2142
1987
|
if (!id) {
|
|
2143
1988
|
console.log("No id for", props);
|
|
2144
|
-
throw new Error(
|
|
1989
|
+
throw new Error(`no id for props ${JSON.stringify(props)}`);
|
|
2145
1990
|
}
|
|
2146
|
-
|
|
2147
|
-
|
|
1991
|
+
const inputProps = {
|
|
1992
|
+
...rest,
|
|
2148
1993
|
...getInputProps(schema, type, options)
|
|
2149
1994
|
};
|
|
2150
1995
|
let inputValue;
|
|
2151
|
-
|
|
2152
1996
|
if (inputProps.type === "number" || inputProps.type === "integer") {
|
|
2153
1997
|
inputValue = value || value === 0 ? value : "";
|
|
2154
1998
|
} else {
|
|
2155
1999
|
inputValue = value == null ? "" : value;
|
|
2156
2000
|
}
|
|
2157
|
-
|
|
2158
2001
|
const _onChange = useCallback(_ref => {
|
|
2159
2002
|
let {
|
|
2160
2003
|
target: {
|
|
@@ -2163,7 +2006,6 @@ function BaseInputTemplate(props) {
|
|
|
2163
2006
|
} = _ref;
|
|
2164
2007
|
return onChange(value === "" ? options.emptyValue : value);
|
|
2165
2008
|
}, [onChange, options]);
|
|
2166
|
-
|
|
2167
2009
|
const _onBlur = useCallback(_ref2 => {
|
|
2168
2010
|
let {
|
|
2169
2011
|
target: {
|
|
@@ -2172,7 +2014,6 @@ function BaseInputTemplate(props) {
|
|
|
2172
2014
|
} = _ref2;
|
|
2173
2015
|
return onBlur(id, value);
|
|
2174
2016
|
}, [onBlur, id]);
|
|
2175
|
-
|
|
2176
2017
|
const _onFocus = useCallback(_ref3 => {
|
|
2177
2018
|
let {
|
|
2178
2019
|
target: {
|
|
@@ -2181,7 +2022,6 @@ function BaseInputTemplate(props) {
|
|
|
2181
2022
|
} = _ref3;
|
|
2182
2023
|
return onFocus(id, value);
|
|
2183
2024
|
}, [onFocus, id]);
|
|
2184
|
-
|
|
2185
2025
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("input", {
|
|
2186
2026
|
id: id,
|
|
2187
2027
|
name: id,
|
|
@@ -2191,13 +2031,13 @@ function BaseInputTemplate(props) {
|
|
|
2191
2031
|
autoFocus: autofocus,
|
|
2192
2032
|
value: inputValue,
|
|
2193
2033
|
...inputProps,
|
|
2194
|
-
list: schema.examples ?
|
|
2034
|
+
list: schema.examples ? `examples_${id}` : undefined,
|
|
2195
2035
|
onChange: _onChange,
|
|
2196
2036
|
onBlur: _onBlur,
|
|
2197
2037
|
onFocus: _onFocus
|
|
2198
2038
|
}), Array.isArray(schema.examples) && /*#__PURE__*/React.createElement("datalist", {
|
|
2199
|
-
key:
|
|
2200
|
-
id:
|
|
2039
|
+
key: `datalist_${id}`,
|
|
2040
|
+
id: `examples_${id}`
|
|
2201
2041
|
}, [...new Set(schema.examples.concat(schema.default ? [schema.default] : []))].map(example => /*#__PURE__*/React.createElement("option", {
|
|
2202
2042
|
key: example,
|
|
2203
2043
|
value: example
|
|
@@ -2206,7 +2046,6 @@ function BaseInputTemplate(props) {
|
|
|
2206
2046
|
|
|
2207
2047
|
/** The `SubmitButton` renders a button that represent the `Submit` action on a form
|
|
2208
2048
|
*/
|
|
2209
|
-
|
|
2210
2049
|
function SubmitButton(_ref) {
|
|
2211
2050
|
let {
|
|
2212
2051
|
uiSchema
|
|
@@ -2216,15 +2055,13 @@ function SubmitButton(_ref) {
|
|
|
2216
2055
|
norender,
|
|
2217
2056
|
props: submitButtonProps = {}
|
|
2218
2057
|
} = getSubmitButtonOptions(uiSchema);
|
|
2219
|
-
|
|
2220
2058
|
if (norender) {
|
|
2221
2059
|
return null;
|
|
2222
2060
|
}
|
|
2223
|
-
|
|
2224
2061
|
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
|
|
2225
2062
|
type: "submit",
|
|
2226
2063
|
...submitButtonProps,
|
|
2227
|
-
className:
|
|
2064
|
+
className: `btn btn-info ${submitButtonProps.className}`
|
|
2228
2065
|
}, submitText));
|
|
2229
2066
|
}
|
|
2230
2067
|
|
|
@@ -2238,10 +2075,10 @@ function IconButton(props) {
|
|
|
2238
2075
|
} = props;
|
|
2239
2076
|
return /*#__PURE__*/React.createElement("button", {
|
|
2240
2077
|
type: "button",
|
|
2241
|
-
className:
|
|
2078
|
+
className: `btn btn-${iconType} ${className}`,
|
|
2242
2079
|
...otherProps
|
|
2243
2080
|
}, /*#__PURE__*/React.createElement("i", {
|
|
2244
|
-
className:
|
|
2081
|
+
className: `glyphicon glyphicon-${icon}`
|
|
2245
2082
|
}));
|
|
2246
2083
|
}
|
|
2247
2084
|
function MoveDownButton(props) {
|
|
@@ -2272,7 +2109,6 @@ function RemoveButton(props) {
|
|
|
2272
2109
|
|
|
2273
2110
|
/** The `AddButton` renders a button that represent the `Add` action on a form
|
|
2274
2111
|
*/
|
|
2275
|
-
|
|
2276
2112
|
function AddButton(_ref) {
|
|
2277
2113
|
let {
|
|
2278
2114
|
className,
|
|
@@ -2282,7 +2118,7 @@ function AddButton(_ref) {
|
|
|
2282
2118
|
return /*#__PURE__*/React.createElement("div", {
|
|
2283
2119
|
className: "row"
|
|
2284
2120
|
}, /*#__PURE__*/React.createElement("p", {
|
|
2285
|
-
className:
|
|
2121
|
+
className: `col-xs-3 col-xs-offset-9 text-right ${className}`
|
|
2286
2122
|
}, /*#__PURE__*/React.createElement(IconButton, {
|
|
2287
2123
|
iconType: "info",
|
|
2288
2124
|
icon: "plus",
|
|
@@ -2293,29 +2129,28 @@ function AddButton(_ref) {
|
|
|
2293
2129
|
})));
|
|
2294
2130
|
}
|
|
2295
2131
|
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2132
|
+
function buttonTemplates() {
|
|
2133
|
+
return {
|
|
2134
|
+
SubmitButton,
|
|
2135
|
+
AddButton,
|
|
2136
|
+
MoveDownButton,
|
|
2137
|
+
MoveUpButton,
|
|
2138
|
+
RemoveButton
|
|
2139
|
+
};
|
|
2140
|
+
}
|
|
2303
2141
|
|
|
2304
2142
|
/** The `DescriptionField` is the template to use to render the description of a field
|
|
2305
2143
|
*
|
|
2306
2144
|
* @param props - The `DescriptionFieldProps` for this component
|
|
2307
2145
|
*/
|
|
2308
|
-
|
|
2309
2146
|
function DescriptionField(props) {
|
|
2310
2147
|
const {
|
|
2311
2148
|
id,
|
|
2312
2149
|
description
|
|
2313
2150
|
} = props;
|
|
2314
|
-
|
|
2315
2151
|
if (!description) {
|
|
2316
2152
|
return null;
|
|
2317
2153
|
}
|
|
2318
|
-
|
|
2319
2154
|
if (typeof description === "string") {
|
|
2320
2155
|
return /*#__PURE__*/React.createElement("p", {
|
|
2321
2156
|
id: id,
|
|
@@ -2333,7 +2168,6 @@ function DescriptionField(props) {
|
|
|
2333
2168
|
*
|
|
2334
2169
|
* @param props - The `ErrorListProps` for this component
|
|
2335
2170
|
*/
|
|
2336
|
-
|
|
2337
2171
|
function ErrorList(_ref) {
|
|
2338
2172
|
let {
|
|
2339
2173
|
errors
|
|
@@ -2359,18 +2193,15 @@ const REQUIRED_FIELD_SYMBOL$1 = "*";
|
|
|
2359
2193
|
*
|
|
2360
2194
|
* @param props - The `LabelProps` for this component
|
|
2361
2195
|
*/
|
|
2362
|
-
|
|
2363
2196
|
function Label(props) {
|
|
2364
2197
|
const {
|
|
2365
2198
|
label,
|
|
2366
2199
|
required,
|
|
2367
2200
|
id
|
|
2368
2201
|
} = props;
|
|
2369
|
-
|
|
2370
2202
|
if (!label) {
|
|
2371
2203
|
return null;
|
|
2372
2204
|
}
|
|
2373
|
-
|
|
2374
2205
|
return /*#__PURE__*/React.createElement("label", {
|
|
2375
2206
|
className: "control-label",
|
|
2376
2207
|
htmlFor: id
|
|
@@ -2384,7 +2215,6 @@ function Label(props) {
|
|
|
2384
2215
|
*
|
|
2385
2216
|
* @param props - The `FieldTemplateProps` for this component
|
|
2386
2217
|
*/
|
|
2387
|
-
|
|
2388
2218
|
function FieldTemplate(props) {
|
|
2389
2219
|
const {
|
|
2390
2220
|
id,
|
|
@@ -2401,14 +2231,13 @@ function FieldTemplate(props) {
|
|
|
2401
2231
|
} = props;
|
|
2402
2232
|
const uiOptions = getUiOptions(uiSchema);
|
|
2403
2233
|
const WrapIfAdditionalTemplate = getTemplate("WrapIfAdditionalTemplate", registry, uiOptions);
|
|
2404
|
-
|
|
2405
2234
|
if (hidden) {
|
|
2406
2235
|
return /*#__PURE__*/React.createElement("div", {
|
|
2407
2236
|
className: "hidden"
|
|
2408
2237
|
}, children);
|
|
2409
2238
|
}
|
|
2410
|
-
|
|
2411
|
-
|
|
2239
|
+
return /*#__PURE__*/React.createElement(WrapIfAdditionalTemplate, {
|
|
2240
|
+
...props
|
|
2412
2241
|
}, displayLabel && /*#__PURE__*/React.createElement(Label, {
|
|
2413
2242
|
label: label,
|
|
2414
2243
|
required: required,
|
|
@@ -2420,18 +2249,15 @@ function FieldTemplate(props) {
|
|
|
2420
2249
|
*
|
|
2421
2250
|
* @param props - The `FieldErrorProps` for the errors being rendered
|
|
2422
2251
|
*/
|
|
2423
|
-
|
|
2424
2252
|
function FieldErrorTemplate(props) {
|
|
2425
2253
|
const {
|
|
2426
2254
|
errors = [],
|
|
2427
2255
|
idSchema
|
|
2428
2256
|
} = props;
|
|
2429
|
-
|
|
2430
2257
|
if (errors.length === 0) {
|
|
2431
2258
|
return null;
|
|
2432
2259
|
}
|
|
2433
|
-
|
|
2434
|
-
const id = idSchema.$id + "__error";
|
|
2260
|
+
const id = `${idSchema.$id}__error`;
|
|
2435
2261
|
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("ul", {
|
|
2436
2262
|
id: id,
|
|
2437
2263
|
className: "error-detail bs-callout bs-callout-info"
|
|
@@ -2447,26 +2273,21 @@ function FieldErrorTemplate(props) {
|
|
|
2447
2273
|
*
|
|
2448
2274
|
* @param props - The `FieldHelpProps` to be rendered
|
|
2449
2275
|
*/
|
|
2450
|
-
|
|
2451
2276
|
function FieldHelpTemplate(props) {
|
|
2452
2277
|
const {
|
|
2453
2278
|
idSchema,
|
|
2454
2279
|
help
|
|
2455
2280
|
} = props;
|
|
2456
|
-
|
|
2457
2281
|
if (!help) {
|
|
2458
2282
|
return null;
|
|
2459
2283
|
}
|
|
2460
|
-
|
|
2461
|
-
const id = idSchema.$id + "__help";
|
|
2462
|
-
|
|
2284
|
+
const id = `${idSchema.$id}__help`;
|
|
2463
2285
|
if (typeof help === "string") {
|
|
2464
2286
|
return /*#__PURE__*/React.createElement("p", {
|
|
2465
2287
|
id: id,
|
|
2466
2288
|
className: "help-block"
|
|
2467
2289
|
}, help);
|
|
2468
2290
|
}
|
|
2469
|
-
|
|
2470
2291
|
return /*#__PURE__*/React.createElement("div", {
|
|
2471
2292
|
id: id,
|
|
2472
2293
|
className: "help-block"
|
|
@@ -2479,7 +2300,6 @@ function FieldHelpTemplate(props) {
|
|
|
2479
2300
|
*
|
|
2480
2301
|
* @param props - The `ObjectFieldTemplateProps` for this component
|
|
2481
2302
|
*/
|
|
2482
|
-
|
|
2483
2303
|
function ObjectFieldTemplate(props) {
|
|
2484
2304
|
const {
|
|
2485
2305
|
description,
|
|
@@ -2497,8 +2317,8 @@ function ObjectFieldTemplate(props) {
|
|
|
2497
2317
|
} = props;
|
|
2498
2318
|
const options = getUiOptions(uiSchema);
|
|
2499
2319
|
const TitleFieldTemplate = getTemplate("TitleFieldTemplate", registry, options);
|
|
2500
|
-
const DescriptionFieldTemplate = getTemplate("DescriptionFieldTemplate", registry, options);
|
|
2501
|
-
|
|
2320
|
+
const DescriptionFieldTemplate = getTemplate("DescriptionFieldTemplate", registry, options);
|
|
2321
|
+
// Button templates are not overridden in the uiSchema
|
|
2502
2322
|
const {
|
|
2503
2323
|
ButtonTemplates: {
|
|
2504
2324
|
AddButton
|
|
@@ -2507,14 +2327,14 @@ function ObjectFieldTemplate(props) {
|
|
|
2507
2327
|
return /*#__PURE__*/React.createElement("fieldset", {
|
|
2508
2328
|
id: idSchema.$id
|
|
2509
2329
|
}, (options.title || title) && /*#__PURE__*/React.createElement(TitleFieldTemplate, {
|
|
2510
|
-
id: idSchema.$id
|
|
2330
|
+
id: `${idSchema.$id}__title`,
|
|
2511
2331
|
title: options.title || title,
|
|
2512
2332
|
required: required,
|
|
2513
2333
|
schema: schema,
|
|
2514
2334
|
uiSchema: uiSchema,
|
|
2515
2335
|
registry: registry
|
|
2516
2336
|
}), (options.description || description) && /*#__PURE__*/React.createElement(DescriptionFieldTemplate, {
|
|
2517
|
-
id: idSchema.$id
|
|
2337
|
+
id: `${idSchema.$id}__description`,
|
|
2518
2338
|
description: options.description || description,
|
|
2519
2339
|
schema: schema,
|
|
2520
2340
|
uiSchema: uiSchema,
|
|
@@ -2532,7 +2352,6 @@ const REQUIRED_FIELD_SYMBOL = "*";
|
|
|
2532
2352
|
*
|
|
2533
2353
|
* @param props - The `TitleFieldProps` for this component
|
|
2534
2354
|
*/
|
|
2535
|
-
|
|
2536
2355
|
function TitleField(props) {
|
|
2537
2356
|
const {
|
|
2538
2357
|
id,
|
|
@@ -2551,7 +2370,6 @@ function TitleField(props) {
|
|
|
2551
2370
|
*
|
|
2552
2371
|
* @param props - The `FieldProps` for this template
|
|
2553
2372
|
*/
|
|
2554
|
-
|
|
2555
2373
|
function UnsupportedField(props) {
|
|
2556
2374
|
const {
|
|
2557
2375
|
schema,
|
|
@@ -2568,7 +2386,6 @@ function UnsupportedField(props) {
|
|
|
2568
2386
|
*
|
|
2569
2387
|
* @param props - The `WrapIfAdditionalProps` for this component
|
|
2570
2388
|
*/
|
|
2571
|
-
|
|
2572
2389
|
function WrapIfAdditionalTemplate(props) {
|
|
2573
2390
|
const {
|
|
2574
2391
|
id,
|
|
@@ -2583,21 +2400,18 @@ function WrapIfAdditionalTemplate(props) {
|
|
|
2583
2400
|
children,
|
|
2584
2401
|
uiSchema,
|
|
2585
2402
|
registry
|
|
2586
|
-
} = props;
|
|
2587
|
-
|
|
2403
|
+
} = props;
|
|
2404
|
+
// Button templates are not overridden in the uiSchema
|
|
2588
2405
|
const {
|
|
2589
2406
|
RemoveButton
|
|
2590
2407
|
} = registry.templates.ButtonTemplates;
|
|
2591
|
-
const keyLabel = label
|
|
2592
|
-
|
|
2408
|
+
const keyLabel = `${label} Key`; // i18n ?
|
|
2593
2409
|
const additional = (ADDITIONAL_PROPERTY_FLAG in schema);
|
|
2594
|
-
|
|
2595
2410
|
if (!additional) {
|
|
2596
2411
|
return /*#__PURE__*/React.createElement("div", {
|
|
2597
2412
|
className: classNames
|
|
2598
2413
|
}, children);
|
|
2599
2414
|
}
|
|
2600
|
-
|
|
2601
2415
|
return /*#__PURE__*/React.createElement("div", {
|
|
2602
2416
|
className: classNames
|
|
2603
2417
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -2609,11 +2423,11 @@ function WrapIfAdditionalTemplate(props) {
|
|
|
2609
2423
|
}, /*#__PURE__*/React.createElement(Label, {
|
|
2610
2424
|
label: keyLabel,
|
|
2611
2425
|
required: required,
|
|
2612
|
-
id: id
|
|
2426
|
+
id: `${id}-key`
|
|
2613
2427
|
}), /*#__PURE__*/React.createElement("input", {
|
|
2614
2428
|
className: "form-control",
|
|
2615
2429
|
type: "text",
|
|
2616
|
-
id: id
|
|
2430
|
+
id: `${id}-key`,
|
|
2617
2431
|
onBlur: event => onKeyChange(event.target.value),
|
|
2618
2432
|
defaultValue: label
|
|
2619
2433
|
}))), /*#__PURE__*/React.createElement("div", {
|
|
@@ -2631,46 +2445,43 @@ function WrapIfAdditionalTemplate(props) {
|
|
|
2631
2445
|
}))));
|
|
2632
2446
|
}
|
|
2633
2447
|
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2448
|
+
function templates() {
|
|
2449
|
+
return {
|
|
2450
|
+
ArrayFieldDescriptionTemplate,
|
|
2451
|
+
ArrayFieldItemTemplate,
|
|
2452
|
+
ArrayFieldTemplate,
|
|
2453
|
+
ArrayFieldTitleTemplate,
|
|
2454
|
+
ButtonTemplates: buttonTemplates(),
|
|
2455
|
+
BaseInputTemplate,
|
|
2456
|
+
DescriptionFieldTemplate: DescriptionField,
|
|
2457
|
+
ErrorListTemplate: ErrorList,
|
|
2458
|
+
FieldTemplate,
|
|
2459
|
+
FieldErrorTemplate,
|
|
2460
|
+
FieldHelpTemplate,
|
|
2461
|
+
ObjectFieldTemplate,
|
|
2462
|
+
TitleFieldTemplate: TitleField,
|
|
2463
|
+
UnsupportedFieldTemplate: UnsupportedField,
|
|
2464
|
+
WrapIfAdditionalTemplate
|
|
2465
|
+
};
|
|
2466
|
+
}
|
|
2651
2467
|
|
|
2652
2468
|
function rangeOptions(start, stop) {
|
|
2653
2469
|
const options = [];
|
|
2654
|
-
|
|
2655
2470
|
for (let i = start; i <= stop; i++) {
|
|
2656
2471
|
options.push({
|
|
2657
2472
|
value: i,
|
|
2658
2473
|
label: pad(i, 2)
|
|
2659
2474
|
});
|
|
2660
2475
|
}
|
|
2661
|
-
|
|
2662
2476
|
return options;
|
|
2663
2477
|
}
|
|
2664
|
-
|
|
2665
2478
|
function readyForChange(state) {
|
|
2666
2479
|
return Object.values(state).every(value => value !== -1);
|
|
2667
2480
|
}
|
|
2668
|
-
|
|
2669
2481
|
function dateElementProps(state, time, yearsRange) {
|
|
2670
2482
|
if (yearsRange === void 0) {
|
|
2671
2483
|
yearsRange = [1900, new Date().getFullYear() + 2];
|
|
2672
2484
|
}
|
|
2673
|
-
|
|
2674
2485
|
const {
|
|
2675
2486
|
year,
|
|
2676
2487
|
month,
|
|
@@ -2692,7 +2503,6 @@ function dateElementProps(state, time, yearsRange) {
|
|
|
2692
2503
|
range: [1, 31],
|
|
2693
2504
|
value: day
|
|
2694
2505
|
}];
|
|
2695
|
-
|
|
2696
2506
|
if (time) {
|
|
2697
2507
|
data.push({
|
|
2698
2508
|
type: "hour",
|
|
@@ -2708,10 +2518,8 @@ function dateElementProps(state, time, yearsRange) {
|
|
|
2708
2518
|
value: second
|
|
2709
2519
|
});
|
|
2710
2520
|
}
|
|
2711
|
-
|
|
2712
2521
|
return data;
|
|
2713
2522
|
}
|
|
2714
|
-
|
|
2715
2523
|
function DateElement(_ref) {
|
|
2716
2524
|
let {
|
|
2717
2525
|
type,
|
|
@@ -2754,8 +2562,6 @@ function DateElement(_ref) {
|
|
|
2754
2562
|
/** The `AltDateWidget` is an alternative widget for rendering date properties.
|
|
2755
2563
|
* @param props - The `WidgetProps` for this component
|
|
2756
2564
|
*/
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
2565
|
function AltDateWidget(_ref2) {
|
|
2760
2566
|
let {
|
|
2761
2567
|
time = false,
|
|
@@ -2771,7 +2577,8 @@ function AltDateWidget(_ref2) {
|
|
|
2771
2577
|
value
|
|
2772
2578
|
} = _ref2;
|
|
2773
2579
|
const [state, setState] = useReducer((state, action) => {
|
|
2774
|
-
return {
|
|
2580
|
+
return {
|
|
2581
|
+
...state,
|
|
2775
2582
|
...action
|
|
2776
2583
|
};
|
|
2777
2584
|
}, parseDateString(value, time));
|
|
@@ -2793,21 +2600,17 @@ function AltDateWidget(_ref2) {
|
|
|
2793
2600
|
}, []);
|
|
2794
2601
|
const handleSetNow = useCallback(event => {
|
|
2795
2602
|
event.preventDefault();
|
|
2796
|
-
|
|
2797
2603
|
if (disabled || readonly) {
|
|
2798
2604
|
return;
|
|
2799
2605
|
}
|
|
2800
|
-
|
|
2801
2606
|
const nowDateObj = parseDateString(new Date().toJSON(), time);
|
|
2802
2607
|
setState(nowDateObj);
|
|
2803
2608
|
}, [disabled, readonly, time]);
|
|
2804
2609
|
const handleClear = useCallback(event => {
|
|
2805
2610
|
event.preventDefault();
|
|
2806
|
-
|
|
2807
2611
|
if (disabled || readonly) {
|
|
2808
2612
|
return;
|
|
2809
2613
|
}
|
|
2810
|
-
|
|
2811
2614
|
setState(parseDateString("", time));
|
|
2812
2615
|
onChange(undefined);
|
|
2813
2616
|
}, [disabled, readonly, time, onChange]);
|
|
@@ -2841,7 +2644,6 @@ function AltDateWidget(_ref2) {
|
|
|
2841
2644
|
*
|
|
2842
2645
|
* @param props - The `WidgetProps` for this component
|
|
2843
2646
|
*/
|
|
2844
|
-
|
|
2845
2647
|
function AltDateTimeWidget(_ref) {
|
|
2846
2648
|
let {
|
|
2847
2649
|
time = true,
|
|
@@ -2861,7 +2663,6 @@ function AltDateTimeWidget(_ref) {
|
|
|
2861
2663
|
*
|
|
2862
2664
|
* @param props - The `WidgetProps` for this component
|
|
2863
2665
|
*/
|
|
2864
|
-
|
|
2865
2666
|
function CheckboxWidget(_ref) {
|
|
2866
2667
|
let {
|
|
2867
2668
|
schema,
|
|
@@ -2878,16 +2679,16 @@ function CheckboxWidget(_ref) {
|
|
|
2878
2679
|
onChange,
|
|
2879
2680
|
registry
|
|
2880
2681
|
} = _ref;
|
|
2881
|
-
const DescriptionFieldTemplate = getTemplate("DescriptionFieldTemplate", registry, options);
|
|
2682
|
+
const DescriptionFieldTemplate = getTemplate("DescriptionFieldTemplate", registry, options);
|
|
2683
|
+
// Because an unchecked checkbox will cause html5 validation to fail, only add
|
|
2882
2684
|
// the "required" attribute if the field value must be "true", due to the
|
|
2883
2685
|
// "const" or "enum" keywords
|
|
2884
|
-
|
|
2885
2686
|
const required = schemaRequiresTrueValue(schema);
|
|
2886
2687
|
const handleChange = useCallback(event => onChange(event.target.checked), [onChange]);
|
|
2887
2688
|
const handleBlur = useCallback(event => onBlur(id, event.target.checked), [onBlur, id]);
|
|
2888
2689
|
const handleFocus = useCallback(event => onFocus(id, event.target.checked), [onFocus, id]);
|
|
2889
2690
|
return /*#__PURE__*/React.createElement("div", {
|
|
2890
|
-
className:
|
|
2691
|
+
className: `checkbox ${disabled || readonly ? "disabled" : ""}`
|
|
2891
2692
|
}, schema.description && /*#__PURE__*/React.createElement(DescriptionFieldTemplate, {
|
|
2892
2693
|
id: id + "__description",
|
|
2893
2694
|
description: schema.description,
|
|
@@ -2910,12 +2711,11 @@ function CheckboxWidget(_ref) {
|
|
|
2910
2711
|
|
|
2911
2712
|
function selectValue(value, selected, all) {
|
|
2912
2713
|
const at = all.indexOf(value);
|
|
2913
|
-
const updated = selected.slice(0, at).concat(value, selected.slice(at));
|
|
2714
|
+
const updated = selected.slice(0, at).concat(value, selected.slice(at));
|
|
2715
|
+
// As inserting values at predefined index positions doesn't work with empty
|
|
2914
2716
|
// arrays, we need to reorder the updated selection to match the initial order
|
|
2915
|
-
|
|
2916
2717
|
return updated.sort((a, b) => Number(all.indexOf(a) > all.indexOf(b)));
|
|
2917
2718
|
}
|
|
2918
|
-
|
|
2919
2719
|
function deselectValue(value, selected) {
|
|
2920
2720
|
return selected.filter(v => v !== value);
|
|
2921
2721
|
}
|
|
@@ -2924,8 +2724,6 @@ function deselectValue(value, selected) {
|
|
|
2924
2724
|
*
|
|
2925
2725
|
* @param props - The `WidgetProps` for this component
|
|
2926
2726
|
*/
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
2727
|
function CheckboxesWidget(_ref) {
|
|
2930
2728
|
let {
|
|
2931
2729
|
id,
|
|
@@ -2947,7 +2745,6 @@ function CheckboxesWidget(_ref) {
|
|
|
2947
2745
|
const checked = value.indexOf(option.value) !== -1;
|
|
2948
2746
|
const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) != -1;
|
|
2949
2747
|
const disabledCls = disabled || itemDisabled || readonly ? "disabled" : "";
|
|
2950
|
-
|
|
2951
2748
|
const handleChange = event => {
|
|
2952
2749
|
const all = enumOptions.map(_ref2 => {
|
|
2953
2750
|
let {
|
|
@@ -2955,17 +2752,15 @@ function CheckboxesWidget(_ref) {
|
|
|
2955
2752
|
} = _ref2;
|
|
2956
2753
|
return value;
|
|
2957
2754
|
});
|
|
2958
|
-
|
|
2959
2755
|
if (event.target.checked) {
|
|
2960
2756
|
onChange(selectValue(option.value, value, all));
|
|
2961
2757
|
} else {
|
|
2962
2758
|
onChange(deselectValue(option.value, value));
|
|
2963
2759
|
}
|
|
2964
2760
|
};
|
|
2965
|
-
|
|
2966
2761
|
const checkbox = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("input", {
|
|
2967
2762
|
type: "checkbox",
|
|
2968
|
-
id: id
|
|
2763
|
+
id: `${id}-${option.value}`,
|
|
2969
2764
|
name: id,
|
|
2970
2765
|
checked: checked,
|
|
2971
2766
|
disabled: disabled || itemDisabled || readonly,
|
|
@@ -2974,10 +2769,10 @@ function CheckboxesWidget(_ref) {
|
|
|
2974
2769
|
}), /*#__PURE__*/React.createElement("span", null, option.label));
|
|
2975
2770
|
return inline ? /*#__PURE__*/React.createElement("label", {
|
|
2976
2771
|
key: option.value,
|
|
2977
|
-
className:
|
|
2772
|
+
className: `checkbox-inline ${disabledCls}`
|
|
2978
2773
|
}, checkbox) : /*#__PURE__*/React.createElement("div", {
|
|
2979
2774
|
key: option.value,
|
|
2980
|
-
className:
|
|
2775
|
+
className: `checkbox ${disabledCls}`
|
|
2981
2776
|
}, /*#__PURE__*/React.createElement("label", null, checkbox));
|
|
2982
2777
|
}));
|
|
2983
2778
|
}
|
|
@@ -2987,7 +2782,6 @@ function CheckboxesWidget(_ref) {
|
|
|
2987
2782
|
*
|
|
2988
2783
|
* @param props - The `WidgetProps` for this component
|
|
2989
2784
|
*/
|
|
2990
|
-
|
|
2991
2785
|
function ColorWidget(props) {
|
|
2992
2786
|
const {
|
|
2993
2787
|
disabled,
|
|
@@ -3008,7 +2802,6 @@ function ColorWidget(props) {
|
|
|
3008
2802
|
*
|
|
3009
2803
|
* @param props - The `WidgetProps` for this component
|
|
3010
2804
|
*/
|
|
3011
|
-
|
|
3012
2805
|
function DateWidget(props) {
|
|
3013
2806
|
const {
|
|
3014
2807
|
onChange,
|
|
@@ -3029,7 +2822,6 @@ function DateWidget(props) {
|
|
|
3029
2822
|
*
|
|
3030
2823
|
* @param props - The `WidgetProps` for this component
|
|
3031
2824
|
*/
|
|
3032
|
-
|
|
3033
2825
|
function DateTimeWidget(props) {
|
|
3034
2826
|
const {
|
|
3035
2827
|
onChange,
|
|
@@ -3050,7 +2842,6 @@ function DateTimeWidget(props) {
|
|
|
3050
2842
|
*
|
|
3051
2843
|
* @param props - The `WidgetProps` for this component
|
|
3052
2844
|
*/
|
|
3053
|
-
|
|
3054
2845
|
function EmailWidget(props) {
|
|
3055
2846
|
const {
|
|
3056
2847
|
options,
|
|
@@ -3067,10 +2858,8 @@ function addNameToDataURL(dataURL, name) {
|
|
|
3067
2858
|
if (dataURL === null) {
|
|
3068
2859
|
return null;
|
|
3069
2860
|
}
|
|
3070
|
-
|
|
3071
|
-
return dataURL.replace(";base64", ";name=" + encodeURIComponent(name) + ";base64");
|
|
2861
|
+
return dataURL.replace(";base64", `;name=${encodeURIComponent(name)};base64`);
|
|
3072
2862
|
}
|
|
3073
|
-
|
|
3074
2863
|
function processFile(file) {
|
|
3075
2864
|
const {
|
|
3076
2865
|
name,
|
|
@@ -3080,10 +2869,8 @@ function processFile(file) {
|
|
|
3080
2869
|
return new Promise((resolve, reject) => {
|
|
3081
2870
|
const reader = new window.FileReader();
|
|
3082
2871
|
reader.onerror = reject;
|
|
3083
|
-
|
|
3084
2872
|
reader.onload = event => {
|
|
3085
2873
|
var _event$target;
|
|
3086
|
-
|
|
3087
2874
|
if (typeof ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result) === "string") {
|
|
3088
2875
|
resolve({
|
|
3089
2876
|
dataURL: addNameToDataURL(event.target.result, name),
|
|
@@ -3100,24 +2887,19 @@ function processFile(file) {
|
|
|
3100
2887
|
});
|
|
3101
2888
|
}
|
|
3102
2889
|
};
|
|
3103
|
-
|
|
3104
2890
|
reader.readAsDataURL(file);
|
|
3105
2891
|
});
|
|
3106
2892
|
}
|
|
3107
|
-
|
|
3108
2893
|
function processFiles(files) {
|
|
3109
2894
|
return Promise.all(Array.from(files).map(processFile));
|
|
3110
2895
|
}
|
|
3111
|
-
|
|
3112
2896
|
function FilesInfo(_ref) {
|
|
3113
2897
|
let {
|
|
3114
2898
|
filesInfo
|
|
3115
2899
|
} = _ref;
|
|
3116
|
-
|
|
3117
2900
|
if (filesInfo.length === 0) {
|
|
3118
2901
|
return null;
|
|
3119
2902
|
}
|
|
3120
|
-
|
|
3121
2903
|
return /*#__PURE__*/React.createElement("ul", {
|
|
3122
2904
|
className: "file-info"
|
|
3123
2905
|
}, filesInfo.map((fileInfo, key) => {
|
|
@@ -3131,7 +2913,6 @@ function FilesInfo(_ref) {
|
|
|
3131
2913
|
}, /*#__PURE__*/React.createElement("strong", null, name), " (", type, ", ", size, " bytes)");
|
|
3132
2914
|
}));
|
|
3133
2915
|
}
|
|
3134
|
-
|
|
3135
2916
|
function extractFileInfo(dataURLs) {
|
|
3136
2917
|
return dataURLs.filter(dataURL => typeof dataURL !== "undefined").map(dataURL => {
|
|
3137
2918
|
const {
|
|
@@ -3149,8 +2930,6 @@ function extractFileInfo(dataURLs) {
|
|
|
3149
2930
|
* The `FileWidget` is a widget for rendering file upload fields.
|
|
3150
2931
|
* It is typically used with a string property with data-url format.
|
|
3151
2932
|
*/
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
2933
|
function FileWidget(_ref2) {
|
|
3155
2934
|
let {
|
|
3156
2935
|
multiple,
|
|
@@ -3168,11 +2947,9 @@ function FileWidget(_ref2) {
|
|
|
3168
2947
|
if (!event.target.files) {
|
|
3169
2948
|
return;
|
|
3170
2949
|
}
|
|
3171
|
-
|
|
3172
2950
|
processFiles(event.target.files).then(filesInfoEvent => {
|
|
3173
2951
|
setFilesInfo(filesInfoEvent);
|
|
3174
2952
|
const newValue = filesInfoEvent.map(fileInfo => fileInfo.dataURL);
|
|
3175
|
-
|
|
3176
2953
|
if (multiple) {
|
|
3177
2954
|
onChange(newValue);
|
|
3178
2955
|
} else {
|
|
@@ -3200,7 +2977,6 @@ function FileWidget(_ref2) {
|
|
|
3200
2977
|
*
|
|
3201
2978
|
* @param props - The `WidgetProps` for this component
|
|
3202
2979
|
*/
|
|
3203
|
-
|
|
3204
2980
|
function HiddenWidget(_ref) {
|
|
3205
2981
|
let {
|
|
3206
2982
|
id,
|
|
@@ -3218,7 +2994,6 @@ function HiddenWidget(_ref) {
|
|
|
3218
2994
|
*
|
|
3219
2995
|
* @param props - The `WidgetProps` for this component
|
|
3220
2996
|
*/
|
|
3221
|
-
|
|
3222
2997
|
function PasswordWidget(props) {
|
|
3223
2998
|
const {
|
|
3224
2999
|
options,
|
|
@@ -3236,7 +3011,6 @@ function PasswordWidget(props) {
|
|
|
3236
3011
|
*
|
|
3237
3012
|
* @param props - The `WidgetProps` for this component
|
|
3238
3013
|
*/
|
|
3239
|
-
|
|
3240
3014
|
function RadioWidget(_ref) {
|
|
3241
3015
|
let {
|
|
3242
3016
|
options,
|
|
@@ -3256,9 +3030,9 @@ function RadioWidget(_ref) {
|
|
|
3256
3030
|
enumOptions,
|
|
3257
3031
|
enumDisabled,
|
|
3258
3032
|
inline
|
|
3259
|
-
} = options;
|
|
3033
|
+
} = options;
|
|
3034
|
+
// checked={checked} has been moved above name={name}, As mentioned in #349;
|
|
3260
3035
|
// this is a temporary fix for radio button rendering bug in React, facebook/react#7630.
|
|
3261
|
-
|
|
3262
3036
|
const handleBlur = useCallback(event => onBlur(id, event.target.value), [onBlur, id]);
|
|
3263
3037
|
const handleFocus = useCallback(event => onFocus(id, event.target.value), [onFocus, id]);
|
|
3264
3038
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -3268,12 +3042,10 @@ function RadioWidget(_ref) {
|
|
|
3268
3042
|
const checked = option.value === value;
|
|
3269
3043
|
const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) != -1;
|
|
3270
3044
|
const disabledCls = disabled || itemDisabled || readonly ? "disabled" : "";
|
|
3271
|
-
|
|
3272
3045
|
const handleChange = () => onChange(option.value);
|
|
3273
|
-
|
|
3274
3046
|
const radio = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("input", {
|
|
3275
3047
|
type: "radio",
|
|
3276
|
-
id: id
|
|
3048
|
+
id: `${id}-${option.value}`,
|
|
3277
3049
|
checked: checked,
|
|
3278
3050
|
name: name,
|
|
3279
3051
|
required: required,
|
|
@@ -3286,10 +3058,10 @@ function RadioWidget(_ref) {
|
|
|
3286
3058
|
}), /*#__PURE__*/React.createElement("span", null, option.label));
|
|
3287
3059
|
return inline ? /*#__PURE__*/React.createElement("label", {
|
|
3288
3060
|
key: option.value,
|
|
3289
|
-
className:
|
|
3061
|
+
className: `radio-inline ${disabledCls}`
|
|
3290
3062
|
}, radio) : /*#__PURE__*/React.createElement("div", {
|
|
3291
3063
|
key: option.value,
|
|
3292
|
-
className:
|
|
3064
|
+
className: `radio ${disabledCls}`
|
|
3293
3065
|
}, /*#__PURE__*/React.createElement("label", null, radio));
|
|
3294
3066
|
}));
|
|
3295
3067
|
}
|
|
@@ -3299,7 +3071,6 @@ function RadioWidget(_ref) {
|
|
|
3299
3071
|
*
|
|
3300
3072
|
* @param props - The `WidgetProps` for this component
|
|
3301
3073
|
*/
|
|
3302
|
-
|
|
3303
3074
|
function RangeWidget(props) {
|
|
3304
3075
|
const {
|
|
3305
3076
|
value,
|
|
@@ -3323,7 +3094,6 @@ function getValue(event, multiple) {
|
|
|
3323
3094
|
if (multiple) {
|
|
3324
3095
|
return Array.from(event.target.options).slice().filter(o => o.selected).map(o => o.value);
|
|
3325
3096
|
}
|
|
3326
|
-
|
|
3327
3097
|
return event.target.value;
|
|
3328
3098
|
}
|
|
3329
3099
|
/** The `SelectWidget` is a widget for rendering dropdowns.
|
|
@@ -3331,8 +3101,6 @@ function getValue(event, multiple) {
|
|
|
3331
3101
|
*
|
|
3332
3102
|
* @param props - The `WidgetProps` for this component
|
|
3333
3103
|
*/
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
3104
|
function SelectWidget(_ref) {
|
|
3337
3105
|
let {
|
|
3338
3106
|
schema,
|
|
@@ -3398,7 +3166,6 @@ function SelectWidget(_ref) {
|
|
|
3398
3166
|
*
|
|
3399
3167
|
* @param props - The `WidgetProps` for this component
|
|
3400
3168
|
*/
|
|
3401
|
-
|
|
3402
3169
|
function TextareaWidget(_ref) {
|
|
3403
3170
|
let {
|
|
3404
3171
|
id,
|
|
@@ -3453,7 +3220,6 @@ function TextareaWidget(_ref) {
|
|
|
3453
3220
|
onChange: handleChange
|
|
3454
3221
|
});
|
|
3455
3222
|
}
|
|
3456
|
-
|
|
3457
3223
|
TextareaWidget.defaultProps = {
|
|
3458
3224
|
autofocus: false,
|
|
3459
3225
|
options: {}
|
|
@@ -3463,14 +3229,14 @@ TextareaWidget.defaultProps = {
|
|
|
3463
3229
|
*
|
|
3464
3230
|
* @param props - The `WidgetProps` for this component
|
|
3465
3231
|
*/
|
|
3466
|
-
|
|
3467
3232
|
function TextWidget(props) {
|
|
3468
3233
|
const {
|
|
3469
3234
|
options,
|
|
3470
3235
|
registry
|
|
3471
3236
|
} = props;
|
|
3472
3237
|
const BaseInputTemplate = getTemplate("BaseInputTemplate", registry, options);
|
|
3473
|
-
return /*#__PURE__*/React.createElement(BaseInputTemplate, {
|
|
3238
|
+
return /*#__PURE__*/React.createElement(BaseInputTemplate, {
|
|
3239
|
+
...props
|
|
3474
3240
|
});
|
|
3475
3241
|
}
|
|
3476
3242
|
|
|
@@ -3478,7 +3244,6 @@ function TextWidget(props) {
|
|
|
3478
3244
|
*
|
|
3479
3245
|
* @param props - The `WidgetProps` for this component
|
|
3480
3246
|
*/
|
|
3481
|
-
|
|
3482
3247
|
function URLWidget(props) {
|
|
3483
3248
|
const {
|
|
3484
3249
|
options,
|
|
@@ -3495,7 +3260,6 @@ function URLWidget(props) {
|
|
|
3495
3260
|
*
|
|
3496
3261
|
* @param props - The `WidgetProps` for this component
|
|
3497
3262
|
*/
|
|
3498
|
-
|
|
3499
3263
|
function UpDownWidget(props) {
|
|
3500
3264
|
const {
|
|
3501
3265
|
options,
|
|
@@ -3508,44 +3272,44 @@ function UpDownWidget(props) {
|
|
|
3508
3272
|
});
|
|
3509
3273
|
}
|
|
3510
3274
|
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3275
|
+
function widgets() {
|
|
3276
|
+
return {
|
|
3277
|
+
PasswordWidget,
|
|
3278
|
+
RadioWidget,
|
|
3279
|
+
UpDownWidget,
|
|
3280
|
+
RangeWidget,
|
|
3281
|
+
SelectWidget,
|
|
3282
|
+
TextWidget,
|
|
3283
|
+
DateWidget,
|
|
3284
|
+
DateTimeWidget,
|
|
3285
|
+
AltDateWidget,
|
|
3286
|
+
AltDateTimeWidget,
|
|
3287
|
+
EmailWidget,
|
|
3288
|
+
URLWidget,
|
|
3289
|
+
TextareaWidget,
|
|
3290
|
+
HiddenWidget,
|
|
3291
|
+
ColorWidget,
|
|
3292
|
+
FileWidget,
|
|
3293
|
+
CheckboxWidget,
|
|
3294
|
+
CheckboxesWidget
|
|
3295
|
+
};
|
|
3296
|
+
}
|
|
3531
3297
|
|
|
3532
3298
|
/** The default registry consists of all the fields, templates and widgets provided in the core implementation,
|
|
3533
3299
|
* plus an empty `rootSchema` and `formContext. We omit schemaUtils here because it cannot be defaulted without a
|
|
3534
3300
|
* rootSchema and validator. It will be added into the computed registry later in the Form.
|
|
3535
3301
|
*/
|
|
3536
|
-
|
|
3537
3302
|
function getDefaultRegistry() {
|
|
3538
3303
|
return {
|
|
3539
|
-
fields,
|
|
3540
|
-
templates,
|
|
3541
|
-
widgets,
|
|
3304
|
+
fields: fields(),
|
|
3305
|
+
templates: templates(),
|
|
3306
|
+
widgets: widgets(),
|
|
3542
3307
|
rootSchema: {},
|
|
3543
3308
|
formContext: {}
|
|
3544
3309
|
};
|
|
3545
3310
|
}
|
|
3546
3311
|
|
|
3547
3312
|
/** The `Form` component renders the outer form and all the fields defined in the `schema` */
|
|
3548
|
-
|
|
3549
3313
|
class Form extends Component {
|
|
3550
3314
|
/** The ref used to hold the `form` element, this needs to be `any` because `tagName` or `_internalFormWrapper` can
|
|
3551
3315
|
* provide any possible type here
|
|
@@ -3560,36 +3324,30 @@ class Form extends Component {
|
|
|
3560
3324
|
constructor(props) {
|
|
3561
3325
|
super(props);
|
|
3562
3326
|
this.formElement = void 0;
|
|
3563
|
-
|
|
3564
3327
|
this.getUsedFormData = (formData, fields) => {
|
|
3565
3328
|
// For the case of a single input form
|
|
3566
3329
|
if (fields.length === 0 && typeof formData !== "object") {
|
|
3567
3330
|
return formData;
|
|
3568
3331
|
}
|
|
3569
|
-
|
|
3332
|
+
// _pick has incorrect type definition, it works with string[][], because lodash/hasIn supports it
|
|
3570
3333
|
const data = _pick(formData, fields);
|
|
3571
|
-
|
|
3572
3334
|
if (Array.isArray(formData)) {
|
|
3573
3335
|
return Object.keys(data).map(key => data[key]);
|
|
3574
3336
|
}
|
|
3575
|
-
|
|
3576
3337
|
return data;
|
|
3577
3338
|
};
|
|
3578
|
-
|
|
3579
3339
|
this.getFieldNames = (pathSchema, formData) => {
|
|
3580
3340
|
const getAllPaths = function (_obj, acc, paths) {
|
|
3581
3341
|
if (acc === void 0) {
|
|
3582
3342
|
acc = [];
|
|
3583
3343
|
}
|
|
3584
|
-
|
|
3585
3344
|
if (paths === void 0) {
|
|
3586
|
-
paths = [
|
|
3345
|
+
paths = [[]];
|
|
3587
3346
|
}
|
|
3588
|
-
|
|
3589
3347
|
Object.keys(_obj).forEach(key => {
|
|
3590
3348
|
if (typeof _obj[key] === "object") {
|
|
3591
|
-
const newPaths = paths.map(path => path
|
|
3592
|
-
|
|
3349
|
+
const newPaths = paths.map(path => [...path, key]);
|
|
3350
|
+
// If an object is marked with additionalProperties, all its keys are valid
|
|
3593
3351
|
if (_obj[key][RJSF_ADDITONAL_PROPERTIES_FLAG] && _obj[key][NAME_KEY] !== "") {
|
|
3594
3352
|
acc.push(_obj[key][NAME_KEY]);
|
|
3595
3353
|
} else {
|
|
@@ -3597,12 +3355,9 @@ class Form extends Component {
|
|
|
3597
3355
|
}
|
|
3598
3356
|
} else if (key === NAME_KEY && _obj[key] !== "") {
|
|
3599
3357
|
paths.forEach(path => {
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
const formValue = get(formData, path); // adds path to fieldNames if it points to a value
|
|
3358
|
+
const formValue = get(formData, path);
|
|
3359
|
+
// adds path to fieldNames if it points to a value
|
|
3603
3360
|
// or an empty object/array
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
3361
|
if (typeof formValue !== "object" || _isEmpty(formValue)) {
|
|
3607
3362
|
acc.push(path);
|
|
3608
3363
|
}
|
|
@@ -3611,10 +3366,8 @@ class Form extends Component {
|
|
|
3611
3366
|
});
|
|
3612
3367
|
return acc;
|
|
3613
3368
|
};
|
|
3614
|
-
|
|
3615
3369
|
return getAllPaths(pathSchema);
|
|
3616
3370
|
};
|
|
3617
|
-
|
|
3618
3371
|
this.onChange = (formData, newErrorSchema, id) => {
|
|
3619
3372
|
const {
|
|
3620
3373
|
extraErrors,
|
|
@@ -3628,19 +3381,16 @@ class Form extends Component {
|
|
|
3628
3381
|
schemaUtils,
|
|
3629
3382
|
schema
|
|
3630
3383
|
} = this.state;
|
|
3631
|
-
|
|
3632
3384
|
if (isObject$1(formData) || Array.isArray(formData)) {
|
|
3633
3385
|
const newState = this.getStateFromProps(this.props, formData);
|
|
3634
3386
|
formData = newState.formData;
|
|
3635
3387
|
}
|
|
3636
|
-
|
|
3637
3388
|
const mustValidate = !noValidate && liveValidate;
|
|
3638
3389
|
let state = {
|
|
3639
3390
|
formData,
|
|
3640
3391
|
schema
|
|
3641
3392
|
};
|
|
3642
3393
|
let newFormData = formData;
|
|
3643
|
-
|
|
3644
3394
|
if (omitExtraData === true && liveOmit === true) {
|
|
3645
3395
|
const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
|
|
3646
3396
|
const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", formData);
|
|
@@ -3650,20 +3400,17 @@ class Form extends Component {
|
|
|
3650
3400
|
formData: newFormData
|
|
3651
3401
|
};
|
|
3652
3402
|
}
|
|
3653
|
-
|
|
3654
3403
|
if (mustValidate) {
|
|
3655
3404
|
const schemaValidation = this.validate(newFormData);
|
|
3656
3405
|
let errors = schemaValidation.errors;
|
|
3657
3406
|
let errorSchema = schemaValidation.errorSchema;
|
|
3658
3407
|
const schemaValidationErrors = errors;
|
|
3659
3408
|
const schemaValidationErrorSchema = errorSchema;
|
|
3660
|
-
|
|
3661
3409
|
if (extraErrors) {
|
|
3662
3410
|
const merged = schemaUtils.mergeValidationData(schemaValidation, extraErrors);
|
|
3663
3411
|
errorSchema = merged.errorSchema;
|
|
3664
3412
|
errors = merged.errors;
|
|
3665
3413
|
}
|
|
3666
|
-
|
|
3667
3414
|
state = {
|
|
3668
3415
|
formData: newFormData,
|
|
3669
3416
|
errors,
|
|
@@ -3679,39 +3426,32 @@ class Form extends Component {
|
|
|
3679
3426
|
errors: schemaUtils.getValidator().toErrorList(errorSchema)
|
|
3680
3427
|
};
|
|
3681
3428
|
}
|
|
3682
|
-
|
|
3683
|
-
|
|
3429
|
+
this.setState(state, () => onChange && onChange({
|
|
3430
|
+
...this.state,
|
|
3684
3431
|
...state
|
|
3685
3432
|
}, id));
|
|
3686
3433
|
};
|
|
3687
|
-
|
|
3688
3434
|
this.onBlur = (id, data) => {
|
|
3689
3435
|
const {
|
|
3690
3436
|
onBlur
|
|
3691
3437
|
} = this.props;
|
|
3692
|
-
|
|
3693
3438
|
if (onBlur) {
|
|
3694
3439
|
onBlur(id, data);
|
|
3695
3440
|
}
|
|
3696
3441
|
};
|
|
3697
|
-
|
|
3698
3442
|
this.onFocus = (id, data) => {
|
|
3699
3443
|
const {
|
|
3700
3444
|
onFocus
|
|
3701
3445
|
} = this.props;
|
|
3702
|
-
|
|
3703
3446
|
if (onFocus) {
|
|
3704
3447
|
onFocus(id, data);
|
|
3705
3448
|
}
|
|
3706
3449
|
};
|
|
3707
|
-
|
|
3708
3450
|
this.onSubmit = event => {
|
|
3709
3451
|
event.preventDefault();
|
|
3710
|
-
|
|
3711
3452
|
if (event.target !== event.currentTarget) {
|
|
3712
3453
|
return;
|
|
3713
3454
|
}
|
|
3714
|
-
|
|
3715
3455
|
event.persist();
|
|
3716
3456
|
const {
|
|
3717
3457
|
omitExtraData,
|
|
@@ -3726,14 +3466,12 @@ class Form extends Component {
|
|
|
3726
3466
|
schema,
|
|
3727
3467
|
schemaUtils
|
|
3728
3468
|
} = this.state;
|
|
3729
|
-
|
|
3730
3469
|
if (omitExtraData === true) {
|
|
3731
3470
|
const retrievedSchema = schemaUtils.retrieveSchema(schema, newFormData);
|
|
3732
3471
|
const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", newFormData);
|
|
3733
3472
|
const fieldNames = this.getFieldNames(pathSchema, newFormData);
|
|
3734
3473
|
newFormData = this.getUsedFormData(newFormData, fieldNames);
|
|
3735
3474
|
}
|
|
3736
|
-
|
|
3737
3475
|
if (noValidate || this.validateForm()) {
|
|
3738
3476
|
// There are no errors generated through schema validation.
|
|
3739
3477
|
// Check for user provided errors and update state accordingly.
|
|
@@ -3747,7 +3485,8 @@ class Form extends Component {
|
|
|
3747
3485
|
schemaValidationErrorSchema: {}
|
|
3748
3486
|
}, () => {
|
|
3749
3487
|
if (onSubmit) {
|
|
3750
|
-
onSubmit({
|
|
3488
|
+
onSubmit({
|
|
3489
|
+
...this.state,
|
|
3751
3490
|
formData: newFormData,
|
|
3752
3491
|
status: "submitted"
|
|
3753
3492
|
}, event);
|
|
@@ -3755,17 +3494,13 @@ class Form extends Component {
|
|
|
3755
3494
|
});
|
|
3756
3495
|
}
|
|
3757
3496
|
};
|
|
3758
|
-
|
|
3759
3497
|
if (!props.validator) {
|
|
3760
3498
|
throw new Error("A validator is required for Form functionality to work");
|
|
3761
3499
|
}
|
|
3762
|
-
|
|
3763
3500
|
this.state = this.getStateFromProps(props, props.formData);
|
|
3764
|
-
|
|
3765
3501
|
if (this.props.onChange && !deepEquals(this.state.formData, this.props.formData)) {
|
|
3766
3502
|
this.props.onChange(this.state);
|
|
3767
3503
|
}
|
|
3768
|
-
|
|
3769
3504
|
this.formElement = /*#__PURE__*/React.createRef();
|
|
3770
3505
|
}
|
|
3771
3506
|
/** React lifecycle method that gets called before new props are provided, updates the state based on new props. It
|
|
@@ -3774,15 +3509,11 @@ class Form extends Component {
|
|
|
3774
3509
|
*
|
|
3775
3510
|
* @param nextProps - The new set of props about to be applied to the `Form`
|
|
3776
3511
|
*/
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
3512
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
3780
3513
|
const nextState = this.getStateFromProps(nextProps, nextProps.formData);
|
|
3781
|
-
|
|
3782
3514
|
if (!deepEquals(nextState.formData, nextProps.formData) && !deepEquals(nextState.formData, this.state.formData) && nextProps.onChange) {
|
|
3783
3515
|
nextProps.onChange(nextState);
|
|
3784
3516
|
}
|
|
3785
|
-
|
|
3786
3517
|
this.setState(nextState);
|
|
3787
3518
|
}
|
|
3788
3519
|
/** Extracts the updated state from the given `props` and `inputFormData`. As part of this process, the
|
|
@@ -3793,8 +3524,6 @@ class Form extends Component {
|
|
|
3793
3524
|
* @param inputFormData - The new or current data for the `Form`
|
|
3794
3525
|
* @returns - The new state for the `Form`
|
|
3795
3526
|
*/
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
3527
|
getStateFromProps(props, inputFormData) {
|
|
3799
3528
|
const state = this.state || {};
|
|
3800
3529
|
const schema = "schema" in props ? props.schema : this.props.schema;
|
|
@@ -3804,14 +3533,11 @@ class Form extends Component {
|
|
|
3804
3533
|
const mustValidate = edit && !props.noValidate && liveValidate;
|
|
3805
3534
|
const rootSchema = schema;
|
|
3806
3535
|
let schemaUtils = state.schemaUtils;
|
|
3807
|
-
|
|
3808
3536
|
if (!schemaUtils || schemaUtils.doesSchemaUtilsDiffer(props.validator, rootSchema)) {
|
|
3809
3537
|
schemaUtils = createSchemaUtils(props.validator, rootSchema);
|
|
3810
3538
|
}
|
|
3811
|
-
|
|
3812
3539
|
const formData = schemaUtils.getDefaultFormState(schema, inputFormData);
|
|
3813
3540
|
const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
|
|
3814
|
-
|
|
3815
3541
|
const getCurrentErrors = () => {
|
|
3816
3542
|
if (props.noValidate) {
|
|
3817
3543
|
return {
|
|
@@ -3824,18 +3550,15 @@ class Form extends Component {
|
|
|
3824
3550
|
errorSchema: state.schemaValidationErrorSchema || {}
|
|
3825
3551
|
};
|
|
3826
3552
|
}
|
|
3827
|
-
|
|
3828
3553
|
return {
|
|
3829
3554
|
errors: state.errors || [],
|
|
3830
3555
|
errorSchema: state.errorSchema || {}
|
|
3831
3556
|
};
|
|
3832
3557
|
};
|
|
3833
|
-
|
|
3834
3558
|
let errors;
|
|
3835
3559
|
let errorSchema;
|
|
3836
3560
|
let schemaValidationErrors = state.schemaValidationErrors;
|
|
3837
3561
|
let schemaValidationErrorSchema = state.schemaValidationErrorSchema;
|
|
3838
|
-
|
|
3839
3562
|
if (mustValidate) {
|
|
3840
3563
|
const schemaValidation = this.validate(formData, schema, schemaUtils);
|
|
3841
3564
|
errors = schemaValidation.errors;
|
|
@@ -3847,7 +3570,6 @@ class Form extends Component {
|
|
|
3847
3570
|
errors = currentErrors.errors;
|
|
3848
3571
|
errorSchema = currentErrors.errorSchema;
|
|
3849
3572
|
}
|
|
3850
|
-
|
|
3851
3573
|
if (props.extraErrors) {
|
|
3852
3574
|
const merged = schemaUtils.mergeValidationData({
|
|
3853
3575
|
errorSchema,
|
|
@@ -3856,7 +3578,6 @@ class Form extends Component {
|
|
|
3856
3578
|
errorSchema = merged.errorSchema;
|
|
3857
3579
|
errors = merged.errors;
|
|
3858
3580
|
}
|
|
3859
|
-
|
|
3860
3581
|
const idSchema = schemaUtils.toIdSchema(retrievedSchema, uiSchema["ui:rootFieldId"], formData, props.idPrefix, props.idSeparator);
|
|
3861
3582
|
const nextState = {
|
|
3862
3583
|
schemaUtils,
|
|
@@ -3878,8 +3599,6 @@ class Form extends Component {
|
|
|
3878
3599
|
* @param nextState - The next version of the state
|
|
3879
3600
|
* @returns - True if the component should be updated, false otherwise
|
|
3880
3601
|
*/
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
3602
|
shouldComponentUpdate(nextProps, nextState) {
|
|
3884
3603
|
return shouldRender(this, nextProps, nextState);
|
|
3885
3604
|
}
|
|
@@ -3890,13 +3609,10 @@ class Form extends Component {
|
|
|
3890
3609
|
* @param schema - The schema used to validate against
|
|
3891
3610
|
* @param altSchemaUtils - The alternate schemaUtils to use for validation
|
|
3892
3611
|
*/
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
3612
|
validate(formData, schema, altSchemaUtils) {
|
|
3896
3613
|
if (schema === void 0) {
|
|
3897
3614
|
schema = this.props.schema;
|
|
3898
3615
|
}
|
|
3899
|
-
|
|
3900
3616
|
const schemaUtils = altSchemaUtils ? altSchemaUtils : this.state.schemaUtils;
|
|
3901
3617
|
const {
|
|
3902
3618
|
customValidate,
|
|
@@ -3906,8 +3622,6 @@ class Form extends Component {
|
|
|
3906
3622
|
return schemaUtils.getValidator().validateFormData(formData, resolvedSchema, customValidate, transformErrors);
|
|
3907
3623
|
}
|
|
3908
3624
|
/** Renders any errors contained in the `state` in using the `ErrorList`, if not disabled by `showErrorList`. */
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
3625
|
renderErrors(registry) {
|
|
3912
3626
|
const {
|
|
3913
3627
|
errors,
|
|
@@ -3916,13 +3630,11 @@ class Form extends Component {
|
|
|
3916
3630
|
uiSchema
|
|
3917
3631
|
} = this.state;
|
|
3918
3632
|
const {
|
|
3919
|
-
showErrorList,
|
|
3920
3633
|
formContext
|
|
3921
3634
|
} = this.props;
|
|
3922
3635
|
const options = getUiOptions(uiSchema);
|
|
3923
3636
|
const ErrorListTemplate = getTemplate("ErrorListTemplate", registry, options);
|
|
3924
|
-
|
|
3925
|
-
if (errors && errors.length && showErrorList != false) {
|
|
3637
|
+
if (errors && errors.length) {
|
|
3926
3638
|
return /*#__PURE__*/React.createElement(ErrorListTemplate, {
|
|
3927
3639
|
errors: errors,
|
|
3928
3640
|
errorSchema: errorSchema || {},
|
|
@@ -3931,7 +3643,6 @@ class Form extends Component {
|
|
|
3931
3643
|
formContext: formContext
|
|
3932
3644
|
});
|
|
3933
3645
|
}
|
|
3934
|
-
|
|
3935
3646
|
return null;
|
|
3936
3647
|
}
|
|
3937
3648
|
/** Returns the `formData` with only the elements specified in the `fields` list
|
|
@@ -3940,11 +3651,9 @@ class Form extends Component {
|
|
|
3940
3651
|
* @param fields - The fields to keep while filtering
|
|
3941
3652
|
*/
|
|
3942
3653
|
|
|
3943
|
-
|
|
3944
3654
|
/** Returns the registry for the form */
|
|
3945
3655
|
getRegistry() {
|
|
3946
3656
|
var _this$props$templates;
|
|
3947
|
-
|
|
3948
3657
|
const {
|
|
3949
3658
|
schemaUtils
|
|
3950
3659
|
} = this.state;
|
|
@@ -3955,16 +3664,20 @@ class Form extends Component {
|
|
|
3955
3664
|
formContext
|
|
3956
3665
|
} = getDefaultRegistry();
|
|
3957
3666
|
return {
|
|
3958
|
-
fields: {
|
|
3667
|
+
fields: {
|
|
3668
|
+
...fields,
|
|
3959
3669
|
...this.props.fields
|
|
3960
3670
|
},
|
|
3961
|
-
templates: {
|
|
3671
|
+
templates: {
|
|
3672
|
+
...templates,
|
|
3962
3673
|
...this.props.templates,
|
|
3963
|
-
ButtonTemplates: {
|
|
3674
|
+
ButtonTemplates: {
|
|
3675
|
+
...templates.ButtonTemplates,
|
|
3964
3676
|
...((_this$props$templates = this.props.templates) === null || _this$props$templates === void 0 ? void 0 : _this$props$templates.ButtonTemplates)
|
|
3965
3677
|
}
|
|
3966
3678
|
},
|
|
3967
|
-
widgets: {
|
|
3679
|
+
widgets: {
|
|
3680
|
+
...widgets,
|
|
3968
3681
|
...this.props.widgets
|
|
3969
3682
|
},
|
|
3970
3683
|
rootSchema: this.props.schema,
|
|
@@ -3973,8 +3686,6 @@ class Form extends Component {
|
|
|
3973
3686
|
};
|
|
3974
3687
|
}
|
|
3975
3688
|
/** Provides a function that can be used to programmatically submit the `Form` */
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
3689
|
submit() {
|
|
3979
3690
|
if (this.formElement.current) {
|
|
3980
3691
|
this.formElement.current.dispatchEvent(new CustomEvent("submit", {
|
|
@@ -3988,8 +3699,6 @@ class Form extends Component {
|
|
|
3988
3699
|
*
|
|
3989
3700
|
* @returns - True if the form is valid, false otherwise.
|
|
3990
3701
|
*/
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
3702
|
validateForm() {
|
|
3994
3703
|
const {
|
|
3995
3704
|
extraErrors,
|
|
@@ -4006,14 +3715,12 @@ class Form extends Component {
|
|
|
4006
3715
|
let errorSchema = schemaValidation.errorSchema;
|
|
4007
3716
|
const schemaValidationErrors = errors;
|
|
4008
3717
|
const schemaValidationErrorSchema = errorSchema;
|
|
4009
|
-
|
|
4010
3718
|
if (errors.length > 0) {
|
|
4011
3719
|
if (extraErrors) {
|
|
4012
3720
|
const merged = schemaUtils.mergeValidationData(schemaValidation, extraErrors);
|
|
4013
3721
|
errorSchema = merged.errorSchema;
|
|
4014
3722
|
errors = merged.errors;
|
|
4015
3723
|
}
|
|
4016
|
-
|
|
4017
3724
|
this.setState({
|
|
4018
3725
|
errors,
|
|
4019
3726
|
errorSchema,
|
|
@@ -4028,14 +3735,11 @@ class Form extends Component {
|
|
|
4028
3735
|
});
|
|
4029
3736
|
return false;
|
|
4030
3737
|
}
|
|
4031
|
-
|
|
4032
3738
|
return true;
|
|
4033
3739
|
}
|
|
4034
3740
|
/** Renders the `Form` fields inside the <form> | `tagName` or `_internalFormWrapper`, rendering any errors if
|
|
4035
3741
|
* needed along with the submit button or any children of the form.
|
|
4036
3742
|
*/
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
3743
|
render() {
|
|
4040
3744
|
const {
|
|
4041
3745
|
children,
|
|
@@ -4055,6 +3759,7 @@ class Form extends Component {
|
|
|
4055
3759
|
disabled = false,
|
|
4056
3760
|
readonly = false,
|
|
4057
3761
|
formContext,
|
|
3762
|
+
showErrorList = "top",
|
|
4058
3763
|
_internalFormWrapper
|
|
4059
3764
|
} = this.props;
|
|
4060
3765
|
const {
|
|
@@ -4070,10 +3775,10 @@ class Form extends Component {
|
|
|
4070
3775
|
} = registry.fields;
|
|
4071
3776
|
const {
|
|
4072
3777
|
SubmitButton
|
|
4073
|
-
} = registry.templates.ButtonTemplates;
|
|
4074
|
-
//
|
|
3778
|
+
} = registry.templates.ButtonTemplates;
|
|
3779
|
+
// The `semantic-ui` and `material-ui` themes have `_internalFormWrapper`s that take an `as` prop that is the
|
|
3780
|
+
// PropTypes.elementType to use for the inner tag, so we'll need to pass `tagName` along if it is provided.
|
|
4075
3781
|
// NOTE, the `as` prop is native to `semantic-ui` and is emulated in the `material-ui` theme
|
|
4076
|
-
|
|
4077
3782
|
const as = _internalFormWrapper ? tagName : undefined;
|
|
4078
3783
|
const FormTag = _internalFormWrapper || tagName || "form";
|
|
4079
3784
|
return /*#__PURE__*/React.createElement(FormTag, {
|
|
@@ -4090,7 +3795,7 @@ class Form extends Component {
|
|
|
4090
3795
|
onSubmit: this.onSubmit,
|
|
4091
3796
|
as: as,
|
|
4092
3797
|
ref: this.formElement
|
|
4093
|
-
}, this.renderErrors(registry), /*#__PURE__*/React.createElement(_SchemaField, {
|
|
3798
|
+
}, showErrorList === "top" && this.renderErrors(registry), /*#__PURE__*/React.createElement(_SchemaField, {
|
|
4094
3799
|
name: "",
|
|
4095
3800
|
schema: schema,
|
|
4096
3801
|
uiSchema: uiSchema,
|
|
@@ -4108,36 +3813,38 @@ class Form extends Component {
|
|
|
4108
3813
|
readonly: readonly
|
|
4109
3814
|
}), children ? children : /*#__PURE__*/React.createElement(SubmitButton, {
|
|
4110
3815
|
uiSchema: uiSchema
|
|
4111
|
-
}));
|
|
3816
|
+
}), showErrorList === "bottom" && this.renderErrors(registry));
|
|
4112
3817
|
}
|
|
4113
|
-
|
|
4114
3818
|
}
|
|
4115
3819
|
|
|
4116
3820
|
/** A Higher-Order component that creates a wrapper around a `Form` with the overrides from the `WithThemeProps` */
|
|
4117
|
-
|
|
4118
3821
|
function withTheme(themeProps) {
|
|
4119
3822
|
return /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
4120
3823
|
var _themeProps$templates, _templates;
|
|
4121
|
-
|
|
4122
3824
|
let {
|
|
4123
3825
|
fields,
|
|
4124
3826
|
widgets,
|
|
4125
3827
|
templates,
|
|
4126
3828
|
...directProps
|
|
4127
3829
|
} = _ref;
|
|
4128
|
-
fields = {
|
|
3830
|
+
fields = {
|
|
3831
|
+
...themeProps.fields,
|
|
4129
3832
|
...fields
|
|
4130
3833
|
};
|
|
4131
|
-
widgets = {
|
|
3834
|
+
widgets = {
|
|
3835
|
+
...themeProps.widgets,
|
|
4132
3836
|
...widgets
|
|
4133
3837
|
};
|
|
4134
|
-
templates = {
|
|
3838
|
+
templates = {
|
|
3839
|
+
...themeProps.templates,
|
|
4135
3840
|
...templates,
|
|
4136
|
-
ButtonTemplates: {
|
|
3841
|
+
ButtonTemplates: {
|
|
3842
|
+
...(themeProps === null || themeProps === void 0 ? void 0 : (_themeProps$templates = themeProps.templates) === null || _themeProps$templates === void 0 ? void 0 : _themeProps$templates.ButtonTemplates),
|
|
4137
3843
|
...((_templates = templates) === null || _templates === void 0 ? void 0 : _templates.ButtonTemplates)
|
|
4138
3844
|
}
|
|
4139
3845
|
};
|
|
4140
|
-
return /*#__PURE__*/React.createElement(Form, {
|
|
3846
|
+
return /*#__PURE__*/React.createElement(Form, {
|
|
3847
|
+
...themeProps,
|
|
4141
3848
|
...directProps,
|
|
4142
3849
|
fields: fields,
|
|
4143
3850
|
widgets: widgets,
|