Skip to content

Commit

Permalink
feat(hooks): document query suggestions (#396)
Browse files Browse the repository at this point in the history
Co-authored-by: Sarah Dayan <[email protected]>
  • Loading branch information
dhayab and sarahdayan authored Jul 7, 2022
1 parent 2a3342c commit e34bde4
Show file tree
Hide file tree
Showing 14 changed files with 2,025 additions and 0 deletions.
8 changes: 8 additions & 0 deletions react-instantsearch-hooks/query-suggestions/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
23 changes: 23 additions & 0 deletions react-instantsearch-hooks/query-suggestions/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
.parcel-cache
*.local

# Editor directories and files
.vscode
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
5 changes: 5 additions & 0 deletions react-instantsearch-hooks/query-suggestions/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"singleQuote": true,
"proseWrap": "never",
"trailingComma": "es5"
}
19 changes: 19 additions & 0 deletions react-instantsearch-hooks/query-suggestions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# query-suggestions

_This project was generated with [create-instantsearch-app](https://github.com/algolia/create-instantsearch-app) by [Algolia](https://algolia.com)._

## Get started

To run this project locally, install the dependencies and run the local server:

```sh
npm install
npm start
```

Alternatively, you may use [Yarn](https://http://yarnpkg.com/):

```sh
yarn
yarn start
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions react-instantsearch-hooks/query-suggestions/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>

<link rel="shortcut icon" href="favicon.png">

<!--
Do not use @7 in production, use a complete version like x.x.x, see website for latest version:
https://www.algolia.com/doc/guides/building-search-ui/installation/react/#load-the-style
-->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css"
/>

<title>query-suggestions</title>
</head>

<body>
<noscript> You need to enable JavaScript to run this app. </noscript>

<div id="root"></div>

<script type="module" src="src/index.tsx"></script>
</body>
</html>
23 changes: 23 additions & 0 deletions react-instantsearch-hooks/query-suggestions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "query-suggestions",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "parcel index.html",
"build": "parcel build index.html"
},
"dependencies": {
"@algolia/autocomplete-js": "1.7.0",
"@algolia/autocomplete-plugin-query-suggestions": "1.7.0",
"@algolia/autocomplete-theme-classic": "1.7.0",
"algoliasearch": "4",
"instantsearch.js": "4.40.5",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-instantsearch-hooks-web": "6.29.0"
},
"devDependencies": {
"@types/react": "17.0.45",
"parcel": "2.5.0"
}
}
35 changes: 35 additions & 0 deletions react-instantsearch-hooks/query-suggestions/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
body,
h1 {
margin: 0;
padding: 0;
}

body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}

.container {
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
}

.current-refinements {
display: flex;
align-items: center;
padding: 1rem 0;
min-height: 64px;
}

@media screen and (max-width: 768px) {
.ais-Hits .ais-Hits-item {
width: calc(50% - 1rem);
}
}

@media screen and (max-width: 480px) {
.ais-Hits .ais-Hits-item {
width: 100%;
}
}
45 changes: 45 additions & 0 deletions react-instantsearch-hooks/query-suggestions/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
Configure,
CurrentRefinements,
Highlight,
Hits,
InstantSearch,
} from 'react-instantsearch-hooks-web';

import './App.css';

import type { Hit } from 'instantsearch.js';

import { SearchBoxWithSuggestions } from './SearchBoxWithSuggestions';
import { searchClient } from './searchClient';

export function App() {
return (
<div className="container">
<InstantSearch searchClient={searchClient} indexName="instant_search">
<Configure hitsPerPage={16} />

<SearchBoxWithSuggestions />

<CurrentRefinements
className="current-refinements"
includedAttributes={['query', 'categories']}
/>

<Hits hitComponent={Hit} />
</InstantSearch>
</div>
);
}

type HitProps = {
hit: Hit;
};

function Hit({ hit }: HitProps) {
return (
<article>
<Highlight attribute="name" hit={hit} />
</article>
);
}
31 changes: 31 additions & 0 deletions react-instantsearch-hooks/query-suggestions/src/Autocomplete.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { createElement, Fragment, useEffect, useRef } from 'react';
import { render } from 'react-dom';

import { autocomplete } from '@algolia/autocomplete-js';

import type { AutocompleteOptions } from '@algolia/autocomplete-js';
import type { BaseItem } from '@algolia/autocomplete-core';

import '@algolia/autocomplete-theme-classic';

type AutocompleteProps = Partial<AutocompleteOptions<BaseItem>>;

export function Autocomplete(props: AutocompleteProps) {
const containerRef = useRef<HTMLDivElement>(null);

useEffect(() => {
if (!containerRef.current) {
return;
}

const search = autocomplete({
...props,
container: containerRef.current,
renderer: { createElement, Fragment, render },
});

return () => search.destroy();
}, [props]);

return <div ref={containerRef} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useCallback, useMemo } from 'react';

import { createQuerySuggestionsPlugin } from '@algolia/autocomplete-plugin-query-suggestions';
import {
useInstantSearch,
useMenu,
useSearchBox,
} from 'react-instantsearch-hooks-web';

import { Autocomplete } from './Autocomplete';
import { searchClient } from './searchClient';

export function SearchBoxWithSuggestions() {
const { setIndexUiState } = useInstantSearch();
const { query } = useSearchBox();
useMenu({ attribute: 'categories' });

const plugins = useMemo(() => {
const querySuggestionsPlugin = createQuerySuggestionsPlugin({
indexName: 'instant_search_demo_query_suggestions',
searchClient,
categoryAttribute: [
'instant_search',
'facets',
'exact_matches',
'categories',
],
transformSource({ source }) {
return {
...source,
onSelect({ item }) {
setIndexUiState((indexUiState) => ({
...indexUiState,
query: item.query,
menu: {
categories: item.__autocomplete_qsCategory || '',
},
}));
},
};
},
});

return [querySuggestionsPlugin];
}, []);

const initialState = useMemo(() => ({ query }), [query]);

const onReset = useCallback(
() =>
setIndexUiState((indexUiState) => ({
...indexUiState,
query: '',
menu: { categories: '' },
})),
[]
);

return (
<Autocomplete
placeholder="Search for products..."
plugins={plugins}
initialState={initialState}
onReset={onReset}
/>
);
}
5 changes: 5 additions & 0 deletions react-instantsearch-hooks/query-suggestions/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import ReactDOM from 'react-dom';

import { App } from './App';

ReactDOM.render(<App />, document.getElementById('root'));
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import algoliasearch from 'algoliasearch/lite';

export const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
Loading

0 comments on commit e34bde4

Please sign in to comment.