Files
2026-05-27 23:29:53 +01:00

2.4 KiB

OpenSpec Change: enterprise-react-pdf

  • Change ID: enterprise-react-pdf
  • Package: @suaveplan/react-pdf
  • Category: react
  • Target path: react/media/react-pdf
  • Status: PROPOSED
  • Date: 2026-04-24
  • Reference spec: /mnt/s/web/suaveplan/enterprise/react-pdf.md

Summary

Deliver @suaveplan/react-pdf on genesis from scratch at enterprise quality. A React PDF viewer with two tiers: a lightweight NativePdfViewer (browser <object> + toolbar) and a full PdfJsViewer powered by pdfjs-dist (text layer, annotations, page count, search, outline). The PdfViewer component selects between tiers via a mode prop. Genesis fixes the hardcoded totalPages={0} bug, adds a real page-count reader, and adds accessibility (screen-reader text layer), Storybook stories, and Playwright E2E.


Current-state audit (genesis)

Package does not exist on genesis — fresh build.


Available workspace deps on genesis

Package Role
@suaveplan/error (workspace:^) PdfError
@suaveplan/react-translate (workspace:^) i18n
zod (catalog:forms) Config schemas

External: pdfjs-dist catalog:documents, tslib catalog:build. React 18 peer.


Preserved public API surface

PdfViewer, PdfToolbar
PdfViewerProps, PdfToolbarProps

New additions for genesis

  1. PdfJsViewer — pdfjs-dist-powered: real page count, text layer, search, outline, PdfError on load failure.
  2. NativePdfViewer — preserved <object> approach (lightweight).
  3. PdfViewer mode prop — 'native' | 'pdfjs' (default 'pdfjs').
  4. Bug fix — totalPages is now real (from pdf.numPages in pdfjs mode, or 0 with a clear "unknown" label in native mode).
  5. PdfError — codes: PDF_LOAD_FAILED, PDF_RENDER_FAILED.
  6. Accessibility — text layer in pdfjs mode; aria-label on toolbar buttons.
  7. Stories — PdfViewer native + pdfjs modes, loading, error, playground.
  8. Playwright E2E — load PDF, verify page count displayed, navigate to page 2.

File layout

react/media/react-pdf/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    pdf-viewer/ (tsx + types + md + test + stories + index)
    native-pdf-viewer/ (tsx + types + md + test + index)
    pdf-js-viewer/ (tsx + types + md + test + index)
    pdf-toolbar/ (tsx + types + md + test + stories + index)
    types/
  e2e/
    pdf.spec.ts