Documentation
¶
Overview ¶
Package registry is the process-global catalog of components whose CSS is shipped as real stylesheets and loaded on demand by the runtime.
Registration is handle-based: RegisterStyle returns a *Style. The caller stashes the handle in a package var and reuses it at every render site. The component name lives in exactly one place.
// modal/modal.go
var Style = registry.RegisterStyle("modal", modalCSS)
func modalCSS(t style.Theme) string {
return style.NewComponentSheet("modal", t).
Rule(".header").Set("font-weight", "700").End().
MustBuild()
}
// at a render site:
func (s *Screen) Render() render.HTML {
return modal.Style.Render(&modal.Modal{Title: "Hi"})
}
Style.Render wraps the component, injects data-fui-comp="<name>" onto its outermost tag (no extra DOM node), and records the name into a request-scoped collector so the SSR host can emit a <link> in <head> before first paint. After hydration, the runtime takes over: any data-fui-comp marker in newly inserted DOM triggers loadComponentCSS, which dedups on the link's data-fui-style attr.
Component CSS is always scoped to [data-fui-comp="<name>"]. Global rules belong in theme.css or WithCustomCSS — see the design doc at core-ui/ARCHITECTURE.md.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EagerNames ¶
func EagerNames() []string
EagerNames returns the sorted list of names of every LoadAlways entry. Used by the SSR host to seed <head> links on every page regardless of what the page actually rendered.
Types ¶
type Entry ¶
type Entry struct {
Name string
StyleFn func(style.Theme) string
Load LoadMode
// contains filtered or unexported fields
}
Entry is one row in the catalog.
type LoadMode ¶
type LoadMode int
LoadMode controls when a component's CSS is fetched by the browser.
const ( // LoadAuto loads the component's CSS the first time its marker // appears in the DOM. The SSR host also emits a <link> in <head> // for any LoadAuto component rendered on the initial page, so // there is no FOUC on hard load. LoadAuto LoadMode = iota // LoadPrewarm behaves like LoadAuto + a throttled idle-time // prefetch. Use for components that are likely to appear soon // (a command palette, a modal opened from a hotkey). LoadPrewarm // LoadAlways emits the <link> in <head> on every page, // regardless of whether the page renders the component. Use for // page chrome — headers, layout primitives — that almost every // screen touches. LoadAlways )
type Style ¶
type Style struct {
// contains filtered or unexported fields
}
Style is the handle returned by RegisterStyle. Authors keep it in a package var and call .Render at every use site.
func RegisterStyle ¶
RegisterStyle registers a component's stylesheet builder under a process-wide unique name and returns a handle. Identical re-registration (same StyleFn pointer + same options) is a no-op; any other duplicate panics so misnames surface at startup.
func (*Style) Render ¶
Render renders the component and injects data-fui-comp="<name>" onto its outermost tag. Panics on malformed component output with a message that tells the author how to fix it.
The injected marker is the source of truth for both:
the SSR host (which scans the final rendered HTML and emits <link>s in <head> before first paint via registry.Scan), and
the client runtime (which scans newly inserted DOM and calls loadComponentCSS for each marker).
Both paths dedup on the link's data-fui-style attribute, so a component never re-fetches across the SSR + hydration handoff or across page-to-page navigations.
func (*Style) WrapHTML ¶
WrapHTML is the function-level form of Render. Use it when the component renders via a helper function returning render.HTML (most of framework/ui), so you can adopt the registry without restructuring into a Component type.
func PageHeader(cfg PageHeaderConfig) render.HTML {
return Style.WrapHTML(/* existing render */)
}