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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user