diff --git a/website/src/css/customTheme.scss b/website/src/css/customTheme.scss index 269bf2a7939..ee5b1fc708b 100644 --- a/website/src/css/customTheme.scss +++ b/website/src/css/customTheme.scss @@ -754,6 +754,43 @@ html[data-theme="dark"] .homepage { /* Blog */ +// Compact multi-author blog grid: two columns (one on the smallest screens), +// capped to a narrow width on desktop rather than spanning the content. +.col--6[class*="authorCol"] { + --ifm-avatar-intro-margin: 0.7rem; + + flex: 0 0 50%; + + @media (max-width: 768px) { + flex: 0 0 100%; + } + + [class*="authorImage"] { + --ifm-avatar-photo-size: 1.75rem; + } + + [class*="authorName"] { + font-size: 0.9rem; + } + + [class*="authorTitle"] { + font-size: 0.75rem; + + // Don't truncate long titles. + display: block; + overflow: visible; + line-clamp: none; + -webkit-line-clamp: none; + } +} + +// Cap the grid on desktop only; tablet keeps the full-width two columns. +@media (min-width: 997px) { + .row:has(> [class*="authorCol"]) { + max-width: 560px; + } +} + .avatar__name { font-weight: 600; display: inline-flex; diff --git a/website/src/theme/BlogLayout/index.tsx b/website/src/theme/BlogLayout/index.tsx index 7bb44c0730c..c64158dcbac 100644 --- a/website/src/theme/BlogLayout/index.tsx +++ b/website/src/theme/BlogLayout/index.tsx @@ -9,30 +9,52 @@ import type {Props} from '@theme/BlogLayout'; import React from 'react'; import clsx from 'clsx'; +import {useLocation} from '@docusaurus/router'; import Layout from '@theme/Layout'; import BlogSidebar from '@theme/BlogSidebar'; import DocsSecondaryNav from '@site/src/components/DocsSecondaryNav'; +import styles from './styles.module.css'; + +// Individual posts live under a dated path; the index, pagination, tags, +// archive and authors routes are the list-style pages that keep the sidebar. +function useIsBlogPost() { + const {pathname} = useLocation(); + return ( + pathname !== '/blog' && + pathname !== '/blog/' && + !pathname.startsWith('/blog/page/') && + !pathname.startsWith('/blog/tags') && + !pathname.startsWith('/blog/archive') && + !pathname.startsWith('/blog/authors') + ); +} + // Ejected from @docusaurus/theme-classic to render the shared secondary nav // full-width below the main navbar, above the blog content. export default function BlogLayout(props: Props) { const {sidebar, toc, children, ...layoutProps} = props; - const hasSidebar = sidebar && sidebar.items.length > 0; + const isBlogPost = useIsBlogPost(); + // Individual posts drop the recent-posts sidebar and center their content. + const showSidebar = !isBlogPost && sidebar && sidebar.items.length > 0; + + let mainClassName; + if (isBlogPost) { + mainClassName = clsx('col', styles.blogPostMain); + } else if (showSidebar) { + mainClassName = clsx('col', 'col--7'); + } else { + mainClassName = clsx('col', 'col--9', 'col--offset-1'); + } return (
- -
- {children} -
- {toc &&
{toc}
} + {showSidebar && } +
{children}
+ {toc &&
{toc}
}
diff --git a/website/src/theme/BlogLayout/styles.module.css b/website/src/theme/BlogLayout/styles.module.css new file mode 100644 index 00000000000..f1bb5e7eab3 --- /dev/null +++ b/website/src/theme/BlogLayout/styles.module.css @@ -0,0 +1,19 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.blogPostMain { + max-width: 800px; + padding-block: 24px; + margin-inline: auto; +} + +@media (min-width: 997px) { + .tocColumn { + flex: 0 0 200px; + max-width: 200px; + } +}