CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-riot

Simple and elegant component-based UI library

Pending
Overview
Eval results
Files

mounting-lifecycle.mddocs/

Mounting and Lifecycle

Core functionality for mounting components to DOM elements and managing their lifecycle. Components go through mount, update, and unmount phases with corresponding lifecycle hooks.

Capabilities

Mount Components

Mounts registered components to DOM elements, creating component instances.

/**
 * Mounting function for globally registered components
 * @param selector - CSS selector string or HTMLElement to mount to
 * @param initialProps - Initial properties to pass to the component
 * @param componentName - Optional specific component name to mount
 * @returns Array of mounted component instances
 */
function mount<Props extends DefaultProps, State extends DefaultState>(
  selector: string | HTMLElement,
  initialProps?: Props,
  componentName?: string
): RiotComponent<Props, State>[];

Usage Examples:

import { mount, register } from "riot";

// Mount all registered components matching their tag names
const components = mount("my-component");

// Mount with initial props
const components = mount("my-timer", { startTime: 10 });

// Mount to specific element
const element = document.getElementById("app");
const components = mount(element, { title: "Hello World" });

// Mount specific component to elements
const components = mount(".widget", { theme: "dark" }, "my-widget");

Unmount Components

Unmounts component instances from DOM elements, cleaning up resources and optionally preserving the root element.

/**
 * Unmounting helper function for components mounted to DOM nodes
 * @param selector - CSS selector string or HTMLElement to unmount from
 * @param keepRootElement - If true, preserves the root DOM element
 * @returns Array of DOM elements that were unmounted
 */
function unmount(
  selector: string | HTMLElement,
  keepRootElement?: boolean
): HTMLElement[];

Usage Examples:

import { unmount } from "riot";

// Unmount all components in matching elements
const elements = unmount("my-component");

// Unmount but keep the DOM element
const elements = unmount(".widgets", true);

// Unmount from specific element
const element = document.getElementById("app");
const elements = unmount(element);

Component Lifecycle

Components follow a predictable lifecycle with hooks for each phase:

Lifecycle Methods

interface RiotComponent<Props = DefaultProps, State = DefaultState> {
  /** Called before component is mounted to DOM */
  onBeforeMount?(props: Props, state: State): void;
  
  /** Called after component is mounted to DOM */
  onMounted?(props: Props, state: State): void;
  
  /** Called before component state/props update */
  onBeforeUpdate?(props: Props, state: State): void;
  
  /** Called after component state/props update */
  onUpdated?(props: Props, state: State): void;
  
  /** Called before component is unmounted from DOM */
  onBeforeUnmount?(props: Props, state: State): void;
  
  /** Called after component is unmounted from DOM */
  onUnmounted?(props: Props, state: State): void;
  
  /** Optional method to control when component should update */
  shouldUpdate?(newProps: Props, oldProps: Props): boolean;
}

Component Instance Methods

Once mounted, component instances provide methods for state management:

interface RiotComponent<Props = DefaultProps, State = DefaultState> {
  /** Mount component to DOM element */
  mount(
    element: HTMLElement,
    initialState?: State,
    parentScope?: object
  ): RiotComponent<Props, State>;
  
  /** Update component state and re-render */
  update(
    newState?: Partial<State>,
    parentScope?: object
  ): RiotComponent<Props, State>;
  
  /** Unmount component from DOM */
  unmount(keepRootElement?: boolean): RiotComponent<Props, State>;
  
  /** Query single element within component root */
  $(selector: string): Element | null;
  
  /** Query multiple elements within component root */
  $$(selector: string): Element[];
}

Component Properties

Component instances have read-only properties and mutable state:

interface RiotComponent<Props = DefaultProps, State = DefaultState> {
  /** Read-only props passed to component */
  readonly props: Props;
  
  /** Root DOM element of the component */
  readonly root: HTMLElement;
  
  /** Component name (if registered) */
  readonly name?: string;
  
  /** Slot data for child content */
  readonly slots: TagSlotData[];
  
  /** Mutable component state */
  state: State;
  
  /** Optional child component mappings */
  components?: RiotComponentsMap;
}

Usage Example:

const componentDef = {
  onBeforeMount(props, state) {
    this.state = { count: props.initial || 0 };
  },
  
  onMounted(props, state) {
    console.log("Component mounted with state:", state);
  },
  
  increment() {
    this.update({ count: this.state.count + 1 });
  },
  
  onBeforeUpdate(props, state) {
    console.log("Updating from", this.state.count, "to", state.count);
  },
  
  onUnmounted() {
    console.log("Component cleaned up");
  }
};

Types

type DefaultProps = Record<PropertyKey, any>;
type DefaultState = Record<PropertyKey, any>;

type TagSlotData = {
  id: string;
  html: string;
  bindings: BindingData[];
};

type RiotComponentsMap = {
  [key: string]: RiotComponentWrapper<RiotComponent>;
};

Install with Tessl CLI

npx tessl i tessl/npm-riot

docs

compilation.md

component-factory.md

component-registration.md

index.md

mounting-lifecycle.md

plugin-system.md

pure-components.md

utilities.md

tile.json