@rjsf/core 6.0.0-beta.13 → 6.0.0-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core.umd.js +243 -125
- package/dist/index.esm.js +285 -161
- package/dist/index.esm.js.map +3 -3
- package/dist/index.js +309 -186
- package/dist/index.js.map +3 -3
- package/lib/components/Form.d.ts +44 -13
- package/lib/components/Form.d.ts.map +1 -1
- package/lib/components/Form.js +84 -27
- package/lib/components/fields/ArrayField.d.ts +14 -4
- package/lib/components/fields/ArrayField.d.ts.map +1 -1
- package/lib/components/fields/ArrayField.js +73 -27
- package/lib/components/fields/BooleanField.d.ts.map +1 -1
- package/lib/components/fields/BooleanField.js +6 -1
- package/lib/components/fields/LayoutGridField.d.ts +19 -1
- package/lib/components/fields/LayoutGridField.d.ts.map +1 -1
- package/lib/components/fields/LayoutGridField.js +62 -12
- package/lib/components/fields/LayoutMultiSchemaField.d.ts.map +1 -1
- package/lib/components/fields/LayoutMultiSchemaField.js +2 -1
- package/lib/components/fields/MultiSchemaField.d.ts.map +1 -1
- package/lib/components/fields/MultiSchemaField.js +2 -1
- package/lib/components/fields/NullField.js +3 -3
- package/lib/components/fields/NumberField.js +2 -2
- package/lib/components/fields/ObjectField.d.ts +2 -2
- package/lib/components/fields/ObjectField.d.ts.map +1 -1
- package/lib/components/fields/ObjectField.js +16 -19
- package/lib/components/fields/SchemaField.js +2 -2
- package/lib/components/fields/StringField.d.ts.map +1 -1
- package/lib/components/fields/StringField.js +6 -1
- package/lib/components/widgets/AltDateWidget.d.ts.map +1 -1
- package/lib/components/widgets/AltDateWidget.js +15 -18
- package/lib/components/widgets/CheckboxesWidget.js +2 -2
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -12
- package/src/components/Form.tsx +99 -25
- package/src/components/fields/ArrayField.tsx +74 -28
- package/src/components/fields/BooleanField.tsx +10 -1
- package/src/components/fields/LayoutGridField.tsx +69 -11
- package/src/components/fields/LayoutMultiSchemaField.tsx +2 -1
- package/src/components/fields/MultiSchemaField.tsx +2 -1
- package/src/components/fields/NullField.tsx +3 -3
- package/src/components/fields/NumberField.tsx +2 -2
- package/src/components/fields/ObjectField.tsx +16 -26
- package/src/components/fields/SchemaField.tsx +2 -2
- package/src/components/fields/StringField.tsx +10 -1
- package/src/components/widgets/AltDateWidget.tsx +20 -22
- package/src/components/widgets/CheckboxesWidget.tsx +2 -2
package/lib/components/Form.d.ts
CHANGED
|
@@ -214,12 +214,27 @@ export interface IChangeEvent<T = any, S extends StrictRJSFSchema = RJSFSchema,
|
|
|
214
214
|
/** The status of the form when submitted */
|
|
215
215
|
status?: 'submitted';
|
|
216
216
|
}
|
|
217
|
+
/** The definition of a pending change that will be processed in the `onChange` handler
|
|
218
|
+
*/
|
|
219
|
+
interface PendingChange<T> {
|
|
220
|
+
/** The path into the formData/errorSchema at which the `newValue`/`newErrorSchema` will be set */
|
|
221
|
+
path?: (number | string)[];
|
|
222
|
+
/** The new value to set into the formData */
|
|
223
|
+
newValue?: T;
|
|
224
|
+
/** The new errors to be set into the errorSchema, if any */
|
|
225
|
+
newErrorSchema?: ErrorSchema<T>;
|
|
226
|
+
/** The optional id of the field for which the change is being made */
|
|
227
|
+
id?: string;
|
|
228
|
+
}
|
|
217
229
|
/** The `Form` component renders the outer form and all the fields defined in the `schema` */
|
|
218
230
|
export default class Form<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> extends Component<FormProps<T, S, F>, FormState<T, S, F>> {
|
|
219
231
|
/** The ref used to hold the `form` element, this needs to be `any` because `tagName` or `_internalFormWrapper` can
|
|
220
232
|
* provide any possible type here
|
|
221
233
|
*/
|
|
222
234
|
formElement: RefObject<any>;
|
|
235
|
+
/** The list of pending changes
|
|
236
|
+
*/
|
|
237
|
+
pendingChanges: PendingChange<T>[];
|
|
223
238
|
/** Constructs the `Form` from the `props`. Will setup the initial state from the props. It will also call the
|
|
224
239
|
* `onChange` handler if the initially provided `formData` is modified to add missing default values as part of the
|
|
225
240
|
* state construction.
|
|
@@ -280,7 +295,7 @@ export default class Form<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
280
295
|
* @param formDataChangedFields - The changed fields of `formData`
|
|
281
296
|
* @returns - The new state for the `Form`
|
|
282
297
|
*/
|
|
283
|
-
getStateFromProps(props: FormProps<T, S, F>, inputFormData?: T, retrievedSchema?: S, isSchemaChanged?: boolean, formDataChangedFields?: string[]): FormState<T, S, F>;
|
|
298
|
+
getStateFromProps(props: FormProps<T, S, F>, inputFormData?: T, retrievedSchema?: S, isSchemaChanged?: boolean, formDataChangedFields?: string[], skipLiveValidate?: boolean): FormState<T, S, F>;
|
|
284
299
|
/** React lifecycle method that is used to determine whether component should be updated.
|
|
285
300
|
*
|
|
286
301
|
* @param nextProps - The next version of the props
|
|
@@ -298,7 +313,8 @@ export default class Form<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
298
313
|
*
|
|
299
314
|
* @param formData - The new form data to validate
|
|
300
315
|
* @param schema - The schema used to validate against
|
|
301
|
-
* @param altSchemaUtils - The alternate schemaUtils to use for validation
|
|
316
|
+
* @param [altSchemaUtils] - The alternate schemaUtils to use for validation
|
|
317
|
+
* @param [retrievedSchema] - An optionally retrieved schema for per
|
|
302
318
|
*/
|
|
303
319
|
validate(formData: T | undefined, schema?: S, altSchemaUtils?: SchemaUtilsType<T, S, F>, retrievedSchema?: S): ValidationData<T>;
|
|
304
320
|
/** Renders any errors contained in the `state` in using the `ErrorList`, if not disabled by `showErrorList`. */
|
|
@@ -321,19 +337,33 @@ export default class Form<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
321
337
|
* @returns The `formData` after omitting extra data
|
|
322
338
|
*/
|
|
323
339
|
omitExtraData: (formData?: T) => T | undefined;
|
|
324
|
-
|
|
325
|
-
/** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
|
|
326
|
-
* `formData` along with a new `ErrorSchema`. It will first update the `formData` with any missing default fields and
|
|
327
|
-
* then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not
|
|
328
|
-
* in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
|
|
329
|
-
* updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
|
|
330
|
-
* callback will be called if specified with the updated state.
|
|
340
|
+
/** Filtering errors based on your retrieved schema to only show errors for properties in the selected branch.
|
|
331
341
|
*
|
|
332
|
-
* @param
|
|
333
|
-
* @param
|
|
334
|
-
* @param
|
|
342
|
+
* @param schemaErrors - The schema errors to filter
|
|
343
|
+
* @param [resolvedSchema] - An optionally resolved schema to use for performance reasons
|
|
344
|
+
* @param [formData] - The formData to help filter errors
|
|
345
|
+
* @private
|
|
335
346
|
*/
|
|
336
|
-
|
|
347
|
+
private filterErrorsBasedOnSchema;
|
|
348
|
+
/** Pushes the given change information into the `pendingChanges` array and then calls `processPendingChanges()` if
|
|
349
|
+
* the array only contains a single pending change.
|
|
350
|
+
*
|
|
351
|
+
* @param newValue - The new form data from a change to a field
|
|
352
|
+
* @param [path] - The path to the change into which to set the formData
|
|
353
|
+
* @param [newErrorSchema] - The new `ErrorSchema` based on the field change
|
|
354
|
+
* @param [id] - The id of the field that caused the change
|
|
355
|
+
*/
|
|
356
|
+
onChange: (newValue: T | undefined, path?: (number | string)[], newErrorSchema?: ErrorSchema<T>, id?: string) => void;
|
|
357
|
+
/** Function to handle changes made to a field in the `Form`. This handler gets the first change from the
|
|
358
|
+
* `pendingChanges` list, containing the `newValue` for the `formData` and the `path` at which the `newValue` is to be
|
|
359
|
+
* updated, along with a new, optional `ErrorSchema` for that same `path` and potentially the `id` of the field being
|
|
360
|
+
* changed. It will first update the `formData` with any missing default fields and then, if `omitExtraData` and
|
|
361
|
+
* `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not in a form field. Then, the
|
|
362
|
+
* resulting `formData` will be validated if required. The state will be updated with the new updated (potentially
|
|
363
|
+
* filtered) `formData`, any errors that resulted from validation. Finally the `onChange` callback will be called, if
|
|
364
|
+
* specified, with the updated state and the `processPendingChange()` function is called again.
|
|
365
|
+
*/
|
|
366
|
+
processPendingChange(): void;
|
|
337
367
|
/**
|
|
338
368
|
* If the retrievedSchema has changed the new retrievedSchema is returned.
|
|
339
369
|
* Otherwise, the old retrievedSchema is returned to persist reference.
|
|
@@ -404,4 +434,5 @@ export default class Form<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
404
434
|
*/
|
|
405
435
|
render(): import("react/jsx-runtime").JSX.Element;
|
|
406
436
|
}
|
|
437
|
+
export {};
|
|
407
438
|
//# sourceMappingURL=Form.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../../src/components/Form.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAa,MAAM,OAAO,CAAC;AAChG,OAAO,EAEL,eAAe,EAEf,WAAW,EACX,gBAAgB,EAChB,eAAe,EAKf,QAAQ,EAIR,UAAU,EACV,gBAAgB,EAChB,QAAQ,EACR,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,mBAAmB,EAEnB,eAAe,EAGf,aAAa,EAEb,QAAQ,EAGR,cAAc,EAEd,aAAa,EACb,qCAAqC,EACrC,6BAA6B,EAG9B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../../src/components/Form.tsx"],"names":[],"mappings":"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"}
|
package/lib/components/Form.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Component, createRef } from 'react';
|
|
3
3
|
import { createSchemaUtils, deepEquals, getChangedFields, getTemplate, getUiOptions, isObject, mergeObjects, NAME_KEY, RJSF_ADDITIONAL_PROPERTIES_FLAG, shouldRender, SUBMIT_BTN_OPTIONS_KEY, toErrorList, UI_GLOBAL_OPTIONS_KEY, UI_OPTIONS_KEY, validationDataMerge, createErrorHandler, unwrapErrorHandler, } from '@rjsf/utils';
|
|
4
|
+
import _cloneDeep from 'lodash-es/cloneDeep.js';
|
|
4
5
|
import _forEach from 'lodash-es/forEach.js';
|
|
5
6
|
import _get from 'lodash-es/get.js';
|
|
6
7
|
import _isEmpty from 'lodash-es/isEmpty.js';
|
|
7
8
|
import _isNil from 'lodash-es/isNil.js';
|
|
8
9
|
import _pick from 'lodash-es/pick.js';
|
|
10
|
+
import _set from 'lodash-es/set.js';
|
|
9
11
|
import _toPath from 'lodash-es/toPath.js';
|
|
10
12
|
import getDefaultRegistry from '../getDefaultRegistry.js';
|
|
11
13
|
/** The `Form` component renders the outer form and all the fields defined in the `schema` */
|
|
@@ -14,6 +16,9 @@ export default class Form extends Component {
|
|
|
14
16
|
* provide any possible type here
|
|
15
17
|
*/
|
|
16
18
|
formElement;
|
|
19
|
+
/** The list of pending changes
|
|
20
|
+
*/
|
|
21
|
+
pendingChanges = [];
|
|
17
22
|
/** Constructs the `Form` from the `props`. Will setup the initial state from the props. It will also call the
|
|
18
23
|
* `onChange` handler if the initially provided `formData` is modified to add missing default values as part of the
|
|
19
24
|
* state construction.
|
|
@@ -51,16 +56,23 @@ export default class Form extends Component {
|
|
|
51
56
|
*/
|
|
52
57
|
getSnapshotBeforeUpdate(prevProps, prevState) {
|
|
53
58
|
if (!deepEquals(this.props, prevProps)) {
|
|
59
|
+
// Compare the previous props formData against the current props formData
|
|
54
60
|
const formDataChangedFields = getChangedFields(this.props.formData, prevProps.formData);
|
|
61
|
+
// Compare the current props formData against the current state's formData to determine if the new props were the
|
|
62
|
+
// result of the onChange from the existing state formData
|
|
63
|
+
const stateDataChangedFields = getChangedFields(this.props.formData, this.state.formData);
|
|
55
64
|
const isSchemaChanged = !deepEquals(prevProps.schema, this.props.schema);
|
|
56
65
|
// When formData is not an object, getChangedFields returns an empty array.
|
|
57
66
|
// In this case, deepEquals is most needed to check again.
|
|
58
67
|
const isFormDataChanged = formDataChangedFields.length > 0 || !deepEquals(prevProps.formData, this.props.formData);
|
|
68
|
+
const isStateDataChanged = stateDataChangedFields.length > 0 || !deepEquals(this.state.formData, this.props.formData);
|
|
59
69
|
const nextState = this.getStateFromProps(this.props, this.props.formData,
|
|
60
70
|
// If the `schema` has changed, we need to update the retrieved schema.
|
|
61
71
|
// Or if the `formData` changes, for example in the case of a schema with dependencies that need to
|
|
62
72
|
// match one of the subSchemas, the retrieved schema must be updated.
|
|
63
|
-
isSchemaChanged || isFormDataChanged ? undefined : this.state.retrievedSchema, isSchemaChanged, formDataChangedFields
|
|
73
|
+
isSchemaChanged || isFormDataChanged ? undefined : this.state.retrievedSchema, isSchemaChanged, formDataChangedFields,
|
|
74
|
+
// Skip live validation for this request if no form data has changed from the last state
|
|
75
|
+
!isStateDataChanged);
|
|
64
76
|
const shouldUpdate = !deepEquals(nextState, prevState);
|
|
65
77
|
return { nextState, shouldUpdate };
|
|
66
78
|
}
|
|
@@ -100,14 +112,14 @@ export default class Form extends Component {
|
|
|
100
112
|
* @param formDataChangedFields - The changed fields of `formData`
|
|
101
113
|
* @returns - The new state for the `Form`
|
|
102
114
|
*/
|
|
103
|
-
getStateFromProps(props, inputFormData, retrievedSchema, isSchemaChanged = false, formDataChangedFields = []) {
|
|
115
|
+
getStateFromProps(props, inputFormData, retrievedSchema, isSchemaChanged = false, formDataChangedFields = [], skipLiveValidate = false) {
|
|
104
116
|
const state = this.state || {};
|
|
105
117
|
const schema = 'schema' in props ? props.schema : this.props.schema;
|
|
106
118
|
const validator = 'validator' in props ? props.validator : this.props.validator;
|
|
107
119
|
const uiSchema = ('uiSchema' in props ? props.uiSchema : this.props.uiSchema) || {};
|
|
108
120
|
const edit = typeof inputFormData !== 'undefined';
|
|
109
121
|
const liveValidate = 'liveValidate' in props ? props.liveValidate : this.props.liveValidate;
|
|
110
|
-
const mustValidate = edit && !props.noValidate && liveValidate;
|
|
122
|
+
const mustValidate = edit && !props.noValidate && liveValidate && !skipLiveValidate;
|
|
111
123
|
const experimental_defaultFormStateBehavior = 'experimental_defaultFormStateBehavior' in props
|
|
112
124
|
? props.experimental_defaultFormStateBehavior
|
|
113
125
|
: this.props.experimental_defaultFormStateBehavior;
|
|
@@ -209,8 +221,7 @@ export default class Form extends Component {
|
|
|
209
221
|
let customValidateErrors = {};
|
|
210
222
|
if (typeof customValidate === 'function') {
|
|
211
223
|
const errorHandler = customValidate(prevFormData, createErrorHandler(prevFormData), uiSchema);
|
|
212
|
-
|
|
213
|
-
customValidateErrors = userErrorSchema;
|
|
224
|
+
customValidateErrors = unwrapErrorHandler(errorHandler);
|
|
214
225
|
}
|
|
215
226
|
return customValidateErrors;
|
|
216
227
|
}
|
|
@@ -219,7 +230,8 @@ export default class Form extends Component {
|
|
|
219
230
|
*
|
|
220
231
|
* @param formData - The new form data to validate
|
|
221
232
|
* @param schema - The schema used to validate against
|
|
222
|
-
* @param altSchemaUtils - The alternate schemaUtils to use for validation
|
|
233
|
+
* @param [altSchemaUtils] - The alternate schemaUtils to use for validation
|
|
234
|
+
* @param [retrievedSchema] - An optionally retrieved schema for per
|
|
223
235
|
*/
|
|
224
236
|
validate(formData, schema = this.state.schema, altSchemaUtils, retrievedSchema) {
|
|
225
237
|
const schemaUtils = altSchemaUtils ? altSchemaUtils : this.state.schemaUtils;
|
|
@@ -302,10 +314,15 @@ export default class Form extends Component {
|
|
|
302
314
|
const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
|
|
303
315
|
const pathSchema = schemaUtils.toPathSchema(retrievedSchema, '', formData);
|
|
304
316
|
const fieldNames = this.getFieldNames(pathSchema, formData);
|
|
305
|
-
|
|
306
|
-
return newFormData;
|
|
317
|
+
return this.getUsedFormData(formData, fieldNames);
|
|
307
318
|
};
|
|
308
|
-
|
|
319
|
+
/** Filtering errors based on your retrieved schema to only show errors for properties in the selected branch.
|
|
320
|
+
*
|
|
321
|
+
* @param schemaErrors - The schema errors to filter
|
|
322
|
+
* @param [resolvedSchema] - An optionally resolved schema to use for performance reasons
|
|
323
|
+
* @param [formData] - The formData to help filter errors
|
|
324
|
+
* @private
|
|
325
|
+
*/
|
|
309
326
|
filterErrorsBasedOnSchema(schemaErrors, resolvedSchema, formData) {
|
|
310
327
|
const { retrievedSchema, schemaUtils } = this.state;
|
|
311
328
|
const _retrievedSchema = resolvedSchema ?? retrievedSchema;
|
|
@@ -347,23 +364,47 @@ export default class Form extends Component {
|
|
|
347
364
|
};
|
|
348
365
|
return filterNilOrEmptyErrors(filteredErrors, prevCustomValidateErrors);
|
|
349
366
|
}
|
|
350
|
-
/**
|
|
351
|
-
*
|
|
352
|
-
* then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not
|
|
353
|
-
* in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
|
|
354
|
-
* updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
|
|
355
|
-
* callback will be called if specified with the updated state.
|
|
367
|
+
/** Pushes the given change information into the `pendingChanges` array and then calls `processPendingChanges()` if
|
|
368
|
+
* the array only contains a single pending change.
|
|
356
369
|
*
|
|
357
|
-
* @param
|
|
358
|
-
* @param
|
|
359
|
-
* @param
|
|
370
|
+
* @param newValue - The new form data from a change to a field
|
|
371
|
+
* @param [path] - The path to the change into which to set the formData
|
|
372
|
+
* @param [newErrorSchema] - The new `ErrorSchema` based on the field change
|
|
373
|
+
* @param [id] - The id of the field that caused the change
|
|
374
|
+
*/
|
|
375
|
+
onChange = (newValue, path, newErrorSchema, id) => {
|
|
376
|
+
this.pendingChanges.push({ newValue, path, newErrorSchema, id });
|
|
377
|
+
if (this.pendingChanges.length === 1) {
|
|
378
|
+
this.processPendingChange();
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
/** Function to handle changes made to a field in the `Form`. This handler gets the first change from the
|
|
382
|
+
* `pendingChanges` list, containing the `newValue` for the `formData` and the `path` at which the `newValue` is to be
|
|
383
|
+
* updated, along with a new, optional `ErrorSchema` for that same `path` and potentially the `id` of the field being
|
|
384
|
+
* changed. It will first update the `formData` with any missing default fields and then, if `omitExtraData` and
|
|
385
|
+
* `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not in a form field. Then, the
|
|
386
|
+
* resulting `formData` will be validated if required. The state will be updated with the new updated (potentially
|
|
387
|
+
* filtered) `formData`, any errors that resulted from validation. Finally the `onChange` callback will be called, if
|
|
388
|
+
* specified, with the updated state and the `processPendingChange()` function is called again.
|
|
360
389
|
*/
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
390
|
+
processPendingChange() {
|
|
391
|
+
if (this.pendingChanges.length === 0) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
const { newValue, path, id } = this.pendingChanges[0];
|
|
395
|
+
let { newErrorSchema } = this.pendingChanges[0];
|
|
396
|
+
const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange, idPrefix = '' } = this.props;
|
|
397
|
+
const { formData: oldFormData, schemaUtils, schema, errorSchema } = this.state;
|
|
398
|
+
const isRootPath = !path || path.length === 0 || (path.length === 1 && path[0] === idPrefix);
|
|
364
399
|
let retrievedSchema = this.state.retrievedSchema;
|
|
400
|
+
let formData = isRootPath ? newValue : _cloneDeep(oldFormData);
|
|
365
401
|
if (isObject(formData) || Array.isArray(formData)) {
|
|
366
|
-
|
|
402
|
+
if (!isRootPath) {
|
|
403
|
+
// If the newValue is not on the root path, then set it into the form data
|
|
404
|
+
_set(formData, path, newValue);
|
|
405
|
+
}
|
|
406
|
+
// Pass true to skip live validation in `getStateFromProps()` since we will do it a bit later
|
|
407
|
+
const newState = this.getStateFromProps(this.props, formData, undefined, undefined, undefined, true);
|
|
367
408
|
formData = newState.formData;
|
|
368
409
|
retrievedSchema = newState.retrievedSchema;
|
|
369
410
|
}
|
|
@@ -376,7 +417,15 @@ export default class Form extends Component {
|
|
|
376
417
|
formData: newFormData,
|
|
377
418
|
};
|
|
378
419
|
}
|
|
379
|
-
if
|
|
420
|
+
// First update the value in the newErrorSchema in a copy of the old error schema if it was specified and the path
|
|
421
|
+
// is not the root
|
|
422
|
+
if (newErrorSchema && !isRootPath) {
|
|
423
|
+
const errorSchemaCopy = _cloneDeep(errorSchema);
|
|
424
|
+
_set(errorSchemaCopy, path, newErrorSchema);
|
|
425
|
+
newErrorSchema = errorSchemaCopy;
|
|
426
|
+
}
|
|
427
|
+
// If there are pending changes in the queue, skip live validation since it will happen with the last change
|
|
428
|
+
if (mustValidate && this.pendingChanges.length === 1) {
|
|
380
429
|
const schemaValidation = this.validate(newFormData, schema, schemaUtils, retrievedSchema);
|
|
381
430
|
let errors = schemaValidation.errors;
|
|
382
431
|
let errorSchema = schemaValidation.errorSchema;
|
|
@@ -401,6 +450,7 @@ export default class Form extends Component {
|
|
|
401
450
|
};
|
|
402
451
|
}
|
|
403
452
|
else if (!noValidate && newErrorSchema) {
|
|
453
|
+
// Merging 'newErrorSchema' into 'errorSchema' to display the custom raised errors.
|
|
404
454
|
const errorSchema = extraErrors
|
|
405
455
|
? mergeObjects(newErrorSchema, extraErrors, 'preventDuplicates')
|
|
406
456
|
: newErrorSchema;
|
|
@@ -410,8 +460,15 @@ export default class Form extends Component {
|
|
|
410
460
|
errors: toErrorList(errorSchema),
|
|
411
461
|
};
|
|
412
462
|
}
|
|
413
|
-
this.setState(state, () =>
|
|
414
|
-
|
|
463
|
+
this.setState(state, () => {
|
|
464
|
+
if (onChange) {
|
|
465
|
+
onChange({ ...this.state, ...state }, id);
|
|
466
|
+
}
|
|
467
|
+
// Now remove the change we just completed and call this again
|
|
468
|
+
this.pendingChanges.shift();
|
|
469
|
+
this.processPendingChange();
|
|
470
|
+
});
|
|
471
|
+
}
|
|
415
472
|
/**
|
|
416
473
|
* If the retrievedSchema has changed the new retrievedSchema is returned.
|
|
417
474
|
* Otherwise, the old retrievedSchema is returned to persist reference.
|
|
@@ -643,7 +700,7 @@ export default class Form extends Component {
|
|
|
643
700
|
* needed along with the submit button or any children of the form.
|
|
644
701
|
*/
|
|
645
702
|
render() {
|
|
646
|
-
const { children, id, idPrefix, idSeparator, className = '', tagName, name, method, target, action, autoComplete, enctype, acceptCharset, noHtml5Validate = false, disabled, readonly, formContext, showErrorList = 'top', _internalFormWrapper, } = this.props;
|
|
703
|
+
const { children, id, idPrefix = '', idSeparator, className = '', tagName, name, method, target, action, autoComplete, enctype, acceptCharset, noHtml5Validate = false, disabled, readonly, formContext, showErrorList = 'top', _internalFormWrapper, } = this.props;
|
|
647
704
|
const { schema, uiSchema, formData, errorSchema, idSchema } = this.state;
|
|
648
705
|
const registry = this.getRegistry();
|
|
649
706
|
const { SchemaField: _SchemaField } = registry.fields;
|
|
@@ -658,6 +715,6 @@ export default class Form extends Component {
|
|
|
658
715
|
submitOptions = { ...submitOptions, props: { ...submitOptions.props, disabled: true } };
|
|
659
716
|
}
|
|
660
717
|
const submitUiSchema = { [UI_OPTIONS_KEY]: { [SUBMIT_BTN_OPTIONS_KEY]: submitOptions } };
|
|
661
|
-
return (_jsxs(FormTag, { className: className ? className : 'rjsf', id: id, name: name, method: method, target: target, action: action, autoComplete: autoComplete, encType: enctype, acceptCharset: acceptCharset, noValidate: noHtml5Validate, onSubmit: this.onSubmit, as: as, ref: this.formElement, children: [showErrorList === 'top' && this.renderErrors(registry), _jsx(_SchemaField, { name:
|
|
718
|
+
return (_jsxs(FormTag, { className: className ? className : 'rjsf', id: id, name: name, method: method, target: target, action: action, autoComplete: autoComplete, encType: enctype, acceptCharset: acceptCharset, noValidate: noHtml5Validate, onSubmit: this.onSubmit, as: as, ref: this.formElement, children: [showErrorList === 'top' && this.renderErrors(registry), _jsx(_SchemaField, { name: idPrefix, schema: schema, uiSchema: uiSchema, errorSchema: errorSchema, idSchema: idSchema, idPrefix: idPrefix, idSeparator: idSeparator, formContext: formContext, formData: formData, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, registry: registry, disabled: disabled, readonly: readonly }), children ? children : _jsx(SubmitButton, { uiSchema: submitUiSchema, registry: registry }), showErrorList === 'bottom' && this.renderErrors(registry)] }));
|
|
662
719
|
}
|
|
663
720
|
}
|
|
@@ -106,9 +106,19 @@ declare class ArrayField<T = any, S extends StrictRJSFSchema = RJSFSchema, F ext
|
|
|
106
106
|
*
|
|
107
107
|
* @param index - The index of the item being changed
|
|
108
108
|
*/
|
|
109
|
-
onChangeForIndex: (index: number) => (value: any, newErrorSchema?: ErrorSchema<T>, id?: string) => void;
|
|
109
|
+
onChangeForIndex: (index: number) => (value: any, path?: (number | string)[], newErrorSchema?: ErrorSchema<T>, id?: string) => void;
|
|
110
110
|
/** Callback handler used to change the value for a checkbox */
|
|
111
111
|
onSelectChange: (value: any) => void;
|
|
112
|
+
/** Helper method to compute item UI schema for both normal and fixed arrays
|
|
113
|
+
* Handles both static object and dynamic function cases
|
|
114
|
+
*
|
|
115
|
+
* @param uiSchema - The parent UI schema containing items definition
|
|
116
|
+
* @param item - The item data
|
|
117
|
+
* @param index - The index of the item
|
|
118
|
+
* @param formContext - The form context
|
|
119
|
+
* @returns The computed UI schema for the item
|
|
120
|
+
*/
|
|
121
|
+
private computeItemUiSchema;
|
|
112
122
|
/** Renders the `ArrayField` depending on the specific needs of the schema and uischema elements
|
|
113
123
|
*/
|
|
114
124
|
render(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -143,7 +153,7 @@ declare class ArrayField<T = any, S extends StrictRJSFSchema = RJSFSchema, F ext
|
|
|
143
153
|
canMoveDown: boolean;
|
|
144
154
|
itemSchema: S;
|
|
145
155
|
itemData: T[];
|
|
146
|
-
itemUiSchema: UiSchema<T[], S, F
|
|
156
|
+
itemUiSchema: UiSchema<T[], S, F> | undefined;
|
|
147
157
|
itemIdSchema: IdSchema<T[]>;
|
|
148
158
|
itemErrorSchema?: ErrorSchema<T[]>;
|
|
149
159
|
autofocus?: boolean;
|
|
@@ -170,7 +180,7 @@ declare class ArrayField<T = any, S extends StrictRJSFSchema = RJSFSchema, F ext
|
|
|
170
180
|
onReorderClick: (index: number, newIndex: number) => (event: MouseEvent<HTMLButtonElement>) => void;
|
|
171
181
|
registry: import("@rjsf/utils").Registry<T[], S, F>;
|
|
172
182
|
schema: S;
|
|
173
|
-
uiSchema: UiSchema<T[], S, F
|
|
183
|
+
uiSchema: UiSchema<T[], S, F> | undefined;
|
|
174
184
|
};
|
|
175
185
|
className: string;
|
|
176
186
|
disabled: boolean | undefined;
|
|
@@ -181,7 +191,7 @@ declare class ArrayField<T = any, S extends StrictRJSFSchema = RJSFSchema, F ext
|
|
|
181
191
|
readonly: boolean | undefined;
|
|
182
192
|
registry: import("@rjsf/utils").Registry<T[], S, F>;
|
|
183
193
|
schema: S;
|
|
184
|
-
uiSchema: UiSchema<T[], S, F
|
|
194
|
+
uiSchema: UiSchema<T[], S, F> | undefined;
|
|
185
195
|
};
|
|
186
196
|
}
|
|
187
197
|
/** `ArrayField` is `React.ComponentType<FieldProps<T[], S, F>>` (necessarily) but the `registry` requires things to be a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrayField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/ArrayField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EASL,WAAW,EACX,UAAU,EACV,eAAe,EACf,QAAQ,EACR,UAAU,EACV,gBAAgB,EAEhB,QAAQ,EAET,MAAM,aAAa,CAAC;AAOrB,mEAAmE;AACnE,KAAK,iBAAiB,CAAC,CAAC,IAAI;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC;AAErD,4DAA4D;AAC5D,KAAK,eAAe,CAAC,CAAC,IAAI;IACxB,mCAAmC;IACnC,aAAa,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;IACtC,0EAA0E;IAC1E,oBAAoB,EAAE,OAAO,CAAC;CAC/B,CAAC;AAmCF;;GAEG;AACH,cAAM,UAAU,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,CAAE,SAAQ,SAAS,CACnH,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EACrB,eAAe,CAAC,CAAC,CAAC,CACnB;IACC;;;OAGG;gBACS,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAUxC;;;;;OAKG;IACH,MAAM,CAAC,wBAAwB,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/G,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAC1C,SAAS,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;;;;;;;IAwBzC;;OAEG;IACH,IAAI,SAAS,QAQZ;IAED;;;;;OAKG;IACH,cAAc,CAAC,UAAU,EAAE,CAAC;IAU5B;;;;;;OAMG;IACH,UAAU,CAAC,SAAS,EAAE,GAAG,EAAE;IAe3B;;OAEG;IACH,kBAAkB,QAAO,CAAC,CASxB;IAEF;;;;;;OAMG;IACH,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"ArrayField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/ArrayField.tsx"],"names":[],"mappings":"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"}
|
|
@@ -5,10 +5,10 @@ import cloneDeep from 'lodash-es/cloneDeep.js';
|
|
|
5
5
|
import get from 'lodash-es/get.js';
|
|
6
6
|
import isObject from 'lodash-es/isObject.js';
|
|
7
7
|
import set from 'lodash-es/set.js';
|
|
8
|
-
import
|
|
8
|
+
import uniqueId from 'lodash-es/uniqueId.js';
|
|
9
9
|
/** Used to generate a unique ID for an element in a row */
|
|
10
10
|
function generateRowId() {
|
|
11
|
-
return
|
|
11
|
+
return uniqueId('rjsf-array-item-');
|
|
12
12
|
}
|
|
13
13
|
/** Converts the `formData` into `KeyedFormDataType` data, using the `generateRowId()` function to create the key
|
|
14
14
|
*
|
|
@@ -179,7 +179,9 @@ class ArrayField extends Component {
|
|
|
179
179
|
this.setState({
|
|
180
180
|
keyedFormData: newKeyedFormData,
|
|
181
181
|
updatedKeyedFormData: true,
|
|
182
|
-
},
|
|
182
|
+
},
|
|
183
|
+
// add click will pass the empty `path` array to the onChange which adds the appropriate path
|
|
184
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData), [], newErrorSchema));
|
|
183
185
|
}
|
|
184
186
|
/** Callback handler for when the user clicks on the add button. Creates a new row of keyed form data at the end of
|
|
185
187
|
* the list, adding it into the state, and then returning `onChange()` with the plain form data converted from the
|
|
@@ -242,7 +244,9 @@ class ArrayField extends Component {
|
|
|
242
244
|
this.setState({
|
|
243
245
|
keyedFormData: newKeyedFormData,
|
|
244
246
|
updatedKeyedFormData: true,
|
|
245
|
-
},
|
|
247
|
+
},
|
|
248
|
+
// Copy index will pass the empty `path` array to the onChange which adds the appropriate path
|
|
249
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData), [], newErrorSchema));
|
|
246
250
|
};
|
|
247
251
|
};
|
|
248
252
|
/** Callback handler for when the user clicks on the remove button on an existing array element. Removes the row of
|
|
@@ -276,7 +280,9 @@ class ArrayField extends Component {
|
|
|
276
280
|
this.setState({
|
|
277
281
|
keyedFormData: newKeyedFormData,
|
|
278
282
|
updatedKeyedFormData: true,
|
|
279
|
-
},
|
|
283
|
+
},
|
|
284
|
+
// drop index will pass the empty `path` array to the onChange which adds the appropriate path
|
|
285
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData), [], newErrorSchema));
|
|
280
286
|
};
|
|
281
287
|
};
|
|
282
288
|
/** Callback handler for when the user clicks on one of the move item buttons on an existing array element. Moves the
|
|
@@ -321,7 +327,9 @@ class ArrayField extends Component {
|
|
|
321
327
|
const newKeyedFormData = reOrderArray();
|
|
322
328
|
this.setState({
|
|
323
329
|
keyedFormData: newKeyedFormData,
|
|
324
|
-
},
|
|
330
|
+
},
|
|
331
|
+
// reorder click will pass the empty `path` array to the onChange which adds the appropriate path
|
|
332
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData), [], newErrorSchema));
|
|
325
333
|
};
|
|
326
334
|
};
|
|
327
335
|
/** Callback handler used to deal with changing the value of the data in the array at the `index`. Calls the
|
|
@@ -330,27 +338,52 @@ class ArrayField extends Component {
|
|
|
330
338
|
* @param index - The index of the item being changed
|
|
331
339
|
*/
|
|
332
340
|
onChangeForIndex = (index) => {
|
|
333
|
-
return (value, newErrorSchema, id) => {
|
|
334
|
-
const {
|
|
335
|
-
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
onChange(newFormData, errorSchema &&
|
|
343
|
-
errorSchema && {
|
|
344
|
-
...errorSchema,
|
|
345
|
-
[index]: newErrorSchema,
|
|
346
|
-
}, id);
|
|
341
|
+
return (value, path, newErrorSchema, id) => {
|
|
342
|
+
const { onChange } = this.props;
|
|
343
|
+
// Copy the current path and insert in the index into the first location
|
|
344
|
+
const changePath = Array.isArray(path) ? path.slice() : [];
|
|
345
|
+
changePath.unshift(index);
|
|
346
|
+
onChange(
|
|
347
|
+
// We need to treat undefined items as nulls to have validation.
|
|
348
|
+
// See https://github.com/tdegrunt/jsonschema/issues/206
|
|
349
|
+
value === undefined ? null : value, changePath, newErrorSchema, id);
|
|
347
350
|
};
|
|
348
351
|
};
|
|
349
352
|
/** Callback handler used to change the value for a checkbox */
|
|
350
353
|
onSelectChange = (value) => {
|
|
351
354
|
const { onChange, idSchema } = this.props;
|
|
352
|
-
|
|
355
|
+
// select change will pass an empty `path` array since the `ObjectField` will add the path value automatically
|
|
356
|
+
onChange(value, [], undefined, idSchema && idSchema.$id);
|
|
353
357
|
};
|
|
358
|
+
/** Helper method to compute item UI schema for both normal and fixed arrays
|
|
359
|
+
* Handles both static object and dynamic function cases
|
|
360
|
+
*
|
|
361
|
+
* @param uiSchema - The parent UI schema containing items definition
|
|
362
|
+
* @param item - The item data
|
|
363
|
+
* @param index - The index of the item
|
|
364
|
+
* @param formContext - The form context
|
|
365
|
+
* @returns The computed UI schema for the item
|
|
366
|
+
*/
|
|
367
|
+
computeItemUiSchema(uiSchema, item, index, formContext) {
|
|
368
|
+
if (typeof uiSchema.items === 'function') {
|
|
369
|
+
try {
|
|
370
|
+
// Call the function with item data, index, and form context
|
|
371
|
+
// TypeScript now correctly infers the types thanks to the ArrayElement type in UiSchema
|
|
372
|
+
const result = uiSchema.items(item, index, formContext);
|
|
373
|
+
// Only use the result if it's truthy
|
|
374
|
+
return result;
|
|
375
|
+
}
|
|
376
|
+
catch (e) {
|
|
377
|
+
console.error(`Error executing dynamic uiSchema.items function for item at index ${index}:`, e);
|
|
378
|
+
// Fall back to undefined to allow the field to still render
|
|
379
|
+
return undefined;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
// Static object case - preserve undefined to maintain backward compatibility
|
|
384
|
+
return uiSchema.items;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
354
387
|
/** Renders the `ArrayField` depending on the specific needs of the schema and uischema elements
|
|
355
388
|
*/
|
|
356
389
|
render() {
|
|
@@ -398,6 +431,8 @@ class ArrayField extends Component {
|
|
|
398
431
|
const itemErrorSchema = errorSchema ? errorSchema[index] : undefined;
|
|
399
432
|
const itemIdPrefix = idSchema.$id + idSeparator + index;
|
|
400
433
|
const itemIdSchema = schemaUtils.toIdSchema(itemSchema, itemIdPrefix, itemCast, idPrefix, idSeparator);
|
|
434
|
+
// Compute the item UI schema using the helper method
|
|
435
|
+
const itemUiSchema = this.computeItemUiSchema(uiSchema, item, index, formContext);
|
|
401
436
|
return this.renderArrayFieldItem({
|
|
402
437
|
key,
|
|
403
438
|
index,
|
|
@@ -410,7 +445,7 @@ class ArrayField extends Component {
|
|
|
410
445
|
itemIdSchema,
|
|
411
446
|
itemErrorSchema,
|
|
412
447
|
itemData: itemCast,
|
|
413
|
-
itemUiSchema
|
|
448
|
+
itemUiSchema,
|
|
414
449
|
autofocus: autofocus && index === 0,
|
|
415
450
|
onBlur,
|
|
416
451
|
onFocus,
|
|
@@ -507,11 +542,22 @@ class ArrayField extends Component {
|
|
|
507
542
|
: itemSchemas[index]) || {};
|
|
508
543
|
const itemIdPrefix = idSchema.$id + idSeparator + index;
|
|
509
544
|
const itemIdSchema = schemaUtils.toIdSchema(itemSchema, itemIdPrefix, itemCast, idPrefix, idSeparator);
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
545
|
+
// Compute the item UI schema - handle both static and dynamic cases
|
|
546
|
+
let itemUiSchema;
|
|
547
|
+
if (additional) {
|
|
548
|
+
// For additional items, use additionalItems uiSchema
|
|
549
|
+
itemUiSchema = uiSchema.additionalItems;
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
// For fixed items, uiSchema.items can be an array, a function, or a single object
|
|
553
|
+
if (Array.isArray(uiSchema.items)) {
|
|
554
|
+
itemUiSchema = uiSchema.items[index];
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
// Use the helper method for function or static object cases
|
|
558
|
+
itemUiSchema = this.computeItemUiSchema(uiSchema, item, index, formContext);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
515
561
|
const itemErrorSchema = errorSchema ? errorSchema[index] : undefined;
|
|
516
562
|
return this.renderArrayFieldItem({
|
|
517
563
|
key,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BooleanField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/BooleanField.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BooleanField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/BooleanField.tsx"],"names":[],"mappings":"AACA,OAAO,EAIL,UAAU,EACV,eAAe,EAGf,UAAU,EACV,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAGrB;;;;GAIG;AACH,iBAAS,YAAY,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,EACrG,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,2CAoG3B;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback } from 'react';
|
|
2
3
|
import { getWidget, getUiOptions, optionsList, TranslatableString, } from '@rjsf/utils';
|
|
3
4
|
import isObject from 'lodash-es/isObject.js';
|
|
4
5
|
/** The `BooleanField` component is used to render a field in the schema is boolean. It constructs `enumOptions` for the
|
|
@@ -51,6 +52,10 @@ function BooleanField(props) {
|
|
|
51
52
|
enumOptions = optionsList({ enum: enums }, uiSchema);
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
+
const onWidgetChange = useCallback((value, errorSchema, id) => {
|
|
56
|
+
// Boolean field change passes an empty path array to the parent field which adds the appropriate path
|
|
57
|
+
return onChange(value, [], errorSchema, id);
|
|
58
|
+
}, [onChange]);
|
|
59
|
+
return (_jsx(Widget, { options: { ...options, enumOptions }, schema: schema, uiSchema: uiSchema, id: idSchema.$id, name: name, onChange: onWidgetChange, onFocus: onFocus, onBlur: onBlur, label: label, hideLabel: !displayLabel, value: formData, required: required, disabled: disabled, readonly: readonly, hideError: hideError, registry: registry, formContext: formContext, autofocus: autofocus, rawErrors: rawErrors }));
|
|
55
60
|
}
|
|
56
61
|
export default BooleanField;
|