Marble UI
← Components

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>

PropTypeDefaultDescription
index *requirednumber—
source *requiredSource—

<Sources>

Source list under an answer: compact chips or numbered cards.

PropTypeDefaultDescription
items *requiredSource[]—
classNamestring—
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" />
  • Sources numbers items by array order, so give each Citation the matching index. snippet only appears in the citation preview.
  • chips (default) show the number and domain; cards add the title in a two-column grid and read better with a screen reader.
  • MarkdownResponse only 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
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