lotusui the ikaito design language for Gio — desktop, mobile, web
GitHub

Select

Trigger + chevron, a floating panel of options, check-marked selection.

A bordered trigger showing the current choice; clicking it opens a floating panel over the content beneath — built on the shared portal primitive (Floating), so it escapes any parent clipping, paints above everything, and wins the pointer. Picking an option, pressing anywhere else, or Escape closes it; the panel opens aligned to the current selection. Web-specific composition (SelectTrigger/SelectValue sub-components) and RTL are "from the web": Go structs replace composition, and RTL layout is not yet supported by the underlying toolkit.

Installation

Use the module import (the default), or own the source: lotusui add vendors the component into your app and lotusui update keeps the copy mergeable — see Registry.

Go
go get github.com/ikaito-com/lotusui

# or vendor the source into your app:
go run github.com/ikaito-com/lotusui/cmd/lotusui add select

Usage

Start with Selected: -1 and a Placeholder — the trigger shows it in muted ink until the user picks. Open the demo's panel: it floats over whatever is beneath.

Go
fruit := lotusui.Select{
	Options:     []string{"Apple", "Banana", "Blueberry", "Grapes", "Pineapple"},
	Selected:    -1,
	Placeholder: "Select a fruit",
}
fruit.Layout(th, gtx, "Fruit")

Align item with trigger

AlignItemWithTrigger overlays the open panel so the SELECTED row sits directly over the trigger — the native-select feel — instead of dropping below. Long lists still scroll; the alignment accounts for scrolled-away rows.

Go
font := lotusui.Select{Options: fonts, Selected: 3, AlignItemWithTrigger: true}

Groups

Groups renders options under muted labels with separators between groups. Selected indexes the flattened option list, in order.

Go
produce := lotusui.Select{
	Groups: []lotusui.SelectGroup{
		{Label: "Fruits", Options: []string{"Apple", "Banana", "Cherry"}},
		{Label: "Vegetables", Options: []string{"Carrot", "Leek", "Spinach"}},
	},
	Selected: -1, Placeholder: "Pick a produce…",
}

Scrollable

The panel caps at seven rows; longer lists scroll inside it, and the panel opens scrolled to the current selection — the align-with-trigger behavior, transposed.

Go
tz := lotusui.Select{Options: timezones, Selected: 10}

Disabled

Freezes the control on its current choice — identity fields that cannot change after creation.

Go
engine.Disabled = true

Invalid

Danger chrome on the trigger — pair it with a Field error message.

Go
size.Invalid = true

Sizes

All seven shared Size presets on the trigger frame.

Go
sel.Size = lotusui.Size2XS // … through lotusui.Size2XL

API

OptionTypeDescription
Options[]stringThe choices, rendered as check-markable rows in the floating panel.
Groups[]SelectGroupWins over Options: options under muted labels, separators between groups; Selected indexes the flattened list.
SizeSizeThe shared size presets for the trigger frame.
SelectedintIndex of the current choice; -1 = nothing chosen yet (shows Placeholder).
PlaceholderstringShown in muted ink while Selected is out of range.
AlignItemWithTriggerboolOpen the panel with the selected row over the trigger.
InvalidboolDanger chrome on the trigger.
DisabledboolFreezes the control: no pointer cursor, no opening, dimmed value.

Every demo on this site is the real Go component compiled to WebAssembly — one gallery app, one bundle, addressed by URL hash.