Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

📑 Add document outline mobile view #369

Merged
merged 12 commits into from
May 21, 2024
1 change: 0 additions & 1 deletion packages/site/src/pages/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export { ErrorProjectNotFound } from './ErrorProjectNotFound.js';
export { ErrorDocumentNotFound } from './ErrorDocumentNotFound.js';
export { Error404 } from './Error404.js';
export { ArticlePage, ArticlePageCatchBoundary, ProjectPageCatchBoundary } from './Article.js';
export { App, Document, AppCatchBoundary } from './Root.js';
7 changes: 5 additions & 2 deletions themes/article/app/components/Article.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ export function Article({
hideKeywords,
hideOutline,
hideTitle,
outlineMaxDepth,
}: {
article: PageLoader;
hideKeywords?: boolean;
hideOutline?: boolean;
hideTitle?: boolean;
outlineMaxDepth?: number;
}) {
const keywords = article.frontmatter?.keywords ?? [];
const tree = copyNode(article.mdast);
Expand All @@ -42,12 +44,13 @@ export function Article({
<ExecuteScopeProvider enable={compute?.enabled ?? false} contents={article}>
{!hideTitle && <FrontmatterBlock frontmatter={{ title, subtitle }} className="mb-5" />}
{!hideOutline && (
<div className="sticky top-0 z-10 hidden h-0 pt-2 ml-10 col-margin-right lg:block">
<DocumentOutline className="relative">
<div className="block my-10 lg:sticky lg:top-0 lg:z-10 lg:h-0 lg:pt-2 lg:my-0 lg:ml-10 lg:col-margin-right">
<DocumentOutline className="relative" maxdepth={outlineMaxDepth}>
<SupportingDocuments />
</DocumentOutline>
</div>
)}

{compute?.enabled &&
compute?.features.notebookCompute &&
article.kind === SourceFileKind.Notebook && <NotebookToolbar showLaunch />}
Expand Down
43 changes: 33 additions & 10 deletions themes/article/app/components/ArticlePage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { PageLoader } from '@myst-theme/common';
import { FooterLinksBlock, ArticleHeader, Error404 } from '@myst-theme/site';
import {
FooterLinksBlock,
ArticleHeader,
Error404,
ErrorProjectNotFound,
ErrorDocumentNotFound,
} from '@myst-theme/site';
import { LaunchBinder, useComputeOptions } from '@myst-theme/jupyter';
import { ArrowLeftIcon } from '@heroicons/react/24/outline';
import { DocumentArrowDownIcon } from '@heroicons/react/24/outline';
Expand All @@ -15,17 +21,20 @@ import classNames from 'classnames';
import { BusyScopeProvider, ExecuteScopeProvider } from '@myst-theme/jupyter';
import { DownloadLinksArea } from './Downloads';
import { Article } from './Article';

export interface ArticleTemplateOptions {
hide_toc?: boolean;
hide_footer_links?: boolean;
numbered_references?: boolean;
}
import type { TemplateOptions } from '../types.js';

export function ArticlePage({ article }: { article: PageLoader }) {
const grid = useGridSystemProvider();
const { projects, hide_footer_links } = (useSiteManifest() ?? {}) as SiteManifest &
ArticleTemplateOptions;

const siteManifest = useSiteManifest() as SiteManifest;
const pageDesign: TemplateOptions = (article.frontmatter as any)?.options ?? {};
const siteDesign: TemplateOptions = siteManifest?.options ?? {};

const { projects } = siteManifest;
const { hide_footer_links, hide_outline, outline_maxdepth } = {
...siteDesign,
...pageDesign,
};
const Link = useLinkProvider();
const baseurl = useBaseurl();
const compute = useComputeOptions();
Expand Down Expand Up @@ -91,11 +100,25 @@ export function ArticlePage({ article }: { article: PageLoader }) {
</a>
</div>
)}
<Article article={article} hideKeywords={!isIndex} hideTitle={isIndex} />
<Article
article={article}
hideKeywords={!isIndex}
hideTitle={isIndex}
hideOutline={hide_outline}
outlineMaxDepth={outline_maxdepth}
/>
</main>
{!hide_footer_links && <FooterLinksBlock links={article.footer} />}
</ExecuteScopeProvider>
</BusyScopeProvider>
</ReferencesProvider>
);
}

export function ProjectPageCatchBoundary() {
return <ErrorProjectNotFound />;
}

export function ArticlePageCatchBoundary() {
return <ErrorDocumentNotFound />;
}
3 changes: 2 additions & 1 deletion themes/article/app/routes/$.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
type LoaderFunction,
type V2_MetaFunction,
} from '@remix-run/node';
import { getMetaTagsForArticle, KatexCSS, ArticlePageCatchBoundary } from '@myst-theme/site';
import { getMetaTagsForArticle, KatexCSS } from '@myst-theme/site';
import { ArticlePageCatchBoundary } from '../components/ArticlePage';
import { getConfig, getPage } from '~/utils/loaders.server';
import { useLoaderData } from '@remix-run/react';
import type { SiteManifest } from 'myst-config';
Expand Down
8 changes: 2 additions & 6 deletions themes/article/app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import {
ProjectPageCatchBoundary,
getMetaTagsForArticle,
responseNoArticle,
responseNoSite,
} from '@myst-theme/site';
import { getMetaTagsForArticle, responseNoArticle, responseNoSite } from '@myst-theme/site';
import Page from './$';
import { ArticlePageAndNavigation } from '../components/ArticlePageAndNavigation';
import { ProjectPageCatchBoundary } from '../components/ArticlePage';
import { getConfig, getPage } from '../utils/loaders.server';
import type { LoaderFunction, V2_MetaFunction } from '@remix-run/node';
import { redirect } from '@remix-run/node';
Expand Down
6 changes: 6 additions & 0 deletions themes/article/app/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface TemplateOptions {
hide_toc?: boolean;
hide_outline?: boolean;
hide_footer_links?: boolean;
outline_maxdepth?: number;
}
9 changes: 9 additions & 0 deletions themes/article/template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ options:
- type: boolean
id: hide_footer_links
description: Hide the previous/next links in the footer
- type: boolean
id: hide_outline
description: Hide the document outline on all pages
- type: number
id: outline_maxdepth
description: The maximum depth to show on the document outline, for example, `2` would show only two depths of headings (e.g. `<H1>` and `<H2>`).
min: 1
max: 6
integer: true
- type: string
id: twitter
description: Twitter handle related to the site
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React from 'react';
import { ReferencesProvider, useProjectManifest } from '@myst-theme/providers';
import { ReferencesProvider, useProjectManifest, useSiteManifest } from '@myst-theme/providers';
import {
Bibliography,
ContentBlocks,
FooterLinksBlock,
FrontmatterParts,
BackmatterParts,
} from '../components/index.js';
import { ErrorDocumentNotFound } from './ErrorDocumentNotFound.js';
import { ErrorProjectNotFound } from './ErrorProjectNotFound.js';
DocumentOutline,
ErrorDocumentNotFound,
ErrorProjectNotFound,
extractKnownParts,
} from '@myst-theme/site';
import type { SiteManifest } from 'myst-config';
import type { PageLoader } from '@myst-theme/common';
import { copyNode, type GenericParent } from 'myst-common';
import { SourceFileKind } from 'myst-spec-ext';
Expand All @@ -21,8 +24,8 @@ import {
useComputeOptions,
} from '@myst-theme/jupyter';
import { FrontmatterBlock } from '@myst-theme/frontmatter';
import { extractKnownParts } from '../utils.js';
import type { SiteAction } from 'myst-config';
import type { TemplateOptions } from '../types.js';

/**
* Combines the project downloads and the export options
Expand Down Expand Up @@ -53,7 +56,13 @@ export const ArticlePage = React.memo(function ({
const manifest = useProjectManifest();
const compute = useComputeOptions();

const { hide_title_block, hide_footer_links } = (article.frontmatter as any)?.options ?? {};
const pageDesign: TemplateOptions = (article.frontmatter as any)?.options ?? {};
const siteDesign: TemplateOptions =
(useSiteManifest() as SiteManifest & TemplateOptions)?.options ?? {};
const { hide_title_block, hide_footer_links, hide_outline, outline_maxdepth } = {
...siteDesign,
...pageDesign,
};
const downloads = combineDownloads(manifest?.downloads, article.frontmatter);
const tree = copyNode(article.mdast);
const keywords = article.frontmatter?.keywords ?? [];
Expand All @@ -73,6 +82,11 @@ export const ArticlePage = React.memo(function ({
className="pt-5 mb-8"
/>
)}
{!hide_outline && (
<div className="block my-10 lg:sticky lg:top-0 lg:z-10 lg:h-0 lg:pt-2 lg:my-0 lg:ml-10 lg:col-margin-right">
<DocumentOutline className="relative" maxdepth={outline_maxdepth} />
</div>
)}
{compute?.enabled &&
compute.features.notebookCompute &&
article.kind === SourceFileKind.Notebook && <NotebookToolbar showLaunch />}
Expand Down
38 changes: 7 additions & 31 deletions themes/book/app/routes/$.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ import {
import { getProject, isFlatSite, type PageLoader } from '@myst-theme/common';
import {
KatexCSS,
ArticlePage,
useOutlineHeight,
useTocHeight,
DocumentOutline,
Navigation,
TopNav,
ArticlePageCatchBoundary,
getMetaTagsForArticle,
} from '@myst-theme/site';
import { getConfig, getPage } from '~/utils/loaders.server';
Expand All @@ -29,7 +26,8 @@ import {
} from '@myst-theme/providers';
import { MadeWithMyst } from '@myst-theme/icons';
import { ComputeOptionsProvider, ThebeLoaderAndServer } from '@myst-theme/jupyter';

import { ArticlePage, ArticlePageCatchBoundary } from '../components/ArticlePage.js';
import type { TemplateOptions } from '../types.js';
type ManifestProject = Required<SiteManifest>['projects'][0];

export const meta: V2_MetaFunction = ({ data, matches, location }) => {
Expand Down Expand Up @@ -107,24 +105,15 @@ export function ArticlePageAndNavigation({
);
}

export interface BookThemeTemplateOptions {
hide_toc?: boolean;
hide_outline?: boolean;
hide_footer_links?: boolean;
outline_maxdepth?: number;
numbered_references?: boolean;
}

export default function Page() {
const { container, outline } = useOutlineHeight();
const top = useThemeTop();
const { container } = useOutlineHeight();
const data = useLoaderData() as { page: PageLoader; project: ManifestProject };

const baseurl = useBaseurl();
const pageDesign: BookThemeTemplateOptions = (data.page.frontmatter as any)?.options ?? {};
const siteDesign: BookThemeTemplateOptions =
(useSiteManifest() as SiteManifest & BookThemeTemplateOptions)?.options ?? {};
const { hide_toc, hide_outline, hide_footer_links, outline_maxdepth } = {
const pageDesign: TemplateOptions = (data.page.frontmatter as any)?.options ?? {};
const siteDesign: TemplateOptions =
(useSiteManifest() as SiteManifest & TemplateOptions)?.options ?? {};
const { hide_toc, hide_footer_links } = {
...siteDesign,
...pageDesign,
};
Expand All @@ -137,19 +126,6 @@ export default function Page() {
>
<ThebeLoaderAndServer baseurl={baseurl}>
<main ref={container} className="article-grid subgrid-gap col-screen">
{!hide_outline && (
<div
className="sticky z-10 hidden h-0 col-margin-right-inset lg:block"
style={{ top }}
>
<DocumentOutline
top={16}
className="relative"
outlineRef={outline}
maxdepth={outline_maxdepth}
/>
</div>
)}
<ArticlePage article={data.page} hide_all_footer_links={hide_footer_links} />
</main>
</ThebeLoaderAndServer>
Expand Down
7 changes: 7 additions & 0 deletions themes/book/app/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface TemplateOptions {
hide_toc?: boolean;
hide_outline?: boolean;
hide_footer_links?: boolean;
outline_maxdepth?: number;
hide_title_block?: boolean;
agoose77 marked this conversation as resolved.
Show resolved Hide resolved
}
Loading