Skip to content

Commit

Permalink
docs(instantsearch): keep autocomplete in sync with query during navi…
Browse files Browse the repository at this point in the history
…gation (#1036)
  • Loading branch information
dhayab committed Nov 3, 2022
1 parent 006c113 commit d0ca975
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 108 deletions.
4 changes: 0 additions & 4 deletions examples/instantsearch/env.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import * as preact from 'preact';

// Parcel picks the `source` field of the monorepo packages and thus doesn't
// apply the Babel config. We therefore need to manually override the constants
// in the app, as well as the React pragmas.
// See https://twitter.com/devongovett/status/1134231234605830144
(global as any).__DEV__ = process.env.NODE_ENV !== 'production';
(global as any).__TEST__ = false;
(global as any).h = preact.h;
(global as any).React = preact;
7 changes: 3 additions & 4 deletions examples/instantsearch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
"@algolia/autocomplete-plugin-query-suggestions": "1.7.3",
"@algolia/autocomplete-plugin-recent-searches": "1.7.3",
"@algolia/autocomplete-theme-classic": "1.7.3",
"@algolia/client-search": "4.9.1",
"algoliasearch": "4.9.1",
"instantsearch.js": "4.22.0",
"preact": "10.5.13"
"@algolia/client-search": "4.14.2",
"algoliasearch": "4.14.2",
"instantsearch.js": "4.49.0"
},
"devDependencies": {
"parcel": "2.7.0"
Expand Down
2 changes: 1 addition & 1 deletion examples/instantsearch/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ import { startAutocomplete } from './autocomplete';
import { search } from './instantsearch';

search.start();
startAutocomplete();
startAutocomplete(search);
120 changes: 62 additions & 58 deletions examples/instantsearch/src/autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { autocomplete } from '@algolia/autocomplete-js';
import { createQuerySuggestionsPlugin } from '@algolia/autocomplete-plugin-query-suggestions';
import { createLocalStorageRecentSearchesPlugin } from '@algolia/autocomplete-plugin-recent-searches';
import { h, Fragment } from 'preact';
import { InstantSearch } from 'instantsearch.js';

import {
debouncedSetInstantSearchUiState,
Expand Down Expand Up @@ -42,29 +42,27 @@ function getItemUrl({ query, category }) {
});
}

function ItemWrapper({ children, query, category }) {
function getItemWrapper({ html, children, query, category }) {
const uiState = {
query,
hierarchicalMenu: {
[INSTANT_SEARCH_HIERARCHICAL_ATTRIBUTE]: [category],
},
};

return (
<a
className="aa-ItemLink"
href={getInstantSearchUrl(uiState)}
onClick={(event) => {
if (!isModifierEvent(event)) {
// Bypass the original link behavior if there's no event modifier
// to set the InstantSearch UI state without reloading the page.
event.preventDefault();
}
}}
>
{children}
</a>
);
return html`<a
class="aa-ItemLink"
href=${getInstantSearchUrl(uiState)}
onClick=${(event) => {
if (!isModifierEvent(event)) {
// Bypass the original link behavior if there's no event modifier
// to set the InstantSearch UI state without reloading the page.
event.preventDefault();
}
}}
>
${children}
</a>`;
}

const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
Expand Down Expand Up @@ -94,15 +92,14 @@ const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
// and plug it to the InstantSearch router.
item(params) {
const { children } = (source.templates.item(params) as any).props;
const { item, html } = params;

return (
<ItemWrapper
query={params.item.label}
category={params.item.category}
>
{children}
</ItemWrapper>
);
return getItemWrapper({
query: item.label,
category: item.category,
html,
children,
});
},
},
};
Expand All @@ -115,7 +112,7 @@ const querySuggestionsPluginInCategory = createQuerySuggestionsPlugin({
getSearchParams() {
const currentCategory = getInstantSearchCurrentCategory();

return recentSearchesPlugin.data.getAlgoliaSearchParams({
return recentSearchesPlugin.data!.getAlgoliaSearchParams({
hitsPerPage: 3,
facetFilters: [
`${INSTANT_SEARCH_INDEX_NAME}.facets.exact_matches.${INSTANT_SEARCH_HIERARCHICAL_ATTRIBUTE}.value:${currentCategory}`,
Expand Down Expand Up @@ -152,22 +149,22 @@ const querySuggestionsPluginInCategory = createQuerySuggestionsPlugin({
},
templates: {
...source.templates,
header() {
return (
<Fragment>
<span className="aa-SourceHeaderTitle">In {currentCategory}</span>
<div className="aa-SourceHeaderLine" />
</Fragment>
);
header({ html }) {
return html`
<span class="aa-SourceHeaderTitle">In ${currentCategory}</span>
<div class="aa-SourceHeaderLine" />
`;
},
item(params) {
const { children } = (source.templates.item(params) as any).props;
const { item, html } = params;

return (
<ItemWrapper query={params.item.query} category={currentCategory}>
{children}
</ItemWrapper>
);
return getItemWrapper({
query: item.query,
category: currentCategory,
html,
children,
});
},
},
};
Expand All @@ -181,12 +178,12 @@ const querySuggestionsPlugin = createQuerySuggestionsPlugin({
const currentCategory = getInstantSearchCurrentCategory();

if (!currentCategory) {
return recentSearchesPlugin.data.getAlgoliaSearchParams({
return recentSearchesPlugin.data!.getAlgoliaSearchParams({
hitsPerPage: 6,
});
}

return recentSearchesPlugin.data.getAlgoliaSearchParams({
return recentSearchesPlugin.data!.getAlgoliaSearchParams({
hitsPerPage: 3,
facetFilters: [
`${INSTANT_SEARCH_INDEX_NAME}.facets.exact_matches.${INSTANT_SEARCH_HIERARCHICAL_ATTRIBUTE}.value:-${currentCategory}`,
Expand Down Expand Up @@ -229,29 +226,26 @@ const querySuggestionsPlugin = createQuerySuggestionsPlugin({
},
templates: {
...source.templates,
header() {
header({ html }) {
if (!currentCategory) {
return null;
}

return (
<Fragment>
<span className="aa-SourceHeaderTitle">In other categories</span>
<div className="aa-SourceHeaderLine" />
</Fragment>
);
return html`
<span class="aa-SourceHeaderTitle">In other categories</span>
<div class="aa-SourceHeaderLine" />
`;
},
item(params) {
const { children } = (source.templates.item(params) as any).props;
const { item, html } = params;

return (
<ItemWrapper
query={params.item.query}
category={params.item.__autocomplete_qsCategory}
>
{children}
</ItemWrapper>
);
return getItemWrapper({
query: item.query,
category: item.__autocomplete_qsCategory,
html,
children,
});
},
},
};
Expand All @@ -260,8 +254,10 @@ const querySuggestionsPlugin = createQuerySuggestionsPlugin({

const searchPageState = getInstantSearchUiState();

export function startAutocomplete() {
autocomplete({
export function startAutocomplete(searchInstance: InstantSearch) {
let skipInstantSearchStateUpdate = false;

const { setQuery } = autocomplete({
container: '#autocomplete',
placeholder: 'Search for products',
openOnFocus: true,
Expand Down Expand Up @@ -292,9 +288,17 @@ export function startAutocomplete() {
});
},
onStateChange({ prevState, state }) {
if (prevState.query !== state.query) {
if (!skipInstantSearchStateUpdate && prevState.query !== state.query) {
debouncedSetInstantSearchUiState({ query: state.query });
}
skipInstantSearchStateUpdate = false;
},
});

window.addEventListener('popstate', () => {
skipInstantSearchStateUpdate = true;
setQuery(
(searchInstance.helper && searchInstance.helper.state.query) || ''
);
});
}
28 changes: 16 additions & 12 deletions examples/instantsearch/src/instantsearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,16 @@ search.addWidgets([
}));
},
templates: {
item: `
item: (hit, { html, components }) => html`
<article class="hit">
<div class="hit-image">
<img src="{{image}}" alt="{{name}}">
<img src="${hit.image}" alt="${hit.name}" />
</div>
<div>
<h1>
{{#helpers.snippet}}{ "attribute": "name" }{{/helpers.snippet}}
</h1>
<h1>${components.Snippet({ hit, attribute: 'name' })}</h1>
<div>
By <strong>{{brand}}</strong> in <strong>{{category}}</strong>
By <strong>${hit.brand}</strong> in
<strong>${hit.category}</strong>
</div>
</div>
Expand All @@ -81,7 +80,8 @@ search.addWidgets([
gap: 8px;
"
>
{{#rating}}
${hit.rating > 0 &&
html`
<div
style="
display: grid;
Expand All @@ -101,11 +101,13 @@ search.addWidgets([
stroke-linecap="round"
stroke-linejoin="round"
>
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
/>
</svg>
{{rating}}
${hit.rating}
</div>
{{/rating}}
`}
<div
style="
Expand All @@ -130,9 +132,11 @@ search.addWidgets([
top: 1px;
"
>
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
<path
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
></path>
</svg>
<span>{{comments}}</span>
<span>${hit.comments}</span>
</div>
</div>
</article>
Expand Down
Loading

0 comments on commit d0ca975

Please sign in to comment.