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

Button

Six variants × seven sizes × any color, options-driven.

One button, configured by ButtonProps. State lives in the caller's widget.Clickable; every visual state below walks the theme's tokens and scale steps, so a custom theme restyles all of it. Pressing nudges the button 1dp down — the same tactile response on every variant; the pointer cursor signals interactivity. Anchor-style rendering (as-link) and RTL are "from the web": a Link-variant button IS the link here, and RTL layout is not yet supported by the 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 button

Usage

Go
var save widget.Clickable
if save.Clicked(gtx) { /* … */ }
lotusui.Button(th, &save, "Button", lotusui.ButtonProps{})

Secondary

The muted solid for auxiliary actions — quiet next to a Default.

Go
lotusui.Button(th, &b, "Secondary", lotusui.ButtonProps{Variant: lotusui.ButtonSecondary})

Destructive

The danger solid — Delete-class actions exclusively.

Go
lotusui.Button(th, &b, "Destructive", lotusui.ButtonProps{Variant: lotusui.ButtonDestructive})

Outline

Bordered with quiet ink; fills faintly on hover.

Go
lotusui.Button(th, &b, "Outline", lotusui.ButtonProps{Variant: lotusui.ButtonOutline})

Ghost

No chrome until hovered — toolbars, dense rows.

Go
lotusui.Button(th, &b, "Ghost", lotusui.ButtonProps{Variant: lotusui.ButtonGhost})

Icon

An empty label with IconStart renders an icon-only, square-padded button.

Go
lotusui.Button(th, &b, "", lotusui.ButtonProps{
	Variant: lotusui.ButtonOutline, IconStart: lotusui.IconSettings})

With icon

IconStart/IconEnd render beside the label, tinted with the button's own ink and sized to its text.

Go
lotusui.Button(th, &add, "Add item", lotusui.ButtonProps{IconStart: lotusui.IconAdd})
lotusui.Button(th, &next, "Continue", lotusui.ButtonProps{
	Variant: lotusui.ButtonOutline, IconEnd: lotusui.IconExpand})

Rounded

Rounded renders the pill form — full-round corners on any variant.

Go
lotusui.Button(th, &b, "Rounded", lotusui.ButtonProps{Rounded: true})

Loading

Loading disables input and shows a spinner over the label (width preserved); LoadingText swaps the label instead, spinner at the start.

Go
lotusui.Button(th, &save, "Save", lotusui.ButtonProps{Loading: saving})
lotusui.Button(th, &save, "Save", lotusui.ButtonProps{
	Loading: saving, LoadingText: "Saving…"})

Sizes

Seven presets on the shared Size scale — 2XS through 2XL, text and padding moving together.

Go
lotusui.Button(th, &btn, "2XS", lotusui.ButtonProps{Size: lotusui.Size2XS})
lotusui.Button(th, &btn, "2XL", lotusui.ButtonProps{Size: lotusui.Size2XL})

Color

Color re-colors any variant from a ColorScale — one anchor in, the whole interaction ladder out (.500 base, .600 hover, .700 pressed): a custom color can never fall out of step with its hover and pressed states.

Go
lotusui.Button(th, &go1, "Teal", lotusui.ButtonProps{Color: lotusui.Teal})
lotusui.Button(th, &go2, "Brand", lotusui.ButtonProps{Color: lotusui.ScaleFrom(brand)})

Scheme

Scheme wins over Color and the variant's role scheme: full manual control of every slot.

Go
soft := lotusui.Teal.SoftScheme()
lotusui.Button(th, &go1, "Go", lotusui.ButtonProps{Scheme: &soft})

Disabled

Disabled walks a brighter step of the button's own color scale — same hue, quieter chrome (Soft fills lift to Subtle; Color solids mute to .200 fill / .600 ink; outline/ghost/link ink softens) — and drops the pointer cursor, hover fill, and press nudge.

Go
lotusui.Button(th, &btn, "Disabled", lotusui.ButtonProps{Disabled: true})

Cursor

Buttons render the pointer cursor whenever they are enabled — interactivity is signalled by the cursor, the hover fill, and the press nudge together. Disabled buttons drop all three.

Group

There is no group component on purpose: HStack IS the group — buttons are widgets, so grouping is ordinary composition. (An attached, shared-border group is on the roadmap.)

Go
lotusui.HStack(th.Space.SM,
	lotusui.Button(th, &cancel, "Cancel", lotusui.ButtonProps{Variant: lotusui.ButtonOutline}),
	lotusui.Button(th, &save, "Save", lotusui.ButtonProps{}),
)

Keyboard focus

A focused button renders a 2dp ring in the theme's FocusRing token — focus is never signalled by color alone. FullWidth makes any button span the column; RightAligned anchors a dialog's button row to the right edge.

API

OptionTypeDescription
VariantButtonVariantButtonDefault (default), ButtonSecondary, ButtonDestructive, ButtonOutline, ButtonGhost, ButtonLink.
SizeSizeSize2XS … Size2XL, SizeMD default — the shared size presets.
ColorColorScaleRe-colors the variant from a scale; the interaction ladder derives from it.
Scheme*SchemeWins over Color: full manual slot control — e.g. Teal.SoftScheme().
IconStart / IconEndstringEmbedded icon names beside the label; empty label + IconStart = icon-only.
RoundedboolThe pill form — full-round corners.
LoadingboolSpinner over the label (width kept), input off.
LoadingTextstringReplaces the label while Loading, spinner at the start.
DisabledboolBrighter same-hue step of the button's scale; swallows clicks and drops the pointer cursor.

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