Skip to content

Commit 9d28a3b

Browse files
committed
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
1 parent fc1264c commit 9d28a3b

File tree

2 files changed

+118
-10
lines changed

2 files changed

+118
-10
lines changed

packages/ui-time-select/src/TimeSelect/__new-tests__/TimeSelect.test.tsx

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,125 @@ describe('<TimeSelect />', () => {
249249
await userEvent.type(input, '7:45 PM')
250250
fireEvent.blur(input) // sends onChange event
251251

252-
await waitFor(() => {
253-
expect(onChange).toHaveBeenCalled()
254-
expect(onKeyDown).toHaveBeenCalled()
255-
expect(handleInputChange).toHaveBeenCalled()
256-
expect(input).toHaveValue('7:45 PM')
252+
expect(onChange).toHaveBeenCalledWith(expect.anything(), {
253+
inputText: '7:45 PM',
254+
value: expect.anything()
255+
})
256+
expect(onKeyDown).toHaveBeenCalled()
257+
expect(handleInputChange).toHaveBeenCalled()
258+
expect(input).toHaveValue('7:45 PM')
259+
})
260+
261+
it('allowClearingSelection allows to clear the value', async () => {
262+
const defaultValue = moment.tz(
263+
'1986-05-17T18:00:00.000Z', // 2:00 PM in US/Eastern
264+
moment.ISO_8601,
265+
'en',
266+
'US/Eastern'
267+
)
268+
const onChange = vi.fn()
269+
render(
270+
<TimeSelect
271+
allowClearingSelection
272+
renderLabel="Choose a time"
273+
allowNonStepInput={true}
274+
locale="en_AU"
275+
timezone="US/Eastern"
276+
defaultValue={defaultValue.toISOString()}
277+
onChange={onChange}
278+
/>
279+
)
280+
const input = screen.getByRole('combobox')
281+
282+
await userEvent.type(
283+
input,
284+
'{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}'
285+
)
286+
fireEvent.blur(input) // sends onChange event
287+
288+
expect(onChange).toHaveBeenCalledWith(expect.anything(), {
289+
inputText: '',
290+
value: ''
291+
})
292+
expect(input).toHaveValue('')
293+
})
294+
295+
it('Can change from defaultValue', async () => {
296+
const defaultValue = moment.tz(
297+
'1986-05-17T18:00:00.000Z', // 2:00 PM in US/Eastern
298+
moment.ISO_8601,
299+
'en',
300+
'US/Eastern'
301+
)
302+
const onChange = vi.fn()
303+
const onKeyDown = vi.fn()
304+
const handleInputChange = vi.fn()
305+
render(
306+
<TimeSelect
307+
renderLabel="Choose a time"
308+
allowNonStepInput={true}
309+
locale="en_AU"
310+
timezone="US/Eastern"
311+
defaultValue={defaultValue.toISOString()}
312+
onChange={onChange}
313+
onInputChange={handleInputChange}
314+
onKeyDown={onKeyDown}
315+
/>
316+
)
317+
const input = screen.getByRole('combobox')
318+
319+
await userEvent.type(
320+
input,
321+
'{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}7:45 PM'
322+
)
323+
fireEvent.blur(input) // sends onChange event
324+
expect(onChange).toHaveBeenCalledWith(expect.anything(), {
325+
inputText: '7:45 PM',
326+
value: '1986-05-17T23:45:00.000Z'
327+
})
328+
expect(onKeyDown).toHaveBeenCalled()
329+
expect(handleInputChange).toHaveBeenCalled()
330+
expect(input).toHaveValue('7:45 PM')
331+
})
332+
333+
it('Reverts to a set value if the current one is invalid', async () => {
334+
const defaultValue = moment.tz(
335+
'1986-05-17T18:00:00.000Z', // 2:00 PM in US/Eastern
336+
moment.ISO_8601,
337+
'en',
338+
'US/Eastern'
339+
)
340+
const onChange = vi.fn()
341+
const onKeyDown = vi.fn()
342+
const handleInputChange = vi.fn()
343+
render(
344+
<TimeSelect
345+
renderLabel="Choose a time"
346+
allowNonStepInput={true}
347+
locale="en_AU"
348+
timezone="US/Eastern"
349+
defaultValue={defaultValue.toISOString()}
350+
onChange={onChange}
351+
onInputChange={handleInputChange}
352+
onKeyDown={onKeyDown}
353+
/>
354+
)
355+
const input = screen.getByRole('combobox')
356+
357+
await userEvent.type(
358+
input,
359+
'{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}7:45 PM'
360+
)
361+
fireEvent.blur(input) // sends onChange event
362+
await userEvent.type(input, 'asdf')
363+
fireEvent.blur(input)
364+
expect(onChange).toHaveBeenCalledWith(expect.anything(), {
365+
inputText: '7:45 PM',
366+
value: '1986-05-17T23:45:00.000Z'
257367
})
368+
expect(onKeyDown).toHaveBeenCalled()
369+
expect(handleInputChange).toHaveBeenCalled()
370+
expect(input).toHaveValue('7:45 PM')
258371
})
259372

260373
describe('input', () => {

packages/ui-time-select/src/TimeSelect/index.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,6 @@ class TimeSelect extends Component<TimeSelectProps, TimeSelectState> {
335335
this.setState({ fireChangeOnBlur: newOptions[0] })
336336
} else {
337337
this.setState({
338-
// needs not to lose selectedOptionId in controlled mode otherwise it'd
339-
// revert to the default or '' instead of the set value
340-
selectedOptionId: this.isControlled
341-
? this.state.selectedOptionId
342-
: undefined,
343338
fireChangeOnBlur: undefined,
344339
isInputCleared: this.props.allowClearingSelection! && value === ''
345340
})

0 commit comments

Comments
 (0)