import React from 'react';
export declare enum ScrollReason {
    OBSERVED = "observed",
    REQUESTED = "requested"
}
/**
 * @Deprecated use ScrollReason
 */
export declare const SCROLL_REASON: typeof ScrollReason;
export type NodeId = string | number;
export interface TreeNode {
    id: NodeId;
}
export interface StickyTreeNode<TNodeType extends TreeNode = TreeNode> {
    height?: number;
    isSticky?: boolean;
    stickyTop?: number;
    zIndex?: number;
    node: TNodeType;
    meta?: any;
}
export interface EnhancedStickyTreeLeafNode<TNodeType extends TreeNode = TreeNode> extends Required<StickyTreeNode<TNodeType>> {
    id: NodeId;
    depth: number;
    index: number;
    top: number;
    totalHeight: number;
    isFirstChild: boolean;
    isLastChild: boolean;
    isLeafNode: boolean;
}
export interface EnhancedStickyTreeParentNode<TNodeType extends TreeNode = TreeNode> extends EnhancedStickyTreeLeafNode<TNodeType> {
    parentInfo: EnhancedStickyTreeLeafNode<TNodeType>;
    parentIndex: number;
    children: number[];
}
export type EnhancedStickyTreeNode<TNodeType extends TreeNode = TreeNode> = EnhancedStickyTreeLeafNode<TNodeType> | EnhancedStickyTreeParentNode<TNodeType>;
export type StickyTreeGetChildren<TNodeType extends TreeNode = TreeNode> = (node: TNodeType, nodeInfo: EnhancedStickyTreeNode<TNodeType>) => StickyTreeNode<TNodeType>[] | undefined;
export interface StickyTreeRowRendererProps<TNodeType extends TreeNode = TreeNode, TMeta = any> {
    node: TNodeType;
    nodeInfo: EnhancedStickyTreeNode<TNodeType>;
    style: React.CSSProperties;
    meta?: TMeta;
}
export type StickyTreeRowRenderer<TNodeType extends TreeNode = TreeNode, TMeta = any> = (props: StickyTreeRowRendererProps<TNodeType, TMeta>) => React.ReactElement;
export type StickyTreeOnScroll = (scrollInfo: {
    scrollTop: number;
    scrollLeft: number;
    scrollReason: ScrollReason;
}) => void;
export type StickyTreeOnRowsRendered<TNodeType extends TreeNode = TreeNode> = (renderInfo: {
    overscanStartIndex: number;
    overscanStopIndex: number;
    startIndex: number;
    stopIndex: number;
    startNode?: EnhancedStickyTreeNode<TNodeType>;
    endNode?: EnhancedStickyTreeNode<TNodeType>;
    nodes: EnhancedStickyTreeNode<TNodeType>[];
}) => void;
export interface StickyTreeProps<TNodeType extends TreeNode = TreeNode, TMeta = any> {
    /**
     * Returns an array of child objects that represent the children of a particular node.
     * The returned object for each child should be in the form:
     *
     * { id: 'childId', height: [number], isSticky: [true|false], stickyTop: [number], zIndex: 0 }
     *
     * Where id and height are mandatory. If isSticky is true, stickyTop and zIndex should also be returned.
     *
     * Example:
     *
     * const getChildren = (id) => {
     *    return myTree[id].children.map(childId => ({
     *      id: childId
     *      isSticky: nodeIsSticky(childId),
     *      height: myTree[childId].height,
     *      ...
     *    }))
     * }
     */
    getChildren: StickyTreeGetChildren<TNodeType>;
    /**
     * Called to retrieve a row to render. The function should return a single React node.
     * The function is called with an object in the form:
     *
     * <pre>
     *     rowRenderer({ id, style, nodeInfo })
     * </pre>
     *
     * The id is the id from either the root property passed to the tree, or one returned in the getChildren call.
     */
    rowRenderer: StickyTreeRowRenderer<TNodeType, TMeta>;
    /**
     * Allows for extra props to be passed to the rowRenderer, whilst simultaneously allowing for updates to rows for values that are apart of the model.
     * For example, selectedRowId, activeRowId etc. Updates to meta will no rebuild the tree, only re-render visible nodes.
     */
    meta?: TMeta;
    /**
     * An object which represents the root node in the form:
     *
     * {
     *   id: 'myRootNodeId',
     *   isSticky: true
     * }
     *
     * This will be the first node passed to rowRenderer({id: myRootNodeId, ...}). Your id might be an index in an array or map lookup.
     */
    root: StickyTreeNode<TNodeType>;
    /**
     * Lets StickyTree know how many rows above and below the visible area should be rendered, to improve performance.
     */
    overscanRowCount?: number;
    /**
     * The height of the outer container.
     */
    height: number;
    /**
     * The width of the outer container
     */
    width: number;
    /**
     * if false, then the width and height are not set as inline styles on the sticky tree element.
     */
    inlineWidthHeight?: boolean;
    /**
     * if true, the root node will be rendered (by calling rowRenderer() for the root id). Otherwise no root node will be rendered.
     */
    renderRoot?: boolean;
    /**
     * Sets the position of the tree to the specified scrollTop. To reset
     * this, change this to -1 or undefined
     */
    scrollTop?: number;
    /**
     * Sets the position of the tree to the specified scrollIndex. This is useful when
     * paired with onRowsRendered() which returns the startIndex and stopIndex.
     */
    scrollIndex?: number;
    /**
     * Called whenever the scrollTop position changes.
     */
    onScroll?: StickyTreeOnScroll;
    /**
     * Called to indicate that a new render range for rows has been rendered.
     */
    onRowsRendered?: StickyTreeOnRowsRendered<TNodeType>;
    /**
     * Specifies the default row height which will be used if the child or root object do not have a height specified.
     */
    rowHeight?: number;
    /**
     * If true, all leaf nodes will be wrapped with a div, even when they are not sticky. this may help with certain tree structures where you need a constant key
     * for the element so that it is not recreated when React dom diffing occurs.
     */
    wrapAllLeafNodes?: boolean;
    /**
     * If true, we can make some assumptions about the results returned by getChildren() which improve rendering performance.
     */
    isModelImmutable?: boolean;
    /**
     * Returns a reference to the tree so the API can be used on the tree.
     * @param tree
     */
    apiRef?: (tree: StickyTree<TNodeType>) => void;
}
export interface StickyTreeState {
    scrollTop: number;
    currNodePos: number;
    scrollTick: boolean;
    scrollReason?: ScrollReason;
}
export interface RowRenderRange {
    start: number;
    end: number;
    visibleStart: number;
    visibleEnd: number;
}
export default class StickyTree<TNodeType extends TreeNode = TreeNode, TMeta = any> extends React.PureComponent<StickyTreeProps<TNodeType, TMeta>, StickyTreeState> {
    static defaultProps: {
        overscanRowCount: number;
        renderRoot: boolean;
        wrapAllLeafNodes: boolean;
        isModelImmutable: boolean;
    };
    private nodes;
    private getChildrenCache;
    private rowRenderCache;
    private rowRenderRange?;
    private structureChanged;
    private elemRef;
    private pendingScrollTop?;
    private treeToRender;
    constructor(props: StickyTreeProps<TNodeType, TMeta>);
    /**
     *  Converts the consumer's tree structure into a flat array with root at index: 0,
     *  including information about the top and height of each node.
     *
     *  i.e:
     *  [
     *    { id: 'root', top: 0, index: 0, height: 100. isSticky: true , zIndex: 0, stickyTop: 10 },
     *    { id: 'child1', top: 10, index: 1, parentIndex: 0 height: 10, isSticky: false },
     *    ...
     *  ]
     */
    private flattenTree;
    private getBranchChildrenIds;
    UNSAFE_componentWillMount(): void;
    private treeDataUpdated;
    UNSAFE_componentWillReceiveProps(newProps: StickyTreeProps<TNodeType>): void;
    UNSAFE_componentWillUpdate(newProps: StickyTreeProps<TNodeType>, newState: StickyTreeState): void;
    getNode(nodeId: NodeId): TNodeType;
    /**
     * Returns the index of the node in a flat list tree (post-order traversal).
     *
     * @param nodeId The node index to get the index for.
     * @returns {number}
     */
    getNodeIndex(nodeId: NodeId): number;
    /**
     * Returns the node that appears higher than this node (either a parent, sibling or child of the sibling above).
     * @param nodeId The node to get the previous node of.
     * @returns {*}
     */
    getPreviousNodeId(nodeId: NodeId): NodeId | undefined;
    /**
     * Returns the node that appears lower than this node (sibling or sibling of the node's parent).
     * @param nodeId The node to get the next node of.
     * @returns {*}
     */
    getNextNodeId(nodeId: NodeId): NodeId | undefined;
    /**
     * Returns true if the node is completely visible and is not obscured.
     * This will return false when the node is partially obscured.
     *
     * @param nodeId The id of the node to check
     * @param includeObscured if true, this method will return true for partially visible nodes.
     * @returns {boolean}
     */
    isNodeVisible(nodeId: NodeId, includeObscured?: boolean): boolean;
    /**
     * Returns true if the node is completely visible and is not obscured, unless includeObscured is specified.
     * This will return false when the node is partially obscured, unless includeObscured is set to true.
     *
     * @param index The index of the node to check, generally retrieved via getNodeIndex()
     * @param includeObscured if true, this method will return true for partially visible nodes.
     * @returns {boolean}
     */
    isIndexVisible(index: number, includeObscured?: boolean): boolean;
    /**
     * Returns true if the node is within the view port window. Note this this will return FALSE for visible sticky nodes that are
     * partially out of view disregarding sticky, which is useful when the node will become unstuck. This may occur when the node is
     * collapsed in a tree. In this case, you want to scroll this node back into view so that the collapsed node stays in the same position.
     *
     * @param nodeId The id of the node to check
     * @returns {boolean}
     */
    isNodeInViewport(nodeId: NodeId): boolean;
    /**
     * Returns true if the node is within the view port window. Note this this will return FALSE for visible sticky nodes that are
     * partially out of view disregarding sticky, which is useful when the node will become unstuck. This may occur when the node is
     * collapsed in a tree. In this case, you want to scroll this node back into view so that the collapsed node stays in the same position.
     *
     * This also returns false if the node is partially out of view.
     *
     * @param index The node index, generally retrieved via getNodeIndex()
     * @returns {boolean}
     */
    isIndexInViewport(index: number): boolean;
    /**
     * Returns the top of the node with the specified id.
     * @param nodeId
     */
    getNodeTop(nodeId: NodeId): number;
    /**
     * Returns the top of the node with the specified index.
     * @param index
     */
    getIndexTop(index: number): number;
    /**
     * Returns the scrollTop of the scrollable element
     *
     * @return returns -1 if the elem does not exist.
     */
    getScrollTop(): number;
    /**
     * Returns the scrollLeft of the scrollable element
     *
     * @return returns -1 if the elem does not exist.
     */
    getScrollLeft(): number;
    /**
     * Sets the scrollTop position of the scrollable element.
     * @param scrollTop
     */
    setScrollTop(scrollTop: number): void;
    /**
     * Sets the scrollLeft position of the scrollable element.
     * @param scrollLeft
     */
    setScrollLeft(scrollLeft: number): void;
    /**
     * Scrolls the node into view so that it is visible.
     *
     * @param nodeId The node id of the node to scroll into view.
     * @param alignToTop if true, the node will aligned to the top of viewport, or sticky parent. If false, the bottom of the node will
     * be aligned with the bottom of the viewport.
     */
    scrollNodeIntoView(nodeId: NodeId, alignToTop?: boolean): void;
    /**
     * Scrolls the node into view so that it is visible.
     *
     * @param index The index of the node.
     * @param alignToTop if true, the node will aligned to the top of viewport, or sticky parent. If false, the bottom of the node will
     * be aligned with the bottom of the viewport.
     */
    scrollIndexIntoView(index: number, alignToTop?: boolean): void;
    componentDidUpdate(prevProps: StickyTreeProps<TNodeType>, prevState: StickyTreeState): void;
    private refreshCachedMetadata;
    recomputeTree(): void;
    private storeRenderTree;
    forceUpdate(): void;
    private renderParentTree;
    private renderParentContainer;
    private getChildContainerStyle;
    private renderChildWithChildren;
    private getClientNodeStyle;
    private getClientLeafNodeStyle;
    private renderChildren;
    private renderNode;
    /**
     * Determines the start and end number of the range to be rendered.
     * @returns {{start: number, end: number}} Indexes within nodes
     */
    private getRenderRowRange;
    /**
     * Returns the parent path from nodes for the specified index within nodes.
     * @param nodeIndex
     * @param topDownOrder if true, the array with index 0 will be the root node, otherwise 0 will be the immediate parent.
     * @returns {Array<TreeNode>}
     */
    private getParentPath;
    /**
     * Searches from the current node position downwards to see if the top of nodes above are greater
     * than or equal to the current scrollTop
     * @param scrollTop
     * @param searchPos
     * @returns {number}
     */
    private forwardSearch;
    /**
     * Searches from the current node position upwards to see if the top of nodes above are less than
     * or equal the current scrollTop.
     * @param scrollTop
     * @param searchPos
     * @returns {number}
     */
    private backwardSearch;
    /**
     * Sets the scroll top in state and finds and sets the closest node to that scroll top.
     */
    private setScrollTopAndClosestNode;
    private onScroll;
    render(): React.JSX.Element;
}
