import { IComponentConstructable } from 'yuzu/types';
import { Component } from 'yuzu';
import { IContext } from './context';
export declare type entrySelectorFn = (sbx: Sandbox<any>) => boolean | HTMLElement[];
export declare type sandboxComponentOptions = [IComponentConstructable<Component<any, any>>, Record<string, any>];
export interface ISandboxRegistryEntry {
    component: IComponentConstructable<Component<any, any>>;
    selector: string | entrySelectorFn;
    [key: string]: any;
}
export interface ISandboxOptions {
    components?: (IComponentConstructable<Component<any, any>> | sandboxComponentOptions)[];
    root: HTMLElement | string;
    context: IContext<any>;
    id: string;
}
/**
 * A sandbox can be used to initialize a set of components based on an element's innerHTML.
 *
 * Lets say we have the following component:
 *
 * ```js
 * class Counter extends Component {
 *   static root = '.Counter';
 *
 *   // other stuff here ...
 * }
 * ```
 *
 * We can register the component inside a sandbox like this:
 *
 * ```js
 * const sandbox = new Sandbox({
 *   components: [Counter],
 *   id: 'main', // optional
 * });
 *
 * sandbox.mount('#main');
 * ```
 *
 * In this way the sandbox will attach itself to the element matching `#main` and will traverse its children
 * looking for every `.Counter` element attaching an instance of the Counter component onto it.
 *
 * To prevent a component for being initialized (for example when you want to initialize it at a later moment)
 * just add a `data-skip` attribute to its root element.
 *
 * @class
 * @param {object} config
 * @param {Component[]|[Component, object][]} [config.components] Array of components constructor or array with [ComponentConstructor, options]
 * @param {HTMLElement|string} [config.root=document.body] Root element of the sandbox. Either a DOM element or a CSS selector
 * @param {string} [config.id] ID of the sandbox
 * @property {string} $id Sandbox internal id
 * @property {HTMLElement} $el Sandbox root DOM element
 * @property {Context} $ctx Internal [context](/packages/yuzu-application/api/context). Used to share data across child instances
 * @property {object[]} $registry Registered components storage
 * @property {Map} $instances Running instances storage
 * @returns {Sandbox}
 */
export declare class Sandbox<S = {}> extends Component<S, ISandboxOptions> {
    static SB_DATA_ATTR: string;
    defaultOptions(): ISandboxOptions;
    $id: string;
    $ctx?: IContext;
    $registry: ISandboxRegistryEntry[];
    $instances: Map<string | entrySelectorFn, Component<any, any>[]>;
    /**
     * Creates a sandbox instance.
     *
     * @constructor
     */
    constructor(options?: Partial<ISandboxOptions>);
    /**
     * ```js
     * register(params)
     * ```
     *
     * Registers a new component into the sandbox. The registered components
     * will be traversed on `.mount()` initializing every matching component.
     *
     * @param {object} params Every property other than `component` and `selector` will be used as component option
     * @param {Component} params.component Component constructor
     * @param {string} params.selector Child component root CSS selector
     * @example
     * sandbox.register({
     *   component: Counter,
     *   selector: '.Counter',
     *   theme: 'dark' // <-- instance options
     * });
     */
    register<C extends Component<any, any>>(params: {
        component: IComponentConstructable<C>;
        selector: string | entrySelectorFn;
        [key: string]: any;
    }): void;
    /**
     * ```js
     * start([data])
     * ```
     *
     * **DEPRECATED!** Use `sandbox.mount(root)` instead.
     *
     * Starts the sandbox with an optional context.
     *
     * The store will be available inside each component at `this.$context`.
     *
     * @deprecated
     * @param {object} [data] Optional context data object to be injected into the child components.
     * @fires Sandbox#beforeStart
     * @fires Sandbox#start Events dispatched after all components are initialized
     * @returns {Sandbox}
     * @example
     * sandbox.start();
     *
     * // with context data
     * sandbox.start({ globalTheme: 'dark' });
     */
    start(data?: {}): this;
    /**
     * ```js
     * mount([el], [state])
     * ```
     *
     * Enhances `Component.mount()` by firing the child components discovery logic.
     * By default will use `document.body` as mount element.
     *
     * @param {string|Element} el Component's root element
     * @param {object|null} [state={}] Initial state
     * @fires Sandbox#beforeStart
     * @fires Sandbox#start Events dispatched after all components are initialized
     * @returns {Sandbox}
     */
    mount(el: string | Element, state?: Partial<S> | null): this;
    /**
     * Setups the sandbox context passed in the options.
     *
     * @ignore
     */
    setup(): void;
    /**
     * Initializes the sandbox child components.
     *
     * @ignore
     * @returns {Promise}
     */
    discover(): Promise<void>;
    /**
     * Resolves a configured component selector to a list of DOM nodes or a boolean (for detached components)
     *
     * @ignore
     * @param {string|function} selector Selector string or function.
     * @returns {HTMLElement[]|boolean}
     */
    resolveSelector(selector: string | entrySelectorFn): HTMLElement[] | boolean;
    /**
     * Creates a component instance.
     * Reads inline components from the passed-in root DOM element.
     *
     * @ignore
     * @param {object} options instance options
     * @param {HTMLElement} [el] Root element
     * @returns {Component}
     */
    createInstance<C extends Component<any, any>>(ComponentConstructor: IComponentConstructable<C>, options: Record<string, any>, el?: HTMLElement): Promise<C>;
    /**
     * ```js
     * stop()
     * ```
     *
     * **DEPRECATED!** Use `sandbox.destroy()` instead.
     *
     * Stops every running component, clears sandbox events and destroys the instance.
     *
     * @deprecated
     * @fires Sandbox#beforeStop
     * @fires Sandbox#stop
     * @returns {Promise<void>}
     * @example
     * sandbox.stop();
     */
    stop(): Promise<void>;
    /**
     * ```js
     * destroy()
     * ```
     *
     * Enhances `Component.destroy()`.
     * Stops every running component, clears sandbox events and destroys the instance.
     *
     * @deprecated
     * @fires Sandbox#beforeStop
     * @fires Sandbox#stop
     * @returns {Promise<void>}
     * @example
     * sandbox.destroy();
     */
    destroy(): Promise<void>;
    /**
     * Removes events and associated store
     *
     * @ignore
     */
    clear(): void;
}
