Add typography roles, text primitives, fontkit measurer and layout lint

Txt always sets an absolute line height; RenderTxt never does. Row pins
every cell and stacks when the fill column would be too narrow. IdText and
FitText shrink then chunk or truncate. The fontkit measurer matches react-pdf
text widths exactly. A TypeScript-AST lint test enforces the layout rules
(no lineHeight outside Txt, no non-literal fixed/wrap/minPresenceAhead,
flexGrow needs flexBasis, no stray absolute positioning).
This commit is contained in:
2026-10-04 04:48:19 +05:30
parent 92ba3d9590
commit 40aa3e05d9
22 changed files with 1375 additions and 34 deletions
+25
View File
@@ -0,0 +1,25 @@
import { roleToken } from "../fonts/roles";
import { Txt, type TxtProps } from "./Txt";
export interface TrackedProps extends Omit<TxtProps, "align"> {
align: "right" | "center";
}
/**
* textkit adds letterSpacing after every glyph, the last one included, so right- and centre-aligned
* tracked text sits one tracking step too far left. This cancels it with a negative margin: the full
* step on the right edge for `right`, half a step each side for `center` (shifting the box right by
* half a step).
*
* HAZARD: the Text box now overhangs its parent by up to one tracking step. Overflow and safe-zone
* audits must measure ink (glyph extents), not boxes, or they flag it.
*/
export function Tracked({ align, style, ...rest }: TrackedProps) {
const token = roleToken(rest.role);
const step = (token.tracking ?? 0) * token.size;
const margin =
align === "right"
? { marginRight: -step }
: { marginLeft: step / 2, marginRight: -step / 2 };
return <Txt {...rest} align={align} style={{ ...margin, ...style }} />;
}