@apify/docs-theme 1.0.243 → 1.0.245

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 (50) hide show
  1. package/LICENSE +201 -0
  2. package/package.json +48 -48
  3. package/src/config.js +1 -3
  4. package/src/markdown.js +8 -6
  5. package/src/roa-loader/index.js +16 -14
  6. package/src/theme/ColorModeToggle/index.jsx +14 -27
  7. package/src/theme/DocBreadcrumbs/Items/Home/index.js +2 -1
  8. package/src/theme/DocBreadcrumbs/index.js +10 -20
  9. package/src/theme/DocItemContent/index.js +42 -43
  10. package/src/theme/DocItemContent/styles.module.css +1 -3
  11. package/src/theme/DocSidebarItem/Category/index.js +36 -54
  12. package/src/theme/DocSidebarItem/Link/index.jsx +9 -23
  13. package/src/theme/DocSidebarItem/Link/styles.module.css +1 -1
  14. package/src/theme/Footer/LinkItem/index.js +7 -12
  15. package/src/theme/Footer/index.jsx +2 -3
  16. package/src/theme/Heading/index.jsx +3 -4
  17. package/src/theme/Heading/styles.module.css +23 -23
  18. package/src/theme/Icon/DarkMode/index.jsx +7 -1
  19. package/src/theme/Icon/LightMode/index.jsx +28 -10
  20. package/src/theme/LLMButtons/index.jsx +7 -37
  21. package/src/theme/Layout/index.jsx +10 -9
  22. package/src/theme/Logo/index.js +3 -16
  23. package/src/theme/MDXComponents/A.js +11 -6
  24. package/src/theme/MDXComponents/Code.js +3 -2
  25. package/src/theme/MDXComponents/Details.js +1 -3
  26. package/src/theme/MDXComponents/Head.js +2 -1
  27. package/src/theme/MDXComponents/Img/index.js +1 -7
  28. package/src/theme/MDXComponents/Img/styles.module.css +1 -1
  29. package/src/theme/MDXComponents/Ul/index.js +1 -1
  30. package/src/theme/MDXComponents/Ul/styles.module.css +2 -2
  31. package/src/theme/Navbar/CTA/index.jsx +3 -1
  32. package/src/theme/Navbar/CTA/styles.module.css +45 -45
  33. package/src/theme/Navbar/Content/index.jsx +29 -28
  34. package/src/theme/Navbar/MobileSidebar/Header/index.jsx +3 -1
  35. package/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.jsx +15 -29
  36. package/src/theme/NavbarItem/ComponentTypes.jsx +3 -22
  37. package/src/theme/NavbarItem/NavbarNavLink.jsx +28 -24
  38. package/src/theme/NotFound.jsx +2 -6
  39. package/src/theme/RunnableCodeBlock/RunnableCodeBlock.jsx +43 -9
  40. package/src/theme/SearchBar/index.js +21 -21
  41. package/src/theme/SearchBar/styles.css +84 -83
  42. package/src/theme/SearchMetadata/index.js +8 -8
  43. package/src/theme/SearchPage/index.js +173 -230
  44. package/src/theme/SearchPage/styles.module.css +59 -59
  45. package/src/theme/TOCItems/Tree.jsx +2 -12
  46. package/src/theme/TOCItems/index.jsx +2 -12
  47. package/src/theme/custom.css +90 -75
  48. package/src/theme.js +15 -19
  49. package/src/utils.js +1 -5
  50. package/static/js/custom.js +7 -5
@@ -6,22 +6,12 @@ import algoliaSearchHelper from 'algoliasearch-helper';
6
6
  import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
7
7
  import Head from '@docusaurus/Head';
8
8
  import { useAllDocsData } from '@docusaurus/plugin-content-docs/client';
9
- import {
10
- HtmlClassNameProvider,
11
- useEvent,
12
- usePluralForm,
13
- } from '@docusaurus/theme-common';
14
- import {
15
- useSearchQueryString,
16
- useTitleFormatter,
17
- } from '@docusaurus/theme-common/internal';
9
+ import { HtmlClassNameProvider, useEvent, usePluralForm } from '@docusaurus/theme-common';
10
+ import { useSearchQueryString, useTitleFormatter } from '@docusaurus/theme-common/internal';
18
11
  import Translate, { translate } from '@docusaurus/Translate';
19
12
  import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
20
13
  import { useLocation } from '@docusaurus/router';
21
- import {
22
- useAlgoliaThemeConfig,
23
- useSearchResultUrlProcessor,
24
- } from '@docusaurus/theme-search-algolia/client';
14
+ import { useAlgoliaThemeConfig, useSearchResultUrlProcessor } from '@docusaurus/theme-search-algolia/client';
25
15
  import Layout from '@theme/Layout';
26
16
  import { Link } from '../SearchBar';
27
17
  import styles from './styles.module.css';
@@ -29,40 +19,41 @@ import styles from './styles.module.css';
29
19
  // Very simple pluralization: probably good enough for now
30
20
  function useDocumentsFoundPlural() {
31
21
  const { selectMessage } = usePluralForm();
32
- return (count) => selectMessage(
33
- count,
34
- translate(
35
- {
36
- id: 'theme.SearchPage.documentsFound.plurals',
37
- description:
22
+ return (count) =>
23
+ selectMessage(
24
+ count,
25
+ translate(
26
+ {
27
+ id: 'theme.SearchPage.documentsFound.plurals',
28
+ description:
38
29
  '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)',
39
- message: 'One document found|{count} documents found',
40
- },
41
- { count },
42
- ),
43
- );
30
+ message: 'One document found|{count} documents found',
31
+ },
32
+ { count },
33
+ ),
34
+ );
44
35
  }
45
36
 
46
37
  function useDocsSearchVersionsHelpers() {
47
38
  const allDocsData = useAllDocsData();
48
39
  // State of the version select menus / algolia facet filters
49
40
  // docsPluginId -> versionName map
50
- const [searchVersions, setSearchVersions] = useState(() => Object.entries(allDocsData).reduce(
51
- (acc, [pluginId, pluginData]) => ({
52
- ...acc,
53
- [pluginId]: pluginData.versions[0].name,
54
- }),
55
- {},
56
- ),
41
+ const [searchVersions, setSearchVersions] = useState(() =>
42
+ Object.entries(allDocsData).reduce(
43
+ (acc, [pluginId, pluginData]) => ({
44
+ ...acc,
45
+ [pluginId]: pluginData.versions[0].name,
46
+ }),
47
+ {},
48
+ ),
57
49
  );
58
50
  // Set the value of a single select menu
59
- const setSearchVersion = (pluginId, searchVersion) => setSearchVersions((s) => ({
60
- ...s,
61
- [pluginId]: searchVersion,
62
- }));
63
- const versioningEnabled = Object.values(allDocsData).some(
64
- (docsData) => docsData.versions.length > 1,
65
- );
51
+ const setSearchVersion = (pluginId, searchVersion) =>
52
+ setSearchVersions((s) => ({
53
+ ...s,
54
+ [pluginId]: searchVersion,
55
+ }));
56
+ const versioningEnabled = Object.values(allDocsData).some((docsData) => docsData.versions.length > 1);
66
57
  return {
67
58
  allDocsData,
68
59
  versioningEnabled,
@@ -73,37 +64,22 @@ function useDocsSearchVersionsHelpers() {
73
64
 
74
65
  // We want to display one select per versioned docs plugin instance
75
66
  function SearchVersionSelectList({ docsSearchVersionsHelpers }) {
76
- const versionedPluginEntries = Object.entries(
77
- docsSearchVersionsHelpers.allDocsData,
78
- )
67
+ const versionedPluginEntries = Object.entries(docsSearchVersionsHelpers.allDocsData)
79
68
  // Do not show a version select for unversioned docs plugin instances
80
69
  .filter(([, docsData]) => docsData.versions.length > 1);
81
70
  return (
82
- <div
83
- className={clsx(
84
- 'col',
85
- 'col--3',
86
- 'padding-left--none',
87
- styles.searchVersionColumn,
88
- )}>
71
+ <div className={clsx('col', 'col--3', 'padding-left--none', styles.searchVersionColumn)}>
89
72
  {versionedPluginEntries.map(([pluginId, docsData]) => {
90
73
  const labelPrefix = versionedPluginEntries.length > 1 ? `${pluginId}: ` : '';
91
74
  return (
92
75
  <select
93
76
  key={pluginId}
94
- onChange={(e) => docsSearchVersionsHelpers.setSearchVersion(
95
- pluginId,
96
- e.target.value,
97
- )
98
- }
77
+ onChange={(e) => docsSearchVersionsHelpers.setSearchVersion(pluginId, e.target.value)}
99
78
  defaultValue={docsSearchVersionsHelpers.searchVersions[pluginId]}
100
- className={styles.searchVersionInput}>
79
+ className={styles.searchVersionInput}
80
+ >
101
81
  {docsData.versions.map((version, i) => (
102
- <option
103
- key={i}
104
- label={`${labelPrefix}${version.label}`}
105
- value={version.name}
106
- />
82
+ <option key={i} label={`${labelPrefix}${version.label}`} value={version.name} />
107
83
  ))}
108
84
  </select>
109
85
  );
@@ -113,7 +89,10 @@ function SearchVersionSelectList({ docsSearchVersionsHelpers }) {
113
89
  }
114
90
 
115
91
  function SearchPageContent() {
116
- const { siteConfig, i18n: { currentLocale } } = useDocusaurusContext();
92
+ const {
93
+ siteConfig,
94
+ i18n: { currentLocale },
95
+ } = useDocusaurusContext();
117
96
  const {
118
97
  algolia: { appId, apiKey, indexName },
119
98
  } = useAlgoliaThemeConfig();
@@ -132,41 +111,35 @@ function SearchPageContent() {
132
111
  hasMore: null,
133
112
  loading: null,
134
113
  };
135
- const [searchResultState, searchResultStateDispatcher] = useReducer(
136
- (prevState, data) => {
137
- switch (data.type) {
138
- case 'reset': {
139
- return initialSearchResultState;
140
- }
141
- case 'loading': {
142
- return { ...prevState, loading: true };
143
- }
144
- case 'update': {
145
- if (searchQuery !== data.value.query) {
146
- return prevState;
147
- }
148
- return {
149
- ...data.value,
150
- items:
151
- data.value.lastPage === 0
152
- ? data.value.items
153
- : prevState.items.concat(data.value.items),
154
- };
155
- }
156
- case 'advance': {
157
- const hasMore = prevState.totalPages > prevState.lastPage + 1;
158
- return {
159
- ...prevState,
160
- lastPage: hasMore ? prevState.lastPage + 1 : prevState.lastPage,
161
- hasMore,
162
- };
163
- }
164
- default:
114
+ const [searchResultState, searchResultStateDispatcher] = useReducer((prevState, data) => {
115
+ switch (data.type) {
116
+ case 'reset': {
117
+ return initialSearchResultState;
118
+ }
119
+ case 'loading': {
120
+ return { ...prevState, loading: true };
121
+ }
122
+ case 'update': {
123
+ if (searchQuery !== data.value.query) {
165
124
  return prevState;
125
+ }
126
+ return {
127
+ ...data.value,
128
+ items: data.value.lastPage === 0 ? data.value.items : prevState.items.concat(data.value.items),
129
+ };
166
130
  }
167
- },
168
- initialSearchResultState,
169
- );
131
+ case 'advance': {
132
+ const hasMore = prevState.totalPages > prevState.lastPage + 1;
133
+ return {
134
+ ...prevState,
135
+ lastPage: hasMore ? prevState.lastPage + 1 : prevState.lastPage,
136
+ hasMore,
137
+ };
138
+ }
139
+ default:
140
+ return prevState;
141
+ }
142
+ }, initialSearchResultState);
170
143
  const algoliaClient = liteClient(appId, apiKey);
171
144
  const algoliaHelper = algoliaSearchHelper(algoliaClient, indexName, {
172
145
  hitsPerPage: 15,
@@ -174,97 +147,80 @@ function SearchPageContent() {
174
147
  disjunctiveFacets: ['language', 'docusaurus_tag'],
175
148
  });
176
149
 
177
- algoliaHelper.on(
178
- 'result',
179
- ({ results: { query, hits, page, nbHits, nbPages } }) => {
180
- if (query === '' || !Array.isArray(hits)) {
181
- searchResultStateDispatcher({ type: 'reset' });
182
- return;
150
+ algoliaHelper.on('result', ({ results: { query, hits, page, nbHits, nbPages } }) => {
151
+ if (query === '' || !Array.isArray(hits)) {
152
+ searchResultStateDispatcher({ type: 'reset' });
153
+ return;
154
+ }
155
+ const sanitizeValue = (value) =>
156
+ value.replace(/algolia-docsearch-suggestion--highlight/g, 'search-result-match');
157
+ const items = hits.map(({ url, _highlightResult: { hierarchy }, _snippetResult: snippet = {} }) => {
158
+ if (url.startsWith(siteConfig.url)) {
159
+ url = url.substring(siteConfig.url.length);
183
160
  }
184
- const sanitizeValue = (value) => value.replace(
185
- /algolia-docsearch-suggestion--highlight/g,
186
- 'search-result-match',
187
- );
188
- const items = hits.map(
189
- ({
190
- url,
191
- _highlightResult: { hierarchy },
192
- _snippetResult: snippet = {},
193
- }) => {
194
- if (url.startsWith(siteConfig.url)) {
195
- url = url.substring(siteConfig.url.length);
196
- }
197
161
 
198
- const titles = Object.keys(hierarchy).map((key) => sanitizeValue(hierarchy[key].value));
199
- return {
200
- title: titles.pop(),
201
- url,
202
- summary: snippet.content
203
- ? `${sanitizeValue(snippet.content.value)}...`
204
- : '',
205
- breadcrumbs: titles,
206
- };
207
- },
208
- );
209
- searchResultStateDispatcher({
210
- type: 'update',
211
- value: {
212
- items,
213
- query,
214
- totalResults: nbHits,
215
- totalPages: nbPages,
216
- lastPage: page,
217
- hasMore: nbPages > page + 1,
218
- loading: false,
219
- },
220
- });
221
- },
222
- );
162
+ const titles = Object.keys(hierarchy).map((key) => sanitizeValue(hierarchy[key].value));
163
+ return {
164
+ title: titles.pop(),
165
+ url,
166
+ summary: snippet.content ? `${sanitizeValue(snippet.content.value)}...` : '',
167
+ breadcrumbs: titles,
168
+ };
169
+ });
170
+ searchResultStateDispatcher({
171
+ type: 'update',
172
+ value: {
173
+ items,
174
+ query,
175
+ totalResults: nbHits,
176
+ totalPages: nbPages,
177
+ lastPage: page,
178
+ hasMore: nbPages > page + 1,
179
+ loading: false,
180
+ },
181
+ });
182
+ });
223
183
  const [loaderRef, setLoaderRef] = useState(null);
224
184
  const prevY = useRef(0);
225
185
  const observer = useRef(
226
- ExecutionEnvironment.canUseIntersectionObserver
227
- && new IntersectionObserver(
228
- (entries) => {
229
- const {
230
- isIntersecting,
231
- boundingClientRect: { y: currentY },
232
- } = entries[0];
233
- if (isIntersecting && prevY.current > currentY) {
234
- searchResultStateDispatcher({ type: 'advance' });
235
- }
236
- prevY.current = currentY;
237
- },
238
- { threshold: 1 },
239
- ),
186
+ ExecutionEnvironment.canUseIntersectionObserver &&
187
+ new IntersectionObserver(
188
+ (entries) => {
189
+ const {
190
+ isIntersecting,
191
+ boundingClientRect: { y: currentY },
192
+ } = entries[0];
193
+ if (isIntersecting && prevY.current > currentY) {
194
+ searchResultStateDispatcher({ type: 'advance' });
195
+ }
196
+ prevY.current = currentY;
197
+ },
198
+ { threshold: 1 },
199
+ ),
240
200
  );
241
- const getTitle = () => (searchQuery
242
- ? translate(
243
- {
244
- id: 'theme.SearchPage.existingResultsTitle',
245
- message: 'Search results for "{query}"',
246
- description: 'The search page title for non-empty query',
247
- },
248
- {
249
- query: searchQuery,
250
- },
251
- )
252
- : translate({
253
- id: 'theme.SearchPage.emptyResultsTitle',
254
- message: 'Search the documentation',
255
- description: 'The search page title for empty query',
256
- }));
201
+ const getTitle = () =>
202
+ searchQuery
203
+ ? translate(
204
+ {
205
+ id: 'theme.SearchPage.existingResultsTitle',
206
+ message: 'Search results for "{query}"',
207
+ description: 'The search page title for non-empty query',
208
+ },
209
+ {
210
+ query: searchQuery,
211
+ },
212
+ )
213
+ : translate({
214
+ id: 'theme.SearchPage.emptyResultsTitle',
215
+ message: 'Search the documentation',
216
+ description: 'The search page title for empty query',
217
+ });
257
218
  const makeSearch = useEvent((page = 0) => {
258
219
  algoliaHelper.addDisjunctiveFacetRefinement('docusaurus_tag', 'default-latest');
259
220
  algoliaHelper.addDisjunctiveFacetRefinement('language', currentLocale);
260
- Object.entries(docsSearchVersionsHelpers.searchVersions).forEach(
261
- ([pluginId, searchVersion]) => {
262
- algoliaHelper.addDisjunctiveFacetRefinement(
263
- 'docusaurus_tag',
264
- `docs-${pluginId}-${searchVersion}`,
265
- );
266
- },
267
- );
221
+ Object.entries(docsSearchVersionsHelpers.searchVersions).forEach(([pluginId, searchVersion]) => {
222
+ algoliaHelper.addDisjunctiveFacetRefinement('docusaurus_tag', `docs-${pluginId}-${searchVersion}`);
223
+ });
268
224
  algoliaHelper.setQuery(searchQuery).setPage(page).search();
269
225
  });
270
226
  useEffect(() => {
@@ -301,7 +257,7 @@ function SearchPageContent() {
301
257
  We should not index search pages
302
258
  See https://github.com/facebook/docusaurus/pull/3233
303
259
  */}
304
- <meta property="robots" content="noindex, follow"/>
260
+ <meta property="robots" content="noindex, follow" />
305
261
  </Head>
306
262
 
307
263
  <div className="container margin-vert--lg">
@@ -319,7 +275,8 @@ function SearchPageContent() {
319
275
  className={clsx('col', styles.searchQueryColumn, {
320
276
  'col--9': docsSearchVersionsHelpers.versioningEnabled,
321
277
  'col--12': !docsSearchVersionsHelpers.versioningEnabled,
322
- })}>
278
+ })}
279
+ >
323
280
  <input
324
281
  type="search"
325
282
  name="q"
@@ -342,25 +299,16 @@ function SearchPageContent() {
342
299
  </div>
343
300
 
344
301
  {docsSearchVersionsHelpers.versioningEnabled && (
345
- <SearchVersionSelectList
346
- docsSearchVersionsHelpers={docsSearchVersionsHelpers}
347
- />
302
+ <SearchVersionSelectList docsSearchVersionsHelpers={docsSearchVersionsHelpers} />
348
303
  )}
349
304
  </form>
350
305
 
351
306
  <div className="row">
352
307
  <div className={clsx('col', 'col--8', styles.searchResultsColumn)}>
353
- {!!searchResultState.totalResults
354
- && documentsFoundPlural(searchResultState.totalResults)}
308
+ {!!searchResultState.totalResults && documentsFoundPlural(searchResultState.totalResults)}
355
309
  </div>
356
310
 
357
- <div
358
- className={clsx(
359
- 'col',
360
- 'col--4',
361
- 'text--right',
362
- styles.searchLogoColumn,
363
- )}>
311
+ <div className={clsx('col', 'col--4', 'text--right', styles.searchLogoColumn)}>
364
312
  <a
365
313
  target="_blank"
366
314
  rel="noopener noreferrer"
@@ -369,7 +317,8 @@ function SearchPageContent() {
369
317
  id: 'theme.SearchPage.algoliaLabel',
370
318
  message: 'Search by Algolia',
371
319
  description: 'The ARIA label for Algolia mention',
372
- })}>
320
+ })}
321
+ >
373
322
  <svg viewBox="0 0 168 24" className={styles.algoliaLogo}>
374
323
  <g fill="none">
375
324
  <path
@@ -392,42 +341,36 @@ function SearchPageContent() {
392
341
 
393
342
  {searchResultState.items.length > 0 ? (
394
343
  <main>
395
- {searchResultState.items.map(
396
- ({ title, url, summary, breadcrumbs }, i) => (
397
- <article key={i} className={styles.searchResultItem}>
398
- <h2 className={styles.searchResultItemHeading}>
399
- <Link href={url} dangerouslySetInnerHTML={{ __html: title }}/>
400
- </h2>
344
+ {searchResultState.items.map(({ title, url, summary, breadcrumbs }, i) => (
345
+ <article key={i} className={styles.searchResultItem}>
346
+ <h2 className={styles.searchResultItemHeading}>
347
+ <Link href={url} dangerouslySetInnerHTML={{ __html: title }} />
348
+ </h2>
401
349
 
402
- {breadcrumbs.length > 0 && (
403
- <nav aria-label="breadcrumbs">
404
- <ul
405
- className={clsx(
406
- 'breadcrumbs',
407
- styles.searchResultItemPath,
408
- )}>
409
- {breadcrumbs.map((html, index) => (
410
- <li
411
- key={index}
412
- className="breadcrumbs__item"
413
- // Developer provided the HTML, so assume it's safe.
414
- dangerouslySetInnerHTML={{ __html: html }}
415
- />
416
- ))}
417
- </ul>
418
- </nav>
419
- )}
350
+ {breadcrumbs.length > 0 && (
351
+ <nav aria-label="breadcrumbs">
352
+ <ul className={clsx('breadcrumbs', styles.searchResultItemPath)}>
353
+ {breadcrumbs.map((html, index) => (
354
+ <li
355
+ key={index}
356
+ className="breadcrumbs__item"
357
+ // Developer provided the HTML, so assume it's safe.
358
+ dangerouslySetInnerHTML={{ __html: html }}
359
+ />
360
+ ))}
361
+ </ul>
362
+ </nav>
363
+ )}
420
364
 
421
- {summary && (
422
- <p
423
- className={styles.searchResultItemSummary}
424
- // Developer provided the HTML, so assume it's safe.
425
- dangerouslySetInnerHTML={{ __html: summary }}
426
- />
427
- )}
428
- </article>
429
- ),
430
- )}
365
+ {summary && (
366
+ <p
367
+ className={styles.searchResultItemSummary}
368
+ // Developer provided the HTML, so assume it's safe.
369
+ dangerouslySetInnerHTML={{ __html: summary }}
370
+ />
371
+ )}
372
+ </article>
373
+ ))}
431
374
  </main>
432
375
  ) : (
433
376
  [
@@ -435,14 +378,13 @@ function SearchPageContent() {
435
378
  <p key="no-results">
436
379
  <Translate
437
380
  id="theme.SearchPage.noResultsText"
438
- description="The paragraph for empty search result">
381
+ description="The paragraph for empty search result"
382
+ >
439
383
  No results were found
440
384
  </Translate>
441
385
  </p>
442
386
  ),
443
- !!searchResultState.loading && (
444
- <div key="spinner" className={styles.loadingSpinner}/>
445
- ),
387
+ !!searchResultState.loading && <div key="spinner" className={styles.loadingSpinner} />,
446
388
  ]
447
389
  )}
448
390
 
@@ -450,7 +392,8 @@ function SearchPageContent() {
450
392
  <div className={styles.loader} ref={setLoaderRef}>
451
393
  <Translate
452
394
  id="theme.SearchPage.fetchingNewResults"
453
- description="The paragraph for fetching new search results">
395
+ description="The paragraph for fetching new search results"
396
+ >
454
397
  Fetching new results...
455
398
  </Translate>
456
399
  </div>
@@ -463,7 +406,7 @@ function SearchPageContent() {
463
406
  export default function SearchPage() {
464
407
  return (
465
408
  <HtmlClassNameProvider className="search-page-wrapper">
466
- <SearchPageContent/>
409
+ <SearchPageContent />
467
410
  </HtmlClassNameProvider>
468
411
  );
469
412
  }