@rjsf/core 5.18.5 → 5.19.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/dist/core.umd.js CHANGED
@@ -1417,7 +1417,7 @@
1417
1417
  );
1418
1418
  const FieldComponent = getFieldComponent(schema, uiOptions, idSchema, registry);
1419
1419
  const disabled = Boolean(uiOptions.disabled ?? props.disabled);
1420
- const readonly = Boolean(uiOptions.readonly ?? props.readonly ?? props.schema.readOnly ?? schema.readOnly);
1420
+ const readonly = Boolean(uiOptions.readonly ?? (props.readonly || props.schema.readOnly || schema.readOnly));
1421
1421
  const uiSchemaHideError = uiOptions.hideError;
1422
1422
  const hideError = uiSchemaHideError === void 0 ? props.hideError : Boolean(uiSchemaHideError);
1423
1423
  const autofocus = Boolean(uiOptions.autofocus ?? props.autofocus);
@@ -2288,13 +2288,6 @@
2288
2288
  };
2289
2289
  }
2290
2290
  var templates_default = templates;
2291
- function rangeOptions(start, stop) {
2292
- const options = [];
2293
- for (let i = start; i <= stop; i++) {
2294
- options.push({ value: i, label: utils.pad(i, 2) });
2295
- }
2296
- return options;
2297
- }
2298
2291
  function readyForChange(state) {
2299
2292
  return Object.values(state).every((value) => value !== -1);
2300
2293
  }
@@ -2321,7 +2314,7 @@
2321
2314
  id,
2322
2315
  name,
2323
2316
  className: "form-control",
2324
- options: { enumOptions: rangeOptions(range[0], range[1]) },
2317
+ options: { enumOptions: utils.dateRangeOptions(range[0], range[1]) },
2325
2318
  placeholder: type,
2326
2319
  value,
2327
2320
  disabled,
@@ -3030,9 +3023,22 @@
3030
3023
  };
3031
3024
  return getAllPaths(pathSchema);
3032
3025
  };
3026
+ /** Returns the `formData` after filtering to remove any extra data not in a form field
3027
+ *
3028
+ * @param formData - The data for the `Form`
3029
+ * @returns The `formData` after omitting extra data
3030
+ */
3031
+ this.omitExtraData = (formData) => {
3032
+ const { schema, schemaUtils } = this.state;
3033
+ const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
3034
+ const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", formData);
3035
+ const fieldNames = this.getFieldNames(pathSchema, formData);
3036
+ const newFormData = this.getUsedFormData(formData, fieldNames);
3037
+ return newFormData;
3038
+ };
3033
3039
  /** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
3034
3040
  * `formData` along with a new `ErrorSchema`. It will first update the `formData` with any missing default fields and
3035
- * then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filterer to remove any extra data not
3041
+ * then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not
3036
3042
  * in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
3037
3043
  * updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
3038
3044
  * callback will be called if specified with the updated state.
@@ -3051,12 +3057,8 @@
3051
3057
  const mustValidate = !noValidate && liveValidate;
3052
3058
  let state = { formData, schema };
3053
3059
  let newFormData = formData;
3054
- let _retrievedSchema;
3055
3060
  if (omitExtraData === true && liveOmit === true) {
3056
- _retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
3057
- const pathSchema = schemaUtils.toPathSchema(_retrievedSchema, "", formData);
3058
- const fieldNames = this.getFieldNames(pathSchema, formData);
3059
- newFormData = this.getUsedFormData(formData, fieldNames);
3061
+ newFormData = this.omitExtraData(formData);
3060
3062
  state = {
3061
3063
  formData: newFormData
3062
3064
  };
@@ -3087,9 +3089,6 @@
3087
3089
  errors: utils.toErrorList(errorSchema)
3088
3090
  };
3089
3091
  }
3090
- if (_retrievedSchema) {
3091
- state.retrievedSchema = _retrievedSchema;
3092
- }
3093
3092
  this.setState(state, () => onChange && onChange({ ...this.state, ...state }, id));
3094
3093
  };
3095
3094
  /**
@@ -3151,14 +3150,10 @@
3151
3150
  event.persist();
3152
3151
  const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
3153
3152
  let { formData: newFormData } = this.state;
3154
- const { schema, schemaUtils } = this.state;
3155
3153
  if (omitExtraData === true) {
3156
- const retrievedSchema = schemaUtils.retrieveSchema(schema, newFormData);
3157
- const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", newFormData);
3158
- const fieldNames = this.getFieldNames(pathSchema, newFormData);
3159
- newFormData = this.getUsedFormData(newFormData, fieldNames);
3154
+ newFormData = this.omitExtraData(newFormData);
3160
3155
  }
3161
- if (noValidate || this.validateForm()) {
3156
+ if (noValidate || this.validateFormWithFormData(newFormData)) {
3162
3157
  const errorSchema = extraErrors || {};
3163
3158
  const errors = extraErrors ? utils.toErrorList(extraErrors) : [];
3164
3159
  this.setState(
@@ -3188,6 +3183,59 @@
3188
3183
  this.formElement.current.requestSubmit();
3189
3184
  }
3190
3185
  };
3186
+ /** Validates the form using the given `formData`. For use on form submission or on programmatic validation.
3187
+ * If `onError` is provided, then it will be called with the list of errors.
3188
+ *
3189
+ * @param formData - The form data to validate
3190
+ * @returns - True if the form is valid, false otherwise.
3191
+ */
3192
+ this.validateFormWithFormData = (formData) => {
3193
+ const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
3194
+ const { errors: prevErrors } = this.state;
3195
+ const schemaValidation = this.validate(formData);
3196
+ let errors = schemaValidation.errors;
3197
+ let errorSchema = schemaValidation.errorSchema;
3198
+ const schemaValidationErrors = errors;
3199
+ const schemaValidationErrorSchema = errorSchema;
3200
+ const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
3201
+ if (hasError) {
3202
+ if (extraErrors) {
3203
+ const merged = utils.validationDataMerge(schemaValidation, extraErrors);
3204
+ errorSchema = merged.errorSchema;
3205
+ errors = merged.errors;
3206
+ }
3207
+ if (focusOnFirstError) {
3208
+ if (typeof focusOnFirstError === "function") {
3209
+ focusOnFirstError(errors[0]);
3210
+ } else {
3211
+ this.focusOnError(errors[0]);
3212
+ }
3213
+ }
3214
+ this.setState(
3215
+ {
3216
+ errors,
3217
+ errorSchema,
3218
+ schemaValidationErrors,
3219
+ schemaValidationErrorSchema
3220
+ },
3221
+ () => {
3222
+ if (onError) {
3223
+ onError(errors);
3224
+ } else {
3225
+ console.error("Form validation failed", errors);
3226
+ }
3227
+ }
3228
+ );
3229
+ } else if (prevErrors.length > 0) {
3230
+ this.setState({
3231
+ errors: [],
3232
+ errorSchema: {},
3233
+ schemaValidationErrors: [],
3234
+ schemaValidationErrorSchema: {}
3235
+ });
3236
+ }
3237
+ return !hasError;
3238
+ };
3191
3239
  if (!props.validator) {
3192
3240
  throw new Error("A validator is required for Form functionality to work");
3193
3241
  }
@@ -3431,57 +3479,19 @@
3431
3479
  field.focus();
3432
3480
  }
3433
3481
  }
3434
- /** Programmatically validate the form. If `onError` is provided, then it will be called with the list of errors the
3482
+ /** Programmatically validate the form. If `omitExtraData` is true, the `formData` will first be filtered to remove
3483
+ * any extra data not in a form field. If `onError` is provided, then it will be called with the list of errors the
3435
3484
  * same way as would happen on form submission.
3436
3485
  *
3437
3486
  * @returns - True if the form is valid, false otherwise.
3438
3487
  */
3439
3488
  validateForm() {
3440
- const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
3441
- const { formData, errors: prevErrors } = this.state;
3442
- const schemaValidation = this.validate(formData);
3443
- let errors = schemaValidation.errors;
3444
- let errorSchema = schemaValidation.errorSchema;
3445
- const schemaValidationErrors = errors;
3446
- const schemaValidationErrorSchema = errorSchema;
3447
- const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
3448
- if (hasError) {
3449
- if (extraErrors) {
3450
- const merged = utils.validationDataMerge(schemaValidation, extraErrors);
3451
- errorSchema = merged.errorSchema;
3452
- errors = merged.errors;
3453
- }
3454
- if (focusOnFirstError) {
3455
- if (typeof focusOnFirstError === "function") {
3456
- focusOnFirstError(errors[0]);
3457
- } else {
3458
- this.focusOnError(errors[0]);
3459
- }
3460
- }
3461
- this.setState(
3462
- {
3463
- errors,
3464
- errorSchema,
3465
- schemaValidationErrors,
3466
- schemaValidationErrorSchema
3467
- },
3468
- () => {
3469
- if (onError) {
3470
- onError(errors);
3471
- } else {
3472
- console.error("Form validation failed", errors);
3473
- }
3474
- }
3475
- );
3476
- } else if (prevErrors.length > 0) {
3477
- this.setState({
3478
- errors: [],
3479
- errorSchema: {},
3480
- schemaValidationErrors: [],
3481
- schemaValidationErrorSchema: {}
3482
- });
3489
+ const { omitExtraData } = this.props;
3490
+ let { formData: newFormData } = this.state;
3491
+ if (omitExtraData === true) {
3492
+ newFormData = this.omitExtraData(newFormData);
3483
3493
  }
3484
- return !hasError;
3494
+ return this.validateFormWithFormData(newFormData);
3485
3495
  }
3486
3496
  /** Renders the `Form` fields inside the <form> | `tagName` or `_internalFormWrapper`, rendering any errors if
3487
3497
  * needed along with the submit button or any children of the form.
package/dist/index.esm.js CHANGED
@@ -1528,7 +1528,7 @@ function SchemaFieldRender(props) {
1528
1528
  );
1529
1529
  const FieldComponent = getFieldComponent(schema, uiOptions, idSchema, registry);
1530
1530
  const disabled = Boolean(uiOptions.disabled ?? props.disabled);
1531
- const readonly = Boolean(uiOptions.readonly ?? props.readonly ?? props.schema.readOnly ?? schema.readOnly);
1531
+ const readonly = Boolean(uiOptions.readonly ?? (props.readonly || props.schema.readOnly || schema.readOnly));
1532
1532
  const uiSchemaHideError = uiOptions.hideError;
1533
1533
  const hideError = uiSchemaHideError === void 0 ? props.hideError : Boolean(uiSchemaHideError);
1534
1534
  const autofocus = Boolean(uiOptions.autofocus ?? props.autofocus);
@@ -2519,20 +2519,13 @@ var templates_default = templates;
2519
2519
  import { useCallback as useCallback4, useEffect as useEffect2, useReducer, useState as useState2 } from "react";
2520
2520
  import {
2521
2521
  ariaDescribedByIds as ariaDescribedByIds2,
2522
+ dateRangeOptions,
2522
2523
  parseDateString,
2523
2524
  toDateString,
2524
- pad,
2525
2525
  TranslatableString as TranslatableString11,
2526
2526
  getDateElementProps
2527
2527
  } from "@rjsf/utils";
2528
2528
  import { jsx as jsx26, jsxs as jsxs14 } from "react/jsx-runtime";
2529
- function rangeOptions(start, stop) {
2530
- const options = [];
2531
- for (let i = start; i <= stop; i++) {
2532
- options.push({ value: i, label: pad(i, 2) });
2533
- }
2534
- return options;
2535
- }
2536
2529
  function readyForChange(state) {
2537
2530
  return Object.values(state).every((value) => value !== -1);
2538
2531
  }
@@ -2559,7 +2552,7 @@ function DateElement({
2559
2552
  id,
2560
2553
  name,
2561
2554
  className: "form-control",
2562
- options: { enumOptions: rangeOptions(range[0], range[1]) },
2555
+ options: { enumOptions: dateRangeOptions(range[0], range[1]) },
2563
2556
  placeholder: type,
2564
2557
  value,
2565
2558
  disabled,
@@ -3379,9 +3372,22 @@ var Form = class extends Component5 {
3379
3372
  };
3380
3373
  return getAllPaths(pathSchema);
3381
3374
  };
3375
+ /** Returns the `formData` after filtering to remove any extra data not in a form field
3376
+ *
3377
+ * @param formData - The data for the `Form`
3378
+ * @returns The `formData` after omitting extra data
3379
+ */
3380
+ this.omitExtraData = (formData) => {
3381
+ const { schema, schemaUtils } = this.state;
3382
+ const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
3383
+ const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", formData);
3384
+ const fieldNames = this.getFieldNames(pathSchema, formData);
3385
+ const newFormData = this.getUsedFormData(formData, fieldNames);
3386
+ return newFormData;
3387
+ };
3382
3388
  /** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
3383
3389
  * `formData` along with a new `ErrorSchema`. It will first update the `formData` with any missing default fields and
3384
- * then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filterer to remove any extra data not
3390
+ * then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not
3385
3391
  * in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
3386
3392
  * updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
3387
3393
  * callback will be called if specified with the updated state.
@@ -3402,10 +3408,7 @@ var Form = class extends Component5 {
3402
3408
  let newFormData = formData;
3403
3409
  let _retrievedSchema;
3404
3410
  if (omitExtraData === true && liveOmit === true) {
3405
- _retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
3406
- const pathSchema = schemaUtils.toPathSchema(_retrievedSchema, "", formData);
3407
- const fieldNames = this.getFieldNames(pathSchema, formData);
3408
- newFormData = this.getUsedFormData(formData, fieldNames);
3411
+ newFormData = this.omitExtraData(formData);
3409
3412
  state = {
3410
3413
  formData: newFormData
3411
3414
  };
@@ -3500,14 +3503,10 @@ var Form = class extends Component5 {
3500
3503
  event.persist();
3501
3504
  const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
3502
3505
  let { formData: newFormData } = this.state;
3503
- const { schema, schemaUtils } = this.state;
3504
3506
  if (omitExtraData === true) {
3505
- const retrievedSchema = schemaUtils.retrieveSchema(schema, newFormData);
3506
- const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", newFormData);
3507
- const fieldNames = this.getFieldNames(pathSchema, newFormData);
3508
- newFormData = this.getUsedFormData(newFormData, fieldNames);
3507
+ newFormData = this.omitExtraData(newFormData);
3509
3508
  }
3510
- if (noValidate || this.validateForm()) {
3509
+ if (noValidate || this.validateFormWithFormData(newFormData)) {
3511
3510
  const errorSchema = extraErrors || {};
3512
3511
  const errors = extraErrors ? toErrorList(extraErrors) : [];
3513
3512
  this.setState(
@@ -3537,6 +3536,59 @@ var Form = class extends Component5 {
3537
3536
  this.formElement.current.requestSubmit();
3538
3537
  }
3539
3538
  };
3539
+ /** Validates the form using the given `formData`. For use on form submission or on programmatic validation.
3540
+ * If `onError` is provided, then it will be called with the list of errors.
3541
+ *
3542
+ * @param formData - The form data to validate
3543
+ * @returns - True if the form is valid, false otherwise.
3544
+ */
3545
+ this.validateFormWithFormData = (formData) => {
3546
+ const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
3547
+ const { errors: prevErrors } = this.state;
3548
+ const schemaValidation = this.validate(formData);
3549
+ let errors = schemaValidation.errors;
3550
+ let errorSchema = schemaValidation.errorSchema;
3551
+ const schemaValidationErrors = errors;
3552
+ const schemaValidationErrorSchema = errorSchema;
3553
+ const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
3554
+ if (hasError) {
3555
+ if (extraErrors) {
3556
+ const merged = validationDataMerge(schemaValidation, extraErrors);
3557
+ errorSchema = merged.errorSchema;
3558
+ errors = merged.errors;
3559
+ }
3560
+ if (focusOnFirstError) {
3561
+ if (typeof focusOnFirstError === "function") {
3562
+ focusOnFirstError(errors[0]);
3563
+ } else {
3564
+ this.focusOnError(errors[0]);
3565
+ }
3566
+ }
3567
+ this.setState(
3568
+ {
3569
+ errors,
3570
+ errorSchema,
3571
+ schemaValidationErrors,
3572
+ schemaValidationErrorSchema
3573
+ },
3574
+ () => {
3575
+ if (onError) {
3576
+ onError(errors);
3577
+ } else {
3578
+ console.error("Form validation failed", errors);
3579
+ }
3580
+ }
3581
+ );
3582
+ } else if (prevErrors.length > 0) {
3583
+ this.setState({
3584
+ errors: [],
3585
+ errorSchema: {},
3586
+ schemaValidationErrors: [],
3587
+ schemaValidationErrorSchema: {}
3588
+ });
3589
+ }
3590
+ return !hasError;
3591
+ };
3540
3592
  if (!props.validator) {
3541
3593
  throw new Error("A validator is required for Form functionality to work");
3542
3594
  }
@@ -3780,57 +3832,19 @@ var Form = class extends Component5 {
3780
3832
  field.focus();
3781
3833
  }
3782
3834
  }
3783
- /** Programmatically validate the form. If `onError` is provided, then it will be called with the list of errors the
3835
+ /** Programmatically validate the form. If `omitExtraData` is true, the `formData` will first be filtered to remove
3836
+ * any extra data not in a form field. If `onError` is provided, then it will be called with the list of errors the
3784
3837
  * same way as would happen on form submission.
3785
3838
  *
3786
3839
  * @returns - True if the form is valid, false otherwise.
3787
3840
  */
3788
3841
  validateForm() {
3789
- const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
3790
- const { formData, errors: prevErrors } = this.state;
3791
- const schemaValidation = this.validate(formData);
3792
- let errors = schemaValidation.errors;
3793
- let errorSchema = schemaValidation.errorSchema;
3794
- const schemaValidationErrors = errors;
3795
- const schemaValidationErrorSchema = errorSchema;
3796
- const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
3797
- if (hasError) {
3798
- if (extraErrors) {
3799
- const merged = validationDataMerge(schemaValidation, extraErrors);
3800
- errorSchema = merged.errorSchema;
3801
- errors = merged.errors;
3802
- }
3803
- if (focusOnFirstError) {
3804
- if (typeof focusOnFirstError === "function") {
3805
- focusOnFirstError(errors[0]);
3806
- } else {
3807
- this.focusOnError(errors[0]);
3808
- }
3809
- }
3810
- this.setState(
3811
- {
3812
- errors,
3813
- errorSchema,
3814
- schemaValidationErrors,
3815
- schemaValidationErrorSchema
3816
- },
3817
- () => {
3818
- if (onError) {
3819
- onError(errors);
3820
- } else {
3821
- console.error("Form validation failed", errors);
3822
- }
3823
- }
3824
- );
3825
- } else if (prevErrors.length > 0) {
3826
- this.setState({
3827
- errors: [],
3828
- errorSchema: {},
3829
- schemaValidationErrors: [],
3830
- schemaValidationErrorSchema: {}
3831
- });
3842
+ const { omitExtraData } = this.props;
3843
+ let { formData: newFormData } = this.state;
3844
+ if (omitExtraData === true) {
3845
+ newFormData = this.omitExtraData(newFormData);
3832
3846
  }
3833
- return !hasError;
3847
+ return this.validateFormWithFormData(newFormData);
3834
3848
  }
3835
3849
  /** Renders the `Form` fields inside the <form> | `tagName` or `_internalFormWrapper`, rendering any errors if
3836
3850
  * needed along with the submit button or any children of the form.