Skip to content

Commit 7327400

Browse files
committed
Add examples to demo
- resolveProps multiple solutions - custom layout components - resolveProps stored in DB
1 parent 00d2afe commit 7327400

File tree

8 files changed

+263
-4
lines changed

8 files changed

+263
-4
lines changed

packages/react-renderer-demo/src/components/navigation/schemas/custom-examples.schema.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
const customExamplesSchema = [
2-
{
3-
component: 'sample-example',
4-
linkText: 'Sample example'
5-
},
62
{
73
component: 'mui-one-row-layout',
84
linkText: 'MUI one row layout'
5+
},
6+
{
7+
component: 'custom-layout-component',
8+
linkText: 'Custom layout component'
9+
},
10+
{
11+
component: 'resolve-props-example',
12+
linkText: 'Resolving props according to different field'
13+
},
14+
{
15+
component: 'resolve-props-db',
16+
linkText: 'ResolveProps stored in DB'
917
}
1018
];
1119

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from 'react';
2+
import FormRenderer from '@data-driven-forms/react-form-renderer/form-renderer';
3+
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
4+
import FormTemplate from '@data-driven-forms/mui-component-mapper/form-template';
5+
import TextField from '@data-driven-forms/mui-component-mapper/text-field';
6+
import useFormApi from '@data-driven-forms/react-form-renderer/use-form-api';
7+
8+
import Grid from '@material-ui/core/Grid';
9+
10+
const TwoColumns = ({ fields }) => {
11+
const { renderForm } = useFormApi();
12+
13+
return (
14+
<Grid container spacing={3}>
15+
{
16+
fields.map(field => (
17+
<Grid key={field.name} item xs={6}>
18+
{renderForm([field])}
19+
</Grid>
20+
))
21+
}
22+
</Grid>
23+
);
24+
};
25+
26+
const schema = {
27+
fields: [{
28+
name: 'layout',
29+
component: 'two-columns',
30+
fields: [{
31+
name: 'first-name',
32+
label: 'First name',
33+
component: componentTypes.TEXT_FIELD,
34+
},
35+
{
36+
name: 'last-name',
37+
label: 'Last name',
38+
component: componentTypes.TEXT_FIELD,
39+
},
40+
{
41+
name: 'address-1',
42+
label: 'Address 1',
43+
component: componentTypes.TEXT_FIELD,
44+
},
45+
{
46+
name: 'address-2',
47+
label: 'Address 2',
48+
component: componentTypes.TEXT_FIELD,
49+
}]
50+
}]
51+
};
52+
53+
const componentMapper = {
54+
[componentTypes.TEXT_FIELD]: TextField,
55+
'two-columns': TwoColumns,
56+
};
57+
58+
const CustomLayoutComponent = () =>
59+
<FormRenderer
60+
FormTemplate={FormTemplate}
61+
componentMapper={componentMapper}
62+
schema={schema}
63+
onSubmit={console.log}
64+
/>;
65+
66+
export default CustomLayoutComponent;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React from 'react';
2+
import FormRenderer from '@data-driven-forms/react-form-renderer/form-renderer';
3+
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
4+
import FormTemplate from '@data-driven-forms/mui-component-mapper/form-template';
5+
import TextField from '@data-driven-forms/mui-component-mapper/text-field';
6+
import Checkbox from '@data-driven-forms/mui-component-mapper/checkbox';
7+
8+
const isEnabled = () => (_props, _field, formOptions) =>
9+
formOptions.getState().values.custom_email
10+
? {isDisabled: false}
11+
: {isDisabled: true};
12+
13+
const actionMapper = {
14+
isEnabled
15+
};
16+
17+
const schema = {
18+
fields: [{
19+
name: 'custom_email',
20+
label: 'Use custom email',
21+
component: 'checkbox',
22+
},
23+
{
24+
name: 'email',
25+
label: 'Email',
26+
component: 'text-field',
27+
actions: {
28+
resolveProps: ['isEnabled']
29+
}
30+
}]
31+
};
32+
33+
const componentMapper = {
34+
[componentTypes.CHECKBOX]: Checkbox,
35+
[componentTypes.TEXT_FIELD]: TextField,
36+
};
37+
38+
const ResolvePropsDb = () =>
39+
<FormRenderer
40+
FormTemplate={FormTemplate}
41+
componentMapper={componentMapper}
42+
schema={schema}
43+
onSubmit={console.log}
44+
subscription={{ values: true }}
45+
actionMapper={actionMapper}
46+
/>;
47+
48+
export default ResolvePropsDb;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import FormRenderer from '@data-driven-forms/react-form-renderer/form-renderer';
3+
import FormSpy from '@data-driven-forms/react-form-renderer/form-spy';
4+
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
5+
import FormTemplate from '@data-driven-forms/mui-component-mapper/form-template';
6+
import TextField from '@data-driven-forms/mui-component-mapper/text-field';
7+
import Checkbox from '@data-driven-forms/mui-component-mapper/checkbox';
8+
9+
const TextFieldWrapped = (props) => <FormSpy subscription={{values: true}}>
10+
{() => <TextField {...props} />}
11+
</FormSpy>;
12+
13+
const schema = {
14+
fields: [{
15+
name: 'custom_email',
16+
label: 'Use custom email',
17+
component: componentTypes.CHECKBOX,
18+
},
19+
{
20+
name: 'email',
21+
label: 'Email',
22+
component: 'text-field-wrapper',
23+
resolveProps: (_props, _field, formOptions) =>
24+
formOptions.getState().values.custom_email
25+
? {isDisabled: false}
26+
: {isDisabled: true}
27+
}]
28+
};
29+
30+
const componentMapper = {
31+
[componentTypes.CHECKBOX]: Checkbox,
32+
'text-field-wrapper': TextFieldWrapped,
33+
};
34+
35+
const ResolvePropsFormSpy = () =>
36+
<FormRenderer
37+
FormTemplate={FormTemplate}
38+
componentMapper={componentMapper}
39+
schema={schema}
40+
onSubmit={console.log}
41+
/>;
42+
43+
export default ResolvePropsFormSpy;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import FormRenderer from '@data-driven-forms/react-form-renderer/form-renderer';
3+
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
4+
import FormTemplate from '@data-driven-forms/mui-component-mapper/form-template';
5+
import TextField from '@data-driven-forms/mui-component-mapper/text-field';
6+
import Checkbox from '@data-driven-forms/mui-component-mapper/checkbox';
7+
8+
const schema = {
9+
fields: [{
10+
name: 'custom_email',
11+
label: 'Use custom email',
12+
component: componentTypes.CHECKBOX,
13+
},
14+
{
15+
name: 'email',
16+
label: 'Email',
17+
component: componentTypes.TEXT_FIELD,
18+
resolveProps: (_props, _field, formOptions) =>
19+
formOptions.getState().values.custom_email
20+
? {isDisabled: false}
21+
: {isDisabled: true}
22+
}]
23+
};
24+
25+
const componentMapper = {
26+
[componentTypes.CHECKBOX]: Checkbox,
27+
[componentTypes.TEXT_FIELD]: TextField,
28+
};
29+
30+
const ResolvePropsSubscription = () =>
31+
<FormRenderer
32+
FormTemplate={FormTemplate}
33+
componentMapper={componentMapper}
34+
schema={schema}
35+
onSubmit={console.log}
36+
subscription={{ values: true }}
37+
/>;
38+
39+
export default ResolvePropsSubscription;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import DocPage from '@docs/doc-page';
2+
import CodeExample from '@docs/code-example';
3+
4+
<DocPage>
5+
6+
# Custom layout component
7+
8+
Writing layout components is simple. The only thing you need to use is [renderForm](/hooks/use-form-api#renderform) to render nested fields.
9+
10+
In this example we will implement two columns layout, that is using Material Grid component, but the principle is the same for all other mappers and custom design systems.
11+
12+
## Preview
13+
14+
<CodeExample source="components/examples/custom-layout-component" mode="preview" />
15+
16+
</DocPage>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import DocPage from '@docs/doc-page';
2+
import CodeExample from '@docs/code-example';
3+
4+
<DocPage>
5+
6+
# resolveProps stored in DB
7+
8+
Even the fact that [resolveProps](/schema/resolve-props) is a JavaScript function does not prevent storing it in a database that does not allow to store code. You can simply store it as an [action](/mappers/action-mapper).
9+
10+
## Preview
11+
12+
<CodeExample source="components/examples/resolve-props-db" mode="preview" />
13+
14+
</DocPage>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import DocPage from '@docs/doc-page';
2+
import CodeExample from '@docs/code-example';
3+
4+
<DocPage>
5+
6+
# Resolving props according to different field
7+
8+
[resolveProps](/schema/resolve-props) is a powerful tool for changing props run-time. In this example, we will present how to change props according to a value of different field.
9+
10+
To achieve that you need to rerender the changing field on each form change. That can be done via two ways:
11+
12+
## Subscription example
13+
14+
Using [subscription](/components/renderer#optionalprops) is a simple way how to let form to be rerendered each time values changed. However, this solution can bring a performance hit when used in large forms with tens of fields.
15+
16+
<CodeExample source="components/examples/resolve-props-subscription" mode="preview" />
17+
18+
## Wrap the component in FormSpy
19+
20+
You can wrap the changing field in [FormSpy component](/components/form-spy) to optimize the rendering. Using FormSpy the only nested fields will be rerendered.
21+
22+
<CodeExample source="components/examples/resolve-props-formspy" mode="preview" />
23+
24+
25+
</DocPage>

0 commit comments

Comments
 (0)