Simple file search live filter sandbox example

This commit is contained in:
Darren Burns
2022-05-20 13:52:03 +01:00
parent 66d73bcdef
commit d8aa103633
3 changed files with 96 additions and 12 deletions

74
sandbox/file_search.py Normal file
View File

@@ -0,0 +1,74 @@
from __future__ import annotations
from pathlib import Path
from typing import Iterable
from rich.console import RenderableType
from rich.style import Style
from rich.table import Table
from rich.text import Text
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
def get_files() -> list[Path]:
files = [file for file in Path.cwd().iterdir()]
return files
class FileTable(Widget):
filter = Reactive("", layout=True)
def __init__(self, *args, files: Iterable[Path] | None = None, **kwargs):
super().__init__(*args, **kwargs)
self.files = files if files is not None else []
@property
def filtered_files(self) -> list[Path]:
return [
file
for file in self.files
if self.filter == "" or (self.filter and self.filter in file.name)
]
def get_content_height(self, container: Size, viewport: Size, width: int) -> int:
return len(self.filtered_files)
def render(self, style: Style) -> RenderableType:
grid = Table.grid()
grid.add_column()
for file in self.filtered_files:
file_text = Text(" " + file.name)
file_text.highlight_regex(self.filter, "black on yellow")
grid.add_row(file_text)
return grid
class FileSearchApp(App[str]):
dark = True
def on_mount(self) -> None:
self.file_table = FileTable(id="file_table", files=list(Path.cwd().iterdir()))
self.mount(file_table_wrapper=Widget(self.file_table))
self.search_bar = TextInput(placeholder="Search for files...")
self.search_bar.cursor_blink_enabled = True
self.search_bar.focus()
self.mount(search_bar=self.search_bar)
def handle_changed(self, event: TextWidgetBase.Changed) -> None:
if event.sender == self.search_bar:
self.file_table.filter = event.value
app = FileSearchApp(
log_path="textual.log", css_path="file_search.scss", watch_css=True, log_verbosity=2
)
if __name__ == "__main__":
result = app.run()

21
sandbox/file_search.scss Normal file
View File

@@ -0,0 +1,21 @@
Screen {
layout: dock;
docks: top=top bottom=bottom;
}
#file_table_wrapper {
dock: bottom;
height: auto;
overflow: auto auto;
scrollbar-color: $accent-darken-1;
}
#file_table {
height: auto;
}
#search_bar {
dock: bottom;
background: $accent;
height: 1;
}