* initial implementation of search modal * added hit and search suggestions * added support for multiple indices * updated sample env * added close when click outside dropdown * test for mobile * added mobile design * added shortcut * dark mode fixes * added search to docs * added plugins filter * added React import * moved filters to configurations * handled error on page load * change suggestion text * removed hits limit * handle select all * open link in current tab * change highlight colors * added support for shortcuts + auto focus * change header and footer * redesigned search ui
71 lines
1.7 KiB
TypeScript
71 lines
1.7 KiB
TypeScript
import { useCallback, useEffect } from "react"
|
|
import { usePageLoading } from "../providers/page-loading"
|
|
|
|
type useKeyboardShortcutOptions = {
|
|
metakey?: boolean
|
|
shortcutKeys: string[]
|
|
action: (e: KeyboardEvent) => void
|
|
checkEditing?: boolean
|
|
preventDefault?: boolean
|
|
}
|
|
|
|
const useKeyboardShortcut = ({
|
|
metakey = true,
|
|
shortcutKeys,
|
|
action,
|
|
checkEditing = true,
|
|
preventDefault = true,
|
|
}: useKeyboardShortcutOptions) => {
|
|
const { isLoading } = usePageLoading()
|
|
|
|
function isEditingContent(event: KeyboardEvent) {
|
|
const element = event.target as HTMLElement
|
|
const tagName = element.tagName
|
|
return (
|
|
element.isContentEditable ||
|
|
tagName === "INPUT" ||
|
|
tagName === "SELECT" ||
|
|
tagName === "TEXTAREA"
|
|
)
|
|
}
|
|
|
|
const checkKeysPressed = useCallback(
|
|
(pressedKey: string) => {
|
|
const lowerPressedKey = pressedKey.toLowerCase()
|
|
return shortcutKeys.some(
|
|
(value) => lowerPressedKey === value.toLowerCase()
|
|
)
|
|
},
|
|
[shortcutKeys]
|
|
)
|
|
|
|
const sidebarShortcut = useCallback(
|
|
(e: KeyboardEvent) => {
|
|
if (isLoading) {
|
|
return
|
|
}
|
|
if (
|
|
(!metakey || e.metaKey || e.ctrlKey) &&
|
|
checkKeysPressed(e.key) &&
|
|
(!checkEditing || !isEditingContent(e))
|
|
) {
|
|
if (preventDefault) {
|
|
e.preventDefault()
|
|
}
|
|
action(e)
|
|
}
|
|
},
|
|
[isLoading, metakey, checkKeysPressed, checkEditing, action, preventDefault]
|
|
)
|
|
|
|
useEffect(() => {
|
|
window.addEventListener("keydown", sidebarShortcut)
|
|
|
|
return () => {
|
|
window.removeEventListener("keydown", sidebarShortcut)
|
|
}
|
|
}, [sidebarShortcut])
|
|
}
|
|
|
|
export default useKeyboardShortcut
|