Skip to content

Commit

Permalink
Merge pull request #18 from jupyter-book/fix/primary-sidebar
Browse files Browse the repository at this point in the history
📱fixes mobile navigation using new `PrimarySidebar`
  • Loading branch information
stevejpurves authored Aug 26, 2024
2 parents ca32d47 + fcce48c commit 84c9a25
Show file tree
Hide file tree
Showing 9 changed files with 2,794 additions and 3,204 deletions.
61 changes: 51 additions & 10 deletions theme/app/components/Page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import type { PageLoader } from '@myst-theme/common';
import { DEFAULT_NAV_HEIGHT, Navigation, SkipToArticle, useTocHeight } from '@myst-theme/site';
import {
ConfigurablePrimaryNavigation,
DEFAULT_NAV_HEIGHT,
SkipTo,
useSidebarHeight,
} from '@myst-theme/site';
import {
SiteProvider,
TabStateProvider,
UiStateProvider,
useBaseurl,
useSiteManifest,
useThemeTop,
} from '@myst-theme/providers';
import { getProjectHeadings } from '@myst-theme/common';
import { MadeWithMyst } from '@myst-theme/icons';
import { BusyScopeProvider, ExecuteScopeProvider, useComputeOptions } from '@myst-theme/jupyter';
import Logo from './logo-icon.svg';
import JupyterLogo from './jupyter.svg';
Expand Down Expand Up @@ -102,25 +110,47 @@ export function NavigationAndFooter({
children,
tightFooter,
hide_toc,
mobileOnly,
mobileNavOnly,
projectSlug,
siteConfig,
mainSiteConfig,
}: {
children: React.ReactNode;
tightFooter?: boolean;
hide_toc?: boolean;
mobileOnly?: boolean; // do not show the TOC/Headings inline on the page
mobileNavOnly?: boolean; // only show the hamburger menu at `lg` and below
projectSlug?: string;
siteConfig?: SiteManifest;
mainSiteConfig?: SiteManifest;
}) {
const siteConfigDefault = useSiteManifest();
const top = useThemeTop();
const { container, toc } = useTocHeight<HTMLDivElement>(top);
const { container, toc: sidebar } = useSidebarHeight<HTMLDivElement>(top);

const localSiteConfig = useSiteManifest();
if (!localSiteConfig && !mainSiteConfig) return null;
const { nav } = mainSiteConfig ?? localSiteConfig ?? {};

let headings = undefined;
if (projectSlug && localSiteConfig) {
headings = getProjectHeadings(localSiteConfig, projectSlug, {
addGroups: false,
});
}

return (
<UiStateProvider>
<SkipToArticle frontmatter={false} />
<SiteProvider config={siteConfig ?? siteConfigDefault}>
<TopNav hide_toc={hide_toc} />
<SkipTo targets={[{ id: 'skip-to-article', title: 'Skip To Article' }]} />
<SiteProvider config={mainSiteConfig ?? localSiteConfig}>
<TopNav hide_toc={hide_toc} mobileNavOnly={mobileNavOnly} />
</SiteProvider>
<Navigation tocRef={toc} hide_toc={hide_toc} projectSlug={projectSlug} />
<ConfigurablePrimaryNavigation
sidebarRef={sidebar}
hide_toc={hide_toc}
nav={nav}
headings={headings}
footer={<MadeWithMyst />}
mobileOnly={mobileNavOnly || mobileOnly}
/>
<div
ref={container}
style={{ minHeight: `calc(100vh - ${top + 200}px)`, marginTop: DEFAULT_NAV_HEIGHT }}
Expand Down Expand Up @@ -160,14 +190,25 @@ export function ArticleAndNavigation({
children,
header,
hide_toc,
mobileOnly,
mobileNavOnly,
projectSlug,
}: {
header?: React.ReactNode;
children: React.ReactNode;
hide_toc?: boolean;
mobileOnly?: boolean; // do not show the TOC/Headings inline on the page
mobileNavOnly?: boolean; // only show the hamburger menu at `lg` and below
projectSlug?: string;
}) {
const top = useThemeTop();
return (
<NavigationAndFooter hide_toc={hide_toc}>
<NavigationAndFooter
hide_toc={hide_toc}
mobileOnly={mobileOnly}
mobileNavOnly={mobileNavOnly}
projectSlug={projectSlug}
>
{header}
<TabStateProvider>
<article style={{ minHeight: `calc(100vh - ${top}px)` }}>{children}</article>
Expand Down
15 changes: 13 additions & 2 deletions theme/app/components/TopNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,13 @@ function ThemeTag() {

const knownProjects = new Set(['guide', 'spec', 'jtex', 'thebe']);

export function TopNav({ hide_toc }: { hide_toc?: boolean }) {
export function TopNav({
hide_toc,
mobileNavOnly,
}: {
hide_toc?: boolean;
mobileNavOnly?: boolean;
}) {
const [open, setOpen] = useNavOpen();
const config = useSiteManifest();
const { nav } = config ?? {};
Expand All @@ -223,7 +229,12 @@ export function TopNav({ hide_toc }: { hide_toc?: boolean }) {
<nav className="flex flex-wrap items-center justify-between">
<div className="flex flex-row items-center justify-start mr-2 sm:mr-7">
{!hide_toc && (
<div className="block xl:hidden">
<div
className={classNames('block', {
'xl:hidden': !mobileNavOnly,
'lg:hidden': mobileNavOnly,
})}
>
<button
className="flex items-center text-stone-600 hover:text-black"
onClick={() => {
Expand Down
4 changes: 2 additions & 2 deletions theme/app/routes/$project.($slug).tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ export default function Page() {
<FrontmatterBlock
kind={article.kind}
frontmatter={article.frontmatter}
className="pt-5"
className="pt-9"
/>
<div
className="sticky z-10 hidden h-0 pt-2 ml-10 col-margin-right lg:block"
className="sticky z-10 hidden h-0 pt-5 ml-10 col-margin-right lg:block"
style={{ top }}
>
<DocumentOutline top={16} className="relative lg:block" outlineRef={outline} />
Expand Down
7 changes: 2 additions & 5 deletions theme/app/routes/$project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ export default function LandingPage() {
return (
<BaseUrlProvider baseurl={`/${project}`}>
<SiteProvider config={config}>
<NavigationAndFooter
projectSlug={config?.projects?.[0].slug}
siteConfig={siteConfig as any}
>
<NavigationAndFooter projectSlug={project} mainSiteConfig={siteConfig as any}>
<Outlet />
</NavigationAndFooter>
</SiteProvider>
Expand All @@ -40,7 +37,7 @@ export default function LandingPage() {

export function CatchBoundary() {
return (
<NavigationAndFooter hide_toc>
<NavigationAndFooter mobileOnly>
<Error404 />
</NavigationAndFooter>
);
Expand Down
4 changes: 2 additions & 2 deletions theme/app/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default function LandingPage() {
const article = useLoaderData<PageLoader>() as PageLoader;
(article.frontmatter as any).options = { hide_title_block: true, hide_footer_links: true };
return (
<ArticleAndNavigation header={<HeaderSection />} hide_toc>
<ArticleAndNavigation header={<HeaderSection />} mobileNavOnly>
<ProjectProvider>
<ComputeOptionsProvider
features={{ notebookCompute: true, figureCompute: true, launchBinder: false }}
Expand All @@ -52,7 +52,7 @@ export default function LandingPage() {

export function CatchBoundary() {
return (
<NavigationAndFooter hide_toc>
<NavigationAndFooter mobileOnly>
<Error404 />
</NavigationAndFooter>
);
Expand Down
12 changes: 6 additions & 6 deletions theme/app/routes/overview.($slug).tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { getPage } from '../utils/loaders.server';
import { NavLink, useLoaderData } from '@remix-run/react';
import { ArticleAndNavigation, NavigationAndFooter } from '../components/Page';
import { BaseUrlProvider, ProjectProvider, useSiteManifest } from '@myst-theme/providers';
import classNames from 'classnames';
import { Error404 } from '../components/Error404';
import { ArticlePage } from '~/components/ArticlePage';
import classNames from 'classnames';

const baseurl = 'overview';

Expand Down Expand Up @@ -38,8 +38,8 @@ export default function ContentPage() {
const article = useLoaderData<PageLoader>() as PageLoader;
(article as any).frontmatter.options = { hide_title_block: true, hide_footer_links: true };
return (
<ArticleAndNavigation hide_toc>
<BaseUrlProvider baseurl={`/${baseurl}`}>
<BaseUrlProvider baseurl={`/${baseurl}`}>
<ArticleAndNavigation mobileNavOnly>
<ProjectProvider>
<ComputeOptionsProvider
features={{ notebookCompute: true, figureCompute: true, launchBinder: false }}
Expand All @@ -48,7 +48,7 @@ export default function ContentPage() {
<main className="article article-grid grid-gap py-[100px]">
<h1 className="text-center">{article.frontmatter.title}</h1>
<div className="col-body-outset">
<div className="border-y border-gray-200 py-3 my-[100px] flex flex-row justify-around">
<div className="flex flex-row justify-around py-3 mt-12 mb-20 border-gray-200 border-y">
{site?.projects?.[0].pages
.filter((p) => 'slug' in p)
.map((p) => {
Expand All @@ -74,8 +74,8 @@ export default function ContentPage() {
</ThebeLoaderAndServer>
</ComputeOptionsProvider>
</ProjectProvider>
</BaseUrlProvider>
</ArticleAndNavigation>
</ArticleAndNavigation>
</BaseUrlProvider>
);
}

Expand Down
8 changes: 4 additions & 4 deletions theme/app/routes/sandbox.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FrontmatterBlock } from '@myst-theme/frontmatter';
import { getMetaTagsForArticle , ProjectPageCatchBoundary } from '@myst-theme/site';
import { getMetaTagsForArticle, ProjectPageCatchBoundary } from '@myst-theme/site';
import { ArticleAndNavigation, NavigationAndFooter } from '../components/Page';
import { TabStateProvider, UiStateProvider } from '@myst-theme/providers';
import { MySTRenderer } from 'myst-demo';
Expand Down Expand Up @@ -48,8 +48,8 @@ export const loader: LoaderFunction = async ({ request }) => {
const url = new URL(request.url);
const myst = url.searchParams.get('myst');
const tab = url.searchParams.get('tab');
const srcURL = url.searchParams.get("url");
const srcURL = url.searchParams.get('url');

let data;
if (srcURL) {
const response = await fetch(srcURL);
Expand Down Expand Up @@ -163,7 +163,7 @@ export default function ContentPage() {
}, [tab]);

return (
<NavigationAndFooter tightFooter hide_toc>
<NavigationAndFooter tightFooter mobileNavOnly>
<TabStateProvider>
<UiStateProvider>
<main className="relative p-0 article">
Expand Down
Loading

0 comments on commit 84c9a25

Please sign in to comment.