Documentation
¶
Overview ¶
Package interactive provides declarative interactivity primitives for GoFastr components. It wraps arbitrary render.HTML with data-fui-* attributes the runtime understands — RPC calls, signal bindings, widget chaining — without writing any JavaScript.
Usage:
interactive.OnClick(btn,
interactive.Post("/api/like").OnSuccess(interactive.SetSignal("count")),
)
The package only emits attributes the runtime already handles (data-fui-rpc, data-fui-signal, data-fui-open, etc.) plus new ones added for chaining (data-fui-rpc-open, data-fui-rpc-signal).
Index ¶
- func AnimateOnSignal(html render.HTML, signalName, cssClass string) render.HTML
- func BindAttr(html render.HTML, signal, attr string) render.HTML
- func BindHTML(html render.HTML, signal string) render.HTML
- func BindText(html render.HTML, signal string) render.HTML
- func CancelEdit(html render.HTML, signalName string) render.HTML
- func ClosePaneOnClick(html render.HTML, pane string) render.HTML
- func Dropdown(trigger, panel render.HTML) render.HTML
- func EditToggle(html render.HTML, signalName string) render.HTML
- func IncLocal(html render.HTML, signalName string, delta int) render.HTML
- func LiveSearch(form render.HTML, action Action, debounceMs int) render.HTML
- func OnClick(html render.HTML, action Action) render.HTML
- func OnSubmit(html render.HTML, action Action) render.HTML
- func OpenOnClick(html render.HTML, widget string) render.HTML
- func OpenPaneOnClick(html render.HTML, pane string) render.HTML
- func OptimisticUpdate(action Action, idle, success render.HTML) render.HTML
- func Reveal(html render.HTML, animationType string) render.HTML
- func SectionMenu(cfg SectionMenuConfig) render.HTML
- func SectionMenuDrawer(cfg SectionMenuConfig) *widget.Builder
- func SetLocal(html render.HTML, signalName, value string) render.HTML
- func ToastOnClick(html render.HTML, t Toast) render.HTML
- func ToggleLocal(html render.HTML, signalName string) render.HTML
- type Action
- type Effect
- func AfterDisable() Effect
- func AfterText(text string) Effect
- func CloseWidget() Effect
- func Confirm(message string) Effectdeprecated
- func Navigate(path string) Effect
- func OpenWidget(name string) Effect
- func PushState(path string) Effect
- func ResetForm() Effect
- func ScrollTo(selector string) Effect
- func SetSignal(name string) Effect
- type SectionGroup
- type SectionItem
- type SectionMenuConfig
- type Toast
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AnimateOnSignal ¶
AnimateOnSignal wraps an element so it gets a CSS class when a signal is truthy and loses it when falsy. Used for CSS transition-driven animations like slide-down, fade, etc.
Panics if signalName or cssClass is empty.
func BindAttr ¶ added in v0.42.0
BindAttr wraps an HTML element whose attribute tracks a signal. Injects data-fui-signal, data-fui-signal-mode="attr", and data-fui-signal-attr="<attr>". Use when a signal should drive a single attribute (e.g. aria-expanded, data-active) rather than text content.
func BindHTML ¶ added in v0.42.0
BindHTML wraps an HTML region whose innerHTML is replaced with the signal value (the trusted-HTML path). Injects data-fui-signal and data-fui-signal-mode="html". Use for an island slot an RPC re-renders server-side and returns as a fragment.
func BindText ¶ added in v0.42.0
BindText wraps an HTML element whose textContent tracks a signal (HTML-escaped). Injects data-fui-signal and data-fui-signal-mode="text". This is the default mode — a bare data-fui-signal with no mode behaves identically — but emitting the mode explicitly documents intent.
func CancelEdit ¶
CancelEdit wraps an element so clicking it sets a signal to false, closing the inline-edit mode. Typically used on a cancel button inside the edit form.
func ClosePaneOnClick ¶ added in v0.42.0
ClosePaneOnClick wraps an HTML element so clicking it closes a side pane. Maps to data-fui-pane-close="<pane>". A non-empty pane ("secondary" or "tertiary") closes that specific pane; an empty pane emits data-fui-pane-close="" and closes the topmost open pane. Any other value panics.
func EditToggle ¶
EditToggle wraps an element so clicking it toggles a boolean signal. Semantic alias for ToggleLocal used in inline-edit patterns: clicking the text span enters edit mode.
func IncLocal ¶
IncLocal wraps an HTML element so clicking it increments a numeric signal by delta (default 1). No RPC is fired.
func LiveSearch ¶
LiveSearch wraps a form element so input changes fire debounced RPCs. The search input should be the first <input> inside the form. Results are written into the signal named by the action's OnSuccess effect (typically via SetSignal).
debounceMs controls the delay between keystrokes and the RPC call. If debounceMs is 0, a default of 300ms is used.
func OnClick ¶
OnClick wraps an HTML element so that clicking it fires the action. The element must be a clickable element (button, a, etc.).
func OpenOnClick ¶ added in v0.42.0
OpenOnClick wraps an HTML element so clicking it opens a registered widget surface. Maps to data-fui-open="<widget>". This is the click-to-open trigger — distinct from OpenWidget, which opens a widget only after a successful RPC (data-fui-rpc-open).
func OpenPaneOnClick ¶ added in v0.42.0
OpenPaneOnClick wraps an HTML element so clicking it opens the named side pane. Maps to data-fui-pane-open="<pane>". Panics unless pane is "secondary" or "tertiary".
func OptimisticUpdate ¶
─── Optimistic update ─────────────────────────────────────────────
OptimisticUpdate renders a button that flips to its "success" visual state immediately on click, fires an RPC in the background, and reverts to idle if the RPC fails (non-2xx or network error).
The runtime module optimisticaction.js handles the full lifecycle: idle → pending (optimistic flip) → committed (RPC 2xx) or error → idle.
The caller provides two visual states:
- idle: the default appearance (e.g. "♡ Like")
- success: the committed appearance (e.g. "♥ Liked")
Example:
OptimisticUpdate(
interactive.Post("/api/like/42"),
render.HTML(`<span class="icon">♡</span> Like`),
render.HTML(`<span class="icon">♥</span> Liked`),
)
Produces:
<button data-fui-comp="ui-optimistic-action"
data-state="idle"
data-fui-optimistic-endpoint="/api/like/42"
data-fui-optimistic-method="POST">
<span data-fui-optimistic-idle><span class="icon">♡</span> Like</span>
<span hidden data-fui-optimistic-success><span class="icon">♥</span> Liked</span>
</button>
func Reveal ¶
Reveal wraps an element so it animates in when it enters the viewport. The animationType determines the direction ("fade-up", "fade-in", "slide-left", "slide-right"). Empty → "fade-in". The element renders visible without JS (progressive enhancement); reveal.js adds the hidden state on boot and removes it on intersection.
func SectionMenu ¶
func SectionMenu(cfg SectionMenuConfig) render.HTML
SectionMenu renders the desktop rail plus the mobile trigger button. Mount the matching drawer once with SectionMenuDrawer.
func SectionMenuDrawer ¶
func SectionMenuDrawer(cfg SectionMenuConfig) *widget.Builder
SectionMenuDrawer returns the mobile drawer widget for a SectionMenu — a left-edge preset.Drawer (backdrop + click-outside / Escape close + scroll lock + focus trap) carrying the same menu body. Mount it once at startup:
widget.MountBuilder(router, interactive.SectionMenuDrawer(cfg))
func SetLocal ¶
SetLocal wraps an HTML element so clicking it sets a signal to a fixed value. No RPC is fired — the update is instant.
func ToastOnClick ¶ added in v0.42.0
ToastOnClick wraps an HTML element so clicking it fires a toast with the given config. Maps to data-fui-toast="<json>". The JSON is compact (no whitespace) with HTML escaping disabled, matching what call sites hand-write today; render.Attr then escapes the value for the attribute context.
Types ¶
type Action ¶
type Action struct {
// contains filtered or unexported fields
}
Action describes an RPC call triggered by click or submit.
func (Action) Attrs ¶ added in v0.42.0
Attrs returns the data-fui-* attributes this Action would inject, as a plain map[string]string. It is the same map OnClick/OnSubmit splice into the opening tag — exported so a call site can merge it into an existing attribute map (an render.Tag attrs map or a ui.*Config ExtraAttrs) and let render.Tag's sorted writer place every attribute in the same order a hand-written map would. Prefer this over the wrapper functions whenever byte-identical attribute ordering matters (the wrappers append at the tag's first '>', which can reorder attributes relative to a sorted map render).
The returned map is a fresh copy; mutating it does not affect the Action. It is assignable directly to html.Attrs (a map[string]string alias) and to render.Tag's attrs argument.
func (Action) WithBody ¶ added in v0.42.0
WithBody attaches a static JSON body to the action — the payload sent for a non-form RPC (a button click that isn't inside a <form>). Maps to data-fui-rpc-body="<json>". The runtime sends it verbatim as the request body with Content-Type: application/json.
Panics if json is not valid JSON (json.Valid), so a malformed body fails loudly at build/render time rather than producing a runtime request the server rejects. For form-backed RPCs the runtime serializes the form fields itself — do not call WithBody there.
func (Action) WithConfirm ¶ added in v0.12.0
WithConfirm gates the action behind a PRE-FLIGHT confirmation. Before the RPC is dispatched, the runtime shows a native window.confirm(message) dialog; cancelling aborts the request entirely, so the RPC never fires. Because the gate runs *before* the request — not after it succeeds — it is a property of the Action itself, not an OnSuccess effect. Use for destructive actions (delete, revoke, drop):
interactive.OnClick(deleteBtn,
interactive.Delete("/api/items/42").
WithConfirm("Delete this item? This cannot be undone."),
)
window.confirm is native, unthemed, and blocks browser automation. For a design-system-styled confirmation that matches the rest of the app (and is drivable by tests), reach for framework/ui.ConfirmAction instead — it renders a themed alertdialog whose Confirm button carries the RPC.
Maps to data-fui-confirm="message".
type Effect ¶
type Effect interface {
// contains filtered or unexported methods
}
Effect is something that happens after an RPC response.
func AfterDisable ¶ added in v0.3.2
func AfterDisable() Effect
AfterDisable permanently disables the trigger element on 2xx RPC success (sets aria-disabled="true" and, for buttons/inputs, disabled=true). Use with AfterText for "Saved ✓" / "Revealed ✓" feedback. Maps to the boolean attribute data-fui-rpc-after-disable.
func AfterText ¶ added in v0.3.2
AfterText replaces the trigger element's text content with text on 2xx RPC success. One-shot — subsequent re-clicks are idempotent via data-fui-rpc-after-done. Pair with AfterDisable for "Saved ✓" feedback. Maps to data-fui-rpc-after-text="text".
func CloseWidget ¶
func CloseWidget() Effect
CloseWidget closes the enclosing widget on RPC success. Maps to data-fui-rpc-close="true".
func Confirm
deprecated
added in
v0.3.2
Confirm shows a window.confirm dialog before the RPC fires. The RPC is cancelled if the user dismisses the dialog.
Deprecated: Confirm is passed to OnSuccess(...) even though it fires PRE-flight (before the request, not after success) — a placement that has misled readers into thinking the gate runs on the response. Use Action.WithConfirm(message) instead, which reads in the correct order and lives where the timing implies. This effect still works and maps to the same data-fui-confirm attribute.
func Navigate ¶
Navigate does an SPA navigation on RPC success. Maps to data-fui-rpc-navigate="path".
func OpenWidget ¶
OpenWidget opens a named widget when the RPC succeeds. Maps to data-fui-rpc-open="name".
func PushState ¶ added in v0.3.2
PushState applies a URL update via history.pushState after 2xx RPC success without triggering a fetch. The server-supplied X-Gofastr-Push-State header takes precedence over this attribute when both are present. Maps to data-fui-push-state="path".
func ResetForm ¶
func ResetForm() Effect
ResetForm resets the enclosing form on RPC success. Maps to data-fui-rpc-reset="true".
type SectionGroup ¶
type SectionGroup struct {
Label string
Eyebrow string // optional ordinal/kicker shown before the label (e.g. "01")
Items []SectionItem
// Collapsed starts the group closed in the mobile drawer. A group holding
// the active item is forced open regardless. (The desktop rail always
// shows every group expanded.)
Collapsed bool
}
SectionGroup is a labelled, collapsible cluster of items.
type SectionItem ¶
type SectionItem struct {
Label string
Href string
Active bool // marks the current page (aria-current="page" + .is-active)
}
SectionItem is one navigable link in a SectionMenu group.
type SectionMenuConfig ¶
type SectionMenuConfig struct {
// Lead is an optional ungrouped item rendered above the groups
// (e.g. an "Overview" / index link).
Lead *SectionItem
Groups []SectionGroup
// AriaLabel names the nav landmark (e.g. "Documentation sections").
AriaLabel string
// TriggerLabel is the mobile trigger button's text. Default "Menu".
TriggerLabel string
// DrawerName is the widget name shared by the trigger button
// (data-fui-open) and SectionMenuDrawer. Required for the mobile sheet;
// must be unique per distinct menu on a site.
DrawerName string
Class string
ID string
}
SectionMenuConfig configures a SectionMenu and its drawer.
type Toast ¶ added in v0.42.0
type Toast struct {
Variant string `json:"variant,omitempty"` // "success" | "warning" | "danger" | "info" | "neutral"; defaults to "info"
Title string `json:"title,omitempty"` // required by the runtime — a toast with no title is dropped
Body string `json:"body,omitempty"` // optional supporting copy
Stack string `json:"stack,omitempty"` // named [data-fui-toast-stack] container; empty → the auto stack
TTLMs int `json:"ttl,omitempty"` // auto-dismiss delay in ms; 0 → persistent (manual dismiss only)
}
Toast is the config for a click-fired toast notification. Zero fields are omitted from the emitted JSON, so a Toast{Variant, Title, Body, TTLMs} marshals to exactly {"variant":…,"title":…,"body":…,"ttl":…} — the shape call sites hand-write. The runtime's toast module (core-ui/runtime/src/toasts.js __gofastr.toast) reads these keys: variant, title, body, ttl, stack.