/** * Extended Ink Key type with additional properties * * Ink's standard Key type doesn't include backspace and delete, * but these are available at runtime. This extends the type * to include them for better type safety. */ /** * Extended Key type that includes backspace and delete * These properties are present at runtime but not in Ink's type definitions */ export interface ExtendedKey { upArrow: boolean; downArrow: boolean; leftArrow: boolean; rightArrow: boolean; pageDown: boolean; pageUp: boolean; return: boolean; escape: boolean; tab: boolean; backspace: boolean; delete: boolean; meta: boolean; ctrl: boolean; shift: boolean; } /** * Type guard to check if a key object has the extended properties */ export function isExtendedKey(key: unknown): key is ExtendedKey { return ( typeof key === "object" && key !== null && "upArrow" in key && "downArrow" in key ); } /** * Check if the key press represents a backspace or delete action */ export function isBackspaceOrDelete(key: ExtendedKey): boolean { return key.backspace || key.delete; } /** * Handle text input with backspace/delete support * Returns the new string value after processing the input * * @param currentValue - The current text value * @param input - The input character (if any) * @param key - The key object with backspace/delete flags * @param maxLength - Optional maximum length for the input * @returns The new text value, or null if no change */ export function handleTextInput( currentValue: string, input: string, key: ExtendedKey, maxLength?: number ): string | null { // Handle backspace/delete if (key.backspace || key.delete) { if (currentValue.length > 0) { return currentValue.slice(0, -1); } return null; } // Handle regular character input if (input.length === 1) { if (maxLength !== undefined && currentValue.length >= maxLength) { return null; } return currentValue + input; } return null; } /** * Handle numeric-only input with backspace/delete support * * @param currentValue - The current numeric string value * @param input - The input character (if any) * @param key - The key object with backspace/delete flags * @param maxLength - Optional maximum length for the input * @returns The new numeric string value, or null if no change */ export function handleNumericInput( currentValue: string, input: string, key: ExtendedKey, maxLength?: number ): string | null { // Handle backspace/delete if (key.backspace || key.delete) { if (currentValue.length > 0) { return currentValue.slice(0, -1); } return null; } // Only accept numeric characters if (/^[0-9]$/.test(input)) { if (maxLength !== undefined && currentValue.length >= maxLength) { return null; } return currentValue + input; } return null; }