Documentation
¶
Overview ¶
Package component defines the component model for GoFastr's core-ui framework.
A Component describes its visual appearance via the Render method, returning render.HTML. Components that handle user events implement the InteractiveComponent interface by adding an Actions method.
The package provides:
- Component and InteractiveComponent interfaces
- ComponentBase for embedding common fields (ID, Class)
- ComponentContext for event data and state access
- ActionRegistry and On() for declarative event handling
- Lifecycle hooks (Mount, Update, Unmount)
- ComponentList for rendering multiple components
Basic usage:
type Greeting struct {
component.ComponentBase
Name string
}
func (g *Greeting) Render() render.HTML {
return render.Tag("p", nil, render.Text("Hello, "+g.Name))
}
Index ¶
- func ComponentList(components ...Component) render.HTML
- func IsInteractive(c Component) bool
- func RenderComponent(c Component) render.HTML
- func SafeRender(c Component) (html render.HTML, err error)
- func SafeRenderCtx(ctx context.Context, c Component) (html render.HTML, err error)
- type ActionDef
- type ActionOption
- type ActionRegistry
- type Component
- type ComponentBase
- type ComponentContext
- type ContextComponent
- type ContextOnly
- type ErrorBoundary
- type InteractiveComponent
- type Lifecycle
- type LifecycleHook
- type ServerCall
- type Widget
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ComponentList ¶
ComponentList renders multiple components joined together.
func IsInteractive ¶
IsInteractive returns true if the component implements InteractiveComponent.
func RenderComponent ¶
RenderComponent calls the Render method of any Component and returns its HTML. This is a convenience function for composing components.
func SafeRender ¶
SafeRender calls Render() with panic recovery. If the component panics, it returns a fallback error UI. Components implementing ErrorBoundary get a custom fallback; others get a generic red-bordered box.
func SafeRenderCtx ¶
SafeRenderCtx is the context-aware variant of SafeRender. If c implements ContextComponent its RenderCtx(ctx) is called; otherwise Render() is called. Panic recovery and ErrorBoundary handling are identical to SafeRender.
Types ¶
type ActionDef ¶
type ActionDef struct {
Event string // "click", "submit", "input", "change", "keydown", etc.
Handler func(*ComponentContext) // the server-side handler (runs in Go)
Server bool // if true, this action must run on the server
Debounce int // debounce in milliseconds (0 = no debounce)
// ClientJS is the JavaScript handler body. This is what gets compiled
// into the actions.js bundle. It receives a `params` object with:
// params.value — input value (for input/change events)
// params.* — any data-param-* attributes from the trigger element
//
// Available runtime helpers via `G` (window.__gofastr):
// G.getState(key, default) G.setState(key, value)
// G.updateText(sel, text) G.updateHTML(sel, html)
// G.toast(msg) G.navigate(path)
// G.addClass(sel, cls) G.removeClass(sel, cls)
//
// Example: "G.setState('count', G.getState('count', 0) + 1); G.updateText('[data-count]', G.getState('count', 0));"
ClientJS string
}
ActionDef defines a single event handler within a component.
func On ¶
func On(event string, handler func(*ComponentContext), opts ...ActionOption) ActionDef
On registers an event handler into the current registry. This is the primary API for .ui.go files.
Usage: On("click", func(ctx *ComponentContext) { ... }, WithClientJS("G.setState('x', 1)"))
type ActionOption ¶
type ActionOption func(*ActionDef)
ActionOption is a functional option for ActionDef.
func WithClientJS ¶
func WithClientJS(js string) ActionOption
WithClientJS sets the client-side JavaScript handler body. This JS runs in the browser when the action is triggered.
type ActionRegistry ¶
type ActionRegistry struct {
// contains filtered or unexported fields
}
ActionRegistry holds all registered actions for a component.
func ExtractActions ¶
func ExtractActions(c Component) *ActionRegistry
func NewActionRegistry ¶
func NewActionRegistry() *ActionRegistry
NewActionRegistry creates a new action registry.
func (*ActionRegistry) All ¶
func (r *ActionRegistry) All() []ActionDef
All returns all registered actions.
func (*ActionRegistry) Get ¶
func (r *ActionRegistry) Get(eventName string) (ActionDef, bool)
Get retrieves the action for an event name.
func (*ActionRegistry) HasActions ¶
func (r *ActionRegistry) HasActions() bool
HasActions returns true if any actions are registered.
func (*ActionRegistry) Register ¶
func (r *ActionRegistry) Register(action ActionDef)
Register adds an action handler for an event.
type Component ¶
Component is the base interface for all UI components. A component describes its appearance via Render.
type ComponentBase ¶
ComponentBase provides common fields for all components. Embed this in your component structs for convenience.
type ComponentContext ¶
type ComponentContext struct {
// Event data
EventName string
TargetID string
Params map[string]string
// State access
StateGetter func(key string) any
StateSetter func(key string, value any)
}
ComponentContext holds the execution context for a component action. It provides access to event data and component state.
func NewComponentContext ¶
func NewComponentContext(eventName, targetID string, params map[string]string) *ComponentContext
NewComponentContext creates a new context with the given event data.
func (*ComponentContext) GetState ¶
func (ctx *ComponentContext) GetState(key string) any
GetState retrieves state by key.
func (*ComponentContext) Param ¶
func (ctx *ComponentContext) Param(name string) string
Param returns a named parameter from the event context.
func (*ComponentContext) ParamInt ¶
func (ctx *ComponentContext) ParamInt(name string) (int, error)
ParamInt returns a named integer parameter from the event context.
func (*ComponentContext) SetState ¶
func (ctx *ComponentContext) SetState(key string, value any)
SetState updates state by key.
type ContextComponent ¶
ContextComponent is the optional ctx-aware render interface. Implementations receive the request context and can branch on auth state, locale, or any other request-scoped value that isn't loaded into struct fields by Load(ctx).
The framework prefers RenderCtx over Render when both exist. ContextComponent intentionally does NOT embed Component — a type that only wants the ctx-aware shape can satisfy Component via the ContextOnly{} embed below, avoiding the `func (c) Render() HTML { return c.RenderCtx(context.Background()) }` boilerplate.
type ContextOnly ¶
type ContextOnly struct{}
ContextOnly is a zero-byte embed helper for components that only want to implement RenderCtx. Embedding it provides a Render() satisfying the Component interface; that Render is never called when the type also implements RenderCtx (the framework dispatch prefers RenderCtx and skips Render in that case).
type Home struct {
component.ContextOnly
// ... your fields
}
func (h *Home) RenderCtx(ctx context.Context) render.HTML { ... }
No need to write a Render() stub on Home — ContextOnly provides one.
func (ContextOnly) Render ¶
func (ContextOnly) Render() render.HTML
Render satisfies the Component interface. In practice it is never called: SafeRenderCtx and Screen.RenderCtx detect RenderCtx via a structural type check and route to it directly.
type ErrorBoundary ¶
ErrorBoundary is implemented by components that provide a custom error fallback.
type InteractiveComponent ¶
type InteractiveComponent interface {
Component
Actions()
}
InteractiveComponent extends Component with event handling. Components that implement this interface can respond to user events.
type Lifecycle ¶
type Lifecycle struct {
// contains filtered or unexported fields
}
Lifecycle manages mount, update, and unmount hooks.
func (*Lifecycle) HasMountHooks ¶
HasMountHooks returns true if any mount hooks are registered.
func (*Lifecycle) OnMount ¶
func (l *Lifecycle) OnMount(fn LifecycleHook)
OnMount registers a hook to run when the component first renders.
func (*Lifecycle) OnUnmount ¶
func (l *Lifecycle) OnUnmount(fn LifecycleHook)
OnUnmount registers a hook to run when the component is removed.
func (*Lifecycle) OnUpdate ¶
func (l *Lifecycle) OnUpdate(fn LifecycleHook)
OnUpdate registers a hook to run when the component re-renders.
func (*Lifecycle) TriggerMount ¶
func (l *Lifecycle) TriggerMount()
TriggerMount runs all mount hooks.
func (*Lifecycle) TriggerUnmount ¶
func (l *Lifecycle) TriggerUnmount()
TriggerUnmount runs all unmount hooks.
func (*Lifecycle) TriggerUpdate ¶
func (l *Lifecycle) TriggerUpdate()
TriggerUpdate runs all update hooks.
type LifecycleHook ¶
type LifecycleHook func()
LifecycleHook is a function that runs at a specific point in a component's life.
type ServerCall ¶
ServerCall represents a call that should be executed on the server.
func Server ¶
func Server(action string, params ...string) *ServerCall
Server marks an action as requiring server-side execution. When the compiler sees this, it generates JS that POSTs to the server instead of running locally. The server handler runs in a goroutine.
type Widget ¶
type Widget struct {
ID string // unique widget ID (used for data-widget attribute)
Component Component // the component that renders this widget
Actions *ActionRegistry // extracted actions from the component
}
Widget is a self-contained interactive unit that serves as a hydration boundary. Widgets are hydrated incrementally on first user interaction. Components inside a Widget are compiled to JS for client-side execution.
func NewWidget ¶
NewWidget creates a new widget wrapping a component. It automatically extracts actions if the component implements InteractiveComponent.
func (*Widget) IsInteractive ¶
IsInteractive returns true if the widget's component has actions.