Easy Accessible Click Handlers

If you add a click event to a non-interactive html element such as a div you should also add keyboard support. For interactive elements like a button this is already taken care of by the browser.

If you use eslint-plugin-jsx-a11y you will see this war…

If you add a click event to a non-interactive html element such as a div you should also add keyboard support. For interactive elements like a button this is already taken care of by the browser.

If you use eslint-plugin-jsx-a11y you will see this warning when you add an onClick event:

71:13  warning  Visible, non-interactive elements with click handlers must have at least one keyboard listener jsx-a11y/click-events-have-key-events

To get rid of this warning, my default approach is to add an additional handler for onKeyDown, filter for the enter key and trigger the same event as I have for onClick.

Additionally I add the role and tabIndex attributes as recommended.

function handleClick() { setWhatever(true) }

function handleKeyDown(e) {
  if (e.keyCode === 13) {
    handleClick();
  }
}

return <div
  role={'button'}
  tabIndex={0}
  onClick={handleClick}
  onKeyDown={handleKeyDown}
>Click me!</div>

In comparison to a button this adds quite lot of code and markup and makes simple components often look more complex than they really are:

function handleClick() { setWhatever(true) }

return <button onClick={handleClick}>Click me!</button>

To avoid this, you can add a simple helper function that returns all required attributes, I called mine accessibleOnClick:

export function filterKeyEnter(handler) {
  return e => {
    if (e.keyCode === 13) {
      handler(e);
    }
  }
}

export function accessibleOnClick(handler) {
  return {
    role: 'button',
    tabIndex: tabIndex || 0,
    onKeyDown: filterKeyEnter(handler),
    onClick: handler
  }
}

In your JSX you can now use the spread opperator to add all attributes returned by accessibleOnClick.

function handleClick() { setWhatever(true) }

return <div
{...accessibleOnClick(handleClick)}
>Click me!</button>

This is one of my favorite helper functions and I use it on a regular basis.

Do you have a similar/different approach for this type of click handlers? Let me know!


Print Share Comment Cite Upload Translate
APA
Andreas Riedmüller | Sciencx (2024-03-28T17:42:28+00:00) » Easy Accessible Click Handlers. Retrieved from https://www.scien.cx/2021/06/14/easy-accessible-click-handlers/.
MLA
" » Easy Accessible Click Handlers." Andreas Riedmüller | Sciencx - Monday June 14, 2021, https://www.scien.cx/2021/06/14/easy-accessible-click-handlers/
HARVARD
Andreas Riedmüller | Sciencx Monday June 14, 2021 » Easy Accessible Click Handlers., viewed 2024-03-28T17:42:28+00:00,<https://www.scien.cx/2021/06/14/easy-accessible-click-handlers/>
VANCOUVER
Andreas Riedmüller | Sciencx - » Easy Accessible Click Handlers. [Internet]. [Accessed 2024-03-28T17:42:28+00:00]. Available from: https://www.scien.cx/2021/06/14/easy-accessible-click-handlers/
CHICAGO
" » Easy Accessible Click Handlers." Andreas Riedmüller | Sciencx - Accessed 2024-03-28T17:42:28+00:00. https://www.scien.cx/2021/06/14/easy-accessible-click-handlers/
IEEE
" » Easy Accessible Click Handlers." Andreas Riedmüller | Sciencx [Online]. Available: https://www.scien.cx/2021/06/14/easy-accessible-click-handlers/. [Accessed: 2024-03-28T17:42:28+00:00]
rf:citation
» Easy Accessible Click Handlers | Andreas Riedmüller | Sciencx | https://www.scien.cx/2021/06/14/easy-accessible-click-handlers/ | 2024-03-28T17:42:28+00:00
https://github.com/addpipe/simple-recorderjs-demo