from textual.screen import ModalScreen from textual.containers import Vertical from textual.widgets import Static, Button, Input from textual.containers import HorizontalGroup, Center from textual.binding import Binding from typing import Literal class Prompt(ModalScreen): DEFAULT_CSS = """ Prompt { align: center middle; #window { max-width: 50; height: auto; border: panel $accent; #question { width: 100%; margin: 2; margin-top: 1; } #bottom { dock: bottom; margin-bottom: 1; margin-left: 1; #yes { margin-left: 1; margin-right: 2; } #confirm-string { margin-left: 1; } Input { max-width: 25; } } } } """ BINDINGS = [ Binding("escape", "close", "Close") ] def action_close(self): self.dismiss(None) def on_button_pressed(self, event: Button.Pressed): if event.button.id == "yes": self.dismiss(True) elif event.button.id == "no": self.dismiss(False) elif event.button.id == "confirm-string": self.dismiss(self.query_one("#input").value) def __init__(self, question: str, prompt_type: Literal["confirm", "string"], title: str = "Confirm"): super().__init__() self.question = question self.window_title = title self.prompt_type = prompt_type def compose(self): with Vertical(id="window") as window: window.border_title = self.window_title yield Static(self.question, id="question") if self.prompt_type == "confirm": with HorizontalGroup(id="bottom"): yield Button("Yes", variant="success", id="yes") yield Button("No", variant="error", id="no") elif self.prompt_type == "string": with HorizontalGroup(id="bottom"): yield Input(id="input", max_length=30) yield Button("Confirm", variant="success", id="confirm-string")