Tabs
Three variants and an explicit Update contract.
Tab labels in a row; the active one styled by variant. Update must run
before anything reads the selection in the same frame — Layout deliberately does NOT process
clicks, so a consumer that forgets Update gets dead tabs (impossible to miss) instead of subtle
one-frame lag (which survives review).
Like every choice component, the selection is a VALUE: the cursor is
unexported, Value()/SetValue() read and write it, the zero value picks
the first option, and an unknown value clears rather than falling back to option 0 — see
Select for the full contract.
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 get github.com/ikaito-com/lotusui
# or vendor the source into your app:
go run github.com/ikaito-com/lotusui/cmd/lotusui add tabs
Usage
The default look: the strip sits in a muted rounded well and the active tab is a raised panel inside it.
tabs := lotusui.Tabs{Options: lotusui.TabOpts("Account", "Password")}
tabs.Update(gtx) // BEFORE anything reads the selection
body := accountBody
if tabs.Value() == "Password" {
body = passwordBody
}
tabs.Layout(th, gtx)
Line variant
TabsLine is the classic underline strip: quiet labels, a 2dp
brand-ink bar under the active tab, hover pre-shadowed.
tabs := lotusui.Tabs{Variant: lotusui.TabsLine}
Subtle variant
TabsSubtle renders pill-styled labels without the well — the quietest strip.
tabs := lotusui.Tabs{Variant: lotusui.TabsSubtle}
Vertical
Vertical stacks the strip as a column — pair it with your content beside it.
tabs := lotusui.Tabs{Vertical: true}
Icons
Each option's Icon renders before its label, in the tab's own ink.
tabs := lotusui.Tabs{Options: []lotusui.TabOption{
{Label: "Files", Icon: lotusui.IconFile},
{Label: "Changes", Icon: lotusui.IconChanges},
{Label: "Settings", Icon: lotusui.IconSettings},
}}
Disabled tab
A disabled option dims, drops the pointer cursor, and its clicks are skipped by Update.
tabs := lotusui.Tabs{Options: []lotusui.TabOption{
{Label: "Overview"},
{Label: "Archived", Disabled: true},
{Label: "Settings"},
}}
API
| Option | Type | Description |
|---|---|---|
Options | []TabOption | The tabs: Label, Value, Icon and Disabled. TabOpts("a","b") builds label-only strips. |
Update(gtx) | method | Processes clicks. MUST run before anything reads the selection in a frame — Layout never processes clicks. |
Value() / SetValue(v) | string | The selected tab's value; SetValue with an unknown value clears. |
Clear() / Chosen() | method | Leave nothing selected; whether a tab is selected. |
Variant | TabsVariant | TabsDefault (muted well, raised active tab), TabsLine (underline strip), TabsSubtle (pill-styled). |
Vertical | bool | Stacks the strip as a column. |