mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Document Footer widget
This commit is contained in:
15
docs/examples/widgets/footer.py
Normal file
15
docs/examples/widgets/footer.py
Normal 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()
|
||||||
1
docs/reference/footer.md
Normal file
1
docs/reference/footer.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
::: textual.widgets.Footer
|
||||||
@@ -38,11 +38,11 @@ Clicking any of the non-disabled buttons in the example app below will result in
|
|||||||
| `variant` | `str` | `"default"` | Semantic styling variant. One of `default`, `primary`, `success`, `warning`, `error`. |
|
| `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. |
|
| `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
|
### 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
|
- [x] Bubbles
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,41 @@
|
|||||||
# Footer
|
# Footer
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
A simple footer widget which is docked to the bottom of its parent container. Displays
|
||||||
|
available keybindings for the currently focused widget.
|
||||||
|
|
||||||
|
## 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"}
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "button.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
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ nav:
|
|||||||
- "events/screen_suspend.md"
|
- "events/screen_suspend.md"
|
||||||
- "events/show.md"
|
- "events/show.md"
|
||||||
- Styles:
|
- Styles:
|
||||||
- "styles/index.md"
|
- "styles/index.md"
|
||||||
- "styles/align.md"
|
- "styles/align.md"
|
||||||
- "styles/background.md"
|
- "styles/background.md"
|
||||||
- "styles/border.md"
|
- "styles/border.md"
|
||||||
@@ -100,6 +100,7 @@ nav:
|
|||||||
- "reference/containers.md"
|
- "reference/containers.md"
|
||||||
- "reference/dom_node.md"
|
- "reference/dom_node.md"
|
||||||
- "reference/events.md"
|
- "reference/events.md"
|
||||||
|
- "reference/footer.md"
|
||||||
- "reference/geometry.md"
|
- "reference/geometry.md"
|
||||||
- "reference/index.md"
|
- "reference/index.md"
|
||||||
- "reference/message_pump.md"
|
- "reference/message_pump.md"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from textual.app import App
|
|||||||
from textual.geometry import Size
|
from textual.geometry import Size
|
||||||
from textual.reactive import Reactive
|
from textual.reactive import Reactive
|
||||||
from textual.widget import Widget
|
from textual.widget import Widget
|
||||||
from textual.widgets.text_input import TextInput, TextWidgetBase
|
from textual.widgets._input import Input
|
||||||
|
|
||||||
|
|
||||||
def get_files() -> list[Path]:
|
def get_files() -> list[Path]:
|
||||||
@@ -53,12 +53,12 @@ class FileSearchApp(App):
|
|||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
self.file_table = FileTable(id="file_table", files=list(Path.cwd().iterdir()))
|
self.file_table = FileTable(id="file_table", files=list(Path.cwd().iterdir()))
|
||||||
self.search_bar = TextInput(placeholder="Search for files...")
|
self.search_bar = Input(placeholder="Search for files...")
|
||||||
self.search_bar.focus()
|
# self.search_bar.focus()
|
||||||
self.mount(file_table_wrapper=Widget(self.file_table))
|
|
||||||
self.mount(search_bar=self.search_bar)
|
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
|
self.file_table.filter = event.value
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
Screen {
|
Screen {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#file_table_wrapper {
|
#file_table_wrapper {
|
||||||
dock: bottom;
|
|
||||||
height: auto;
|
|
||||||
overflow: auto auto;
|
|
||||||
scrollbar-color: $accent-darken-1;
|
scrollbar-color: $accent-darken-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,7 +11,5 @@ Screen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#search_bar {
|
#search_bar {
|
||||||
dock: bottom;
|
|
||||||
background: $accent;
|
|
||||||
height: 1;
|
height: 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,18 +20,18 @@ class Footer(Widget):
|
|||||||
dock: bottom;
|
dock: bottom;
|
||||||
height: 1;
|
height: 1;
|
||||||
}
|
}
|
||||||
Footer > .footer--highlight {
|
Footer > .footer--highlight {
|
||||||
background: $accent-darken-1;
|
background: $accent-darken-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Footer > .footer--highlight-key {
|
Footer > .footer--highlight-key {
|
||||||
background: $secondary;
|
background: $secondary;
|
||||||
text-style: bold;
|
text-style: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
Footer > .footer--key {
|
Footer > .footer--key {
|
||||||
text-style: bold;
|
text-style: bold;
|
||||||
background: $accent-darken-2;
|
background: $accent-darken-2;
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ class Footer(Widget):
|
|||||||
self.highlight_key = event.style.meta.get("key")
|
self.highlight_key = event.style.meta.get("key")
|
||||||
|
|
||||||
async def on_leave(self, event: events.Leave) -> None:
|
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
|
self.highlight_key = None
|
||||||
|
|
||||||
def __rich_repr__(self) -> rich.repr.Result:
|
def __rich_repr__(self) -> rich.repr.Result:
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class Input(Widget, can_focus=True):
|
|||||||
DEFAULT_CSS = """
|
DEFAULT_CSS = """
|
||||||
Input {
|
Input {
|
||||||
background: $boost;
|
background: $boost;
|
||||||
color: $text;
|
color: $text;
|
||||||
padding: 0 2;
|
padding: 0 2;
|
||||||
border: tall $background;
|
border: tall $background;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -82,9 +82,9 @@ class Input(Widget, can_focus=True):
|
|||||||
Binding("left", "cursor_left", "cursor left"),
|
Binding("left", "cursor_left", "cursor left"),
|
||||||
Binding("right", "cursor_right", "cursor right"),
|
Binding("right", "cursor_right", "cursor right"),
|
||||||
Binding("backspace", "delete_left", "delete left"),
|
Binding("backspace", "delete_left", "delete left"),
|
||||||
Binding("home", "home", "Home"),
|
Binding("home", "home", "home"),
|
||||||
Binding("end", "end", "Home"),
|
Binding("end", "end", "end"),
|
||||||
Binding("ctrl+d", "delete_right", "Delete"),
|
Binding("ctrl+d", "delete_right", "delete right"),
|
||||||
]
|
]
|
||||||
|
|
||||||
COMPONENT_CLASSES = {"input--cursor", "input--placeholder"}
|
COMPONENT_CLASSES = {"input--cursor", "input--placeholder"}
|
||||||
|
|||||||
Reference in New Issue
Block a user