Skip to content

Commit 56e04e0

Browse files
committed
feat(renderer): allow definition of global props in component mapper.
1 parent 9cd85b8 commit 56e04e0

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

packages/react-form-renderer/demo/form-fields-mapper.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ const mapper = {
8282
[componentTypes.TAB_ITEM]: (props) => <div>tab item</div>,
8383
[componentTypes.DATE_PICKER]: (props) => <div>date picker</div>,
8484
[componentTypes.TIME_PICKER]: (props) => <div>time picker</div>,
85-
dataShower: AsyncComponent
85+
dataShower: AsyncComponent,
86+
'composite-mapper-field': {
87+
component: TextField,
88+
className: 'composite-component-class'
89+
}
8690
};
8791

8892
export default mapper;

packages/react-form-renderer/demo/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ const validatorMapper = {
3232

3333
const asyncValidatorSchema = {
3434
fields: [
35+
{
36+
component: 'composite-mapper-field',
37+
name: 'composite-field',
38+
label: 'Componsite field'
39+
},
3540
{
3641
component: 'text-field',
3742
name: 'async-validation-field',

packages/react-form-renderer/src/form-renderer/render-form.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const SingleField = ({ component, condition, hideField, validate, ...rest }) =>
5555

5656
const validation = validate || rest.dataType ? getValidate(validate, rest.dataType, validatorMapper) : undefined;
5757

58-
const componentProps = {
58+
let componentProps = {
5959
type: assignSpecialType(component),
6060
...rest,
6161
...(Object.prototype.hasOwnProperty.call(rest, 'initialValue') && Object.prototype.hasOwnProperty.call(rest, 'dataType')
@@ -67,8 +67,15 @@ const SingleField = ({ component, condition, hideField, validate, ...rest }) =>
6767
: { validate: composeValidators(validation) }
6868
: {})
6969
};
70-
71-
const Component = componentMapper[component];
70+
const componentBinding = componentMapper[component];
71+
let Component;
72+
if (typeof componentBinding === 'object' && Object.prototype.hasOwnProperty.call(componentBinding, 'component')) {
73+
const { component, ...mapperProps } = componentBinding;
74+
Component = component;
75+
componentProps = { ...mapperProps, ...componentProps };
76+
} else {
77+
Component = componentBinding;
78+
}
7279

7380
return (
7481
<FormConditionWrapper condition={condition}>
@@ -84,7 +91,7 @@ SingleField.propTypes = {
8491
condition: PropTypes.object,
8592
hideField: PropTypes.bool,
8693
dataType: PropTypes.string,
87-
validate: PropTypes.arrayOf(PropTypes.func),
94+
validate: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object])),
8895
initialValue: PropTypes.any
8996
};
9097

packages/react-form-renderer/src/tests/form-renderer/render-form.test.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ import useFieldApi from '../../files/use-field-api';
1313
import FieldProvider from '../../files/field-provider';
1414

1515
const TextField = (props) => {
16-
const { input, meta } = useFieldApi(props);
16+
const { input, meta, ...rest } = useFieldApi(props);
1717
return (
1818
<div>
19-
<input {...input} />
19+
<input {...input} {...rest} />
2020
{meta.error && <div id="error">{meta.error}</div>}
2121
</div>
2222
);
@@ -1498,4 +1498,34 @@ describe('renderForm function', () => {
14981498
.text()
14991499
).toEqual('standard label');
15001500
});
1501+
1502+
describe('composite mapper component', () => {
1503+
const schema = {
1504+
fields: [
1505+
{
1506+
component: 'text-field',
1507+
name: 'props-from-mapper',
1508+
label: 'Number field',
1509+
type: 'number'
1510+
}
1511+
]
1512+
};
1513+
const wrapper = mount(
1514+
<FormRenderer
1515+
FormTemplate={FormTemplate}
1516+
schema={schema}
1517+
onSubmit={() => {}}
1518+
componentMapper={{
1519+
'text-field': {
1520+
component: TextField,
1521+
className: 'composite-class',
1522+
type: 'text'
1523+
}
1524+
}}
1525+
/>
1526+
);
1527+
const { className, type } = wrapper.find('input').props();
1528+
expect(className).toEqual('composite-class');
1529+
expect(type).toEqual('number');
1530+
});
15011531
});

0 commit comments

Comments
 (0)