Skip to content

Commit

Permalink
fix: allow full-width TOC when sidebar is useable
Browse files Browse the repository at this point in the history
  • Loading branch information
agoose77 committed Jul 31, 2024
1 parent 2778ea6 commit fd76852
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 8 deletions.
10 changes: 8 additions & 2 deletions packages/providers/src/ui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ import { useMediaQuery } from './hooks.js';

type UiState = {
isNavOpen?: boolean;
isWide?: boolean;
};

type UiContextType = [UiState, (state: UiState) => void];

const UiContext = createContext<UiContextType | undefined>(undefined);
export const UiContext = createContext<UiContextType | undefined>(undefined);

// Create a provider for components to consume and subscribe to changes
export function UiStateProvider({ children }: { children: React.ReactNode }) {
// Close the nav
const wide = useMediaQuery('(min-width: 1280px)');
const [state, setState] = useState<UiState>({ isNavOpen: false });
useEffect(() => {
if (wide) setState({ ...state, isNavOpen: false });
if (wide) setState({ ...state, isNavOpen: false, isWide: wide });
}, [wide]);
return <UiContext.Provider value={[state, setState]}>{children}</UiContext.Provider>;
}
Expand All @@ -28,3 +29,8 @@ export function useNavOpen(): [boolean, (open: boolean) => void] {
};
return [state?.isNavOpen ?? false, setOpen];
}

export function isWide(): boolean {
const [state, _] = useContext(UiContext) ?? [];

Check warning on line 34 in packages/providers/src/ui.tsx

View workflow job for this annotation

GitHub Actions / lint

'_' is assigned a value but never used
return state?.isWide ?? false;
}
11 changes: 8 additions & 3 deletions packages/site/src/components/Navigation/TableOfContents.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { useEffect, useRef } from 'react';
import React, { useEffect, useRef, useContext } from 'react';
import classNames from 'classnames';
import { useNavigation } from '@remix-run/react';
import {
useNavOpen,
useSiteManifest,
useGridSystemProvider,
useThemeTop,
isWide,
} from '@myst-theme/providers';
import { getProjectHeadings } from '@myst-theme/common';
import { Toc } from './TableOfContentsItems.js';
Expand All @@ -14,11 +15,15 @@ export function useTocHeight<T extends HTMLElement = HTMLElement>(top = 0, inset
const container = useRef<T>(null);
const toc = useRef<HTMLDivElement>(null);
const transitionState = useNavigation().state;
const wide = isWide();
const setHeight = () => {
if (!container.current || !toc.current) return;
const height = container.current.offsetHeight - window.scrollY;
const div = toc.current.firstChild as HTMLDivElement;
if (div) div.style.height = `min(calc(100vh - ${top}px), ${height + inset}px)`;
if (div)
div.style.height = wide
? `min(calc(100vh - ${top}px), ${height + inset}px)`
: `calc(100vh - ${top}px)`;
const nav = toc.current.querySelector('nav');
if (nav) nav.style.opacity = height > 150 ? '1' : '0';
};
Expand All @@ -30,7 +35,7 @@ export function useTocHeight<T extends HTMLElement = HTMLElement>(top = 0, inset
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [container, toc, transitionState]);
}, [container, toc, transitionState, wide]);
return { container, toc };
}

Expand Down
28 changes: 25 additions & 3 deletions themes/book/app/routes/$.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const loader: LoaderFunction = async ({ params, request }) => {
return json({ config, page, project });
};

export function ArticlePageAndNavigation({
function ArticlePageAndNavigationInternal({
children,
hide_toc,
projectSlug,
Expand All @@ -85,7 +85,7 @@ export function ArticlePageAndNavigation({
const top = useThemeTop();
const { container, toc } = useTocHeight(top, inset);
return (
<UiStateProvider>
<>
<TopNav />
<Navigation
tocRef={toc}
Expand All @@ -102,10 +102,32 @@ export function ArticlePageAndNavigation({
{children}
</article>
</TabStateProvider>
</UiStateProvider>
</>
);
}

export function ArticlePageAndNavigation({
children,
hide_toc,
projectSlug,
inset = 20, // begin text 20px from the top (aligned with menu)
}: {
hide_toc?: boolean;
projectSlug?: string;
children: React.ReactNode;
inset?: number;
}) {
return (
<UiStateProvider>
<ArticlePageAndNavigationInternal
children={children}
hide_toc={hide_toc}
projectSlug={projectSlug}
inset={inset}
/>
</UiStateProvider>
);
}

export default function Page() {
const { container } = useOutlineHeight();
Expand Down

0 comments on commit fd76852

Please sign in to comment.