Elements
In Whisq, every HTML element is a function. No JSX, no templates — just function calls with full TypeScript support.
Basic Usage
Section titled “Basic Usage”import { div, h1, p, button, span } from "@whisq/core";
// With props + childrendiv({ class: "card", id: "main" }, h1("Title"), p("Content"),)
// Without props — just childrendiv( h1("Title"), p("Content"),)
// Single text childh1("Hello Whisq")button("Click me")The first argument is either a props object or a child. Whisq detects which automatically.
Available Elements
Section titled “Available Elements”Every standard HTML tag has a function:
Layout: div, span, main, section, article, aside, header, footer, nav
Text: h1–h6, p, strong, em, small, pre, code
Interactive: button, a
Forms: form, input, textarea, select, option, label
Lists: ul, ol, li
Table: table, thead, tbody, tr, th, td
Media: img, video, audio
Misc: br, hr, iframe
Reactive Props
Section titled “Reactive Props”Pass a function for any prop to make it reactive:
import { signal, div, span } from "@whisq/core";
const active = signal(false);
// Reactive classdiv({ class: () => active.value ? "card active" : "card" }, span("Content"),)
// Reactive stylediv({ style: () => `color: ${color.value}` }, "Styled text")
// Reactive visibilitydiv({ hidden: () => !visible.value }, "Now you see me")Events
Section titled “Events”Events use on* props with function handlers:
button({ onclick: () => count.value++ }, "Click me")input({ oninput: (e) => name.value = e.target.value })form({ onsubmit: (e) => { e.preventDefault(); save(); } }, // form children)All standard DOM events are supported: onclick, oninput, onchange, onsubmit, onkeydown, onmouseenter, onfocus, onblur, etc.
Reactive Children
Section titled “Reactive Children”Pass a function as a child to make it reactive:
const name = signal("World");
div( // Static child — never changes h1("Hello"), // Reactive child — updates when `name` changes p(() => `Welcome, ${name.value}!`),)h() — Low-Level Element Creation
Section titled “h() — Low-Level Element Creation”For dynamic tag names or custom elements:
import { h } from "@whisq/core";
h("custom-element", { class: "foo" }, "content")h("details", { open: true }, h("summary", {}, "Click"), "Hidden content")ref — Direct DOM Access
Section titled “ref — Direct DOM Access”Access the underlying DOM element via the ref prop:
import { signal } from "@whisq/core";
const inputRef = signal<HTMLInputElement | null>(null);
input({ ref: inputRef, type: "text" })
// Later: inputRef.value?.focus()Or with a callback:
input({ ref: (el) => el?.focus(), type: "text",})mount() — Attach to DOM
Section titled “mount() — Attach to DOM”Mount a WhisqNode into a DOM container:
import { div, mount } from "@whisq/core";
const dispose = mount( div("Hello Whisq"), document.getElementById("app")!,);
// Later: dispose() to unmount and clean upNext Steps
Section titled “Next Steps”- Components — Encapsulate elements in reusable components
- Styling — Scoped CSS with
sheet()andstyles()