import { type FocusEventHandler, type KeyboardEventHandler, type MouseEventHandler, type Ref, type RefCallback, type RefObject } from "react";
import { type MenuProps } from "../menu/Menu.js";
import { type MenuSheetConfigurableProps } from "../menu/MenuSheet.js";
import { type GetDefaultFocusedIndex, type GetFocusableElements, type KeyboardMovementExtensionData, type KeyboardMovementProviderImplementation, type KeyboardMovementProviderOptions } from "../movement/types.js";
import { type PositionAnchor, type PositionWidth } from "../positioning/types.js";
import { type TransitionCallbacks } from "../transition/types.js";
import { type NonNullMutableRef, type UseStateInitializer, type UseStateSetter } from "../types.js";
/**
 * @since 6.0.0
 */
export declare const getNonDisabledOptions: (container: HTMLElement) => readonly HTMLElement[];
/**
 * @since 6.0.0
 */
export type SupportedComboboxPopup = "listbox" | "grid" | "dialog";
/**
 * @since 6.0.0
 */
export interface ComboboxKeyboardMovementData<E extends HTMLElement = HTMLInputElement> extends KeyboardMovementExtensionData<E> {
    show: () => void;
    hide: () => void;
    visible: boolean;
    /**
     * @since 6.3.0 Renamed from `focusLast` to `focusLastRef` to support the new
     * actions.
     */
    focusLastRef: NonNullMutableRef<boolean>;
}
/**
 * @since 6.0.0
 */
export type ExtendComboboxKeyDown<E extends HTMLElement = HTMLInputElement> = (movementData: ComboboxKeyboardMovementData<E>) => void;
/**
 * @since 6.0.0
 */
export type ComboboxKeyboardMovementOptions<ComboboxEl extends HTMLElement = HTMLInputElement> = Pick<KeyboardMovementProviderOptions<ComboboxEl>, "onClick" | "onFocus" | "onKeyDown" | "disabled" | "loopable" | "searchable" | "onFocusChange" | "isNegativeOneAllowed">;
/**
 * @since 6.0.0
 */
export interface ComboboxVisibilityOptions {
    /**
     * This can be used to control the popup's visibility and **must** be used
     * along with {@link setVisible}.
     */
    visible?: boolean;
    /**
     * Used to control the popup's visibility and should generally be a `useState`
     * setter.
     *
     * @example Controlling the Visibility
     * ```tsx
     * const [visible, setVisible] = useState(false);
     *
     * useCombobox({
     *   visible,
     *   setVisible,
     * });
     * ```
     */
    setVisible?: UseStateSetter<boolean>;
    /**
     * Set this to `true` to have the combobox's popup visible by default.
     *
     * @defaultValue `false`
     */
    defaultVisible?: UseStateInitializer<boolean>;
}
/**
 * @since 6.0.0
 */
export interface ConfigurableComboboxOptions<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLElement> extends ComboboxKeyboardMovementOptions<ComboboxEl>, ComboboxVisibilityOptions {
    /**
     * This is the {@link InputHTMLAttributes.form} attribute and is used to
     * attempt submitting a form when the enter key is pressed.
     */
    form?: string;
    /**
     * @defaultValue `"combobox-popup-" + useId()`
     */
    popupId?: string;
    popupRef?: Ref<PopupEl>;
    /**
     * @defaultValue `"combobox-" + useId()`
     */
    comboboxId?: string;
    comboboxRef?: Ref<ComboboxEl>;
    /**
     * @defaultValue `"listbox"`
     */
    popup?: "listbox" | "grid" | "dialog";
    /**
     * @defaultValue `false`
     */
    multiselect?: boolean;
    extendKeyDown?: ExtendComboboxKeyDown<ComboboxEl>;
    /**
     * @defaultValue {@link getNonDisabledOptions}
     */
    getFocusableElements?: GetFocusableElements;
    getDefaultFocusedIndex?: GetDefaultFocusedIndex;
}
/**
 * @since 6.0.0
 */
export interface ComboboxGetEnterDefaultFocusedIndexOptions {
    focusLast: boolean;
    focusables: readonly HTMLElement[];
    currentFocusIndex: number;
}
/**
 * @since 6.0.0
 */
export interface ComboboxOptions<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLElement> extends ConfigurableComboboxOptions<ComboboxEl, PopupEl> {
    getEnterDefaultFocusedIndex: (options: ComboboxGetEnterDefaultFocusedIndexOptions) => number;
}
/**
 * @since 6.0.0
 */
export interface ComboboxWidgetProps<ComboboxEl extends HTMLElement = HTMLInputElement> {
    "aria-controls": string;
    "aria-disabled": true | undefined;
    "aria-expanded": boolean;
    "aria-haspopup": SupportedComboboxPopup;
    id: string;
    ref: RefCallback<ComboboxEl>;
    role: "combobox";
    onClick: MouseEventHandler<ComboboxEl>;
    onFocus: FocusEventHandler<ComboboxEl>;
    onKeyDown: KeyboardEventHandler<ComboboxEl>;
}
/**
 * @since 6.0.0
 */
export interface ComboboxWidgetPopupProps<PopupEl extends HTMLElement = HTMLElement> {
    "aria-multiselectable": true | undefined;
    id: string;
    ref: RefCallback<PopupEl>;
    role: "listbox" | "dialog" | "grid";
}
/**
 * @since 6.0.0
 */
export type ComboboxTransitionCallbacks = Pick<TransitionCallbacks, "onEntering" | "onEntered" | "onExiting" | "onExited">;
/**
 * @since 6.0.0
 */
export interface ComboboxTransitionOptions extends ComboboxTransitionCallbacks {
    disableTransition?: boolean;
}
/**
 * @since 6.0.0
 */
export type ConfigurableComboboxMenuProps = Partial<Omit<MenuProps, "visible" | "onRequestClose" | keyof ComboboxWidgetPopupProps>>;
/**
 * @since 6.0.0
 */
export interface ProvidedComboboxMenuProps<PopupEl extends HTMLElement = HTMLDivElement> extends Required<ComboboxTransitionCallbacks>, ComboboxWidgetPopupProps<PopupEl> {
    visible: boolean;
    onRequestClose: () => void;
    /** @defaultValue `"min"` */
    width: PositionWidth;
    /** @defaultValue `BELOW_CENTER_ANCHOR` */
    anchor: PositionAnchor;
    fixedTo: RefObject<HTMLElement>;
    sheetProps: MenuSheetConfigurableProps & Required<ComboboxTransitionCallbacks>;
}
/**
 * @since 6.0.0
 */
export interface ComboboxMenuProps<PopupEl extends HTMLElement = HTMLDivElement> extends Omit<ConfigurableComboboxMenuProps, keyof ProvidedComboboxMenuProps>, ProvidedComboboxMenuProps<PopupEl> {
}
/**
 * @since 6.0.0
 */
export interface ComboboxImplementation<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLElement> extends Omit<KeyboardMovementProviderImplementation<ComboboxEl>, "nodeRef"> {
    show: () => void;
    hide: () => void;
    visible: boolean;
    setVisible: UseStateSetter<boolean>;
    focusLast: NonNullMutableRef<boolean>;
    popupRef: RefObject<PopupEl>;
    popupProps: ComboboxWidgetPopupProps<PopupEl>;
    comboboxRef: RefObject<ComboboxEl>;
    comboboxProps: ComboboxWidgetProps<ComboboxEl>;
    /**
     * Since the combobox usually uses the `Menu` as a popup element, this is a
     * helper util to create the required props and merge any additional props
     * with reasonable defaults.
     */
    getMenuProps: (overrides?: ConfigurableComboboxMenuProps) => ComboboxMenuProps<PopupEl>;
}
/**
 * @since 6.0.0
 */
export declare function useCombobox<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLElement>(options: ComboboxOptions<ComboboxEl, PopupEl>): ComboboxImplementation<ComboboxEl, PopupEl>;
