Citation Sources
spectrumui/citation-sourcesFreeBlock
Inline citation markers with hover previews or a footnote list.
Install it
npx shadcn@latest add https://ui.spectrumhq.in/r/citation-sources.jsonSource
1'use client';23import { cn } from '@/lib/utils';4import type { Citation } from './types';56export type CitationSourcesVariant = 'Inline' | 'Footnotes';78export interface CitationSourcesProps {9 text: string;10 citations: Citation[];11 variant?: CitationSourcesVariant;12 className?: string;13}1415export function CitationSources({16 text,17 citations,18 variant = 'Inline',19 className,20}: CitationSourcesProps) {21 const byIndex = new Map(citations.map((citation) => [citation.index, citation]));22 const parts = text.split(/(\[\d+\])/g).filter(Boolean);2324 return (25 <div className={cn('w-full max-w-[520px] text-[13.5px]', className)}>26 <p className="leading-[1.7] text-neutral-700 dark:text-neutral-300">27 {parts.map((part, index) => {28 const match = /^\[(\d+)\]$/.exec(part);29 if (!match) return <span key={index}>{part}</span>;30 const citation = byIndex.get(Number(match[1]));31 if (!citation) return <span key={index}>{part}</span>;32 return <CitationMarker key={index} citation={citation} />;33 })}34 </p>3536 {variant === 'Footnotes' && (37 <ol className="mt-4 space-y-2 border-t border-black/[0.06] pt-3 dark:border-white/[0.07]">38 {citations.map((citation) => (39 <li key={citation.id} className="flex gap-2.5 text-[12.5px] leading-[1.55]">40 <span className="grid size-[16px] shrink-0 translate-y-0.5 place-items-center rounded bg-black/[0.06] font-mono text-[9px] font-semibold text-neutral-600 dark:bg-white/[0.08] dark:text-neutral-300">41 {citation.index}42 </span>43 <span className="min-w-0">44 <span className="font-medium text-neutral-800 dark:text-neutral-200">45 {citation.title}46 </span>47 <span className="ml-1.5 font-mono text-[10.5px] text-neutral-400 dark:text-neutral-600">48 {new URL(citation.url).hostname}49 </span>50 {citation.snippet && (51 <span className="mt-0.5 block text-neutral-500 dark:text-neutral-400">52 {citation.snippet}53 </span>54 )}55 </span>56 </li>57 ))}58 </ol>59 )}60 </div>61 );62}6364function CitationMarker({ citation }: { citation: Citation }) {65 return (66 <span className="group/cite relative inline-block">67 <button68 type="button"69// … truncated
Files it writes
More from spectrumui
All 182 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Agent Planagent-plan | spectrumui | Blocks | Free | 1 dep | |
| Agent Stepsagent-steps | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Approval Cardapproval-card | spectrumui | Blocks | Free | 1 dep | |
| Chat Empty Statechat-empty-state | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Code Blockcode-block | spectrumui | Blocks | Free | 1 dep | |
| Conversation Listconversation-list | spectrumui | Blocks | Free | 1 dep | |
| Diff Viewdiff-view | spectrumui | Blocks | Free | 1 dep | |
| Error Stateerror-state | spectrumui | Blocks | Free | 1 dep |
