import { type Component, type OverlayMargin, type SizeValue } from "@earendil-works/pi-tui"; import { type ExtensionCustomComponent } from "../../../core/extensions/ui-types.js"; /** * What {@link ReservedBottomOverlay} needs from the component it wraps: the * documented `ctx.ui.custom()` contract, plus the internal-UI-action flag the * host reads off whichever component holds focus. */ export type WrappedOverlayComponent = ExtensionCustomComponent & { handlesInternalUiAction?: boolean; }; /** * Transcript rows that must stay visible above a reserving bottom overlay. * * A bottom-anchored overlay is composited over the transcript rather than * measured into the layout, so nothing stops it covering the whole screen. Six * rows is the floor at which the transcript is still legible while paging, and * it is what makes the reserve arithmetic below total-occlusion-proof: * `visibleStrip === terminalRows - overlayHeight`, so bounding the overlay to * `terminalRows - MIN_TRANSCRIPT_STRIP_ROWS` guarantees the strip. */ export declare const MIN_TRANSCRIPT_STRIP_ROWS = 6; /** Resolve pi-tui's terminal-relative max-height rule for valid SizeValue input. */ export declare function resolveOverlayMaxHeight(maxHeight: SizeValue | undefined, terminalRows: number, margin?: OverlayMargin | number): number | undefined; /** * Fit `lines` into `budget` rows. * * Trailing blank rows go first — a bottom-anchored overlay pays for them in * occlusion and they carry nothing. The last {@link OVERLAY_TAIL_KEEP_ROWS} rows * are always kept, because the closing border and the key hints live there. * * What survives in between is a single window of the frame, and it is placed so * that it still contains the row the component marked as active. Keeping a fixed * head instead — which is what this did first — drops the selected option on a * short terminal: at 80 columns the marker sits at row `6 + 2 * optionIndex`, so * option 4 disappeared below 24 rows and option 1 below 18, and the dialog looked * frozen under the arrow keys. The window is the earliest one that still holds * the active row, so a frame whose active row is already near the top crops * exactly as it did before. */ export declare function boundOverlayLines(lines: readonly string[], budget: number): string[]; /** * A blocking overlay that leaves room for the transcript. * * Wraps the component an extension mounted with `reserveTranscriptRows`, bounds * its height so it can never cover the whole screen, and records the height it * actually painted so {@link TranscriptOverlayReserve} can extend the * transcript's scroll extent by exactly the rows this overlay hides. */ export declare class ReservedBottomOverlay implements Component { readonly wantsKeyRelease: boolean; readonly handlesInternalUiAction: boolean; private readonly inner; private readonly getTerminalRows; private readonly margin; private readonly maxHeight; private readonly shouldPassViewportInput; private readonly onHeightChange; private height; constructor(inner: WrappedOverlayComponent, getTerminalRows: () => number, margin?: OverlayMargin | number, maxHeight?: SizeValue, shouldPassViewportInput?: (data: string) => boolean, onHeightChange?: () => void); /** Rows painted by the last `render`. Zero before the first frame. */ get renderedHeight(): number; render(width: number): string[]; handleInput(data: string): boolean | undefined | Promise; invalidate(): void; dispose(): void; } export interface TranscriptOverlayIntersection { top: number; bottom: number; } /** Return the terminal-row interval where a bottom overlay covers the transcript. */ export declare function transcriptOverlayIntersection(overlayHeight: number, terminalRows: number, transcriptViewportHeight: number, margin?: OverlayMargin | number): TranscriptOverlayIntersection | undefined; /** * One host-owned blank-row coordinator appended to the transcript document. * * Each visible bottom overlay supplies its real transcript intersection. The * blank tail equals only the connected covered suffix at the transcript bottom: * floating overlays need no tail, while overlapping intervals are unioned once. */ export declare class TranscriptOverlayReserve implements Component { private readonly getTranscriptViewportHeight; private readonly reservations; constructor(getTranscriptViewportHeight: () => number); get empty(): boolean; register(getIntersection: () => TranscriptOverlayIntersection | undefined): () => void; handleInput(_data: string): void; invalidate(): void; render(_width: number): string[]; } /** * Zero-margin compatibility helper for callers that only need the covered * transcript-bottom suffix length. */ export declare function occludedTranscriptRows(overlayHeight: number, terminalRows: number, transcriptViewportHeight: number): number; //# sourceMappingURL=reserved-bottom-overlay.d.ts.map