angular-eslint icon indicating copy to clipboard operation
angular-eslint copied to clipboard

[@angular-eslint/template/interactive-supports-focus] Forms are erroneously marked as unfocusable

Open yktoo opened this issue 2 years ago • 2 comments

Description and reproduction of the issue

The rule erroneously marks the following form element as "Elements with interaction handlers must be focusable."

<form (ngSubmit)="submit()" (keydown.control.enter)="submit()">
...

This is wrong because the handler is perfectly useful for submitting the form when focus is in any of its controls. The form itself is not required to have a tabindex, and it isn't meant to ever be focused itself.

In my opinion, this rule should check not only the element containing the handler, but all child elements as well, and defer if any of those is focusable. Keyboard events are bubbling by default:

Keyboard events are only generated by <input>, <textarea>, <summary> and anything with the contentEditable or tabindex attribute. If not caught, they bubble up the DOM tree until they reach Document.

Versions

package version
@angular-eslint/eslint-plugin-template 16.0.3
@angular-eslint/template-parser 16.0.3
@typescript-eslint/parser 5.60.0
ESLint 8.43.0
node 18.16.0
# Please run `npx ng version` in your project and paste the full output here:
Angular CLI: 16.1.0
Node: 18.16.0
Package Manager: npm 9.5.1
OS: linux x64

Angular: 16.1.2
... animations, common, compiler, core, forms, localize
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1601.1
@angular-devkit/build-angular   16.1.1
@angular-devkit/core            16.1.0
@angular-devkit/schematics      16.1.0
@angular/cli                    16.1.0
@angular/compiler-cli           16.1.0
@schematics/angular             16.1.0
rxjs                            7.8.1
  • [x] I have tried restarting my IDE and the issue persists.
  • [x] I have updated to the latest supported version of the packages and checked my ng version output per the instructions given here.

yktoo avatar Jun 23 '23 12:06 yktoo

I am getting the same issue with the following:

<mat-toolbar>
    <div class="footer-left">
        <span>...</span>
    </div>
    <div class="footer-center">
        <span>...</span>
    </div>
    <div class="footer-right">
        <span class="ui-icon ui-info" (click)="onClickInfo()" title="About..."></span>  <!-- HERE -->
    </div>
</mat-toolbar>

kgish avatar Dec 04 '23 09:12 kgish

In addition to the examples listed, this can also apply to any place where the event listeners are listening for the events to bubble up. The individual items that can be clicked should be focusable, but the element that is listening to the bubbled events does not need to be in order for the functionality to be accessible.

Edit to add: This might not work in all situations, but just wanted to note for others that might find this, in looking at the rule page, there are a few ways to silence this error by indicating that the element does not need to be interactive to be accessible, despite the event. Depending on the use case, giving the element a role that doesn't require interactivity (i.e. presentation / none), marking the element as aria-hidden, aria-disabled, disabled, etc. are some of the potential options that allow this rule to pass. Obviously don't do any of these just to eliminate the error if it actually harms accessibility, but check the rule documentation for the full list of what markup will pass this rule.

localpcguy avatar Jan 25 '24 23:01 localpcguy

Just end up with same errors with that rule - and it does not even go away if the div has tabindex=0 or role="button" I am forced to add aria-disabled="true"... but it is not disabled - it is a clickable div based element.

div based buttons and other intractable elements are extremely common in web and found across all UX libraries.

Ketec avatar Jul 12 '24 14:07 Ketec

Same for < img >

pedroll avatar May 30 '25 17:05 pedroll

@pedroll can I ask why you have click or keyboard events on an img? It’s not the sort of element where you’d be capturing bubbled events. Should you be wrapping the img in a button for accessibility?

sandikbarr avatar May 30 '25 23:05 sandikbarr