Research report
A long report built for reading: 68ch measure, a table of contents that follows you, citations that preview and jump to sources, and export.
On this page
A long report with a table of contents that follows you, citations and export.
Installation
Usage
import { ResearchReport } from "@/components/ui/chatcn/research-report"
<ResearchReport
title="How long should a line of text be on screen?"
dek="Long lines read slightly faster, shorter lines are preferred."
sources={sources}
sections={[
{
id: "summary",
title: "Summary",
blocks: [
"Print advice says 45 to 75 characters [1]. WCAG caps lines at 80 [2].",
{ type: "list", items: ["**Speed:** long lines read faster [3, 4]."] },
],
},
]}
/>Blocks are data, so the same content renders, counts its reading time and exports to Markdown. Strings are paragraphs; objects add list, quote, table, h3 and node for anything custom. Inline text supports [1] and [1, 3] citations, **bold**, *italic*, code and links.
Examples
Inside a full research run
With streaming, sections fill in as they are written, the table of contents grows with them, and the caret marks the last block.
A full run: plan, searches, sources read, then the report writes itself in with citations.
Props
| Prop | Type | Notes |
|---|---|---|
title | string | |
dek | string | One or two sentences under the title |
sections | ResearchReportSection[] | { id, title, blocks } |
sources | ResearchReportSource[] | Citation numbers index into this list, from 1 |
date | string | Meta line |
sourcesRead | number | Shows 11 sources cited of 64 read |
streaming | boolean | Caret on the last block, export waits |
density | "default" | "comfortable" | 15/24 or 16/26 prose. Default comfortable |
toc | boolean | Sticky contents when the container is at least 48 rem wide |
onCopyMarkdown, onDownload | (markdown) => void | Replace the built-in clipboard and file download |
filename | string | Download name. Defaults to the title as a slug |
actions | ReactNode | More buttons after Download |
researchReportToMarkdown({ title, dek, sections, sources }) is exported for your own export flows.
Keyboard
| Key | Action |
|---|---|
Tab | Contents links, citations, export buttons, then sources |
Enter on a contents link | Jump to the section instantly and focus its heading |
Enter on a citation | Jump to the numbered source |
| Focus on a citation | Opens its preview without animation. Esc closes it |
Accessibility
- The contents is a
navwitharia-current="location"on the section you are reading. - Sections are labelled by their headings, which take focus after a jump so screen readers continue from there.
- Each citation is a link named Source 3 and its title. Modified clicks still open the source itself.
- The copy button keeps its label and announces Copied in a live region.
Motion
- Contents clicks scroll smoothly with a pointer and instantly from the keyboard or under reduced motion.
- The active contents item changes color over 150 ms. The cited source flashes a fill for 1.6 s after a jump.
- Streamed sections fade in over 150 ms as whole blocks. Words never animate.