diff --git a/frontend/src/components/ui/input-search.tsx b/frontend/src/components/ui/input-search.tsx index dbb15915..571f94bd 100644 --- a/frontend/src/components/ui/input-search.tsx +++ b/frontend/src/components/ui/input-search.tsx @@ -1,9 +1,11 @@ import { Search } from 'lucide-react'; import { motion } from 'motion/react'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from '@/components/ui/input-group'; +import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; import { cn } from '@/lib/utils'; +import { isMac } from '@/lib/utils/platform'; interface InputSearchProps { /** Accessible label for the trigger button + the input. */ @@ -58,6 +60,20 @@ export function InputSearch({ const expand = useCallback(() => setIsExpanded(true), []); + // Hint shown over the collapsed trigger. The hotkey suffix mirrors the + // platform's modifier glyph (⌘ on Apple, Ctrl elsewhere) so the tooltip + // is actionable — the user sees the exact keys they can press without + // having to discover them by trial. + const tooltipText = useMemo(() => { + if (!hotkey) { + return placeholder; + } + + const modifier = isMac() ? '⌘' : 'Ctrl'; + + return `${placeholder} (${modifier} ${hotkey.toUpperCase()})`; + }, [hotkey, placeholder]); + // Focus the input the frame after it appears. `rAF` defers past the same // commit so motion's transform has started, otherwise focus can land on // a still-zero-width box and the user's caret blinks invisibly until the @@ -175,15 +191,20 @@ export function InputSearch({ className="text-muted-foreground" /> ) : ( - - + + + + + + {tooltipText} + )}