import type { FigmaNode } from './parser.js'; import type { NodeBounds } from './bounds-cache.js'; export type InferredDirection = 'row' | 'column' | 'absolute'; export type InferredSource = 'figma' | 'inferred' | 'absolute'; export type AlignItems = 'flex-start' | 'center' | 'flex-end' | 'stretch'; export type JustifyContent = 'flex-start' | 'center' | 'flex-end' | 'space-between'; export type SizingBehavior = 'fixed' | 'fill' | 'hug'; export interface InferredPadding { top: number; right: number; bottom: number; left: number; } export interface InferredSelfSizing { horizontal: SizingBehavior; vertical: SizingBehavior; flex?: number; } /** Per-child margin when gap is non-uniform */ export interface ChildMargin { marginStart: number; } export interface InferredLayout { source: InferredSource; display: 'flex' | 'block' | 'none'; flexDirection?: 'row' | 'column'; gap?: number; alignItems?: AlignItems; justifyContent?: JustifyContent; padding?: InferredPadding; selfSizing?: InferredSelfSizing; position?: 'absolute'; left?: number; top?: number; right?: number; bottom?: number; childMargins?: ChildMargin[]; /** * Negative-gap / overlap pattern detected. * Parent should use position:relative, overlapping children get position:absolute. * Contains nodeIds of children that overflow the padding area. */ overlappingChildIds?: string[]; } /** Minimal child representation for inference (uses absolute bounds) */ export interface ChildBounds { nodeId: string; x: number; y: number; width: number; height: number; } /** * Group numeric values that are within `epsilon` of each other. * Returns an array of groups, each group is an array of original indices. */ export declare function groupByProximity(values: number[], epsilon: number): number[][]; /** * Detect whether children are arranged as a row, column, or freely positioned. */ export declare function detectDirection(children: ChildBounds[], epsilon?: number): InferredDirection; export interface GapResult { uniform: boolean; gap?: number; margins?: ChildMargin[]; } /** * Compute gap between sorted children along the given direction. * Returns uniform gap if all gaps are similar, otherwise per-child margins. */ export declare function inferGap(sortedChildren: ChildBounds[], direction: 'row' | 'column'): GapResult; /** * Infer cross-axis alignment of children. * For row → checks y-axis alignment. For column → checks x-axis alignment. */ export declare function inferAlignment(children: ChildBounds[], parentBounds: NodeBounds, direction: 'row' | 'column', padding?: InferredPadding): AlignItems; /** * Infer main-axis justify-content. */ export declare function inferJustify(sortedChildren: ChildBounds[], parentBounds: NodeBounds, direction: 'row' | 'column', padding?: InferredPadding): JustifyContent; /** * Infer container padding from the gap between parent bounds and outermost children. */ export declare function inferPadding(children: ChildBounds[], parentBounds: NodeBounds): InferredPadding; /** * Infer how a child sizes itself within a flex container. */ export declare function inferSizing(child: ChildBounds, parentBounds: NodeBounds, siblings: ChildBounds[], direction: 'row' | 'column', padding?: InferredPadding): InferredSelfSizing; /** * Infer the layout for a container node from its children's absolute bounds. * * Strategy: * 1. If Figma Auto Layout is present (mode=row/column) → trust Figma, cross-validate gap * 2. If no Auto Layout (mode=none) → infer from coordinates * 3. If inference fails → fallback to absolute positioning */ export declare function inferLayoutForNode(node: FigmaNode, childBounds: ChildBounds[], parentBounds: NodeBounds): InferredLayout; //# sourceMappingURL=layout-inference.d.ts.map