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 →


ui.tab_bar( [ui.Tab.for_file("src/main.rs"), ui.Tab.for_file("src/app.rs", dirty=True, status="modified"), ui.Tab.for_file("README.md", preview=True)], "src/main.rs", on_select=on_select, on_close=on_close, start=[ui.icon_button("arrow-left", on_back, size="sm"), ui.icon_button("arrow-right", on_forward, size="sm")], end=[ui.icon_button("plus", on_new, size="sm"), ui.icon_button("columns-2", on_split, size="sm")],)When to use
Section titled “When to use”- For open documents in an editor, or any set of views the user opens and closes.
import pyzed as pzfrom 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)Variants
Section titled “Variants”

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)

dirty=TrueCode
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)

preview=TrueCode
pz.container(ui.tab_bar([ui.Tab.for_file("README.md", preview=True)], "README.md", on_close=on_close), width=400)

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(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)Controls
Section titled “Controls”

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)

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)])States and events
Section titled “States and events”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.


pinned=TrueCode
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)Events
Section titled “Events”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().
Handling the events
Section titled “Handling the events”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))from dataclasses import dataclass
@dataclassclass Activate: path: str
@dataclassclass Close: path: str
class Editor(pz.App): open, active = ["main.py", "app.py"], "main.py"
def update(self, message): match message: case Activate(path): self.active = path case Close(path): self.open = [p for p in self.open if p != path] self.active = self.open[0] 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=Activate, on_close=Close)from dataclasses import dataclass
@dataclass(frozen=True)class State: open: tuple = ("main.py", "app.py") active: str = "main.py"
def view(state, set_state): def close(path): rest = tuple(p for p in state.open if p != path) set_state(open=rest, active=state.active if state.active != path else (rest[0] if rest else "")) return ui.tab_bar([ui.Tab.for_file(p) for p in state.open], state.active, on_select=lambda p: set_state(active=p), on_close=close)Properties and API
Section titled “Properties and API”ui.tab_bar
Section titled “ui.tab_bar”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).
ui.Tab
Section titled “ui.Tab”@dataclassclass 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…). |
ui.tab
Section titled “ui.tab”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).