Skip to content

feat(pdf): add a pdfmake-based PDF toolkit - #317

Open
gcutrini wants to merge 1 commit into
v4.xfrom
feature/pdf-toolkit-v4
Open

feat(pdf): add a pdfmake-based PDF toolkit#317
gcutrini wants to merge 1 commit into
v4.xfrom
feature/pdf-toolkit-v4

Conversation

@gcutrini

Copy link
Copy Markdown
Contributor

Ref: https://app.clickup.com/t/86bbf0d90

Adds src/utils/pdf — a React-agnostic PDF toolkit on pdfmake (createDocument, resolveFont, imageDataUrl, downloadBlob, field, badge). pdfmake is an optional peer; the toolkit never imports it, the consumer injects one instance.

Why: react-pdf renders through react-reconciler. React 19 commits the reconciler container asynchronously, but react-pdf reads container.document.props synchronously right after updateContainer — so under React 19 it reads null and throws (Cannot read properties of null (reading 'props'), upstream diegomura/react-pdf#3223); under React 17/18 the commit was synchronous and never raced. Our stack spans React 17/18 (legacy widgets) and React 19 (the Next event site), so PDF generation broke on React 19. pdfmake has no reconciler, so it sidesteps this entirely.

Add a React-agnostic PDF toolkit under src/utils/pdf so PDF generation does
not depend on @react-pdf/renderer, which breaks on React 19. pdfmake has no
reconciler, so the same code runs on React 16/17 and 19.

- createDocument({ pdfMake, font, template, data }) runs a pure
  (data, { font }) => docDefinition template and returns
  download/open/print/getBlob/getBase64 (all promise-based, per pdfmake 0.3).
- resolveFont fetches a URL font and base64-embeds it (pdfmake cannot load
  fonts by URL in the browser), falling back to Helvetica.
- imageDataUrl base64s an image for the same reason.
- downloadBlob saves through a light-DOM anchor so a widget inside a shadow
  root keeps the download filename.
- field and badge are shared node builders: a label/value pair and an SVG
  badge with a CSS-like radius.

pdfmake is declared as an optional peer dependency: the toolkit only receives
a pdfMake instance and never imports pdfmake, so consumers that do not use
the toolkit need not install it.
@gcutrini
gcutrini requested a review from smarcet August 16, 2026 18:27
@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6f86325d-20fd-43c6-8426-e4e6a4ed534c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants