Skip to content

Commit

Permalink
[cross browser fix] Webkit state update behavior
Browse files Browse the repository at this point in the history
for some incredibly frustrating reason, firefox correctly runs `finishParsing` after `this.setState` after `onChange` fires, but webkit browsers run it before `onChange`, thus the state shenanigans

and for some even more incredibly bizarre reason, `requestAnimationFrame` works for every browser :dead_inside:
  • Loading branch information
cee-chen committed Nov 3, 2023
1 parent 69de2c7 commit 1b6335c
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ jest.mock('../../date_picker', () => ({
}));

describe('EuiAbsoluteTab', () => {
// mock requestAnimationFrame to fire immediately
const rafSpy = jest
.spyOn(window, 'requestAnimationFrame')
.mockImplementation((cb: Function) => cb());
afterAll(() => rafSpy.mockRestore());

const props = {
dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS',
timeFormat: 'HH:mm',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,19 @@ export class EuiAbsoluteTab extends Component<

parseUserDateInput = (textInputValue: string) => {
this.isParsing = true;
const finishParsing = () => {
// Wait a tick for state to finish updating (whatever gets returned),
// and then allow `onChange` user input to continue setting state
requestAnimationFrame(() => {
this.isParsing = false;
};
});

const invalidDateState = {
textInputValue,
isTextInvalid: true,
valueAsMoment: null,
};
if (!textInputValue) {
return this.setState(invalidDateState, finishParsing);
return this.setState(invalidDateState);
}

const { onChange, dateFormat } = this.props;
Expand All @@ -128,17 +130,14 @@ export class EuiAbsoluteTab extends Component<

if (dateIsValid) {
onChange(valueAsMoment.toISOString());
this.setState(
{
textInputValue: valueAsMoment.format(this.props.dateFormat),
valueAsMoment: valueAsMoment,
hasUnparsedText: false,
isTextInvalid: false,
},
finishParsing
);
this.setState({
textInputValue: valueAsMoment.format(this.props.dateFormat),
valueAsMoment: valueAsMoment,
hasUnparsedText: false,
isTextInvalid: false,
});
} else {
this.setState(invalidDateState, finishParsing);
this.setState(invalidDateState);
}
};

Expand Down

0 comments on commit 1b6335c

Please sign in to comment.