@rjsf/core 6.0.0-beta.8 → 6.0.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 (160) hide show
  1. package/README.md +2 -0
  2. package/dist/core.umd.js +2042 -1987
  3. package/dist/index.cjs +4909 -0
  4. package/dist/index.cjs.map +7 -0
  5. package/dist/index.esm.js +2509 -2389
  6. package/dist/index.esm.js.map +4 -4
  7. package/lib/components/Form.d.ts +137 -34
  8. package/lib/components/Form.d.ts.map +1 -1
  9. package/lib/components/Form.js +318 -173
  10. package/lib/components/fields/ArrayField.d.ts +2 -187
  11. package/lib/components/fields/ArrayField.d.ts.map +1 -1
  12. package/lib/components/fields/ArrayField.js +526 -492
  13. package/lib/components/fields/BooleanField.d.ts.map +1 -1
  14. package/lib/components/fields/BooleanField.js +8 -3
  15. package/lib/components/fields/FallbackField.d.ts +7 -0
  16. package/lib/components/fields/FallbackField.d.ts.map +1 -0
  17. package/lib/components/fields/FallbackField.js +72 -0
  18. package/lib/components/fields/LayoutGridField.d.ts +109 -186
  19. package/lib/components/fields/LayoutGridField.d.ts.map +1 -1
  20. package/lib/components/fields/LayoutGridField.js +426 -426
  21. package/lib/components/fields/LayoutHeaderField.d.ts +1 -1
  22. package/lib/components/fields/LayoutHeaderField.js +3 -3
  23. package/lib/components/fields/LayoutMultiSchemaField.d.ts.map +1 -1
  24. package/lib/components/fields/LayoutMultiSchemaField.js +6 -6
  25. package/lib/components/fields/MultiSchemaField.d.ts.map +1 -1
  26. package/lib/components/fields/MultiSchemaField.js +16 -10
  27. package/lib/components/fields/NullField.js +3 -3
  28. package/lib/components/fields/NumberField.d.ts.map +1 -1
  29. package/lib/components/fields/NumberField.js +3 -3
  30. package/lib/components/fields/ObjectField.d.ts +2 -68
  31. package/lib/components/fields/ObjectField.d.ts.map +1 -1
  32. package/lib/components/fields/ObjectField.js +163 -163
  33. package/lib/components/fields/OptionalDataControlsField.d.ts +8 -0
  34. package/lib/components/fields/OptionalDataControlsField.d.ts.map +1 -0
  35. package/lib/components/fields/OptionalDataControlsField.js +43 -0
  36. package/lib/components/fields/SchemaField.d.ts.map +1 -1
  37. package/lib/components/fields/SchemaField.js +52 -30
  38. package/lib/components/fields/StringField.d.ts.map +1 -1
  39. package/lib/components/fields/StringField.js +8 -3
  40. package/lib/components/fields/index.d.ts.map +1 -1
  41. package/lib/components/fields/index.js +4 -0
  42. package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts +1 -1
  43. package/lib/components/templates/ArrayFieldDescriptionTemplate.js +3 -3
  44. package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts +3 -3
  45. package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts.map +1 -1
  46. package/lib/components/templates/ArrayFieldItemButtonsTemplate.js +3 -8
  47. package/lib/components/templates/ArrayFieldItemTemplate.d.ts +3 -3
  48. package/lib/components/templates/ArrayFieldItemTemplate.d.ts.map +1 -1
  49. package/lib/components/templates/ArrayFieldItemTemplate.js +1 -1
  50. package/lib/components/templates/ArrayFieldTemplate.d.ts +1 -1
  51. package/lib/components/templates/ArrayFieldTemplate.d.ts.map +1 -1
  52. package/lib/components/templates/ArrayFieldTemplate.js +4 -5
  53. package/lib/components/templates/ArrayFieldTitleTemplate.d.ts +1 -1
  54. package/lib/components/templates/ArrayFieldTitleTemplate.d.ts.map +1 -1
  55. package/lib/components/templates/ArrayFieldTitleTemplate.js +3 -3
  56. package/lib/components/templates/BaseInputTemplate.js +2 -2
  57. package/lib/components/templates/ButtonTemplates/AddButton.d.ts +1 -1
  58. package/lib/components/templates/ButtonTemplates/AddButton.d.ts.map +1 -1
  59. package/lib/components/templates/ButtonTemplates/AddButton.js +2 -2
  60. package/lib/components/templates/FallbackFieldTemplate.d.ts +7 -0
  61. package/lib/components/templates/FallbackFieldTemplate.d.ts.map +1 -0
  62. package/lib/components/templates/FallbackFieldTemplate.js +12 -0
  63. package/lib/components/templates/FieldErrorTemplate.js +2 -2
  64. package/lib/components/templates/FieldHelpTemplate.js +2 -2
  65. package/lib/components/templates/MultiSchemaFieldTemplate.d.ts +8 -0
  66. package/lib/components/templates/MultiSchemaFieldTemplate.d.ts.map +1 -0
  67. package/lib/components/templates/MultiSchemaFieldTemplate.js +10 -0
  68. package/lib/components/templates/ObjectFieldTemplate.d.ts.map +1 -1
  69. package/lib/components/templates/ObjectFieldTemplate.js +3 -2
  70. package/lib/components/templates/OptionalDataControlsTemplate.d.ts +11 -0
  71. package/lib/components/templates/OptionalDataControlsTemplate.d.ts.map +1 -0
  72. package/lib/components/templates/OptionalDataControlsTemplate.js +20 -0
  73. package/lib/components/templates/TitleField.d.ts.map +1 -1
  74. package/lib/components/templates/TitleField.js +2 -2
  75. package/lib/components/templates/UnsupportedField.js +3 -3
  76. package/lib/components/templates/WrapIfAdditionalTemplate.js +2 -2
  77. package/lib/components/templates/index.d.ts.map +1 -1
  78. package/lib/components/templates/index.js +6 -0
  79. package/lib/components/widgets/AltDateWidget.d.ts +1 -1
  80. package/lib/components/widgets/AltDateWidget.d.ts.map +1 -1
  81. package/lib/components/widgets/AltDateWidget.js +5 -46
  82. package/lib/components/widgets/CheckboxWidget.d.ts +1 -1
  83. package/lib/components/widgets/CheckboxWidget.d.ts.map +1 -1
  84. package/lib/components/widgets/CheckboxWidget.js +2 -2
  85. package/lib/components/widgets/CheckboxesWidget.d.ts +1 -1
  86. package/lib/components/widgets/CheckboxesWidget.d.ts.map +1 -1
  87. package/lib/components/widgets/CheckboxesWidget.js +4 -4
  88. package/lib/components/widgets/FileWidget.d.ts.map +1 -1
  89. package/lib/components/widgets/FileWidget.js +7 -87
  90. package/lib/components/widgets/HiddenWidget.d.ts +1 -1
  91. package/lib/components/widgets/HiddenWidget.d.ts.map +1 -1
  92. package/lib/components/widgets/HiddenWidget.js +2 -2
  93. package/lib/components/widgets/RadioWidget.d.ts +1 -1
  94. package/lib/components/widgets/RadioWidget.d.ts.map +1 -1
  95. package/lib/components/widgets/RadioWidget.js +2 -2
  96. package/lib/components/widgets/RatingWidget.d.ts +1 -1
  97. package/lib/components/widgets/RatingWidget.d.ts.map +1 -1
  98. package/lib/components/widgets/RatingWidget.js +2 -2
  99. package/lib/components/widgets/SelectWidget.d.ts +1 -1
  100. package/lib/components/widgets/SelectWidget.d.ts.map +1 -1
  101. package/lib/components/widgets/SelectWidget.js +2 -2
  102. package/lib/components/widgets/TextareaWidget.d.ts +1 -1
  103. package/lib/components/widgets/TextareaWidget.d.ts.map +1 -1
  104. package/lib/components/widgets/TextareaWidget.js +2 -2
  105. package/lib/getDefaultRegistry.d.ts.map +1 -1
  106. package/lib/getDefaultRegistry.js +6 -1
  107. package/lib/getTestRegistry.d.ts +5 -0
  108. package/lib/getTestRegistry.d.ts.map +1 -0
  109. package/lib/getTestRegistry.js +23 -0
  110. package/lib/index.d.ts +2 -1
  111. package/lib/index.d.ts.map +1 -1
  112. package/lib/index.js +2 -1
  113. package/lib/tsconfig.tsbuildinfo +1 -1
  114. package/package.json +35 -20
  115. package/src/components/Form.tsx +468 -206
  116. package/src/components/fields/ArrayField.tsx +871 -723
  117. package/src/components/fields/BooleanField.tsx +14 -5
  118. package/src/components/fields/FallbackField.tsx +157 -0
  119. package/src/components/fields/LayoutGridField.tsx +626 -603
  120. package/src/components/fields/LayoutHeaderField.tsx +3 -3
  121. package/src/components/fields/LayoutMultiSchemaField.tsx +9 -10
  122. package/src/components/fields/MultiSchemaField.tsx +57 -36
  123. package/src/components/fields/NullField.tsx +3 -3
  124. package/src/components/fields/NumberField.tsx +11 -3
  125. package/src/components/fields/ObjectField.tsx +308 -239
  126. package/src/components/fields/OptionalDataControlsField.tsx +84 -0
  127. package/src/components/fields/SchemaField.tsx +75 -94
  128. package/src/components/fields/StringField.tsx +14 -5
  129. package/src/components/fields/index.ts +4 -0
  130. package/src/components/templates/ArrayFieldDescriptionTemplate.tsx +3 -3
  131. package/src/components/templates/ArrayFieldItemButtonsTemplate.tsx +16 -21
  132. package/src/components/templates/ArrayFieldItemTemplate.tsx +3 -3
  133. package/src/components/templates/ArrayFieldTemplate.tsx +11 -18
  134. package/src/components/templates/ArrayFieldTitleTemplate.tsx +4 -3
  135. package/src/components/templates/BaseInputTemplate.tsx +5 -5
  136. package/src/components/templates/ButtonTemplates/AddButton.tsx +2 -0
  137. package/src/components/templates/FallbackFieldTemplate.tsx +28 -0
  138. package/src/components/templates/FieldErrorTemplate.tsx +2 -2
  139. package/src/components/templates/FieldHelpTemplate.tsx +2 -2
  140. package/src/components/templates/MultiSchemaFieldTemplate.tsx +20 -0
  141. package/src/components/templates/ObjectFieldTemplate.tsx +12 -7
  142. package/src/components/templates/OptionalDataControlsTemplate.tsx +43 -0
  143. package/src/components/templates/TitleField.tsx +6 -1
  144. package/src/components/templates/UnsupportedField.tsx +3 -3
  145. package/src/components/templates/WrapIfAdditionalTemplate.tsx +5 -5
  146. package/src/components/templates/index.ts +6 -0
  147. package/src/components/widgets/AltDateWidget.tsx +8 -126
  148. package/src/components/widgets/CheckboxWidget.tsx +4 -3
  149. package/src/components/widgets/CheckboxesWidget.tsx +5 -4
  150. package/src/components/widgets/FileWidget.tsx +11 -102
  151. package/src/components/widgets/HiddenWidget.tsx +2 -1
  152. package/src/components/widgets/RadioWidget.tsx +3 -2
  153. package/src/components/widgets/RatingWidget.tsx +2 -1
  154. package/src/components/widgets/SelectWidget.tsx +3 -2
  155. package/src/components/widgets/TextareaWidget.tsx +3 -2
  156. package/src/getDefaultRegistry.ts +14 -1
  157. package/src/getTestRegistry.tsx +38 -0
  158. package/src/index.ts +2 -1
  159. package/dist/index.js +0 -4834
  160. package/dist/index.js.map +0 -7
@@ -1,32 +1,52 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Component } from 'react';
3
- import { getTemplate, getUiOptions, orderProperties, TranslatableString, ADDITIONAL_PROPERTY_FLAG, PROPERTIES_KEY, REF_KEY, ANY_OF_KEY, ONE_OF_KEY, } from '@rjsf/utils';
2
+ import { useCallback, useState } from 'react';
3
+ import { ADDITIONAL_PROPERTY_FLAG, ANY_OF_KEY, getTemplate, getUiOptions, hashObject, isFormDataAvailable, orderProperties, shouldRenderOptionalField, toFieldPathId, useDeepCompareMemo, ONE_OF_KEY, PROPERTIES_KEY, REF_KEY, TranslatableString, } from '@rjsf/utils';
4
4
  import Markdown from 'markdown-to-jsx';
5
5
  import get from 'lodash-es/get.js';
6
6
  import has from 'lodash-es/has.js';
7
7
  import isObject from 'lodash-es/isObject.js';
8
8
  import set from 'lodash-es/set.js';
9
9
  import unset from 'lodash-es/unset.js';
10
- /** The `ObjectField` component is used to render a field in the schema that is of type `object`. It tracks whether an
11
- * additional property key was modified and what it was modified to
10
+ /** Returns a flag indicating whether the `name` field is required in the object schema
12
11
  *
13
- * @param props - The `FieldProps` for this template
12
+ * @param schema - The schema to check
13
+ * @param name - The name of the field to check for required-ness
14
+ * @returns - True if the field `name` is required, false otherwise
14
15
  */
15
- class ObjectField extends Component {
16
- /** Set up the initial state */
17
- state = {
18
- wasPropertyKeyModified: false,
19
- additionalProperties: {},
20
- };
21
- /** Returns a flag indicating whether the `name` field is required in the object schema
22
- *
23
- * @param name - The name of the field to check for required-ness
24
- * @returns - True if the field `name` is required, false otherwise
25
- */
26
- isRequired(name) {
27
- const { schema } = this.props;
28
- return Array.isArray(schema.required) && schema.required.indexOf(name) !== -1;
16
+ function isRequired(schema, name) {
17
+ return Array.isArray(schema.required) && schema.required.indexOf(name) !== -1;
18
+ }
19
+ /** Returns a default value to be used for a new additional schema property of the given `type`
20
+ *
21
+ * @param translateString - The string translation function from the registry
22
+ * @param type - The type of the new additional schema property
23
+ */
24
+ function getDefaultValue(translateString, type) {
25
+ switch (type) {
26
+ case 'array':
27
+ return [];
28
+ case 'boolean':
29
+ return false;
30
+ case 'null':
31
+ return null;
32
+ case 'number':
33
+ return 0;
34
+ case 'object':
35
+ return {};
36
+ case 'string':
37
+ default:
38
+ // We don't have a datatype for some reason (perhaps additionalProperties was true)
39
+ return translateString(TranslatableString.NewStringDefault);
29
40
  }
41
+ }
42
+ /** The `ObjectFieldProperty` component is used to render the `SchemaField` for a child property of an object
43
+ */
44
+ function ObjectFieldProperty(props) {
45
+ const { fieldPathId, schema, registry, uiSchema, errorSchema, formData, onChange, onBlur, onFocus, disabled, readonly, required, hideError, propertyName, handleKeyRename, handleRemoveProperty, addedByAdditionalProperties, } = props;
46
+ const [wasPropertyKeyModified, setWasPropertyKeyModified] = useState(false);
47
+ const { globalFormOptions, fields } = registry;
48
+ const { SchemaField } = fields;
49
+ const innerFieldIdPathId = useDeepCompareMemo(toFieldPathId(propertyName, globalFormOptions, fieldPathId.path));
30
50
  /** Returns the `onPropertyChange` handler for the `name` field. Handles the special case where a user is attempting
31
51
  * to clear the data for a field added as an additional property. Calls the `onChange()` handler with the updated
32
52
  * formData.
@@ -35,42 +55,59 @@ class ObjectField extends Component {
35
55
  * @param addedByAdditionalProperties - Flag indicating whether this property is an additional property
36
56
  * @returns - The onPropertyChange callback for the `name` property
37
57
  */
38
- onPropertyChange = (name, addedByAdditionalProperties = false) => {
39
- return (value, newErrorSchema, id) => {
40
- const { formData, onChange, errorSchema } = this.props;
41
- if (value === undefined && addedByAdditionalProperties) {
42
- // Don't set value = undefined for fields added by
43
- // additionalProperties. Doing so removes them from the
44
- // formData, which causes them to completely disappear
45
- // (including the input field for the property name). Unlike
46
- // fields which are "mandated" by the schema, these fields can
47
- // be set to undefined by clicking a "delete field" button, so
48
- // set empty values to the empty string.
49
- value = '';
50
- }
51
- const newFormData = { ...formData, [name]: value };
52
- onChange(newFormData, errorSchema &&
53
- errorSchema && {
54
- ...errorSchema,
55
- [name]: newErrorSchema,
56
- }, id);
57
- };
58
- };
59
- /** Returns a callback to handle the onDropPropertyClick event for the given `key` which removes the old `key` data
60
- * and calls the `onChange` callback with it
61
- *
62
- * @param key - The key for which the drop callback is desired
63
- * @returns - The drop property click callback
58
+ const onPropertyChange = useCallback((value, path, newErrorSchema, id) => {
59
+ if (value === undefined && addedByAdditionalProperties) {
60
+ // Don't set value = undefined for fields added by additionalProperties. Doing so removes them from the
61
+ // formData, which causes them to completely disappear (including the input field for the property name). Unlike
62
+ // fields which are "mandated" by the schema, these fields can be set to undefined by clicking a "delete field"
63
+ // button, so set empty values to the empty string.
64
+ value = '';
65
+ }
66
+ onChange(value, path, newErrorSchema, id);
67
+ }, [onChange, addedByAdditionalProperties]);
68
+ /** The key change event handler; Called when the key associated with a field is changed for an additionalProperty.
69
+ * simply returns a function that call the `handleKeyChange()` event with the value
64
70
  */
65
- onDropPropertyClick = (key) => {
66
- return (event) => {
67
- event.preventDefault();
68
- const { onChange, formData } = this.props;
69
- const copiedFormData = { ...formData };
70
- unset(copiedFormData, key);
71
- onChange(copiedFormData);
72
- };
73
- };
71
+ const onKeyRename = useCallback((value) => {
72
+ if (propertyName !== value) {
73
+ setWasPropertyKeyModified(true);
74
+ }
75
+ handleKeyRename(propertyName, value);
76
+ }, [propertyName, handleKeyRename]);
77
+ /** Returns a callback the handle the blur event, getting the value from the target and passing that along to the
78
+ * `handleKeyChange` function
79
+ */
80
+ const onKeyRenameBlur = useCallback((event) => {
81
+ const { target: { value }, } = event;
82
+ onKeyRename(value);
83
+ }, [onKeyRename]);
84
+ /** The property drop/removal event handler; Called when a field is removed in an additionalProperty context
85
+ */
86
+ const onRemoveProperty = useCallback(() => {
87
+ handleRemoveProperty(propertyName);
88
+ }, [propertyName, handleRemoveProperty]);
89
+ return (_jsx(SchemaField, { name: propertyName, required: required, schema: schema, uiSchema: uiSchema, errorSchema: errorSchema, fieldPathId: innerFieldIdPathId, formData: formData, wasPropertyKeyModified: wasPropertyKeyModified, onKeyRename: onKeyRename, onKeyRenameBlur: onKeyRenameBlur, onRemoveProperty: onRemoveProperty, onChange: onPropertyChange, onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError }));
90
+ }
91
+ /** The `ObjectField` component is used to render a field in the schema that is of type `object`. It tracks whether an
92
+ * additional property key was modified and what it was modified to
93
+ *
94
+ * @param props - The `FieldProps` for this template
95
+ */
96
+ export default function ObjectField(props) {
97
+ const { schema: rawSchema, uiSchema = {}, formData, errorSchema, fieldPathId, name, required = false, disabled, readonly, hideError, onBlur, onFocus, onChange, registry, title, } = props;
98
+ const { fields, schemaUtils, translateString, globalUiOptions } = registry;
99
+ const { OptionalDataControlsField } = fields;
100
+ const schema = schemaUtils.retrieveSchema(rawSchema, formData, true);
101
+ const uiOptions = getUiOptions(uiSchema, globalUiOptions);
102
+ const { properties: schemaProperties = {} } = schema;
103
+ const formDataHash = hashObject(formData || {});
104
+ // All the children will use childFieldPathId if present in the props, falling back to the fieldPathId
105
+ const childFieldPathId = props.childFieldPathId ?? fieldPathId;
106
+ const templateTitle = uiOptions.title ?? schema.title ?? title ?? name;
107
+ const description = uiOptions.description ?? schema.description;
108
+ const renderOptionalField = shouldRenderOptionalField(registry, schema, required, uiSchema);
109
+ const hasFormData = isFormDataAvailable(formData);
110
+ let orderedProperties = [];
74
111
  /** Computes the next available key name from the `preferredKey`, indexing through the already existing keys until one
75
112
  * that is already not assigned is found.
76
113
  *
@@ -78,81 +115,25 @@ class ObjectField extends Component {
78
115
  * @param [formData] - The form data in which to check if the desired key already exists
79
116
  * @returns - The name of the next available key from `preferredKey`
80
117
  */
81
- getAvailableKey = (preferredKey, formData) => {
82
- const { uiSchema, registry } = this.props;
83
- const { duplicateKeySuffixSeparator = '-' } = getUiOptions(uiSchema, registry.globalUiOptions);
118
+ const getAvailableKey = useCallback((preferredKey, formData) => {
119
+ const { duplicateKeySuffixSeparator = '-' } = getUiOptions(uiSchema, globalUiOptions);
84
120
  let index = 0;
85
121
  let newKey = preferredKey;
86
122
  while (has(formData, newKey)) {
87
123
  newKey = `${preferredKey}${duplicateKeySuffixSeparator}${++index}`;
88
124
  }
89
125
  return newKey;
90
- };
91
- /** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
92
- * callback will attempt to rename the key and move the existing data to that key, calling `onChange` when it does.
93
- *
94
- * @param oldValue - The old value of a field
95
- * @returns - The key change callback function
96
- */
97
- onKeyChange = (oldValue) => {
98
- return (value, newErrorSchema) => {
99
- if (oldValue === value) {
100
- return;
101
- }
102
- const { formData, onChange, errorSchema } = this.props;
103
- value = this.getAvailableKey(value, formData);
104
- const newFormData = {
105
- ...formData,
106
- };
107
- const newKeys = { [oldValue]: value };
108
- const keyValues = Object.keys(newFormData).map((key) => {
109
- const newKey = newKeys[key] || key;
110
- return { [newKey]: newFormData[key] };
111
- });
112
- const renamedObj = Object.assign({}, ...keyValues);
113
- this.setState({ wasPropertyKeyModified: true });
114
- onChange(renamedObj, errorSchema &&
115
- errorSchema && {
116
- ...errorSchema,
117
- [value]: newErrorSchema,
118
- });
119
- };
120
- };
121
- /** Returns a default value to be used for a new additional schema property of the given `type`
122
- *
123
- * @param type - The type of the new additional schema property
124
- */
125
- getDefaultValue(type) {
126
- const { registry: { translateString }, } = this.props;
127
- switch (type) {
128
- case 'array':
129
- return [];
130
- case 'boolean':
131
- return false;
132
- case 'null':
133
- return null;
134
- case 'number':
135
- return 0;
136
- case 'object':
137
- return {};
138
- case 'string':
139
- default:
140
- // We don't have a datatype for some reason (perhaps additionalProperties was true)
141
- return translateString(TranslatableString.NewStringDefault);
142
- }
143
- }
126
+ }, [uiSchema, globalUiOptions]);
144
127
  /** Handles the adding of a new additional property on the given `schema`. Calls the `onChange` callback once the new
145
128
  * default data for that field has been added to the formData.
146
- *
147
- * @param schema - The schema element to which the new property is being added
148
129
  */
149
- handleAddClick = (schema) => () => {
130
+ const onAddProperty = useCallback(() => {
150
131
  if (!(schema.additionalProperties || schema.patternProperties)) {
151
132
  return;
152
133
  }
153
- const { formData, onChange, registry } = this.props;
134
+ const { translateString } = registry;
154
135
  const newFormData = { ...formData };
155
- const newKey = this.getAvailableKey('newKey', newFormData);
136
+ const newKey = getAvailableKey('newKey', newFormData);
156
137
  if (schema.patternProperties) {
157
138
  // Cast this to make the `set` work properly
158
139
  set(newFormData, newKey, null);
@@ -168,7 +149,7 @@ class ObjectField extends Component {
168
149
  let apSchema = schema.additionalProperties;
169
150
  if (REF_KEY in apSchema) {
170
151
  const { schemaUtils } = registry;
171
- apSchema = schemaUtils.retrieveSchema({ $ref: apSchema[REF_KEY] }, formData);
152
+ apSchema = schemaUtils.retrieveSchema({ [REF_KEY]: apSchema[REF_KEY] }, formData);
172
153
  type = apSchema.type;
173
154
  constValue = apSchema.const;
174
155
  defaultValue = apSchema.default;
@@ -177,24 +158,42 @@ class ObjectField extends Component {
177
158
  type = 'object';
178
159
  }
179
160
  }
180
- const newValue = constValue ?? defaultValue ?? this.getDefaultValue(type);
161
+ const newValue = constValue ?? defaultValue ?? getDefaultValue(translateString, type);
181
162
  // Cast this to make the `set` work properly
182
163
  set(newFormData, newKey, newValue);
183
164
  }
184
- onChange(newFormData);
185
- };
186
- /** Renders the `ObjectField` from the given props
165
+ onChange(newFormData, childFieldPathId.path);
166
+ }, [formData, onChange, registry, childFieldPathId, getAvailableKey, schema]);
167
+ /** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
168
+ * callback will attempt to rename the key and move the existing data to that key, calling `onChange` when it does.
169
+ *
170
+ * @param oldKey - The old key for the field
171
+ * @param newKey - The new key for the field
172
+ * @returns - The key change callback function
173
+ */
174
+ const handleKeyRename = useCallback((oldKey, newKey) => {
175
+ if (oldKey !== newKey) {
176
+ const actualNewKey = getAvailableKey(newKey, formData);
177
+ const newFormData = {
178
+ ...formData,
179
+ };
180
+ const newKeys = { [oldKey]: actualNewKey };
181
+ const keyValues = Object.keys(newFormData).map((key) => {
182
+ const newKey = newKeys[key] || key;
183
+ return { [newKey]: newFormData[key] };
184
+ });
185
+ const renamedObj = Object.assign({}, ...keyValues);
186
+ onChange(renamedObj, childFieldPathId.path);
187
+ }
188
+ }, [formData, onChange, childFieldPathId, getAvailableKey]);
189
+ /** Handles the remove click which removes the old `key` data and calls the `onChange` callback with it
187
190
  */
188
- render() {
189
- const { schema: rawSchema, uiSchema = {}, formData, errorSchema, idSchema, name, required = false, disabled, readonly, hideError, idPrefix, idSeparator, onBlur, onFocus, registry, title, } = this.props;
190
- const { fields, formContext, schemaUtils, translateString, globalUiOptions } = registry;
191
- const { SchemaField } = fields;
192
- const schema = schemaUtils.retrieveSchema(rawSchema, formData);
193
- const uiOptions = getUiOptions(uiSchema, globalUiOptions);
194
- const { properties: schemaProperties = {} } = schema;
195
- const templateTitle = uiOptions.title ?? schema.title ?? title ?? name;
196
- const description = uiOptions.description ?? schema.description;
197
- let orderedProperties;
191
+ const handleRemoveProperty = useCallback((key) => {
192
+ const copiedFormData = { ...formData };
193
+ unset(copiedFormData, key);
194
+ onChange(copiedFormData, childFieldPathId.path);
195
+ }, [onChange, childFieldPathId, formData]);
196
+ if (!renderOptionalField || hasFormData) {
198
197
  try {
199
198
  const properties = Object.keys(schemaProperties);
200
199
  orderedProperties = orderProperties(properties, uiOptions.order);
@@ -202,37 +201,38 @@ class ObjectField extends Component {
202
201
  catch (err) {
203
202
  return (_jsxs("div", { children: [_jsx("p", { className: 'rjsf-config-error', style: { color: 'red' }, children: _jsx(Markdown, { options: { disableParsingRawHTML: true }, children: translateString(TranslatableString.InvalidObjectField, [name || 'root', err.message]) }) }), _jsx("pre", { children: JSON.stringify(schema) })] }));
204
203
  }
205
- const Template = getTemplate('ObjectFieldTemplate', registry, uiOptions);
206
- const templateProps = {
207
- // getDisplayLabel() always returns false for object types, so just check the `uiOptions.label`
208
- title: uiOptions.label === false ? '' : templateTitle,
209
- description: uiOptions.label === false ? undefined : description,
210
- properties: orderedProperties.map((name) => {
211
- const addedByAdditionalProperties = has(schema, [PROPERTIES_KEY, name, ADDITIONAL_PROPERTY_FLAG]);
212
- const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[name];
213
- const hidden = getUiOptions(fieldUiSchema).widget === 'hidden';
214
- const fieldIdSchema = get(idSchema, [name], {});
215
- return {
216
- content: (_jsx(SchemaField, { name: name, required: this.isRequired(name), schema: get(schema, [PROPERTIES_KEY, name], {}), uiSchema: fieldUiSchema, errorSchema: get(errorSchema, name), idSchema: fieldIdSchema, idPrefix: idPrefix, idSeparator: idSeparator, formData: get(formData, name), formContext: formContext, wasPropertyKeyModified: this.state.wasPropertyKeyModified, onKeyChange: this.onKeyChange(name), onChange: this.onPropertyChange(name, addedByAdditionalProperties), onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError, onDropPropertyClick: this.onDropPropertyClick }, name)),
217
- name,
218
- readonly,
219
- disabled,
220
- required,
221
- hidden,
222
- };
223
- }),
224
- readonly,
225
- disabled,
226
- required,
227
- idSchema,
228
- uiSchema,
229
- errorSchema,
230
- schema,
231
- formData,
232
- formContext,
233
- registry,
234
- };
235
- return _jsx(Template, { ...templateProps, onAddClick: this.handleAddClick });
236
204
  }
205
+ const Template = getTemplate('ObjectFieldTemplate', registry, uiOptions);
206
+ const optionalDataControl = renderOptionalField ? (_jsx(OptionalDataControlsField, { ...props, fieldPathId: childFieldPathId, schema: schema })) : undefined;
207
+ const templateProps = {
208
+ // getDisplayLabel() always returns false for object types, so just check the `uiOptions.label`
209
+ title: uiOptions.label === false ? '' : templateTitle,
210
+ description: uiOptions.label === false ? undefined : description,
211
+ properties: orderedProperties.map((name) => {
212
+ const addedByAdditionalProperties = has(schema, [PROPERTIES_KEY, name, ADDITIONAL_PROPERTY_FLAG]);
213
+ const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[name];
214
+ const hidden = getUiOptions(fieldUiSchema).widget === 'hidden';
215
+ const content = (_jsx(ObjectFieldProperty, { propertyName: name, required: isRequired(schema, name), schema: get(schema, [PROPERTIES_KEY, name], {}), uiSchema: fieldUiSchema, errorSchema: get(errorSchema, name), fieldPathId: childFieldPathId, formData: get(formData, name), handleKeyRename: handleKeyRename, handleRemoveProperty: handleRemoveProperty, addedByAdditionalProperties: addedByAdditionalProperties, onChange: onChange, onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError }, addedByAdditionalProperties ? `${name}-${formDataHash}` : name));
216
+ return {
217
+ content,
218
+ name,
219
+ readonly,
220
+ disabled,
221
+ required,
222
+ hidden,
223
+ };
224
+ }),
225
+ readonly,
226
+ disabled,
227
+ required,
228
+ fieldPathId,
229
+ uiSchema,
230
+ errorSchema,
231
+ schema,
232
+ formData,
233
+ registry,
234
+ optionalDataControl,
235
+ className: renderOptionalField ? 'rjsf-optional-object-field' : undefined,
236
+ };
237
+ return _jsx(Template, { ...templateProps, onAddProperty: onAddProperty });
237
238
  }
238
- export default ObjectField;
@@ -0,0 +1,8 @@
1
+ import { FieldProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
2
+ /** The `OptionalDataControlsField` component is used to render the optional data controls for the field associated
3
+ * with the given props.
4
+ *
5
+ * @param props - The `FieldProps` for this template
6
+ */
7
+ export default function OptionalDataControlsField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>): "" | import("react/jsx-runtime").JSX.Element | undefined;
8
+ //# sourceMappingURL=OptionalDataControlsField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OptionalDataControlsField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/OptionalDataControlsField.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,eAAe,EAOf,UAAU,EACV,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,gBAAgB,GAAG,UAAU,EACvC,CAAC,SAAS,eAAe,GAAG,GAAG,EAC/B,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,4DA4D3B"}
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { getSchemaType, getTemplate, getUiOptions, isFormDataAvailable, optionalControlsId, TranslatableString, } from '@rjsf/utils';
3
+ /** The `OptionalDataControlsField` component is used to render the optional data controls for the field associated
4
+ * with the given props.
5
+ *
6
+ * @param props - The `FieldProps` for this template
7
+ */
8
+ export default function OptionalDataControlsField(props) {
9
+ const { schema, uiSchema = {}, formData, disabled = false, readonly = false, onChange, errorSchema, fieldPathId, registry, } = props;
10
+ const { globalUiOptions = {}, schemaUtils, translateString } = registry;
11
+ const uiOptions = getUiOptions(uiSchema, globalUiOptions);
12
+ const OptionalDataControlsTemplate = getTemplate('OptionalDataControlsTemplate', registry, uiOptions);
13
+ const hasFormData = isFormDataAvailable(formData);
14
+ let id;
15
+ let label;
16
+ let onAddClick;
17
+ let onRemoveClick;
18
+ if (disabled || readonly) {
19
+ id = optionalControlsId(fieldPathId, 'Msg');
20
+ label = hasFormData ? undefined : translateString(TranslatableString.OptionalObjectEmptyMsg);
21
+ }
22
+ else {
23
+ const labelEnum = hasFormData ? TranslatableString.OptionalObjectRemove : TranslatableString.OptionalObjectAdd;
24
+ label = translateString(labelEnum);
25
+ if (hasFormData) {
26
+ id = optionalControlsId(fieldPathId, 'Remove');
27
+ onRemoveClick = () => onChange(undefined, fieldPathId.path, errorSchema);
28
+ }
29
+ else {
30
+ id = optionalControlsId(fieldPathId, 'Add');
31
+ onAddClick = () => {
32
+ // If it has form data, store an empty object, otherwise get the default form state and use it
33
+ let newFormData = schemaUtils.getDefaultFormState(schema, formData, 'excludeObjectChildren');
34
+ if (newFormData === undefined) {
35
+ // If new form data ended up being undefined, and we have pushed the add button we need to actually add data
36
+ newFormData = getSchemaType(schema) === 'array' ? [] : {};
37
+ }
38
+ onChange(newFormData, fieldPathId.path, errorSchema);
39
+ };
40
+ }
41
+ }
42
+ return (label && (_jsx(OptionalDataControlsTemplate, { id: id, registry: registry, schema: schema, uiSchema: uiSchema, label: label, onAddClick: onAddClick, onRemoveClick: onRemoveClick })));
43
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/SchemaField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAiB,MAAM,OAAO,CAAC;AAC9D,OAAO,EAKL,UAAU,EAEV,eAAe,EAQf,UAAU,EACV,gBAAgB,EAIjB,MAAM,aAAa,CAAC;AA6TrB;;GAEG;AACH,cAAM,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,CAAE,SAAQ,SAAS,CACpH,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CACpB;IACC,qBAAqB,CAAC,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAI9D,MAAM;CAGP;AAED,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"SchemaField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/SchemaField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAiB,MAAM,OAAO,CAAC;AAC9D,OAAO,EAQL,UAAU,EAEV,eAAe,EAQf,UAAU,EAGV,gBAAgB,EAIjB,MAAM,aAAa,CAAC;AAgSrB;;GAEG;AACH,cAAM,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,CAAE,SAAQ,SAAS,CACpH,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CACpB;IACC,qBAAqB,CAAC,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAS9D,MAAM;CAGP;AAED,eAAe,WAAW,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, Component } from 'react';
3
- import { ADDITIONAL_PROPERTY_FLAG, deepEquals, descriptionId, getSchemaType, getTemplate, getUiOptions, ID_KEY, mergeObjects, TranslatableString, UI_OPTIONS_KEY, } from '@rjsf/utils';
3
+ import { ADDITIONAL_PROPERTY_FLAG, ANY_OF_KEY, descriptionId, getSchemaType, getTemplate, getUiOptions, ID_KEY, isFormDataAvailable, ONE_OF_KEY, shouldRender, shouldRenderOptionalField, toFieldPathId, UI_OPTIONS_KEY, } from '@rjsf/utils';
4
4
  import isObject from 'lodash-es/isObject.js';
5
5
  import omit from 'lodash-es/omit.js';
6
6
  /** The map of component type to FieldName */
@@ -19,13 +19,12 @@ const COMPONENT_TYPES = {
19
19
  *
20
20
  * @param schema - The schema from which to obtain the type
21
21
  * @param uiOptions - The UI Options that may affect the component decision
22
- * @param idSchema - The id that is passed to the `UnsupportedFieldTemplate`
23
22
  * @param registry - The registry from which fields and templates are obtained
24
23
  * @returns - The `Field` component that is used to render the actual field data
25
24
  */
26
- function getFieldComponent(schema, uiOptions, idSchema, registry) {
25
+ function getFieldComponent(schema, uiOptions, registry) {
27
26
  const field = uiOptions.field;
28
- const { fields, translateString } = registry;
27
+ const { fields } = registry;
29
28
  if (typeof field === 'function') {
30
29
  return field;
31
30
  }
@@ -44,12 +43,7 @@ function getFieldComponent(schema, uiOptions, idSchema, registry) {
44
43
  if (!componentName && (schema.anyOf || schema.oneOf)) {
45
44
  return () => null;
46
45
  }
47
- return componentName in fields
48
- ? fields[componentName]
49
- : () => {
50
- const UnsupportedFieldTemplate = getTemplate('UnsupportedFieldTemplate', registry, uiOptions);
51
- return (_jsx(UnsupportedFieldTemplate, { schema: schema, idSchema: idSchema, reason: translateString(TranslatableString.UnknownFieldType, [String(schema.type)]), registry: registry }));
52
- };
46
+ return componentName in fields ? fields[componentName] : fields['FallbackField'];
53
47
  }
54
48
  /** The `SchemaFieldRender` component is the work-horse of react-jsonschema-form, determining what kind of real field to
55
49
  * render based on the `schema`, `uiSchema` and all the other props. It also deals with rendering the `anyOf` and
@@ -58,24 +52,24 @@ function getFieldComponent(schema, uiOptions, idSchema, registry) {
58
52
  * @param props - The `FieldProps` for this component
59
53
  */
60
54
  function SchemaFieldRender(props) {
61
- const { schema: _schema, idSchema: _idSchema, uiSchema, formData, errorSchema, idPrefix, idSeparator, name, onChange, onKeyChange, onDropPropertyClick, required, registry, wasPropertyKeyModified = false, } = props;
62
- const { formContext, schemaUtils, globalUiOptions } = registry;
55
+ const { schema: _schema, fieldPathId, uiSchema, formData, errorSchema, name, onChange, onKeyRename, onKeyRenameBlur, onRemoveProperty, required = false, registry, wasPropertyKeyModified = false, } = props;
56
+ const { schemaUtils, globalFormOptions, globalUiOptions, fields } = registry;
57
+ const { AnyOfField: _AnyOfField, OneOfField: _OneOfField } = fields;
63
58
  const uiOptions = getUiOptions(uiSchema, globalUiOptions);
64
59
  const FieldTemplate = getTemplate('FieldTemplate', registry, uiOptions);
65
60
  const DescriptionFieldTemplate = getTemplate('DescriptionFieldTemplate', registry, uiOptions);
66
61
  const FieldHelpTemplate = getTemplate('FieldHelpTemplate', registry, uiOptions);
67
62
  const FieldErrorTemplate = getTemplate('FieldErrorTemplate', registry, uiOptions);
68
63
  const schema = schemaUtils.retrieveSchema(_schema, formData);
69
- const fieldId = _idSchema[ID_KEY];
70
- const idSchema = mergeObjects(schemaUtils.toIdSchema(schema, fieldId, formData, idPrefix, idSeparator), _idSchema);
64
+ const fieldId = fieldPathId[ID_KEY];
71
65
  /** Intermediary `onChange` handler for field components that will inject the `id` of the current field into the
72
66
  * `onChange` chain if it is not already being provided from a deeper level in the hierarchy
73
67
  */
74
- const handleFieldComponentChange = useCallback((formData, newErrorSchema, id) => {
68
+ const handleFieldComponentChange = useCallback((formData, path, newErrorSchema, id) => {
75
69
  const theId = id || fieldId;
76
- return onChange(formData, newErrorSchema, theId);
70
+ return onChange(formData, path, newErrorSchema, theId);
77
71
  }, [fieldId, onChange]);
78
- const FieldComponent = getFieldComponent(schema, uiOptions, idSchema, registry);
72
+ const FieldComponent = getFieldComponent(schema, uiOptions, registry);
79
73
  const disabled = Boolean(uiOptions.disabled ?? props.disabled);
80
74
  const readonly = Boolean(uiOptions.readonly ?? (props.readonly || props.schema.readOnly || schema.readOnly));
81
75
  const uiSchemaHideError = uiOptions.hideError;
@@ -85,15 +79,44 @@ function SchemaFieldRender(props) {
85
79
  if (Object.keys(schema).length === 0) {
86
80
  return null;
87
81
  }
88
- const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
82
+ let displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
83
+ /** If the schema `anyOf` or 'oneOf' can be rendered as a select control, don't render the selection and let
84
+ * `StringField` component handle rendering unless there is a field override and that field replaces the any or one of
85
+ */
86
+ const isReplacingAnyOrOneOf = uiOptions.field && uiOptions.fieldReplacesAnyOrOneOf === true;
87
+ let XxxOfField;
88
+ let XxxOfOptions;
89
+ // When rendering the `XxxOfField` we'll need to change the fieldPathId of the main component, remembering the
90
+ // fieldPathId of the children for the ObjectField and ArrayField
91
+ let fieldPathIdProps = { fieldPathId };
92
+ if ((ANY_OF_KEY in schema || ONE_OF_KEY in schema) && !isReplacingAnyOrOneOf && !schemaUtils.isSelect(schema)) {
93
+ if (schema[ANY_OF_KEY]) {
94
+ XxxOfField = _AnyOfField;
95
+ XxxOfOptions = schema[ANY_OF_KEY].map((_schema) => schemaUtils.retrieveSchema(isObject(_schema) ? _schema : {}, formData));
96
+ }
97
+ else if (schema[ONE_OF_KEY]) {
98
+ XxxOfField = _OneOfField;
99
+ XxxOfOptions = schema[ONE_OF_KEY].map((_schema) => schemaUtils.retrieveSchema(isObject(_schema) ? _schema : {}, formData));
100
+ }
101
+ // When the anyOf/oneOf is an optional data control render AND it does not have form data, hide the label
102
+ const isOptionalRender = shouldRenderOptionalField(registry, schema, required, uiSchema);
103
+ const hasFormData = isFormDataAvailable(formData);
104
+ displayLabel = displayLabel && (!isOptionalRender || hasFormData);
105
+ fieldPathIdProps = {
106
+ childFieldPathId: fieldPathId,
107
+ // The main FieldComponent will add `XxxOf` onto the fieldPathId to avoid duplication with the rendering of the
108
+ // same FieldComponent by the `XxxOfField`
109
+ fieldPathId: toFieldPathId('XxxOf', globalFormOptions, fieldPathId),
110
+ };
111
+ }
89
112
  const { __errors, ...fieldErrorSchema } = errorSchema || {};
90
113
  // See #439: uiSchema: Don't pass consumed class names or style to child components
91
114
  const fieldUiSchema = omit(uiSchema, ['ui:classNames', 'classNames', 'ui:style']);
92
115
  if (UI_OPTIONS_KEY in fieldUiSchema) {
93
116
  fieldUiSchema[UI_OPTIONS_KEY] = omit(fieldUiSchema[UI_OPTIONS_KEY], ['classNames', 'style']);
94
117
  }
95
- const field = (_jsx(FieldComponent, { ...props, onChange: handleFieldComponentChange, idSchema: idSchema, schema: schema, uiSchema: fieldUiSchema, disabled: disabled, readonly: readonly, hideError: hideError, autofocus: autofocus, errorSchema: fieldErrorSchema, formContext: formContext, rawErrors: __errors }));
96
- const id = idSchema[ID_KEY];
118
+ const field = (_jsx(FieldComponent, { ...props, onChange: handleFieldComponentChange, ...fieldPathIdProps, schema: schema, uiSchema: fieldUiSchema, disabled: disabled, readonly: readonly, hideError: hideError, autofocus: autofocus, errorSchema: fieldErrorSchema, rawErrors: __errors }));
119
+ const id = fieldPathId[ID_KEY];
97
120
  // If this schema has a title defined, but the user has set a new key/label, retain their input.
98
121
  let label;
99
122
  if (wasPropertyKeyModified) {
@@ -115,12 +138,12 @@ function SchemaFieldRender(props) {
115
138
  if (uiOptions.classNames) {
116
139
  classNames.push(uiOptions.classNames);
117
140
  }
118
- const helpComponent = (_jsx(FieldHelpTemplate, { help: help, idSchema: idSchema, schema: schema, uiSchema: uiSchema, hasErrors: !hideError && __errors && __errors.length > 0, registry: registry }));
141
+ const helpComponent = (_jsx(FieldHelpTemplate, { help: help, fieldPathId: fieldPathId, schema: schema, uiSchema: uiSchema, hasErrors: !hideError && __errors && __errors.length > 0, registry: registry }));
119
142
  /*
120
143
  * AnyOf/OneOf errors handled by child schema
121
144
  * unless it can be rendered as select control
122
145
  */
123
- const errorsComponent = hideError || ((schema.anyOf || schema.oneOf) && !schemaUtils.isSelect(schema)) ? undefined : (_jsx(FieldErrorTemplate, { errors: __errors, errorSchema: errorSchema, idSchema: idSchema, schema: schema, uiSchema: uiSchema, registry: registry }));
146
+ const errorsComponent = hideError || (XxxOfField && !schemaUtils.isSelect(schema)) ? undefined : (_jsx(FieldErrorTemplate, { errors: __errors, errorSchema: errorSchema, fieldPathId: fieldPathId, schema: schema, uiSchema: uiSchema, registry: registry }));
124
147
  const fieldProps = {
125
148
  description: (_jsx(DescriptionFieldTemplate, { id: descriptionId(id), description: description, schema: schema, uiSchema: uiSchema, registry: registry })),
126
149
  rawDescription: description,
@@ -132,8 +155,9 @@ function SchemaFieldRender(props) {
132
155
  label,
133
156
  hidden,
134
157
  onChange,
135
- onKeyChange,
136
- onDropPropertyClick,
158
+ onKeyRename,
159
+ onKeyRenameBlur,
160
+ onRemoveProperty,
137
161
  required,
138
162
  disabled,
139
163
  readonly,
@@ -141,23 +165,21 @@ function SchemaFieldRender(props) {
141
165
  displayLabel,
142
166
  classNames: classNames.join(' ').trim(),
143
167
  style: uiOptions.style,
144
- formContext,
145
168
  formData,
146
169
  schema,
147
170
  uiSchema,
148
171
  registry,
149
172
  };
150
- const _AnyOfField = registry.fields.AnyOfField;
151
- const _OneOfField = registry.fields.OneOfField;
152
- const isReplacingAnyOrOneOf = uiSchema?.['ui:field'] && uiSchema?.['ui:fieldReplacesAnyOrOneOf'] === true;
153
- return (_jsx(FieldTemplate, { ...fieldProps, children: _jsxs(_Fragment, { children: [field, schema.anyOf && !isReplacingAnyOrOneOf && !schemaUtils.isSelect(schema) && (_jsx(_AnyOfField, { name: name, disabled: disabled, readonly: readonly, hideError: hideError, errorSchema: errorSchema, formData: formData, formContext: formContext, idPrefix: idPrefix, idSchema: idSchema, idSeparator: idSeparator, onBlur: props.onBlur, onChange: props.onChange, onFocus: props.onFocus, options: schema.anyOf.map((_schema) => schemaUtils.retrieveSchema(isObject(_schema) ? _schema : {}, formData)), registry: registry, required: required, schema: schema, uiSchema: uiSchema })), schema.oneOf && !isReplacingAnyOrOneOf && !schemaUtils.isSelect(schema) && (_jsx(_OneOfField, { name: name, disabled: disabled, readonly: readonly, hideError: hideError, errorSchema: errorSchema, formData: formData, formContext: formContext, idPrefix: idPrefix, idSchema: idSchema, idSeparator: idSeparator, onBlur: props.onBlur, onChange: props.onChange, onFocus: props.onFocus, options: schema.oneOf.map((_schema) => schemaUtils.retrieveSchema(isObject(_schema) ? _schema : {}, formData)), registry: registry, required: required, schema: schema, uiSchema: uiSchema }))] }) }));
173
+ return (_jsx(FieldTemplate, { ...fieldProps, children: _jsxs(_Fragment, { children: [field, XxxOfField && (_jsx(XxxOfField, { name: name, disabled: disabled, readonly: readonly, hideError: hideError, errorSchema: errorSchema, formData: formData, fieldPathId: fieldPathId, onBlur: props.onBlur, onChange: props.onChange, onFocus: props.onFocus, options: XxxOfOptions, registry: registry, required: required, schema: schema, uiSchema: uiSchema }))] }) }));
154
174
  }
155
175
  /** The `SchemaField` component determines whether it is necessary to rerender the component based on any props changes
156
176
  * and if so, calls the `SchemaFieldRender` component with the props.
157
177
  */
158
178
  class SchemaField extends Component {
159
179
  shouldComponentUpdate(nextProps) {
160
- return !deepEquals(this.props, nextProps);
180
+ const { registry: { globalFormOptions }, } = this.props;
181
+ const { experimental_componentUpdateStrategy = 'customDeep' } = globalFormOptions;
182
+ return shouldRender(this, nextProps, this.state, experimental_componentUpdateStrategy);
161
183
  }
162
184
  render() {
163
185
  return _jsx(SchemaFieldRender, { ...this.props });
@@ -1 +1 @@
1
- {"version":3,"file":"StringField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/StringField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,UAAU,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,iBAAS,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,EACpG,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,2CAsD3B;AAED,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"StringField.d.ts","sourceRoot":"","sources":["../../../src/components/fields/StringField.tsx"],"names":[],"mappings":"AACA,OAAO,EAKL,UAAU,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,iBAAS,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,GAAG,UAAU,EAAE,CAAC,SAAS,eAAe,GAAG,GAAG,EACpG,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,2CA6D3B;AAED,eAAe,WAAW,CAAC"}