Merge pull request #16380 from overleaf/mj-select-keyboard

[web] Allow keyboard interactions with custom select component

GitOrigin-RevId: 81adea8e456bd6ce2483dfa17a352c24c36e5768
This commit is contained in:
Mathias Jakobsen 2024-01-05 09:18:30 +00:00 committed by Copybot
parent 92f8e445d3
commit 45274d9dff
2 changed files with 28 additions and 2 deletions

View file

@ -1,6 +1,6 @@
/* eslint-disable jsx-a11y/label-has-for */
/* eslint-disable jsx-a11y/label-has-associated-control */
import { useRef, useEffect } from 'react'
import { useRef, useEffect, KeyboardEventHandler, useCallback } from 'react'
import classNames from 'classnames'
import { useSelect } from 'downshift'
import Icon from './icon'
@ -59,6 +59,7 @@ export const Select = <T,>({
getMenuProps,
getItemProps,
highlightedIndex,
openMenu,
} = useSelect({
items: items ?? [],
itemToString,
@ -91,6 +92,17 @@ export const Select = <T,>({
}
}, [name, itemToString, selectedItem, defaultItem])
const onKeyDown: KeyboardEventHandler<HTMLButtonElement> = useCallback(
event => {
if (event.key === 'Enter' && !isOpen) {
event.preventDefault()
;(event.nativeEvent as any).preventDownshiftDefault = true
openMenu()
}
},
[isOpen, openMenu]
)
let value: string | undefined
if (selectedItem || defaultItem) {
value = itemToString(selectedItem || defaultItem)
@ -113,7 +125,12 @@ export const Select = <T,>({
) : null}
<div
className={classNames({ disabled }, 'select-trigger')}
{...getToggleButtonProps({ disabled })}
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
tabIndex={0}
{...getToggleButtonProps({
disabled,
onKeyDown,
})}
>
<div>{value}</div>
<div>

View file

@ -266,4 +266,13 @@ describe('<Select />', function () {
})
})
})
describe('keyboard navigation', function () {
it('can select an item using the keyboard', function () {
render({ defaultText: 'Choose an item' })
cy.findByText('Choose an item').type('{Enter}{downArrow}{Enter}')
cy.findByText('Demo item 1').should('exist')
cy.findByText('Demo item 2').should('not.exist')
})
})
})