vanjs-htm
Version:
HTM with VanJS for JSX-like syntax in vanilla JavaScript using VanJS reactivity.
107 lines (106 loc) • 5.02 kB
TypeScript
import type htm from 'htm';
import type { ChildDom, State, Van } from 'vanjs-core';
import type { KeyType, ValueType, list } from 'vanjs-ext';
export type { ChildDom, Van, htm, list };
/**
* Configuration options for initializing a VanHTM instance.
*/
export type VanHTMOptions = {
/** The htm template literal parser instance. */
htm: typeof htm;
/**
* A VanJS instance (or a compatible subset) providing `add` and `tags` functionalities.
*/
van: Pick<Van, 'add' | 'tags'>;
/**
* Optional, an object containing VanJS extensions.
* `list` from `vanjs-ext` is required for the `for:each` directive.
*/
vanX?: {
list: typeof list;
};
/**
* Optional HTML entity decoder function.
* This function is applied to static text content within templates.
* It is required if using a build of `van-htm` that has decoding enabled (e.g., `/withDecoding`).
* The function should take a string with HTML entities (e.g., '&') and return a string with decoded characters (e.g., '&').
* @param input The string containing HTML entities.
* @returns The string with HTML entities decoded.
*/
decode?: (input: string) => string;
};
/**
* Represents a VanHTM instance, providing template literal functionality and portal management.
*/
export type VanHTM = {
/**
* An htm-compatible template literal tag function.
* Parses HTML-like template strings and produces VanJS DOM elements or ChildDom.
* Supports special directives like `for:each`, `show:when`, `show:fallback`, and `portal:mount`.
* @param template The template string array.
* @param substitutions Values to be interpolated into the template.
* @returns The DOM element(s) or ChildDom generated from the template.
*/
html: <T = ChildDom>(template: TemplateStringsArray, ...substitutions: any[]) => T;
/**
* Removes portal elements that were previously rendered by this VanHTM instance.
* It searches for comment placeholders within the `parent` node and removes
* corresponding elements from the `portalTarget` (or document.body by default)
* using querySelector.
* @param parent The parent Node where the portal placeholder comments were rendered.
* @param portalTarget Optional. The Element or CSS selector string for the container
* where portal content was mounted. Defaults to `document.body`.
*/
rmPortals: (parent: Node, portalTarget?: Element | string) => void;
};
/**
* The itemFunc that the `for:each` directive uses with vanX.list.
* Refer to https://vanjs.org/x for more details.
* The function `((v, deleter, k) => Node)` is used to generate the UI element (or rarely, text node) for each list item.
* @template T The type of the items in the list <typeof items> (items must be vanX.reactive).
* @param v A State object corresponding to each list item.
* You can directly use it as a State-based property / child node, read its value for building the UI element, and/or set its value in some event handlers.
* @param deleter A function (() => void) that can be used in the event handler to delete the entire item.
* Typically the deleter function can be used as the onclick handler of a deletion button.
* @param k (Requires VanX 0.2.0 or later) the key of the corresponding list item, which is the index if items is an Array or the property key if items is a plain object.
* @returns The Node or DOM element to be rendered for the item.
*/
export type ListItemFunction<T extends object> = (v: State<ValueType<T>>, deleter: () => void, k: KeyType<T>) => Node;
/**
* Creates a VanHTM instance that provides HTML template literal functionality with VanJS integration.
*
* @param options - Configuration object for VanHTM
* @param options.htm - The htm template literal parser
* @param options.van - VanJS instance with 'add' and 'tags' methods
* @param options.vanX - VanJS extensions object containing the 'list' function
* @param options.decode - Optional HTML entity decoder function for template content, required in builds `withDecoding`
*
* @returns VanHTM instance with html template function and portal management (rmPortals)
*
* @example
* ```typescript
* import htm from 'htm';
* import van from 'vanjs-core';
* import { list, reactive } from 'vanjs-ext';
* import vanHTM from 'van-htm';
*
* const { html } = vanHTM({ htm, van, vanX: { list } });
*
* // Basic usage
* const element = html`<div>Hello World</div>`;
*
* // With conditional rendering
* const conditional = html`<div show:when=${true}>Visible</div>`;
*
* // With loops
* const items = reactive([1, 2, 3]);
* const list = html`<ul for:each=${items}>${(v) => html`<li>${v}</li>`}</ul>`;
*
* // With portals
* const portal = html`<div portal:mount="body">Portaled content</div>`;
*
* van.add(document.body, element, conditional, list);
* ```
*/
declare const vanHTM: (options: VanHTMOptions) => VanHTM;
export default vanHTM;