ensure that you can't use Enter to invoke the Switch

And a bunch of keyPress and keyboard related shenanigans
This commit is contained in:
Robin Malfait
2020-10-06 14:00:01 +02:00
parent 6ea5c93457
commit fecd61dff6
6 changed files with 115 additions and 41 deletions
@@ -156,6 +156,24 @@ describe('Keyboard interactions', () => {
})
})
describe('`Enter` key', () => {
it('should not be possible to use Enter to toggle the Switch', async () => {
const handleChange = jest.fn()
render(<Switch checked={false} onChange={handleChange} />)
// Ensure checkbox is off
assertSwitch({ state: SwitchState.Off })
// Focus the switch
getSwitch()?.focus()
// Try to toggle
await press(Keys.Enter)
expect(handleChange).not.toHaveBeenCalled()
})
})
describe('`Tab` key', () => {
it('should be possible to tab away from the Switch', async () => {
render(
@@ -55,7 +55,14 @@ const DEFAULT_SWITCH_TAG = 'button'
type SwitchRenderPropArg = { checked: boolean }
type SwitchPropsWeControl = 'id' | 'role' | 'tabIndex' | 'aria-checked' | 'onClick' | 'onKeyUp'
type SwitchPropsWeControl =
| 'id'
| 'role'
| 'tabIndex'
| 'aria-checked'
| 'onClick'
| 'onKeyUp'
| 'onKeyPress'
export function Switch<TTag extends React.ElementType = typeof DEFAULT_SWITCH_TAG>(
props: Props<
@@ -84,14 +91,18 @@ export function Switch<TTag extends React.ElementType = typeof DEFAULT_SWITCH_TA
)
const handleKeyUp = React.useCallback(
(event: React.KeyboardEvent<HTMLElement>) => {
if (event.key === Keys.Space) {
event.preventDefault()
toggle()
}
if (event.key !== Keys.Tab) event.preventDefault()
if (event.key === Keys.Space) toggle()
},
[toggle]
)
// This is needed so that we can "cancel" the click event when we use the `Enter` key on a button.
const handleKeyPress = React.useCallback(
(event: React.KeyboardEvent<HTMLElement>) => event.preventDefault(),
[]
)
const propsBag = React.useMemo<SwitchRenderPropArg>(() => ({ checked }), [checked])
const propsWeControl = {
id,
@@ -103,6 +114,7 @@ export function Switch<TTag extends React.ElementType = typeof DEFAULT_SWITCH_TA
'aria-labelledby': groupContext?.label?.id,
onClick: handleClick,
onKeyUp: handleKeyUp,
onKeyPress: handleKeyPress,
}
return render({ ...passThroughProps, ...propsWeControl }, propsBag, DEFAULT_SWITCH_TAG)