diff --git a/web/src/components/DatePicker.jsx b/web/src/components/DatePicker.jsx index fc9f1705d..b05257633 100644 --- a/web/src/components/DatePicker.jsx +++ b/web/src/components/DatePicker.jsx @@ -53,7 +53,7 @@ export const DateFilterOptions = [ }, { label: 'Custom Range', - value: null, + value: 'custom_range', }, ]; @@ -134,6 +134,7 @@ export default function DatePicker({ tabIndex="0" onClick={onClick} value={propValue} + {...props} />
{ + (value) => { setSelected(options.findIndex(({ value }) => Object.values(propSelected).includes(value))); setShowMenu(false); - if (!value) return setShowDatePicker(true); - onChange && onChange(value, label); + //show calender date range picker + if (value === 'custom_range') return setShowDatePicker(true); + onChange && onChange(value); }, [onChange, options, propSelected, setSelected] ); const handleDateRange = useCallback( (range) => { - onChange && onChange(range, 'range'); + onChange && onChange(range); setShowMenu(false); }, [onChange] @@ -98,6 +99,44 @@ export default function Select({ setShowMenu(true); }, [setShowMenu]); + const handleKeydownDatePicker = useCallback( + (event) => { + switch (event.key) { + case 'Enter': { + if (!showMenu) { + setShowMenu(true); + setFocused(selected); + } else { + setSelected(focused); + if (options[focused].value === 'custom_range') { + setShowMenu(false); + return setShowDatePicker(true); + } + + onChange && onChange(options[focused].value); + setShowMenu(false); + } + break; + } + + case 'ArrowDown': { + const newIndex = focused + 1; + newIndex < options.length && setFocused(newIndex); + break; + } + + case 'ArrowUp': { + const newIndex = focused - 1; + newIndex > -1 && setFocused(newIndex); + break; + } + + // no default + } + }, + [onChange, options, showMenu, setShowMenu, setFocused, focused, selected] + ); + const handleKeydown = useCallback( (event) => { switch (event.key) { @@ -107,7 +146,7 @@ export default function Select({ setFocused(selected); } else { setSelected(focused); - onChange && onChange(options[focused].value, options[focused].label); + onChange && onChange({ [paramName]: options[focused].value }); setShowMenu(false); } break; @@ -146,7 +185,7 @@ export default function Select({ } }; window.addEventListener('click', addBackDrop); - // setDateToInput(state.selectedDay); + return function cleanup() { window.removeEventListener('click', addBackDrop); }; @@ -161,7 +200,7 @@ export default function Select({ label={label} onchange={onChange} onclick={handleClick} - onkeydown={handleKeydown} + onkeydown={handleKeydownDatePicker} trailingIcon={showMenu ? ArrowDropup : ArrowDropdown} value={datePickerValue} /> diff --git a/web/src/components/__tests__/Select.test.jsx b/web/src/components/__tests__/Select.test.jsx index 6d9858d67..00c58d9e3 100644 --- a/web/src/components/__tests__/Select.test.jsx +++ b/web/src/components/__tests__/Select.test.jsx @@ -4,6 +4,30 @@ import { fireEvent, render, screen } from '@testing-library/preact'; describe('Select', () => { test('on focus, shows a menu', async () => { + const handleChange = jest.fn(); + render( + { ); expect(screen.queryByRole('listbox')).not.toBeInTheDocument(); - fireEvent.click(screen.getByRole('textbox')); + const input = screen.getByRole('textbox'); + fireEvent.focus(input); + fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' }); expect(screen.queryByRole('listbox')).toBeInTheDocument(); - expect(screen.queryByRole('option', { name: 'tacos' })).toBeInTheDocument(); - expect(screen.queryByRole('option', { name: 'burritos' })).toBeInTheDocument(); - fireEvent.click(screen.queryByRole('option', { name: 'tacos' })); - expect(handleChange).toHaveBeenCalledWith({ dinner: 'tacos' }, 'tacos'); + fireEvent.keyDown(input, { key: 'ArrowDown', code: 'ArrowDown' }); + fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' }); + expect(handleChange).toHaveBeenCalledWith({ dinner: 'burritos' }); }); - - // test('allows keyboard navigation', async () => { - // const handleChange = jest.fn(); - // render( - ); + paramName.map((name) => Object.assign(obj, { [name]: searchParams.get(name) }), [searchParams]); + return