From c37e58b15a4f79836930827e6e7406c3a3f381ef Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sun, 4 Dec 2022 11:35:29 +0000 Subject: [PATCH 001/310] Remove the link to the forums --- docs/help.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/help.md b/docs/help.md index 488d0919b..645f7bd65 100644 --- a/docs/help.md +++ b/docs/help.md @@ -9,8 +9,3 @@ Report bugs via GitHub on the Textual [issues](https://github.com/Textualize/tex ## Discord Server For more realtime feedback or chat, join our discord server to connect with the [Textual community](https://discord.gg/Enf6Z3qhVr). - -## Forum - -Visit the [Textual forum](https://community.textualize.io/) for Textual (and Rich) discussions. - From f5f525f1c8d7e0dc5740bb16eb4ebdebbe67843d Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sun, 4 Dec 2022 11:38:03 +0000 Subject: [PATCH 002/310] Emphasise that help can be found in GitHub discussions --- docs/help.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/help.md b/docs/help.md index 645f7bd65..a27dae4e0 100644 --- a/docs/help.md +++ b/docs/help.md @@ -6,6 +6,10 @@ If you need help with any aspect of Textual, let us know! We would be happy to h Report bugs via GitHub on the Textual [issues](https://github.com/Textualize/textual/issues) page. You can also post feature requests via GitHub issues, but see the [roadmap](./roadmap.md) first. +## Help with using Textual + +You can seek help with using Textual [in the discussion area on GitHub](https://github.com/Textualize/textual/discussions). + ## Discord Server For more realtime feedback or chat, join our discord server to connect with the [Textual community](https://discord.gg/Enf6Z3qhVr). From 26a9e3fced78184fde7752521a23e130cd2c65bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 13 Dec 2022 18:29:55 +0000 Subject: [PATCH 003/310] Use Label for simple text widgets. --- docs/examples/styles/align.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples/styles/align.py b/docs/examples/styles/align.py index 6abee37ce..89f293aae 100644 --- a/docs/examples/styles/align.py +++ b/docs/examples/styles/align.py @@ -1,11 +1,11 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label class AlignApp(App): def compose(self): - yield Static("Vertical alignment with [b]Textual[/]", classes="box") - yield Static("Take note, browsers.", classes="box") + yield Label("Vertical alignment with [b]Textual[/]", classes="box") + yield Label("Take note, browsers.", classes="box") app = AlignApp(css_path="align.css") From 2faff2fbfc0ac350deccc09c10eeb7aeaa842a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 13 Dec 2022 18:30:14 +0000 Subject: [PATCH 004/310] Add complete alignment grid screenshot. --- docs/examples/styles/align_all.css | 53 ++++++++++++++++++++++++++++++ docs/examples/styles/align_all.py | 20 +++++++++++ docs/styles/align.md | 24 +++++++++++++- 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 docs/examples/styles/align_all.css create mode 100644 docs/examples/styles/align_all.py diff --git a/docs/examples/styles/align_all.css b/docs/examples/styles/align_all.css new file mode 100644 index 000000000..33591df19 --- /dev/null +++ b/docs/examples/styles/align_all.css @@ -0,0 +1,53 @@ +#left-top { + /* align: left top; this is the default value and is implied. */ +} + +#center-top { + align: center top; +} + +#right-top { + align: right top; +} + +#left-middle { + align: left middle; +} + +#center-middle { + align: center middle; +} + +#right-middle { + align: right middle; +} + +#left-bottom { + align: left bottom; +} + +#center-bottom { + align: center bottom; +} + +#right-bottom { + align: right bottom; +} + +Screen { + layout: grid; + grid-size: 3 3; + grid-gutter: 1; +} + +Container { + background: $boost; + border: solid gray; + height: 100%; +} + +Label { + width: auto; + height: 1; + background: $accent; +} \ No newline at end of file diff --git a/docs/examples/styles/align_all.py b/docs/examples/styles/align_all.py new file mode 100644 index 000000000..1ff8d6040 --- /dev/null +++ b/docs/examples/styles/align_all.py @@ -0,0 +1,20 @@ +from textual.app import App, ComposeResult +from textual.containers import Container +from textual.widgets import Label + + +class AlignAllApp(App): + """App that illustrates all alignments.""" + + CSS_PATH = "align_all.css" + + def compose(self) -> ComposeResult: + yield Container(Label("left top"), id="left-top") + yield Container(Label("center top"), id="center-top") + yield Container(Label("right top"), id="right-top") + yield Container(Label("left middle"), id="left-middle") + yield Container(Label("center middle"), id="center-middle") + yield Container(Label("right middle"), id="right-middle") + yield Container(Label("left bottom"), id="left-bottom") + yield Container(Label("center bottom"), id="center-bottom") + yield Container(Label("right bottom"), id="right-bottom") diff --git a/docs/styles/align.md b/docs/styles/align.md index 15bbcbed9..24692e611 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -30,7 +30,9 @@ align-vertical: ; | `bottom` | Align content at the bottom of the vertical axis | -## Example +## Examples + +This example contains a simple app with two labels centered on the screen with `align: center middle;`: === "align.py" @@ -50,6 +52,26 @@ align-vertical: ; ``` +The next example shows a 3 by 3 grid of containers with text labels. +Each label has been aligned differently inside its container, and its text shows its `align: ...` value. + +=== "align_all.py" + + ```python + --8<-- "docs/examples/styles/align_all.py" + ``` + +=== "align_all.css" + + ```css + --8<-- "docs/examples/styles/align_all.css" + ``` + +=== "Output" + + ```{.textual path="docs/examples/styles/align_all.py"} + ``` + ## CSS ```sass From 481ec2a3ab55e141b337e457f505334720c5ea18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 14 Dec 2022 14:34:12 +0000 Subject: [PATCH 005/310] Improve doc string for class method Color.parse --- src/textual/color.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/textual/color.py b/src/textual/color.py index a53a0abaf..c0a43c85b 100644 --- a/src/textual/color.py +++ b/src/textual/color.py @@ -386,23 +386,22 @@ class Color(NamedTuple): Colors may be parsed from the following formats: - Text beginning with a `#` is parsed as hex: + - Text beginning with a `#` is parsed as a hexadecimal color code, + where R, G, B, and A must be hexadecimal digits (0-9A-F): - R, G, and B must be hex digits (0-9A-F) + - `#RGB` + - `#RGBA` + - `#RRGGBB` + - `#RRGGBBAA` - - `#RGB` - - `#RRGGBB` - - `#RRGGBBAA` + - Text in the following formats is parsed as decimal values, + where RED, GREEN, and BLUE must be numbers between 0 and 255 + and ALPHA must be a value between 0 and 1: - Text in the following formats is parsed as decimal values: - - RED, GREEN, and BLUE must be numbers between 0 and 255. - ALPHA should ba a value between 0 and 1. - - - `rgb(RED,GREEN,BLUE)` - - `rgba(RED,GREEN,BLUE,ALPHA)` - - `hsl(RED,GREEN,BLUE)` - - `hsla(RED,GREEN,BLUE,ALPHA)` + - `rgb(RED,GREEN,BLUE)` + - `rgba(RED,GREEN,BLUE,ALPHA)` + - `hsl(RED,GREEN,BLUE)` + - `hsla(RED,GREEN,BLUE,ALPHA)` All other text will raise a `ColorParseError`. From afac92439c97a6a338dea80607af1e6bbad8fdcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 14 Dec 2022 14:35:11 +0000 Subject: [PATCH 006/310] Add example for background transparency. --- docs/examples/styles/align_all.css | 2 +- .../styles/background_transparency.css | 49 +++++++++++++++++++ .../styles/background_transparency.py | 20 ++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 docs/examples/styles/background_transparency.css create mode 100644 docs/examples/styles/background_transparency.py diff --git a/docs/examples/styles/align_all.css b/docs/examples/styles/align_all.css index 33591df19..6f3aa58e3 100644 --- a/docs/examples/styles/align_all.css +++ b/docs/examples/styles/align_all.css @@ -50,4 +50,4 @@ Label { width: auto; height: 1; background: $accent; -} \ No newline at end of file +} diff --git a/docs/examples/styles/background_transparency.css b/docs/examples/styles/background_transparency.css new file mode 100644 index 000000000..9c38d2888 --- /dev/null +++ b/docs/examples/styles/background_transparency.css @@ -0,0 +1,49 @@ +#t10 { + background: red 10%; +} + +#t20 { + background: red 20%; +} + +#t30 { + background: red 30%; +} + +#t40 { + background: red 40%; +} + +#t50 { + background: red 50%; +} + +#t60 { + background: red 60%; +} + +#t70 { + background: red 70%; +} + +#t80 { + background: red 80%; +} + +#t90 { + background: red 90%; +} + +#t100 { + background: red 100%; +} + +Screen { + layout: horizontal; +} + +Static { + height: 100%; + width: 1fr; + content-align: center middle; +} diff --git a/docs/examples/styles/background_transparency.py b/docs/examples/styles/background_transparency.py new file mode 100644 index 000000000..942bb51b8 --- /dev/null +++ b/docs/examples/styles/background_transparency.py @@ -0,0 +1,20 @@ +from textual.app import App, ComposeResult +from textual.widgets import Static + + +class BackgroundTransparencyApp(App): + """Simple app to exemplify different transparency settings.""" + def compose(self) -> ComposeResult: + yield Static("10%", id="t10") + yield Static("20%", id="t20") + yield Static("30%", id="t30") + yield Static("40%", id="t40") + yield Static("50%", id="t50") + yield Static("60%", id="t60") + yield Static("70%", id="t70") + yield Static("80%", id="t80") + yield Static("90%", id="t90") + yield Static("100%", id="t100") + + +app = BackgroundTransparencyApp(css_path="background_transparency.css") From 3e5698c21ebc5ab8009a05f424aa679a61dec70b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 14 Dec 2022 15:24:17 +0000 Subject: [PATCH 007/310] Fix docstring for class method Color.parse. --- src/textual/color.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/textual/color.py b/src/textual/color.py index c0a43c85b..f51eabbaa 100644 --- a/src/textual/color.py +++ b/src/textual/color.py @@ -394,16 +394,21 @@ class Color(NamedTuple): - `#RRGGBB` - `#RRGGBBAA` - - Text in the following formats is parsed as decimal values, - where RED, GREEN, and BLUE must be numbers between 0 and 255 - and ALPHA must be a value between 0 and 1: + - Alternatively, RGB colors can also be specified in the format + that follows, where R, G, and B must be numbers between 0 and 255 + and A must be a value between 0 and 1: - - `rgb(RED,GREEN,BLUE)` - - `rgba(RED,GREEN,BLUE,ALPHA)` - - `hsl(RED,GREEN,BLUE)` - - `hsla(RED,GREEN,BLUE,ALPHA)` + - `rgb(R,G,B)` + - `rgb(R,G,B,A)` - All other text will raise a `ColorParseError`. + - The HSL model can also be used, with a syntax similar to the above, + if H is a value between 0 and 360, S and L are percentages, and A + is a value between 0 and 1: + + - `hsl(H,S,L)` + - `hsla(H,S,L,A)` + + Any other formats will raise a `ColorParseError`. Args: color_text (str | Color): Text with a valid color format. Color objects will @@ -413,7 +418,7 @@ class Color(NamedTuple): ColorParseError: If the color is not encoded correctly. Returns: - Color: New color object. + Color: Instance encoding the color specified by the argument. """ if isinstance(color_text, Color): return color_text From c3d8df7d2e43a59eb65c7e088833387a7a3f3aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 11:30:39 +0000 Subject: [PATCH 008/310] Improve docs on background style. --- docs/styles/background.md | 40 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/docs/styles/background.md b/docs/styles/background.md index 6c41885c7..b9cf36b48 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -1,6 +1,6 @@ # Background -The `background` rule sets the background color of the widget. +The `background` rule sets the background color of a widget with an optional transparency level. ## Syntax @@ -8,7 +8,15 @@ The `background` rule sets the background color of the widget. background: []; ``` -## Example +The legal values for `` are dependant on the [class `Color`][textual.color.Color] and include: + + - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); + - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); + - a color description in the HSL system (e.g., `hsl(290,70%,80%)`) + +For more details about the exact formats accepted, see [the class method `Color.parse`][textual.color.Color.parse]. + +## Examples This example creates three widgets and applies a different background to each. @@ -29,6 +37,25 @@ This example creates three widgets and applies a different background to each. ```{.textual path="docs/examples/styles/background.py"} ``` +The next example creates ten widgets layed out side by side to show the effect of setting different percentages for the transparency of the background color. + +=== "background_transparency.py" + + ```python + --8<-- "docs/examples/styles/background_transparency.py" + ``` + +=== "background_transparency.css" + + ```sass + --8<-- "docs/examples/styles/background_transparency.css" + ``` + +=== "Output" + + ```{.textual path="docs/examples/styles/background_transparency.py"} + ``` + ## CSS ```sass @@ -40,6 +67,9 @@ background: red 20%; /* RGB color */ background: rgb(100,120,200); + +/* HSL color */ +background: hsl(290,70%,80%); ``` ## Python @@ -49,9 +79,13 @@ You can use the same syntax as CSS, or explicitly set a `Color` object for finer ```python # Set blue background widget.styles.background = "blue" +# Set through HSL model +widget.styles.background = "hsl(351,32%,89%)" from textual.color import Color -# Set with a color object +# Set with a color object by parsing a string widget.styles.background = Color.parse("pink") +widget.styles.background = Color.parse("#FF00FF") +# Set with a color object instantiated directly widget.styles.background = Color(120, 60, 100) ``` From d5d24235fab2af31e93787babcf32009fce82125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 11:55:42 +0000 Subject: [PATCH 009/310] Factor out css color syntax into snippet. This refactoring allows the _same_ paragraph(s) about the syntax of a color in Textual CSS to be reused throughout the docs, preventing us from repeating ourselves and allowing us to be more consistent. --- docs/styles/background.md | 8 +------- docs/styles/snippets/color_css_syntax.md | 7 +++++++ 2 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 docs/styles/snippets/color_css_syntax.md diff --git a/docs/styles/background.md b/docs/styles/background.md index b9cf36b48..eb71f3d7f 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -8,13 +8,7 @@ The `background` rule sets the background color of a widget with an optional tra background: []; ``` -The legal values for `` are dependant on the [class `Color`][textual.color.Color] and include: - - - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); - - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); - - a color description in the HSL system (e.g., `hsl(290,70%,80%)`) - -For more details about the exact formats accepted, see [the class method `Color.parse`][textual.color.Color.parse]. +--8<-- "docs/styles/snippets/color_css_syntax.md" ## Examples diff --git a/docs/styles/snippets/color_css_syntax.md b/docs/styles/snippets/color_css_syntax.md new file mode 100644 index 000000000..e15897f5f --- /dev/null +++ b/docs/styles/snippets/color_css_syntax.md @@ -0,0 +1,7 @@ +The legal values for `` are dependant on the [class `Color`][textual.color.Color] and include: + + - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); + - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); + - a color description in the HSL system (e.g., `hsl(290,70%,80%)`) + +For more details about the exact formats accepted, see [the class method `Color.parse`][textual.color.Color.parse]. From 3a83c26779e0a449571842ee4008c59e75da5414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 16:14:56 +0000 Subject: [PATCH 010/310] Replace statics with labels. --- docs/examples/styles/border.css | 9 +++++---- docs/examples/styles/border.py | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/examples/styles/border.css b/docs/examples/styles/border.css index 762430dc8..27b9e281d 100644 --- a/docs/examples/styles/border.css +++ b/docs/examples/styles/border.css @@ -1,24 +1,25 @@ Screen { background: white; } -Screen > Static { +Screen > Label { + width: 100%; height: 5; content-align: center middle; color: white; margin: 1; box-sizing: border-box; } -#static1 { +#label1 { background: red 20%; color: red; border: solid red; } -#static2 { +#label2 { background: green 20%; color: green; border: dashed green; } -#static3 { +#label3 { background: blue 20%; color: blue; border: tall blue; diff --git a/docs/examples/styles/border.py b/docs/examples/styles/border.py index 4dbc8ef4f..d426e85b0 100644 --- a/docs/examples/styles/border.py +++ b/docs/examples/styles/border.py @@ -1,12 +1,12 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label class BorderApp(App): def compose(self): - yield Static("My border is solid red", id="static1") - yield Static("My border is dashed green", id="static2") - yield Static("My border is tall blue", id="static3") + yield Label("My border is solid red", id="label1") + yield Label("My border is dashed green", id="label2") + yield Label("My border is tall blue", id="label3") app = BorderApp(css_path="border.css") From e70f271afc01d5e14c7af07ceee4af62ddb7cf3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 16:15:30 +0000 Subject: [PATCH 011/310] Add example with all border types. --- docs/examples/styles/border_all.css | 71 +++++++++++++++++++++++++++++ docs/examples/styles/border_all.py | 26 +++++++++++ 2 files changed, 97 insertions(+) create mode 100644 docs/examples/styles/border_all.css create mode 100644 docs/examples/styles/border_all.py diff --git a/docs/examples/styles/border_all.css b/docs/examples/styles/border_all.css new file mode 100644 index 000000000..527b1adab --- /dev/null +++ b/docs/examples/styles/border_all.css @@ -0,0 +1,71 @@ +#ascii { + border: ascii $accent; +} + +#blank { + border: blank $accent; +} + +#dashed { + border: dashed $accent; +} + +#double { + border: double $accent; +} + +#heavy { + border: heavy $accent; +} + +#hidden { + border: hidden $accent; +} + +#hkey { + border: hkey $accent; +} + +#inner { + border: inner $accent; +} + +#none { + border: none $accent; +} + +#outer { + border: outer $accent; +} + +#round { + border: round $accent; +} + +#solid { + border: solid $accent; +} + +#tall { + border: tall $accent; +} + +#vkey { + border: vkey $accent; +} + +#wide { + border: wide $accent; +} + +Grid { + grid-size: 3 5; + align: center middle; + grid-gutter: 1 2; +} + +Label { + width: 20; + height: 3; + content-align: center middle; +} diff --git a/docs/examples/styles/border_all.py b/docs/examples/styles/border_all.py new file mode 100644 index 000000000..d839c3e5a --- /dev/null +++ b/docs/examples/styles/border_all.py @@ -0,0 +1,26 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Label + + +class AllBordersApp(App): + def compose(self): + yield Grid( + Label("ascii", id="ascii"), + Label("blank", id="blank"), + Label("dashed", id="dashed"), + Label("double", id="double"), + Label("heavy", id="heavy"), + Label("hidden/none", id="hidden"), + Label("hkey", id="hkey"), + Label("inner", id="inner"), + Label("none", id="none"), + Label("outer", id="outer"), + Label("round", id="round"), + Label("solid", id="solid"), + Label("tall", id="tall"), + Label("vkey", id="vkey"), + Label("wide", id="wide"), + ) + +app = AllBordersApp(css_path="border_all.css") From 4897b9d1b7a447def4def388f61559aa56b5e2a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 16:16:21 +0000 Subject: [PATCH 012/310] Complete border reference. --- docs/styles/border.md | 98 +++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 26 deletions(-) diff --git a/docs/styles/border.md b/docs/styles/border.md index 757ce988b..710bcb601 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -1,50 +1,77 @@ # Border -The `border` rule enables the drawing of a box around a widget. A border is set with a border value (see below) followed by a color. +The `border` rule enables the drawing of a box around a widget. A border is set with a border type (see below) and a 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. ## Syntax ``` -border: [] []; -border-top: [] []; -border-right: [] []; -border-bottom: [] []; -border-left: [] []; +border: [] []; +border-top: [] []; +border-right: [] []; +border-bottom: [] []; +border-left: [] []; ``` -### Values +### Border types -| Border value | Description | -|--------------|---------------------------------------------------------| -| `"ascii"` | A border with plus, hyphen, and vertical bar | -| `"blank"` | A blank border (reserves space for a border) | -| `"dashed"` | Dashed line border | -| `"double"` | Double lined border | -| `"heavy"` | Heavy border | -| `"hidden"` | Alias for "none" | -| `"hkey"` | Horizontal key-line border | -| `"inner"` | Thick solid border | -| `"none"` | Disabled border | -| `"outer"` | Think solid border with additional space around content | -| `"round"` | Rounded corners | -| `"solid"` | Solid border | -| `"tall"` | Solid border with extras space top and bottom | -| `"vkey"` | Vertical key-line border | -| `"wide"` | Solid border with additional space left and right | +| Border type | Description | +|-------------|---------------------------------------------------------| +| `"ascii"` | A border with plus, hyphen, and vertical bar characters | +| `"blank"` | A blank border (reserves space for a border) | +| `"dashed"` | Dashed line border | +| `"double"` | Double lined border | +| `"heavy"` | Heavy border | +| `"hidden"` | Alias for "none" | +| `"hkey"` | Horizontal key-line border | +| `"inner"` | Thick solid border | +| `"none"` | Disabled border | +| `"outer"` | Solid border with additional space around content | +| `"round"` | Rounded corners | +| `"solid"` | Solid border | +| `"tall"` | Solid border with extras space top and bottom | +| `"vkey"` | Vertical key-line border | +| `"wide"` | Solid border with additional space left and right | For example, `heavy white` would display a heavy white line around a widget. +### Color syntax + +--8<-- "docs/styles/snippets/color_css_syntax.md" + +### Multiple edge rules + +If multiple border rules target the same edge, the last rule 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 a border color is specified but the border type is omitted, it defaults to solid. +If a border type is specified but the border color is omitted, it defaults to green (RGB color `"#00FF00"`). + ## Border command -The `textual` CLI has a subcommand which will let you explore the various border types: +The `textual` CLI has a subcommand which will let you explore the various border types interactively: ``` textual borders ``` -## Example +Alternatively, you can see the examples below. + +## Examples This examples shows three widgets with different border styles. @@ -65,6 +92,25 @@ This examples shows three widgets with different border styles. ```{.textual path="docs/examples/styles/border.py"} ``` +The next example shows a grid with all the available border types. + +=== "border_all.py" + + ```py + --8<-- "docs/examples/styles/border_all.py" + ``` + +=== "border_all.css" + + ```css + --8<-- "docs/examples/styles/border_all.css" + ``` + +=== "Output" + + ```{.textual path="docs/examples/styles/border_all.py"} + ``` + ## CSS ```sass From 6139e9d6b456ee7c6afeebaa465f1a38be5ac9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 16:22:35 +0000 Subject: [PATCH 013/310] Mention theme variables for colors. --- docs/styles/snippets/color_css_syntax.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/styles/snippets/color_css_syntax.md b/docs/styles/snippets/color_css_syntax.md index e15897f5f..57bf87c0f 100644 --- a/docs/styles/snippets/color_css_syntax.md +++ b/docs/styles/snippets/color_css_syntax.md @@ -2,6 +2,7 @@ The legal values for `` are dependant on the [class `Color`][textual.colo - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); - - a color description in the HSL system (e.g., `hsl(290,70%,80%)`) + - a color description in the HSL system (e.g., `hsl(290,70%,80%)`); and + - a color variable from [Textual's default themes](../../guide/design#theme-reference). For more details about the exact formats accepted, see [the class method `Color.parse`][textual.color.Color.parse]. From 11e41ad2e94e6ae91bc7155dd02f6a058fdde3bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 16:24:11 +0000 Subject: [PATCH 014/310] Fix typo. --- docs/styles/box_sizing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/styles/box_sizing.md b/docs/styles/box_sizing.md index bc089ad44..819c9b305 100644 --- a/docs/styles/box_sizing.md +++ b/docs/styles/box_sizing.md @@ -18,7 +18,7 @@ box-sizing: [border-box|content-box]; ## Example Both widgets in this example have the same height (5). -The top widget has `box-sizing: border-box` which means that padding and border reduces the space for content. +The top widget has `box-sizing: border-box` which means that padding and border reduce the space for content. The bottom widget has `box-sizing: content-box` which increases the size of the widget to compensate for padding and border. === "box_sizing.py" From f0ea8a8664a38b62ac5ebdc0b8b3f59cf6db0796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 17:24:23 +0000 Subject: [PATCH 015/310] Replace statics with labels. --- docs/examples/styles/color.css | 9 +++++---- docs/examples/styles/color.py | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/examples/styles/color.css b/docs/examples/styles/color.css index b5552495a..b44a0d02e 100644 --- a/docs/examples/styles/color.css +++ b/docs/examples/styles/color.css @@ -1,13 +1,14 @@ -Static { +Label { height:1fr; content-align: center middle; + width: 100%; } -#static1 { +#label1 { color: red; } -#static2 { +#label2 { color: rgb(0, 255, 0); } -#static3 { +#label3 { color: hsl(240, 100%, 50%) } diff --git a/docs/examples/styles/color.py b/docs/examples/styles/color.py index 26543b0a0..0f10ea39e 100644 --- a/docs/examples/styles/color.py +++ b/docs/examples/styles/color.py @@ -1,12 +1,12 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label class ColorApp(App): def compose(self): - yield Static("I'm red!", id="static1") - yield Static("I'm rgb(0, 255, 0)!", id="static2") - yield Static("I'm hsl(240, 100%, 50%)!", id="static3") + yield Label("I'm red!", id="label1") + yield Label("I'm rgb(0, 255, 0)!", id="label2") + yield Label("I'm hsl(240, 100%, 50%)!", id="label3") app = ColorApp(css_path="color.css") From decdc892e9d2b9f22cd155c69fb3d800b0c6da1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 17:25:39 +0000 Subject: [PATCH 016/310] Add example to show auto selection of text color. --- docs/examples/styles/color_auto.css | 26 ++++++++++++++++++++++++++ docs/examples/styles/color_auto.py | 14 ++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 docs/examples/styles/color_auto.css create mode 100644 docs/examples/styles/color_auto.py diff --git a/docs/examples/styles/color_auto.css b/docs/examples/styles/color_auto.css new file mode 100644 index 000000000..08fab1d0f --- /dev/null +++ b/docs/examples/styles/color_auto.css @@ -0,0 +1,26 @@ +Label { + color: auto 80%; + content-align: center middle; + height: 1fr; + width: 100%; +} + +#lbl1 { + background: red 80%; +} + +#lbl2 { + background: yellow 80%; +} + +#lbl3 { + background: blue 80%; +} + +#lbl4 { + background: pink 80%; +} + +#lbl5 { + background: green 80%; +} diff --git a/docs/examples/styles/color_auto.py b/docs/examples/styles/color_auto.py new file mode 100644 index 000000000..5202415c5 --- /dev/null +++ b/docs/examples/styles/color_auto.py @@ -0,0 +1,14 @@ +from textual.app import App +from textual.widgets import Label + + +class ColorApp(App): + def compose(self): + yield Label("The quick brown fox jumps over the lazy dog!", id="lbl1") + yield Label("The quick brown fox jumps over the lazy dog!", id="lbl2") + yield Label("The quick brown fox jumps over the lazy dog!", id="lbl3") + yield Label("The quick brown fox jumps over the lazy dog!", id="lbl4") + yield Label("The quick brown fox jumps over the lazy dog!", id="lbl5") + + +app = ColorApp(css_path="color_auto.css") From 426aaf263c9ffc0d1556b5c83b11b0d25be50e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 17:25:52 +0000 Subject: [PATCH 017/310] Complete CSS color reference. --- docs/styles/color.md | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/docs/styles/color.md b/docs/styles/color.md index 0fae0a0b0..e9a6a74b6 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -1,16 +1,22 @@ # Color -The `color` rule sets the text color of a Widget. +The `color` rule sets the text color of a widget. ## Syntax ``` -color: | auto []; +color: ( | auto) []; ``` -## Example +Use `auto` to automatically choose a color with suitable contrast for readability. -This example sets a different text color to three different widgets. +--8<-- "docs/styles/snippets/color_css_syntax.md" + +The optional percentage sets the transparency level. + +## Examples + +This example sets a different text color for each of three different widgets. === "color.py" @@ -29,6 +35,25 @@ This example sets a different text color to three different widgets. ```{.textual path="docs/examples/styles/color.py"} ``` +The next example shows how `auto` chooses between a lighter or a darker text color to increase the contrast and improve readability. + +=== "color_auto.py" + + ```py + --8<-- "docs/examples/styles/color_auto.py" + ``` + +=== "color_auto.css" + + ```css hl_lines="2" + --8<-- "docs/examples/styles/color_auto.css" + ``` + +=== "Output" + + ```{.textual path="docs/examples/styles/color_auto.py"} + ``` + ## CSS ```sass @@ -56,5 +81,4 @@ widget.styles.color = "blue" from textual.color import Color # Set with a color object widget.styles.color = Color.parse("pink") - ``` From e5ef92d4432ad29ab543c11f695b2273ce165277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 17:43:16 +0000 Subject: [PATCH 018/310] Add remark not to confuse with . --- docs/styles/align.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/styles/align.md b/docs/styles/align.md index 24692e611..d3a3927db 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -1,6 +1,10 @@ # Align The `align` style aligns children within a container. +Not to be confused with [`content-align`](../content_align). + +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. ## Syntax From 03a2e3080ac166f343733790de01bbb52ba75ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:09:13 +0000 Subject: [PATCH 019/310] Add CSS and Python syntax for individual axis alignment. --- docs/styles/align.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/styles/align.md b/docs/styles/align.md index d3a3927db..028b475ee 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -81,8 +81,13 @@ Each label has been aligned differently inside its container, and its text shows ```sass /* Align child widgets to the center. */ align: center middle; -/* Align child widget to th top right */ +/* Align child widget to the top right */ align: right top; + +/* Change the horizontal alignment of the children of a widget */ +align-horizontal: right; +/* Change the vertical alignment of the children of a widget */ +align-vertical: middle; ``` ## Python @@ -91,4 +96,9 @@ align: right top; widget.styles.align = ("center", "middle") # Align child widgets to the top right widget.styles.align = ("right", "top") + +# Change the horizontal alignment of the children of a widget +widget.styles.align_horizontal = "right" +# Change the vertical alignment of the children of a widget +widget.styles.align_vertical = "middle" ``` From ddd2e25038cbcec4e0f6b32339ecc4eef5a2f25f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:10:02 +0000 Subject: [PATCH 020/310] Change statics to labels. --- docs/examples/styles/content_align.css | 6 ++++-- docs/examples/styles/content_align.py | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/examples/styles/content_align.css b/docs/examples/styles/content_align.css index 7024809b0..c195a9fff 100644 --- a/docs/examples/styles/content_align.css +++ b/docs/examples/styles/content_align.css @@ -4,7 +4,8 @@ } #box2 { - content-align: center middle; + content-align-horizontal: center; + content-align-vertical: middle; background: green; } @@ -13,7 +14,8 @@ background: blue; } -Static { +Label { + width: 100%; height: 1fr; padding: 1; color: white; diff --git a/docs/examples/styles/content_align.py b/docs/examples/styles/content_align.py index c0213c63e..25bb3b29c 100644 --- a/docs/examples/styles/content_align.py +++ b/docs/examples/styles/content_align.py @@ -1,12 +1,12 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label class ContentAlignApp(App): def compose(self): - yield Static("With [i]content-align[/] you can...", id="box1") - yield Static("...[b]Easily align content[/]...", id="box2") - yield Static("...Horizontally [i]and[/] vertically!", id="box3") + yield Label("With [i]content-align[/] you can...", id="box1") + yield Label("...[b]Easily align content[/]...", id="box2") + yield Label("...Horizontally [i]and[/] vertically!", id="box3") app = ContentAlignApp(css_path="content_align.css") From 378f25a2b4d07663a659e8c7a2dd991543b1a20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:10:22 +0000 Subject: [PATCH 021/310] Add example app with content alignment grid. --- docs/examples/styles/content_align_all.css | 39 ++++++++++++++++++++++ docs/examples/styles/content_align_all.py | 18 ++++++++++ 2 files changed, 57 insertions(+) create mode 100644 docs/examples/styles/content_align_all.css create mode 100644 docs/examples/styles/content_align_all.py diff --git a/docs/examples/styles/content_align_all.css b/docs/examples/styles/content_align_all.css new file mode 100644 index 000000000..1d1e099a3 --- /dev/null +++ b/docs/examples/styles/content_align_all.css @@ -0,0 +1,39 @@ +#left-top { + /* content-align: left top; this is the default implied value. */ +} +#center-top { + content-align: center top; +} +#right-top { + content-align: right top; +} +#left-middle { + content-align: left middle; +} +#center-middle { + content-align: center middle; +} +#right-middle { + content-align: right middle; +} +#left-bottom { + content-align: left bottom; +} +#center-bottom { + content-align: center bottom; +} +#right-bottom { + content-align: right bottom; +} + +Screen { + layout: grid; + grid-size: 3 3; + grid-gutter: 1; +} + +Label { + width: 100%; + height: 100%; + background: $primary; +} diff --git a/docs/examples/styles/content_align_all.py b/docs/examples/styles/content_align_all.py new file mode 100644 index 000000000..046011667 --- /dev/null +++ b/docs/examples/styles/content_align_all.py @@ -0,0 +1,18 @@ +from textual.app import App +from textual.widgets import Label + + +class AllContentAlignApp(App): + def compose(self): + yield Label("left top", id="left-top") + yield Label("center top", id="center-top") + yield Label("right top", id="right-top") + yield Label("left middle", id="left-middle") + yield Label("center middle", id="center-middle") + yield Label("right middle", id="right-middle") + yield Label("left bottom", id="left-bottom") + yield Label("center bottom", id="center-bottom") + yield Label("right bottom", id="right-bottom") + + +app = AllContentAlignApp(css_path="content_align_all.css") From 155f5ede7b68bc0634c721385ec14c2d8ea3a0e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:10:36 +0000 Subject: [PATCH 022/310] Complete reference for content-align. --- docs/styles/content_align.md | 43 +++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/styles/content_align.md b/docs/styles/content_align.md index 35a4a4c57..b085e5cb3 100644 --- a/docs/styles/content_align.md +++ b/docs/styles/content_align.md @@ -1,13 +1,18 @@ # Content-align The `content-align` style aligns content _inside_ a widget. +Not to be confused with [`align`](../align). + +You can specify the alignment of content on both the horizontal and vertical axes at the same time, +or on each of the axis separately. -You can specify the alignment of content on both the horizontal and vertical axes. ## Syntax ``` content-align: ; +content-align-horizontal: ; +content-align-vertical: ; ``` ### Values @@ -28,7 +33,9 @@ content-align: ; | `middle` | Align content in the middle of the vertical axis | | `bottom` | Align content at the bottom of the vertical axis | -## Example +## Examples + +This first example shows three labels stacked vertically, each with different content alignments. === "content_align.py" @@ -38,7 +45,7 @@ content-align: ; === "content_align.css" - ```scss + ```scss hl_lines="2 7-8 13" --8<-- "docs/examples/styles/content_align.css" ``` @@ -47,6 +54,26 @@ content-align: ; ```{.textual path="docs/examples/styles/content_align.py"} ``` +The next example shows a 3 by 3 grid of labels. +Each label has its text aligned differently. + +=== "content_align_all.py" + + ```py + --8<-- "docs/examples/styles/content_align_all.py" + ``` + +=== "content_align_all.css" + + ```css + --8<-- "docs/examples/styles/content_align_all.css" + ``` + +=== "Output" + + ```{.textual path="docs/examples/styles/content_align_all.py"} + ``` + ## CSS ```sass @@ -54,6 +81,11 @@ content-align: ; content-align: center middle; /* Align content at the top right of a widget */ content-align: right top; + +/* Change the horizontal alignment of the content of a widget */ +content-align-horizontal: right; +/* Change the vertical alignment of the content of a widget */ +content-align-vertical: middle; ``` ## Python @@ -62,4 +94,9 @@ content-align: right top; widget.styles.content_align = ("center", "middle") # Align content at the top right of a widget widget.styles.content_align = ("right", "top") + +# Change the horizontal alignment of the content of a widget +widget.styles.content_align_horizontal = "right" +# Change the vertical alignment of the content of a widget +widget.styles.content_align_vertical = "middle" ``` From 4d810fcf0b8a47aa7d7f23028dcec1ee2b3d9c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:20:50 +0000 Subject: [PATCH 023/310] Minor tweaks. --- docs/styles/display.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/styles/display.md b/docs/styles/display.md index 5462367d4..12a72808f 100644 --- a/docs/styles/display.md +++ b/docs/styles/display.md @@ -5,19 +5,19 @@ The `display` property defines whether a widget is displayed or not. ## Syntax ``` -display: [none|block]; +display: none | block; ``` ### Values -| Value | Description | -|-------------------|---------------------------------------------------------------------------| -| `block` (default) | Display the widget as normal | -| `none` | The widget not be displayed, and space will no longer be reserved for it. | +| Value | Description | +|-------------------|--------------------------------------------------------------------------| +| `block` (default) | Display the widget as normal. | +| `none` | The widget is not displayed and space will no longer be reserved for it. | ## Example -Note that the second widget is hidden by adding the `"remove"` class which sets the display style to None. +Note that the second widget is hidden by adding the `"remove"` class which sets the display style to `none`. === "display.py" @@ -39,10 +39,10 @@ Note that the second widget is hidden by adding the `"remove"` class which sets ## CSS ```sass -/* Widget is on screen */ +/* Widget is shown */ display: block; -/* Widget is not on the screen */ +/* Widget is not shown */ display: none; ``` From 9c10dcf80e783d5441cb08e0ae7c109fad17bb38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:59:57 +0000 Subject: [PATCH 024/310] Add dock example with four docks. --- docs/examples/styles/dock_all.css | 34 +++++++++++++++++++++++++++++++ docs/examples/styles/dock_all.py | 17 ++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 docs/examples/styles/dock_all.css create mode 100644 docs/examples/styles/dock_all.py diff --git a/docs/examples/styles/dock_all.css b/docs/examples/styles/dock_all.css new file mode 100644 index 000000000..2a78c8616 --- /dev/null +++ b/docs/examples/styles/dock_all.css @@ -0,0 +1,34 @@ +#left { + dock: left; + height: 100%; + width: auto; + align-vertical: middle; +} +#top { + dock: top; + height: auto; + width: 100%; + align-horizontal: center; +} +#right { + dock: right; + height: 100%; + width: auto; + align-vertical: middle; +} +#bottom { + dock: bottom; + height: auto; + width: 100%; + align-horizontal: center; +} + +Screen { + align: center middle; +} + +#big_container { + width: 75%; + height: 75%; + border: round white; +} diff --git a/docs/examples/styles/dock_all.py b/docs/examples/styles/dock_all.py new file mode 100644 index 000000000..30907f98a --- /dev/null +++ b/docs/examples/styles/dock_all.py @@ -0,0 +1,17 @@ +from textual.app import App +from textual.containers import Container +from textual.widgets import Label + + +class DockAllApp(App): + def compose(self): + yield Container( + Container(Label("left"), id="left"), + Container(Label("top"), id="top"), + Container(Label("right"), id="right"), + Container(Label("bottom"), id="bottom"), + id="big_container", + ) + + +app = DockAllApp(css_path="dock_all.css") From 22351a7cfb7b79add69d537a2b7df5803ee28f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 15 Dec 2022 19:00:16 +0000 Subject: [PATCH 025/310] Add example to dock reference. --- docs/styles/dock.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/styles/dock.md b/docs/styles/dock.md index 875358614..5a71eb6f9 100644 --- a/docs/styles/dock.md +++ b/docs/styles/dock.md @@ -5,10 +5,10 @@ The `dock` property is used to fix a widget to the edge of a container (which ma ## Syntax ``` -dock: top|right|bottom|left; +dock: top | right | bottom | left; ``` -## Example +## Examples The example below shows a `left` docked sidebar. Notice that even though the content is scrolled, the sidebar remains fixed. @@ -30,6 +30,26 @@ Notice that even though the content is scrolled, the sidebar remains fixed. --8<-- "docs/examples/guide/layout/dock_layout1_sidebar.css" ``` +The second example shows how one can use full-width or full-height containers to dock labels to the edges of a larger container. +The labels will remain in that position (docked) even if the container they are in scrolls horizontally and/or vertically. + +=== "Output" + + ```{.textual path="docs/examples/styles/dock_all.py"} + ``` + +=== "dock_all.py" + + ```py + --8<-- "docs/examples/styles/dock_all.py" + ``` + +=== "dock_all.css" + + ```css hl_lines="2-5 8-11 14-17 20-23" + --8<-- "docs/examples/styles/dock_all.css" + ``` + ## CSS ```sass From 9e7c4f4f4ab667b17bc7cab3b89e606ee4667c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 10:13:20 +0000 Subject: [PATCH 026/310] Split grid reference into subpages. --- docs/styles/grid/column_span.md | 1 + docs/styles/grid/grid_columns.md | 1 + docs/styles/grid/grid_gutter.md | 1 + docs/styles/grid/grid_rows.md | 1 + docs/styles/grid/grid_size.md | 1 + docs/styles/{grid.md => grid/index.md} | 0 docs/styles/grid/row_span.md | 1 + mkdocs.yml | 9 ++++++++- 8 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 docs/styles/grid/column_span.md create mode 100644 docs/styles/grid/grid_columns.md create mode 100644 docs/styles/grid/grid_gutter.md create mode 100644 docs/styles/grid/grid_rows.md create mode 100644 docs/styles/grid/grid_size.md rename docs/styles/{grid.md => grid/index.md} (100%) create mode 100644 docs/styles/grid/row_span.md diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md new file mode 100644 index 000000000..4bf511a8c --- /dev/null +++ b/docs/styles/grid/column_span.md @@ -0,0 +1 @@ +# Column-span diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md new file mode 100644 index 000000000..f2f5e4fe3 --- /dev/null +++ b/docs/styles/grid/grid_columns.md @@ -0,0 +1 @@ +# Grid-columns diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md new file mode 100644 index 000000000..28f309dc0 --- /dev/null +++ b/docs/styles/grid/grid_gutter.md @@ -0,0 +1 @@ +# Grid-gutter diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md new file mode 100644 index 000000000..34bfd043c --- /dev/null +++ b/docs/styles/grid/grid_rows.md @@ -0,0 +1 @@ +# Grid-rows diff --git a/docs/styles/grid/grid_size.md b/docs/styles/grid/grid_size.md new file mode 100644 index 000000000..0dbf58784 --- /dev/null +++ b/docs/styles/grid/grid_size.md @@ -0,0 +1 @@ +# Grid-size diff --git a/docs/styles/grid.md b/docs/styles/grid/index.md similarity index 100% rename from docs/styles/grid.md rename to docs/styles/grid/index.md diff --git a/docs/styles/grid/row_span.md b/docs/styles/grid/row_span.md new file mode 100644 index 000000000..d05182ace --- /dev/null +++ b/docs/styles/grid/row_span.md @@ -0,0 +1 @@ +# Row-span diff --git a/mkdocs.yml b/mkdocs.yml index 4f3247d92..7575fea5f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -63,7 +63,14 @@ nav: - "styles/content_align.md" - "styles/display.md" - "styles/dock.md" - - "styles/grid.md" + - Grid: + - "styles/grid/index.md" + - "styles/grid/grid_size.md" + - "styles/grid/grid_rows.md" + - "styles/grid/grid_columns.md" + - "styles/grid/grid_gutter.md" + - "styles/grid/row_span.md" + - "styles/grid/column_span.md" - "styles/height.md" - "styles/layer.md" - "styles/layers.md" From b87d1c2e4a8737d84e933b36573564eebefa8888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 10:19:44 +0000 Subject: [PATCH 027/310] Add pages for CSS units. --- docs/styles/css_units/color.md | 15 +++++++++++++++ docs/styles/css_units/index.md | 10 ++++++++++ docs/styles/css_units/integer.md | 1 + docs/styles/css_units/percentage.md | 1 + docs/styles/css_units/scalar.md | 1 + mkdocs.yml | 6 ++++++ 6 files changed, 34 insertions(+) create mode 100644 docs/styles/css_units/color.md create mode 100644 docs/styles/css_units/index.md create mode 100644 docs/styles/css_units/integer.md create mode 100644 docs/styles/css_units/percentage.md create mode 100644 docs/styles/css_units/scalar.md diff --git a/docs/styles/css_units/color.md b/docs/styles/css_units/color.md new file mode 100644 index 000000000..f5574c559 --- /dev/null +++ b/docs/styles/css_units/color.md @@ -0,0 +1,15 @@ +# Color unit + +!!! warning + + Not to be confused with the [`color`](../color.md) CSS rule to set text color. + +## Syntax + +--8<-- "../snippets/color_css_syntax.md" + +## Used by + + - [`background`](../background.md) + - [`border`](../border.md) + - [`color`](../color.md) diff --git a/docs/styles/css_units/index.md b/docs/styles/css_units/index.md new file mode 100644 index 000000000..3e9f7bb1f --- /dev/null +++ b/docs/styles/css_units/index.md @@ -0,0 +1,10 @@ +# CSS units + +Many CSS rules accept units of some sort, as opposed to a set of values. + +The different CSS units are: + + - [color](./color.md) – e.g., to set the [background color](../background.md); + - [integer](./integer.md) – e.g., to set the [`grid-size`](../grid/grid_size.md); + - [percentage](./percentage.md) – e.g., to set the transparency of the [background color](../background.md); and + - [scalar](./scalar.md) – e.g., to set the [width](../width.md) of a widget. diff --git a/docs/styles/css_units/integer.md b/docs/styles/css_units/integer.md new file mode 100644 index 000000000..52361c807 --- /dev/null +++ b/docs/styles/css_units/integer.md @@ -0,0 +1 @@ +# Integer diff --git a/docs/styles/css_units/percentage.md b/docs/styles/css_units/percentage.md new file mode 100644 index 000000000..556753e81 --- /dev/null +++ b/docs/styles/css_units/percentage.md @@ -0,0 +1 @@ +# Percentage diff --git a/docs/styles/css_units/scalar.md b/docs/styles/css_units/scalar.md new file mode 100644 index 000000000..7b3723c22 --- /dev/null +++ b/docs/styles/css_units/scalar.md @@ -0,0 +1 @@ +# Scalar diff --git a/mkdocs.yml b/mkdocs.yml index 7575fea5f..a8c59f569 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -54,6 +54,12 @@ nav: - "events/screen_suspend.md" - "events/show.md" - Styles: + - CSS units: + - "styles/css_units/index.md" + - "styles/css_units/color.md" + - "styles/css_units/integer.md" + - "styles/css_units/percentage.md" + - "styles/css_units/scalar.md" - "styles/index.md" - "styles/align.md" - "styles/background.md" From 482e28bbf6f9b9c7000fc64da4f9d93fb770f945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 10:50:59 +0000 Subject: [PATCH 028/310] Add pages for all links rules. --- docs/styles/css_units/color.md | 28 ++++++++++++++++++++++ docs/styles/{links.md => links/index.md} | 0 docs/styles/links/link_background.md | 0 docs/styles/links/link_color.md | 0 docs/styles/links/link_hover_background.md | 0 docs/styles/links/link_hover_color.md | 0 docs/styles/links/link_hover_style.md | 0 docs/styles/links/link_style.md | 0 mkdocs.yml | 9 ++++++- 9 files changed, 36 insertions(+), 1 deletion(-) rename docs/styles/{links.md => links/index.md} (100%) create mode 100644 docs/styles/links/link_background.md create mode 100644 docs/styles/links/link_color.md create mode 100644 docs/styles/links/link_hover_background.md create mode 100644 docs/styles/links/link_hover_color.md create mode 100644 docs/styles/links/link_hover_style.md create mode 100644 docs/styles/links/link_style.md diff --git a/docs/styles/css_units/color.md b/docs/styles/css_units/color.md index f5574c559..c770954b3 100644 --- a/docs/styles/css_units/color.md +++ b/docs/styles/css_units/color.md @@ -8,6 +8,34 @@ --8<-- "../snippets/color_css_syntax.md" +## Examples + +```css +Widget { + color: red; + color: #A8F; + color: #FF00FFDD; + color: rgb(15,200,73); + color: hsl(300,20,70); + color: $accent; +} +``` + +```py +# Mimicking the CSS syntax +widget.styles.color = "red" +widget.styles.color = "#A8F" +widget.styles.color = "#FF00FFDD" +widget.styles.color = "rgb(15,200,73)" +widget.styles.color = "hsl(300,20,70)" +widget.styles.color = "$accent" + +# Using a Color object directly... +widget.styles.color = Color(16, 200, 45) +# ... which can parse the CSS syntax +widget.styles.color = Color.parse("#A8F") +``` + ## Used by - [`background`](../background.md) diff --git a/docs/styles/links.md b/docs/styles/links/index.md similarity index 100% rename from docs/styles/links.md rename to docs/styles/links/index.md diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/styles/links/link_color.md b/docs/styles/links/link_color.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/styles/links/link_hover_background.md b/docs/styles/links/link_hover_background.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/styles/links/link_hover_style.md b/docs/styles/links/link_hover_style.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md new file mode 100644 index 000000000..e69de29bb diff --git a/mkdocs.yml b/mkdocs.yml index a8c59f569..507d13bee 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -81,7 +81,14 @@ nav: - "styles/layer.md" - "styles/layers.md" - "styles/layout.md" - - "styles/links.md" + - Links: + - "styles/links/index.md" + - "styles/links/link_color.md" + - "styles/links/link_background.md" + - "styles/links/link_style.md" + - "styles/links/link_hover_color.md" + - "styles/links/link_hover_background.md" + - "styles/links/link_hover_style.md" - "styles/margin.md" - "styles/max_height.md" - "styles/max_width.md" From fbe763fde085d0502e059e88891cbad118644d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 10:54:55 +0000 Subject: [PATCH 029/310] Add pages for all scrollbar color rules. --- .../styles/{scrollbar.md => scrollbar_colors/index.md} | 0 docs/styles/scrollbar_colors/scrollbar_background.md | 1 + .../scrollbar_colors/scrollbar_background_active.md | 1 + .../scrollbar_colors/scrollbar_background_hover.md | 1 + docs/styles/scrollbar_colors/scrollbar_color.md | 1 + docs/styles/scrollbar_colors/scrollbar_color_active.md | 1 + docs/styles/scrollbar_colors/scrollbar_color_hover.md | 1 + docs/styles/scrollbar_colors/scrollbar_corner_color.md | 1 + mkdocs.yml | 10 +++++++++- 9 files changed, 16 insertions(+), 1 deletion(-) rename docs/styles/{scrollbar.md => scrollbar_colors/index.md} (100%) create mode 100644 docs/styles/scrollbar_colors/scrollbar_background.md create mode 100644 docs/styles/scrollbar_colors/scrollbar_background_active.md create mode 100644 docs/styles/scrollbar_colors/scrollbar_background_hover.md create mode 100644 docs/styles/scrollbar_colors/scrollbar_color.md create mode 100644 docs/styles/scrollbar_colors/scrollbar_color_active.md create mode 100644 docs/styles/scrollbar_colors/scrollbar_color_hover.md create mode 100644 docs/styles/scrollbar_colors/scrollbar_corner_color.md diff --git a/docs/styles/scrollbar.md b/docs/styles/scrollbar_colors/index.md similarity index 100% rename from docs/styles/scrollbar.md rename to docs/styles/scrollbar_colors/index.md diff --git a/docs/styles/scrollbar_colors/scrollbar_background.md b/docs/styles/scrollbar_colors/scrollbar_background.md new file mode 100644 index 000000000..e8432f8dd --- /dev/null +++ b/docs/styles/scrollbar_colors/scrollbar_background.md @@ -0,0 +1 @@ +# Scrollbar-background diff --git a/docs/styles/scrollbar_colors/scrollbar_background_active.md b/docs/styles/scrollbar_colors/scrollbar_background_active.md new file mode 100644 index 000000000..b1c08d764 --- /dev/null +++ b/docs/styles/scrollbar_colors/scrollbar_background_active.md @@ -0,0 +1 @@ +# Scrollbar-background-active diff --git a/docs/styles/scrollbar_colors/scrollbar_background_hover.md b/docs/styles/scrollbar_colors/scrollbar_background_hover.md new file mode 100644 index 000000000..e3eac7c8e --- /dev/null +++ b/docs/styles/scrollbar_colors/scrollbar_background_hover.md @@ -0,0 +1 @@ +# Scrollbar-background-hover diff --git a/docs/styles/scrollbar_colors/scrollbar_color.md b/docs/styles/scrollbar_colors/scrollbar_color.md new file mode 100644 index 000000000..651c89489 --- /dev/null +++ b/docs/styles/scrollbar_colors/scrollbar_color.md @@ -0,0 +1 @@ +# Scrollbar-color diff --git a/docs/styles/scrollbar_colors/scrollbar_color_active.md b/docs/styles/scrollbar_colors/scrollbar_color_active.md new file mode 100644 index 000000000..144a5d365 --- /dev/null +++ b/docs/styles/scrollbar_colors/scrollbar_color_active.md @@ -0,0 +1 @@ +# Scrollbar-color-active diff --git a/docs/styles/scrollbar_colors/scrollbar_color_hover.md b/docs/styles/scrollbar_colors/scrollbar_color_hover.md new file mode 100644 index 000000000..4529c5817 --- /dev/null +++ b/docs/styles/scrollbar_colors/scrollbar_color_hover.md @@ -0,0 +1 @@ +# Scrollbar-color-hover diff --git a/docs/styles/scrollbar_colors/scrollbar_corner_color.md b/docs/styles/scrollbar_colors/scrollbar_corner_color.md new file mode 100644 index 000000000..fb418249c --- /dev/null +++ b/docs/styles/scrollbar_colors/scrollbar_corner_color.md @@ -0,0 +1 @@ +# Scrollbar-corner-color diff --git a/mkdocs.yml b/mkdocs.yml index 507d13bee..54f046f2d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -99,7 +99,15 @@ nav: - "styles/outline.md" - "styles/overflow.md" - "styles/padding.md" - - "styles/scrollbar.md" + - Scrollbar colors: + - "styles/scrollbar_colors/index.md" + - "styles/scrollbar_colors/scrollbar_color.md" + - "styles/scrollbar_colors/scrollbar_color_hover.md" + - "styles/scrollbar_colors/scrollbar_color_active.md" + - "styles/scrollbar_colors/scrollbar_background.md" + - "styles/scrollbar_colors/scrollbar_background_hover.md" + - "styles/scrollbar_colors/scrollbar_background_active.md" + - "styles/scrollbar_colors/scrollbar_corner_color.md" - "styles/scrollbar_gutter.md" - "styles/scrollbar_size.md" - "styles/text_align.md" From 93eacff505b5fa6e76d63a28f3d27d1285da5ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 11:12:20 +0000 Subject: [PATCH 030/310] Complete color unit reference. --- docs/styles/css_units/color.md | 50 ++++++++++++++++-------- docs/styles/snippets/color_css_syntax.md | 1 + 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/docs/styles/css_units/color.md b/docs/styles/css_units/color.md index c770954b3..18297fc1c 100644 --- a/docs/styles/css_units/color.md +++ b/docs/styles/css_units/color.md @@ -1,39 +1,42 @@ # Color unit +Color units are used with rules that need to set the color of a part of a widget. +For example, the `background` rule sets the color of the background of a widget. + !!! warning Not to be confused with the [`color`](../color.md) CSS rule to set text color. ## Syntax ---8<-- "../snippets/color_css_syntax.md" +--8<-- "docs/styles/snippets/color_css_syntax.md" ## Examples ```css Widget { - color: red; - color: #A8F; - color: #FF00FFDD; - color: rgb(15,200,73); - color: hsl(300,20,70); - color: $accent; + background: red; /* color name */ + background: #A8F; /* 3-digit hex RGB */ + background: #FF00FFDD; /* 6-digit hex RGB + transparency */ + background: rgb(15,200,73); /* RGB description */ + background: hsl(300,20%,70%); /* HSL description */ + background: $accent; /* Textual variable */ } ``` ```py # Mimicking the CSS syntax -widget.styles.color = "red" -widget.styles.color = "#A8F" -widget.styles.color = "#FF00FFDD" -widget.styles.color = "rgb(15,200,73)" -widget.styles.color = "hsl(300,20,70)" -widget.styles.color = "$accent" +widget.styles.background = "red" +widget.styles.background = "#A8F" +widget.styles.background = "#FF00FFDD" +widget.styles.background = "rgb(15,200,73)" +widget.styles.background = "hsl(300,20%,70%)" +widget.styles.background = "$accent" # Using a Color object directly... -widget.styles.color = Color(16, 200, 45) -# ... which can parse the CSS syntax -widget.styles.color = Color.parse("#A8F") +widget.styles.background = Color(16, 200, 45) +# ... which can also parse the CSS syntax +widget.styles.background = Color.parse("#A8F") ``` ## Used by @@ -41,3 +44,18 @@ widget.styles.color = Color.parse("#A8F") - [`background`](../background.md) - [`border`](../border.md) - [`color`](../color.md) + - Links: + - [`link-color`](../links/link_color.md) + - [`link-background`](../links/link_background.md) + - [`link-hover-color`](../links/link_hover_color.md) + - [`link-hover-background`](../links/link_hover_background.md) + - [`outline`](../outline.md) + - Scrollbars: + - [`scrollbar-color`](../scrollbar_colors/scrollbar_color.md) + - [`scrollbar-color-hover`](../scrollbar_colors/scrollbar_color_hover.md) + - [`scrollbar-color-active`](../scrollbar_colors/scrollbar_color_active.md) + - [`scrollbar-background`](../scrollbar_colors/scrollbar_background.md) + - [`scrollbar-background-hover`](../scrollbar_colors/scrollbar_background_hover.md) + - [`scrollbar-background-active`](../scrollbar_colors/scrollbar_background_active.md) + - [`scrollbar-corner-color`](../scrollbar_colors/scrollbar_corner_color.md) + - [`tint`](../tint.md) diff --git a/docs/styles/snippets/color_css_syntax.md b/docs/styles/snippets/color_css_syntax.md index 57bf87c0f..e699a41b0 100644 --- a/docs/styles/snippets/color_css_syntax.md +++ b/docs/styles/snippets/color_css_syntax.md @@ -2,6 +2,7 @@ The legal values for `` are dependant on the [class `Color`][textual.colo - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); + - a color description in the RGB system (e.g., `rgb(23,78,200)`); - a color description in the HSL system (e.g., `hsl(290,70%,80%)`); and - a color variable from [Textual's default themes](../../guide/design#theme-reference). From 9de55aa1cee725788ebab1b26888787a620931d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 11:55:20 +0000 Subject: [PATCH 031/310] Add reference for fractional. --- docs/styles/css_units/fractional.md | 28 +++++++++++++++++++++++ docs/styles/css_units/index.md | 1 + docs/styles/snippets/fractional_syntax.md | 6 +++++ mkdocs.yml | 1 + 4 files changed, 36 insertions(+) create mode 100644 docs/styles/css_units/fractional.md create mode 100644 docs/styles/snippets/fractional_syntax.md diff --git a/docs/styles/css_units/fractional.md b/docs/styles/css_units/fractional.md new file mode 100644 index 000000000..9ef896916 --- /dev/null +++ b/docs/styles/css_units/fractional.md @@ -0,0 +1,28 @@ +# Fractional + +## Syntax + +--8<-- "docs/styles/snippets/fractional_syntax.md" + +!!! warning + + Not to be confused with the [percentage](./percentage.md) unit nor with the [scalar](./scalar.md) unit. + +## Examples + +```css +Widget { + text-opacity: 0.45; + text-opacity: 45%; +} +``` + +```py +widget.styles.text_opacity = 0.45 +widget.styles.text_opacity = "45%" +``` + +## Used by + + - [`opacity`](../opacity.md) + - [`text-opacity`](../text_opacity.md) diff --git a/docs/styles/css_units/index.md b/docs/styles/css_units/index.md index 3e9f7bb1f..d98e6f722 100644 --- a/docs/styles/css_units/index.md +++ b/docs/styles/css_units/index.md @@ -5,6 +5,7 @@ Many CSS rules accept units of some sort, as opposed to a set of values. The different CSS units are: - [color](./color.md) – e.g., to set the [background color](../background.md); + - [fractional](./fractional.md) – e.g., to set a widget's [`opacity`](../opacity.md); - [integer](./integer.md) – e.g., to set the [`grid-size`](../grid/grid_size.md); - [percentage](./percentage.md) – e.g., to set the transparency of the [background color](../background.md); and - [scalar](./scalar.md) – e.g., to set the [width](../width.md) of a widget. diff --git a/docs/styles/snippets/fractional_syntax.md b/docs/styles/snippets/fractional_syntax.md new file mode 100644 index 000000000..3c41ae409 --- /dev/null +++ b/docs/styles/snippets/fractional_syntax.md @@ -0,0 +1,6 @@ +A fractional value can be set to + + - a float between 0 and 1 (e.g., `0.45`); or + - a percentage between 0% and 100% (e.g., `45%`). + +Values outside their ranges will be clamped. diff --git a/mkdocs.yml b/mkdocs.yml index 54f046f2d..37f62b80d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -57,6 +57,7 @@ nav: - CSS units: - "styles/css_units/index.md" - "styles/css_units/color.md" + - "styles/css_units/fractional.md" - "styles/css_units/integer.md" - "styles/css_units/percentage.md" - "styles/css_units/scalar.md" From dc127dad86699b995fa0f78e2d94124d53cc6ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 12:01:59 +0000 Subject: [PATCH 032/310] Add a snippet with the percentage syntax. --- docs/styles/css_units/percentage.md | 26 +++++++++++++++++++++++ docs/styles/snippets/percentage_syntax.md | 2 ++ 2 files changed, 28 insertions(+) create mode 100644 docs/styles/snippets/percentage_syntax.md diff --git a/docs/styles/css_units/percentage.md b/docs/styles/css_units/percentage.md index 556753e81..70dd51292 100644 --- a/docs/styles/css_units/percentage.md +++ b/docs/styles/css_units/percentage.md @@ -1 +1,27 @@ # Percentage + +## Syntax + +--8<-- "docs/styles/snippets/percentage_syntax.md" + +!!! warning + + Not to be confused with the [fractional](./fractional.md) unit nor with the [scalar](./scalar.md) unit. + +## Examples + +```css +Widget { + background: red 70%; +} +``` + +```py +widget.styles.background = "red 70%" +``` + +## Used by + + - [`background`](../background.md) + - [`color`](../color.md) + - [`tint`](../tint.md) diff --git a/docs/styles/snippets/percentage_syntax.md b/docs/styles/snippets/percentage_syntax.md new file mode 100644 index 000000000..212b31bc1 --- /dev/null +++ b/docs/styles/snippets/percentage_syntax.md @@ -0,0 +1,2 @@ +A percentage is a number followed by the percent sign. +The number doesn't have to be an integer and values are clamped between 0% and 100%. From 77fcac719f2d7a58826c6764f47425b1cf93d6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 12:05:31 +0000 Subject: [PATCH 033/310] Link to percentage unit. --- docs/styles/background.md | 4 +++- docs/styles/color.md | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/styles/background.md b/docs/styles/background.md index eb71f3d7f..aadfd273f 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -1,6 +1,6 @@ # Background -The `background` rule sets the background color of a widget with an optional transparency level. +The `background` rule sets the background color of a widget. ## Syntax @@ -10,6 +10,8 @@ background: []; --8<-- "docs/styles/snippets/color_css_syntax.md" +The optional [percentage](./css_units/percentage.md) sets the transparency level and will override any transparency specified directly in the color. + ## Examples This example creates three widgets and applies a different background to each. diff --git a/docs/styles/color.md b/docs/styles/color.md index e9a6a74b6..f2b85507b 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -1,6 +1,6 @@ # Color -The `color` rule sets the text color of a widget. +The `color` rule sets the text color of a widget with an optional. ## Syntax @@ -12,7 +12,7 @@ Use `auto` to automatically choose a color with suitable contrast for readabilit --8<-- "docs/styles/snippets/color_css_syntax.md" -The optional percentage sets the transparency level. +The optional [percentage](./css_units/percentage.md) sets the transparency level and will override any transparency specified directly in the color. ## Examples From 73bdd7ed43f44f54311ff803f4ade8dff1aac767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 16:11:42 +0000 Subject: [PATCH 034/310] Complete reference for scalar unit. --- docs/styles/css_units/scalar.md | 122 ++++++++++++++++++++++++++ docs/styles/snippets/scalar_syntax.md | 8 ++ 2 files changed, 130 insertions(+) create mode 100644 docs/styles/snippets/scalar_syntax.md diff --git a/docs/styles/css_units/scalar.md b/docs/styles/css_units/scalar.md index 7b3723c22..3a50d8397 100644 --- a/docs/styles/css_units/scalar.md +++ b/docs/styles/css_units/scalar.md @@ -1 +1,123 @@ # Scalar + +A scalar unit is a numeric value with a unit, e.g., `50vh`. +Scalars are used with styles that specify lengths, like `width` and `height`. + +Scalars also accept the special value `auto`. + +## Syntax + +--8<-- "docs/styles/snippets/scalar_syntax.md" + +A complete reference table and detailed explanations follow. +You can [skip to the examples](#Examples). + +| Unit symbol | Unit | Example | Description | +|-------------|-----------------|---------|-------------------------------------------------------------| +| `""` | Cell | `10` | Number of cells (rows or columns). | +| `"fr"` | Fraction | `1fr` | Specifies the proportion of space the widget should occupy. | +| `"%"` | Percent | `75%` | Length relative to the container widget. | +| `"w"` | Width | `25w` | Percentage relative to the width of the container widget. | +| `"h"` | Height | `75h` | Percentage relative to the height of the container widget. | +| `"vw"` | Viewport width | `25vw` | Percentage relative to the viewport width. | +| `"vh"` | Viewport height | `75vh` | Percentage relative to the viewport height. | +| - | Auto | `auto` | Tries to compute the optimal size to fit without scrolling. | + +### Cell + +The number of cells is the only unit for a scalar that is _absolute_. +This can be an integer or a float but floats are truncated to integers. + +If used to specify a horizontal length, it corresponds to the number of columns. +For example, in `width: 15`, this sets the width of a widget to be equal to 15 cells, which translates to 15 columns. + +If used to specify a vertical length, it corresponds to the number of lines. +For example, in `height: 10`, this sets the height of a widget to be equal to 10 cells, which translates to 10 lines. + +### Fraction + +The fraction scalar is used to represent proportional sizes. + +For example, if two widgets are side by side and one has `width: 1fr` and the other has `width: 3fr`, the second one will be three times as wide as the first one. + +### Percent + +The percent scalar is used to specify a total length relative to the space made available by the container widget. + +If used to specify a horizontal length, it will be relative to the width of the container. +For example, `width: 50%` sets the width of a widget to 50% of the width of its container. + +If used to specify a vertical length, it will be relative to the height of the container. +For example, `height: 50%` sets the height of a widget to 50% of the height of its container. + +### Width + +The width scalar is similar to the percent scalar, except it sets the percentage to be relative to the width of the container. + +For example, `width: 25w` sets the width of a widget to 25% of the width of its container and `height: 25w` sets the height of a widget to 25% of the width of its container. +So, if the container has a width of 100 cells, the width and the height of the child widget will be of 25 cells. + +### Height + +The height scalar is similar to the percent scalar, except it sets the percentage to be relative to the height of the container. + +For example, `height: 75h` sets the height of a widget to 75% of the height of its container and `width: 75h` sets the width of a widget to 75% of the height of its container. +So, if the container has a height of 100 cells, the width and the height of the child widget will be of 75 cells. + +### Viewport width + +This is the same as the [width scalar](#Width), except that it is relative to the width of the viewport instead of the width of the immediate container. + +For example, `width: 25vw` will try to set the width of a widget to be 25% of the viewport width, regardless of the widths of its containers. + +### Viewport height + +This is the same as the [height scalar](#Height), except that it is relative to the height of the viewport instead of the height of the immediate container. + +For example, `height: 75vh` will try to set the height of a widget to be 75% of the viewport height, regardless of the height of its containers. + +### Auto + +This special value will try to calculate the optimal size to fit the contents of the widget without scrolling. + +For example, if its container is big enough, a label with `width: auto` will be just as wide as its text. + +## Examples + +```css +Widget { + width: 16; + width: 1fr; + width: 50%; + width: 25w; + width: 75h; + width: 25vw; + width: 75vh; + width: auto; +} +``` + +```py +widget.styles.width = 16 # Cell scalar can be an int or a float +widget.styles.width = "1fr" +widget.styles.width = "50%" +widget.styles.width = "25w" +widget.styles.width = "75h" +widget.styles.width = "25vw" +widget.styles.width = "75vh" +widget.styles.width = "auto" +``` + +## Used by + + - Grids: + - [`grid-rows`](../grid/grid_rows.md) + - [`grid-columns`](../grid/grid_columns.md) + - [`grid-gutter`](../grid/grid_gutter.md) + - [`height`](../height.md) + - [`max-height`](../max_height.md) + - [`max-width`](../max_width.md) + - [`min-height`](../min_height.md) + - [`min-width`](../min_width.md) + - [`offset`](../offset.md) + - [`width`](../width.md) diff --git a/docs/styles/snippets/scalar_syntax.md b/docs/styles/snippets/scalar_syntax.md new file mode 100644 index 000000000..9581e271b --- /dev/null +++ b/docs/styles/snippets/scalar_syntax.md @@ -0,0 +1,8 @@ +A scalar can be any of the following: + + - a fixed number of cells (e.g., `10`); + - a fractional proportion relative to the sizes of the other widgets (e.g., `1fr`); + - a percentage relative to the container widget (e.g., `50%`); + - a percentage relative to the container width/height (e.g., `25w`/`75h`); + - a percentage relative to the viewport width/height (e.g., `25vw`/`75vh`); or + - the special value `auto` to compute the optimal size to fit without scrolling. From 0e78dce72736eaf36110feb87d7a36eda807c30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 16:24:43 +0000 Subject: [PATCH 035/310] Complete integer reference. --- docs/styles/css_units/integer.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/styles/css_units/integer.md b/docs/styles/css_units/integer.md index 52361c807..82fb5bd67 100644 --- a/docs/styles/css_units/integer.md +++ b/docs/styles/css_units/integer.md @@ -1 +1,30 @@ # Integer + +An integer unit. + +## Syntax + +Any legal integer, like `-10` or `42`. +Integer units can be negative, althought that may not make sense in some rules. + +## Examples + +```css +Widget { + margin: -5 10; +} +``` + +```py +widget.styles.offset = (-5, 10) +``` + +## Used by + + - Grids: + - [`grid-size`](../grid/grid_size.md) + - [`grid-rows`](../grid/grid_rows.md) + - [`grid-columns`](../grid/grid_columns.md) + - [`margin`](../margin.md) + - [`padding`](../padding.md) + - [`scrollbar-size`](../scrollbar_size.md) From 18a006607c9fc00c6ee03dabd0b4094a6487b47f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:09:35 +0000 Subject: [PATCH 036/310] Add example for grid rows. --- docs/examples/styles/grid_rows.css | 11 +++++++++++ docs/examples/styles/grid_rows.py | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 docs/examples/styles/grid_rows.css create mode 100644 docs/examples/styles/grid_rows.py diff --git a/docs/examples/styles/grid_rows.css b/docs/examples/styles/grid_rows.css new file mode 100644 index 000000000..bb29cb064 --- /dev/null +++ b/docs/examples/styles/grid_rows.css @@ -0,0 +1,11 @@ +Grid { + grid-size: 2 5; + grid-rows: 1fr 6 25%; +} + +Label { + border: round white; + content-align: center middle; + width: 100%; + height: 100%; +} diff --git a/docs/examples/styles/grid_rows.py b/docs/examples/styles/grid_rows.py new file mode 100644 index 000000000..ed06f7b6d --- /dev/null +++ b/docs/examples/styles/grid_rows.py @@ -0,0 +1,22 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Label + + +class MyApp(App): + def compose(self): + yield Grid( + Label("1fr"), + Label("1fr"), + Label("height = 6"), + Label("height = 6"), + Label("25%"), + Label("25%"), + Label("1fr"), + Label("1fr"), + Label("height = 6"), + Label("height = 6"), + ) + + +app = MyApp(css_path="grid_rows.css") From da51877941d339d0ff7694cc1db670eeeba6dec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:50:13 +0000 Subject: [PATCH 037/310] Add example for grid columns. --- docs/examples/styles/grid_columns.css | 11 +++++++++++ docs/examples/styles/grid_columns.py | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 docs/examples/styles/grid_columns.css create mode 100644 docs/examples/styles/grid_columns.py diff --git a/docs/examples/styles/grid_columns.css b/docs/examples/styles/grid_columns.css new file mode 100644 index 000000000..dc3aa47db --- /dev/null +++ b/docs/examples/styles/grid_columns.css @@ -0,0 +1,11 @@ +Grid { + grid-size: 5 2; + grid-columns: 1fr 16 2fr; +} + +Label { + border: round white; + content-align-horizontal: center; + width: 100%; + height: 100%; +} diff --git a/docs/examples/styles/grid_columns.py b/docs/examples/styles/grid_columns.py new file mode 100644 index 000000000..05c772d56 --- /dev/null +++ b/docs/examples/styles/grid_columns.py @@ -0,0 +1,22 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Label + + +class MyApp(App): + def compose(self): + yield Grid( + Label("1fr"), + Label("width = 16"), + Label("2fr"), + Label("1fr"), + Label("width = 16"), + Label("1fr"), + Label("width = 16"), + Label("2fr"), + Label("1fr"), + Label("width = 16"), + ) + + +app = MyApp(css_path="grid_columns.css") From 5e901458fb0ca9fdce0dd6886d741515040aefc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:01:29 +0000 Subject: [PATCH 038/310] Add grid size examples. --- docs/examples/styles/grid_size_both.css | 10 ++++++++++ docs/examples/styles/grid_size_both.py | 17 +++++++++++++++++ docs/examples/styles/grid_size_columns.css | 10 ++++++++++ docs/examples/styles/grid_size_columns.py | 17 +++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 docs/examples/styles/grid_size_both.css create mode 100644 docs/examples/styles/grid_size_both.py create mode 100644 docs/examples/styles/grid_size_columns.css create mode 100644 docs/examples/styles/grid_size_columns.py diff --git a/docs/examples/styles/grid_size_both.css b/docs/examples/styles/grid_size_both.css new file mode 100644 index 000000000..8f3c2dce5 --- /dev/null +++ b/docs/examples/styles/grid_size_both.css @@ -0,0 +1,10 @@ +Grid { + grid-size: 2 4; /* (1)! */ +} + +Label { + border: round white; + content-align: center middle; + width: 100%; + height: 100%; +} diff --git a/docs/examples/styles/grid_size_both.py b/docs/examples/styles/grid_size_both.py new file mode 100644 index 000000000..6383cc760 --- /dev/null +++ b/docs/examples/styles/grid_size_both.py @@ -0,0 +1,17 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Label + + +class MyApp(App): + def compose(self): + yield Grid( + Label("1"), + Label("2"), + Label("3"), + Label("4"), + Label("5"), + ) + + +app = MyApp(css_path="grid_size_both.css") diff --git a/docs/examples/styles/grid_size_columns.css b/docs/examples/styles/grid_size_columns.css new file mode 100644 index 000000000..1fd94d653 --- /dev/null +++ b/docs/examples/styles/grid_size_columns.css @@ -0,0 +1,10 @@ +Grid { + grid-size: 2; /* (1)! */ +} + +Label { + border: round white; + content-align: center middle; + width: 100%; + height: 100%; +} diff --git a/docs/examples/styles/grid_size_columns.py b/docs/examples/styles/grid_size_columns.py new file mode 100644 index 000000000..06be94150 --- /dev/null +++ b/docs/examples/styles/grid_size_columns.py @@ -0,0 +1,17 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Label + + +class MyApp(App): + def compose(self): + yield Grid( + Label("1"), + Label("2"), + Label("3"), + Label("4"), + Label("5"), + ) + + +app = MyApp(css_path="grid_size_columns.css") From 2bf444e01508c05ca80afc8e3794e8e745c902ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:02:12 +0000 Subject: [PATCH 039/310] Complete reference for grid size. --- docs/styles/grid/grid_size.md | 75 +++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/docs/styles/grid/grid_size.md b/docs/styles/grid/grid_size.md index 0dbf58784..d4c737014 100644 --- a/docs/styles/grid/grid_size.md +++ b/docs/styles/grid/grid_size.md @@ -1 +1,76 @@ # Grid-size + +The `grid-size` style sets the number of columns and rows in a grid layout. + +The number of rows can be left unspecified and it will be computed automatically. + +## Syntax + +```sass +grid-size: []; +``` + +The first integer specifies the number of columns and the second integer specifies the number of rows. + +## Examples + +In the first example, we create a grid with 2 columns and 5 rows, regardless of the fact that we do not have enough labels to fill in the whole grid: + +=== "Output" + + ```{.textual path="docs/examples/styles/grid_size_both.py"} + ``` + +=== "grid_size_both.py" + + ```py + --8<-- "docs/examples/styles/grid_size_both.py" + ``` + +=== "grid_size_both.css" + + ```css hl_lines="2" + --8<-- "docs/examples/styles/grid_size_both.css" + ``` + + 1. Create a grid with 2 columns and 4 rows. + +In the second example, we create a grid with 2 columns and however many rows are needed to display all of the grid children: + +=== "Output" + + ```{.textual path="docs/examples/styles/grid_size_columns.py"} + ``` + +=== "grid_size_columns.py" + + ```py + --8<-- "docs/examples/styles/grid_size_columns.py" + ``` + +=== "grid_size_columns.css" + + ```css + --8<-- "docs/examples/styles/grid_size_columns.css" + ``` + + 1. Create a grid with 2 columns and however many rows. + +## CSS + +```sass +/* Grid with 3 rows and 5 columns */ +grid-size: 3 5; + +/* Grid with 4 columns and as many rows as needed */ +grid-size: 4; +``` + +## Python + +To programmatically change the grid size, the number of rows and columns must be specified separately: + +```py +widget.styles.grid_size_rows = 3 +widget.styles.grid_size_columns = 6 +``` From d1af311e3b9eaab2ed1ea099977432b843f9ce58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:02:27 +0000 Subject: [PATCH 040/310] Complete reference for grid-columns. --- docs/styles/grid/grid_columns.md | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index f2f5e4fe3..1b2125b38 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -1 +1,61 @@ # Grid-columns + +The `grid-columns` style allows to define the width of the columns of the grid. + +## Syntax + +```sass +grid-columns: . . .; +``` + +If there are more columns in the grid than scalars specified in `grid-columns`, they are reused cyclically. + +Scalar units can be mixed. + +--8<-- "docs/styles/snippets/scalar_syntax.md" + +## Example + +The example below shows a grid with 10 labels laid out in a grid with 2 rows and 5 columns. + +We set `grid-columns: 1fr 16 2fr`. +Because there are more rows than scalars in the style rule, the scalars will be reused: + + - columns 1 and 4 have width `1fr`; + - columns 2 and 5 have width `16`; and + - column 3 has width `2fr`. + + +=== "Output" + + ```{.textual path="docs/examples/styles/grid_columns.py"} + ``` + +=== "grid_columns.py" + + ```py + --8<-- "docs/examples/styles/grid_columns.py" + ``` + +=== "grid_columns.css" + + ```css + --8<-- "docs/examples/styles/grid_columns.css" + ``` + +## CSS + +```sass +/* Set all columns to have 50% width */ +grid-columns: 50%; + +/* Every other column is twice as wide as the first one */ +grid-columns: 1fr 2fr; +``` + +### Python + +```py +grid.styles.grid_columns = "50%" +grid.styles.grid_columns = "1fr 2fr" +``` From d0e3734f304433c736558e114f72195f5e750c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:02:40 +0000 Subject: [PATCH 041/310] Complete reference for grid-rows. --- docs/styles/grid/grid_rows.md | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index 34bfd043c..a71175c0d 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -1 +1,61 @@ # Grid-rows + +The `grid-rows` style allows to define the height of the rows of the grid. + +## Syntax + +```sass +grid-rows: . . .; +``` + +If there are more rows in the grid than scalars specified in `grid-rows`, they are reused cyclically. + +Scalar units can be mixed. + +--8<-- "docs/styles/snippets/scalar_syntax.md" + +## Example + +The example below shows a grid with 10 labels laid out in a grid with 5 rows and 2 columns. + +We set `grid-rows: 1fr 6 25%`. +Because there are more rows than scalars in the style rule, the scalars will be reused: + + - rows 1 and 4 have height `1fr`; + - rows 2 and 5 have height `6`; and + - row 3 has height `25%`. + + +=== "Output" + + ```{.textual path="docs/examples/styles/grid_rows.py"} + ``` + +=== "grid_rows.py" + + ```py + --8<-- "docs/examples/styles/grid_rows.py" + ``` + +=== "grid_rows.css" + + ```css + --8<-- "docs/examples/styles/grid_rows.css" + ``` + +## CSS + +```sass +/* Set all rows to have 50% height */ +grid-rows: 50%; + +/* Every other row is twice as tall as the first one */ +grid-rows: 1fr 2fr; +``` + +### Python + +```py +grid.styles.grid_rows = "50%" +grid.styles.grid_rows = "1fr 2fr" +``` From 50ee4e57f2c294eca58bbbadc860aa813458702c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:42:28 +0000 Subject: [PATCH 042/310] Add example for grid-gutter. --- docs/examples/styles/grid_gutter.css | 11 +++++++++++ docs/examples/styles/grid_gutter.py | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 docs/examples/styles/grid_gutter.css create mode 100644 docs/examples/styles/grid_gutter.py diff --git a/docs/examples/styles/grid_gutter.css b/docs/examples/styles/grid_gutter.css new file mode 100644 index 000000000..e4f5240e8 --- /dev/null +++ b/docs/examples/styles/grid_gutter.css @@ -0,0 +1,11 @@ +Grid { + grid-size: 2 4; + grid-gutter: 1 2 /* (1)! */ +} + +Label { + border: round white; + content-align: center middle; + width: 100%; + height: 100%; +} diff --git a/docs/examples/styles/grid_gutter.py b/docs/examples/styles/grid_gutter.py new file mode 100644 index 000000000..363d4a37f --- /dev/null +++ b/docs/examples/styles/grid_gutter.py @@ -0,0 +1,20 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Label + + +class MyApp(App): + def compose(self): + yield Grid( + Label("1"), + Label("2"), + Label("3"), + Label("4"), + Label("5"), + Label("6"), + Label("7"), + Label("8"), + ) + + +app = MyApp(css_path="grid_gutter.css") From 5ff0f79720903ae7383b9d176a67078b3737b9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:42:45 +0000 Subject: [PATCH 043/310] Add example for row-span. --- docs/examples/styles/row_span.css | 30 ++++++++++++++++++++++++++++++ docs/examples/styles/row_span.py | 19 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 docs/examples/styles/row_span.css create mode 100644 docs/examples/styles/row_span.py diff --git a/docs/examples/styles/row_span.css b/docs/examples/styles/row_span.css new file mode 100644 index 000000000..195ca2ac7 --- /dev/null +++ b/docs/examples/styles/row_span.css @@ -0,0 +1,30 @@ +#p1 { + row-span: 4; +} +#p2 { + row-span: 3; +} +#p3 { + row-span: 2; +} +#p4 { + row-span: 1; /* Didn't need to be set explicitly. */ +} +#p5 { + row-span: 3; +} +#p6 { + row-span: 2; +} +#p7 { + /* Default value is 1. */ +} + +Grid { + grid-size: 4 4; + grid-gutter: 1 2; +} + +Placeholder { + height: 100%; +} diff --git a/docs/examples/styles/row_span.py b/docs/examples/styles/row_span.py new file mode 100644 index 000000000..826dc13eb --- /dev/null +++ b/docs/examples/styles/row_span.py @@ -0,0 +1,19 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Placeholder + + +class MyApp(App): + def compose(self): + yield Grid( + Placeholder(id="p1"), + Placeholder(id="p2"), + Placeholder(id="p3"), + Placeholder(id="p4"), + Placeholder(id="p5"), + Placeholder(id="p6"), + Placeholder(id="p7"), + ) + + +app = MyApp(css_path="row_span.css") From 0ccc2bbc00ae7eb1007a47628476dc6b1069aba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:44:48 +0000 Subject: [PATCH 044/310] Add example for column-span. --- docs/examples/styles/column_span.css | 30 ++++++++++++++++++++++++++++ docs/examples/styles/column_span.py | 19 ++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 docs/examples/styles/column_span.css create mode 100644 docs/examples/styles/column_span.py diff --git a/docs/examples/styles/column_span.css b/docs/examples/styles/column_span.css new file mode 100644 index 000000000..d96fbf4f3 --- /dev/null +++ b/docs/examples/styles/column_span.css @@ -0,0 +1,30 @@ +#p1 { + column-span: 4; +} +#p2 { + column-span: 3; +} +#p3 { + column-span: 1; /* Didn't need to be set explicitly. */ +} +#p4 { + column-span: 2; +} +#p5 { + column-span: 2; +} +#p6 { + /* Default value is 1. */ +} +#p7 { + column-span: 3; +} + +Grid { + grid-size: 4 4; + grid-gutter: 1 2; +} + +Placeholder { + height: 100%; +} diff --git a/docs/examples/styles/column_span.py b/docs/examples/styles/column_span.py new file mode 100644 index 000000000..272819621 --- /dev/null +++ b/docs/examples/styles/column_span.py @@ -0,0 +1,19 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Placeholder + + +class MyApp(App): + def compose(self): + yield Grid( + Placeholder(id="p1"), + Placeholder(id="p2"), + Placeholder(id="p3"), + Placeholder(id="p4"), + Placeholder(id="p5"), + Placeholder(id="p6"), + Placeholder(id="p7"), + ) + + +app = MyApp(css_path="column_span.css") From 936f57cafb0aa5d02c979cfc0dad38847d4cde76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:45:05 +0000 Subject: [PATCH 045/310] Complete reference for grid-gutter. --- docs/styles/grid/grid_gutter.md | 59 +++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md index 28f309dc0..cb90d2d5a 100644 --- a/docs/styles/grid/grid_gutter.md +++ b/docs/styles/grid/grid_gutter.md @@ -1 +1,60 @@ # Grid-gutter + +The `grid-gutter` style sets the size of the gutter in the grid layout. +That is, it sets the space between adjacent cells in the grid. + +Gutter is only applied _between_ the edges of cells. +No spacing is added between the edges of cells and the edges of the container. + +## Syntax + +```sass +grid-gutter: []; +``` + +If only one scalar is supplied, it sets the horizontal and vertical gutter. +If two scalars are supplied, they set the vertical and horizontal gutters, respectively. + +--8<-- "docs/styles/snippets/scalar_syntax.md" + +## Example + +The example below employs a common trick to apply visually consistent spacing around all grid cells. + +=== "Output" + + ```{.textual path="docs/examples/styles/grid_gutter.py"} + ``` + +=== "grid_gutter.py" + + ```py + --8<-- "docs/examples/styles/grid_gutter.py" + ``` + +=== "grid_gutter.css" + + ```css + --8<-- "docs/examples/styles/grid_gutter.css" + ``` + + 1. We set the horizontal gutter to be double the vertical gutter because terminal cells are typically two times taller than they are wide. Thus, the result shows visually consistent spacing around grid cells. + +## CSS + +```sass +/* Set vertical and horizontal gutters to be the same */ +grid-gutter: 5%; + +/* Set vertical and horizontal gutters separately */ +grid-gutter: 1 2; +``` + +## Python + +Vertical and horizontal gutters correspond to different Python properties, so they must be set separately: + +```py +widget.styles.grid_gutter_vertical = "1" +widget.styles.grid_gutter_horizontal = "2" +``` From 8c45f297ae4f19a080a35b22e104223142d67093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:45:23 +0000 Subject: [PATCH 046/310] Complete reference for row-span. --- docs/styles/grid/row_span.md | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docs/styles/grid/row_span.md b/docs/styles/grid/row_span.md index d05182ace..040e88a6c 100644 --- a/docs/styles/grid/row_span.md +++ b/docs/styles/grid/row_span.md @@ -1 +1,45 @@ # Row-span + +The `row-span` style specifies how many rows a widget will span in a grid layout. + +## Syntax + +```sass +row-span: +``` + +## Example + +The example below shows a 4 by 4 grid where many placeholders span over several rows. + +Notice that grid cells are filled from left to right, top to bottom. +After placing the placeholders `#p1`, `#p2`, `#p3`, and `#p4`, the next available cell is in the second row, fourth column, which is where the top of `#p5` is. + +=== "Output" + + ```{.textual path="docs/examples/styles/row_span.py"} + ``` + +=== "row_span.py" + + ```py + --8<-- "docs/examples/styles/row_span.py" + ``` + +=== "row_span.css" + + ```css + --8<-- "docs/examples/styles/row_span.css" + ``` + +## CSS + +```sass +row-span: 3 +``` + +## Python + +```py +widget.styles.row_span = 3 +``` From 9816fdb11be173855125ba1aadbfd1acfcc85fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:45:38 +0000 Subject: [PATCH 047/310] Complete reference for column-span. --- docs/styles/grid/column_span.md | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md index 4bf511a8c..00442fbd1 100644 --- a/docs/styles/grid/column_span.md +++ b/docs/styles/grid/column_span.md @@ -1 +1,42 @@ # Column-span + +The `column-span` style specifies how many rows a widget will span in a grid layout. + +## Syntax + +```sass +column-span: +``` + +## Example + +The example below shows a 4 by 4 grid where many placeholders span over several columns. + +=== "Output" + + ```{.textual path="docs/examples/styles/column_span.py"} + ``` + +=== "column_span.py" + + ```py + --8<-- "docs/examples/styles/column_span.py" + ``` + +=== "column_span.css" + + ```css + --8<-- "docs/examples/styles/column_span.css" + ``` + +## CSS + +```sass +column-span: 3 +``` + +## Python + +```py +widget.styles.column_span = 3 +``` From d3adf6bf689a2de10beb325a978afac6eb77555e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 09:37:07 +0000 Subject: [PATCH 048/310] Add note about grid styles applicability. --- docs/styles/grid/column_span.md | 4 ++++ docs/styles/grid/grid_columns.md | 4 ++++ docs/styles/grid/grid_gutter.md | 4 ++++ docs/styles/grid/grid_rows.md | 4 ++++ docs/styles/grid/grid_size.md | 4 ++++ docs/styles/grid/row_span.md | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md index 00442fbd1..2ac8d808f 100644 --- a/docs/styles/grid/column_span.md +++ b/docs/styles/grid/column_span.md @@ -2,6 +2,10 @@ The `column-span` style specifies how many rows a widget will span in a grid layout. +!!! note + + This style only affects widgets that are direct children of a widget with `layout: grid`. + ## Syntax ```sass diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index 1b2125b38..a75fd6157 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -2,6 +2,10 @@ The `grid-columns` style allows to define the width of the columns of the grid. +!!! note + + This style only affects widgets with `layout: grid`. + ## Syntax ```sass diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md index cb90d2d5a..843fae81d 100644 --- a/docs/styles/grid/grid_gutter.md +++ b/docs/styles/grid/grid_gutter.md @@ -6,6 +6,10 @@ That is, it sets the space between adjacent cells in the grid. Gutter is only applied _between_ the edges of cells. No spacing is added between the edges of cells and the edges of the container. +!!! note + + This style only affects widgets with `layout: grid`. + ## Syntax ```sass diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index a71175c0d..5859b80ce 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -2,6 +2,10 @@ The `grid-rows` style allows to define the height of the rows of the grid. +!!! note + + This style only affects widgets with `layout: grid`. + ## Syntax ```sass diff --git a/docs/styles/grid/grid_size.md b/docs/styles/grid/grid_size.md index d4c737014..b75e862e7 100644 --- a/docs/styles/grid/grid_size.md +++ b/docs/styles/grid/grid_size.md @@ -4,6 +4,10 @@ The `grid-size` style sets the number of columns and rows in a grid layout. The number of rows can be left unspecified and it will be computed automatically. +!!! note + + This style only affects widgets with `layout: grid`. + ## Syntax ```sass diff --git a/docs/styles/grid/row_span.md b/docs/styles/grid/row_span.md index 040e88a6c..ce3565528 100644 --- a/docs/styles/grid/row_span.md +++ b/docs/styles/grid/row_span.md @@ -2,6 +2,10 @@ The `row-span` style specifies how many rows a widget will span in a grid layout. +!!! note + + This style only affects widgets that are direct children of a widget with `layout: grid`. + ## Syntax ```sass From 08a03779864dfcddc0c3692f59707f628a4b21b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 10:39:55 +0000 Subject: [PATCH 049/310] Link unit snippet to the unit page. We use absolute links because the relative links of snippets only resolve when clicked, so the link can point to different places if the snippet is included in pages in different paths. --- docs/styles/snippets/color_css_syntax.md | 2 +- docs/styles/snippets/fractional_syntax.md | 2 +- docs/styles/snippets/percentage_syntax.md | 2 +- docs/styles/snippets/scalar_syntax.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/styles/snippets/color_css_syntax.md b/docs/styles/snippets/color_css_syntax.md index e699a41b0..e71985e70 100644 --- a/docs/styles/snippets/color_css_syntax.md +++ b/docs/styles/snippets/color_css_syntax.md @@ -1,4 +1,4 @@ -The legal values for `` are dependant on the [class `Color`][textual.color.Color] and include: +The legal values for a [color](/styles/css_units/color.md) depend on the [class `Color`][textual.color.Color] and include: - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); diff --git a/docs/styles/snippets/fractional_syntax.md b/docs/styles/snippets/fractional_syntax.md index 3c41ae409..9c7a28029 100644 --- a/docs/styles/snippets/fractional_syntax.md +++ b/docs/styles/snippets/fractional_syntax.md @@ -1,4 +1,4 @@ -A fractional value can be set to +A [fractional](/styles/css_units/fractional) value can be set to - a float between 0 and 1 (e.g., `0.45`); or - a percentage between 0% and 100% (e.g., `45%`). diff --git a/docs/styles/snippets/percentage_syntax.md b/docs/styles/snippets/percentage_syntax.md index 212b31bc1..179cf1753 100644 --- a/docs/styles/snippets/percentage_syntax.md +++ b/docs/styles/snippets/percentage_syntax.md @@ -1,2 +1,2 @@ -A percentage is a number followed by the percent sign. +A [percentage](/styles/css_units/percentage) is a number followed by the percent sign. The number doesn't have to be an integer and values are clamped between 0% and 100%. diff --git a/docs/styles/snippets/scalar_syntax.md b/docs/styles/snippets/scalar_syntax.md index 9581e271b..22e022663 100644 --- a/docs/styles/snippets/scalar_syntax.md +++ b/docs/styles/snippets/scalar_syntax.md @@ -1,4 +1,4 @@ -A scalar can be any of the following: +A [scalar](/styles/css_units/scalar) can be any of the following: - a fixed number of cells (e.g., `10`); - a fractional proportion relative to the sizes of the other widgets (e.g., `1fr`); From 591e343a5a7eb44c08c5266de2b4f3a51cf3df59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 10:40:13 +0000 Subject: [PATCH 050/310] Add example to compare all heights. --- docs/examples/styles/height_comparison.css | 34 ++++++++++++++++++++++ docs/examples/styles/height_comparison.py | 28 ++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 docs/examples/styles/height_comparison.css create mode 100644 docs/examples/styles/height_comparison.py diff --git a/docs/examples/styles/height_comparison.css b/docs/examples/styles/height_comparison.css new file mode 100644 index 000000000..ca2737e07 --- /dev/null +++ b/docs/examples/styles/height_comparison.css @@ -0,0 +1,34 @@ +#cells { + height: 2; /* (1)! */ +} +#percent { + height: 12.5%; /* (2)! */ +} +#w { + height: 5w; /* (3)! */ +} +#h { + height: 12.5h; /* (4)! */ +} +#vw { + height: 7.5vw; /* (5)! */ +} +#vh { + height: 12.5vh; /* (6)! */ +} +#auto { + height: auto; /* (7)! */ +} +#fr1 { + height: 1fr; /* (8)! */ +} +#fr2 { + height: 2fr; /* (9)! */ +} + +VerticalRuler { + dock: right; + overflow: hidden; + width: auto; + background: $accent; +} diff --git a/docs/examples/styles/height_comparison.py b/docs/examples/styles/height_comparison.py new file mode 100644 index 000000000..b24f257aa --- /dev/null +++ b/docs/examples/styles/height_comparison.py @@ -0,0 +1,28 @@ +from textual.app import App +from textual.containers import Vertical +from textual.widgets import Placeholder, Label, Static + + +class VerticalRuler(Static): + def compose(self): + ruler_text = "\n".join(map(str, range(1, 100))) + yield Label(ruler_text) + + +class HeightComparisonApp(App): + def compose(self): + yield Vertical( + Placeholder(id="cells"), # (1)! + Placeholder(id="percent"), + Placeholder(id="w"), + Placeholder(id="h"), + Placeholder(id="vw"), + Placeholder(id="vh"), + Placeholder(id="auto"), + Placeholder(id="fr1"), + Placeholder(id="fr2"), + ) + yield VerticalRuler() + + +app = HeightComparisonApp(css_path="height_comparison.css") From a63920da3911950dca83a0b64371b16e59153e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 10:40:59 +0000 Subject: [PATCH 051/310] Complete height reference. [skip ci] --- docs/styles/height.md | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/styles/height.md b/docs/styles/height.md index 18622615d..d3ce3b8f0 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -8,7 +8,9 @@ The `height` rule sets a widget's height. By default, it sets the height of the height: ; ``` -## Example +--8<-- "docs/styles/snippets/scalar_syntax.md" + +## Examples This examples creates a widget with a height of 50% of the screen. @@ -29,6 +31,41 @@ This examples creates a widget with a height of 50% of the screen. ```{.textual path="docs/examples/styles/height.py"} ``` +The next example creates a series of wide widgets with heights set with different units. +Open the CSS file tab to see the comments that explain how each height is computed. +(The output includes a vertical ruler on the right to make it easier to check the height of each widget.) + +=== "Output" + + ```{.textual path="docs/examples/styles/height_comparison.py" lines=24 columns=80} + ``` + +=== "height_comparison.py" + + ```py hl_lines="15-23" + --8<-- "docs/examples/styles/height_comparison.py" + ``` + + 1. The id of the placeholder identifies which unit will be used to set the height of the widget. + +=== "height_comparison.css" + + ```css hl_lines="2 5 8 11 14 17 20 23 26" + --8<-- "docs/examples/styles/height_comparison.css" + ``` + + 1. This sets the height to 2 lines. + 2. This sets the height to 12.5% of the space made available by the container. The container is 24 lines tall, so 12.5% of 24 is 3. + 3. This sets the height to 5% of the width of the direct container, which is the `Vertical` container. Because it expands to fit all of the terminal, the width of the `Vertical` is 80 and 5% of 80 is 4. + 4. This sets the height to 12.5% of the height of the direct container, which is the `Vertical` container. Because it expands to fit all of the terminal, the height of the `Vertical` is 24 and 12.5% of 24 is 3. + 5. This sets the height to 7.5% of the viewport width, which is 80. 7.5% of 80 is 5.6 which gets truncated to 5. + 6. This sets the height to 12.5% of the viewport height, which is 24. 12.5% of 24 is 3. + 7. This sets the height of the placeholder to be the optimal size that fits the content without scrolling. + Because the content only spans one line, the placeholder has its height set to 1. + 8. This sets the height to `1fr`, which means this placeholder will have half the height of a placeholder with `2fr`. + 9. This sets the height to `2fr`, which means this placeholder will have twice the height of a placeholder with `1fr`. + + ## CSS ```sass @@ -45,7 +82,7 @@ height: auto ## Python ```python -self.styles.height = 10 +self.styles.height = 10 # Explicit cell height can be an int self.styles.height = "50%" self.styles.height = "auto" ``` From 6451d192a64703c7241505b16859985922d7b1b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 11:16:31 +0000 Subject: [PATCH 052/310] Reorder CSS rule by relevance. --- docs/examples/guide/layout/layers.css | 2 +- docs/guide/layout.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/guide/layout/layers.css b/docs/examples/guide/layout/layers.css index 4465b2d91..7dab8dfd5 100644 --- a/docs/examples/guide/layout/layers.css +++ b/docs/examples/guide/layout/layers.css @@ -11,8 +11,8 @@ Static { } #box1 { - background: darkcyan; layer: above; + background: darkcyan; } #box2 { diff --git a/docs/guide/layout.md b/docs/guide/layout.md index 495cb6f86..94405d837 100644 --- a/docs/guide/layout.md +++ b/docs/guide/layout.md @@ -503,7 +503,7 @@ However, in this case, both `#box1` and `#box2` are assigned to layers which def === "layers.css" - ```sass hl_lines="3 15 19" + ```sass hl_lines="3 14 19" --8<-- "docs/examples/guide/layout/layers.css" ``` From c087c93930a717af9e5959e56c151a6e565b5ef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 11:16:55 +0000 Subject: [PATCH 053/310] Complete references for layer(s). [skip ci] --- docs/styles/layer.md | 6 +++--- docs/styles/layers.md | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/styles/layer.md b/docs/styles/layer.md index 383e745b2..5c68a5327 100644 --- a/docs/styles/layer.md +++ b/docs/styles/layer.md @@ -1,8 +1,8 @@ # Layer The `layer` property is used to assign widgets to a layer. -The value of the `layer` property must be the name of a layer defined using a `layers` declaration. Layers control the order in which widgets are painted on screen. +The value of the `layer` property must be the name of a layer defined using a `layers` declaration. More information on layers can be found in the [guide](../guide/layout.md#layers). ## Syntax @@ -31,7 +31,7 @@ However, since `#box1` is on the higher layer, it is drawn on top of `#box2`. === "layers.css" - ```sass hl_lines="3 15 19" + ```sass hl_lines="3 14 19" --8<-- "docs/examples/guide/layout/layers.css" ``` @@ -46,5 +46,5 @@ layer: below; ```python # Draw the widget on the layer called 'below' -widget.layer = "below" +widget.styles.layer = "below" ``` diff --git a/docs/styles/layers.md b/docs/styles/layers.md index 9eed3156d..443431120 100644 --- a/docs/styles/layers.md +++ b/docs/styles/layers.md @@ -1,16 +1,20 @@ # Layers The `layers` property allows you to define an ordered set of layers. -These `layers` can later be referenced using the `layer` property. Layers control the order in which widgets are painted on screen. +These `layers` can later be referenced using the `layer` property. More information on layers can be found in the [guide](../guide/layout.md#layers). ## Syntax ``` -layers: ...; +layers: . . .; ``` +Layers that come first in the list are drawn before the layers that come after. +This means the first layer will be under all other layers and the last layer will be above all other layers. +See the example below. + ## Example In the example below, `#box1` is yielded before `#box2`. @@ -31,7 +35,7 @@ However, since `#box1` is on the higher layer, it is drawn on top of `#box2`. === "layers.css" - ```sass hl_lines="3 15 19" + ```sass hl_lines="3 14 19" --8<-- "docs/examples/guide/layout/layers.css" ``` @@ -46,5 +50,5 @@ layers: below above; ```python # Bottom layer is called 'below', layer above it is called 'above' -widget.layers = ("below", "above") +widget.style.layers = ("below", "above") ``` From d3634ce73147daabd89a2c2eda5cc65458132028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 11:27:16 +0000 Subject: [PATCH 054/310] Link layer(s) references. --- docs/styles/layer.md | 2 +- docs/styles/layers.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/styles/layer.md b/docs/styles/layer.md index 5c68a5327..39a7e0d14 100644 --- a/docs/styles/layer.md +++ b/docs/styles/layer.md @@ -2,7 +2,7 @@ The `layer` property is used to assign widgets to a layer. Layers control the order in which widgets are painted on screen. -The value of the `layer` property must be the name of a layer defined using a `layers` declaration. +The value of the `layer` property must be the name of a layer defined using a [`layers`](../layers) declaration. More information on layers can be found in the [guide](../guide/layout.md#layers). ## Syntax diff --git a/docs/styles/layers.md b/docs/styles/layers.md index 443431120..c619eb0d6 100644 --- a/docs/styles/layers.md +++ b/docs/styles/layers.md @@ -2,7 +2,7 @@ The `layers` property allows you to define an ordered set of layers. Layers control the order in which widgets are painted on screen. -These `layers` can later be referenced using the `layer` property. +These `layers` can later be referenced using the [`layer`](../layer) property. More information on layers can be found in the [guide](../guide/layout.md#layers). ## Syntax From 3abfa549fecb4f5e7c73a086c2540ff7aa95c9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 11:43:27 +0000 Subject: [PATCH 055/310] Complete layout reference. --- docs/styles/layout.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/styles/layout.md b/docs/styles/layout.md index a3021f753..e94b77d01 100644 --- a/docs/styles/layout.md +++ b/docs/styles/layout.md @@ -2,12 +2,12 @@ The `layout` property defines how a widget arranges its children. -See [layout](../guide/layout.md) guide for more information. +See the [layout](../guide/layout.md) guide for more information. ## Syntax ``` -layout: [grid|horizontal|vertical]; +layout: grid | horizontal | vertical; ``` ### Values @@ -21,6 +21,7 @@ layout: [grid|horizontal|vertical]; ## Example Note how the `layout` property affects the arrangement of widgets in the example below. +To learn more about the grid layout, you can see the [layout guide](../guide/layout.md) or the [grid reference](../grid). === "layout.py" @@ -48,5 +49,5 @@ layout: horizontal; ## Python ```python -widget.layout = "horizontal" +widget.styles.layout = "horizontal" ``` From 9b40682fe0c2b5f22ad6c4619a093ec50dc58b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 13:49:42 +0000 Subject: [PATCH 056/310] Link to related grid styles. --- docs/styles/grid/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/styles/grid/index.md b/docs/styles/grid/index.md index 9f7bbc1fd..16c51ae3c 100644 --- a/docs/styles/grid/index.md +++ b/docs/styles/grid/index.md @@ -6,12 +6,12 @@ For an in-depth look at the grid layout, visit the grid [guide](../guide/layout. | Property | Description | |----------------|------------------------------------------------| -| `grid-size` | Number of columns and rows in the grid layout. | -| `grid-rows` | Height of grid rows. | -| `grid-columns` | Width of grid columns. | -| `grid-gutter` | Spacing between grid cells. | -| `row-span` | Number of rows a cell spans. | -| `column-span` | Number of columns a cell spans. | +| [`grid-size`](./grid_size.md) | Number of columns and rows in the grid layout. | +| [`grid-rows`](./grid_rows.md) | Height of grid rows. | +| [`grid-columns`](./grid_columns.md) | Width of grid columns. | +| [`grid-gutter`](./grid_gutter.md) | Spacing between grid cells. | +| [`row-span`](./row_span.md) | Number of rows a cell spans. | +| [`column-span`](./column_span.md) | Number of columns a cell spans. | ## Syntax From 1a81fa1d1b7fd44b69cba100095cd58c85582694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 14:30:52 +0000 Subject: [PATCH 057/310] Fix link in color unit snippet. --- docs/styles/snippets/color_css_syntax.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/styles/snippets/color_css_syntax.md b/docs/styles/snippets/color_css_syntax.md index e71985e70..8e818339a 100644 --- a/docs/styles/snippets/color_css_syntax.md +++ b/docs/styles/snippets/color_css_syntax.md @@ -1,4 +1,4 @@ -The legal values for a [color](/styles/css_units/color.md) depend on the [class `Color`][textual.color.Color] and include: +The legal values for a [color](/styles/css_units/color) depend on the [class `Color`][textual.color.Color] and include: - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); From 88077875716593a04d42f5ed507e96641221c029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 14:48:06 +0000 Subject: [PATCH 058/310] Add CSS unit reference for text style. --- docs/styles/css_units/text_style.md | 51 +++++++++++++++++++++++ docs/styles/snippets/text_style_syntax.md | 9 ++++ 2 files changed, 60 insertions(+) create mode 100644 docs/styles/css_units/text_style.md create mode 100644 docs/styles/snippets/text_style_syntax.md diff --git a/docs/styles/css_units/text_style.md b/docs/styles/css_units/text_style.md new file mode 100644 index 000000000..02474ce9b --- /dev/null +++ b/docs/styles/css_units/text_style.md @@ -0,0 +1,51 @@ +# Text style + +The text style unit is a combination of any of the legal text style values in a space-separated list. + +!!! warning + + Not to be confused with the [`text-style`](../text_style.md) CSS rule that sets the style of text in a widget. + +## Syntax + +--8<-- "docs/styles/snippets/text_style_syntax.md" + +## Examples + +!!! note + + The `text-style` CSS rule and the text style unit are closely related but they are not the same thing. + Here, we show examples of the text style unit, which are relevant for [all CSS rules](#used-by) that use the text style unit. + +```css +Widget { + text-style: bold; + text-style: italic; + text-style: reverse; + text-style: underline; + text-style: strike; + + /* When the unit expected is a style, you can specify multiple values */ + text-style: strike bold italic reverse; + text-style: bold underline italic; +} +``` + +```py +widget.styles.text_style = "bold" +widget.styles.text_style = "italic" +widget.styles.text_style = "reverse" +widget.styles.text_style = "underline" +widget.styles.text_style = "strike" + +# Multiple values can be specified +widget.styles.text_style = "strike bold italic reverse" +widget.styles.text_style = "bold underline italic" +``` + +## Used by + + - Links: + - [`link-style`](../links/link_style.md) + - [`link-hover-style`](../links/link_hover_style.md) + - [`text-style`](../text_style.md) diff --git a/docs/styles/snippets/text_style_syntax.md b/docs/styles/snippets/text_style_syntax.md new file mode 100644 index 000000000..acc385c46 --- /dev/null +++ b/docs/styles/snippets/text_style_syntax.md @@ -0,0 +1,9 @@ +The [text style](/styles/css_units/text_style) unit can be any space-separated combination of the following values: + +| Value | Description | +|-------------|----------------------------------------------------------------| +| `bold` | **bold text** | +| `italic` | _italic text_ | +| `reverse` | reverse video text (foreground and background colors reversed) | +| `underline` | underline text | +| `strike` | strikethrough text | From 2f99225abe185d339ac4e31a8d445e95f299d05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 14:50:32 +0000 Subject: [PATCH 059/310] Add text style unit to docs. --- docs/styles/css_units/index.md | 11 ++++++----- mkdocs.yml | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/styles/css_units/index.md b/docs/styles/css_units/index.md index d98e6f722..45c5735fc 100644 --- a/docs/styles/css_units/index.md +++ b/docs/styles/css_units/index.md @@ -4,8 +4,9 @@ Many CSS rules accept units of some sort, as opposed to a set of values. The different CSS units are: - - [color](./color.md) – e.g., to set the [background color](../background.md); - - [fractional](./fractional.md) – e.g., to set a widget's [`opacity`](../opacity.md); - - [integer](./integer.md) – e.g., to set the [`grid-size`](../grid/grid_size.md); - - [percentage](./percentage.md) – e.g., to set the transparency of the [background color](../background.md); and - - [scalar](./scalar.md) – e.g., to set the [width](../width.md) of a widget. + - [color](./color.md) – e.g., to set the background color of a widget; + - [fractional](./fractional.md) – e.g., to set the opacity of a widget; + - [integer](./integer.md) – e.g., to set the size of a grid layout; + - [percentage](./percentage.md) – e.g., to set the transparency of colors; + - [scalar](./scalar.md) – e.g., to set the dimensions of a widget; and + - [text style](./text_style.md) – e.g., to style the text of a widget. diff --git a/mkdocs.yml b/mkdocs.yml index 37f62b80d..bcd98b6fa 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -61,6 +61,7 @@ nav: - "styles/css_units/integer.md" - "styles/css_units/percentage.md" - "styles/css_units/scalar.md" + - "styles/css_units/text_style.md" - "styles/index.md" - "styles/align.md" - "styles/background.md" From 4aad7cda8958aeb5df399a8edfc62be7905ba4a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 17:29:57 +0000 Subject: [PATCH 060/310] Add example for link color. --- docs/examples/styles/link_color.css | 11 +++++++++++ docs/examples/styles/link_color.py | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 docs/examples/styles/link_color.css create mode 100644 docs/examples/styles/link_color.py diff --git a/docs/examples/styles/link_color.css b/docs/examples/styles/link_color.css new file mode 100644 index 000000000..949af7078 --- /dev/null +++ b/docs/examples/styles/link_color.css @@ -0,0 +1,11 @@ +#lbl1, #lbl2 { + link-color: red; /* (1)! */ +} + +#lbl3 { + link-color: hsl(60,100%,50%) 50%; +} + +#lbl4 { + link-color: $accent; +} diff --git a/docs/examples/styles/link_color.py b/docs/examples/styles/link_color.py new file mode 100644 index 000000000..85cd36c18 --- /dev/null +++ b/docs/examples/styles/link_color.py @@ -0,0 +1,25 @@ +from textual.app import App +from textual.widgets import Label + + +class LinkColorApp(App): + def compose(self): + yield Label( + "Visit the [link=https://textualize.io]Textualize[/link] website.", + id="lbl1", # (1)! + ) + yield Label( + "Click [@click=app.bell]here[/] for the bell sound.", + id="lbl2", # (2)! + ) + yield Label( + "You can also click [@click=app.bell]here[/] for the bell sound.", + id="lbl3", # (3)! + ) + yield Label( + "[@click=app.quit]Exit this application.[/]", + id="lbl4", # (4)! + ) + + +app = LinkColorApp(css_path="link_color.css") From 8138961f60dd7b9c9d4303b4eae4623191738b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:46:33 +0000 Subject: [PATCH 061/310] Add example for link background. --- docs/examples/styles/link_background.css | 11 +++++++++++ docs/examples/styles/link_background.py | 25 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 docs/examples/styles/link_background.css create mode 100644 docs/examples/styles/link_background.py diff --git a/docs/examples/styles/link_background.css b/docs/examples/styles/link_background.css new file mode 100644 index 000000000..94a31b2c7 --- /dev/null +++ b/docs/examples/styles/link_background.css @@ -0,0 +1,11 @@ +#lbl1, #lbl2 { + link-background: red; /* (1)! */ +} + +#lbl3 { + link-background: hsl(60,100%,50%) 50%; +} + +#lbl4 { + link-background: $accent; +} diff --git a/docs/examples/styles/link_background.py b/docs/examples/styles/link_background.py new file mode 100644 index 000000000..dc21f3298 --- /dev/null +++ b/docs/examples/styles/link_background.py @@ -0,0 +1,25 @@ +from textual.app import App +from textual.widgets import Label + + +class LinkBackgroundApp(App): + def compose(self): + yield Label( + "Visit the [link=https://textualize.io]Textualize[/link] website.", + id="lbl1", # (1)! + ) + yield Label( + "Click [@click=app.bell]here[/] for the bell sound.", + id="lbl2", # (2)! + ) + yield Label( + "You can also click [@click=app.bell]here[/] for the bell sound.", + id="lbl3", # (3)! + ) + yield Label( + "[@click=app.quit]Exit this application.[/]", + id="lbl4", # (4)! + ) + + +app = LinkBackgroundApp(css_path="link_background.css") From 47ef2aa73fc58a5d8dfaa4758cafe82de5c58d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:46:44 +0000 Subject: [PATCH 062/310] Add example for link style. --- docs/examples/styles/link_style.css | 11 +++++++++++ docs/examples/styles/link_style.py | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 docs/examples/styles/link_style.css create mode 100644 docs/examples/styles/link_style.py diff --git a/docs/examples/styles/link_style.css b/docs/examples/styles/link_style.css new file mode 100644 index 000000000..63240c91a --- /dev/null +++ b/docs/examples/styles/link_style.css @@ -0,0 +1,11 @@ +#lbl1, #lbl2 { + link-style: bold italic; /* (1)! */ +} + +#lbl3 { + link-style: reverse strike; +} + +#lbl4 { + link-style: bold; +} diff --git a/docs/examples/styles/link_style.py b/docs/examples/styles/link_style.py new file mode 100644 index 000000000..5ed9f12a9 --- /dev/null +++ b/docs/examples/styles/link_style.py @@ -0,0 +1,25 @@ +from textual.app import App +from textual.widgets import Label + + +class LinkStyleApp(App): + def compose(self): + yield Label( + "Visit the [link=https://textualize.io]Textualize[/link] website.", + id="lbl1", # (1)! + ) + yield Label( + "Click [@click=app.bell]here[/] for the bell sound.", + id="lbl2", # (2)! + ) + yield Label( + "You can also click [@click=app.bell]here[/] for the bell sound.", + id="lbl3", # (3)! + ) + yield Label( + "[@click=app.quit]Exit this application.[/]", + id="lbl4", # (4)! + ) + + +app = LinkStyleApp(css_path="link_style.css") From e68e02405f813a5e7c4dc7b8e11bd8cc742d8055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:47:05 +0000 Subject: [PATCH 063/310] Add example for link hover color. --- docs/examples/styles/link_hover_color.css | 11 ++++++++++ docs/examples/styles/link_hover_color.py | 25 +++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 docs/examples/styles/link_hover_color.css create mode 100644 docs/examples/styles/link_hover_color.py diff --git a/docs/examples/styles/link_hover_color.css b/docs/examples/styles/link_hover_color.css new file mode 100644 index 000000000..234184f47 --- /dev/null +++ b/docs/examples/styles/link_hover_color.css @@ -0,0 +1,11 @@ +#lbl1, #lbl2 { + link-hover-color: red; /* (1)! */ +} + +#lbl3 { + link-hover-color: hsl(60,100%,50%) 50%; +} + +#lbl4 { + link-hover-color: black; +} diff --git a/docs/examples/styles/link_hover_color.py b/docs/examples/styles/link_hover_color.py new file mode 100644 index 000000000..56093563d --- /dev/null +++ b/docs/examples/styles/link_hover_color.py @@ -0,0 +1,25 @@ +from textual.app import App +from textual.widgets import Label + + +class LinkHoverColorApp(App): + def compose(self): + yield Label( + "Visit the [link=https://textualize.io]Textualize[/link] website.", + id="lbl1", # (1)! + ) + yield Label( + "Click [@click=app.bell]here[/] for the bell sound.", + id="lbl2", # (2)! + ) + yield Label( + "You can also click [@click=app.bell]here[/] for the bell sound.", + id="lbl3", # (3)! + ) + yield Label( + "[@click=app.quit]Exit this application.[/]", + id="lbl4", # (4)! + ) + + +app = LinkHoverColorApp(css_path="link_hover_color.css") From 8ce8b4c33a1643de2716ee88e4bfa725f4a06140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:47:15 +0000 Subject: [PATCH 064/310] Add example for link hover background. --- .../examples/styles/link_hover_background.css | 11 ++++++++ docs/examples/styles/link_hover_background.py | 25 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 docs/examples/styles/link_hover_background.css create mode 100644 docs/examples/styles/link_hover_background.py diff --git a/docs/examples/styles/link_hover_background.css b/docs/examples/styles/link_hover_background.css new file mode 100644 index 000000000..68d564ae2 --- /dev/null +++ b/docs/examples/styles/link_hover_background.css @@ -0,0 +1,11 @@ +#lbl1, #lbl2 { + link-hover-background: red; /* (1)! */ +} + +#lbl3 { + link-hover-background: hsl(60,100%,50%) 50%; +} + +#lbl4 { + /* Empty to show the default hover background */ /* (2)! */ +} diff --git a/docs/examples/styles/link_hover_background.py b/docs/examples/styles/link_hover_background.py new file mode 100644 index 000000000..f1112b355 --- /dev/null +++ b/docs/examples/styles/link_hover_background.py @@ -0,0 +1,25 @@ +from textual.app import App +from textual.widgets import Label + + +class LinkHoverBackgroundApp(App): + def compose(self): + yield Label( + "Visit the [link=https://textualize.io]Textualize[/link] website.", + id="lbl1", # (1)! + ) + yield Label( + "Click [@click=app.bell]here[/] for the bell sound.", + id="lbl2", # (2)! + ) + yield Label( + "You can also click [@click=app.bell]here[/] for the bell sound.", + id="lbl3", # (3)! + ) + yield Label( + "[@click=app.quit]Exit this application.[/]", + id="lbl4", # (4)! + ) + + +app = LinkHoverBackgroundApp(css_path="link_hover_background.css") From 57af822730262067558c54629719435d981cabbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:47:22 +0000 Subject: [PATCH 065/310] Add example for link hover style. --- docs/examples/styles/link_hover_style.css | 11 ++++++++++ docs/examples/styles/link_hover_style.py | 25 +++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 docs/examples/styles/link_hover_style.css create mode 100644 docs/examples/styles/link_hover_style.py diff --git a/docs/examples/styles/link_hover_style.css b/docs/examples/styles/link_hover_style.css new file mode 100644 index 000000000..169e69d29 --- /dev/null +++ b/docs/examples/styles/link_hover_style.css @@ -0,0 +1,11 @@ +#lbl1, #lbl2 { + link-hover-style: bold italic; /* (1)! */ +} + +#lbl3 { + link-hover-style: reverse strike; +} + +#lbl4 { + link-hover-style: bold; +} diff --git a/docs/examples/styles/link_hover_style.py b/docs/examples/styles/link_hover_style.py new file mode 100644 index 000000000..6a6ef3dba --- /dev/null +++ b/docs/examples/styles/link_hover_style.py @@ -0,0 +1,25 @@ +from textual.app import App +from textual.widgets import Label + + +class LinkHoverStyleApp(App): + def compose(self): + yield Label( + "Visit the [link=https://textualize.io]Textualize[/link] website.", + id="lbl1", # (1)! + ) + yield Label( + "Click [@click=app.bell]here[/] for the bell sound.", + id="lbl2", # (2)! + ) + yield Label( + "You can also click [@click=app.bell]here[/] for the bell sound.", + id="lbl3", # (3)! + ) + yield Label( + "[@click=app.quit]Exit this application.[/]", + id="lbl4", # (4)! + ) + + +app = LinkHoverStyleApp(css_path="link_hover_style.css") From 0654e1c4c78953adfe6b5c5e4fdb0264ea675300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:47:48 +0000 Subject: [PATCH 066/310] Add GIF demos for link hover rules. --- .../links/demos/link_hover_background_demo.gif | Bin 0 -> 138390 bytes .../links/demos/link_hover_color_demo.gif | Bin 0 -> 170605 bytes .../links/demos/link_hover_style_demo.gif | Bin 0 -> 186544 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/styles/links/demos/link_hover_background_demo.gif create mode 100644 docs/styles/links/demos/link_hover_color_demo.gif create mode 100644 docs/styles/links/demos/link_hover_style_demo.gif diff --git a/docs/styles/links/demos/link_hover_background_demo.gif b/docs/styles/links/demos/link_hover_background_demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..5052b7889dfd69b8f95494e201fdd8c7c08a0c1b GIT binary patch literal 138390 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
*1?v>((A2*tv@=VFFW2! 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 A`v3p{ literal 0 HcmV?d00001 diff --git a/docs/styles/links/demos/link_hover_color_demo.gif b/docs/styles/links/demos/link_hover_color_demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..a2dd07e62e502dfcd45ff850535c07c261407ae7 GIT binary patch literal 170605 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

fn^zWiW%;{ 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 diff --git a/docs/styles/links/index.md b/docs/styles/links/index.md index 475686cbd..855e391ce 100644 --- a/docs/styles/links/index.md +++ b/docs/styles/links/index.md @@ -8,24 +8,24 @@ Textual supports the concept of inline "links" embedded in text which trigger an There are a number of styles which influence the appearance of these links within a widget. -| Property | Description | -|-------------------------|-------------------------------------------------------------| -| [`link-color`](./link_color.md) | The color of link text. | -| [`link-background`](./link_background.md) | The background color of link text. | -| [`link-style`](./link_style.md) | The style of link text (e.g. underline). | -| [`link-hover-color`](./link_hover_color.md) | The color of link text with the cursor above it. | -| [`link-hover-background`](./link_hover_background.md) | The background color of link text with the cursor above it. | -| [`link-hover-style`](./link_hover_style.md) | The style of link text with the cursor above it. | +| Property | Description | +|-------------------------------------------------------|-------------------------------------------------------------------| +| [`link-color`](./link_color.md) | The color of the link text. | +| [`link-background`](./link_background.md) | The background color of the link text. | +| [`link-style`](./link_style.md) | The style of the link text (e.g. underline). | +| [`link-hover-color`](./link_hover_color.md) | The color of the link text when the cursor is over it. | +| [`link-hover-background`](./link_hover_background.md) | The background color of the link text when the cursor is over it. | +| [`link-hover-style`](./link_hover_style.md) | The style of the link text when the cursor is over it. | ## Syntax ```scss -link-color: ; -link-background: ; -link-style: ...; -link-hover-color: ; -link-hover-background: ; -link-hover-style: ...; +link-color: []; +link-background: []; +link-style: ; +link-hover-color: []; +link-hover-background: []; +link-hover-style: ; ``` --8<-- "docs/styles/snippets/color_css_syntax.md" @@ -34,8 +34,8 @@ link-hover-style: ...; ## Example -In the example below, the first `Static` illustrates default link styling. -The second `Static` uses CSS to customize the link color, background, and style. +In the example below, the first label illustrates default link styling. +The second label uses CSS to customize the link color, background, and style. === "Output" diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md index 6f067499e..9f69c06f1 100644 --- a/docs/styles/links/link_background.md +++ b/docs/styles/links/link_background.md @@ -4,7 +4,7 @@ The `link-background` sets the background color of the link. !!! note - `link-background` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + `link-background` only applies to Textual action links as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. ## Syntax @@ -18,7 +18,7 @@ link-background: ; ## Example -The example below shows some links with their color changed. +The example below shows some links with their background color changed. It also shows that `link-background` does not affect hyperlinks. === "Output" diff --git a/docs/styles/links/link_color.md b/docs/styles/links/link_color.md index 468ce4182..8e9fa0e57 100644 --- a/docs/styles/links/link_color.md +++ b/docs/styles/links/link_color.md @@ -4,7 +4,7 @@ The `link-color` sets the color of the link text. !!! note - `link-style` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + `link-color` only applies to Textual action links as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. ## Syntax diff --git a/docs/styles/links/link_hover_background.md b/docs/styles/links/link_hover_background.md index 89e1661c1..1e6cf8659 100644 --- a/docs/styles/links/link_hover_background.md +++ b/docs/styles/links/link_hover_background.md @@ -1,10 +1,10 @@ # Link-hover-background -The `link-hover-background` sets the background color of the link. +The `link-hover-background` sets the background color of the link when the mouse cursor is over the link. !!! note - `link-hover-background` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + `link-hover-background` only applies to Textual action links as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. ## Syntax diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md index da8ce5f8e..0e19ce95e 100644 --- a/docs/styles/links/link_hover_color.md +++ b/docs/styles/links/link_hover_color.md @@ -4,7 +4,7 @@ The `link-hover-color` sets the color of the link text when the mouse cursor is !!! note - `link-hover-color` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + `link-hover-color` only applies to Textual action links as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. ## Syntax diff --git a/docs/styles/links/link_hover_style.md b/docs/styles/links/link_hover_style.md index 9a054f1e8..45479ea7c 100644 --- a/docs/styles/links/link_hover_style.md +++ b/docs/styles/links/link_hover_style.md @@ -4,7 +4,7 @@ The `link-hover-style` sets the text style for the link text when the mouse curs !!! note - `link-hover-style` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + `link-hover-style` only applies to Textual action links as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. ## Syntax diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md index 9fb1c47d8..2dff30b3a 100644 --- a/docs/styles/links/link_style.md +++ b/docs/styles/links/link_style.md @@ -4,7 +4,7 @@ The `link-style` sets the text style for the link text. !!! note - `link-style` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + `link-style` only applies to Textual action links as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. ## Syntax From 9e294b85f38226db837f00091e3c6aefed3e67be Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 21 Dec 2022 14:38:42 +0000 Subject: [PATCH 076/310] ws --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42111addd..eba3de4e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,6 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). - ## [0.6.0] - 2022-12-11 ### Added From d3c91075c658d1d366824c862f05449ad3f5016d Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Wed, 21 Dec 2022 16:19:23 +0000 Subject: [PATCH 077/310] Add test for line crop issue --- tests/test_input.py | 8 ++++++++ tests/test_segment_tools.py | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/test_input.py diff --git a/tests/test_input.py b/tests/test_input.py new file mode 100644 index 000000000..87971757b --- /dev/null +++ b/tests/test_input.py @@ -0,0 +1,8 @@ +from textual.widgets._input import _InputRenderable, Input + + +def test_input_renderable(): + input_widget = Input(value="a1あ11bcdaef123a1a") + + renderable_cursor = _InputRenderable(input_widget, cursor_visible=True) + renderable_no_cursor = _InputRenderable(input_widget, cursor_visible=False) diff --git a/tests/test_segment_tools.py b/tests/test_segment_tools.py index 630114ed9..7483d2b15 100644 --- a/tests/test_segment_tools.py +++ b/tests/test_segment_tools.py @@ -63,6 +63,17 @@ def test_line_crop_edge_2(): assert result == expected +def test_line_crop_highlight_reverse_bug(): + """Regression test for #818""" + segments_joined = [Segment('a1あ11bcdaef123a1a')] + segments_split = [Segment('a1あ11bcdaef'), Segment('1'), Segment('23a1a')] + + joined1 = "".join(seg.text for seg in line_crop(segments_split, start=9, end=16, total=23)) + joined2 = "".join(seg.text for seg in line_crop(segments_joined, start=9, end=16, total=23)) + + assert joined1 == joined2 + + def test_line_trim(): segments = [Segment("foo")] From a617d4091cd90d645a1181a5a6f6f500a36639b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 16:48:43 +0000 Subject: [PATCH 078/310] Add example with all margin rules. --- docs/examples/styles/margin_all.css | 54 +++++++++++++++++++++++++++++ docs/examples/styles/margin_all.py | 20 +++++++++++ 2 files changed, 74 insertions(+) create mode 100644 docs/examples/styles/margin_all.css create mode 100644 docs/examples/styles/margin_all.py diff --git a/docs/examples/styles/margin_all.css b/docs/examples/styles/margin_all.css new file mode 100644 index 000000000..a6b1e7dc3 --- /dev/null +++ b/docs/examples/styles/margin_all.css @@ -0,0 +1,54 @@ +Screen { + background: $background; +} + +Grid { + grid-size: 4; + grid-gutter: 1 2; +} + +Placeholder { + width: 100%; + height: 100%; +} + +Container { + width: 100%; + height: 100%; +} + +.bordered { + border: white round; +} + +#p1 { + /* default is no margin */ +} + +#p2 { + margin: 1; +} + +#p3 { + margin: 1 5; +} + +#p4 { + margin: 1 1 2 6; +} + +#p5 { + margin-top: 4; +} + +#p6 { + margin-right: 3; +} + +#p7 { + margin-bottom: 4; +} + +#p8 { + margin-left: 3; +} diff --git a/docs/examples/styles/margin_all.py b/docs/examples/styles/margin_all.py new file mode 100644 index 000000000..b88705f26 --- /dev/null +++ b/docs/examples/styles/margin_all.py @@ -0,0 +1,20 @@ +from textual.app import App +from textual.containers import Container, Grid +from textual.widgets import Placeholder + + +class MarginAllApp(App): + def compose(self): + yield Grid( + Container(Placeholder("no margin", id="p1"), classes="bordered"), + Container(Placeholder("margin: 1", id="p2"), classes="bordered"), + Container(Placeholder("margin: 1 5", id="p3"), classes="bordered"), + Container(Placeholder("margin: 1 1 2 6", id="p4"), classes="bordered"), + Container(Placeholder("margin-top: 4", id="p5"), classes="bordered"), + Container(Placeholder("margin-right: 3", id="p6"), classes="bordered"), + Container(Placeholder("margin-bottom: 4", id="p7"), classes="bordered"), + Container(Placeholder("margin-left: 3", id="p8"), classes="bordered"), + ) + + +app = MarginAllApp(css_path="margin_all.css") From e789c9c006faca9c76f77871cff442a8978a9305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 16:49:27 +0000 Subject: [PATCH 079/310] Use labels instead of statics. --- docs/examples/styles/margin.css | 8 ++++---- docs/examples/styles/margin.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/styles/margin.css b/docs/examples/styles/margin.css index e1b01fa03..296a88174 100644 --- a/docs/examples/styles/margin.css +++ b/docs/examples/styles/margin.css @@ -3,8 +3,8 @@ Screen { color: black; } -Static { - margin: 4 8; - background: blue 20%; +Label { + margin: 4 8; + background: blue 20%; border: blue wide; -} +} diff --git a/docs/examples/styles/margin.py b/docs/examples/styles/margin.py index 3e6129ead..7551d5865 100644 --- a/docs/examples/styles/margin.py +++ b/docs/examples/styles/margin.py @@ -1,5 +1,5 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label TEXT = """I must not fear. Fear is the mind-killer. @@ -12,7 +12,7 @@ Where the fear has gone there will be nothing. Only I will remain.""" class MarginApp(App): def compose(self): - yield Static(TEXT) + yield Label(TEXT) app = MarginApp(css_path="margin.css") From 6a07f300942ae9694b0d25138d545d9fec03b518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 16:49:44 +0000 Subject: [PATCH 080/310] Complete margin reference. --- docs/styles/margin.md | 67 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/docs/styles/margin.md b/docs/styles/margin.md index 21cab8c61..41bb34a04 100644 --- a/docs/styles/margin.md +++ b/docs/styles/margin.md @@ -2,25 +2,37 @@ The `margin` rule adds space around the entire widget. Margin may be specified with 1, 2 or 4 values. -| Example | Description | -|--------------------|---------------------------------------------------------------------| -| `margin: 1;` | A single value sets a margin of 1 around all 4 edges | -| `margin: 1 2;` | Two values sets the margin for the top/bottom and left/right edges | -| `margin: 1 2 3 4;` | Four values sets top, right, bottom, and left margins independently | +| Example | Description | +|--------------------|----------------------------------------------------------------------| +| `margin: 1;` | A single value sets the margin around all 4 edges. | +| `margin: 1 2;` | Two values sets the margin for the top/bottom and left/right edges. | +| `margin: 1 2 3 4;` | Four values sets top, right, bottom, and left margins independently. | Margin may also be set individually by setting `margin-top`, `margin-right`, `margin-bottom`, or `margin-left` to a single value. ## Syntax ``` -margin: ; +margin: ; /* Same value for the 4 edges. */ margin: ; +/* top/bot, left/right */ margin: ; +/* top, right, bottom, left */ + +margin-top: ; +margin-right: ; +margin-bottom: ; +margin-left: ; ``` -## Example +## Examples -In this example we add a large margin to some static text. +In the example below we add a large margin to a label, which makes it move away from the top-left corner of the screen. + +=== "Output" + + ```{.textual path="docs/examples/styles/margin.py"} + ``` === "margin.py" @@ -34,21 +46,54 @@ In this example we add a large margin to some static text. --8<-- "docs/examples/styles/margin.css" ``` +The next example shows a grid. +In each cell, we have a placeholder that has its margins set in different ways. + === "Output" - ```{.textual path="docs/examples/styles/margin.py"} + ```{.textual path="docs/examples/styles/margin_all.py"} + ``` + +=== "margin_all.py" + + ```py + --8<-- "docs/examples/styles/margin_all.py" + ``` + +=== "margin_all.css" + + ```py + --8<-- "docs/examples/styles/margin_all.css" ``` ## CSS ```sass +/* Set margin of 1 around all edges */ +margin: 1 /* Set margin of 2 on the top and bottom edges, and 4 on the left and right */ margin: 2 4; +/* Set margin of 1 on the top, 2 on the right, + 3 on the bottom, and 4 on the left */ +margin: 1 2 3 4; + +margin-top: 1; +margin-right: 2; +margin-bottom: 3; +margin-left: 4; ``` ## Python +In Python, you cannot set any of the individual `margin` rules `margin-top`, `margin-right`, `margin-bottom`, and `margin-left`. + +However, you _can_ set margin to a single integer, a tuple of 2 integers, or a tuple of 4 integers: + ```python -# In Python you can set the margin as a tuple of integers -widget.styles.margin = (2, 3) +# Set margin of 1 around all edges +widget.styles.margin = 1 +# Set margin of 2 on the top and bottom edges, and 4 on the left and right +widget.styles.margin = (2, 4) +# Set margin of 1 on top, 2 on the right, 3 on the bottom, and 4 on the left +widget.styles.margin = (1, 2, 3, 4) ``` From dfcaada0b84181e19b55bd5b33a92f6e5ffdf453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 17:30:55 +0000 Subject: [PATCH 081/310] Move snippets to top level of docs. --- docs/{styles => }/snippets/color_css_syntax.md | 0 docs/{styles => }/snippets/fractional_syntax.md | 0 docs/{styles => }/snippets/percentage_syntax.md | 0 docs/{styles => }/snippets/scalar_syntax.md | 0 docs/{styles => }/snippets/text_style_syntax.md | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename docs/{styles => }/snippets/color_css_syntax.md (100%) rename docs/{styles => }/snippets/fractional_syntax.md (100%) rename docs/{styles => }/snippets/percentage_syntax.md (100%) rename docs/{styles => }/snippets/scalar_syntax.md (100%) rename docs/{styles => }/snippets/text_style_syntax.md (100%) diff --git a/docs/styles/snippets/color_css_syntax.md b/docs/snippets/color_css_syntax.md similarity index 100% rename from docs/styles/snippets/color_css_syntax.md rename to docs/snippets/color_css_syntax.md diff --git a/docs/styles/snippets/fractional_syntax.md b/docs/snippets/fractional_syntax.md similarity index 100% rename from docs/styles/snippets/fractional_syntax.md rename to docs/snippets/fractional_syntax.md diff --git a/docs/styles/snippets/percentage_syntax.md b/docs/snippets/percentage_syntax.md similarity index 100% rename from docs/styles/snippets/percentage_syntax.md rename to docs/snippets/percentage_syntax.md diff --git a/docs/styles/snippets/scalar_syntax.md b/docs/snippets/scalar_syntax.md similarity index 100% rename from docs/styles/snippets/scalar_syntax.md rename to docs/snippets/scalar_syntax.md diff --git a/docs/styles/snippets/text_style_syntax.md b/docs/snippets/text_style_syntax.md similarity index 100% rename from docs/styles/snippets/text_style_syntax.md rename to docs/snippets/text_style_syntax.md From 52b30c8d3b094baad7e058ab3c7286b63cdc7ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 17:32:23 +0000 Subject: [PATCH 082/310] Add snippets for syntax code blocks. When defining the formal syntax of CSS rules we will use a syntax similar to that of the MDN docs and we want to be able to link directly from the syntax to the CSS types involved, so we cannot do that from within a markdown code block. Instead, we use explicit HTML that we include in two snippets so that it is easier to maintain. --- docs/snippets/syntax_block_end.md | 2 ++ docs/snippets/syntax_block_start.md | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 docs/snippets/syntax_block_end.md create mode 100644 docs/snippets/syntax_block_start.md diff --git a/docs/snippets/syntax_block_end.md b/docs/snippets/syntax_block_end.md new file mode 100644 index 000000000..a100faef8 --- /dev/null +++ b/docs/snippets/syntax_block_end.md @@ -0,0 +1,2 @@ + + diff --git a/docs/snippets/syntax_block_start.md b/docs/snippets/syntax_block_start.md new file mode 100644 index 000000000..3eddc9775 --- /dev/null +++ b/docs/snippets/syntax_block_start.md @@ -0,0 +1,2 @@ + +


From 74c525e56d96934d52dc02c91c1ae8b86b1a248a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?=
 <5621605+rodrigogiraoserrao@users.noreply.github.com>
Date: Wed, 21 Dec 2022 17:32:44 +0000
Subject: [PATCH 083/310] Rename CSS units as CSS types.

---
 docs/{styles/css_units => css_types}/color.md      |  0
 docs/{styles/css_units => css_types}/fractional.md |  0
 docs/css_types/index.md                            | 12 ++++++++++++
 docs/{styles/css_units => css_types}/integer.md    |  0
 docs/{styles/css_units => css_types}/percentage.md |  0
 docs/{styles/css_units => css_types}/scalar.md     |  0
 docs/{styles/css_units => css_types}/text_style.md |  0
 docs/styles/css_units/index.md                     | 12 ------------
 8 files changed, 12 insertions(+), 12 deletions(-)
 rename docs/{styles/css_units => css_types}/color.md (100%)
 rename docs/{styles/css_units => css_types}/fractional.md (100%)
 create mode 100644 docs/css_types/index.md
 rename docs/{styles/css_units => css_types}/integer.md (100%)
 rename docs/{styles/css_units => css_types}/percentage.md (100%)
 rename docs/{styles/css_units => css_types}/scalar.md (100%)
 rename docs/{styles/css_units => css_types}/text_style.md (100%)
 delete mode 100644 docs/styles/css_units/index.md

diff --git a/docs/styles/css_units/color.md b/docs/css_types/color.md
similarity index 100%
rename from docs/styles/css_units/color.md
rename to docs/css_types/color.md
diff --git a/docs/styles/css_units/fractional.md b/docs/css_types/fractional.md
similarity index 100%
rename from docs/styles/css_units/fractional.md
rename to docs/css_types/fractional.md
diff --git a/docs/css_types/index.md b/docs/css_types/index.md
new file mode 100644
index 000000000..60aaaa695
--- /dev/null
+++ b/docs/css_types/index.md
@@ -0,0 +1,12 @@
+# CSS Types
+
+CSS types define the values that Textual CSS rules accept.
+
+CSS types will be linked from within the [styles reference](../styles/index.md) in the "Formal Syntax" section of each rule.
+The CSS types will be denoted by a keyword enclosed by angle brackets `<` and `>`.
+
+For example, the style [`align-horizontal`](../styles/align.md) references the CSS type [](./horizontal.md):
+
+--8<-- "docs/snippets/syntax_block_start.md"
+align-horizontal: <horizontal>
+--8<-- "docs/snippets/syntax_block_end.md"
diff --git a/docs/styles/css_units/integer.md b/docs/css_types/integer.md
similarity index 100%
rename from docs/styles/css_units/integer.md
rename to docs/css_types/integer.md
diff --git a/docs/styles/css_units/percentage.md b/docs/css_types/percentage.md
similarity index 100%
rename from docs/styles/css_units/percentage.md
rename to docs/css_types/percentage.md
diff --git a/docs/styles/css_units/scalar.md b/docs/css_types/scalar.md
similarity index 100%
rename from docs/styles/css_units/scalar.md
rename to docs/css_types/scalar.md
diff --git a/docs/styles/css_units/text_style.md b/docs/css_types/text_style.md
similarity index 100%
rename from docs/styles/css_units/text_style.md
rename to docs/css_types/text_style.md
diff --git a/docs/styles/css_units/index.md b/docs/styles/css_units/index.md
deleted file mode 100644
index 45c5735fc..000000000
--- a/docs/styles/css_units/index.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# CSS units
-
-Many CSS rules accept units of some sort, as opposed to a set of values.
-
-The different CSS units are:
-
- - [color](./color.md) – e.g., to set the background color of a widget;
- - [fractional](./fractional.md) – e.g., to set the opacity of a widget;
- - [integer](./integer.md) – e.g., to set the size of a grid layout;
- - [percentage](./percentage.md) – e.g., to set the transparency of colors;
- - [scalar](./scalar.md) – e.g., to set the dimensions of a widget; and
- - [text style](./text_style.md) – e.g., to style the text of a widget.

From fe0ee2634b4136c34036f6793329cd755b3fdf77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?=
 <5621605+rodrigogiraoserrao@users.noreply.github.com>
Date: Wed, 21 Dec 2022 17:33:28 +0000
Subject: [PATCH 084/310] Sync mkdocs and reference index with changes.

---
 docs/reference/index.md |  9 +++++++++
 mkdocs.yml              | 16 ++++++++--------
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/docs/reference/index.md b/docs/reference/index.md
index 1ddd462b1..607587a59 100644
--- a/docs/reference/index.md
+++ b/docs/reference/index.md
@@ -4,6 +4,15 @@ Welcome to the Textual Reference.
 
 
+- :octicons-book-16:{ .lg .middle } __CSS Types__ + + --- + + CSS Types are the data types that CSS [styles](../styles/index.md) accept in their rules. + + :octicons-arrow-right-24: [CSS Types Reference](../css_types/index.md) + + - :octicons-book-16:{ .lg .middle } __Events__ --- diff --git a/mkdocs.yml b/mkdocs.yml index bcd98b6fa..92b192279 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -28,6 +28,14 @@ nav: - "roadmap.md" - Reference: - "reference/index.md" + - CSS Types: + - "css_types/index.md" + - "css_types/color.md" + - "css_types/fractional.md" + - "css_types/integer.md" + - "css_types/percentage.md" + - "css_types/scalar.md" + - "css_types/text_style.md" - Events: - "events/index.md" - "events/blur.md" @@ -54,14 +62,6 @@ nav: - "events/screen_suspend.md" - "events/show.md" - Styles: - - CSS units: - - "styles/css_units/index.md" - - "styles/css_units/color.md" - - "styles/css_units/fractional.md" - - "styles/css_units/integer.md" - - "styles/css_units/percentage.md" - - "styles/css_units/scalar.md" - - "styles/css_units/text_style.md" - "styles/index.md" - "styles/align.md" - "styles/background.md" From 673088ca93f20349362505ef194edc31a762e456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 17:37:36 +0000 Subject: [PATCH 085/310] Fix issue with < and > characters. --- docs/css_types/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/css_types/index.md b/docs/css_types/index.md index 60aaaa695..4de42270c 100644 --- a/docs/css_types/index.md +++ b/docs/css_types/index.md @@ -5,7 +5,7 @@ CSS types define the values that Textual CSS rules accept. CSS types will be linked from within the [styles reference](../styles/index.md) in the "Formal Syntax" section of each rule. The CSS types will be denoted by a keyword enclosed by angle brackets `<` and `>`. -For example, the style [`align-horizontal`](../styles/align.md) references the CSS type [](./horizontal.md): +For example, the style [`align-horizontal`](../styles/align.md) references the CSS type [``](./horizontal.md): --8<-- "docs/snippets/syntax_block_start.md" align-horizontal: <horizontal> From bcd08d2d46c1e08406e9fedd4a9373c0cf395687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 17:52:15 +0000 Subject: [PATCH 086/310] Remove css type . --- docs/css_types/fractional.md | 28 ---------------------------- docs/snippets/fractional_syntax.md | 6 ------ 2 files changed, 34 deletions(-) delete mode 100644 docs/css_types/fractional.md delete mode 100644 docs/snippets/fractional_syntax.md diff --git a/docs/css_types/fractional.md b/docs/css_types/fractional.md deleted file mode 100644 index 9ef896916..000000000 --- a/docs/css_types/fractional.md +++ /dev/null @@ -1,28 +0,0 @@ -# Fractional - -## Syntax - ---8<-- "docs/styles/snippets/fractional_syntax.md" - -!!! warning - - Not to be confused with the [percentage](./percentage.md) unit nor with the [scalar](./scalar.md) unit. - -## Examples - -```css -Widget { - text-opacity: 0.45; - text-opacity: 45%; -} -``` - -```py -widget.styles.text_opacity = 0.45 -widget.styles.text_opacity = "45%" -``` - -## Used by - - - [`opacity`](../opacity.md) - - [`text-opacity`](../text_opacity.md) diff --git a/docs/snippets/fractional_syntax.md b/docs/snippets/fractional_syntax.md deleted file mode 100644 index 9c7a28029..000000000 --- a/docs/snippets/fractional_syntax.md +++ /dev/null @@ -1,6 +0,0 @@ -A [fractional](/styles/css_units/fractional) value can be set to - - - a float between 0 and 1 (e.g., `0.45`); or - - a percentage between 0% and 100% (e.g., `45%`). - -Values outside their ranges will be clamped. From c973fb4cba1eb5aafc7bf0299ae08c8d33f395de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 17:56:17 +0000 Subject: [PATCH 087/310] Update links to snippets. --- docs/css_types/color.md | 2 +- docs/css_types/percentage.md | 2 +- docs/css_types/scalar.md | 2 +- docs/css_types/text_style.md | 2 +- docs/styles/background.md | 2 +- docs/styles/border.md | 2 +- docs/styles/color.md | 2 +- docs/styles/grid/grid_columns.md | 2 +- docs/styles/grid/grid_gutter.md | 2 +- docs/styles/grid/grid_rows.md | 2 +- docs/styles/height.md | 2 +- docs/styles/links/index.md | 4 ++-- docs/styles/links/link_background.md | 4 ++-- docs/styles/links/link_color.md | 4 ++-- docs/styles/links/link_hover_background.md | 4 ++-- docs/styles/links/link_hover_color.md | 4 ++-- docs/styles/links/link_hover_style.md | 4 ++-- docs/styles/links/link_style.md | 2 +- 18 files changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/css_types/color.md b/docs/css_types/color.md index 18297fc1c..df4b2d6ba 100644 --- a/docs/css_types/color.md +++ b/docs/css_types/color.md @@ -9,7 +9,7 @@ For example, the `background` rule sets the color of the background of a widget. ## Syntax ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" ## Examples diff --git a/docs/css_types/percentage.md b/docs/css_types/percentage.md index 70dd51292..dcc05a358 100644 --- a/docs/css_types/percentage.md +++ b/docs/css_types/percentage.md @@ -2,7 +2,7 @@ ## Syntax ---8<-- "docs/styles/snippets/percentage_syntax.md" +--8<-- "docs/snippets/percentage_syntax.md" !!! warning diff --git a/docs/css_types/scalar.md b/docs/css_types/scalar.md index 3a50d8397..e889e8377 100644 --- a/docs/css_types/scalar.md +++ b/docs/css_types/scalar.md @@ -7,7 +7,7 @@ Scalars also accept the special value `auto`. ## Syntax ---8<-- "docs/styles/snippets/scalar_syntax.md" +--8<-- "docs/snippets/scalar_syntax.md" A complete reference table and detailed explanations follow. You can [skip to the examples](#Examples). diff --git a/docs/css_types/text_style.md b/docs/css_types/text_style.md index 02474ce9b..7e7860906 100644 --- a/docs/css_types/text_style.md +++ b/docs/css_types/text_style.md @@ -8,7 +8,7 @@ The text style unit is a combination of any of the legal text style values in a ## Syntax ---8<-- "docs/styles/snippets/text_style_syntax.md" +--8<-- "docs/snippets/text_style_syntax.md" ## Examples diff --git a/docs/styles/background.md b/docs/styles/background.md index aadfd273f..43d43621b 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -8,7 +8,7 @@ The `background` rule sets the background color of a widget. background: []; ``` ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" The optional [percentage](./css_units/percentage.md) sets the transparency level and will override any transparency specified directly in the color. diff --git a/docs/styles/border.md b/docs/styles/border.md index 710bcb601..6203fa210 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -38,7 +38,7 @@ For example, `heavy white` would display a heavy white line around a widget. ### Color syntax ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" ### Multiple edge rules diff --git a/docs/styles/color.md b/docs/styles/color.md index f2b85507b..b7994dc40 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -10,7 +10,7 @@ color: ( | auto) []; Use `auto` to automatically choose a color with suitable contrast for readability. ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" The optional [percentage](./css_units/percentage.md) sets the transparency level and will override any transparency specified directly in the color. diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index a75fd6157..74762814d 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -16,7 +16,7 @@ If there are more columns in the grid than scalars specified in `grid-columns`, Scalar units can be mixed. ---8<-- "docs/styles/snippets/scalar_syntax.md" +--8<-- "docs/snippets/scalar_syntax.md" ## Example diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md index 843fae81d..f5dc0c785 100644 --- a/docs/styles/grid/grid_gutter.md +++ b/docs/styles/grid/grid_gutter.md @@ -19,7 +19,7 @@ grid-gutter: []; If only one scalar is supplied, it sets the horizontal and vertical gutter. If two scalars are supplied, they set the vertical and horizontal gutters, respectively. ---8<-- "docs/styles/snippets/scalar_syntax.md" +--8<-- "docs/snippets/scalar_syntax.md" ## Example diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index 5859b80ce..81d1c1fae 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -16,7 +16,7 @@ If there are more rows in the grid than scalars specified in `grid-rows`, they a Scalar units can be mixed. ---8<-- "docs/styles/snippets/scalar_syntax.md" +--8<-- "docs/snippets/scalar_syntax.md" ## Example diff --git a/docs/styles/height.md b/docs/styles/height.md index d3ce3b8f0..f3003dd88 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -8,7 +8,7 @@ The `height` rule sets a widget's height. By default, it sets the height of the height: ; ``` ---8<-- "docs/styles/snippets/scalar_syntax.md" +--8<-- "docs/snippets/scalar_syntax.md" ## Examples diff --git a/docs/styles/links/index.md b/docs/styles/links/index.md index 855e391ce..d2cab4887 100644 --- a/docs/styles/links/index.md +++ b/docs/styles/links/index.md @@ -28,9 +28,9 @@ link-hover-background: []; link-hover-style: ; ``` ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" ---8<-- "docs/styles/snippets/text_style_syntax.md" +--8<-- "docs/snippets/text_style_syntax.md" ## Example diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md index 9f69c06f1..81e70b446 100644 --- a/docs/styles/links/link_background.md +++ b/docs/styles/links/link_background.md @@ -12,9 +12,9 @@ The `link-background` sets the background color of the link. link-background: ; ``` ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" ---8<-- "docs/styles/snippets/percentage_syntax.md" +--8<-- "docs/snippets/percentage_syntax.md" ## Example diff --git a/docs/styles/links/link_color.md b/docs/styles/links/link_color.md index 8e9fa0e57..c226281b9 100644 --- a/docs/styles/links/link_color.md +++ b/docs/styles/links/link_color.md @@ -12,9 +12,9 @@ The `link-color` sets the color of the link text. link-color: ; ``` ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" ---8<-- "docs/styles/snippets/percentage_syntax.md" +--8<-- "docs/snippets/percentage_syntax.md" ## Example diff --git a/docs/styles/links/link_hover_background.md b/docs/styles/links/link_hover_background.md index 1e6cf8659..d1d2a5c85 100644 --- a/docs/styles/links/link_hover_background.md +++ b/docs/styles/links/link_hover_background.md @@ -12,9 +12,9 @@ The `link-hover-background` sets the background color of the link when the mouse link-hover-background: ; ``` ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" ---8<-- "docs/styles/snippets/percentage_syntax.md" +--8<-- "docs/snippets/percentage_syntax.md" ## Example diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md index 0e19ce95e..df781c78d 100644 --- a/docs/styles/links/link_hover_color.md +++ b/docs/styles/links/link_hover_color.md @@ -12,9 +12,9 @@ The `link-hover-color` sets the color of the link text when the mouse cursor is link-hover-color: ; ``` ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" ---8<-- "docs/styles/snippets/percentage_syntax.md" +--8<-- "docs/snippets/percentage_syntax.md" ## Example diff --git a/docs/styles/links/link_hover_style.md b/docs/styles/links/link_hover_style.md index 45479ea7c..308a56ad1 100644 --- a/docs/styles/links/link_hover_style.md +++ b/docs/styles/links/link_hover_style.md @@ -12,9 +12,9 @@ The `link-hover-style` sets the text style for the link text when the mouse curs link-hover-style: ; ``` ---8<-- "docs/styles/snippets/color_css_syntax.md" +--8<-- "docs/snippets/color_css_syntax.md" ---8<-- "docs/styles/snippets/percentage_syntax.md" +--8<-- "docs/snippets/percentage_syntax.md" ## Example diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md index 2dff30b3a..8a79c75c3 100644 --- a/docs/styles/links/link_style.md +++ b/docs/styles/links/link_style.md @@ -12,7 +12,7 @@ The `link-style` sets the text style for the link text. link-style: ; ``` ---8<-- "docs/styles/snippets/text_style_syntax.md" +--8<-- "docs/snippets/text_style_syntax.md" ## Example From 3953eb742c4d95c869374c3780635008f368d885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 18:12:10 +0000 Subject: [PATCH 088/310] Delete section 'Used by'. --- docs/css_types/color.md | 21 --------------------- docs/css_types/integer.md | 10 ---------- docs/css_types/percentage.md | 6 ------ docs/css_types/scalar.md | 14 -------------- docs/css_types/text_style.md | 7 ------- 5 files changed, 58 deletions(-) diff --git a/docs/css_types/color.md b/docs/css_types/color.md index df4b2d6ba..cf6754f89 100644 --- a/docs/css_types/color.md +++ b/docs/css_types/color.md @@ -38,24 +38,3 @@ widget.styles.background = Color(16, 200, 45) # ... which can also parse the CSS syntax widget.styles.background = Color.parse("#A8F") ``` - -## Used by - - - [`background`](../background.md) - - [`border`](../border.md) - - [`color`](../color.md) - - Links: - - [`link-color`](../links/link_color.md) - - [`link-background`](../links/link_background.md) - - [`link-hover-color`](../links/link_hover_color.md) - - [`link-hover-background`](../links/link_hover_background.md) - - [`outline`](../outline.md) - - Scrollbars: - - [`scrollbar-color`](../scrollbar_colors/scrollbar_color.md) - - [`scrollbar-color-hover`](../scrollbar_colors/scrollbar_color_hover.md) - - [`scrollbar-color-active`](../scrollbar_colors/scrollbar_color_active.md) - - [`scrollbar-background`](../scrollbar_colors/scrollbar_background.md) - - [`scrollbar-background-hover`](../scrollbar_colors/scrollbar_background_hover.md) - - [`scrollbar-background-active`](../scrollbar_colors/scrollbar_background_active.md) - - [`scrollbar-corner-color`](../scrollbar_colors/scrollbar_corner_color.md) - - [`tint`](../tint.md) diff --git a/docs/css_types/integer.md b/docs/css_types/integer.md index 82fb5bd67..dacab27c6 100644 --- a/docs/css_types/integer.md +++ b/docs/css_types/integer.md @@ -18,13 +18,3 @@ Widget { ```py widget.styles.offset = (-5, 10) ``` - -## Used by - - - Grids: - - [`grid-size`](../grid/grid_size.md) - - [`grid-rows`](../grid/grid_rows.md) - - [`grid-columns`](../grid/grid_columns.md) - - [`margin`](../margin.md) - - [`padding`](../padding.md) - - [`scrollbar-size`](../scrollbar_size.md) diff --git a/docs/css_types/percentage.md b/docs/css_types/percentage.md index dcc05a358..e0d3fd1d7 100644 --- a/docs/css_types/percentage.md +++ b/docs/css_types/percentage.md @@ -19,9 +19,3 @@ Widget { ```py widget.styles.background = "red 70%" ``` - -## Used by - - - [`background`](../background.md) - - [`color`](../color.md) - - [`tint`](../tint.md) diff --git a/docs/css_types/scalar.md b/docs/css_types/scalar.md index e889e8377..14a33a361 100644 --- a/docs/css_types/scalar.md +++ b/docs/css_types/scalar.md @@ -107,17 +107,3 @@ widget.styles.width = "25vw" widget.styles.width = "75vh" widget.styles.width = "auto" ``` - -## Used by - - - Grids: - - [`grid-rows`](../grid/grid_rows.md) - - [`grid-columns`](../grid/grid_columns.md) - - [`grid-gutter`](../grid/grid_gutter.md) - - [`height`](../height.md) - - [`max-height`](../max_height.md) - - [`max-width`](../max_width.md) - - [`min-height`](../min_height.md) - - [`min-width`](../min_width.md) - - [`offset`](../offset.md) - - [`width`](../width.md) diff --git a/docs/css_types/text_style.md b/docs/css_types/text_style.md index 7e7860906..c8e29608c 100644 --- a/docs/css_types/text_style.md +++ b/docs/css_types/text_style.md @@ -42,10 +42,3 @@ widget.styles.text_style = "strike" widget.styles.text_style = "strike bold italic reverse" widget.styles.text_style = "bold underline italic" ``` - -## Used by - - - Links: - - [`link-style`](../links/link_style.md) - - [`link-hover-style`](../links/link_hover_style.md) - - [`text-style`](../text_style.md) From bf2000f9b587cc1d7af22f4dcf00b36b4b770bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 19:40:18 +0000 Subject: [PATCH 089/310] Create subfolder for syntax snippets. --- docs/snippets/percentage_syntax.md | 2 -- .../{color_css_syntax.md => type_syntax/color.md} | 4 ++-- docs/snippets/type_syntax/percentage.md | 2 ++ docs/snippets/{scalar_syntax.md => type_syntax/scalar.md} | 2 +- .../{text_style_syntax.md => type_syntax/text_style.md} | 8 ++++---- mkdocs.yml | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 docs/snippets/percentage_syntax.md rename docs/snippets/{color_css_syntax.md => type_syntax/color.md} (65%) create mode 100644 docs/snippets/type_syntax/percentage.md rename docs/snippets/{scalar_syntax.md => type_syntax/scalar.md} (86%) rename docs/snippets/{text_style_syntax.md => type_syntax/text_style.md} (84%) diff --git a/docs/snippets/percentage_syntax.md b/docs/snippets/percentage_syntax.md deleted file mode 100644 index 179cf1753..000000000 --- a/docs/snippets/percentage_syntax.md +++ /dev/null @@ -1,2 +0,0 @@ -A [percentage](/styles/css_units/percentage) is a number followed by the percent sign. -The number doesn't have to be an integer and values are clamped between 0% and 100%. diff --git a/docs/snippets/color_css_syntax.md b/docs/snippets/type_syntax/color.md similarity index 65% rename from docs/snippets/color_css_syntax.md rename to docs/snippets/type_syntax/color.md index 8e818339a..7b87daac3 100644 --- a/docs/snippets/color_css_syntax.md +++ b/docs/snippets/type_syntax/color.md @@ -1,9 +1,9 @@ -The legal values for a [color](/styles/css_units/color) depend on the [class `Color`][textual.color.Color] and include: +The legal values for a [``](/css_types/color) depend on the [class `Color`][textual.color.Color] and include: - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); - a color description in the RGB system (e.g., `rgb(23,78,200)`); - a color description in the HSL system (e.g., `hsl(290,70%,80%)`); and - - a color variable from [Textual's default themes](../../guide/design#theme-reference). For more details about the exact formats accepted, see [the class method `Color.parse`][textual.color.Color.parse]. +[Textual's default themes](../../guide/design#theme-reference) also provide many CSS variables with colors. diff --git a/docs/snippets/type_syntax/percentage.md b/docs/snippets/type_syntax/percentage.md new file mode 100644 index 000000000..ae6d3a619 --- /dev/null +++ b/docs/snippets/type_syntax/percentage.md @@ -0,0 +1,2 @@ +A [``](/css_types/percentage) is a [``](/css_types/number) followed by the percent sign `%` (without spaces). +Some rules may clamp the values between `0%` and `100%`. diff --git a/docs/snippets/scalar_syntax.md b/docs/snippets/type_syntax/scalar.md similarity index 86% rename from docs/snippets/scalar_syntax.md rename to docs/snippets/type_syntax/scalar.md index 22e022663..f29e9f4b2 100644 --- a/docs/snippets/scalar_syntax.md +++ b/docs/snippets/type_syntax/scalar.md @@ -1,4 +1,4 @@ -A [scalar](/styles/css_units/scalar) can be any of the following: +A [``](/css_types/scalar) can be any of the following: - a fixed number of cells (e.g., `10`); - a fractional proportion relative to the sizes of the other widgets (e.g., `1fr`); diff --git a/docs/snippets/text_style_syntax.md b/docs/snippets/type_syntax/text_style.md similarity index 84% rename from docs/snippets/text_style_syntax.md rename to docs/snippets/type_syntax/text_style.md index 532b83cf8..0e544bfcc 100644 --- a/docs/snippets/text_style_syntax.md +++ b/docs/snippets/type_syntax/text_style.md @@ -1,10 +1,10 @@ -The [text style](/styles/css_units/text_style) unit can be any _space-separated_ combination of the following values: +The [``](/css_types/text_style) type can be any _space-separated_ combination of the following values: | Value | Description | |-------------|----------------------------------------------------------------| | `bold` | **bold text** | | `italic` | _italic text_ | -| `reverse` | reverse video text (foreground and background colors reversed) | -| `underline` | underline text | -| `strike` | strikethrough text | | `none` | plain text with no styling | +| `reverse` | reverse video text (foreground and background colors reversed) | +| `strike` | strikethrough text | +| `underline` | underline text | diff --git a/mkdocs.yml b/mkdocs.yml index 92b192279..3bfe525c2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -31,8 +31,8 @@ nav: - CSS Types: - "css_types/index.md" - "css_types/color.md" - - "css_types/fractional.md" - "css_types/integer.md" + - "css_types/number.md" - "css_types/percentage.md" - "css_types/scalar.md" - "css_types/text_style.md" From cf6cd06a33db2e92e44f3e54dfde9de7dc2c55a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 19:41:19 +0000 Subject: [PATCH 090/310] Add CSS type number. --- docs/css_types/number.md | 31 +++++++++++++++++++++++++++++ docs/snippets/type_syntax/number.md | 1 + 2 files changed, 32 insertions(+) create mode 100644 docs/css_types/number.md create mode 100644 docs/snippets/type_syntax/number.md diff --git a/docs/css_types/number.md b/docs/css_types/number.md new file mode 100644 index 000000000..0e1cc3e8f --- /dev/null +++ b/docs/css_types/number.md @@ -0,0 +1,31 @@ +# <number> + +The `` CSS type represents a real number, which can be an integer or a number with a decimal part (akin to a `float` in Python). + +## Syntax + +--8<-- "docs/snippets/type_syntax/number.md" + +## Examples + +### CSS + +```sass +* { + css-rule: 6 /* Integers are numbers */ + css-rule: -13 /* Numbers can be negative */ + css-rule: 4.75 /* Numbers can have a decimal part */ + css-rule: -73.73 +} +``` + +### Python + +In Python, a rule that expects a CSS type `` will accept an `int` or a `float`: + +```py +number = 6 # ints are numbers +number = -13 # ints can be negative +number = 4.75 # floats are numbers +number = -73.73 # negative floats too +``` diff --git a/docs/snippets/type_syntax/number.md b/docs/snippets/type_syntax/number.md new file mode 100644 index 000000000..aaf0aac07 --- /dev/null +++ b/docs/snippets/type_syntax/number.md @@ -0,0 +1 @@ +A [``](/css_types/number) is an [``](/css_types/integer), optionally followed by the decimal point `.` and a decimal part composed of one or more digits. From 175f6b65cbddd597aca18a172e67610f2b286681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 19:41:39 +0000 Subject: [PATCH 091/310] Refactor units to types. --- docs/css_types/color.md | 45 +++++++++++++----------- docs/css_types/integer.md | 25 ++++++++++---- docs/css_types/percentage.md | 26 +++++++++----- docs/css_types/scalar.md | 67 ++++++++++++++++++++---------------- docs/css_types/text_style.md | 55 +++++++++++++++-------------- 5 files changed, 125 insertions(+), 93 deletions(-) diff --git a/docs/css_types/color.md b/docs/css_types/color.md index cf6754f89..db3e82b96 100644 --- a/docs/css_types/color.md +++ b/docs/css_types/color.md @@ -1,40 +1,43 @@ -# Color unit +# <color> -Color units are used with rules that need to set the color of a part of a widget. -For example, the `background` rule sets the color of the background of a widget. +The `` CSS type represents a color. !!! warning - Not to be confused with the [`color`](../color.md) CSS rule to set text color. + Not to be confused with the [`color`](../styles/color.md) CSS rule to set text color. ## Syntax ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" ## Examples -```css -Widget { - background: red; /* color name */ - background: #A8F; /* 3-digit hex RGB */ - background: #FF00FFDD; /* 6-digit hex RGB + transparency */ - background: rgb(15,200,73); /* RGB description */ - background: hsl(300,20%,70%); /* HSL description */ - background: $accent; /* Textual variable */ +### CSS + +```sass +* { + rule: red; /* color name */ + rule: #A8F; /* 3-digit hex RGB */ + rule: #FF00FFDD; /* 6-digit hex RGB + transparency */ + rule: rgb(15,200,73); /* RGB description */ + rule: hsl(300,20%,70%); /* HSL description */ + rule: $accent; /* Textual variable */ } ``` +### Python + ```py # Mimicking the CSS syntax -widget.styles.background = "red" -widget.styles.background = "#A8F" -widget.styles.background = "#FF00FFDD" -widget.styles.background = "rgb(15,200,73)" -widget.styles.background = "hsl(300,20%,70%)" -widget.styles.background = "$accent" +color = "red" +color = "#A8F" +color = "#FF00FFDD" +color = "rgb(15,200,73)" +color = "hsl(300,20%,70%)" +color = "$accent" # Using a Color object directly... -widget.styles.background = Color(16, 200, 45) +color = Color(16, 200, 45) # ... which can also parse the CSS syntax -widget.styles.background = Color.parse("#A8F") +color = Color.parse("#A8F") ``` diff --git a/docs/css_types/integer.md b/docs/css_types/integer.md index dacab27c6..c6904fbc3 100644 --- a/docs/css_types/integer.md +++ b/docs/css_types/integer.md @@ -1,20 +1,31 @@ -# Integer +# <integer> -An integer unit. +The `` CSS type represents an integer number and can be positive or negative. + +!!! note + + Some CSS rules may expect an `` within certain bounds. If that is the case, it will be noted in that rule. ## Syntax Any legal integer, like `-10` or `42`. -Integer units can be negative, althought that may not make sense in some rules. ## Examples -```css -Widget { - margin: -5 10; +### CSS + +```sass +* { + rule: -5; + rule: 10; } ``` +### Python + +In Python, a rule that expects a CSS type `` will expect a value of the type `int`: + ```py -widget.styles.offset = (-5, 10) +integer = -5 +integer = 10 ``` diff --git a/docs/css_types/percentage.md b/docs/css_types/percentage.md index e0d3fd1d7..a2f45d274 100644 --- a/docs/css_types/percentage.md +++ b/docs/css_types/percentage.md @@ -1,21 +1,29 @@ -# Percentage +# <percentage> -## Syntax - ---8<-- "docs/snippets/percentage_syntax.md" +The `` CSS type represents a percentage value. +It is often used to represent values that are relative to the parent's values. !!! warning - Not to be confused with the [fractional](./fractional.md) unit nor with the [scalar](./scalar.md) unit. + Not to be confused with the [``](./scalar.md) type. + +## Syntax + +--8<-- "docs/snippets/type_syntax/percentage.md" ## Examples -```css -Widget { - background: red 70%; +### CSS + +```sass +* { + rule: 70%; /* Integer followed by % */ + rule: -3.5%; /* The number can be negative/decimal */ } ``` +### Python + ```py -widget.styles.background = "red 70%" +percentage = "70%" ``` diff --git a/docs/css_types/scalar.md b/docs/css_types/scalar.md index 14a33a361..7e37e7fca 100644 --- a/docs/css_types/scalar.md +++ b/docs/css_types/scalar.md @@ -1,16 +1,19 @@ -# Scalar +# <scalar> -A scalar unit is a numeric value with a unit, e.g., `50vh`. -Scalars are used with styles that specify lengths, like `width` and `height`. +The `` CSS type represents a length. +It can be a [``](./number.md) and a unit, or the special value `auto`. +It is used to represent lengths, for example in the [`width`](../styles/width.md) and [`height`](../styles/height.md) rules. -Scalars also accept the special value `auto`. +!!! warning + + Not to be confused with the [``](./number.md) or [``](./percentage.md) types. ## Syntax ---8<-- "docs/snippets/scalar_syntax.md" +--8<-- "docs/snippets/type_syntax/scalar.md" A complete reference table and detailed explanations follow. -You can [skip to the examples](#Examples). +You can [skip to the examples](#examples). | Unit symbol | Unit | Example | Description | |-------------|-----------------|---------|-------------------------------------------------------------| @@ -36,13 +39,13 @@ For example, in `height: 10`, this sets the height of a widget to be equal to 10 ### Fraction -The fraction scalar is used to represent proportional sizes. +The unit fraction is used to represent proportional sizes. For example, if two widgets are side by side and one has `width: 1fr` and the other has `width: 3fr`, the second one will be three times as wide as the first one. ### Percent -The percent scalar is used to specify a total length relative to the space made available by the container widget. +The percent unit matches a [``](./percentage.md) and is used to specify a total length relative to the space made available by the container widget. If used to specify a horizontal length, it will be relative to the width of the container. For example, `width: 50%` sets the width of a widget to 50% of the width of its container. @@ -52,27 +55,27 @@ For example, `height: 50%` sets the height of a widget to 50% of the height of i ### Width -The width scalar is similar to the percent scalar, except it sets the percentage to be relative to the width of the container. +The width unit is similar to the percent unit, except it sets the percentage to be relative to the width of the container. For example, `width: 25w` sets the width of a widget to 25% of the width of its container and `height: 25w` sets the height of a widget to 25% of the width of its container. So, if the container has a width of 100 cells, the width and the height of the child widget will be of 25 cells. ### Height -The height scalar is similar to the percent scalar, except it sets the percentage to be relative to the height of the container. +The height unit is similar to the percent unit, except it sets the percentage to be relative to the height of the container. For example, `height: 75h` sets the height of a widget to 75% of the height of its container and `width: 75h` sets the width of a widget to 75% of the height of its container. So, if the container has a height of 100 cells, the width and the height of the child widget will be of 75 cells. ### Viewport width -This is the same as the [width scalar](#Width), except that it is relative to the width of the viewport instead of the width of the immediate container. +This is the same as the [width unit](#width), except that it is relative to the width of the viewport instead of the width of the immediate container. For example, `width: 25vw` will try to set the width of a widget to be 25% of the viewport width, regardless of the widths of its containers. ### Viewport height -This is the same as the [height scalar](#Height), except that it is relative to the height of the viewport instead of the height of the immediate container. +This is the same as the [height unit](#height), except that it is relative to the height of the viewport instead of the height of the immediate container. For example, `height: 75vh` will try to set the height of a widget to be 75% of the viewport height, regardless of the height of its containers. @@ -84,26 +87,30 @@ For example, if its container is big enough, a label with `width: auto` will be ## Examples -```css -Widget { - width: 16; - width: 1fr; - width: 50%; - width: 25w; - width: 75h; - width: 25vw; - width: 75vh; - width: auto; +### CSS + +```sass +* { + rule: 16; /* 16 cells */ + rule: 1fr; /* proportional size of 1 */ + rule: 50%; /* 50% of the same dimension of the parent */ + rule: 25w; /* 25% of the width of the parent */ + rule: 75h; /* 75% of the height of the parent */ + rule: 25vw; /* 25% of the viewport width */ + rule: 75vh; /* 75% of the viewport height */ + rule: auto; /* special value */ } ``` +### Python + ```py -widget.styles.width = 16 # Cell scalar can be an int or a float -widget.styles.width = "1fr" -widget.styles.width = "50%" -widget.styles.width = "25w" -widget.styles.width = "75h" -widget.styles.width = "25vw" -widget.styles.width = "75vh" -widget.styles.width = "auto" +scalar = 16 # Cell unit can be specified with an int/float +scalar = "1fr" # proportional size of 1 +scalar = "50%" # 50% of the same dimension of the parent +scalar = "25w" # 25% of the width of the parent +scalar = "75h" # 75% of the height of the parent +scalar = "25vw" # 25% of the viewport width +scalar = "75vh" # 75% of the viewport height +scalar = "auto" # special value ``` diff --git a/docs/css_types/text_style.md b/docs/css_types/text_style.md index c8e29608c..7fa9964e9 100644 --- a/docs/css_types/text_style.md +++ b/docs/css_types/text_style.md @@ -1,6 +1,6 @@ -# Text style +# <text-style> -The text style unit is a combination of any of the legal text style values in a space-separated list. +The `` CSS type represents styles that can be applied to text. !!! warning @@ -8,37 +8,40 @@ The text style unit is a combination of any of the legal text style values in a ## Syntax ---8<-- "docs/snippets/text_style_syntax.md" +--8<-- "docs/snippets/type_syntax/text_style.md" ## Examples -!!! note +### CSS - The `text-style` CSS rule and the text style unit are closely related but they are not the same thing. - Here, we show examples of the text style unit, which are relevant for [all CSS rules](#used-by) that use the text style unit. +```sass +* { + /* You can specify any value by itself. */ + rule: bold; + rule: italic; + rule: none; + rule: reverse; + rule: strike; + rule: underline; -```css -Widget { - text-style: bold; - text-style: italic; - text-style: reverse; - text-style: underline; - text-style: strike; - - /* When the unit expected is a style, you can specify multiple values */ - text-style: strike bold italic reverse; - text-style: bold underline italic; + /* You can also combine multiple values. */ + rule: strike bold italic reverse; + rule: bold underline italic; } ``` -```py -widget.styles.text_style = "bold" -widget.styles.text_style = "italic" -widget.styles.text_style = "reverse" -widget.styles.text_style = "underline" -widget.styles.text_style = "strike" +### Python -# Multiple values can be specified -widget.styles.text_style = "strike bold italic reverse" -widget.styles.text_style = "bold underline italic" +```py +# You can specify any value by itself +text_style = "bold" +text_style = "italic" +text_style = "none" +text_style = "reverse" +text_style = "strike" +text_style = "underline" + +# You can also combine multiple values +text_style = "strike bold italic reverse" +text_style = "bold underline italic" ``` From d7049c89a0775a7d1a820e2fd47cbbd80e8f3f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 19:41:54 +0000 Subject: [PATCH 092/310] Fix links to snippets and types. --- docs/styles/background.md | 2 +- docs/styles/border.md | 2 +- docs/styles/color.md | 2 +- docs/styles/grid/grid_columns.md | 2 +- docs/styles/grid/grid_gutter.md | 2 +- docs/styles/grid/grid_rows.md | 2 +- docs/styles/height.md | 2 +- docs/styles/links/index.md | 4 ++-- docs/styles/links/link_background.md | 4 ++-- docs/styles/links/link_color.md | 4 ++-- docs/styles/links/link_hover_background.md | 4 ++-- docs/styles/links/link_hover_color.md | 4 ++-- docs/styles/links/link_hover_style.md | 4 ++-- docs/styles/links/link_style.md | 2 +- 14 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/styles/background.md b/docs/styles/background.md index 43d43621b..a551953fc 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -8,7 +8,7 @@ The `background` rule sets the background color of a widget. background: []; ``` ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" The optional [percentage](./css_units/percentage.md) sets the transparency level and will override any transparency specified directly in the color. diff --git a/docs/styles/border.md b/docs/styles/border.md index 6203fa210..c6a8d87bc 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -38,7 +38,7 @@ For example, `heavy white` would display a heavy white line around a widget. ### Color syntax ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" ### Multiple edge rules diff --git a/docs/styles/color.md b/docs/styles/color.md index b7994dc40..eae9a07e6 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -10,7 +10,7 @@ color: ( | auto) []; Use `auto` to automatically choose a color with suitable contrast for readability. ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" The optional [percentage](./css_units/percentage.md) sets the transparency level and will override any transparency specified directly in the color. diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index 74762814d..cf60a9d9c 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -16,7 +16,7 @@ If there are more columns in the grid than scalars specified in `grid-columns`, Scalar units can be mixed. ---8<-- "docs/snippets/scalar_syntax.md" +--8<-- "docs/snippets/type_syntax/scalar.md" ## Example diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md index f5dc0c785..ba856ee7b 100644 --- a/docs/styles/grid/grid_gutter.md +++ b/docs/styles/grid/grid_gutter.md @@ -19,7 +19,7 @@ grid-gutter: []; If only one scalar is supplied, it sets the horizontal and vertical gutter. If two scalars are supplied, they set the vertical and horizontal gutters, respectively. ---8<-- "docs/snippets/scalar_syntax.md" +--8<-- "docs/snippets/type_syntax/scalar.md" ## Example diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index 81d1c1fae..8296047db 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -16,7 +16,7 @@ If there are more rows in the grid than scalars specified in `grid-rows`, they a Scalar units can be mixed. ---8<-- "docs/snippets/scalar_syntax.md" +--8<-- "docs/snippets/type_syntax/scalar.md" ## Example diff --git a/docs/styles/height.md b/docs/styles/height.md index f3003dd88..5183bcbbf 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -8,7 +8,7 @@ The `height` rule sets a widget's height. By default, it sets the height of the height: ; ``` ---8<-- "docs/snippets/scalar_syntax.md" +--8<-- "docs/snippets/type_syntax/scalar.md" ## Examples diff --git a/docs/styles/links/index.md b/docs/styles/links/index.md index d2cab4887..471e0b29d 100644 --- a/docs/styles/links/index.md +++ b/docs/styles/links/index.md @@ -28,9 +28,9 @@ link-hover-background: []; link-hover-style: ; ``` ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" ---8<-- "docs/snippets/text_style_syntax.md" +--8<-- "docs/snippets/type_syntax/text_style.md" ## Example diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md index 81e70b446..6c0dd0cc0 100644 --- a/docs/styles/links/link_background.md +++ b/docs/styles/links/link_background.md @@ -12,9 +12,9 @@ The `link-background` sets the background color of the link. link-background: ; ``` ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" ---8<-- "docs/snippets/percentage_syntax.md" +--8<-- "docs/snippets/type_syntax/percentage.md" ## Example diff --git a/docs/styles/links/link_color.md b/docs/styles/links/link_color.md index c226281b9..36dbf7b73 100644 --- a/docs/styles/links/link_color.md +++ b/docs/styles/links/link_color.md @@ -12,9 +12,9 @@ The `link-color` sets the color of the link text. link-color: ; ``` ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" ---8<-- "docs/snippets/percentage_syntax.md" +--8<-- "docs/snippets/type_syntax/percentage.md" ## Example diff --git a/docs/styles/links/link_hover_background.md b/docs/styles/links/link_hover_background.md index d1d2a5c85..c22a52476 100644 --- a/docs/styles/links/link_hover_background.md +++ b/docs/styles/links/link_hover_background.md @@ -12,9 +12,9 @@ The `link-hover-background` sets the background color of the link when the mouse link-hover-background: ; ``` ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" ---8<-- "docs/snippets/percentage_syntax.md" +--8<-- "docs/snippets/type_syntax/percentage.md" ## Example diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md index df781c78d..e0a1409a3 100644 --- a/docs/styles/links/link_hover_color.md +++ b/docs/styles/links/link_hover_color.md @@ -12,9 +12,9 @@ The `link-hover-color` sets the color of the link text when the mouse cursor is link-hover-color: ; ``` ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" ---8<-- "docs/snippets/percentage_syntax.md" +--8<-- "docs/snippets/type_syntax/percentage.md" ## Example diff --git a/docs/styles/links/link_hover_style.md b/docs/styles/links/link_hover_style.md index 308a56ad1..b3d92b3fe 100644 --- a/docs/styles/links/link_hover_style.md +++ b/docs/styles/links/link_hover_style.md @@ -12,9 +12,9 @@ The `link-hover-style` sets the text style for the link text when the mouse curs link-hover-style: ; ``` ---8<-- "docs/snippets/color_css_syntax.md" +--8<-- "docs/snippets/type_syntax/color.md" ---8<-- "docs/snippets/percentage_syntax.md" +--8<-- "docs/snippets/type_syntax/percentage.md" ## Example diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md index 8a79c75c3..c25670055 100644 --- a/docs/styles/links/link_style.md +++ b/docs/styles/links/link_style.md @@ -12,7 +12,7 @@ The `link-style` sets the text style for the link text. link-style: ; ``` ---8<-- "docs/snippets/text_style_syntax.md" +--8<-- "docs/snippets/type_syntax/text_style.md" ## Example From 32fb2ec147964a87ff85d132f566f13ae0e5f2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 20:58:27 +0000 Subject: [PATCH 093/310] Add pages for horizontal and vertical types. --- docs/css_types/horizontal.md | 27 +++++++++++++++++++++++++ docs/css_types/vertical.md | 27 +++++++++++++++++++++++++ docs/snippets/type_syntax/horizontal.md | 7 +++++++ docs/snippets/type_syntax/vertical.md | 7 +++++++ 4 files changed, 68 insertions(+) create mode 100644 docs/css_types/horizontal.md create mode 100644 docs/css_types/vertical.md create mode 100644 docs/snippets/type_syntax/horizontal.md create mode 100644 docs/snippets/type_syntax/vertical.md diff --git a/docs/css_types/horizontal.md b/docs/css_types/horizontal.md new file mode 100644 index 000000000..2aef91b47 --- /dev/null +++ b/docs/css_types/horizontal.md @@ -0,0 +1,27 @@ +# <horizontal> + +The `` CSS type represents a position along the horizontal axis. + +## Syntax + +--8<-- "docs/snippets/type_syntax/horizontal.md" + +## Examples + +### CSS + +```sass +* { + rule: left; + rule: center; + rule: right +} +``` + +### Python + +```py +horizontal = "left" +horizontal = "center" +horizontal = "right" +``` diff --git a/docs/css_types/vertical.md b/docs/css_types/vertical.md new file mode 100644 index 000000000..f301e1fe1 --- /dev/null +++ b/docs/css_types/vertical.md @@ -0,0 +1,27 @@ +# <vertical> + +The `` CSS type represents a position along the vertical axis. + +## Syntax + +--8<-- "docs/snippets/type_syntax/vertical.md" + +## Examples + +### CSS + +```sass +* { + rule: top; + rule: middle; + rule: bottom +} +``` + +### Python + +```py +vertical = "top" +vertical = "middle" +vertical = "bottom" +``` diff --git a/docs/snippets/type_syntax/horizontal.md b/docs/snippets/type_syntax/horizontal.md new file mode 100644 index 000000000..9aad683f0 --- /dev/null +++ b/docs/snippets/type_syntax/horizontal.md @@ -0,0 +1,7 @@ +The [``](/css_types/horizontal) type can take any of the following values: + +| Value | Description | +| ---------------- | -------------------------------------------- | +| `left` (default) | Aligns on the left of the horizontal axis. | +| `center` | Aligns in the center of the horizontal axis. | +| `right` | Aligns on the right of the horizontal axis. | diff --git a/docs/snippets/type_syntax/vertical.md b/docs/snippets/type_syntax/vertical.md new file mode 100644 index 000000000..b5d91213e --- /dev/null +++ b/docs/snippets/type_syntax/vertical.md @@ -0,0 +1,7 @@ +The [``](/css_types/vertical) type can take any of the following values: + +| Value | Description | +| --------------- | ------------------------------------------ | +| `top` (default) | Aligns at the top of the vertical axis. | +| `middle` | Aligns in the middle of the vertical axis. | +| `bottom` | Aligns at the bottom of the vertical axis. | From 4513924dcfcba3e367864b6c2c5edd08d1902d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 20:59:14 +0000 Subject: [PATCH 094/310] Fix page. --- docs/css_types/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/css_types/index.md b/docs/css_types/index.md index 4de42270c..7f48be2de 100644 --- a/docs/css_types/index.md +++ b/docs/css_types/index.md @@ -1,12 +1,12 @@ # CSS Types -CSS types define the values that Textual CSS rules accept. +CSS types define the values that Textual CSS styles accept. -CSS types will be linked from within the [styles reference](../styles/index.md) in the "Formal Syntax" section of each rule. +CSS types will be linked from within the [styles reference](../styles/index.md) in the "Formal Syntax" section of each style. The CSS types will be denoted by a keyword enclosed by angle brackets `<` and `>`. For example, the style [`align-horizontal`](../styles/align.md) references the CSS type [``](./horizontal.md): --8<-- "docs/snippets/syntax_block_start.md" -align-horizontal: <horizontal> +align-horizontal: <horizontal>; --8<-- "docs/snippets/syntax_block_end.md" From d6498dc3e08b9ad38308fd94c0aff49fb30a7788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 20:59:28 +0000 Subject: [PATCH 095/310] Add horizontal and vertical pages to TOC. --- mkdocs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index 3bfe525c2..9564036f5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -31,11 +31,13 @@ nav: - CSS Types: - "css_types/index.md" - "css_types/color.md" + - "css_types/horizontal.md" - "css_types/integer.md" - "css_types/number.md" - "css_types/percentage.md" - "css_types/scalar.md" - "css_types/text_style.md" + - "css_types/vertical.md" - Events: - "events/index.md" - "events/blur.md" From 7ad921e6bcebf1626a66850748a0f1a062023604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 20:59:40 +0000 Subject: [PATCH 096/310] Update align style. --- docs/styles/align.md | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/docs/styles/align.md b/docs/styles/align.md index 028b475ee..eccb0b637 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -8,30 +8,23 @@ or on each of the axis separately. ## Syntax -``` -align: ; -align-horizontal: ; -align-vertical: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +align: <horizontal> <vertical>; +align-horizontal: <horizontal>; +align-vertical: <vertical>; +--8<-- "docs/snippets/syntax_block_end.md" +The style `align` takes a [``](../css_types/horizontal.md) followed by a [``](../css_types/vertical.md). +To specify alignment on a single axis, use the respective style and type: + + - `align-horizontal` takes a [``](../css_types/horizontal.md) and does alignment along the horizontal axis; and + - `align-vertical` takes a [``](../css_types/vertical.md) and does alignment along the vertical axis. ### Values -#### `HORIZONTAL` +--8<-- "docs/snippets/type_syntax/horizontal.md" -| Value | Description | -| ---------------- | -------------------------------------------------- | -| `left` (default) | Align content on the left of the horizontal axis | -| `center` | Align content in the center of the horizontal axis | -| `right` | Align content on the right of the horizontal axis | - -#### `VERTICAL` - -| Value | Description | -| --------------- | ------------------------------------------------ | -| `top` (default) | Align content at the top of the vertical axis | -| `middle` | Align content in the middle of the vertical axis | -| `bottom` | Align content at the bottom of the vertical axis | +--8<-- "docs/snippets/type_syntax/vertical.md" ## Examples From 201c136f806fa790b1f1a0a29d1e8bb3411353b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 21:05:44 +0000 Subject: [PATCH 097/310] Update percentage type reference. --- docs/css_types/percentage.md | 1 + docs/snippets/type_syntax/percentage.md | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/css_types/percentage.md b/docs/css_types/percentage.md index a2f45d274..c7196bd94 100644 --- a/docs/css_types/percentage.md +++ b/docs/css_types/percentage.md @@ -10,6 +10,7 @@ It is often used to represent values that are relative to the parent's values. ## Syntax --8<-- "docs/snippets/type_syntax/percentage.md" +Some rules may clamp the values between `0%` and `100%`. ## Examples diff --git a/docs/snippets/type_syntax/percentage.md b/docs/snippets/type_syntax/percentage.md index ae6d3a619..a131f0c2c 100644 --- a/docs/snippets/type_syntax/percentage.md +++ b/docs/snippets/type_syntax/percentage.md @@ -1,2 +1 @@ A [``](/css_types/percentage) is a [``](/css_types/number) followed by the percent sign `%` (without spaces). -Some rules may clamp the values between `0%` and `100%`. From d195ff8b5742b3c21230b7185c897f1d6f3e2c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 21:06:25 +0000 Subject: [PATCH 098/310] Update reference for background style. --- docs/styles/background.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/styles/background.md b/docs/styles/background.md index a551953fc..09a94f609 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -4,13 +4,18 @@ The `background` rule sets the background color of a widget. ## Syntax -``` -background: []; -``` +--8<-- "docs/snippets/syntax_block_start.md" +background: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +The style `background` needs a [``](../css_types/color.md) followed by an optional [``](../css_types/percentage.md) to specify the color transparency. + +### Values --8<-- "docs/snippets/type_syntax/color.md" -The optional [percentage](./css_units/percentage.md) sets the transparency level and will override any transparency specified directly in the color. +--8<-- "docs/snippets/type_syntax/percentage.md" +This is clamped between `0%` and `100%`. ## Examples From bc59c855b0187285962a3ad43f6d3a817eec8a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 21:37:16 +0000 Subject: [PATCH 099/310] Add reference for border type. --- docs/css_types/border.md | 51 +++++++++++++++++++++++++++++ docs/snippets/type_syntax/border.md | 19 +++++++++++ mkdocs.yml | 1 + 3 files changed, 71 insertions(+) create mode 100644 docs/css_types/border.md create mode 100644 docs/snippets/type_syntax/border.md diff --git a/docs/css_types/border.md b/docs/css_types/border.md new file mode 100644 index 000000000..e85311b1a --- /dev/null +++ b/docs/css_types/border.md @@ -0,0 +1,51 @@ +# <border> + +The `` CSS type represents a border style. + +## Syntax + +--8<-- "docs/snippets/type_syntax/border.md" + +## Examples + +### CSS + +```sass +* { + rule: "ascii" /* A border with plus, hyphen, and vertical bar characters. */ + rule: "blank" /* A blank border (reserves space for a border). */ + rule: "dashed" /* Dashed line border. */ + rule: "double" /* Double lined border. */ + rule: "heavy" /* Heavy border. */ + rule: "hidden" /* Alias for "none". */ + rule: "hkey" /* Horizontal key-line border. */ + rule: "inner" /* Thick solid border. */ + rule: "none" /* Disabled border. */ + rule: "outer" /* Solid border with additional space around content. */ + rule: "round" /* Rounded corners. */ + rule: "solid" /* Solid border. */ + rule: "tall" /* Solid border with additional space top and bottom. */ + rule: "vkey" /* Vertical key-line border. */ + rule: "wide" /* Solid border with additional space left and right. */ +} +``` + +### Python + +```py +border: "ascii" # A border with plus, hyphen, and vertical bar characters. +border: "blank" # A blank border (reserves space for a border). +border: "dashed" # Dashed line border. +border: "double" # Double lined border. +border: "heavy" # Heavy border. +border: "hidden" # Alias for "none". +border: "hkey" # Horizontal key-line border. +border: "inner" # Thick solid border. +border: "none" # Disabled border. +border: "outer" # Solid border with additional space around content. +border: "round" # Rounded corners. +border: "solid" # Solid border. +border: "tall" # Solid border with extras space top and bottom. +border: "vkey" # Vertical key-line border. +border: "wide" # Solid border with additional space left and right. +``` diff --git a/docs/snippets/type_syntax/border.md b/docs/snippets/type_syntax/border.md new file mode 100644 index 000000000..ca739ad79 --- /dev/null +++ b/docs/snippets/type_syntax/border.md @@ -0,0 +1,19 @@ +The [``](/css_types/border.md) type can take any of the following values: + +| Border type | Description | +|-------------|----------------------------------------------------------| +| `"ascii"` | A border with plus, hyphen, and vertical bar characters. | +| `"blank"` | A blank border (reserves space for a border). | +| `"dashed"` | Dashed line border. | +| `"double"` | Double lined border. | +| `"heavy"` | Heavy border. | +| `"hidden"` | Alias for "none". | +| `"hkey"` | Horizontal key-line border. | +| `"inner"` | Thick solid border. | +| `"none"` | Disabled border. | +| `"outer"` | Solid border with additional space around content. | +| `"round"` | Rounded corners. | +| `"solid"` | Solid border. | +| `"tall"` | Solid border with additional space top and bottom. | +| `"vkey"` | Vertical key-line border. | +| `"wide"` | Solid border with additional space left and right. | diff --git a/mkdocs.yml b/mkdocs.yml index 9564036f5..70e596110 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -30,6 +30,7 @@ nav: - "reference/index.md" - CSS Types: - "css_types/index.md" + - "css_types/border.md" - "css_types/color.md" - "css_types/horizontal.md" - "css_types/integer.md" From d82b21786aad5a4f9fbed080524e21db968ce8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 21:37:40 +0000 Subject: [PATCH 100/310] Update border rule reference. --- docs/styles/border.md | 51 ++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/docs/styles/border.md b/docs/styles/border.md index c6a8d87bc..3d9ce909d 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -1,42 +1,29 @@ # Border -The `border` rule enables the drawing of a box around a widget. A border is set with a border type (see below) and a 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. +The `border` rule enables the drawing of a box around a widget. ## Syntax -``` -border: [] []; -border-top: [] []; -border-right: [] []; -border-bottom: [] []; -border-left: [] []; -``` +--8<-- "docs/snippets/syntax_block_start.md" +border: [<border>] [<color>]; -### Border types +border-top: [<border>] [<color>]; +border-right: [<border>] [<color>]; +border-bottom: [<border>] [<color>]; +border-left: [<border>] [<color>]; +--8<-- "docs/snippets/syntax_block_end.md" -| Border type | Description | -|-------------|---------------------------------------------------------| -| `"ascii"` | A border with plus, hyphen, and vertical bar characters | -| `"blank"` | A blank border (reserves space for a border) | -| `"dashed"` | Dashed line border | -| `"double"` | Double lined border | -| `"heavy"` | Heavy border | -| `"hidden"` | Alias for "none" | -| `"hkey"` | Horizontal key-line border | -| `"inner"` | Thick solid border | -| `"none"` | Disabled border | -| `"outer"` | Solid border with additional space around content | -| `"round"` | Rounded corners | -| `"solid"` | Solid border | -| `"tall"` | Solid border with extras space top and bottom | -| `"vkey"` | Vertical key-line border | -| `"wide"` | Solid border with additional space left and right | +The style `border` accepts an optional [``](../css_types/border.md) that sets the visual style of the widget border and an optional [``](../css_types/color.md) to set the color of the border. -For example, `heavy white` would display a heavy white line around a widget. +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. -### Color syntax +### Values + +#### <border> + +--8<-- "docs/snippets/type_syntax/border.md" + +#### <color> --8<-- "docs/snippets/type_syntax/color.md" @@ -58,8 +45,8 @@ The CSS snippet above will add a solid green border around `Static` widgets, exc ### Defaults -If a border color is specified but the border type is omitted, it defaults to solid. -If a border type is specified but the border color is omitted, it defaults to green (RGB color `"#00FF00"`). +If `` is specified but `` is not, it defaults to `"solid"`. +If `` is specified but ``is not, it defaults to green (RGB color `"#00FF00"`). ## Border command From ea1dd86a3bf4e0316ddc703eba134fc5afebbcd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 21:38:05 +0000 Subject: [PATCH 101/310] Uniformise CSS rules reference format. --- docs/styles/align.md | 11 ++++++++--- docs/styles/background.md | 4 ++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/styles/align.md b/docs/styles/align.md index eccb0b637..41fb1b80f 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -3,18 +3,19 @@ The `align` style aligns children within a container. Not to be confused with [`content-align`](../content_align). -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. - ## Syntax --8<-- "docs/snippets/syntax_block_start.md" align: <horizontal> <vertical>; + align-horizontal: <horizontal>; align-vertical: <vertical>; --8<-- "docs/snippets/syntax_block_end.md" The style `align` takes a [``](../css_types/horizontal.md) followed by a [``](../css_types/vertical.md). + +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 [``](../css_types/horizontal.md) and does alignment along the horizontal axis; and @@ -22,8 +23,12 @@ To specify alignment on a single axis, use the respective style and type: ### Values +#### <horizontal> + --8<-- "docs/snippets/type_syntax/horizontal.md" +#### <vertical> + --8<-- "docs/snippets/type_syntax/vertical.md" diff --git a/docs/styles/background.md b/docs/styles/background.md index 09a94f609..be2d7f867 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -12,8 +12,12 @@ The style `background` needs a [``](../css_types/color.md) followed by an ### Values +#### <color> + --8<-- "docs/snippets/type_syntax/color.md" +#### <percentage> + --8<-- "docs/snippets/type_syntax/percentage.md" This is clamped between `0%` and `100%`. From bc574414b91e1a890acc02d651279b8a7e9e6404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 21:54:40 +0000 Subject: [PATCH 102/310] Update box-sizing. --- docs/styles/box_sizing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/styles/box_sizing.md b/docs/styles/box_sizing.md index 819c9b305..0a57c2c6f 100644 --- a/docs/styles/box_sizing.md +++ b/docs/styles/box_sizing.md @@ -5,7 +5,7 @@ The `box-sizing` property determines how the width and height of a widget are ca ## Syntax ``` -box-sizing: [border-box|content-box]; +box-sizing: border-box | content-box; ``` ### Values From 969d3057b39294bdb8e04c0d6326a714da9612aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 22:03:41 +0000 Subject: [PATCH 103/310] Update rule color reference. --- docs/styles/color.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/styles/color.md b/docs/styles/color.md index eae9a07e6..e12e72df4 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -1,18 +1,28 @@ # Color -The `color` rule sets the text color of a widget with an optional. +The `color` rule sets the text color of a widget. ## Syntax -``` -color: ( | auto) []; -``` +--8<-- "docs/snippets/syntax_block_start.md" +color: (<color> | auto) [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" -Use `auto` to automatically choose a color with suitable contrast for readability. +The style `color` needs a [``](../css_types/color.md) followed by an optional [``](../css_types/percentage.md) to specify the color transparency. + +Instead of a [``](../css_types/color.md), one can use the special value `"auto"` to choose automatically the color with the best contrast for readability purposes. + +### Values + +#### <color> --8<-- "docs/snippets/type_syntax/color.md" -The optional [percentage](./css_units/percentage.md) sets the transparency level and will override any transparency specified directly in the color. +The alternative value `"auto"` picks the color that provides the best contrast for readability purposes. + +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" ## Examples From 95a1c8f7be9e824527b6920614bf9560a4459a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 22:09:58 +0000 Subject: [PATCH 104/310] Update reference for content align rule. --- docs/styles/content_align.md | 39 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/docs/styles/content_align.md b/docs/styles/content_align.md index b085e5cb3..5208314ca 100644 --- a/docs/styles/content_align.md +++ b/docs/styles/content_align.md @@ -3,35 +3,34 @@ The `content-align` style aligns content _inside_ a widget. Not to be confused with [`align`](../align). -You can specify the alignment of content on both the horizontal and vertical axes at the same time, -or on each of the axis separately. - ## Syntax -``` -content-align: ; -content-align-horizontal: ; -content-align-vertical: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +content-align: <horizontal> <vertical>; + +content-align-horizontal: <horizontal>; +content-align-vertical: <vertical>; +--8<-- "docs/snippets/syntax_block_end.md" + +The style `content-align` takes a [``](../css_types/horizontal.md) followed by a [``](../css_types/vertical.md). + +You can specify the alignment of content on both the horizontal and vertical axes at the same time, +or on each of the axis separately. +To specify content alignment on a single axis, use the respective style and type: + + - `content-align-horizontal` takes a [``](../css_types/horizontal.md) and does alignment along the horizontal axis; and + - `content-align-vertical` takes a [``](../css_types/vertical.md) and does alignment along the vertical axis. ### Values -#### `HORIZONTAL` +#### <horizontal> -| Value | Description | -| ---------------- | -------------------------------------------------- | -| `left` (default) | Align content on the left of the horizontal axis | -| `center` | Align content in the center of the horizontal axis | -| `right` | Align content on the right of the horizontal axis | +--8<-- "docs/snippets/type_syntax/horizontal.md" -#### `VERTICAL` +#### <vertical> -| Value | Description | -| --------------- | ------------------------------------------------ | -| `top` (default) | Align content at the top of the vertical axis | -| `middle` | Align content in the middle of the vertical axis | -| `bottom` | Align content at the bottom of the vertical axis | +--8<-- "docs/snippets/type_syntax/vertical.md" ## Examples From e19ddf0247da0d9f1c8959c43162ac05bd383a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 22:14:03 +0000 Subject: [PATCH 105/310] Fix tables of values. --- docs/snippets/type_syntax/border.md | 30 ++++++++++++------------- docs/snippets/type_syntax/horizontal.md | 2 +- docs/snippets/type_syntax/vertical.md | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/snippets/type_syntax/border.md b/docs/snippets/type_syntax/border.md index ca739ad79..ce8c6eaa2 100644 --- a/docs/snippets/type_syntax/border.md +++ b/docs/snippets/type_syntax/border.md @@ -2,18 +2,18 @@ The [``](/css_types/border.md) type can take any of the following values | Border type | Description | |-------------|----------------------------------------------------------| -| `"ascii"` | A border with plus, hyphen, and vertical bar characters. | -| `"blank"` | A blank border (reserves space for a border). | -| `"dashed"` | Dashed line border. | -| `"double"` | Double lined border. | -| `"heavy"` | Heavy border. | -| `"hidden"` | Alias for "none". | -| `"hkey"` | Horizontal key-line border. | -| `"inner"` | Thick solid border. | -| `"none"` | Disabled border. | -| `"outer"` | Solid border with additional space around content. | -| `"round"` | Rounded corners. | -| `"solid"` | Solid border. | -| `"tall"` | Solid border with additional space top and bottom. | -| `"vkey"` | Vertical key-line border. | -| `"wide"` | Solid border with additional space left and right. | +| `ascii` | A border with plus, hyphen, and vertical bar characters. | +| `blank` | A blank border (reserves space for a border). | +| `dashed` | Dashed line border. | +| `double` | Double lined border. | +| `heavy` | Heavy border. | +| `hidden` | Alias for "none". | +| `hkey` | Horizontal key-line border. | +| `inner` | Thick solid border. | +| `none` | Disabled border. | +| `outer` | Solid border with additional space around content. | +| `round` | Rounded corners. | +| `solid` | Solid border. | +| `tall` | Solid border with additional space top and bottom. | +| `vkey` | Vertical key-line border. | +| `wide` | Solid border with additional space left and right. | diff --git a/docs/snippets/type_syntax/horizontal.md b/docs/snippets/type_syntax/horizontal.md index 9aad683f0..4d80d23ee 100644 --- a/docs/snippets/type_syntax/horizontal.md +++ b/docs/snippets/type_syntax/horizontal.md @@ -2,6 +2,6 @@ The [``](/css_types/horizontal) type can take any of the following v | Value | Description | | ---------------- | -------------------------------------------- | -| `left` (default) | Aligns on the left of the horizontal axis. | | `center` | Aligns in the center of the horizontal axis. | +| `left` (default) | Aligns on the left of the horizontal axis. | | `right` | Aligns on the right of the horizontal axis. | diff --git a/docs/snippets/type_syntax/vertical.md b/docs/snippets/type_syntax/vertical.md index b5d91213e..34e7acceb 100644 --- a/docs/snippets/type_syntax/vertical.md +++ b/docs/snippets/type_syntax/vertical.md @@ -2,6 +2,6 @@ The [``](/css_types/vertical) type can take any of the following value | Value | Description | | --------------- | ------------------------------------------ | -| `top` (default) | Aligns at the top of the vertical axis. | -| `middle` | Aligns in the middle of the vertical axis. | | `bottom` | Aligns at the bottom of the vertical axis. | +| `middle` | Aligns in the middle of the vertical axis. | +| `top` (default) | Aligns at the top of the vertical axis. | From db9ea459c848fcfe0922a9d158ebce2641891084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 22:14:52 +0000 Subject: [PATCH 106/310] Minor fixes for consistency. --- docs/styles/box_sizing.md | 2 +- docs/styles/display.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/styles/box_sizing.md b/docs/styles/box_sizing.md index 0a57c2c6f..5ad0be42a 100644 --- a/docs/styles/box_sizing.md +++ b/docs/styles/box_sizing.md @@ -10,7 +10,7 @@ box-sizing: border-box | content-box; ### Values -| Values | Description | +| Value | Description | |------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `border-box` (default) | Padding and border are included in the width and height. If you add padding and/or border the widget will not change in size, but you will have less space for content. | | `content-box` | Padding and border will increase the size of the widget, leaving the content area unaffected. | diff --git a/docs/styles/display.md b/docs/styles/display.md index 12a72808f..c9a52f329 100644 --- a/docs/styles/display.md +++ b/docs/styles/display.md @@ -5,7 +5,7 @@ The `display` property defines whether a widget is displayed or not. ## Syntax ``` -display: none | block; +display: block | none; ``` ### Values From 03cbd50d6d9b1bd03da8edff6f5b504ee99d069b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 22:19:09 +0000 Subject: [PATCH 107/310] Update dock reference. --- docs/styles/dock.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/styles/dock.md b/docs/styles/dock.md index 5a71eb6f9..dceb0beec 100644 --- a/docs/styles/dock.md +++ b/docs/styles/dock.md @@ -5,9 +5,11 @@ The `dock` property is used to fix a widget to the edge of a container (which ma ## Syntax ``` -dock: top | right | bottom | left; +dock: bottom | left | right | top; ``` +The option chosen determines the edge to which the widget is docked. + ## Examples The example below shows a `left` docked sidebar. @@ -53,13 +55,17 @@ The labels will remain in that position (docked) even if the container they are ## CSS ```sass -/* Dock the widget on the left edge of its parent container */ -dock: left; +dock: bottom; /* Docks on the bottom edge of the parent container. */ +dock: left; /* Docks on the left edge of the parent container. */ +dock: right; /* Docks on the right edge of the parent container. */ +dock: top; /* Docks on the top edge of the parent container. */ ``` ## Python ```python -# Dock the widget on the left edge of its parent container -widget.styles.dock = "left" +widget.styles.dock = bottom; # Dock bottom. +widget.styles.dock = left; # Dock left. +widget.styles.dock = right; # Dock right. +widget.styles.dock = top; # Dock top. ``` From b22352874d18e95982ea5817dede6066969c8fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 22:21:39 +0000 Subject: [PATCH 108/310] Update height reference. --- docs/styles/height.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/styles/height.md b/docs/styles/height.md index 5183bcbbf..b198ebecb 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -1,12 +1,17 @@ # Height -The `height` rule sets a widget's height. By default, it sets the height of the content area, but if `box-sizing` is set to `border-box` it sets the height of the border area. +The `height` rule sets a widget's height. ## Syntax -``` -height: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +height: <scalar>; +--8<-- "docs/snippets/syntax_block_end.md" + +The style `height` needs a [``](../css_types/scalar.md) to determine the vertical length of the widget. +By default, it sets the height of the content area, but if [`box-sizing`](./box_sizing) is set to `border-box` it sets the height of the border area. + +### Values --8<-- "docs/snippets/type_syntax/scalar.md" From a3ff968c6cd439e126756525a03fb54ab3e35d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 22:45:50 +0000 Subject: [PATCH 109/310] Refactor integer type. --- docs/css_types/integer.md | 10 +++++----- docs/snippets/type_syntax/integer.md | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 docs/snippets/type_syntax/integer.md diff --git a/docs/css_types/integer.md b/docs/css_types/integer.md index c6904fbc3..cde2faa1a 100644 --- a/docs/css_types/integer.md +++ b/docs/css_types/integer.md @@ -1,15 +1,15 @@ # <integer> -The `` CSS type represents an integer number and can be positive or negative. +The `` CSS type represents an integer number. + +## Syntax + +--8<-- "docs/snippets/type_syntax/integer.md" !!! note Some CSS rules may expect an `` within certain bounds. If that is the case, it will be noted in that rule. -## Syntax - -Any legal integer, like `-10` or `42`. - ## Examples ### CSS diff --git a/docs/snippets/type_syntax/integer.md b/docs/snippets/type_syntax/integer.md new file mode 100644 index 000000000..111b84b80 --- /dev/null +++ b/docs/snippets/type_syntax/integer.md @@ -0,0 +1 @@ +An [``](/css_types/integer) is any valid integer number like `-10` or `42`. From a1a7b4db2a72bf2ef1230dddf59718c3c837712f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 23:04:53 +0000 Subject: [PATCH 110/310] Update grid references. [skip ci] --- docs/styles/grid/column_span.md | 12 ++++++--- docs/styles/grid/grid_columns.md | 11 +++++--- docs/styles/grid/grid_gutter.md | 13 ++++++---- docs/styles/grid/grid_rows.md | 11 +++++--- docs/styles/grid/grid_size.md | 14 ++++++++--- docs/styles/grid/index.md | 43 +++++++++++++++++++++++--------- docs/styles/grid/row_span.md | 12 ++++++--- 7 files changed, 81 insertions(+), 35 deletions(-) diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md index 2ac8d808f..e86e5dcfe 100644 --- a/docs/styles/grid/column_span.md +++ b/docs/styles/grid/column_span.md @@ -8,9 +8,15 @@ The `column-span` style specifies how many rows a widget will span in a grid lay ## Syntax -```sass -column-span: -``` +--8<-- "docs/snippets/syntax_block_start.md" +column-span: <integer>; +--8<-- "docs/snippets/syntax_block_end.md" + +The style `column-span` accepts a single non-negative [``](../../css_types/integer.md) that quantifies how many columns the given widget spans. + +### Values + +--8<-- "docs/snippets/type_syntax/integer.md" ## Example diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index cf60a9d9c..78d57371f 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -8,13 +8,16 @@ The `grid-columns` style allows to define the width of the columns of the grid. ## Syntax -```sass -grid-columns: . . .; -``` +--8<-- "docs/snippets/syntax_block_start.md" +grid-columns: <scalar>+; +--8<-- "docs/snippets/syntax_block_end.md" + +The style `grid-columns` takes one or more [``](../../css_types/scalar.md) that specify the length of the columns of the grid. If there are more columns in the grid than scalars specified in `grid-columns`, they are reused cyclically. +If the number of [``](../../css_types/scalar.md) is in excess, the excess is ignored. -Scalar units can be mixed. +### Values --8<-- "docs/snippets/type_syntax/scalar.md" diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md index ba856ee7b..23d3c113f 100644 --- a/docs/styles/grid/grid_gutter.md +++ b/docs/styles/grid/grid_gutter.md @@ -12,12 +12,15 @@ No spacing is added between the edges of cells and the edges of the container. ## Syntax -```sass -grid-gutter: []; -``` +--8<-- "docs/snippets/syntax_block_start.md" +grid-gutter: <scalar> [<scalar>]; +--8<-- "docs/snippets/syntax_block_end.md" -If only one scalar is supplied, it sets the horizontal and vertical gutter. -If two scalars are supplied, they set the vertical and horizontal gutters, respectively. +The style `grid-gutter` takes one or two [``](../../css_types/scalar.md) that set the length of the gutter along the vertical and horizontal axes. +If only one [``](../../css_types/scalar.md) is supplied, it sets the vertical and horizontal gutters. +If two are supplied, they set the vertical and horizontal gutters, respectively. + +### Values --8<-- "docs/snippets/type_syntax/scalar.md" diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index 8296047db..b3945b0bb 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -8,13 +8,16 @@ The `grid-rows` style allows to define the height of the rows of the grid. ## Syntax -```sass -grid-rows: . . .; -``` +--8<-- "docs/snippets/syntax_block_start.md" +grid-rows: <scalar>+; +--8<-- "docs/snippets/syntax_block_end.md" + +The style `grid-rows` takes one or more [``](../../css_types/scalar.md) that specify the length of the rows of the grid. If there are more rows in the grid than scalars specified in `grid-rows`, they are reused cyclically. +If the number of [``](../../css_types/scalar.md) is in excess, the excess is ignored. -Scalar units can be mixed. +### Values --8<-- "docs/snippets/type_syntax/scalar.md" diff --git a/docs/styles/grid/grid_size.md b/docs/styles/grid/grid_size.md index b75e862e7..970b96e5b 100644 --- a/docs/styles/grid/grid_size.md +++ b/docs/styles/grid/grid_size.md @@ -10,11 +10,17 @@ The number of rows can be left unspecified and it will be computed automatically ## Syntax -```sass -grid-size: []; -``` +--8<-- "docs/snippets/syntax_block_start.md" +grid-size: <integer> [<integer>]; +--8<-- "docs/snippets/syntax_block_end.md" -The first integer specifies the number of columns and the second integer specifies the number of rows. +The style `grid-size` takes one or two non-negative [``](../../css_types/integer.md). +The first defines how many columns there are in the grid. +If present, the second one sets the number of rows – regardless of the number of children of the grid –, otherwise the number of rows is computed automatically. + +### Values + +--8<-- "docs/snippets/type_syntax/integer.md" ## Examples diff --git a/docs/styles/grid/index.md b/docs/styles/grid/index.md index 16c51ae3c..7e3adf39c 100644 --- a/docs/styles/grid/index.md +++ b/docs/styles/grid/index.md @@ -6,24 +6,43 @@ For an in-depth look at the grid layout, visit the grid [guide](../guide/layout. | Property | Description | |----------------|------------------------------------------------| -| [`grid-size`](./grid_size.md) | Number of columns and rows in the grid layout. | -| [`grid-rows`](./grid_rows.md) | Height of grid rows. | +| [`column-span`](./column_span.md) | Number of columns a cell spans. | | [`grid-columns`](./grid_columns.md) | Width of grid columns. | | [`grid-gutter`](./grid_gutter.md) | Spacing between grid cells. | +| [`grid-rows`](./grid_rows.md) | Height of grid rows. | +| [`grid-size`](./grid_size.md) | Number of columns and rows in the grid layout. | | [`row-span`](./row_span.md) | Number of rows a cell spans. | -| [`column-span`](./column_span.md) | Number of columns a cell spans. | ## Syntax -```sass -grid-size: []; -/* columns first, then rows */ -grid-rows: . . .; -grid-columns: . . .; -grid-gutter: ; -row-span: ; -column-span: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +column-span: <integer>; + +grid-columns: <scalar>+; + +grid-gutter: <scalar> [<scalar>]; + +grid-rows: <scalar>+; + +grid-size: <integer> [<integer>]; + +row-span: <integer>; +--8<-- "docs/snippets/syntax_block_end.md" + +The styles `column-span` and `row-span` accept a single non-negative [``](../../css_types/integer.md) while the style `grid-size` accepts one or two non-negative [``](../../css_types/integer.md). + +The style `grid-gutter` accepts one or two [``](../../css_types/scalar.md) while the styles `grid-columns` and `grid-rows` accept one or more. + + +### Values + +#### <integer> + +--8<-- "docs/snippets/type_syntax/integer.md" + +#### <scalar> + +--8<-- "docs/snippets/type_syntax/scalar.md" ## Example diff --git a/docs/styles/grid/row_span.md b/docs/styles/grid/row_span.md index ce3565528..ff1258302 100644 --- a/docs/styles/grid/row_span.md +++ b/docs/styles/grid/row_span.md @@ -8,9 +8,15 @@ The `row-span` style specifies how many rows a widget will span in a grid layout ## Syntax -```sass -row-span: -``` +--8<-- "docs/snippets/syntax_block_start.md" +row-span: <integer>; +--8<-- "docs/snippets/syntax_block_end.md" + +The style `row-span` accepts a single non-negative [``](../../css_types/integer.md) that quantifies how many rows the given widget spans. + +### Values + +--8<-- "docs/snippets/type_syntax/integer.md" ## Example From 3495a9b7e1b88a65e60d508dd398244fb534d5d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 11:26:04 +0000 Subject: [PATCH 111/310] Add template files for consistency. --- docs/css_types/_template.md | 40 ++++++++ docs/snippets/type_syntax/_template.md | 39 ++++++++ docs/styles/_template.md | 128 +++++++++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 docs/css_types/_template.md create mode 100644 docs/snippets/type_syntax/_template.md create mode 100644 docs/styles/_template.md diff --git a/docs/css_types/_template.md b/docs/css_types/_template.md new file mode 100644 index 000000000..c9fe058d4 --- /dev/null +++ b/docs/css_types/_template.md @@ -0,0 +1,40 @@ + + +# <type-name> + + + +## Syntax + + + +## Examples + +### CSS + + + +```sass +* { + rule: type-value-1; + rule: type-value-2; + rule: type-value-3; +} +``` + +### Python + + + +```py +type_name = type_value_1 +type_name = type_value_2 +type_name = type_value_3 +``` diff --git a/docs/snippets/type_syntax/_template.md b/docs/snippets/type_syntax/_template.md new file mode 100644 index 000000000..77697f721 --- /dev/null +++ b/docs/snippets/type_syntax/_template.md @@ -0,0 +1,39 @@ + + + + + + + diff --git a/docs/styles/_template.md b/docs/styles/_template.md new file mode 100644 index 000000000..8d2e61271 --- /dev/null +++ b/docs/styles/_template.md @@ -0,0 +1,128 @@ + + +# Rule-name + + + +## Syntax + +--8<-- "docs/snippets/syntax_block_start.md" + +--8<-- "docs/snippets/syntax_block_end.md" + + + +### Values + + + + + +### Defaults + + + +## Examples + + + + + + + +## CSS + + + +## Python + + From ea60ddc5e1b1fd4cd901c20e0968ca1c9515dc84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 11:53:17 +0000 Subject: [PATCH 112/310] Create type . --- docs/css_types/name.md | 33 +++++++++++++++++++++++++++++++ docs/snippets/type_syntax/name.md | 4 ++++ mkdocs.yml | 1 + 3 files changed, 38 insertions(+) create mode 100644 docs/css_types/name.md create mode 100644 docs/snippets/type_syntax/name.md diff --git a/docs/css_types/name.md b/docs/css_types/name.md new file mode 100644 index 000000000..00998e2c0 --- /dev/null +++ b/docs/css_types/name.md @@ -0,0 +1,33 @@ +# <name> + +The `` type represents a sequence of characters that identifies something. + +## Syntax + +--8<-- "docs/snippets/type_syntax/name.md" + +## Examples + +### CSS + +```sass +* { + rule: onlyLetters; + rule: Letters-and-hiphens; + rule: _leading-underscore; + rule: letters-and-1-digit; + rule: name1234567890; +} +``` + +### Python + + + +```py +name = "onlyLetters" +name = "Letters-and-hiphens" +name = "_leading-underscore" +name = "letters-and-1-digit" +name = "name1234567890" +``` diff --git a/docs/snippets/type_syntax/name.md b/docs/snippets/type_syntax/name.md new file mode 100644 index 000000000..b36abbb4e --- /dev/null +++ b/docs/snippets/type_syntax/name.md @@ -0,0 +1,4 @@ +A [``](/css_types/name) is any non-empty sequence of characters: + + - starting with a letter `a-z`, `A-Z`, or underscore `_`; and + - followed by zero or more letters `a-zA-Z`, digits `0-9`, underscores `_`, and hiphens `-`. diff --git a/mkdocs.yml b/mkdocs.yml index 70e596110..fa67d613e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -34,6 +34,7 @@ nav: - "css_types/color.md" - "css_types/horizontal.md" - "css_types/integer.md" + - "css_types/name.md" - "css_types/number.md" - "css_types/percentage.md" - "css_types/scalar.md" From 7cb630cc3bd374f447bd9984a56b90f0ee188210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 12:15:57 +0000 Subject: [PATCH 113/310] Update reference for layer(s). [skip ci] --- docs/snippets/type_syntax/border.md | 2 +- docs/styles/layer.md | 24 +++++++++++++++++------- docs/styles/layers.md | 22 +++++++++++++--------- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/docs/snippets/type_syntax/border.md b/docs/snippets/type_syntax/border.md index ce8c6eaa2..519507bdd 100644 --- a/docs/snippets/type_syntax/border.md +++ b/docs/snippets/type_syntax/border.md @@ -1,4 +1,4 @@ -The [``](/css_types/border.md) type can take any of the following values: +The [``](/css_types/border) type can take any of the following values: | Border type | Description | |-------------|----------------------------------------------------------| diff --git a/docs/styles/layer.md b/docs/styles/layer.md index 39a7e0d14..27492311c 100644 --- a/docs/styles/layer.md +++ b/docs/styles/layer.md @@ -1,15 +1,25 @@ # Layer -The `layer` property is used to assign widgets to a layer. -Layers control the order in which widgets are painted on screen. -The value of the `layer` property must be the name of a layer defined using a [`layers`](../layers) declaration. -More information on layers can be found in the [guide](../guide/layout.md#layers). +The `layer` property defines the layer a widget belongs to. ## Syntax -``` -layer: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +layer: <name>; +--8<-- "docs/snippets/syntax_block_end.md" + +The `layer` rule accepts a [``](../css_types/name.md) that defines the layer this widget belongs to. +This [``](../css_types/name.md) must correspond to a [``](../css_types/name.md) that has been defined in a [`layers`](./layers.md) rule by an ancestor of this widget. + +More information on layers can be found in the [guide](../guide/layout.md#layers). + +### Values + +--8<-- "docs/snippets/type_syntax/name.md" + +!!! warning + + Using a `` that hasn't been defined in a [`layers`](./layers.md) declaration of an ancestor of this widget has no effect. ## Example diff --git a/docs/styles/layers.md b/docs/styles/layers.md index c619eb0d6..af7d0766a 100644 --- a/docs/styles/layers.md +++ b/docs/styles/layers.md @@ -1,19 +1,23 @@ # Layers The `layers` property allows you to define an ordered set of layers. -Layers control the order in which widgets are painted on screen. -These `layers` can later be referenced using the [`layer`](../layer) property. -More information on layers can be found in the [guide](../guide/layout.md#layers). ## Syntax -``` -layers: . . .; -``` +--8<-- "docs/snippets/syntax_block_start.md" +layers: <name>+; +--8<-- "docs/snippets/syntax_block_end.md" -Layers that come first in the list are drawn before the layers that come after. -This means the first layer will be under all other layers and the last layer will be above all other layers. -See the example below. +The `layers` rule accepts one or more [``](../css_types/name.md) that define the layers that the widget is aware of, and the order in which they will be painted on the screen. + +The values used here can later be referenced using the [`layer`](../layer) property. +The layers defined first in the list are drawn under the layers that are defined later in the list. + +More information on layers can be found in the [guide](../guide/layout.md#layers). + +### Values + +--8<-- "docs/snippets/type_syntax/name.md" ## Example From 164678ab66a2d4a9a3cf8667e7d76c27aab41f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:05:17 +0000 Subject: [PATCH 114/310] Fix reference for layout. --- docs/examples/styles/layout.css | 2 +- docs/examples/styles/layout.py | 14 +++++++------- docs/styles/layout.md | 10 ++++++---- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/examples/styles/layout.css b/docs/examples/styles/layout.css index b0f7e3385..bb43aeb44 100644 --- a/docs/examples/styles/layout.css +++ b/docs/examples/styles/layout.css @@ -10,7 +10,7 @@ height: auto; } -Static { +Label { margin: 1; width: 12; color: black; diff --git a/docs/examples/styles/layout.py b/docs/examples/styles/layout.py index f7c04e984..bc87a4bb0 100644 --- a/docs/examples/styles/layout.py +++ b/docs/examples/styles/layout.py @@ -1,20 +1,20 @@ from textual.app import App from textual.containers import Container -from textual.widgets import Static +from textual.widgets import Label class LayoutApp(App): def compose(self): yield Container( - Static("Layout"), - Static("Is"), - Static("Vertical"), + Label("Layout"), + Label("Is"), + Label("Vertical"), id="vertical-layout", ) yield Container( - Static("Layout"), - Static("Is"), - Static("Horizontal"), + Label("Layout"), + Label("Is"), + Label("Horizontal"), id="horizontal-layout", ) diff --git a/docs/styles/layout.md b/docs/styles/layout.md index e94b77d01..13544bd7e 100644 --- a/docs/styles/layout.md +++ b/docs/styles/layout.md @@ -2,13 +2,13 @@ The `layout` property defines how a widget arranges its children. -See the [layout](../guide/layout.md) guide for more information. - ## Syntax -``` +--8<-- "docs/snippets/syntax_block_start.md" layout: grid | horizontal | vertical; -``` +--8<-- "docs/snippets/syntax_block_end.md" + +The `layout` style takes an option that defines how child widgets will be arranged, as per the table shown below. ### Values @@ -18,6 +18,8 @@ layout: grid | horizontal | vertical; | `horizontal` | Child widgets will be arranged along the horizontal axis, from left to right. | | `vertical` (default) | Child widgets will be arranged along the vertical axis, from top to bottom. | +See the [layout](../guide/layout.md) guide for more information. + ## Example Note how the `layout` property affects the arrangement of widgets in the example below. From a61405e7923bfb5cc71fd238c70c7f0bcd47f15e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:17:38 +0000 Subject: [PATCH 115/310] Add direct links to sub rules. --- docs/styles/grid/index.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/styles/grid/index.md b/docs/styles/grid/index.md index 7e3adf39c..4f7390ed5 100644 --- a/docs/styles/grid/index.md +++ b/docs/styles/grid/index.md @@ -16,22 +16,20 @@ For an in-depth look at the grid layout, visit the grid [guide](../guide/layout. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -column-span: <integer>; +column-span: <integer>; -grid-columns: <scalar>+; +grid-columns: <scalar>+; -grid-gutter: <scalar> [<scalar>]; +grid-gutter: <scalar> [<scalar>]; -grid-rows: <scalar>+; +grid-rows: <scalar>+; -grid-size: <integer> [<integer>]; +grid-size: <integer> [<integer>]; -row-span: <integer>; +row-span: <integer>; --8<-- "docs/snippets/syntax_block_end.md" -The styles `column-span` and `row-span` accept a single non-negative [``](../../css_types/integer.md) while the style `grid-size` accepts one or two non-negative [``](../../css_types/integer.md). - -The style `grid-gutter` accepts one or two [``](../../css_types/scalar.md) while the styles `grid-columns` and `grid-rows` accept one or more. +Visit each style's reference page to learn more about how the values are used. ### Values From a89a4b93e07d7bb84d4812dc6d47ebcd23e5446e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:19:55 +0000 Subject: [PATCH 116/310] Fix table. --- docs/snippets/type_syntax/text_style.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/snippets/type_syntax/text_style.md b/docs/snippets/type_syntax/text_style.md index 0e544bfcc..96907b3a5 100644 --- a/docs/snippets/type_syntax/text_style.md +++ b/docs/snippets/type_syntax/text_style.md @@ -1,10 +1,10 @@ The [``](/css_types/text_style) type can be any _space-separated_ combination of the following values: -| Value | Description | -|-------------|----------------------------------------------------------------| -| `bold` | **bold text** | -| `italic` | _italic text_ | -| `none` | plain text with no styling | -| `reverse` | reverse video text (foreground and background colors reversed) | -| `strike` | strikethrough text | -| `underline` | underline text | +| Value | Description | +|-------------|-----------------------------------------------------------------| +| `bold` | **Bold text.** | +| `italic` | _Italic text._ | +| `none` | Plain text with no styling. | +| `reverse` | Reverse video text (foreground and background colors reversed). | +| `strike` | Strikethrough text. | +| `underline` | Underline text. | From f807df73f9ea3568f41c67195d4f3ef7e2982c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:41:16 +0000 Subject: [PATCH 117/310] Update links references. --- docs/snippets/type_syntax/text_style.md | 2 +- docs/styles/links/index.md | 42 +++++++++++++++------- docs/styles/links/link_background.md | 14 ++++++-- docs/styles/links/link_color.md | 14 ++++++-- docs/styles/links/link_hover_background.md | 18 ++++++++-- docs/styles/links/link_hover_color.md | 18 ++++++++-- docs/styles/links/link_hover_style.md | 16 ++++++--- docs/styles/links/link_style.md | 14 ++++++-- 8 files changed, 104 insertions(+), 34 deletions(-) diff --git a/docs/snippets/type_syntax/text_style.md b/docs/snippets/type_syntax/text_style.md index 96907b3a5..f95b25b9b 100644 --- a/docs/snippets/type_syntax/text_style.md +++ b/docs/snippets/type_syntax/text_style.md @@ -1,4 +1,4 @@ -The [``](/css_types/text_style) type can be any _space-separated_ combination of the following values: +A [``](/css_types/text_style) can be any _space-separated_ combination of the following values: | Value | Description | |-------------|-----------------------------------------------------------------| diff --git a/docs/styles/links/index.md b/docs/styles/links/index.md index 471e0b29d..d8a69b555 100644 --- a/docs/styles/links/index.md +++ b/docs/styles/links/index.md @@ -1,35 +1,51 @@ # Links Textual supports the concept of inline "links" embedded in text which trigger an action when pressed. +There are a number of styles which influence the appearance of these links within a widget. !!! note These CSS rules only target Textual action links. Internet hyperlinks are not affected by these CSS rules. -There are a number of styles which influence the appearance of these links within a widget. - | Property | Description | |-------------------------------------------------------|-------------------------------------------------------------------| -| [`link-color`](./link_color.md) | The color of the link text. | | [`link-background`](./link_background.md) | The background color of the link text. | -| [`link-style`](./link_style.md) | The style of the link text (e.g. underline). | -| [`link-hover-color`](./link_hover_color.md) | The color of the link text when the cursor is over it. | +| [`link-color`](./link_color.md) | The color of the link text. | | [`link-hover-background`](./link_hover_background.md) | The background color of the link text when the cursor is over it. | +| [`link-hover-color`](./link_hover_color.md) | The color of the link text when the cursor is over it. | | [`link-hover-style`](./link_hover_style.md) | The style of the link text when the cursor is over it. | +| [`link-style`](./link_style.md) | The style of the link text (e.g. underline). | ## Syntax -```scss -link-color: []; -link-background: []; -link-style: ; -link-hover-color: []; -link-hover-background: []; -link-hover-style: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +link-background: <color> [<percentage>]; + +link-color: <color> [<percentage>]; + +link-style: <text-style>; + +link-hover-background: <color> [<percentage>]; + +link-hover-color: <color> [<percentage>]; + +link-hover-style: <text-style>; +--8<-- "docs/snippets/syntax_block_end.md" + +Visit each style's reference page to learn more about how the values are used. + +### Values + +#### <color> --8<-- "docs/snippets/type_syntax/color.md" +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" + +#### <text-style> + --8<-- "docs/snippets/type_syntax/text_style.md" ## Example diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md index 6c0dd0cc0..5d6b78046 100644 --- a/docs/styles/links/link_background.md +++ b/docs/styles/links/link_background.md @@ -8,12 +8,20 @@ The `link-background` sets the background color of the link. ## Syntax -```sass -link-background: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +link-background: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`link-background` accepts a [``](../../css_types/color.md) (with an optional transparency level defined by a [``](../../css_types/percentage.md)) that is used to define the background color of text enclosed in Textual action links. + +### Values + +#### <color> --8<-- "docs/snippets/type_syntax/color.md" +#### <percentage> + --8<-- "docs/snippets/type_syntax/percentage.md" ## Example diff --git a/docs/styles/links/link_color.md b/docs/styles/links/link_color.md index 36dbf7b73..4b537a1b2 100644 --- a/docs/styles/links/link_color.md +++ b/docs/styles/links/link_color.md @@ -8,12 +8,20 @@ The `link-color` sets the color of the link text. ## Syntax -```sass -link-color: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +link-color: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`link-color` accepts a [``](../../css_types/color.md) (with an optional transparency level defined by a [``](../../css_types/percentage.md)) that is used to define the color of text enclosed in Textual action links. + +### Values + +#### <color> --8<-- "docs/snippets/type_syntax/color.md" +#### <percentage> + --8<-- "docs/snippets/type_syntax/percentage.md" ## Example diff --git a/docs/styles/links/link_hover_background.md b/docs/styles/links/link_hover_background.md index c22a52476..03235bb60 100644 --- a/docs/styles/links/link_hover_background.md +++ b/docs/styles/links/link_hover_background.md @@ -8,14 +8,26 @@ The `link-hover-background` sets the background color of the link when the mouse ## Syntax -```sass -link-hover-background: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +link-hover-background: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`link-hover-background` accepts a [``](../../css_types/color.md) (with an optional transparency level defined by a [``](../../css_types/percentage.md)) that is used to define the background color of text enclosed in Textual action links when the mouse pointer is over it. + +### Values + +#### <color> --8<-- "docs/snippets/type_syntax/color.md" +#### <percentage> + --8<-- "docs/snippets/type_syntax/percentage.md" +### Defaults + +If not provided, a Textual action link will have `link-hover-background` set to `$accent`. + ## Example The example below shows some links that have their background colour changed when the mouse moves over it and it shows that there is a default color for `link-hover-background`. diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md index e0a1409a3..d04758987 100644 --- a/docs/styles/links/link_hover_color.md +++ b/docs/styles/links/link_hover_color.md @@ -8,14 +8,26 @@ The `link-hover-color` sets the color of the link text when the mouse cursor is ## Syntax -```sass -link-hover-color: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +link-hover-color: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`link-hover-color` accepts a [``](../../css_types/color.md) (with an optional transparency level defined by a [``](../../css_types/percentage.md)) that is used to define the color of text enclosed in Textual action links when the mouse pointer is over it. + +### Values + +#### <color> --8<-- "docs/snippets/type_syntax/color.md" +#### <percentage> + --8<-- "docs/snippets/type_syntax/percentage.md" +### Defaults + +If not provided, a Textual action link will have `link-hover-color` set to `white`. + ## Example The example below shows some links that have their colour changed when the mouse moves over it. diff --git a/docs/styles/links/link_hover_style.md b/docs/styles/links/link_hover_style.md index b3d92b3fe..015930c0b 100644 --- a/docs/styles/links/link_hover_style.md +++ b/docs/styles/links/link_hover_style.md @@ -8,13 +8,19 @@ The `link-hover-style` sets the text style for the link text when the mouse curs ## Syntax -```sass -link-hover-style: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +link-hover-style: <text-style>; +--8<-- "docs/snippets/syntax_block_end.md" ---8<-- "docs/snippets/type_syntax/color.md" +`link-hover-style` applies its [``](../../css_types/text_style.md) to the text of Textual action links when the mouse pointer is over them. ---8<-- "docs/snippets/type_syntax/percentage.md" +### Values + +--8<-- "docs/snippets/type_syntax/text_style.md" + +### Defaults + +If not provided, a Textual action link will have `link-hover-style` set to `bold`. ## Example diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md index c25670055..2f37484f9 100644 --- a/docs/styles/links/link_style.md +++ b/docs/styles/links/link_style.md @@ -8,12 +8,20 @@ The `link-style` sets the text style for the link text. ## Syntax -```sass -link-style: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +link-style: <text-style>; +--8<-- "docs/snippets/syntax_block_end.md" + +`link-style` will take all the values specified and will apply that styling to text that is enclosed by a Textual action link. + +### Values --8<-- "docs/snippets/type_syntax/text_style.md" +### Defaults + +If not provided, a Textual action link will have `link-style` set to `underline`. + ## Example The example below shows some links with different styles applied to their text. From b3d80c432e647f706bf538e5445a3afc50b9aadc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 15:43:11 +0000 Subject: [PATCH 118/310] Update reference for margin. --- docs/styles/margin.md | 51 ++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/docs/styles/margin.md b/docs/styles/margin.md index 41bb34a04..a7543f24e 100644 --- a/docs/styles/margin.md +++ b/docs/styles/margin.md @@ -1,29 +1,40 @@ # Margin -The `margin` rule adds space around the entire widget. Margin may be specified with 1, 2 or 4 values. - -| Example | Description | -|--------------------|----------------------------------------------------------------------| -| `margin: 1;` | A single value sets the margin around all 4 edges. | -| `margin: 1 2;` | Two values sets the margin for the top/bottom and left/right edges. | -| `margin: 1 2 3 4;` | Four values sets top, right, bottom, and left margins independently. | - -Margin may also be set individually by setting `margin-top`, `margin-right`, `margin-bottom`, or `margin-left` to a single value. +The `margin` rule specifies spacing around a widget. ## Syntax -``` -margin: ; /* Same value for the 4 edges. */ -margin: ; -/* top/bot, left/right */ -margin: ; -/* top, right, bottom, left */ +--8<-- "docs/snippets/syntax_block_start.md" +margin: <integer> + # one value for all edges + | <integer> <integer> + # top/bot left/right + | <integer> <integer> <integer> <integer>; + # top right bot left -margin-top: ; -margin-right: ; -margin-bottom: ; -margin-left: ; -``` +margin-top: <integer>; +margin-right: <integer>; +margin-bottom: <integer>; +margin-left: <integer>; +--8<-- "docs/snippets/syntax_block_end.md" + +The `margin` specifies spacing around the four edges of the widget equal to the [``](../css_types/integer.md) specified. +The number of values given defines what edges get what margin: + + - 1 [``](../css_types/integer.md) sets the same margin for the four edges of the widget; + - 2 [``](../css_types/integer.md) set margin for top/bottom and left/right edges, respectively. + - 4 [``](../css_types/integer.md) set margin for the top, right, bottom, and left edges, respectively. + +!!! tip + + To remember the order of the edges affected by the rule `margin` when it has 4 values, think of a clock. + Its hand starts at the top and the goes clockwise: top, right, bottom, left. + +Alternatively, margin can be set for each edge individually through the rules `margin-top`, `margin-right`, `margin-bottom`, and `margin-left`, respectively. + +### Values + +--8<-- "docs/snippets/type_syntax/integer.md" ## Examples From d5da65a44b35c2789dfa08f9387f4975c998e6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:45:42 +0000 Subject: [PATCH 119/310] Tweak template. --- docs/styles/_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/styles/_template.md b/docs/styles/_template.md index 8d2e61271..772d905c7 100644 --- a/docs/styles/_template.md +++ b/docs/styles/_template.md @@ -59,7 +59,7 @@ Short description of the first example. === "rule.css" - ```scss + ```css --8<-- "docs/examples/styles/rule.css" ``` --> From d0c744d8d9d5ffab1a4ea36b628dfc106f6a038f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:45:55 +0000 Subject: [PATCH 120/310] Add examples for min/max width/height. --- docs/examples/styles/max_height.css | 25 +++++++++++++++++++++++++ docs/examples/styles/max_height.py | 16 ++++++++++++++++ docs/examples/styles/max_width.css | 25 +++++++++++++++++++++++++ docs/examples/styles/max_width.py | 16 ++++++++++++++++ docs/examples/styles/min_height.css | 26 ++++++++++++++++++++++++++ docs/examples/styles/min_height.py | 16 ++++++++++++++++ docs/examples/styles/min_width.css | 26 ++++++++++++++++++++++++++ docs/examples/styles/min_width.py | 16 ++++++++++++++++ 8 files changed, 166 insertions(+) create mode 100644 docs/examples/styles/max_height.css create mode 100644 docs/examples/styles/max_height.py create mode 100644 docs/examples/styles/max_width.css create mode 100644 docs/examples/styles/max_width.py create mode 100644 docs/examples/styles/min_height.css create mode 100644 docs/examples/styles/min_height.py create mode 100644 docs/examples/styles/min_width.css create mode 100644 docs/examples/styles/min_width.py diff --git a/docs/examples/styles/max_height.css b/docs/examples/styles/max_height.css new file mode 100644 index 000000000..7bbc5966e --- /dev/null +++ b/docs/examples/styles/max_height.css @@ -0,0 +1,25 @@ +Horizontal { + height: 100%; + width: 100%; +} + +Placeholder { + height: 100%; + width: 1fr; +} + +#p1 { + max-height: 10w; +} + +#p2 { + max-height: 999; /* (1)! */ +} + +#p3 { + max-height: 50%; +} + +#p4 { + max-height: 10; +} diff --git a/docs/examples/styles/max_height.py b/docs/examples/styles/max_height.py new file mode 100644 index 000000000..7f3a00fda --- /dev/null +++ b/docs/examples/styles/max_height.py @@ -0,0 +1,16 @@ +from textual.app import App +from textual.containers import Horizontal +from textual.widgets import Placeholder + + +class MaxHeightApp(App): + def compose(self): + yield Horizontal( + Placeholder("max-height: 10w", id="p1"), + Placeholder("max-height: 999", id="p2"), + Placeholder("max-height: 50%", id="p3"), + Placeholder("max-height: 10", id="p4"), + ) + + +app = MaxHeightApp(css_path="max_height.css") diff --git a/docs/examples/styles/max_width.css b/docs/examples/styles/max_width.css new file mode 100644 index 000000000..a32353a78 --- /dev/null +++ b/docs/examples/styles/max_width.css @@ -0,0 +1,25 @@ +Horizontal { + height: 100%; + width: 100%; +} + +Placeholder { + width: 100%; + height: 1fr; +} + +#p1 { + max-width: 50h; +} + +#p2 { + max-width: 999; /* (1)! */ +} + +#p3 { + max-width: 50%; +} + +#p4 { + max-width: 30; +} diff --git a/docs/examples/styles/max_width.py b/docs/examples/styles/max_width.py new file mode 100644 index 000000000..0ee440a92 --- /dev/null +++ b/docs/examples/styles/max_width.py @@ -0,0 +1,16 @@ +from textual.app import App +from textual.containers import Vertical +from textual.widgets import Placeholder + + +class MaxWidthApp(App): + def compose(self): + yield Vertical( + Placeholder("max-width: 50h", id="p1"), + Placeholder("max-width: 999", id="p2"), + Placeholder("max-width: 50%", id="p3"), + Placeholder("max-width: 30", id="p4"), + ) + + +app = MaxWidthApp(css_path="max_width.css") diff --git a/docs/examples/styles/min_height.css b/docs/examples/styles/min_height.css new file mode 100644 index 000000000..ca4d2853f --- /dev/null +++ b/docs/examples/styles/min_height.css @@ -0,0 +1,26 @@ +Horizontal { + height: 100%; + width: 100%; + overflow-y: auto; +} + +Placeholder { + width: 1fr; + height: 50%; +} + +#p1 { + min-height: 25%; /* (1)! */ +} + +#p2 { + min-height: 75%; +} + +#p3 { + min-height: 30; +} + +#p4 { + min-height: 40w; +} diff --git a/docs/examples/styles/min_height.py b/docs/examples/styles/min_height.py new file mode 100644 index 000000000..b6e02deda --- /dev/null +++ b/docs/examples/styles/min_height.py @@ -0,0 +1,16 @@ +from textual.app import App +from textual.containers import Horizontal +from textual.widgets import Placeholder + + +class MinHeightApp(App): + def compose(self): + yield Horizontal( + Placeholder("min-height: 25%", id="p1"), + Placeholder("min-height: 75%", id="p2"), + Placeholder("min-height: 30", id="p3"), + Placeholder("min-height: 40w", id="p4"), + ) + + +app = MinHeightApp(css_path="min_height.css") diff --git a/docs/examples/styles/min_width.css b/docs/examples/styles/min_width.css new file mode 100644 index 000000000..43dd8400a --- /dev/null +++ b/docs/examples/styles/min_width.css @@ -0,0 +1,26 @@ +Vertical { + height: 100%; + width: 100%; + overflow-x: auto; +} + +Placeholder { + height: 1fr; + width: 50%; +} + +#p1 { + min-width: 25%; /* (1)! */ +} + +#p2 { + min-width: 75%; +} + +#p3 { + min-width: 100; +} + +#p4 { + min-width: 400h; +} diff --git a/docs/examples/styles/min_width.py b/docs/examples/styles/min_width.py new file mode 100644 index 000000000..25195c61d --- /dev/null +++ b/docs/examples/styles/min_width.py @@ -0,0 +1,16 @@ +from textual.app import App +from textual.containers import Vertical +from textual.widgets import Placeholder + + +class MinWidthApp(App): + def compose(self): + yield Vertical( + Placeholder("min-width: 25%", id="p1"), + Placeholder("min-width: 75%", id="p2"), + Placeholder("min-width: 100", id="p3"), + Placeholder("min-width: 400h", id="p4"), + ) + + +app = MinWidthApp(css_path="min_width.css") From 296dd73565d168f9ad038df08159d0cfc61c4ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:46:08 +0000 Subject: [PATCH 121/310] Update reference for min/max width/height. --- docs/styles/max_height.md | 45 +++++++++++++++++++++++++++------ docs/styles/max_width.md | 50 +++++++++++++++++++++++++++++-------- docs/styles/min_height.md | 49 ++++++++++++++++++++++++++++-------- docs/styles/min_width.md | 52 ++++++++++++++++++++++++++++++--------- 4 files changed, 157 insertions(+), 39 deletions(-) diff --git a/docs/styles/max_height.md b/docs/styles/max_height.md index e80d996fe..b483200f4 100644 --- a/docs/styles/max_height.md +++ b/docs/styles/max_height.md @@ -4,18 +4,48 @@ The `max-height` rule sets a maximum height for a widget. ## Syntax -``` -max-height: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +max-height: <scalar>; +--8<-- "docs/snippets/syntax_block_end.md" + +The `max-height` rule accepts a [``](../css_types/scalar.md) that defines an upper bound for the [`height`](./height.md) of a widget. +That is, the height of a widget is never allowed to exceed `max-height`. + +### Values + +--8<-- "docs/snippets/type_syntax/scalar.md" + +## Example + +The example below shows some placeholders that were defined to span vertically from the top edge of the terminal to the bottom edge. +Then, we set `max-height` individually on each placeholder. + +=== "Output" + + ```{.textual path="docs/examples/styles/max_height.py"} + ``` + +=== "max_height.py" + + ```py + --8<-- "docs/examples/styles/max_height.py" + ``` + +=== "max_height.css" + + ```css + --8<-- "docs/examples/styles/max_height.css" + ``` + + 1. This won't affect the placeholder because its height is less than the maximum height. ## CSS ```sass - -/* Set a maximum height of 10 rows */ +/* Set the maximum height to 10 rows */ max-height: 10; -/* Set a maximum height of 25% of the screen height */ +/* Set the maximum height to 25% of the viewport height */ max-height: 25vh; ``` @@ -25,7 +55,6 @@ max-height: 25vh; # Set the maximum height to 10 rows widget.styles.max_height = 10 -# Set the maximum height to 25% of the screen height +# Set the maximum height to 25% of the viewport height widget.styles.max_height = "25vh" - ``` diff --git a/docs/styles/max_width.md b/docs/styles/max_width.md index c6ce4ef67..1682c5301 100644 --- a/docs/styles/max_width.md +++ b/docs/styles/max_width.md @@ -4,27 +4,57 @@ The `max-width` rule sets a maximum width for a widget. ## Syntax -``` -max-width: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +max-width: <scalar>; +--8<-- "docs/snippets/syntax_block_end.md" + +The `max-width` rule accepts a [``](../css_types/scalar.md) that defines an upper bound for the [`width`](./width.md) of a widget. +That is, the width of a widget is never allowed to exceed `max-width`. + +### Values + +--8<-- "docs/snippets/type_syntax/scalar.md" + +## Example + +The example below shows some placeholders that were defined to span horizontally from the top edge of the terminal to the bottom edge. +Then, we set `max-width` individually on each placeholder. + +=== "Output" + + ```{.textual path="docs/examples/styles/max_width.py"} + ``` + +=== "max_width.py" + + ```py + --8<-- "docs/examples/styles/max_width.py" + ``` + +=== "max_width.css" + + ```scss + --8<-- "docs/examples/styles/max_width.css" + ``` + + 1. This won't affect the placeholder because its width is less than the maximum width. ## CSS ```sass - -/* Set a maximum width of 10 cells */ +/* Set the maximum width to 10 rows */ max-width: 10; -/* Set a maximum width of 25% of the screen width */ -max-width: 25vw; +/* Set the maximum width to 25% of the viewport width */ +max-width: 25vh; ``` ## Python ```python -# Set the maximum width to 10 cells +# Set the maximum width to 10 rows widget.styles.max_width = 10 -# Set the maximum width to 25% of the screen width -widget.styles.max_width = "25vw" +# Set the maximum width to 25% of the viewport width +widget.styles.max_width = "25vh" ``` diff --git a/docs/styles/min_height.md b/docs/styles/min_height.md index b110e190e..1279f92fb 100644 --- a/docs/styles/min_height.md +++ b/docs/styles/min_height.md @@ -4,18 +4,48 @@ The `min-height` rule sets a minimum height for a widget. ## Syntax -``` -min-height: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +min-height: <scalar>; +--8<-- "docs/snippets/syntax_block_end.md" + +The `min-height` rule accepts a [``](../css_types/scalar.md) that defines a lower bound for the [`height`](./height.md) of a widget. +That is, the height of a widget is never allowed to be under `min-height`. + +### Values + +--8<-- "docs/snippets/type_syntax/scalar.md" + +## Example + +The example below shows some placeholders with their height set to `50%`. +Then, we set `min-height` individually on each placeholder. + +=== "Output" + + ```{.textual path="docs/examples/styles/min_height.py"} + ``` + +=== "min_height.py" + + ```py + --8<-- "docs/examples/styles/min_height.py" + ``` + +=== "min_height.css" + + ```css hl_lines="13" + --8<-- "docs/examples/styles/min_height.css" + ``` + + 1. This won't affect the placeholder because its height is larger than the minimum height. ## CSS ```sass - -/* Set a minimum height of 10 rows */ +/* Set the minimum height to 10 rows */ min-height: 10; -/* Set a minimum height of 25% of the screen height */ +/* Set the minimum height to 25% of the viewport height */ min-height: 25vh; ``` @@ -23,9 +53,8 @@ min-height: 25vh; ```python # Set the minimum height to 10 rows -self.styles.min_height = 10 - -# Set the minimum height to 25% of the screen height -self.styles.min_height = "25vh" +widget.styles.min_height = 10 +# Set the minimum height to 25% of the viewport height +widget.styles.min_height = "25vh" ``` diff --git a/docs/styles/min_width.md b/docs/styles/min_width.md index 81331469a..cd4d1899e 100644 --- a/docs/styles/min_width.md +++ b/docs/styles/min_width.md @@ -1,30 +1,60 @@ # Min-width -The `min-width` rules sets a minimum width for a widget. +The `min-width` rule sets a minimum width for a widget. ## Syntax -``` -min-width: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +min-width: <scalar>; +--8<-- "docs/snippets/syntax_block_end.md" + +The `min-width` rule accepts a [``](../css_types/scalar.md) that defines a lower bound for the [`width`](./width.md) of a widget. +That is, the width of a widget is never allowed to be under `min-width`. + +### Values + +--8<-- "docs/snippets/type_syntax/scalar.md" + +## Example + +The example below shows some placeholders with their width set to `50%`. +Then, we set `min-width` individually on each placeholder. + +=== "Output" + + ```{.textual path="docs/examples/styles/min_width.py"} + ``` + +=== "min_width.py" + + ```py + --8<-- "docs/examples/styles/min_width.py" + ``` + +=== "min_width.css" + + ```css hl_lines="13" + --8<-- "docs/examples/styles/min_width.css" + ``` + + 1. This won't affect the placeholder because its width is larger than the minimum width. ## CSS ```sass - -/* Set a minimum width of 10 cells */ +/* Set the minimum width to 10 rows */ min-width: 10; -/* Set a minimum width of 25% of the screen width */ -min-width: 25vw; +/* Set the minimum width to 25% of the viewport width */ +min-width: 25vh; ``` ## Python ```python -# Set the minimum width to 10 cells +# Set the minimum width to 10 rows widget.styles.min_width = 10 -# Set the minimum width to 25% of the screen width -widget.styles.min_width = "25vw" +# Set the minimum width to 25% of the viewport width +widget.styles.min_width = "25vh" ``` From 289ec2556bcaf04086ad40127706508c108097e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 18:00:52 +0000 Subject: [PATCH 122/310] Tweak example for offset. --- docs/examples/styles/offset.css | 6 +++--- docs/examples/styles/offset.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/examples/styles/offset.css b/docs/examples/styles/offset.css index d0a54a355..673f9fe1c 100644 --- a/docs/examples/styles/offset.css +++ b/docs/examples/styles/offset.css @@ -3,10 +3,10 @@ Screen { color: black; layout: horizontal; } -Static { +Label { width: 20; height: 10; - content-align: center middle; + content-align: center middle; } .paul { @@ -24,7 +24,7 @@ Static { } .chani { - offset: 0 5; + offset: 0 -2; background: blue 20%; border: outer blue; color: blue; diff --git a/docs/examples/styles/offset.py b/docs/examples/styles/offset.py index d850b3778..337e1112a 100644 --- a/docs/examples/styles/offset.py +++ b/docs/examples/styles/offset.py @@ -1,12 +1,12 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label class OffsetApp(App): def compose(self): - yield Static("Paul (offset 8 2)", classes="paul") - yield Static("Duncan (offset 4 10)", classes="duncan") - yield Static("Chani (offset 0 5)", classes="chani") + yield Label("Paul (offset 8 2)", classes="paul") + yield Label("Duncan (offset 4 10)", classes="duncan") + yield Label("Chani (offset 0 -2)", classes="chani") app = OffsetApp(css_path="offset.css") From 9d8e4c53dc2ef574a2fcc978f1f4d45ab2b26e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 18:01:03 +0000 Subject: [PATCH 123/310] Update reference for offset. --- docs/styles/offset.md | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/docs/styles/offset.md b/docs/styles/offset.md index 059a1edbe..e8cf643d6 100644 --- a/docs/styles/offset.md +++ b/docs/styles/offset.md @@ -1,19 +1,33 @@ # Offset -The `offset` rule adds an offset to the widget's position. The offset is given as two values. - -Coordinates may be specified individually with `offset-x` and `offset-y`. +The `offset` rule defines an offset for the position of the widget. ## Syntax -``` -offset: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +offset: <scalar> <scalar>; + +offset-x: <scalar>; +offset-y: <scalar> +--8<-- "docs/snippets/syntax_block_end.md" + +The two [``](../css_types/scalar.md) in the `offset` define, respectively, the offsets in the horizontal and vertical axes for the widget. + +To specify an offset along a single axis, you can use `offset-x` and `offset-y`. + +### Values + +--8<-- "docs/snippets/type_syntax/scalar.md" ## Example In this example, we have 3 widgets with differing offsets. +=== "Output" + + ```{.textual path="docs/examples/styles/offset.py"} + ``` + === "offset.py" ```python @@ -26,20 +40,23 @@ In this example, we have 3 widgets with differing offsets. --8<-- "docs/examples/styles/offset.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/offset.py"} - ``` - ## CSS ```sass -/* Move the widget 2 cells in the x direction, and 4 in the y direction. */ -offset: 2 4; +/* Move the widget 8 cells in the x direction and 2 in tye y direction */ +offset: 8 2; + +/* Move the widget 4 cells in the x direction +offset-x: 4; +/* Move the widget -2 cells in the y direction +offset-y: -2; ``` ## Python +You cannot change programmatically the offset for a single axis. +You have to set the two axes at the same time. + ```python # Move the widget 2 cells in the x direction, and 4 in the y direction. widget.styles.offset = (2, 4) From 8c0f1dc83c4dbd37c8e1bb5bc3f6961b38df58dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 18:13:36 +0000 Subject: [PATCH 124/310] Fix links to CSS types. --- docs/styles/_template.md | 5 ++++- docs/styles/align.md | 12 ++++++------ docs/styles/background.md | 4 ++-- docs/styles/border.md | 12 ++++++------ docs/styles/color.md | 6 +++--- docs/styles/content_align.md | 12 ++++++------ docs/styles/grid/column_span.md | 4 ++-- docs/styles/grid/grid_columns.md | 6 +++--- docs/styles/grid/grid_gutter.md | 6 +++--- docs/styles/grid/grid_rows.md | 6 +++--- docs/styles/grid/grid_size.md | 4 ++-- docs/styles/grid/index.md | 12 ++++++------ docs/styles/grid/row_span.md | 4 ++-- docs/styles/height.md | 4 ++-- docs/styles/layer.md | 6 +++--- docs/styles/layers.md | 4 ++-- docs/styles/links/index.md | 12 ++++++------ docs/styles/links/link_background.md | 4 ++-- docs/styles/links/link_color.md | 4 ++-- docs/styles/links/link_hover_background.md | 4 ++-- docs/styles/links/link_hover_color.md | 4 ++-- docs/styles/links/link_hover_style.md | 4 ++-- docs/styles/links/link_style.md | 2 +- docs/styles/margin.md | 22 +++++++++++----------- docs/styles/max_height.md | 4 ++-- docs/styles/max_width.md | 4 ++-- docs/styles/min_height.md | 4 ++-- docs/styles/min_width.md | 4 ++-- docs/styles/offset.md | 8 ++++---- 29 files changed, 95 insertions(+), 92 deletions(-) diff --git a/docs/styles/_template.md b/docs/styles/_template.md index 772d905c7..c92c701f7 100644 --- a/docs/styles/_template.md +++ b/docs/styles/_template.md @@ -8,7 +8,10 @@ One or two sentences is typically enough. --> ## Syntax --8<-- "docs/snippets/syntax_block_start.md" - + --8<-- "docs/snippets/syntax_block_end.md" diff --git a/docs/styles/align.md b/docs/styles/align.md index 41fb1b80f..0f3121f01 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -6,20 +6,20 @@ Not to be confused with [`content-align`](../content_align). ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -align: <horizontal> <vertical>; +align: <horizontal> <vertical>; -align-horizontal: <horizontal>; -align-vertical: <vertical>; +align-horizontal: <horizontal>; +align-vertical: <vertical>; --8<-- "docs/snippets/syntax_block_end.md" -The style `align` takes a [``](../css_types/horizontal.md) followed by a [``](../css_types/vertical.md). +The style `align` takes a [``](../../css_types/horizontal) followed by a [``](../../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 [``](../css_types/horizontal.md) and does alignment along the horizontal axis; and - - `align-vertical` takes a [``](../css_types/vertical.md) and does alignment along the vertical axis. + - `align-horizontal` takes a [``](../../css_types/horizontal) and does alignment along the horizontal axis; and + - `align-vertical` takes a [``](../../css_types/vertical) and does alignment along the vertical axis. ### Values diff --git a/docs/styles/background.md b/docs/styles/background.md index be2d7f867..d22581a57 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -5,10 +5,10 @@ The `background` rule sets the background color of a widget. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -background: <color> [<percentage>]; +background: <color> [<percentage>]; --8<-- "docs/snippets/syntax_block_end.md" -The style `background` needs a [``](../css_types/color.md) followed by an optional [``](../css_types/percentage.md) to specify the color transparency. +The style `background` needs a [``](../../css_types/color) followed by an optional [``](../../css_types/percentage) to specify the color transparency. ### Values diff --git a/docs/styles/border.md b/docs/styles/border.md index 3d9ce909d..15013f650 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -5,15 +5,15 @@ The `border` rule enables the drawing of a box around a widget. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -border: [<border>] [<color>]; +border: [<border>] [<color>]; -border-top: [<border>] [<color>]; -border-right: [<border>] [<color>]; -border-bottom: [<border>] [<color>]; -border-left: [<border>] [<color>]; +border-top: [<border>] [<color>]; +border-right: [<border>] [<color>]; +border-bottom: [<border>] [<color>]; +border-left: [<border>] [<color>]; --8<-- "docs/snippets/syntax_block_end.md" -The style `border` accepts an optional [``](../css_types/border.md) that sets the visual style of the widget border and an optional [``](../css_types/color.md) to set the color of the border. +The style `border` accepts an optional [``](../../css_types/border) that sets the visual style of the widget border and an optional [``](../../css_types/color) to set the color of the border. 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. diff --git a/docs/styles/color.md b/docs/styles/color.md index e12e72df4..4db2eccb4 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -5,12 +5,12 @@ The `color` rule sets the text color of a widget. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -color: (<color> | auto) [<percentage>]; +color: (<color> | auto) [<percentage>]; --8<-- "docs/snippets/syntax_block_end.md" -The style `color` needs a [``](../css_types/color.md) followed by an optional [``](../css_types/percentage.md) to specify the color transparency. +The style `color` needs a [``](../../css_types/color) followed by an optional [``](../../css_types/percentage) to specify the color transparency. -Instead of a [``](../css_types/color.md), one can use the special value `"auto"` to choose automatically the color with the best contrast for readability purposes. +Instead of a [``](../../css_types/color), one can use the special value `"auto"` to choose automatically the color with the best contrast for readability purposes. ### Values diff --git a/docs/styles/content_align.md b/docs/styles/content_align.md index 5208314ca..bdf073199 100644 --- a/docs/styles/content_align.md +++ b/docs/styles/content_align.md @@ -7,20 +7,20 @@ Not to be confused with [`align`](../align). ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -content-align: <horizontal> <vertical>; +content-align: <horizontal> <vertical>; -content-align-horizontal: <horizontal>; -content-align-vertical: <vertical>; +content-align-horizontal: <horizontal>; +content-align-vertical: <vertical>; --8<-- "docs/snippets/syntax_block_end.md" -The style `content-align` takes a [``](../css_types/horizontal.md) followed by a [``](../css_types/vertical.md). +The style `content-align` takes a [``](../../css_types/horizontal) followed by a [``](../../css_types/vertical). You can specify the alignment of content on both the horizontal and vertical axes at the same time, or on each of the axis separately. To specify content alignment on a single axis, use the respective style and type: - - `content-align-horizontal` takes a [``](../css_types/horizontal.md) and does alignment along the horizontal axis; and - - `content-align-vertical` takes a [``](../css_types/vertical.md) and does alignment along the vertical axis. + - `content-align-horizontal` takes a [``](../../css_types/horizontal) and does alignment along the horizontal axis; and + - `content-align-vertical` takes a [``](../../css_types/vertical) and does alignment along the vertical axis. ### Values diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md index e86e5dcfe..7f02b87d4 100644 --- a/docs/styles/grid/column_span.md +++ b/docs/styles/grid/column_span.md @@ -9,10 +9,10 @@ The `column-span` style specifies how many rows a widget will span in a grid lay ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -column-span: <integer>; +column-span: <integer>; --8<-- "docs/snippets/syntax_block_end.md" -The style `column-span` accepts a single non-negative [``](../../css_types/integer.md) that quantifies how many columns the given widget spans. +The style `column-span` accepts a single non-negative [``](../../../css_types/integer) that quantifies how many columns the given widget spans. ### Values diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index 78d57371f..f603fde86 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -9,13 +9,13 @@ The `grid-columns` style allows to define the width of the columns of the grid. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -grid-columns: <scalar>+; +grid-columns: <scalar>+; --8<-- "docs/snippets/syntax_block_end.md" -The style `grid-columns` takes one or more [``](../../css_types/scalar.md) that specify the length of the columns of the grid. +The style `grid-columns` takes one or more [``](../../../css_types/scalar) that specify the length of the columns of the grid. If there are more columns in the grid than scalars specified in `grid-columns`, they are reused cyclically. -If the number of [``](../../css_types/scalar.md) is in excess, the excess is ignored. +If the number of [``](../../../css_types/scalar) is in excess, the excess is ignored. ### Values diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md index 23d3c113f..2488f95f0 100644 --- a/docs/styles/grid/grid_gutter.md +++ b/docs/styles/grid/grid_gutter.md @@ -13,11 +13,11 @@ No spacing is added between the edges of cells and the edges of the container. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -grid-gutter: <scalar> [<scalar>]; +grid-gutter: <scalar> [<scalar>]; --8<-- "docs/snippets/syntax_block_end.md" -The style `grid-gutter` takes one or two [``](../../css_types/scalar.md) that set the length of the gutter along the vertical and horizontal axes. -If only one [``](../../css_types/scalar.md) is supplied, it sets the vertical and horizontal gutters. +The style `grid-gutter` takes one or two [``](../../../css_types/scalar) that set the length of the gutter along the vertical and horizontal axes. +If only one [``](../../../css_types/scalar) is supplied, it sets the vertical and horizontal gutters. If two are supplied, they set the vertical and horizontal gutters, respectively. ### Values diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index b3945b0bb..72b12b270 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -9,13 +9,13 @@ The `grid-rows` style allows to define the height of the rows of the grid. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -grid-rows: <scalar>+; +grid-rows: <scalar>+; --8<-- "docs/snippets/syntax_block_end.md" -The style `grid-rows` takes one or more [``](../../css_types/scalar.md) that specify the length of the rows of the grid. +The style `grid-rows` takes one or more [``](../../../css_types/scalar) that specify the length of the rows of the grid. If there are more rows in the grid than scalars specified in `grid-rows`, they are reused cyclically. -If the number of [``](../../css_types/scalar.md) is in excess, the excess is ignored. +If the number of [``](../../../css_types/scalar) is in excess, the excess is ignored. ### Values diff --git a/docs/styles/grid/grid_size.md b/docs/styles/grid/grid_size.md index 970b96e5b..b35e4d391 100644 --- a/docs/styles/grid/grid_size.md +++ b/docs/styles/grid/grid_size.md @@ -11,10 +11,10 @@ The number of rows can be left unspecified and it will be computed automatically ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -grid-size: <integer> [<integer>]; +grid-size: <integer> [<integer>]; --8<-- "docs/snippets/syntax_block_end.md" -The style `grid-size` takes one or two non-negative [``](../../css_types/integer.md). +The style `grid-size` takes one or two non-negative [``](../../../css_types/integer). The first defines how many columns there are in the grid. If present, the second one sets the number of rows – regardless of the number of children of the grid –, otherwise the number of rows is computed automatically. diff --git a/docs/styles/grid/index.md b/docs/styles/grid/index.md index 4f7390ed5..b96f1fbd5 100644 --- a/docs/styles/grid/index.md +++ b/docs/styles/grid/index.md @@ -16,17 +16,17 @@ For an in-depth look at the grid layout, visit the grid [guide](../guide/layout. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -column-span: <integer>; +column-span: <integer>; -grid-columns: <scalar>+; +grid-columns: <scalar>+; -grid-gutter: <scalar> [<scalar>]; +grid-gutter: <scalar> [<scalar>]; -grid-rows: <scalar>+; +grid-rows: <scalar>+; -grid-size: <integer> [<integer>]; +grid-size: <integer> [<integer>]; -row-span: <integer>; +row-span: <integer>; --8<-- "docs/snippets/syntax_block_end.md" Visit each style's reference page to learn more about how the values are used. diff --git a/docs/styles/grid/row_span.md b/docs/styles/grid/row_span.md index ff1258302..8e874480b 100644 --- a/docs/styles/grid/row_span.md +++ b/docs/styles/grid/row_span.md @@ -9,10 +9,10 @@ The `row-span` style specifies how many rows a widget will span in a grid layout ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -row-span: <integer>; +row-span: <integer>; --8<-- "docs/snippets/syntax_block_end.md" -The style `row-span` accepts a single non-negative [``](../../css_types/integer.md) that quantifies how many rows the given widget spans. +The style `row-span` accepts a single non-negative [``](../../../css_types/integer) that quantifies how many rows the given widget spans. ### Values diff --git a/docs/styles/height.md b/docs/styles/height.md index b198ebecb..a4858a95f 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -5,10 +5,10 @@ The `height` rule sets a widget's height. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -height: <scalar>; +height: <scalar>; --8<-- "docs/snippets/syntax_block_end.md" -The style `height` needs a [``](../css_types/scalar.md) to determine the vertical length of the widget. +The style `height` needs a [``](../../css_types/scalar) to determine the vertical length of the widget. By default, it sets the height of the content area, but if [`box-sizing`](./box_sizing) is set to `border-box` it sets the height of the border area. ### Values diff --git a/docs/styles/layer.md b/docs/styles/layer.md index 27492311c..6e6f02476 100644 --- a/docs/styles/layer.md +++ b/docs/styles/layer.md @@ -5,11 +5,11 @@ The `layer` property defines the layer a widget belongs to. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -layer: <name>; +layer: <name>; --8<-- "docs/snippets/syntax_block_end.md" -The `layer` rule accepts a [``](../css_types/name.md) that defines the layer this widget belongs to. -This [``](../css_types/name.md) must correspond to a [``](../css_types/name.md) that has been defined in a [`layers`](./layers.md) rule by an ancestor of this widget. +The `layer` rule accepts a [``](../../css_types/name) that defines the layer this widget belongs to. +This [``](../../css_types/name) must correspond to a [``](../../css_types/name) that has been defined in a [`layers`](./layers) rule by an ancestor of this widget. More information on layers can be found in the [guide](../guide/layout.md#layers). diff --git a/docs/styles/layers.md b/docs/styles/layers.md index af7d0766a..427d2761e 100644 --- a/docs/styles/layers.md +++ b/docs/styles/layers.md @@ -5,10 +5,10 @@ The `layers` property allows you to define an ordered set of layers. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -layers: <name>+; +layers: <name>+; --8<-- "docs/snippets/syntax_block_end.md" -The `layers` rule accepts one or more [``](../css_types/name.md) that define the layers that the widget is aware of, and the order in which they will be painted on the screen. +The `layers` rule accepts one or more [``](../../css_types/name) that define the layers that the widget is aware of, and the order in which they will be painted on the screen. The values used here can later be referenced using the [`layer`](../layer) property. The layers defined first in the list are drawn under the layers that are defined later in the list. diff --git a/docs/styles/links/index.md b/docs/styles/links/index.md index d8a69b555..6aea1f6da 100644 --- a/docs/styles/links/index.md +++ b/docs/styles/links/index.md @@ -19,17 +19,17 @@ There are a number of styles which influence the appearance of these links withi ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -link-background: <color> [<percentage>]; +link-background: <color> [<percentage>]; -link-color: <color> [<percentage>]; +link-color: <color> [<percentage>]; -link-style: <text-style>; +link-style: <text-style>; -link-hover-background: <color> [<percentage>]; +link-hover-background: <color> [<percentage>]; -link-hover-color: <color> [<percentage>]; +link-hover-color: <color> [<percentage>]; -link-hover-style: <text-style>; +link-hover-style: <text-style>; --8<-- "docs/snippets/syntax_block_end.md" Visit each style's reference page to learn more about how the values are used. diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md index 5d6b78046..92e1e6191 100644 --- a/docs/styles/links/link_background.md +++ b/docs/styles/links/link_background.md @@ -9,10 +9,10 @@ The `link-background` sets the background color of the link. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -link-background: <color> [<percentage>]; +link-background: <color> [<percentage>]; --8<-- "docs/snippets/syntax_block_end.md" -`link-background` accepts a [``](../../css_types/color.md) (with an optional transparency level defined by a [``](../../css_types/percentage.md)) that is used to define the background color of text enclosed in Textual action links. +`link-background` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the background color of text enclosed in Textual action links. ### Values diff --git a/docs/styles/links/link_color.md b/docs/styles/links/link_color.md index 4b537a1b2..e9ce8c210 100644 --- a/docs/styles/links/link_color.md +++ b/docs/styles/links/link_color.md @@ -9,10 +9,10 @@ The `link-color` sets the color of the link text. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -link-color: <color> [<percentage>]; +link-color: <color> [<percentage>]; --8<-- "docs/snippets/syntax_block_end.md" -`link-color` accepts a [``](../../css_types/color.md) (with an optional transparency level defined by a [``](../../css_types/percentage.md)) that is used to define the color of text enclosed in Textual action links. +`link-color` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of text enclosed in Textual action links. ### Values diff --git a/docs/styles/links/link_hover_background.md b/docs/styles/links/link_hover_background.md index 03235bb60..9da9e27c6 100644 --- a/docs/styles/links/link_hover_background.md +++ b/docs/styles/links/link_hover_background.md @@ -9,10 +9,10 @@ The `link-hover-background` sets the background color of the link when the mouse ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -link-hover-background: <color> [<percentage>]; +link-hover-background: <color> [<percentage>]; --8<-- "docs/snippets/syntax_block_end.md" -`link-hover-background` accepts a [``](../../css_types/color.md) (with an optional transparency level defined by a [``](../../css_types/percentage.md)) that is used to define the background color of text enclosed in Textual action links when the mouse pointer is over it. +`link-hover-background` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the background color of text enclosed in Textual action links when the mouse pointer is over it. ### Values diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md index d04758987..a1f53c4f9 100644 --- a/docs/styles/links/link_hover_color.md +++ b/docs/styles/links/link_hover_color.md @@ -9,10 +9,10 @@ The `link-hover-color` sets the color of the link text when the mouse cursor is ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -link-hover-color: <color> [<percentage>]; +link-hover-color: <color> [<percentage>]; --8<-- "docs/snippets/syntax_block_end.md" -`link-hover-color` accepts a [``](../../css_types/color.md) (with an optional transparency level defined by a [``](../../css_types/percentage.md)) that is used to define the color of text enclosed in Textual action links when the mouse pointer is over it. +`link-hover-color` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of text enclosed in Textual action links when the mouse pointer is over it. ### Values diff --git a/docs/styles/links/link_hover_style.md b/docs/styles/links/link_hover_style.md index 015930c0b..3a9d429db 100644 --- a/docs/styles/links/link_hover_style.md +++ b/docs/styles/links/link_hover_style.md @@ -9,10 +9,10 @@ The `link-hover-style` sets the text style for the link text when the mouse curs ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -link-hover-style: <text-style>; +link-hover-style: <text-style>; --8<-- "docs/snippets/syntax_block_end.md" -`link-hover-style` applies its [``](../../css_types/text_style.md) to the text of Textual action links when the mouse pointer is over them. +`link-hover-style` applies its [``](../../../css_types/text_style) to the text of Textual action links when the mouse pointer is over them. ### Values diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md index 2f37484f9..336e5a437 100644 --- a/docs/styles/links/link_style.md +++ b/docs/styles/links/link_style.md @@ -9,7 +9,7 @@ The `link-style` sets the text style for the link text. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -link-style: <text-style>; +link-style: <text-style>; --8<-- "docs/snippets/syntax_block_end.md" `link-style` will take all the values specified and will apply that styling to text that is enclosed by a Textual action link. diff --git a/docs/styles/margin.md b/docs/styles/margin.md index a7543f24e..de97a31f7 100644 --- a/docs/styles/margin.md +++ b/docs/styles/margin.md @@ -5,25 +5,25 @@ The `margin` rule specifies spacing around a widget. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -margin: <integer> +margin: <integer> # one value for all edges - | <integer> <integer> + | <integer> <integer> # top/bot left/right - | <integer> <integer> <integer> <integer>; + | <integer> <integer> <integer> <integer>; # top right bot left -margin-top: <integer>; -margin-right: <integer>; -margin-bottom: <integer>; -margin-left: <integer>; +margin-top: <integer>; +margin-right: <integer>; +margin-bottom: <integer>; +margin-left: <integer>; --8<-- "docs/snippets/syntax_block_end.md" -The `margin` specifies spacing around the four edges of the widget equal to the [``](../css_types/integer.md) specified. +The `margin` specifies spacing around the four edges of the widget equal to the [``](../../css_types/integer) specified. The number of values given defines what edges get what margin: - - 1 [``](../css_types/integer.md) sets the same margin for the four edges of the widget; - - 2 [``](../css_types/integer.md) set margin for top/bottom and left/right edges, respectively. - - 4 [``](../css_types/integer.md) set margin for the top, right, bottom, and left edges, respectively. + - 1 [``](../../css_types/integer) sets the same margin for the four edges of the widget; + - 2 [``](../../css_types/integer) set margin for top/bottom and left/right edges, respectively. + - 4 [``](../../css_types/integer) set margin for the top, right, bottom, and left edges, respectively. !!! tip diff --git a/docs/styles/max_height.md b/docs/styles/max_height.md index b483200f4..c14162517 100644 --- a/docs/styles/max_height.md +++ b/docs/styles/max_height.md @@ -5,10 +5,10 @@ The `max-height` rule sets a maximum height for a widget. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -max-height: <scalar>; +max-height: <scalar>; --8<-- "docs/snippets/syntax_block_end.md" -The `max-height` rule accepts a [``](../css_types/scalar.md) that defines an upper bound for the [`height`](./height.md) of a widget. +The `max-height` rule accepts a [``](../../css_types/scalar) that defines an upper bound for the [`height`](./height) of a widget. That is, the height of a widget is never allowed to exceed `max-height`. ### Values diff --git a/docs/styles/max_width.md b/docs/styles/max_width.md index 1682c5301..41d07b315 100644 --- a/docs/styles/max_width.md +++ b/docs/styles/max_width.md @@ -5,10 +5,10 @@ The `max-width` rule sets a maximum width for a widget. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -max-width: <scalar>; +max-width: <scalar>; --8<-- "docs/snippets/syntax_block_end.md" -The `max-width` rule accepts a [``](../css_types/scalar.md) that defines an upper bound for the [`width`](./width.md) of a widget. +The `max-width` rule accepts a [``](../../css_types/scalar) that defines an upper bound for the [`width`](./width) of a widget. That is, the width of a widget is never allowed to exceed `max-width`. ### Values diff --git a/docs/styles/min_height.md b/docs/styles/min_height.md index 1279f92fb..79adb93bb 100644 --- a/docs/styles/min_height.md +++ b/docs/styles/min_height.md @@ -5,10 +5,10 @@ The `min-height` rule sets a minimum height for a widget. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -min-height: <scalar>; +min-height: <scalar>; --8<-- "docs/snippets/syntax_block_end.md" -The `min-height` rule accepts a [``](../css_types/scalar.md) that defines a lower bound for the [`height`](./height.md) of a widget. +The `min-height` rule accepts a [``](../../css_types/scalar) that defines a lower bound for the [`height`](./height) of a widget. That is, the height of a widget is never allowed to be under `min-height`. ### Values diff --git a/docs/styles/min_width.md b/docs/styles/min_width.md index cd4d1899e..4db00c5e4 100644 --- a/docs/styles/min_width.md +++ b/docs/styles/min_width.md @@ -5,10 +5,10 @@ The `min-width` rule sets a minimum width for a widget. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -min-width: <scalar>; +min-width: <scalar>; --8<-- "docs/snippets/syntax_block_end.md" -The `min-width` rule accepts a [``](../css_types/scalar.md) that defines a lower bound for the [`width`](./width.md) of a widget. +The `min-width` rule accepts a [``](../../css_types/scalar) that defines a lower bound for the [`width`](./width) of a widget. That is, the width of a widget is never allowed to be under `min-width`. ### Values diff --git a/docs/styles/offset.md b/docs/styles/offset.md index e8cf643d6..10ca2dd4d 100644 --- a/docs/styles/offset.md +++ b/docs/styles/offset.md @@ -5,13 +5,13 @@ The `offset` rule defines an offset for the position of the widget. ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -offset: <scalar> <scalar>; +offset: <scalar> <scalar>; -offset-x: <scalar>; -offset-y: <scalar> +offset-x: <scalar>; +offset-y: <scalar> --8<-- "docs/snippets/syntax_block_end.md" -The two [``](../css_types/scalar.md) in the `offset` define, respectively, the offsets in the horizontal and vertical axes for the widget. +The two [``](../../css_types/scalar) in the `offset` define, respectively, the offsets in the horizontal and vertical axes for the widget. To specify an offset along a single axis, you can use `offset-x` and `offset-y`. From bebd054e5e059eca2705f386ef595882026cf54f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 18:38:14 +0000 Subject: [PATCH 125/310] Update opacity example. --- docs/examples/styles/opacity.css | 5 +++-- docs/examples/styles/opacity.py | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/examples/styles/opacity.css b/docs/examples/styles/opacity.css index 15d059480..1a59b197b 100644 --- a/docs/examples/styles/opacity.css +++ b/docs/examples/styles/opacity.css @@ -19,10 +19,11 @@ } Screen { - background: antiquewhite; + background: black; } -Static { +Label { + width: 100%; height: 1fr; border: outer dodgerblue; background: lightseagreen; diff --git a/docs/examples/styles/opacity.py b/docs/examples/styles/opacity.py index d723b1d84..5a079fb64 100644 --- a/docs/examples/styles/opacity.py +++ b/docs/examples/styles/opacity.py @@ -1,14 +1,14 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label class OpacityApp(App): def compose(self): - yield Static("opacity: 0%", id="zero-opacity") - yield Static("opacity: 25%", id="quarter-opacity") - yield Static("opacity: 50%", id="half-opacity") - yield Static("opacity: 75%", id="three-quarter-opacity") - yield Static("opacity: 100%", id="full-opacity") + yield Label("opacity: 0%", id="zero-opacity") + yield Label("opacity: 25%", id="quarter-opacity") + yield Label("opacity: 50%", id="half-opacity") + yield Label("opacity: 75%", id="three-quarter-opacity") + yield Label("opacity: 100%", id="full-opacity") app = OpacityApp(css_path="opacity.css") From 7047cc494f713351de4795c1a3bec12ada1b8f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 22 Dec 2022 18:38:24 +0000 Subject: [PATCH 126/310] Update reference for opacity. [skip ci] --- docs/styles/opacity.md | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/docs/styles/opacity.md b/docs/styles/opacity.md index 1ccff5458..571b74daf 100644 --- a/docs/styles/opacity.md +++ b/docs/styles/opacity.md @@ -1,24 +1,33 @@ # Opacity -The `opacity` property can be used to make a widget partially or fully transparent. - +The `opacity` property sets the opacity/transparency of a widget. ## Syntax -``` -opacity: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +opacity: <number> | <percentage>; +--8<-- "docs/snippets/syntax_block_end.md" + +The opacity of a widget can be set as a [``](../css_types/number.md) between `0` and `1` or a [``](../css_types/percentage.md) between `0%` and `100%`. +`0`/`0%` means no opacity, which is equivalent to full transparency. +Conversely, `1`/`100%` means full opacity, which is equivalent to no transparency. ### Values -As a fractional property, `opacity` can be set to either a float (between 0 and 1), -or a percentage, e.g. `45%`. -Float values will be clamped between 0 and 1. -Percentage values will be clamped between 0% and 100%. +### <number> + +--8<-- "docs/snippets/type_syntax/number.md" +The value of [``](../../css_types/number) is clamped between `0` and `1`. + +### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" +The value of [``](../../css_types/percentage) is clamped between `0%` and `100%`. ## Example -This example shows, from top to bottom, increasing opacity values. +This example shows, from top to bottom, increasing opacity values for a label with a border and some text. +When the opacity is zero, all we see is the (black) background. === "opacity.py" From dceeb80bcd3d3083ac4f18be549268925e5bca49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:33:58 +0000 Subject: [PATCH 127/310] Add reference to border command. --- docs/css_types/border.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/css_types/border.md b/docs/css_types/border.md index e85311b1a..e44d294d5 100644 --- a/docs/css_types/border.md +++ b/docs/css_types/border.md @@ -6,6 +6,14 @@ The `` CSS type represents a border style. --8<-- "docs/snippets/type_syntax/border.md" +## Border command + +The `textual` CLI has a subcommand which will let you explore the various border types interactively, when applied to the CSS rule [`border`](../styles/border.md): + +``` +textual borders +``` + ## Examples ### CSS From 0fe5a980330525dfe53bba70afd970e8a17e0db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:34:22 +0000 Subject: [PATCH 128/310] Use labels instead of statics. --- docs/examples/styles/outline.css | 2 +- docs/examples/styles/outline.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples/styles/outline.css b/docs/examples/styles/outline.css index 487270c6a..b422b5332 100644 --- a/docs/examples/styles/outline.css +++ b/docs/examples/styles/outline.css @@ -2,7 +2,7 @@ Screen { background: white; color: black; } -Static { +Label { margin: 4 8; background: green 20%; outline: wide green; diff --git a/docs/examples/styles/outline.py b/docs/examples/styles/outline.py index e64b11dc2..5f82c85dc 100644 --- a/docs/examples/styles/outline.py +++ b/docs/examples/styles/outline.py @@ -1,5 +1,5 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label TEXT = """I must not fear. @@ -13,7 +13,7 @@ Where the fear has gone there will be nothing. Only I will remain.""" class OutlineApp(App): def compose(self): - yield Static(TEXT) + yield Label(TEXT) app = OutlineApp(css_path="outline.css") From 52497172b03ca452a3158b994399c984b31dea8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:34:37 +0000 Subject: [PATCH 129/310] Add example to compare border and outline. --- docs/examples/styles/outline_vs_border.css | 11 +++++++++++ docs/examples/styles/outline_vs_border.py | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 docs/examples/styles/outline_vs_border.css create mode 100644 docs/examples/styles/outline_vs_border.py diff --git a/docs/examples/styles/outline_vs_border.css b/docs/examples/styles/outline_vs_border.css new file mode 100644 index 000000000..8153bf048 --- /dev/null +++ b/docs/examples/styles/outline_vs_border.css @@ -0,0 +1,11 @@ +Label { + height: 8; +} + +.outline { + outline: $error round; +} + +.border { + border: $success heavy; +} diff --git a/docs/examples/styles/outline_vs_border.py b/docs/examples/styles/outline_vs_border.py new file mode 100644 index 000000000..62b072ebd --- /dev/null +++ b/docs/examples/styles/outline_vs_border.py @@ -0,0 +1,21 @@ +from textual.app import App +from textual.widgets import Label + + +TEXT = """I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain.""" + + +class OutlineBorderApp(App): + def compose(self): + yield Label(TEXT, classes="outline") + yield Label(TEXT, classes="border") + yield Label(TEXT, classes="outline border") + + +app = OutlineBorderApp(css_path="outline_vs_border.css") From 01fcfe5459034404996ca1979796bedcd6b49e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:34:50 +0000 Subject: [PATCH 130/310] Rework outline reference. --- docs/styles/outline.md | 82 ++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/docs/styles/outline.md b/docs/styles/outline.md index 284c669a8..3d1916090 100644 --- a/docs/styles/outline.md +++ b/docs/styles/outline.md @@ -1,50 +1,46 @@ # Outline -The `outline` rule enables the drawing of a box around a widget. Similar to `border`, but unlike border, outline will -draw _over_ the content area. This rule can be useful for emphasis if you want to display an outline for a brief time to -draw the user's attention to it. +The `outline` rule enables the drawing of a box around the content of a widget, which means the outline is drawn _over_ the content area. -An outline is set with a border value (see table below) followed by a color. +!!! warning -Outlines may also be set individually with the `outline-top`, `outline-right`, `outline-bottom` and `outline-left` -rules. + Not to be confused with [`border`](./border.md). ## Syntax -``` -outline: [] []; -outline-top: [] []; -outline-right: [] []; -outline-bottom: [] []; -outline-left: [] []; -``` +--8<-- "docs/snippets/syntax_block_start.md" +outline: [<border>] [<color>]; + +outline-top: [<border>] [<color>]; +outline-right: [<border>] [<color>]; +outline-bottom: [<border>] [<color>]; +outline-left: [<border>] [<color>]; +--8<-- "docs/snippets/syntax_block_end.md" + +The style `outline` accepts an optional [``](../../css_types/border) that sets the visual style of the widget outline and an optional [``](../../css_types/color) to set the color of the outline. + +Unlike the style [`border`](./border.md), the frame of the outline is drawn over the content area of the widget. +This rule can be useful for temporary emphasis of the content of a widget, if you want to draw the user's attention to it. ### Values -| Border value | Description | -|--------------|---------------------------------------------------------| -| `"ascii"` | A border with plus, hyphen, and vertical bar | -| `"blank"` | A blank border (reserves space for a border) | -| `"dashed"` | Dashed line border | -| `"double"` | Double lined border | -| `"heavy"` | Heavy border | -| `"hidden"` | Alias for "none" | -| `"hkey"` | Horizontal key-line border | -| `"inner"` | Thick solid border | -| `"none"` | Disabled border | -| `"outer"` | Think solid border with additional space around content | -| `"round"` | Rounded corners | -| `"solid"` | Solid border | -| `"tall"` | Solid border with extras space top and bottom | -| `"vkey"` | Vertical key-line border | -| `"wide"` | Solid border with additional space left and right | +#### <border> -For example, `heavy white` would display a heavy white line around a widget. +--8<-- "docs/snippets/type_syntax/border.md" -## Example +#### <color> + +--8<-- "docs/snippets/type_syntax/color.md" + +## Examples This example shows a widget with an outline. Note how the outline occludes the text area. +=== "Output" + + ```{.textual path="docs/examples/styles/outline.py"} + ``` + === "outline.py" ```python @@ -57,9 +53,25 @@ This example shows a widget with an outline. Note how the outline occludes the t --8<-- "docs/examples/styles/outline.css" ``` +The next example makes the difference clearer, by having three labels side-by-side. +They contain the same text, have the same width and height, and are styled exactly the same up to their `outline` and [`border`](./border.md) rules. +This example also shows that a widget can contain both a `border` and an `outline`: + === "Output" - ```{.textual path="docs/examples/styles/outline.py"} + ```{.textual path="docs/examples/styles/outline_vs_border.py"} + ``` + +=== "outline_vs_border.py" + + ```python + --8<-- "docs/examples/styles/outline_vs_border.py" + ``` + +=== "outline_vs_border.css" + + ```css + --8<-- "docs/examples/styles/outline_vs_border.css" ``` ## CSS @@ -76,8 +88,8 @@ outline-left:outer red; ```python # Set a heavy white outline -widget.outline = ("heavy", "white) +widget.outline = ("heavy", "white") # Set a red outline on the left -widget.outline_left = ("outer", "red) +widget.outline_left = ("outer", "red") ``` From 80f2ad214b33efa3cea916ab0b0dbf68de62519e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:58:53 +0000 Subject: [PATCH 131/310] Fix examples for CSS type border. --- docs/css_types/border.md | 60 ++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/css_types/border.md b/docs/css_types/border.md index e44d294d5..eb37d685c 100644 --- a/docs/css_types/border.md +++ b/docs/css_types/border.md @@ -20,40 +20,40 @@ textual borders ```sass * { - rule: "ascii" /* A border with plus, hyphen, and vertical bar characters. */ - rule: "blank" /* A blank border (reserves space for a border). */ - rule: "dashed" /* Dashed line border. */ - rule: "double" /* Double lined border. */ - rule: "heavy" /* Heavy border. */ - rule: "hidden" /* Alias for "none". */ - rule: "hkey" /* Horizontal key-line border. */ - rule: "inner" /* Thick solid border. */ - rule: "none" /* Disabled border. */ - rule: "outer" /* Solid border with additional space around content. */ - rule: "round" /* Rounded corners. */ - rule: "solid" /* Solid border. */ - rule: "tall" /* Solid border with additional space top and bottom. */ - rule: "vkey" /* Vertical key-line border. */ - rule: "wide" /* Solid border with additional space left and right. */ + rule: ascii /* A border with plus, hyphen, and vertical bar characters. */ + rule: blank /* A blank border (reserves space for a border). */ + rule: dashed /* Dashed line border. */ + rule: double /* Double lined border. */ + rule: heavy /* Heavy border. */ + rule: hidden /* Alias for "none". */ + rule: hkey /* Horizontal key-line border. */ + rule: inner /* Thick solid border. */ + rule: none /* Disabled border. */ + rule: outer /* Solid border with additional space around content. */ + rule: round /* Rounded corners. */ + rule: solid /* Solid border. */ + rule: tall /* Solid border with additional space top and bottom. */ + rule: vkey /* Vertical key-line border. */ + rule: wide /* Solid border with additional space left and right. */ } ``` ### Python ```py -border: "ascii" # A border with plus, hyphen, and vertical bar characters. -border: "blank" # A blank border (reserves space for a border). -border: "dashed" # Dashed line border. -border: "double" # Double lined border. -border: "heavy" # Heavy border. -border: "hidden" # Alias for "none". -border: "hkey" # Horizontal key-line border. -border: "inner" # Thick solid border. -border: "none" # Disabled border. -border: "outer" # Solid border with additional space around content. -border: "round" # Rounded corners. -border: "solid" # Solid border. -border: "tall" # Solid border with extras space top and bottom. -border: "vkey" # Vertical key-line border. -border: "wide" # Solid border with additional space left and right. +border = "ascii" # A border with plus, hyphen, and vertical bar characters. +border = "blank" # A blank border (reserves space for a border). +border = "dashed" # Dashed line border. +border = "double" # Double lined border. +border = "heavy" # Heavy border. +border = "hidden" # Alias for "none". +border = "hkey" # Horizontal key-line border. +border = "inner" # Thick solid border. +border = "none" # Disabled border. +border = "outer" # Solid border with additional space around content. +border = "round" # Rounded corners. +border = "solid" # Solid border. +border = "tall" # Solid border with extras space top and bottom. +border = "vkey" # Vertical key-line border. +border = "wide" # Solid border with additional space left and right. ``` From 8fd118c4bcde9a960b5539a0d6bd265998e8851c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:25:47 +0000 Subject: [PATCH 132/310] Add overflow CSS type. --- docs/css_types/overflow.md | 27 +++++++++++++++++++++++++++ docs/snippets/type_syntax/overflow.md | 7 +++++++ mkdocs.yml | 1 + 3 files changed, 35 insertions(+) create mode 100644 docs/css_types/overflow.md create mode 100644 docs/snippets/type_syntax/overflow.md diff --git a/docs/css_types/overflow.md b/docs/css_types/overflow.md new file mode 100644 index 000000000..c5fe6010e --- /dev/null +++ b/docs/css_types/overflow.md @@ -0,0 +1,27 @@ +# <overflow> + +The `` CSS type represents overflow modes. + +## Syntax + +--8<-- "docs/snippets/type_syntax/overflow.md" + +## Examples + +### CSS + +```sass +* { + rule: auto; /* Determine overflow mode automatically. */ + rule: hidden; /* Don't overflow. */ + rule: scroll; /* Allow overflowing. */ +} +``` + +### Python + +```py +overflow = "auto" # Determine overflow mode automatically. +overflow = "hidden" # Don't overflow. +overflow = "scroll" # Allow overflowing. +``` diff --git a/docs/snippets/type_syntax/overflow.md b/docs/snippets/type_syntax/overflow.md new file mode 100644 index 000000000..25307f510 --- /dev/null +++ b/docs/snippets/type_syntax/overflow.md @@ -0,0 +1,7 @@ +The [``](/css_types/overflow) type can take any of the following values: + +| Value | Description | +|----------|----------------------------------------| +| `auto` | Determine overflow mode automatically. | +| `hidden` | Don't overflow. | +| `scroll` | Allow overflowing. | diff --git a/mkdocs.yml b/mkdocs.yml index fa67d613e..f0693c69c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -36,6 +36,7 @@ nav: - "css_types/integer.md" - "css_types/name.md" - "css_types/number.md" + - "css_types/overflow.md" - "css_types/percentage.md" - "css_types/scalar.md" - "css_types/text_style.md" From 56e5e39740200494f3dd4784012753364f8e20d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:26:01 +0000 Subject: [PATCH 133/310] Refactor overflow reference. [skip ci] --- docs/styles/overflow.md | 55 ++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/docs/styles/overflow.md b/docs/styles/overflow.md index 7b49ec4f1..84a903fd1 100644 --- a/docs/styles/overflow.md +++ b/docs/styles/overflow.md @@ -1,35 +1,48 @@ # Overflow -The `overflow` rule specifies if and when scrollbars should be displayed on the `x` and `y` axis. -The rule takes two overflow values; one for the horizontal bar (x-axis), followed by the vertical bar (y-axis). - -The default value for overflow is `"auto auto"` which will show scrollbars automatically for both scrollbars if content doesn't fit within container. - -Overflow may also be set independently by setting the `overflow-x` rule for the horizontal bar, and `overflow-y` for the vertical bar. +The `overflow` rule specifies if and when scrollbars should be displayed. ## Syntax -``` -overflow: [auto|hidden|scroll]; -overflow-x: [auto|hidden|scroll]; -overflow-y: [auto|hidden|scroll]; -``` +--8<-- "docs/snippets/syntax_block_start.md" +overflow: <overflow> <overflow>; + +overflow-x: <overflow>; +overflow-y: <overflow>; +--8<-- "docs/snippets/syntax_block_end.md" + +The style `overflow` accepts two values that determine when to display scrollbars in a container widget. +The two values set the overflow for the horizontal and vertical axes, respectively. + +Overflow may also be set individually for each axis: + + - `overflow-x` sets the overflow for the horizontal axis; and + - `overflow-y` sets the overflow for the vertical axis. ### Values -| Value | Description | -|------------------|---------------------------------------------------------| -| `auto` (default) | Automatically show the scrollbar if content doesn't fit | -| `hidden` | Never show the scrollbar | -| `scroll` | Always show the scrollbar | +--8<-- "docs/snippets/type_syntax/overflow.md" + +### Defaults + +The default setting for containers is `overflow: auto auto`. + +!!! warning + + Some built-in containers like `Horizontal` and `Vertical` override these defaults. ## Example -Here we split the screen in to left and right sections, each with three vertically scrolling widgets that do not fit in to the height of the terminal. +Here we split the screen into left and right sections, each with three vertically scrolling widgets that do not fit into the height of the terminal. The left side has `overflow-y: auto` (the default) and will automatically show a scrollbar. The right side has `overflow-y: hidden` which will prevent a scrollbar from being shown. +=== "Output" + + ```{.textual path="docs/examples/styles/overflow.py"} + ``` + === "overflow.py" ```python @@ -42,11 +55,6 @@ The right side has `overflow-y: hidden` which will prevent a scrollbar from bein --8<-- "docs/examples/styles/overflow.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/overflow.py"} - ``` - ## CSS ```sass @@ -62,11 +70,12 @@ overflow-x: scroll; ## Python +Overflow cannot be programmatically set for both axes at the same time. + ```python # Hide the vertical scrollbar widget.styles.overflow_y = "hidden" # Always show the horizontal scrollbar widget.styles.overflow_x = "scroll" - ``` From 454d36cdc70aca371d6e75e48db53b1392efc617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:43:38 +0000 Subject: [PATCH 134/310] Use labels instead of static. --- docs/examples/styles/padding.css | 2 +- docs/examples/styles/padding.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples/styles/padding.css b/docs/examples/styles/padding.css index 4c558895b..68ad84385 100644 --- a/docs/examples/styles/padding.css +++ b/docs/examples/styles/padding.css @@ -3,7 +3,7 @@ Screen { color: blue; } -Static { +Label { padding: 4 8; background: blue 20%; } diff --git a/docs/examples/styles/padding.py b/docs/examples/styles/padding.py index 4893838c1..13c43381a 100644 --- a/docs/examples/styles/padding.py +++ b/docs/examples/styles/padding.py @@ -1,5 +1,5 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label TEXT = """I must not fear. Fear is the mind-killer. @@ -12,7 +12,7 @@ Where the fear has gone there will be nothing. Only I will remain.""" class PaddingApp(App): def compose(self): - yield Static(TEXT) + yield Label(TEXT) app = PaddingApp(css_path="padding.css") From 745ec529b930994fa9d3d1f6744267c5a1a5d218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:43:47 +0000 Subject: [PATCH 135/310] Update padding reference. --- docs/styles/padding.md | 75 +++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 22 deletions(-) diff --git a/docs/styles/padding.md b/docs/styles/padding.md index 6336a3d5f..439ed2a9e 100644 --- a/docs/styles/padding.md +++ b/docs/styles/padding.md @@ -1,26 +1,44 @@ # Padding -The padding rule adds space around the content of a widget. You can specify padding with 1, 2 or 4 numbers. - -| example | | -| ------------------- | ------------------------------------------------------------------- | -| `padding: 1;` | A single value sets a padding of 1 around all 4 edges | -| `padding: 1 2;` | Two values sets the padding for the top/bottom and left/right edges | -| `padding: 1 2 3 4;` | Four values sets top, right, bottom, and left padding independently | - -Padding may also be set individually by setting `padding-top`, `padding-right`, `padding-bottom`, or `padding-left` to a single value. +The `padding` rule specifies spacing around the content of a widget. ## Syntax -``` -padding: ; -padding: ; -padding: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +padding: <integer> # one value for all edges + | <integer> <integer> + # top/bot left/right + | <integer> <integer> <integer> <integer>; + # top right bot left + +padding-top: <integer>; +padding-right: <integer>; +padding-bottom: <integer>; +padding-left: <integer>; +--8<-- "docs/snippets/syntax_block_end.md" + +The `padding` specifies spacing around the _content_ of a widget, thus this spacing is added _inside_ the widget. +The values of the [``](../../css_types/integer) determine how much spacing is added and the number of values define what edges get what padding: + + - 1 [``](../../css_types/integer) sets the same padding for the four edges of the widget; + - 2 [``](../../css_types/integer) set padding for top/bottom and left/right edges, respectively. + - 4 [``](../../css_types/integer) set padding for the top, right, bottom, and left edges, respectively. + +!!! tip + + To remember the order of the edges affected by the rule `padding` when it has 4 values, think of a clock. + Its hand starts at the top and the goes clockwise: top, right, bottom, left. + +Alternatively, padding can be set for each edge individually through the rules `padding-top`, `padding-right`, `padding-bottom`, and `padding-left`, respectively. ## Example -This example adds padding around static text. +This example adds padding around some text. + +=== "Output" + + ```{.textual path="docs/examples/styles/padding.py"} + ``` === "padding.py" @@ -34,21 +52,34 @@ This example adds padding around static text. --8<-- "docs/examples/styles/padding.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/padding.py"} - ``` - ## CSS ```sass +/* Set padding of 1 around all edges */ +padding: 1 /* Set padding of 2 on the top and bottom edges, and 4 on the left and right */ padding: 2 4; +/* Set padding of 1 on the top, 2 on the right, + 3 on the bottom, and 4 on the left */ +padding: 1 2 3 4; + +padding-top: 1; +padding-right: 2; +padding-bottom: 3; +padding-left: 4; ``` ## Python +In Python, you cannot set any of the individual `padding` rules `padding-top`, `padding-right`, `padding-bottom`, and `padding-left`. + +However, you _can_ set padding to a single integer, a tuple of 2 integers, or a tuple of 4 integers: + ```python -# In Python you can set the padding as a tuple of integers -widget.styles.padding = (2, 3) +# Set padding of 1 around all edges +widget.styles.padding = 1 +# Set padding of 2 on the top and bottom edges, and 4 on the left and right +widget.styles.padding = (2, 4) +# Set padding of 1 on top, 2 on the right, 3 on the bottom, and 4 on the left +widget.styles.padding = (1, 2, 3, 4) ``` From d708c53e6cbb55f844c107828566d9e5222ba4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 13:32:08 +0000 Subject: [PATCH 136/310] Fix links in link index. --- docs/styles/links/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/styles/links/index.md b/docs/styles/links/index.md index 6aea1f6da..edbc86bb5 100644 --- a/docs/styles/links/index.md +++ b/docs/styles/links/index.md @@ -19,17 +19,17 @@ There are a number of styles which influence the appearance of these links withi ## Syntax --8<-- "docs/snippets/syntax_block_start.md" -link-background: <color> [<percentage>]; +link-background: <color> [<percentage>]; -link-color: <color> [<percentage>]; +link-color: <color> [<percentage>]; -link-style: <text-style>; +link-style: <text-style>; -link-hover-background: <color> [<percentage>]; +link-hover-background: <color> [<percentage>]; -link-hover-color: <color> [<percentage>]; +link-hover-color: <color> [<percentage>]; -link-hover-style: <text-style>; +link-hover-style: <text-style>; --8<-- "docs/snippets/syntax_block_end.md" Visit each style's reference page to learn more about how the values are used. From 7fb00f531c3bc3e199bff077bc8147723e5a2756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 17:09:35 +0000 Subject: [PATCH 137/310] Add example for corner colors. --- .../styles/scrollbar_corner_color.css | 4 ++++ .../examples/styles/scrollbar_corner_color.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 docs/examples/styles/scrollbar_corner_color.css create mode 100644 docs/examples/styles/scrollbar_corner_color.py diff --git a/docs/examples/styles/scrollbar_corner_color.css b/docs/examples/styles/scrollbar_corner_color.css new file mode 100644 index 000000000..3cf382371 --- /dev/null +++ b/docs/examples/styles/scrollbar_corner_color.css @@ -0,0 +1,4 @@ +Screen { + overflow: auto auto; + scrollbar-corner-color: white; +} diff --git a/docs/examples/styles/scrollbar_corner_color.py b/docs/examples/styles/scrollbar_corner_color.py new file mode 100644 index 000000000..9e20fedbb --- /dev/null +++ b/docs/examples/styles/scrollbar_corner_color.py @@ -0,0 +1,19 @@ +from textual.app import App +from textual.widgets import Label + +TEXT = """I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain. +""" + + +class ScrollbarCornerColorApp(App): + def compose(self): + yield Label(TEXT.replace("\n", " ") + "\n" + TEXT * 10) + + +app = ScrollbarCornerColorApp(css_path="scrollbar_corner_color.css") From 14f0240d6a0d068bcdb807843670da6abdfeaea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 17:09:58 +0000 Subject: [PATCH 138/310] Add example for (background) scrollbar active/hover. --- docs/examples/styles/scrollbars2.css | 8 ++++++++ docs/examples/styles/scrollbars2.py | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 docs/examples/styles/scrollbars2.css create mode 100644 docs/examples/styles/scrollbars2.py diff --git a/docs/examples/styles/scrollbars2.css b/docs/examples/styles/scrollbars2.css new file mode 100644 index 000000000..4e7fa8145 --- /dev/null +++ b/docs/examples/styles/scrollbars2.css @@ -0,0 +1,8 @@ +Screen { + scrollbar-background: blue; + scrollbar-background-active: red; + scrollbar-background-hover: purple; + scrollbar-color: cyan; + scrollbar-color-active: yellow; + scrollbar-color-hover: pink; +} diff --git a/docs/examples/styles/scrollbars2.py b/docs/examples/styles/scrollbars2.py new file mode 100644 index 000000000..988b87130 --- /dev/null +++ b/docs/examples/styles/scrollbars2.py @@ -0,0 +1,19 @@ +from textual.app import App +from textual.widgets import Label + +TEXT = """I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain. +""" + + +class Scrollbar2App(App): + def compose(self): + yield Label(TEXT * 10) + + +app = Scrollbar2App(css_path="scrollbars2.css") From 9b53c7a70409d0f137600cfc71dcfe991b93b8f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 17:10:12 +0000 Subject: [PATCH 139/310] Update base scrollbar example. --- docs/examples/styles/scrollbars.css | 29 ++++++++++------------------- docs/examples/styles/scrollbars.py | 10 ++++++---- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/docs/examples/styles/scrollbars.css b/docs/examples/styles/scrollbars.css index 8399bd077..b94952274 100644 --- a/docs/examples/styles/scrollbars.css +++ b/docs/examples/styles/scrollbars.css @@ -1,23 +1,14 @@ -Screen { - background: #212121; - color: white 80%; - layout: horizontal; +Label { + width: 150%; + height: 150%; } -Static { - padding: 1 2; -} - -.panel1 { - width: 1fr; +.right { + scrollbar-background: red; scrollbar-color: green; - scrollbar-background: #bbb; - padding: 1 2; -} + scrollbar-corner-color: blue; +} -.panel2 { - width: 1fr; - scrollbar-color: yellow; - scrollbar-background: purple; - padding: 1 2; -} +Horizontal > Container { + width: 50%; +} diff --git a/docs/examples/styles/scrollbars.py b/docs/examples/styles/scrollbars.py index f426c0d57..371027ecc 100644 --- a/docs/examples/styles/scrollbars.py +++ b/docs/examples/styles/scrollbars.py @@ -1,6 +1,6 @@ from textual.app import App -from textual.containers import Vertical -from textual.widgets import Static +from textual.containers import Horizontal, Container +from textual.widgets import Label TEXT = """I must not fear. Fear is the mind-killer. @@ -14,8 +14,10 @@ Where the fear has gone there will be nothing. Only I will remain. class ScrollbarApp(App): def compose(self): - yield Vertical(Static(TEXT * 5), classes="panel1") - yield Vertical(Static(TEXT * 5), classes="panel2") + yield Horizontal( + Container(Label(TEXT * 10)), + Container(Label(TEXT * 10), classes="right"), + ) app = ScrollbarApp(css_path="scrollbars.css") From 3ebc78260bb611b159d005ecb5161952124e3ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 4 Jan 2023 17:10:31 +0000 Subject: [PATCH 140/310] Update reference for all scrollbar colors. --- docs/styles/scrollbar_colors/index.md | 83 ++++++++++--------- .../scrollbar_colors/scrollbar_background.md | 49 +++++++++++ .../scrollbar_background_active.md | 50 +++++++++++ .../scrollbar_background_hover.md | 50 +++++++++++ .../scrollbar_colors/scrollbar_color.md | 50 +++++++++++ .../scrollbar_color_active.md | 50 +++++++++++ .../scrollbar_colors/scrollbar_color_hover.md | 50 +++++++++++ .../scrollbar_corner_color.md | 53 ++++++++++++ mkdocs.yml | 8 +- 9 files changed, 399 insertions(+), 44 deletions(-) diff --git a/docs/styles/scrollbar_colors/index.md b/docs/styles/scrollbar_colors/index.md index 3a4ec1f33..f3dd5b093 100644 --- a/docs/styles/scrollbar_colors/index.md +++ b/docs/styles/scrollbar_colors/index.md @@ -3,31 +3,55 @@ There are a number of rules to set the colors used in Textual scrollbars. You won't typically need to do this, as the default themes have carefully chosen colors, but you can if you want to. -| Rule | Color | -|-------------------------------|---------------------------------------------------------| -| `scrollbar-color` | Scrollbar "thumb" (movable part) | -| `scrollbar-color-hover` | Scrollbar thumb when the mouse is hovering over it | -| `scrollbar-color-active` | Scrollbar thumb when it is active (being dragged) | -| `scrollbar-background` | Scrollbar background | -| `scrollbar-background-hover` | Scrollbar background when the mouse is hovering over it | -| `scrollbar-background-active` | Scrollbar background when the thumb is being dragged | -| `scrollbar-corner-color` | The gap between the horizontal and vertical scrollbars | +| Rule | Applies to | +|-------------------------------------------------------------------|----------------------------------------------------------| +| [`scrollbar-background`](./scrollbar_background.md) | Scrollbar background. | +| [`scrollbar-background-active`](./scrollbar_background_active.md) | Scrollbar background when the thumb is being dragged. | +| [`scrollbar-background-hover`](./scrollbar_background_hover.md) | Scrollbar background when the mouse is hovering over it. | +| [`scrollbar-color`](./scrollbar_color.md) | Scrollbar "thumb" (movable part). | +| [`scrollbar-color-active`](./scrollbar_color_active.md) | Scrollbar thumb when it is active (being dragged). | +| [`scrollbar-color-hover`](./scrollbar_color_hover.md) | Scrollbar thumb when the mouse is hovering over it. | +| [`scrollbar-corner-color`](./scrollbar_corner_color.md) | The gap between the horizontal and vertical scrollbars. | ## Syntax -``` -scrollbar-color: ; -scrollbar-color-hover: ; -scrollbar-color-active: ; -scrollbar-background: ; -scrollbar-background-hover: ; -scrollbar-background-active: ; -scrollbar-corner-color: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-background: <color> [<percentage>]; + +scrollbar-background-active: <color> [<percentage>]; + +scrollbar-background-hover: <color> [<percentage>]; + +scrollbar-color: <color> [<percentage>]; + +scrollbar-color-active: <color> [<percentage>]; + +scrollbar-color-hover: <color> [<percentage>]; + +scrollbar-corner-color: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +Visit each style's reference page to learn more about how the values are used. + +### Values + +#### <color> + +--8<-- "docs/snippets/type_syntax/color.md" + +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" ## Example -In this example we have two panels with different scrollbar colors set for each. +This example shows two planels that contain oversized text. +The right panel sets `scrollbar-background`, `scrollbar-color`, and `scrollbar-corner-color`, and the left panel shows the default colors for comparison. + +=== "Output" + + ```{.textual path="docs/examples/styles/scrollbars.py"} + ``` === "scrollbars.py" @@ -40,24 +64,3 @@ In this example we have two panels with different scrollbar colors set for each. ```css --8<-- "docs/examples/styles/scrollbars.css" ``` - -=== "Output" - - ```{.textual path="docs/examples/styles/scrollbars.py"} - ``` - -## CSS - -```sass -/* Set widget scrollbar color to yellow */ -Widget { - scrollbar-color: yellow; -} -``` - -## Python - -```python -# Set the scrollbar color to yellow -widget.styles.scrollbar_color = "yellow" -``` diff --git a/docs/styles/scrollbar_colors/scrollbar_background.md b/docs/styles/scrollbar_colors/scrollbar_background.md index e8432f8dd..199f46249 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background.md +++ b/docs/styles/scrollbar_colors/scrollbar_background.md @@ -1 +1,50 @@ # Scrollbar-background + +The `scrollbar-background` sets the background color of the scrollbar. +## Syntax + +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-background: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`scrollbar-background` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the background color of a scrollbar. + +### Values + +#### <color> + +--8<-- "docs/snippets/type_syntax/color.md" + +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" + +## Example + +=== "Output" + + Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + +=== "scrollbars2.py" + + ```py + --8<-- "docs/examples/styles/scrollbars2.py" + ``` + +=== "scrollbars2.css" + + ```css hl_lines="2" + --8<-- "docs/examples/styles/scrollbars2.css" + ``` + +## CSS + +```css +scrollbar-backround: blue; +``` + +## Python + +```py +widget.styles.scrollbar_background = "blue" +``` diff --git a/docs/styles/scrollbar_colors/scrollbar_background_active.md b/docs/styles/scrollbar_colors/scrollbar_background_active.md index b1c08d764..6bab78684 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_active.md @@ -1 +1,51 @@ # Scrollbar-background-active + +The `scrollbar-background-active` sets the background color of the scrollbar when the thumb is being dragged. + +## Syntax + +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-background-active: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`scrollbar-background-active` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the background color of a scrollbar when its thumb is being dragged. + +### Values + +#### <color> + +--8<-- "docs/snippets/type_syntax/color.md" + +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" + +## Example + +=== "Output" + + Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + +=== "scrollbars2.py" + + ```py + --8<-- "docs/examples/styles/scrollbars2.py" + ``` + +=== "scrollbars2.css" + + ```css hl_lines="3" + --8<-- "docs/examples/styles/scrollbars2.css" + ``` + +## CSS + +```css +scrollbar-backround-active: red; +``` + +## Python + +```py +widget.styles.scrollbar_background_active = "red" +``` diff --git a/docs/styles/scrollbar_colors/scrollbar_background_hover.md b/docs/styles/scrollbar_colors/scrollbar_background_hover.md index e3eac7c8e..c86bd42b0 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_hover.md @@ -1 +1,51 @@ # Scrollbar-background-hover + +The `scrollbar-background-hover` sets the background color of the scrollbar when the cursor is over it. + +## Syntax + +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-background-hover: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`scrollbar-background-hover` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the background color of a scrollbar when the cursor is over it. + +### Values + +#### <color> + +--8<-- "docs/snippets/type_syntax/color.md" + +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" + +## Example + +=== "Output" + + Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + +=== "scrollbars2.py" + + ```py + --8<-- "docs/examples/styles/scrollbars2.py" + ``` + +=== "scrollbars2.css" + + ```css hl_lines="4" + --8<-- "docs/examples/styles/scrollbars2.css" + ``` + +## CSS + +```css +scrollbar-background-hover: purple; +``` + +## Python + +```py +widget.styles.scrollbar_background_hover = "purple" +``` diff --git a/docs/styles/scrollbar_colors/scrollbar_color.md b/docs/styles/scrollbar_colors/scrollbar_color.md index 651c89489..7943dc232 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_color.md @@ -1 +1,51 @@ # Scrollbar-color + +The `scrollbar-color` sets the color of the scrollbar. + +## Syntax + +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-color: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`scrollbar-color` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of a scrollbar. + +### Values + +#### <color> + +--8<-- "docs/snippets/type_syntax/color.md" + +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" + +## Example + +=== "Output" + + Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + +=== "scrollbars2.py" + + ```py + --8<-- "docs/examples/styles/scrollbars2.py" + ``` + +=== "scrollbars2.css" + + ```css hl_lines="5" + --8<-- "docs/examples/styles/scrollbars2.css" + ``` + +## CSS + +```css +scrollbar-color: cyan; +``` + +## Python + +```py +widget.styles.scrollbar_color = "cyan" +``` diff --git a/docs/styles/scrollbar_colors/scrollbar_color_active.md b/docs/styles/scrollbar_colors/scrollbar_color_active.md index 144a5d365..9e33efc3c 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_active.md @@ -1 +1,51 @@ # Scrollbar-color-active + +The `scrollbar-color-active` sets the color of the scrollbar when the thumb is being dragged. + +## Syntax + +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-color-active: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`scrollbar-color-active` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of a scrollbar when its thumb is being dragged. + +### Values + +#### <color> + +--8<-- "docs/snippets/type_syntax/color.md" + +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" + +## Example + +=== "Output" + + Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + +=== "scrollbars2.py" + + ```py + --8<-- "docs/examples/styles/scrollbars2.py" + ``` + +=== "scrollbars2.css" + + ```css hl_lines="6" + --8<-- "docs/examples/styles/scrollbars2.css" + ``` + +## CSS + +```css +scrollbar-color-active: yellow; +``` + +## Python + +```py +widget.styles.scrollbar_color_active = "yellow" +``` diff --git a/docs/styles/scrollbar_colors/scrollbar_color_hover.md b/docs/styles/scrollbar_colors/scrollbar_color_hover.md index 4529c5817..1ef9c53a5 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_hover.md @@ -1 +1,51 @@ # Scrollbar-color-hover + +The `scrollbar-color-hover` sets the color of the scrollbar when the cursor is over it. + +## Syntax + +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-color-hover: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`scrollbar-color-hover` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of a scrollbar when the cursor is over it. + +### Values + +#### <color> + +--8<-- "docs/snippets/type_syntax/color.md" + +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" + +## Example + +=== "Output" + + Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + +=== "scrollbars2.py" + + ```py + --8<-- "docs/examples/styles/scrollbars2.py" + ``` + +=== "scrollbars2.css" + + ```css hl_lines="7" + --8<-- "docs/examples/styles/scrollbars2.css" + ``` + +## CSS + +```css +scrollbar-color-hover: pink; +``` + +## Python + +```py +widget.styles.scrollbar_color_hover = "pink" +``` diff --git a/docs/styles/scrollbar_colors/scrollbar_corner_color.md b/docs/styles/scrollbar_colors/scrollbar_corner_color.md index fb418249c..c020d698f 100644 --- a/docs/styles/scrollbar_colors/scrollbar_corner_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_corner_color.md @@ -1 +1,54 @@ # Scrollbar-corner-color + +The `scrollbar-corner-color` sets the color of the gap between the horizontal and vertical scrollbars. + +## Syntax + +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-corner-color: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +`scrollbar-corner-color` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of the gap between the horizontal and vertical scrollbars of a widget. + +### Values + +#### <color> + +--8<-- "docs/snippets/type_syntax/color.md" + +#### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" + +## Example + +The example below sets the scrollbar corner (bottom-right of the screen) to white. + +=== "Output" + + ```{.textual path="docs/examples/styles/scrollbar_corner_color.py"} + ``` + +=== "scrollbar_corner_color.py" + + ```py + --8<-- "docs/examples/styles/scrollbar_corner_color.py" + ``` + +=== "scrollbar_corner_color.css" + + ```css hl_lines="3" + --8<-- "docs/examples/styles/scrollbar_corner_color.css" + ``` + +## CSS + +```css +scrollbar-color: cyan; +``` + +## Python + +```py +widget.styles.scrollbar_color = "cyan" +``` diff --git a/mkdocs.yml b/mkdocs.yml index f0693c69c..f6245746d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -108,12 +108,12 @@ nav: - "styles/padding.md" - Scrollbar colors: - "styles/scrollbar_colors/index.md" - - "styles/scrollbar_colors/scrollbar_color.md" - - "styles/scrollbar_colors/scrollbar_color_hover.md" - - "styles/scrollbar_colors/scrollbar_color_active.md" - "styles/scrollbar_colors/scrollbar_background.md" - - "styles/scrollbar_colors/scrollbar_background_hover.md" - "styles/scrollbar_colors/scrollbar_background_active.md" + - "styles/scrollbar_colors/scrollbar_background_hover.md" + - "styles/scrollbar_colors/scrollbar_color.md" + - "styles/scrollbar_colors/scrollbar_color_active.md" + - "styles/scrollbar_colors/scrollbar_color_hover.md" - "styles/scrollbar_colors/scrollbar_corner_color.md" - "styles/scrollbar_gutter.md" - "styles/scrollbar_size.md" From c81a046c0c9156b33c634755f9065c463f9a1fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 5 Jan 2023 10:33:42 +0000 Subject: [PATCH 141/310] Fix and tweak scrollbar corner color reference. --- docs/styles/scrollbar_colors/scrollbar_corner_color.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/styles/scrollbar_colors/scrollbar_corner_color.md b/docs/styles/scrollbar_colors/scrollbar_corner_color.md index c020d698f..4edc582d4 100644 --- a/docs/styles/scrollbar_colors/scrollbar_corner_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_corner_color.md @@ -22,11 +22,11 @@ The `scrollbar-corner-color` sets the color of the gap between the horizontal an ## Example -The example below sets the scrollbar corner (bottom-right of the screen) to white. +The example below sets the scrollbar corner (bottom-right corner of the screen) to white. === "Output" - ```{.textual path="docs/examples/styles/scrollbar_corner_color.py"} + ```{.textual path="docs/examples/styles/scrollbar_corner_color.py" lines=5} ``` === "scrollbar_corner_color.py" @@ -44,11 +44,11 @@ The example below sets the scrollbar corner (bottom-right of the screen) to whit ## CSS ```css -scrollbar-color: cyan; +scrollbar-corner-color: white; ``` ## Python ```py -widget.styles.scrollbar_color = "cyan" +widget.styles.scrollbar_corner_color = "white" ``` From 73621b6867e11718907eedee4109af96a203401f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 5 Jan 2023 11:21:31 +0000 Subject: [PATCH 142/310] Review reference for scrollbar-gutter. --- docs/styles/scrollbar_gutter.md | 39 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/docs/styles/scrollbar_gutter.md b/docs/styles/scrollbar_gutter.md index 7c2ed5e44..c08ac4e2d 100644 --- a/docs/styles/scrollbar_gutter.md +++ b/docs/styles/scrollbar_gutter.md @@ -1,27 +1,32 @@ # Scrollbar-gutter -The `scrollbar-gutter` rule allows authors to reserve space for the vertical scrollbar. - -Setting the value to `stable` prevents unwanted layout changes when the scrollbar becomes visible. +The `scrollbar-gutter` rule allows reserving space for a vertical scrollbar. ## Syntax -``` -scrollbar-gutter: [auto|stable]; -``` +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-gutter: auto | stable; +--8<-- "docs/snippets/syntax_block_end.md" ### Values -| Value | Description | -|------------------|--------------------------------------------------| -| `auto` (default) | No space is reserved for the vertical scrollbar. | -| `stable` | Space is reserved for the vertical scrollbar. | +| Value | Description | +|------------------|------------------------------------------------| +| `auto` (default) | No space is reserved for a vertical scrollbar. | +| `stable` | Space is reserved for a vertical scrollbar. | + +Setting the value to `stable` prevents unwanted layout changes when the scrollbar becomes visible, whereas the default value of `auto` means that the layout of your application is recomputed when a vertical scrollbar becomes needed. ## Example In the example below, notice the gap reserved for the scrollbar on the right side of the terminal window. +=== "Output" + + ```{.textual path="docs/examples/styles/scrollbar_gutter.py"} + ``` + === "scrollbar_gutter.py" ```python @@ -30,24 +35,20 @@ terminal window. === "scrollbar_gutter.css" - ```scss + ```scss hl_lines="2" --8<-- "docs/examples/styles/scrollbar_gutter.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/scrollbar_gutter.py"} - ``` - ## CSS ```sass -/* Reserve space for vertical scrollbar */ -scrollbar-gutter: stable; +scrollbar-gutter: auto; /* Don't reserve space for a vertical scrollbar. */ +scrollbar-gutter: stable; /* Reserve space for a vertical scrollbar. */ ``` ## Python ```python -self.styles.scrollbar_gutter = "stable" +self.styles.scrollbar_gutter = "auto" # Don't reserve space for a vertical scrollbar. +self.styles.scrollbar_gutter = "stable" # Reserve space for a vertical scrollbar. ``` From 5b6bedd8c677e316850450692e92175d4b5d3da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 5 Jan 2023 12:01:23 +0000 Subject: [PATCH 143/310] Fix example to use labels. --- docs/examples/styles/scrollbar_size.css | 2 +- docs/examples/styles/scrollbar_size.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples/styles/scrollbar_size.css b/docs/examples/styles/scrollbar_size.css index b119f07a3..4165f287c 100644 --- a/docs/examples/styles/scrollbar_size.css +++ b/docs/examples/styles/scrollbar_size.css @@ -4,7 +4,7 @@ Screen { layout: horizontal; } -Static { +Label { padding: 1 2; width: 200; } diff --git a/docs/examples/styles/scrollbar_size.py b/docs/examples/styles/scrollbar_size.py index 97facad70..1bbcec572 100644 --- a/docs/examples/styles/scrollbar_size.py +++ b/docs/examples/styles/scrollbar_size.py @@ -1,6 +1,6 @@ from textual.app import App from textual.containers import Vertical -from textual.widgets import Static +from textual.widgets import Label TEXT = """I must not fear. Fear is the mind-killer. @@ -14,7 +14,7 @@ Where the fear has gone there will be nothing. Only I will remain. class ScrollbarApp(App): def compose(self): - yield Vertical(Static(TEXT * 5), classes="panel") + yield Vertical(Label(TEXT * 5), classes="panel") app = ScrollbarApp(css_path="scrollbar_size.css") From f457afd82607e1c385f8c7b460f733e07c9a8e88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 5 Jan 2023 12:01:41 +0000 Subject: [PATCH 144/310] Add example for all scrollbar size rules. --- docs/examples/styles/scrollbar_size2.css | 18 ++++++++++++++++++ docs/examples/styles/scrollbar_size2.py | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 docs/examples/styles/scrollbar_size2.css create mode 100644 docs/examples/styles/scrollbar_size2.py diff --git a/docs/examples/styles/scrollbar_size2.css b/docs/examples/styles/scrollbar_size2.css new file mode 100644 index 000000000..6054ceed1 --- /dev/null +++ b/docs/examples/styles/scrollbar_size2.css @@ -0,0 +1,18 @@ +Container { + width: 1fr; +} + +#v1 { + scrollbar-size: 5 1; + background: red 20%; +} + +#v2 { + scrollbar-size-vertical: 1; + background: green 20%; +} + +#v3 { + scrollbar-size-horizontal: 5; + background: blue 20%; +} diff --git a/docs/examples/styles/scrollbar_size2.py b/docs/examples/styles/scrollbar_size2.py new file mode 100644 index 000000000..66bd7e397 --- /dev/null +++ b/docs/examples/styles/scrollbar_size2.py @@ -0,0 +1,24 @@ +from textual.app import App +from textual.containers import Horizontal, Container +from textual.widgets import Label + +TEXT = """I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain. +""" + + +class ScrollbarApp(App): + def compose(self): + yield Horizontal( + Container(Label(TEXT * 5), id="v1"), + Container(Label(TEXT * 5), id="v2"), + Container(Label(TEXT * 5), id="v3"), + ) + + +app = ScrollbarApp(css_path="scrollbar_size2.css") From ffe1f4a0c46cee58af5cb8c14f825d9c62ad492a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 5 Jan 2023 12:02:01 +0000 Subject: [PATCH 145/310] Update scrollbar-size rule reference. [skip ci] --- docs/styles/scrollbar_size.md | 66 ++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/docs/styles/scrollbar_size.md b/docs/styles/scrollbar_size.md index ccc9c5e80..19c092971 100644 --- a/docs/styles/scrollbar_size.md +++ b/docs/styles/scrollbar_size.md @@ -1,19 +1,31 @@ # Scrollbar-size -The `scrollbar-size` rule changes the size of the scrollbars. It takes 2 integers for horizontal and vertical scrollbar size respectively. - -The scrollbar dimensions may also be set individually with `scrollbar-size-horizontal` and `scrollbar-size-vertical`. +The `scrollbar-size` rule defines the width of the scrollbars. ## Syntax -``` -scrollbar-size: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +scrollbar-size: <integer> <integer>; + # horizontal vertical -## Example +scrollbar-size-horizontal: <integer>; +scrollbar-size-vertical: <integer>; +--8<-- "docs/snippets/syntax_block_end.md" + +The `scrollbar-size` rule takes two [``](../css_types/integer.md) to set the horizontal and vertical scrollbar sizes, respectively. +This customisable size is the width of the scrollbar, given that its length will always be 100% of the container. + +The scrollbar widths may also be set individually with `scrollbar-size-horizontal` and `scrollbar-size-vertical`. + +## Examples In this example we modify the size of the widget's scrollbar to be _much_ larger than usual. +=== "Output" + + ```{.textual path="docs/examples/styles/scrollbar_size.py"} + ``` + === "scrollbar_size.py" ```python @@ -22,28 +34,50 @@ In this example we modify the size of the widget's scrollbar to be _much_ larger === "scrollbar_size.css" - ```css + ```css hl_lines="13" --8<-- "docs/examples/styles/scrollbar_size.css" ``` +In the next example we show three containers with differently sized scrollbars. + === "Output" - ```{.textual path="docs/examples/styles/scrollbar_size.py"} + ```{.textual path="docs/examples/styles/scrollbar_size2.py"} + ``` + +=== "scrollbar_size2.py" + + ```python + --8<-- "docs/examples/styles/scrollbar_size2.py" + ``` + +=== "scrollbar_size2.css" + + ```css hl_lines="6 11 16" + --8<-- "docs/examples/styles/scrollbar_size2.css" ``` ## CSS ```sass /* Set horizontal scrollbar to 10, and vertical scrollbar to 4 */ -Widget { - scrollbar-size: 10 4; -} +scrollbar-size: 10 4; + +/* Set horizontal scrollbar to 10 */ +scrollbar-size-horizontal: 10; + +/* Set vertical scrollbar to 4 */ +scrollbar-size-vertical: 4; ``` ## Python -```python -# Set horizontal scrollbar to 10, and vertical scrollbar to 4 -widget.styles.horizontal_scrollbar = 10 -widget.styles.vertical_scrollbar = 10 +The rule `scrollbar-size` has no Python equivalent. +The scrollbar sizes must be set independently: + +```py +# Set horizontal scrollbar to 10: +widget.styles.scrollbar_size_horizontal = 10 +# Set vertical scrollbar to 4: +widget.styles.scrollbar_size_vertical = 4 ``` From fa0a4ba3d40c8349cfd877d948279c9a13d73bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 5 Jan 2023 18:29:51 +0000 Subject: [PATCH 146/310] Fix link. --- docs/css_types/text_style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/css_types/text_style.md b/docs/css_types/text_style.md index 7fa9964e9..5f128b004 100644 --- a/docs/css_types/text_style.md +++ b/docs/css_types/text_style.md @@ -4,7 +4,7 @@ The `` CSS type represents styles that can be applied to text. !!! warning - Not to be confused with the [`text-style`](../text_style.md) CSS rule that sets the style of text in a widget. + Not to be confused with the [`text-style`](../styles/text_style.md) CSS rule that sets the style of text in a widget. ## Syntax From d27e13a49ae3527c56de31b1f896e79753c54793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 5 Jan 2023 18:33:51 +0000 Subject: [PATCH 147/310] Add text-align CSS type. --- docs/css_types/text_align.md | 37 +++++++++++++++++++++++++ docs/snippets/type_syntax/text_align.md | 14 ++++++++++ mkdocs.yml | 1 + 3 files changed, 52 insertions(+) create mode 100644 docs/css_types/text_align.md create mode 100644 docs/snippets/type_syntax/text_align.md diff --git a/docs/css_types/text_align.md b/docs/css_types/text_align.md new file mode 100644 index 000000000..c9fc59785 --- /dev/null +++ b/docs/css_types/text_align.md @@ -0,0 +1,37 @@ +# <text-align> + +The `` CSS type represents alignments that can be applied to text. + +!!! warning + + Not to be confused with the [`text-align`](../styles/text_align.md) CSS rule that sets the alignment of text in a widget. + +## Syntax + +--8<-- "docs/snippets/type_syntax/text_align.md" + +## Examples + +### CSS + +```sass +* { + rule: center; + rule: end; + rule: justify; + rule: left; + rule: right; + rule: start; +} +``` + +### Python + +```py +text_align = "center" +text_align = "end" +text_align = "justify" +text_align = "left" +text_align = "right" +text_align = "start" +``` diff --git a/docs/snippets/type_syntax/text_align.md b/docs/snippets/type_syntax/text_align.md new file mode 100644 index 000000000..6720422e5 --- /dev/null +++ b/docs/snippets/type_syntax/text_align.md @@ -0,0 +1,14 @@ +A [``](/css_types/text_align) can be any of the following values: + +| Value | Alignment type | +|-----------|--------------------------------------| +| `center` | Center alignment. | +| `end` | Alias for `right`. | +| `justify` | Text is justified inside the widget. | +| `left` | Left alignment. | +| `right` | Right alignment. | +| `start` | Alias for `left`. | + +!!! tip + + The meanings of `start` and `end` will likely change when RTL languages become supported by Textual. diff --git a/mkdocs.yml b/mkdocs.yml index f6245746d..d23a8a2ee 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -39,6 +39,7 @@ nav: - "css_types/overflow.md" - "css_types/percentage.md" - "css_types/scalar.md" + - "css_types/text_align.md" - "css_types/text_style.md" - "css_types/vertical.md" - Events: From c65c691b5a9877c6a5c3fd5e8e02ad7d868c98a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 5 Jan 2023 18:35:21 +0000 Subject: [PATCH 148/310] Rework text-align CSS reference. [skip ci] --- docs/styles/text_align.md | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/docs/styles/text_align.md b/docs/styles/text_align.md index 1fc9b515c..cc72ac2d1 100644 --- a/docs/styles/text_align.md +++ b/docs/styles/text_align.md @@ -1,28 +1,32 @@ # Text-align -The `text-align` rule aligns text within a widget. +The `text-align` rule sets the text alignment in a widget. ## Syntax -``` -text-align: [left|start|center|right|end|justify]; -``` +--8<-- "docs/snippets/syntax_block_start.md" +text-align: <text-align>; +--8<-- "docs/snippets/syntax_block_end.md" + +The `text-align` rule accepts a value of the type [``](../css_types/text_align.md) that defines how text is aligned inside the widget. ### Values -| Value | Description | -|-----------|----------------------------------| -| `left` | Left aligns text in the widget | -| `start` | Left aligns text in the widget | -| `center` | Center aligns text in the widget | -| `right` | Right aligns text in the widget | -| `end` | Right aligns text in the widget | -| `justify` | Justifies text in the widget | +--8<-- "docs/snippets/type_syntax/text_align.md" + +### Defaults + +The default value is `start`. ## Example This example shows, from top to bottom: `left`, `center`, `right`, and `justify` text alignments. +=== "Output" + + ```{.textual path="docs/examples/styles/text_align.py"} + ``` + === "text_align.py" ```python @@ -35,18 +39,13 @@ This example shows, from top to bottom: `left`, `center`, `right`, and `justify` --8<-- "docs/examples/styles/text_align.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/text_align.py"} - ``` +[//]: # (TODO: Add an example that shows how `start` and `end` change when RTL support is added.) ## CSS ```sass -/* Set text in all Widgets to be right aligned */ -Widget { - text-align: right; -} +/* Set text in the widget to be right aligned */ +text-align: right; ``` ## Python From 7743feadff24b75920dc51d85a4c2a230f9a675b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 10:28:54 +0000 Subject: [PATCH 149/310] Add GIF to show all scrollbar colors. --- .../scrollbar_colors/scrollbar_background.md | 7 ++++++- .../scrollbar_background_active.md | 7 ++++++- .../scrollbar_background_hover.md | 7 ++++++- .../styles/scrollbar_colors/scrollbar_color.md | 7 ++++++- .../scrollbar_colors/scrollbar_color_active.md | 7 ++++++- .../scrollbar_colors/scrollbar_color_hover.md | 7 ++++++- .../scrollbar_colors/scrollbar_colors_demo.gif | Bin 0 -> 644536 bytes 7 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 docs/styles/scrollbar_colors/scrollbar_colors_demo.gif diff --git a/docs/styles/scrollbar_colors/scrollbar_background.md b/docs/styles/scrollbar_colors/scrollbar_background.md index 199f46249..e2792c67e 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background.md +++ b/docs/styles/scrollbar_colors/scrollbar_background.md @@ -23,7 +23,12 @@ The `scrollbar-background` sets the background color of the scrollbar. === "Output" - Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + ![](scrollbar_colors_demo.gif) + + !!! note + + The GIF above has reduced quality to make it easier to load in the documentation. + Try running the example yourself with `textual run docs/examples/styles/scrollbars2.py`. === "scrollbars2.py" diff --git a/docs/styles/scrollbar_colors/scrollbar_background_active.md b/docs/styles/scrollbar_colors/scrollbar_background_active.md index 6bab78684..2652418ee 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_active.md @@ -24,7 +24,12 @@ The `scrollbar-background-active` sets the background color of the scrollbar whe === "Output" - Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + ![](scrollbar_colors_demo.gif) + + !!! note + + The GIF above has reduced quality to make it easier to load in the documentation. + Try running the example yourself with `textual run docs/examples/styles/scrollbars2.py`. === "scrollbars2.py" diff --git a/docs/styles/scrollbar_colors/scrollbar_background_hover.md b/docs/styles/scrollbar_colors/scrollbar_background_hover.md index c86bd42b0..b01ebe1b9 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_hover.md @@ -24,7 +24,12 @@ The `scrollbar-background-hover` sets the background color of the scrollbar when === "Output" - Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + ![](scrollbar_colors_demo.gif) + + !!! note + + The GIF above has reduced quality to make it easier to load in the documentation. + Try running the example yourself with `textual run docs/examples/styles/scrollbars2.py`. === "scrollbars2.py" diff --git a/docs/styles/scrollbar_colors/scrollbar_color.md b/docs/styles/scrollbar_colors/scrollbar_color.md index 7943dc232..421e67661 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_color.md @@ -24,7 +24,12 @@ The `scrollbar-color` sets the color of the scrollbar. === "Output" - Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + ![](scrollbar_colors_demo.gif) + + !!! note + + The GIF above has reduced quality to make it easier to load in the documentation. + Try running the example yourself with `textual run docs/examples/styles/scrollbars2.py`. === "scrollbars2.py" diff --git a/docs/styles/scrollbar_colors/scrollbar_color_active.md b/docs/styles/scrollbar_colors/scrollbar_color_active.md index 9e33efc3c..6767790ff 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_active.md @@ -24,7 +24,12 @@ The `scrollbar-color-active` sets the color of the scrollbar when the thumb is b === "Output" - Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + ![](scrollbar_colors_demo.gif) + + !!! note + + The GIF above has reduced quality to make it easier to load in the documentation. + Try running the example yourself with `textual run docs/examples/styles/scrollbars2.py`. === "scrollbars2.py" diff --git a/docs/styles/scrollbar_colors/scrollbar_color_hover.md b/docs/styles/scrollbar_colors/scrollbar_color_hover.md index 1ef9c53a5..3005d0da1 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_hover.md @@ -24,7 +24,12 @@ The `scrollbar-color-hover` sets the color of the scrollbar when the cursor is o === "Output" - Awaits resolution of [issue 1479](https://github.com/textualize/textual/issues/1479). + ![](scrollbar_colors_demo.gif) + + !!! note + + The GIF above has reduced quality to make it easier to load in the documentation. + Try running the example yourself with `textual run docs/examples/styles/scrollbars2.py`. === "scrollbars2.py" diff --git a/docs/styles/scrollbar_colors/scrollbar_colors_demo.gif b/docs/styles/scrollbar_colors/scrollbar_colors_demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..b78a05afe2fc8bff3acb704f01823440ded6b906 GIT binary patch literal 644536 zcmbT7^#NHyaxpV`F3Km+8w(%Z3JqKHlD9qGE9|abjX(i|-bjZa39d*P0j~iin6vN=(*J z*E$<@R#H+DgTctk%lJ|JY;A1o>+2srd{|OkA}KDpy0UuI`smM}KeslwjvPL+`Theh z53hu{q?Dx8+c$3$5)#D4#j`T9va_>eqGR5F*l>1sX>Msb=5XxGm#=QFZY|BNGSade z>l>mXBF09>@v(8cUv~us1x18~4GtJAEi8Td_^GM6SwccWMn*!$HB=-B)lfQot$_NV^8k@_>YXAM~y!VIu=eEG^&f)szb}cQvot?!$e{P71D#^(j zeEmrK`#0kE9`N}SOGHE}CnrNe@yO)MnBTvF>(}veiWcf8eENDTrKDuPe+GX41}%AP zWaPDFWR8l9^GPVE{QL>Da&cuKd4>n%{^|(vOGtj>#cVYLpUN~=jIgYu$`ARm_j!49 zu|huqpbdrk3jiYOh7Sb8Z$2MiF#>T1 z0DhvMe83e~iHp|&z@C|qft;)+LfhDZ-zfq(Lj%s70ci1HTqF>64mcMLMAHCTEN~70 z{sO=DZ1~7$fwREgAJI~lgv3Ad|9_L+=RRiTe8PfAw$jtmfr9^5lKqRfh&n@~1qR?_ zgQKbV!1JergS1Ya3CAC`vBrn{g$70evOi%k7_bj${BP&~xe|cf2R@CIK&!L3aY+7E z`nZB@uM$t9Q4$gHtS4DeSWe$4(yuoOD}SspPPf`RC47!$Qw&q+O_jBXFkRre;30`Dm`eeM-f>O?L|6A<_0}w$;mmS7~!s+rQgoRy>9q zr#jM~p!i$U(_?d``oh6P9&Tfufl|BwOr%g2r7ck_&D~Fw4jG2etkf+QUfh}{hz^xj z9HXAt3Mn_ORZI5BQTjYNazid_F0Wx`QM}Xow9iD%ZqrPB$o|04n>FVtRIjL;X1V{D z_v`5?hwV+YR_n4}n>6nm(=2v5*HXP>*K`LaFXWpAo%ECejeJjRIj;F!;4`>6nJC9Y zeH&HiLX{1{Npnpl2#OoIo*xV3vXFlAsPMIZTX)>`@Oz_i4*Jk;EPLXO(%{~RG}KV5ojCUV-w^nhaZ1-#q2L`IoDDgrRWp0SnDQeqm=$E z*Wtl-Kz^*Bjbgr=Ry_GeNJn>FapKz&r(CyR_mx=nJ^Q!bm(~151vLf^54~@o`l8Y;XG56}%`=+<6=U1Dl z8FrfYnU@kGIv(W?g|}~&+9^G_H}+iX+H}RnT$tW)oCCX!2Xj5*DKhG)o-gh^wX_2< z-16{y&vmVmpAH>2Tx*AR9G_J^7M@}L%}!o;=1`1hzy$MU&BeY1Tgwb6BuGvVm8s6$ z7^NUd*;7EZOUi9ZKfv3UREhg^i%Un9Rj~{&4S_y6lJIOmttZWTG z!8SVT(pqtY^6gt6%6VUR)#u107=1`T@cY(A-@wE0TW?-TtUX+;uqk{}`Q0mW7k69Y zPha)R^O3fp7oS9Y6Z$%A_ET6s^T(%*g!f@zH>`Qh9xoh!dhyYluNh{|zfQ>P&xp3{ z7pT*huDkrq?UNIAu!xAtba)eTKwc7M&TXJ#E>cKi!1@-Dyc~$w+;-(!l8U*48acHz z3M$>Y06i?8^(q?Cp4%M&F{KlFi(z+53Rv7K3k>1?FiPV5xntz3Ar?MK`J$qPzVrjj z$9dwv6-z6TGHf#EUM)jZm5vRkyIRf;Hh1K!4U>c1U~@tbgRH9zluoB=dePj5vv zRCTY!dzj~6rAHU>MuS|nFU`eZyUE2_iui=lUMpFYvS5`ssmN)bc_U*#4AUJ%54+4WPSifN7ZToOFU20 zgLh`_9GEt4HHv?mj$;#ER{V0VI{cWMOGU>8Hz9D=gaBFn(gqs0gET{fvRY25>oLfg zNZe?^=LxH^8%_psH%8X~D?9yYxa3npl?DDtliQv22X|XyXPr&uSIA!GJ9mCO56*?4 zCsd4IwyfDVQp7TAM$eDm%by4}7Id3Az5mzcQtyFR)?N>7#$5#~n(s;a=CiW=B>%(p z6Ply)p3kqSiQbL(t^Jk)0c*nB+5i!>b6$rLj^a)yfn%?I_h2C?nQ^zXe;A z^%T0p;Q4y+sfU8FjL3fLSWgu3Oy;rvDTuGlvNXt&XI&d`qI^b5Fs zX&&&ygTSs<_pK&gA~Go+MC?&8m$@aWopUhxG!Xt{6o58hAtTp_+^mm1Lek!Fd>X4> z@W(FPbpb#a;i05$$4ephbv!g8DCG>mjaYzE7@q6Ydm`r5_98+Egf{W^Uma>UhoE#N-|&Eq$3J)7LOizZzO(LTIq_j zsiNrqi!P~S$9lqUUHDH<+1QPF7c5TLJF2aFfAr{;uL!A{)k8%;2b_AoSq9tc+>Pe*4aT6&z-=hVtck4lI`5Mk?5R_#Obb2h$$pNr{NKKT`i0Vv!3?}^%Ce68KF#~@gTNNC#m%9$`gaM5Bo5o z900b7L@6N+F*FWbCXR8ez#Mu!RHKaGl?%PYAnt_ys8>5q2yc=7Tw*Use+C)6Gm z9RGQW4o#w8UN!q6=z%dh%xgqIt1uQO=-iWZ(Rwq8B}0P5IH7oq+7T$eOYfXwY~&IC zNn_v!Gh7q0BspIUY_TBY0?F&D0rJ}HKfinQ{08+RZFjF#IA?J*-4%CWe_sH2? z4I*&V$~T;>BGGE+N%k>wce`^ip;k~$h7NOs`)*sC>(HQRHUhFwapwDWQ2n#PGlqGX zg`s+lRJ4k8u)N&MYv$o!@nXdEObF8ZD!YW^0UsS0{gkaD z?RfInOB-BBK%0SKq_`v~XgI!}`VmHB1IP!Vr#xaV&sW3t!L zRL^#6QuWxgAPbxPb-}~ya;Hs(PAhe}$B9toRur6n26Yu2b5Cd9D#&9qZC*xY4HXya z8~NzqLI0dY8)FAlV8S6J>^m%pe<6F}2k?4Okwm+)tOUwqp+2;f($fjyEZAimSiKt} zfIr9@57TS4vr=?*ZUsqfn9D-Mb_z_Np7w+b%H?q)X3AJq%#McuV%a(VD?}L~D4GM8 zrukl;O+(ZC?6#pV?t$WLkdJK_V4Qa{_;lh*;0UC^z&NP*Yd(47vRInZ&_=!yO8IB1 zajBqMcYKhIf8m^PK`xxGIq3O)Uyr%nTMnx~{z8ntbYCsP+Uu@j-kfpS?Sg`V^ul1( z!~zj?WqRWEX~f}~G6x!BIt}Kz0KA^be&=qoM7m;c1@qQPyLk^Tg@@|4LJqw;72lPF zqq)dngKiW8$~gfs90Y+36Q;v_7qZoKu4*m750T=F`sAyFOIKhP(``9eL4b^e8L=SR z+tv02xbXtXpADLe1CM`Rzm=!pzJ2ZN=Ofr*1)c31USc=S8Q$=ZFI&E^T2xS;7*l&` z)%4VCMJdw;$f!7qVnXWGb%VW#^aS4rc^97r`Zv@D4A(w^9V>0GjXGZtTUc9>q$m}5 z{hg;(e?&-EgtgOWFM< z!$d(%rC`Cvd4tym((ONNWBS(!6)RW9e5*$ZI+zLFv=4axNV6 zH_SfDsWbR`OVsVoPt0c5Tg`qp9hs*(B0eY~5?T+aAmbA)EEHh!c(}PxsWCe$M(>Um z`Of@$_TMh>lsg1T1{GQ%cAO;7R#zzkRFDITlHt!{6U@jkAp%?=50aAj7)v-R;UssNYmZ_)`G$960*) zeTmj|3LathBN4@FE4_b8hWzg`J#DwEW_Epium}%4!j5vym~2$s2Uot(2almZjkM%+ zK%WJKoNbjA=c0{qic1cBzza+myev&FRtGHIsuV?w0W`t+jH0Ut4dzeF))awBUWfZ_ zXQ`3lhjT)G=i#~lLdt~xUFFc)AvK}-Zoa)v+@4nSp|B{$ zI+HgCuZFSVNcJCj_Sw+E7~#R(M?={8p~6R`MD zJboiC{mGAUyk-`pXPociIPbOLVr&8Ll3Q8L&LQb-xaRbpMcR=E6RgAIm;V-fzO1m5f zcBuTk^|`5q{FlOv3BMELT$&m9^6_)-88oR3%7N+f6l?z-{dh|&W{v*(e5AFM^(B34 zx_&H1ZbmkIS}lA$s%iSeqYSw%X@#xv*7b?+sF#UNV?yIF_dijx{Bxc>bAGW+)!}Z| zss7cEV`8UcX6CTLPO71m=XAMVldd(L#JPmd-w6{$K?}G z-;5vjo4~)p{x*Fs;4}Rse3t!ZUPE(MM<<`&+*Gw-2wneSClO??wXm zx^CKX%AW(5cc#OHW{x`YKmMp+acxFMep8pYDez=5{@DAlvHx1Gd=RTxDn0x@PGalA z+qKq+HF4gS{9~&Vmp)ATZk?zY;(fGg9`T{*?N&7Jnsnn<-P?~V%^y-4T8G$$iOq(i zk0-8~O;5aeL++bS-I`8>%}Acz#&&Q1{+PbB^(mEi`;F#yo>?aJ?{<#V=W(;oMN4NP zm);2YuiN{*U32&xJ<1W4`4VULWmRfh>Jv6%^b>Ah`-}3#7s*eS=s%wqo4&LdNe}#> zKG%t(i|&lz;>QgcG@ac<6LhHsrME%X%A)TP8>f^q!1Ee1i>^49y<8^)(90n*$WZD=lhR z-j=xdym1fE<2mXF|32o%$>F?Qnd-y$^Q&uj?XLb{wEReT zw*2dZ>D4o}3s0M0o$RoX>n@M_iIhP9(DKCtSUe29d54I~GIXHiM}obTy^=aYhr^us zt#eX&huCR2-Ty4E3M-q0L6QdHNYCM%@d<>3M7qwPbJ%}h`~)&|tz0by@Fa_5j9*fk zF43-6k3Yw71Q%IjnTb0PvH62v!A4v?ZGpf%K;qS>($L}JdH!%Yc}N&-{FRkMNBG++ zqIoqpTHD5Oa+&+yXev4^ZJUrQj~WrPyqmP~rRsxKt5`!?W!6&SyJY*8!@}{O5y)fbW?V(J={B1r$5u&Y{&2-|z{kz78KEKBQW}n-51?F&LE@8dcdMTz>5%-mO1<^Ek?8(|5{g^&Css+n$)v zm=Kb+RsVC>N#@2w=RpV2z#=TFnLvoNF|PB!jq zclSAI_05g!+&<-DmpvLy`aF2xxEXCc^o1F5l_o2O?^~y5NY}8;A=MRas_quAbq+wZ znLhxC_Am#M@_df-L6bj+3eD_Xje4HU2XpC3z5yZlGtLWJLQg6P6h5y_mf>Ae&enDZ zxof>SeA)Pbw8bnQ&$mve^lu1t!&~qXq5r*_51C0$y*Q!Eq;o}B!1xDe2(tf)H?%J# z7NHHzMegE>Ns?WU_NSZ_)Uf_37ec>4I32KaJSQ(od^?eZ)WJg%k@>Bi-5qkRcJy|U zW|XqFH%Io_fnfVMMpiqOX+@0mjXQmHD?%Mf+${+8OEN5+59*Y@yw?QNo;F(Rz~05o>DE+Is&KNb?kw;KjqQefW}~1BESKd z&Sa?eIyVH@r_g35*%ny@a@sthG@mb9dVOqf3a z5b#7aml zm!;nS+dmS=l|Q)ovExzpq85>JR{G?H>4%FpTExxY$M-i2ldd{8U-g5|9;XhNTfE0y zyLF;w-5qy-y67a}CP&I4K#I2k z*+x3o0UavpfgD6DjR>OMnRdbk=7=l`Qe~8hwdLeaw=Y0;?-L}yrS}v*Qc%is@^`&J zuLKDHBq5o>JB(*yG*as9S%ReN1Wr?$W3F5dn;+KzGk7w3M9jU1{|b%4i%i3S>!7&| z8BzIa0J}MqMc>ttC+_%yI|uQn=h=m`^05rhjJV{u&@*g=D4BrTQ3wCD1)@Jk6E3`Y%|v!Zp<}O|f%pTI zR`9mQIUfr|RS6tHTI53ObaOqyGcff8z=xvJ`wb377#YEw*lc(M;3rC!MccK4NIi5v zK8qibd|MFHqn{|5Q;9i(g<{*VbbU4*eS9AqDO$!+ZUNCKiqP$(REn!?hpaA!x-D*c z9w$O$fM_;&^kv|QeNvZU-S}8kgIwvSnN|Jq^r4XY|0F+95ynvwU!5O7*VYD0#%}qI z(i*{(*OU#^M@{_Y3db!klu=9uXHm-z6K9oKa_`>_EYR{R(+cl5w z)8R-fI&Thz2yI=^vkNP!_>pu?FKhu}$GQa*(Sg9-DM6R4%K9J+ayYXPsGbtzjujhn zDR2`So-uJnhS~DbSL0-qr6T&(0wYxufcmH~koh`+a=@Y481B5JLmcH_gh-wQ?e#c^b~a@ap6MKKrc3Mtkd3>8IUs7tLO=iP>JhFj))<1K|l_L)F&- zK!|XJ0sQ*H#NzK%W>!^&f^w~lp6#ohNPyq{exYElAr7KDbNjq3Lv04K=>>pTrY0FB zMFS=3A-t`CCX2xZFn;<;b#RIm@)Q^$ngdQ1gAI*xi&C%eYmkQx{ISyl`P;OrkrNeA?3zDijCg~baeRuwEZbT&Zb+4INI+72Y zsPO|7#z8L2K{e>$(=WK3U^?YDgf~P0N2i18-Fh6x?n|(3i4I!_)NyHP)qU?DSl*0B z%3~8#696R9$l4VVM=-+ zwDVPB?yUmU>oY&nPQjElY1f0CuZyn>j^m6Bu<6;jXW~?bQGWfuyjn+mrjVs|lqK}; zZ{)?zqnG!N(w7HTDcKCmM1}%sT!%DC9!xeJ%%YGM=!0p|q}w@z>#c+PnKgq~2@rnw z%=iz3JnN*9AJ(aClF0#^+cQTQ`E4(CY+kEf{er)$J0ktoR#cvayOJcIL@E+qXX4zm zezOM*jTmxdKmdS%Isl^U;8PA=F$b*c!;BCgo0Up6G#(b&hHw`@&OidvMqqGN3xdfA z${$X-g=#1>4cjTYxWf=uAu8%vC4CU&Vcp6`LuK7Dvedfj?y}xAThT7P{1b_vPcV@> zN8|zfz_x==!xFK0>&R$=(z>APOtW@eCQqF8gQ0c_suk*oJtr$odk`EZk!37<1* z(GpMXCFG2bW|3_~2hk6R4rmfxi({wzW9X7oVr6ib_SuU4-nhn2*6=<3u>tcj3r70W z_uMPd$5u_B!{Wy_vc}XKkJ;ysjVum7vxh8M+ISU|GwHg|KP+d;8V&Q( zf!y;DtrN#TCyi}-AAdqRzWwOMufDNWnDig-WADW*XtG5CrF^=qqqh_ip9w-GXCQ)l z5P2L#Z~?E?mHEgWK$7XTBWchyhOUa;FBs2n{EmVSLj_CUH;kjptv|c4Ge8p>y{Law<4+nxq9&Wp z;35NY=^WG>hWtadg}r+I{;rv@QM&zv;?~tx@`PgeM2Nagc3GQM;6#C>{#4hb%Hm}1 zj`OQx=cLI=GTcS!@g!Fcs70fH{tw`zK%n)2Hr??=`#n!h7gC@Tu;J`=anibA^0=mp zWAb2;cM9!((~i#7P5vbL>kL>n5VnU@S%(O-Z4M|NJzWc_v!uglfXO*)(NSlU*OOM3 zvd2!5^@SOHD>{c}kO*P7RMvPt?fUIWN8FYp9y=gX4wQLw^Vd%)zhU%Df_(wpsRX8a z_{e~U_2pnNnj^N4aOhS)9m8kWYmv&ca3ZwibSNxId$uAtuw^KZ1k5xRM1FFz7vjnT>z!&f5WS z_A`l<*^66lPifBu!ZKriJ4&qsayek{W*(aUB9J&vv9CDLYNbF*Mhd_!(v`QjwEJc%wyd4}!+blH!3DTV3d1SO95(|UVl zw(rxfyJCYrSHmEB_4k{W2VZJFhZnn^d@YbTimX^Z()GCH>&WpNE3;o3PyV(#zBhXE z*J#<`?2G+PkNw@_TaVs>N(%#35Xvb)l=My!$++U;@i)8rPx}kNaN&JlD=O_j%!fg8jU*ZjvAnJ0NDl5 zVvFu}?m1TFp9%BK)RDtVphr0GcL4x{1uUPv(%Sad+GbyHVe%mFCCY=sIgo}~eJ&E+ zfJ#S2R6swLR7&y;LXVRaf5DG8I_Avf`^W(lY43hLVAn)9XT9M%t9cpdG`lF`XgLZTc!u_SJ zF>!LeC}}aMnQ~k%_h;>bdxw-9>cc(h5Br*-?qd{>zbD&MLSK8(jkWn<6)Dw|32Y{h8vOcCj~` zBKb^kAOGyTPEvoK#KAB8OD7O7t!DaK_)^x%Q-Pw@>z;*=8wPj6EUBE^-Xz{NH$ zt|+B9bP1U+t@tRUXrw;nnJhz~XvRf-;EP78kUnWb>-(2M6jp1Rw%2)qp3T#MLSkUAKMK?Tfd98`@VCWYuDy#G?{PLNoLpSX|(h4UE7oAT-Tx{=iYM8>)@_;?5_9Ib55Vmo#guFuy)RGde?vLT!hsueBoa?h$*8Pb?Qir=l-t$ zjooA4qX~S`G>@>esyjy?2in8ZEmPB!(!Tl2#9mQ}jV?ME?-hIQ^igl6?=h+0X+_`5 zbz=Q)#*R|HC&Ye_zZ^?@7fY9k3l;f(dH*~8;Ezj1595x1PdsUIf$Q7;)7!DBC*!VB zzcV|(XQuv$QvMcl^hZ|9kL*veS!d!d$^6Vd9jh=%#||g1HR_@BeVP`XGnzOzmANrtVBz z$|vyKhp|teeo31Hv1fJ>e|`!7d423mU9tI~bl3~Nu$i?_r?vjf9l1Dt^349s^q*PL z?YVcA1S{{qybZ#i@fA$Ie__yKrG}Ehg|wZ07g)O1@u=7xCwA zeD8hwyYI#C{?6aED+za|f43D~d2(d`vG)G=)ctRKzwN#DZnj)D_qx2tg~U;#*ecX* zR<{yloJDjeFIuDuD5Difx{Ez2ys|wDM%PlY@)D4IKYEW{&K0e>F8A4IRox6xUA@V) zoa%uR!NB*I+khk`Z|NQP5)%g0G`JZjGFD|{w2>Ly(|NdozwsH*jp>KYJxm+)J zvwybx&6m3zN|#ea!FiEUIgICe?MqXkUKX8F-d$_!ZKJJ3zTC zg|Qjy3&i0#`KyM$gB7&HOzHv(g1eRsm$@*W0(a0SS`)8#=U50*Ld5o0i#?fQY=j)f zoy9N+ij&U^l?CwvB%?K_SYmRgvXh-b0Vcp?CU~t>pZRSy_t#3CJIcqDZUyA~8NE55 z(cGVeQJNt>JK@wGuTuLn9uM4-rhf)6hUfY*AYl}i1vbW5<;~5uid`aH0U$Q;*tUI6 zc4?0&st?jM!ozJmRRToP`QLhOcpNMvLmGBbw`)Q}KeGvZtqqe^9@@T{)Q(>Tv}6QG zC{nm@qO+(1TW$IfR8RBFD9_Vc{$M2mY5@a$&Db}K_16S2T_ zre28r+^=Nv8o@0;gQd45i&1+qJZ=kCK>6xVsT)TP4(ty|s%w^Y*BjiVMS3Y!ITkp$ zbw^(_H?T>{vru#X3?-h__#No%@%e&_g~wEziyKCmN=BO7w}L%X$I~~w#7$WM9D$6C z8b($!04~RER$_~pTg{21VvdynS5s80#Y^)ekIB~5Fixk-^JP#P(f>kQQdI;m-jpF>JR*a!K~FSdMFWJ_l;0G41V)UF*xUBu6g- zB1tD!el22nJ|4oP9M#;J^o>8a`<~b4v!#fI2BDkJRB{3CCM?Rk_qqFZ4gg0*FLw92 z9e;1oW)Uq5EMl+Ma=mSeX$8f+bMHhwUwmx3?++Y^=I@0U{+o>SLkxMkrhkjV&V!or z7QJbf^*V>72D2GL!9FiYSf(VF53bu)0oPy^eKoVQI33xIaczY+@20@tpv{}gwgHF8 zhL{ktg&>U$s&#!bUP+`wqycbAOq=HESTV((xTZP9;x?e$Puo&k(B1^NVCX+Kufq@? zWO=6Cb@3eYhoZy&G06Iff;oyl{3qId)Dypfj)HRKe9Ch5=a%FbV8S>AO$jI_NTD9C zILUQ-L~Z?dqujqLwm4%?R8_*?4*KM%{Yu^W|>QeaRkvQ-Xm0(jB~YXm|M>{pp^Rl@t?e zDFDduHhRF{^~iUY%$C3PBE(1v z%Aq)~J3t=+^?p%C42AS5sj5f?IO0!v))Z;QGUd{0bhb|1ceo&j*}7L(K$?V~6CfV8tEq)!7|7%9^bDm} z*ED~zx##*ey1jo6C*=l%hwCBSba7avp)AxYhj|c;K9+e=Rs$+bbP#1T)mVfE=cZu! z?zW?_xb7Q}{f!1MhX*7Dg0tFO=%C|xUtLV@;&nnY9Tu_SVs6%4P~fGC5do54$`Y>= zb(RG}a-gTg7Epq80!E<~;HTobF)VU`MnGXpgiX~y%FA!t>d?V5DD;cE-A`dXaW1SR z%M618S4tiP>fKXWj$|O|c*F*L3XW?6c)KXcl7qt#3pOA~+wL)pZh$zoLU<0bAeelH z!&ns))*~?kHyeO!#xbJKY=d8#1Cmtkvd?`*Ft?Af%;k}Z29?hf<0_Lw@e2@M&bNG( zI>lrj;k1iXn$Ir;K6AUa2PwdYZW~5xIpH9vyDX-(cW1UM>K4`~-CbTG_P&<8<9>pV zkVz}d1`WI-aHRn!?wKZYjh7P=d6MY+dX>=W|IqF!oJ7%pMVLib#Dfv@L}4TzGPnZa zoBb^*)Vbax+z-UvybWDQQIi9Y#hhKDan1>c-rIQYh9Qg7=T9W_;u1;%v zbwyajv*E(_IlW6OpFDu;T56V^T#4RpJkAuTgtsghiZch8gcJaCpR;;RIqm=!s{Es* zScJj^U0d%9veQYyt8(0`QIh?!lN?5KrKem}JpY|I3XhDD4Pd*cVk_}m1 zoD(HrRNuA{p|c`PoaDk*JmbBFURM`RfEHNOLx6~4AOJeqf-h$;WT^16;&4cv?zr4Jc+3m zKm_endb&;u-)^oYA|yFG9ar%{A@!coN(UX*lqj6T7VRR4#g(8rbbf-nsQY+ED}fscq6S5wlVy)C zh{pXPK*AW;lJb+J033;kBy;y?r7_$I*XId*nC=-ej)Z zH&pA*w`hAte|U54U_B_Rc{6hRx5XmcN; zRbu`#a6!y>SF<9ut!Vc##p*L%mgW?$c z7?7nqD1XdDA_I z4ECxr?85c|%m{!lK>E zbmSlbQ&u87Hi0U3@uLoP6~8OXa=^~GN=QoaRh0=g){MLJ(}LN6&uiaJyO2RTI+7=T z6m>lC-Qi0B-bDD4Bk4L-h<}Gp)^e0s_jdDqgQ#SP#&z2mdi&^>^M(;|D%Fvi0I$)w zt!KfKv6#)Uvt2kFq9LQ#l!n})9|v9fOb0}+Il;1gQc&*hq*+@S5x^5uhK{aH?k6Ml zZ4uE`NXdT^hn^ALN3S1x_^48`q8mK|P`92@jxMBjDX)9fEcY666oO!ZCsvPm9=JmANP^Sz8St9!lX{@Q zh*fKC-L-s@|Mpsnwm-kmeb9RkuTY>um0eGbJG9Hg)CW|{U z(s^aq(|D_faEIc9MAM{daIB>!7%r(h?Mrg(u-Mzy@}}S$;de!{*XwX(MmBodAMIrZ zaa+>y7Ndg0>xJTJ9)hM42jEr*=7}RL25nvw5yx-ZC)_x_*bjj zXe}}N+iKr&XQ5d&>P)^$iUgF#Fbw%u6YYHUFO^t)Bga=gfK6Wnv$(RtHtma2pDcy- zHJnWm!RQBtTnzJx8x#&(IeWo6l0*#jY~+rs9Oa+Lj+#LI2t`Qxu(>4dieJ?M;kw$L;;gk26{rRq{-8fM6BEi<%zw_;U%e;aDBtW1( z%r}fZ>Z&xW3D%bOBS>tF3Sk-z-W-EBd-^!SiI48fC5F{`G`dhtfYD~yfA4)H>V2H! zf<$nq`7mCvvZgFKuymphnYQn8!N0q*gkTk1&gJfv`An!=pPyxD$rzMd&Y*uJ1xmy* zQ1x@)y8-Tsaolc`{cz^lDiNX5{=}>X?mk|xbkZ9akbz+E3w3v80A%s>2N@;zRM(ll z3gk!jBlrzk)5~k6Rw?Phdpp#x;#;7<2Tz(xdIO%D9zs-|BCf0#C+Z7CRtqdM7&?z3dJFP|(z&TbAkBMDEDJeu>noZJ%e=)w z@rp(hh1=;uuzkvh^V^M1sz@1s2&TC>(y98vM<)X(#JwDUqwb0K&uR>LNE$>`G~spz zC|LjIcS8_1C*K-&b*VX0&@>{)hyZ!iz@LHC4Jt+yA-)+CS0Atu0m=<3L^O&nOlNEM zjJEvCjs_4m1Bi%aareyvIU8jP0xbBf_Ox-j?(GoR+S2yLWz~Vm)AsNEwW0SB&O?c4 zOnRTg=`S>*Ly8G$*pX0Qdw5y3K;!hvTTNptx}eT0guR0Gs~dk9sV0N!zU~D=7bXh> zyZvL(y61v5gYys?#IpifzP5L&zKH)S>laGuM#=~Y%rwvTEB@D--l)Kc4hVB=AHoE5 zm#pk>J@4UwCp}*%g02GPCr9YH5!(t}V(Jo=K1N}+)~SORH*VJJh;vF&M~V7pQLl}a zyBjr|S8s}CvNK4U0qoOhTczBM!|-kXGf&uz_rQzga6z|V1_#(v1KZDq*2G`QFh&V; z>F8MK_w6j8f6%>WWY2sdz?Aa%g>uxZ`wt%gWTZUBx7Q?F*ylo&<}bBk(hlHL>H!o8 zpQInKND*qw&N$3<@WHxA*grqL?c%E%B<}E)*)Mu|7~g;@UC#EgWJfjc2;PiXGW>Yp z1)o@2Xzxn3m=->zr;)oW^e_8^Wd2e6gxkCEyk#-|ToNI3o+n9Sjp;SI-&8;ei~Vf= zO5&@q>|^kJA^{;Uz3WMXIn7bs47!Ch7{^n#7F5;o@?ef!uFJBeNZw1igU`86jPz}u z*i6Z@J{K9g`~1Ed3~QE=W)=`o)PdZNNt&6%c@J5PHAf_|#R(BsCs7X-H7-7SE|6DY z-SRwlhz-eal@7gg@SUw`>};glHtN7BNESW4OYx!t?^cwJR+}G!81MuQ3 z;nDQE{y^jIH5-?iQn zX}fbYWTN9)z-9Y%wUHBaQe-c#!_X=7*IUKDR7I4;xeRH z=5lOy!P)Wn6Th^DWxE7%qFAjvUx6{6%mz-qN=&yUj|s6iV5D9a#`|aX&Nz{{M?HO# zr>}O5p*Dw3B=OL-Feapj`=KF4lSf&WaN_QDS00RO+YJA6nr7S+q_QqCu!)_r; zA}q*@7H7k2bAo>K$b{)zls}f+x{@uZ^Yd-nFDsRI5m-b8Q7obN>iC;btEkhA15?Ag z?s=|o_;C_Wq2Ki{zWqb$^|9cSw%$=T;-0p`vl#~?d-~04dl(~9 zVC#>-R?CzE$D?2V1N)Ui@ul@^fRO*36>g1T z6V{38#Q7XGjP|6y>mwKenql)=!A3|VyR66Ygbzbj9WJ-a8yxlmX zu>hLsc{!?|ql7}RND^u8a>1N9@u`Z20#r=7I*DkQLTdXhi>^P-wJq zUJwS*5LTv+ri)fi5UuAOZ+_9vqyHIi7Kslb43rd_BS|XpbnI(RruAJ7bRu&UrTU*? zdbzEsc*&%F{+-o4{ldcrGdIKhXq~HH+LV(~nmZfEv8aHoDFlV!G)+h=`R>A z`{Vy<+;a?d^p4MUwZdEO7q1xb#jdlfG zN1REGxXK~;Ht}1@&z#Hm1BTz$#7+5lXqLD4ALLEN^B>i{8XfQIofMp;E9*SNO853I zfuHeAmig!EcN%sw&b0u-fPOCg^@Yo63wUEzi9ez3Sx7!yO+b7w|E0D<#NBDO#II97 z2*-*MdpT9cJl5B;-}w(Wb4W-SxOtt83GvMLX%u-gBUb9n7M!S*@g?}4zUW5Vl+N#R zZ#ee=!nOBr=gOmv9?`Ge-#kdjC!Um==F70@~KtK)7ZC_KWBU} zk3&0BB&+tK7Sla8y%M~ueyvtsUHTb$Y-i};7NxQJ-<7qy&wH-)9bfK2e<`T#`Tb@1 zV{+n7^Fh_0t%bAI``_Q3dYZKHIpb;Kk5BjCCjZ<1I+qCUO75+&oZNboPh7fLecFJ5 zK={*E?%5aWzHNoEDu=C04i6#Y}v8{<=KbyKH+^(y^Aex~!M0d@I?p zX&H5Y)>v6NB4=BrmhWbe@%pP^v{5I3#?v(A1IKd3+kE*xWg4rE6y(GXEdSm#?-A%@ zqy^`svlsC`krx}elsUjL*@A$X%8yer53=iI6)c7=1$GKcJ!NH{%iZleKJHx3_d#C& zj@IWIMDY#l+sa4vN1Pw+l-zR^g0$!cC4(1A9=yD*?x#QE)wg5SBjkb2vgmmK1}wYL z{{~|hq&KJLKr-)jR`7EYI-nv-4)o6uh0-hSkuSSb&Mc3)W&ZuF%iJS@s`Qe3KmM${wXUDF@6)b}s{HKw z{XeHVGx__5+Mj*yme013ogSnN{^uyQFw(>ABbxW)DLhg}z%_xH_v7Uvy1^F;1(g@kyf zo?z=T`%MqKW;URHB{J*J3#Zr`#f1|*54$E8!g-5DJwHiYdbsjt>iBmh`%wGq(F~if zF&8hK`#wF>vm2Ij@dMl9@6GE^AAP@{oOJNp6I8h5g3yT&HTSSy=HR(ONI4P_JzrJ0 zjfGi^lPo{oVC2TlK2gU5Y+97#lYs*IUk2qe7IG#Z8l=hLW+4tn-OJ~uMT2~Z5szyk zF0XoKYsMY7?XFtePbKpWsOv=Kvd#PTnM@9UXIFElvbicH%-*urnGAR=>=e5CWx#DU zlfsea`|@54Rs0%zN=8;kRIzhdLs*EvN}q=&w#n_Vb-=C3P?c{2G{nkmMGG?dMQ1J|Z>av-1_Yix48eJZY*_fIoft6!N&hhc z)i6qDJ5C2G!c?D|R7IIq8O%M={PBePp+QjAf~-z7Lr~rHhnh9`q5(n zmX2e?5Qj zN>oQr;4Ay25$}&pY^k4^*Lx0{IqVOEMI(B8*&g-vi@&v}O9#l(K<@zE5`bB++*kZe zhnd*g%)l?2;pR){<&^heS6djqo#1q`U8kksQPM`5c=}pr#1Jf*3o>d3I`k#^5~&G@EG+SjzU*PNKGLo>i)6`~(Q z?XF5gmjP^KIN6d4&y+3pq@(hf%T+XvaO`d&tyzH1vXUQI90GL`zb4X==J5B29P<@8 z%7E^ysSYy(wARjk?qF?oU1rxLu#NV^RPkSJ38=hV$S+&4;sLczD%`VS`<^_6!E6gL z^n zM;@=A@6M~efj^%XVI8?8pP9XrmB*vxuy!LnRLSSL(nS{KhZ#zwAmy|nMWu|07JH@U zLY2qkHySlB(d{qdrC4h0D880#vQez>5Em~{SubEAPWt4UJ@?-gQ@#SI>qtWr?fpUH z#+x3jb2<}Tmf1ao1$>BzbOK8p9^*)rDq({*cYLg|Fh?0T%oZfp${w?W?lE&U+62R? znl40^mPkYp9-d1Fl8GVqRJI5@kdkJdOh7B|ut-oL+tcGs)Zk7kYalfsoxtX*U>`Vf zt+61+kq*}*ux4*5f0kFOQBv-=SIrtXc*S!}`@CxVj=|%JW9_ZV{Q(ADEe0<(H0&&rNR9mnH8Mg>ra$W$ha)$1dF zd2v&(FCUgBrwPVnnv4mN{Sfs)ZECPEkdLrh(Sx3V{Ej`ZFJW2g;IojC<&_*+!CUd(p=D}@}ZZq54zk3v#t zY?dda6D7GZl7xS8kYKeup8S zh4F?+81cVTm@lCAw)6^rzN|w^vXd_3+wnelV&ni0s zTM57`(PJCw&ZpErEB7H98Lo56lihVc3h%Y#wYxQ+**Lhu<@O}i{qp_2Mpd`#7dLB5 z+#XMPkna6j3w3{zw?ER})XDEL7W*^v?Anr*XTw*o{>_u`n$FDFV|KJyD0o((cHf;4 z7YvLek;!67K)eRFt#rt!#{%G|G2=y9=`D-yjMqUyEW`!c3dr%zw`_q#1bJQ6_HI~Gp9zF za)5lX1+sAk$~tC8gZ(BVA=wRtc_^Fmj_L7xU@6i6X=;!XCkjr7Ev7Id_B0^X5Y@ zH=Nfkmvar*uY7j$x;=H-CGYb6nS?j|R|2>a`!9LclqAkgB@X`dnE2^F^Yh$x5z8U$ z9!fyS63`Jur(;++YRW{y*}#XGd@$ha@hQq9MJANW${tfskd}~?bI6dBDXDWo;hvt; z;W&3G&>IE|8b1==lnxJ?{CD7raN9ov=}oeYevSVd%TYlL*uX08Z#fk) z6Q(XDz5co0^xZQ-Xych+=3|%4>hBp3zbB=YB@Itqxm=c&)ahQLmw78bb798)w{!Bg zx^NVhdoFT5o`6_pCQlI1a34(`Sb45ExK zXsR`J=UD84Gs=@lBQoocCPU*sXh099inT~qflVHo1+G+nd;Yk4Xvav=>Q=DT zk=I>yR#ss{&z7Q3e6PRl^vJr>{0hA|qp8?xn6KW=AfvIZp?$XOBZ1QduXl^Uab^RR zN6as>z5AK}@Ze`w1Vkt?of+Q9Rtf=D?LH}Zj7#$|>6L{zxrBx7G(kO#%uqNh(~ z?YyF4$dtcMKp%o{jFNj*Rm&Fkej6%s<};fH6`AhQsqJtv9$>*^U9JEuI6CI5ZD-bFWU+_0JJz%e-@Kj1 zS^=QSh^)08^g4jW=$I=G8~gk>TNyz08|;33>~RqSiePp>q_de{fnl(Sh)!5%0V_k) z+l;``xNunuV6DRvzlyTnJNB4cEVe`xtRg^)@{ck+=-<=W90x4U&)d9?cC{2C?xJpA z<@rXQ&*;(0KR7er;ALQG;n^^i(Ri&f-Q>^hVU_yli2Q-IM+3VJE{_I2XFN>!EwYmP zC%s!oF8xAoTC8&V5QuXfO*>G`zsSxQ79P8>`~`u*B+QE))O{GyPE-jKsrpiH^ZEG2s`#W|=yh_j0 zRm{tV}ziRFlct`tfqQ3X?iKk80$q6CnmI|srl$>gR_vHJrq;E+* zAFQhO_1~=Cm;Bi3y?Wyy>qu3{Q}6wwUVpB3{mz&C{rX^|`^{dz;4jjtJ&w0$E=M$+ zJ#OtMW(gW)pv294I)lbj*+sO}=i|3|2rza{oREPvZ{0OBK{4IFpb3iKX^NOIk~>TD zwq*fU_g+jvs@!m~`hltZSmsfgTzTA;AEA9wa^*J+J+Aa-I@IUnOO=$yMDE<4tTl0X zCf3y=|NN$&_WH`F=<~KE#!elfv)@BpABfx4e=2YLe7aM8sV}UH+h4QuLO&FyGOq5` zbtzyqwDo9HUM|bQxtFdJ@7+qxBLr3~o{f&DpO$)EyvX-?qS3*{c{=`bZJ?0&F@?dA zn0hVm4tp<~!eKXZ|XCf6Z`o)~7&5BG|X^#2Gpa`h;+O znZx_T;IK%uHcYrAVEu-DrGb-_<87O?>y9op|E&ur)ZcDE1^MrS!rm*?0#`1xIFMT* z9&{6yZGWeF&^B)WI5bU3Iu*%2rY#FaS^eq~pc4A%)fAxb^91oEe`jg*aOm^$8>(F$ zcT#Ii_2y~z{J+PYP!o>)F5N~b5xZ*EyAjUnCPWywQ0jtN+k`Wl zc)&a&eXg=XO+N5_Oi^pzf#dK+f4no_Be;8yB*D9q$_VvRAtiA z=2c{nWFh5D>cGbn!*?a0@XmQO|J?7xtGq|wIO)iH=Wfqx23a#q^wvWugI5=GAcYD} z-b0X>3)Kq>H5#&YEA$*myMIpYio}>FF%?0>qZEQhqidt7fR@z71lWs@blsCk_lCsk zW7SZO;uSFZL^|5#3S~n(h zWl(URvi+k*$-OU9?H2`k$}_7kXW`@KLQJBH_0XFP-m_bX9~&tZl|7=t>)8Zs8?a7lI}1wCp%r*jOyJEwfSFMx!=@l;&(Id3EY z@yd4FvE0~EloZ4xso_AqTF#IO{t8b*zK(h)dpQw7K_BzeJoHjkff{S~pd4eP+Yi02aItf(5#fpy;$bNdi8BQ-inLU=VgS09 zO5#=AN)a)^Bg8uKhsTj{{t7BW&=o@GV#o)$R05kN)|e*|53(F*g8uX7z+rAEDfo)NBj~J9DFkbo2Gm1| zDujvim;57;peOd?kK3Z`@)3)2s=c5vjp(FHBq{*9NIn3H8{;byJT#KIo{wY(z{lG~$4|Cj?2F$7r91sK=A$Eg@w*E)GT%{ai;AJlSj4#Q0dYTn|O z^gnz{G^eliSx=PWYCtPnA{X8&9r^Tgh@d@QKs}<%Y@LbZq%Ng>D;i_JQ|$U*O2A-UdRRGq?GZw8U^DAAGn~s^B4ja9Qlj)6VEv{G<~*c z1~nRi4bG5il4>=a4IR7k!JG?IgBa}tc$Jw5jsXCnT7*Xh(uwwYmlgFhH$tOr7wRbn z;3<5+mP(;BIq4Y+3EX3MWD=EAsrtfW0Ly<{Tbb2Z;O92PX^Ta29Y#!Copjb98UXT1 zf$aiD?2Csj?RaY0p^X-HhDua6H>?!Z8=51i0bF|ol)Gyng?}O>QBVqg#0)?aX?{ow z{?&net6FOr6DG-U1&(fktL1c9Gn(1u6;I}5ir|VB!HSb*_c_dIWPalLT3&OykS0?+ z%b{C}odAPb+LF14Xx93BKKwu^3~XY8y73oM2|#*iB^@c_3VZLh1+u|)=L8tms9D<+ zT84(~sz33xv`hfh!Xl4H=pkYW^#Q9h_qc}oVCrp9>1!&RTsVZDW&m7Y&Ve_bg#BBRW<^s z^23+o0ieu4oQTNqw+&!z;Nx+G<7q&kDR&Sx6^)MpZ7;ZO`I-4>Y1YJR5)tND$P)7lGBw^a2oU7!PF(2ohmVIH-2TWzXNY z`9YQpNp)f31d8F6^Z@~x6T|T5d8n>ow1ne;rnIq|m9%QoEckgkTNDEzrJ(g0Kn;%( z*aE}|NqPQ=2|f5RdV0VzBz0&vTvaWZNsz_BUIl>$1cVb4)GUIrW8plsL)sp0f;YJA z9LmZpG$24|JlJ|&@bvbfx6hCpOSH#2nGg_9=~@|N(S;6+3P;YRxVVEp@``h;&R`xt z-f&##(4>{_L+uXbio431JagI<43D95y z-qf_`Ww~L87A6|x`-9Lci+>e_@MR_m(gBvAs&WzV8$)@?`gY6=Et?wBNgBv5AaFGcP%q+HF=MzK4QQR_(VN0RF@EaQR6(YF6H514P{Qx zecHnyfo(HCUJDq^A2gOi>HXeX#su4IoB?wetgmrQo&q zM@@jkkAq-&O2&&ggUtycbByu|GSF@c%mN_k##4K@ifv`wdLvn0Y1y%uhp)zk-v>eA z8({7)z;z4qrJO1CNl^e2c&3n+42*FEytSR%f@}qEPEZF#An}~rl%gA}EaD!Z0;V+yjW>_((bkSPD!kQYr9z%UV!oL5Z zEO^^lM!`#;!fhI3@@z&^Wjn!)=EG{5Jkr8#e<%}H@ODU-7j=XC0B|+>!R7KXjEn;O zC=tBAqkT@pBKbj$7wG98C3&n~E{t)>{6~ds1l&ziNyGVS!voMc+N8q0x?)*qp|hyb z9)3z7kDF4&hl3ZiAhM4ZCYU?QX~S)amozB|l@Z=Q!@}n%pa~$c;)>YlI_oi*xAr4m z{F_Eh8l0suMb#u(fM968b@Zca)` z4+BU%yyZ%p9-`CdR;xwKf1(Gp+i?ac@G>?=YIJ4Q_KFCoT28y|u+F@HYFYHYMufqq{ zYD2paf|wiECc%FTo;>LY(%wTuYO1euKJ2B&N!GgjDbcgP3;GAn#nQnhPg z5$7SXEjWwbq06-(CWJ+oUhlbnI}DGQ(bGL%)3{Trl45dWU8CfFZL%T*3Ww?UXtxL1 z)+&_Cv(z?lM-bQh%O+BD3?m+%AXsHQx)@OJeQm)MM~AjQlqp1Z{!k`}+!nbhW$q&t zZkCz)<+H}(E$-gz{_PaZE%*P_@yS}uE_P<^*w{6%MtF`L7@b}?66c7rg|SmF>1v+_ zqui!M;O7qY+EhT5U>JTp%FFe#C*@%9Qa?-xUuc7C9`SI=`l2fpRkgU@Y)W`CISn4C z4z?#YTWt%5Y#W>4U;?I3LV)`?0<@mfohb@TX3_ur=e_SJ>D&(oDc+p(yqppD!ei+P zi*U)iFlNjXPFh764v8e5w{(WfxCdgd>-va3RmUPI^~eDEzVpvcHcklH(BO)>kn&;+ zcB`eM;M51&DXZX97;!PBS$L@1$l4=yx!Xpb1i)totb-#?QCYMGBCKvc8gWg%uPNx8 z+JVd<6%TNStJ*8s#`Vp@+_KE6dhV`t-l*TyaN#OH&u7WmT_U}_A=dF)eiJFhk~23a zCrQ$x%o`_ebDvv&zPx)dc{CfY1oVAq2M?O^F23x{6}!qu1u#sA{WN&gxU%sx^r4nG zS^Cnq1|~wu=cXcg<=ig|=_vT7wCeGB1E3XfEpZ1Sg@xblnC2+Rkg!FhE4r7cK@x3F z0fY$S-nnB1>N;)q91LwbdtL}OFBtF?p}N+}LDxBEsc+_pVWYF{yeAl$E+((g7>M!& z*iZp$5f3_>VIH^Pt|5ymw_$o5r!A?omxKD<8YNeAX-Q8GFU$#U3UU#e)3Js`sdL(2 zD%5e%?w2NvO$!IC>qiNtEx#Rq{@*wrW2-nNVUJ%Zj5fhk_dW*ejn7Ab6RzxpM=`H+>NzENle zSs8%lKjr!62H5APE(2wK{fC;qS#GSM|0LZrOR%GEDg2cg-8H)3!Ci#P?oyACJ9E%Ws59Hr*I$Tu>U% zID2T@&Zha};I*=r88%?(#^Q%&SO9KeaOI|5!77K(dv@X(nSZ_Q{>lmtc}nzysOr(V zx%bG|bMqp$pI-Sd^}L9bn8X;^uB#a$xp4F2qTsT89vE@v5;_|suJoK+^V$YfXdk%q zU|AHhFH^_#bKoIdXE9vxPHhb+5)tWj979+azs+y8r- z013bZU}Cgjb0(rt&8ysIb2bfbZhODsO|3HaBg-j1Hgs@#C5(e`Gp>E}e5B@qH~{9Y zaQtQPJh9k!P?QfMSIeTpDj`q{FGPXVm~Z&)?RmkCARH*>xt%c$c80+z{qS2uFmYOR zvJDb*Xm+-ReHPi3SOM&8A%0t!#i?%s;VkUBcxNmE!Xm?I2NIH1C(v{_4+FZ3e9Kzn zV!f%;bq{7&m9B*Uz)twk>Umk2GWeQvF89r@8U-A=;BaY)U+eX^%)j64iS5_Zq)rfF z*32$-Xzqyj?58E9)zzO8_@5g3NFD~PSaLzVP<^a-P8!?u)fslE+c&%qJB59D*>qF$ z;deYEQ;h*r!$2mCHXv*dpz}qT3V`4l)jeUybBv^H z<_|Zc{DZ~7l%(&I9)X|k`~hkL(#te>8gpG+51{N!d4EQmAuPq3S168gJhzi%3L(Um znTjOYOq7z-VJA{*I|Jl!m$$#%Vg_VNh|VY4E%&8mD|0nDM%b_PavakypIy`J&x9k5 z*ee{z>kjvD1Qk6aY$4Khd36Iv3vPUt_~E)zBDP4@LQ{~>Vcq1G6o@`zZY#^!0*$3H zJ&7eMx*P7ykTfL(e31{O68ELF~PKcQ&CM^VLQkna?L}Cv*i!A6*Mmp zGVWf%khDh1M|^P!=oUAHe14x=3|cr>P00DqIo+_DQi4|!=VQo7s@k-umeMoithyz^IO1omabHo~VC>6Mvzh}=u(8KHHs#yRqES1ChD zcODJmqE3psbPhvkC}S(nRZ3OP{w83^=7Fj~$%GycYI)IzB|VeR#gaO-<&AwH0pY|P zlQja9hvjWw2$8i|_CkuZq+};bI!lpkm-|_-QR=jaycHdgHrFf4)q47+#Y9LV2!LcQ z*T~rjOY%sb^nI;O79~pAnxXiSkq6RzicK|eX&l2a3+7B<=I9VGy;Z5dNr72>IvkS;WSF?`eYii! zck~NxfHVAy2CAbBSk9DMYHEFLl+vg&N}%>;!g{oO-(T!^^7YMfQ#_K%F@lYRao~e$ zGFrzimrc;VrJ87Nu6<-nz_ZVS>3d zGRuLCNv-Jnu~~VTS^mwF{bAx-fM*IywJb)uI2-_B7&_I11y@I0Oe>-AJ ze2mh!);@2423F86-@kF)uLGE!JKOWOz9J?hWxJ~X+-KyyF>{%{SIR-X5d*yE-+cKf zU}k8<9b?XZ|Nlz16(`gu9BQfDCv^{P-;`us|-Kmru&HPpPP(~-G^TF+n} zZrrpYYFF^_p$jiBl;Q7WlzddJohUTc3Vg6@8cNg^Vw?U$78=B=`lPtI5^5te^c_QC z3X4RPNrW`_A&}4C%V#X+t75Hf$fD#}!!F~iB8#mt3F$9jyD~)KMrRuyDIP`l9K;%F zQozixV;)?W_Kakka=k67HPmxKEXB6m8Or`rrg5@^52lZiRv_N}Co_cpS0Wqqmt4Vh$PK?;el z?q3X)a`F+rAVI6v16z0ce3BC2-|1_)rKl(({Vqm-c=@{H?2VtEJNeX_bE4Qe_*+8- zprg%Ll#1l`s;69Uhs&$`S#Wd5>=aS|6!JOT8L|4njh05?d8^t7jW-!Z{%eMiKpBr? z@*u1eO~*+_^#|yjFKHa%=Gnn=q$J@|e|XLwIox2I(JZSv)gz zC}fay6taSRmIe9Ng)j6`N>H)qwIkbYQ*@8nElScH zKi;t)87pxgsTGw|vQ$~`E39g}CH&-*dD8kQ1=-%9@TZKc*t)ILugON~ z5-P<1$u4Byfhxz0_E~V^f9Z(S>O@hknuDEBvBIv%2jV1RKKt?sa2Td82PN%Kz!T!0 zeSddWcT~gg`+oT;)}7cSUDl?crjIiyAyEI^&`J~m<96&!Y0FJ^4)LsvxtE-0i^2z7 z)sO1TewT}D%h zpOTO46aJdH_UV;eurHX0*oo$OoN?<{g>wnF?#14fmX9Rzd%i2EZy!)Gi_GzA@@0K4 zbm!>m{VXZf_k16Pp2;jJvc*#%c_yB|3EmElv%}w63yj5F^cbL5PEik(KsmjH~=Uq#`8 z^WwWV#}MA}nQ}|15z+fqVu>nVUvZBW9OhpXRLaHdtU?YSoLg$94lG7)QsKLs(|LzZ z!xvL8bUw^JKGr0tcR3Q5$jM&^9{MTCygnCj zKY#P`+2hQl`cp?b2@Y+SdNEWYOdjWBh>7B5%Vtj#BoKd&KKR;v0OafsA1uA;enr~y z0(e@=W8d=&7_vDtiJHt&goyjg?zMluD>=(6i^E>$1rMyme|S_&p$uVBc;*hC$=U;r(I;gd#pd+x-R%7# z+Vj(@=exxzYs2oDc}TI5B(2rQnc35K^W^P`EEd<^Wo}Ttkt~Etd0u$ukQdc>M{Ei< zoV#K;_sCH4i;cP)tCoaat9glu_l z$M_28>hWKNYY8z(X(ly#>(6!37Eb%O*$!OE?tfZ!MfHT@#b5*=E7GiP{`n;yF#iiX z_ben;Myi^~s*b+p$2U^5s5o;YZ{fnti~SZA#WG?ww*fq$u?HS|!OgkFuZ9A|QN-dV zMLnK^9>cpO^FU+M3%=UZ76vtCTBm>YDLjkFm5l(!%}LUYq_9w#kD15d6tYZ?(wasQ z6?^*BaC62s&ST}JB0B|vgUZcQW@v)L#pGbSl$#6+8s9SP57OBCoWss|nqAn>nd`D8~PKuYE}VvMV|YasJf5SWyFRVyYzC-MPgI0`(5?NTG!+{9jc z&I@|CK~vp*-yp2Axv|4Rf{=r-HQY$j=0r}tQ#=nwI`#$?ZSygQlZ^#z$0KEE-oR%>;h_F}w)b$SOgf%eXPIM8$X>PRvlU5z*!W=Q$_R0}RNHg_Mt9 zSLP!EbThTBXY|MB!ds94|3t;((?_Km09Q66!!dy}Bh@Z7865FH)e}u70K3iWMynEa zW@bn;nFo-LohlEOBeR*1ZNkhXw>gd)Lj0~EhH0;%NY)ddB*%~vZGi7Idqq5&n+81m zlegtcy5vY-$E5Hx0dyUGsTMfZoD215wyA1b{hi?IM0a6H`QIlH(y;THEqwq%KUN- z36NM1skbd6J%)s5C#~s|)LlJp;-EZNkbme933)XaqYfv~`RHdhR&H=INu;u=LtF9l zNxBpYRu)H-QBm%-V1 zW=E_Tz9s-bT#RdPWN09|ku*ZL+Y)Kvj2O3^d?QC7KldU%>=vO;PRu(IRSBfa>vPr% zTKz&b`WQGUFe-#1d1}w8Wdb*Y0KZ?5a^|e&kd&l`i&oa;_lXfMWyweXN@KU6vq>V@Nb96Gr|PvQ}1qEDPf3xQTby_#6OIO{c z3X1+mQlvBP$r?ZWGCO@(?;HR3*57A}rA;0AL+!8rgB~NEHA|0FtC2SXX zH3Ny$WJEk!I$};EkM!4iSqHm<3W9Oyy>}Dkv4WOSgfDvJi+Sdi-O>;L$Qc3@vVw zVwzuP1g|FM;{}jc7i}J|bu-Q5b`BrV=tj7ooOy%+7);+z5Ib@A9_-?uw12Pe2;!YOz2&72RxT#X}UiKGCVH{2Wp=257F^3N`Ty}luT3;ZatS#h> z7~uoBAD#0xpI*-llEO}AwHz-Q#T5AeTkFr8}$BdRbmoXTrUY!q8yr?wJ~#?iq3z=+AA zq0qk7)&Kr=y^0BmExKrHw5fid3<^}qJ+s4>?;QVXC!Kye>4xyhr}+5W08+~+?jSBp z-W*z6WPeA>@82u}f+F8tj$Fjajl&WlNh;!^ zun~E$imV(&WVa>p5bYlIk}$61UBZWy7Bc@<)^&YBrKC@f_p^`w6|S2UaXJ?z8w5%X z75QBZ&Dv=Ue)>G%2}9b}Nxtj^uNEY#=NvvWU!4MKdXJRMpPnksypRv^2{|@((;oki zxi=4o`fdOJU$d{qjBUm~7_v9XmZ%w9c9JAXLkJ-uB-Lz&Y}t~K#u}2eSW;k-a_KbPS>sjYg-#AyL__phZ)izjyGc= zb^wkF`jlB2biw26mMaS6kI2@Dz39d5cMm1mhtTc7To~T!=R|ApkprdkFe0SJJ{plvcRv~y`?-^n)$@HN z`@I!1V`u5U+qN@B3&%d~<%NM`^;dd7RyrNIb$3U{p@G#Y*$pkUyw(9AeraO-B66fO zZpW{?VUPc+b&@O$_?Dl{62xI9?xF@ysxF<4wd(I~ss3QN7LtbYFxa$yQ0nYAg_c~B z-p{M0F~fEVX-ZWcPm5PwJ}@8qDQ%%KTVlh<8%1O0Z7}M=E^LG+<+OIYBVtgWUBABBf(eV;G;eH(ski z2ouly0Aj3-NbwUwjXvjL_EkTD!q8-K$_NDB`7~PKVpxee__mHPSx4WjrQX z9nuNXp$aYW?~lSEQPGX1R$@D2_*Sy`_yg_sATK<~`%88(DSyM6Bc9%>lqRqJcB@%1 zjIY8)8pJD+2PNLNf1O5$NeAHRYco#TSruTF3cR@gScB;HUSb0cW*I!jgNEe|6R~FL z_)ghi=PVcuA536LqZ>AGYXd5tOojNiEQkXWsEv`STnSYg`92G!-xJaLuFVaGA6F&#A@#`x z=LsdMDgv}|a5j&)W>U>y6UPf_bg<;x$qAxLU1Z~()!9)i!nVY?Xi0l0ez{xajq$bW zioSFC-Q*REk9c&?aFdL|RmY|^wWqmaX#@M)Ca-i!q2T$08TMy! zX&-mO<*>)HI5>I1uqECzdlGy=-oYgPj%omzhdO(U8rcr&CvyoQw-}mb;p9?FqUZET zH9b$J!aZ9RSyiP{6O8PDot7;TMNs3g-K7{Mq~Ms308nvaK(tia<&*?a5Qz*zVSrq3 zC~58KO(58E4#=*>!^rU}ND$c`;bC*LAOr*twxbjC$xI1zxUCI{1L`=#ovEu(U%$cY zOa&wt&8GpUQC3nL`TX^fGeFDtQgMesgq$pVokukoWy~OwsC>+GdI!EEiz)G#k-EE@ z4(+4XUa96ow`z7Ys!}(=HqH5db;y8Ql6k5r?SN%4O>D6YmLU?omJVQc9Jq{EX9c>F zEd%}80M0`Ns*VRVzeZcG8E!bKgS4WsvPAJ3Sodww5)#Seh^`o;o<3wFD{=sG9vMP3 zwUiwS&fR#J4^`*W&|p3{E_)jY#Rnx8245^7v(ReGEEQ$JfT%bBibJUAXx+62uKbu^ zYTl1@sj?LC22EP(=?4RQ9?n5DoJ!9PSwA3pN`N)81gV?lrjOr~mAqpvfV&ErM;HPs zqJj*uBxw*`EO|dD8wdG}D{W(AGoDsGyHiUyX^Vd3V_=X|B- zyx>MOevz)a=pcie<=XHm>PC__ER_n@ioJw7Zm?exfXVh2tH8HxPL&J`0332~SBq4Xi(u1uqN?Cx48vwN+=hs$8f_;)y zu3vdLz`)chQM>?%76XifGIg|uXVeew4TR8^-3!S=5Ev=orI#_4C`d6njT!fBxd@G_ z(U80@5n&@p%9*1h;qf%YpbkZz!VqO5?J|5kM~1JCAhp!tJ7^$jO;F-gG)u-^z*5&O z1)0yyZQB&xUZY}1tGJ_q#XV&{uFnT;J4oO}sYw=PF~J)fUi#&x^4i?_AY97fMdUF+ zibCcZ;|s483i~uymrq|{t+B|;9_vVCuXbEYC8K9K07fkZLr=_qb}OQ^PQc(sb^uZ{ z{;9Ivm-26w22QJ+bB_fII~`Z)>qh1vi$|cMBh-<58DOptx}77J!h}f$%ye{3BhZYA ztUJ;AFY|#!5HbR5vdd&B5Es{dO-uJ;f|x6$&OnOjUUiY zP%G|nf1|z%Y#!6M<2585=WO&6Ld>XpClmL!`$LMxhT%<&k#ijCjHBuK!-LVQaOJF$ zdNCxQ)t-{Ss1YU(-oq5!ynB4T?^kEK72eeoJluh8Ioh|U;hZ~zTCWj5skh|c)MB&@ zdhHX~Ien@3z#3N#yzU$mrn{rFct-#j`ALTw%BJ1h-DT0(;0O(*G2z9pW#2R;XVTp| zd-t?0!H)z9Uq-m~_-|Q>Y*u(sB>NeNGz-r ztH`1+dUr1sz4n>i{q*}h*X7gs1214>=K=5yKzo3t_}1^@x6x;fE9T6OlWWKFc8Pzy zYiFUY5?#>xR#s?>pM%=&PsP zoH)Db)zSU~zo;c^tJ7A>k}?hL2oP|FsJ#a!&LCbDc55_6ZpUsKnNIj7Vh&y zrf{UX!uWJlpAgyCMXZCn7=nJykmbh6em%ChaWV$X!%5hRcL|Bdvl;WlgzpTomqPsL zHbP$)VU~>FqJn?NC;TEy43ddC4B{+b9PZ~w^OJFzl z_T(C-WKuk#{q4Mu)0|(6MKa^_JD_6{hjs%rQb0R965CF4tzYE2J% zM+DOMXoTP?_IA*S;;U6fTXKTD^7mcD8??8e9EwAkvcA7MSP2==9IHs;#7_}Z%T(RV z9!~h*x>2V8u1pPGMwU@snwg^3myy3rQGZR56P}M7sZx#A250;vp=A>{RsMSN!l>=l z%j2q=A19xDD^+SM9?U3LK2f9%E;5A|nboVAq2)KXm2Z|QQc4xH?4

()HNoR2O-3 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 qScF3KdXgYR?6#&_!r&2VJQN&m}~JRR$-CnCGX% zzoi=Ei1r*j>LXC+NMg__r}=Jd&fht;LjSpGC3(T{uyP++ow;U%LFF6j_iC$ZHlMJsXp+?_;6W&pXPmkx@f6>5%_@4%<04OS7Gw zqdT3CCZ=7&F-6k3K5g^eRIG}Znep*DRpW#wy&m=r2&3+5S#pJxd_){3VgxUDK#cYk zau62O*BYtoe`DpD^qmcpPO>#)#yjIhTYGG$VE$I52hqG$WnoxXk2J863hLIr4w&43lm%o1SHm@jrj1eXm^TTH#Em-^X`3`y3C9x;M&uD|-) zoQ!bCa9kbRSUPH88cqy6PXT75C&a~9HkVMhE^v`WU0%WOCD8xH1=6>9w ztXC{5W|{LTLmrTG1~;#lN8v55wU+&J^rqs^GxE1@8fmI5ft-wyrxtjmu^Ieg-BjG$ zb^C*|}zr+s@nwz*Bz7LKfe}jjP z0=|duQ)dF^-bgO#f}krWl=wvCXttwS8wRs+a%Q9MjwuWy!K&I=L&coKwP27DQz z9(^FX*=u`7sBt6Qcps_V4`BNaI#S@L9=89qL4G+-N>q5F##@mM{LVpoPP+xK*kz|{ zsTLp=0glT!DBB+E$mi6djFm;83@b}=6x48#KAz-;y^;NuPz?TnuE=JrNJDr$+x`*c zz6@B~b6ne$J&16zfrbSmf9f67KjZn(W{)S48;s|wj}QseeQKd9Pte((Sd0kY-hc!L-iw&Jse9&tfCqjFC$`Yu)Vz zYO(@N;H<`*s*dPVomkg#WspjQ7w@klmUkRT6asDU)10aTM;j69cw}6yMk1fyWEj3e z3lDDFxO-B;gHn#0lMmtV$WVg!)wuQcBgYe6x2IDubvpLb$O$A6#db7)UG|H%w=*L_ zr$8S^0xBZ5l)7f!8V4i0^ebJp2hcfABQ{VAUW!=ZMD%o+2XNFZo%B$n%ZNYWND_*T zp&r(yAcB}KJ&O*d39u0rS!!bty<9=8gOKO&GF0$wKdj^#WXddYpYc3gxn(Q5(0PHN zxR&zW3&eLJl*jcn`b!rGfR{(=i%=rPlh;G@-8hZJ58&mf9)~QUlY7%lb~t@qBUC4* zX**PGT&T_(_P+COUAe7YDK`#HAJ}V0M1Xy;Z5twZn)zKBQQr@S+9Ps`b9`Gj+s9VC zI!>JLI=*-BUd~(UdYlG+x?U7tP0bvOM=6Frb?=7-{?qgwvyKLaG?%(nxQ7qf5FwNyKht#M^`6W zcvkNw047xUS8L_dFrysch(3iW>0BPHX#$AISB*Lvg~7ktcl_H|`^S;W%E~veS zc`6&kk2*KiDg-lX7=`tJ_qtUK?Db_gdzloZK~(d3SLbE$7flP`M$do(|q`FGLoqlej=6Lq$Yx*M6B0H zVA?PdHvpw6pZz*RT=Y1hp>Kq|!c;RM>(wjl?^7vO)4E^mxaY%GtYF=F1%zV+xqXqW z*r!{6sj2G%yV3Z4#jh2$Bjr0HvoQPPg9oxSsac9^0uP{N$g#z)O@)4rB+Cah<&Vna z3B7M<()bONA9D1cc3f;%cVUN``S8Ndb)Xp;ud5@*a&~8ZL)r;zjl@7^4Y2cd=0(-w z(3Wa_KEr?opbl`}8o@^V)<6W$Fk6U`BL1mT@HA-NpYCXTMIojGzr7B0

Q}iH8UA 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

MF;!i=lVd`#(4-yTwqupnG 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�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 Z>F5rDfaP?m-SWZe_ND8yE90vjNS zbizewmpd)5^!5YtJ~SVB$$n{m6TpOD`UdNkkVHTo-JFF{A)XBs-XoyL_Q;c64n&o( zgy_bs4{B@>&P@ejYo!U9O^AQMOT?wW*VYpNDTBC|Fl!T)7&-F7`(rWwEHJ|!LDQV= z0n@|?7cAqG8p|vMP?)pn=!kGHSxP@INl5rNx@3tvG918d(DcirumTg=NeL&Ii6>8` zq$a0lYvhvhnY4UbF1M|&GttyTA5bTwRB}!g3X?Yz#f0(lI92n)v+;pQMQ4yPSwq*6 zA_6kYPB7QOBQ+2Xbb-wsr3oaUPP82Zx_vTpimUx-n2mq@gq9V^xy;g~+e=Vq)?Ph) z_~xA?!YO`%#-{BymXo#wIG{KS1XT1*Ld?@TC@)Az39?qzfZfEal9HSn*5fH>2a53z zC-?bZl}m6=3d*4N3L=FJ52##ZKrD%A1WyPho3G4H?sPs4@b2ZM>0u{U9{QjmK37Ez z0v-Eds{Fpi`>|#evrCda`3AI}hxA@^Z`rddHD#a_W}~HU{I&wt!}6FmgY`giWvGvJ zDuEno25qYR%@dD-6aXcF@b`I3U?&2aDNJsbFe|^LD7&!abZ%LB zdFjcjirl)oqO(=!8}ncUdsvw%DLqtg9Oh~f_>9AR=WnCC#FO1|eV41=J zD_|^xtuatn4%63BHVoqyoe3QP%j~F{7^Ww^z+y$hUFQgz>Hw5!HY(v{FZ&eT#E zsR0D9jhl#=X;|+H61K9v)h7wMV@BHSDUFd_>@L!=z|vkkyql?N`L3^e>*p`kvVg$r z>U|zsa^k>r5?M3X47sZJZg^?|$c#qPP4dka!H|QRHqIbTS#QfUV!QB(>9}5N*GDHU z2G*PZO~W!lsH+$tw4;hZn_VW-Z1}MrIoxZ4sSGghR*k5Ic43OBw8VMZQ2>ae^(W*V2OO!#mX_g19) zV(q%8#=uCruC2JP6^EFXp+&b>%OS->Ap)wx7is45^mQEm_*%{D9!dVHCsG9b76tD| zMZ}x(zj`P9NQE5$c>r>N#&2twput_k#I%!4%?!=-%u~7XnFZW6EIg51TvB?vf?I`| zQdW1muD(Sy|Md6onu)^ECgG360qFFD=dQ$r-ISf(fF;%ZDcSnQChR-aAhJ^6iEqm?DMnG z739}gBQqf>Oo+;?+cJULk0v_JmhB@zN3$bHAZnE3o643vO?6@A0>YjxP*d!Sn}l#1 zdux<2Avu7^%M_3=6WGR?RB}? Date: Fri, 6 Jan 2023 10:40:31 +0000 Subject: [PATCH 150/310] Improve text-align example. Replace statics with labels; change to a 2 x 2 grid layout to make it easier to see the difference between 'center' and 'justify'; increase readability by setting 'color: auto' in the labels. --- docs/examples/styles/text_align.css | 27 ++++++++++++++++----------- docs/examples/styles/text_align.py | 26 ++++++++++---------------- docs/styles/text_align.md | 2 +- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/docs/examples/styles/text_align.css b/docs/examples/styles/text_align.css index c594254d6..32714ba23 100644 --- a/docs/examples/styles/text_align.css +++ b/docs/examples/styles/text_align.css @@ -1,24 +1,29 @@ #one { - text-align: left; - background: lightblue; - + text-align: left; + background: lightblue; } #two { - text-align: center; - background: indianred; + text-align: center; + background: indianred; } #three { - text-align: right; - background: palegreen; + text-align: right; + background: palegreen; } #four { - text-align: justify; - background: palevioletred; + text-align: justify; + background: palevioletred; } -Static { - padding: 1; +Label { + padding: 1 2; + height: 100%; + color: auto; +} + +Grid { + grid-size: 2 2; } diff --git a/docs/examples/styles/text_align.py b/docs/examples/styles/text_align.py index 27e2892fa..0c72a17f3 100644 --- a/docs/examples/styles/text_align.py +++ b/docs/examples/styles/text_align.py @@ -1,7 +1,6 @@ -from __future__ import annotations - -from textual.app import App, ComposeResult -from textual.widgets import Static +from textual.app import App +from textual.containers import Grid +from textual.widgets import Label TEXT = ( "I must not fear. Fear is the mind-killer. Fear is the little-death that " @@ -11,18 +10,13 @@ TEXT = ( class TextAlign(App): - def compose(self) -> ComposeResult: - left = Static("[b]Left aligned[/]\n" + TEXT, id="one") - yield left - - right = Static("[b]Center aligned[/]\n" + TEXT, id="two") - yield right - - center = Static("[b]Right aligned[/]\n" + TEXT, id="three") - yield center - - full = Static("[b]Justified[/]\n" + TEXT, id="four") - yield full + def compose(self): + yield Grid( + Label("[b]Left aligned[/]\n" + TEXT, id="one"), + Label("[b]Center aligned[/]\n" + TEXT, id="two"), + Label("[b]Right aligned[/]\n" + TEXT, id="three"), + Label("[b]Justified[/]\n" + TEXT, id="four"), + ) app = TextAlign(css_path="text_align.css") diff --git a/docs/styles/text_align.md b/docs/styles/text_align.md index cc72ac2d1..dc55dc03e 100644 --- a/docs/styles/text_align.md +++ b/docs/styles/text_align.md @@ -35,7 +35,7 @@ This example shows, from top to bottom: `left`, `center`, `right`, and `justify` === "text_align.css" - ```css + ```css hl_lines="2 7 12 17" --8<-- "docs/examples/styles/text_align.css" ``` From 2dda2866286a32bd6b7febeefd6df56bf224b2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 10:42:18 +0000 Subject: [PATCH 151/310] Fix alphabetical order of styles. --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 6dd34196c..fffeef3c0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -119,8 +119,8 @@ nav: - "styles/scrollbar_gutter.md" - "styles/scrollbar_size.md" - "styles/text_align.md" - - "styles/text_style.md" - "styles/text_opacity.md" + - "styles/text_style.md" - "styles/tint.md" - "styles/visibility.md" - "styles/width.md" From a25ba1bea47326265fcb200f6a5ed1cd7811c2de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 10:47:31 +0000 Subject: [PATCH 152/310] Update *opacity references. --- docs/styles/opacity.md | 3 ++- docs/styles/text_opacity.md | 40 ++++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/docs/styles/opacity.md b/docs/styles/opacity.md index 571b74daf..4844f9342 100644 --- a/docs/styles/opacity.md +++ b/docs/styles/opacity.md @@ -8,9 +8,10 @@ The `opacity` property sets the opacity/transparency of a widget. opacity: <number> | <percentage>; --8<-- "docs/snippets/syntax_block_end.md" -The opacity of a widget can be set as a [``](../css_types/number.md) between `0` and `1` or a [``](../css_types/percentage.md) between `0%` and `100%`. +The opacity of a widget can be set as a [``](../css_types/number.md) or a [``](../css_types/percentage.md). `0`/`0%` means no opacity, which is equivalent to full transparency. Conversely, `1`/`100%` means full opacity, which is equivalent to no transparency. +Values outside of these ranges will be clamped. ### Values diff --git a/docs/styles/text_opacity.md b/docs/styles/text_opacity.md index 5a0e1c6c5..b7b8f63ff 100644 --- a/docs/styles/text_opacity.md +++ b/docs/styles/text_opacity.md @@ -4,20 +4,35 @@ The `text-opacity` blends the color of the content of a widget with the color of ## Syntax -``` -text-opacity: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +text-opacity: <number> | <percentage>; +--8<-- "docs/snippets/syntax_block_end.md" + +The text opacity can be set as a [``](../css_types/number.md) or a [``](../css_types/percentage.md). +`0`/`0%` means no opacity, which is equivalent to full transparency. +Conversely, `1`/`100%` means full opacity, which is equivalent to no transparency. +Values outside of these ranges will be clamped. ### Values -As a fractional property, `text-opacity` can be set to either a float (between 0 and 1), -or a percentage, e.g. `45%`. -Float values will be clamped between 0 and 1. -Percentage values will be clamped between 0% and 100%. +### <number> + +--8<-- "docs/snippets/type_syntax/number.md" +The value of [``](../../css_types/number) is clamped between `0` and `1`. + +### <percentage> + +--8<-- "docs/snippets/type_syntax/percentage.md" +The value of [``](../../css_types/percentage) is clamped between `0%` and `100%`. ## Example -This example shows, from top to bottom, increasing text-opacity values. +This example shows, from top to bottom, increasing `text-opacity` values. + +=== "Output" + + ```{.textual path="docs/examples/styles/text_opacity.py"} + ``` === "text_opacity.py" @@ -31,18 +46,11 @@ This example shows, from top to bottom, increasing text-opacity values. --8<-- "docs/examples/styles/text_opacity.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/text_opacity.py"} - ``` - ## CSS ```sass /* Set the text to be "half-faded" against the background of the widget */ -Widget { - text-opacity: 50%; -} +text-opacity: 50%; ``` ## Python From c7c352a38a3fa95c74bd6a0d002703cb013c8810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 10:49:25 +0000 Subject: [PATCH 153/310] Replace statics with labels. [skip ci] --- docs/examples/styles/text_opacity.css | 3 ++- docs/examples/styles/text_opacity.py | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/examples/styles/text_opacity.css b/docs/examples/styles/text_opacity.css index 882cc8acb..56ae0e576 100644 --- a/docs/examples/styles/text_opacity.css +++ b/docs/examples/styles/text_opacity.css @@ -18,8 +18,9 @@ text-opacity: 100%; } -Static { +Label { height: 1fr; + width: 100%; text-align: center; text-style: bold; } diff --git a/docs/examples/styles/text_opacity.py b/docs/examples/styles/text_opacity.py index a2e9dcff2..351093e67 100644 --- a/docs/examples/styles/text_opacity.py +++ b/docs/examples/styles/text_opacity.py @@ -1,14 +1,14 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label class TextOpacityApp(App): def compose(self): - yield Static("text-opacity: 0%", id="zero-opacity") - yield Static("text-opacity: 25%", id="quarter-opacity") - yield Static("text-opacity: 50%", id="half-opacity") - yield Static("text-opacity: 75%", id="three-quarter-opacity") - yield Static("text-opacity: 100%", id="full-opacity") + yield Label("text-opacity: 0%", id="zero-opacity") + yield Label("text-opacity: 25%", id="quarter-opacity") + yield Label("text-opacity: 50%", id="half-opacity") + yield Label("text-opacity: 75%", id="three-quarter-opacity") + yield Label("text-opacity: 100%", id="full-opacity") app = TextOpacityApp(css_path="text_opacity.css") From 0abeba620ef6e583ed956a9d935be079e4299928 Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Fri, 6 Jan 2023 11:14:15 +0000 Subject: [PATCH 154/310] Method for converting Strip index to cell position --- src/textual/strip.py | 35 +++++++++++++++++++++++++++++++++++ tests/test_strip.py | 29 +++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/textual/strip.py b/src/textual/strip.py index 7a83d5e40..be9dc80b0 100644 --- a/src/textual/strip.py +++ b/src/textual/strip.py @@ -68,6 +68,41 @@ class Strip: """ return [cls(segments, cell_length) for segments in lines] + def index_to_cell_position(self, index: int) -> int: + """Given a character index, return the cell position of that character. + This is the sum of the cell lengths of all the characters *before* the character + at `index`. + + Args: + index (int): The index to convert. + + Returns: + int: The cell position of the character at `index`. + """ + if index == 0: + return 0 + + cell_position_end = 0 + segment_length = 0 + segment_end_index = 0 + segment_cell_length = 0 + text = "" + iter_segments = iter(self) + while segment_end_index < index: + segment = next(iter_segments) + text = segment.text + segment_length = len(text) + segment_cell_length = cell_len(text) + cell_position_end += segment_cell_length + segment_end_index += segment_length + + # Check how far into this segment the target index is + segment_index_start = segment_end_index - segment_length + index_within_segment = index - segment_index_start + segment_cell_start = cell_position_end - segment_cell_length + + return segment_cell_start + cell_len(text[:index_within_segment]) + @property def cell_length(self) -> int: """Get the number of cells required to render this object.""" diff --git a/tests/test_strip.py b/tests/test_strip.py index 891af9845..15d527119 100644 --- a/tests/test_strip.py +++ b/tests/test_strip.py @@ -1,3 +1,4 @@ +import pytest from rich.segment import Segment from rich.style import Style @@ -62,9 +63,7 @@ def test_eq(): def test_adjust_cell_length(): - for repeat in range(3): - assert Strip([]).adjust_cell_length(3) == Strip([Segment(" ")]) assert Strip([Segment("f")]).adjust_cell_length(3) == Strip( [Segment("f"), Segment(" ")] @@ -119,9 +118,7 @@ def test_style_links(): def test_crop(): - for repeat in range(3): - assert Strip([Segment("foo")]).crop(0, 3) == Strip([Segment("foo")]) assert Strip([Segment("foo")]).crop(0, 2) == Strip([Segment("fo")]) assert Strip([Segment("foo")]).crop(0, 1) == Strip([Segment("f")]) @@ -136,10 +133,30 @@ def test_crop(): def test_divide(): - for repeat in range(3): - assert Strip([Segment("foo")]).divide([1, 2]) == [ Strip([Segment("f")]), Strip([Segment("o")]), ] + + +@pytest.mark.parametrize( + "index,cell_position", + [ + (0, 0), + (1, 1), + (2, 2), + (3, 3), + (4, 4), + (5, 6), + (6, 8), + (7, 10), + (8, 11), + (9, 12), + (10, 13), + (11, 14), + ], +) +def test_index_to_cell_position(index, cell_position): + strip = Strip([Segment("ab"), Segment("cd日本語ef"), Segment("gh")]) + assert cell_position == strip.index_to_cell_position(index) From 1bd720ef0dbf9de7b4a16138c03e998375eb5bfd Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Fri, 6 Jan 2023 13:55:48 +0000 Subject: [PATCH 155/310] Index to cell position --- poetry.lock | 303 +++++++++++++++++----------------- src/textual/_segment_tools.py | 41 +++++ src/textual/strip.py | 25 +-- tests/test_segment_tools.py | 12 +- tests/test_strip.py | 5 + 5 files changed, 202 insertions(+), 184 deletions(-) diff --git a/poetry.lock b/poetry.lock index 180acad62..34c7f058e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -182,7 +182,7 @@ test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] [[package]] name = "coverage" -version = "7.0.1" +version = "7.0.3" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -269,7 +269,7 @@ typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\"" [[package]] name = "griffe" -version = "0.25.2" +version = "0.25.3" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." category = "dev" optional = false @@ -313,7 +313,7 @@ socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "httpx" -version = "0.23.1" +version = "0.23.3" description = "The next generation HTTP client." category = "dev" optional = false @@ -333,7 +333,7 @@ socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "identify" -version = "2.5.11" +version = "2.5.12" description = "File identification library for Python" category = "dev" optional = false @@ -524,7 +524,7 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] [[package]] name = "mkdocstrings-python" -version = "0.8.2" +version = "0.8.3" description = "A Python handler for mkdocstrings." category = "dev" optional = false @@ -661,7 +661,7 @@ virtualenv = ">=20.10.0" [[package]] name = "pygments" -version = "2.13.0" +version = "2.14.0" description = "Pygments is a syntax highlighting package written in Python." category = "main" optional = false @@ -875,7 +875,7 @@ python-versions = ">=3.7" [[package]] name = "syrupy" -version = "3.0.5" +version = "3.0.6" description = "Pytest Snapshot Test Utility" category = "dev" optional = false @@ -887,7 +887,7 @@ pytest = ">=5.1.0,<8.0.0" [[package]] name = "time-machine" -version = "2.8.2" +version = "2.9.0" description = "Travel through time in your tests." category = "dev" optional = false @@ -969,7 +969,7 @@ testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7 [[package]] name = "watchdog" -version = "2.2.0" +version = "2.2.1" description = "Filesystem events monitoring" category = "dev" optional = false @@ -1178,57 +1178,57 @@ commonmark = [ {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, ] coverage = [ - {file = "coverage-7.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b3695c4f4750bca943b3e1f74ad4be8d29e4aeab927d50772c41359107bd5d5c"}, - {file = "coverage-7.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fa6a5a224b7f4cfb226f4fc55a57e8537fcc096f42219128c2c74c0e7d0953e1"}, - {file = "coverage-7.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74f70cd92669394eaf8d7756d1b195c8032cf7bbbdfce3bc489d4e15b3b8cf73"}, - {file = "coverage-7.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b66bb21a23680dee0be66557dc6b02a3152ddb55edf9f6723fa4a93368f7158d"}, - {file = "coverage-7.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d87717959d4d0ee9db08a0f1d80d21eb585aafe30f9b0a54ecf779a69cb015f6"}, - {file = "coverage-7.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:854f22fa361d1ff914c7efa347398374cc7d567bdafa48ac3aa22334650dfba2"}, - {file = "coverage-7.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1e414dc32ee5c3f36544ea466b6f52f28a7af788653744b8570d0bf12ff34bc0"}, - {file = "coverage-7.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6c5ad996c6fa4d8ed669cfa1e8551348729d008a2caf81489ab9ea67cfbc7498"}, - {file = "coverage-7.0.1-cp310-cp310-win32.whl", hash = "sha256:691571f31ace1837838b7e421d3a09a8c00b4aac32efacb4fc9bd0a5c647d25a"}, - {file = "coverage-7.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:89caf4425fe88889e2973a8e9a3f6f5f9bbe5dd411d7d521e86428c08a873a4a"}, - {file = "coverage-7.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:63d56165a7c76265468d7e0c5548215a5ba515fc2cba5232d17df97bffa10f6c"}, - {file = "coverage-7.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f943a3b2bc520102dd3e0bb465e1286e12c9a54f58accd71b9e65324d9c7c01"}, - {file = "coverage-7.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:830525361249dc4cd013652b0efad645a385707a5ae49350c894b67d23fbb07c"}, - {file = "coverage-7.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd1b9c5adc066db699ccf7fa839189a649afcdd9e02cb5dc9d24e67e7922737d"}, - {file = "coverage-7.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00c14720b8b3b6c23b487e70bd406abafc976ddc50490f645166f111c419c39"}, - {file = "coverage-7.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6d55d840e1b8c0002fce66443e124e8581f30f9ead2e54fbf6709fb593181f2c"}, - {file = "coverage-7.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:66b18c3cf8bbab0cce0d7b9e4262dc830e93588986865a8c78ab2ae324b3ed56"}, - {file = "coverage-7.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:12a5aa77783d49e05439fbe6e6b427484f8a0f9f456b46a51d8aac022cfd024d"}, - {file = "coverage-7.0.1-cp311-cp311-win32.whl", hash = "sha256:b77015d1cb8fe941be1222a5a8b4e3fbca88180cfa7e2d4a4e58aeabadef0ab7"}, - {file = "coverage-7.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb992c47cb1e5bd6a01e97182400bcc2ba2077080a17fcd7be23aaa6e572e390"}, - {file = "coverage-7.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e78e9dcbf4f3853d3ae18a8f9272111242531535ec9e1009fa8ec4a2b74557dc"}, - {file = "coverage-7.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e60bef2e2416f15fdc05772bf87db06c6a6f9870d1db08fdd019fbec98ae24a9"}, - {file = "coverage-7.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9823e4789ab70f3ec88724bba1a203f2856331986cd893dedbe3e23a6cfc1e4e"}, - {file = "coverage-7.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9158f8fb06747ac17bd237930c4372336edc85b6e13bdc778e60f9d685c3ca37"}, - {file = "coverage-7.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:486ee81fa694b4b796fc5617e376326a088f7b9729c74d9defa211813f3861e4"}, - {file = "coverage-7.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1285648428a6101b5f41a18991c84f1c3959cee359e51b8375c5882fc364a13f"}, - {file = "coverage-7.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2c44fcfb3781b41409d0f060a4ed748537557de9362a8a9282182fafb7a76ab4"}, - {file = "coverage-7.0.1-cp37-cp37m-win32.whl", hash = "sha256:d6814854c02cbcd9c873c0f3286a02e3ac1250625cca822ca6bc1018c5b19f1c"}, - {file = "coverage-7.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f66460f17c9319ea4f91c165d46840314f0a7c004720b20be58594d162a441d8"}, - {file = "coverage-7.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b373c9345c584bb4b5f5b8840df7f4ab48c4cbb7934b58d52c57020d911b856"}, - {file = "coverage-7.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d3022c3007d3267a880b5adcf18c2a9bf1fc64469b394a804886b401959b8742"}, - {file = "coverage-7.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92651580bd46519067e36493acb394ea0607b55b45bd81dd4e26379ed1871f55"}, - {file = "coverage-7.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cfc595d2af13856505631be072835c59f1acf30028d1c860b435c5fc9c15b69"}, - {file = "coverage-7.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b4b3a4d9915b2be879aff6299c0a6129f3d08a775d5a061f503cf79571f73e4"}, - {file = "coverage-7.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b6f22bb64cc39bcb883e5910f99a27b200fdc14cdd79df8696fa96b0005c9444"}, - {file = "coverage-7.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72d1507f152abacea81f65fee38e4ef3ac3c02ff8bc16f21d935fd3a8a4ad910"}, - {file = "coverage-7.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0a79137fc99815fff6a852c233628e735ec15903cfd16da0f229d9c4d45926ab"}, - {file = "coverage-7.0.1-cp38-cp38-win32.whl", hash = "sha256:b3763e7fcade2ff6c8e62340af9277f54336920489ceb6a8cd6cc96da52fcc62"}, - {file = "coverage-7.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:09f6b5a8415b6b3e136d5fec62b552972187265cb705097bf030eb9d4ffb9b60"}, - {file = "coverage-7.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:978258fec36c154b5e250d356c59af7d4c3ba02bef4b99cda90b6029441d797d"}, - {file = "coverage-7.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:19ec666533f0f70a0993f88b8273057b96c07b9d26457b41863ccd021a043b9a"}, - {file = "coverage-7.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfded268092a84605f1cc19e5c737f9ce630a8900a3589e9289622db161967e9"}, - {file = "coverage-7.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07bcfb1d8ac94af886b54e18a88b393f6a73d5959bb31e46644a02453c36e475"}, - {file = "coverage-7.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397b4a923cc7566bbc7ae2dfd0ba5a039b61d19c740f1373791f2ebd11caea59"}, - {file = "coverage-7.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aec2d1515d9d39ff270059fd3afbb3b44e6ec5758af73caf18991807138c7118"}, - {file = "coverage-7.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c20cfebcc149a4c212f6491a5f9ff56f41829cd4f607b5be71bb2d530ef243b1"}, - {file = "coverage-7.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fd556ff16a57a070ce4f31c635953cc44e25244f91a0378c6e9bdfd40fdb249f"}, - {file = "coverage-7.0.1-cp39-cp39-win32.whl", hash = "sha256:b9ea158775c7c2d3e54530a92da79496fb3fb577c876eec761c23e028f1e216c"}, - {file = "coverage-7.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:d1991f1dd95eba69d2cd7708ff6c2bbd2426160ffc73c2b81f617a053ebcb1a8"}, - {file = "coverage-7.0.1-pp37.pp38.pp39-none-any.whl", hash = "sha256:3dd4ee135e08037f458425b8842d24a95a0961831a33f89685ff86b77d378f89"}, - {file = "coverage-7.0.1.tar.gz", hash = "sha256:a4a574a19eeb67575a5328a5760bbbb737faa685616586a9f9da4281f940109c"}, + {file = "coverage-7.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f7c51b6074a8a3063c341953dffe48fd6674f8e4b1d3c8aa8a91f58d6e716a8"}, + {file = "coverage-7.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:628f47eaf66727fc986d3b190d6fa32f5e6b7754a243919d28bc0fd7974c449f"}, + {file = "coverage-7.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89d5abf86c104de808108a25d171ad646c07eda96ca76c8b237b94b9c71e518"}, + {file = "coverage-7.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75e43c6f4ea4d122dac389aabdf9d4f0e160770a75e63372f88005d90f5bcc80"}, + {file = "coverage-7.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49da0ff241827ebb52d5d6d5a36d33b455fa5e721d44689c95df99fd8db82437"}, + {file = "coverage-7.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0bce4ad5bdd0b02e177a085d28d2cea5fc57bb4ba2cead395e763e34cf934eb1"}, + {file = "coverage-7.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f79691335257d60951638dd43576b9bcd6f52baa5c1c2cd07a509bb003238372"}, + {file = "coverage-7.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5722269ed05fbdb94eef431787c66b66260ff3125d1a9afcc00facff8c45adf9"}, + {file = "coverage-7.0.3-cp310-cp310-win32.whl", hash = "sha256:bdbda870e0fda7dd0fe7db7135ca226ec4c1ade8aa76e96614829b56ca491012"}, + {file = "coverage-7.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:e56fae4292e216b8deeee38ace84557b9fa85b52db005368a275427cdabb8192"}, + {file = "coverage-7.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b82343a5bc51627b9d606f0b6b6b9551db7b6311a5dd920fa52a94beae2e8959"}, + {file = "coverage-7.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fd0a8aa431f9b7ad9eb8264f55ef83cbb254962af3775092fb6e93890dea9ca2"}, + {file = "coverage-7.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:112cfead1bd22eada8a8db9ed387bd3e8be5528debc42b5d3c1f7da4ffaf9fb5"}, + {file = "coverage-7.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af87e906355fa42447be5c08c5d44e6e1c005bf142f303f726ddf5ed6e0c8a4d"}, + {file = "coverage-7.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f30090e22a301952c5abd0e493a1c8358b4f0b368b49fa3e4568ed3ed68b8d1f"}, + {file = "coverage-7.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ae871d09901911eedda1981ea6fd0f62a999107293cdc4c4fd612321c5b34745"}, + {file = "coverage-7.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ed7c9debf7bfc63c9b9f8b595409237774ff4b061bf29fba6f53b287a2fdeab9"}, + {file = "coverage-7.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:13121fa22dcd2c7b19c5161e3fd725692448f05377b788da4502a383573227b3"}, + {file = "coverage-7.0.3-cp311-cp311-win32.whl", hash = "sha256:037b51ee86bc600f99b3b957c20a172431c35c2ef9c1ca34bc813ab5b51fd9f5"}, + {file = "coverage-7.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:25fde928306034e8deecd5fc91a07432dcc282c8acb76749581a28963c9f4f3f"}, + {file = "coverage-7.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7e8b0642c38b3d3b3c01417643ccc645345b03c32a2e84ef93cdd6844d6fe530"}, + {file = "coverage-7.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18b09811f849cc958d23f733a350a66b54a8de3fed1e6128ba55a5c97ffb6f65"}, + {file = "coverage-7.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:349d0b545520e8516f7b4f12373afc705d17d901e1de6a37a20e4ec9332b61f7"}, + {file = "coverage-7.0.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5b38813eee5b4739f505d94247604c72eae626d5088a16dd77b08b8b1724ab3"}, + {file = "coverage-7.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ba9af1218fa01b1f11c72271bc7290b701d11ad4dbc2ae97c445ecacf6858dba"}, + {file = "coverage-7.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c5648c7eec5cf1ba5db1cf2d6c10036a582d7f09e172990474a122e30c841361"}, + {file = "coverage-7.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d0df04495b76a885bfef009f45eebe8fe2fbf815ad7a83dabcf5aced62f33162"}, + {file = "coverage-7.0.3-cp37-cp37m-win32.whl", hash = "sha256:af6cef3796b8068713a48dd67d258dc9a6e2ebc3bd4645bfac03a09672fa5d20"}, + {file = "coverage-7.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:62ef3800c4058844e2e3fa35faa9dd0ccde8a8aba6c763aae50342e00d4479d4"}, + {file = "coverage-7.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:acef7f3a3825a2d218a03dd02f5f3cc7f27aa31d882dd780191d1ad101120d74"}, + {file = "coverage-7.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a530663a361eb27375cec28aea5cd282089b5e4b022ae451c4c3493b026a68a5"}, + {file = "coverage-7.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c58cd6bb46dcb922e0d5792850aab5964433d511b3a020867650f8d930dde4f4"}, + {file = "coverage-7.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f918e9ef4c98f477a5458238dde2a1643aed956c7213873ab6b6b82e32b8ef61"}, + {file = "coverage-7.0.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b865aa679bee7fbd1c55960940dbd3252621dd81468268786c67122bbd15343"}, + {file = "coverage-7.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c5d9b480ebae60fc2cbc8d6865194136bc690538fa542ba58726433bed6e04cc"}, + {file = "coverage-7.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:985ad2af5ec3dbb4fd75d5b0735752c527ad183455520055a08cf8d6794cabfc"}, + {file = "coverage-7.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ca15308ef722f120967af7474ba6a453e0f5b6f331251e20b8145497cf1bc14a"}, + {file = "coverage-7.0.3-cp38-cp38-win32.whl", hash = "sha256:c1cee10662c25c94415bbb987f2ec0e6ba9e8fce786334b10be7e6a7ab958f69"}, + {file = "coverage-7.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:44d6a556de4418f1f3bfd57094b8c49f0408df5a433cf0d253eeb3075261c762"}, + {file = "coverage-7.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e6dcc70a25cb95df0ae33dfc701de9b09c37f7dd9f00394d684a5b57257f8246"}, + {file = "coverage-7.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bf76d79dfaea802f0f28f50153ffbc1a74ae1ee73e480baeda410b4f3e7ab25f"}, + {file = "coverage-7.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88834e5d56d01c141c29deedacba5773fe0bed900b1edc957595a8a6c0da1c3c"}, + {file = "coverage-7.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef001a60e888f8741e42e5aa79ae55c91be73761e4df5e806efca1ddd62fd400"}, + {file = "coverage-7.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4959dc506be74e4963bd2c42f7b87d8e4b289891201e19ec551e64c6aa5441f8"}, + {file = "coverage-7.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b791beb17b32ac019a78cfbe6184f992b6273fdca31145b928ad2099435e2fcb"}, + {file = "coverage-7.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b07651e3b9af8f1a092861d88b4c74d913634a7f1f2280fca0ad041ad84e9e96"}, + {file = "coverage-7.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:55e46fa4168ccb7497c9be78627fcb147e06f474f846a10d55feeb5108a24ef0"}, + {file = "coverage-7.0.3-cp39-cp39-win32.whl", hash = "sha256:e3f1cd1cd65695b1540b3cf7828d05b3515974a9d7c7530f762ac40f58a18161"}, + {file = "coverage-7.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:d8249666c23683f74f8f93aeaa8794ac87cc61c40ff70374a825f3352a4371dc"}, + {file = "coverage-7.0.3-pp37.pp38.pp39-none-any.whl", hash = "sha256:b1ffc8f58b81baed3f8962e28c30d99442079b82ce1ec836a1f67c0accad91c1"}, + {file = "coverage-7.0.3.tar.gz", hash = "sha256:d5be4e93acce64f516bf4fd239c0e6118fc913c93fa1a3f52d15bdcc60d97b2d"}, ] distlib = [ {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, @@ -1331,8 +1331,8 @@ gitpython = [ {file = "GitPython-3.1.30.tar.gz", hash = "sha256:769c2d83e13f5d938b7688479da374c4e3d49f71549aaf462b646db9602ea6f8"}, ] griffe = [ - {file = "griffe-0.25.2-py3-none-any.whl", hash = "sha256:0868da415c5f43fe186705c041d98b69523c24a6504e841031373eacfdd7ec05"}, - {file = "griffe-0.25.2.tar.gz", hash = "sha256:555707b3417355e015d837845522cb38ee4ffcec485427868648eafacabe142e"}, + {file = "griffe-0.25.3-py3-none-any.whl", hash = "sha256:c98e8471a4fc7675a7989f45563a9f7ccbfdfb1713725526d69dec1bbdcda74a"}, + {file = "griffe-0.25.3.tar.gz", hash = "sha256:a71f156851649b3f0bdad6eb6bf7d7ac70e720a30da9f2d5a60e042480e92c03"}, ] h11 = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, @@ -1343,12 +1343,12 @@ httpcore = [ {file = "httpcore-0.16.3.tar.gz", hash = "sha256:c5d6f04e2fc530f39e0c077e6a30caa53f1451096120f1f38b954afd0b17c0cb"}, ] httpx = [ - {file = "httpx-0.23.1-py3-none-any.whl", hash = "sha256:0b9b1f0ee18b9978d637b0776bfd7f54e2ca278e063e3586d8f01cda89e042a8"}, - {file = "httpx-0.23.1.tar.gz", hash = "sha256:202ae15319be24efe9a8bd4ed4360e68fde7b38bcc2ce87088d416f026667d19"}, + {file = "httpx-0.23.3-py3-none-any.whl", hash = "sha256:a211fcce9b1254ea24f0cd6af9869b3d29aba40154e947d2a07bb499b3e310d6"}, + {file = "httpx-0.23.3.tar.gz", hash = "sha256:9818458eb565bb54898ccb9b8b251a28785dd4a55afbc23d0eb410754fe7d0f9"}, ] identify = [ - {file = "identify-2.5.11-py2.py3-none-any.whl", hash = "sha256:e7db36b772b188099616aaf2accbee122949d1c6a1bac4f38196720d6f9f06db"}, - {file = "identify-2.5.11.tar.gz", hash = "sha256:14b7076b29c99b1b0b8b08e96d448c7b877a9b07683cd8cfda2ea06af85ffa1c"}, + {file = "identify-2.5.12-py2.py3-none-any.whl", hash = "sha256:e8a400c3062d980243d27ce10455a52832205649bbcaf27ffddb3dfaaf477bad"}, + {file = "identify-2.5.12.tar.gz", hash = "sha256:0bc96b09c838310b6fcfcc61f78a981ea07f94836ef6ef553da5bb5d4745d662"}, ] idna = [ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, @@ -1441,8 +1441,8 @@ mkdocstrings = [ {file = "mkdocstrings-0.19.1.tar.gz", hash = "sha256:d1037cacb4b522c1e8c164ed5d00d724a82e49dcee0af80db8fb67b384faeef9"}, ] mkdocstrings-python = [ - {file = "mkdocstrings-python-0.8.2.tar.gz", hash = "sha256:b22528b7a7a0589d007eced019d97ad14de4eba4b2b9ba6a013bb66edc74ab43"}, - {file = "mkdocstrings_python-0.8.2-py3-none-any.whl", hash = "sha256:213d9592e66e084a9bd2fa4956d6294a3487c6dc9cc45164058d6317249b7b6e"}, + {file = "mkdocstrings-python-0.8.3.tar.gz", hash = "sha256:9ae473f6dc599339b09eee17e4d2b05d6ac0ec29860f3fc9b7512d940fc61adf"}, + {file = "mkdocstrings_python-0.8.3-py3-none-any.whl", hash = "sha256:4e6e1cd6f37a785de0946ced6eb846eb2f5d891ac1cc2c7b832943d3529087a7"}, ] msgpack = [ {file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250"}, @@ -1639,8 +1639,8 @@ pre-commit = [ {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"}, ] pygments = [ - {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, - {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, + {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, + {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, ] pymdown-extensions = [ {file = "pymdown_extensions-9.9-py3-none-any.whl", hash = "sha256:ac698c15265680db5eb13cd4342abfcde2079ac01e5486028f47a1b41547b859"}, @@ -1745,60 +1745,63 @@ sniffio = [ {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, ] syrupy = [ - {file = "syrupy-3.0.5-py3-none-any.whl", hash = "sha256:6dc0472cc690782b517d509a2854b5ca552a9851acf43b8a847cfa1aed6f6b01"}, - {file = "syrupy-3.0.5.tar.gz", hash = "sha256:928962a6c14abb2695be9a49b42a016a4e4abdb017a69104cde958f2faf01f98"}, + {file = "syrupy-3.0.6-py3-none-any.whl", hash = "sha256:9c18e22264026b34239bcc87ab7cc8d893eb17236ea7dae634217ea4f22a848d"}, + {file = "syrupy-3.0.6.tar.gz", hash = "sha256:583aa5ca691305c27902c3e29a1ce9da50ff9ab5f184c54b1dc124a16e4a6cf4"}, ] time-machine = [ - {file = "time-machine-2.8.2.tar.gz", hash = "sha256:2ff3cd145c381ac87b1c35400475a8f019b15dc2267861aad0466f55b49e7813"}, - {file = "time_machine-2.8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:931f762053031ec76e81d5b97b276d6cbc3c9958fd281a3661a4e4dcd434ae4d"}, - {file = "time_machine-2.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2bec6756c46d9e7ccfaeb177fde46da01af74ac9e5862dd9528e501d367f451e"}, - {file = "time_machine-2.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:959e63ad6980df1c36aefd19ae746e9b01c2be2f009199ec996fde0443b84de0"}, - {file = "time_machine-2.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62db94b5ebe246949e6cedc57e7b96028f18ab9fb63b391d0e94d2e963702e30"}, - {file = "time_machine-2.8.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4b40d872fd025c9ee6924372d345b2788aac9df89eba5562e6464dde04cf99"}, - {file = "time_machine-2.8.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b68259837b59c3bef30c5cff24d73228c5a5821342af624c78707fe297153221"}, - {file = "time_machine-2.8.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:46b4d2763c514d0036f7f46b23836d8fba0240ac1c50df588ca43193a59ee184"}, - {file = "time_machine-2.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f416489bc8d0adb4bd63edcce5ba743b408f3c161ab0e1a65f9f904a6f9a06c0"}, - {file = "time_machine-2.8.2-cp310-cp310-win32.whl", hash = "sha256:94ab54c2062a362059a02e6df624151bfdcda79dab704ffee220bb31f8153e24"}, - {file = "time_machine-2.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:f227819cfa27793e759811dabe6187e8f36dba6ac3a404516e17a81bb0216763"}, - {file = "time_machine-2.8.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:875eedfdf9cc59a9d119420b35c43a6d7ec08951a86581b4a4dbde47e6327256"}, - {file = "time_machine-2.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01ee31fca1414d1198feff9eb7d062ca42aea9d1c01f63cdd6b2e0bb4f7479a9"}, - {file = "time_machine-2.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4387678c392cfb40c038016b04f5becb022bdc371ecabded751c2a116d2c0b5a"}, - {file = "time_machine-2.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a42739702fd8ccbf4295aa6a0e5089f0ce125974e06ab157c6e4f4eadbc167c"}, - {file = "time_machine-2.8.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1963e1b9ea4891cbdd8a8f12cfb273dc7d3b0771ffe61238d688a7c2499445ef"}, - {file = "time_machine-2.8.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7c0234c2fae05b4945b711d655af3487df34c466e184fbce7253dfc28c9980d1"}, - {file = "time_machine-2.8.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19d01c6b6791c3ff45f8c82d149ac28292cf67242b1ace3dc1fdc0494edc111e"}, - {file = "time_machine-2.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b05a2ca1045edd343fa07d2c55d57695c40b7af1e4c7df480d8e1976eb48a22f"}, - {file = "time_machine-2.8.2-cp311-cp311-win32.whl", hash = "sha256:71607d92fd23cd5fc5bcddb3ec6b91a6a1b07f7277e7e58dce0a5c1f67d229cd"}, - {file = "time_machine-2.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9e4c58915b2136041027fb4d795e8844112683e550a9aed24ecde1de8a5a8f2"}, - {file = "time_machine-2.8.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b20f55d76cacb8b6f99c4161d8bfd6fc3be8d8ae003df2a79dbda9015d6ab85"}, - {file = "time_machine-2.8.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb64b249df5c2958484706bdc095b326baf0f9c4a96c990d63a6e290680a8933"}, - {file = "time_machine-2.8.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:460f3d7344b64c906030013f6ca314017d7cbeb211e6c8c0efbdb3a2f5b168e3"}, - {file = "time_machine-2.8.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ccd0e73e75f9cc624be08a2ae0305617ce7890d5b55f938ba336f086001ac66"}, - {file = "time_machine-2.8.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8856b03574bc88f506534489562dfeb9c057485052817895413d8f33e7d03d28"}, - {file = "time_machine-2.8.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3be539125dc815ff1f1ff05cd00f8839132a4b3a729809fa4a7de405f47cbd0b"}, - {file = "time_machine-2.8.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c3b356e9038abb78618169b86a2bc3488aa2faee27fa97c9cd8638972d60dfe"}, - {file = "time_machine-2.8.2-cp37-cp37m-win32.whl", hash = "sha256:bfbe53b80402ab3c93f112374d8624eb5e7f26395f01aea341bf91b4a512e36e"}, - {file = "time_machine-2.8.2-cp37-cp37m-win_amd64.whl", hash = "sha256:71917d38d2c34039a31ac0d63970f6009072a14c3a89169d165ca81130daf308"}, - {file = "time_machine-2.8.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a3384f03776ffed86afdc2a807aa80fc656fbce6605e9b89261fc17302759290"}, - {file = "time_machine-2.8.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6d084ccfbf30c658c23b1340583aa64afe4c6421b4d2ab3a84769915630e0d68"}, - {file = "time_machine-2.8.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ed6c02afa3fc48af1fa256d5a3a18b63c3e36e7759fec8184e340e1b2f38f77"}, - {file = "time_machine-2.8.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c783769cc7b722e4b9df6015919a65952e58eb6fe884c198c1f56d58d883d0bc"}, - {file = "time_machine-2.8.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5da17b12c20d96b69bbe71d1e260e76c81072cded63539050d0f8aa26e9701dc"}, - {file = "time_machine-2.8.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0213c32498190d7701cf90dc8a4f87d6d8571b856a16b474072e37f9e4daf896"}, - {file = "time_machine-2.8.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c47caacc5a00656ee9e4ad4600ed46e036f233bbd93ed99c0da5f3dcec6a1a64"}, - {file = "time_machine-2.8.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0e7950776b9087ba8e44f3602e5d695eaba853518c9963f41f3cba094000d87f"}, - {file = "time_machine-2.8.2-cp38-cp38-win32.whl", hash = "sha256:8bb1e68434a6c45bf2ef5d738420399803e7aa8211d77353e416d5043f82053e"}, - {file = "time_machine-2.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:f67957dac20cca1171a7b63a8343c86f4f589e42f3c61bce687e77dd475e4d88"}, - {file = "time_machine-2.8.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:18d60cb6eb2bb896ef442628be783d2ddf374873caefb083cbc2b2ed19361157"}, - {file = "time_machine-2.8.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:82055dc781c4c9f6c97f3a349473ab44f1096da61a8cf1e72c105d12a39344ea"}, - {file = "time_machine-2.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bfaa1018ea5695a47f9536e1c7f7a112d55741162d8cdaa49801b3977f710666"}, - {file = "time_machine-2.8.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f9c6bdead992708d3f88e9e337f08f9067e259eb6a7df23f94652cee7f08459"}, - {file = "time_machine-2.8.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e6ba08062248fd9ba750ca997ed8699176d71b0d3aa525333efbd10e644f574"}, - {file = "time_machine-2.8.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7d7233bb7a01d27e93fd8f687227fb93d314fb5048127844c248d76067b36e84"}, - {file = "time_machine-2.8.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0cb22588e0c88239bad7ac5d593dc1119aacb7ac074e7aa2badc53583b92febf"}, - {file = "time_machine-2.8.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ba71634179448df5dc6fb85d61e3956c8e33755ad3f76549dacb9c4854e88046"}, - {file = "time_machine-2.8.2-cp39-cp39-win32.whl", hash = "sha256:70ccbd8c5c4396fe4d60b0ceacef47f95e44f84a4d1d8cd5acdf9f81880e863a"}, - {file = "time_machine-2.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:32f77a14ffbaeef8ae5e5bb86eb0e76057b56cb94f1f4990756c66047f8cac91"}, + {file = "time-machine-2.9.0.tar.gz", hash = "sha256:60222d43f6e93a926adc36ed37a54bc8e4d0d8d1c4d449096afcfe85086129c2"}, + {file = "time_machine-2.9.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fd72c0b2e7443fff6e4481991742b72c17f73735e5fdd176406ca48df187a5c9"}, + {file = "time_machine-2.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5657e0e6077cf15b37f0d8cf78e868113bbb3ecccc60064c40fe52d8166ca8b1"}, + {file = "time_machine-2.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bfa82614a98ecee70272bb6038d210b2ad7b2a6b8a678b400c34bdaf776802a7"}, + {file = "time_machine-2.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4380bd6697cc7db3c9e6843f24779ac0550affa9d9a8e5f9e5d5cc139cb6583"}, + {file = "time_machine-2.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6211beee9f5dace08b1bbbb1fb09e34a69c52d87eea676729f14c8660481dff6"}, + {file = "time_machine-2.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:68ec8b83197db32c7a12da5f6b83c91271af3ed7f5dc122d2900a8de01dff9f0"}, + {file = "time_machine-2.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c5dbc8b87cdc7be070a499f2bd1cd405c7f647abeb3447dfd397639df040bc64"}, + {file = "time_machine-2.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:948ca690f9770ad4a93fa183061c11346505598f5f0b721965bc85ec83bb103d"}, + {file = "time_machine-2.9.0-cp310-cp310-win32.whl", hash = "sha256:f92d5d2eb119a6518755c4c9170112094c706d1c604460f50afc1308eeb97f0e"}, + {file = "time_machine-2.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:cb51432652ad663b4cbd631c73c90f9e94f463382b86c0b6b854173700512a70"}, + {file = "time_machine-2.9.0-cp310-cp310-win_arm64.whl", hash = "sha256:8976b7b1f7de13598b655d459f5640f90f3cd587283e1b914a22e45946c5485b"}, + {file = "time_machine-2.9.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6463e302c96eb8c691c4340e281bd54327a213b924fa189aea81accf7e7f78df"}, + {file = "time_machine-2.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6b632d60aa0883dc7292ac3d32050604d26ec2bbd5c4d42fb0de3b4ef17343e2"}, + {file = "time_machine-2.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d329578abe47ce95baa015ef3825acebb1b73b5fa6f818fdf2d4685a00ca457f"}, + {file = "time_machine-2.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ba5fc2655749066d68986de8368984dad4082db2fbeade78f40506dc5b65672"}, + {file = "time_machine-2.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49df5eea2160068e5b2bf28c22fc4c5aea00862ad88ddc3b62fc0f0683e97538"}, + {file = "time_machine-2.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8830510adbf0a231184da277db9de1d55ef93ed228a575d217aaee295505abf1"}, + {file = "time_machine-2.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b16a2129f9146faa080bfd1b53447761f7386ec5c72890c827a65f33ab200336"}, + {file = "time_machine-2.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a2cf80e5deaaa68c6cefb25303a4c870490b4e7591ed8e2435a65728920bc097"}, + {file = "time_machine-2.9.0-cp311-cp311-win32.whl", hash = "sha256:fe013942ab7f3241fcbe66ee43222d47f499d1e0cb69e913791c52e638ddd7f0"}, + {file = "time_machine-2.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:1d0ab46ce8a60baf9d86525694bf698fed9efefd22b8cbe1ca3e74abbb3239e1"}, + {file = "time_machine-2.9.0-cp311-cp311-win_arm64.whl", hash = "sha256:4f3755d9342ca1f1019418db52072272dfd75eb818fa4726fa8aabe208b38c26"}, + {file = "time_machine-2.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9ee553f7732fa51e019e3329a6984593184c4e0410af1e73d91ce38a5d4b34ab"}, + {file = "time_machine-2.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:359c806e5b9a7a3c73dbb808d19dca297f5504a5eefdc5d031db8d918f43e364"}, + {file = "time_machine-2.9.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e2a90b8300812d8d774f2d2fc216fec3c7d94132ac589e062489c395061f16c"}, + {file = "time_machine-2.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36dde844d28549929fab171d683c28a8db1c206547bcf6b7aca77319847d2046"}, + {file = "time_machine-2.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:728263611d7940fda34d21573bd2b3f1491bdb52dbf75c5fe6c226dfe4655201"}, + {file = "time_machine-2.9.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8bcc86b5a07ea9745f26dfad958dde0a4f56748c2ae0c9a96200a334d1b55055"}, + {file = "time_machine-2.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b9c36240876622b7f2f9e11bf72f100857c0a1e1a59af2da3d5067efea62c37"}, + {file = "time_machine-2.9.0-cp37-cp37m-win32.whl", hash = "sha256:eaf334477bc0a9283d5150a56be8670a07295ef676e5b5a7f086952929d1a56b"}, + {file = "time_machine-2.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8e797e5a2a99d1b237183e52251abfc1ad85c376278b39d1aca76a451a97861a"}, + {file = "time_machine-2.9.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:69898aed9b2315a90f5855343d9aa34d05fa06032e2e3bb14f2528941ec89dc1"}, + {file = "time_machine-2.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c01dbc3671d0649023daf623e952f9f0b4d904d57ab546d6d35a4aeb14915e8d"}, + {file = "time_machine-2.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f080f6f7ca8cfca43bc5639288aebd0a273b4b5bd0acff609c2318728b13a18"}, + {file = "time_machine-2.9.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8670cb5cfda99f483d60de6ce56ceb0ec5d359193e79e4688e1c3c9db3937383"}, + {file = "time_machine-2.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f97ed8bc5b517844a71030f74e9561de92f4902c306e6ccc8331a5b0c8dd0e00"}, + {file = "time_machine-2.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bdbe785e046d124f73cca603ee37d5fae0b15dc4c13702488ad19de56aae08ba"}, + {file = "time_machine-2.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:fcdef7687aed5c4331c9808f4a414a41987441c3e7a2ba554e4dccfa4218e788"}, + {file = "time_machine-2.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f6e79643368828d4651146a486be5a662846ac223ab5e2c73ddd519acfcc243c"}, + {file = "time_machine-2.9.0-cp38-cp38-win32.whl", hash = "sha256:bb15b2b79b00d3f6cf7d62096f5e782fa740ecedfe0540c09f1d1e4d3d7b81ba"}, + {file = "time_machine-2.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:3ff5148e2e73392db8418a1fe2f0b06f4a0e76772933502fb61e4c3000b5324e"}, + {file = "time_machine-2.9.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8367fd03f2d7349c7fc20f14de186974eaca2502c64b948212de663742c8fd11"}, + {file = "time_machine-2.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4b55654aaeaba380fcd6c004b8ada2978fdd4ece1e61e6b9717c6d4cc7fbbcd9"}, + {file = "time_machine-2.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae4e3f02ab5dabb35adca606237c7e1a515c86d69c0b7092bbe0e1cfe5cffc61"}, + {file = "time_machine-2.9.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:010a58a8de1120308befae19e6c9de2ef5ca5206635cea33cb264998725cc027"}, + {file = "time_machine-2.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b32addbf56639a9a8261fb62f8ea83473447671c83ca2c017ab1eabf4841157f"}, + {file = "time_machine-2.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:372a97da01db89533d2f4ce50bbd908e5c56df7b8cfd6a005b177d0b14dc2938"}, + {file = "time_machine-2.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b8faff03231ee55d5a216ce3e9171c5205459f866f54d4b5ee8aa1d860e4ce11"}, + {file = "time_machine-2.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:748d701228e646c224f2adfa6a11b986cd4aa90f1b8c13ef4534a3919c796bc0"}, + {file = "time_machine-2.9.0-cp39-cp39-win32.whl", hash = "sha256:d79d374e32488c76cdb06fbdd4464083aeaa715ddca3e864bac7c7760eb03729"}, + {file = "time_machine-2.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:cc6bf01211b5ea40f633d5502c5aa495b415ebaff66e041820997dae70a508e1"}, + {file = "time_machine-2.9.0-cp39-cp39-win_arm64.whl", hash = "sha256:3ce445775fcf7cb4040cfdba4b7c4888e7fd98bbcccfe1dc3fa8a798ed1f1d24"}, ] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, @@ -1851,34 +1854,34 @@ virtualenv = [ {file = "virtualenv-20.17.1.tar.gz", hash = "sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058"}, ] watchdog = [ - {file = "watchdog-2.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ed91c3ccfc23398e7aa9715abf679d5c163394b8cad994f34f156d57a7c163dc"}, - {file = "watchdog-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:76a2743402b794629a955d96ea2e240bd0e903aa26e02e93cd2d57b33900962b"}, - {file = "watchdog-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:920a4bda7daa47545c3201a3292e99300ba81ca26b7569575bd086c865889090"}, - {file = "watchdog-2.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ceaa9268d81205876bedb1069f9feab3eccddd4b90d9a45d06a0df592a04cae9"}, - {file = "watchdog-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1893d425ef4fb4f129ee8ef72226836619c2950dd0559bba022b0818c63a7b60"}, - {file = "watchdog-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e99c1713e4436d2563f5828c8910e5ff25abd6ce999e75f15c15d81d41980b6"}, - {file = "watchdog-2.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a5bd9e8656d07cae89ac464ee4bcb6f1b9cecbedc3bf1334683bed3d5afd39ba"}, - {file = "watchdog-2.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a048865c828389cb06c0bebf8a883cec3ae58ad3e366bcc38c61d8455a3138f"}, - {file = "watchdog-2.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e722755d995035dd32177a9c633d158f2ec604f2a358b545bba5bed53ab25bca"}, - {file = "watchdog-2.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:af4b5c7ba60206759a1d99811b5938ca666ea9562a1052b410637bb96ff97512"}, - {file = "watchdog-2.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:619d63fa5be69f89ff3a93e165e602c08ed8da402ca42b99cd59a8ec115673e1"}, - {file = "watchdog-2.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1f2b0665c57358ce9786f06f5475bc083fea9d81ecc0efa4733fd0c320940a37"}, - {file = "watchdog-2.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:441024df19253bb108d3a8a5de7a186003d68564084576fecf7333a441271ef7"}, - {file = "watchdog-2.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1a410dd4d0adcc86b4c71d1317ba2ea2c92babaf5b83321e4bde2514525544d5"}, - {file = "watchdog-2.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28704c71afdb79c3f215c90231e41c52b056ea880b6be6cee035c6149d658ed1"}, - {file = "watchdog-2.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2ac0bd7c206bb6df78ef9e8ad27cc1346f2b41b1fef610395607319cdab89bc1"}, - {file = "watchdog-2.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:27e49268735b3c27310883012ab3bd86ea0a96dcab90fe3feb682472e30c90f3"}, - {file = "watchdog-2.2.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:2af1a29fd14fc0a87fb6ed762d3e1ae5694dcde22372eebba50e9e5be47af03c"}, - {file = "watchdog-2.2.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:c7bd98813d34bfa9b464cf8122e7d4bec0a5a427399094d2c17dd5f70d59bc61"}, - {file = "watchdog-2.2.0-py3-none-manylinux2014_i686.whl", hash = "sha256:56fb3f40fc3deecf6e518303c7533f5e2a722e377b12507f6de891583f1b48aa"}, - {file = "watchdog-2.2.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:74535e955359d79d126885e642d3683616e6d9ab3aae0e7dcccd043bd5a3ff4f"}, - {file = "watchdog-2.2.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:cf05e6ff677b9655c6e9511d02e9cc55e730c4e430b7a54af9c28912294605a4"}, - {file = "watchdog-2.2.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:d6ae890798a3560688b441ef086bb66e87af6b400a92749a18b856a134fc0318"}, - {file = "watchdog-2.2.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e5aed2a700a18c194c39c266900d41f3db0c1ebe6b8a0834b9995c835d2ca66e"}, - {file = "watchdog-2.2.0-py3-none-win32.whl", hash = "sha256:d0fb5f2b513556c2abb578c1066f5f467d729f2eb689bc2db0739daf81c6bb7e"}, - {file = "watchdog-2.2.0-py3-none-win_amd64.whl", hash = "sha256:1f8eca9d294a4f194ce9df0d97d19b5598f310950d3ac3dd6e8d25ae456d4c8a"}, - {file = "watchdog-2.2.0-py3-none-win_ia64.whl", hash = "sha256:ad0150536469fa4b693531e497ffe220d5b6cd76ad2eda474a5e641ee204bbb6"}, - {file = "watchdog-2.2.0.tar.gz", hash = "sha256:83cf8bc60d9c613b66a4c018051873d6273d9e45d040eed06d6a96241bd8ec01"}, + {file = "watchdog-2.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a09483249d25cbdb4c268e020cb861c51baab2d1affd9a6affc68ffe6a231260"}, + {file = "watchdog-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5100eae58133355d3ca6c1083a33b81355c4f452afa474c2633bd2fbbba398b3"}, + {file = "watchdog-2.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e618a4863726bc7a3c64f95c218437f3349fb9d909eb9ea3a1ed3b567417c661"}, + {file = "watchdog-2.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:102a60093090fc3ff76c983367b19849b7cc24ec414a43c0333680106e62aae1"}, + {file = "watchdog-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:748ca797ff59962e83cc8e4b233f87113f3cf247c23e6be58b8a2885c7337aa3"}, + {file = "watchdog-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6ccd8d84b9490a82b51b230740468116b8205822ea5fdc700a553d92661253a3"}, + {file = "watchdog-2.2.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6e01d699cd260d59b84da6bda019dce0a3353e3fcc774408ae767fe88ee096b7"}, + {file = "watchdog-2.2.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8586d98c494690482c963ffb24c49bf9c8c2fe0589cec4dc2f753b78d1ec301d"}, + {file = "watchdog-2.2.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:adaf2ece15f3afa33a6b45f76b333a7da9256e1360003032524d61bdb4c422ae"}, + {file = "watchdog-2.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83a7cead445008e880dbde833cb9e5cc7b9a0958edb697a96b936621975f15b9"}, + {file = "watchdog-2.2.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8ac23ff2c2df4471a61af6490f847633024e5aa120567e08d07af5718c9d092"}, + {file = "watchdog-2.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d0f29fd9f3f149a5277929de33b4f121a04cf84bb494634707cfa8ea8ae106a8"}, + {file = "watchdog-2.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:967636031fa4c4955f0f3f22da3c5c418aa65d50908d31b73b3b3ffd66d60640"}, + {file = "watchdog-2.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96cbeb494e6cbe3ae6aacc430e678ce4b4dd3ae5125035f72b6eb4e5e9eb4f4e"}, + {file = "watchdog-2.2.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:61fdb8e9c57baf625e27e1420e7ca17f7d2023929cd0065eb79c83da1dfbeacd"}, + {file = "watchdog-2.2.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4cb5ecc332112017fbdb19ede78d92e29a8165c46b68a0b8ccbd0a154f196d5e"}, + {file = "watchdog-2.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a480d122740debf0afac4ddd583c6c0bb519c24f817b42ed6f850e2f6f9d64a8"}, + {file = "watchdog-2.2.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:978a1aed55de0b807913b7482d09943b23a2d634040b112bdf31811a422f6344"}, + {file = "watchdog-2.2.1-py3-none-manylinux2014_armv7l.whl", hash = "sha256:8c28c23972ec9c524967895ccb1954bc6f6d4a557d36e681a36e84368660c4ce"}, + {file = "watchdog-2.2.1-py3-none-manylinux2014_i686.whl", hash = "sha256:c27d8c1535fd4474e40a4b5e01f4ba6720bac58e6751c667895cbc5c8a7af33c"}, + {file = "watchdog-2.2.1-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d6b87477752bd86ac5392ecb9eeed92b416898c30bd40c7e2dd03c3146105646"}, + {file = "watchdog-2.2.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:cece1aa596027ff56369f0b50a9de209920e1df9ac6d02c7f9e5d8162eb4f02b"}, + {file = "watchdog-2.2.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:8b5cde14e5c72b2df5d074774bdff69e9b55da77e102a91f36ef26ca35f9819c"}, + {file = "watchdog-2.2.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e038be858425c4f621900b8ff1a3a1330d9edcfeaa1c0468aeb7e330fb87693e"}, + {file = "watchdog-2.2.1-py3-none-win32.whl", hash = "sha256:bc43c1b24d2f86b6e1cc15f68635a959388219426109233e606517ff7d0a5a73"}, + {file = "watchdog-2.2.1-py3-none-win_amd64.whl", hash = "sha256:17f1708f7410af92ddf591e94ae71a27a13974559e72f7e9fde3ec174b26ba2e"}, + {file = "watchdog-2.2.1-py3-none-win_ia64.whl", hash = "sha256:195ab1d9d611a4c1e5311cbf42273bc541e18ea8c32712f2fb703cfc6ff006f9"}, + {file = "watchdog-2.2.1.tar.gz", hash = "sha256:cdcc23c9528601a8a293eb4369cbd14f6b4f34f07ae8769421252e9c22718b6f"}, ] yarl = [ {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bb81f753c815f6b8e2ddd2eef3c855cf7da193b82396ac013c661aaa6cc6b0a5"}, diff --git a/src/textual/_segment_tools.py b/src/textual/_segment_tools.py index c12b06cbc..47a8be0d9 100644 --- a/src/textual/_segment_tools.py +++ b/src/textual/_segment_tools.py @@ -14,6 +14,47 @@ from .css.types import AlignHorizontal, AlignVertical from .geometry import Size +def index_to_cell_position(segments: Iterable[Segment], index: int) -> int: + """Given a character index, return the cell position of that character within + an Iterable of Segments. This is the sum of the cell lengths of all the characters + *before* the character at `index`. + + Args: + segments (Iterable[Segment]): The segments to find the cell position within. + index (int): The index to convert into a cell position. + + Returns: + int: The cell position of the character at `index`. If the `index` is not + valid within the segments, returns 0. + """ + if index == 0: + return 0 + + cell_position_end = 0 + segment_length = 0 + segment_end_index = 0 + segment_cell_length = 0 + text = "" + iter_segments = iter(segments) + try: + while segment_end_index < index: + segment = next(iter_segments) + text = segment.text + segment_length = len(text) + segment_cell_length = cell_len(text) + cell_position_end += segment_cell_length + segment_end_index += segment_length + except StopIteration: + return 0 + + # Check how far into this segment the target index is + segment_index_start = segment_end_index - segment_length + index_within_segment = index - segment_index_start + segment_cell_start = cell_position_end - segment_cell_length + + return segment_cell_start + cell_len(text[:index_within_segment]) + + def line_crop( segments: list[Segment], start: int, end: int, total: int ) -> list[Segment]: diff --git a/src/textual/strip.py b/src/textual/strip.py index be9dc80b0..f7ea831df 100644 --- a/src/textual/strip.py +++ b/src/textual/strip.py @@ -10,6 +10,7 @@ from rich.style import Style from ._cache import FIFOCache from ._filter import LineFilter +from ._segment_tools import index_to_cell_position @rich.repr.auto @@ -79,29 +80,7 @@ class Strip: Returns: int: The cell position of the character at `index`. """ - if index == 0: - return 0 - - cell_position_end = 0 - segment_length = 0 - segment_end_index = 0 - segment_cell_length = 0 - text = "" - iter_segments = iter(self) - while segment_end_index < index: - segment = next(iter_segments) - text = segment.text - segment_length = len(text) - segment_cell_length = cell_len(text) - cell_position_end += segment_cell_length - segment_end_index += segment_length - - # Check how far into this segment the target index is - segment_index_start = segment_end_index - segment_length - index_within_segment = index - segment_index_start - segment_cell_start = cell_position_end - segment_cell_length - - return segment_cell_start + cell_len(text[:index_within_segment]) + return index_to_cell_position(self._segments, index) @property def cell_length(self) -> int: diff --git a/tests/test_segment_tools.py b/tests/test_segment_tools.py index 7483d2b15..a5dd592a1 100644 --- a/tests/test_segment_tools.py +++ b/tests/test_segment_tools.py @@ -1,3 +1,4 @@ +import pytest from rich.segment import Segment from rich.style import Style @@ -63,17 +64,6 @@ def test_line_crop_edge_2(): assert result == expected -def test_line_crop_highlight_reverse_bug(): - """Regression test for #818""" - segments_joined = [Segment('a1あ11bcdaef123a1a')] - segments_split = [Segment('a1あ11bcdaef'), Segment('1'), Segment('23a1a')] - - joined1 = "".join(seg.text for seg in line_crop(segments_split, start=9, end=16, total=23)) - joined2 = "".join(seg.text for seg in line_crop(segments_joined, start=9, end=16, total=23)) - - assert joined1 == joined2 - - def test_line_trim(): segments = [Segment("foo")] diff --git a/tests/test_strip.py b/tests/test_strip.py index 15d527119..473063503 100644 --- a/tests/test_strip.py +++ b/tests/test_strip.py @@ -160,3 +160,8 @@ def test_divide(): def test_index_to_cell_position(index, cell_position): strip = Strip([Segment("ab"), Segment("cd日本語ef"), Segment("gh")]) assert cell_position == strip.index_to_cell_position(index) + + +def test_index_cell_position_no_segments(): + strip = Strip([]) + assert strip.index_to_cell_position(2) == 0 From 433c86d4b9a8139ea851eb8c08ec797ca0a94c64 Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Fri, 6 Jan 2023 13:59:36 +0000 Subject: [PATCH 156/310] Remove unused test file --- tests/test_input.py | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 tests/test_input.py diff --git a/tests/test_input.py b/tests/test_input.py deleted file mode 100644 index 87971757b..000000000 --- a/tests/test_input.py +++ /dev/null @@ -1,8 +0,0 @@ -from textual.widgets._input import _InputRenderable, Input - - -def test_input_renderable(): - input_widget = Input(value="a1あ11bcdaef123a1a") - - renderable_cursor = _InputRenderable(input_widget, cursor_visible=True) - renderable_no_cursor = _InputRenderable(input_widget, cursor_visible=False) From c90e12a35bea42d18336867ba2fbe4dd4ddc6ea2 Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Fri, 6 Jan 2023 13:59:52 +0000 Subject: [PATCH 157/310] Remove unused import in test file --- tests/test_segment_tools.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_segment_tools.py b/tests/test_segment_tools.py index a5dd592a1..630114ed9 100644 --- a/tests/test_segment_tools.py +++ b/tests/test_segment_tools.py @@ -1,4 +1,3 @@ -import pytest from rich.segment import Segment from rich.style import Style From 127662943198488586dd5c60376c3b6d321709a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 14:18:07 +0000 Subject: [PATCH 158/310] Update example. --- docs/examples/styles/text_style.css | 10 +++++----- docs/examples/styles/text_style.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/examples/styles/text_style.css b/docs/examples/styles/text_style.css index bf953d42c..b0a4041ba 100644 --- a/docs/examples/styles/text_style.css +++ b/docs/examples/styles/text_style.css @@ -1,18 +1,18 @@ Screen { layout: horizontal; } -Static { - width:1fr; +Label { + width: 1fr; } -#static1 { +#lbl1 { background: red 30%; text-style: bold; } -#static2 { +#lbl2 { background: green 30%; text-style: italic; } -#static3 { +#lbl3 { background: blue 30%; text-style: reverse; } diff --git a/docs/examples/styles/text_style.py b/docs/examples/styles/text_style.py index f9a59a76f..6dd1476eb 100644 --- a/docs/examples/styles/text_style.py +++ b/docs/examples/styles/text_style.py @@ -1,5 +1,5 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label TEXT = """I must not fear. Fear is the mind-killer. @@ -12,9 +12,9 @@ Where the fear has gone there will be nothing. Only I will remain.""" class TextStyleApp(App): def compose(self): - yield Static(TEXT, id="static1") - yield Static(TEXT, id="static2") - yield Static(TEXT, id="static3") + yield Label(TEXT, id="lbl1") + yield Label(TEXT, id="lbl2") + yield Label(TEXT, id="lbl3") app = TextStyleApp(css_path="text_style.css") From 72d3171a79202cf73822cab7577646e2a5f9c998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 14:18:21 +0000 Subject: [PATCH 159/310] Add example with all text styles. --- docs/examples/styles/text_style_all.css | 42 +++++++++++++++++++++++++ docs/examples/styles/text_style_all.py | 28 +++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 docs/examples/styles/text_style_all.css create mode 100644 docs/examples/styles/text_style_all.py diff --git a/docs/examples/styles/text_style_all.css b/docs/examples/styles/text_style_all.css new file mode 100644 index 000000000..e71787c51 --- /dev/null +++ b/docs/examples/styles/text_style_all.css @@ -0,0 +1,42 @@ +#lbl1 { + text-style: none; +} + +#lbl2 { + text-style: bold; +} + +#lbl3 { + text-style: italic; +} + +#lbl4 { + text-style: reverse; +} + +#lbl5 { + text-style: strike; +} + +#lbl6 { + text-style: underline; +} + +#lbl7 { + text-style: bold italic; +} + +#lbl8 { + text-style: reverse strike; +} + +Grid { + grid-size: 4; + grid-gutter: 1 2; + margin: 1 2; + height: 100%; +} + +Label { + height: 100%; +} diff --git a/docs/examples/styles/text_style_all.py b/docs/examples/styles/text_style_all.py new file mode 100644 index 000000000..9bb21b062 --- /dev/null +++ b/docs/examples/styles/text_style_all.py @@ -0,0 +1,28 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Label + +TEXT = """I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain.""" + + +class AllTextStyleApp(App): + def compose(self): + yield Grid( + Label("none\n" + TEXT, id="lbl1"), + Label("bold\n" + TEXT, id="lbl2"), + Label("italic\n" + TEXT, id="lbl3"), + Label("reverse\n" + TEXT, id="lbl4"), + Label("strike\n" + TEXT, id="lbl5"), + Label("underline\n" + TEXT, id="lbl6"), + Label("bold italic\n" + TEXT, id="lbl7"), + Label("reverse strike\n" + TEXT, id="lbl8"), + ) + + +app = AllTextStyleApp(css_path="text_style_all.css") From 583b1273acd9da27e3996ecb4d109ceac47dbd8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 14:18:50 +0000 Subject: [PATCH 160/310] Update text style reference. [skip ci] --- docs/styles/text_style.md | 46 ++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/docs/styles/text_style.md b/docs/styles/text_style.md index b54a1f2aa..815c040ec 100644 --- a/docs/styles/text_style.md +++ b/docs/styles/text_style.md @@ -1,29 +1,27 @@ # Text-style -The `text-style` rule enables a number of different ways of displaying text. - -Text styles may be set in combination. -For example `bold underline` or `reverse underline strike`. +The `text-style` sets the style for the text in a widget. ## Syntax -``` -text-style: ...; -``` +--8<-- "docs/snippets/syntax_block_start.md" +text-style: <text-style>; +--8<-- "docs/snippets/syntax_block_end.md" + +`text-style` will take all the values specified and will apply that styling combination to the text in the widget. ### Values -| Value | Description | -|-------------|----------------------------------------------------------------| -| `bold` | **bold text** | -| `italic` | _italic text_ | -| `reverse` | reverse video text (foreground and background colors reversed) | -| `underline` | underline text | -| `strike` | strikethrough text | +--8<-- "docs/snippets/type_syntax/text_style.md" -## Example +## Examples -Each of the three text panels has a different text style. +Each of the three text panels has a different text style, respectively `bold`, `italic`, and `reverse`, from left to right. + +=== "Output" + + ```{.textual path="docs/examples/styles/text_style.py" lines=14} + ``` === "text_style.py" @@ -37,9 +35,23 @@ Each of the three text panels has a different text style. --8<-- "docs/examples/styles/text_style.css" ``` +The next example shows all different styles on their own, as well as some combinations of styles in a single widget. + === "Output" - ```{.textual path="docs/examples/styles/text_style.py"} + ```{.textual path="docs/examples/styles/text_style_all.py"} + ``` + +=== "text_style_all.py" + + ```python + --8<-- "docs/examples/styles/text_style_all.py" + ``` + +=== "text_style_all.css" + + ```css + --8<-- "docs/examples/styles/text_style_all.css" ``` ## CSS From 42baa0e074695d4711f93878d45531f5a46f03bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 14:41:13 +0000 Subject: [PATCH 161/310] Remove redundant values subsections. [skip ci] --- docs/styles/align.md | 11 ----------- docs/styles/background.md | 13 +------------ docs/styles/border.md | 10 ---------- docs/styles/color.md | 12 ------------ docs/styles/content_align.md | 10 ---------- docs/styles/height.md | 4 ---- docs/styles/layer.md | 4 ---- docs/styles/layers.md | 4 ---- docs/styles/margin.md | 4 ---- docs/styles/max_height.md | 4 ---- docs/styles/max_width.md | 4 ---- docs/styles/min_height.md | 4 ---- docs/styles/min_width.md | 4 ---- docs/styles/offset.md | 4 ---- docs/styles/opacity.md | 12 ------------ docs/styles/outline.md | 10 ---------- docs/styles/overflow.md | 4 ---- docs/styles/text_align.md | 4 ---- docs/styles/text_opacity.md | 12 ------------ docs/styles/text_style.md | 4 ---- 20 files changed, 1 insertion(+), 137 deletions(-) diff --git a/docs/styles/align.md b/docs/styles/align.md index 0f3121f01..f2a42cb4a 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -21,17 +21,6 @@ To specify alignment on a single axis, use the respective style and type: - `align-horizontal` takes a [``](../../css_types/horizontal) and does alignment along the horizontal axis; and - `align-vertical` takes a [``](../../css_types/vertical) and does alignment along the vertical axis. -### Values - -#### <horizontal> - ---8<-- "docs/snippets/type_syntax/horizontal.md" - -#### <vertical> - ---8<-- "docs/snippets/type_syntax/vertical.md" - - ## Examples This example contains a simple app with two labels centered on the screen with `align: center middle;`: diff --git a/docs/styles/background.md b/docs/styles/background.md index d22581a57..c10baa28e 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -8,18 +8,7 @@ The `background` rule sets the background color of a widget. background: <color> [<percentage>]; --8<-- "docs/snippets/syntax_block_end.md" -The style `background` needs a [``](../../css_types/color) followed by an optional [``](../../css_types/percentage) to specify the color transparency. - -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" -This is clamped between `0%` and `100%`. +The style `background` needs a [``](../../css_types/color) followed by an optional [``](../../css_types/percentage) to specify the color transparency (clamped between `0%` and `100%`). ## Examples diff --git a/docs/styles/border.md b/docs/styles/border.md index 15013f650..5439b3ec7 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -17,16 +17,6 @@ The style `border` accepts an optional [``](../../css_types/border) that 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. -### Values - -#### <border> - ---8<-- "docs/snippets/type_syntax/border.md" - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - ### Multiple edge rules If multiple border rules target the same edge, the last rule that targets a specific edge is the one that is applied to that edge. diff --git a/docs/styles/color.md b/docs/styles/color.md index 4db2eccb4..508e47c18 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -12,18 +12,6 @@ The style `color` needs a [``](../../css_types/color) followed by an opti Instead of a [``](../../css_types/color), one can use the special value `"auto"` to choose automatically the color with the best contrast for readability purposes. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -The alternative value `"auto"` picks the color that provides the best contrast for readability purposes. - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ## Examples This example sets a different text color for each of three different widgets. diff --git a/docs/styles/content_align.md b/docs/styles/content_align.md index bdf073199..b459009c6 100644 --- a/docs/styles/content_align.md +++ b/docs/styles/content_align.md @@ -22,16 +22,6 @@ To specify content alignment on a single axis, use the respective style and type - `content-align-horizontal` takes a [``](../../css_types/horizontal) and does alignment along the horizontal axis; and - `content-align-vertical` takes a [``](../../css_types/vertical) and does alignment along the vertical axis. -### Values - -#### <horizontal> - ---8<-- "docs/snippets/type_syntax/horizontal.md" - -#### <vertical> - ---8<-- "docs/snippets/type_syntax/vertical.md" - ## Examples This first example shows three labels stacked vertically, each with different content alignments. diff --git a/docs/styles/height.md b/docs/styles/height.md index a4858a95f..97dd82524 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -11,10 +11,6 @@ height: <scalar>; The style `height` needs a [``](../../css_types/scalar) to determine the vertical length of the widget. By default, it sets the height of the content area, but if [`box-sizing`](./box_sizing) is set to `border-box` it sets the height of the border area. -### Values - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Examples This examples creates a widget with a height of 50% of the screen. diff --git a/docs/styles/layer.md b/docs/styles/layer.md index 6e6f02476..851a02eb3 100644 --- a/docs/styles/layer.md +++ b/docs/styles/layer.md @@ -13,10 +13,6 @@ This [``](../../css_types/name) must correspond to a [``](../../css_ More information on layers can be found in the [guide](../guide/layout.md#layers). -### Values - ---8<-- "docs/snippets/type_syntax/name.md" - !!! warning Using a `` that hasn't been defined in a [`layers`](./layers.md) declaration of an ancestor of this widget has no effect. diff --git a/docs/styles/layers.md b/docs/styles/layers.md index 427d2761e..518293311 100644 --- a/docs/styles/layers.md +++ b/docs/styles/layers.md @@ -15,10 +15,6 @@ The layers defined first in the list are drawn under the layers that are defined More information on layers can be found in the [guide](../guide/layout.md#layers). -### Values - ---8<-- "docs/snippets/type_syntax/name.md" - ## Example In the example below, `#box1` is yielded before `#box2`. diff --git a/docs/styles/margin.md b/docs/styles/margin.md index de97a31f7..c537393d6 100644 --- a/docs/styles/margin.md +++ b/docs/styles/margin.md @@ -32,10 +32,6 @@ The number of values given defines what edges get what margin: Alternatively, margin can be set for each edge individually through the rules `margin-top`, `margin-right`, `margin-bottom`, and `margin-left`, respectively. -### Values - ---8<-- "docs/snippets/type_syntax/integer.md" - ## Examples In the example below we add a large margin to a label, which makes it move away from the top-left corner of the screen. diff --git a/docs/styles/max_height.md b/docs/styles/max_height.md index c14162517..32f869755 100644 --- a/docs/styles/max_height.md +++ b/docs/styles/max_height.md @@ -11,10 +11,6 @@ max-height: <scalar>; The `max-height` rule accepts a [``](../../css_types/scalar) that defines an upper bound for the [`height`](./height) of a widget. That is, the height of a widget is never allowed to exceed `max-height`. -### Values - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Example The example below shows some placeholders that were defined to span vertically from the top edge of the terminal to the bottom edge. diff --git a/docs/styles/max_width.md b/docs/styles/max_width.md index 41d07b315..210fdab49 100644 --- a/docs/styles/max_width.md +++ b/docs/styles/max_width.md @@ -11,10 +11,6 @@ max-width: <scalar>; The `max-width` rule accepts a [``](../../css_types/scalar) that defines an upper bound for the [`width`](./width) of a widget. That is, the width of a widget is never allowed to exceed `max-width`. -### Values - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Example The example below shows some placeholders that were defined to span horizontally from the top edge of the terminal to the bottom edge. diff --git a/docs/styles/min_height.md b/docs/styles/min_height.md index 79adb93bb..883351b38 100644 --- a/docs/styles/min_height.md +++ b/docs/styles/min_height.md @@ -11,10 +11,6 @@ min-height: <scalar>; The `min-height` rule accepts a [``](../../css_types/scalar) that defines a lower bound for the [`height`](./height) of a widget. That is, the height of a widget is never allowed to be under `min-height`. -### Values - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Example The example below shows some placeholders with their height set to `50%`. diff --git a/docs/styles/min_width.md b/docs/styles/min_width.md index 4db00c5e4..c64374097 100644 --- a/docs/styles/min_width.md +++ b/docs/styles/min_width.md @@ -11,10 +11,6 @@ min-width: <scalar>; The `min-width` rule accepts a [``](../../css_types/scalar) that defines a lower bound for the [`width`](./width) of a widget. That is, the width of a widget is never allowed to be under `min-width`. -### Values - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Example The example below shows some placeholders with their width set to `50%`. diff --git a/docs/styles/offset.md b/docs/styles/offset.md index 10ca2dd4d..ad113de9f 100644 --- a/docs/styles/offset.md +++ b/docs/styles/offset.md @@ -15,10 +15,6 @@ The two [``](../../css_types/scalar) in the `offset` define, respectivel To specify an offset along a single axis, you can use `offset-x` and `offset-y`. -### Values - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Example In this example, we have 3 widgets with differing offsets. diff --git a/docs/styles/opacity.md b/docs/styles/opacity.md index 4844f9342..bf05fca28 100644 --- a/docs/styles/opacity.md +++ b/docs/styles/opacity.md @@ -13,18 +13,6 @@ The opacity of a widget can be set as a [``](../css_types/number.md) or Conversely, `1`/`100%` means full opacity, which is equivalent to no transparency. Values outside of these ranges will be clamped. -### Values - -### <number> - ---8<-- "docs/snippets/type_syntax/number.md" -The value of [``](../../css_types/number) is clamped between `0` and `1`. - -### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" -The value of [``](../../css_types/percentage) is clamped between `0%` and `100%`. - ## Example This example shows, from top to bottom, increasing opacity values for a label with a border and some text. diff --git a/docs/styles/outline.md b/docs/styles/outline.md index 3d1916090..24ca78c7b 100644 --- a/docs/styles/outline.md +++ b/docs/styles/outline.md @@ -22,16 +22,6 @@ The style `outline` accepts an optional [``](../../css_types/border) tha Unlike the style [`border`](./border.md), the frame of the outline is drawn over the content area of the widget. This rule can be useful for temporary emphasis of the content of a widget, if you want to draw the user's attention to it. -### Values - -#### <border> - ---8<-- "docs/snippets/type_syntax/border.md" - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - ## Examples This example shows a widget with an outline. Note how the outline occludes the text area. diff --git a/docs/styles/overflow.md b/docs/styles/overflow.md index 84a903fd1..ba9296996 100644 --- a/docs/styles/overflow.md +++ b/docs/styles/overflow.md @@ -19,10 +19,6 @@ Overflow may also be set individually for each axis: - `overflow-x` sets the overflow for the horizontal axis; and - `overflow-y` sets the overflow for the vertical axis. -### Values - ---8<-- "docs/snippets/type_syntax/overflow.md" - ### Defaults The default setting for containers is `overflow: auto auto`. diff --git a/docs/styles/text_align.md b/docs/styles/text_align.md index dc55dc03e..2eccff1e2 100644 --- a/docs/styles/text_align.md +++ b/docs/styles/text_align.md @@ -10,10 +10,6 @@ text-align: <text-align>; The `text-align` rule accepts a value of the type [``](../css_types/text_align.md) that defines how text is aligned inside the widget. -### Values - ---8<-- "docs/snippets/type_syntax/text_align.md" - ### Defaults The default value is `start`. diff --git a/docs/styles/text_opacity.md b/docs/styles/text_opacity.md index b7b8f63ff..304aac548 100644 --- a/docs/styles/text_opacity.md +++ b/docs/styles/text_opacity.md @@ -13,18 +13,6 @@ The text opacity can be set as a [``](../css_types/number.md) or a [``](../../css_types/number) is clamped between `0` and `1`. - -### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" -The value of [``](../../css_types/percentage) is clamped between `0%` and `100%`. - ## Example This example shows, from top to bottom, increasing `text-opacity` values. diff --git a/docs/styles/text_style.md b/docs/styles/text_style.md index 815c040ec..19010325e 100644 --- a/docs/styles/text_style.md +++ b/docs/styles/text_style.md @@ -10,10 +10,6 @@ text-style: <text-style>; `text-style` will take all the values specified and will apply that styling combination to the text in the widget. -### Values - ---8<-- "docs/snippets/type_syntax/text_style.md" - ## Examples Each of the three text panels has a different text style, respectively `bold`, `italic`, and `reverse`, from left to right. From 69a143442ce669ca49649c083e914fdf40fe920c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 14:50:31 +0000 Subject: [PATCH 162/310] Inline css type values in their reference. [skip ci] --- docs/css_types/_template.md | 33 ++++++++++++++++++++- docs/css_types/border.md | 20 ++++++++++++- docs/css_types/color.md | 10 ++++++- docs/css_types/horizontal.md | 8 ++++- docs/css_types/integer.md | 2 +- docs/css_types/name.md | 5 +++- docs/css_types/number.md | 2 +- docs/css_types/overflow.md | 8 ++++- docs/css_types/percentage.md | 2 +- docs/css_types/scalar.md | 9 +++++- docs/css_types/text_align.md | 15 +++++++++- docs/css_types/text_style.md | 11 ++++++- docs/css_types/vertical.md | 8 ++++- docs/snippets/type_syntax/_template.md | 39 ------------------------- docs/snippets/type_syntax/border.md | 19 ------------ docs/snippets/type_syntax/color.md | 9 ------ docs/snippets/type_syntax/horizontal.md | 7 ----- docs/snippets/type_syntax/integer.md | 1 - docs/snippets/type_syntax/name.md | 4 --- docs/snippets/type_syntax/number.md | 1 - docs/snippets/type_syntax/overflow.md | 7 ----- docs/snippets/type_syntax/percentage.md | 1 - docs/snippets/type_syntax/scalar.md | 8 ----- docs/snippets/type_syntax/text_align.md | 14 --------- docs/snippets/type_syntax/text_style.md | 10 ------- docs/snippets/type_syntax/vertical.md | 7 ----- 26 files changed, 120 insertions(+), 140 deletions(-) delete mode 100644 docs/snippets/type_syntax/_template.md delete mode 100644 docs/snippets/type_syntax/border.md delete mode 100644 docs/snippets/type_syntax/color.md delete mode 100644 docs/snippets/type_syntax/horizontal.md delete mode 100644 docs/snippets/type_syntax/integer.md delete mode 100644 docs/snippets/type_syntax/name.md delete mode 100644 docs/snippets/type_syntax/number.md delete mode 100644 docs/snippets/type_syntax/overflow.md delete mode 100644 docs/snippets/type_syntax/percentage.md delete mode 100644 docs/snippets/type_syntax/scalar.md delete mode 100644 docs/snippets/type_syntax/text_align.md delete mode 100644 docs/snippets/type_syntax/text_style.md delete mode 100644 docs/snippets/type_syntax/vertical.md diff --git a/docs/css_types/_template.md b/docs/css_types/_template.md index c9fe058d4..fbb79dcb6 100644 --- a/docs/css_types/_template.md +++ b/docs/css_types/_template.md @@ -6,10 +6,41 @@ ## Syntax + + + + + + ## Examples ### CSS diff --git a/docs/css_types/border.md b/docs/css_types/border.md index eb37d685c..447a74069 100644 --- a/docs/css_types/border.md +++ b/docs/css_types/border.md @@ -4,7 +4,25 @@ The `` CSS type represents a border style. ## Syntax ---8<-- "docs/snippets/type_syntax/border.md" +The [``](/css_types/border) type can take any of the following values: + +| Border type | Description | +|-------------|----------------------------------------------------------| +| `ascii` | A border with plus, hyphen, and vertical bar characters. | +| `blank` | A blank border (reserves space for a border). | +| `dashed` | Dashed line border. | +| `double` | Double lined border. | +| `heavy` | Heavy border. | +| `hidden` | Alias for "none". | +| `hkey` | Horizontal key-line border. | +| `inner` | Thick solid border. | +| `none` | Disabled border. | +| `outer` | Solid border with additional space around content. | +| `round` | Rounded corners. | +| `solid` | Solid border. | +| `tall` | Solid border with additional space top and bottom. | +| `vkey` | Vertical key-line border. | +| `wide` | Solid border with additional space left and right. | ## Border command diff --git a/docs/css_types/color.md b/docs/css_types/color.md index db3e82b96..0d6852356 100644 --- a/docs/css_types/color.md +++ b/docs/css_types/color.md @@ -8,7 +8,15 @@ The `` CSS type represents a color. ## Syntax ---8<-- "docs/snippets/type_syntax/color.md" +The legal values for a [``](/css_types/color) depend on the [class `Color`][textual.color.Color] and include: + + - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); + - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); + - a color description in the RGB system (e.g., `rgb(23,78,200)`); + - a color description in the HSL system (e.g., `hsl(290,70%,80%)`); and + +For more details about the exact formats accepted, see [the class method `Color.parse`][textual.color.Color.parse]. +[Textual's default themes](../../guide/design#theme-reference) also provide many CSS variables with colors. ## Examples diff --git a/docs/css_types/horizontal.md b/docs/css_types/horizontal.md index 2aef91b47..f5df8d04a 100644 --- a/docs/css_types/horizontal.md +++ b/docs/css_types/horizontal.md @@ -4,7 +4,13 @@ The `` CSS type represents a position along the horizontal axis. ## Syntax ---8<-- "docs/snippets/type_syntax/horizontal.md" +The [``](/css_types/horizontal) type can take any of the following values: + +| Value | Description | +| ---------------- | -------------------------------------------- | +| `center` | Aligns in the center of the horizontal axis. | +| `left` (default) | Aligns on the left of the horizontal axis. | +| `right` | Aligns on the right of the horizontal axis. | ## Examples diff --git a/docs/css_types/integer.md b/docs/css_types/integer.md index cde2faa1a..6823d97fb 100644 --- a/docs/css_types/integer.md +++ b/docs/css_types/integer.md @@ -4,7 +4,7 @@ The `` CSS type represents an integer number. ## Syntax ---8<-- "docs/snippets/type_syntax/integer.md" +An [``](/css_types/integer) is any valid integer number like `-10` or `42`. !!! note diff --git a/docs/css_types/name.md b/docs/css_types/name.md index 00998e2c0..ef2faa625 100644 --- a/docs/css_types/name.md +++ b/docs/css_types/name.md @@ -4,7 +4,10 @@ The `` type represents a sequence of characters that identifies something. ## Syntax ---8<-- "docs/snippets/type_syntax/name.md" +A [``](/css_types/name) is any non-empty sequence of characters: + + - starting with a letter `a-z`, `A-Z`, or underscore `_`; and + - followed by zero or more letters `a-zA-Z`, digits `0-9`, underscores `_`, and hiphens `-`. ## Examples diff --git a/docs/css_types/number.md b/docs/css_types/number.md index 0e1cc3e8f..a3b50660c 100644 --- a/docs/css_types/number.md +++ b/docs/css_types/number.md @@ -4,7 +4,7 @@ The `` CSS type represents a real number, which can be an integer or a n ## Syntax ---8<-- "docs/snippets/type_syntax/number.md" +A [``](/css_types/number) is an [``](/css_types/integer), optionally followed by the decimal point `.` and a decimal part composed of one or more digits. ## Examples diff --git a/docs/css_types/overflow.md b/docs/css_types/overflow.md index c5fe6010e..b4f89aa2f 100644 --- a/docs/css_types/overflow.md +++ b/docs/css_types/overflow.md @@ -4,7 +4,13 @@ The `` CSS type represents overflow modes. ## Syntax ---8<-- "docs/snippets/type_syntax/overflow.md" +The [``](/css_types/overflow) type can take any of the following values: + +| Value | Description | +|----------|----------------------------------------| +| `auto` | Determine overflow mode automatically. | +| `hidden` | Don't overflow. | +| `scroll` | Allow overflowing. | ## Examples diff --git a/docs/css_types/percentage.md b/docs/css_types/percentage.md index c7196bd94..6252cae97 100644 --- a/docs/css_types/percentage.md +++ b/docs/css_types/percentage.md @@ -9,7 +9,7 @@ It is often used to represent values that are relative to the parent's values. ## Syntax ---8<-- "docs/snippets/type_syntax/percentage.md" +A [``](/css_types/percentage) is a [``](/css_types/number) followed by the percent sign `%` (without spaces). Some rules may clamp the values between `0%` and `100%`. ## Examples diff --git a/docs/css_types/scalar.md b/docs/css_types/scalar.md index 7e37e7fca..e909c2f05 100644 --- a/docs/css_types/scalar.md +++ b/docs/css_types/scalar.md @@ -10,7 +10,14 @@ It is used to represent lengths, for example in the [`width`](../styles/width.md ## Syntax ---8<-- "docs/snippets/type_syntax/scalar.md" +A [``](/css_types/scalar) can be any of the following: + + - a fixed number of cells (e.g., `10`); + - a fractional proportion relative to the sizes of the other widgets (e.g., `1fr`); + - a percentage relative to the container widget (e.g., `50%`); + - a percentage relative to the container width/height (e.g., `25w`/`75h`); + - a percentage relative to the viewport width/height (e.g., `25vw`/`75vh`); or + - the special value `auto` to compute the optimal size to fit without scrolling. A complete reference table and detailed explanations follow. You can [skip to the examples](#examples). diff --git a/docs/css_types/text_align.md b/docs/css_types/text_align.md index c9fc59785..8a18b51c7 100644 --- a/docs/css_types/text_align.md +++ b/docs/css_types/text_align.md @@ -8,7 +8,20 @@ The `` CSS type represents alignments that can be applied to text. ## Syntax ---8<-- "docs/snippets/type_syntax/text_align.md" +A [``](/css_types/text_align) can be any of the following values: + +| Value | Alignment type | +|-----------|--------------------------------------| +| `center` | Center alignment. | +| `end` | Alias for `right`. | +| `justify` | Text is justified inside the widget. | +| `left` | Left alignment. | +| `right` | Right alignment. | +| `start` | Alias for `left`. | + +!!! tip + + The meanings of `start` and `end` will likely change when RTL languages become supported by Textual. ## Examples diff --git a/docs/css_types/text_style.md b/docs/css_types/text_style.md index 5f128b004..1dd36ce10 100644 --- a/docs/css_types/text_style.md +++ b/docs/css_types/text_style.md @@ -8,7 +8,16 @@ The `` CSS type represents styles that can be applied to text. ## Syntax ---8<-- "docs/snippets/type_syntax/text_style.md" +A [``](/css_types/text_style) can be any _space-separated_ combination of the following values: + +| Value | Description | +|-------------|-----------------------------------------------------------------| +| `bold` | **Bold text.** | +| `italic` | _Italic text._ | +| `none` | Plain text with no styling. | +| `reverse` | Reverse video text (foreground and background colors reversed). | +| `strike` | Strikethrough text. | +| `underline` | Underline text. | ## Examples diff --git a/docs/css_types/vertical.md b/docs/css_types/vertical.md index f301e1fe1..5d95e093f 100644 --- a/docs/css_types/vertical.md +++ b/docs/css_types/vertical.md @@ -4,7 +4,13 @@ The `` CSS type represents a position along the vertical axis. ## Syntax ---8<-- "docs/snippets/type_syntax/vertical.md" +The [``](/css_types/vertical) type can take any of the following values: + +| Value | Description | +| --------------- | ------------------------------------------ | +| `bottom` | Aligns at the bottom of the vertical axis. | +| `middle` | Aligns in the middle of the vertical axis. | +| `top` (default) | Aligns at the top of the vertical axis. | ## Examples diff --git a/docs/snippets/type_syntax/_template.md b/docs/snippets/type_syntax/_template.md deleted file mode 100644 index 77697f721..000000000 --- a/docs/snippets/type_syntax/_template.md +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - diff --git a/docs/snippets/type_syntax/border.md b/docs/snippets/type_syntax/border.md deleted file mode 100644 index 519507bdd..000000000 --- a/docs/snippets/type_syntax/border.md +++ /dev/null @@ -1,19 +0,0 @@ -The [``](/css_types/border) type can take any of the following values: - -| Border type | Description | -|-------------|----------------------------------------------------------| -| `ascii` | A border with plus, hyphen, and vertical bar characters. | -| `blank` | A blank border (reserves space for a border). | -| `dashed` | Dashed line border. | -| `double` | Double lined border. | -| `heavy` | Heavy border. | -| `hidden` | Alias for "none". | -| `hkey` | Horizontal key-line border. | -| `inner` | Thick solid border. | -| `none` | Disabled border. | -| `outer` | Solid border with additional space around content. | -| `round` | Rounded corners. | -| `solid` | Solid border. | -| `tall` | Solid border with additional space top and bottom. | -| `vkey` | Vertical key-line border. | -| `wide` | Solid border with additional space left and right. | diff --git a/docs/snippets/type_syntax/color.md b/docs/snippets/type_syntax/color.md deleted file mode 100644 index 7b87daac3..000000000 --- a/docs/snippets/type_syntax/color.md +++ /dev/null @@ -1,9 +0,0 @@ -The legal values for a [``](/css_types/color) depend on the [class `Color`][textual.color.Color] and include: - - - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); - - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); - - a color description in the RGB system (e.g., `rgb(23,78,200)`); - - a color description in the HSL system (e.g., `hsl(290,70%,80%)`); and - -For more details about the exact formats accepted, see [the class method `Color.parse`][textual.color.Color.parse]. -[Textual's default themes](../../guide/design#theme-reference) also provide many CSS variables with colors. diff --git a/docs/snippets/type_syntax/horizontal.md b/docs/snippets/type_syntax/horizontal.md deleted file mode 100644 index 4d80d23ee..000000000 --- a/docs/snippets/type_syntax/horizontal.md +++ /dev/null @@ -1,7 +0,0 @@ -The [``](/css_types/horizontal) type can take any of the following values: - -| Value | Description | -| ---------------- | -------------------------------------------- | -| `center` | Aligns in the center of the horizontal axis. | -| `left` (default) | Aligns on the left of the horizontal axis. | -| `right` | Aligns on the right of the horizontal axis. | diff --git a/docs/snippets/type_syntax/integer.md b/docs/snippets/type_syntax/integer.md deleted file mode 100644 index 111b84b80..000000000 --- a/docs/snippets/type_syntax/integer.md +++ /dev/null @@ -1 +0,0 @@ -An [``](/css_types/integer) is any valid integer number like `-10` or `42`. diff --git a/docs/snippets/type_syntax/name.md b/docs/snippets/type_syntax/name.md deleted file mode 100644 index b36abbb4e..000000000 --- a/docs/snippets/type_syntax/name.md +++ /dev/null @@ -1,4 +0,0 @@ -A [``](/css_types/name) is any non-empty sequence of characters: - - - starting with a letter `a-z`, `A-Z`, or underscore `_`; and - - followed by zero or more letters `a-zA-Z`, digits `0-9`, underscores `_`, and hiphens `-`. diff --git a/docs/snippets/type_syntax/number.md b/docs/snippets/type_syntax/number.md deleted file mode 100644 index aaf0aac07..000000000 --- a/docs/snippets/type_syntax/number.md +++ /dev/null @@ -1 +0,0 @@ -A [``](/css_types/number) is an [``](/css_types/integer), optionally followed by the decimal point `.` and a decimal part composed of one or more digits. diff --git a/docs/snippets/type_syntax/overflow.md b/docs/snippets/type_syntax/overflow.md deleted file mode 100644 index 25307f510..000000000 --- a/docs/snippets/type_syntax/overflow.md +++ /dev/null @@ -1,7 +0,0 @@ -The [``](/css_types/overflow) type can take any of the following values: - -| Value | Description | -|----------|----------------------------------------| -| `auto` | Determine overflow mode automatically. | -| `hidden` | Don't overflow. | -| `scroll` | Allow overflowing. | diff --git a/docs/snippets/type_syntax/percentage.md b/docs/snippets/type_syntax/percentage.md deleted file mode 100644 index a131f0c2c..000000000 --- a/docs/snippets/type_syntax/percentage.md +++ /dev/null @@ -1 +0,0 @@ -A [``](/css_types/percentage) is a [``](/css_types/number) followed by the percent sign `%` (without spaces). diff --git a/docs/snippets/type_syntax/scalar.md b/docs/snippets/type_syntax/scalar.md deleted file mode 100644 index f29e9f4b2..000000000 --- a/docs/snippets/type_syntax/scalar.md +++ /dev/null @@ -1,8 +0,0 @@ -A [``](/css_types/scalar) can be any of the following: - - - a fixed number of cells (e.g., `10`); - - a fractional proportion relative to the sizes of the other widgets (e.g., `1fr`); - - a percentage relative to the container widget (e.g., `50%`); - - a percentage relative to the container width/height (e.g., `25w`/`75h`); - - a percentage relative to the viewport width/height (e.g., `25vw`/`75vh`); or - - the special value `auto` to compute the optimal size to fit without scrolling. diff --git a/docs/snippets/type_syntax/text_align.md b/docs/snippets/type_syntax/text_align.md deleted file mode 100644 index 6720422e5..000000000 --- a/docs/snippets/type_syntax/text_align.md +++ /dev/null @@ -1,14 +0,0 @@ -A [``](/css_types/text_align) can be any of the following values: - -| Value | Alignment type | -|-----------|--------------------------------------| -| `center` | Center alignment. | -| `end` | Alias for `right`. | -| `justify` | Text is justified inside the widget. | -| `left` | Left alignment. | -| `right` | Right alignment. | -| `start` | Alias for `left`. | - -!!! tip - - The meanings of `start` and `end` will likely change when RTL languages become supported by Textual. diff --git a/docs/snippets/type_syntax/text_style.md b/docs/snippets/type_syntax/text_style.md deleted file mode 100644 index f95b25b9b..000000000 --- a/docs/snippets/type_syntax/text_style.md +++ /dev/null @@ -1,10 +0,0 @@ -A [``](/css_types/text_style) can be any _space-separated_ combination of the following values: - -| Value | Description | -|-------------|-----------------------------------------------------------------| -| `bold` | **Bold text.** | -| `italic` | _Italic text._ | -| `none` | Plain text with no styling. | -| `reverse` | Reverse video text (foreground and background colors reversed). | -| `strike` | Strikethrough text. | -| `underline` | Underline text. | diff --git a/docs/snippets/type_syntax/vertical.md b/docs/snippets/type_syntax/vertical.md deleted file mode 100644 index 34e7acceb..000000000 --- a/docs/snippets/type_syntax/vertical.md +++ /dev/null @@ -1,7 +0,0 @@ -The [``](/css_types/vertical) type can take any of the following values: - -| Value | Description | -| --------------- | ------------------------------------------ | -| `bottom` | Aligns at the bottom of the vertical axis. | -| `middle` | Aligns in the middle of the vertical axis. | -| `top` (default) | Aligns at the top of the vertical axis. | From ee4b2cfe9e053cc20254a2e7d2450770f43f4a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 14:53:07 +0000 Subject: [PATCH 163/310] Update tint example to use labels. --- docs/examples/styles/tint.css | 3 ++- docs/examples/styles/tint.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/examples/styles/tint.css b/docs/examples/styles/tint.css index 6fa6a3a67..312f26a66 100644 --- a/docs/examples/styles/tint.css +++ b/docs/examples/styles/tint.css @@ -1,5 +1,6 @@ -Static { +Label { height: 3; + width: 100%; text-style: bold; background: white; color: black; diff --git a/docs/examples/styles/tint.py b/docs/examples/styles/tint.py index 44d816b0b..3da5f40a7 100644 --- a/docs/examples/styles/tint.py +++ b/docs/examples/styles/tint.py @@ -1,13 +1,13 @@ from textual.app import App from textual.color import Color -from textual.widgets import Static +from textual.widgets import Label class TintApp(App): def compose(self): color = Color.parse("green") for tint_alpha in range(0, 101, 10): - widget = Static(f"tint: green {tint_alpha}%;") + widget = Label(f"tint: green {tint_alpha}%;") widget.styles.tint = color.with_alpha(tint_alpha / 100) yield widget From 498f452b8877d4b9c41b86a352391e3ae8fca16b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 14:53:18 +0000 Subject: [PATCH 164/310] Update tint reference. --- docs/styles/tint.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/styles/tint.md b/docs/styles/tint.md index dde7e3aaf..e387b0bc7 100644 --- a/docs/styles/tint.md +++ b/docs/styles/tint.md @@ -1,12 +1,14 @@ # Tint -The tint rule blends a color with the widget. The color should likely have an _alpha_ component, or the end result would obscure the widget content. +The `tint` rule blends a color with the whole widget. ## Syntax -``` -tint: []; -``` +--8<-- "docs/snippets/syntax_block_start.md" +tint: <color> [<percentage>]; +--8<-- "docs/snippets/syntax_block_end.md" + +The tint rule blends a [``](../css_types/color.md) with the widget. The color should likely have an _alpha_ component (specified directly in the color used or by the optional [``](../css_types/percentage.md)), otherwise the end result will obscure the widget content. ## Example @@ -47,5 +49,5 @@ from textual.color import Color widget.styles.tint = Color.parse("red").with_alpha(0.2); # A green tint -widget.styles.tint = "rgba(0, 200, 0, 0.3): +widget.styles.tint = "rgba(0, 200, 0, 0.3)" ``` From 597a8923e9eb07cc7f00ff0e40c3fd37f6f00c18 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 6 Jan 2023 15:32:04 +0000 Subject: [PATCH 165/310] run black on tests --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0a091f72f..bee80413b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,5 +12,4 @@ repos: rev: 22.10.0 hooks: - id: black - exclude: ^tests/ exclude: ^tests/snapshot_tests From 3fe855296c40a59937f8399236be0aad251da26f Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Fri, 6 Jan 2023 16:34:57 +0000 Subject: [PATCH 166/310] Raise exception from index to cell position method --- src/textual/_segment_tools.py | 15 ++++++++++++--- tests/test_strip.py | 10 +++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/textual/_segment_tools.py b/src/textual/_segment_tools.py index 47a8be0d9..3ccfcf97a 100644 --- a/src/textual/_segment_tools.py +++ b/src/textual/_segment_tools.py @@ -14,6 +14,10 @@ from .css.types import AlignHorizontal, AlignVertical from .geometry import Size +class NoCellPositionForIndex(Exception): + pass + + def index_to_cell_position(segments: Iterable[Segment], index: int) -> int: """Given a character index, return the cell position of that character within an Iterable of Segments. This is the sum of the cell lengths of all the characters @@ -24,9 +28,14 @@ def index_to_cell_position(segments: Iterable[Segment], index: int) -> int: index (int): The index to convert into a cell position. Returns: - int: The cell position of the character at `index`. If the `index` is not - valid within the segments, returns 0. + int: The cell position of the character at `index`. + + Raises: + NoCellPositionForIndex: If the supplied index doesn't fall within the given segments. """ + if not segments: + raise NoCellPositionForIndex + if index == 0: return 0 @@ -45,7 +54,7 @@ def index_to_cell_position(segments: Iterable[Segment], index: int) -> int: cell_position_end += segment_cell_length segment_end_index += segment_length except StopIteration: - return 0 + raise NoCellPositionForIndex # Check how far into this segment the target index is segment_index_start = segment_end_index - segment_length diff --git a/tests/test_strip.py b/tests/test_strip.py index 473063503..7674c2fd8 100644 --- a/tests/test_strip.py +++ b/tests/test_strip.py @@ -2,6 +2,7 @@ import pytest from rich.segment import Segment from rich.style import Style +from textual._segment_tools import NoCellPositionForIndex from textual.strip import Strip from textual._filter import Monochrome @@ -164,4 +165,11 @@ def test_index_to_cell_position(index, cell_position): def test_index_cell_position_no_segments(): strip = Strip([]) - assert strip.index_to_cell_position(2) == 0 + with pytest.raises(NoCellPositionForIndex): + strip.index_to_cell_position(2) + + +def test_index_cell_position_index_too_large(): + strip = Strip([Segment("abcdef"), Segment("ghi")]) + with pytest.raises(NoCellPositionForIndex): + strip.index_to_cell_position(100) From d69168a922f7e50b89e151917aa946b3470d808f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 16:37:41 +0000 Subject: [PATCH 167/310] Update visibility example to use labels. --- docs/examples/styles/visibility.css | 13 +++++++------ docs/examples/styles/visibility.py | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/examples/styles/visibility.css b/docs/examples/styles/visibility.css index 349bb1345..da684c03f 100644 --- a/docs/examples/styles/visibility.css +++ b/docs/examples/styles/visibility.css @@ -1,12 +1,13 @@ Screen { background: green; } -Static { - height: 5; - background: white; - color: blue; - border: heavy blue; +Label { + height: 5; + width: 100%; + background: white; + color: blue; + border: heavy blue; } -Static.invisible { +Label.invisible { visibility: hidden; } diff --git a/docs/examples/styles/visibility.py b/docs/examples/styles/visibility.py index 169cc8041..b9f790243 100644 --- a/docs/examples/styles/visibility.py +++ b/docs/examples/styles/visibility.py @@ -1,12 +1,12 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label class VisibilityApp(App): def compose(self): - yield Static("Widget 1") - yield Static("Widget 2", classes="invisible") - yield Static("Widget 3") + yield Label("Widget 1") + yield Label("Widget 2", classes="invisible") + yield Label("Widget 3") app = VisibilityApp(css_path="visibility.css") From 2217a8f5fa1320a57bd9be106f66e58e25cf1aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 16:38:31 +0000 Subject: [PATCH 168/310] Add new visibility example. This new example shows how we can have an invisible container with visible children. --- .../examples/styles/visibility_containers.css | 22 ++++++++++++++ docs/examples/styles/visibility_containers.py | 30 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 docs/examples/styles/visibility_containers.css create mode 100644 docs/examples/styles/visibility_containers.py diff --git a/docs/examples/styles/visibility_containers.css b/docs/examples/styles/visibility_containers.css new file mode 100644 index 000000000..c8b75e7ae --- /dev/null +++ b/docs/examples/styles/visibility_containers.css @@ -0,0 +1,22 @@ +Horizontal { + padding: 1 2; /* (1)! */ + background: white; +} + +#top {} /* (2)! */ + +#middle { /* (3)! */ + visibility: hidden; +} + +#bot { /* (4)! */ + visibility: hidden; +} + +#bot > Placeholder { /* (5)! */ + visibility: visible; +} + +Placeholder { + width: 1fr; +} diff --git a/docs/examples/styles/visibility_containers.py b/docs/examples/styles/visibility_containers.py new file mode 100644 index 000000000..879b916fb --- /dev/null +++ b/docs/examples/styles/visibility_containers.py @@ -0,0 +1,30 @@ +from textual.app import App +from textual.containers import Horizontal, Vertical +from textual.widgets import Placeholder + + +class VisibilityContainersApp(App): + def compose(self): + yield Vertical( + Horizontal( + Placeholder(), + Placeholder(), + Placeholder(), + id="top", + ), + Horizontal( + Placeholder(), + Placeholder(), + Placeholder(), + id="middle", + ), + Horizontal( + Placeholder(), + Placeholder(), + Placeholder(), + id="bot", + ), + ) + + +app = VisibilityContainersApp(css_path="visibility_containers.css") From 2867b09923eb0fc53f167c53aab38001ad9f5651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 16:38:49 +0000 Subject: [PATCH 169/310] Update visibility reference. --- docs/styles/visibility.md | 72 +++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 14 deletions(-) diff --git a/docs/styles/visibility.md b/docs/styles/visibility.md index d864487b0..fbed34e8b 100644 --- a/docs/styles/visibility.md +++ b/docs/styles/visibility.md @@ -1,24 +1,42 @@ # Visibility -The `visibility` rule may be used to make a widget invisible while still reserving spacing for it. +The `visibility` rule determines whether a widget is visible or not. ## Syntax -``` -visibility: [visible|hidden]; -``` +--8<-- "docs/snippets/syntax_block_start.md" +visibility: hidden | visible; +--8<-- "docs/snippets/syntax_block_end.md" + +`visibility` takes one of two values to set the visibility of a widget. ### Values -| Value | Description | -|---------------------|----------------------------------------| -| `visible` (default) | The widget will be displayed as normal | -| `hidden` | The widget will be invisible | +| Value | Description | +|---------------------|-----------------------------------------| +| `hidden` | The widget will be invisible. | +| `visible` (default) | The widget will be displayed as normal. | -## Example +### Visibility inheritance + +!!! note + + Children of an invisible container _can_ be visible. + +By default, children inherit the visibility of their parents. +So, if a container is set to be invisible, its children widgets will also be invisible by default. +However, those widgets can be made visible if their visibility is explicitly set to `visibility: visible`. +This is shown in the second example below. + +## Examples Note that the second widget is hidden, while leaving a space where it would have been rendered. +=== "Output" + + ```{.textual path="docs/examples/styles/visibility.py"} + ``` + === "visibility.py" ```python @@ -31,19 +49,45 @@ Note that the second widget is hidden, while leaving a space where it would have --8<-- "docs/examples/styles/visibility.css" ``` +The next example shows the interaction of the `visibility` rule with invisible containers that have visible children. +The app below has three rows with a `Horizontal` container per row and three placeholders per row. +The containers all have a white background, and then: + + - the top container is visible by default (we can see the white background around the placeholders); + - the middle container is invisible and the children placeholders inherited that setting; + - the bottom container is invisible _but_ the children placeholders are visible because they were set to be visible. + === "Output" - ```{.textual path="docs/examples/styles/visibility.py"} + ```{.textual path="docs/examples/styles/visibility_containers.py"} ``` +=== "visibility_containers.py" + + ```python + --8<-- "docs/examples/styles/visibility_containers.py" + ``` + +=== "visibility_containers.css" + + ```css hl_lines="2-3 6 8-10 12-14 16-18" + --8<-- "docs/examples/styles/visibility_containers.css" + ``` + + 1. The padding and the white background let us know when the `Horizontal` is visible. + 2. The top `Horizontal` is visible by default, and so are its children. + 3. The middle `Horizontal` is made invisible and its children will inherit that setting. + 4. The bottom `Horizontal` is made invisible... + 5. ... but its children override that setting and become visible. + ## CSS ```sass -/* Widget is on screen */ -visibility: visible; - -/* Widget is not on the screen */ +/* Widget is invisible */ visibility: hidden; + +/* Widget is visible */ +visibility: visible; ``` ## Python From 0db3fa6701ec1239aa4b08310f95cdcb0a52b9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:25:01 +0000 Subject: [PATCH 170/310] Simplify Placeholder implementation. Instead of creating a private widget that is the only child of 'Placeholder', that was inheriting from 'Container', simplify everything. 'Placeholder' now inherits directly from 'Widget' and it saves a dictionary with its renderables per variant, instead of deferring that to the child '_PlaceholderLabel'. --- src/textual/widgets/_placeholder.py | 80 ++++++++--------------------- 1 file changed, 20 insertions(+), 60 deletions(-) diff --git a/src/textual/widgets/_placeholder.py b/src/textual/widgets/_placeholder.py index eabe762c9..137a0fd1c 100644 --- a/src/textual/widgets/_placeholder.py +++ b/src/textual/widgets/_placeholder.py @@ -3,7 +3,6 @@ from __future__ import annotations from itertools import cycle from .. import events -from ..containers import Container from ..css._error_tools import friendly_list from ..reactive import Reactive, reactive from ..widget import Widget, RenderResult @@ -36,19 +35,10 @@ _LOREM_IPSUM_PLACEHOLDER_TEXT = "Lorem ipsum dolor sit amet, consectetur adipisc class InvalidPlaceholderVariant(Exception): - pass + """Raised when an invalid Placeholder variant is set.""" -class _PlaceholderLabel(Widget): - def __init__(self, content, classes) -> None: - super().__init__(classes=classes) - self._content = content - - def render(self) -> RenderResult: - return self._content - - -class Placeholder(Container): +class Placeholder(Widget): """A simple placeholder widget to use before you build your custom widgets. This placeholder has a couple of variants that show different data. @@ -63,44 +53,24 @@ class Placeholder(Container): DEFAULT_CSS = """ Placeholder { - align: center middle; + content-align: center middle; overflow: hidden; + color: $text; } Placeholder.-text { padding: 1; } - - _PlaceholderLabel { - height: auto; - color: $text; - } - - Placeholder > _PlaceholderLabel { - content-align: center middle; - } - - Placeholder.-default > _PlaceholderLabel.-size, - Placeholder.-default > _PlaceholderLabel.-text, - Placeholder.-size > _PlaceholderLabel.-default, - Placeholder.-size > _PlaceholderLabel.-text, - Placeholder.-text > _PlaceholderLabel.-default, - Placeholder.-text > _PlaceholderLabel.-size { - display: none; - } - - Placeholder.-default > _PlaceholderLabel.-default, - Placeholder.-size > _PlaceholderLabel.-size, - Placeholder.-text > _PlaceholderLabel.-text { - display: block; - } """ + # Consecutive placeholders get assigned consecutive colors. _COLORS = cycle(_PLACEHOLDER_BACKGROUND_COLORS) _SIZE_RENDER_TEMPLATE = "[b]{} x {}[/b]" variant: Reactive[PlaceholderVariant] = reactive("default") + _renderables: dict[PlaceholderVariant, RenderResult] + @classmethod def reset_color_cycle(cls) -> None: """Reset the placeholder background color cycle.""" @@ -128,27 +98,14 @@ class Placeholder(Container): classes (str | None, optional): A space separated string with the CSS classes of the placeholder, if any. Defaults to None. """ - # Create and cache labels for all the variants. - self._default_label = _PlaceholderLabel( - label if label else f"#{id}" if id else "Placeholder", - "-default", - ) - self._size_label = _PlaceholderLabel( - "", - "-size", - ) - self._text_label = _PlaceholderLabel( - "\n\n".join(_LOREM_IPSUM_PLACEHOLDER_TEXT for _ in range(5)), - "-text", - ) - super().__init__( - self._default_label, - self._size_label, - self._text_label, - name=name, - id=id, - classes=classes, - ) + # Create and cache renderables for all the variants. + self._renderables = { + "default": label if label else f"#{id}" if id else "Placeholder", + "size": "", + "text": "\n\n".join(_LOREM_IPSUM_PLACEHOLDER_TEXT for _ in range(5)), + } + + super().__init__(name=name, id=id, classes=classes) self.styles.background = f"{next(Placeholder._COLORS)} 50%" @@ -158,6 +115,9 @@ class Placeholder(Container): while next(self._variants_cycle) != self.variant: pass + def render(self) -> RenderResult: + return self._renderables[self.variant] + def cycle_variant(self) -> None: """Get the next variant in the cycle.""" self.variant = next(self._variants_cycle) @@ -183,6 +143,6 @@ class Placeholder(Container): def on_resize(self, event: events.Resize) -> None: """Update the placeholder "size" variant with the new placeholder size.""" - self._size_label._content = self._SIZE_RENDER_TEMPLATE.format(*self.size) + self._renderables["size"] = self._SIZE_RENDER_TEMPLATE.format(*self.size) if self.variant == "size": - self._size_label.refresh(layout=True) + self.refresh(layout=True) From d08699ff503551ef4a60a22a24df024245810e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:30:39 +0000 Subject: [PATCH 171/310] Update placeholder snapshot test. Although there was no visual difference in the output, the snapshot tool was complaining because there are now less things to draw on the screen, thus the snapshots looked different. Hence, the placeholder snapshot needed to be updated. --- .../__snapshots__/test_snapshots.ambr | 135 +++++++++--------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index 4a9464a81..d920e8d87 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -7800,145 +7800,142 @@ font-weight: 700; } - .terminal-2023815619-matrix { + .terminal-1570661136-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2023815619-title { + .terminal-1570661136-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2023815619-r1 { fill: #e8e0e7 } - .terminal-2023815619-r2 { fill: #c5c8c6 } - .terminal-2023815619-r3 { fill: #eae3e5 } - .terminal-2023815619-r4 { fill: #ede6e6 } - .terminal-2023815619-r5 { fill: #efe9e4 } - .terminal-2023815619-r6 { fill: #efeedf } - .terminal-2023815619-r7 { fill: #e9eee5 } - .terminal-2023815619-r8 { fill: #e4eee8 } - .terminal-2023815619-r9 { fill: #dfebed } - .terminal-2023815619-r10 { fill: #e2edeb } - .terminal-2023815619-r11 { fill: #e4eee8;font-weight: bold } - .terminal-2023815619-r12 { fill: #dfebed;font-weight: bold } - .terminal-2023815619-r13 { fill: #e3e6eb } - .terminal-2023815619-r14 { fill: #dfe9ed } - .terminal-2023815619-r15 { fill: #e3e6eb;font-weight: bold } - .terminal-2023815619-r16 { fill: #e6e3e9 } + .terminal-1570661136-r1 { fill: #c5c8c6 } + .terminal-1570661136-r2 { fill: #eae3e5 } + .terminal-1570661136-r3 { fill: #e8e0e7 } + .terminal-1570661136-r4 { fill: #efe9e4 } + .terminal-1570661136-r5 { fill: #ede6e6 } + .terminal-1570661136-r6 { fill: #efeedf } + .terminal-1570661136-r7 { fill: #e9eee5 } + .terminal-1570661136-r8 { fill: #e2edeb } + .terminal-1570661136-r9 { fill: #e4eee8;font-weight: bold } + .terminal-1570661136-r10 { fill: #dfebed;font-weight: bold } + .terminal-1570661136-r11 { fill: #dfe9ed } + .terminal-1570661136-r12 { fill: #e3e6eb;font-weight: bold } + .terminal-1570661136-r13 { fill: #e6e3e9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - PlaceholderApp + PlaceholderApp - - - - - Placeholder p2 here! - This is a custom label for p1. - #p4 - #p3#p5Placeholde - r - - Lorem ipsum dolor sit  - 26 x 6amet, consectetur 27 x 6 - adipiscing elit. Etiam  - feugiat ac elit sit amet  - - - Lorem ipsum dolor sit amet,  - consectetur adipiscing elit. Etiam 40 x 6 - feugiat ac elit sit amet accumsan.  - Suspendisse bibendum nec libero quis  - gravida. Phasellus id eleifend ligula. - Nullam imperdiet sem tellus, sed  - vehicula nisl faucibus sit amet. Lorem ipsum dolor sit amet,  - Praesent iaculis tempor ultricies. Sedconsectetur adipiscing elit. Etiam  - lacinia, tellus id rutrum lacinia, feugiat ac elit sit amet accumsan.  - sapien sapien congue mauris, sit amet Suspendisse bibendum nec libero quis  + + + + + Placeholder p2 here! + This is a custom label for p1. + #p4 + #p3#p5Placeholde + r + + Lorem ipsum dolor sit  + 26 x 6amet, consectetur 27 x 6 + adipiscing elit. Etiam  + feugiat ac elit sit amet  + + + Lorem ipsum dolor sit amet,  + consectetur adipiscing elit. Etiam 40 x 6 + feugiat ac elit sit amet accumsan.  + Suspendisse bibendum nec libero quis  + gravida. Phasellus id eleifend ligula. + Nullam imperdiet sem tellus, sed  + vehicula nisl faucibus sit amet. Lorem ipsum dolor sit amet,  + Praesent iaculis tempor ultricies. Sedconsectetur adipiscing elit. Etiam  + lacinia, tellus id rutrum lacinia, feugiat ac elit sit amet accumsan.  + sapien sapien congue mauris, sit amet Suspendisse bibendum nec libero quis  From 93453af00ed12acf028a3d59511723936ed42a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:31:34 +0000 Subject: [PATCH 172/310] Update changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eed95593..8da8e3b9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - The styles `scrollbar-background-active` and `scrollbar-color-hover` are no longer ignored https://github.com/Textualize/textual/pull/1480 +- The widget `Placeholder` can now have its width set to `auto` https://github.com/Textualize/textual/pull/1508 ## [0.9.1] - 2022-12-30 From ea8252cfcc83549b1e1791288b23e052551b163d Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sat, 7 Jan 2023 09:30:01 +0000 Subject: [PATCH 173/310] Run black over recent Tree tests Now that we're running black on tests... --- tests/tree/test_tree_node_children.py | 15 ++++++++++----- tests/tree/test_tree_node_label.py | 2 ++ tests/tree/test_tree_node_parent.py | 1 + 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/tree/test_tree_node_children.py b/tests/tree/test_tree_node_children.py index 5b4751745..eb5c949c0 100644 --- a/tests/tree/test_tree_node_children.py +++ b/tests/tree/test_tree_node_children.py @@ -1,6 +1,7 @@ import pytest from textual.widgets import Tree, TreeNode + def label_of(node: TreeNode[None]): """Get the label of a node as a string""" return str(node.label) @@ -8,17 +9,21 @@ def label_of(node: TreeNode[None]): def test_tree_node_children() -> None: """A node's children property should act like an immutable list.""" - CHILDREN=23 + CHILDREN = 23 tree = Tree[None]("Root") for child in range(CHILDREN): tree.root.add(str(child)) - assert len(tree.root.children)==CHILDREN + assert len(tree.root.children) == CHILDREN for child in range(CHILDREN): assert label_of(tree.root.children[child]) == str(child) assert label_of(tree.root.children[0]) == "0" - assert label_of(tree.root.children[-1]) == str(CHILDREN-1) - assert [label_of(node) for node in tree.root.children] == [str(n) for n in range(CHILDREN)] - assert [label_of(node) for node in tree.root.children[:2]] == [str(n) for n in range(2)] + assert label_of(tree.root.children[-1]) == str(CHILDREN - 1) + assert [label_of(node) for node in tree.root.children] == [ + str(n) for n in range(CHILDREN) + ] + assert [label_of(node) for node in tree.root.children[:2]] == [ + str(n) for n in range(2) + ] with pytest.raises(TypeError): tree.root.children[0] = tree.root.children[1] with pytest.raises(TypeError): diff --git a/tests/tree/test_tree_node_label.py b/tests/tree/test_tree_node_label.py index 55af8088e..e64fcf24d 100644 --- a/tests/tree/test_tree_node_label.py +++ b/tests/tree/test_tree_node_label.py @@ -1,6 +1,7 @@ from textual.widgets import Tree, TreeNode from rich.text import Text + def test_tree_node_label() -> None: """It should be possible to modify a TreeNode's label.""" node = TreeNode(Tree[None]("Xenomorph Lifecycle"), None, 0, "Facehugger") @@ -8,6 +9,7 @@ def test_tree_node_label() -> None: node.label = "Chestbuster" assert node.label == Text("Chestbuster") + def test_tree_node_label_via_tree() -> None: """It should be possible to modify a TreeNode's label when created via a Tree.""" tree = Tree[None]("Xenomorph Lifecycle") diff --git a/tests/tree/test_tree_node_parent.py b/tests/tree/test_tree_node_parent.py index 90353ea92..b9d85af43 100644 --- a/tests/tree/test_tree_node_parent.py +++ b/tests/tree/test_tree_node_parent.py @@ -1,5 +1,6 @@ from textual.widgets import TreeNode, Tree + def test_tree_node_parent() -> None: """It should be possible to access a TreeNode's parent.""" tree = Tree[None]("Anakin") From b8500de1e93102919e53012dcf7a4e81f2daaf37 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sat, 7 Jan 2023 09:32:43 +0000 Subject: [PATCH 174/310] Run black over recent immutable sequence view tests Now that we're running black on tests... --- tests/test_immutable_sequence_view.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/test_immutable_sequence_view.py b/tests/test_immutable_sequence_view.py index 5af7f5133..fd691798c 100644 --- a/tests/test_immutable_sequence_view.py +++ b/tests/test_immutable_sequence_view.py @@ -3,6 +3,7 @@ import pytest from typing import Sequence from textual._immutable_sequence_view import ImmutableSequenceView + def wrap(source: Sequence[int]) -> ImmutableSequenceView[int]: """Wrap a sequence of integers inside an immutable sequence view.""" return ImmutableSequenceView[int](source) @@ -24,7 +25,7 @@ def test_non_empty_immutable_sequence() -> None: def test_no_assign_to_immutable_sequence() -> None: """It should not be possible to assign into an immutable sequence.""" - tester = wrap([1,2,3,4,5]) + tester = wrap([1, 2, 3, 4, 5]) with pytest.raises(TypeError): tester[0] = 23 with pytest.raises(TypeError): @@ -33,7 +34,7 @@ def test_no_assign_to_immutable_sequence() -> None: def test_no_del_from_iummutable_sequence() -> None: """It should not be possible delete an item from an immutable sequence.""" - tester = wrap([1,2,3,4,5]) + tester = wrap([1, 2, 3, 4, 5]) with pytest.raises(TypeError): del tester[0] @@ -46,23 +47,23 @@ def test_get_item_from_immutable_sequence() -> None: def test_get_slice_from_immutable_sequence() -> None: """It should be possible to get a slice from an immutable sequence.""" - assert list(wrap(range(10))[0:2]) == [0,1] - assert list(wrap(range(10))[0:-1]) == [0,1,2,3,4,5,6,7,8] + assert list(wrap(range(10))[0:2]) == [0, 1] + assert list(wrap(range(10))[0:-1]) == [0, 1, 2, 3, 4, 5, 6, 7, 8] def test_immutable_sequence_contains() -> None: """It should be possible to see if an immutable sequence contains a value.""" - tester = wrap([1,2,3,4,5]) + tester = wrap([1, 2, 3, 4, 5]) assert 1 in tester assert 11 not in tester def test_immutable_sequence_index() -> None: - tester = wrap([1,2,3,4,5]) + tester = wrap([1, 2, 3, 4, 5]) assert tester.index(1) == 0 with pytest.raises(ValueError): _ = tester.index(11) def test_reverse_immutable_sequence() -> None: - assert list(reversed(wrap([1,2]))) == [2,1] + assert list(reversed(wrap([1, 2]))) == [2, 1] From af56d88a6d75b2f98628c5dab7cae331953b065d Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 5 Jan 2023 10:35:25 +0000 Subject: [PATCH 175/310] Add a public read-only parent property to TreeNode See #1397. --- CHANGELOG.md | 1 + src/textual/widgets/_tree.py | 5 +++++ tests/tree/test_tree_node_parent.py | 10 ++++++++++ 3 files changed, 16 insertions(+) create mode 100644 tests/tree/test_tree_node_parent.py diff --git a/CHANGELOG.md b/CHANGELOG.md index fa82c5ab1..f852ea6d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Added `TreeNode.parent` -- a read-only property for accessing a node's parent https://github.com/Textualize/textual/issues/1397 - Added public `TreeNode` label access via `TreeNode.label` https://github.com/Textualize/textual/issues/1396 ### Changed diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index e7ac669dc..39b63a037 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -121,6 +121,11 @@ class TreeNode(Generic[TreeDataType]): """NodeID: Get the node ID.""" return self._id + @property + def parent(self) -> TreeNode[TreeDataType] | None: + """TreeNode[TreeDataType] | None: The parent of the node.""" + return self._parent + @property def is_expanded(self) -> bool: """bool: Check if the node is expanded.""" diff --git a/tests/tree/test_tree_node_parent.py b/tests/tree/test_tree_node_parent.py new file mode 100644 index 000000000..90353ea92 --- /dev/null +++ b/tests/tree/test_tree_node_parent.py @@ -0,0 +1,10 @@ +from textual.widgets import TreeNode, Tree + +def test_tree_node_parent() -> None: + """It should be possible to access a TreeNode's parent.""" + tree = Tree[None]("Anakin") + child = tree.root.add("Leia") + grandchild = child.add("Ben") + assert tree.root.parent is None + assert grandchild.parent == child + assert child.parent == tree.root From ad6a716d099b56e50e81fb693464f7cff63457c6 Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Fri, 6 Jan 2023 14:32:23 +0000 Subject: [PATCH 176/310] Fix mouse01 example background transparency --- docs/examples/guide/input/mouse01.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/examples/guide/input/mouse01.css b/docs/examples/guide/input/mouse01.css index 95685d023..a37245093 100644 --- a/docs/examples/guide/input/mouse01.css +++ b/docs/examples/guide/input/mouse01.css @@ -6,17 +6,17 @@ TextLog { layer: log; } -PlayArea { - background: transparent; +PlayArea { + opacity: 0%; layer: ball; - + } Ball { layer: ball; width: auto; height: 1; background: $secondary; - border: tall $secondary; + border: tall $secondary; color: $background; box-sizing: content-box; text-style: bold; From 2c827e18d096095a1078ec70919047d4a00217d3 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 5 Jan 2023 21:11:14 +0000 Subject: [PATCH 177/310] Add a generic immutable sequence wrapper class In anticipation of satisfying #1398, this adds a generic immutable sequence wrapper class. The idea being that it can be used to wrap up a list or similar, that you don't want the caller to modify. This commit aims to get the basics down for this, and also adds a minimal set of unit tests. --- src/textual/_collections.py | 65 +++++++++++++++++++++++++++++ tests/test_collections.py | 81 +++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 src/textual/_collections.py create mode 100644 tests/test_collections.py diff --git a/src/textual/_collections.py b/src/textual/_collections.py new file mode 100644 index 000000000..09b8af206 --- /dev/null +++ b/src/textual/_collections.py @@ -0,0 +1,65 @@ +"""Provides collection-based utility code.""" + +from __future__ import annotations +from typing import Generic, TypeVar, Iterator, overload, Iterable + +T = TypeVar("T") + + +class ImmutableSequence(Generic[T]): + """Class to wrap a sequence of some sort, but not allow modification.""" + + def __init__(self, wrap: Iterable[T]) -> None: + """Initialise the immutable sequence. + + Args: + wrap (Iterable[T]): The iterable value being wrapped. + """ + self._list = list(wrap) + + @overload + def __getitem__(self, index: int) -> T: + ... + + @overload + def __getitem__(self, index: slice) -> ImmutableSequence[T]: + ... + + def __getitem__(self, index: int | slice) -> T | ImmutableSequence[T]: + return ( + self._list[index] + if isinstance(index, int) + else ImmutableSequence[T](self._list[index]) + ) + + def __iter__(self) -> Iterator[T]: + return iter(self._list) + + def __len__(self) -> int: + return len(self._list) + + def __length_hint__(self) -> int: + return len(self) + + def __bool__(self) -> bool: + return bool(len(self)) + + def __contains__(self, item: T) -> bool: + return item in self._list + + def index(self, item: T) -> int: + """Return the index of the given item. + + Args: + item (T): The item to find in the sequence. + + Returns: + int: The index of the item in the sequence. + + Raises: + ValueError: If the item is not in the sequence. + """ + return self._list.index(item) + + def __reversed__(self) -> Iterator[T]: + return reversed(self._list) diff --git a/tests/test_collections.py b/tests/test_collections.py new file mode 100644 index 000000000..cd4d0f71e --- /dev/null +++ b/tests/test_collections.py @@ -0,0 +1,81 @@ +import pytest + +from typing import Iterable +from textual._collections import ImmutableSequence + +def wrap(source: Iterable[int]) -> ImmutableSequence[int]: + """Wrap an itertable of integers inside an immutable sequence.""" + return ImmutableSequence[int](source) + + +def test_empty_immutable_sequence() -> None: + """An empty immutable sequence should act as anticipated.""" + assert len(wrap([])) == 0 + assert bool(wrap([])) is False + assert list(wrap([])) == [] + + +def test_non_empty_immutable_sequence() -> None: + """A non-empty immutable sequence should act as anticipated.""" + assert len(wrap([0])) == 1 + assert bool(wrap([0])) is True + assert list(wrap([0])) == [0] + + +def test_immutable_sequence_from_empty_iter() -> None: + """An immutable sequence around an empty iterator should act as anticipated.""" + assert len(wrap([])) == 0 + assert bool(wrap([])) is False + assert list(wrap(iter([]))) == [] + + +def test_immutable_sequence_from_non_empty_iter() -> None: + """An immutable sequence around a non-empty iterator should act as anticipated.""" + assert len(wrap(range(23))) == 23 + assert bool(wrap(range(23))) is True + assert list(wrap(range(23))) == list(range(23)) + + +def test_no_assign_to_immutable_sequence() -> None: + """It should not be possible to assign into an immutable sequence.""" + tester = wrap([1,2,3,4,5]) + with pytest.raises(TypeError): + tester[0] = 23 + with pytest.raises(TypeError): + tester[0:3] = 23 + + +def test_no_del_from_iummutable_sequence() -> None: + """It should not be possible delete an item from an immutable sequence.""" + tester = wrap([1,2,3,4,5]) + with pytest.raises(TypeError): + del tester[0] + + +def test_get_item_from_immutable_sequence() -> None: + """It should be possible to get an item from an immutable sequence.""" + assert wrap(range(10))[0] == 0 + assert wrap(range(10))[-1] == 9 + +def test_get_slice_from_immutable_sequence() -> None: + """It should be possible to get a slice from an immutable sequence.""" + assert list(wrap(range(10))[0:2]) == [0,1] + assert list(wrap(range(10))[0:-1]) == [0,1,2,3,4,5,6,7,8] + + +def test_immutable_sequence_contains() -> None: + """It should be possible to see if an immutable sequence contains a value.""" + tester = wrap([1,2,3,4,5]) + assert 1 in tester + assert 11 not in tester + + +def test_immutable_sequence_index() -> None: + tester = wrap([1,2,3,4,5]) + assert tester.index(1) == 0 + with pytest.raises(ValueError): + _ = tester.index(11) + + +def test_reverse_immutable_sequence() -> None: + assert list(reversed(wrap([1,2]))) == [2,1] From 0029470b4b11ad65bd516756ac924f01ca48f7c8 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 5 Jan 2023 21:24:47 +0000 Subject: [PATCH 178/310] Add read-only access to the children of a TreeNode See #1398. --- CHANGELOG.md | 1 + src/textual/widgets/_tree.py | 10 +++++++++ tests/tree/test_tree_node_children.py | 32 +++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 tests/tree/test_tree_node_children.py diff --git a/CHANGELOG.md b/CHANGELOG.md index f852ea6d5..64be93e2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `TreeNode.parent` -- a read-only property for accessing a node's parent https://github.com/Textualize/textual/issues/1397 - Added public `TreeNode` label access via `TreeNode.label` https://github.com/Textualize/textual/issues/1396 +- Added read-only public access to the children of a `TreeNode` via `TreeNode.children` https://github.com/Textualize/textual/issues/1398 ### Changed diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index 39b63a037..9fb5639ec 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -14,6 +14,7 @@ from .._loop import loop_last from .._segment_tools import line_crop, line_pad from .._types import MessageTarget from .._typing import TypeAlias +from .._collections import ImmutableSequence from ..binding import Binding from ..geometry import Region, Size, clamp from ..message import Message @@ -53,6 +54,10 @@ class _TreeLine(Generic[TreeDataType]): return guides +class TreeNodes(ImmutableSequence["TreeNode[TreeDataType]"]): + """An immutable collection of `TreeNode`.""" + + @rich.repr.auto class TreeNode(Generic[TreeDataType]): """An object that represents a "node" in a tree control.""" @@ -91,6 +96,11 @@ class TreeNode(Generic[TreeDataType]): self._selected_ = False self._updates += 1 + @property + def children(self) -> TreeNodes[TreeDataType]: + """TreeNodes[TreeDataType]: The child nodes of a TreeNode.""" + return TreeNodes(self._children) + @property def line(self) -> int: """int: Get the line number for this node, or -1 if it is not displayed.""" diff --git a/tests/tree/test_tree_node_children.py b/tests/tree/test_tree_node_children.py new file mode 100644 index 000000000..22df664db --- /dev/null +++ b/tests/tree/test_tree_node_children.py @@ -0,0 +1,32 @@ +import pytest +from textual.widgets import Tree, TreeNode + +def label_of(node: TreeNode[None]): + """Get the label of a node. + + TODO: This is just a helper function to reduce the number of type + errors, which can and will be remove once this code is merged with a + version of main that also has the TreeNode.label PR merged. + """ + return str(node._label) + + +def test_tree_node_children() -> None: + """A node's children property should act like an immutable list.""" + CHILDREN=23 + tree = Tree[None]("Root") + for child in range(CHILDREN): + tree.root.add(str(child)) + assert len(tree.root.children)==CHILDREN + for child in range(CHILDREN): + assert label_of(tree.root.children[child]) == str(child) + assert label_of(tree.root.children[0]) == "0" + assert label_of(tree.root.children[-1]) == str(CHILDREN-1) + assert [label_of(node) for node in tree.root.children] == [str(n) for n in range(CHILDREN)] + assert [label_of(node) for node in tree.root.children[:2]] == [str(n) for n in range(2)] + with pytest.raises(TypeError): + tree.root.children[0] = tree.root.children[1] + with pytest.raises(TypeError): + del tree.root.children[0] + with pytest.raises(TypeError): + del tree.root.children[0:2] From d95957188b723ef8fde1c8cc7f07426b729d3bd6 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 5 Jan 2023 23:06:42 +0000 Subject: [PATCH 179/310] Simplify ImmutableSequence.__bool__ --- src/textual/_collections.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/_collections.py b/src/textual/_collections.py index 09b8af206..cbdef05b2 100644 --- a/src/textual/_collections.py +++ b/src/textual/_collections.py @@ -42,7 +42,7 @@ class ImmutableSequence(Generic[T]): return len(self) def __bool__(self) -> bool: - return bool(len(self)) + return bool(self._list) def __contains__(self, item: T) -> bool: return item in self._list From 948cb6676f762351734e9fc0c99778063ee48f10 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 5 Jan 2023 23:16:51 +0000 Subject: [PATCH 180/310] Focus less on it being a list and more a thing that's wrapped --- src/textual/_collections.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/textual/_collections.py b/src/textual/_collections.py index cbdef05b2..91def6bde 100644 --- a/src/textual/_collections.py +++ b/src/textual/_collections.py @@ -15,7 +15,7 @@ class ImmutableSequence(Generic[T]): Args: wrap (Iterable[T]): The iterable value being wrapped. """ - self._list = list(wrap) + self._wrap = tuple(wrap) @overload def __getitem__(self, index: int) -> T: @@ -27,25 +27,25 @@ class ImmutableSequence(Generic[T]): def __getitem__(self, index: int | slice) -> T | ImmutableSequence[T]: return ( - self._list[index] + self._wrap[index] if isinstance(index, int) - else ImmutableSequence[T](self._list[index]) + else ImmutableSequence[T](self._wrap[index]) ) def __iter__(self) -> Iterator[T]: - return iter(self._list) + return iter(self._wrap) def __len__(self) -> int: - return len(self._list) + return len(self._wrap) def __length_hint__(self) -> int: return len(self) def __bool__(self) -> bool: - return bool(self._list) + return bool(self._wrap) def __contains__(self, item: T) -> bool: - return item in self._list + return item in self._wrap def index(self, item: T) -> int: """Return the index of the given item. @@ -59,7 +59,7 @@ class ImmutableSequence(Generic[T]): Raises: ValueError: If the item is not in the sequence. """ - return self._list.index(item) + return self._wrap.index(item) def __reversed__(self) -> Iterator[T]: - return reversed(self._list) + return reversed(self._wrap) From 274bb634caac540f0c1760faa8c2c5cfe0f97b6a Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Fri, 6 Jan 2023 06:01:59 +0000 Subject: [PATCH 181/310] Only convert to an indexable sequence if absolutely necessary --- src/textual/_collections.py | 4 ++-- tests/test_collections.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/textual/_collections.py b/src/textual/_collections.py index 91def6bde..2b3f0ec16 100644 --- a/src/textual/_collections.py +++ b/src/textual/_collections.py @@ -1,7 +1,7 @@ """Provides collection-based utility code.""" from __future__ import annotations -from typing import Generic, TypeVar, Iterator, overload, Iterable +from typing import Generic, TypeVar, Iterator, overload, Iterable, Sequence T = TypeVar("T") @@ -15,7 +15,7 @@ class ImmutableSequence(Generic[T]): Args: wrap (Iterable[T]): The iterable value being wrapped. """ - self._wrap = tuple(wrap) + self._wrap = wrap if isinstance(wrap, Sequence) else tuple(wrap) @overload def __getitem__(self, index: int) -> T: diff --git a/tests/test_collections.py b/tests/test_collections.py index cd4d0f71e..de2cbf686 100644 --- a/tests/test_collections.py +++ b/tests/test_collections.py @@ -57,10 +57,11 @@ def test_get_item_from_immutable_sequence() -> None: assert wrap(range(10))[0] == 0 assert wrap(range(10))[-1] == 9 + def test_get_slice_from_immutable_sequence() -> None: """It should be possible to get a slice from an immutable sequence.""" - assert list(wrap(range(10))[0:2]) == [0,1] - assert list(wrap(range(10))[0:-1]) == [0,1,2,3,4,5,6,7,8] + assert list(wrap(iter(range(10)))[0:2]) == [0,1] + assert list(wrap(iter(range(10)))[0:-1]) == [0,1,2,3,4,5,6,7,8] def test_immutable_sequence_contains() -> None: From 12c61291505f27dcea4fc0d5a6b499380c1ad467 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Fri, 6 Jan 2023 06:14:49 +0000 Subject: [PATCH 182/310] Tweak the unit tests for ImmutableSequence Make it 100% clear that the tests that are about wrapping iterators actually are wrapping iterators. --- tests/test_collections.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_collections.py b/tests/test_collections.py index de2cbf686..56d44cd70 100644 --- a/tests/test_collections.py +++ b/tests/test_collections.py @@ -24,16 +24,16 @@ def test_non_empty_immutable_sequence() -> None: def test_immutable_sequence_from_empty_iter() -> None: """An immutable sequence around an empty iterator should act as anticipated.""" - assert len(wrap([])) == 0 - assert bool(wrap([])) is False + assert len(wrap(iter([]))) == 0 + assert bool(wrap(iter([]))) is False assert list(wrap(iter([]))) == [] def test_immutable_sequence_from_non_empty_iter() -> None: """An immutable sequence around a non-empty iterator should act as anticipated.""" - assert len(wrap(range(23))) == 23 - assert bool(wrap(range(23))) is True - assert list(wrap(range(23))) == list(range(23)) + assert len(wrap(iter(range(23)))) == 23 + assert bool(wrap(iter(range(23)))) is True + assert list(wrap(iter(range(23)))) == list(range(23)) def test_no_assign_to_immutable_sequence() -> None: @@ -60,8 +60,8 @@ def test_get_item_from_immutable_sequence() -> None: def test_get_slice_from_immutable_sequence() -> None: """It should be possible to get a slice from an immutable sequence.""" - assert list(wrap(iter(range(10)))[0:2]) == [0,1] - assert list(wrap(iter(range(10)))[0:-1]) == [0,1,2,3,4,5,6,7,8] + assert list(wrap(range(10))[0:2]) == [0,1] + assert list(wrap(range(10))[0:-1]) == [0,1,2,3,4,5,6,7,8] def test_immutable_sequence_contains() -> None: From 53df47b4015fefe4dd3d3f747f54e3393523b41f Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Fri, 6 Jan 2023 12:23:51 +0000 Subject: [PATCH 183/310] Rename ImmutableSequence to ImmutableSequenceView Also, in doing so, drop support for unrolling iterators and making them into indexable sequences. See the following feedback: https://github.com/Textualize/textual/pull/1495#pullrequestreview-1238616797 https://github.com/Textualize/textual/pull/1495#issuecomment-1373553580 --- ...ections.py => _immutable_sequence_view.py} | 18 +++++++------- src/textual/widgets/_tree.py | 4 ++-- ...ons.py => test_immutable_sequence_view.py} | 24 ++++--------------- 3 files changed, 16 insertions(+), 30 deletions(-) rename src/textual/{_collections.py => _immutable_sequence_view.py} (72%) rename tests/{test_collections.py => test_immutable_sequence_view.py} (69%) diff --git a/src/textual/_collections.py b/src/textual/_immutable_sequence_view.py similarity index 72% rename from src/textual/_collections.py rename to src/textual/_immutable_sequence_view.py index 2b3f0ec16..39815d96b 100644 --- a/src/textual/_collections.py +++ b/src/textual/_immutable_sequence_view.py @@ -1,35 +1,35 @@ -"""Provides collection-based utility code.""" +"""Provides an immutable sequence view class.""" from __future__ import annotations -from typing import Generic, TypeVar, Iterator, overload, Iterable, Sequence +from typing import Generic, TypeVar, Iterator, overload, Sequence T = TypeVar("T") -class ImmutableSequence(Generic[T]): +class ImmutableSequenceView(Generic[T]): """Class to wrap a sequence of some sort, but not allow modification.""" - def __init__(self, wrap: Iterable[T]) -> None: + def __init__(self, wrap: Sequence[T]) -> None: """Initialise the immutable sequence. Args: - wrap (Iterable[T]): The iterable value being wrapped. + wrap (Sequence[T]): The sequence being wrapped. """ - self._wrap = wrap if isinstance(wrap, Sequence) else tuple(wrap) + self._wrap = wrap @overload def __getitem__(self, index: int) -> T: ... @overload - def __getitem__(self, index: slice) -> ImmutableSequence[T]: + def __getitem__(self, index: slice) -> ImmutableSequenceView[T]: ... - def __getitem__(self, index: int | slice) -> T | ImmutableSequence[T]: + def __getitem__(self, index: int | slice) -> T | ImmutableSequenceView[T]: return ( self._wrap[index] if isinstance(index, int) - else ImmutableSequence[T](self._wrap[index]) + else ImmutableSequenceView[T](self._wrap[index]) ) def __iter__(self) -> Iterator[T]: diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index 9fb5639ec..866a4d7ce 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -14,7 +14,7 @@ from .._loop import loop_last from .._segment_tools import line_crop, line_pad from .._types import MessageTarget from .._typing import TypeAlias -from .._collections import ImmutableSequence +from .._immutable_sequence_view import ImmutableSequenceView from ..binding import Binding from ..geometry import Region, Size, clamp from ..message import Message @@ -54,7 +54,7 @@ class _TreeLine(Generic[TreeDataType]): return guides -class TreeNodes(ImmutableSequence["TreeNode[TreeDataType]"]): +class TreeNodes(ImmutableSequenceView["TreeNode[TreeDataType]"]): """An immutable collection of `TreeNode`.""" diff --git a/tests/test_collections.py b/tests/test_immutable_sequence_view.py similarity index 69% rename from tests/test_collections.py rename to tests/test_immutable_sequence_view.py index 56d44cd70..5af7f5133 100644 --- a/tests/test_collections.py +++ b/tests/test_immutable_sequence_view.py @@ -1,11 +1,11 @@ import pytest -from typing import Iterable -from textual._collections import ImmutableSequence +from typing import Sequence +from textual._immutable_sequence_view import ImmutableSequenceView -def wrap(source: Iterable[int]) -> ImmutableSequence[int]: - """Wrap an itertable of integers inside an immutable sequence.""" - return ImmutableSequence[int](source) +def wrap(source: Sequence[int]) -> ImmutableSequenceView[int]: + """Wrap a sequence of integers inside an immutable sequence view.""" + return ImmutableSequenceView[int](source) def test_empty_immutable_sequence() -> None: @@ -22,20 +22,6 @@ def test_non_empty_immutable_sequence() -> None: assert list(wrap([0])) == [0] -def test_immutable_sequence_from_empty_iter() -> None: - """An immutable sequence around an empty iterator should act as anticipated.""" - assert len(wrap(iter([]))) == 0 - assert bool(wrap(iter([]))) is False - assert list(wrap(iter([]))) == [] - - -def test_immutable_sequence_from_non_empty_iter() -> None: - """An immutable sequence around a non-empty iterator should act as anticipated.""" - assert len(wrap(iter(range(23)))) == 23 - assert bool(wrap(iter(range(23)))) is True - assert list(wrap(iter(range(23)))) == list(range(23)) - - def test_no_assign_to_immutable_sequence() -> None: """It should not be possible to assign into an immutable sequence.""" tester = wrap([1,2,3,4,5]) From 2bf41fe4280fc562f010a45791c1edb774bd8120 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Fri, 6 Jan 2023 12:31:27 +0000 Subject: [PATCH 184/310] Correct docstring for the return type of index --- src/textual/_immutable_sequence_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/_immutable_sequence_view.py b/src/textual/_immutable_sequence_view.py index 39815d96b..21cc22fef 100644 --- a/src/textual/_immutable_sequence_view.py +++ b/src/textual/_immutable_sequence_view.py @@ -54,7 +54,7 @@ class ImmutableSequenceView(Generic[T]): item (T): The item to find in the sequence. Returns: - int: The index of the item in the sequence. + T: The index of the item in the sequence. Raises: ValueError: If the item is not in the sequence. From 1e8162e8d0420d7ed1fec9b6ea8f77deb304654d Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Fri, 6 Jan 2023 12:31:59 +0000 Subject: [PATCH 185/310] Add support for star/stop values on index See https://github.com/Textualize/textual/pull/1495#pullrequestreview-1238616797 --- src/textual/_immutable_sequence_view.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/textual/_immutable_sequence_view.py b/src/textual/_immutable_sequence_view.py index 21cc22fef..27283dbc4 100644 --- a/src/textual/_immutable_sequence_view.py +++ b/src/textual/_immutable_sequence_view.py @@ -1,6 +1,7 @@ """Provides an immutable sequence view class.""" from __future__ import annotations +from sys import maxsize from typing import Generic, TypeVar, Iterator, overload, Sequence T = TypeVar("T") @@ -47,11 +48,13 @@ class ImmutableSequenceView(Generic[T]): def __contains__(self, item: T) -> bool: return item in self._wrap - def index(self, item: T) -> int: + def index(self, item: T, start: int = 0, stop: int = maxsize) -> int: """Return the index of the given item. Args: item (T): The item to find in the sequence. + start (int, optional): Optional start location. + stop (int, optional): Optional stop location. Returns: T: The index of the item in the sequence. @@ -59,7 +62,7 @@ class ImmutableSequenceView(Generic[T]): Raises: ValueError: If the item is not in the sequence. """ - return self._wrap.index(item) + return self._wrap.index(item, start, stop) def __reversed__(self) -> Iterator[T]: return reversed(self._wrap) From c22cc30e71c65384e7d237e8d012d3ab2427ff1f Mon Sep 17 00:00:00 2001 From: darrenburns Date: Fri, 6 Jan 2023 16:28:34 +0000 Subject: [PATCH 186/310] Ensure pretty traceback for error in Widget compose method (#1505) * Ensure pretty traceback for error in Widget compose method * Fail fast and pretty tracebacks for Widget compose errors --- CHANGELOG.md | 1 + src/textual/widget.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64be93e2f..6eed95593 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - `MouseScrollUp` and `MouseScrollDown` now inherit from `MouseEvent` and have attached modifier keys. https://github.com/Textualize/textual/pull/1458 +- Fail-fast and print pretty tracebacks for Widget compose errors https://github.com/Textualize/textual/pull/1505 ### Fixed diff --git a/src/textual/widget.py b/src/textual/widget.py index 65ff0bc0d..185d18a64 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -33,6 +33,7 @@ from rich.measure import Measurement from rich.segment import Segment from rich.style import Style from rich.text import Text +from rich.traceback import Traceback from . import errors, events, messages from ._animator import DEFAULT_EASING, Animatable, BoundAnimator, EasingFunction @@ -2333,7 +2334,10 @@ class Widget(DOMNode): raise TypeError( f"{self!r} compose() returned an invalid response; {error}" ) from None - await self.mount(*widgets) + except Exception: + self.app.panic(Traceback()) + else: + await self.mount(*widgets) def _on_mount(self, event: events.Mount) -> None: if self.styles.overflow_y == "scroll": From 94e8b777793b2a7264f6fa8af1985cc88dc517b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:25:01 +0000 Subject: [PATCH 187/310] Simplify Placeholder implementation. Instead of creating a private widget that is the only child of 'Placeholder', that was inheriting from 'Container', simplify everything. 'Placeholder' now inherits directly from 'Widget' and it saves a dictionary with its renderables per variant, instead of deferring that to the child '_PlaceholderLabel'. --- src/textual/widgets/_placeholder.py | 80 ++++++++--------------------- 1 file changed, 20 insertions(+), 60 deletions(-) diff --git a/src/textual/widgets/_placeholder.py b/src/textual/widgets/_placeholder.py index eabe762c9..137a0fd1c 100644 --- a/src/textual/widgets/_placeholder.py +++ b/src/textual/widgets/_placeholder.py @@ -3,7 +3,6 @@ from __future__ import annotations from itertools import cycle from .. import events -from ..containers import Container from ..css._error_tools import friendly_list from ..reactive import Reactive, reactive from ..widget import Widget, RenderResult @@ -36,19 +35,10 @@ _LOREM_IPSUM_PLACEHOLDER_TEXT = "Lorem ipsum dolor sit amet, consectetur adipisc class InvalidPlaceholderVariant(Exception): - pass + """Raised when an invalid Placeholder variant is set.""" -class _PlaceholderLabel(Widget): - def __init__(self, content, classes) -> None: - super().__init__(classes=classes) - self._content = content - - def render(self) -> RenderResult: - return self._content - - -class Placeholder(Container): +class Placeholder(Widget): """A simple placeholder widget to use before you build your custom widgets. This placeholder has a couple of variants that show different data. @@ -63,44 +53,24 @@ class Placeholder(Container): DEFAULT_CSS = """ Placeholder { - align: center middle; + content-align: center middle; overflow: hidden; + color: $text; } Placeholder.-text { padding: 1; } - - _PlaceholderLabel { - height: auto; - color: $text; - } - - Placeholder > _PlaceholderLabel { - content-align: center middle; - } - - Placeholder.-default > _PlaceholderLabel.-size, - Placeholder.-default > _PlaceholderLabel.-text, - Placeholder.-size > _PlaceholderLabel.-default, - Placeholder.-size > _PlaceholderLabel.-text, - Placeholder.-text > _PlaceholderLabel.-default, - Placeholder.-text > _PlaceholderLabel.-size { - display: none; - } - - Placeholder.-default > _PlaceholderLabel.-default, - Placeholder.-size > _PlaceholderLabel.-size, - Placeholder.-text > _PlaceholderLabel.-text { - display: block; - } """ + # Consecutive placeholders get assigned consecutive colors. _COLORS = cycle(_PLACEHOLDER_BACKGROUND_COLORS) _SIZE_RENDER_TEMPLATE = "[b]{} x {}[/b]" variant: Reactive[PlaceholderVariant] = reactive("default") + _renderables: dict[PlaceholderVariant, RenderResult] + @classmethod def reset_color_cycle(cls) -> None: """Reset the placeholder background color cycle.""" @@ -128,27 +98,14 @@ class Placeholder(Container): classes (str | None, optional): A space separated string with the CSS classes of the placeholder, if any. Defaults to None. """ - # Create and cache labels for all the variants. - self._default_label = _PlaceholderLabel( - label if label else f"#{id}" if id else "Placeholder", - "-default", - ) - self._size_label = _PlaceholderLabel( - "", - "-size", - ) - self._text_label = _PlaceholderLabel( - "\n\n".join(_LOREM_IPSUM_PLACEHOLDER_TEXT for _ in range(5)), - "-text", - ) - super().__init__( - self._default_label, - self._size_label, - self._text_label, - name=name, - id=id, - classes=classes, - ) + # Create and cache renderables for all the variants. + self._renderables = { + "default": label if label else f"#{id}" if id else "Placeholder", + "size": "", + "text": "\n\n".join(_LOREM_IPSUM_PLACEHOLDER_TEXT for _ in range(5)), + } + + super().__init__(name=name, id=id, classes=classes) self.styles.background = f"{next(Placeholder._COLORS)} 50%" @@ -158,6 +115,9 @@ class Placeholder(Container): while next(self._variants_cycle) != self.variant: pass + def render(self) -> RenderResult: + return self._renderables[self.variant] + def cycle_variant(self) -> None: """Get the next variant in the cycle.""" self.variant = next(self._variants_cycle) @@ -183,6 +143,6 @@ class Placeholder(Container): def on_resize(self, event: events.Resize) -> None: """Update the placeholder "size" variant with the new placeholder size.""" - self._size_label._content = self._SIZE_RENDER_TEMPLATE.format(*self.size) + self._renderables["size"] = self._SIZE_RENDER_TEMPLATE.format(*self.size) if self.variant == "size": - self._size_label.refresh(layout=True) + self.refresh(layout=True) From 4c3eb3e021e906d4be03f3ec45e2f957898e39dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:30:39 +0000 Subject: [PATCH 188/310] Update placeholder snapshot test. Although there was no visual difference in the output, the snapshot tool was complaining because there are now less things to draw on the screen, thus the snapshots looked different. Hence, the placeholder snapshot needed to be updated. --- .../__snapshots__/test_snapshots.ambr | 135 +++++++++--------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index 4a9464a81..d920e8d87 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -7800,145 +7800,142 @@ font-weight: 700; } - .terminal-2023815619-matrix { + .terminal-1570661136-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2023815619-title { + .terminal-1570661136-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2023815619-r1 { fill: #e8e0e7 } - .terminal-2023815619-r2 { fill: #c5c8c6 } - .terminal-2023815619-r3 { fill: #eae3e5 } - .terminal-2023815619-r4 { fill: #ede6e6 } - .terminal-2023815619-r5 { fill: #efe9e4 } - .terminal-2023815619-r6 { fill: #efeedf } - .terminal-2023815619-r7 { fill: #e9eee5 } - .terminal-2023815619-r8 { fill: #e4eee8 } - .terminal-2023815619-r9 { fill: #dfebed } - .terminal-2023815619-r10 { fill: #e2edeb } - .terminal-2023815619-r11 { fill: #e4eee8;font-weight: bold } - .terminal-2023815619-r12 { fill: #dfebed;font-weight: bold } - .terminal-2023815619-r13 { fill: #e3e6eb } - .terminal-2023815619-r14 { fill: #dfe9ed } - .terminal-2023815619-r15 { fill: #e3e6eb;font-weight: bold } - .terminal-2023815619-r16 { fill: #e6e3e9 } + .terminal-1570661136-r1 { fill: #c5c8c6 } + .terminal-1570661136-r2 { fill: #eae3e5 } + .terminal-1570661136-r3 { fill: #e8e0e7 } + .terminal-1570661136-r4 { fill: #efe9e4 } + .terminal-1570661136-r5 { fill: #ede6e6 } + .terminal-1570661136-r6 { fill: #efeedf } + .terminal-1570661136-r7 { fill: #e9eee5 } + .terminal-1570661136-r8 { fill: #e2edeb } + .terminal-1570661136-r9 { fill: #e4eee8;font-weight: bold } + .terminal-1570661136-r10 { fill: #dfebed;font-weight: bold } + .terminal-1570661136-r11 { fill: #dfe9ed } + .terminal-1570661136-r12 { fill: #e3e6eb;font-weight: bold } + .terminal-1570661136-r13 { fill: #e6e3e9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - PlaceholderApp + PlaceholderApp - - - - - Placeholder p2 here! - This is a custom label for p1. - #p4 - #p3#p5Placeholde - r - - Lorem ipsum dolor sit  - 26 x 6amet, consectetur 27 x 6 - adipiscing elit. Etiam  - feugiat ac elit sit amet  - - - Lorem ipsum dolor sit amet,  - consectetur adipiscing elit. Etiam 40 x 6 - feugiat ac elit sit amet accumsan.  - Suspendisse bibendum nec libero quis  - gravida. Phasellus id eleifend ligula. - Nullam imperdiet sem tellus, sed  - vehicula nisl faucibus sit amet. Lorem ipsum dolor sit amet,  - Praesent iaculis tempor ultricies. Sedconsectetur adipiscing elit. Etiam  - lacinia, tellus id rutrum lacinia, feugiat ac elit sit amet accumsan.  - sapien sapien congue mauris, sit amet Suspendisse bibendum nec libero quis  + + + + + Placeholder p2 here! + This is a custom label for p1. + #p4 + #p3#p5Placeholde + r + + Lorem ipsum dolor sit  + 26 x 6amet, consectetur 27 x 6 + adipiscing elit. Etiam  + feugiat ac elit sit amet  + + + Lorem ipsum dolor sit amet,  + consectetur adipiscing elit. Etiam 40 x 6 + feugiat ac elit sit amet accumsan.  + Suspendisse bibendum nec libero quis  + gravida. Phasellus id eleifend ligula. + Nullam imperdiet sem tellus, sed  + vehicula nisl faucibus sit amet. Lorem ipsum dolor sit amet,  + Praesent iaculis tempor ultricies. Sedconsectetur adipiscing elit. Etiam  + lacinia, tellus id rutrum lacinia, feugiat ac elit sit amet accumsan.  + sapien sapien congue mauris, sit amet Suspendisse bibendum nec libero quis  From e37b6e8ccaf9ea88c1cbcf945d7fa3fa99a169d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Sat, 7 Jan 2023 09:39:08 +0000 Subject: [PATCH 189/310] Update changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eed95593..8da8e3b9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - The styles `scrollbar-background-active` and `scrollbar-color-hover` are no longer ignored https://github.com/Textualize/textual/pull/1480 +- The widget `Placeholder` can now have its width set to `auto` https://github.com/Textualize/textual/pull/1508 ## [0.9.1] - 2022-12-30 From 8de6d8fd69e70569b70c50daae2ff55771b4c743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Sat, 7 Jan 2023 09:40:03 +0000 Subject: [PATCH 190/310] Add new width comparison example. --- docs/examples/styles/width_comparison.css | 39 +++++++++++++++++++++++ docs/examples/styles/width_comparison.py | 28 ++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 docs/examples/styles/width_comparison.css create mode 100644 docs/examples/styles/width_comparison.py diff --git a/docs/examples/styles/width_comparison.css b/docs/examples/styles/width_comparison.css new file mode 100644 index 000000000..2e2f0512d --- /dev/null +++ b/docs/examples/styles/width_comparison.css @@ -0,0 +1,39 @@ +#cells { + width: 9; /* (1)! */ +} +#percent { + width: 12.5%; /* (2)! */ +} +#w { + width: 10w; /* (3)! */ +} +#h { + width: 25h; /* (4)! */ +} +#vw { + width: 15vw; /* (5)! */ +} +#vh { + width: 25vh; /* (6)! */ +} +#auto { + width: auto; /* (7)! */ +} +#fr1 { + width: 1fr; /* (8)! */ +} +#fr3 { + width: 3fr; /* (9)! */ +} + +Screen { + layers: ruler; +} + +Ruler { + layer: ruler; + dock: bottom; + overflow: hidden; + height: 1; + background: $accent; +} diff --git a/docs/examples/styles/width_comparison.py b/docs/examples/styles/width_comparison.py new file mode 100644 index 000000000..2971425b6 --- /dev/null +++ b/docs/examples/styles/width_comparison.py @@ -0,0 +1,28 @@ +from textual.app import App +from textual.containers import Horizontal +from textual.widgets import Placeholder, Label, Static + + +class Ruler(Static): + def compose(self): + ruler_text = "····•" * 100 + yield Label(ruler_text) + + +class HeightComparisonApp(App): + def compose(self): + yield Horizontal( + Placeholder(id="cells"), # (1)! + Placeholder(id="percent"), + Placeholder(id="w"), + Placeholder(id="h"), + Placeholder(id="vw"), + Placeholder(id="vh"), + Placeholder(id="auto"), + Placeholder(id="fr1"), + Placeholder(id="fr3"), + ) + yield Ruler() + + +app = HeightComparisonApp(css_path="width_comparison.css") From 08baaf11f30fce69935a31be7cbcedf5893f128e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Sat, 7 Jan 2023 09:40:32 +0000 Subject: [PATCH 191/310] Refactor width reference. --- docs/styles/width.md | 58 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/docs/styles/width.md b/docs/styles/width.md index 499048483..dd349a5ae 100644 --- a/docs/styles/width.md +++ b/docs/styles/width.md @@ -1,14 +1,17 @@ # Width -The `width` rule sets a widget's width. By default, it sets the width of the content area, but if `box-sizing` is set to `border-box` it sets the width of the border area. +The `width` rule sets a widget's width. ## Syntax -``` -width: ; -``` +--8<-- "docs/snippets/syntax_block_start.md" +width: <scalar>; +--8<-- "docs/snippets/syntax_block_end.md" -## Example +The style `width` needs a [``](../../css_types/scalar) to determine the horizontal length of the width. +By default, it sets the width of the content area, but if [`box-sizing`](./box_sizing) is set to `border-box` it sets the width of the border area. + +## Examples This example adds a widget with 50% width of the screen. @@ -29,6 +32,45 @@ This example adds a widget with 50% width of the screen. ```{.textual path="docs/examples/styles/width.py"} ``` +--- + + +=== "Output" + + ```{.textual path="docs/examples/styles/width_comparison.py" lines=24 columns=80} + ``` + +=== "width_comparison.py" + + ```py hl_lines="15-23" + --8<-- "docs/examples/styles/width_comparison.py" + ``` + + 1. The id of the placeholder identifies which unit will be used to set the width of the widget. + +=== "width_comparison.css" + + ```css hl_lines="2 5 8 11 14 17 20 23 26" + --8<-- "docs/examples/styles/width_comparison.css" + ``` + + 1. This sets the width to 9 columns. + 2. This sets the width to 12.5% of the space made available by the container. + The container is 80 columns wide, so 12.5% of 80 is 10. + 3. This sets the width to 10% of the width of the direct container, which is the `Horizontal` container. + Because it expands to fit all of the terminal, the width of the `Horizontal` is 80 and 10% of 80 is 8. + 4. This sets the width to 25% of the height of the direct container, which is the `Horizontal` container. + Because it expands to fit all of the terminal, the height of the `Horizontal` is 24 and 25% of 24 is 6. + 5. This sets the width to 15% of the viewport width, which is 80. + 15% of 80 is 12. + 6. This sets the width to 25% of the viewport height, which is 24. + 25% of 24 is 6. + 7. This sets the width of the placeholder to be the optimal size that fits the content without scrolling. + Because the content is the string `"#auto"`, the placeholder has its width set to 5. + 8. This sets the width to `1fr`, which means this placeholder will have a third of the width of a placeholder with `3fr`. + 9. This sets the width to `3fr`, which means this placeholder will have triple the width of a placeholder with `1fr`. + + ## CSS ```sass @@ -45,7 +87,7 @@ width: auto ## Python ```python -self.styles.width = 10 -self.styles.width = "50% -self.styles.width = "auto" +widget.styles.width = 10 +widget.styles.width = "50% +widget.styles.width = "auto" ``` From aad41b8de04445dc9c0b36af58c04b3fe44c799f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Sat, 7 Jan 2023 09:44:28 +0000 Subject: [PATCH 192/310] Fix height example. [skip ci] --- docs/examples/styles/height_comparison.css | 11 ++++++++--- docs/examples/styles/height_comparison.py | 8 ++++---- docs/styles/height.md | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/docs/examples/styles/height_comparison.css b/docs/examples/styles/height_comparison.css index ca2737e07..10902dda5 100644 --- a/docs/examples/styles/height_comparison.css +++ b/docs/examples/styles/height_comparison.css @@ -11,7 +11,7 @@ height: 12.5h; /* (4)! */ } #vw { - height: 7.5vw; /* (5)! */ + height: 6.25vw; /* (5)! */ } #vh { height: 12.5vh; /* (6)! */ @@ -26,9 +26,14 @@ height: 2fr; /* (9)! */ } -VerticalRuler { +Screen { + layers: ruler; +} + +Ruler { + layer: ruler; dock: right; overflow: hidden; - width: auto; + width: 1; background: $accent; } diff --git a/docs/examples/styles/height_comparison.py b/docs/examples/styles/height_comparison.py index b24f257aa..c679a68e6 100644 --- a/docs/examples/styles/height_comparison.py +++ b/docs/examples/styles/height_comparison.py @@ -3,16 +3,16 @@ from textual.containers import Vertical from textual.widgets import Placeholder, Label, Static -class VerticalRuler(Static): +class Ruler(Static): def compose(self): - ruler_text = "\n".join(map(str, range(1, 100))) + ruler_text = "·\n·\n·\n·\n•\n" * 100 yield Label(ruler_text) class HeightComparisonApp(App): def compose(self): yield Vertical( - Placeholder(id="cells"), # (1)! + Placeholder(id="cells"), # (1)! Placeholder(id="percent"), Placeholder(id="w"), Placeholder(id="h"), @@ -22,7 +22,7 @@ class HeightComparisonApp(App): Placeholder(id="fr1"), Placeholder(id="fr2"), ) - yield VerticalRuler() + yield Ruler() app = HeightComparisonApp(css_path="height_comparison.css") diff --git a/docs/styles/height.md b/docs/styles/height.md index 97dd82524..437f69b8d 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -59,7 +59,7 @@ Open the CSS file tab to see the comments that explain how each height is comput 2. This sets the height to 12.5% of the space made available by the container. The container is 24 lines tall, so 12.5% of 24 is 3. 3. This sets the height to 5% of the width of the direct container, which is the `Vertical` container. Because it expands to fit all of the terminal, the width of the `Vertical` is 80 and 5% of 80 is 4. 4. This sets the height to 12.5% of the height of the direct container, which is the `Vertical` container. Because it expands to fit all of the terminal, the height of the `Vertical` is 24 and 12.5% of 24 is 3. - 5. This sets the height to 7.5% of the viewport width, which is 80. 7.5% of 80 is 5.6 which gets truncated to 5. + 5. This sets the height to 6.25% of the viewport width, which is 80. 6.25% of 80 is 5. 6. This sets the height to 12.5% of the viewport height, which is 24. 12.5% of 24 is 3. 7. This sets the height of the placeholder to be the optimal size that fits the content without scrolling. Because the content only spans one line, the placeholder has its height set to 1. From c0d7f7cebf4d51cb9324c3ad507bae61769d0083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Sat, 7 Jan 2023 09:47:56 +0000 Subject: [PATCH 193/310] Add note about Textual limitation. --- docs/styles/border.md | 4 ++++ docs/styles/outline.md | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/styles/border.md b/docs/styles/border.md index 5439b3ec7..c471f580d 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -2,6 +2,10 @@ The `border` rule enables the drawing of a box around a widget. +!!! note + + Due to a Textual limitation, [`border`](./border.md) and [`outline`](./outline.md) cannot coexist in the same edge of a widget. + ## Syntax --8<-- "docs/snippets/syntax_block_start.md" diff --git a/docs/styles/outline.md b/docs/styles/outline.md index 24ca78c7b..3b4c63764 100644 --- a/docs/styles/outline.md +++ b/docs/styles/outline.md @@ -2,9 +2,9 @@ The `outline` rule enables the drawing of a box around the content of a widget, which means the outline is drawn _over_ the content area. -!!! warning +!!! note - Not to be confused with [`border`](./border.md). + Due to a Textual limitation, [`border`](./border.md) and [`outline`](./outline.md) cannot coexist in the same edge of a widget. ## Syntax From fd9c1de3e2254b7cc83b0ffa0d95a9eeea83f805 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sat, 7 Jan 2023 14:04:52 +0000 Subject: [PATCH 194/310] Call from thread method --- src/textual/app.py | 68 ++++++++++++++++++++++++++++++++++++--- tests/test_concurrency.py | 50 ++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 tests/test_concurrency.py diff --git a/src/textual/app.py b/src/textual/app.py index b207bbd02..df38c6091 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1,6 +1,8 @@ from __future__ import annotations import asyncio +from concurrent.futures import Future +from functools import partial import inspect import io import os @@ -18,6 +20,7 @@ from time import perf_counter from typing import ( TYPE_CHECKING, Any, + Awaitable, Callable, Generic, Iterable, @@ -206,6 +209,8 @@ class _WriterThread(threading.Thread): CSSPathType = Union[str, PurePath, List[Union[str, PurePath]], None] +CallThreadReturnType = TypeVar("CallThreadReturnType") + @rich.repr.auto class App(Generic[ReturnType], DOMNode): @@ -353,6 +358,8 @@ class App(Generic[ReturnType], DOMNode): else: self.devtools = DevtoolsClient() + self._loop: asyncio.AbstractEventLoop | None = None + self._thread_id: int = 0 self._return_value: ReturnType | None = None self._exit = False @@ -604,6 +611,51 @@ class App(Generic[ReturnType], DOMNode): except Exception as error: self._handle_exception(error) + def call_from_thread( + self, + callback: Callable[..., CallThreadReturnType | Awaitable[CallThreadReturnType]], + *args, + **kwargs, + ) -> CallThreadReturnType: + """Run a callback from another thread. + + Like asyncio apps in general, Textual apps are not thread-safe. If you call methods + or set attributes on Textual objects from a thread, you may get unpredictable results. + + This method will ensure that your code is ran within the correct context. + + Args: + callback (Callable): A callable to run. + *args: Arguments to the callback. + **kwargs: Keyword arguments for the callback. + + Raises: + RuntimeError: If the app isn't running or if this method is called from the same + thread where the app is running. + """ + + if self._loop is None: + raise RuntimeError("App is not running") + + if self._thread_id == threading.get_ident(): + raise RuntimeError( + "The `call_from_thread` method must run in a different thread from the app" + ) + + callback_with_args = partial(callback, *args, **kwargs) + + async def run_callback() -> CallThreadReturnType: + """Run the callback, set the result or error on the future.""" + self._set_active() + return await invoke(callback_with_args) + + # Post the message to the main loop + future: Future[Any] = asyncio.run_coroutine_threadsafe( + run_callback(), loop=self._loop + ) + result = future.result() + return result + def action_toggle_dark(self) -> None: """Action to toggle dark mode.""" self.dark = not self.dark @@ -874,11 +926,17 @@ class App(Generic[ReturnType], DOMNode): async def run_app() -> None: """Run the app.""" - await self.run_async( - headless=headless, - size=size, - auto_pilot=auto_pilot, - ) + self._loop = asyncio.get_running_loop() + self._thread_id = threading.get_ident() + try: + await self.run_async( + headless=headless, + size=size, + auto_pilot=auto_pilot, + ) + finally: + self._loop = None + self._thread_id = 0 if _ASYNCIO_GET_EVENT_LOOP_IS_DEPRECATED: # N.B. This doesn't work with Python<3.10, as we end up with 2 event loops: diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py new file mode 100644 index 000000000..88a3ccf4b --- /dev/null +++ b/tests/test_concurrency.py @@ -0,0 +1,50 @@ +import pytest + +from threading import Thread +from textual.app import App, ComposeResult +from textual.widgets import TextLog + + +def test_call_from_thread_app_not_running(): + app = App() + + # Should fail if app is not running + with pytest.raises(RuntimeError): + app.call_from_thread(print) + + +def test_call_from_thread(): + class BackgroundThread(Thread): + """A background thread which will modify app in some way.""" + + def __init__(self, app: App) -> None: + self.app = app + super().__init__() + + def run(self) -> None: + def write_stuff(text: str) -> None: + """Write stuff to a widget.""" + self.app.query_one(TextLog).write(text) + + self.app.call_from_thread(write_stuff, "Hello") + # Exit the app with a code we can assert + self.app.call_from_thread(self.app.exit, 123) + + class ThreadTestApp(App): + """Trivial app with a single widget.""" + + def compose(self) -> ComposeResult: + yield TextLog() + + def on_ready(self) -> None: + """Launch a thread which will modify the app.""" + try: + self.call_from_thread(print) + except RuntimeError as error: + self._runtime_error = error + BackgroundThread(self).start() + + app = ThreadTestApp() + result = app.run(headless=True, size=(80, 24)) + assert isinstance(app._runtime_error, RuntimeError) + assert result == 123 From 249c2f319f00e1a9987fa59124048dfc6390f154 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sat, 7 Jan 2023 14:05:46 +0000 Subject: [PATCH 195/310] typing --- src/textual/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/app.py b/src/textual/app.py index df38c6091..89da6aaf6 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -650,7 +650,7 @@ class App(Generic[ReturnType], DOMNode): return await invoke(callback_with_args) # Post the message to the main loop - future: Future[Any] = asyncio.run_coroutine_threadsafe( + future: Future[CallThreadReturnType] = asyncio.run_coroutine_threadsafe( run_callback(), loop=self._loop ) result = future.result() From e11f563123581f898df1067f3457b46048c1152f Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sat, 7 Jan 2023 14:24:17 +0000 Subject: [PATCH 196/310] docstrings --- tests/test_concurrency.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index 88a3ccf4b..c73418f2f 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -14,6 +14,8 @@ def test_call_from_thread_app_not_running(): def test_call_from_thread(): + """Test the call_from_thread method.""" + class BackgroundThread(Thread): """A background thread which will modify app in some way.""" @@ -41,6 +43,7 @@ def test_call_from_thread(): try: self.call_from_thread(print) except RuntimeError as error: + # Calling this from the same thread as the app is an error self._runtime_error = error BackgroundThread(self).start() From 90d38cd0dac9a75532594f7bba8e426397149c0e Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sat, 7 Jan 2023 22:45:38 +0000 Subject: [PATCH 197/310] WIP: devlog blog post about looking for help with Textual Work in progress. First rough draft of ideas, committing and pushing to remote as backup for the night. --- docs/blog/posts/looking-for-help.md | 262 ++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 docs/blog/posts/looking-for-help.md diff --git a/docs/blog/posts/looking-for-help.md b/docs/blog/posts/looking-for-help.md new file mode 100644 index 000000000..23022da2b --- /dev/null +++ b/docs/blog/posts/looking-for-help.md @@ -0,0 +1,262 @@ +--- +draft: true +date: 2023-01-07 +categories: + - DevLog +authors: + - davep +--- + +# So you're looking for a wee bit of Textual help... + +## Introduction + +!!! quote + + Patience, Highlander. You have done well. But it'll take time. You are + generations being born and dying. You are at one with all living things. + Each man's thoughts and dreams are yours to know. You have power beyond + imagination. Use it well, my friend. Don't lose your head. + + Juan Sánchez Villalobos Ramírez, Chief metallurgist to King Charles V of Spain + +As of the time of writing, I'm a handful of days off having been with +Textualize for 3 months. It's been fun, and educational, and every bit as +engaging as I'd hoped, and more. One thing I hadn't quite prepared for +though, but which I really love, is how so many other people are learning +Textual along with me! + + + +Even in those three months the library has changed and expanded quite a lot, +and it continues to do so. Meanwhile, more and more people are turning up +and using the framework; you can see this online in social media, blogs and +of course [in the ever-growing list of projects on GitHub which depend on +Textual](https://github.com/Textualize/textual/network/dependents). + +This inevitably means there's a lot of people getting to grips with a new +tool, and one that is still a bit of a moving target. This in turn means +lots of people are coming to us to get help. + +As I've watched this happen I've noticed a few patterns emerging. Some of +these good or neutral, some... let's just say not really beneficial to those +seeking the help, or to those trying to provide the help. So I wanted to +write a little bit about the different ways you can get help with Textual +and your Textual-based projects, and to also try and encourage people to +take the most helpful and positive approach to getting that help. + +Now, before I go on, I want to make something *very* clear: I'm writing this +as an individual. This is my own personal view, and my own advice from me to +anyone who wishes to take it. It's not Textual (the project) or Textualize +(the company) policy, rules or guidelines. This is just some ageing hacker's +take on how best to go about asking for help, informed by years of asking +for and also providing help in email, on Usenet, on forums, etc. + +Or, put another way, if what you read in here seems sensible to you, I +figure we'll likely have already hit it off over on GitHub or in the Discord +sever. ;-) + +## Where to go for help + +At this point this is almost a bit of an FAQ itself, so I thought I'd +address it here: where's the best place to ask for help about Textual, and +what's the difference between GitHub Issues, Discussions and our Discord +server? + +I'd suggest thinking of them like this: + +### Discord + +You have a question, or need help with something, and perhaps you could do +with a reply as soon as possible. But, and this is the **really important +part**, it doesn't matter if you don't get a response. If you're in this +situation then the Discord server is possibly a good place to start. If +you're lucky someone will be hanging about who can help out. + +I can't speak for anyone else, but keep this in mind: when I look in on +Discord I tend not to go scrolling back much to see if anything has been +missed. If something catches my eye, I'll try and reply, but if it +doesn't... well, it's mostly an instant chat thing so I don't dive too +deeply back in time. + +My own advice would be to treat Discord as an ephemeral resource. It happens +in the moment but fades away pretty quickly. It's like knocking on a +friend's door to see if they're in. If they're not in, you might leave them +a note, which is sort of like going to... + +### GitHub + +On the other hand, if you have a question or need some help or something +where you want to stand a good chance of the Textual developers (amongst +others) seeing it and responding, I'd recommend that GitHub is the place to +go. Dropping something into the discussions there, or leaving an issue, +ensures it'll get seen. It won't get lost. + +As for which you should use -- a discussion or an issue -- I'd suggest this: +if you need help with something, or you want to check your understanding of +something, or you just want to be sure something is a problem before taking +it further, a discussion might be the best thing. On the other hand, if +you've got a clear bug or feature request on your hands, an issue makes a +lot of sense. + +Don't worry if you're not sure which camp your question or whatever falls +into though; go with what you think is right. There's no harm done either +way (I may move an issue to a discussion first before replying, if it's +really just a request for help -- but that's mostly so everyone can benefit +from finding it in the right place later on down the line). + +## The dos and don'ts of getting help + +Now on to the fun part. This is where I get a bit preachy. Ish. Kinda. A +little bit. Again, please remember, this isn't a set of rules, this isn't a +set of official guidelines, this is just a bunch of *"if you want my advice, +and I know you didn't ask but you've read this far so you actually sort of +did don't say I didn't warn you!"* waffle. + +This isn't going to be an exhaustive collection, far from it. But I feel +these are some important highlights. + +### Do... + +When looking for help, in any of the locations mentioned above, I'd totally +encourage: + +#### Be clear and detailed + +Too much detail is almost always way better than not enough. *"My program +didn't run"*, often even with some of the code supplied, is so much harder +to help than *"I ran this code I'm posting here, and I expected this +particular outcome, and I expected it because I'd read this particular thing +in the docs and had comprehended it to mean this, but instead the outcome +was this exception here, and I'm a but stuck -- can someone offer some +pointers?"* + +The former approach means there often ends up having to be a back and forth +which can last a long time, and which can sometimes be frustrating for the +person asking. Manage frustration: be clear, tell us everything you can. + +#### Say what resources you've used already + +If you've read the potions of the documentation that relate to what you're +trying to do, it's going to be really helpful if you say so. If you don't, +it might be assumed you haven't and you may end up being pointed at them. + +So, please, if you've checked the documentation, looked in the FAQ, done a +search of past issues or discussions or perhaps even done a search on the +Discord server... please say so. + +#### Be polite + +This one can go a long way when looking for help. Look, I get it, +programming is bloody frustrating at times. We've all rage-quit some code at +some point, I'm sure. It's likely going to be your moment of greatest +frustration when you go looking for help. But if you turn up looking for +help acting all grumpy and stuff it's not going to come over well. Folk are +less likely to be motivated to lend a hand to someone who seems rather +annoyed. + +If you throw in a please and thank-you here and there that makes it all the +better. + +#### Fully consider the replies + +You could find yourself getting a reply that you're sure won't help at all. +That's fair. But be sure to fully consider it first. Perhaps you missed the +obvious along the way and this is 100% the course correction you'd +unknowingly come looking for in the first place. Sure, the person replying +might have totally misunderstood what was being asked, or might be giving a +wrong answer (it me! I've totally done that and will again!), but even then +a reply along the lines of *"I'm not sure that's what I'm looking for, +because..."* gets everyone to the solution faster than *"lol nah"*. + +#### Entertain what might seem like odd questions + +Aye, I get it, being asked questions when you're looking for an *answer* can +be a bit frustrating. But if you find yourself on the receiving end of a +small series of questions about your question, keep this in mind: Textual is +still rather new and still developing and it's possible that what you're +trying to do isn't the correct way to do that thing. To the person looking +to help you it may seem to them you have an [XY +problem](https://en.wikipedia.org/wiki/XY_problem). + +Entertaining those questions might just get you to the real solution to your +problem. + +#### Allow for language differences + +You don't need me to tell you that a project such as Textual has a global +audience. With that rather obvious fact comes the other fact that we don't +all share the same first language. So, please, as much as possible, try and +allow for that. If someone is trying to help you out, and they make it clear +they're struggling to follow you, keep this in mind. + +#### Acknowledge the answer + +I suppose this is a variation on "be polite" (really, a thanks can go a long +way), but there's more to this than a friendly acknowledgement. If someone +has gone to the trouble of offering some help, it's helpful to everyone who +comes after you to acknowledge if it worked or not. That way a future +help-seeker will know if the answer they're reading stands a chance of being +the right one. + +### Don't... + +Okay, now for a bot of old-hacker finger-wagging. Here's a few things I'd +personally discourage: + +#### Lack patience + +Sure, it can be annoying. You're in your flow, you've got a neat idea for a +thing you want to build, you're stuck on one particular thing and you really +need help right now! Thing is, that's unlikely to happen. Badgering +individuals, or a whole resource, to reply right now, or complaining that +it's been `$TIME_PERIOD` since you asked and nobody has replied... that's +just going to make people less likely to reply. + +#### Unnecessarily tag individuals + +This one often goes hand in hand with the "lack patience" thing: Be it +asking on Discord, or in GitHub issues, discussions or even PRs, +unnecessarily tagging individuals is a bit rude. Speaking for myself and +only myself: I *love* helping folk with Textual. If I could help everyone +all the time the moment they have a problem, I would. But it doesn't work +like that. There's any number of reasons I might not be responding to a +particular request, including but not limited to (here I'm talking +personally because I don't want to speak for anyone else, but I'm sure I'm +not alone here): + +- I have a job. Sure, my job is (in part) Textual, but there's more to it + than that particular issue. I might be doing other stuff. +- I have my own projects to work on too. I like coding for fun as well (or + writing preaching old dude blog posts like this I guess, but you get the + idea). +- I actually have other interests outside of work hours so I might actually + be out doing a 10k in the local glen, or battling headcrabs in VR, or + something. +- Housework. :-/ + +You get the idea though. So while I'm off having a well-rounded life, it's +not good to get unnecessarily intrusive alerts to something that either a) +doesn't actually directly involve me or b) could wait. + +#### Seek personal support + +Again, I'm going to speak totally for myself here, but I also feel the +general case is polite for all: there's a lot of good support resources +available already; sending DMs on Discord or Twitter or in the Fediverse, +looking for direct personal support, isn't really the best way to get help. +Using those resources is absolutely the *best* way to get that help. Why's +it a bad idea to dive into DMs? Here's some reasons I think it's not a good +idea: + +- It's a variation on "unnecessarily tagging individuals". +- You're short-changing yourself when it comes to getting help. If you ask + somewhere more public you're asking a much bigger audience, who + collectively have more time, more knowledge and more experience than a + single individual. +- Following on from that, any answers can be (politely) fact-checked or + enhanced by that audience, resulting in a better chance of getting the + best help possible. +- The next seeker-of-help gets to miss out on your question and the answer. + If asked and answered in public, it's a record that can help someone else + in the future. From a242d4b6c57322eef328dea42bc2631f9da1fffa Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sat, 7 Jan 2023 22:50:35 +0000 Subject: [PATCH 198/310] Fix blog typo The first of many, I'm sure. --- docs/blog/posts/looking-for-help.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/blog/posts/looking-for-help.md b/docs/blog/posts/looking-for-help.md index 23022da2b..2da46f021 100644 --- a/docs/blog/posts/looking-for-help.md +++ b/docs/blog/posts/looking-for-help.md @@ -201,7 +201,7 @@ the right one. ### Don't... -Okay, now for a bot of old-hacker finger-wagging. Here's a few things I'd +Okay, now for a bit of old-hacker finger-wagging. Here's a few things I'd personally discourage: #### Lack patience From a3601cf0becd6aebcee16c43be52ccb2fadc57a3 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sat, 7 Jan 2023 22:52:16 +0000 Subject: [PATCH 199/310] Fix blog typo The second of many, I'm sure. --- docs/blog/posts/looking-for-help.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/blog/posts/looking-for-help.md b/docs/blog/posts/looking-for-help.md index 2da46f021..e7d759c96 100644 --- a/docs/blog/posts/looking-for-help.md +++ b/docs/blog/posts/looking-for-help.md @@ -128,7 +128,7 @@ didn't run"*, often even with some of the code supplied, is so much harder to help than *"I ran this code I'm posting here, and I expected this particular outcome, and I expected it because I'd read this particular thing in the docs and had comprehended it to mean this, but instead the outcome -was this exception here, and I'm a but stuck -- can someone offer some +was this exception here, and I'm a bit stuck -- can someone offer some pointers?"* The former approach means there often ends up having to be a back and forth From b13fc3d5b64bc4413dfc3a9854b4ebea627e106a Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 8 Jan 2023 16:20:15 +0000 Subject: [PATCH 200/310] snapshot --- src/textual/_compositor.py | 10 +- src/textual/widget.py | 23 ++- .../__snapshots__/test_snapshots.ambr | 162 +++++++++--------- 3 files changed, 106 insertions(+), 89 deletions(-) diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index 1e7ab1603..a941aaacd 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -25,6 +25,7 @@ from rich.style import Style from . import errors from ._cells import cell_len from ._loop import loop_last +from ._profile import timer from .strip import Strip from ._typing import TypeAlias from .geometry import NULL_OFFSET, Offset, Region, Size @@ -253,7 +254,9 @@ class Compositor: # Keep a copy of the old map because we're going to compare it with the update old_map = self.map.copy() old_widgets = old_map.keys() - map, widgets = self._arrange_root(parent, size) + + with timer("arrange"): + map, widgets = self._arrange_root(parent, size) new_widgets = map.keys() @@ -268,10 +271,12 @@ class Compositor: screen = size.region + changes = map.items() ^ old_map.items() + # Widgets with changed size resized_widgets = { widget - for widget, (region, *_) in map.items() + for widget, (region, *_) in changes if widget in old_widgets and old_map[widget].region.size != region.size } @@ -279,7 +284,6 @@ class Compositor: # i.e. if something is moved / deleted / added if screen not in self._dirty_regions: - changes = map.items() ^ old_map.items() regions = { region for region in ( diff --git a/src/textual/widget.py b/src/textual/widget.py index 185d18a64..735d74003 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -43,6 +43,7 @@ from ._easing import DEFAULT_SCROLL_EASING from ._layout import Layout from ._segment_tools import align_lines from ._styles_cache import StylesCache +from ._profile import timer from .actions import SkipAction from .await_remove import AwaitRemove from .binding import Binding @@ -804,13 +805,17 @@ class Widget(DOMNode): def watch_scroll_x(self, new_value: float) -> None: if self.show_horizontal_scrollbar: - self.horizontal_scrollbar.position = int(new_value) - self.refresh(layout=True, repaint=False) + new_position = int(round(new_value)) + if self.horizontal_scrollbar.position != new_position: + self.horizontal_scrollbar.position = new_position + self._refresh_scroll() def watch_scroll_y(self, new_value: float) -> None: if self.show_vertical_scrollbar: - self.vertical_scrollbar.position = int(new_value) - self.refresh(layout=True, repaint=False) + new_position = int(round(new_value)) + if self.vertical_scrollbar.position != new_position: + self.vertical_scrollbar.position = new_position + self._refresh_scroll() def validate_scroll_x(self, value: float) -> float: return clamp(value, 0, self.max_scroll_x) @@ -2155,8 +2160,16 @@ class Widget(DOMNode): event._set_forwarded() await self.post_message(event) + def _refresh_scroll(self) -> None: + """Refreshes the scroll position.""" + self._layout_required = True + self.check_idle() + def refresh( - self, *regions: Region, repaint: bool = True, layout: bool = False + self, + *regions: Region, + repaint: bool = True, + layout: bool = False, ) -> None: """Initiate a refresh of the widget. diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index d920e8d87..3368ae9c2 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -4779,169 +4779,169 @@ font-weight: 700; } - .terminal-4040833233-matrix { + .terminal-2908062273-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4040833233-title { + .terminal-2908062273-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4040833233-r1 { fill: #c5c8c6 } - .terminal-4040833233-r2 { fill: #e3e3e3 } - .terminal-4040833233-r3 { fill: #e1e1e1 } - .terminal-4040833233-r4 { fill: #23568b } - .terminal-4040833233-r5 { fill: #e2e2e2 } - .terminal-4040833233-r6 { fill: #004578 } - .terminal-4040833233-r7 { fill: #14191f } - .terminal-4040833233-r8 { fill: #262626 } - .terminal-4040833233-r9 { fill: #e2e2e2;font-weight: bold;text-decoration: underline; } - .terminal-4040833233-r10 { fill: #e2e2e2;font-weight: bold } - .terminal-4040833233-r11 { fill: #7ae998 } - .terminal-4040833233-r12 { fill: #4ebf71;font-weight: bold } - .terminal-4040833233-r13 { fill: #008139 } - .terminal-4040833233-r14 { fill: #dde8f3;font-weight: bold } - .terminal-4040833233-r15 { fill: #ddedf9 } + .terminal-2908062273-r1 { fill: #c5c8c6 } + .terminal-2908062273-r2 { fill: #e3e3e3 } + .terminal-2908062273-r3 { fill: #e1e1e1 } + .terminal-2908062273-r4 { fill: #23568b } + .terminal-2908062273-r5 { fill: #e2e2e2 } + .terminal-2908062273-r6 { fill: #14191f } + .terminal-2908062273-r7 { fill: #004578 } + .terminal-2908062273-r8 { fill: #262626 } + .terminal-2908062273-r9 { fill: #e2e2e2;font-weight: bold;text-decoration: underline; } + .terminal-2908062273-r10 { fill: #e2e2e2;font-weight: bold } + .terminal-2908062273-r11 { fill: #7ae998 } + .terminal-2908062273-r12 { fill: #4ebf71;font-weight: bold } + .terminal-2908062273-r13 { fill: #008139 } + .terminal-2908062273-r14 { fill: #dde8f3;font-weight: bold } + .terminal-2908062273-r15 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - Textual Demo + Textual Demo - - - - Textual Demo - ▅▅ - - TOP - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▃ - - Widgets - Textual Demo - - Welcome! Textual is a framework for creating sophisticated - Rich contentapplications with the terminal. - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Start - CSS▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - - - - - - -                           Widgets                            -  CTRL+C  Quit  CTRL+B  Sidebar  CTRL+T  Toggle Dark mode  CTRL+S  Screenshot  F1  Notes  + + + + Textual Demo + ▅▅ + + TOP + + ▃▃ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Widgets + + Textual Demo + + Rich contentWelcome! Textual is a framework for creating sophisticated + applications with the terminal. + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + CSSStart + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + + + +  CTRL+C  Quit  CTRL+B  Sidebar  CTRL+T  Toggle Dark mode  CTRL+S  Screenshot  F1  Notes  From e8dc95351ebd5fcf632bfd9d2313d358b307e10a Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 8 Jan 2023 16:28:53 +0000 Subject: [PATCH 201/310] comment, remove debug --- CHANGELOG.md | 1 + src/textual/_compositor.py | 13 ++++--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8da8e3b9e..90bb8ddc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `MouseScrollUp` and `MouseScrollDown` now inherit from `MouseEvent` and have attached modifier keys. https://github.com/Textualize/textual/pull/1458 - Fail-fast and print pretty tracebacks for Widget compose errors https://github.com/Textualize/textual/pull/1505 +- Added Widget._refresh_scroll to avoid expensive layout when scrolling https://github.com/Textualize/textual/pull/1524 ### Fixed diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index a941aaacd..e7c9fe214 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -255,9 +255,7 @@ class Compositor: old_map = self.map.copy() old_widgets = old_map.keys() - with timer("arrange"): - map, widgets = self._arrange_root(parent, size) - + map, widgets = self._arrange_root(parent, size) new_widgets = map.keys() # Newly visible widgets @@ -269,8 +267,7 @@ class Compositor: self.map = map self.widgets = widgets - screen = size.region - + # Contains widgets + geometry for every widget that changed (added, removed, or updated) changes = map.items() ^ old_map.items() # Widgets with changed size @@ -280,10 +277,8 @@ class Compositor: if widget in old_widgets and old_map[widget].region.size != region.size } - # Gets pairs of tuples of (Widget, MapGeometry) which have changed - # i.e. if something is moved / deleted / added - - if screen not in self._dirty_regions: + screen_region = size.region + if screen_region not in self._dirty_regions: regions = { region for region in ( From 03a159e1c83efa5a2f3e2b8fa0c5cd35d2a632b7 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 8 Jan 2023 16:36:27 +0000 Subject: [PATCH 202/310] Remove timer import --- src/textual/_compositor.py | 1 - src/textual/widget.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index e7c9fe214..7522ddb53 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -25,7 +25,6 @@ from rich.style import Style from . import errors from ._cells import cell_len from ._loop import loop_last -from ._profile import timer from .strip import Strip from ._typing import TypeAlias from .geometry import NULL_OFFSET, Offset, Region, Size diff --git a/src/textual/widget.py b/src/textual/widget.py index 735d74003..e03d16712 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -43,7 +43,6 @@ from ._easing import DEFAULT_SCROLL_EASING from ._layout import Layout from ._segment_tools import align_lines from ._styles_cache import StylesCache -from ._profile import timer from .actions import SkipAction from .await_remove import AwaitRemove from .binding import Binding From 80a33c074bea81cefc89468636cdba57aa8427cd Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 8 Jan 2023 16:47:53 +0000 Subject: [PATCH 203/310] more accurate optimization --- src/textual/widget.py | 14 +- .../__snapshots__/test_snapshots.ambr | 162 +++++++++--------- 2 files changed, 87 insertions(+), 89 deletions(-) diff --git a/src/textual/widget.py b/src/textual/widget.py index e03d16712..60d1cad9c 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -802,18 +802,16 @@ class Widget(DOMNode): if self.auto_links: self.highlight_link_id = hover_style.link_id - def watch_scroll_x(self, new_value: float) -> None: + def watch_scroll_x(self, old_value: float, new_value: float) -> None: if self.show_horizontal_scrollbar: - new_position = int(round(new_value)) - if self.horizontal_scrollbar.position != new_position: - self.horizontal_scrollbar.position = new_position + self.horizontal_scrollbar.position = int(new_value) + if int(old_value) != int(new_value): self._refresh_scroll() - def watch_scroll_y(self, new_value: float) -> None: + def watch_scroll_y(self, old_value: float, new_value: float) -> None: if self.show_vertical_scrollbar: - new_position = int(round(new_value)) - if self.vertical_scrollbar.position != new_position: - self.vertical_scrollbar.position = new_position + self.vertical_scrollbar.position = int(new_value) + if int(old_value) != int(new_value): self._refresh_scroll() def validate_scroll_x(self, value: float) -> float: diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index 3368ae9c2..d920e8d87 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -4779,169 +4779,169 @@ font-weight: 700; } - .terminal-2908062273-matrix { + .terminal-4040833233-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2908062273-title { + .terminal-4040833233-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2908062273-r1 { fill: #c5c8c6 } - .terminal-2908062273-r2 { fill: #e3e3e3 } - .terminal-2908062273-r3 { fill: #e1e1e1 } - .terminal-2908062273-r4 { fill: #23568b } - .terminal-2908062273-r5 { fill: #e2e2e2 } - .terminal-2908062273-r6 { fill: #14191f } - .terminal-2908062273-r7 { fill: #004578 } - .terminal-2908062273-r8 { fill: #262626 } - .terminal-2908062273-r9 { fill: #e2e2e2;font-weight: bold;text-decoration: underline; } - .terminal-2908062273-r10 { fill: #e2e2e2;font-weight: bold } - .terminal-2908062273-r11 { fill: #7ae998 } - .terminal-2908062273-r12 { fill: #4ebf71;font-weight: bold } - .terminal-2908062273-r13 { fill: #008139 } - .terminal-2908062273-r14 { fill: #dde8f3;font-weight: bold } - .terminal-2908062273-r15 { fill: #ddedf9 } + .terminal-4040833233-r1 { fill: #c5c8c6 } + .terminal-4040833233-r2 { fill: #e3e3e3 } + .terminal-4040833233-r3 { fill: #e1e1e1 } + .terminal-4040833233-r4 { fill: #23568b } + .terminal-4040833233-r5 { fill: #e2e2e2 } + .terminal-4040833233-r6 { fill: #004578 } + .terminal-4040833233-r7 { fill: #14191f } + .terminal-4040833233-r8 { fill: #262626 } + .terminal-4040833233-r9 { fill: #e2e2e2;font-weight: bold;text-decoration: underline; } + .terminal-4040833233-r10 { fill: #e2e2e2;font-weight: bold } + .terminal-4040833233-r11 { fill: #7ae998 } + .terminal-4040833233-r12 { fill: #4ebf71;font-weight: bold } + .terminal-4040833233-r13 { fill: #008139 } + .terminal-4040833233-r14 { fill: #dde8f3;font-weight: bold } + .terminal-4040833233-r15 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - Textual Demo + Textual Demo - - - - Textual Demo - ▅▅ - - TOP - - ▃▃ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Widgets - - Textual Demo - - Rich contentWelcome! Textual is a framework for creating sophisticated - applications with the terminal. - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - CSSStart - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - - - - - - -  CTRL+C  Quit  CTRL+B  Sidebar  CTRL+T  Toggle Dark mode  CTRL+S  Screenshot  F1  Notes  + + + + Textual Demo + ▅▅ + + TOP + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▃ + + Widgets + Textual Demo + + Welcome! Textual is a framework for creating sophisticated + Rich contentapplications with the terminal. + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Start + CSS▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + + + +                           Widgets                            +  CTRL+C  Quit  CTRL+B  Sidebar  CTRL+T  Toggle Dark mode  CTRL+S  Screenshot  F1  Notes  From 958b6d143928bdbc36a3a34ee4857e24ed7b8a8a Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 8 Jan 2023 16:53:06 +0000 Subject: [PATCH 204/310] smoother animation with roundering --- src/textual/widget.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/textual/widget.py b/src/textual/widget.py index 60d1cad9c..8c3f7951d 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -804,14 +804,14 @@ class Widget(DOMNode): def watch_scroll_x(self, old_value: float, new_value: float) -> None: if self.show_horizontal_scrollbar: - self.horizontal_scrollbar.position = int(new_value) - if int(old_value) != int(new_value): + self.horizontal_scrollbar.position = round(new_value) + if round(old_value) != round(new_value): self._refresh_scroll() def watch_scroll_y(self, old_value: float, new_value: float) -> None: if self.show_vertical_scrollbar: - self.vertical_scrollbar.position = int(new_value) - if int(old_value) != int(new_value): + self.vertical_scrollbar.position = round(new_value) + if round(old_value) != round(new_value): self._refresh_scroll() def validate_scroll_x(self, value: float) -> float: @@ -1149,7 +1149,7 @@ class Widget(DOMNode): Returns: Offset: Offset a container has been scrolled by. """ - return Offset(int(self.scroll_x), int(self.scroll_y)) + return Offset(round(self.scroll_x), round(self.scroll_y)) @property def is_transparent(self) -> bool: From 244b1e333c4c9f498e008b46d4997ceab250d92b Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 8 Jan 2023 17:30:11 +0000 Subject: [PATCH 205/310] optimization --- src/textual/_compositor.py | 70 ++++++++++++++++++++------------------ src/textual/geometry.py | 5 ++- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index 7522ddb53..3c7fda165 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -390,43 +390,47 @@ class Compositor: ) widgets.update(arranged_widgets) - # An offset added to all placements - placement_offset = container_region.offset - placement_scroll_offset = placement_offset - widget.scroll_offset + if placements: + # An offset added to all placements + placement_offset = container_region.offset + placement_scroll_offset = ( + placement_offset - widget.scroll_offset + ) - _layers = widget.layers - layers_to_index = { - layer_name: index for index, layer_name in enumerate(_layers) - } - get_layer_index = layers_to_index.get + _layers = widget.layers + layers_to_index = { + layer_name: index + for index, layer_name in enumerate(_layers) + } + get_layer_index = layers_to_index.get - # Add all the widgets - for sub_region, margin, sub_widget, z, fixed in reversed( - placements - ): - # Combine regions with children to calculate the "virtual size" - if fixed: - widget_region = sub_region + placement_offset - else: - total_region = total_region.union( - sub_region.grow(spacing + margin) + # Add all the widgets + for sub_region, margin, sub_widget, z, fixed in reversed( + placements + ): + # Combine regions with children to calculate the "virtual size" + if fixed: + widget_region = sub_region + placement_offset + else: + total_region = total_region.union( + sub_region.grow(spacing).grow(margin) + ) + widget_region = sub_region + placement_scroll_offset + + widget_order = order + ( + (get_layer_index(sub_widget.layer, 0), z, layer_order), ) - widget_region = sub_region + placement_scroll_offset - widget_order = order + ( - (get_layer_index(sub_widget.layer, 0), z, layer_order), - ) - - add_widget( - sub_widget, - sub_region, - widget_region, - widget_order, - layer_order, - sub_clip, - visible, - ) - layer_order -= 1 + add_widget( + sub_widget, + sub_region, + widget_region, + widget_order, + layer_order, + sub_clip, + visible, + ) + layer_order -= 1 if visible: # Add any scrollbars diff --git a/src/textual/geometry.py b/src/textual/geometry.py index 9b5c09f03..17e938b1d 100644 --- a/src/textual/geometry.py +++ b/src/textual/geometry.py @@ -684,6 +684,7 @@ class Region(NamedTuple): ) return new_region + @lru_cache(maxsize=4096) def grow(self, margin: tuple[int, int, int, int]) -> Region: """Grow a region by adding spacing. @@ -704,6 +705,7 @@ class Region(NamedTuple): height=max(0, height + top + bottom), ) + @lru_cache(maxsize=4096) def shrink(self, margin: tuple[int, int, int, int]) -> Region: """Shrink a region by subtracting spacing. @@ -713,7 +715,8 @@ class Region(NamedTuple): Returns: Region: The new, smaller region. """ - + if not any(margin): + return self top, right, bottom, left = margin x, y, width, height = self return Region( From ba3bda2c2cb5f86b08591830994642ae27051efa Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 8 Jan 2023 17:45:39 +0000 Subject: [PATCH 206/310] micro optimizations --- src/textual/_compositor.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index 3c7fda165..bc56d019d 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -344,6 +344,7 @@ class Compositor: layer_order: int, clip: Region, visible: bool, + _MapGeometry=MapGeometry, ) -> None: """Called recursively to place a widget and its children in the map. @@ -413,12 +414,15 @@ class Compositor: widget_region = sub_region + placement_offset else: total_region = total_region.union( - sub_region.grow(spacing).grow(margin) + sub_region.grow(spacing + margin) ) widget_region = sub_region + placement_scroll_offset - widget_order = order + ( - (get_layer_index(sub_widget.layer, 0), z, layer_order), + widget_order = ( + *order, + get_layer_index(sub_widget.layer, 0), + z, + layer_order, ) add_widget( @@ -437,7 +441,7 @@ class Compositor: for chrome_widget, chrome_region in widget._arrange_scrollbars( container_region ): - map[chrome_widget] = MapGeometry( + map[chrome_widget] = _MapGeometry( chrome_region + layout_offset, order, clip, @@ -446,7 +450,7 @@ class Compositor: chrome_region, ) - map[widget] = MapGeometry( + map[widget] = _MapGeometry( region + layout_offset, order, clip, @@ -457,7 +461,7 @@ class Compositor: elif visible: # Add the widget to the map - map[widget] = MapGeometry( + map[widget] = _MapGeometry( region + layout_offset, order, clip, From e12d1f8bbbce600d0244e1d45d4b29f1fea42777 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sun, 8 Jan 2023 17:51:32 +0000 Subject: [PATCH 207/310] Fleshing out the post a wee bit more Needs whittling and rounding and stuff, perhaps, but I think I'm mostly there. A post-dinner top-to-bottom read is in now in order before I finally decide if I like it or not. --- docs/blog/posts/looking-for-help.md | 57 +++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/docs/blog/posts/looking-for-help.md b/docs/blog/posts/looking-for-help.md index e7d759c96..1de449f53 100644 --- a/docs/blog/posts/looking-for-help.md +++ b/docs/blog/posts/looking-for-help.md @@ -84,6 +84,15 @@ in the moment but fades away pretty quickly. It's like knocking on a friend's door to see if they're in. If they're not in, you might leave them a note, which is sort of like going to... +!!! note + + As a slight aside here: sometimes people will pop up in Discord, ask a + question about something that turns out looking like a bug, and that's + the last we hear of it. Please, please, **please**, if this happens, the + most helpful thing you can do is go raise an issue for us. It'll help us + to keep track of problems, it'll help get your problem fixed, it'll mean + everyone benefits. + ### GitHub On the other hand, if you have a question or need some help or something @@ -199,6 +208,20 @@ comes after you to acknowledge if it worked or not. That way a future help-seeker will know if the answer they're reading stands a chance of being the right one. +#### Accept that Textual is zero-point software (right now) + +Of course the aim is to have every release of Textual be stable and useful, +but things will break. So, please, do keep in mind things like: + +- Textual likely doesn't have your feature of choice just yet. +- Might accidentally break something (perhaps pinning Textual and testing + each release is a good plan here?). +- Might deliberately break something because we've decided to take a + particular feature or way of doing things in a better direction. + +Of course it can be a bit frustrating a times, but overall the aim is to +have the best framework possible in the long run. + ### Don't... Okay, now for a bit of old-hacker finger-wagging. Here's a few things I'd @@ -260,3 +283,37 @@ idea: - The next seeker-of-help gets to miss out on your question and the answer. If asked and answered in public, it's a record that can help someone else in the future. + +#### Doubt your ability or skill level + +I suppose this should really be a do rather than a don't, as here I want to +encourage something positive. A few times I've helped people out who have +been very apologetic about their questions being "noob" questions, or about +how they're fairly new to Python, or programming in general. Really, please, +don't feel the need to apologise and don't be ashamed of where you're at. + +If you've asked something that's obviously answered in the documentation, +that's not a problem; you'll likely get pointed at the docs and it's what +happens next that's the key bit. If the attitude is *"oh, cool, that's +exactly what I needed to be reading, thanks!"* that's a really positive +thing. The only time it's a problem is when there's a real reluctance to use +the available resources. We've all seen that person somewhere at some point, +right? ;-) + +## Conclusion + +So, that's my waffle over. As I said at the start: this is my own personal +thoughts on how to get help with Textual, both as someone whose job it is to +work on Textual and help people with Textual, and also as a FOSS advocate +and supporter who can normally be found helping Textual users when he's not +"on the clock" too. + +What I've written here isn't exhaustive. Neither is it novel. Plenty has +been written on the general subject in the past, and I'm sure more will be +written on the subject in the future. I do, however, feel that these are the +most common things I notice. I'd say those dos and don'ts cover 90% of *"can +I get some help?"* interactions; perhaps closer to 99%. + +Finally, and I think this is the most important thing to remember, the next +time you are battling some issue while working with Textual: [don't lose +your head](https://www.youtube.com/watch?v=KdYvKF9O7Y8)! From 01ad0df17fdd172a76f94f7dae6b3adbbd202f17 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Sun, 8 Jan 2023 21:10:50 +0000 Subject: [PATCH 208/310] Final tweaks to the "asking for help" blog post It's not finished, it never will be, but it's good to go. --- docs/blog/posts/looking-for-help.md | 49 +++++++++++++++-------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/docs/blog/posts/looking-for-help.md b/docs/blog/posts/looking-for-help.md index 1de449f53..46a9aa4eb 100644 --- a/docs/blog/posts/looking-for-help.md +++ b/docs/blog/posts/looking-for-help.md @@ -1,6 +1,6 @@ --- -draft: true -date: 2023-01-07 +draft: false +date: 2023-01-08 categories: - DevLog authors: @@ -24,14 +24,14 @@ As of the time of writing, I'm a handful of days off having been with Textualize for 3 months. It's been fun, and educational, and every bit as engaging as I'd hoped, and more. One thing I hadn't quite prepared for though, but which I really love, is how so many other people are learning -Textual along with me! +Textual along with me. Even in those three months the library has changed and expanded quite a lot, -and it continues to do so. Meanwhile, more and more people are turning up -and using the framework; you can see this online in social media, blogs and -of course [in the ever-growing list of projects on GitHub which depend on +and it continues to do so. Meanwhile, more people are turning up and using +the framework; you can see this online in social media, blogs and of course +[in the ever-growing list of projects on GitHub which depend on Textual](https://github.com/Textualize/textual/network/dependents). This inevitably means there's a lot of people getting to grips with a new @@ -52,7 +52,7 @@ anyone who wishes to take it. It's not Textual (the project) or Textualize take on how best to go about asking for help, informed by years of asking for and also providing help in email, on Usenet, on forums, etc. -Or, put another way, if what you read in here seems sensible to you, I +Or, put another way: if what you read in here seems sensible to you, I figure we'll likely have already hit it off over on GitHub or in the Discord sever. ;-) @@ -79,12 +79,7 @@ missed. If something catches my eye, I'll try and reply, but if it doesn't... well, it's mostly an instant chat thing so I don't dive too deeply back in time. -My own advice would be to treat Discord as an ephemeral resource. It happens -in the moment but fades away pretty quickly. It's like knocking on a -friend's door to see if they're in. If they're not in, you might leave them -a note, which is sort of like going to... - -!!! note +!!! tip inline end "Going from Discord to a GitHub issue" As a slight aside here: sometimes people will pop up in Discord, ask a question about something that turns out looking like a bug, and that's @@ -93,6 +88,11 @@ a note, which is sort of like going to... to keep track of problems, it'll help get your problem fixed, it'll mean everyone benefits. +My own advice would be to treat Discord as an ephemeral resource. It happens +in the moment but fades away pretty quickly. It's like knocking on a +friend's door to see if they're in. If they're not in, you might leave them +a note, which is sort of like going to... + ### GitHub On the other hand, if you have a question or need some help or something @@ -214,9 +214,9 @@ Of course the aim is to have every release of Textual be stable and useful, but things will break. So, please, do keep in mind things like: - Textual likely doesn't have your feature of choice just yet. -- Might accidentally break something (perhaps pinning Textual and testing +- We might accidentally break something (perhaps pinning Textual and testing each release is a good plan here?). -- Might deliberately break something because we've decided to take a +- We might deliberately break something because we've decided to take a particular feature or way of doing things in a better direction. Of course it can be a bit frustrating a times, but overall the aim is to @@ -268,9 +268,9 @@ Again, I'm going to speak totally for myself here, but I also feel the general case is polite for all: there's a lot of good support resources available already; sending DMs on Discord or Twitter or in the Fediverse, looking for direct personal support, isn't really the best way to get help. -Using those resources is absolutely the *best* way to get that help. Why's -it a bad idea to dive into DMs? Here's some reasons I think it's not a good -idea: +Using the public/collective resources is absolutely the *best* way to get +that help. Why's it a bad idea to dive into DMs? Here's some reasons I think +it's not a good idea: - It's a variation on "unnecessarily tagging individuals". - You're short-changing yourself when it comes to getting help. If you ask @@ -286,11 +286,12 @@ idea: #### Doubt your ability or skill level -I suppose this should really be a do rather than a don't, as here I want to -encourage something positive. A few times I've helped people out who have -been very apologetic about their questions being "noob" questions, or about -how they're fairly new to Python, or programming in general. Really, please, -don't feel the need to apologise and don't be ashamed of where you're at. +I suppose this should really be phrased as a do rather than a don't, as here +I want to encourage something positive. A few times I've helped people out +who have been very apologetic about their questions being "noob" questions, +or about how they're fairly new to Python, or programming in general. +Really, please, don't feel the need to apologise and don't be ashamed of +where you're at. If you've asked something that's obviously answered in the documentation, that's not a problem; you'll likely get pointed at the docs and it's what @@ -300,6 +301,8 @@ thing. The only time it's a problem is when there's a real reluctance to use the available resources. We've all seen that person somewhere at some point, right? ;-) +Not knowing things [is totally cool](https://xkcd.com/1053/). + ## Conclusion So, that's my waffle over. As I said at the start: this is my own personal From 3f4bb0af3fa5d664641a19910b5ecd684072818e Mon Sep 17 00:00:00 2001 From: Anthony Shaw Date: Mon, 9 Jan 2023 08:14:06 +1100 Subject: [PATCH 209/310] Annotate only_one comment with additional context See #1490 --- src/textual/css/query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/css/query.py b/src/textual/css/query.py index c14d032ab..fe9366d50 100644 --- a/src/textual/css/query.py +++ b/src/textual/css/query.py @@ -246,7 +246,7 @@ class DOMQuery(Generic[QueryType]): # should *not* be anything there, so we *should* get an # IndexError. We *could* have just checked the length of the # query, but the idea here is to do the check as cheaply as - # possible. + # possible. "There can be only one!" -- Duncan McLeod _ = self.nodes[1] raise TooManyMatches( "Call to only_one resulted in more than one matched node" From 7a214578e92d43d896baab81c89751aa4d4f84aa Mon Sep 17 00:00:00 2001 From: Anthony Shaw Date: Mon, 9 Jan 2023 08:24:24 +1100 Subject: [PATCH 210/310] Update query.py --- src/textual/css/query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/css/query.py b/src/textual/css/query.py index fe9366d50..9814382f9 100644 --- a/src/textual/css/query.py +++ b/src/textual/css/query.py @@ -246,7 +246,7 @@ class DOMQuery(Generic[QueryType]): # should *not* be anything there, so we *should* get an # IndexError. We *could* have just checked the length of the # query, but the idea here is to do the check as cheaply as - # possible. "There can be only one!" -- Duncan McLeod + # possible. "There can be only one!" -- Kurgan et al. _ = self.nodes[1] raise TooManyMatches( "Call to only_one resulted in more than one matched node" From acb206046ac2a436de125f9327a7234fe036c0a0 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 8 Jan 2023 22:19:48 +0000 Subject: [PATCH 211/310] simplify resized widgets --- src/textual/_compositor.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index bc56d019d..e7d436add 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -269,11 +269,14 @@ class Compositor: # Contains widgets + geometry for every widget that changed (added, removed, or updated) changes = map.items() ^ old_map.items() + # Widgets in both new and old + common_widgets = old_widgets & new_widgets + # Widgets with changed size resized_widgets = { widget for widget, (region, *_) in changes - if widget in old_widgets and old_map[widget].region.size != region.size + if widget in common_widgets and old_map[widget].region.size != region.size } screen_region = size.region From 204f3e48edda63ea214142dc84aada9be4727146 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 8 Jan 2023 22:32:09 +0000 Subject: [PATCH 212/310] optimization --- src/textual/_compositor.py | 5 ++++- src/textual/geometry.py | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index e7d436add..163ce7665 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -276,7 +276,10 @@ class Compositor: resized_widgets = { widget for widget, (region, *_) in changes - if widget in common_widgets and old_map[widget].region.size != region.size + if ( + widget in common_widgets + and not old_map[widget].region.same_size(region) + ) } screen_region = size.region diff --git a/src/textual/geometry.py b/src/textual/geometry.py index 17e938b1d..9990a9cdb 100644 --- a/src/textual/geometry.py +++ b/src/textual/geometry.py @@ -541,6 +541,18 @@ class Region(NamedTuple): width2, height2 = size return Region(x, y, min(width1, width2), min(height1, height2)) + def same_size(self, region: Region) -> bool: + """Check if another region is the same size. Equivalent to `self.size == region.size`, + but a little faster. + + Args: + region (Region): A region. + + Returns: + bool: True if both regions are the same size, False if they are different sizes. + """ + return self[2:] == region[2:] + def expand(self, size: tuple[int, int]) -> Region: """Increase the size of the region by adding a border. From a1b4d53fb9465295ee1bb84a594b1541e17efba5 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 08:51:00 +0000 Subject: [PATCH 213/310] Update date This hasn't been accepted/published yet so let's update the date. --- docs/blog/posts/looking-for-help.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/blog/posts/looking-for-help.md b/docs/blog/posts/looking-for-help.md index 46a9aa4eb..ad1c8e8fa 100644 --- a/docs/blog/posts/looking-for-help.md +++ b/docs/blog/posts/looking-for-help.md @@ -1,6 +1,6 @@ --- draft: false -date: 2023-01-08 +date: 2023-01-09 categories: - DevLog authors: @@ -20,7 +20,7 @@ authors: Juan Sánchez Villalobos Ramírez, Chief metallurgist to King Charles V of Spain -As of the time of writing, I'm a handful of days off having been with +As of the time of writing, I'm a couple or so days off having been with Textualize for 3 months. It's been fun, and educational, and every bit as engaging as I'd hoped, and more. One thing I hadn't quite prepared for though, but which I really love, is how so many other people are learning From 81ddae793332c6e14835c6d80961c8cb2cb2fb03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 09:32:10 +0000 Subject: [PATCH 214/310] Use specific rules in CSS type examples. [skip ci] --- docs/css_types/_template.md | 9 ++++----- docs/css_types/border.md | 39 ++++++++---------------------------- docs/css_types/color.md | 29 +++++++++++++++------------ docs/css_types/horizontal.md | 10 +++------ docs/css_types/integer.md | 8 +++----- docs/css_types/name.md | 16 +++------------ docs/css_types/number.md | 17 ++++++++-------- docs/css_types/overflow.md | 10 +++------ docs/css_types/percentage.md | 15 ++++++++++---- docs/css_types/scalar.md | 22 +++++--------------- docs/css_types/text_align.md | 14 ++----------- docs/css_types/text_style.md | 20 +++++------------- docs/css_types/vertical.md | 10 +++------ 13 files changed, 74 insertions(+), 145 deletions(-) diff --git a/docs/css_types/_template.md b/docs/css_types/_template.md index fbb79dcb6..079f1b7ef 100644 --- a/docs/css_types/_template.md +++ b/docs/css_types/_template.md @@ -46,14 +46,13 @@ The [``](/css_types/my_type) type can take any of the following values: ### CSS ```sass -* { +.some-class { rule: type-value-1; rule: type-value-2; rule: type-value-3; @@ -65,7 +64,7 @@ Add comments when needed/if helpful. ```py -type_name = type_value_1 -type_name = type_value_2 -type_name = type_value_3 +widget.styles.rule = type_value_1 +widget.styles.rule = type_value_2 +widget.styles.rule = type_value_3 ``` diff --git a/docs/css_types/border.md b/docs/css_types/border.md index 447a74069..8147cbf39 100644 --- a/docs/css_types/border.md +++ b/docs/css_types/border.md @@ -37,41 +37,18 @@ textual borders ### CSS ```sass -* { - rule: ascii /* A border with plus, hyphen, and vertical bar characters. */ - rule: blank /* A blank border (reserves space for a border). */ - rule: dashed /* Dashed line border. */ - rule: double /* Double lined border. */ - rule: heavy /* Heavy border. */ - rule: hidden /* Alias for "none". */ - rule: hkey /* Horizontal key-line border. */ - rule: inner /* Thick solid border. */ - rule: none /* Disabled border. */ - rule: outer /* Solid border with additional space around content. */ - rule: round /* Rounded corners. */ - rule: solid /* Solid border. */ - rule: tall /* Solid border with additional space top and bottom. */ - rule: vkey /* Vertical key-line border. */ - rule: wide /* Solid border with additional space left and right. */ +#container { + border: heavy red; +} + +#heading { + border-bottom: solid blue; } ``` ### Python ```py -border = "ascii" # A border with plus, hyphen, and vertical bar characters. -border = "blank" # A blank border (reserves space for a border). -border = "dashed" # Dashed line border. -border = "double" # Double lined border. -border = "heavy" # Heavy border. -border = "hidden" # Alias for "none". -border = "hkey" # Horizontal key-line border. -border = "inner" # Thick solid border. -border = "none" # Disabled border. -border = "outer" # Solid border with additional space around content. -border = "round" # Rounded corners. -border = "solid" # Solid border. -border = "tall" # Solid border with extras space top and bottom. -border = "vkey" # Vertical key-line border. -border = "wide" # Solid border with additional space left and right. +widget.styles.border = ("heavy", "red") +widget.styles.border_bottom = ("solid", "blue") ``` diff --git a/docs/css_types/color.md b/docs/css_types/color.md index 0d6852356..4b18f07f3 100644 --- a/docs/css_types/color.md +++ b/docs/css_types/color.md @@ -23,27 +23,30 @@ For more details about the exact formats accepted, see [the class method `Color. ### CSS ```sass -* { - rule: red; /* color name */ - rule: #A8F; /* 3-digit hex RGB */ - rule: #FF00FFDD; /* 6-digit hex RGB + transparency */ - rule: rgb(15,200,73); /* RGB description */ - rule: hsl(300,20%,70%); /* HSL description */ - rule: $accent; /* Textual variable */ +Header { + background: red; /* Color name */ +} + +.accent { + color: $accent; /* Textual variable */ +} + +#footer { + tint: hsl(300, 20%, 70%); /* HSL description */ } ``` ### Python +In Python, rules that expect a `` can also accept an instance of the type [`Color`][textual.color.Color]. + ```py # Mimicking the CSS syntax -color = "red" -color = "#A8F" -color = "#FF00FFDD" -color = "rgb(15,200,73)" -color = "hsl(300,20%,70%)" -color = "$accent" +widget.styles.background = "red" # Color name +widget.styles.color = "$accent" # Textual variable +widget.styles.tint = "hsl(300, 20%, 70%)" # HSL description +from textual.color import Color # Using a Color object directly... color = Color(16, 200, 45) # ... which can also parse the CSS syntax diff --git a/docs/css_types/horizontal.md b/docs/css_types/horizontal.md index f5df8d04a..d46d17a55 100644 --- a/docs/css_types/horizontal.md +++ b/docs/css_types/horizontal.md @@ -17,17 +17,13 @@ The [``](/css_types/horizontal) type can take any of the following v ### CSS ```sass -* { - rule: left; - rule: center; - rule: right +.container { + align-horizontal: right; } ``` ### Python ```py -horizontal = "left" -horizontal = "center" -horizontal = "right" +widget.styles.align_horizontal = "right" ``` diff --git a/docs/css_types/integer.md b/docs/css_types/integer.md index 6823d97fb..ac97f400e 100644 --- a/docs/css_types/integer.md +++ b/docs/css_types/integer.md @@ -15,9 +15,8 @@ An [``](/css_types/integer) is any valid integer number like `-10` or ` ### CSS ```sass -* { - rule: -5; - rule: 10; +.classname { + offset: 10 -20 } ``` @@ -26,6 +25,5 @@ An [``](/css_types/integer) is any valid integer number like `-10` or ` In Python, a rule that expects a CSS type `` will expect a value of the type `int`: ```py -integer = -5 -integer = 10 +widget.styles.offset = (10, -20) ``` diff --git a/docs/css_types/name.md b/docs/css_types/name.md index ef2faa625..caca3639a 100644 --- a/docs/css_types/name.md +++ b/docs/css_types/name.md @@ -14,23 +14,13 @@ A [``](/css_types/name) is any non-empty sequence of characters: ### CSS ```sass -* { - rule: onlyLetters; - rule: Letters-and-hiphens; - rule: _leading-underscore; - rule: letters-and-1-digit; - rule: name1234567890; +Screen { + layers: onlyLetters Letters-and-hiphens _lead-under letters-1-digit; } ``` ### Python - - ```py -name = "onlyLetters" -name = "Letters-and-hiphens" -name = "_leading-underscore" -name = "letters-and-1-digit" -name = "name1234567890" +widget.styles.layers = "onlyLetters Letters-and-hiphens _lead-under letters-1-digit" ``` diff --git a/docs/css_types/number.md b/docs/css_types/number.md index a3b50660c..c810a315f 100644 --- a/docs/css_types/number.md +++ b/docs/css_types/number.md @@ -11,11 +11,12 @@ A [``](/css_types/number) is an [``](/css_types/integer), optio ### CSS ```sass -* { - css-rule: 6 /* Integers are numbers */ - css-rule: -13 /* Numbers can be negative */ - css-rule: 4.75 /* Numbers can have a decimal part */ - css-rule: -73.73 +Grid { + grid-size: 3 6 /* Integers are numbers */ +} + +.translucid { + opacity: 0.5 /* Numbers can have a decimal part */ } ``` @@ -24,8 +25,6 @@ A [``](/css_types/number) is an [``](/css_types/integer), optio In Python, a rule that expects a CSS type `` will accept an `int` or a `float`: ```py -number = 6 # ints are numbers -number = -13 # ints can be negative -number = 4.75 # floats are numbers -number = -73.73 # negative floats too +widget.styles.grid_size = (3, 6) # Integers are numbers +widget.styles.opacity = 0.5 # Numbers can have a decimal part ``` diff --git a/docs/css_types/overflow.md b/docs/css_types/overflow.md index b4f89aa2f..ebfcc0585 100644 --- a/docs/css_types/overflow.md +++ b/docs/css_types/overflow.md @@ -17,17 +17,13 @@ The [``](/css_types/overflow) type can take any of the following value ### CSS ```sass -* { - rule: auto; /* Determine overflow mode automatically. */ - rule: hidden; /* Don't overflow. */ - rule: scroll; /* Allow overflowing. */ +#container { + overflow-y: hidden; /* Don't overflow */ } ``` ### Python ```py -overflow = "auto" # Determine overflow mode automatically. -overflow = "hidden" # Don't overflow. -overflow = "scroll" # Allow overflowing. +widget.styles.overflow_y = "hidden" # Don't overflow ``` diff --git a/docs/css_types/percentage.md b/docs/css_types/percentage.md index 6252cae97..8deb78c0e 100644 --- a/docs/css_types/percentage.md +++ b/docs/css_types/percentage.md @@ -17,14 +17,21 @@ Some rules may clamp the values between `0%` and `100%`. ### CSS ```sass -* { - rule: 70%; /* Integer followed by % */ - rule: -3.5%; /* The number can be negative/decimal */ +#footer { + /* Integer followed by % */ + color: red 70%; + + /* The number can be negative/decimal, although that may not make sense */ + offset: -30% 12.5%; } ``` ### Python ```py -percentage = "70%" +# Integer followed by % +widget.styles.color = "red 70%" + +# The number can be negative/decimal, althought that may not make sense +widget.styles.offset = ("-30%", "12.5%") ``` diff --git a/docs/css_types/scalar.md b/docs/css_types/scalar.md index e909c2f05..bf1640348 100644 --- a/docs/css_types/scalar.md +++ b/docs/css_types/scalar.md @@ -97,27 +97,15 @@ For example, if its container is big enough, a label with `width: auto` will be ### CSS ```sass -* { - rule: 16; /* 16 cells */ - rule: 1fr; /* proportional size of 1 */ - rule: 50%; /* 50% of the same dimension of the parent */ - rule: 25w; /* 25% of the width of the parent */ - rule: 75h; /* 75% of the height of the parent */ - rule: 25vw; /* 25% of the viewport width */ - rule: 75vh; /* 75% of the viewport height */ - rule: auto; /* special value */ +Horizontal { + width: 60; /* 60 cells */ + height: 1fr; /* proportional size of 1 */ } ``` ### Python ```py -scalar = 16 # Cell unit can be specified with an int/float -scalar = "1fr" # proportional size of 1 -scalar = "50%" # 50% of the same dimension of the parent -scalar = "25w" # 25% of the width of the parent -scalar = "75h" # 75% of the height of the parent -scalar = "25vw" # 25% of the viewport width -scalar = "75vh" # 75% of the viewport height -scalar = "auto" # special value +widget.styles.width = 16 # Cell unit can be specified with an int/float +widget.styles.height = "1fr" # proportional size of 1 ``` diff --git a/docs/css_types/text_align.md b/docs/css_types/text_align.md index 8a18b51c7..acc670bd3 100644 --- a/docs/css_types/text_align.md +++ b/docs/css_types/text_align.md @@ -28,23 +28,13 @@ A [``](/css_types/text_align) can be any of the following values: ### CSS ```sass -* { - rule: center; - rule: end; +Label { rule: justify; - rule: left; - rule: right; - rule: start; } ``` ### Python ```py -text_align = "center" -text_align = "end" -text_align = "justify" -text_align = "left" -text_align = "right" -text_align = "start" +widget.styles.text_align = "justify" ``` diff --git a/docs/css_types/text_style.md b/docs/css_types/text_style.md index 1dd36ce10..f41646e3c 100644 --- a/docs/css_types/text_style.md +++ b/docs/css_types/text_style.md @@ -24,18 +24,14 @@ A [``](/css_types/text_style) can be any _space-separated_ combinati ### CSS ```sass -* { +#label1 { /* You can specify any value by itself. */ - rule: bold; - rule: italic; - rule: none; - rule: reverse; rule: strike; - rule: underline; +} +#label2 { /* You can also combine multiple values. */ rule: strike bold italic reverse; - rule: bold underline italic; } ``` @@ -43,14 +39,8 @@ A [``](/css_types/text_style) can be any _space-separated_ combinati ```py # You can specify any value by itself -text_style = "bold" -text_style = "italic" -text_style = "none" -text_style = "reverse" -text_style = "strike" -text_style = "underline" +widget.styles.text_style = "strike" # You can also combine multiple values -text_style = "strike bold italic reverse" -text_style = "bold underline italic" +widget.styles.text_style = "bold underline italic" ``` diff --git a/docs/css_types/vertical.md b/docs/css_types/vertical.md index 5d95e093f..d5d8066aa 100644 --- a/docs/css_types/vertical.md +++ b/docs/css_types/vertical.md @@ -17,17 +17,13 @@ The [``](/css_types/vertical) type can take any of the following value ### CSS ```sass -* { - rule: top; - rule: middle; - rule: bottom +.container { + align-vertical: top; } ``` ### Python ```py -vertical = "top" -vertical = "middle" -vertical = "bottom" +widget.styles.align_vertical = "top" ``` From bd9d88fa4f5943c8dac323916e236b306d4f8735 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 10:10:29 +0000 Subject: [PATCH 215/310] Fix a typo --- docs/blog/posts/looking-for-help.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/blog/posts/looking-for-help.md b/docs/blog/posts/looking-for-help.md index ad1c8e8fa..bfbb484e2 100644 --- a/docs/blog/posts/looking-for-help.md +++ b/docs/blog/posts/looking-for-help.md @@ -54,7 +54,7 @@ for and also providing help in email, on Usenet, on forums, etc. Or, put another way: if what you read in here seems sensible to you, I figure we'll likely have already hit it off over on GitHub or in the Discord -sever. ;-) +server. ;-) ## Where to go for help From 0a190193d763db429660416935078d8bc0db2f22 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 10:16:52 +0000 Subject: [PATCH 216/310] Link to GitHub and Discord early on For the benefit of those who aren't there yet. --- docs/blog/posts/looking-for-help.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/blog/posts/looking-for-help.md b/docs/blog/posts/looking-for-help.md index bfbb484e2..fe142303d 100644 --- a/docs/blog/posts/looking-for-help.md +++ b/docs/blog/posts/looking-for-help.md @@ -53,8 +53,9 @@ take on how best to go about asking for help, informed by years of asking for and also providing help in email, on Usenet, on forums, etc. Or, put another way: if what you read in here seems sensible to you, I -figure we'll likely have already hit it off over on GitHub or in the Discord -server. ;-) +figure we'll likely have already hit it off [over on +GitHub](https://github.com/Textualize/textual) or in [the Discord +server](https://discord.gg/Enf6Z3qhVr). ;-) ## Where to go for help From 1ef20eb4ecb19edd3156831a54e65522ae2a850c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 10:29:47 +0000 Subject: [PATCH 217/310] Improve CSS type color reference. [skip ci] --- docs/css_types/color.md | 98 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 7 deletions(-) diff --git a/docs/css_types/color.md b/docs/css_types/color.md index 4b18f07f3..09b950006 100644 --- a/docs/css_types/color.md +++ b/docs/css_types/color.md @@ -8,15 +8,99 @@ The `` CSS type represents a color. ## Syntax -The legal values for a [``](/css_types/color) depend on the [class `Color`][textual.color.Color] and include: +A [``](/css_types/color) should be in one of the formats explained in this section. +A bullet point summary of the formats available follows: - - a recognised [named color](../../api/color#textual.color--named-colors) (e.g., `red`); - - a hexadecimal number representing the RGB values of the color (e.g., `#F35573`); - - a color description in the RGB system (e.g., `rgb(23,78,200)`); - - a color description in the HSL system (e.g., `hsl(290,70%,80%)`); and + - a recognised [named color](#named-colors) (e.g., `red`); + - a 3 or 6 hexadecimal digit number representing the [RGB values](#hex-rgb-value) of the color (e.g., `#F35573`); + - a 4 or 8 hexadecimal digit number representing the [RGBA values](#hex-rgba-value) of the color (e.g., `#F35573A0`); + - a color description in the RGB system, [with](#rgba-description) or [without](#rgb-description) transparency (e.g., `rgb(23, 78, 200)`); + - a color description in the HSL system, [with](#hsla-description) or [without](#hsl-description) transparency (e.g., `hsl(290, 70%, 80%)`); -For more details about the exact formats accepted, see [the class method `Color.parse`][textual.color.Color.parse]. -[Textual's default themes](../../guide/design#theme-reference) also provide many CSS variables with colors. +[Textual's default themes](../../guide/design#theme-reference) also provide many CSS variables with colors that can be used out of the box. + +### Named colors + +A named color is a [``](./name.md) that Textual recognises. +Below, you can find a (collapsed) list of all of the named colors that Textual recognises, along with their hexadecimal values, their RGB values, and a visual sample. + +

+All named colors available. + +```{.rich columns="80" title="colors"} +from textual._color_constants import COLOR_NAME_TO_RGB +from textual.color import Color +from rich.table import Table +from rich.text import Text +table = Table("Name", "hex", "RGB", "Color", expand=True, highlight=True) + +for name, triplet in sorted(COLOR_NAME_TO_RGB.items()): + if len(triplet) != 3: + continue + color = Color(*triplet) + r, g, b = triplet + table.add_row( + f'"{name}"', + Text(f"{color.hex}", "bold green"), + f"rgb({r}, {g}, {b})", + Text(" ", style=f"on rgb({r},{g},{b})") + ) +output = table +``` + +
+ +### Hex RGB value + +The hexadecimal RGB format starts with an octothorpe `#` and is then followed by 3 or 6 hexadecimal digits: `0123456789ABCDEF`. +Casing is ignored. + + - If 6 digits are used, the format is `#RRGGBB`: + - `RR` represents the red channel; + - `GG` represents the green channel; and + - `BB` represents the blue channel. + - If 3 digits are used, the format is `#RGB`. + +In a 3 digit color, each channel is represented by a single digit which is duplicated when converting to the 6 digit format. +For example, the color `#A2F` is the same as `#AA22FF`. + +### Hex RGBA value + +This is the same as the [hex RGB value](#hex-rgb-value), but with an extra channel for the alpha component (that sets transparency). + + - If 8 digits are used, the format is `#RRGGBBAA`, equivalent to the format `#RRGGBB` with two extra digits for transparency. + - If 4 digits are used, the format is `#RGBA`, equivalent to the format `#RGB` with an extra digit for transparency. + +### `rgb` description + +The `rgb` format description is a functional description of a color in the RGB color space. +This description follows the format `rgb(red, green, blue)`, where `red`, `green`, and `blue` are decimal integers between 0 and 255. +They represent the value of the channel with the same name. + +For example, `rgb(0, 255, 32)` is equivalent to `#00FF20`. + +### `rgba` description + +The `rgba` format description is the same as the `rgb` with an extra parameter for transparency, which should be a value between `0` and `1`. + +For example, `rgba(0, 255, 32, 0.5)` is the color `rgb(0, 255, 32)` with 50% transparency. + +### `hsl` description + +The `hsl` format description is a functional description of a color in the HSL color space. +This description follows the format `hsl(hue, saturation, lightness)`, where + + - `hue` is a float between 0 and 360; + - `saturation` is a percentage between `0%` and `100%`; and + - `lightness` is a percentage between `0%` and `100%`. + +For example, the color `#00FF20` would be represented as `hsl(128, 100%, 50%)` in the HSL color space. + +### `hsla` description + +The `hsla` format description is the same as the `hsl` with an extra parameter for transparency, which should be a value between `0` and `1`. + +For example, `hsla(128, 100%, 50%, 0.5)` is the color `hsl(128, 100%, 50%)` with 50% transparency. ## Examples From 3ac98187f9beb0dccc3ceb95ca42a66958093b35 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 9 Jan 2023 10:41:04 +0000 Subject: [PATCH 218/310] removed same_size --- src/textual/_compositor.py | 5 +---- src/textual/geometry.py | 12 ------------ 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index 163ce7665..ca92e525e 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -276,10 +276,7 @@ class Compositor: resized_widgets = { widget for widget, (region, *_) in changes - if ( - widget in common_widgets - and not old_map[widget].region.same_size(region) - ) + if (widget in common_widgets and old_map[widget].region[2:] != region[2:]) } screen_region = size.region diff --git a/src/textual/geometry.py b/src/textual/geometry.py index 9990a9cdb..17e938b1d 100644 --- a/src/textual/geometry.py +++ b/src/textual/geometry.py @@ -541,18 +541,6 @@ class Region(NamedTuple): width2, height2 = size return Region(x, y, min(width1, width2), min(height1, height2)) - def same_size(self, region: Region) -> bool: - """Check if another region is the same size. Equivalent to `self.size == region.size`, - but a little faster. - - Args: - region (Region): A region. - - Returns: - bool: True if both regions are the same size, False if they are different sizes. - """ - return self[2:] == region[2:] - def expand(self, size: tuple[int, int]) -> Region: """Increase the size of the region by adding a border. From 40cbbc31b80b961902c4f61f62527431dddc0ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 10:54:04 +0000 Subject: [PATCH 219/310] Add note about viewport size. [skip ci] --- docs/css_types/scalar.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/css_types/scalar.md b/docs/css_types/scalar.md index bf1640348..d8086a45d 100644 --- a/docs/css_types/scalar.md +++ b/docs/css_types/scalar.md @@ -77,12 +77,14 @@ So, if the container has a height of 100 cells, the width and the height of the ### Viewport width This is the same as the [width unit](#width), except that it is relative to the width of the viewport instead of the width of the immediate container. +The width of the viewport is the width of the terminal minus the widths of widgets that are docked left or right. For example, `width: 25vw` will try to set the width of a widget to be 25% of the viewport width, regardless of the widths of its containers. ### Viewport height This is the same as the [height unit](#height), except that it is relative to the height of the viewport instead of the height of the immediate container. +The height of the viewport is the height of the terminal minus the heights of widgets that are docked top or bottom. For example, `height: 75vh` will try to set the height of a widget to be 75% of the viewport height, regardless of the height of its containers. From 196d430582f30486dba76395f7c219e2edb0fba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 11:20:04 +0000 Subject: [PATCH 220/310] Style all Textual CSS as 'sass' Textual CSS is better highlighted in SASS code blocks because the SASS parser seems to be more lenient. --- docs/blog/posts/spinners-and-pbs-in-textual.md | 2 +- docs/guide/CSS.md | 8 ++++---- docs/styles/_template.md | 4 ++-- docs/styles/align.md | 4 ++-- docs/styles/border.md | 4 ++-- docs/styles/box_sizing.md | 2 +- docs/styles/color.md | 4 ++-- docs/styles/content_align.md | 4 ++-- docs/styles/display.md | 2 +- docs/styles/dock.md | 2 +- docs/styles/grid/column_span.md | 2 +- docs/styles/grid/grid_columns.md | 2 +- docs/styles/grid/grid_gutter.md | 2 +- docs/styles/grid/grid_rows.md | 2 +- docs/styles/grid/grid_size.md | 4 ++-- docs/styles/grid/row_span.md | 2 +- docs/styles/height.md | 2 +- docs/styles/links/link_background.md | 4 ++-- docs/styles/links/link_color.md | 4 ++-- docs/styles/links/link_hover_background.md | 4 ++-- docs/styles/links/link_hover_color.md | 4 ++-- docs/styles/links/link_hover_style.md | 4 ++-- docs/styles/links/link_style.md | 4 ++-- docs/styles/margin.md | 2 +- docs/styles/max_height.md | 2 +- docs/styles/max_width.md | 2 +- docs/styles/min_height.md | 2 +- docs/styles/min_width.md | 2 +- docs/styles/offset.md | 2 +- docs/styles/opacity.md | 2 +- docs/styles/outline.md | 4 ++-- docs/styles/overflow.md | 2 +- docs/styles/padding.md | 2 +- docs/styles/scrollbar_colors/index.md | 2 +- docs/styles/scrollbar_colors/scrollbar_background.md | 4 ++-- .../scrollbar_colors/scrollbar_background_active.md | 4 ++-- .../styles/scrollbar_colors/scrollbar_background_hover.md | 4 ++-- docs/styles/scrollbar_colors/scrollbar_color.md | 4 ++-- docs/styles/scrollbar_colors/scrollbar_color_active.md | 4 ++-- docs/styles/scrollbar_colors/scrollbar_color_hover.md | 4 ++-- docs/styles/scrollbar_colors/scrollbar_corner_color.md | 4 ++-- docs/styles/scrollbar_gutter.md | 2 +- docs/styles/scrollbar_size.md | 4 ++-- docs/styles/text_align.md | 2 +- docs/styles/text_opacity.md | 2 +- docs/styles/text_style.md | 4 ++-- docs/styles/tint.md | 2 +- docs/styles/visibility.md | 4 ++-- docs/styles/width.md | 4 ++-- docs/widgets/button.md | 2 +- docs/widgets/checkbox.md | 2 +- docs/widgets/placeholder.md | 2 +- 52 files changed, 79 insertions(+), 79 deletions(-) diff --git a/docs/blog/posts/spinners-and-pbs-in-textual.md b/docs/blog/posts/spinners-and-pbs-in-textual.md index a92ba590a..daa6b774f 100644 --- a/docs/blog/posts/spinners-and-pbs-in-textual.md +++ b/docs/blog/posts/spinners-and-pbs-in-textual.md @@ -396,7 +396,7 @@ Below you can see the code I wrote and a short animation of the app working. === "CSS" - ```css + ```sass Screen { align: center middle; } diff --git a/docs/guide/CSS.md b/docs/guide/CSS.md index 9dc1f6fb2..80753ddbd 100644 --- a/docs/guide/CSS.md +++ b/docs/guide/CSS.md @@ -344,7 +344,7 @@ The `#dialog Button` selector matches all buttons that are below the widget with As with all selectors, you can combine as many as you wish. The following will match a `Button` that is under a `Horizontal` widget _and_ under a widget with an id of `"dialog"`: -```css +```sass #dialog Horizontal Button { text-style: bold; } @@ -400,14 +400,14 @@ You can define variables to reduce repetition and encourage consistency in your Variables in Textual CSS are prefixed with `$`. Here's an example of how you might define a variable called `$border`: -```scss +```sass $border: wide green; ``` With our variable assigned, we can write `$border` and it will be substituted with `wide green`. Consider the following snippet: -```scss +```sass #foo { border: $border; } @@ -415,7 +415,7 @@ Consider the following snippet: This will be translated into: -```scss +```sass #foo { border: wide green; } diff --git a/docs/styles/_template.md b/docs/styles/_template.md index c92c701f7..325fb3432 100644 --- a/docs/styles/_template.md +++ b/docs/styles/_template.md @@ -62,7 +62,7 @@ Short description of the first example. === "rule.css" - ```css + ```sass --8<-- "docs/examples/styles/rule.css" ``` --> @@ -84,7 +84,7 @@ Short description of the second example. === "rule.css" - ```scss + ```sass --8<-- "docs/examples/styles/rule.css" ``` diff --git a/docs/styles/align.md b/docs/styles/align.md index f2a42cb4a..ba6298917 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -33,7 +33,7 @@ This example contains a simple app with two labels centered on the screen with ` === "align.css" - ```scss hl_lines="2" + ```sass hl_lines="2" --8<-- "docs/examples/styles/align.css" ``` @@ -54,7 +54,7 @@ Each label has been aligned differently inside its container, and its text shows === "align_all.css" - ```css + ```sass --8<-- "docs/examples/styles/align_all.css" ``` diff --git a/docs/styles/border.md b/docs/styles/border.md index c471f580d..017fcb9e9 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -64,7 +64,7 @@ This examples shows three widgets with different border styles. === "border.css" - ```css + ```sass --8<-- "docs/examples/styles/border.css" ``` @@ -83,7 +83,7 @@ The next example shows a grid with all the available border types. === "border_all.css" - ```css + ```sass --8<-- "docs/examples/styles/border_all.css" ``` diff --git a/docs/styles/box_sizing.md b/docs/styles/box_sizing.md index 5ad0be42a..73fe9064c 100644 --- a/docs/styles/box_sizing.md +++ b/docs/styles/box_sizing.md @@ -29,7 +29,7 @@ The bottom widget has `box-sizing: content-box` which increases the size of the === "box_sizing.css" - ```css + ```sass --8<-- "docs/examples/styles/box_sizing.css" ``` diff --git a/docs/styles/color.md b/docs/styles/color.md index 508e47c18..8fa321fc4 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -24,7 +24,7 @@ This example sets a different text color for each of three different widgets. === "color.css" - ```css + ```sass --8<-- "docs/examples/styles/color.css" ``` @@ -43,7 +43,7 @@ The next example shows how `auto` chooses between a lighter or a darker text col === "color_auto.css" - ```css hl_lines="2" + ```sass hl_lines="2" --8<-- "docs/examples/styles/color_auto.css" ``` diff --git a/docs/styles/content_align.md b/docs/styles/content_align.md index b459009c6..462bf8548 100644 --- a/docs/styles/content_align.md +++ b/docs/styles/content_align.md @@ -34,7 +34,7 @@ This first example shows three labels stacked vertically, each with different co === "content_align.css" - ```scss hl_lines="2 7-8 13" + ```sass hl_lines="2 7-8 13" --8<-- "docs/examples/styles/content_align.css" ``` @@ -54,7 +54,7 @@ Each label has its text aligned differently. === "content_align_all.css" - ```css + ```sass --8<-- "docs/examples/styles/content_align_all.css" ``` diff --git a/docs/styles/display.md b/docs/styles/display.md index c9a52f329..ad308398b 100644 --- a/docs/styles/display.md +++ b/docs/styles/display.md @@ -27,7 +27,7 @@ Note that the second widget is hidden by adding the `"remove"` class which sets === "display.css" - ```css + ```sass --8<-- "docs/examples/styles/display.css" ``` diff --git a/docs/styles/dock.md b/docs/styles/dock.md index dceb0beec..75d72eb23 100644 --- a/docs/styles/dock.md +++ b/docs/styles/dock.md @@ -48,7 +48,7 @@ The labels will remain in that position (docked) even if the container they are === "dock_all.css" - ```css hl_lines="2-5 8-11 14-17 20-23" + ```sass hl_lines="2-5 8-11 14-17 20-23" --8<-- "docs/examples/styles/dock_all.css" ``` diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md index 7f02b87d4..72ba1a5f3 100644 --- a/docs/styles/grid/column_span.md +++ b/docs/styles/grid/column_span.md @@ -35,7 +35,7 @@ The example below shows a 4 by 4 grid where many placeholders span over several === "column_span.css" - ```css + ```sass --8<-- "docs/examples/styles/column_span.css" ``` diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index f603fde86..ab6edb79c 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -46,7 +46,7 @@ Because there are more rows than scalars in the style rule, the scalars will be === "grid_columns.css" - ```css + ```sass --8<-- "docs/examples/styles/grid_columns.css" ``` diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md index 2488f95f0..9293c0672 100644 --- a/docs/styles/grid/grid_gutter.md +++ b/docs/styles/grid/grid_gutter.md @@ -41,7 +41,7 @@ The example below employs a common trick to apply visually consistent spacing ar === "grid_gutter.css" - ```css + ```sass --8<-- "docs/examples/styles/grid_gutter.css" ``` diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index 72b12b270..dbf5a161a 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -46,7 +46,7 @@ Because there are more rows than scalars in the style rule, the scalars will be === "grid_rows.css" - ```css + ```sass --8<-- "docs/examples/styles/grid_rows.css" ``` diff --git a/docs/styles/grid/grid_size.md b/docs/styles/grid/grid_size.md index b35e4d391..3752bdfba 100644 --- a/docs/styles/grid/grid_size.md +++ b/docs/styles/grid/grid_size.md @@ -39,7 +39,7 @@ In the first example, we create a grid with 2 columns and 5 rows, regardless of === "grid_size_both.css" - ```css hl_lines="2" + ```sass hl_lines="2" --8<-- "docs/examples/styles/grid_size_both.css" ``` @@ -60,7 +60,7 @@ In the second example, we create a grid with 2 columns and however many rows are === "grid_size_columns.css" - ```css + ```sass --8<-- "docs/examples/styles/grid_size_columns.css" ``` diff --git a/docs/styles/grid/row_span.md b/docs/styles/grid/row_span.md index 8e874480b..b7afb8146 100644 --- a/docs/styles/grid/row_span.md +++ b/docs/styles/grid/row_span.md @@ -38,7 +38,7 @@ After placing the placeholders `#p1`, `#p2`, `#p3`, and `#p4`, the next availabl === "row_span.css" - ```css + ```sass --8<-- "docs/examples/styles/row_span.css" ``` diff --git a/docs/styles/height.md b/docs/styles/height.md index 437f69b8d..e9c558d50 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -51,7 +51,7 @@ Open the CSS file tab to see the comments that explain how each height is comput === "height_comparison.css" - ```css hl_lines="2 5 8 11 14 17 20 23 26" + ```sass hl_lines="2 5 8 11 14 17 20 23 26" --8<-- "docs/examples/styles/height_comparison.css" ``` diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md index 92e1e6191..ab6e775f5 100644 --- a/docs/styles/links/link_background.md +++ b/docs/styles/links/link_background.md @@ -47,7 +47,7 @@ It also shows that `link-background` does not affect hyperlinks. === "link_background.css" - ```css hl_lines="2 6 10" + ```sass hl_lines="2 6 10" --8<-- "docs/examples/styles/link_background.css" ``` @@ -55,7 +55,7 @@ It also shows that `link-background` does not affect hyperlinks. ## CSS -```css +```sass link-background: red 70%; link-background: $accent; ``` diff --git a/docs/styles/links/link_color.md b/docs/styles/links/link_color.md index e9ce8c210..c4d14ab3f 100644 --- a/docs/styles/links/link_color.md +++ b/docs/styles/links/link_color.md @@ -47,7 +47,7 @@ It also shows that `link-color` does not affect hyperlinks. === "link_color.css" - ```css hl_lines="2 6 10" + ```sass hl_lines="2 6 10" --8<-- "docs/examples/styles/link_color.css" ``` @@ -55,7 +55,7 @@ It also shows that `link-color` does not affect hyperlinks. ## CSS -```css +```sass link-color: red 70%; link-color: $accent; ``` diff --git a/docs/styles/links/link_hover_background.md b/docs/styles/links/link_hover_background.md index 9da9e27c6..f8850420e 100644 --- a/docs/styles/links/link_hover_background.md +++ b/docs/styles/links/link_hover_background.md @@ -56,7 +56,7 @@ It also shows that `link-hover-background` does not affect hyperlinks. === "link_hover_background.css" - ```css hl_lines="2 6 10" + ```sass hl_lines="2 6 10" --8<-- "docs/examples/styles/link_hover_background.css" ``` @@ -65,7 +65,7 @@ It also shows that `link-hover-background` does not affect hyperlinks. ## CSS -```css +```sass link-hover-background: red 70%; link-hover-background: $accent; ``` diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md index a1f53c4f9..ec36aec95 100644 --- a/docs/styles/links/link_hover_color.md +++ b/docs/styles/links/link_hover_color.md @@ -60,7 +60,7 @@ It also shows that `link-hover-color` does not affect hyperlinks. === "link_hover_color.css" - ```css hl_lines="2 6 10" + ```sass hl_lines="2 6 10" --8<-- "docs/examples/styles/link_hover_color.css" ``` @@ -68,7 +68,7 @@ It also shows that `link-hover-color` does not affect hyperlinks. ## CSS -```css +```sass link-hover-color: red 70%; link-hover-color: black; ``` diff --git a/docs/styles/links/link_hover_style.md b/docs/styles/links/link_hover_style.md index 3a9d429db..e5917c7b2 100644 --- a/docs/styles/links/link_hover_style.md +++ b/docs/styles/links/link_hover_style.md @@ -54,7 +54,7 @@ It also shows that `link-hover-style` does not affect hyperlinks. === "link_hover_style.css" - ```css hl_lines="2 6 10" + ```sass hl_lines="2 6 10" --8<-- "docs/examples/styles/link_hover_style.css" ``` @@ -63,7 +63,7 @@ It also shows that `link-hover-style` does not affect hyperlinks. ## CSS -```css +```sass link-hover-style: bold; link-hover-style: bold italic reverse; ``` diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md index 336e5a437..000222b41 100644 --- a/docs/styles/links/link_style.md +++ b/docs/styles/links/link_style.md @@ -45,7 +45,7 @@ It also shows that `link-style` does not affect hyperlinks. === "link_style.css" - ```css hl_lines="2 6 10" + ```sass hl_lines="2 6 10" --8<-- "docs/examples/styles/link_style.css" ``` @@ -53,7 +53,7 @@ It also shows that `link-style` does not affect hyperlinks. ## CSS -```css +```sass link-style: bold; link-style: bold italic reverse; ``` diff --git a/docs/styles/margin.md b/docs/styles/margin.md index c537393d6..e5fba6f7d 100644 --- a/docs/styles/margin.md +++ b/docs/styles/margin.md @@ -49,7 +49,7 @@ In the example below we add a large margin to a label, which makes it move away === "margin.css" - ```css + ```sass --8<-- "docs/examples/styles/margin.css" ``` diff --git a/docs/styles/max_height.md b/docs/styles/max_height.md index 32f869755..02fb415ed 100644 --- a/docs/styles/max_height.md +++ b/docs/styles/max_height.md @@ -29,7 +29,7 @@ Then, we set `max-height` individually on each placeholder. === "max_height.css" - ```css + ```sass --8<-- "docs/examples/styles/max_height.css" ``` diff --git a/docs/styles/max_width.md b/docs/styles/max_width.md index 210fdab49..f0bee7ff9 100644 --- a/docs/styles/max_width.md +++ b/docs/styles/max_width.md @@ -29,7 +29,7 @@ Then, we set `max-width` individually on each placeholder. === "max_width.css" - ```scss + ```sass --8<-- "docs/examples/styles/max_width.css" ``` diff --git a/docs/styles/min_height.md b/docs/styles/min_height.md index 883351b38..a4e7c8c1d 100644 --- a/docs/styles/min_height.md +++ b/docs/styles/min_height.md @@ -29,7 +29,7 @@ Then, we set `min-height` individually on each placeholder. === "min_height.css" - ```css hl_lines="13" + ```sass hl_lines="13" --8<-- "docs/examples/styles/min_height.css" ``` diff --git a/docs/styles/min_width.md b/docs/styles/min_width.md index c64374097..d07926d8e 100644 --- a/docs/styles/min_width.md +++ b/docs/styles/min_width.md @@ -29,7 +29,7 @@ Then, we set `min-width` individually on each placeholder. === "min_width.css" - ```css hl_lines="13" + ```sass hl_lines="13" --8<-- "docs/examples/styles/min_width.css" ``` diff --git a/docs/styles/offset.md b/docs/styles/offset.md index ad113de9f..e09279dbd 100644 --- a/docs/styles/offset.md +++ b/docs/styles/offset.md @@ -32,7 +32,7 @@ In this example, we have 3 widgets with differing offsets. === "offset.css" - ```css + ```sass --8<-- "docs/examples/styles/offset.css" ``` diff --git a/docs/styles/opacity.md b/docs/styles/opacity.md index bf05fca28..e7baef264 100644 --- a/docs/styles/opacity.md +++ b/docs/styles/opacity.md @@ -26,7 +26,7 @@ When the opacity is zero, all we see is the (black) background. === "opacity.css" - ```scss + ```sass --8<-- "docs/examples/styles/opacity.css" ``` diff --git a/docs/styles/outline.md b/docs/styles/outline.md index 3b4c63764..427448773 100644 --- a/docs/styles/outline.md +++ b/docs/styles/outline.md @@ -39,7 +39,7 @@ This example shows a widget with an outline. Note how the outline occludes the t === "outline.css" - ```css + ```sass --8<-- "docs/examples/styles/outline.css" ``` @@ -60,7 +60,7 @@ This example also shows that a widget can contain both a `border` and an `outlin === "outline_vs_border.css" - ```css + ```sass --8<-- "docs/examples/styles/outline_vs_border.css" ``` diff --git a/docs/styles/overflow.md b/docs/styles/overflow.md index ba9296996..51b8acf89 100644 --- a/docs/styles/overflow.md +++ b/docs/styles/overflow.md @@ -47,7 +47,7 @@ The right side has `overflow-y: hidden` which will prevent a scrollbar from bein === "overflow.css" - ```css + ```sass --8<-- "docs/examples/styles/overflow.css" ``` diff --git a/docs/styles/padding.md b/docs/styles/padding.md index 439ed2a9e..38212b158 100644 --- a/docs/styles/padding.md +++ b/docs/styles/padding.md @@ -48,7 +48,7 @@ This example adds padding around some text. === "padding.css" - ```css + ```sass --8<-- "docs/examples/styles/padding.css" ``` diff --git a/docs/styles/scrollbar_colors/index.md b/docs/styles/scrollbar_colors/index.md index f3dd5b093..997891805 100644 --- a/docs/styles/scrollbar_colors/index.md +++ b/docs/styles/scrollbar_colors/index.md @@ -61,6 +61,6 @@ The right panel sets `scrollbar-background`, `scrollbar-color`, and `scrollbar-c === "scrollbars.css" - ```css + ```sass --8<-- "docs/examples/styles/scrollbars.css" ``` diff --git a/docs/styles/scrollbar_colors/scrollbar_background.md b/docs/styles/scrollbar_colors/scrollbar_background.md index e2792c67e..aa375a93f 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background.md +++ b/docs/styles/scrollbar_colors/scrollbar_background.md @@ -38,13 +38,13 @@ The `scrollbar-background` sets the background color of the scrollbar. === "scrollbars2.css" - ```css hl_lines="2" + ```sass hl_lines="2" --8<-- "docs/examples/styles/scrollbars2.css" ``` ## CSS -```css +```sass scrollbar-backround: blue; ``` diff --git a/docs/styles/scrollbar_colors/scrollbar_background_active.md b/docs/styles/scrollbar_colors/scrollbar_background_active.md index 2652418ee..be98ec44c 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_active.md @@ -39,13 +39,13 @@ The `scrollbar-background-active` sets the background color of the scrollbar whe === "scrollbars2.css" - ```css hl_lines="3" + ```sass hl_lines="3" --8<-- "docs/examples/styles/scrollbars2.css" ``` ## CSS -```css +```sass scrollbar-backround-active: red; ``` diff --git a/docs/styles/scrollbar_colors/scrollbar_background_hover.md b/docs/styles/scrollbar_colors/scrollbar_background_hover.md index b01ebe1b9..e815db3c7 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_hover.md @@ -39,13 +39,13 @@ The `scrollbar-background-hover` sets the background color of the scrollbar when === "scrollbars2.css" - ```css hl_lines="4" + ```sass hl_lines="4" --8<-- "docs/examples/styles/scrollbars2.css" ``` ## CSS -```css +```sass scrollbar-background-hover: purple; ``` diff --git a/docs/styles/scrollbar_colors/scrollbar_color.md b/docs/styles/scrollbar_colors/scrollbar_color.md index 421e67661..6d461dfcf 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_color.md @@ -39,13 +39,13 @@ The `scrollbar-color` sets the color of the scrollbar. === "scrollbars2.css" - ```css hl_lines="5" + ```sass hl_lines="5" --8<-- "docs/examples/styles/scrollbars2.css" ``` ## CSS -```css +```sass scrollbar-color: cyan; ``` diff --git a/docs/styles/scrollbar_colors/scrollbar_color_active.md b/docs/styles/scrollbar_colors/scrollbar_color_active.md index 6767790ff..dd38b9fd7 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_active.md @@ -39,13 +39,13 @@ The `scrollbar-color-active` sets the color of the scrollbar when the thumb is b === "scrollbars2.css" - ```css hl_lines="6" + ```sass hl_lines="6" --8<-- "docs/examples/styles/scrollbars2.css" ``` ## CSS -```css +```sass scrollbar-color-active: yellow; ``` diff --git a/docs/styles/scrollbar_colors/scrollbar_color_hover.md b/docs/styles/scrollbar_colors/scrollbar_color_hover.md index 3005d0da1..dde2c1443 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_hover.md @@ -39,13 +39,13 @@ The `scrollbar-color-hover` sets the color of the scrollbar when the cursor is o === "scrollbars2.css" - ```css hl_lines="7" + ```sass hl_lines="7" --8<-- "docs/examples/styles/scrollbars2.css" ``` ## CSS -```css +```sass scrollbar-color-hover: pink; ``` diff --git a/docs/styles/scrollbar_colors/scrollbar_corner_color.md b/docs/styles/scrollbar_colors/scrollbar_corner_color.md index 4edc582d4..65738a825 100644 --- a/docs/styles/scrollbar_colors/scrollbar_corner_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_corner_color.md @@ -37,13 +37,13 @@ The example below sets the scrollbar corner (bottom-right corner of the screen) === "scrollbar_corner_color.css" - ```css hl_lines="3" + ```sass hl_lines="3" --8<-- "docs/examples/styles/scrollbar_corner_color.css" ``` ## CSS -```css +```sass scrollbar-corner-color: white; ``` diff --git a/docs/styles/scrollbar_gutter.md b/docs/styles/scrollbar_gutter.md index c08ac4e2d..db5270303 100644 --- a/docs/styles/scrollbar_gutter.md +++ b/docs/styles/scrollbar_gutter.md @@ -35,7 +35,7 @@ terminal window. === "scrollbar_gutter.css" - ```scss hl_lines="2" + ```sass hl_lines="2" --8<-- "docs/examples/styles/scrollbar_gutter.css" ``` diff --git a/docs/styles/scrollbar_size.md b/docs/styles/scrollbar_size.md index 19c092971..d74073328 100644 --- a/docs/styles/scrollbar_size.md +++ b/docs/styles/scrollbar_size.md @@ -34,7 +34,7 @@ In this example we modify the size of the widget's scrollbar to be _much_ larger === "scrollbar_size.css" - ```css hl_lines="13" + ```sass hl_lines="13" --8<-- "docs/examples/styles/scrollbar_size.css" ``` @@ -53,7 +53,7 @@ In the next example we show three containers with differently sized scrollbars. === "scrollbar_size2.css" - ```css hl_lines="6 11 16" + ```sass hl_lines="6 11 16" --8<-- "docs/examples/styles/scrollbar_size2.css" ``` diff --git a/docs/styles/text_align.md b/docs/styles/text_align.md index 2eccff1e2..851962604 100644 --- a/docs/styles/text_align.md +++ b/docs/styles/text_align.md @@ -31,7 +31,7 @@ This example shows, from top to bottom: `left`, `center`, `right`, and `justify` === "text_align.css" - ```css hl_lines="2 7 12 17" + ```sass hl_lines="2 7 12 17" --8<-- "docs/examples/styles/text_align.css" ``` diff --git a/docs/styles/text_opacity.md b/docs/styles/text_opacity.md index 304aac548..006d9f3de 100644 --- a/docs/styles/text_opacity.md +++ b/docs/styles/text_opacity.md @@ -30,7 +30,7 @@ This example shows, from top to bottom, increasing `text-opacity` values. === "text_opacity.css" - ```css + ```sass --8<-- "docs/examples/styles/text_opacity.css" ``` diff --git a/docs/styles/text_style.md b/docs/styles/text_style.md index 19010325e..b89372eb4 100644 --- a/docs/styles/text_style.md +++ b/docs/styles/text_style.md @@ -27,7 +27,7 @@ Each of the three text panels has a different text style, respectively `bold`, ` === "text_style.css" - ```css + ```sass --8<-- "docs/examples/styles/text_style.css" ``` @@ -46,7 +46,7 @@ The next example shows all different styles on their own, as well as some combin === "text_style_all.css" - ```css + ```sass --8<-- "docs/examples/styles/text_style_all.css" ``` diff --git a/docs/styles/tint.md b/docs/styles/tint.md index e387b0bc7..5b0a86e6c 100644 --- a/docs/styles/tint.md +++ b/docs/styles/tint.md @@ -22,7 +22,7 @@ This examples shows a green tint with gradually increasing alpha. === "tint.css" - ```css + ```sass --8<-- "docs/examples/styles/tint.css" ``` diff --git a/docs/styles/visibility.md b/docs/styles/visibility.md index fbed34e8b..fb066d555 100644 --- a/docs/styles/visibility.md +++ b/docs/styles/visibility.md @@ -45,7 +45,7 @@ Note that the second widget is hidden, while leaving a space where it would have === "visibility.css" - ```css + ```sass --8<-- "docs/examples/styles/visibility.css" ``` @@ -70,7 +70,7 @@ The containers all have a white background, and then: === "visibility_containers.css" - ```css hl_lines="2-3 6 8-10 12-14 16-18" + ```sass hl_lines="2-3 6 8-10 12-14 16-18" --8<-- "docs/examples/styles/visibility_containers.css" ``` diff --git a/docs/styles/width.md b/docs/styles/width.md index dd349a5ae..32aa5a073 100644 --- a/docs/styles/width.md +++ b/docs/styles/width.md @@ -23,7 +23,7 @@ This example adds a widget with 50% width of the screen. === "width.css" - ```css + ```sass --8<-- "docs/examples/styles/width.css" ``` @@ -50,7 +50,7 @@ This example adds a widget with 50% width of the screen. === "width_comparison.css" - ```css hl_lines="2 5 8 11 14 17 20 23 26" + ```sass hl_lines="2 5 8 11 14 17 20 23 26" --8<-- "docs/examples/styles/width_comparison.css" ``` diff --git a/docs/widgets/button.md b/docs/widgets/button.md index 6683ee73a..ff7436d3b 100644 --- a/docs/widgets/button.md +++ b/docs/widgets/button.md @@ -25,7 +25,7 @@ Clicking any of the non-disabled buttons in the example app below will result th === "button.css" - ```css + ```sass --8<-- "docs/examples/widgets/button.css" ``` diff --git a/docs/widgets/checkbox.md b/docs/widgets/checkbox.md index c1ef5265a..6a8acc612 100644 --- a/docs/widgets/checkbox.md +++ b/docs/widgets/checkbox.md @@ -22,7 +22,7 @@ The example below shows checkboxes in various states. === "checkbox.css" - ```css + ```sass --8<-- "docs/examples/widgets/checkbox.css" ``` diff --git a/docs/widgets/placeholder.md b/docs/widgets/placeholder.md index be935d4a3..237573312 100644 --- a/docs/widgets/placeholder.md +++ b/docs/widgets/placeholder.md @@ -27,7 +27,7 @@ The example below shows each placeholder variant. === "placeholder.css" - ```css + ```sass --8<-- "docs/examples/widgets/placeholder.css" ``` From da9a481f1c104038e759a963ca297c27ed4c0680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 11:28:47 +0000 Subject: [PATCH 221/310] Remove inclusion of old css types snippets. Supposedly, this had been done in an earlier commit for all styles. Apparently, I forgot to open styles references that were one level deeper in the directory, so the pages about grid, links, and scrollbar colors still included the css types values directly in their reference pages. --- docs/styles/grid/column_span.md | 4 ---- docs/styles/grid/grid_columns.md | 4 ---- docs/styles/grid/grid_gutter.md | 4 ---- docs/styles/grid/grid_rows.md | 4 ---- docs/styles/grid/grid_size.md | 4 ---- docs/styles/grid/index.md | 11 ----------- docs/styles/grid/row_span.md | 4 ---- docs/styles/links/index.md | 14 -------------- docs/styles/links/link_background.md | 10 ---------- docs/styles/links/link_color.md | 10 ---------- docs/styles/links/link_hover_background.md | 10 ---------- docs/styles/links/link_hover_color.md | 10 ---------- docs/styles/links/link_hover_style.md | 4 ---- docs/styles/links/link_style.md | 4 ---- docs/styles/scrollbar_colors/index.md | 10 ---------- .../scrollbar_colors/scrollbar_background.md | 10 ---------- .../scrollbar_background_active.md | 10 ---------- .../scrollbar_colors/scrollbar_background_hover.md | 10 ---------- docs/styles/scrollbar_colors/scrollbar_color.md | 10 ---------- .../scrollbar_colors/scrollbar_color_active.md | 10 ---------- .../scrollbar_colors/scrollbar_color_hover.md | 10 ---------- .../scrollbar_colors/scrollbar_corner_color.md | 10 ---------- 22 files changed, 177 deletions(-) diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md index 72ba1a5f3..cb4fbe813 100644 --- a/docs/styles/grid/column_span.md +++ b/docs/styles/grid/column_span.md @@ -14,10 +14,6 @@ column-span: <integer>; The style `column-span` accepts a single non-negative [``](../../../css_types/integer) that quantifies how many columns the given widget spans. -### Values - ---8<-- "docs/snippets/type_syntax/integer.md" - ## Example The example below shows a 4 by 4 grid where many placeholders span over several columns. diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index ab6edb79c..6ea34dfff 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -17,10 +17,6 @@ The style `grid-columns` takes one or more [``](../../../css_types/scala If there are more columns in the grid than scalars specified in `grid-columns`, they are reused cyclically. If the number of [``](../../../css_types/scalar) is in excess, the excess is ignored. -### Values - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Example The example below shows a grid with 10 labels laid out in a grid with 2 rows and 5 columns. diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md index 9293c0672..1b61a1ae1 100644 --- a/docs/styles/grid/grid_gutter.md +++ b/docs/styles/grid/grid_gutter.md @@ -20,10 +20,6 @@ The style `grid-gutter` takes one or two [``](../../../css_types/scalar) If only one [``](../../../css_types/scalar) is supplied, it sets the vertical and horizontal gutters. If two are supplied, they set the vertical and horizontal gutters, respectively. -### Values - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Example The example below employs a common trick to apply visually consistent spacing around all grid cells. diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index dbf5a161a..94d87f856 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -17,10 +17,6 @@ The style `grid-rows` takes one or more [``](../../../css_types/scalar) If there are more rows in the grid than scalars specified in `grid-rows`, they are reused cyclically. If the number of [``](../../../css_types/scalar) is in excess, the excess is ignored. -### Values - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Example The example below shows a grid with 10 labels laid out in a grid with 5 rows and 2 columns. diff --git a/docs/styles/grid/grid_size.md b/docs/styles/grid/grid_size.md index 3752bdfba..812408906 100644 --- a/docs/styles/grid/grid_size.md +++ b/docs/styles/grid/grid_size.md @@ -18,10 +18,6 @@ The style `grid-size` takes one or two non-negative [``](../../../css_t The first defines how many columns there are in the grid. If present, the second one sets the number of rows – regardless of the number of children of the grid –, otherwise the number of rows is computed automatically. -### Values - ---8<-- "docs/snippets/type_syntax/integer.md" - ## Examples In the first example, we create a grid with 2 columns and 5 rows, regardless of the fact that we do not have enough labels to fill in the whole grid: diff --git a/docs/styles/grid/index.md b/docs/styles/grid/index.md index b96f1fbd5..c68172865 100644 --- a/docs/styles/grid/index.md +++ b/docs/styles/grid/index.md @@ -31,17 +31,6 @@ For an in-depth look at the grid layout, visit the grid [guide](../guide/layout. Visit each style's reference page to learn more about how the values are used. - -### Values - -#### <integer> - ---8<-- "docs/snippets/type_syntax/integer.md" - -#### <scalar> - ---8<-- "docs/snippets/type_syntax/scalar.md" - ## Example The example below shows all the properties above in action. diff --git a/docs/styles/grid/row_span.md b/docs/styles/grid/row_span.md index b7afb8146..a6e15c3ac 100644 --- a/docs/styles/grid/row_span.md +++ b/docs/styles/grid/row_span.md @@ -14,10 +14,6 @@ row-span: <integer>; The style `row-span` accepts a single non-negative [``](../../../css_types/integer) that quantifies how many rows the given widget spans. -### Values - ---8<-- "docs/snippets/type_syntax/integer.md" - ## Example The example below shows a 4 by 4 grid where many placeholders span over several rows. diff --git a/docs/styles/links/index.md b/docs/styles/links/index.md index edbc86bb5..031af1d6e 100644 --- a/docs/styles/links/index.md +++ b/docs/styles/links/index.md @@ -34,20 +34,6 @@ There are a number of styles which influence the appearance of these links withi Visit each style's reference page to learn more about how the values are used. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - -#### <text-style> - ---8<-- "docs/snippets/type_syntax/text_style.md" - ## Example In the example below, the first label illustrates default link styling. diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md index ab6e775f5..e171f3fcf 100644 --- a/docs/styles/links/link_background.md +++ b/docs/styles/links/link_background.md @@ -14,16 +14,6 @@ link-background: <color> [<color> [<color> [`](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the background color of text enclosed in Textual action links when the mouse pointer is over it. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ### Defaults If not provided, a Textual action link will have `link-hover-background` set to `$accent`. diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md index ec36aec95..026c8d264 100644 --- a/docs/styles/links/link_hover_color.md +++ b/docs/styles/links/link_hover_color.md @@ -14,16 +14,6 @@ link-hover-color: <color> [<text-style>; `link-hover-style` applies its [``](../../../css_types/text_style) to the text of Textual action links when the mouse pointer is over them. -### Values - ---8<-- "docs/snippets/type_syntax/text_style.md" - ### Defaults If not provided, a Textual action link will have `link-hover-style` set to `bold`. diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md index 000222b41..8c2eac88c 100644 --- a/docs/styles/links/link_style.md +++ b/docs/styles/links/link_style.md @@ -14,10 +14,6 @@ link-style: <text-style>; `link-style` will take all the values specified and will apply that styling to text that is enclosed by a Textual action link. -### Values - ---8<-- "docs/snippets/type_syntax/text_style.md" - ### Defaults If not provided, a Textual action link will have `link-style` set to `underline`. diff --git a/docs/styles/scrollbar_colors/index.md b/docs/styles/scrollbar_colors/index.md index 997891805..a136e00ea 100644 --- a/docs/styles/scrollbar_colors/index.md +++ b/docs/styles/scrollbar_colors/index.md @@ -33,16 +33,6 @@ You won't typically need to do this, as the default themes have carefully chosen Visit each style's reference page to learn more about how the values are used. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ## Example This example shows two planels that contain oversized text. diff --git a/docs/styles/scrollbar_colors/scrollbar_background.md b/docs/styles/scrollbar_colors/scrollbar_background.md index aa375a93f..97fe18f61 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background.md +++ b/docs/styles/scrollbar_colors/scrollbar_background.md @@ -9,16 +9,6 @@ The `scrollbar-background` sets the background color of the scrollbar. `scrollbar-background` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the background color of a scrollbar. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ## Example === "Output" diff --git a/docs/styles/scrollbar_colors/scrollbar_background_active.md b/docs/styles/scrollbar_colors/scrollbar_background_active.md index be98ec44c..6f83a2622 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_active.md @@ -10,16 +10,6 @@ The `scrollbar-background-active` sets the background color of the scrollbar whe `scrollbar-background-active` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the background color of a scrollbar when its thumb is being dragged. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ## Example === "Output" diff --git a/docs/styles/scrollbar_colors/scrollbar_background_hover.md b/docs/styles/scrollbar_colors/scrollbar_background_hover.md index e815db3c7..fd4349f91 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_hover.md @@ -10,16 +10,6 @@ The `scrollbar-background-hover` sets the background color of the scrollbar when `scrollbar-background-hover` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the background color of a scrollbar when the cursor is over it. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ## Example === "Output" diff --git a/docs/styles/scrollbar_colors/scrollbar_color.md b/docs/styles/scrollbar_colors/scrollbar_color.md index 6d461dfcf..5b1bb92be 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_color.md @@ -10,16 +10,6 @@ The `scrollbar-color` sets the color of the scrollbar. `scrollbar-color` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of a scrollbar. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ## Example === "Output" diff --git a/docs/styles/scrollbar_colors/scrollbar_color_active.md b/docs/styles/scrollbar_colors/scrollbar_color_active.md index dd38b9fd7..57fba7383 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_active.md @@ -10,16 +10,6 @@ The `scrollbar-color-active` sets the color of the scrollbar when the thumb is b `scrollbar-color-active` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of a scrollbar when its thumb is being dragged. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ## Example === "Output" diff --git a/docs/styles/scrollbar_colors/scrollbar_color_hover.md b/docs/styles/scrollbar_colors/scrollbar_color_hover.md index dde2c1443..a3fe72153 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_hover.md @@ -10,16 +10,6 @@ The `scrollbar-color-hover` sets the color of the scrollbar when the cursor is o `scrollbar-color-hover` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of a scrollbar when the cursor is over it. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ## Example === "Output" diff --git a/docs/styles/scrollbar_colors/scrollbar_corner_color.md b/docs/styles/scrollbar_colors/scrollbar_corner_color.md index 65738a825..05b3517c3 100644 --- a/docs/styles/scrollbar_colors/scrollbar_corner_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_corner_color.md @@ -10,16 +10,6 @@ The `scrollbar-corner-color` sets the color of the gap between the horizontal an `scrollbar-corner-color` accepts a [``](../../../css_types/color) (with an optional transparency level defined by a [``](../../../css_types/percentage)) that is used to define the color of the gap between the horizontal and vertical scrollbars of a widget. -### Values - -#### <color> - ---8<-- "docs/snippets/type_syntax/color.md" - -#### <percentage> - ---8<-- "docs/snippets/type_syntax/percentage.md" - ## Example The example below sets the scrollbar corner (bottom-right corner of the screen) to white. From 34ff6bf26077feefad2ca7ae2588ea66e92dc3fc Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 11:47:40 +0000 Subject: [PATCH 222/310] Add some unit tests for Tree messages/event handling I'm about to work on #1400 and it seems like a good idea to put some tests in place first to ensure nothing gets disturbed. --- tests/tree/test_tree_messages.py | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 tests/tree/test_tree_messages.py diff --git a/tests/tree/test_tree_messages.py b/tests/tree/test_tree_messages.py new file mode 100644 index 000000000..4a6d65ce2 --- /dev/null +++ b/tests/tree/test_tree_messages.py @@ -0,0 +1,54 @@ +from typing import Any +from textual.app import App, ComposeResult +from textual.widgets import Tree +from textual.message import Message + + +class TreeApp(App[None]): + """Test tree app.""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.messages: list[str] = [] + + def compose(self) -> ComposeResult: + """Compose the child widgets.""" + yield Tree[None]("Root") + + def on_mount(self) -> None: + """""" + self.query_one(Tree[None]).root.add("Child") + self.query_one(Tree[None]).focus() + + def record(self, event: Message) -> None: + self.messages.append(event.__class__.__name__) + + def on_tree_node_selected(self, event: Tree.NodeSelected[None]) -> None: + self.record(event) + + def on_tree_node_expanded(self, event: Tree.NodeExpanded[None]) -> None: + self.record(event) + + def on_tree_node_collapsed(self, event: Tree.NodeCollapsed[None]) -> None: + self.record(event) + + +async def test_tree_node_selected_message() -> None: + """Selecting a node should result in a selected message being emitted.""" + async with TreeApp().run_test() as pilot: + await pilot.press("enter") + assert pilot.app.messages[-1] == "NodeSelected" + + +async def test_tree_node_expanded_message() -> None: + """Expanding a node should result in an expanded message being emitted.""" + async with TreeApp().run_test() as pilot: + await pilot.press("enter") + assert pilot.app.messages[0] == "NodeExpanded" + + +async def test_tree_node_collapsed_message() -> None: + """Collapsing a node should result in a collapsed message being emitted.""" + async with TreeApp().run_test() as pilot: + await pilot.press("enter", "enter") + assert pilot.app.messages[-2] == "NodeCollapsed" From 9226e90a5523a4e493fff10021240b37be022e4d Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 12:21:21 +0000 Subject: [PATCH 223/310] Give the existing node messages a common base class All three do the same thing, so we may as well give them a common base; especially given that we're about to go and add yet another message that'll do the same thing again but only (because we need it to) differ in name. --- src/textual/widgets/_tree.py | 37 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index 866a4d7ce..14801c039 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -331,45 +331,40 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): ), } - class NodeSelected(Generic[EventTreeDataType], Message, bubble=True): + class NodeMessage(Generic[EventTreeDataType], Message, bubble=True): + """Base class for events sent when something happens with a node. + + Attributes: + TreeNode[EventTreeDataType]: The node involved in the event. + """ + + def __init__( + self, sender: MessageTarget, node: TreeNode[EventTreeDataType] + ) -> None: + self.node = node + super().__init__(sender) + + class NodeSelected(NodeMessage[EventTreeDataType]): """Event sent when a node is selected. Attributes: TreeNode[EventTreeDataType]: The node that was selected. """ - def __init__( - self, sender: MessageTarget, node: TreeNode[EventTreeDataType] - ) -> None: - self.node = node - super().__init__(sender) - - class NodeExpanded(Generic[EventTreeDataType], Message, bubble=True): + class NodeExpanded(NodeMessage[EventTreeDataType]): """Event sent when a node is expanded. Attributes: TreeNode[EventTreeDataType]: The node that was expanded. """ - def __init__( - self, sender: MessageTarget, node: TreeNode[EventTreeDataType] - ) -> None: - self.node = node - super().__init__(sender) - - class NodeCollapsed(Generic[EventTreeDataType], Message, bubble=True): + class NodeCollapsed(NodeMessage[EventTreeDataType]): """Event sent when a node is collapsed. Attributes: TreeNode[EventTreeDataType]: The node that was collapsed. """ - def __init__( - self, sender: MessageTarget, node: TreeNode[EventTreeDataType] - ) -> None: - self.node = node - super().__init__(sender) - def __init__( self, label: TextType, From 6f10c63bb0ff8d9444a0762a40e4ec83c63d8533 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 12:54:26 +0000 Subject: [PATCH 224/310] Perform tests on all recorded tree events --- tests/tree/test_tree_messages.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/tree/test_tree_messages.py b/tests/tree/test_tree_messages.py index 4a6d65ce2..01a2f2645 100644 --- a/tests/tree/test_tree_messages.py +++ b/tests/tree/test_tree_messages.py @@ -37,18 +37,23 @@ async def test_tree_node_selected_message() -> None: """Selecting a node should result in a selected message being emitted.""" async with TreeApp().run_test() as pilot: await pilot.press("enter") - assert pilot.app.messages[-1] == "NodeSelected" + assert pilot.app.messages == ["NodeExpanded", "NodeSelected"] async def test_tree_node_expanded_message() -> None: """Expanding a node should result in an expanded message being emitted.""" async with TreeApp().run_test() as pilot: await pilot.press("enter") - assert pilot.app.messages[0] == "NodeExpanded" + assert pilot.app.messages == ["NodeExpanded", "NodeSelected"] async def test_tree_node_collapsed_message() -> None: """Collapsing a node should result in a collapsed message being emitted.""" async with TreeApp().run_test() as pilot: await pilot.press("enter", "enter") - assert pilot.app.messages[-2] == "NodeCollapsed" + assert pilot.app.messages == [ + "NodeExpanded", + "NodeSelected", + "NodeCollapsed", + "NodeSelected", + ] From 0cf299540fa9d8b8630c0d6fe4a95e0deb8799a8 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 12:54:57 +0000 Subject: [PATCH 225/310] Add a message for when a node is highlighted This is sort of different from selected. Selected is when someone mashes the enter button or clicks on a node. Highlighted is when the cursor moves into a new node. See #1400. --- src/textual/widgets/_tree.py | 9 +++++++++ tests/tree/test_tree_messages.py | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index 14801c039..7b33db8c8 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -365,6 +365,13 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): TreeNode[EventTreeDataType]: The node that was collapsed. """ + class NodeHighlighted(NodeMessage[EventTreeDataType]): + """Event sent when a node is highlighted. + + Attributes: + TreeNode[EventTreeDataType]: The node that was collapsed. + """ + def __init__( self, label: TextType, @@ -573,6 +580,8 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): self._refresh_node(node) node._selected = True self._cursor_node = node + if previous_node != node: + self.post_message_no_wait(self.NodeHighlighted(self, node)) def watch_guide_depth(self, guide_depth: int) -> None: self._invalidate() diff --git a/tests/tree/test_tree_messages.py b/tests/tree/test_tree_messages.py index 01a2f2645..ff2d8069c 100644 --- a/tests/tree/test_tree_messages.py +++ b/tests/tree/test_tree_messages.py @@ -32,6 +32,9 @@ class TreeApp(App[None]): def on_tree_node_collapsed(self, event: Tree.NodeCollapsed[None]) -> None: self.record(event) + def on_tree_node_highlighted(self, event: Tree.NodeHighlighted[None]) -> None: + self.record(event) + async def test_tree_node_selected_message() -> None: """Selecting a node should result in a selected message being emitted.""" @@ -57,3 +60,10 @@ async def test_tree_node_collapsed_message() -> None: "NodeCollapsed", "NodeSelected", ] + + +async def test_tree_node_highlighted_message() -> None: + """Highlighting a node should result in a highlighted message being emitted.""" + async with TreeApp().run_test() as pilot: + await pilot.press("enter", "down") + assert pilot.app.messages == ["NodeExpanded", "NodeSelected", "NodeHighlighted"] From 57687ccacf013abcacd3745a29519d092863b713 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 12:57:23 +0000 Subject: [PATCH 226/310] Update the ChangeLog with details about Tree.NodeHighlighted --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90bb8ddc2..34d161158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `TreeNode.parent` -- a read-only property for accessing a node's parent https://github.com/Textualize/textual/issues/1397 - Added public `TreeNode` label access via `TreeNode.label` https://github.com/Textualize/textual/issues/1396 - Added read-only public access to the children of a `TreeNode` via `TreeNode.children` https://github.com/Textualize/textual/issues/1398 +- Added a `Tree.NodeHighlighted` message, giving a `on_tree_node_highlighted` event handler https://github.com/Textualize/textual/issues/1400 ### Changed From 151673cd53d2703b2ac8e5aa30aab428a5dc211e Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:12:57 +0000 Subject: [PATCH 227/310] Remove empty docstring --- tests/tree/test_tree_messages.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/tree/test_tree_messages.py b/tests/tree/test_tree_messages.py index ff2d8069c..50d0fa3e8 100644 --- a/tests/tree/test_tree_messages.py +++ b/tests/tree/test_tree_messages.py @@ -16,7 +16,6 @@ class TreeApp(App[None]): yield Tree[None]("Root") def on_mount(self) -> None: - """""" self.query_one(Tree[None]).root.add("Child") self.query_one(Tree[None]).focus() From c00a6da90dff912f6c14d55afa5c4da30f86887b Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:13:54 +0000 Subject: [PATCH 228/310] Check if I need to import from the future for Python 3.8 --- tests/tree/test_tree_messages.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/tree/test_tree_messages.py b/tests/tree/test_tree_messages.py index 50d0fa3e8..1537c8c00 100644 --- a/tests/tree/test_tree_messages.py +++ b/tests/tree/test_tree_messages.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from textual.app import App, ComposeResult from textual.widgets import Tree From 346659f47f6533e318d276cb2425b00130e4f8f7 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:28:25 +0000 Subject: [PATCH 229/310] Move typing of the tree into its own class --- tests/tree/test_tree_messages.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/tree/test_tree_messages.py b/tests/tree/test_tree_messages.py index 1537c8c00..67620d70e 100644 --- a/tests/tree/test_tree_messages.py +++ b/tests/tree/test_tree_messages.py @@ -6,6 +6,10 @@ from textual.widgets import Tree from textual.message import Message +class MyTree(Tree[None]): + pass + + class TreeApp(App[None]): """Test tree app.""" @@ -15,11 +19,11 @@ class TreeApp(App[None]): def compose(self) -> ComposeResult: """Compose the child widgets.""" - yield Tree[None]("Root") + yield MyTree("Root") def on_mount(self) -> None: - self.query_one(Tree[None]).root.add("Child") - self.query_one(Tree[None]).focus() + self.query_one(MyTree).root.add("Child") + self.query_one(MyTree).focus() def record(self, event: Message) -> None: self.messages.append(event.__class__.__name__) From 489ba10c8aff4ea7c8f71f093e90dc967f89374b Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:36:29 +0000 Subject: [PATCH 230/310] Sprinkle some pauses into the node message tests --- tests/tree/test_tree_messages.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/tree/test_tree_messages.py b/tests/tree/test_tree_messages.py index 67620d70e..f271d4e42 100644 --- a/tests/tree/test_tree_messages.py +++ b/tests/tree/test_tree_messages.py @@ -45,6 +45,7 @@ async def test_tree_node_selected_message() -> None: """Selecting a node should result in a selected message being emitted.""" async with TreeApp().run_test() as pilot: await pilot.press("enter") + await pilot.pause(2 / 100) assert pilot.app.messages == ["NodeExpanded", "NodeSelected"] @@ -52,6 +53,7 @@ async def test_tree_node_expanded_message() -> None: """Expanding a node should result in an expanded message being emitted.""" async with TreeApp().run_test() as pilot: await pilot.press("enter") + await pilot.pause(2 / 100) assert pilot.app.messages == ["NodeExpanded", "NodeSelected"] @@ -59,6 +61,7 @@ async def test_tree_node_collapsed_message() -> None: """Collapsing a node should result in a collapsed message being emitted.""" async with TreeApp().run_test() as pilot: await pilot.press("enter", "enter") + await pilot.pause(2 / 100) assert pilot.app.messages == [ "NodeExpanded", "NodeSelected", @@ -71,4 +74,5 @@ async def test_tree_node_highlighted_message() -> None: """Highlighting a node should result in a highlighted message being emitted.""" async with TreeApp().run_test() as pilot: await pilot.press("enter", "down") + await pilot.pause(2 / 100) assert pilot.app.messages == ["NodeExpanded", "NodeSelected", "NodeHighlighted"] From 71b859b6e255dac458cd41d5912466614019c931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:49:32 +0000 Subject: [PATCH 231/310] Add thorough example for all outlines. --- docs/examples/styles/outline_all.css | 72 ++++++++++++++++++++++++++++ docs/examples/styles/outline_all.py | 26 ++++++++++ 2 files changed, 98 insertions(+) create mode 100644 docs/examples/styles/outline_all.css create mode 100644 docs/examples/styles/outline_all.py diff --git a/docs/examples/styles/outline_all.css b/docs/examples/styles/outline_all.css new file mode 100644 index 000000000..63215bae7 --- /dev/null +++ b/docs/examples/styles/outline_all.css @@ -0,0 +1,72 @@ +#ascii { + outline: ascii $accent; +} + +#blank { + outline: blank $accent; +} + +#dashed { + outline: dashed $accent; +} + +#double { + outline: double $accent; +} + +#heavy { + outline: heavy $accent; +} + +#hidden { + outline: hidden $accent; +} + +#hkey { + outline: hkey $accent; +} + +#inner { + outline: inner $accent; +} + +#none { + outline: none $accent; +} + +#outer { + outline: outer $accent; +} + +#round { + outline: round $accent; +} + +#solid { + outline: solid $accent; +} + +#tall { + outline: tall $accent; +} + +#vkey { + outline: vkey $accent; +} + +#wide { + outline: wide $accent; +} + +Grid { + grid-size: 3 5; + align: center middle; + grid-gutter: 1 2; +} + +Label { + width: 20; + height: 3; + content-align: center middle; + background: red; +} diff --git a/docs/examples/styles/outline_all.py b/docs/examples/styles/outline_all.py new file mode 100644 index 000000000..5c7a5f445 --- /dev/null +++ b/docs/examples/styles/outline_all.py @@ -0,0 +1,26 @@ +from textual.app import App +from textual.containers import Grid +from textual.widgets import Label + + +class AllOutlinesApp(App): + def compose(self): + yield Grid( + Label("ascii", id="ascii"), + Label("blank", id="blank"), + Label("dashed", id="dashed"), + Label("double", id="double"), + Label("heavy", id="heavy"), + Label("hidden/none", id="hidden"), + Label("hkey", id="hkey"), + Label("inner", id="inner"), + Label("none", id="none"), + Label("outer", id="outer"), + Label("round", id="round"), + Label("solid", id="solid"), + Label("tall", id="tall"), + Label("vkey", id="vkey"), + Label("wide", id="wide"), + ) + +app = AllOutlinesApp(css_path="outline_all.css") From dd6e73aa39ed5cf6135403f8e25ba702471a2923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:50:45 +0000 Subject: [PATCH 232/310] Add subsections for references with 2+ examples. --- docs/styles/align.md | 4 ++++ docs/styles/background.md | 4 ++++ docs/styles/border.md | 28 ++++++++++++++++++++++++++++ docs/styles/color.md | 4 ++++ docs/styles/content_align.md | 4 ++++ docs/styles/dock.md | 4 ++++ docs/styles/grid/grid_size.md | 4 ++++ docs/styles/height.md | 4 ++++ docs/styles/margin.md | 4 ++++ docs/styles/outline.md | 30 ++++++++++++++++++++++++++++-- docs/styles/scrollbar_size.md | 4 ++++ docs/styles/text_style.md | 4 ++++ docs/styles/visibility.md | 4 ++++ docs/styles/width.md | 5 +++-- 14 files changed, 103 insertions(+), 4 deletions(-) diff --git a/docs/styles/align.md b/docs/styles/align.md index ba6298917..37a42802e 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -23,6 +23,8 @@ To specify alignment on a single axis, use the respective style and type: ## Examples +### Basic usage + This example contains a simple app with two labels centered on the screen with `align: center middle;`: === "align.py" @@ -43,6 +45,8 @@ This example contains a simple app with two labels centered on the screen with ` ``` +### All alignments + The next example shows a 3 by 3 grid of containers with text labels. Each label has been aligned differently inside its container, and its text shows its `align: ...` value. diff --git a/docs/styles/background.md b/docs/styles/background.md index c10baa28e..bae1e3805 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -12,6 +12,8 @@ The style `background` needs a [``](../../css_types/color) followed by an ## Examples +### Basic usage + This example creates three widgets and applies a different background to each. === "background.py" @@ -31,6 +33,8 @@ This example creates three widgets and applies a different background to each. ```{.textual path="docs/examples/styles/background.py"} ``` +### Different transparency settings + The next example creates ten widgets layed out side by side to show the effect of setting different percentages for the transparency of the background color. === "background_transparency.py" diff --git a/docs/styles/border.md b/docs/styles/border.md index 017fcb9e9..cda0434ec 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -54,6 +54,8 @@ Alternatively, you can see the examples below. ## Examples +### Basic usage + This examples shows three widgets with different border styles. === "border.py" @@ -73,6 +75,8 @@ This examples shows three widgets with different border styles. ```{.textual path="docs/examples/styles/border.py"} ``` +### All border types + The next example shows a grid with all the available border types. === "border_all.py" @@ -92,6 +96,30 @@ The next example shows a grid with all the available border types. ```{.textual path="docs/examples/styles/border_all.py"} ``` +### Borders and outlines + +The next example makes the difference between [`border`](./border.md) and [`outline`](./outline.md) clearer by having three labels side-by-side. +They contain the same text, have the same width and height, and are styled exactly the same up to their `outline` and [`border`](./border.md) rules. + +This example also shows that a widget cannot contain both a `border` and an `outline`: + +=== "Output" + + ```{.textual path="docs/examples/styles/outline_vs_border.py"} + ``` + +=== "outline_vs_border.py" + + ```python + --8<-- "docs/examples/styles/outline_vs_border.py" + ``` + +=== "outline_vs_border.css" + + ```sass + --8<-- "docs/examples/styles/outline_vs_border.css" + ``` + ## CSS ```sass diff --git a/docs/styles/color.md b/docs/styles/color.md index 8fa321fc4..f253e4063 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -14,6 +14,8 @@ Instead of a [``](../../css_types/color), one can use the special value ` ## Examples +### Basic usage + This example sets a different text color for each of three different widgets. === "color.py" @@ -33,6 +35,8 @@ This example sets a different text color for each of three different widgets. ```{.textual path="docs/examples/styles/color.py"} ``` +### Auto + The next example shows how `auto` chooses between a lighter or a darker text color to increase the contrast and improve readability. === "color_auto.py" diff --git a/docs/styles/content_align.md b/docs/styles/content_align.md index 462bf8548..f3a09243c 100644 --- a/docs/styles/content_align.md +++ b/docs/styles/content_align.md @@ -24,6 +24,8 @@ To specify content alignment on a single axis, use the respective style and type ## Examples +### Basic usage + This first example shows three labels stacked vertically, each with different content alignments. === "content_align.py" @@ -43,6 +45,8 @@ This first example shows three labels stacked vertically, each with different co ```{.textual path="docs/examples/styles/content_align.py"} ``` +### All content alignments + The next example shows a 3 by 3 grid of labels. Each label has its text aligned differently. diff --git a/docs/styles/dock.md b/docs/styles/dock.md index 75d72eb23..d8c4e1477 100644 --- a/docs/styles/dock.md +++ b/docs/styles/dock.md @@ -12,6 +12,8 @@ The option chosen determines the edge to which the widget is docked. ## Examples +### Basic usage + The example below shows a `left` docked sidebar. Notice that even though the content is scrolled, the sidebar remains fixed. @@ -32,6 +34,8 @@ Notice that even though the content is scrolled, the sidebar remains fixed. --8<-- "docs/examples/guide/layout/dock_layout1_sidebar.css" ``` +### Advanced usage + The second example shows how one can use full-width or full-height containers to dock labels to the edges of a larger container. The labels will remain in that position (docked) even if the container they are in scrolls horizontally and/or vertically. diff --git a/docs/styles/grid/grid_size.md b/docs/styles/grid/grid_size.md index 812408906..e8dd30293 100644 --- a/docs/styles/grid/grid_size.md +++ b/docs/styles/grid/grid_size.md @@ -20,6 +20,8 @@ If present, the second one sets the number of rows – regardless of the number ## Examples +### Columns and rows + In the first example, we create a grid with 2 columns and 5 rows, regardless of the fact that we do not have enough labels to fill in the whole grid: === "Output" @@ -41,6 +43,8 @@ In the first example, we create a grid with 2 columns and 5 rows, regardless of 1. Create a grid with 2 columns and 4 rows. +### Columns only + In the second example, we create a grid with 2 columns and however many rows are needed to display all of the grid children: === "Output" diff --git a/docs/styles/height.md b/docs/styles/height.md index e9c558d50..5dbc1d4b7 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -13,6 +13,8 @@ By default, it sets the height of the content area, but if [`box-sizing`](./box_ ## Examples +### Basic usage + This examples creates a widget with a height of 50% of the screen. === "height.py" @@ -32,6 +34,8 @@ This examples creates a widget with a height of 50% of the screen. ```{.textual path="docs/examples/styles/height.py"} ``` +### All height formats + The next example creates a series of wide widgets with heights set with different units. Open the CSS file tab to see the comments that explain how each height is computed. (The output includes a vertical ruler on the right to make it easier to check the height of each widget.) diff --git a/docs/styles/margin.md b/docs/styles/margin.md index e5fba6f7d..641f9c29d 100644 --- a/docs/styles/margin.md +++ b/docs/styles/margin.md @@ -34,6 +34,8 @@ Alternatively, margin can be set for each edge individually through the rules `m ## Examples +### Basic usage + In the example below we add a large margin to a label, which makes it move away from the top-left corner of the screen. === "Output" @@ -53,6 +55,8 @@ In the example below we add a large margin to a label, which makes it move away --8<-- "docs/examples/styles/margin.css" ``` +### All margin settings + The next example shows a grid. In each cell, we have a placeholder that has its margins set in different ways. diff --git a/docs/styles/outline.md b/docs/styles/outline.md index 427448773..e63995647 100644 --- a/docs/styles/outline.md +++ b/docs/styles/outline.md @@ -24,6 +24,8 @@ This rule can be useful for temporary emphasis of the content of a widget, if yo ## Examples +### Basic usage + This example shows a widget with an outline. Note how the outline occludes the text area. === "Output" @@ -43,9 +45,33 @@ This example shows a widget with an outline. Note how the outline occludes the t --8<-- "docs/examples/styles/outline.css" ``` -The next example makes the difference clearer, by having three labels side-by-side. +### All outline types + +The next example shows a grid with all the available outline types. + +=== "outline_all.py" + + ```py + --8<-- "docs/examples/styles/outline_all.py" + ``` + +=== "outline_all.css" + + ```sass + --8<-- "docs/examples/styles/outline_all.css" + ``` + +=== "Output" + + ```{.textual path="docs/examples/styles/outline_all.py"} + ``` + +### Borders and outlines + +The next example makes the difference between [`border`](./border.md) and [`outline`](./outline.md) clearer by having three labels side-by-side. They contain the same text, have the same width and height, and are styled exactly the same up to their `outline` and [`border`](./border.md) rules. -This example also shows that a widget can contain both a `border` and an `outline`: + +This example also shows that a widget cannot contain both a `border` and an `outline`: === "Output" diff --git a/docs/styles/scrollbar_size.md b/docs/styles/scrollbar_size.md index d74073328..2e5a6cfff 100644 --- a/docs/styles/scrollbar_size.md +++ b/docs/styles/scrollbar_size.md @@ -19,6 +19,8 @@ The scrollbar widths may also be set individually with `scrollbar-size-horizonta ## Examples +### Basic usage + In this example we modify the size of the widget's scrollbar to be _much_ larger than usual. === "Output" @@ -38,6 +40,8 @@ In this example we modify the size of the widget's scrollbar to be _much_ larger --8<-- "docs/examples/styles/scrollbar_size.css" ``` +### Scrollbar sizes comparison + In the next example we show three containers with differently sized scrollbars. === "Output" diff --git a/docs/styles/text_style.md b/docs/styles/text_style.md index b89372eb4..f8a91a2e8 100644 --- a/docs/styles/text_style.md +++ b/docs/styles/text_style.md @@ -12,6 +12,8 @@ text-style: <text-style>; ## Examples +### Basic usage + Each of the three text panels has a different text style, respectively `bold`, `italic`, and `reverse`, from left to right. === "Output" @@ -31,6 +33,8 @@ Each of the three text panels has a different text style, respectively `bold`, ` --8<-- "docs/examples/styles/text_style.css" ``` +### All text styles + The next example shows all different styles on their own, as well as some combinations of styles in a single widget. === "Output" diff --git a/docs/styles/visibility.md b/docs/styles/visibility.md index fb066d555..9a925a78c 100644 --- a/docs/styles/visibility.md +++ b/docs/styles/visibility.md @@ -30,6 +30,8 @@ This is shown in the second example below. ## Examples +### Basic usage + Note that the second widget is hidden, while leaving a space where it would have been rendered. === "Output" @@ -49,6 +51,8 @@ Note that the second widget is hidden, while leaving a space where it would have --8<-- "docs/examples/styles/visibility.css" ``` +### Overriding container visibility + The next example shows the interaction of the `visibility` rule with invisible containers that have visible children. The app below has three rows with a `Horizontal` container per row and three placeholders per row. The containers all have a white background, and then: diff --git a/docs/styles/width.md b/docs/styles/width.md index 32aa5a073..901a23839 100644 --- a/docs/styles/width.md +++ b/docs/styles/width.md @@ -13,6 +13,8 @@ By default, it sets the width of the content area, but if [`box-sizing`](./box_s ## Examples +### Basic usage + This example adds a widget with 50% width of the screen. === "width.py" @@ -32,8 +34,7 @@ This example adds a widget with 50% width of the screen. ```{.textual path="docs/examples/styles/width.py"} ``` ---- - +### All width formats === "Output" From e7afcbc0b57cb1fcda27548976927bf1d3885028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:52:02 +0000 Subject: [PATCH 233/310] Add reference to 'textual borders' command. --- docs/styles/outline.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/styles/outline.md b/docs/styles/outline.md index e63995647..759949586 100644 --- a/docs/styles/outline.md +++ b/docs/styles/outline.md @@ -22,6 +22,14 @@ The style `outline` accepts an optional [``](../../css_types/border) tha Unlike the style [`border`](./border.md), the frame of the outline is drawn over the content area of the widget. This rule can be useful for temporary emphasis of the content of a widget, if you want to draw the user's attention to it. +## Border command + +The `textual` CLI has a subcommand which will let you explore the various border types interactively, when applied to the CSS rule [`border`](../styles/border.md): + +``` +textual borders +``` + ## Examples ### Basic usage From 04ef895626c90c9b3b3e76eec93b0d812b04baec Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:55:53 +0000 Subject: [PATCH 234/310] Run black over child widget moving tests --- tests/test_widget_child_moving.py | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/tests/test_widget_child_moving.py b/tests/test_widget_child_moving.py index 43aa849eb..d9e15de66 100644 --- a/tests/test_widget_child_moving.py +++ b/tests/test_widget_child_moving.py @@ -3,6 +3,7 @@ import pytest from textual.app import App from textual.widget import Widget, WidgetError + async def test_widget_move_child() -> None: """Test moving a widget in a child list.""" @@ -35,29 +36,24 @@ async def test_widget_move_child() -> None: pilot.app.screen.move_child(child, before=Widget()) # Make a background set of widgets. - widgets = [Widget(id=f"widget-{n}") for n in range( 10 )] + widgets = [Widget(id=f"widget-{n}") for n in range(10)] # Test attempting to move past the end of the child list. async with App().run_test() as pilot: container = Widget(*widgets) await pilot.app.mount(container) with pytest.raises(WidgetError): - container.move_child(widgets[0], before=len(widgets)+10) + container.move_child(widgets[0], before=len(widgets) + 10) # Test attempting to move before the end of the child list. async with App().run_test() as pilot: container = Widget(*widgets) await pilot.app.mount(container) with pytest.raises(WidgetError): - container.move_child(widgets[0], before=-(len(widgets)+10)) + container.move_child(widgets[0], before=-(len(widgets) + 10)) # Test the different permutations of moving one widget before another. - perms = ( - ( 1, 0 ), - ( widgets[1], 0 ), - ( 1, widgets[ 0 ] ), - ( widgets[ 1 ], widgets[ 0 ]) - ) + perms = ((1, 0), (widgets[1], 0), (1, widgets[0]), (widgets[1], widgets[0])) for child, target in perms: async with App().run_test() as pilot: container = Widget(*widgets) @@ -68,12 +64,7 @@ async def test_widget_move_child() -> None: assert container.children[2].id == "widget-2" # Test the different permutations of moving one widget after another. - perms = ( - ( 0, 1 ), - ( widgets[0], 1 ), - ( 0, widgets[ 1 ] ), - ( widgets[ 0 ], widgets[ 1 ]) - ) + perms = ((0, 1), (widgets[0], 1), (0, widgets[1]), (widgets[0], widgets[1])) for child, target in perms: async with App().run_test() as pilot: container = Widget(*widgets) From 06ab4f4d706d5320cad45718c1fb76263b1a79f0 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:56:35 +0000 Subject: [PATCH 235/310] Run black over child focus tests --- tests/test_focus.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_focus.py b/tests/test_focus.py index 67a8b1a92..99a6d443d 100644 --- a/tests/test_focus.py +++ b/tests/test_focus.py @@ -10,6 +10,7 @@ class Focusable(Widget, can_focus=True): class NonFocusable(Widget, can_focus=False, can_focus_children=False): pass + class ChildrenFocusableOnly(Widget, can_focus=False, can_focus_children=True): pass From 1300807b3a6a7a6ff3cd5b747aaf2034238df194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:57:04 +0000 Subject: [PATCH 236/310] Put example outputs in first tab. --- docs/styles/align.md | 21 ++++++++++----------- docs/styles/background.md | 20 ++++++++++---------- docs/styles/border.md | 20 ++++++++++---------- docs/styles/box_sizing.md | 10 +++++----- docs/styles/color.md | 20 ++++++++++---------- docs/styles/content_align.md | 20 ++++++++++---------- docs/styles/display.md | 10 +++++----- docs/styles/height.md | 10 +++++----- docs/styles/layout.md | 10 +++++----- docs/styles/opacity.md | 10 +++++----- docs/styles/outline.md | 10 +++++----- docs/styles/tint.md | 10 +++++----- docs/styles/width.md | 10 +++++----- 13 files changed, 90 insertions(+), 91 deletions(-) diff --git a/docs/styles/align.md b/docs/styles/align.md index 37a42802e..eacff5740 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -27,6 +27,11 @@ To specify alignment on a single axis, use the respective style and type: This example contains a simple app with two labels centered on the screen with `align: center middle;`: +=== "Output" + + ```{.textual path="docs/examples/styles/align.py"} + ``` + === "align.py" ```python @@ -39,17 +44,16 @@ This example contains a simple app with two labels centered on the screen with ` --8<-- "docs/examples/styles/align.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/align.py"} - - ``` - ### All alignments The next example shows a 3 by 3 grid of containers with text labels. Each label has been aligned differently inside its container, and its text shows its `align: ...` value. +=== "Output" + + ```{.textual path="docs/examples/styles/align_all.py"} + ``` + === "align_all.py" ```python @@ -62,11 +66,6 @@ Each label has been aligned differently inside its container, and its text shows --8<-- "docs/examples/styles/align_all.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/align_all.py"} - ``` - ## CSS ```sass diff --git a/docs/styles/background.md b/docs/styles/background.md index bae1e3805..63ef73b55 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -16,6 +16,11 @@ The style `background` needs a [``](../../css_types/color) followed by an This example creates three widgets and applies a different background to each. +=== "Output" + + ```{.textual path="docs/examples/styles/background.py"} + ``` + === "background.py" ```python @@ -28,15 +33,15 @@ This example creates three widgets and applies a different background to each. --8<-- "docs/examples/styles/background.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/background.py"} - ``` - ### Different transparency settings The next example creates ten widgets layed out side by side to show the effect of setting different percentages for the transparency of the background color. +=== "Output" + + ```{.textual path="docs/examples/styles/background_transparency.py"} + ``` + === "background_transparency.py" ```python @@ -49,11 +54,6 @@ The next example creates ten widgets layed out side by side to show the effect o --8<-- "docs/examples/styles/background_transparency.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/background_transparency.py"} - ``` - ## CSS ```sass diff --git a/docs/styles/border.md b/docs/styles/border.md index cda0434ec..270003f73 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -58,6 +58,11 @@ Alternatively, you can see the examples below. This examples shows three widgets with different border styles. +=== "Output" + + ```{.textual path="docs/examples/styles/border.py"} + ``` + === "border.py" ```python @@ -70,15 +75,15 @@ This examples shows three widgets with different border styles. --8<-- "docs/examples/styles/border.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/border.py"} - ``` - ### All border types The next example shows a grid with all the available border types. +=== "Output" + + ```{.textual path="docs/examples/styles/border_all.py"} + ``` + === "border_all.py" ```py @@ -91,11 +96,6 @@ The next example shows a grid with all the available border types. --8<-- "docs/examples/styles/border_all.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/border_all.py"} - ``` - ### Borders and outlines The next example makes the difference between [`border`](./border.md) and [`outline`](./outline.md) clearer by having three labels side-by-side. diff --git a/docs/styles/box_sizing.md b/docs/styles/box_sizing.md index 73fe9064c..43ea086b4 100644 --- a/docs/styles/box_sizing.md +++ b/docs/styles/box_sizing.md @@ -21,6 +21,11 @@ Both widgets in this example have the same height (5). The top widget has `box-sizing: border-box` which means that padding and border reduce the space for content. The bottom widget has `box-sizing: content-box` which increases the size of the widget to compensate for padding and border. +=== "Output" + + ```{.textual path="docs/examples/styles/box_sizing.py"} + ``` + === "box_sizing.py" ```python @@ -33,11 +38,6 @@ The bottom widget has `box-sizing: content-box` which increases the size of the --8<-- "docs/examples/styles/box_sizing.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/box_sizing.py"} - ``` - ## CSS ```sass diff --git a/docs/styles/color.md b/docs/styles/color.md index f253e4063..7c9107bfb 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -18,6 +18,11 @@ Instead of a [``](../../css_types/color), one can use the special value ` This example sets a different text color for each of three different widgets. +=== "Output" + + ```{.textual path="docs/examples/styles/color.py"} + ``` + === "color.py" ```python @@ -30,15 +35,15 @@ This example sets a different text color for each of three different widgets. --8<-- "docs/examples/styles/color.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/color.py"} - ``` - ### Auto The next example shows how `auto` chooses between a lighter or a darker text color to increase the contrast and improve readability. +=== "Output" + + ```{.textual path="docs/examples/styles/color_auto.py"} + ``` + === "color_auto.py" ```py @@ -51,11 +56,6 @@ The next example shows how `auto` chooses between a lighter or a darker text col --8<-- "docs/examples/styles/color_auto.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/color_auto.py"} - ``` - ## CSS ```sass diff --git a/docs/styles/content_align.md b/docs/styles/content_align.md index f3a09243c..e53b30667 100644 --- a/docs/styles/content_align.md +++ b/docs/styles/content_align.md @@ -28,6 +28,11 @@ To specify content alignment on a single axis, use the respective style and type This first example shows three labels stacked vertically, each with different content alignments. +=== "Output" + + ```{.textual path="docs/examples/styles/content_align.py"} + ``` + === "content_align.py" ```python @@ -40,16 +45,16 @@ This first example shows three labels stacked vertically, each with different co --8<-- "docs/examples/styles/content_align.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/content_align.py"} - ``` - ### All content alignments The next example shows a 3 by 3 grid of labels. Each label has its text aligned differently. +=== "Output" + + ```{.textual path="docs/examples/styles/content_align_all.py"} + ``` + === "content_align_all.py" ```py @@ -62,11 +67,6 @@ Each label has its text aligned differently. --8<-- "docs/examples/styles/content_align_all.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/content_align_all.py"} - ``` - ## CSS ```sass diff --git a/docs/styles/display.md b/docs/styles/display.md index ad308398b..570379347 100644 --- a/docs/styles/display.md +++ b/docs/styles/display.md @@ -19,6 +19,11 @@ display: block | none; Note that the second widget is hidden by adding the `"remove"` class which sets the display style to `none`. +=== "Output" + + ```{.textual path="docs/examples/styles/display.py"} + ``` + === "display.py" ```python @@ -31,11 +36,6 @@ Note that the second widget is hidden by adding the `"remove"` class which sets --8<-- "docs/examples/styles/display.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/display.py"} - ``` - ## CSS ```sass diff --git a/docs/styles/height.md b/docs/styles/height.md index 5dbc1d4b7..3c77d4f25 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -17,6 +17,11 @@ By default, it sets the height of the content area, but if [`box-sizing`](./box_ This examples creates a widget with a height of 50% of the screen. +=== "Output" + + ```{.textual path="docs/examples/styles/height.py"} + ``` + === "height.py" ```python @@ -29,11 +34,6 @@ This examples creates a widget with a height of 50% of the screen. --8<-- "docs/examples/styles/height.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/height.py"} - ``` - ### All height formats The next example creates a series of wide widgets with heights set with different units. diff --git a/docs/styles/layout.md b/docs/styles/layout.md index 13544bd7e..ad0884c80 100644 --- a/docs/styles/layout.md +++ b/docs/styles/layout.md @@ -25,6 +25,11 @@ See the [layout](../guide/layout.md) guide for more information. Note how the `layout` property affects the arrangement of widgets in the example below. To learn more about the grid layout, you can see the [layout guide](../guide/layout.md) or the [grid reference](../grid). +=== "Output" + + ```{.textual path="docs/examples/styles/layout.py"} + ``` + === "layout.py" ```python @@ -37,11 +42,6 @@ To learn more about the grid layout, you can see the [layout guide](../guide/lay --8<-- "docs/examples/styles/layout.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/layout.py"} - ``` - ## CSS ```sass diff --git a/docs/styles/opacity.md b/docs/styles/opacity.md index e7baef264..f690054d8 100644 --- a/docs/styles/opacity.md +++ b/docs/styles/opacity.md @@ -18,6 +18,11 @@ Values outside of these ranges will be clamped. This example shows, from top to bottom, increasing opacity values for a label with a border and some text. When the opacity is zero, all we see is the (black) background. +=== "Output" + + ```{.textual path="docs/examples/styles/opacity.py"} + ``` + === "opacity.py" ```python @@ -30,11 +35,6 @@ When the opacity is zero, all we see is the (black) background. --8<-- "docs/examples/styles/opacity.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/opacity.py"} - ``` - ## CSS ```sass diff --git a/docs/styles/outline.md b/docs/styles/outline.md index 759949586..7263de8e5 100644 --- a/docs/styles/outline.md +++ b/docs/styles/outline.md @@ -57,6 +57,11 @@ This example shows a widget with an outline. Note how the outline occludes the t The next example shows a grid with all the available outline types. +=== "Output" + + ```{.textual path="docs/examples/styles/outline_all.py"} + ``` + === "outline_all.py" ```py @@ -69,11 +74,6 @@ The next example shows a grid with all the available outline types. --8<-- "docs/examples/styles/outline_all.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/outline_all.py"} - ``` - ### Borders and outlines The next example makes the difference between [`border`](./border.md) and [`outline`](./outline.md) clearer by having three labels side-by-side. diff --git a/docs/styles/tint.md b/docs/styles/tint.md index 5b0a86e6c..206ffe33e 100644 --- a/docs/styles/tint.md +++ b/docs/styles/tint.md @@ -14,6 +14,11 @@ The tint rule blends a [``](../css_types/color.md) with the widget. The c This examples shows a green tint with gradually increasing alpha. +=== "Output" + + ```{.textual path="docs/examples/styles/tint.py"} + ``` + === "tint.py" ```python @@ -26,11 +31,6 @@ This examples shows a green tint with gradually increasing alpha. --8<-- "docs/examples/styles/tint.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/tint.py"} - ``` - ## CSS ```sass diff --git a/docs/styles/width.md b/docs/styles/width.md index 901a23839..6116dda8b 100644 --- a/docs/styles/width.md +++ b/docs/styles/width.md @@ -17,6 +17,11 @@ By default, it sets the width of the content area, but if [`box-sizing`](./box_s This example adds a widget with 50% width of the screen. +=== "Output" + + ```{.textual path="docs/examples/styles/width.py"} + ``` + === "width.py" ```python @@ -29,11 +34,6 @@ This example adds a widget with 50% width of the screen. --8<-- "docs/examples/styles/width.css" ``` -=== "Output" - - ```{.textual path="docs/examples/styles/width.py"} - ``` - ### All width formats === "Output" From 5df5f129068fe483b16cbc8915f4508249d6bdb3 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:57:13 +0000 Subject: [PATCH 237/310] Run black over node tests --- tests/test_node_list.py | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/tests/test_node_list.py b/tests/test_node_list.py index 23b16139d..71001559f 100644 --- a/tests/test_node_list.py +++ b/tests/test_node_list.py @@ -3,15 +3,18 @@ import pytest from textual.widget import Widget from textual._node_list import NodeList + def test_empty_list(): """Does an empty node list report as being empty?""" - assert len(NodeList())==0 + assert len(NodeList()) == 0 + def test_add_one(): """Does adding a node to the node list report as having one item?""" nodes = NodeList() nodes._append(Widget()) - assert len(nodes)==1 + assert len(nodes) == 1 + def test_repeat_add_one(): """Does adding the same item to the node list ignore the additional adds?""" @@ -19,7 +22,8 @@ def test_repeat_add_one(): widget = Widget() for _ in range(1000): nodes._append(widget) - assert len(nodes)==1 + assert len(nodes) == 1 + def test_insert(): nodes = NodeList() @@ -28,8 +32,9 @@ def test_insert(): widget3 = Widget() nodes._append(widget1) nodes._append(widget3) - nodes._insert(1,widget2) - assert list(nodes) == [widget1,widget2,widget3] + nodes._insert(1, widget2) + assert list(nodes) == [widget1, widget2, widget3] + def test_truthy(): """Does a node list act as a truthy object?""" @@ -38,6 +43,7 @@ def test_truthy(): nodes._append(Widget()) assert bool(nodes) + def test_contains(): """Can we check if a widget is (not) within the list?""" widget = Widget() @@ -47,6 +53,7 @@ def test_contains(): assert widget in nodes assert Widget() not in nodes + def test_index(): """Can we get the index of a widget in the list?""" widget = Widget() @@ -56,6 +63,7 @@ def test_index(): nodes._append(widget) assert nodes.index(widget) == 0 + def test_remove(): """Can we remove a widget we've added?""" widget = Widget() @@ -65,29 +73,31 @@ def test_remove(): nodes._remove(widget) assert widget not in nodes + def test_clear(): """Can we clear the list?""" nodes = NodeList() - assert len(nodes)==0 + assert len(nodes) == 0 widgets = [Widget() for _ in range(1000)] for widget in widgets: nodes._append(widget) - assert len(nodes)==1000 + assert len(nodes) == 1000 for widget in widgets: assert widget in nodes nodes._clear() - assert len(nodes)==0 + assert len(nodes) == 0 for widget in widgets: assert widget not in nodes + def test_listy(): nodes = NodeList() widget1 = Widget() widget2 = Widget() nodes._append(widget1) nodes._append(widget2) - assert list(nodes)==[widget1, widget2] - assert list(reversed(nodes))==[widget2, widget1] - assert nodes[0]==widget1 - assert nodes[1]==widget2 - assert nodes[0:2]==[widget1, widget2] + assert list(nodes) == [widget1, widget2] + assert list(reversed(nodes)) == [widget2, widget1] + assert nodes[0] == widget1 + assert nodes[1] == widget2 + assert nodes[0:2] == [widget1, widget2] From afc7ba2a37b227a61f96d2174d7b79ca0398ea04 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:57:49 +0000 Subject: [PATCH 238/310] Run black over unmount tests --- tests/test_unmount.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_unmount.py b/tests/test_unmount.py index 4611ff7d9..13e2e79b3 100644 --- a/tests/test_unmount.py +++ b/tests/test_unmount.py @@ -12,7 +12,9 @@ async def test_unmount(): class UnmountWidget(Container): def on_unmount(self, event: events.Unmount): - unmount_ids.append(f"{self.__class__.__name__}#{self.id}-{self.parent is not None}-{len(self.children)}") + unmount_ids.append( + f"{self.__class__.__name__}#{self.id}-{self.parent is not None}-{len(self.children)}" + ) class MyScreen(Screen): def compose(self) -> ComposeResult: From 8872956b290a03413230f6c52dd931bfee6c7118 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:58:25 +0000 Subject: [PATCH 239/310] Run black over arrange tests --- tests/test_arrange.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_arrange.py b/tests/test_arrange.py index f66f01954..ad70e5cbc 100644 --- a/tests/test_arrange.py +++ b/tests/test_arrange.py @@ -94,8 +94,9 @@ def test_arrange_dock_bottom(): assert widgets == {child, header} assert spacing == Spacing(0, 0, 1, 0) + def test_arrange_dock_badly(): child = Widget(id="child") child.styles.dock = "nowhere" with pytest.raises(AssertionError): - _ = arrange( Widget(), [child], Size(80, 24), Size(80, 24)) + _ = arrange(Widget(), [child], Size(80, 24), Size(80, 24)) From 3f6ec103111af36032f271b35745dc5592876311 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:59:15 +0000 Subject: [PATCH 240/310] Run black over widget mounting tests --- tests/test_widget_mounting.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_widget_mounting.py b/tests/test_widget_mounting.py index bfd4c7188..189c77c14 100644 --- a/tests/test_widget_mounting.py +++ b/tests/test_widget_mounting.py @@ -5,16 +5,19 @@ from textual.widget import Widget, WidgetError, MountError from textual.widgets import Static from textual.css.query import TooManyMatches + class SelfOwn(Widget): """Test a widget that tries to own itself.""" + def __init__(self) -> None: super().__init__(self) + async def test_mount_via_app() -> None: """Perform mount tests via the app.""" # Make a background set of widgets. - widgets = [Static(id=f"starter-{n}") for n in range( 10 )] + widgets = [Static(id=f"starter-{n}") for n in range(10)] async with App().run_test() as pilot: with pytest.raises(WidgetError): From c84a5dc413d99e436267f7f00b33be0da2996c57 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 13:59:59 +0000 Subject: [PATCH 241/310] Run black over widget removing tests --- tests/test_widget_removing.py | 64 +++++++++-------------------------- 1 file changed, 16 insertions(+), 48 deletions(-) diff --git a/tests/test_widget_removing.py b/tests/test_widget_removing.py index 6371cf9d3..e050bb09d 100644 --- a/tests/test_widget_removing.py +++ b/tests/test_widget_removing.py @@ -4,6 +4,7 @@ from textual.widget import Widget from textual.widgets import Static, Button from textual.containers import Container + async def test_remove_single_widget(): """It should be possible to the only widget on a screen.""" async with App().run_test() as pilot: @@ -12,6 +13,7 @@ async def test_remove_single_widget(): await pilot.app.query_one(Static).remove() assert len(pilot.app.screen.children) == 0 + async def test_many_remove_all_widgets(): """It should be possible to remove all widgets on a multi-widget screen.""" async with App().run_test() as pilot: @@ -20,6 +22,7 @@ async def test_many_remove_all_widgets(): await pilot.app.query(Static).remove() assert len(pilot.app.screen.children) == 0 + async def test_many_remove_some_widgets(): """It should be possible to remove some widgets on a multi-widget screen.""" async with App().run_test() as pilot: @@ -28,79 +31,42 @@ async def test_many_remove_some_widgets(): await pilot.app.query(".is-0").remove() assert len(pilot.app.screen.children) == 5 + async def test_remove_branch(): """It should be possible to remove a whole branch in the DOM.""" async with App().run_test() as pilot: await pilot.app.mount( - Container( - Container( - Container( - Container( - Container( - Static() - ) - ) - ) - ) - ), + Container(Container(Container(Container(Container(Static()))))), Static(), - Container( - Container( - Container( - Container( - Container( - Static() - ) - ) - ) - ) - ), + Container(Container(Container(Container(Container(Static()))))), ) assert len(pilot.app.screen.walk_children(with_self=False)) == 13 await pilot.app.screen.children[0].remove() assert len(pilot.app.screen.walk_children(with_self=False)) == 7 + async def test_remove_overlap(): """It should be possible to remove an overlapping collection of widgets.""" async with App().run_test() as pilot: await pilot.app.mount( - Container( - Container( - Container( - Container( - Container( - Static() - ) - ) - ) - ) - ), + Container(Container(Container(Container(Container(Static()))))), Static(), - Container( - Container( - Container( - Container( - Container( - Static() - ) - ) - ) - ) - ), + Container(Container(Container(Container(Container(Static()))))), ) assert len(pilot.app.screen.walk_children(with_self=False)) == 13 await pilot.app.query(Container).remove() assert len(pilot.app.screen.walk_children(with_self=False)) == 1 + async def test_remove_move_focus(): """Removing a focused widget should settle focus elsewhere.""" async with App().run_test() as pilot: - buttons = [ Button(str(n)) for n in range(10)] + buttons = [Button(str(n)) for n in range(10)] await pilot.app.mount(Container(*buttons[:5]), Container(*buttons[5:])) assert len(pilot.app.screen.children) == 2 assert len(pilot.app.screen.walk_children(with_self=False)) == 12 assert pilot.app.focused is None - await pilot.press( "tab" ) + await pilot.press("tab") assert pilot.app.focused is not None assert pilot.app.focused == buttons[0] await pilot.app.screen.children[0].remove() @@ -109,13 +75,14 @@ async def test_remove_move_focus(): assert pilot.app.focused is not None assert pilot.app.focused == buttons[9] + async def test_widget_remove_order(): """A Widget.remove of a top-level widget should cause bottom-first removal.""" removals: list[str] = [] class Removable(Container): - def on_unmount( self, _ ): + def on_unmount(self, _): removals.append(self.id if self.id is not None else "unknown") async with App().run_test() as pilot: @@ -127,13 +94,14 @@ async def test_widget_remove_order(): assert len(pilot.app.screen.walk_children(with_self=False)) == 0 assert removals == ["grandchild", "child", "parent"] + async def test_query_remove_order(): """A DOMQuery.remove of a top-level widget should cause bottom-first removal.""" removals: list[str] = [] class Removable(Container): - def on_unmount( self, _ ): + def on_unmount(self, _): removals.append(self.id if self.id is not None else "unknown") async with App().run_test() as pilot: From 5a09831c5e946cfb4b0e6ffdad5ed70fc2930959 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 14:00:52 +0000 Subject: [PATCH 242/310] Run black over path tests --- tests/test_path.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/test_path.py b/tests/test_path.py index 582addb7c..3b9b268ea 100644 --- a/tests/test_path.py +++ b/tests/test_path.py @@ -27,12 +27,15 @@ class ListPathApp(App[None]): CSS_PATH = ["test.css", Path("/another/path.css")] -@pytest.mark.parametrize("app,expected_css_path_attribute", [ - (RelativePathObjectApp(), [APP_DIR / "test.css"]), - (RelativePathStrApp(), [APP_DIR / "test.css"]), - (AbsolutePathObjectApp(), [Path("/tmp/test.css")]), - (AbsolutePathStrApp(), [Path("/tmp/test.css")]), - (ListPathApp(), [APP_DIR / "test.css", Path("/another/path.css")]), -]) +@pytest.mark.parametrize( + "app,expected_css_path_attribute", + [ + (RelativePathObjectApp(), [APP_DIR / "test.css"]), + (RelativePathStrApp(), [APP_DIR / "test.css"]), + (AbsolutePathObjectApp(), [Path("/tmp/test.css")]), + (AbsolutePathStrApp(), [Path("/tmp/test.css")]), + (ListPathApp(), [APP_DIR / "test.css", Path("/another/path.css")]), + ], +) def test_css_paths_of_various_types(app, expected_css_path_attribute): assert app.css_path == [path.absolute() for path in expected_css_path_attribute] From 8b7189ff52bfc80090ce6c629509f1e42a0e5a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 14:05:59 +0000 Subject: [PATCH 243/310] Reorder subpages alphabetically. --- mkdocs.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index fffeef3c0..ebd1993c7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -79,24 +79,24 @@ nav: - "styles/dock.md" - Grid: - "styles/grid/index.md" - - "styles/grid/grid_size.md" - - "styles/grid/grid_rows.md" + - "styles/grid/column_span.md" - "styles/grid/grid_columns.md" - "styles/grid/grid_gutter.md" + - "styles/grid/grid_rows.md" + - "styles/grid/grid_size.md" - "styles/grid/row_span.md" - - "styles/grid/column_span.md" - "styles/height.md" - "styles/layer.md" - "styles/layers.md" - "styles/layout.md" - Links: - "styles/links/index.md" - - "styles/links/link_color.md" - "styles/links/link_background.md" - - "styles/links/link_style.md" - - "styles/links/link_hover_color.md" + - "styles/links/link_color.md" - "styles/links/link_hover_background.md" + - "styles/links/link_hover_color.md" - "styles/links/link_hover_style.md" + - "styles/links/link_style.md" - "styles/margin.md" - "styles/max_height.md" - "styles/max_width.md" From 8bf211b898fe17aa1b117fad3617c5586209f090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 14:09:34 +0000 Subject: [PATCH 244/310] Fix typo. --- docs/styles/grid/column_span.md | 2 +- docs/styles/tint.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md index cb4fbe813..f88de0546 100644 --- a/docs/styles/grid/column_span.md +++ b/docs/styles/grid/column_span.md @@ -1,6 +1,6 @@ # Column-span -The `column-span` style specifies how many rows a widget will span in a grid layout. +The `column-span` style specifies how many columns a widget will span in a grid layout. !!! note diff --git a/docs/styles/tint.md b/docs/styles/tint.md index 206ffe33e..3d4c308d3 100644 --- a/docs/styles/tint.md +++ b/docs/styles/tint.md @@ -41,7 +41,7 @@ tint: red 20% tint: rgba(0, 200, 0, 0.3); ``` -# Python +## Python ```python # A red tint From 14ebe689b8f30c1d2997dc262829f34757cc6429 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 14:33:48 +0000 Subject: [PATCH 245/310] Remove unused import of Segment --- src/textual/widgets/_tree.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index 866a4d7ce..72ca95444 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -4,7 +4,6 @@ from dataclasses import dataclass from typing import ClassVar, Generic, NewType, TypeVar import rich.repr -from rich.segment import Segment from rich.style import NULL_STYLE, Style from rich.text import Text, TextType From 2941cfb262a552df8a84387f0ae10aa9345abbb3 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 9 Jan 2023 14:34:44 +0000 Subject: [PATCH 246/310] Remove unused import of line_crop --- src/textual/widgets/_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index 72ca95444..bc431e143 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -10,7 +10,7 @@ from rich.text import Text, TextType from .. import events from .._cache import LRUCache from .._loop import loop_last -from .._segment_tools import line_crop, line_pad +from .._segment_tools import line_pad from .._types import MessageTarget from .._typing import TypeAlias from .._immutable_sequence_view import ImmutableSequenceView From e81779f97c012e4674a91d85119e581eb87c7871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 15:25:47 +0000 Subject: [PATCH 247/310] Add 'See also' sections to references. --- docs/styles/align.md | 6 +++++- docs/styles/background.md | 4 ++++ docs/styles/border.md | 5 +++++ docs/styles/box_sizing.md | 5 +++++ docs/styles/color.md | 4 ++++ docs/styles/content_align.md | 7 +++++-- docs/styles/display.md | 4 ++++ docs/styles/dock.md | 4 ++++ docs/styles/grid/column_span.md | 4 ++++ docs/styles/grid/grid_columns.md | 6 +++++- docs/styles/grid/grid_rows.md | 6 +++++- docs/styles/grid/index.md | 4 ++++ docs/styles/grid/row_span.md | 4 ++++ docs/styles/height.md | 5 +++++ docs/styles/layer.md | 5 +++++ docs/styles/layers.md | 5 +++++ docs/styles/layout.md | 5 +++++ docs/styles/links/link_background.md | 5 +++++ docs/styles/links/link_color.md | 5 +++++ docs/styles/links/link_hover_background.md | 6 ++++++ docs/styles/links/link_hover_color.md | 6 ++++++ docs/styles/links/link_hover_style.md | 7 +++++++ docs/styles/links/link_style.md | 5 +++++ docs/styles/margin.md | 4 ++++ docs/styles/max_height.md | 5 +++++ docs/styles/max_width.md | 5 +++++ docs/styles/min_height.md | 5 +++++ docs/styles/min_width.md | 5 +++++ docs/styles/offset.md | 4 ++++ docs/styles/opacity.md | 4 ++++ docs/styles/outline.md | 4 ++++ docs/styles/padding.md | 5 +++++ docs/styles/scrollbar_colors/scrollbar_background.md | 7 +++++++ .../scrollbar_colors/scrollbar_background_active.md | 6 ++++++ .../styles/scrollbar_colors/scrollbar_background_hover.md | 8 ++++++++ docs/styles/scrollbar_colors/scrollbar_color.md | 7 +++++++ docs/styles/scrollbar_colors/scrollbar_color_active.md | 6 ++++++ docs/styles/scrollbar_colors/scrollbar_color_hover.md | 6 ++++++ docs/styles/scrollbar_colors/scrollbar_corner_color.md | 5 +++++ docs/styles/text_align.md | 5 +++++ docs/styles/text_opacity.md | 4 ++++ docs/styles/visibility.md | 4 ++++ docs/styles/width.md | 5 +++++ 43 files changed, 216 insertions(+), 5 deletions(-) diff --git a/docs/styles/align.md b/docs/styles/align.md index eacff5740..8f299d0e3 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -1,7 +1,6 @@ # Align The `align` style aligns children within a container. -Not to be confused with [`content-align`](../content_align). ## Syntax @@ -92,3 +91,8 @@ widget.styles.align_horizontal = "right" # Change the vertical alignment of the children of a widget widget.styles.align_vertical = "middle" ``` + +## See also + + - [`content-align`](./content_align.md) to set the alignment of content inside a widget. + - [`text-align`](./text_align.md) to set the alignment of text in a widget. diff --git a/docs/styles/background.md b/docs/styles/background.md index 63ef73b55..936a350db 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -87,3 +87,7 @@ widget.styles.background = Color.parse("#FF00FF") # Set with a color object instantiated directly widget.styles.background = Color(120, 60, 100) ``` + +## See also + + - [`color`](./color.md) to set the color of text in a widget. diff --git a/docs/styles/border.md b/docs/styles/border.md index 270003f73..3b01cdfbb 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -139,3 +139,8 @@ widget.border = ("heavy", "white") # Set a red border on the left widget.border_left = ("outer", "red") ``` + +## See also + + - [`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. diff --git a/docs/styles/box_sizing.md b/docs/styles/box_sizing.md index 43ea086b4..97bc9f288 100644 --- a/docs/styles/box_sizing.md +++ b/docs/styles/box_sizing.md @@ -57,3 +57,8 @@ widget.box_sizing = "border-box" # Set box sizing to content-box widget.box_sizing = "content-box" ``` + +## See also + + - [`border`](./border.md) to add a border around a widget. + - [`padding`](./padding.md) to add spacing around the content of a widget. diff --git a/docs/styles/color.md b/docs/styles/color.md index 7c9107bfb..f4c6c5efa 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -84,3 +84,7 @@ from textual.color import Color # Set with a color object widget.styles.color = Color.parse("pink") ``` + +## See also + + - [`background`](./background.md) to set the background color in a widget. diff --git a/docs/styles/content_align.md b/docs/styles/content_align.md index e53b30667..89ae21d81 100644 --- a/docs/styles/content_align.md +++ b/docs/styles/content_align.md @@ -1,8 +1,6 @@ # Content-align The `content-align` style aligns content _inside_ a widget. -Not to be confused with [`align`](../align). - ## Syntax @@ -93,3 +91,8 @@ widget.styles.content_align_horizontal = "right" # Change the vertical alignment of the content of a widget widget.styles.content_align_vertical = "middle" ``` + +## See also + + - [`align`](./align.md) to set the alignment of children widgets inside a container. + - [`text-align`](./text_align.md) to set the alignment of text in a widget. diff --git a/docs/styles/display.md b/docs/styles/display.md index 570379347..d0d37a3c1 100644 --- a/docs/styles/display.md +++ b/docs/styles/display.md @@ -65,3 +65,7 @@ widget.display = False # Show the widget widget.display = True ``` + +## See also + + - [`visibility`](./visibility.md) to specify whether a widget is visible or not. diff --git a/docs/styles/dock.md b/docs/styles/dock.md index d8c4e1477..9fbd241ac 100644 --- a/docs/styles/dock.md +++ b/docs/styles/dock.md @@ -73,3 +73,7 @@ widget.styles.dock = left; # Dock left. widget.styles.dock = right; # Dock right. widget.styles.dock = top; # Dock top. ``` + +## See also + + - The [layout guide](../guide/layout.md#docking) section on docking. diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md index f88de0546..bddd24d4a 100644 --- a/docs/styles/grid/column_span.md +++ b/docs/styles/grid/column_span.md @@ -46,3 +46,7 @@ column-span: 3 ```py widget.styles.column_span = 3 ``` + +## See also + + - [`row-span`](./row_span.md) to specify how many rows a widget spans. diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index 6ea34dfff..3c145e638 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -56,9 +56,13 @@ grid-columns: 50%; grid-columns: 1fr 2fr; ``` -### Python +## Python ```py grid.styles.grid_columns = "50%" grid.styles.grid_columns = "1fr 2fr" ``` + +## See also + + - [`grid-rows`](./grid_rows.md) to specify the height of the grid rows. diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index 94d87f856..4303a9029 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -56,9 +56,13 @@ grid-rows: 50%; grid-rows: 1fr 2fr; ``` -### Python +## Python ```py grid.styles.grid_rows = "50%" grid.styles.grid_rows = "1fr 2fr" ``` + +## See also + + - [`grid-columns`](./grid_columns.md) to specify the width of the grid columns. diff --git a/docs/styles/grid/index.md b/docs/styles/grid/index.md index c68172865..0236e62df 100644 --- a/docs/styles/grid/index.md +++ b/docs/styles/grid/index.md @@ -58,3 +58,7 @@ The spacing between grid cells is because of the `grid-gutter` declaration. !!! warning The properties listed on this page will only work when the layout is `grid`. + +## See also + + - The [grid layout](../../guide/layout.md#grid) guide. diff --git a/docs/styles/grid/row_span.md b/docs/styles/grid/row_span.md index a6e15c3ac..12d1670ac 100644 --- a/docs/styles/grid/row_span.md +++ b/docs/styles/grid/row_span.md @@ -49,3 +49,7 @@ row-span: 3 ```py widget.styles.row_span = 3 ``` + +## See also + + - [`column-span`](./column_span.md) to specify how many columns a widget spans. diff --git a/docs/styles/height.md b/docs/styles/height.md index 3c77d4f25..cdaec0018 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -91,3 +91,8 @@ self.styles.height = 10 # Explicit cell height can be an int self.styles.height = "50%" self.styles.height = "auto" ``` + +## See also + + - [`max-height`](./max_height.md) and [`min-height`](./min_height.md) to limit the height of a widget. + - [`width`](./width.md) to set the width of a widget. diff --git a/docs/styles/layer.md b/docs/styles/layer.md index 851a02eb3..b526fd57d 100644 --- a/docs/styles/layer.md +++ b/docs/styles/layer.md @@ -54,3 +54,8 @@ layer: below; # Draw the widget on the layer called 'below' widget.styles.layer = "below" ``` + +## See also + + - The [layout guide](../guide/layout.md#layers) section on layers. + - [`layers`](./layers.md) to define an ordered set of layers. diff --git a/docs/styles/layers.md b/docs/styles/layers.md index 518293311..bab5204d7 100644 --- a/docs/styles/layers.md +++ b/docs/styles/layers.md @@ -52,3 +52,8 @@ layers: below above; # Bottom layer is called 'below', layer above it is called 'above' widget.style.layers = ("below", "above") ``` + +## See also + + - The [layout guide](../guide/layout.md#layers) section on layers. + - [`layer`](./layer.md) to set the layer a widget belongs to. diff --git a/docs/styles/layout.md b/docs/styles/layout.md index ad0884c80..e3d937340 100644 --- a/docs/styles/layout.md +++ b/docs/styles/layout.md @@ -53,3 +53,8 @@ layout: horizontal; ```python widget.styles.layout = "horizontal" ``` + +## See also + + - [Layout guide](../guide/layout.md). + - [Grid reference](./grid/index.md). diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md index e171f3fcf..9944682a6 100644 --- a/docs/styles/links/link_background.md +++ b/docs/styles/links/link_background.md @@ -59,3 +59,8 @@ widget.styles.link_background = "$accent" # You can also use a `Color` object directly: widget.styles.link_background = Color(100, 30, 173) ``` + +## See also + + - [`link-color`](./link_color.md) to set the color of link text. + - [`link-hover-background](./link_hover_background.md) to set the background color of link text when the mouse pointer is over it. diff --git a/docs/styles/links/link_color.md b/docs/styles/links/link_color.md index 573a69631..0d38369ed 100644 --- a/docs/styles/links/link_color.md +++ b/docs/styles/links/link_color.md @@ -59,3 +59,8 @@ widget.styles.link_color = "$accent" # You can also use a `Color` object directly: widget.styles.link_color = Color(100, 30, 173) ``` + +## See also + + - [`link-background`](./link_background.md) to set the background color of link text. + - [`link-hover-color](./link_hover_color.md) to set the color of link text when the mouse pointer is over it. diff --git a/docs/styles/links/link_hover_background.md b/docs/styles/links/link_hover_background.md index 22fd92d52..9afb7d8b6 100644 --- a/docs/styles/links/link_hover_background.md +++ b/docs/styles/links/link_hover_background.md @@ -69,3 +69,9 @@ widget.styles.link_hover_background = "$accent" # You can also use a `Color` object directly: widget.styles.link_hover_background = Color(100, 30, 173) ``` + +## See also + + - [`link-background`](./link_background.md) to set the background color of link text. + - [`link-hover-color](./link_hover_color.md) to set the color of link text when the mouse pointer is over it. + - [`link-hover-style](./link_hover_style.md) to set the style of link text when the mouse pointer is over it. diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md index 026c8d264..7a9311c6c 100644 --- a/docs/styles/links/link_hover_color.md +++ b/docs/styles/links/link_hover_color.md @@ -72,3 +72,9 @@ widget.styles.link_hover_color = "black" # You can also use a `Color` object directly: widget.styles.link_hover_color = Color(100, 30, 173) ``` + +## See also + + - [`link-color`](./link_color.md) to set the color of link text. + - [`link-hover-background](./link_hover_background.md) to set the background color of link text when the mouse pointer is over it. + - [`link-hover-style](./link_hover_style.md) to set the style of link text when the mouse pointer is over it. diff --git a/docs/styles/links/link_hover_style.md b/docs/styles/links/link_hover_style.md index 5268ead28..989c7beae 100644 --- a/docs/styles/links/link_hover_style.md +++ b/docs/styles/links/link_hover_style.md @@ -70,3 +70,10 @@ link-hover-style: bold italic reverse; widget.styles.link_hover_style = "bold" widget.styles.link_hover_style = "bold italic reverse" ``` + +## See also + + - [`link-hover-background](./link_hover_background.md) to set the background color of link text when the mouse pointer is over it. + - [`link-hover-color](./link_hover_color.md) to set the color of link text when the mouse pointer is over it. + - [`link-style`](./link_style.md) to set the style of link text. + - [`text-style`](../text_style.md) to set the style of text in a widget. diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md index 8c2eac88c..f09bfb796 100644 --- a/docs/styles/links/link_style.md +++ b/docs/styles/links/link_style.md @@ -60,3 +60,8 @@ link-style: bold italic reverse; widget.styles.link_style = "bold" widget.styles.link_style = "bold italic reverse" ``` + +## See also + + - [`link-hover-style](./link_hover_style.md) to set the style of link text when the mouse pointer is over it. + - [`text-style`](../text_style.md) to set the style of text in a widget. diff --git a/docs/styles/margin.md b/docs/styles/margin.md index 641f9c29d..ad6b26bfd 100644 --- a/docs/styles/margin.md +++ b/docs/styles/margin.md @@ -108,3 +108,7 @@ widget.styles.margin = (2, 4) # Set margin of 1 on top, 2 on the right, 3 on the bottom, and 4 on the left widget.styles.margin = (1, 2, 3, 4) ``` + +## See also + + - [`padding`](./padding.md) to add spacing around the content of a widget. diff --git a/docs/styles/max_height.md b/docs/styles/max_height.md index 02fb415ed..b8aa0ae2d 100644 --- a/docs/styles/max_height.md +++ b/docs/styles/max_height.md @@ -54,3 +54,8 @@ widget.styles.max_height = 10 # Set the maximum height to 25% of the viewport height widget.styles.max_height = "25vh" ``` + +## See also + + - [`min-height`](./min_height.md) to set a lower bound on the height of a widget. + - [`height`](./height.md) to set the height of a widget. diff --git a/docs/styles/max_width.md b/docs/styles/max_width.md index f0bee7ff9..944a5474a 100644 --- a/docs/styles/max_width.md +++ b/docs/styles/max_width.md @@ -54,3 +54,8 @@ widget.styles.max_width = 10 # Set the maximum width to 25% of the viewport width widget.styles.max_width = "25vh" ``` + +## See also + + - [`min-width`](./min_width.md) to set a lower bound on the width of a widget. + - [`width`](./width.md) to set the width of a widget. diff --git a/docs/styles/min_height.md b/docs/styles/min_height.md index a4e7c8c1d..a201e87aa 100644 --- a/docs/styles/min_height.md +++ b/docs/styles/min_height.md @@ -54,3 +54,8 @@ widget.styles.min_height = 10 # Set the minimum height to 25% of the viewport height widget.styles.min_height = "25vh" ``` + +## See also + + - [`max-height`](./max_height.md) to set an upper bound on the height of a widget. + - [`height`](./height.md) to set the height of a widget. diff --git a/docs/styles/min_width.md b/docs/styles/min_width.md index d07926d8e..fe23b9448 100644 --- a/docs/styles/min_width.md +++ b/docs/styles/min_width.md @@ -54,3 +54,8 @@ widget.styles.min_width = 10 # Set the minimum width to 25% of the viewport width widget.styles.min_width = "25vh" ``` + +## See also + + - [`max-width`](./max_width.md) to set an upper bound on the width of a widget. + - [`width`](./width.md) to set the width of a widget. diff --git a/docs/styles/offset.md b/docs/styles/offset.md index e09279dbd..33b546637 100644 --- a/docs/styles/offset.md +++ b/docs/styles/offset.md @@ -57,3 +57,7 @@ You have to set the two axes at the same time. # Move the widget 2 cells in the x direction, and 4 in the y direction. widget.styles.offset = (2, 4) ``` + +## See also + + - The [layout guide](../guide/layout.md#offsets) section on offsets. diff --git a/docs/styles/opacity.md b/docs/styles/opacity.md index f690054d8..481181851 100644 --- a/docs/styles/opacity.md +++ b/docs/styles/opacity.md @@ -50,3 +50,7 @@ Widget { # Fade the widget to 50% against its parent's background widget.styles.opacity = "50%" ``` + +## See also + + - [`text-opacity`](./text_opacity.md) to blend the color of a widget's content with its background color. diff --git a/docs/styles/outline.md b/docs/styles/outline.md index 7263de8e5..d0d8fa398 100644 --- a/docs/styles/outline.md +++ b/docs/styles/outline.md @@ -117,3 +117,7 @@ widget.outline = ("heavy", "white") # Set a red outline on the left widget.outline_left = ("outer", "red") ``` + +## See also + + - [`border`](./border.md) to add a border around a widget. diff --git a/docs/styles/padding.md b/docs/styles/padding.md index 38212b158..701ebf17e 100644 --- a/docs/styles/padding.md +++ b/docs/styles/padding.md @@ -83,3 +83,8 @@ widget.styles.padding = (2, 4) # Set padding of 1 on top, 2 on the right, 3 on the bottom, and 4 on the left widget.styles.padding = (1, 2, 3, 4) ``` + +## See also + + - [`box-sizing`](./box_sizing.md) to specify how to account for padding in a widget's dimensions. + - [`margin`](./margin.md) to add spacing around a widget. diff --git a/docs/styles/scrollbar_colors/scrollbar_background.md b/docs/styles/scrollbar_colors/scrollbar_background.md index 97fe18f61..bc4e9ebf8 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background.md +++ b/docs/styles/scrollbar_colors/scrollbar_background.md @@ -43,3 +43,10 @@ scrollbar-backround: blue; ```py widget.styles.scrollbar_background = "blue" ``` + +## See also + + - [`scrollbar-bakcground-active`](./scrollbar_color_active.md) to set the scrollbar bakcground color when the scrollbar is being dragged. + - [`scrollbar-bakcground-hover`](./scrollbar_color_hover.md) to set the scrollbar bakcground color when the mouse pointer is over it. + - [`scrollbar-color`](./scrollbar_color.md) to set the color of scrollbars. + - [`scrollbar-corner-color`](./scrollbar_corner_color.md) to set the color of the corner where horizontal and vertical scrollbars meet. diff --git a/docs/styles/scrollbar_colors/scrollbar_background_active.md b/docs/styles/scrollbar_colors/scrollbar_background_active.md index 6f83a2622..6561ad1bc 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_active.md @@ -44,3 +44,9 @@ scrollbar-backround-active: red; ```py widget.styles.scrollbar_background_active = "red" ``` + +## See also + + - [`scrollbar-background`](./scrollbar_background.md) to set the background color of scrollbars. + - [`scrollbar-bakcground-hover`](./scrollbar_color_hover.md) to set the scrollbar bakcground color when the mouse pointer is over it. + - [`scrollbar-color-active`](./scrollbar_color_active.md) to set the scrollbar color when the scrollbar is being dragged. diff --git a/docs/styles/scrollbar_colors/scrollbar_background_hover.md b/docs/styles/scrollbar_colors/scrollbar_background_hover.md index fd4349f91..22628645e 100644 --- a/docs/styles/scrollbar_colors/scrollbar_background_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_background_hover.md @@ -44,3 +44,11 @@ scrollbar-background-hover: purple; ```py widget.styles.scrollbar_background_hover = "purple" ``` + +## See also + +## See also + + - [`scrollbar-background`](./scrollbar_background.md) to set the background color of scrollbars. + - [`scrollbar-bakcground-active`](./scrollbar_color_active.md) to set the scrollbar bakcground color when the scrollbar is being dragged. + - [`scrollbar-color-hover`](./scrollbar_color_hover.md) to set the scrollbar color when the mouse pointer is over it. diff --git a/docs/styles/scrollbar_colors/scrollbar_color.md b/docs/styles/scrollbar_colors/scrollbar_color.md index 5b1bb92be..4930289d7 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_color.md @@ -44,3 +44,10 @@ scrollbar-color: cyan; ```py widget.styles.scrollbar_color = "cyan" ``` + +## See also + + - [`scrollbar-background`](./scrollbar_background.md) to set the background color of scrollbars. + - [`scrollbar-color-active`](./scrollbar_color_active.md) to set the scrollbar color when the scrollbar is being dragged. + - [`scrollbar-color-hover`](./scrollbar_color_hover.md) to set the scrollbar color when the mouse pointer is over it. + - [`scrollbar-corner-color`](./scrollbar_corner_color.md) to set the color of the corner where horizontal and vertical scrollbars meet. diff --git a/docs/styles/scrollbar_colors/scrollbar_color_active.md b/docs/styles/scrollbar_colors/scrollbar_color_active.md index 57fba7383..7be97f8b1 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_active.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_active.md @@ -44,3 +44,9 @@ scrollbar-color-active: yellow; ```py widget.styles.scrollbar_color_active = "yellow" ``` + +## See also + + - [`scrollbar-bakcground-active`](./scrollbar_color_active.md) to set the scrollbar bakcground color when the scrollbar is being dragged. + - [`scrollbar-color`](./scrollbar_color.md) to set the color of scrollbars. + - [`scrollbar-color-hover`](./scrollbar_color_hover.md) to set the scrollbar color when the mouse pointer is over it. diff --git a/docs/styles/scrollbar_colors/scrollbar_color_hover.md b/docs/styles/scrollbar_colors/scrollbar_color_hover.md index a3fe72153..371521b05 100644 --- a/docs/styles/scrollbar_colors/scrollbar_color_hover.md +++ b/docs/styles/scrollbar_colors/scrollbar_color_hover.md @@ -44,3 +44,9 @@ scrollbar-color-hover: pink; ```py widget.styles.scrollbar_color_hover = "pink" ``` + +## See also + + - [`scrollbar-bakcground-hover`](./scrollbar_color_hover.md) to set the scrollbar bakcground color when the mouse pointer is over it. + - [`scrollbar-color`](./scrollbar_color.md) to set the color of scrollbars. + - [`scrollbar-color-active`](./scrollbar_color_active.md) to set the scrollbar color when the scrollbar is being dragged. diff --git a/docs/styles/scrollbar_colors/scrollbar_corner_color.md b/docs/styles/scrollbar_colors/scrollbar_corner_color.md index 05b3517c3..44b0e501d 100644 --- a/docs/styles/scrollbar_colors/scrollbar_corner_color.md +++ b/docs/styles/scrollbar_colors/scrollbar_corner_color.md @@ -42,3 +42,8 @@ scrollbar-corner-color: white; ```py widget.styles.scrollbar_corner_color = "white" ``` + +## See also + + - [`scrollbar-background`](./scrollbar_background.md) to set the background color of scrollbars. + - [`scrollbar-color`](./scrollbar_color.md) to set the color of scrollbars. diff --git a/docs/styles/text_align.md b/docs/styles/text_align.md index 851962604..37a3fc1bd 100644 --- a/docs/styles/text_align.md +++ b/docs/styles/text_align.md @@ -50,3 +50,8 @@ text-align: right; # Set text in the widget to be right aligned widget.styles.text_align = "right" ``` + +## See also + + - [`align`](./align.md) to set the alignment of children widgets inside a container. + - [`content-align`](./content_align.md) to set the alignment of content inside a widget. diff --git a/docs/styles/text_opacity.md b/docs/styles/text_opacity.md index 006d9f3de..25b26eb0f 100644 --- a/docs/styles/text_opacity.md +++ b/docs/styles/text_opacity.md @@ -47,3 +47,7 @@ text-opacity: 50%; # Set the text to be "half-faded" against the background of the widget widget.styles.text_opacity = "50%" ``` + +## See also + + - [`opacity`](./opacity.md) to specify the transparency of a whole widget. diff --git a/docs/styles/visibility.md b/docs/styles/visibility.md index 9a925a78c..62ae2ac89 100644 --- a/docs/styles/visibility.md +++ b/docs/styles/visibility.md @@ -113,3 +113,7 @@ widget.visible = False # Make the widget visible again widget.visible = True ``` + +## See also + + - [`display`](./display.md) to specify whether a widget is displayed or not. diff --git a/docs/styles/width.md b/docs/styles/width.md index 6116dda8b..a66e8ae6c 100644 --- a/docs/styles/width.md +++ b/docs/styles/width.md @@ -92,3 +92,8 @@ widget.styles.width = 10 widget.styles.width = "50% widget.styles.width = "auto" ``` + +## See also + + - [`max-width`](./max_width.md) and [`min-width`](./min_width.md) to limit the width of a widget. + - [`height`](./height.md) to set the height of a widget. From 2827edcd49e2dd76e33dd057c675bbb05040324e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 15:43:15 +0000 Subject: [PATCH 248/310] Add example with all padding types. --- docs/examples/styles/padding_all.css | 45 ++++++++++++++++++++++++++++ docs/examples/styles/padding_all.py | 20 +++++++++++++ docs/styles/padding.md | 29 ++++++++++++++++-- 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 docs/examples/styles/padding_all.css create mode 100644 docs/examples/styles/padding_all.py diff --git a/docs/examples/styles/padding_all.css b/docs/examples/styles/padding_all.css new file mode 100644 index 000000000..6bf822c7c --- /dev/null +++ b/docs/examples/styles/padding_all.css @@ -0,0 +1,45 @@ +Screen { + background: $background; +} + +Grid { + grid-size: 4; + grid-gutter: 1 2; +} + +Placeholder { + width: auto; + height: auto; +} + +#p1 { + /* default is no padding */ +} + +#p2 { + padding: 1; +} + +#p3 { + padding: 1 5; +} + +#p4 { + padding: 1 1 2 6; +} + +#p5 { + padding-top: 4; +} + +#p6 { + padding-right: 3; +} + +#p7 { + padding-bottom: 4; +} + +#p8 { + padding-left: 3; +} diff --git a/docs/examples/styles/padding_all.py b/docs/examples/styles/padding_all.py new file mode 100644 index 000000000..f9387ed55 --- /dev/null +++ b/docs/examples/styles/padding_all.py @@ -0,0 +1,20 @@ +from textual.app import App +from textual.containers import Container, Grid +from textual.widgets import Placeholder + + +class PaddingAllApp(App): + def compose(self): + yield Grid( + Placeholder("no padding", id="p1"), + Placeholder("padding: 1", id="p2"), + Placeholder("padding: 1 5", id="p3"), + Placeholder("padding: 1 1 2 6", id="p4"), + Placeholder("padding-top: 4", id="p5"), + Placeholder("padding-right: 3", id="p6"), + Placeholder("padding-bottom: 4", id="p7"), + Placeholder("padding-left: 3", id="p8"), + ) + + +app = PaddingAllApp(css_path="padding_all.css") diff --git a/docs/styles/padding.md b/docs/styles/padding.md index 701ebf17e..af3d247fd 100644 --- a/docs/styles/padding.md +++ b/docs/styles/padding.md @@ -33,6 +33,8 @@ Alternatively, padding can be set for each edge individually through the rules ` ## Example +### Basic usage + This example adds padding around some text. === "Output" @@ -52,11 +54,34 @@ This example adds padding around some text. --8<-- "docs/examples/styles/padding.css" ``` +### All padding settings + +The next example shows a grid. +In each cell, we have a placeholder that has its padding set in different ways. +The effect of each padding setting is noticeable in the colored background around the text of each placeholder. + +=== "Output" + + ```{.textual path="docs/examples/styles/padding_all.py"} + ``` + +=== "padding_all.py" + + ```py + --8<-- "docs/examples/styles/padding_all.py" + ``` + +=== "padding_all.css" + + ```py + --8<-- "docs/examples/styles/padding_all.css" + ``` + ## CSS ```sass /* Set padding of 1 around all edges */ -padding: 1 +padding: 1; /* Set padding of 2 on the top and bottom edges, and 4 on the left and right */ padding: 2 4; /* Set padding of 1 on the top, 2 on the right, @@ -87,4 +112,4 @@ widget.styles.padding = (1, 2, 3, 4) ## See also - [`box-sizing`](./box_sizing.md) to specify how to account for padding in a widget's dimensions. - - [`margin`](./margin.md) to add spacing around a widget. + - [`padding`](./margin.md) to add spacing around a widget. From a1b9d4b2c53ff35ed5a8b3071c315b08906c7f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:11:45 +0000 Subject: [PATCH 249/310] Fix examples. --- docs/examples/styles/background.css | 8 +++++-- docs/examples/styles/background.py | 8 +++---- docs/examples/styles/border.css | 34 ++++++++++++++++------------ docs/examples/styles/box_sizing.css | 15 +++++++----- docs/examples/styles/color.css | 9 +++++--- docs/examples/styles/display.css | 12 ++++++---- docs/examples/styles/grid_gutter.css | 2 +- docs/examples/styles/height.css | 2 +- docs/examples/styles/overflow.css | 4 ++-- docs/examples/styles/padding.css | 6 ++--- docs/examples/styles/tint.css | 8 +++---- docs/examples/styles/tint.py | 2 +- docs/examples/styles/visibility.css | 2 ++ 13 files changed, 65 insertions(+), 47 deletions(-) diff --git a/docs/examples/styles/background.css b/docs/examples/styles/background.css index 27f8649d2..f2d32df58 100644 --- a/docs/examples/styles/background.css +++ b/docs/examples/styles/background.css @@ -1,14 +1,18 @@ -Static { +Label { + width: 100%; height: 1fr; content-align: center middle; color: white; -} +} + #static1 { background: red; } + #static2 { background: rgb(0, 255, 0); } + #static3 { background: hsl(240, 100%, 50%); } diff --git a/docs/examples/styles/background.py b/docs/examples/styles/background.py index cef306ddc..6d8669baa 100644 --- a/docs/examples/styles/background.py +++ b/docs/examples/styles/background.py @@ -1,12 +1,12 @@ from textual.app import App -from textual.widgets import Static +from textual.widgets import Label class BackgroundApp(App): def compose(self): - yield Static("Widget 1", id="static1") - yield Static("Widget 2", id="static2") - yield Static("Widget 3", id="static3") + yield Label("Widget 1", id="static1") + yield Label("Widget 2", id="static2") + yield Label("Widget 3", id="static3") app = BackgroundApp(css_path="background.css") diff --git a/docs/examples/styles/border.css b/docs/examples/styles/border.css index 27b9e281d..c12333cb8 100644 --- a/docs/examples/styles/border.css +++ b/docs/examples/styles/border.css @@ -1,6 +1,25 @@ +#label1 { + background: red 20%; + color: red; + border: solid red; +} + +#label2 { + background: green 20%; + color: green; + border: dashed green; +} + +#label3 { + background: blue 20%; + color: blue; + border: tall blue; +} + Screen { background: white; } + Screen > Label { width: 100%; height: 5; @@ -8,19 +27,4 @@ Screen > Label { color: white; margin: 1; box-sizing: border-box; -} -#label1 { - background: red 20%; - color: red; - border: solid red; -} -#label2 { - background: green 20%; - color: green; - border: dashed green; -} -#label3 { - background: blue 20%; - color: blue; - border: tall blue; } diff --git a/docs/examples/styles/box_sizing.css b/docs/examples/styles/box_sizing.css index 38f55482d..169faa10e 100644 --- a/docs/examples/styles/box_sizing.css +++ b/docs/examples/styles/box_sizing.css @@ -1,7 +1,16 @@ +#static1 { + box-sizing: border-box; +} + +#static2 { + box-sizing: content-box; +} + Screen { background: white; color: black; } + App Static { background: blue 20%; height: 5; @@ -9,9 +18,3 @@ App Static { padding: 1; border: wide black; } -#static1 { - box-sizing: border-box; -} -#static2 { - box-sizing: content-box; -} diff --git a/docs/examples/styles/color.css b/docs/examples/styles/color.css index b44a0d02e..83242edbc 100644 --- a/docs/examples/styles/color.css +++ b/docs/examples/styles/color.css @@ -1,14 +1,17 @@ Label { - height:1fr; + height: 1fr; content-align: center middle; width: 100%; -} +} + #label1 { color: red; } + #label2 { color: rgb(0, 255, 0); } + #label3 { - color: hsl(240, 100%, 50%) + color: hsl(240, 100%, 50%); } diff --git a/docs/examples/styles/display.css b/docs/examples/styles/display.css index 14bbf6fc4..7131fb638 100644 --- a/docs/examples/styles/display.css +++ b/docs/examples/styles/display.css @@ -1,12 +1,14 @@ Screen { background: green; } -Static { - height: 5; - background: white; - color: blue; - border: heavy blue; + +Static { + height: 5; + background: white; + color: blue; + border: heavy blue; } + Static.remove { display: none; } diff --git a/docs/examples/styles/grid_gutter.css b/docs/examples/styles/grid_gutter.css index e4f5240e8..f7936be03 100644 --- a/docs/examples/styles/grid_gutter.css +++ b/docs/examples/styles/grid_gutter.css @@ -1,6 +1,6 @@ Grid { grid-size: 2 4; - grid-gutter: 1 2 /* (1)! */ + grid-gutter: 1 2; /* (1)! */ } Label { diff --git a/docs/examples/styles/height.css b/docs/examples/styles/height.css index 5baabb27d..81176fa71 100644 --- a/docs/examples/styles/height.css +++ b/docs/examples/styles/height.css @@ -1,4 +1,4 @@ -Screen > Widget { +Screen > Widget { background: green; height: 50%; color: white; diff --git a/docs/examples/styles/overflow.css b/docs/examples/styles/overflow.css index 27eaa81c1..3b68440c7 100644 --- a/docs/examples/styles/overflow.css +++ b/docs/examples/styles/overflow.css @@ -8,8 +8,8 @@ Vertical { } Static { - margin: 1 2; - background: green 80%; + margin: 1 2; + background: green 80%; border: green wide; color: white 90%; height: auto; diff --git a/docs/examples/styles/padding.css b/docs/examples/styles/padding.css index 68ad84385..f993ce924 100644 --- a/docs/examples/styles/padding.css +++ b/docs/examples/styles/padding.css @@ -4,6 +4,6 @@ Screen { } Label { - padding: 4 8; - background: blue 20%; -} + padding: 4 8; + background: blue 20%; +} diff --git a/docs/examples/styles/tint.css b/docs/examples/styles/tint.css index 312f26a66..596949ece 100644 --- a/docs/examples/styles/tint.css +++ b/docs/examples/styles/tint.css @@ -1,8 +1,8 @@ -Label { +Label { height: 3; width: 100%; text-style: bold; - background: white; - color: black; - content-align: center middle; + background: white; + color: black; + content-align: center middle; } diff --git a/docs/examples/styles/tint.py b/docs/examples/styles/tint.py index 3da5f40a7..a77bc4a5e 100644 --- a/docs/examples/styles/tint.py +++ b/docs/examples/styles/tint.py @@ -8,7 +8,7 @@ class TintApp(App): color = Color.parse("green") for tint_alpha in range(0, 101, 10): widget = Label(f"tint: green {tint_alpha}%;") - widget.styles.tint = color.with_alpha(tint_alpha / 100) + widget.styles.tint = color.with_alpha(tint_alpha / 100) # (1)! yield widget diff --git a/docs/examples/styles/visibility.css b/docs/examples/styles/visibility.css index da684c03f..c0f6b2b82 100644 --- a/docs/examples/styles/visibility.css +++ b/docs/examples/styles/visibility.css @@ -1,6 +1,7 @@ Screen { background: green; } + Label { height: 5; width: 100%; @@ -8,6 +9,7 @@ Label { color: blue; border: heavy blue; } + Label.invisible { visibility: hidden; } From a3a452b674e37e01946213dbf13efaa4a2e8bc2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:11:59 +0000 Subject: [PATCH 250/310] Highlight rule usage in references. [skip ci] --- docs/styles/align.md | 2 +- docs/styles/background.md | 8 ++++---- docs/styles/border.md | 6 +++--- docs/styles/box_sizing.md | 2 +- docs/styles/color.md | 4 ++-- docs/styles/content_align.md | 2 +- docs/styles/display.md | 2 +- docs/styles/grid/column_span.md | 4 ++-- docs/styles/grid/grid_columns.md | 2 +- docs/styles/grid/grid_gutter.md | 2 +- docs/styles/grid/grid_rows.md | 2 +- docs/styles/grid/grid_size.md | 2 +- docs/styles/grid/row_span.md | 2 +- docs/styles/height.md | 2 +- docs/styles/layout.md | 2 +- docs/styles/margin.md | 6 +++--- docs/styles/max_height.md | 2 +- docs/styles/max_width.md | 2 +- docs/styles/min_height.md | 2 +- docs/styles/min_width.md | 2 +- docs/styles/offset.md | 2 +- docs/styles/opacity.md | 6 ++---- docs/styles/outline.md | 9 +++++---- docs/styles/overflow.md | 2 +- docs/styles/padding.md | 4 ++-- docs/styles/text_opacity.md | 2 +- docs/styles/text_style.md | 4 ++-- docs/styles/tint.md | 6 ++++-- docs/styles/visibility.md | 2 +- docs/styles/width.md | 4 ++-- 30 files changed, 50 insertions(+), 49 deletions(-) diff --git a/docs/styles/align.md b/docs/styles/align.md index 8f299d0e3..0bbb7eddf 100644 --- a/docs/styles/align.md +++ b/docs/styles/align.md @@ -61,7 +61,7 @@ Each label has been aligned differently inside its container, and its text shows === "align_all.css" - ```sass + ```sass hl_lines="2 6 10 14 18 22 26 30 34" --8<-- "docs/examples/styles/align_all.css" ``` diff --git a/docs/styles/background.md b/docs/styles/background.md index 936a350db..8bfdc3fd8 100644 --- a/docs/styles/background.md +++ b/docs/styles/background.md @@ -29,7 +29,7 @@ This example creates three widgets and applies a different background to each. === "background.css" - ```sass + ```sass hl_lines="9 13 17" --8<-- "docs/examples/styles/background.css" ``` @@ -50,7 +50,7 @@ The next example creates ten widgets layed out side by side to show the effect o === "background_transparency.css" - ```sass + ```sass hl_lines="2 6 10 14 18 22 26 30 34 38" --8<-- "docs/examples/styles/background_transparency.css" ``` @@ -64,10 +64,10 @@ background: blue; background: red 20%; /* RGB color */ -background: rgb(100,120,200); +background: rgb(100, 120, 200); /* HSL color */ -background: hsl(290,70%,80%); +background: hsl(290, 70%, 80%); ``` ## Python diff --git a/docs/styles/border.md b/docs/styles/border.md index 3b01cdfbb..fd6f117dd 100644 --- a/docs/styles/border.md +++ b/docs/styles/border.md @@ -71,7 +71,7 @@ This examples shows three widgets with different border styles. === "border.css" - ```sass + ```sass hl_lines="4 10 16" --8<-- "docs/examples/styles/border.css" ``` @@ -86,7 +86,7 @@ The next example shows a grid with all the available border types. === "border_all.py" - ```py + ```py hl_lines="2 6 10 14 18 22 26 30 34 38 42 46 50 54 58" --8<-- "docs/examples/styles/border_all.py" ``` @@ -116,7 +116,7 @@ This example also shows that a widget cannot contain both a `border` and an `out === "outline_vs_border.css" - ```sass + ```sass hl_lines="5-7 9-11" --8<-- "docs/examples/styles/outline_vs_border.css" ``` diff --git a/docs/styles/box_sizing.md b/docs/styles/box_sizing.md index 97bc9f288..f8c99f4cf 100644 --- a/docs/styles/box_sizing.md +++ b/docs/styles/box_sizing.md @@ -34,7 +34,7 @@ The bottom widget has `box-sizing: content-box` which increases the size of the === "box_sizing.css" - ```sass + ```sass hl_lines="2 6" --8<-- "docs/examples/styles/box_sizing.css" ``` diff --git a/docs/styles/color.md b/docs/styles/color.md index f4c6c5efa..901c33b22 100644 --- a/docs/styles/color.md +++ b/docs/styles/color.md @@ -31,7 +31,7 @@ This example sets a different text color for each of three different widgets. === "color.css" - ```sass + ```sass hl_lines="8 12 16" --8<-- "docs/examples/styles/color.css" ``` @@ -66,7 +66,7 @@ color: blue; color: red 20%; /* RGB color */ -color: rgb(100,120,200); +color: rgb(100, 120, 200); /* Automatically choose color with suitable contrast for readability */ color: auto; diff --git a/docs/styles/content_align.md b/docs/styles/content_align.md index 89ae21d81..2902d9a84 100644 --- a/docs/styles/content_align.md +++ b/docs/styles/content_align.md @@ -61,7 +61,7 @@ Each label has its text aligned differently. === "content_align_all.css" - ```sass + ```sass hl_lines="2 5 8 11 14 17 20 23 26" --8<-- "docs/examples/styles/content_align_all.css" ``` diff --git a/docs/styles/display.md b/docs/styles/display.md index d0d37a3c1..8077776b1 100644 --- a/docs/styles/display.md +++ b/docs/styles/display.md @@ -32,7 +32,7 @@ Note that the second widget is hidden by adding the `"remove"` class which sets === "display.css" - ```sass + ```sass hl_lines="13" --8<-- "docs/examples/styles/display.css" ``` diff --git a/docs/styles/grid/column_span.md b/docs/styles/grid/column_span.md index bddd24d4a..2ea6261e6 100644 --- a/docs/styles/grid/column_span.md +++ b/docs/styles/grid/column_span.md @@ -31,14 +31,14 @@ The example below shows a 4 by 4 grid where many placeholders span over several === "column_span.css" - ```sass + ```sass hl_lines="2 5 8 11 14 20" --8<-- "docs/examples/styles/column_span.css" ``` ## CSS ```sass -column-span: 3 +column-span: 3; ``` ## Python diff --git a/docs/styles/grid/grid_columns.md b/docs/styles/grid/grid_columns.md index 3c145e638..e1d34e28d 100644 --- a/docs/styles/grid/grid_columns.md +++ b/docs/styles/grid/grid_columns.md @@ -42,7 +42,7 @@ Because there are more rows than scalars in the style rule, the scalars will be === "grid_columns.css" - ```sass + ```sass hl_lines="3" --8<-- "docs/examples/styles/grid_columns.css" ``` diff --git a/docs/styles/grid/grid_gutter.md b/docs/styles/grid/grid_gutter.md index 1b61a1ae1..98a6d2d1e 100644 --- a/docs/styles/grid/grid_gutter.md +++ b/docs/styles/grid/grid_gutter.md @@ -37,7 +37,7 @@ The example below employs a common trick to apply visually consistent spacing ar === "grid_gutter.css" - ```sass + ```sass hl_lines="3" --8<-- "docs/examples/styles/grid_gutter.css" ``` diff --git a/docs/styles/grid/grid_rows.md b/docs/styles/grid/grid_rows.md index 4303a9029..eb53264fa 100644 --- a/docs/styles/grid/grid_rows.md +++ b/docs/styles/grid/grid_rows.md @@ -42,7 +42,7 @@ Because there are more rows than scalars in the style rule, the scalars will be === "grid_rows.css" - ```sass + ```sass hl_lines="3" --8<-- "docs/examples/styles/grid_rows.css" ``` diff --git a/docs/styles/grid/grid_size.md b/docs/styles/grid/grid_size.md index e8dd30293..d4d746bf9 100644 --- a/docs/styles/grid/grid_size.md +++ b/docs/styles/grid/grid_size.md @@ -60,7 +60,7 @@ In the second example, we create a grid with 2 columns and however many rows are === "grid_size_columns.css" - ```sass + ```sass hl_lines="2" --8<-- "docs/examples/styles/grid_size_columns.css" ``` diff --git a/docs/styles/grid/row_span.md b/docs/styles/grid/row_span.md index 12d1670ac..d55da6bfa 100644 --- a/docs/styles/grid/row_span.md +++ b/docs/styles/grid/row_span.md @@ -34,7 +34,7 @@ After placing the placeholders `#p1`, `#p2`, `#p3`, and `#p4`, the next availabl === "row_span.css" - ```sass + ```sass hl_lines="2 5 8 11 14 17 20" --8<-- "docs/examples/styles/row_span.css" ``` diff --git a/docs/styles/height.md b/docs/styles/height.md index cdaec0018..15d5399a3 100644 --- a/docs/styles/height.md +++ b/docs/styles/height.md @@ -30,7 +30,7 @@ This examples creates a widget with a height of 50% of the screen. === "height.css" - ```python + ```sass hl_lines="3" --8<-- "docs/examples/styles/height.css" ``` diff --git a/docs/styles/layout.md b/docs/styles/layout.md index e3d937340..8de70d561 100644 --- a/docs/styles/layout.md +++ b/docs/styles/layout.md @@ -38,7 +38,7 @@ To learn more about the grid layout, you can see the [layout guide](../guide/lay === "layout.css" - ```sass + ```sass hl_lines="2 8" --8<-- "docs/examples/styles/layout.css" ``` diff --git a/docs/styles/margin.md b/docs/styles/margin.md index ad6b26bfd..dd922de11 100644 --- a/docs/styles/margin.md +++ b/docs/styles/margin.md @@ -51,7 +51,7 @@ In the example below we add a large margin to a label, which makes it move away === "margin.css" - ```sass + ```sass hl_lines="7" --8<-- "docs/examples/styles/margin.css" ``` @@ -73,7 +73,7 @@ In each cell, we have a placeholder that has its margins set in different ways. === "margin_all.css" - ```py + ```sass hl_lines="25 29 33 37 41 45 49 53" --8<-- "docs/examples/styles/margin_all.css" ``` @@ -81,7 +81,7 @@ In each cell, we have a placeholder that has its margins set in different ways. ```sass /* Set margin of 1 around all edges */ -margin: 1 +margin: 1; /* Set margin of 2 on the top and bottom edges, and 4 on the left and right */ margin: 2 4; /* Set margin of 1 on the top, 2 on the right, diff --git a/docs/styles/max_height.md b/docs/styles/max_height.md index b8aa0ae2d..aa89dbade 100644 --- a/docs/styles/max_height.md +++ b/docs/styles/max_height.md @@ -29,7 +29,7 @@ Then, we set `max-height` individually on each placeholder. === "max_height.css" - ```sass + ```sass hl_lines="12 16 20 24" --8<-- "docs/examples/styles/max_height.css" ``` diff --git a/docs/styles/max_width.md b/docs/styles/max_width.md index 944a5474a..9cf7236b2 100644 --- a/docs/styles/max_width.md +++ b/docs/styles/max_width.md @@ -29,7 +29,7 @@ Then, we set `max-width` individually on each placeholder. === "max_width.css" - ```sass + ```sass hl_lines="12 16 20 24" --8<-- "docs/examples/styles/max_width.css" ``` diff --git a/docs/styles/min_height.md b/docs/styles/min_height.md index a201e87aa..a25dc9c7a 100644 --- a/docs/styles/min_height.md +++ b/docs/styles/min_height.md @@ -29,7 +29,7 @@ Then, we set `min-height` individually on each placeholder. === "min_height.css" - ```sass hl_lines="13" + ```sass hl_lines="13 17 21 25" --8<-- "docs/examples/styles/min_height.css" ``` diff --git a/docs/styles/min_width.md b/docs/styles/min_width.md index fe23b9448..15c32b64b 100644 --- a/docs/styles/min_width.md +++ b/docs/styles/min_width.md @@ -29,7 +29,7 @@ Then, we set `min-width` individually on each placeholder. === "min_width.css" - ```sass hl_lines="13" + ```sass hl_lines="13 17 21 25" --8<-- "docs/examples/styles/min_width.css" ``` diff --git a/docs/styles/offset.md b/docs/styles/offset.md index 33b546637..3c9b69711 100644 --- a/docs/styles/offset.md +++ b/docs/styles/offset.md @@ -32,7 +32,7 @@ In this example, we have 3 widgets with differing offsets. === "offset.css" - ```sass + ```sass hl_lines="13 20 27" --8<-- "docs/examples/styles/offset.css" ``` diff --git a/docs/styles/opacity.md b/docs/styles/opacity.md index 481181851..88db9ce9e 100644 --- a/docs/styles/opacity.md +++ b/docs/styles/opacity.md @@ -31,7 +31,7 @@ When the opacity is zero, all we see is the (black) background. === "opacity.css" - ```sass + ```sass hl_lines="2 6 10 14 18" --8<-- "docs/examples/styles/opacity.css" ``` @@ -39,9 +39,7 @@ When the opacity is zero, all we see is the (black) background. ```sass /* Fade the widget to 50% against its parent's background */ -Widget { - opacity: 50%; -} +opacity: 50%; ``` ## Python diff --git a/docs/styles/outline.md b/docs/styles/outline.md index d0d8fa398..2df963f9b 100644 --- a/docs/styles/outline.md +++ b/docs/styles/outline.md @@ -34,7 +34,8 @@ textual borders ### Basic usage -This example shows a widget with an outline. Note how the outline occludes the text area. +This example shows a widget with an outline. +Note how the outline occludes the text area. === "Output" @@ -49,7 +50,7 @@ This example shows a widget with an outline. Note how the outline occludes the t === "outline.css" - ```sass + ```sass hl_lines="8" --8<-- "docs/examples/styles/outline.css" ``` @@ -70,7 +71,7 @@ The next example shows a grid with all the available outline types. === "outline_all.css" - ```sass + ```sass hl_lines="2 6 10 14 18 22 26 30 34 38 42 46 50 54 58" --8<-- "docs/examples/styles/outline_all.css" ``` @@ -94,7 +95,7 @@ This example also shows that a widget cannot contain both a `border` and an `out === "outline_vs_border.css" - ```sass + ```sass hl_lines="5-7 9-11" --8<-- "docs/examples/styles/outline_vs_border.css" ``` diff --git a/docs/styles/overflow.md b/docs/styles/overflow.md index 51b8acf89..12edaac15 100644 --- a/docs/styles/overflow.md +++ b/docs/styles/overflow.md @@ -47,7 +47,7 @@ The right side has `overflow-y: hidden` which will prevent a scrollbar from bein === "overflow.css" - ```sass + ```sass hl_lines="19" --8<-- "docs/examples/styles/overflow.css" ``` diff --git a/docs/styles/padding.md b/docs/styles/padding.md index af3d247fd..ae4a83dc1 100644 --- a/docs/styles/padding.md +++ b/docs/styles/padding.md @@ -50,7 +50,7 @@ This example adds padding around some text. === "padding.css" - ```sass + ```sass hl_lines="7" --8<-- "docs/examples/styles/padding.css" ``` @@ -73,7 +73,7 @@ The effect of each padding setting is noticeable in the colored background aroun === "padding_all.css" - ```py + ```sass hl_lines="16 20 24 28 32 36 40 44" --8<-- "docs/examples/styles/padding_all.css" ``` diff --git a/docs/styles/text_opacity.md b/docs/styles/text_opacity.md index 25b26eb0f..ca89a3b0c 100644 --- a/docs/styles/text_opacity.md +++ b/docs/styles/text_opacity.md @@ -30,7 +30,7 @@ This example shows, from top to bottom, increasing `text-opacity` values. === "text_opacity.css" - ```sass + ```sass hl_lines="2 6 10 14 18" --8<-- "docs/examples/styles/text_opacity.css" ``` diff --git a/docs/styles/text_style.md b/docs/styles/text_style.md index f8a91a2e8..aa0d4fcdd 100644 --- a/docs/styles/text_style.md +++ b/docs/styles/text_style.md @@ -29,7 +29,7 @@ Each of the three text panels has a different text style, respectively `bold`, ` === "text_style.css" - ```sass + ```sass hl_lines="9 13 17" --8<-- "docs/examples/styles/text_style.css" ``` @@ -50,7 +50,7 @@ The next example shows all different styles on their own, as well as some combin === "text_style_all.css" - ```sass + ```sass hl_lines="2 6 10 14 18 22 26 30" --8<-- "docs/examples/styles/text_style_all.css" ``` diff --git a/docs/styles/tint.md b/docs/styles/tint.md index 3d4c308d3..6ca08b04e 100644 --- a/docs/styles/tint.md +++ b/docs/styles/tint.md @@ -21,10 +21,12 @@ This examples shows a green tint with gradually increasing alpha. === "tint.py" - ```python + ```python hl_lines="11" --8<-- "docs/examples/styles/tint.py" ``` + 1. We set the tint to a `Color` instance with varying levels of transparency, set through the method `.with_alpha`. + === "tint.css" ```sass @@ -35,7 +37,7 @@ This examples shows a green tint with gradually increasing alpha. ```sass /* A red tint (could indicate an error) */ -tint: red 20% +tint: red 20%; /* A green tint */ tint: rgba(0, 200, 0, 0.3); diff --git a/docs/styles/visibility.md b/docs/styles/visibility.md index 62ae2ac89..2d9e07590 100644 --- a/docs/styles/visibility.md +++ b/docs/styles/visibility.md @@ -47,7 +47,7 @@ Note that the second widget is hidden, while leaving a space where it would have === "visibility.css" - ```sass + ```sass hl_lines="14" --8<-- "docs/examples/styles/visibility.css" ``` diff --git a/docs/styles/width.md b/docs/styles/width.md index a66e8ae6c..bc1cf055b 100644 --- a/docs/styles/width.md +++ b/docs/styles/width.md @@ -30,7 +30,7 @@ This example adds a widget with 50% width of the screen. === "width.css" - ```sass + ```sass hl_lines="3" --8<-- "docs/examples/styles/width.css" ``` @@ -82,7 +82,7 @@ width: 10; width: 50%; /* Automatic width */ -width: auto +width: auto; ``` ## Python From e5375d0a2faa219661447e52e353fa53099a71da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:26:33 +0000 Subject: [PATCH 251/310] Reset color cycle before tests. We need to reset the color cycle for placeholders before each CSS property test because we need to ensure consistent colouring of the placeholders as tests are added/removed/reordered. --- tests/snapshot_tests/test_snapshots.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index 9eda4b045..e2da09d18 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -137,6 +137,7 @@ PATHS = [ @pytest.mark.parametrize("file_name", PATHS) def test_css_property(file_name, snap_compare): path_to_app = STYLES_EXAMPLES_DIR / file_name + Placeholder.reset_color_cycle() assert snap_compare(path_to_app) From 15691b4451cbff6d34f04fceea52192bb0a0f834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:34:06 +0000 Subject: [PATCH 252/310] Remove debugging style. --- docs/examples/styles/outline_all.css | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/examples/styles/outline_all.css b/docs/examples/styles/outline_all.css index 63215bae7..a206787e4 100644 --- a/docs/examples/styles/outline_all.css +++ b/docs/examples/styles/outline_all.css @@ -68,5 +68,4 @@ Label { width: 20; height: 3; content-align: center middle; - background: red; } From 130d8b8d059339812842002235a53f4069a53be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:34:24 +0000 Subject: [PATCH 253/310] Increase negative y offset. --- docs/examples/styles/offset.css | 2 +- docs/examples/styles/offset.py | 2 +- docs/styles/offset.md | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/examples/styles/offset.css b/docs/examples/styles/offset.css index 673f9fe1c..c659a00ed 100644 --- a/docs/examples/styles/offset.css +++ b/docs/examples/styles/offset.css @@ -24,7 +24,7 @@ Label { } .chani { - offset: 0 -2; + offset: 0 -3; background: blue 20%; border: outer blue; color: blue; diff --git a/docs/examples/styles/offset.py b/docs/examples/styles/offset.py index 337e1112a..01ceccc42 100644 --- a/docs/examples/styles/offset.py +++ b/docs/examples/styles/offset.py @@ -6,7 +6,7 @@ class OffsetApp(App): def compose(self): yield Label("Paul (offset 8 2)", classes="paul") yield Label("Duncan (offset 4 10)", classes="duncan") - yield Label("Chani (offset 0 -2)", classes="chani") + yield Label("Chani (offset 0 -3)", classes="chani") app = OffsetApp(css_path="offset.css") diff --git a/docs/styles/offset.md b/docs/styles/offset.md index 3c9b69711..2a5ffefce 100644 --- a/docs/styles/offset.md +++ b/docs/styles/offset.md @@ -39,13 +39,13 @@ In this example, we have 3 widgets with differing offsets. ## CSS ```sass -/* Move the widget 8 cells in the x direction and 2 in tye y direction */ +/* Move the widget 8 cells in the x direction and 2 in the y direction */ offset: 8 2; /* Move the widget 4 cells in the x direction offset-x: 4; -/* Move the widget -2 cells in the y direction -offset-y: -2; +/* Move the widget -3 cells in the y direction +offset-y: -3; ``` ## Python From d41471034a0535953eceabdfa764d8d230f22aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:39:12 +0000 Subject: [PATCH 254/310] Fix failing tests. --- docs/examples/styles/margin.css | 1 + docs/examples/styles/outline.css | 2 ++ docs/examples/styles/padding.css | 1 + 3 files changed, 4 insertions(+) diff --git a/docs/examples/styles/margin.css b/docs/examples/styles/margin.css index 296a88174..fd8e0633b 100644 --- a/docs/examples/styles/margin.css +++ b/docs/examples/styles/margin.css @@ -7,4 +7,5 @@ Label { margin: 4 8; background: blue 20%; border: blue wide; + width: 100%; } diff --git a/docs/examples/styles/outline.css b/docs/examples/styles/outline.css index b422b5332..10b475529 100644 --- a/docs/examples/styles/outline.css +++ b/docs/examples/styles/outline.css @@ -2,8 +2,10 @@ Screen { background: white; color: black; } + Label { margin: 4 8; background: green 20%; outline: wide green; + width: 100%; } diff --git a/docs/examples/styles/padding.css b/docs/examples/styles/padding.css index f993ce924..7acebc85b 100644 --- a/docs/examples/styles/padding.css +++ b/docs/examples/styles/padding.css @@ -6,4 +6,5 @@ Screen { Label { padding: 4 8; background: blue 20%; + width: 100%; } From d9a0c343d7be717fbe646dada7b1ae302e6ffe1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:42:15 +0000 Subject: [PATCH 255/310] Update snapshot tests. --- .../__snapshots__/test_snapshots.ambr | 5878 ++++++++++++++++- 1 file changed, 5636 insertions(+), 242 deletions(-) diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index d920e8d87..0f1da3cf2 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -659,6 +659,164 @@ ''' # --- +# name: test_css_property[align_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AlignAllApp + + + + + + + + + + ──────────────────────────────────────────────────────────────────────── + left topcenter topright top + + + + + ──────────────────────────────────────────────────────────────────────── + + ──────────────────────────────────────────────────────────────────────── + + + left middlecenter middleright middle + + + ──────────────────────────────────────────────────────────────────────── + + ──────────────────────────────────────────────────────────────────────── + + + + + + left bottomcenter bottomright bottom + ──────────────────────────────────────────────────────────────────────── + + + + + ''' +# --- # name: test_css_property[background.py] ''' @@ -814,6 +972,170 @@ ''' # --- +# name: test_css_property[background_transparency.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BackgroundTransparencyApp + + + + + + + + + + + + + + + + + + + + + 10%20%30%40%50%60%70%80%90%100% + + + + + + + + + + + + + + + + + ''' +# --- # name: test_css_property[border.py] ''' @@ -972,6 +1294,164 @@ ''' # --- +# name: test_css_property[border_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllBordersApp + + + + + + + + + + +------------------+╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + |ascii|blankdashed + +------------------+╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + + + ══════════════════━━━━━━━━━━━━━━━━━━ + doubleheavyhidden/none + ══════════════════━━━━━━━━━━━━━━━━━━ + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + hkeyinnernone + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ + + + ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀──────────────────────────────────── + outerroundsolid + ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄──────────────────────────────────── + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + tallvkeywide + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + ''' +# --- # name: test_css_property[box_sizing.py] ''' @@ -1285,6 +1765,326 @@ ''' # --- +# name: test_css_property[color_auto.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ColorApp + + + + + + + + + + + The quick brown fox jumps over the lazy dog! + + + + + The quick brown fox jumps over the lazy dog! + + + + + The quick brown fox jumps over the lazy dog! + + + + + The quick brown fox jumps over the lazy dog! + + + + + The quick brown fox jumps over the lazy dog! + + + + + + + ''' +# --- +# name: test_css_property[column_span.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + + + #p1 + + + + + + #p2#p3 + + + + + + #p4#p5 + + + + + + #p6#p7 + + + + + + + + ''' +# --- # name: test_css_property[content_align.py] ''' @@ -1442,6 +2242,162 @@ ''' # --- +# name: test_css_property[content_align_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllContentAlignApp + + + + + + + + + + left topcenter topright top + + + + + + + + + + + left middlecenter middleright middle + + + + + + + + + + + + left bottomcenter bottomright bottom + + + + + ''' +# --- # name: test_css_property[display.py] ''' @@ -1598,6 +2554,162 @@ ''' # --- +# name: test_css_property[dock_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DockAllApp + + + + + + + + + + + + + ────────────────────────────────────────────────────────── + top + + + + + + + leftright + + + + + + + + bottom + ────────────────────────────────────────────────────────── + + + + + + + + ''' +# --- # name: test_css_property[grid.py] ''' @@ -1755,6 +2867,786 @@ ''' # --- +# name: test_css_property[grid_columns.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ────────────────────────────────────────────────────────────────────── + 1frwidth = 162fr1frwidth = 16 + + + + + + + + + + ────────────────────────────────────────────────────────────────────── + ────────────────────────────────────────────────────────────────────── + 1frwidth = 162fr1frwidth = 16 + + + + + + + + + + ────────────────────────────────────────────────────────────────────── + + + + + ''' +# --- +# name: test_css_property[grid_gutter.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ────────────────────────────────────────────────────────────────────────── + + 12 + + ────────────────────────────────────────────────────────────────────────── + + ────────────────────────────────────────────────────────────────────────── + + 34 + + ────────────────────────────────────────────────────────────────────────── + + ────────────────────────────────────────────────────────────────────────── + + 56 + + ────────────────────────────────────────────────────────────────────────── + + ────────────────────────────────────────────────────────────────────────── + + 78 + + + ────────────────────────────────────────────────────────────────────────── + + + + + ''' +# --- +# name: test_css_property[grid_rows.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ──────────────────────────────────────────────────────────────────────────── + 1fr1fr + ──────────────────────────────────────────────────────────────────────────── + ──────────────────────────────────────────────────────────────────────────── + + height = 6height = 6 + + + ──────────────────────────────────────────────────────────────────────────── + ──────────────────────────────────────────────────────────────────────────── + + 25%25% + + + ──────────────────────────────────────────────────────────────────────────── + ──────────────────────────────────────────────────────────────────────────── + 1fr1fr + ──────────────────────────────────────────────────────────────────────────── + ──────────────────────────────────────────────────────────────────────────── + + height = 6height = 6 + + + ──────────────────────────────────────────────────────────────────────────── + + + + + ''' +# --- +# name: test_css_property[grid_size_both.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ──────────────────────────────────────────────────────────────────────────── + + 12 + + + ──────────────────────────────────────────────────────────────────────────── + ──────────────────────────────────────────────────────────────────────────── + + 34 + + + ──────────────────────────────────────────────────────────────────────────── + ────────────────────────────────────── + + 5 + + + ────────────────────────────────────── + + + + + + + + + + + ''' +# --- +# name: test_css_property[grid_size_columns.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ──────────────────────────────────────────────────────────────────────────── + + + 12 + + + + ──────────────────────────────────────────────────────────────────────────── + ──────────────────────────────────────────────────────────────────────────── + + + 34 + + + + ──────────────────────────────────────────────────────────────────────────── + ────────────────────────────────────── + + + 5 + + + + ────────────────────────────────────── + + + + + ''' +# --- # name: test_css_property[height.py] ''' @@ -1911,6 +3803,170 @@ ''' # --- +# name: test_css_property[height_comparison.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeightComparisonApp + + + + + + + + + + #cells· + · + · + #percent· + + · + #w· + · + · + + #h· + · + · + · + #vw + · + · + · + #vh· + + #auto· + #fr1· + #fr2· + · + + + + + ''' +# --- # name: test_css_property[layout.py] ''' @@ -2069,6 +4125,948 @@ ''' # --- +# name: test_css_property[link_background.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkBackgroundApp + + + + + + + + + + Visit the Textualize website. + Click here for the bell sound. + You can also click here for the bell sound. + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_color.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkColorApp + + + + + + + + + + Visit the Textualize website. + Click here for the bell sound. + You can also click here for the bell sound. + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_hover_background.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkHoverBackgroundApp + + + + + + + + + + Visit the Textualize website. + Click here for the bell sound. + You can also click here for the bell sound. + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_hover_color.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkHoverColorApp + + + + + + + + + + Visit the Textualize website. + Click here for the bell sound. + You can also click here for the bell sound. + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_hover_style.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkHoverStyleApp + + + + + + + + + + Visit the Textualize website. + Click here for the bell sound. + You can also click here for the bell sound. + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_style.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkStyleApp + + + + + + + + + + Visit the Textualize website. + Click here for the bell sound. + You can also click here for the bell sound. + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- # name: test_css_property[links.py] ''' @@ -2383,6 +5381,805 @@ ''' # --- +# name: test_css_property[margin_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarginAllApp + + + + + + + + + + ────────────────────────────────────────────────────────────────── + + + + marginmargin: 1  + no marginmargin: 1: 1 51 2 6 + + + + + ────────────────────────────────────────────────────────────────── + + ────────────────────────────────────────────────────────────────── + + + margin-bottom: 4 + + margin-right: margin-left: 3 + 3 + margin-top: 4 + + + + ────────────────────────────────────────────────────────────────── + + + + + ''' +# --- +# name: test_css_property[max_height.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaxHeightApp + + + + + + + + + + + + + max-height: 10w + max-height: 10 + max-height: 50% + + + + + + max-height: 999 + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[max_width.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaxWidthApp + + + + + + + + + + + + max-width:  + 50h + + + + + max-width: 999 + + + + + + max-width: 50% + + + + + + max-width: 30 + + + + + + + + ''' +# --- +# name: test_css_property[min_height.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MinHeightApp + + + + + + + + + + + + + + + min-height: 25% + + + min-height: 75% + + + + + + min-height: 30 + min-height: 40w + + + ▃▃ + + + + + + + + + + ''' +# --- +# name: test_css_property[min_width.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MinWidthApp + + + + + + + + + + + + min-width: 25% + + + + + min-width: 75% + + + + + + min-width: 100 + + + + + + min-width: 400h + + + + + + + + + ''' +# --- # name: test_css_property[offset.py] ''' @@ -2406,134 +6203,134 @@ font-weight: 700; } - .terminal-4002837244-matrix { + .terminal-292160688-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4002837244-title { + .terminal-292160688-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4002837244-r1 { fill: #000000 } - .terminal-4002837244-r2 { fill: #c5c8c6 } - .terminal-4002837244-r3 { fill: #ff0000 } - .terminal-4002837244-r4 { fill: #0000ff } - .terminal-4002837244-r5 { fill: #008000 } + .terminal-292160688-r1 { fill: #000000 } + .terminal-292160688-r2 { fill: #0000ff } + .terminal-292160688-r3 { fill: #c5c8c6 } + .terminal-292160688-r4 { fill: #ff0000 } + .terminal-292160688-r5 { fill: #008000 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - OffsetApp + OffsetApp - - - - - - ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ - - - ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ - Paul (offset 8 2) - - - Chani (offset 0 5) - ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ - ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ - - - Duncan (offset ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ - 10) - - - - ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ - - - + + + + + Chani (offset 0  + ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀-3) + + + + Paul (offset 8 2)▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + + + + ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ + ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + + + Duncan (offset 4  + 10) + + + + ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + + + @@ -2564,140 +6361,140 @@ font-weight: 700; } - .terminal-2191428201-matrix { + .terminal-3644012779-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2191428201-title { + .terminal-3644012779-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2191428201-r1 { fill: #fefcf9 } - .terminal-2191428201-r2 { fill: #c5c8c6 } - .terminal-2191428201-r3 { fill: #c3d4e1 } - .terminal-2191428201-r4 { fill: #f4edde;font-weight: bold } - .terminal-2191428201-r5 { fill: #8cbdeb } - .terminal-2191428201-r6 { fill: #eeefe5;font-weight: bold } - .terminal-2191428201-r7 { fill: #55a6f5 } - .terminal-2191428201-r8 { fill: #e8f1ec;font-weight: bold } - .terminal-2191428201-r9 { fill: #1e90ff } - .terminal-2191428201-r10 { fill: #e2f4f3;font-weight: bold } + .terminal-3644012779-r1 { fill: #dddddd } + .terminal-3644012779-r2 { fill: #c5c8c6 } + .terminal-3644012779-r3 { fill: #07243f } + .terminal-3644012779-r4 { fill: #383d3c;font-weight: bold } + .terminal-3644012779-r5 { fill: #0f487f } + .terminal-3644012779-r6 { fill: #717a79;font-weight: bold } + .terminal-3644012779-r7 { fill: #166cbf } + .terminal-3644012779-r8 { fill: #a9b7b6;font-weight: bold } + .terminal-3644012779-r9 { fill: #1e90ff } + .terminal-3644012779-r10 { fill: #e2f4f3;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - OpacityApp + OpacityApp - - - - - - - - ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ - - opacity: 25% - - ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ - ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ - - opacity: 50% - - ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ - ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ - - opacity: 75% - - ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ - ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ - - opacity: 100% - - ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + + + + + + + + ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ + + opacity: 25% + + ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ + + opacity: 50% + + ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ + + opacity: 75% + + ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ + + opacity: 100% + + ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ @@ -2861,6 +6658,321 @@ ''' # --- +# name: test_css_property[outline_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllOutlinesApp + + + + + + + + + + +------------------+╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + |ascii|blankdashed + +------------------+╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + + + ══════════════════━━━━━━━━━━━━━━━━━━ + doubleheavyhidden/none + ══════════════════━━━━━━━━━━━━━━━━━━ + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + hkeyinnernone + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ + + + ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀──────────────────────────────────── + outerroundsolid + ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄──────────────────────────────────── + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + tallvkeywide + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + ''' +# --- +# name: test_css_property[outline_vs_border.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OutlineBorderApp + + + + + + + + + + ─────────────────────────────────────────────────────────────────── + ear is the mind-killer. + ear is the little-death that brings total obliteration. +  will face my fear. +  will permit it to pass over me and through me. + nd when it has gone past, I will turn the inner eye to see its path + here the fear has gone there will be nothing. Only I will remain. + ─────────────────────────────────────────────────────────────────── + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + ───────────────────────────────────────────────────────────────────── + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + ───────────────────────────────────────────────────────────────────── + + + + + ''' +# --- # name: test_css_property[overflow.py] ''' @@ -3175,6 +7287,485 @@ ''' # --- +# name: test_css_property[padding_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PaddingAllApp + + + + + + + + + + no padding + padding: 1padding:padding: 1 1 + 1 52 6 + + + + + + + + + + padding-right: 3padding-bottom: 4padding-left: 3 + + + + padding-top: 4 + + + + + + + + + + + + ''' +# --- +# name: test_css_property[row_span.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + + + #p4 + + + #p3 + + + #p2 + + + #p1 + + + #p5 + + + #p6 + + + #p7 + + + + + + + + ''' +# --- +# name: test_css_property[scrollbar_corner_color.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarCornerColorApp + + + + + + + + + + I must not fear. Fear is the mind-killer. Fear is the little-death that brings + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain.▅▅ + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + + + + + + ''' +# --- # name: test_css_property[scrollbar_gutter.py] ''' @@ -3487,6 +8078,165 @@ ''' # --- +# name: test_css_property[scrollbar_size2.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarApp + + + + + + + + + + I must not fear.I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death Fear is the little-death tFear is the little-death  + I will face my fear.I will face my fear.I will face my fear. + I will permit it to pass I will permit it to pass oI will permit it to pass  + And when it has gone pastAnd when it has gone past,And when it has gone past + Where the fear has gone tWhere the fear has gone thWhere the fear has gone t + I must not fear.I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death Fear is the little-death tFear is the little-death  + I will face my fear.I will face my fear.I will face my fear.▇▇ + I will permit it to pass I will permit it to pass oI will permit it to pass  + And when it has gone pastAnd when it has gone past,And when it has gone past + Where the fear has gone tWhere the fear has gone thWhere the fear has gone t + I must not fear.I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death Fear is the little-death tFear is the little-death  + I will face my fear.I will face my fear.I will face my fear. + I will permit it to pass I will permit it to pass oI will permit it to pass  + And when it has gone past, + Where the fear has gone th + I must not fear. + Fear is the mind-killer. + + + + + + ''' +# --- # name: test_css_property[scrollbars.py] ''' @@ -3510,134 +8260,292 @@ font-weight: 700; } - .terminal-3032075324-matrix { + .terminal-2627045644-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3032075324-title { + .terminal-2627045644-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3032075324-r1 { fill: #c5c8c6 } - .terminal-3032075324-r2 { fill: #d2d2d2 } - .terminal-3032075324-r3 { fill: #bbbbbb } - .terminal-3032075324-r4 { fill: #800080 } + .terminal-2627045644-r1 { fill: #e1e1e1 } + .terminal-2627045644-r2 { fill: #c5c8c6 } + .terminal-2627045644-r3 { fill: #14191f } + .terminal-2627045644-r4 { fill: #ff0000 } + .terminal-2627045644-r5 { fill: #23568b } + .terminal-2627045644-r6 { fill: #008000 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - ScrollbarApp + ScrollbarApp - - - - - - I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death that Fear is the little-death that  - brings total obliteration.brings total obliteration. - I will face my fear.I will face my fear. - I will permit it to pass over I will permit it to pass over  - me and through me.▇▇me and through me.▇▇ - And when it has gone past, I And when it has gone past, I  - will turn the inner eye to seewill turn the inner eye to see - its path.its path. - Where the fear has gone there Where the fear has gone there  - will be nothing. Only I will will be nothing. Only I will  - remain.remain. - I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death that Fear is the little-death that  - brings total obliteration.brings total obliteration. - I will face my fear.I will face my fear. - I will permit it to pass over I will permit it to pass over  - me and through me.me and through me. - And when it has gone past, I And when it has gone past, I  - + + + + I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death that brings tFear is the little-death that brings t + I will face my fear.I will face my fear. + I will permit it to pass over me and tI will permit it to pass over me and t + And when it has gone past, I will turnAnd when it has gone past, I will turn + see its path.see its path. + Where the fear has gone there will be Where the fear has gone there will be  + will remain.will remain. + I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death that brings tFear is the little-death that brings t + I will face my fear.I will face my fear. + I will permit it to pass over me and tI will permit it to pass over me and t + And when it has gone past, I will turnAnd when it has gone past, I will turn + see its path.▃▃see its path.▃▃ + Where the fear has gone there will be Where the fear has gone there will be  + will remain.will remain. + I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death that brings tFear is the little-death that brings t + I will face my fear.I will face my fear. + I will permit it to pass over me and tI will permit it to pass over me and t + + + + + + ''' +# --- +# name: test_css_property[scrollbars2.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Scrollbar2App + + + + + + + + + + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + Fear is the mind-killer.▇▇ + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. @@ -3667,138 +8575,138 @@ font-weight: 700; } - .terminal-1285129494-matrix { + .terminal-3840959336-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1285129494-title { + .terminal-3840959336-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1285129494-r1 { fill: #c5c8c6 } - .terminal-1285129494-r2 { fill: #f4f9fb;font-weight: bold } - .terminal-1285129494-r3 { fill: #f4f9fb } - .terminal-1285129494-r4 { fill: #f8e9e9 } - .terminal-1285129494-r5 { fill: #f8e9e9;font-weight: bold } - .terminal-1285129494-r6 { fill: #f1fef1 } - .terminal-1285129494-r7 { fill: #f1fef1;font-weight: bold } - .terminal-1285129494-r8 { fill: #faecf0;font-weight: bold } - .terminal-1285129494-r9 { fill: #faecf0 } + .terminal-3840959336-r1 { fill: #c5c8c6 } + .terminal-3840959336-r2 { fill: #161c1d;font-weight: bold } + .terminal-3840959336-r3 { fill: #161c1d } + .terminal-3840959336-r4 { fill: #f8e9e9 } + .terminal-3840959336-r5 { fill: #f8e9e9;font-weight: bold } + .terminal-3840959336-r6 { fill: #132013 } + .terminal-3840959336-r7 { fill: #132013;font-weight: bold } + .terminal-3840959336-r8 { fill: #1c0e13;font-weight: bold } + .terminal-3840959336-r9 { fill: #1c0e13 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - TextAlign + TextAlign - - - - - Left aligned - I must not fear. Fear is the mind-killer. Fear is the little-death that brings - total obliteration. I will face my fear. I will permit it to pass over me and  - through me.                                                                    - - - Center aligned - I must not fear. Fear is the mind-killer. Fear is the little-death that brings - total obliteration. I will face my fear. I will permit it to pass over me and  -                                  through me.                                   - - - Right aligned - I must not fear. Fear is the mind-killer. Fear is the little-death that brings -  total obliteration. I will face my fear. I will permit it to pass over me and -                                                                    through me. - - - Justified - I must not fear. Fear is the mind-killer. Fear is the little-death that brings - total obliteration. I will face my fear. I will permit it to pass over me  and - through me. + + + + + Left alignedCenter aligned + I must not fear. Fear is the            I must not fear. Fear is the     + mind-killer. Fear is the                  mind-killer. Fear is the       + little-death that brings total         little-death that brings total    + obliteration. I will face my fear. Iobliteration. I will face my fear. I + will permit it to pass over me and   will permit it to pass over me and  + through me.                                     through me.              + + + + + + Right alignedJustified +         I must not fear. Fear is theI  must  not  fear.  Fear   is   the +             mind-killer. Fear is themind-killer.     Fear     is     the +       little-death that brings totallittle-death   that   brings   total + obliteration. I will face my fear. Iobliteration. I will face my fear. I +   will permit it to pass over me andwill permit it to pass over  me  and +                          through me.through me. + + + @@ -4122,6 +9030,168 @@ ''' # --- +# name: test_css_property[text_style_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllTextStyleApp + + + + + + + + + + + nonebolditalicreverse + I must not fear.I must not fear.I must not fear.I must not fear. + Fear is the Fear is the Fear is the Fear is the  + mind-killer.mind-killer.mind-killer.mind-killer. + Fear is the Fear is the Fear is the Fear is the  + little-death thatlittle-death that little-death thatlittle-death that  + brings total brings total brings total brings total  + obliteration.obliteration.obliteration.obliteration. + I will face my I will face my I will face my I will face my  + fear.fear.fear.fear. + + strikeunderlinebold italicreverse strike + I must not fear.I must not fear.I must not fear.I must not fear. + Fear is the Fear is the Fear is the Fear is the  + mind-killer.mind-killer.mind-killer.mind-killer. + Fear is the Fear is the Fear is the Fear is the  + little-death thatlittle-death that little-death thatlittle-death that  + brings total brings total brings total brings total  + obliteration.obliteration.obliteration.obliteration. + I will face my I will face my I will face my I will face my  + fear.fear.fear.fear. + I will permit it I will permit it I will permit it I will permit it  + + + + + + ''' +# --- # name: test_css_property[tint.py] ''' @@ -4442,6 +9512,166 @@ ''' # --- +# name: test_css_property[visibility_containers.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VisibilityContainersApp + + + + + + + + + + + + + PlaceholderPlaceholderPlaceholder + + + + + + + + + + + + + + + + PlaceholderPlaceholderPlaceholder + + + + + + + + + ''' +# --- # name: test_css_property[width.py] ''' @@ -4598,6 +9828,170 @@ ''' # --- +# name: test_css_property[width_comparison.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeightComparisonApp + + + + + + + + + + + + + + + + + + + + + #cells#percent#w#h#vw#vh#auto#fr1#fr3 + + + + + + + + + + + + ····•····•····•····•····•····•····•····•····•····•····•····•····•····•····•····• + + + + + ''' +# --- # name: test_datatable_render ''' From 9b779c130d55b0ea18cfdb6c331649653da47510 Mon Sep 17 00:00:00 2001 From: Ofek Lev Date: Tue, 10 Jan 2023 01:42:16 -0500 Subject: [PATCH 256/310] Fix typo --- docs/examples/events/dictionary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/events/dictionary.py b/docs/examples/events/dictionary.py index 24544c39e..cf85c2bf6 100644 --- a/docs/examples/events/dictionary.py +++ b/docs/examples/events/dictionary.py @@ -12,7 +12,7 @@ from textual.widgets import Static, Input class DictionaryApp(App): - """Searches ab dictionary API as-you-type.""" + """Searches a dictionary API as-you-type.""" CSS_PATH = "dictionary.css" From 6ea68cc1121911d6b40f52da029b6fb301d94b5e Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 10 Jan 2023 10:42:07 +0000 Subject: [PATCH 257/310] Add Tree.get_node_by_id The thinking here is that a user of a Tree may want to relate notes to other parts of their UI, or other data in their application. While this could be done by keeping a reference to the node itself, it could also be beneficial to just track the ID. Given that ID is a public property of a TreeNode, but given it doesn't currently have any other (public) purpose, this seems to add some useful symmetry. --- CHANGELOG.md | 1 + src/textual/widgets/_tree.py | 11 +++++++++++ tests/tree/test_tree_get_node_by_id.py | 16 ++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 tests/tree/test_tree_get_node_by_id.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 90bb8ddc2..b94054b1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `TreeNode.parent` -- a read-only property for accessing a node's parent https://github.com/Textualize/textual/issues/1397 - Added public `TreeNode` label access via `TreeNode.label` https://github.com/Textualize/textual/issues/1396 - Added read-only public access to the children of a `TreeNode` via `TreeNode.children` https://github.com/Textualize/textual/issues/1398 +- Added `Tree.get_node_by_id` to allow getting a node by its ID ### Changed diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index bc431e143..f6c3be5b0 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -513,6 +513,17 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): else: return line.node + def get_node_by_id(self, node_id: NodeID) -> TreeNode[TreeDataType]: + """Get a tree node by its ID. + + Args: + node_id (NodeID): The ID of the node to get. + + Returns: + TreeNode[TreeDataType]: The node associated with that ID. + """ + return self._nodes[node_id] + def validate_cursor_line(self, value: int) -> int: """Prevent cursor line from going outside of range.""" return clamp(value, 0, len(self._tree_lines) - 1) diff --git a/tests/tree/test_tree_get_node_by_id.py b/tests/tree/test_tree_get_node_by_id.py new file mode 100644 index 000000000..fbe01a150 --- /dev/null +++ b/tests/tree/test_tree_get_node_by_id.py @@ -0,0 +1,16 @@ +import pytest +from typing import cast +from textual.widgets import Tree +from textual.widgets._tree import NodeID + + +def test_get_tree_node_by_id() -> None: + """It should be possible to get a TreeNode by its ID.""" + tree = Tree[None]("Anakin") + child = tree.root.add("Leia") + grandchild = child.add("Ben") + assert tree.get_node_by_id(tree.root.id).id == tree.root.id + assert tree.get_node_by_id(child.id).id == child.id + assert tree.get_node_by_id(grandchild.id).id == grandchild.id + with pytest.raises(KeyError): + tree.get_node_by_id(cast(NodeID, grandchild.id + 1000)) From 39ec545b694bf325709a03af997e349c07be33dd Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 10 Jan 2023 10:46:00 +0000 Subject: [PATCH 258/310] Update the CHANGELOG with a link to the PR Now that it's a PR --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b94054b1d..4b61efc94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `TreeNode.parent` -- a read-only property for accessing a node's parent https://github.com/Textualize/textual/issues/1397 - Added public `TreeNode` label access via `TreeNode.label` https://github.com/Textualize/textual/issues/1396 - Added read-only public access to the children of a `TreeNode` via `TreeNode.children` https://github.com/Textualize/textual/issues/1398 -- Added `Tree.get_node_by_id` to allow getting a node by its ID +- Added `Tree.get_node_by_id` to allow getting a node by its ID https://github.com/Textualize/textual/pull/1535 ### Changed From c19521ac4386d60aa2d0fbe47b22783a0fcf40d7 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 10 Jan 2023 14:14:54 +0000 Subject: [PATCH 259/310] Make events.Paste bubble See #1434. --- CHANGELOG.md | 1 + src/textual/events.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90bb8ddc2..12600609e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `MouseScrollUp` and `MouseScrollDown` now inherit from `MouseEvent` and have attached modifier keys. https://github.com/Textualize/textual/pull/1458 - Fail-fast and print pretty tracebacks for Widget compose errors https://github.com/Textualize/textual/pull/1505 - Added Widget._refresh_scroll to avoid expensive layout when scrolling https://github.com/Textualize/textual/pull/1524 +- `events.Pase` now bubbles https://github.com/Textualize/textual/issues/1434 ### Fixed diff --git a/src/textual/events.py b/src/textual/events.py index e99007e21..376d17fe7 100644 --- a/src/textual/events.py +++ b/src/textual/events.py @@ -481,7 +481,7 @@ class DescendantBlur(Event, bubble=True, verbose=True): @rich.repr.auto -class Paste(Event, bubble=False): +class Paste(Event, bubble=True): """Event containing text that was pasted into the Textual application. This event will only appear when running in a terminal emulator that supports bracketed paste mode. Textual will enable bracketed pastes when an app starts, From 0f8c0b43bfcea3a742ebab64dc1c63a44c5bb660 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 10 Jan 2023 14:24:58 +0000 Subject: [PATCH 260/310] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12600609e..21c79a734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `MouseScrollUp` and `MouseScrollDown` now inherit from `MouseEvent` and have attached modifier keys. https://github.com/Textualize/textual/pull/1458 - Fail-fast and print pretty tracebacks for Widget compose errors https://github.com/Textualize/textual/pull/1505 - Added Widget._refresh_scroll to avoid expensive layout when scrolling https://github.com/Textualize/textual/pull/1524 -- `events.Pase` now bubbles https://github.com/Textualize/textual/issues/1434 +- `events.Paste` now bubbles https://github.com/Textualize/textual/issues/1434 ### Fixed From d8a4fda4f1ce4ffaf853a3aa2245f008cb610ab0 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 10 Jan 2023 14:26:04 +0000 Subject: [PATCH 261/310] Fix a CHANGELOG typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12600609e..21c79a734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `MouseScrollUp` and `MouseScrollDown` now inherit from `MouseEvent` and have attached modifier keys. https://github.com/Textualize/textual/pull/1458 - Fail-fast and print pretty tracebacks for Widget compose errors https://github.com/Textualize/textual/pull/1505 - Added Widget._refresh_scroll to avoid expensive layout when scrolling https://github.com/Textualize/textual/pull/1524 -- `events.Pase` now bubbles https://github.com/Textualize/textual/issues/1434 +- `events.Paste` now bubbles https://github.com/Textualize/textual/issues/1434 ### Fixed From e1d36e5be82b8a4fb37e5a2b36e2f3b7435dcc9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 10 Jan 2023 14:45:37 +0000 Subject: [PATCH 262/310] Minor doc fixes. --- docs/styles/grid/index.md | 2 +- mkdocs.yml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/styles/grid/index.md b/docs/styles/grid/index.md index 0236e62df..364fbaf3e 100644 --- a/docs/styles/grid/index.md +++ b/docs/styles/grid/index.md @@ -2,7 +2,7 @@ There are a number of properties relating to the Textual `grid` layout. -For an in-depth look at the grid layout, visit the grid [guide](../guide/layout.md#grid). +For an in-depth look at the grid layout, visit the grid [guide](../../guide/layout.md#grid). | Property | Description | |----------------|------------------------------------------------| diff --git a/mkdocs.yml b/mkdocs.yml index ebd1993c7..24914866c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -143,6 +143,7 @@ nav: - API: - "api/index.md" - "api/app.md" + - "api/binding.md" - "api/button.md" - "api/checkbox.md" - "api/color.md" @@ -161,12 +162,15 @@ nav: - "api/message_pump.md" - "api/message.md" - "api/pilot.md" + - "api/placeholder.md" - "api/query.md" - "api/reactive.md" - "api/screen.md" - "api/static.md" - "api/text_log.md" - "api/timer.md" + - "api/tree.md" + - "api/tree_node.md" - "api/walk.md" - "api/widget.md" - "Blog": From 728acc27c0d90a9e00184871a78df840d1bf69d3 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 10 Jan 2023 14:57:35 +0000 Subject: [PATCH 263/310] Introduce an exception specific to handling an unknown node ID See https://github.com/Textualize/textual/pull/1535#discussion_r1065873649 --- src/textual/widgets/_tree.py | 11 ++++++++++- tests/tree/test_tree_get_node_by_id.py | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index f6c3be5b0..0f1d99af7 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -513,6 +513,9 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): else: return line.node + class UnknownID(Exception): + """Exception raised when referring to an unknown `TreeNode` ID.""" + def get_node_by_id(self, node_id: NodeID) -> TreeNode[TreeDataType]: """Get a tree node by its ID. @@ -521,8 +524,14 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): Returns: TreeNode[TreeDataType]: The node associated with that ID. + + Raises: + Tree.UnknownID: Raised if the `TreeNode` ID is unknown. """ - return self._nodes[node_id] + try: + return self._nodes[node_id] + except KeyError: + raise self.UnknownID(f"Unknown TreeNode ID: {node_id}") from None def validate_cursor_line(self, value: int) -> int: """Prevent cursor line from going outside of range.""" diff --git a/tests/tree/test_tree_get_node_by_id.py b/tests/tree/test_tree_get_node_by_id.py index fbe01a150..d9eca97af 100644 --- a/tests/tree/test_tree_get_node_by_id.py +++ b/tests/tree/test_tree_get_node_by_id.py @@ -12,5 +12,5 @@ def test_get_tree_node_by_id() -> None: assert tree.get_node_by_id(tree.root.id).id == tree.root.id assert tree.get_node_by_id(child.id).id == child.id assert tree.get_node_by_id(grandchild.id).id == grandchild.id - with pytest.raises(KeyError): + with pytest.raises(Tree.UnknownID): tree.get_node_by_id(cast(NodeID, grandchild.id + 1000)) From 19d27aa7a68a26b5467dbbe18c24daa0299a4255 Mon Sep 17 00:00:00 2001 From: Nitzan Shaked Date: Fri, 6 Jan 2023 09:22:24 +0200 Subject: [PATCH 264/310] proposal for fixing #1453 along the way: make Tree._refresh_node somewhat more efficient by: * stopping early * coallescing multiple refresh() calls of single lines into one call change "TreeControl" to "Tree" in a few texts (and funny enough, in demo.css, which doesn't even use it); remove the (appearantly dead) Tree._refresh_node_line --- src/textual/demo.css | 52 ++++++++++++++++++------------------ src/textual/demo.py | 2 +- src/textual/widget.py | 2 +- src/textual/widgets/_tree.py | 40 ++++++++++++++++++--------- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/src/textual/demo.css b/src/textual/demo.css index 521346545..c93224e9f 100644 --- a/src/textual/demo.css +++ b/src/textual/demo.css @@ -4,7 +4,7 @@ Screen { layers: base overlay notes notifications; - overflow: hidden; + overflow: hidden; } @@ -17,15 +17,15 @@ Notification { background: $background; color: $text; height: auto; - + } -Sidebar { +Sidebar { width: 40; - background: $panel; - transition: offset 500ms in_out_cubic; + background: $panel; + transition: offset 500ms in_out_cubic; layer: overlay; - + } Sidebar:focus-within { @@ -58,8 +58,8 @@ Option { margin: 1 0 0 1; height: 3; padding: 1 2; - background: $boost; - border: tall $panel; + background: $boost; + border: tall $panel; text-align: center; } @@ -72,11 +72,11 @@ Body { height: 100%; overflow-y: scroll; width: 100%; - background: $surface; + background: $surface; } -AboveFold { +AboveFold { width: 100%; height: 100%; align: center middle; @@ -84,11 +84,11 @@ AboveFold { Welcome { background: $boost; - height: auto; + height: auto; max-width: 100; min-width: 40; border: wide $primary; - padding: 1 2; + padding: 1 2; margin: 1 2; box-sizing: border-box; } @@ -101,11 +101,11 @@ Welcome Button { Column { height: auto; min-height: 100vh; - align: center top; + align: center top; } -DarkSwitch { +DarkSwitch { background: $panel; padding: 1; dock: bottom; @@ -138,8 +138,8 @@ TextLog { layer: notes; border-top: hkey $primary; offset-y: 0; - transition: offset 400ms in_out_cubic; - padding: 0 1 1 1; + transition: offset 400ms in_out_cubic; + padding: 0 1 1 1; } @@ -148,15 +148,15 @@ TextLog:focus { } TextLog.-hidden { - offset-y: 100%; + offset-y: 100%; } -Section { +Section { height: auto; - min-width: 40; - margin: 1 2 4 2; + min-width: 40; + margin: 1 2 4 2; } @@ -167,7 +167,7 @@ SectionTitle { text-style: bold; } -SubTitle { +SubTitle { padding-top: 1; border-bottom: heavy $panel; color: $text; @@ -181,7 +181,7 @@ TextContent { QuickAccess { width: 30; dock: left; - + } LocationLink { @@ -189,7 +189,7 @@ LocationLink { height: 1; padding: 1 2; background: $boost; - color: $text; + color: $text; box-sizing: content-box; content-align: center middle; } @@ -219,7 +219,7 @@ LoginForm { grid-rows: 4; grid-columns: 12 1fr; background: $boost; - border: wide $background; + border: wide $background; } LoginForm Button{ @@ -234,11 +234,11 @@ LoginForm .label { Message { margin: 0 1; - + } -TreeControl { +Tree { margin: 1 0; } diff --git a/src/textual/demo.py b/src/textual/demo.py index 7d6ec498b..c9b15d628 100644 --- a/src/textual/demo.py +++ b/src/textual/demo.py @@ -140,7 +140,7 @@ Build your own or use the builtin widgets. - **Button** Clickable button with a number of styles. - **Checkbox** A checkbox to toggle between states. - **DataTable** A spreadsheet-like widget for navigating data. Cells may contain text or Rich renderables. -- **TreeControl** An generic tree with expandable nodes. +- **Tree** An generic tree with expandable nodes. - **DirectoryTree** A tree of file and folders. - *... many more planned ...* diff --git a/src/textual/widget.py b/src/textual/widget.py index 8c3f7951d..7808f1a08 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -680,7 +680,7 @@ class Widget(DOMNode): def compose(self) -> ComposeResult: yield Header() yield Container( - TreeControl(), Viewer() + Tree(), Viewer() ) yield Footer() ``` diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index a41928941..fea694616 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -595,7 +595,10 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): Args: line (int): A line number. """ - self.scroll_to_region(Region(0, line, self.size.width, 1)) + tree_line = self._tree_lines[line] + region_x = tree_line._get_guide_width(self.guide_depth, self.show_root) + region_width = self.get_label_width(tree_line.node) + self.scroll_to_region(Region(region_x, line, region_width, 1)) def scroll_to_node(self, node: TreeNode[TreeDataType]) -> None: """Scroll to the given node. @@ -616,23 +619,36 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): region = Region(0, line - self.scroll_offset.y, self.size.width, 1) self.refresh(region) - def _refresh_node_line(self, line: int) -> None: - node = self._get_node(line) - if node is not None: - self._refresh_node(node) - def _refresh_node(self, node: TreeNode[TreeDataType]) -> None: """Refresh a node and all its children. Args: node (TreeNode[TreeDataType]): A tree node. """ - scroll_y = self.scroll_offset.y - height = self.size.height - visible_lines = self._tree_lines[scroll_y : scroll_y + height] - for line_no, line in enumerate(visible_lines, scroll_y): - if node in line.path: - self.refresh_line(line_no) + view_y1 = self.scroll_offset.y + view_y2 = min(view_y1 + self.size.height, len(self._tree_lines)) + + refresh_region_y = max(node.line, view_y1) + if refresh_region_y >= view_y2: + return + + refresh_region_height = 0 + for y in range(refresh_region_y, view_y2): + if node in self._tree_lines[y].path: + refresh_region_height += 1 + else: + break + + if refresh_region_height == 0: + return + + region = Region( + 0, + refresh_region_y - self.scroll_offset.y, + self.size.width, + refresh_region_height, + ) + self.refresh(region) @property def _tree_lines(self) -> list[_TreeLine]: From d938ab9c5cd1d655e0a06201278734517699572f Mon Sep 17 00:00:00 2001 From: Nitzan Shaked Date: Tue, 10 Jan 2023 17:15:12 +0200 Subject: [PATCH 265/310] fix PR comments --- src/textual/widgets/_tree.py | 51 ++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index fea694616..09b4a3b42 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -556,6 +556,15 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): else: return tree_line.node + def _get_label_region(self, line: int) -> Region | None: + try: + tree_line = self._tree_lines[line] + except IndexError: + return None + region_x = tree_line._get_guide_width(self.guide_depth, self.show_root) + region_width = self.get_label_width(tree_line.node) + return Region(region_x, line, region_width, 1) + def watch_hover_line(self, previous_hover_line: int, hover_line: int) -> None: previous_node = self._get_node(previous_hover_line) if previous_node is not None: @@ -595,10 +604,9 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): Args: line (int): A line number. """ - tree_line = self._tree_lines[line] - region_x = tree_line._get_guide_width(self.guide_depth, self.show_root) - region_width = self.get_label_width(tree_line.node) - self.scroll_to_region(Region(region_x, line, region_width, 1)) + region = self._get_label_region(line) + if region is not None: + self.scroll_to_region(region) def scroll_to_node(self, node: TreeNode[TreeDataType]) -> None: """Scroll to the given node. @@ -619,36 +627,23 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): region = Region(0, line - self.scroll_offset.y, self.size.width, 1) self.refresh(region) + def _refresh_node_line(self, line: int) -> None: + node = self._get_node(line) + if node is not None: + self._refresh_node(node) + def _refresh_node(self, node: TreeNode[TreeDataType]) -> None: """Refresh a node and all its children. Args: node (TreeNode[TreeDataType]): A tree node. """ - view_y1 = self.scroll_offset.y - view_y2 = min(view_y1 + self.size.height, len(self._tree_lines)) - - refresh_region_y = max(node.line, view_y1) - if refresh_region_y >= view_y2: - return - - refresh_region_height = 0 - for y in range(refresh_region_y, view_y2): - if node in self._tree_lines[y].path: - refresh_region_height += 1 - else: - break - - if refresh_region_height == 0: - return - - region = Region( - 0, - refresh_region_y - self.scroll_offset.y, - self.size.width, - refresh_region_height, - ) - self.refresh(region) + scroll_y = self.scroll_offset.y + height = self.size.height + visible_lines = self._tree_lines[scroll_y : scroll_y + height] + for line_no, line in enumerate(visible_lines, scroll_y): + if node in line.path: + self.refresh_line(line_no) @property def _tree_lines(self) -> list[_TreeLine]: From 1430b6bf33769dfd57949f2ad556da87e2818240 Mon Sep 17 00:00:00 2001 From: Nitzan Shaked Date: Sat, 31 Dec 2022 20:53:57 +0200 Subject: [PATCH 266/310] POC for pluggable scrollbar renderers --- src/textual/demo.css | 50 ++++----- src/textual/demo_thin_scrollbar.py | 157 +++++++++++++++++++++++++++++ src/textual/scrollbar.py | 5 +- 3 files changed, 186 insertions(+), 26 deletions(-) create mode 100644 src/textual/demo_thin_scrollbar.py diff --git a/src/textual/demo.css b/src/textual/demo.css index 521346545..a18b0f7a0 100644 --- a/src/textual/demo.css +++ b/src/textual/demo.css @@ -4,7 +4,7 @@ Screen { layers: base overlay notes notifications; - overflow: hidden; + overflow: hidden; } @@ -17,15 +17,15 @@ Notification { background: $background; color: $text; height: auto; - + } -Sidebar { +Sidebar { width: 40; - background: $panel; - transition: offset 500ms in_out_cubic; + background: $panel; + transition: offset 500ms in_out_cubic; layer: overlay; - + } Sidebar:focus-within { @@ -58,8 +58,8 @@ Option { margin: 1 0 0 1; height: 3; padding: 1 2; - background: $boost; - border: tall $panel; + background: $boost; + border: tall $panel; text-align: center; } @@ -72,11 +72,11 @@ Body { height: 100%; overflow-y: scroll; width: 100%; - background: $surface; + background: $surface; } -AboveFold { +AboveFold { width: 100%; height: 100%; align: center middle; @@ -84,11 +84,11 @@ AboveFold { Welcome { background: $boost; - height: auto; + height: auto; max-width: 100; min-width: 40; border: wide $primary; - padding: 1 2; + padding: 1 2; margin: 1 2; box-sizing: border-box; } @@ -101,11 +101,11 @@ Welcome Button { Column { height: auto; min-height: 100vh; - align: center top; + align: center top; } -DarkSwitch { +DarkSwitch { background: $panel; padding: 1; dock: bottom; @@ -138,8 +138,8 @@ TextLog { layer: notes; border-top: hkey $primary; offset-y: 0; - transition: offset 400ms in_out_cubic; - padding: 0 1 1 1; + transition: offset 400ms in_out_cubic; + padding: 0 1 1 1; } @@ -148,15 +148,15 @@ TextLog:focus { } TextLog.-hidden { - offset-y: 100%; + offset-y: 100%; } -Section { +Section { height: auto; - min-width: 40; - margin: 1 2 4 2; + min-width: 40; + margin: 1 2 4 2; } @@ -167,7 +167,7 @@ SectionTitle { text-style: bold; } -SubTitle { +SubTitle { padding-top: 1; border-bottom: heavy $panel; color: $text; @@ -181,7 +181,7 @@ TextContent { QuickAccess { width: 30; dock: left; - + } LocationLink { @@ -189,7 +189,7 @@ LocationLink { height: 1; padding: 1 2; background: $boost; - color: $text; + color: $text; box-sizing: content-box; content-align: center middle; } @@ -219,7 +219,7 @@ LoginForm { grid-rows: 4; grid-columns: 12 1fr; background: $boost; - border: wide $background; + border: wide $background; } LoginForm Button{ @@ -234,7 +234,7 @@ LoginForm .label { Message { margin: 0 1; - + } diff --git a/src/textual/demo_thin_scrollbar.py b/src/textual/demo_thin_scrollbar.py new file mode 100644 index 000000000..1a84a5079 --- /dev/null +++ b/src/textual/demo_thin_scrollbar.py @@ -0,0 +1,157 @@ +from __future__ import annotations + +from math import ceil + +from rich.color import Color +from rich.segment import Segment, Segments +from rich.style import Style + +from textual.app import App, ComposeResult +from textual.scrollbar import ScrollBar, ScrollBarRender +from textual.containers import Vertical +from textual.widgets import Footer, Header, Static + + +class ThinScrollBarRender(ScrollBarRender): + @classmethod + def render_bar( + cls, + size: int = 25, + virtual_size: float = 50, + window_size: float = 20, + position: float = 0, + thickness: int = 1, + vertical: bool = True, + back_color: Color = Color.parse("#555555"), + bar_color: Color = Color.parse("bright_magenta"), + ) -> Segments: + if vertical or thickness > 1: + return super().render_bar( + size=size, + virtual_size=virtual_size, + window_size=window_size, + position=position, + thickness=thickness, + vertical=vertical, + back_color=back_color, + bar_color=bar_color, + ) + + assert not vertical + assert thickness == 1 + + _Style = Style + _Segment = Segment + + norm_style = _Style(bgcolor=back_color, color=bar_color) + + bars_start = ["▝", " "] + bars_start_style = norm_style + bars_end = ["▘", " "] + bars_end_style = norm_style + blank = " " + blank_style = norm_style + full = "▀" + full_style = norm_style + + assert len(bars_end) == len(bars_start) + + len_bars = len(bars_start) + + upper_meta = {"@mouse.up": "scroll_up"} + middle_meta = {"@mouse.up": "release", "@mouse.down": "grab"} + lower_meta = {"@mouse.up": "scroll_down"} + + upper_back_style = blank_style + _Style.from_meta(upper_meta) + middle_fg_style = full_style + _Style.from_meta(middle_meta) + lower_back_style = blank_style + _Style.from_meta(lower_meta) + + upper_back_segment = _Segment(blank, upper_back_style) + middle_fg_segment = _Segment(full, middle_fg_style) + lower_back_segment = _Segment(blank, lower_back_style) + + if window_size and size and virtual_size and size != virtual_size: + step_size = virtual_size / size + + start = int(position / step_size * len_bars) + end = start + max(len_bars, int(ceil(window_size / step_size * len_bars))) + + start_index, start_bar = divmod(max(0, start), len_bars) + end_index, end_bar = divmod(max(0, end), len_bars) + + segments = ( + [lower_back_segment] * (start_index) + + [middle_fg_segment] * (end_index - start_index) + + [upper_back_segment] * (size - end_index) + ) + + # Apply the smaller bar characters to head and tail of scrollbar for more "granularity" + if start_index < len(segments): + start_bar_character = bars_start[len_bars - 1 - start_bar] + if start_bar_character != " ": + segments[start_index] = _Segment( + start_bar_character, + bars_start_style + _Style.from_meta(middle_meta), + ) + if end_index < len(segments): + end_bar_character = bars_end[len_bars - 1 - end_bar] + if end_bar_character != " ": + segments[end_index] = _Segment( + end_bar_character, + bars_end_style + _Style.from_meta(middle_meta), + ) + else: + segments = [_Segment(blank, blank_style)] * int(size) + + return Segments((segments + [_Segment.line()]), new_lines=False) + + +class MyTextBox(Vertical): + DEFAULT_CSS = """ + MyTextBox { + background: $panel; + width: 20; + height: 10; + overflow: scroll; + } + MyTextBox > Static { + width: auto; + } + """ + + def compose(self) -> ComposeResult: + yield Static( + "\n".join( + f"{i:2} a somewhat long line that exceeds width {i:2}" + for i in range(1, 21) + ) + ) + + +class ThinScrollBarDemoApp(App[None]): + TITLE = "Thin ScrollBar Demo" + DEFAULT_CSS = """ + MyTextBox { margin: 1 1 1 1; } + """ + + def compose(self) -> ComposeResult: + yield Header() + yield Vertical( + MyTextBox(id="box1"), + MyTextBox(id="box2"), + MyTextBox(id="box3"), + ) + yield Footer() + + def on_mount(self) -> None: + # ... and because ScrollBar uses `self.renderer` rather than + # `type(self).renderer` (that's intentional), we can even do this: + self.query_one( + "#box2", MyTextBox + ).horizontal_scrollbar.renderer = ScrollBarRender + + +app = ThinScrollBarDemoApp() +ScrollBar.renderer = ThinScrollBarRender +if __name__ == "__main__": + app.run() diff --git a/src/textual/scrollbar.py b/src/textual/scrollbar.py index f9db9c71b..8c846d07b 100644 --- a/src/textual/scrollbar.py +++ b/src/textual/scrollbar.py @@ -1,6 +1,7 @@ from __future__ import annotations from math import ceil +from typing import ClassVar, Type import rich.repr from rich.color import Color @@ -190,6 +191,8 @@ class ScrollBarRender: @rich.repr.auto class ScrollBar(Widget): + renderer: ClassVar[Type[ScrollBarRender]] = ScrollBarRender + DEFAULT_CSS = """ ScrollBar { link-hover-color: ; @@ -236,7 +239,7 @@ class ScrollBar(Widget): color = styles.scrollbar_color color = background + color scrollbar_style = Style.from_color(color.rich_color, background.rich_color) - return ScrollBarRender( + return self.renderer( virtual_size=self.window_virtual_size, window_size=( self.window_size if self.window_size < self.window_virtual_size else 0 From 494c63a72bca44e7683c5d19e24202edfd03a0dd Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 10 Jan 2023 15:28:17 +0000 Subject: [PATCH 267/310] Tweak the unknown node ID exception See https://github.com/Textualize/textual/pull/1535#discussion_r1065904713 and https://github.com/Textualize/textual/pull/1535#discussion_r1065909144 --- src/textual/widgets/_tree.py | 4 ++-- tests/tree/test_tree_get_node_by_id.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index 0f1d99af7..b6f844383 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -513,7 +513,7 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): else: return line.node - class UnknownID(Exception): + class UnknownNodeID(Exception): """Exception raised when referring to an unknown `TreeNode` ID.""" def get_node_by_id(self, node_id: NodeID) -> TreeNode[TreeDataType]: @@ -531,7 +531,7 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): try: return self._nodes[node_id] except KeyError: - raise self.UnknownID(f"Unknown TreeNode ID: {node_id}") from None + raise self.UnknownNodeID(f"Unknown NodeID ({node_id}) in tree") from None def validate_cursor_line(self, value: int) -> int: """Prevent cursor line from going outside of range.""" diff --git a/tests/tree/test_tree_get_node_by_id.py b/tests/tree/test_tree_get_node_by_id.py index d9eca97af..ffee36996 100644 --- a/tests/tree/test_tree_get_node_by_id.py +++ b/tests/tree/test_tree_get_node_by_id.py @@ -12,5 +12,5 @@ def test_get_tree_node_by_id() -> None: assert tree.get_node_by_id(tree.root.id).id == tree.root.id assert tree.get_node_by_id(child.id).id == child.id assert tree.get_node_by_id(grandchild.id).id == grandchild.id - with pytest.raises(Tree.UnknownID): + with pytest.raises(Tree.UnknownNodeID): tree.get_node_by_id(cast(NodeID, grandchild.id + 1000)) From b09511b6e6b4d83d077ace2d3e8d6955bb69ac25 Mon Sep 17 00:00:00 2001 From: Nitzan Shaked Date: Tue, 10 Jan 2023 17:32:38 +0200 Subject: [PATCH 268/310] Fix PR comments --- src/textual/demo_thin_scrollbar.py | 157 ----------------------------- src/textual/scrollbar.py | 21 ++++ 2 files changed, 21 insertions(+), 157 deletions(-) delete mode 100644 src/textual/demo_thin_scrollbar.py diff --git a/src/textual/demo_thin_scrollbar.py b/src/textual/demo_thin_scrollbar.py deleted file mode 100644 index 1a84a5079..000000000 --- a/src/textual/demo_thin_scrollbar.py +++ /dev/null @@ -1,157 +0,0 @@ -from __future__ import annotations - -from math import ceil - -from rich.color import Color -from rich.segment import Segment, Segments -from rich.style import Style - -from textual.app import App, ComposeResult -from textual.scrollbar import ScrollBar, ScrollBarRender -from textual.containers import Vertical -from textual.widgets import Footer, Header, Static - - -class ThinScrollBarRender(ScrollBarRender): - @classmethod - def render_bar( - cls, - size: int = 25, - virtual_size: float = 50, - window_size: float = 20, - position: float = 0, - thickness: int = 1, - vertical: bool = True, - back_color: Color = Color.parse("#555555"), - bar_color: Color = Color.parse("bright_magenta"), - ) -> Segments: - if vertical or thickness > 1: - return super().render_bar( - size=size, - virtual_size=virtual_size, - window_size=window_size, - position=position, - thickness=thickness, - vertical=vertical, - back_color=back_color, - bar_color=bar_color, - ) - - assert not vertical - assert thickness == 1 - - _Style = Style - _Segment = Segment - - norm_style = _Style(bgcolor=back_color, color=bar_color) - - bars_start = ["▝", " "] - bars_start_style = norm_style - bars_end = ["▘", " "] - bars_end_style = norm_style - blank = " " - blank_style = norm_style - full = "▀" - full_style = norm_style - - assert len(bars_end) == len(bars_start) - - len_bars = len(bars_start) - - upper_meta = {"@mouse.up": "scroll_up"} - middle_meta = {"@mouse.up": "release", "@mouse.down": "grab"} - lower_meta = {"@mouse.up": "scroll_down"} - - upper_back_style = blank_style + _Style.from_meta(upper_meta) - middle_fg_style = full_style + _Style.from_meta(middle_meta) - lower_back_style = blank_style + _Style.from_meta(lower_meta) - - upper_back_segment = _Segment(blank, upper_back_style) - middle_fg_segment = _Segment(full, middle_fg_style) - lower_back_segment = _Segment(blank, lower_back_style) - - if window_size and size and virtual_size and size != virtual_size: - step_size = virtual_size / size - - start = int(position / step_size * len_bars) - end = start + max(len_bars, int(ceil(window_size / step_size * len_bars))) - - start_index, start_bar = divmod(max(0, start), len_bars) - end_index, end_bar = divmod(max(0, end), len_bars) - - segments = ( - [lower_back_segment] * (start_index) - + [middle_fg_segment] * (end_index - start_index) - + [upper_back_segment] * (size - end_index) - ) - - # Apply the smaller bar characters to head and tail of scrollbar for more "granularity" - if start_index < len(segments): - start_bar_character = bars_start[len_bars - 1 - start_bar] - if start_bar_character != " ": - segments[start_index] = _Segment( - start_bar_character, - bars_start_style + _Style.from_meta(middle_meta), - ) - if end_index < len(segments): - end_bar_character = bars_end[len_bars - 1 - end_bar] - if end_bar_character != " ": - segments[end_index] = _Segment( - end_bar_character, - bars_end_style + _Style.from_meta(middle_meta), - ) - else: - segments = [_Segment(blank, blank_style)] * int(size) - - return Segments((segments + [_Segment.line()]), new_lines=False) - - -class MyTextBox(Vertical): - DEFAULT_CSS = """ - MyTextBox { - background: $panel; - width: 20; - height: 10; - overflow: scroll; - } - MyTextBox > Static { - width: auto; - } - """ - - def compose(self) -> ComposeResult: - yield Static( - "\n".join( - f"{i:2} a somewhat long line that exceeds width {i:2}" - for i in range(1, 21) - ) - ) - - -class ThinScrollBarDemoApp(App[None]): - TITLE = "Thin ScrollBar Demo" - DEFAULT_CSS = """ - MyTextBox { margin: 1 1 1 1; } - """ - - def compose(self) -> ComposeResult: - yield Header() - yield Vertical( - MyTextBox(id="box1"), - MyTextBox(id="box2"), - MyTextBox(id="box3"), - ) - yield Footer() - - def on_mount(self) -> None: - # ... and because ScrollBar uses `self.renderer` rather than - # `type(self).renderer` (that's intentional), we can even do this: - self.query_one( - "#box2", MyTextBox - ).horizontal_scrollbar.renderer = ScrollBarRender - - -app = ThinScrollBarDemoApp() -ScrollBar.renderer = ThinScrollBarRender -if __name__ == "__main__": - app.run() diff --git a/src/textual/scrollbar.py b/src/textual/scrollbar.py index 8c846d07b..ec3cd4790 100644 --- a/src/textual/scrollbar.py +++ b/src/textual/scrollbar.py @@ -192,6 +192,27 @@ class ScrollBarRender: class ScrollBar(Widget): renderer: ClassVar[Type[ScrollBarRender]] = ScrollBarRender + """The class used for rendering scrollbars. + This can be overriden and set to a ScrollBarRender-derived class + in order to delegate all scrollbar rendering to that class. E.g.: + + ``` + class MyScrollBarRender(ScrollBarRender): ... + + app = MyApp() + ScrollBar.renderer = MyScrollBarRender + app.run() + ``` + + Because this variable is accessed through specific instances + (rather than through the class ScrollBar itself) it is also possible + to set this on specific scrollbar instance to change only that + instance: + + ``` + my_widget.horizontal_scrollbar.renderer = MyScrollBarRender + ``` + """ DEFAULT_CSS = """ ScrollBar { From cb9a67cf053a1c8f1c90659b9ec3a978d4b3c2ab Mon Sep 17 00:00:00 2001 From: Nitzan Shaked Date: Tue, 10 Jan 2023 17:56:28 +0200 Subject: [PATCH 269/310] added docstring to _get_label_region --- src/textual/widgets/_tree.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/textual/widgets/_tree.py b/src/textual/widgets/_tree.py index 09b4a3b42..96f1f5d5b 100644 --- a/src/textual/widgets/_tree.py +++ b/src/textual/widgets/_tree.py @@ -557,6 +557,18 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True): return tree_line.node def _get_label_region(self, line: int) -> Region | None: + """Returns the region occupied by the label of the node at line `line`. + + This can be used, e.g., when scrolling to that line such that the label + is visible after the scroll. + + Args: + line (int): A line number. + + Returns: + Region | None: the region occupied by the label, or `None` if the + line is not in the tree. + """ try: tree_line = self._tree_lines[line] except IndexError: From 43915b941552e1560799d8bca559a5c8d44ac673 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 10 Jan 2023 16:07:33 +0000 Subject: [PATCH 270/310] update to introduction --- docs/index.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/index.md b/docs/index.md index 2be8c2514..c290c6cf8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,7 +3,12 @@ Welcome to the [Textual](https://github.com/Textualize/textual) framework documentation. Built with ❤️ by [Textualize.io](https://www.textualize.io) -
+ +## In a hurry? + +[Get started](./getting_started.md){ .md-button .md-button--primary } or jump straight to [Tutorial](./tutorial.md){ .md-button .md-button--primary } + +## What is Textual? Textual is a framework for building applications that run within your terminal. Text User Interfaces (TUIs) have a number of advantages over web and desktop apps. @@ -22,7 +27,7 @@ Textual is a framework for building applications that run within your terminal. Low system requirements. Run Textual on a single board computer if you want to. - + - :material-microsoft-windows:{ .lg .middle } :material-apple:{ .lg .middle } :fontawesome-brands-linux:{ .lg .middle } __Cross platform__ @@ -30,7 +35,7 @@ Textual is a framework for building applications that run within your terminal. Textual runs just about everywhere. - + - :material-network:{ .lg .middle } __Remote__ @@ -52,13 +57,11 @@ Textual is a framework for building applications that run within your terminal. --- Textual is licensed under MIT. - +
-
- ```{.textual path="examples/calculator.py" columns=100 lines=41 press="3,.,1,4,5,9,2,_,_,_,_,_,_,_,_"} ``` @@ -79,5 +82,3 @@ Textual is a framework for building applications that run within your terminal. ```{.textual path="docs/examples/app/widgets01.py"} ``` - - From e4cef274b18d5e9661f41912c878629b10ae49a1 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 10 Jan 2023 17:59:58 +0000 Subject: [PATCH 271/310] tweak --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index c290c6cf8..072662a5e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,7 +6,7 @@ Welcome to the [Textual](https://github.com/Textualize/textual) framework docume ## In a hurry? -[Get started](./getting_started.md){ .md-button .md-button--primary } or jump straight to [Tutorial](./tutorial.md){ .md-button .md-button--primary } +[Get started](./getting_started.md){ .md-button .md-button--primary } or [Tutorial](./tutorial.md){ .md-button .md-button--secondary } ## What is Textual? From 1c4fe0c4fb49ad528af860070152deaf7bd97966 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 10 Jan 2023 18:18:49 +0000 Subject: [PATCH 272/310] added text re navigation --- docs/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/index.md b/docs/index.md index 072662a5e..584f60f93 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,6 +6,8 @@ Welcome to the [Textual](https://github.com/Textualize/textual) framework docume ## In a hurry? +See the navigation links in the header or side-bars. Click the :octicons-three-bars-16: button (top left) on mobile. + [Get started](./getting_started.md){ .md-button .md-button--primary } or [Tutorial](./tutorial.md){ .md-button .md-button--secondary } ## What is Textual? From 8cb98631d4ca4fad001ca143e5019cd0df25b6b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 11:59:49 +0000 Subject: [PATCH 273/310] Fix doc issue. --- src/textual/widgets/_placeholder.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/textual/widgets/_placeholder.py b/src/textual/widgets/_placeholder.py index 137a0fd1c..98a915ee8 100644 --- a/src/textual/widgets/_placeholder.py +++ b/src/textual/widgets/_placeholder.py @@ -46,9 +46,12 @@ class Placeholder(Widget): can also be initialised in a specific variant. The variants available are: - default: shows an identifier label or the ID of the placeholder. - size: shows the size of the placeholder. - text: shows some Lorem Ipsum text on the placeholder. + + | Variant | Placeholder shows | + |---------|------------------------------------------------| + | default | Identifier label or the ID of the placeholder. | + | size | Size of the placeholder. | + | text | Lorem Ipsum text. | """ DEFAULT_CSS = """ From 81d3201b1da8f1e4eae84261d9d2245624a6b66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 12:30:58 +0000 Subject: [PATCH 274/310] Add switch to control component class inheritance. --- src/textual/dom.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/textual/dom.py b/src/textual/dom.py index 1204073a0..16f1c3686 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -98,6 +98,9 @@ class DOMNode(MessagePump): # True if this node inherits the CSS from the base class. _inherit_css: ClassVar[bool] = True + # True if this node inherits the component classes from the base class. + _inherit_component_classes: ClassVar[bool] = True + # True to inherit bindings from base class _inherit_bindings: ClassVar[bool] = True From be31341c5b5c93fbc979ae1590e3d8cde52a7223 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 11 Jan 2023 13:20:29 +0000 Subject: [PATCH 275/310] Add a textual diagnose CLI command This, in this early version anyway, emits a simple dump of GitHub-issue-friendly markdown text that lists all of the key information we may want to know when someone using having a problem with Textual. See #1542. --- CHANGELOG.md | 1 + src/textual/cli/cli.py | 8 ++ src/textual/cli/tools/__init__.py | 0 src/textual/cli/tools/diagnose.py | 121 ++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 src/textual/cli/tools/__init__.py create mode 100644 src/textual/cli/tools/diagnose.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cd10be6f..5a19bc726 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added read-only public access to the children of a `TreeNode` via `TreeNode.children` https://github.com/Textualize/textual/issues/1398 - Added `Tree.get_node_by_id` to allow getting a node by its ID https://github.com/Textualize/textual/pull/1535 - Added a `Tree.NodeHighlighted` message, giving a `on_tree_node_highlighted` event handler https://github.com/Textualize/textual/issues/1400 +- Added `diagnose` as a `texttual` command https://github.com/Textualize/textual/issues/1542 ### Changed diff --git a/src/textual/cli/cli.py b/src/textual/cli/cli.py index 9113338f1..6c99811d7 100644 --- a/src/textual/cli/cli.py +++ b/src/textual/cli/cli.py @@ -131,3 +131,11 @@ def keys(): from textual.cli.previews import keys keys.app.run() + + +@run.command("diagnose") +def run_diagnose(): + """Print information about the Textual environment""" + from textual.cli.tools.diagnose import diagnose + + diagnose() diff --git a/src/textual/cli/tools/__init__.py b/src/textual/cli/tools/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/textual/cli/tools/diagnose.py b/src/textual/cli/tools/diagnose.py new file mode 100644 index 000000000..2b5821c18 --- /dev/null +++ b/src/textual/cli/tools/diagnose.py @@ -0,0 +1,121 @@ +"""Textual CLI command code to print diagnostic information.""" + +import os +import sys +import platform +from importlib_metadata import version +from rich.console import Console + + +def _section(title: str, values: dict[str, str]) -> None: + """Print a collection of named values within a titled section. + + Args: + title (str): The title for the section. + values (dict[str, str]): The values to print out. + """ + max_name = len(max(list(values.keys()), key=len)) + max_value = len(max(list(values.values()), key=len)) + print(f"## {title}") + print() + print(f"| {'Name':{max_name}} | {'Value':{max_value}} |") + print(f"|-{'-' * max_name}-|-{'-'*max_value}-|") + for name, value in values.items(): + print(f"| {name:{max_name}} | {value:{max_value}} |") + print() + + +def _versions() -> None: + """Print useful version numbers.""" + _section("Versions", {"Textual": version("textual"), "Rich": version("rich")}) + + +def _python() -> None: + """Print information about Python.""" + _section( + "Python", + { + "Version": platform.python_version(), + "Implementation": platform.python_implementation(), + "Compiler": platform.python_compiler(), + "Executable": sys.executable, + }, + ) + + +def _os() -> None: + _section( + "Operating System", + { + "System": platform.system(), + "Release": platform.release(), + "Version": platform.version(), + }, + ) + + +def _guess_term() -> str: + """Try and guess which terminal is being used.""" + + # First obvious place to look is in $TERM_PROGRAM. + term_program = os.environ.get("TERM_PROGRAM") + + if term_program is None: + # Seems we couldn't get it that way. Let's check for some of the + # more common terminal signatures. + if "ALACRITTY_WINDOW_ID" in os.environ: + term_program = "Alacritty" + elif "KITTY_PID" in os.environ: + term_program = "Kitty" + elif "WT_SESSION" in os.environ: + term_program = "Windows Terminal" + elif "INSIDE_EMACS" in os.environ and os.environ["INSIDE_EMACS"].endswith( + "eshell" + ): + term_program = "GNU Emacs (eshell)" + elif "JEDITERM_SOURCE_ARGS" in os.environ: + term_program = "PyCharm" + + else: + # See if we can pull out some sort of version information too. + term_version = os.environ.get("TERM_PROGRAM_VERSION") + if term_version is not None: + term_program = f"{term_program} ({term_version})" + + return "*Unknown*" if term_program is None else term_program + + +def _term() -> None: + """Print information about the terminal.""" + _section( + "Terminal", + { + "Terminal Application": _guess_term(), + "TERM": os.environ.get("TERM", "*Not set*"), + "COLORTERM": os.environ.get("COLORTERM", "*Not set*"), + "FORCE_COLOR": os.environ.get("FORCE_COLOR", "*Not set*"), + "NO_COLOR": os.environ.get("NO_COLOR", "*Not set*"), + }, + ) + + +def _console() -> None: + """Print The Rich console options.""" + _section( + "Rich Console options", + {k: str(v) for k, v in Console().options.__dict__.items()}, + ) + + +def diagnose() -> None: + """Print information about Textual and its environment to help diagnose problems.""" + print("# Textual Diagnostics") + print() + _versions() + _python() + _os() + _term() + _console() + # TODO: Recommended changes. Given all of the above, make any useful + # recommendations to the user (eg: don't use Windows console, use + # Windows Terminal; don't use macOS Terminal.app, etc). From 966bca3669a3a0c57159e8b885f3f236ed2e3822 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 11 Jan 2023 13:49:42 +0000 Subject: [PATCH 276/310] Pick up anything INSIDE_EMACS This should, from what I can see, pick up being run inside any Emacs-based shell/term. --- src/textual/cli/tools/diagnose.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/textual/cli/tools/diagnose.py b/src/textual/cli/tools/diagnose.py index 2b5821c18..acdd21b35 100644 --- a/src/textual/cli/tools/diagnose.py +++ b/src/textual/cli/tools/diagnose.py @@ -69,10 +69,10 @@ def _guess_term() -> str: term_program = "Kitty" elif "WT_SESSION" in os.environ: term_program = "Windows Terminal" - elif "INSIDE_EMACS" in os.environ and os.environ["INSIDE_EMACS"].endswith( - "eshell" - ): - term_program = "GNU Emacs (eshell)" + elif "INSIDE_EMACS" in os.environ and os.environ["INSIDE_EMACS"]: + term_program = ( + f"GNU Emacs {' '.join(os.environ['INSIDE_EMACS'].split(','))}" + ) elif "JEDITERM_SOURCE_ARGS" in os.environ: term_program = "PyCharm" From 7f6cfdf6f1d89d638ab301a31ef7d48597b12015 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 11 Jan 2023 14:41:57 +0000 Subject: [PATCH 277/310] DRY getting an environment variable representation --- src/textual/cli/tools/diagnose.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/textual/cli/tools/diagnose.py b/src/textual/cli/tools/diagnose.py index acdd21b35..5d39d36b5 100644 --- a/src/textual/cli/tools/diagnose.py +++ b/src/textual/cli/tools/diagnose.py @@ -85,16 +85,28 @@ def _guess_term() -> str: return "*Unknown*" if term_program is None else term_program +def _env(var_name: str) -> str: + """Get a representation of an environment variable. + + Args: + var_name (str): The name of the variable to get. + + Returns: + str: The value, or an indication that it isn't set. + """ + return os.environ.get(var_name, "*Not set*") + + def _term() -> None: """Print information about the terminal.""" _section( "Terminal", { "Terminal Application": _guess_term(), - "TERM": os.environ.get("TERM", "*Not set*"), - "COLORTERM": os.environ.get("COLORTERM", "*Not set*"), - "FORCE_COLOR": os.environ.get("FORCE_COLOR", "*Not set*"), - "NO_COLOR": os.environ.get("NO_COLOR", "*Not set*"), + "TERM": _env("TERM"), + "COLORTERM": _env("COLORTERM"), + "FORCE_COLOR": _env("FORCE_COLOR"), + "NO_COLOR": _env("NO_COLOR"), }, ) From 4ba974e2b4b5cc576ffedc711aeef084076f4a2c Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 11 Jan 2023 15:06:37 +0000 Subject: [PATCH 278/310] Fix a CHANGELOG typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a19bc726..af9c30012 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added read-only public access to the children of a `TreeNode` via `TreeNode.children` https://github.com/Textualize/textual/issues/1398 - Added `Tree.get_node_by_id` to allow getting a node by its ID https://github.com/Textualize/textual/pull/1535 - Added a `Tree.NodeHighlighted` message, giving a `on_tree_node_highlighted` event handler https://github.com/Textualize/textual/issues/1400 -- Added `diagnose` as a `texttual` command https://github.com/Textualize/textual/issues/1542 +- Added `diagnose` as a `textual` command https://github.com/Textualize/textual/issues/1542 ### Changed From 05931c448d0a943e117c40512168028dee7c75c4 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 11 Jan 2023 15:08:22 +0000 Subject: [PATCH 279/310] Embrace the functional --- src/textual/cli/tools/diagnose.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/textual/cli/tools/diagnose.py b/src/textual/cli/tools/diagnose.py index 5d39d36b5..447d21f95 100644 --- a/src/textual/cli/tools/diagnose.py +++ b/src/textual/cli/tools/diagnose.py @@ -14,8 +14,8 @@ def _section(title: str, values: dict[str, str]) -> None: title (str): The title for the section. values (dict[str, str]): The values to print out. """ - max_name = len(max(list(values.keys()), key=len)) - max_value = len(max(list(values.values()), key=len)) + max_name = max(map(len, values.keys())) + max_value = max(map(len, values.values())) print(f"## {title}") print() print(f"| {'Name':{max_name}} | {'Value':{max_value}} |") From f5d8de419460188c01ded0315e1a5477a0361a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 15:09:14 +0000 Subject: [PATCH 280/310] Add test for COMPONENT_CLASSES inheritance. --- tests/test_dom.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/test_dom.py b/tests/test_dom.py index c1b5221c0..f9f5b50cf 100644 --- a/tests/test_dom.py +++ b/tests/test_dom.py @@ -115,6 +115,53 @@ def test_get_default_css(): assert e_css[1][1:] == ("C", -2) +def test_component_classes_inheritance(): + """Test if component classes are inherited properly.""" + + class A(DOMNode): + COMPONENT_CLASSES = {"a-1", "a-2"} + + class B(A): + COMPONENT_CLASSES = {"b-1"} + _inherit_component_classes = False + + class C(B): + COMPONENT_CLASSES = {"c-1", "c-2"} + + class D(C): + pass + + class E(D): + COMPONENT_CLASSES = {"e-1"} + + class F(E): + COMPONENT_CLASSES = {"f-1"} + _inherit_component_classes = False + + node = DOMNode() + node_cc = node.get_component_classes() + a = A() + a_cc = a.get_component_classes() + b = B() + b_cc = b.get_component_classes() + c = C() + c_cc = c.get_component_classes() + d = D() + d_cc = d.get_component_classes() + e = E() + e_cc = e.get_component_classes() + f = F() + f_cc = f.get_component_classes() + + assert node_cc == set() + assert a_cc == {"a-1", "a-2"} + assert b_cc == {"b-1"} + assert c_cc == {"b-1", "c-1", "c-2"} + assert d_cc == c_cc + assert e_cc == {"b-1", "c-1", "c-2", "e-1"} + assert f_cc == {"f-1"} + + @pytest.fixture def search(): """ From c4aac3e5ad36ba9fcece41701d912273c9f9228d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 15:12:32 +0000 Subject: [PATCH 281/310] Add mechanism to get inherited component classes. --- src/textual/dom.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/textual/dom.py b/src/textual/dom.py index 16f1c3686..d2dcf8863 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -282,6 +282,25 @@ class DOMNode(MessagePump): return css_stack + def get_component_classes(self) -> set[str]: + """Gets the component classes for this class and inherited from bases. + + Component classes are inherited from base classes, unless + `_inherit_component_classes` is set to `False`. + + Returns: + set[str]: a set with all the component classes available. + """ + + component_classes: set[str] = set() + for base in self._node_bases: + component_classes.update(base.__dict__.get("COMPONENT_CLASSES", set())) + if not base.__dict__.get("_inherit_component_classes", True): + break + + return component_classes + + @property def parent(self) -> DOMNode | None: """DOMNode | None: The parent node.""" From b4121acb457e0fed1a1b5322198d2493fdc6311c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 15:12:55 +0000 Subject: [PATCH 282/310] Enable component class inheritance. --- src/textual/css/stylesheet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/css/stylesheet.py b/src/textual/css/stylesheet.py index 56ea05dc0..176a420a2 100644 --- a/src/textual/css/stylesheet.py +++ b/src/textual/css/stylesheet.py @@ -407,7 +407,7 @@ class Stylesheet: self.replace_rules(node, node_rules, animate=animate) node._component_styles.clear() - for component in node.COMPONENT_CLASSES: + for component in node.get_component_classes(): virtual_node = DOMNode(classes=component) virtual_node._attach(node) self.apply(virtual_node, animate=False) From d7782a68783771b57882865e190420659415ea07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 15:15:17 +0000 Subject: [PATCH 283/310] Update changelog. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cd10be6f..69fa73822 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added read-only public access to the children of a `TreeNode` via `TreeNode.children` https://github.com/Textualize/textual/issues/1398 - Added `Tree.get_node_by_id` to allow getting a node by its ID https://github.com/Textualize/textual/pull/1535 - Added a `Tree.NodeHighlighted` message, giving a `on_tree_node_highlighted` event handler https://github.com/Textualize/textual/issues/1400 +- Added a `_inherit_component_classes` class variable to control whether or not component classes are inherited from base classes https://github.com/Textualize/textual/issues/1399 ### Changed @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fail-fast and print pretty tracebacks for Widget compose errors https://github.com/Textualize/textual/pull/1505 - Added Widget._refresh_scroll to avoid expensive layout when scrolling https://github.com/Textualize/textual/pull/1524 - `events.Paste` now bubbles https://github.com/Textualize/textual/issues/1434 +- `COMPONENT_CLASSES` are now inherited from base classes https://github.com/Textualize/textual/issues/1399 ### Fixed From 69c327b20dbf6f932d280accf35ea70da6b5be30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 15:40:02 +0000 Subject: [PATCH 284/310] Format. --- src/textual/dom.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/textual/dom.py b/src/textual/dom.py index d2dcf8863..ca2930468 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -300,7 +300,6 @@ class DOMNode(MessagePump): return component_classes - @property def parent(self) -> DOMNode | None: """DOMNode | None: The parent node.""" From d9666653458b9454665b3b2c8b02237e1193b78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 16:05:44 +0000 Subject: [PATCH 285/310] Address review comments. --- CHANGELOG.md | 2 +- src/textual/dom.py | 6 +++++- tests/test_dom.py | 12 ++++++++---- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d1c1209a..cc8e1df94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added read-only public access to the children of a `TreeNode` via `TreeNode.children` https://github.com/Textualize/textual/issues/1398 - Added `Tree.get_node_by_id` to allow getting a node by its ID https://github.com/Textualize/textual/pull/1535 - Added a `Tree.NodeHighlighted` message, giving a `on_tree_node_highlighted` event handler https://github.com/Textualize/textual/issues/1400 -- Added a `_inherit_component_classes` class variable to control whether or not component classes are inherited from base classes https://github.com/Textualize/textual/issues/1399 +- Added a `inherit_component_classes` subclassing parameter to control whether or not component classes are inherited from base classes https://github.com/Textualize/textual/issues/1399 - Added `diagnose` as a `textual` command https://github.com/Textualize/textual/issues/1542 ### Changed diff --git a/src/textual/dom.py b/src/textual/dom.py index ca2930468..43685c539 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -163,11 +163,15 @@ class DOMNode(MessagePump): self.refresh() def __init_subclass__( - cls, inherit_css: bool = True, inherit_bindings: bool = True + cls, + inherit_css: bool = True, + inherit_bindings: bool = True, + inherit_component_classes: bool = True, ) -> None: super().__init_subclass__() cls._inherit_css = inherit_css cls._inherit_bindings = inherit_bindings + cls._inherit_component_classes = inherit_component_classes css_type_names: set[str] = set() for base in cls._css_bases(cls): css_type_names.add(base.__name__) diff --git a/tests/test_dom.py b/tests/test_dom.py index f9f5b50cf..b8cca4737 100644 --- a/tests/test_dom.py +++ b/tests/test_dom.py @@ -47,6 +47,7 @@ def test_validate(): def test_inherited_bindings(): """Test if binding merging is done correctly when (not) inheriting bindings.""" + class A(DOMNode): BINDINGS = [("a", "a", "a")] @@ -81,14 +82,19 @@ def test_inherited_bindings(): def test_get_default_css(): class A(DOMNode): pass + class B(A): pass + class C(B): DEFAULT_CSS = "C" + class D(C): pass + class E(D): DEFAULT_CSS = "E" + node = DOMNode() node_css = node.get_default_css() a = A() @@ -121,9 +127,8 @@ def test_component_classes_inheritance(): class A(DOMNode): COMPONENT_CLASSES = {"a-1", "a-2"} - class B(A): + class B(A, inherit_component_classes=False): COMPONENT_CLASSES = {"b-1"} - _inherit_component_classes = False class C(B): COMPONENT_CLASSES = {"c-1", "c-2"} @@ -134,9 +139,8 @@ def test_component_classes_inheritance(): class E(D): COMPONENT_CLASSES = {"e-1"} - class F(E): + class F(E, inherit_component_classes=False): COMPONENT_CLASSES = {"f-1"} - _inherit_component_classes = False node = DOMNode() node_cc = node.get_component_classes() From 5035c29b87deda9cd7386df2b7da61cdce76e04f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 18:52:00 +0000 Subject: [PATCH 286/310] Add early return in view_position calculation. When an input is instantiated without an argument for the parameter 'value', the first time the watchers associated with its reactive attributes run, the attribute self.view_position is set to 1, which makes no sense because there isn't even any value in the input. Thus, when the value is later modified programmatically, e.g., because it is set with 'some_input_widget.value = some_value', the attribute self.view_position will still be 1 and the text will be rendered starting from the first character. As two example situations of this, consider #1477 and #1443. --- src/textual/widgets/_input.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/textual/widgets/_input.py b/src/textual/widgets/_input.py index c2bfa638a..ec68be8cd 100644 --- a/src/textual/widgets/_input.py +++ b/src/textual/widgets/_input.py @@ -148,6 +148,11 @@ class Input(Widget, can_focus=True): def watch_cursor_position(self, cursor_position: int) -> None: width = self.content_size.width + if width == 0: + # If the input has no width the view position can't be elsewhere. + self.view_position = 0 + return + view_start = self.view_position view_end = view_start + width cursor_offset = self._cursor_offset From 0bc10f0ec4380c5f42c1ab937b93e2287f5daf33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 19:15:10 +0000 Subject: [PATCH 287/310] Add regression tests. --- tests/test_input.py | 99 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 tests/test_input.py diff --git a/tests/test_input.py b/tests/test_input.py new file mode 100644 index 000000000..06f7c8b11 --- /dev/null +++ b/tests/test_input.py @@ -0,0 +1,99 @@ +from rich.console import Console +from textual.app import App +from textual.widgets import Input + + +async def test_input_value_visible_on_instantiation(): + """Check if the full input value is rendered if the input is instantiated with it.""" + + class MyApp(App): + def compose(self): + yield Input(value="value") + + app = MyApp() + async with app.run_test(): + console = Console(width=5) + with console.capture() as capture: + console.print(app.query_one(Input).render()) + assert capture.get() == "value" + + +async def test_input_value_visible_after_value_assignment(): + """Check if the full input value is rendered if the value is assigned to programmatically.""" + + class MyApp(App): + def compose(self): + yield Input() + + def on_mount(self): + self.query_one(Input).value = "value" + + app = MyApp() + async with app.run_test(): + console = Console(width=5) + with console.capture() as capture: + console.print(app.query_one(Input).render()) + assert capture.get() == "value" + + +async def test_input_value_visible_if_mounted_later(): + """Check if full input value is rendered if the widget is mounted later.""" + + class MyApp(App): + BINDINGS = [("a", "add_input", "add_input")] + + def action_add_input(self): + self.mount(Input(value="value")) + + app = MyApp() + async with app.run_test() as pilot: + await pilot.press("a") + console = Console(width=5) + with console.capture() as capture: + console.print(app.query_one(Input).render()) + assert capture.get() == "value" + + +async def test_input_value_visible_if_mounted_later_and_focused(): + """Check if full input value is rendered if the widget is mounted later and immediately focused.""" + + class MyApp(App): + BINDINGS = [("a", "add_input", "add_input")] + + def action_add_input(self): + inp = Input(value="value") + self.mount(inp) + inp.focus() + + app = MyApp() + async with app.run_test() as pilot: + await pilot.press("a") + console = Console(width=5) + with console.capture() as capture: + console.print(app.query_one(Input).render()) + assert capture.get() == "value" + + +async def test_input_value_visible_if_mounted_later_and_assigned_after(): + """Check if full value rendered if the widget is mounted later and the value is then assigned to.""" + + class MyApp(App): + BINDINGS = [ + ("a", "add_input", "add_input"), + ("v", "set_value", "set_value"), + ] + + def action_add_input(self): + self.mount(Input()) + + def action_set_value(self): + self.query_one(Input).value = "value" + + app = MyApp() + async with app.run_test() as pilot: + await pilot.press("a") + await pilot.press("v") + console = Console(width=5) + with console.capture() as capture: + console.print(app.query_one(Input).render()) + assert capture.get() == "value" From 6a495005b649408a37e012aa4b865326b61a21aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 11 Jan 2023 19:21:31 +0000 Subject: [PATCH 288/310] Changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af9c30012..70da0208d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - The styles `scrollbar-background-active` and `scrollbar-color-hover` are no longer ignored https://github.com/Textualize/textual/pull/1480 - The widget `Placeholder` can now have its width set to `auto` https://github.com/Textualize/textual/pull/1508 +- Behavior of widget `Input` when rendering after programmatic value change and related scenarios https://github.com/Textualize/textual/issues/1477 https://github.com/Textualize/textual/issues/1443 ## [0.9.1] - 2022-12-30 From dad930d390d653ad79e4641da2d75f69c551b1b9 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 12 Jan 2023 09:27:14 +0000 Subject: [PATCH 289/310] Add a missing return value to a docstring --- src/textual/cli/tools/diagnose.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/textual/cli/tools/diagnose.py b/src/textual/cli/tools/diagnose.py index 447d21f95..5a73f4307 100644 --- a/src/textual/cli/tools/diagnose.py +++ b/src/textual/cli/tools/diagnose.py @@ -55,7 +55,11 @@ def _os() -> None: def _guess_term() -> str: - """Try and guess which terminal is being used.""" + """Try and guess which terminal is being used. + + Returns: + str: The best guess at the name of the terminal. + """ # First obvious place to look is in $TERM_PROGRAM. term_program = os.environ.get("TERM_PROGRAM") From 2c4a889d7193b806f59e6a3c2ab5f11d2ab93701 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 12 Jan 2023 09:33:46 +0000 Subject: [PATCH 290/310] Tidy up the output of the console dimensions --- src/textual/cli/tools/diagnose.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/textual/cli/tools/diagnose.py b/src/textual/cli/tools/diagnose.py index 5a73f4307..4b6803a05 100644 --- a/src/textual/cli/tools/diagnose.py +++ b/src/textual/cli/tools/diagnose.py @@ -3,8 +3,10 @@ import os import sys import platform +from typing import Any +from functools import singledispatch from importlib_metadata import version -from rich.console import Console +from rich.console import Console, ConsoleDimensions def _section(title: str, values: dict[str, str]) -> None: @@ -115,11 +117,29 @@ def _term() -> None: ) +@singledispatch +def _str_rich(value: Any) -> str: + """Convert a rich console option to a string. + + Args: + value (Any): The value to convert to a string. + + Returns: + str: The string version of the value for output + """ + return str(value) + + +@_str_rich.register +def _(value: ConsoleDimensions) -> str: + return f"width={value.width}, height={value.height}" + + def _console() -> None: """Print The Rich console options.""" _section( "Rich Console options", - {k: str(v) for k, v in Console().options.__dict__.items()}, + {k: _str_rich(v) for k, v in Console().options.__dict__.items()}, ) From 922c2273b1d0849d12cbabc552292bca2a95c45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 12 Jan 2023 12:00:53 +0000 Subject: [PATCH 291/310] Match clock color to header. --- CHANGELOG.md | 1 + src/textual/widgets/_header.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af9c30012..402b8064c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fail-fast and print pretty tracebacks for Widget compose errors https://github.com/Textualize/textual/pull/1505 - Added Widget._refresh_scroll to avoid expensive layout when scrolling https://github.com/Textualize/textual/pull/1524 - `events.Paste` now bubbles https://github.com/Textualize/textual/issues/1434 +- Clock color in the `Header` widget now matches the header color https://github.com/Textualize/textual/issues/1459 ### Fixed diff --git a/src/textual/widgets/_header.py b/src/textual/widgets/_header.py index 66e4d4fe0..197601481 100644 --- a/src/textual/widgets/_header.py +++ b/src/textual/widgets/_header.py @@ -45,7 +45,7 @@ class HeaderClock(HeaderClockSpace): DEFAULT_CSS = """ HeaderClock { - background: $secondary-background-lighten-1; + background: $foreground-darken-1 5%; color: $text; text-opacity: 85%; content-align: center middle; @@ -97,7 +97,7 @@ class Header(Widget): } Header.-tall { height: 3; - } + } """ tall = Reactive(False) From dff226efa29d338a2c9f03b83ee4f592c370602f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 12 Jan 2023 14:49:16 +0000 Subject: [PATCH 292/310] Update docstring. --- src/textual/dom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/dom.py b/src/textual/dom.py index 43685c539..cbf5ca27f 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -290,7 +290,7 @@ class DOMNode(MessagePump): """Gets the component classes for this class and inherited from bases. Component classes are inherited from base classes, unless - `_inherit_component_classes` is set to `False`. + `inherit_component_classes` is set to `False` when subclassing. Returns: set[str]: a set with all the component classes available. From dd478dd249a1b4d659649d5442afab4f77d3e88f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 12 Jan 2023 15:00:56 +0000 Subject: [PATCH 293/310] Make list_view snapshot test pass more reliably --- tests/snapshot_tests/test_snapshots.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index e2da09d18..29262d69d 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -103,7 +103,7 @@ def test_header_render(snap_compare): def test_list_view(snap_compare): assert snap_compare( - WIDGET_EXAMPLES_DIR / "list_view.py", press=["tab", "down", "down", "up"] + WIDGET_EXAMPLES_DIR / "list_view.py", press=["tab", "down", "down", "up", "_"] ) From a3e54323d949021082d4cc8b7d65dc89e8995f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 12 Jan 2023 15:47:58 +0000 Subject: [PATCH 294/310] Make methods private. --- src/textual/app.py | 2 +- src/textual/css/stylesheet.py | 2 +- src/textual/dom.py | 7 +++++-- src/textual/widget.py | 2 +- tests/test_dom.py | 28 ++++++++++++++-------------- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/textual/app.py b/src/textual/app.py index 89da6aaf6..ec5955840 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1405,7 +1405,7 @@ class App(Generic[ReturnType], DOMNode): try: if self.css_path: self.stylesheet.read_all(self.css_path) - for path, css, tie_breaker in self.get_default_css(): + for path, css, tie_breaker in self._get_default_css(): self.stylesheet.add_source( css, path=path, is_default_css=True, tie_breaker=tie_breaker ) diff --git a/src/textual/css/stylesheet.py b/src/textual/css/stylesheet.py index 176a420a2..ad59ac00c 100644 --- a/src/textual/css/stylesheet.py +++ b/src/textual/css/stylesheet.py @@ -407,7 +407,7 @@ class Stylesheet: self.replace_rules(node, node_rules, animate=animate) node._component_styles.clear() - for component in node.get_component_classes(): + for component in node._get_component_classes(): virtual_node = DOMNode(classes=component) virtual_node._attach(node) self.apply(virtual_node, animate=False) diff --git a/src/textual/dom.py b/src/textual/dom.py index cbf5ca27f..876924288 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -262,9 +262,12 @@ class DOMNode(MessagePump): if self._classes: yield "classes", " ".join(self._classes) - def get_default_css(self) -> list[tuple[str, str, int]]: + def _get_default_css(self) -> list[tuple[str, str, int]]: """Gets the CSS for this class and inherited from bases. + Default CSS is inherited from base classes, unless `inherit_css` is set to + `False` when subclassing. + Returns: list[tuple[str, str]]: a list of tuples containing (PATH, SOURCE) for this and inherited from base classes. @@ -286,7 +289,7 @@ class DOMNode(MessagePump): return css_stack - def get_component_classes(self) -> set[str]: + def _get_component_classes(self) -> set[str]: """Gets the component classes for this class and inherited from bases. Component classes are inherited from base classes, unless diff --git a/src/textual/widget.py b/src/textual/widget.py index 7808f1a08..7e409e277 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -695,7 +695,7 @@ class Widget(DOMNode): app (App): App instance. """ # Parse the Widget's CSS - for path, css, tie_breaker in self.get_default_css(): + for path, css, tie_breaker in self._get_default_css(): self.app.stylesheet.add_source( css, path=path, is_default_css=True, tie_breaker=tie_breaker ) diff --git a/tests/test_dom.py b/tests/test_dom.py index b8cca4737..ded834300 100644 --- a/tests/test_dom.py +++ b/tests/test_dom.py @@ -79,7 +79,7 @@ def test_inherited_bindings(): assert list(e._bindings.keys.keys()) == ["e"] -def test_get_default_css(): +def test__get_default_css(): class A(DOMNode): pass @@ -96,17 +96,17 @@ def test_get_default_css(): DEFAULT_CSS = "E" node = DOMNode() - node_css = node.get_default_css() + node_css = node._get_default_css() a = A() - a_css = a.get_default_css() + a_css = a._get_default_css() b = B() - b_css = b.get_default_css() + b_css = b._get_default_css() c = C() - c_css = c.get_default_css() + c_css = c._get_default_css() d = D() - d_css = d.get_default_css() + d_css = d._get_default_css() e = E() - e_css = e.get_default_css() + e_css = e._get_default_css() # Descendants that don't assign to DEFAULT_CSS don't add new CSS to the stack. assert len(node_css) == len(a_css) == len(b_css) == 0 @@ -143,19 +143,19 @@ def test_component_classes_inheritance(): COMPONENT_CLASSES = {"f-1"} node = DOMNode() - node_cc = node.get_component_classes() + node_cc = node._get_component_classes() a = A() - a_cc = a.get_component_classes() + a_cc = a._get_component_classes() b = B() - b_cc = b.get_component_classes() + b_cc = b._get_component_classes() c = C() - c_cc = c.get_component_classes() + c_cc = c._get_component_classes() d = D() - d_cc = d.get_component_classes() + d_cc = d._get_component_classes() e = E() - e_cc = e.get_component_classes() + e_cc = e._get_component_classes() f = F() - f_cc = f.get_component_classes() + f_cc = f._get_component_classes() assert node_cc == set() assert a_cc == {"a-1", "a-2"} From feb8591e72b5f89c318db9550410faf7d370d4dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 12 Jan 2023 16:11:36 +0000 Subject: [PATCH 295/310] Fix test: await widget mount before focusing Follow-up to #1548 --- tests/test_input.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_input.py b/tests/test_input.py index 06f7c8b11..067c4374c 100644 --- a/tests/test_input.py +++ b/tests/test_input.py @@ -60,9 +60,9 @@ async def test_input_value_visible_if_mounted_later_and_focused(): class MyApp(App): BINDINGS = [("a", "add_input", "add_input")] - def action_add_input(self): + async def action_add_input(self): inp = Input(value="value") - self.mount(inp) + await self.mount(inp) inp.focus() app = MyApp() From 027635b978d2999ca128fe0462250a66915d6e60 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 12 Jan 2023 17:45:36 +0000 Subject: [PATCH 296/310] merge --- CHANGELOG.md | 1 + docs/index.md | 1 - src/textual/app.py | 6 +- src/textual/dom.py | 1 + src/textual/message_pump.py | 3 + src/textual/reactive.py | 72 +++++++---- .../__snapshots__/test_snapshots.ambr | 120 +++++++++--------- tests/test_reactive.py | 45 +++++-- 8 files changed, 153 insertions(+), 96 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed97fda10..71f5a6049 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added Widget._refresh_scroll to avoid expensive layout when scrolling https://github.com/Textualize/textual/pull/1524 - `events.Paste` now bubbles https://github.com/Textualize/textual/issues/1434 - Clock color in the `Header` widget now matches the header color https://github.com/Textualize/textual/issues/1459 +- Watch methods may now take no parameters ### Fixed diff --git a/docs/index.md b/docs/index.md index 584f60f93..1d776e820 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,3 @@ - # Introduction Welcome to the [Textual](https://github.com/Textualize/textual) framework documentation. Built with ❤️ by [Textualize.io](https://www.textualize.io) diff --git a/src/textual/app.py b/src/textual/app.py index 89da6aaf6..2097abeeb 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -249,9 +249,9 @@ class App(Generic[ReturnType], DOMNode): Binding("shift+tab", "focus_previous", "Focus Previous", show=False), ] - title: Reactive[str] = Reactive("") - sub_title: Reactive[str] = Reactive("") - dark: Reactive[bool] = Reactive(True) + title: Reactive[str] = Reactive("", no_compute=True) + sub_title: Reactive[str] = Reactive("", no_compute=True) + dark: Reactive[bool] = Reactive(True, no_compute=True) def __init__( self, diff --git a/src/textual/dom.py b/src/textual/dom.py index 1204073a0..c1152e8b0 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -31,6 +31,7 @@ from .css.parse import parse_declarations from .css.styles import RenderStyles, Styles from .css.tokenize import IDENTIFIER from .message_pump import MessagePump +from .reactive import Reactive from .timer import Timer from .walk import walk_breadth_first, walk_depth_first diff --git a/src/textual/message_pump.py b/src/textual/message_pump.py index 5c3fca3f6..fef27b304 100644 --- a/src/textual/message_pump.py +++ b/src/textual/message_pump.py @@ -108,6 +108,7 @@ class MessagePump(metaclass=MessagePumpMeta): @property def is_running(self) -> bool: + """bool: Check if the message pump is running (potentially processing messages)""" return self._running @property @@ -326,6 +327,8 @@ class MessagePump(metaclass=MessagePumpMeta): try: await self._dispatch_message(events.Compose(sender=self)) await self._dispatch_message(events.Mount(sender=self)) + except Exception as error: + self.app._handle_exception(error) finally: # This is critical, mount may be waiting self._mounted_event.set() diff --git a/src/textual/reactive.py b/src/textual/reactive.py index d13039cde..3096ef83e 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -44,6 +44,7 @@ class Reactive(Generic[ReactiveType]): repaint (bool, optional): Perform a repaint on change. Defaults to True. init (bool, optional): Call watchers on initialize (post mount). Defaults to False. always_update (bool, optional): Call watchers even when the new value equals the old value. Defaults to False. + no_compute (bool, optional): Don't run compute methods when attribute is changed. Defaults to False. """ def __init__( @@ -54,12 +55,15 @@ class Reactive(Generic[ReactiveType]): repaint: bool = True, init: bool = False, always_update: bool = False, + no_compute: bool = False, ) -> None: self._default = default self._layout = layout self._repaint = repaint self._init = init self._always_update = always_update + self._no_compute = no_compute + self._is_compute = False @classmethod def init( @@ -69,6 +73,7 @@ class Reactive(Generic[ReactiveType]): layout: bool = False, repaint: bool = True, always_update: bool = False, + no_compute: bool = False, ) -> Reactive: """A reactive variable that calls watchers and compute on initialize (post mount). @@ -77,6 +82,7 @@ class Reactive(Generic[ReactiveType]): layout (bool, optional): Perform a layout on change. Defaults to False. repaint (bool, optional): Perform a repaint on change. Defaults to True. always_update (bool, optional): Call watchers even when the new value equals the old value. Defaults to False. + no_compute (bool, optional): Don't run compute methods when attribute is changed. Defaults to False. Returns: Reactive: A Reactive instance which calls watchers or initialize. @@ -87,6 +93,7 @@ class Reactive(Generic[ReactiveType]): repaint=repaint, init=True, always_update=always_update, + no_compute=no_compute, ) @classmethod @@ -105,24 +112,29 @@ class Reactive(Generic[ReactiveType]): return cls(default, layout=False, repaint=False, init=True) @classmethod - def _initialize_object(cls, obj: object) -> None: + def _initialize_object(cls, obj: Reactable) -> None: """Set defaults and call any watchers / computes for the first time. Args: obj (Reactable): An object with Reactive descriptors """ - if not hasattr(obj, "__reactive_initialized"): + return + if not getattr(obj, "__reactive_initialized", False): startswith = str.startswith + watchers = [] for key in obj.__class__.__dict__: if startswith(key, "_default_"): name = key[9:] + internal_name = f"_reactive_{name}" # Check defaults - if not hasattr(obj, name): + if internal_name not in obj.__dict__: # Attribute has no value yet default = getattr(obj, key) default_value = default() if callable(default) else default # Set the default vale (calls `__set__`) - setattr(obj, name, default_value) + obj.__dict__[internal_name] = default_value + watchers.append((name, default_value)) + setattr(obj, "__reactive_initialized", True) @classmethod @@ -140,6 +152,7 @@ class Reactive(Generic[ReactiveType]): # Check for compute method if hasattr(owner, f"compute_{name}"): # Compute methods are stored in a list called `__computes` + self._is_compute = True try: computes = getattr(owner, "__computes") except AttributeError: @@ -156,7 +169,13 @@ class Reactive(Generic[ReactiveType]): def __get__(self, obj: Reactable, obj_type: type[object]) -> ReactiveType: _rich_traceback_omit = True - value: _NotSet | ReactiveType = getattr(obj, self.internal_name, _NOT_SET) + + value: _NotSet | ReactiveType + if self._is_compute: + value = getattr(obj, f"compute_{self.name}")() + else: + value = getattr(obj, self.internal_name, _NOT_SET) + if isinstance(value, _NotSet): # No value present, we need to set the default init_name = f"_default_{self.name}" @@ -164,13 +183,19 @@ class Reactive(Generic[ReactiveType]): default_value = default() if callable(default) else default # Set and return the value setattr(obj, self.internal_name, default_value) + if self._init: + print("CHECK WATCHERS") self._check_watchers(obj, self.name, default_value) - return default_value + + if not self._no_compute: + self._compute(obj) + value = getattr(obj, self.internal_name) return value def __set__(self, obj: Reactable, value: ReactiveType) -> None: _rich_traceback_omit = True + # Reactive._initialize_object(obj) name = self.name current_value = getattr(obj, name) # Check for validate function @@ -182,8 +207,13 @@ class Reactive(Generic[ReactiveType]): if current_value != value or self._always_update: # Store the internal value setattr(obj, self.internal_name, value) + # Check all watchers self._check_watchers(obj, name, current_value) + + if not self._no_compute: + self._compute(obj) + # Refresh according to descriptor flags if self._layout or self._repaint: obj.refresh(repaint=self._repaint, layout=self._layout) @@ -225,10 +255,13 @@ class Reactive(Generic[ReactiveType]): bool: True if the watcher was run, or False if it was posted. """ _rich_traceback_omit = True - if count_parameters(watch_function) == 2: + param_count = count_parameters(watch_function) + if param_count == 2: watch_result = watch_function(old_value, value) - else: + elif param_count == 1: watch_result = watch_function(value) + else: + watch_result = watch_function() if isawaitable(watch_result): # Result is awaitable, so we need to await it within an async context obj.post_message_no_wait( @@ -244,24 +277,14 @@ class Reactive(Generic[ReactiveType]): require_compute = False watch_function = getattr(obj, f"watch_{name}", None) if callable(watch_function): - require_compute = require_compute or invoke_watcher( - watch_function, old_value, value - ) + invoke_watcher(watch_function, old_value, value) watchers: list[Callable] = getattr(obj, "__watchers", {}).get(name, []) for watcher in watchers: - require_compute = require_compute or invoke_watcher( - watcher, old_value, value - ) - - if require_compute: - # Run computes - obj.post_message_no_wait( - events.Callback(sender=obj, callback=partial(Reactive._compute, obj)) - ) + invoke_watcher(watcher, old_value, value) @classmethod - async def _compute(cls, obj: Reactable) -> None: + def _compute(cls, obj: Reactable) -> None: """Invoke all computes. Args: @@ -274,9 +297,8 @@ class Reactive(Generic[ReactiveType]): compute_method = getattr(obj, f"compute_{compute}") except AttributeError: continue - - value = await invoke(compute_method) - setattr(obj, compute, value) + value = compute_method() + setattr(obj, f"_reactive_{compute}", value) class reactive(Reactive[ReactiveType]): @@ -347,3 +369,5 @@ def watch( if init: current_value = getattr(obj, attribute_name, None) Reactive._check_watchers(obj, attribute_name, current_value) + print(obj, attribute_name) + print(watchers) diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index 0f1da3cf2..14baa3354 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -13035,136 +13035,136 @@ font-weight: 700; } - .terminal-4137661484-matrix { + .terminal-3727479996-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4137661484-title { + .terminal-3727479996-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4137661484-r1 { fill: #ffff00 } - .terminal-4137661484-r2 { fill: #c5c8c6 } - .terminal-4137661484-r3 { fill: #e3e3e3 } - .terminal-4137661484-r4 { fill: #ddeedd } - .terminal-4137661484-r5 { fill: #dde8f3;font-weight: bold } - .terminal-4137661484-r6 { fill: #ddedf9 } + .terminal-3727479996-r1 { fill: #ffff00 } + .terminal-3727479996-r2 { fill: #e3e3e3 } + .terminal-3727479996-r3 { fill: #c5c8c6 } + .terminal-3727479996-r4 { fill: #ddeedd } + .terminal-3727479996-r5 { fill: #dde8f3;font-weight: bold } + .terminal-3727479996-r6 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - Layers + Layers - - - - ────────────────────────────────── - It's full of stars! My God! It's full of sta - - This should float over the top - - - ────────────────────────────────── - - - - - - - - - - - - - - - - -  T  Toggle Screen  + + + + ──────────────────────────────────Layers + It's full of stars! My God! It's full of sta + + This should float over the top + + + ────────────────────────────────── + + + + + + + + + + + + + + + + +  T  Toggle Screen  diff --git a/tests/test_reactive.py b/tests/test_reactive.py index 5824f26f4..e3e30f698 100644 --- a/tests/test_reactive.py +++ b/tests/test_reactive.py @@ -2,8 +2,9 @@ import asyncio import pytest -from textual.app import App +from textual.app import App, ComposeResult from textual.reactive import reactive, var +from textual.widget import Widget OLD_VALUE = 5_000 NEW_VALUE = 1_000_000 @@ -81,7 +82,8 @@ async def test_watch_async_init_true(): await asyncio.wait_for(app.watcher_called_event.wait(), timeout=0.05) except TimeoutError: pytest.fail( - "Async watcher wasn't called within timeout when reactive init = True") + "Async watcher wasn't called within timeout when reactive init = True" + ) assert app.count == OLD_VALUE assert app.watcher_old_value == OLD_VALUE @@ -171,8 +173,12 @@ async def test_reactive_with_callable_default(): app = ReactiveCallable() async with app.run_test(): - assert app.value == OLD_VALUE # The value should be set to the return val of the callable - assert called_with_app is app # Ensure the App is passed into the reactive default callable + assert ( + app.value == OLD_VALUE + ) # The value should be set to the return val of the callable + assert ( + called_with_app is app + ) # Ensure the App is passed into the reactive default callable assert app.watcher_called_with == OLD_VALUE @@ -216,8 +222,7 @@ async def test_validate_init_true_set_before_dom_ready(): assert validator_call_count == 1 - -@pytest.mark.xfail(reason="Compute methods not called when init=True [issue#1227]") +# @pytest.mark.xfail(reason="Compute methods not called when init=True [issue#1227]") async def test_reactive_compute_first_time_set(): class ReactiveComputeFirstTimeSet(App): number = reactive(1) @@ -228,11 +233,10 @@ async def test_reactive_compute_first_time_set(): app = ReactiveComputeFirstTimeSet() async with app.run_test(): - await asyncio.sleep(.2) # TODO: We sleep here while issue#1218 is open + await asyncio.sleep(0.2) # TODO: We sleep here while issue#1218 is open assert app.double_number == 2 -@pytest.mark.xfail(reason="Compute methods not called immediately [issue#1218]") async def test_reactive_method_call_order(): class CallOrder(App): count = reactive(OLD_VALUE, init=False) @@ -266,3 +270,28 @@ async def test_reactive_method_call_order(): ] assert app.count == NEW_VALUE + 1 assert app.count_times_ten == (NEW_VALUE + 1) * 10 + + +async def test_premature_reactive_call(): + + watcher_called = False + + class BrokenWidget(Widget): + foo = reactive(1) + + def __init__(self) -> None: + super().__init__() + self.foo = "bar" + + async def watch_foo(self) -> None: + nonlocal watcher_called + watcher_called = True + + class PrematureApp(App): + def compose(self) -> ComposeResult: + yield BrokenWidget() + + app = PrematureApp() + async with app.run_test() as pilot: + assert watcher_called + app.exit() From 8f0f0d8c12e0b5f5be86504848140a0a532d3774 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 10:44:13 +0000 Subject: [PATCH 297/310] refactor --- src/textual/reactive.py | 94 ++++++++++++++++++++++++++++------------- tests/test_reactive.py | 2 +- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/textual/reactive.py b/src/textual/reactive.py index 3096ef83e..686de95b8 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -111,6 +111,24 @@ class Reactive(Generic[ReactiveType]): """ return cls(default, layout=False, repaint=False, init=True) + def _initialize_reactive(self, obj: Reactable, name: str) -> None: + internal_name = f"_reactive_{name}" + if hasattr(obj, internal_name): + # Attribute already has a value + return + if self._is_compute: + default = getattr(obj, f"compute_{name}")() + else: + default_or_callable = self._default + default = ( + default_or_callable() + if callable(default_or_callable) + else default_or_callable + ) + setattr(obj, internal_name, default) + if self._init: + self._check_watchers(obj, name, default) + @classmethod def _initialize_object(cls, obj: Reactable) -> None: """Set defaults and call any watchers / computes for the first time. @@ -118,24 +136,31 @@ class Reactive(Generic[ReactiveType]): Args: obj (Reactable): An object with Reactive descriptors """ - return - if not getattr(obj, "__reactive_initialized", False): - startswith = str.startswith - watchers = [] - for key in obj.__class__.__dict__: - if startswith(key, "_default_"): - name = key[9:] - internal_name = f"_reactive_{name}" - # Check defaults - if internal_name not in obj.__dict__: - # Attribute has no value yet - default = getattr(obj, key) - default_value = default() if callable(default) else default - # Set the default vale (calls `__set__`) - obj.__dict__[internal_name] = default_value - watchers.append((name, default_value)) + reactives = getattr(obj, "__reactives", {}) + for name, reactive in reactives.items(): + reactive._initialize_reactive(obj, name) - setattr(obj, "__reactive_initialized", True) + # startswith = str.startswith + # watchers = [] + # reactives = getattr(obj, "__reactives", []) + + # print(reactives) + # for name in reactives.keys(): + # internal_name = f"_reactive_{name}" + # # Check defaults + # if internal_name not in obj.__dict__: + # # Attribute has no value yet + + # for k in obj.__dict__: + # if k.startswith("_default"): + # print(k) + + # default = getattr(obj, f"_default_{name}") + # default_value = default() if callable(default) else default + # # Set the default vale (calls `__set__`) + # obj.__dict__[internal_name] = None + # setattr(obj, name, default_value) + # # watchers.append((name, default_value)) @classmethod def _reset_object(cls, obj: object) -> None: @@ -148,6 +173,9 @@ class Reactive(Generic[ReactiveType]): getattr(obj, "__computes", []).clear() def __set_name__(self, owner: Type[MessageTarget], name: str) -> None: + reactives = getattr(owner, "__reactives", {}) + reactives[name] = self + setattr(owner, "__reactives", reactives) # Check for compute method if hasattr(owner, f"compute_{name}"): @@ -170,32 +198,38 @@ class Reactive(Generic[ReactiveType]): def __get__(self, obj: Reactable, obj_type: type[object]) -> ReactiveType: _rich_traceback_omit = True + self._initialize_reactive(obj, self.name) + value: _NotSet | ReactiveType if self._is_compute: value = getattr(obj, f"compute_{self.name}")() else: value = getattr(obj, self.internal_name, _NOT_SET) - if isinstance(value, _NotSet): - # No value present, we need to set the default - init_name = f"_default_{self.name}" - default = getattr(obj, init_name) - default_value = default() if callable(default) else default - # Set and return the value - setattr(obj, self.internal_name, default_value) + if not self._no_compute: + self._compute(obj) - if self._init: - print("CHECK WATCHERS") - self._check_watchers(obj, self.name, default_value) + # if isinstance(value, _NotSet): + # # No value present, we need to set the default + # init_name = f"_default_{self.name}" + # default = getattr(obj, init_name) + # default_value = default() if callable(default) else default + # # Set and return the value + # setattr(obj, self.internal_name, default_value) - if not self._no_compute: - self._compute(obj) - value = getattr(obj, self.internal_name) + # if self._init: + # self._check_watchers(obj, self.name, default_value) + + # if not self._no_compute: + # self._compute(obj) + # value = getattr(obj, self.internal_name) return value def __set__(self, obj: Reactable, value: ReactiveType) -> None: _rich_traceback_omit = True # Reactive._initialize_object(obj) + + self._initialize_reactive(obj, self.name) name = self.name current_value = getattr(obj, name) # Check for validate function diff --git a/tests/test_reactive.py b/tests/test_reactive.py index e3e30f698..3d03c6d49 100644 --- a/tests/test_reactive.py +++ b/tests/test_reactive.py @@ -159,7 +159,7 @@ async def test_reactive_with_callable_default(): Textual will call it in order to retrieve the default value.""" called_with_app = None - def set_called(app: App) -> int: + def set_called() -> int: nonlocal called_with_app called_with_app = app return OLD_VALUE From 7e428e2f4ca53ff589e7e91d763794241fd2db4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Fri, 13 Jan 2023 10:58:57 +0000 Subject: [PATCH 298/310] fix tests: await all mounts. --- tests/test_input.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_input.py b/tests/test_input.py index 067c4374c..bbdb66e86 100644 --- a/tests/test_input.py +++ b/tests/test_input.py @@ -42,8 +42,8 @@ async def test_input_value_visible_if_mounted_later(): class MyApp(App): BINDINGS = [("a", "add_input", "add_input")] - def action_add_input(self): - self.mount(Input(value="value")) + async def action_add_input(self): + await self.mount(Input(value="value")) app = MyApp() async with app.run_test() as pilot: @@ -83,8 +83,8 @@ async def test_input_value_visible_if_mounted_later_and_assigned_after(): ("v", "set_value", "set_value"), ] - def action_add_input(self): - self.mount(Input()) + async def action_add_input(self): + await self.mount(Input()) def action_set_value(self): self.query_one(Input).value = "value" From c3129c8331b8a1b341079ed1596ce4969dc72d2b Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 17:22:52 +0000 Subject: [PATCH 299/310] fix inheritance --- src/textual/dom.py | 13 +++++++++ src/textual/reactive.py | 59 ++++++++++++++++----------------------- tests/test_reactive.py | 62 ++++++++++++++++++++++++++++++++++------- 3 files changed, 89 insertions(+), 45 deletions(-) diff --git a/src/textual/dom.py b/src/textual/dom.py index c1152e8b0..33469be24 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -108,6 +108,8 @@ class DOMNode(MessagePump): # Generated list of bindings _merged_bindings: ClassVar[Bindings] | None = None + _reactives: ClassVar[dict[str, Reactive]] + def __init__( self, *, @@ -164,6 +166,17 @@ class DOMNode(MessagePump): cls, inherit_css: bool = True, inherit_bindings: bool = True ) -> None: super().__init_subclass__() + + reactives = cls._reactives = {} + for base in reversed(cls.__mro__): + reactives.update( + { + name: reactive + for name, reactive in base.__dict__.items() + if isinstance(reactive, Reactive) + } + ) + cls._inherit_css = inherit_css cls._inherit_bindings = inherit_bindings css_type_names: set[str] = set() diff --git a/src/textual/reactive.py b/src/textual/reactive.py index 686de95b8..4a65201d0 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -13,6 +13,8 @@ from typing import ( Union, ) +import rich.repr + from . import events from ._callback import count_parameters, invoke from ._types import MessageTarget @@ -35,6 +37,7 @@ _NOT_SET = _NotSet() T = TypeVar("T") +@rich.repr.auto class Reactive(Generic[ReactiveType]): """Reactive descriptor. @@ -47,6 +50,8 @@ class Reactive(Generic[ReactiveType]): no_compute (bool, optional): Don't run compute methods when attribute is changed. Defaults to False. """ + _reactives: TypeVar[dict[str, object]] = {} + def __init__( self, default: ReactiveType | Callable[[], ReactiveType], @@ -65,6 +70,14 @@ class Reactive(Generic[ReactiveType]): self._no_compute = no_compute self._is_compute = False + def __rich_repr__(self) -> rich.repr.Result: + yield self._default + yield "layout", self._layout + yield "repaint", self._repaint + yield "init", self._init + yield "always_update", self._always_update + yield "no_compute", self._no_compute + @classmethod def init( cls, @@ -111,12 +124,13 @@ class Reactive(Generic[ReactiveType]): """ return cls(default, layout=False, repaint=False, init=True) - def _initialize_reactive(self, obj: Reactable, name: str) -> None: + def _initialize_reactive(self, obj: Reactable, name: str) -> bool: internal_name = f"_reactive_{name}" if hasattr(obj, internal_name): # Attribute already has a value return - if self._is_compute: + compute_method = getattr(obj, f"compute_{name}", None) + if compute_method is not None and self._init: default = getattr(obj, f"compute_{name}")() else: default_or_callable = self._default @@ -136,32 +150,10 @@ class Reactive(Generic[ReactiveType]): Args: obj (Reactable): An object with Reactive descriptors """ - reactives = getattr(obj, "__reactives", {}) - for name, reactive in reactives.items(): + + for name, reactive in obj._reactives.items(): reactive._initialize_reactive(obj, name) - # startswith = str.startswith - # watchers = [] - # reactives = getattr(obj, "__reactives", []) - - # print(reactives) - # for name in reactives.keys(): - # internal_name = f"_reactive_{name}" - # # Check defaults - # if internal_name not in obj.__dict__: - # # Attribute has no value yet - - # for k in obj.__dict__: - # if k.startswith("_default"): - # print(k) - - # default = getattr(obj, f"_default_{name}") - # default_value = default() if callable(default) else default - # # Set the default vale (calls `__set__`) - # obj.__dict__[internal_name] = None - # setattr(obj, name, default_value) - # # watchers.append((name, default_value)) - @classmethod def _reset_object(cls, obj: object) -> None: """Reset reactive structures on object (to avoid reference cycles). @@ -173,9 +165,6 @@ class Reactive(Generic[ReactiveType]): getattr(obj, "__computes", []).clear() def __set_name__(self, owner: Type[MessageTarget], name: str) -> None: - reactives = getattr(owner, "__reactives", {}) - reactives[name] = self - setattr(owner, "__reactives", reactives) # Check for compute method if hasattr(owner, f"compute_{name}"): @@ -198,16 +187,18 @@ class Reactive(Generic[ReactiveType]): def __get__(self, obj: Reactable, obj_type: type[object]) -> ReactiveType: _rich_traceback_omit = True + # Reactive._initialize_object(obj) self._initialize_reactive(obj, self.name) value: _NotSet | ReactiveType - if self._is_compute: + compute_method = getattr(self, f"compute_{self.name}", None) + if compute_method is not None: value = getattr(obj, f"compute_{self.name}")() else: - value = getattr(obj, self.internal_name, _NOT_SET) + value = getattr(obj, self.internal_name) - if not self._no_compute: - self._compute(obj) + # if not self._no_compute: + # self._compute(obj) # if isinstance(value, _NotSet): # # No value present, we need to set the default @@ -307,8 +298,6 @@ class Reactive(Generic[ReactiveType]): else: return True - # Compute is only required if a watcher runs immediately, not if they were posted. - require_compute = False watch_function = getattr(obj, f"watch_{name}", None) if callable(watch_function): invoke_watcher(watch_function, old_value, value) diff --git a/tests/test_reactive.py b/tests/test_reactive.py index 3d03c6d49..eef5a9423 100644 --- a/tests/test_reactive.py +++ b/tests/test_reactive.py @@ -3,7 +3,7 @@ import asyncio import pytest from textual.app import App, ComposeResult -from textual.reactive import reactive, var +from textual.reactive import Reactive, reactive, var from textual.widget import Widget OLD_VALUE = 5_000 @@ -157,15 +157,15 @@ async def test_reactive_always_update(): async def test_reactive_with_callable_default(): """A callable can be supplied as the default value for a reactive. Textual will call it in order to retrieve the default value.""" - called_with_app = None + called_with_app = False def set_called() -> int: nonlocal called_with_app - called_with_app = app + called_with_app = True return OLD_VALUE class ReactiveCallable(App): - value = reactive(set_called) + value = reactive(lambda: 123) watcher_called_with = None def watch_value(self, new_value): @@ -174,12 +174,8 @@ async def test_reactive_with_callable_default(): app = ReactiveCallable() async with app.run_test(): assert ( - app.value == OLD_VALUE + app.value == 123 ) # The value should be set to the return val of the callable - assert ( - called_with_app is app - ) # Ensure the App is passed into the reactive default callable - assert app.watcher_called_with == OLD_VALUE async def test_validate_init_true(): @@ -240,7 +236,7 @@ async def test_reactive_compute_first_time_set(): async def test_reactive_method_call_order(): class CallOrder(App): count = reactive(OLD_VALUE, init=False) - count_times_ten = reactive(OLD_VALUE * 10) + count_times_ten = reactive(OLD_VALUE * 10, init=False) calls = [] def validate_count(self, value: int) -> int: @@ -295,3 +291,49 @@ async def test_premature_reactive_call(): async with app.run_test() as pilot: assert watcher_called app.exit() + + +async def test_reactive_inheritance(): + """Check that inheritance works as expected for reactives.""" + + class Primary(App): + foo = reactive(1) + bar = reactive("bar") + + class Secondary(Primary): + foo = reactive(2) + egg = reactive("egg") + + class Tertiary(Secondary): + baz = reactive("baz") + + from rich import print + + primary = Primary() + secondary = Secondary() + tertiary = Tertiary() + + primary_reactive_count = len(primary._reactives) + + # Secondary adds one new reactive + assert len(secondary._reactives) == primary_reactive_count + 1 + + Reactive._initialize_object(primary) + Reactive._initialize_object(secondary) + Reactive._initialize_object(tertiary) + + # Primary doesn't have egg + with pytest.raises(AttributeError): + assert primary.egg + + # primary has foo of 1 + assert primary.foo == 1 + # secondary has different reactive + assert secondary.foo == 2 + # foo is accessible through tertiary + assert tertiary.foo == 2 + + with pytest.raises(AttributeError): + secondary.baz + + assert tertiary.baz == "baz" From f7c671f7109213004ea5ecb95620d3801cb2ff86 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Fri, 13 Jan 2023 17:25:32 +0000 Subject: [PATCH 300/310] Update DOMQuery.only_one to include NoMatches in raises list See #1560 --- src/textual/css/query.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/textual/css/query.py b/src/textual/css/query.py index 9814382f9..5902b3e1f 100644 --- a/src/textual/css/query.py +++ b/src/textual/css/query.py @@ -233,6 +233,7 @@ class DOMQuery(Generic[QueryType]): Raises: WrongType: If the wrong type was found. + NoMatches: If no node matches the query. TooManyMatches: If there is more than one matching node in the query. Returns: From 9a396ece29ff9839c7e0b7f3bd5039348df6fd14 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Fri, 13 Jan 2023 17:33:23 +0000 Subject: [PATCH 301/310] Expand the docstring for DOMNode.query_one See #1560. In short: query_one was changed a couple of months back so that it searched for only a single instance of a hit for the query, rather than (as before) returning the first item that matched the query. Unfortunately the docstring didn't get the necessary update. This should hopefully make things a wee bit clearer in the docs. --- src/textual/dom.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/textual/dom.py b/src/textual/dom.py index 1204073a0..6113d967d 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -745,13 +745,18 @@ class DOMNode(MessagePump): selector: str | type[ExpectType], expect_type: type[ExpectType] | None = None, ) -> ExpectType | Widget: - """Get the first Widget matching the given selector or selector type. + """Get a single Widget matching the given selector or selector type. Args: selector (str | type): A selector. expect_type (type | None, optional): Require the object be of the supplied type, or None for any type. Defaults to None. + Raises: + WrongType: If the wrong type was found. + NoMatches: If no node matches the query. + TooManyMatches: If there is more than one matching node in the query. + Returns: Widget | ExpectType: A widget matching the selector. """ From 40434e7ef10dce800d5e63972139fe8c1986d5f6 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 17:36:41 +0000 Subject: [PATCH 302/310] co_compute to compute --- CHANGELOG.md | 1 + src/textual/app.py | 6 +++--- src/textual/reactive.py | 42 ++++++++++------------------------------- 3 files changed, 14 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71f5a6049..954f3b7d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `events.Paste` now bubbles https://github.com/Textualize/textual/issues/1434 - Clock color in the `Header` widget now matches the header color https://github.com/Textualize/textual/issues/1459 - Watch methods may now take no parameters +- Added `compute` parameter to reactive ### Fixed diff --git a/src/textual/app.py b/src/textual/app.py index 2097abeeb..9b46b9e7d 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -249,9 +249,9 @@ class App(Generic[ReturnType], DOMNode): Binding("shift+tab", "focus_previous", "Focus Previous", show=False), ] - title: Reactive[str] = Reactive("", no_compute=True) - sub_title: Reactive[str] = Reactive("", no_compute=True) - dark: Reactive[bool] = Reactive(True, no_compute=True) + title: Reactive[str] = Reactive("", compute=False) + sub_title: Reactive[str] = Reactive("", compute=False) + dark: Reactive[bool] = Reactive(True, compute=False) def __init__( self, diff --git a/src/textual/reactive.py b/src/textual/reactive.py index 4a65201d0..bcce2f7e0 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -47,7 +47,7 @@ class Reactive(Generic[ReactiveType]): repaint (bool, optional): Perform a repaint on change. Defaults to True. init (bool, optional): Call watchers on initialize (post mount). Defaults to False. always_update (bool, optional): Call watchers even when the new value equals the old value. Defaults to False. - no_compute (bool, optional): Don't run compute methods when attribute is changed. Defaults to False. + compute (bool, optional): Don't run compute methods when attribute is changed. Defaults to True. """ _reactives: TypeVar[dict[str, object]] = {} @@ -60,15 +60,14 @@ class Reactive(Generic[ReactiveType]): repaint: bool = True, init: bool = False, always_update: bool = False, - no_compute: bool = False, + compute: bool = True, ) -> None: self._default = default self._layout = layout self._repaint = repaint self._init = init self._always_update = always_update - self._no_compute = no_compute - self._is_compute = False + self._run_compute = compute def __rich_repr__(self) -> rich.repr.Result: yield self._default @@ -76,7 +75,7 @@ class Reactive(Generic[ReactiveType]): yield "repaint", self._repaint yield "init", self._init yield "always_update", self._always_update - yield "no_compute", self._no_compute + yield "compute", self._run_compute @classmethod def init( @@ -86,7 +85,7 @@ class Reactive(Generic[ReactiveType]): layout: bool = False, repaint: bool = True, always_update: bool = False, - no_compute: bool = False, + compute: bool = True, ) -> Reactive: """A reactive variable that calls watchers and compute on initialize (post mount). @@ -95,7 +94,7 @@ class Reactive(Generic[ReactiveType]): layout (bool, optional): Perform a layout on change. Defaults to False. repaint (bool, optional): Perform a repaint on change. Defaults to True. always_update (bool, optional): Call watchers even when the new value equals the old value. Defaults to False. - no_compute (bool, optional): Don't run compute methods when attribute is changed. Defaults to False. + compute (bool, optional): Don't run compute methods when attribute is changed. Defaults to False. Returns: Reactive: A Reactive instance which calls watchers or initialize. @@ -106,7 +105,7 @@ class Reactive(Generic[ReactiveType]): repaint=repaint, init=True, always_update=always_update, - no_compute=no_compute, + compute=compute, ) @classmethod @@ -122,7 +121,7 @@ class Reactive(Generic[ReactiveType]): Returns: Reactive: A Reactive descriptor. """ - return cls(default, layout=False, repaint=False, init=True) + return cls(default, layout=False, repaint=False, init=False) def _initialize_reactive(self, obj: Reactable, name: str) -> bool: internal_name = f"_reactive_{name}" @@ -169,7 +168,6 @@ class Reactive(Generic[ReactiveType]): # Check for compute method if hasattr(owner, f"compute_{name}"): # Compute methods are stored in a list called `__computes` - self._is_compute = True try: computes = getattr(owner, "__computes") except AttributeError: @@ -187,38 +185,18 @@ class Reactive(Generic[ReactiveType]): def __get__(self, obj: Reactable, obj_type: type[object]) -> ReactiveType: _rich_traceback_omit = True - # Reactive._initialize_object(obj) self._initialize_reactive(obj, self.name) - value: _NotSet | ReactiveType + value: ReactiveType compute_method = getattr(self, f"compute_{self.name}", None) if compute_method is not None: value = getattr(obj, f"compute_{self.name}")() else: value = getattr(obj, self.internal_name) - - # if not self._no_compute: - # self._compute(obj) - - # if isinstance(value, _NotSet): - # # No value present, we need to set the default - # init_name = f"_default_{self.name}" - # default = getattr(obj, init_name) - # default_value = default() if callable(default) else default - # # Set and return the value - # setattr(obj, self.internal_name, default_value) - - # if self._init: - # self._check_watchers(obj, self.name, default_value) - - # if not self._no_compute: - # self._compute(obj) - # value = getattr(obj, self.internal_name) return value def __set__(self, obj: Reactable, value: ReactiveType) -> None: _rich_traceback_omit = True - # Reactive._initialize_object(obj) self._initialize_reactive(obj, self.name) name = self.name @@ -236,7 +214,7 @@ class Reactive(Generic[ReactiveType]): # Check all watchers self._check_watchers(obj, name, current_value) - if not self._no_compute: + if self._run_compute: self._compute(obj) # Refresh according to descriptor flags From fb5dccf739413a0cbd12f24136115ecd9429d14b Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 17:37:02 +0000 Subject: [PATCH 303/310] fix return --- src/textual/reactive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/reactive.py b/src/textual/reactive.py index bcce2f7e0..ad4907908 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -123,7 +123,7 @@ class Reactive(Generic[ReactiveType]): """ return cls(default, layout=False, repaint=False, init=False) - def _initialize_reactive(self, obj: Reactable, name: str) -> bool: + def _initialize_reactive(self, obj: Reactable, name: str) -> None: internal_name = f"_reactive_{name}" if hasattr(obj, internal_name): # Attribute already has a value From 90f570494d3de780337f2251bf5b6f2df24d3e8f Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 17:40:42 +0000 Subject: [PATCH 304/310] docstring --- src/textual/reactive.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/textual/reactive.py b/src/textual/reactive.py index ad4907908..8a7d03d7f 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -124,6 +124,12 @@ class Reactive(Generic[ReactiveType]): return cls(default, layout=False, repaint=False, init=False) def _initialize_reactive(self, obj: Reactable, name: str) -> None: + """Initialized a reactive attribute on an object. + + Args: + obj (Reactable): An object with reactive attributes. + name (str): name of attribute. + """ internal_name = f"_reactive_{name}" if hasattr(obj, internal_name): # Attribute already has a value From 5f77cd189f5af99108dea0360e624660eae5eff2 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 18:18:12 +0000 Subject: [PATCH 305/310] fix reactive computes --- src/textual/reactive.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/textual/reactive.py b/src/textual/reactive.py index 8a7d03d7f..ad817acb9 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -196,7 +196,10 @@ class Reactive(Generic[ReactiveType]): value: ReactiveType compute_method = getattr(self, f"compute_{self.name}", None) if compute_method is not None: + old_value = getattr(obj, self.internal_name) value = getattr(obj, f"compute_{self.name}")() + setattr(obj, self.internal_name, value) + self._check_watchers(obj, self.name, old_value) else: value = getattr(obj, self.internal_name) return value @@ -298,14 +301,16 @@ class Reactive(Generic[ReactiveType]): obj (Reactable): Reactable object. """ _rich_traceback_guard = True - computes = getattr(obj, "__computes", []) - for compute in computes: + for compute in obj._reactives.keys(): try: compute_method = getattr(obj, f"compute_{compute}") except AttributeError: continue + current_value = getattr(obj, f"_reactive_{compute}") value = compute_method() setattr(obj, f"_reactive_{compute}", value) + if value != current_value: + cls._check_watchers(obj, compute, current_value) class reactive(Reactive[ReactiveType]): @@ -346,9 +351,16 @@ class var(Reactive[ReactiveType]): """ def __init__( - self, default: ReactiveType | Callable[[], ReactiveType], init: bool = True + self, + default: ReactiveType | Callable[[], ReactiveType], + init: bool = True, ) -> None: - super().__init__(default, layout=False, repaint=False, init=init) + super().__init__( + default, + layout=False, + repaint=False, + init=init, + ) def watch( @@ -376,5 +388,3 @@ def watch( if init: current_value = getattr(obj, attribute_name, None) Reactive._check_watchers(obj, attribute_name, current_value) - print(obj, attribute_name) - print(watchers) From 35cbd30fb7635e6e0ba62c4c0f6cb11c9c6e089c Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 20:50:00 +0000 Subject: [PATCH 306/310] fix superfluous scrollbars --- src/textual/app.py | 9 +++++---- src/textual/widget.py | 7 +++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/textual/app.py b/src/textual/app.py index 9b46b9e7d..e704c11fb 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1687,7 +1687,7 @@ class App(Generic[ReturnType], DOMNode): """Close all message pumps.""" # Close all screens on the stack - for screen in self._screen_stack: + for screen in reversed(self._screen_stack): if screen._running: await self._prune_node(screen) @@ -2051,8 +2051,9 @@ class App(Generic[ReturnType], DOMNode): while stack: widget = pop() - if widget.children: - yield [*widget.children, *widget._get_virtual_dom()] + children = [*widget.children, *widget._get_virtual_dom()] + if children: + yield children for child in widget.children: push(child) @@ -2121,7 +2122,7 @@ class App(Generic[ReturnType], DOMNode): for child in children: self._unregister(child) - await root._close_messages(wait=False) + await root._close_messages(wait=True) self._unregister(root) async def action_check_bindings(self, key: str) -> None: diff --git a/src/textual/widget.py b/src/textual/widget.py index 7808f1a08..5a1a00e0f 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -935,8 +935,11 @@ class Widget(DOMNode): self.show_horizontal_scrollbar = show_horizontal self.show_vertical_scrollbar = show_vertical - self.horizontal_scrollbar.display = show_horizontal - self.vertical_scrollbar.display = show_vertical + + if self._horizontal_scrollbar is not None or show_horizontal: + self.horizontal_scrollbar.display = show_horizontal + if self._vertical_scrollbar is not None or show_vertical: + self.vertical_scrollbar.display = show_vertical @property def scrollbars_enabled(self) -> tuple[bool, bool]: From 6af2b61fc78e87881b2dd0bf0b13caeab76b37c8 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 20:56:33 +0000 Subject: [PATCH 307/310] watching computed --- tests/test_reactive.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/test_reactive.py b/tests/test_reactive.py index eef5a9423..d908fa025 100644 --- a/tests/test_reactive.py +++ b/tests/test_reactive.py @@ -337,3 +337,35 @@ async def test_reactive_inheritance(): secondary.baz assert tertiary.baz == "baz" + + +async def test_watch_compute(): + """Check that watching a computed attribute works.""" + + watch_called: list[bool] = [] + + class Calculator(App): + + numbers = var("0") + show_ac = var(True) + value = var("") + + def compute_show_ac(self) -> bool: + return self.value in ("", "0") and self.numbers == "0" + + def watch_show_ac(self, show_ac: bool) -> None: + """Called when show_ac changes.""" + watch_called.append(show_ac) + + app = Calculator() + + async with app.run_test() as pilot: + assert app.show_ac is True + app.value = "1" + assert app.show_ac is False + app.value = "0" + assert app.show_ac is True + app.numbers = "123" + assert app.show_ac is False + + assert watch_called == [True, False, True, False] From 6063b0c9b22a8cf2ab2e0fc15318c15a4e1ee54a Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 21:17:19 +0000 Subject: [PATCH 308/310] remove comment [skip ci] --- tests/test_reactive.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_reactive.py b/tests/test_reactive.py index d908fa025..94ce7ac9f 100644 --- a/tests/test_reactive.py +++ b/tests/test_reactive.py @@ -218,7 +218,6 @@ async def test_validate_init_true_set_before_dom_ready(): assert validator_call_count == 1 -# @pytest.mark.xfail(reason="Compute methods not called when init=True [issue#1227]") async def test_reactive_compute_first_time_set(): class ReactiveComputeFirstTimeSet(App): number = reactive(1) From 6d57ba46233e2dbe9df14f4c309bc011170c8c25 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 13 Jan 2023 22:17:48 +0000 Subject: [PATCH 309/310] docstring fix --- src/textual/reactive.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/textual/reactive.py b/src/textual/reactive.py index ad817acb9..94a92b18a 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -47,7 +47,7 @@ class Reactive(Generic[ReactiveType]): repaint (bool, optional): Perform a repaint on change. Defaults to True. init (bool, optional): Call watchers on initialize (post mount). Defaults to False. always_update (bool, optional): Call watchers even when the new value equals the old value. Defaults to False. - compute (bool, optional): Don't run compute methods when attribute is changed. Defaults to True. + compute (bool, optional): Run compute methods when attribute is changed. Defaults to True. """ _reactives: TypeVar[dict[str, object]] = {} @@ -94,7 +94,7 @@ class Reactive(Generic[ReactiveType]): layout (bool, optional): Perform a layout on change. Defaults to False. repaint (bool, optional): Perform a repaint on change. Defaults to True. always_update (bool, optional): Call watchers even when the new value equals the old value. Defaults to False. - compute (bool, optional): Don't run compute methods when attribute is changed. Defaults to False. + compute (bool, optional): Run compute methods when attribute is changed. Defaults to True. Returns: Reactive: A Reactive instance which calls watchers or initialize. From 582aadb4b23f442d666a08785eda07eda325b794 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 15 Jan 2023 10:10:52 +0000 Subject: [PATCH 310/310] docstring [skip ci] --- src/textual/message_pump.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/message_pump.py b/src/textual/message_pump.py index fef27b304..f243b3934 100644 --- a/src/textual/message_pump.py +++ b/src/textual/message_pump.py @@ -108,7 +108,7 @@ class MessagePump(metaclass=MessagePumpMeta): @property def is_running(self) -> bool: - """bool: Check if the message pump is running (potentially processing messages)""" + """bool: Is the message pump running (potentially processing messages).""" return self._running @property

fn^zWiW%;{ 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 literal 0 HcmV?d00001 From 777fd4df2fcb13ffc43308a0bbc799eb4f09ef21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:48:04 +0000 Subject: [PATCH 067/310] Complete links reference. --- docs/styles/links/index.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/docs/styles/links/index.md b/docs/styles/links/index.md index 225126aad..475686cbd 100644 --- a/docs/styles/links/index.md +++ b/docs/styles/links/index.md @@ -2,16 +2,20 @@ Textual supports the concept of inline "links" embedded in text which trigger an action when pressed. +!!! note + + These CSS rules only target Textual action links. Internet hyperlinks are not affected by these CSS rules. + There are a number of styles which influence the appearance of these links within a widget. | Property | Description | |-------------------------|-------------------------------------------------------------| -| `link-color` | The color of link text. | -| `link-background` | The background color of link text. | -| `link-style` | The style of link text (e.g. underline). | -| `link-hover-color` | The color of link text with the cursor above it. | -| `link-hover-background` | The background color of link text with the cursor above it. | -| `link-hover-style` | The style of link text with the cursor above it. | +| [`link-color`](./link_color.md) | The color of link text. | +| [`link-background`](./link_background.md) | The background color of link text. | +| [`link-style`](./link_style.md) | The style of link text (e.g. underline). | +| [`link-hover-color`](./link_hover_color.md) | The color of link text with the cursor above it. | +| [`link-hover-background`](./link_hover_background.md) | The background color of link text with the cursor above it. | +| [`link-hover-style`](./link_hover_style.md) | The style of link text with the cursor above it. | ## Syntax @@ -24,6 +28,10 @@ link-hover-background: ; link-hover-style: ...; ``` +--8<-- "docs/styles/snippets/color_css_syntax.md" + +--8<-- "docs/styles/snippets/text_style_syntax.md" + ## Example In the example below, the first `Static` illustrates default link styling. @@ -52,6 +60,6 @@ The second `Static` uses CSS to customize the link color, background, and style. ## See Also -* An [introduction to links](../guide/actions.md#links) in the Actions guide. +* An [introduction to links](../../guide/actions.md#links) in the Actions guide. [//]: # (TODO: Links are documented twice in the guide, and one will likely be removed. Check the link above still works after that.) From 39a37219b16dcfb6a9d5427bac678f9cb66e39b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:48:23 +0000 Subject: [PATCH 068/310] Add link color reference. --- docs/styles/links/link_color.md | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/docs/styles/links/link_color.md b/docs/styles/links/link_color.md index e69de29bb..468ce4182 100644 --- a/docs/styles/links/link_color.md +++ b/docs/styles/links/link_color.md @@ -0,0 +1,63 @@ +# Link-color + +The `link-color` sets the color of the link text. + +!!! note + + `link-style` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + +## Syntax + +```sass +link-color: ; +``` + +--8<-- "docs/styles/snippets/color_css_syntax.md" + +--8<-- "docs/styles/snippets/percentage_syntax.md" + +## Example + +The example below shows some links with their color changed. +It also shows that `link-color` does not affect hyperlinks. + +=== "Output" + + ```{.textual path="docs/examples/styles/link_color.py" lines=6} + ``` + +=== "link_color.py" + + ```py hl_lines="8-9 12-13 16-17 20-21" + --8<-- "docs/examples/styles/link_color.py" + ``` + + 1. This label has an hyperlink so it won't be affected by the `link-color` rule. + 2. This label has an "action link" that can be styled with `link-color`. + 3. This label has an "action link" that can be styled with `link-color`. + 4. This label has an "action link" that can be styled with `link-color`. + +=== "link_color.css" + + ```css hl_lines="2 6 10" + --8<-- "docs/examples/styles/link_color.css" + ``` + + 1. This will only affect one of the labels because action links are the only links that this rule affects. + +## CSS + +```css +link-color: red 70%; +link-color: $accent; +``` + +## Python + +```py +widget.styles.link_color = "red 70%" +widget.styles.link_color = "$accent" + +# You can also use a `Color` object directly: +widget.styles.link_color = Color(100, 30, 173) +``` From 06604882830d979d8bd51a27210f17178462d2c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:48:40 +0000 Subject: [PATCH 069/310] Add link background reference. --- docs/styles/links/link_background.md | 63 ++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/docs/styles/links/link_background.md b/docs/styles/links/link_background.md index e69de29bb..6f067499e 100644 --- a/docs/styles/links/link_background.md +++ b/docs/styles/links/link_background.md @@ -0,0 +1,63 @@ +# Link-background + +The `link-background` sets the background color of the link. + +!!! note + + `link-background` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + +## Syntax + +```sass +link-background: ; +``` + +--8<-- "docs/styles/snippets/color_css_syntax.md" + +--8<-- "docs/styles/snippets/percentage_syntax.md" + +## Example + +The example below shows some links with their color changed. +It also shows that `link-background` does not affect hyperlinks. + +=== "Output" + + ```{.textual path="docs/examples/styles/link_background.py" lines=6} + ``` + +=== "link_background.py" + + ```py hl_lines="8-9 12-13 16-17 20-21" + --8<-- "docs/examples/styles/link_background.py" + ``` + + 1. This label has an hyperlink so it won't be affected by the `link-background` rule. + 2. This label has an "action link" that can be styled with `link-background`. + 3. This label has an "action link" that can be styled with `link-background`. + 4. This label has an "action link" that can be styled with `link-background`. + +=== "link_background.css" + + ```css hl_lines="2 6 10" + --8<-- "docs/examples/styles/link_background.css" + ``` + + 1. This will only affect one of the labels because action links are the only links that this rule affects. + +## CSS + +```css +link-background: red 70%; +link-background: $accent; +``` + +## Python + +```py +widget.styles.link_background = "red 70%" +widget.styles.link_background = "$accent" + +# You can also use a `Color` object directly: +widget.styles.link_background = Color(100, 30, 173) +``` From 81080fbc87b59a692aba91cf9ce0576461452167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:48:52 +0000 Subject: [PATCH 070/310] Add link style reference. --- docs/styles/links/link_style.md | 58 +++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/docs/styles/links/link_style.md b/docs/styles/links/link_style.md index e69de29bb..9fb1c47d8 100644 --- a/docs/styles/links/link_style.md +++ b/docs/styles/links/link_style.md @@ -0,0 +1,58 @@ +# Link-style + +The `link-style` sets the text style for the link text. + +!!! note + + `link-style` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + +## Syntax + +```sass +link-style: ; +``` + +--8<-- "docs/styles/snippets/text_style_syntax.md" + +## Example + +The example below shows some links with different styles applied to their text. +It also shows that `link-style` does not affect hyperlinks. + +=== "Output" + + ```{.textual path="docs/examples/styles/link_style.py" lines=6} + ``` + +=== "link_style.py" + + ```py hl_lines="8-9 12-13 16-17 20-21" + --8<-- "docs/examples/styles/link_style.py" + ``` + + 1. This label has an hyperlink so it won't be affected by the `link-style` rule. + 2. This label has an "action link" that can be styled with `link-style`. + 3. This label has an "action link" that can be styled with `link-style`. + 4. This label has an "action link" that can be styled with `link-style`. + +=== "link_style.css" + + ```css hl_lines="2 6 10" + --8<-- "docs/examples/styles/link_style.css" + ``` + + 1. This will only affect one of the labels because action links are the only links that this rule affects. + +## CSS + +```css +link-style: bold; +link-style: bold italic reverse; +``` + +## Python + +```py +widget.styles.link_style = "bold" +widget.styles.link_style = "bold italic reverse" +``` From 2da7773aea906c29f604036cba153b1f74a21ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:48:59 +0000 Subject: [PATCH 071/310] Add link hover style reference. --- docs/styles/links/link_hover_style.md | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/docs/styles/links/link_hover_style.md b/docs/styles/links/link_hover_style.md index e69de29bb..9a054f1e8 100644 --- a/docs/styles/links/link_hover_style.md +++ b/docs/styles/links/link_hover_style.md @@ -0,0 +1,70 @@ +# Link-hover-style + +The `link-hover-style` sets the text style for the link text when the mouse cursor is over the link. + +!!! note + + `link-hover-style` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + +## Syntax + +```sass +link-hover-style: ; +``` + +--8<-- "docs/styles/snippets/color_css_syntax.md" + +--8<-- "docs/styles/snippets/percentage_syntax.md" + +## Example + +The example below shows some links that have their colour changed when the mouse moves over it. +It also shows that `link-hover-style` does not affect hyperlinks. + +=== "Output" + + ![](./demos/link_hover_style_demo.gif) + + !!! note + + The background color also changes when the mouse moves over the links because that is the default behavior. + That can be customised by setting [`link-hover-background`](./link_hover_background.md) but we haven't done so in this example. + + !!! note + + The GIF has reduced quality to make it easier to load in the documentation. + Try running the example yourself with `textual run docs/examples/styles/link_hover_style.py`. + +=== "link_hover_style.py" + + ```py hl_lines="8-9 12-13 16-17 20-21" + --8<-- "docs/examples/styles/link_hover_style.py" + ``` + + 1. This label has an hyperlink so it won't be affected by the `link-hover-style` rule. + 2. This label has an "action link" that can be styled with `link-hover-style`. + 3. This label has an "action link" that can be styled with `link-hover-style`. + 4. This label has an "action link" that can be styled with `link-hover-style`. + +=== "link_hover_style.css" + + ```css hl_lines="2 6 10" + --8<-- "docs/examples/styles/link_hover_style.css" + ``` + + 1. This will only affect one of the labels because action links are the only links that this rule affects. + 2. The default behavior for links on hover is to change to a different text style, so we don't need to change anything if all we want is to add emphasis to the link under the mouse. + +## CSS + +```css +link-hover-style: bold; +link-hover-style: bold italic reverse; +``` + +## Python + +```py +widget.styles.link_hover_style = "bold" +widget.styles.link_hover_style = "bold italic reverse" +``` From 6436b776b0a82be5d2d29287316ab00c1daa5ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:49:08 +0000 Subject: [PATCH 072/310] Add link hover color reference. --- docs/styles/links/link_hover_color.md | 72 +++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/docs/styles/links/link_hover_color.md b/docs/styles/links/link_hover_color.md index e69de29bb..da8ce5f8e 100644 --- a/docs/styles/links/link_hover_color.md +++ b/docs/styles/links/link_hover_color.md @@ -0,0 +1,72 @@ +# Link-hover-color + +The `link-hover-color` sets the color of the link text when the mouse cursor is over the link. + +!!! note + + `link-hover-color` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + +## Syntax + +```sass +link-hover-color: ; +``` + +--8<-- "docs/styles/snippets/color_css_syntax.md" + +--8<-- "docs/styles/snippets/percentage_syntax.md" + +## Example + +The example below shows some links that have their colour changed when the mouse moves over it. +It also shows that `link-hover-color` does not affect hyperlinks. + +=== "Output" + + ![](./demos/link_hover_color_demo.gif) + + !!! note + + The background color also changes when the mouse moves over the links because that is the default behavior. + That can be customised by setting [`link-hover-background`](./link_hover_background.md) but we haven't done so in this example. + + !!! note + + The GIF has reduced quality to make it easier to load in the documentation. + Try running the example yourself with `textual run docs/examples/styles/link_hover_color.py`. + +=== "link_hover_color.py" + + ```py hl_lines="8-9 12-13 16-17 20-21" + --8<-- "docs/examples/styles/link_hover_color.py" + ``` + + 1. This label has an hyperlink so it won't be affected by the `link-hover-color` rule. + 2. This label has an "action link" that can be styled with `link-hover-color`. + 3. This label has an "action link" that can be styled with `link-hover-color`. + 4. This label has an "action link" that can be styled with `link-hover-color`. + +=== "link_hover_color.css" + + ```css hl_lines="2 6 10" + --8<-- "docs/examples/styles/link_hover_color.css" + ``` + + 1. This will only affect one of the labels because action links are the only links that this rule affects. + +## CSS + +```css +link-hover-color: red 70%; +link-hover-color: black; +``` + +## Python + +```py +widget.styles.link_hover_color = "red 70%" +widget.styles.link_hover_color = "black" + +# You can also use a `Color` object directly: +widget.styles.link_hover_color = Color(100, 30, 173) +``` From 516f3a20e328e1e8e49dab4dbc557daa01b0dabb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:49:17 +0000 Subject: [PATCH 073/310] Add link hover background reference. [skip ci] --- docs/styles/links/link_hover_background.md | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/docs/styles/links/link_hover_background.md b/docs/styles/links/link_hover_background.md index e69de29bb..89e1661c1 100644 --- a/docs/styles/links/link_hover_background.md +++ b/docs/styles/links/link_hover_background.md @@ -0,0 +1,69 @@ +# Link-hover-background + +The `link-hover-background` sets the background color of the link. + +!!! note + + `link-hover-background` only applies to "action links" as described in the [actions guide](../../guide/actions.md#links) and not to regular hyperlinks. + +## Syntax + +```sass +link-hover-background: ; +``` + +--8<-- "docs/styles/snippets/color_css_syntax.md" + +--8<-- "docs/styles/snippets/percentage_syntax.md" + +## Example + +The example below shows some links that have their background colour changed when the mouse moves over it and it shows that there is a default color for `link-hover-background`. + +It also shows that `link-hover-background` does not affect hyperlinks. + +=== "Output" + + ![](./demos/link_hover_background_demo.gif) + + !!! note + + The GIF has reduced quality to make it easier to load in the documentation. + Try running the example yourself with `textual run docs/examples/styles/link_hover_background.py`. + +=== "link_hover_background.py" + + ```py hl_lines="8-9 12-13 16-17 20-21" + --8<-- "docs/examples/styles/link_hover_background.py" + ``` + + 1. This label has an hyperlink so it won't be affected by the `link-hover-background` rule. + 2. This label has an "action link" that can be styled with `link-hover-background`. + 3. This label has an "action link" that can be styled with `link-hover-background`. + 4. This label has an "action link" that can be styled with `link-hover-background`. + +=== "link_hover_background.css" + + ```css hl_lines="2 6 10" + --8<-- "docs/examples/styles/link_hover_background.css" + ``` + + 1. This will only affect one of the labels because action links are the only links that this rule affects. + 2. The default behavior for links on hover is to change to a different background color, so we don't need to change anything if all we want is to add emphasis to the link under the mouse. + +## CSS + +```css +link-hover-background: red 70%; +link-hover-background: $accent; +``` + +## Python + +```py +widget.styles.link_hover_background = "red 70%" +widget.styles.link_hover_background = "$accent" + +# You can also use a `Color` object directly: +widget.styles.link_hover_background = Color(100, 30, 173) +``` From cd3ba5cf2e931dfd18567d48415ae01544b178e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 11:29:17 +0000 Subject: [PATCH 074/310] Add to documented text styles. --- docs/styles/snippets/text_style_syntax.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/styles/snippets/text_style_syntax.md b/docs/styles/snippets/text_style_syntax.md index acc385c46..532b83cf8 100644 --- a/docs/styles/snippets/text_style_syntax.md +++ b/docs/styles/snippets/text_style_syntax.md @@ -1,4 +1,4 @@ -The [text style](/styles/css_units/text_style) unit can be any space-separated combination of the following values: +The [text style](/styles/css_units/text_style) unit can be any _space-separated_ combination of the following values: | Value | Description | |-------------|----------------------------------------------------------------| @@ -7,3 +7,4 @@ The [text style](/styles/css_units/text_style) unit can be any space-separated c | `reverse` | reverse video text (foreground and background colors reversed) | | `underline` | underline text | | `strike` | strikethrough text | +| `none` | plain text with no styling | From 52804e95f200a2e71b56640af5f90110a47644a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 21 Dec 2022 11:29:32 +0000 Subject: [PATCH 075/310] Revise links reference. [skip ci] --- .../links/demos/link_hover_style_demo.gif | Bin 186544 -> 238790 bytes docs/styles/links/index.md | 32 +++++++++--------- docs/styles/links/link_background.md | 4 +-- docs/styles/links/link_color.md | 2 +- docs/styles/links/link_hover_background.md | 4 +-- docs/styles/links/link_hover_color.md | 2 +- docs/styles/links/link_hover_style.md | 2 +- docs/styles/links/link_style.md | 2 +- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/styles/links/demos/link_hover_style_demo.gif b/docs/styles/links/demos/link_hover_style_demo.gif index 901a5af395837e9b9b78e4985b6265c0012646cb..cc0a699c1379e10dfdc63c3097cc52ef6778bc0a 100644 GIT binary patch literal 238790 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 WLw;@fu~l>>=geUq*wLWxxBq`GGsr6d literal 186544 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