/**
 * Configuration for tree focus behavior.
 *
 * The tree keyboard model differs from a linear list (useListFocus): while
 * ArrowUp/ArrowDown/Home/End roam linearly over the *visible* treeitems,
 * ArrowRight/ArrowLeft carry tree semantics (expand/collapse, move to
 * first-child / parent). The hook stays generic by taking callbacks for the
 * tree-specific bits (expansion toggling, activation) — mirroring how
 * useGridFocus takes `isCellFocusable` rather than hardcoding disabled logic.
 */
export interface UseTreeFocusOptions {
    /**
     * Selector for treeitems within the tree. Matches ALL visible treeitems in
     * DOM order (collapsed subtrees are not rendered, so they are naturally
     * excluded). Disabled treeitems are still matched and then skipped via
     * {@link UseTreeFocusOptions.isItemDisabled}.
     * @default '[role="treeitem"]'
     */
    itemSelector?: string;
    /**
     * Predicate determining whether a treeitem matched by `itemSelector` is
     * disabled and must be skipped during arrow/Home/End navigation. A `.focus()`
     * on a disabled item silently no-ops, so navigation would otherwise stall.
     *
     * @default reads `data-tree-disabled` (present ⇒ disabled)
     */
    isItemDisabled?: (item: HTMLElement) => boolean;
    /**
     * Reads the nesting level (aria-level style, 1-based) of a treeitem. Used to
     * resolve first-child (ArrowRight) and parent (ArrowLeft) targets from the
     * flat visible-item list.
     *
     * @default reads the `aria-level` attribute (falling back to `1`)
     */
    getLevel?: (item: HTMLElement) => number;
    /**
     * Whether a treeitem is an expanded parent. Read DOM-side (aria-expanded)
     * by default so it reflects the rendered tree without prop plumbing.
     *
     * @default `aria-expanded === 'true'`
     */
    isExpanded?: (item: HTMLElement) => boolean;
    /**
     * Whether a treeitem is a collapsed parent (has children but is closed).
     *
     * @default `aria-expanded === 'false'`
     */
    isCollapsed?: (item: HTMLElement) => boolean;
    /**
     * Resolve the stable id for a treeitem, passed to `onToggleExpand` /
     * `onActivate`. Returns `undefined` when the element carries no id.
     *
     * @default reads the `data-tree-id` attribute
     */
    getItemId?: (item: HTMLElement) => string | undefined;
    /**
     * Called to expand/collapse the treeitem with the given id (ArrowRight on a
     * collapsed parent, ArrowLeft on an expanded parent, and Enter/Space on a
     * parent that has no inner action).
     */
    onToggleExpand?: (id: string) => void;
    /**
     * Called when Enter/Space activates a treeitem. Return `true` if the
     * activation was handled (e.g. an inner link/button was clicked); return
     * `false`/`undefined` to let the hook fall back to toggling expansion for a
     * parent. When omitted, the hook falls straight through to expansion
     * toggling for parents.
     *
     * @param item The focused treeitem element.
     * @param id The treeitem's id (per `getItemId`), if any.
     */
    onActivate?: (item: HTMLElement, id: string | undefined) => boolean | undefined;
    /**
     * Whether typeahead (jump to next item whose text starts with the typed
     * characters) is enabled.
     * @default true
     */
    typeahead?: boolean;
    /** Reset delay for the typeahead buffer, in ms. @default 500 */
    typeaheadResetMs?: number;
    /**
     * Notified whenever the hook moves focus to a treeitem, with its id (if any).
     * TreeList uses this to move its single roving tab stop.
     */
    onActiveChange?: (id: string | undefined) => void;
    /**
     * Roving-tabindex ownership. When true, the hook manages a single tab stop
     * across the visible treeitems: exactly one enabled treeitem carries
     * `tabindex="0"` and the rest `tabindex="-1"`. The tab stop is repaired on
     * mount and whenever items mount/unmount or toggle disabled, and moves with
     * keyboard navigation. Attach the returned {@link UseTreeFocusReturn.handleFocus}
     * to the container's `onFocus` to keep the stop in sync after clicks or
     * programmatic focus.
     *
     * On mount the hook preserves an existing `tabindex="0"` treeitem (so a
     * consumer can seed the active item in its render); if none exists it
     * promotes the first enabled treeitem.
     *
     * When false (the default), the hook only *moves* focus (`.focus()`) and
     * never touches `tabindex` — the caller owns tab-stop management.
     * @default false
     */
    hasRovingTabIndex?: boolean;
}
/**
 * Return type for useTreeFocus hook.
 */
export interface UseTreeFocusReturn<T extends HTMLElement = HTMLElement> {
    /** Ref to attach to the tree container element (role="tree"). */
    treeRef: React.RefObject<T | null>;
    /** Key down handler to attach to the tree container. */
    handleKeyDown: (e: React.KeyboardEvent) => void;
    /**
     * Focus handler to attach to the container's `onFocus`. Keeps the roving tab
     * stop in sync when `hasRovingTabIndex` is enabled; a no-op otherwise, so it
     * is always safe to attach.
     */
    handleFocus: (e: React.FocusEvent) => void;
    /** Focus the first enabled visible treeitem. */
    focusFirst: () => void;
    /** Focus the last enabled visible treeitem. */
    focusLast: () => void;
}
/**
 * Hook for managing roving-tabindex focus + the WAI-ARIA tree keyboard model.
 *
 * A tree is not a linear list: ArrowUp/ArrowDown/Home/End roam linearly over
 * the *visible* treeitems (skipping disabled ones), but ArrowRight/ArrowLeft
 * carry tree semantics. This is why a tree needs its own hook rather than
 * reusing `useListFocus` — the same reason 2D grids get `useGridFocus`.
 *
 * - ArrowDown / ArrowUp: move to next/previous visible treeitem (skip disabled)
 * - ArrowRight: collapsed parent → expand; expanded parent → first child;
 *   leaf → no-op
 * - ArrowLeft: expanded parent → collapse; otherwise → move to parent treeitem
 * - Home / End: first / last visible treeitem
 * - Enter / Space: activate (`onActivate`), falling back to expansion toggle
 * - Printable characters: typeahead to the next matching treeitem
 *
 * The hook is DOM-query based (reads aria-expanded/aria-level and data-*
 * attributes) and stays generic via option callbacks for the tree-specific
 * bits (`onToggleExpand`, `onActivate`, `getLevel`, `isItemDisabled`, …).
 *
 * @example
 * ```
 * const {treeRef, handleKeyDown, handleFocus} = useTreeFocus<HTMLUListElement>({
 *   onToggleExpand: id => toggle(id),
 *   hasRovingTabIndex: true,
 * });
 *
 * <ul ref={treeRef} role="tree" onKeyDown={handleKeyDown} onFocus={handleFocus}>
 *   {items.map(item => <li role="treeitem" tabIndex={-1}>{item.label}</li>)}
 * </ul>
 * ```
 */
export declare function useTreeFocus<T extends HTMLElement = HTMLElement>(options?: UseTreeFocusOptions): UseTreeFocusReturn<T>;
//# sourceMappingURL=useTreeFocus.d.ts.map