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";
/**
 * @remarks \@since 6.0.0
 */
export declare const getNonDisabledOptions: (container: HTMLElement) => readonly HTMLElement[];
/**
 * @remarks \@since 6.0.0
 */
export type SupportedComboboxPopup = "listbox" | "grid" | "dialog";
/**
 * @remarks \@since 6.0.0
 */
export interface ComboboxKeyboardMovementData<E extends HTMLElement = HTMLInputElement> extends KeyboardMovementExtensionData<E> {
    show(): void;
    hide(): void;
    visible: boolean;
    focusLast: NonNullMutableRef<boolean>;
}
/**
 * @remarks \@since 6.0.0
 */
export type ExtendComboboxKeyDown<E extends HTMLElement = HTMLInputElement> = (movementData: ComboboxKeyboardMovementData<E>) => void;
/**
 * @remarks \@since 6.0.0
 */
export type ComboboxKeyboardMovementOptions<ComboboxEl extends HTMLElement = HTMLInputElement> = Pick<KeyboardMovementProviderOptions<ComboboxEl>, "onClick" | "onFocus" | "onKeyDown" | "disabled" | "loopable" | "searchable" | "onFocusChange" | "isNegativeOneAllowed">;
/**
 * @remarks \@since 6.0.0
 */
export interface BaseComboboxOptions<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLElement> extends ComboboxKeyboardMovementOptions<ComboboxEl> {
    /**
     * 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`
     */
    defaultVisible?: UseStateInitializer<boolean>;
    extendKeyDown?: ExtendComboboxKeyDown<ComboboxEl>;
    /**
     * @defaultValue {@link getNonDisabledOptions}
     */
    getFocusableElements?: GetFocusableElements;
    getDefaultFocusedIndex?: GetDefaultFocusedIndex;
}
/**
 * @remarks \@since 6.0.0
 */
export interface ComboboxOptions<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLElement> extends BaseComboboxOptions<ComboboxEl, PopupEl> {
    getEnterDefaultFocusedIndex(options: {
        focusLast: boolean;
        focusables: readonly HTMLElement[];
        currentFocusIndex: number;
    }): number;
}
/**
 * @remarks \@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>;
}
/**
 * @remarks \@since 6.0.0
 */
export interface ComboboxWidgetPopupProps<PopupEl extends HTMLElement = HTMLElement> {
    id: string;
    ref: RefCallback<PopupEl>;
    role: "listbox" | "dialog" | "grid";
}
/**
 * @remarks \@since 6.0.0
 */
export type ComboboxTransitionCallbacks = Pick<TransitionCallbacks, "onEntering" | "onEntered" | "onExiting" | "onExited">;
/**
 * @remarks \@since 6.0.0
 */
export interface ComboboxTransitionOptions extends ComboboxTransitionCallbacks {
    disableTransition?: boolean;
}
/**
 * @remarks \@since 6.0.0
 */
export type ConfigurableComboboxMenuProps = Partial<Omit<MenuProps, "fixedTo" | "visible" | "onRequestClose" | keyof ComboboxWidgetPopupProps>>;
/**
 * @remarks \@since 6.0.0
 */
export interface ProvidedComboboxMenuProps<ComboboxEl extends HTMLElement = HTMLInputElement, 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<ComboboxEl>;
    sheetProps: MenuSheetConfigurableProps & Required<ComboboxTransitionCallbacks>;
}
/**
 * @remarks \@since 6.0.0
 */
export interface ComboboxMenuProps<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLDivElement> extends Omit<ConfigurableComboboxMenuProps, keyof ProvidedComboboxMenuProps>, ProvidedComboboxMenuProps<ComboboxEl, PopupEl> {
}
/**
 * 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.
 */
export type ComboboxGetMenuProps<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLDivElement> = (props?: ConfigurableComboboxMenuProps) => ComboboxMenuProps<ComboboxEl, PopupEl>;
/**
 * @remarks \@since 6.0.0
 */
export interface ComboboxImplementation<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLElement> extends KeyboardMovementProviderImplementation<ComboboxEl> {
    show(): void;
    hide(): void;
    visible: boolean;
    setVisible: UseStateSetter<boolean>;
    focusLast: NonNullMutableRef<boolean>;
    popupRef: RefObject<PopupEl>;
    popupProps: ComboboxWidgetPopupProps<PopupEl>;
    comboboxRef: RefObject<ComboboxEl>;
    comboboxProps: ComboboxWidgetProps<ComboboxEl>;
    getMenuProps: ComboboxGetMenuProps<ComboboxEl, PopupEl>;
    getTransitionCallbacks(options: ComboboxTransitionOptions): Required<ComboboxTransitionCallbacks>;
}
/**
 * @remarks \@since 6.0.0
 */
export declare function useCombobox<ComboboxEl extends HTMLElement = HTMLInputElement, PopupEl extends HTMLElement = HTMLElement>(options: ComboboxOptions<ComboboxEl, PopupEl>): ComboboxImplementation<ComboboxEl, PopupEl>;
