Skip to content

Commit 5c3b1c5

Browse files
committed
feat(renderer): add resolveProps option
1 parent 146e2d3 commit 5c3b1c5

File tree

2 files changed

+48
-18
lines changed

2 files changed

+48
-18
lines changed

packages/react-form-renderer/src/files/use-field-api.js

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ const reducer = (state, { type, specialType, validate, arrayValidator, initialVa
5757
}
5858
};
5959

60-
const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...props }) => {
61-
const { actionMapper, validatorMapper, formOptions } = useContext(RendererContext);
60+
const useFieldApi = ({ name, initializeOnMount, component, render, validate, resolveProps, ...props }) => {
61+
const { validatorMapper, formOptions } = useContext(RendererContext);
6262

6363
const [{ type, initialValue, validate: stateValidate, arrayValidator }, dispatch] = useReducer(
6464
reducer,
@@ -154,25 +154,14 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...
154154
[]
155155
);
156156

157-
/**
158-
* Map actions to props
159-
*/
160-
let overrideProps = {};
161-
if (props.actions) {
162-
Object.keys(props.actions).forEach((prop) => {
163-
const [action, ...args] = props.actions[prop];
164-
overrideProps[prop] = actionMapper[action](...args);
165-
});
166-
}
167-
168157
const { initialValue: _initialValue, clearOnUnmount, dataType, clearedValue, isEqual: _isEqual, ...cleanProps } = props;
169158

170159
/**
171160
* construct component props necessary that would live in field provider
172161
*/
173162
return {
174163
...cleanProps,
175-
...overrideProps,
164+
...(resolveProps ? resolveProps(cleanProps, fieldProps, formOptions) : {}),
176165
...fieldProps,
177166
...(arrayValidator ? { arrayValidator } : {}),
178167
input: {

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

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ FormConditionWrapper.propTypes = {
3535
};
3636

3737
const SingleField = ({ component, condition, hideField, ...rest }) => {
38-
const { componentMapper } = useContext(RendererContext);
38+
const { actionMapper, componentMapper } = useContext(RendererContext);
3939

4040
let componentProps = {
4141
component,
@@ -47,15 +47,52 @@ const SingleField = ({ component, condition, hideField, ...rest }) => {
4747
if (typeof componentBinding === 'object' && Object.prototype.hasOwnProperty.call(componentBinding, 'component')) {
4848
const { component, ...mapperProps } = componentBinding;
4949
Component = component;
50-
componentProps = { ...mapperProps, ...componentProps };
50+
componentProps = {
51+
...mapperProps,
52+
...componentProps,
53+
// merge mapper and field actions
54+
...(mapperProps.actions && rest.actions ? { actions: { ...mapperProps.actions, ...rest.actions } } : {}),
55+
// merge mapper and field resolveProps
56+
...(mapperProps.resolveProps && rest.resolveProps
57+
? {
58+
resolveProps: (...args) => ({
59+
...mapperProps.resolveProps(...args),
60+
...rest.resolveProps(...args)
61+
})
62+
}
63+
: {})
64+
};
5165
} else {
5266
Component = componentBinding;
5367
}
5468

69+
/**
70+
* Map actions to props
71+
*/
72+
let overrideProps = {};
73+
let mergedResolveProps; // new object has to be created because of references
74+
if (componentProps.actions) {
75+
Object.keys(componentProps.actions).forEach((prop) => {
76+
const [action, ...args] = componentProps.actions[prop];
77+
overrideProps[prop] = actionMapper[action](...args);
78+
});
79+
80+
// Merge componentProps resolve props and actions resolve props
81+
if (componentProps.resolveProps && overrideProps.resolveProps) {
82+
mergedResolveProps = (...args) => ({
83+
...componentProps.resolveProps(...args),
84+
...overrideProps.resolveProps(...args)
85+
});
86+
}
87+
88+
// do not pass actions object to components
89+
delete componentProps.actions;
90+
}
91+
5592
return (
5693
<FormConditionWrapper condition={condition}>
5794
<FormFieldHideWrapper hideField={hideField}>
58-
<Component {...componentProps} />
95+
<Component {...componentProps} {...overrideProps} {...(mergedResolveProps && { resolveProps: mergedResolveProps })} />
5996
</FormFieldHideWrapper>
6097
</FormConditionWrapper>
6198
);
@@ -67,7 +104,11 @@ SingleField.propTypes = {
67104
hideField: PropTypes.bool,
68105
dataType: PropTypes.string,
69106
validate: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object])),
70-
initialValue: PropTypes.any
107+
initialValue: PropTypes.any,
108+
actions: PropTypes.shape({
109+
[PropTypes.string]: PropTypes.func
110+
}),
111+
resolveProps: PropTypes.func
71112
};
72113

73114
const renderForm = (fields) => fields.map((field) => (Array.isArray(field) ? renderForm(field) : <SingleField key={field.name} {...field} />));

0 commit comments

Comments
 (0)