UNPKG

@tmorin/ceb-templating-builder

Version:

The package is part of the `<ceb/>` library. It provides a builder which enhances the definition of Custom Elements (v1) with a templating solution.

236 lines (235 loc) 8.77 kB
import { Builder, CustomElementConstructor, HooksRegistration } from "@tmorin/ceb-elements-core"; /** * The common parameters of the rendering. */ export declare type TemplateParameters = { /** * When true, the rendering solution render the template with a _scope_. */ greyDom: boolean; }; /** * A template updates the children of an element. * @template P The type of the template parameters. */ export interface Template<P = any> { /** * Render the template. * @param destination the destination node * @param parameters the parameters of the rendering */ render(destination: DocumentFragment | Element, parameters?: TemplateParameters & P): void; } /** * The builder handles the integration of a templating solution to update the content of the Custom Element. * * Firstly, the integration of the templating solution has to be defined in a method, by default the method name is `render`. * The implementation of the method (i.e. the method `render`) must return an instance of {@link Template}. * * Secondly, the render method is wrapped by the builder in order to render the {@link Template} once returned. * That means, each time the render method is invoked, the returned {@link Template} is rendered automatically. * The wrapping is also responsible to select the right destination of the template: Light DOM vs Shadow DOM. * * By default, the template is rendered into the Light DOM of the Custom Element. * However, the builder can render the template into the Shadow DOM with {@link TemplateBuilder.shadow}. * Another switch, {@link TemplateBuilder.grey} can be used to force the rendering into a _scope_. * * If the _scope_ is not required, the Custom Element content can be simply preserve from ancestral rendering process with {@link TemplateBuilder.preserveContent}. * * Attributes can also be preserved from ancestral rendering process with {@link TemplateBuilder.preserveAttributes}. * * By default, the name of the wrapped method is `render`. * However, the name can be changed with {@link TemplateBuilder.method}. * * When a {@link Template} is rendered, template parameters can be provided to the {@link Template.render} method. * The template parameters can be set with {@link TemplateBuilder.parameters}. * * The library provides a built-in template solution: {@link html}. * * Finally, the builder can be registered using the method {@link ElementBuilder.builder} of the main builder (i.e. {@link ElementBuilder}). * However, it can also be registered with the decorative style using the decorator {@link TemplateBuilder.decorate}. * * @template E the type of the Custom Element * @template P The type of the template parameters. */ export declare class TemplateBuilder<E extends HTMLElement, P> implements Builder<E> { private _isGrey; private _preserveContent; private _preserveAttributes; private _isShadow; private _isFocusDelegation?; private _methName; private _parameters?; private constructor(); /** * Provides a fresh builder. * @template E the type of the Custom Element * @template P The type of the template parameters. */ static get<E extends HTMLElement, P>(): TemplateBuilder<E, P>; /** * Forces the rendering into the Shadow DOM. * * {@link TemplateBuilder.shadow} and {@link TemplateBuilder.grey} are exclusives. * * @example * ```typescript * import {ElementBuilder} from "@tmorin/ceb-elements-core" * import {html} from "@tmorin/ceb-templating-literal" * import {TemplateBuilder} from "@tmorin/ceb-templating-builder" * class HelloWorld extends HTMLElement { * value = "World" * render() { * return html`Hello, ${this.value}!` * } * } * ElementBuilder.get().builder( * TemplateBuilder.get().shadow() * ).register() * ``` * * @param focus when true the focus will be delegated to the shadow DOM */ shadow(focus?: boolean): this; /** * Forces the rendering into the Grey DOM. * * {@link TemplateBuilder.shadow} and {@link TemplateBuilder.grey} are exclusives. * {@link TemplateBuilder.preserveContent} and {@link TemplateBuilder.grey} are exclusives. * * @example * ```typescript * import {ElementBuilder} from "@tmorin/ceb-elements-core" * import {html} from "@tmorin/ceb-templating-literal" * import {TemplateBuilder} from "@tmorin/ceb-templating-builder" * class HelloWorld extends HTMLElement { * value = "World" * render() { * return html`Hello, ${this.value}!` * } * } * ElementBuilder.get().builder( * TemplateBuilder.get().grey() * ).register() * ``` */ grey(): this; /** * Prevent mutations on the Custom Element content from rendering processes coming from ancestors. * * {@link TemplateBuilder.preserveContent} and {@link TemplateBuilder.grey} are exclusives. * * @example * ```typescript * import {ElementBuilder} from "@tmorin/ceb-elements-core" * import {html} from "@tmorin/ceb-templating-literal" * import {TemplateBuilder} from "@tmorin/ceb-templating-builder" * class HelloWorld extends HTMLElement { * value = "World" * render() { * return html`Hello, ${this.value}!` * } * } * ElementBuilder.get().builder( * TemplateBuilder.get().preserveContent() * ).register() * ``` */ preserveContent(): this; /** * Preserve attributes of the Custom Element from rendering processes coming from ancestors. * * @example * ```typescript * import {ElementBuilder} from "@tmorin/ceb-elements-core" * import {html} from "@tmorin/ceb-templating-literal" * import {TemplateBuilder} from "@tmorin/ceb-templating-builder" * class HelloWorld extends HTMLElement { * value = "World" * render() { * return html`Hello, ${this.value}!` * } * } * ElementBuilder.get().builder( * TemplateBuilder.get().preserveAttributes("class", "id") * ).register() * ``` * * @param names the names of the attribute */ preserveAttributes(...names: Array<string>): this; /** * Overrides the default render method name. * * @example * ```typescript * import {ElementBuilder} from "@tmorin/ceb-elements-core" * import {html} from "@tmorin/ceb-templating-literal" * import {TemplateBuilder} from "@tmorin/ceb-templating-builder" * class HelloWorld extends HTMLElement { * value = "World" * doRender() { * return html`Hello, ${this.value}!` * } * } * ElementBuilder.get().builder( * TemplateBuilder.get().method("doRender") * ).register() * ``` * * @param methName the render method name */ method(methName: string): this; /** * Set render parameters. * * @example * ```typescript * import {ElementBuilder} from "@tmorin/ceb-elements-core" * import {html} from "@tmorin/ceb-templating-literal" * import {TemplateBuilder} from "@tmorin/ceb-templating-builder" * import {UpdateParameters} from "@tmorin/ceb-templating-engine" * class HelloWorld extends HTMLElement { * value = "World" * doRender() { * return html`Hello, ${this.value}!` * } * } * ElementBuilder.get().builder( * TemplateBuilder.get<UpdateParameters>() * .parameters({ greyDom: true }) * ).register() * ``` * * @param parameters the parameters */ parameters(parameters: P): this; /** * Decorates the render method. * * @example * ```typescript * import {ElementBuilder} from "@tmorin/ceb-elements-core" * import {html} from "@tmorin/ceb-templating-literal" * import {TemplateBuilder} from "@tmorin/ceb-templating-builder" * @ElementBuilder.get<HelloWorld>().decorate() * class HelloWorld extends HTMLElement { * value = "World" * @TemplateBuilder.get().decorate() * render() { * return html`Hello, ${this.value}!` * } * } * ``` */ decorate<E extends HTMLElement>(): MethodDecorator; /** * This API is dedicated for developer of Builders. * @protected */ build(Constructor: CustomElementConstructor<E>, hooks: HooksRegistration<E & { [key: string]: any; __ceb_engine_preserve_children?: boolean; __ceb_engine_preserve_attributes?: Array<string>; }>): void; }