@rjsf/core 6.6.2 → 6.7.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.
Files changed (162) hide show
  1. package/LICENSE.md +201 -0
  2. package/dist/core.umd.js +274 -245
  3. package/dist/index.cjs +911 -873
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.esm.js +702 -659
  6. package/dist/index.esm.js.map +4 -4
  7. package/lib/components/Form.d.ts +2 -2
  8. package/lib/components/Form.d.ts.map +1 -1
  9. package/lib/components/Form.js +30 -15
  10. package/lib/components/RichDescription.d.ts +1 -1
  11. package/lib/components/RichDescription.d.ts.map +1 -1
  12. package/lib/components/RichHelp.d.ts +1 -1
  13. package/lib/components/RichHelp.d.ts.map +1 -1
  14. package/lib/components/SchemaExamples.d.ts +1 -1
  15. package/lib/components/SchemaExamples.d.ts.map +1 -1
  16. package/lib/components/fields/ArrayField.d.ts +1 -1
  17. package/lib/components/fields/ArrayField.d.ts.map +1 -1
  18. package/lib/components/fields/BooleanField.d.ts +1 -1
  19. package/lib/components/fields/BooleanField.d.ts.map +1 -1
  20. package/lib/components/fields/CyclicSchemaField.d.ts +8 -0
  21. package/lib/components/fields/CyclicSchemaField.d.ts.map +1 -0
  22. package/lib/components/fields/CyclicSchemaField.js +21 -0
  23. package/lib/components/fields/FallbackField.d.ts +1 -1
  24. package/lib/components/fields/FallbackField.d.ts.map +1 -1
  25. package/lib/components/fields/LayoutGridField.d.ts +1 -1
  26. package/lib/components/fields/LayoutGridField.d.ts.map +1 -1
  27. package/lib/components/fields/LayoutHeaderField.d.ts +1 -1
  28. package/lib/components/fields/LayoutHeaderField.d.ts.map +1 -1
  29. package/lib/components/fields/LayoutMultiSchemaField.d.ts +1 -1
  30. package/lib/components/fields/LayoutMultiSchemaField.d.ts.map +1 -1
  31. package/lib/components/fields/MultiSchemaField.d.ts +1 -46
  32. package/lib/components/fields/MultiSchemaField.d.ts.map +1 -1
  33. package/lib/components/fields/MultiSchemaField.js +111 -135
  34. package/lib/components/fields/NumberField.d.ts +1 -1
  35. package/lib/components/fields/NumberField.d.ts.map +1 -1
  36. package/lib/components/fields/NumberField.js +1 -1
  37. package/lib/components/fields/ObjectField.d.ts +1 -1
  38. package/lib/components/fields/ObjectField.d.ts.map +1 -1
  39. package/lib/components/fields/ObjectField.js +2 -2
  40. package/lib/components/fields/OptionalDataControlsField.d.ts +1 -1
  41. package/lib/components/fields/OptionalDataControlsField.d.ts.map +1 -1
  42. package/lib/components/fields/SchemaField.d.ts +13 -7
  43. package/lib/components/fields/SchemaField.d.ts.map +1 -1
  44. package/lib/components/fields/SchemaField.js +37 -24
  45. package/lib/components/fields/StringField.d.ts +1 -1
  46. package/lib/components/fields/StringField.d.ts.map +1 -1
  47. package/lib/components/fields/index.d.ts.map +1 -1
  48. package/lib/components/fields/index.js +2 -0
  49. package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts +1 -1
  50. package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts.map +1 -1
  51. package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts +1 -1
  52. package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts.map +1 -1
  53. package/lib/components/templates/ArrayFieldItemTemplate.d.ts +1 -1
  54. package/lib/components/templates/ArrayFieldItemTemplate.d.ts.map +1 -1
  55. package/lib/components/templates/ArrayFieldTemplate.d.ts +1 -1
  56. package/lib/components/templates/ArrayFieldTemplate.d.ts.map +1 -1
  57. package/lib/components/templates/ArrayFieldTitleTemplate.d.ts +1 -1
  58. package/lib/components/templates/ArrayFieldTitleTemplate.d.ts.map +1 -1
  59. package/lib/components/templates/BaseInputTemplate.d.ts +1 -1
  60. package/lib/components/templates/BaseInputTemplate.d.ts.map +1 -1
  61. package/lib/components/templates/BaseInputTemplate.js +2 -2
  62. package/lib/components/templates/ButtonTemplates/AddButton.d.ts +1 -1
  63. package/lib/components/templates/ButtonTemplates/AddButton.d.ts.map +1 -1
  64. package/lib/components/templates/ButtonTemplates/IconButton.d.ts +6 -6
  65. package/lib/components/templates/ButtonTemplates/IconButton.d.ts.map +1 -1
  66. package/lib/components/templates/ButtonTemplates/SubmitButton.d.ts +1 -1
  67. package/lib/components/templates/ButtonTemplates/SubmitButton.d.ts.map +1 -1
  68. package/lib/components/templates/CyclicSchemaExpandTemplate.d.ts +7 -0
  69. package/lib/components/templates/CyclicSchemaExpandTemplate.d.ts.map +1 -0
  70. package/lib/components/templates/CyclicSchemaExpandTemplate.js +12 -0
  71. package/lib/components/templates/DescriptionField.d.ts +1 -1
  72. package/lib/components/templates/DescriptionField.d.ts.map +1 -1
  73. package/lib/components/templates/ErrorList.d.ts +1 -1
  74. package/lib/components/templates/ErrorList.d.ts.map +1 -1
  75. package/lib/components/templates/FallbackFieldTemplate.d.ts +1 -1
  76. package/lib/components/templates/FallbackFieldTemplate.d.ts.map +1 -1
  77. package/lib/components/templates/FieldErrorTemplate.d.ts +1 -1
  78. package/lib/components/templates/FieldErrorTemplate.d.ts.map +1 -1
  79. package/lib/components/templates/FieldHelpTemplate.d.ts +1 -1
  80. package/lib/components/templates/FieldHelpTemplate.d.ts.map +1 -1
  81. package/lib/components/templates/FieldTemplate/FieldTemplate.d.ts +1 -1
  82. package/lib/components/templates/FieldTemplate/FieldTemplate.d.ts.map +1 -1
  83. package/lib/components/templates/FieldTemplate/Label.d.ts +1 -1
  84. package/lib/components/templates/FieldTemplate/Label.d.ts.map +1 -1
  85. package/lib/components/templates/GridTemplate.d.ts +1 -1
  86. package/lib/components/templates/GridTemplate.d.ts.map +1 -1
  87. package/lib/components/templates/MultiSchemaFieldTemplate.d.ts +1 -1
  88. package/lib/components/templates/MultiSchemaFieldTemplate.d.ts.map +1 -1
  89. package/lib/components/templates/ObjectFieldTemplate.d.ts +1 -1
  90. package/lib/components/templates/ObjectFieldTemplate.d.ts.map +1 -1
  91. package/lib/components/templates/OptionalDataControlsTemplate.d.ts +1 -1
  92. package/lib/components/templates/OptionalDataControlsTemplate.d.ts.map +1 -1
  93. package/lib/components/templates/TitleField.d.ts +1 -1
  94. package/lib/components/templates/TitleField.d.ts.map +1 -1
  95. package/lib/components/templates/UnsupportedField.d.ts +1 -1
  96. package/lib/components/templates/UnsupportedField.d.ts.map +1 -1
  97. package/lib/components/templates/UnsupportedField.js +1 -1
  98. package/lib/components/templates/WrapIfAdditionalTemplate.d.ts +1 -1
  99. package/lib/components/templates/WrapIfAdditionalTemplate.d.ts.map +1 -1
  100. package/lib/components/templates/index.d.ts.map +1 -1
  101. package/lib/components/templates/index.js +2 -0
  102. package/lib/components/widgets/AltDateTimeWidget.d.ts +1 -1
  103. package/lib/components/widgets/AltDateTimeWidget.d.ts.map +1 -1
  104. package/lib/components/widgets/AltDateWidget.d.ts +1 -1
  105. package/lib/components/widgets/AltDateWidget.d.ts.map +1 -1
  106. package/lib/components/widgets/CheckboxWidget.d.ts +1 -1
  107. package/lib/components/widgets/CheckboxWidget.d.ts.map +1 -1
  108. package/lib/components/widgets/CheckboxesWidget.d.ts +1 -1
  109. package/lib/components/widgets/CheckboxesWidget.d.ts.map +1 -1
  110. package/lib/components/widgets/CheckboxesWidget.js +2 -2
  111. package/lib/components/widgets/ColorWidget.d.ts +1 -1
  112. package/lib/components/widgets/ColorWidget.d.ts.map +1 -1
  113. package/lib/components/widgets/DateTimeWidget.d.ts +1 -1
  114. package/lib/components/widgets/DateTimeWidget.d.ts.map +1 -1
  115. package/lib/components/widgets/DateWidget.d.ts +1 -1
  116. package/lib/components/widgets/DateWidget.d.ts.map +1 -1
  117. package/lib/components/widgets/EmailWidget.d.ts +1 -1
  118. package/lib/components/widgets/EmailWidget.d.ts.map +1 -1
  119. package/lib/components/widgets/FileWidget.d.ts +1 -1
  120. package/lib/components/widgets/FileWidget.d.ts.map +1 -1
  121. package/lib/components/widgets/HiddenWidget.d.ts +1 -1
  122. package/lib/components/widgets/HiddenWidget.d.ts.map +1 -1
  123. package/lib/components/widgets/PasswordWidget.d.ts +1 -1
  124. package/lib/components/widgets/PasswordWidget.d.ts.map +1 -1
  125. package/lib/components/widgets/RadioWidget.d.ts +1 -1
  126. package/lib/components/widgets/RadioWidget.d.ts.map +1 -1
  127. package/lib/components/widgets/RadioWidget.js +2 -2
  128. package/lib/components/widgets/RangeWidget.d.ts +1 -1
  129. package/lib/components/widgets/RangeWidget.d.ts.map +1 -1
  130. package/lib/components/widgets/RatingWidget.d.ts +1 -1
  131. package/lib/components/widgets/RatingWidget.d.ts.map +1 -1
  132. package/lib/components/widgets/SelectWidget.d.ts +1 -1
  133. package/lib/components/widgets/SelectWidget.d.ts.map +1 -1
  134. package/lib/components/widgets/SelectWidget.js +9 -8
  135. package/lib/components/widgets/TextWidget.d.ts +1 -1
  136. package/lib/components/widgets/TextWidget.d.ts.map +1 -1
  137. package/lib/components/widgets/TextareaWidget.d.ts +1 -1
  138. package/lib/components/widgets/TextareaWidget.d.ts.map +1 -1
  139. package/lib/components/widgets/TextareaWidget.js +3 -3
  140. package/lib/components/widgets/TimeWidget.d.ts +1 -1
  141. package/lib/components/widgets/TimeWidget.d.ts.map +1 -1
  142. package/lib/components/widgets/URLWidget.d.ts +1 -1
  143. package/lib/components/widgets/URLWidget.d.ts.map +1 -1
  144. package/lib/components/widgets/UpDownWidget.d.ts +1 -1
  145. package/lib/components/widgets/UpDownWidget.d.ts.map +1 -1
  146. package/lib/tsconfig.tsbuildinfo +1 -1
  147. package/package.json +28 -27
  148. package/src/components/Form.tsx +34 -15
  149. package/src/components/fields/CyclicSchemaField.tsx +40 -0
  150. package/src/components/fields/MultiSchemaField.tsx +201 -230
  151. package/src/components/fields/NumberField.tsx +1 -1
  152. package/src/components/fields/ObjectField.tsx +5 -2
  153. package/src/components/fields/SchemaField.tsx +46 -34
  154. package/src/components/fields/index.ts +2 -0
  155. package/src/components/templates/BaseInputTemplate.tsx +2 -5
  156. package/src/components/templates/CyclicSchemaExpandTemplate.tsx +31 -0
  157. package/src/components/templates/UnsupportedField.tsx +1 -1
  158. package/src/components/templates/index.ts +2 -0
  159. package/src/components/widgets/CheckboxesWidget.tsx +2 -2
  160. package/src/components/widgets/RadioWidget.tsx +2 -2
  161. package/src/components/widgets/SelectWidget.tsx +45 -30
  162. package/src/components/widgets/TextareaWidget.tsx +3 -3
package/dist/core.umd.js CHANGED
@@ -898,6 +898,33 @@
898
898
  );
899
899
  }
900
900
  var BooleanField_default = BooleanField;
901
+ function CyclicSchemaField(props) {
902
+ const [expanded, setExpanded] = react.useState(false);
903
+ const { name, registry, schema, uiSchema, fieldPathId } = props;
904
+ const { globalUiOptions } = registry;
905
+ const uiOptions = utils.getUiOptions(uiSchema, globalUiOptions);
906
+ const CyclicSchemaExpandTemplate2 = utils.getTemplate(
907
+ "CyclicSchemaExpandTemplate",
908
+ registry,
909
+ uiOptions
910
+ );
911
+ if (!expanded) {
912
+ return /* @__PURE__ */ jsxRuntime.jsx(
913
+ CyclicSchemaExpandTemplate2,
914
+ {
915
+ registry,
916
+ schema,
917
+ uiSchema,
918
+ name,
919
+ fieldPathId,
920
+ onExpand: () => setExpanded(true)
921
+ }
922
+ );
923
+ }
924
+ const { fields: fields2 } = registry;
925
+ const { SchemaField: SchemaField2 } = fields2;
926
+ return /* @__PURE__ */ jsxRuntime.jsx(SchemaField2, { ...props, schema: { ...schema, [utils.RJSF_REF_CYCLE_KEY]: false } });
927
+ }
901
928
  function getFallbackTypeSelectionSchema(title) {
902
929
  return {
903
930
  type: "string",
@@ -1523,217 +1550,179 @@
1523
1550
  }
1524
1551
  );
1525
1552
  }
1526
- var AnyOfField = class extends react.Component {
1527
- /** Flag to skip the formData-change-driven option recalculation when the user just selected an option.
1528
- * Set to true in the setState callback of onOptionChange (after onChange is called), consumed and reset in
1529
- * componentDidUpdate. This prevents the matching-option recalculation from overriding a user's explicit choice
1530
- * when getDefaultFormState populates undefined properties that make deepEquals see a false formData change.
1531
- */
1532
- skipNextOptionRecalculation = false;
1533
- /** Constructs an `AnyOfField` with the given `props` to initialize the initially selected option in state
1534
- *
1535
- * @param props - The `FieldProps` for this template
1536
- */
1537
- constructor(props) {
1538
- super(props);
1539
- const {
1540
- formData,
1541
- options,
1542
- registry: { schemaUtils }
1543
- } = this.props;
1544
- const retrievedOptions = options.map((opt) => schemaUtils.retrieveSchema(opt, formData));
1545
- this.state = {
1546
- retrievedOptions,
1547
- selectedOption: this.getMatchingOption(0, formData, retrievedOptions)
1548
- };
1549
- }
1550
- /** React lifecycle method that is called when the props and/or state for this component is updated. It recomputes the
1551
- * currently selected option based on the overall `formData`
1552
- *
1553
- * @param prevProps - The previous `FieldProps` for this template
1554
- * @param prevState - The previous `AnyOfFieldState` for this template
1555
- */
1556
- componentDidUpdate(prevProps, prevState) {
1557
- const { formData, options, fieldPathId } = this.props;
1558
- const { selectedOption } = this.state;
1559
- let newState = this.state;
1560
- if (!utils.deepEquals(prevProps.options, options)) {
1561
- const {
1562
- registry: { schemaUtils }
1563
- } = this.props;
1564
- const retrievedOptions = options.map((opt) => schemaUtils.retrieveSchema(opt, formData));
1565
- newState = { selectedOption, retrievedOptions };
1553
+ function AnyOfField(props) {
1554
+ const {
1555
+ name,
1556
+ disabled = false,
1557
+ errorSchema = {},
1558
+ formData,
1559
+ fieldPathId,
1560
+ onBlur,
1561
+ onChange,
1562
+ onFocus,
1563
+ options,
1564
+ readonly,
1565
+ registry,
1566
+ required = false,
1567
+ schema,
1568
+ uiSchema
1569
+ } = props;
1570
+ const { schemaUtils } = registry;
1571
+ const formDataHash = utils.hashObject(formData ?? null);
1572
+ const retrievedOptions = react.useMemo(
1573
+ () => options.map((opt) => schemaUtils.retrieveSchema(opt, formData)),
1574
+ // oxlint-disable-next-line react-hooks/exhaustive-deps -- formDataHash is the value-stable proxy for formData
1575
+ [options, schemaUtils, formDataHash]
1576
+ );
1577
+ const [selectedOption, setSelectedOption] = react.useState(() => {
1578
+ const discriminator = utils.getDiscriminatorFieldFromSchema(schema);
1579
+ return schemaUtils.getClosestMatchingOption(formData, retrievedOptions, 0, discriminator);
1580
+ });
1581
+ const skipNextOptionRecalculation = react.useRef(false);
1582
+ const prevFormDataRef = react.useRef(formData);
1583
+ const prevFieldIdRef = react.useRef(fieldPathId.$id);
1584
+ react.useEffect(() => {
1585
+ const prevFormData = prevFormDataRef.current;
1586
+ const prevFieldId = prevFieldIdRef.current;
1587
+ prevFormDataRef.current = formData;
1588
+ prevFieldIdRef.current = fieldPathId.$id;
1589
+ if (!utils.deepEquals(formData, prevFormData) && fieldPathId.$id === prevFieldId) {
1590
+ if (skipNextOptionRecalculation.current) {
1591
+ skipNextOptionRecalculation.current = false;
1592
+ return;
1593
+ }
1594
+ const discriminator = utils.getDiscriminatorFieldFromSchema(schema);
1595
+ const matchingOption = schemaUtils.getClosestMatchingOption(
1596
+ formData,
1597
+ retrievedOptions,
1598
+ selectedOption,
1599
+ discriminator
1600
+ );
1601
+ if (matchingOption !== selectedOption) {
1602
+ setSelectedOption(matchingOption);
1603
+ }
1566
1604
  }
1567
- if (!utils.deepEquals(formData, prevProps.formData) && fieldPathId.$id === prevProps.fieldPathId.$id) {
1568
- if (this.skipNextOptionRecalculation) {
1569
- this.skipNextOptionRecalculation = false;
1570
- } else {
1571
- const { retrievedOptions } = newState;
1572
- const matchingOption = this.getMatchingOption(selectedOption, formData, retrievedOptions);
1573
- if (prevState && matchingOption !== selectedOption) {
1574
- newState = { selectedOption: matchingOption, retrievedOptions };
1575
- }
1605
+ });
1606
+ const fieldId = `${fieldPathId.$id}${schema.oneOf ? "__oneof_select" : "__anyof_select"}`;
1607
+ const onOptionChange = react.useCallback(
1608
+ (option2) => {
1609
+ if (disabled || readonly) {
1610
+ return;
1611
+ }
1612
+ const intOption = option2 !== void 0 ? parseInt(option2, 10) : -1;
1613
+ if (intOption === selectedOption) {
1614
+ return;
1576
1615
  }
1616
+ const newOption = intOption >= 0 ? retrievedOptions[intOption] : void 0;
1617
+ const oldOption = selectedOption >= 0 ? retrievedOptions[selectedOption] : void 0;
1618
+ let newFormData = schemaUtils.sanitizeDataForNewSchema(newOption, oldOption, formData);
1619
+ if (newOption) {
1620
+ newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, "excludeObjectChildren");
1621
+ }
1622
+ setSelectedOption(intOption);
1623
+ skipNextOptionRecalculation.current = true;
1624
+ onChange(newFormData, fieldPathId.path, void 0, fieldId);
1625
+ },
1626
+ // setSelectedOption is stable (guaranteed by useState); skipNextOptionRecalculation is a ref
1627
+ [selectedOption, retrievedOptions, disabled, readonly, schemaUtils, formData, fieldPathId, onChange, fieldId]
1628
+ );
1629
+ const { widgets: widgets2, fields: fields2, translateString, globalUiOptions } = registry;
1630
+ const { SchemaField: SchemaFieldComponent } = fields2;
1631
+ const MultiSchemaFieldTemplate2 = utils.getTemplate(
1632
+ "MultiSchemaFieldTemplate",
1633
+ registry,
1634
+ globalUiOptions
1635
+ );
1636
+ const isOptionalRender = utils.shouldRenderOptionalField(registry, schema, required, uiSchema);
1637
+ const hasFormData = utils.isFormDataAvailable(formData);
1638
+ const {
1639
+ widget = "select",
1640
+ placeholder,
1641
+ autofocus,
1642
+ autocomplete,
1643
+ title = schema.title,
1644
+ ...uiOptions
1645
+ } = utils.getUiOptions(uiSchema, globalUiOptions);
1646
+ const Widget = utils.getWidget({ type: "number" }, widget, widgets2);
1647
+ const rawErrors = get(errorSchema, utils.ERRORS_KEY, []);
1648
+ const fieldErrorSchema = omit3(errorSchema, [utils.ERRORS_KEY]);
1649
+ const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
1650
+ const option = selectedOption >= 0 ? retrievedOptions[selectedOption] || null : null;
1651
+ let optionSchema;
1652
+ if (option) {
1653
+ const { required: schemaRequired, type: schemaType } = schema;
1654
+ const parentProps = {};
1655
+ if (schemaRequired) {
1656
+ parentProps.required = schemaRequired;
1577
1657
  }
1578
- if (newState !== this.state) {
1579
- this.setState(newState);
1658
+ if (schemaType !== void 0 && !("type" in option)) {
1659
+ parentProps.type = schemaType;
1580
1660
  }
1661
+ optionSchema = Object.keys(parentProps).length > 0 ? utils.mergeSchemas(parentProps, option) : option;
1581
1662
  }
1582
- /** Determines the best matching option for the given `formData` and `options`.
1583
- *
1584
- * @param formData - The new formData
1585
- * @param options - The list of options to choose from
1586
- * @return - The index of the `option` that best matches the `formData`
1587
- */
1588
- getMatchingOption(selectedOption, formData, options) {
1589
- const {
1590
- schema,
1591
- registry: { schemaUtils }
1592
- } = this.props;
1593
- const discriminator = utils.getDiscriminatorFieldFromSchema(schema);
1594
- const option = schemaUtils.getClosestMatchingOption(formData, options, selectedOption, discriminator);
1595
- return option;
1596
- }
1597
- /** Callback handler to remember what the currently selected option is. In addition to that the `formData` is updated
1598
- * to remove properties that are not part of the newly selected option schema, and then the updated data is passed to
1599
- * the `onChange` handler.
1600
- *
1601
- * @param option - The new option value being selected
1602
- */
1603
- onOptionChange = (option) => {
1604
- const { selectedOption, retrievedOptions } = this.state;
1605
- const { disabled = false, formData, onChange, readonly = false, registry, fieldPathId } = this.props;
1606
- if (disabled || readonly) {
1607
- return;
1608
- }
1609
- const { schemaUtils } = registry;
1610
- const intOption = option !== void 0 ? parseInt(option, 10) : -1;
1611
- if (intOption === selectedOption) {
1612
- return;
1663
+ let optionsUiSchema = [];
1664
+ if (utils.ONE_OF_KEY in schema && uiSchema && utils.ONE_OF_KEY in uiSchema) {
1665
+ if (Array.isArray(uiSchema[utils.ONE_OF_KEY])) {
1666
+ optionsUiSchema = uiSchema[utils.ONE_OF_KEY];
1667
+ } else {
1668
+ console.warn(`uiSchema.oneOf is not an array for "${title || name}"`);
1613
1669
  }
1614
- const newOption = intOption >= 0 ? retrievedOptions[intOption] : void 0;
1615
- const oldOption = selectedOption >= 0 ? retrievedOptions[selectedOption] : void 0;
1616
- let newFormData = schemaUtils.sanitizeDataForNewSchema(newOption, oldOption, formData);
1617
- if (newOption) {
1618
- newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, "excludeObjectChildren");
1670
+ } else if (utils.ANY_OF_KEY in schema && uiSchema && utils.ANY_OF_KEY in uiSchema) {
1671
+ if (Array.isArray(uiSchema[utils.ANY_OF_KEY])) {
1672
+ optionsUiSchema = uiSchema[utils.ANY_OF_KEY];
1673
+ } else {
1674
+ console.warn(`uiSchema.anyOf is not an array for "${title || name}"`);
1619
1675
  }
1620
- this.setState({ selectedOption: intOption }, () => {
1621
- this.skipNextOptionRecalculation = true;
1622
- onChange(newFormData, fieldPathId.path, void 0, this.getFieldId());
1623
- });
1624
- };
1625
- getFieldId() {
1626
- const { fieldPathId, schema } = this.props;
1627
- return `${fieldPathId.$id}${schema.oneOf ? "__oneof_select" : "__anyof_select"}`;
1628
1676
  }
1629
- /** Renders the `AnyOfField` selector along with a `SchemaField` for the value of the `formData`
1630
- */
1631
- render() {
1632
- const {
1633
- name,
1634
- disabled = false,
1635
- errorSchema = {},
1636
- formData,
1677
+ let optionUiSchema = uiSchema;
1678
+ if (selectedOption >= 0 && optionsUiSchema.length > selectedOption) {
1679
+ optionUiSchema = optionsUiSchema[selectedOption];
1680
+ }
1681
+ const translateEnum = title ? utils.TranslatableString.TitleOptionPrefix : utils.TranslatableString.OptionPrefix;
1682
+ const translateParams = title ? [title] : [];
1683
+ const enumOptions = retrievedOptions.map((opt, index) => {
1684
+ const { title: uiTitle = opt.title } = utils.getUiOptions(optionsUiSchema[index]);
1685
+ return {
1686
+ label: uiTitle || translateString(translateEnum, translateParams.concat(String(index + 1))),
1687
+ value: index
1688
+ };
1689
+ });
1690
+ const selector = !isOptionalRender || hasFormData ? /* @__PURE__ */ jsxRuntime.jsx(
1691
+ Widget,
1692
+ {
1693
+ id: fieldId,
1694
+ name: `${name}${schema.oneOf ? "__oneof_select" : "__anyof_select"}`,
1695
+ schema: { type: "number", default: 0 },
1696
+ onChange: onOptionChange,
1637
1697
  onBlur,
1638
1698
  onFocus,
1639
- readonly,
1640
- required = false,
1641
- registry,
1642
- schema,
1643
- uiSchema
1644
- } = this.props;
1645
- const { widgets: widgets2, fields: fields2, translateString, globalUiOptions, schemaUtils } = registry;
1646
- const { SchemaField: SchemaFieldComponent } = fields2;
1647
- const MultiSchemaFieldTemplate2 = utils.getTemplate(
1648
- "MultiSchemaFieldTemplate",
1699
+ disabled: disabled || isEmpty(enumOptions),
1700
+ multiple: false,
1701
+ rawErrors,
1702
+ errorSchema: fieldErrorSchema,
1703
+ value: selectedOption >= 0 ? selectedOption : void 0,
1704
+ options: { enumOptions, ...uiOptions },
1649
1705
  registry,
1650
- globalUiOptions
1651
- );
1652
- const isOptionalRender = utils.shouldRenderOptionalField(registry, schema, required, uiSchema);
1653
- const hasFormData = utils.isFormDataAvailable(formData);
1654
- const { selectedOption, retrievedOptions } = this.state;
1655
- const {
1656
- widget = "select",
1657
1706
  placeholder,
1658
- autofocus,
1659
1707
  autocomplete,
1660
- title = schema.title,
1661
- ...uiOptions
1662
- } = utils.getUiOptions(uiSchema, globalUiOptions);
1663
- const Widget = utils.getWidget({ type: "number" }, widget, widgets2);
1664
- const rawErrors = get(errorSchema, utils.ERRORS_KEY, []);
1665
- const fieldErrorSchema = omit3(errorSchema, [utils.ERRORS_KEY]);
1666
- const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
1667
- const option = selectedOption >= 0 ? retrievedOptions[selectedOption] || null : null;
1668
- let optionSchema;
1669
- if (option) {
1670
- const { required: schemaRequired } = schema;
1671
- optionSchema = schemaRequired ? utils.mergeSchemas({ required: schemaRequired }, option) : option;
1672
- }
1673
- let optionsUiSchema = [];
1674
- if (utils.ONE_OF_KEY in schema && uiSchema && utils.ONE_OF_KEY in uiSchema) {
1675
- if (Array.isArray(uiSchema[utils.ONE_OF_KEY])) {
1676
- optionsUiSchema = uiSchema[utils.ONE_OF_KEY];
1677
- } else {
1678
- console.warn(`uiSchema.oneOf is not an array for "${title || name}"`);
1679
- }
1680
- } else if (utils.ANY_OF_KEY in schema && uiSchema && utils.ANY_OF_KEY in uiSchema) {
1681
- if (Array.isArray(uiSchema[utils.ANY_OF_KEY])) {
1682
- optionsUiSchema = uiSchema[utils.ANY_OF_KEY];
1683
- } else {
1684
- console.warn(`uiSchema.anyOf is not an array for "${title || name}"`);
1685
- }
1708
+ autofocus,
1709
+ label: title ?? name,
1710
+ hideLabel: !displayLabel,
1711
+ readonly
1686
1712
  }
1687
- let optionUiSchema = uiSchema;
1688
- if (selectedOption >= 0 && optionsUiSchema.length > selectedOption) {
1689
- optionUiSchema = optionsUiSchema[selectedOption];
1713
+ ) : void 0;
1714
+ const optionsSchemaField = optionSchema && optionSchema.type !== "null" && /* @__PURE__ */ jsxRuntime.jsx(SchemaFieldComponent, { ...props, schema: optionSchema, uiSchema: optionUiSchema }) || null;
1715
+ return /* @__PURE__ */ jsxRuntime.jsx(
1716
+ MultiSchemaFieldTemplate2,
1717
+ {
1718
+ schema,
1719
+ registry,
1720
+ uiSchema,
1721
+ selector,
1722
+ optionSchemaField: optionsSchemaField
1690
1723
  }
1691
- const translateEnum = title ? utils.TranslatableString.TitleOptionPrefix : utils.TranslatableString.OptionPrefix;
1692
- const translateParams = title ? [title] : [];
1693
- const enumOptions = retrievedOptions.map((opt, index) => {
1694
- const { title: uiTitle = opt.title } = utils.getUiOptions(optionsUiSchema[index]);
1695
- return {
1696
- label: uiTitle || translateString(translateEnum, translateParams.concat(String(index + 1))),
1697
- value: index
1698
- };
1699
- });
1700
- const selector = !isOptionalRender || hasFormData ? /* @__PURE__ */ jsxRuntime.jsx(
1701
- Widget,
1702
- {
1703
- id: this.getFieldId(),
1704
- name: `${name}${schema.oneOf ? "__oneof_select" : "__anyof_select"}`,
1705
- schema: { type: "number", default: 0 },
1706
- onChange: this.onOptionChange,
1707
- onBlur,
1708
- onFocus,
1709
- disabled: disabled || isEmpty(enumOptions),
1710
- multiple: false,
1711
- rawErrors,
1712
- errorSchema: fieldErrorSchema,
1713
- value: selectedOption >= 0 ? selectedOption : void 0,
1714
- options: { enumOptions, ...uiOptions },
1715
- registry,
1716
- placeholder,
1717
- autocomplete,
1718
- autofocus,
1719
- label: title ?? name,
1720
- hideLabel: !displayLabel,
1721
- readonly
1722
- }
1723
- ) : void 0;
1724
- const optionsSchemaField = optionSchema && optionSchema.type !== "null" && /* @__PURE__ */ jsxRuntime.jsx(SchemaFieldComponent, { ...this.props, schema: optionSchema, uiSchema: optionUiSchema }) || null;
1725
- return /* @__PURE__ */ jsxRuntime.jsx(
1726
- MultiSchemaFieldTemplate2,
1727
- {
1728
- schema,
1729
- registry,
1730
- uiSchema,
1731
- selector,
1732
- optionSchemaField: optionsSchemaField
1733
- }
1734
- );
1735
- }
1736
- };
1724
+ );
1725
+ }
1737
1726
  var MultiSchemaField_default = AnyOfField;
1738
1727
  function NullField(props) {
1739
1728
  const { formData, onChange, fieldPathId } = props;
@@ -1756,7 +1745,7 @@
1756
1745
  (newValue, path, errorSchema, id) => {
1757
1746
  setLastValue(newValue);
1758
1747
  const normalizedValue = `${newValue}`.startsWith(".") ? `0${newValue}` : newValue;
1759
- const processed = typeof normalizedValue === "string" && normalizedValue.match(trailingCharMatcherWithPrefix) ? utils.asNumber(normalizedValue.replace(trailingCharMatcher, "")) : utils.asNumber(normalizedValue);
1748
+ const processed = typeof normalizedValue === "string" && trailingCharMatcherWithPrefix.exec(normalizedValue) ? utils.asNumber(normalizedValue.replace(trailingCharMatcher, "")) : utils.asNumber(normalizedValue);
1760
1749
  onChange(processed, path, errorSchema, id);
1761
1750
  },
1762
1751
  [onChange]
@@ -1945,7 +1934,7 @@
1945
1934
  apSchema = schemaUtils.retrieveSchema({ [utils.REF_KEY]: apSchema[utils.REF_KEY] }, formData);
1946
1935
  type = apSchema.type;
1947
1936
  constValue = apSchema.const;
1948
- defaultValue = apSchema.default;
1937
+ defaultValue = schemaUtils.getDefaultFormState(apSchema, defaultValue);
1949
1938
  }
1950
1939
  if (!type && (utils.ANY_OF_KEY in apSchema || utils.ONE_OF_KEY in apSchema)) {
1951
1940
  type = "object";
@@ -2014,7 +2003,9 @@
2014
2003
  title: uiOptions.label === false ? "" : templateTitle,
2015
2004
  description: uiOptions.label === false ? void 0 : description,
2016
2005
  properties: orderedProperties.map((propertyName) => {
2017
- const addedByAdditionalProperties = has(schema, [utils.PROPERTIES_KEY, propertyName, utils.ADDITIONAL_PROPERTY_FLAG]);
2006
+ const addedByAdditionalProperties = Boolean(
2007
+ schema.properties?.[propertyName]?.[utils.ADDITIONAL_PROPERTY_FLAG]
2008
+ );
2018
2009
  const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[propertyName];
2019
2010
  const hidden = utils.getUiOptions(fieldUiSchema).widget === "hidden";
2020
2011
  const content = /* @__PURE__ */ jsxRuntime.jsx(
@@ -2131,7 +2122,7 @@
2131
2122
  };
2132
2123
  function getFieldComponent(schema, uiOptions, registry) {
2133
2124
  const { field } = uiOptions;
2134
- const { fields: fields2 } = registry;
2125
+ const { fields: fields2, schemaUtils } = registry;
2135
2126
  if (typeof field === "function") {
2136
2127
  return field;
2137
2128
  }
@@ -2145,7 +2136,7 @@
2145
2136
  if (schemaId && schemaId in fields2) {
2146
2137
  componentName = schemaId;
2147
2138
  }
2148
- if (!componentName && (schema.anyOf || schema.oneOf)) {
2139
+ if ((schema.anyOf || schema.oneOf) && !schemaUtils.isSelect(schema) && componentName !== "ObjectField") {
2149
2140
  return () => null;
2150
2141
  }
2151
2142
  return componentName in fields2 ? fields2[componentName] : fields2.FallbackField;
@@ -2167,7 +2158,18 @@
2167
2158
  wasPropertyKeyModified = false
2168
2159
  } = props;
2169
2160
  const { schemaUtils, globalFormOptions, globalUiOptions, fields: fields2 } = registry;
2170
- const { AnyOfField: _AnyOfField, OneOfField: _OneOfField } = fields2;
2161
+ const { AnyOfField: _AnyOfField, OneOfField: _OneOfField, CyclicSchemaField: CyclicSchemaField2 } = fields2;
2162
+ const fieldId = fieldPathId[utils.ID_KEY];
2163
+ const handleFieldComponentChange = react.useCallback(
2164
+ (newFormData, path, newErrorSchema, id2) => {
2165
+ const theId = id2 || fieldId;
2166
+ return onChange(newFormData, path, newErrorSchema, theId);
2167
+ },
2168
+ [fieldId, onChange]
2169
+ );
2170
+ if (_schema[utils.RJSF_REF_CYCLE_KEY]) {
2171
+ return /* @__PURE__ */ jsxRuntime.jsx(CyclicSchemaField2, { ...props });
2172
+ }
2171
2173
  const uiSchema = utils.resolveUiSchema(_schema, _uiSchema, registry);
2172
2174
  const uiOptions = utils.getUiOptions(uiSchema, globalUiOptions);
2173
2175
  const FieldTemplate2 = utils.getTemplate("FieldTemplate", registry, uiOptions);
@@ -2179,14 +2181,6 @@
2179
2181
  const FieldHelpTemplate2 = utils.getTemplate("FieldHelpTemplate", registry, uiOptions);
2180
2182
  const FieldErrorTemplate2 = utils.getTemplate("FieldErrorTemplate", registry, uiOptions);
2181
2183
  const schema = schemaUtils.retrieveSchema(_schema, formData);
2182
- const fieldId = fieldPathId[utils.ID_KEY];
2183
- const handleFieldComponentChange = react.useCallback(
2184
- (newFormData, path, newErrorSchema, id2) => {
2185
- const theId = id2 || fieldId;
2186
- return onChange(newFormData, path, newErrorSchema, theId);
2187
- },
2188
- [fieldId, onChange]
2189
- );
2190
2184
  const FieldComponent = getFieldComponent(schema, uiOptions, registry);
2191
2185
  const isDeprecated = Boolean(schema.deprecated);
2192
2186
  const deprecatedHandling = isDeprecated ? uiOptions.deprecatedHandling ?? "label" : void 0;
@@ -2348,18 +2342,16 @@
2348
2342
  )
2349
2343
  ] }) });
2350
2344
  }
2351
- var SchemaField = class extends react.Component {
2352
- shouldComponentUpdate(nextProps) {
2353
- const {
2354
- registry: { globalFormOptions }
2355
- } = this.props;
2356
- const { experimental_componentUpdateStrategy = "customDeep" } = globalFormOptions;
2357
- return utils.shouldRender(this, nextProps, this.state, experimental_componentUpdateStrategy);
2345
+ var SchemaField = react.memo(SchemaFieldRender, (prevProps, nextProps) => {
2346
+ const { experimental_componentUpdateStrategy = "customDeep" } = nextProps.registry.globalFormOptions;
2347
+ if (experimental_componentUpdateStrategy === "always") {
2348
+ return false;
2358
2349
  }
2359
- render() {
2360
- return /* @__PURE__ */ jsxRuntime.jsx(SchemaFieldRender, { ...this.props });
2350
+ if (experimental_componentUpdateStrategy === "shallow") {
2351
+ return utils.shallowEquals(prevProps, nextProps);
2361
2352
  }
2362
- };
2353
+ return utils.deepEquals(prevProps, nextProps);
2354
+ });
2363
2355
  var SchemaField_default = SchemaField;
2364
2356
  function StringField(props) {
2365
2357
  const {
@@ -2430,6 +2422,7 @@
2430
2422
  ArrayField,
2431
2423
  // ArrayField falls back to SchemaField if ArraySchemaField is not defined, which it isn't by default
2432
2424
  BooleanField: BooleanField_default,
2425
+ CyclicSchemaField,
2433
2426
  FallbackField,
2434
2427
  LayoutGridField,
2435
2428
  LayoutHeaderField,
@@ -2705,12 +2698,9 @@
2705
2698
  ({ target: { value: newValue } }) => onChange(newValue === "" ? options.emptyValue : newValue),
2706
2699
  [onChange, options]
2707
2700
  );
2708
- const handleBlur = react.useCallback(
2709
- ({ target }) => onBlur(id, target && target.value),
2710
- [onBlur, id]
2711
- );
2701
+ const handleBlur = react.useCallback(({ target }) => onBlur(id, target?.value), [onBlur, id]);
2712
2702
  const handleFocus = react.useCallback(
2713
- ({ target }) => onFocus(id, target && target.value),
2703
+ ({ target }) => onFocus(id, target?.value),
2714
2704
  [onFocus, id]
2715
2705
  );
2716
2706
  const handleClear = react.useCallback(
@@ -2852,6 +2842,27 @@
2852
2842
  };
2853
2843
  }
2854
2844
  var ButtonTemplates_default = buttonTemplates;
2845
+ function CyclicSchemaExpandTemplate(props) {
2846
+ const { name, fieldPathId, registry, onExpand } = props;
2847
+ const { translateString } = registry;
2848
+ const buttonId5 = `${fieldPathId[utils.ID_KEY]}-button`;
2849
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem" }, children: [
2850
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-danger", children: translateString(utils.TranslatableString.CycleDetected, [name]) }),
2851
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2852
+ /* @__PURE__ */ jsxRuntime.jsx(
2853
+ "button",
2854
+ {
2855
+ id: buttonId5,
2856
+ type: "button",
2857
+ className: "btn btn-sm btn-warning",
2858
+ onClick: () => onExpand(fieldPathId[utils.ID_KEY]),
2859
+ children: translateString(utils.TranslatableString.ExpandButton)
2860
+ }
2861
+ ),
2862
+ " "
2863
+ ] })
2864
+ ] });
2865
+ }
2855
2866
  var TEST_IDS = utils.getTestIds();
2856
2867
  function RichDescription({ description, registry, uiSchema = {} }) {
2857
2868
  const { globalUiOptions } = registry;
@@ -3089,7 +3100,7 @@
3089
3100
  const { translateString } = registry;
3090
3101
  let translateEnum = utils.TranslatableString.UnsupportedField;
3091
3102
  const translateParams = [];
3092
- if (fieldPathId && fieldPathId.$id) {
3103
+ if (fieldPathId?.$id) {
3093
3104
  translateEnum = utils.TranslatableString.UnsupportedFieldWithId;
3094
3105
  translateParams.push(fieldPathId.$id);
3095
3106
  }
@@ -3179,6 +3190,7 @@
3179
3190
  ArrayFieldTitleTemplate,
3180
3191
  ButtonTemplates: ButtonTemplates_default(),
3181
3192
  BaseInputTemplate,
3193
+ CyclicSchemaExpandTemplate,
3182
3194
  DescriptionFieldTemplate: DescriptionField,
3183
3195
  ErrorListTemplate: ErrorList,
3184
3196
  FallbackFieldTemplate,
@@ -3247,11 +3259,11 @@
3247
3259
  const optionValueFormat = utils.getOptionValueFormat(options);
3248
3260
  const checkboxesValues = Array.isArray(value) ? value : [value];
3249
3261
  const handleBlur = react.useCallback(
3250
- ({ target }) => onBlur(id, utils.enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)),
3262
+ ({ target }) => onBlur(id, utils.enumOptionValueDecoder(target?.value, enumOptions, optionValueFormat, emptyValue)),
3251
3263
  [onBlur, id, enumOptions, emptyValue, optionValueFormat]
3252
3264
  );
3253
3265
  const handleFocus = react.useCallback(
3254
- ({ target }) => onFocus(id, utils.enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)),
3266
+ ({ target }) => onFocus(id, utils.enumOptionValueDecoder(target?.value, enumOptions, optionValueFormat, emptyValue)),
3255
3267
  [onFocus, id, enumOptions, emptyValue, optionValueFormat]
3256
3268
  );
3257
3269
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "checkboxes", id, children: Array.isArray(enumOptions) && enumOptions.map((option, index) => {
@@ -3495,11 +3507,11 @@
3495
3507
  const { enumOptions, enumDisabled, inline, emptyValue } = options;
3496
3508
  const optionValueFormat = utils.getOptionValueFormat(options);
3497
3509
  const handleBlur = react.useCallback(
3498
- ({ target }) => onBlur(id, utils.enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)),
3510
+ ({ target }) => onBlur(id, utils.enumOptionValueDecoder(target?.value, enumOptions, optionValueFormat, emptyValue)),
3499
3511
  [onBlur, enumOptions, emptyValue, id, optionValueFormat]
3500
3512
  );
3501
3513
  const handleFocus = react.useCallback(
3502
- ({ target }) => onFocus(id, utils.enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)),
3514
+ ({ target }) => onFocus(id, utils.enumOptionValueDecoder(target?.value, enumOptions, optionValueFormat, emptyValue)),
3503
3515
  [onFocus, enumOptions, emptyValue, id, optionValueFormat]
3504
3516
  );
3505
3517
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "field-radio-group", id, role: "radiogroup", children: Array.isArray(enumOptions) && enumOptions.map((option, i) => {
@@ -3664,7 +3676,9 @@
3664
3676
  onBlur,
3665
3677
  onFocus,
3666
3678
  placeholder,
3667
- htmlName
3679
+ htmlName,
3680
+ registry,
3681
+ uiSchema
3668
3682
  }) {
3669
3683
  const { enumOptions, enumDisabled, emptyValue: optEmptyVal } = options;
3670
3684
  const emptyValue = multiple ? [] : "";
@@ -3692,8 +3706,19 @@
3692
3706
  );
3693
3707
  const selectValue = utils.enumOptionSelectedValue(value, enumOptions, multiple, optionValueFormat, emptyValue);
3694
3708
  const showPlaceholderOption = !multiple && schema.default === void 0;
3695
- return (
3696
- // oxlint-disable-next-line jsx-a11y/no-autofocus
3709
+ utils.logUnsupportedDefaultForEnum(id, schema, enumOptions, multiple);
3710
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3711
+ /* @__PURE__ */ jsxRuntime.jsx(
3712
+ utils.SelectedOptionDescription,
3713
+ {
3714
+ id,
3715
+ multiple,
3716
+ options,
3717
+ registry,
3718
+ uiSchema,
3719
+ value
3720
+ }
3721
+ ),
3697
3722
  /* @__PURE__ */ jsxRuntime.jsxs(
3698
3723
  "select",
3699
3724
  {
@@ -3726,12 +3751,12 @@
3726
3751
  ]
3727
3752
  }
3728
3753
  )
3729
- );
3754
+ ] });
3730
3755
  }
3731
3756
  var SelectWidget_default = SelectWidget;
3732
3757
  function TextareaWidget({
3733
3758
  id,
3734
- options = {},
3759
+ options,
3735
3760
  placeholder,
3736
3761
  value,
3737
3762
  required,
@@ -3748,11 +3773,11 @@
3748
3773
  [onChange, options.emptyValue]
3749
3774
  );
3750
3775
  const handleBlur = react.useCallback(
3751
- ({ target }) => onBlur(id, target && target.value),
3776
+ ({ target }) => onBlur(id, target?.value),
3752
3777
  [onBlur, id]
3753
3778
  );
3754
3779
  const handleFocus = react.useCallback(
3755
- ({ target }) => onFocus(id, target && target.value),
3780
+ ({ target }) => onFocus(id, target?.value),
3756
3781
  [id, onFocus]
3757
3782
  );
3758
3783
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -4154,14 +4179,15 @@
4154
4179
  const schemaUtils = altSchemaUtils || this.state.schemaUtils;
4155
4180
  const { customValidate, transformErrors, uiSchema } = this.props;
4156
4181
  const validationSchema = retrievedSchema ?? schema;
4157
- return schemaUtils.getValidator().validateFormData(formData, validationSchema, customValidate, transformErrors, uiSchema);
4182
+ const validationFormData = formData ? JSON.parse(JSON.stringify(formData)) : void 0;
4183
+ return schemaUtils.getValidator().validateFormData(validationFormData, validationSchema, customValidate, transformErrors, uiSchema);
4158
4184
  }
4159
4185
  /** Renders any errors contained in the `state` in using the `ErrorList`, if not disabled by `showErrorList`. */
4160
4186
  renderErrors(registry) {
4161
4187
  const { errors, errorSchema, schema, uiSchema } = this.state;
4162
4188
  const options = utils.getUiOptions(uiSchema);
4163
4189
  const ErrorListTemplate = utils.getTemplate("ErrorListTemplate", registry, options);
4164
- if (errors && errors.length) {
4190
+ if (errors?.length) {
4165
4191
  return /* @__PURE__ */ jsxRuntime.jsx(
4166
4192
  ErrorListTemplate,
4167
4193
  {
@@ -4308,10 +4334,10 @@
4308
4334
  const wasPreviouslyNull = oldFormData === null || oldFormData === void 0;
4309
4335
  const inputForDefaults = hasOnlyUndefinedValues && wasPreviouslyNull ? void 0 : formData;
4310
4336
  if (utils.isObject(formData) || Array.isArray(formData)) {
4337
+ let plainLeafWasCleared = false;
4311
4338
  if (newValue === ADDITIONAL_PROPERTY_KEY_REMOVE) {
4312
4339
  _unset(formData, path);
4313
4340
  } else if (!isRootPath) {
4314
- let unsetPath = false;
4315
4341
  let valueForPath = newValue;
4316
4342
  if (newValue === void 0) {
4317
4343
  const lastSegment = path[path.length - 1];
@@ -4322,12 +4348,12 @@
4322
4348
  const leaf = field;
4323
4349
  const isOneOfOrAnyOfLeaf = leaf && (utils.ONE_OF_KEY in leaf || utils.ANY_OF_KEY in leaf);
4324
4350
  if (!isOneOfOrAnyOfLeaf && leaf !== void 0) {
4325
- unsetPath = true;
4351
+ plainLeafWasCleared = true;
4326
4352
  }
4327
4353
  }
4328
4354
  }
4329
- if (unsetPath) {
4330
- _unset(formData, path);
4355
+ if (plainLeafWasCleared) {
4356
+ set(formData, path, void 0);
4331
4357
  } else {
4332
4358
  set(formData, path, valueForPath);
4333
4359
  }
@@ -4344,6 +4370,9 @@
4344
4370
  );
4345
4371
  formData = newState.formData;
4346
4372
  retrievedSchema = newState.retrievedSchema;
4373
+ if (plainLeafWasCleared && formData) {
4374
+ set(formData, path, void 0);
4375
+ }
4347
4376
  }
4348
4377
  const mustValidate = !noValidate && (liveValidate === true || liveValidate === "onChange");
4349
4378
  let state = { formData, retrievedSchema };
@@ -4443,7 +4472,7 @@
4443
4472
  initialDefaultsGenerated: false,
4444
4473
  customErrors: void 0
4445
4474
  };
4446
- this.setState(state, () => onChange && onChange(toIChangeEvent({ ...this.state, ...state })));
4475
+ this.setState(state, () => onChange?.(toIChangeEvent({ ...this.state, ...state })));
4447
4476
  };
4448
4477
  /** Callback function to handle when a field on the form is blurred. Calls the `onBlur` callback for the `Form` if it
4449
4478
  * was provided. Also runs any live validation and/or live omit operations if the flags indicate they should happen
@@ -4620,7 +4649,7 @@
4620
4649
  if (!field) {
4621
4650
  field = this.formElement.current.querySelector(`input[id^="${elementId}"], button[id^="${elementId}"]`);
4622
4651
  }
4623
- if (field && field.length) {
4652
+ if (field?.length) {
4624
4653
  field = field[0];
4625
4654
  }
4626
4655
  if (field) {