@docusaurus/theme-search-algolia 0.0.0-4197 → 0.0.0-4204

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.
Files changed (34) hide show
  1. package/copyUntypedFiles.js +20 -0
  2. package/lib/index.d.ts +11 -0
  3. package/lib/index.js +80 -0
  4. package/lib/templates/opensearch.d.ts +8 -0
  5. package/lib/templates/opensearch.js +23 -0
  6. package/lib/theme/SearchBar/index.d.ts +9 -0
  7. package/lib/theme/SearchBar/index.js +153 -0
  8. package/lib/theme/SearchBar/styles.css +21 -0
  9. package/lib/theme/SearchBar/styles.module.css +20 -0
  10. package/lib/theme/SearchMetadata/index.d.ts +10 -0
  11. package/lib/theme/SearchMetadata/index.js +20 -0
  12. package/lib/theme/SearchPage/index.d.ts +9 -0
  13. package/lib/theme/SearchPage/index.js +304 -0
  14. package/lib/theme/SearchPage/styles.module.css +119 -0
  15. package/lib/theme/hooks/useAlgoliaContextualFacetFilters.d.ts +8 -0
  16. package/lib/theme/hooks/useAlgoliaContextualFacetFilters.js +15 -0
  17. package/lib/theme/hooks/useSearchQuery.d.ts +9 -0
  18. package/lib/theme/hooks/useSearchQuery.js +44 -0
  19. package/lib/validateThemeConfig.d.ts +13 -0
  20. package/lib/validateThemeConfig.js +39 -0
  21. package/package.json +18 -7
  22. package/src/{index.js → index.ts} +25 -16
  23. package/src/templates/{opensearch.js → opensearch.ts} +1 -1
  24. package/src/theme/SearchBar/{index.js → index.tsx} +70 -26
  25. package/src/theme/SearchMetadata/{index.js → index.tsx} +8 -1
  26. package/src/theme/SearchPage/{index.js → index.tsx} +60 -26
  27. package/src/theme/hooks/{useAlgoliaContextualFacetFilters.js → useAlgoliaContextualFacetFilters.ts} +3 -2
  28. package/src/theme/hooks/{useSearchQuery.js → useSearchQuery.ts} +4 -3
  29. package/src/theme-search-algolia.d.ts +49 -0
  30. package/src/types.d.ts +10 -0
  31. package/src/{validateThemeConfig.js → validateThemeConfig.ts} +9 -6
  32. package/tsconfig.browser.json +8 -0
  33. package/tsconfig.json +9 -0
  34. package/tsconfig.server.json +4 -0
@@ -5,26 +5,33 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- const path = require('path');
9
- const fs = require('fs');
10
- const eta = require('eta');
11
- const {normalizeUrl, getSwizzledComponent} = require('@docusaurus/utils');
12
- const openSearchTemplate = require('./templates/opensearch');
13
- const {validateThemeConfig} = require('./validateThemeConfig');
14
- const {memoize} = require('lodash');
8
+ import path from 'path';
9
+ import fs from 'fs';
10
+ import {defaultConfig, compile} from 'eta';
11
+ import {normalizeUrl, getSwizzledComponent} from '@docusaurus/utils';
12
+ import openSearchTemplate from './templates/opensearch';
13
+ import {memoize} from 'lodash';
14
+
15
+ import type {DocusaurusContext, Plugin} from '@docusaurus/types';
15
16
 
16
17
  const getCompiledOpenSearchTemplate = memoize(() => {
17
- return eta.compile(openSearchTemplate.trim());
18
+ return compile(openSearchTemplate.trim());
18
19
  });
19
20
 
20
- function renderOpenSearchTemplate(data) {
21
+ function renderOpenSearchTemplate(data: {
22
+ title: string;
23
+ url: string;
24
+ favicon: string | null;
25
+ }) {
21
26
  const compiled = getCompiledOpenSearchTemplate();
22
- return compiled(data, eta.defaultConfig);
27
+ return compiled(data, defaultConfig);
23
28
  }
24
29
 
25
30
  const OPEN_SEARCH_FILENAME = 'opensearch.xml';
26
31
 
27
- function theme(context) {
32
+ export default function theme(
33
+ context: DocusaurusContext & {baseUrl: string},
34
+ ): Plugin<void> {
28
35
  const {
29
36
  baseUrl,
30
37
  siteConfig: {title, url, favicon},
@@ -37,12 +44,16 @@ function theme(context) {
37
44
  return {
38
45
  name: 'docusaurus-theme-search-algolia',
39
46
 
47
+ getPathsToWatch() {
48
+ return [pagePath];
49
+ },
50
+
40
51
  getThemePath() {
41
52
  return path.resolve(__dirname, './theme');
42
53
  },
43
54
 
44
- getPathsToWatch() {
45
- return [pagePath];
55
+ getTypeScriptThemePath() {
56
+ return path.resolve(__dirname, '..', 'src', 'theme');
46
57
  },
47
58
 
48
59
  async contentLoaded({actions: {addRoute}}) {
@@ -87,6 +98,4 @@ function theme(context) {
87
98
  };
88
99
  }
89
100
 
90
- module.exports = theme;
91
-
92
- theme.validateThemeConfig = validateThemeConfig;
101
+ export {validateThemeConfig} from './validateThemeConfig';
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- module.exports = `
8
+ export default `
9
9
  <?xml version="1.0" encoding="UTF-8"?>
10
10
  <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
11
11
  xmlns:moz="http://www.mozilla.org/2006/browser/search/">
@@ -4,6 +4,7 @@
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
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
7
8
 
8
9
  import React, {useState, useRef, useCallback, useMemo} from 'react';
9
10
  import {createPortal} from 'react-dom';
@@ -19,13 +20,42 @@ import useAlgoliaContextualFacetFilters from '@theme/hooks/useAlgoliaContextualF
19
20
  import {translate} from '@docusaurus/Translate';
20
21
  import styles from './styles.module.css';
21
22
 
22
- let DocSearchModal = null;
23
+ import type {
24
+ DocSearchModal as DocSearchModalType,
25
+ DocSearchModalProps,
26
+ } from '@docsearch/react';
27
+ import type {
28
+ InternalDocSearchHit,
29
+ StoredDocSearchHit,
30
+ } from '@docsearch/react/dist/esm/types';
31
+ import type {AutocompleteState} from '@algolia/autocomplete-core';
23
32
 
24
- function Hit({hit, children}) {
33
+ type DocSearchProps = Omit<
34
+ DocSearchModalProps,
35
+ 'onClose' | 'initialScrollY'
36
+ > & {
37
+ contextualSearch?: string;
38
+ externalUrlRegex?: string;
39
+ };
40
+
41
+ let DocSearchModal: typeof DocSearchModalType | null = null;
42
+
43
+ function Hit({
44
+ hit,
45
+ children,
46
+ }: {
47
+ hit: InternalDocSearchHit | StoredDocSearchHit;
48
+ children: React.ReactNode;
49
+ }) {
25
50
  return <Link to={hit.url}>{children}</Link>;
26
51
  }
27
52
 
28
- function ResultsFooter({state, onClose}) {
53
+ type ResultsFooterProps = {
54
+ state: AutocompleteState<InternalDocSearchHit>;
55
+ onClose: () => void;
56
+ };
57
+
58
+ function ResultsFooter({state, onClose}: ResultsFooterProps) {
29
59
  const {generateSearchPageLink} = useSearchQuery();
30
60
 
31
61
  return (
@@ -35,7 +65,11 @@ function ResultsFooter({state, onClose}) {
35
65
  );
36
66
  }
37
67
 
38
- function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
68
+ function DocSearch({
69
+ contextualSearch,
70
+ externalUrlRegex,
71
+ ...props
72
+ }: DocSearchProps) {
39
73
  const {siteMetadata} = useDocusaurusContext();
40
74
 
41
75
  const contextualSearchFacetFilters = useAlgoliaContextualFacetFilters();
@@ -56,10 +90,12 @@ function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
56
90
 
57
91
  const {withBaseUrl} = useBaseUrlUtils();
58
92
  const history = useHistory();
59
- const searchContainer = useRef(null);
60
- const searchButtonRef = useRef(null);
93
+ const searchContainer = useRef<HTMLDivElement | null>(null);
94
+ const searchButtonRef = useRef<HTMLButtonElement>(null);
61
95
  const [isOpen, setIsOpen] = useState(false);
62
- const [initialQuery, setInitialQuery] = useState(null);
96
+ const [initialQuery, setInitialQuery] = useState<string | undefined>(
97
+ undefined,
98
+ );
63
99
 
64
100
  const importDocSearchModalIfNeeded = useCallback(() => {
65
101
  if (DocSearchModal) {
@@ -67,7 +103,9 @@ function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
67
103
  }
68
104
 
69
105
  return Promise.all([
106
+ // @ts-ignore
70
107
  import('@docsearch/react/modal'),
108
+ // @ts-ignore
71
109
  import('@docsearch/react/style'),
72
110
  import('./styles.css'),
73
111
  ]).then(([{DocSearchModal: Modal}]) => {
@@ -88,7 +126,7 @@ function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
88
126
 
89
127
  const onClose = useCallback(() => {
90
128
  setIsOpen(false);
91
- searchContainer.current.remove();
129
+ searchContainer.current?.remove();
92
130
  }, [setIsOpen]);
93
131
 
94
132
  const onInput = useCallback(
@@ -102,35 +140,38 @@ function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
102
140
  );
103
141
 
104
142
  const navigator = useRef({
105
- navigate({itemUrl}) {
143
+ navigate({itemUrl}: {itemUrl?: string}) {
106
144
  // Algolia results could contain URL's from other domains which cannot
107
145
  // be served through history and should navigate with window.location
108
146
  if (isRegexpStringMatch(externalUrlRegex, itemUrl)) {
109
- window.location.href = itemUrl;
147
+ window.location.href = itemUrl!;
110
148
  } else {
111
- history.push(itemUrl);
149
+ history.push(itemUrl!);
112
150
  }
113
151
  },
114
152
  }).current;
115
153
 
116
- const transformItems = useRef((items) => {
117
- return items.map((item) => {
118
- // If Algolia contains a external domain, we should navigate without relative URL
119
- if (isRegexpStringMatch(externalUrlRegex, item.url)) {
120
- return item;
121
- }
154
+ const transformItems = useRef<DocSearchModalProps['transformItems']>(
155
+ (items) => {
156
+ return items.map((item) => {
157
+ // If Algolia contains a external domain, we should navigate without relative URL
158
+ if (isRegexpStringMatch(externalUrlRegex, item.url)) {
159
+ return item;
160
+ }
122
161
 
123
- // We transform the absolute URL into a relative URL.
124
- const url = new URL(item.url);
125
- return {
126
- ...item,
127
- url: withBaseUrl(`${url.pathname}${url.hash}`),
128
- };
129
- });
130
- }).current;
162
+ // We transform the absolute URL into a relative URL.
163
+ const url = new URL(item.url);
164
+ return {
165
+ ...item,
166
+ url: withBaseUrl(`${url.pathname}${url.hash}`),
167
+ };
168
+ });
169
+ },
170
+ ).current;
131
171
 
132
172
  const resultsFooterComponent = useMemo(
133
- () => (footerProps) => <ResultsFooter {...footerProps} onClose={onClose} />,
173
+ () => (footerProps: ResultsFooterProps) =>
174
+ <ResultsFooter {...footerProps} onClose={onClose} />,
134
175
  [onClose],
135
176
  );
136
177
 
@@ -188,6 +229,8 @@ function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
188
229
  </div>
189
230
 
190
231
  {isOpen &&
232
+ DocSearchModal &&
233
+ searchContainer.current &&
191
234
  createPortal(
192
235
  <DocSearchModal
193
236
  onClose={onClose}
@@ -209,6 +252,7 @@ function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
209
252
 
210
253
  function SearchBar() {
211
254
  const {siteConfig} = useDocusaurusContext();
255
+ // @ts-ignore
212
256
  return <DocSearch {...siteConfig.themeConfig.algolia} />;
213
257
  }
214
258
 
@@ -8,9 +8,14 @@
8
8
  import React from 'react';
9
9
 
10
10
  import Head from '@docusaurus/Head';
11
+ import type {SearchMetadataProps} from '@theme/SearchMetadata';
11
12
 
12
13
  // Override default/agnostic SearchMetas to use Algolia-specific metadata
13
- export default function AlgoliaSearchMetadata({locale, version, tag}) {
14
+ function SearchMetadata({
15
+ locale,
16
+ version,
17
+ tag,
18
+ }: SearchMetadataProps): JSX.Element {
14
19
  // Seems safe to consider here the locale is the language,
15
20
  // as the existing docsearch:language filter is afaik a regular string-based filter
16
21
  const language = locale;
@@ -23,3 +28,5 @@ export default function AlgoliaSearchMetadata({locale, version, tag}) {
23
28
  </Head>
24
29
  );
25
30
  }
31
+
32
+ export default SearchMetadata;
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  /* eslint-disable jsx-a11y/no-autofocus */
9
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
9
10
 
10
11
  import React, {useEffect, useState, useReducer, useRef} from 'react';
11
12
 
@@ -32,7 +33,7 @@ import styles from './styles.module.css';
32
33
  // Very simple pluralization: probably good enough for now
33
34
  function useDocumentsFoundPlural() {
34
35
  const {selectMessage} = usePluralForm();
35
- return (count) =>
36
+ return (count: number) =>
36
37
  selectMessage(
37
38
  count,
38
39
  translate(
@@ -52,14 +53,19 @@ function useDocsSearchVersionsHelpers() {
52
53
 
53
54
  // State of the version select menus / algolia facet filters
54
55
  // docsPluginId -> versionName map
55
- const [searchVersions, setSearchVersions] = useState(() => {
56
- return Object.entries(allDocsData).reduce((acc, [pluginId, pluginData]) => {
57
- return {...acc, [pluginId]: pluginData.versions[0].name};
58
- }, {});
59
- });
56
+ const [searchVersions, setSearchVersions] = useState<Record<string, string>>(
57
+ () => {
58
+ return Object.entries(allDocsData).reduce(
59
+ (acc, [pluginId, pluginData]) => {
60
+ return {...acc, [pluginId]: pluginData.versions[0].name};
61
+ },
62
+ {},
63
+ );
64
+ },
65
+ );
60
66
 
61
67
  // Set the value of a single select menu
62
- const setSearchVersion = (pluginId, searchVersion) =>
68
+ const setSearchVersion = (pluginId: string, searchVersion: string) =>
63
69
  setSearchVersions((s) => ({...s, [pluginId]: searchVersion}));
64
70
 
65
71
  const versioningEnabled = Object.values(allDocsData).some(
@@ -75,7 +81,11 @@ function useDocsSearchVersionsHelpers() {
75
81
  }
76
82
 
77
83
  // We want to display one select per versioned docs plugin instance
78
- const SearchVersionSelectList = ({docsSearchVersionsHelpers}) => {
84
+ const SearchVersionSelectList = ({
85
+ docsSearchVersionsHelpers,
86
+ }: {
87
+ docsSearchVersionsHelpers: ReturnType<typeof useDocsSearchVersionsHelpers>;
88
+ }) => {
79
89
  const versionedPluginEntries = Object.entries(
80
90
  docsSearchVersionsHelpers.allDocsData,
81
91
  )
@@ -118,10 +128,32 @@ const SearchVersionSelectList = ({docsSearchVersionsHelpers}) => {
118
128
  );
119
129
  };
120
130
 
121
- function SearchPage() {
131
+ type ResultDispatcherState = {
132
+ items: {
133
+ title: string;
134
+ url: string;
135
+ summary: string;
136
+ breadcrumbs: string[];
137
+ }[];
138
+ query: string | null;
139
+ totalResults: number | null;
140
+ totalPages: number | null;
141
+ lastPage: number | null;
142
+ hasMore: boolean | null;
143
+ loading: boolean | null;
144
+ };
145
+
146
+ type ResultDispatcher =
147
+ | {type: 'reset'; value?: undefined}
148
+ | {type: 'loading'; value?: undefined}
149
+ | {type: 'update'; value: ResultDispatcherState}
150
+ | {type: 'advance'; value?: undefined};
151
+
152
+ function SearchPage(): JSX.Element {
122
153
  const {
123
154
  siteConfig: {
124
155
  themeConfig: {
156
+ // @ts-ignore
125
157
  algolia: {appId, apiKey, indexName, externalUrlRegex},
126
158
  },
127
159
  },
@@ -131,7 +163,7 @@ function SearchPage() {
131
163
 
132
164
  const docsSearchVersionsHelpers = useDocsSearchVersionsHelpers();
133
165
  const {searchQuery, setSearchQuery} = useSearchQuery();
134
- const initialSearchResultState = {
166
+ const initialSearchResultState: ResultDispatcherState = {
135
167
  items: [],
136
168
  query: null,
137
169
  totalResults: null,
@@ -141,8 +173,8 @@ function SearchPage() {
141
173
  loading: null,
142
174
  };
143
175
  const [searchResultState, searchResultStateDispatcher] = useReducer(
144
- (prevState, {type, value: state}) => {
145
- switch (type) {
176
+ (prevState: ResultDispatcherState, data: ResultDispatcher) => {
177
+ switch (data.type) {
146
178
  case 'reset': {
147
179
  return initialSearchResultState;
148
180
  }
@@ -150,24 +182,24 @@ function SearchPage() {
150
182
  return {...prevState, loading: true};
151
183
  }
152
184
  case 'update': {
153
- if (searchQuery !== state.query) {
185
+ if (searchQuery !== data.value.query) {
154
186
  return prevState;
155
187
  }
156
188
 
157
189
  return {
158
- ...state,
190
+ ...data.value,
159
191
  items:
160
- state.lastPage === 0
161
- ? state.items
162
- : prevState.items.concat(state.items),
192
+ data.value.lastPage === 0
193
+ ? data.value.items
194
+ : prevState.items.concat(data.value.items),
163
195
  };
164
196
  }
165
197
  case 'advance': {
166
- const hasMore = prevState.totalPages > prevState.lastPage + 1;
198
+ const hasMore = prevState.totalPages! > prevState.lastPage! + 1;
167
199
 
168
200
  return {
169
201
  ...prevState,
170
- lastPage: hasMore ? prevState.lastPage + 1 : prevState.lastPage,
202
+ lastPage: hasMore ? prevState.lastPage! + 1 : prevState.lastPage,
171
203
  hasMore,
172
204
  };
173
205
  }
@@ -193,7 +225,7 @@ function SearchPage() {
193
225
  return;
194
226
  }
195
227
 
196
- const sanitizeValue = (value) => {
228
+ const sanitizeValue = (value: string) => {
197
229
  return value.replace(
198
230
  /algolia-docsearch-suggestion--highlight/g,
199
231
  'search-result-match',
@@ -212,7 +244,7 @@ function SearchPage() {
212
244
  });
213
245
 
214
246
  return {
215
- title: titles.pop(),
247
+ title: titles.pop()!,
216
248
  url: isRegexpStringMatch(externalUrlRegex, parsedURL.href)
217
249
  ? parsedURL.href
218
250
  : parsedURL.pathname + parsedURL.hash,
@@ -239,7 +271,7 @@ function SearchPage() {
239
271
  },
240
272
  );
241
273
 
242
- const [loaderRef, setLoaderRef] = useState(null);
274
+ const [loaderRef, setLoaderRef] = useState<HTMLDivElement | null>(null);
243
275
  const prevY = useRef(0);
244
276
  const observer = useRef(
245
277
  ExecutionEnvironment.canUseDOM &&
@@ -278,7 +310,7 @@ function SearchPage() {
278
310
  description: 'The search page title for empty query',
279
311
  });
280
312
 
281
- const makeSearch = useDynamicCallback((page = 0) => {
313
+ const makeSearch = useDynamicCallback((page: number = 0) => {
282
314
  algoliaHelper.addDisjunctiveFacetRefinement('docusaurus_tag', 'default');
283
315
  algoliaHelper.addDisjunctiveFacetRefinement('language', currentLocale);
284
316
 
@@ -299,9 +331,11 @@ function SearchPage() {
299
331
  return undefined;
300
332
  }
301
333
  const currentObserver = observer.current;
302
-
303
- currentObserver.observe(loaderRef);
304
- return () => currentObserver.unobserve(loaderRef);
334
+ if (currentObserver) {
335
+ currentObserver.observe(loaderRef);
336
+ return () => currentObserver.unobserve(loaderRef);
337
+ }
338
+ return () => true;
305
339
  }, [loaderRef]);
306
340
 
307
341
  useEffect(() => {
@@ -5,10 +5,11 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import useContextualSearchFilters from '@theme/hooks/useContextualSearchFilters';
8
+ import type {useAlgoliaContextualFacetFiltersReturns} from '@theme/hooks/useAlgoliaContextualFacetFilters';
9
+ import {useContextualSearchFilters} from '@docusaurus/theme-common';
9
10
 
10
11
  // Translate search-engine agnostic search filters to Algolia search filters
11
- export default function useAlgoliaContextualFacetFilters() {
12
+ export default function useAlgoliaContextualFacetFilters(): useAlgoliaContextualFacetFiltersReturns {
12
13
  const {locale, tags} = useContextualSearchFilters();
13
14
 
14
15
  // seems safe to convert locale->language, see AlgoliaSearchMetadata comment
@@ -8,10 +8,11 @@
8
8
  import {useHistory} from '@docusaurus/router';
9
9
  import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
10
10
  import {useCallback, useEffect, useState} from 'react';
11
+ import type {SearchQuery} from '@theme/hooks/useSearchQuery';
11
12
 
12
13
  const SEARCH_PARAM_QUERY = 'q';
13
14
 
14
- function useSearchQuery() {
15
+ function useSearchQuery(): SearchQuery {
15
16
  const history = useHistory();
16
17
  const {
17
18
  siteConfig: {baseUrl},
@@ -28,7 +29,7 @@ function useSearchQuery() {
28
29
  }, []);
29
30
 
30
31
  const setSearchQuery = useCallback(
31
- (newSearchQuery) => {
32
+ (newSearchQuery: string) => {
32
33
  const searchParams = new URLSearchParams(window.location.search);
33
34
 
34
35
  if (newSearchQuery) {
@@ -46,7 +47,7 @@ function useSearchQuery() {
46
47
  );
47
48
 
48
49
  const generateSearchPageLink = useCallback(
49
- (targetSearchQuery) => {
50
+ (targetSearchQuery: string) => {
50
51
  // Refer to https://github.com/facebook/docusaurus/pull/2838
51
52
  return `${baseUrl}search?q=${encodeURIComponent(targetSearchQuery)}`;
52
53
  },
@@ -0,0 +1,49 @@
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
+ declare module '@docusaurus/theme-search-algolia' {
9
+ export type Options = never;
10
+ }
11
+
12
+ declare module '@theme/hooks/useSearchQuery' {
13
+ export interface SearchQuery {
14
+ searchQuery: string;
15
+
16
+ setSearchQuery(newSearchQuery: string): void;
17
+
18
+ generateSearchPageLink(targetSearchQuery: string): string;
19
+ }
20
+
21
+ export default function useSearchQuery(): SearchQuery;
22
+ }
23
+
24
+ declare module '@theme/hooks/useAlgoliaContextualFacetFilters' {
25
+ export type useAlgoliaContextualFacetFiltersReturns = [string, string[]];
26
+
27
+ export default function useAlgoliaContextualFacetFilters(): useAlgoliaContextualFacetFiltersReturns;
28
+ }
29
+
30
+ declare module '@theme/SearchPage' {
31
+ const SearchPage: () => JSX.Element;
32
+ export default SearchPage;
33
+ }
34
+
35
+ declare module '@theme/SearchMetadata' {
36
+ export type SearchMetadataProps = {
37
+ readonly locale?: string;
38
+ readonly version?: string;
39
+ readonly tag?: string;
40
+ };
41
+
42
+ const SearchMetadata: (props: SearchMetadataProps) => JSX.Element;
43
+ export default SearchMetadata;
44
+ }
45
+
46
+ declare module '@theme/SearchBar' {
47
+ const SearchBar: () => JSX.Element;
48
+ export default SearchBar;
49
+ }
package/src/types.d.ts ADDED
@@ -0,0 +1,10 @@
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
+ /// <reference types="@docusaurus/module-type-aliases" />
9
+ /// <reference types="@docusaurus/theme-common" />
10
+ /// <reference types="@docusaurus/theme-classic" />
@@ -5,7 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- const {Joi} = require('@docusaurus/utils-validation');
8
+ import {Joi} from '@docusaurus/utils-validation';
9
+ import type {ThemeConfig, Validate, ValidationResult} from '@docusaurus/types';
9
10
 
10
11
  const DEFAULT_CONFIG = {
11
12
  contextualSearch: false, // future: maybe we want to enable this by default
@@ -18,7 +19,7 @@ const DEFAULT_CONFIG = {
18
19
  };
19
20
  exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
20
21
 
21
- const Schema = Joi.object({
22
+ export const Schema = Joi.object({
22
23
  algolia: Joi.object({
23
24
  // Docusaurus attributes
24
25
  contextualSearch: Joi.boolean().default(DEFAULT_CONFIG.contextualSearch),
@@ -35,11 +36,13 @@ const Schema = Joi.object({
35
36
  .required()
36
37
  .unknown(), // DocSearch 3 is still alpha: don't validate the rest for now
37
38
  });
38
- exports.Schema = Schema;
39
39
 
40
- exports.validateThemeConfig = function validateThemeConfig({
40
+ export function validateThemeConfig({
41
41
  validate,
42
42
  themeConfig,
43
- }) {
43
+ }: {
44
+ validate: Validate<ThemeConfig>;
45
+ themeConfig: ThemeConfig;
46
+ }): ValidationResult<ThemeConfig> {
44
47
  return validate(Schema, themeConfig);
45
- };
48
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "esnext",
5
+ "jsx": "react-native"
6
+ },
7
+ "include": ["src/theme/", "src/*.d.ts"]
8
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "lib": ["DOM", "ES2019"],
5
+ "rootDir": "src",
6
+ "baseUrl": "src",
7
+ "outDir": "lib"
8
+ }
9
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["src/*.ts", "src/templates/*.ts"]
4
+ }