Hyperscript interface for creating hast (HTML/SVG) syntax trees with CSS selector support and JSX integration
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core hyperscript functions for creating hast trees with CSS selector syntax support and intelligent property handling.
Creates HTML hast trees using hyperscript syntax with CSS selector support.
/**
* Creates HTML hast trees using hyperscript syntax
* @param selector - CSS selector string or null/undefined for root
* @param properties - Element properties and attributes
* @param children - Child elements or content
* @returns Element or Root node
*/
function h(selector?: string | null, properties?: Properties, ...children: Child[]): Result;
// Overloads:
function h(selector: null | undefined, ...children: Child[]): Root;
function h(selector: string, properties: Properties, ...children: Child[]): Element;
function h(selector: string, ...children: Child[]): Element;Usage Examples:
import { h } from "hastscript";
// Basic element creation
const div = h("div", "Hello World");
// Result: { type: 'element', tagName: 'div', properties: {}, children: [{ type: 'text', value: 'Hello World' }] }
// Element with CSS selector
const element = h("div.container#main", "Content");
// Result: <div id="main" class="container">Content</div>
// Element with properties
const input = h("input", { type: "text", placeholder: "Enter name", required: true });
// Element with style object
const styled = h("div", { style: { color: "red", fontSize: "16px" } }, "Styled text");
// Element with multiple children
const list = h("ul",
h("li", "Item 1"),
h("li", "Item 2"),
h("li", "Item 3")
);
// Root node (fragment)
const root = h(null,
h("p", "First paragraph"),
h("p", "Second paragraph")
);
// Complex selector with properties
const complex = h("div.card.active#card-1",
{ "data-id": "123", "aria-label": "Main card" },
h("h2", "Card Title"),
h("p", "Card content")
);Creates SVG hast trees using hyperscript syntax with case-sensitive tag names.
/**
* Creates SVG hast trees using hyperscript syntax with case-sensitive tag names
* @param selector - CSS selector string or null/undefined for root
* @param properties - Element properties and attributes
* @param children - Child elements or content
* @returns Element or Root node
*/
function s(selector?: string | null, properties?: Properties, ...children: Child[]): Result;
// Overloads:
function s(selector: null | undefined, ...children: Child[]): Root;
function s(selector: string, properties: Properties, ...children: Child[]): Element;
function s(selector: string, ...children: Child[]): Element;Usage Examples:
import { s } from "hastscript";
// Basic SVG element
const circle = s("circle", { cx: 50, cy: 50, r: 40, fill: "red" });
// Complete SVG with nested elements
const svg = s("svg", { viewBox: "0 0 100 100", width: 100, height: 100 },
s("circle", { cx: 50, cy: 50, r: 40, fill: "blue" }),
s("text", { x: 50, y: 55, textAnchor: "middle", fill: "white" }, "SVG")
);
// Case-sensitive SVG elements
const gradient = s("linearGradient", { id: "grad1" },
s("stop", { offset: "0%", stopColor: "rgb(255,255,0)" }),
s("stop", { offset: "100%", stopColor: "rgb(255,0,0)" })
);
// SVG with foreign object
const foreign = s("foreignObject", { x: 10, y: 10, width: 100, height: 50 },
"HTML content inside SVG"
);Properties are intelligently transformed based on the property type and schema:
Boolean Properties:
h("input", { required: true, disabled: false });
// required becomes "required", disabled is omittedArray Properties:
h("div", { className: ["container", "active"] });
// Becomes class="container active"Style Objects:
h("div", { style: { fontSize: "16px", marginTop: "10px" } });
// Becomes style="font-size: 16px; margin-top: 10px"Data Attributes:
h("div", { "data-id": "123", "aria-label": "Button" });
// Preserved as-isSelectors support standard CSS syntax:
// Tag name
h("div");
// With class
h("div.container");
// With ID
h("div#main");
// With multiple classes
h("div.container.active.highlight");
// Combined
h("div.container#main.active");
// Default tag names
h(".container"); // Uses default "div" for HTML
s(".icon"); // Uses default "g" for SVGChildren can be various types and are automatically processed:
// String/number children become text nodes
h("p", "Hello", " ", "World", 123);
// Null/undefined children are ignored
h("div", null, "Content", undefined);
// Arrays of children are flattened
h("ul", [
h("li", "Item 1"),
h("li", "Item 2")
]);
// Nested arrays are flattened recursively
h("div", [
["Text ", h("strong", "Bold")],
[" more text"]
]);
// Root nodes are unwrapped
const content = h(null, h("p", "Para 1"), h("p", "Para 2"));
h("div", content); // Children of root are added directlyTemplate elements receive special handling where their children are moved to a content property:
// Template element special handling
h("template", h("p", "Template content"));
// Result: {
// type: 'element',
// tagName: 'template',
// properties: {},
// children: [],
// content: {
// type: 'root',
// children: [{ type: 'element', tagName: 'p', ... }]
// }
// }type Child = ArrayChild | Nodes | PrimitiveChild;
type PrimitiveChild = number | string | null | undefined;
type ArrayChild = Array<ArrayChildNested | Nodes | PrimitiveChild>;
type ArrayChildNested = Array<Nodes | PrimitiveChild>;
interface Properties {
[key: string]: PropertyValue | Style;
}
type PropertyValue = ArrayValue | PrimitiveValue;
type PrimitiveValue = boolean | number | string | null | undefined;
type ArrayValue = Array<number | string>;
interface Style {
[key: string]: StyleValue;
}
type StyleValue = number | string;
type Result = Element | Root;