yuzu-application
Version:
Yuzu Application Manager
204 lines (203 loc) • 6.9 kB
TypeScript
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;
}