Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/taffy-layout-engine.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@react-pdf/layout': minor
---

Replace the Yoga layout engine with Taffy (`taffy-layout`).

Layout defaults are kept Yoga-compatible (column direction, `align-content: flex-start`, items shrink to 0), so most documents render identically. Notable changes: long texts in row containers no longer overlap, `flex: 1` items inside auto-height columns get their content height instead of collapsing, and images/SVGs without an explicit size inside rows take their intrinsic size instead of the full row width. `position: static` is treated as `relative`. The WASM module is shipped as a separate `.wasm` asset that bundlers must be able to resolve via `new URL(..., import.meta.url)`.
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
yoga-layout
lib
packages/pdfkit
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ When making changes, always include tests. Add tests in the same location where
### Code Style

- ESLint 9 with TypeScript parser, Prettier (single quotes), enforced via Husky pre-commit hooks
- Packages `yoga` and everything under `apps` are excluded from linting
- Everything under `apps` is excluded from linting

## Previewing PDFs

Expand Down
2 changes: 1 addition & 1 deletion apps/site/app/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const FEATURES = [
},
{
title: 'Layout you already know',
body: 'Yoga brings flexbox to the page: rows, columns, wrapping and absolute positioning.',
body: 'Taffy brings flexbox to the page: rows, columns, wrapping and absolute positioning.',
},
{
title: 'Beyond text',
Expand Down
4 changes: 2 additions & 2 deletions apps/site/content/docs/v4/tailwind.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ State variants — `hover:`, `focus:`, `dark:`, `group-*`, `peer-*` — describe

- Supports the CSS properties that make sense in a PDF context and are supported by react-pdf — see [valid CSS properties](/docs/v4/styling#valid-css-properties).
- Uses `pt` as the internal unit ([valid units](/docs/v4/styling#valid-units)), with `1rem = 12pt` by default. Change it with `ptPerRem`.
- react-pdf uses [Yoga](https://yogalayout.dev/) for layout, so some defaults differ from the web — `flex-direction` defaults to `column`, for example. Add `flex-row` where you need it.
- react-pdf keeps Yoga-style layout defaults (now implemented with [Taffy](https://github.com/DioxusLabs/taffy)), so some differ from the web — `flex-direction` defaults to `column`, for example. Add `flex-row` where you need it.
- Line heights are emitted unitless, since react-pdf only supports unitless `lineHeight`.
- `aspect-auto` and `line-clamp-none` warn as unsupported. react-pdf has no style value meaning "no aspect ratio" or "no clamp" — leaving the utility off is the reset.
- Intrinsic sizing (`w-fit`, `h-min`, `max-w-max`, …), `max-w-none` / `max-h-none`, and lengths in units react-pdf can't parse (`max-w-prose` is `65ch`) warn as unsupported. Yoga has no equivalent, and passing the value through would throw while laying out the document.
- Intrinsic sizing (`w-fit`, `h-min`, `max-w-max`, …), `max-w-none` / `max-h-none`, and lengths in units react-pdf can't parse (`max-w-prose` is `65ch`) warn as unsupported. react-pdf has no equivalent, and passing the value through would throw while laying out the document.
- `float-*` and `clear-*` map to react-pdf's [float support](/docs/v4/floats), which is newer and has rough edges: setting `lineHeight` on floated content breaks text wrap, and parents don't grow to contain their floats.
1 change: 0 additions & 1 deletion eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const ignoreConfig = {
'**/dist',
'**/lib',
'**/node_modules',
'**/packages/yoga/**',
'**/apps/**',
],
};
Expand Down
4 changes: 2 additions & 2 deletions packages/layout/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# @react-pdf/layout

Layout engine for react-pdf. Takes the document element tree produced by the reconciler and resolves it into an absolutely positioned page tree: it parses styles, measures text with textkit, computes flexbox layout with Yoga, resolves images and SVG, and paginates content into fixed-size pages ready for rendering.
Layout engine for react-pdf. Takes the document element tree produced by the reconciler and resolves it into an absolutely positioned page tree: it parses styles, measures text with textkit, computes flexbox layout with Taffy, resolves images and SVG, and paginates content into fixed-size pages ready for rendering.

## Installation

Expand All @@ -20,7 +20,7 @@ import layout from '@react-pdf/layout';
const layoutTree = await layout(documentTree, fontStore);
```

The default export is an async function that composes the individual resolution steps (styles, inheritance, page sizes, Yoga layout, text layout, pagination, and so on) over a document root node and returns the fully resolved tree consumed by `@react-pdf/render`.
The default export is an async function that composes the individual resolution steps (styles, inheritance, page sizes, flexbox layout, text layout, pagination, and so on) over a document root node and returns the fully resolved tree consumed by `@react-pdf/render`.

## License

Expand Down
246 changes: 0 additions & 246 deletions packages/layout/globals.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/layout/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@react-pdf/types": "^2.14.0",
"emoji-regex-xs": "^1.0.0",
"queue": "^6.0.1",
"yoga-layout": "^3.2.1"
"taffy-layout": "^3.0.0"
},
"files": [
"lib"
Expand Down
4 changes: 2 additions & 2 deletions packages/layout/src/canvas/measureCanvas.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MeasureFunction } from 'yoga-layout/load';
import { MeasureFunction } from '../taffy/measure';
import getMargin from '../node/getMargin';
import getPadding from '../node/getPadding';
import isHeightAuto from '../page/isHeightAuto';
Expand Down Expand Up @@ -103,7 +103,7 @@ const measureCtx = () => {
*/

/**
* Yoga canvas measure function
* Canvas measure function
*
* @param {Object} page
* @param {Object} node
Expand Down
Loading
Loading