@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myst-theme/site",
3
- "version": "0.5.1",
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.1",
20
- "@myst-theme/frontmatter": "^0.5.1",
21
- "@myst-theme/jupyter": "^0.5.1",
22
- "@myst-theme/common": "^0.5.1",
23
- "@myst-theme/providers": "^0.5.1",
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.1",
30
- "myst-to-react": "^0.5.1",
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.0",
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 className="inline h-5 pr-2 shrink-0" />
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 className="self-center w-6 h-6 transition-transform group-hover:-translate-x-1 shrink-0" />
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 className="self-center w-6 h-6 transition-transform group-hover:translate-x-1 shrink-0" />
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
- <div className="absolute border-white shadow-2xl bg-white/80 dark:bg-black/80 backdrop-blur top-[2rem] h-[calc(100%-4rem)] w-full col-screen md:col-screen-inset pointer-events-none"></div>
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('flex w-full align-middle z-10 py-2 mb-[1rem] text-sm', {
44
- 'col-screen md:col-screen-inset px-4': frontmatter?.banner,
45
- 'col-page-right': !frontmatter?.banner,
46
- 'bg-white/80 dark:bg-black/80': frontmatter?.banner,
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
- {subject && (
50
- <div
51
- className={classNames('flex-none pr-2 smallcaps', {
52
- 'border-r mr-2': venue,
53
- })}
54
- >
55
- {subject}
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
- <Journal venue={venue} biblio={biblio} />
59
- <div className="flex-grow"></div>
60
- <LicenseBadges license={frontmatter?.license} />
61
- <OpenAccessBadge open_access={frontmatter?.open_access} />
62
- <GitHubLink github={frontmatter?.github} />
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 className="w-5 h-5 ml-2 -mr-1 text-violet-200 hover:text-violet-100" />
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 origin-top-left left-4 ring-1 ring-black ring-opacity-5 focus:outline-none">
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 className="w-8 h-8 p-1" />
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 origin-top-right ring-1 ring-black ring-opacity-5 focus:outline-none">
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 className="w-8 h-8 p-1" />
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';
@@ -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';
@@ -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 />