@myst-theme/site 0.13.0 → 0.13.2
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 +12 -12
- package/src/components/DocumentOutline.tsx +4 -1
- package/src/components/Headers.tsx +9 -4
- package/src/components/Navigation/Search.tsx +7 -4
- package/src/components/SkipToArticle.tsx +4 -1
- package/src/pages/Article.tsx +1 -1
- package/src/pages/ErrorUnhandled.tsx +1 -1
- package/src/pages/Root.tsx +3 -0
- package/src/utils.ts +10 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myst-theme/site",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@headlessui/react": "^1.7.15",
|
|
23
23
|
"@heroicons/react": "^2.0.18",
|
|
24
|
-
"@myst-theme/common": "^0.13.
|
|
25
|
-
"@myst-theme/diagrams": "^0.13.
|
|
26
|
-
"@myst-theme/frontmatter": "^0.13.
|
|
27
|
-
"@myst-theme/jupyter": "^0.13.
|
|
28
|
-
"@myst-theme/providers": "^0.13.
|
|
29
|
-
"@myst-theme/search": "^0.13.
|
|
24
|
+
"@myst-theme/common": "^0.13.2",
|
|
25
|
+
"@myst-theme/diagrams": "^0.13.2",
|
|
26
|
+
"@myst-theme/frontmatter": "^0.13.2",
|
|
27
|
+
"@myst-theme/jupyter": "^0.13.2",
|
|
28
|
+
"@myst-theme/providers": "^0.13.2",
|
|
29
|
+
"@myst-theme/search": "^0.13.2",
|
|
30
30
|
"@radix-ui/react-collapsible": "^1.0.3",
|
|
31
31
|
"@radix-ui/react-dialog": "^1.0.3",
|
|
32
32
|
"@radix-ui/react-radio-group": "^1.2.0",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"@radix-ui/react-visually-hidden": "^1.1.0",
|
|
36
36
|
"classnames": "^2.3.2",
|
|
37
37
|
"lodash.throttle": "^4.1.1",
|
|
38
|
-
"myst-common": "^1.7.
|
|
39
|
-
"myst-config": "^1.7.
|
|
40
|
-
"myst-demo": "^0.13.
|
|
41
|
-
"myst-spec-ext": "^1.7.
|
|
42
|
-
"myst-to-react": "^0.13.
|
|
38
|
+
"myst-common": "^1.7.2",
|
|
39
|
+
"myst-config": "^1.7.2",
|
|
40
|
+
"myst-demo": "^0.13.2",
|
|
41
|
+
"myst-spec-ext": "^1.7.2",
|
|
42
|
+
"myst-to-react": "^0.13.2",
|
|
43
43
|
"nbtx": "^0.2.3",
|
|
44
44
|
"node-cache": "^5.1.2",
|
|
45
45
|
"node-fetch": "^2.6.11",
|
|
@@ -60,11 +60,14 @@ const Headings = ({ headings, activeId }: Props) => (
|
|
|
60
60
|
href={`#${heading.id}`}
|
|
61
61
|
onClick={(e) => {
|
|
62
62
|
e.preventDefault();
|
|
63
|
-
const el = document.querySelector(`#${heading.id}`);
|
|
63
|
+
const el = document.querySelector(`#${heading.id}`) as HTMLElement | undefined;
|
|
64
64
|
if (!el) return;
|
|
65
65
|
|
|
66
66
|
el.scrollIntoView({ behavior: 'smooth' });
|
|
67
67
|
history.replaceState(undefined, '', `#${heading.id}`);
|
|
68
|
+
// Changes keyboard tab-index location
|
|
69
|
+
if (el.tabIndex === -1) el.tabIndex = -1;
|
|
70
|
+
el.focus({ preventScroll: true });
|
|
68
71
|
}}
|
|
69
72
|
// Note that the title can have math in it!
|
|
70
73
|
dangerouslySetInnerHTML={{ __html: heading.titleHTML }}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from '@myst-theme/frontmatter';
|
|
8
8
|
import { useGridSystemProvider } from '@myst-theme/providers';
|
|
9
9
|
import classNames from 'classnames';
|
|
10
|
-
import type {
|
|
10
|
+
import type { PageFrontmatterWithDownloads } from '@myst-theme/common';
|
|
11
11
|
import { ThemeButton } from './Navigation/index.js';
|
|
12
12
|
|
|
13
13
|
export function ArticleHeader({
|
|
@@ -16,13 +16,13 @@ export function ArticleHeader({
|
|
|
16
16
|
toggleTheme,
|
|
17
17
|
className,
|
|
18
18
|
}: {
|
|
19
|
-
frontmatter:
|
|
19
|
+
frontmatter: PageFrontmatterWithDownloads;
|
|
20
20
|
children?: React.ReactNode;
|
|
21
21
|
toggleTheme?: boolean;
|
|
22
22
|
className?: string;
|
|
23
23
|
}) {
|
|
24
24
|
const grid = useGridSystemProvider();
|
|
25
|
-
const { subject, venue,
|
|
25
|
+
const { subject, venue, volume, issue, ...rest } = frontmatter ?? {};
|
|
26
26
|
const positionBackground = {
|
|
27
27
|
'col-page-right': grid === 'article-left-grid',
|
|
28
28
|
'col-page': grid === 'article-grid',
|
|
@@ -71,7 +71,12 @@ export function ArticleHeader({
|
|
|
71
71
|
})}
|
|
72
72
|
>
|
|
73
73
|
{subject && <div className={classNames('flex-none pr-2 smallcaps')}>{subject}</div>}
|
|
74
|
-
<Journal
|
|
74
|
+
<Journal
|
|
75
|
+
venue={venue}
|
|
76
|
+
volume={volume}
|
|
77
|
+
issue={issue}
|
|
78
|
+
className="hidden pl-2 border-l md:block"
|
|
79
|
+
/>
|
|
75
80
|
<div className="flex-grow"></div>
|
|
76
81
|
<div className="hidden sm:block">
|
|
77
82
|
<LicenseBadges license={frontmatter?.license} />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useState, useMemo, useCallback, useRef, forwardRef } from 'react';
|
|
2
2
|
import type { KeyboardEventHandler, Dispatch, SetStateAction, FormEvent, MouseEvent } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { useFetcher } from '@remix-run/react';
|
|
4
4
|
import {
|
|
5
5
|
ArrowTurnDownLeftIcon,
|
|
6
6
|
MagnifyingGlassIcon,
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
useLinkProvider,
|
|
21
21
|
withBaseurl,
|
|
22
22
|
useBaseurl,
|
|
23
|
+
useNavigateProvider,
|
|
23
24
|
} from '@myst-theme/providers';
|
|
24
25
|
|
|
25
26
|
/**
|
|
@@ -182,6 +183,7 @@ function SearchResultItem({
|
|
|
182
183
|
closeSearch?: () => void;
|
|
183
184
|
}) {
|
|
184
185
|
const { hierarchy, type, url, queries } = result;
|
|
186
|
+
const baseurl = useBaseurl();
|
|
185
187
|
const Link = useLinkProvider();
|
|
186
188
|
|
|
187
189
|
// Render the icon
|
|
@@ -219,7 +221,7 @@ function SearchResultItem({
|
|
|
219
221
|
return (
|
|
220
222
|
<Link
|
|
221
223
|
className="block px-1 py-2 text-gray-700 rounded shadow-md dark:text-white group-aria-selected:bg-blue-600 group-aria-selected:text-white dark:shadow-none dark:bg-stone-800"
|
|
222
|
-
to={url}
|
|
224
|
+
to={withBaseurl(url, baseurl)}
|
|
223
225
|
// Close the main search on click
|
|
224
226
|
onClick={closeSearch}
|
|
225
227
|
>
|
|
@@ -415,7 +417,8 @@ function SearchForm({
|
|
|
415
417
|
setQuery(event.target.value);
|
|
416
418
|
}, []);
|
|
417
419
|
// Handle item selection
|
|
418
|
-
const navigate =
|
|
420
|
+
const navigate = useNavigateProvider();
|
|
421
|
+
const baseurl = useBaseurl();
|
|
419
422
|
|
|
420
423
|
// Handle item selection and navigation
|
|
421
424
|
const handleSearchKeyPress = useCallback<KeyboardEventHandler<HTMLInputElement>>(
|
|
@@ -434,7 +437,7 @@ function SearchForm({
|
|
|
434
437
|
|
|
435
438
|
const url = searchResults[selectedIndex]?.url;
|
|
436
439
|
if (url) {
|
|
437
|
-
navigate(url);
|
|
440
|
+
navigate(withBaseurl(url, baseurl));
|
|
438
441
|
closeSearch?.();
|
|
439
442
|
}
|
|
440
443
|
}
|
|
@@ -3,10 +3,13 @@ import React, { useCallback } from 'react';
|
|
|
3
3
|
function makeSkipClickHandler(hash: string) {
|
|
4
4
|
return (e: React.UIEvent<HTMLElement, Event>) => {
|
|
5
5
|
e.preventDefault();
|
|
6
|
-
const el = document.querySelector(`#${hash}`);
|
|
6
|
+
const el = document.querySelector(`#${hash}`) as HTMLElement;
|
|
7
7
|
if (!el) return;
|
|
8
8
|
(el.nextSibling as HTMLElement).focus();
|
|
9
9
|
history.replaceState(undefined, '', `#${hash}`);
|
|
10
|
+
// Changes keyboard tab-index location
|
|
11
|
+
if (el.tabIndex === -1) el.tabIndex = -1;
|
|
12
|
+
el.focus({ preventScroll: true });
|
|
10
13
|
};
|
|
11
14
|
}
|
|
12
15
|
|
package/src/pages/Article.tsx
CHANGED
|
@@ -42,7 +42,7 @@ export const ArticlePage = React.memo(function ({
|
|
|
42
42
|
const downloads = combineDownloads(manifest?.downloads, article.frontmatter);
|
|
43
43
|
const tree = copyNode(article.mdast);
|
|
44
44
|
const keywords = article.frontmatter?.keywords ?? [];
|
|
45
|
-
const parts = extractKnownParts(tree);
|
|
45
|
+
const parts = extractKnownParts(tree, article.frontmatter?.parts);
|
|
46
46
|
|
|
47
47
|
return (
|
|
48
48
|
<ReferencesProvider
|
package/src/pages/Root.tsx
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
NavLink,
|
|
21
21
|
useRouteError,
|
|
22
22
|
isRouteErrorResponse,
|
|
23
|
+
useNavigate,
|
|
23
24
|
} from '@remix-run/react';
|
|
24
25
|
import {
|
|
25
26
|
DEFAULT_NAV_HEIGHT,
|
|
@@ -53,6 +54,7 @@ export function Document({
|
|
|
53
54
|
top?: number;
|
|
54
55
|
renderers?: NodeRenderers;
|
|
55
56
|
}) {
|
|
57
|
+
const navigate = useNavigate();
|
|
56
58
|
const links = staticBuild
|
|
57
59
|
? {
|
|
58
60
|
Link: (props: any) => <Link {...{ ...props, reloadDocument: true }} />,
|
|
@@ -61,6 +63,7 @@ export function Document({
|
|
|
61
63
|
: {
|
|
62
64
|
Link: Link as any,
|
|
63
65
|
NavLink: NavLink as any,
|
|
66
|
+
navigate,
|
|
64
67
|
};
|
|
65
68
|
|
|
66
69
|
// (Local) theme state driven by SSR and cookie/localStorage
|
package/src/utils.ts
CHANGED
|
@@ -18,13 +18,21 @@ export type KnownParts = {
|
|
|
18
18
|
acknowledgments?: GenericParent;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
export function extractKnownParts(
|
|
21
|
+
export function extractKnownParts(
|
|
22
|
+
tree: GenericParent,
|
|
23
|
+
parts?: Record<string, { mdast?: GenericParent }>,
|
|
24
|
+
): KnownParts {
|
|
22
25
|
const abstract = extractPart(tree, 'abstract');
|
|
23
26
|
const summary = extractPart(tree, 'summary', { requireExplicitPart: true });
|
|
24
27
|
const keypoints = extractPart(tree, ['keypoints'], { requireExplicitPart: true });
|
|
25
28
|
const data_availability = extractPart(tree, ['data_availability', 'data availability']);
|
|
26
29
|
const acknowledgments = extractPart(tree, ['acknowledgments', 'acknowledgements']);
|
|
27
|
-
|
|
30
|
+
const otherParts = Object.fromEntries(
|
|
31
|
+
Object.entries(parts ?? {}).map(([k, v]) => {
|
|
32
|
+
return [k, v.mdast];
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
return { abstract, summary, keypoints, data_availability, acknowledgments, ...otherParts };
|
|
28
36
|
}
|
|
29
37
|
|
|
30
38
|
/**
|