Skip to content

Commit b734afa

Browse files
committed
Fuzzy search works almost lag-less
1 parent ec03764 commit b734afa

File tree

5 files changed

+64
-14
lines changed

5 files changed

+64
-14
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
"@testing-library/react": "^11.1.0",
1111
"@testing-library/user-event": "^12.1.10",
1212
"framer-motion": "^4.1.11",
13+
"fuse.js": "^6.4.6",
14+
"lodash": "^4.17.21",
1315
"react": "^17.0.2",
1416
"react-dom": "^17.0.2",
1517
"react-icons": "^4.2.0",

src/App.js

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,97 @@
1+
import React, { useState, useCallback } from 'react'
2+
import _ from 'lodash'
13
import data from './data/ps1_data.json'
24
import { Box, Flex } from '@chakra-ui/layout';
5+
import Fuse from 'fuse.js'
36

47
import List from './components/List';
58
import Filters from './components/Filters'
69
import SearchBar from './components/SearchBar';
710

11+
const SEARCH_DEBOUNCE_PERIOD = 10
12+
13+
data.pop()
14+
815
function App() {
9-
data.pop()
16+
const [stations, setStations] = useState(data)
17+
const [searchVal, setSearchVal] = useState('')
18+
19+
const options = {
20+
keys: [
21+
{
22+
name: 'name',
23+
weight: 10
24+
},
25+
{
26+
name: 'projects.title',
27+
weight: 4
28+
},
29+
{
30+
name: 'projects.description',
31+
weight: 2
32+
}
33+
]
34+
}
35+
const searchIndex = Fuse.createIndex(options.keys, stations)
36+
const fuse = new Fuse(stations, options, searchIndex)
37+
38+
function onSearch(query) {
39+
if (query === '') {
40+
return data
41+
}
42+
const results = fuse.search(query).map(({ item }) => item)
43+
return results
44+
}
45+
46+
const performSearch = useCallback(_.debounce((query) => {
47+
const results = onSearch(query)
48+
setStations(results)
49+
}, SEARCH_DEBOUNCE_PERIOD), [])
50+
51+
function onSearchValueChange(query) {
52+
performSearch(query)
53+
}
54+
55+
1056
return (
1157
<Flex
1258
height="100vh"
13-
// bg="gray.50"
1459
justifyContent="center"
15-
// overflow="hidden"
1660
>
1761
<Box
1862
position="relative"
1963
display="flex"
2064
flexDirection="column"
21-
// bg="red"
2265
height="100vh"
23-
// mt="150px"
2466
>
2567
<Filters/>
2668
<Box
2769
ml="350px"
28-
// bg="tomato"
2970
position="relative"
3071
flex="1 1 auto"
3172
minWidth="1200px"
3273
display="flex"
3374
flexDirection="column"
34-
// height="100%"
3575
>
3676
<Box
3777
width="100%"
3878
height="80px"
39-
// bg="aqua"
4079
display="flex"
4180
alignItems="center"
4281
position="absolute"
4382
>
44-
<SearchBar/>
83+
<SearchBar
84+
onSearch={onSearchValueChange}
85+
/>
4586
</Box>
4687

4788
<Box
48-
// bg="yellow"
4989
height="100%"
5090
boxSizing='border-box'
5191
mt="80px"
5292
flex="1 1 auto"
5393
>
54-
<List stations={data}/>
94+
<List stations={stations}/>
5595
</Box>
5696

5797
</Box>

src/components/Filters.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const Filters = (props) => {
1717
boxSizing='border-box'
1818
padding='8px'
1919
>
20-
Bruh
20+
2121
</Box>
2222
)
2323
}

src/components/SearchBar.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react'
1+
import React, { useCallback } from 'react'
22
import {
33
Box,
44
Input,
@@ -10,6 +10,7 @@ import {
1010
import { FiSearch } from 'react-icons/fi'
1111
import { FaSearch } from 'react-icons/fa'
1212

13+
1314
const SearchBar = (props) => {
1415
const Icon = (
1516
<Box>
@@ -31,6 +32,8 @@ const SearchBar = (props) => {
3132
placeholder="Search"
3233
variant="filled"
3334
height="42px"
35+
onChange={(e) => props.onSearch(e.target.value)}
36+
// value={props.value}
3437
/>
3538
</InputGroup>
3639
</Box>

yarn.lock

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5894,6 +5894,11 @@ functional-red-black-tree@^1.0.1:
58945894
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
58955895
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
58965896

5897+
fuse.js@^6.4.6:
5898+
version "6.4.6"
5899+
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-6.4.6.tgz#62f216c110e5aa22486aff20be7896d19a059b79"
5900+
integrity sha512-/gYxR/0VpXmWSfZOIPS3rWwU8SHgsRTwWuXhyb2O6s7aRuVtHtxCkR33bNYu3wyLyNx/Wpv0vU7FZy8Vj53VNw==
5901+
58975902
gensync@^1.0.0-beta.1:
58985903
version "1.0.0-beta.2"
58995904
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@@ -7704,7 +7709,7 @@ lodash.uniq@^4.5.0:
77047709
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
77057710
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
77067711

7707-
"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5:
7712+
"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5:
77087713
version "4.17.21"
77097714
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
77107715
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==

0 commit comments

Comments
 (0)