# Source Citation List

Source Citation List [#source-citation-list]

The **SourceCitationList** extends `Sources` for in-message attribution. It renders retrieved RAG passages behind a collapsible "Show N sources" toggle, each with a numbered badge, a similarity score (flat text + radial confidence ring via `ConfidenceRing`), and clamped body text with a staggered fade-in. Data source: a `Source[]` (`{ text, score }`) from `useSemanticSearch` / `useAnswerQuestion` / `useAskDocument`.

Preview [#preview]

```tsx
'use client';

/**
 * @file source-citation-list-demo.tsx
 * @description Docs preview for `SourceCitationList`. Renders an assistant
 * answer with a collapsible "Show N sources" attribution, each with a radial
 * confidence ring.
 */
import {
  SourceCitationList,
  type CitationSource,
} from '@/components/source-citation-list';

const SOURCES: CitationSource[] = [
  {
    title: 'handbook.pdf, p.12',
    text: 'After the first model download, all inference runs locally with no network access required.',
    score: 0.93,
  },
  {
    title: 'faq.md',
    text: 'Your data never leaves the device. There is no telemetry and no API keys.',
    score: 0.78,
  },
  {
    title: 'architecture.md',
    text: 'Vector search and embeddings execute in the browser via WebGPU or WASM.',
    score: 0.65,
  },
];

export default function SourceCitationListDemo() {
  return (
    <div className="w-full max-w-xl rounded-lg border border-border bg-card p-4 text-card-foreground">
      <p className="text-sm">
        Yes, LocalMode works fully offline after the initial download, and your
        data stays on the device.
      </p>
      <SourceCitationList sources={SOURCES} defaultOpen />
    </div>
  );
}
```

Installation [#installation]

```bash
npx shadcn@latest add @localmode/ui/conversation/source-citation-list
```

Data source & dependencies [#data-source--dependencies]

**Data source:** renders a `Source[]` (`{ text, score }`) you pass — works with any backend. Recommended producer: `useSemanticSearch` / `useAnswerQuestion` / `useAskDocument` from `@localmode/react` (on-device, optional).

* `clsx` + `tailwind-merge` — via the shared `cn()` util (installed automatically as a registry dependency)

Files installed [#files-installed]

* `source-citation-list.tsx` — `SourceCitationList` + `ConfidenceRing`
* `lib/utils.ts` — the `cn()` helper (if not already present)

Props [#props]

**SourceCitationList**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `sources` | `array` | — | **Required.** The retrieved sources to attribute. |
| `defaultOpen` | `boolean` | `false` | Open by default. |

Examples [#examples]

Attribute an answer [#attribute-an-answer]

```tsx
import { SourceCitationList } from '@/components/source-citation-list';

<SourceCitationList
  sources={results.map((r) => ({ title: r.metadata.title, text: r.text, score: r.score }))}
/>
```

Customization [#customization]

The `ConfidenceRing` is a dependency-free SVG — reuse it standalone for any 0–1 score. Adjust the `line-clamp` or the stagger delay in the copied file.

These primitives are presentational and hook-driven: they render props and emit callbacks, holding only local view state. The orchestration state (e.g. `useSemanticSearch`) lives in your app. Every surface uses shadcn/ui CSS-variable utilities, so it inherits your theme — restyle the copied file freely.