import { IDisposable } from '@lumino/disposable';
import { Message } from '@lumino/messaging';
import { ISignal, Signal } from '@lumino/signaling';
import { Widget } from '@lumino/widgets';
import * as React from 'react';
type ReactRenderElement = Array<React.ReactElement<any>> | React.ReactElement<any>;
/**
 * An abstract class for a Lumino widget which renders a React component.
 */
export declare abstract class ReactWidget extends Widget {
    constructor();
    /**
     * Creates a new `ReactWidget` that renders a constant element.
     * @param element React element to render.
     */
    static create(element: ReactRenderElement): ReactWidget;
    /**
     * Render the content of this widget using the virtual DOM.
     *
     * This method will be called anytime the widget needs to be rendered, which
     * includes layout triggered rendering.
     *
     * Subclasses should define this method and return the root React nodes here.
     */
    protected abstract render(): ReactRenderElement | null;
    /**
     * Called to update the state of the widget.
     *
     * The default implementation of this method triggers
     * VDOM based rendering by calling the `renderDOM` method.
     */
    protected onUpdateRequest(msg: Message): void;
    /**
     * Called after the widget is attached to the DOM
     */
    protected onAfterAttach(msg: Message): void;
    /**
     * Called before the widget is detached from the DOM.
     */
    protected onBeforeDetach(msg: Message): void;
    /**
     * Render the React nodes to the DOM.
     *
     * @returns a promise that resolves when the rendering is done.
     */
    private renderDOM;
    renderPromise?: Promise<void>;
    private _rootDOM;
}
/**
 * An abstract ReactWidget with a model.
 */
export declare abstract class VDomRenderer<T extends VDomRenderer.IModel | null = null> extends ReactWidget {
    /**
     * Create a new VDomRenderer
     */
    constructor(model?: T);
    /**
     * A signal emitted when the model changes.
     */
    get modelChanged(): ISignal<this, void>;
    /**
     * Set the model and fire changed signals.
     */
    set model(newValue: T);
    /**
     * Get the current model.
     */
    get model(): T;
    /**
     * Dispose this widget.
     */
    dispose(): void;
    private _model;
    private _modelChanged;
}
/**
 * Props for the UseSignal component
 */
export interface IUseSignalProps<SENDER, ARGS> {
    /**
     * Lumino signal to connect to.
     */
    signal: ISignal<SENDER, ARGS>;
    /**
     * Initial value to use for the sender, used before the signal emits a value.
     * If not provided, initial sender will be undefined
     */
    initialSender?: SENDER;
    /**
     * Initial value to use for the args, used before the signal emits a value.
     * If not provided, initial args will be undefined.
     */
    initialArgs?: ARGS;
    /**
     * Function mapping the last signal value or initial values to an element to render.
     *
     * Note: returns `React.ReactNode` as per
     * https://github.com/sw-yx/react-typescript-cheatsheet#higher-order-componentsrender-props
     */
    children: (sender?: SENDER, args?: ARGS) => React.ReactNode;
    /**
     * Given the last signal value, should return whether to update the state or not.
     *
     * The default unconditionally returns `true`, so you only have to override if you want
     * to skip some updates.
     */
    shouldUpdate?: (sender: SENDER, args: ARGS) => boolean;
}
/**
 * State for the UseSignal component
 */
export interface IUseSignalState<SENDER, ARGS> {
    value: [SENDER?, ARGS?];
}
/**
 * UseSignal provides a way to hook up a Lumino signal to a React element,
 * so that the element is re-rendered every time the signal fires.
 *
 * It is implemented through the "render props" technique, using the `children`
 * prop as a function to render, so that it can be used either as a prop or as a child
 * of this element
 * https://reactjs.org/docs/render-props.html
 *
 *
 * Example as child:
 *
 * ```
 * function LiveButton(isActiveSignal: ISignal<any, boolean>) {
 *  return (
 *    <UseSignal signal={isActiveSignal} initialArgs={true}>
 *     {(_, isActive) => <Button isActive={isActive}>}
 *    </UseSignal>
 *  )
 * }
 * ```
 *
 * Example as prop:
 *
 * ```
 * function LiveButton(isActiveSignal: ISignal<any, boolean>) {
 *  return (
 *    <UseSignal
 *      signal={isActiveSignal}
 *      initialArgs={true}
 *      children={(_, isActive) => <Button isActive={isActive}>}
 *    />
 *  )
 * }
 * ```
 */
export declare class UseSignal<SENDER, ARGS> extends React.Component<IUseSignalProps<SENDER, ARGS>, IUseSignalState<SENDER, ARGS>> {
    constructor(props: IUseSignalProps<SENDER, ARGS>);
    componentDidMount(): void;
    componentWillUnmount(): void;
    private slot;
    render(): React.ReactNode;
}
/**
 * The namespace for VDomRenderer statics.
 */
export declare namespace VDomRenderer {
    /**
     * An interface for a model to be used with vdom rendering.
     */
    interface IModel extends IDisposable {
        /**
         * A signal emitted when any model state changes.
         */
        readonly stateChanged: ISignal<this, void>;
    }
}
/**
 * Concrete implementation of VDomRenderer model.
 */
export declare class VDomModel implements VDomRenderer.IModel {
    /**
     * A signal emitted when any model state changes.
     */
    readonly stateChanged: Signal<this, void>;
    /**
     * Test whether the model is disposed.
     */
    get isDisposed(): boolean;
    /**
     * Dispose the model.
     */
    dispose(): void;
    private _isDisposed;
}
export {};
