GetStream / stream-chat-angular

💬 Angular Chat SDK ➜ Stream Chat. Build a chat app with ease.
https://getstream.io/chat/sdk/angular/
50 stars 31 forks source link

Usage of `div` elements as buttons #354

Open arnautov-anton opened 2 years ago

arnautov-anton commented 2 years ago

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

szuperaz commented 2 years ago

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.

ilyakonrad commented 5 months ago

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) {}
}