UNPKG

@xeito/core

Version:

Core modules for Xeito | Framework for building web applications

394 lines (369 loc) 13.2 kB
import { Hole } from 'uhtml'; export { Hole, Renderable, TemplateFunction, html, render, svg } from 'uhtml'; interface PropChange { name: string; oldValue: string; newValue: string; } interface ActionResult { (...args: any[]): void; } declare class XeitoComponent extends HTMLElement { /** * Xeito internals object * Will be populated by the @Component decorator * with the component's metadata */ private _XeitoInternals; private _DOMRoot; private _template; private _state; private _props; private _watchers; private _IActionIndex; private _actionInstances; private _IPipeIndex; private _pipeInstances; private _stores; private _storeSubscriptions; private _dirty; /** * Global properties object (will be populated by the parent component or the Xeito instance) */ global: Record<string, any>; /** * Slot Content * Will be populated by the constructor * It will contain the slotted content of the component * eg: <xeito-component><div slot="header">Header</div></xeito-component> * slotContent.header will contain the div element * This can be accessed inside the render method * eg: html`<div>${this.slotContent.header}</div>` */ slotContent: Record<string, any>; constructor(); /** * Native connectedCallback * Will be called when the component is connected to the DOM * */ connectedCallback(): void; /** * Get the slotted content of the component * @returns { Record<string, any> } Slot content object */ private getSlotContent; /** * Assign children global * Assigns the global property to the children of the component */ private assignChildrenGlobal; /** * Bind methods * Binds the methods of the component to the component itself * This is done to avoid having to wrap the methods in arrow functions * eg: onClick={this.onClick} instead of onClick={() => this.onClick()} * NOTE: Arrow functions are still required to pass data to the method or native events * eg: onClick={() => this.onClick(data)} or onClick={(e) => this.onClick(e)} */ private bindMethods; /** * Request an update of the component * This will schedule an update of the template (batching updates by using a promise) */ requestUpdate(): void; /** * Force an update of the component (no batching) * This will update the template immediately without batching * This should be used with caution as it can cause performance issues */ forceUpdate(): void; /** * Update the component * This will render the template and update the DOM * It will also reset the pipe index before rendering */ private _update; /** * Sets a state value and triggers an update if needed * @param key Key of the state to set * @param value Value to set * @param triggerUpdate Whether to trigger an update or not */ setState(key: string, value: any): void; /** * Returns the value of a state key * @param key Key of the state to get * @returns Value of the state key */ getState(key: string): any; /** * Sets a prop value and triggers an update * @param key Key of the prop to set * @param value Value to set */ setProp(key: string, value: any): void; /** * Returns the value of a prop key * @param key Key of the prop to get * @returns Value of the prop key */ getProp(key: string): any; /** * Sets a store and subscribes to it to trigger updates when it changes * @param key Key of the property that contains the store * @param store The store to set */ setStore(key: string, store: any): void; /** * Returns the store for the given key * @param key Key of the property that contains the store * @returns The store */ getStore(key: string): any; /** * Use method (Use an action inside the component) * The 'use' method is used to provide actions to the template * Actions have to be provided in the Component decorator options * eg: @Component({ actions: [Action1, Action2] }) * @param selector * @param args * @returns */ use(selector: string, ...args: any[]): ActionResult | void; /** * Pipe method (Use a pipe inside the component) * The 'pipe' method is used to provide pipes to the template * Pipes have to be provided in the Component decorator options * eg: @Component({ pipes: [Pipe1, Pipe2] }) * @param selector * @param args * @returns */ pipe(selector: string, ...args: any[]): any; /** * Native attributeChangedCallback * Calls the onChanges method and requests an update of the component * @param name * @param oldValue * @param newValue */ attributeChangedCallback(this: any, name: string, oldValue: string, newValue: string): void; /** * Native disconnectedCallback * Calls the onWillUnmount method */ disconnectedCallback(): void; /** * Render method desgin to be overriden by the user */ render(): Hole | void; /** * Lifecycle methods desgin to be overriden by the user * onInit: Called when the component is initialized (constructor) * onWillMount: Called before the first render (connectedCallback) * onDidMount: Called after the first render (connectedCallback) * onUnmount: Called when the component is unmounted (disconnectedCallback) */ onInit(): any; onWillMount(): any; onDidMount(): any; onUnmount(): any; /** * On changes method desgin to be overriden by the user * Gets called when an attribute/property changes (attributeChangedCallback) * @param { PropChange } change Prop changes object */ onPropChange(change: PropChange): void; } interface XeitoGlobal { properties: Record<string, any>; components: Array<typeof XeitoComponent>; pipes: any[]; actions: any[]; } declare class Xeito { private _rootElement; private plugins; global: XeitoGlobal; constructor(rootComponent: any); /** * * @param rootElement The root element to render the root component in (can be a string selector) */ bootstrap(rootElement: HTMLElement | string): void; /** * Register a plugin to the Xeito instance * @param plugin The plugin class to register * @param options The options to pass to the plugin install method */ usePlugin(plugin: any, options?: any): void; /** * Attaches the global object to all the global components * Including the root component (which is a global component) * This is called during the bootstrap process */ private attachGlobal; } declare class XeitoPlugin { private _xeito; constructor(xeito: Xeito); /** * Install method called by Xeito when the plugin is registered * Designed to be overriden by the plugin author * @param {any} options The options passed to the plugin when it was registered */ install(options?: any): void; /** * Register a global action that can be used in any component * @param {string} selector The selector of the action * @param {any} action The action function */ registerGlobalAction(action: any): void; /** * Register a global property that can be used in any component * @param {string} selector The selector of the property * @param {any} property The property value */ registerGlobalProperty(selector: string, property: any): void; /** * Register a global pipe that can be used in any component * @param {string} selector The selector of the pipe * @param {any} pipe The pipe function */ registerGlobalPipe(pipe: any): void; /** * Register a global component that can be used in any component without importing it */ registerGlobalComponent(component: any): void; } interface ActionMetadata { selector: string; } declare function Action(actionMetadata: ActionMetadata): <T extends new (...args: any[]) => {}>(constructor: T) => { new (...args: any[]): { selector: string; update(element: any, ...args: any[]): void; clean(): void; }; } & T; interface ComponentMetadata { selector: string; shadow?: boolean; imports?: any[]; actions?: any[]; pipes?: any[]; services?: any[]; } declare function Component(componentMetadata: ComponentMetadata): (constructor: any) => any; interface EventConfig { name?: string; composed?: boolean; bubbles?: boolean; cancelable?: boolean; } /** * Event Decorator * Used to decorate a property on a class to create a new Event Emitter * The Event Emitter is a class that contains a single method: emit * * This decorator wraps the property with a getter/setter that returns a new Event Emitter * @param eventConfig * @returns */ declare function Event(eventConfig?: EventConfig): (target: any, key: string) => void; declare function Global(propertyName?: string): (target: any, key: string) => void; interface PipeMetadata { selector: string; } declare function Pipe(pipeMetadata: PipeMetadata): <T extends new (...args: any[]) => {}>(constructor: T) => { new (...args: any[]): { selector: string; previousValue: any; previousArgs: any[]; previousResult: any; update(value: any, ...args: any[]): any; clean(): void; }; } & T; /** * Property decorator * Allows the user to define a custom attribute in the component tag * The property value will be set to the received attribute value */ declare function Prop(): (target: any, key: string) => void; /** * Ref decorator * It only returns an object of type ElementRef which is just an object with a current property * The current property is the element reference that gets popuplated upon rendering * * User could achieve the same result with an empty object declaration * But this decorator is more readable than having an empty object declaration in the class * * @returns {PropertyDecorator} */ declare function Ref(): (target: any, key: any) => void; /** * State decorator * Wraps the state property with a Proxy or a getter/setter * This way we can detect when the state changes and trigger a re-render */ declare function State(): (target: any, key: string) => void; /** * Decorator for watching changes to reactive properties. * Must be applied to a method of a component class. * This decorator adds a setter to gain access to the instance. * Then it adds the method to the list of watchers for the given property. * The setter is removed after the first call and replaced with the original method. * @param propertyNames Names of properties to watch for changes. (must be decorated with @State) * * Usage example: * @Watch('count', 'name') * watchCount(update: WatchUpdate) { * // This method will be called when the value of the 'count' or 'name' property changes * } */ declare function Watch(...propertyNames: string[]): (target: any, key: string, descriptor: any) => void; /** * Event Emitter class * Used by the `Event` decorator to return a new Event Emitter when the property is accessed * The event emitter contains only a single method: `emit` * The emit method will dispatch a new `CustomEvent` with the given name and detail * The EventConfig is set by the decorator based on the user configuration or the reflected metadata */ declare class Emitter<T> { private clazz; private eventConfig; constructor(clazz: HTMLElement, eventConfig: EventConfig); emit(value: T): void; } interface ElementRef { current: HTMLElement | any; } /** * Interface for the value of the parameter * Received by a method decorated with @Watch * eg: * @Watch('$count', '$name') * watchCount(update: WatchUpdate) { * // update.name = '$count' or '$name' * // update.value = the new value of the state for the given property name * } */ interface WatchUpdate { [name: string]: any; value: any; } interface XeitoInternals { selector?: string; actions?: any[]; pipes?: any[]; imports?: any[]; services?: any[]; shadow?: boolean; DOMRoot?: Element | HTMLElement | Node | null; template?: Element | HTMLElement | Node | null; global?: Record<string, any>; componentStyleSheet?: CSSStyleSheet[]; } export { Action, ActionMetadata, ActionResult, Component, ComponentMetadata, ElementRef, Emitter, Event, EventConfig, Global, Pipe, PipeMetadata, Prop, PropChange, Ref, State, Watch, WatchUpdate, Xeito, XeitoComponent, XeitoGlobal, XeitoInternals, XeitoPlugin };