import React from "react";
import { IDeferred } from "matrix-js-sdk/src/utils";
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix";
import { Defaultize } from "./@types/common";
export type ComponentType = React.ComponentType<{
    onFinished(...args: any): void;
}> | React.ComponentType<any>;
export type ComponentProps<C extends ComponentType> = Defaultize<Omit<React.ComponentProps<C>, "onFinished">, C["defaultProps"]> & Partial<Pick<React.ComponentProps<C>, "onFinished">>;
export interface IModal<C extends ComponentType> {
    elem: React.ReactNode;
    className?: string;
    beforeClosePromise?: Promise<boolean>;
    closeReason?: ModalCloseReason;
    onBeforeClose?(reason?: ModalCloseReason): Promise<boolean>;
    onFinished: ComponentProps<C>["onFinished"];
    close(...args: Parameters<ComponentProps<C>["onFinished"]>): void;
    hidden?: boolean;
    deferred?: IDeferred<Parameters<ComponentProps<C>["onFinished"]>>;
}
export interface IHandle<C extends ComponentType> {
    finished: Promise<Parameters<ComponentProps<C>["onFinished"]>>;
    close(...args: Parameters<ComponentProps<C>["onFinished"]>): void;
}
interface IOptions<C extends ComponentType> {
    onBeforeClose?: IModal<C>["onBeforeClose"];
}
export declare enum ModalManagerEvent {
    Opened = "opened",
    Closed = "closed"
}
type HandlerMap = {
    [ModalManagerEvent.Opened]: () => void;
    [ModalManagerEvent.Closed]: () => void;
};
type ModalCloseReason = "backgroundClick";
export declare class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMap> {
    private counter;
    private priorityModal;
    private staticModal;
    private modals;
    private static getOrCreateContainer;
    private static getOrCreateStaticContainer;
    constructor();
    private onAction;
    toggleCurrentDialogVisibility(): void;
    hasDialogs(): boolean;
    createDialog<C extends ComponentType>(Element: C, props?: ComponentProps<C>, className?: string, isPriorityModal?: boolean, isStaticModal?: boolean, options?: IOptions<C>): IHandle<C>;
    appendDialog<C extends ComponentType>(Element: C, props?: ComponentProps<C>, className?: string): IHandle<C>;
    /**
     * DEPRECATED.
     * This is used only for tests. They should be using forceCloseAllModals but that
     * caused a chunk of tests to fail, so for now they continue to use this.
     *
     * @param reason either "backgroundClick" or undefined
     * @return whether a modal was closed
     */
    closeCurrentModal(reason?: ModalCloseReason): boolean;
    /**
     * Forces closes all open modals. The modals onBeforeClose function will not be
     * run and the modal will not have a chance to prevent closing. Intended for
     * situations like the user logging out of the app.
     */
    forceCloseAllModals(): void;
    private buildModal;
    private getCloseFn;
    /**
     * @callback onBeforeClose
     * @param {string?} reason either "backgroundClick" or null
     * @return {Promise<bool>} whether the dialog should close
     */
    /**
     * Open a modal view.
     *
     * This can be used to display a react component which is loaded as an asynchronous
     * webpack component. To do this, set 'loader' as:
     *
     *   (cb) => {
     *       require(['<module>'], cb);
     *   }
     *
     * @param {Promise} prom   a promise which resolves with a React component
     *   which will be displayed as the modal view.
     *
     * @param {Object} props   properties to pass to the displayed
     *    component. (We will also pass an 'onFinished' property.)
     *
     * @param {String} className   CSS class to apply to the modal wrapper
     *
     * @param {boolean} isPriorityModal if true, this modal will be displayed regardless
     *                                  of other modals that are currently in the stack.
     *                                  Also, when closed, all modals will be removed
     *                                  from the stack.
     * @param {boolean} isStaticModal  if true, this modal will be displayed under other
     *                                 modals in the stack. When closed, all modals will
     *                                 also be removed from the stack. This is not compatible
     *                                 with being a priority modal. Only one modal can be
     *                                 static at a time.
     * @param {Object} options? extra options for the dialog
     * @param {onBeforeClose} options.onBeforeClose a callback to decide whether to close the dialog
     * @returns {object} Object with 'close' parameter being a function that will close the dialog
     */
    createDialogAsync<C extends ComponentType>(prom: Promise<C>, props?: ComponentProps<C>, className?: string, isPriorityModal?: boolean, isStaticModal?: boolean, options?: IOptions<C>): IHandle<C>;
    private appendDialogAsync;
    private emitIfChanged;
    /**
     * Emit the closed event
     * @private
     */
    private emitClosed;
    private onBackgroundClick;
    private getCurrentModal;
    private reRender;
}
declare const _default: ModalManager;
export default _default;
