forms

package
v1.27.0 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

FilterBar component: the horizontal auto-submit filter row for list pages — the converged shape behind DiscordSync's filterForm (9 list pages) and dnsblockd's filter rows, extracted per the 2026-10-10 four-project analysis (TODO_LIST #390). Composes FilterDropdown/FilterInput/Checkbox children; see docs/recipes/horizontal-filter-bar.md for the pattern this component productizes (including the two battle-tested footguns it encodes).

FilterChips component: zero-JS link-based filter chips — filter state lives in the URL, chips are plain links, no JavaScript anywhere (SEO- and crawler-friendly). Extracted from nsfw-classifier's historyChip (history_page.templ:105, 2026-10-10 analysis, TODO_LIST #391).

SegmentedControl component: a single-select segmented button group in two zero-JS modes — link mode (server-round-trip filtering, the FilterChips sibling with segmented visuals) and radio mode (a native radiogroup that submits with its enclosing form, e.g. FilterBar). Extracted from dnsblockd's duration/preset button groups and nsfw-classifier's threshold presets (2026-10-10 analysis, TODO_LIST #394).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FilterToggleHref

func FilterToggleHref(basePath string, params url.Values, key, value string) string

FilterToggleHref builds a chip href that sets key=value on basePath, preserving every other query param; an empty value REMOVES the key (the "All" chip). Values are URL-escaped via url.Values — injection-safe by construction.

href := forms.FilterToggleHref("/history", r.URL.Query(), "source", "upload")

Types

type FilterBarProps

type FilterBarProps struct {
	utils.BaseProps

	// Action is the list-page URL: the form's GET action (the no-JS
	// fallback), the Reset link target, and — when Wire is unset — the
	// auto-submit fetch URL. An empty Action renders an unwired form
	// (inert bar; useful for pure-CSS composition).
	Action string
	// Wire, when set with a non-empty URL, owns the auto-submit wiring in
	// both dialects. Defaults applied by the component: the change event
	// plus form encoding, so every filter field in the form serializes.
	// Target/PushURL render for htmx only; Datastar targeting is
	// response-driven — wrap the handler in wire.Handler.
	Wire *wire.Action
	// Target is the results-region selector the response swaps into
	// (htmx hx-target). Empty leaves htmx's default (the form itself).
	Target string
	// Sticky renders the top-anchored shell (sticky top-0, z-20, border,
	// solid background) — the pattern for bars above long result lists.
	Sticky bool
	// ResetText renders a ghost Reset link to the unfiltered Action URL
	// when non-empty ("Reset" via DefaultFilterBarProps).
	ResetText string
	// NoPushURL opts out of pushing the filtered URL (the zero value
	// pushes, so filtered views are shareable — the list-page convention;
	// htmx dialect only).
	NoPushURL bool
}

FilterBarProps configures a horizontal auto-submit filter bar. The bar is a GET form: children render the filter controls (FilterDropdown selects, checkboxes, search inputs, hidden inputs); any select or checkbox change re-submits the form without a page reload, and the noscript Apply button keeps non-JS browsers working with a full-page load.

func DefaultFilterBarProps

func DefaultFilterBarProps() FilterBarProps

DefaultFilterBarProps returns sensible defaults.

type FilterChip

type FilterChip struct {
	// Label is the visible chip text.
	Label string
	// Href is the link target carrying the chip's filter state.
	Href string
	// Active marks the currently applied filter. The active chip renders
	// aria-current="true" and the filled style; keeping the link (like the
	// extraction source) is honest about the current state.
	Active bool
}

FilterChip is one filter link. The consumer owns the href — filter state is query-param truth, and only the consumer knows the page's full param set (cursors, lanes, sibling filters). Build common toggles with FilterToggleHref.

type FilterChipsProps

type FilterChipsProps struct {
	utils.BaseProps

	// Chips renders left to right. Provide an "All" chip (empty-value href)
	// so users can clear the filter without JavaScript.
	Chips []FilterChip
}

FilterChipsProps configures a row of zero-JS filter chips.

func DefaultFilterChipsProps

func DefaultFilterChipsProps() FilterChipsProps

DefaultFilterChipsProps returns sensible defaults.

type SegmentedControlItem

type SegmentedControlItem struct {
	// Label is the visible text.
	Label string
	// Value is the option's submitted value (radio mode).
	Value string
	// Href, when set on ANY item, switches the whole control to link mode —
	// every item should carry one (a mixed control is a consumer bug;
	// items without an Href render inert links in link mode).
	Href string
}

SegmentedControlItem is one option.

type SegmentedControlProps

type SegmentedControlProps struct {
	utils.BaseProps

	// Name is the radio group's field name (radio mode). Ignored in link
	// mode.
	Name string
	// Items render in FORWARD DOM order (first item first) so radiogroup
	// arrow keys move down the value order (the Rating rule).
	Items []SegmentedControlItem
	// ActiveValue marks the selected item: the checked radio (radio mode)
	// or aria-current link (link mode).
	ActiveValue string
}

SegmentedControlProps configures a segmented single-select group.

func DefaultSegmentedControlProps

func DefaultSegmentedControlProps() SegmentedControlProps

DefaultSegmentedControlProps returns sensible defaults.

Jump to

Keyboard shortcuts

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