Skip to content

Preview Rail

A rail of compact ticks that stands in for section navigation. Hovering a tick swells it — and its neighbours, in falling steps — into a pyramid, while a floating card names the destination before you commit. Keyboard focus drives the same preview; pointer-only affordances never gate the navigation itself.

Vertical (live)

Sweep the tick column to see the pyramid form and the preview card glide between rows. Click a tick to select it — the selected tick holds the gold accent.

Wallet sections

Default preview card: label + description on a soft-radius surface.

import { PreviewRail } from "@coldharbor/ui";

<PreviewRail
  label="Wallet sections"
  defaultActiveId="overview"
  items={[
    { id: "overview", label: "Overview", description: "Total balance…" },
    { id: "activity", label: "Activity", description: "Sends, receives…" },
  ]}
  onItemSelect={(item) => router.push(`/wallet/${item.id}`)}
/>
  • --ch-fg
  • --ch-fg-faint
  • --ch-primary
  • --ch-surface
  • --ch-border
  • --ch-focus
  • --ch-radius-soft-lg

Horizontal

Ticks stand upright and grow from the baseline; the preview floats above the rail. Suits step trackers and timeline scrubbing.

Transaction lifecycle
<PreviewRail
  orientation="horizontal"
  defaultActiveId="mempool"
  highlightActive
  items={TX_STEPS}
/>
  • --ch-fg
  • --ch-fg-faint
  • --ch-primary
  • --ch-surface
  • --ch-border
  • --ch-focus
  • --ch-radius-soft-lg

Custom preview

renderPreview replaces the default card. Here: a mono amount readout per section, preview on the left (previewSide="before").

Balances by section

Rail sits right; the card slides in from the left of the ticks.

<PreviewRail
  previewSide="before"
  items={balances}
  renderPreview={(item) => (
    <div className="ch-soft-lg border border-line bg-surface p-4 shadow-raise">
      <p className="font-mono text-[10px] tracking-[0.18em] text-faint uppercase">{item.label}</p>
      <p className="mt-1 font-mono text-lg text-primary tabular-nums">{item.description}</p>
    </div>
  )}
/>
  • --ch-fg
  • --ch-fg-faint
  • --ch-primary
  • --ch-surface
  • --ch-border
  • --ch-focus
  • --ch-radius-soft-lg

Accessibility notes

Each tick is a real button (or anchor when href is set) with an aria-label; the preview layer is aria-hidden decoration. Keyboard focus-visible swells the pyramid exactly like hover, and reduced motion collapses all springs to instant transitions.

Links instead of buttons

href turns each tick into an anchor; aria-current='page' marks the selection.

  • --ch-fg
  • --ch-fg-faint
  • --ch-primary
  • --ch-surface
  • --ch-border
  • --ch-focus
  • --ch-radius-soft-lg