Skip to content

Commit e6a6d23

Browse files
committed
feat(manager): implement allowNull
1 parent 6cdad9f commit e6a6d23

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

packages/form-state-manager/src/files/use-field.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const useField = ({
6565
formatOnBlur,
6666
beforeSubmit,
6767
afterSubmit,
68+
allowNull,
6869
...props
6970
}: UseField): UseFieldData => {
7071
const { registerField, unregisterField, change, getFieldValue, blur, focus, formOptions, ...rest } = useContext(FormManagerContext);
@@ -135,7 +136,7 @@ const useField = ({
135136
}
136137
};
137138

138-
let valueToReturn = formOptions().getFieldValue(name) || '';
139+
let valueToReturn = formOptions().getFieldValue(name);
139140
let checked;
140141

141142
if (type === 'checkbox') {
@@ -157,9 +158,15 @@ const useField = ({
157158
finalFormat = format;
158159
}
159160

161+
valueToReturn = finalFormat(valueToReturn, name);
162+
163+
if ((valueToReturn === null && !allowNull) || (valueToReturn !== null && !valueToReturn)) {
164+
valueToReturn = '';
165+
}
166+
160167
return {
161168
input: {
162-
value: finalFormat(valueToReturn, name),
169+
value: valueToReturn,
163170
onChange,
164171
onFocus: () => focus(name),
165172
onBlur: () => blur(name),

packages/form-state-manager/src/tests/files/use-field.test.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,4 +1206,61 @@ describe('useField', () => {
12061206
expect(wrapper.find('input').props().value).toEqual(''); // it's controlled
12071207
});
12081208
});
1209+
1210+
describe('allowNull', () => {
1211+
let Dummy;
1212+
let wrapper;
1213+
1214+
beforeEach(() => {
1215+
managerApi = createManagerApi({});
1216+
1217+
Dummy = (props) => {
1218+
const { input } = useField(props);
1219+
return <input {...input} />;
1220+
};
1221+
});
1222+
1223+
it('by default converts null to empty string', async () => {
1224+
wrapper = mount(
1225+
<FormManagerContext.Provider value={{ ...managerApi(), formOptions: managerApi }}>
1226+
<Dummy name="field" />
1227+
</FormManagerContext.Provider>
1228+
);
1229+
1230+
await act(async () => {
1231+
wrapper.find('input').simulate('change', { target: { value: null } });
1232+
});
1233+
wrapper.update();
1234+
1235+
expect(wrapper.find('input').props().value).toEqual('');
1236+
});
1237+
1238+
it('allows null', async () => {
1239+
// disable console errors:
1240+
// expected:
1241+
// 1. input cannot be null
1242+
// 2. controlled to uncontrolled
1243+
1244+
// eslint-disable-next-line no-console
1245+
const _consoleError = console.error;
1246+
// eslint-disable-next-line no-console
1247+
console.error = jest.fn();
1248+
1249+
wrapper = mount(
1250+
<FormManagerContext.Provider value={{ ...managerApi(), formOptions: managerApi }}>
1251+
<Dummy name="field" allowNull />
1252+
</FormManagerContext.Provider>
1253+
);
1254+
1255+
await act(async () => {
1256+
wrapper.find('input').simulate('change', { target: { value: null } });
1257+
});
1258+
wrapper.update();
1259+
1260+
expect(wrapper.find('input').props().value).toEqual(null);
1261+
1262+
// eslint-disable-next-line no-console
1263+
console.error = _consoleError;
1264+
});
1265+
});
12091266
});

packages/form-state-manager/src/types/use-field.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export interface UseField extends AnyObject {
8080
formatOnBlur?: boolean;
8181
afterSubmit?: AfterSubmit;
8282
beforeSubmit?: BeforeSubmit;
83+
allowNull?: boolean;
8384
}
8485

8586
export default UseField;

0 commit comments

Comments
 (0)