Skip to content

Instantly share code, notes, and snippets.

@dclstn
Created May 23, 2023 18:41
Show Gist options
  • Select an option

  • Save dclstn/053e946165a865827d990b55db4f8e2f to your computer and use it in GitHub Desktop.

Select an option

Save dclstn/053e946165a865827d990b55db4f8e2f to your computer and use it in GitHub Desktop.
Implementation of an Autocomplete Input in Chakra UI
import {Box, Input, Text} from '@chakra-ui/react';
import React from 'react';
interface AutocompleteInputProps {
value: string;
matches: {label: string; value: string}[];
onChange: (value: string) => void;
}
export default function AutocompleteInput({
matches,
onChange,
...props
}: Omit<React.ComponentProps<typeof Input>, 'onChange'> & AutocompleteInputProps) {
const [focused, setFocused] = React.useState(false);
const inputRef = React.useRef<HTMLInputElement>(null);
React.useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (!focused || event.target == null) {
return;
}
if (inputRef.current && !inputRef.current.contains(event.target as Node)) {
setFocused(false);
}
};
document.addEventListener('click', handleClickOutside);
return () => {
document.removeEventListener('click', handleClickOutside);
};
}, [focused, inputRef]);
return (
<>
<Input
{...props}
ref={inputRef}
onFocus={() => setFocused(true)}
onChange={({target: {value: inputValue}}) => onChange(inputValue)}
/>
{focused && matches.length > 0 ? (
<Box
boxShadow="md"
borderBottomRadius="md"
bgColor="gray.800"
borderWidth="0px 1px 1px 1px"
pos="absolute"
zIndex={1}
w="100%">
{matches.map(({label, value: matchValue}) => (
<Box
key={label}
cursor="pointer"
_hover={{bgColor: 'gray.700'}}
onClick={() => {
setFocused(false);
onChange(matchValue);
}}
px={4}
py={2}
justifyContent="space-between">
<Text>{label}</Text>
</Box>
))}
</Box>
) : null}
</>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment