/**
 * Navigation orientation for a linear list.
 * - `'horizontal'`: ArrowLeft/ArrowRight move between items.
 * - `'vertical'`: ArrowUp/ArrowDown move between items.
 * - `'both'`: all four arrows move between items (in linear DOM order).
 */
export type ListFocusOrientation = 'horizontal' | 'vertical' | 'both';
/**
 * Configuration for list focus behavior
 */
export interface UseListFocusOptions {
    /**
     * Selector for focusable items within the list.
     * @default '[role="menuitem"]'
     */
    itemSelector?: string;
    /**
     * Selector identifying a list boundary — used to scope a list that contains
     * *nested* lists of the same kind (e.g. a menu with submenu flyouts).
     *
     * Overlays like submenu flyouts render inline (native popover, not a
     * portal), so a nested list's items are DOM descendants of the parent list.
     * Without scoping, the parent's `querySelectorAll` sweeps the nested items
     * into its roving order (leaving hidden items `.focus()` can't land on), and
     * key events from the nested list bubble into the parent's handler (moving
     * focus twice). When set, `useListFocus`:
     *   - counts an item as its own only when the item's nearest
     *     `boundarySelector` ancestor is this list's container, and
     *   - ignores key events whose nearest `boundarySelector` ancestor is not
     *     this list's container (i.e. they originated in a nested list).
     *
     * Typically `'[role="menu"]'` for menus. Omit for flat lists.
     */
    boundarySelector?: string;
    /**
     * Whether arrow navigation wraps around at the ends.
     * @default true
     */
    wrap?: boolean;
    /**
     * Callback when Escape key is pressed.
     */
    onEscape?: () => void;
    /**
     * Navigation orientation. `'horizontal'` uses ArrowLeft/ArrowRight,
     * `'vertical'` uses ArrowUp/ArrowDown, `'both'` accepts all four arrows.
     * @default 'vertical'
     */
    orientation?: ListFocusOrientation;
    /**
     * Whether Home/End jump to the first/last enabled item.
     * @default true
     */
    hasHomeEnd?: boolean;
    /**
     * @deprecated Direction is auto-detected from the container's computed
     * `direction` — omit this. The explicit override is redundant (there's no
     * valid reason to force RTL arrows in an LTR context) and will be removed in
     * an upcoming major.
     *
     * When set, forces whether the list is right-to-left: ArrowLeft/ArrowRight
     * are swapped so horizontal navigation follows visual direction. When
     * omitted (preferred), the direction is auto-detected from the container's
     * computed `direction` (read lazily on keydown, horizontal arrows only).
     * @default undefined (auto-detect from the container)
     */
    isRtl?: boolean;
    /**
     * Roving-tabindex ownership. When true, the hook manages a single tab stop
     * across the items: exactly one enabled item carries `tabindex="0"` and the
     * rest `tabindex="-1"`. The tab stop is stamped on mount and repaired
     * whenever items mount/unmount or toggle disabled, and moves with arrow
     * navigation. Attach the returned {@link UseListFocusReturn.handleFocus} to
     * the container's `onFocus` to keep the stop in sync after clicks or
     * programmatic focus.
     *
     * When false (the default), the hook only *moves* focus (`.focus()`) and
     * never touches `tabindex` — the caller owns tab-stop management.
     * @default false
     */
    hasRovingTabIndex?: boolean;
    /**
     * When true, arrow keys are not stolen from a nested text input/textarea
     * whose caret is not at the boundary in the direction of travel (or that has
     * a non-collapsed selection), and are never stolen from a nested
     * `contenteditable` (rich-text editor / chat composer). This preserves
     * normal caret movement while the user is editing inline within the list
     * (e.g. a toolbar search field or composer).
     * @default false
     */
    hasCaretGuard?: boolean;
}
/**
 * Return type for useListFocus hook
 */
export interface UseListFocusReturn<T extends HTMLElement = HTMLElement> {
    /**
     * Ref to attach to the list container element.
     */
    listRef: React.RefObject<T | null>;
    /**
     * Key down handler to attach to the list 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 a specific item by index.
     */
    focusItem: (index: number) => void;
    /**
     * Focus the first enabled item. Returns true when an item was focused.
     */
    focusFirst: () => boolean;
    /**
     * Focus the last enabled item. Returns true when an item was focused.
     */
    focusLast: () => boolean;
    /**
     * Whether a key event belongs to this list level (vs. a nested list that
     * shares the same `boundarySelector`). Useful when a consumer wraps
     * `handleKeyDown` with extra behavior (Enter/Space activation, typeahead)
     * and must apply it only to events this level owns. Always true when no
     * `boundarySelector` is configured.
     */
    ownsEvent: (e: React.KeyboardEvent) => boolean;
    /**
     * The current, in-DOM-order list of this level's focusable items (already
     * scoped by `boundarySelector`). Exposed so consumers can build typeahead
     * targets from the same source of truth as roving focus, rather than
     * re-querying and re-filtering.
     */
    getItems: () => HTMLElement[];
}
/**
 * Hook for managing keyboard navigation within a linear list.
 *
 * Implements WAI-ARIA menu/listbox/toolbar pattern:
 * - ArrowDown/ArrowRight: Move to next item (wraps to first)
 * - ArrowUp/ArrowLeft: Move to previous item (wraps to last)
 * - Home: Move to first item
 * - End: Move to last item
 * - Escape: Custom callback (e.g., close menu)
 *
 * By default the hook only *moves* focus and leaves `tabindex` management to
 * the caller. Opt into {@link UseListFocusOptions.hasRovingTabIndex} for a hook
 * that owns a single tab stop (roving tabindex) across the items — stamping and
 * repairing it as items mount/unmount or toggle disabled — for toolbars,
 * segmented controls, tab strips, and similar composite widgets.
 *
 * @example
 * ```
 * const {listRef, handleKeyDown} = useListFocus({
 *   onEscape: () => layer.hide(),
 * });
 *
 * <div ref={listRef} role="menu" onKeyDown={handleKeyDown}>
 *   {items.map(item => <div role="menuitem" tabIndex={0}>{item}</div>)}
 * </div>
 * ```
 *
 * Roving-tabindex composite (e.g. a toolbar):
 *
 * @example
 * ```
 * const {listRef, handleKeyDown, handleFocus} = useListFocus<HTMLDivElement>({
 *   itemSelector: 'button, input, [tabindex]',
 *   orientation: 'horizontal',
 *   hasRovingTabIndex: true,
 *   hasCaretGuard: true,
 * });
 *
 * <div ref={listRef} role="toolbar" onKeyDown={handleKeyDown} onFocus={handleFocus}>
 *   {children}
 * </div>
 * ```
 */
export declare function useListFocus<T extends HTMLElement = HTMLElement>(options?: UseListFocusOptions): UseListFocusReturn<T>;
//# sourceMappingURL=useListFocus.d.ts.map