@rjsf/core 6.0.0-alpha.0 → 6.0.0-beta.2
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.umd.js +1680 -809
- package/dist/index.esm.js +2166 -1198
- package/dist/index.esm.js.map +4 -4
- package/dist/index.js +2221 -1299
- package/dist/index.js.map +4 -4
- package/lib/components/Form.d.ts +22 -9
- package/lib/components/Form.d.ts.map +1 -0
- package/lib/components/Form.js +368 -312
- package/lib/components/RichDescription.d.ts +20 -0
- package/lib/components/RichDescription.d.ts.map +1 -0
- package/lib/components/RichDescription.js +17 -0
- package/lib/components/fields/ArrayField.d.ts +20 -9
- package/lib/components/fields/ArrayField.d.ts.map +1 -0
- package/lib/components/fields/ArrayField.js +212 -206
- package/lib/components/fields/BooleanField.d.ts +1 -0
- package/lib/components/fields/BooleanField.d.ts.map +1 -0
- package/lib/components/fields/BooleanField.js +6 -14
- package/lib/components/fields/LayoutGridField.d.ts +480 -0
- package/lib/components/fields/LayoutGridField.d.ts.map +1 -0
- package/lib/components/fields/LayoutGridField.js +711 -0
- package/lib/components/fields/LayoutHeaderField.d.ts +12 -0
- package/lib/components/fields/LayoutHeaderField.d.ts.map +1 -0
- package/lib/components/fields/LayoutHeaderField.js +23 -0
- package/lib/components/fields/LayoutMultiSchemaField.d.ts +28 -0
- package/lib/components/fields/LayoutMultiSchemaField.d.ts.map +1 -0
- package/lib/components/fields/LayoutMultiSchemaField.js +114 -0
- package/lib/components/fields/MultiSchemaField.d.ts +1 -0
- package/lib/components/fields/MultiSchemaField.d.ts.map +1 -0
- package/lib/components/fields/MultiSchemaField.js +31 -31
- package/lib/components/fields/NullField.d.ts +1 -0
- package/lib/components/fields/NullField.d.ts.map +1 -0
- package/lib/components/fields/NullField.js +0 -1
- package/lib/components/fields/NumberField.d.ts +1 -0
- package/lib/components/fields/NumberField.d.ts.map +1 -0
- package/lib/components/fields/NumberField.js +2 -3
- package/lib/components/fields/ObjectField.d.ts +1 -0
- package/lib/components/fields/ObjectField.d.ts.map +1 -0
- package/lib/components/fields/ObjectField.js +146 -141
- package/lib/components/fields/SchemaField.d.ts +1 -0
- package/lib/components/fields/SchemaField.d.ts.map +1 -0
- package/lib/components/fields/SchemaField.js +10 -20
- package/lib/components/fields/StringField.d.ts +1 -0
- package/lib/components/fields/StringField.d.ts.map +1 -0
- package/lib/components/fields/StringField.js +1 -3
- package/lib/components/fields/index.d.ts +1 -0
- package/lib/components/fields/index.d.ts.map +1 -0
- package/lib/components/fields/index.js +14 -9
- package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts +1 -0
- package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts.map +1 -0
- package/lib/components/templates/ArrayFieldDescriptionTemplate.js +0 -1
- package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts +8 -0
- package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts.map +1 -0
- package/lib/components/templates/ArrayFieldItemButtonsTemplate.js +17 -0
- package/lib/components/templates/ArrayFieldItemTemplate.d.ts +4 -3
- package/lib/components/templates/ArrayFieldItemTemplate.d.ts.map +1 -0
- package/lib/components/templates/ArrayFieldItemTemplate.js +7 -6
- package/lib/components/templates/ArrayFieldTemplate.d.ts +2 -1
- package/lib/components/templates/ArrayFieldTemplate.d.ts.map +1 -0
- package/lib/components/templates/ArrayFieldTemplate.js +3 -4
- package/lib/components/templates/ArrayFieldTitleTemplate.d.ts +1 -0
- package/lib/components/templates/ArrayFieldTitleTemplate.d.ts.map +1 -0
- package/lib/components/templates/ArrayFieldTitleTemplate.js +0 -1
- package/lib/components/templates/BaseInputTemplate.d.ts +1 -0
- package/lib/components/templates/BaseInputTemplate.d.ts.map +1 -0
- package/lib/components/templates/BaseInputTemplate.js +0 -1
- package/lib/components/templates/ButtonTemplates/AddButton.d.ts +1 -0
- package/lib/components/templates/ButtonTemplates/AddButton.d.ts.map +1 -0
- package/lib/components/templates/ButtonTemplates/AddButton.js +1 -2
- package/lib/components/templates/ButtonTemplates/IconButton.d.ts +1 -0
- package/lib/components/templates/ButtonTemplates/IconButton.d.ts.map +1 -0
- package/lib/components/templates/ButtonTemplates/IconButton.js +4 -5
- package/lib/components/templates/ButtonTemplates/SubmitButton.d.ts +1 -0
- package/lib/components/templates/ButtonTemplates/SubmitButton.d.ts.map +1 -0
- package/lib/components/templates/ButtonTemplates/SubmitButton.js +0 -1
- package/lib/components/templates/ButtonTemplates/index.d.ts +1 -0
- package/lib/components/templates/ButtonTemplates/index.d.ts.map +1 -0
- package/lib/components/templates/ButtonTemplates/index.js +3 -4
- package/lib/components/templates/DescriptionField.d.ts +1 -0
- package/lib/components/templates/DescriptionField.d.ts.map +1 -0
- package/lib/components/templates/DescriptionField.js +3 -8
- package/lib/components/templates/ErrorList.d.ts +1 -0
- package/lib/components/templates/ErrorList.d.ts.map +1 -0
- package/lib/components/templates/ErrorList.js +0 -1
- package/lib/components/templates/FieldErrorTemplate.d.ts +1 -0
- package/lib/components/templates/FieldErrorTemplate.d.ts.map +1 -0
- package/lib/components/templates/FieldErrorTemplate.js +0 -1
- package/lib/components/templates/FieldHelpTemplate.d.ts +1 -0
- package/lib/components/templates/FieldHelpTemplate.d.ts.map +1 -0
- package/lib/components/templates/FieldHelpTemplate.js +0 -1
- package/lib/components/templates/FieldTemplate/FieldTemplate.d.ts +1 -0
- package/lib/components/templates/FieldTemplate/FieldTemplate.d.ts.map +1 -0
- package/lib/components/templates/FieldTemplate/FieldTemplate.js +1 -2
- package/lib/components/templates/FieldTemplate/Label.d.ts +1 -0
- package/lib/components/templates/FieldTemplate/Label.d.ts.map +1 -0
- package/lib/components/templates/FieldTemplate/Label.js +0 -1
- package/lib/components/templates/FieldTemplate/index.d.ts +2 -1
- package/lib/components/templates/FieldTemplate/index.d.ts.map +1 -0
- package/lib/components/templates/FieldTemplate/index.js +1 -2
- package/lib/components/templates/GridTemplate.d.ts +8 -0
- package/lib/components/templates/GridTemplate.d.ts.map +1 -0
- package/lib/components/templates/GridTemplate.js +10 -0
- package/lib/components/templates/ObjectFieldTemplate.d.ts +1 -0
- package/lib/components/templates/ObjectFieldTemplate.d.ts.map +1 -0
- package/lib/components/templates/ObjectFieldTemplate.js +2 -3
- package/lib/components/templates/TitleField.d.ts +1 -0
- package/lib/components/templates/TitleField.d.ts.map +1 -0
- package/lib/components/templates/TitleField.js +0 -1
- package/lib/components/templates/UnsupportedField.d.ts +1 -0
- package/lib/components/templates/UnsupportedField.d.ts.map +1 -0
- package/lib/components/templates/UnsupportedField.js +0 -1
- package/lib/components/templates/WrapIfAdditionalTemplate.d.ts +1 -0
- package/lib/components/templates/WrapIfAdditionalTemplate.d.ts.map +1 -0
- package/lib/components/templates/WrapIfAdditionalTemplate.js +10 -6
- package/lib/components/templates/index.d.ts +1 -0
- package/lib/components/templates/index.d.ts.map +1 -0
- package/lib/components/templates/index.js +19 -16
- package/lib/components/widgets/AltDateTimeWidget.d.ts +1 -0
- package/lib/components/widgets/AltDateTimeWidget.d.ts.map +1 -0
- package/lib/components/widgets/AltDateTimeWidget.js +0 -1
- package/lib/components/widgets/AltDateWidget.d.ts +1 -0
- package/lib/components/widgets/AltDateWidget.d.ts.map +1 -0
- package/lib/components/widgets/AltDateWidget.js +0 -1
- package/lib/components/widgets/CheckboxWidget.d.ts +1 -0
- package/lib/components/widgets/CheckboxWidget.d.ts.map +1 -0
- package/lib/components/widgets/CheckboxWidget.js +2 -4
- package/lib/components/widgets/CheckboxesWidget.d.ts +1 -0
- package/lib/components/widgets/CheckboxesWidget.d.ts.map +1 -0
- package/lib/components/widgets/CheckboxesWidget.js +0 -1
- package/lib/components/widgets/ColorWidget.d.ts +1 -0
- package/lib/components/widgets/ColorWidget.d.ts.map +1 -0
- package/lib/components/widgets/ColorWidget.js +0 -1
- package/lib/components/widgets/DateTimeWidget.d.ts +1 -0
- package/lib/components/widgets/DateTimeWidget.d.ts.map +1 -0
- package/lib/components/widgets/DateTimeWidget.js +0 -1
- package/lib/components/widgets/DateWidget.d.ts +1 -0
- package/lib/components/widgets/DateWidget.d.ts.map +1 -0
- package/lib/components/widgets/DateWidget.js +0 -1
- package/lib/components/widgets/EmailWidget.d.ts +1 -0
- package/lib/components/widgets/EmailWidget.d.ts.map +1 -0
- package/lib/components/widgets/EmailWidget.js +0 -1
- package/lib/components/widgets/FileWidget.d.ts +1 -0
- package/lib/components/widgets/FileWidget.d.ts.map +1 -0
- package/lib/components/widgets/FileWidget.js +3 -5
- package/lib/components/widgets/HiddenWidget.d.ts +1 -0
- package/lib/components/widgets/HiddenWidget.d.ts.map +1 -0
- package/lib/components/widgets/HiddenWidget.js +0 -1
- package/lib/components/widgets/PasswordWidget.d.ts +1 -0
- package/lib/components/widgets/PasswordWidget.d.ts.map +1 -0
- package/lib/components/widgets/PasswordWidget.js +0 -1
- package/lib/components/widgets/RadioWidget.d.ts +1 -0
- package/lib/components/widgets/RadioWidget.d.ts.map +1 -0
- package/lib/components/widgets/RadioWidget.js +3 -4
- package/lib/components/widgets/RangeWidget.d.ts +1 -0
- package/lib/components/widgets/RangeWidget.d.ts.map +1 -0
- package/lib/components/widgets/RangeWidget.js +0 -1
- package/lib/components/widgets/RatingWidget.d.ts +15 -0
- package/lib/components/widgets/RatingWidget.d.ts.map +1 -0
- package/lib/components/widgets/RatingWidget.js +63 -0
- package/lib/components/widgets/SelectWidget.d.ts +1 -0
- package/lib/components/widgets/SelectWidget.d.ts.map +1 -0
- package/lib/components/widgets/SelectWidget.js +4 -5
- package/lib/components/widgets/TextWidget.d.ts +1 -0
- package/lib/components/widgets/TextWidget.d.ts.map +1 -0
- package/lib/components/widgets/TextWidget.js +0 -1
- package/lib/components/widgets/TextareaWidget.d.ts +1 -0
- package/lib/components/widgets/TextareaWidget.d.ts.map +1 -0
- package/lib/components/widgets/TextareaWidget.js +0 -1
- package/lib/components/widgets/TimeWidget.d.ts +1 -0
- package/lib/components/widgets/TimeWidget.d.ts.map +1 -0
- package/lib/components/widgets/TimeWidget.js +0 -1
- package/lib/components/widgets/URLWidget.d.ts +1 -0
- package/lib/components/widgets/URLWidget.d.ts.map +1 -0
- package/lib/components/widgets/URLWidget.js +0 -1
- package/lib/components/widgets/UpDownWidget.d.ts +1 -0
- package/lib/components/widgets/UpDownWidget.d.ts.map +1 -0
- package/lib/components/widgets/UpDownWidget.js +0 -1
- package/lib/components/widgets/index.d.ts +1 -0
- package/lib/components/widgets/index.d.ts.map +1 -0
- package/lib/components/widgets/index.js +21 -20
- package/lib/getDefaultRegistry.d.ts +1 -0
- package/lib/getDefaultRegistry.d.ts.map +1 -0
- package/lib/getDefaultRegistry.js +3 -4
- package/lib/index.d.ts +7 -5
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +5 -5
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/withTheme.d.ts +2 -1
- package/lib/withTheme.d.ts.map +1 -0
- package/lib/withTheme.js +7 -8
- package/package.json +46 -37
- package/src/components/Form.tsx +127 -41
- package/src/components/RichDescription.tsx +50 -0
- package/src/components/fields/ArrayField.tsx +34 -24
- package/src/components/fields/BooleanField.tsx +6 -14
- package/src/components/fields/LayoutGridField.tsx +967 -0
- package/src/components/fields/LayoutHeaderField.tsx +49 -0
- package/src/components/fields/LayoutMultiSchemaField.tsx +228 -0
- package/src/components/fields/MultiSchemaField.tsx +9 -4
- package/src/components/fields/NullField.tsx +1 -1
- package/src/components/fields/NumberField.tsx +5 -5
- package/src/components/fields/ObjectField.tsx +32 -24
- package/src/components/fields/SchemaField.tsx +17 -30
- package/src/components/fields/StringField.tsx +2 -2
- package/src/components/fields/index.ts +7 -1
- package/src/components/templates/ArrayFieldDescriptionTemplate.tsx +2 -2
- package/src/components/templates/ArrayFieldItemButtonsTemplate.tsx +85 -0
- package/src/components/templates/ArrayFieldItemTemplate.tsx +18 -57
- package/src/components/templates/ArrayFieldTemplate.tsx +10 -8
- package/src/components/templates/ArrayFieldTitleTemplate.tsx +2 -2
- package/src/components/templates/BaseInputTemplate.tsx +4 -4
- package/src/components/templates/ButtonTemplates/IconButton.tsx +9 -36
- package/src/components/templates/ButtonTemplates/SubmitButton.tsx +1 -1
- package/src/components/templates/ButtonTemplates/index.ts +1 -1
- package/src/components/templates/DescriptionField.tsx +9 -15
- package/src/components/templates/FieldErrorTemplate.tsx +1 -1
- package/src/components/templates/FieldHelpTemplate.tsx +1 -1
- package/src/components/templates/FieldTemplate/FieldTemplate.tsx +2 -2
- package/src/components/templates/GridTemplate.tsx +15 -0
- package/src/components/templates/ObjectFieldTemplate.tsx +5 -3
- package/src/components/templates/TitleField.tsx +1 -1
- package/src/components/templates/UnsupportedField.tsx +1 -1
- package/src/components/templates/WrapIfAdditionalTemplate.tsx +14 -4
- package/src/components/templates/index.ts +4 -0
- package/src/components/widgets/AltDateWidget.tsx +9 -6
- package/src/components/widgets/CheckboxWidget.tsx +5 -5
- package/src/components/widgets/CheckboxesWidget.tsx +2 -2
- package/src/components/widgets/ColorWidget.tsx +1 -1
- package/src/components/widgets/DateTimeWidget.tsx +1 -1
- package/src/components/widgets/DateWidget.tsx +1 -1
- package/src/components/widgets/EmailWidget.tsx +1 -1
- package/src/components/widgets/FileWidget.tsx +5 -5
- package/src/components/widgets/PasswordWidget.tsx +1 -1
- package/src/components/widgets/RadioWidget.tsx +3 -3
- package/src/components/widgets/RangeWidget.tsx +1 -1
- package/src/components/widgets/RatingWidget.tsx +129 -0
- package/src/components/widgets/SelectWidget.tsx +4 -3
- package/src/components/widgets/TextWidget.tsx +1 -1
- package/src/components/widgets/TextareaWidget.tsx +3 -3
- package/src/components/widgets/TimeWidget.tsx +1 -1
- package/src/components/widgets/URLWidget.tsx +1 -1
- package/src/components/widgets/UpDownWidget.tsx +1 -1
- package/src/components/widgets/index.ts +3 -1
- package/src/getDefaultRegistry.ts +1 -1
- package/src/index.ts +3 -2
- package/src/tsconfig.json +14 -6
- package/src/withTheme.tsx +4 -3
- package/LICENSE.md +0 -201
- package/lib/components/Form.js.map +0 -1
- package/lib/components/fields/ArrayField.js.map +0 -1
- package/lib/components/fields/BooleanField.js.map +0 -1
- package/lib/components/fields/MultiSchemaField.js.map +0 -1
- package/lib/components/fields/NullField.js.map +0 -1
- package/lib/components/fields/NumberField.js.map +0 -1
- package/lib/components/fields/ObjectField.js.map +0 -1
- package/lib/components/fields/SchemaField.js.map +0 -1
- package/lib/components/fields/StringField.js.map +0 -1
- package/lib/components/fields/index.js.map +0 -1
- package/lib/components/templates/ArrayFieldDescriptionTemplate.js.map +0 -1
- package/lib/components/templates/ArrayFieldItemTemplate.js.map +0 -1
- package/lib/components/templates/ArrayFieldTemplate.js.map +0 -1
- package/lib/components/templates/ArrayFieldTitleTemplate.js.map +0 -1
- package/lib/components/templates/BaseInputTemplate.js.map +0 -1
- package/lib/components/templates/ButtonTemplates/AddButton.js.map +0 -1
- package/lib/components/templates/ButtonTemplates/IconButton.js.map +0 -1
- package/lib/components/templates/ButtonTemplates/SubmitButton.js.map +0 -1
- package/lib/components/templates/ButtonTemplates/index.js.map +0 -1
- package/lib/components/templates/DescriptionField.js.map +0 -1
- package/lib/components/templates/ErrorList.js.map +0 -1
- package/lib/components/templates/FieldErrorTemplate.js.map +0 -1
- package/lib/components/templates/FieldHelpTemplate.js.map +0 -1
- package/lib/components/templates/FieldTemplate/FieldTemplate.js.map +0 -1
- package/lib/components/templates/FieldTemplate/Label.js.map +0 -1
- package/lib/components/templates/FieldTemplate/index.js.map +0 -1
- package/lib/components/templates/ObjectFieldTemplate.js.map +0 -1
- package/lib/components/templates/TitleField.js.map +0 -1
- package/lib/components/templates/UnsupportedField.js.map +0 -1
- package/lib/components/templates/WrapIfAdditionalTemplate.js.map +0 -1
- package/lib/components/templates/index.js.map +0 -1
- package/lib/components/widgets/AltDateTimeWidget.js.map +0 -1
- package/lib/components/widgets/AltDateWidget.js.map +0 -1
- package/lib/components/widgets/CheckboxWidget.js.map +0 -1
- package/lib/components/widgets/CheckboxesWidget.js.map +0 -1
- package/lib/components/widgets/ColorWidget.js.map +0 -1
- package/lib/components/widgets/DateTimeWidget.js.map +0 -1
- package/lib/components/widgets/DateWidget.js.map +0 -1
- package/lib/components/widgets/EmailWidget.js.map +0 -1
- package/lib/components/widgets/FileWidget.js.map +0 -1
- package/lib/components/widgets/HiddenWidget.js.map +0 -1
- package/lib/components/widgets/PasswordWidget.js.map +0 -1
- package/lib/components/widgets/RadioWidget.js.map +0 -1
- package/lib/components/widgets/RangeWidget.js.map +0 -1
- package/lib/components/widgets/SelectWidget.js.map +0 -1
- package/lib/components/widgets/TextWidget.js.map +0 -1
- package/lib/components/widgets/TextareaWidget.js.map +0 -1
- package/lib/components/widgets/TimeWidget.js.map +0 -1
- package/lib/components/widgets/URLWidget.js.map +0 -1
- package/lib/components/widgets/UpDownWidget.js.map +0 -1
- package/lib/components/widgets/index.js.map +0 -1
- package/lib/getDefaultRegistry.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/withTheme.js.map +0 -1
package/dist/core.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@rjsf/utils'), require('lodash/forEach'), require('lodash/get'), require('lodash/isEmpty'), require('lodash/pick'), require('lodash/toPath'), require('lodash/cloneDeep'), require('lodash/isObject'), require('lodash/set'), require('nanoid'), require('react/jsx-runtime'), require('lodash/
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'react', '@rjsf/utils', 'lodash/forEach', 'lodash/get', 'lodash/isEmpty', 'lodash/pick', 'lodash/toPath', 'lodash/cloneDeep', 'lodash/isObject', 'lodash/set', 'nanoid', 'react/jsx-runtime', 'lodash/
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.JSONSchemaForm = {}, global.react, global.utils, global._forEach, global.
|
|
5
|
-
})(this, (function (exports, react, utils, _forEach,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@rjsf/utils'), require('lodash/forEach'), require('lodash/get'), require('lodash/isEmpty'), require('lodash/isNil'), require('lodash/pick'), require('lodash/toPath'), require('lodash/cloneDeep'), require('lodash/isObject'), require('lodash/set'), require('nanoid'), require('react/jsx-runtime'), require('lodash/each'), require('lodash/flatten'), require('lodash/has'), require('lodash/includes'), require('lodash/intersection'), require('lodash/isFunction'), require('lodash/isEqual'), require('lodash/isPlainObject'), require('lodash/isString'), require('lodash/isUndefined'), require('lodash/noop'), require('lodash/omit'), require('markdown-to-jsx'), require('lodash/unset')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'react', '@rjsf/utils', 'lodash/forEach', 'lodash/get', 'lodash/isEmpty', 'lodash/isNil', 'lodash/pick', 'lodash/toPath', 'lodash/cloneDeep', 'lodash/isObject', 'lodash/set', 'nanoid', 'react/jsx-runtime', 'lodash/each', 'lodash/flatten', 'lodash/has', 'lodash/includes', 'lodash/intersection', 'lodash/isFunction', 'lodash/isEqual', 'lodash/isPlainObject', 'lodash/isString', 'lodash/isUndefined', 'lodash/noop', 'lodash/omit', 'markdown-to-jsx', 'lodash/unset'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.JSONSchemaForm = {}, global.react, global.utils, global._forEach, global.get2, global.isEmpty, global._isNil, global._pick, global._toPath, global.cloneDeep2, global.isObject, global.set, global.nanoid, global.jsxRuntime, global.each, global.flatten, global.has, global.includes, global.intersection, global.isFunction, global.isEqual, global.isPlainObject, global.isString, global.isUndefined, global.noop, global.omit3, global.Markdown, global.unset));
|
|
5
|
+
})(this, (function (exports, react, utils, _forEach, get2, isEmpty, _isNil, _pick, _toPath, cloneDeep2, isObject, set, nanoid, jsxRuntime, each, flatten, has, includes, intersection, isFunction, isEqual, isPlainObject, isString, isUndefined, noop, omit3, Markdown, unset) { 'use strict';
|
|
6
6
|
|
|
7
7
|
// src/components/Form.tsx
|
|
8
8
|
function generateRowId() {
|
|
@@ -29,189 +29,6 @@
|
|
|
29
29
|
*/
|
|
30
30
|
constructor(props) {
|
|
31
31
|
super(props);
|
|
32
|
-
/** Returns the default form information for an item based on the schema for that item. Deals with the possibility
|
|
33
|
-
* that the schema is fixed and allows additional items.
|
|
34
|
-
*/
|
|
35
|
-
this._getNewFormDataRow = () => {
|
|
36
|
-
const { schema, registry } = this.props;
|
|
37
|
-
const { schemaUtils } = registry;
|
|
38
|
-
let itemSchema = schema.items;
|
|
39
|
-
if (utils.isFixedItems(schema) && utils.allowAdditionalItems(schema)) {
|
|
40
|
-
itemSchema = schema.additionalItems;
|
|
41
|
-
}
|
|
42
|
-
return schemaUtils.getDefaultFormState(itemSchema);
|
|
43
|
-
};
|
|
44
|
-
/** Callback handler for when the user clicks on the add button. Creates a new row of keyed form data at the end of
|
|
45
|
-
* the list, adding it into the state, and then returning `onChange()` with the plain form data converted from the
|
|
46
|
-
* keyed data
|
|
47
|
-
*
|
|
48
|
-
* @param event - The event for the click
|
|
49
|
-
*/
|
|
50
|
-
this.onAddClick = (event) => {
|
|
51
|
-
this._handleAddClick(event);
|
|
52
|
-
};
|
|
53
|
-
/** Callback handler for when the user clicks on the add button on an existing array element. Creates a new row of
|
|
54
|
-
* keyed form data inserted at the `index`, adding it into the state, and then returning `onChange()` with the plain
|
|
55
|
-
* form data converted from the keyed data
|
|
56
|
-
*
|
|
57
|
-
* @param index - The index at which the add button is clicked
|
|
58
|
-
*/
|
|
59
|
-
this.onAddIndexClick = (index) => {
|
|
60
|
-
return (event) => {
|
|
61
|
-
this._handleAddClick(event, index);
|
|
62
|
-
};
|
|
63
|
-
};
|
|
64
|
-
/** Callback handler for when the user clicks on the copy button on an existing array element. Clones the row of
|
|
65
|
-
* keyed form data at the `index` into the next position in the state, and then returning `onChange()` with the plain
|
|
66
|
-
* form data converted from the keyed data
|
|
67
|
-
*
|
|
68
|
-
* @param index - The index at which the copy button is clicked
|
|
69
|
-
*/
|
|
70
|
-
this.onCopyIndexClick = (index) => {
|
|
71
|
-
return (event) => {
|
|
72
|
-
if (event) {
|
|
73
|
-
event.preventDefault();
|
|
74
|
-
}
|
|
75
|
-
const { onChange, errorSchema } = this.props;
|
|
76
|
-
const { keyedFormData } = this.state;
|
|
77
|
-
let newErrorSchema;
|
|
78
|
-
if (errorSchema) {
|
|
79
|
-
newErrorSchema = {};
|
|
80
|
-
for (const idx in errorSchema) {
|
|
81
|
-
const i = parseInt(idx);
|
|
82
|
-
if (i <= index) {
|
|
83
|
-
set(newErrorSchema, [i], errorSchema[idx]);
|
|
84
|
-
} else if (i > index) {
|
|
85
|
-
set(newErrorSchema, [i + 1], errorSchema[idx]);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const newKeyedFormDataRow = {
|
|
90
|
-
key: generateRowId(),
|
|
91
|
-
item: cloneDeep(keyedFormData[index].item)
|
|
92
|
-
};
|
|
93
|
-
const newKeyedFormData = [...keyedFormData];
|
|
94
|
-
if (index !== void 0) {
|
|
95
|
-
newKeyedFormData.splice(index + 1, 0, newKeyedFormDataRow);
|
|
96
|
-
} else {
|
|
97
|
-
newKeyedFormData.push(newKeyedFormDataRow);
|
|
98
|
-
}
|
|
99
|
-
this.setState(
|
|
100
|
-
{
|
|
101
|
-
keyedFormData: newKeyedFormData,
|
|
102
|
-
updatedKeyedFormData: true
|
|
103
|
-
},
|
|
104
|
-
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
|
|
105
|
-
);
|
|
106
|
-
};
|
|
107
|
-
};
|
|
108
|
-
/** Callback handler for when the user clicks on the remove button on an existing array element. Removes the row of
|
|
109
|
-
* keyed form data at the `index` in the state, and then returning `onChange()` with the plain form data converted
|
|
110
|
-
* from the keyed data
|
|
111
|
-
*
|
|
112
|
-
* @param index - The index at which the remove button is clicked
|
|
113
|
-
*/
|
|
114
|
-
this.onDropIndexClick = (index) => {
|
|
115
|
-
return (event) => {
|
|
116
|
-
if (event) {
|
|
117
|
-
event.preventDefault();
|
|
118
|
-
}
|
|
119
|
-
const { onChange, errorSchema } = this.props;
|
|
120
|
-
const { keyedFormData } = this.state;
|
|
121
|
-
let newErrorSchema;
|
|
122
|
-
if (errorSchema) {
|
|
123
|
-
newErrorSchema = {};
|
|
124
|
-
for (const idx in errorSchema) {
|
|
125
|
-
const i = parseInt(idx);
|
|
126
|
-
if (i < index) {
|
|
127
|
-
set(newErrorSchema, [i], errorSchema[idx]);
|
|
128
|
-
} else if (i > index) {
|
|
129
|
-
set(newErrorSchema, [i - 1], errorSchema[idx]);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
const newKeyedFormData = keyedFormData.filter((_, i) => i !== index);
|
|
134
|
-
this.setState(
|
|
135
|
-
{
|
|
136
|
-
keyedFormData: newKeyedFormData,
|
|
137
|
-
updatedKeyedFormData: true
|
|
138
|
-
},
|
|
139
|
-
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
|
|
140
|
-
);
|
|
141
|
-
};
|
|
142
|
-
};
|
|
143
|
-
/** Callback handler for when the user clicks on one of the move item buttons on an existing array element. Moves the
|
|
144
|
-
* row of keyed form data at the `index` to the `newIndex` in the state, and then returning `onChange()` with the
|
|
145
|
-
* plain form data converted from the keyed data
|
|
146
|
-
*
|
|
147
|
-
* @param index - The index of the item to move
|
|
148
|
-
* @param newIndex - The index to where the item is to be moved
|
|
149
|
-
*/
|
|
150
|
-
this.onReorderClick = (index, newIndex) => {
|
|
151
|
-
return (event) => {
|
|
152
|
-
if (event) {
|
|
153
|
-
event.preventDefault();
|
|
154
|
-
event.currentTarget.blur();
|
|
155
|
-
}
|
|
156
|
-
const { onChange, errorSchema } = this.props;
|
|
157
|
-
let newErrorSchema;
|
|
158
|
-
if (errorSchema) {
|
|
159
|
-
newErrorSchema = {};
|
|
160
|
-
for (const idx in errorSchema) {
|
|
161
|
-
const i = parseInt(idx);
|
|
162
|
-
if (i == index) {
|
|
163
|
-
set(newErrorSchema, [newIndex], errorSchema[index]);
|
|
164
|
-
} else if (i == newIndex) {
|
|
165
|
-
set(newErrorSchema, [index], errorSchema[newIndex]);
|
|
166
|
-
} else {
|
|
167
|
-
set(newErrorSchema, [idx], errorSchema[i]);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
const { keyedFormData } = this.state;
|
|
172
|
-
function reOrderArray() {
|
|
173
|
-
const _newKeyedFormData = keyedFormData.slice();
|
|
174
|
-
_newKeyedFormData.splice(index, 1);
|
|
175
|
-
_newKeyedFormData.splice(newIndex, 0, keyedFormData[index]);
|
|
176
|
-
return _newKeyedFormData;
|
|
177
|
-
}
|
|
178
|
-
const newKeyedFormData = reOrderArray();
|
|
179
|
-
this.setState(
|
|
180
|
-
{
|
|
181
|
-
keyedFormData: newKeyedFormData
|
|
182
|
-
},
|
|
183
|
-
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
|
|
184
|
-
);
|
|
185
|
-
};
|
|
186
|
-
};
|
|
187
|
-
/** Callback handler used to deal with changing the value of the data in the array at the `index`. Calls the
|
|
188
|
-
* `onChange` callback with the updated form data
|
|
189
|
-
*
|
|
190
|
-
* @param index - The index of the item being changed
|
|
191
|
-
*/
|
|
192
|
-
this.onChangeForIndex = (index) => {
|
|
193
|
-
return (value, newErrorSchema, id) => {
|
|
194
|
-
const { formData, onChange, errorSchema } = this.props;
|
|
195
|
-
const arrayData = Array.isArray(formData) ? formData : [];
|
|
196
|
-
const newFormData = arrayData.map((item, i) => {
|
|
197
|
-
const jsonValue = typeof value === "undefined" ? null : value;
|
|
198
|
-
return index === i ? jsonValue : item;
|
|
199
|
-
});
|
|
200
|
-
onChange(
|
|
201
|
-
newFormData,
|
|
202
|
-
errorSchema && errorSchema && {
|
|
203
|
-
...errorSchema,
|
|
204
|
-
[index]: newErrorSchema
|
|
205
|
-
},
|
|
206
|
-
id
|
|
207
|
-
);
|
|
208
|
-
};
|
|
209
|
-
};
|
|
210
|
-
/** Callback handler used to change the value for a checkbox */
|
|
211
|
-
this.onSelectChange = (value) => {
|
|
212
|
-
const { onChange, idSchema } = this.props;
|
|
213
|
-
onChange(value, void 0, idSchema && idSchema.$id);
|
|
214
|
-
};
|
|
215
32
|
const { formData = [] } = props;
|
|
216
33
|
const keyedFormData = generateKeyedFormData(formData);
|
|
217
34
|
this.state = {
|
|
@@ -249,10 +66,10 @@
|
|
|
249
66
|
get itemTitle() {
|
|
250
67
|
const { schema, registry } = this.props;
|
|
251
68
|
const { translateString } = registry;
|
|
252
|
-
return
|
|
69
|
+
return get2(
|
|
253
70
|
schema,
|
|
254
71
|
[utils.ITEMS_KEY, "title"],
|
|
255
|
-
|
|
72
|
+
get2(schema, [utils.ITEMS_KEY, "description"], translateString(utils.TranslatableString.ArrayItemTitle))
|
|
256
73
|
);
|
|
257
74
|
}
|
|
258
75
|
/** Determines whether the item described in the schema is always required, which is determined by whether any item
|
|
@@ -286,6 +103,18 @@
|
|
|
286
103
|
}
|
|
287
104
|
return addable;
|
|
288
105
|
}
|
|
106
|
+
/** Returns the default form information for an item based on the schema for that item. Deals with the possibility
|
|
107
|
+
* that the schema is fixed and allows additional items.
|
|
108
|
+
*/
|
|
109
|
+
_getNewFormDataRow = () => {
|
|
110
|
+
const { schema, registry } = this.props;
|
|
111
|
+
const { schemaUtils } = registry;
|
|
112
|
+
let itemSchema = schema.items;
|
|
113
|
+
if (utils.isFixedItems(schema) && utils.allowAdditionalItems(schema)) {
|
|
114
|
+
itemSchema = schema.additionalItems;
|
|
115
|
+
}
|
|
116
|
+
return schemaUtils.getDefaultFormState(itemSchema);
|
|
117
|
+
};
|
|
289
118
|
/** Callback handler for when the user clicks on the add or add at index buttons. Creates a new row of keyed form data
|
|
290
119
|
* either at the end of the list (when index is not specified) or inserted at the `index` when it is, adding it into
|
|
291
120
|
* the state, and then returning `onChange()` with the plain form data converted from the keyed data
|
|
@@ -329,6 +158,177 @@
|
|
|
329
158
|
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
|
|
330
159
|
);
|
|
331
160
|
}
|
|
161
|
+
/** Callback handler for when the user clicks on the add button. Creates a new row of keyed form data at the end of
|
|
162
|
+
* the list, adding it into the state, and then returning `onChange()` with the plain form data converted from the
|
|
163
|
+
* keyed data
|
|
164
|
+
*
|
|
165
|
+
* @param event - The event for the click
|
|
166
|
+
*/
|
|
167
|
+
onAddClick = (event) => {
|
|
168
|
+
this._handleAddClick(event);
|
|
169
|
+
};
|
|
170
|
+
/** Callback handler for when the user clicks on the add button on an existing array element. Creates a new row of
|
|
171
|
+
* keyed form data inserted at the `index`, adding it into the state, and then returning `onChange()` with the plain
|
|
172
|
+
* form data converted from the keyed data
|
|
173
|
+
*
|
|
174
|
+
* @param index - The index at which the add button is clicked
|
|
175
|
+
*/
|
|
176
|
+
onAddIndexClick = (index) => {
|
|
177
|
+
return (event) => {
|
|
178
|
+
this._handleAddClick(event, index);
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
/** Callback handler for when the user clicks on the copy button on an existing array element. Clones the row of
|
|
182
|
+
* keyed form data at the `index` into the next position in the state, and then returning `onChange()` with the plain
|
|
183
|
+
* form data converted from the keyed data
|
|
184
|
+
*
|
|
185
|
+
* @param index - The index at which the copy button is clicked
|
|
186
|
+
*/
|
|
187
|
+
onCopyIndexClick = (index) => {
|
|
188
|
+
return (event) => {
|
|
189
|
+
if (event) {
|
|
190
|
+
event.preventDefault();
|
|
191
|
+
}
|
|
192
|
+
const { onChange, errorSchema } = this.props;
|
|
193
|
+
const { keyedFormData } = this.state;
|
|
194
|
+
let newErrorSchema;
|
|
195
|
+
if (errorSchema) {
|
|
196
|
+
newErrorSchema = {};
|
|
197
|
+
for (const idx in errorSchema) {
|
|
198
|
+
const i = parseInt(idx);
|
|
199
|
+
if (i <= index) {
|
|
200
|
+
set(newErrorSchema, [i], errorSchema[idx]);
|
|
201
|
+
} else if (i > index) {
|
|
202
|
+
set(newErrorSchema, [i + 1], errorSchema[idx]);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const newKeyedFormDataRow = {
|
|
207
|
+
key: generateRowId(),
|
|
208
|
+
item: cloneDeep2(keyedFormData[index].item)
|
|
209
|
+
};
|
|
210
|
+
const newKeyedFormData = [...keyedFormData];
|
|
211
|
+
if (index !== void 0) {
|
|
212
|
+
newKeyedFormData.splice(index + 1, 0, newKeyedFormDataRow);
|
|
213
|
+
} else {
|
|
214
|
+
newKeyedFormData.push(newKeyedFormDataRow);
|
|
215
|
+
}
|
|
216
|
+
this.setState(
|
|
217
|
+
{
|
|
218
|
+
keyedFormData: newKeyedFormData,
|
|
219
|
+
updatedKeyedFormData: true
|
|
220
|
+
},
|
|
221
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
|
|
222
|
+
);
|
|
223
|
+
};
|
|
224
|
+
};
|
|
225
|
+
/** Callback handler for when the user clicks on the remove button on an existing array element. Removes the row of
|
|
226
|
+
* keyed form data at the `index` in the state, and then returning `onChange()` with the plain form data converted
|
|
227
|
+
* from the keyed data
|
|
228
|
+
*
|
|
229
|
+
* @param index - The index at which the remove button is clicked
|
|
230
|
+
*/
|
|
231
|
+
onDropIndexClick = (index) => {
|
|
232
|
+
return (event) => {
|
|
233
|
+
if (event) {
|
|
234
|
+
event.preventDefault();
|
|
235
|
+
}
|
|
236
|
+
const { onChange, errorSchema } = this.props;
|
|
237
|
+
const { keyedFormData } = this.state;
|
|
238
|
+
let newErrorSchema;
|
|
239
|
+
if (errorSchema) {
|
|
240
|
+
newErrorSchema = {};
|
|
241
|
+
for (const idx in errorSchema) {
|
|
242
|
+
const i = parseInt(idx);
|
|
243
|
+
if (i < index) {
|
|
244
|
+
set(newErrorSchema, [i], errorSchema[idx]);
|
|
245
|
+
} else if (i > index) {
|
|
246
|
+
set(newErrorSchema, [i - 1], errorSchema[idx]);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const newKeyedFormData = keyedFormData.filter((_, i) => i !== index);
|
|
251
|
+
this.setState(
|
|
252
|
+
{
|
|
253
|
+
keyedFormData: newKeyedFormData,
|
|
254
|
+
updatedKeyedFormData: true
|
|
255
|
+
},
|
|
256
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
|
|
257
|
+
);
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
/** Callback handler for when the user clicks on one of the move item buttons on an existing array element. Moves the
|
|
261
|
+
* row of keyed form data at the `index` to the `newIndex` in the state, and then returning `onChange()` with the
|
|
262
|
+
* plain form data converted from the keyed data
|
|
263
|
+
*
|
|
264
|
+
* @param index - The index of the item to move
|
|
265
|
+
* @param newIndex - The index to where the item is to be moved
|
|
266
|
+
*/
|
|
267
|
+
onReorderClick = (index, newIndex) => {
|
|
268
|
+
return (event) => {
|
|
269
|
+
if (event) {
|
|
270
|
+
event.preventDefault();
|
|
271
|
+
event.currentTarget.blur();
|
|
272
|
+
}
|
|
273
|
+
const { onChange, errorSchema } = this.props;
|
|
274
|
+
let newErrorSchema;
|
|
275
|
+
if (errorSchema) {
|
|
276
|
+
newErrorSchema = {};
|
|
277
|
+
for (const idx in errorSchema) {
|
|
278
|
+
const i = parseInt(idx);
|
|
279
|
+
if (i == index) {
|
|
280
|
+
set(newErrorSchema, [newIndex], errorSchema[index]);
|
|
281
|
+
} else if (i == newIndex) {
|
|
282
|
+
set(newErrorSchema, [index], errorSchema[newIndex]);
|
|
283
|
+
} else {
|
|
284
|
+
set(newErrorSchema, [idx], errorSchema[i]);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const { keyedFormData } = this.state;
|
|
289
|
+
function reOrderArray() {
|
|
290
|
+
const _newKeyedFormData = keyedFormData.slice();
|
|
291
|
+
_newKeyedFormData.splice(index, 1);
|
|
292
|
+
_newKeyedFormData.splice(newIndex, 0, keyedFormData[index]);
|
|
293
|
+
return _newKeyedFormData;
|
|
294
|
+
}
|
|
295
|
+
const newKeyedFormData = reOrderArray();
|
|
296
|
+
this.setState(
|
|
297
|
+
{
|
|
298
|
+
keyedFormData: newKeyedFormData
|
|
299
|
+
},
|
|
300
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
|
|
301
|
+
);
|
|
302
|
+
};
|
|
303
|
+
};
|
|
304
|
+
/** Callback handler used to deal with changing the value of the data in the array at the `index`. Calls the
|
|
305
|
+
* `onChange` callback with the updated form data
|
|
306
|
+
*
|
|
307
|
+
* @param index - The index of the item being changed
|
|
308
|
+
*/
|
|
309
|
+
onChangeForIndex = (index) => {
|
|
310
|
+
return (value, newErrorSchema, id) => {
|
|
311
|
+
const { formData, onChange, errorSchema } = this.props;
|
|
312
|
+
const arrayData = Array.isArray(formData) ? formData : [];
|
|
313
|
+
const newFormData = arrayData.map((item, i) => {
|
|
314
|
+
const jsonValue = typeof value === "undefined" ? null : value;
|
|
315
|
+
return index === i ? jsonValue : item;
|
|
316
|
+
});
|
|
317
|
+
onChange(
|
|
318
|
+
newFormData,
|
|
319
|
+
errorSchema && errorSchema && {
|
|
320
|
+
...errorSchema,
|
|
321
|
+
[index]: newErrorSchema
|
|
322
|
+
},
|
|
323
|
+
id
|
|
324
|
+
);
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
/** Callback handler used to change the value for a checkbox */
|
|
328
|
+
onSelectChange = (value) => {
|
|
329
|
+
const { onChange, idSchema } = this.props;
|
|
330
|
+
onChange(value, void 0, idSchema && idSchema.$id);
|
|
331
|
+
};
|
|
332
332
|
/** Renders the `ArrayField` depending on the specific needs of the schema and uischema elements
|
|
333
333
|
*/
|
|
334
334
|
render() {
|
|
@@ -423,7 +423,7 @@
|
|
|
423
423
|
totalItems: keyedFormData.length
|
|
424
424
|
});
|
|
425
425
|
}),
|
|
426
|
-
className: `field field-array field-array-of-${itemsSchema.type}`,
|
|
426
|
+
className: `rjsf-field rjsf-field-array rjsf-field-array-of-${itemsSchema.type}`,
|
|
427
427
|
disabled,
|
|
428
428
|
idSchema,
|
|
429
429
|
uiSchema,
|
|
@@ -631,7 +631,7 @@
|
|
|
631
631
|
const canAdd = this.canAddItem(items) && !!additionalSchema;
|
|
632
632
|
const arrayProps = {
|
|
633
633
|
canAdd,
|
|
634
|
-
className: "field field-array field-array-fixed-items",
|
|
634
|
+
className: "rjsf-field rjsf-field-array rjsf-field-array-fixed-items",
|
|
635
635
|
disabled,
|
|
636
636
|
idSchema,
|
|
637
637
|
formData,
|
|
@@ -712,14 +712,14 @@
|
|
|
712
712
|
} = registry;
|
|
713
713
|
const ItemSchemaField = ArraySchemaField || SchemaField2;
|
|
714
714
|
const { orderable = true, removable = true, copyable = false } = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
715
|
-
const
|
|
715
|
+
const has4 = {
|
|
716
716
|
moveUp: orderable && canMoveUp,
|
|
717
717
|
moveDown: orderable && canMoveDown,
|
|
718
718
|
copy: copyable && canAdd,
|
|
719
719
|
remove: removable && canRemove,
|
|
720
720
|
toolbar: false
|
|
721
721
|
};
|
|
722
|
-
|
|
722
|
+
has4.toolbar = Object.keys(has4).some((key2) => has4[key2]);
|
|
723
723
|
return {
|
|
724
724
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
725
725
|
ItemSchemaField,
|
|
@@ -747,21 +747,31 @@
|
|
|
747
747
|
rawErrors
|
|
748
748
|
}
|
|
749
749
|
),
|
|
750
|
-
|
|
750
|
+
buttonsProps: {
|
|
751
|
+
idSchema: itemIdSchema,
|
|
752
|
+
disabled,
|
|
753
|
+
readonly,
|
|
754
|
+
canAdd,
|
|
755
|
+
hasCopy: has4.copy,
|
|
756
|
+
hasMoveUp: has4.moveUp,
|
|
757
|
+
hasMoveDown: has4.moveDown,
|
|
758
|
+
hasRemove: has4.remove,
|
|
759
|
+
index,
|
|
760
|
+
totalItems,
|
|
761
|
+
onAddIndexClick: this.onAddIndexClick,
|
|
762
|
+
onCopyIndexClick: this.onCopyIndexClick,
|
|
763
|
+
onDropIndexClick: this.onDropIndexClick,
|
|
764
|
+
onReorderClick: this.onReorderClick,
|
|
765
|
+
registry,
|
|
766
|
+
schema: itemSchema,
|
|
767
|
+
uiSchema: itemUiSchema
|
|
768
|
+
},
|
|
769
|
+
className: "rjsf-array-item",
|
|
751
770
|
disabled,
|
|
752
|
-
|
|
753
|
-
hasCopy: has2.copy,
|
|
754
|
-
hasToolbar: has2.toolbar,
|
|
755
|
-
hasMoveUp: has2.moveUp,
|
|
756
|
-
hasMoveDown: has2.moveDown,
|
|
757
|
-
hasRemove: has2.remove,
|
|
771
|
+
hasToolbar: has4.toolbar,
|
|
758
772
|
index,
|
|
759
773
|
totalItems,
|
|
760
774
|
key,
|
|
761
|
-
onAddIndexClick: this.onAddIndexClick,
|
|
762
|
-
onCopyIndexClick: this.onCopyIndexClick,
|
|
763
|
-
onDropIndexClick: this.onDropIndexClick,
|
|
764
|
-
onReorderClick: this.onReorderClick,
|
|
765
775
|
readonly,
|
|
766
776
|
registry,
|
|
767
777
|
schema: itemSchema,
|
|
@@ -796,6 +806,7 @@
|
|
|
796
806
|
title: uiTitle,
|
|
797
807
|
// Unlike the other fields, don't use `getDisplayLabel()` since it always returns false for the boolean type
|
|
798
808
|
label: displayLabel = true,
|
|
809
|
+
enumNames,
|
|
799
810
|
...options
|
|
800
811
|
} = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
801
812
|
const Widget = utils.getWidget(schema, widget, widgets2);
|
|
@@ -820,9 +831,8 @@
|
|
|
820
831
|
uiSchema
|
|
821
832
|
);
|
|
822
833
|
} else {
|
|
823
|
-
const schemaWithEnumNames = schema;
|
|
824
834
|
const enums = schema.enum ?? [true, false];
|
|
825
|
-
if (!
|
|
835
|
+
if (!enumNames && enums.length === 2 && enums.every((v) => typeof v === "boolean")) {
|
|
826
836
|
enumOptions = [
|
|
827
837
|
{
|
|
828
838
|
value: enums[0],
|
|
@@ -834,42 +844,717 @@
|
|
|
834
844
|
}
|
|
835
845
|
];
|
|
836
846
|
} else {
|
|
837
|
-
enumOptions = utils.optionsList(
|
|
847
|
+
enumOptions = utils.optionsList({ enum: enums }, uiSchema);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
851
|
+
Widget,
|
|
852
|
+
{
|
|
853
|
+
options: { ...options, enumOptions },
|
|
854
|
+
schema,
|
|
855
|
+
uiSchema,
|
|
856
|
+
id: idSchema.$id,
|
|
857
|
+
name,
|
|
858
|
+
onChange,
|
|
859
|
+
onFocus,
|
|
860
|
+
onBlur,
|
|
861
|
+
label,
|
|
862
|
+
hideLabel: !displayLabel,
|
|
863
|
+
value: formData,
|
|
864
|
+
required,
|
|
865
|
+
disabled,
|
|
866
|
+
readonly,
|
|
867
|
+
hideError,
|
|
868
|
+
registry,
|
|
869
|
+
formContext,
|
|
870
|
+
autofocus,
|
|
871
|
+
rawErrors
|
|
872
|
+
}
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
var BooleanField_default = BooleanField;
|
|
876
|
+
var LOOKUP_REGEX = /^\$lookup=(.+)/;
|
|
877
|
+
var LAYOUT_GRID_UI_OPTION = "layoutGrid";
|
|
878
|
+
var UI_GLOBAL_OPTIONS = "ui:global_options";
|
|
879
|
+
function getNonNullishValue(value, fallback) {
|
|
880
|
+
return value ?? fallback;
|
|
881
|
+
}
|
|
882
|
+
var LayoutGridField = class _LayoutGridField extends react.PureComponent {
|
|
883
|
+
static defaultProps = {
|
|
884
|
+
layoutGridSchema: void 0
|
|
885
|
+
};
|
|
886
|
+
static TEST_IDS = utils.getTestIds();
|
|
887
|
+
/** Computes the uiSchema for the field with `name` from the `uiProps` and `uiSchema` provided. The field UI Schema
|
|
888
|
+
* will always contain a copy of the global options from the `uiSchema` (so they can be passed down) as well as
|
|
889
|
+
* copying them into the local ui options. When the `forceReadonly` flag is true, then the field UI Schema is
|
|
890
|
+
* updated to make "readonly" be true. When the `schemaReadonly` flag is true AND the field UI Schema does NOT have
|
|
891
|
+
* the flag already provided, then we also make "readonly" true. We always make sure to return the final value of the
|
|
892
|
+
* field UI Schema's "readonly" flag as `uiReadonly` along with the `fieldUiSchema` in the return value.
|
|
893
|
+
*
|
|
894
|
+
* @param field - The name of the field to pull the existing UI Schema for
|
|
895
|
+
* @param uiProps - Any props that should be put into the field's uiSchema
|
|
896
|
+
* @param [uiSchema] - The optional UI Schema from which to get the UI schema for the field
|
|
897
|
+
* @param [schemaReadonly] - Optional flag indicating whether the schema indicates the field is readonly
|
|
898
|
+
* @param [forceReadonly] - Optional flag indicating whether the Form itself is in readonly mode
|
|
899
|
+
*/
|
|
900
|
+
static computeFieldUiSchema(field, uiProps, uiSchema, schemaReadonly, forceReadonly) {
|
|
901
|
+
const globalUiOptions = get2(uiSchema, [UI_GLOBAL_OPTIONS], {});
|
|
902
|
+
const localUiSchema = get2(uiSchema, field);
|
|
903
|
+
const localUiOptions = { ...get2(localUiSchema, [utils.UI_OPTIONS_KEY], {}), ...uiProps, ...globalUiOptions };
|
|
904
|
+
const fieldUiSchema = { ...localUiSchema };
|
|
905
|
+
if (!isEmpty(localUiOptions)) {
|
|
906
|
+
set(fieldUiSchema, [utils.UI_OPTIONS_KEY], localUiOptions);
|
|
907
|
+
}
|
|
908
|
+
if (!isEmpty(globalUiOptions)) {
|
|
909
|
+
set(fieldUiSchema, [UI_GLOBAL_OPTIONS], globalUiOptions);
|
|
910
|
+
}
|
|
911
|
+
let { readonly: uiReadonly } = utils.getUiOptions(fieldUiSchema);
|
|
912
|
+
if (forceReadonly === true || isUndefined(uiReadonly) && schemaReadonly === true) {
|
|
913
|
+
uiReadonly = true;
|
|
914
|
+
if (has(localUiOptions, utils.READONLY_KEY)) {
|
|
915
|
+
set(fieldUiSchema, [utils.UI_OPTIONS_KEY, utils.READONLY_KEY], true);
|
|
916
|
+
} else {
|
|
917
|
+
set(fieldUiSchema, `ui:${utils.READONLY_KEY}`, true);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
return { fieldUiSchema, uiReadonly };
|
|
921
|
+
}
|
|
922
|
+
/** Given an `operator`, `datum` and `value` determines whether this condition is considered matching. Matching
|
|
923
|
+
* depends on the `operator`. The `datum` and `value` are converted into arrays if they aren't already and then the
|
|
924
|
+
* contents of the two arrays are compared using the `operator`. When `operator` is All, then the two arrays must be
|
|
925
|
+
* equal to match. When `operator` is SOME then the intersection of the two arrays must have at least one value in
|
|
926
|
+
* common to match. When `operator` is NONE then the intersection of the two arrays must not have any values in common
|
|
927
|
+
* to match.
|
|
928
|
+
*
|
|
929
|
+
* @param [operator] - The optional operator for the condition
|
|
930
|
+
* @param [datum] - The optional datum for the condition, this can be an item or a list of items of type unknown
|
|
931
|
+
* @param [value='$0m3tH1nG Un3xP3cT3d'] The optional value for the condition, defaulting to a highly unlikely value
|
|
932
|
+
* to avoid comparing two undefined elements when `value` was forgotten in the condition definition.
|
|
933
|
+
* This can be an item or a list of items of type unknown
|
|
934
|
+
* @returns - True if the condition matches, false otherwise
|
|
935
|
+
*/
|
|
936
|
+
static conditionMatches(operator, datum, value = "$0m3tH1nG Un3xP3cT3d") {
|
|
937
|
+
const data = flatten([datum]).sort();
|
|
938
|
+
const values = flatten([value]).sort();
|
|
939
|
+
switch (operator) {
|
|
940
|
+
case "all" /* ALL */:
|
|
941
|
+
return isEqual(data, values);
|
|
942
|
+
case "some" /* SOME */:
|
|
943
|
+
return intersection(data, values).length > 0;
|
|
944
|
+
case "none" /* NONE */:
|
|
945
|
+
return intersection(data, values).length === 0;
|
|
946
|
+
default:
|
|
947
|
+
return false;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
/** From within the `layoutGridSchema` finds the `children` and any extra `gridProps` from the object keyed by
|
|
951
|
+
* `schemaKey`. If the `children` contains extra `gridProps` and those props contain a `className` string, try to
|
|
952
|
+
* lookup whether that `className` has a replacement value in the `registry` using the `FORM_CONTEXT_LOOKUP_BASE`.
|
|
953
|
+
* When the `className` value contains multiple classNames separated by a space, the lookup will look for a
|
|
954
|
+
* replacement value for each `className` and combine them into one.
|
|
955
|
+
*
|
|
956
|
+
* @param layoutGridSchema - The GridSchemaType instance from which to obtain the `schemaKey` children and extra props
|
|
957
|
+
* @param schemaKey - A `GridType` value, used to get the children and extra props from within the `layoutGridSchema`
|
|
958
|
+
* @param registry - The `@rjsf` Registry from which to look up `classNames` if they are present in the extra props
|
|
959
|
+
* @returns - An object containing the list of `LayoutGridSchemaType` `children` and any extra `gridProps`
|
|
960
|
+
* @throws - A `TypeError` when the `children` is not an array
|
|
961
|
+
*/
|
|
962
|
+
static findChildrenAndProps(layoutGridSchema, schemaKey, registry) {
|
|
963
|
+
let gridProps = {};
|
|
964
|
+
let children = layoutGridSchema[schemaKey];
|
|
965
|
+
if (isPlainObject(children)) {
|
|
966
|
+
const { children: elements, className: toMapClassNames, ...otherProps } = children;
|
|
967
|
+
children = elements;
|
|
968
|
+
if (toMapClassNames) {
|
|
969
|
+
const classes = toMapClassNames.split(" ");
|
|
970
|
+
const className = classes.map((ele) => utils.lookupFromFormContext(registry, ele, ele)).join(" ");
|
|
971
|
+
gridProps = { ...otherProps, className };
|
|
972
|
+
} else {
|
|
973
|
+
gridProps = otherProps;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
if (!Array.isArray(children)) {
|
|
977
|
+
throw new TypeError(`Expected array for "${schemaKey}" in ${JSON.stringify(layoutGridSchema)}`);
|
|
978
|
+
}
|
|
979
|
+
return { children, gridProps };
|
|
980
|
+
}
|
|
981
|
+
/** Generates an idSchema for the `schema` using `@rjsf`'s `toIdSchema` util, passing the `baseIdSchema`'s `$id` value
|
|
982
|
+
* as the id prefix.
|
|
983
|
+
*
|
|
984
|
+
* @param schemaUtils - The `SchemaUtilsType` used to call `toIdSchema`
|
|
985
|
+
* @param schema - The schema to generate the idSchema for
|
|
986
|
+
* @param baseIdSchema - The IdSchema for the base
|
|
987
|
+
* @param formData - The formData to pass the `toIdSchema`
|
|
988
|
+
* @param [idSeparator] - The param to pass into the `toIdSchema` util which will use it to join the `idSchema` paths
|
|
989
|
+
* @returns - The generated `idSchema` for the `schema`
|
|
990
|
+
*/
|
|
991
|
+
static getIdSchema(schemaUtils, baseIdSchema, formData, schema = {}, idSeparator) {
|
|
992
|
+
const baseId = get2(baseIdSchema, utils.ID_KEY);
|
|
993
|
+
return schemaUtils.toIdSchema(schema, baseId, formData, baseId, idSeparator);
|
|
994
|
+
}
|
|
995
|
+
/** Given a `dottedPath` to a field in the `initialSchema`, iterate through each individual path in the schema until
|
|
996
|
+
* the leaf path is found and returned (along with whether that leaf path `isRequired`) OR no schema exists for an
|
|
997
|
+
* element in the path. If the leaf schema element happens to be a oneOf/anyOf then also return the oneOf/anyOf as
|
|
998
|
+
* `options`.
|
|
999
|
+
*
|
|
1000
|
+
* @param schemaUtils - The `SchemaUtilsType` used to call `retrieveSchema`
|
|
1001
|
+
* @param dottedPath - The dotted-path to the field for which to get the schema
|
|
1002
|
+
* @param initialSchema - The initial schema to start the search from
|
|
1003
|
+
* @param formData - The formData, useful for resolving a oneOf/anyOf selection in the path hierarchy
|
|
1004
|
+
* @param initialIdSchema - The initial idSchema to start the search from
|
|
1005
|
+
* @param [idSeparator] - The param to pass into the `toIdSchema` util which will use it to join the `idSchema` paths
|
|
1006
|
+
* @returns - An object containing the destination schema, isRequired and isReadonly flags for the field and options
|
|
1007
|
+
* info if a oneOf/anyOf
|
|
1008
|
+
*/
|
|
1009
|
+
static getSchemaDetailsForField(schemaUtils, dottedPath, initialSchema, formData, initialIdSchema, idSeparator) {
|
|
1010
|
+
let rawSchema = initialSchema;
|
|
1011
|
+
let idSchema = initialIdSchema;
|
|
1012
|
+
const parts = dottedPath.split(".");
|
|
1013
|
+
const leafPath = parts.pop();
|
|
1014
|
+
let schema = schemaUtils.retrieveSchema(rawSchema, formData);
|
|
1015
|
+
let innerData = formData;
|
|
1016
|
+
let isReadonly = schema.readOnly;
|
|
1017
|
+
parts.forEach((part) => {
|
|
1018
|
+
if (has(schema, utils.PROPERTIES_KEY)) {
|
|
1019
|
+
rawSchema = get2(schema, [utils.PROPERTIES_KEY, part], {});
|
|
1020
|
+
idSchema = get2(idSchema, part, {});
|
|
1021
|
+
} else if (schema && (has(schema, utils.ONE_OF_KEY) || has(schema, utils.ANY_OF_KEY))) {
|
|
1022
|
+
const xxx = has(schema, utils.ONE_OF_KEY) ? utils.ONE_OF_KEY : utils.ANY_OF_KEY;
|
|
1023
|
+
const selectedSchema = schemaUtils.findSelectedOptionInXxxOf(schema, part, xxx, innerData);
|
|
1024
|
+
const selectedIdSchema = _LayoutGridField.getIdSchema(
|
|
1025
|
+
schemaUtils,
|
|
1026
|
+
idSchema,
|
|
1027
|
+
formData,
|
|
1028
|
+
selectedSchema,
|
|
1029
|
+
idSeparator
|
|
1030
|
+
);
|
|
1031
|
+
rawSchema = get2(selectedSchema, [utils.PROPERTIES_KEY, part], {});
|
|
1032
|
+
idSchema = get2(selectedIdSchema, part, {});
|
|
1033
|
+
} else {
|
|
1034
|
+
rawSchema = {};
|
|
1035
|
+
}
|
|
1036
|
+
innerData = get2(innerData, part, {});
|
|
1037
|
+
schema = schemaUtils.retrieveSchema(rawSchema, innerData);
|
|
1038
|
+
isReadonly = getNonNullishValue(schema.readOnly, isReadonly);
|
|
1039
|
+
});
|
|
1040
|
+
let optionsInfo;
|
|
1041
|
+
let isRequired = false;
|
|
1042
|
+
if (isEmpty(schema)) {
|
|
1043
|
+
schema = void 0;
|
|
1044
|
+
}
|
|
1045
|
+
if (schema && leafPath) {
|
|
1046
|
+
if (schema && (has(schema, utils.ONE_OF_KEY) || has(schema, utils.ANY_OF_KEY))) {
|
|
1047
|
+
const xxx = has(schema, utils.ONE_OF_KEY) ? utils.ONE_OF_KEY : utils.ANY_OF_KEY;
|
|
1048
|
+
schema = schemaUtils.findSelectedOptionInXxxOf(schema, leafPath, xxx, innerData);
|
|
1049
|
+
const rawIdSchema = _LayoutGridField.getIdSchema(schemaUtils, idSchema, formData, schema, idSeparator);
|
|
1050
|
+
idSchema = utils.mergeObjects(rawIdSchema, idSchema);
|
|
1051
|
+
}
|
|
1052
|
+
isRequired = schema !== void 0 && Array.isArray(schema.required) && includes(schema.required, leafPath);
|
|
1053
|
+
schema = get2(schema, [utils.PROPERTIES_KEY, leafPath]);
|
|
1054
|
+
schema = schema ? schemaUtils.retrieveSchema(schema) : schema;
|
|
1055
|
+
idSchema = get2(idSchema, leafPath, {});
|
|
1056
|
+
isReadonly = getNonNullishValue(schema?.readOnly, isReadonly);
|
|
1057
|
+
if (schema && (has(schema, utils.ONE_OF_KEY) || has(schema, utils.ANY_OF_KEY))) {
|
|
1058
|
+
const xxx = has(schema, utils.ONE_OF_KEY) ? utils.ONE_OF_KEY : utils.ANY_OF_KEY;
|
|
1059
|
+
const discriminator = utils.getDiscriminatorFieldFromSchema(schema);
|
|
1060
|
+
optionsInfo = { options: schema[xxx], hasDiscriminator: !!discriminator };
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
return { schema, isRequired, isReadonly, optionsInfo, idSchema };
|
|
1064
|
+
}
|
|
1065
|
+
/** Gets the custom render component from the `render`, by either determining that it is either already a function or
|
|
1066
|
+
* it is a non-function value that can be used to look up the function in the registry. If no function can be found,
|
|
1067
|
+
* null is returned.
|
|
1068
|
+
*
|
|
1069
|
+
* @param render - The potential render function or lookup name to one
|
|
1070
|
+
* @param registry - The `@rjsf` Registry from which to look up `classNames` if they are present in the extra props
|
|
1071
|
+
* @returns - Either a render function if available, or null if not
|
|
1072
|
+
*/
|
|
1073
|
+
static getCustomRenderComponent(render, registry) {
|
|
1074
|
+
let customRenderer = render;
|
|
1075
|
+
if (isString(customRenderer)) {
|
|
1076
|
+
customRenderer = utils.lookupFromFormContext(registry, customRenderer);
|
|
1077
|
+
}
|
|
1078
|
+
if (isFunction(customRenderer)) {
|
|
1079
|
+
return customRenderer;
|
|
1080
|
+
}
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
/** Extract the `name`, and optional `render` and all other props from the `gridSchema`. We look up the `render` to
|
|
1084
|
+
* see if can be resolved to a UIComponent. If `name` does not exist and there is an optional `render` UIComponent, we
|
|
1085
|
+
* set the `rendered` component with only specified props for that component in the object.
|
|
1086
|
+
*
|
|
1087
|
+
* @param registry - The `@rjsf` Registry from which to look up `classNames` if they are present in the extra props
|
|
1088
|
+
* @param gridSchema - The string or object that represents the configuration for the grid field
|
|
1089
|
+
* @returns - The UIComponentPropsType computed from the gridSchema
|
|
1090
|
+
*/
|
|
1091
|
+
static computeUIComponentPropsFromGridSchema(registry, gridSchema) {
|
|
1092
|
+
let name;
|
|
1093
|
+
let UIComponent = null;
|
|
1094
|
+
let uiProps = {};
|
|
1095
|
+
let rendered;
|
|
1096
|
+
if (isString(gridSchema) || isUndefined(gridSchema)) {
|
|
1097
|
+
name = gridSchema ?? "";
|
|
1098
|
+
} else {
|
|
1099
|
+
const { name: innerName, render, ...innerProps } = gridSchema;
|
|
1100
|
+
name = innerName;
|
|
1101
|
+
uiProps = innerProps;
|
|
1102
|
+
if (!isEmpty(uiProps)) {
|
|
1103
|
+
each(uiProps, (prop, key) => {
|
|
1104
|
+
if (isString(prop)) {
|
|
1105
|
+
const match = LOOKUP_REGEX.exec(prop);
|
|
1106
|
+
if (Array.isArray(match) && match.length > 1) {
|
|
1107
|
+
const name2 = match[1];
|
|
1108
|
+
uiProps[key] = utils.lookupFromFormContext(registry, name2, name2);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
UIComponent = _LayoutGridField.getCustomRenderComponent(render, registry);
|
|
1114
|
+
if (!innerName && UIComponent) {
|
|
1115
|
+
rendered = /* @__PURE__ */ jsxRuntime.jsx(UIComponent, { ...innerProps, "data-testid": _LayoutGridField.TEST_IDS.uiComponent });
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
return { name, UIComponent, uiProps, rendered };
|
|
1119
|
+
}
|
|
1120
|
+
/** Constructs an `LayoutGridField` with the given `props`
|
|
1121
|
+
*
|
|
1122
|
+
* @param props - The `LayoutGridField` for this template
|
|
1123
|
+
*/
|
|
1124
|
+
constructor(props) {
|
|
1125
|
+
super(props);
|
|
1126
|
+
}
|
|
1127
|
+
/** Generates an `onChange` handler for the field associated with the `dottedPath`. This handler will clone and update
|
|
1128
|
+
* the `formData` with the new `value` and the `errorSchema` if an `errSchema` is provided. After updating those two
|
|
1129
|
+
* elements, they will then be passed on to the `onChange` handler of the `LayoutFieldGrid`.
|
|
1130
|
+
*
|
|
1131
|
+
* @param dottedPath - The dotted-path to the field for which to generate the onChange handler
|
|
1132
|
+
* @returns - The `onChange` handling function for the `dottedPath` field
|
|
1133
|
+
*/
|
|
1134
|
+
onFieldChange = (dottedPath) => {
|
|
1135
|
+
return (value, errSchema, id) => {
|
|
1136
|
+
const { onChange, errorSchema, formData } = this.props;
|
|
1137
|
+
const newFormData = cloneDeep2(formData || {});
|
|
1138
|
+
let newErrorSchema = errorSchema;
|
|
1139
|
+
if (errSchema && errorSchema) {
|
|
1140
|
+
newErrorSchema = cloneDeep2(errorSchema);
|
|
1141
|
+
set(newErrorSchema, dottedPath, errSchema);
|
|
1142
|
+
}
|
|
1143
|
+
set(newFormData, dottedPath, value);
|
|
1144
|
+
onChange(newFormData, newErrorSchema, id);
|
|
1145
|
+
};
|
|
1146
|
+
};
|
|
1147
|
+
/** Renders the `children` of the `GridType.CONDITION` if it passes. The `layoutGridSchema` for the
|
|
1148
|
+
* `GridType.CONDITION` is separated into the `children` and other `gridProps`. The `gridProps` are used to extract
|
|
1149
|
+
* the `operator`, `field` and `value` of the condition. If the condition matches, then all of the `children` are
|
|
1150
|
+
* rendered, otherwise null is returned.
|
|
1151
|
+
*
|
|
1152
|
+
* @param layoutGridSchema - The string or object that represents the configuration for the grid field
|
|
1153
|
+
* @returns - The rendered the children for the `GridType.CONDITION` or null
|
|
1154
|
+
*/
|
|
1155
|
+
renderCondition(layoutGridSchema) {
|
|
1156
|
+
const { formData, registry } = this.props;
|
|
1157
|
+
const { children, gridProps } = _LayoutGridField.findChildrenAndProps(
|
|
1158
|
+
layoutGridSchema,
|
|
1159
|
+
"ui:condition" /* CONDITION */,
|
|
1160
|
+
registry
|
|
1161
|
+
);
|
|
1162
|
+
const { operator, field = "", value } = gridProps;
|
|
1163
|
+
const fieldData = get2(formData, field, null);
|
|
1164
|
+
if (_LayoutGridField.conditionMatches(operator, fieldData, value)) {
|
|
1165
|
+
return this.renderChildren(children);
|
|
1166
|
+
}
|
|
1167
|
+
return null;
|
|
1168
|
+
}
|
|
1169
|
+
/** Renders a material-ui `GridTemplate` as an item. The `layoutGridSchema` for the `GridType.COLUMN` is separated
|
|
1170
|
+
* into the `children` and other `gridProps`. The `gridProps` will be spread onto the outer `GridTemplate`. Inside
|
|
1171
|
+
* the `GridTemplate` all the `children` are rendered.
|
|
1172
|
+
*
|
|
1173
|
+
* @param layoutGridSchema - The string or object that represents the configuration for the grid field
|
|
1174
|
+
* @returns - The rendered `GridTemplate` containing the children for the `GridType.COLUMN`
|
|
1175
|
+
*/
|
|
1176
|
+
renderCol(layoutGridSchema) {
|
|
1177
|
+
const { registry, uiSchema } = this.props;
|
|
1178
|
+
const { children, gridProps } = _LayoutGridField.findChildrenAndProps(
|
|
1179
|
+
layoutGridSchema,
|
|
1180
|
+
"ui:col" /* COLUMN */,
|
|
1181
|
+
registry
|
|
1182
|
+
);
|
|
1183
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
1184
|
+
const GridTemplate2 = utils.getTemplate("GridTemplate", registry, uiOptions);
|
|
1185
|
+
return /* @__PURE__ */ jsxRuntime.jsx(GridTemplate2, { column: true, "data-testid": _LayoutGridField.TEST_IDS.col, ...gridProps, children: this.renderChildren(children) });
|
|
1186
|
+
}
|
|
1187
|
+
/** Renders a material-ui `GridTemplate` as an item. The `layoutGridSchema` for the `GridType.COLUMNS` is separated
|
|
1188
|
+
* into the `children` and other `gridProps`. The `children` is iterated on and `gridProps` will be spread onto the
|
|
1189
|
+
* outer `GridTemplate`. Each child will have their own rendered `GridTemplate`.
|
|
1190
|
+
*
|
|
1191
|
+
* @param layoutGridSchema - The string or object that represents the configuration for the grid field
|
|
1192
|
+
* @returns - The rendered `GridTemplate` containing the children for the `GridType.COLUMNS`
|
|
1193
|
+
*/
|
|
1194
|
+
renderColumns(layoutGridSchema) {
|
|
1195
|
+
const { registry, uiSchema } = this.props;
|
|
1196
|
+
const { children, gridProps } = _LayoutGridField.findChildrenAndProps(
|
|
1197
|
+
layoutGridSchema,
|
|
1198
|
+
"ui:columns" /* COLUMNS */,
|
|
1199
|
+
registry
|
|
1200
|
+
);
|
|
1201
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
1202
|
+
const GridTemplate2 = utils.getTemplate("GridTemplate", registry, uiOptions);
|
|
1203
|
+
return children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1204
|
+
GridTemplate2,
|
|
1205
|
+
{
|
|
1206
|
+
column: true,
|
|
1207
|
+
"data-testid": _LayoutGridField.TEST_IDS.col,
|
|
1208
|
+
...gridProps,
|
|
1209
|
+
children: this.renderChildren([child])
|
|
1210
|
+
},
|
|
1211
|
+
`column-${utils.hashObject(child)}`
|
|
1212
|
+
));
|
|
1213
|
+
}
|
|
1214
|
+
/** Renders a material-ui `GridTemplate` as a container. The
|
|
1215
|
+
* `layoutGridSchema` for the `GridType.ROW` is separated into the `children` and other `gridProps`. The `gridProps`
|
|
1216
|
+
* will be spread onto the outer `GridTemplate`. Inside of the `GridTemplate` all of the `children` are rendered.
|
|
1217
|
+
*
|
|
1218
|
+
* @param layoutGridSchema - The string or object that represents the configuration for the grid field
|
|
1219
|
+
* @returns - The rendered `GridTemplate` containing the children for the `GridType.ROW`
|
|
1220
|
+
*/
|
|
1221
|
+
renderRow(layoutGridSchema) {
|
|
1222
|
+
const { registry, uiSchema } = this.props;
|
|
1223
|
+
const { children, gridProps } = _LayoutGridField.findChildrenAndProps(
|
|
1224
|
+
layoutGridSchema,
|
|
1225
|
+
"ui:row" /* ROW */,
|
|
1226
|
+
registry
|
|
1227
|
+
);
|
|
1228
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
1229
|
+
const GridTemplate2 = utils.getTemplate("GridTemplate", registry, uiOptions);
|
|
1230
|
+
return /* @__PURE__ */ jsxRuntime.jsx(GridTemplate2, { ...gridProps, "data-testid": _LayoutGridField.TEST_IDS.row, children: this.renderChildren(children) });
|
|
1231
|
+
}
|
|
1232
|
+
/** Iterates through all the `childrenLayoutGridSchema`, rendering a nested `LayoutGridField` for each item in the
|
|
1233
|
+
* list, passing all the props for the current `LayoutGridField` along, updating the `schema` by calling
|
|
1234
|
+
* `retrieveSchema()` on it to resolve any `$ref`s. In addition to the updated `schema`, each item in
|
|
1235
|
+
* `childrenLayoutGridSchema` is passed as `layoutGridSchema`.
|
|
1236
|
+
*
|
|
1237
|
+
* @param childrenLayoutGridSchema - The list of strings or objects that represents the configurations for the
|
|
1238
|
+
* children fields
|
|
1239
|
+
* @returns - The nested `LayoutGridField`s
|
|
1240
|
+
*/
|
|
1241
|
+
renderChildren(childrenLayoutGridSchema) {
|
|
1242
|
+
const { registry, schema: rawSchema, formData } = this.props;
|
|
1243
|
+
const { schemaUtils } = registry;
|
|
1244
|
+
const schema = schemaUtils.retrieveSchema(rawSchema, formData);
|
|
1245
|
+
return childrenLayoutGridSchema.map((layoutGridSchema) => /* @__PURE__ */ react.createElement(
|
|
1246
|
+
_LayoutGridField,
|
|
1247
|
+
{
|
|
1248
|
+
...this.props,
|
|
1249
|
+
key: `layoutGrid-${utils.hashObject(layoutGridSchema)}`,
|
|
1250
|
+
schema,
|
|
1251
|
+
layoutGridSchema
|
|
1252
|
+
}
|
|
1253
|
+
));
|
|
1254
|
+
}
|
|
1255
|
+
/** Renders the field described by `gridSchema`. If `gridSchema` is not an object, then is will be assumed
|
|
1256
|
+
* to be the dotted-path to the field in the schema. Otherwise, we extract the `name`, and optional `render` and all
|
|
1257
|
+
* other props. If `name` does not exist and there is an optional `render`, we return the `render` component with only
|
|
1258
|
+
* specified props for that component. If `name` exists, we take the name, the initial & root schemas and the formData
|
|
1259
|
+
* and get the destination schema, is required state and optional oneOf/anyOf options for it. If the destination
|
|
1260
|
+
* schema was located along with oneOf/anyOf options then a `LayoutMultiSchemaField` will be rendered with the
|
|
1261
|
+
* `uiSchema`, `errorSchema`, `idSchema` and `formData` drilled down to the dotted-path field, spreading any other
|
|
1262
|
+
* props from `gridSchema` into the `ui:options`. If the destination schema located without any oneOf/anyOf options,
|
|
1263
|
+
* then a `SchemaField` will be rendered with the same props as mentioned in the previous sentence. If no destination
|
|
1264
|
+
* schema was located, but a custom render component was found, then it will be rendered with many of the non-event
|
|
1265
|
+
* handling props. If none of the previous render paths are valid, then a null is returned.
|
|
1266
|
+
*
|
|
1267
|
+
* @param gridSchema - The string or object that represents the configuration for the grid field
|
|
1268
|
+
* @returns - One of `LayoutMultiSchemaField`, `SchemaField`, a custom render component or null, depending
|
|
1269
|
+
*/
|
|
1270
|
+
renderField(gridSchema) {
|
|
1271
|
+
const {
|
|
1272
|
+
schema: initialSchema,
|
|
1273
|
+
uiSchema,
|
|
1274
|
+
errorSchema,
|
|
1275
|
+
idSchema,
|
|
1276
|
+
onBlur,
|
|
1277
|
+
onFocus,
|
|
1278
|
+
formData,
|
|
1279
|
+
readonly,
|
|
1280
|
+
registry,
|
|
1281
|
+
idSeparator,
|
|
1282
|
+
layoutGridSchema,
|
|
1283
|
+
// Used to pull this out of otherProps since we don't want to pass it through
|
|
1284
|
+
...otherProps
|
|
1285
|
+
} = this.props;
|
|
1286
|
+
const { fields: fields2, schemaUtils } = registry;
|
|
1287
|
+
const { SchemaField: SchemaField2, LayoutMultiSchemaField: LayoutMultiSchemaField2 } = fields2;
|
|
1288
|
+
const uiComponentProps = _LayoutGridField.computeUIComponentPropsFromGridSchema(registry, gridSchema);
|
|
1289
|
+
if (uiComponentProps.rendered) {
|
|
1290
|
+
return uiComponentProps.rendered;
|
|
1291
|
+
}
|
|
1292
|
+
const { name, UIComponent, uiProps } = uiComponentProps;
|
|
1293
|
+
const {
|
|
1294
|
+
schema,
|
|
1295
|
+
isRequired,
|
|
1296
|
+
isReadonly,
|
|
1297
|
+
optionsInfo,
|
|
1298
|
+
idSchema: fieldIdSchema
|
|
1299
|
+
} = _LayoutGridField.getSchemaDetailsForField(
|
|
1300
|
+
schemaUtils,
|
|
1301
|
+
name,
|
|
1302
|
+
initialSchema,
|
|
1303
|
+
formData,
|
|
1304
|
+
idSchema,
|
|
1305
|
+
idSeparator
|
|
1306
|
+
);
|
|
1307
|
+
if (schema) {
|
|
1308
|
+
const Field = optionsInfo?.hasDiscriminator ? LayoutMultiSchemaField2 : SchemaField2;
|
|
1309
|
+
const { fieldUiSchema, uiReadonly } = _LayoutGridField.computeFieldUiSchema(
|
|
1310
|
+
name,
|
|
1311
|
+
uiProps,
|
|
1312
|
+
uiSchema,
|
|
1313
|
+
isReadonly,
|
|
1314
|
+
readonly
|
|
1315
|
+
);
|
|
1316
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1317
|
+
Field,
|
|
838
1318
|
{
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1319
|
+
"data-testid": optionsInfo?.hasDiscriminator ? _LayoutGridField.TEST_IDS.layoutMultiSchemaField : _LayoutGridField.TEST_IDS.field,
|
|
1320
|
+
...otherProps,
|
|
1321
|
+
name,
|
|
1322
|
+
required: isRequired,
|
|
1323
|
+
readonly: uiReadonly,
|
|
1324
|
+
schema,
|
|
1325
|
+
uiSchema: fieldUiSchema,
|
|
1326
|
+
errorSchema: get2(errorSchema, name),
|
|
1327
|
+
idSchema: fieldIdSchema,
|
|
1328
|
+
idSeparator,
|
|
1329
|
+
formData: get2(formData, name),
|
|
1330
|
+
onChange: this.onFieldChange(name),
|
|
1331
|
+
onBlur,
|
|
1332
|
+
onFocus,
|
|
1333
|
+
options: optionsInfo?.options,
|
|
1334
|
+
registry
|
|
1335
|
+
}
|
|
1336
|
+
);
|
|
1337
|
+
}
|
|
1338
|
+
if (UIComponent) {
|
|
1339
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1340
|
+
UIComponent,
|
|
1341
|
+
{
|
|
1342
|
+
"data-testid": _LayoutGridField.TEST_IDS.uiComponent,
|
|
1343
|
+
...otherProps,
|
|
1344
|
+
name,
|
|
1345
|
+
required: isRequired,
|
|
1346
|
+
formData,
|
|
1347
|
+
readOnly: !!isReadonly || readonly,
|
|
1348
|
+
errorSchema,
|
|
1349
|
+
uiSchema,
|
|
1350
|
+
schema: initialSchema,
|
|
1351
|
+
idSchema,
|
|
1352
|
+
idSeparator,
|
|
1353
|
+
onBlur,
|
|
1354
|
+
onFocus,
|
|
1355
|
+
registry,
|
|
1356
|
+
...uiProps
|
|
1357
|
+
}
|
|
844
1358
|
);
|
|
845
1359
|
}
|
|
1360
|
+
return null;
|
|
1361
|
+
}
|
|
1362
|
+
/** Renders the `LayoutGridField`. If there isn't a `layoutGridSchema` prop defined, then try pulling it out of the
|
|
1363
|
+
* `uiSchema` via `ui:LayoutGridField`. If `layoutGridSchema` is an object, then check to see if any of the properties
|
|
1364
|
+
* match one of the `GridType`s. If so, call the appropriate render function for the type. Otherwise, just call the
|
|
1365
|
+
* generic `renderField()` function with the `layoutGridSchema`.
|
|
1366
|
+
*
|
|
1367
|
+
* @returns - the rendered `LayoutGridField`
|
|
1368
|
+
*/
|
|
1369
|
+
render() {
|
|
1370
|
+
const { uiSchema } = this.props;
|
|
1371
|
+
let { layoutGridSchema } = this.props;
|
|
1372
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
1373
|
+
if (!layoutGridSchema && LAYOUT_GRID_UI_OPTION in uiOptions && isObject(uiOptions[LAYOUT_GRID_UI_OPTION])) {
|
|
1374
|
+
layoutGridSchema = uiOptions[LAYOUT_GRID_UI_OPTION];
|
|
1375
|
+
}
|
|
1376
|
+
if (isObject(layoutGridSchema)) {
|
|
1377
|
+
if ("ui:row" /* ROW */ in layoutGridSchema) {
|
|
1378
|
+
return this.renderRow(layoutGridSchema);
|
|
1379
|
+
}
|
|
1380
|
+
if ("ui:col" /* COLUMN */ in layoutGridSchema) {
|
|
1381
|
+
return this.renderCol(layoutGridSchema);
|
|
1382
|
+
}
|
|
1383
|
+
if ("ui:columns" /* COLUMNS */ in layoutGridSchema) {
|
|
1384
|
+
return this.renderColumns(layoutGridSchema);
|
|
1385
|
+
}
|
|
1386
|
+
if ("ui:condition" /* CONDITION */ in layoutGridSchema) {
|
|
1387
|
+
return this.renderCondition(layoutGridSchema);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
return this.renderField(layoutGridSchema);
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1393
|
+
function LayoutHeaderField(props) {
|
|
1394
|
+
const { idSchema, title, schema, uiSchema, required, registry, name } = props;
|
|
1395
|
+
const options = utils.getUiOptions(uiSchema, registry.globalUiOptions);
|
|
1396
|
+
const { title: uiTitle } = options;
|
|
1397
|
+
const { title: schemaTitle } = schema;
|
|
1398
|
+
const fieldTitle = uiTitle || title || schemaTitle || name;
|
|
1399
|
+
if (!fieldTitle) {
|
|
1400
|
+
return null;
|
|
1401
|
+
}
|
|
1402
|
+
const TitleFieldTemplate = utils.getTemplate(
|
|
1403
|
+
"TitleFieldTemplate",
|
|
1404
|
+
registry,
|
|
1405
|
+
options
|
|
1406
|
+
);
|
|
1407
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1408
|
+
TitleFieldTemplate,
|
|
1409
|
+
{
|
|
1410
|
+
id: utils.titleId(idSchema),
|
|
1411
|
+
title: fieldTitle,
|
|
1412
|
+
required,
|
|
1413
|
+
schema,
|
|
1414
|
+
uiSchema,
|
|
1415
|
+
registry
|
|
1416
|
+
}
|
|
1417
|
+
);
|
|
1418
|
+
}
|
|
1419
|
+
function getSelectedOption(options, selectorField, value) {
|
|
1420
|
+
const defaultValue = "!@#!@$@#$!@$#";
|
|
1421
|
+
const schemaOptions = options.map(({ schema }) => schema);
|
|
1422
|
+
return schemaOptions.find((option) => {
|
|
1423
|
+
const selector = get2(option, [utils.PROPERTIES_KEY, selectorField]);
|
|
1424
|
+
const result = get2(selector, utils.DEFAULT_KEY, get2(selector, utils.CONST_KEY, defaultValue));
|
|
1425
|
+
return result === value;
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
function computeEnumOptions(schema, options, schemaUtils, uiSchema, formData) {
|
|
1429
|
+
const realOptions = options.map((opt) => schemaUtils.retrieveSchema(opt, formData));
|
|
1430
|
+
let tempSchema = schema;
|
|
1431
|
+
if (has(schema, utils.ONE_OF_KEY)) {
|
|
1432
|
+
tempSchema = { ...schema, [utils.ONE_OF_KEY]: realOptions };
|
|
1433
|
+
} else if (has(schema, utils.ANY_OF_KEY)) {
|
|
1434
|
+
tempSchema = { ...schema, [utils.ANY_OF_KEY]: realOptions };
|
|
1435
|
+
}
|
|
1436
|
+
const enumOptions = utils.optionsList(tempSchema, uiSchema);
|
|
1437
|
+
if (!enumOptions) {
|
|
1438
|
+
throw new Error(`No enumOptions were computed from the schema ${JSON.stringify(tempSchema)}`);
|
|
1439
|
+
}
|
|
1440
|
+
return enumOptions;
|
|
1441
|
+
}
|
|
1442
|
+
function LayoutMultiSchemaField(props) {
|
|
1443
|
+
const {
|
|
1444
|
+
name,
|
|
1445
|
+
baseType,
|
|
1446
|
+
disabled = false,
|
|
1447
|
+
formData,
|
|
1448
|
+
idSchema,
|
|
1449
|
+
onBlur,
|
|
1450
|
+
onChange,
|
|
1451
|
+
options,
|
|
1452
|
+
onFocus,
|
|
1453
|
+
registry,
|
|
1454
|
+
uiSchema,
|
|
1455
|
+
schema,
|
|
1456
|
+
formContext,
|
|
1457
|
+
autofocus,
|
|
1458
|
+
readonly,
|
|
1459
|
+
required,
|
|
1460
|
+
errorSchema,
|
|
1461
|
+
hideError = false
|
|
1462
|
+
} = props;
|
|
1463
|
+
const { widgets: widgets2, schemaUtils, globalUiOptions } = registry;
|
|
1464
|
+
const [enumOptions, setEnumOptions] = react.useState(computeEnumOptions(schema, options, schemaUtils, uiSchema, formData));
|
|
1465
|
+
const id = get2(idSchema, utils.ID_KEY);
|
|
1466
|
+
const discriminator = utils.getDiscriminatorFieldFromSchema(schema);
|
|
1467
|
+
const FieldErrorTemplate2 = utils.getTemplate("FieldErrorTemplate", registry, options);
|
|
1468
|
+
const FieldTemplate2 = utils.getTemplate("FieldTemplate", registry, options);
|
|
1469
|
+
const schemaHash = utils.hashObject(schema);
|
|
1470
|
+
const optionsHash = utils.hashObject(options);
|
|
1471
|
+
const uiSchemaHash = uiSchema ? utils.hashObject(uiSchema) : "";
|
|
1472
|
+
const formDataHash = formData ? utils.hashObject(formData) : "";
|
|
1473
|
+
react.useEffect(() => {
|
|
1474
|
+
setEnumOptions(computeEnumOptions(schema, options, schemaUtils, uiSchema, formData));
|
|
1475
|
+
}, [schemaHash, optionsHash, schemaUtils, uiSchemaHash, formDataHash]);
|
|
1476
|
+
const {
|
|
1477
|
+
widget = discriminator ? "radio" : "select",
|
|
1478
|
+
title = "",
|
|
1479
|
+
placeholder = "",
|
|
1480
|
+
optionsSchemaSelector: selectorField = discriminator,
|
|
1481
|
+
hideError: uiSchemaHideError,
|
|
1482
|
+
...uiOptions
|
|
1483
|
+
} = utils.getUiOptions(uiSchema);
|
|
1484
|
+
if (!selectorField) {
|
|
1485
|
+
throw new Error("No selector field provided for the LayoutMultiSchemaField");
|
|
846
1486
|
}
|
|
1487
|
+
const selectedOption = get2(formData, selectorField);
|
|
1488
|
+
let optionSchema = get2(enumOptions[0]?.schema, [utils.PROPERTIES_KEY, selectorField], {});
|
|
1489
|
+
const option = getSelectedOption(enumOptions, selectorField, selectedOption);
|
|
1490
|
+
optionSchema = optionSchema?.type ? optionSchema : { ...optionSchema, type: option?.type || baseType };
|
|
1491
|
+
const Widget = utils.getWidget(optionSchema, widget, widgets2);
|
|
1492
|
+
const hideFieldError = uiSchemaHideError === void 0 ? hideError : Boolean(uiSchemaHideError);
|
|
1493
|
+
const rawErrors = get2(errorSchema, [utils.ERRORS_KEY], []);
|
|
1494
|
+
const fieldErrorSchema = omit3(errorSchema, [utils.ERRORS_KEY]);
|
|
1495
|
+
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
1496
|
+
const onOptionChange = (opt) => {
|
|
1497
|
+
const newOption = getSelectedOption(enumOptions, selectorField, opt);
|
|
1498
|
+
const oldOption = getSelectedOption(enumOptions, selectorField, selectedOption);
|
|
1499
|
+
let newFormData = schemaUtils.sanitizeDataForNewSchema(newOption, oldOption, formData);
|
|
1500
|
+
if (newFormData && newOption) {
|
|
1501
|
+
newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, "excludeObjectChildren");
|
|
1502
|
+
}
|
|
1503
|
+
if (newFormData) {
|
|
1504
|
+
set(newFormData, selectorField, opt);
|
|
1505
|
+
}
|
|
1506
|
+
onChange(newFormData, void 0, id);
|
|
1507
|
+
};
|
|
1508
|
+
const widgetOptions = { enumOptions, ...uiOptions };
|
|
1509
|
+
const errors = !hideFieldError && rawErrors.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(FieldErrorTemplate2, { idSchema, schema, errors: rawErrors, registry }) : void 0;
|
|
1510
|
+
const ignored = (value) => noop;
|
|
847
1511
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
848
|
-
|
|
1512
|
+
FieldTemplate2,
|
|
849
1513
|
{
|
|
850
|
-
|
|
1514
|
+
id,
|
|
851
1515
|
schema,
|
|
1516
|
+
label: (title || schema.title) ?? "",
|
|
1517
|
+
disabled: disabled || Array.isArray(enumOptions) && isEmpty(enumOptions),
|
|
852
1518
|
uiSchema,
|
|
853
|
-
|
|
854
|
-
name,
|
|
855
|
-
onChange,
|
|
856
|
-
onFocus,
|
|
857
|
-
onBlur,
|
|
858
|
-
label,
|
|
859
|
-
hideLabel: !displayLabel,
|
|
860
|
-
value: formData,
|
|
1519
|
+
formContext,
|
|
861
1520
|
required,
|
|
862
|
-
|
|
863
|
-
readonly,
|
|
864
|
-
hideError,
|
|
1521
|
+
readonly: !!readonly,
|
|
865
1522
|
registry,
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
1523
|
+
displayLabel,
|
|
1524
|
+
errors,
|
|
1525
|
+
onChange,
|
|
1526
|
+
onDropPropertyClick: ignored,
|
|
1527
|
+
onKeyChange: ignored,
|
|
1528
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1529
|
+
Widget,
|
|
1530
|
+
{
|
|
1531
|
+
id,
|
|
1532
|
+
name,
|
|
1533
|
+
schema,
|
|
1534
|
+
label: (title || schema.title) ?? "",
|
|
1535
|
+
disabled: disabled || Array.isArray(enumOptions) && isEmpty(enumOptions),
|
|
1536
|
+
uiSchema,
|
|
1537
|
+
formContext,
|
|
1538
|
+
autofocus,
|
|
1539
|
+
readonly,
|
|
1540
|
+
required,
|
|
1541
|
+
registry,
|
|
1542
|
+
multiple: false,
|
|
1543
|
+
rawErrors,
|
|
1544
|
+
hideError: hideFieldError,
|
|
1545
|
+
hideLabel: !displayLabel,
|
|
1546
|
+
errorSchema: fieldErrorSchema,
|
|
1547
|
+
placeholder,
|
|
1548
|
+
onChange: onOptionChange,
|
|
1549
|
+
onBlur,
|
|
1550
|
+
onFocus,
|
|
1551
|
+
value: selectedOption,
|
|
1552
|
+
options: widgetOptions
|
|
1553
|
+
}
|
|
1554
|
+
)
|
|
869
1555
|
}
|
|
870
1556
|
);
|
|
871
1557
|
}
|
|
872
|
-
var BooleanField_default = BooleanField;
|
|
873
1558
|
var AnyOfField = class extends react.Component {
|
|
874
1559
|
/** Constructs an `AnyOfField` with the given `props` to initialize the initially selected option in state
|
|
875
1560
|
*
|
|
@@ -877,29 +1562,6 @@
|
|
|
877
1562
|
*/
|
|
878
1563
|
constructor(props) {
|
|
879
1564
|
super(props);
|
|
880
|
-
/** Callback handler to remember what the currently selected option is. In addition to that the `formData` is updated
|
|
881
|
-
* to remove properties that are not part of the newly selected option schema, and then the updated data is passed to
|
|
882
|
-
* the `onChange` handler.
|
|
883
|
-
*
|
|
884
|
-
* @param option - The new option value being selected
|
|
885
|
-
*/
|
|
886
|
-
this.onOptionChange = (option) => {
|
|
887
|
-
const { selectedOption, retrievedOptions } = this.state;
|
|
888
|
-
const { formData, onChange, registry } = this.props;
|
|
889
|
-
const { schemaUtils } = registry;
|
|
890
|
-
const intOption = option !== void 0 ? parseInt(option, 10) : -1;
|
|
891
|
-
if (intOption === selectedOption) {
|
|
892
|
-
return;
|
|
893
|
-
}
|
|
894
|
-
const newOption = intOption >= 0 ? retrievedOptions[intOption] : void 0;
|
|
895
|
-
const oldOption = selectedOption >= 0 ? retrievedOptions[selectedOption] : void 0;
|
|
896
|
-
let newFormData = schemaUtils.sanitizeDataForNewSchema(newOption, oldOption, formData);
|
|
897
|
-
if (newFormData && newOption) {
|
|
898
|
-
newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, "excludeObjectChildren");
|
|
899
|
-
}
|
|
900
|
-
onChange(newFormData, void 0, this.getFieldId());
|
|
901
|
-
this.setState({ selectedOption: intOption });
|
|
902
|
-
};
|
|
903
1565
|
const {
|
|
904
1566
|
formData,
|
|
905
1567
|
options,
|
|
@@ -954,6 +1616,30 @@
|
|
|
954
1616
|
const option = schemaUtils.getClosestMatchingOption(formData, options, selectedOption, discriminator);
|
|
955
1617
|
return option;
|
|
956
1618
|
}
|
|
1619
|
+
/** Callback handler to remember what the currently selected option is. In addition to that the `formData` is updated
|
|
1620
|
+
* to remove properties that are not part of the newly selected option schema, and then the updated data is passed to
|
|
1621
|
+
* the `onChange` handler.
|
|
1622
|
+
*
|
|
1623
|
+
* @param option - The new option value being selected
|
|
1624
|
+
*/
|
|
1625
|
+
onOptionChange = (option) => {
|
|
1626
|
+
const { selectedOption, retrievedOptions } = this.state;
|
|
1627
|
+
const { formData, onChange, registry } = this.props;
|
|
1628
|
+
const { schemaUtils } = registry;
|
|
1629
|
+
const intOption = option !== void 0 ? parseInt(option, 10) : -1;
|
|
1630
|
+
if (intOption === selectedOption) {
|
|
1631
|
+
return;
|
|
1632
|
+
}
|
|
1633
|
+
const newOption = intOption >= 0 ? retrievedOptions[intOption] : void 0;
|
|
1634
|
+
const oldOption = selectedOption >= 0 ? retrievedOptions[selectedOption] : void 0;
|
|
1635
|
+
let newFormData = schemaUtils.sanitizeDataForNewSchema(newOption, oldOption, formData);
|
|
1636
|
+
if (newOption) {
|
|
1637
|
+
newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, "excludeObjectChildren");
|
|
1638
|
+
}
|
|
1639
|
+
this.setState({ selectedOption: intOption }, () => {
|
|
1640
|
+
onChange(newFormData, void 0, this.getFieldId());
|
|
1641
|
+
});
|
|
1642
|
+
};
|
|
957
1643
|
getFieldId() {
|
|
958
1644
|
const { idSchema, schema } = this.props;
|
|
959
1645
|
return `${idSchema.$id}${schema.oneOf ? "__oneof_select" : "__anyof_select"}`;
|
|
@@ -968,6 +1654,7 @@
|
|
|
968
1654
|
formContext,
|
|
969
1655
|
onBlur,
|
|
970
1656
|
onFocus,
|
|
1657
|
+
readonly,
|
|
971
1658
|
registry,
|
|
972
1659
|
schema,
|
|
973
1660
|
uiSchema
|
|
@@ -984,8 +1671,8 @@
|
|
|
984
1671
|
...uiOptions
|
|
985
1672
|
} = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
986
1673
|
const Widget = utils.getWidget({ type: "number" }, widget, widgets2);
|
|
987
|
-
const rawErrors =
|
|
988
|
-
const fieldErrorSchema =
|
|
1674
|
+
const rawErrors = get2(errorSchema, utils.ERRORS_KEY, []);
|
|
1675
|
+
const fieldErrorSchema = omit3(errorSchema, [utils.ERRORS_KEY]);
|
|
989
1676
|
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
990
1677
|
const option = selectedOption >= 0 ? retrievedOptions[selectedOption] || null : null;
|
|
991
1678
|
let optionSchema;
|
|
@@ -1042,10 +1729,11 @@
|
|
|
1042
1729
|
autocomplete,
|
|
1043
1730
|
autofocus,
|
|
1044
1731
|
label: title ?? name,
|
|
1045
|
-
hideLabel: !displayLabel
|
|
1732
|
+
hideLabel: !displayLabel,
|
|
1733
|
+
readonly
|
|
1046
1734
|
}
|
|
1047
1735
|
) }),
|
|
1048
|
-
optionSchema && /* @__PURE__ */ jsxRuntime.jsx(_SchemaField, { ...this.props, schema: optionSchema, uiSchema: optionUiSchema })
|
|
1736
|
+
optionSchema && optionSchema.type !== "null" && /* @__PURE__ */ jsxRuntime.jsx(_SchemaField, { ...this.props, schema: optionSchema, uiSchema: optionUiSchema })
|
|
1049
1737
|
] });
|
|
1050
1738
|
}
|
|
1051
1739
|
};
|
|
@@ -1058,13 +1746,13 @@
|
|
|
1058
1746
|
const { StringField: StringField2 } = registry.fields;
|
|
1059
1747
|
let value = formData;
|
|
1060
1748
|
const handleChange = react.useCallback(
|
|
1061
|
-
(value2) => {
|
|
1749
|
+
(value2, errorSchema, id) => {
|
|
1062
1750
|
setLastValue(value2);
|
|
1063
1751
|
if (`${value2}`.charAt(0) === ".") {
|
|
1064
1752
|
value2 = `0${value2}`;
|
|
1065
1753
|
}
|
|
1066
1754
|
const processed = typeof value2 === "string" && value2.match(trailingCharMatcherWithPrefix) ? utils.asNumber(value2.replace(trailingCharMatcher, "")) : utils.asNumber(value2);
|
|
1067
|
-
onChange(processed);
|
|
1755
|
+
onChange(processed, errorSchema, id);
|
|
1068
1756
|
},
|
|
1069
1757
|
[onChange]
|
|
1070
1758
|
);
|
|
@@ -1078,134 +1766,11 @@
|
|
|
1078
1766
|
}
|
|
1079
1767
|
var NumberField_default = NumberField;
|
|
1080
1768
|
var ObjectField = class extends react.Component {
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
additionalProperties: {}
|
|
1087
|
-
};
|
|
1088
|
-
/** Returns the `onPropertyChange` handler for the `name` field. Handles the special case where a user is attempting
|
|
1089
|
-
* to clear the data for a field added as an additional property. Calls the `onChange()` handler with the updated
|
|
1090
|
-
* formData.
|
|
1091
|
-
*
|
|
1092
|
-
* @param name - The name of the property
|
|
1093
|
-
* @param addedByAdditionalProperties - Flag indicating whether this property is an additional property
|
|
1094
|
-
* @returns - The onPropertyChange callback for the `name` property
|
|
1095
|
-
*/
|
|
1096
|
-
this.onPropertyChange = (name, addedByAdditionalProperties = false) => {
|
|
1097
|
-
return (value, newErrorSchema, id) => {
|
|
1098
|
-
const { formData, onChange, errorSchema } = this.props;
|
|
1099
|
-
if (value === void 0 && addedByAdditionalProperties) {
|
|
1100
|
-
value = "";
|
|
1101
|
-
}
|
|
1102
|
-
const newFormData = { ...formData, [name]: value };
|
|
1103
|
-
onChange(
|
|
1104
|
-
newFormData,
|
|
1105
|
-
errorSchema && errorSchema && {
|
|
1106
|
-
...errorSchema,
|
|
1107
|
-
[name]: newErrorSchema
|
|
1108
|
-
},
|
|
1109
|
-
id
|
|
1110
|
-
);
|
|
1111
|
-
};
|
|
1112
|
-
};
|
|
1113
|
-
/** Returns a callback to handle the onDropPropertyClick event for the given `key` which removes the old `key` data
|
|
1114
|
-
* and calls the `onChange` callback with it
|
|
1115
|
-
*
|
|
1116
|
-
* @param key - The key for which the drop callback is desired
|
|
1117
|
-
* @returns - The drop property click callback
|
|
1118
|
-
*/
|
|
1119
|
-
this.onDropPropertyClick = (key) => {
|
|
1120
|
-
return (event) => {
|
|
1121
|
-
event.preventDefault();
|
|
1122
|
-
const { onChange, formData } = this.props;
|
|
1123
|
-
const copiedFormData = { ...formData };
|
|
1124
|
-
unset(copiedFormData, key);
|
|
1125
|
-
onChange(copiedFormData);
|
|
1126
|
-
};
|
|
1127
|
-
};
|
|
1128
|
-
/** Computes the next available key name from the `preferredKey`, indexing through the already existing keys until one
|
|
1129
|
-
* that is already not assigned is found.
|
|
1130
|
-
*
|
|
1131
|
-
* @param preferredKey - The preferred name of a new key
|
|
1132
|
-
* @param [formData] - The form data in which to check if the desired key already exists
|
|
1133
|
-
* @returns - The name of the next available key from `preferredKey`
|
|
1134
|
-
*/
|
|
1135
|
-
this.getAvailableKey = (preferredKey, formData) => {
|
|
1136
|
-
const { uiSchema, registry } = this.props;
|
|
1137
|
-
const { duplicateKeySuffixSeparator = "-" } = utils.getUiOptions(uiSchema, registry.globalUiOptions);
|
|
1138
|
-
let index = 0;
|
|
1139
|
-
let newKey = preferredKey;
|
|
1140
|
-
while (has(formData, newKey)) {
|
|
1141
|
-
newKey = `${preferredKey}${duplicateKeySuffixSeparator}${++index}`;
|
|
1142
|
-
}
|
|
1143
|
-
return newKey;
|
|
1144
|
-
};
|
|
1145
|
-
/** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
|
|
1146
|
-
* callback will attempt to rename the key and move the existing data to that key, calling `onChange` when it does.
|
|
1147
|
-
*
|
|
1148
|
-
* @param oldValue - The old value of a field
|
|
1149
|
-
* @returns - The key change callback function
|
|
1150
|
-
*/
|
|
1151
|
-
this.onKeyChange = (oldValue) => {
|
|
1152
|
-
return (value, newErrorSchema) => {
|
|
1153
|
-
if (oldValue === value) {
|
|
1154
|
-
return;
|
|
1155
|
-
}
|
|
1156
|
-
const { formData, onChange, errorSchema } = this.props;
|
|
1157
|
-
value = this.getAvailableKey(value, formData);
|
|
1158
|
-
const newFormData = {
|
|
1159
|
-
...formData
|
|
1160
|
-
};
|
|
1161
|
-
const newKeys = { [oldValue]: value };
|
|
1162
|
-
const keyValues = Object.keys(newFormData).map((key) => {
|
|
1163
|
-
const newKey = newKeys[key] || key;
|
|
1164
|
-
return { [newKey]: newFormData[key] };
|
|
1165
|
-
});
|
|
1166
|
-
const renamedObj = Object.assign({}, ...keyValues);
|
|
1167
|
-
this.setState({ wasPropertyKeyModified: true });
|
|
1168
|
-
onChange(
|
|
1169
|
-
renamedObj,
|
|
1170
|
-
errorSchema && errorSchema && {
|
|
1171
|
-
...errorSchema,
|
|
1172
|
-
[value]: newErrorSchema
|
|
1173
|
-
}
|
|
1174
|
-
);
|
|
1175
|
-
};
|
|
1176
|
-
};
|
|
1177
|
-
/** Handles the adding of a new additional property on the given `schema`. Calls the `onChange` callback once the new
|
|
1178
|
-
* default data for that field has been added to the formData.
|
|
1179
|
-
*
|
|
1180
|
-
* @param schema - The schema element to which the new property is being added
|
|
1181
|
-
*/
|
|
1182
|
-
this.handleAddClick = (schema) => () => {
|
|
1183
|
-
if (!schema.additionalProperties) {
|
|
1184
|
-
return;
|
|
1185
|
-
}
|
|
1186
|
-
const { formData, onChange, registry } = this.props;
|
|
1187
|
-
const newFormData = { ...formData };
|
|
1188
|
-
let type = void 0;
|
|
1189
|
-
let defaultValue = void 0;
|
|
1190
|
-
if (isObject(schema.additionalProperties)) {
|
|
1191
|
-
type = schema.additionalProperties.type;
|
|
1192
|
-
defaultValue = schema.additionalProperties.default;
|
|
1193
|
-
let apSchema = schema.additionalProperties;
|
|
1194
|
-
if (utils.REF_KEY in apSchema) {
|
|
1195
|
-
const { schemaUtils } = registry;
|
|
1196
|
-
apSchema = schemaUtils.retrieveSchema({ $ref: apSchema[utils.REF_KEY] }, formData);
|
|
1197
|
-
type = apSchema.type;
|
|
1198
|
-
defaultValue = apSchema.default;
|
|
1199
|
-
}
|
|
1200
|
-
if (!type && (utils.ANY_OF_KEY in apSchema || utils.ONE_OF_KEY in apSchema)) {
|
|
1201
|
-
type = "object";
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
const newKey = this.getAvailableKey("newKey", newFormData);
|
|
1205
|
-
set(newFormData, newKey, defaultValue ?? this.getDefaultValue(type));
|
|
1206
|
-
onChange(newFormData);
|
|
1207
|
-
};
|
|
1208
|
-
}
|
|
1769
|
+
/** Set up the initial state */
|
|
1770
|
+
state = {
|
|
1771
|
+
wasPropertyKeyModified: false,
|
|
1772
|
+
additionalProperties: {}
|
|
1773
|
+
};
|
|
1209
1774
|
/** Returns a flag indicating whether the `name` field is required in the object schema
|
|
1210
1775
|
*
|
|
1211
1776
|
* @param name - The name of the field to check for required-ness
|
|
@@ -1215,6 +1780,95 @@
|
|
|
1215
1780
|
const { schema } = this.props;
|
|
1216
1781
|
return Array.isArray(schema.required) && schema.required.indexOf(name) !== -1;
|
|
1217
1782
|
}
|
|
1783
|
+
/** Returns the `onPropertyChange` handler for the `name` field. Handles the special case where a user is attempting
|
|
1784
|
+
* to clear the data for a field added as an additional property. Calls the `onChange()` handler with the updated
|
|
1785
|
+
* formData.
|
|
1786
|
+
*
|
|
1787
|
+
* @param name - The name of the property
|
|
1788
|
+
* @param addedByAdditionalProperties - Flag indicating whether this property is an additional property
|
|
1789
|
+
* @returns - The onPropertyChange callback for the `name` property
|
|
1790
|
+
*/
|
|
1791
|
+
onPropertyChange = (name, addedByAdditionalProperties = false) => {
|
|
1792
|
+
return (value, newErrorSchema, id) => {
|
|
1793
|
+
const { formData, onChange, errorSchema } = this.props;
|
|
1794
|
+
if (value === void 0 && addedByAdditionalProperties) {
|
|
1795
|
+
value = "";
|
|
1796
|
+
}
|
|
1797
|
+
const newFormData = { ...formData, [name]: value };
|
|
1798
|
+
onChange(
|
|
1799
|
+
newFormData,
|
|
1800
|
+
errorSchema && errorSchema && {
|
|
1801
|
+
...errorSchema,
|
|
1802
|
+
[name]: newErrorSchema
|
|
1803
|
+
},
|
|
1804
|
+
id
|
|
1805
|
+
);
|
|
1806
|
+
};
|
|
1807
|
+
};
|
|
1808
|
+
/** Returns a callback to handle the onDropPropertyClick event for the given `key` which removes the old `key` data
|
|
1809
|
+
* and calls the `onChange` callback with it
|
|
1810
|
+
*
|
|
1811
|
+
* @param key - The key for which the drop callback is desired
|
|
1812
|
+
* @returns - The drop property click callback
|
|
1813
|
+
*/
|
|
1814
|
+
onDropPropertyClick = (key) => {
|
|
1815
|
+
return (event) => {
|
|
1816
|
+
event.preventDefault();
|
|
1817
|
+
const { onChange, formData } = this.props;
|
|
1818
|
+
const copiedFormData = { ...formData };
|
|
1819
|
+
unset(copiedFormData, key);
|
|
1820
|
+
onChange(copiedFormData);
|
|
1821
|
+
};
|
|
1822
|
+
};
|
|
1823
|
+
/** Computes the next available key name from the `preferredKey`, indexing through the already existing keys until one
|
|
1824
|
+
* that is already not assigned is found.
|
|
1825
|
+
*
|
|
1826
|
+
* @param preferredKey - The preferred name of a new key
|
|
1827
|
+
* @param [formData] - The form data in which to check if the desired key already exists
|
|
1828
|
+
* @returns - The name of the next available key from `preferredKey`
|
|
1829
|
+
*/
|
|
1830
|
+
getAvailableKey = (preferredKey, formData) => {
|
|
1831
|
+
const { uiSchema, registry } = this.props;
|
|
1832
|
+
const { duplicateKeySuffixSeparator = "-" } = utils.getUiOptions(uiSchema, registry.globalUiOptions);
|
|
1833
|
+
let index = 0;
|
|
1834
|
+
let newKey = preferredKey;
|
|
1835
|
+
while (has(formData, newKey)) {
|
|
1836
|
+
newKey = `${preferredKey}${duplicateKeySuffixSeparator}${++index}`;
|
|
1837
|
+
}
|
|
1838
|
+
return newKey;
|
|
1839
|
+
};
|
|
1840
|
+
/** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
|
|
1841
|
+
* callback will attempt to rename the key and move the existing data to that key, calling `onChange` when it does.
|
|
1842
|
+
*
|
|
1843
|
+
* @param oldValue - The old value of a field
|
|
1844
|
+
* @returns - The key change callback function
|
|
1845
|
+
*/
|
|
1846
|
+
onKeyChange = (oldValue) => {
|
|
1847
|
+
return (value, newErrorSchema) => {
|
|
1848
|
+
if (oldValue === value) {
|
|
1849
|
+
return;
|
|
1850
|
+
}
|
|
1851
|
+
const { formData, onChange, errorSchema } = this.props;
|
|
1852
|
+
value = this.getAvailableKey(value, formData);
|
|
1853
|
+
const newFormData = {
|
|
1854
|
+
...formData
|
|
1855
|
+
};
|
|
1856
|
+
const newKeys = { [oldValue]: value };
|
|
1857
|
+
const keyValues = Object.keys(newFormData).map((key) => {
|
|
1858
|
+
const newKey = newKeys[key] || key;
|
|
1859
|
+
return { [newKey]: newFormData[key] };
|
|
1860
|
+
});
|
|
1861
|
+
const renamedObj = Object.assign({}, ...keyValues);
|
|
1862
|
+
this.setState({ wasPropertyKeyModified: true });
|
|
1863
|
+
onChange(
|
|
1864
|
+
renamedObj,
|
|
1865
|
+
errorSchema && errorSchema && {
|
|
1866
|
+
...errorSchema,
|
|
1867
|
+
[value]: newErrorSchema
|
|
1868
|
+
}
|
|
1869
|
+
);
|
|
1870
|
+
};
|
|
1871
|
+
};
|
|
1218
1872
|
/** Returns a default value to be used for a new additional schema property of the given `type`
|
|
1219
1873
|
*
|
|
1220
1874
|
* @param type - The type of the new additional schema property
|
|
@@ -1239,6 +1893,45 @@
|
|
|
1239
1893
|
return translateString(utils.TranslatableString.NewStringDefault);
|
|
1240
1894
|
}
|
|
1241
1895
|
}
|
|
1896
|
+
/** Handles the adding of a new additional property on the given `schema`. Calls the `onChange` callback once the new
|
|
1897
|
+
* default data for that field has been added to the formData.
|
|
1898
|
+
*
|
|
1899
|
+
* @param schema - The schema element to which the new property is being added
|
|
1900
|
+
*/
|
|
1901
|
+
handleAddClick = (schema) => () => {
|
|
1902
|
+
if (!(schema.additionalProperties || schema.patternProperties)) {
|
|
1903
|
+
return;
|
|
1904
|
+
}
|
|
1905
|
+
const { formData, onChange, registry } = this.props;
|
|
1906
|
+
const newFormData = { ...formData };
|
|
1907
|
+
const newKey = this.getAvailableKey("newKey", newFormData);
|
|
1908
|
+
if (schema.patternProperties) {
|
|
1909
|
+
set(newFormData, newKey, null);
|
|
1910
|
+
} else {
|
|
1911
|
+
let type = void 0;
|
|
1912
|
+
let constValue = void 0;
|
|
1913
|
+
let defaultValue = void 0;
|
|
1914
|
+
if (isObject(schema.additionalProperties)) {
|
|
1915
|
+
type = schema.additionalProperties.type;
|
|
1916
|
+
constValue = schema.additionalProperties.const;
|
|
1917
|
+
defaultValue = schema.additionalProperties.default;
|
|
1918
|
+
let apSchema = schema.additionalProperties;
|
|
1919
|
+
if (utils.REF_KEY in apSchema) {
|
|
1920
|
+
const { schemaUtils } = registry;
|
|
1921
|
+
apSchema = schemaUtils.retrieveSchema({ $ref: apSchema[utils.REF_KEY] }, formData);
|
|
1922
|
+
type = apSchema.type;
|
|
1923
|
+
constValue = apSchema.const;
|
|
1924
|
+
defaultValue = apSchema.default;
|
|
1925
|
+
}
|
|
1926
|
+
if (!type && (utils.ANY_OF_KEY in apSchema || utils.ONE_OF_KEY in apSchema)) {
|
|
1927
|
+
type = "object";
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
const newValue = constValue ?? defaultValue ?? this.getDefaultValue(type);
|
|
1931
|
+
set(newFormData, newKey, newValue);
|
|
1932
|
+
}
|
|
1933
|
+
onChange(newFormData);
|
|
1934
|
+
};
|
|
1242
1935
|
/** Renders the `ObjectField` from the given props
|
|
1243
1936
|
*/
|
|
1244
1937
|
render() {
|
|
@@ -1273,7 +1966,7 @@
|
|
|
1273
1966
|
orderedProperties = utils.orderProperties(properties, uiOptions.order);
|
|
1274
1967
|
} catch (err) {
|
|
1275
1968
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1276
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "config-error", style: { color: "red" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { options: { disableParsingRawHTML: true }, children: translateString(utils.TranslatableString.InvalidObjectField, [name || "root", err.message]) }) }),
|
|
1969
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "rjsf-config-error", style: { color: "red" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { options: { disableParsingRawHTML: true }, children: translateString(utils.TranslatableString.InvalidObjectField, [name || "root", err.message]) }) }),
|
|
1277
1970
|
/* @__PURE__ */ jsxRuntime.jsx("pre", { children: JSON.stringify(schema) })
|
|
1278
1971
|
] });
|
|
1279
1972
|
}
|
|
@@ -1286,20 +1979,20 @@
|
|
|
1286
1979
|
const addedByAdditionalProperties = has(schema, [utils.PROPERTIES_KEY, name2, utils.ADDITIONAL_PROPERTY_FLAG]);
|
|
1287
1980
|
const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[name2];
|
|
1288
1981
|
const hidden = utils.getUiOptions(fieldUiSchema).widget === "hidden";
|
|
1289
|
-
const fieldIdSchema =
|
|
1982
|
+
const fieldIdSchema = get2(idSchema, [name2], {});
|
|
1290
1983
|
return {
|
|
1291
1984
|
content: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1292
1985
|
SchemaField2,
|
|
1293
1986
|
{
|
|
1294
1987
|
name: name2,
|
|
1295
1988
|
required: this.isRequired(name2),
|
|
1296
|
-
schema:
|
|
1989
|
+
schema: get2(schema, [utils.PROPERTIES_KEY, name2], {}),
|
|
1297
1990
|
uiSchema: fieldUiSchema,
|
|
1298
|
-
errorSchema:
|
|
1991
|
+
errorSchema: get2(errorSchema, name2),
|
|
1299
1992
|
idSchema: fieldIdSchema,
|
|
1300
1993
|
idPrefix,
|
|
1301
1994
|
idSeparator,
|
|
1302
|
-
formData:
|
|
1995
|
+
formData: get2(formData, name2),
|
|
1303
1996
|
formContext,
|
|
1304
1997
|
wasPropertyKeyModified: this.state.wasPropertyKeyModified,
|
|
1305
1998
|
onKeyChange: this.onKeyChange(name2),
|
|
@@ -1432,9 +2125,9 @@
|
|
|
1432
2125
|
}
|
|
1433
2126
|
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
1434
2127
|
const { __errors, ...fieldErrorSchema } = errorSchema || {};
|
|
1435
|
-
const fieldUiSchema =
|
|
2128
|
+
const fieldUiSchema = omit3(uiSchema, ["ui:classNames", "classNames", "ui:style"]);
|
|
1436
2129
|
if (utils.UI_OPTIONS_KEY in fieldUiSchema) {
|
|
1437
|
-
fieldUiSchema[utils.UI_OPTIONS_KEY] =
|
|
2130
|
+
fieldUiSchema[utils.UI_OPTIONS_KEY] = omit3(fieldUiSchema[utils.UI_OPTIONS_KEY], ["classNames", "style"]);
|
|
1438
2131
|
}
|
|
1439
2132
|
const field = /* @__PURE__ */ jsxRuntime.jsx(
|
|
1440
2133
|
FieldComponent,
|
|
@@ -1461,20 +2154,11 @@
|
|
|
1461
2154
|
label = utils.ADDITIONAL_PROPERTY_FLAG in schema ? name : uiOptions.title || props.schema.title || schema.title || props.title || name;
|
|
1462
2155
|
}
|
|
1463
2156
|
const description = uiOptions.description || props.schema.description || schema.description || "";
|
|
1464
|
-
const richDescription = uiOptions.enableMarkdownInDescription ? /* @__PURE__ */ jsxRuntime.jsx(Markdown, { options: { disableParsingRawHTML: true }, children: description }) : description;
|
|
1465
2157
|
const help = uiOptions.help;
|
|
1466
2158
|
const hidden = uiOptions.widget === "hidden";
|
|
1467
|
-
const classNames = ["
|
|
2159
|
+
const classNames = ["rjsf-field", `rjsf-field-${utils.getSchemaType(schema)}`];
|
|
1468
2160
|
if (!hideError && __errors && __errors.length > 0) {
|
|
1469
|
-
classNames.push("field-error
|
|
1470
|
-
}
|
|
1471
|
-
if (uiSchema?.classNames) {
|
|
1472
|
-
{
|
|
1473
|
-
console.warn(
|
|
1474
|
-
"'uiSchema.classNames' is deprecated and may be removed in a major release; Use 'ui:classNames' instead."
|
|
1475
|
-
);
|
|
1476
|
-
}
|
|
1477
|
-
classNames.push(uiSchema.classNames);
|
|
2161
|
+
classNames.push("rjsf-field-error");
|
|
1478
2162
|
}
|
|
1479
2163
|
if (uiOptions.classNames) {
|
|
1480
2164
|
classNames.push(uiOptions.classNames);
|
|
@@ -1506,7 +2190,7 @@
|
|
|
1506
2190
|
DescriptionFieldTemplate,
|
|
1507
2191
|
{
|
|
1508
2192
|
id: utils.descriptionId(id),
|
|
1509
|
-
description
|
|
2193
|
+
description,
|
|
1510
2194
|
schema,
|
|
1511
2195
|
uiSchema,
|
|
1512
2196
|
registry
|
|
@@ -1561,6 +2245,7 @@
|
|
|
1561
2245
|
(_schema2) => schemaUtils.retrieveSchema(isObject(_schema2) ? _schema2 : {}, formData)
|
|
1562
2246
|
),
|
|
1563
2247
|
registry,
|
|
2248
|
+
required,
|
|
1564
2249
|
schema,
|
|
1565
2250
|
uiSchema
|
|
1566
2251
|
}
|
|
@@ -1585,6 +2270,7 @@
|
|
|
1585
2270
|
(_schema2) => schemaUtils.retrieveSchema(isObject(_schema2) ? _schema2 : {}, formData)
|
|
1586
2271
|
),
|
|
1587
2272
|
registry,
|
|
2273
|
+
required,
|
|
1588
2274
|
schema,
|
|
1589
2275
|
uiSchema
|
|
1590
2276
|
}
|
|
@@ -1674,6 +2360,9 @@
|
|
|
1674
2360
|
ArrayField: ArrayField_default,
|
|
1675
2361
|
// ArrayField falls back to SchemaField if ArraySchemaField is not defined, which it isn't by default
|
|
1676
2362
|
BooleanField: BooleanField_default,
|
|
2363
|
+
LayoutGridField,
|
|
2364
|
+
LayoutHeaderField,
|
|
2365
|
+
LayoutMultiSchemaField,
|
|
1677
2366
|
NumberField: NumberField_default,
|
|
1678
2367
|
ObjectField: ObjectField_default,
|
|
1679
2368
|
OneOfField: MultiSchemaField_default,
|
|
@@ -1707,24 +2396,13 @@
|
|
|
1707
2396
|
);
|
|
1708
2397
|
}
|
|
1709
2398
|
function ArrayFieldItemTemplate(props) {
|
|
1710
|
-
const {
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
hasToolbar,
|
|
1715
|
-
hasMoveDown,
|
|
1716
|
-
hasMoveUp,
|
|
1717
|
-
hasRemove,
|
|
1718
|
-
hasCopy,
|
|
1719
|
-
index,
|
|
1720
|
-
onCopyIndexClick,
|
|
1721
|
-
onDropIndexClick,
|
|
1722
|
-
onReorderClick,
|
|
1723
|
-
readonly,
|
|
2399
|
+
const { children, className, buttonsProps, hasToolbar, registry, uiSchema } = props;
|
|
2400
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
2401
|
+
const ArrayFieldItemButtonsTemplate2 = utils.getTemplate(
|
|
2402
|
+
"ArrayFieldItemButtonsTemplate",
|
|
1724
2403
|
registry,
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
const { CopyButton: CopyButton2, MoveDownButton: MoveDownButton2, MoveUpButton: MoveUpButton2, RemoveButton: RemoveButton2 } = registry.templates.ButtonTemplates;
|
|
2404
|
+
uiOptions
|
|
2405
|
+
);
|
|
1728
2406
|
const btnStyle = {
|
|
1729
2407
|
flex: 1,
|
|
1730
2408
|
paddingLeft: 6,
|
|
@@ -1733,7 +2411,7 @@
|
|
|
1733
2411
|
};
|
|
1734
2412
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
1735
2413
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: hasToolbar ? "col-xs-9" : "col-xs-12", children }),
|
|
1736
|
-
hasToolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-3 array-item-toolbox", children: /* @__PURE__ */ jsxRuntime.
|
|
2414
|
+
hasToolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-3 array-item-toolbox", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1737
2415
|
"div",
|
|
1738
2416
|
{
|
|
1739
2417
|
className: "btn-group",
|
|
@@ -1741,52 +2419,79 @@
|
|
|
1741
2419
|
display: "flex",
|
|
1742
2420
|
justifyContent: "space-around"
|
|
1743
2421
|
},
|
|
1744
|
-
children:
|
|
1745
|
-
(hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1746
|
-
MoveUpButton2,
|
|
1747
|
-
{
|
|
1748
|
-
style: btnStyle,
|
|
1749
|
-
disabled: disabled || readonly || !hasMoveUp,
|
|
1750
|
-
onClick: onReorderClick(index, index - 1),
|
|
1751
|
-
uiSchema,
|
|
1752
|
-
registry
|
|
1753
|
-
}
|
|
1754
|
-
),
|
|
1755
|
-
(hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1756
|
-
MoveDownButton2,
|
|
1757
|
-
{
|
|
1758
|
-
style: btnStyle,
|
|
1759
|
-
disabled: disabled || readonly || !hasMoveDown,
|
|
1760
|
-
onClick: onReorderClick(index, index + 1),
|
|
1761
|
-
uiSchema,
|
|
1762
|
-
registry
|
|
1763
|
-
}
|
|
1764
|
-
),
|
|
1765
|
-
hasCopy && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1766
|
-
CopyButton2,
|
|
1767
|
-
{
|
|
1768
|
-
style: btnStyle,
|
|
1769
|
-
disabled: disabled || readonly,
|
|
1770
|
-
onClick: onCopyIndexClick(index),
|
|
1771
|
-
uiSchema,
|
|
1772
|
-
registry
|
|
1773
|
-
}
|
|
1774
|
-
),
|
|
1775
|
-
hasRemove && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1776
|
-
RemoveButton2,
|
|
1777
|
-
{
|
|
1778
|
-
style: btnStyle,
|
|
1779
|
-
disabled: disabled || readonly,
|
|
1780
|
-
onClick: onDropIndexClick(index),
|
|
1781
|
-
uiSchema,
|
|
1782
|
-
registry
|
|
1783
|
-
}
|
|
1784
|
-
)
|
|
1785
|
-
]
|
|
2422
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ArrayFieldItemButtonsTemplate2, { ...buttonsProps, style: btnStyle })
|
|
1786
2423
|
}
|
|
1787
2424
|
) })
|
|
1788
2425
|
] });
|
|
1789
2426
|
}
|
|
2427
|
+
function ArrayFieldItemButtonsTemplate(props) {
|
|
2428
|
+
const {
|
|
2429
|
+
disabled,
|
|
2430
|
+
hasCopy,
|
|
2431
|
+
hasMoveDown,
|
|
2432
|
+
hasMoveUp,
|
|
2433
|
+
hasRemove,
|
|
2434
|
+
idSchema,
|
|
2435
|
+
index,
|
|
2436
|
+
onCopyIndexClick,
|
|
2437
|
+
onDropIndexClick,
|
|
2438
|
+
onReorderClick,
|
|
2439
|
+
readonly,
|
|
2440
|
+
registry,
|
|
2441
|
+
uiSchema
|
|
2442
|
+
} = props;
|
|
2443
|
+
const { CopyButton: CopyButton2, MoveDownButton: MoveDownButton2, MoveUpButton: MoveUpButton2, RemoveButton: RemoveButton2 } = registry.templates.ButtonTemplates;
|
|
2444
|
+
const onCopyClick = react.useMemo(() => onCopyIndexClick(index), [index, onCopyIndexClick]);
|
|
2445
|
+
const onRemoveClick = react.useMemo(() => onDropIndexClick(index), [index, onDropIndexClick]);
|
|
2446
|
+
const onArrowUpClick = react.useMemo(() => onReorderClick(index, index - 1), [index, onReorderClick]);
|
|
2447
|
+
const onArrowDownClick = react.useMemo(() => onReorderClick(index, index + 1), [index, onReorderClick]);
|
|
2448
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2449
|
+
(hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2450
|
+
MoveUpButton2,
|
|
2451
|
+
{
|
|
2452
|
+
id: utils.buttonId(idSchema, "moveUp"),
|
|
2453
|
+
className: "rjsf-array-item-move-up",
|
|
2454
|
+
disabled: disabled || readonly || !hasMoveUp,
|
|
2455
|
+
onClick: onArrowUpClick,
|
|
2456
|
+
uiSchema,
|
|
2457
|
+
registry
|
|
2458
|
+
}
|
|
2459
|
+
),
|
|
2460
|
+
(hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2461
|
+
MoveDownButton2,
|
|
2462
|
+
{
|
|
2463
|
+
id: utils.buttonId(idSchema, "moveDown"),
|
|
2464
|
+
className: "rjsf-array-item-move-down",
|
|
2465
|
+
disabled: disabled || readonly || !hasMoveDown,
|
|
2466
|
+
onClick: onArrowDownClick,
|
|
2467
|
+
uiSchema,
|
|
2468
|
+
registry
|
|
2469
|
+
}
|
|
2470
|
+
),
|
|
2471
|
+
hasCopy && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2472
|
+
CopyButton2,
|
|
2473
|
+
{
|
|
2474
|
+
id: utils.buttonId(idSchema, "copy"),
|
|
2475
|
+
className: "rjsf-array-item-copy",
|
|
2476
|
+
disabled: disabled || readonly,
|
|
2477
|
+
onClick: onCopyClick,
|
|
2478
|
+
uiSchema,
|
|
2479
|
+
registry
|
|
2480
|
+
}
|
|
2481
|
+
),
|
|
2482
|
+
hasRemove && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2483
|
+
RemoveButton2,
|
|
2484
|
+
{
|
|
2485
|
+
id: utils.buttonId(idSchema, "remove"),
|
|
2486
|
+
className: "rjsf-array-item-remove",
|
|
2487
|
+
disabled: disabled || readonly,
|
|
2488
|
+
onClick: onRemoveClick,
|
|
2489
|
+
uiSchema,
|
|
2490
|
+
registry
|
|
2491
|
+
}
|
|
2492
|
+
)
|
|
2493
|
+
] });
|
|
2494
|
+
}
|
|
1790
2495
|
function ArrayFieldTemplate(props) {
|
|
1791
2496
|
const {
|
|
1792
2497
|
canAdd,
|
|
@@ -1847,7 +2552,8 @@
|
|
|
1847
2552
|
canAdd && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1848
2553
|
AddButton2,
|
|
1849
2554
|
{
|
|
1850
|
-
|
|
2555
|
+
id: utils.buttonId(idSchema, "add"),
|
|
2556
|
+
className: "rjsf-array-item-add",
|
|
1851
2557
|
onClick: onAddClick,
|
|
1852
2558
|
disabled: disabled || readonly,
|
|
1853
2559
|
uiSchema,
|
|
@@ -1971,58 +2677,25 @@
|
|
|
1971
2677
|
const {
|
|
1972
2678
|
registry: { translateString }
|
|
1973
2679
|
} = props;
|
|
1974
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
}
|
|
1982
|
-
);
|
|
1983
|
-
}
|
|
1984
|
-
function MoveDownButton(props) {
|
|
1985
|
-
const {
|
|
1986
|
-
registry: { translateString }
|
|
1987
|
-
} = props;
|
|
1988
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1989
|
-
IconButton,
|
|
1990
|
-
{
|
|
1991
|
-
title: translateString(utils.TranslatableString.MoveDownButton),
|
|
1992
|
-
className: "array-item-move-down",
|
|
1993
|
-
...props,
|
|
1994
|
-
icon: "arrow-down"
|
|
1995
|
-
}
|
|
1996
|
-
);
|
|
2680
|
+
return /* @__PURE__ */ jsxRuntime.jsx(IconButton, { title: translateString(utils.TranslatableString.CopyButton), ...props, icon: "copy" });
|
|
2681
|
+
}
|
|
2682
|
+
function MoveDownButton(props) {
|
|
2683
|
+
const {
|
|
2684
|
+
registry: { translateString }
|
|
2685
|
+
} = props;
|
|
2686
|
+
return /* @__PURE__ */ jsxRuntime.jsx(IconButton, { title: translateString(utils.TranslatableString.MoveDownButton), ...props, icon: "arrow-down" });
|
|
1997
2687
|
}
|
|
1998
2688
|
function MoveUpButton(props) {
|
|
1999
2689
|
const {
|
|
2000
2690
|
registry: { translateString }
|
|
2001
2691
|
} = props;
|
|
2002
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2003
|
-
IconButton,
|
|
2004
|
-
{
|
|
2005
|
-
title: translateString(utils.TranslatableString.MoveUpButton),
|
|
2006
|
-
className: "array-item-move-up",
|
|
2007
|
-
...props,
|
|
2008
|
-
icon: "arrow-up"
|
|
2009
|
-
}
|
|
2010
|
-
);
|
|
2692
|
+
return /* @__PURE__ */ jsxRuntime.jsx(IconButton, { title: translateString(utils.TranslatableString.MoveUpButton), ...props, icon: "arrow-up" });
|
|
2011
2693
|
}
|
|
2012
2694
|
function RemoveButton(props) {
|
|
2013
2695
|
const {
|
|
2014
2696
|
registry: { translateString }
|
|
2015
2697
|
} = props;
|
|
2016
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2017
|
-
IconButton,
|
|
2018
|
-
{
|
|
2019
|
-
title: translateString(utils.TranslatableString.RemoveButton),
|
|
2020
|
-
className: "array-item-remove",
|
|
2021
|
-
...props,
|
|
2022
|
-
iconType: "danger",
|
|
2023
|
-
icon: "remove"
|
|
2024
|
-
}
|
|
2025
|
-
);
|
|
2698
|
+
return /* @__PURE__ */ jsxRuntime.jsx(IconButton, { title: translateString(utils.TranslatableString.RemoveButton), ...props, iconType: "danger", icon: "remove" });
|
|
2026
2699
|
}
|
|
2027
2700
|
function AddButton({
|
|
2028
2701
|
className,
|
|
@@ -2057,16 +2730,22 @@
|
|
|
2057
2730
|
};
|
|
2058
2731
|
}
|
|
2059
2732
|
var ButtonTemplates_default = buttonTemplates;
|
|
2733
|
+
var TEST_IDS = utils.getTestIds();
|
|
2734
|
+
function RichDescription({ description, registry, uiSchema = {} }) {
|
|
2735
|
+
const { globalUiOptions } = registry;
|
|
2736
|
+
const uiOptions = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
2737
|
+
if (uiOptions.enableMarkdownInDescription && typeof description === "string") {
|
|
2738
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Markdown, { options: { disableParsingRawHTML: true }, "data-testid": TEST_IDS.markdown, children: description });
|
|
2739
|
+
}
|
|
2740
|
+
return description;
|
|
2741
|
+
}
|
|
2742
|
+
RichDescription.TEST_IDS = TEST_IDS;
|
|
2060
2743
|
function DescriptionField(props) {
|
|
2061
|
-
const { id, description } = props;
|
|
2744
|
+
const { id, description, registry, uiSchema } = props;
|
|
2062
2745
|
if (!description) {
|
|
2063
2746
|
return null;
|
|
2064
2747
|
}
|
|
2065
|
-
|
|
2066
|
-
return /* @__PURE__ */ jsxRuntime.jsx("p", { id, className: "field-description", children: description });
|
|
2067
|
-
} else {
|
|
2068
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { id, className: "field-description", children: description });
|
|
2069
|
-
}
|
|
2748
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { id, className: "field-description", children: /* @__PURE__ */ jsxRuntime.jsx(RichDescription, { description, registry, uiSchema }) });
|
|
2070
2749
|
}
|
|
2071
2750
|
function ErrorList({
|
|
2072
2751
|
errors,
|
|
@@ -2134,6 +2813,10 @@
|
|
|
2134
2813
|
}
|
|
2135
2814
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { id, className: "help-block", children: help });
|
|
2136
2815
|
}
|
|
2816
|
+
function GridTemplate(props) {
|
|
2817
|
+
const { children, column, className, ...rest } = props;
|
|
2818
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, ...rest, children });
|
|
2819
|
+
}
|
|
2137
2820
|
function ObjectFieldTemplate(props) {
|
|
2138
2821
|
const {
|
|
2139
2822
|
description,
|
|
@@ -2185,7 +2868,8 @@
|
|
|
2185
2868
|
utils.canExpand(schema, uiSchema, formData) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2186
2869
|
AddButton2,
|
|
2187
2870
|
{
|
|
2188
|
-
|
|
2871
|
+
id: utils.buttonId(idSchema, "add"),
|
|
2872
|
+
className: "rjsf-object-property-expand",
|
|
2189
2873
|
onClick: onAddClick(schema),
|
|
2190
2874
|
disabled: disabled || readonly,
|
|
2191
2875
|
uiSchema,
|
|
@@ -2233,6 +2917,8 @@
|
|
|
2233
2917
|
readonly,
|
|
2234
2918
|
required,
|
|
2235
2919
|
schema,
|
|
2920
|
+
hideError,
|
|
2921
|
+
rawErrors,
|
|
2236
2922
|
children,
|
|
2237
2923
|
uiSchema,
|
|
2238
2924
|
registry
|
|
@@ -2241,10 +2927,15 @@
|
|
|
2241
2927
|
const { RemoveButton: RemoveButton2 } = templates2.ButtonTemplates;
|
|
2242
2928
|
const keyLabel = translateString(utils.TranslatableString.KeyLabel, [label]);
|
|
2243
2929
|
const additional = utils.ADDITIONAL_PROPERTY_FLAG in schema;
|
|
2930
|
+
const classNamesList = ["form-group", classNames];
|
|
2931
|
+
if (!hideError && rawErrors && rawErrors.length > 0) {
|
|
2932
|
+
classNamesList.push("has-error has-danger");
|
|
2933
|
+
}
|
|
2934
|
+
const uiClassNames = classNamesList.join(" ").trim();
|
|
2244
2935
|
if (!additional) {
|
|
2245
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
2936
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: uiClassNames, style, children });
|
|
2246
2937
|
}
|
|
2247
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
2938
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: uiClassNames, style, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "row", children: [
|
|
2248
2939
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-5 form-additional", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "form-group", children: [
|
|
2249
2940
|
/* @__PURE__ */ jsxRuntime.jsx(Label, { label: keyLabel, required, id: `${id}-key` }),
|
|
2250
2941
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2262,7 +2953,8 @@
|
|
|
2262
2953
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2263
2954
|
RemoveButton2,
|
|
2264
2955
|
{
|
|
2265
|
-
|
|
2956
|
+
id: utils.buttonId(id, "remove"),
|
|
2957
|
+
className: "rjsf-object-property-remove btn-block",
|
|
2266
2958
|
style: { border: "0" },
|
|
2267
2959
|
disabled: disabled || readonly,
|
|
2268
2960
|
onClick: onDropPropertyClick(label),
|
|
@@ -2278,6 +2970,7 @@
|
|
|
2278
2970
|
return {
|
|
2279
2971
|
ArrayFieldDescriptionTemplate,
|
|
2280
2972
|
ArrayFieldItemTemplate,
|
|
2973
|
+
ArrayFieldItemButtonsTemplate,
|
|
2281
2974
|
ArrayFieldTemplate,
|
|
2282
2975
|
ArrayFieldTitleTemplate,
|
|
2283
2976
|
ButtonTemplates: ButtonTemplates_default(),
|
|
@@ -2287,6 +2980,7 @@
|
|
|
2287
2980
|
FieldTemplate: FieldTemplate_default,
|
|
2288
2981
|
FieldErrorTemplate,
|
|
2289
2982
|
FieldHelpTemplate,
|
|
2983
|
+
GridTemplate,
|
|
2290
2984
|
ObjectFieldTemplate,
|
|
2291
2985
|
TitleFieldTemplate: TitleField,
|
|
2292
2986
|
UnsupportedFieldTemplate: UnsupportedField_default,
|
|
@@ -2351,9 +3045,12 @@
|
|
|
2351
3045
|
}) {
|
|
2352
3046
|
const { translateString } = registry;
|
|
2353
3047
|
const [lastValue, setLastValue] = react.useState(value);
|
|
2354
|
-
const [state, setState] = react.useReducer(
|
|
2355
|
-
|
|
2356
|
-
|
|
3048
|
+
const [state, setState] = react.useReducer(
|
|
3049
|
+
(state2, action) => {
|
|
3050
|
+
return { ...state2, ...action };
|
|
3051
|
+
},
|
|
3052
|
+
utils.parseDateString(value, time)
|
|
3053
|
+
);
|
|
2357
3054
|
react.useEffect(() => {
|
|
2358
3055
|
const stateValue = utils.toDateString(state, time);
|
|
2359
3056
|
if (readyForChange(state) && stateValue !== value) {
|
|
@@ -2457,7 +3154,7 @@
|
|
|
2457
3154
|
);
|
|
2458
3155
|
const description = options.description ?? schema.description;
|
|
2459
3156
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `checkbox ${disabled || readonly ? "disabled" : ""}`, children: [
|
|
2460
|
-
!hideLabel &&
|
|
3157
|
+
!hideLabel && description && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2461
3158
|
DescriptionFieldTemplate,
|
|
2462
3159
|
{
|
|
2463
3160
|
id: utils.descriptionId(id),
|
|
@@ -2661,7 +3358,7 @@
|
|
|
2661
3358
|
type: blob.type
|
|
2662
3359
|
}
|
|
2663
3360
|
];
|
|
2664
|
-
} catch
|
|
3361
|
+
} catch {
|
|
2665
3362
|
return acc;
|
|
2666
3363
|
}
|
|
2667
3364
|
}, []);
|
|
@@ -2677,7 +3374,7 @@
|
|
|
2677
3374
|
processFiles(event.target.files).then((filesInfoEvent) => {
|
|
2678
3375
|
const newValue = filesInfoEvent.map((fileInfo) => fileInfo.dataURL);
|
|
2679
3376
|
if (multiple) {
|
|
2680
|
-
onChange(value.concat(newValue
|
|
3377
|
+
onChange(value.concat(newValue));
|
|
2681
3378
|
} else {
|
|
2682
3379
|
onChange(newValue[0]);
|
|
2683
3380
|
}
|
|
@@ -2750,13 +3447,13 @@
|
|
|
2750
3447
|
const { enumOptions, enumDisabled, inline, emptyValue } = options;
|
|
2751
3448
|
const handleBlur = react.useCallback(
|
|
2752
3449
|
({ target }) => onBlur(id, utils.enumOptionsValueForIndex(target && target.value, enumOptions, emptyValue)),
|
|
2753
|
-
[onBlur, id]
|
|
3450
|
+
[onBlur, enumOptions, emptyValue, id]
|
|
2754
3451
|
);
|
|
2755
3452
|
const handleFocus = react.useCallback(
|
|
2756
3453
|
({ target }) => onFocus(id, utils.enumOptionsValueForIndex(target && target.value, enumOptions, emptyValue)),
|
|
2757
|
-
[onFocus, id]
|
|
3454
|
+
[onFocus, enumOptions, emptyValue, id]
|
|
2758
3455
|
);
|
|
2759
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "field-radio-group", id, children: Array.isArray(enumOptions) && enumOptions.map((option, i) => {
|
|
3456
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "field-radio-group", id, role: "radiogroup", children: Array.isArray(enumOptions) && enumOptions.map((option, i) => {
|
|
2760
3457
|
const checked = utils.enumOptionsIsSelected(option.value, value);
|
|
2761
3458
|
const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1;
|
|
2762
3459
|
const disabledCls = disabled || itemDisabled || readonly ? "disabled" : "";
|
|
@@ -2797,6 +3494,105 @@
|
|
|
2797
3494
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "range-view", children: value })
|
|
2798
3495
|
] });
|
|
2799
3496
|
}
|
|
3497
|
+
function RatingWidget({
|
|
3498
|
+
id,
|
|
3499
|
+
value,
|
|
3500
|
+
required,
|
|
3501
|
+
disabled,
|
|
3502
|
+
readonly,
|
|
3503
|
+
autofocus,
|
|
3504
|
+
onChange,
|
|
3505
|
+
onFocus,
|
|
3506
|
+
onBlur,
|
|
3507
|
+
schema,
|
|
3508
|
+
options
|
|
3509
|
+
}) {
|
|
3510
|
+
const { stars = 5, shape = "star" } = options;
|
|
3511
|
+
const numStars = schema.maximum ? Math.min(schema.maximum, 5) : Math.min(Math.max(stars, 1), 5);
|
|
3512
|
+
const min = schema.minimum || 0;
|
|
3513
|
+
const handleStarClick = react.useCallback(
|
|
3514
|
+
(starValue) => {
|
|
3515
|
+
if (!disabled && !readonly) {
|
|
3516
|
+
onChange(starValue);
|
|
3517
|
+
}
|
|
3518
|
+
},
|
|
3519
|
+
[onChange, disabled, readonly]
|
|
3520
|
+
);
|
|
3521
|
+
const handleFocus = react.useCallback(
|
|
3522
|
+
(event) => {
|
|
3523
|
+
if (onFocus) {
|
|
3524
|
+
const starValue = Number(event.target.dataset.value);
|
|
3525
|
+
onFocus(id, starValue);
|
|
3526
|
+
}
|
|
3527
|
+
},
|
|
3528
|
+
[onFocus, id]
|
|
3529
|
+
);
|
|
3530
|
+
const handleBlur = react.useCallback(
|
|
3531
|
+
(event) => {
|
|
3532
|
+
if (onBlur) {
|
|
3533
|
+
const starValue = Number(event.target.dataset.value);
|
|
3534
|
+
onBlur(id, starValue);
|
|
3535
|
+
}
|
|
3536
|
+
},
|
|
3537
|
+
[onBlur, id]
|
|
3538
|
+
);
|
|
3539
|
+
const getSymbol = (isFilled) => {
|
|
3540
|
+
if (shape === "heart") {
|
|
3541
|
+
return isFilled ? "\u2665" : "\u2661";
|
|
3542
|
+
}
|
|
3543
|
+
return isFilled ? "\u2605" : "\u2606";
|
|
3544
|
+
};
|
|
3545
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3546
|
+
"div",
|
|
3547
|
+
{
|
|
3548
|
+
className: "rating-widget",
|
|
3549
|
+
style: {
|
|
3550
|
+
display: "inline-flex",
|
|
3551
|
+
fontSize: "1.5rem",
|
|
3552
|
+
cursor: disabled || readonly ? "default" : "pointer"
|
|
3553
|
+
},
|
|
3554
|
+
children: [
|
|
3555
|
+
[...Array(numStars)].map((_, index) => {
|
|
3556
|
+
const starValue = min + index;
|
|
3557
|
+
const isFilled = starValue <= value;
|
|
3558
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3559
|
+
"span",
|
|
3560
|
+
{
|
|
3561
|
+
onClick: () => handleStarClick(starValue),
|
|
3562
|
+
onFocus: handleFocus,
|
|
3563
|
+
onBlur: handleBlur,
|
|
3564
|
+
"data-value": starValue,
|
|
3565
|
+
tabIndex: disabled || readonly ? -1 : 0,
|
|
3566
|
+
role: "radio",
|
|
3567
|
+
"aria-checked": starValue === value,
|
|
3568
|
+
"aria-label": `${starValue} ${shape === "heart" ? "heart" : "star"}${starValue === 1 ? "" : "s"}`,
|
|
3569
|
+
style: {
|
|
3570
|
+
color: isFilled ? "#FFD700" : "#ccc",
|
|
3571
|
+
padding: "0 0.2rem",
|
|
3572
|
+
transition: "color 0.2s",
|
|
3573
|
+
userSelect: "none"
|
|
3574
|
+
},
|
|
3575
|
+
children: getSymbol(isFilled)
|
|
3576
|
+
},
|
|
3577
|
+
index
|
|
3578
|
+
);
|
|
3579
|
+
}),
|
|
3580
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3581
|
+
"input",
|
|
3582
|
+
{
|
|
3583
|
+
type: "hidden",
|
|
3584
|
+
id,
|
|
3585
|
+
name: id,
|
|
3586
|
+
value: value || "",
|
|
3587
|
+
required,
|
|
3588
|
+
disabled: disabled || readonly,
|
|
3589
|
+
"aria-hidden": "true"
|
|
3590
|
+
}
|
|
3591
|
+
)
|
|
3592
|
+
]
|
|
3593
|
+
}
|
|
3594
|
+
) });
|
|
3595
|
+
}
|
|
2800
3596
|
function getValue(event, multiple) {
|
|
2801
3597
|
if (multiple) {
|
|
2802
3598
|
return Array.from(event.target.options).slice().filter((o) => o.selected).map((o) => o.value);
|
|
@@ -2825,21 +3621,21 @@
|
|
|
2825
3621
|
const newValue = getValue(event, multiple);
|
|
2826
3622
|
return onFocus(id, utils.enumOptionsValueForIndex(newValue, enumOptions, optEmptyVal));
|
|
2827
3623
|
},
|
|
2828
|
-
[onFocus, id,
|
|
3624
|
+
[onFocus, id, multiple, enumOptions, optEmptyVal]
|
|
2829
3625
|
);
|
|
2830
3626
|
const handleBlur = react.useCallback(
|
|
2831
3627
|
(event) => {
|
|
2832
3628
|
const newValue = getValue(event, multiple);
|
|
2833
3629
|
return onBlur(id, utils.enumOptionsValueForIndex(newValue, enumOptions, optEmptyVal));
|
|
2834
3630
|
},
|
|
2835
|
-
[onBlur, id,
|
|
3631
|
+
[onBlur, id, multiple, enumOptions, optEmptyVal]
|
|
2836
3632
|
);
|
|
2837
3633
|
const handleChange = react.useCallback(
|
|
2838
3634
|
(event) => {
|
|
2839
3635
|
const newValue = getValue(event, multiple);
|
|
2840
3636
|
return onChange(utils.enumOptionsValueForIndex(newValue, enumOptions, optEmptyVal));
|
|
2841
3637
|
},
|
|
2842
|
-
[onChange,
|
|
3638
|
+
[onChange, multiple, enumOptions, optEmptyVal]
|
|
2843
3639
|
);
|
|
2844
3640
|
const selectedIndexes = utils.enumOptionsIndexForValue(value, enumOptions, multiple);
|
|
2845
3641
|
const showPlaceholderOption = !multiple && schema.default === void 0;
|
|
@@ -2849,6 +3645,7 @@
|
|
|
2849
3645
|
id,
|
|
2850
3646
|
name: id,
|
|
2851
3647
|
multiple,
|
|
3648
|
+
role: "combobox",
|
|
2852
3649
|
className: "form-control",
|
|
2853
3650
|
value: typeof selectedIndexes === "undefined" ? emptyValue : selectedIndexes,
|
|
2854
3651
|
required,
|
|
@@ -2957,6 +3754,7 @@
|
|
|
2957
3754
|
PasswordWidget,
|
|
2958
3755
|
RadioWidget: RadioWidget_default,
|
|
2959
3756
|
RangeWidget,
|
|
3757
|
+
RatingWidget,
|
|
2960
3758
|
SelectWidget: SelectWidget_default,
|
|
2961
3759
|
TextWidget,
|
|
2962
3760
|
TextareaWidget: TextareaWidget_default,
|
|
@@ -2979,6 +3777,10 @@
|
|
|
2979
3777
|
};
|
|
2980
3778
|
}
|
|
2981
3779
|
var Form = class extends react.Component {
|
|
3780
|
+
/** The ref used to hold the `form` element, this needs to be `any` because `tagName` or `_internalFormWrapper` can
|
|
3781
|
+
* provide any possible type here
|
|
3782
|
+
*/
|
|
3783
|
+
formElement;
|
|
2982
3784
|
/** Constructs the `Form` from the `props`. Will setup the initial state from the props. It will also call the
|
|
2983
3785
|
* `onChange` handler if the initially provided `formData` is modified to add missing default values as part of the
|
|
2984
3786
|
* state construction.
|
|
@@ -2987,266 +3789,6 @@
|
|
|
2987
3789
|
*/
|
|
2988
3790
|
constructor(props) {
|
|
2989
3791
|
super(props);
|
|
2990
|
-
/** Returns the `formData` with only the elements specified in the `fields` list
|
|
2991
|
-
*
|
|
2992
|
-
* @param formData - The data for the `Form`
|
|
2993
|
-
* @param fields - The fields to keep while filtering
|
|
2994
|
-
*/
|
|
2995
|
-
this.getUsedFormData = (formData, fields2) => {
|
|
2996
|
-
if (fields2.length === 0 && typeof formData !== "object") {
|
|
2997
|
-
return formData;
|
|
2998
|
-
}
|
|
2999
|
-
const data = _pick(formData, fields2);
|
|
3000
|
-
if (Array.isArray(formData)) {
|
|
3001
|
-
return Object.keys(data).map((key) => data[key]);
|
|
3002
|
-
}
|
|
3003
|
-
return data;
|
|
3004
|
-
};
|
|
3005
|
-
/** Returns the list of field names from inspecting the `pathSchema` as well as using the `formData`
|
|
3006
|
-
*
|
|
3007
|
-
* @param pathSchema - The `PathSchema` object for the form
|
|
3008
|
-
* @param [formData] - The form data to use while checking for empty objects/arrays
|
|
3009
|
-
*/
|
|
3010
|
-
this.getFieldNames = (pathSchema, formData) => {
|
|
3011
|
-
const getAllPaths = (_obj, acc = [], paths = [[]]) => {
|
|
3012
|
-
Object.keys(_obj).forEach((key) => {
|
|
3013
|
-
if (typeof _obj[key] === "object") {
|
|
3014
|
-
const newPaths = paths.map((path) => [...path, key]);
|
|
3015
|
-
if (_obj[key][utils.RJSF_ADDITIONAL_PROPERTIES_FLAG] && _obj[key][utils.NAME_KEY] !== "") {
|
|
3016
|
-
acc.push(_obj[key][utils.NAME_KEY]);
|
|
3017
|
-
} else {
|
|
3018
|
-
getAllPaths(_obj[key], acc, newPaths);
|
|
3019
|
-
}
|
|
3020
|
-
} else if (key === utils.NAME_KEY && _obj[key] !== "") {
|
|
3021
|
-
paths.forEach((path) => {
|
|
3022
|
-
const formValue = get3(formData, path);
|
|
3023
|
-
if (typeof formValue !== "object" || isEmpty(formValue) || Array.isArray(formValue) && formValue.every((val) => typeof val !== "object")) {
|
|
3024
|
-
acc.push(path);
|
|
3025
|
-
}
|
|
3026
|
-
});
|
|
3027
|
-
}
|
|
3028
|
-
});
|
|
3029
|
-
return acc;
|
|
3030
|
-
};
|
|
3031
|
-
return getAllPaths(pathSchema);
|
|
3032
|
-
};
|
|
3033
|
-
/** Returns the `formData` after filtering to remove any extra data not in a form field
|
|
3034
|
-
*
|
|
3035
|
-
* @param formData - The data for the `Form`
|
|
3036
|
-
* @returns The `formData` after omitting extra data
|
|
3037
|
-
*/
|
|
3038
|
-
this.omitExtraData = (formData) => {
|
|
3039
|
-
const { schema, schemaUtils } = this.state;
|
|
3040
|
-
const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
|
|
3041
|
-
const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", formData);
|
|
3042
|
-
const fieldNames = this.getFieldNames(pathSchema, formData);
|
|
3043
|
-
const newFormData = this.getUsedFormData(formData, fieldNames);
|
|
3044
|
-
return newFormData;
|
|
3045
|
-
};
|
|
3046
|
-
/** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
|
|
3047
|
-
* `formData` along with a new `ErrorSchema`. It will first update the `formData` with any missing default fields and
|
|
3048
|
-
* then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not
|
|
3049
|
-
* in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
|
|
3050
|
-
* updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
|
|
3051
|
-
* callback will be called if specified with the updated state.
|
|
3052
|
-
*
|
|
3053
|
-
* @param formData - The new form data from a change to a field
|
|
3054
|
-
* @param newErrorSchema - The new `ErrorSchema` based on the field change
|
|
3055
|
-
* @param id - The id of the field that caused the change
|
|
3056
|
-
*/
|
|
3057
|
-
this.onChange = (formData, newErrorSchema, id) => {
|
|
3058
|
-
const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange } = this.props;
|
|
3059
|
-
const { schemaUtils, schema, retrievedSchema } = this.state;
|
|
3060
|
-
if (utils.isObject(formData) || Array.isArray(formData)) {
|
|
3061
|
-
const newState = this.getStateFromProps(this.props, formData, retrievedSchema);
|
|
3062
|
-
formData = newState.formData;
|
|
3063
|
-
}
|
|
3064
|
-
const mustValidate = !noValidate && liveValidate;
|
|
3065
|
-
let state = { formData, schema };
|
|
3066
|
-
let newFormData = formData;
|
|
3067
|
-
if (omitExtraData === true && liveOmit === true) {
|
|
3068
|
-
newFormData = this.omitExtraData(formData);
|
|
3069
|
-
state = {
|
|
3070
|
-
formData: newFormData
|
|
3071
|
-
};
|
|
3072
|
-
}
|
|
3073
|
-
if (mustValidate) {
|
|
3074
|
-
const schemaValidation = this.validate(newFormData, schema, schemaUtils, retrievedSchema);
|
|
3075
|
-
let errors = schemaValidation.errors;
|
|
3076
|
-
let errorSchema = schemaValidation.errorSchema;
|
|
3077
|
-
const schemaValidationErrors = errors;
|
|
3078
|
-
const schemaValidationErrorSchema = errorSchema;
|
|
3079
|
-
if (extraErrors) {
|
|
3080
|
-
const merged = utils.validationDataMerge(schemaValidation, extraErrors);
|
|
3081
|
-
errorSchema = merged.errorSchema;
|
|
3082
|
-
errors = merged.errors;
|
|
3083
|
-
}
|
|
3084
|
-
if (newErrorSchema) {
|
|
3085
|
-
const filteredErrors = this.filterErrorsBasedOnSchema(newErrorSchema, retrievedSchema, newFormData);
|
|
3086
|
-
errorSchema = utils.mergeObjects(errorSchema, filteredErrors, "preventDuplicates");
|
|
3087
|
-
}
|
|
3088
|
-
state = {
|
|
3089
|
-
formData: newFormData,
|
|
3090
|
-
errors,
|
|
3091
|
-
errorSchema,
|
|
3092
|
-
schemaValidationErrors,
|
|
3093
|
-
schemaValidationErrorSchema
|
|
3094
|
-
};
|
|
3095
|
-
} else if (!noValidate && newErrorSchema) {
|
|
3096
|
-
const errorSchema = extraErrors ? utils.mergeObjects(newErrorSchema, extraErrors, "preventDuplicates") : newErrorSchema;
|
|
3097
|
-
state = {
|
|
3098
|
-
formData: newFormData,
|
|
3099
|
-
errorSchema,
|
|
3100
|
-
errors: utils.toErrorList(errorSchema)
|
|
3101
|
-
};
|
|
3102
|
-
}
|
|
3103
|
-
this.setState(state, () => onChange && onChange({ ...this.state, ...state }, id));
|
|
3104
|
-
};
|
|
3105
|
-
/**
|
|
3106
|
-
* Callback function to handle reset form data.
|
|
3107
|
-
* - Reset all fields with default values.
|
|
3108
|
-
* - Reset validations and errors
|
|
3109
|
-
*
|
|
3110
|
-
*/
|
|
3111
|
-
this.reset = () => {
|
|
3112
|
-
const { onChange } = this.props;
|
|
3113
|
-
const newState = this.getStateFromProps(this.props, void 0);
|
|
3114
|
-
const newFormData = newState.formData;
|
|
3115
|
-
const state = {
|
|
3116
|
-
formData: newFormData,
|
|
3117
|
-
errorSchema: {},
|
|
3118
|
-
errors: [],
|
|
3119
|
-
schemaValidationErrors: [],
|
|
3120
|
-
schemaValidationErrorSchema: {}
|
|
3121
|
-
};
|
|
3122
|
-
this.setState(state, () => onChange && onChange({ ...this.state, ...state }));
|
|
3123
|
-
};
|
|
3124
|
-
/** Callback function to handle when a field on the form is blurred. Calls the `onBlur` callback for the `Form` if it
|
|
3125
|
-
* was provided.
|
|
3126
|
-
*
|
|
3127
|
-
* @param id - The unique `id` of the field that was blurred
|
|
3128
|
-
* @param data - The data associated with the field that was blurred
|
|
3129
|
-
*/
|
|
3130
|
-
this.onBlur = (id, data) => {
|
|
3131
|
-
const { onBlur } = this.props;
|
|
3132
|
-
if (onBlur) {
|
|
3133
|
-
onBlur(id, data);
|
|
3134
|
-
}
|
|
3135
|
-
};
|
|
3136
|
-
/** Callback function to handle when a field on the form is focused. Calls the `onFocus` callback for the `Form` if it
|
|
3137
|
-
* was provided.
|
|
3138
|
-
*
|
|
3139
|
-
* @param id - The unique `id` of the field that was focused
|
|
3140
|
-
* @param data - The data associated with the field that was focused
|
|
3141
|
-
*/
|
|
3142
|
-
this.onFocus = (id, data) => {
|
|
3143
|
-
const { onFocus } = this.props;
|
|
3144
|
-
if (onFocus) {
|
|
3145
|
-
onFocus(id, data);
|
|
3146
|
-
}
|
|
3147
|
-
};
|
|
3148
|
-
/** Callback function to handle when the form is submitted. First, it prevents the default event behavior. Nothing
|
|
3149
|
-
* happens if the target and currentTarget of the event are not the same. It will omit any extra data in the
|
|
3150
|
-
* `formData` in the state if `omitExtraData` is true. It will validate the resulting `formData`, reporting errors
|
|
3151
|
-
* via the `onError()` callback unless validation is disabled. Finally, it will add in any `extraErrors` and then call
|
|
3152
|
-
* back the `onSubmit` callback if it was provided.
|
|
3153
|
-
*
|
|
3154
|
-
* @param event - The submit HTML form event
|
|
3155
|
-
*/
|
|
3156
|
-
this.onSubmit = (event) => {
|
|
3157
|
-
event.preventDefault();
|
|
3158
|
-
if (event.target !== event.currentTarget) {
|
|
3159
|
-
return;
|
|
3160
|
-
}
|
|
3161
|
-
event.persist();
|
|
3162
|
-
const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
|
|
3163
|
-
let { formData: newFormData } = this.state;
|
|
3164
|
-
if (omitExtraData === true) {
|
|
3165
|
-
newFormData = this.omitExtraData(newFormData);
|
|
3166
|
-
}
|
|
3167
|
-
if (noValidate || this.validateFormWithFormData(newFormData)) {
|
|
3168
|
-
const errorSchema = extraErrors || {};
|
|
3169
|
-
const errors = extraErrors ? utils.toErrorList(extraErrors) : [];
|
|
3170
|
-
this.setState(
|
|
3171
|
-
{
|
|
3172
|
-
formData: newFormData,
|
|
3173
|
-
errors,
|
|
3174
|
-
errorSchema,
|
|
3175
|
-
schemaValidationErrors: [],
|
|
3176
|
-
schemaValidationErrorSchema: {}
|
|
3177
|
-
},
|
|
3178
|
-
() => {
|
|
3179
|
-
if (onSubmit) {
|
|
3180
|
-
onSubmit({ ...this.state, formData: newFormData, status: "submitted" }, event);
|
|
3181
|
-
}
|
|
3182
|
-
}
|
|
3183
|
-
);
|
|
3184
|
-
}
|
|
3185
|
-
};
|
|
3186
|
-
/** Provides a function that can be used to programmatically submit the `Form` */
|
|
3187
|
-
this.submit = () => {
|
|
3188
|
-
if (this.formElement.current) {
|
|
3189
|
-
const submitCustomEvent = new CustomEvent("submit", {
|
|
3190
|
-
cancelable: true
|
|
3191
|
-
});
|
|
3192
|
-
submitCustomEvent.preventDefault();
|
|
3193
|
-
this.formElement.current.dispatchEvent(submitCustomEvent);
|
|
3194
|
-
this.formElement.current.requestSubmit();
|
|
3195
|
-
}
|
|
3196
|
-
};
|
|
3197
|
-
/** Validates the form using the given `formData`. For use on form submission or on programmatic validation.
|
|
3198
|
-
* If `onError` is provided, then it will be called with the list of errors.
|
|
3199
|
-
*
|
|
3200
|
-
* @param formData - The form data to validate
|
|
3201
|
-
* @returns - True if the form is valid, false otherwise.
|
|
3202
|
-
*/
|
|
3203
|
-
this.validateFormWithFormData = (formData) => {
|
|
3204
|
-
const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
|
|
3205
|
-
const { errors: prevErrors } = this.state;
|
|
3206
|
-
const schemaValidation = this.validate(formData);
|
|
3207
|
-
let errors = schemaValidation.errors;
|
|
3208
|
-
let errorSchema = schemaValidation.errorSchema;
|
|
3209
|
-
const schemaValidationErrors = errors;
|
|
3210
|
-
const schemaValidationErrorSchema = errorSchema;
|
|
3211
|
-
const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
|
|
3212
|
-
if (hasError) {
|
|
3213
|
-
if (extraErrors) {
|
|
3214
|
-
const merged = utils.validationDataMerge(schemaValidation, extraErrors);
|
|
3215
|
-
errorSchema = merged.errorSchema;
|
|
3216
|
-
errors = merged.errors;
|
|
3217
|
-
}
|
|
3218
|
-
if (focusOnFirstError) {
|
|
3219
|
-
if (typeof focusOnFirstError === "function") {
|
|
3220
|
-
focusOnFirstError(errors[0]);
|
|
3221
|
-
} else {
|
|
3222
|
-
this.focusOnError(errors[0]);
|
|
3223
|
-
}
|
|
3224
|
-
}
|
|
3225
|
-
this.setState(
|
|
3226
|
-
{
|
|
3227
|
-
errors,
|
|
3228
|
-
errorSchema,
|
|
3229
|
-
schemaValidationErrors,
|
|
3230
|
-
schemaValidationErrorSchema
|
|
3231
|
-
},
|
|
3232
|
-
() => {
|
|
3233
|
-
if (onError) {
|
|
3234
|
-
onError(errors);
|
|
3235
|
-
} else {
|
|
3236
|
-
console.error("Form validation failed", errors);
|
|
3237
|
-
}
|
|
3238
|
-
}
|
|
3239
|
-
);
|
|
3240
|
-
} else if (prevErrors.length > 0) {
|
|
3241
|
-
this.setState({
|
|
3242
|
-
errors: [],
|
|
3243
|
-
errorSchema: {},
|
|
3244
|
-
schemaValidationErrors: [],
|
|
3245
|
-
schemaValidationErrorSchema: {}
|
|
3246
|
-
});
|
|
3247
|
-
}
|
|
3248
|
-
return !hasError;
|
|
3249
|
-
};
|
|
3250
3792
|
if (!props.validator) {
|
|
3251
3793
|
throw new Error("A validator is required for Form functionality to work");
|
|
3252
3794
|
}
|
|
@@ -3276,8 +3818,9 @@
|
|
|
3276
3818
|
*/
|
|
3277
3819
|
getSnapshotBeforeUpdate(prevProps, prevState) {
|
|
3278
3820
|
if (!utils.deepEquals(this.props, prevProps)) {
|
|
3821
|
+
const formDataChangedFields = utils.getChangedFields(this.props.formData, prevProps.formData);
|
|
3279
3822
|
const isSchemaChanged = !utils.deepEquals(prevProps.schema, this.props.schema);
|
|
3280
|
-
const isFormDataChanged = !utils.deepEquals(prevProps.formData, this.props.formData);
|
|
3823
|
+
const isFormDataChanged = formDataChangedFields.length > 0 || !utils.deepEquals(prevProps.formData, this.props.formData);
|
|
3281
3824
|
const nextState = this.getStateFromProps(
|
|
3282
3825
|
this.props,
|
|
3283
3826
|
this.props.formData,
|
|
@@ -3285,7 +3828,8 @@
|
|
|
3285
3828
|
// Or if the `formData` changes, for example in the case of a schema with dependencies that need to
|
|
3286
3829
|
// match one of the subSchemas, the retrieved schema must be updated.
|
|
3287
3830
|
isSchemaChanged || isFormDataChanged ? void 0 : this.state.retrievedSchema,
|
|
3288
|
-
isSchemaChanged
|
|
3831
|
+
isSchemaChanged,
|
|
3832
|
+
formDataChangedFields
|
|
3289
3833
|
);
|
|
3290
3834
|
const shouldUpdate = !utils.deepEquals(nextState, prevState);
|
|
3291
3835
|
return { nextState, shouldUpdate };
|
|
@@ -3300,9 +3844,6 @@
|
|
|
3300
3844
|
* If an update is required, it applies the next state and, if needed, triggers the `onChange` handler to inform about
|
|
3301
3845
|
* changes.
|
|
3302
3846
|
*
|
|
3303
|
-
* This method effectively replaces the deprecated `UNSAFE_componentWillReceiveProps`, providing a safer alternative
|
|
3304
|
-
* to handle prop changes and state updates.
|
|
3305
|
-
*
|
|
3306
3847
|
* @param _ - The previous set of props.
|
|
3307
3848
|
* @param prevState - The previous state of the component before the update.
|
|
3308
3849
|
* @param snapshot - The value returned from `getSnapshotBeforeUpdate`.
|
|
@@ -3324,9 +3865,10 @@
|
|
|
3324
3865
|
* @param inputFormData - The new or current data for the `Form`
|
|
3325
3866
|
* @param retrievedSchema - An expanded schema, if not provided, it will be retrieved from the `schema` and `formData`.
|
|
3326
3867
|
* @param isSchemaChanged - A flag indicating whether the schema has changed.
|
|
3868
|
+
* @param formDataChangedFields - The changed fields of `formData`
|
|
3327
3869
|
* @returns - The new state for the `Form`
|
|
3328
3870
|
*/
|
|
3329
|
-
getStateFromProps(props, inputFormData, retrievedSchema, isSchemaChanged = false) {
|
|
3871
|
+
getStateFromProps(props, inputFormData, retrievedSchema, isSchemaChanged = false, formDataChangedFields = []) {
|
|
3330
3872
|
const state = this.state || {};
|
|
3331
3873
|
const schema = "schema" in props ? props.schema : this.props.schema;
|
|
3332
3874
|
const uiSchema = ("uiSchema" in props ? props.uiSchema : this.props.uiSchema) || {};
|
|
@@ -3335,12 +3877,25 @@
|
|
|
3335
3877
|
const mustValidate = edit && !props.noValidate && liveValidate;
|
|
3336
3878
|
const rootSchema = schema;
|
|
3337
3879
|
const experimental_defaultFormStateBehavior = "experimental_defaultFormStateBehavior" in props ? props.experimental_defaultFormStateBehavior : this.props.experimental_defaultFormStateBehavior;
|
|
3880
|
+
const experimental_customMergeAllOf = "experimental_customMergeAllOf" in props ? props.experimental_customMergeAllOf : this.props.experimental_customMergeAllOf;
|
|
3338
3881
|
let schemaUtils = state.schemaUtils;
|
|
3339
|
-
if (!schemaUtils || schemaUtils.doesSchemaUtilsDiffer(
|
|
3340
|
-
|
|
3882
|
+
if (!schemaUtils || schemaUtils.doesSchemaUtilsDiffer(
|
|
3883
|
+
props.validator,
|
|
3884
|
+
rootSchema,
|
|
3885
|
+
experimental_defaultFormStateBehavior,
|
|
3886
|
+
experimental_customMergeAllOf
|
|
3887
|
+
)) {
|
|
3888
|
+
schemaUtils = utils.createSchemaUtils(
|
|
3889
|
+
props.validator,
|
|
3890
|
+
rootSchema,
|
|
3891
|
+
experimental_defaultFormStateBehavior,
|
|
3892
|
+
experimental_customMergeAllOf
|
|
3893
|
+
);
|
|
3341
3894
|
}
|
|
3342
3895
|
const formData = schemaUtils.getDefaultFormState(schema, inputFormData);
|
|
3343
|
-
const _retrievedSchema =
|
|
3896
|
+
const _retrievedSchema = this.updateRetrievedSchema(
|
|
3897
|
+
retrievedSchema ?? schemaUtils.retrieveSchema(schema, formData)
|
|
3898
|
+
);
|
|
3344
3899
|
const getCurrentErrors = () => {
|
|
3345
3900
|
if (props.noValidate || isSchemaChanged) {
|
|
3346
3901
|
return { errors: [], errorSchema: {} };
|
|
@@ -3362,7 +3917,7 @@
|
|
|
3362
3917
|
if (mustValidate) {
|
|
3363
3918
|
const schemaValidation = this.validate(formData, schema, schemaUtils, _retrievedSchema);
|
|
3364
3919
|
errors = schemaValidation.errors;
|
|
3365
|
-
if (
|
|
3920
|
+
if (retrievedSchema === void 0) {
|
|
3366
3921
|
errorSchema = schemaValidation.errorSchema;
|
|
3367
3922
|
} else {
|
|
3368
3923
|
errorSchema = utils.mergeObjects(
|
|
@@ -3377,6 +3932,20 @@
|
|
|
3377
3932
|
const currentErrors = getCurrentErrors();
|
|
3378
3933
|
errors = currentErrors.errors;
|
|
3379
3934
|
errorSchema = currentErrors.errorSchema;
|
|
3935
|
+
if (formDataChangedFields.length > 0) {
|
|
3936
|
+
const newErrorSchema = formDataChangedFields.reduce(
|
|
3937
|
+
(acc, key) => {
|
|
3938
|
+
acc[key] = void 0;
|
|
3939
|
+
return acc;
|
|
3940
|
+
},
|
|
3941
|
+
{}
|
|
3942
|
+
);
|
|
3943
|
+
errorSchema = schemaValidationErrorSchema = utils.mergeObjects(
|
|
3944
|
+
currentErrors.errorSchema,
|
|
3945
|
+
newErrorSchema,
|
|
3946
|
+
"preventDuplicates"
|
|
3947
|
+
);
|
|
3948
|
+
}
|
|
3380
3949
|
}
|
|
3381
3950
|
if (props.extraErrors) {
|
|
3382
3951
|
const merged = utils.validationDataMerge({ errorSchema, errors }, props.extraErrors);
|
|
@@ -3414,6 +3983,21 @@
|
|
|
3414
3983
|
shouldComponentUpdate(nextProps, nextState) {
|
|
3415
3984
|
return utils.shouldRender(this, nextProps, nextState);
|
|
3416
3985
|
}
|
|
3986
|
+
/** Gets the previously raised customValidate errors.
|
|
3987
|
+
*
|
|
3988
|
+
* @returns the previous customValidate errors
|
|
3989
|
+
*/
|
|
3990
|
+
getPreviousCustomValidateErrors() {
|
|
3991
|
+
const { customValidate, uiSchema } = this.props;
|
|
3992
|
+
const prevFormData = this.state.formData;
|
|
3993
|
+
let customValidateErrors = {};
|
|
3994
|
+
if (typeof customValidate === "function") {
|
|
3995
|
+
const errorHandler = customValidate(prevFormData, utils.createErrorHandler(prevFormData), uiSchema);
|
|
3996
|
+
const userErrorSchema = utils.unwrapErrorHandler(errorHandler);
|
|
3997
|
+
customValidateErrors = userErrorSchema;
|
|
3998
|
+
}
|
|
3999
|
+
return customValidateErrors;
|
|
4000
|
+
}
|
|
3417
4001
|
/** Validates the `formData` against the `schema` using the `altSchemaUtils` (if provided otherwise it uses the
|
|
3418
4002
|
* `schemaUtils` in the state), returning the results.
|
|
3419
4003
|
*
|
|
@@ -3448,6 +4032,62 @@
|
|
|
3448
4032
|
}
|
|
3449
4033
|
return null;
|
|
3450
4034
|
}
|
|
4035
|
+
/** Returns the `formData` with only the elements specified in the `fields` list
|
|
4036
|
+
*
|
|
4037
|
+
* @param formData - The data for the `Form`
|
|
4038
|
+
* @param fields - The fields to keep while filtering
|
|
4039
|
+
*/
|
|
4040
|
+
getUsedFormData = (formData, fields2) => {
|
|
4041
|
+
if (fields2.length === 0 && typeof formData !== "object") {
|
|
4042
|
+
return formData;
|
|
4043
|
+
}
|
|
4044
|
+
const data = _pick(formData, fields2);
|
|
4045
|
+
if (Array.isArray(formData)) {
|
|
4046
|
+
return Object.keys(data).map((key) => data[key]);
|
|
4047
|
+
}
|
|
4048
|
+
return data;
|
|
4049
|
+
};
|
|
4050
|
+
/** Returns the list of field names from inspecting the `pathSchema` as well as using the `formData`
|
|
4051
|
+
*
|
|
4052
|
+
* @param pathSchema - The `PathSchema` object for the form
|
|
4053
|
+
* @param [formData] - The form data to use while checking for empty objects/arrays
|
|
4054
|
+
*/
|
|
4055
|
+
getFieldNames = (pathSchema, formData) => {
|
|
4056
|
+
const getAllPaths = (_obj, acc = [], paths = [[]]) => {
|
|
4057
|
+
Object.keys(_obj).forEach((key) => {
|
|
4058
|
+
if (typeof _obj[key] === "object") {
|
|
4059
|
+
const newPaths = paths.map((path) => [...path, key]);
|
|
4060
|
+
if (_obj[key][utils.RJSF_ADDITIONAL_PROPERTIES_FLAG] && _obj[key][utils.NAME_KEY] !== "") {
|
|
4061
|
+
acc.push(_obj[key][utils.NAME_KEY]);
|
|
4062
|
+
} else {
|
|
4063
|
+
getAllPaths(_obj[key], acc, newPaths);
|
|
4064
|
+
}
|
|
4065
|
+
} else if (key === utils.NAME_KEY && _obj[key] !== "") {
|
|
4066
|
+
paths.forEach((path) => {
|
|
4067
|
+
const formValue = get2(formData, path);
|
|
4068
|
+
if (typeof formValue !== "object" || isEmpty(formValue) || Array.isArray(formValue) && formValue.every((val) => typeof val !== "object")) {
|
|
4069
|
+
acc.push(path);
|
|
4070
|
+
}
|
|
4071
|
+
});
|
|
4072
|
+
}
|
|
4073
|
+
});
|
|
4074
|
+
return acc;
|
|
4075
|
+
};
|
|
4076
|
+
return getAllPaths(pathSchema);
|
|
4077
|
+
};
|
|
4078
|
+
/** Returns the `formData` after filtering to remove any extra data not in a form field
|
|
4079
|
+
*
|
|
4080
|
+
* @param formData - The data for the `Form`
|
|
4081
|
+
* @returns The `formData` after omitting extra data
|
|
4082
|
+
*/
|
|
4083
|
+
omitExtraData = (formData) => {
|
|
4084
|
+
const { schema, schemaUtils } = this.state;
|
|
4085
|
+
const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
|
|
4086
|
+
const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", formData);
|
|
4087
|
+
const fieldNames = this.getFieldNames(pathSchema, formData);
|
|
4088
|
+
const newFormData = this.getUsedFormData(formData, fieldNames);
|
|
4089
|
+
return newFormData;
|
|
4090
|
+
};
|
|
3451
4091
|
// Filtering errors based on your retrieved schema to only show errors for properties in the selected branch.
|
|
3452
4092
|
filterErrorsBasedOnSchema(schemaErrors, resolvedSchema, formData) {
|
|
3453
4093
|
const { retrievedSchema, schemaUtils } = this.state;
|
|
@@ -3458,18 +4098,185 @@
|
|
|
3458
4098
|
if (resolvedSchema?.type !== "object" && resolvedSchema?.type !== "array") {
|
|
3459
4099
|
filteredErrors.__errors = schemaErrors.__errors;
|
|
3460
4100
|
}
|
|
3461
|
-
const
|
|
4101
|
+
const prevCustomValidateErrors = this.getPreviousCustomValidateErrors();
|
|
4102
|
+
const filterPreviousCustomErrors = (errors = [], prevCustomErrors) => {
|
|
4103
|
+
if (errors.length === 0) {
|
|
4104
|
+
return errors;
|
|
4105
|
+
}
|
|
4106
|
+
return errors.filter((error) => {
|
|
4107
|
+
return !prevCustomErrors.includes(error);
|
|
4108
|
+
});
|
|
4109
|
+
};
|
|
4110
|
+
const filterNilOrEmptyErrors = (errors, previousCustomValidateErrors = {}) => {
|
|
3462
4111
|
_forEach(errors, (errorAtKey, errorKey) => {
|
|
3463
|
-
|
|
4112
|
+
const prevCustomValidateErrorAtKey = previousCustomValidateErrors[errorKey];
|
|
4113
|
+
if (_isNil(errorAtKey) || Array.isArray(errorAtKey) && errorAtKey.length === 0) {
|
|
3464
4114
|
delete errors[errorKey];
|
|
4115
|
+
} else if (utils.isObject(errorAtKey) && utils.isObject(prevCustomValidateErrorAtKey) && Array.isArray(prevCustomValidateErrorAtKey?.__errors)) {
|
|
4116
|
+
errors[errorKey] = filterPreviousCustomErrors(errorAtKey.__errors, prevCustomValidateErrorAtKey.__errors);
|
|
3465
4117
|
} else if (typeof errorAtKey === "object" && !Array.isArray(errorAtKey.__errors)) {
|
|
3466
|
-
|
|
4118
|
+
filterNilOrEmptyErrors(errorAtKey, previousCustomValidateErrors[errorKey]);
|
|
3467
4119
|
}
|
|
3468
4120
|
});
|
|
3469
4121
|
return errors;
|
|
3470
4122
|
};
|
|
3471
|
-
return
|
|
4123
|
+
return filterNilOrEmptyErrors(filteredErrors, prevCustomValidateErrors);
|
|
4124
|
+
}
|
|
4125
|
+
/** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
|
|
4126
|
+
* `formData` along with a new `ErrorSchema`. It will first update the `formData` with any missing default fields and
|
|
4127
|
+
* then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not
|
|
4128
|
+
* in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
|
|
4129
|
+
* updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
|
|
4130
|
+
* callback will be called if specified with the updated state.
|
|
4131
|
+
*
|
|
4132
|
+
* @param formData - The new form data from a change to a field
|
|
4133
|
+
* @param newErrorSchema - The new `ErrorSchema` based on the field change
|
|
4134
|
+
* @param id - The id of the field that caused the change
|
|
4135
|
+
*/
|
|
4136
|
+
onChange = (formData, newErrorSchema, id) => {
|
|
4137
|
+
const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange } = this.props;
|
|
4138
|
+
const { schemaUtils, schema } = this.state;
|
|
4139
|
+
let retrievedSchema = this.state.retrievedSchema;
|
|
4140
|
+
if (utils.isObject(formData) || Array.isArray(formData)) {
|
|
4141
|
+
const newState = this.getStateFromProps(this.props, formData);
|
|
4142
|
+
formData = newState.formData;
|
|
4143
|
+
retrievedSchema = newState.retrievedSchema;
|
|
4144
|
+
}
|
|
4145
|
+
const mustValidate = !noValidate && liveValidate;
|
|
4146
|
+
let state = { formData, schema };
|
|
4147
|
+
let newFormData = formData;
|
|
4148
|
+
if (omitExtraData === true && liveOmit === true) {
|
|
4149
|
+
newFormData = this.omitExtraData(formData);
|
|
4150
|
+
state = {
|
|
4151
|
+
formData: newFormData
|
|
4152
|
+
};
|
|
4153
|
+
}
|
|
4154
|
+
if (mustValidate) {
|
|
4155
|
+
const schemaValidation = this.validate(newFormData, schema, schemaUtils, retrievedSchema);
|
|
4156
|
+
let errors = schemaValidation.errors;
|
|
4157
|
+
let errorSchema = schemaValidation.errorSchema;
|
|
4158
|
+
const schemaValidationErrors = errors;
|
|
4159
|
+
const schemaValidationErrorSchema = errorSchema;
|
|
4160
|
+
if (extraErrors) {
|
|
4161
|
+
const merged = utils.validationDataMerge(schemaValidation, extraErrors);
|
|
4162
|
+
errorSchema = merged.errorSchema;
|
|
4163
|
+
errors = merged.errors;
|
|
4164
|
+
}
|
|
4165
|
+
if (newErrorSchema) {
|
|
4166
|
+
const filteredErrors = this.filterErrorsBasedOnSchema(newErrorSchema, retrievedSchema, newFormData);
|
|
4167
|
+
errorSchema = utils.mergeObjects(errorSchema, filteredErrors, "preventDuplicates");
|
|
4168
|
+
}
|
|
4169
|
+
state = {
|
|
4170
|
+
formData: newFormData,
|
|
4171
|
+
errors,
|
|
4172
|
+
errorSchema,
|
|
4173
|
+
schemaValidationErrors,
|
|
4174
|
+
schemaValidationErrorSchema
|
|
4175
|
+
};
|
|
4176
|
+
} else if (!noValidate && newErrorSchema) {
|
|
4177
|
+
const errorSchema = extraErrors ? utils.mergeObjects(newErrorSchema, extraErrors, "preventDuplicates") : newErrorSchema;
|
|
4178
|
+
state = {
|
|
4179
|
+
formData: newFormData,
|
|
4180
|
+
errorSchema,
|
|
4181
|
+
errors: utils.toErrorList(errorSchema)
|
|
4182
|
+
};
|
|
4183
|
+
}
|
|
4184
|
+
this.setState(state, () => onChange && onChange({ ...this.state, ...state }, id));
|
|
4185
|
+
};
|
|
4186
|
+
/**
|
|
4187
|
+
* If the retrievedSchema has changed the new retrievedSchema is returned.
|
|
4188
|
+
* Otherwise, the old retrievedSchema is returned to persist reference.
|
|
4189
|
+
* - This ensures that AJV retrieves the schema from the cache when it has not changed,
|
|
4190
|
+
* avoiding the performance cost of recompiling the schema.
|
|
4191
|
+
*
|
|
4192
|
+
* @param retrievedSchema The new retrieved schema.
|
|
4193
|
+
* @returns The new retrieved schema if it has changed, else the old retrieved schema.
|
|
4194
|
+
*/
|
|
4195
|
+
updateRetrievedSchema(retrievedSchema) {
|
|
4196
|
+
const isTheSame = utils.deepEquals(retrievedSchema, this.state?.retrievedSchema);
|
|
4197
|
+
return isTheSame ? this.state.retrievedSchema : retrievedSchema;
|
|
3472
4198
|
}
|
|
4199
|
+
/**
|
|
4200
|
+
* Callback function to handle reset form data.
|
|
4201
|
+
* - Reset all fields with default values.
|
|
4202
|
+
* - Reset validations and errors
|
|
4203
|
+
*
|
|
4204
|
+
*/
|
|
4205
|
+
reset = () => {
|
|
4206
|
+
const { onChange } = this.props;
|
|
4207
|
+
const newState = this.getStateFromProps(this.props, void 0);
|
|
4208
|
+
const newFormData = newState.formData;
|
|
4209
|
+
const state = {
|
|
4210
|
+
formData: newFormData,
|
|
4211
|
+
errorSchema: {},
|
|
4212
|
+
errors: [],
|
|
4213
|
+
schemaValidationErrors: [],
|
|
4214
|
+
schemaValidationErrorSchema: {}
|
|
4215
|
+
};
|
|
4216
|
+
this.setState(state, () => onChange && onChange({ ...this.state, ...state }));
|
|
4217
|
+
};
|
|
4218
|
+
/** Callback function to handle when a field on the form is blurred. Calls the `onBlur` callback for the `Form` if it
|
|
4219
|
+
* was provided.
|
|
4220
|
+
*
|
|
4221
|
+
* @param id - The unique `id` of the field that was blurred
|
|
4222
|
+
* @param data - The data associated with the field that was blurred
|
|
4223
|
+
*/
|
|
4224
|
+
onBlur = (id, data) => {
|
|
4225
|
+
const { onBlur } = this.props;
|
|
4226
|
+
if (onBlur) {
|
|
4227
|
+
onBlur(id, data);
|
|
4228
|
+
}
|
|
4229
|
+
};
|
|
4230
|
+
/** Callback function to handle when a field on the form is focused. Calls the `onFocus` callback for the `Form` if it
|
|
4231
|
+
* was provided.
|
|
4232
|
+
*
|
|
4233
|
+
* @param id - The unique `id` of the field that was focused
|
|
4234
|
+
* @param data - The data associated with the field that was focused
|
|
4235
|
+
*/
|
|
4236
|
+
onFocus = (id, data) => {
|
|
4237
|
+
const { onFocus } = this.props;
|
|
4238
|
+
if (onFocus) {
|
|
4239
|
+
onFocus(id, data);
|
|
4240
|
+
}
|
|
4241
|
+
};
|
|
4242
|
+
/** Callback function to handle when the form is submitted. First, it prevents the default event behavior. Nothing
|
|
4243
|
+
* happens if the target and currentTarget of the event are not the same. It will omit any extra data in the
|
|
4244
|
+
* `formData` in the state if `omitExtraData` is true. It will validate the resulting `formData`, reporting errors
|
|
4245
|
+
* via the `onError()` callback unless validation is disabled. Finally, it will add in any `extraErrors` and then call
|
|
4246
|
+
* back the `onSubmit` callback if it was provided.
|
|
4247
|
+
*
|
|
4248
|
+
* @param event - The submit HTML form event
|
|
4249
|
+
*/
|
|
4250
|
+
onSubmit = (event) => {
|
|
4251
|
+
event.preventDefault();
|
|
4252
|
+
if (event.target !== event.currentTarget) {
|
|
4253
|
+
return;
|
|
4254
|
+
}
|
|
4255
|
+
event.persist();
|
|
4256
|
+
const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
|
|
4257
|
+
let { formData: newFormData } = this.state;
|
|
4258
|
+
if (omitExtraData === true) {
|
|
4259
|
+
newFormData = this.omitExtraData(newFormData);
|
|
4260
|
+
}
|
|
4261
|
+
if (noValidate || this.validateFormWithFormData(newFormData)) {
|
|
4262
|
+
const errorSchema = extraErrors || {};
|
|
4263
|
+
const errors = extraErrors ? utils.toErrorList(extraErrors) : [];
|
|
4264
|
+
this.setState(
|
|
4265
|
+
{
|
|
4266
|
+
formData: newFormData,
|
|
4267
|
+
errors,
|
|
4268
|
+
errorSchema,
|
|
4269
|
+
schemaValidationErrors: [],
|
|
4270
|
+
schemaValidationErrorSchema: {}
|
|
4271
|
+
},
|
|
4272
|
+
() => {
|
|
4273
|
+
if (onSubmit) {
|
|
4274
|
+
onSubmit({ ...this.state, formData: newFormData, status: "submitted" }, event);
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4277
|
+
);
|
|
4278
|
+
}
|
|
4279
|
+
};
|
|
3473
4280
|
/** Returns the registry for the form */
|
|
3474
4281
|
getRegistry() {
|
|
3475
4282
|
const { translateString: customTranslateString, uiSchema = {} } = this.props;
|
|
@@ -3493,6 +4300,17 @@
|
|
|
3493
4300
|
globalUiOptions: uiSchema[utils.UI_GLOBAL_OPTIONS_KEY]
|
|
3494
4301
|
};
|
|
3495
4302
|
}
|
|
4303
|
+
/** Provides a function that can be used to programmatically submit the `Form` */
|
|
4304
|
+
submit = () => {
|
|
4305
|
+
if (this.formElement.current) {
|
|
4306
|
+
const submitCustomEvent = new CustomEvent("submit", {
|
|
4307
|
+
cancelable: true
|
|
4308
|
+
});
|
|
4309
|
+
submitCustomEvent.preventDefault();
|
|
4310
|
+
this.formElement.current.dispatchEvent(submitCustomEvent);
|
|
4311
|
+
this.formElement.current.requestSubmit();
|
|
4312
|
+
}
|
|
4313
|
+
};
|
|
3496
4314
|
/** Attempts to focus on the field associated with the `error`. Uses the `property` field to compute path of the error
|
|
3497
4315
|
* field, then, using the `idPrefix` and `idSeparator` converts that path into an id. Then the input element with that
|
|
3498
4316
|
* id is attempted to be found using the `formElement` ref. If it is located, then it is focused.
|
|
@@ -3511,7 +4329,7 @@
|
|
|
3511
4329
|
const elementId = path.join(idSeparator);
|
|
3512
4330
|
let field = this.formElement.current.elements[elementId];
|
|
3513
4331
|
if (!field) {
|
|
3514
|
-
field = this.formElement.current.querySelector(`input[id
|
|
4332
|
+
field = this.formElement.current.querySelector(`input[id^="${elementId}"`);
|
|
3515
4333
|
}
|
|
3516
4334
|
if (field && field.length) {
|
|
3517
4335
|
field = field[0];
|
|
@@ -3520,6 +4338,59 @@
|
|
|
3520
4338
|
field.focus();
|
|
3521
4339
|
}
|
|
3522
4340
|
}
|
|
4341
|
+
/** Validates the form using the given `formData`. For use on form submission or on programmatic validation.
|
|
4342
|
+
* If `onError` is provided, then it will be called with the list of errors.
|
|
4343
|
+
*
|
|
4344
|
+
* @param formData - The form data to validate
|
|
4345
|
+
* @returns - True if the form is valid, false otherwise.
|
|
4346
|
+
*/
|
|
4347
|
+
validateFormWithFormData = (formData) => {
|
|
4348
|
+
const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
|
|
4349
|
+
const { errors: prevErrors } = this.state;
|
|
4350
|
+
const schemaValidation = this.validate(formData);
|
|
4351
|
+
let errors = schemaValidation.errors;
|
|
4352
|
+
let errorSchema = schemaValidation.errorSchema;
|
|
4353
|
+
const schemaValidationErrors = errors;
|
|
4354
|
+
const schemaValidationErrorSchema = errorSchema;
|
|
4355
|
+
const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
|
|
4356
|
+
if (hasError) {
|
|
4357
|
+
if (extraErrors) {
|
|
4358
|
+
const merged = utils.validationDataMerge(schemaValidation, extraErrors);
|
|
4359
|
+
errorSchema = merged.errorSchema;
|
|
4360
|
+
errors = merged.errors;
|
|
4361
|
+
}
|
|
4362
|
+
if (focusOnFirstError) {
|
|
4363
|
+
if (typeof focusOnFirstError === "function") {
|
|
4364
|
+
focusOnFirstError(errors[0]);
|
|
4365
|
+
} else {
|
|
4366
|
+
this.focusOnError(errors[0]);
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
this.setState(
|
|
4370
|
+
{
|
|
4371
|
+
errors,
|
|
4372
|
+
errorSchema,
|
|
4373
|
+
schemaValidationErrors,
|
|
4374
|
+
schemaValidationErrorSchema
|
|
4375
|
+
},
|
|
4376
|
+
() => {
|
|
4377
|
+
if (onError) {
|
|
4378
|
+
onError(errors);
|
|
4379
|
+
} else {
|
|
4380
|
+
console.error("Form validation failed", errors);
|
|
4381
|
+
}
|
|
4382
|
+
}
|
|
4383
|
+
);
|
|
4384
|
+
} else if (prevErrors.length > 0) {
|
|
4385
|
+
this.setState({
|
|
4386
|
+
errors: [],
|
|
4387
|
+
errorSchema: {},
|
|
4388
|
+
schemaValidationErrors: [],
|
|
4389
|
+
schemaValidationErrorSchema: {}
|
|
4390
|
+
});
|
|
4391
|
+
}
|
|
4392
|
+
return !hasError;
|
|
4393
|
+
};
|
|
3523
4394
|
/** Programmatically validate the form. If `omitExtraData` is true, the `formData` will first be filtered to remove
|
|
3524
4395
|
* any extra data not in a form field. If `onError` is provided, then it will be called with the list of errors the
|
|
3525
4396
|
* same way as would happen on form submission.
|
|
@@ -3551,7 +4422,6 @@
|
|
|
3551
4422
|
action,
|
|
3552
4423
|
autoComplete,
|
|
3553
4424
|
enctype,
|
|
3554
|
-
acceptcharset,
|
|
3555
4425
|
acceptCharset,
|
|
3556
4426
|
noHtml5Validate = false,
|
|
3557
4427
|
disabled,
|
|
@@ -3582,7 +4452,7 @@
|
|
|
3582
4452
|
action,
|
|
3583
4453
|
autoComplete,
|
|
3584
4454
|
encType: enctype,
|
|
3585
|
-
acceptCharset
|
|
4455
|
+
acceptCharset,
|
|
3586
4456
|
noValidate: noHtml5Validate,
|
|
3587
4457
|
onSubmit: this.onSubmit,
|
|
3588
4458
|
as,
|
|
@@ -3645,9 +4515,10 @@
|
|
|
3645
4515
|
}
|
|
3646
4516
|
|
|
3647
4517
|
// src/index.ts
|
|
3648
|
-
var
|
|
4518
|
+
var index_default = Form;
|
|
3649
4519
|
|
|
3650
|
-
exports.
|
|
4520
|
+
exports.RichDescription = RichDescription;
|
|
4521
|
+
exports.default = index_default;
|
|
3651
4522
|
exports.getDefaultRegistry = getDefaultRegistry;
|
|
3652
4523
|
exports.withTheme = withTheme;
|
|
3653
4524
|
|