@seqera/docusaurus-theme-seqera 1.0.30-next.99 → 1.0.31-next.102
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/styles/admonition-alerts.css +1 -1
- package/lib/styles/typography.css +3 -3
- package/lib/theme/BlogLayout/index.js +2 -2
- package/lib/theme/BlogPostItem/Container/index.js +6 -1
- package/lib/theme/BlogSidebar/Desktop/index.js +8 -4
- package/lib/theme/Navbar/Content/index.js +10 -2
- package/lib/theme/Navbar/MobileSidebar/PrimaryMenu/index.js +8 -16
- package/lib/theme/NavbarItem/NavbarNavLink.js +7 -0
- package/package.json +1 -1
- package/src/styles/admonition-alerts.css +1 -1
- package/src/styles/typography.css +3 -3
- package/src/theme/BlogLayout/index.tsx +2 -2
- package/src/theme/BlogPostItem/Container/index.tsx +2 -1
- package/src/theme/BlogSidebar/Desktop/index.tsx +4 -3
- package/src/theme/Navbar/Content/index.tsx +4 -2
- package/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx +8 -16
- package/src/theme/NavbarItem/NavbarNavLink.tsx +7 -0
- package/lib/theme/SearchBar/index.d.ts +0 -12
- package/lib/theme/SearchBar/index.js +0 -239
- package/lib/theme/SearchBar/styles.css +0 -21
- package/src/theme/SearchBar/index.tsx +0 -314
- package/src/theme/SearchBar/styles.css +0 -21
|
@@ -18,8 +18,7 @@ h6 {
|
|
|
18
18
|
border-bottom: 4px solid transparent;
|
|
19
19
|
}
|
|
20
20
|
.navbar__link--active {
|
|
21
|
-
|
|
22
|
-
border-bottom: 4px solid var(--color-blu-600);
|
|
21
|
+
border-bottom: 4px solid var(--color-nextflow-500);
|
|
23
22
|
padding-bottom: 0.1rem;
|
|
24
23
|
}
|
|
25
24
|
|
|
@@ -256,6 +255,7 @@ main prose styles
|
|
|
256
255
|
|
|
257
256
|
/* Tables */
|
|
258
257
|
table {
|
|
258
|
+
display: table;
|
|
259
259
|
width: 100%;
|
|
260
260
|
margin-top: 2rem;
|
|
261
261
|
margin-bottom: 2rem;
|
|
@@ -343,7 +343,7 @@ main prose styles
|
|
|
343
343
|
/* Dark mode overrides */
|
|
344
344
|
[data-theme='dark'] .prose__wrapper {
|
|
345
345
|
code:not(pre code) {
|
|
346
|
-
border-color: var(--color-gray-
|
|
346
|
+
border-color: var(--color-gray-700);
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
.admonition code:not(pre code) {
|
|
@@ -7,11 +7,11 @@ export default function BlogLayout(props) {
|
|
|
7
7
|
const hasSidebar = sidebar && sidebar.items.length > 0;
|
|
8
8
|
return (
|
|
9
9
|
<Layout {...layoutProps}>
|
|
10
|
-
<div className="container">
|
|
10
|
+
<div className="container container--fluid margin-vert--lg">
|
|
11
11
|
<div className="row">
|
|
12
12
|
<BlogSidebar sidebar={sidebar} />
|
|
13
13
|
<main
|
|
14
|
-
className={clsx('w-full prose__wrapper col
|
|
14
|
+
className={clsx('w-full prose__wrapper col px-4 md:px-8', {
|
|
15
15
|
'col--7': hasSidebar,
|
|
16
16
|
'col--9 col--offset-1': !hasSidebar,
|
|
17
17
|
})}>
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
2
3
|
export default function BlogPostItemContainer({children, className}) {
|
|
3
|
-
return
|
|
4
|
+
return (
|
|
5
|
+
<article className={clsx('max-w-3xl mx-auto', className)}>
|
|
6
|
+
{children}
|
|
7
|
+
</article>
|
|
8
|
+
);
|
|
4
9
|
}
|
|
@@ -28,7 +28,7 @@ function BlogSidebarDesktop({sidebar}) {
|
|
|
28
28
|
const pathMatch = location.pathname.match(
|
|
29
29
|
/\/changelog\/(?:tags\/)?([^\/]+)(?:\/v[\d.]+.*)?/,
|
|
30
30
|
);
|
|
31
|
-
const product = pathMatch
|
|
31
|
+
const product = pathMatch?.[1] ?? null;
|
|
32
32
|
// Map product names to their correct documentation paths
|
|
33
33
|
const getProductPath = (product) => {
|
|
34
34
|
if (!product || product === 'tags' || product === 'page') return '/';
|
|
@@ -39,9 +39,13 @@ function BlogSidebarDesktop({sidebar}) {
|
|
|
39
39
|
return mapping[product] || `/${product}`;
|
|
40
40
|
};
|
|
41
41
|
// Filter the sidebar for just this product
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
const productPath = getProductPath(product);
|
|
43
|
+
const filteredItems =
|
|
44
|
+
product && productPath !== '/'
|
|
45
|
+
? items.filter((item) =>
|
|
46
|
+
item.permalink.includes(`/changelog/${product}/`),
|
|
47
|
+
)
|
|
48
|
+
: items;
|
|
45
49
|
return (
|
|
46
50
|
<aside
|
|
47
51
|
className={`${styles.sidebarWrapper} col col--3 border-r border-black/20 dark:border-white/20`}>
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
splitNavbarItems,
|
|
10
10
|
useNavbarMobileSidebar,
|
|
11
11
|
} from '@docusaurus/theme-common/internal';
|
|
12
|
+
import {useLocation} from '@docusaurus/router';
|
|
12
13
|
import NavbarItem from '@theme/NavbarItem';
|
|
13
14
|
import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
|
|
14
15
|
import SearchBar from '@theme/SearchBar';
|
|
@@ -66,6 +67,7 @@ function NavbarContentLayout({left, right, isMenuOpen}) {
|
|
|
66
67
|
}
|
|
67
68
|
export default function NavbarContent() {
|
|
68
69
|
const mobileSidebar = useNavbarMobileSidebar();
|
|
70
|
+
const {pathname} = useLocation();
|
|
69
71
|
const items = useNavbarItems();
|
|
70
72
|
const [leftItems, rightItems] = splitNavbarItems(items);
|
|
71
73
|
const searchBarItem = items.find((item) => item.type === 'search');
|
|
@@ -110,13 +112,19 @@ export default function NavbarContent() {
|
|
|
110
112
|
</div>
|
|
111
113
|
<div className="mr-2">
|
|
112
114
|
<a
|
|
113
|
-
className=
|
|
115
|
+
className={clsx(
|
|
116
|
+
'navbar__link ml-8 font-normal',
|
|
117
|
+
pathname.startsWith('/platform-api/') && 'navbar__link--active',
|
|
118
|
+
)}
|
|
114
119
|
href="/platform-api/"
|
|
115
120
|
aria-label="Platform API">
|
|
116
121
|
Platform API
|
|
117
122
|
</a>
|
|
118
123
|
<a
|
|
119
|
-
className=
|
|
124
|
+
className={clsx(
|
|
125
|
+
'navbar__link ml-8 font-normal',
|
|
126
|
+
pathname.startsWith('/changelog/') && 'navbar__link--active',
|
|
127
|
+
)}
|
|
120
128
|
href="/changelog/"
|
|
121
129
|
aria-label="Changelog">
|
|
122
130
|
Changelog
|
|
@@ -50,28 +50,20 @@ export default function NavbarMobilePrimaryMenu() {
|
|
|
50
50
|
Resources
|
|
51
51
|
</h3>
|
|
52
52
|
|
|
53
|
-
<
|
|
54
|
-
<li className="mb-3">
|
|
55
|
-
<Link
|
|
56
|
-
className="menu__link"
|
|
57
|
-
to={'/changelog'}
|
|
58
|
-
aria-label="Changelog">
|
|
59
|
-
Changelog
|
|
60
|
-
</Link>
|
|
61
|
-
</li>
|
|
53
|
+
<li className="mb-3">
|
|
62
54
|
<Link
|
|
63
55
|
className="menu__link"
|
|
64
|
-
to={'/platform-
|
|
65
|
-
aria-label="
|
|
66
|
-
|
|
56
|
+
to={'/platform-api/'}
|
|
57
|
+
aria-label="Platform API">
|
|
58
|
+
Platform API
|
|
67
59
|
</Link>
|
|
68
|
-
</
|
|
60
|
+
</li>
|
|
69
61
|
<li className="mb-3">
|
|
70
62
|
<Link
|
|
71
63
|
className="menu__link"
|
|
72
|
-
to={'/
|
|
73
|
-
aria-label="
|
|
74
|
-
|
|
64
|
+
to={'/changelog/'}
|
|
65
|
+
aria-label="Changelog">
|
|
66
|
+
Changelog
|
|
75
67
|
</Link>
|
|
76
68
|
</li>
|
|
77
69
|
</div>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
2
3
|
import Link from '@docusaurus/Link';
|
|
3
4
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
|
4
5
|
import isInternalUrl from '@docusaurus/isInternalUrl';
|
|
5
6
|
import {isRegexpStringMatch} from '@docusaurus/theme-common';
|
|
7
|
+
import {useLocation} from '@docusaurus/router';
|
|
6
8
|
import IconExternalLink from '@theme/Icon/ExternalLink';
|
|
7
9
|
export default function NavbarNavLink({
|
|
8
10
|
activeBasePath,
|
|
@@ -21,6 +23,7 @@ export default function NavbarNavLink({
|
|
|
21
23
|
const activeBaseUrl = useBaseUrl(activeBasePath);
|
|
22
24
|
const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true});
|
|
23
25
|
const isExternalLink = label && href && !isInternalUrl(href);
|
|
26
|
+
const {pathname} = useLocation();
|
|
24
27
|
// Link content is set through html XOR label
|
|
25
28
|
const linkContentProps = html
|
|
26
29
|
? {dangerouslySetInnerHTML: {__html: html}}
|
|
@@ -37,10 +40,14 @@ export default function NavbarNavLink({
|
|
|
37
40
|
),
|
|
38
41
|
};
|
|
39
42
|
if (href) {
|
|
43
|
+
const isActiveHref = !isExternalLink && pathname.startsWith(href);
|
|
40
44
|
return (
|
|
41
45
|
<Link
|
|
42
46
|
href={prependBaseUrlToHref ? normalizedHref : href}
|
|
43
47
|
{...props}
|
|
48
|
+
{...(isActiveHref && {
|
|
49
|
+
className: clsx(props.className, props.activeClassName),
|
|
50
|
+
})}
|
|
44
51
|
{...linkContentProps}
|
|
45
52
|
/>
|
|
46
53
|
);
|
package/package.json
CHANGED
|
@@ -18,8 +18,7 @@ h6 {
|
|
|
18
18
|
border-bottom: 4px solid transparent;
|
|
19
19
|
}
|
|
20
20
|
.navbar__link--active {
|
|
21
|
-
|
|
22
|
-
border-bottom: 4px solid var(--color-blu-600);
|
|
21
|
+
border-bottom: 4px solid var(--color-nextflow-500);
|
|
23
22
|
padding-bottom: 0.1rem;
|
|
24
23
|
}
|
|
25
24
|
|
|
@@ -256,6 +255,7 @@ main prose styles
|
|
|
256
255
|
|
|
257
256
|
/* Tables */
|
|
258
257
|
table {
|
|
258
|
+
display: table;
|
|
259
259
|
width: 100%;
|
|
260
260
|
margin-top: 2rem;
|
|
261
261
|
margin-bottom: 2rem;
|
|
@@ -343,7 +343,7 @@ main prose styles
|
|
|
343
343
|
/* Dark mode overrides */
|
|
344
344
|
[data-theme='dark'] .prose__wrapper {
|
|
345
345
|
code:not(pre code) {
|
|
346
|
-
border-color: var(--color-gray-
|
|
346
|
+
border-color: var(--color-gray-700);
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
.admonition code:not(pre code) {
|
|
@@ -13,11 +13,11 @@ export default function BlogLayout(props: Props): ReactNode {
|
|
|
13
13
|
|
|
14
14
|
return (
|
|
15
15
|
<Layout {...layoutProps}>
|
|
16
|
-
<div className="container">
|
|
16
|
+
<div className="container container--fluid margin-vert--lg">
|
|
17
17
|
<div className="row">
|
|
18
18
|
<BlogSidebar sidebar={sidebar} />
|
|
19
19
|
<main
|
|
20
|
-
className={clsx('w-full prose__wrapper col
|
|
20
|
+
className={clsx('w-full prose__wrapper col px-4 md:px-8', {
|
|
21
21
|
'col--7': hasSidebar,
|
|
22
22
|
'col--9 col--offset-1': !hasSidebar,
|
|
23
23
|
})}>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
import React, {type ReactNode} from 'react';
|
|
4
|
+
import clsx from 'clsx';
|
|
4
5
|
import type {Props} from '@theme/BlogPostItem/Container';
|
|
5
6
|
|
|
6
7
|
export default function BlogPostItemContainer({
|
|
7
8
|
children,
|
|
8
9
|
className,
|
|
9
10
|
}: Props): ReactNode {
|
|
10
|
-
return <article className={className}>{children}</article>;
|
|
11
|
+
return <article className={clsx('max-w-3xl mx-auto', className)}>{children}</article>;
|
|
11
12
|
}
|
|
@@ -31,7 +31,7 @@ function BlogSidebarDesktop({sidebar}: Props) {
|
|
|
31
31
|
// Figure out if we're looking at a product tag or changelog entry
|
|
32
32
|
const location = useLocation();
|
|
33
33
|
const pathMatch = location.pathname.match(/\/changelog\/(?:tags\/)?([^\/]+)(?:\/v[\d.]+.*)?/);
|
|
34
|
-
const product = pathMatch
|
|
34
|
+
const product = pathMatch?.[1] ?? null;
|
|
35
35
|
|
|
36
36
|
// Map product names to their correct documentation paths
|
|
37
37
|
const getProductPath = (product: string | null): string => {
|
|
@@ -44,8 +44,9 @@ function BlogSidebarDesktop({sidebar}: Props) {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
// Filter the sidebar for just this product
|
|
47
|
-
const
|
|
48
|
-
|
|
47
|
+
const productPath = getProductPath(product);
|
|
48
|
+
const filteredItems = product && productPath !== '/'
|
|
49
|
+
? items.filter(item => item.permalink.includes(`/changelog/${product}/`))
|
|
49
50
|
: items;
|
|
50
51
|
|
|
51
52
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
splitNavbarItems,
|
|
10
10
|
useNavbarMobileSidebar,
|
|
11
11
|
} from '@docusaurus/theme-common/internal';
|
|
12
|
+
import {useLocation} from '@docusaurus/router';
|
|
12
13
|
import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem';
|
|
13
14
|
import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
|
|
14
15
|
import SearchBar from '@theme/SearchBar';
|
|
@@ -79,6 +80,7 @@ function NavbarContentLayout({
|
|
|
79
80
|
|
|
80
81
|
export default function NavbarContent(): ReactNode {
|
|
81
82
|
const mobileSidebar = useNavbarMobileSidebar();
|
|
83
|
+
const {pathname} = useLocation();
|
|
82
84
|
|
|
83
85
|
const items = useNavbarItems();
|
|
84
86
|
const [leftItems, rightItems] = splitNavbarItems(items);
|
|
@@ -126,13 +128,13 @@ export default function NavbarContent(): ReactNode {
|
|
|
126
128
|
</div>
|
|
127
129
|
<div className="mr-2">
|
|
128
130
|
<a
|
|
129
|
-
className=
|
|
131
|
+
className={clsx('navbar__link ml-8 font-normal', pathname.startsWith('/platform-api/') && 'navbar__link--active')}
|
|
130
132
|
href="/platform-api/"
|
|
131
133
|
aria-label="Platform API">
|
|
132
134
|
Platform API
|
|
133
135
|
</a>
|
|
134
136
|
<a
|
|
135
|
-
className=
|
|
137
|
+
className={clsx('navbar__link ml-8 font-normal', pathname.startsWith('/changelog/') && 'navbar__link--active')}
|
|
136
138
|
href="/changelog/"
|
|
137
139
|
aria-label="Changelog">
|
|
138
140
|
Changelog
|
|
@@ -54,28 +54,20 @@ export default function NavbarMobilePrimaryMenu(): ReactNode {
|
|
|
54
54
|
Resources
|
|
55
55
|
</h3>
|
|
56
56
|
|
|
57
|
-
<
|
|
58
|
-
<li className="mb-3">
|
|
59
|
-
<Link
|
|
60
|
-
className="menu__link"
|
|
61
|
-
to={'/changelog'}
|
|
62
|
-
aria-label="Changelog">
|
|
63
|
-
Changelog
|
|
64
|
-
</Link>
|
|
65
|
-
</li>
|
|
57
|
+
<li className="mb-3">
|
|
66
58
|
<Link
|
|
67
59
|
className="menu__link"
|
|
68
|
-
to={'/platform-
|
|
69
|
-
aria-label="
|
|
70
|
-
|
|
60
|
+
to={'/platform-api/'}
|
|
61
|
+
aria-label="Platform API">
|
|
62
|
+
Platform API
|
|
71
63
|
</Link>
|
|
72
|
-
</
|
|
64
|
+
</li>
|
|
73
65
|
<li className="mb-3">
|
|
74
66
|
<Link
|
|
75
67
|
className="menu__link"
|
|
76
|
-
to={'/
|
|
77
|
-
aria-label="
|
|
78
|
-
|
|
68
|
+
to={'/changelog/'}
|
|
69
|
+
aria-label="Changelog">
|
|
70
|
+
Changelog
|
|
79
71
|
</Link>
|
|
80
72
|
</li>
|
|
81
73
|
</div>
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
import React, {type ReactNode} from 'react';
|
|
4
|
+
import clsx from 'clsx';
|
|
4
5
|
import Link from '@docusaurus/Link';
|
|
5
6
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
|
6
7
|
import isInternalUrl from '@docusaurus/isInternalUrl';
|
|
7
8
|
import {isRegexpStringMatch} from '@docusaurus/theme-common';
|
|
9
|
+
import {useLocation} from '@docusaurus/router';
|
|
8
10
|
import IconExternalLink from '@theme/Icon/ExternalLink';
|
|
9
11
|
import type {Props} from '@theme/NavbarItem/NavbarNavLink';
|
|
10
12
|
|
|
@@ -25,6 +27,7 @@ export default function NavbarNavLink({
|
|
|
25
27
|
const activeBaseUrl = useBaseUrl(activeBasePath);
|
|
26
28
|
const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true});
|
|
27
29
|
const isExternalLink = label && href && !isInternalUrl(href);
|
|
30
|
+
const {pathname} = useLocation();
|
|
28
31
|
|
|
29
32
|
// Link content is set through html XOR label
|
|
30
33
|
const linkContentProps = html
|
|
@@ -43,10 +46,14 @@ export default function NavbarNavLink({
|
|
|
43
46
|
};
|
|
44
47
|
|
|
45
48
|
if (href) {
|
|
49
|
+
const isActiveHref = !isExternalLink && pathname.startsWith(href);
|
|
46
50
|
return (
|
|
47
51
|
<Link
|
|
48
52
|
href={prependBaseUrlToHref ? normalizedHref : href}
|
|
49
53
|
{...props}
|
|
54
|
+
{...(isActiveHref && {
|
|
55
|
+
className: clsx(props.className, props.activeClassName),
|
|
56
|
+
})}
|
|
50
57
|
{...linkContentProps}
|
|
51
58
|
/>
|
|
52
59
|
);
|
|
@@ -1,12 +0,0 @@
|
|
|
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
|
-
* Swizzled from docusaurus-theme-search-typesense SearchBar.
|
|
8
|
-
* Adds full hierarchy breadcrumbs and product labels to the path shown
|
|
9
|
-
* under each modal result. Product routes are configured via
|
|
10
|
-
* themeConfig.typesense.productRoutes.
|
|
11
|
-
*/
|
|
12
|
-
export default function SearchBar(): JSX.Element;
|
|
@@ -1,239 +0,0 @@
|
|
|
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
|
-
* Swizzled from docusaurus-theme-search-typesense SearchBar.
|
|
8
|
-
* Adds full hierarchy breadcrumbs and product labels to the path shown
|
|
9
|
-
* under each modal result. Product routes are configured via
|
|
10
|
-
* themeConfig.typesense.productRoutes.
|
|
11
|
-
*/
|
|
12
|
-
import React, {useState, useRef, useCallback, useMemo} from 'react';
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
import {createPortal} from 'react-dom';
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
import {useHistory} from '@docusaurus/router';
|
|
19
|
-
// @ts-ignore
|
|
20
|
-
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
import Link from '@docusaurus/Link';
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
import {isRegexpStringMatch} from '@docusaurus/theme-common';
|
|
25
|
-
import {
|
|
26
|
-
DocSearchButton,
|
|
27
|
-
useDocSearchKeyboardEvents,
|
|
28
|
-
} from 'typesense-docsearch-react';
|
|
29
|
-
import {useTypesenseContextualFilters} from 'docusaurus-theme-search-typesense/client';
|
|
30
|
-
// @ts-ignore
|
|
31
|
-
import Translate from '@docusaurus/Translate';
|
|
32
|
-
// @ts-ignore
|
|
33
|
-
import translations from '@theme/SearchTranslations';
|
|
34
|
-
import {DocsPreferredVersionContextProvider} from '@docusaurus/plugin-content-docs/lib/client/index.js';
|
|
35
|
-
let DocSearchModal = null;
|
|
36
|
-
function Hit({hit, children}) {
|
|
37
|
-
return <Link to={hit.url}>{children}</Link>;
|
|
38
|
-
}
|
|
39
|
-
function ResultsFooter({state, onClose}) {
|
|
40
|
-
const {
|
|
41
|
-
siteConfig: {baseUrl},
|
|
42
|
-
} = useDocusaurusContext();
|
|
43
|
-
return (
|
|
44
|
-
<Link
|
|
45
|
-
to={`${baseUrl}search?q=${encodeURIComponent(state.query)}`}
|
|
46
|
-
onClick={onClose}>
|
|
47
|
-
<Translate
|
|
48
|
-
id="theme.SearchBar.seeAll"
|
|
49
|
-
values={{count: state.context.nbHits}}>
|
|
50
|
-
{'See all {count} results'}
|
|
51
|
-
</Translate>
|
|
52
|
-
</Link>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Resolve a product label from a URL pathname using the configured productRoutes.
|
|
57
|
-
*/
|
|
58
|
-
function getProductLabel(pathname, productRoutes) {
|
|
59
|
-
const match = productRoutes.find(([prefix]) => pathname.startsWith(prefix));
|
|
60
|
-
return match ? match[1] : null;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Build a breadcrumb string from all ancestor hierarchy levels of a hit.
|
|
64
|
-
* For lvl2+ and content hits this replaces the single-level hierarchy.lvl1
|
|
65
|
-
* path with the full parent chain (e.g. "Nextflow › Getting Started › Installation").
|
|
66
|
-
*
|
|
67
|
-
* When productRoutes are provided, the first level (lvl0, typically "Documentation")
|
|
68
|
-
* is replaced with the product name derived from the hit URL.
|
|
69
|
-
*/
|
|
70
|
-
function buildBreadcrumb(item, productRoutes) {
|
|
71
|
-
const {type} = item;
|
|
72
|
-
const maxLevel =
|
|
73
|
-
type === 'content' ? 7 : parseInt(type.replace('lvl', ''), 10);
|
|
74
|
-
const parts = [];
|
|
75
|
-
for (let i = 0; i < maxLevel; i++) {
|
|
76
|
-
const val = item[`hierarchy.lvl${i}`];
|
|
77
|
-
if (val) parts.push(val);
|
|
78
|
-
}
|
|
79
|
-
// Replace lvl0 (typically "Documentation") with the product label
|
|
80
|
-
if (parts.length > 0 && productRoutes.length > 0) {
|
|
81
|
-
try {
|
|
82
|
-
const pathname = new URL(item.url).pathname;
|
|
83
|
-
const product = getProductLabel(pathname, productRoutes);
|
|
84
|
-
if (product) {
|
|
85
|
-
parts[0] = product;
|
|
86
|
-
}
|
|
87
|
-
} catch {
|
|
88
|
-
// URL parsing failed — keep the original lvl0 value
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return parts.length > 1 ? parts.join(' › ') : null;
|
|
92
|
-
}
|
|
93
|
-
function DocSearch({
|
|
94
|
-
contextualSearch,
|
|
95
|
-
externalUrlRegex,
|
|
96
|
-
productRoutes = [],
|
|
97
|
-
...props
|
|
98
|
-
}) {
|
|
99
|
-
const contextualSearchFacetFilters = useTypesenseContextualFilters();
|
|
100
|
-
const configFacetFilters = props.typesenseSearchParameters?.filter_by ?? '';
|
|
101
|
-
const facetFilters = contextualSearch
|
|
102
|
-
? [contextualSearchFacetFilters, configFacetFilters]
|
|
103
|
-
.filter((e) => e)
|
|
104
|
-
.join(' && ')
|
|
105
|
-
: configFacetFilters;
|
|
106
|
-
const typesenseSearchParameters = {
|
|
107
|
-
filter_by: facetFilters,
|
|
108
|
-
...props.typesenseSearchParameters,
|
|
109
|
-
};
|
|
110
|
-
const {withBaseUrl} = useBaseUrlUtils();
|
|
111
|
-
const history = useHistory();
|
|
112
|
-
const searchContainer = useRef(null);
|
|
113
|
-
const searchButtonRef = useRef(null);
|
|
114
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
115
|
-
const [initialQuery, setInitialQuery] = useState(undefined);
|
|
116
|
-
const importDocSearchModalIfNeeded = useCallback(() => {
|
|
117
|
-
if (DocSearchModal) {
|
|
118
|
-
return Promise.resolve();
|
|
119
|
-
}
|
|
120
|
-
return Promise.all([
|
|
121
|
-
// @ts-ignore
|
|
122
|
-
import('typesense-docsearch-react/modal'),
|
|
123
|
-
// @ts-ignore
|
|
124
|
-
import('typesense-docsearch-react/style'),
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
import('./styles.css'),
|
|
127
|
-
]).then(([{DocSearchModal: Modal}]) => {
|
|
128
|
-
DocSearchModal = Modal;
|
|
129
|
-
});
|
|
130
|
-
}, []);
|
|
131
|
-
const onOpen = useCallback(() => {
|
|
132
|
-
importDocSearchModalIfNeeded().then(() => {
|
|
133
|
-
searchContainer.current = document.createElement('div');
|
|
134
|
-
document.body.insertBefore(
|
|
135
|
-
searchContainer.current,
|
|
136
|
-
document.body.firstChild,
|
|
137
|
-
);
|
|
138
|
-
setIsOpen(true);
|
|
139
|
-
});
|
|
140
|
-
}, [importDocSearchModalIfNeeded]);
|
|
141
|
-
const onClose = useCallback(() => {
|
|
142
|
-
setIsOpen(false);
|
|
143
|
-
searchContainer.current?.remove();
|
|
144
|
-
}, []);
|
|
145
|
-
const onInput = useCallback(
|
|
146
|
-
(event) => {
|
|
147
|
-
importDocSearchModalIfNeeded().then(() => {
|
|
148
|
-
setIsOpen(true);
|
|
149
|
-
setInitialQuery(event.key);
|
|
150
|
-
});
|
|
151
|
-
},
|
|
152
|
-
[importDocSearchModalIfNeeded],
|
|
153
|
-
);
|
|
154
|
-
const navigator = useRef({
|
|
155
|
-
navigate({itemUrl}) {
|
|
156
|
-
if (isRegexpStringMatch(externalUrlRegex, itemUrl)) {
|
|
157
|
-
window.location.href = itemUrl;
|
|
158
|
-
} else {
|
|
159
|
-
history.push(itemUrl);
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
}).current;
|
|
163
|
-
const transformItems = useRef((items) =>
|
|
164
|
-
items.map((item) => {
|
|
165
|
-
// Transform absolute URL to relative.
|
|
166
|
-
const withRelativeUrl = isRegexpStringMatch(externalUrlRegex, item.url)
|
|
167
|
-
? item
|
|
168
|
-
: {
|
|
169
|
-
...item,
|
|
170
|
-
url: withBaseUrl(
|
|
171
|
-
`${new URL(item.url).pathname}${new URL(item.url).hash}`,
|
|
172
|
-
),
|
|
173
|
-
};
|
|
174
|
-
// Overwrite hierarchy.lvl1 with the full ancestor breadcrumb so the
|
|
175
|
-
// DocSearch-Hit-path slot shows the complete path for lvl2+ results.
|
|
176
|
-
const breadcrumb = buildBreadcrumb(withRelativeUrl, productRoutes);
|
|
177
|
-
if (!breadcrumb) return withRelativeUrl;
|
|
178
|
-
return {
|
|
179
|
-
...withRelativeUrl,
|
|
180
|
-
'hierarchy.lvl1': breadcrumb,
|
|
181
|
-
};
|
|
182
|
-
}),
|
|
183
|
-
).current;
|
|
184
|
-
const resultsFooterComponent = useMemo(
|
|
185
|
-
() =>
|
|
186
|
-
// eslint-disable-next-line react/no-unstable-nested-components
|
|
187
|
-
(footerProps) =>
|
|
188
|
-
<ResultsFooter {...footerProps} onClose={onClose} />,
|
|
189
|
-
[onClose],
|
|
190
|
-
);
|
|
191
|
-
useDocSearchKeyboardEvents({
|
|
192
|
-
isOpen,
|
|
193
|
-
onOpen,
|
|
194
|
-
onClose,
|
|
195
|
-
onInput,
|
|
196
|
-
searchButtonRef,
|
|
197
|
-
});
|
|
198
|
-
return (
|
|
199
|
-
<>
|
|
200
|
-
<DocSearchButton
|
|
201
|
-
onTouchStart={importDocSearchModalIfNeeded}
|
|
202
|
-
onFocus={importDocSearchModalIfNeeded}
|
|
203
|
-
onMouseOver={importDocSearchModalIfNeeded}
|
|
204
|
-
onClick={onOpen}
|
|
205
|
-
ref={searchButtonRef}
|
|
206
|
-
translations={translations.button}
|
|
207
|
-
/>
|
|
208
|
-
{isOpen &&
|
|
209
|
-
DocSearchModal &&
|
|
210
|
-
searchContainer.current &&
|
|
211
|
-
createPortal(
|
|
212
|
-
<DocSearchModal
|
|
213
|
-
onClose={onClose}
|
|
214
|
-
initialScrollY={window.scrollY}
|
|
215
|
-
initialQuery={initialQuery}
|
|
216
|
-
navigator={navigator}
|
|
217
|
-
transformItems={transformItems}
|
|
218
|
-
hitComponent={Hit}
|
|
219
|
-
{...(props.searchPagePath && {resultsFooterComponent})}
|
|
220
|
-
{...props}
|
|
221
|
-
typesenseSearchParameters={typesenseSearchParameters}
|
|
222
|
-
typesenseServerConfig={props.typesenseServerConfig}
|
|
223
|
-
typesenseCollectionName={props.typesenseCollectionName}
|
|
224
|
-
placeholder={translations.placeholder}
|
|
225
|
-
translations={translations.modal}
|
|
226
|
-
/>,
|
|
227
|
-
searchContainer.current,
|
|
228
|
-
)}
|
|
229
|
-
</>
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
export default function SearchBar() {
|
|
233
|
-
const {siteConfig} = useDocusaurusContext();
|
|
234
|
-
return (
|
|
235
|
-
<DocsPreferredVersionContextProvider>
|
|
236
|
-
<DocSearch {...siteConfig.themeConfig.typesense} />
|
|
237
|
-
</DocsPreferredVersionContextProvider>
|
|
238
|
-
);
|
|
239
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
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
|
-
:root {
|
|
9
|
-
--docsearch-primary-color: var(--ifm-color-primary);
|
|
10
|
-
--docsearch-text-color: var(--ifm-font-color-base);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.DocSearch-Button {
|
|
14
|
-
margin: 0;
|
|
15
|
-
transition: all var(--ifm-transition-fast)
|
|
16
|
-
var(--ifm-transition-timing-default);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.DocSearch-Container {
|
|
20
|
-
z-index: calc(var(--ifm-z-index-fixed) + 1);
|
|
21
|
-
}
|
|
@@ -1,314 +0,0 @@
|
|
|
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
|
-
* Swizzled from docusaurus-theme-search-typesense SearchBar.
|
|
8
|
-
* Adds full hierarchy breadcrumbs and product labels to the path shown
|
|
9
|
-
* under each modal result. Product routes are configured via
|
|
10
|
-
* themeConfig.typesense.productRoutes.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import React, {useState, useRef, useCallback, useMemo} from 'react';
|
|
14
|
-
// @ts-ignore
|
|
15
|
-
import {createPortal} from 'react-dom';
|
|
16
|
-
// @ts-ignore
|
|
17
|
-
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
import {useHistory} from '@docusaurus/router';
|
|
20
|
-
// @ts-ignore
|
|
21
|
-
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
|
|
22
|
-
// @ts-ignore
|
|
23
|
-
import Link from '@docusaurus/Link';
|
|
24
|
-
// @ts-ignore
|
|
25
|
-
import {isRegexpStringMatch} from '@docusaurus/theme-common';
|
|
26
|
-
import {
|
|
27
|
-
DocSearchButton,
|
|
28
|
-
useDocSearchKeyboardEvents,
|
|
29
|
-
} from 'typesense-docsearch-react';
|
|
30
|
-
import {useTypesenseContextualFilters} from 'docusaurus-theme-search-typesense/client';
|
|
31
|
-
// @ts-ignore
|
|
32
|
-
import Translate from '@docusaurus/Translate';
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
import translations from '@theme/SearchTranslations';
|
|
35
|
-
import {DocsPreferredVersionContextProvider} from '@docusaurus/plugin-content-docs/lib/client/index.js';
|
|
36
|
-
|
|
37
|
-
import type {
|
|
38
|
-
DocSearchModal as DocSearchModalType,
|
|
39
|
-
DocSearchModalProps,
|
|
40
|
-
} from 'typesense-docsearch-react';
|
|
41
|
-
import type {
|
|
42
|
-
InternalDocSearchHit,
|
|
43
|
-
StoredDocSearchHit,
|
|
44
|
-
} from 'typesense-docsearch-react/dist/esm/types';
|
|
45
|
-
|
|
46
|
-
type DocSearchProps = Omit<
|
|
47
|
-
DocSearchModalProps,
|
|
48
|
-
'onClose' | 'initialScrollY'
|
|
49
|
-
> & {
|
|
50
|
-
contextualSearch?: string;
|
|
51
|
-
externalUrlRegex?: string;
|
|
52
|
-
searchPagePath: boolean | string;
|
|
53
|
-
productRoutes?: [string, string, string | null, string | null][];
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
let DocSearchModal: typeof DocSearchModalType | null = null;
|
|
57
|
-
|
|
58
|
-
function Hit({
|
|
59
|
-
hit,
|
|
60
|
-
children,
|
|
61
|
-
}: {
|
|
62
|
-
hit: InternalDocSearchHit | StoredDocSearchHit;
|
|
63
|
-
children: React.ReactNode;
|
|
64
|
-
}) {
|
|
65
|
-
return <Link to={hit.url}>{children}</Link>;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
type ResultsFooterProps = {
|
|
69
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
-
state: any;
|
|
71
|
-
onClose: () => void;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
function ResultsFooter({state, onClose}: ResultsFooterProps) {
|
|
75
|
-
const {
|
|
76
|
-
siteConfig: {baseUrl},
|
|
77
|
-
} = useDocusaurusContext();
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<Link
|
|
81
|
-
to={`${baseUrl}search?q=${encodeURIComponent(state.query)}`}
|
|
82
|
-
onClick={onClose}>
|
|
83
|
-
<Translate
|
|
84
|
-
id="theme.SearchBar.seeAll"
|
|
85
|
-
values={{count: state.context.nbHits}}>
|
|
86
|
-
{'See all {count} results'}
|
|
87
|
-
</Translate>
|
|
88
|
-
</Link>
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Resolve a product label from a URL pathname using the configured productRoutes.
|
|
94
|
-
*/
|
|
95
|
-
function getProductLabel(
|
|
96
|
-
pathname: string,
|
|
97
|
-
productRoutes: [string, string, string | null, string | null][],
|
|
98
|
-
): string | null {
|
|
99
|
-
const match = productRoutes.find(([prefix]) =>
|
|
100
|
-
pathname.startsWith(prefix),
|
|
101
|
-
);
|
|
102
|
-
return match ? match[1] : null;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Build a breadcrumb string from all ancestor hierarchy levels of a hit.
|
|
107
|
-
* For lvl2+ and content hits this replaces the single-level hierarchy.lvl1
|
|
108
|
-
* path with the full parent chain (e.g. "Nextflow › Getting Started › Installation").
|
|
109
|
-
*
|
|
110
|
-
* When productRoutes are provided, the first level (lvl0, typically "Documentation")
|
|
111
|
-
* is replaced with the product name derived from the hit URL.
|
|
112
|
-
*/
|
|
113
|
-
function buildBreadcrumb(
|
|
114
|
-
item: InternalDocSearchHit | StoredDocSearchHit,
|
|
115
|
-
productRoutes: [string, string, string | null, string | null][],
|
|
116
|
-
): string | null {
|
|
117
|
-
const {type} = item;
|
|
118
|
-
const maxLevel =
|
|
119
|
-
type === 'content' ? 7 : parseInt(type.replace('lvl', ''), 10);
|
|
120
|
-
|
|
121
|
-
const parts: string[] = [];
|
|
122
|
-
for (let i = 0; i < maxLevel; i++) {
|
|
123
|
-
const val = (item as unknown as Record<string, string | null>)[
|
|
124
|
-
`hierarchy.lvl${i}`
|
|
125
|
-
];
|
|
126
|
-
if (val) parts.push(val);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Replace lvl0 (typically "Documentation") with the product label
|
|
130
|
-
if (parts.length > 0 && productRoutes.length > 0) {
|
|
131
|
-
try {
|
|
132
|
-
const pathname = new URL(item.url).pathname;
|
|
133
|
-
const product = getProductLabel(pathname, productRoutes);
|
|
134
|
-
if (product) {
|
|
135
|
-
parts[0] = product;
|
|
136
|
-
}
|
|
137
|
-
} catch {
|
|
138
|
-
// URL parsing failed — keep the original lvl0 value
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return parts.length > 1 ? parts.join(' › ') : null;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function DocSearch({
|
|
146
|
-
contextualSearch,
|
|
147
|
-
externalUrlRegex,
|
|
148
|
-
productRoutes = [],
|
|
149
|
-
...props
|
|
150
|
-
}: DocSearchProps) {
|
|
151
|
-
const contextualSearchFacetFilters =
|
|
152
|
-
useTypesenseContextualFilters() as string;
|
|
153
|
-
const configFacetFilters: string =
|
|
154
|
-
props.typesenseSearchParameters?.filter_by ?? '';
|
|
155
|
-
const facetFilters = contextualSearch
|
|
156
|
-
? [contextualSearchFacetFilters, configFacetFilters]
|
|
157
|
-
.filter((e) => e)
|
|
158
|
-
.join(' && ')
|
|
159
|
-
: configFacetFilters;
|
|
160
|
-
|
|
161
|
-
const typesenseSearchParameters = {
|
|
162
|
-
filter_by: facetFilters,
|
|
163
|
-
...props.typesenseSearchParameters,
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const {withBaseUrl} = useBaseUrlUtils();
|
|
167
|
-
const history = useHistory();
|
|
168
|
-
const searchContainer = useRef<HTMLDivElement | null>(null);
|
|
169
|
-
const searchButtonRef = useRef<HTMLButtonElement>(null);
|
|
170
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
171
|
-
const [initialQuery, setInitialQuery] = useState<string | undefined>(
|
|
172
|
-
undefined,
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
const importDocSearchModalIfNeeded = useCallback(() => {
|
|
176
|
-
if (DocSearchModal) {
|
|
177
|
-
return Promise.resolve();
|
|
178
|
-
}
|
|
179
|
-
return Promise.all([
|
|
180
|
-
// @ts-ignore
|
|
181
|
-
import('typesense-docsearch-react/modal') as Promise<
|
|
182
|
-
typeof import('typesense-docsearch-react')
|
|
183
|
-
>,
|
|
184
|
-
// @ts-ignore
|
|
185
|
-
import('typesense-docsearch-react/style'),
|
|
186
|
-
// @ts-ignore
|
|
187
|
-
import('./styles.css'),
|
|
188
|
-
]).then(([{DocSearchModal: Modal}]) => {
|
|
189
|
-
DocSearchModal = Modal;
|
|
190
|
-
});
|
|
191
|
-
}, []);
|
|
192
|
-
|
|
193
|
-
const onOpen = useCallback(() => {
|
|
194
|
-
importDocSearchModalIfNeeded().then(() => {
|
|
195
|
-
searchContainer.current = document.createElement('div');
|
|
196
|
-
document.body.insertBefore(
|
|
197
|
-
searchContainer.current,
|
|
198
|
-
document.body.firstChild,
|
|
199
|
-
);
|
|
200
|
-
setIsOpen(true);
|
|
201
|
-
});
|
|
202
|
-
}, [importDocSearchModalIfNeeded]);
|
|
203
|
-
|
|
204
|
-
const onClose = useCallback(() => {
|
|
205
|
-
setIsOpen(false);
|
|
206
|
-
searchContainer.current?.remove();
|
|
207
|
-
}, []);
|
|
208
|
-
|
|
209
|
-
const onInput = useCallback(
|
|
210
|
-
(event: KeyboardEvent) => {
|
|
211
|
-
importDocSearchModalIfNeeded().then(() => {
|
|
212
|
-
setIsOpen(true);
|
|
213
|
-
setInitialQuery(event.key);
|
|
214
|
-
});
|
|
215
|
-
},
|
|
216
|
-
[importDocSearchModalIfNeeded],
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
const navigator = useRef({
|
|
220
|
-
navigate({itemUrl}: {itemUrl?: string}) {
|
|
221
|
-
if (isRegexpStringMatch(externalUrlRegex, itemUrl)) {
|
|
222
|
-
window.location.href = itemUrl!;
|
|
223
|
-
} else {
|
|
224
|
-
history.push(itemUrl!);
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
}).current;
|
|
228
|
-
|
|
229
|
-
const transformItems = useRef<DocSearchModalProps['transformItems']>(
|
|
230
|
-
(items) =>
|
|
231
|
-
items.map((item) => {
|
|
232
|
-
// Transform absolute URL to relative.
|
|
233
|
-
const withRelativeUrl = isRegexpStringMatch(externalUrlRegex, item.url)
|
|
234
|
-
? item
|
|
235
|
-
: {
|
|
236
|
-
...item,
|
|
237
|
-
url: withBaseUrl(
|
|
238
|
-
`${new URL(item.url).pathname}${new URL(item.url).hash}`,
|
|
239
|
-
),
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
// Overwrite hierarchy.lvl1 with the full ancestor breadcrumb so the
|
|
243
|
-
// DocSearch-Hit-path slot shows the complete path for lvl2+ results.
|
|
244
|
-
const breadcrumb = buildBreadcrumb(withRelativeUrl, productRoutes);
|
|
245
|
-
if (!breadcrumb) return withRelativeUrl;
|
|
246
|
-
|
|
247
|
-
return {
|
|
248
|
-
...withRelativeUrl,
|
|
249
|
-
'hierarchy.lvl1': breadcrumb,
|
|
250
|
-
};
|
|
251
|
-
}),
|
|
252
|
-
).current;
|
|
253
|
-
|
|
254
|
-
const resultsFooterComponent: DocSearchProps['resultsFooterComponent'] =
|
|
255
|
-
useMemo(
|
|
256
|
-
() =>
|
|
257
|
-
// eslint-disable-next-line react/no-unstable-nested-components
|
|
258
|
-
(footerProps: Omit<ResultsFooterProps, 'onClose'>): JSX.Element => (
|
|
259
|
-
<ResultsFooter {...footerProps} onClose={onClose} />
|
|
260
|
-
),
|
|
261
|
-
[onClose],
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
useDocSearchKeyboardEvents({
|
|
265
|
-
isOpen,
|
|
266
|
-
onOpen,
|
|
267
|
-
onClose,
|
|
268
|
-
onInput,
|
|
269
|
-
searchButtonRef,
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
return (
|
|
273
|
-
<>
|
|
274
|
-
<DocSearchButton
|
|
275
|
-
onTouchStart={importDocSearchModalIfNeeded}
|
|
276
|
-
onFocus={importDocSearchModalIfNeeded}
|
|
277
|
-
onMouseOver={importDocSearchModalIfNeeded}
|
|
278
|
-
onClick={onOpen}
|
|
279
|
-
ref={searchButtonRef}
|
|
280
|
-
translations={translations.button}
|
|
281
|
-
/>
|
|
282
|
-
{isOpen &&
|
|
283
|
-
DocSearchModal &&
|
|
284
|
-
searchContainer.current &&
|
|
285
|
-
createPortal(
|
|
286
|
-
<DocSearchModal
|
|
287
|
-
onClose={onClose}
|
|
288
|
-
initialScrollY={window.scrollY}
|
|
289
|
-
initialQuery={initialQuery}
|
|
290
|
-
navigator={navigator}
|
|
291
|
-
transformItems={transformItems}
|
|
292
|
-
hitComponent={Hit}
|
|
293
|
-
{...(props.searchPagePath && {resultsFooterComponent})}
|
|
294
|
-
{...props}
|
|
295
|
-
typesenseSearchParameters={typesenseSearchParameters}
|
|
296
|
-
typesenseServerConfig={props.typesenseServerConfig}
|
|
297
|
-
typesenseCollectionName={props.typesenseCollectionName}
|
|
298
|
-
placeholder={translations.placeholder}
|
|
299
|
-
translations={translations.modal}
|
|
300
|
-
/>,
|
|
301
|
-
searchContainer.current,
|
|
302
|
-
)}
|
|
303
|
-
</>
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
export default function SearchBar(): JSX.Element {
|
|
308
|
-
const {siteConfig} = useDocusaurusContext();
|
|
309
|
-
return (
|
|
310
|
-
<DocsPreferredVersionContextProvider>
|
|
311
|
-
<DocSearch {...(siteConfig.themeConfig.typesense as DocSearchProps)} />
|
|
312
|
-
</DocsPreferredVersionContextProvider>
|
|
313
|
-
);
|
|
314
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
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
|
-
:root {
|
|
9
|
-
--docsearch-primary-color: var(--ifm-color-primary);
|
|
10
|
-
--docsearch-text-color: var(--ifm-font-color-base);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.DocSearch-Button {
|
|
14
|
-
margin: 0;
|
|
15
|
-
transition: all var(--ifm-transition-fast)
|
|
16
|
-
var(--ifm-transition-timing-default);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.DocSearch-Container {
|
|
20
|
-
z-index: calc(var(--ifm-z-index-fixed) + 1);
|
|
21
|
-
}
|