Build a List View
ListViewModel is a pure model for item-oriented list content. It does not own
application state and does not import Textual.
from rich.text import Text
from lazy_cuh import ( LineNumberMode, LineNumberSpec, ListViewModel, ListViewSpec, NavigableItem,)
items = ( NavigableItem(id="one", label=Text("first item")), NavigableItem(id="two", label=Text("second item")),)
view = ListViewModel( items=items, cursor_index=1, spec=ListViewSpec( width=40, line_numbers=LineNumberSpec(LineNumberMode.RELATIVE), ),)
for line in view.rendered_lines(): print(line.plain)Navigation remains item-based. If an item wraps to multiple terminal lines, moving down still moves to the next item, not to the next visual row.
When app state changes, replace the rendered items while preserving the cursor:
view = view.with_items(next_items)The cursor is clamped automatically if the new list is shorter.
Textual widgets should adapt this model to terminal rendering and emit typed events upward. They should not own the semantic items, commands, or domain state.