@rjsf/core 5.18.4 → 5.18.6
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 +101 -78
- package/dist/index.esm.js +101 -74
- package/dist/index.esm.js.map +3 -3
- package/dist/index.js +101 -74
- package/dist/index.js.map +3 -3
- package/lib/components/Form.d.ts +16 -2
- package/lib/components/Form.js +78 -57
- package/lib/components/Form.js.map +1 -1
- package/lib/components/fields/ArrayField.d.ts +2 -2
- package/lib/components/fields/NumberField.js +1 -1
- package/lib/components/fields/NumberField.js.map +1 -1
- package/lib/components/fields/ObjectField.js +5 -2
- package/lib/components/fields/ObjectField.js.map +1 -1
- package/lib/components/fields/SchemaField.js +4 -3
- package/lib/components/fields/SchemaField.js.map +1 -1
- package/lib/components/templates/BaseInputTemplate.js +2 -2
- package/lib/components/templates/BaseInputTemplate.js.map +1 -1
- package/lib/components/templates/WrapIfAdditionalTemplate.js +1 -1
- package/lib/components/templates/WrapIfAdditionalTemplate.js.map +1 -1
- package/lib/components/widgets/CheckboxesWidget.js +2 -2
- package/lib/components/widgets/CheckboxesWidget.js.map +1 -1
- package/lib/components/widgets/RadioWidget.js +2 -2
- package/lib/components/widgets/RadioWidget.js.map +1 -1
- package/lib/components/widgets/TextareaWidget.js +2 -2
- package/lib/components/widgets/TextareaWidget.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/src/components/Form.tsx +40 -21
- package/src/components/fields/NumberField.tsx +1 -1
- package/src/components/fields/ObjectField.tsx +6 -3
- package/src/components/fields/SchemaField.tsx +3 -3
- package/src/components/templates/BaseInputTemplate.tsx +5 -2
- package/src/components/templates/WrapIfAdditionalTemplate.tsx +1 -1
- package/src/components/widgets/CheckboxesWidget.tsx +4 -4
- package/src/components/widgets/RadioWidget.tsx +4 -4
- package/src/components/widgets/TextareaWidget.tsx +2 -2
package/dist/index.js
CHANGED
|
@@ -1132,7 +1132,7 @@ function NumberField(props) {
|
|
|
1132
1132
|
[onChange]
|
|
1133
1133
|
);
|
|
1134
1134
|
if (typeof lastValue === "string" && typeof value === "number") {
|
|
1135
|
-
const re = new RegExp(
|
|
1135
|
+
const re = new RegExp(`^(${String(value).replace(".", "\\.")})?\\.?0*$`);
|
|
1136
1136
|
if (lastValue.match(re)) {
|
|
1137
1137
|
value = lastValue;
|
|
1138
1138
|
}
|
|
@@ -1260,20 +1260,23 @@ var ObjectField = class extends import_react4.Component {
|
|
|
1260
1260
|
const { formData, onChange, registry } = this.props;
|
|
1261
1261
|
const newFormData = { ...formData };
|
|
1262
1262
|
let type = void 0;
|
|
1263
|
+
let defaultValue = void 0;
|
|
1263
1264
|
if ((0, import_isObject3.default)(schema.additionalProperties)) {
|
|
1264
1265
|
type = schema.additionalProperties.type;
|
|
1266
|
+
defaultValue = schema.additionalProperties.default;
|
|
1265
1267
|
let apSchema = schema.additionalProperties;
|
|
1266
1268
|
if (import_utils5.REF_KEY in apSchema) {
|
|
1267
1269
|
const { schemaUtils } = registry;
|
|
1268
1270
|
apSchema = schemaUtils.retrieveSchema({ $ref: apSchema[import_utils5.REF_KEY] }, formData);
|
|
1269
1271
|
type = apSchema.type;
|
|
1272
|
+
defaultValue = apSchema.default;
|
|
1270
1273
|
}
|
|
1271
1274
|
if (!type && (import_utils5.ANY_OF_KEY in apSchema || import_utils5.ONE_OF_KEY in apSchema)) {
|
|
1272
1275
|
type = "object";
|
|
1273
1276
|
}
|
|
1274
1277
|
}
|
|
1275
1278
|
const newKey = this.getAvailableKey("newKey", newFormData);
|
|
1276
|
-
(0, import_set2.default)(newFormData, newKey, this.getDefaultValue(type));
|
|
1279
|
+
(0, import_set2.default)(newFormData, newKey, defaultValue ?? this.getDefaultValue(type));
|
|
1277
1280
|
onChange(newFormData);
|
|
1278
1281
|
};
|
|
1279
1282
|
}
|
|
@@ -1321,8 +1324,8 @@ var ObjectField = class extends import_react4.Component {
|
|
|
1321
1324
|
idSchema,
|
|
1322
1325
|
name,
|
|
1323
1326
|
required = false,
|
|
1324
|
-
disabled
|
|
1325
|
-
readonly
|
|
1327
|
+
disabled,
|
|
1328
|
+
readonly,
|
|
1326
1329
|
hideError,
|
|
1327
1330
|
idPrefix,
|
|
1328
1331
|
idSeparator,
|
|
@@ -1501,11 +1504,11 @@ function SchemaFieldRender(props) {
|
|
|
1501
1504
|
[fieldId, onChange]
|
|
1502
1505
|
);
|
|
1503
1506
|
const FieldComponent = getFieldComponent(schema, uiOptions, idSchema, registry);
|
|
1504
|
-
const disabled = Boolean(
|
|
1505
|
-
const readonly = Boolean(
|
|
1507
|
+
const disabled = Boolean(uiOptions.disabled ?? props.disabled);
|
|
1508
|
+
const readonly = Boolean(uiOptions.readonly ?? props.readonly ?? props.schema.readOnly ?? schema.readOnly);
|
|
1506
1509
|
const uiSchemaHideError = uiOptions.hideError;
|
|
1507
1510
|
const hideError = uiSchemaHideError === void 0 ? props.hideError : Boolean(uiSchemaHideError);
|
|
1508
|
-
const autofocus = Boolean(
|
|
1511
|
+
const autofocus = Boolean(uiOptions.autofocus ?? props.autofocus);
|
|
1509
1512
|
if (Object.keys(schema).length === 0) {
|
|
1510
1513
|
return null;
|
|
1511
1514
|
}
|
|
@@ -2030,9 +2033,12 @@ function BaseInputTemplate(props) {
|
|
|
2030
2033
|
({ target: { value: value2 } }) => onChange(value2 === "" ? options.emptyValue : value2),
|
|
2031
2034
|
[onChange, options]
|
|
2032
2035
|
);
|
|
2033
|
-
const _onBlur = (0, import_react7.useCallback)(
|
|
2036
|
+
const _onBlur = (0, import_react7.useCallback)(
|
|
2037
|
+
({ target }) => onBlur(id, target && target.value),
|
|
2038
|
+
[onBlur, id]
|
|
2039
|
+
);
|
|
2034
2040
|
const _onFocus = (0, import_react7.useCallback)(
|
|
2035
|
-
({ target
|
|
2041
|
+
({ target }) => onFocus(id, target && target.value),
|
|
2036
2042
|
[onFocus, id]
|
|
2037
2043
|
);
|
|
2038
2044
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
@@ -2410,7 +2416,7 @@ function WrapIfAdditionalTemplate(props) {
|
|
|
2410
2416
|
className: "form-control",
|
|
2411
2417
|
type: "text",
|
|
2412
2418
|
id: `${id}-key`,
|
|
2413
|
-
onBlur: (
|
|
2419
|
+
onBlur: ({ target }) => onKeyChange(target && target.value),
|
|
2414
2420
|
defaultValue: label
|
|
2415
2421
|
}
|
|
2416
2422
|
)
|
|
@@ -2684,11 +2690,11 @@ function CheckboxesWidget({
|
|
|
2684
2690
|
}) {
|
|
2685
2691
|
const checkboxesValues = Array.isArray(value) ? value : [value];
|
|
2686
2692
|
const handleBlur = (0, import_react10.useCallback)(
|
|
2687
|
-
({ target
|
|
2693
|
+
({ target }) => onBlur(id, (0, import_utils24.enumOptionsValueForIndex)(target && target.value, enumOptions, emptyValue)),
|
|
2688
2694
|
[onBlur, id]
|
|
2689
2695
|
);
|
|
2690
2696
|
const handleFocus = (0, import_react10.useCallback)(
|
|
2691
|
-
({ target
|
|
2697
|
+
({ target }) => onFocus(id, (0, import_utils24.enumOptionsValueForIndex)(target && target.value, enumOptions, emptyValue)),
|
|
2692
2698
|
[onFocus, id]
|
|
2693
2699
|
);
|
|
2694
2700
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "checkboxes", id, children: Array.isArray(enumOptions) && enumOptions.map((option, index) => {
|
|
@@ -2966,11 +2972,11 @@ function RadioWidget({
|
|
|
2966
2972
|
}) {
|
|
2967
2973
|
const { enumOptions, enumDisabled, inline, emptyValue } = options;
|
|
2968
2974
|
const handleBlur = (0, import_react13.useCallback)(
|
|
2969
|
-
({ target
|
|
2975
|
+
({ target }) => onBlur(id, (0, import_utils31.enumOptionsValueForIndex)(target && target.value, enumOptions, emptyValue)),
|
|
2970
2976
|
[onBlur, id]
|
|
2971
2977
|
);
|
|
2972
2978
|
const handleFocus = (0, import_react13.useCallback)(
|
|
2973
|
-
({ target
|
|
2979
|
+
({ target }) => onFocus(id, (0, import_utils31.enumOptionsValueForIndex)(target && target.value, enumOptions, emptyValue)),
|
|
2974
2980
|
[onFocus, id]
|
|
2975
2981
|
);
|
|
2976
2982
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "field-radio-group", id, children: Array.isArray(enumOptions) && enumOptions.map((option, i) => {
|
|
@@ -3116,11 +3122,11 @@ function TextareaWidget({
|
|
|
3116
3122
|
[onChange, options.emptyValue]
|
|
3117
3123
|
);
|
|
3118
3124
|
const handleBlur = (0, import_react15.useCallback)(
|
|
3119
|
-
({ target
|
|
3125
|
+
({ target }) => onBlur(id, target && target.value),
|
|
3120
3126
|
[onBlur, id]
|
|
3121
3127
|
);
|
|
3122
3128
|
const handleFocus = (0, import_react15.useCallback)(
|
|
3123
|
-
({ target
|
|
3129
|
+
({ target }) => onFocus(id, target && target.value),
|
|
3124
3130
|
[id, onFocus]
|
|
3125
3131
|
);
|
|
3126
3132
|
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
@@ -3279,9 +3285,22 @@ var Form = class extends import_react17.Component {
|
|
|
3279
3285
|
};
|
|
3280
3286
|
return getAllPaths(pathSchema);
|
|
3281
3287
|
};
|
|
3288
|
+
/** Returns the `formData` after filtering to remove any extra data not in a form field
|
|
3289
|
+
*
|
|
3290
|
+
* @param formData - The data for the `Form`
|
|
3291
|
+
* @returns The `formData` after omitting extra data
|
|
3292
|
+
*/
|
|
3293
|
+
this.omitExtraData = (formData) => {
|
|
3294
|
+
const { schema, schemaUtils } = this.state;
|
|
3295
|
+
const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
|
|
3296
|
+
const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", formData);
|
|
3297
|
+
const fieldNames = this.getFieldNames(pathSchema, formData);
|
|
3298
|
+
const newFormData = this.getUsedFormData(formData, fieldNames);
|
|
3299
|
+
return newFormData;
|
|
3300
|
+
};
|
|
3282
3301
|
/** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
|
|
3283
3302
|
* `formData` along with a new `ErrorSchema`. It will first update the `formData` with any missing default fields and
|
|
3284
|
-
* then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be
|
|
3303
|
+
* then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not
|
|
3285
3304
|
* in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
|
|
3286
3305
|
* updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
|
|
3287
3306
|
* callback will be called if specified with the updated state.
|
|
@@ -3302,10 +3321,7 @@ var Form = class extends import_react17.Component {
|
|
|
3302
3321
|
let newFormData = formData;
|
|
3303
3322
|
let _retrievedSchema;
|
|
3304
3323
|
if (omitExtraData === true && liveOmit === true) {
|
|
3305
|
-
|
|
3306
|
-
const pathSchema = schemaUtils.toPathSchema(_retrievedSchema, "", formData);
|
|
3307
|
-
const fieldNames = this.getFieldNames(pathSchema, formData);
|
|
3308
|
-
newFormData = this.getUsedFormData(formData, fieldNames);
|
|
3324
|
+
newFormData = this.omitExtraData(formData);
|
|
3309
3325
|
state = {
|
|
3310
3326
|
formData: newFormData
|
|
3311
3327
|
};
|
|
@@ -3400,14 +3416,10 @@ var Form = class extends import_react17.Component {
|
|
|
3400
3416
|
event.persist();
|
|
3401
3417
|
const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
|
|
3402
3418
|
let { formData: newFormData } = this.state;
|
|
3403
|
-
const { schema, schemaUtils } = this.state;
|
|
3404
3419
|
if (omitExtraData === true) {
|
|
3405
|
-
|
|
3406
|
-
const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", newFormData);
|
|
3407
|
-
const fieldNames = this.getFieldNames(pathSchema, newFormData);
|
|
3408
|
-
newFormData = this.getUsedFormData(newFormData, fieldNames);
|
|
3420
|
+
newFormData = this.omitExtraData(newFormData);
|
|
3409
3421
|
}
|
|
3410
|
-
if (noValidate || this.
|
|
3422
|
+
if (noValidate || this.validateFormWithFormData(newFormData)) {
|
|
3411
3423
|
const errorSchema = extraErrors || {};
|
|
3412
3424
|
const errors = extraErrors ? (0, import_utils39.toErrorList)(extraErrors) : [];
|
|
3413
3425
|
this.setState(
|
|
@@ -3437,6 +3449,59 @@ var Form = class extends import_react17.Component {
|
|
|
3437
3449
|
this.formElement.current.requestSubmit();
|
|
3438
3450
|
}
|
|
3439
3451
|
};
|
|
3452
|
+
/** Validates the form using the given `formData`. For use on form submission or on programmatic validation.
|
|
3453
|
+
* If `onError` is provided, then it will be called with the list of errors.
|
|
3454
|
+
*
|
|
3455
|
+
* @param formData - The form data to validate
|
|
3456
|
+
* @returns - True if the form is valid, false otherwise.
|
|
3457
|
+
*/
|
|
3458
|
+
this.validateFormWithFormData = (formData) => {
|
|
3459
|
+
const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
|
|
3460
|
+
const { errors: prevErrors } = this.state;
|
|
3461
|
+
const schemaValidation = this.validate(formData);
|
|
3462
|
+
let errors = schemaValidation.errors;
|
|
3463
|
+
let errorSchema = schemaValidation.errorSchema;
|
|
3464
|
+
const schemaValidationErrors = errors;
|
|
3465
|
+
const schemaValidationErrorSchema = errorSchema;
|
|
3466
|
+
const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
|
|
3467
|
+
if (hasError) {
|
|
3468
|
+
if (extraErrors) {
|
|
3469
|
+
const merged = (0, import_utils39.validationDataMerge)(schemaValidation, extraErrors);
|
|
3470
|
+
errorSchema = merged.errorSchema;
|
|
3471
|
+
errors = merged.errors;
|
|
3472
|
+
}
|
|
3473
|
+
if (focusOnFirstError) {
|
|
3474
|
+
if (typeof focusOnFirstError === "function") {
|
|
3475
|
+
focusOnFirstError(errors[0]);
|
|
3476
|
+
} else {
|
|
3477
|
+
this.focusOnError(errors[0]);
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
this.setState(
|
|
3481
|
+
{
|
|
3482
|
+
errors,
|
|
3483
|
+
errorSchema,
|
|
3484
|
+
schemaValidationErrors,
|
|
3485
|
+
schemaValidationErrorSchema
|
|
3486
|
+
},
|
|
3487
|
+
() => {
|
|
3488
|
+
if (onError) {
|
|
3489
|
+
onError(errors);
|
|
3490
|
+
} else {
|
|
3491
|
+
console.error("Form validation failed", errors);
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
);
|
|
3495
|
+
} else if (prevErrors.length > 0) {
|
|
3496
|
+
this.setState({
|
|
3497
|
+
errors: [],
|
|
3498
|
+
errorSchema: {},
|
|
3499
|
+
schemaValidationErrors: [],
|
|
3500
|
+
schemaValidationErrorSchema: {}
|
|
3501
|
+
});
|
|
3502
|
+
}
|
|
3503
|
+
return !hasError;
|
|
3504
|
+
};
|
|
3440
3505
|
if (!props.validator) {
|
|
3441
3506
|
throw new Error("A validator is required for Form functionality to work");
|
|
3442
3507
|
}
|
|
@@ -3680,57 +3745,19 @@ var Form = class extends import_react17.Component {
|
|
|
3680
3745
|
field.focus();
|
|
3681
3746
|
}
|
|
3682
3747
|
}
|
|
3683
|
-
/** Programmatically validate the form.
|
|
3748
|
+
/** Programmatically validate the form. If `omitExtraData` is true, the `formData` will first be filtered to remove
|
|
3749
|
+
* any extra data not in a form field. If `onError` is provided, then it will be called with the list of errors the
|
|
3684
3750
|
* same way as would happen on form submission.
|
|
3685
3751
|
*
|
|
3686
3752
|
* @returns - True if the form is valid, false otherwise.
|
|
3687
3753
|
*/
|
|
3688
3754
|
validateForm() {
|
|
3689
|
-
const {
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
let errorSchema = schemaValidation.errorSchema;
|
|
3694
|
-
const schemaValidationErrors = errors;
|
|
3695
|
-
const schemaValidationErrorSchema = errorSchema;
|
|
3696
|
-
const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
|
|
3697
|
-
if (hasError) {
|
|
3698
|
-
if (extraErrors) {
|
|
3699
|
-
const merged = (0, import_utils39.validationDataMerge)(schemaValidation, extraErrors);
|
|
3700
|
-
errorSchema = merged.errorSchema;
|
|
3701
|
-
errors = merged.errors;
|
|
3702
|
-
}
|
|
3703
|
-
if (focusOnFirstError) {
|
|
3704
|
-
if (typeof focusOnFirstError === "function") {
|
|
3705
|
-
focusOnFirstError(errors[0]);
|
|
3706
|
-
} else {
|
|
3707
|
-
this.focusOnError(errors[0]);
|
|
3708
|
-
}
|
|
3709
|
-
}
|
|
3710
|
-
this.setState(
|
|
3711
|
-
{
|
|
3712
|
-
errors,
|
|
3713
|
-
errorSchema,
|
|
3714
|
-
schemaValidationErrors,
|
|
3715
|
-
schemaValidationErrorSchema
|
|
3716
|
-
},
|
|
3717
|
-
() => {
|
|
3718
|
-
if (onError) {
|
|
3719
|
-
onError(errors);
|
|
3720
|
-
} else {
|
|
3721
|
-
console.error("Form validation failed", errors);
|
|
3722
|
-
}
|
|
3723
|
-
}
|
|
3724
|
-
);
|
|
3725
|
-
} else if (prevErrors.length > 0) {
|
|
3726
|
-
this.setState({
|
|
3727
|
-
errors: [],
|
|
3728
|
-
errorSchema: {},
|
|
3729
|
-
schemaValidationErrors: [],
|
|
3730
|
-
schemaValidationErrorSchema: {}
|
|
3731
|
-
});
|
|
3755
|
+
const { omitExtraData } = this.props;
|
|
3756
|
+
let { formData: newFormData } = this.state;
|
|
3757
|
+
if (omitExtraData === true) {
|
|
3758
|
+
newFormData = this.omitExtraData(newFormData);
|
|
3732
3759
|
}
|
|
3733
|
-
return
|
|
3760
|
+
return this.validateFormWithFormData(newFormData);
|
|
3734
3761
|
}
|
|
3735
3762
|
/** Renders the `Form` fields inside the <form> | `tagName` or `_internalFormWrapper`, rendering any errors if
|
|
3736
3763
|
* needed along with the submit button or any children of the form.
|
|
@@ -3752,8 +3779,8 @@ var Form = class extends import_react17.Component {
|
|
|
3752
3779
|
acceptcharset,
|
|
3753
3780
|
acceptCharset,
|
|
3754
3781
|
noHtml5Validate = false,
|
|
3755
|
-
disabled
|
|
3756
|
-
readonly
|
|
3782
|
+
disabled,
|
|
3783
|
+
readonly,
|
|
3757
3784
|
formContext,
|
|
3758
3785
|
showErrorList = "top",
|
|
3759
3786
|
_internalFormWrapper
|