react-pretext-hooks
v0.1.0
Published
React hooks and components for @chenglou/pretext text measurement & layout
Maintainers
Readme
react-pretext-hooks
React hooks and components for @chenglou/pretext — fast, accurate text measurement & layout without touching the DOM.
Install
npm install react-pretext-hooks @chenglou/pretext react@chenglou/pretext and react (>=18) are peer dependencies.
API
useTextLayout(text, font, width, lineHeight, options?)
All-in-one hook. Returns { height, lineCount }.
import { useTextLayout } from "react-pretext-hooks";
function MyComponent() {
const { height, lineCount } = useTextLayout(
"Hello world, this is a long paragraph…",
"16px/1.5 Inter",
300,
24,
);
return <div style={{ height }}>…</div>;
}usePrepared(text, font, options?)
Returns the raw PreparedText handle for power users who want to call layout() manually at multiple widths.
import { usePrepared } from "react-pretext-hooks";
import { layout } from "@chenglou/pretext";
function MyComponent({ widths }: { widths: number[] }) {
const prepared = usePrepared("Some text", "16px Inter");
const layouts = widths.map((w) => layout(prepared, w, 24));
// …
}useAutoLayout(text, font, lineHeight, ref, options?)
ResizeObserver-aware hook. Attach it to a container ref and it recomputes layout automatically when the container resizes.
import { useRef } from "react";
import { useAutoLayout } from "react-pretext-hooks";
function AutoBox() {
const ref = useRef<HTMLDivElement>(null);
const { height, lineCount, width } = useAutoLayout(
"Resizable text…",
"16px Inter",
24,
ref,
);
return (
<div ref={ref} style={{ height }}>
Resizable text…
</div>
);
}<MeasuredText>
Component wrapper around useAutoLayout. Renders a container whose height is driven by the measured text layout.
import { MeasuredText } from "react-pretext-hooks";
<MeasuredText text="Hello world" font="16px Inter" lineHeight={24}>
<p>Hello world</p>
</MeasuredText>Props:
| Prop | Type | Description |
| ------------ | ----------------------------- | ---------------------------------------------- |
| text | string | The text to measure. |
| font | string | CSS font shorthand (e.g. "16px Inter"). |
| lineHeight | number | Line height in pixels. |
| options | PrepareOptions | Optional whiteSpace / wordBreak overrides. |
| children | ReactNode | Rendered inside the container (defaults to text). |
| className | string | Class name for the wrapper element. |
| style | CSSProperties | Additional inline styles. |
| as | keyof JSX.IntrinsicElements | HTML tag to render (default "div"). |
The component also sets data-measured-height, data-measured-lines, and data-measured-width attributes on the wrapper element.
PrepareOptions
interface PrepareOptions {
whiteSpace?: "normal" | "pre-wrap";
wordBreak?: "normal" | "keep-all";
}How it works
@chenglou/pretext splits text measurement into two phases:
prepare()— the expensive step. Segments text and measures each segment via an offscreen canvas. This is memoized by the hooks so it only runs whentextorfontchange.layout()— pure arithmetic (~0.0002 ms). Computes height and line count from the prepared data for a given width. This runs on every resize or parameter change with negligible cost.
License
MIT
