class

Phosphor::SearchMock

Inherits Phosphor::MockWidget < Reference < Object

A composite of InputMock + ListMock that filters rows in real time — the common /-search pattern nearly every list-heavy TUI app implements.

Generic and app-agnostic: no knowledge of AppState, Msg, or the application theme. The Widget wrapper resolves theme → Style values and sets them in Props before each render.

SearchMock never filters props.all_rows itself — the owning Widget#sync filters all_rows by query and populates filtered_rows in Props. render_content only ever draws from props.filtered_rows; all_rows is carried through unread so the Widget has somewhere to pull the unfiltered dataset from, never so SearchMock can run a filter algorithm on it. See .claude/rules/widgets.md § "Anti-patterns to flag".

Constructors

new(props : Props, state : MockWidget::WidgetState = MockWidget::WidgetState.new)

Initialises the search widget with props and an optional state. Constructs the internal @input and @list widgets once, seeded from props; render_content re-syncs their Props on every call so their own WidgetState (cursor position, scroll offset) persists across renders like any other MockWidget.

Source

Instance methods

handle_cmd(cmd : Cmd) : CmdResult

Routes cmd by type, delegating to whichever internal widget owns that concern:

  • Cmd::InsertChar, Cmd::DeleteChar, Cmd::MoveCursorLeft, Cmd::MoveCursorRight, Cmd::SelectAll — delegate to @input, returning its CmdResult unchanged. Typing never moves the list cursor.
  • Cmd::MoveUp, Cmd::MoveDown — delegate to @list, returning its CmdResult unchanged. Navigation never affects the query.
  • Cmd::Confirm — always CmdResult::Bubble, so the owning Widget can read @list's cursor and emit a domain Msg for the selected filtered row. SearchMock has no idea what selecting a row means.
  • Cmd::Cancel — always CmdResult::Bubble, so the owning Widget can dismiss the search.
  • Any other command — returns CmdResult::None.
Source
input

The internal InputMock driving the query field. Read-only — exposed so specs can inspect its props/state directly (e.g. to confirm navigation commands never touch the query); nothing outside this class should mutate it.

Source
list

The internal ListMock driving the filtered results. Read-only — same rationale as #input.

Source
props
Source
props=(props : Props)
Source
render_content(frame : Frame, buf : Buffer) : Void

Renders the query field on the top row and the filtered results below it, into buf within frame.

@input and @list are re-synced from props first (so external changes to query/filtered_rows/styles between renders show up immediately), then @input renders into a one-row frame at frame.y and @list renders into the remaining rows below — computed with plain Frame arithmetic, not Layout (SearchMock is a MockWidget, not a Screen).

Source

Nested types