Components

Feed

Headless WAI-ARIA feed primitives for focusable article streams whose content may load or change while users read.

When to Use

Use Feed for a stream of articles—such as activity, news, or social posts—when keyboard users need to move article by article and new items may load. Use List for a static set without feed navigation. Pair Feed with Virtualizer only when large collections require windowing; Feed itself does not fetch or virtualize.

Features

  • Implements feed and article roles.
  • Supports known totals and unknown/infinite size announcements.
  • Normalizes zero-based indexes to one-based positions.
  • Exposes loading or mutation state with aria-busy.
  • Implements article and outside-feed keyboard movement.
  • Preserves native props and supports custom composition.

Import

import { Feed } from "@flowstack-ui/atom";

Anatomy

<Feed.Root>
  <Feed.Item />
</Feed.Root>

useFeedContext()

API Reference

Root

Renders a div feed by default, provides total-size context, and handles keys for its direct article children.

PropTypeDefault
busybooleanfalse
setSizenumber | "unknown"-
asChildbooleanfalse
renderRenderProp-

Positive finite sizes are truncated to integers. "unknown" is exposed to ARIA as -1.

ARIA attributeValues
role"feed"
aria-busy"true" while busy
Data attributeValues
[data-slot]"feed"
[data-busy]Present while busy

Item

Renders a focusable article. position is one-based; zero-based index is converted to one-based. A local setSize overrides Root.

PropTypeDefault
positionnumber-
indexnumber-
setSizenumber | "unknown"Root setSize
asChildbooleanfalse
renderRenderProp-
ARIA attributeValues
role"article"
aria-posinsetNormalized one-based position
aria-setsizeNormalized total or -1 when unknown

Item defaults tabIndex to 0; a native tabIndex override is preserved.

Data attributeValues
[data-slot]"feed-item"
[data-position]Normalized position
[data-setsize]Normalized total or "unknown"

useFeedContext

Returns Root's { busy, setSize } state and throws outside Root.

Examples

Known Article Stream

import { Feed } from "@flowstack-ui/atom";

const updates = [
  { id: "1", title: "Build finished", summary: "Version 2 is ready." },
  { id: "2", title: "Review requested", summary: "Ada requested your review." },
];

export function ActivityFeed() {
  return (
    <Feed.Root setSize={updates.length} aria-label="Activity updates">
      {updates.map((update, index) => (
        <Feed.Item key={update.id} index={index}>
          <h2>{update.title}</h2>
          <p>{update.summary}</p>
        </Feed.Item>
      ))}
    </Feed.Root>
  );
}

Infinite Loading Feed

import { Feed } from "@flowstack-ui/atom";

export function LoadingFeed({ loading }: { loading: boolean }) {
  return (
    <Feed.Root setSize="unknown" busy={loading} aria-label="News">
      <Feed.Item position={41}><h2>Latest update</h2></Feed.Item>
      <Feed.Item position={42}><h2>Earlier update</h2></Feed.Item>
    </Feed.Root>
  );
}

Accessibility

Feed follows the WAI-ARIA Feed pattern. Give Root an accessible name and each Item a useful heading or other article name. Set busy while adding or replacing articles and provide accurate positions for paged or virtualized slices.

KeyDescription
PageDownMoves from the current Item or its descendant to the next Item.
PageUpMoves to the previous Item.
Ctrl+Home / Cmd+HomeMoves to the last focusable element before Root.
Ctrl+End / Cmd+EndMoves to the first focusable element after Root.

Changelog

See CHANGELOG.md.