28

I used the following jsx to construct an entry in a FAQ table:

  <li key={faqKey} className={styles.entry} onClick={handleExpandFn}>
    <div>
      <span className={`icon-next ${questionClassname}`} />
      <span className={styles['question-text']}>{faqEntry.question}</span>
    </div>
    {faqEntry.answer}
  </li>

The idea is that when a user click on the entry, it will toggle the open state of the entry. In the other word, when a user clicks on an open FAQ entry, it will close it. Otherwise it will open it.

However the li tag triggers this eslint violation: Visible, non-interactive elements should not have mouse or keyboard event listeners jsx-a11y/no-static-element-interactions

Unfortunately I don't think there is alternative way to the above html markup. Since it is jsx, it also does not allow override such as // eslint-disable-line jsx-a11y/no-static-element-interactions (The inline comment will be printed out to the web page)

So how I can work around it? Happy to use different jsx markup or jsx eslint override

Anthony Kong
  • 37,791
  • 46
  • 172
  • 304

9 Answers9

93

For those who are looking for a workaround, use role="presentation" in your tag.

Prasanna
  • 4,125
  • 18
  • 41
14

Here's how you could revise the markup to be semantically appropriate and get the onclick off the <li>

<li key={faqKey} className={styles.entry}>
  <h3>
    <button type='button' onClick={handleExpandFn}>
      <span className={`icon-next ${questionClassname}`} />
      <span className={styles['question-text']}>{faqEntry.question}</span>
    </button>
  </h3>
  <div className='add_a_panel_class_name_here'>
    {faqEntry.answer}
  </div>
</li>

So with the above: the <h3> will make the titles of the FAQs easily searchable by screen reader users that are navigating by headings

placing the <button> inside of the <h3> gives you the appropriate element to attach a click event to (you want to use a button here because you're toggling state. an <a> should be used if you were going to a new page. You also don't need to add a tabindex to a button as they are inherently focusable).

There are some additional steps you'd likely want to implement, using ARIA expanded and controls attributes on the button, but the above should get you to a good base for moving beyond your error.

scottohara
  • 727
  • 4
  • 11
9

You could put eslint-disable-line in the jsx

  <li // eslint-disable-line jsx-a11y/no-static-element-interactions
    key={faqKey} 
    className={styles.entry} 
    onClick={handleExpandFn}
   >
    <div>
      <span className={`icon-next ${questionClassname}`} />
      <span className={styles['question-text']}>{faqEntry.question}</span>
    </div>
    {faqEntry.answer}
  </li>

Another option, add role='presentation'

  <li 
    key={faqKey} 
    className={styles.entry} 
    onClick={handleExpandFn} 
    role='presentation'
  >
    <div>
      <span className={`icon-next ${questionClassname}`} />
      <span className={styles['question-text']}>{faqEntry.question}</span>
    </div>
    {faqEntry.answer}
  </li>
Mark Swardstrom
  • 17,217
  • 6
  • 62
  • 70
8

One solution I can remember is to use an anchor element with tab-index.

<a style={{display: 'list-item'}} tabIndex={-42} key={faqKey} className={styles.entry} onClick={handleExpandFn}>
  <div>
    <span className={`icon-next ${questionClassname}`} />
    <span className={styles['question-text']}>{faqEntry.question}</span>
  </div>
  {faqEntry.answer}
</a>
JD Hernandez
  • 1,785
  • 1
  • 20
  • 29
  • Thx for the answer. What is a sensible `tabIndex` number? Any integer? – Anthony Kong Apr 11 '17 at 09:33
  • You can probably use the index of the item if the data comes from an array. – JD Hernandez Apr 11 '17 at 14:24
  • 1
    The warning is gone because the `onClick` attribute is moved from a static/non-interactive element (i.e. `
  • `), to an interactive element (i.e. ``. Here is the [W3C reference](https://dev.w3.org/html5/pf-summary/interactive-elements.html) for interactive html elements. – JD Hernandez Jun 07 '17 at 01:29