Co-authored-by: Renovate Bot <bot@renovateapp.com> Co-authored-by: Samuel Bodin <1637651+bodinsamuel@users.noreply.github.com> Co-authored-by: Clément Vannicatte <vannicattec@gmail.com>
73 lines
1.9 KiB
TypeScript
73 lines
1.9 KiB
TypeScript
import React from 'react';
|
|
|
|
export interface UseDocSearchKeyboardEventsProps {
|
|
isOpen: boolean;
|
|
onOpen: () => void;
|
|
onClose: () => void;
|
|
onInput?: (event: KeyboardEvent) => void;
|
|
searchButtonRef?: React.RefObject<HTMLButtonElement>;
|
|
}
|
|
|
|
function isEditingContent(event: KeyboardEvent): boolean {
|
|
const element = event.target as HTMLElement;
|
|
const tagName = element.tagName;
|
|
|
|
return (
|
|
element.isContentEditable ||
|
|
tagName === 'INPUT' ||
|
|
tagName === 'SELECT' ||
|
|
tagName === 'TEXTAREA'
|
|
);
|
|
}
|
|
|
|
export function useDocSearchKeyboardEvents({
|
|
isOpen,
|
|
onOpen,
|
|
onClose,
|
|
onInput,
|
|
searchButtonRef,
|
|
}: UseDocSearchKeyboardEventsProps) {
|
|
React.useEffect(() => {
|
|
function onKeyDown(event: KeyboardEvent) {
|
|
function open() {
|
|
// We check that no other DocSearch modal is showing before opening
|
|
// another one.
|
|
if (!document.body.classList.contains('DocSearch--active')) {
|
|
onOpen();
|
|
}
|
|
}
|
|
if (
|
|
(event.keyCode === 27 && isOpen) ||
|
|
// The `Cmd+K` shortcut both opens and closes the modal.
|
|
(event.key === 'k' && (event.metaKey || event.ctrlKey)) ||
|
|
// The `/` shortcut opens but doesn't close the modal because it's
|
|
// a character.
|
|
(!isEditingContent(event) && event.key === '/' && !isOpen)
|
|
) {
|
|
event.preventDefault();
|
|
|
|
if (isOpen) {
|
|
onClose();
|
|
} else if (!document.body.classList.contains('DocSearch--active')) {
|
|
open();
|
|
}
|
|
}
|
|
|
|
if (
|
|
searchButtonRef &&
|
|
searchButtonRef.current === document.activeElement &&
|
|
onInput
|
|
) {
|
|
if (/[a-zA-Z0-9]/.test(String.fromCharCode(event.keyCode))) {
|
|
onInput(event);
|
|
}
|
|
}
|
|
}
|
|
|
|
window.addEventListener('keydown', onKeyDown);
|
|
|
|
return () => {
|
|
window.removeEventListener('keydown', onKeyDown);
|
|
};
|
|
}, [isOpen, onOpen, onClose, onInput, searchButtonRef]);
|
|
}
|