Skip to content

Commit f4752f7

Browse files
committed
Implement widgets command
1 parent 7717c49 commit f4752f7

File tree

15 files changed

+719
-1
lines changed

15 files changed

+719
-1
lines changed

src/textual_dev/cli.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ def colors() -> None:
219219
ColorsApp().run()
220220

221221

222+
@run.command("widgets")
223+
def widgets() -> None:
224+
"""Explore possible example_widgets."""
225+
from textual_dev.previews import WidgetsApp
226+
227+
WidgetsApp().run()
228+
229+
222230
@run.command("keys")
223231
def keys() -> None:
224232
"""Show key events."""

src/textual_dev/previews/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
from .colors import ColorsApp
55
from .easing import EasingApp
66
from .keys import KeysApp
7+
from .widgets import WidgetsApp
78

8-
__all__ = ["BorderApp", "ColorsApp", "EasingApp", "KeysApp"]
9+
__all__ = ["BorderApp", "ColorsApp", "EasingApp", "KeysApp", "WidgetsApp"]
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import random
2+
from statistics import mean
3+
4+
from textual.app import ComposeResult
5+
from textual.containers import Container
6+
from textual.widgets import (
7+
DirectoryTree,
8+
Footer,
9+
Header,
10+
Input,
11+
Label,
12+
ListView,
13+
ListItem,
14+
LoadingIndicator,
15+
Sparkline,
16+
Static,
17+
Tree,
18+
)
19+
20+
from .button import button_example
21+
from .checkbox import checkbox_example
22+
from .data_table import data_table_example
23+
from .markdown import markdown_viewer_example, markdown_example
24+
from .option_list import option_list_example
25+
from .placeholder import placeholder_example
26+
from .pretty import pretty_example
27+
from .radio import radio_button_example, radio_set_example
28+
from .select import select_example, selection_list_example
29+
from .switch import switch_example
30+
31+
32+
def directory_tree_example(id: str) -> ComposeResult:
33+
yield Container(DirectoryTree("./"), id=id)
34+
35+
36+
def footer_example(id: str) -> ComposeResult:
37+
yield Container(Footer(), id=id)
38+
39+
40+
def header_example(id: str) -> ComposeResult:
41+
yield Container(Header(), id=id)
42+
43+
44+
def input_example(id: str) -> ComposeResult:
45+
yield Container(
46+
Input(placeholder="First Name"), Input(placeholder="Last Name"), id=id
47+
)
48+
49+
50+
def label_example(id: str) -> ComposeResult:
51+
yield Container(Label("Hello, world!"), id=id)
52+
53+
54+
def list_item_example(id: str) -> ComposeResult:
55+
yield Container(
56+
ListView(
57+
ListItem(Label("One")),
58+
ListItem(Label("Two")),
59+
ListItem(Label("Three")),
60+
),
61+
id=id,
62+
)
63+
64+
yield Footer()
65+
66+
67+
def loading_example(id: str) -> ComposeResult:
68+
yield Container(LoadingIndicator(), id=id)
69+
70+
71+
def sparkline_example(id: str) -> ComposeResult:
72+
data = [random.expovariate(1 / 3) for _ in range(1000)]
73+
74+
yield Container(
75+
Sparkline(data, summary_function=max),
76+
Sparkline(data, summary_function=mean),
77+
Sparkline(data, summary_function=min),
78+
id=id,
79+
)
80+
81+
82+
def static_example(id: str) -> ComposeResult:
83+
yield Container(Static("Hello, world!"), id=id)
84+
85+
86+
def tree_example(id: str) -> ComposeResult:
87+
tree: Tree[dict] = Tree("Dune")
88+
tree.root.expand()
89+
characters = tree.root.add("Characters", expand=True)
90+
characters.add_leaf("Paul")
91+
characters.add_leaf("Jessica")
92+
characters.add_leaf("Chani")
93+
yield Container(tree, id=id)
94+
95+
96+
__all__ = [
97+
"button_example",
98+
"checkbox_example",
99+
"data_table_example",
100+
"directory_tree_example",
101+
"footer_example",
102+
"header_example",
103+
"input_example",
104+
"label_example",
105+
"list_item_example",
106+
"loading_example",
107+
"markdown_viewer_example",
108+
"markdown_example",
109+
"option_list_example",
110+
"placeholder_example",
111+
"pretty_example",
112+
"radio_button_example",
113+
"radio_set_example",
114+
"select_example",
115+
"selection_list_example",
116+
"sparkline_example",
117+
"static_example",
118+
"switch_example",
119+
"tree_example",
120+
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from textual.app import ComposeResult
2+
from textual.containers import Horizontal, VerticalScroll
3+
from textual.widgets import Static, Button
4+
5+
6+
def button_example(id: str) -> ComposeResult:
7+
yield Horizontal(
8+
VerticalScroll(
9+
Static("Standard Buttons", classes="header"),
10+
Button("Default"),
11+
Button("Primary!", variant="primary"),
12+
Button.success("Success!"),
13+
Button.warning("Warning!"),
14+
Button.error("Error!"),
15+
),
16+
VerticalScroll(
17+
Static("Disabled Buttons", classes="header"),
18+
Button("Default", disabled=True),
19+
Button("Primary!", variant="primary", disabled=True),
20+
Button.success("Success!", disabled=True),
21+
Button.warning("Warning!", disabled=True),
22+
Button.error("Error!", disabled=True),
23+
),
24+
id=id,
25+
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from textual.app import ComposeResult
2+
from textual.containers import VerticalScroll, Container
3+
from textual.widgets import Checkbox
4+
5+
6+
def checkbox_example(id: str) -> ComposeResult:
7+
yield Container(
8+
VerticalScroll(
9+
Checkbox("Arrakis :sweat:"),
10+
Checkbox("Caladan"),
11+
Checkbox("Chusuk"),
12+
Checkbox("[b]Giedi Prime[/b]"),
13+
Checkbox("[magenta]Ginaz[/]"),
14+
Checkbox("Grumman", True),
15+
Checkbox("Kaitain", id="initial_focus"),
16+
Checkbox("Novebruns", True),
17+
),
18+
id=id,
19+
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from textual.containers import Container
2+
from textual.app import ComposeResult
3+
from textual.widgets import DataTable
4+
5+
ROWS = [
6+
("lane", "swimmer", "country", "time"),
7+
(4, "Joseph Schooling", "Singapore", 50.39),
8+
(2, "Michael Phelps", "United States", 51.14),
9+
(5, "Chad le Clos", "South Africa", 51.14),
10+
(6, "László Cseh", "Hungary", 51.14),
11+
(3, "Li Zhuhao", "China", 51.26),
12+
(8, "Mehdy Metella", "France", 51.58),
13+
(7, "Tom Shields", "United States", 51.73),
14+
(1, "Aleksandr Sadovnikov", "Russia", 51.84),
15+
(10, "Darren Burns", "Scotland", 51.84),
16+
]
17+
18+
19+
def data_table_example(id: str) -> ComposeResult:
20+
table = DataTable()
21+
table.add_columns(*ROWS[0])
22+
table.add_rows(ROWS[1:])
23+
24+
yield Container(table, id=id)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from textual.containers import Container
2+
from textual.app import ComposeResult
3+
from textual.widgets import MarkdownViewer, Markdown
4+
5+
EXAMPLE_MARKDOWN_VIEWER = """\
6+
# Markdown Viewer
7+
8+
This is an example of Textual's `MarkdownViewer` widget.
9+
10+
11+
## Features
12+
13+
Markdown syntax and extensions are supported.
14+
15+
- Typography *emphasis*, **strong**, `inline code` etc.
16+
- Headers
17+
- Lists (bullet and ordered)
18+
- Syntax highlighted code blocks
19+
- Tables!
20+
21+
## Tables
22+
23+
Tables are displayed in a DataTable widget.
24+
25+
| Name | Type | Default | Description |
26+
| --------------- | ------ | ------- | ---------------------------------- |
27+
| `show_header` | `bool` | `True` | Show the table header |
28+
| `fixed_rows` | `int` | `0` | Number of fixed rows |
29+
| `fixed_columns` | `int` | `0` | Number of fixed columns |
30+
| `zebra_stripes` | `bool` | `False` | Display alternating colors on rows |
31+
| `header_height` | `int` | `1` | Height of header row |
32+
| `show_cursor` | `bool` | `True` | Show a cell cursor |
33+
34+
35+
## Code Blocks
36+
37+
Code blocks are syntax highlighted, with guidelines.
38+
39+
```python
40+
class ListViewExample(App):
41+
def compose(self) -> ComposeResult:
42+
yield ListView(
43+
ListItem(Label("One")),
44+
ListItem(Label("Two")),
45+
ListItem(Label("Three")),
46+
)
47+
yield Footer()
48+
```
49+
"""
50+
51+
EXAMPLE_MARKDOWN = """\
52+
# Markdown Document
53+
54+
This is an example of Textual's `Markdown` widget.
55+
56+
## Features
57+
58+
Markdown syntax and extensions are supported.
59+
60+
- Typography *emphasis*, **strong**, `inline code` etc.
61+
- Headers
62+
- Lists (bullet and ordered)
63+
- Syntax highlighted code blocks
64+
- Tables!
65+
"""
66+
67+
68+
def markdown_viewer_example(id: str) -> ComposeResult:
69+
yield Container(
70+
MarkdownViewer(EXAMPLE_MARKDOWN_VIEWER, show_table_of_contents=True), id=id
71+
)
72+
73+
74+
def markdown_example(id: str) -> ComposeResult:
75+
yield Container(Markdown(EXAMPLE_MARKDOWN), id=id)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from textual.containers import Container
2+
from textual.app import ComposeResult
3+
from textual.widgets import Footer, Header, OptionList
4+
from textual.widgets.option_list import Option, Separator
5+
6+
7+
def option_list_example(id: str) -> ComposeResult:
8+
yield Container(
9+
Header(),
10+
OptionList(
11+
Option("Aerilon", id="aer"),
12+
Option("Aquaria", id="aqu"),
13+
Separator(),
14+
Option("Canceron", id="can"),
15+
Option("Caprica", id="cap", disabled=True),
16+
Separator(),
17+
Option("Gemenon", id="gem"),
18+
Separator(),
19+
Option("Leonis", id="leo"),
20+
Option("Libran", id="lib"),
21+
Separator(),
22+
Option("Picon", id="pic"),
23+
Separator(),
24+
Option("Sagittaron", id="sag"),
25+
Option("Scorpia", id="sco"),
26+
Separator(),
27+
Option("Tauron", id="tau"),
28+
Separator(),
29+
Option("Virgon", id="vir"),
30+
),
31+
Footer(),
32+
id=id,
33+
)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from textual.app import ComposeResult
2+
from textual.containers import Container, Horizontal, VerticalScroll
3+
from textual.widgets import Placeholder
4+
5+
6+
def placeholder_example(id: str) -> ComposeResult:
7+
yield Container(
8+
VerticalScroll(
9+
Container(
10+
Placeholder("This is a custom label for p1.", id="p1"),
11+
Placeholder("Placeholder p2 here!", id="p2"),
12+
Placeholder(id="p3"),
13+
Placeholder(id="p4"),
14+
Placeholder(id="p5"),
15+
Placeholder(),
16+
Horizontal(
17+
Placeholder(variant="size", id="col1"),
18+
Placeholder(variant="text", id="col2"),
19+
Placeholder(variant="size", id="col3"),
20+
id="c1",
21+
),
22+
id="bot",
23+
),
24+
Container(
25+
Placeholder(variant="text", id="left"),
26+
Placeholder(variant="size", id="topright"),
27+
Placeholder(variant="text", id="botright"),
28+
id="top",
29+
),
30+
id="content",
31+
),
32+
id=id,
33+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from textual.containers import Container
2+
from textual.app import ComposeResult
3+
from textual.widgets import Pretty
4+
5+
DATA = {
6+
"title": "Back to the Future",
7+
"releaseYear": 1985,
8+
"director": "Robert Zemeckis",
9+
"genre": "Adventure, Comedy, Sci-Fi",
10+
"cast": [
11+
{"actor": "Michael J. Fox", "character": "Marty McFly"},
12+
{"actor": "Christopher Lloyd", "character": "Dr. Emmett Brown"},
13+
],
14+
}
15+
16+
17+
def pretty_example(id: str) -> ComposeResult:
18+
yield Container(Pretty(DATA), id=id)

0 commit comments

Comments
 (0)