Skip to content
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

Merged

Conversation

andrewdushane
Copy link
Contributor

@andrewdushane andrewdushane commented Jul 10, 2017

If onKeyDown prop is supplied, prefer that.
If SafeAnchor renders an a tag, supply onKeyDown handler for "space" that calls the onClick handler.
Test that space bar calls click handler.

Addresses #2681

If `onKeyDown` prop is supplied, prefer that
If no `onKeyDown` supplied, handle "space" with the `onClick` handler.
Test that space bar calls click handler.
@@ -55,8 +58,14 @@ class SafeAnchor extends React.Component {
}
}

handleKeyDown(event) {
if (keycode(event) === 'space') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just do

event.key === ' '

@@ -74,6 +83,7 @@ class SafeAnchor extends React.Component {
<Component
{...props}
onClick={this.handleClick}
onKeyDown={onKeyDown || this.handleKeyDown}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably chain them

@@ -55,8 +58,14 @@ class SafeAnchor extends React.Component {
}
}

handleKeyDown(event) {
if (keycode(event) === 'space') {
this.handleClick(event);
Copy link
Member

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?

@@ -74,6 +83,7 @@ class SafeAnchor extends React.Component {
<Component
{...props}
onClick={this.handleClick}
onKeyDown={onKeyDown || this.handleKeyDown}
Copy link
Member

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>

AJD added 2 commits July 10, 2017 14:38
Chain own-props `onKeyDown` with space handler
@andrewdushane
Copy link
Contributor Author

👍 @taion

const { componentClass: Component, disabled, onKeyDown, ...props } = this.props;

const handleKeyDown = Component === 'a' ?
createChainedFunction(this.handleKeyDown, onKeyDown) : onKeyDown;
Copy link
Contributor Author

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.

Copy link
Member

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

@@ -55,8 +58,18 @@ class SafeAnchor extends React.Component {
}
}

handleKeyDown(event) {
event.preventDefault();
Copy link
Member

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

const { componentClass: Component, disabled, onKeyDown, ...props } = this.props;

const handleKeyDown = Component === 'a' ?
createChainedFunction(this.handleKeyDown, onKeyDown) : onKeyDown;
Copy link
Member

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;
Copy link
Contributor

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 ?

Copy link
Contributor Author

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

Copy link
Member

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;
Copy link
Member

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

@taion
Copy link
Member

taion commented Aug 26, 2017

@jquense thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants