Skip to content

Commit ee0d6a9

Browse files
committed
fix(renderer): use custom registerField function
1 parent 678dc37 commit ee0d6a9

File tree

13 files changed

+225
-36
lines changed

13 files changed

+225
-36
lines changed

__mocks__/with-provider.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React from 'react';
33
import { RendererContext } from '@data-driven-forms/react-form-renderer';
44
import Form from '@data-driven-forms/react-form-renderer/form';
55

6-
const RenderWithProvider = ({ value = { formOptions: {} }, children, onSubmit = () => {} }) => {
6+
const RenderWithProvider = ({ value = { formOptions: {internalRegisterField: jest.fn(), internalUnRegisterField: jest.fn()} }, children, onSubmit = () => {} }) => {
77
return (
88
<Form onSubmit={onSubmit}>
99
{() => (

packages/ant-component-mapper/src/tests/slider.test.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import React from 'react';
2-
import { Form as DDFForm } from '@data-driven-forms/react-form-renderer';
2+
import { Form as DDFForm, RendererContext } from '@data-driven-forms/react-form-renderer';
33
import { mount } from 'enzyme';
44
import { Slider as AntSlider, Form as OriginalForm } from 'antd';
55
import Slider from '../slider';
66
import FormGroup from '../form-group';
77

88
const Form = (props) => (
99
<OriginalForm>
10-
<DDFForm onSubmit={jest.fn()} {...props} />
10+
<RendererContext.Provider value={{ formOptions: { internalRegisterField: jest.fn(), internalUnRegisterField: jest.fn() } }}>
11+
<DDFForm onSubmit={jest.fn()} {...props} />
12+
</RendererContext.Provider>
1113
</OriginalForm>
1214
);
1315

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import React from 'react';
33
import PropTypes from 'prop-types';
44
import ReactDOM from 'react-dom';
5-
import { FormRenderer, useFieldApi, componentTypes } from '../src';
5+
import { FormRenderer, useFieldApi, componentTypes, useFormApi } from '../src';
66
import MuiTextField from '@material-ui/core/TextField';
77
import Grid from '@material-ui/core/Grid';
88

@@ -108,16 +108,25 @@ const TextField = (props) => {
108108
);
109109
};
110110

111-
const fields = [];
111+
const Spy = () => {
112+
const formApi = useFormApi();
113+
console.log(formApi);
114+
return null;
115+
};
116+
117+
const fields = [{
118+
name: 'optionsSpy',
119+
component: 'spy',
120+
}];
112121

113-
for (let index = 0; index < 1000; index++) {
122+
for (let index = 0; index < 10; index++) {
114123
fields.push({
115124
name: `field-${index}`,
116125
label: `Text field ${index}`,
117126
component: 'text-field',
118127
...(index > 0 ? {
119128
condition: {
120-
when: `field-${index - 1}`,
129+
when: [`field-${index - 1}`, 'prdel'],
121130
isEmpty: true
122131
}
123132
} : {})
@@ -134,7 +143,8 @@ const App = () => {
134143
<div style={{ padding: 20 }}>
135144
<FormRenderer
136145
componentMapper={{
137-
[componentTypes.TEXT_FIELD]: TextField
146+
[componentTypes.TEXT_FIELD]: TextField,
147+
spy: Spy
138148
}}
139149
onSubmit={console.log}
140150
FormTemplate={MuiFormTemplate}

packages/react-form-renderer/src/field-provider/field-provider.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ComponentType, ReactNode } from 'react';
33
export interface FieldProviderProps<T> {
44
Component?: ComponentType<any>;
55
render?: (props: T) => ReactNode;
6+
skipRegistration?: boolean;
67
}
78

89
declare const FieldProvider: React.ComponentType<FieldProviderProps<object>>;

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useRef } from 'react';
1+
import React, { useState, useRef, useCallback } from 'react';
22
import Form from '../form';
33
import arrayMutators from 'final-form-arrays';
44
import PropTypes from 'prop-types';
@@ -26,9 +26,20 @@ const FormRenderer = ({
2626
...props
2727
}) => {
2828
const [fileInputs, setFileInputs] = useState([]);
29+
const [registeredFields, setRegisteredFields] = useState({});
2930
const focusDecorator = useRef(createFocusDecorator());
3031
let schemaError;
3132

33+
const internalRegisterField = (name) => {
34+
setRegisteredFields(prev => prev[name] ? ({...prev, [name]: prev[name] + 1}) : ({...prev, [name]: 1}));
35+
};
36+
37+
const internalUnRegisterField = (name) => {
38+
setRegisteredFields(({[name]: currentField, ...prev}) => currentField && currentField > 1 ? ({[name]: currentField - 1, ...prev}) : prev);
39+
};
40+
41+
const internalGetRegisteredFields = () => Object.entries(registeredFields).reduce((acc, [name, value]) => value > 0 ? [...acc, name] : acc, []);
42+
3243
const validatorMapperMerged = { ...defaultValidatorMapper, ...validatorMapper };
3344

3445
try {
@@ -80,8 +91,12 @@ const FormRenderer = ({
8091
reset,
8192
clearOnUnmount,
8293
renderForm,
94+
internalRegisterField,
95+
internalUnRegisterField,
8396
...mutators,
84-
...form
97+
...form,
98+
ffGetRegisteredFields: form.getRegisteredFields,
99+
getRegisteredFields: internalGetRegisteredFields,
85100
}
86101
}}
87102
>

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

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
33
import set from 'lodash/set';
44
import RendererContext from '../renderer-context';
55
import Condition from '../condition';
6-
import { Field } from 'react-final-form';
6+
import FieldProvider from '../field-provider';
77
import getConditionTriggers from '../get-condition-triggers';
88

99
const FormFieldHideWrapper = ({ hideField, children }) => (hideField ? <div hidden>{children}</div> : children);
@@ -42,18 +42,16 @@ const ConditionTriggerDetector = ({ values = {}, triggers = [], children, condit
4242

4343
const name = internalTriggers.shift();
4444
return (
45-
<Field name={name} subscription={{ value: true }}>
46-
{({input: {value}}) => (
47-
<ConditionTriggerDetector
48-
triggers={[...internalTriggers]}
49-
values={set({...values}, name, value)}
50-
condition={condition}
51-
field={field}
52-
>
53-
{children}
54-
</ConditionTriggerDetector>
55-
)}
56-
</Field>
45+
<FieldProvider skipRegistration name={name} subscription={{ value: true }} render={({input: {value}}) => (
46+
<ConditionTriggerDetector
47+
triggers={[...internalTriggers]}
48+
values={set({...values}, name, value)}
49+
condition={condition}
50+
field={field}
51+
>
52+
{children}
53+
</ConditionTriggerDetector>
54+
)}/>
5755
);
5856
};
5957

packages/react-form-renderer/src/renderer-context/renderer-context.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ export interface FormOptions extends FormApi {
1414
handleSubmit: () => Promise<AnyObject | undefined> | undefined;
1515
clearedValue?: any;
1616
renderForm: (fields: Field[]) => ReactNode[];
17+
internalRegisterField: (name: string) => void;
18+
internalUnregisterField: (name: string) => void;
19+
getRegisteredFields: () => string[];
20+
ffGetRegisteredFields: () => string[];
1721
}
1822

1923
export interface RendererContextValue {

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

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,10 @@ exports[`renderForm function #condition should render condition field only if co
247247
]
248248
}
249249
>
250-
<ForwardRef(Field)
250+
<FieldProvider
251251
name="a"
252+
render={[Function]}
253+
skipRegistration={true}
252254
subscription={
253255
Object {
254256
"value": true,
@@ -289,8 +291,10 @@ exports[`renderForm function #condition should render condition field only if co
289291
}
290292
}
291293
>
292-
<ForwardRef(Field)
294+
<FieldProvider
293295
name="b"
296+
render={[Function]}
297+
skipRegistration={true}
294298
subscription={
295299
Object {
296300
"value": true,
@@ -331,8 +335,10 @@ exports[`renderForm function #condition should render condition field only if co
331335
}
332336
}
333337
>
334-
<ForwardRef(Field)
338+
<FieldProvider
335339
name="c"
340+
render={[Function]}
341+
skipRegistration={true}
336342
subscription={
337343
Object {
338344
"value": true,
@@ -432,11 +438,11 @@ exports[`renderForm function #condition should render condition field only if co
432438
/>
433439
</ConditionTriggerWrapper>
434440
</ConditionTriggerDetector>
435-
</ForwardRef(Field)>
441+
</FieldProvider>
436442
</ConditionTriggerDetector>
437-
</ForwardRef(Field)>
443+
</FieldProvider>
438444
</ConditionTriggerDetector>
439-
</ForwardRef(Field)>
445+
</FieldProvider>
440446
</ConditionTriggerDetector>
441447
</FormConditionWrapper>
442448
</SingleField>
@@ -672,8 +678,10 @@ exports[`renderForm function #condition should render condition field only if on
672678
]
673679
}
674680
>
675-
<ForwardRef(Field)
681+
<FieldProvider
676682
name="a"
683+
render={[Function]}
684+
skipRegistration={true}
677685
subscription={
678686
Object {
679687
"value": true,
@@ -707,8 +715,10 @@ exports[`renderForm function #condition should render condition field only if on
707715
}
708716
}
709717
>
710-
<ForwardRef(Field)
718+
<FieldProvider
711719
name="b"
720+
render={[Function]}
721+
skipRegistration={true}
712722
subscription={
713723
Object {
714724
"value": true,
@@ -787,9 +797,9 @@ exports[`renderForm function #condition should render condition field only if on
787797
/>
788798
</ConditionTriggerWrapper>
789799
</ConditionTriggerDetector>
790-
</ForwardRef(Field)>
800+
</FieldProvider>
791801
</ConditionTriggerDetector>
792-
</ForwardRef(Field)>
802+
</FieldProvider>
793803
</ConditionTriggerDetector>
794804
</FormConditionWrapper>
795805
</SingleField>

0 commit comments

Comments
 (0)