From f21562c5558938796454e492bc76c6a5f4fb1639 Mon Sep 17 00:00:00 2001 From: Virgil Date: Fri, 27 Mar 2026 19:56:29 +0000 Subject: [PATCH] docs: add generated package specs Co-Authored-By: Virgil --- specs/cmd/codegen.md | 11 +++ specs/cmd/wasm.md | 11 +++ specs/codegen.md | 34 +++++++ specs/root.md | 225 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 281 insertions(+) create mode 100644 specs/cmd/codegen.md create mode 100644 specs/cmd/wasm.md create mode 100644 specs/codegen.md create mode 100644 specs/root.md diff --git a/specs/cmd/codegen.md b/specs/cmd/codegen.md new file mode 100644 index 0000000..2c91894 --- /dev/null +++ b/specs/cmd/codegen.md @@ -0,0 +1,11 @@ +# main +**Import:** `dappco.re/go/core/html/cmd/codegen` +**Files:** 1 + +## Types + +None. + +## Functions + +None. diff --git a/specs/cmd/wasm.md b/specs/cmd/wasm.md new file mode 100644 index 0000000..6c6b299 --- /dev/null +++ b/specs/cmd/wasm.md @@ -0,0 +1,11 @@ +# main +**Import:** `dappco.re/go/core/html/cmd/wasm` +**Files:** 2 + +## Types + +None. + +## Functions + +None. diff --git a/specs/codegen.md b/specs/codegen.md new file mode 100644 index 0000000..dfd1114 --- /dev/null +++ b/specs/codegen.md @@ -0,0 +1,34 @@ +# codegen +**Import:** `dappco.re/go/core/html/codegen` +**Files:** 2 + +## Types + +None. + +## Functions + +### `GenerateBundle` +`func GenerateBundle(slots map[string]string) (string, error)` + +GenerateBundle produces all WC class definitions and registrations +for a set of HLCRF slot assignments. +Usage example: js, err := GenerateBundle(map[string]string{"H": "nav-bar"}) + +### `GenerateClass` +`func GenerateClass(tag, slot string) (string, error)` + +GenerateClass produces a JS class definition for a custom element. +Usage example: js, err := GenerateClass("nav-bar", "H") + +### `GenerateRegistration` +`func GenerateRegistration(tag, className string) string` + +GenerateRegistration produces the customElements.define() call. +Usage example: js := GenerateRegistration("nav-bar", "NavBar") + +### `TagToClassName` +`func TagToClassName(tag string) string` + +TagToClassName converts a kebab-case tag to PascalCase class name. +Usage example: className := TagToClassName("nav-bar") diff --git a/specs/root.md b/specs/root.md new file mode 100644 index 0000000..6360930 --- /dev/null +++ b/specs/root.md @@ -0,0 +1,225 @@ +# html +**Import:** `dappco.re/go/core/html` +**Files:** 13 + +## Types + +### `Context` +`type Context struct` + +Context carries rendering state through the node tree. +Usage example: ctx := NewContext() + +Fields: +- `Identity string` +- `Locale string` +- `Entitlements func(feature string) bool` +- `Data map[string]any` +- Unexported fields are present. + +Methods: +None. + +### `Layout` +`type Layout struct` + +Layout is an HLCRF compositor. Arranges nodes into semantic HTML regions +with deterministic path-based IDs. +Usage example: page := NewLayout("HCF").H(Text("title")).C(Text("body")) + +Fields: +- No exported fields. +- Unexported fields are present. + +Methods: +- `func (l *Layout) C(nodes ...Node) *Layout` + C appends nodes to the Content (main) slot. + Usage example: NewLayout("C").C(Text("body")) +- `func (l *Layout) F(nodes ...Node) *Layout` + F appends nodes to the Footer slot. + Usage example: NewLayout("CF").F(Text("footer")) +- `func (l *Layout) H(nodes ...Node) *Layout` + H appends nodes to the Header slot. + Usage example: NewLayout("HCF").H(Text("title")) +- `func (l *Layout) L(nodes ...Node) *Layout` + L appends nodes to the Left aside slot. + Usage example: NewLayout("LC").L(Text("nav")) +- `func (l *Layout) R(nodes ...Node) *Layout` + R appends nodes to the Right aside slot. + Usage example: NewLayout("CR").R(Text("ads")) +- `func (l *Layout) Render(ctx *Context) string` + Render produces the semantic HTML for this layout. + Usage example: html := NewLayout("C").C(Text("body")).Render(NewContext()) + Only slots present in the variant string are rendered. + +### `Node` +`type Node interface` + +Node is anything renderable. +Usage example: var n Node = El("div", Text("welcome")) + +Members: +- `Render(ctx *Context) string` + +Methods: +None. + +### `Responsive` +`type Responsive struct` + +Responsive wraps multiple Layout variants for breakpoint-aware rendering. +Usage example: r := NewResponsive().Variant("mobile", NewLayout("C")) +Each variant is rendered inside a container with data-variant for CSS targeting. + +Fields: +- No exported fields. +- Unexported fields are present. + +Methods: +- `func (r *Responsive) Render(ctx *Context) string` + Render produces HTML with each variant in a data-variant container. + Usage example: html := NewResponsive().Variant("mobile", NewLayout("C")).Render(NewContext()) +- `func (r *Responsive) Variant(name string, layout *Layout) *Responsive` + Variant adds a named layout variant (e.g., "desktop", "tablet", "mobile"). + Usage example: NewResponsive().Variant("desktop", NewLayout("HLCRF")) + Variants render in insertion order. + +### `Translator` +`type Translator interface` + +Translator provides Text() lookups for a rendering context. +Usage example: ctx := NewContextWithService(myTranslator) + +The default server build uses go-i18n. Alternate builds, including WASM, +can provide any implementation with the same T() method. + +Members: +- `T(key string, args ...any) string` + +Methods: +None. + +## Functions + +### `Attr` +`func Attr(n Node, key, value string) Node` + +Attr sets an attribute on an El node. Returns the node for chaining. +Usage example: Attr(El("a", Text("docs")), "href", "/docs") +It recursively traverses through wrappers like If, Unless, and Entitled. + +### `CompareVariants` +`func CompareVariants(r *Responsive, ctx *Context) map[string]float64` + +CompareVariants runs the imprint pipeline on each responsive variant independently +and returns pairwise similarity scores. Key format: "name1:name2". +Usage example: scores := CompareVariants(NewResponsive(), NewContext()) + +### `Each` +`func Each[T any](items []T, fn func(T) Node) Node` + +Each iterates items and renders each via fn. +Usage example: Each([]string{"a", "b"}, func(v string) Node { return Text(v) }) + +### `EachSeq` +`func EachSeq[T any](items iter.Seq[T], fn func(T) Node) Node` + +EachSeq iterates an iter.Seq and renders each via fn. +Usage example: EachSeq(slices.Values([]string{"a", "b"}), func(v string) Node { return Text(v) }) + +### `El` +`func El(tag string, children ...Node) Node` + +El creates an HTML element node with children. +Usage example: El("section", Text("welcome")) + +### `Entitled` +`func Entitled(feature string, node Node) Node` + +Entitled renders child only when entitlement is granted. Absent, not hidden. +Usage example: Entitled("beta", Text("preview")) +If no entitlement function is set on the context, access is denied by default. + +### `If` +`func If(cond func(*Context) bool, node Node) Node` + +If renders child only when condition is true. +Usage example: If(func(ctx *Context) bool { return ctx.Identity != "" }, Text("hi")) + +### `Imprint` +`func Imprint(node Node, ctx *Context) reversal.GrammarImprint` + +Imprint renders a node tree to HTML, strips tags, tokenises the text, +and returns a GrammarImprint — the full render-reverse pipeline. +Usage example: imp := Imprint(Text("welcome"), NewContext()) + +### `NewContext` +`func NewContext() *Context` + +NewContext creates a new rendering context with sensible defaults. +Usage example: html := Render(Text("welcome"), NewContext()) + +### `NewContextWithService` +`func NewContextWithService(svc Translator) *Context` + +NewContextWithService creates a rendering context backed by a specific translator. +Usage example: ctx := NewContextWithService(myTranslator) + +### `NewLayout` +`func NewLayout(variant string) *Layout` + +NewLayout creates a new Layout with the given variant string. +Usage example: page := NewLayout("HLCRF") +The variant determines which slots are rendered (e.g., "HLCRF", "HCF", "C"). + +### `NewResponsive` +`func NewResponsive() *Responsive` + +NewResponsive creates a new multi-variant responsive compositor. +Usage example: r := NewResponsive() + +### `ParseBlockID` +`func ParseBlockID(id string) []byte` + +ParseBlockID extracts the slot sequence from a data-block ID. +Usage example: slots := ParseBlockID("L-0-C-0") +"L-0-C-0" → ['L', 'C'] + +### `Raw` +`func Raw(content string) Node` + +Raw creates a node that renders without escaping (escape hatch for trusted content). +Usage example: Raw("trusted") + +### `Render` +`func Render(node Node, ctx *Context) string` + +Render is a convenience function that renders a node tree to HTML. +Usage example: html := Render(El("main", Text("welcome")), NewContext()) + +### `StripTags` +`func StripTags(html string) string` + +StripTags removes HTML tags from rendered output, returning plain text. +Usage example: text := StripTags("
Hello world
") +Tag boundaries are collapsed into single spaces; result is trimmed. +Does not handle script/style element content (go-html does not generate these). + +### `Switch` +`func Switch(selector func(*Context) string, cases map[string]Node) Node` + +Switch renders based on runtime selector value. +Usage example: Switch(func(ctx *Context) string { return ctx.Locale }, map[string]Node{"en": Text("hello")}) + +### `Text` +`func Text(key string, args ...any) Node` + +Text creates a node that renders through the go-i18n grammar pipeline. +Usage example: Text("welcome", "Ada") +Output is HTML-escaped by default. Safe-by-default path. + +### `Unless` +`func Unless(cond func(*Context) bool, node Node) Node` + +Unless renders child only when condition is false. +Usage example: Unless(func(ctx *Context) bool { return ctx.Identity == "" }, Text("welcome")) -- 2.45.3