Atomic Angular — Doc interne

RowGrid

A keyboard-navigable ARIA grid shell for a list of rows that hold more than one focusable control — reach for it instead of List/ListItem in that case.

RowGrid is a keyboard-navigable ARIA grid shell for a list of rows: ↑/↓ walk the rows, Tab enters the focused row's own controls, Enter activates the row. Row content is fully projected, so it fits any row shape a consumer needs. Reach for it instead of List/ListItem whenever a row holds more than one focusable control — a listbox option cannot contain one at all.

Minimal example

A row-activated results grid
sample.component.ts
import { Component } from "@angular/core";
import { RowGridComponent } from "@sinequa/galactik";

type Result = { id: string; url: string; title: string };

@Component({
  selector: "sample-component",
  imports: [RowGridComponent],
  template: `
    <row-grid [items]="results" [ariaLabel]="'Results'" (rowActivate)="open($event)">
      <ng-template let-item let-index="index">
        <a [href]="item.url">{{ item.title }}</a>
      </ng-template>
    </row-grid>
  `,
})
export class SampleComponent {
  results: Result[] = [];

  open(item: Result): void {
    /* … */
  }
}

How it works

Roles, keyboard navigation and the reflected state come entirely from @angular/aria/grid's Grid/GridRow/GridCell — RowGrid renders no ARIA behavior of its own, only the shell around it and its two outputs.

renders renders ng-template outlet keydown.enter rowActivate(item) focusin, near the end endApproached() RowGridComponent ngGridRow ngGridCell Caller-projected row content Caller

rowActivate fires on Enter because the interactive cell sits above the projected content in the DOM. endApproached fires once keyboard focus reaches the last rowsBeforeEnd rows, so an infinite-scroll list can keep growing for a keyboard user who never touches the mouse wheel.

Recipes

Infinite scroll

Loading more as focus approaches the end
sample.component.ts
import { Component } from "@angular/core";
import { RowGridComponent } from "@sinequa/galactik";

type Result = { id: string; url: string; title: string };

@Component({
  selector: "sample-component",
  imports: [RowGridComponent],
  template: `
    <row-grid [items]="results" [ariaRowCount]="totalCount" (endApproached)="loadMore()">
      <ng-template let-item>{{ item.title }}</ng-template>
    </row-grid>
  `,
})
export class SampleComponent {
  results: Result[] = [];
  totalCount = 0;

  loadMore(): void {
    /* fetch the next page and append to results */
  }
}

Options

Prop

Type

Pitfalls

What's next

On this page