Search code examples
htmlangularangular-material-5

Select the second button in an angular material modal


I have a simple modal in angular material. I want to focus the yes button when it opens / is loaded. I did achieve this by setting tabindex='-1' on the no button and autoFocus: true in the provider. However this causes an UX issue where you cannot focus the no button with your keyboard. How can I focus the second button while keeping it accessible by keyboard. I also tried using tabindex, which did not appear to affect the selection. I am looking for an elegant solution ( so preferably without writing some typescript to solve it )

dialog.component.html

<h2 mat-dialog-title>Cookie request</h2>
<mat-dialog-content>Should we use a cookie to automatically log you in next time?</mat-dialog-content>
<mat-dialog-actions>
  <button mat-button [mat-dialog-close]='false' tabindex='-1'>No</button>
  <button mat-button [mat-dialog-close]="true"  tabindex='1'>Yes</button>
</mat-dialog-actions>

excerpt from app.module.ts

@NgModule({
  declarations: [...stuff],
  imports: [...stuff],
  providers: [
    {provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: {hasBackdrop: true, disableClose: true, autoFocus: true }}
  ],
  entryComponents: [
    DialogComponent
  ],
  bootstrap: [AppComponent]
})

The official docs: https://material.angular.io/components/dialog/api

Optional: how do I enforce focus to stay inside my modal until it's closed?


Solution

  • As per the Stackblitz of material dialog, you can see they are using cdkFocusInitial to focus the OK button.

    [Edit : maybe not accurate, but still interesting !] To navigate to the other focusable element (If needed), tabindex does not seems towork properly but I think your answer is here : Angular A11y

    [Edit 2] : Since some people can't access stackblitz properly, here the sample of the dialog html code:

    <h1 mat-dialog-title>Hi {{data.name}}</h1>
    <div mat-dialog-content>
      <p>What's your favorite animal?</p>
      <mat-form-field>
        <mat-label>Favorite Animal</mat-label>
        <input matInput [(ngModel)]="data.animal">
      </mat-form-field>
    </div>
    <div mat-dialog-actions>
      <button mat-button (click)="onNoClick()">No Thanks</button>
      <button mat-button [mat-dialog-close]="data.animal" cdkFocusInitial>Ok</button>
    </div>