Help us shape the future of Go! Take the 2026 Go Developer Survey

builder

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package builder is the page_doc v2 model: a tree of layout nodes with a validator, pure edit ops, a closed style vocabulary and v1 section conversion. It is a leaf package (stdlib and jsonschema only) so render, entity and server can share one type without import cycles.

Index

Constants

View Source
const (
	BindText  = "text"
	BindURL   = "url"
	BindImage = "image"
)

Bind classes: what a source yields and what a prop accepts (x-hm-bind).

View Source
const (
	SlotHeader  = "header"
	SlotFooter  = "footer"
	SlotSingle  = "single"
	SlotArchive = "archive"
)

The layout slots a theme part can fill.

View Source
const (
	DiffAdded   = "added"
	DiffRemoved = "removed"
	DiffMoved   = "moved"
	DiffChanged = "changed"
)

Node change operations.

View Source
const (
	MaxDepth = 8
	MaxNodes = 1000
	MaxBytes = 1 << 20
)

Limits on a stored doc.

View Source
const (
	ExtValue = "value" // one string for a prop binding
	ExtItems = "items" // a list for a loop with from:"source"
)

Source kinds of a plugin data source (sdk.BuilderSource).

View Source
const (
	MaxPackWidgets     = 64    // registered plugin widgets in total
	MaxPackProps       = 24    // properties of one widget schema
	MaxPackSchemaBytes = 16384 // size of one widget schema

)

Plugin widget limits.

View Source
const (
	RefMaxDepth = 3    // blocks inside blocks
	RefMaxNodes = 1000 // expanded nodes per rendered page
)

Limits on reference expansion (see Engine.expandRefs in render).

View Source
const PackGroup = "Plugin widgets"

PackGroup is the palette group of every plugin widget.

Variables

View Source
var (
	ErrPresetExists   = errors.New("a preset with this name exists")
	ErrTooManyPresets = fmt.Errorf("at most %d presets", maxPresets)
)

ErrPresetExists and ErrTooManyPresets are the refusals of AddPreset.

View Source
var ErrInvalid = errors.New("builder: invalid doc")

ErrInvalid is wrapped by every validation failure.

View Source
var ReservedAnchors = []string{"main-content", "toc", "top", "main", "content"}

ReservedAnchors are the ids the theme and the core own: an anchor equal to one would make a duplicate DOM id. The hm- prefix covers the builder's own ids (hm-search-q, hm-related-h, hm-builder-*, hm-canvas-bridge, hm-tab<N>[p]), the -strip-label suffix the section strips. A node id of the same doc is reserved too (form fields render it as their id); see CheckSettings. A test in render scans the default theme for literal ids against this.

View Source
var UniversalKeys = []string{"preset", "navlabel", "anchor", "aria", "tip"}

UniversalKeys are the props every kind schema gets from withUniversal rather than declaring them, so no kind lists them as a Content field: preset (a style preset name), navlabel (the author's name for the node in the navigator; never rendered), and the element settings anchor (public id), aria (aria-label) and tip (title attribute).

Functions

func AddPreset

func AddPreset(themeExtra []byte, name string, p Preset) ([]byte, error)

AddPreset creates one preset under builder.presets and leaves everything else as stored. It validates p and refuses an existing name (ErrPresetExists, also for a stored one that no longer parses) and more than 48 presets.

func AriaAllowed

func AriaAllowed(n *Node) bool

AriaAllowed reports whether n may carry an accessible name (aria-label): a plain div container (no link, no landmark tag) has no role that takes one.

func Breakpoints

func Breakpoints() []string

Breakpoints lists the breakpoints of a style-map key, widest first.

func CheckRefs

func CheckRefs(selfID string, d *Doc, lookup func(id string) (*Doc, bool)) error

CheckRefs refuses a doc whose references would loop or nest deeper than RefMaxDepth once the doc itself is embedded (render allows RefMaxDepth blocks on its stack, and the doc counts as one). selfID is the entity the doc belongs to (a reference to it is a cycle). lookup returns the doc of a block id; a missing block is not an error here (it renders as a placeholder). The error names the path.

func CoerceProp

func CoerceProp(kind, key, raw string) (any, error)

CoerceProp converts a posted form string to the typed value of a prop, checked against the kind's schema. An empty string returns nil, meaning "delete the prop". Object props take a JSON object.

func InlineText

func InlineText(s string) string

InlineText is the text of an inline html value: tags removed, entities decoded.

func IsPackKind

func IsPackKind(name string) bool

IsPackKind reports whether name has the shape of a plugin widget kind, whether or not it is registered.

func LightboxSrc

func LightboxSrc(src string) bool

LightboxSrc reports whether src can be opened by a lightbox link: non-empty and a path or http(s) URL (a data: or other scheme is not).

func MergeParts

func MergeParts(themeExtra []byte, parts map[string]string) ([]byte, error)

MergeParts applies a slot -> part id patch to builder.parts, leaving the other slots, tokens, presets and every other key as stored. An empty id removes the slot. An unknown slot or a non-uuid id is refused.

func MergePresets

func MergePresets(themeExtra []byte, updates map[string]*Preset) ([]byte, error)

MergePresets applies updates to builder.presets: a non-nil preset replaces or adds, a nil one deletes. Presets not named stay exactly as stored. Each one is validated and the total stays within 48.

func MergeTokens

func MergeTokens(themeExtra []byte, t Tokens) ([]byte, error)

MergeTokens replaces only builder.tokens, leaving presets (even ones that would not parse) and every other key as stored. Empty tokens remove the key.

func NodeCSS

func NodeCSS(n *Node) string

NodeCSS compiles one node's own styles with the default options.

func NodeCSSWith

func NodeCSSWith(n *Node, o CSSOpts) string

NodeCSSWith compiles one node's own styles (not its children) into rules for the selector .hm-n-<id>. Output order is deterministic. Invalid entries are skipped: Validate rejects them on save, and an invalid value is never emitted. The id is checked here too, so a doc that skipped Validate cannot inject a selector. A node that references a preset doubles the class, so its own values beat the preset's at every breakpoint whatever the source order.

func NodePreset

func NodePreset(n *Node) string

NodePreset is the style preset a native node references, or "". A component ignores presets, and an invalid name is not a reference.

func PackKindName

func PackKindName(plugin, widget string) (string, error)

PackKindName returns the builder kind of widget of plugin: "<plugin>_<widget>".

func PackOwns

func PackOwns(kind, key string) bool

PackOwns reports whether the plugin kind declares the element setting key itself.

func ParseSKey

func ParseSKey(k string) (bp, state string, ok bool)

ParseSKey splits a style-map key: "md:hover" gives ("md","hover",true), a plain "md" gives ("md","",true). Anything else ("base:", "xl:hover", "base:hover:focus", "base:visited") is not a key.

func PartSlots

func PartSlots() []string

PartSlots lists the layout slots in display order.

func PresetCSS

func PresetCSS(name string, p Preset, o CSSOpts) string

PresetCSS compiles one preset into rules for .hm-p-<name>, per breakpoint with the same media queries as a node. An invalid name yields "".

func PropBindClass

func PropBindClass(kind, key string) string

PropBindClass is the binding class ("text", "url", "image") the prop key of kind takes, "" when it is not bindable. It reads the live registry, so a plugin widget counts as soon as it is registered.

func PropMaxLength

func PropMaxLength(kind, key string) int

PropMaxLength is the schema maxLength of a string prop of kind, 0 when the kind or prop is unknown or has no limit.

func RefIDs

func RefIDs(d *Doc) []string

RefIDs returns the block ids referenced by d, unique, in document order.

func ReservedAnchor

func ReservedAnchor(a string) bool

ReservedAnchor reports whether a is an id the page itself uses.

func SectionMaps

func SectionMaps(ss []Section) []any

SectionMaps renders sections as the JSON shape stored in attributes.page_sections (the mirror of a v1-expressible doc).

func SetExtSources

func SetExtSources(ss []ExtSource)

SetExtSources replaces the registered plugin data sources (the packages / plugin layer calls it when the set of granted sources changes). Entries with a bad name, kind or class are dropped; the list is kept sorted by id.

func SetPackKinds

func SetPackKinds(ws []PackWidgetSchema) error

SetPackKinds replaces the plugin kinds with ws (nil removes them all) in one atomic swap. Core kinds are always present and never replaced; on error the previous snapshot stays.

func SlotCount

func SlotCount(d *Doc) int

SlotCount returns the number of slot nodes in d.

func SlotReplaces

func SlotReplaces(d *Doc) bool

SlotReplaces reports whether d holds a slot node with replace set: the part then stands in for the theme's own content markup (archive parts only).

func States

func States() []string

States lists the states a style-map key may add after the breakpoint ("md:hover").

func TakesChildren

func TakesChildren(kind string) bool

TakesChildren reports whether nodes of a kind can hold children.

func TakesElementProps

func TakesElementProps(kind string) bool

TakesElementProps reports whether nodes of kind carry anchor, aria and tip.

func TreeCSS

func TreeCSS(ns []*Node, out map[string]string)

TreeCSS compiles a subtree into out with the default options.

func TreeCSSIn

func TreeCSSIn(ns []*Node, parent *Node, out map[string]string, o CSSOpts)

TreeCSSIn is TreeCSSWith for nodes that sit under parent (nil at top level).

func TreeCSSWith

func TreeCSSWith(ns []*Node, out map[string]string, o CSSOpts)

TreeCSSWith compiles a subtree into out: node id -> css, only for nodes with styles.

func V1Expressible

func V1Expressible(d *Doc) bool

V1Expressible reports whether every top-level node is v1-shaped.

func ValidAnchor

func ValidAnchor(a string) bool

ValidAnchor reports whether a is usable as a public anchor id (the render also checks it: canvas patches skip Validate).

func ValidBind

func ValidBind(src string) (class string, err error)

ValidBind reports the class of a binding source, or an error wrapping ErrInvalid when it is not in the vocabulary.

func ValidExtID

func ValidExtID(id string) bool

ValidExtID reports whether id has the shape of an ext source id.

func ValidID

func ValidID(id string) bool

ValidID reports whether id is usable as a node id (and so in a class selector or attribute value).

func ValidPartSlot

func ValidPartSlot(s string) bool

ValidPartSlot reports whether s names a layout slot.

func ValidPresetName

func ValidPresetName(s string) bool

ValidPresetName reports whether s is a legal style preset name.

func ValidatePreset

func ValidatePreset(name string, p Preset) error

ValidatePreset checks one preset: a legal name, a short label and at least one style entry, every one of them valid for the StyleSpec.

func ValidateRaw

func ValidateRaw(raw []byte) error

ValidateRaw parses and validates a stored doc, enforcing the 1 MB cap.

func ValidateStyleValue

func ValidateStyleValue(key, value string) error

ValidateStyleValue checks one style value of a preset against the StyleSpec.

func ValidateToken

func ValidateToken(class, name, value string) error

ValidateToken checks one token value: class is color, space, fs or shadow.

Types

type BindSource

type BindSource struct {
	Source, Label, Group, Class string
}

BindSource is one entry of the closed source vocabulary. A Source ending in "<path>" or "<key>" is a pattern; the rest are exact.

func BindSources

func BindSources() []BindSource

BindSources lists the source vocabulary for the editor, in display order. Pattern sources end in "<path>" or "<key>". Registered plugin value sources (ext.<plugin>.<name>) follow the core ones. The result is a fresh copy.

func SourcesFor

func SourcesFor(propClass string, inLoop bool) []BindSource

SourcesFor lists the sources a prop of propClass (text, url or image) may bind to, in vocabulary order; inLoop says whether a loop item is in scope. Pattern sources are included (their Source ends in "<path>" or "<key>").

type BootKind

type BootKind struct {
	Kind     string         `json:"kind"`
	Children bool           `json:"children"`
	Props    []BootProp     `json:"props"`
	Default  map[string]any `json:"default,omitempty"`
	// Widget kinds: palette label, hint, group and the seeded children.
	Label string     `json:"label,omitempty"`
	Hint  string     `json:"hint,omitempty"`
	Group string     `json:"group,omitempty"`
	Seed  []SeedNode `json:"seed,omitempty"`
	// Hidden kinds (ref, slot) are not offered by the stock palette.
	Hidden bool `json:"hidden,omitempty"`
	// Display is the kind's default CSS display (see KindInfo.Display).
	Display string `json:"display,omitempty"`
	// Universal lists the element-setting props (anchor, aria, tip, ...) the kind takes.
	Universal []string `json:"u,omitempty"`
	// Interactive kinds may not sit inside a linked container (the editor checks it before saving).
	Interactive bool `json:"ia,omitempty"`
	// OnlyIn is the one parent kind the kind may sit under; set by BootKinds(true) only.
	OnlyIn string `json:"onlyIn,omitempty"`
}

BootKind is the JSON view of a KindInfo: what the admin builder boots from and what the MCP builder_kinds tool returns.

func BootKinds

func BootKinds(withOnlyIn bool) []BootKind

BootKinds lists every kind in palette order as JSON-ready values. The admin boot leaves withOnlyIn false (its payload is fixed); MCP asks for the rule.

type BootProp

type BootProp struct {
	Key      string   `json:"key"`
	Type     string   `json:"type"`
	Enum     []any    `json:"enum,omitempty"`
	Min      *float64 `json:"min,omitempty"`
	Max      *float64 `json:"max,omitempty"`
	Required bool     `json:"required,omitempty"`
	// Widget is the inspector control hint, MaxLength the string limit.
	Widget    string `json:"widget,omitempty"`
	MaxLength int    `json:"maxLength,omitempty"`
	// Bind is the class of source the prop accepts (text, url, image), empty when it cannot be bound.
	Bind string `json:"bind,omitempty"`
	// Pattern is the regular expression a string value must match.
	Pattern string `json:"pattern,omitempty"`
}

BootProp is the JSON view of a PropInfo.

func UniversalProps

func UniversalProps() []BootProp

UniversalProps describes the element-setting props every kind may take (a kind lists the ones it takes in BootKind.Universal), with their limits.

type CSSOpts

type CSSOpts struct {
	// Vars compiles the type-scale tokens to var(--hm-fs-<t>,<literal>) so a
	// site design system can override them; off, they compile to the literal.
	Vars bool
	// Force also emits every state rule for a forced selector,
	// [data-hm-force="hover"] and so on, so the canvas can show a state without
	// the pointer. The public render never sets it.
	Force bool
}

CSSOpts selects the spelling of the compiled CSS.

type Design

type Design struct {
	Tokens  Tokens            `json:"tokens"`
	Presets map[string]Preset `json:"presets"`
	// Parts assigns a theme_part entity id to a layout slot (see PartSlots).
	Parts map[string]string `json:"parts"`
}

Design is the site design system.

func ParseDesign

func ParseDesign(themeExtra []byte) (Design, error)

ParseDesign reads the "builder" key of the theme settings JSON. It never fails closed on bad data: invalid tokens, presets and values are dropped and reported in the returned (joined) error, the valid rest is kept. Absent data is an empty design with a nil error.

func (Design) MergeInto

func (d Design) MergeInto(themeExtra []byte) ([]byte, error)

MergeInto sets the tokens and presets of d under the "builder" key of the theme settings JSON, keeping every other key (and any other key inside "builder"). Empty parts are removed.

func (Design) TokenCSS

func (d Design) TokenCSS() string

TokenCSS returns the ":root{--hm-...}" block of the tokens that differ from their defaults, sorted by property, or "" when none does. Invalid values and unknown names are skipped, so the output is safe in a <style> element.

func (Design) Validate

func (d Design) Validate() error

Validate checks the design strictly (used on save): closed token names, valid values, valid presets.

type Doc

type Doc struct {
	V     int     `json:"v"`
	Nodes []*Node `json:"nodes"`
}

Doc is page_doc v2.

func FromSections

func FromSections(in []Section) *Doc

FromSections converts v1 page_sections into a v2 doc: each section becomes container(tag=section, v1) > component. Document order is the renderer's order: stable by sort_order, then array position. ToSections writes sort_order = position, so a round trip is equal up to sort_order renumbering and repair of unusable or duplicate section ids. Content is copied.

func Parse

func Parse(raw []byte) (*Doc, error)

Parse decodes and validates a doc. Unknown fields are rejected.

func ParseExact

func ParseExact(raw []byte) (*Doc, error)

ParseExact is Parse with numbers kept as json.Number, so a doc that is stored again keeps every digit (12345678901234567890, 9.90). Renderers use Parse, whose float64 values match what the v1 section reader produced.

func (*Doc) Apply

func (d *Doc) Apply(op Op) (Op, error)

Apply applies op and returns its inverse. The doc must be valid before the call; it is valid afterwards, and unchanged when Apply returns an error (an op that would produce an invalid doc, or break an element-setting rule the doc kept before, is rolled back and reported as ErrInvalid).

func (*Doc) CheckSettings

func (d *Doc) CheckSettings() error

CheckSettings enforces the element-setting rules that relate nodes to each other: unique, unreserved anchors; a linked container without interactive content; an image that is a link or a lightbox, not both. It runs on write paths only (not in Parse): a stored doc is never refused for these, the renderer degrades instead. Errors wrap ErrInvalid.

func (*Doc) Count

func (d *Doc) Count() int

Count is the number of nodes.

func (*Doc) Find

func (d *Doc) Find(id string) (node, parent *Node)

Find returns the node with id and its parent (nil at top level).

func (*Doc) LightboxUnnamed

func (d *Doc) LightboxUnnamed() []string

LightboxUnnamed returns the ids of the images that open in a lightbox (their own switch or their gallery's) but have nothing to name the link by: no accessible name, no alt text (a decorative image has none) and no caption. A screen reader reads such a link as an empty one. It is a warning for the author, not a save error.

func (*Doc) Validate

func (d *Doc) Validate() error

Validate checks shape, limits, ids, kinds and props. Every error wraps ErrInvalid.

type DocDiff

type DocDiff struct {
	Changes   []NodeChange
	Truncated int // changes beyond the cap, not listed
}

DocDiff is the per-node difference between two docs, matched by node id.

func DiffDocs

func DiffDocs(a, b *Doc) *DocDiff

DiffDocs compares a (older) with b (newer) by node id. A nil doc is empty. Changes come in the new doc's document order, then removed roots in the old doc's order, capped at 200.

type ExtSource

type ExtSource struct {
	Plugin, Name, Label, Kind, Class string
}

ExtSource is one data source a plugin offers to the builder. Its id in docs is "ext.<Plugin>.<Name>". Class (text, url or image) is only set for value sources.

func ExtSources

func ExtSources() []ExtSource

ExtSources returns the registered plugin data sources (a fresh copy).

func (ExtSource) ID

func (s ExtSource) ID() string

ID is the source id used in node bindings and in a loop's source prop.

type FieldChange

type FieldChange struct {
	Key, BP  string
	Kind     string // DiffAdded | DiffRemoved | DiffChanged
	Old, New string // short renderings, "" when absent
	// Note qualifies the change ("formatting changed": an inline html change
	// whose text is the same).
	Note string
}

FieldChange is one changed prop, style or binding. BP is set for styles.

type KindInfo

type KindInfo struct {
	Kind     string
	Children bool
	Props    []PropInfo
	Default  map[string]any
	// Universal lists the universal props (UniversalKeys) this kind takes.
	Universal []string
	// Interactive kinds render (or may render) links, buttons or other interactive
	// content, so a linked container cannot hold them (see InteractiveIn).
	Interactive bool
	// Widget kinds only: palette label, hint, group and the children a fresh
	// node is inserted with.
	Label, Hint, Group string
	// OnlyIn is the one parent kind a node of this kind may sit under ("" = any).
	OnlyIn string
	Seed   []SeedNode
	// Hidden kinds are read by the client but never offered by the stock
	// palette: the editor adds ref through blocks, slot in part mode and
	// loopempty from a loop's inspector.
	Hidden bool
	// Display is the CSS display a shown node of this kind has by default (the
	// root rule of its base or widget CSS; a container in grid layout is "grid").
	// The editor writes it when "show" has to undo a wider hide.
	Display string
}

KindInfo describes one node kind for the palette, inspector and outline. Default holds the props of a fresh node (nil when the kind needs none).

func Kinds

func Kinds() []KindInfo

Kinds lists every node kind in palette order. The result is a fresh copy.

type Node

type Node struct {
	ID string                       `json:"id"`
	T  string                       `json:"t"`
	P  map[string]any               `json:"p,omitempty"`
	S  map[string]map[string]string `json:"s,omitempty"`
	C  []*Node                      `json:"c,omitempty"`
	// B binds props to data: prop key -> source (see BindSources). While b[key]
	// exists p[key] is ignored; render resolves the source.
	B map[string]string `json:"b,omitempty"`
}

Node is one element of the tree.

t: "container" | widget kind | "component" (theme section)
p: props, validated per kind by a JSON Schema
s: styles per breakpoint ("base", "md", "sm") or breakpoint and state
   ("md:hover"; see ParseSKey), StyleSpec keys only
c: children (containers only)
b: prop bindings, prop key -> data source

func Components

func Components(d *Doc) []*Node

Components returns every component node in document order, for readers that scan theme-section content (forms, entity links).

func FreshIDs

func FreshIDs(ns []*Node, gen func() string) []*Node

FreshIDs returns a deep copy of ns with new ids from gen, unique within the copy (a repeated id from gen is asked for again).

func InteractiveIn

func InteractiveIn(n *Node) *Node

InteractiveIn returns the first node below n (depth first, hidden ones included) that is or may be interactive, or nil. n itself is not examined: a linked container is the link.

func NewComponent

func NewComponent(typ, id string) (*Node, error)

NewComponent returns a component node of the given theme section type.

func NewNode

func NewNode(kind, id string) (*Node, error)

NewNode returns a valid default node of a native kind. The component kind needs a type, so it is refused here: use NewComponent.

func NewTree

func NewTree(kind string) (Node, error)

NewTree returns a valid default node of kind with its seeded children, all with fresh ids. Like NewNode, a component is refused.

func NodesOfKind

func NodesOfKind(d *Doc, kind string) []*Node

NodesOfKind returns every node of kind in document order, for readers that need a widget's props (the forms a page embeds).

func PrefixIDs

func PrefixIDs(ns []*Node, prefix string) []*Node

PrefixIDs returns a deep copy of ns with every id set to prefix+id, so a block's nodes never collide with the ids of the page that embeds it. An id that would pass 64 characters becomes prefix + 12 hex digits of the hash of the original id. The result is deterministic and every id stays valid.

func ReadableNodes

func ReadableNodes(content []byte) []*Node

ReadableNodes returns the top-level nodes of a tree template's content that this build accepts, each checked as a doc of its own.

func V1Shaped

func V1Shaped(n *Node) (*Node, bool)

V1Shaped reports whether a top-level node is exactly what a v1 section converts to, and returns its component. Renderers use it to send such nodes through the theme section partial (byte-identical to v1).

type NodeChange

type NodeChange struct {
	ID    string
	T     string // kind in the new doc (old doc for removed)
	Label string // palette label of T, T itself when it has none
	Hint  string // a short text of the node, "" when it has none
	Op    string // DiffAdded | DiffRemoved | DiffMoved | DiffChanged
	// Parent is the parent id in the new doc (old doc for removed), "" = top
	// level; Index is the position among its siblings there.
	Parent  string
	Index   int
	Subtree int
	// Field changes of a node in both docs (a moved node lists them too).
	Props, Styles, Binds []FieldChange
	TypeFrom             string // the old kind when t changed
}

NodeChange is one node that differs. Added and removed nodes are reported by their root only (Subtree counts the descendants that went with them).

type Op

type Op struct {
	Op     string          `json:"op"` // insert | move | remove | setProp | setStyle | setBind
	ID     string          `json:"id,omitempty"`
	Parent string          `json:"parent,omitempty"` // "" = top level
	Index  int             `json:"index,omitempty"`
	Node   *Node           `json:"node,omitempty"`
	Key    string          `json:"key,omitempty"`
	BP     string          `json:"bp,omitempty"`
	Value  json.RawMessage `json:"value,omitempty"` // setProp: any JSON, null deletes; setStyle, setBind: string, null deletes
}

Op is one edit. The editor sends these verbs; Apply returns the inverse so undo is just applying the inverse ops in reverse order.

type PackWidgetSchema

type PackWidgetSchema struct {
	Name   string // the full kind, <plugin>_<widget>
	Schema []byte
	// contains filtered or unexported fields
}

PackWidgetSchema is one parsed plugin widget schema, ready for SetPackKinds.

func ParsePackWidget

func ParsePackWidget(plugin, widget string, schema []byte, own map[string]bool) (PackWidgetSchema, error)

ParsePackWidget validates the schema.json of widget of plugin. own names the full kinds of every widget of the same package, which a seed or only_in may reference besides native and core kinds.

func (PackWidgetSchema) Owned

func (w PackWidgetSchema) Owned() []string

Owned lists the element settings (anchor, aria, tip) the widget declares as its own props, sorted. The core skips them for the kind. Installing a new package that does so is refused; an installed one keeps working.

type Preset

type Preset struct {
	Label string                       `json:"label"`
	S     map[string]map[string]string `json:"s"`
}

Preset is a named, reusable StyleSpec style map (breakpoint -> key -> value).

type PropInfo

type PropInfo struct {
	Key      string
	Type     string
	Enum     []any
	Min, Max *float64
	Required bool
	// Widget is the inspector control hint (x-hm-widget), "" for the default
	// control of the type. MaxLength is the string length limit, 0 for none.
	Widget    string
	MaxLength int
	// Bind is the class of source the prop accepts (x-hm-bind: text, url or
	// image), "" when the prop cannot be bound.
	Bind string
}

PropInfo describes one prop of a node kind, derived from its compiled schema. Type is "string", "integer", "boolean" or "object".

type Section

type Section struct {
	ID        string
	Type      string
	Title     string
	Content   map[string]any
	IsVisible *bool
	SortOrder int
	// Extra holds the section keys this model does not know. They ride along
	// in the component's p.extra so a round trip never drops them.
	Extra map[string]any
}

Section is one v1 page section, as in attributes.page_sections[]. It mirrors render.Section so the two convert without a shared dependency.

func LegacySections

func LegacySections(d *Doc) ([]Section, bool)

LegacySections is the section list of a page, derived from its doc: what readers that still want v1-shaped data (the public JSON, plugins, hooks) see instead of the frozen page_sections mirror. ok is false when the doc holds anything v1 cannot express (a builder-only page has no sections).

func SectionFromMap

func SectionFromMap(i int, m map[string]any) Section

SectionFromMap reads the i-th stored page_sections item. It is the one reader of that shape (the public renderer, the write seam and the convert CLI all use it), so they cannot disagree: an id missing or not a string becomes its printed value or "s<i>", sort_order may be a number or a numeric string, and every other key lands in Extra.

func SectionsFromJSON

func SectionsFromJSON(attrs json.RawMessage, exact bool) []Section

SectionsFromJSON decodes attributes.page_sections one item at a time, so a malformed sibling costs that section and not the page. exact keeps numbers as json.Number (the write path); otherwise they are float64 (the render path).

func ToSections

func ToSections(d *Doc) ([]Section, bool)

ToSections converts a doc back to v1 sections: ok is false once the doc holds anything v1 cannot express. sort_order is the position.

type SeedNode

type SeedNode struct {
	T string            `json:"t"`
	P map[string]any    `json:"p,omitempty"`
	B map[string]string `json:"b,omitempty"`
	C []SeedNode        `json:"c,omitempty"`
}

SeedNode is a child inserted with a freshly dropped widget.

type StyleSpecEntry

type StyleSpecEntry struct {
	Key   string   `json:"key"`
	Kind  string   `json:"kind"`
	Props []string `json:"props"`
	// Tokens maps an allowed token to its CSS value (space, color, radius, fs, len).
	Tokens map[string]string `json:"tokens,omitempty"`
	// Enum maps an allowed value to its CSS value (kind enum).
	Enum map[string]string `json:"enum,omitempty"`
	// Pattern is the regexp of the literal values allowed besides tokens.
	Pattern string `json:"pattern,omitempty"`
	// Min, Max and Tpl describe a numeric key (kind count): a whole number in
	// [Min,Max] replaces %d in Tpl.
	// Min and Max are pointers so a zero bound (z: 0) is still sent.
	Min *int   `json:"min,omitempty"`
	Max *int   `json:"max,omitempty"`
	Tpl string `json:"tpl,omitempty"`
	// Settle marks a key the client does not preview on its own: the server
	// css message settles it.
	Settle bool `json:"settle,omitempty"`
	// States marks a key that may be set inside a state (hover, focus, ...).
	States bool `json:"states,omitempty"`
}

StyleSpecEntry is one style key of the table served to clients.

func StyleSpecTable

func StyleSpecTable() []StyleSpecEntry

StyleSpecTable returns the vocabulary as JSON-serialisable data, sorted by key. The slice and maps are fresh copies; callers cannot alter the compiler.

type Tokens

type Tokens struct {
	Color  map[string]string `json:"color,omitempty"`
	Space  map[string]string `json:"space,omitempty"`
	FS     map[string]string `json:"fs,omitempty"`
	Shadow map[string]string `json:"shadow,omitempty"`
}

Tokens are the editable values of the design tokens. A missing entry means the built-in default.

func DefaultTokens

func DefaultTokens() Tokens

DefaultTokens returns the built-in token values (what the editor prefills).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL