import type { DesignTokens, SemanticTree } from "@design-parity/core"; /** A request to capture one HTML export's layout. */ export interface LayoutRequest { /** Absolute path to the HTML export to measure. */ htmlPath: string; /** CSS width to render at — the design's dp width. Defaults to 411. */ widthDp?: number; /** CSS height to render at. Defaults to 914. */ heightDp?: number; } /** Captures a reference layout tree, or `undefined` when it can't. */ export type LayoutExtractor = (req: LayoutRequest) => Promise; /** * Resolve a Chrome candidate to an **absolute** executable path, or `undefined` * when it can't be found. puppeteer-core `existsSync`s the `executablePath` it's * given and rejects anything that isn't a real path — so a bare command name * like `google-chrome-stable` (resolvable only via `PATH`) must be looked up * here first, or every candidate throws and the layout capture silently no-ops. * An absolute candidate is used as-is when it exists; a bare name is searched * across `PATH`. */ export declare function resolveExecutable(candidate: string, env?: NodeJS.ProcessEnv): string | undefined; /** * The element's resolved CSS that maps to design spec — read from * `getComputedStyle` in the page, carried out as raw strings and parsed in * {@link treeFromRects} (so the parsing is unit-testable without a browser). */ export interface RawStyle { paddingTop: string; paddingRight: string; paddingBottom: string; paddingLeft: string; borderRadius: string; fontFamily: string; fontSize: string; fontWeight: string; lineHeight: string; color: string; } /** The raw per-element record pulled out of the page. */ interface RawRect { label: string; role: string | null; x: number; y: number; w: number; h: number; /** Resolved computed style for the spec overlays (absent in older captures). */ style?: RawStyle; } /** * Default extractor: render the export headlessly via `puppeteer-core` and read * the bounds of every text leaf (an element with text and no element children) * plus every "accessible object" — a control/graphic the a11y tree exposes even * without text, i.e. an element carrying a `role` / `aria-label` or a native * interactive/graphic tag (`button`, `a[href]`, `img`) — into a flat tree. That * second class is what boxes the icon buttons / switches the candidate already * reports as Compose `Role` nodes. Returns `undefined` if `puppeteer-core` * isn't installed or no Chrome launches. */ export declare const puppeteerLayoutExtractor: LayoutExtractor; /** * Map an element's resolved style to the spec {@link DesignTokens} the report's * overlays read — typography (face/size/weight/line-height), foreground colour, * uniform padding, and corner radius. Values are in CSS px, i.e. dp at the * extractor's `deviceScaleFactor: 1`, so they share the reference bounds' unit. * Returns `undefined` when the style yields nothing usable. */ export declare function tokensFromStyle(style: RawStyle | undefined): DesignTokens | undefined; /** * Build a flat {@link SemanticTree} from raw element rects (rounded to dp). When * the capture `frame` (the render viewport, in dp) is supplied it is stamped on * the root as `bounds`, so the diff engine can read the reference's coordinate * extent and normalise the candidate's render-pixel geometry into this dp space * (the two sides render at different densities). Omitting it leaves the root * unbounded, so the diff treats the trees as already sharing a space. * * Each rect's resolved {@link RawStyle} (when captured) becomes the node's spec * `tokens` — padding/radius/typography/colour — so the report's annotation * overlays light up on the reference panel, not just the candidate. */ export declare function treeFromRects(rects: RawRect[], frame?: { width: number; height: number; }): SemanticTree; export {}; //# sourceMappingURL=layout-extractor.d.ts.map