Newer
Older
navi-1 / clients / terminal / tui / widgets / input_box.py
"""Input box widget for the TUI."""

from __future__ import annotations

from textual.app import ComposeResult
from textual.containers import Vertical
from textual.widgets import Input

from clients.terminal.tui.events import UserSubmitted


class InputBox(Vertical):
    """Bottom prompt frame with input field."""

    DEFAULT_CSS = """
    InputBox {
        height: auto;
        min-height: 3;
        border: heavy $tui-prompt-border;
        background: $tui-surface;
        color: $tui-text;
        padding: 0 1;
    }
    InputBox > Input {
        height: 3;
        width: 100%;
        border: none;
        background: $tui-surface;
        color: $tui-text;
        padding: 0;
    }
    InputBox > Input:focus {
        border: none;
        background-tint: transparent;
    }
    InputBox > Input > .input--placeholder {
        color: $tui-text-dim;
    }
    InputBox > Input > .input--cursor {
        background: $tui-text;
        color: $tui-background;
        text-style: bold;
    }
    InputBox > Input > .input--selection {
        background: $tui-selection;
        color: $tui-background;
    }
    """

    def __init__(self) -> None:
        super().__init__()
        self._input = Input(placeholder="Ask anything...", classes="input-field")

    def compose(self) -> ComposeResult:
        yield self._input

    def on_mount(self) -> None:
        self._input.focus()

    def on_input_changed(self, event: Input.Changed) -> None:
        self._input.refresh(layout=False)

    def on_input_submitted(self, event: Input.Submitted) -> None:
        text = event.value.strip()
        if text:
            self.post_message(UserSubmitted(text))
            self._input.value = ""

    def focus_input(self) -> None:
        self._input.focus()

    def set_placeholder(self, text: str) -> None:
        self._input.placeholder = text

    def set_prompt_char(self, char: str) -> None:
        self._prompt.update(char)