Skip to content

Commit b8bc278

Browse files
committed
search page: support docs multi-instance
1 parent 3ba9274 commit b8bc278

2 files changed

Lines changed: 95 additions & 46 deletions

File tree

packages/docusaurus-theme-search-algolia/src/theme/SearchPage/index.js

Lines changed: 94 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,96 @@ import clsx from 'clsx';
1616
import Head from '@docusaurus/Head';
1717
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
1818
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
19-
import {useDocsData} from '@theme/hooks/useDocs';
19+
import {useAllDocsData} from '@theme/hooks/useDocs';
2020
import useSearchQuery from '@theme/hooks/useSearchQuery';
2121
import Link from '@docusaurus/Link';
2222
import Layout from '@theme/Layout';
2323

24-
import {DEFAULT_PLUGIN_ID} from '@docusaurus/constants';
25-
2624
import styles from './styles.module.css';
2725

2826
function pluralize(count, word) {
2927
return count > 1 ? `${word}s` : word;
3028
}
3129

30+
function useDocsSearchVersionsHelpers() {
31+
const allDocsData = useAllDocsData();
32+
33+
// State of the version select menus / algolia facet filters
34+
// docsPluginId -> versionName map
35+
const [searchVersions, setSearchVersions] = useState(() => {
36+
return Object.entries(allDocsData).reduce((acc, [pluginId, pluginData]) => {
37+
return {...acc, [pluginId]: pluginData.versions[0].name};
38+
}, {});
39+
});
40+
41+
// Set the value of a single select menu
42+
const setSearchVersion = (pluginId, searchVersion) =>
43+
setSearchVersions((s) => ({...s, [pluginId]: searchVersion}));
44+
45+
const versioningEnabled = Object.values(allDocsData).some(
46+
(docsData) => docsData.versions.length > 1,
47+
);
48+
49+
return {
50+
allDocsData,
51+
versioningEnabled,
52+
searchVersions,
53+
setSearchVersion,
54+
};
55+
}
56+
57+
// We want to display one select per versioned docs plugin instance
58+
const SearchVersionSelectList = ({docsSearchVersionsHelpers}) => {
59+
const versionedPluginEntries = Object.entries(
60+
docsSearchVersionsHelpers.allDocsData,
61+
)
62+
// Do not show a version select for unversioned docs plugin instances
63+
.filter(([, docsData]) => docsData.versions.length > 1);
64+
65+
return (
66+
<div
67+
className={clsx(
68+
'col',
69+
'col--3',
70+
'padding-left--none',
71+
styles.searchVersionColumn,
72+
)}>
73+
{versionedPluginEntries.map(([pluginId, docsData]) => {
74+
const labelPrefix =
75+
versionedPluginEntries.length > 1 ? `${pluginId}: ` : '';
76+
return (
77+
<select
78+
key={pluginId}
79+
onChange={(e) =>
80+
docsSearchVersionsHelpers.setSearchVersion(
81+
pluginId,
82+
e.target.value,
83+
)
84+
}
85+
defaultValue={docsSearchVersionsHelpers.searchVersions[pluginId]}
86+
className={styles.searchVersionInput}>
87+
{docsData.versions.map((version, i) => (
88+
<option
89+
key={i}
90+
label={`${labelPrefix}${version.label}`}
91+
value={version.name}
92+
/>
93+
))}
94+
</select>
95+
);
96+
})}
97+
</div>
98+
);
99+
};
100+
32101
function Search() {
33102
const {
34103
siteConfig: {
35104
themeConfig: {algolia: {appId = 'BH4D9OD16A', apiKey, indexName} = {}},
36105
} = {},
37106
} = useDocusaurusContext();
38-
const {versions} = useDocsData(DEFAULT_PLUGIN_ID);
39-
const versioningEnabled = versions.length > 0;
107+
const docsSearchVersionsHelpers = useDocsSearchVersionsHelpers();
40108
const {searchValue, updateSearchPath} = useSearchQuery();
41-
const [searchVersion, setSearchVersion] = useState(versions[0]?.name);
42109
const [searchQuery, setSearchQuery] = useState(searchValue);
43110
const initialSearchResultState = {
44111
items: [],
@@ -90,7 +157,7 @@ function Search() {
90157
const algoliaHelper = algoliaSearchHelper(algoliaClient, indexName, {
91158
hitsPerPage: 15,
92159
advancedSyntax: true,
93-
facets: searchVersion ? ['version'] : [],
160+
disjunctiveFacets: ['docusaurus_tag'],
94161
});
95162

96163
algoliaHelper.on(
@@ -172,25 +239,19 @@ function Search() {
172239
: 'Search the documentation';
173240

174241
const makeSearch = (page = 0) => {
175-
if (searchVersion) {
176-
algoliaHelper
177-
.setQuery(searchQuery)
178-
.addFacetRefinement('version', searchVersion)
179-
.setPage(page)
180-
.search();
181-
} else {
182-
algoliaHelper.setQuery(searchQuery).setPage(page).search();
183-
}
184-
};
185-
186-
const handleSearchInputChange = (e) => {
187-
const searchInputValue = e.target.value;
242+
algoliaHelper.setQuery(searchQuery).setPage(page);
243+
244+
algoliaHelper.addDisjunctiveFacetRefinement('docusaurus_tag', 'default');
245+
Object.entries(docsSearchVersionsHelpers.searchVersions).forEach(
246+
([pluginId, searchVersion]) => {
247+
algoliaHelper.addDisjunctiveFacetRefinement(
248+
'docusaurus_tag',
249+
`docs-${pluginId}-${searchVersion}`,
250+
);
251+
},
252+
);
188253

189-
if (e.target.tagName === 'SELECT') {
190-
setSearchVersion(searchInputValue);
191-
} else {
192-
setSearchQuery(searchInputValue);
193-
}
254+
algoliaHelper.search();
194255
};
195256

196257
useEffect(() => {
@@ -217,7 +278,7 @@ function Search() {
217278
makeSearch();
218279
}, 300);
219280
}
220-
}, [searchQuery, searchVersion]);
281+
}, [searchQuery, docsSearchVersionsHelpers.searchVersions]);
221282

222283
useEffect(() => {
223284
if (!searchResultState.lastPage || searchResultState.lastPage === 0) {
@@ -249,39 +310,26 @@ function Search() {
249310
<form className="row" onSubmit={(e) => e.preventDefault()}>
250311
<div
251312
className={clsx('col', styles.searchQueryColumn, {
252-
'col--9': versioningEnabled,
253-
'col--12': !versioningEnabled,
313+
'col--9': docsSearchVersionsHelpers.versioningEnabled,
314+
'col--12': !docsSearchVersionsHelpers.versioningEnabled,
254315
})}>
255316
<input
256317
type="search"
257318
name="q"
258319
className={styles.searchQueryInput}
259320
placeholder="Type your search here"
260321
aria-label="Search"
261-
onChange={handleSearchInputChange}
322+
onChange={(e) => setSearchQuery(e.target.value)}
262323
value={searchQuery}
263324
autoComplete="off"
264325
autoFocus
265326
/>
266327
</div>
267328

268-
{versioningEnabled && (
269-
<div
270-
className={clsx(
271-
'col',
272-
'col--3',
273-
'padding-left--none',
274-
styles.searchVersionColumn,
275-
)}>
276-
<select
277-
onChange={handleSearchInputChange}
278-
defaultValue={searchVersion}
279-
className={styles.searchVersionInput}>
280-
{versions.map((version, i) => (
281-
<option key={i} label={version.label} value={version.name} />
282-
))}
283-
</select>
284-
</div>
329+
{docsSearchVersionsHelpers.versioningEnabled && (
330+
<SearchVersionSelectList
331+
docsSearchVersionsHelpers={docsSearchVersionsHelpers}
332+
/>
285333
)}
286334
</form>
287335

packages/docusaurus-theme-search-algolia/src/theme/SearchPage/styles.module.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
padding: 0.5rem;
1515
width: 100%;
1616
background: #fff;
17+
margin-bottom: 1rem;
1718
}
1819

1920
.searchResultsColumn {

0 commit comments

Comments
 (0)