mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
more docs
This commit is contained in:
38
docs/examples/styles/scrollbar_size.py
Normal file
38
docs/examples/styles/scrollbar_size.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from textual.app import App
|
||||
from textual import layout
|
||||
from textual.widgets import Static
|
||||
|
||||
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):
|
||||
CSS = """
|
||||
Screen {
|
||||
background: white;
|
||||
color: blue 80%;
|
||||
layout: horizontal;
|
||||
}
|
||||
|
||||
Static {
|
||||
padding: 1 2;
|
||||
width: 200;
|
||||
}
|
||||
|
||||
.panel {
|
||||
scrollbar-size: 10 4;
|
||||
padding: 1 2;
|
||||
}
|
||||
"""
|
||||
|
||||
def compose(self):
|
||||
yield layout.Vertical(Static(TEXT * 5), classes="panel")
|
||||
|
||||
|
||||
app = ScrollbarApp()
|
||||
49
docs/examples/styles/scrollbars.py
Normal file
49
docs/examples/styles/scrollbars.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from textual.app import App
|
||||
from textual import layout
|
||||
from textual.widgets import Static
|
||||
|
||||
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):
|
||||
CSS = """
|
||||
|
||||
Screen {
|
||||
background: #212121;
|
||||
color: white 80%;
|
||||
layout: horizontal;
|
||||
}
|
||||
|
||||
Static {
|
||||
padding: 1 2;
|
||||
}
|
||||
|
||||
.panel1 {
|
||||
width: 1fr;
|
||||
scrollbar-color: green;
|
||||
scrollbar-background: #bbb;
|
||||
padding: 1 2;
|
||||
}
|
||||
|
||||
.panel2 {
|
||||
width: 1fr;
|
||||
scrollbar-color: yellow;
|
||||
scrollbar-background: purple;
|
||||
padding: 1 2;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
def compose(self):
|
||||
yield layout.Vertical(Static(TEXT * 5), classes="panel1")
|
||||
yield layout.Vertical(Static(TEXT * 5), classes="panel2")
|
||||
|
||||
|
||||
app = ScrollbarApp()
|
||||
@@ -1,10 +1,10 @@
|
||||
# Height
|
||||
|
||||
The `height` style 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. 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.
|
||||
|
||||
## Example
|
||||
|
||||
=== "width.py"
|
||||
=== "height.py"
|
||||
|
||||
```python
|
||||
--8<-- "docs/examples/styles/height.py"
|
||||
|
||||
@@ -42,9 +42,9 @@ overflow-x: scroll;
|
||||
|
||||
```python
|
||||
# Hide the vertical scrollbar
|
||||
self.styles.overflow_y = "hidden"
|
||||
widget.styles.overflow_y = "hidden"
|
||||
|
||||
# Always show the horizontal scrollbar
|
||||
self.styles.overflow_x = "scroll"
|
||||
widget.styles.overflow_x = "scroll"
|
||||
|
||||
```
|
||||
|
||||
43
docs/styles/scrollbar.md
Normal file
43
docs/styles/scrollbar.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Scrollbar colors
|
||||
|
||||
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-color-active` | Scrollbar background when the thumb is being dragged |
|
||||
|
||||
## Example
|
||||
|
||||
In this example we have two panels, with different scrollbar colors set for each.
|
||||
|
||||
=== "scrollbars.py"
|
||||
|
||||
```python
|
||||
--8<-- "docs/examples/styles/scrollbars.py"
|
||||
```
|
||||
|
||||
=== "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"
|
||||
```
|
||||
37
docs/styles/scrollbar_size.md
Normal file
37
docs/styles/scrollbar_size.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 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`.
|
||||
|
||||
## Example
|
||||
|
||||
In this example we modify the size of the widgets scrollbar to be _much_ larger than usual.
|
||||
|
||||
=== "scrollbar_size.py"
|
||||
|
||||
```python
|
||||
--8<-- "docs/examples/styles/scrollbar_size.py"
|
||||
```
|
||||
|
||||
=== "Output"
|
||||
|
||||
```{.textual path="docs/examples/styles/scrollbar_size.py"}
|
||||
```
|
||||
|
||||
## CSS
|
||||
|
||||
```sass
|
||||
/* Set horizontal scrollbar to 10, and vertical scrollbar to 4 */
|
||||
Widget {
|
||||
scrollbar-size: 10 4;
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
```python
|
||||
# Set horizontal scrollbar to 10, and vertical scrollbar to 4
|
||||
widget.styles.horizontal_scrollbar = 10
|
||||
widget.styles.vertical_scrollbar = 10
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
# Width
|
||||
|
||||
The `width` style 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. 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.
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ nav:
|
||||
- "styles/outline.md"
|
||||
- "styles/overflow.md"
|
||||
- "styles/padding.md"
|
||||
- "styles/scrollbar.md"
|
||||
- "styles/scrollbar_size.md"
|
||||
- "styles/text_style.md"
|
||||
- "styles/tint.md"
|
||||
- "styles/visibility.md"
|
||||
|
||||
@@ -100,7 +100,7 @@ Tweet {
|
||||
|
||||
|
||||
.scrollable {
|
||||
|
||||
overflow-x: auto;
|
||||
overflow-y: scroll;
|
||||
margin: 1 2;
|
||||
height: 20;
|
||||
|
||||
@@ -9,39 +9,51 @@ from textual.widget import Widget
|
||||
from textual.widgets import Static, DataTable
|
||||
|
||||
CODE = '''
|
||||
class Offset(NamedTuple):
|
||||
"""A point defined by x and y coordinates."""
|
||||
from __future__ import annotations
|
||||
|
||||
x: int = 0
|
||||
y: int = 0
|
||||
from typing import Iterable, TypeVar
|
||||
|
||||
@property
|
||||
def is_origin(self) -> bool:
|
||||
"""Check if the point is at the origin (0, 0)"""
|
||||
return self == (0, 0)
|
||||
T = TypeVar("T")
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
return self != (0, 0)
|
||||
|
||||
def __add__(self, other: object) -> Offset:
|
||||
if isinstance(other, tuple):
|
||||
_x, _y = self
|
||||
x, y = other
|
||||
return Offset(_x + x, _y + y)
|
||||
return NotImplemented
|
||||
def loop_first(values: Iterable[T]) -> Iterable[tuple[bool, T]]:
|
||||
"""Iterate and generate a tuple with a flag for first value."""
|
||||
iter_values = iter(values)
|
||||
try:
|
||||
value = next(iter_values)
|
||||
except StopIteration:
|
||||
return
|
||||
yield True, value
|
||||
for value in iter_values:
|
||||
yield False, value
|
||||
|
||||
def __sub__(self, other: object) -> Offset:
|
||||
if isinstance(other, tuple):
|
||||
_x, _y = self
|
||||
x, y = other
|
||||
return Offset(_x - x, _y - y)
|
||||
return NotImplemented
|
||||
|
||||
def __mul__(self, other: object) -> Offset:
|
||||
if isinstance(other, (float, int)):
|
||||
x, y = self
|
||||
return Offset(int(x * other), int(y * other))
|
||||
return NotImplemented
|
||||
def loop_last(values: Iterable[T]) -> Iterable[tuple[bool, T]]:
|
||||
"""Iterate and generate a tuple with a flag for last value."""
|
||||
iter_values = iter(values)
|
||||
try:
|
||||
previous_value = next(iter_values)
|
||||
except StopIteration:
|
||||
return
|
||||
for value in iter_values:
|
||||
yield False, previous_value
|
||||
previous_value = value
|
||||
yield True, previous_value
|
||||
|
||||
|
||||
def loop_first_last(values: Iterable[T]) -> Iterable[tuple[bool, bool, T]]:
|
||||
"""Iterate and generate a tuple with a flag for first and last value."""
|
||||
iter_values = iter(values)
|
||||
try:
|
||||
previous_value = next(iter_values)
|
||||
except StopIteration:
|
||||
return
|
||||
first = True
|
||||
for value in iter_values:
|
||||
yield first, False, previous_value
|
||||
first = False
|
||||
previous_value = value
|
||||
yield first, True, previous_value
|
||||
'''
|
||||
|
||||
|
||||
@@ -111,7 +123,10 @@ class BasicApp(App, css_path="basic.css"):
|
||||
yield from (
|
||||
Tweet(TweetBody()),
|
||||
Widget(
|
||||
Static(Syntax(CODE, "python"), classes="code"),
|
||||
Static(
|
||||
Syntax(CODE, "python", line_numbers=True, indent_guides=True),
|
||||
classes="code",
|
||||
),
|
||||
classes="scrollable",
|
||||
),
|
||||
table,
|
||||
|
||||
@@ -443,52 +443,6 @@ def layout_property_help_text(property_name: str, context: StylingContext) -> He
|
||||
)
|
||||
|
||||
|
||||
def docks_property_help_text(property_name: str, context: StylingContext) -> HelpText:
|
||||
"""Help text to show when the user supplies an invalid value for docks.
|
||||
|
||||
Args:
|
||||
property_name (str): The name of the property
|
||||
context (StylingContext | None): The context the property is being used in.
|
||||
|
||||
Returns:
|
||||
HelpText: Renderable for displaying the help text for this property
|
||||
"""
|
||||
property_name = _contextualize_property_name(property_name, context)
|
||||
return HelpText(
|
||||
summary=f"Invalid value for [i]{property_name}[/] property",
|
||||
bullets=[
|
||||
*ContextSpecificBullets(
|
||||
inline=[
|
||||
Bullet(
|
||||
f"The [i]{property_name}[/] property expects an iterable of DockGroups",
|
||||
examples=[
|
||||
Example(
|
||||
f"widget.styles.{property_name} = [DockGroup(...), DockGroup(...)]"
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
css=[
|
||||
Bullet(
|
||||
f"The [i]{property_name}[/] property expects a value of the form <name>=<edge>/<zindex>...",
|
||||
examples=[
|
||||
Example(
|
||||
f"{property_name}: lhs=left/2; [dim]# dock named [u]lhs[/], on [u]left[/] edge, with z-index [u]2[/]"
|
||||
),
|
||||
Example(
|
||||
f"{property_name}: top=top/3 rhs=right/2; [dim]# declaring multiple docks"
|
||||
),
|
||||
],
|
||||
),
|
||||
Bullet("<name> can be any string you want"),
|
||||
Bullet(f"<edge> must be one of {friendly_list(VALID_EDGE)}"),
|
||||
Bullet(f"<zindex> must be an integer"),
|
||||
],
|
||||
).get_by_context(context)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def dock_property_help_text(property_name: str, context: StylingContext) -> HelpText:
|
||||
"""Help text to show when the user supplies an invalid value for dock.
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ from ._help_text import (
|
||||
string_enum_help_text,
|
||||
border_property_help_text,
|
||||
layout_property_help_text,
|
||||
docks_property_help_text,
|
||||
dock_property_help_text,
|
||||
fractional_property_help_text,
|
||||
align_help_text,
|
||||
|
||||
@@ -9,8 +9,6 @@ from textual.css._help_text import (
|
||||
color_property_help_text,
|
||||
border_property_help_text,
|
||||
layout_property_help_text,
|
||||
docks_property_help_text,
|
||||
dock_property_help_text,
|
||||
fractional_property_help_text,
|
||||
offset_property_help_text,
|
||||
align_help_text,
|
||||
@@ -92,12 +90,6 @@ def test_layout_property_help_text(styling_context):
|
||||
assert "layout" in rendered
|
||||
|
||||
|
||||
def test_docks_property_help_text(styling_context):
|
||||
rendered = render(docks_property_help_text("docks", styling_context))
|
||||
assert "Invalid value for" in rendered
|
||||
assert "docks" in rendered
|
||||
|
||||
|
||||
def test_fractional_property_help_text(styling_context):
|
||||
rendered = render(fractional_property_help_text("opacity", styling_context))
|
||||
assert "Invalid value for" in rendered
|
||||
|
||||
Reference in New Issue
Block a user