jsx-eslint / eslint-plugin-jsx-a11y

Static AST checker for a11y rules on JSX elements.
MIT License
3.38k stars 637 forks source link

a11y warnings on the `<dialog>` element #1000

Open matys1 opened 1 month ago

matys1 commented 1 month ago

I want to add a <dialog> element with some content and add an onClick event handler such that when the user clicks anywhere on the backdrop the <dialog> closes but if the users clicks on the content within the <dialog> it remains open. This was straight forwards to implement so I did:

const handleSidebarBackdrop = (event: React.MouseEvent<HTMLDialogElement, MouseEvent>) => {
  if (sidebarDialogRef.current && event.target === sidebarDialogRef.current) {
    sidebarDialogRef.current.close();
    setSidebarOpen(false);
  }
};

// ...
<dialog onClick={handleSidebarBackdrop} ref={sidebarDialogRef}>

I immediately get two warnings:

  1. Visible, non-interactive elements with click handlers must have at least one keyboard listener.eslint[jsx-a11y/click-events-have-key-events](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/click-events-have-key-events.md)
  2. Non-interactive elements should not be assigned mouse or keyboard event listeners.eslint[jsx-a11y/no-noninteractive-element-interactions](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/no-noninteractive-element-interactions.md)

When I check MDN <dialog> page it says: "The

HTML element represents a modal or non-modal dialog box or other interactive component, such as a dismissible alert, inspector, or subwindow."

Why is <dialog> treated as non-interactive when it obviously is interactive? Also I can add onKeyDown event handler to e.g. close the <dialog> on escape key presses to get rid of the first warning but the <dialog> already handles escape key presses natively so this is redundant.

Can someone explain why this is happening?

ljharb commented 1 month ago

Why wouldn't you set this on window, so you can capture clicks outside the dialog?

matys1 commented 1 month ago

@ljharb I was considering that as well. And I suppose that would solve the issue if you don't mind the event bubbling all the way to the window and doing it on that level. Still I find it perhaps a bit limiting that dialog is treated an non-interactive element and you cannot assign any handlers on it.

torickjdavis commented 1 month ago

@matys1, I believe there's another open issue that's relevant to this discussion; #932.