Documentation
¶
Overview ¶
Package bind provides element annotation helpers for tether. Each helper attaches a data-tether-* attribute to a Fluent element, telling the client JS runtime how to handle that element - which events to forward, what client-side behaviour to apply, or which reactive signals to bind.
All bindings are applied via Apply with composable Option values:
bind.Apply(button.Text("Delete"),
bind.OnClick("delete"),
bind.Confirm("Are you sure?"),
bind.Disable("Deleting..."),
)
This top-to-bottom style scales cleanly as behaviours are stacked and provides a single, consistent way to annotate elements.
Index ¶
- func Apply[E Settable[E]](el E, opts ...Option) E
- type Option
- func AutoFocus() Option
- func BindAttr(attr, signal string) Option
- func BindClass(class, signal string) Option
- func BindHide(signal string) Option
- func BindShow(signal string) Option
- func BindText(signal string) Option
- func BindValue(signal string) Option
- func Cloak() Option
- func Collect(selector string) Option
- func Confirm(message string) Option
- func Data(key, value string) Option
- func Debounce(d time.Duration) Option
- func Disable(text string) Option
- func Event(eventType, action string) Option
- func EventData(key, value string) Option
- func FilterKey(key string) Option
- func FocusTrap() Option
- func Hook(name string) Option
- func Indicator(selector string) Option
- func Link() Option
- func OnBlur(action string) Option
- func OnChange(action string) Option
- func OnClick(action string) Option
- func OnFocus(action string) Option
- func OnInput(action string) Option
- func OnKeyDown(action string) Option
- func OnSubmit(action string) Option
- func OnViewport(action string) Option
- func Optimistic(signal, value string) Option
- func OptimisticToggle(signal string) Option
- func Permanent() Option
- func Prefix(name string) Option
- func PushSubscribe() Option
- func Reset() Option
- func SetSignal(signal, value string) Option
- func Throttle(d time.Duration) Option
- func ToggleAttr(attr string) Option
- func ToggleClass(class string) Option
- func ToggleSignal(signal string) Option
- func ToggleTarget(selector string) Option
- func Transition(name string) Option
- func Upload(action string) Option
- func UploadInput(selector string) Option
- func UploadProgress(action string) Option
- type Settable
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Option ¶
type Option struct {
// contains filtered or unexported fields
}
Option describes a single data attribute to apply to an element. Use with Apply for a top-to-bottom composition style when stacking multiple behaviours on one element:
bind.Apply(button.Text("Delete"),
bind.OnClick("delete"),
bind.Confirm("Are you sure?"),
bind.Disable("Deleting..."),
)
func AutoFocus ¶
func AutoFocus() Option
AutoFocus moves keyboard focus to this element after each server update morphs the DOM. Use this on the primary input in a form so the cursor returns there after each interaction.
func BindAttr ¶
BindAttr sets an HTML attribute to the signal's value. When the signal is falsy the attribute is removed entirely. Use this for dynamic attributes like "disabled", "aria-expanded", or "href".
func BindClass ¶
BindClass adds the CSS class when the named signal is truthy and removes it when falsy. Use this for conditional styling that reacts to server-pushed state without a full render cycle.
func BindHide ¶
BindHide is the inverse of BindShow: the element is hidden when the signal is truthy and visible when falsy.
func BindShow ¶
BindShow makes the element visible when the named signal is truthy and hidden when falsy. Visibility is toggled via CSS display - the element remains in the DOM either way.
func BindText ¶
BindText replaces the element's text content with the signal's current value whenever the server pushes an update via [tether.Session.Signal]. The signal name must match the key passed to Signal().
func BindValue ¶
BindValue binds a form element's value property (input, select, textarea) to a named signal. When the server pushes a new signal value, the form element's displayed value updates instantly.
func Cloak ¶
func Cloak() Option
Cloak hides the element until the tether runtime initialises. The client removes the attribute on startup, making the element visible. Use this to prevent a flash of unbound content - e.g. a signal-bound element that would briefly show its raw template text before the signal value is applied.
func Collect ¶
Collect adds a CSS selector that the client resolves at event time. Matched elements contribute their current value to Event.Data, keyed by the element's name or id attribute. Use this to send input values with a click or keydown event without wrapping in a form:
bind.Apply(button.New().Text("Send"),
bind.OnClick("chat.send"),
bind.Collect("#message-input"),
)
func Confirm ¶
Confirm shows a browser confirmation dialog before the event is sent. If the user cancels, the event is silently dropped.
func Data ¶
Data sets a custom data-tether-* attribute on the element. This is the escape hatch for attributes not covered by the built-in options.
func Debounce ¶
Debounce overrides the default input debounce delay for this element. The default (300ms, configurable via [tether.App].Client.DefaultDebounce) groups rapid keystrokes into a single event. Set a shorter duration for search-as-you-type, or a longer one for expensive operations.
func Disable ¶
Disable replaces the element's text and disables it while the server processes the event. The original text and state are restored when the server responds. Prevents double-clicks and gives users visual feedback that something is happening.
func Event ¶
Event forwards an arbitrary DOM event to the server. Use this for event types not covered by the built-in options (OnClick, OnSubmit, etc.). The eventType is the standard DOM event name.
bind.Apply(el, bind.Event("dblclick", "open-editor"))
func EventData ¶
EventData attaches a static key-value pair to every event from this element. The pair appears in [tether.Event].Data alongside any values the client collects automatically (input value, form fields). Use this to carry context - like an item ID - with each click so the handler knows which item was acted on without maintaining server-side selection state.
func FilterKey ¶
FilterKey restricts an OnKeyDown binding to fire only for a specific key (e.g. "Enter", "Escape"). Other keys are silently ignored by the client and never reach the server.
func FocusTrap ¶
func FocusTrap() Option
FocusTrap constrains keyboard focus (Tab/Shift+Tab) to elements within this container. Use this for modals and drawers to prevent focus from escaping to elements behind the overlay - required for accessibility.
func Hook ¶
Hook attaches a named JS lifecycle hook to the element. Hooks are defined in application JS (e.g. hooks.js) and receive callbacks for mounted, updated, and destroyed events. Use this to integrate third-party JS libraries (charts, maps, editors) that need to initialise when the element appears, update when its data attributes change, and clean up when it is removed from the DOM.
func Indicator ¶
Indicator shows a loading spinner or skeleton at the given CSS selector while the server processes the event. The indicator is removed when the server responds. Use this for actions where the user needs visual feedback in a different part of the page from the triggering element.
func Link ¶
func Link() Option
Link enables client-side navigation for anchor elements. Instead of a full page reload, the client intercepts the click, updates the browser URL via pushState, and sends a navigate event to the server. The server re-renders the active page and pushes a diff - only the changed content is updated, preserving scroll position and input state. Use this for navigation within a single tether handler. For links to a different handler (e.g. from /ws/ to /sse/), use a regular <a> tag so the browser performs a full page load.
func OnBlur ¶
OnBlur forwards blur events to the server. Fires when the element loses keyboard focus. Useful for validating input on exit.
func OnChange ¶
OnChange forwards change events to the server. Unlike OnInput, this fires once when the user commits a value (leaving a text field, selecting a dropdown option, toggling a checkbox). The element's value is included in [tether.Event].Data["value"].
func OnClick ¶
OnClick forwards click events to the server. The action identifies which click this is (e.g. "delete", "save") so Handle can switch on it.
func OnFocus ¶
OnFocus forwards focus events to the server. Fires when the element receives keyboard focus (click, tab, or programmatic focus).
func OnInput ¶
OnInput forwards input events to the server with debouncing. The element's current value is included automatically in [tether.Event].Data["value"]. Debounce delay defaults to 300ms (configurable via [tether.App].Client.DefaultDebounce or per-element via Debounce).
func OnKeyDown ¶
OnKeyDown forwards keydown events to the server. The pressed key name (e.g. "Enter", "Escape", "ArrowUp") is available via [tether.Event].Key(). Combine with FilterKey to restrict which keys trigger the server event.
func OnSubmit ¶
OnSubmit forwards form submissions to the server. All named fields inside the form are automatically collected into [tether.Event].Data so the handler can read them by name (ev.Data["email"], ev.Int("age")).
func OnViewport ¶
OnViewport fires when the element enters the visible viewport, using an IntersectionObserver internally. Place this on a sentinel element at the bottom of a list to implement infinite scroll - when the sentinel scrolls into view, the server loads the next page of data.
func Optimistic ¶
Optimistic sets a signal immediately on click AND sends the event to the server. The signal provides instant visual feedback while the server processes the event. If the server sends a different signal value in its response, the client updates to match - the server is always authoritative.
func OptimisticToggle ¶
OptimisticToggle flips a boolean signal immediately on click AND sends the event to the server. Like Optimistic but for boolean toggles - the signal flips instantly while the server processes the real state change.
func Permanent ¶
func Permanent() Option
Permanent excludes the element from DOM morphing. When idiomorph processes a server update, it skips elements marked permanent - their content, attributes, and children are preserved exactly as-is. Use this for elements with client-side state that must survive server updates (e.g. a video player, an interactive map, or a third-party widget that manages its own DOM).
func Prefix ¶
Prefix sets the event namespace for a component container. When the client JS sends an event from inside a prefixed container, it automatically prepends the prefix to the action. This allows components to use bare action names (e.g. "send") while the framework routes them via the full prefixed name (e.g. "shoutbox.send").
Apply Prefix to the element that wraps a mounted component's Render output:
bind.Apply(div.New(s.Chat.Render()), bind.Prefix("chat")).Dynamic("chat-section")
func PushSubscribe ¶
func PushSubscribe() Option
PushSubscribe marks a button for Web Push subscription. On click, the browser requests notification permission from the user and, if granted, subscribes via the service worker's PushManager. The subscription is sent to [tether.PushConfig].OnSubscribe so it can be stored for later use with [tether.Session.Push].
func Reset ¶
func Reset() Option
Reset clears all form fields after a successful submit. Useful for chat-style inputs where the form should be ready for the next message immediately after sending.
func SetSignal ¶
SetSignal sets a signal to a specific value on click. No server round-trip - the signal updates instantly on the client. Use this for tab selection, radio-style patterns, or any case where clicking an element should set a known value.
func Throttle ¶
Throttle sets a minimum interval between events from this element. Unlike Debounce which waits for a pause, Throttle fires the first event immediately and drops subsequent events until the interval elapses. Use this for scroll or resize handlers where you want regular updates without flooding the server.
func ToggleAttr ¶
ToggleAttr toggles a boolean HTML attribute (e.g. "hidden", "disabled", "open") on click without a server round-trip.
func ToggleClass ¶
ToggleClass adds or removes a CSS class on click without a server round-trip. Useful for toggling visibility, active states, or themes entirely on the client. Combine with ToggleTarget to toggle a class on a different element.
func ToggleSignal ¶
ToggleSignal flips a boolean signal between true and false on click. No server round-trip - the signal updates instantly on the client. Combine with BindShow or BindClass for UI that toggles without network latency (dropdowns, accordions, dark mode).
func ToggleTarget ¶
ToggleTarget directs a ToggleClass or ToggleAttr at a different element identified by a CSS selector, rather than the clicked element.
func Transition ¶
Transition enables CSS enter/leave transitions on the element. The name maps to CSS class prefixes: {name}-enter-from, {name}-enter-to, {name}-leave-from, {name}-leave-to. When the element is added to the DOM, the enter classes are applied; when removed, the leave classes animate the element out before it is actually deleted.
func Upload ¶
Upload marks the element as a file upload trigger. Clicking it opens the browser's file picker. When files are selected, they are uploaded as a multipart POST to the server and delivered to [tether.UploadConfig].Handle. The action string identifies which upload this is (e.g. "avatar", "document") and appears in [tether.Upload].Action.
func UploadInput ¶
UploadInput provides a CSS selector for the file <input> element when it is not adjacent to the upload trigger in the DOM. By default the client looks for the nearest file input; use this when the input is elsewhere (e.g. hidden, in a different container).
func UploadProgress ¶
UploadProgress binds a <progress> element's value attribute to the upload progress for the named action. The client updates the value (0–100) as bytes are sent, giving users a visual progress bar.