Skip to content

Commit f71f352

Browse files
committed
Rewrite serach component to use local-search
1 parent b00d2b6 commit f71f352

File tree

3 files changed

+96
-119
lines changed

3 files changed

+96
-119
lines changed

theme/gatsby-config.js

Lines changed: 60 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module.exports = ({
66
sidebar,
77
print,
88
checkLinks = {},
9-
search = false,
9+
search = true,
1010
}) => ({
1111
siteMetadata: {
1212
title: 'Docs',
@@ -42,79 +42,7 @@ module.exports = ({
4242
`gatsby-plugin-material-ui`,
4343
`gatsby-plugin-react-helmet`,
4444
`gatsby-plugin-sharp`,
45-
{
46-
resolve: 'gatsby-plugin-local-search',
47-
options: {
48-
// A unique name for the search index. This should be descriptive of
49-
// what the index contains. This is required.
50-
name: 'pages',
51-
52-
// Set the search engine to create the index. This is required.
53-
// The following engines are supported: flexsearch, lunr
54-
engine: 'flexsearch',
55-
56-
// GraphQL query used to fetch all data for the search index. This is
57-
// required.
58-
query: `
59-
{
60-
allMarkdownRemark {
61-
nodes {
62-
id
63-
frontmatter {
64-
path
65-
title
66-
}
67-
rawMarkdownBody
68-
}
69-
}
70-
}
71-
`,
7245

73-
// Field used as the reference value for each document.
74-
// Default: 'id'.
75-
ref: 'id',
76-
77-
// List of keys to index. The values of the keys are taken from the
78-
// normalizer function below.
79-
// Default: all fields
80-
index: ['title', 'description', 'body'],
81-
82-
// List of keys to store and make available in your UI. The values of
83-
// the keys are taken from the normalizer function below.
84-
// Default: all fields
85-
store: ['title', 'id', 'description'],
86-
87-
// Function used to map the result from the GraphQL query. This should
88-
// return an array of items to index in the form of flat objects
89-
// containing properties to index. The objects must contain the `ref`
90-
// field above (default: 'id'). This is required.
91-
normalizer: ({ data }) =>
92-
data.allMarkdownRemark.nodes.map((node) => ({
93-
id: node.id,
94-
path: node.frontmatter.path,
95-
title: node.frontmatter.title,
96-
body: node.rawMarkdownBody,
97-
})),
98-
},
99-
},
100-
// {
101-
// resolve: `@gatsby-contrib/gatsby-plugin-elasticlunr-search`,
102-
// options: {
103-
// // don't index anything if search is off
104-
// // this retains schema entries but stops the effort.
105-
// fields: search ? [`title`, `description`, `content`] : [],
106-
// resolvers: {
107-
// Docs: {
108-
// title: (node) => node.title,
109-
// description: (node) => node.metaDescription,
110-
// // TODO: This is the full raw body, including front matter
111-
// content: (node) => node.rawBody,
112-
// slug: (node) => node.slug,
113-
// },
114-
// },
115-
// // TODO: Optional filter here, which would be useful for drafts?
116-
// },
117-
// },
11846
{
11947
resolve: `gatsby-plugin-layout`,
12048
options: {
@@ -186,5 +114,64 @@ module.exports = ({
186114
],
187115
},
188116
},
117+
{
118+
resolve: 'gatsby-plugin-local-search',
119+
options: {
120+
// A unique name for the search index. This should be descriptive of
121+
// what the index contains. This is required.
122+
name: 'pages',
123+
124+
// Set the search engine to create the index. This is required.
125+
// The following engines are supported: flexsearch, lunr
126+
engine: 'flexsearch',
127+
128+
// GraphQL query used to fetch all data for the search index. This is
129+
// required.
130+
query: `
131+
{
132+
allMdx {
133+
nodes {
134+
id
135+
slug
136+
frontmatter {
137+
title
138+
metaDescription
139+
}
140+
excerpt
141+
rawBody
142+
}
143+
}
144+
}
145+
`,
146+
147+
// Field used as the reference value for each document.
148+
// Default: 'id'.
149+
ref: 'id',
150+
151+
// List of keys to index. The values of the keys are taken from the
152+
// normalizer function below.
153+
// Default: all fields
154+
index: ['title', 'description', 'body'],
155+
156+
// List of keys to store and make available in your UI. The values of
157+
// the keys are taken from the normalizer function below.
158+
// Default: all fields
159+
store: ['id', 'slug', 'title', 'description', 'excerpt'],
160+
161+
// Function used to map the result from the GraphQL query. This should
162+
// return an array of items to index in the form of flat objects
163+
// containing properties to index. The objects must contain the `ref`
164+
// field above (default: 'id'). This is required.
165+
normalizer: ({ data }) =>
166+
data.allMdx.nodes.map((node) => ({
167+
id: node.id,
168+
slug: node.slug,
169+
title: node.frontmatter.title,
170+
description: node.frontmatter.description,
171+
excerpt: node.excerpt,
172+
body: node.rawBody,
173+
})),
174+
},
175+
},
189176
],
190177
})

theme/src/components/Search.tsx

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,14 @@ import {
88
TextField,
99
Typography,
1010
} from '@committed/components'
11-
import { Index } from 'elasticlunr'
12-
import React, {
13-
FC,
14-
useCallback,
15-
useContext,
16-
useEffect,
17-
useMemo,
18-
useState,
19-
} from 'react'
11+
import { useFlexSearch } from 'react-use-flexsearch'
12+
import React, { FC, useContext, useState } from 'react'
2013
import { DocsContext } from './Layout'
14+
import { withPrefix } from 'gatsby'
2115

2216
interface SearchProps {
2317
index: any
18+
store: any
2419
}
2520

2621
// These are defined through gatsby-node.js in the elasticlunr config
@@ -35,34 +30,16 @@ interface Result {
3530
export const Search: FC<SearchProps> = (props: SearchProps) => {
3631
const { navigate } = useContext(DocsContext)
3732

38-
const [query, setQuery] = useState('')
39-
const [results, setResults] = useState<Result[]>([])
33+
const [query, setQuery] = useState(null)
34+
const results = useFlexSearch(query, props.index, props.store)
4035

41-
const index = useMemo(() => {
42-
return Index.load(props.index)
43-
}, props.index)
44-
45-
const search = useCallback(() => {
46-
// Consider: Should we stop if query.length < 3?
47-
48-
const r = index
49-
// Expand allows for partial matches (mer matches mermaid)
50-
.search(query, JSON.parse('{ "expand": true }'))
51-
// Map over each ID and return the full document
52-
.map(({ ref }) => index.documentStore.getDoc(ref))
53-
54-
// Consider: Should be limit number of results?
55-
setResults(r)
56-
}, [index, query, setResults])
57-
58-
// Consider: Search as you type - possible not a good idea for larger sites?
59-
useEffect(() => search(), [query, search])
36+
console.log(results)
6037

6138
return (
6239
<>
6340
<Card>
6441
<CardContent>
65-
<Form display="flex" width={1} onSubmit={search}>
42+
<Form display="flex" width={1} onSubmit={(e) => e.preventDefault()}>
6643
<TextField
6744
flexGrow={1}
6845
id="query-input"
@@ -75,7 +52,7 @@ export const Search: FC<SearchProps> = (props: SearchProps) => {
7552
</Form>
7653
</CardContent>
7754
</Card>
78-
{results.length === 0 && query !== '' && (
55+
{results.length === 0 && query !== null && query !== '' && (
7956
<Typography variant="body1" gutterBottom>
8057
Sorry, no results found for "<i>{query}</i>"
8158
</Typography>
@@ -87,18 +64,28 @@ export const Search: FC<SearchProps> = (props: SearchProps) => {
8764
Found {results.length} results for "<i>{query}</i>".
8865
</Typography>
8966
<List>
90-
{results.map((r) => (
91-
<ListItem
92-
key={r.id}
93-
button
94-
onClick={() => {
95-
navigate(r.slug)
96-
}}
97-
>
98-
{r.title}
99-
{r.description && <small>: {r.description}</small>}
100-
</ListItem>
101-
))}
67+
{results.map((r) => {
68+
let desc = r.description || r.excerpt
69+
return (
70+
<ListItem
71+
key={r.id}
72+
button
73+
onClick={() => {
74+
// TODO: slug = test/mdTest is wrong, so we lowerc ase.
75+
// I don't know if there's a bug somewhere else (or ig we are wrong to have an upper case in our filename)
76+
navigate(withPrefix(r.slug.toLowerCase()))
77+
}}
78+
>
79+
<div>
80+
<b>
81+
{r.title || 'Untitled'}
82+
{desc ? ': ' : ''}
83+
</b>
84+
<small>{desc}</small>
85+
</div>
86+
</ListItem>
87+
)
88+
})}
10289
</List>
10390
</CardContent>
10491
</Card>

theme/src/layout/search.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ export default () => (
77
<StaticQuery
88
query={graphql`
99
query SearchIndexQuery {
10-
siteSearchIndex {
10+
localSearchPages {
1111
index
12+
store
1213
}
1314
}
1415
`}
15-
render={({ siteSearchIndex: { index } }) => <Search index={index} />}
16+
render={({ localSearchPages: { index, store } }) => (
17+
<Search index={index} store={store} />
18+
)}
1619
/>
1720
)

0 commit comments

Comments
 (0)