Components/Sources

Sources

A collapsible citation list whose links never navigate on their own.

VerifiedSince 0.3.9

Sources

Basic Usage

Sources

Loading demo...

Stacked Sources

variant="stack" swaps the header globe for the leading favicons, overlapped. The reader can see which sites back an answer while the list is still collapsed, so opening it becomes optional rather than necessary.

Stacked sources in a streaming answer

Once the answer settles, the stacked header appears alongside the vertical follow-up list.

Loading demo...

Interaction Contract

  • variant="stack" draws at most the first three sources that can actually render a head, and falls back to the globe when none can rather than leaving a gap. A favicon that fails to load drops out of the stack and the next source takes its place.
  • The ring around each head comes from --tx-sources-stack-ring, defaulting to the page background. Its job is to punch a gap where the discs overlap, so repoint it when the header sits on anything other than the page colour.
  • Links never navigate on their own. A click calls preventDefault() and emits open; whether and where to open it is the host's decision. That is deliberate for sandboxed surfaces such as an Electron renderer.
  • The href is still present on the <a>, so the browser's own "open in new tab" and "copy link address" affordances keep working.
  • Open state is owned by the component and seeded from defaultOpen. It is uncontrolled — changing defaultOpen later has no effect.
  • The collapsed header defaults to Used N source(s) and pluralizes itself. labelFormatter replaces it entirely.
  • Titles fall back to the domain: an empty title shows the URL's hostname with a leading www. stripped, and a URL that URL cannot parse is shown verbatim.
  • A favicon that fails to load is recorded permanently for that source, so a broken image is not re-requested.
  • Favicons carry alt="" and aria-hidden; the accessible name comes from the title and domain text.
  • The list is an <ol> and the ordinals come from render order rather than a data field, so reordering sources renumbers them.

API

Props

NameTypeDefaultDescription
sourcesAiSourceItem[]The citations to render, where AiSourceItem is { id, url, title?, favicon? }. Required.
labelFormatter(count: number) => stringReplaces the collapsed header text. Falls back to Used N source(s).
defaultOpenbooleanfalseInitial open state. Read once, on mount.
variant'default' | 'stack''default'stack replaces the header globe with overlapped favicons.

Events

NamePayloadDescription
open(source: AiSourceItem)Emitted when a citation is clicked. The default navigation is already prevented, so the host must perform it.

Slots

TxSources exposes no slots. Each row is a fixed composition of ordinal, favicon, title and domain.

Best Practices

  • Handle open — without a listener, clicking a citation does nothing at all.
  • On desktop, open in the external browser and pass noopener rather than navigating the app window away.
  • Use stable ids: the failed-favicon record is keyed by id, so a changing id makes broken images retry.
  • Override labelFormatter for non-English surfaces; the default carries English pluralization.