Skip to content

Commit 1c1210b

Browse files
committed
feat(mui): add form error alert
1 parent de12613 commit 1c1210b

File tree

2 files changed

+134
-2
lines changed

2 files changed

+134
-2
lines changed

packages/mui-component-mapper/src/form-template/form-template.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import { Grid, Button as MUIButton, Typography } from '@material-ui/core';
44
import { makeStyles } from '@material-ui/core/styles';
5+
import Alert from '@material-ui/lab/Alert';
6+
import AlertTitle from '@material-ui/lab/AlertTitle';
57

68
import FormTemplate from '@data-driven-forms/common/form-template';
9+
import clsx from 'clsx';
710

811
const useStyles = makeStyles(() => ({
912
buttonGroup: {
@@ -86,8 +89,53 @@ Button.propTypes = {
8689
buttonType: PropTypes.string
8790
};
8891

92+
const useAlertStyles = makeStyles(() => ({
93+
alert: {
94+
width: '100%',
95+
margin: 8
96+
}
97+
}));
98+
99+
export const FormError = ({ formError, alertProps }) => {
100+
const { alert } = useAlertStyles();
101+
102+
if (typeof formError === 'object' && (formError.title || formError.title)) {
103+
const { title, description, TitleProps, className, ...props } = formError;
104+
105+
return (
106+
<Alert severity="error" {...props} {...alertProps} className={clsx(alert, alertProps?.className, className)}>
107+
{title && <AlertTitle {...TitleProps}>{title}</AlertTitle>}
108+
{description}
109+
</Alert>
110+
);
111+
}
112+
113+
if (formError) {
114+
return (
115+
<Alert severity="error" {...alertProps} className={clsx(alert, alertProps?.className)}>
116+
{formError}
117+
</Alert>
118+
);
119+
}
120+
121+
return null;
122+
};
123+
124+
FormError.propTypes = {
125+
formError: PropTypes.any,
126+
alertProps: PropTypes.object
127+
};
128+
89129
const MuiFormTemplate = (props) => (
90-
<FormTemplate FormWrapper={Form} Button={Button} ButtonGroup={ButtonGroup} Title={Title} Description={Description} {...props} />
130+
<FormTemplate
131+
BeforeError={FormError}
132+
FormWrapper={Form}
133+
Button={Button}
134+
ButtonGroup={ButtonGroup}
135+
Title={Title}
136+
Description={Description}
137+
{...props}
138+
/>
91139
);
92140

93141
export default MuiFormTemplate;

packages/mui-component-mapper/src/tests/form-template.test.js

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import React from 'react';
2-
import { FormRenderer } from '@data-driven-forms/react-form-renderer';
2+
import { act } from 'react-dom/test-utils';
3+
import { FormRenderer, FormError } from '@data-driven-forms/react-form-renderer';
34
import { mount } from 'enzyme';
45
import { Typography } from '@material-ui/core';
6+
import Alert from '@material-ui/lab/Alert';
7+
import AlertTitle from '@material-ui/lab/AlertTitle';
58

69
import { componentMapper, FormTemplate } from '../';
710

@@ -26,4 +29,85 @@ describe('<FormTemplate />', () => {
2629

2730
expect(wrapper.find(Typography).text()).toEqual('Some title');
2831
});
32+
33+
it('show form alert message', async () => {
34+
const wrapper = mount(
35+
<FormRenderer
36+
schema={{
37+
fields: [
38+
{
39+
component: 'text-field',
40+
name: 'field'
41+
}
42+
]
43+
}}
44+
validate={({ field }) => {
45+
if (field) {
46+
return { [FormError]: 'some error title' };
47+
}
48+
}}
49+
onSubmit={jest.fn()}
50+
FormTemplate={FormTemplate}
51+
componentMapper={componentMapper}
52+
/>
53+
);
54+
55+
expect(wrapper.find(Alert)).toHaveLength(0);
56+
57+
await act(async () => {
58+
wrapper
59+
.find('input')
60+
.first()
61+
.instance().value = 'cats';
62+
wrapper
63+
.find('input')
64+
.first()
65+
.simulate('change');
66+
});
67+
wrapper.update();
68+
69+
expect(wrapper.find(Alert)).toHaveLength(1);
70+
expect(wrapper.find(Alert).text()).toEqual('some error title');
71+
});
72+
73+
it('show form alert message as object', async () => {
74+
const wrapper = mount(
75+
<FormRenderer
76+
schema={{
77+
fields: [
78+
{
79+
component: 'text-field',
80+
name: 'field'
81+
}
82+
]
83+
}}
84+
validate={({ field }) => {
85+
if (field) {
86+
return { [FormError]: { title: 'some error title', description: 'some description' } };
87+
}
88+
}}
89+
onSubmit={jest.fn()}
90+
FormTemplate={FormTemplate}
91+
componentMapper={componentMapper}
92+
/>
93+
);
94+
95+
expect(wrapper.find(Alert)).toHaveLength(0);
96+
97+
await act(async () => {
98+
wrapper
99+
.find('input')
100+
.first()
101+
.instance().value = 'cats';
102+
wrapper
103+
.find('input')
104+
.first()
105+
.simulate('change');
106+
});
107+
wrapper.update();
108+
109+
expect(wrapper.find(Alert)).toHaveLength(1);
110+
expect(wrapper.find(AlertTitle).text()).toEqual('some error title');
111+
expect(wrapper.find(Alert).text()).toEqual('some error titlesome description');
112+
});
29113
});

0 commit comments

Comments
 (0)