@docusaurus/theme-search-algolia 2.0.0-beta.15d451942 → 2.0.0-beta.18
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.d.ts +7 -0
- package/lib/client/index.js +7 -0
- package/lib/client/useAlgoliaContextualFacetFilters.d.ts +7 -0
- package/lib/client/useAlgoliaContextualFacetFilters.js +15 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.js +107 -0
- package/lib/templates/opensearch.d.ts +8 -0
- package/lib/templates/opensearch.js +23 -0
- package/lib/theme/SearchBar/index.d.ts +8 -0
- package/{src → lib}/theme/SearchBar/index.js +45 -50
- package/lib/theme/SearchBar/styles.css +21 -0
- package/lib/theme/SearchBar/styles.module.css +20 -0
- package/lib/theme/SearchPage/index.d.ts +8 -0
- package/{src → lib}/theme/SearchPage/index.js +95 -128
- package/lib/theme/SearchPage/styles.module.css +119 -0
- package/lib/validateThemeConfig.d.ts +15 -0
- package/lib/validateThemeConfig.js +50 -0
- package/package.json +34 -13
- package/src/client/index.ts +8 -0
- package/src/{theme/hooks/useAlgoliaContextualFacetFilters.js → client/useAlgoliaContextualFacetFilters.ts} +3 -3
- package/src/deps.d.ts +10 -0
- package/src/index.ts +116 -0
- package/src/templates/{opensearch.js → opensearch.ts} +7 -5
- package/src/theme/SearchBar/index.tsx +276 -0
- package/src/theme/SearchPage/index.tsx +528 -0
- package/src/theme/SearchPage/styles.module.css +15 -34
- package/src/theme-search-algolia.d.ts +35 -0
- package/src/types.d.ts +10 -0
- package/src/validateThemeConfig.ts +53 -0
- package/src/__tests__/validateThemeConfig.test.js +0 -121
- package/src/index.js +0 -92
- package/src/theme/SearchMetadatas/index.js +0 -25
- package/src/theme/hooks/useSearchQuery.js +0 -44
- package/src/validateThemeConfig.js +0 -45
|
@@ -4,26 +4,27 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
7
|
/* eslint-disable jsx-a11y/no-autofocus */
|
|
9
|
-
|
|
10
8
|
import React, {useEffect, useState, useReducer, useRef} from 'react';
|
|
11
|
-
|
|
12
9
|
import algoliaSearch from 'algoliasearch/lite';
|
|
13
10
|
import algoliaSearchHelper from 'algoliasearch-helper';
|
|
14
11
|
import clsx from 'clsx';
|
|
15
|
-
|
|
16
12
|
import Head from '@docusaurus/Head';
|
|
17
13
|
import Link from '@docusaurus/Link';
|
|
18
14
|
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
|
19
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
HtmlClassNameProvider,
|
|
17
|
+
useTitleFormatter,
|
|
18
|
+
usePluralForm,
|
|
19
|
+
isRegexpStringMatch,
|
|
20
|
+
useDynamicCallback,
|
|
21
|
+
useSearchPage,
|
|
22
|
+
} from '@docusaurus/theme-common';
|
|
20
23
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|
21
|
-
import {useAllDocsData} from '@
|
|
22
|
-
import useSearchQuery from '@theme/hooks/useSearchQuery';
|
|
24
|
+
import {useAllDocsData} from '@docusaurus/plugin-content-docs/client';
|
|
23
25
|
import Layout from '@theme/Layout';
|
|
24
26
|
import Translate, {translate} from '@docusaurus/Translate';
|
|
25
27
|
import styles from './styles.module.css';
|
|
26
|
-
|
|
27
28
|
// Very simple pluralization: probably good enough for now
|
|
28
29
|
function useDocumentsFoundPlural() {
|
|
29
30
|
const {selectMessage} = usePluralForm();
|
|
@@ -41,26 +42,25 @@ function useDocumentsFoundPlural() {
|
|
|
41
42
|
),
|
|
42
43
|
);
|
|
43
44
|
}
|
|
44
|
-
|
|
45
45
|
function useDocsSearchVersionsHelpers() {
|
|
46
46
|
const allDocsData = useAllDocsData();
|
|
47
|
-
|
|
48
47
|
// State of the version select menus / algolia facet filters
|
|
49
48
|
// docsPluginId -> versionName map
|
|
50
|
-
const [searchVersions, setSearchVersions] = useState(() =>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
const [searchVersions, setSearchVersions] = useState(() =>
|
|
50
|
+
Object.entries(allDocsData).reduce(
|
|
51
|
+
(acc, [pluginId, pluginData]) => ({
|
|
52
|
+
...acc,
|
|
53
|
+
[pluginId]: pluginData.versions[0].name,
|
|
54
|
+
}),
|
|
55
|
+
{},
|
|
56
|
+
),
|
|
57
|
+
);
|
|
56
58
|
// Set the value of a single select menu
|
|
57
59
|
const setSearchVersion = (pluginId, searchVersion) =>
|
|
58
60
|
setSearchVersions((s) => ({...s, [pluginId]: searchVersion}));
|
|
59
|
-
|
|
60
61
|
const versioningEnabled = Object.values(allDocsData).some(
|
|
61
62
|
(docsData) => docsData.versions.length > 1,
|
|
62
63
|
);
|
|
63
|
-
|
|
64
64
|
return {
|
|
65
65
|
allDocsData,
|
|
66
66
|
versioningEnabled,
|
|
@@ -68,15 +68,13 @@ function useDocsSearchVersionsHelpers() {
|
|
|
68
68
|
setSearchVersion,
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
|
-
|
|
72
71
|
// We want to display one select per versioned docs plugin instance
|
|
73
|
-
|
|
72
|
+
function SearchVersionSelectList({docsSearchVersionsHelpers}) {
|
|
74
73
|
const versionedPluginEntries = Object.entries(
|
|
75
74
|
docsSearchVersionsHelpers.allDocsData,
|
|
76
75
|
)
|
|
77
76
|
// Do not show a version select for unversioned docs plugin instances
|
|
78
77
|
.filter(([, docsData]) => docsData.versions.length > 1);
|
|
79
|
-
|
|
80
78
|
return (
|
|
81
79
|
<div
|
|
82
80
|
className={clsx(
|
|
@@ -111,22 +109,18 @@ const SearchVersionSelectList = ({docsSearchVersionsHelpers}) => {
|
|
|
111
109
|
})}
|
|
112
110
|
</div>
|
|
113
111
|
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function SearchPage() {
|
|
112
|
+
}
|
|
113
|
+
function SearchPageContent() {
|
|
117
114
|
const {
|
|
118
|
-
siteConfig: {
|
|
119
|
-
themeConfig: {
|
|
120
|
-
algolia: {appId, apiKey, indexName},
|
|
121
|
-
},
|
|
122
|
-
},
|
|
115
|
+
siteConfig: {themeConfig},
|
|
123
116
|
i18n: {currentLocale},
|
|
124
117
|
} = useDocusaurusContext();
|
|
118
|
+
const {
|
|
119
|
+
algolia: {appId, apiKey, indexName, externalUrlRegex},
|
|
120
|
+
} = themeConfig;
|
|
125
121
|
const documentsFoundPlural = useDocumentsFoundPlural();
|
|
126
|
-
|
|
127
122
|
const docsSearchVersionsHelpers = useDocsSearchVersionsHelpers();
|
|
128
|
-
const {
|
|
129
|
-
const [searchQuery, setSearchQuery] = useState(searchValue);
|
|
123
|
+
const {searchQuery, setSearchQuery} = useSearchPage();
|
|
130
124
|
const initialSearchResultState = {
|
|
131
125
|
items: [],
|
|
132
126
|
query: null,
|
|
@@ -137,8 +131,8 @@ function SearchPage() {
|
|
|
137
131
|
loading: null,
|
|
138
132
|
};
|
|
139
133
|
const [searchResultState, searchResultStateDispatcher] = useReducer(
|
|
140
|
-
(prevState,
|
|
141
|
-
switch (type) {
|
|
134
|
+
(prevState, data) => {
|
|
135
|
+
switch (data.type) {
|
|
142
136
|
case 'reset': {
|
|
143
137
|
return initialSearchResultState;
|
|
144
138
|
}
|
|
@@ -146,21 +140,19 @@ function SearchPage() {
|
|
|
146
140
|
return {...prevState, loading: true};
|
|
147
141
|
}
|
|
148
142
|
case 'update': {
|
|
149
|
-
if (searchQuery !==
|
|
143
|
+
if (searchQuery !== data.value.query) {
|
|
150
144
|
return prevState;
|
|
151
145
|
}
|
|
152
|
-
|
|
153
146
|
return {
|
|
154
|
-
...
|
|
147
|
+
...data.value,
|
|
155
148
|
items:
|
|
156
|
-
|
|
157
|
-
?
|
|
158
|
-
: prevState.items.concat(
|
|
149
|
+
data.value.lastPage === 0
|
|
150
|
+
? data.value.items
|
|
151
|
+
: prevState.items.concat(data.value.items),
|
|
159
152
|
};
|
|
160
153
|
}
|
|
161
154
|
case 'advance': {
|
|
162
155
|
const hasMore = prevState.totalPages > prevState.lastPage + 1;
|
|
163
|
-
|
|
164
156
|
return {
|
|
165
157
|
...prevState,
|
|
166
158
|
lastPage: hasMore ? prevState.lastPage + 1 : prevState.lastPage,
|
|
@@ -179,36 +171,33 @@ function SearchPage() {
|
|
|
179
171
|
advancedSyntax: true,
|
|
180
172
|
disjunctiveFacets: ['language', 'docusaurus_tag'],
|
|
181
173
|
});
|
|
182
|
-
|
|
183
174
|
algoliaHelper.on(
|
|
184
175
|
'result',
|
|
185
176
|
({results: {query, hits, page, nbHits, nbPages}}) => {
|
|
186
|
-
if (query === '' || !(hits
|
|
177
|
+
if (query === '' || !Array.isArray(hits)) {
|
|
187
178
|
searchResultStateDispatcher({type: 'reset'});
|
|
188
179
|
return;
|
|
189
180
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return value.replace(
|
|
181
|
+
const sanitizeValue = (value) =>
|
|
182
|
+
value.replace(
|
|
193
183
|
/algolia-docsearch-suggestion--highlight/g,
|
|
194
184
|
'search-result-match',
|
|
195
185
|
);
|
|
196
|
-
};
|
|
197
|
-
|
|
198
186
|
const items = hits.map(
|
|
199
187
|
({
|
|
200
188
|
url,
|
|
201
189
|
_highlightResult: {hierarchy},
|
|
202
190
|
_snippetResult: snippet = {},
|
|
203
191
|
}) => {
|
|
204
|
-
const
|
|
205
|
-
const titles = Object.keys(hierarchy).map((key) =>
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
192
|
+
const parsedURL = new URL(url);
|
|
193
|
+
const titles = Object.keys(hierarchy).map((key) =>
|
|
194
|
+
sanitizeValue(hierarchy[key].value),
|
|
195
|
+
);
|
|
209
196
|
return {
|
|
210
197
|
title: titles.pop(),
|
|
211
|
-
url:
|
|
198
|
+
url: isRegexpStringMatch(externalUrlRegex, parsedURL.href)
|
|
199
|
+
? parsedURL.href
|
|
200
|
+
: parsedURL.pathname + parsedURL.hash,
|
|
212
201
|
summary: snippet.content
|
|
213
202
|
? `${sanitizeValue(snippet.content.value)}...`
|
|
214
203
|
: '',
|
|
@@ -216,7 +205,6 @@ function SearchPage() {
|
|
|
216
205
|
};
|
|
217
206
|
},
|
|
218
207
|
);
|
|
219
|
-
|
|
220
208
|
searchResultStateDispatcher({
|
|
221
209
|
type: 'update',
|
|
222
210
|
value: {
|
|
@@ -231,7 +219,6 @@ function SearchPage() {
|
|
|
231
219
|
});
|
|
232
220
|
},
|
|
233
221
|
);
|
|
234
|
-
|
|
235
222
|
const [loaderRef, setLoaderRef] = useState(null);
|
|
236
223
|
const prevY = useRef(0);
|
|
237
224
|
const observer = useRef(
|
|
@@ -242,17 +229,14 @@ function SearchPage() {
|
|
|
242
229
|
isIntersecting,
|
|
243
230
|
boundingClientRect: {y: currentY},
|
|
244
231
|
} = entries[0];
|
|
245
|
-
|
|
246
232
|
if (isIntersecting && prevY.current > currentY) {
|
|
247
233
|
searchResultStateDispatcher({type: 'advance'});
|
|
248
234
|
}
|
|
249
|
-
|
|
250
235
|
prevY.current = currentY;
|
|
251
236
|
},
|
|
252
237
|
{threshold: 1},
|
|
253
238
|
),
|
|
254
239
|
);
|
|
255
|
-
|
|
256
240
|
const getTitle = () =>
|
|
257
241
|
searchQuery
|
|
258
242
|
? translate(
|
|
@@ -270,11 +254,9 @@ function SearchPage() {
|
|
|
270
254
|
message: 'Search the documentation',
|
|
271
255
|
description: 'The search page title for empty query',
|
|
272
256
|
});
|
|
273
|
-
|
|
274
|
-
const makeSearch = (page = 0) => {
|
|
257
|
+
const makeSearch = useDynamicCallback((page = 0) => {
|
|
275
258
|
algoliaHelper.addDisjunctiveFacetRefinement('docusaurus_tag', 'default');
|
|
276
259
|
algoliaHelper.addDisjunctiveFacetRefinement('language', currentLocale);
|
|
277
|
-
|
|
278
260
|
Object.entries(docsSearchVersionsHelpers.searchVersions).forEach(
|
|
279
261
|
([pluginId, searchVersion]) => {
|
|
280
262
|
algoliaHelper.addDisjunctiveFacetRefinement(
|
|
@@ -283,52 +265,36 @@ function SearchPage() {
|
|
|
283
265
|
);
|
|
284
266
|
},
|
|
285
267
|
);
|
|
286
|
-
|
|
287
268
|
algoliaHelper.setQuery(searchQuery).setPage(page).search();
|
|
288
|
-
};
|
|
289
|
-
|
|
269
|
+
});
|
|
290
270
|
useEffect(() => {
|
|
291
271
|
if (!loaderRef) {
|
|
292
272
|
return undefined;
|
|
293
273
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
274
|
+
const currentObserver = observer.current;
|
|
275
|
+
if (currentObserver) {
|
|
276
|
+
currentObserver.observe(loaderRef);
|
|
277
|
+
return () => currentObserver.unobserve(loaderRef);
|
|
278
|
+
}
|
|
279
|
+
return () => true;
|
|
300
280
|
}, [loaderRef]);
|
|
301
|
-
|
|
302
281
|
useEffect(() => {
|
|
303
|
-
updateSearchPath(searchQuery);
|
|
304
|
-
|
|
305
282
|
searchResultStateDispatcher({type: 'reset'});
|
|
306
|
-
|
|
307
283
|
if (searchQuery) {
|
|
308
284
|
searchResultStateDispatcher({type: 'loading'});
|
|
309
|
-
|
|
310
285
|
setTimeout(() => {
|
|
311
286
|
makeSearch();
|
|
312
287
|
}, 300);
|
|
313
288
|
}
|
|
314
|
-
}, [searchQuery, docsSearchVersionsHelpers.searchVersions]);
|
|
315
|
-
|
|
289
|
+
}, [searchQuery, docsSearchVersionsHelpers.searchVersions, makeSearch]);
|
|
316
290
|
useEffect(() => {
|
|
317
291
|
if (!searchResultState.lastPage || searchResultState.lastPage === 0) {
|
|
318
292
|
return;
|
|
319
293
|
}
|
|
320
|
-
|
|
321
294
|
makeSearch(searchResultState.lastPage);
|
|
322
|
-
}, [searchResultState.lastPage]);
|
|
323
|
-
|
|
324
|
-
useEffect(() => {
|
|
325
|
-
if (searchValue && searchValue !== searchQuery) {
|
|
326
|
-
setSearchQuery(searchValue);
|
|
327
|
-
}
|
|
328
|
-
}, [searchValue]);
|
|
329
|
-
|
|
295
|
+
}, [makeSearch, searchResultState.lastPage]);
|
|
330
296
|
return (
|
|
331
|
-
<Layout
|
|
297
|
+
<Layout>
|
|
332
298
|
<Head>
|
|
333
299
|
<title>{useTitleFormatter(getTitle())}</title>
|
|
334
300
|
{/*
|
|
@@ -375,16 +341,19 @@ function SearchPage() {
|
|
|
375
341
|
)}
|
|
376
342
|
</form>
|
|
377
343
|
|
|
378
|
-
<div className=
|
|
344
|
+
<div className="row">
|
|
379
345
|
<div className={clsx('col', 'col--8', styles.searchResultsColumn)}>
|
|
380
|
-
{!!searchResultState.totalResults &&
|
|
381
|
-
|
|
382
|
-
{documentsFoundPlural(searchResultState.totalResults)}
|
|
383
|
-
</strong>
|
|
384
|
-
)}
|
|
346
|
+
{!!searchResultState.totalResults &&
|
|
347
|
+
documentsFoundPlural(searchResultState.totalResults)}
|
|
385
348
|
</div>
|
|
386
349
|
|
|
387
|
-
<div
|
|
350
|
+
<div
|
|
351
|
+
className={clsx(
|
|
352
|
+
'col',
|
|
353
|
+
'col--4',
|
|
354
|
+
'text--right',
|
|
355
|
+
styles.searchLogoColumn,
|
|
356
|
+
)}>
|
|
388
357
|
<a
|
|
389
358
|
target="_blank"
|
|
390
359
|
rel="noopener noreferrer"
|
|
@@ -394,10 +363,7 @@ function SearchPage() {
|
|
|
394
363
|
message: 'Search by Algolia',
|
|
395
364
|
description: 'The ARIA label for Algolia mention',
|
|
396
365
|
})}>
|
|
397
|
-
<svg
|
|
398
|
-
viewBox="0 0 168 24"
|
|
399
|
-
className={styles.algoliaLogo}
|
|
400
|
-
xmlns="http://www.w3.org/2000/svg">
|
|
366
|
+
<svg viewBox="0 0 168 24" className={styles.algoliaLogo}>
|
|
401
367
|
<g fill="none">
|
|
402
368
|
<path
|
|
403
369
|
className={styles.algoliaLogoPathFill}
|
|
@@ -418,34 +384,32 @@ function SearchPage() {
|
|
|
418
384
|
</div>
|
|
419
385
|
|
|
420
386
|
{searchResultState.items.length > 0 ? (
|
|
421
|
-
<
|
|
387
|
+
<main>
|
|
422
388
|
{searchResultState.items.map(
|
|
423
389
|
({title, url, summary, breadcrumbs}, i) => (
|
|
424
390
|
<article key={i} className={styles.searchResultItem}>
|
|
425
|
-
<
|
|
426
|
-
to={url}
|
|
427
|
-
|
|
428
|
-
dangerouslySetInnerHTML={{__html: title}}
|
|
429
|
-
/>
|
|
391
|
+
<h2 className={styles.searchResultItemHeading}>
|
|
392
|
+
<Link to={url} dangerouslySetInnerHTML={{__html: title}} />
|
|
393
|
+
</h2>
|
|
430
394
|
|
|
431
395
|
{breadcrumbs.length > 0 && (
|
|
432
|
-
<
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
396
|
+
<nav aria-label="breadcrumbs">
|
|
397
|
+
<ul
|
|
398
|
+
className={clsx(
|
|
399
|
+
'breadcrumbs',
|
|
400
|
+
styles.searchResultItemPath,
|
|
401
|
+
)}>
|
|
402
|
+
{breadcrumbs.map((html, index) => (
|
|
403
|
+
<li
|
|
404
|
+
key={index}
|
|
405
|
+
className="breadcrumbs__item"
|
|
442
406
|
// Developer provided the HTML, so assume it's safe.
|
|
443
407
|
// eslint-disable-next-line react/no-danger
|
|
444
408
|
dangerouslySetInnerHTML={{__html: html}}
|
|
445
409
|
/>
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
</
|
|
410
|
+
))}
|
|
411
|
+
</ul>
|
|
412
|
+
</nav>
|
|
449
413
|
)}
|
|
450
414
|
|
|
451
415
|
{summary && (
|
|
@@ -459,7 +423,7 @@ function SearchPage() {
|
|
|
459
423
|
</article>
|
|
460
424
|
),
|
|
461
425
|
)}
|
|
462
|
-
</
|
|
426
|
+
</main>
|
|
463
427
|
) : (
|
|
464
428
|
[
|
|
465
429
|
searchQuery && !searchResultState.loading && (
|
|
@@ -479,18 +443,21 @@ function SearchPage() {
|
|
|
479
443
|
|
|
480
444
|
{searchResultState.hasMore && (
|
|
481
445
|
<div className={styles.loader} ref={setLoaderRef}>
|
|
482
|
-
<
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
</Translate>
|
|
488
|
-
</span>
|
|
446
|
+
<Translate
|
|
447
|
+
id="theme.SearchPage.fetchingNewResults"
|
|
448
|
+
description="The paragraph for fetching new search results">
|
|
449
|
+
Fetching new results...
|
|
450
|
+
</Translate>
|
|
489
451
|
</div>
|
|
490
452
|
)}
|
|
491
453
|
</div>
|
|
492
454
|
</Layout>
|
|
493
455
|
);
|
|
494
456
|
}
|
|
495
|
-
|
|
496
|
-
|
|
457
|
+
export default function SearchPage() {
|
|
458
|
+
return (
|
|
459
|
+
<HtmlClassNameProvider className="search-page-wrapper">
|
|
460
|
+
<SearchPageContent />
|
|
461
|
+
</HtmlClassNameProvider>
|
|
462
|
+
);
|
|
463
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.searchQueryInput,
|
|
9
|
+
.searchVersionInput {
|
|
10
|
+
border-radius: var(--ifm-global-radius);
|
|
11
|
+
border: 2px solid var(--ifm-toc-border-color);
|
|
12
|
+
font: var(--ifm-font-size-base) var(--ifm-font-family-base);
|
|
13
|
+
padding: 0.8rem;
|
|
14
|
+
width: 100%;
|
|
15
|
+
background: var(--docsearch-searchbox-focus-background);
|
|
16
|
+
color: var(--docsearch-text-color);
|
|
17
|
+
margin-bottom: 0.5rem;
|
|
18
|
+
transition: border var(--ifm-transition-fast) ease;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.searchQueryInput:focus,
|
|
22
|
+
.searchVersionInput:focus {
|
|
23
|
+
border-color: var(--docsearch-primary-color);
|
|
24
|
+
outline: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.searchQueryInput::placeholder {
|
|
28
|
+
color: var(--docsearch-muted-color);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.searchResultsColumn {
|
|
32
|
+
font-size: 0.9rem;
|
|
33
|
+
font-weight: bold;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.algoliaLogo {
|
|
37
|
+
max-width: 150px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.algoliaLogoPathFill {
|
|
41
|
+
fill: var(--ifm-font-color-base);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.searchResultItem {
|
|
45
|
+
padding: 1rem 0;
|
|
46
|
+
border-bottom: 1px solid var(--ifm-toc-border-color);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.searchResultItemHeading {
|
|
50
|
+
font-weight: 400;
|
|
51
|
+
margin-bottom: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.searchResultItemPath {
|
|
55
|
+
font-size: 0.8rem;
|
|
56
|
+
color: var(--ifm-color-content-secondary);
|
|
57
|
+
--ifm-breadcrumb-separator-size-multiplier: 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.searchResultItemSummary {
|
|
61
|
+
margin: 0.5rem 0 0;
|
|
62
|
+
font-style: italic;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@media only screen and (max-width: 996px) {
|
|
66
|
+
.searchQueryColumn {
|
|
67
|
+
max-width: 60% !important;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.searchVersionColumn {
|
|
71
|
+
max-width: 40% !important;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.searchResultsColumn {
|
|
75
|
+
max-width: 60% !important;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.searchLogoColumn {
|
|
79
|
+
max-width: 40% !important;
|
|
80
|
+
padding-left: 0 !important;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@media screen and (max-width: 576px) {
|
|
85
|
+
.searchQueryColumn {
|
|
86
|
+
max-width: 100% !important;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.searchVersionColumn {
|
|
90
|
+
max-width: 100% !important;
|
|
91
|
+
padding-left: var(--ifm-spacing-horizontal) !important;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.loadingSpinner {
|
|
96
|
+
width: 3rem;
|
|
97
|
+
height: 3rem;
|
|
98
|
+
border: 0.4em solid #eee;
|
|
99
|
+
border-top-color: var(--ifm-color-primary);
|
|
100
|
+
border-radius: 50%;
|
|
101
|
+
animation: loading-spin 1s linear infinite;
|
|
102
|
+
margin: 0 auto;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@keyframes loading-spin {
|
|
106
|
+
100% {
|
|
107
|
+
transform: rotate(360deg);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.loader {
|
|
112
|
+
margin-top: 2rem;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
:global(.search-result-match) {
|
|
116
|
+
color: var(--docsearch-hit-color);
|
|
117
|
+
background: rgb(255 215 142 / 25%);
|
|
118
|
+
padding: 0.09em 0;
|
|
119
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import { Joi } from '@docusaurus/utils-validation';
|
|
8
|
+
import type { ThemeConfig, ThemeConfigValidationContext } from '@docusaurus/types';
|
|
9
|
+
export declare const DEFAULT_CONFIG: {
|
|
10
|
+
contextualSearch: boolean;
|
|
11
|
+
searchParameters: {};
|
|
12
|
+
searchPagePath: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const Schema: Joi.ObjectSchema<any>;
|
|
15
|
+
export declare function validateThemeConfig({ validate, themeConfig, }: ThemeConfigValidationContext<ThemeConfig>): ThemeConfig;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, '__esModule', {value: true});
|
|
9
|
+
exports.validateThemeConfig = exports.Schema = exports.DEFAULT_CONFIG = void 0;
|
|
10
|
+
const utils_validation_1 = require('@docusaurus/utils-validation');
|
|
11
|
+
exports.DEFAULT_CONFIG = {
|
|
12
|
+
// enabled by default, as it makes sense in most cases
|
|
13
|
+
// see also https://github.com/facebook/docusaurus/issues/5880
|
|
14
|
+
contextualSearch: true,
|
|
15
|
+
searchParameters: {},
|
|
16
|
+
searchPagePath: 'search',
|
|
17
|
+
};
|
|
18
|
+
exports.Schema = utils_validation_1.Joi.object({
|
|
19
|
+
algolia: utils_validation_1.Joi.object({
|
|
20
|
+
// Docusaurus attributes
|
|
21
|
+
contextualSearch: utils_validation_1.Joi.boolean().default(
|
|
22
|
+
exports.DEFAULT_CONFIG.contextualSearch,
|
|
23
|
+
),
|
|
24
|
+
externalUrlRegex: utils_validation_1.Joi.string().optional(),
|
|
25
|
+
// Algolia attributes
|
|
26
|
+
appId: utils_validation_1.Joi.string().required().messages({
|
|
27
|
+
'any.required':
|
|
28
|
+
'"algolia.appId" is required. If you haven\'t migrated to the new DocSearch infra, please refer to the blog post for instructions: https://docusaurus.io/blog/2021/11/21/algolia-docsearch-migration',
|
|
29
|
+
}),
|
|
30
|
+
apiKey: utils_validation_1.Joi.string().required(),
|
|
31
|
+
indexName: utils_validation_1.Joi.string().required(),
|
|
32
|
+
searchParameters: utils_validation_1.Joi.object()
|
|
33
|
+
.default(exports.DEFAULT_CONFIG.searchParameters)
|
|
34
|
+
.unknown(),
|
|
35
|
+
searchPagePath: utils_validation_1.Joi.alternatives()
|
|
36
|
+
.try(
|
|
37
|
+
utils_validation_1.Joi.boolean().invalid(true),
|
|
38
|
+
utils_validation_1.Joi.string(),
|
|
39
|
+
)
|
|
40
|
+
.allow(null)
|
|
41
|
+
.default(exports.DEFAULT_CONFIG.searchPagePath),
|
|
42
|
+
})
|
|
43
|
+
.label('themeConfig.algolia')
|
|
44
|
+
.required()
|
|
45
|
+
.unknown(), // DocSearch 3 is still alpha: don't validate the rest for now
|
|
46
|
+
});
|
|
47
|
+
function validateThemeConfig({validate, themeConfig}) {
|
|
48
|
+
return validate(exports.Schema, themeConfig);
|
|
49
|
+
}
|
|
50
|
+
exports.validateThemeConfig = validateThemeConfig;
|
package/package.json
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/theme-search-algolia",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.18",
|
|
4
4
|
"description": "Algolia search component for Docusaurus.",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./client": "./lib/client/index.js",
|
|
8
|
+
".": "./lib/index.js"
|
|
9
|
+
},
|
|
10
|
+
"types": "src/theme-search-algolia.d.ts",
|
|
6
11
|
"publishConfig": {
|
|
7
12
|
"access": "public"
|
|
8
13
|
},
|
|
@@ -12,24 +17,40 @@
|
|
|
12
17
|
"directory": "packages/docusaurus-theme-search-algolia"
|
|
13
18
|
},
|
|
14
19
|
"license": "MIT",
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "yarn build:server && yarn build:client && yarn build:copy && yarn build:format",
|
|
22
|
+
"build:server": "tsc --project tsconfig.server.json",
|
|
23
|
+
"build:client": "tsc --project tsconfig.client.json",
|
|
24
|
+
"build:copy": "node copyUntypedFiles.mjs",
|
|
25
|
+
"build:format": "prettier --config ../../.prettierrc --write \"lib/**/*.js\""
|
|
26
|
+
},
|
|
15
27
|
"dependencies": {
|
|
16
|
-
"@docsearch/react": "^3.0.0
|
|
17
|
-
"@docusaurus/core": "2.0.0-beta.
|
|
18
|
-
"@docusaurus/
|
|
19
|
-
"@docusaurus/
|
|
20
|
-
"@docusaurus/
|
|
21
|
-
"
|
|
22
|
-
"
|
|
28
|
+
"@docsearch/react": "^3.0.0",
|
|
29
|
+
"@docusaurus/core": "2.0.0-beta.18",
|
|
30
|
+
"@docusaurus/logger": "2.0.0-beta.18",
|
|
31
|
+
"@docusaurus/plugin-content-docs": "2.0.0-beta.18",
|
|
32
|
+
"@docusaurus/theme-common": "2.0.0-beta.18",
|
|
33
|
+
"@docusaurus/theme-translations": "2.0.0-beta.18",
|
|
34
|
+
"@docusaurus/utils": "2.0.0-beta.18",
|
|
35
|
+
"@docusaurus/utils-validation": "2.0.0-beta.18",
|
|
36
|
+
"algoliasearch": "^4.13.0",
|
|
37
|
+
"algoliasearch-helper": "^3.7.4",
|
|
23
38
|
"clsx": "^1.1.1",
|
|
24
|
-
"eta": "^1.12.
|
|
25
|
-
"
|
|
39
|
+
"eta": "^1.12.3",
|
|
40
|
+
"fs-extra": "^10.0.1",
|
|
41
|
+
"lodash": "^4.17.21",
|
|
42
|
+
"tslib": "^2.3.1",
|
|
43
|
+
"utility-types": "^3.10.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@docusaurus/module-type-aliases": "2.0.0-beta.18"
|
|
26
47
|
},
|
|
27
48
|
"peerDependencies": {
|
|
28
49
|
"react": "^16.8.4 || ^17.0.0",
|
|
29
50
|
"react-dom": "^16.8.4 || ^17.0.0"
|
|
30
51
|
},
|
|
31
52
|
"engines": {
|
|
32
|
-
"node": ">=
|
|
53
|
+
"node": ">=14"
|
|
33
54
|
},
|
|
34
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "1a945d06993d53376e61bed2c942799fe07dc336"
|
|
35
56
|
}
|