Skip to content

App Shells

These whole-screen layouts combine the techniques from the other pages. Each root fills the screen and is split with flexbox: fixed parts take a length or their content's size, and the part that fills takes fill(1). Splitting space shows the same splits with grid, and Choosing a layout model builds a whole shell both ways.

The header and footer take their content's height, and the body takes the rest.

@component
def header_body_footer() -> Div:
    return Div(
        style=col,
        children=[
            Text(style=border | border_heavy | text_justify_center, content="header: content height"),
            Text(style=fill(1) | border, content="body: fill(1)"),
            Text(style=text_bg("slate", 700), content=" footer: one row, no border"),
        ],
    )

Header, body and footer

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                  header: content height                  ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┌──────────────────────────────────────────────────────────┐
│body: fill(1)                                             │
│                                                          │
│                                                          │
│                                                          │
└──────────────────────────────────────────────────────────┘
 footer: one row, no border                                 

A row that fills the rest of a column holds the sidebar and the main pane, and the status bar takes one row below them.

@component
def sidebar_status() -> Div:
    return Div(
        style=col,
        children=[
            Div(
                style=row | fill(1),
                children=[
                    Text(style=length(20) | border, content="sidebar:\nlength(20)"),
                    Text(style=fill(1) | border, content="main: fill(1)"),
                ],
            ),
            Text(style=text_bg("slate", 700), content=" status bar: one row, no border"),
        ],
    )

Sidebar, main pane and status bar

┌──────────────────┐┌──────────────────────────────────────┐
│sidebar:          ││main: fill(1)                         │
│length(20)        ││                                      │
│                  ││                                      │
│                  ││                                      │
│                  ││                                      │
│                  ││                                      │
│                  ││                                      │
└──────────────────┘└──────────────────────────────────────┘
 status bar: one row, no border                             

Three panes

Fixed panes on both sides, and a middle column split 2:1 between two panes. border_collapse on both containers makes neighbors share their borders.

@component
def three_panes() -> Div:
    return Div(
        style=row | border_collapse,
        children=[
            Text(style=length(20) | border, content="files:\nlength(20)"),
            Div(
                style=col | fill(1) | border_collapse,
                children=[
                    Text(style=fill(2) | border, content="editor: fill(2)"),
                    Text(style=fill(1) | border, content="terminal: fill(1)"),
                ],
            ),
            Text(style=length(20) | border, content="outline:\nlength(20)"),
        ],
    )

Three panes

┌──────────────────┬────────────────────────────────────────┬──────────────────┐
│files:            │editor: fill(2)                         │outline:          │
│length(20)        │                                        │length(20)        │
│                  │                                        │                  │
│                  │                                        │                  │
│                  │                                        │                  │
│                  │                                        │                  │
│                  │                                        │                  │
│                  ├────────────────────────────────────────┤                  │
│                  │terminal: fill(1)                       │                  │
│                  │                                        │                  │
│                  │                                        │                  │
│                  │                                        │                  │
└──────────────────┴────────────────────────────────────────┴──────────────────┘

A dialog over the app

See A dialog centered over the app.