import { type AnimationOptions } from 'motion';
/**
 * Measure an element's bounding client rect without current transform.
 *
 * Temporarily clears `transform` to avoid skewing measurements, restoring it
 * immediately after reading the rect.
 *
 * When `scrollContainers` are provided, the returned rect is shifted by the
 * **sum** of each container's `scrollLeft` / `scrollTop`. When
 * `includeViewportScroll` is true, the viewport's `window.scrollX` /
 * `window.scrollY` is included too. FLIP deltas computed from two such
 * measures stay correct even when the user scrolls between measurements —
 * including a nested `layoutScroll` inside another `layoutScroll`. Mirrors
 * framer-motion's `removeElementScroll`, which walks every ancestor in the
 * path, plus root scroll compensation from the projection tree.
 *
 * Pass an empty array (or omit) for viewport-relative behaviour.
 *
 * `baseTransform` is the value the element's `transform` is set to while
 * measuring (default `'none'`, i.e. all transforms removed). The
 * projection system passes the element's mount-time transform here so
 * that a user-authored static `transform` is preserved in the
 * measurement while only the motion-applied portion (written after
 * mount) is removed — mirroring framer-motion's `removeBoxTransforms`,
 * which only subtracts motion-tracked `latestValues` and leaves
 * user-authored transforms intact. Existing FLIP callers omit it and
 * get the original strip-everything behaviour.
 *
 * @param el Element to measure.
 * @param scrollContainers Optional ancestor chain with `layoutScroll` enabled.
 * @param baseTransform Transform string applied during measurement. Defaults to `'none'`.
 * @param includeViewportScroll Whether to include `window.scrollX/Y` in the returned rect.
 * @returns DOMRect snapshot of the element.
 *
 * @example
 * ```ts
 * // No scroll containers — viewport-relative rect.
 * const rect = measureRect(node)
 *
 * // Single ancestor scroll container (one `layoutScroll`).
 * const rect = measureRect(node, [scrollPanel])
 *
 * // Nested `layoutScroll` ancestors — sums offsets from every container.
 * const rect = measureRect(node, [innerScroll, outerScroll])
 * ```
 */
export declare const measureRect: (el: HTMLElement, scrollContainers?: HTMLElement[], baseTransform?: string, includeViewportScroll?: boolean) => DOMRect;
/**
 * Minimal rectangle shape `computeFlipTransforms` reads. A `DOMRect`
 * satisfies it structurally, and so does a projection `Box` converted to
 * `{ left, top, width, height }`. Declared here (rather than importing
 * the projection `Box`) so `layout.ts` stays free of a circular
 * dependency on `projection.ts`, which imports `measureRect` from here.
 */
export interface RectLike {
    left: number;
    top: number;
    width: number;
    height: number;
}
/**
 * Compute FLIP transform deltas between two rects.
 *
 * @param prev Previous rect.
 * @param next Next rect.
 * @param mode `true` for translate+scale, `'position'` for translate only.
 * @return Deltas and flags indicating which transforms to apply.
 */
export declare const computeFlipTransforms: (prev: RectLike, next: RectLike, mode: boolean | "position") => {
    dx: number;
    dy: number;
    sx: number;
    sy: number;
    shouldTranslate: boolean;
    shouldScale: boolean;
};
/**
 * Run a FLIP animation for the provided deltas.
 *
 * Pre-applies the inverse transform to avoid layout flashes, then animates back
 * to identity using the provided transition.
 *
 * @param el Target element.
 * @param transforms Deltas computed by `computeFlipTransforms`.
 * @param transition Timing/options for the animation.
 */
export declare const runFlipAnimation: (el: HTMLElement, transforms: {
    dx: number;
    dy: number;
    sx: number;
    sy: number;
    shouldTranslate: boolean;
    shouldScale: boolean;
}, transition: AnimationOptions) => void;
/**
 * Toggle compositor hints for smoother transform animations.
 *
 * @param el Target element.
 * @param enabled Whether to enable compositor hints.
 */
export declare const setCompositorHints: (el: HTMLElement, enabled: boolean) => void;
/**
 * Observe size/attribute changes that commonly trigger layout changes.
 *
 * Returns a cleanup function that disconnects observers. The callback is called
 * for resize events and attribute/class/style changes on the element and
 * immediate parent child-list changes.
 *
 * @param el Element to observe.
 * @param onChange Callback invoked when a relevant change is detected.
 * @return Cleanup function.
 */
export declare const observeLayoutChanges: (el: HTMLElement, onChange: () => void) => (() => void);
