Context:
I have a component that loads a <table mat-table> with a given data source. 
I have added a (keydown) function to the <tr mat-row>. 
The function allows me to shift the row highlighting up and down the rows as I press the up/down arrow keys.
Issues:
- In order for the (keydown) function to execute, I have to either click one of the table rows to set the focus, or use the Tab through multiple items to eventually focus on the table rows. 
- The (keydown) function is only changing the highlighting of the rows, and not the :focus. So if I hit the down arrow, the next row down highlights, but the :focus outline remains on the previous row. 
I've tried a few solutions, and it seems I cannot focus the <tr> tags without clicking / Tabbing. The autofocus directive is not supported for <tr> tags. Using .focus() errors out, claiming that .focus() is not a function, even if I cast it to the HTMLElement type.
Example:
let firstRow = this.dataSource.connect().value[0] as unknown as HTMLTableRowElement;
firstRow.focus();
ERROR TypeError: firstRow.focus is not a function
I have also tried applying tabIndex="0" to the mat-row, but it does not become the first tab-able element on the page.
The table is sort-able, so I am using dataSource.connect().value[0] to find the first row, rather than dataSource.data[0].
This is because dataSource.data[0] was giving the pre-sorted array, which was defeating the purpose of the up/down arrow functionality.
TS Component:
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { TableService } from '../table.service';
import { SelectionModel } from '@angular/cdk/collections';
import { TableGrid } from '../TableGrid';
@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
  @ViewChild(MatSort, { static: true }) sort: MatSort;
  dataSource: MatTableDataSource<TableGrid> = null;
  displayedColumns = [
    'locked',
    'includeRe',
    'includeMv'];
  selection = new SelectionModel<TableGrid>(false, []);
  selectedRowId = 0;
  selectedRowIndex = 0;
  constructor( private tableService: TableService) { }
  ngOnInit() {
    this.tableService.get();
    this.tableService.tableGrid
      .subscribe(result => {
        this.selectedRowId = 0;
        this.dataSource = new MatTableDataSource(result);
        this.dataSource.sort = this.sort;
        if (this.dataSource.data.length > 0) {
          this.onRowClicked(this.dataSource.data[0]);
        }
      });
  }
  onRowClicked(row) {
    this.selection.clear();
    this.selection.select(row);
    this.selectedRowId = row.id;
    this.selectedRowIndex = this.dataSource.connect().value.indexOf(row);
    this.tableService.setId(row.id, row.name, row.locked, row.isDeleteable, row.includeHistory);
  }
  tableKeydown(event: KeyboardEvent) {
    if (!this.selection.isEmpty()) {
      let newSelection;
      const currentIndex = this.selectedRowIndex;
      if (event.key === 'ArrowDown') {
        newSelection = this.dataSource.connect().value[currentIndex + 1];
      } else if (event.key === 'ArrowUp') {
        newSelection = this.dataSource.connect().value[currentIndex - 1];
      }
      if (newSelection) {
        this.selectedRowId = newSelection.id;
        this.onRowClicked(newSelection);
      }
    }
  }
}
HTML:
<div class="container">
  <div class="table-container">
    <table mat-table [dataSource]="dataSource" matSort aria-label="Elements">
      <ng-container matColumnDef="locked">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Locked</th>
        <td mat-cell *matCellDef="let row">
          <i *ngIf="row.locked === true" class="material-icons">lock</i>
        </td>
      </ng-container>
      <ng-container matColumnDef="includeRe">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>RE</th>
        <td mat-cell *matCellDef="let row">
          <i *ngIf="row.includeRe === true" class="material-icons">house</i>
        </td>
      </ng-container>
      <ng-container matColumnDef="includeMv">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>MV</th>
        <td mat-cell *matCellDef="let row">
          <i *ngIf="row.includeMv === true" class="material-icons">directions_car</i>
        </td>
      </ng-container>
      <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky:true"></tr>
      <tr mat-row tabIndex="0" *matRowDef="let row; columns: displayedColumns;"
          (click)="onRowClicked(row)"
          (keydown)="tableKeydown($event)"
          [ngClass] = "{'highlight' : row.id == selectedRowId}">
      </tr>
    </table>
  </div>
</div>
Desired Functionality:
I would like to set the :focus attribute to the first <tr> of the table on init, so that the (keydown) function is immediately usable.
I would also like to get the (keydown) function to set the :focus on the <tr> tags.
What I'm trying to avoid
I would like to avoid creating a custom focus class to reproduce the focus outline effect. I would also like to avoid disabling the focus-outline on table-rows. What I want, is to put the :focus pseudo-class on the <tr>. If this is impossible, I will consider alternatives.
I can add more info if needed, but I'm trying to keep it relatively anonymous as this is work-related.
I'm relatively new to Angular, but have developed for a few years in React. Any advice would be appreciated.
Thank you.
 
    