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

[UI Framework] Add KuiKeyboardAccessible component to UI Framework. #11743

Merged

Conversation

cjcenizal
Copy link
Contributor

This React component is an analogue to the kbn-accessible-click directive introduced in #11591. You can wrap an element within this component to make it keyboard-accessible per #11513.

CC @Bargs if you're interested.

// If the developer hasn't already specified attributes required for accessibility, add them.
const props = Object.assign({
tabIndex: '0',
role: 'button',
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this role be applied only to elements that "appear as a button" to the user with a screenreader?

https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role

If I understand the intention, this container class would also be applied to anchor links in text - that doesn't seem like something we want 100% of the time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're absolutely right man. I'll update this PR. I also created #11810 so that we update kbn-accessible-click, too.

Copy link
Member

Choose a reason for hiding this comment

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

To add more to my comment, the MDN docs say this role will make screenreaders announce that the element is a button. Although, it might not be a button visually, for example we will use KuiKeyboardAccessible on an anchor tag when simply using href is not an option (i.e. the anchor tag just has an onClick).

If a screenreader announces something is a button when it is visually not a button, that seems like a negligible issue. Unless the way it is announced is totally confusing. That might be worth looking into. I'm ok with this as it is though.

// Support keyboard accessibility by emulating mouse click on ENTER or SPACE keypress.
if (accessibleClickKeys[e.keyCode]) {
// Delegate to the click handler on the element.
this.props.children.props.onClick(e);
Copy link
Member

Choose a reason for hiding this comment

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

Have you thought about making SPACE emulate click just for button elements? I’m pretty used to having SPACE act as page down unless focus is on a button. If focus is on a link, it should just be an ENTER keypress to emulate a click.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for catching this, great point.

@cjcenizal cjcenizal added the Team:Platform-Design Team Label for Kibana Design Team. Support the Analyze group of plugins. label May 15, 2017
@cjcenizal
Copy link
Contributor Author

cjcenizal commented May 16, 2017

After talking about this with @tsullivan we agreed that it doesn't make sense to use this component on an element which is acting as a link. In that case, you'd just use an anchor tag with an href. It only makes sense to use this component on an element which acts as a button or otherwise responds to the SPACE keypress, like checkboxes and radio buttons. See http://webaim.org/techniques/keyboard/ for more info on these types of elements.

Copy link
Contributor

@kimjoar kimjoar left a comment

Choose a reason for hiding this comment

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

LGTM. Seems to work as expected. Just some minor comments, feel free to skip any of them.

}, child.props, {
// We don't want to allow the child to overwrite these handlers.
onKeyDown: this.onKeyDown,
onKeyUp: this.onKeyUp,
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe throw errors in the proptypes stuff below if you override these? (It can be annoying to debug if you add onKeyUp and your function is just never called ;))

(We don't use them often, but there are a couple of keyDown uses in the app, at least)

}

applyKeyboardAccessibility(child) {
// If the developer hasn't already specified attributes required for accessibility, add them.
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe "Add attributes required for accessibility unless they are already specified"?


applyKeyboardAccessibility(child) {
// If the developer hasn't already specified attributes required for accessibility, add them.
const props = Object.assign({
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd probably write this as:

const props = {
  tabIndex: '0',
  role: 'button',
  ...child.props,
  onKeyDown: this.onKeyDown,
  onKeyUp: this.onKeyUp,
}

I just think it reads better than Object.assign

}

// Support keyboard accessibility by emulating mouse click on ENTER or SPACE keypress.
if (accessibleClickKeys[e.keyCode]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick. I think I'd prefer e.keyCode === ENTER_KEY || e.keyCode === SPACE_KEY, just to be clear. Or maybe make it a function instead isAccessibleClickKey(e.keyCode)? (I just think it reads better)

In either case I think the comment can be removed.


<KuiKeyboardAccessible>
<div onClick={() => window.alert('Div clicked')}>
Click this div, which itself contains another acessible element:&nbsp;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should specify the expectation/intention here (when you click on the inner KuiKeyboardAccessible it triggers both onClicks).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch... I think this is actually a bug. We only want the child's click handler to be called it's clicked.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, on second thought, you're right. That is the expected behavior. I need to update the SPACE and ENTER keypress handlers to mirror this behavior.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if it should trigger both or not. I was mostly commenting because it did trigger both when I played around with this and I wasn't sure if it was expected or not, so my comment was just about making intention/expectation clear in the "Click this div" text.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool, thanks. I looked into it and I decided that the onClick on the parent element should be responsible for comparing the event's target and currentTarget, instead of making that the responsibility of this component.

…ents. This mirrors mouse click behavior.

- Throw errors if KuiKeyboardAccessible child has onKeyDown or onKeyUp props.
- Refine syntax and improve comments.
@cjcenizal cjcenizal force-pushed the feature/keyboard-accessible-component branch from 7ddac92 to 8e4a06d Compare May 22, 2017 17:23
onKeyUp: this.onKeyUp,
};

return cloneElement(child, props);
Copy link
Member

Choose a reason for hiding this comment

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

pretty cool

Copy link
Member

@tsullivan tsullivan left a comment

Choose a reason for hiding this comment

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

LGTM 🎆

@cjcenizal cjcenizal merged commit 66c6db0 into elastic:master May 23, 2017
@cjcenizal cjcenizal deleted the feature/keyboard-accessible-component branch May 23, 2017 17:19
cjcenizal added a commit to cjcenizal/kibana that referenced this pull request May 23, 2017
…lastic#11743)

* Move accessibleClickKeys service into UI Framework.
* Add KuiKeyboardAccessible component to UI Framework.
* Change KuiKeyboardAccessible and kbn-accessible-click to propagate events. This mirrors mouse click behavior.
cjcenizal added a commit that referenced this pull request May 23, 2017
…11743) (#11974)

* Move accessibleClickKeys service into UI Framework.
* Add KuiKeyboardAccessible component to UI Framework.
* Change KuiKeyboardAccessible and kbn-accessible-click to propagate events. This mirrors mouse click behavior.
snide pushed a commit to snide/kibana that referenced this pull request May 30, 2017
…lastic#11743)

* Move accessibleClickKeys service into UI Framework.
* Add KuiKeyboardAccessible component to UI Framework.
* Change KuiKeyboardAccessible and kbn-accessible-click to propagate events. This mirrors mouse click behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release_note:enhancement Team:Platform-Design Team Label for Kibana Design Team. Support the Analyze group of plugins. v5.5.0 v6.0.0-alpha2 v6.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants