@rjsf/core 5.0.0-beta.6 → 5.0.0-beta.9

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.
@@ -784,9 +784,11 @@ class ArrayField extends React.Component {
784
784
  } = this.props;
785
785
  const {
786
786
  fields: {
787
+ ArraySchemaField,
787
788
  SchemaField
788
789
  }
789
790
  } = registry;
791
+ const ItemSchemaField = ArraySchemaField || SchemaField;
790
792
  const {
791
793
  orderable = true,
792
794
  removable = true
@@ -799,7 +801,7 @@ class ArrayField extends React.Component {
799
801
  };
800
802
  has.toolbar = Object.keys(has).some(key => has[key]);
801
803
  return {
802
- children: /*#__PURE__*/React__default["default"].createElement(SchemaField, {
804
+ children: /*#__PURE__*/React__default["default"].createElement(ItemSchemaField, {
803
805
  name: name,
804
806
  index: index,
805
807
  schema: itemSchema,
@@ -833,7 +835,8 @@ class ArrayField extends React.Component {
833
835
  onDropIndexClick: this.onDropIndexClick,
834
836
  onReorderClick: this.onReorderClick,
835
837
  readonly,
836
- registry
838
+ registry,
839
+ uiSchema: itemUiSchema
837
840
  };
838
841
  }
839
842
 
@@ -1595,58 +1598,6 @@ function getFieldComponent(schema, uiOptions, idSchema, registry) {
1595
1598
  });
1596
1599
  };
1597
1600
  }
1598
- /** The `Help` component renders any help desired for a field
1599
- *
1600
- * @param props - The id and help information to be rendered
1601
- */
1602
-
1603
-
1604
- function Help(props) {
1605
- const {
1606
- id,
1607
- help
1608
- } = props;
1609
-
1610
- if (!help) {
1611
- return null;
1612
- }
1613
-
1614
- if (typeof help === "string") {
1615
- return /*#__PURE__*/React__default["default"].createElement("p", {
1616
- id: id,
1617
- className: "help-block"
1618
- }, help);
1619
- }
1620
-
1621
- return /*#__PURE__*/React__default["default"].createElement("div", {
1622
- id: id,
1623
- className: "help-block"
1624
- }, help);
1625
- }
1626
- /** The `ErrorList` component renders the errors local to the particular field
1627
- *
1628
- * @param props - The list of errors to show
1629
- */
1630
-
1631
-
1632
- function ErrorList$1(props) {
1633
- const {
1634
- errors = []
1635
- } = props;
1636
-
1637
- if (errors.length === 0) {
1638
- return null;
1639
- }
1640
-
1641
- return /*#__PURE__*/React__default["default"].createElement("div", null, /*#__PURE__*/React__default["default"].createElement("ul", {
1642
- className: "error-detail bs-callout bs-callout-info"
1643
- }, errors.filter(elem => !!elem).map((error, index) => {
1644
- return /*#__PURE__*/React__default["default"].createElement("li", {
1645
- className: "text-danger",
1646
- key: index
1647
- }, error);
1648
- })));
1649
- }
1650
1601
  /** The `SchemaFieldRender` component is the work-horse of react-jsonschema-form, determining what kind of real field to
1651
1602
  * render based on the `schema`, `uiSchema` and all the other props. It also deals with rendering the `anyOf` and
1652
1603
  * `oneOf` fields.
@@ -1679,6 +1630,8 @@ function SchemaFieldRender(props) {
1679
1630
  const uiOptions = utils.getUiOptions(uiSchema);
1680
1631
  const FieldTemplate = utils.getTemplate("FieldTemplate", registry, uiOptions);
1681
1632
  const DescriptionFieldTemplate = utils.getTemplate("DescriptionFieldTemplate", registry, uiOptions);
1633
+ const FieldHelpTemplate = utils.getTemplate("FieldHelpTemplate", registry, uiOptions);
1634
+ const FieldErrorTemplate = utils.getTemplate("FieldErrorTemplate", registry, uiOptions);
1682
1635
  const schema = schemaUtils.retrieveSchema(_schema, formData);
1683
1636
  const idSchema = utils.mergeObjects(schemaUtils.toIdSchema(schema, _idSchema.$id, formData, idPrefix, idSeparator), _idSchema);
1684
1637
  const FieldComponent = getFieldComponent(schema, uiOptions, idSchema, registry);
@@ -1724,16 +1677,15 @@ function SchemaFieldRender(props) {
1724
1677
  if (wasPropertyKeyModified) {
1725
1678
  label = name;
1726
1679
  } else {
1727
- label = uiOptions.title || props.schema.title || schema.title || name;
1680
+ label = utils.ADDITIONAL_PROPERTY_FLAG in schema ? name : uiOptions.title || props.schema.title || schema.title || name;
1728
1681
  }
1729
1682
 
1730
1683
  const description = uiOptions.description || props.schema.description || schema.description || "";
1731
- const errors = __errors;
1732
1684
  const help = uiOptions.help;
1733
1685
  const hidden = uiOptions.widget === "hidden";
1734
1686
  const classNames = ["form-group", "field", "field-" + schema.type];
1735
1687
 
1736
- if (!hideError && errors && errors.length > 0) {
1688
+ if (!hideError && __errors && __errors.length > 0) {
1737
1689
  classNames.push("field-error has-error has-danger");
1738
1690
  }
1739
1691
 
@@ -1749,6 +1701,22 @@ function SchemaFieldRender(props) {
1749
1701
  classNames.push(uiOptions.classNames);
1750
1702
  }
1751
1703
 
1704
+ const helpComponent = /*#__PURE__*/React__default["default"].createElement(FieldHelpTemplate, {
1705
+ help: help,
1706
+ idSchema: idSchema,
1707
+ schema: schema,
1708
+ uiSchema: uiSchema,
1709
+ hasErrors: !hideError && __errors && __errors.length > 0,
1710
+ registry: registry
1711
+ });
1712
+ const errorsComponent = hideError ? undefined : /*#__PURE__*/React__default["default"].createElement(FieldErrorTemplate, {
1713
+ errors: __errors,
1714
+ errorSchema: errorSchema,
1715
+ idSchema: idSchema,
1716
+ schema: schema,
1717
+ uiSchema: uiSchema,
1718
+ registry: registry
1719
+ });
1752
1720
  const fieldProps = {
1753
1721
  description: /*#__PURE__*/React__default["default"].createElement(DescriptionFieldTemplate, {
1754
1722
  id: id + "__description",
@@ -1756,15 +1724,10 @@ function SchemaFieldRender(props) {
1756
1724
  registry: registry
1757
1725
  }),
1758
1726
  rawDescription: description,
1759
- help: /*#__PURE__*/React__default["default"].createElement(Help, {
1760
- id: id + "__help",
1761
- help: help
1762
- }),
1727
+ help: helpComponent,
1763
1728
  rawHelp: typeof help === "string" ? help : undefined,
1764
- errors: hideError ? undefined : /*#__PURE__*/React__default["default"].createElement(ErrorList$1, {
1765
- errors: errors
1766
- }),
1767
- rawErrors: hideError ? undefined : errors,
1729
+ errors: errorsComponent,
1730
+ rawErrors: hideError ? undefined : __errors,
1768
1731
  id,
1769
1732
  label,
1770
1733
  hidden,
@@ -1932,6 +1895,7 @@ function NullField(props) {
1932
1895
  const fields = {
1933
1896
  AnyOfField: AnyOfField,
1934
1897
  ArrayField,
1898
+ // ArrayField falls back to SchemaField if ArraySchemaField is not defined, which it isn't by default
1935
1899
  BooleanField,
1936
1900
  NumberField,
1937
1901
  ObjectField,
@@ -1987,7 +1951,8 @@ function ArrayFieldItemTemplate(props) {
1987
1951
  onDropIndexClick,
1988
1952
  onReorderClick,
1989
1953
  readonly,
1990
- registry
1954
+ registry,
1955
+ uiSchema
1991
1956
  } = props;
1992
1957
  const {
1993
1958
  MoveDownButton,
@@ -2015,15 +1980,18 @@ function ArrayFieldItemTemplate(props) {
2015
1980
  }, (hasMoveUp || hasMoveDown) && /*#__PURE__*/React__default["default"].createElement(MoveUpButton, {
2016
1981
  style: btnStyle,
2017
1982
  disabled: disabled || readonly || !hasMoveUp,
2018
- onClick: onReorderClick(index, index - 1)
1983
+ onClick: onReorderClick(index, index - 1),
1984
+ uiSchema: uiSchema
2019
1985
  }), (hasMoveUp || hasMoveDown) && /*#__PURE__*/React__default["default"].createElement(MoveDownButton, {
2020
1986
  style: btnStyle,
2021
1987
  disabled: disabled || readonly || !hasMoveDown,
2022
- onClick: onReorderClick(index, index + 1)
1988
+ onClick: onReorderClick(index, index + 1),
1989
+ uiSchema: uiSchema
2023
1990
  }), hasRemove && /*#__PURE__*/React__default["default"].createElement(RemoveButton, {
2024
1991
  style: btnStyle,
2025
1992
  disabled: disabled || readonly,
2026
- onClick: onDropIndexClick(index)
1993
+ onClick: onDropIndexClick(index),
1994
+ uiSchema: uiSchema
2027
1995
  }))));
2028
1996
  }
2029
1997
 
@@ -2085,7 +2053,8 @@ function ArrayFieldTemplate(props) {
2085
2053
  })), canAdd && /*#__PURE__*/React__default["default"].createElement(AddButton, {
2086
2054
  className: "array-item-add",
2087
2055
  onClick: onAddClick,
2088
- disabled: disabled || readonly
2056
+ disabled: disabled || readonly,
2057
+ uiSchema: uiSchema
2089
2058
  }));
2090
2059
  }
2091
2060
 
@@ -2242,6 +2211,7 @@ function IconButton(props) {
2242
2211
  iconType = "default",
2243
2212
  icon,
2244
2213
  className,
2214
+ uiSchema,
2245
2215
  ...otherProps
2246
2216
  } = props;
2247
2217
  return /*#__PURE__*/React__default["default"].createElement("button", {
@@ -2405,6 +2375,7 @@ function WrapIfAdditional(props) {
2405
2375
  required,
2406
2376
  schema,
2407
2377
  children,
2378
+ uiSchema,
2408
2379
  registry
2409
2380
  } = props;
2410
2381
  const {
@@ -2448,7 +2419,8 @@ function WrapIfAdditional(props) {
2448
2419
  border: "0"
2449
2420
  },
2450
2421
  disabled: disabled || readonly,
2451
- onClick: onDropPropertyClick(label)
2422
+ onClick: onDropPropertyClick(label),
2423
+ uiSchema: uiSchema
2452
2424
  }))));
2453
2425
  }
2454
2426
 
@@ -2485,6 +2457,63 @@ function FieldTemplate(props) {
2485
2457
  }), displayLabel && description ? description : null, children, errors, help);
2486
2458
  }
2487
2459
 
2460
+ /** The `FieldErrorTemplate` component renders the errors local to the particular field
2461
+ *
2462
+ * @param props - The `FieldErrorProps` for the errors being rendered
2463
+ */
2464
+
2465
+ function FieldErrorTemplate(props) {
2466
+ const {
2467
+ errors = [],
2468
+ idSchema
2469
+ } = props;
2470
+
2471
+ if (errors.length === 0) {
2472
+ return null;
2473
+ }
2474
+
2475
+ const id = idSchema.$id + "__error";
2476
+ return /*#__PURE__*/React__default["default"].createElement("div", null, /*#__PURE__*/React__default["default"].createElement("ul", {
2477
+ id: id,
2478
+ className: "error-detail bs-callout bs-callout-info"
2479
+ }, errors.filter(elem => !!elem).map((error, index) => {
2480
+ return /*#__PURE__*/React__default["default"].createElement("li", {
2481
+ className: "text-danger",
2482
+ key: index
2483
+ }, error);
2484
+ })));
2485
+ }
2486
+
2487
+ /** The `FieldHelpTemplate` component renders any help desired for a field
2488
+ *
2489
+ * @param props - The `FieldHelpProps` to be rendered
2490
+ */
2491
+
2492
+ function FieldHelpTemplate(props) {
2493
+ const {
2494
+ idSchema,
2495
+ help
2496
+ } = props;
2497
+
2498
+ if (!help) {
2499
+ return null;
2500
+ }
2501
+
2502
+ const id = idSchema.$id + "__help";
2503
+
2504
+ if (typeof help === "string") {
2505
+ return /*#__PURE__*/React__default["default"].createElement("p", {
2506
+ id: id,
2507
+ className: "help-block"
2508
+ }, help);
2509
+ }
2510
+
2511
+ return /*#__PURE__*/React__default["default"].createElement("div", {
2512
+ id: id,
2513
+ className: "help-block"
2514
+ }, help);
2515
+ }
2516
+
2488
2517
  /** The `ObjectFieldTemplate` is the template to use to render all the inner properties of an object along with the
2489
2518
  * title and description if available. If the object is expandable, then an `AddButton` is also rendered after all
2490
2519
  * the properties.
@@ -2531,7 +2560,8 @@ function ObjectFieldTemplate(props) {
2531
2560
  }), properties.map(prop => prop.content), utils.canExpand(schema, uiSchema, formData) && /*#__PURE__*/React__default["default"].createElement(AddButton, {
2532
2561
  className: "object-property-expand",
2533
2562
  onClick: onAddClick(schema),
2534
- disabled: disabled || readonly
2563
+ disabled: disabled || readonly,
2564
+ uiSchema: uiSchema
2535
2565
  }));
2536
2566
  }
2537
2567
 
@@ -2581,6 +2611,8 @@ const templates = {
2581
2611
  DescriptionFieldTemplate: DescriptionField,
2582
2612
  ErrorListTemplate: ErrorList,
2583
2613
  FieldTemplate,
2614
+ FieldErrorTemplate,
2615
+ FieldHelpTemplate,
2584
2616
  ObjectFieldTemplate,
2585
2617
  TitleFieldTemplate: TitleField,
2586
2618
  UnsupportedFieldTemplate: UnsupportedField
@@ -3645,8 +3677,7 @@ class Form extends React.Component {
3645
3677
  omitExtraData,
3646
3678
  extraErrors,
3647
3679
  noValidate,
3648
- onSubmit,
3649
- onError
3680
+ onSubmit
3650
3681
  } = this.props;
3651
3682
  let {
3652
3683
  formData: newFormData
@@ -3663,54 +3694,26 @@ class Form extends React.Component {
3663
3694
  newFormData = this.getUsedFormData(newFormData, fieldNames);
3664
3695
  }
3665
3696
 
3666
- if (!noValidate) {
3667
- const schemaValidation = this.validate(schemaUtils, newFormData);
3668
- let errors = schemaValidation.errors;
3669
- let errorSchema = schemaValidation.errorSchema;
3670
- const schemaValidationErrors = errors;
3671
- const schemaValidationErrorSchema = errorSchema;
3672
-
3673
- if (errors.length > 0) {
3674
- if (extraErrors) {
3675
- const merged = schemaUtils.mergeValidationData(schemaValidation, extraErrors);
3676
- errorSchema = merged.errorSchema;
3677
- errors = merged.errors;
3697
+ if (noValidate || this.validateForm()) {
3698
+ // There are no errors generated through schema validation.
3699
+ // Check for user provided errors and update state accordingly.
3700
+ const errorSchema = extraErrors || {};
3701
+ const errors = extraErrors ? schemaUtils.getValidator().toErrorList(extraErrors) : [];
3702
+ this.setState({
3703
+ formData: newFormData,
3704
+ errors,
3705
+ errorSchema,
3706
+ schemaValidationErrors: [],
3707
+ schemaValidationErrorSchema: {}
3708
+ }, () => {
3709
+ if (onSubmit) {
3710
+ onSubmit({ ...this.state,
3711
+ formData: newFormData,
3712
+ status: "submitted"
3713
+ }, event);
3678
3714
  }
3679
-
3680
- this.setState({
3681
- errors,
3682
- errorSchema,
3683
- schemaValidationErrors,
3684
- schemaValidationErrorSchema
3685
- }, () => {
3686
- if (onError) {
3687
- onError(errors);
3688
- } else {
3689
- console.error("Form validation failed", errors);
3690
- }
3691
- });
3692
- return;
3693
- }
3694
- } // There are no errors generated through schema validation.
3695
- // Check for user provided errors and update state accordingly.
3696
-
3697
-
3698
- const errorSchema = extraErrors || {};
3699
- const errors = extraErrors ? schemaUtils.getValidator().toErrorList(extraErrors) : [];
3700
- this.setState({
3701
- formData: newFormData,
3702
- errors,
3703
- errorSchema,
3704
- schemaValidationErrors: [],
3705
- schemaValidationErrorSchema: {}
3706
- }, () => {
3707
- if (onSubmit) {
3708
- onSubmit({ ...this.state,
3709
- formData: newFormData,
3710
- status: "submitted"
3711
- }, event);
3712
- }
3713
- });
3715
+ });
3716
+ }
3714
3717
  };
3715
3718
 
3716
3719
  if (!props.validator) {
@@ -3938,6 +3941,54 @@ class Form extends React.Component {
3938
3941
  this.formElement.current.requestSubmit();
3939
3942
  }
3940
3943
  }
3944
+ /** Programmatically validate the form. If `onError` is provided, then it will be called with the list of errors the
3945
+ * same way as would happen on form submission.
3946
+ *
3947
+ * @returns - True if the form is valid, false otherwise.
3948
+ */
3949
+
3950
+
3951
+ validateForm() {
3952
+ const {
3953
+ extraErrors,
3954
+ onError
3955
+ } = this.props;
3956
+ const {
3957
+ formData
3958
+ } = this.state;
3959
+ const {
3960
+ schemaUtils
3961
+ } = this.state;
3962
+ const schemaValidation = this.validate(schemaUtils, formData);
3963
+ let errors = schemaValidation.errors;
3964
+ let errorSchema = schemaValidation.errorSchema;
3965
+ const schemaValidationErrors = errors;
3966
+ const schemaValidationErrorSchema = errorSchema;
3967
+
3968
+ if (errors.length > 0) {
3969
+ if (extraErrors) {
3970
+ const merged = schemaUtils.mergeValidationData(schemaValidation, extraErrors);
3971
+ errorSchema = merged.errorSchema;
3972
+ errors = merged.errors;
3973
+ }
3974
+
3975
+ this.setState({
3976
+ errors,
3977
+ errorSchema,
3978
+ schemaValidationErrors,
3979
+ schemaValidationErrorSchema
3980
+ }, () => {
3981
+ if (onError) {
3982
+ onError(errors);
3983
+ } else {
3984
+ console.error("Form validation failed", errors);
3985
+ }
3986
+ });
3987
+ return false;
3988
+ }
3989
+
3990
+ return true;
3991
+ }
3941
3992
  /** Renders the `Form` fields inside the <form> | `tagName` or `_internalFormWrapper`, rendering any errors if
3942
3993
  * needed along with the submit button or any children of the form.
3943
3994
  */