Documentation
¶
Overview ¶
ARIA attribute helpers for form field accessibility.
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
Package forms provides accessible, CSP-compliant form controls for Go templ applications.
Components include text inputs, selects, textareas, checkboxes, labels, and validation error helpers. All controls support error states with proper ARIA attributes.
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
ID sanitization for form field elements.
Shared Tailwind class strings for form input elements.
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
Radio and RadioGroup component types and helpers.
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
templ: version: v0.3.1020
Index ¶
- func Calendar(props CalendarProps) templ.Component
- func Checkbox(props CheckboxProps) templ.Component
- func Combobox(props ComboboxProps) templ.Component
- func DatePicker(props DatePickerProps) templ.Component
- func DirtyGuard(props DirtyGuardProps) templ.Component
- func EnterKeyHintTypeIsValid(v EnterKeyHintType) bool
- func ErrorAttrs(id, errorMessage, helpTextID string) templ.Attributes
- func FieldError(fieldID, message string) templ.Component
- func FileInput(props FileInputProps) templ.Component
- func FilterDropdown(props FilterDropdownProps) templ.Component
- func FilterInput(props FilterInputProps) templ.Component
- func Form(props FormProps) templ.Component
- func FormEnctypeIsValid(e FormEnctype) bool
- func FormFieldWrapper(props FormFieldProps) templ.Component
- func FormLayoutIsValid(l FormLayout) bool
- func FormMethodIsValid(v FormMethod) bool
- func HelpTextID(id string) string
- func Input(props InputProps) templ.Component
- func InputGroup(props InputGroupProps) templ.Component
- func InputGroupPaddingClass(left, right bool) string
- func InputTypeIsValid(v InputType) bool
- func Label(forID, text string, required bool) templ.Component
- func Radio(props RadioProps) templ.Component
- func RadioGroup(props RadioGroupProps) templ.Component
- func Rating(props RatingProps) templ.Component
- func RatingSizeIsValid(v RatingSize) bool
- func SanitizeID(s string) string
- func Select(props SelectProps) templ.Component
- func Slider(props SliderProps) templ.Component
- func TagsInput(props TagsInputProps) templ.Component
- func Textarea(props TextareaProps) templ.Component
- func Toggle(props ToggleProps) templ.Component
- func ToggleSizeIsValid(v ToggleSize) bool
- func ValidationSummary(props ValidationSummaryProps) templ.Component
- type CalendarProps
- type CheckboxProps
- type ComboboxOption
- type ComboboxProps
- type DatePickerProps
- type DirtyGuardProps
- type EnterKeyHintType
- type FileInputProps
- type FilterDropdownProps
- type FilterInputProps
- type FormEnctype
- type FormFieldProps
- type FormLayout
- type FormMethod
- type FormProps
- type InputGroupProps
- type InputProps
- type InputType
- type RadioGroupProps
- type RadioOption
- type RadioProps
- type RatingProps
- type RatingSize
- type SelectGroup
- type SelectOption
- type SelectProps
- type SliderProps
- type TagsInputProps
- type TextareaProps
- type ToggleProps
- type ToggleSize
- type ValidationError
- type ValidationSummaryProps
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Calendar ¶ added in v0.17.0
func Calendar(props CalendarProps) templ.Component
Calendar renders a month-view calendar with server-side navigation. Each day is a link (when HrefBase is set) or a span.
@forms.Calendar(forms.CalendarProps{
Year: 2026, Month: time.July,
SelectedDate: &someDate,
HrefBase: "/calendar?y={year}&m={month}&d={day}",
HrefPrev: "/calendar?y=2026&m=6",
HrefNext: "/calendar?y=2026&m=8",
})
Example ¶
selected := time.Date(2026, 7, 15, 0, 0, 0, 0, time.UTC)
_ = Calendar(CalendarProps{
Year: 2026,
Month: time.July,
SelectedDate: &selected,
HrefBase: "/calendar?y={year}&m={month}&d={day}",
})
func Checkbox ¶
func Checkbox(props CheckboxProps) templ.Component
Checkbox renders a checkbox with label
@forms.Checkbox(forms.CheckboxProps{Name: "terms", ID: "terms", Label: "I agree to the terms"})
func Combobox ¶ added in v0.4.0
func Combobox(props ComboboxProps) templ.Component
Combobox renders an accessible autocomplete input with a filterable dropdown. As the user types, options are filtered client-side. Clicking an option fills the input and sets the hidden value for form submission.
@forms.Combobox(forms.ComboboxProps{
Name: "country",
ID: "country",
Label: "Country",
Placeholder: "Search countries...",
Options: []forms.ComboboxOption{
{Value: "de", Label: "Germany"},
{Value: "at", Label: "Austria"},
},
})
func DatePicker ¶ added in v0.4.0
func DatePicker(props DatePickerProps) templ.Component
DatePicker renders a labeled date input with optional min/max constraints, error, and help text
@forms.DatePicker(forms.DatePickerProps{
Name: "birthday",
ID: "birthday",
Label: "Date of Birth",
Required: true,
})
func DirtyGuard ¶ added in v1.14.0
func DirtyGuard(props DirtyGuardProps) templ.Component
DirtyGuard renders the page-level script for the unsaved-changes guard. Include it once per page; forms opt in by rendering the `data-tc-dirty-guard` attribute (forms.FormProps.DirtyGuard does this). The guard marks a guarded form dirty on any input or change and clears it when that form submits (native and wired submits both dispatch the submit event, so HTMX and Datastar submissions clear the flag too). When the user tries to leave with a dirty form, the browser's native confirmation dialog appears — the dialog text is chosen by the browser, not the page.
The script is idempotent across HTMX swaps and Datastar patches (global singleton flag, ADR-0005) and tracks form elements in a WeakSet, so swapped-in forms start clean without any re-initialization. Auto-submit filter components (FilterInput) do not dispatch submit events — apply the guard to save-style forms, not live filters.
@forms.DirtyGuard(forms.DirtyGuardProps{Nonce: nonce})
...
@forms.Form(forms.FormProps{Action: "/save", DirtyGuard: true}) { ... }
func EnterKeyHintTypeIsValid ¶ added in v0.18.0
func EnterKeyHintTypeIsValid(v EnterKeyHintType) bool
EnterKeyHintTypeIsValid returns true if v is a recognized enterkeyhint value.
func ErrorAttrs ¶
func ErrorAttrs(id, errorMessage, helpTextID string) templ.Attributes
ErrorAttrs returns templ attributes for aria-invalid and aria-describedby when an error message or help text is present. Returns nil only when both errorMessage and helpTextID are empty. When helpTextID is non-empty it is always emitted via aria-describedby (independent of id), so id-less fields with help text remain accessible to assistive technology.
func FieldError ¶
FieldError renders a field-level validation error
@forms.FieldError("email", "This field is required")
func FileInput ¶
func FileInput(props FileInputProps) templ.Component
FileInput renders a labeled file input with styled native button
@forms.FileInput(forms.FileInputProps{
Name: "avatar",
Label: "Upload avatar",
Accept: "image/*",
})
func FilterDropdown ¶ added in v0.17.0
func FilterDropdown(props FilterDropdownProps) templ.Component
FilterDropdown renders a compact labeled select with HTMX auto-submit. It is designed for filter bars where each dropdown independently triggers a server-side filter refresh on change.
@forms.FilterDropdown(forms.FilterDropdownProps{
Name: "status",
Label: "Status",
Value: "active",
HxGet: "/api/users",
HxTarget: "#user-list",
Options: []forms.SelectOption{
{Value: "", Label: "All"},
{Value: "active", Label: "Active"},
{Value: "inactive", Label: "Inactive"},
},
})
Example ¶
_ = FilterDropdown(FilterDropdownProps{
Name: "status",
Label: "Status",
Value: "active",
HxGet: "/api/users",
HxTarget: "#user-list",
Options: []SelectOption{
{Value: "all", Label: "All"},
{Value: "active", Label: "Active"},
{Value: "inactive", Label: "Inactive"},
},
})
Example (Wired) ¶
_ = FilterDropdown(FilterDropdownProps{
Name: "status",
Label: "Status",
Options: []SelectOption{
{Value: "active", Label: "Active"},
{Value: "inactive", Label: "Inactive"},
},
Wire: &wire.Action{
URL: "/api/users/filter",
Target: "#user-list",
},
})
func FilterInput ¶ added in v1.14.0
func FilterInput(props FilterInputProps) templ.Component
FilterInput renders a debounced search/filter input that auto-submits as the user types. The `<search>` landmark wraps a GET form, so the request carries the field as a query parameter under both transports and the form still submits natively without JavaScript.
@forms.FilterInput(forms.FilterInputProps{
Name: "q",
Label: "Search users",
Placeholder: "Type to filter…",
Wire: &wire.Action{URL: "/api/users/search", Target: "#user-list"},
})
Example ¶
_ = FilterInput(FilterInputProps{
Name: "q",
Label: "Search users",
Placeholder: "Type to filter…",
DebounceMS: 300,
Wire: &wire.Action{
URL: "/api/users/search",
Target: "#user-list",
},
})
func Form ¶
Form renders a form element with optional CSRF token
@forms.Form(forms.FormProps{Action: "/submit", CSRFToken: "token123"}) {
@forms.Input(forms.InputProps{Name: "email"})
}
Dual-transport submit — the same props under either runtime:
@forms.Form(forms.FormProps{
Wire: &wire.Action{Transport: wire.TransportDatastar, Method: wire.MethodPost, URL: "/api/save"},
}) {
@forms.Input(forms.InputProps{Name: "email"})
}
Example ¶
_ = Form(FormProps{
Action: "/api/users",
Method: FormPost,
CSRFToken: "example-token",
})
Example (Wire) ¶
_ = Form(FormProps{
Method: FormPost,
CSRFToken: "session-token",
NoValidate: true,
Wire: &wire.Action{
Method: wire.MethodPost,
URL: "/api/save",
Target: "#save-region",
},
})
func FormEnctypeIsValid ¶ added in v1.14.0
func FormEnctypeIsValid(e FormEnctype) bool
FormEnctypeIsValid reports whether e is a recognized FormEnctype. The zero value counts as valid: it means "use the HTML default".
func FormFieldWrapper ¶
func FormFieldWrapper(props FormFieldProps) templ.Component
FormFieldWrapper renders the standard form field structure: optional Label, children (input/select/textarea), optional Error, optional HelpText. Use this to DRY up all form control components.
@forms.FormFieldWrapper(forms.FormFieldProps{ID: "email", Label: "Email", Required: true, Error: "Invalid", HelpText: "Use work email"}) {
<input type="email" name="email" />
}
func FormLayoutIsValid ¶ added in v0.19.0
func FormLayoutIsValid(l FormLayout) bool
FormLayoutIsValid reports whether l is a recognized FormLayout.
func FormMethodIsValid ¶ added in v0.8.0
func FormMethodIsValid(v FormMethod) bool
FormMethodIsValid reports whether v is one of the defined FormMethod constants.
func HelpTextID ¶
HelpTextID returns the HTML ID for a help text element, or "" if id is empty.
func Input ¶
func Input(props InputProps) templ.Component
Input renders a labeled text input with optional error and help text
@forms.Input(forms.InputProps{
Name: "email",
Type: forms.InputEmail,
Label: "Email address",
Required: true,
})
Example ¶
_ = Input(InputProps{
Name: "email",
Type: InputEmail,
Label: "Email address",
Placeholder: "you@example.com",
HelpText: "We'll never share your email.",
})
func InputGroup ¶
func InputGroup(props InputGroupProps) templ.Component
InputGroup renders a form control with optional left/right addons. Addons are absolutely positioned inside the input area.
@forms.InputGroup(forms.InputGroupProps{
LeftAddon: icons.Icon(icons.Search, "h-5 w-5 text-gray-400 dark:text-gray-500"),
}) {
@forms.Input(forms.InputProps{Class: "ps-10"})
}
func InputGroupPaddingClass ¶
InputGroupPaddingClass returns the appropriate padding class for an input that lives inside an InputGroup with the given addons. Call this from your input's Class field to avoid manual padding:
@forms.InputGroup(forms.InputGroupProps{LeftAddon: icon}) {
@forms.Input(forms.InputProps{Class: forms.InputGroupPaddingClass(true, false)})
}
func InputTypeIsValid ¶ added in v0.8.0
InputTypeIsValid reports whether v is one of the defined InputType constants.
func Label ¶
Label renders a form label with optional required indicator
@forms.Label("email", "Email address", true)
func Radio ¶
func Radio(props RadioProps) templ.Component
Radio renders a single radio button with label
@forms.Radio(forms.RadioProps{
ID: "plan-pro",
Name: "plan",
Value: "pro",
Label: "Pro Plan",
Checked: true,
})
func RadioGroup ¶
func RadioGroup(props RadioGroupProps) templ.Component
RadioGroup renders a fieldset of radio buttons with legend, error, and help text
@forms.RadioGroup(forms.RadioGroupProps{
Name: "plan",
Label: "Select a plan",
Options: []forms.RadioOption{
{Value: "free", Label: "Free"},
{Value: "pro", Label: "Pro"},
},
})
func Rating ¶ added in v0.17.0
func Rating(props RatingProps) templ.Component
Rating renders an accessible star rating using radio inputs. Each star is a labeled radio button with keyboard navigation. In ReadOnly mode, renders a static display with aria-label.
@forms.Rating(forms.RatingProps{
Name: "quality",
Value: 4,
Max: 5,
})
Example ¶
_ = Rating(RatingProps{
Name: "quality",
Value: 4,
Max: 5,
Label: "Product Quality",
})
Example (ReadOnly) ¶
_ = Rating(RatingProps{
Value: 3,
Max: 5,
ReadOnly: true,
})
func RatingSizeIsValid ¶ added in v0.17.0
func RatingSizeIsValid(v RatingSize) bool
RatingSizeIsValid reports whether v is one of the defined RatingSize constants.
func SanitizeID ¶
SanitizeID returns a safe HTML ID from arbitrary text.
func Select ¶
func Select(props SelectProps) templ.Component
Select renders a labeled select dropdown
@forms.Select(forms.SelectProps{
Name: "country",
Label: "Country",
Options: []forms.SelectOption{
{Value: "de", Label: "Germany"},
{Value: "at", Label: "Austria"},
},
})
// Grouped options (renders <optgroup>):
//
@forms.Select(forms.SelectProps{
Name: "channel",
Label: "Channel",
Groups: []forms.SelectGroup{
{Label: "Text Channels", Options: []forms.SelectOption{
{Value: "general", Label: "#general"},
{Value: "random", Label: "#random"},
}},
{Label: "Voice Channels", Options: []forms.SelectOption{
{Value: "voice-1", Label: "🔊 Lounge"},
}},
},
})
Example ¶
_ = Select(SelectProps{
Name: "country",
Label: "Country",
Options: []SelectOption{
{Value: "us", Label: "United States"},
{Value: "de", Label: "Germany"},
},
})
func Slider ¶ added in v0.17.0
func Slider(props SliderProps) templ.Component
Slider renders a labeled range input with accessible labeling.
@forms.Slider(forms.SliderProps{
Name: "volume",
Label: "Volume",
Min: 0,
Max: 100,
Value: 50,
Step: 5,
})
Example ¶
_ = Slider(SliderProps{
Name: "volume",
Label: "Volume",
Min: 0,
Max: 100,
Value: 50,
Step: 5,
ShowValue: true,
})
func TagsInput ¶ added in v0.17.0
func TagsInput(props TagsInputProps) templ.Component
TagsInput renders a tag input with add/remove functionality. Tags are submitted as repeated hidden inputs. A CSP-safe singleton script handles Enter-to-add, Backspace-to-delete-last, and remove-button clicks.
@forms.TagsInput(forms.TagsInputProps{
Name: "skills",
Label: "Skills",
Values: []string{"Go", "HTMX"},
Placeholder: "Add a skill...",
})
Example ¶
_ = TagsInput(TagsInputProps{
Name: "skills",
Label: "Skills",
Values: []string{"Go", "HTMX"},
Placeholder: "Add a skill...",
})
func Textarea ¶
func Textarea(props TextareaProps) templ.Component
Textarea renders a labeled textarea
@forms.Textarea(forms.TextareaProps{
Name: "bio",
Label: "Bio",
Rows: 4,
Placeholder: "Tell us about yourself...",
})
Example ¶
_ = Textarea(TextareaProps{
Name: "bio",
Label: "Biography",
Placeholder: "Tell us about yourself...",
Rows: 4,
MaxLength: 500,
})
func Toggle ¶
func Toggle(props ToggleProps) templ.Component
Toggle renders an accessible toggle switch Uses a visually-hidden checkbox for native form submission and accessibility.
@forms.Toggle(forms.ToggleProps{Name: "notifications", Label: "Enable notifications", Checked: true})
func ToggleSizeIsValid ¶ added in v0.8.0
func ToggleSizeIsValid(v ToggleSize) bool
ToggleSizeIsValid reports whether v is one of the defined ToggleSize constants.
func ValidationSummary ¶ added in v0.3.0
func ValidationSummary(props ValidationSummaryProps) templ.Component
ValidationSummary renders an accessible error summary for form validation
@forms.ValidationSummary(forms.ValidationSummaryProps{
Errors: []forms.ValidationError{
{Field: "email", Message: "Email is required"},
{Field: "name", Message: "Name must be at least 2 characters"},
},
})
Types ¶
type CalendarProps ¶ added in v0.17.0
type CalendarProps struct {
utils.BaseProps
// Year and Month define which month to display.
Year int
Month time.Month
// SelectedDate highlights the matching day.
SelectedDate *time.Time
// HrefBase is the URL pattern for day links. Use {year}, {month}, {day} as placeholders.
// Example: "/calendar?year={year}&month={month}&day={day}"
HrefBase string
// HrefPrev/HrefNext are URLs for the prev/next month navigation links.
HrefPrev string
HrefNext string
// MinDate/MaxDate disable days outside the range.
MinDate *time.Time
MaxDate *time.Time
}
CalendarProps configures a month-view calendar for date selection. Navigation is server-side via HrefPrev/HrefNext links.
func DefaultCalendarProps ¶ added in v0.17.0
func DefaultCalendarProps() CalendarProps
DefaultCalendarProps returns sensible defaults (current month).
type CheckboxProps ¶
type CheckboxProps struct {
utils.BaseProps
Name string
Value string
Label string
Checked bool
Required bool
Disabled bool
Error string
HelpText string
}
CheckboxProps configures a checkbox input
func DefaultCheckboxProps ¶
func DefaultCheckboxProps() CheckboxProps
DefaultCheckboxProps returns sensible defaults
type ComboboxOption ¶ added in v0.4.0
ComboboxOption represents a single selectable option in a combobox.
type ComboboxProps ¶ added in v0.4.0
type ComboboxProps struct {
utils.BaseProps
Name string
Label string
Placeholder string
Options []ComboboxOption
Value string
Required bool
Disabled bool
Error string
HelpText string
}
ComboboxProps configures an autocomplete text input with a filterable dropdown of options. The selected value is submitted via a hidden input with the given Name, so it works in plain HTML forms and HTMX requests.
func DefaultComboboxProps ¶ added in v0.4.0
func DefaultComboboxProps() ComboboxProps
DefaultComboboxProps returns sensible defaults
type DatePickerProps ¶ added in v0.4.0
type DatePickerProps struct {
utils.BaseProps
Name string
Value string
Label string
Min string
Max string
Required bool
Disabled bool
Error string
HelpText string
}
DatePickerProps configures a native HTML date input
func DefaultDatePickerProps ¶ added in v0.4.0
func DefaultDatePickerProps() DatePickerProps
DefaultDatePickerProps returns sensible defaults
type DirtyGuardProps ¶ added in v1.14.0
DirtyGuardProps configures the unsaved-changes guard script.
type EnterKeyHintType ¶ added in v0.18.0
type EnterKeyHintType string
EnterKeyHintType defines valid HTML enterkeyhint values for the mobile keyboard Enter key label. See: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint
const ( EnterKeyHintEnter EnterKeyHintType = "enter" EnterKeyHintDone EnterKeyHintType = "done" EnterKeyHintGo EnterKeyHintType = "go" EnterKeyHintNext EnterKeyHintType = "next" EnterKeyHintPrevious EnterKeyHintType = "previous" EnterKeyHintSearch EnterKeyHintType = "search" EnterKeyHintSend EnterKeyHintType = "send" )
type FileInputProps ¶
type FileInputProps struct {
utils.BaseProps
Name string
Label string
Required bool
Disabled bool
Error string
HelpText string
Accept string // e.g. ".jpg,.png" or "image/*"
Multiple bool
}
FileInputProps configures a file input
func DefaultFileInputProps ¶
func DefaultFileInputProps() FileInputProps
DefaultFileInputProps returns sensible defaults
type FilterDropdownProps ¶ added in v0.17.0
type FilterDropdownProps struct {
utils.BaseProps
Name string
Label string
Options []SelectOption
// Value pre-selects the option whose Value matches. Use this to
// preserve the user's last filter selection across HTMX re-renders.
Value string
// HxGet is the server endpoint to fetch filtered results.
HxGet string
// HxTarget is the CSS selector for the element to swap results into.
HxTarget string
// HxSwap controls how the response is swapped (default: "innerHTML").
HxSwap string
// HxTrigger overrides the default "change" trigger. Use e.g.
// "change delay:500ms" for debounced filtering.
HxTrigger string
// HxInclude is a CSS selector or keyword (e.g. "closest form") to
// include additional form values in the request.
HxInclude string
// HxIndicator is a CSS selector for the element to show while loading.
HxIndicator string
// HelpText shows a small caption below the select.
HelpText string
// Action is the no-JS fallback the wired form submits to via GET. When
// Wire is set, the component wraps the select in a GET form with a
// <noscript> Apply button so browsers without JavaScript still apply the
// filter (with a full-page load). Ignored when Wire is unset.
Action string
// Wire, when set with a non-empty URL, owns the auto-submit wiring in
// both dialects and the legacy HxGet/HxTarget/HxSwap/HxTrigger fields are
// ignored (HxInclude/HxIndicator still render — they are htmx-dialect
// extras outside the wire common subset, ADR-0036). Defaults applied by
// the component: Event resolves to change and ContentType to form
// encoding, so the request carries the filter fields as query parameters
// via the wrapping form. Wire.Target renders for htmx only; Datastar
// targeting is response-driven — wrap the handler in wire.Handler. An
// empty Wire.URL wires nothing (plain HTMX select).
Wire *wire.Action
}
FilterDropdownProps configures a compact select dropdown purpose-built for HTMX filter bars. On change, it auto-submits a GET request to HxGet and swaps the results into HxTarget — no manual form wiring needed.
Typical use: a filter bar with status, date-range, and sort dropdowns. Each FilterDropdown independently triggers a server-side filter refresh via HTMX without a full page reload or a wrapping <form>.
func DefaultFilterDropdownProps ¶ added in v0.17.0
func DefaultFilterDropdownProps() FilterDropdownProps
DefaultFilterDropdownProps returns sensible defaults.
type FilterInputProps ¶ added in v1.14.0
type FilterInputProps struct {
utils.BaseProps
// Name is the field name submitted with the request (e.g. "q").
Name string
// Label shows a visible caption above the input. When empty, set
// AriaLabel so screen readers can still announce the field.
Label string
// Value pre-fills the input. Use this to preserve the query across
// server re-renders of the filter bar.
Value string
// Placeholder shows hint text inside the empty input.
Placeholder string
// HelpText shows a small caption below the input, linked via
// aria-describedby.
HelpText string
// Action is the no-JS fallback the form submits to via GET. When empty,
// the form has no action attribute (submits to the current URL).
Action string
// DebounceMS delays the wired request until typing pauses for this many
// milliseconds. Default 300 via DefaultFilterInputProps; 0 disables the
// debounce (a request fires on every keystroke). htmx renders it as the
// `input changed delay:<n>ms` trigger; Datastar as the
// `__debounce.<n>ms` event modifier (spelling decoded from the pinned
// v1.0.3 bundle — see docs/datastar-runtime-facts.md).
DebounceMS int
// Wire, when set with a non-empty URL, submits the input via the
// configured transport instead of a full page load (see the wire
// package, ADR-0036). Defaults applied by the component: Event resolves
// to input and ContentType to form encoding, so the request carries
// `?<Name>=<Value>` as a query parameter. Wire.Target renders for htmx
// only (hx-target); Datastar targeting is response-driven — wrap the
// handler in wire.Handler. An empty Wire.URL wires nothing.
Wire *wire.Action
}
FilterInputProps configures a debounced search/filter text input that auto-submits to a server endpoint as the user types — under either transport. It is the input sibling of FilterDropdown: purpose-built for filter bars, result tables, and live search regions.
The component always renders a `<search>` landmark containing a GET form, so a no-JS browser still submits natively and both runtimes serialize the field as a query parameter (the form encoding path — see docs/recipes/server-side-validation.md for the wire contract).
func DefaultFilterInputProps ¶ added in v1.14.0
func DefaultFilterInputProps() FilterInputProps
DefaultFilterInputProps returns sensible defaults (300ms debounce).
type FormEnctype ¶ added in v1.14.0
type FormEnctype string
FormEnctype is a typed enum for the form's enctype attribute — how field values are encoded in the POST body. Both runtimes honor it: htmx serializes natively per enctype, and the pinned Datastar bundle sends a FormData body exactly when enctype is multipart (see docs/datastar-runtime-facts.md).
const ( // FormEnctypeUrlencoded is the HTML default // (application/x-www-form-urlencoded). The zero value resolves here. FormEnctypeUrlencoded FormEnctype = "application/x-www-form-urlencoded" // FormEnctypeMultipart is multipart/form-data — required for file // uploads (input type=file). FormEnctypeMultipart FormEnctype = "multipart/form-data" )
type FormFieldProps ¶ added in v0.6.0
FormFieldProps configures the standard form field wrapper structure. Used by FormFieldWrapper to DRY up all form control components.
type FormLayout ¶ added in v0.19.0
type FormLayout string
FormLayout is a typed enum controlling the visual layout of a Form. Unknown values fall back to FormLayoutStack. See ADR-0016 for when to use each.
const ( // FormLayoutStack — vertical column with space-y-6 between fields. The // default; use for data-entry forms where each field gets its own row. FormLayoutStack FormLayout = "stack" // FormLayoutInline — horizontal flex-wrap row with gap-3. Use for filter // bars and toolbars where fields are short and should sit on one line. // Deprecated in favor of FormLayoutGrid when label alignment matters // across wrapped rows (flex-wrap misaligns labels). // // Width contract: fields size to their content, never to the form's // full width. This works because field wrappers are shrink-to-fit flex // items — do NOT wrap fields in `w-full` containers here, and prefer // short inputs (the w-full on the input element itself resolves to the // intrinsic width). Pinned by the browser guard // visualtest.TestFormLayoutInlineWidthContract. FormLayoutInline FormLayout = "inline" // FormLayoutGrid — horizontal grid with auto-sized label column and a // flexible value column. Use for settings forms and admin panels where // labels must stay aligned even when fields wrap. // Emits: grid grid-cols-1 sm:grid-cols-[auto_minmax(0,1fr)] items-start gap-x-4 gap-y-3 FormLayoutGrid FormLayout = "grid" // FormLayoutDefault is the canonical default (Stack). FormLayoutDefault FormLayout = FormLayoutStack )
type FormMethod ¶
type FormMethod string
FormMethod defines the HTTP method for a form. HTML forms only support GET and POST (per the HTML spec). For transport-agnostic requests using other verbs (PUT, DELETE, PATCH), keep Method as the no-JS fallback (typically FormPost) and set Wire:
forms.FormProps{
Method: forms.FormPost,
Wire: &wire.Action{Method: wire.MethodPut, URL: "/api/item/123"},
}
const ( FormGet FormMethod = "GET" FormPost FormMethod = "POST" )
type FormProps ¶
type FormProps struct {
utils.BaseProps
Action string
Method FormMethod
// Enctype selects the encoding of a POST body. Zero value (and unknown
// values) resolve to the HTML default, urlencoded; set
// FormEnctypeMultipart for file uploads. Under both transports the
// runtime honors it: htmx serializes natively, the pinned Datastar
// bundle sends a FormData body exactly when enctype is multipart.
Enctype FormEnctype
CSRFToken string
CSRFTokenName string // Hidden input name attribute; defaults to "csrf_token"
// Layout selects the visual layout: Stack (default), Inline (horizontal
// flex-wrap), or Grid (aligned label/value columns).
Layout FormLayout
// Validate, when true, adds hx-validate="true" for HTML5 constraint
// validation before HTMX submit.
Validate bool
// DirtyGuard opts this form into the unsaved-changes guard: render
// forms.DirtyGuard once on the page and the browser warns before
// leaving with unsaved changes in this form (see DirtyGuardProps).
DirtyGuard bool
// NoValidate renders the HTML novalidate attribute, disabling the
// browser's native constraint validation on submit. Symmetric across
// transports: under htmx it suppresses the built-in reportValidity UI;
// under Datastar it lifts the pinned bundle's form-encoding validation
// gate (the runtime only calls checkValidity when the form lacks
// novalidate), letting server-side validation own the error UX — see
// docs/recipes/server-side-validation.md. Pair with Validate
// (hx-validate="true") to keep htmx's pre-submit check while dropping
// the native tooltips.
NoValidate bool
// ContainerAware, when true, wraps the form in a @container div and swaps
// sm: breakpoint classes for @sm: so the Grid layout responds to the
// parent container's width, not the viewport. Useful when a form is placed
// inside a modal, drawer, sidebar, or other constrained layout. Default
// false (viewport breakpoints). See ADR-0018.
ContainerAware bool
// Wire, when set, submits the form via the configured transport instead
// of a full page load (see the wire package, ADR-0036). The form's fields
// serialize in both dialects: htmx natively (hx-post + hx-trigger
// "submit"), Datastar via {contentType: 'form'} on data-on:submit — a
// runtime capability verified against the pinned v1.0.3 bundle (HTML5
// validation gates the request, the submitter button's name/value is
// appended, enctype selects multipart for file uploads, GET carries the
// fields as query parameters).
//
// Field defaults: an unspecified Event resolves to submit, an unspecified
// ContentType resolves to form encoding (set ContentTypeJSON explicitly to
// submit Datastar signals instead — then no form fields travel). Method
// follows wire's zero-value contract (GET) — set MethodPost for mutating
// submissions, mirroring DefaultFormProps's native Method. Wire.URL
// replaces Action for the wired request; Action/Method stay as the no-JS
// fallback. Wire.Target renders only for htmx (hx-target); Datastar
// targeting is response-driven — wrap the handler in wire.Handler.
// An empty Wire.URL wires nothing (the form stays a plain HTML form).
Wire *wire.Action
}
FormProps configures a form wrapper
func DefaultFormProps ¶
func DefaultFormProps() FormProps
DefaultFormProps returns sensible defaults
type InputGroupProps ¶
type InputGroupProps struct {
utils.BaseProps
LeftAddon templ.Component
RightAddon templ.Component
}
InputGroupProps configures an input group with optional left/right addons
Use with Input, Select, or Textarea. When using an addon, add padding to the input so the content doesn't overlap:
- Left addon → add "ps-10" to input Class
- Right addon → add "pe-10" to input Class
- Both → add "ps-10 pe-10"
func DefaultInputGroupProps ¶
func DefaultInputGroupProps() InputGroupProps
DefaultInputGroupProps returns sensible defaults
type InputProps ¶
type InputProps struct {
utils.BaseProps
Type InputType
Name string
Value string
Placeholder string
Label string
Required bool
Disabled bool
ReadOnly bool
AutoFocus bool
MaxLength int
EnterKeyHint EnterKeyHintType
Error string
HelpText string
}
InputProps configures a text input. EnterKeyHint, when set, overrides the auto-derived mobile keyboard hint. Uses the same EnterKeyHintType enum as Textarea for a unified API across form components.
func DefaultInputProps ¶
func DefaultInputProps() InputProps
DefaultInputProps returns sensible defaults
type InputType ¶
type InputType string
InputType defines HTML input types
const ( InputText InputType = "text" InputEmail InputType = "email" InputPassword InputType = "password" InputNumber InputType = "number" InputTel InputType = "tel" InputURL InputType = "url" InputDate InputType = "date" InputTime InputType = "time" InputDatetime InputType = "datetime-local" InputSearch InputType = "search" InputHidden InputType = "hidden" )
type RadioGroupProps ¶
type RadioGroupProps struct {
utils.BaseProps
Name string
Label string // renders as <legend>
Options []RadioOption
Inline bool // horizontal layout
Error string // group-level error
HelpText string
Required bool
}
RadioGroupProps configures a group of radio buttons.
func DefaultRadioGroupProps ¶
func DefaultRadioGroupProps() RadioGroupProps
DefaultRadioGroupProps returns sensible defaults.
type RadioOption ¶
RadioOption represents a single option in a radio group.
type RadioProps ¶
type RadioProps struct {
utils.BaseProps
Name string
Value string
Label string
Checked bool
Required bool
Disabled bool
}
RadioProps configures a single radio button input.
func DefaultRadioProps ¶
func DefaultRadioProps() RadioProps
DefaultRadioProps returns sensible defaults.
type RatingProps ¶ added in v0.17.0
type RatingProps struct {
utils.BaseProps
Name string
Value int // current rating (0 = unrated)
Max int // maximum stars (default: 5)
Size RatingSize
ReadOnly bool // display-only mode (no inputs)
Required bool
Label string
HelpText string
}
RatingProps configures an interactive star rating component. Uses radio inputs under the hood for full keyboard accessibility.
func DefaultRatingProps ¶ added in v0.17.0
func DefaultRatingProps() RatingProps
DefaultRatingProps returns sensible defaults.
type RatingSize ¶ added in v0.17.0
type RatingSize string
RatingSize controls the visual size of rating stars.
const ( RatingSizeSM RatingSize = "sm" RatingSizeMD RatingSize = "md" // default RatingSizeLG RatingSize = "lg" )
type SelectGroup ¶ added in v0.15.0
type SelectGroup struct {
Label string
Options []SelectOption
}
SelectGroup represents an <optgroup> with a label and its options. When SelectProps.Groups is non-empty, options are rendered as optgroups instead of a flat list. Use this for logically grouping options (e.g. channels by category, cities by country).
type SelectOption ¶
SelectOption represents a single option in a select. If both Disabled and Selected are true, Selected is cleared because a disabled option cannot be meaningfully pre-selected by the user.
type SelectProps ¶
type SelectProps struct {
utils.BaseProps
Name string
Label string
Options []SelectOption
// Groups, when non-empty, renders <optgroup> elements instead of a flat
// Options list. Each group has its own label. Options is ignored when
// Groups is set.
Groups []SelectGroup
Required bool
Disabled bool
// Stylable, when true, opts into the modern customizable <select> API
// (appearance: base-select). Emits a <button><selectedcontent> structure
// inside the select for CSS styling. Non-supporting browsers ignore
// these elements — progressive enhancement, no breaking changes.
// Requires the .tc-select CSS from templates/app.css.
Stylable bool
Error string
HelpText string
}
SelectProps configures a select dropdown. Set Groups to render <optgroup> elements; Options is ignored when Groups is non-empty.
func DefaultSelectProps ¶
func DefaultSelectProps() SelectProps
DefaultSelectProps returns sensible defaults
type SliderProps ¶ added in v0.17.0
type SliderProps struct {
utils.BaseProps
Name string
Label string
Min float64
Max float64
Value float64
Step float64
Required bool
Disabled bool
HelpText string
Error string
// ShowValue displays the current value next to the label.
ShowValue bool
}
SliderProps configures a range input slider.
func DefaultSliderProps ¶ added in v0.17.0
func DefaultSliderProps() SliderProps
DefaultSliderProps returns sensible defaults.
type TagsInputProps ¶ added in v0.17.0
type TagsInputProps struct {
utils.BaseProps
Name string
Label string
Values []string
Placeholder string
MaxTags int // 0 = unlimited
AllowDuplicate bool // false by default
Required bool
Disabled bool
Error string
HelpText string
}
TagsInputProps configures a tag input where users can add and remove tags. Tags are rendered as removable badges. Values are submitted as repeated hidden inputs with the given Name, so the server receives []string.
func DefaultTagsInputProps ¶ added in v0.17.0
func DefaultTagsInputProps() TagsInputProps
DefaultTagsInputProps returns sensible defaults.
type TextareaProps ¶
type TextareaProps struct {
utils.BaseProps
Name string
Value string
Placeholder string
Label string
Rows int
Required bool
Disabled bool
ReadOnly bool
MaxLength int
AutoGrow bool
EnterKeyHint EnterKeyHintType
Error string
HelpText string
}
TextareaProps configures a textarea. AutoGrow (default true) uses the modern CSS field-sizing: content property to grow the textarea to fit its content without JavaScript. EnterKeyHint sets the mobile keyboard's Enter key label (e.g. "send" for chat, "done", "go", "next", "previous", "search").
func DefaultTextareaProps ¶
func DefaultTextareaProps() TextareaProps
DefaultTextareaProps returns sensible defaults
type ToggleProps ¶
type ToggleProps struct {
utils.BaseProps
Name string
Label string
Checked bool
Disabled bool
Required bool
Error string
HelpText string
Size ToggleSize
}
ToggleProps configures a toggle/switch input
func DefaultToggleProps ¶
func DefaultToggleProps() ToggleProps
DefaultToggleProps returns sensible defaults
type ToggleSize ¶
type ToggleSize string
ToggleSize defines the size of a toggle switch
const ( ToggleSizeSM ToggleSize = "sm" ToggleSizeMD ToggleSize = "md" ToggleSizeLG ToggleSize = "lg" )
type ValidationError ¶ added in v0.3.0
type ValidationError struct {
Field string // HTML element ID (e.g. "email", "user_name") — used as the anchor href target
Message string
}
FieldError represents a single field validation error
type ValidationSummaryProps ¶ added in v0.3.0
type ValidationSummaryProps struct {
utils.BaseProps
Errors []ValidationError
}
ValidationSummaryProps configures a form validation error summary
func DefaultValidationSummaryProps ¶ added in v0.3.0
func DefaultValidationSummaryProps() ValidationSummaryProps
DefaultValidationSummaryProps returns sensible defaults
Source Files
¶
- aria.go
- calendar_templ.go
- combobox_templ.go
- date_picker_templ.go
- dirty_guard_templ.go
- doc.go
- enums_go.go
- file_input_templ.go
- filter_dropdown_templ.go
- filter_input_templ.go
- form_templ.go
- ids.go
- input_classes.go
- input_group_templ.go
- input_templ.go
- label_templ.go
- radio.go
- radio_templ.go
- rating_templ.go
- select_templ.go
- slider_templ.go
- tags_input_templ.go
- textarea_templ.go
- toggle_templ.go
- validation_templ.go