Accordion
Stacked collapsible sections separated by dividers. Sections are (key, title, content) tuples or ui.AccordionSection objects (with icon and a header end widget). You own the open state: open is a set of keys, a {key: bool} dict or True, and on_toggle receives the key.
ui.accordion · Category: Lists and menus · Full reference →


rows = lambda *items: pz.column([ui.field(k, ui.switch(v, on_toggle)) for k, v in items], spacing=8)pz.container(ui.accordion([ ("editor", "Editor", rows(("Soft wrap", True), ("Minimap", False))), ("files", "Files", rows(("Autosave", True))), ("git", "Git", ui.muted("Collapsed sections only show their header.")),], open={"editor", "files"}, on_toggle=on_toggle, icons={"editor": "file-code", "files": "folder", "git": "git-branch"}), width=400)When to use
Section titled “When to use”- For long settings or property panels where users only need a few sections at a time.
- For a single collapsible block, use a Disclosure.
import pyzed as pzfrom pyzed import ui
class Settings(pz.App): def __init__(self): self.open = {"editor"}
def view(self): return ui.accordion( [("editor", "Editor", ui.muted("…")), ("files", "Files", ui.muted("…"))], open=self.open, on_toggle=lambda key: self.open.symmetric_difference_update({key}), )Variants
Section titled “Variants”Open sections
Section titled “Open sections”

Code
pz.container(ui.accordion([("a", "Editor", ui.muted("…")), ("b", "Files", ui.muted("…")), ("c", "Git", ui.muted("…"))], open=set(), on_toggle=on_toggle), width=320)

open={"a"}Code
pz.container(ui.accordion([("a", "Editor", ui.muted("Font, wrapping, minimap.")), ("b", "Files", ui.muted("…"))], open={"a"}, on_toggle=on_toggle), width=320)

open=TrueCode
pz.container(ui.accordion([("a", "Editor", ui.muted("Font, wrapping.")), ("b", "Files", ui.muted("Autosave."))], open=True, on_toggle=on_toggle), width=320)Content
Section titled “Content”

icons=Code
pz.container(ui.accordion([("e", "Editor", ui.muted("…")), ("g", "Git", ui.muted("…"))], open=set(), icons={"e": "file-code", "g": "git-branch"}, on_toggle=on_toggle), width=320)

AccordionSection(end=)Code
pz.container(ui.accordion([ui.AccordionSection("p", "Problems", ui.muted("…"), icon="circle-x", end=ui.count_badge(3, tint="error"))], open=set(), on_toggle=on_toggle), width=320)Events
Section titled “Events”Accordion has 1 event 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 | Handler gets | When |
|---|---|---|
on_toggle |
(key) |
Called with the key of the clicked header. |
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 Settings(pz.App): def __init__(self): self.open = {"editor"}
def toggle(self, key): # on_toggle: the key of the clicked header self.open ^= {key}
def view(self): return ui.accordion([("editor", "Editor", ui.muted("Font, tabs, wrapping")), ("files", "Files", ui.muted("Autosave, encoding"))], open=self.open, on_toggle=self.toggle)from dataclasses import dataclass
@dataclassclass Toggle: key: str
class Settings(pz.App): open = frozenset({"editor"})
def update(self, message): match message: case Toggle(key): self.open = self.open ^ {key}
def view(self): return ui.accordion([("editor", "Editor", ui.muted("…")), ("files", "Files", ui.muted("…"))], open=self.open, on_toggle=Toggle)from dataclasses import dataclass
@dataclass(frozen=True)class State: open: frozenset = frozenset({"editor"})
def view(state, set_state): return ui.accordion([("editor", "Editor", ui.muted("…")), ("files", "Files", ui.muted("…"))], open=state.open, on_toggle=lambda key: set_state(open=state.open ^ {key}))Properties and API
Section titled “Properties and API”ui.accordion
Section titled “ui.accordion”accordion( sections, *, open=(), on_toggle=None, icons=None, spacing=8, padding=(6, 12, 10, 12), theme=None,)Stacked collapsible sections separated by dividers, like the panels of a settings screen. Each header spans the whole width, so the content lines up with the rest of the panel. You own the open state: change it in on_toggle.
| Property | Default | Description |
|---|---|---|
sections |
required | ui.AccordionSection(key, title, content, icon=None, end=None) items (or (key, title, content) tuples). |
open |
() |
The set of open ids, a {id: bool} dict, or True for all. |
icons |
None |
{id: icon}: a Lucide icon for each header. |
spacing |
8 |
Space around the dividers between sections. |
padding |
(6, 12, 10, 12) |
Padding around the content of an open section. |
theme |
None |
Theme to use instead of the current one (pyzed.theme.current()). |
Events: on_toggle (events).
ui.AccordionSection
Section titled “ui.AccordionSection”class AccordionSectionOne section of ui.accordion: key, title, content and optional icon and header end widget.
| Property | Default | Description |
|---|---|---|
key |
required | Key that identifies the subscription (defaults to the message or the function). |
title |
required | Title. |
content |
required | Content: a Widget, a string or a number (converted to text). |
icon |
None |
Name of a Lucide icon (pyzed icons lists them). |
end |
None |
Widgets at the end (right). |