export type ChatListOrder = 'newest-on-top' | 'oldest-on-top';
/**
 * Keeps a scroll container stuck to its "newest" edge as items are
 * appended, so long as the user hasn't scrolled away.
 *
 * We use imperative scrolling rather than `flex-direction: column-reverse`
 * so DOM order matches visual order (copy/paste, screen readers, tab
 * order all align with what the user sees). CSS `overflow-anchor: auto`
 * — the default and left enabled here — solves a different problem:
 * preserving scroll position when content is inserted *above* the
 * viewport. It doesn't stick the scroll to the newest edge when items
 * arrive below the viewport, which is what chat typically needs; that
 * requires the imperative approach in this class.
 *
 * Lifecycle:
 * - `beforeRender()` in `componentWillRender` — snapshot whether the
 *   user is near the newest edge, using the order the scroll position
 *   was last measured against. Capturing here (synchronously, before
 *   the new DOM lands) avoids the race a scroll-event listener would
 *   have with `componentDidRender`.
 * - `afterRender()` in `componentDidRender` — if the snapshot said
 *   "near newest", re-pin to the newest edge (new `scrollHeight`).
 * - `repinIfSticky()` for out-of-band re-pins (e.g. after the typing
 *   indicator's height transition finishes — its `scrollHeight`
 *   change lands after `componentDidRender`).
 *
 * Scroll-container contract: the passed element must itself be the
 * scrolling ancestor (the element whose `scrollTop` / `scrollHeight`
 * / `clientHeight` reflect the chat list's scroll state). In practice
 * that is the component's host, which sets `overflow: hidden auto` on
 * itself. If future refactors introduce an inner scrolling wrapper,
 * pass that wrapper instead.
 */
export declare class ScrollAnchor {
    private readonly scrollContainer;
    private readonly getOrder;
    private isSticky;
    private paintedOrder;
    constructor(scrollContainer: HTMLElement, getOrder: () => ChatListOrder, initialOrder: ChatListOrder);
    beforeRender(): void;
    afterRender(): void;
    repinIfSticky(): void;
    private scrollToNewest;
    private distanceFromNewestEdge;
}
//# sourceMappingURL=scroll-anchor.d.ts.map