/** * Focus management system. * A framework-global singleton that tracks focusable elements (inputs, buttons, etc). * * Focusables auto-register when created and coordinate focus through this manager. * Only one element can be focused at a time. */ /** * Common terminal key codes. */ export declare const KEYS: { readonly BACKSPACE: ""; readonly BACKSPACE_CTRL_H: "\b"; readonly DELETE: "\u001B[3~"; readonly LEFT: "\u001B[D"; readonly RIGHT: "\u001B[C"; readonly UP: "\u001B[A"; readonly DOWN: "\u001B[B"; readonly HOME: "\u001B[H"; readonly HOME_ALT: "\u001B[1~"; readonly END: "\u001B[F"; readonly END_ALT: "\u001B[4~"; readonly ENTER: "\r"; readonly ENTER_LF: "\n"; readonly TAB: "\t"; readonly SHIFT_TAB: "\u001B[Z"; readonly ESCAPE: "\u001B"; readonly CTRL_A: "\u0001"; readonly CTRL_C: "\u0003"; readonly CTRL_D: "\u0004"; readonly CTRL_E: "\u0005"; readonly CTRL_J: "\n"; readonly CTRL_K: "\v"; readonly CTRL_L: "\f"; readonly CTRL_N: "\u000E"; readonly CTRL_P: "\u0010"; readonly CTRL_U: "\u0015"; readonly CTRL_W: "\u0017"; readonly ALT_LEFT: "\u001Bb"; readonly ALT_LEFT_CSI: "\u001B[1;3D"; readonly ALT_RIGHT: "\u001Bf"; readonly ALT_RIGHT_CSI: "\u001B[1;3C"; readonly SHIFT_ENTER: "\u001B[13;2u"; readonly ALT_BACKSPACE: "\u001B"; readonly SPACE: " "; }; /** * Interface for any focusable element (input, button, etc). */ export interface Focusable { focused: () => boolean; focus: () => void; blur: () => void; dispose: () => void; handleKey: (key: string) => boolean; /** @internal */ _setFocused: (focused: boolean) => void; } /** * Options for createFocusable. */ export interface FocusableOptions { /** * Key handler. Return true if key was consumed, false to let it bubble. */ onKey: (key: string) => boolean; /** * Whether to auto-register with focus manager (default: true). */ register?: boolean; } /** * Create a base focusable with focus management wired up. * Use this as the foundation for inputs, buttons, selects, etc. * * @example * ```ts * const { focusable, focused, setFocused } = createFocusable({ * onKey: (key) => { * if (key === KEYS.ENTER) { doSomething(); return true; } * return false; * }, * }); * ``` */ export declare function createFocusable(options: FocusableOptions): { focusable: Focusable; focused: () => boolean; setFocused: (focused: boolean) => void; }; /** * Register a focusable with the focus manager. * Called automatically by createInput(), createButton(), etc. * @internal */ export declare function registerFocusable(focusable: Focusable): void; /** * Unregister a focusable from the focus manager. * Called by focusable.dispose(). * @internal */ export declare function unregisterFocusable(focusable: Focusable): void; /** * Called when a focusable wants to gain focus. * Blurs any currently focused element first. * @internal */ export declare function requestFocus(focusable: Focusable): void; /** * Called when a focusable wants to blur. * @internal */ export declare function requestBlur(focusable: Focusable): void; /** * The global focus manager. * * @example * ```tsx * import { focus, createInput, createButton, KEYS } from 'treeli'; * * const username = createInput(); * const submit = createButton({ onPress: () => console.log('Submitted!') }); * * // Focus first element * username.focus(); * * // In your keypress handler: * onKeypress(key) { * // Focus manager handles Tab/Shift+Tab and routes keys * if (focus.handleKey(key)) return; // consumed * * // Handle other app shortcuts... * } * ``` */ export declare const focus: { /** * Get the currently focused element (reactive signal). */ current: import("./reactive.ts").Accessor; /** * Focus the next element in registration order. * Wraps around to the first element. */ next(): void; /** * Focus the previous element in registration order. * Wraps around to the last element. */ prev(): void; /** * Route a keypress to the currently focused element. * Automatically handles Tab (next) and Shift+Tab (prev) for focus navigation. * If no element consumes the key, calls the unhandled key handler. * Returns true if the key was consumed, false otherwise. */ handleKey(key: string): boolean; /** * Set a handler for keys that no focusable element consumes. * Useful for global shortcuts like toggling a log viewer. * Returns a cleanup function to remove the handler. */ setUnhandledKeyHandler(handler: (key: string) => boolean): () => void; /** * Manually set the focused element. * Pass null to blur all elements. */ set(focusable: Focusable | null): void; /** * Get all registered focusable elements. */ getAll(): Focusable[]; /** * Clear all registered focusables and handlers. * Useful for testing or app reset. */ clear(): void; }; /** * Options for createKeySequence. */ export interface KeySequenceOptions { /** * Map of key sequences to handlers. * Keys are concatenated key strings (e.g., "gg", "dd", "yy"). */ sequences: Record void>; /** * Timeout in milliseconds before resetting the sequence buffer. * Default: 1000ms */ timeout?: number; /** * Handler for keys that don't match any sequence prefix. * Called with the unmatched key. Return true if consumed. */ onUnmatched?: (key: string) => boolean; } /** * Create a key sequence handler for multi-key commands. * Useful for vim-like keybindings (gg, dd, yy, etc.). * * @example * ```ts * const handleKey = createKeySequence({ * sequences: { * "gg": () => goToTop(), * "dd": () => deleteLine(), * "yy": () => yankLine(), * "dw": () => deleteWord(), * }, * onUnmatched: (key) => { * // Handle single-key commands like 'h', 'j', 'k', 'l' * if (key === "j") { moveDown(); return true; } * return false; * }, * }); * * // Use in a focusable's onKey handler: * const { focusable } = createFocusable({ * onKey: handleKey, * }); * ``` */ export declare function createKeySequence(options: KeySequenceOptions): (key: string) => boolean; //# sourceMappingURL=focus.d.ts.map