diff --git a/src/ui/tui/hooks/useKeyboardHints.tsx b/src/ui/tui/hooks/useKeyboardHints.tsx index ae3a2ecc..192aff95 100644 --- a/src/ui/tui/hooks/useKeyboardHints.tsx +++ b/src/ui/tui/hooks/useKeyboardHints.tsx @@ -2,16 +2,14 @@ * KeyboardHintsProvider — Context for collecting and displaying keyboard hints. * * Input components register their hints via useKeyBindings. The provider - * flattens, deduplicates, and sorts them. It auto-dismisses 3s after the - * first keypress and resets when the hint set changes (screen navigation). + * flattens, deduplicates, and sorts them. The hints bar stays visible for as + * long as a screen has registered hints — it never auto-dismisses. */ -import { useInput } from 'ink'; import { createContext, useCallback, useContext, - useEffect, useRef, useState, type ReactNode, @@ -28,20 +26,16 @@ interface KeyboardHintsContextValue { register(id: string, hints: KeyboardHint[]): void; unregister(id: string): void; hints: KeyboardHint[]; - visible: boolean; } const KeyboardHintsContext = createContext({ register: () => undefined, unregister: () => undefined, hints: [], - visible: false, }); export const useKeyboardHintsContext = () => useContext(KeyboardHintsContext); -const DISMISS_DELAY = 3000; - export const KeyboardHintsProvider = ({ children, }: { @@ -49,8 +43,6 @@ export const KeyboardHintsProvider = ({ }) => { const registrationsRef = useRef(new Map()); const [hints, setHints] = useState([]); - const [visible, setVisible] = useState(true); - const timerRef = useRef | null>(null); const prevHintsKeyRef = useRef(''); const recompute = useCallback(() => { @@ -64,14 +56,6 @@ export const KeyboardHintsProvider = ({ if (newKey !== prevHintsKeyRef.current) { prevHintsKeyRef.current = newKey; setHints(deduped); - // Reset visibility when hints change (new screen) - if (newKey.length > 0) { - setVisible(true); - if (timerRef.current) { - clearTimeout(timerRef.current); - timerRef.current = null; - } - } } }, []); @@ -91,29 +75,8 @@ export const KeyboardHintsProvider = ({ [recompute], ); - // Dismiss on first keypress after 3s - useInput(() => { - if (!visible) return; - if (timerRef.current) return; // already counting down - timerRef.current = setTimeout(() => { - setVisible(false); - timerRef.current = null; - }, DISMISS_DELAY); - }); - - // Cleanup timer on unmount - useEffect(() => { - return () => { - if (timerRef.current) { - clearTimeout(timerRef.current); - } - }; - }, []); - return ( - + {children} ); diff --git a/src/ui/tui/playground/demos/KeyboardHintsDemo.tsx b/src/ui/tui/playground/demos/KeyboardHintsDemo.tsx index 04e155d3..77b647a8 100644 --- a/src/ui/tui/playground/demos/KeyboardHintsDemo.tsx +++ b/src/ui/tui/playground/demos/KeyboardHintsDemo.tsx @@ -3,8 +3,8 @@ * * Cycles through SinglePicker, MultiPicker, GroupedPicker, and Confirmation * so the user can see the hints bar update automatically for each component. - * The bar appears at the bottom of the screen and dismisses 3s after the - * first keypress, then reappears when the component changes. + * The bar appears at the bottom of the screen and stays visible, updating to + * match the active component. */ import { Box, Text } from 'ink'; diff --git a/src/ui/tui/primitives/KeyboardHintsBar.tsx b/src/ui/tui/primitives/KeyboardHintsBar.tsx index 1cdb94c4..f64a467d 100644 --- a/src/ui/tui/primitives/KeyboardHintsBar.tsx +++ b/src/ui/tui/primitives/KeyboardHintsBar.tsx @@ -1,9 +1,8 @@ /** * KeyboardHintsBar — Row showing active keyboard shortcuts. * - * Always reserves its row to prevent layout shift. When hints are - * visible, renders them in dimmed grey text. When dismissed, renders - * an empty reserved row. + * Always reserves its row to prevent layout shift, and always renders the + * active hints (in dimmed grey text) while a screen has registered them. */ import { Box, Text } from 'ink'; @@ -11,24 +10,21 @@ import { useKeyboardHintsContext } from '@ui/tui/hooks/useKeyboardHints'; import { Colors } from '@ui/tui/styles'; export const KeyboardHintsBar = () => { - const { hints, visible } = useKeyboardHintsContext(); - - const showHints = visible && hints.length > 0; + const { hints } = useKeyboardHintsContext(); return ( - {showHints && - hints.map((hint, i) => ( - - - {hint.label} - - {hint.action} - - ))} + {hints.map((hint, i) => ( + + + {hint.label} + + {hint.action} + + ))} ); };