Sources / Citations
Preview: Inline
Numbered inline citation ("[2]") with a hover/focus preview of the source.
Import
import { Citation, Sources } from '@marbleui/ui'Props
<Citation>
| Prop | Type | Default | Description |
|---|---|---|---|
| index *required | number | — | |
| source *required | Source | — |
<Sources>
Source list under an answer: compact chips or numbered cards.
| Prop | Type | Default | Description |
|---|---|---|---|
| items *required | Source[] | — | |
| className | string | — | |
| variant | 'chips' | 'cards' | 'chips' |
Accessibility
Keyboard interaction, focus management and ARIA semantics come from the underlying primitive: React Aria Link. Follow the primitive's docs for the full keyboard map.
Usage notes
Sources lists where an answer came from, under the MarkdownResponse in an assistant ChatMessage. Citation is the numbered inline marker that links to one source and previews it on hover, focus or long press.
const sources = [{ id: 'mdn', title: 'scroll-snap-type – MDN', url: 'https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type', snippet: 'Sets how strictly snap points are enforced.' }]
<p>Detents use native scroll snapping<Citation index={1} source={sources[0]} />.</p>
<Sources items={sources} variant="cards" />
Sourcesnumbers items by array order, so give eachCitationthe matchingindex.snippetonly appears in the citation preview.chips(default) show the number and domain;cardsadd the title in a two-column grid and read better with a screen reader.MarkdownResponseonly takes a string, so citations need text you render yourself.- All links open in a new tab. The icon is the domain’s first letter; no favicons are fetched.
Example source · show· hide
import { Citation, Sources } from './sources'
const items = [
{ id: '1', title: 'Sheet – React Aria', url: 'https://react-aria.adobe.com/Sheet', snippet: 'A Sheet is a swipeable overlay that slides in from the edge of the viewport.' },
{ id: '2', title: 'Scroll snap – MDN Web Docs', url: 'https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type', snippet: 'The scroll-snap-type property sets how strictly snap points are enforced.' },
{ id: '3', title: 'Designing bottom sheets', url: 'https://www.nngroup.com/articles/bottom-sheet/', snippet: 'Bottom sheets work best for short, secondary content.' },
{ id: '4', title: 'iOS sheets – Human Interface Guidelines', url: 'https://developer.apple.com/design/human-interface-guidelines/sheets' },
]
export const styles = {
Inline: () => (
<div className="flex w-[30rem] flex-col gap-4 text-sm text-fg">
<p>
React Aria’s Sheet uses native scroll snapping for its detents<Citation index={1} source={items[0]!} />, which keeps
momentum and rubber-banding consistent with the platform<Citation index={2} source={items[1]!} />.
</p>
<Sources items={items} />
</div>
),
Cards: () => <Sources items={items} variant="cards" className="w-[30rem]" />,
}Source: packages/ui/src/sources/sources.tsx
Catalog
- Category
- ai-agents
- Priority
- Pro
- Primitive
- composed
- React Aria
- PreviewTrigger
- Base UI
- Preview Card