diff --git a/components/Reference/Filters.tsx b/components/Reference/Filters.tsx index 81e8c37c..3729823e 100644 --- a/components/Reference/Filters.tsx +++ b/components/Reference/Filters.tsx @@ -1,4 +1,4 @@ -import { useState, useMemo, useEffect } from 'react' +import { useState, useMemo, useEffect, useRef } from 'react' import debounce from 'lodash.debounce' import { useRouter } from 'next/router' @@ -33,6 +33,8 @@ const Filters = ({ onSetFilter, isPrecompiled = false }: Props) => { [isPrecompiled], ) + const inputRef = useRef(null) + const handleKeywordChange = debounce( (value: string) => onSetFilter(searchFilter.value, value), debounceTimeout, @@ -45,6 +47,13 @@ const Filters = ({ onSetFilter, isPrecompiled = false }: Props) => { setSearchFilter(option) } + const handleAltK = (event: KeyboardEvent) => { + if (event.altKey && event.key.toLowerCase() === 'k') { + inputRef.current?.focus() + inputRef.current?.value && inputRef.current.select() + } + } + // Change filter and search opcode according to query param useEffect(() => { const query = router.query @@ -56,6 +65,11 @@ const Filters = ({ onSetFilter, isPrecompiled = false }: Props) => { handleKeywordChange(query.name as string) router.push(router) } + + // Register and clean up Alt+K event listener + window.addEventListener('keydown', handleAltK) + return () => window.removeEventListener('keydown', handleAltK) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [router.isReady]) @@ -78,6 +92,7 @@ const Filters = ({ onSetFilter, isPrecompiled = false }: Props) => { { diff --git a/components/ui/Input.tsx b/components/ui/Input.tsx index 3c523f29..2b85edd6 100644 --- a/components/ui/Input.tsx +++ b/components/ui/Input.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useState, ForwardedRef, forwardRef } from 'react' import cn from 'classnames' @@ -6,59 +6,75 @@ import { Icon } from './Icon' type Props = { searchable?: boolean + ref?: ForwardedRef className?: string } & React.ComponentPropsWithoutRef<'input'> -export const Input: React.FC = ({ - searchable = false, - onFocus, - onBlur, - className, - ...rest -}) => { - const [isFocused, setIsFocused] = useState(false) +export const Input: React.FC = forwardRef( + ( + { searchable = false, onFocus, onBlur, className, ...rest }, + ref: ForwardedRef, + ) => { + const [isFocused, setIsFocused] = useState(false) + const [isInputEmpty, setIsInputEmpty] = useState(true) - const handleFocus = (e: any) => { - setIsFocused(true) - if (onFocus) { - onFocus(e) + const handleFocus = (e: any) => { + setIsFocused(true) + if (onFocus) { + onFocus(e) + } } - } - const handleBlur = (e: any) => { - setIsFocused(false) - if (onBlur && e) { - onBlur(e) + const handleBlur = (e: any) => { + setIsFocused(false) + if (onBlur && e) { + onBlur(e) + } } - } - return ( -
- - {searchable && ( - { + if (e.target.value === '') { + setIsInputEmpty(true) + } else { + setIsInputEmpty(false) + } + } + + return ( +
+ - )} -
- ) -} + {searchable && ( + <> + {isInputEmpty && ( + Alt+K + )} + + + )} +
+ ) + }, +)