From 6441225a0e81f99233ba3d376580065b9dbd304c Mon Sep 17 00:00:00 2001 From: Matyas Szabo Date: Thu, 13 Feb 2025 20:51:38 +0100 Subject: [PATCH] fix(ui-time-select): fix TimeSelect showing the wrong value when defaultValue is set and enteting a wrong value after a good one TimeSelect was resetting to its defaultValue after a valid value was set if entering an invalid value. This commit fixes it by not losing the selected option ID when the input changes INSTUI-4451 --- .../__new-tests__/TimeSelect.test.tsx | 123 +++++++++++++++++- .../ui-time-select/src/TimeSelect/index.tsx | 5 - 2 files changed, 118 insertions(+), 10 deletions(-) diff --git a/packages/ui-time-select/src/TimeSelect/__new-tests__/TimeSelect.test.tsx b/packages/ui-time-select/src/TimeSelect/__new-tests__/TimeSelect.test.tsx index bc20edf059..44ae737978 100644 --- a/packages/ui-time-select/src/TimeSelect/__new-tests__/TimeSelect.test.tsx +++ b/packages/ui-time-select/src/TimeSelect/__new-tests__/TimeSelect.test.tsx @@ -249,12 +249,125 @@ describe('', () => { await userEvent.type(input, '7:45 PM') fireEvent.blur(input) // sends onChange event - await waitFor(() => { - expect(onChange).toHaveBeenCalled() - expect(onKeyDown).toHaveBeenCalled() - expect(handleInputChange).toHaveBeenCalled() - expect(input).toHaveValue('7:45 PM') + expect(onChange).toHaveBeenCalledWith(expect.anything(), { + inputText: '7:45 PM', + value: expect.anything() + }) + expect(onKeyDown).toHaveBeenCalled() + expect(handleInputChange).toHaveBeenCalled() + expect(input).toHaveValue('7:45 PM') + }) + + it('allowClearingSelection allows to clear the value', async () => { + const defaultValue = moment.tz( + '1986-05-17T18:00:00.000Z', // 2:00 PM in US/Eastern + moment.ISO_8601, + 'en', + 'US/Eastern' + ) + const onChange = vi.fn() + render( + + ) + const input = screen.getByRole('combobox') + + await userEvent.type( + input, + '{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}' + ) + fireEvent.blur(input) // sends onChange event + + expect(onChange).toHaveBeenCalledWith(expect.anything(), { + inputText: '', + value: '' + }) + expect(input).toHaveValue('') + }) + + it('Can change from defaultValue', async () => { + const defaultValue = moment.tz( + '1986-05-17T18:00:00.000Z', // 2:00 PM in US/Eastern + moment.ISO_8601, + 'en', + 'US/Eastern' + ) + const onChange = vi.fn() + const onKeyDown = vi.fn() + const handleInputChange = vi.fn() + render( + + ) + const input = screen.getByRole('combobox') + + await userEvent.type( + input, + '{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}7:45 PM' + ) + fireEvent.blur(input) // sends onChange event + expect(onChange).toHaveBeenCalledWith(expect.anything(), { + inputText: '7:45 PM', + value: '1986-05-17T23:45:00.000Z' + }) + expect(onKeyDown).toHaveBeenCalled() + expect(handleInputChange).toHaveBeenCalled() + expect(input).toHaveValue('7:45 PM') + }) + + it('Reverts to a set value if the current one is invalid', async () => { + const defaultValue = moment.tz( + '1986-05-17T18:00:00.000Z', // 2:00 PM in US/Eastern + moment.ISO_8601, + 'en', + 'US/Eastern' + ) + const onChange = vi.fn() + const onKeyDown = vi.fn() + const handleInputChange = vi.fn() + render( + + ) + const input = screen.getByRole('combobox') + + await userEvent.type( + input, + '{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}7:45 PM' + ) + fireEvent.blur(input) // sends onChange event + await userEvent.type(input, 'asdf') + fireEvent.blur(input) + expect(onChange).toHaveBeenCalledWith(expect.anything(), { + inputText: '7:45 PM', + value: '1986-05-17T23:45:00.000Z' }) + expect(onKeyDown).toHaveBeenCalled() + expect(handleInputChange).toHaveBeenCalled() + expect(input).toHaveValue('7:45 PM') }) describe('input', () => { diff --git a/packages/ui-time-select/src/TimeSelect/index.tsx b/packages/ui-time-select/src/TimeSelect/index.tsx index 59350dba1d..e4252a5c41 100644 --- a/packages/ui-time-select/src/TimeSelect/index.tsx +++ b/packages/ui-time-select/src/TimeSelect/index.tsx @@ -335,11 +335,6 @@ class TimeSelect extends Component { this.setState({ fireChangeOnBlur: newOptions[0] }) } else { this.setState({ - // needs not to lose selectedOptionId in controlled mode otherwise it'd - // revert to the default or '' instead of the set value - selectedOptionId: this.isControlled - ? this.state.selectedOptionId - : undefined, fireChangeOnBlur: undefined, isInputCleared: this.props.allowClearingSelection && value === '' })