How to Focus an Input Field with a Hotkey in React

RMAG news

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.

Leave a Reply

Your email address will not be published. Required fields are marked *