Coverage for src / lilbee / cli / tui / widgets / search_hf_cta_item.py: 100%

37 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-04-29 19:16 +0000

1"""Focusable CTA row that asks the user to search HuggingFace for the term.""" 

2 

3from __future__ import annotations 

4 

5from dataclasses import dataclass 

6from pathlib import Path 

7from typing import ClassVar 

8 

9from textual import containers, widgets 

10from textual.app import ComposeResult 

11from textual.binding import Binding 

12from textual.events import Click 

13from textual.message import Message 

14 

15from lilbee.cli.tui import messages as msg 

16 

17_CSS_FILE = Path(__file__).parent / "search_hf_cta_item.tcss" 

18 

19 

20class SearchHFCtaItem(containers.VerticalGroup, can_focus=True): 

21 """A focusable list row that fires the HF search worker when activated.""" 

22 

23 DEFAULT_CSS: ClassVar[str] = _CSS_FILE.read_text(encoding="utf-8") 

24 

25 BINDINGS: ClassVar = [Binding("enter", "select", "Select", show=False)] 

26 

27 @dataclass 

28 class Selected(Message): 

29 item: SearchHFCtaItem 

30 

31 @property 

32 def control(self) -> SearchHFCtaItem: 

33 return self.item 

34 

35 @property 

36 def term(self) -> str: 

37 return self.item.term 

38 

39 def __init__(self, term: str) -> None: 

40 self._term = term 

41 super().__init__() 

42 

43 @property 

44 def term(self) -> str: 

45 return self._term 

46 

47 def action_select(self) -> None: 

48 self.post_message(self.Selected(self)) 

49 

50 def on_click(self, event: Click) -> None: 

51 event.stop() 

52 self.focus() 

53 self.post_message(self.Selected(self)) 

54 

55 def compose(self) -> ComposeResult: 

56 yield widgets.Static(msg.CATALOG_SEARCH_HF_CTA.format(query=self._term), id="cta-label")