Skip to content

Commit

Permalink
add: local search via flexsearch
Browse files Browse the repository at this point in the history
  • Loading branch information
brianzinn committed Feb 20, 2022
1 parent 2eada3e commit 4fc50f2
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 77 deletions.
12 changes: 0 additions & 12 deletions packages/static/content/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,3 @@ Scene/Engine/Canvas.

[![NPM version](http://img.shields.io/npm/v/react-babylonjs.svg?style=flat-square)](https://www.npmjs.com/package/react-babylonjs)
[![NPM downloads](http://img.shields.io/npm/dm/react-babylonjs.svg?style=flat-square)](https://www.npmjs.com/package/react-babylonjs)

# Quickstart

```
npx create-react-babylon-js-app MyFirstApp
```

or

```
yarn create react-babylon-js-app MyFirstApp
```
7 changes: 0 additions & 7 deletions packages/static/content/introduction.md

This file was deleted.

18 changes: 16 additions & 2 deletions packages/static/content/nav.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
const toc = [
'/',
'/introduction',
'/quickstart',
'/guides/index',
'/guides/react-boilerplate/index',
'/guides/react-with-imperitive-babylonjs/index',
'/guides/react-with-declarative-babylonjs/index',
'/guides/animation/index',
'/guides/debugging/index',
'/guides/getting-even-more-reactive/index',
'/guides/hoc/index',
'/guides/adding-animation-and-color/index',
Expand All @@ -17,7 +18,20 @@ const navSortMap = toc.reduce((c, slug, i) => {
}, {})

const sortPages = (allMdx) => {
allMdx.edges.sort((a, b) => navSortMap[a.node.fields.slug] - navSortMap[b.node.fields.slug])
// console.log('nav sort map:', navSortMap);
allMdx.edges.sort((a, b) => {
const aIndex = navSortMap[a.node.fields.slug]
const bIndex = navSortMap[b.node.fields.slug]
if (aIndex === undefined) {
console.error('slug not found:', a.node.fields.slug)
return -1
}
if (bIndex === undefined) {
console.error('slug not found:', b.node.fields.slug)
return -1
}
return aIndex - bIndex
})
// console.log(JSON.stringify(allMdx, null, 2))

const slugs = allMdx.edges.map((e) => e.node.fields.slug)
Expand Down
34 changes: 34 additions & 0 deletions packages/static/content/quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: 'Quickstart'
metaTitle: 'Quickstart'
metaDescription: 'Guide to get started'
---

# Getting Started

When starting a Create React App (CRA) you optionally choose a template like:
`npx create-react-app my-app --template typescript`

> ```sh
> npx create-react-app my-app
> cd my-app
> ```
>
> or
>
> ```sh
> yarn create react-app my-app
> cd my-app
> ```
With that empty project, you just need to add the babylon dependencies:
> ```sh
> npm i react-babylonjs @babylonjs/core @babylonjs/gui
> ```
>
> or
>
> ```sh
> yarn add react-babylonjs @babylonjs/core @babylonjs/gui
> ```
42 changes: 42 additions & 0 deletions packages/static/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,48 @@ const plugins = [
extensions: ['.mdx', '.md'],
},
},
{
resolve: 'gatsby-plugin-local-search',
options: {
name: 'pages',
engine: 'flexsearch',
engineOptions: {
encode: 'icase',
tokenize: 'forward',
async: false,
},
query: `
{
allMdx {
edges {
node {
id
fields { slug }
excerpt
rawBody
frontmatter {
title
}
}
}
}
}
`,
ref: 'id',
index: ['title', 'rawBody'],
store: ['id', 'slug', 'description', 'title', 'excerpt', 'title'],
normalizer: ({ data }) => {
// console.log('check data', JSON.stringify(data));
return data.allMdx.edges.map((edge) => ({
id: edge.node.id,
slug: edge.node.fields.slug,
rawBody: edge.node.rawBody,
excerpt: edge.node.excerpt,
title: edge.node.frontmatter.title,
}))
},
},
},
{
resolve: `gatsby-plugin-gtag`,
options: {
Expand Down
3 changes: 3 additions & 0 deletions packages/static/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"gatsby-plugin-emotion": "^7.0.0",
"gatsby-plugin-gtag": "^1.0.13",
"gatsby-plugin-layout": "^3.0.0",
"gatsby-plugin-local-search": "^2.0.1",
"gatsby-plugin-manifest": "^4.0.0",
"gatsby-plugin-mdx": "^3.0.0",
"gatsby-plugin-offline": "^5.0.0",
Expand All @@ -46,6 +47,7 @@
"lodash.flatten": "^4.4.0",
"lodash.startcase": "^4.4.0",
"prismjs": "^1.23.0",
"query-string": "^7.1.1",
"react": "^17.0.2",
"react-babylonjs": "^3.0.31",
"react-dom": "^17.0.2",
Expand All @@ -56,6 +58,7 @@
"react-instantsearch-dom": "^6.11.0",
"react-live": "^2.2.3",
"react-loadable": "^5.5.0",
"react-use-flexsearch": "^0.1.1",
"styled-components": "^5.3.0",
"type-fest": "^2.9.0"
},
Expand Down
144 changes: 144 additions & 0 deletions packages/static/src/components/flexSearch/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { css } from '@emotion/core'
import { Link } from 'gatsby'
import * as queryString from 'query-string'
import React, { useState } from 'react'
import { useFlexSearch } from 'react-use-flexsearch'
import styled from 'styled-components'
import sortPages from '../../../content/nav'

const isBrowser = typeof window !== 'undefined'

const SearchBar = styled.div`
display: flex;
border: 1px solid #dfe1e5;
border-radius: 10px;
width: 100%;
height: 3rem;
background: #fdfdfd;
svg {
margin: auto 1rem;
height: 20px;
width: 20px;
color: #9aa0a6;
fill: #9aa0a6;
}
input {
display: flex;
flex: 100%;
height: 100%;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
Arial, sans-serif;
font-size: 16px;
background-color: transparent;
border: none;
margin: 0;
padding: 0;
padding-right: 0.5rem;
color: rgb(55, 53, 47);
word-wrap: break-word;
outline: none;
}
`

const SearchedResults = ({ results }) =>
results.length > 0 ? (
results.map((result) => {
// console.log('rendering result', result);
const node = {
node: {
fields: {
title: result.title,
slug: result.slug,
},
},
}
return <SidebarItem node={node} />
})
) : (
<p style={{ textAlign: 'center' }}>Sorry, couldn't find any posts matching this search.</p>
)

// node: {
// fields: {
// slug: string
// title: string
// }
// }
const SidebarItem = ({ node }) => {
const { fields } = node.node
const { slug, title } = fields
if (slug === '/') return null
const indent = (() => {
const parts = slug.slice(1).split('/')
// console.log(JSON.stringify(parts))
let level = parts.length - 1
// console.log(level)
if (parts.pop() === 'index') level--
// console.log(JSON.stringify(parts))
// console.log(level)
return level * 10
})()
const isSlugActive = isBrowser && window.location.href.endsWith(slug)
return (
<Link
to={slug}
css={css`
color: ${isSlugActive ? '#6c6cdd' : '#4a3636'};
/* font-weight: ${isSlugActive ? 'bold' : ''}; */
text-decoration: none;
display: block;
padding: 5px;
padding-left: ${indent}px;
width: 235px;
margin-left: 20px;
padding-right: 10px;
margin-bottom: 10px;
&:hover {
color: orange;
cursor: pointer;
}
`}
key={slug}
>
{title}
</Link>
)
}

const SidebarList = ({ nodes }) => {
return nodes.map((node) => <SidebarItem node={node} />)
}

const FlexSearch = ({ localSearchPages: { index, store }, location, allMdx }) => {
const { search } = queryString.parse(location.search)
const [query, setQuery] = useState(search || '')

const results = useFlexSearch(query, index, store)

sortPages(allMdx)

return (
<>
<SearchBar>
<svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
<input
id="search"
type="search"
placeholder="Search all content"
value={query}
onChange={(e) => {
// navigate(
// e.target.value ? `/blog/?search=${e.target.value}` : "/blog/"
// )
setQuery(e.target.value)
}}
/>
</SearchBar>
{query ? <SearchedResults results={results} /> : <SidebarList nodes={allMdx.edges} />}
</>
)
}

export default FlexSearch
Loading

0 comments on commit 4fc50f2

Please sign in to comment.