@rjsf/core 6.2.5 → 6.3.1
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.
- package/dist/core.umd.js +20 -6
- package/dist/index.cjs +317 -297
- package/dist/index.cjs.map +4 -4
- package/dist/index.esm.js +162 -139
- package/dist/index.esm.js.map +4 -4
- package/lib/components/Form.d.ts.map +1 -1
- package/lib/components/Form.js +7 -2
- package/lib/components/SchemaExamples.d.ts +16 -0
- package/lib/components/SchemaExamples.d.ts.map +1 -0
- package/lib/components/SchemaExamples.js +23 -0
- package/lib/components/fields/ArrayField.d.ts.map +1 -1
- package/lib/components/fields/LayoutGridField.d.ts.map +1 -1
- package/lib/components/fields/ObjectField.d.ts.map +1 -1
- package/lib/components/fields/SchemaField.d.ts.map +1 -1
- package/lib/components/fields/SchemaField.js +3 -2
- package/lib/components/templates/BaseInputTemplate.d.ts.map +1 -1
- package/lib/components/templates/BaseInputTemplate.js +2 -5
- package/lib/index.d.ts +3 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/components/Form.tsx +18 -6
- package/src/components/SchemaExamples.tsx +36 -0
- package/src/components/fields/ArrayField.tsx +10 -4
- package/src/components/fields/LayoutGridField.tsx +5 -2
- package/src/components/fields/ObjectField.tsx +5 -2
- package/src/components/fields/SchemaField.tsx +3 -1
- package/src/components/templates/BaseInputTemplate.tsx +3 -9
- package/src/index.ts +11 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rjsf/core",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.1",
|
|
4
4
|
"description": "A simple React component capable of building HTML forms out of a JSON schema.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"compileReplacer": "tsc -p tsconfig.replacer.json && move-file lodashReplacer.js lodashReplacer.cjs",
|
|
@@ -66,21 +66,21 @@
|
|
|
66
66
|
"node": ">=20"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@rjsf/utils": "^6.
|
|
69
|
+
"@rjsf/utils": "^6.3.x",
|
|
70
70
|
"react": ">=18"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"lodash": "^4.17.
|
|
74
|
-
"lodash-es": "^4.17.
|
|
73
|
+
"lodash": "^4.17.23",
|
|
74
|
+
"lodash-es": "^4.17.23",
|
|
75
75
|
"markdown-to-jsx": "^8.0.0",
|
|
76
76
|
"prop-types": "^15.8.1"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@rjsf/snapshot-tests": "
|
|
80
|
-
"@rjsf/utils": "
|
|
81
|
-
"@rjsf/validator-ajv8": "
|
|
79
|
+
"@rjsf/snapshot-tests": "6.3.1",
|
|
80
|
+
"@rjsf/utils": "6.3.1",
|
|
81
|
+
"@rjsf/validator-ajv8": "6.3.1",
|
|
82
82
|
"@testing-library/jest-dom": "^6.9.1",
|
|
83
|
-
"@testing-library/react": "^16.3.
|
|
83
|
+
"@testing-library/react": "^16.3.2",
|
|
84
84
|
"@testing-library/user-event": "^14.6.1",
|
|
85
85
|
"@types/react-portal": "^4.0.7",
|
|
86
86
|
"ajv": "^8.17.1",
|
package/src/components/Form.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
ErrorSchema,
|
|
7
7
|
ErrorSchemaBuilder,
|
|
8
8
|
ErrorTransformer,
|
|
9
|
+
expandUiSchemaDefinitions,
|
|
9
10
|
FieldPathId,
|
|
10
11
|
FieldPathList,
|
|
11
12
|
FormContextType,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
toErrorList,
|
|
29
30
|
toFieldPathId,
|
|
30
31
|
UiSchema,
|
|
32
|
+
UI_DEFINITIONS_KEY,
|
|
31
33
|
UI_GLOBAL_OPTIONS_KEY,
|
|
32
34
|
UI_OPTIONS_KEY,
|
|
33
35
|
ValidationData,
|
|
@@ -311,11 +313,14 @@ export interface FormState<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
|
|
|
311
313
|
/** The event data passed when changes have been made to the form, includes everything from the `FormState` except
|
|
312
314
|
* the schema validation errors. An additional `status` is added when returned from `onSubmit`
|
|
313
315
|
*/
|
|
314
|
-
export interface IChangeEvent<
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
316
|
+
export interface IChangeEvent<
|
|
317
|
+
T = any,
|
|
318
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
319
|
+
F extends FormContextType = any,
|
|
320
|
+
> extends Pick<
|
|
321
|
+
FormState<T, S, F>,
|
|
322
|
+
'schema' | 'uiSchema' | 'fieldPathId' | 'schemaUtils' | 'formData' | 'edit' | 'errors' | 'errorSchema'
|
|
323
|
+
> {
|
|
319
324
|
/** The status of the form when submitted */
|
|
320
325
|
status?: 'submitted';
|
|
321
326
|
}
|
|
@@ -620,6 +625,12 @@ export default class Form<
|
|
|
620
625
|
// Only store a new registry when the props cause a different one to be created
|
|
621
626
|
const newRegistry = this.getRegistry(props, rootSchema, schemaUtils);
|
|
622
627
|
const registry = deepEquals(state.registry, newRegistry) ? state.registry : newRegistry;
|
|
628
|
+
|
|
629
|
+
// Pre-expand ui:definitions into the uiSchema structure (must happen after registry is created)
|
|
630
|
+
const expandedUiSchema: UiSchema<T, S, F> = registry.uiSchemaDefinitions
|
|
631
|
+
? expandUiSchemaDefinitions<T, S, F>(rootSchema, uiSchema, registry)
|
|
632
|
+
: uiSchema;
|
|
633
|
+
|
|
623
634
|
// Only compute a new `fieldPathId` when the `idPrefix` is different than the existing fieldPathId's ID_KEY
|
|
624
635
|
const fieldPathId =
|
|
625
636
|
state.fieldPathId && state.fieldPathId?.[ID_KEY] === registry.globalFormOptions.idPrefix
|
|
@@ -628,7 +639,7 @@ export default class Form<
|
|
|
628
639
|
const nextState: FormState<T, S, F> = {
|
|
629
640
|
schemaUtils,
|
|
630
641
|
schema: rootSchema,
|
|
631
|
-
uiSchema,
|
|
642
|
+
uiSchema: expandedUiSchema,
|
|
632
643
|
fieldPathId,
|
|
633
644
|
formData,
|
|
634
645
|
edit,
|
|
@@ -1149,6 +1160,7 @@ export default class Form<
|
|
|
1149
1160
|
translateString: customTranslateString || translateString,
|
|
1150
1161
|
globalUiOptions: uiSchema[UI_GLOBAL_OPTIONS_KEY],
|
|
1151
1162
|
globalFormOptions: this.getGlobalFormOptions(props),
|
|
1163
|
+
uiSchemaDefinitions: uiSchema[UI_DEFINITIONS_KEY] ?? {},
|
|
1152
1164
|
};
|
|
1153
1165
|
}
|
|
1154
1166
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { examplesId, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
|
|
2
|
+
|
|
3
|
+
export interface SchemaExamplesProps<S extends StrictRJSFSchema = RJSFSchema> {
|
|
4
|
+
/** The id of the input element this datalist is for */
|
|
5
|
+
id: string;
|
|
6
|
+
/** The JSON schema object containing examples and default value */
|
|
7
|
+
schema: S;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Renders a `<datalist>` element containing options from schema examples and default value.
|
|
11
|
+
* Normalizes types to prevent duplicate keys when examples and default have different types.
|
|
12
|
+
* For example, if examples are strings ["5432"] and default is number 5432, the default
|
|
13
|
+
* will not be added as a duplicate option.
|
|
14
|
+
*
|
|
15
|
+
* @param props - The `SchemaExamplesProps` for this component
|
|
16
|
+
*/
|
|
17
|
+
export default function SchemaExamples<S extends StrictRJSFSchema = RJSFSchema>(props: SchemaExamplesProps<S>) {
|
|
18
|
+
const { id, schema } = props;
|
|
19
|
+
const { examples, default: schemaDefault } = schema;
|
|
20
|
+
if (!Array.isArray(examples)) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return (
|
|
24
|
+
<datalist key={`datalist_${id}`} id={examplesId(id)}>
|
|
25
|
+
{(examples as string[])
|
|
26
|
+
.concat(
|
|
27
|
+
schemaDefault !== undefined && !examples.map(String).includes(String(schemaDefault))
|
|
28
|
+
? ([schemaDefault] as string[])
|
|
29
|
+
: [],
|
|
30
|
+
)
|
|
31
|
+
.map((example: any) => {
|
|
32
|
+
return <option key={String(example)} value={example} />;
|
|
33
|
+
})}
|
|
34
|
+
</datalist>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
@@ -166,8 +166,11 @@ function getNewFormDataRow<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
/** Props used for ArrayAsXxxx type components*/
|
|
169
|
-
interface ArrayAsFieldProps<
|
|
170
|
-
|
|
169
|
+
interface ArrayAsFieldProps<
|
|
170
|
+
T = any,
|
|
171
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
172
|
+
F extends FormContextType = any,
|
|
173
|
+
> extends FieldProps<T, S, F> {
|
|
171
174
|
/** The callback used to update the array when the selector changes */
|
|
172
175
|
onSelectChange: (value: T) => void;
|
|
173
176
|
}
|
|
@@ -522,8 +525,11 @@ function ArrayFieldItem<T = any, S extends StrictRJSFSchema = RJSFSchema, F exte
|
|
|
522
525
|
}
|
|
523
526
|
|
|
524
527
|
/** The properties required by the stateless components that render the items using the `ArrayFieldItem` */
|
|
525
|
-
interface InternalArrayFieldProps<
|
|
526
|
-
|
|
528
|
+
interface InternalArrayFieldProps<
|
|
529
|
+
T = any,
|
|
530
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
531
|
+
F extends FormContextType = any,
|
|
532
|
+
> extends FieldProps<T[], S, F> {
|
|
527
533
|
/** The keyedFormData from the `ArrayField` state */
|
|
528
534
|
keyedFormData: KeyedFormDataType<T>[];
|
|
529
535
|
/** The callback used to handle the adding of an item at the given index (or the end, if missing) */
|
|
@@ -83,8 +83,11 @@ export type GridSchemaType = {
|
|
|
83
83
|
*/
|
|
84
84
|
export type LayoutGridSchemaType = GridSchemaType | ConfigObject | string;
|
|
85
85
|
|
|
86
|
-
export interface LayoutGridFieldProps<
|
|
87
|
-
|
|
86
|
+
export interface LayoutGridFieldProps<
|
|
87
|
+
T = any,
|
|
88
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
89
|
+
F extends FormContextType = any,
|
|
90
|
+
> extends FieldProps<T, S, F> {
|
|
88
91
|
/** Optional string or object used to describe the current level of the `LayoutGridField`
|
|
89
92
|
*/
|
|
90
93
|
layoutGridSchema?: LayoutGridSchemaType;
|
|
@@ -69,8 +69,11 @@ function getDefaultValue<T = any, S extends StrictRJSFSchema = RJSFSchema, F ext
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/** Props for the `ObjectFieldProperty` component */
|
|
72
|
-
interface ObjectFieldPropertyProps<
|
|
73
|
-
|
|
72
|
+
interface ObjectFieldPropertyProps<
|
|
73
|
+
T = any,
|
|
74
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
75
|
+
F extends FormContextType = any,
|
|
76
|
+
> extends Omit<FieldProps<T, S, F>, 'name'> {
|
|
74
77
|
/** The name of the property within the parent object */
|
|
75
78
|
propertyName: string;
|
|
76
79
|
/** Flag indicating whether this property was added by the additionalProperties UI */
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
isFormDataAvailable,
|
|
18
18
|
ONE_OF_KEY,
|
|
19
19
|
Registry,
|
|
20
|
+
resolveUiSchema,
|
|
20
21
|
RJSFSchema,
|
|
21
22
|
shouldRender,
|
|
22
23
|
shouldRenderOptionalField,
|
|
@@ -93,7 +94,7 @@ function SchemaFieldRender<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
|
|
|
93
94
|
const {
|
|
94
95
|
schema: _schema,
|
|
95
96
|
fieldPathId,
|
|
96
|
-
uiSchema,
|
|
97
|
+
uiSchema: _uiSchema,
|
|
97
98
|
formData,
|
|
98
99
|
errorSchema,
|
|
99
100
|
name,
|
|
@@ -107,6 +108,7 @@ function SchemaFieldRender<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
|
|
|
107
108
|
} = props;
|
|
108
109
|
const { schemaUtils, globalFormOptions, globalUiOptions, fields } = registry;
|
|
109
110
|
const { AnyOfField: _AnyOfField, OneOfField: _OneOfField } = fields;
|
|
111
|
+
const uiSchema = resolveUiSchema<T, S, F>(_schema, _uiSchema, registry);
|
|
110
112
|
const uiOptions = getUiOptions<T, S, F>(uiSchema, globalUiOptions);
|
|
111
113
|
const FieldTemplate = getTemplate<'FieldTemplate', T, S, F>('FieldTemplate', registry, uiOptions);
|
|
112
114
|
const DescriptionFieldTemplate = getTemplate<'DescriptionFieldTemplate', T, S, F>(
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
StrictRJSFSchema,
|
|
10
10
|
} from '@rjsf/utils';
|
|
11
11
|
|
|
12
|
+
import SchemaExamples from '../SchemaExamples';
|
|
13
|
+
|
|
12
14
|
/** The `BaseInputTemplate` is the template to use to render the basic `<input>` component for the `core` theme.
|
|
13
15
|
* It is used as the template for rendering many of the <input> based widgets that differ by `type` and callbacks only.
|
|
14
16
|
* It can be customized/overridden for other themes or individual implementations as needed.
|
|
@@ -103,15 +105,7 @@ export default function BaseInputTemplate<
|
|
|
103
105
|
{options.allowClearTextInputs && !readonly && !disabled && inputValue && (
|
|
104
106
|
<ClearButton registry={registry} onClick={_onClear} />
|
|
105
107
|
)}
|
|
106
|
-
{
|
|
107
|
-
<datalist key={`datalist_${id}`} id={examplesId(id)}>
|
|
108
|
-
{(schema.examples as string[])
|
|
109
|
-
.concat(schema.default && !schema.examples.includes(schema.default) ? ([schema.default] as string[]) : [])
|
|
110
|
-
.map((example: any) => {
|
|
111
|
-
return <option key={example} value={example} />;
|
|
112
|
-
})}
|
|
113
|
-
</datalist>
|
|
114
|
-
)}
|
|
108
|
+
<SchemaExamples id={id} schema={schema} />
|
|
115
109
|
</>
|
|
116
110
|
);
|
|
117
111
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import Form, { FormProps, FormState, IChangeEvent } from './components/Form';
|
|
2
2
|
import RichDescription, { RichDescriptionProps } from './components/RichDescription';
|
|
3
3
|
import RichHelp, { RichHelpProps } from './components/RichHelp';
|
|
4
|
+
import SchemaExamples, { SchemaExamplesProps } from './components/SchemaExamples';
|
|
4
5
|
import withTheme, { ThemeProps } from './withTheme';
|
|
5
6
|
import getDefaultRegistry from './getDefaultRegistry';
|
|
6
7
|
import getTestRegistry from './getTestRegistry';
|
|
7
8
|
|
|
8
|
-
export type {
|
|
9
|
+
export type {
|
|
10
|
+
FormProps,
|
|
11
|
+
FormState,
|
|
12
|
+
IChangeEvent,
|
|
13
|
+
ThemeProps,
|
|
14
|
+
RichDescriptionProps,
|
|
15
|
+
RichHelpProps,
|
|
16
|
+
SchemaExamplesProps,
|
|
17
|
+
};
|
|
9
18
|
|
|
10
|
-
export { withTheme, getDefaultRegistry, getTestRegistry, RichDescription, RichHelp };
|
|
19
|
+
export { withTheme, getDefaultRegistry, getTestRegistry, RichDescription, RichHelp, SchemaExamples };
|
|
11
20
|
export default Form;
|