StatusBar#

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

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

Usage#

By convention the status bar reads as a quiet display strip — for interactive controls (buttons, a search box) use a Toolbar instead. Nothing enforces it, but the default 'chrome' surface and compact density are tuned for passive status. Segments add left-to-right; an add_spacer() (or side="right") splits the band into a left and a right cluster.

Text segments#

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

sb = bs.StatusBar(horizontal="stretch")
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("Errors: 0", icon="x-circle", side="right")   # right cluster
sb.add_text("Warnings: 2", icon="exclamation-triangle", side="right")
sb.add_text("UTF-8", side="right")
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#

Pass a widget class to add_widget() (with side= to choose the cluster) and the band builds it, or create any widget with parent=statusbar to add it to the left cluster. Useful for a slim progress indicator or a badge.

sb = bs.StatusBar(horizontal="stretch")
sb.add_text("Syncing", icon="arrow-repeat")
bs.ProgressBar(parent=sb, value=65)
sb.add_text("main", icon="git", side="right")
StatusBar with an inline progress bar — light theme StatusBar with an inline progress bar — dark theme

Clearing segments#

clear() removes every segment, resetting the band to empty — useful when you rebuild the status from scratch.

sb.clear()

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(horizontal="stretch", surface="card")
sb.add_text("Card surface", icon="layers")
sb.add_text("3 warnings", icon="exclamation-triangle", side="right")
sb.add_text("main", icon="git", side="right")
StatusBar with card surface — light theme StatusBar with card surface — dark theme

Pinning to a window#

Use horizontal="stretch" 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(horizontal="stretch", side="bottom")
    sb.add_text("Ready", icon="check-circle")
    sb.add_text("main", icon="git", side="right")

    with bs.Column(grow=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 — Column / Row parents use the layout kwargs below, grid-based parents use grid kwargs.

Column (vertical layout)

Used inside a Column, App, or any other container with a column layout. Children are arranged top-to-bottom, so horizontal aligns each child across the width and grow shares the vertical space. (vertical does not apply — the order of the children sets their top-to-bottom position.)

horizontal

Cross-axis placement of the widget: 'left', 'center', 'right', or 'stretch' to fill the available width.

grow

Claim and fill a share of the leftover vertical space (the layout direction). True or False.

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=.

Row (horizontal layout)

Used inside a Row or any other container with a row layout. Children are arranged left-to-right, so vertical aligns each child across the height and grow shares the horizontal space. (horizontal does not apply — the order of the children sets their left-to-right position.)

vertical

Cross-axis placement of the widget: 'top', 'center', 'bottom', or 'stretch' to fill the available height.

grow

Claim and fill a share of the leftover horizontal space (the layout direction). True or False.

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.

horizontal

Horizontal placement within the grid cell: 'left', 'center', 'right', or 'stretch' to fill the cell width.

vertical

Vertical placement within the grid cell: 'top', 'center', 'bottom', or 'stretch' to fill the cell height.

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#

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

AppShell — full application scaffold with a built-in status bar, toolbars, 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.Column(grow=True, horizontal_items="stretch", gap=16):
 5
 6        # ── Text segments + clusters ───────────────────────────────────────
 7        with bs.Column(gap=4):
 8            bs.Label("Segments and clusters", font="heading-sm")
 9            sb1 = bs.StatusBar(horizontal="stretch")
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.Column(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(horizontal="stretch")
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.Column(gap=4):
33            bs.Label("Embedded widget", font="heading-sm")
34            sb3 = bs.StatusBar(horizontal="stretch")
35            sb3.add_text("Syncing", icon="arrow-repeat")
36            sb3.add_widget(bs.ProgressBar, value=65)
37            sb3.add_text("main", icon="git", side="right")
38
39        # ── Surface ────────────────────────────────────────────────────────
40        with bs.Column(gap=4):
41            bs.Label("Card surface", font="heading-sm")
42            sb4 = bs.StatusBar(horizontal="stretch", surface="card")
43            sb4.add_text("Card surface", icon="layers")
44            sb4.add_text("3 warnings", icon="exclamation-triangle", side="right")
45
46app.run()