Merge pull request #819 from Textualize/docs-widgets

Document widgets
This commit is contained in:
Will McGugan
2022-10-05 09:27:00 +01:00
committed by GitHub
26 changed files with 265 additions and 39 deletions

View File

@@ -8,7 +8,7 @@ The `Click` event is sent to a widget when the user clicks a mouse button.
## Attributes
| attribute | type | purpose |
| ---------- | ---- | ----------------------------------------- |
|------------|------|-------------------------------------------|
| `x` | int | Mouse x coordinate, relative to Widget |
| `y` | int | Mouse y coordinate, relative to Widget |
| `delta_x` | int | Change in x since last mouse event |

View File

@@ -8,7 +8,7 @@ The `MouseMove` event is sent to a widget when the mouse pointer is moved over a
## Attributes
| attribute | type | purpose |
| ---------- | ---- | ----------------------------------------- |
|------------|------|-------------------------------------------|
| `x` | int | Mouse x coordinate, relative to Widget |
| `y` | int | Mouse y coordinate, relative to Widget |
| `delta_x` | int | Change in x since last mouse event |

View File

@@ -8,7 +8,7 @@ The `MouseRelease` event is sent to a widget when it is no longer receiving mous
## Attributes
| attribute | type | purpose |
| ---------------- | ------ | --------------------------------------------- |
|------------------|--------|-----------------------------------------------|
| `mouse_position` | Offset | Mouse coordinates when the mouse was released |
## Code

View File

@@ -8,7 +8,7 @@ The `MouseScrollDown` event is sent to a widget when the scroll wheel (or trackp
## Attributes
| attribute | type | purpose |
| --------- | ---- | -------------------------------------- |
|-----------|------|----------------------------------------|
| `x` | int | Mouse x coordinate, relative to Widget |
| `y` | int | Mouse y coordinate, relative to Widget |

View File

@@ -8,7 +8,7 @@ The `MouseScrollUp` event is sent to a widget when the scroll wheel (or trackpad
## Attributes
| attribute | type | purpose |
| --------- | ---- | -------------------------------------- |
|-----------|------|----------------------------------------|
| `x` | int | Mouse x coordinate, relative to Widget |
| `y` | int | Mouse y coordinate, relative to Widget |

View File

@@ -8,7 +8,7 @@ The `MouseUp` event is sent to a widget when the user releases a mouse button.
## Attributes
| attribute | type | purpose |
| ---------- | ---- | ----------------------------------------- |
|------------|------|-------------------------------------------|
| `x` | int | Mouse x coordinate, relative to Widget |
| `y` | int | Mouse y coordinate, relative to Widget |
| `delta_x` | int | Change in x since last mouse event |

View File

@@ -8,7 +8,7 @@ The `Paste` event is sent to a widget when the user pastes text.
## Attributes
| attribute | type | purpose |
| --------- | ---- | ------------------------ |
|-----------|------|--------------------------|
| `text` | str | The text that was pasted |
## Code

View File

@@ -8,7 +8,7 @@ The `Resize` event is sent to a widget when its size changes and when it is firs
## Attributes
| attribute | type | purpose |
| ---------------- | ---- | ------------------------------------------------ |
|------------------|------|--------------------------------------------------|
| `size` | Size | The new size of the Widget |
| `virtual_size` | Size | The virtual size (scrollable area) of the Widget |
| `container_size` | Size | The size of the container (parent widget) |

View File

@@ -0,0 +1,15 @@
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.widgets import Footer
class FooterApp(App):
BINDINGS = [Binding(key="q", action="quit", description="Quit the app")]
def compose(self) -> ComposeResult:
yield Footer()
if __name__ == "__main__":
app = FooterApp()
app.run()

View File

@@ -0,0 +1,12 @@
from textual.app import App, ComposeResult
from textual.widgets import Header
class HeaderApp(App):
def compose(self) -> ComposeResult:
yield Header()
if __name__ == "__main__":
app = HeaderApp()
app.run()

View File

@@ -0,0 +1,13 @@
from textual.app import App, ComposeResult
from textual.widgets import Input
class InputApp(App):
def compose(self) -> ComposeResult:
yield Input(placeholder="First Name")
yield Input(placeholder="Last Name")
if __name__ == "__main__":
app = InputApp()
app.run()

View File

@@ -0,0 +1,12 @@
from textual.app import App, ComposeResult
from textual.widgets import Static
class StaticApp(App):
def compose(self) -> ComposeResult:
yield Static("Hello, world!")
if __name__ == "__main__":
app = StaticApp()
app.run()

1
docs/reference/footer.md Normal file
View File

@@ -0,0 +1 @@
::: textual.widgets.Footer

1
docs/reference/header.md Normal file
View File

@@ -0,0 +1 @@
::: textual.widgets.Header

1
docs/reference/input.md Normal file
View File

@@ -0,0 +1 @@
::: textual.widgets.Input

View File

@@ -1,6 +1,5 @@
# Button
## Description
A simple button widget which can be pressed using a mouse click or by pressing ++return++
when it has focus.
@@ -33,16 +32,16 @@ Clicking any of the non-disabled buttons in the example app below will result in
## Reactive Attributes
| Name | Type | Default | Description |
|------------|--------|-------------|-----------------------------------------------------------------------------------------------------------------------------------|
| ---------- | ------ | ----------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `label` | `str` | `""` | The text that appears inside the button. |
| `variant` | `str` | `"default"` | Semantic styling variant. One of `default`, `primary`, `success`, `warning`, `error`. |
| `disabled` | `bool` | `False` | Whether the button is disabled or not. Disabled buttons cannot be focused or clicked, and are styled in a way that suggests this. |
## Events
## Messages
### Pressed
The `Button.Pressed` event is sent when the button is pressed.
The `Button.Pressed` message is sent when the button is pressed.
- [x] Bubbles

View File

@@ -1 +1,42 @@
# Footer
A simple footer widget which is docked to the bottom of its parent container. Displays
available keybindings for the currently focused widget.
- [ ] Focusable
- [ ] Container
## Example
The example below shows an app with a single keybinding that contains only a `Footer`
widget. Notice how the `Footer` automatically displays the keybind.
=== "Output"
```{.textual path="docs/examples/widgets/footer.py"}
```
=== "footer.py"
```python
--8<-- "docs/examples/widgets/footer.py"
```
## Reactive Attributes
| Name | Type | Default | Description |
| --------------- | ----- | ------- | --------------------------------------------------------------------------------------------------------- |
| `highlight_key` | `str` | `None` | Stores the currently highlighted key. This is typically the key the cursor is hovered over in the footer. |
## Messages
This widget sends no messages.
## Additional Notes
* You can prevent keybindings from appearing in the footer by setting the `show` argument of the `Binding` to `False`.
* You can customize the text that appears for the key itself in the footer using the `key_display` argument of `Binding`.
## See Also
* [Footer](../reference/footer.md) code reference

View File

@@ -1 +1,35 @@
# Header
A simple header widget which docks itself to the top of the parent container.
- [ ] Focusable
- [ ] Container
## Example
The example below shows an app with a `Header`.
=== "Output"
```{.textual path="docs/examples/widgets/header.py"}
```
=== "header.py"
```python
--8<-- "docs/examples/widgets/header.py"
```
## Reactive Attributes
| Name | Type | Default | Description |
| ------ | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `tall` | `bool` | `True` | Whether the `Header` widget is displayed as tall or not. The tall variant is 3 cells tall by default. The non-tall variant is a single cell tall. This can be toggled by clicking on the header. |
## Messages
This widget sends no messages.
## See Also
* [Header](../reference/header.md) code reference

View File

@@ -1 +1,67 @@
# Input
A single-line text input widget.
- [x] Focusable
- [ ] Container
## Example
The example below shows how you might create a simple form using two `Input` widgets.
=== "Output"
```{.textual path="docs/examples/widgets/input.py" press="tab,D,a,r,r,e,n"}
```
=== "input.py"
```python
--8<-- "docs/examples/widgets/input.py"
```
## Reactive Attributes
| Name | Type | Default | Description |
| ----------------- | ------ | ------- | --------------------------------------------------------------- |
| `cursor_blink` | `bool` | `True` | True if cursor blinking is enabled. |
| `value` | `str` | `""` | The value currently in the text input. |
| `cursor_position` | `int` | `0` | The index of the cursor in the value string. |
| `placeholder` | `str` | `str` | The dimmed placeholder text to display when the input is empty. |
| `password` | `bool` | `False` | True if the input should be masked. |
## Messages
### Changed
The `Input.Changed` message is sent when the value in the text input changes.
- [x] Bubbles
#### Attributes
| attribute | type | purpose |
| --------- | ----- | -------------------------------- |
| `value` | `str` | The new value in the text input. |
### Submitted
The `Input.Submitted` message is sent when you press ++enter++ with the text field submitted.
- [x] Bubbles
#### Attributes
| attribute | type | purpose |
| --------- | ----- | -------------------------------- |
| `value` | `str` | The new value in the text input. |
## Additional Notes
* The spacing around the text content is due to border. To remove it, set `border: none;` in your CSS.
## See Also
* [Input](../reference/input.md) code reference

View File

@@ -1 +1,34 @@
# Static
A widget which displays static content.
Can be used for simple text labels, but can also contain more complex Rich renderables.
- [ ] Focusable
- [x] Container
## Example
The example below shows how you can use a `Static` widget as a simple text label.
=== "Output"
```{.textual path="docs/examples/widgets/static.py"}
```
=== "static.py"
```python
--8<-- "docs/examples/widgets/static.py"
```
## Reactive Attributes
This widget has no reactive attributes.
## Messages
This widget sends no messages.
## See Also
* [Static](../reference/static.md) code reference

View File

@@ -52,7 +52,7 @@ nav:
- "events/screen_suspend.md"
- "events/show.md"
- Styles:
- "styles/index.md"
- "styles/index.md"
- "styles/align.md"
- "styles/background.md"
- "styles/border.md"
@@ -101,7 +101,9 @@ nav:
- "reference/containers.md"
- "reference/dom_node.md"
- "reference/events.md"
- "reference/footer.md"
- "reference/geometry.md"
- "reference/header.md"
- "reference/index.md"
- "reference/message_pump.md"
- "reference/message.md"
@@ -179,7 +181,7 @@ plugins:
handlers:
python:
options:
show_source: false
show_source: false
filters:
- "!^_"
- "^__init__$"

View File

@@ -11,7 +11,7 @@ from textual.app import App
from textual.geometry import Size
from textual.reactive import Reactive
from textual.widget import Widget
from textual.widgets.text_input import TextInput, TextWidgetBase
from textual.widgets._input import Input
def get_files() -> list[Path]:
@@ -53,12 +53,12 @@ class FileSearchApp(App):
def on_mount(self) -> None:
self.file_table = FileTable(id="file_table", files=list(Path.cwd().iterdir()))
self.search_bar = TextInput(placeholder="Search for files...")
self.search_bar.focus()
self.mount(file_table_wrapper=Widget(self.file_table))
self.search_bar = Input(placeholder="Search for files...")
# self.search_bar.focus()
self.mount(search_bar=self.search_bar)
self.mount(file_table_wrapper=Widget(self.file_table))
def on_text_input_changed(self, event: TextInput.Changed) -> None:
def on_input_changed(self, event: Input.Changed) -> None:
self.file_table.filter = event.value

View File

@@ -1,12 +1,8 @@
Screen {
}
#file_table_wrapper {
dock: bottom;
height: auto;
overflow: auto auto;
scrollbar-color: $accent-darken-1;
}
@@ -15,7 +11,5 @@ Screen {
}
#search_bar {
dock: bottom;
background: $accent;
height: 1;
}

View File

@@ -12,6 +12,7 @@ from ..widget import Widget
@rich.repr.auto
class Footer(Widget):
"""A simple header widget which docks itself to the top of the parent container."""
DEFAULT_CSS = """
Footer {
@@ -20,18 +21,18 @@ class Footer(Widget):
dock: bottom;
height: 1;
}
Footer > .footer--highlight {
background: $accent-darken-1;
Footer > .footer--highlight {
background: $accent-darken-1;
}
Footer > .footer--highlight-key {
background: $secondary;
text-style: bold;
Footer > .footer--highlight-key {
background: $secondary;
text-style: bold;
}
Footer > .footer--key {
text-style: bold;
background: $accent-darken-2;
text-style: bold;
background: $accent-darken-2;
}
"""
@@ -65,7 +66,7 @@ class Footer(Widget):
self.highlight_key = event.style.meta.get("key")
async def on_leave(self, event: events.Leave) -> None:
"""Clear any highlight when the mouse leave the widget"""
"""Clear any highlight when the mouse leaves the widget"""
self.highlight_key = None
def __rich_repr__(self) -> rich.repr.Result:

View File

@@ -56,7 +56,7 @@ class Input(Widget, can_focus=True):
DEFAULT_CSS = """
Input {
background: $boost;
color: $text;
color: $text;
padding: 0 2;
border: tall $background;
width: 100%;
@@ -82,9 +82,9 @@ class Input(Widget, can_focus=True):
Binding("left", "cursor_left", "cursor left"),
Binding("right", "cursor_right", "cursor right"),
Binding("backspace", "delete_left", "delete left"),
Binding("home", "home", "Home"),
Binding("end", "end", "Home"),
Binding("ctrl+d", "delete_right", "Delete"),
Binding("home", "home", "home"),
Binding("end", "end", "end"),
Binding("ctrl+d", "delete_right", "delete right"),
Binding("enter", "submit", "Submit"),
]

View File

@@ -25,13 +25,14 @@ def _check_renderable(renderable: object):
class Static(Widget):
"""A widget to display simple static content, or use as a base- lass for more complex widgets.
"""A widget to display simple static content, or use as a base class for more complex widgets.
Args:
renderable (RenderableType, optional): A Rich renderable, or string containing console markup.
Defaults to "".
expand (bool, optional): Expand content if required to fill container. Defaults to False.
shrink (bool, optional): Shrink content if required to fill container. Defaults to False.
markup (bool, optional): True if markup should be parsed and rendered. Defaults to True.
name (str | None, optional): Name of widget. Defaults to None.
id (str | None, optional): ID of Widget. Defaults to None.
classes (str | None, optional): Space separated list of class names. Defaults to None.