import { ReactElement, ChangeEvent, ComponentType, CSSProperties, ForwardedRef, HTMLInputAutoCompleteAttribute, KeyboardEvent, MouseEvent, ReactNode } from "react";
import { BlockNoteEditor, User } from "@blocknote/core";
import { DefaultReactGridSuggestionItem } from "../components/SuggestionMenu/GridSuggestionMenu/types.js";
import { DefaultReactSuggestionItem } from "../components/SuggestionMenu/types.js";
type ToolbarRootType = {
    className?: string;
    children?: ReactNode;
    onMouseEnter?: () => void;
    onMouseLeave?: () => void;
    variant?: "default" | "action-toolbar";
};
type ToolbarButtonType = {
    className?: string;
    mainTooltip?: string;
    secondaryTooltip?: string;
    icon?: ReactNode;
    onClick?: (e: MouseEvent) => void;
    isSelected?: boolean;
    isDisabled?: boolean;
    variant?: "default" | "compact";
} & ({
    children: ReactNode;
    label?: string;
} | {
    children?: undefined;
    label: string;
});
type ToolbarSelectType = {
    className?: string;
    items: {
        text: string;
        icon: ReactNode;
        onClick: () => void;
        isSelected: boolean;
        isDisabled?: boolean;
    }[];
    isDisabled?: boolean;
    portalElement: HTMLElement | null;
    /**
     * When true, the UI library must not move focus into the surface when it
     * opens (the mobile toolbar: a focus move blurs the editor and closes the
     * on-screen keyboard). An input inside that asks for focus itself still
     * gets it.
     */
    preventFocusOnOpen?: boolean;
};
type MenuButtonType = {
    className?: string;
    onClick?: (e: MouseEvent) => void;
    icon?: ReactNode;
    onDragStart?: (e: React.DragEvent) => void;
    onDragEnd?: (e: React.DragEvent) => void;
    draggable?: boolean;
} & ({
    children: ReactNode;
    label?: string;
} | {
    children?: undefined;
    label: string;
});
export type ComponentProps = {
    FormattingToolbar: {
        Root: ToolbarRootType;
        Button: ToolbarButtonType;
        Select: ToolbarSelectType;
    };
    FilePanel: {
        Root: {
            className?: string;
            tabs: {
                name: string;
                tabPanel: ReactNode;
            }[];
            openTab: string;
            setOpenTab: (name: string) => void;
            defaultOpenTab: string;
            loading: boolean;
        };
        Button: {
            className?: string;
            /**
             * Explicit, because the skins' underlying buttons disagree on the
             * default (Mantine's is `type="button"`, shadcn's was `"submit"`) and
             * a submit button inside a `Form.Root` must reliably submit on every
             * skin. `"submit"` buttons need no `onClick` - the form's `onSubmit`
             * is the single commit path, so clicking cannot fire twice.
             */
            type: "button" | "submit";
            onClick?: () => void;
        } & ({
            children: ReactNode;
            label?: string;
        } | {
            children?: undefined;
            label: string;
        });
        FileInput: {
            className?: string;
            accept: string;
            value: File | null;
            placeholder: string;
            onChange: (payload: File | null) => void;
        };
        TabPanel: {
            className?: string;
            children?: ReactNode;
        };
        TextInput: {
            className?: string;
            value: string;
            placeholder: string;
            onChange: (event: ChangeEvent<HTMLInputElement>) => void;
            onKeyDown?: (event: KeyboardEvent) => void;
        };
    };
    LinkToolbar: {
        Root: ToolbarRootType;
        Button: ToolbarButtonType;
        Select: ToolbarSelectType;
    };
    SideMenu: {
        Root: {
            className?: string;
            children?: ReactNode;
        };
        Button: {
            className?: string;
            onClick?: (e: MouseEvent) => void;
            icon?: ReactNode;
            onDragStart?: (e: React.DragEvent) => void;
            onDragEnd?: (e: React.DragEvent) => void;
            draggable?: boolean;
        } & ({
            children: ReactNode;
            label?: string;
        } | {
            children?: undefined;
            label: string;
        });
    };
    SuggestionMenu: {
        Root: {
            id: string;
            className?: string;
            children?: ReactNode;
        };
        EmptyItem: {
            className?: string;
            children?: ReactNode;
        };
        Item: {
            className?: string;
            id: string;
            isSelected: boolean;
            onClick: () => void;
            item: Omit<DefaultReactSuggestionItem, "onItemClick">;
        };
        Label: {
            className?: string;
            children?: ReactNode;
        };
        Loader: {
            className?: string;
        };
    };
    GridSuggestionMenu: {
        Root: {
            id: string;
            columns: number;
            className?: string;
            children?: ReactNode;
        };
        EmptyItem: {
            columns: number;
            className?: string;
            children?: ReactNode;
        };
        Item: {
            className?: string;
            id: string;
            isSelected: boolean;
            onClick: () => void;
            item: DefaultReactGridSuggestionItem;
        };
        Loader: {
            columns: number;
            className?: string;
            children?: ReactNode;
        };
    };
    TableHandle: {
        Root: {
            className?: string;
            draggable: boolean;
            onDragStart: (e: React.DragEvent) => void;
            onDragEnd: () => void;
            style?: CSSProperties;
        } & ({
            children: ReactNode;
            label?: string;
        } | {
            children?: undefined;
            label: string;
        });
        ExtendButton: {
            className?: string;
            onClick: (e: React.MouseEvent) => void;
            onMouseDown: (e: React.MouseEvent) => void;
            children: ReactNode;
        };
    };
    Comments: {
        Card: {
            className?: string;
            headerText?: string;
            selected?: boolean;
            onFocus?: (event: React.FocusEvent) => void;
            onBlur?: (event: React.FocusEvent) => void;
            tabIndex?: number;
            children?: ReactNode;
        };
        CardSection: {
            className?: string;
            children?: ReactNode;
        };
        ExpandSectionsPrompt: {
            className?: string;
            children?: ReactNode;
        };
        Editor: {
            className?: string;
            autoFocus?: boolean;
            editable: boolean;
            editor: BlockNoteEditor<any, any, any>;
            onFocus?: () => void;
            onBlur?: () => void;
        };
        Comment: {
            className?: string;
            children?: ReactNode;
            authorInfo: "loading" | User;
            timeString: string;
            edited: boolean;
            actions?: ReactNode;
            showActions?: boolean | "hover";
            emojiPickerOpen?: boolean;
        };
    };
    Versioning: {
        /**
         * The scrollable container for the version-history sidebar (header +
         * snapshot rows).
         */
        Sidebar: {
            className?: string;
            children?: ReactNode;
        };
        /**
         * A single row in the version-history sidebar — the live "current version"
         * entry or a stored snapshot.
         */
        Snapshot: {
            className?: string;
            /** Whether this row is the version currently shown in the editor. */
            selected?: boolean;
            /** Whether this row is the baseline the current diff is compared against. */
            comparing?: boolean;
            onClick?: () => void;
            /** Row actions (e.g. the "..." menu), revealed on hover. */
            actions?: ReactNode;
            children?: ReactNode;
        };
    };
    AttributionTooltip: {
        /**
         * The attribution tooltip shown when hovering a suggestion mark. Positioned
         * by floating-ui and portaled by the controller — this only styles the box.
         */
        Root: {
            className?: string;
            /**
             * App-supplied class from `getAttributionMarkClassName` (override path).
             * When set, `Root` applies it and ignores `backgroundColor`.
             */
            markClassName?: string;
            /**
             * Per-user author color (default path). Applied inline when there's no
             * `markClassName`, since the tooltip is portaled away from the mark and
             * can't inherit the mark's color.
             */
            backgroundColor?: string;
            children?: ReactNode;
        };
    };
    Generic: {
        Badge: {
            Root: {
                className?: string;
                text: string;
                icon?: ReactNode;
                isSelected?: boolean;
                mainTooltip?: string;
                secondaryTooltip?: string;
                onClick?: (event: React.MouseEvent) => void;
                onMouseEnter?: () => void;
            };
            Group: {
                className?: string;
                children: ReactNode;
            };
        };
        Form: {
            Root: {
                children?: ReactNode;
                /**
                 * Called on the form's `submit` event. Implementations must render a
                 * real `<form>` and `preventDefault`: native submission is the only
                 * path that works for every input source — mobile IMEs commit
                 * through it without dispatching any key event.
                 */
                onSubmit?: () => void;
                /**
                 * The form's submit control, rendered inside the `<form>`. Usually
                 * `ScreenReaderOnlySubmit`; a visible `type="submit"` button to make
                 * it the form's one affordance (the embed tab); or `"none"` — then
                 * the form must have exactly one field, or Enter submits nothing.
                 */
                submitButton: ReactElement | "none";
            };
            TextInput: {
                className?: string;
                name: string;
                label?: string;
                variant?: "default" | "large";
                icon: ReactNode;
                rightSection?: ReactNode;
                autoFocus?: boolean;
                placeholder?: string;
                disabled?: boolean;
                value: string;
                onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
                onChange: (event: ChangeEvent<HTMLInputElement>) => void;
                autoComplete?: HTMLInputAutoCompleteAttribute;
                "aria-activedescendant"?: string;
                ref?: ForwardedRef<HTMLInputElement>;
            };
        };
        Menu: {
            Root: {
                sub?: boolean;
                onOpenChange?: (open: boolean) => void;
                position?: "top" | "right" | "bottom" | "left" | `${"top" | "right" | "bottom" | "left"}-${"start" | "end"}`;
                portalElement: HTMLElement | null;
                /** See `ToolbarSelect.preventFocusOnOpen`. */
                preventFocusOnOpen?: boolean;
                children?: ReactNode;
            };
            Divider: {
                className?: string;
            };
            Dropdown: {
                className?: string;
                children?: ReactNode;
                sub?: boolean;
            };
            Item: {
                className?: string;
                children?: ReactNode;
                subTrigger?: boolean;
                icon?: ReactNode;
                checked?: boolean;
                onClick?: () => void;
            };
            Label: {
                className?: string;
                children?: ReactNode;
            };
            Trigger: {
                children?: ReactNode;
                sub?: boolean;
            };
            Button: MenuButtonType;
        };
        Popover: {
            Root: {
                open?: boolean;
                onOpenChange?: (open: boolean) => void;
                position?: "top" | "right" | "bottom" | "left" | `${"top" | "right" | "bottom" | "left"}-${"start" | "end"}`;
                portalElement: HTMLElement | null;
                children?: ReactNode;
            };
            Content: {
                className?: string;
                variant: "form-popover" | "panel-popover";
                children?: ReactNode;
            };
            Trigger: {
                children?: ReactNode;
            };
        };
        Toolbar: {
            Root: ToolbarRootType;
            Button: ToolbarButtonType;
            Select: ToolbarSelectType;
        };
    };
};
export type Components = {
    [Components in keyof Omit<ComponentProps, "Generic">]: {
        [Component in keyof ComponentProps[Components]]: ComponentType<ComponentProps[Components][Component]>;
    };
} & {
    Generic: {
        [GenericComponents in keyof ComponentProps["Generic"]]: {
            [Component in keyof ComponentProps["Generic"][GenericComponents]]: ComponentType<ComponentProps["Generic"][GenericComponents][Component]>;
        };
    };
};
export declare const ComponentsContext: import("react").Context<Components | undefined>;
export declare function useComponentsContext(): Components | undefined;
export {};
