stream-chat-angular icon indicating copy to clipboard operation
stream-chat-angular copied to clipboard

Usage of `div` elements as buttons

Open arnautov-anton opened this issue 2 years ago • 2 comments

Probably not ideal for the accessibility but open for debate. Here are the places I stumbled upon "untabbable" buttons (there might be more):

  • Modal "close" button
  • MessageAction buttons (reply, reaction...)
  • Attachments in file preview list (retry upload and remove upload)

arnautov-anton avatar Jul 21 '22 22:07 arnautov-anton

Thanks Anton, we should remove those, I know React had a cleanup for them, but Angular didn't. Will leave this after the release though.

szuperaz avatar Jul 25 '22 07:07 szuperaz

Good point, but there's an alternative. Instead of replacing all divs with buttons and cancelling the default button styles, you can add this directive to all non-interactive-by-default elements and they will become fully interactive/accessible.

import { Directive, ElementRef, HostBinding, HostListener, Input } from '@angular/core'

@Directive({
  selector: '[appInteractive]',
  host: { role: 'button' }
})
export class InteractiveElementDirective {
  @Input() appInteractive: boolean | ''

  get isInteractive(): boolean {
    return this.appInteractive !== false
  }

  @HostListener('keydown.enter', ['$event'])
  @HostListener('keydown.space', ['$event'])
  handleEnterKeydown(event: MouseEvent & { currentTarget: HTMLElement }): void {
    if (this.el.nativeElement === event.target && this.isInteractive) {
      event.currentTarget.click()
    }
  }

  @HostBinding('tabindex')
  get tabIndex() {
    return this.isInteractive ? 0 : -1
  }

  constructor(private el: ElementRef) {}
}

ilyakonrad avatar Mar 29 '24 13:03 ilyakonrad