Border style (#2292)

* border styles

* docs for border styles

* fix tests

* tests

* tests and docs

* changelog

* implement auto

* style information fix
This commit is contained in:
Will McGugan
2023-04-16 12:31:39 +01:00
committed by GitHub
parent 9fb63f9b53
commit 0509cf8948
27 changed files with 1807 additions and 1247 deletions

View File

@@ -20,6 +20,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- option `--port` to the command `textual console` to specify which port the console should connect to https://github.com/Textualize/textual/pull/2258
- `Widget.scroll_to_center` method to scroll children to the center of container widget https://github.com/Textualize/textual/pull/2255 and https://github.com/Textualize/textual/pull/2276
- Added `TabActivated` message to `TabbedContent` https://github.com/Textualize/textual/pull/2260
- Added "panel" border style https://github.com/Textualize/textual/pull/2292
- Added `border-title-color`, `border-title-background`, `border-title-style` rules https://github.com/Textualize/textual/issues/2289
- Added `border-subtitle-color`, `border-subtitle-background`, `border-subtitle-style` rules https://github.com/Textualize/textual/issues/2289
### Fixed

View File

@@ -0,0 +1,16 @@
Screen {
align: center middle;
}
Label {
padding: 4 8;
border: heavy red;
border-title-color: green;
border-title-background: white;
border-title-style: bold;
border-subtitle-color: magenta;
border-subtitle-background: yellow;
border-subtitle-style: italic;
}

View File

@@ -0,0 +1,19 @@
from textual.app import App, ComposeResult
from textual.widgets import Label
class BorderTitleApp(App):
CSS_PATH = "border_title_colors.css"
def compose(self) -> ComposeResult:
yield Label("Hello, World!")
def on_mount(self) -> None:
label = self.query_one(Label)
label.border_title = "Textual Rocks"
label.border_subtitle = "Textual Rocks"
if __name__ == "__main__":
app = BorderTitleApp()
app.run()

View File

@@ -0,0 +1,18 @@
The following examples demonstrates customization of the border color and text style rules.
=== "Output"
```{.textual path="docs/examples/styles/border_title_colors.py"}
```
=== "border_title_colors.py"
```python
--8<-- "docs/examples/styles/border_title_colors.py"
```
=== "border_title_colors.css"
```sass
--8<-- "docs/examples/styles/border_title_colors.css"
```

View File

@@ -0,0 +1,9 @@
- [`border-title-align`](./border_title_align.md) to set the title's alignment.
- [`border-title-color`](./border_subtitle_color.md) to set the title's color.
- [`border-title-background`](./border_subtitle_background.md) to set the title's background color.
- [`border-title-style`](./border_subtitle_style.md) to set the title's text style.
- [`border-subtitle-align`](./border_subtitle_align.md) to set the sub-title's alignment.
- [`border-subtitle-color`](./border_subtitle_color.md) to set the sub-title's color.
- [`border-subtitle-background`](./border_subtitle_background.md) to set the sub-title's background color.
- [`border-subtitle-style`](./border_subtitle_style.md) to set the sub-title's text style.

View File

@@ -13,12 +13,7 @@ align-vertical: <a href="../../css_types/vertical">&lt;vertical&gt;</a>;
The `align` style takes a [`<horizontal>`](../../css_types/horizontal) followed by a [`<vertical>`](../../css_types/vertical).
You can specify the alignment of children on both the horizontal and vertical axes at the same time,
or on each of the axis separately.
To specify alignment on a single axis, use the respective style and type:
- `align-horizontal` takes a [`<horizontal>`](../../css_types/horizontal) and does alignment along the horizontal axis; and
- `align-vertical` takes a [`<vertical>`](../../css_types/vertical) and does alignment along the vertical axis.
You can also set the alignment for each axis individually with `align-horizontal` and `align-vertical`.
## Examples

View File

@@ -2,9 +2,11 @@
The `border` style enables the drawing of a box around a widget.
A border style may also be applied to individual edges with `border-top`, `border-right`, `border-bottom`, and `border-left`.
!!! note
Due to a Textual limitation, [`border`](./border.md) and [`outline`](./outline.md) cannot coexist in the same edge of a widget.
[`border`](./border.md) and [`outline`](./outline.md) cannot coexist in the same edge of a widget.
## Syntax
@@ -17,31 +19,10 @@ border-bottom: [<a href="../../css_types/border">&lt;border&gt;</a>] [<a href=".
border-left: [<a href="../../css_types/border">&lt;border&gt;</a>] [<a href="../../css_types/color">&lt;color&gt;</a> [<a href="../../css_types/percentage">&lt;percentage&gt;</a>]];
--8<-- "docs/snippets/syntax_block_end.md"
The `border` style accepts an optional [`<border>`](../../css_types/border) that sets the visual style of the widget border, an optional [`<color>`](../../css_types/color) to set the color of the border, and an optional [`<percentage>`](../../css_types/percentage) to specify the color transparency.
In CSS, the border is set with a [border style](./border.md) and a color. Both are optional. An optional percentage may be added to blend the border with the background color.
Borders may also be set individually for the four edges of a widget with the `border-top`, `border-right`, `border-bottom` and `border-left` rules.
In Python, the border is set with a tuple of [border style](./border.md) and a color.
### Multiple edge rules
If multiple border styles target the same edge, the last style that targets a specific edge is the one that is applied to that edge.
For example, consider the CSS below:
```sass
Static {
border-top: dashed red;
border: solid green; /* overrides the border-top rule above */
/* Change the border but just for the bottom edge: */
border-bottom: double blue;
}
```
The CSS snippet above will add a solid green border around `Static` widgets, except for the bottom edge, which will be double blue.
### Defaults
If `<color>` is specified but `<border>` is not, it defaults to `"solid"`.
If `<border>` is specified but `<color>`is not, it defaults to green (RGB color `"#00FF00"`).
If `<percentage>` is not specified it defaults to `100%`.
## Border command
@@ -128,3 +109,4 @@ widget.styles.border_left = ("outer", "red")
- [`box-sizing`](./box_sizing.md) to specify how to account for the border in a widget's dimensions.
- [`outline`](./outline.md) to add an outline around the content of a widget.
--8<-- "docs/snippets/see_also_border.md"

View File

@@ -60,3 +60,7 @@ widget.styles.border_subtitle_align = "left"
widget.styles.border_subtitle_align = "center"
widget.styles.border_subtitle_align = "right"
```
## See also
--8<-- "docs/snippets/see_also_border.md"

View File

@@ -0,0 +1,34 @@
# Border-subtitle-background
The `border-subtitle-background` style sets the *background* color of the [border_subtitle][textual.widget.Widget.border_subtitle].
## Syntax
--8<-- "docs/snippets/syntax_block_start.md"
border-subtitle-background: (<a href="../../css_types/color">&lt;color&gt;</a> | auto) [<a href="../../css_types/percentage">&lt;percentage&gt;</a>];
--8<-- "docs/snippets/syntax_block_end.md"
## Example
--8<-- "docs/snippets/border_title_color.md"
## CSS
```sass
border-subtitle-background: blue;
```
## Python
```python
widget.styles.border_subtitle_background = "blue"
```
## See also
--8<-- "docs/snippets/see_also_border.md"

View File

@@ -0,0 +1,33 @@
# Border-subtitle-color
The `border-subtitle-color` style sets the color of the [border_subtitle][textual.widget.Widget.border_subtitle].
## Syntax
--8<-- "docs/snippets/syntax_block_start.md"
border-subtitle-color: (<a href="../../css_types/color">&lt;color&gt;</a> | auto) [<a href="../../css_types/percentage">&lt;percentage&gt;</a>];
--8<-- "docs/snippets/syntax_block_end.md"
## Example
--8<-- "docs/snippets/border_title_color.md"
## CSS
```sass
border-subtitle-color: red;
```
## Python
```python
widget.styles.border_subtitle_color = "red"
```
## See also
--8<-- "docs/snippets/see_also_border.md"

View File

@@ -0,0 +1,35 @@
# Border-subtitle-style
The `border-subtitle-style` style sets the text style of the [border_subtitle][textual.widget.Widget.border_subtitle].
## Syntax
--8<-- "docs/snippets/syntax_block_start.md"
border-subtitle-style: <a href="../../css_types/text_style">&lt;text-style&gt;</a>;
--8<-- "docs/snippets/syntax_block_end.md"
## Example
--8<-- "docs/snippets/border_title_color.md"
## CSS
```sass
border-subtitle-style: bold underline;
```
## Python
```python
widget.styles.border_subtitle_style = "bold underline"
```
## See also
--8<-- "docs/snippets/see_also_border.md"

View File

@@ -60,3 +60,7 @@ widget.styles.border_title_align = "left"
widget.styles.border_title_align = "center"
widget.styles.border_title_align = "right"
```
## See also
--8<-- "docs/snippets/see_also_border.md"

View File

@@ -0,0 +1,33 @@
# Border-title-background
The `border-title-background` style sets the *background* color of the [border_title][textual.widget.Widget.border_title].
## Syntax
--8<-- "docs/snippets/syntax_block_start.md"
border-title-background: (<a href="../../css_types/color">&lt;color&gt;</a> | auto) [<a href="../../css_types/percentage">&lt;percentage&gt;</a>];
--8<-- "docs/snippets/syntax_block_end.md"
## Example
--8<-- "docs/snippets/border_title_color.md"
## CSS
```sass
border-title-background: blue;
```
## Python
```python
widget.styles.border_title_background = "blue"
```
## See also
--8<-- "docs/snippets/see_also_border.md"

View File

@@ -0,0 +1,31 @@
# Border-title-color
The `border-title-color` style sets the color of the [border_title][textual.widget.Widget.border_title].
## Syntax
--8<-- "docs/snippets/syntax_block_start.md"
border-title-color: (<a href="../../css_types/color">&lt;color&gt;</a> | auto) [<a href="../../css_types/percentage">&lt;percentage&gt;</a>];
--8<-- "docs/snippets/syntax_block_end.md"
## Example
--8<-- "docs/snippets/border_title_color.md"
## CSS
```sass
border-title-color: red;
```
## Python
```python
widget.styles.border_title_color = "red"
```
## See also
--8<-- "docs/snippets/see_also_border.md"

View File

@@ -0,0 +1,35 @@
# Border-title-style
The `border-title-style` style sets the text style of the [border_title][textual.widget.Widget.border_title].
## Syntax
--8<-- "docs/snippets/syntax_block_start.md"
border-title-style: <a href="../../css_types/text_style">&lt;text-style&gt;</a>;
--8<-- "docs/snippets/syntax_block_end.md"
## Example
--8<-- "docs/snippets/border_title_color.md"
## CSS
```sass
border-title-style: bold underline;
```
## Python
```python
widget.styles.border_title_style = "bold underline"
```
## See also
--8<-- "docs/snippets/see_also_border.md"

View File

@@ -4,7 +4,7 @@ The `outline` style enables the drawing of a box around the content of a widget,
!!! note
Due to a Textual limitation, [`border`](./border.md) and [`outline`](./outline.md) cannot coexist in the same edge of a widget.
[`border`](./border.md) and [`outline`](./outline.md) cannot coexist in the same edge of a widget.
## Syntax

View File

@@ -1,6 +1,6 @@
# Text-style
The `text-style` sets the style for the text in a widget.
The `text-style` style sets the style for the text in a widget.
## Syntax

View File

@@ -64,17 +64,23 @@ nav:
- "events/screen_suspend.md"
- "events/show.md"
- Styles:
- "styles/index.md"
- "styles/align.md"
- "styles/background.md"
- "styles/border.md"
- "styles/border_subtitle_align.md"
- "styles/border_subtitle_background.md"
- "styles/border_subtitle_color.md"
- "styles/border_subtitle_style.md"
- "styles/border_title_align.md"
- "styles/border_title_background.md"
- "styles/border_title_color.md"
- "styles/border_title_style.md"
- "styles/border.md"
- "styles/box_sizing.md"
- "styles/color.md"
- "styles/content_align.md"
- "styles/display.md"
- "styles/dock.md"
- "styles/index.md"
- Grid:
- "styles/grid/index.md"
- "styles/grid/column_span.md"

View File

@@ -102,9 +102,14 @@ BORDER_CHARS: dict[
("", " ", ""),
("", "", ""),
),
"panel": (
("", "", ""),
("", " ", ""),
("", "", ""),
),
"wide": (
("", "", ""),
("", " ", ""),
("", " ", ""),
("", "", ""),
),
}
@@ -195,6 +200,11 @@ BORDER_LOCATIONS: dict[
(2, 0, 1),
(2, 0, 1),
),
"panel": (
(2, 0, 1),
(2, 0, 1),
(2, 0, 1),
),
"wide": (
(1, 1, 1),
(0, 1, 3),
@@ -202,6 +212,11 @@ BORDER_LOCATIONS: dict[
),
}
# Some borders (such as panel) require that the title (and subtitle) be draw in reverse.
# This is a mapping of the border type on to a tuple for the top and bottom borders, to indicate
# reverse colors is required.
BORDER_TITLE_FLIP: dict[str, tuple[bool, bool]] = {"panel": (True, False)}
# In a similar fashion, we extract the border _label_ locations for easier access when
# rendering a border label.
# The values are a pair with (title location, subtitle location).
@@ -283,7 +298,7 @@ def get_box(
def render_border_label(
label: Text,
label: tuple[Text, Style],
is_title: bool,
name: EdgeType,
width: int,
@@ -300,7 +315,7 @@ def render_border_label(
account the inner, outer, and border-specific, styles.
Args:
label: The label to display (that may contain markup).
label: Tuple of label and style to render in the border.
is_title: Whether we are rendering the title (`True`) or the subtitle (`False`).
name: Name of the box type.
width: The width, in cells, of the space available for the whole edge.
@@ -323,14 +338,21 @@ def render_border_label(
# How many cells do we need to reserve for surrounding blanks and corners?
corners_needed = has_left_corner + has_right_corner
cells_reserved = 2 * corners_needed
if not label.cell_len or width <= cells_reserved:
text_label, label_style = label
if not text_label.cell_len or width <= cells_reserved:
return
text_label = label.copy()
text_label = text_label.copy()
text_label.truncate(width - cells_reserved, overflow="ellipsis")
segments = text_label.render(console)
if has_left_corner:
text_label.pad_left(1)
if has_right_corner:
text_label.pad_right(1)
text_label.stylize_before(label_style)
label_style_location = BORDER_LABEL_LOCATIONS[name][0 if is_title else 1]
flip_top, flip_bottom = BORDER_TITLE_FLIP.get(name, (False, False))
inner = inner_style + style
outer = outer_style + style
@@ -347,15 +369,14 @@ def render_border_label(
else:
assert False
styled_segments = [
Segment(segment.text, base_style + segment.style) for segment in segments
]
blank = Segment(" ", base_style)
if has_left_corner:
yield blank
yield from styled_segments
if has_right_corner:
yield blank
if (flip_top and is_title) or (flip_bottom and not is_title):
base_style = base_style.without_color + Style.from_color(
base_style.bgcolor, base_style.color
)
text_label.stylize_before(base_style + label_style)
segments = text_label.render(console)
yield from segments
def render_row(

View File

@@ -107,6 +107,10 @@ class StylesCache:
Returns:
Rendered lines.
"""
border_title = widget._border_title
border_subtitle = widget._border_subtitle
base_background, background = widget.background_colors
styles = widget.styles
strips = self.render(
@@ -116,8 +120,22 @@ class StylesCache:
background,
widget.render_line,
widget.app.console,
widget._border_title,
widget._border_subtitle,
(
None
if border_title is None
else (
border_title,
*widget._get_title_style_information(base_background),
)
),
(
None
if border_subtitle is None
else (
border_subtitle,
*widget._get_subtitle_style_information(base_background),
)
),
content_size=widget.content_region.size,
padding=styles.padding,
crop=crop,
@@ -147,8 +165,8 @@ class StylesCache:
background: Color,
render_content_line: RenderLineCallback,
console: Console,
border_title: Text | None,
border_subtitle: Text | None,
border_title: tuple[Text, Color, Color, Style] | None,
border_subtitle: tuple[Text, Color, Color, Style] | None,
content_size: Size | None = None,
padding: Spacing | None = None,
crop: Region | None = None,
@@ -163,8 +181,8 @@ class StylesCache:
background: Background color of widget.
render_content_line: Callback to render content line.
console: The console in use by the app.
border_title: The title for the widget border.
border_subtitle: The subtitle for the widget border.
border_title: Optional tuple of (title, color, background, style).
border_subtitle: Optional tuple of (subtitle, color, background, style).
content_size: Size of content or None to assume full size.
padding: Override padding from Styles, or None to use styles.padding.
crop: Region to crop to.
@@ -229,8 +247,8 @@ class StylesCache:
background: Color,
render_content_line: Callable[[int], Strip],
console: Console,
border_title: Text | None,
border_subtitle: Text | None,
border_title: tuple[Text, Color, Color, Style] | None,
border_subtitle: tuple[Text, Color, Color, Style] | None,
) -> Strip:
"""Render a styled line.
@@ -244,8 +262,8 @@ class StylesCache:
background: Background color of widget.
render_content_line: Callback to render a line of content.
console: The console in use by the app.
border_title: The title for the widget border.
border_subtitle: The subtitle for the widget border.
border_title: Optional tuple of (title, color, background, style).
border_subtitle: Optional tuple of (subtitle, color, background, style).
Returns:
A line of segments.
@@ -305,10 +323,26 @@ class StylesCache:
has_left = border_left != ""
has_right = border_right != ""
border_label = border_title if is_top else border_subtitle
if border_label is None:
render_label = None
else:
label, label_color, label_background, style = border_label
base_label_background = base_background + background
style += Style.from_color(
(
(base_label_background + label_color).rich_color
if label_color.a
else None
),
(base_label_background + label_background).rich_color
if label_background.a
else None,
)
render_label = (label, style)
# Try to save time with expensive call to `render_border_label`:
if border_label:
if render_label:
label_segments = render_border_label(
border_label,
render_label,
is_top,
border_edge_type,
width - 2,

View File

@@ -640,6 +640,11 @@ class StylesBuilder:
process_link_hover_color = process_color
process_link_hover_background = process_color
process_border_title_color = process_color
process_border_title_background = process_color
process_border_subtitle_color = process_color
process_border_subtitle_background = process_color
def process_text_style(self, name: str, tokens: list[Token]) -> None:
for token in tokens:
value = token.value
@@ -656,6 +661,9 @@ class StylesBuilder:
process_link_style = process_text_style
process_link_hover_style = process_text_style
process_border_title_style = process_text_style
process_border_subtitle_style = process_text_style
def process_text_align(self, name: str, tokens: list[Token]) -> None:
"""Process a text-align declaration"""
if not tokens:

View File

@@ -167,6 +167,16 @@ class RulesMap(TypedDict, total=False):
link_hover_background: Color
link_hover_style: Style
auto_border_title_color: bool
border_title_color: Color
border_title_background: Color
border_title_style: Style
auto_border_subtitle_color: bool
border_subtitle_color: Color
border_subtitle_background: Color
border_subtitle_style: Style
RULE_NAMES = list(RulesMap.__annotations__.keys())
RULE_NAMES_SET = frozenset(RULE_NAMES)
@@ -321,6 +331,16 @@ class StylesBase(ABC):
link_hover_background = ColorProperty("transparent")
link_hover_style = StyleFlagsProperty()
auto_border_title_color = BooleanProperty(default=False)
border_title_color = ColorProperty(Color(255, 255, 255, 0))
border_title_background = ColorProperty(Color(0, 0, 0, 0))
border_title_style = StyleFlagsProperty()
auto_border_subtitle_color = BooleanProperty(default=False)
border_subtitle_color = ColorProperty(Color(255, 255, 255, 0))
border_subtitle_background = ColorProperty(Color(0, 0, 0, 0))
border_subtitle_style = StyleFlagsProperty()
def __textual_animation__(
self,
attribute: str,
@@ -990,6 +1010,22 @@ class Styles(StylesBase):
if "link_hover_style" in rules:
append_declaration("link-hover-style", str(self.link_hover_style))
if "border_title_color" in rules:
append_declaration("title-color", self.border_title_color.css)
if "border_title_background" in rules:
append_declaration("title-background", self.border_title_background.css)
if "border_title_style" in rules:
append_declaration("title-text-style", str(self.border_title_style))
if "border_subtitle_color" in rules:
append_declaration("subtitle-color", self.border_subtitle_color.css)
if "border_subtitle_background" in rules:
append_declaration(
"subtitle-background", self.border_subtitle_background.css
)
if "border_subtitle_text_style" in rules:
append_declaration("subtitle-text-style", str(self.border_subtitle_style))
lines.sort()
return lines

View File

@@ -25,6 +25,7 @@ EdgeType = Literal[
"hkey",
"vkey",
"tall",
"panel",
"wide",
]
Visibility = Literal["visible", "hidden", "initial", "inherit"]

View File

@@ -765,6 +765,52 @@ class DOMNode(MessagePump):
)
return style
def _get_title_style_information(
self, background: Color
) -> tuple[Color, Color, Style]:
"""Get a Rich Style object for for titles.
Args:
background: The background color.
Returns:
A Rich style.
"""
styles = self.styles
if styles.auto_border_title_color:
color = background.get_contrast_text(styles.border_title_color.a)
else:
color = styles.border_title_color
return (
color,
styles.border_title_background,
styles.border_title_style,
)
def _get_subtitle_style_information(
self, background: Color
) -> tuple[Color, Color, Style]:
"""Get a Rich Style object for for titles.
Args:
background: The background color.
Returns:
A Rich style.
"""
styles = self.styles
if styles.auto_border_subtitle_color:
color = background.get_contrast_text(styles.border_subtitle_color.a)
else:
color = styles.border_subtitle_color
return (
color,
styles.border_subtitle_background,
styles.border_subtitle_style,
)
@property
def background_colors(self) -> tuple[Color, Color]:
"""The background color and the color of the parent's background.

File diff suppressed because one or more lines are too long

View File

@@ -105,7 +105,7 @@ def test_render_border_label_empty_label_skipped(
assert [] == list(
render_border_label(
Text(""),
(Text(""), Style()),
True,
"round",
width,
@@ -142,7 +142,7 @@ def test_render_border_label_skipped_if_narrow(
assert [] == list(
render_border_label(
Text.from_markup(label),
(Text.from_markup(label), Style()),
True,
"round",
width,
@@ -180,11 +180,10 @@ def test_render_border_label_wide_plain(label: str):
True,
True,
)
left, original_text, right = render_border_label(Text.from_markup(label), *args)
segments = render_border_label((Text.from_markup(label), Style()), *args)
(segment,) = segments
assert left == _BLANK_SEGMENT
assert right == _BLANK_SEGMENT
assert original_text == Segment(label, _EMPTY_STYLE)
assert segment == Segment(f" {label} ", None)
@pytest.mark.parametrize(
@@ -200,7 +199,7 @@ def test_render_border_empty_text_with_markup(label: str):
"""Test label rendering if there is no text but some markup."""
assert [] == list(
render_border_label(
Text.from_markup(label),
(Text.from_markup(label), Style()),
True,
"round",
999,
@@ -222,7 +221,7 @@ def test_render_border_label():
# Implicit test on the number of segments returned:
blank1, what, is_up, with_you, blank2 = render_border_label(
Text.from_markup(label),
(Text.from_markup(label), Style()),
True,
"round",
9999,
@@ -251,7 +250,7 @@ def test_render_border_label():
assert with_you == expected_with_you
blank1, what, blank2 = render_border_label(
Text.from_markup(label),
(Text.from_markup(label), Style()),
True,
"round",
5 + 4, # 5 where "What…" fits + 2 for the blank spaces + 2 for the corners.

View File

@@ -72,8 +72,8 @@ def test_border():
Color.parse("green"),
content.__getitem__,
Console(),
"",
"",
None,
None,
content_size=Size(3, 3),
)
@@ -106,8 +106,8 @@ def test_padding():
Color.parse("green"),
content.__getitem__,
Console(),
"",
"",
None,
None,
content_size=Size(3, 3),
)
@@ -141,8 +141,8 @@ def test_padding_border():
Color.parse("green"),
content.__getitem__,
Console(),
"",
"",
None,
None,
content_size=Size(3, 3),
)
@@ -177,8 +177,8 @@ def test_outline():
Color.parse("green"),
content.__getitem__,
Console(),
"",
"",
None,
None,
content_size=Size(3, 3),
)
@@ -208,8 +208,8 @@ def test_crop():
Color.parse("green"),
content.__getitem__,
Console(),
"",
"",
None,
None,
content_size=Size(3, 3),
crop=Region(2, 2, 3, 3),
)
@@ -247,8 +247,8 @@ def test_dirty_cache() -> None:
Color.parse("green"),
get_content_line,
Console(),
"",
"",
None,
None,
content_size=Size(3, 3),
)
assert rendered_lines == [0, 1, 2]
@@ -275,8 +275,8 @@ def test_dirty_cache() -> None:
Color.parse("green"),
get_content_line,
Console(),
"",
"",
None,
None,
content_size=Size(3, 3),
)
assert rendered_lines == []
@@ -294,8 +294,8 @@ def test_dirty_cache() -> None:
Color.parse("green"),
get_content_line,
Console(),
"",
"",
None,
None,
content_size=Size(3, 3),
)
assert rendered_lines == [0, 1]