Skip to content

Commit

Permalink
updated iterateFieldsByAction to break out of all loops on first focus
Browse files Browse the repository at this point in the history
  • Loading branch information
David Pflasterer committed Apr 26, 2024
1 parent 7cdad77 commit 0b3341f
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 5 deletions.
139 changes: 139 additions & 0 deletions src/__tests__/logic/iterateFieldsByAction.test.ts
Expand Up @@ -64,4 +64,143 @@ describe('focusFieldBy', () => {
);
}).not.toThrow();
});

it('should focus on the first error it encounter and not the second', () => {
const focus = jest.fn();
iterateFieldsByAction(
{
first: {
_f: {
name: 'first',
ref: {
name: 'first',
focus,
},
},
},
second: {
_f: {
name: 'second',
ref: {
name: 'second',
focus,
},
},
},
},
(ref) => {
// @ts-ignore
ref.focus && ref.focus(ref.name);
return 1;
},
);
expect(focus).toBeCalledWith('first');
expect(focus).not.toBeCalledWith('second');
});

it('should recursively drill into objects', () => {
const focus = jest.fn();
iterateFieldsByAction(
{
test: {
name: {

Check failure on line 106 in src/__tests__/logic/iterateFieldsByAction.test.ts

View workflow job for this annotation

GitHub Actions / build

Object literal may only specify known properties, and 'name' does not exist in type 'Field'.
first: {
_f: {
name: 'name.first',
ref: {
name: 'first',
focus,
},
},
},
last: {
_f: {
name: 'name.last',
ref: {
name: 'last',
focus,
},
},
},
},
},
},
(ref, key) => {
if (key === 'name.last') {
// @ts-ignore
ref.focus && ref.focus(ref.name);
return 1;
}
return;
},
);
expect(focus).not.toBeCalledWith('first');
expect(focus).toBeCalledWith('last');
});

it('should should recursively drill into objects and break out of all loops on first focus', () => {
const focus = jest.fn();
const notFocus = jest.fn();
iterateFieldsByAction(
{
personal: {
name: {

Check failure on line 147 in src/__tests__/logic/iterateFieldsByAction.test.ts

View workflow job for this annotation

GitHub Actions / build

Object literal may only specify known properties, and 'name' does not exist in type 'Field'.
first: {
_f: {
name: 'name.first',
ref: {
name: 'first',
focus: notFocus,
},
},
},
last: {
_f: {
name: 'name.last',
ref: {
name: 'last',
focus,
},
},
},
},
phone: {
_f: {
name: 'phone',
ref: {
name: 'phone',
focus: notFocus,
},
},
},
address: {
line1: {
_f: {
name: 'address.line1',
ref: {
name: 'line1',
focus: notFocus,
},
},
},
},
},
},
(ref, key) => {
// @ts-ignore
ref.focus && ref.focus(ref.name);
return key === 'name.last' ? 1 : undefined;
},
);
// 'focus' should be called on 'last' and never again
expect(focus).not.toBeCalledWith('first'); // not valid
expect(focus).toBeCalledWith('last'); // valid
expect(focus).not.toBeCalledWith('phone'); // stopped
expect(focus).not.toBeCalledWith('line1');
// 'notFocus' should be called on the first, then never again
expect(notFocus).toBeCalledWith('first'); // not valid
expect(notFocus).not.toBeCalledWith('last'); // valid
expect(notFocus).not.toBeCalledWith('phone'); // stopped
expect(notFocus).not.toBeCalledWith('line1');
});
});
14 changes: 9 additions & 5 deletions src/logic/iterateFieldsByAction.ts
Expand Up @@ -16,17 +16,21 @@ const iterateFieldsByAction = (

if (_f) {
if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) {
break;
return true;
} else if (_f.ref && action(_f.ref, _f.name) && !abortEarly) {
break;
return true;
} else {
iterateFieldsByAction(currentField, action);
if (iterateFieldsByAction(currentField, action)) {
break;
}
}
} else if (isObject(currentField)) {
iterateFieldsByAction(currentField, action);
if (iterateFieldsByAction(currentField, action)) {
break;
}
}
}
}
return;
};

export default iterateFieldsByAction;

0 comments on commit 0b3341f

Please sign in to comment.