@docusaurus/theme-search-algolia 0.0.0-4533 → 0.0.0-4539
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client/index.js +1 -1
- package/lib/client/useAlgoliaContextualFacetFilters.js +6 -6
- package/lib/index.js +84 -67
- package/lib/templates/opensearch.js +2 -2
- package/lib/theme/SearchBar/index.js +176 -120
- package/lib/theme/SearchMetadata/index.js +11 -9
- package/lib/theme/SearchPage/index.js +380 -220
- package/lib/validateThemeConfig.js +31 -27
- package/package.json +13 -12
|
@@ -5,292 +5,452 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
/* eslint-disable jsx-a11y/no-autofocus */
|
|
8
|
-
import React, {
|
|
8
|
+
import React, {useEffect, useState, useReducer, useRef} from 'react';
|
|
9
9
|
import algoliaSearch from 'algoliasearch/lite';
|
|
10
10
|
import algoliaSearchHelper from 'algoliasearch-helper';
|
|
11
11
|
import clsx from 'clsx';
|
|
12
12
|
import Head from '@docusaurus/Head';
|
|
13
13
|
import Link from '@docusaurus/Link';
|
|
14
14
|
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
useTitleFormatter,
|
|
17
|
+
usePluralForm,
|
|
18
|
+
isRegexpStringMatch,
|
|
19
|
+
useDynamicCallback,
|
|
20
|
+
useSearchPage,
|
|
21
|
+
} from '@docusaurus/theme-common';
|
|
16
22
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|
17
|
-
import {
|
|
23
|
+
import {useAllDocsData} from '@docusaurus/plugin-content-docs/client';
|
|
18
24
|
import Layout from '@theme/Layout';
|
|
19
|
-
import Translate, {
|
|
25
|
+
import Translate, {translate} from '@docusaurus/Translate';
|
|
20
26
|
import styles from './styles.module.css';
|
|
21
27
|
// Very simple pluralization: probably good enough for now
|
|
22
28
|
function useDocumentsFoundPlural() {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
const {selectMessage} = usePluralForm();
|
|
30
|
+
return (count) =>
|
|
31
|
+
selectMessage(
|
|
32
|
+
count,
|
|
33
|
+
translate(
|
|
34
|
+
{
|
|
35
|
+
id: 'theme.SearchPage.documentsFound.plurals',
|
|
36
|
+
description:
|
|
37
|
+
'Pluralized label for "{count} documents found". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',
|
|
38
|
+
message: 'One document found|{count} documents found',
|
|
39
|
+
},
|
|
40
|
+
{count},
|
|
41
|
+
),
|
|
42
|
+
);
|
|
29
43
|
}
|
|
30
44
|
function useDocsSearchVersionsHelpers() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
const allDocsData = useAllDocsData();
|
|
46
|
+
// State of the version select menus / algolia facet filters
|
|
47
|
+
// docsPluginId -> versionName map
|
|
48
|
+
const [searchVersions, setSearchVersions] = useState(() =>
|
|
49
|
+
Object.entries(allDocsData).reduce(
|
|
50
|
+
(acc, [pluginId, pluginData]) => ({
|
|
35
51
|
...acc,
|
|
36
52
|
[pluginId]: pluginData.versions[0].name,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
}),
|
|
54
|
+
{},
|
|
55
|
+
),
|
|
56
|
+
);
|
|
57
|
+
// Set the value of a single select menu
|
|
58
|
+
const setSearchVersion = (pluginId, searchVersion) =>
|
|
59
|
+
setSearchVersions((s) => ({...s, [pluginId]: searchVersion}));
|
|
60
|
+
const versioningEnabled = Object.values(allDocsData).some(
|
|
61
|
+
(docsData) => docsData.versions.length > 1,
|
|
62
|
+
);
|
|
63
|
+
return {
|
|
64
|
+
allDocsData,
|
|
65
|
+
versioningEnabled,
|
|
66
|
+
searchVersions,
|
|
67
|
+
setSearchVersion,
|
|
68
|
+
};
|
|
47
69
|
}
|
|
48
70
|
// We want to display one select per versioned docs plugin instance
|
|
49
|
-
function SearchVersionSelectList({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
function SearchVersionSelectList({docsSearchVersionsHelpers}) {
|
|
72
|
+
const versionedPluginEntries = Object.entries(
|
|
73
|
+
docsSearchVersionsHelpers.allDocsData,
|
|
74
|
+
)
|
|
75
|
+
// Do not show a version select for unversioned docs plugin instances
|
|
76
|
+
.filter(([, docsData]) => docsData.versions.length > 1);
|
|
77
|
+
return (
|
|
78
|
+
<div
|
|
79
|
+
className={clsx(
|
|
80
|
+
'col',
|
|
81
|
+
'col--3',
|
|
82
|
+
'padding-left--none',
|
|
83
|
+
styles.searchVersionColumn,
|
|
84
|
+
)}>
|
|
54
85
|
{versionedPluginEntries.map(([pluginId, docsData]) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
86
|
+
const labelPrefix =
|
|
87
|
+
versionedPluginEntries.length > 1 ? `${pluginId}: ` : '';
|
|
88
|
+
return (
|
|
89
|
+
<select
|
|
90
|
+
key={pluginId}
|
|
91
|
+
onChange={(e) =>
|
|
92
|
+
docsSearchVersionsHelpers.setSearchVersion(
|
|
93
|
+
pluginId,
|
|
94
|
+
e.target.value,
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
defaultValue={docsSearchVersionsHelpers.searchVersions[pluginId]}
|
|
98
|
+
className={styles.searchVersionInput}>
|
|
99
|
+
{docsData.versions.map((version, i) => (
|
|
100
|
+
<option
|
|
101
|
+
key={i}
|
|
102
|
+
label={`${labelPrefix}${version.label}`}
|
|
103
|
+
value={version.name}
|
|
104
|
+
/>
|
|
105
|
+
))}
|
|
106
|
+
</select>
|
|
107
|
+
);
|
|
108
|
+
})}
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
61
111
|
}
|
|
62
112
|
function SearchPage() {
|
|
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
|
-
return prevState;
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
...data.value,
|
|
91
|
-
items: data.value.lastPage === 0
|
|
92
|
-
? data.value.items
|
|
93
|
-
: prevState.items.concat(data.value.items),
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
case 'advance': {
|
|
97
|
-
const hasMore = prevState.totalPages > prevState.lastPage + 1;
|
|
98
|
-
return {
|
|
99
|
-
...prevState,
|
|
100
|
-
lastPage: hasMore ? prevState.lastPage + 1 : prevState.lastPage,
|
|
101
|
-
hasMore,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
default:
|
|
105
|
-
return prevState;
|
|
113
|
+
const {
|
|
114
|
+
siteConfig: {themeConfig},
|
|
115
|
+
i18n: {currentLocale},
|
|
116
|
+
} = useDocusaurusContext();
|
|
117
|
+
const {
|
|
118
|
+
algolia: {appId, apiKey, indexName, externalUrlRegex},
|
|
119
|
+
} = themeConfig;
|
|
120
|
+
const documentsFoundPlural = useDocumentsFoundPlural();
|
|
121
|
+
const docsSearchVersionsHelpers = useDocsSearchVersionsHelpers();
|
|
122
|
+
const {searchQuery, setSearchQuery} = useSearchPage();
|
|
123
|
+
const initialSearchResultState = {
|
|
124
|
+
items: [],
|
|
125
|
+
query: null,
|
|
126
|
+
totalResults: null,
|
|
127
|
+
totalPages: null,
|
|
128
|
+
lastPage: null,
|
|
129
|
+
hasMore: null,
|
|
130
|
+
loading: null,
|
|
131
|
+
};
|
|
132
|
+
const [searchResultState, searchResultStateDispatcher] = useReducer(
|
|
133
|
+
(prevState, data) => {
|
|
134
|
+
switch (data.type) {
|
|
135
|
+
case 'reset': {
|
|
136
|
+
return initialSearchResultState;
|
|
106
137
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const algoliaHelper = algoliaSearchHelper(algoliaClient, indexName, {
|
|
110
|
-
hitsPerPage: 15,
|
|
111
|
-
advancedSyntax: true,
|
|
112
|
-
disjunctiveFacets: ['language', 'docusaurus_tag'],
|
|
113
|
-
});
|
|
114
|
-
algoliaHelper.on('result', ({ results: { query, hits, page, nbHits, nbPages } }) => {
|
|
115
|
-
if (query === '' || !(hits instanceof Array)) {
|
|
116
|
-
searchResultStateDispatcher({ type: 'reset' });
|
|
117
|
-
return;
|
|
138
|
+
case 'loading': {
|
|
139
|
+
return {...prevState, loading: true};
|
|
118
140
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
141
|
+
case 'update': {
|
|
142
|
+
if (searchQuery !== data.value.query) {
|
|
143
|
+
return prevState;
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
...data.value,
|
|
147
|
+
items:
|
|
148
|
+
data.value.lastPage === 0
|
|
149
|
+
? data.value.items
|
|
150
|
+
: prevState.items.concat(data.value.items),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
case 'advance': {
|
|
154
|
+
const hasMore = prevState.totalPages > prevState.lastPage + 1;
|
|
155
|
+
return {
|
|
156
|
+
...prevState,
|
|
157
|
+
lastPage: hasMore ? prevState.lastPage + 1 : prevState.lastPage,
|
|
158
|
+
hasMore,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
default:
|
|
162
|
+
return prevState;
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
initialSearchResultState,
|
|
166
|
+
);
|
|
167
|
+
const algoliaClient = algoliaSearch(appId, apiKey);
|
|
168
|
+
const algoliaHelper = algoliaSearchHelper(algoliaClient, indexName, {
|
|
169
|
+
hitsPerPage: 15,
|
|
170
|
+
advancedSyntax: true,
|
|
171
|
+
disjunctiveFacets: ['language', 'docusaurus_tag'],
|
|
172
|
+
});
|
|
173
|
+
algoliaHelper.on(
|
|
174
|
+
'result',
|
|
175
|
+
({results: {query, hits, page, nbHits, nbPages}}) => {
|
|
176
|
+
if (query === '' || !(hits instanceof Array)) {
|
|
177
|
+
searchResultStateDispatcher({type: 'reset'});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const sanitizeValue = (value) =>
|
|
181
|
+
value.replace(
|
|
182
|
+
/algolia-docsearch-suggestion--highlight/g,
|
|
183
|
+
'search-result-match',
|
|
184
|
+
);
|
|
185
|
+
const items = hits.map(
|
|
186
|
+
({
|
|
187
|
+
url,
|
|
188
|
+
_highlightResult: {hierarchy},
|
|
189
|
+
_snippetResult: snippet = {},
|
|
190
|
+
}) => {
|
|
191
|
+
const parsedURL = new URL(url);
|
|
192
|
+
const titles = Object.keys(hierarchy).map((key) =>
|
|
193
|
+
sanitizeValue(hierarchy[key].value),
|
|
194
|
+
);
|
|
195
|
+
return {
|
|
196
|
+
title: titles.pop(),
|
|
197
|
+
url: isRegexpStringMatch(externalUrlRegex, parsedURL.href)
|
|
198
|
+
? parsedURL.href
|
|
199
|
+
: parsedURL.pathname + parsedURL.hash,
|
|
200
|
+
summary: snippet.content
|
|
201
|
+
? `${sanitizeValue(snippet.content.value)}...`
|
|
202
|
+
: '',
|
|
203
|
+
breadcrumbs: titles,
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
);
|
|
207
|
+
searchResultStateDispatcher({
|
|
208
|
+
type: 'update',
|
|
209
|
+
value: {
|
|
210
|
+
items,
|
|
211
|
+
query,
|
|
212
|
+
totalResults: nbHits,
|
|
213
|
+
totalPages: nbPages,
|
|
214
|
+
lastPage: page,
|
|
215
|
+
hasMore: nbPages > page + 1,
|
|
216
|
+
loading: false,
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
},
|
|
220
|
+
);
|
|
221
|
+
const [loaderRef, setLoaderRef] = useState(null);
|
|
222
|
+
const prevY = useRef(0);
|
|
223
|
+
const observer = useRef(
|
|
224
|
+
ExecutionEnvironment.canUseDOM &&
|
|
225
|
+
new IntersectionObserver(
|
|
226
|
+
(entries) => {
|
|
227
|
+
const {
|
|
228
|
+
isIntersecting,
|
|
229
|
+
boundingClientRect: {y: currentY},
|
|
230
|
+
} = entries[0];
|
|
231
|
+
if (isIntersecting && prevY.current > currentY) {
|
|
232
|
+
searchResultStateDispatcher({type: 'advance'});
|
|
233
|
+
}
|
|
234
|
+
prevY.current = currentY;
|
|
235
|
+
},
|
|
236
|
+
{threshold: 1},
|
|
237
|
+
),
|
|
238
|
+
);
|
|
239
|
+
const getTitle = () =>
|
|
240
|
+
searchQuery
|
|
241
|
+
? translate(
|
|
242
|
+
{
|
|
159
243
|
id: 'theme.SearchPage.existingResultsTitle',
|
|
160
244
|
message: 'Search results for "{query}"',
|
|
161
245
|
description: 'The search page title for non-empty query',
|
|
162
|
-
|
|
246
|
+
},
|
|
247
|
+
{
|
|
163
248
|
query: searchQuery,
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
249
|
+
},
|
|
250
|
+
)
|
|
251
|
+
: translate({
|
|
252
|
+
id: 'theme.SearchPage.emptyResultsTitle',
|
|
253
|
+
message: 'Search the documentation',
|
|
254
|
+
description: 'The search page title for empty query',
|
|
169
255
|
});
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
256
|
+
const makeSearch = useDynamicCallback((page = 0) => {
|
|
257
|
+
algoliaHelper.addDisjunctiveFacetRefinement('docusaurus_tag', 'default');
|
|
258
|
+
algoliaHelper.addDisjunctiveFacetRefinement('language', currentLocale);
|
|
259
|
+
Object.entries(docsSearchVersionsHelpers.searchVersions).forEach(
|
|
260
|
+
([pluginId, searchVersion]) => {
|
|
261
|
+
algoliaHelper.addDisjunctiveFacetRefinement(
|
|
262
|
+
'docusaurus_tag',
|
|
263
|
+
`docs-${pluginId}-${searchVersion}`,
|
|
264
|
+
);
|
|
265
|
+
},
|
|
266
|
+
);
|
|
267
|
+
algoliaHelper.setQuery(searchQuery).setPage(page).search();
|
|
268
|
+
});
|
|
269
|
+
useEffect(() => {
|
|
270
|
+
if (!loaderRef) {
|
|
271
|
+
return undefined;
|
|
272
|
+
}
|
|
273
|
+
const currentObserver = observer.current;
|
|
274
|
+
if (currentObserver) {
|
|
275
|
+
currentObserver.observe(loaderRef);
|
|
276
|
+
return () => currentObserver.unobserve(loaderRef);
|
|
277
|
+
}
|
|
278
|
+
return () => true;
|
|
279
|
+
}, [loaderRef]);
|
|
280
|
+
useEffect(() => {
|
|
281
|
+
searchResultStateDispatcher({type: 'reset'});
|
|
282
|
+
if (searchQuery) {
|
|
283
|
+
searchResultStateDispatcher({type: 'loading'});
|
|
284
|
+
setTimeout(() => {
|
|
285
|
+
makeSearch();
|
|
286
|
+
}, 300);
|
|
287
|
+
}
|
|
288
|
+
}, [searchQuery, docsSearchVersionsHelpers.searchVersions, makeSearch]);
|
|
289
|
+
useEffect(() => {
|
|
290
|
+
if (!searchResultState.lastPage || searchResultState.lastPage === 0) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
makeSearch(searchResultState.lastPage);
|
|
294
|
+
}, [makeSearch, searchResultState.lastPage]);
|
|
295
|
+
return (
|
|
296
|
+
<Layout wrapperClassName="search-page-wrapper">
|
|
205
297
|
<Head>
|
|
206
298
|
<title>{useTitleFormatter(getTitle())}</title>
|
|
207
299
|
{/*
|
|
208
300
|
We should not index search pages
|
|
209
301
|
See https://github.com/facebook/docusaurus/pull/3233
|
|
210
302
|
*/}
|
|
211
|
-
<meta property="robots" content="noindex, follow"/>
|
|
303
|
+
<meta property="robots" content="noindex, follow" />
|
|
212
304
|
</Head>
|
|
213
305
|
|
|
214
306
|
<div className="container margin-vert--lg">
|
|
215
307
|
<h1>{getTitle()}</h1>
|
|
216
308
|
|
|
217
309
|
<form className="row" onSubmit={(e) => e.preventDefault()}>
|
|
218
|
-
<div
|
|
219
|
-
'col
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
310
|
+
<div
|
|
311
|
+
className={clsx('col', styles.searchQueryColumn, {
|
|
312
|
+
'col--9': docsSearchVersionsHelpers.versioningEnabled,
|
|
313
|
+
'col--12': !docsSearchVersionsHelpers.versioningEnabled,
|
|
314
|
+
})}>
|
|
315
|
+
<input
|
|
316
|
+
type="search"
|
|
317
|
+
name="q"
|
|
318
|
+
className={styles.searchQueryInput}
|
|
319
|
+
placeholder={translate({
|
|
320
|
+
id: 'theme.SearchPage.inputPlaceholder',
|
|
321
|
+
message: 'Type your search here',
|
|
322
|
+
description: 'The placeholder for search page input',
|
|
323
|
+
})}
|
|
324
|
+
aria-label={translate({
|
|
325
|
+
id: 'theme.SearchPage.inputLabel',
|
|
326
|
+
message: 'Search',
|
|
327
|
+
description: 'The ARIA label for search page input',
|
|
328
|
+
})}
|
|
329
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
330
|
+
value={searchQuery}
|
|
331
|
+
autoComplete="off"
|
|
332
|
+
autoFocus
|
|
333
|
+
/>
|
|
231
334
|
</div>
|
|
232
335
|
|
|
233
|
-
{docsSearchVersionsHelpers.versioningEnabled && (
|
|
336
|
+
{docsSearchVersionsHelpers.versioningEnabled && (
|
|
337
|
+
<SearchVersionSelectList
|
|
338
|
+
docsSearchVersionsHelpers={docsSearchVersionsHelpers}
|
|
339
|
+
/>
|
|
340
|
+
)}
|
|
234
341
|
</form>
|
|
235
342
|
|
|
236
343
|
<div className="row">
|
|
237
344
|
<div className={clsx('col', 'col--8', styles.searchResultsColumn)}>
|
|
238
345
|
{!!searchResultState.totalResults &&
|
|
239
|
-
|
|
346
|
+
documentsFoundPlural(searchResultState.totalResults)}
|
|
240
347
|
</div>
|
|
241
348
|
|
|
242
|
-
<div
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
349
|
+
<div
|
|
350
|
+
className={clsx(
|
|
351
|
+
'col',
|
|
352
|
+
'col--4',
|
|
353
|
+
'text--right',
|
|
354
|
+
styles.searchLogoColumn,
|
|
355
|
+
)}>
|
|
356
|
+
<a
|
|
357
|
+
target="_blank"
|
|
358
|
+
rel="noopener noreferrer"
|
|
359
|
+
href="https://www.algolia.com/"
|
|
360
|
+
aria-label={translate({
|
|
361
|
+
id: 'theme.SearchPage.algoliaLabel',
|
|
362
|
+
message: 'Search by Algolia',
|
|
363
|
+
description: 'The ARIA label for Algolia mention',
|
|
364
|
+
})}>
|
|
248
365
|
<svg viewBox="0 0 168 24" className={styles.algoliaLogo}>
|
|
249
366
|
<g fill="none">
|
|
250
|
-
<path
|
|
251
|
-
|
|
252
|
-
|
|
367
|
+
<path
|
|
368
|
+
className={styles.algoliaLogoPathFill}
|
|
369
|
+
d="M120.925 18.804c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 0 0-1.574-.199 5.7 5.7 0 0 0-.897.069 2.699 2.699 0 0 0-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 0 1-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 0 1-1.471-.636 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 0 1 1.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 0 1 1.82-.185 8.404 8.404 0 0 1 1.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 0 0-.384-.73 1.784 1.784 0 0 0-.724-.493 3.164 3.164 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 0 0-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 0 1 2.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 0 0-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 0 0-.814.24 1.46 1.46 0 0 0-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 0 1 .233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 0 1-1.471-.635 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 0 1 2.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 0 0-.109-.875 1.873 1.873 0 0 0-.384-.731 1.784 1.784 0 0 0-.724-.492 3.165 3.165 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 0 0-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 0 1 2.073-.177zm-8.034-1.271a1.626 1.626 0 0 1-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 0 1-1.128 1.906 4.986 4.986 0 0 1-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 0 1-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 0 1-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 0 1 1.15-1.892 5.133 5.133 0 0 1 1.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 0 1 1.753 1.216 5.644 5.644 0 0 1 1.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 0 0-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 0 1-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 0 1-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 0 1 2.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17zM6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 0 0-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 0 1-.582-.271 13.67 13.67 0 0 1-.55-.287 4.275 4.275 0 0 1-.567-.351 6.92 6.92 0 0 1-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 0 1-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 0 0-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 0 0-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 0 0-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 0 1-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z"
|
|
370
|
+
/>
|
|
371
|
+
<path
|
|
372
|
+
fill="#5468FF"
|
|
373
|
+
d="M78.988.938h16.594a2.968 2.968 0 0 1 2.966 2.966V20.5a2.967 2.967 0 0 1-2.966 2.964H78.988a2.967 2.967 0 0 1-2.966-2.964V3.897A2.961 2.961 0 0 1 78.988.938z"
|
|
374
|
+
/>
|
|
375
|
+
<path
|
|
376
|
+
fill="white"
|
|
377
|
+
d="M89.632 5.967v-.772a.978.978 0 0 0-.978-.977h-2.28a.978.978 0 0 0-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 0 1 1.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 0 0-1.382 0l-.465.465a.973.973 0 0 0 0 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 0 0-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 0 1-4.49-4.482 4.488 4.488 0 0 1 4.49-4.482 4.488 4.488 0 0 1 4.489 4.482 4.484 4.484 0 0 1-4.49 4.482m0-10.85a6.363 6.363 0 1 0 0 12.729 6.37 6.37 0 0 0 6.372-6.368 6.358 6.358 0 0 0-6.371-6.36"
|
|
378
|
+
/>
|
|
253
379
|
</g>
|
|
254
380
|
</svg>
|
|
255
381
|
</a>
|
|
256
382
|
</div>
|
|
257
383
|
</div>
|
|
258
384
|
|
|
259
|
-
{searchResultState.items.length > 0 ? (
|
|
260
|
-
|
|
385
|
+
{searchResultState.items.length > 0 ? (
|
|
386
|
+
<main>
|
|
387
|
+
{searchResultState.items.map(
|
|
388
|
+
({title, url, summary, breadcrumbs}, i) => (
|
|
389
|
+
<article key={i} className={styles.searchResultItem}>
|
|
261
390
|
<h2 className={styles.searchResultItemHeading}>
|
|
262
|
-
<Link to={url} dangerouslySetInnerHTML={{
|
|
391
|
+
<Link to={url} dangerouslySetInnerHTML={{__html: title}} />
|
|
263
392
|
</h2>
|
|
264
393
|
|
|
265
|
-
{breadcrumbs.length > 0 && (
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
394
|
+
{breadcrumbs.length > 0 && (
|
|
395
|
+
<nav aria-label="breadcrumbs">
|
|
396
|
+
<ul
|
|
397
|
+
className={clsx(
|
|
398
|
+
'breadcrumbs',
|
|
399
|
+
styles.searchResultItemPath,
|
|
400
|
+
)}>
|
|
401
|
+
{breadcrumbs.map((html, index) => (
|
|
402
|
+
<li
|
|
403
|
+
key={index}
|
|
404
|
+
className="breadcrumbs__item"
|
|
405
|
+
// Developer provided the HTML, so assume it's safe.
|
|
406
|
+
// eslint-disable-next-line react/no-danger
|
|
407
|
+
dangerouslySetInnerHTML={{__html: html}}
|
|
408
|
+
/>
|
|
409
|
+
))}
|
|
271
410
|
</ul>
|
|
272
|
-
</nav>
|
|
411
|
+
</nav>
|
|
412
|
+
)}
|
|
273
413
|
|
|
274
|
-
{summary && (
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
414
|
+
{summary && (
|
|
415
|
+
<p
|
|
416
|
+
className={styles.searchResultItemSummary}
|
|
417
|
+
// Developer provided the HTML, so assume it's safe.
|
|
418
|
+
// eslint-disable-next-line react/no-danger
|
|
419
|
+
dangerouslySetInnerHTML={{__html: summary}}
|
|
420
|
+
/>
|
|
421
|
+
)}
|
|
422
|
+
</article>
|
|
423
|
+
),
|
|
424
|
+
)}
|
|
425
|
+
</main>
|
|
426
|
+
) : (
|
|
427
|
+
[
|
|
428
|
+
searchQuery && !searchResultState.loading && (
|
|
429
|
+
<p key="no-results">
|
|
430
|
+
<Translate
|
|
431
|
+
id="theme.SearchPage.noResultsText"
|
|
432
|
+
description="The paragraph for empty search result">
|
|
282
433
|
No results were found
|
|
283
434
|
</Translate>
|
|
284
|
-
</p>
|
|
285
|
-
|
|
286
|
-
|
|
435
|
+
</p>
|
|
436
|
+
),
|
|
437
|
+
!!searchResultState.loading && (
|
|
438
|
+
<div key="spinner" className={styles.loadingSpinner} />
|
|
439
|
+
),
|
|
440
|
+
]
|
|
441
|
+
)}
|
|
287
442
|
|
|
288
|
-
{searchResultState.hasMore && (
|
|
289
|
-
|
|
443
|
+
{searchResultState.hasMore && (
|
|
444
|
+
<div className={styles.loader} ref={setLoaderRef}>
|
|
445
|
+
<Translate
|
|
446
|
+
id="theme.SearchPage.fetchingNewResults"
|
|
447
|
+
description="The paragraph for fetching new search results">
|
|
290
448
|
Fetching new results...
|
|
291
449
|
</Translate>
|
|
292
|
-
</div>
|
|
450
|
+
</div>
|
|
451
|
+
)}
|
|
293
452
|
</div>
|
|
294
|
-
</Layout>
|
|
453
|
+
</Layout>
|
|
454
|
+
);
|
|
295
455
|
}
|
|
296
456
|
export default SearchPage;
|