@myst-theme/site 0.17.1 → 1.0.0
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/package.json +8 -8
- package/src/components/Abstract.tsx +5 -4
- package/src/components/Backmatter.tsx +9 -4
- package/src/components/Bibliography.tsx +11 -6
- package/src/components/ContentBlocks.tsx +2 -1
- package/src/components/DocumentOutline.tsx +9 -8
- package/src/components/FooterLinksBlock.tsx +10 -5
- package/src/components/Footnotes.tsx +10 -6
- package/src/components/FrontmatterParts.tsx +13 -5
- package/src/components/Headers.tsx +11 -6
- package/src/components/Keywords.tsx +14 -12
- package/src/components/Navigation/ActionMenu.tsx +4 -3
- package/src/components/Navigation/HomeLink.tsx +2 -2
- package/src/components/Navigation/Loading.tsx +2 -2
- package/src/components/Navigation/Navigation.tsx +1 -1
- package/src/components/Navigation/PrimarySidebar.tsx +29 -16
- package/src/components/Navigation/Search.tsx +16 -14
- package/src/components/Navigation/TableOfContentsItems.tsx +6 -6
- package/src/components/Navigation/ThemeButton.tsx +3 -3
- package/src/components/Navigation/TopNav.tsx +8 -8
- package/src/components/SkipToArticle.tsx +5 -5
- package/src/components/Spinner.tsx +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myst-theme/site",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@headlessui/react": "^1.7.15",
|
|
23
23
|
"@heroicons/react": "^2.0.18",
|
|
24
|
-
"@myst-theme/common": "^0.
|
|
25
|
-
"@myst-theme/diagrams": "^0.
|
|
26
|
-
"@myst-theme/frontmatter": "^0.
|
|
27
|
-
"@myst-theme/providers": "^0.
|
|
28
|
-
"@myst-theme/search": "^0.
|
|
24
|
+
"@myst-theme/common": "^1.0.0",
|
|
25
|
+
"@myst-theme/diagrams": "^1.0.0",
|
|
26
|
+
"@myst-theme/frontmatter": "^1.0.0",
|
|
27
|
+
"@myst-theme/providers": "^1.0.0",
|
|
28
|
+
"@myst-theme/search": "^1.0.0",
|
|
29
29
|
"@radix-ui/react-collapsible": "^1.0.3",
|
|
30
30
|
"@radix-ui/react-dialog": "^1.0.3",
|
|
31
31
|
"@radix-ui/react-visually-hidden": "^1.1.0",
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"lodash.throttle": "^4.1.1",
|
|
34
34
|
"myst-common": "^1.8.1",
|
|
35
35
|
"myst-config": "^1.7.9",
|
|
36
|
-
"myst-demo": "^0.
|
|
36
|
+
"myst-demo": "^1.0.0",
|
|
37
37
|
"myst-spec-ext": "^1.8.1",
|
|
38
|
-
"myst-to-react": "^0.
|
|
38
|
+
"myst-to-react": "^1.0.0",
|
|
39
39
|
"nbtx": "^0.2.3",
|
|
40
40
|
"node-cache": "^5.1.2",
|
|
41
41
|
"node-fetch": "^2.6.11",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { GenericParent } from 'myst-common';
|
|
2
2
|
import { MyST, HashLink } from 'myst-to-react';
|
|
3
|
+
import classNames from 'classnames';
|
|
3
4
|
|
|
4
5
|
export function Abstract({
|
|
5
6
|
content,
|
|
@@ -14,13 +15,13 @@ export function Abstract({
|
|
|
14
15
|
}) {
|
|
15
16
|
if (!content) return null;
|
|
16
17
|
return (
|
|
17
|
-
<div className={className}>
|
|
18
|
-
<h2 id={id} className="mb-3 text-base font-semibold group">
|
|
18
|
+
<div className={classNames('myst-abstract', className)}>
|
|
19
|
+
<h2 id={id} className="myst-abstract-title mb-3 text-base font-semibold group">
|
|
19
20
|
{title}
|
|
20
21
|
<HashLink id={id} title={`Link to ${title}`} hover className="ml-2" />
|
|
21
22
|
</h2>
|
|
22
|
-
<div className="px-6 py-1 mb-3 rounded-sm bg-slate-50 dark:bg-slate-800">
|
|
23
|
-
<MyST ast={content} className="col-body" />
|
|
23
|
+
<div className="myst-abstract-box px-6 py-1 mb-3 rounded-sm bg-slate-50 dark:bg-slate-800">
|
|
24
|
+
<MyST ast={content} className="myst-abstract-content col-body" />
|
|
24
25
|
</div>
|
|
25
26
|
</div>
|
|
26
27
|
);
|
|
@@ -13,7 +13,7 @@ export function BackmatterParts({
|
|
|
13
13
|
innerClassName?: string;
|
|
14
14
|
}) {
|
|
15
15
|
return (
|
|
16
|
-
<div className={containerClassName}>
|
|
16
|
+
<div className={classNames('myst-backmatter-parts', containerClassName)}>
|
|
17
17
|
<Backmatter
|
|
18
18
|
className={innerClassName}
|
|
19
19
|
title="Acknowledgments"
|
|
@@ -43,15 +43,20 @@ export function Backmatter({
|
|
|
43
43
|
}) {
|
|
44
44
|
if (!content) return null;
|
|
45
45
|
return (
|
|
46
|
-
<div
|
|
46
|
+
<div
|
|
47
|
+
className={classNames(
|
|
48
|
+
'myst-backmatter flex flex-col w-full md:flex-row group/backmatter',
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
>
|
|
47
52
|
<h2
|
|
48
53
|
id={id}
|
|
49
|
-
className="mt-5 text-base font-semibold group md:w-[200px] self-start md:flex-none opacity-90 group-hover/backmatter:opacity-100"
|
|
54
|
+
className="myst-backmatter-title mt-5 text-base font-semibold group md:w-[200px] self-start md:flex-none opacity-90 group-hover/backmatter:opacity-100"
|
|
50
55
|
>
|
|
51
56
|
{title}
|
|
52
57
|
<HashLink id={id} title={`Link to ${title}`} hover className="ml-2" />
|
|
53
58
|
</h2>
|
|
54
|
-
<div className="grow opacity-90 group-hover/backmatter:opacity-100 col-screen">
|
|
59
|
+
<div className="myst-backmatter-content grow opacity-90 group-hover/backmatter:opacity-100 col-screen">
|
|
55
60
|
<MyST ast={getChildren(content)} />
|
|
56
61
|
</div>
|
|
57
62
|
</div>
|
|
@@ -22,25 +22,30 @@ export function Bibliography({
|
|
|
22
22
|
return (
|
|
23
23
|
<section
|
|
24
24
|
id="references"
|
|
25
|
-
className={classNames(
|
|
25
|
+
className={classNames(
|
|
26
|
+
'myst-bibliography',
|
|
27
|
+
grid,
|
|
28
|
+
'subgrid-gap col-screen',
|
|
29
|
+
containerClassName,
|
|
30
|
+
)}
|
|
26
31
|
>
|
|
27
32
|
<div className={innerClassName}>
|
|
28
33
|
{!!hideLongBibliography && filtered.length > hideLongBibliography && (
|
|
29
34
|
<button
|
|
30
35
|
onClick={() => setHidden(!hidden)}
|
|
31
|
-
className="float-right p-1 px-2 text-xs border rounded hover:border-blue-500 dark:hover:border-blue-400"
|
|
36
|
+
className="myst-bibliography-toggle float-right p-1 px-2 text-xs border rounded hover:border-blue-500 dark:hover:border-blue-400"
|
|
32
37
|
>
|
|
33
38
|
{hidden ? 'Show All' : 'Collapse'}
|
|
34
39
|
</button>
|
|
35
40
|
)}
|
|
36
|
-
<header className="text-lg font-semibold text-stone-900 dark:text-white group">
|
|
41
|
+
<header className="myst-bibliography-header text-lg font-semibold text-stone-900 dark:text-white group">
|
|
37
42
|
References
|
|
38
43
|
<HashLink id="references" title="Link to References" hover className="ml-2" />
|
|
39
44
|
</header>
|
|
40
45
|
</div>
|
|
41
46
|
<div
|
|
42
47
|
className={classNames(
|
|
43
|
-
'pl-3 mb-8 text-xs text-stone-500 dark:text-stone-300',
|
|
48
|
+
'myst-bibliography-list pl-3 mb-8 text-xs text-stone-500 dark:text-stone-300',
|
|
44
49
|
innerClassName,
|
|
45
50
|
)}
|
|
46
51
|
>
|
|
@@ -50,7 +55,7 @@ export function Bibliography({
|
|
|
50
55
|
return (
|
|
51
56
|
<li
|
|
52
57
|
key={label}
|
|
53
|
-
className="break-words"
|
|
58
|
+
className="myst-bibliography-item break-words"
|
|
54
59
|
id={`cite-${label}`}
|
|
55
60
|
dangerouslySetInnerHTML={{ __html: html || '' }}
|
|
56
61
|
/>
|
|
@@ -60,7 +65,7 @@ export function Bibliography({
|
|
|
60
65
|
<li className="text-center list-none">
|
|
61
66
|
<button
|
|
62
67
|
onClick={() => setHidden(!hidden)}
|
|
63
|
-
className="p-2 border rounded hover:border-blue-500 dark:hover:border-blue-400"
|
|
68
|
+
className="myst-bibliography-toggle p-2 border rounded hover:border-blue-500 dark:hover:border-blue-400"
|
|
64
69
|
>
|
|
65
70
|
{hidden ? `Show all ${filtered.length} references` : 'Collapse references'}
|
|
66
71
|
</button>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SourceFileKind } from 'myst-spec-ext';
|
|
2
2
|
import type { GenericParent } from 'myst-common';
|
|
3
3
|
import { MyST, Block as MystBlock } from 'myst-to-react';
|
|
4
|
+
import classNames from 'classnames';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* @deprecated This component is not maintained, in favor of the generic `MyST` component
|
|
@@ -13,7 +14,7 @@ export function ContentBlocks({
|
|
|
13
14
|
pageKind?: SourceFileKind;
|
|
14
15
|
className?: string;
|
|
15
16
|
}) {
|
|
16
|
-
return <MyST ast={mdast} className={className} />;
|
|
17
|
+
return <MyST ast={mdast} className={classNames('myst-content-blocks', className)} />;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
/** @deprecated use `import { Block } from 'myst-to-react';` */
|
|
@@ -35,15 +35,16 @@ type Props = {
|
|
|
35
35
|
* scrollIntoView is used to ensure that when a user clicks on an item, it will smoothly scroll.
|
|
36
36
|
*/
|
|
37
37
|
const Headings = ({ headings, activeId }: Props) => (
|
|
38
|
-
<ul className="text-sm leading-6 text-slate-400">
|
|
38
|
+
<ul className="myst-outline-list text-sm leading-6 text-slate-400">
|
|
39
39
|
{headings.map((heading) => (
|
|
40
40
|
<li
|
|
41
41
|
key={heading.id}
|
|
42
|
-
className={classNames('border-l-2 hover:border-l-blue-500', {
|
|
42
|
+
className={classNames('myst-outline-item border-l-2 hover:border-l-blue-500', {
|
|
43
43
|
'text-blue-600': heading.id === activeId,
|
|
44
44
|
'border-l-gray-300 dark:border-l-gray-50': heading.id !== activeId,
|
|
45
45
|
'border-l-blue-500': heading.id === activeId,
|
|
46
46
|
'bg-blue-50 dark:bg-slate-800': heading.id === activeId,
|
|
47
|
+
'myst-outline-item-active': heading.id === activeId,
|
|
47
48
|
})}
|
|
48
49
|
>
|
|
49
50
|
<a
|
|
@@ -393,25 +394,25 @@ export const DocumentOutline = ({
|
|
|
393
394
|
}
|
|
394
395
|
|
|
395
396
|
return (
|
|
396
|
-
<Collapsible.Root open={open} onOpenChange={setOpen}>
|
|
397
|
+
<Collapsible.Root open={open} onOpenChange={setOpen} className="myst-outline-section">
|
|
397
398
|
<nav
|
|
398
399
|
ref={outlineRef}
|
|
399
400
|
aria-label="Document Outline"
|
|
400
401
|
className={classNames(
|
|
401
|
-
'not-prose overflow-y-auto',
|
|
402
|
+
'myst-outline not-prose overflow-y-auto',
|
|
402
403
|
'transition-opacity duration-700', // Animation on load
|
|
403
404
|
className,
|
|
404
405
|
)}
|
|
405
406
|
style={{
|
|
406
407
|
top: top,
|
|
407
|
-
maxHeight: `calc(100vh - ${top +
|
|
408
|
+
maxHeight: `calc(100vh - ${top + 100}px)`,
|
|
408
409
|
}}
|
|
409
410
|
>
|
|
410
|
-
<div className="flex flex-row gap-2 mb-4 text-sm leading-6 uppercase rounded-lg text-slate-900 dark:text-slate-100">
|
|
411
|
+
<div className="myst-outline-header flex flex-row gap-2 mb-4 text-sm leading-6 uppercase rounded-lg text-slate-900 dark:text-slate-100">
|
|
411
412
|
{title}
|
|
412
413
|
<Collapsible.Trigger asChild>
|
|
413
414
|
<button
|
|
414
|
-
className="self-center flex-none rounded-md group hover:bg-slate-300/30 focus:outline outline-blue-200 outline-2"
|
|
415
|
+
className="myst-outline-collapsible self-center flex-none rounded-md group hover:bg-slate-300/30 focus:outline outline-blue-200 outline-2"
|
|
415
416
|
aria-label="Open Contents"
|
|
416
417
|
>
|
|
417
418
|
<ChevronRightIcon
|
|
@@ -439,7 +440,7 @@ export function SupportingDocuments() {
|
|
|
439
440
|
if (!pages || pages.length === 0) return null;
|
|
440
441
|
return (
|
|
441
442
|
<>
|
|
442
|
-
<div className="my-4 text-sm leading-6 uppercase text-slate-900 dark:text-slate-100">
|
|
443
|
+
<div className="myst-supporting-documents my-4 text-sm leading-6 uppercase text-slate-900 dark:text-slate-100">
|
|
443
444
|
Supporting Documents
|
|
444
445
|
</div>
|
|
445
446
|
<ul className="flex flex-col gap-2 pl-0 text-sm leading-6 list-none text-slate-700 dark:text-slate-300">
|
|
@@ -15,7 +15,10 @@ export const FooterLink = ({
|
|
|
15
15
|
return (
|
|
16
16
|
<Link
|
|
17
17
|
prefetch="intent"
|
|
18
|
-
className=
|
|
18
|
+
className={classNames(
|
|
19
|
+
'myst-footer-link flex-1 block p-4 font-normal text-gray-600 no-underline border border-gray-200 rounded shadow-sm group hover:border-blue-600 dark:hover:border-blue-400 hover:text-blue-600 dark:hover:text-blue-400 dark:text-gray-100 dark:border-gray-500 hover:shadow-lg dark:shadow-neutral-700',
|
|
20
|
+
{ 'myst-footer-link-prev': right, 'myst-footer-link-next': !right },
|
|
21
|
+
)}
|
|
19
22
|
to={withBaseurl(url, baseurl)}
|
|
20
23
|
>
|
|
21
24
|
<div className="flex h-full align-middle">
|
|
@@ -23,18 +26,20 @@ export const FooterLink = ({
|
|
|
23
26
|
<ArrowLeftIcon
|
|
24
27
|
width="1.5rem"
|
|
25
28
|
height="1.5rem"
|
|
26
|
-
className="self-center transition-transform group-hover:-translate-x-1 shrink-0"
|
|
29
|
+
className="myst-footer-link-icon self-center transition-transform group-hover:-translate-x-1 shrink-0"
|
|
27
30
|
/>
|
|
28
31
|
)}
|
|
29
32
|
<div className={classNames('flex-grow', { 'text-right': right })}>
|
|
30
|
-
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
33
|
+
<div className="myst-footer-link-group text-xs text-gray-500 dark:text-gray-400">
|
|
34
|
+
{group || ' '}
|
|
35
|
+
</div>
|
|
31
36
|
{short_title || title}
|
|
32
37
|
</div>
|
|
33
38
|
{!right && (
|
|
34
39
|
<ArrowRightIcon
|
|
35
40
|
width="1.5rem"
|
|
36
41
|
height="1.5rem"
|
|
37
|
-
className="self-center transition-transform group-hover:translate-x-1 shrink-0"
|
|
42
|
+
className="myst-footer-link-icon self-center transition-transform group-hover:translate-x-1 shrink-0"
|
|
38
43
|
/>
|
|
39
44
|
)}
|
|
40
45
|
</div>
|
|
@@ -45,7 +50,7 @@ export const FooterLink = ({
|
|
|
45
50
|
export function FooterLinksBlock({ links }: { links?: FooterLinks }) {
|
|
46
51
|
if (!links || (!links.navigation?.prev && !links.navigation?.next)) return null;
|
|
47
52
|
return (
|
|
48
|
-
<div className="flex pt-10 mb-10 space-x-4">
|
|
53
|
+
<div className="myst-footer-links flex pt-10 mb-10 space-x-4">
|
|
49
54
|
{links.navigation?.prev && <FooterLink {...links.navigation?.prev} right />}
|
|
50
55
|
{links.navigation?.next && <FooterLink {...links.navigation?.next} />}
|
|
51
56
|
</div>
|
|
@@ -20,29 +20,33 @@ export function Footnotes({
|
|
|
20
20
|
return (
|
|
21
21
|
<section
|
|
22
22
|
id="footnotes"
|
|
23
|
-
className={classNames(grid, 'subgrid-gap col-screen', containerClassName)}
|
|
23
|
+
className={classNames('myst-footnotes', grid, 'subgrid-gap col-screen', containerClassName)}
|
|
24
24
|
>
|
|
25
25
|
<div className={innerClassName}>
|
|
26
|
-
<header className="text-lg font-semibold text-stone-900 dark:text-white group">
|
|
26
|
+
<header className="myst-footnotes-header text-lg font-semibold text-stone-900 dark:text-white group">
|
|
27
27
|
Footnotes
|
|
28
28
|
<HashLink id="footnotes" title="Link to Footnotes" hover className="ml-2" />
|
|
29
29
|
</header>
|
|
30
30
|
</div>
|
|
31
31
|
<div
|
|
32
32
|
className={classNames(
|
|
33
|
-
'pl-3 mb-8 text-xs text-stone-500 dark:text-stone-300',
|
|
33
|
+
'myst-footnotes-list pl-3 mb-8 text-xs text-stone-500 dark:text-stone-300',
|
|
34
34
|
innerClassName,
|
|
35
35
|
)}
|
|
36
36
|
>
|
|
37
37
|
<ol>
|
|
38
38
|
{defs.map((fn) => {
|
|
39
39
|
return (
|
|
40
|
-
<li
|
|
40
|
+
<li
|
|
41
|
+
key={(fn as GenericNode).key}
|
|
42
|
+
id={`fn-${fn.identifier}`}
|
|
43
|
+
className="myst-footnotes-item group"
|
|
44
|
+
>
|
|
41
45
|
<div className="flex flex-row">
|
|
42
|
-
<div className="break-words grow">
|
|
46
|
+
<div className="myst-footnote-content break-words grow">
|
|
43
47
|
<MyST ast={fn.children} />
|
|
44
48
|
</div>
|
|
45
|
-
<div className="flex flex-col grow-0">
|
|
49
|
+
<div className="myst-footnote-backlinks flex flex-col grow-0">
|
|
46
50
|
{refs
|
|
47
51
|
.filter((ref) => ref.identifier === fn.identifier)
|
|
48
52
|
.map((ref) => (
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type KnownParts } from '../utils.js';
|
|
2
2
|
import { Abstract } from './Abstract.js';
|
|
3
3
|
import { Keywords } from './Keywords.js';
|
|
4
|
+
import classNames from 'classnames';
|
|
4
5
|
|
|
5
6
|
export function FrontmatterParts({
|
|
6
7
|
parts,
|
|
@@ -17,21 +18,28 @@ export function FrontmatterParts({
|
|
|
17
18
|
}) {
|
|
18
19
|
if (!parts.abstract && !parts.keypoints && !parts.summary) return null;
|
|
19
20
|
return (
|
|
20
|
-
<div className={containerClassName}>
|
|
21
|
-
<Abstract className={innerClassName} content={parts.abstract} />
|
|
21
|
+
<div className={classNames('myst-fm-parts', containerClassName)}>
|
|
22
22
|
<Abstract
|
|
23
|
-
className={innerClassName}
|
|
23
|
+
className={classNames('myst-fm-section', innerClassName)}
|
|
24
|
+
content={parts.abstract}
|
|
25
|
+
/>
|
|
26
|
+
<Abstract
|
|
27
|
+
className={classNames('myst-fm-section', innerClassName)}
|
|
24
28
|
content={parts.keypoints}
|
|
25
29
|
title="Key Points"
|
|
26
30
|
id="keypoints"
|
|
27
31
|
/>
|
|
28
32
|
<Abstract
|
|
29
|
-
className={innerClassName}
|
|
33
|
+
className={classNames('myst-fm-section', innerClassName)}
|
|
30
34
|
content={parts.summary}
|
|
31
35
|
title="Plain Language Summary"
|
|
32
36
|
id="summary"
|
|
33
37
|
/>
|
|
34
|
-
<Keywords
|
|
38
|
+
<Keywords
|
|
39
|
+
className={classNames('myst-fm-section', innerClassName)}
|
|
40
|
+
keywords={keywords}
|
|
41
|
+
hideKeywords={hideKeywords}
|
|
42
|
+
/>
|
|
35
43
|
</div>
|
|
36
44
|
);
|
|
37
45
|
}
|
|
@@ -15,11 +15,13 @@ export function ArticleHeader({
|
|
|
15
15
|
children,
|
|
16
16
|
toggleTheme,
|
|
17
17
|
className,
|
|
18
|
+
hideAuthors,
|
|
18
19
|
}: {
|
|
19
20
|
frontmatter: PageFrontmatterWithDownloads;
|
|
20
21
|
children?: React.ReactNode;
|
|
21
22
|
toggleTheme?: boolean;
|
|
22
23
|
className?: string;
|
|
24
|
+
hideAuthors?: boolean;
|
|
23
25
|
}) {
|
|
24
26
|
const grid = useGridSystemProvider();
|
|
25
27
|
const { subject, venue, volume, issue, ...rest } = frontmatter ?? {};
|
|
@@ -32,12 +34,12 @@ export function ArticleHeader({
|
|
|
32
34
|
'col-page-left': grid === 'article-grid',
|
|
33
35
|
};
|
|
34
36
|
return (
|
|
35
|
-
<header className="relative col-screen">
|
|
37
|
+
<header className="myst-article-header relative col-screen">
|
|
36
38
|
{frontmatter?.banner && (
|
|
37
39
|
// This is the banner contained in a full-bleed div
|
|
38
40
|
<div
|
|
39
41
|
className={classNames(
|
|
40
|
-
'absolute',
|
|
42
|
+
'myst-article-header-background absolute',
|
|
41
43
|
grid,
|
|
42
44
|
'subgrid-gap col-screen bg-no-repeat bg-cover bg-top w-full h-full -z-10 pointer-events-none',
|
|
43
45
|
)}
|
|
@@ -48,7 +50,7 @@ export function ArticleHeader({
|
|
|
48
50
|
)}
|
|
49
51
|
<div
|
|
50
52
|
className={classNames(
|
|
51
|
-
'w-full relative col-screen article',
|
|
53
|
+
'myst-article-header-content w-full relative col-screen article',
|
|
52
54
|
grid,
|
|
53
55
|
'subgrid-gap',
|
|
54
56
|
{
|
|
@@ -59,7 +61,7 @@ export function ArticleHeader({
|
|
|
59
61
|
)}
|
|
60
62
|
>
|
|
61
63
|
<div
|
|
62
|
-
className={classNames(positionBackground, {
|
|
64
|
+
className={classNames('myst-article-header-banner', positionBackground, {
|
|
63
65
|
'shadow-2xl bg-white/80 dark:bg-black/80 backdrop-blur': frontmatter?.banner,
|
|
64
66
|
})}
|
|
65
67
|
>
|
|
@@ -83,16 +85,19 @@ export function ArticleHeader({
|
|
|
83
85
|
<OpenAccessBadge open_access={frontmatter?.open_access} />
|
|
84
86
|
<GitHubLink github={frontmatter?.github} />
|
|
85
87
|
</div>
|
|
86
|
-
{toggleTheme &&
|
|
88
|
+
{toggleTheme && (
|
|
89
|
+
<ThemeButton className="myst-article-header-theme-button inline-block w-5 h-5 mt-0.5 ml-1" />
|
|
90
|
+
)}
|
|
87
91
|
</div>
|
|
88
92
|
<div className="flex flex-col mb-10 md:flex-row">
|
|
89
93
|
<FrontmatterBlock
|
|
90
94
|
frontmatter={rest}
|
|
91
95
|
authorStyle="list"
|
|
92
|
-
className={classNames('flex-grow', {
|
|
96
|
+
className={classNames('myst-article-header-fm flex-grow', {
|
|
93
97
|
'pt-6 px-6': frontmatter?.banner,
|
|
94
98
|
...positionFrontmatter,
|
|
95
99
|
})}
|
|
100
|
+
hideAuthors={hideAuthors}
|
|
96
101
|
hideBadges
|
|
97
102
|
hideExports
|
|
98
103
|
/>
|
|
@@ -12,18 +12,20 @@ export function Keywords({
|
|
|
12
12
|
}) {
|
|
13
13
|
if (hideKeywords || !keywords || keywords.length === 0) return null;
|
|
14
14
|
return (
|
|
15
|
-
<div className={classNames('mb-10 group', className)}>
|
|
16
|
-
<span className="mr-2 font-semibold">Keywords:</span>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
<div className={classNames('myst-keywords mb-10 group', className)}>
|
|
16
|
+
<span className="myst-keywords-label mr-2 font-semibold">Keywords:</span>
|
|
17
|
+
<span className="myst-keywords-list">
|
|
18
|
+
{keywords.map((k, i) => (
|
|
19
|
+
<span
|
|
20
|
+
key={k}
|
|
21
|
+
className={classNames('myst-keywords-item', {
|
|
22
|
+
"after:content-[','] after:mr-1": i < keywords.length - 1,
|
|
23
|
+
})}
|
|
24
|
+
>
|
|
25
|
+
{k}
|
|
26
|
+
</span>
|
|
27
|
+
))}
|
|
28
|
+
</span>
|
|
27
29
|
<HashLink id="keywords" title="Link to Keywords" hover className="ml-2" />
|
|
28
30
|
</div>
|
|
29
31
|
);
|
|
@@ -7,9 +7,9 @@ import type { SiteManifest } from 'myst-config';
|
|
|
7
7
|
export function ActionMenu({ actions }: { actions?: SiteManifest['actions'] }) {
|
|
8
8
|
if (!actions || actions.length === 0) return null;
|
|
9
9
|
return (
|
|
10
|
-
<Menu as="div" className="relative">
|
|
10
|
+
<Menu as="div" className="myst-action-menu relative">
|
|
11
11
|
<div>
|
|
12
|
-
<Menu.Button className="flex text-sm bg-transparent rounded-full focus:outline-none">
|
|
12
|
+
<Menu.Button className="myst-action-menu-button flex text-sm bg-transparent rounded-full focus:outline-none">
|
|
13
13
|
<span className="sr-only">Open Menu</span>
|
|
14
14
|
<div className="flex items-center text-stone-200 hover:text-white">
|
|
15
15
|
<EllipsisVerticalIcon width="2rem" height="2rem" className="p-1" />
|
|
@@ -25,13 +25,14 @@ export function ActionMenu({ actions }: { actions?: SiteManifest['actions'] }) {
|
|
|
25
25
|
leaveFrom="transform opacity-100 scale-100"
|
|
26
26
|
leaveTo="transform opacity-0 scale-95"
|
|
27
27
|
>
|
|
28
|
-
<Menu.Items className="absolute right-0 w-48 py-1 mt-2 origin-top-right bg-white rounded-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
|
|
28
|
+
<Menu.Items className="myst-action-menu-dropdown absolute right-0 w-48 py-1 mt-2 origin-top-right bg-white rounded-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
|
|
29
29
|
{actions?.map((action) => (
|
|
30
30
|
<Menu.Item key={action.url}>
|
|
31
31
|
{({ active }) => (
|
|
32
32
|
<a
|
|
33
33
|
href={action.url}
|
|
34
34
|
className={classNames(
|
|
35
|
+
'myst-action-menu-item',
|
|
35
36
|
active ? 'bg-gray-100' : '',
|
|
36
37
|
'block px-4 py-2 text-sm text-gray-700',
|
|
37
38
|
)}
|
|
@@ -19,13 +19,13 @@ export function HomeLink({
|
|
|
19
19
|
const nothingSet = !logo && !logoText;
|
|
20
20
|
return (
|
|
21
21
|
<Link
|
|
22
|
-
className="flex items-center ml-3 dark:text-white w-fit md:ml-5 xl:ml-7"
|
|
22
|
+
className="myst-home-link flex items-center ml-3 dark:text-white w-fit md:ml-5 xl:ml-7"
|
|
23
23
|
to={url ? url : withBaseurl('/', baseurl)}
|
|
24
24
|
prefetch="intent"
|
|
25
25
|
>
|
|
26
26
|
{logo && (
|
|
27
27
|
<div
|
|
28
|
-
className={classNames('p-1 mr-3', {
|
|
28
|
+
className={classNames('myst-home-link-logo p-1 mr-3', {
|
|
29
29
|
'dark:bg-white dark:rounded': !logoDark,
|
|
30
30
|
})}
|
|
31
31
|
>
|
|
@@ -48,9 +48,9 @@ export function LoadingBar() {
|
|
|
48
48
|
return (
|
|
49
49
|
<div
|
|
50
50
|
className={classNames(
|
|
51
|
-
'w-screen h-[2px] bg-blue-500 absolute left-0 bottom-0 transition-transform',
|
|
51
|
+
'myst-loading-bar w-screen h-[2px] bg-blue-500 absolute left-0 bottom-0 transition-transform',
|
|
52
52
|
{
|
|
53
|
-
'animate-load scale-x-40': isLoading,
|
|
53
|
+
'myst-loading-bar-progress animate-load scale-x-40': isLoading,
|
|
54
54
|
'scale-x-100': !isLoading,
|
|
55
55
|
},
|
|
56
56
|
)}
|
|
@@ -92,7 +92,7 @@ export const ConfigurablePrimaryNavigation = ({
|
|
|
92
92
|
<>
|
|
93
93
|
{open && !mobileOnly && headings && (
|
|
94
94
|
<div
|
|
95
|
-
className="fixed inset-0 z-30 bg-black opacity-50"
|
|
95
|
+
className="myst-navigation-overlay fixed inset-0 z-30 bg-black opacity-50"
|
|
96
96
|
style={{ marginTop: top }}
|
|
97
97
|
onClick={() => setOpen(false)}
|
|
98
98
|
></div>
|
|
@@ -7,6 +7,9 @@ import {
|
|
|
7
7
|
useGridSystemProvider,
|
|
8
8
|
useThemeTop,
|
|
9
9
|
useIsWide,
|
|
10
|
+
useBaseurl,
|
|
11
|
+
withBaseurl,
|
|
12
|
+
useBannerState,
|
|
10
13
|
} from '@myst-theme/providers';
|
|
11
14
|
import type { Heading } from '@myst-theme/common';
|
|
12
15
|
import { Toc } from './TableOfContentsItems.js';
|
|
@@ -16,12 +19,14 @@ import * as Collapsible from '@radix-ui/react-collapsible';
|
|
|
16
19
|
import { ChevronRightIcon } from '@heroicons/react/24/solid';
|
|
17
20
|
|
|
18
21
|
export function SidebarNavItem({ item }: { item: SiteNavItem }) {
|
|
22
|
+
const baseurl = useBaseurl();
|
|
19
23
|
if (!item.children?.length) {
|
|
20
24
|
return (
|
|
21
25
|
<ExternalOrInternalLink
|
|
22
26
|
nav
|
|
23
|
-
to={item.url ?? ''}
|
|
27
|
+
to={withBaseurl(item.url, baseurl) ?? ''}
|
|
24
28
|
className={classNames(
|
|
29
|
+
'myst-primary-sidebar-item-short',
|
|
25
30
|
'p-2 my-1 rounded-lg',
|
|
26
31
|
'hover:bg-slate-300/30',
|
|
27
32
|
'block break-words focus:outline outline-blue-200 outline-2 rounded',
|
|
@@ -36,38 +41,40 @@ export function SidebarNavItem({ item }: { item: SiteNavItem }) {
|
|
|
36
41
|
<Collapsible.Root className="w-full" open={open} onOpenChange={setOpen}>
|
|
37
42
|
<div
|
|
38
43
|
className={classNames(
|
|
44
|
+
'myst-primary-sidebar-item',
|
|
39
45
|
'flex flex-row w-full gap-2 px-2 my-1 text-left rounded-lg outline-none',
|
|
40
46
|
'hover:bg-slate-300/30',
|
|
41
47
|
)}
|
|
42
48
|
>
|
|
43
49
|
<ExternalOrInternalLink
|
|
44
50
|
nav
|
|
45
|
-
to={item.url ?? ''}
|
|
46
|
-
className={classNames('py-2 grow', {})}
|
|
51
|
+
to={withBaseurl(item.url, baseurl) ?? ''}
|
|
52
|
+
className={classNames('myst-primary-sidebar-item-title py-2 grow', {})}
|
|
47
53
|
onClick={() => setOpen(!open)}
|
|
48
54
|
>
|
|
49
55
|
{item.title}
|
|
50
56
|
</ExternalOrInternalLink>
|
|
51
57
|
<Collapsible.Trigger asChild>
|
|
52
58
|
<button
|
|
53
|
-
className="self-center flex-none rounded-md group hover:bg-slate-300/30 focus:outline outline-blue-200 outline-2"
|
|
59
|
+
className="myst-primary-sidebar-item-child self-center flex-none rounded-md group hover:bg-slate-300/30 focus:outline outline-blue-200 outline-2"
|
|
54
60
|
aria-label="Open Folder"
|
|
55
61
|
>
|
|
56
62
|
<ChevronRightIcon
|
|
57
|
-
className="transition-transform duration-300 group-data-[state=open]:rotate-90 text-text-slate-700 dark:text-slate-100"
|
|
63
|
+
className="myst-primary-sidebar-item-icon transition-transform duration-300 group-data-[state=open]:rotate-90 text-text-slate-700 dark:text-slate-100"
|
|
58
64
|
height="1.5rem"
|
|
59
65
|
width="1.5rem"
|
|
60
66
|
/>
|
|
61
67
|
</button>
|
|
62
68
|
</Collapsible.Trigger>
|
|
63
69
|
</div>
|
|
64
|
-
<Collapsible.Content className="pl-3 pr-[2px] collapsible-content">
|
|
70
|
+
<Collapsible.Content className="myst-primary-sidebar-item-content pl-3 pr-[2px] collapsible-content">
|
|
65
71
|
{item.children.map((action) => (
|
|
66
72
|
<ExternalOrInternalLink
|
|
67
73
|
nav
|
|
68
74
|
key={action.url}
|
|
69
|
-
to={action.url || ''}
|
|
75
|
+
to={withBaseurl(action.url, baseurl) || ''}
|
|
70
76
|
className={classNames(
|
|
77
|
+
'myst-primary-sidebar-item-link',
|
|
71
78
|
'p-2 my-1 rounded-lg',
|
|
72
79
|
'hover:bg-slate-300/30',
|
|
73
80
|
'block break-words focus:outline outline-blue-200 outline-2 rounded',
|
|
@@ -97,15 +104,18 @@ export function useSidebarHeight<T extends HTMLElement = HTMLElement>(top = 0, i
|
|
|
97
104
|
const toc = useRef<HTMLDivElement>(null);
|
|
98
105
|
const transitionState = useNavigation().state;
|
|
99
106
|
const wide = useIsWide();
|
|
107
|
+
const { bannerState } = useBannerState();
|
|
108
|
+
const totalTop = top + bannerState.height;
|
|
109
|
+
|
|
100
110
|
const setHeight = () => {
|
|
101
111
|
if (!container.current || !toc.current) return;
|
|
102
112
|
const height = container.current.offsetHeight - window.scrollY;
|
|
103
113
|
const div = toc.current.firstChild as HTMLDivElement;
|
|
104
114
|
if (div)
|
|
105
115
|
div.style.height = wide
|
|
106
|
-
? `min(calc(100vh - ${
|
|
107
|
-
: `calc(100vh - ${
|
|
108
|
-
if (div) div.style.height = `min(calc(100vh - ${
|
|
116
|
+
? `min(calc(100vh - ${totalTop}px), ${height + inset}px)`
|
|
117
|
+
: `calc(100vh - ${totalTop}px)`;
|
|
118
|
+
if (div) div.style.height = `min(calc(100vh - ${totalTop}px), ${height + inset}px)`;
|
|
109
119
|
const nav = toc.current.querySelector('nav');
|
|
110
120
|
if (nav) nav.style.opacity = height > 150 ? '1' : '0';
|
|
111
121
|
};
|
|
@@ -117,7 +127,7 @@ export function useSidebarHeight<T extends HTMLElement = HTMLElement>(top = 0, i
|
|
|
117
127
|
return () => {
|
|
118
128
|
window.removeEventListener('scroll', handleScroll);
|
|
119
129
|
};
|
|
120
|
-
}, [container, toc, transitionState, wide]);
|
|
130
|
+
}, [container, toc, transitionState, wide, totalTop]);
|
|
121
131
|
return { container, toc };
|
|
122
132
|
}
|
|
123
133
|
|
|
@@ -137,6 +147,7 @@ export const PrimarySidebar = ({
|
|
|
137
147
|
mobileOnly?: boolean;
|
|
138
148
|
}) => {
|
|
139
149
|
const top = useThemeTop();
|
|
150
|
+
const { bannerState } = useBannerState();
|
|
140
151
|
const grid = useGridSystemProvider();
|
|
141
152
|
const footerRef = useRef<HTMLDivElement>(null);
|
|
142
153
|
const [open] = useNavOpen();
|
|
@@ -155,16 +166,18 @@ export const PrimarySidebar = ({
|
|
|
155
166
|
<div
|
|
156
167
|
ref={sidebarRef as any}
|
|
157
168
|
className={classNames(
|
|
169
|
+
'myst-primary-sidebar',
|
|
158
170
|
'fixed',
|
|
159
171
|
`xl:${grid}`, // for example, xl:article-grid
|
|
160
172
|
'grid-gap xl:w-screen xl:pointer-events-none overflow-auto max-xl:min-w-[300px]',
|
|
161
173
|
{ 'lg:hidden': nav && hide_toc },
|
|
162
174
|
{ hidden: !open, 'z-30': open, 'z-10': !open },
|
|
163
175
|
)}
|
|
164
|
-
style={{ top }}
|
|
176
|
+
style={{ top: top + bannerState.height }}
|
|
165
177
|
>
|
|
166
178
|
<div
|
|
167
179
|
className={classNames(
|
|
180
|
+
'myst-primary-sidebar-pointer',
|
|
168
181
|
'pointer-events-auto',
|
|
169
182
|
'xl:col-margin-left flex-col',
|
|
170
183
|
'overflow-hidden',
|
|
@@ -177,11 +190,11 @@ export const PrimarySidebar = ({
|
|
|
177
190
|
},
|
|
178
191
|
)}
|
|
179
192
|
>
|
|
180
|
-
<div className="flex-grow py-6 overflow-y-auto primary-scrollbar">
|
|
193
|
+
<div className="myst-primary-sidebar-nav flex-grow py-6 overflow-y-auto primary-scrollbar">
|
|
181
194
|
{nav && (
|
|
182
195
|
<nav
|
|
183
196
|
aria-label="Navigation"
|
|
184
|
-
className="overflow-y-hidden transition-opacity ml-3 xl:ml-0 mr-3 max-w-[350px] lg:hidden"
|
|
197
|
+
className="myst-primary-sidebar-topnav overflow-y-hidden transition-opacity ml-3 xl:ml-0 mr-3 max-w-[350px] lg:hidden"
|
|
185
198
|
>
|
|
186
199
|
<SidebarNav nav={nav} />
|
|
187
200
|
</nav>
|
|
@@ -190,7 +203,7 @@ export const PrimarySidebar = ({
|
|
|
190
203
|
{headings && (
|
|
191
204
|
<nav
|
|
192
205
|
aria-label="Table of Contents"
|
|
193
|
-
className="flex-grow overflow-y-hidden transition-opacity ml-3 xl:ml-0 mr-3 max-w-[350px]"
|
|
206
|
+
className="myst-primary-sidebar-toc flex-grow overflow-y-hidden transition-opacity ml-3 xl:ml-0 mr-3 max-w-[350px]"
|
|
194
207
|
>
|
|
195
208
|
<Toc headings={headings} />
|
|
196
209
|
</nav>
|
|
@@ -198,7 +211,7 @@ export const PrimarySidebar = ({
|
|
|
198
211
|
</div>
|
|
199
212
|
{footer && (
|
|
200
213
|
<div
|
|
201
|
-
className="flex-none py-6 transition-all duration-700 translate-y-6 opacity-0"
|
|
214
|
+
className="myst-primary-sidebar-footer flex-none py-6 transition-all duration-700 translate-y-6 opacity-0"
|
|
202
215
|
ref={footerRef}
|
|
203
216
|
>
|
|
204
217
|
{footer}
|
|
@@ -174,7 +174,7 @@ function SearchShortcut() {
|
|
|
174
174
|
return (
|
|
175
175
|
<div
|
|
176
176
|
aria-hidden
|
|
177
|
-
className="items-center hidden mx-1 font-mono text-sm text-gray-
|
|
177
|
+
className="myst-search-shortcut items-center hidden mx-1 font-mono text-sm text-gray-600 sm:flex gap-x-1"
|
|
178
178
|
>
|
|
179
179
|
<kbd
|
|
180
180
|
className={classNames(
|
|
@@ -224,7 +224,7 @@ function SearchResultItem({
|
|
|
224
224
|
|
|
225
225
|
// Render the icon
|
|
226
226
|
const iconProps = useMemo(() => {
|
|
227
|
-
return { className: 'inline-block w-6 mx-2 shrink-0' };
|
|
227
|
+
return { className: 'myst-search-result-icon inline-block w-6 mx-2 shrink-0' };
|
|
228
228
|
}, []);
|
|
229
229
|
const iconRenderer = createElement(
|
|
230
230
|
type === 'lvl1' ? DocumentIcon : type === 'content' ? Bars3BottomLeftIcon : HashtagIcon,
|
|
@@ -241,7 +241,7 @@ function SearchResultItem({
|
|
|
241
241
|
text={title}
|
|
242
242
|
matches={matches}
|
|
243
243
|
limit={type === 'content' ? charLimit : undefined}
|
|
244
|
-
className="text-sm"
|
|
244
|
+
className="myst-search-result-highlight text-sm"
|
|
245
245
|
/>
|
|
246
246
|
);
|
|
247
247
|
|
|
@@ -338,7 +338,7 @@ function SearchResults({
|
|
|
338
338
|
[onHoverSelect],
|
|
339
339
|
);
|
|
340
340
|
return (
|
|
341
|
-
<div className="mt-4 overflow-y-scroll">
|
|
341
|
+
<div className="myst-search-results mt-4 overflow-y-scroll">
|
|
342
342
|
{searchResults.length ? (
|
|
343
343
|
<ul
|
|
344
344
|
// Accessiblity:
|
|
@@ -363,7 +363,7 @@ function SearchResults({
|
|
|
363
363
|
// Indicate whether this is selected
|
|
364
364
|
aria-selected={selectedIndex === index}
|
|
365
365
|
// Allow for nested-highlighting
|
|
366
|
-
className="group"
|
|
366
|
+
className="myst-search-result-item group"
|
|
367
367
|
// Trigger selection on movement, so that scrolling doesn't trigger handler
|
|
368
368
|
onMouseMove={handleMouseMove}
|
|
369
369
|
>
|
|
@@ -372,7 +372,7 @@ function SearchResults({
|
|
|
372
372
|
))}
|
|
373
373
|
</ul>
|
|
374
374
|
) : (
|
|
375
|
-
<span>No results found.</span>
|
|
375
|
+
<span className="myst-search-no-results">No results found.</span>
|
|
376
376
|
)}
|
|
377
377
|
</div>
|
|
378
378
|
);
|
|
@@ -506,8 +506,9 @@ function SearchForm({
|
|
|
506
506
|
<>
|
|
507
507
|
<form onSubmit={onSubmit}>
|
|
508
508
|
<div className="relative flex w-full h-10 flow-row gap-x-1 ">
|
|
509
|
-
<label id={
|
|
510
|
-
<MagnifyingGlassIcon className="absolute text-gray-
|
|
509
|
+
<label id={searchLabelID} htmlFor={searchInputID}>
|
|
510
|
+
<MagnifyingGlassIcon className="absolute text-gray-600 inset-y-0 start-0 h-10 w-10 p-2.5 aspect-square flex items-center pointer-events-none" />
|
|
511
|
+
<span className="hidden">Search query</span>
|
|
511
512
|
</label>
|
|
512
513
|
<input
|
|
513
514
|
autoComplete="off"
|
|
@@ -515,7 +516,7 @@ function SearchForm({
|
|
|
515
516
|
disabled={!enabled}
|
|
516
517
|
autoCapitalize="false"
|
|
517
518
|
className={classNames(
|
|
518
|
-
'block flex-grow p-2 ps-10 placeholder-gray-400',
|
|
519
|
+
'myst-search-input block flex-grow p-2 ps-10 placeholder-gray-400',
|
|
519
520
|
'border border-gray-300 dark:border-gray-600',
|
|
520
521
|
'rounded-lg bg-gray-50 dark:bg-gray-700',
|
|
521
522
|
'focus:ring-blue-500 dark:focus:ring-blue-500',
|
|
@@ -540,7 +541,7 @@ function SearchForm({
|
|
|
540
541
|
</div>
|
|
541
542
|
</form>
|
|
542
543
|
{!enabled && (
|
|
543
|
-
<div className="mx-2 mt-4 text-sm text-gray-500">
|
|
544
|
+
<div className="myst-search-no-results mx-2 mt-4 text-sm text-gray-500">
|
|
544
545
|
Search is not enabled for this site. :(
|
|
545
546
|
</div>
|
|
546
547
|
)}
|
|
@@ -560,12 +561,13 @@ const SearchPlaceholderButton = forwardRef<
|
|
|
560
561
|
<button
|
|
561
562
|
{...props}
|
|
562
563
|
className={classNames(
|
|
564
|
+
'myst-search-bar',
|
|
563
565
|
className,
|
|
564
|
-
'flex items-center h-10 aspect-square sm:w-64 text-left text-gray-
|
|
566
|
+
'flex items-center h-10 aspect-square sm:w-64 text-left text-gray-600',
|
|
565
567
|
'border border-gray-300 dark:border-gray-600',
|
|
566
568
|
'rounded-lg bg-gray-50 dark:bg-gray-700',
|
|
567
569
|
{
|
|
568
|
-
'hover:ring-blue-500': !disabled,
|
|
570
|
+
'myst-search-bar-disabled hover:ring-blue-500': !disabled,
|
|
569
571
|
'dark:hover:ring-blue-500': !disabled,
|
|
570
572
|
'hover:border-blue-500': !disabled,
|
|
571
573
|
'dark:hover:border-blue-500': !disabled,
|
|
@@ -575,7 +577,7 @@ const SearchPlaceholderButton = forwardRef<
|
|
|
575
577
|
ref={ref}
|
|
576
578
|
>
|
|
577
579
|
<MagnifyingGlassIcon className="p-2.5 h-10 w-10 aspect-square" />
|
|
578
|
-
<span className="hidden sm:block grow">Search</span>
|
|
580
|
+
<span className="myst-search-text-placeholder hidden sm:block grow">Search</span>
|
|
579
581
|
<SearchShortcut />
|
|
580
582
|
</button>
|
|
581
583
|
);
|
|
@@ -630,7 +632,7 @@ export function Search({ debounceTime = 500, charLimit = 64 }: SearchProps) {
|
|
|
630
632
|
<Dialog.Portal>
|
|
631
633
|
<Dialog.Overlay className="fixed inset-0 bg-[#656c85cc] z-[1000]" />
|
|
632
634
|
<Dialog.Content
|
|
633
|
-
className="fixed flex flex-col top-0 bg-white dark:bg-stone-900 z-[1001] h-screen w-screen sm:left-1/2 sm:-translate-x-1/2 sm:w-[90vw] sm:max-w-screen-sm sm:h-auto sm:max-h-[var(--content-max-height)] sm:top-[var(--content-top)] sm:rounded-md p-4 text-gray-900 dark:text-white"
|
|
635
|
+
className="myst-search-dialog fixed flex flex-col top-0 bg-white dark:bg-stone-900 z-[1001] h-screen w-screen sm:left-1/2 sm:-translate-x-1/2 sm:w-[90vw] sm:max-w-screen-sm sm:h-auto sm:max-h-[var(--content-max-height)] sm:top-[var(--content-top)] sm:rounded-md p-4 text-gray-900 dark:text-white"
|
|
634
636
|
// Store state as CSS variables so that we can set the style with tailwind variants
|
|
635
637
|
style={
|
|
636
638
|
{
|
|
@@ -65,7 +65,7 @@ function childrenOpen(headings: NestedHeading[], pathname: string, baseurl?: str
|
|
|
65
65
|
export const Toc = ({ headings }: { headings: Heading[] }) => {
|
|
66
66
|
const nested = nestToc(headings);
|
|
67
67
|
return (
|
|
68
|
-
<div className="w-full px-1 dark:text-white">
|
|
68
|
+
<div className="myst-toc w-full px-1 dark:text-white">
|
|
69
69
|
{nested.map((item) => (
|
|
70
70
|
<NestedToc heading={item} key={item.id} />
|
|
71
71
|
))}
|
|
@@ -93,7 +93,7 @@ function LinkItem({
|
|
|
93
93
|
<Link
|
|
94
94
|
title={`${heading.enumerator ? `${heading.enumerator} ` : ''}${heading.title}`}
|
|
95
95
|
className={classNames(
|
|
96
|
-
'block break-words focus:outline outline-blue-200 outline-2 rounded',
|
|
96
|
+
'myst-toc-heading block break-words focus:outline outline-blue-200 outline-2 rounded',
|
|
97
97
|
className,
|
|
98
98
|
)}
|
|
99
99
|
to={heading.url}
|
|
@@ -159,8 +159,8 @@ const NestedToc = ({ heading }: { heading: NestedHeading }) => {
|
|
|
159
159
|
if (!heading.children || heading.children.length === 0) {
|
|
160
160
|
return (
|
|
161
161
|
<LinkItem
|
|
162
|
-
className={classNames('p-2 my-1 rounded-lg', {
|
|
163
|
-
'bg-blue-300/30': exact,
|
|
162
|
+
className={classNames('myst-toc-item p-2 my-1 rounded-lg', {
|
|
163
|
+
'myst-toc-item-exact bg-blue-300/30': exact,
|
|
164
164
|
'hover:bg-slate-300/30': !exact,
|
|
165
165
|
'font-bold': heading.level === 'index',
|
|
166
166
|
})}
|
|
@@ -172,9 +172,9 @@ const NestedToc = ({ heading }: { heading: NestedHeading }) => {
|
|
|
172
172
|
<Collapsible.Root className="w-full" open={open} onOpenChange={setOpen}>
|
|
173
173
|
<div
|
|
174
174
|
className={classNames(
|
|
175
|
-
'flex flex-row w-full gap-2 px-2 my-1 text-left rounded-lg outline-none',
|
|
175
|
+
'myst-toc-item flex flex-row w-full gap-2 px-2 my-1 text-left rounded-lg outline-none',
|
|
176
176
|
{
|
|
177
|
-
'bg-blue-300/30': exact,
|
|
177
|
+
'myst-toc-item-exact bg-blue-300/30': exact,
|
|
178
178
|
'hover:bg-slate-300/30': !exact,
|
|
179
179
|
},
|
|
180
180
|
)}
|
|
@@ -8,15 +8,15 @@ export function ThemeButton({ className = 'w-8 h-8 mx-3' }: { className?: string
|
|
|
8
8
|
return (
|
|
9
9
|
<button
|
|
10
10
|
className={classNames(
|
|
11
|
-
'theme rounded-full aspect-square border border-stone-700 dark:border-white hover:bg-neutral-100 border-solid overflow-hidden text-stone-700 dark:text-white hover:text-stone-500 dark:hover:text-neutral-800',
|
|
11
|
+
'myst-theme-button theme rounded-full aspect-square border border-stone-700 dark:border-white hover:bg-neutral-100 border-solid overflow-hidden text-stone-700 dark:text-white hover:text-stone-500 dark:hover:text-neutral-800',
|
|
12
12
|
className,
|
|
13
13
|
)}
|
|
14
14
|
title={`Toggle theme between light and dark mode`}
|
|
15
15
|
aria-label={`Toggle theme between light and dark mode`}
|
|
16
16
|
onClick={nextTheme}
|
|
17
17
|
>
|
|
18
|
-
<MoonIcon className="h-full w-full p-0.5 hidden dark:block" />
|
|
19
|
-
<SunIcon className="h-full w-full p-0.5 dark:hidden" />
|
|
18
|
+
<MoonIcon className="myst-theme-moon-icon h-full w-full p-0.5 hidden dark:block" />
|
|
19
|
+
<SunIcon className="myst-theme-sun-icon h-full w-full p-0.5 dark:hidden" />
|
|
20
20
|
</button>
|
|
21
21
|
);
|
|
22
22
|
}
|
|
@@ -24,7 +24,7 @@ export function NavItem({ item }: { item: SiteNavItem }) {
|
|
|
24
24
|
const baseurl = useBaseurl();
|
|
25
25
|
if (!('children' in item)) {
|
|
26
26
|
return (
|
|
27
|
-
<div className="relative inline-block mx-2 grow-0">
|
|
27
|
+
<div className="myst-top-nav-item relative inline-block mx-2 grow-0">
|
|
28
28
|
<ExternalOrInternalLink
|
|
29
29
|
nav
|
|
30
30
|
to={withBaseurl(item.url, baseurl) ?? ''}
|
|
@@ -43,7 +43,7 @@ export function NavItem({ item }: { item: SiteNavItem }) {
|
|
|
43
43
|
);
|
|
44
44
|
}
|
|
45
45
|
return (
|
|
46
|
-
<Menu as="div" className="relative inline-block mx-2 grow-0">
|
|
46
|
+
<Menu as="div" className="myst-top-nav-dropdown relative inline-block mx-2 grow-0">
|
|
47
47
|
<div className="inline-block">
|
|
48
48
|
<Menu.Button className="inline-flex items-center justify-center w-full py-1 mx-2 font-medium rounded-md text-md text-stone-900 dark:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
|
|
49
49
|
<span>{item.title}</span>
|
|
@@ -63,14 +63,14 @@ export function NavItem({ item }: { item: SiteNavItem }) {
|
|
|
63
63
|
leaveFrom="transform opacity-100 scale-100"
|
|
64
64
|
leaveTo="transform opacity-0 scale-95"
|
|
65
65
|
>
|
|
66
|
-
<Menu.Items className="absolute w-48 py-1 mt-2 origin-top-left bg-white rounded-sm shadow-lg left-4 ring-1 ring-black ring-opacity-5 focus:outline-none">
|
|
66
|
+
<Menu.Items className="myst-top-nav-dropdown-items absolute w-48 py-1 mt-2 origin-top-left bg-white rounded-sm shadow-lg left-4 ring-1 ring-black ring-opacity-5 focus:outline-none">
|
|
67
67
|
{item.children?.map((action) => (
|
|
68
68
|
<Menu.Item key={action.url}>
|
|
69
69
|
{/* This is really ugly, BUT, the action needs to be defined HERE or the click away doesn't work for some reason */}
|
|
70
70
|
{action.url?.startsWith('http') ? (
|
|
71
71
|
<a
|
|
72
72
|
href={action.url || ''}
|
|
73
|
-
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-black"
|
|
73
|
+
className="myst-top-nav-dropdown-item block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-black"
|
|
74
74
|
target="_blank"
|
|
75
75
|
rel="noopener noreferrer"
|
|
76
76
|
>
|
|
@@ -81,7 +81,7 @@ export function NavItem({ item }: { item: SiteNavItem }) {
|
|
|
81
81
|
to={action.url || ''}
|
|
82
82
|
className={({ isActive }) =>
|
|
83
83
|
classNames(
|
|
84
|
-
' block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-black
|
|
84
|
+
'myst-top-nav-dropdown-item block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-black',
|
|
85
85
|
{
|
|
86
86
|
'text-black font-bold': isActive,
|
|
87
87
|
},
|
|
@@ -116,8 +116,8 @@ export function TopNav({ hideToc, hideSearch }: { hideToc?: boolean; hideSearch?
|
|
|
116
116
|
const { title, nav, actions } = config ?? {};
|
|
117
117
|
const { logo, logo_dark, logo_text, logo_url } = config?.options ?? {};
|
|
118
118
|
return (
|
|
119
|
-
<div className="bg-white/80 backdrop-blur dark:bg-stone-900/80 shadow dark:shadow-stone-700 p-3 md:px-8 sticky w-screen top-0 z-30 h-[60px]">
|
|
120
|
-
<nav className="flex items-center justify-between flex-nowrap max-w-[1440px] mx-auto">
|
|
119
|
+
<div className="myst-top-nav bg-white/80 backdrop-blur dark:bg-stone-900/80 shadow dark:shadow-stone-700 p-3 md:px-8 sticky w-screen top-0 z-30 h-[60px]">
|
|
120
|
+
<nav className="myst-top-nav-bar flex items-center justify-between flex-nowrap max-w-[1440px] mx-auto">
|
|
121
121
|
<div className="flex flex-row xl:min-w-[19.5rem] mr-2 sm:mr-7 justify-start items-center shrink-0">
|
|
122
122
|
{
|
|
123
123
|
<div
|
|
@@ -127,7 +127,7 @@ export function TopNav({ hideToc, hideSearch }: { hideToc?: boolean; hideSearch?
|
|
|
127
127
|
})}
|
|
128
128
|
>
|
|
129
129
|
<button
|
|
130
|
-
className="flex items-center border-stone-400 text-stone-800 hover:text-stone-900 dark:text-stone-200 hover:dark:text-stone-100"
|
|
130
|
+
className="myst-top-nav-menu-button flex items-center border-stone-400 text-stone-800 hover:text-stone-900 dark:text-stone-200 hover:dark:text-stone-100"
|
|
131
131
|
onClick={() => {
|
|
132
132
|
setOpen(!open);
|
|
133
133
|
}}
|
|
@@ -31,13 +31,13 @@ export function SkipToArticle({
|
|
|
31
31
|
const articleHandler = useCallback(() => makeSkipClickHandler(art), [article]);
|
|
32
32
|
return (
|
|
33
33
|
<div
|
|
34
|
-
className="fixed top-1 left-1 h-[0px] w-[0px] focus-within:z-40 focus-within:h-auto focus-within:w-auto bg-white overflow-hidden focus-within:p-2 focus-within:ring-1"
|
|
34
|
+
className="myst-skip-to-article fixed top-1 left-1 h-[0px] w-[0px] focus-within:z-40 focus-within:h-auto focus-within:w-auto bg-white overflow-hidden focus-within:p-2 focus-within:ring-1"
|
|
35
35
|
aria-label="skip to content options"
|
|
36
36
|
>
|
|
37
37
|
{frontmatter && (
|
|
38
38
|
<a
|
|
39
39
|
href={`#${fm}`}
|
|
40
|
-
className="block px-2 py-1 text-black underline"
|
|
40
|
+
className="myst-skip-to-link block px-2 py-1 text-black underline"
|
|
41
41
|
onClick={frontmatterHandler}
|
|
42
42
|
>
|
|
43
43
|
Skip to article frontmatter
|
|
@@ -46,7 +46,7 @@ export function SkipToArticle({
|
|
|
46
46
|
{article && (
|
|
47
47
|
<a
|
|
48
48
|
href={`#${art}`}
|
|
49
|
-
className="block px-2 py-1 text-black underline"
|
|
49
|
+
className="myst-skip-to-link block px-2 py-1 text-black underline"
|
|
50
50
|
onClick={articleHandler}
|
|
51
51
|
>
|
|
52
52
|
Skip to article content
|
|
@@ -62,14 +62,14 @@ export function SkipToArticle({
|
|
|
62
62
|
export const SkipTo = React.memo(({ targets }: { targets: { id: string; title: string }[] }) => {
|
|
63
63
|
return (
|
|
64
64
|
<div
|
|
65
|
-
className="fixed top-1 left-1 h-[0px] w-[0px] focus-within:z-40 focus-within:h-auto focus-within:w-auto bg-white overflow-hidden focus-within:p-2 focus-within:ring-1"
|
|
65
|
+
className="myst-skip-to-article fixed top-1 left-1 h-[0px] w-[0px] focus-within:z-40 focus-within:h-auto focus-within:w-auto bg-white overflow-hidden focus-within:p-2 focus-within:ring-1"
|
|
66
66
|
aria-label="skip to content options"
|
|
67
67
|
>
|
|
68
68
|
{targets.map(({ id, title }) => (
|
|
69
69
|
<a
|
|
70
70
|
key={id}
|
|
71
71
|
href={`#${id}`}
|
|
72
|
-
className="block px-2 py-1 text-black underline"
|
|
72
|
+
className="myst-skip-to-link block px-2 py-1 text-black underline"
|
|
73
73
|
onClick={makeSkipClickHandler(id)}
|
|
74
74
|
>
|
|
75
75
|
{title}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export function Spinner({ size }: { size: number }) {
|
|
2
2
|
return (
|
|
3
|
-
<div role="status">
|
|
3
|
+
<div role="status" className="myst-spinner">
|
|
4
4
|
<svg
|
|
5
5
|
aria-hidden="true"
|
|
6
|
-
className={`w-[${size}px] h-[${size}px] mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-green-600`}
|
|
6
|
+
className={`myst-spinner-icon w-[${size}px] h-[${size}px] mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-green-600`}
|
|
7
7
|
viewBox="0 0 100 101"
|
|
8
8
|
fill="none"
|
|
9
9
|
xmlns="http://www.w3.org/2000/svg"
|