Coverage for src / lilbee / cli / tui / widgets / confirm_dialog.py: 100%
27 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-04-29 19:16 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-04-29 19:16 +0000
1"""Reusable confirmation modal dialog."""
3from __future__ import annotations
5from typing import ClassVar
7from textual.app import ComposeResult
8from textual.binding import Binding, BindingType
9from textual.containers import Center, Vertical
10from textual.screen import ModalScreen
11from textual.widgets import Button, Label, Static
14class ConfirmDialog(ModalScreen[bool]):
15 """Modal yes/no dialog that returns True (confirmed) or False (cancelled)."""
17 CSS_PATH = "confirm_dialog.tcss"
19 BINDINGS: ClassVar[list[BindingType]] = [
20 Binding("y", "confirm", "Yes", show=True),
21 Binding("enter", "confirm", "Confirm", show=False),
22 Binding("n", "cancel", "No", show=True),
23 Binding("escape", "cancel", "Cancel", show=False),
24 ]
26 def __init__(self, title: str, message: str) -> None:
27 super().__init__()
28 self._title = title
29 self._message = message
31 def compose(self) -> ComposeResult:
32 with Vertical():
33 yield Static(self._title, id="confirm-title")
34 yield Label(self._message, id="confirm-message")
35 with Center():
36 yield Button("Yes (y)", variant="error", id="confirm-yes")
37 yield Button("No (n)", variant="default", id="confirm-no")
39 def on_button_pressed(self, event: Button.Pressed) -> None:
40 self.dismiss(event.button.id == "confirm-yes")
42 def action_confirm(self) -> None:
43 self.dismiss(True)
45 def action_cancel(self) -> None:
46 self.dismiss(False)