StatusBar#

A horizontal band of passive status segments — counts, sync state, cursor position, a ready message. Segments are added left-to-right via add_text() and add_widget(); an add_spacer() (or side="right") splits the band into a left and a right cluster.

StatusBar at the bottom of an app window — light theme StatusBar at the bottom of an app window — dark theme

By convention the status bar reads as a quiet display strip — for interactive controls (buttons, a search box) use a CommandBar instead. Nothing enforces it, but the default 'chrome' surface and compact density are tuned for passive status.

Usage#

Text segments#

add_text() adds a text segment, optionally with an icon= and a font= token.

sb = bs.StatusBar(fill="x")
sb.add_text("Ready", icon="check-circle")
sb.add_text("Ln 12, Col 5", font="caption")

Left and right clusters#

Pass side="right" to push a segment to the right cluster (the first one inserts the flexible spacer automatically). Call add_spacer() explicitly to split the band at a chosen point.

sb.add_text("Ready", icon="check-circle")   # left
sb.add_text("UTF-8", side="right")           # right cluster
sb.add_text("main", icon="git", side="right")
StatusBar segments split into left and right clusters — light theme StatusBar segments split into left and right clusters — dark theme

Reactive segments#

Pass textsignal= to bind a segment to a Signal — the text follows the signal’s value and updates live as it changes, ideal for a running count or sync state.

issues = bs.Signal("0 issues")
sb.add_text(textsignal=issues, icon="exclamation-triangle")

issues.set("3 issues")   # the segment updates automatically

Embedding widgets#

Create any widget with parent=statusbar to add it to the left cluster, or pass a pre-parented widget to add_widget() (with side= to choose the cluster). Useful for a slim progress indicator or a badge.

sb = bs.StatusBar(fill="x")
sb.add_text("Syncing", icon="arrow-repeat")
bs.ProgressBar(parent=sb, value=65)
sb.add_text("main", icon="git", side="right")

Surface#

surface= sets the band’s background token — the default 'chrome' is a quiet, recessed band; 'card' lifts it from the page.

sb = bs.StatusBar(fill="x", surface="card")
sb.add_text("Card surface", icon="layers")
sb.add_text("3 warnings", icon="exclamation-triangle", side="right")
StatusBar with card surface — light theme StatusBar with card surface — dark theme

Pinning to a window#

Use fill="x" with side="bottom" to pin a status bar to the bottom of any App or Window.

with bs.App(title="My App", size=(800, 500)) as app:
    sb = bs.StatusBar(fill="x", side="bottom")
    sb.add_text("Ready", icon="check-circle")
    sb.add_text("main", icon="git", side="right")

    with bs.VStack(fill="both", expand=True, padding=16):
        bs.Label("Document", font="heading-lg")
app.run()

Status bar inside AppShell#

AppShell includes a built-in status band along the bottom. Access it via shell.statusbar and call the same add_* methods — the band appears on the first segment added.

with bs.AppShell(title="My App") as shell:
    shell.statusbar.add_text("Ready", icon="check-circle")
    shell.statusbar.add_text("2 unread", side="right")
    ...

Widget sizing#

All widgets accept self-placement kwargs via **kwargs. The parent container determines which options apply — stack-based parents use stack kwargs, grid-based parents use grid kwargs. Unrecognised keys are silently ignored.

Stack#

Used inside VStack, HStack, App, and other stack containers.

fill

Fill direction: 'x', 'y', 'both', or 'none'.

expand

Grow to consume extra space in the parent. True or False.

anchor

Alignment when the widget does not fill the available slot: 'n', 's', 'e', 'w', 'center', 'nw', etc.

margin

External spacing in pixels. Accepts an integer (equal on all sides), a 2-tuple (horizontal, vertical), or a 4-tuple (left, top, right, bottom).

margin_x

Horizontal external spacing (left and right). Accepts an integer or a 2-tuple (left, right) for asymmetric spacing. Overrides the horizontal component of margin=.

margin_y

Vertical external spacing (top and bottom). Accepts an integer or a 2-tuple (top, bottom) for asymmetric spacing. Overrides the vertical component of margin=.

Grid#

Used inside a Grid container.

row / column

Zero-based row and column indices.

rowspan / columnspan

Number of rows or columns to span.

sticky

Alignment and fill within the grid cell. Any combination of 'n', 's', 'e', 'w' — e.g. 'ew' stretches horizontally, 'nsew' fills the entire cell.

margin

External spacing in pixels. Accepts an integer, a 2-tuple (horizontal, vertical), or a 4-tuple (left, top, right, bottom).

margin_x

Horizontal external spacing. Accepts an integer or (left, right).

margin_y

Vertical external spacing. Accepts an integer or (top, bottom).

See also#

CommandBar — the interactive sibling for buttons and controls in the window chrome.

AppShell — full application scaffold with a built-in status bar, command bar, and sidebar.

API#

The complete reference for StatusBar lives on the Widgets API page. At a glance:

StatusBar

A horizontal status band of passive segments — counts, sync state, a ready message.

Full Example#

 1
 2with bs.App(title="StatusBar demo", minsize=(720, 360), padding=16) as app:
 3
 4    with bs.VStack(fill="both", expand=True, gap=16):
 5
 6        # ── Text segments + clusters ───────────────────────────────────────
 7        with bs.VStack(fill="x", gap=4):
 8            bs.Label("Segments and clusters", font="heading-sm")
 9            sb1 = bs.StatusBar(fill="x")
10            sb1.add_text("Ready", icon="check-circle")
11            sb1.add_text("Ln 12, Col 5", side="right")
12            sb1.add_text("UTF-8", side="right")
13            sb1.add_text("main", icon="git", side="right")
14
15        # ── Reactive (textsignal) ──────────────────────────────────────────
16        with bs.VStack(fill="x", gap=4):
17            bs.Label("Reactive (textsignal)", font="heading-sm")
18            issues = bs.Signal("0 issues")
19            seen = {"n": 0}
20
21            sb2 = bs.StatusBar(fill="x")
22            sb2.add_text(textsignal=issues, icon="exclamation-triangle")
23            sb2.add_text("Saved", icon="cloud-check", side="right")
24
25            def add_issue():
26                seen["n"] += 1
27                issues.set(f"{seen['n']} issues")
28
29            bs.Button("Add issue", icon="plus", on_click=add_issue)
30
31        # ── Embedded widget ────────────────────────────────────────────────
32        with bs.VStack(fill="x", gap=4):
33            bs.Label("Embedded widget", font="heading-sm")
34            sb3 = bs.StatusBar(fill="x")
35            sb3.add_text("Syncing", icon="arrow-repeat")
36            bs.ProgressBar(parent=sb3, value=65)
37            sb3.add_text("main", icon="git", side="right")
38
39        # ── Surface ────────────────────────────────────────────────────────
40        with bs.VStack(fill="x", gap=4):
41            bs.Label("Card surface", font="heading-sm")
42            sb4 = bs.StatusBar(fill="x", surface="card")
43            sb4.add_text("Card surface", icon="layers")
44            sb4.add_text("3 warnings", icon="exclamation-triangle", side="right")
45
46app.run()