import type { DragObject } from "../../client/editContext";
import { Component, Placeholder } from "../../pageModel";
import type { BridgeGeometrySnapshot } from "../../bridge/protocol";
import { OverlayMetrics, OverlayRect } from "./geometry";
/**
 * A single insertion gap inside a placeholder, in overlay/document space.
 *
 * `index` is the RAW position among ALL of the placeholder's DOM-ordered
 * children (before-first = 0, after-component-i = i + 1), including hidden
 * layout components. This is what the host sibling-shift animation needs. The
 * layout-excluded index that edit operations expect is derived on demand via
 * {@link layoutAwareIndex}.
 */
export type PlaceholderZone = {
    placeholder: Placeholder;
    position: {
        x: number;
        y: number;
    };
    index: number;
    targetRect?: OverlayRect | null;
    element?: Element | null;
    anchor: "top" | "bottom" | "left" | "right";
    orientation: "horizontal" | "vertical";
    description?: string | null;
};
export type PlaceholderZonesInput = {
    placeholders: Placeholder[];
    geometry: BridgeGeometrySnapshot | undefined;
    metrics: OverlayMetrics;
    dragObject?: DragObject;
    selectedForInsertion?: string;
    insertMode?: boolean;
    showLayoutComponents?: boolean;
    hoveredComponentId?: string;
    scopeInsertModeToHoveredComponent?: boolean;
};
export type InsertSuitabilityInput = Pick<PlaceholderZonesInput, "dragObject" | "selectedForInsertion" | "insertMode"> & {
    selectedForInsertionIsComponent?: boolean;
};
/**
 * Convert a raw zone index (over all DOM children) into the layout-excluded
 * index that `MoveComponentOperation` / `addComponent` expect. Shared by the
 * drop-zone dots, the insertion line, and keyboard reordering so all three
 * agree around hidden layout components.
 */
export declare function layoutAwareIndex(components: Component[], rawIndex: number): number;
/**
 * Compute the set of insertion gaps for the current drag/insert context, at
 * their TRUE positions (no overlap-avoidance shuffling). This is the single
 * source of truth consumed by both the drop-zone dots (which then apply
 * presentation-only overlap avoidance) and the live insertion zone.
 */
export declare function computePlaceholderZones(input: PlaceholderZonesInput): PlaceholderZone[];
export declare function placeholderAcceptsInsertContext(placeholder: Placeholder, { dragObject, selectedForInsertion, insertMode, selectedForInsertionIsComponent, }: InsertSuitabilityInput): boolean;
/**
 * Pick the insertion gap nearest the cursor (in overlay/document space),
 * weighting the placeholder's cross axis so the cursor stays within the
 * hovered column/row.
 */
export declare function resolveNearestGap(point: {
    x: number;
    y: number;
}, zones: PlaceholderZone[]): PlaceholderZone | null;
export declare function placeholderZonesEqual(previous: PlaceholderZone[], next: PlaceholderZone[]): boolean;
export declare function measureBridgePlaceholderZones(placeholder: Placeholder, geometry: BridgeGeometrySnapshot, metrics: OverlayMetrics): PlaceholderZone[];
export declare function isInsideLayoutComponent(component?: Component | null): boolean;
