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 ¶
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.