X-07 · Composites · App components
All elements · DocumentViewer on the Composites page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve DocumentViewer
Approving as
Dispatches office files, PDF, image and email to one frame: viewer toolbar, thumbnail rail, canvas and a properties rail. Email swaps the canvas for a header/body/attachments layout.
The specimens below are copied from
viewer.html, which shows them inside the
app shell, by bun scripts/design-pages/build-composite-pages.mjs — edit that file, not this
one; --check fails when they drift.
qf-office is the host wrapper QAction opens office files in. The QEditor editor runs in an
iframe (__embed) and draws its own ribbon, canvas and status bar — the
office mockups (X-13 OfficeApp). The window
header is the editor's title bar (owner decision Q1): the app glyph and name, the file name, the save
state and the window controls. A file therefore opens as a standalone window rather than in place.
The window is an OverlaySystem window:
a non-modal dialog.qf-overlay[data-window] driven by js/windows.js — dragged,
resized, raised and snapped (data-snap) inside the nearest [data-window-area],
which on these pages is the shell's .qf-content. Each file row carries
data-ds-open-window="viewer-office-window", so clicking it opens or raises the window. The
title bar carries the file name, the kind chip, a save indicator and the standard
.qf-window-controls.
| Axis | Values |
|---|---|
.qf-viewer[data-kind] |
pdf · image · office · email |
[data-thumbs] · [data-props] |
hidden (collapse a rail) |
__toolbar · __thumbs · __thumb[aria-current] ·
__canvas · __sheet · __props · __page
|
regions |
.qf-office[data-kind] |
document · spreadsheet · presentation · pdf — picks the sprite icon and title-bar tint |
.qf-office[data-mode] |
edit · review · view (the editor drops its ribbon panel) |
.qf-office[data-state] |
ready (default) · loading · error |
.qf-office__embed · __placeholder · __fallback |
the editor iframe · boot skeleton · unsupported state with a Download action |
__app · __glyph · __title · __filename
|
the title bar in the window header: app glyph and name, the file name button (file flyout) |
__brand · __meta · __save[data-state] |
kind icon, kind chip, saved · saving · unsaved · offline · error |
Guidance
When to use
- Use it to show a PDF, image or email attached to a record, with page thumbnails and a properties rail.
-
Use it to open an office file (document, spreadsheet, presentation) in
qf-office, the QEditor host, as its own window. - Use it when users need to page, zoom, rotate, print, download or share a file without leaving the app.
- Use the email kind to show header fields, the body and attachments of a stored message.
When to consider something else
- Use the rich-text Editor for a formatted property value rather than a file. See Editor.
- Use ObjectDisplay when the user needs the record's properties more than the file itself. See ObjectDisplay.
- Use a Dropzone to attach a file; the viewer only shows files. See Dropzone.
- Use an Empty state with a Download action when a file type has no viewer. See EmptyState.
Usability
-
Set
data-kind(pdf, image, office, email) so the frame shows the right toolbar and canvas. -
Collapse the thumbnail or properties rail with
data-thumbs="hidden"ordata-props="hidden"when space is tight. - Mark the current page thumbnail with
aria-current. -
In
qf-office, show the file name, kind chip and save state in the window header, and setdata-modeto edit, review or view. -
When the editor cannot open a file (
data-state="error"), show the fallback with Download and Try again.
- Do not open office files in place in the page; they open as an OverlaySystem window.
- Do not leave users on an endless loading skeleton; move to the error fallback.
- Do not show the save state by color alone; keep its text (Saved, Saving…, Offline).
Accessibility
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves through the viewer toolbar (zoom, page number, rotate, print, download, share, properties), the thumbnails, the canvas and the properties rail. |
| Enter or Space |
Activates the focused toolbar button; Properties toggles the rail and reports
aria-pressed.
|
| Enter | In the page number field, goes to that page. |
| Arrow Up / Arrow Down | The binding must move between thumbnails with arrow keys and show the chosen page on Enter. |
| Escape |
In a qf-office window, closes the window and returns focus to the file row that
opened it.
|
Roles and names
-
The viewer toolbar is
role="toolbar"with icon-only buttons named Zoom out, Zoom in, Rotate, Print, Download, Share and Properties; the page field is labeledPage number. -
Thumbnails are
divs in the reference; the binding must make them buttons or options with a name such asPage 2and keeparia-currenton the shown page. -
Email headers are a
<dl>; attachment chips aredata-clickablespans in the reference and must become buttons or links named with the file name and size. -
The office iframe has a
titlenaming the editor and file, such asDocument editor: Assessment report CS-2041.docx. -
While
data-state="loading", the binding should setaria-busy="true"on the host and expose theStarting the editor…text.
Focus
- Opening a file window moves focus into it; closing returns focus to the file row.
- Changing page from a thumbnail must not move focus to the canvas unless the user asks.
- On error, move focus to the fallback's heading or Download button.
Other requirements
- Images need a text alternative from the file's title or description (1.1.1); PDFs must be tagged or offered as an accessible alternative (Section 508 E205.4).
- Announce save-state changes and the switch from loading to error in a polite live region (4.1.3).
- Zoomed pages may scroll in two directions; the toolbar and rails must still reflow at 320 CSS pixels (1.4.10).
- Toolbar icon buttons must meet 24 by 24 CSS pixels (2.5.8).
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (5 rows) |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (5 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- viewer --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
| Source | css/classic/composites/documents.css |
|---|---|
| Specimens also use | Avatar · Box · Button · Card · Chip · Divider · EmptyState · Icon · List · ObjectDisplay · Overlay · Skeleton · Table · Text · Toolbar |
| Sprites | sprites/icons.svg · sprites/office-icons.svg |
| React | Not yet available: the React binding has not started. |
Latest updates
| Date | Version | Breaking | Description |
|---|---|---|---|
| 2026-10-02 | 0.1 | No | Retire the vendor imitation in X-07; qf-office hosts the editor |