diff --git a/src/dom/h.ts b/src/dom/h.ts index 045296f..6b7cdcf 100644 --- a/src/dom/h.ts +++ b/src/dom/h.ts @@ -4,18 +4,15 @@ import { Children, DoomProperties, DoomProperty, + HTMLTag, Reactive, Style, Styles, } from "./types"; import { updateChildren } from "./updateChildren"; -export function h( - component: K, - a?: DoomProperties | Children, - b?: Children -): Element { - const el: HTMLElementTagNameMap[K] = document.createElement(component as K); +export function h(component: K, a?: DoomProperties | Children, b?: Children): Element { + const el: HTMLTag[K] = document.createElement(component as K); const { properties, children } = prepareArguments(a, b); toProperties(properties).forEach(({ key, value }) => { @@ -51,10 +48,7 @@ function t(text: Reactive): Text { return textNode; } -function addChildren( - el: HTMLElementTagNameMap[K], - children: Children | undefined -) { +function addChildren(el: HTMLTag[K], children: Children | undefined) { if (typeof children === "function") { effect(() => updateChildren(el, evaluateChildNodes(children))); } else if (Array.isArray(children)) { @@ -64,18 +58,14 @@ function addChildren( } } -function appendTo( - element: HTMLElementTagNameMap[K] -): (c: ChildNode) => ChildNode { +function appendTo(element: HTMLTag[K]): (c: ChildNode) => ChildNode { return (child: ChildNode) => { element.appendChild(child); return child; }; } -function toProperties( - properties: DoomProperties -): DoomProperty[] { +function toProperties(properties: DoomProperties): DoomProperty[] { return Object.entries(properties).map((property) => { return { key: property[0], value: property[1] } as DoomProperty; }); @@ -97,18 +87,12 @@ function evaluateChildNodes(children: Reactive): ChildNode[] { : [toChildNode(reactive)]; } -function toChildNode(child: Child): ChildNode { - return typeof child === "object" ? child : t(child); -} +const toChildNode = (child: Child) => typeof child === "object" ? child : t(child); const pass = (prop: Reactive): T => prop as T; -const evaluate = (prop: Reactive): T => - typeof prop !== "function" ? prop : (prop as Function)(); +const evaluate = (prop: Reactive): T => typeof prop !== "function" ? prop : (prop as Function)(); -function prepareArguments( - a: unknown, - b: unknown -) { +function prepareArguments(a: unknown, b: unknown) { if (!a && !b) { return { properties: {} as DoomProperties, children: [] as Children }; } diff --git a/src/dom/html.ts b/src/dom/html.ts index 4ffb306..006dc21 100644 --- a/src/dom/html.ts +++ b/src/dom/html.ts @@ -1,113 +1,113 @@ import { h } from "./h"; -import { Children, Component, DoomProperties } from "./types"; +import { HTMLComponent } from "./types"; -export const A: Component | Children | undefined> = (props, children) => { return h("a", props, children); } -export const Abbr: Component | Children | undefined> = (props, children) => { return h("abbr", props, children); } -export const Address: Component | Children | undefined> = (props, children) => { return h("address", props, children); } -export const Area: Component | Children | undefined> = (props, children) => { return h("area", props, children); } -export const Article: Component | Children | undefined> = (props, children) => { return h("article", props, children); } -export const Aside: Component | Children | undefined> = (props, children) => { return h("aside", props, children); } -export const Audio: Component | Children | undefined> = (props, children) => { return h("audio", props, children); } -export const B: Component | Children | undefined> = (props, children) => { return h("b", props, children); } -export const Base: Component | Children | undefined> = (props, children) => { return h("base", props, children); } -export const Bdi: Component | Children | undefined> = (props, children) => { return h("bdi", props, children); } -export const Bdo: Component | Children | undefined> = (props, children) => { return h("bdo", props, children); } -export const Blockquote: Component | Children | undefined> = (props, children) => { return h("blockquote", props, children); } -export const Body: Component | Children | undefined> = (props, children) => { return h("body", props, children); } -export const Br: Component | Children | undefined> = (props, children) => { return h("br", props, children); } -export const Button: Component | Children | undefined> = (props, children) => { return h("button", props, children); } -export const Canvas: Component | Children | undefined> = (props, children) => { return h("canvas", props, children); } -export const Caption: Component | Children | undefined> = (props, children) => { return h("caption", props, children); } -export const Cite: Component | Children | undefined> = (props, children) => { return h("cite", props, children); } -export const Code: Component | Children | undefined> = (props, children) => { return h("code", props, children); } -export const Col: Component | Children | undefined> = (props, children) => { return h("col", props, children); } -export const Colgroup: Component | Children | undefined> = (props, children) => { return h("colgroup", props, children); } -export const Data: Component | Children | undefined> = (props, children) => { return h("data", props, children); } -export const Datalist: Component | Children | undefined> = (props, children) => { return h("datalist", props, children); } -export const Dd: Component | Children | undefined> = (props, children) => { return h("dd", props, children); } -export const Del: Component | Children | undefined> = (props, children) => { return h("del", props, children); } -export const Details: Component | Children | undefined> = (props, children) => { return h("details", props, children); } -export const Dfn: Component | Children | undefined> = (props, children) => { return h("dfn", props, children); } -export const Dialog: Component | Children | undefined> = (props, children) => { return h("dialog", props, children); } -export const Div: Component | Children | undefined> = (props, children) => { return h("div", props, children); } -export const Dl: Component | Children | undefined> = (props, children) => { return h("dl", props, children); } -export const Dt: Component | Children | undefined> = (props, children) => { return h("dt", props, children); } -export const Em: Component | Children | undefined> = (props, children) => { return h("em", props, children); } -export const Embed: Component | Children | undefined> = (props, children) => { return h("embed", props, children); } -export const Fieldset: Component | Children | undefined> = (props, children) => { return h("fieldset", props, children); } -export const Figcaption: Component | Children | undefined> = (props, children) => { return h("figcaption", props, children); } -export const Figure: Component | Children | undefined> = (props, children) => { return h("figure", props, children); } -export const Footer: Component | Children | undefined> = (props, children) => { return h("footer", props, children); } -export const Form: Component | Children | undefined> = (props, children) => { return h("form", props, children); } -export const H1: Component | Children | undefined> = (props, children) => { return h("h1", props, children); } -export const H2: Component | Children | undefined> = (props, children) => { return h("h2", props, children); } -export const H3: Component | Children | undefined> = (props, children) => { return h("h3", props, children); } -export const H4: Component | Children | undefined> = (props, children) => { return h("h4", props, children); } -export const H5: Component | Children | undefined> = (props, children) => { return h("h5", props, children); } -export const H6: Component | Children | undefined> = (props, children) => { return h("h6", props, children); } -export const Head: Component | Children | undefined> = (props, children) => { return h("head", props, children); } -export const Header: Component | Children | undefined> = (props, children) => { return h("header", props, children); } -export const Hgroup: Component | Children | undefined> = (props, children) => { return h("hgroup", props, children); } -export const Hr: Component | Children | undefined> = (props, children) => { return h("hr", props, children); } -export const Html: Component | Children | undefined> = (props, children) => { return h("html", props, children); } -export const I: Component | Children | undefined> = (props, children) => { return h("i", props, children); } -export const Iframe: Component | Children | undefined> = (props, children) => { return h("iframe", props, children); } -export const Img: Component | Children | undefined> = (props, children) => { return h("img", props, children); } -export const Input: Component | Children | undefined> = (props, children) => { return h("input", props, children); } -export const Ins: Component | Children | undefined> = (props, children) => { return h("ins", props, children); } -export const Kbd: Component | Children | undefined> = (props, children) => { return h("kbd", props, children); } -export const Label: Component | Children | undefined> = (props, children) => { return h("label", props, children); } -export const Legend: Component | Children | undefined> = (props, children) => { return h("legend", props, children); } -export const Li: Component | Children | undefined> = (props, children) => { return h("li", props, children); } -export const Link: Component | Children | undefined> = (props, children) => { return h("link", props, children); } -export const Main: Component | Children | undefined> = (props, children) => { return h("main", props, children); } -export const Map: Component | Children | undefined> = (props, children) => { return h("map", props, children); } -export const Mark: Component | Children | undefined> = (props, children) => { return h("mark", props, children); } -export const Menu: Component | Children | undefined> = (props, children) => { return h("menu", props, children); } -export const Meta: Component | Children | undefined> = (props, children) => { return h("meta", props, children); } -export const Meter: Component | Children | undefined> = (props, children) => { return h("meter", props, children); } -export const Nav: Component | Children | undefined> = (props, children) => { return h("nav", props, children); } -export const Noscript: Component | Children | undefined> = (props, children) => { return h("noscript", props, children); } -export const Ol: Component | Children | undefined> = (props, children) => { return h("ol", props, children); } -export const Optgroup: Component | Children | undefined> = (props, children) => { return h("optgroup", props, children); } -export const Option: Component | Children | undefined> = (props, children) => { return h("option", props, children); } -export const Output: Component | Children | undefined> = (props, children) => { return h("output", props, children); } -export const P: Component | Children | undefined> = (props, children) => { return h("p", props, children); } -export const Picture: Component | Children | undefined> = (props, children) => { return h("picture", props, children); } -export const Pre: Component | Children | undefined> = (props, children) => { return h("pre", props, children); } -export const Progress: Component | Children | undefined> = (props, children) => { return h("progress", props, children); } -export const Q: Component | Children | undefined> = (props, children) => { return h("q", props, children); } -export const Rp: Component | Children | undefined> = (props, children) => { return h("rp", props, children); } -export const Rt: Component | Children | undefined> = (props, children) => { return h("rt", props, children); } -export const Ruby: Component | Children | undefined> = (props, children) => { return h("ruby", props, children); } -export const S: Component | Children | undefined> = (props, children) => { return h("s", props, children); } -export const Samp: Component | Children | undefined> = (props, children) => { return h("samp", props, children); } -export const Script: Component | Children | undefined> = (props, children) => { return h("script", props, children); } -export const Section: Component | Children | undefined> = (props, children) => { return h("section", props, children); } -export const Select: Component | Children | undefined> = (props, children) => { return h("select", props, children); } -export const Slot: Component | Children | undefined> = (props, children) => { return h("slot", props, children); } -export const Small: Component | Children | undefined> = (props, children) => { return h("small", props, children); } -export const Source: Component | Children | undefined> = (props, children) => { return h("source", props, children); } -export const Span: Component | Children | undefined> = (props, children) => { return h("span", props, children); } -export const Strong: Component | Children | undefined> = (props, children) => { return h("strong", props, children); } -export const Style: Component | Children | undefined> = (props, children) => { return h("style", props, children); } -export const Sub: Component | Children | undefined> = (props, children) => { return h("sub", props, children); } -export const Summary: Component | Children | undefined> = (props, children) => { return h("summary", props, children); } -export const Sup: Component | Children | undefined> = (props, children) => { return h("sup", props, children); } -export const Table: Component | Children | undefined> = (props, children) => { return h("table", props, children); } -export const Tbody: Component | Children | undefined> = (props, children) => { return h("tbody", props, children); } -export const Td: Component | Children | undefined> = (props, children) => { return h("td", props, children); } -export const Template: Component | Children | undefined> = (props, children) => { return h("template", props, children); } -export const Textarea: Component | Children | undefined> = (props, children) => { return h("textarea", props, children); } -export const Tfoot: Component | Children | undefined> = (props, children) => { return h("tfoot", props, children); } -export const Th: Component | Children | undefined> = (props, children) => { return h("th", props, children); } -export const Thead: Component | Children | undefined> = (props, children) => { return h("thead", props, children); } -export const Time: Component | Children | undefined> = (props, children) => { return h("time", props, children); } -export const Title: Component | Children | undefined> = (props, children) => { return h("title", props, children); } -export const Tr: Component | Children | undefined> = (props, children) => { return h("tr", props, children); } -export const Track: Component | Children | undefined> = (props, children) => { return h("track", props, children); } -export const U: Component | Children | undefined> = (props, children) => { return h("u", props, children); } -export const Ul: Component | Children | undefined> = (props, children) => { return h("ul", props, children); } -export const Var: Component | Children | undefined> = (props, children) => { return h("var", props, children); } -export const Video: Component | Children | undefined> = (props, children) => { return h("video", props, children); } -export const Wbr: Component | Children | undefined> = (props, children) => { return h("wbr", props, children); } +export const A: HTMLComponent<"a"> = (props, children) => { return h("a", props, children); } +export const Abbr: HTMLComponent<"abbr"> = (props, children) => { return h("abbr", props, children); } +export const Address: HTMLComponent<"address"> = (props, children) => { return h("address", props, children); } +export const Area: HTMLComponent<"area"> = (props, children) => { return h("area", props, children); } +export const Article: HTMLComponent<"article"> = (props, children) => { return h("article", props, children); } +export const Aside: HTMLComponent<"aside"> = (props, children) => { return h("aside", props, children); } +export const Audio: HTMLComponent<"audio"> = (props, children) => { return h("audio", props, children); } +export const B: HTMLComponent<"b"> = (props, children) => { return h("b", props, children); } +export const Base: HTMLComponent<"base"> = (props, children) => { return h("base", props, children); } +export const Bdi: HTMLComponent<"bdi"> = (props, children) => { return h("bdi", props, children); } +export const Bdo: HTMLComponent<"bdo"> = (props, children) => { return h("bdo", props, children); } +export const Blockquote: HTMLComponent<"blockquote"> = (props, children) => { return h("blockquote", props, children); } +export const Body: HTMLComponent<"body"> = (props, children) => { return h("body", props, children); } +export const Br: HTMLComponent<"br"> = (props, children) => { return h("br", props, children); } +export const Button: HTMLComponent<"button"> = (props, children) => { return h("button", props, children); } +export const Canvas: HTMLComponent<"canvas"> = (props, children) => { return h("canvas", props, children); } +export const Caption: HTMLComponent<"caption"> = (props, children) => { return h("caption", props, children); } +export const Cite: HTMLComponent<"cite"> = (props, children) => { return h("cite", props, children); } +export const Code: HTMLComponent<"code"> = (props, children) => { return h("code", props, children); } +export const Col: HTMLComponent<"col"> = (props, children) => { return h("col", props, children); } +export const Colgroup: HTMLComponent<"colgroup"> = (props, children) => { return h("colgroup", props, children); } +export const Data: HTMLComponent<"data"> = (props, children) => { return h("data", props, children); } +export const Datalist: HTMLComponent<"datalist"> = (props, children) => { return h("datalist", props, children); } +export const Dd: HTMLComponent<"dd"> = (props, children) => { return h("dd", props, children); } +export const Del: HTMLComponent<"del"> = (props, children) => { return h("del", props, children); } +export const Details: HTMLComponent<"details"> = (props, children) => { return h("details", props, children); } +export const Dfn: HTMLComponent<"dfn"> = (props, children) => { return h("dfn", props, children); } +export const Dialog: HTMLComponent<"dialog"> = (props, children) => { return h("dialog", props, children); } +export const Div: HTMLComponent<"div"> = (props, children) => { return h("div", props, children); } +export const Dl: HTMLComponent<"dl"> = (props, children) => { return h("dl", props, children); } +export const Dt: HTMLComponent<"dt"> = (props, children) => { return h("dt", props, children); } +export const Em: HTMLComponent<"em"> = (props, children) => { return h("em", props, children); } +export const Embed: HTMLComponent<"embed"> = (props, children) => { return h("embed", props, children); } +export const Fieldset: HTMLComponent<"fieldset"> = (props, children) => { return h("fieldset", props, children); } +export const Figcaption: HTMLComponent<"figcaption"> = (props, children) => { return h("figcaption", props, children); } +export const Figure: HTMLComponent<"figure"> = (props, children) => { return h("figure", props, children); } +export const Footer: HTMLComponent<"footer"> = (props, children) => { return h("footer", props, children); } +export const Form: HTMLComponent<"form"> = (props, children) => { return h("form", props, children); } +export const H1: HTMLComponent<"h1"> = (props, children) => { return h("h1", props, children); } +export const H2: HTMLComponent<"h2"> = (props, children) => { return h("h2", props, children); } +export const H3: HTMLComponent<"h3"> = (props, children) => { return h("h3", props, children); } +export const H4: HTMLComponent<"h4"> = (props, children) => { return h("h4", props, children); } +export const H5: HTMLComponent<"h5"> = (props, children) => { return h("h5", props, children); } +export const H6: HTMLComponent<"h6"> = (props, children) => { return h("h6", props, children); } +export const Head: HTMLComponent<"head"> = (props, children) => { return h("head", props, children); } +export const Header: HTMLComponent<"header"> = (props, children) => { return h("header", props, children); } +export const Hgroup: HTMLComponent<"hgroup"> = (props, children) => { return h("hgroup", props, children); } +export const Hr: HTMLComponent<"hr"> = (props, children) => { return h("hr", props, children); } +export const Html: HTMLComponent<"html"> = (props, children) => { return h("html", props, children); } +export const I: HTMLComponent<"i"> = (props, children) => { return h("i", props, children); } +export const Iframe: HTMLComponent<"iframe"> = (props, children) => { return h("iframe", props, children); } +export const Img: HTMLComponent<"img"> = (props, children) => { return h("img", props, children); } +export const Input: HTMLComponent<"input"> = (props, children) => { return h("input", props, children); } +export const Ins: HTMLComponent<"ins"> = (props, children) => { return h("ins", props, children); } +export const Kbd: HTMLComponent<"kbd"> = (props, children) => { return h("kbd", props, children); } +export const Label: HTMLComponent<"label"> = (props, children) => { return h("label", props, children); } +export const Legend: HTMLComponent<"legend"> = (props, children) => { return h("legend", props, children); } +export const Li: HTMLComponent<"li"> = (props, children) => { return h("li", props, children); } +export const Link: HTMLComponent<"link"> = (props, children) => { return h("link", props, children); } +export const Main: HTMLComponent<"main"> = (props, children) => { return h("main", props, children); } +export const Map: HTMLComponent<"map"> = (props, children) => { return h("map", props, children); } +export const Mark: HTMLComponent<"mark"> = (props, children) => { return h("mark", props, children); } +export const Menu: HTMLComponent<"menu"> = (props, children) => { return h("menu", props, children); } +export const Meta: HTMLComponent<"meta"> = (props, children) => { return h("meta", props, children); } +export const Meter: HTMLComponent<"meter"> = (props, children) => { return h("meter", props, children); } +export const Nav: HTMLComponent<"nav"> = (props, children) => { return h("nav", props, children); } +export const Noscript: HTMLComponent<"noscript"> = (props, children) => { return h("noscript", props, children); } +export const Ol: HTMLComponent<"ol"> = (props, children) => { return h("ol", props, children); } +export const Optgroup: HTMLComponent<"optgroup"> = (props, children) => { return h("optgroup", props, children); } +export const Option: HTMLComponent<"option"> = (props, children) => { return h("option", props, children); } +export const Output: HTMLComponent<"output"> = (props, children) => { return h("output", props, children); } +export const P: HTMLComponent<"p"> = (props, children) => { return h("p", props, children); } +export const Picture: HTMLComponent<"picture"> = (props, children) => { return h("picture", props, children); } +export const Pre: HTMLComponent<"pre"> = (props, children) => { return h("pre", props, children); } +export const Progress: HTMLComponent<"progress"> = (props, children) => { return h("progress", props, children); } +export const Q: HTMLComponent<"q"> = (props, children) => { return h("q", props, children); } +export const Rp: HTMLComponent<"rp"> = (props, children) => { return h("rp", props, children); } +export const Rt: HTMLComponent<"rt"> = (props, children) => { return h("rt", props, children); } +export const Ruby: HTMLComponent<"ruby"> = (props, children) => { return h("ruby", props, children); } +export const S: HTMLComponent<"s"> = (props, children) => { return h("s", props, children); } +export const Samp: HTMLComponent<"samp"> = (props, children) => { return h("samp", props, children); } +export const Script: HTMLComponent<"script"> = (props, children) => { return h("script", props, children); } +export const Section: HTMLComponent<"section"> = (props, children) => { return h("section", props, children); } +export const Select: HTMLComponent<"select"> = (props, children) => { return h("select", props, children); } +export const Slot: HTMLComponent<"slot"> = (props, children) => { return h("slot", props, children); } +export const Small: HTMLComponent<"small"> = (props, children) => { return h("small", props, children); } +export const Source: HTMLComponent<"source"> = (props, children) => { return h("source", props, children); } +export const Span: HTMLComponent<"span"> = (props, children) => { return h("span", props, children); } +export const Strong: HTMLComponent<"strong"> = (props, children) => { return h("strong", props, children); } +export const Style: HTMLComponent<"style"> = (props, children) => { return h("style", props, children); } +export const Sub: HTMLComponent<"sub"> = (props, children) => { return h("sub", props, children); } +export const Summary: HTMLComponent<"summary"> = (props, children) => { return h("summary", props, children); } +export const Sup: HTMLComponent<"sup"> = (props, children) => { return h("sup", props, children); } +export const Table: HTMLComponent<"table"> = (props, children) => { return h("table", props, children); } +export const Tbody: HTMLComponent<"tbody"> = (props, children) => { return h("tbody", props, children); } +export const Td: HTMLComponent<"td"> = (props, children) => { return h("td", props, children); } +export const Template: HTMLComponent<"template"> = (props, children) => { return h("template", props, children); } +export const Textarea: HTMLComponent<"textarea"> = (props, children) => { return h("textarea", props, children); } +export const Tfoot: HTMLComponent<"tfoot"> = (props, children) => { return h("tfoot", props, children); } +export const Th: HTMLComponent<"th"> = (props, children) => { return h("th", props, children); } +export const Thead: HTMLComponent<"thead"> = (props, children) => { return h("thead", props, children); } +export const Time: HTMLComponent<"time"> = (props, children) => { return h("time", props, children); } +export const Title: HTMLComponent<"title"> = (props, children) => { return h("title", props, children); } +export const Tr: HTMLComponent<"tr"> = (props, children) => { return h("tr", props, children); } +export const Track: HTMLComponent<"track"> = (props, children) => { return h("track", props, children); } +export const U: HTMLComponent<"u"> = (props, children) => { return h("u", props, children); } +export const Ul: HTMLComponent<"ul"> = (props, children) => { return h("ul", props, children); } +export const Var: HTMLComponent<"var"> = (props, children) => { return h("var", props, children); } +export const Video: HTMLComponent<"video"> = (props, children) => { return h("video", props, children); } +export const Wbr: HTMLComponent<"wbr"> = (props, children) => { return h("wbr", props, children); } diff --git a/src/dom/types.ts b/src/dom/types.ts index 42ea6bd..f8dfd2c 100644 --- a/src/dom/types.ts +++ b/src/dom/types.ts @@ -1,6 +1,8 @@ import { Accessor } from "../reactivity/types" +export type HTMLTag = HTMLElementTagNameMap export type Component

= ((props: P, children?: Children) => Element) +export type HTMLComponent

= Component | Children | undefined> export type Children = Reactive export type Child = Element | Reactive export type Reactive = T | Accessor @@ -17,15 +19,15 @@ export type Styles = { [K in keyof StylesDeclaration as K extends keyof StylesDe export type Style = {key: keyof Styles, value: Styles[keyof Styles]} type PartialWithStyles = Partial }> -type ElementWithoutEvents = Omit | 'innerHTML' | 'innerText' | 'outerHTML' | 'outerText'> -type ElementProperties = PartialWithStyles>> +type ElementWithoutEvents = Omit | 'innerHTML' | 'innerText' | 'outerHTML' | 'outerText'> +type ElementProperties = PartialWithStyles>> type ElementEvents = Partial>> -export type DoomProperties = { - [K in keyof ElementProperties as K extends keyof HTMLElementTagNameMap[T] ? K : never]?: Reactive[K]> +export type DoomProperties = { + [K in keyof ElementProperties as K extends keyof HTMLTag[T] ? K : never]?: Reactive[K]> } & ElementEvents -export type DoomProperty = { - key: keyof HTMLElementTagNameMap[T], - value: Reactive +export type DoomProperty = { + key: keyof HTMLTag[T], + value: Reactive } \ No newline at end of file diff --git a/src/dom/updateChildren.ts b/src/dom/updateChildren.ts index 378d38a..6c40dec 100644 --- a/src/dom/updateChildren.ts +++ b/src/dom/updateChildren.ts @@ -1,4 +1,7 @@ -// Slightly modified version of: https://github.com/ryansolid/dom-expressions/blob/main/packages/dom-expressions/src/reconcile.js +/* + * Slightly modified and tested version of: + * https://github.com/ryansolid/dom-expressions/blob/main/packages/dom-expressions/src/reconcile.js +*/ export function updateChildren(parentNode: Node, b: ChildNode[]) { let a = childrenOf(parentNode); let bLength = b.length,