Source code for olink.tui.widgets

"""Custom Textual widgets for the TUI."""

from rich.text import Text

# Runtime import: read by Sphinx autodoc / get_type_hints on compose().
from textual.app import ComposeResult  # noqa: TC002
from textual.binding import Binding
from textual.widgets import Input, ListItem, ListView, Static

# Runtime import: read by Sphinx autodoc / get_type_hints on the widget signatures.
from olink.tui.models import TargetItem  # noqa: TC001

__all__ = ["SearchInput", "StatusBar", "TargetListWidget", "TargetRow"]


[docs] class TargetRow(ListItem): """A single target row in the list.""" def __init__(self, item: TargetItem) -> None: self.item = item super().__init__()
[docs] def compose(self) -> ComposeResult: """Render the pin marker, name and description as one styled line.""" label = Text() marker = "★ " if self.item.pinned else " " label.append(marker, style="yellow") label.append(f"{self.item.name:20s}", style="cyan") label.append(f" {self.item.description}") yield Static(label)
[docs] class TargetListWidget(ListView): """Scrollable list of targets.""" BINDINGS = [ Binding("j", "cursor_down", "Down", show=False), Binding("k", "cursor_up", "Up", show=False), ] def __init__(self) -> None: super().__init__()
[docs] def get_selected_item(self) -> TargetItem | None: """Get the currently highlighted target item.""" if isinstance(self.highlighted_child, TargetRow): return self.highlighted_child.item return None
[docs] def update_items(self, items: list[TargetItem]) -> None: """Replace the list contents.""" self.clear() for item in items: self.append(TargetRow(item))
[docs] class SearchInput(Input): """Search bar that appears when / is pressed.""" DEFAULT_CSS = """ SearchInput { dock: bottom; height: 1; display: none; } """ def __init__(self) -> None: super().__init__(placeholder="Search…")
[docs] class StatusBar(Static): """Bottom status bar showing mode, count, and messages.""" def on_mount(self) -> None: self.styles.background = "darkblue" self.styles.color = "white" self.styles.height = 1 self.styles.dock = "bottom"
[docs] def status_update(self, mode: str, count: int, total: int) -> None: """Update the status bar content.""" mode_label = "Available" if mode == "available" else "All" self.update(f" [{mode_label}: {count}/{total}]") self.styles.color = "white"
[docs] def set_error(self, message: str) -> None: """Show an error message.""" self.update(f" \u2717 {message}") self.styles.color = "red"
[docs] def set_success(self, message: str) -> None: """Show a success message.""" self.update(f" \u2713 {message}") self.styles.color = "green"