Files
lucide/site/src/components/IconOverview.tsx

120 lines
2.9 KiB
TypeScript
Raw Normal View History

import {
Box,
Input,
InputGroup,
InputLeftElement,
Text,
useColorMode,
Icon,
2021-04-30 01:19:45 +02:00
} from '@chakra-ui/react';
import IconList from './IconList';
2020-11-16 12:05:34 +01:00
import { useEffect, useMemo, useRef, useState } from 'react';
import useSearch from '../lib/useSearch';
import { useRouter } from 'next/router';
import theme from '../lib/theme';
import { Search as SearchIcon } from 'lucide-react';
2020-11-16 12:05:34 +01:00
import debounce from 'lodash/debounce';
const isFilledString = (string) => string !== undefined && string !== null && string !== '';
const IconOverview = ({ data }) => {
const router = useRouter();
2020-11-16 12:05:34 +01:00
const { search } = router.query;
const [queryText, setQueryText] = useState(search);
const { colorMode } = useColorMode();
const inputElement = useRef(null);
function handleKeyDown(event) {
if (event.key === '/' && inputElement.current !== document.activeElement) {
event.preventDefault();
inputElement.current.focus();
}
}
2020-11-16 12:05:34 +01:00
const setQueryParam = (searchString) => {
const { query, asPath } = router;
if(isFilledString(searchString)) {
let route = {
pathname: '',
query
}
2020-11-16 12:05:34 +01:00
if(query.iconName) {
route.query.iconName = query.iconName;
route.pathname = '/icon/[iconName]';
}
2020-11-16 12:05:34 +01:00
route.query.search = searchString;
router.replace(route);
}
else {
if (query?.search) {
delete query.search;
router.replace({
query
})
}
}
}
// @ts-ignore
const searchResults = useMemo(() => useSearch(data, queryText), [data, queryText])
const handleSearchInput = debounce((event) => {
event.persist();
const { value = '' } = inputElement?.current;
setQueryText(value)
setQueryParam(value)
}, 400)
useEffect(() => {
setQueryText(search)
}, [search]);
useEffect(() => {
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, []);
return (
<>
<InputGroup position="sticky" top={4} zIndex={1}>
<InputLeftElement
children={
<Icon>
<SearchIcon />
</Icon>
}
/>
<Input
ref={inputElement}
placeholder={`Search ${Object.keys(data).length} icons (Press "/" to focus)`}
2020-11-16 12:05:34 +01:00
onChange={handleSearchInput}
defaultValue={queryText}
bg={colorMode == 'light' ? theme.colors.white : theme.colors.gray[700]}
/>
</InputGroup>
<Box marginTop={5}>
2020-11-16 12:05:34 +01:00
{searchResults.length > 0 ? (
<IconList icons={searchResults} />
) : (
<Text
fontSize="2xl"
fontWeight="bold"
textAlign="center"
style={{ wordBreak: 'break-word' }}
>
2020-11-16 12:05:34 +01:00
No results found for "{queryText}"
</Text>
)}
</Box>
</>
);
};
export default IconOverview;