Skip to content

Commit fbfca35

Browse files
feat(emptyStates): implements empty source template and renderEmpty method (#395)
* Implements `empty` template and `renderEmpty` method * Add wait function to `test/utils` folder Co-authored-by: François Chalifour <francoischalifour@users.noreply.github.com>
1 parent c1c8ddb commit fbfca35

5 files changed

Lines changed: 114 additions & 3 deletions

File tree

examples/js/app.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import {
2+
autocomplete,
3+
getAlgoliaHits,
4+
reverseHighlightHit,
5+
} from '@algolia/autocomplete-js';
6+
import { createAlgoliaInsightsPlugin } from '@algolia/autocomplete-plugin-algolia-insights';
7+
import { createQuerySuggestionsPlugin } from '@algolia/autocomplete-plugin-query-suggestions';
8+
import { createLocalStorageRecentSearchesPlugin } from '@algolia/autocomplete-plugin-recent-searches';
9+
import algoliasearch from 'algoliasearch';
10+
import insightsClient from 'search-insights';
11+
12+
import '@algolia/autocomplete-theme-classic';
13+
14+
const appId = 'latency';
15+
const apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
16+
const searchClient = algoliasearch(appId, apiKey);
17+
insightsClient('init', { appId, apiKey });
18+
19+
const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({ insightsClient });
20+
const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
21+
key: 'search',
22+
limit: 3,
23+
});
24+
const querySuggestionsPlugin = createQuerySuggestionsPlugin({
25+
searchClient,
26+
indexName: 'instant_search_demo_query_suggestions',
27+
getSearchParams() {
28+
return recentSearchesPlugin.data.getAlgoliaSearchParams({
29+
clickAnalytics: true,
30+
});
31+
},
32+
});
33+
34+
autocomplete({
35+
container: '#autocomplete',
36+
placeholder: 'Search',
37+
openOnFocus: true,
38+
plugins: [
39+
algoliaInsightsPlugin,
40+
recentSearchesPlugin,
41+
querySuggestionsPlugin,
42+
],
43+
getSources({ query }) {
44+
if (!query) {
45+
return [];
46+
}
47+
48+
return [
49+
{
50+
getItems() {
51+
return getAlgoliaHits({
52+
searchClient,
53+
queries: [{ indexName: 'instant_search', query }],
54+
});
55+
},
56+
templates: {
57+
item({ item, root }) {
58+
const itemContent = document.createElement('div');
59+
const ItemSourceIcon = document.createElement('div');
60+
const itemTitle = document.createElement('div');
61+
const sourceIcon = document.createElement('img');
62+
63+
sourceIcon.width = 20;
64+
sourceIcon.height = 20;
65+
sourceIcon.src = item.image;
66+
67+
ItemSourceIcon.classList.add('aa-ItemSourceIcon');
68+
ItemSourceIcon.appendChild(sourceIcon);
69+
70+
itemTitle.innerHTML = reverseHighlightHit({
71+
hit: item,
72+
attribute: 'name',
73+
});
74+
itemTitle.classList.add('aa-ItemTitle');
75+
76+
itemContent.classList.add('aa-ItemContent');
77+
itemContent.appendChild(ItemSourceIcon);
78+
itemContent.appendChild(itemTitle);
79+
80+
root.appendChild(itemContent);
81+
},
82+
empty({ root }) {
83+
const itemContent = document.createElement('div');
84+
85+
itemContent.innerHTML = 'No results for this query';
86+
itemContent.classList.add('aa-ItemContent');
87+
88+
root.appendChild(itemContent);
89+
},
90+
},
91+
},
92+
];
93+
},
94+
});

packages/autocomplete-js/src/__tests__/autocomplete.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { fireEvent, waitFor } from '@testing-library/dom';
22

3+
import { wait } from '../../../../test/utils';
34
import { autocomplete } from '../autocomplete';
45

56
describe('autocomplete-js', () => {
@@ -92,8 +93,8 @@ describe('autocomplete-js', () => {
9293
stroke-dasharray="164.93361431346415 56.97787143782138"
9394
stroke-width="6"
9495
>
95-
96-
96+
97+
9798
<animatetransform
9899
attributeName="transform"
99100
dur="1s"
@@ -102,7 +103,7 @@ describe('autocomplete-js', () => {
102103
type="rotate"
103104
values="0 50 50;90 50 50;180 50 50;360 50 50"
104105
/>
105-
106+
106107
107108
</circle>
108109
</svg>

packages/autocomplete-js/src/autocomplete.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,16 @@ export function autocomplete<TItem extends BaseItem>(
150150
props.value.renderer.renderEmpty) ||
151151
props.value.renderer.render;
152152

153+
hasEmptySourceTemplateRef.current = renderProps.state.collections.some(
154+
(collection) => collection.source.templates.empty
155+
);
156+
157+
const render =
158+
(!getItemsCount(renderProps.state) &&
159+
!hasEmptySourceTemplateRef.current &&
160+
props.value.renderer.renderEmpty) ||
161+
props.value.renderer.render;
162+
153163
renderSearchBox(renderProps);
154164
renderPanel(render, renderProps);
155165
}

test/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export * from './createSource';
88
export * from './createState';
99
export * from './defer';
1010
export * from './runAllMicroTasks';
11+
export * from './wait';

test/utils/wait.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export function wait(time: number) {
2+
return new Promise((resolve) => {
3+
setTimeout(resolve, time);
4+
});
5+
}

0 commit comments

Comments
 (0)