Atomic Angular — Doc interne

RowFeed

A WAI-ARIA feed of articles for a list of cards that grows as the user scrolls — reach for it instead of RowGrid when the list is not a table.

RowFeed renders a list as a WAI-ARIA feed: a role="feed" container of <article>s. A grid without headers reads as a layout table (RGAA 5.3), so use it instead of RowGrid for a list of cards filled in as the user scrolls. Article content is fully projected through an ng-template.

Minimal example

An article-activated results feed
sample.component.ts
import { Component } from "@angular/core";
import { RowFeedComponent } from "@sinequa/galactik";

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

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

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

How it works

@angular/aria has no feed primitive, so the keyboard lives in the component: the articles are a roving tab stop (tabindex 0 on one, -1 on the others), and ↑/↓, PageUp/PageDown, Home and End move from one article to the next without wrapping. Enter on the article itself emits rowActivate. Tab walks the controls inside the article as in any page, and keys pressed on those controls keep their own meaning.

Each article carries aria-posinset and aria-setsize (ariaRowCount when the source reports a total, else the rendered length), and the feed carries aria-busy while busy is set.

Recipes

Infinite scroll

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

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

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

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

endApproached fires once keyboard focus reaches the last rowsBeforeEnd articles, so the list keeps growing for a keyboard user who never touches the mouse wheel.

Options

Prop

Type

What's next

On this page