100+ type-checked HTML5 element functions for @thi.ng/hiccup related infrastructure
npm install @thi.ng/hiccup-html
!npm downloads

> [!NOTE]
> This is one of 214 standalone projects, maintained as part
> of the @thi.ng/umbrella monorepo
> and anti-framework.
>
> 🚀 Please help me to work full-time on these projects by sponsoring me on
> GitHub. Thank you! ❤️
- About
- Supported elements
- Block content
- Forms / inputs
- Head / metadata
- Inline
- Lists
- Media
- Sections
- Tables
- Compatibility
- Status
- Support packages
- Related packages
- Installation
- Dependencies
- Usage examples
- API
- defElement
- Element creation
- Authors
- License
100+ type-checked HTML5 element functions for @thi.ng/hiccup related infrastructure.
The following type-checked factory functions are provided so far and in most
cases include specialized type definitions for element-specific attributes,
incl. enumerated attrib values (where applicable/useful) and 420+ CSS property
names (for use with the style attrib). See type definitions in
api.ts
and defElement() below for more details.
#### Block content
- blockquote
- details
- dialog
- div
- figcaption
- figure
- hr
- iframe
- para
- pre
- slot
- summary
- template
#### Forms / inputs
- button
- checkbox
- fieldset
- form
- inputColor
- inputFile
- inputNumber
- inputPass
- inputRange
- inputReset
- inputSearch
- inputSubmit
- inputText
- label
- legend
- meter
- optGroup
- option
- output
- progress
- radio
- select
- textArea
#### Head / metadata
- base
- head
- link
- linkCSS
- meta
- metaReferrer
- metaRefresh
- metaRobots
- metaUTF8
- metaViewport
- metaXUA
- script
- style
- title
#### Inline
- abbr
- anchor
- br
- cite
- code
- data
- del
- dfn
- em
- i
- ins
- kbd
- mark
- quote
- small
- span
- strikethrough
- strong
- sub
- sup
- time
- variable
- wbr
#### Lists
- datalist
- dd
- dl
- dt
- li
- menu
- ol
- ul
#### Media
- audio
- canvas
- img
- object
- picture
- source
- track
- video
#### Sections
- address
- article
- aside
- body
- comment
- footer
- h1
- h2
- h3
- h4
- h5
- h6
- header
- hgroup
- html
- main
- nav
- noscript
- search
- section
#### Tables
- caption
- col
- colgroup
- table
- tbody
- td
- tfoot
- th
- thead
- tr
The hiccup syntax is (by design) merely a convention and specific
feature support and interpretation is down to the actual tooling used.
Whilst not a direct aspect or feature of this package, the type
definitions for element attributes defined here allow certain constructs
which are only supported by some hiccup consumers. OTOH not all of
the constructs are meaningful in the different usage contexts and for
most there're compatible alternative ways of expressing the same data.
The table below provides an overview of the _current_ syntax feature
support by the relevant packages consuming hiccup:
- @thi.ng/hiccup
- @thi.ng/hdom
- @thi.ng/rdom
| Feature | Example and HTML equivalent/result | hiccup | hdom | rdom | All other features not explicitly mentioned are supported by all three (1) Excluding event listener attribs, these are always function values (2) The STABLE - used in production Search or submit any issues for this package The current aim is not necessarily to have wrappers for each possible - @thi.ng/hiccup-html-parse - Well-formed HTML parsing and customizable transformation to nested JS arrays in @thi.ng/hiccup format - @thi.ng/hdom - Lightweight vanilla ES6 UI component trees with customizable branch-local behaviors `` ESM import: ` Browser ESM import: ` Package sizes (brotli'd, pre-treeshake): ESM: 1.63 KB Note: @thi.ng/api is in _most_ cases a type-only import (not used at runtime) 33 projects in this repo's | Screenshot | Description | Live demo | Source | ` const choices = [ $compile( All element functions are created via the higher-order function defElement Define element with defaults: ` const el = defElement("tag") Define with custom attribs & no children allowed: ` // extend global HTML default attribs // provide type constraints and default attribs // or create new versions of existing elements with more limited The Attribs The AttribVal #### Element creation The function returned by defElement ` (emmet: string, attribs?: Nullable The result of either form is a simple tuple, defining an HTML element in If the second call signature is used, the initial emmet ` const el = defElement | Call | Result | ` // with default attribs | Call | Result | If this project contributes to an academic publication, please cite it as: ` © 2020 - 2026 Karsten Schmidt // Apache License 2.0
|----------------------------|------------------------------------------------------|--------|------|------|
| Emmet style tags | ["div#id.foo", {}] | ✅ | ✅ | ✅ |
| | | | | |
| class attrib as object | ["a.bar.baz", { class: { foo: true, bar: false }}] | ✅ | ✅ | ✅ |
| | | | | |
| style attrib as object | ["div", { style: { color: "red" }}] | ✅ | ✅ | ✅ |
| | | | | |
| Attrib array values | ["img", { srcset: ["1.jpg", "2.jpg"] }] | ✅ | ❌ | ✅ |
| | | | | |
| Data attribs as object | ["a", { data: { foo: 42 }}] | ✅ | ❌ | ✅ |
| | | | | |
| Function attrib values (1) | ["a", { id: () => "epoch-" + Date.now() }] | ✅ | ✅ | ✅ |
| | | | | |
| IDeref attrib values (2) | ["div", { id: { deref() { return "foo"; }}}] | ✅ | ❌ | ✅ |
| | | | | |
packages.
of course, but will NOT be evaluated to obtain final attrib valueIDeref
interface is implemented by various data structures in the
thi.ng/umbrella eco system (most relevant:
@thi.ng/rstream,
@thi.ng/atom).Status
HTML5 element, but certainly to support the most commonly used ones. PRs
welcome!Support packages
Related packages
- @thi.ng/rdom - Lightweight, reactive, VDOM-less UI/DOM components with async lifecycle and @thi.ng/hiccup compatible
- @thi.ng/hiccup-svg - SVG element functions for @thi.ng/hiccup & related toolingInstallation
bash`
yarn add @thi.ng/hiccup-htmlts`
import * as html from "@thi.ng/hiccup-html";html`Dependencies
Usage examples
/examples
directory are using this package:
|:----------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------|:----------------------------------------------------------|:---------------------------------------------------------------------------------------|
|
| Large ASCII font text generator using @thi.ng/rdom | Demo | Source |
|
| Figlet-style bitmap font creation with transducers | Demo | Source |
|
| Interactive & reactive image blurhash generator | Demo | Source |
|
| Self-modifying, animated typographic grid with emergent complex patterns | Demo | Source |
|
| Tool to interactively compute & visualize color contrasts against WCAG threshold | Demo | Source |
|
| Probabilistic color theme generator | Demo | Source |
|
| CSP channel-based event handling, async transducers & reactive UI components | Demo | Source |
|
| Color palette generation via dominant color extraction from uploaded images | Demo | Source |
|
| Randomized space-filling, nested grid layout generator | Demo | Source |
|
| Browser REPL for a Lispy S-expression based mini language | Demo | Source |
|
| Mastodon API feed reader with support for different media types, fullscreen media modal, HTML rewriting | Demo | Source |
|
| Basic thi.ng/meta-css usage & testbed | Demo | Source |
|
| Parser grammar livecoding editor/playground & codegen | Demo | Source |
|
| Randomized 4-point 2D color gradient image generator | Demo | Source |
|
| Interactive pixel sorting tool using thi.ng/color & thi.ng/pixel | Demo | Source |
|
| RGB waveform image analysis | Demo | Source |
|
| Procedural stochastic text generation via custom DSL, parse grammar & AST transformation | Demo | Source |
|
| rdom drag & drop example | Demo | Source |
|
| Basic usage of the declarative rdom-forms generator | Demo | Source |
|
| rstream & transducer-based FSM for converting key event sequences into high-level commands | Demo | Source |
|
| rdom & hiccup-canvas interop test | Demo | Source |
|
| Basic thi.ng/router usage with thi.ng/rdom components | Demo | Source |
| | Full umbrella repo doc string search w/ paginated results | Demo | Source |
|
| Defining & using basic Web Components (with shadow DOM) via @thi.ng/rdom & @thi.ng/meta-css | Demo | Source |
|
| Responsive image gallery with tag-based Jaccard similarity ranking | Demo | Source |
|
| Generative audio synth offline renderer and WAV file export | Demo | Source |
|
| Declarative component-based system with central rstream-based pubsub event bus | Demo | Source |
|
| Responsive & reactively computed stacked column layout | Demo | Source |
|
| SVG path parsing & dynamic resampling | Demo | Source |
|
| Tree-based UI to find & explore thi.ng projects via their associated keywords | Demo | Source |
|
| thi.ng/rdom & thi.ng/rstream based quiz to guess thi.ng package names | Demo | Source |
|
| Multi-layer vectorization & dithering of bitmap images | Demo | Source |
|
| rdom & WebGL-based image channel editor | Demo | Source |API
ts
import { div, label, option, select } from "@thi.ng/hiccup-html";
import { $compile } from "@thi.ng/rdom";
["#f00", "Red"],
["#ff0", "Yellow"],
["#0f0", "Green"],
["#0ff", "Cyan"],
["#00f", "Blue"],
["#f0f", "Magenta"],
];
div(
null,
label({ for: "colors" }, "Fave color: "),
select(
{
id: "colors",
onchange: (e) => alert((
},
option(null, "Please choose..."),
...choices.map((x) => option({ value: x[0] }, x[1]))
)
)
).mount(document.body);
`$3
defElement
which produces the typed, variadic factories. takes an element nameAttribs
and optional set of default attributes. It also uses generics to enforce types
for the element's attributes (default:any
and/or children/body (default: ).ts
import { defElement } from "@thi.ng/hiccup-html";
`ts
import { Attribs, AttribVal, defElement } from "@thi.ng/hiccup-html";
interface MyAttribs extends Attribs {
class: AttribVal
width: AttribVal
height: AttribVal
}
const el = defElement
"tag",
{ width: 100, height: 100 }
);
// user customization options...
const div = defElement
` interface provides a common, fully typed base definition
of HTML attributes (incl. event listeners and enumerated attrib options)
and can be found in
api.ts. type wrapper is used to allow for reactive attributeIDeref
values (in
@thi.ng/rdom)
and
instances
when later providing attribute values to an element. has the following
signatures:ts
(attribs?: Nullable
`
@thi.ng/hiccup
syntax.-style string
will be appended to the tag name and merely acts as syntax sugar for
providing an element ID and/or CSS classes.ts
import { defElement } from "@thi.ng/hiccup-html";
`
|-----------------------------------|----------------------------------|
| el() | ["a", null] |el(null)
| | ["a", null] |el(null, "body")
| | ["a", null, "body"] |el({ c: 2 })
| | ["a", { c: 2 }] |el({ c: 2 }, "body")
| | ["a", { c: 2 }, "body"] |el("#id.foo")
| | ["a#id.foo", null] |el("#id.foo", { c: 2 })
| | ["a#id.foo", { c: 2 }] |el("#id.foo", { c: 2 }, "body")
| | ["a#id.foo", { c: 2 }, "body"] |el("#id.foo", null, "body")
| | ["a#id.foo", null, "body"] |ts
import { defElement } from "@thi.ng/hiccup-html";
const el = defElement
`
|-----------------------------------|----------------------------------------|
| el() | ["a", { b: 1 }] |el(null)
| | ["a", { b: 1 }] |el(null, "body")
| | ["a", { b: 1 }, "body"] |el({ c: 2 })
| | ["a", { b: 1, c: 2 }] |el({ c: 2 }, "body")
| | ["a", { b: 1, c: 2 }, "body"] |el("#id.foo")
| | ["a#id.foo", { b: 1 }] |el("#id.foo", { c: 2 })
| | ["a#id.foo", { b: 1, c: 2 }] |el("#id.foo", { c: 2 }, "body")
| | ["a#id.foo", { b: 1, c: 2 }, "body"] |el("#id.foo", null, "body")
| | ["a#id.foo", { b: 1 }, "body"] |Authors
bibtex``
@misc{thing-hiccup-html,
title = "@thi.ng/hiccup-html",
author = "Karsten Schmidt",
note = "https://thi.ng/hiccup-html",
year = 2020
}License