@rjsf/core 6.6.2 → 6.7.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/LICENSE.md +201 -0
- package/dist/core.umd.js +274 -245
- package/dist/index.cjs +911 -873
- package/dist/index.cjs.map +4 -4
- package/dist/index.esm.js +702 -659
- package/dist/index.esm.js.map +4 -4
- package/lib/components/Form.d.ts +2 -2
- package/lib/components/Form.d.ts.map +1 -1
- package/lib/components/Form.js +30 -15
- package/lib/components/RichDescription.d.ts +1 -1
- package/lib/components/RichDescription.d.ts.map +1 -1
- package/lib/components/RichHelp.d.ts +1 -1
- package/lib/components/RichHelp.d.ts.map +1 -1
- package/lib/components/SchemaExamples.d.ts +1 -1
- package/lib/components/SchemaExamples.d.ts.map +1 -1
- package/lib/components/fields/ArrayField.d.ts +1 -1
- package/lib/components/fields/ArrayField.d.ts.map +1 -1
- package/lib/components/fields/BooleanField.d.ts +1 -1
- package/lib/components/fields/BooleanField.d.ts.map +1 -1
- package/lib/components/fields/CyclicSchemaField.d.ts +8 -0
- package/lib/components/fields/CyclicSchemaField.d.ts.map +1 -0
- package/lib/components/fields/CyclicSchemaField.js +21 -0
- package/lib/components/fields/FallbackField.d.ts +1 -1
- package/lib/components/fields/FallbackField.d.ts.map +1 -1
- package/lib/components/fields/LayoutGridField.d.ts +1 -1
- package/lib/components/fields/LayoutGridField.d.ts.map +1 -1
- package/lib/components/fields/LayoutHeaderField.d.ts +1 -1
- package/lib/components/fields/LayoutHeaderField.d.ts.map +1 -1
- package/lib/components/fields/LayoutMultiSchemaField.d.ts +1 -1
- package/lib/components/fields/LayoutMultiSchemaField.d.ts.map +1 -1
- package/lib/components/fields/MultiSchemaField.d.ts +1 -46
- package/lib/components/fields/MultiSchemaField.d.ts.map +1 -1
- package/lib/components/fields/MultiSchemaField.js +111 -135
- package/lib/components/fields/NumberField.d.ts +1 -1
- package/lib/components/fields/NumberField.d.ts.map +1 -1
- package/lib/components/fields/NumberField.js +1 -1
- package/lib/components/fields/ObjectField.d.ts +1 -1
- package/lib/components/fields/ObjectField.d.ts.map +1 -1
- package/lib/components/fields/ObjectField.js +2 -2
- package/lib/components/fields/OptionalDataControlsField.d.ts +1 -1
- package/lib/components/fields/OptionalDataControlsField.d.ts.map +1 -1
- package/lib/components/fields/SchemaField.d.ts +13 -7
- package/lib/components/fields/SchemaField.d.ts.map +1 -1
- package/lib/components/fields/SchemaField.js +37 -24
- package/lib/components/fields/StringField.d.ts +1 -1
- package/lib/components/fields/StringField.d.ts.map +1 -1
- package/lib/components/fields/index.d.ts.map +1 -1
- package/lib/components/fields/index.js +2 -0
- package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts +1 -1
- package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts.map +1 -1
- package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts +1 -1
- package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts.map +1 -1
- package/lib/components/templates/ArrayFieldItemTemplate.d.ts +1 -1
- package/lib/components/templates/ArrayFieldItemTemplate.d.ts.map +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/ArrayFieldTitleTemplate.d.ts +1 -1
- package/lib/components/templates/ArrayFieldTitleTemplate.d.ts.map +1 -1
- package/lib/components/templates/BaseInputTemplate.d.ts +1 -1
- package/lib/components/templates/BaseInputTemplate.d.ts.map +1 -1
- 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/IconButton.d.ts +6 -6
- package/lib/components/templates/ButtonTemplates/IconButton.d.ts.map +1 -1
- package/lib/components/templates/ButtonTemplates/SubmitButton.d.ts +1 -1
- package/lib/components/templates/ButtonTemplates/SubmitButton.d.ts.map +1 -1
- package/lib/components/templates/CyclicSchemaExpandTemplate.d.ts +7 -0
- package/lib/components/templates/CyclicSchemaExpandTemplate.d.ts.map +1 -0
- package/lib/components/templates/CyclicSchemaExpandTemplate.js +12 -0
- package/lib/components/templates/DescriptionField.d.ts +1 -1
- package/lib/components/templates/DescriptionField.d.ts.map +1 -1
- package/lib/components/templates/ErrorList.d.ts +1 -1
- package/lib/components/templates/ErrorList.d.ts.map +1 -1
- package/lib/components/templates/FallbackFieldTemplate.d.ts +1 -1
- package/lib/components/templates/FallbackFieldTemplate.d.ts.map +1 -1
- package/lib/components/templates/FieldErrorTemplate.d.ts +1 -1
- package/lib/components/templates/FieldErrorTemplate.d.ts.map +1 -1
- package/lib/components/templates/FieldHelpTemplate.d.ts +1 -1
- package/lib/components/templates/FieldHelpTemplate.d.ts.map +1 -1
- package/lib/components/templates/FieldTemplate/FieldTemplate.d.ts +1 -1
- package/lib/components/templates/FieldTemplate/FieldTemplate.d.ts.map +1 -1
- package/lib/components/templates/FieldTemplate/Label.d.ts +1 -1
- package/lib/components/templates/FieldTemplate/Label.d.ts.map +1 -1
- package/lib/components/templates/GridTemplate.d.ts +1 -1
- package/lib/components/templates/GridTemplate.d.ts.map +1 -1
- package/lib/components/templates/MultiSchemaFieldTemplate.d.ts +1 -1
- package/lib/components/templates/MultiSchemaFieldTemplate.d.ts.map +1 -1
- package/lib/components/templates/ObjectFieldTemplate.d.ts +1 -1
- package/lib/components/templates/ObjectFieldTemplate.d.ts.map +1 -1
- package/lib/components/templates/OptionalDataControlsTemplate.d.ts +1 -1
- package/lib/components/templates/OptionalDataControlsTemplate.d.ts.map +1 -1
- package/lib/components/templates/TitleField.d.ts +1 -1
- package/lib/components/templates/TitleField.d.ts.map +1 -1
- package/lib/components/templates/UnsupportedField.d.ts +1 -1
- package/lib/components/templates/UnsupportedField.d.ts.map +1 -1
- package/lib/components/templates/UnsupportedField.js +1 -1
- package/lib/components/templates/WrapIfAdditionalTemplate.d.ts +1 -1
- package/lib/components/templates/WrapIfAdditionalTemplate.d.ts.map +1 -1
- package/lib/components/templates/index.d.ts.map +1 -1
- package/lib/components/templates/index.js +2 -0
- package/lib/components/widgets/AltDateTimeWidget.d.ts +1 -1
- package/lib/components/widgets/AltDateTimeWidget.d.ts.map +1 -1
- package/lib/components/widgets/AltDateWidget.d.ts +1 -1
- package/lib/components/widgets/AltDateWidget.d.ts.map +1 -1
- package/lib/components/widgets/CheckboxWidget.d.ts +1 -1
- package/lib/components/widgets/CheckboxWidget.d.ts.map +1 -1
- 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 +2 -2
- package/lib/components/widgets/ColorWidget.d.ts +1 -1
- package/lib/components/widgets/ColorWidget.d.ts.map +1 -1
- package/lib/components/widgets/DateTimeWidget.d.ts +1 -1
- package/lib/components/widgets/DateTimeWidget.d.ts.map +1 -1
- package/lib/components/widgets/DateWidget.d.ts +1 -1
- package/lib/components/widgets/DateWidget.d.ts.map +1 -1
- package/lib/components/widgets/EmailWidget.d.ts +1 -1
- package/lib/components/widgets/EmailWidget.d.ts.map +1 -1
- package/lib/components/widgets/FileWidget.d.ts +1 -1
- package/lib/components/widgets/FileWidget.d.ts.map +1 -1
- package/lib/components/widgets/HiddenWidget.d.ts +1 -1
- package/lib/components/widgets/HiddenWidget.d.ts.map +1 -1
- package/lib/components/widgets/PasswordWidget.d.ts +1 -1
- package/lib/components/widgets/PasswordWidget.d.ts.map +1 -1
- 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/RangeWidget.d.ts +1 -1
- package/lib/components/widgets/RangeWidget.d.ts.map +1 -1
- package/lib/components/widgets/RatingWidget.d.ts +1 -1
- package/lib/components/widgets/RatingWidget.d.ts.map +1 -1
- 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 +9 -8
- package/lib/components/widgets/TextWidget.d.ts +1 -1
- package/lib/components/widgets/TextWidget.d.ts.map +1 -1
- 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 +3 -3
- package/lib/components/widgets/TimeWidget.d.ts +1 -1
- package/lib/components/widgets/TimeWidget.d.ts.map +1 -1
- package/lib/components/widgets/URLWidget.d.ts +1 -1
- package/lib/components/widgets/URLWidget.d.ts.map +1 -1
- package/lib/components/widgets/UpDownWidget.d.ts +1 -1
- package/lib/components/widgets/UpDownWidget.d.ts.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +28 -27
- package/src/components/Form.tsx +34 -15
- package/src/components/fields/CyclicSchemaField.tsx +40 -0
- package/src/components/fields/MultiSchemaField.tsx +201 -230
- package/src/components/fields/NumberField.tsx +1 -1
- package/src/components/fields/ObjectField.tsx +5 -2
- package/src/components/fields/SchemaField.tsx +46 -34
- package/src/components/fields/index.ts +2 -0
- package/src/components/templates/BaseInputTemplate.tsx +2 -5
- package/src/components/templates/CyclicSchemaExpandTemplate.tsx +31 -0
- package/src/components/templates/UnsupportedField.tsx +1 -1
- package/src/components/templates/index.ts +2 -0
- package/src/components/widgets/CheckboxesWidget.tsx +2 -2
- package/src/components/widgets/RadioWidget.tsx +2 -2
- package/src/components/widgets/SelectWidget.tsx +45 -30
- package/src/components/widgets/TextareaWidget.tsx +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { ANY_OF_KEY, deepEquals, ERRORS_KEY, getDiscriminatorFieldFromSchema, getTemplate, getUiOptions, getWidget, isFormDataAvailable, mergeSchemas, ONE_OF_KEY, shouldRenderOptionalField, TranslatableString, } from '@rjsf/utils';
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { ANY_OF_KEY, deepEquals, ERRORS_KEY, getDiscriminatorFieldFromSchema, getTemplate, getUiOptions, getWidget, hashObject, isFormDataAvailable, mergeSchemas, ONE_OF_KEY, shouldRenderOptionalField, TranslatableString, } from '@rjsf/utils';
|
|
4
4
|
import get from 'lodash-es/get.js';
|
|
5
5
|
import isEmpty from 'lodash-es/isEmpty.js';
|
|
6
6
|
import omit from 'lodash-es/omit.js';
|
|
@@ -9,85 +9,60 @@ import omit from 'lodash-es/omit.js';
|
|
|
9
9
|
*
|
|
10
10
|
* @param props - The `FieldProps` for this template
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
function AnyOfField(props) {
|
|
13
|
+
const { name, disabled = false, errorSchema = {}, formData, fieldPathId, onBlur, onChange, onFocus, options, readonly, registry, required = false, schema, uiSchema, } = props;
|
|
14
|
+
const { schemaUtils } = registry;
|
|
15
|
+
// Hash formData by value so the memo only invalidates when data actually changes, not on every
|
|
16
|
+
// new object reference. hashObject(undefined) throws, so null is used as the fallback.
|
|
17
|
+
const formDataHash = hashObject(formData ?? null);
|
|
18
|
+
// retrievedOptions is purely derived from options — useMemo handles re-derivation automatically
|
|
19
|
+
// when options, schemaUtils, or formData's value changes, with no render-phase dispatch needed.
|
|
20
|
+
const retrievedOptions = useMemo(() => options.map((opt) => schemaUtils.retrieveSchema(opt, formData)),
|
|
21
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps -- formDataHash is the value-stable proxy for formData
|
|
22
|
+
[options, schemaUtils, formDataHash]);
|
|
23
|
+
const [selectedOption, setSelectedOption] = useState(() => {
|
|
24
|
+
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
25
|
+
return schemaUtils.getClosestMatchingOption(formData, retrievedOptions, 0, discriminator);
|
|
26
|
+
});
|
|
13
27
|
/** Flag to skip the formData-change-driven option recalculation when the user just selected an option.
|
|
14
|
-
* Set to true in
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*/
|
|
18
|
-
skipNextOptionRecalculation = false;
|
|
19
|
-
/** Constructs an `AnyOfField` with the given `props` to initialize the initially selected option in state
|
|
20
|
-
*
|
|
21
|
-
* @param props - The `FieldProps` for this template
|
|
22
|
-
*/
|
|
23
|
-
constructor(props) {
|
|
24
|
-
super(props);
|
|
25
|
-
const { formData, options, registry: { schemaUtils }, } = this.props;
|
|
26
|
-
// cache the retrieved options in state in case they have $refs to save doing it later
|
|
27
|
-
const retrievedOptions = options.map((opt) => schemaUtils.retrieveSchema(opt, formData));
|
|
28
|
-
this.state = {
|
|
29
|
-
retrievedOptions,
|
|
30
|
-
selectedOption: this.getMatchingOption(0, formData, retrievedOptions),
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
/** React lifecycle method that is called when the props and/or state for this component is updated. It recomputes the
|
|
34
|
-
* currently selected option based on the overall `formData`
|
|
35
|
-
*
|
|
36
|
-
* @param prevProps - The previous `FieldProps` for this template
|
|
37
|
-
* @param prevState - The previous `AnyOfFieldState` for this template
|
|
28
|
+
* Set to true in onOptionChange (before onChange is called), consumed and reset in the update effect.
|
|
29
|
+
* This prevents the matching-option recalculation from overriding a user's explicit choice when
|
|
30
|
+
* getDefaultFormState populates undefined properties that make deepEquals see a false formData change.
|
|
38
31
|
*/
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
32
|
+
const skipNextOptionRecalculation = useRef(false);
|
|
33
|
+
const prevFormDataRef = useRef(formData);
|
|
34
|
+
const prevFieldIdRef = useRef(fieldPathId.$id);
|
|
35
|
+
// Mirrors componentDidUpdate: re-match selectedOption when formData changes on the same field.
|
|
36
|
+
// Runs after every render (no deps array) to compare against prev values stored in refs.
|
|
37
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const prevFormData = prevFormDataRef.current;
|
|
40
|
+
const prevFieldId = prevFieldIdRef.current;
|
|
41
|
+
prevFormDataRef.current = formData;
|
|
42
|
+
prevFieldIdRef.current = fieldPathId.$id;
|
|
43
|
+
if (!deepEquals(formData, prevFormData) && fieldPathId.$id === prevFieldId) {
|
|
44
|
+
if (skipNextOptionRecalculation.current) {
|
|
45
|
+
skipNextOptionRecalculation.current = false;
|
|
46
|
+
return;
|
|
52
47
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
newState = { selectedOption: matchingOption, retrievedOptions };
|
|
58
|
-
}
|
|
48
|
+
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
49
|
+
const matchingOption = schemaUtils.getClosestMatchingOption(formData, retrievedOptions, selectedOption, discriminator);
|
|
50
|
+
if (matchingOption !== selectedOption) {
|
|
51
|
+
setSelectedOption(matchingOption);
|
|
59
52
|
}
|
|
60
53
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.setState(newState);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/** Determines the best matching option for the given `formData` and `options`.
|
|
67
|
-
*
|
|
68
|
-
* @param formData - The new formData
|
|
69
|
-
* @param options - The list of options to choose from
|
|
70
|
-
* @return - The index of the `option` that best matches the `formData`
|
|
71
|
-
*/
|
|
72
|
-
getMatchingOption(selectedOption, formData, options) {
|
|
73
|
-
const { schema, registry: { schemaUtils }, } = this.props;
|
|
74
|
-
const discriminator = getDiscriminatorFieldFromSchema(schema);
|
|
75
|
-
const option = schemaUtils.getClosestMatchingOption(formData, options, selectedOption, discriminator);
|
|
76
|
-
return option;
|
|
77
|
-
}
|
|
54
|
+
});
|
|
55
|
+
const fieldId = `${fieldPathId.$id}${schema.oneOf ? '__oneof_select' : '__anyof_select'}`;
|
|
78
56
|
/** Callback handler to remember what the currently selected option is. In addition to that the `formData` is updated
|
|
79
57
|
* to remove properties that are not part of the newly selected option schema, and then the updated data is passed to
|
|
80
58
|
* the `onChange` handler.
|
|
81
59
|
*
|
|
82
60
|
* @param option - The new option value being selected
|
|
83
61
|
*/
|
|
84
|
-
onOptionChange = (option) => {
|
|
85
|
-
const { selectedOption, retrievedOptions } = this.state;
|
|
86
|
-
const { disabled = false, formData, onChange, readonly = false, registry, fieldPathId } = this.props;
|
|
62
|
+
const onOptionChange = useCallback((option) => {
|
|
87
63
|
if (disabled || readonly) {
|
|
88
64
|
return;
|
|
89
65
|
}
|
|
90
|
-
const { schemaUtils } = registry;
|
|
91
66
|
const intOption = option !== undefined ? parseInt(option, 10) : -1;
|
|
92
67
|
if (intOption === selectedOption) {
|
|
93
68
|
return;
|
|
@@ -100,79 +75,80 @@ class AnyOfField extends Component {
|
|
|
100
75
|
// so that only the root objects themselves are created without adding undefined children properties
|
|
101
76
|
newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, 'excludeObjectChildren');
|
|
102
77
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
78
|
+
setSelectedOption(intOption);
|
|
79
|
+
skipNextOptionRecalculation.current = true;
|
|
80
|
+
onChange(newFormData, fieldPathId.path, undefined, fieldId);
|
|
81
|
+
},
|
|
82
|
+
// setSelectedOption is stable (guaranteed by useState); skipNextOptionRecalculation is a ref
|
|
83
|
+
[selectedOption, retrievedOptions, disabled, readonly, schemaUtils, formData, fieldPathId, onChange, fieldId]);
|
|
84
|
+
const { widgets, fields, translateString, globalUiOptions } = registry;
|
|
85
|
+
const { SchemaField: SchemaFieldComponent } = fields;
|
|
86
|
+
const MultiSchemaFieldTemplate = getTemplate('MultiSchemaFieldTemplate', registry, globalUiOptions);
|
|
87
|
+
const isOptionalRender = shouldRenderOptionalField(registry, schema, required, uiSchema);
|
|
88
|
+
const hasFormData = isFormDataAvailable(formData);
|
|
89
|
+
const { widget = 'select', placeholder, autofocus, autocomplete, title = schema.title, ...uiOptions } = getUiOptions(uiSchema, globalUiOptions);
|
|
90
|
+
const Widget = getWidget({ type: 'number' }, widget, widgets);
|
|
91
|
+
const rawErrors = get(errorSchema, ERRORS_KEY, []);
|
|
92
|
+
const fieldErrorSchema = omit(errorSchema, [ERRORS_KEY]);
|
|
93
|
+
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
94
|
+
const option = selectedOption >= 0 ? retrievedOptions[selectedOption] || null : null;
|
|
95
|
+
let optionSchema;
|
|
96
|
+
if (option) {
|
|
97
|
+
const { required: schemaRequired, type: schemaType } = schema;
|
|
98
|
+
const parentProps = {};
|
|
99
|
+
if (schemaRequired) {
|
|
100
|
+
parentProps.required = schemaRequired;
|
|
101
|
+
}
|
|
102
|
+
// Propagate the parent schema type to options that don't define their own.
|
|
103
|
+
// This is necessary when the parent constrains the type (e.g. { type: 'string',
|
|
104
|
+
// oneOf: [{ pattern: '...' }, { pattern: '...' }] }) but the option sub-schemas
|
|
105
|
+
// omit the type — without it, getSchemaType returns undefined and the option
|
|
106
|
+
// renders as FallbackField instead of the correct widget (e.g. StringField).
|
|
107
|
+
if (schemaType !== undefined && !('type' in option)) {
|
|
108
|
+
parentProps.type = schemaType;
|
|
109
|
+
}
|
|
110
|
+
// Merge in all the non-oneOf/anyOf properties and also skip the special ADDITIONAL_PROPERTY_FLAG property
|
|
111
|
+
optionSchema = Object.keys(parentProps).length > 0 ? mergeSchemas(parentProps, option) : option;
|
|
111
112
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const { SchemaField: SchemaFieldComponent } = fields;
|
|
118
|
-
const MultiSchemaFieldTemplate = getTemplate('MultiSchemaFieldTemplate', registry, globalUiOptions);
|
|
119
|
-
const isOptionalRender = shouldRenderOptionalField(registry, schema, required, uiSchema);
|
|
120
|
-
const hasFormData = isFormDataAvailable(formData);
|
|
121
|
-
const { selectedOption, retrievedOptions } = this.state;
|
|
122
|
-
const { widget = 'select', placeholder, autofocus, autocomplete, title = schema.title, ...uiOptions } = getUiOptions(uiSchema, globalUiOptions);
|
|
123
|
-
const Widget = getWidget({ type: 'number' }, widget, widgets);
|
|
124
|
-
const rawErrors = get(errorSchema, ERRORS_KEY, []);
|
|
125
|
-
const fieldErrorSchema = omit(errorSchema, [ERRORS_KEY]);
|
|
126
|
-
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
127
|
-
const option = selectedOption >= 0 ? retrievedOptions[selectedOption] || null : null;
|
|
128
|
-
let optionSchema;
|
|
129
|
-
if (option) {
|
|
130
|
-
// merge top level required field
|
|
131
|
-
const { required: schemaRequired } = schema;
|
|
132
|
-
// Merge in all the non-oneOf/anyOf properties and also skip the special ADDITIONAL_PROPERTY_FLAG property
|
|
133
|
-
optionSchema = schemaRequired ? mergeSchemas({ required: schemaRequired }, option) : option;
|
|
113
|
+
// First we will check to see if there is an anyOf/oneOf override for the UI schema
|
|
114
|
+
let optionsUiSchema = [];
|
|
115
|
+
if (ONE_OF_KEY in schema && uiSchema && ONE_OF_KEY in uiSchema) {
|
|
116
|
+
if (Array.isArray(uiSchema[ONE_OF_KEY])) {
|
|
117
|
+
optionsUiSchema = uiSchema[ONE_OF_KEY];
|
|
134
118
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (Array.isArray(uiSchema[ONE_OF_KEY])) {
|
|
139
|
-
optionsUiSchema = uiSchema[ONE_OF_KEY];
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
// oxlint-disable-next-line no-console
|
|
143
|
-
console.warn(`uiSchema.oneOf is not an array for "${title || name}"`);
|
|
144
|
-
}
|
|
119
|
+
else {
|
|
120
|
+
// oxlint-disable-next-line no-console
|
|
121
|
+
console.warn(`uiSchema.oneOf is not an array for "${title || name}"`);
|
|
145
122
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
else {
|
|
151
|
-
// oxlint-disable-next-line no-console
|
|
152
|
-
console.warn(`uiSchema.anyOf is not an array for "${title || name}"`);
|
|
153
|
-
}
|
|
123
|
+
}
|
|
124
|
+
else if (ANY_OF_KEY in schema && uiSchema && ANY_OF_KEY in uiSchema) {
|
|
125
|
+
if (Array.isArray(uiSchema[ANY_OF_KEY])) {
|
|
126
|
+
optionsUiSchema = uiSchema[ANY_OF_KEY];
|
|
154
127
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
optionUiSchema = optionsUiSchema[selectedOption];
|
|
128
|
+
else {
|
|
129
|
+
// oxlint-disable-next-line no-console
|
|
130
|
+
console.warn(`uiSchema.anyOf is not an array for "${title || name}"`);
|
|
159
131
|
}
|
|
160
|
-
const translateEnum = title
|
|
161
|
-
? TranslatableString.TitleOptionPrefix
|
|
162
|
-
: TranslatableString.OptionPrefix;
|
|
163
|
-
const translateParams = title ? [title] : [];
|
|
164
|
-
const enumOptions = retrievedOptions.map((opt, index) => {
|
|
165
|
-
// Also see if there is an override title in the uiSchema for each option, otherwise use the title from the option
|
|
166
|
-
const { title: uiTitle = opt.title } = getUiOptions(optionsUiSchema[index]);
|
|
167
|
-
return {
|
|
168
|
-
label: uiTitle || translateString(translateEnum, translateParams.concat(String(index + 1))),
|
|
169
|
-
value: index,
|
|
170
|
-
};
|
|
171
|
-
});
|
|
172
|
-
const selector = !isOptionalRender || hasFormData ? (_jsx(Widget, { id: this.getFieldId(), name: `${name}${schema.oneOf ? '__oneof_select' : '__anyof_select'}`, schema: { type: 'number', default: 0 }, onChange: this.onOptionChange, onBlur: onBlur, onFocus: onFocus, disabled: disabled || isEmpty(enumOptions), multiple: false, rawErrors: rawErrors, errorSchema: fieldErrorSchema, value: selectedOption >= 0 ? selectedOption : undefined, options: { enumOptions, ...uiOptions }, registry: registry, placeholder: placeholder, autocomplete: autocomplete, autofocus: autofocus, label: title ?? name, hideLabel: !displayLabel, readonly: readonly })) : undefined;
|
|
173
|
-
const optionsSchemaField = (optionSchema && optionSchema.type !== 'null' && (_jsx(SchemaFieldComponent, { ...this.props, schema: optionSchema, uiSchema: optionUiSchema }))) ||
|
|
174
|
-
null;
|
|
175
|
-
return (_jsx(MultiSchemaFieldTemplate, { schema: schema, registry: registry, uiSchema: uiSchema, selector: selector, optionSchemaField: optionsSchemaField }));
|
|
176
132
|
}
|
|
133
|
+
// Then we pick the one that matches the selected option index, if one exists otherwise default to the main uiSchema
|
|
134
|
+
let optionUiSchema = uiSchema;
|
|
135
|
+
if (selectedOption >= 0 && optionsUiSchema.length > selectedOption) {
|
|
136
|
+
optionUiSchema = optionsUiSchema[selectedOption];
|
|
137
|
+
}
|
|
138
|
+
const translateEnum = title
|
|
139
|
+
? TranslatableString.TitleOptionPrefix
|
|
140
|
+
: TranslatableString.OptionPrefix;
|
|
141
|
+
const translateParams = title ? [title] : [];
|
|
142
|
+
const enumOptions = retrievedOptions.map((opt, index) => {
|
|
143
|
+
const { title: uiTitle = opt.title } = getUiOptions(optionsUiSchema[index]);
|
|
144
|
+
return {
|
|
145
|
+
label: uiTitle || translateString(translateEnum, translateParams.concat(String(index + 1))),
|
|
146
|
+
value: index,
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
const selector = !isOptionalRender || hasFormData ? (_jsx(Widget, { id: fieldId, name: `${name}${schema.oneOf ? '__oneof_select' : '__anyof_select'}`, schema: { type: 'number', default: 0 }, onChange: onOptionChange, onBlur: onBlur, onFocus: onFocus, disabled: disabled || isEmpty(enumOptions), multiple: false, rawErrors: rawErrors, errorSchema: fieldErrorSchema, value: selectedOption >= 0 ? selectedOption : undefined, options: { enumOptions, ...uiOptions }, registry: registry, placeholder: placeholder, autocomplete: autocomplete, autofocus: autofocus, label: title ?? name, hideLabel: !displayLabel, readonly: readonly })) : undefined;
|
|
150
|
+
const optionsSchemaField = (optionSchema && optionSchema.type !== 'null' && (_jsx(SchemaFieldComponent, { ...props, schema: optionSchema, uiSchema: optionUiSchema }))) ||
|
|
151
|
+
null;
|
|
152
|
+
return (_jsx(MultiSchemaFieldTemplate, { schema: schema, registry: registry, uiSchema: uiSchema, selector: selector, optionSchemaField: optionsSchemaField }));
|
|
177
153
|
}
|
|
178
154
|
export default AnyOfField;
|
|
@@ -16,6 +16,6 @@ import type { FieldProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '
|
|
|
16
16
|
* value cached in the state. If it matches the cached value, the cached
|
|
17
17
|
* value is passed to the input instead of the formData value
|
|
18
18
|
*/
|
|
19
|
-
declare function NumberField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): import("react
|
|
19
|
+
declare function NumberField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): import("react").JSX.Element;
|
|
20
20
|
export default NumberField;
|
|
21
21
|
//# sourceMappingURL=NumberField.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NumberField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/NumberField.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,UAAU,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAerB;;;;;;;;;;;;;;;;GAgBG;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
|
|
1
|
+
{"version":3,"file":"NumberField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/NumberField.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,UAAU,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAerB;;;;;;;;;;;;;;;;GAgBG;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,+BAgD3B;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -46,7 +46,7 @@ function NumberField(props) {
|
|
|
46
46
|
// Check that the value is a string (this can happen if the widget used is a
|
|
47
47
|
// <select>, due to an enum declaration etc) then, if the value ends in a
|
|
48
48
|
// trailing decimal point or multiple zeroes, strip the trailing values
|
|
49
|
-
const processed = typeof normalizedValue === 'string' &&
|
|
49
|
+
const processed = typeof normalizedValue === 'string' && trailingCharMatcherWithPrefix.exec(normalizedValue)
|
|
50
50
|
? asNumber(normalizedValue.replace(trailingCharMatcher, ''))
|
|
51
51
|
: asNumber(normalizedValue);
|
|
52
52
|
onChange(processed, path, errorSchema, id);
|
|
@@ -4,5 +4,5 @@ import type { FieldProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '
|
|
|
4
4
|
*
|
|
5
5
|
* @param props - The `FieldProps` for this template
|
|
6
6
|
*/
|
|
7
|
-
export default function ObjectField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): import("react
|
|
7
|
+
export default function ObjectField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): import("react").JSX.Element;
|
|
8
8
|
//# sourceMappingURL=ObjectField.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/ObjectField.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,UAAU,EACV,eAAe,
|
|
1
|
+
{"version":3,"file":"ObjectField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/ObjectField.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,UAAU,EACV,eAAe,EAIf,UAAU,EACV,gBAAgB,EACjB,MAAM,aAAa,CAAC;AA6LrB;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,EACnH,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,+BA8O3B"}
|
|
@@ -155,7 +155,7 @@ export default function ObjectField(props) {
|
|
|
155
155
|
apSchema = schemaUtils.retrieveSchema({ [REF_KEY]: apSchema[REF_KEY] }, formData);
|
|
156
156
|
type = apSchema.type;
|
|
157
157
|
constValue = apSchema.const;
|
|
158
|
-
defaultValue = apSchema
|
|
158
|
+
defaultValue = schemaUtils.getDefaultFormState(apSchema, defaultValue);
|
|
159
159
|
}
|
|
160
160
|
if (!type && (ANY_OF_KEY in apSchema || ONE_OF_KEY in apSchema)) {
|
|
161
161
|
type = 'object';
|
|
@@ -233,7 +233,7 @@ export default function ObjectField(props) {
|
|
|
233
233
|
title: uiOptions.label === false ? '' : templateTitle,
|
|
234
234
|
description: uiOptions.label === false ? undefined : description,
|
|
235
235
|
properties: orderedProperties.map((propertyName) => {
|
|
236
|
-
const addedByAdditionalProperties =
|
|
236
|
+
const addedByAdditionalProperties = Boolean(schema.properties?.[propertyName]?.[ADDITIONAL_PROPERTY_FLAG]);
|
|
237
237
|
const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[propertyName];
|
|
238
238
|
const hidden = getUiOptions(fieldUiSchema).widget === 'hidden';
|
|
239
239
|
const content = (_jsx(ObjectFieldProperty, { propertyName: propertyName, required: isRequired(schema, propertyName), schema: get(schema, [PROPERTIES_KEY, propertyName], {}), uiSchema: fieldUiSchema, errorSchema: get(errorSchema, [propertyName]), fieldPathId: childFieldPathId, formData: get(formData, [propertyName]), handleKeyRename: handleKeyRename, handleRemoveProperty: handleRemoveProperty, addedByAdditionalProperties: addedByAdditionalProperties, onChange: onChange, onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError }, getStableKey(propertyName)));
|
|
@@ -4,5 +4,5 @@ import type { FieldProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '
|
|
|
4
4
|
*
|
|
5
5
|
* @param props - The `FieldProps` for this template
|
|
6
6
|
*/
|
|
7
|
-
export default function OptionalDataControlsField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): "" | import("react
|
|
7
|
+
export default function OptionalDataControlsField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): "" | import("react").JSX.Element | undefined;
|
|
8
8
|
//# sourceMappingURL=OptionalDataControlsField.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptionalDataControlsField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/OptionalDataControlsField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EAEf,UAAU,EACV,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAUrB;;;;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,
|
|
1
|
+
{"version":3,"file":"OptionalDataControlsField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/OptionalDataControlsField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EAEf,UAAU,EACV,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAUrB;;;;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,gDA4D3B"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import { Component } from 'react';
|
|
2
1
|
import type { FieldProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
|
|
3
|
-
/** The `
|
|
4
|
-
*
|
|
2
|
+
/** The `SchemaFieldRender` component is the work-horse of react-jsonschema-form, determining what kind of real field to
|
|
3
|
+
* render based on the `schema`, `uiSchema` and all the other props. It also deals with rendering the `anyOf` and
|
|
4
|
+
* `oneOf` fields.
|
|
5
|
+
*
|
|
6
|
+
* @param props - The `FieldProps` for this component
|
|
5
7
|
*/
|
|
6
|
-
declare
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
declare function SchemaFieldRender<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): import("react").JSX.Element | null;
|
|
9
|
+
/** The `SchemaField` component wraps `SchemaFieldRender` with a custom memoization comparator that determines whether it is necessary to rerender the component based on any props changes
|
|
10
|
+
* using `experimental_componentUpdateStrategy`.
|
|
11
|
+
*
|
|
12
|
+
* The cast to `typeof SchemaFieldRender` preserves the generic type signature (<T, S, F>) for consumers,
|
|
13
|
+
* since React.memo's return type erases generic parameters.
|
|
14
|
+
*/
|
|
15
|
+
declare const SchemaField: typeof SchemaFieldRender;
|
|
10
16
|
export default SchemaField;
|
|
11
17
|
//# sourceMappingURL=SchemaField.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/SchemaField.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SchemaField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/SchemaField.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAKV,UAAU,EAEV,eAAe,EAGf,UAAU,EACV,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAgFrB;;;;;GAKG;AACH,iBAAS,iBAAiB,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,EAC1G,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,sCA+O3B;AAED;;;;;GAKG;AACH,QAAA,MAAM,WAAW,EAUA,OAAO,iBAAiB,CAAC;AAE1C,eAAe,WAAW,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback,
|
|
3
|
-
import { ADDITIONAL_PROPERTY_FLAG, ANY_OF_KEY, descriptionId, getSchemaType, getTemplate, getUiOptions, ID_KEY, isFormDataAvailable, ONE_OF_KEY, resolveUiSchema,
|
|
2
|
+
import { useCallback, memo } from 'react';
|
|
3
|
+
import { ADDITIONAL_PROPERTY_FLAG, ANY_OF_KEY, deepEquals, descriptionId, getSchemaType, getTemplate, getUiOptions, ID_KEY, isFormDataAvailable, ONE_OF_KEY, resolveUiSchema, RJSF_REF_CYCLE_KEY, shallowEquals, shouldRenderOptionalField, toFieldPathId, TranslatableString, 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 */
|
|
@@ -24,7 +24,7 @@ const COMPONENT_TYPES = {
|
|
|
24
24
|
*/
|
|
25
25
|
function getFieldComponent(schema, uiOptions, registry) {
|
|
26
26
|
const { field } = uiOptions;
|
|
27
|
-
const { fields } = registry;
|
|
27
|
+
const { fields, schemaUtils } = registry;
|
|
28
28
|
if (typeof field === 'function') {
|
|
29
29
|
return field;
|
|
30
30
|
}
|
|
@@ -38,9 +38,13 @@ function getFieldComponent(schema, uiOptions, registry) {
|
|
|
38
38
|
if (schemaId && schemaId in fields) {
|
|
39
39
|
componentName = schemaId;
|
|
40
40
|
}
|
|
41
|
-
// If the
|
|
42
|
-
//
|
|
43
|
-
|
|
41
|
+
// If the schema uses 'anyOf' or 'oneOf' and is not a pure select (all-constant options),
|
|
42
|
+
// let the MultiSchemaField component handle the form display entirely.
|
|
43
|
+
// ObjectField is excluded: it renders shared properties (defined at the parent schema
|
|
44
|
+
// level) alongside the XxxOfField option selector.
|
|
45
|
+
// All other field types — including primitives and arrays — have no shared renderable
|
|
46
|
+
// properties, so the outer FieldComponent would only produce a spurious duplicate input.
|
|
47
|
+
if ((schema.anyOf || schema.oneOf) && !schemaUtils.isSelect(schema) && componentName !== 'ObjectField') {
|
|
44
48
|
return () => null;
|
|
45
49
|
}
|
|
46
50
|
return componentName in fields ? fields[componentName] : fields.FallbackField;
|
|
@@ -54,14 +58,7 @@ function getFieldComponent(schema, uiOptions, registry) {
|
|
|
54
58
|
function SchemaFieldRender(props) {
|
|
55
59
|
const { schema: _schema, fieldPathId, uiSchema: _uiSchema, formData, errorSchema, name, onChange, onKeyRename, onKeyRenameBlur, onRemoveProperty, required = false, registry, wasPropertyKeyModified = false, } = props;
|
|
56
60
|
const { schemaUtils, globalFormOptions, globalUiOptions, fields } = registry;
|
|
57
|
-
const { AnyOfField: _AnyOfField, OneOfField: _OneOfField } = fields;
|
|
58
|
-
const uiSchema = resolveUiSchema(_schema, _uiSchema, registry);
|
|
59
|
-
const uiOptions = getUiOptions(uiSchema, globalUiOptions);
|
|
60
|
-
const FieldTemplate = getTemplate('FieldTemplate', registry, uiOptions);
|
|
61
|
-
const DescriptionFieldTemplate = getTemplate('DescriptionFieldTemplate', registry, uiOptions);
|
|
62
|
-
const FieldHelpTemplate = getTemplate('FieldHelpTemplate', registry, uiOptions);
|
|
63
|
-
const FieldErrorTemplate = getTemplate('FieldErrorTemplate', registry, uiOptions);
|
|
64
|
-
const schema = schemaUtils.retrieveSchema(_schema, formData);
|
|
61
|
+
const { AnyOfField: _AnyOfField, OneOfField: _OneOfField, CyclicSchemaField } = fields;
|
|
65
62
|
const fieldId = fieldPathId[ID_KEY];
|
|
66
63
|
/** Intermediary `onChange` handler for field components that will inject the `id` of the current field into the
|
|
67
64
|
* `onChange` chain if it is not already being provided from a deeper level in the hierarchy
|
|
@@ -70,6 +67,18 @@ function SchemaFieldRender(props) {
|
|
|
70
67
|
const theId = id || fieldId;
|
|
71
68
|
return onChange(newFormData, path, newErrorSchema, theId);
|
|
72
69
|
}, [fieldId, onChange]);
|
|
70
|
+
// Stop $ref cycles: when resolveAllReferences detects a repeated property $ref it tags the schema with this flag.
|
|
71
|
+
// The check must come after all hook calls to satisfy React's rules of hooks.
|
|
72
|
+
if (_schema[RJSF_REF_CYCLE_KEY]) {
|
|
73
|
+
return _jsx(CyclicSchemaField, { ...props });
|
|
74
|
+
}
|
|
75
|
+
const uiSchema = resolveUiSchema(_schema, _uiSchema, registry);
|
|
76
|
+
const uiOptions = getUiOptions(uiSchema, globalUiOptions);
|
|
77
|
+
const FieldTemplate = getTemplate('FieldTemplate', registry, uiOptions);
|
|
78
|
+
const DescriptionFieldTemplate = getTemplate('DescriptionFieldTemplate', registry, uiOptions);
|
|
79
|
+
const FieldHelpTemplate = getTemplate('FieldHelpTemplate', registry, uiOptions);
|
|
80
|
+
const FieldErrorTemplate = getTemplate('FieldErrorTemplate', registry, uiOptions);
|
|
81
|
+
const schema = schemaUtils.retrieveSchema(_schema, formData);
|
|
73
82
|
const FieldComponent = getFieldComponent(schema, uiOptions, registry);
|
|
74
83
|
const isDeprecated = Boolean(schema.deprecated);
|
|
75
84
|
const deprecatedHandling = isDeprecated ? (uiOptions.deprecatedHandling ?? 'label') : undefined;
|
|
@@ -179,17 +188,21 @@ function SchemaFieldRender(props) {
|
|
|
179
188
|
};
|
|
180
189
|
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 }))] }) }));
|
|
181
190
|
}
|
|
182
|
-
/** The `SchemaField` component determines whether it is necessary to rerender the component based on any props changes
|
|
183
|
-
*
|
|
191
|
+
/** The `SchemaField` component wraps `SchemaFieldRender` with a custom memoization comparator that determines whether it is necessary to rerender the component based on any props changes
|
|
192
|
+
* using `experimental_componentUpdateStrategy`.
|
|
193
|
+
*
|
|
194
|
+
* The cast to `typeof SchemaFieldRender` preserves the generic type signature (<T, S, F>) for consumers,
|
|
195
|
+
* since React.memo's return type erases generic parameters.
|
|
184
196
|
*/
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return shouldRender(this, nextProps, this.state, experimental_componentUpdateStrategy);
|
|
197
|
+
const SchemaField = memo(SchemaFieldRender, (prevProps, nextProps) => {
|
|
198
|
+
const { experimental_componentUpdateStrategy = 'customDeep' } = nextProps.registry.globalFormOptions;
|
|
199
|
+
if (experimental_componentUpdateStrategy === 'always') {
|
|
200
|
+
return false; // always re-render — never consider props equal
|
|
190
201
|
}
|
|
191
|
-
|
|
192
|
-
return
|
|
202
|
+
if (experimental_componentUpdateStrategy === 'shallow') {
|
|
203
|
+
return shallowEquals(prevProps, nextProps);
|
|
193
204
|
}
|
|
194
|
-
|
|
205
|
+
// default: 'customDeep'
|
|
206
|
+
return deepEquals(prevProps, nextProps);
|
|
207
|
+
});
|
|
195
208
|
export default SchemaField;
|
|
@@ -3,6 +3,6 @@ import type { FieldProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '
|
|
|
3
3
|
*
|
|
4
4
|
* @param props - The `FieldProps` for this template
|
|
5
5
|
*/
|
|
6
|
-
declare function StringField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): import("react
|
|
6
|
+
declare function StringField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): import("react").JSX.Element;
|
|
7
7
|
export default StringField;
|
|
8
8
|
//# sourceMappingURL=StringField.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StringField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/StringField.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAe,MAAM,aAAa,CAAC;AAG1G;;;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
|
|
1
|
+
{"version":3,"file":"StringField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/StringField.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAe,MAAM,aAAa,CAAC;AAG1G;;;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,+BA4D3B;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/fields/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,eAAe,EAAE,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/fields/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,eAAe,EAAE,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAiB5G,iBAAS,MAAM,CACb,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,KAC5B,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAmB/B;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ArrayField from './ArrayField.js';
|
|
2
2
|
import BooleanField from './BooleanField.js';
|
|
3
|
+
import CyclicSchemaField from './CyclicSchemaField.js';
|
|
3
4
|
import FallbackField from './FallbackField.js';
|
|
4
5
|
import LayoutGridField from './LayoutGridField.js';
|
|
5
6
|
import LayoutHeaderField from './LayoutHeaderField.js';
|
|
@@ -17,6 +18,7 @@ function fields() {
|
|
|
17
18
|
ArrayField: ArrayField,
|
|
18
19
|
// ArrayField falls back to SchemaField if ArraySchemaField is not defined, which it isn't by default
|
|
19
20
|
BooleanField,
|
|
21
|
+
CyclicSchemaField,
|
|
20
22
|
FallbackField,
|
|
21
23
|
LayoutGridField,
|
|
22
24
|
LayoutHeaderField,
|
|
@@ -4,5 +4,5 @@ import type { ArrayFieldDescriptionProps, FormContextType, RJSFSchema, StrictRJS
|
|
|
4
4
|
*
|
|
5
5
|
* @param props - The `ArrayFieldDescriptionProps` for the component
|
|
6
6
|
*/
|
|
7
|
-
export default function ArrayFieldDescriptionTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldDescriptionProps<T, S, F>): import("react
|
|
7
|
+
export default function ArrayFieldDescriptionTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldDescriptionProps<T, S, F>): import("react").JSX.Element | null;
|
|
8
8
|
//# sourceMappingURL=ArrayFieldDescriptionTemplate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrayFieldDescriptionTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/templates/ArrayFieldDescriptionTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG7G;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,6BAA6B,CACnD,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,0BAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"ArrayFieldDescriptionTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/templates/ArrayFieldDescriptionTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG7G;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,6BAA6B,CACnD,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,0BAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,sCAqB3C"}
|
|
@@ -4,5 +4,5 @@ import type { ArrayFieldItemButtonsTemplateProps, FormContextType, RJSFSchema, S
|
|
|
4
4
|
*
|
|
5
5
|
* @param props - The `ArrayFieldItemButtonsTemplateProps` props for the component
|
|
6
6
|
*/
|
|
7
|
-
export default function ArrayFieldItemButtonsTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldItemButtonsTemplateProps<T, S, F>): import("react
|
|
7
|
+
export default function ArrayFieldItemButtonsTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldItemButtonsTemplateProps<T, S, F>): import("react").JSX.Element;
|
|
8
8
|
//# sourceMappingURL=ArrayFieldItemButtonsTemplate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrayFieldItemButtonsTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/templates/ArrayFieldItemButtonsTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kCAAkC,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGrH;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,6BAA6B,CACnD,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,kCAAkC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"ArrayFieldItemButtonsTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/templates/ArrayFieldItemButtonsTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kCAAkC,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGrH;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,6BAA6B,CACnD,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,kCAAkC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,+BA8DnD"}
|
|
@@ -3,5 +3,5 @@ import type { ArrayFieldItemTemplateProps, FormContextType, RJSFSchema, StrictRJ
|
|
|
3
3
|
*
|
|
4
4
|
* @param props - The `ArrayFieldItemTemplateProps` props for the component
|
|
5
5
|
*/
|
|
6
|
-
export default function ArrayFieldItemTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldItemTemplateProps<T, S, F>): import("react
|
|
6
|
+
export default function ArrayFieldItemTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldItemTemplateProps<T, S, F>): import("react").JSX.Element;
|
|
7
7
|
//# sourceMappingURL=ArrayFieldItemTemplate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrayFieldItemTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/templates/ArrayFieldItemTemplate.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG9G;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAC5C,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,2BAA2B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"ArrayFieldItemTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/templates/ArrayFieldItemTemplate.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG9G;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAC5C,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,2BAA2B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,+BA6B5C"}
|
|
@@ -3,5 +3,5 @@ import type { ArrayFieldTemplateProps, FormContextType, RJSFSchema, StrictRJSFSc
|
|
|
3
3
|
*
|
|
4
4
|
* @param props - The `ArrayFieldTemplateProps` props for the component
|
|
5
5
|
*/
|
|
6
|
-
export default function ArrayFieldTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldTemplateProps<T, S, F>): import("react
|
|
6
|
+
export default function ArrayFieldTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldTemplateProps<T, S, F>): import("react").JSX.Element;
|
|
7
7
|
//# sourceMappingURL=ArrayFieldTemplate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrayFieldTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/templates/ArrayFieldTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG1G;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACxC,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"ArrayFieldTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/templates/ArrayFieldTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG1G;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACxC,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,+BAgExC"}
|
|
@@ -4,5 +4,5 @@ import type { ArrayFieldTitleProps, FormContextType, RJSFSchema, StrictRJSFSchem
|
|
|
4
4
|
*
|
|
5
5
|
* @param props - The `ArrayFieldTitleProps` for the component
|
|
6
6
|
*/
|
|
7
|
-
export default function ArrayFieldTitleTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldTitleProps<T, S, F>): import("react
|
|
7
|
+
export default function ArrayFieldTitleTemplate<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: ArrayFieldTitleProps<T, S, F>): import("react").JSX.Element | null;
|
|
8
8
|
//# sourceMappingURL=ArrayFieldTitleTemplate.d.ts.map
|