Skip to content

Layout: justify/flex distribution for leftover space #58

Description

@ralyodio

Leftover space in a container has exactly one policy today: flexible children absorb it. There is no way to say "pack these to the end", "centre them", or "spread them evenly" without inserting spacers by hand.

Today

Constraint (packages/hqtui/src/layout.ts:20) carries size, min, max and intrinsic, and solve() distributes what is left over to fr/fill children. Anything else is manual: the demo's own status row does

r.badge({ text: "err", color: entry.danger, size: 6 });
r.spacer("fill");

to push content left, and the dashboard uses p.spacer("fill") to bottom-align a divider. That works, but it is layout state encoded as a sibling, and it does not survive someone reordering the children.

What ratatui does

Flex::{Legacy, Start, End, Center, SpaceBetween, SpaceEvenly, SpaceAround} on the layout, orthogonal to the constraints themselves.

https://docs.rs/ratatui/latest/ratatui/layout/enum.Flex.html

Proposal

Add justify to ContainerOptions:

ui.row({ justify: "space-between" }, r => { ... });

with "start" | "end" | "center" | "space-between" | "space-around" | "space-evenly", defaulting to "start" so every existing layout renders unchanged. It applies only when the children leave slack — a row containing any fr/fill child has none, so the option is inert there and costs nothing.

The whole change is inside solve() plus one option passed through Container. Existing spacer("fill") code keeps working.

Cost

Rendering behaviour, so it lands in all six ports (ports/{rust,go,python,zig,cpp} and the COBOL adapter) with regenerated conformance fixtures. The TypeScript side is small; the ports are the work. Default-start means the fixtures should regenerate byte for byte until someone opts in, which makes it a safe one to do early.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions