@rjsf/core 5.0.2 → 5.2.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.
@@ -7,12 +7,14 @@ var utils = require('@rjsf/utils');
7
7
  var get = require('lodash/get');
8
8
  var isEmpty = require('lodash/isEmpty');
9
9
  var _pick = require('lodash/pick');
10
+ var _toPath = require('lodash/toPath');
10
11
  var isObject = require('lodash/isObject');
11
12
  var set = require('lodash/set');
12
13
  var nanoid = require('nanoid');
13
14
  var omit = require('lodash/omit');
14
15
  var has = require('lodash/has');
15
16
  var unset = require('lodash/unset');
17
+ var Markdown = require('markdown-to-jsx');
16
18
 
17
19
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
18
20
 
@@ -20,11 +22,13 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
20
22
  var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
21
23
  var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
22
24
  var _pick__default = /*#__PURE__*/_interopDefaultLegacy(_pick);
25
+ var _toPath__default = /*#__PURE__*/_interopDefaultLegacy(_toPath);
23
26
  var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
24
27
  var set__default = /*#__PURE__*/_interopDefaultLegacy(set);
25
28
  var omit__default = /*#__PURE__*/_interopDefaultLegacy(omit);
26
29
  var has__default = /*#__PURE__*/_interopDefaultLegacy(has);
27
30
  var unset__default = /*#__PURE__*/_interopDefaultLegacy(unset);
31
+ var Markdown__default = /*#__PURE__*/_interopDefaultLegacy(Markdown);
28
32
 
29
33
  function _defineProperties(target, props) {
30
34
  for (var i = 0; i < props.length; i++) {
@@ -204,7 +208,7 @@ var ArrayField = /*#__PURE__*/function (_Component) {
204
208
  onChange = _this$props3.onChange,
205
209
  errorSchema = _this$props3.errorSchema;
206
210
  var newErrorSchema;
207
- if (_this.props.errorSchema) {
211
+ if (errorSchema) {
208
212
  newErrorSchema = {};
209
213
  for (var idx in errorSchema) {
210
214
  var i = parseInt(idx);
@@ -381,14 +385,15 @@ var ArrayField = /*#__PURE__*/function (_Component) {
381
385
  uiSchema = _this$props7.uiSchema,
382
386
  idSchema = _this$props7.idSchema,
383
387
  registry = _this$props7.registry;
384
- var schemaUtils = registry.schemaUtils;
388
+ var schemaUtils = registry.schemaUtils,
389
+ translateString = registry.translateString;
385
390
  if (!(utils.ITEMS_KEY in schema)) {
386
391
  var uiOptions = utils.getUiOptions(uiSchema);
387
392
  var UnsupportedFieldTemplate = utils.getTemplate("UnsupportedFieldTemplate", registry, uiOptions);
388
393
  return /*#__PURE__*/React__default["default"].createElement(UnsupportedFieldTemplate, {
389
394
  schema: schema,
390
395
  idSchema: idSchema,
391
- reason: "Missing items definition",
396
+ reason: translateString(utils.TranslatableString.MissingItems),
392
397
  registry: registry
393
398
  });
394
399
  }
@@ -845,8 +850,11 @@ var ArrayField = /*#__PURE__*/function (_Component) {
845
850
  _createClass(ArrayField, [{
846
851
  key: "itemTitle",
847
852
  get: function get() {
848
- var schema = this.props.schema;
849
- return get__default["default"](schema, [utils.ITEMS_KEY, "title"], get__default["default"](schema, [utils.ITEMS_KEY, "description"], "Item"));
853
+ var _this$props14 = this.props,
854
+ schema = _this$props14.schema,
855
+ registry = _this$props14.registry;
856
+ var translateString = registry.translateString;
857
+ return get__default["default"](schema, [utils.ITEMS_KEY, "title"], get__default["default"](schema, [utils.ITEMS_KEY, "description"], translateString(utils.TranslatableString.ArrayItemTitle)));
850
858
  }
851
859
  }]);
852
860
  return ArrayField;
@@ -875,19 +883,22 @@ function BooleanField(props) {
875
883
  rawErrors = props.rawErrors;
876
884
  var title = schema.title;
877
885
  var widgets = registry.widgets,
878
- formContext = registry.formContext;
886
+ formContext = registry.formContext,
887
+ translateString = registry.translateString;
879
888
  var _getUiOptions = utils.getUiOptions(uiSchema),
880
889
  _getUiOptions$widget = _getUiOptions.widget,
881
890
  widget = _getUiOptions$widget === void 0 ? "checkbox" : _getUiOptions$widget,
882
891
  options = _objectWithoutPropertiesLoose(_getUiOptions, _excluded$8);
883
892
  var Widget = utils.getWidget(schema, widget, widgets);
893
+ var yes = translateString(utils.TranslatableString.YesLabel);
894
+ var no = translateString(utils.TranslatableString.NoLabel);
884
895
  var enumOptions;
885
896
  if (Array.isArray(schema.oneOf)) {
886
897
  enumOptions = utils.optionsList({
887
898
  oneOf: schema.oneOf.map(function (option) {
888
899
  if (isObject__default["default"](option)) {
889
900
  return _extends({}, option, {
890
- title: option.title || (option["const"] === true ? "Yes" : "No")
901
+ title: option.title || (option["const"] === true ? yes : no)
891
902
  });
892
903
  }
893
904
  return undefined;
@@ -905,10 +916,10 @@ function BooleanField(props) {
905
916
  })) {
906
917
  enumOptions = [{
907
918
  value: enums[0],
908
- label: enums[0] ? "Yes" : "No"
919
+ label: enums[0] ? yes : no
909
920
  }, {
910
921
  value: enums[1],
911
- label: enums[1] ? "Yes" : "No"
922
+ label: enums[1] ? yes : no
912
923
  }];
913
924
  } else {
914
925
  enumOptions = utils.optionsList({
@@ -941,9 +952,6 @@ function BooleanField(props) {
941
952
  }
942
953
 
943
954
  var _excluded$7 = ["widget", "placeholder", "autofocus", "autocomplete", "title"];
944
- /** The prefix used when a oneOf option does not have a title
945
- */
946
- var UNKNOWN_OPTION_PREFIX = "Option";
947
955
  /** The `AnyOfField` component is used to render a field in the schema that is an `anyOf`, `allOf` or `oneOf`. It tracks
948
956
  * the currently selected option and cleans up any irrelevant data in `formData`.
949
957
  *
@@ -1082,7 +1090,8 @@ var AnyOfField = /*#__PURE__*/function (_Component) {
1082
1090
  schema = _this$props5.schema,
1083
1091
  uiSchema = _this$props5.uiSchema;
1084
1092
  var widgets = registry.widgets,
1085
- fields = registry.fields;
1093
+ fields = registry.fields,
1094
+ translateString = registry.translateString;
1086
1095
  var _SchemaField = fields.SchemaField;
1087
1096
  var _this$state2 = this.state,
1088
1097
  selectedOption = _this$state2.selectedOption,
@@ -1110,10 +1119,11 @@ var AnyOfField = /*#__PURE__*/function (_Component) {
1110
1119
  type: baseType
1111
1120
  });
1112
1121
  }
1113
- var optionLabel = title ? title + " " + UNKNOWN_OPTION_PREFIX.toLowerCase() : UNKNOWN_OPTION_PREFIX;
1122
+ var translateEnum = title ? utils.TranslatableString.TitleOptionPrefix : utils.TranslatableString.OptionPrefix;
1123
+ var translateParams = title ? [title] : [];
1114
1124
  var enumOptions = retrievedOptions.map(function (opt, index) {
1115
1125
  return {
1116
- label: opt.title || optionLabel + " " + (index + 1),
1126
+ label: opt.title || translateString(translateEnum, translateParams.concat(String(index + 1))),
1117
1127
  value: index
1118
1128
  };
1119
1129
  });
@@ -1368,9 +1378,8 @@ var ObjectField = /*#__PURE__*/function (_Component) {
1368
1378
  * @param type - The type of the new additional schema property
1369
1379
  */
1370
1380
  _proto.getDefaultValue = function getDefaultValue(type) {
1381
+ var translateString = this.props.registry.translateString;
1371
1382
  switch (type) {
1372
- case "string":
1373
- return "New Value";
1374
1383
  case "array":
1375
1384
  return [];
1376
1385
  case "boolean":
@@ -1381,9 +1390,10 @@ var ObjectField = /*#__PURE__*/function (_Component) {
1381
1390
  return 0;
1382
1391
  case "object":
1383
1392
  return {};
1393
+ case "string":
1384
1394
  default:
1385
1395
  // We don't have a datatype for some reason (perhaps additionalProperties was true)
1386
- return "New Value";
1396
+ return translateString(utils.TranslatableString.NewStringDefault);
1387
1397
  }
1388
1398
  }
1389
1399
  /** Handles the adding of a new additional property on the given `schema`. Calls the `onChange` callback once the new
@@ -1517,7 +1527,8 @@ var COMPONENT_TYPES = {
1517
1527
  */
1518
1528
  function getFieldComponent(schema, uiOptions, idSchema, registry) {
1519
1529
  var field = uiOptions.field;
1520
- var fields = registry.fields;
1530
+ var fields = registry.fields,
1531
+ translateString = registry.translateString;
1521
1532
  if (typeof field === "function") {
1522
1533
  return field;
1523
1534
  }
@@ -1539,7 +1550,7 @@ function getFieldComponent(schema, uiOptions, idSchema, registry) {
1539
1550
  return /*#__PURE__*/React__default["default"].createElement(UnsupportedFieldTemplate, {
1540
1551
  schema: schema,
1541
1552
  idSchema: idSchema,
1542
- reason: "Unknown field type " + schema.type,
1553
+ reason: translateString(utils.TranslatableString.UnknownFieldType, [String(schema.type)]),
1543
1554
  registry: registry
1544
1555
  });
1545
1556
  };
@@ -2124,24 +2135,27 @@ function IconButton(props) {
2124
2135
  }));
2125
2136
  }
2126
2137
  function MoveDownButton(props) {
2138
+ var translateString = props.registry.translateString;
2127
2139
  return /*#__PURE__*/React__default["default"].createElement(IconButton, _extends({
2128
- title: "Move down",
2140
+ title: translateString(utils.TranslatableString.MoveDownButton),
2129
2141
  className: "array-item-move-down"
2130
2142
  }, props, {
2131
2143
  icon: "arrow-down"
2132
2144
  }));
2133
2145
  }
2134
2146
  function MoveUpButton(props) {
2147
+ var translateString = props.registry.translateString;
2135
2148
  return /*#__PURE__*/React__default["default"].createElement(IconButton, _extends({
2136
- title: "Move up",
2149
+ title: translateString(utils.TranslatableString.MoveUpButton),
2137
2150
  className: "array-item-move-up"
2138
2151
  }, props, {
2139
2152
  icon: "arrow-up"
2140
2153
  }));
2141
2154
  }
2142
2155
  function RemoveButton(props) {
2156
+ var translateString = props.registry.translateString;
2143
2157
  return /*#__PURE__*/React__default["default"].createElement(IconButton, _extends({
2144
- title: "Remove",
2158
+ title: translateString(utils.TranslatableString.RemoveButton),
2145
2159
  className: "array-item-remove"
2146
2160
  }, props, {
2147
2161
  iconType: "danger",
@@ -2156,6 +2170,7 @@ function AddButton(_ref) {
2156
2170
  onClick = _ref.onClick,
2157
2171
  disabled = _ref.disabled,
2158
2172
  registry = _ref.registry;
2173
+ var translateString = registry.translateString;
2159
2174
  return /*#__PURE__*/React__default["default"].createElement("div", {
2160
2175
  className: "row"
2161
2176
  }, /*#__PURE__*/React__default["default"].createElement("p", {
@@ -2164,7 +2179,7 @@ function AddButton(_ref) {
2164
2179
  iconType: "info",
2165
2180
  icon: "plus",
2166
2181
  className: "btn-add col-xs-12",
2167
- title: "Add",
2182
+ title: translateString(utils.TranslatableString.AddButton),
2168
2183
  onClick: onClick,
2169
2184
  disabled: disabled,
2170
2185
  registry: registry
@@ -2209,14 +2224,16 @@ function DescriptionField(props) {
2209
2224
  * @param props - The `ErrorListProps` for this component
2210
2225
  */
2211
2226
  function ErrorList(_ref) {
2212
- var errors = _ref.errors;
2227
+ var errors = _ref.errors,
2228
+ registry = _ref.registry;
2229
+ var translateString = registry.translateString;
2213
2230
  return /*#__PURE__*/React__default["default"].createElement("div", {
2214
2231
  className: "panel panel-danger errors"
2215
2232
  }, /*#__PURE__*/React__default["default"].createElement("div", {
2216
2233
  className: "panel-heading"
2217
2234
  }, /*#__PURE__*/React__default["default"].createElement("h3", {
2218
2235
  className: "panel-title"
2219
- }, "Errors")), /*#__PURE__*/React__default["default"].createElement("ul", {
2236
+ }, translateString(utils.TranslatableString.ErrorsLabel))), /*#__PURE__*/React__default["default"].createElement("ul", {
2220
2237
  className: "list-group"
2221
2238
  }, errors.map(function (error, i) {
2222
2239
  return /*#__PURE__*/React__default["default"].createElement("li", {
@@ -2399,10 +2416,22 @@ function TitleField(props) {
2399
2416
  function UnsupportedField(props) {
2400
2417
  var schema = props.schema,
2401
2418
  idSchema = props.idSchema,
2402
- reason = props.reason;
2419
+ reason = props.reason,
2420
+ registry = props.registry;
2421
+ var translateString = registry.translateString;
2422
+ var translateEnum = utils.TranslatableString.UnsupportedField;
2423
+ var translateParams = [];
2424
+ if (idSchema && idSchema.$id) {
2425
+ translateEnum = utils.TranslatableString.UnsupportedFieldWithId;
2426
+ translateParams.push(idSchema.$id);
2427
+ }
2428
+ if (reason) {
2429
+ translateEnum = translateEnum === utils.TranslatableString.UnsupportedField ? utils.TranslatableString.UnsupportedFieldWithReason : utils.TranslatableString.UnsupportedFieldWithIdAndReason;
2430
+ translateParams.push(reason);
2431
+ }
2403
2432
  return /*#__PURE__*/React__default["default"].createElement("div", {
2404
2433
  className: "unsupported-field"
2405
- }, /*#__PURE__*/React__default["default"].createElement("p", null, "Unsupported field schema", idSchema && idSchema.$id && /*#__PURE__*/React__default["default"].createElement("span", null, " for", " field ", /*#__PURE__*/React__default["default"].createElement("code", null, idSchema.$id)), reason && /*#__PURE__*/React__default["default"].createElement("em", null, ": ", reason), "."), schema && /*#__PURE__*/React__default["default"].createElement("pre", null, JSON.stringify(schema, null, 2)));
2434
+ }, /*#__PURE__*/React__default["default"].createElement("p", null, /*#__PURE__*/React__default["default"].createElement(Markdown__default["default"], null, translateString(translateEnum, translateParams))), schema && /*#__PURE__*/React__default["default"].createElement("pre", null, JSON.stringify(schema, null, 2)));
2406
2435
  }
2407
2436
 
2408
2437
  /** The `WrapIfAdditional` component is used by the `FieldTemplate` to rename, or remove properties that are
@@ -2424,9 +2453,11 @@ function WrapIfAdditionalTemplate(props) {
2424
2453
  children = props.children,
2425
2454
  uiSchema = props.uiSchema,
2426
2455
  registry = props.registry;
2456
+ var templates = registry.templates,
2457
+ translateString = registry.translateString;
2427
2458
  // Button templates are not overridden in the uiSchema
2428
- var RemoveButton = registry.templates.ButtonTemplates.RemoveButton;
2429
- var keyLabel = label + " Key"; // i18n ?
2459
+ var RemoveButton = templates.ButtonTemplates.RemoveButton;
2460
+ var keyLabel = translateString(utils.TranslatableString.KeyLabel, [label]);
2430
2461
  var additional = (utils.ADDITIONAL_PROPERTY_FLAG in schema);
2431
2462
  if (!additional) {
2432
2463
  return /*#__PURE__*/React__default["default"].createElement("div", {
@@ -2603,6 +2634,7 @@ function AltDateWidget(_ref2) {
2603
2634
  onFocus = _ref2.onFocus,
2604
2635
  onChange = _ref2.onChange,
2605
2636
  value = _ref2.value;
2637
+ var translateString = registry.translateString;
2606
2638
  var _useReducer = React.useReducer(function (state, action) {
2607
2639
  return _extends({}, state, action);
2608
2640
  }, utils.parseDateString(value, time)),
@@ -2643,6 +2675,7 @@ function AltDateWidget(_ref2) {
2643
2675
  className: "list-inline"
2644
2676
  }, dateElementProps(state, time, options.yearsRange).map(function (elemProps, i) {
2645
2677
  return /*#__PURE__*/React__default["default"].createElement("li", {
2678
+ className: "list-inline-item",
2646
2679
  key: i
2647
2680
  }, /*#__PURE__*/React__default["default"].createElement(DateElement, _extends({
2648
2681
  rootId: id,
@@ -2655,15 +2688,19 @@ function AltDateWidget(_ref2) {
2655
2688
  onFocus: onFocus,
2656
2689
  autofocus: autofocus && i === 0
2657
2690
  })));
2658
- }), (options.hideNowButton !== "undefined" ? !options.hideNowButton : true) && /*#__PURE__*/React__default["default"].createElement("li", null, /*#__PURE__*/React__default["default"].createElement("a", {
2691
+ }), (options.hideNowButton !== "undefined" ? !options.hideNowButton : true) && /*#__PURE__*/React__default["default"].createElement("li", {
2692
+ className: "list-inline-item"
2693
+ }, /*#__PURE__*/React__default["default"].createElement("a", {
2659
2694
  href: "#",
2660
2695
  className: "btn btn-info btn-now",
2661
2696
  onClick: handleSetNow
2662
- }, "Now")), (options.hideClearButton !== "undefined" ? !options.hideClearButton : true) && /*#__PURE__*/React__default["default"].createElement("li", null, /*#__PURE__*/React__default["default"].createElement("a", {
2697
+ }, translateString(utils.TranslatableString.NowLabel))), (options.hideClearButton !== "undefined" ? !options.hideClearButton : true) && /*#__PURE__*/React__default["default"].createElement("li", {
2698
+ className: "list-inline-item"
2699
+ }, /*#__PURE__*/React__default["default"].createElement("a", {
2663
2700
  href: "#",
2664
2701
  className: "btn btn-warning btn-clear",
2665
2702
  onClick: handleClear
2666
- }, "Clear")));
2703
+ }, translateString(utils.TranslatableString.ClearLabel))));
2667
2704
  }
2668
2705
 
2669
2706
  var _excluded$1 = ["time"];
@@ -2916,10 +2953,12 @@ function processFiles(files) {
2916
2953
  return Promise.all(Array.from(files).map(processFile));
2917
2954
  }
2918
2955
  function FilesInfo(_ref) {
2919
- var filesInfo = _ref.filesInfo;
2956
+ var filesInfo = _ref.filesInfo,
2957
+ registry = _ref.registry;
2920
2958
  if (filesInfo.length === 0) {
2921
2959
  return null;
2922
2960
  }
2961
+ var translateString = registry.translateString;
2923
2962
  return /*#__PURE__*/React__default["default"].createElement("ul", {
2924
2963
  className: "file-info"
2925
2964
  }, filesInfo.map(function (fileInfo, key) {
@@ -2928,7 +2967,7 @@ function FilesInfo(_ref) {
2928
2967
  type = fileInfo.type;
2929
2968
  return /*#__PURE__*/React__default["default"].createElement("li", {
2930
2969
  key: key
2931
- }, /*#__PURE__*/React__default["default"].createElement("strong", null, name), " (", type, ", ", size, " bytes)");
2970
+ }, /*#__PURE__*/React__default["default"].createElement(Markdown__default["default"], null, translateString(utils.TranslatableString.FilesInfo, [name, type, String(size)])));
2932
2971
  }));
2933
2972
  }
2934
2973
  function extractFileInfo(dataURLs) {
@@ -2958,7 +2997,8 @@ function FileWidget(_ref2) {
2958
2997
  value = _ref2.value,
2959
2998
  _ref2$autofocus = _ref2.autofocus,
2960
2999
  autofocus = _ref2$autofocus === void 0 ? false : _ref2$autofocus,
2961
- options = _ref2.options;
3000
+ options = _ref2.options,
3001
+ registry = _ref2.registry;
2962
3002
  var extractedFilesInfo = React.useMemo(function () {
2963
3003
  return Array.isArray(value) ? extractFileInfo(value) : extractFileInfo([value]);
2964
3004
  }, [value]);
@@ -2993,7 +3033,8 @@ function FileWidget(_ref2) {
2993
3033
  accept: options.accept ? String(options.accept) : undefined,
2994
3034
  "aria-describedby": utils.ariaDescribedByIds(id)
2995
3035
  })), /*#__PURE__*/React__default["default"].createElement(FilesInfo, {
2996
- filesInfo: filesInfo
3036
+ filesInfo: filesInfo,
3037
+ registry: registry
2997
3038
  }));
2998
3039
  }
2999
3040
 
@@ -3305,7 +3346,8 @@ function getDefaultRegistry() {
3305
3346
  templates: templates(),
3306
3347
  widgets: widgets(),
3307
3348
  rootSchema: {},
3308
- formContext: {}
3349
+ formContext: {},
3350
+ translateString: utils.englishStringTranslator
3309
3351
  };
3310
3352
  }
3311
3353
 
@@ -3532,7 +3574,7 @@ var Form = /*#__PURE__*/function (_Component) {
3532
3574
  if (!schemaUtils || schemaUtils.doesSchemaUtilsDiffer(props.validator, rootSchema)) {
3533
3575
  schemaUtils = utils.createSchemaUtils(props.validator, rootSchema);
3534
3576
  }
3535
- var formData = schemaUtils.getDefaultFormState(schema, inputFormData, "excludeObjectChildren");
3577
+ var formData = schemaUtils.getDefaultFormState(schema, inputFormData);
3536
3578
  var retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
3537
3579
  var getCurrentErrors = function getCurrentErrors() {
3538
3580
  if (props.noValidate) {
@@ -3633,7 +3675,8 @@ var Form = /*#__PURE__*/function (_Component) {
3633
3675
  errorSchema: errorSchema || {},
3634
3676
  schema: schema,
3635
3677
  uiSchema: uiSchema,
3636
- formContext: formContext
3678
+ formContext: formContext,
3679
+ registry: registry
3637
3680
  });
3638
3681
  }
3639
3682
  return null;
@@ -3646,12 +3689,14 @@ var Form = /*#__PURE__*/function (_Component) {
3646
3689
  /** Returns the registry for the form */
3647
3690
  _proto.getRegistry = function getRegistry() {
3648
3691
  var _this$props$templates;
3692
+ var customTranslateString = this.props.translateString;
3649
3693
  var schemaUtils = this.state.schemaUtils;
3650
3694
  var _getDefaultRegistry = getDefaultRegistry(),
3651
3695
  fields = _getDefaultRegistry.fields,
3652
3696
  templates = _getDefaultRegistry.templates,
3653
3697
  widgets = _getDefaultRegistry.widgets,
3654
- formContext = _getDefaultRegistry.formContext;
3698
+ formContext = _getDefaultRegistry.formContext,
3699
+ translateString = _getDefaultRegistry.translateString;
3655
3700
  return {
3656
3701
  fields: _extends({}, fields, this.props.fields),
3657
3702
  templates: _extends({}, templates, this.props.templates, {
@@ -3660,7 +3705,8 @@ var Form = /*#__PURE__*/function (_Component) {
3660
3705
  widgets: _extends({}, widgets, this.props.widgets),
3661
3706
  rootSchema: this.props.schema,
3662
3707
  formContext: this.props.formContext || formContext,
3663
- schemaUtils: schemaUtils
3708
+ schemaUtils: schemaUtils,
3709
+ translateString: customTranslateString || translateString
3664
3710
  };
3665
3711
  }
3666
3712
  /** Provides a function that can be used to programmatically submit the `Form` */;
@@ -3672,15 +3718,47 @@ var Form = /*#__PURE__*/function (_Component) {
3672
3718
  this.formElement.current.requestSubmit();
3673
3719
  }
3674
3720
  }
3721
+ /** Attempts to focus on the field associated with the `error`. Uses the `property` field to compute path of the error
3722
+ * field, then, using the `idPrefix` and `idSeparator` converts that path into an id. Then the input element with that
3723
+ * id is attempted to be found using the `formElement` ref. If it is located, then it is focused.
3724
+ *
3725
+ * @param error - The error on which to focus
3726
+ */;
3727
+ _proto.focusOnError = function focusOnError(error) {
3728
+ var _this$props4 = this.props,
3729
+ _this$props4$idPrefix = _this$props4.idPrefix,
3730
+ idPrefix = _this$props4$idPrefix === void 0 ? "root" : _this$props4$idPrefix,
3731
+ _this$props4$idSepara = _this$props4.idSeparator,
3732
+ idSeparator = _this$props4$idSepara === void 0 ? "_" : _this$props4$idSepara;
3733
+ var property = error.property;
3734
+ var path = _toPath__default["default"](property);
3735
+ if (path[0] === "") {
3736
+ // Most of the time the `.foo` property results in the first element being empty, so replace it with the idPrefix
3737
+ path[0] = idPrefix;
3738
+ } else {
3739
+ // Otherwise insert the idPrefix into the first location using unshift
3740
+ path.unshift(idPrefix);
3741
+ }
3742
+ var elementId = path.join(idSeparator);
3743
+ var field = this.formElement.current.elements[elementId];
3744
+ if (!field) {
3745
+ // if not an exact match, try finding an input starting with the element id (like radio buttons or checkboxes)
3746
+ field = this.formElement.current.querySelector("input[id^=" + elementId);
3747
+ }
3748
+ if (field) {
3749
+ field.focus();
3750
+ }
3751
+ }
3675
3752
  /** Programmatically validate the form. If `onError` is provided, then it will be called with the list of errors the
3676
3753
  * same way as would happen on form submission.
3677
3754
  *
3678
3755
  * @returns - True if the form is valid, false otherwise.
3679
3756
  */;
3680
3757
  _proto.validateForm = function validateForm() {
3681
- var _this$props4 = this.props,
3682
- extraErrors = _this$props4.extraErrors,
3683
- onError = _this$props4.onError;
3758
+ var _this$props5 = this.props,
3759
+ extraErrors = _this$props5.extraErrors,
3760
+ focusOnFirstError = _this$props5.focusOnFirstError,
3761
+ onError = _this$props5.onError;
3684
3762
  var formData = this.state.formData;
3685
3763
  var schemaUtils = this.state.schemaUtils;
3686
3764
  var schemaValidation = this.validate(formData);
@@ -3694,6 +3772,9 @@ var Form = /*#__PURE__*/function (_Component) {
3694
3772
  errorSchema = merged.errorSchema;
3695
3773
  errors = merged.errors;
3696
3774
  }
3775
+ if (focusOnFirstError) {
3776
+ this.focusOnError(schemaValidation.errors[0]);
3777
+ }
3697
3778
  this.setState({
3698
3779
  errors: errors,
3699
3780
  errorSchema: errorSchema,
@@ -3714,31 +3795,31 @@ var Form = /*#__PURE__*/function (_Component) {
3714
3795
  * needed along with the submit button or any children of the form.
3715
3796
  */;
3716
3797
  _proto.render = function render() {
3717
- var _this$props5 = this.props,
3718
- children = _this$props5.children,
3719
- id = _this$props5.id,
3720
- idPrefix = _this$props5.idPrefix,
3721
- idSeparator = _this$props5.idSeparator,
3722
- _this$props5$classNam = _this$props5.className,
3723
- className = _this$props5$classNam === void 0 ? "" : _this$props5$classNam,
3724
- tagName = _this$props5.tagName,
3725
- name = _this$props5.name,
3726
- method = _this$props5.method,
3727
- target = _this$props5.target,
3728
- action = _this$props5.action,
3729
- autoComplete = _this$props5.autoComplete,
3730
- enctype = _this$props5.enctype,
3731
- acceptcharset = _this$props5.acceptcharset,
3732
- _this$props5$noHtml5V = _this$props5.noHtml5Validate,
3733
- noHtml5Validate = _this$props5$noHtml5V === void 0 ? false : _this$props5$noHtml5V,
3734
- _this$props5$disabled = _this$props5.disabled,
3735
- disabled = _this$props5$disabled === void 0 ? false : _this$props5$disabled,
3736
- _this$props5$readonly = _this$props5.readonly,
3737
- readonly = _this$props5$readonly === void 0 ? false : _this$props5$readonly,
3738
- formContext = _this$props5.formContext,
3739
- _this$props5$showErro = _this$props5.showErrorList,
3740
- showErrorList = _this$props5$showErro === void 0 ? "top" : _this$props5$showErro,
3741
- _internalFormWrapper = _this$props5._internalFormWrapper;
3798
+ var _this$props6 = this.props,
3799
+ children = _this$props6.children,
3800
+ id = _this$props6.id,
3801
+ idPrefix = _this$props6.idPrefix,
3802
+ idSeparator = _this$props6.idSeparator,
3803
+ _this$props6$classNam = _this$props6.className,
3804
+ className = _this$props6$classNam === void 0 ? "" : _this$props6$classNam,
3805
+ tagName = _this$props6.tagName,
3806
+ name = _this$props6.name,
3807
+ method = _this$props6.method,
3808
+ target = _this$props6.target,
3809
+ action = _this$props6.action,
3810
+ autoComplete = _this$props6.autoComplete,
3811
+ enctype = _this$props6.enctype,
3812
+ acceptcharset = _this$props6.acceptcharset,
3813
+ _this$props6$noHtml5V = _this$props6.noHtml5Validate,
3814
+ noHtml5Validate = _this$props6$noHtml5V === void 0 ? false : _this$props6$noHtml5V,
3815
+ _this$props6$disabled = _this$props6.disabled,
3816
+ disabled = _this$props6$disabled === void 0 ? false : _this$props6$disabled,
3817
+ _this$props6$readonly = _this$props6.readonly,
3818
+ readonly = _this$props6$readonly === void 0 ? false : _this$props6$readonly,
3819
+ formContext = _this$props6.formContext,
3820
+ _this$props6$showErro = _this$props6.showErrorList,
3821
+ showErrorList = _this$props6$showErro === void 0 ? "top" : _this$props6$showErro,
3822
+ _internalFormWrapper = _this$props6._internalFormWrapper;
3742
3823
  var _this$state4 = this.state,
3743
3824
  schema = _this$state4.schema,
3744
3825
  uiSchema = _this$state4.uiSchema,