Skip to content

Commit

Permalink
Focus Opcode-Search on Alt+K (#278)
Browse files Browse the repository at this point in the history
  • Loading branch information
lmittmann authored Dec 14, 2023
1 parent 080c358 commit e8f9816
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 49 deletions.
17 changes: 16 additions & 1 deletion components/Reference/Filters.tsx
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -33,6 +33,8 @@ const Filters = ({ onSetFilter, isPrecompiled = false }: Props) => {
[isPrecompiled],
)

const inputRef = useRef<HTMLInputElement>(null)

const handleKeywordChange = debounce(
(value: string) => onSetFilter(searchFilter.value, value),
debounceTimeout,
Expand All @@ -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
Expand All @@ -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])

Expand All @@ -78,6 +92,7 @@ const Filters = ({ onSetFilter, isPrecompiled = false }: Props) => {
</div>

<Input
ref={inputRef}
searchable
value={searchKeyword}
onChange={(e) => {
Expand Down
112 changes: 64 additions & 48 deletions components/ui/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,64 +1,80 @@
import React, { useState } from 'react'
import React, { useState, ForwardedRef, forwardRef } from 'react'

import cn from 'classnames'

import { Icon } from './Icon'

type Props = {
searchable?: boolean
ref?: ForwardedRef<HTMLInputElement>
className?: string
} & React.ComponentPropsWithoutRef<'input'>

export const Input: React.FC<Props> = ({
searchable = false,
onFocus,
onBlur,
className,
...rest
}) => {
const [isFocused, setIsFocused] = useState(false)
export const Input: React.FC<Props> = forwardRef(
(
{ searchable = false, onFocus, onBlur, className, ...rest },
ref: ForwardedRef<HTMLInputElement>,
) => {
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 (
<div
className={cn(
'flex items-center rounded px-3 py-2',
{
shadow: isFocused,
},
className,
)}
>
<input
onFocus={handleFocus}
onBlur={handleBlur}
className="w-full outline-none bg-transparent dark:placeholder-black-400 text-sm"
{...rest}
/>
{searchable && (
<Icon
name="search-line"
className={cn(
'ml-2',
isFocused
? 'text-gray-400 dark:text-gray-300'
: 'text-gray-300 dark:text-gray-400',
)}
const handleInput = (e: any) => {
if (e.target.value === '') {
setIsInputEmpty(true)
} else {
setIsInputEmpty(false)
}
}

return (
<div
className={cn(
'flex items-center rounded px-3 py-2 text-sm relative',
{
shadow: isFocused,
},
className,
)}
>
<input
ref={ref}
onFocus={handleFocus}
onBlur={handleBlur}
onInput={handleInput}
className="w-full outline-none bg-transparent dark:placeholder-black-400"
{...rest}
/>
)}
</div>
)
}
{searchable && (
<>
{isInputEmpty && (
<span className="text-black-400 absolute right-8">Alt+K</span>
)}
<Icon
name="search-line"
className={cn(
'ml-2',
isFocused
? 'text-gray-400 dark:text-gray-300'
: 'text-gray-300 dark:text-gray-400',
)}
/>
</>
)}
</div>
)
},
)

1 comment on commit e8f9816

@vercel
Copy link

@vercel vercel bot commented on e8f9816 Dec 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.