mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Merge branch 'css' of github.com:willmcgugan/textual into docs-widgets
This commit is contained in:
@@ -2,18 +2,12 @@ Screen {
|
||||
background: $panel;
|
||||
}
|
||||
|
||||
TextInput {
|
||||
dock: top;
|
||||
border: tall $background;
|
||||
Input {
|
||||
dock: top;
|
||||
width: 100%;
|
||||
height: 1;
|
||||
padding: 0 1;
|
||||
margin: 1 1 0 1;
|
||||
background: $boost;
|
||||
}
|
||||
|
||||
TextInput:focus {
|
||||
border: tall $accent;
|
||||
margin: 1 1 0 1;
|
||||
}
|
||||
|
||||
#results {
|
||||
|
||||
13
docs/examples/guide/reactivity/computed01.css
Normal file
13
docs/examples/guide/reactivity/computed01.css
Normal file
@@ -0,0 +1,13 @@
|
||||
#color-inputs {
|
||||
dock: top;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
Input {
|
||||
width: 1fr;
|
||||
}
|
||||
|
||||
#color {
|
||||
height: 100%;
|
||||
border: tall $secondary;
|
||||
}
|
||||
47
docs/examples/guide/reactivity/computed01.py
Normal file
47
docs/examples/guide/reactivity/computed01.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.color import Color
|
||||
from textual.containers import Horizontal
|
||||
from textual.reactive import reactive
|
||||
from textual.widgets import Input, Static
|
||||
|
||||
|
||||
class ComputedApp(App):
|
||||
CSS_PATH = "computed01.css"
|
||||
|
||||
red = reactive(0)
|
||||
green = reactive(0)
|
||||
blue = reactive(0)
|
||||
color = reactive(Color.parse("transparent"))
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Horizontal(
|
||||
Input("0", placeholder="Enter red 0-255", id="red"),
|
||||
Input("0", placeholder="Enter green 0-255", id="green"),
|
||||
Input("0", placeholder="Enter blue 0-255", id="blue"),
|
||||
id="color-inputs",
|
||||
)
|
||||
yield Static(id="color")
|
||||
|
||||
def compute_color(self) -> Color: # (1)!
|
||||
return Color(self.red, self.green, self.blue).clamped
|
||||
|
||||
def watch_color(self, color: Color) -> None: # (2)
|
||||
self.query_one("#color").styles.background = color
|
||||
|
||||
def on_input_changed(self, event: Input.Changed) -> None:
|
||||
try:
|
||||
component = int(event.value)
|
||||
except ValueError:
|
||||
self.bell()
|
||||
else:
|
||||
if event.input.id == "red":
|
||||
self.red = component
|
||||
elif event.input.id == "green":
|
||||
self.green = component
|
||||
else:
|
||||
self.blue = component
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = ComputedApp()
|
||||
app.run()
|
||||
9
docs/examples/guide/reactivity/refresh01.css
Normal file
9
docs/examples/guide/reactivity/refresh01.css
Normal file
@@ -0,0 +1,9 @@
|
||||
Input {
|
||||
dock: top;
|
||||
margin-top: 1;
|
||||
}
|
||||
|
||||
Name {
|
||||
height: 100%;
|
||||
content-align: center middle;
|
||||
}
|
||||
29
docs/examples/guide/reactivity/refresh01.py
Normal file
29
docs/examples/guide/reactivity/refresh01.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.reactive import reactive
|
||||
from textual.widget import Widget
|
||||
from textual.widgets import Input
|
||||
|
||||
|
||||
class Name(Widget):
|
||||
"""Generates a greeting."""
|
||||
|
||||
who = reactive("name")
|
||||
|
||||
def render(self) -> str:
|
||||
return f"Hello, {self.who}!"
|
||||
|
||||
|
||||
class WatchApp(App):
|
||||
CSS_PATH = "refresh01.css"
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Input(placeholder="Enter your name")
|
||||
yield Name()
|
||||
|
||||
def on_input_changed(self, event: Input.Changed) -> None:
|
||||
self.query_one(Name).who = event.value
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = WatchApp()
|
||||
app.run()
|
||||
10
docs/examples/guide/reactivity/refresh02.css
Normal file
10
docs/examples/guide/reactivity/refresh02.css
Normal file
@@ -0,0 +1,10 @@
|
||||
Input {
|
||||
dock: top;
|
||||
margin-top: 1;
|
||||
}
|
||||
|
||||
Name {
|
||||
width: auto;
|
||||
height: auto;
|
||||
border: heavy $secondary;
|
||||
}
|
||||
29
docs/examples/guide/reactivity/refresh02.py
Normal file
29
docs/examples/guide/reactivity/refresh02.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.reactive import reactive
|
||||
from textual.widget import Widget
|
||||
from textual.widgets import Input
|
||||
|
||||
|
||||
class Name(Widget):
|
||||
"""Generates a greeting."""
|
||||
|
||||
who = reactive("name", layout=True) # (1)!
|
||||
|
||||
def render(self) -> str:
|
||||
return f"Hello, {self.who}!"
|
||||
|
||||
|
||||
class WatchApp(App):
|
||||
CSS_PATH = "refresh02.css"
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Input(placeholder="Enter your name")
|
||||
yield Name()
|
||||
|
||||
def on_input_changed(self, event: Input.Changed) -> None:
|
||||
self.query_one(Name).who = event.value
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = WatchApp()
|
||||
app.run()
|
||||
4
docs/examples/guide/reactivity/validate01.css
Normal file
4
docs/examples/guide/reactivity/validate01.css
Normal file
@@ -0,0 +1,4 @@
|
||||
#buttons {
|
||||
dock: top;
|
||||
height: auto;
|
||||
}
|
||||
38
docs/examples/guide/reactivity/validate01.py
Normal file
38
docs/examples/guide/reactivity/validate01.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Horizontal
|
||||
from textual.reactive import reactive
|
||||
from textual.widgets import Button, TextLog
|
||||
|
||||
|
||||
class ValidateApp(App):
|
||||
CSS_PATH = "validate01.css"
|
||||
|
||||
count = reactive(0)
|
||||
|
||||
def validate_count(self, count: int) -> int:
|
||||
"""Validate value."""
|
||||
if count < 0:
|
||||
count = 0
|
||||
elif count > 10:
|
||||
count = 10
|
||||
return count
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Horizontal(
|
||||
Button("+1", id="plus", variant="success"),
|
||||
Button("-1", id="minus", variant="error"),
|
||||
id="buttons",
|
||||
)
|
||||
yield TextLog(highlight=True)
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
if event.button.id == "plus":
|
||||
self.count += 1
|
||||
else:
|
||||
self.count -= 1
|
||||
self.query_one(TextLog).write(f"{self.count=}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = ValidateApp()
|
||||
app.run()
|
||||
21
docs/examples/guide/reactivity/watch01.css
Normal file
21
docs/examples/guide/reactivity/watch01.css
Normal file
@@ -0,0 +1,21 @@
|
||||
Input {
|
||||
dock: top;
|
||||
margin-top: 1;
|
||||
}
|
||||
|
||||
#colors {
|
||||
grid-size: 2 1;
|
||||
grid-gutter: 2 4;
|
||||
grid-columns: 1fr;
|
||||
margin: 0 1;
|
||||
}
|
||||
|
||||
#old {
|
||||
height: 100%;
|
||||
border: wide $secondary;
|
||||
}
|
||||
|
||||
#new {
|
||||
height: 100%;
|
||||
border: wide $secondary;
|
||||
}
|
||||
33
docs/examples/guide/reactivity/watch01.py
Normal file
33
docs/examples/guide/reactivity/watch01.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.color import Color, ColorParseError
|
||||
from textual.containers import Grid
|
||||
from textual.reactive import reactive
|
||||
from textual.widgets import Input, Static
|
||||
|
||||
|
||||
class WatchApp(App):
|
||||
CSS_PATH = "watch01.css"
|
||||
|
||||
color = reactive(Color.parse("transparent")) # (1)!
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Input(placeholder="Enter a color")
|
||||
yield Grid(Static(id="old"), Static(id="new"), id="colors")
|
||||
|
||||
def watch_color(self, old_color: Color, new_color: Color) -> None: # (2)!
|
||||
self.query_one("#old").styles.background = old_color
|
||||
self.query_one("#new").styles.background = new_color
|
||||
|
||||
def on_input_submitted(self, event: Input.Submitted) -> None:
|
||||
try:
|
||||
input_color = Color.parse(event.value)
|
||||
except ColorParseError:
|
||||
pass
|
||||
else:
|
||||
self.query_one(Input).value = ""
|
||||
self.color = input_color # (3)!
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = WatchApp()
|
||||
app.run()
|
||||
Reference in New Issue
Block a user