registry

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 12 Imported by: 0

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.

func Scan

func Scan(html string) []string

Scan returns the sorted, deduped list of component names referenced by data-fui-comp attributes in html. Used by the SSR host to decide which <link> tags to emit in <head>.

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.

func All

func All() []*Entry

All returns a snapshot of every registered entry, sorted by name.

func Lookup

func Lookup(name string) (*Entry, bool)

Lookup returns the entry registered under name.

func (*Entry) CSSFor

func (e *Entry) CSSFor(theme style.Theme) string

CSSFor returns the scoped CSS bytes for this entry under the given theme, building and caching on first call.

func (*Entry) VersionFor

func (e *Entry) VersionFor(theme style.Theme) string

VersionFor returns the content-addressed version string for this entry's CSS under the given theme. Build is shared with CSSFor.

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 Option

type Option func(*Entry)

Option configures an Entry at registration time.

func WithLoad

func WithLoad(m LoadMode) Option

WithLoad sets the load mode. Default is LoadAuto.

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

func RegisterStyle(name string, fn func(style.Theme) string, opts ...Option) *Style

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) Entry

func (s *Style) Entry() *Entry

Entry returns the underlying Entry (for the catalog endpoint).

func (*Style) Name

func (s *Style) Name() string

Name returns the registered name.

func (*Style) Render

func (s *Style) Render(c component.Component) render.HTML

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

func (s *Style) WrapHTML(html render.HTML) render.HTML

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 */)
}

Jump to

Keyboard shortcuts

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