Xzero UI
Pro library

Source cardsPro

A row of cited sources under an AI answer where cards stream in with real site marks while the model searches, the overflow collapses into a stack of favicons, hovering lifts a preview with the passage, and an inline [n] citation highlights its card.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/source-cards
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/source-cards

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { SourceCards, SourceCitation } from "@/components/xzero/source-cards/source-cards";

<SourceCards
  sources={results}            // [{ title, url, snippet, published }]
  status={searching ? "searching" : "done"}
  total={8}
  query="stripe webhook signature verification"
  duration={2100}
  onSourceClick={(source) => openReader(source.url)}
>
  <p>
    Read the raw body with <code>await request.text()</code> before parsing it <SourceCitation n={1} />
    <SourceCitation n={2} />.
  </p>
</SourceCards>

API reference

SourceCards

A row of cited sources under an AI answer. Each card shows the site's mark, its domain, the citation number and a two line title. While searching, cards stream into reserved slots under "Searching 3 of 7"; past max the rest collapse into a stack of overlapping marks ("+4 more"). Hovering or focusing a card lifts a preview with the passage, and a SourceCitation in the answer highlights its card. With no sources it renders a self-playing demo.

PropTypeDefaultDescription
sourcesSourceCardsSource[]–The sources in citation order: source 1 is cited as [1]. Append as results arrive; each new card fades into its slot. Leave out for the self-playing demo.
status"searching" | "done" | "error""done"Searching shows a spinner, a shimmering "Searching", a rolling count and reserved slots. Done shows "7 sources" and the time. Error keeps what arrived and shows "Search failed" with Retry. Done with no sources shows "No sources found".
totalnumber–How many sources the search will return. Drives "Searching 3 of 7" and reserves that many slots, so the row never shifts while it fills.
querystring–The search query, shown muted after the status while searching or when nothing was found.
durationnumber–Search time in ms, shown after the count when done ("7 sources · 2.1s").
maxnumber3Cards shown before the rest collapse into the stack. The grid has max + 1 columns on wide containers and two below 540px.
expandedboolean–Controls whether the stack is open. Pair with onExpandedChange.
defaultExpandedbooleanfalseOpens the stack on first render.
onExpandedChange(expanded: boolean) => void–Called from the stack, the Show all toggle, or a citation that points into the stack.
highlightednumber | null–Controlled highlighted source number (1-based). Uncontrolled, a citation click highlights its card for 2.6s.
onHighlightChange(n: number | null) => void–Called when a SourceCitation is clicked.
onSourceClick(source: SourceCardsSource, n: number) => void–Makes cards buttons and calls this instead of navigating, for an in-app reader or analytics. Without it cards are links that open in a new tab.
onRetry() => void–Shows Retry on error and Search again when nothing was found.
errorstring–Detail shown after "Search failed", such as "The search provider timed out after 8s."
hideStatusbooleanfalseHides the status line when your UI already shows search progress.
childrenReactNode–The answer, rendered between the status line and the cards. Its height springs as it streams so the cards glide down. SourceCitation inside it is linked to the cards.
labelstring"Sources"Accessible name of the source list.
classNamestring–Class on the root element.

SourceCitation

An inline [n] chip for the answer text, styled like the number on each card. Inside SourceCards it names its source for screen readers, turns accent while its card is highlighted, and highlights the card on click (opening the stack when needed).

PropTypeDefaultDescription
n (required)number–The 1-based source number.
onClick(event: MouseEvent<HTMLButtonElement>) => void–Extra click handler, for example to scroll the cards into view.
classNamestring–Class on the chip.

SourceCardsSource

One source.

PropTypeDefaultDescription
title (required)string–Page title as the search result shows it. Clamped to two lines on the card.
url (required)string–Full URL. The host becomes the domain and picks the mark: github.com, developer.mozilla.org, stripe.com, vercel.com, wikipedia.org and stackoverflow.com draw their real marks; anything else gets a lettered disc.
idstring–Stable key. Defaults to the URL.
sitestring–Readable site name for the preview and the stack, such as "Stripe Docs".
snippetstring–The passage the answer relied on, shown in the hover preview (four lines).
publishedstring–Short date label, such as "Oct 9, 2026".
mark"github" | "mdn" | "stripe" | "vercel" | "wikipedia" | "stackoverflow"–Forces a built in mark when the URL does not match.
iconReactNode–Custom favicon, drawn at 14px on the card and 16px in the preview.

SourceCardsSimulation

The demo SourceCards renders without sources, exported for docs and previews.

PropTypeDefaultDescription
scenario"live" | "error" | "empty""live"Live searches, streams a cited answer and tours two citations, looping until someone interacts. Error fails after two sources with Retry. Empty finds nothing and offers Search again.
classNamestring–Class on the demo panel.

Keyboard interactions

KeysAction
TabMoves through citations, the Show all toggle, each card and the stack. A focused card shows its preview.
Enter / SpaceOpens a card (or calls onSourceClick), opens the stack, or highlights a citation's card.
EscapeCloses the open preview.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in ai

Guidance for AI tools

Source cards: A row of cited sources under an AI answer where cards stream in with real site marks while the model searches, the overflow collapses into a stack of favicons, hovering lifts a preview with the passage, and an inline [n] citation highlights its card. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components