import { type Component, type Input } from "@earendil-works/pi-tui"; import type { Theme } from "../../../../modes/interactive/theme/theme.js"; import type { QuestionData } from "../tool/types.js"; import type { ChatRowView } from "./components/chat-row-view.ts"; import type { PreviewPaneProps } from "./components/preview/preview-pane.ts"; import { type DialogState } from "./dialog-builder.ts"; import type { StatefulView } from "./stateful-view.ts"; import type { TabComponents } from "./tab-components.ts"; /** * Per-tab content provider. Pure functional — closes over construction-time * config; per-tick state threads through method args. The chrome wrapper * enforces height equality across tabs via `bodyHeight + footerRowCount`. */ export interface TabContentStrategy { /** Total RENDERED footer rows — MUST equal what `footerRows()` actually emits. Drives residual math. */ readonly footerRowCount: number; /** Variable rows above the body, after top chrome (border + tabBar + Spacer). */ headingRows(state: DialogState): Component[]; /** Body Component placed at the body slot. */ bodyComponent(state: DialogState): Component; /** Natural rendered height of `bodyComponent(state)` at given width. */ bodyHeight(width: number, state: DialogState): number; /** Optional rows between body's trailing Spacer and the bottom border. */ midRows(state: DialogState): Component[]; /** Footer rows below the bottom border. Rendered row count MUST equal `footerRowCount`. */ footerRows(state: DialogState): Component[]; } export interface QuestionTabStrategyConfig { theme: Theme; questions: readonly QuestionData[]; getPreviewPane: () => StatefulView; tabsByIndex: ReadonlyArray; notesInput: Input; chatRow: ChatRowView; isMulti: boolean; getCurrentBodyHeight: (width: number) => number; } export declare class QuestionTabStrategy implements TabContentStrategy { /** Spacer(1) + chatRow(1) + Spacer(1) + Text(hint, 1) = 4 rendered rows. */ readonly footerRowCount = 4; private readonly config; constructor(config: QuestionTabStrategyConfig); headingRows(state: DialogState): Component[]; bodyComponent(state: DialogState): Component; bodyHeight(width: number, _state: DialogState): number; midRows(state: DialogState): Component[]; footerRows(state: DialogState): Component[]; } export interface SubmitTabStrategyConfig { theme: Theme; questions: readonly QuestionData[]; submitPicker: Component | undefined; } export declare class SubmitTabStrategy implements TabContentStrategy { /** Spacer(1) + Text(prompt, 1) + Spacer(1) + submitPicker(2) = 5 rendered rows. Fallback path lands at 5 via 2 trailing Spacer(1)s. */ readonly footerRowCount = 5; private readonly config; constructor(config: SubmitTabStrategyConfig); headingRows(_state: DialogState): Component[]; bodyComponent(state: DialogState): Component; bodyHeight(width: number, state: DialogState): number; midRows(_state: DialogState): Component[]; footerRows(state: DialogState): Component[]; } /** * Build the controls hint line. Order is fixed so `HINT_SINGLE` / `HINT_MULTI` * remain contiguous substrings of the result: * Enter · ↑/↓ [· Space toggle] [· n notes] [· Tab switch] · Esc */ export declare function buildHintText(question: QuestionData | undefined, isMulti: boolean, state: DialogState): string; //# sourceMappingURL=tab-content-strategy.d.ts.map