Skip to content

Div

A Div is a box that holds other elements and components, as HTML's <div> does. It has no content of its own: what it shows comes from its children, which it lays out, and from its style, which decorates the box around them.

  • children is a tuple of elements and components, laid out in order as flexbox items by default, or as grid items (see Choosing a layout model). A component among them runs and is replaced by the element it returns.
  • style sets how the Div lays its children out (direction, gap, alignment), how big it is, and what it draws: a border, padding and margin colors, and a content_color that fills its box. A Div with no border, padding, margin_color or content_color draws nothing, not even its background, so a plain one used only for layout leaves whatever lies beneath it visible.
  • on_input receives the input events whose target is the Div or anything inside it, since an event bubbles from its target up through every ancestor until a handler handles it.

Each card below is a Div holding two Texts, with its own selected state. The Texts have no handlers, so a click on either one bubbles up to the card's on_click, as a click on the border does, and the selected card merges in a heavier, brighter border.

CARD = col | border | border_lightrounded | border_color("slate", 500) | pad_x(1) | width(24)
SELECTED_CARD = border_heavy | border_color("sky", 400)


@component
def card(title: str, body: str) -> Div:
    is_selected, set_selected = use_state(False)

    def flip() -> None:
        set_selected(not is_selected)

    return Div(
        style=CARD | (SELECTED_CARD if is_selected else default),
        on_input=on_click(flip),
        children=(
            Text(style=text_color("sky", 300), content=title),
            Text(style=text_wrap_stable | text_color("slate", 300), content=body),
        ),
    )


@component
def root() -> Div:
    return Div(
        style=row | gap(2),
        children=(
            card("Inbox", "Messages waiting for a reply."),
            card("Drafts", "Messages you started and haven't sent."),
            card("Archive", "Everything else."),
        ),
    )

Three cards, the middle one selected

╭──────────────────────╮  ┏━━━━━━━━━━━━━━━━━━━━━━┓  ╭──────────────────────╮
│ Inbox                │  ┃ Drafts               ┃  │ Archive              │
│ Messages waiting for │  ┃ Messages you started ┃  │ Everything else.     │
│ a reply.             │  ┃ and haven't sent.    ┃  │                      │
╰──────────────────────╯  ┗━━━━━━━━━━━━━━━━━━━━━━┛  ╰──────────────────────╯

A handle names the Div for the scroll controls, which scroll it when it's a scroll container or scroll it into view, and for use_scroll.

API

counterweight.elements.Div dataclass

Div(
    *,
    style: Style = _DEFAULT_STYLE,
    children: tuple[Component | AnyElement, ...] = (),
    on_input: InputHandler | None = None,
    handle: ElementHandle | None = None,
)

A box that lays out its children, as a <div> is in HTML: in a flex row or column, or a grid, as its style's layout says.

style class-attribute instance-attribute

style: Style = _DEFAULT_STYLE

How the box is laid out and drawn, and how it lays out its children.

children class-attribute instance-attribute

children: tuple[Component | AnyElement, ...] = ()

The components and elements inside the box, in order.

on_input class-attribute instance-attribute

on_input: InputHandler | None = None

The handler for the input events that reach this element, as their target or as they bubble up from a descendant: key presses and pastes while it or a descendant is focused, and mouse events over the parts of it that are painted.

handle class-attribute instance-attribute

handle: ElementHandle | None = None

The element handle that names this element for controls such as ScrollTo, and for use_scroll.