Components

Document Preview

Shows statements, invoices and contracts inside the product, with a header for pages, zoom, download and print, and a rail of page thumbnails.

Preview

Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.

Installation

SoonInstalling from the registry is coming soon. Until then, these are the commands you will run.
npx ritla add document-preview

Also works with shadcn: npx shadcn@latest add @ritla/document-preview

Dependencies it brings: @phosphor-icons/react

Installing by hand copies the component's source into your project. The source comes with a Ritla UI license, so the CLI is the short way to the same files.

Usage

import { DocumentPreview } from "@/components/ui/document-preview";
// Pages come from the app's own renderer: images made on the server, or a library such as
// pdf.js drawing each page to a canvas. The viewer only shows them.
<DocumentPreview
  fileName="Statement_Sep_2026.pdf"
  pages={pageImages.map((src, i) => ({ content: <img src={src} alt={`Page ${i + 1}`} /> }))}
  downloadHref="/statements/2026-09.pdf"
  downloadLabel="Download PDF, 240 KB"
/>

Examples

The document keeps its direction

An English statement in the viewer, without the rail. In the Arabic preview the header mirrors, and the pages stay English and left to right, because each page carries its own dir and lang.

Get the code ›

API reference

DocumentPreview

PropTypeDefaultDescription
fileNamestringNoneThe file name, read left to right. Keep personal data out of it.
pages{ content, dir?, lang?, thumbnail? }[]NoneThe pages as the app renders them, in their own language and direction. The component does not read PDFs: the app renders each page with its own tool, such as server-made images or a library like pdf.js, and passes them here (an <img>, a <canvas> or content).
pageWidth / pageHeightnumber560 / 792The page size in pixels at 100%.
sidebarbooleanNoneFigma's Sidebar: the thumbnail rail, open by default for three pages or more, hidden on phones.
downloadHref / downloadLabelstringNoneThe download link, named with the file's type and size (“Download PDF, 240 KB”).
onPrint() => voidNoneThe print button; hidden without it.
menuReactNodeNoneA More button opening a Menu with the other actions.

Accessibility

Keyboard

Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.

KeyAction
TabThrough the header buttons, then the thumbnails, then the page area.
EnterOn a thumbnail: goes to that page.
ArrowDownArrowUpIn the page area: scrolls up and down.

ARIA

  • Every header button has a name: Download, Print, Zoom in, Zoom out, Fit to width, Rotate clockwise.
  • The page number follows the scroll and is announced “Page 1 of 3”.
  • Thumbnails are buttons in a nav named Pages; the current one is aria-current.
  • The document's text stays selectable when you render it as content, not an image.

Arabic and RTL notes

Mirrors

  • The menu and file name sit on the right; download and print on the left.
  • The thumbnail rail moves to the right.
  • The page count reads «1 من 2».

Does not mirror

  • The pages themselves keep their own language and direction.
  • The file name stays left to right.
  • Rotate turns clockwise, and its icon doesn't mirror.
Numerals
The page number and zoom percentage follow the product's numerals; the document's own figures are as on its pages.
Arabic typography
File name label-16 Semibold; counters label-14 and label-12 Medium, white on the dark bar.
Mixed-direction text
The file name and zoom percentage are isolated LTR.