New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SafeAnchor a11y - Provide keydown handler for "space" #2697
SafeAnchor a11y - Provide keydown handler for "space" #2697
Conversation
If `onKeyDown` prop is supplied, prefer that If no `onKeyDown` supplied, handle "space" with the `onClick` handler. Test that space bar calls click handler.
src/SafeAnchor.js
Outdated
@@ -55,8 +58,14 @@ class SafeAnchor extends React.Component { | |||
} | |||
} | |||
|
|||
handleKeyDown(event) { | |||
if (keycode(event) === 'space') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just do
event.key === ' '
src/SafeAnchor.js
Outdated
@@ -74,6 +83,7 @@ class SafeAnchor extends React.Component { | |||
<Component | |||
{...props} | |||
onClick={this.handleClick} | |||
onKeyDown={onKeyDown || this.handleKeyDown} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably chain them
src/SafeAnchor.js
Outdated
@@ -55,8 +58,14 @@ class SafeAnchor extends React.Component { | |||
} | |||
} | |||
|
|||
handleKeyDown(event) { | |||
if (keycode(event) === 'space') { | |||
this.handleClick(event); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably preventDefault
here regardless to prevent scrolling?
src/SafeAnchor.js
Outdated
@@ -74,6 +83,7 @@ class SafeAnchor extends React.Component { | |||
<Component | |||
{...props} | |||
onClick={this.handleClick} | |||
onKeyDown={onKeyDown || this.handleKeyDown} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need to do this if the element is actually <button>
Chain own-props `onKeyDown` with space handler
👍 @taion |
src/SafeAnchor.js
Outdated
const { componentClass: Component, disabled, onKeyDown, ...props } = this.props; | ||
|
||
const handleKeyDown = Component === 'a' ? | ||
createChainedFunction(this.handleKeyDown, onKeyDown) : onKeyDown; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be more performant to do this in the constructor, but if the onKeyDown
prop were changed after the component mounted, the handler wouldn't update. Don't see another way to do this without breaking backwards compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, sorry, i take that back – i forgot that using <button>
was handled upstream in <Button>
. you don't need to check for a
here
src/SafeAnchor.js
Outdated
@@ -55,8 +58,18 @@ class SafeAnchor extends React.Component { | |||
} | |||
} | |||
|
|||
handleKeyDown(event) { | |||
event.preventDefault(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only if key is space
src/SafeAnchor.js
Outdated
const { componentClass: Component, disabled, onKeyDown, ...props } = this.props; | ||
|
||
const handleKeyDown = Component === 'a' ? | ||
createChainedFunction(this.handleKeyDown, onKeyDown) : onKeyDown; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, sorry, i take that back – i forgot that using <button>
was handled upstream in <Button>
. you don't need to check for a
here
.find('a') | ||
.trigger('keyDown', { key: ' ', preventDefault() {} }); | ||
|
||
handleClick.should.have.been.calledOnce; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expect(handleClick).to.have.been.calledOnce
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're equivalent, I was following the pattern of the "it forwards onclick" test https://github.com/andy-j-d/react-bootstrap/blob/b8800dbba51e86ed4bdd34c046f820a67194029c/test/SafeAnchorSpec.js#L39
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah this is fine as long as we're not using assert – i prefer expect
but consistency has some value
.find('a') | ||
.trigger('keyDown', { key: ' ', preventDefault() {} }); | ||
|
||
handleClick.should.have.been.calledOnce; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah this is fine as long as we're not using assert – i prefer expect
but consistency has some value
@jquense thoughts? |
IfonKeyDown
prop is supplied, prefer that.If SafeAnchor renders an
a
tag, supply onKeyDown handler for "space" that calls theonClick
handler.Test that space bar calls click handler.
Addresses #2681