Select

A select dropdown with label, validation states, large lists, Alpine.js binding for dependent selects, and disabled/readonly modes.

Usage Example
@selectfield.Select(selectfield.Config{
    ID:    "os",
    Name:  "os",
    Label: "Operating System",
    Options: []selectfield.Option{
        {Value: "mac", Label: "Mac"},
        {Value: "windows", Label: "Windows"},
        {Value: "linux", Label: "Linux"},
    },
})

Error State

State: selectfield.StateError recolors the field and shows HelperText as an error.

Error: Please select an operating system
Error State
@selectfield.Select(selectfield.Config{
    ID:         "os-error",
    Name:       "os",
    Label:      "Operating System",
    State:      selectfield.StateError,
    HelperText: "Error: Please select an operating system",
    Options:    options,
})

Success State

State: selectfield.StateSuccess applies the success styling. Mark an Option Selected for the initial value.

Success State
@selectfield.Select(selectfield.Config{
    ID:    "os-success",
    Name:  "os",
    Label: "Operating System",
    State: selectfield.StateSuccess,
    Options: []selectfield.Option{
        {Value: "mac", Label: "Mac", Selected: true},
        {Value: "windows", Label: "Windows"},
    },
})

Large List

Selects handle long option lists (e.g. a country picker) with native scrolling.

Large List
@selectfield.Select(selectfield.Config{
    ID:           "country",
    Name:         "country",
    Label:        "Country",
    Autocomplete: "country",
    Options:      countryOptions(),
})

Dependent Selects (Alpine.js)

Bind Alpine.Model to share state; Alpine.BindDisabled keeps the second select disabled until the first has a value.

Dependent Selects (Alpine.js)
<div x-data="{ firstValue: '', secondValue: '' }">
    @selectfield.Select(selectfield.Config{ID: "modelName", Alpine: &selectfield.AlpineConfig{Model: "firstValue"}, Options: models})
    @selectfield.Select(selectfield.Config{ID: "year", Alpine: &selectfield.AlpineConfig{Model: "secondValue", BindDisabled: "!firstValue"}, Options: years})
</div>

Disabled

Disabled: true blocks interaction.

Disabled
@selectfield.Select(selectfield.Config{
    ID:       "os-disabled",
    Name:     "os",
    Label:    "Operating System",
    Disabled: true,
    Options:  options,
})

Readonly

Readonly: true keeps the selected value submittable but prevents the user from changing it.

Readonly
@selectfield.Select(selectfield.Config{
    ID:       "os-readonly",
    Name:     "os-readonly",
    Label:    "Operating System",
    Readonly: true,
    Options:  options,
})

Shell Mode

Set Shell: true when Select should provide trigger and dropdown chrome while custom templ children own the value. Use ValueExpr for the trigger text and dispatch select-close after a pick.

Shell Mode
<div x-data="{ access: 'Viewer' }">
    @selectfield.Select(selectfield.Config{
        ID:           "access-shell",
        Label:        "Access level",
        Shell:        true,
        TriggerLabel: "Role",
        ValueExpr:    "access",
    }) {
        <button type="button" x-on:click="access = 'Admin'; $dispatch('select-close')">Admin</button>
        <button type="button" x-on:click="access = 'Viewer'; $dispatch('select-close')">Viewer</button>
    }
</div>

API Reference

PropTypeDefaultDescription
IDstring""Unique id (seeds the trigger id <id>-trigger and option ids).
Namestring""Form field name.
Labelstring""Label above the select.
Placeholderstring""Placeholder option shown when nothing is selected.
Options[]OptionnilOptions (Value, Label, Selected).
StateStateStateDefaultValidation state: "" (default), "error", "success".
HelperTextstring""Text below the field, recolored by State.
DisabledboolfalseDisable the select.
ReadonlyboolfalseNon-editable but submittable.
Autocompletestring""HTML autocomplete attribute.
Alpine*AlpineConfignilClient-side Alpine bindings (Model, BindDisabled).
InputAttrstempl.AttributesnilArbitrary attributes on the select.
RootClassstring""Extra classes on the container.
ShellboolfalseRender only the trigger/dropdown shell and use child content as the dropdown body.
TriggerLeadingtempl.ComponentnilOptional component rendered before the trigger text, such as a swatch or icon.
ValueExprstring""Alpine expression used for shell-mode trigger text and aria-label.
TriggerLabelstring""Static label shown on the left side of a shell trigger, with ValueExpr rendered muted on the right.