Skip to content

Elements ​

Every element an applet can draw, what it is for, and its props. Types covers how each SDK names things and the rules every element shares; the parent table says which element may hold which.

Types ​

Names, children and callbacks ​

Element types are lowercase and props are camelCase; the tables on this page use these names, and each SDK spells them in its own style. This helper builds a section that holds one row per message, a toggle row and a button:

tsx
const inbox = (messages: Message[]): Node => (
    <Section
        title="Inbox"
        className="dim-label"
    >
        {messages.map((m) => (
            <Row
                key={m.id}
                title={m.subject}
            />
        ))}
        <ToggleRow
            title="Do not disturb"
            active={quiet}
            onToggle={setQuiet}
        />
        <Button onClick={sync}>Sync now</Button>
    </Section>
);
python
def inbox(messages: list[Message]) -> W:
    return Section(
        [
            Row(
                key=m.id,
                title=m.subject,
            )
            for m in messages
        ],
        ToggleRow(
            title="Do not disturb",
            active=quiet,
            on_toggle=set_quiet,
        ),
        Button(
            "Sync now",
            on_click=sync,
        ),
        title="Inbox",
        class_name="dim-label",
    )
go
func inbox(messages []Message) sdk.Widget {
	rows := make([]sdk.Widget, 0, len(messages))
	for _, m := range messages {
		rows = append(rows, sdk.Row(sdk.RowProps{
			Key:   m.ID,
			Title: m.Subject,
		}))
	}
	return sdk.Section(
		sdk.SectionProps{
			Title:     "Inbox",
			ClassName: "dim-label",
		},
		rows,
		sdk.ToggleRow(sdk.ToggleRowProps{
			Title:    "Do not disturb",
			Active:   quiet,
			OnToggle: setQuiet,
		}),
		sdk.Button(sdk.ButtonProps{OnClick: sync}, "Sync now"),
	)
}
rust
fn inbox(messages: &[Message], quiet: bool) -> Widget<Msg> {
    section()
        .title("Inbox")
        .class_name(ClassName::DimLabel)
        .children(messages.iter().map(|m| {
            row()
                .key(m.id)
                .title(&m.subject)
        }))
        .child(
            toggle_row()
                .title("Do not disturb")
                .active(quiet)
                .on_toggle(Msg::SetQuiet),
        )
        .child(
            button()
                .text("Sync now")
                .on_click(|| Msg::Sync),
        )
        .into()
}
  • A child is an element or a list of elements. key keeps an element's identity when its list reorders.
  • Where an SDK takes text as a child, text in a label, indicator or button becomes its text, and text in any other element becomes a label.
  • An event prop takes a handler, called with the arguments its Type column shows, such as (active: boolean).
  • A prop left out takes its default. The Go SDK leaves out every zero field except the value of sliderrow and scale, so a number prop whose zero is a real value is a pointer: Width: sdk.Ptr(48), Level: sdk.Ptr(0.5).

Controlled inputs ​

A control shows the value your applet passes. Update that value in the callback; if you do not, the next render puts the old value back. The controlled props are togglerow.active, expanderrow.open, sliderrow.value, entry.value, entryrow.value, scale.value, switch.active, togglebutton.active, checkbutton.active, dropdown.selected and choicelist.selected.

Class names ​

className takes one style class from this list:

dim-label, caption, heading, title-1, title-2, title-3, title-4, numeric, accent, success, warning, error, flat, pill, circular, column, network-popover__rule, bluetooth-popover, network-popover.

Its type is ClassName in every SDK. addon, container, row, actionrow, togglerow, meterrow, expanderrow, end, start, sliderrow, entryrow, factlist and swatch take no className. There is no applet CSS.

Severity and tone ​

TypeValuesUsed by
Severityinfo, warning, errorindicator, notice
RowTonewarning, error, destructivethe tone of rows, sliderrow and entryrow, which drops destructive
Toneaccent, dim, success, warning, errordots, calendar events

A Tone is a named theme color, so it follows the light or dark theme. These and every other enum prop take one of the values their table lists, in the form the example above uses for className.

Text and values ​

  • Text props (titles, subtitles, labels, values, tooltips, counts, descriptions and placeholders) are plain text, never markup. The panel drops control characters and bidi overrides, folds whitespace into single spaces, trims the ends, and cuts the text at 256 characters with a trailing …. Text that ends up empty counts as absent. entry.value and entryrow.value keep their spaces and hold up to 4096 characters.
  • An icon is a themed icon name matching ^[A-Za-z0-9_.-]+$, such as network-wireless-symbolic, never a path. Any other value is dropped.
  • A prop of the wrong type, or an enum string its table does not list, is dropped as if absent.
  • An array prop with more than 64 items, at any depth, rejects the whole render. bars.values, bars.tooltips and sparkline.values may hold 366.
  • A parent with more than 200 children rejects the whole render.

Parent table ​

The root holds indicator and popover elements. The panel shows the first popover.

ParentChildren
rootindicator, popover
popoverat most one addon, and any body element
addonat most one of readout, switch, container, swatch
containerat most one body element
sectionbody elements
revealerbody elements
stackbody elements
boxbody elements
rowat most one of image, readout, spinner, drawn at its end
actionrowat most one of image, readout, spinner, drawn at its end, and at most one start
meterrowat most one of image, readout, spinner, drawn at its end
expanderrowat most one end and one start; drawer children: actionrow, togglerow, meterrow, sliderrow, expanderrow, factlist, choicelist, row
endat most one of image, readout, spinner, label, box, container
startat most one of image, button, readout, spinner, dots, swatch
sliderrowat most one start
entryrowat most one of image, spinner, button, drawn at its end
togglerownothing
anything elsenothing

Body elements are section, row, actionrow, togglerow, meterrow, expanderrow, sliderrow, entry, entryrow, placeholder, box, container, label, image, button, switch, scale, spinner, separator, factlist, choicelist, readout, notice, calendar, dots, dropdown, togglebutton, checkbutton, revealer, stack, rangebar, bars, sparkline and unsupported.

A section may sit in a popover, box, container, revealer or stack, but never anywhere under another section, however deep. A type the panel does not know becomes unsupported. A child the table does not list rejects the whole render.

Elements ​

indicator ​

The chip on the bar that shows your applet's state at a glance. A left click opens the popover.

tsx
<Indicator
    icon="mail-unread-symbolic"
    badge="3"
    tooltip="3 unread messages"
/>
python
Indicator(
    icon="mail-unread-symbolic",
    badge="3",
    tooltip="3 unread messages",
)
go
sdk.Indicator(sdk.IndicatorProps{
	Icon:    "mail-unread-symbolic",
	Badge:   "3",
	Tooltip: "3 unread messages",
})
rust
indicator()
    .icon("mail-unread-symbolic")
    .badge("3")
    .tooltip("3 unread messages")
PropTypeDefaultWhat it does
iconstringThe chip's icon
textstring, up to 32 characters shownA label beside the icon
tooltipstringText shown on hover
badgestring, up to 8 charactersA short count on the chip, such as 3; it takes the attention dot's place
overlaystringAn icon drawn over the corner of icon
dotCSS colorA dot in this color, such as #e01b24
severityinfo, warning, errorwarning and error color the icon and label; info looks like none
attentionbooleanfalseMarks the chip with a dot
noticebooleanfalseA rounded accent background behind the icon and label
classNameclassA style class from Class names
onPress(button: number)Called on a click other than the left one, with 2 for middle, 3 for right, or the button's code
onScroll(dx: number, dy: number)Called once per scroll step: dy is -1 up and 1 down, dx is -1 left and 1 right

popover ​

The card that opens from the indicator, with an optional header above its body. The body scrolls once it passes 60% of the monitor's height.

tsx
<Popover
    icon="mail-unread-symbolic"
    title="Mail"
    subtitle="3 unread"
>
    <Row
        title="Lunch with Maya"
        subtitle="Maya Lindqvist"
    />
</Popover>
python
Popover(
    Row(
        title="Lunch with Maya",
        subtitle="Maya Lindqvist",
    ),
    icon="mail-unread-symbolic",
    title="Mail",
    subtitle="3 unread",
)
go
sdk.Popover(
	sdk.PopoverProps{
		Icon:     "mail-unread-symbolic",
		Title:    "Mail",
		Subtitle: "3 unread",
	},
	sdk.Row(sdk.RowProps{
		Title:    "Lunch with Maya",
		Subtitle: "Maya Lindqvist",
	}),
)
rust
popover()
    .icon("mail-unread-symbolic")
    .title("Mail")
    .subtitle("3 unread")
    .child(
        row()
            .title("Lunch with Maya")
            .subtitle("Maya Lindqvist"),
    )
PropTypeDefaultWhat it does
titlestringThe header's title; without it the header is hidden
subtitlestringA line under the title
iconstringThe header's icon
sizeregular, wideregularThe card's width
classNameclassA style class from Class names

addon ​

One control in the popover header's end, such as a power switch or a large reading. It takes no props.

tsx
<Popover title="Wi-Fi">
    <Addon>
        <Switch
            active={on}
            onToggle={setOn}
        />
    </Addon>
</Popover>
python
Popover(
    Addon(
        Switch(
            active=on,
            on_toggle=set_on,
        )
    ),
    title="Wi-Fi",
)
go
sdk.Popover(
	sdk.PopoverProps{Title: "Wi-Fi"},
	sdk.Addon(
		sdk.AddonProps{},
		sdk.Switch(sdk.SwitchProps{
			Active:   on,
			OnToggle: setOn,
		}),
	),
)
rust
popover()
    .title("Wi-Fi")
    .child(
        addon().child(
            switch()
                .active(on)
                .on_toggle(Msg::SetOn),
        ),
    )

container ​

A box of a set size and color around one element, for a colored tile or a fixed width.

tsx
<Container
    width={48}
    height={48}
    background="blue"
    align="center"
>
    <Label text="21°" />
</Container>
python
Container(
    Label(text="21°"),
    width=48,
    height=48,
    background="blue",
    align="center",
)
go
sdk.Container(
	sdk.ContainerProps{
		Width:      sdk.Ptr(48),
		Height:     sdk.Ptr(48),
		Background: "blue",
		Align:      "center",
	},
	sdk.Label(sdk.LabelProps{Text: "21°"}),
)
rust
container()
    .width(Some(48))
    .height(Some(48))
    .background(Paint::Blue)
    .align(Align::Center)
    .child(label().text("21°"))
PropTypeDefaultWhat it does
widthnumber, -1..1024-1The width in pixels; -1 follows the child
heightnumber, -1..1024-1The height in pixels; -1 follows the child
backgroundred, orange, yellow, green, blue, purple, light, darkThe fill color
colorthe same values as backgroundThe color of the text inside
alignfill, start, end, center, baselinefillWhere the child sits inside the box

section ​

A titled group of elements, such as the networks in range.

tsx
<Section
    title="Inbox"
    count="3"
>
    <Row title="Lunch with Maya" />
</Section>
python
Section(
    Row(title="Lunch with Maya"),
    title="Inbox",
    count="3",
)
go
sdk.Section(
	sdk.SectionProps{
		Title: "Inbox",
		Count: "3",
	},
	sdk.Row(sdk.RowProps{Title: "Lunch with Maya"}),
)
rust
section()
    .title("Inbox")
    .count("3")
    .child(row().title("Lunch with Maya"))
PropTypeDefaultWhat it does
titlestringThe heading above the group
countstringShort text beside the title, such as 3
classNameclassA style class from Class names

row ​

A line of information that does nothing when clicked: an icon, a title, a subtitle and a value. actionrow, togglerow, meterrow and expanderrow take these props too.

tsx
<Row
    icon="network-wireless-symbolic"
    title="Lighthouse"
    value="5 GHz"
/>
python
Row(
    icon="network-wireless-symbolic",
    title="Lighthouse",
    value="5 GHz",
)
go
sdk.Row(sdk.RowProps{
	Icon:  "network-wireless-symbolic",
	Title: "Lighthouse",
	Value: "5 GHz",
})
rust
row()
    .icon("network-wireless-symbolic")
    .title("Lighthouse")
    .value("5 GHz")
PropTypeDefaultWhat it does
titlestringThe main text
subtitlestringA second line under the title
iconstringAn icon at the start
valuestringShort text at the end, such as 5 GHz
tooltipstringText shown on hover
tonewarning, error, destructivewarning and error color the icon, subtitle and value; destructive colors the title red
typographynumeric, monospacenumeric gives every digit the same width, so changing figures stay put; monospace sets the row in a fixed-width font
inactivebooleanfalseFades the row

actionrow ​

A row the user clicks to do something, such as Connect. It takes the row props and these:

tsx
<ActionRow
    icon="view-refresh-symbolic"
    title="Sync now"
    busy={syncing}
    onActivate={sync}
/>
python
ActionRow(
    icon="view-refresh-symbolic",
    title="Sync now",
    busy=syncing,
    on_activate=sync,
)
go
sdk.ActionRow(sdk.ActionRowProps{
	Icon:       "view-refresh-symbolic",
	Title:      "Sync now",
	Busy:       syncing,
	OnActivate: sync,
})
rust
action_row()
    .icon("view-refresh-symbolic")
    .title("Sync now")
    .busy(syncing)
    .on_activate(|| Msg::Sync)
PropTypeDefaultWhat it does
busybooleanfalseShows a spinner at the end in place of the value
inactivebooleanfalseFades the row and ignores clicks
onActivate()Called when the user clicks the row

togglerow ​

A row with a switch or a check box, for a setting the user turns on and off. It takes the row props and these:

tsx
<ToggleRow
    title="Do not disturb"
    active={quiet}
    onToggle={setQuiet}
/>
python
ToggleRow(
    title="Do not disturb",
    active=quiet,
    on_toggle=set_quiet,
)
go
sdk.ToggleRow(sdk.ToggleRowProps{
	Title:    "Do not disturb",
	Active:   quiet,
	OnToggle: setQuiet,
})
rust
toggle_row()
    .title("Do not disturb")
    .active(quiet)
    .on_toggle(Msg::SetQuiet)
PropTypeDefaultWhat it does
activebooleanfalseWhether the switch or check box is on
controlswitch, checkswitchDraws a switch or a check box
busybooleanfalseShows a spinner at the end in place of the value
inactivebooleanfalseFades the row and ignores input
onToggle(active: boolean)Called when the user flips it, with the new state

meterrow ​

A row with a level bar, such as disk use. It takes the row props and these:

tsx
<MeterRow
    icon="drive-harddisk-symbolic"
    title="Home"
    value="72%"
    level={0.72}
/>
python
MeterRow(
    icon="drive-harddisk-symbolic",
    title="Home",
    value="72%",
    level=0.72,
)
go
sdk.MeterRow(sdk.MeterRowProps{
	Icon:  "drive-harddisk-symbolic",
	Title: "Home",
	Value: "72%",
	Level: sdk.Ptr(0.72),
})
rust
meter_row()
    .icon("drive-harddisk-symbolic")
    .title("Home")
    .value("72%")
    .level(Some(0.72))
PropTypeDefaultWhat it does
levelnumber, 0..1How full the bar is; without it no bar is drawn
tonewarning, error, destructiveAlso colors the bar
busybooleanfalseShows a spinner at the end in place of the value

expanderrow ​

A row that opens a drawer of more rows below it, such as the details of one network. Opening one drawer closes the others in the popover. It takes the row props and these:

tsx
<ExpanderRow
    title="Lighthouse"
    subtitle="Connected"
    open={expanded}
    onToggle={setExpanded}
>
    <Row
        title="Signal"
        value="82%"
    />
</ExpanderRow>
python
ExpanderRow(
    Row(
        title="Signal",
        value="82%",
    ),
    title="Lighthouse",
    subtitle="Connected",
    open=expanded,
    on_toggle=set_expanded,
)
go
sdk.ExpanderRow(
	sdk.ExpanderRowProps{
		Title:    "Lighthouse",
		Subtitle: "Connected",
		Open:     expanded,
		OnToggle: setExpanded,
	},
	sdk.Row(sdk.RowProps{
		Title: "Signal",
		Value: "82%",
	}),
)
rust
expander_row()
    .title("Lighthouse")
    .subtitle("Connected")
    .open(expanded)
    .on_toggle(Msg::SetExpanded)
    .child(
        row()
            .title("Signal")
            .value("82%"),
    )
PropTypeDefaultWhat it does
openbooleanfalseWhether the drawer is open
titleLinesnumber, 1..41How many lines the title may wrap onto
tintbooleanfalsetone colors the whole head and the open card, not only its text
busybooleanfalseShows a spinner at the end of the head in place of the value
inactivebooleanfalseFades the head; the drawer still opens
onToggle(open: boolean)Called when the drawer opens or closes, with the new state, also when the panel closes it because another drawer opened

end ​

Puts one image, readout or spinner at the end of an expander row's head, such as a device's battery level. It has no props, and an empty end draws nothing.

tsx
<ExpanderRow
    icon="audio-headphones-symbolic"
    title="AirPods Pro"
>
    <End>
        <Readout
            value="80"
            unit="%"
        />
    </End>
</ExpanderRow>
python
ExpanderRow(
    End(
        Readout(
            value="80",
            unit="%",
        )
    ),
    icon="audio-headphones-symbolic",
    title="AirPods Pro",
)
go
sdk.ExpanderRow(
	sdk.ExpanderRowProps{
		Icon:  "audio-headphones-symbolic",
		Title: "AirPods Pro",
	},
	sdk.End(
		sdk.EndProps{},
		sdk.Readout(sdk.ReadoutProps{
			Value: "80",
			Unit:  "%",
		}),
	),
)
rust
expander_row()
    .icon("audio-headphones-symbolic")
    .title("AirPods Pro")
    .child(
        end().child(
            readout()
                .value("80")
                .unit("%"),
        ),
    )

start ​

Puts one control at the start of a row, such as a mute button beside a volume slider. In a slider row it sits left of the slider; in an action or expander row it takes the place of the icon. It has no props, and an empty start draws nothing.

tsx
<SliderRow
    title="Volume"
    value={volume}
    onChange={setVolume}
>
    <Start>
        <Button
            icon="audio-volume-high-symbolic"
            tooltip="Mute"
            onClick={toggleMute}
        />
    </Start>
</SliderRow>
python
SliderRow(
    Start(
        Button(
            icon="audio-volume-high-symbolic",
            tooltip="Mute",
            on_click=toggle_mute,
        )
    ),
    title="Volume",
    value=volume,
    on_change=set_volume,
)
go
sdk.SliderRow(
	sdk.SliderRowProps{
		Title:    "Volume",
		Value:    volume,
		OnChange: setVolume,
	},
	sdk.Start(
		sdk.StartProps{},
		sdk.Button(sdk.ButtonProps{
			Icon:    "audio-volume-high-symbolic",
			Tooltip: "Mute",
			OnClick: toggleMute,
		}),
	),
)
rust
slider_row()
    .title("Volume")
    .value(volume)
    .on_change(Msg::Volume)
    .child(
        start().child(
            button()
                .icon("audio-volume-high-symbolic")
                .tooltip("Mute")
                .on_click(|| Msg::ToggleMute),
        ),
    )

sliderrow ​

A row with a slider, for a level the user drags, such as volume or brightness. A start child adds a control to its left.

tsx
<SliderRow
    title="Brightness"
    value={brightness}
    onChange={setBrightness}
/>
python
SliderRow(
    title="Brightness",
    value=brightness,
    on_change=set_brightness,
)
go
sdk.SliderRow(sdk.SliderRowProps{
	Title:    "Brightness",
	Value:    brightness,
	OnChange: setBrightness,
})
rust
slider_row()
    .title("Brightness")
    .value(brightness)
    .on_change(Msg::Brightness)
PropTypeDefaultWhat it does
valuemin..maxminWhere the slider's knob sits
minnumber below max0The value at the slider's left end
maxnumber above min1The value at the slider's right end
stepnumber above 00.01How far one arrow key press moves the knob
titlestringNames the slider for screen readers; it is not drawn
subtitlestringA line of text under the slider
tooltipstringText shown on hover
tonewarning, error, destructiveColors the row to flag the level
inactivebooleanfalseFades the slider and stops it from moving
onMove(value: number)Called while the user drags, with the current value
onChange(value: number)Called once when a drag ends or a key moves the knob, with the new value

entry ​

A one-line text field, for a name, a search or a new item.

tsx
<Entry
    placeholder="Add a task"
    value={draft}
    onChange={setDraft}
    onSubmit={addTask}
/>
python
Entry(
    placeholder="Add a task",
    value=draft,
    on_change=set_draft,
    on_submit=add_task,
)
go
sdk.Entry(sdk.EntryProps{
	Placeholder: "Add a task",
	Value:       draft,
	OnChange:    setDraft,
	OnSubmit:    addTask,
})
rust
entry()
    .placeholder("Add a task")
    .value(draft)
    .on_change(Msg::Draft)
    .on_submit(Msg::AddTask)
PropTypeDefaultWhat it does
valuestring, up to 4096 characters, spaces kept""The text in the field
placeholderstringHint text shown while the field is empty
classNameclassA style class from Class names
onChange(value: string)Called on every edit, with the whole text
onSubmit(value: string)Called when the user presses Enter, with the whole text

entryrow ​

A text field drawn as a row, for a new item in a list: the height, padding and corners of the rows around it, on a filled background, its text lined up with their titles. An optional title sits above the text as a caption. One image, spinner or button child is drawn at its end, such as an inline Add button.

tsx
<EntryRow
    title="New task"
    placeholder="Add a task"
    value={draft}
    onChange={setDraft}
    onSubmit={addTask}
>
    <Button text="Add" onClick={addTask} />
</EntryRow>
python
EntryRow(
    Button(text="Add", on_click=add_task),
    title="New task",
    placeholder="Add a task",
    value=draft,
    on_change=set_draft,
    on_submit=add_task,
)
go
sdk.EntryRow(sdk.EntryRowProps{
	Title:       "New task",
	Placeholder: "Add a task",
	Value:       draft,
	OnChange:    setDraft,
	OnSubmit:    addTask,
}, sdk.Button(sdk.ButtonProps{Text: "Add", OnClick: addTaskNow}))
rust
entry_row()
    .title("New task")
    .placeholder("Add a task")
    .value(draft)
    .on_change(Msg::Draft)
    .on_submit(Msg::AddTask)
    .child(button().text("Add").on_click(|| Msg::AddTaskNow))
PropTypeDefaultWhat it does
valuestring, up to 4096 characters, spaces kept""The text in the field
titlestringA caption above the text
placeholderstringHint text shown while the field is empty
toneRowTonewarning or error tints the row and its caption; destructive is dropped
inactivebooleanfalseMakes the field and its end child insensitive
tooltipstringPlain text
onChange(value: string)Called on every edit, with the whole text
onSubmit(value: string)Called when the user presses Enter, with the whole text

placeholder ​

An empty state: an icon, a title and a line of explanation, centered, for a list with nothing in it.

tsx
<Placeholder
    icon="bluetooth-disabled-symbolic"
    title="No devices"
    description="Paired devices show up here"
/>
python
Placeholder(
    icon="bluetooth-disabled-symbolic",
    title="No devices",
    description="Paired devices show up here",
)
go
sdk.Placeholder(sdk.PlaceholderProps{
	Icon:        "bluetooth-disabled-symbolic",
	Title:       "No devices",
	Description: "Paired devices show up here",
})
rust
placeholder()
    .icon("bluetooth-disabled-symbolic")
    .title("No devices")
    .description("Paired devices show up here")
PropTypeDefaultWhat it does
iconstringAn icon above the title
titlestringThe main line, such as what is missing
descriptionstringA smaller line under the title
classNameclassA style class from Class names

box ​

Lays out its children in a row or a column, such as a set of buttons side by side.

tsx
<Box
    spacing={6}
    halign="center"
>
    <Button
        icon="media-skip-backward-symbolic"
        tooltip="Previous"
        onClick={previous}
    />
    <Button
        icon="media-playback-pause-symbolic"
        tooltip="Pause"
        onClick={pause}
    />
</Box>
python
Box(
    Button(
        icon="media-skip-backward-symbolic",
        tooltip="Previous",
        on_click=previous,
    ),
    Button(
        icon="media-playback-pause-symbolic",
        tooltip="Pause",
        on_click=pause,
    ),
    spacing=6,
    halign="center",
)
go
sdk.Box(
	sdk.BoxProps{
		Spacing: 6,
		Halign:  "center",
	},
	sdk.Button(sdk.ButtonProps{
		Icon:    "media-skip-backward-symbolic",
		Tooltip: "Previous",
		OnClick: previous,
	}),
	sdk.Button(sdk.ButtonProps{
		Icon:    "media-playback-pause-symbolic",
		Tooltip: "Pause",
		OnClick: pause,
	}),
)
rust
bx().spacing(6)
    .halign(Align::Center)
    .child(
        button()
            .icon("media-skip-backward-symbolic")
            .tooltip("Previous")
            .on_click(|| Msg::Previous),
    )
    .child(
        button()
            .icon("media-playback-pause-symbolic")
            .tooltip("Pause")
            .on_click(|| Msg::Pause),
    )
PropTypeDefaultWhat it does
orientationhorizontal, verticalhorizontalLines the children up side by side or one under another
spacing0..240Pixels between children
homogeneousbooleanfalseGives every child the same size
halignfill, start, end, center, baselinefillWhere the box sits across the width it is given
valignfill, start, end, center, baselinefillWhere the box sits across the height it is given
hexpandbooleanfalseTakes any spare width
vexpandbooleanfalseTakes any spare height
classNameclassA style class from Class names

label ​

A piece of plain text, such as a caption or a status line. Every label is about 48 characters wide at most.

tsx
<Label
    text="Last synced 5 minutes ago"
    className="dim-label"
    wrap
/>
python
Label(
    text="Last synced 5 minutes ago",
    class_name="dim-label",
    wrap=True,
)
go
sdk.Label(sdk.LabelProps{
	Text:      "Last synced 5 minutes ago",
	ClassName: "dim-label",
	Wrap:      true,
})
rust
label()
    .text("Last synced 5 minutes ago")
    .class_name(ClassName::DimLabel)
    .wrap(true)
PropTypeDefaultWhat it does
textstringThe words shown, never read as markup
wrapbooleanfalseBreaks long text onto more lines
lines0..80With wrap, the most lines shown before the text is cut with …; 0 shows every line
ellipsizenone, start, middle, endendWithout wrap, where text that does not fit is cut with …
xalign0..10.5Horizontal position of the text: 0 left, 0.5 centered, 1 right
classNameclassA style class from Class names

image ​

A themed icon on its own, such as a weather symbol. It shows an icon from the icon theme, never a file.

tsx
<Image
    icon="weather-clear-symbolic"
    pixelSize={32}
    tooltip="Clear sky"
/>
python
Image(
    icon="weather-clear-symbolic",
    pixel_size=32,
    tooltip="Clear sky",
)
go
sdk.Image(sdk.ImageProps{
	Icon:      "weather-clear-symbolic",
	PixelSize: sdk.Ptr(32),
	Tooltip:   "Clear sky",
})
rust
image()
    .icon("weather-clear-symbolic")
    .pixel_size(Some(32))
    .tooltip("Clear sky")
PropTypeDefaultWhat it does
iconstringThe icon name
pixelSize8..64the theme's sizeThe icon's size in pixels
tooltipstringText shown on hover, also read by screen readers
classNameclassA style class from Class names

swatch ​

A chip filled with one color, such as a preview of a color temperature.

tsx
<Addon>
    <Swatch
        color="#e0563f"
        size="large"
        tooltip="Night light color"
    />
</Addon>
python
Addon(
    Swatch(
        color="#e0563f",
        size="large",
        tooltip="Night light color",
    )
)
go
sdk.Addon(
	sdk.AddonProps{},
	sdk.Swatch(sdk.SwatchProps{
		Color:   "#e0563f",
		Size:    "large",
		Tooltip: "Night light color",
	}),
)
rust
addon().child(
    swatch()
        .color("#e0563f")
        .size(SwatchSize::Large)
        .tooltip("Night light color"),
)
PropTypeDefaultWhat it does
colorCSS color, up to 256 charactersThe fill, such as #e0563f, rgb(224 86 63) or orange. Without a color, or with one that does not parse, the chip is empty
sizeregular, largeregularlarge is the bigger chip for the popover header
tooltipstringText shown on hover

button ​

A push button with text, an icon or both, for a single action.

tsx
<Button
    icon="view-refresh-symbolic"
    tooltip="Refresh"
    onClick={refresh}
/>
python
Button(
    icon="view-refresh-symbolic",
    tooltip="Refresh",
    on_click=refresh,
)
go
sdk.Button(sdk.ButtonProps{
	Icon:    "view-refresh-symbolic",
	Tooltip: "Refresh",
	OnClick: refresh,
})
rust
button()
    .icon("view-refresh-symbolic")
    .tooltip("Refresh")
    .on_click(|| Msg::Refresh)
PropTypeDefaultWhat it does
textstringThe button's label
iconstringAn icon, before the text when both are set
tooltipstringtextText shown on hover, also read by screen readers; give an icon-only button one
sensitivebooleantruefalse grays the button out and ignores clicks
classNameclassA style class from Class names
onClick()Called when the user clicks the button

switch ​

An on and off switch on its own, such as one in the popover header. In a list, a togglerow gives the switch a title.

tsx
<Switch
    active={enabled}
    onToggle={setEnabled}
/>
python
Switch(
    active=enabled,
    on_toggle=set_enabled,
)
go
sdk.Switch(sdk.SwitchProps{
	Active:   enabled,
	OnToggle: setEnabled,
})
rust
switch()
    .active(enabled)
    .on_toggle(Msg::Enabled)
PropTypeDefaultWhat it does
activebooleanfalseWhether the switch is on
sensitivebooleantruefalse grays the switch out and ignores clicks
classNameclassA style class from Class names
onToggle(active: boolean)Called when the user flips the switch, with the new state

scale ​

A bare slider with no title or row around it. In a list, a sliderrow gives it a row.

tsx
<Scale
    value={opacity}
    min={0}
    max={100}
    step={5}
    onChange={setOpacity}
/>
python
Scale(
    value=opacity,
    min=0,
    max=100,
    step=5,
    on_change=set_opacity,
)
go
sdk.Scale(sdk.ScaleProps{
	Value:    opacity,
	Min:      0,
	Max:      100,
	Step:     5,
	OnChange: setOpacity,
})
rust
scale()
    .value(opacity)
    .min(0.0)
    .max(100.0)
    .step(5.0)
    .on_change(Msg::Opacity)
PropTypeDefaultWhat it does
valuenumber, clamped to min..max0Where the slider's knob sits
minnumber below max0The value at the slider's left end
maxnumber above min1The value at the slider's right end
stepnumber, 0 or more0How far one arrow key press moves the knob; 0 moves it a hundredth of the range
sensitivebooleantruefalse grays the slider out and ignores input
classNameclassA style class from Class names
onChange(value: number)Called each time the user moves the knob, with the new value

spinner ​

A spinning busy indicator, for work in progress.

tsx
<Spinner />
python
Spinner()
go
sdk.Spinner(sdk.SpinnerProps{})
rust
spinner()
PropTypeDefaultWhat it does
classNameclassA style class from Class names

factlist ​

A list of label and value pairs, such as a connection's details.

tsx
<FactList
    facts={[
        { label: "IP address", value: "192.168.1.24" },
        { label: "Signal", value: "Weak", warning: true },
    ]}
/>
python
FactList(
    facts=[
        {"label": "IP address", "value": "192.168.1.24"},
        {"label": "Signal", "value": "Weak", "warning": True},
    ]
)
go
sdk.FactList(sdk.FactListProps{Facts: []sdk.Fact{
	{
		Label: "IP address",
		Value: "192.168.1.24",
	},
	{
		Label:   "Signal",
		Value:   "Weak",
		Warning: true,
	},
}})
rust
fact_list().facts([
    Fact::new("IP address", "192.168.1.24"),
    Fact::new("Signal", "Weak").warning(true),
])
PropTypeDefaultWhat it does
factsarray of {label, value, warning?}, 0..64 itemsOne row per fact, the label at the start and the value at the end. warning colors that row as a warning

choicelist ​

A list of choices with a check mark on the selected one, for picking one option while seeing them all, such as a power profile.

tsx
<ChoiceList
    choices={[
        { label: "Balanced" },
        {
            label: "Power saver",
            detail: "Dims the screen and slows the processor",
        },
    ]}
    selected={profile}
    onSelect={setProfile}
/>
python
ChoiceList(
    choices=[
        {"label": "Balanced"},
        {
            "label": "Power saver",
            "detail": "Dims the screen and slows the processor",
        },
    ],
    selected=profile,
    on_select=set_profile,
)
go
sdk.ChoiceList(sdk.ChoiceListProps{
	Choices: []sdk.Choice{
		{Label: "Balanced"},
		{
			Label:  "Power saver",
			Detail: "Dims the screen and slows the processor",
		},
	},
	Selected: sdk.Ptr(profile),
	OnSelect: setProfile,
})
rust
choice_list()
    .choices([
        Choice::new("Balanced"),
        Choice::new("Power saver")
            .detail("Dims the screen and slows the processor"),
    ])
    .selected(Some(profile))
    .on_select(Msg::Profile)
PropTypeDefaultWhat it does
choicesarray of {label, detail?, icon?, warning?}, 0..64 itemsOne row per choice: label is its title, detail a line under it, icon an icon before it, and warning colors it as a warning
selectedindexWhich choice is checked; absent or out of range checks none
classNameclassA style class from Class names
onSelect(index: number)Called when the user picks a choice, with its index

readout ​

A large value with a smaller unit beside it, such as a temperature.

tsx
<Readout
    value="21"
    unit="°C"
/>
python
Readout(
    value="21",
    unit="°C",
)
go
sdk.Readout(sdk.ReadoutProps{
	Value: "21",
	Unit:  "°C",
})
rust
readout()
    .value("21")
    .unit("°C")
PropTypeDefaultWhat it does
valuestringThe number or word in large type
unitstringThe smaller text after it
classNameclassA style class from Class names

notice ​

A highlighted message, such as a warning the user should see first. With onActivate it becomes a button with a chevron.

tsx
<Notice
    icon="battery-caution-symbolic"
    title="Battery low"
    subtitle="12% left"
    severity="warning"
    onActivate={openPowerSettings}
/>
python
Notice(
    icon="battery-caution-symbolic",
    title="Battery low",
    subtitle="12% left",
    severity="warning",
    on_activate=open_power_settings,
)
go
sdk.Notice(sdk.NoticeProps{
	Icon:       "battery-caution-symbolic",
	Title:      "Battery low",
	Subtitle:   "12% left",
	Severity:   "warning",
	OnActivate: openPowerSettings,
})
rust
notice()
    .icon("battery-caution-symbolic")
    .title("Battery low")
    .subtitle("12% left")
    .severity(Severity::Warning)
    .on_activate(|| Msg::OpenPowerSettings)
PropTypeDefaultWhat it does
titlestringThe message
subtitlestringA smaller line under the title
iconstringAn icon before the text
severityinfo, warning, errorinfoColors the notice; info is the plain style
classNameclassA style class from Class names
onActivate()Makes the notice clickable, with a chevron, and is called when the user clicks it

calendar ​

A month grid the user pages through and picks a day from, with colored dots on the days that have events.

tsx
<Calendar
    year={year}
    month={month}
    today="2026-10-18"
    selected={day}
    events={[{ date: "2026-10-21", colors: ["accent"] }]}
    onMonth={showMonth}
    onSelect={setDay}
/>
python
Calendar(
    year=year,
    month=month,
    today="2026-10-18",
    selected=day,
    events=[{"date": "2026-10-21", "colors": ["accent"]}],
    on_month=show_month,
    on_select=set_day,
)
go
sdk.Calendar(sdk.CalendarProps{
	Year:     year,
	Month:    month,
	Today:    "2026-10-18",
	Selected: day,
	Events: []sdk.CalendarEvent{{
		Date:   "2026-10-21",
		Colors: []sdk.Tone{"accent"},
	}},
	OnMonth:  showMonth,
	OnSelect: setDay,
})
rust
calendar()
    .year(year)
    .month(month)
    .today("2026-10-18")
    .selected(day)
    .events([CalendarEvent::new("2026-10-21").color(Tone::Accent)])
    .on_month(Msg::Month)
    .on_select(Msg::Day)
PropTypeDefaultWhat it does
yearnumber, 1..9999With month, the month the grid shows
monthnumber, 1..12With year, the month the grid shows
todayYYYY-MM-DDThe day marked as today. The grid's today button pages to it and selects it
selectedYYYY-MM-DDThe highlighted day. Absent, no day is highlighted
eventsarray of {date, colors?}, first 3 tones shownMarks each date with colored dots
classNameclassA style class for the grid
onMonth(year: number, month: number)Called when the user pages to another month
onSelect(date: string)Called when the user picks a day, with it as YYYY-MM-DD

dots ​

A short row of colored dots, for a status at a glance, such as which of three devices are connected.

tsx
<Dots colors={["success", "error"]} />
python
Dots(
    colors=[
        "success",
        "error",
    ]
)
go
sdk.Dots(sdk.DotsProps{Colors: []sdk.Tone{"success", "error"}})
rust
dots().colors([Tone::Success, Tone::Error])
PropTypeDefaultWhat it does
colorsarray of accent, dim, success, warning, errorOne dot per tone, in order
maxnumber, 1..33The most dots shown; tones past it are not drawn
sizenumber, 2..164Dot diameter in pixels
uniformbooleanfalseDraws every dot in the faded text color instead of its tone
classNameclassA style class for the dots

A compact button that opens a list and shows the chosen option, for picking one of a few named choices.

tsx
<DropDown
    options={["Celsius", "Fahrenheit"]}
    selected={unit}
    onSelect={setUnit}
/>
python
DropDown(
    options=[
        "Celsius",
        "Fahrenheit",
    ],
    selected=unit,
    on_select=set_unit,
)
go
sdk.DropDown(sdk.DropDownProps{
	Options:  []string{"Celsius", "Fahrenheit"},
	Selected: sdk.Ptr(unit),
	OnSelect: setUnit,
})
rust
drop_down()
    .options(["Celsius", "Fahrenheit"])
    .selected(Some(unit))
    .on_select(Msg::Unit)
PropTypeDefaultWhat it does
optionsarray of stringThe choices in the list, in order
selectednumberThe index of the option shown on the button
classNameclassA style class for the button
onSelect(index: number)Called when the user picks an option, with its index

togglebutton ​

A button that stays pressed in until it is clicked again, for an on and off choice that reads better as a button than as a switch.

tsx
<ToggleButton
    label="Mute"
    active={muted}
    onToggle={setMuted}
/>
python
ToggleButton(
    label="Mute",
    active=muted,
    on_toggle=set_muted,
)
go
sdk.ToggleButton(sdk.ToggleButtonProps{
	Label:    "Mute",
	Active:   muted,
	OnToggle: setMuted,
})
rust
toggle_button()
    .label("Mute")
    .active(muted)
    .on_toggle(Msg::Mute)
PropTypeDefaultWhat it does
labelstringThe button's text, and its accessible name
iconstringA themed icon on the button; the accessible name when there is no label
activebooleanfalseWhether the button is pressed in
classNameclassA style class for the button
onToggle(active: boolean)Called when the user clicks the button, with the new state

checkbutton ​

A check box with a label, for an option the user ticks on or off.

tsx
<CheckButton
    label="Show seconds"
    active={seconds}
    onToggle={setSeconds}
/>
python
CheckButton(
    label="Show seconds",
    active=seconds,
    on_toggle=set_seconds,
)
go
sdk.CheckButton(sdk.CheckButtonProps{
	Label:    "Show seconds",
	Active:   seconds,
	OnToggle: setSeconds,
})
rust
check_button()
    .label("Show seconds")
    .active(seconds)
    .on_toggle(Msg::Seconds)
PropTypeDefaultWhat it does
labelstringThe text beside the box, and its accessible name
activebooleanfalseWhether the box is ticked
classNameclassA style class for the check box
onToggle(active: boolean)Called when the user ticks or clears the box, with the new state

revealer ​

Shows or hides its children with an animation, for content that appears on demand, such as extra details under a row.

tsx
<Revealer revealed={details}>
    <Row
        title="Channel"
        value="36"
    />
</Revealer>
python
Revealer(
    Row(
        title="Channel",
        value="36",
    ),
    revealed=details,
)
go
sdk.Revealer(
	sdk.RevealerProps{Revealed: details},
	sdk.Row(sdk.RowProps{
		Title: "Channel",
		Value: "36",
	}),
)
rust
revealer()
    .revealed(details)
    .child(
        row()
            .title("Channel")
            .value("36"),
    )
PropTypeDefaultWhat it does
revealedbooleanfalseWhether the children are shown
transitionslide-down, crossfade, noneslide-downThe animation that shows and hides them
classNameclassA style class for the revealer

stack ​

Holds several children and shows one at a time, for switching between views in the same space.

tsx
<Stack visible={page}>
    <Label text="Today" />
    <Label text="This week" />
</Stack>
python
Stack(
    Label(text="Today"),
    Label(text="This week"),
    visible=page,
)
go
sdk.Stack(sdk.StackProps{Visible: page},
	sdk.Label(sdk.LabelProps{Text: "Today"}),
	sdk.Label(sdk.LabelProps{Text: "This week"}),
)
rust
stack()
    .visible(page)
    .child(label().text("Today"))
    .child(label().text("This week"))
PropTypeDefaultWhat it does
visiblenumber0The index of the child shown. An index with no child keeps the current one
classNameclassA style class for the stack

rangebar ​

A bar that marks a span on a scale, with an optional marker for the current value, such as today's low and high temperature and the temperature now.

tsx
<RangeBar
    min={-5}
    max={25}
    low={8}
    high={17}
    now={12}
/>
python
RangeBar(
    min=-5,
    max=25,
    low=8,
    high=17,
    now=12,
)
go
sdk.RangeBar(sdk.RangeBarProps{
	Min:  -5,
	Max:  25,
	Low:  8,
	High: 17,
	Now:  sdk.Ptr(12.0),
})
rust
range_bar()
    .min(-5.0)
    .max(25.0)
    .low(8.0)
    .high(17.0)
    .now(Some(12.0))
PropTypeDefaultWhat it does
minnumber0The value at the start of the scale
maxnumber above min, else the scale is 0..11The value at the end of the scale
lownumber0, clamped to min..maxWhere the marked span starts
highnumber0, clamped to low..maxWhere the marked span ends
nownumber, min..maxDraws a marker at this value
classNameclassA style class for the bar

bars ​

A small bar chart, for a history of amounts, such as data used per day.

tsx
<Bars
    values={usage}
    label="Data used per day"
/>
python
Bars(
    values=usage,
    label="Data used per day",
)
go
sdk.Bars(sdk.BarsProps{
	Values: usage,
	Label:  "Data used per day",
})
rust
bars()
    .values(usage)
    .label("Data used per day")
PropTypeDefaultWhat it does
valuesarray of number or null, up to 366One bar per value. A null or negative value draws a faint tick. When there are more values than pixels, neighbors merge into one bar showing their largest
tooltipsarray of string or null, up to 366The hover text of the bar at the same index
maximumnumber, above 0the largest valueThe value a full-height bar stands for
highlightLastbooleantrueDims every bar but the last
labelstringThe chart's accessible name
classNameclassA style class for the chart

sparkline ​

A small line chart, for a trend over time, such as processor load.

tsx
<Sparkline
    values={load}
    fill
    showLast
    label="Processor load"
/>
python
Sparkline(
    values=load,
    fill=True,
    show_last=True,
    label="Processor load",
)
go
sdk.Sparkline(sdk.SparklineProps{
	Values:   load,
	Fill:     true,
	ShowLast: true,
	Label:    "Processor load",
})
rust
sparkline()
    .values(load)
    .fill(true)
    .show_last(true)
    .label("Processor load")
PropTypeDefaultWhat it does
valuesarray of number or null, up to 366The points of the line, scaled from the lowest to the highest value. A null leaves a gap; a value alone between gaps is a dot
fillbooleanfalseShades the area under the line
showLastbooleanfalsePuts a dot on the last value
labelstringThe chart's accessible name
classNameclassA style class for the chart

separator ​

A thin line between groups of content.

tsx
<Separator />
python
Separator()
go
sdk.Separator(sdk.SeparatorProps{})
rust
separator()
PropTypeDefaultWhat it does
orientationhorizontal, verticalhorizontalThe direction of the line
classNameclassA style class for the line

unsupported ​

What the panel draws for a type it does not know: a faded row with a warning icon, titled "Unsupported:" and the type name cut to 64 characters, and the subtitle "This applet asked for an element glimpse does not render". The SDKs have no builder for it, and it takes no props.

Released under the BSD 3-Clause license.