@rjsf/core 6.0.0-beta.8 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/core.umd.js +2042 -1987
- package/dist/index.cjs +4909 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.esm.js +2509 -2389
- package/dist/index.esm.js.map +4 -4
- package/lib/components/Form.d.ts +137 -34
- package/lib/components/Form.d.ts.map +1 -1
- package/lib/components/Form.js +318 -173
- package/lib/components/fields/ArrayField.d.ts +2 -187
- package/lib/components/fields/ArrayField.d.ts.map +1 -1
- package/lib/components/fields/ArrayField.js +526 -492
- package/lib/components/fields/BooleanField.d.ts.map +1 -1
- package/lib/components/fields/BooleanField.js +8 -3
- package/lib/components/fields/FallbackField.d.ts +7 -0
- package/lib/components/fields/FallbackField.d.ts.map +1 -0
- package/lib/components/fields/FallbackField.js +72 -0
- package/lib/components/fields/LayoutGridField.d.ts +109 -186
- package/lib/components/fields/LayoutGridField.d.ts.map +1 -1
- package/lib/components/fields/LayoutGridField.js +426 -426
- package/lib/components/fields/LayoutHeaderField.d.ts +1 -1
- package/lib/components/fields/LayoutHeaderField.js +3 -3
- package/lib/components/fields/LayoutMultiSchemaField.d.ts.map +1 -1
- package/lib/components/fields/LayoutMultiSchemaField.js +6 -6
- package/lib/components/fields/MultiSchemaField.d.ts.map +1 -1
- package/lib/components/fields/MultiSchemaField.js +16 -10
- package/lib/components/fields/NullField.js +3 -3
- package/lib/components/fields/NumberField.d.ts.map +1 -1
- package/lib/components/fields/NumberField.js +3 -3
- package/lib/components/fields/ObjectField.d.ts +2 -68
- package/lib/components/fields/ObjectField.d.ts.map +1 -1
- package/lib/components/fields/ObjectField.js +163 -163
- package/lib/components/fields/OptionalDataControlsField.d.ts +8 -0
- package/lib/components/fields/OptionalDataControlsField.d.ts.map +1 -0
- package/lib/components/fields/OptionalDataControlsField.js +43 -0
- package/lib/components/fields/SchemaField.d.ts.map +1 -1
- package/lib/components/fields/SchemaField.js +52 -30
- package/lib/components/fields/StringField.d.ts.map +1 -1
- package/lib/components/fields/StringField.js +8 -3
- package/lib/components/fields/index.d.ts.map +1 -1
- package/lib/components/fields/index.js +4 -0
- package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts +1 -1
- package/lib/components/templates/ArrayFieldDescriptionTemplate.js +3 -3
- package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts +3 -3
- package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts.map +1 -1
- package/lib/components/templates/ArrayFieldItemButtonsTemplate.js +3 -8
- package/lib/components/templates/ArrayFieldItemTemplate.d.ts +3 -3
- package/lib/components/templates/ArrayFieldItemTemplate.d.ts.map +1 -1
- package/lib/components/templates/ArrayFieldItemTemplate.js +1 -1
- package/lib/components/templates/ArrayFieldTemplate.d.ts +1 -1
- package/lib/components/templates/ArrayFieldTemplate.d.ts.map +1 -1
- package/lib/components/templates/ArrayFieldTemplate.js +4 -5
- package/lib/components/templates/ArrayFieldTitleTemplate.d.ts +1 -1
- package/lib/components/templates/ArrayFieldTitleTemplate.d.ts.map +1 -1
- package/lib/components/templates/ArrayFieldTitleTemplate.js +3 -3
- package/lib/components/templates/BaseInputTemplate.js +2 -2
- package/lib/components/templates/ButtonTemplates/AddButton.d.ts +1 -1
- package/lib/components/templates/ButtonTemplates/AddButton.d.ts.map +1 -1
- package/lib/components/templates/ButtonTemplates/AddButton.js +2 -2
- package/lib/components/templates/FallbackFieldTemplate.d.ts +7 -0
- package/lib/components/templates/FallbackFieldTemplate.d.ts.map +1 -0
- package/lib/components/templates/FallbackFieldTemplate.js +12 -0
- package/lib/components/templates/FieldErrorTemplate.js +2 -2
- package/lib/components/templates/FieldHelpTemplate.js +2 -2
- package/lib/components/templates/MultiSchemaFieldTemplate.d.ts +8 -0
- package/lib/components/templates/MultiSchemaFieldTemplate.d.ts.map +1 -0
- package/lib/components/templates/MultiSchemaFieldTemplate.js +10 -0
- package/lib/components/templates/ObjectFieldTemplate.d.ts.map +1 -1
- package/lib/components/templates/ObjectFieldTemplate.js +3 -2
- package/lib/components/templates/OptionalDataControlsTemplate.d.ts +11 -0
- package/lib/components/templates/OptionalDataControlsTemplate.d.ts.map +1 -0
- package/lib/components/templates/OptionalDataControlsTemplate.js +20 -0
- package/lib/components/templates/TitleField.d.ts.map +1 -1
- package/lib/components/templates/TitleField.js +2 -2
- package/lib/components/templates/UnsupportedField.js +3 -3
- package/lib/components/templates/WrapIfAdditionalTemplate.js +2 -2
- package/lib/components/templates/index.d.ts.map +1 -1
- package/lib/components/templates/index.js +6 -0
- package/lib/components/widgets/AltDateWidget.d.ts +1 -1
- package/lib/components/widgets/AltDateWidget.d.ts.map +1 -1
- package/lib/components/widgets/AltDateWidget.js +5 -46
- package/lib/components/widgets/CheckboxWidget.d.ts +1 -1
- package/lib/components/widgets/CheckboxWidget.d.ts.map +1 -1
- package/lib/components/widgets/CheckboxWidget.js +2 -2
- package/lib/components/widgets/CheckboxesWidget.d.ts +1 -1
- package/lib/components/widgets/CheckboxesWidget.d.ts.map +1 -1
- package/lib/components/widgets/CheckboxesWidget.js +4 -4
- package/lib/components/widgets/FileWidget.d.ts.map +1 -1
- package/lib/components/widgets/FileWidget.js +7 -87
- package/lib/components/widgets/HiddenWidget.d.ts +1 -1
- package/lib/components/widgets/HiddenWidget.d.ts.map +1 -1
- package/lib/components/widgets/HiddenWidget.js +2 -2
- package/lib/components/widgets/RadioWidget.d.ts +1 -1
- package/lib/components/widgets/RadioWidget.d.ts.map +1 -1
- package/lib/components/widgets/RadioWidget.js +2 -2
- package/lib/components/widgets/RatingWidget.d.ts +1 -1
- package/lib/components/widgets/RatingWidget.d.ts.map +1 -1
- package/lib/components/widgets/RatingWidget.js +2 -2
- package/lib/components/widgets/SelectWidget.d.ts +1 -1
- package/lib/components/widgets/SelectWidget.d.ts.map +1 -1
- package/lib/components/widgets/SelectWidget.js +2 -2
- package/lib/components/widgets/TextareaWidget.d.ts +1 -1
- package/lib/components/widgets/TextareaWidget.d.ts.map +1 -1
- package/lib/components/widgets/TextareaWidget.js +2 -2
- package/lib/getDefaultRegistry.d.ts.map +1 -1
- package/lib/getDefaultRegistry.js +6 -1
- package/lib/getTestRegistry.d.ts +5 -0
- package/lib/getTestRegistry.d.ts.map +1 -0
- package/lib/getTestRegistry.js +23 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -20
- package/src/components/Form.tsx +468 -206
- package/src/components/fields/ArrayField.tsx +871 -723
- package/src/components/fields/BooleanField.tsx +14 -5
- package/src/components/fields/FallbackField.tsx +157 -0
- package/src/components/fields/LayoutGridField.tsx +626 -603
- package/src/components/fields/LayoutHeaderField.tsx +3 -3
- package/src/components/fields/LayoutMultiSchemaField.tsx +9 -10
- package/src/components/fields/MultiSchemaField.tsx +57 -36
- package/src/components/fields/NullField.tsx +3 -3
- package/src/components/fields/NumberField.tsx +11 -3
- package/src/components/fields/ObjectField.tsx +308 -239
- package/src/components/fields/OptionalDataControlsField.tsx +84 -0
- package/src/components/fields/SchemaField.tsx +75 -94
- package/src/components/fields/StringField.tsx +14 -5
- package/src/components/fields/index.ts +4 -0
- package/src/components/templates/ArrayFieldDescriptionTemplate.tsx +3 -3
- package/src/components/templates/ArrayFieldItemButtonsTemplate.tsx +16 -21
- package/src/components/templates/ArrayFieldItemTemplate.tsx +3 -3
- package/src/components/templates/ArrayFieldTemplate.tsx +11 -18
- package/src/components/templates/ArrayFieldTitleTemplate.tsx +4 -3
- package/src/components/templates/BaseInputTemplate.tsx +5 -5
- package/src/components/templates/ButtonTemplates/AddButton.tsx +2 -0
- package/src/components/templates/FallbackFieldTemplate.tsx +28 -0
- package/src/components/templates/FieldErrorTemplate.tsx +2 -2
- package/src/components/templates/FieldHelpTemplate.tsx +2 -2
- package/src/components/templates/MultiSchemaFieldTemplate.tsx +20 -0
- package/src/components/templates/ObjectFieldTemplate.tsx +12 -7
- package/src/components/templates/OptionalDataControlsTemplate.tsx +43 -0
- package/src/components/templates/TitleField.tsx +6 -1
- package/src/components/templates/UnsupportedField.tsx +3 -3
- package/src/components/templates/WrapIfAdditionalTemplate.tsx +5 -5
- package/src/components/templates/index.ts +6 -0
- package/src/components/widgets/AltDateWidget.tsx +8 -126
- package/src/components/widgets/CheckboxWidget.tsx +4 -3
- package/src/components/widgets/CheckboxesWidget.tsx +5 -4
- package/src/components/widgets/FileWidget.tsx +11 -102
- package/src/components/widgets/HiddenWidget.tsx +2 -1
- package/src/components/widgets/RadioWidget.tsx +3 -2
- package/src/components/widgets/RatingWidget.tsx +2 -1
- package/src/components/widgets/SelectWidget.tsx +3 -2
- package/src/components/widgets/TextareaWidget.tsx +3 -2
- package/src/getDefaultRegistry.ts +14 -1
- package/src/getTestRegistry.tsx +38 -0
- package/src/index.ts +2 -1
- package/dist/index.js +0 -4834
- package/dist/index.js.map +0 -7
|
@@ -1,32 +1,52 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { getTemplate, getUiOptions, orderProperties,
|
|
2
|
+
import { useCallback, useState } from 'react';
|
|
3
|
+
import { ADDITIONAL_PROPERTY_FLAG, ANY_OF_KEY, getTemplate, getUiOptions, hashObject, isFormDataAvailable, orderProperties, shouldRenderOptionalField, toFieldPathId, useDeepCompareMemo, ONE_OF_KEY, PROPERTIES_KEY, REF_KEY, TranslatableString, } from '@rjsf/utils';
|
|
4
4
|
import Markdown from 'markdown-to-jsx';
|
|
5
5
|
import get from 'lodash-es/get.js';
|
|
6
6
|
import has from 'lodash-es/has.js';
|
|
7
7
|
import isObject from 'lodash-es/isObject.js';
|
|
8
8
|
import set from 'lodash-es/set.js';
|
|
9
9
|
import unset from 'lodash-es/unset.js';
|
|
10
|
-
/**
|
|
11
|
-
* additional property key was modified and what it was modified to
|
|
10
|
+
/** Returns a flag indicating whether the `name` field is required in the object schema
|
|
12
11
|
*
|
|
13
|
-
* @param
|
|
12
|
+
* @param schema - The schema to check
|
|
13
|
+
* @param name - The name of the field to check for required-ness
|
|
14
|
+
* @returns - True if the field `name` is required, false otherwise
|
|
14
15
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
function isRequired(schema, name) {
|
|
17
|
+
return Array.isArray(schema.required) && schema.required.indexOf(name) !== -1;
|
|
18
|
+
}
|
|
19
|
+
/** Returns a default value to be used for a new additional schema property of the given `type`
|
|
20
|
+
*
|
|
21
|
+
* @param translateString - The string translation function from the registry
|
|
22
|
+
* @param type - The type of the new additional schema property
|
|
23
|
+
*/
|
|
24
|
+
function getDefaultValue(translateString, type) {
|
|
25
|
+
switch (type) {
|
|
26
|
+
case 'array':
|
|
27
|
+
return [];
|
|
28
|
+
case 'boolean':
|
|
29
|
+
return false;
|
|
30
|
+
case 'null':
|
|
31
|
+
return null;
|
|
32
|
+
case 'number':
|
|
33
|
+
return 0;
|
|
34
|
+
case 'object':
|
|
35
|
+
return {};
|
|
36
|
+
case 'string':
|
|
37
|
+
default:
|
|
38
|
+
// We don't have a datatype for some reason (perhaps additionalProperties was true)
|
|
39
|
+
return translateString(TranslatableString.NewStringDefault);
|
|
29
40
|
}
|
|
41
|
+
}
|
|
42
|
+
/** The `ObjectFieldProperty` component is used to render the `SchemaField` for a child property of an object
|
|
43
|
+
*/
|
|
44
|
+
function ObjectFieldProperty(props) {
|
|
45
|
+
const { fieldPathId, schema, registry, uiSchema, errorSchema, formData, onChange, onBlur, onFocus, disabled, readonly, required, hideError, propertyName, handleKeyRename, handleRemoveProperty, addedByAdditionalProperties, } = props;
|
|
46
|
+
const [wasPropertyKeyModified, setWasPropertyKeyModified] = useState(false);
|
|
47
|
+
const { globalFormOptions, fields } = registry;
|
|
48
|
+
const { SchemaField } = fields;
|
|
49
|
+
const innerFieldIdPathId = useDeepCompareMemo(toFieldPathId(propertyName, globalFormOptions, fieldPathId.path));
|
|
30
50
|
/** Returns the `onPropertyChange` handler for the `name` field. Handles the special case where a user is attempting
|
|
31
51
|
* to clear the data for a field added as an additional property. Calls the `onChange()` handler with the updated
|
|
32
52
|
* formData.
|
|
@@ -35,42 +55,59 @@ class ObjectField extends Component {
|
|
|
35
55
|
* @param addedByAdditionalProperties - Flag indicating whether this property is an additional property
|
|
36
56
|
* @returns - The onPropertyChange callback for the `name` property
|
|
37
57
|
*/
|
|
38
|
-
onPropertyChange = (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
const newFormData = { ...formData, [name]: value };
|
|
52
|
-
onChange(newFormData, errorSchema &&
|
|
53
|
-
errorSchema && {
|
|
54
|
-
...errorSchema,
|
|
55
|
-
[name]: newErrorSchema,
|
|
56
|
-
}, id);
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
/** Returns a callback to handle the onDropPropertyClick event for the given `key` which removes the old `key` data
|
|
60
|
-
* and calls the `onChange` callback with it
|
|
61
|
-
*
|
|
62
|
-
* @param key - The key for which the drop callback is desired
|
|
63
|
-
* @returns - The drop property click callback
|
|
58
|
+
const onPropertyChange = useCallback((value, path, newErrorSchema, id) => {
|
|
59
|
+
if (value === undefined && addedByAdditionalProperties) {
|
|
60
|
+
// Don't set value = undefined for fields added by additionalProperties. Doing so removes them from the
|
|
61
|
+
// formData, which causes them to completely disappear (including the input field for the property name). Unlike
|
|
62
|
+
// fields which are "mandated" by the schema, these fields can be set to undefined by clicking a "delete field"
|
|
63
|
+
// button, so set empty values to the empty string.
|
|
64
|
+
value = '';
|
|
65
|
+
}
|
|
66
|
+
onChange(value, path, newErrorSchema, id);
|
|
67
|
+
}, [onChange, addedByAdditionalProperties]);
|
|
68
|
+
/** The key change event handler; Called when the key associated with a field is changed for an additionalProperty.
|
|
69
|
+
* simply returns a function that call the `handleKeyChange()` event with the value
|
|
64
70
|
*/
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
const onKeyRename = useCallback((value) => {
|
|
72
|
+
if (propertyName !== value) {
|
|
73
|
+
setWasPropertyKeyModified(true);
|
|
74
|
+
}
|
|
75
|
+
handleKeyRename(propertyName, value);
|
|
76
|
+
}, [propertyName, handleKeyRename]);
|
|
77
|
+
/** Returns a callback the handle the blur event, getting the value from the target and passing that along to the
|
|
78
|
+
* `handleKeyChange` function
|
|
79
|
+
*/
|
|
80
|
+
const onKeyRenameBlur = useCallback((event) => {
|
|
81
|
+
const { target: { value }, } = event;
|
|
82
|
+
onKeyRename(value);
|
|
83
|
+
}, [onKeyRename]);
|
|
84
|
+
/** The property drop/removal event handler; Called when a field is removed in an additionalProperty context
|
|
85
|
+
*/
|
|
86
|
+
const onRemoveProperty = useCallback(() => {
|
|
87
|
+
handleRemoveProperty(propertyName);
|
|
88
|
+
}, [propertyName, handleRemoveProperty]);
|
|
89
|
+
return (_jsx(SchemaField, { name: propertyName, required: required, schema: schema, uiSchema: uiSchema, errorSchema: errorSchema, fieldPathId: innerFieldIdPathId, formData: formData, wasPropertyKeyModified: wasPropertyKeyModified, onKeyRename: onKeyRename, onKeyRenameBlur: onKeyRenameBlur, onRemoveProperty: onRemoveProperty, onChange: onPropertyChange, onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError }));
|
|
90
|
+
}
|
|
91
|
+
/** The `ObjectField` component is used to render a field in the schema that is of type `object`. It tracks whether an
|
|
92
|
+
* additional property key was modified and what it was modified to
|
|
93
|
+
*
|
|
94
|
+
* @param props - The `FieldProps` for this template
|
|
95
|
+
*/
|
|
96
|
+
export default function ObjectField(props) {
|
|
97
|
+
const { schema: rawSchema, uiSchema = {}, formData, errorSchema, fieldPathId, name, required = false, disabled, readonly, hideError, onBlur, onFocus, onChange, registry, title, } = props;
|
|
98
|
+
const { fields, schemaUtils, translateString, globalUiOptions } = registry;
|
|
99
|
+
const { OptionalDataControlsField } = fields;
|
|
100
|
+
const schema = schemaUtils.retrieveSchema(rawSchema, formData, true);
|
|
101
|
+
const uiOptions = getUiOptions(uiSchema, globalUiOptions);
|
|
102
|
+
const { properties: schemaProperties = {} } = schema;
|
|
103
|
+
const formDataHash = hashObject(formData || {});
|
|
104
|
+
// All the children will use childFieldPathId if present in the props, falling back to the fieldPathId
|
|
105
|
+
const childFieldPathId = props.childFieldPathId ?? fieldPathId;
|
|
106
|
+
const templateTitle = uiOptions.title ?? schema.title ?? title ?? name;
|
|
107
|
+
const description = uiOptions.description ?? schema.description;
|
|
108
|
+
const renderOptionalField = shouldRenderOptionalField(registry, schema, required, uiSchema);
|
|
109
|
+
const hasFormData = isFormDataAvailable(formData);
|
|
110
|
+
let orderedProperties = [];
|
|
74
111
|
/** Computes the next available key name from the `preferredKey`, indexing through the already existing keys until one
|
|
75
112
|
* that is already not assigned is found.
|
|
76
113
|
*
|
|
@@ -78,81 +115,25 @@ class ObjectField extends Component {
|
|
|
78
115
|
* @param [formData] - The form data in which to check if the desired key already exists
|
|
79
116
|
* @returns - The name of the next available key from `preferredKey`
|
|
80
117
|
*/
|
|
81
|
-
getAvailableKey = (preferredKey, formData) => {
|
|
82
|
-
const {
|
|
83
|
-
const { duplicateKeySuffixSeparator = '-' } = getUiOptions(uiSchema, registry.globalUiOptions);
|
|
118
|
+
const getAvailableKey = useCallback((preferredKey, formData) => {
|
|
119
|
+
const { duplicateKeySuffixSeparator = '-' } = getUiOptions(uiSchema, globalUiOptions);
|
|
84
120
|
let index = 0;
|
|
85
121
|
let newKey = preferredKey;
|
|
86
122
|
while (has(formData, newKey)) {
|
|
87
123
|
newKey = `${preferredKey}${duplicateKeySuffixSeparator}${++index}`;
|
|
88
124
|
}
|
|
89
125
|
return newKey;
|
|
90
|
-
};
|
|
91
|
-
/** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
|
|
92
|
-
* callback will attempt to rename the key and move the existing data to that key, calling `onChange` when it does.
|
|
93
|
-
*
|
|
94
|
-
* @param oldValue - The old value of a field
|
|
95
|
-
* @returns - The key change callback function
|
|
96
|
-
*/
|
|
97
|
-
onKeyChange = (oldValue) => {
|
|
98
|
-
return (value, newErrorSchema) => {
|
|
99
|
-
if (oldValue === value) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const { formData, onChange, errorSchema } = this.props;
|
|
103
|
-
value = this.getAvailableKey(value, formData);
|
|
104
|
-
const newFormData = {
|
|
105
|
-
...formData,
|
|
106
|
-
};
|
|
107
|
-
const newKeys = { [oldValue]: value };
|
|
108
|
-
const keyValues = Object.keys(newFormData).map((key) => {
|
|
109
|
-
const newKey = newKeys[key] || key;
|
|
110
|
-
return { [newKey]: newFormData[key] };
|
|
111
|
-
});
|
|
112
|
-
const renamedObj = Object.assign({}, ...keyValues);
|
|
113
|
-
this.setState({ wasPropertyKeyModified: true });
|
|
114
|
-
onChange(renamedObj, errorSchema &&
|
|
115
|
-
errorSchema && {
|
|
116
|
-
...errorSchema,
|
|
117
|
-
[value]: newErrorSchema,
|
|
118
|
-
});
|
|
119
|
-
};
|
|
120
|
-
};
|
|
121
|
-
/** Returns a default value to be used for a new additional schema property of the given `type`
|
|
122
|
-
*
|
|
123
|
-
* @param type - The type of the new additional schema property
|
|
124
|
-
*/
|
|
125
|
-
getDefaultValue(type) {
|
|
126
|
-
const { registry: { translateString }, } = this.props;
|
|
127
|
-
switch (type) {
|
|
128
|
-
case 'array':
|
|
129
|
-
return [];
|
|
130
|
-
case 'boolean':
|
|
131
|
-
return false;
|
|
132
|
-
case 'null':
|
|
133
|
-
return null;
|
|
134
|
-
case 'number':
|
|
135
|
-
return 0;
|
|
136
|
-
case 'object':
|
|
137
|
-
return {};
|
|
138
|
-
case 'string':
|
|
139
|
-
default:
|
|
140
|
-
// We don't have a datatype for some reason (perhaps additionalProperties was true)
|
|
141
|
-
return translateString(TranslatableString.NewStringDefault);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
126
|
+
}, [uiSchema, globalUiOptions]);
|
|
144
127
|
/** Handles the adding of a new additional property on the given `schema`. Calls the `onChange` callback once the new
|
|
145
128
|
* default data for that field has been added to the formData.
|
|
146
|
-
*
|
|
147
|
-
* @param schema - The schema element to which the new property is being added
|
|
148
129
|
*/
|
|
149
|
-
|
|
130
|
+
const onAddProperty = useCallback(() => {
|
|
150
131
|
if (!(schema.additionalProperties || schema.patternProperties)) {
|
|
151
132
|
return;
|
|
152
133
|
}
|
|
153
|
-
const {
|
|
134
|
+
const { translateString } = registry;
|
|
154
135
|
const newFormData = { ...formData };
|
|
155
|
-
const newKey =
|
|
136
|
+
const newKey = getAvailableKey('newKey', newFormData);
|
|
156
137
|
if (schema.patternProperties) {
|
|
157
138
|
// Cast this to make the `set` work properly
|
|
158
139
|
set(newFormData, newKey, null);
|
|
@@ -168,7 +149,7 @@ class ObjectField extends Component {
|
|
|
168
149
|
let apSchema = schema.additionalProperties;
|
|
169
150
|
if (REF_KEY in apSchema) {
|
|
170
151
|
const { schemaUtils } = registry;
|
|
171
|
-
apSchema = schemaUtils.retrieveSchema({
|
|
152
|
+
apSchema = schemaUtils.retrieveSchema({ [REF_KEY]: apSchema[REF_KEY] }, formData);
|
|
172
153
|
type = apSchema.type;
|
|
173
154
|
constValue = apSchema.const;
|
|
174
155
|
defaultValue = apSchema.default;
|
|
@@ -177,24 +158,42 @@ class ObjectField extends Component {
|
|
|
177
158
|
type = 'object';
|
|
178
159
|
}
|
|
179
160
|
}
|
|
180
|
-
const newValue = constValue ?? defaultValue ??
|
|
161
|
+
const newValue = constValue ?? defaultValue ?? getDefaultValue(translateString, type);
|
|
181
162
|
// Cast this to make the `set` work properly
|
|
182
163
|
set(newFormData, newKey, newValue);
|
|
183
164
|
}
|
|
184
|
-
onChange(newFormData);
|
|
185
|
-
};
|
|
186
|
-
/**
|
|
165
|
+
onChange(newFormData, childFieldPathId.path);
|
|
166
|
+
}, [formData, onChange, registry, childFieldPathId, getAvailableKey, schema]);
|
|
167
|
+
/** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
|
|
168
|
+
* callback will attempt to rename the key and move the existing data to that key, calling `onChange` when it does.
|
|
169
|
+
*
|
|
170
|
+
* @param oldKey - The old key for the field
|
|
171
|
+
* @param newKey - The new key for the field
|
|
172
|
+
* @returns - The key change callback function
|
|
173
|
+
*/
|
|
174
|
+
const handleKeyRename = useCallback((oldKey, newKey) => {
|
|
175
|
+
if (oldKey !== newKey) {
|
|
176
|
+
const actualNewKey = getAvailableKey(newKey, formData);
|
|
177
|
+
const newFormData = {
|
|
178
|
+
...formData,
|
|
179
|
+
};
|
|
180
|
+
const newKeys = { [oldKey]: actualNewKey };
|
|
181
|
+
const keyValues = Object.keys(newFormData).map((key) => {
|
|
182
|
+
const newKey = newKeys[key] || key;
|
|
183
|
+
return { [newKey]: newFormData[key] };
|
|
184
|
+
});
|
|
185
|
+
const renamedObj = Object.assign({}, ...keyValues);
|
|
186
|
+
onChange(renamedObj, childFieldPathId.path);
|
|
187
|
+
}
|
|
188
|
+
}, [formData, onChange, childFieldPathId, getAvailableKey]);
|
|
189
|
+
/** Handles the remove click which removes the old `key` data and calls the `onChange` callback with it
|
|
187
190
|
*/
|
|
188
|
-
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const { properties: schemaProperties = {} } = schema;
|
|
195
|
-
const templateTitle = uiOptions.title ?? schema.title ?? title ?? name;
|
|
196
|
-
const description = uiOptions.description ?? schema.description;
|
|
197
|
-
let orderedProperties;
|
|
191
|
+
const handleRemoveProperty = useCallback((key) => {
|
|
192
|
+
const copiedFormData = { ...formData };
|
|
193
|
+
unset(copiedFormData, key);
|
|
194
|
+
onChange(copiedFormData, childFieldPathId.path);
|
|
195
|
+
}, [onChange, childFieldPathId, formData]);
|
|
196
|
+
if (!renderOptionalField || hasFormData) {
|
|
198
197
|
try {
|
|
199
198
|
const properties = Object.keys(schemaProperties);
|
|
200
199
|
orderedProperties = orderProperties(properties, uiOptions.order);
|
|
@@ -202,37 +201,38 @@ class ObjectField extends Component {
|
|
|
202
201
|
catch (err) {
|
|
203
202
|
return (_jsxs("div", { children: [_jsx("p", { className: 'rjsf-config-error', style: { color: 'red' }, children: _jsx(Markdown, { options: { disableParsingRawHTML: true }, children: translateString(TranslatableString.InvalidObjectField, [name || 'root', err.message]) }) }), _jsx("pre", { children: JSON.stringify(schema) })] }));
|
|
204
203
|
}
|
|
205
|
-
const Template = getTemplate('ObjectFieldTemplate', registry, uiOptions);
|
|
206
|
-
const templateProps = {
|
|
207
|
-
// getDisplayLabel() always returns false for object types, so just check the `uiOptions.label`
|
|
208
|
-
title: uiOptions.label === false ? '' : templateTitle,
|
|
209
|
-
description: uiOptions.label === false ? undefined : description,
|
|
210
|
-
properties: orderedProperties.map((name) => {
|
|
211
|
-
const addedByAdditionalProperties = has(schema, [PROPERTIES_KEY, name, ADDITIONAL_PROPERTY_FLAG]);
|
|
212
|
-
const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[name];
|
|
213
|
-
const hidden = getUiOptions(fieldUiSchema).widget === 'hidden';
|
|
214
|
-
const fieldIdSchema = get(idSchema, [name], {});
|
|
215
|
-
return {
|
|
216
|
-
content: (_jsx(SchemaField, { name: name, required: this.isRequired(name), schema: get(schema, [PROPERTIES_KEY, name], {}), uiSchema: fieldUiSchema, errorSchema: get(errorSchema, name), idSchema: fieldIdSchema, idPrefix: idPrefix, idSeparator: idSeparator, formData: get(formData, name), formContext: formContext, wasPropertyKeyModified: this.state.wasPropertyKeyModified, onKeyChange: this.onKeyChange(name), onChange: this.onPropertyChange(name, addedByAdditionalProperties), onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError, onDropPropertyClick: this.onDropPropertyClick }, name)),
|
|
217
|
-
name,
|
|
218
|
-
readonly,
|
|
219
|
-
disabled,
|
|
220
|
-
required,
|
|
221
|
-
hidden,
|
|
222
|
-
};
|
|
223
|
-
}),
|
|
224
|
-
readonly,
|
|
225
|
-
disabled,
|
|
226
|
-
required,
|
|
227
|
-
idSchema,
|
|
228
|
-
uiSchema,
|
|
229
|
-
errorSchema,
|
|
230
|
-
schema,
|
|
231
|
-
formData,
|
|
232
|
-
formContext,
|
|
233
|
-
registry,
|
|
234
|
-
};
|
|
235
|
-
return _jsx(Template, { ...templateProps, onAddClick: this.handleAddClick });
|
|
236
204
|
}
|
|
205
|
+
const Template = getTemplate('ObjectFieldTemplate', registry, uiOptions);
|
|
206
|
+
const optionalDataControl = renderOptionalField ? (_jsx(OptionalDataControlsField, { ...props, fieldPathId: childFieldPathId, schema: schema })) : undefined;
|
|
207
|
+
const templateProps = {
|
|
208
|
+
// getDisplayLabel() always returns false for object types, so just check the `uiOptions.label`
|
|
209
|
+
title: uiOptions.label === false ? '' : templateTitle,
|
|
210
|
+
description: uiOptions.label === false ? undefined : description,
|
|
211
|
+
properties: orderedProperties.map((name) => {
|
|
212
|
+
const addedByAdditionalProperties = has(schema, [PROPERTIES_KEY, name, ADDITIONAL_PROPERTY_FLAG]);
|
|
213
|
+
const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[name];
|
|
214
|
+
const hidden = getUiOptions(fieldUiSchema).widget === 'hidden';
|
|
215
|
+
const content = (_jsx(ObjectFieldProperty, { propertyName: name, required: isRequired(schema, name), schema: get(schema, [PROPERTIES_KEY, name], {}), uiSchema: fieldUiSchema, errorSchema: get(errorSchema, name), fieldPathId: childFieldPathId, formData: get(formData, name), handleKeyRename: handleKeyRename, handleRemoveProperty: handleRemoveProperty, addedByAdditionalProperties: addedByAdditionalProperties, onChange: onChange, onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError }, addedByAdditionalProperties ? `${name}-${formDataHash}` : name));
|
|
216
|
+
return {
|
|
217
|
+
content,
|
|
218
|
+
name,
|
|
219
|
+
readonly,
|
|
220
|
+
disabled,
|
|
221
|
+
required,
|
|
222
|
+
hidden,
|
|
223
|
+
};
|
|
224
|
+
}),
|
|
225
|
+
readonly,
|
|
226
|
+
disabled,
|
|
227
|
+
required,
|
|
228
|
+
fieldPathId,
|
|
229
|
+
uiSchema,
|
|
230
|
+
errorSchema,
|
|
231
|
+
schema,
|
|
232
|
+
formData,
|
|
233
|
+
registry,
|
|
234
|
+
optionalDataControl,
|
|
235
|
+
className: renderOptionalField ? 'rjsf-optional-object-field' : undefined,
|
|
236
|
+
};
|
|
237
|
+
return _jsx(Template, { ...templateProps, onAddProperty: onAddProperty });
|
|
237
238
|
}
|
|
238
|
-
export default ObjectField;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FieldProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
|
|
2
|
+
/** The `OptionalDataControlsField` component is used to render the optional data controls for the field associated
|
|
3
|
+
* with the given props.
|
|
4
|
+
*
|
|
5
|
+
* @param props - The `FieldProps` for this template
|
|
6
|
+
*/
|
|
7
|
+
export default function OptionalDataControlsField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): "" | import("react/jsx-runtime").JSX.Element | undefined;
|
|
8
|
+
//# sourceMappingURL=OptionalDataControlsField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OptionalDataControlsField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/OptionalDataControlsField.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,eAAe,EAOf,UAAU,EACV,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,4DA4D3B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getSchemaType, getTemplate, getUiOptions, isFormDataAvailable, optionalControlsId, TranslatableString, } from '@rjsf/utils';
|
|
3
|
+
/** The `OptionalDataControlsField` component is used to render the optional data controls for the field associated
|
|
4
|
+
* with the given props.
|
|
5
|
+
*
|
|
6
|
+
* @param props - The `FieldProps` for this template
|
|
7
|
+
*/
|
|
8
|
+
export default function OptionalDataControlsField(props) {
|
|
9
|
+
const { schema, uiSchema = {}, formData, disabled = false, readonly = false, onChange, errorSchema, fieldPathId, registry, } = props;
|
|
10
|
+
const { globalUiOptions = {}, schemaUtils, translateString } = registry;
|
|
11
|
+
const uiOptions = getUiOptions(uiSchema, globalUiOptions);
|
|
12
|
+
const OptionalDataControlsTemplate = getTemplate('OptionalDataControlsTemplate', registry, uiOptions);
|
|
13
|
+
const hasFormData = isFormDataAvailable(formData);
|
|
14
|
+
let id;
|
|
15
|
+
let label;
|
|
16
|
+
let onAddClick;
|
|
17
|
+
let onRemoveClick;
|
|
18
|
+
if (disabled || readonly) {
|
|
19
|
+
id = optionalControlsId(fieldPathId, 'Msg');
|
|
20
|
+
label = hasFormData ? undefined : translateString(TranslatableString.OptionalObjectEmptyMsg);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
const labelEnum = hasFormData ? TranslatableString.OptionalObjectRemove : TranslatableString.OptionalObjectAdd;
|
|
24
|
+
label = translateString(labelEnum);
|
|
25
|
+
if (hasFormData) {
|
|
26
|
+
id = optionalControlsId(fieldPathId, 'Remove');
|
|
27
|
+
onRemoveClick = () => onChange(undefined, fieldPathId.path, errorSchema);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
id = optionalControlsId(fieldPathId, 'Add');
|
|
31
|
+
onAddClick = () => {
|
|
32
|
+
// If it has form data, store an empty object, otherwise get the default form state and use it
|
|
33
|
+
let newFormData = schemaUtils.getDefaultFormState(schema, formData, 'excludeObjectChildren');
|
|
34
|
+
if (newFormData === undefined) {
|
|
35
|
+
// If new form data ended up being undefined, and we have pushed the add button we need to actually add data
|
|
36
|
+
newFormData = getSchemaType(schema) === 'array' ? [] : {};
|
|
37
|
+
}
|
|
38
|
+
onChange(newFormData, fieldPathId.path, errorSchema);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return (label && (_jsx(OptionalDataControlsTemplate, { id: id, registry: registry, schema: schema, uiSchema: uiSchema, label: label, onAddClick: onAddClick, onRemoveClick: onRemoveClick })));
|
|
43
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/SchemaField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAiB,MAAM,OAAO,CAAC;AAC9D,OAAO,
|
|
1
|
+
{"version":3,"file":"SchemaField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/SchemaField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAiB,MAAM,OAAO,CAAC;AAC9D,OAAO,EAQL,UAAU,EAEV,eAAe,EAQf,UAAU,EAGV,gBAAgB,EAIjB,MAAM,aAAa,CAAC;AAgSrB;;GAEG;AACH,cAAM,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,CAAE,SAAQ,SAAS,CACpH,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CACpB;IACC,qBAAqB,CAAC,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAS9D,MAAM;CAGP;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, Component } from 'react';
|
|
3
|
-
import { ADDITIONAL_PROPERTY_FLAG,
|
|
3
|
+
import { ADDITIONAL_PROPERTY_FLAG, ANY_OF_KEY, descriptionId, getSchemaType, getTemplate, getUiOptions, ID_KEY, isFormDataAvailable, ONE_OF_KEY, shouldRender, shouldRenderOptionalField, toFieldPathId, UI_OPTIONS_KEY, } from '@rjsf/utils';
|
|
4
4
|
import isObject from 'lodash-es/isObject.js';
|
|
5
5
|
import omit from 'lodash-es/omit.js';
|
|
6
6
|
/** The map of component type to FieldName */
|
|
@@ -19,13 +19,12 @@ const COMPONENT_TYPES = {
|
|
|
19
19
|
*
|
|
20
20
|
* @param schema - The schema from which to obtain the type
|
|
21
21
|
* @param uiOptions - The UI Options that may affect the component decision
|
|
22
|
-
* @param idSchema - The id that is passed to the `UnsupportedFieldTemplate`
|
|
23
22
|
* @param registry - The registry from which fields and templates are obtained
|
|
24
23
|
* @returns - The `Field` component that is used to render the actual field data
|
|
25
24
|
*/
|
|
26
|
-
function getFieldComponent(schema, uiOptions,
|
|
25
|
+
function getFieldComponent(schema, uiOptions, registry) {
|
|
27
26
|
const field = uiOptions.field;
|
|
28
|
-
const { fields
|
|
27
|
+
const { fields } = registry;
|
|
29
28
|
if (typeof field === 'function') {
|
|
30
29
|
return field;
|
|
31
30
|
}
|
|
@@ -44,12 +43,7 @@ function getFieldComponent(schema, uiOptions, idSchema, registry) {
|
|
|
44
43
|
if (!componentName && (schema.anyOf || schema.oneOf)) {
|
|
45
44
|
return () => null;
|
|
46
45
|
}
|
|
47
|
-
return componentName in fields
|
|
48
|
-
? fields[componentName]
|
|
49
|
-
: () => {
|
|
50
|
-
const UnsupportedFieldTemplate = getTemplate('UnsupportedFieldTemplate', registry, uiOptions);
|
|
51
|
-
return (_jsx(UnsupportedFieldTemplate, { schema: schema, idSchema: idSchema, reason: translateString(TranslatableString.UnknownFieldType, [String(schema.type)]), registry: registry }));
|
|
52
|
-
};
|
|
46
|
+
return componentName in fields ? fields[componentName] : fields['FallbackField'];
|
|
53
47
|
}
|
|
54
48
|
/** The `SchemaFieldRender` component is the work-horse of react-jsonschema-form, determining what kind of real field to
|
|
55
49
|
* render based on the `schema`, `uiSchema` and all the other props. It also deals with rendering the `anyOf` and
|
|
@@ -58,24 +52,24 @@ function getFieldComponent(schema, uiOptions, idSchema, registry) {
|
|
|
58
52
|
* @param props - The `FieldProps` for this component
|
|
59
53
|
*/
|
|
60
54
|
function SchemaFieldRender(props) {
|
|
61
|
-
const { schema: _schema,
|
|
62
|
-
const {
|
|
55
|
+
const { schema: _schema, fieldPathId, uiSchema, formData, errorSchema, name, onChange, onKeyRename, onKeyRenameBlur, onRemoveProperty, required = false, registry, wasPropertyKeyModified = false, } = props;
|
|
56
|
+
const { schemaUtils, globalFormOptions, globalUiOptions, fields } = registry;
|
|
57
|
+
const { AnyOfField: _AnyOfField, OneOfField: _OneOfField } = fields;
|
|
63
58
|
const uiOptions = getUiOptions(uiSchema, globalUiOptions);
|
|
64
59
|
const FieldTemplate = getTemplate('FieldTemplate', registry, uiOptions);
|
|
65
60
|
const DescriptionFieldTemplate = getTemplate('DescriptionFieldTemplate', registry, uiOptions);
|
|
66
61
|
const FieldHelpTemplate = getTemplate('FieldHelpTemplate', registry, uiOptions);
|
|
67
62
|
const FieldErrorTemplate = getTemplate('FieldErrorTemplate', registry, uiOptions);
|
|
68
63
|
const schema = schemaUtils.retrieveSchema(_schema, formData);
|
|
69
|
-
const fieldId =
|
|
70
|
-
const idSchema = mergeObjects(schemaUtils.toIdSchema(schema, fieldId, formData, idPrefix, idSeparator), _idSchema);
|
|
64
|
+
const fieldId = fieldPathId[ID_KEY];
|
|
71
65
|
/** Intermediary `onChange` handler for field components that will inject the `id` of the current field into the
|
|
72
66
|
* `onChange` chain if it is not already being provided from a deeper level in the hierarchy
|
|
73
67
|
*/
|
|
74
|
-
const handleFieldComponentChange = useCallback((formData, newErrorSchema, id) => {
|
|
68
|
+
const handleFieldComponentChange = useCallback((formData, path, newErrorSchema, id) => {
|
|
75
69
|
const theId = id || fieldId;
|
|
76
|
-
return onChange(formData, newErrorSchema, theId);
|
|
70
|
+
return onChange(formData, path, newErrorSchema, theId);
|
|
77
71
|
}, [fieldId, onChange]);
|
|
78
|
-
const FieldComponent = getFieldComponent(schema, uiOptions,
|
|
72
|
+
const FieldComponent = getFieldComponent(schema, uiOptions, registry);
|
|
79
73
|
const disabled = Boolean(uiOptions.disabled ?? props.disabled);
|
|
80
74
|
const readonly = Boolean(uiOptions.readonly ?? (props.readonly || props.schema.readOnly || schema.readOnly));
|
|
81
75
|
const uiSchemaHideError = uiOptions.hideError;
|
|
@@ -85,15 +79,44 @@ function SchemaFieldRender(props) {
|
|
|
85
79
|
if (Object.keys(schema).length === 0) {
|
|
86
80
|
return null;
|
|
87
81
|
}
|
|
88
|
-
|
|
82
|
+
let displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
83
|
+
/** If the schema `anyOf` or 'oneOf' can be rendered as a select control, don't render the selection and let
|
|
84
|
+
* `StringField` component handle rendering unless there is a field override and that field replaces the any or one of
|
|
85
|
+
*/
|
|
86
|
+
const isReplacingAnyOrOneOf = uiOptions.field && uiOptions.fieldReplacesAnyOrOneOf === true;
|
|
87
|
+
let XxxOfField;
|
|
88
|
+
let XxxOfOptions;
|
|
89
|
+
// When rendering the `XxxOfField` we'll need to change the fieldPathId of the main component, remembering the
|
|
90
|
+
// fieldPathId of the children for the ObjectField and ArrayField
|
|
91
|
+
let fieldPathIdProps = { fieldPathId };
|
|
92
|
+
if ((ANY_OF_KEY in schema || ONE_OF_KEY in schema) && !isReplacingAnyOrOneOf && !schemaUtils.isSelect(schema)) {
|
|
93
|
+
if (schema[ANY_OF_KEY]) {
|
|
94
|
+
XxxOfField = _AnyOfField;
|
|
95
|
+
XxxOfOptions = schema[ANY_OF_KEY].map((_schema) => schemaUtils.retrieveSchema(isObject(_schema) ? _schema : {}, formData));
|
|
96
|
+
}
|
|
97
|
+
else if (schema[ONE_OF_KEY]) {
|
|
98
|
+
XxxOfField = _OneOfField;
|
|
99
|
+
XxxOfOptions = schema[ONE_OF_KEY].map((_schema) => schemaUtils.retrieveSchema(isObject(_schema) ? _schema : {}, formData));
|
|
100
|
+
}
|
|
101
|
+
// When the anyOf/oneOf is an optional data control render AND it does not have form data, hide the label
|
|
102
|
+
const isOptionalRender = shouldRenderOptionalField(registry, schema, required, uiSchema);
|
|
103
|
+
const hasFormData = isFormDataAvailable(formData);
|
|
104
|
+
displayLabel = displayLabel && (!isOptionalRender || hasFormData);
|
|
105
|
+
fieldPathIdProps = {
|
|
106
|
+
childFieldPathId: fieldPathId,
|
|
107
|
+
// The main FieldComponent will add `XxxOf` onto the fieldPathId to avoid duplication with the rendering of the
|
|
108
|
+
// same FieldComponent by the `XxxOfField`
|
|
109
|
+
fieldPathId: toFieldPathId('XxxOf', globalFormOptions, fieldPathId),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
89
112
|
const { __errors, ...fieldErrorSchema } = errorSchema || {};
|
|
90
113
|
// See #439: uiSchema: Don't pass consumed class names or style to child components
|
|
91
114
|
const fieldUiSchema = omit(uiSchema, ['ui:classNames', 'classNames', 'ui:style']);
|
|
92
115
|
if (UI_OPTIONS_KEY in fieldUiSchema) {
|
|
93
116
|
fieldUiSchema[UI_OPTIONS_KEY] = omit(fieldUiSchema[UI_OPTIONS_KEY], ['classNames', 'style']);
|
|
94
117
|
}
|
|
95
|
-
const field = (_jsx(FieldComponent, { ...props, onChange: handleFieldComponentChange,
|
|
96
|
-
const id =
|
|
118
|
+
const field = (_jsx(FieldComponent, { ...props, onChange: handleFieldComponentChange, ...fieldPathIdProps, schema: schema, uiSchema: fieldUiSchema, disabled: disabled, readonly: readonly, hideError: hideError, autofocus: autofocus, errorSchema: fieldErrorSchema, rawErrors: __errors }));
|
|
119
|
+
const id = fieldPathId[ID_KEY];
|
|
97
120
|
// If this schema has a title defined, but the user has set a new key/label, retain their input.
|
|
98
121
|
let label;
|
|
99
122
|
if (wasPropertyKeyModified) {
|
|
@@ -115,12 +138,12 @@ function SchemaFieldRender(props) {
|
|
|
115
138
|
if (uiOptions.classNames) {
|
|
116
139
|
classNames.push(uiOptions.classNames);
|
|
117
140
|
}
|
|
118
|
-
const helpComponent = (_jsx(FieldHelpTemplate, { help: help,
|
|
141
|
+
const helpComponent = (_jsx(FieldHelpTemplate, { help: help, fieldPathId: fieldPathId, schema: schema, uiSchema: uiSchema, hasErrors: !hideError && __errors && __errors.length > 0, registry: registry }));
|
|
119
142
|
/*
|
|
120
143
|
* AnyOf/OneOf errors handled by child schema
|
|
121
144
|
* unless it can be rendered as select control
|
|
122
145
|
*/
|
|
123
|
-
const errorsComponent = hideError || (
|
|
146
|
+
const errorsComponent = hideError || (XxxOfField && !schemaUtils.isSelect(schema)) ? undefined : (_jsx(FieldErrorTemplate, { errors: __errors, errorSchema: errorSchema, fieldPathId: fieldPathId, schema: schema, uiSchema: uiSchema, registry: registry }));
|
|
124
147
|
const fieldProps = {
|
|
125
148
|
description: (_jsx(DescriptionFieldTemplate, { id: descriptionId(id), description: description, schema: schema, uiSchema: uiSchema, registry: registry })),
|
|
126
149
|
rawDescription: description,
|
|
@@ -132,8 +155,9 @@ function SchemaFieldRender(props) {
|
|
|
132
155
|
label,
|
|
133
156
|
hidden,
|
|
134
157
|
onChange,
|
|
135
|
-
|
|
136
|
-
|
|
158
|
+
onKeyRename,
|
|
159
|
+
onKeyRenameBlur,
|
|
160
|
+
onRemoveProperty,
|
|
137
161
|
required,
|
|
138
162
|
disabled,
|
|
139
163
|
readonly,
|
|
@@ -141,23 +165,21 @@ function SchemaFieldRender(props) {
|
|
|
141
165
|
displayLabel,
|
|
142
166
|
classNames: classNames.join(' ').trim(),
|
|
143
167
|
style: uiOptions.style,
|
|
144
|
-
formContext,
|
|
145
168
|
formData,
|
|
146
169
|
schema,
|
|
147
170
|
uiSchema,
|
|
148
171
|
registry,
|
|
149
172
|
};
|
|
150
|
-
|
|
151
|
-
const _OneOfField = registry.fields.OneOfField;
|
|
152
|
-
const isReplacingAnyOrOneOf = uiSchema?.['ui:field'] && uiSchema?.['ui:fieldReplacesAnyOrOneOf'] === true;
|
|
153
|
-
return (_jsx(FieldTemplate, { ...fieldProps, children: _jsxs(_Fragment, { children: [field, schema.anyOf && !isReplacingAnyOrOneOf && !schemaUtils.isSelect(schema) && (_jsx(_AnyOfField, { name: name, disabled: disabled, readonly: readonly, hideError: hideError, errorSchema: errorSchema, formData: formData, formContext: formContext, idPrefix: idPrefix, idSchema: idSchema, idSeparator: idSeparator, onBlur: props.onBlur, onChange: props.onChange, onFocus: props.onFocus, options: schema.anyOf.map((_schema) => schemaUtils.retrieveSchema(isObject(_schema) ? _schema : {}, formData)), registry: registry, required: required, schema: schema, uiSchema: uiSchema })), schema.oneOf && !isReplacingAnyOrOneOf && !schemaUtils.isSelect(schema) && (_jsx(_OneOfField, { name: name, disabled: disabled, readonly: readonly, hideError: hideError, errorSchema: errorSchema, formData: formData, formContext: formContext, idPrefix: idPrefix, idSchema: idSchema, idSeparator: idSeparator, onBlur: props.onBlur, onChange: props.onChange, onFocus: props.onFocus, options: schema.oneOf.map((_schema) => schemaUtils.retrieveSchema(isObject(_schema) ? _schema : {}, formData)), registry: registry, required: required, schema: schema, uiSchema: uiSchema }))] }) }));
|
|
173
|
+
return (_jsx(FieldTemplate, { ...fieldProps, children: _jsxs(_Fragment, { children: [field, XxxOfField && (_jsx(XxxOfField, { name: name, disabled: disabled, readonly: readonly, hideError: hideError, errorSchema: errorSchema, formData: formData, fieldPathId: fieldPathId, onBlur: props.onBlur, onChange: props.onChange, onFocus: props.onFocus, options: XxxOfOptions, registry: registry, required: required, schema: schema, uiSchema: uiSchema }))] }) }));
|
|
154
174
|
}
|
|
155
175
|
/** The `SchemaField` component determines whether it is necessary to rerender the component based on any props changes
|
|
156
176
|
* and if so, calls the `SchemaFieldRender` component with the props.
|
|
157
177
|
*/
|
|
158
178
|
class SchemaField extends Component {
|
|
159
179
|
shouldComponentUpdate(nextProps) {
|
|
160
|
-
|
|
180
|
+
const { registry: { globalFormOptions }, } = this.props;
|
|
181
|
+
const { experimental_componentUpdateStrategy = 'customDeep' } = globalFormOptions;
|
|
182
|
+
return shouldRender(this, nextProps, this.state, experimental_componentUpdateStrategy);
|
|
161
183
|
}
|
|
162
184
|
render() {
|
|
163
185
|
return _jsx(SchemaFieldRender, { ...this.props });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StringField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/StringField.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StringField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/StringField.tsx"],"names":[],"mappings":"AACA,OAAO,EAKL,UAAU,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,iBAAS,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,EACpG,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,2CA6D3B;AAED,eAAe,WAAW,CAAC"}
|