diff options
Diffstat (limited to 'examples/docs/src')
18 files changed, 225 insertions, 162 deletions
diff --git a/examples/docs/src/components/Footer/AvatarList.astro b/examples/docs/src/components/Footer/AvatarList.astro index e5880a03a..5926936d6 100644 --- a/examples/docs/src/components/Footer/AvatarList.astro +++ b/examples/docs/src/components/Footer/AvatarList.astro @@ -1,12 +1,23 @@ --- // fetch all commits for just this page's path -const path = 'docs/' + Astro.props.path; -const url = `https://api.github.com/repos/withastro/astro/commits?path=${path}`; -const commitsURL = `https://github.com/withastro/astro/commits/main/${path}`; - -async function getCommits(url) { +type Props = { + path: string; +}; +const { path } = Astro.props as Props; +const resolvedPath = `examples/docs/${path}`; +const url = `https://api.github.com/repos/withastro/astro/commits?path=${resolvedPath}`; +const commitsURL = `https://github.com/withastro/astro/commits/main/${resolvedPath}`; + +type Commit = { + author: { + id: string; + login: string; + }; +}; + +async function getCommits(url: string) { try { - const token = import.meta.env.SNOWPACK_PUBLIC_GITHUB_TOKEN; + const token = import.meta.env.SNOWPACK_PUBLIC_GITHUB_TOKEN ?? 'hello'; if (!token) { throw new Error( 'Cannot find "SNOWPACK_PUBLIC_GITHUB_TOKEN" used for escaping rate-limiting.' @@ -32,27 +43,24 @@ async function getCommits(url) { ); } - return data; + return data as Commit[]; } catch (e) { console.warn(`[error] /src/components/AvatarList.astro - ${e?.message ?? e}`); - return new Array(); + ${(e as any)?.message ?? e}`); + return [] as Commit[]; } } -function removeDups(arr) { - if (!arr) { - return new Array(); - } - let map = new Map(); +function removeDups(arr: Commit[]) { + const map = new Map<string, Commit['author']>(); for (let item of arr) { - let author = item.author; + const author = item.author; // Deduplicate based on author.id map.set(author.id, { login: author.login, id: author.id }); } - return Array.from(map.values()); + return [...map.values()]; } const data = await getCommits(url); diff --git a/examples/docs/src/components/Footer/Footer.astro b/examples/docs/src/components/Footer/Footer.astro index d13f832e5..1ec756b86 100644 --- a/examples/docs/src/components/Footer/Footer.astro +++ b/examples/docs/src/components/Footer/Footer.astro @@ -1,16 +1,19 @@ --- import AvatarList from './AvatarList.astro'; -const { path } = Astro.props; +type Props = { + path: string; +}; +const { path } = Astro.props as Props; --- <footer> - <AvatarList {path} /> + <AvatarList path={path} /> </footer> <style> footer { margin-top: auto; - padding: 2rem 0; + padding: 2rem; border-top: 3px solid var(--theme-divider); } </style> diff --git a/examples/docs/src/components/HeadSEO.astro b/examples/docs/src/components/HeadSEO.astro index 75d17bea1..c40e04327 100644 --- a/examples/docs/src/components/HeadSEO.astro +++ b/examples/docs/src/components/HeadSEO.astro @@ -1,35 +1,32 @@ --- -import { SITE, OPEN_GRAPH } from '../config'; +import { SITE, OPEN_GRAPH, Frontmatter } from '../config'; + export interface Props { - frontmatter: any; - site: any; - canonicalURL: URL | string; + frontmatter: Frontmatter; + canonicalUrl: URL; } -const canonicalURL = new URL(Astro.url.pathname, Astro.site); -const { frontmatter = {} } = Astro.props; -const formattedContentTitle = frontmatter.title - ? `${frontmatter.title} 🚀 ${SITE.title}` - : SITE.title; -const imageSrc = frontmatter?.image?.src ?? OPEN_GRAPH.image.src; +const { frontmatter, canonicalUrl } = Astro.props as Props; +const formattedContentTitle = `${frontmatter.title} 🚀 ${SITE.title}`; +const imageSrc = frontmatter.image?.src ?? OPEN_GRAPH.image.src; const canonicalImageSrc = new URL(imageSrc, Astro.site); -const imageAlt = frontmatter?.image?.alt ?? OPEN_GRAPH.image.alt; +const imageAlt = frontmatter.image?.alt ?? OPEN_GRAPH.image.alt; --- <!-- Page Metadata --> -<link rel="canonical" href={canonicalURL} /> +<link rel="canonical" href={canonicalUrl} /> <!-- OpenGraph Tags --> <meta property="og:title" content={formattedContentTitle} /> <meta property="og:type" content="article" /> -<meta property="og:url" content={canonicalURL} /> +<meta property="og:url" content={canonicalUrl} /> <meta property="og:locale" content={frontmatter.ogLocale ?? SITE.defaultLanguage} /> <meta property="og:image" content={canonicalImageSrc} /> <meta property="og:image:alt" content={imageAlt} /> <meta name="description" property="og:description" - content={frontmatter.description ? frontmatter.description : SITE.description} + content={frontmatter.description ?? SITE.description} /> <meta property="og:site_name" content={SITE.title} /> @@ -37,10 +34,7 @@ const imageAlt = frontmatter?.image?.alt ?? OPEN_GRAPH.image.alt; <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:site" content={OPEN_GRAPH.twitter} /> <meta name="twitter:title" content={formattedContentTitle} /> -<meta - name="twitter:description" - content={frontmatter.description ? frontmatter.description : SITE.description} -/> +<meta name="twitter:description" content={frontmatter.description ?? SITE.description} /> <meta name="twitter:image" content={canonicalImageSrc} /> <meta name="twitter:image:alt" content={imageAlt} /> diff --git a/examples/docs/src/components/Header/AstroLogo.astro b/examples/docs/src/components/Header/AstroLogo.astro index 840cbf139..6c8b5b9ce 100644 --- a/examples/docs/src/components/Header/AstroLogo.astro +++ b/examples/docs/src/components/Header/AstroLogo.astro @@ -1,5 +1,8 @@ --- -const { size } = Astro.props; +type Props = { + size: number; +}; +const { size } = Astro.props as Props; --- <svg @@ -14,6 +17,7 @@ const { size } = Astro.props; #flame { fill: var(--theme-text-accent); } + #a { fill: var(--theme-text-accent); } @@ -24,11 +28,13 @@ const { size } = Astro.props; fill-rule="evenodd" clip-rule="evenodd" d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z" - ></path> + > + </path> <path id="flame" fill-rule="evenodd" clip-rule="evenodd" d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z" - ></path> + > + </path> </svg> diff --git a/examples/docs/src/components/Header/Header.astro b/examples/docs/src/components/Header/Header.astro index 2e66300b4..bada732a6 100644 --- a/examples/docs/src/components/Header/Header.astro +++ b/examples/docs/src/components/Header/Header.astro @@ -7,8 +7,12 @@ import SidebarToggle from './SidebarToggle'; import LanguageSelect from './LanguageSelect'; import Search from './Search'; -const { currentPage } = Astro.props; -const lang = currentPage && getLanguageFromURL(currentPage); +type Props = { + currentPage: string; +}; + +const { currentPage } = Astro.props as Props; +const lang = getLanguageFromURL(currentPage); --- <header> @@ -25,11 +29,9 @@ const lang = currentPage && getLanguageFromURL(currentPage); </div> <div style="flex-grow: 1;"></div> {KNOWN_LANGUAGE_CODES.length > 1 && <LanguageSelect lang={lang} client:idle />} - {CONFIG.ALGOLIA && ( - <div class="search-item"> - <Search client:idle /> - </div> - )} + <div class="search-item"> + <Search client:idle /> + </div> </nav> </header> @@ -101,14 +103,17 @@ const lang = currentPage && getLanguageFromURL(currentPage); position: static; padding: 2rem 0rem; } + .logo { width: auto; margin: 0; z-index: 0; } + .logo h1 { display: initial; } + .menu-toggle { display: none; } @@ -129,9 +134,11 @@ const lang = currentPage && getLanguageFromURL(currentPage); display: flex; max-width: 200px; } + :global(.search-item > *) { flex-grow: 1; } + @media (min-width: 50em) { .search-item { max-width: 400px; diff --git a/examples/docs/src/components/Header/LanguageSelect.tsx b/examples/docs/src/components/Header/LanguageSelect.tsx index a895cc7cc..3c0244e0d 100644 --- a/examples/docs/src/components/Header/LanguageSelect.tsx +++ b/examples/docs/src/components/Header/LanguageSelect.tsx @@ -1,11 +1,11 @@ -import type { FunctionalComponent } from 'preact'; -import { h } from 'preact'; +/** @jsxImportSource react */ +import type { FunctionComponent } from 'react'; import './LanguageSelect.css'; import { KNOWN_LANGUAGES, langPathRegex } from '../../languages'; -const LanguageSelect: FunctionalComponent<{ lang: string }> = ({ lang }) => { +const LanguageSelect: FunctionComponent<{ lang: string }> = ({ lang }) => { return ( - <div class="language-select-wrapper"> + <div className="language-select-wrapper"> <svg aria-hidden="true" focusable="false" @@ -25,7 +25,7 @@ const LanguageSelect: FunctionalComponent<{ lang: string }> = ({ lang }) => { /> </svg> <select - class="language-select" + className="language-select" value={lang} onChange={(e) => { const newLang = e.target.value; @@ -34,9 +34,9 @@ const LanguageSelect: FunctionalComponent<{ lang: string }> = ({ lang }) => { window.location.pathname = '/' + newLang + actualDest; }} > - {Object.keys(KNOWN_LANGUAGES).map((key) => { + {Object.entries(KNOWN_LANGUAGES).map(([key, value]) => { return ( - <option value={KNOWN_LANGUAGES[key]}> + <option value={value}> <span>{key}</span> </option> ); diff --git a/examples/docs/src/components/Header/Search.tsx b/examples/docs/src/components/Header/Search.tsx index b8a4292da..19ff9fa78 100644 --- a/examples/docs/src/components/Header/Search.tsx +++ b/examples/docs/src/components/Header/Search.tsx @@ -1,23 +1,23 @@ -/* jsxImportSource: react */ +/** @jsxImportSource react */ import { useState, useCallback, useRef } from 'react'; -import * as CONFIG from '../../config'; -import '@docsearch/css/dist/style.css'; +import { ALGOLIA } from '../../config'; +import '@docsearch/css'; import './Search.css'; -// @ts-ignore -import * as docSearchReact from '@docsearch/react'; -// @ts-ignore import { createPortal } from 'react-dom'; +import * as docSearchReact from '@docsearch/react'; -export default function Search() { - const DocSearchModal = docSearchReact.DocSearchModal || docSearchReact.default.DocSearchModal; - - const useDocSearchKeyboardEvents = - docSearchReact.useDocSearchKeyboardEvents || docSearchReact.default.useDocSearchKeyboardEvents; +/** FIXME: This is still kinda nasty, but DocSearch is not ESM ready. */ +const DocSearchModal = + docSearchReact.DocSearchModal || (docSearchReact as any).default.DocSearchModal; +const useDocSearchKeyboardEvents = + docSearchReact.useDocSearchKeyboardEvents || + (docSearchReact as any).default.useDocSearchKeyboardEvents; +export default function Search() { const [isOpen, setIsOpen] = useState(false); - const searchButtonRef = useRef(); - const [initialQuery, setInitialQuery] = useState(null); + const searchButtonRef = useRef<HTMLButtonElement>(null); + const [initialQuery, setInitialQuery] = useState(''); const onOpen = useCallback(() => { setIsOpen(true); @@ -73,9 +73,9 @@ export default function Search() { initialQuery={initialQuery} initialScrollY={window.scrollY} onClose={onClose} - indexName={(CONFIG as any).ALGOLIA.indexName} - appId={(CONFIG as any).ALGOLIA.appId} - apiKey={(CONFIG as any).ALGOLIA.apiKey} + indexName={ALGOLIA.indexName} + appId={ALGOLIA.appId} + apiKey={ALGOLIA.apiKey} transformItems={(items) => { return items.map((item) => { // We transform the absolute URL into a relative URL to diff --git a/examples/docs/src/components/Header/SidebarToggle.tsx b/examples/docs/src/components/Header/SidebarToggle.tsx index 2be9dee9a..50a5d93d0 100644 --- a/examples/docs/src/components/Header/SidebarToggle.tsx +++ b/examples/docs/src/components/Header/SidebarToggle.tsx @@ -1,12 +1,12 @@ +/** @jsxImportSource preact */ import type { FunctionalComponent } from 'preact'; -import { h, Fragment } from 'preact'; import { useState, useEffect } from 'preact/hooks'; const MenuToggle: FunctionalComponent = () => { const [sidebarShown, setSidebarShown] = useState(false); useEffect(() => { - const body = document.getElementsByTagName('body')[0]; + const body = document.querySelector('body')!; if (sidebarShown) { body.classList.add('mobile-sidebar-toggle'); } else { diff --git a/examples/docs/src/components/Header/SkipToContent.astro b/examples/docs/src/components/Header/SkipToContent.astro index 9e3844e6f..4d97923f6 100644 --- a/examples/docs/src/components/Header/SkipToContent.astro +++ b/examples/docs/src/components/Header/SkipToContent.astro @@ -1,3 +1,7 @@ +--- +type Props = {}; +--- + <a href="#article" class="sr-only focus:not-sr-only skiplink"><span>Skip to Content</span></a> <style> diff --git a/examples/docs/src/components/LeftSidebar/LeftSidebar.astro b/examples/docs/src/components/LeftSidebar/LeftSidebar.astro index 5ffa73c12..d0fe8da4e 100644 --- a/examples/docs/src/components/LeftSidebar/LeftSidebar.astro +++ b/examples/docs/src/components/LeftSidebar/LeftSidebar.astro @@ -1,44 +1,34 @@ --- import { getLanguageFromURL } from '../../languages'; import { SIDEBAR } from '../../config'; -const { currentPage } = Astro.props; + +type Props = { + currentPage: string; +}; + +const { currentPage } = Astro.props as Props; const currentPageMatch = currentPage.slice(1); const langCode = getLanguageFromURL(currentPage); -// SIDEBAR is a flat array. Group it by sections to properly render. -const sidebarSections = SIDEBAR[langCode].reduce((col, item, i) => { - // If the first item is not a section header, create a new container section. - if (i === 0) { - if (!item.header) { - const pseudoSection = { text: '' }; - col.push({ ...pseudoSection, children: [] }); - } - } - if (item.header) { - col.push({ ...item, children: [] }); - } else { - col[col.length - 1].children.push(item); - } - return col; -}, []); +const sidebar = SIDEBAR[langCode]; --- <nav aria-labelledby="grid-left"> <ul class="nav-groups"> - {sidebarSections.map((section) => ( + {Object.entries(sidebar).map(([header, children]) => ( <li> <div class="nav-group"> - <h2 class="nav-group-title">{section.text}</h2> + <h2>{header}</h2> <ul> - {section.children.map((child) => ( - <li class="nav-link"> - <a - href={`${Astro.site.pathname}${child.link}`} - aria-current={`${currentPageMatch === child.link ? 'page' : 'false'}`} - > - {child.text} - </a> - </li> - ))} + {children.map((child) => { + const url = Astro.site?.pathname + child.link; + return ( + <li class="nav-link"> + <a href={url} aria-current={currentPageMatch === child.link ? 'page' : false}> + {child.text} + </a> + </li> + ); + })} </ul> </div> </li> @@ -47,7 +37,7 @@ const sidebarSections = SIDEBAR[langCode].reduce((col, item, i) => { </nav> <script is:inline> - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('DOMContentLoaded', () => { var target = document.querySelector('[aria-current="page"]'); if (target && target.offsetTop > window.innerHeight - 100) { document.querySelector('.nav-groups').scrollTop = target.offsetTop; @@ -60,6 +50,7 @@ const sidebarSections = SIDEBAR[langCode].reduce((col, item, i) => { width: 100%; margin-right: 1rem; } + .nav-groups { height: 100%; padding: 2rem 0; @@ -98,6 +89,7 @@ const sidebarSections = SIDEBAR[langCode].reduce((col, item, i) => { text-decoration: none; display: block; } + .nav-link a:hover, .nav-link a:focus { background-color: var(--theme-bg-hover); diff --git a/examples/docs/src/components/PageContent/PageContent.astro b/examples/docs/src/components/PageContent/PageContent.astro index 49a74ab70..c7c66c7fc 100644 --- a/examples/docs/src/components/PageContent/PageContent.astro +++ b/examples/docs/src/components/PageContent/PageContent.astro @@ -1,8 +1,16 @@ --- +import type { Frontmatter } from '../../config'; import MoreMenu from '../RightSidebar/MoreMenu.astro'; import TableOfContents from '../RightSidebar/TableOfContents'; +import type { MarkdownHeading } from 'astro'; -const { frontmatter, headings, githubEditUrl } = Astro.props; +type Props = { + frontmatter: Frontmatter; + headings: MarkdownHeading[]; + githubEditUrl: string; +}; + +const { frontmatter, headings, githubEditUrl } = Astro.props as Props; const title = frontmatter.title; --- @@ -10,7 +18,7 @@ const title = frontmatter.title; <section class="main-section"> <h1 class="content-title" id="overview">{title}</h1> <nav class="block sm:hidden"> - <TableOfContents client:media="(max-width: 50em)" {headings} /> + <TableOfContents client:media="(max-width: 50em)" headings={headings} /> </nav> <slot /> </section> diff --git a/examples/docs/src/components/RightSidebar/MoreMenu.astro b/examples/docs/src/components/RightSidebar/MoreMenu.astro index fd1067859..8fcbfa567 100644 --- a/examples/docs/src/components/RightSidebar/MoreMenu.astro +++ b/examples/docs/src/components/RightSidebar/MoreMenu.astro @@ -1,8 +1,13 @@ --- import ThemeToggleButton from './ThemeToggleButton'; import * as CONFIG from '../../config'; -const { editHref } = Astro.props; -const showMoreSection = CONFIG.COMMUNITY_INVITE_URL || editHref; + +type Props = { + editHref: string; +}; + +const { editHref } = Astro.props as Props; +const showMoreSection = CONFIG.COMMUNITY_INVITE_URL; --- {showMoreSection && <h2 class="heading">More</h2>} diff --git a/examples/docs/src/components/RightSidebar/RightSidebar.astro b/examples/docs/src/components/RightSidebar/RightSidebar.astro index 6144ed928..d45fbd494 100644 --- a/examples/docs/src/components/RightSidebar/RightSidebar.astro +++ b/examples/docs/src/components/RightSidebar/RightSidebar.astro @@ -1,12 +1,19 @@ --- import TableOfContents from './TableOfContents'; import MoreMenu from './MoreMenu.astro'; -const { headings, githubEditUrl } = Astro.props; +import type { MarkdownHeading } from 'astro'; + +type Props = { + headings: MarkdownHeading[]; + githubEditUrl: string; +}; + +const { headings, githubEditUrl } = Astro.props as Props; --- <nav class="sidebar-nav" aria-labelledby="grid-right"> <div class="sidebar-nav-inner"> - <TableOfContents client:media="(min-width: 50em)" {headings} /> + <TableOfContents client:media="(min-width: 50em)" headings={headings} /> <MoreMenu editHref={githubEditUrl} /> </div> </nav> diff --git a/examples/docs/src/components/RightSidebar/TableOfContents.tsx b/examples/docs/src/components/RightSidebar/TableOfContents.tsx index 6348bdfd0..5c6851462 100644 --- a/examples/docs/src/components/RightSidebar/TableOfContents.tsx +++ b/examples/docs/src/components/RightSidebar/TableOfContents.tsx @@ -1,13 +1,18 @@ import type { FunctionalComponent } from 'preact'; -import { h, Fragment } from 'preact'; import { useState, useEffect, useRef } from 'preact/hooks'; -import { MarkdownHeading } from 'astro'; +import type { MarkdownHeading } from 'astro'; + +type ItemOffsets = { + id: string; + topOffset: number; +}; const TableOfContents: FunctionalComponent<{ headings: MarkdownHeading[] }> = ({ headings = [], }) => { - const itemOffsets = useRef([]); - const [activeId, setActiveId] = useState<string>(undefined); + const itemOffsets = useRef<ItemOffsets[]>([]); + // FIXME: Not sure what this state is doing. It was never set to anything truthy. + const [activeId] = useState<string>(''); useEffect(() => { const getItemOffsets = () => { const titles = document.querySelectorAll('article :is(h1, h2, h3, h4)'); @@ -27,16 +32,16 @@ const TableOfContents: FunctionalComponent<{ headings: MarkdownHeading[] }> = ({ return ( <> - <h2 class="heading">On this page</h2> + <h2 className="heading">On this page</h2> <ul> - <li class={`heading-link depth-2 ${activeId === 'overview' ? 'active' : ''}`.trim()}> + <li className={`heading-link depth-2 ${activeId === 'overview' ? 'active' : ''}`.trim()}> <a href="#overview">Overview</a> </li> {headings .filter(({ depth }) => depth > 1 && depth < 4) .map((heading) => ( <li - class={`heading-link depth-${heading.depth} ${ + className={`heading-link depth-${heading.depth} ${ activeId === heading.slug ? 'active' : '' }`.trim()} > diff --git a/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx b/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx index a3f31288d..b9682aa00 100644 --- a/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx +++ b/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx @@ -1,5 +1,4 @@ import type { FunctionalComponent } from 'preact'; -import { h, Fragment } from 'preact'; import { useState, useEffect } from 'preact/hooks'; import './ThemeToggleButton.css'; @@ -35,7 +34,7 @@ const ThemeToggle: FunctionalComponent = () => { if (import.meta.env.SSR) { return undefined; } - if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) { + if (typeof localStorage !== undefined && localStorage.getItem('theme')) { return localStorage.getItem('theme'); } if (window.matchMedia('(prefers-color-scheme: dark)').matches) { @@ -54,7 +53,7 @@ const ThemeToggle: FunctionalComponent = () => { }, [theme]); return ( - <div class="theme-toggle"> + <div className="theme-toggle"> {themes.map((t, i) => { const icon = icons[i]; const checked = t === theme; diff --git a/examples/docs/src/config.ts b/examples/docs/src/config.ts index b81bf9b4f..b8258b1f7 100644 --- a/examples/docs/src/config.ts +++ b/examples/docs/src/config.ts @@ -14,33 +14,44 @@ export const OPEN_GRAPH = { twitter: 'astrodotbuild', }; +// This is the type of the frontmatter you put in the docs markdown files. +export type Frontmatter = { + title: string; + description: string; + layout: string; + image?: { src: string; alt: string }; + dir?: 'ltr' | 'rtl'; + ogLocale?: string; + lang?: string; +}; + export const KNOWN_LANGUAGES = { English: 'en', -}; +} as const; +export const KNOWN_LANGUAGE_CODES = Object.values(KNOWN_LANGUAGES); -// Uncomment this to add an "Edit this page" button to every page of documentation. -// export const GITHUB_EDIT_URL = `https://github.com/withastro/astro/blob/main/docs/`; +export const GITHUB_EDIT_URL = `https://github.com/withastro/astro/tree/main/examples/docs`; -// Uncomment this to add an "Join our Community" button to every page of documentation. -// export const COMMUNITY_INVITE_URL = `https://astro.build/chat`; +export const COMMUNITY_INVITE_URL = `https://astro.build/chat`; -// Uncomment this to enable site search. // See "Algolia" section of the README for more information. -// export const ALGOLIA = { -// indexName: 'XXXXXXXXXX', -// appId: 'XXXXXXXXXX', -// apiKey: 'XXXXXXXXXX', -// } - -export const SIDEBAR = { - en: [ - { text: '', header: true }, - { text: 'Section Header', header: true }, - { text: 'Introduction', link: 'en/introduction' }, - { text: 'Page 2', link: 'en/page-2' }, - { text: 'Page 3', link: 'en/page-3' }, +export const ALGOLIA = { + indexName: 'XXXXXXXXXX', + appId: 'XXXXXXXXXX', + apiKey: 'XXXXXXXXXX', +}; - { text: 'Another Section', header: true }, - { text: 'Page 4', link: 'en/page-4' }, - ], +export type Sidebar = Record< + typeof KNOWN_LANGUAGE_CODES[number], + Record<string, { text: string; link: string }[]> +>; +export const SIDEBAR: Sidebar = { + en: { + 'Section Header': [ + { text: 'Introduction', link: 'en/introduction' }, + { text: 'Page 2', link: 'en/page-2' }, + { text: 'Page 3', link: 'en/page-3' }, + ], + 'Another Section': [{ text: 'Page 4', link: 'en/page-4' }], + }, }; diff --git a/examples/docs/src/languages.ts b/examples/docs/src/languages.ts index ffc680954..405b6921c 100644 --- a/examples/docs/src/languages.ts +++ b/examples/docs/src/languages.ts @@ -1,10 +1,10 @@ -import { KNOWN_LANGUAGES } from './config'; +import { KNOWN_LANGUAGES, KNOWN_LANGUAGE_CODES } from './config'; +export { KNOWN_LANGUAGES, KNOWN_LANGUAGE_CODES }; -export { KNOWN_LANGUAGES }; -export const KNOWN_LANGUAGE_CODES = Object.values(KNOWN_LANGUAGES); export const langPathRegex = /\/([a-z]{2}-?[A-Z]{0,2})\//; export function getLanguageFromURL(pathname: string) { const langCodeMatch = pathname.match(langPathRegex); - return langCodeMatch ? langCodeMatch[1] : 'en'; + const langCode = langCodeMatch ? langCodeMatch[1] : 'en'; + return langCode as typeof KNOWN_LANGUAGE_CODES[number]; } diff --git a/examples/docs/src/layouts/MainLayout.astro b/examples/docs/src/layouts/MainLayout.astro index 5b35aee18..79a2f81a9 100644 --- a/examples/docs/src/layouts/MainLayout.astro +++ b/examples/docs/src/layouts/MainLayout.astro @@ -6,18 +6,25 @@ import PageContent from '../components/PageContent/PageContent.astro'; import LeftSidebar from '../components/LeftSidebar/LeftSidebar.astro'; import RightSidebar from '../components/RightSidebar/RightSidebar.astro'; import * as CONFIG from '../config'; +import type { MarkdownHeading } from 'astro'; +import Footer from '../components/Footer/Footer.astro'; -const { frontmatter = {}, headings } = Astro.props; +type Props = { + frontmatter: CONFIG.Frontmatter; + headings: MarkdownHeading[]; +}; + +const { frontmatter, headings } = Astro.props as Props; const canonicalURL = new URL(Astro.url.pathname, Astro.site); const currentPage = Astro.url.pathname; const currentFile = `src/pages${currentPage.replace(/\/$/, '')}.md`; -const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + currentFile; +const githubEditUrl = `${CONFIG.GITHUB_EDIT_URL}/${currentFile}`; --- <html dir={frontmatter.dir ?? 'ltr'} lang={frontmatter.lang ?? 'en-us'} class="initial"> <head> <HeadCommon /> - <HeadSEO {frontmatter} canonicalURL={canonicalURL} /> + <HeadSEO frontmatter={frontmatter} canonicalUrl={canonicalURL} /> <title> {frontmatter.title ? `${frontmatter.title} 🚀 ${CONFIG.SITE.title}` : CONFIG.SITE.title} </title> @@ -29,31 +36,36 @@ const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + current --gutter: 0.5rem; --doc-padding: 2rem; } + .layout { display: grid; grid-auto-flow: column; - grid-template-columns: - minmax(var(--gutter), 1fr) - minmax(0, var(--max-width)) - minmax(var(--gutter), 1fr); + grid-template-columns: minmax(var(--gutter), 1fr) minmax(0, var(--max-width)) minmax( + var(--gutter), + 1fr + ); overflow-x: hidden; } + .layout :global(> *) { width: 100%; height: 100%; } + .grid-sidebar { height: 100vh; position: sticky; top: 0; padding: 0; } + #grid-left { position: fixed; background-color: var(--theme-bg); z-index: 10; display: none; } + #grid-main { padding: var(--doc-padding) var(--gutter); grid-column: 2; @@ -61,24 +73,27 @@ const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + current flex-direction: column; height: 100%; } + #grid-right { display: none; } + :global(.mobile-sidebar-toggle) { overflow: hidden; } + :global(.mobile-sidebar-toggle) #grid-left { display: block; top: 2rem; } + @media (min-width: 50em) { .layout { overflow: initial; - grid-template-columns: - 20rem - minmax(0, var(--max-width)); + grid-template-columns: 20rem minmax(0, var(--max-width)); gap: 1em; } + #grid-left { display: flex; padding-left: 2rem; @@ -89,14 +104,12 @@ const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + current @media (min-width: 72em) { .layout { - grid-template-columns: - 20rem - minmax(0, var(--max-width)) - 18rem; + grid-template-columns: 20rem minmax(0, var(--max-width)) 18rem; padding-left: 0; padding-right: 0; margin: 0 auto; } + #grid-right { grid-column: 3; display: flex; @@ -106,19 +119,20 @@ const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + current </head> <body> - <Header {currentPage} /> + <Header currentPage={currentPage} /> <main class="layout"> <aside id="grid-left" class="grid-sidebar" title="Site Navigation"> - <LeftSidebar {currentPage} /> + <LeftSidebar currentPage={currentPage} /> </aside> <div id="grid-main"> - <PageContent {frontmatter} {headings} {githubEditUrl}> + <PageContent frontmatter={frontmatter} headings={headings} githubEditUrl={githubEditUrl}> <slot /> </PageContent> </div> <aside id="grid-right" class="grid-sidebar" title="Table of Contents"> - <RightSidebar {headings} {githubEditUrl} /> + <RightSidebar headings={headings} githubEditUrl={githubEditUrl} /> </aside> </main> + <Footer path={currentFile} /> </body> </html> |