@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
@@ -1,5 +1,5 @@
1
1
  import type { ComponentType } from 'react';
2
- import { useCallback, Component } from 'react';
2
+ import { useCallback, memo } from 'react';
3
3
  import type {
4
4
  ErrorSchema,
5
5
  Field,
@@ -9,6 +9,7 @@ import type {
9
9
  FieldTemplateProps,
10
10
  FormContextType,
11
11
  Registry,
12
+ RJSFMarkedSchema,
12
13
  RJSFSchema,
13
14
  StrictRJSFSchema,
14
15
  UIOptionsType,
@@ -16,6 +17,7 @@ import type {
16
17
  import {
17
18
  ADDITIONAL_PROPERTY_FLAG,
18
19
  ANY_OF_KEY,
20
+ deepEquals,
19
21
  descriptionId,
20
22
  getSchemaType,
21
23
  getTemplate,
@@ -24,7 +26,8 @@ import {
24
26
  isFormDataAvailable,
25
27
  ONE_OF_KEY,
26
28
  resolveUiSchema,
27
- shouldRender,
29
+ RJSF_REF_CYCLE_KEY,
30
+ shallowEquals,
28
31
  shouldRenderOptionalField,
29
32
  toFieldPathId,
30
33
  TranslatableString,
@@ -59,7 +62,7 @@ function getFieldComponent<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
59
62
  registry: Registry<T, S, F>,
60
63
  ): ComponentType<FieldProps<T, S, F>> {
61
64
  const { field } = uiOptions;
62
- const { fields } = registry;
65
+ const { fields, schemaUtils } = registry;
63
66
  if (typeof field === 'function') {
64
67
  return field;
65
68
  }
@@ -77,9 +80,13 @@ function getFieldComponent<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
77
80
  componentName = schemaId;
78
81
  }
79
82
 
80
- // If the type is not defined and the schema uses 'anyOf' or 'oneOf', don't
81
- // render a field and let the MultiSchemaField component handle the form display
82
- if (!componentName && (schema.anyOf || schema.oneOf)) {
83
+ // If the schema uses 'anyOf' or 'oneOf' and is not a pure select (all-constant options),
84
+ // let the MultiSchemaField component handle the form display entirely.
85
+ // ObjectField is excluded: it renders shared properties (defined at the parent schema
86
+ // level) alongside the XxxOfField option selector.
87
+ // All other field types — including primitives and arrays — have no shared renderable
88
+ // properties, so the outer FieldComponent would only produce a spurious duplicate input.
89
+ if ((schema.anyOf || schema.oneOf) && !schemaUtils.isSelect(schema) && componentName !== 'ObjectField') {
83
90
  return () => null;
84
91
  }
85
92
 
@@ -111,18 +118,7 @@ function SchemaFieldRender<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
111
118
  wasPropertyKeyModified = false,
112
119
  } = props;
113
120
  const { schemaUtils, globalFormOptions, globalUiOptions, fields } = registry;
114
- const { AnyOfField: _AnyOfField, OneOfField: _OneOfField } = fields;
115
- const uiSchema = resolveUiSchema<T, S, F>(_schema, _uiSchema, registry);
116
- const uiOptions = getUiOptions<T, S, F>(uiSchema, globalUiOptions);
117
- const FieldTemplate = getTemplate<'FieldTemplate', T, S, F>('FieldTemplate', registry, uiOptions);
118
- const DescriptionFieldTemplate = getTemplate<'DescriptionFieldTemplate', T, S, F>(
119
- 'DescriptionFieldTemplate',
120
- registry,
121
- uiOptions,
122
- );
123
- const FieldHelpTemplate = getTemplate<'FieldHelpTemplate', T, S, F>('FieldHelpTemplate', registry, uiOptions);
124
- const FieldErrorTemplate = getTemplate<'FieldErrorTemplate', T, S, F>('FieldErrorTemplate', registry, uiOptions);
125
- const schema = schemaUtils.retrieveSchema(_schema, formData);
121
+ const { AnyOfField: _AnyOfField, OneOfField: _OneOfField, CyclicSchemaField } = fields;
126
122
  const fieldId = fieldPathId[ID_KEY];
127
123
 
128
124
  /** Intermediary `onChange` handler for field components that will inject the `id` of the current field into the
@@ -136,6 +132,24 @@ function SchemaFieldRender<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
136
132
  [fieldId, onChange],
137
133
  );
138
134
 
135
+ // Stop $ref cycles: when resolveAllReferences detects a repeated property $ref it tags the schema with this flag.
136
+ // The check must come after all hook calls to satisfy React's rules of hooks.
137
+ if ((_schema as RJSFMarkedSchema)[RJSF_REF_CYCLE_KEY]) {
138
+ return <CyclicSchemaField {...props} />;
139
+ }
140
+
141
+ const uiSchema = resolveUiSchema<T, S, F>(_schema, _uiSchema, registry);
142
+ const uiOptions = getUiOptions<T, S, F>(uiSchema, globalUiOptions);
143
+ const FieldTemplate = getTemplate<'FieldTemplate', T, S, F>('FieldTemplate', registry, uiOptions);
144
+ const DescriptionFieldTemplate = getTemplate<'DescriptionFieldTemplate', T, S, F>(
145
+ 'DescriptionFieldTemplate',
146
+ registry,
147
+ uiOptions,
148
+ );
149
+ const FieldHelpTemplate = getTemplate<'FieldHelpTemplate', T, S, F>('FieldHelpTemplate', registry, uiOptions);
150
+ const FieldErrorTemplate = getTemplate<'FieldErrorTemplate', T, S, F>('FieldErrorTemplate', registry, uiOptions);
151
+ const schema = schemaUtils.retrieveSchema(_schema, formData);
152
+
139
153
  const FieldComponent = getFieldComponent<T, S, F>(schema, uiOptions, registry);
140
154
 
141
155
  const isDeprecated = Boolean(schema.deprecated);
@@ -327,24 +341,22 @@ function SchemaFieldRender<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
327
341
  );
328
342
  }
329
343
 
330
- /** The `SchemaField` component determines whether it is necessary to rerender the component based on any props changes
331
- * and if so, calls the `SchemaFieldRender` component with the props.
344
+ /** The `SchemaField` component wraps `SchemaFieldRender` with a custom memoization comparator that determines whether it is necessary to rerender the component based on any props changes
345
+ * using `experimental_componentUpdateStrategy`.
346
+ *
347
+ * The cast to `typeof SchemaFieldRender` preserves the generic type signature (<T, S, F>) for consumers,
348
+ * since React.memo's return type erases generic parameters.
332
349
  */
333
- class SchemaField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> extends Component<
334
- FieldProps<T, S, F>
335
- > {
336
- shouldComponentUpdate(nextProps: Readonly<FieldProps<T, S, F>>) {
337
- const {
338
- registry: { globalFormOptions },
339
- } = this.props;
340
- const { experimental_componentUpdateStrategy = 'customDeep' } = globalFormOptions;
341
-
342
- return shouldRender(this, nextProps, this.state, experimental_componentUpdateStrategy);
350
+ const SchemaField = memo(SchemaFieldRender, (prevProps, nextProps) => {
351
+ const { experimental_componentUpdateStrategy = 'customDeep' } = nextProps.registry.globalFormOptions;
352
+ if (experimental_componentUpdateStrategy === 'always') {
353
+ return false; // always re-render — never consider props equal
343
354
  }
344
-
345
- render() {
346
- return <SchemaFieldRender<T, S, F> {...this.props} />;
355
+ if (experimental_componentUpdateStrategy === 'shallow') {
356
+ return shallowEquals(prevProps, nextProps);
347
357
  }
348
- }
358
+ // default: 'customDeep'
359
+ return deepEquals(prevProps, nextProps);
360
+ }) as unknown as typeof SchemaFieldRender;
349
361
 
350
362
  export default SchemaField;
@@ -2,6 +2,7 @@ import type { Field, FormContextType, RegistryFieldsType, RJSFSchema, StrictRJSF
2
2
 
3
3
  import ArrayField from './ArrayField';
4
4
  import BooleanField from './BooleanField';
5
+ import CyclicSchemaField from './CyclicSchemaField';
5
6
  import FallbackField from './FallbackField';
6
7
  import LayoutGridField from './LayoutGridField';
7
8
  import LayoutHeaderField from './LayoutHeaderField';
@@ -24,6 +25,7 @@ function fields<
24
25
  ArrayField: ArrayField as unknown as Field<T, S, F>,
25
26
  // ArrayField falls back to SchemaField if ArraySchemaField is not defined, which it isn't by default
26
27
  BooleanField,
28
+ CyclicSchemaField,
27
29
  FallbackField,
28
30
  LayoutGridField,
29
31
  LayoutHeaderField,
@@ -64,12 +64,9 @@ export default function BaseInputTemplate<
64
64
  onChange(newValue === '' ? options.emptyValue : newValue),
65
65
  [onChange, options],
66
66
  );
67
- const handleBlur = useCallback(
68
- ({ target }: FocusEvent<HTMLInputElement>) => onBlur(id, target && target.value),
69
- [onBlur, id],
70
- );
67
+ const handleBlur = useCallback(({ target }: FocusEvent<HTMLInputElement>) => onBlur(id, target?.value), [onBlur, id]);
71
68
  const handleFocus = useCallback(
72
- ({ target }: FocusEvent<HTMLInputElement>) => onFocus(id, target && target.value),
69
+ ({ target }: FocusEvent<HTMLInputElement>) => onFocus(id, target?.value),
73
70
  [onFocus, id],
74
71
  );
75
72
  const handleClear = useCallback(
@@ -0,0 +1,31 @@
1
+ import type { CyclicSchemaExpandProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
2
+ import { ID_KEY, TranslatableString } from '@rjsf/utils';
3
+
4
+ /** The `CyclicSchemaExpandTemplate` is the template to use to render the cyclic schema expand message and controls
5
+ *
6
+ * @param props - The `DescriptionFieldProps` for this component
7
+ */
8
+ export default function CyclicSchemaExpandTemplate<
9
+ T = any,
10
+ S extends StrictRJSFSchema = RJSFSchema,
11
+ F extends FormContextType = any,
12
+ >(props: CyclicSchemaExpandProps<T, S, F>) {
13
+ const { name, fieldPathId, registry, onExpand } = props;
14
+ const { translateString } = registry;
15
+ const buttonId = `${fieldPathId[ID_KEY]}-button`;
16
+ return (
17
+ <div style={{ marginTop: '1rem' }}>
18
+ <div className='text-danger'>{translateString(TranslatableString.CycleDetected, [name])}</div>
19
+ <div>
20
+ <button
21
+ id={buttonId}
22
+ type='button'
23
+ className='btn btn-sm btn-warning'
24
+ onClick={() => onExpand(fieldPathId[ID_KEY])}
25
+ >
26
+ {translateString(TranslatableString.ExpandButton)}
27
+ </button>{' '}
28
+ </div>
29
+ </div>
30
+ );
31
+ }
@@ -14,7 +14,7 @@ function UnsupportedField<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
14
14
  const { translateString } = registry;
15
15
  let translateEnum: TranslatableString = TranslatableString.UnsupportedField;
16
16
  const translateParams: string[] = [];
17
- if (fieldPathId && fieldPathId.$id) {
17
+ if (fieldPathId?.$id) {
18
18
  translateEnum = TranslatableString.UnsupportedFieldWithId;
19
19
  translateParams.push(fieldPathId.$id);
20
20
  }
@@ -7,6 +7,7 @@ import ArrayFieldTemplate from './ArrayFieldTemplate';
7
7
  import ArrayFieldTitleTemplate from './ArrayFieldTitleTemplate';
8
8
  import BaseInputTemplate from './BaseInputTemplate';
9
9
  import ButtonTemplates from './ButtonTemplates';
10
+ import CyclicSchemaExpandTemplate from './CyclicSchemaExpandTemplate';
10
11
  import DescriptionField from './DescriptionField';
11
12
  import ErrorList from './ErrorList';
12
13
  import FallbackFieldTemplate from './FallbackFieldTemplate';
@@ -34,6 +35,7 @@ function templates<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends F
34
35
  ArrayFieldTitleTemplate,
35
36
  ButtonTemplates: ButtonTemplates<T, S, F>(),
36
37
  BaseInputTemplate,
38
+ CyclicSchemaExpandTemplate,
37
39
  DescriptionFieldTemplate: DescriptionField,
38
40
  ErrorListTemplate: ErrorList,
39
41
  FallbackFieldTemplate,
@@ -35,13 +35,13 @@ function CheckboxesWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
35
35
 
36
36
  const handleBlur = useCallback(
37
37
  ({ target }: FocusEvent<HTMLInputElement>) =>
38
- onBlur(id, enumOptionValueDecoder<S>(target && target.value, enumOptions, optionValueFormat, emptyValue)),
38
+ onBlur(id, enumOptionValueDecoder<S>(target?.value, enumOptions, optionValueFormat, emptyValue)),
39
39
  [onBlur, id, enumOptions, emptyValue, optionValueFormat],
40
40
  );
41
41
 
42
42
  const handleFocus = useCallback(
43
43
  ({ target }: FocusEvent<HTMLInputElement>) =>
44
- onFocus(id, enumOptionValueDecoder<S>(target && target.value, enumOptions, optionValueFormat, emptyValue)),
44
+ onFocus(id, enumOptionValueDecoder<S>(target?.value, enumOptions, optionValueFormat, emptyValue)),
45
45
  [onFocus, id, enumOptions, emptyValue, optionValueFormat],
46
46
  );
47
47
 
@@ -33,13 +33,13 @@ function RadioWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends
33
33
 
34
34
  const handleBlur = useCallback(
35
35
  ({ target }: FocusEvent<HTMLInputElement>) =>
36
- onBlur(id, enumOptionValueDecoder<S>(target && target.value, enumOptions, optionValueFormat, emptyValue)),
36
+ onBlur(id, enumOptionValueDecoder<S>(target?.value, enumOptions, optionValueFormat, emptyValue)),
37
37
  [onBlur, enumOptions, emptyValue, id, optionValueFormat],
38
38
  );
39
39
 
40
40
  const handleFocus = useCallback(
41
41
  ({ target }: FocusEvent<HTMLInputElement>) =>
42
- onFocus(id, enumOptionValueDecoder<S>(target && target.value, enumOptions, optionValueFormat, emptyValue)),
42
+ onFocus(id, enumOptionValueDecoder<S>(target?.value, enumOptions, optionValueFormat, emptyValue)),
43
43
  [onFocus, enumOptions, emptyValue, id, optionValueFormat],
44
44
  );
45
45
 
@@ -7,6 +7,8 @@ import {
7
7
  enumOptionValueDecoder,
8
8
  enumOptionValueEncoder,
9
9
  getOptionValueFormat,
10
+ logUnsupportedDefaultForEnum,
11
+ SelectedOptionDescription,
10
12
  } from '@rjsf/utils';
11
13
 
12
14
  function getValue(event: SyntheticEvent<HTMLSelectElement>, multiple: boolean) {
@@ -39,6 +41,8 @@ function SelectWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extend
39
41
  onFocus,
40
42
  placeholder,
41
43
  htmlName,
44
+ registry,
45
+ uiSchema,
42
46
  }: WidgetProps<T, S, F>) {
43
47
  const { enumOptions, enumDisabled, emptyValue: optEmptyVal } = options;
44
48
  const emptyValue = multiple ? [] : '';
@@ -70,38 +74,49 @@ function SelectWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extend
70
74
 
71
75
  const selectValue = enumOptionSelectedValue<S>(value, enumOptions, multiple, optionValueFormat, emptyValue);
72
76
  const showPlaceholderOption = !multiple && schema.default === undefined;
77
+ logUnsupportedDefaultForEnum<S>(id, schema, enumOptions, multiple);
73
78
 
74
79
  return (
75
- // oxlint-disable-next-line jsx-a11y/no-autofocus
76
- <select
77
- id={id}
78
- name={htmlName || id}
79
- multiple={multiple}
80
- className='form-control'
81
- value={selectValue}
82
- required={required}
83
- disabled={disabled || readonly}
84
- autoFocus={autofocus}
85
- onBlur={handleBlur}
86
- onFocus={handleFocus}
87
- onChange={handleChange}
88
- aria-describedby={ariaDescribedByIds(id)}
89
- >
90
- {showPlaceholderOption && <option value=''>{placeholder}</option>}
91
- {Array.isArray(enumOptions) &&
92
- enumOptions.map(({ value: enumValue, label: enumLabel }, i) => {
93
- const isDisabled = enumDisabled && enumDisabled.includes(enumValue);
94
- return (
95
- <option
96
- key={String(enumValue)}
97
- value={enumOptionValueEncoder(enumValue, i, optionValueFormat)}
98
- disabled={isDisabled}
99
- >
100
- {enumLabel}
101
- </option>
102
- );
103
- })}
104
- </select>
80
+ <>
81
+ <SelectedOptionDescription
82
+ id={id}
83
+ multiple={multiple}
84
+ options={options}
85
+ registry={registry}
86
+ uiSchema={uiSchema}
87
+ value={value}
88
+ />
89
+ {/* oxlint-disable-next-line jsx-a11y/no-autofocus */}
90
+ <select
91
+ id={id}
92
+ name={htmlName || id}
93
+ multiple={multiple}
94
+ className='form-control'
95
+ value={selectValue}
96
+ required={required}
97
+ disabled={disabled || readonly}
98
+ autoFocus={autofocus}
99
+ onBlur={handleBlur}
100
+ onFocus={handleFocus}
101
+ onChange={handleChange}
102
+ aria-describedby={ariaDescribedByIds(id)}
103
+ >
104
+ {showPlaceholderOption && <option value=''>{placeholder}</option>}
105
+ {Array.isArray(enumOptions) &&
106
+ enumOptions.map(({ value: enumValue, label: enumLabel }, i) => {
107
+ const isDisabled = enumDisabled && enumDisabled.includes(enumValue);
108
+ return (
109
+ <option
110
+ key={String(enumValue)}
111
+ value={enumOptionValueEncoder(enumValue, i, optionValueFormat)}
112
+ disabled={isDisabled}
113
+ >
114
+ {enumLabel}
115
+ </option>
116
+ );
117
+ })}
118
+ </select>
119
+ </>
105
120
  );
106
121
  }
107
122
 
@@ -9,7 +9,7 @@ import { ariaDescribedByIds } from '@rjsf/utils';
9
9
  */
10
10
  function TextareaWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>({
11
11
  id,
12
- options = {},
12
+ options,
13
13
  placeholder,
14
14
  value,
15
15
  required,
@@ -28,12 +28,12 @@ function TextareaWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F exte
28
28
  );
29
29
 
30
30
  const handleBlur = useCallback(
31
- ({ target }: FocusEvent<HTMLTextAreaElement>) => onBlur(id, target && target.value),
31
+ ({ target }: FocusEvent<HTMLTextAreaElement>) => onBlur(id, target?.value),
32
32
  [onBlur, id],
33
33
  );
34
34
 
35
35
  const handleFocus = useCallback(
36
- ({ target }: FocusEvent<HTMLTextAreaElement>) => onFocus(id, target && target.value),
36
+ ({ target }: FocusEvent<HTMLTextAreaElement>) => onFocus(id, target?.value),
37
37
  [id, onFocus],
38
38
  );
39
39