Proposal: Introducing Flexbox to Rich #1287
-
WhatFlex provides us with a powerful method of widget layout. We can use it to space items out with equal space between them, equal space around them, center the items on the axis, align them all at the start of the axis, align them all at the end of the axis. This alignment is typically offered on both the main and cross axis. WhyI've found it to be an intuitive and efficient way of laying things out, which solves many of the use cases I commonly run into when doing web development work. While a grid system is helpful for the broader, macro-level layout, flex offers a means of spacing items within the cells of the grid. Flex is really well known, is framework-agnostic, and is implemented in HTML/CSS and other popular UI frameworks such as Flutter (which has a fantastic API with some similarities to Rich). There are many resources available for learning it online. The APIPrior artHere's how Flutter does it: Row( // also works with Column
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyWidget(),
MyWidget(height: 200.0, width: 200.0),
MyWidget(height: 50.0, width: 50.0)
]
); When you create a
Note that each widget has 2 spaces at each side, so there are 2 spaces between the terminal edge (represented by A Flutter Flex in Rich
I'd like to propose a Here's an example: lhs = Panel("My Fancy App")
rhs = Panel("v90")
Flex(lhs, rhs, align_horizontal="space-evenly", align_vertical="end", height=6) Would render as:
Notice that on the horizontal axis, the items are evenly spaced. On the vertical axis, the items are rendered at end. More ExamplesAgain, I represent the edge of the parent container of the
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi Darren, I've always taken inspiration from CSS/html when implementing Rich, so I can see how flex would be a good fit. I think you can achieve most layouts with the current primitives. The only thing you were missing in your example is that the justify applies to text (if it was css it would probably be text-align). If your v90 panel had from rich.align import Align
from rich.panel import Panel
from rich.table import Table
from rich.console import Console
rich_console = Console()
left = Panel("My Fancy App", expand=False)
right = Panel("v90", expand=False)
grid = Table.grid(expand=True)
grid.add_row(left, Align.right(right))
rich_console.print(grid) However, I can't deny that the flex api is way more intuitive! Flex would also benefit textual where I would like to render "documents" which will be suspiciously like web-pages. What would benefit me is if we did have a Flex class it could produce an intermediate data structure that contains a map of the x, y and width, height coordinates of each flex element within the document. I can use that to render partial updates. Another possibility is CSS grid, which I'm less familiar with, but which could be very powerful for creating advanced layouts. So yeah, I'm open to flex or grid. Did you have any thoughts re implementation? I'm quite busy at the moment with Textual, so I'm unlikely to attempt this any time soon. |
Beta Was this translation helpful? Give feedback.
Hi Darren,
I've always taken inspiration from CSS/html when implementing Rich, so I can see how flex would be a good fit.
I think you can achieve most layouts with the current primitives. The only thing you were missing in your example is that the justify applies to text (if it was css it would probably be text-align). If your v90 panel had
expand=True
, you would see that the text is aligned to the right edge of the panel. To align a renderable, and not just the text contents, you can useAlign.right
: