Skip to content

Tab bar

A row of editor tabs with optional controls at the start and end. ui.Tab.for_file(path) creates a tab with the file’s name, icon and path as id. dirty=True shows a dot that turns into the close button on hover, preview=True draws the name in italics, and status tints it with a git color. on_select(id) and on_close(id) receive the tab id.

ui.tab_bar · Category: Navigation · Full reference →

Tab barTab bar
  • For open documents in an editor, or any set of views the user opens and closes.
import pyzed as pz
from pyzed import ui
class Editor(pz.App):
def __init__(self):
self.open, self.active = ["main.py", "app.py"], "main.py"
def close(self, path):
i = self.open.index(path)
self.open.remove(path)
if self.active == path:
self.active = self.open[min(i, len(self.open) - 1)] if self.open else None
def view(self):
return ui.tab_bar([ui.Tab.for_file(p) for p in self.open], self.active,
on_select=lambda p: setattr(self, "active", p), on_close=self.close)
Tab bar: Active and inactiveTab bar: Active and inactive
Active and inactive
Code
pz.container(ui.tab_bar([ui.Tab.for_file("main.rs"), ui.Tab.for_file("app.rs")], "main.rs",
on_close=on_close), width=400)
Tab bar: dirty=TrueTab bar: dirty=True
dirty=True
Code
pz.container(ui.tab_bar([ui.Tab.for_file("main.rs"), ui.Tab.for_file("notes.md", dirty=True)], "main.rs",
on_close=on_close), width=400)
Tab bar: preview=TrueTab bar: preview=True
preview=True
Code
pz.container(ui.tab_bar([ui.Tab.for_file("README.md", preview=True)], "README.md", on_close=on_close), width=400)
Tab bar: status="modified"Tab bar: status="modified"
status="modified"
Code
pz.container(ui.tab_bar([ui.Tab.for_file("app.py", status="modified"),
ui.Tab.for_file("new.py", status="created")], "app.py", on_close=on_close), width=400)
Tab bar: Tab(icon=)Tab bar: Tab(icon=)
Tab(icon=)
Code
pz.container(ui.tab_bar([ui.Tab("home", "Home", icon="house"), ui.Tab("logs", "Logs", icon="scroll-text")],
"home", on_select=on_select), width=400)
Tab bar: start=, end=Tab bar: start=, end=
start=, end=
Code
pz.container(ui.tab_bar([ui.Tab.for_file("main.rs")], "main.rs", on_close=on_close,
start=[ui.icon_button("arrow-left", on_back, size="sm")],
end=[ui.icon_button("plus", on_new, size="sm")]), width=400)
Tab bar: ui.tab(dimmed=True)Tab bar: ui.tab(dimmed=True)
ui.tab(dimmed=True)
Code
pz.row([ui.tab(ui.Tab.for_file("main.rs"), active=True),
ui.tab(ui.Tab.for_file("app.rs"), active=False, dimmed=True)])

A middle click closes a tab, on_context(id) runs on a right click and on_new on a double click of the empty space.

Tab bar: pinned=TrueTab bar: pinned=True
pinned=True
Code
ui.tab_bar([ui.Tab("app", "app.py", icon="file", pinned=True), ui.Tab("ui", "ui.py", icon="file")],
"ui", on_close=on_close, on_context=on_context, on_new=on_new)

Tab bar has 7 events of its own, listed below. Like every widget it also has the 18 common events (click, double_click, right_click, mouse_enter, drag, key_down, resize…), attached with .on(...): see Events and Events of every component.

Event Of Handler gets When
on_select ui.tab_bar, ui.tab (tab_id) Callable that receives the chosen item.
on_close ui.tab_bar, ui.tab (tab_id) Message or callable sent when the X is pressed.
on_drag ui.tab_bar (tab_id) Called with the tab id when a tab starts being dragged.
on_drop ui.tab_bar (tab_id, event) Called with the tab id and the Event when the dragged tab is released: event.window_x/window_y (outside the window if it was dropped outside) and event.screen.
on_drag_over ui.tab_bar (index) While dragging is set: called with the insertion index under the pointer, or None when it leaves the bar.
on_context ui.tab_bar (tab_id) Called with the id of a tab that is right-clicked.
on_new ui.tab_bar () Sent on a double click of the empty space after the tabs.

Handler gets is what Pyzed passes to your callable: () means nothing. Any handler can also be a message (a value that is not callable), which goes to update().

The same events written three ways. Imperative: methods of the app change self. Declarative: the handlers produce messages and one update() decides. Functional: a pure function draws an immutable state and asks for changes with set_state(...). See Imperative, declarative and functional.

class Editor(pz.App):
def __init__(self):
self.open, self.active = ["main.py", "app.py"], "main.py"
self.untitled = 0
def close(self, path): # on_close: the id of the tab
i = self.open.index(path)
self.open.remove(path)
if self.active == path:
self.active = self.open[min(i, len(self.open) - 1)] if self.open else None
def new(self): # on_new: double click after the tabs
self.untitled += 1
self.open.append(f"untitled-{self.untitled}")
self.active = self.open[-1]
def view(self):
return ui.tab_bar([ui.Tab.for_file(p) for p in self.open], self.active,
on_select=lambda p: setattr(self, "active", p), on_close=self.close,
on_new=self.new, on_context=lambda p: print("menu for", p))
tab_bar(
tabs,
active,
*,
on_select=None,
on_close=None,
start=(),
end=(),
height=32,
on_drag=None,
on_drop=None,
on_drag_over=None,
dragging=None,
drop_index=None,
on_context=None,
on_new=None,
theme=None,
)

A row of tabs with optional controls at the start and end (navigation, split, +). The close button appears on the active tab and on hover. Tabs can be dragged to reorder them or out of the window: see Draggable tabs.

Property Default Description
tabs required List of Tab.
active required Id of the active tab.
start () Widgets at the start (left).
end () Widgets at the end (right).
height 32 Height.
dragging None Id of the tab being dragged (dims it and turns on on_drag_over).
drop_index None Draws the insertion mark before the tab at this index (len(tabs): after the last one).
theme None Theme to use instead of the current one (pyzed.theme.current()).

Events: on_select, on_close, on_drag, on_drop, on_drag_over, on_context, on_new (events).

Full reference →

@dataclass
class Tab(id, label, icon=None, icon_color=None, dirty=False, preview=False, status=None, pinned=False, tooltip=None)

A tab. Tab.for_file(path, **kwargs) creates it with the file’s name and icon.

Property Default Description
id required Stable identifier used to focus or scroll it with a Command.
label required Label text.
icon None Name of a Lucide icon (pyzed icons lists them).
icon_color None Icon color: a theme token or a hex color.
dirty False Unsaved changes (shows a dot).
preview False Preview tab (in italics).
status None Git status (tints the name).
pinned False Shows only the icon, has no close button and goes first in tab_bar.
tooltip None Text shown on hover (the full path…).

Full reference →

tab(item, *, active, on_select=None, on_close=None, height=32, dimmed=False, theme=None)

A single tab. You normally use tab_bar.

Property Default Description
item required The Tab.
active required Whether it is the active one.
height 32 Height.
dimmed False Mutes the label (the tab being dragged).
theme None Theme to use instead of the current one (pyzed.theme.current()).

Events: on_select, on_close (events).

Full reference →