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
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
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