diff --git a/Node-API.-.md b/Node-API.-.md new file mode 100644 index 0000000..6bfcb6b --- /dev/null +++ b/Node-API.-.md @@ -0,0 +1,186 @@ +# Node API + +The `Node` interface is the fundamental building block. All rendered elements implement it. + +See also: [[Home]] | [[Architecture]] | [[Pipeline]] | [[WebAssembly]] | [[Code-Generation]] + +## Node Interface + +```go +type Node interface { + Render(ctx *Context) string +} +``` + +Every node receives a `Context` and returns an HTML string. Nodes compose into trees via `El()` children. + +## Node Types + +### Text — i18n-Aware Text + +```go +func Text(key string, args ...any) Node +``` + +Renders localised text through the i18n service in the context. Output is **HTML-escaped** (safe by default). Supports `fmt.Sprintf`-style arguments. + +```go +html.Text("greeting", userName) +// Looks up "greeting" in locale, formats with userName +// Output: "Hello, Alice" (escaped) +``` + +### El — HTML Element + +```go +func El(tag string, children ...Node) Node +``` + +Creates an HTML element. Children are rendered in order. Void elements (`br`, `img`, `hr`, `input`, `meta`, `link`, `area`, `base`, `col`, `embed`, `source`, `track`, `wbr`) self-close. + +```go +html.El("div", + html.El("h1", html.Text("page.title")), + html.El("p", html.Text("page.body")), +) +//

Page Title

Body text

+``` + +### Attr — Attribute Setter + +```go +func Attr(n Node, key, value string) Node +``` + +Sets an attribute on an element node. Returns the same node for chaining. Values are attribute-escaped. + +```go +html.Attr( + html.El("a", html.Text("link.text")), + "href", "/about", +) +// About +``` + +### Raw — Unescaped Content + +```go +func Raw(content string) Node +``` + +Renders content without escaping. **Use only for trusted content** (pre-sanitised HTML, SVG, etc.). + +```go +html.Raw("...") +``` + +### If — Conditional Rendering + +```go +func If(cond func(*Context) bool, node Node) Node +``` + +Renders the node only when the condition returns true. The condition receives the current context. + +```go +html.If( + func(ctx *html.Context) bool { return ctx.Identity != "" }, + html.El("span", html.Text("user.welcome")), +) +``` + +### Unless — Negated Conditional + +```go +func Unless(cond func(*Context) bool, node Node) Node +``` + +Renders the node when the condition is false. Inverse of `If`. + +```go +html.Unless( + func(ctx *html.Context) bool { return ctx.Identity != "" }, + html.El("a", html.Text("auth.login")), +) +``` + +### Entitled — Feature Gate + +```go +func Entitled(feature string, node Node) Node +``` + +Renders the node only if the feature is present in `ctx.Entitlements`. Used for plan/tier-gated UI. + +```go +html.Entitled("analytics-pro", + html.El("div", html.Text("analytics.advanced_panel")), +) +``` + +### Switch — Runtime Case Selection + +```go +func Switch(selector func(*Context) string, cases map[string]Node) Node +``` + +Evaluates the selector at render time and renders the matching case. No output if no case matches. + +```go +html.Switch( + func(ctx *html.Context) string { return ctx.Data["theme"] }, + map[string]html.Node{ + "dark": html.El("div", html.Attr(html.El("div"), "class", "dark")), + "light": html.El("div", html.Attr(html.El("div"), "class", "light")), + }, +) +``` + +### Each — Generic Iteration + +```go +func Each[T any](items []T, fn func(T) Node) Node +``` + +Iterates over a typed slice, calling the function for each item. Uses Go generics. + +```go +type Article struct { Title, Slug string } + +html.Each(articles, func(a Article) html.Node { + return html.El("li", + html.Attr(html.El("a", html.Text(a.Title)), "href", "/"+a.Slug), + ) +}) +``` + +## Context + +```go +type Context struct { + Identity string + Locale string + Entitlements map[string]bool + Data map[string]string + Service *i18n.Service +} + +func NewContext() *Context +func NewContextWithService(svc *i18n.Service) *Context +``` + +| Field | Purpose | +|-------|---------| +| `Identity` | Current user identifier | +| `Locale` | Language code for i18n lookups | +| `Entitlements` | Feature flags for `Entitled()` gating | +| `Data` | Arbitrary string data for `Switch()` selectors | +| `Service` | go-i18n service for `Text()` rendering | + +## Convenience + +```go +func Render(node Node, ctx *Context) string +``` + +Shorthand for `node.Render(ctx)`. Useful in pipelines.