chore(a11y): 🤖 enable keyboard date range picker selection#856
chore(a11y): 🤖 enable keyboard date range picker selection#856
Conversation
…ow that clears if not complete
…hore/enable-keyboard-date-range-picker-selection
|
How do you actually trigger the DatePicker with just the keyboard? This video is me getting the input focus then trying to open the DatePicker using enter, spacebar, and various keys on the keyboard Screen.Recording.2026-03-03.at.9.25.53.AM.mov |
src/components/DatePicker/Common.tsx
Outdated
| const monthGridRef = useRef<(HTMLButtonElement | null)[]>([]); | ||
| const yearGridRef = useRef<(HTMLButtonElement | null)[]>([]); | ||
| const headerNavRefs = useRef<(HTMLButtonElement | null)[]>([null, null, null]); | ||
|
|
There was a problem hiding this comment.
We prefer the form Array<type> rather than type[] for readability purposes.
There was a problem hiding this comment.
@hoorayimhelping, that's quite subjective, can we not impose it? If you hover a type in your text editor, TypeScript will show the form type[] and not Array, it's the default. A quick search in the project or control plane show plenty of examples of type[] usage.
| newIndex = (index - columns + totalItems) % totalItems; | ||
| break; | ||
| case 'Enter': | ||
| case ' ': |
There was a problem hiding this comment.
Is ' ' the same as spacebar?
There was a problem hiding this comment.
There was a problem hiding this comment.
Can we use space or spacebar or do we have to use ' ' since it's a value? I'd prefer spacebar since it's more explicit and clear
src/components/DatePicker/Common.tsx
Outdated
|
|
||
| const renderYearsGrid = () => { | ||
| const years = []; | ||
| const years: number[] = []; |
There was a problem hiding this comment.
| const years: number[] = []; | |
| const years: Array<number> = []; |
|
|
||
| describe('disabling dates', () => { | ||
| // this test was throwing an error if `vi.useFakeTimers` was called outside | ||
| // of beforeAll, so it needed to be put in here |
There was a problem hiding this comment.
I think you should leave this comment here. We rarely use beforeAll, so explaining why it's here and giving a hint that it shouldn't be changed is probably valuable
| expect(document.activeElement).toBe(getByTestId('month-cell-1')); | ||
| }); | ||
|
|
||
| it('calendar title is keyboard accessible', async () => { |
There was a problem hiding this comment.
| it('calendar title is keyboard accessible', async () => { | |
| it('allows accessing the calendar title by keyboard', async () => { |
| expect(getByTestId('years-grid')).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('day grid supports keyboard navigation and Enter to select', async () => { |
There was a problem hiding this comment.
I think we this should be wrapped in a describe as well
describe('the day grid', () => {
it('supports keyboard navigation and selects with Enter', async ()| selectedDate ? isSameDate(selectedDate, day.value) : isSameDate(today, day.value) | ||
| ); | ||
|
|
||
| const [focusedDayIndex, setFocusedDayIndex] = useState( |
There was a problem hiding this comment.
| const [focusedDayIndex, setFocusedDayIndex] = useState( | |
| const [focusedDayIndex, setFocusedDayIndex] = useState<number>( |
| const [focusedDayIndex, setFocusedDayIndex] = useState( | ||
| initialFocusIndex >= 0 ? initialFocusIndex : 0 | ||
| ); | ||
| const dayRefs = useRef<(HTMLTableCellElement | null)[]>([]); |
There was a problem hiding this comment.
| const dayRefs = useRef<(HTMLTableCellElement | null)[]>([]); | |
| const dayRefs = useRef<Array<(HTMLTableCellElement | null)>>([]); |
|
|
||
| return ( | ||
| <Dropdown | ||
| <Popover.Root |
There was a problem hiding this comment.
Why the change from Dropdown to Popover?
There was a problem hiding this comment.
Tab, then space |
I can't get this to work in Firefox. I'm trying to load the preview in chrome. Where can I find the latest vercel preview? The one auto-posted in a comment is an older build. Chromatic requires a login, which I'm not going to both with on Chrome |
Why?
Enable keyboard date range picker selection
Added keyboard navigation support to the DatePicker component, allowing users to select dates without using a mouse. This improves accessibility and provides a faster workflow for power users.
🤖 Switch base branch to main once #838 is merged
How?
Preview?
Latest update (feb 27 12:15pm GMT)
demo-datepicker-keyboard-navigation.mov
Contrast issue found, e.g. lack contrast on keyboard navigation matching an active element
demo-keyboard-nav-no-contrast-on-active-match.mov
Solution for contrast issue, e.g. replaces active by navigation default focus style
demo-date-picker-solved-selection-nav-matching-active.mov
Result use-cases
demo-date-picking-keyboard-nav-flow.mov