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
npx ritla add document-previewAlso 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.
API reference
DocumentPreview
| Prop | Type | Default | Description |
|---|---|---|---|
fileName | string | None | The file name, read left to right. Keep personal data out of it. |
pages | { content, dir?, lang?, thumbnail? }[] | None | The 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 / pageHeight | number | 560 / 792 | The page size in pixels at 100%. |
sidebar | boolean | None | Figma's Sidebar: the thumbnail rail, open by default for three pages or more, hidden on phones. |
downloadHref / downloadLabel | string | None | The download link, named with the file's type and size (“Download PDF, 240 KB”). |
onPrint | () => void | None | The print button; hidden without it. |
menu | ReactNode | None | A 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.
| Key | Action |
|---|---|
| Tab | Through the header buttons, then the thumbnails, then the page area. |
| Enter | On a thumbnail: goes to that page. |
| ArrowDownArrowUp | In 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
navnamed Pages; the current one isaria-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-16Semibold; counterslabel-14andlabel-12Medium, white on the dark bar. - Mixed-direction text
- The file name and zoom percentage are isolated LTR.