#!/usr/bin/env bun /** * text-input-harness.tsx — Standalone test harness for the TextInput component. * * Run with: bun src/ink/text-input-harness.tsx * * Provides an interactive terminal UI to exercise all TextInput features: * - Single-line and multi-line modes * - Arrow key cursor navigation * - Home/End keys * - Insert/delete at cursor position * - Ctrl+S to submit * - Ctrl+E to open $EDITOR * - Tab to switch between modes * - q in header to quit */ import React, { useState, useCallback } from "react"; import { render, Box, Text, useApp, useInput } from "ink"; import { TextInput } from "./text-input"; import { useTextInput } from "./use-text-input"; import { openEditor } from "./open-editor"; type Mode = "single" | "multi"; function Harness(): React.ReactElement { const { exit } = useApp(); const [mode, setMode] = useState("single"); const [submitted, setSubmitted] = useState(null); const singleLine = useTextInput({ initialValue: "" }); const multiLine = useTextInput({ initialValue: "" }); const current = mode === "single" ? singleLine : multiLine; const handleSubmit = useCallback( (value: string) => { setSubmitted(value); }, [], ); const handleEditorRequest = useCallback( async (currentValue: string) => { try { const edited = await openEditor(currentValue); current.setValue(edited); } catch { // Editor failed — keep current value } }, [current], ); // Global keybinds (Tab to switch mode, Ctrl+C to quit) useInput((input, key) => { if (key.tab) { setMode((m) => (m === "single" ? "multi" : "single")); setSubmitted(null); } if (key.escape) { exit(); } }); return ( {/* Header */} TextInput Harness — test all input features {/* Mode indicator */} Mode: {mode === "single" ? "Single-line" : "Multi-line"} (Tab to switch) {/* Input area */} {mode === "single" ? "Type here (single-line):" : "Type here (multi-line, Enter = newline):"} {/* Debug info */} Value length: {current.value.length} Lines: {current.value.split("\n").length} {current.value.length > 0 && ( Content: {JSON.stringify(current.value)} )} {/* Submitted value */} {submitted !== null && ( Submitted: {JSON.stringify(submitted)} )} {/* Keybind hints */} Keybinds: Ctrl+S Submit value Ctrl+E Open $EDITOR Tab Switch mode Esc Quit ←→↑↓ Move cursor Home/End Jump within line ); } // --------------------------------------------------------------------------- // Entry point // --------------------------------------------------------------------------- const instance = render(); await instance.waitUntilExit();