Skip to content

Commit dc7b4bf

Browse files
authored
Merge pull request #776 from rvsia/addFieldComponent
feat(manager): add field component
2 parents c45ffa1 + 1f47813 commit dc7b4bf

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react';
2+
import useField from './use-field';
3+
import FieldProps from '../types/field';
4+
5+
const Field = React.forwardRef(
6+
({ children, render, component, ...props }: FieldProps, ref): React.ReactElement => {
7+
const fieldProps = useField(props);
8+
9+
if (typeof component === 'string') {
10+
const { meta, input, ...rest } = fieldProps;
11+
12+
return React.createElement(
13+
component,
14+
{
15+
...input,
16+
...rest,
17+
ref
18+
},
19+
children
20+
);
21+
}
22+
23+
if (component) {
24+
const Component = component;
25+
return <Component {...fieldProps} />;
26+
}
27+
28+
if (render) {
29+
return render(fieldProps) as React.ReactElement;
30+
}
31+
32+
return children(fieldProps) as React.ReactElement;
33+
}
34+
);
35+
36+
export default Field;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
4+
import FormStateManager from '../../files/form-state-manager';
5+
import Field from '../../files/field';
6+
7+
describe('<Field />', () => {
8+
let wrapper;
9+
10+
const initialProps = { name: 'some-field', initialValue: 'some-value' };
11+
12+
it('renders with children', () => {
13+
wrapper = mount(<FormStateManager>{() => <Field {...initialProps}>{(props) => <input {...props.input} />}</Field>}</FormStateManager>);
14+
15+
expect(wrapper.find('input').props()).toEqual({
16+
name: initialProps.name,
17+
onBlur: expect.any(Function),
18+
onChange: expect.any(Function),
19+
onFocus: expect.any(Function),
20+
value: initialProps.initialValue
21+
});
22+
});
23+
24+
it('renders with string component', () => {
25+
const ref = React.createRef();
26+
27+
wrapper = mount(<FormStateManager>{() => <Field {...initialProps} component="input" ref={ref} />}</FormStateManager>);
28+
29+
expect(wrapper.find('input').props()).toEqual({
30+
name: initialProps.name,
31+
onBlur: expect.any(Function),
32+
onChange: expect.any(Function),
33+
onFocus: expect.any(Function),
34+
value: initialProps.initialValue
35+
});
36+
});
37+
38+
it('renders with component as ComponentType', () => {
39+
const ref = React.createRef();
40+
const Component = ({ input }) => <input {...input} />;
41+
42+
wrapper = mount(<FormStateManager>{() => <Field {...initialProps} component={Component} />}</FormStateManager>);
43+
44+
expect(wrapper.find('input').props()).toEqual({
45+
name: initialProps.name,
46+
onBlur: expect.any(Function),
47+
onChange: expect.any(Function),
48+
onFocus: expect.any(Function),
49+
value: initialProps.initialValue
50+
});
51+
});
52+
53+
it('renders with render function', () => {
54+
wrapper = mount(<FormStateManager>{() => <Field {...initialProps} render={(props) => <input {...props.input} />} />}</FormStateManager>);
55+
56+
expect(wrapper.find('input').props()).toEqual({
57+
name: initialProps.name,
58+
onBlur: expect.any(Function),
59+
onChange: expect.any(Function),
60+
onFocus: expect.any(Function),
61+
value: initialProps.initialValue
62+
});
63+
});
64+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import AnyObject from './any-object';
2+
import UseField from './use-field';
3+
4+
export interface FieldProps extends UseField {
5+
children: (props: AnyObject) => React.ReactNode;
6+
component: React.ComponentType<AnyObject> | 'input' | 'select' | 'textarea';
7+
ref: React.Ref<any>;
8+
render: (props: AnyObject) => React.ReactNode;
9+
}
10+
11+
export default FieldProps;

0 commit comments

Comments
 (0)