-
Notifications
You must be signed in to change notification settings - Fork 338
Expand file tree
/
Copy pathapp.tsx
More file actions
117 lines (109 loc) · 3.16 KB
/
app.tsx
File metadata and controls
117 lines (109 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/** @jsxRuntime classic */
/** @jsx h */
import {
autocomplete,
AutocompleteComponents,
getAlgoliaResults,
} from '@algolia/autocomplete-js';
import { liteClient as algoliasearch } from 'algoliasearch-v5/lite';
import { h, Fragment } from 'preact';
import '@algolia/autocomplete-theme-classic';
import { createLocalStorageRecentlyViewedItems } from './recentlyViewedItemsPlugin';
import { ProductHit } from './types';
const appId = 'latency';
const apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
const searchClient = algoliasearch(appId, apiKey);
const recentlyViewedItems = createLocalStorageRecentlyViewedItems({
key: 'RECENTLY_VIEWED',
limit: 5,
});
autocomplete<ProductHit>({
container: '#autocomplete',
placeholder: 'Search',
openOnFocus: true,
insights: true,
plugins: [recentlyViewedItems],
getSources({ query }) {
if (!query) {
return [];
}
return [
{
sourceId: 'products',
getItems() {
return getAlgoliaResults<ProductHit>({
searchClient,
queries: [
{
indexName: 'instant_search',
query,
params: {
attributesToSnippet: ['name:10', 'description:35'],
snippetEllipsisText: '…',
},
},
],
});
},
onSelect({ item }) {
recentlyViewedItems.data.addItem({
id: item.objectID,
label: item.name,
image: item.image,
url: item.url,
});
},
templates: {
header() {
return (
<Fragment>
<span className="aa-SourceHeaderTitle">Products</span>
<div className="aa-SourceHeaderLine" />
</Fragment>
);
},
item({ item, components }) {
return (
<AutocompleteProductItem hit={item} components={components} />
);
},
noResults() {
return 'No products for this query.';
},
},
},
];
},
});
type ProductItemProps = {
hit: ProductHit;
components: AutocompleteComponents;
};
function AutocompleteProductItem({ hit, components }: ProductItemProps) {
return (
<div className="aa-ItemWrapper">
<div className="aa-ItemContent">
<div className="aa-ItemIcon aa-ItemIcon--alignTop">
<img src={hit.image} alt={hit.name} width="40" height="40" />
</div>
<div className="aa-ItemContentBody">
<div className="aa-ItemContentTitle">
<components.Highlight hit={hit} attribute="name" />
</div>
</div>
</div>
<div className="aa-ItemActions">
<button
className="aa-ItemActionButton aa-DesktopOnly aa-ActiveOnly"
type="button"
title="Select"
style={{ pointerEvents: 'none' }}
>
<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
<path d="M18.984 6.984h2.016v6h-15.188l3.609 3.609-1.406 1.406-6-6 6-6 1.406 1.406-3.609 3.609h13.172v-4.031z" />
</svg>
</button>
</div>
</div>
);
}