@myst-theme/site 0.5.1 → 0.5.3
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 +9 -9
- package/src/components/Abstract.tsx +40 -0
- package/src/components/DocumentOutline.tsx +6 -2
- package/src/components/FooterLinksBlock.tsx +10 -2
- package/src/components/Headers.tsx +65 -42
- package/src/components/Navigation/TableOfContents.tsx +27 -4
- package/src/components/Navigation/TopNav.tsx +9 -5
- package/src/components/Navigation/index.tsx +1 -1
- package/src/components/index.ts +1 -0
- package/src/pages/Article.tsx +3 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myst-theme/site",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"main": "./src/index.ts",
|
|
5
5
|
"types": "./src/index.ts",
|
|
6
6
|
"files": [
|
|
@@ -16,22 +16,22 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@headlessui/react": "^1.7.15",
|
|
18
18
|
"@heroicons/react": "^2.0.18",
|
|
19
|
-
"@myst-theme/diagrams": "^0.5.
|
|
20
|
-
"@myst-theme/frontmatter": "^0.5.
|
|
21
|
-
"@myst-theme/jupyter": "^0.5.
|
|
22
|
-
"@myst-theme/common": "^0.5.
|
|
23
|
-
"@myst-theme/providers": "^0.5.
|
|
19
|
+
"@myst-theme/diagrams": "^0.5.3",
|
|
20
|
+
"@myst-theme/frontmatter": "^0.5.3",
|
|
21
|
+
"@myst-theme/jupyter": "^0.5.3",
|
|
22
|
+
"@myst-theme/common": "^0.5.3",
|
|
23
|
+
"@myst-theme/providers": "^0.5.3",
|
|
24
24
|
"classnames": "^2.3.2",
|
|
25
25
|
"lodash.throttle": "^4.1.1",
|
|
26
26
|
"myst-common": "^1.1.1",
|
|
27
27
|
"myst-spec-ext": "^1.1.1",
|
|
28
28
|
"myst-config": "^1.1.1",
|
|
29
|
-
"myst-demo": "^0.5.
|
|
30
|
-
"myst-to-react": "^0.5.
|
|
29
|
+
"myst-demo": "^0.5.3",
|
|
30
|
+
"myst-to-react": "^0.5.3",
|
|
31
31
|
"nbtx": "^0.2.3",
|
|
32
32
|
"node-cache": "^5.1.2",
|
|
33
33
|
"node-fetch": "^2.6.11",
|
|
34
|
-
"thebe-react": "^0.3.
|
|
34
|
+
"thebe-react": "^0.3.2",
|
|
35
35
|
"unist-util-select": "^4.0.1"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { GenericParent } from 'myst-common';
|
|
2
|
+
import { ContentBlocks } from './ContentBlocks';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
|
|
5
|
+
export function Abstract({ content }: { content: GenericParent }) {
|
|
6
|
+
if (!content) return null;
|
|
7
|
+
return (
|
|
8
|
+
<>
|
|
9
|
+
<span className="mb-3 font-semibold">Abstract</span>
|
|
10
|
+
<div className="px-6 py-1 mb-3 rounded-sm bg-slate-50 dark:bg-slate-800">
|
|
11
|
+
<ContentBlocks mdast={content} className="col-body" />
|
|
12
|
+
</div>
|
|
13
|
+
</>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function Keywords({
|
|
18
|
+
keywords,
|
|
19
|
+
hideKeywords,
|
|
20
|
+
}: {
|
|
21
|
+
keywords?: string[];
|
|
22
|
+
hideKeywords?: boolean;
|
|
23
|
+
}) {
|
|
24
|
+
if (hideKeywords || !keywords || keywords.length === 0) return null;
|
|
25
|
+
return (
|
|
26
|
+
<div className="mb-10">
|
|
27
|
+
<span className="mr-2 font-semibold">Keywords:</span>
|
|
28
|
+
{keywords.map((k, i) => (
|
|
29
|
+
<span
|
|
30
|
+
key={k}
|
|
31
|
+
className={classNames({
|
|
32
|
+
"after:content-[','] after:mr-1": i < keywords.length - 1,
|
|
33
|
+
})}
|
|
34
|
+
>
|
|
35
|
+
{k}
|
|
36
|
+
</span>
|
|
37
|
+
))}
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -280,12 +280,16 @@ export function SupportingDocuments() {
|
|
|
280
280
|
to={withBaseurl(`/${p.slug}#main`, baseurl)}
|
|
281
281
|
prefetch="intent"
|
|
282
282
|
className={({ isActive }) =>
|
|
283
|
-
classNames('no-underline flex self-center', {
|
|
283
|
+
classNames('no-underline flex self-center hover:text-blue-700', {
|
|
284
284
|
'text-blue-600': isActive,
|
|
285
285
|
})
|
|
286
286
|
}
|
|
287
287
|
>
|
|
288
|
-
<DocumentChartBarIcon
|
|
288
|
+
<DocumentChartBarIcon
|
|
289
|
+
width="1.25rem"
|
|
290
|
+
height="1.25rem"
|
|
291
|
+
className="inline mr-2 shrink-0"
|
|
292
|
+
/>
|
|
289
293
|
<span>{p.short_title || p.title}</span>
|
|
290
294
|
</NavLink>
|
|
291
295
|
</li>
|
|
@@ -21,14 +21,22 @@ const FooterLink = ({
|
|
|
21
21
|
>
|
|
22
22
|
<div className="flex h-full align-middle">
|
|
23
23
|
{right && (
|
|
24
|
-
<ArrowLeftIcon
|
|
24
|
+
<ArrowLeftIcon
|
|
25
|
+
width="1.5rem"
|
|
26
|
+
height="1.5rem"
|
|
27
|
+
className="self-center transition-transform group-hover:-translate-x-1 shrink-0"
|
|
28
|
+
/>
|
|
25
29
|
)}
|
|
26
30
|
<div className={classNames('flex-grow', { 'text-right': right })}>
|
|
27
31
|
<div className="text-xs text-gray-500 dark:text-gray-400">{group || ' '}</div>
|
|
28
32
|
{short_title || title}
|
|
29
33
|
</div>
|
|
30
34
|
{!right && (
|
|
31
|
-
<ArrowRightIcon
|
|
35
|
+
<ArrowRightIcon
|
|
36
|
+
width="1.5rem"
|
|
37
|
+
height="1.5rem"
|
|
38
|
+
className="self-center transition-transform group-hover:translate-x-1 shrink-0"
|
|
39
|
+
/>
|
|
32
40
|
)}
|
|
33
41
|
</div>
|
|
34
42
|
</Link>
|
|
@@ -8,67 +8,90 @@ import {
|
|
|
8
8
|
import { useGridSystemProvider } from '@myst-theme/providers';
|
|
9
9
|
import classNames from 'classnames';
|
|
10
10
|
import type { PageFrontmatter } from 'myst-frontmatter';
|
|
11
|
+
import { ThemeButton } from './Navigation';
|
|
11
12
|
|
|
12
13
|
export function ArticleHeader({
|
|
13
14
|
frontmatter,
|
|
14
15
|
children,
|
|
16
|
+
toggleTheme,
|
|
15
17
|
className,
|
|
16
18
|
}: {
|
|
17
19
|
frontmatter: PageFrontmatter;
|
|
18
20
|
children?: React.ReactNode;
|
|
21
|
+
toggleTheme?: boolean;
|
|
19
22
|
className?: string;
|
|
20
23
|
}) {
|
|
21
24
|
const grid = useGridSystemProvider();
|
|
22
25
|
const { subject, venue, biblio, ...rest } = frontmatter ?? {};
|
|
23
26
|
return (
|
|
24
|
-
<header
|
|
25
|
-
className={classNames(
|
|
26
|
-
'w-full relative pt-[2rem] col-screen article',
|
|
27
|
-
grid,
|
|
28
|
-
'subgrid-gap',
|
|
29
|
-
{
|
|
30
|
-
'bg-no-repeat bg-cover bg-top': frontmatter?.banner,
|
|
31
|
-
'pb-[4rem]': frontmatter?.banner,
|
|
32
|
-
},
|
|
33
|
-
className,
|
|
34
|
-
)}
|
|
35
|
-
style={{
|
|
36
|
-
backgroundImage: frontmatter?.banner ? `url(${frontmatter?.banner})` : undefined,
|
|
37
|
-
}}
|
|
38
|
-
>
|
|
27
|
+
<header className="relative col-screen">
|
|
39
28
|
{frontmatter?.banner && (
|
|
40
|
-
|
|
29
|
+
// This is the banner contained in a full-bleed div
|
|
30
|
+
<div
|
|
31
|
+
className={classNames(
|
|
32
|
+
'absolute',
|
|
33
|
+
grid,
|
|
34
|
+
'subgrid-gap col-screen bg-no-repeat bg-cover bg-top w-full h-full -z-10 pointer-events-none',
|
|
35
|
+
)}
|
|
36
|
+
style={{
|
|
37
|
+
backgroundImage: `url(${frontmatter?.banner})`,
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<div
|
|
41
|
+
className={classNames(
|
|
42
|
+
'absolute border-white shadow-2xl bg-white/80 dark:bg-black/80 backdrop-blur col-page-right',
|
|
43
|
+
'w-full',
|
|
44
|
+
'top-[2rem] h-[calc(100%-4rem)] md:top-[4rem] md:h-[calc(100%-8rem)]',
|
|
45
|
+
)}
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
41
48
|
)}
|
|
42
49
|
<div
|
|
43
|
-
className={classNames(
|
|
44
|
-
'
|
|
45
|
-
|
|
46
|
-
'
|
|
47
|
-
|
|
50
|
+
className={classNames(
|
|
51
|
+
'w-full relative col-screen article',
|
|
52
|
+
grid,
|
|
53
|
+
'subgrid-gap',
|
|
54
|
+
{
|
|
55
|
+
'my-[2rem] pb-[2rem] md:my-[4rem]': frontmatter?.banner,
|
|
56
|
+
'my-[2rem]': !frontmatter?.banner,
|
|
57
|
+
},
|
|
58
|
+
className,
|
|
59
|
+
)}
|
|
48
60
|
>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
<div
|
|
62
|
+
className={classNames('flex w-full align-middle py-2 mb-[1rem] text-sm', {
|
|
63
|
+
'col-page-right px-4 w-full': frontmatter?.banner,
|
|
64
|
+
'bg-white/80 dark:bg-black/80': frontmatter?.banner,
|
|
65
|
+
'col-page-right': !frontmatter?.banner,
|
|
66
|
+
})}
|
|
67
|
+
>
|
|
68
|
+
{subject && (
|
|
69
|
+
<div
|
|
70
|
+
className={classNames('flex-none pr-2 smallcaps', {
|
|
71
|
+
'border-r mr-2': venue,
|
|
72
|
+
})}
|
|
73
|
+
>
|
|
74
|
+
{subject}
|
|
75
|
+
</div>
|
|
76
|
+
)}
|
|
77
|
+
<Journal venue={venue} biblio={biblio} />
|
|
78
|
+
<div className="flex-grow"></div>
|
|
79
|
+
<div className="hidden sm:block">
|
|
80
|
+
<LicenseBadges license={frontmatter?.license} />
|
|
81
|
+
<OpenAccessBadge open_access={frontmatter?.open_access} />
|
|
82
|
+
<GitHubLink github={frontmatter?.github} />
|
|
56
83
|
</div>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
84
|
+
{toggleTheme && <ThemeButton className="inline-block w-5 h-5 mt-0.5 ml-1" />}
|
|
85
|
+
</div>
|
|
86
|
+
<FrontmatterBlock
|
|
87
|
+
frontmatter={rest}
|
|
88
|
+
authorStyle="list"
|
|
89
|
+
className={classNames({ 'pt-4 px-6': frontmatter?.banner })}
|
|
90
|
+
hideBadges
|
|
91
|
+
hideExports
|
|
92
|
+
/>
|
|
93
|
+
{children}
|
|
63
94
|
</div>
|
|
64
|
-
<FrontmatterBlock
|
|
65
|
-
frontmatter={rest}
|
|
66
|
-
authorStyle="list"
|
|
67
|
-
className={classNames('z-10', { 'pt-4': frontmatter?.banner })}
|
|
68
|
-
hideBadges
|
|
69
|
-
hideExports
|
|
70
|
-
/>
|
|
71
|
-
{children}
|
|
72
95
|
</header>
|
|
73
96
|
);
|
|
74
97
|
}
|
|
@@ -64,6 +64,7 @@ const HeadingLink = ({
|
|
|
64
64
|
};
|
|
65
65
|
|
|
66
66
|
const HEADING_CLASSES = 'text-slate-900 leading-5 dark:text-slate-100';
|
|
67
|
+
|
|
67
68
|
const Headings = ({ folder, headings, sections }: Props) => {
|
|
68
69
|
const secs = sections || [];
|
|
69
70
|
return (
|
|
@@ -148,10 +149,6 @@ export const TableOfContents = ({
|
|
|
148
149
|
const footerRef = useRef<HTMLDivElement>(null);
|
|
149
150
|
const [open] = useNavOpen();
|
|
150
151
|
const config = useSiteManifest();
|
|
151
|
-
if (!config) return null;
|
|
152
|
-
const headings = getProjectHeadings(config, projectSlug, {
|
|
153
|
-
addGroups: false,
|
|
154
|
-
});
|
|
155
152
|
useEffect(() => {
|
|
156
153
|
setTimeout(() => {
|
|
157
154
|
if (!footerRef.current) return;
|
|
@@ -159,6 +156,10 @@ export const TableOfContents = ({
|
|
|
159
156
|
footerRef.current.style.transform = 'none';
|
|
160
157
|
}, 500);
|
|
161
158
|
}, [footerRef]);
|
|
159
|
+
if (!config) return null;
|
|
160
|
+
const headings = getProjectHeadings(config, projectSlug, {
|
|
161
|
+
addGroups: false,
|
|
162
|
+
});
|
|
162
163
|
if (!headings) return null;
|
|
163
164
|
return (
|
|
164
165
|
<div
|
|
@@ -205,3 +206,25 @@ export const TableOfContents = ({
|
|
|
205
206
|
</div>
|
|
206
207
|
);
|
|
207
208
|
};
|
|
209
|
+
|
|
210
|
+
export const InlineTableOfContents = ({
|
|
211
|
+
projectSlug,
|
|
212
|
+
tocRef,
|
|
213
|
+
className = 'flex-grow overflow-y-auto max-w-[350px]',
|
|
214
|
+
}: {
|
|
215
|
+
projectSlug?: string;
|
|
216
|
+
className?: string;
|
|
217
|
+
tocRef?: React.RefObject<HTMLElement>;
|
|
218
|
+
}) => {
|
|
219
|
+
const config = useSiteManifest();
|
|
220
|
+
if (!config) return null;
|
|
221
|
+
const headings = getProjectHeadings(config, projectSlug, {
|
|
222
|
+
addGroups: false,
|
|
223
|
+
});
|
|
224
|
+
if (!headings) return null;
|
|
225
|
+
return (
|
|
226
|
+
<nav aria-label="Table of Contents" className={className} ref={tocRef}>
|
|
227
|
+
<Headings folder={projectSlug} headings={headings} sections={config?.projects} />
|
|
228
|
+
</nav>
|
|
229
|
+
);
|
|
230
|
+
};
|
|
@@ -80,7 +80,11 @@ function NavItem({ item }: { item: SiteNavItem }) {
|
|
|
80
80
|
<div className="inline-block">
|
|
81
81
|
<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">
|
|
82
82
|
<span>{item.title}</span>
|
|
83
|
-
<ChevronDownIcon
|
|
83
|
+
<ChevronDownIcon
|
|
84
|
+
width="1.25rem"
|
|
85
|
+
height="1.25rem"
|
|
86
|
+
className="ml-2 -mr-1 text-violet-200 hover:text-violet-100"
|
|
87
|
+
/>
|
|
84
88
|
</Menu.Button>
|
|
85
89
|
</div>
|
|
86
90
|
<Transition
|
|
@@ -92,7 +96,7 @@ function NavItem({ item }: { item: SiteNavItem }) {
|
|
|
92
96
|
leaveFrom="transform opacity-100 scale-100"
|
|
93
97
|
leaveTo="transform opacity-0 scale-95"
|
|
94
98
|
>
|
|
95
|
-
<Menu.Items className="absolute w-48 py-1 mt-2 bg-white rounded-sm shadow-lg
|
|
99
|
+
<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">
|
|
96
100
|
{item.children?.map((action) => (
|
|
97
101
|
<Menu.Item key={action.url}>
|
|
98
102
|
{/* This is really ugly, BUT, the action needs to be defined HERE or the click away doesn't work for some reason */}
|
|
@@ -147,7 +151,7 @@ function ActionMenu({ actions }: { actions?: SiteManifest['actions'] }) {
|
|
|
147
151
|
<Menu.Button className="flex text-sm bg-transparent rounded-full focus:outline-none">
|
|
148
152
|
<span className="sr-only">Open Menu</span>
|
|
149
153
|
<div className="flex items-center text-stone-200 hover:text-white">
|
|
150
|
-
<EllipsisVerticalIcon
|
|
154
|
+
<EllipsisVerticalIcon width="2rem" height="2rem" className="p-1" />
|
|
151
155
|
</div>
|
|
152
156
|
</Menu.Button>
|
|
153
157
|
</div>
|
|
@@ -160,7 +164,7 @@ function ActionMenu({ actions }: { actions?: SiteManifest['actions'] }) {
|
|
|
160
164
|
leaveFrom="transform opacity-100 scale-100"
|
|
161
165
|
leaveTo="transform opacity-0 scale-95"
|
|
162
166
|
>
|
|
163
|
-
<Menu.Items className="absolute right-0 w-48 py-1 mt-2 bg-white rounded-sm shadow-lg
|
|
167
|
+
<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">
|
|
164
168
|
{actions?.map((action) => (
|
|
165
169
|
<Menu.Item key={action.url}>
|
|
166
170
|
{({ active }) => (
|
|
@@ -251,7 +255,7 @@ export function TopNav() {
|
|
|
251
255
|
setOpen(!open);
|
|
252
256
|
}}
|
|
253
257
|
>
|
|
254
|
-
<MenuIcon
|
|
258
|
+
<MenuIcon width="2rem" height="2rem" className="m-1" />
|
|
255
259
|
<span className="sr-only">Open Menu</span>
|
|
256
260
|
</button>
|
|
257
261
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ThemeButton } from './ThemeButton';
|
|
2
2
|
export { TopNav, DEFAULT_NAV_HEIGHT } from './TopNav';
|
|
3
3
|
export { Navigation } from './Navigation';
|
|
4
|
-
export { TableOfContents, useTocHeight } from './TableOfContents';
|
|
4
|
+
export { TableOfContents, InlineTableOfContents, useTocHeight } from './TableOfContents';
|
|
5
5
|
export { LoadingBar } from './Loading';
|
package/src/components/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { FooterLinksBlock } from './FooterLinksBlock';
|
|
|
4
4
|
export { ContentReload } from './ContentReload';
|
|
5
5
|
export { Bibliography } from './Bibliography';
|
|
6
6
|
export { ArticleHeader } from './Headers';
|
|
7
|
+
export { Abstract, Keywords } from './Abstract';
|
|
7
8
|
export { ExternalOrInternalLink } from './ExternalOrInternalLink';
|
|
8
9
|
export * from './Navigation';
|
|
9
10
|
export { renderers } from './renderers';
|
package/src/pages/Article.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ReferencesProvider } from '@myst-theme/providers';
|
|
3
|
-
import { Bibliography, ContentBlocks, FooterLinksBlock } from '../components';
|
|
3
|
+
import { Abstract, Bibliography, ContentBlocks, FooterLinksBlock, Keywords } from '../components';
|
|
4
4
|
import { ErrorDocumentNotFound } from './ErrorDocumentNotFound';
|
|
5
5
|
import { ErrorProjectNotFound } from './ErrorProjectNotFound';
|
|
6
6
|
import type { PageLoader } from '@myst-theme/common';
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
ErrorTray,
|
|
18
18
|
} from '@myst-theme/jupyter';
|
|
19
19
|
import { FrontmatterBlock } from '@myst-theme/frontmatter';
|
|
20
|
-
import classNames from 'classnames';
|
|
21
20
|
|
|
22
21
|
export const ArticlePage = React.memo(function ({
|
|
23
22
|
article,
|
|
@@ -61,29 +60,8 @@ export const ArticlePage = React.memo(function ({
|
|
|
61
60
|
)}
|
|
62
61
|
{canCompute && article.kind === SourceFileKind.Notebook && <NotebookToolbar showLaunch />}
|
|
63
62
|
<ErrorTray pageSlug={article.slug} />
|
|
64
|
-
{abstract
|
|
65
|
-
|
|
66
|
-
<span className="font-semibold">Abstract</span>
|
|
67
|
-
<div className="px-6 py-1 m-3 rounded-sm bg-slate-50 dark:bg-slate-800">
|
|
68
|
-
<ContentBlocks mdast={abstract as GenericParent} className="col-body" />
|
|
69
|
-
</div>
|
|
70
|
-
{!hideKeywords && keywords.length > 0 && (
|
|
71
|
-
<div className="mb-10">
|
|
72
|
-
<span className="mr-2 font-semibold">Keywords:</span>
|
|
73
|
-
{keywords.map((k, i) => (
|
|
74
|
-
<span
|
|
75
|
-
key={k}
|
|
76
|
-
className={classNames({
|
|
77
|
-
"after:content-[','] after:mr-1": i < keywords.length - 1,
|
|
78
|
-
})}
|
|
79
|
-
>
|
|
80
|
-
{k}
|
|
81
|
-
</span>
|
|
82
|
-
))}
|
|
83
|
-
</div>
|
|
84
|
-
)}
|
|
85
|
-
</>
|
|
86
|
-
)}
|
|
63
|
+
<Abstract content={abstract as GenericParent} />
|
|
64
|
+
{abstract && <Keywords keywords={keywords} hideKeywords={hideKeywords} />}
|
|
87
65
|
<ContentBlocks pageKind={article.kind} mdast={tree as GenericParent} />
|
|
88
66
|
<Bibliography />
|
|
89
67
|
<ConnectionStatusTray />
|