Skip to content
Component installs need the registry setup
VegaStack Design

Recent Strip

One row of the records a person opened last, as compact cards in a sideways strip with edge fades and arrow keys, and a single line of chips on a phone.

Status
stable
Since
0.25.90
Accessibility pattern
Named region; one Tab stop, arrow keys between cards

Last updated

Install

Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for Recent Strip before installation. Retain the digest printed by this command.

pnpm exec vegastack-design verify recent-strip

Install with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.

pnpm dlx shadcn@4.21.0 add @vegastack/recent-strip

Run the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.

The same command installs the registry items it composes: @vegastack/button, @vegastack/collapsible, @vegastack/skeleton, @vegastack/use-list-nav, @vegastack/use-media-query.

Usage

import { RecentStrip } from "@/components/ui/recent-strip";

<RecentStrip
  label="Recent"
  collapsible
  open={recentOpen}
  onOpenChange={saveRecentOpen}
  linkRender={<Link href="" />}
  items={recents.map((r) => ({
    href: r.href,
    icon: <KindIcon kind={r.kind} />,
    title: r.title,
    meta: `${r.kindLabel} · ${r.when}`,
  }))}
/>;

One row of the records a person opened last, so they can jump back in without the main list being pushed down a screen. Up to max (six) compact cards — an icon tile, the title and one meta line — sit in a strip that scrolls sideways, with fades at the clipped edges and, on a mouse, buttons at the ends. On a narrow strip (under 28rem of its own width, so a phone) the cards become a single line of chips. The strip is one Tab stop; ← and → move between the cards.

Scope

  • Owns: the heading and its fold toggle, the strip's layout, scroll fades and end buttons, the card and chip shapes, the roving tab stop, the loading skeleton, and rendering nothing when empty.
  • Does not own: which records are recent, their order, their icons or meta text, or remembering whether the strip is folded — pass open/onOpenChange and keep it where the host keeps preferences.
  • Compose with: a router link through linkRender; a formatted time in the meta text (the card is one link, so meta is plain text, never a control); the list it sits above (DataList).

Examples

Recent row

Six cards; the strip scrolls past the frame with fades at the clipped edge.

Collapsible

collapsible makes the heading a toggle that folds the strip to its heading row. Control it with open/onOpenChange to remember the choice.

On a phone

Under 28rem of the strip's own width the cards become one line of chips — the icon and the title — so the list below starts in the first screen.

Loading and empty

loading keeps the heading and shows skeleton cards of the same shape. With no records the strip renders nothing, unless emptyState gives it a line to show.

Recent

Jump back in

Pages, tables and files you open show up here.

API Reference

PropTypeDefaultDescription
collapsiblebooleanfalseThe heading becomes a toggle that folds the strip away to its heading row.
defaultOpenbooleantrueWhether a collapsible strip starts open (uncontrolled).
emptyStateReact.ReactNode—What to show under the heading when there are no records. Without it an empty strip renders nothing at all.
headingRenderReact.ReactElement<unknown, string | React.JSXElementConstructor<any>><h2 />The heading element (<h3 /> under an h2 section). Its children are the label (or the toggle).
itemsRecentStripItem[][]The records, most recent first. Only the first max render.
labelstring"Recent"The strip's heading — and the toggle's name when it is collapsible.
linkRenderReact.ReactElement<unknown, string | React.JSXElementConstructor<any>><a />The element each card renders as — a router link (<Link />); it receives href, the card's classes and its content.
loadingbooleanfalseShows skeleton cards of the same shape (the heading stays) while the records load.
maxnumber6The most cards the strip shows.
onOpenChange((open: boolean) => void)—Called when the toggle opens or folds the strip — persist it to remember the choice.
openboolean—Whether a collapsible strip is open (controlled). Pair with onOpenChange.
scrollBackLabelstring"Scroll back"The name of the mouse-only button that scrolls back.
scrollForwardLabelstring"Scroll forward"The name of the mouse-only button that scrolls forward.

Data attributes and CSS variables on RecentStrip

AttributeValues
data-loading""
data-slot"recent-strip" | "recent-strip-content" | "recent-strip-empty" | "recent-strip-toggle"
data-state"closed" | "open"

RecentStripItem

PropTypeDefaultDescription
href*string—Where the card goes — rendered through linkRender (default <a />).
title*string—The record's name — the link's accessible name.
iconReact.ReactNode—The record's kind as a glyph (decorative).
idstringthe item's `href`Stable key.
metastring—One quiet line under the title on a card ("Page · 2h ago") — plain text, since the whole card is one link; it describes the link and is hidden on the phone's chips.

Accessibility

  • The strip is a region named by its heading; the cards are a list of links, each named by its title and meta line. Icons are decorative.
  • One Tab stop for the whole strip: the arrow keys move between the cards, and focusing a card scrolls it into view.
  • A collapsible heading is a button with aria-expanded, inside the heading element (headingRender, an h2 by default).
  • The scroll buttons at the ends are for the mouse only — out of the tab order and hidden from assistive technology, which reaches every card with the keys.
KeyAction
TabEnters the strip at its current card
← / →Moves to the previous or next card
Home / EndMoves to the first or last card
EnterOpens the card
Enter / SpaceOn the heading, folds or opens it
ContractStates tested
Behaviourdefault, max, collapsed, loading, empty, empty-state, link-render, keyboard-roving, overflow
Accessibilitylabeled-region, heading, keyboard, single-tab-stop, browser-accessibility-test
Visualdefault, hover, focus, collapsed, loading, chips

Do / Don't

Do
Show one Recent row of up to six records above the list, folded away when the person chooses, and render nothing when there is nothing recent.
Don't
Stack Recently viewed and Recently updated grids above the list, so the list starts a screen or more down on a phone.

On this page