Skip to content

Commit

Permalink
feat: move blocks to MyST
Browse files Browse the repository at this point in the history
  • Loading branch information
agoose77 committed Feb 12, 2025
1 parent 83db440 commit a712f91
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 110 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 77 additions & 0 deletions packages/myst-to-react/src/block.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Details } from './dropdown.js';
import { MyST } from './MyST.js';
import { SourceFileKind } from 'myst-spec-ext';
import type { GenericParent } from 'myst-common';
import classNames from 'classnames';
import {
NotebookClearCell,
NotebookRunCell,
NotebookRunCellSpinnerOnly,
executableNodesFromBlock,
} from '@myst-theme/jupyter';
import { useGridSystemProvider, usePageKindProvider } from '@myst-theme/providers';
import type { NodeRenderer } from '@myst-theme/providers';

export function isACodeCell(node: GenericParent) {
return !!executableNodesFromBlock(node);
}
export function Block({
id,
node,
className,
}: {
id: string;
node: GenericParent;
className?: string;
}) {
const pageKind = usePageKindProvider();
const grid = useGridSystemProvider();
const subGrid = node.visibility === 'hide' ? '' : `${grid} subgrid-gap col-screen`;
const dataClassName = typeof node.data?.class === 'string' ? node.data?.class : undefined;
// Hide the subgrid if either the dataClass or the className exists and includes `col-`
const noSubGrid =
(dataClassName && dataClassName.includes('col-')) || (className && className.includes('col-'));
const block = (
<div
key={`block-${id}`}
id={id}
className={classNames('relative group/block', className, dataClassName, {
[subGrid]: !noSubGrid,
hidden: node.visibility === 'remove',
})}
>
{pageKind === SourceFileKind.Notebook && isACodeCell(node) && (
<>
<div className="flex sticky top-[80px] z-10 opacity-70 group-hover/block:opacity-100 group-hover/block:hidden">
<div className="absolute top-0 -right-[28px] flex md:flex-col">
<NotebookRunCellSpinnerOnly id={id} />
</div>
</div>
<div className="hidden sticky top-[80px] z-10 opacity-70 group-hover/block:opacity-100 group-hover/block:flex">
<div className="absolute top-0 -right-[28px] flex md:flex-col">
<NotebookRunCell id={id} />
<NotebookClearCell id={id} />
</div>
</div>
</>
)}
<MyST ast={node.children} />
</div>
);
if (node.visibility === 'hide') {
return <Details title="Notebook Cell">{block}</Details>;
}
return block;
}

export const BlockRenderer: NodeRenderer = ({ node, className }) => {
return (
<Block key={node.key} id={node.key} node={node} className={classNames(node.class, className)} />
);
};

const BLOCK_RENDERERS: Record<string, NodeRenderer> = {
block: BlockRenderer,
};

export default BLOCK_RENDERERS;
19 changes: 19 additions & 0 deletions packages/providers/src/pageKind.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React, { useContext } from 'react';
import type { SourceFileKind } from 'myst-spec-ext';

const PageKindContext = React.createContext<SourceFileKind | undefined>(undefined);

export function PageKindProvider({
pageKind,
children,
}: {
pageKind: SourceFileKind;
children: React.ReactNode;
}) {
return <PageKindContext.Provider value={pageKind}>{children}</PageKindContext.Provider>;
}

export function usePageKindProvider() {
const config = useContext(PageKindContext);
return config;
}
4 changes: 2 additions & 2 deletions packages/site/src/components/Abstract.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { GenericParent } from 'myst-common';
import { ContentBlocks } from './ContentBlocks.js';
import { MyST } from 'myst-to-react';
import { HashLink } from 'myst-to-react';

export function Abstract({
Expand All @@ -21,7 +21,7 @@ export function Abstract({
<HashLink id={id} title={`Link to ${title}`} hover className="ml-2" />
</h2>
<div className="px-6 py-1 mb-3 rounded-sm bg-slate-50 dark:bg-slate-800">
<ContentBlocks mdast={content} className="col-body" />
<MyST ast={content} className="col-body" />
</div>
</div>
);
Expand Down
81 changes: 5 additions & 76 deletions packages/site/src/components/ContentBlocks.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,10 @@
import { Details, MyST } from 'myst-to-react';
import { SourceFileKind } from 'myst-spec-ext';
import type { GenericParent } from 'myst-common';
import classNames from 'classnames';
import {
NotebookClearCell,
NotebookRunCell,
NotebookRunCellSpinnerOnly,
} from '@myst-theme/jupyter';
import { useGridSystemProvider } from '@myst-theme/providers';
import { isACodeCell } from '../utils.js';

export function Block({
id,
pageKind,
node,
className,
}: {
id: string;
pageKind: SourceFileKind;
node: GenericParent;
className?: string;
}) {
const grid = useGridSystemProvider();
const subGrid = node.visibility === 'hide' ? '' : `${grid} subgrid-gap col-screen`;
const dataClassName = typeof node.data?.class === 'string' ? node.data?.class : undefined;
// Hide the subgrid if either the dataClass or the className exists and includes `col-`
const noSubGrid =
(dataClassName && dataClassName.includes('col-')) || (className && className.includes('col-'));
const block = (
<div
key={`block-${id}`}
id={id}
className={classNames('relative group/block', className, dataClassName, {
[subGrid]: !noSubGrid,
hidden: node.visibility === 'remove',
})}
>
{pageKind === SourceFileKind.Notebook && isACodeCell(node) && (
<>
<div className="flex sticky top-[80px] z-10 opacity-70 group-hover/block:opacity-100 group-hover/block:hidden">
<div className="absolute top-0 -right-[28px] flex md:flex-col">
<NotebookRunCellSpinnerOnly id={id} />
</div>
</div>
<div className="hidden sticky top-[80px] z-10 opacity-70 group-hover/block:opacity-100 group-hover/block:flex">
<div className="absolute top-0 -right-[28px] flex md:flex-col">
<NotebookRunCell id={id} />
<NotebookClearCell id={id} />
</div>
</div>
</>
)}
<MyST ast={node.children} />
</div>
);
if (node.visibility === 'hide') {
return <Details title="Notebook Cell">{block}</Details>;
}
return block;
}
import { MyST } from 'myst-to-react';

/**
* @deprecated This component is not maintained, in favor of generic MyST component
*/
export function ContentBlocks({
mdast,
pageKind = SourceFileKind.Article,
Expand All @@ -69,21 +14,5 @@ export function ContentBlocks({
pageKind?: SourceFileKind;
className?: string;
}) {
if (!mdast) return null;
const blocks = mdast.children as GenericParent[];
return (
<>
{blocks
.filter((node) => node.visibility !== 'remove')
.map((node) => (
<Block
key={node.key}
id={node.key}
pageKind={pageKind}
node={node}
className={className}
/>
))}
</>
);
return <MyST ast={mdast} className={className} />;
}
54 changes: 28 additions & 26 deletions packages/site/src/pages/Article.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react';
import { ReferencesProvider, useProjectManifest } from '@myst-theme/providers';
import { ReferencesProvider, useProjectManifest, PageKindProvider } from '@myst-theme/providers';
import {
Bibliography,
ContentBlocks,
FooterLinksBlock,
FrontmatterParts,
BackmatterParts,
} from '../components/index.js';
import type { PageLoader } from '@myst-theme/common';
import { MyST } from 'myst-to-react';
import { copyNode, type GenericParent } from 'myst-common';
import { SourceFileKind } from 'myst-spec-ext';
import {
Expand Down Expand Up @@ -54,30 +54,32 @@ export const ArticlePage = React.memo(function ({
>
<BusyScopeProvider>
<ExecuteScopeProvider enable={compute?.enabled ?? false} contents={article}>
{!hide_title_block && (
<FrontmatterBlock
kind={article.kind}
frontmatter={{ ...article.frontmatter, downloads }}
thebe={thebe}
location={location}
className="mb-8 pt-9"
/>
)}
{compute?.enabled &&
compute.features.notebookCompute &&
article.kind === SourceFileKind.Notebook && <NotebookToolbar showLaunch />}
{compute?.enabled && article.kind === SourceFileKind.Article && (
<ErrorTray pageSlug={article.slug} />
)}
<div id="skip-to-article" />
<FrontmatterParts parts={parts} keywords={keywords} hideKeywords={hideKeywords} />
<ContentBlocks pageKind={article.kind} mdast={tree as GenericParent} />
<BackmatterParts parts={parts} />
<Bibliography />
<ConnectionStatusTray />
{!hide_footer_links && !hide_all_footer_links && (
<FooterLinksBlock links={article.footer} />
)}
<PageKindProvider pageKind={article.kind}>
{!hide_title_block && (
<FrontmatterBlock
kind={article.kind}
frontmatter={{ ...article.frontmatter, downloads }}
thebe={thebe}
location={location}
className="mb-8 pt-9"
/>
)}
{compute?.enabled &&
compute.features.notebookCompute &&
article.kind === SourceFileKind.Notebook && <NotebookToolbar showLaunch />}
{compute?.enabled && article.kind === SourceFileKind.Article && (
<ErrorTray pageSlug={article.slug} />
)}
<div id="skip-to-article" />
<FrontmatterParts parts={parts} keywords={keywords} hideKeywords={hideKeywords} />
<MyST ast={tree as GenericParent} />
<BackmatterParts parts={parts} />
<Bibliography />
<ConnectionStatusTray />
{!hide_footer_links && !hide_all_footer_links && (
<FooterLinksBlock links={article.footer} />
)}
</PageKindProvider>
</ExecuteScopeProvider>
</BusyScopeProvider>
</ReferencesProvider>
Expand Down
10 changes: 6 additions & 4 deletions themes/article/app/components/Article.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { type PageLoader } from '@myst-theme/common';
import {
Bibliography,
ContentBlocks,
DocumentOutline,
SupportingDocuments,
FrontmatterParts,
Expand All @@ -10,18 +9,19 @@ import {
Footnotes,
} from '@myst-theme/site';
import React from 'react';
import { ErrorTray, NotebookToolbar, useComputeOptions } from '@myst-theme/jupyter';
import { ErrorTray, NotebookToolbar, useComputeOptions, BusyScopeProvider, ConnectionStatusTray, ExecuteScopeProvider } from '@myst-theme/jupyter';
import { FrontmatterBlock } from '@myst-theme/frontmatter';
import {
ReferencesProvider,
useThemeTop,
useMediaQuery,
useProjectManifest,
PageKindProvider
} from '@myst-theme/providers';
import type { GenericParent } from 'myst-common';
import { copyNode } from 'myst-common';
import { BusyScopeProvider, ConnectionStatusTray, ExecuteScopeProvider } from '@myst-theme/jupyter';
import { SourceFileKind } from 'myst-spec-ext';
import { MyST } from 'myst-to-react';

const TOP_OFFSET = 24;

Expand Down Expand Up @@ -56,6 +56,7 @@ export function Article({
>
<BusyScopeProvider>
<ExecuteScopeProvider enable={compute?.enabled ?? false} contents={article}>
<PageKindProvider pageKind={article.kind}>
{!hideTitle && (
<FrontmatterBlock
frontmatter={{ title, subtitle }}
Expand Down Expand Up @@ -86,11 +87,12 @@ export function Article({
<ErrorTray pageSlug={article.slug} />
<div id="skip-to-article" />
<FrontmatterParts parts={parts} keywords={keywords} hideKeywords={hideKeywords} />
<ContentBlocks mdast={tree as GenericParent} />
<MyST ast={tree as GenericParent} />
<BackmatterParts parts={parts} />
<Footnotes />
<Bibliography />
<ConnectionStatusTray />
</PageKindProvider>
</ExecuteScopeProvider>
</BusyScopeProvider>
</ReferencesProvider>
Expand Down
7 changes: 5 additions & 2 deletions themes/book/app/components/ArticlePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import {
useSiteManifest,
useThemeTop,
useMediaQuery,
PageKindProvider
} from '@myst-theme/providers';
import {
Bibliography,
ContentBlocks,
FooterLinksBlock,
FrontmatterParts,
BackmatterParts,
Expand All @@ -28,6 +28,7 @@ import {
ErrorTray,
useComputeOptions,
} from '@myst-theme/jupyter';
import { MyST } from 'myst-to-react';
import { FrontmatterBlock } from '@myst-theme/frontmatter';
import type { SiteAction } from 'myst-config';
import type { TemplateOptions } from '../types.js';
Expand Down Expand Up @@ -86,6 +87,7 @@ export const ArticlePage = React.memo(function ({
>
<BusyScopeProvider>
<ExecuteScopeProvider enable={compute?.enabled ?? false} contents={article}>
<PageKindProvider pageKind={article.kind}>
{!hide_title_block && (
<FrontmatterBlock
kind={article.kind}
Expand Down Expand Up @@ -115,14 +117,15 @@ export const ArticlePage = React.memo(function ({
)}
<div id="skip-to-article" />
<FrontmatterParts parts={parts} keywords={keywords} hideKeywords={hideKeywords} />
<ContentBlocks pageKind={article.kind} mdast={tree as GenericParent} />
<MyST ast={tree as GenericParent} />
<BackmatterParts parts={parts} />
<Footnotes />
<Bibliography />
<ConnectionStatusTray />
{!hide_footer_links && !hide_all_footer_links && (
<FooterLinksBlock links={article.footer} />
)}
</PageKindProvider>
</ExecuteScopeProvider>
</BusyScopeProvider>
</ReferencesProvider>
Expand Down

0 comments on commit a712f91

Please sign in to comment.