How to Focus an Input Field with a Hotkey in React

How to Focus an Input Field with a Hotkey in React

Have you ever wondered how to set a hotkey to focus an input field in your React application? Follow along to learn how. We'll even handle showing different hotkeys based on whether the user is on a Mac or Windows system.

Implementation

const SearchInput: FC = () => {
  const inputRef = useRef<HTMLInputElement>(null);
  const [actionKey, setActionKey] = useState<string>('');

  useEffect(() => {
    // check if navigator is defined to prevent unexpected errors if browser does not support
    if (typeof navigator !== 'undefined') {
      if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
        setActionKey('⌘K');
      } else {
        setActionKey('CtrlK');
      }
    }

    const handleKeyPress = (event: KeyboardEvent) => {
      let hotkey = false;
      if (typeof navigator !== 'undefined') {
        if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
          hotkey = event.metaKey && event.key === 'k';
        } else {
          hotkey = event.ctrlKey && event.key === 'k';
        }
      }

      if (hotkey && inputRef.current) {
        inputRef.current.focus();
      }
    };

    // Add event listener when the component mounts
    document.addEventListener('keydown', handleKeyPress);

    // Clean up the event listener when the component unmounts
    return () => {
      document.removeEventListener('keydown', handleKeyPress);
    };
  }, []);

  return (
    <div className="relative">
      <input
        ref={inputRef}
        type="text"
        className="peer block w-full border-0 px-0 py-3 text-xl focus:ring-0  sm:leading-6"
      />
      {actionKey && (
        <div className="absolute inset-y-0 right-0 flex py-3 pr-1.5">
          <kbd className="inline-flex items-center rounded border border-zinc-300 px-1 font-sans text-xs text-zinc-400">
            {actionKey}
          </kbd>
        </div>
      )}
    </div>
  );
};
  • We use the useRef hook to create a reference to the input element.

  • We use the useEffect hook to add an event listener for the specified hotkey.

  • navigator.platform is used to determine if the user is using a mac or windows machine so we know what hotkey to display and listen to.

  • calling inputRef.current.focus() will focus the input if the hotkey is pressed

  • <kbd /> html element is used to denote textual user input from a keyboard MDN

  • navigator.platform is technically deprecated and you could use navigator.userAgent as an alternative.