CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-snabbdom

A virtual DOM library with focus on simplicity, modularity, powerful features and performance.

Pending
Overview
Eval results
Files

modules.mddocs/

Modules

Snabbdom modules extend the core functionality to handle different aspects of DOM elements. Six built-in modules are provided for common use cases.

Capabilities

Attributes Module

Manages HTML attributes on DOM elements with support for boolean attributes and XML namespaces.

/**
 * Attributes module for managing HTML attributes
 */
const attributesModule: Module;

type Attrs = Record<string, string | number | boolean>;

Usage Example:

import { init, attributesModule, h } from "snabbdom";

const patch = init([attributesModule]);

const vnode = h("input", {
  attrs: {
    type: "text",
    placeholder: "Enter name",
    required: true,  // boolean attribute
    disabled: false  // will be removed
  }
});

Class Module

Provides dynamic CSS class management with boolean flags for toggling classes.

/**
 * Class module for managing CSS classes
 */
const classModule: Module;

type Classes = Record<string, boolean>;

Usage Example:

import { init, classModule, h } from "snabbdom";

const patch = init([classModule]);

const isActive = true;
const vnode = h("div", {
  class: {
    active: isActive,
    inactive: !isActive,
    "btn-primary": true,
    hidden: false  // class will be removed
  }
});

Dataset Module

Manages HTML5 data-* attributes through the HTMLElement.dataset property.

/**
 * Dataset module for managing data-* attributes
 */
const datasetModule: Module;

type Dataset = Record<string, string>;

Usage Example:

import { init, datasetModule, h } from "snabbdom";

const patch = init([datasetModule]);

const vnode = h("button", {
  dataset: {
    action: "save",
    target: "user-form",
    userId: "123"
  }
});
// Results in: <button data-action="save" data-target="user-form" data-user-id="123">

Event Listeners Module

Manages DOM event listeners with efficient listener swapping and array-based handlers.

/**
 * Event listeners module for managing DOM events
 */
const eventListenersModule: Module;

type On = {
  [N in keyof HTMLElementEventMap]?:
    | Listener<HTMLElementEventMap[N]>
    | Array<Listener<HTMLElementEventMap[N]>>;
} & {
  [event: string]: Listener<any> | Array<Listener<any>>;
};

type Listener<T> = (this: VNode, ev: T, vnode: VNode) => void;

Usage Example:

import { init, eventListenersModule, h } from "snabbdom";

const patch = init([eventListenersModule]);

function handleClick(ev: MouseEvent, vnode: VNode) {
  console.log("Button clicked!", ev.target);
}

function handleMouseOver(ev: MouseEvent, vnode: VNode) {
  console.log("Mouse over button");
}

const vnode = h("button", {
  on: {
    click: handleClick,
    mouseover: handleMouseOver,
    keydown: [
      (ev: KeyboardEvent) => console.log("Key:", ev.key),
      (ev: KeyboardEvent) => console.log("Code:", ev.code)
    ]
  }
}, "Interactive Button");

Props Module

Sets DOM element properties directly (not attributes) for form elements and custom properties.

/**
 * Props module for managing DOM element properties
 */
const propsModule: Module;

type Props = Record<string, any>;

Usage Example:

import { init, propsModule, h } from "snabbdom";

const patch = init([propsModule]);

const vnode = h("input", {
  props: {
    type: "checkbox",
    checked: true,
    value: "option1",
    disabled: false
  }
});

// For custom elements
const customElement = h("my-component", {
  props: {
    customProperty: { complex: "object" },
    callback: () => console.log("callback")
  }
});

Style Module

Manages CSS styles with support for animations, delayed properties, and removal transitions.

/**
 * Style module for managing CSS styles with animation support
 */
const styleModule: Module;

type VNodeStyle = ElementStyle & 
  Record<string, string> & {
    delayed?: ElementStyle & Record<string, string>;
    remove?: ElementStyle & Record<string, string>;
    destroy?: ElementStyle & Record<string, string>;
  };

type ElementStyle = Partial<CSSStyleDeclaration>;

Usage Examples:

import { init, styleModule, h } from "snabbdom";

const patch = init([styleModule]);

// Basic styling
const styled = h("div", {
  style: {
    color: "blue",
    fontSize: "16px",
    backgroundColor: "#f0f0f0"
  }
});

// CSS custom properties (variables)
const withVariables = h("div", {
  style: {
    "--primary-color": "#007bff",
    "--font-size": "14px",
    color: "var(--primary-color)"
  }
});

// Delayed properties (for entrance animations)
const animated = h("div", {
  style: {
    opacity: "0",
    transform: "translateY(-10px)",
    transition: "all 0.3s ease",
    delayed: {
      opacity: "1",
      transform: "translateY(0)"
    }
  }
});

// Remove properties (for exit animations)
const fadeOut = h("div", {
  style: {
    opacity: "1",
    transition: "opacity 0.3s ease",
    remove: {
      opacity: "0"
    }
  }
});

Module System

Creating Custom Modules

Modules are objects that implement lifecycle hooks to extend Snabbdom functionality.

interface Module {
  pre?: PreHook;
  create?: CreateHook;
  update?: UpdateHook;
  destroy?: DestroyHook;
  remove?: RemoveHook;
  post?: PostHook;
}

type PreHook = () => any;
type CreateHook = (emptyVNode: VNode, vNode: VNode) => any;
type UpdateHook = (oldVNode: VNode, vNode: VNode) => any;
type DestroyHook = (vNode: VNode) => any;
type RemoveHook = (vNode: VNode, removeCallback: () => void) => any;
type PostHook = () => any;

Custom Module Example:

import { Module, VNode, VNodeData } from "snabbdom";

// Custom module for logging
const logModule: Module = {
  create: (emptyVnode: VNode, vnode: VNode) => {
    console.log("Element created:", vnode.sel);
  },
  update: (oldVnode: VNode, vnode: VNode) => {
    console.log("Element updated:", vnode.sel);
  },
  destroy: (vnode: VNode) => {
    console.log("Element destroyed:", vnode.sel);
  }
};

// Use the custom module
const patch = init([logModule, classModule, styleModule]);

Install with Tessl CLI

npx tessl i tessl/npm-snabbdom

docs

advanced.md

core.md

index.md

jsx.md

modules.md

tile.json