Skip to content

Collapsible

Added in version 0.37

A container with a title that can be used to show (expand) or hide (collapse) content, either by clicking or focusing and pressing Enter.

  • Focusable
  • Container

Composing

You can add content to a Collapsible widget either by passing in children to the constructor, or with a context manager (with statement).

Here is an example of using the constructor to add content:

def compose(self) -> ComposeResult:
    yield Collapsible(Label("Hello, world."))

Here's how the to use it with the context manager:

def compose(self) -> ComposeResult:
    with Collapsible():
        yield Label("Hello, world.")

The second form is generally preferred, but the end result is the same.

Title

The default title "Toggle" can be customized by setting the title parameter of the constructor:

def compose(self) -> ComposeResult:
    with Collapsible(title="An interesting story."):
        yield Label("Interesting but verbose story.")

Initial State

The initial state of the Collapsible widget can be customized via the collapsed parameter of the constructor:

def compose(self) -> ComposeResult:
    with Collapsible(title="Contents 1", collapsed=False):
        yield Label("Hello, world.")

    with Collapsible(title="Contents 2", collapsed=True):  # Default.
        yield Label("Hello, world.")

Collapse/Expand Symbols

The symbols used to show the collapsed / expanded state can be customized by setting the parameters collapsed_symbol and expanded_symbol:

def compose(self) -> ComposeResult:
    with Collapsible(collapsed_symbol=">>>", expanded_symbol="v"):
        yield Label("Hello, world.")

Examples

The following example contains three Collapsibles in different states.

CollapsibleApp ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▼ Leto # Duke Leto I Atreides Head of House Atreides. ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▼ Jessica ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ Lady Jessica ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Bene Gesserit and concubine of Leto, and mother of Paul and Alia. ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▼ Paul ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁  Collapse All  E  Expand All 

CollapsibleApp ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▶ Leto ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▶ Jessica ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▶ Paul  C  Collapse All  E  Expand All 

CollapsibleApp ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▼ Leto # Duke Leto I Atreides Head of House Atreides. ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▼ Jessica ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ Lady Jessica ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Bene Gesserit and concubine of Leto, and mother of Paul and Alia. ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▶ Paul  C  Collapse All  E  Expand All 

from textual.app import App, ComposeResult
from textual.widgets import Collapsible, Footer, Label, Markdown

LETO = """\
# Duke Leto I Atreides

Head of House Atreides."""

JESSICA = """
# Lady Jessica

Bene Gesserit and concubine of Leto, and mother of Paul and Alia.
"""

PAUL = """
# Paul Atreides

Son of Leto and Jessica.
"""


class CollapsibleApp(App[None]):
    """An example of collapsible container."""

    BINDINGS = [
        ("c", "collapse_or_expand(True)", "Collapse All"),
        ("e", "collapse_or_expand(False)", "Expand All"),
    ]

    def compose(self) -> ComposeResult:
        """Compose app with collapsible containers."""
        yield Footer()
        with Collapsible(collapsed=False, title="Leto"):
            yield Label(LETO)
        yield Collapsible(Markdown(JESSICA), collapsed=False, title="Jessica")
        with Collapsible(collapsed=True, title="Paul"):
            yield Markdown(PAUL)

    def action_collapse_or_expand(self, collapse: bool) -> None:
        for child in self.walk_children(Collapsible):
            child.collapsed = collapse


if __name__ == "__main__":
    app = CollapsibleApp()
    app.run()

Setting Initial State

The example below shows nested Collapsible widgets and how to set their initial state.

CollapsibleApp ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▼ Toggle ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ▶ Toggle

from textual.app import App, ComposeResult
from textual.widgets import Collapsible, Label


class CollapsibleApp(App[None]):
    def compose(self) -> ComposeResult:
        with Collapsible(collapsed=False):
            with Collapsible():
                yield Label("Hello, world.")


if __name__ == "__main__":
    app = CollapsibleApp()
    app.run()

Custom Symbols

The following example shows Collapsible widgets with custom expand/collapse symbols.

CollapsibleApp ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ >>> Togglev Toggle Hello, world.

from textual.app import App, ComposeResult
from textual.containers import Horizontal
from textual.widgets import Collapsible, Label


class CollapsibleApp(App[None]):
    def compose(self) -> ComposeResult:
        with Horizontal():
            with Collapsible(
                collapsed_symbol=">>>",
                expanded_symbol="v",
            ):
                yield Label("Hello, world.")

            with Collapsible(
                collapsed_symbol=">>>",
                expanded_symbol="v",
                collapsed=False,
            ):
                yield Label("Hello, world.")


if __name__ == "__main__":
    app = CollapsibleApp()
    app.run()

Reactive Attributes

Name Type Default Description
collapsed bool True Controls the collapsed/expanded state of the widget.
title str "Toggle" Title of the collapsed/expanded contents.

Messages

Bindings

The collapsible widget defines the following binding on its title:

Key(s) Description
enter Toggle the collapsible.

Component Classes

This widget has no component classes.

textual.widgets.Collapsible class

def __init__(
    self,
    *children,
    title="Toggle",
    collapsed=True,
    collapsed_symbol="▶",
    expanded_symbol="▼",
    name=None,
    id=None,
    classes=None,
    disabled=False
):

Bases: Widget

A collapsible container.

Parameters
Parameter Default Description
*children
Widget
()

Contents that will be collapsed/expanded.

title
str
'Toggle'

Title of the collapsed/expanded contents.

collapsed
bool
True

Default status of the contents.

collapsed_symbol
str
'▶'

Collapsed symbol before the title.

expanded_symbol
str
'▼'

Expanded symbol before the title.

name
str | None
None

The name of the collapsible.

id
str | None
None

The ID of the collapsible in the DOM.

classes
str | None
None

The CSS classes of the collapsible.

disabled
bool
False

Whether the collapsible is disabled or not.

Collapsed class

Bases: Toggled

Event sent when the Collapsible widget is collapsed.

Can be handled using on_collapsible_collapsed in a subclass of Collapsible or in a parent widget in the DOM.

Expanded class

Bases: Toggled

Event sent when the Collapsible widget is expanded.

Can be handled using on_collapsible_expanded in a subclass of Collapsible or in a parent widget in the DOM.

Toggled class

def __init__(self, collapsible):

Bases: Message

Parent class subclassed by Collapsible messages.

Can be handled with on(Collapsible.Toggled) if you want to handle expansions and collapsed in the same way, or you can handle the specific events individually.

Parameters
Parameter Default Description
collapsible
Collapsible
required

The Collapsible widget that was toggled.

collapsible instance-attribute

collapsible: Collapsible = collapsible

The collapsible that was toggled.

control property

control: Collapsible

An alias for Toggled.collapsible.