Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

File Preview Dialog Block for Radix UI

A shared drive's document list with a full-screen viewer shown open: three drawn pages that turn with buttons or arrow keys, a Fit, 125% and 150% zoom, a details list, activity, a Copy link button and a Download that saves a text file.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Let people read a file without leaving the page it lives on, with this document viewer for React with Radix UI. It opens from the Documents page of Shelfdrive, a shared drive: the page is a drawn list of six files, the opened one shaded, under a soft scrim inside a hairline frame with a plus mark on each corner, and its header holds an outline Open Q3 planning Button. The viewer fills the screen. A title bar names "Q3 planning.pdf" with its size and who it is shared with; a toolbar holds previous and next page buttons around "1 / 3", a Toggle Group for Fit, 125% and 150%, a Copy link Copy Button and Download text, the only Shine Button. The pages are drawn: a heading, paragraphs and a table, then a bar chart, then a timeline. Beside them from md is a list of the file's details and two lines of activity; on a phone they fall under the page. Download saves a real file, "Q3 planning (text).txt", with the written text of the three pages, named for what it is. The page you stopped on is kept, and the page behind says where you were. For preview the viewer is drawn open in place when the page loads, inset so the list shows around it; the header button opens the real full-screen Dialog, with the same page and the same zoom. For drives, document tools, inboxes with attachments and any app that previews files.

FAQ

Why is the viewer already open, and what do I keep?

So you can see it without a click. On load the viewer is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Open Q3 planning button opens the real full-screen Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same PreviewBody and PreviewBar and share the block's state, so the page you turned to in the copy is the page in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

Are these real pages?

No. The three pages are drawn from shapes, hidden from screen readers, and each one is described in words for assistive technology: "Page 2 of 3: a bar chart of weekly active folders, rising over twelve weeks". The block makes no claim that a PDF was rendered. In your app render the real file with your PDF viewer or a page image, keep the page buttons and the zoom, and keep a text description or the document's own text for screen readers.

What does Download save?

A plain-text file, "Q3 planning (text).txt", that holds the written text of the three pages with a "Page 1 of 3" line above each. It is real, the browser saves it, and the button says "Download text" so nobody expects the PDF. The dialog and the polite status message say the PDF itself is not in this demo. In your app point the Download Trigger at the file's URL or a function that returns its Blob.

How do the arrow keys and the zoom work?

With focus on the page area, the arrow keys turn the page: the end-side arrow goes forward in either direction, so in a right-to-left page the left arrow is next. The buttons do the same and go quiet at the first and last page, saying so when pressed. Zoom is one group of three choices, never empty: Fit sizes the page to the viewer's height, and 125% and 150% make it wider than the area so the area scrolls both ways.

What stays local?

The page number, the zoom and the shaded row are local state; nothing is fetched, saved or sent. Copy link puts the typed link shelfdrive.example/d/q3-planning on your clipboard through the browser, and says so, or says it couldn't. In your app load the file by its id, and build the link and the details from your API.

Is it accessible from the keyboard?

Yes. The real dialog is named by its title and described by its sentence, focus stays inside until it closes, and Escape and the close button return focus to Open Q3 planning. The trigger is the button wrapped in DialogTrigger with asChild, and the dialog is controlled with open and onOpenChange. The page area is a named region you can focus and scroll, the zoom is a labelled group, and the copy shown on load moves no focus; Escape inside it and its close button close it and put focus on Open Q3 planning.