selectsearch

package
v0.6.4 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 9 Imported by: 0

README

SelectSearch

Signal-driven searchable dropdown with static options, live filtering, and optional DB search callback.

Features

  • Signal-driven open/close state using Show.
  • Live search filtering with BindChildren for surgical list updates.
  • Badge descriptions for options.
  • Callback for custom search (e.g., database).
  • Two-way bound search input with .Autofocus().
  • Accessible via labels and semantic HTML.

Usage

import "github.com/tinywasm/components/selectsearch"

ss := &selectsearch.SelectSearch{
    Placeholder: "Choose an option...",
    Options: []selectsearch.SsOption{
        {ID: "1", Label: "Option 1", Description: "First option"},
        {ID: "2", Label: "Option 2", Description: "Second option"},
    },
    OnSelect: func(id, description string) {
        fmt.Printf("Selected: %s\n", id)
    },
}

API

SelectSearch Struct
  • Placeholder string: Text shown when no option is selected.
  • Options []SsOption: Initial list of options.
  • OnSelect func(id, description string): Callback triggered when an option is selected.
  • OnSearch func(term string) []SsOption: Callback triggered when all local options are filtered out.
SsOption Struct
  • ID string: Unique identifier for the option.
  • Label string: Visible text for the option.
  • Description string: Optional secondary text (badge).

Filterable

SelectSearch implements widget.Filterable: picking an option calls the registered sink with the option's ID. This is in addition to OnSelect (which also gets Description) — a host that only needs the generic narrowing contract (e.g. tinywasm/layout/crudview's Filter slot) can drop a *SelectSearch in without any bespoke wiring, the same way it accepts a *searchbar.SearchBar today.

Documentation

Index

Constants

View Source
const (
	PartToggle      = widget.Part("toggle")
	PartBackdrop    = widget.Part("backdrop")
	PartDropdown    = widget.Part("dropdown")
	PartHeader      = widget.Part("header")
	PartHeaderBody  = widget.Part("header-body")
	PartPlaceholder = widget.Part("placeholder")
	PartIcon        = widget.Part("icon")
	PartGlyph       = widget.Part("glyph")
	PartSearch      = widget.Part("search")
	PartOptions     = widget.Part("options")
	PartOption      = widget.Part("option")
	PartText        = widget.Part("text")
	PartLabel       = widget.Part("label")
	PartSublabel    = widget.Part("sublabel")
	PartDesc        = widget.Part("desc")
)
View Source
const NameSelectSearch = widget.Name("selectsearch")

NameSelectSearch is the widget name.

Variables

View Source
var (
	ClsSsBox         = NameSelectSearch.Root()
	ClsSsToggle      = NameSelectSearch.Class(PartToggle)
	ClsSsBackdrop    = NameSelectSearch.Class(PartBackdrop)
	ClsSsDropdown    = NameSelectSearch.Class(PartDropdown)
	ClsSsHeader      = NameSelectSearch.Class(PartHeader)
	ClsSsHeaderBody  = NameSelectSearch.Class(PartHeaderBody)
	ClsSsPlaceholder = NameSelectSearch.Class(PartPlaceholder)
	ClsSsIcon        = NameSelectSearch.Class(PartIcon)
	ClsSsGlyph       = NameSelectSearch.Class(PartGlyph)
	ClsSsSearch      = NameSelectSearch.Class(PartSearch)
	ClsSsOptions     = NameSelectSearch.Class(PartOptions)
	ClsSsOption      = NameSelectSearch.Class(PartOption)
	ClsSsText        = NameSelectSearch.Class(PartText)
	ClsSsLabel       = NameSelectSearch.Class(PartLabel)
	ClsSsSublabel    = NameSelectSearch.Class(PartSublabel)
	ClsSsDesc        = NameSelectSearch.Class(PartDesc)
)

Functions

This section is empty.

Types

type SearchMode added in v0.6.0

type SearchMode uint8

SearchMode decides whether the picker shows its search field.

The field is not free: on a phone it summons the on-screen keyboard the instant the control opens, covering half the list the user came to read. That is a good trade when the list is long enough that scanning it is slower than typing, and a bad one when it holds five names.

const (
	// SearchAuto shows the field only when the list is long enough to be
	// worth filtering, or when an OnSearch source is wired — a consumer that
	// fetches results for a term has already declared the list is not
	// browsable, whatever len(Options) says at this instant.
	//
	// It is the zero value on purpose: it is the answer that is right without
	// the consumer having to think, and the one that is right for the case
	// that actually broke (a handful of patients, keyboard in the way).
	SearchAuto SearchMode = iota
	// SearchAlways keeps the field however short the list is.
	SearchAlways
	// SearchNever drops it however long the list is.
	SearchNever
)

type SelectSearch

type SelectSearch struct {
	Element                                  // value embed — NEVER pointer (TinyGo heap constraint)
	Placeholder string                       // text shown when nothing is selected
	Options     []SsOption                   // initial static options
	Search      SearchMode                   // whether the search field appears; zero value is SearchAuto
	OnSelect    func(id, description string) // called when user picks an option
	OnSearch    func(term string) []SsOption // called when ALL local options are filtered out
	// contains filtered or unexported fields
}

func (*SelectSearch) IconSvg

func (c *SelectSearch) IconSvg() *sprite.Sprite

func (*SelectSearch) Init added in v0.1.7

func (c *SelectSearch) Init(_ Ctx)

func (*SelectSearch) OnFilterChange added in v0.5.0

func (c *SelectSearch) OnFilterChange(fn func(term string))

OnFilterChange implements widget.Filterable: it registers the sink called with the picked option's ID whenever a selection is made. This is a SEPARATE, additive wiring path from OnSelect — OnSelect still gets (id, description) for a consumer that needs both; OnFilterChange exists so a host that only knows the generic Filterable contract (e.g. tinywasm/layout/crudview's Filter slot) can drop a *SelectSearch into the same seam a *searchbar.SearchBar fills today, with no bespoke glue.

The signature is fixed by widget.Filterable — do not add a parameter, do not return anything, do not add a companion getter (see searchbar.go's OnFilterChange for the same rule stated for SearchBar).

func (*SelectSearch) Render

func (c *SelectSearch) Render() *Element

func (*SelectSearch) RenderCSS

func (c *SelectSearch) RenderCSS() *css.Stylesheet

RenderCSS defines the selectsearch visual contract using the style DSL.

func (*SelectSearch) SetOptions added in v0.1.7

func (c *SelectSearch) SetOptions(options []SsOption)

SetOptions replaces the option list — safe to call after Init/Render, e.g. once options from an async source (fetch, MCP call) arrive. Preserves the current search query filter, if any.

func (*SelectSearch) WidgetKind added in v0.1.13

func (c *SelectSearch) WidgetKind() widget.Kind

func (*SelectSearch) WidgetName added in v0.1.13

func (c *SelectSearch) WidgetName() widget.Name

type SsOption added in v0.1.4

type SsOption struct {
	ID          string // unique identifier, returned in OnSelect
	Label       string // visible text
	Sublabel    string // optional second line under Label — position only, no assumed content
	Description string // optional badge shown on the right
}

SsOption represents a selectable item.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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