diff --git a/src/crank.ts b/src/crank.ts index 50c34b8f3..20159a18c 100644 --- a/src/crank.ts +++ b/src/crank.ts @@ -253,6 +253,41 @@ export function createElement( return new Element(tag, props as TagProps); } +/** + * Provides dynamic tag functions for creating elements. + * + * Accessing a property returns a function that calls `createElement` + * with the property name as the tag name. + * + * @example + * tags.div({ class: "foo" }, "Hello"); + */ +export const tags = new Proxy( + Object.create(null) as Record< + string, + ( + props?: Record | null | undefined, + ...children: Array + ) => Element + >, + { + get(target, tag: string | symbol) { + if (typeof tag === "symbol" || tag === "then") { + return undefined; + } + + if (!(tag in target)) { + target[tag] = ( + props?: Record | null | undefined, + ...children: Array + ) => createElement(tag, props, ...children); + } + + return target[tag]; + } + } +); + /** Clones a given element, shallowly copying the props object. */ export function cloneElement( el: Element,