Skip to content

Commit 80d556f

Browse files
author
Rani
authored
Merge branch 'main' into fix-additional-property-key
2 parents f28d61f + 7f79f2c commit 80d556f

File tree

28 files changed

+2056
-88
lines changed

28 files changed

+2056
-88
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ jobs:
2828
run: npm run build
2929
env:
3030
SHOW_NETLIFY_BADGE: true
31+
NODE_OPTIONS: --max_old_space_size=4096
3132
- name: Build
3233
if: github.ref == 'refs/heads/main'
3334
run: npm run build
35+
env:
36+
NODE_OPTIONS: --max_old_space_size=4096
3437

3538
- if: matrix.node-version == '16.x'
3639
uses: actions/upload-artifact@v3

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ it according to semantic versioning. For example, if your PR adds a breaking cha
1515
should change the heading of the (upcoming) version to include a major version bump.
1616
1717
-->
18+
# v5.0.0-beta.7
19+
20+
## @rjsf/core
21+
- Added new field `ArraySchemaField`, assigned to `SchemaField` by default, that is used by the `ArrayField` to render the `children` for each array field element
22+
- Refactored the internal `ErrorList` and `Help` components from inside of `SchemaField` to new templates: `FieldErrorTemplate` and `FieldHelpTemplate`; fixes (https://github.com/rjsf-team/react-jsonschema-form/issues/3104)
23+
24+
## @rjsf/utils
25+
- Added new `FieldErrorProps` and `FieldHelpProps` types
26+
- Added new `FieldErrorTemplate` and `FieldHelpTemplate` to the `TemplatesType`
27+
28+
## Dev / docs / playground
29+
- Updated the `custom-templates.md` file to add documentation for the new `FieldErrorTemplate` and `FieldHelpTemplate`
30+
- Updated the `custom-widgets-fields.md` file to add documentation for the new `ArraySchemaField` field.
31+
1832
# v5.0.0-beta.6
1933

2034
## @rjsf/bootstrap-4

docs/advanced-customization/custom-templates.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ Below is the table that lists all the `templates`, their props interface, their
2828
| [BaseInputTemplate*](#BaseInputTemplate) | WidgetProps | ui:BaseInputTemplate | Formerly a `widget` in `@rjsf.core` moved to `templates` and newly implemented in each theme to maximize code reuse. |
2929
| [DescriptionFieldTemplate*](#DescriptionFieldTemplate) | DescriptionFieldProps | ui:DescriptionFieldTemplate | Formerly a `field` in `@rjsf.core` moved to `templates` with the `Template` suffix. Previously implemented in each theme. |
3030
| [ErrorListTemplate*](#ErrorListTemplate) | ErrorListProps | ui:ErrorListTemplate | Formerly `Form.ErrorList` moved to `templates` with the `Templates` suffix. Previously implemented in each theme. |
31+
| [FieldErrorTemplate](#FieldErrorTemplate) | FieldErrorProps | ui:FieldErrorTemplate | Formerly internal `ErrorList` component accessible only to `SchemaField` |
32+
| [FieldHelpTemplate](#FieldHelpTemplate) | FieldHelpProps | ui:FieldHelpTemplate | Formerly internal `Help` component accessible only to `SchemaField` |
3133
| [FieldTemplate](#FieldTemplate) | FieldTemplateProps | ui:FieldTemplate | Formerly `Form.FieldTemplate` or `Registry.FieldTemplate` |
3234
| [ObjectFieldTemplate](#ObjectFieldTemplate) | ObjectFieldTemplateProps | ui:ObjectFieldTemplate | Formerly `Form.ObjectFieldTemplate` or `Registry.ObjectFieldTemplate` |
3335
| [TitleFieldTemplate*](#TitleFieldTemplate) | TitleFieldProps | ui:TitleFieldTemplate | Formerly a `field` in `@rjsf.core` moved to `templates` with the `Template` suffix. Previously implemented in each theme. |
@@ -449,6 +451,85 @@ The following props are passed to the `ErrorListTemplate`:
449451
- `errors`: An array of all errors in this `Form`.
450452
- `errorSchema`: The `ErrorSchema` constructed by `Form`
451453

454+
## FieldErrorTemplate
455+
The `FieldErrorTemplate` is the template that renders all the errors associated a single field.
456+
If you want to customize how the errors are rendered you can.
457+
458+
```tsx
459+
import { FieldErrorProps } from "@rjsf/utils";
460+
import validator from '@rjsf/validator-ajv6';
461+
462+
const schema = {
463+
type: "string",
464+
title: "My input",
465+
description: "input description"
466+
};
467+
468+
function FieldErrorTemplate(props: FieldErrorProps) {
469+
const { errors } = props;
470+
return (
471+
<details id={id}>
472+
<summary>Errors</summary>
473+
<ul>
474+
{errors.map((error: string, i: number) => {
475+
return (
476+
<li key={i} className="error">
477+
{error.stack}
478+
</li>
479+
);
480+
})}
481+
</ul>
482+
</details>
483+
);
484+
}
485+
486+
render((
487+
<Form schema={schema} validator={validator} templates={{ FieldErrorTemplate }} />
488+
), document.getElementById("app"));
489+
```
490+
491+
The following props are passed to the `FieldErrorTemplate`:
492+
493+
- `schema`: The schema for the field
494+
- `uiSchema`: The uiSchema for the field
495+
- `idSchema`: An object containing the id for this field & ids for its properties.
496+
- `errors`: An array of all errors for this field
497+
- `errorSchema`: The `ErrorSchema` for this field
498+
- `registry`: The `Registry` object
499+
500+
## FieldHelpTemplate
501+
The `FieldHelpTemplate` is the template that renders the help associated a single field.
502+
If you want to customize how the help is rendered you can.
503+
504+
```tsx
505+
import { FieldHelpProps } from "@rjsf/utils";
506+
import validator from '@rjsf/validator-ajv6';
507+
508+
const schema = {
509+
type: "string",
510+
title: "My input",
511+
description: "input description"
512+
};
513+
514+
function FieldHelpTemplate(props: FieldHelpProps) {
515+
const { help, idSchema } = props;
516+
const id = `${idSchema.$id}__help`;
517+
return <aside id={id}>{help}</aside>;
518+
}
519+
520+
render((
521+
<Form schema={schema} validator={validator} templates={{ FieldHelpTemplate }} />
522+
), document.getElementById("app"));
523+
```
524+
525+
The following props are passed to the `FieldHelpTemplate`:
526+
527+
- `schema`: The schema for the field
528+
- `uiSchema`: The uiSchema for the field
529+
- `idSchema`: An object containing the id for this field & ids for its properties.
530+
- `help`: The help information to be rendered
531+
- `registry`: The `Registry` object
532+
452533
## FieldTemplate
453534

454535
To take control over the inner organization of each field (each form row), you can define a *field template* for your form.

docs/advanced-customization/custom-widgets-fields.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ function MyForm(props) {
5252
The default fields you can override are:
5353

5454
- `ArrayField`
55+
- `ArraySchemaField`
5556
- `BooleanField`
5657
- `DescriptionField`
5758
- `OneOfField`
@@ -351,3 +352,32 @@ render((
351352
If you're curious how this could ever be useful, have a look at the [Kinto formbuilder](https://github.com/Kinto/formbuilder) repository to see how it's used to provide editing capabilities to any form field.
352353

353354
Props passed to a custom SchemaField are the same as [the ones passed to a custom field](#field-props).
355+
356+
### Custom ArraySchemaField
357+
358+
Everything that was mentioned above for a `Custom SchemaField` applies, but this is only used to render the Array item `children` that are then passed to the `ArrayFieldItemTemplate`.
359+
By default, `ArraySchemaField` uses the main `SchemaField` implementation.
360+
If you want to customize how the individual items for an array are rendered, override the `ArraySchemaField`.
361+
362+
```jsx
363+
import validator from '@rjsf/validator-ajv6';
364+
365+
const CustomArraySchemaField = function(props) {
366+
const { index, registry } = props;
367+
const { SchemaField } = registry.fields;
368+
const name = `Index ${index}`;
369+
return <SchemaField {...props} name={name} />;
370+
};
371+
372+
const fields = {
373+
ArraySchemaField: CustomArraySchemaField
374+
};
375+
376+
const schema = {
377+
type: "string"
378+
};
379+
380+
render((
381+
<Form schema={schema} validator={validator} fields={fields} />
382+
), document.getElementById("app"));
383+
```

packages/antd/test/Form.test.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,27 @@ describe("single fields", () => {
367367
examples: ["Firefox", "Chrome", "Opera", "Vivaldi", "Safari"],
368368
};
369369
const tree = renderer
370-
.create(<Form schema={schema} validator={validator} tagName="div" />)
370+
.create(<Form schema={schema} validator={validator} />)
371+
.toJSON();
372+
expect(tree).toMatchSnapshot();
373+
});
374+
test("help and error display", () => {
375+
const schema = {
376+
type: "string",
377+
};
378+
const uiSchema = {
379+
"ui:help": "help me!",
380+
};
381+
const extraErrors = { __errors: ["an error"] };
382+
const tree = renderer
383+
.create(
384+
<Form
385+
schema={schema}
386+
uiSchema={uiSchema}
387+
validator={validator}
388+
extraErrors={extraErrors}
389+
/>
390+
)
371391
.toJSON();
372392
expect(tree).toMatchSnapshot();
373393
});

packages/antd/test/__snapshots__/Form.test.js.snap

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,124 @@ exports[`single fields format datetime 1`] = `
705705
</form>
706706
`;
707707

708+
exports[`single fields help and error display 1`] = `
709+
<form
710+
className="rjsf"
711+
noValidate={false}
712+
onSubmit={[Function]}
713+
>
714+
<div
715+
className="ant-alert ant-alert-error ant-alert-with-description ant-alert-no-icon panel panel-danger errors"
716+
data-show={true}
717+
role="alert"
718+
style={Object {}}
719+
>
720+
<div
721+
className="ant-alert-content"
722+
>
723+
<div
724+
className="ant-alert-message"
725+
>
726+
Errors
727+
</div>
728+
<div
729+
className="ant-alert-description"
730+
>
731+
<div
732+
className="ant-list ant-list-sm ant-list-split list-group"
733+
>
734+
<div
735+
className="ant-spin-nested-loading"
736+
>
737+
<div
738+
className="ant-spin-container"
739+
>
740+
<li
741+
className="ant-list-item"
742+
>
743+
<div
744+
className="ant-space ant-space-horizontal ant-space-align-center"
745+
style={Object {}}
746+
>
747+
<div
748+
className="ant-space-item"
749+
style={
750+
Object {
751+
"marginRight": 8,
752+
}
753+
}
754+
>
755+
<span
756+
aria-label="exclamation-circle"
757+
className="anticon anticon-exclamation-circle"
758+
role="img"
759+
>
760+
<svg
761+
aria-hidden="true"
762+
data-icon="exclamation-circle"
763+
fill="currentColor"
764+
focusable="false"
765+
height="1em"
766+
viewBox="64 64 896 896"
767+
width="1em"
768+
>
769+
<path
770+
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
771+
/>
772+
<path
773+
d="M464 688a48 48 0 1096 0 48 48 0 10-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z"
774+
/>
775+
</svg>
776+
</span>
777+
</div>
778+
<div
779+
className="ant-space-item"
780+
style={Object {}}
781+
>
782+
. an error
783+
</div>
784+
</div>
785+
</li>
786+
</div>
787+
</div>
788+
</div>
789+
</div>
790+
</div>
791+
</div>
792+
<div
793+
className="form-group field field-string field-error has-error has-danger"
794+
>
795+
<input
796+
className="ant-input"
797+
id="root"
798+
name="root"
799+
onBlur={[Function]}
800+
onChange={[Function]}
801+
onFocus={[Function]}
802+
onKeyDown={[Function]}
803+
placeholder=""
804+
style={
805+
Object {
806+
"width": "100%",
807+
}
808+
}
809+
type="text"
810+
value=""
811+
/>
812+
</div>
813+
<button
814+
className="ant-btn ant-btn-submit"
815+
disabled={false}
816+
onClick={[Function]}
817+
type="submit"
818+
>
819+
<span>
820+
Submit
821+
</span>
822+
</button>
823+
</form>
824+
`;
825+
708826
exports[`single fields hidden field 1`] = `
709827
<form
710828
className="rjsf"
@@ -1213,7 +1331,7 @@ exports[`single fields radio field 1`] = `
12131331
`;
12141332

12151333
exports[`single fields schema examples 1`] = `
1216-
<div
1334+
<form
12171335
className="rjsf"
12181336
noValidate={false}
12191337
onSubmit={[Function]}
@@ -1269,7 +1387,7 @@ exports[`single fields schema examples 1`] = `
12691387
Submit
12701388
</span>
12711389
</button>
1272-
</div>
1390+
</form>
12731391
`;
12741392

12751393
exports[`single fields select field 1`] = `

packages/bootstrap-4/test/Form.test.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import { RJSFSchema, UiSchema } from "@rjsf/utils";
2+
import { RJSFSchema, UiSchema, ErrorSchema } from "@rjsf/utils";
33
import validator from "@rjsf/validator-ajv6";
44
import renderer from "react-test-renderer";
55

@@ -365,7 +365,27 @@ describe("single fields", () => {
365365
examples: ["Firefox", "Chrome", "Opera", "Vivaldi", "Safari"],
366366
};
367367
const tree = renderer
368-
.create(<Form schema={schema} validator={validator} tagName="div" />)
368+
.create(<Form schema={schema} validator={validator} />)
369+
.toJSON();
370+
expect(tree).toMatchSnapshot();
371+
});
372+
test("help and error display", () => {
373+
const schema: RJSFSchema = {
374+
type: "string",
375+
};
376+
const uiSchema: UiSchema = {
377+
"ui:help": "help me!",
378+
};
379+
const extraErrors: ErrorSchema = { __errors: ["an error"] } as ErrorSchema;
380+
const tree = renderer
381+
.create(
382+
<Form
383+
schema={schema}
384+
uiSchema={uiSchema}
385+
validator={validator}
386+
extraErrors={extraErrors}
387+
/>
388+
)
369389
.toJSON();
370390
expect(tree).toMatchSnapshot();
371391
});

0 commit comments

Comments
 (0)