Skip to content

Commit

Permalink
🎑 General theme improvements for Article Theme (#203)
Browse files Browse the repository at this point in the history
- Remove the minimum height from the banner
- Allow document outline to have children
- Add supporting documents export from MyST Site
- Change height calculation for `useOutlineHeight` for container offset
  • Loading branch information
rowanc1 authored Aug 9, 2023
1 parent f8ab986 commit 4701ce8
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .changeset/calm-socks-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@myst-theme/site': patch
---

Change height intersect calculation for `useOutlineHeight` to include container offset.
6 changes: 6 additions & 0 deletions .changeset/eleven-pugs-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@myst-theme/article': patch
'@myst-theme/site': patch
---

Add supporting documents export from MyST Site
5 changes: 5 additions & 0 deletions .changeset/flat-spoons-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@myst-theme/site': patch
---

Allow document outline to have children
6 changes: 6 additions & 0 deletions .changeset/friendly-flowers-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@myst-theme/article': patch
'@myst-theme/site': patch
---

Remove the minimum height from the banner
62 changes: 58 additions & 4 deletions packages/site/src/components/DocumentOutline.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import {
useBaseurl,
useNavLinkProvider,
useSiteManifest,
withBaseurl,
} from '@myst-theme/providers';
import { useNavigation } from '@remix-run/react';
import classNames from 'classnames';
import throttle from 'lodash.throttle';
import { useCallback, useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import DocumentChartBarIcon from '@heroicons/react/24/outline/DocumentChartBarIcon';

const SELECTOR = [1, 2, 3, 4].map((n) => `main h${n}`).join(', ');
const HIGHLIGHT_CLASS = 'highlight';
Expand Down Expand Up @@ -180,13 +187,15 @@ const useIntersectionObserver = (highlight: () => void, onScreen: Set<HTMLHeadin
return { observer };
};

export function useOutlineHeight<T extends HTMLElement = HTMLElement>() {
export function useOutlineHeight<T extends HTMLElement = HTMLElement>(
existingContainer?: React.RefObject<T>,
) {
const container = useRef<T>(null);
const outline = useRef<T>(null);
const transitionState = useNavigation().state;
const setHeight = () => {
if (!container.current || !outline.current) return;
const height = container.current.offsetHeight - window.scrollY;
const height = container.current.offsetHeight - window.scrollY + container.current.offsetTop;
outline.current.style.display = height < 50 ? 'none' : '';
outline.current.style.height = height > window.innerHeight ? '' : `${height}px`;
outline.current.style.opacity = height && height > 300 ? '' : '0';
Expand All @@ -201,6 +210,11 @@ export function useOutlineHeight<T extends HTMLElement = HTMLElement>() {
window.removeEventListener('scroll', handleScroll);
};
}, [container.current, outline.current, transitionState]);

useEffect(() => {
if (!existingContainer || !existingContainer.current) return;
(container as any).current = existingContainer.current;
}, [existingContainer?.current]);
return { container, outline };
}

Expand All @@ -209,16 +223,18 @@ export const DocumentOutline = ({
top,
className,
selector = SELECTOR,
children,
}: {
outlineRef?: React.RefObject<HTMLElement>;
top?: number;
height?: number;
className?: string;
selector?: string;
children?: React.ReactNode;
}) => {
const { activeId, headings, highlight } = useHeaders(selector);
if (headings.length <= 1 || !onClient) {
return <nav suppressHydrationWarning style={{ display: 'none' }} />;
return <nav suppressHydrationWarning>{children}</nav>;
}
return (
<nav
Expand All @@ -238,6 +254,44 @@ export const DocumentOutline = ({
In this article
</div>
<Headings headings={headings} activeId={activeId} highlight={highlight} selector={selector} />
{children}
</nav>
);
};

export function SupportingDocuments() {
const { projects } = useSiteManifest() ?? {};
const NavLink = useNavLinkProvider();
const baseurl = useBaseurl();
const pages = projects?.[0]?.pages;
if (!pages || pages.length === 0) return null;
return (
<>
<div className="my-4 text-sm leading-6 uppercase text-slate-900 dark:text-slate-100">
Supporting Documents
</div>
<ul className="flex flex-col gap-2 pl-0 text-sm leading-6 list-none text-slate-700 dark:text-slate-300">
{pages
.filter((p) => 'slug' in p)
.map((p) => {
return (
<li key={p.slug}>
<NavLink
to={withBaseurl(`/${p.slug}#main`, baseurl)}
prefetch="intent"
className={({ isActive }) =>
classNames('no-underline flex self-center', {
'text-blue-600': isActive,
})
}
>
<DocumentChartBarIcon className="inline h-5 pr-2 shrink-0" />
<span>{p.short_title || p.title}</span>
</NavLink>
</li>
);
})}
</ul>
</>
);
}
2 changes: 1 addition & 1 deletion packages/site/src/components/Headers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function ArticleHeader({
'subgrid-gap',
{
'bg-no-repeat bg-cover bg-top': frontmatter?.banner,
'pb-[4rem] min-h-[300px]': frontmatter?.banner,
'pb-[4rem]': frontmatter?.banner,
},
className,
)}
Expand Down
4 changes: 2 additions & 2 deletions packages/site/src/components/Navigation/TableOfContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export const TableOfContents = ({
footer,
}: {
top?: number;
tocRef?: React.RefObject<HTMLDivElement>;
tocRef?: React.RefObject<HTMLElement>;
projectSlug?: string;
footer?: React.ReactNode;
}) => {
Expand All @@ -162,7 +162,7 @@ export const TableOfContents = ({
if (!headings) return null;
return (
<div
ref={tocRef}
ref={tocRef as any}
className={classNames(
'fixed',
`xl:${grid}`, // for example, xl:article-grid
Expand Down
2 changes: 1 addition & 1 deletion packages/site/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { ContentBlocks } from './ContentBlocks';
export { DocumentOutline, useOutlineHeight } from './DocumentOutline';
export { DocumentOutline, useOutlineHeight, SupportingDocuments } from './DocumentOutline';
export { FooterLinksBlock } from './FooterLinksBlock';
export { ContentReload } from './ContentReload';
export { Bibliography } from './Bibliography';
Expand Down
34 changes: 4 additions & 30 deletions themes/article/app/routes/$.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ArticlePageCatchBoundary,
DocumentOutline,
ArticleHeader,
SupportingDocuments,
} from '@myst-theme/site';
import { FrontmatterBlock } from '@myst-theme/frontmatter';
import ArrowLeftIcon from '@heroicons/react/24/outline/ArrowLeftIcon';
Expand Down Expand Up @@ -150,36 +151,9 @@ export function 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 top={0} className="relative lg:block" />
{projects?.[0]?.pages && projects?.[0]?.pages.length > 0 && (
<>
<div className="mt-4 text-sm leading-6 uppercase text-slate-900 dark:text-slate-100">
Supporting Documents
</div>
<ul className="pl-0 text-sm leading-6 list-none text-slate-400">
{projects?.[0]?.pages
.filter((p) => 'slug' in p)
.map((p) => {
return (
<li key={p.slug}>
<NavLink
to={withBaseurl(`/${p.slug}#main`, baseurl)}
prefetch="intent"
className={({ isActive }) =>
classNames('no-underline flex self-center', {
'text-blue-600': isActive,
})
}
>
<DocumentChartBarIcon className="inline h-5 pr-2 shrink-0" />
<span>{p.title}</span>
</NavLink>
</li>
);
})}
</ul>
</>
)}
<DocumentOutline top={0} className="relative">
<SupportingDocuments />
</DocumentOutline>
</div>
)}
{abstract && (
Expand Down

0 comments on commit 4701ce8

Please sign in to comment.