diff options
author | 2023-06-06 11:21:19 -0500 | |
---|---|---|
committer | 2023-06-06 11:21:19 -0500 | |
commit | 5ed2a2f666707e579e18f2890ab89b7cc6f717c3 (patch) | |
tree | 9895d49bc5bd33a63ff0f2e94053e771a54b9dc4 /examples/docs/src/components | |
parent | d5a089810f8218f694ac56591648d36051708560 (diff) | |
download | astro-5ed2a2f666707e579e18f2890ab89b7cc6f717c3.tar.gz astro-5ed2a2f666707e579e18f2890ab89b7cc6f717c3.tar.zst astro-5ed2a2f666707e579e18f2890ab89b7cc6f717c3.zip |
chore: remove docs example (#7306)
Diffstat (limited to 'examples/docs/src/components')
19 files changed, 0 insertions, 1294 deletions
diff --git a/examples/docs/src/components/Footer/AvatarList.astro b/examples/docs/src/components/Footer/AvatarList.astro deleted file mode 100644 index 8d00e0ec6..000000000 --- a/examples/docs/src/components/Footer/AvatarList.astro +++ /dev/null @@ -1,169 +0,0 @@ ---- -// fetch all commits for just this page's path -type Props = { - path: string; -}; -const { path } = Astro.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.GITHUB_TOKEN ?? 'hello'; - if (!token) { - throw new Error('Cannot find "GITHUB_TOKEN" used for escaping rate-limiting.'); - } - - const auth = `Basic ${Buffer.from(token, 'binary').toString('base64')}`; - - const res = await fetch(url, { - method: 'GET', - headers: { - Authorization: auth, - 'User-Agent': 'astro-docs/1.0', - }, - }); - - const data = await res.json(); - - if (!res.ok) { - throw new Error( - `Request to fetch commits failed. Reason: ${res.statusText} - Message: ${data.message}` - ); - } - - return data as Commit[]; - } catch (e) { - console.warn(`[error] /src/components/AvatarList.astro - ${(e as any)?.message ?? e}`); - return [] as Commit[]; - } -} - -function removeDups(arr: Commit[]) { - const map = new Map<string, Commit['author']>(); - - for (let item of arr) { - const author = item.author; - // Deduplicate based on author.id - map.set(author.id, { login: author.login, id: author.id }); - } - - return [...map.values()]; -} - -const data = await getCommits(url); -const unique = removeDups(data); -const recentContributors = unique.slice(0, 3); // only show avatars for the 3 most recent contributors -const additionalContributors = unique.length - recentContributors.length; // list the rest of them as # of extra contributors ---- - -<!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! --> -<div class="contributors"> - <ul class="avatar-list" style={`--avatar-count: ${recentContributors.length}`}> - { - recentContributors.map((item) => ( - <li> - <a href={`https://github.com/${item.login}`}> - <img - alt={`Contributor ${item.login}`} - title={`Contributor ${item.login}`} - width="64" - height="64" - src={`https://avatars.githubusercontent.com/u/${item.id}`} - /> - </a> - </li> - )) - } - </ul> - { - additionalContributors > 0 && ( - <span> - <a href={commitsURL}>{`and ${additionalContributors} additional contributor${ - additionalContributors > 1 ? 's' : '' - }.`}</a> - </span> - ) - } - {unique.length === 0 && <a href={commitsURL}>Contributors</a>} -</div> - -<style> - .avatar-list { - --avatar-size: 2.5rem; - --avatar-count: 3; - - display: grid; - list-style: none; - /* Default to displaying most of the avatar to - enable easier access on touch devices, ensuring - the WCAG touch target size is met or exceeded */ - grid-template-columns: repeat(var(--avatar-count), max(44px, calc(var(--avatar-size) / 1.15))); - /* `padding` matches added visual dimensions of - the `box-shadow` to help create a more accurate - computed component size */ - padding: 0.08em; - font-size: var(--avatar-size); - } - - @media (any-hover: hover) and (any-pointer: fine) { - .avatar-list { - /* We create 1 extra cell to enable the computed - width to match the final visual width */ - grid-template-columns: repeat(calc(var(--avatar-count) + 1), calc(var(--avatar-size) / 1.75)); - } - } - - .avatar-list li { - width: var(--avatar-size); - height: var(--avatar-size); - } - - .avatar-list li:hover ~ li a, - .avatar-list li:focus-within ~ li a { - transform: translateX(33%); - } - - .avatar-list img, - .avatar-list a { - display: block; - border-radius: 50%; - } - - .avatar-list a { - transition: transform 180ms ease-in-out; - } - - .avatar-list img { - width: 100%; - height: 100%; - object-fit: cover; - background-color: #fff; - box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15); - } - - .avatar-list a:focus { - outline: 2px solid transparent; - /* Double-layer trick to work for dark and light backgrounds */ - box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white; - } - - .contributors { - display: flex; - align-items: center; - } - - .contributors > * + * { - margin-left: 0.75rem; - } -</style> diff --git a/examples/docs/src/components/Footer/Footer.astro b/examples/docs/src/components/Footer/Footer.astro deleted file mode 100644 index 8eab03d82..000000000 --- a/examples/docs/src/components/Footer/Footer.astro +++ /dev/null @@ -1,19 +0,0 @@ ---- -import AvatarList from './AvatarList.astro'; -type Props = { - path: string; -}; -const { path } = Astro.props; ---- - -<footer> - <AvatarList path={path} /> -</footer> - -<style> - footer { - margin-top: auto; - padding: 2rem; - border-top: 3px solid var(--theme-divider); - } -</style> diff --git a/examples/docs/src/components/HeadCommon.astro b/examples/docs/src/components/HeadCommon.astro deleted file mode 100644 index d77e4a90c..000000000 --- a/examples/docs/src/components/HeadCommon.astro +++ /dev/null @@ -1,44 +0,0 @@ ---- -import '../styles/theme.css'; -import '../styles/index.css'; ---- - -<!-- Global Metadata --> -<meta charset="utf-8" /> -<meta name="viewport" content="width=device-width" /> -<meta name="generator" content={Astro.generator} /> - -<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> - -<link rel="sitemap" href="/sitemap.xml" /> - -<!-- Preload Fonts --> -<link rel="preconnect" href="https://fonts.googleapis.com" /> -<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> -<link - href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital@0;1&display=swap" - rel="stylesheet" -/> - -<!-- Scrollable a11y code helper --> -<script src="/make-scrollable-code-focusable.js" is:inline></script> - -<!-- This is intentionally inlined to avoid FOUC --> -<script is:inline> - const root = document.documentElement; - const theme = localStorage.getItem('theme'); - if (theme === 'dark' || (!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)) { - root.classList.add('theme-dark'); - } else { - root.classList.remove('theme-dark'); - } -</script> - -<!-- Global site tag (gtag.js) - Google Analytics --> -<!-- <script async src="https://www.googletagmanager.com/gtag/js?id=G-TEL60V1WM9" is:inline></script> -<script> - window.dataLayer = window.dataLayer || []; - function gtag(){dataLayer.push(arguments);} - gtag('js', new Date()); - gtag('config', 'G-TEL60V1WM9'); -</script> --> diff --git a/examples/docs/src/components/HeadSEO.astro b/examples/docs/src/components/HeadSEO.astro deleted file mode 100644 index e8ac787d3..000000000 --- a/examples/docs/src/components/HeadSEO.astro +++ /dev/null @@ -1,40 +0,0 @@ ---- -import type { CollectionEntry } from 'astro:content'; -import { SITE, OPEN_GRAPH } from '../consts'; - -type Props = { canonicalUrl: URL } & CollectionEntry<'docs'>['data']; - -const { ogLocale, image, title, description, canonicalUrl } = Astro.props; -const formattedContentTitle = `${title} 🚀 ${SITE.title}`; -const imageSrc = image?.src ?? OPEN_GRAPH.image.src; -const canonicalImageSrc = new URL(imageSrc, Astro.site); -const imageAlt = image?.alt ?? OPEN_GRAPH.image.alt; ---- - -<!-- Page Metadata --> -<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:locale" content={ogLocale ?? SITE.defaultLanguage} /> -<meta property="og:image" content={canonicalImageSrc} /> -<meta property="og:image:alt" content={imageAlt} /> -<meta name="description" property="og:description" content={description ?? SITE.description} /> -<meta property="og:site_name" content={SITE.title} /> - -<!-- Twitter Tags --> -<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={description ?? SITE.description} /> -<meta name="twitter:image" content={canonicalImageSrc} /> -<meta name="twitter:image:alt" content={imageAlt} /> - -<!-- - TODO: Add json+ld data, maybe https://schema.org/APIReference makes sense? - Docs: https://developers.google.com/search/docs/advanced/structured-data/intro-structured-data - https://www.npmjs.com/package/schema-dts seems like a great resource for implementing this. - Even better, there's a React component that integrates with `schema-dts`: https://github.com/google/react-schemaorg ---> diff --git a/examples/docs/src/components/Header/AstroLogo.astro b/examples/docs/src/components/Header/AstroLogo.astro deleted file mode 100644 index 1363b3e32..000000000 --- a/examples/docs/src/components/Header/AstroLogo.astro +++ /dev/null @@ -1,40 +0,0 @@ ---- -type Props = { - size: number; -}; -const { size } = Astro.props; ---- - -<svg - class="logo" - width={size} - height={size} - viewBox="0 0 256 256" - fill="none" - xmlns="http://www.w3.org/2000/svg" -> - <style> - #flame { - fill: var(--theme-text-accent); - } - - #a { - fill: var(--theme-text-accent); - } - </style> - <title>Logo</title> - <path - id="a" - 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 - 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> -</svg> diff --git a/examples/docs/src/components/Header/Header.astro b/examples/docs/src/components/Header/Header.astro deleted file mode 100644 index 3f578480b..000000000 --- a/examples/docs/src/components/Header/Header.astro +++ /dev/null @@ -1,149 +0,0 @@ ---- -import { getLanguageFromURL, KNOWN_LANGUAGE_CODES } from '../../languages'; -import { SITE } from '../../consts'; -import AstroLogo from './AstroLogo.astro'; -import SkipToContent from './SkipToContent.astro'; -import SidebarToggle from './SidebarToggle'; -import LanguageSelect from './LanguageSelect'; -import Search from './Search'; - -type Props = { - currentPage: string; -}; - -const { currentPage } = Astro.props; -const lang = getLanguageFromURL(currentPage); ---- - -<header> - <SkipToContent /> - <nav class="nav-wrapper" title="Top Navigation"> - <div class="menu-toggle"> - <SidebarToggle client:idle /> - </div> - <div class="logo flex"> - <a href="/"> - <AstroLogo size={40} /> - <h1>{SITE.title ?? 'Documentation'}</h1> - </a> - </div> - <div style="flex-grow: 1;"></div> - {KNOWN_LANGUAGE_CODES.length > 1 && <LanguageSelect lang={lang} client:idle />} - <div class="search-item"> - <Search client:idle /> - </div> - </nav> -</header> - -<style> - header { - z-index: 11; - height: var(--theme-navbar-height); - width: 100%; - background-color: var(--theme-navbar-bg); - display: flex; - align-items: center; - justify-content: center; - overflow: hidden; - position: sticky; - top: 0; - } - - .logo { - flex: 1; - display: flex; - overflow: hidden; - width: 30px; - font-size: 2rem; - flex-shrink: 0; - font-weight: 600; - line-height: 1; - color: hsla(var(--color-base-white), 100%, 1); - gap: 0.25em; - z-index: -1; - } - - .logo a { - display: flex; - padding: 0.5em 0.25em; - margin: -0.5em -0.25em; - text-decoration: none; - font-weight: bold; - } - - .logo a { - transition: color 100ms ease-out; - color: var(--theme-text); - } - - .logo a:hover, - .logo a:focus { - color: var(--theme-text-accent); - } - - .logo h1 { - display: none; - font: inherit; - color: inherit; - margin: 0; - } - - .nav-wrapper { - display: flex; - align-items: center; - justify-content: flex-end; - gap: 1em; - width: 100%; - max-width: 82em; - padding: 0 1rem; - } - - @media (min-width: 50em) { - header { - position: static; - padding: 2rem 0rem; - } - - .logo { - width: auto; - margin: 0; - z-index: 0; - } - - .logo h1 { - display: initial; - } - - .menu-toggle { - display: none; - } - } - - /** Style Algolia */ - :root { - --docsearch-primary-color: var(--theme-accent); - --docsearch-logo-color: var(--theme-text); - } - - .search-item { - display: none; - position: relative; - z-index: 10; - flex-grow: 1; - padding-right: 0.7rem; - display: flex; - max-width: 200px; - } - - @media (min-width: 50em) { - .search-item { - max-width: 400px; - } - } -</style> - -<style is:global> - .search-item > * { - flex-grow: 1; - } -</style> diff --git a/examples/docs/src/components/Header/LanguageSelect.css b/examples/docs/src/components/Header/LanguageSelect.css deleted file mode 100644 index 9e0ae7ce1..000000000 --- a/examples/docs/src/components/Header/LanguageSelect.css +++ /dev/null @@ -1,47 +0,0 @@ -.language-select { - flex-grow: 1; - width: 48px; - box-sizing: border-box; - margin: 0; - padding: 0.33em 0.5em; - overflow: visible; - font-weight: 500; - font-size: 1rem; - font-family: inherit; - line-height: inherit; - background-color: var(--theme-bg); - border-color: var(--theme-text-lighter); - color: var(--theme-text-light); - border-style: solid; - border-width: 1px; - border-radius: 0.25rem; - outline: 0; - cursor: pointer; - transition-timing-function: ease-out; - transition-duration: 0.2s; - transition-property: border-color, color; - -webkit-font-smoothing: antialiased; - padding-left: 30px; - padding-right: 1rem; -} -.language-select-wrapper .language-select:hover, -.language-select-wrapper .language-select:focus { - color: var(--theme-text); - border-color: var(--theme-text-light); -} -.language-select-wrapper { - color: var(--theme-text-light); - position: relative; -} -.language-select-wrapper > svg { - position: absolute; - top: 7px; - left: 10px; - pointer-events: none; -} - -@media (min-width: 50em) { - .language-select { - width: 100%; - } -} diff --git a/examples/docs/src/components/Header/LanguageSelect.tsx b/examples/docs/src/components/Header/LanguageSelect.tsx deleted file mode 100644 index 97409af2b..000000000 --- a/examples/docs/src/components/Header/LanguageSelect.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/** @jsxImportSource react */ -import type { FunctionComponent } from 'react'; -import './LanguageSelect.css'; -import { KNOWN_LANGUAGES, langPathRegex } from '../../languages'; - -const LanguageSelect: FunctionComponent<{ lang: string }> = ({ lang }) => { - return ( - <div className="language-select-wrapper"> - <svg - aria-hidden="true" - focusable="false" - role="img" - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 88.6 77.3" - height="1.2em" - width="1.2em" - > - <path - fill="currentColor" - d="M61,24.6h7.9l18.7,51.6h-7.7l-5.4-15.5H54.3l-5.6,15.5h-7.2L61,24.6z M72.6,55l-8-22.8L56.3,55H72.6z" - /> - <path - fill="currentColor" - d="M53.6,60.6c-10-4-16-9-22-14c0,0,1.3,1.3,0,0c-6,5-20,13-20,13l-4-6c8-5,10-6,19-13c-2.1-1.9-12-13-13-19h8 c4,9,10,14,10,14c10-8,10-19,10-19h8c0,0-1,13-12,24l0,0c5,5,10,9,19,13L53.6,60.6z M1.6,16.6h56v-8h-23v-7h-9v7h-24V16.6z" - /> - </svg> - <select - className="language-select" - value={lang} - onChange={(e) => { - const newLang = e.target.value; - let actualDest = window.location.pathname.replace(langPathRegex, '/'); - if (actualDest == '/') actualDest = `/introduction`; - window.location.pathname = '/' + newLang + actualDest; - }} - > - {Object.entries(KNOWN_LANGUAGES).map(([key, value]) => { - return ( - <option value={value} key={value}> - {key} - </option> - ); - })} - </select> - </div> - ); -}; - -export default LanguageSelect; diff --git a/examples/docs/src/components/Header/Search.css b/examples/docs/src/components/Header/Search.css deleted file mode 100644 index 09ad520a2..000000000 --- a/examples/docs/src/components/Header/Search.css +++ /dev/null @@ -1,75 +0,0 @@ -/** Style Algolia */ -:root { - --docsearch-primary-color: var(--theme-accent); - --docsearch-logo-color: var(--theme-text); -} -.search-input { - flex-grow: 1; - box-sizing: border-box; - width: 100%; - margin: 0; - padding: 0.33em 0.5em; - overflow: visible; - font-weight: 500; - font-size: 1rem; - font-family: inherit; - line-height: inherit; - background-color: var(--theme-divider); - border-color: var(--theme-divider); - color: var(--theme-text-light); - border-style: solid; - border-width: 1px; - border-radius: 0.25rem; - outline: 0; - cursor: pointer; - transition-timing-function: ease-out; - transition-duration: 0.2s; - transition-property: border-color, color; - -webkit-font-smoothing: antialiased; -} -.search-input:hover, -.search-input:focus { - color: var(--theme-text); - border-color: var(--theme-text-light); -} -.search-input:hover::placeholder, -.search-input:focus::placeholder { - color: var(--theme-text-light); -} -.search-input::placeholder { - color: var(--theme-text-light); -} -.search-hint { - position: absolute; - top: 7px; - right: 19px; - padding: 3px 5px; - display: none; - align-items: center; - justify-content: center; - letter-spacing: 0.125em; - font-size: 13px; - font-family: var(--font-mono); - pointer-events: none; - border-color: var(--theme-text-lighter); - color: var(--theme-text-light); - border-style: solid; - border-width: 1px; - border-radius: 0.25rem; - line-height: 14px; -} - -@media (min-width: 50em) { - .search-hint { - display: flex; - } -} - -/* ------------------------------------------------------------ *\ - DocSearch (Algolia) -\* ------------------------------------------------------------ */ - -.DocSearch-Modal .DocSearch-Hit a { - box-shadow: none; - border: 1px solid var(--theme-accent); -} diff --git a/examples/docs/src/components/Header/Search.tsx b/examples/docs/src/components/Header/Search.tsx deleted file mode 100644 index 620941e3a..000000000 --- a/examples/docs/src/components/Header/Search.tsx +++ /dev/null @@ -1,97 +0,0 @@ -/** @jsxImportSource react */ -import { useState, useCallback, useRef } from 'react'; -import { ALGOLIA } from '../../consts'; -import '@docsearch/css'; -import './Search.css'; - -import { createPortal } from 'react-dom'; -import * as docSearchReact from '@docsearch/react'; - -/** 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<HTMLButtonElement>(null); - const [initialQuery, setInitialQuery] = useState(''); - - const onOpen = useCallback(() => { - setIsOpen(true); - }, [setIsOpen]); - - const onClose = useCallback(() => { - setIsOpen(false); - }, [setIsOpen]); - - const onInput = useCallback( - (e) => { - setIsOpen(true); - setInitialQuery(e.key); - }, - [setIsOpen, setInitialQuery] - ); - - useDocSearchKeyboardEvents({ - isOpen, - onOpen, - onClose, - onInput, - searchButtonRef, - }); - - return ( - <> - <button type="button" ref={searchButtonRef} onClick={onOpen} className="search-input"> - <svg width="24" height="24" fill="none"> - <path - d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" - stroke="currentColor" - strokeWidth="2" - strokeLinecap="round" - strokeLinejoin="round" - /> - </svg> - - <span>Search</span> - - <span className="search-hint"> - <span className="sr-only">Press </span> - - <kbd>/</kbd> - - <span className="sr-only"> to search</span> - </span> - </button> - - {isOpen && - createPortal( - <DocSearchModal - initialQuery={initialQuery} - initialScrollY={window.scrollY} - onClose={onClose} - 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 - // work better on localhost, preview URLS. - const a = document.createElement('a'); - a.href = item.url; - const hash = a.hash === '#overview' ? '' : a.hash; - return { - ...item, - url: `${a.pathname}${hash}`, - }; - }); - }} - />, - document.body - )} - </> - ); -} diff --git a/examples/docs/src/components/Header/SidebarToggle.tsx b/examples/docs/src/components/Header/SidebarToggle.tsx deleted file mode 100644 index 50a5d93d0..000000000 --- a/examples/docs/src/components/Header/SidebarToggle.tsx +++ /dev/null @@ -1,44 +0,0 @@ -/** @jsxImportSource preact */ -import type { FunctionalComponent } from 'preact'; -import { useState, useEffect } from 'preact/hooks'; - -const MenuToggle: FunctionalComponent = () => { - const [sidebarShown, setSidebarShown] = useState(false); - - useEffect(() => { - const body = document.querySelector('body')!; - if (sidebarShown) { - body.classList.add('mobile-sidebar-toggle'); - } else { - body.classList.remove('mobile-sidebar-toggle'); - } - }, [sidebarShown]); - - return ( - <button - type="button" - aria-pressed={sidebarShown ? 'true' : 'false'} - id="menu-toggle" - onClick={() => setSidebarShown(!sidebarShown)} - > - <svg - xmlns="http://www.w3.org/2000/svg" - width="1em" - height="1em" - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - <path - stroke-linecap="round" - stroke-linejoin="round" - stroke-width="2" - d="M4 6h16M4 12h16M4 18h16" - /> - </svg> - <span className="sr-only">Toggle sidebar</span> - </button> - ); -}; - -export default MenuToggle; diff --git a/examples/docs/src/components/Header/SkipToContent.astro b/examples/docs/src/components/Header/SkipToContent.astro deleted file mode 100644 index 4d97923f6..000000000 --- a/examples/docs/src/components/Header/SkipToContent.astro +++ /dev/null @@ -1,26 +0,0 @@ ---- -type Props = {}; ---- - -<a href="#article" class="sr-only focus:not-sr-only skiplink"><span>Skip to Content</span></a> - -<style> - .skiplink, - .skiplink:focus, - .skiplink:focus-visible { - position: absolute; - padding: 0.25em; - font-size: larger; - top: 0; - left: 0; - right: 0; - z-index: 9; - display: block; - text-align: center; - background-color: var(--theme-text-accent); - color: var(--theme-bg); - border-radius: 0.25em; - outline: var(--theme-bg) solid 1px; - outline-offset: 0; - } -</style> diff --git a/examples/docs/src/components/LeftSidebar/LeftSidebar.astro b/examples/docs/src/components/LeftSidebar/LeftSidebar.astro deleted file mode 100644 index 128fc0dac..000000000 --- a/examples/docs/src/components/LeftSidebar/LeftSidebar.astro +++ /dev/null @@ -1,119 +0,0 @@ ---- -import { getLanguageFromURL } from '../../languages'; -import { SIDEBAR } from '../../consts'; - -type Props = { - currentPage: string; -}; - -const { currentPage } = Astro.props; -const currentPageMatch = currentPage.endsWith('/') - ? currentPage.slice(1, -1) - : currentPage.slice(1); -const langCode = getLanguageFromURL(currentPage); -const sidebar = SIDEBAR[langCode]; ---- - -<nav aria-labelledby="grid-left"> - <ul class="nav-groups"> - { - Object.entries(sidebar).map(([header, children]) => ( - <li> - <div class="nav-group"> - <h2 class="nav-group-title">{header}</h2> - <ul> - {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> - )) - } - </ul> -</nav> - -<script is:inline> - window.addEventListener('DOMContentLoaded', () => { - var target = document.querySelector('[aria-current="page"]'); - if (target && target.offsetTop > window.innerHeight - 100) { - document.querySelector('.nav-groups').scrollTop = target.offsetTop; - } - }); -</script> - -<style> - nav { - width: 100%; - margin-right: 1rem; - } - - .nav-groups { - height: 100%; - padding: 2rem 0; - overflow-x: visible; - overflow-y: auto; - max-height: 100vh; - } - - .nav-groups > li + li { - margin-top: 2rem; - } - - .nav-groups > :first-child { - padding-top: var(--doc-padding); - } - - .nav-groups > :last-child { - padding-bottom: 2rem; - margin-bottom: var(--theme-navbar-height); - } - - .nav-group-title { - font-size: 1rem; - font-weight: 700; - padding: 0.1rem 1rem; - text-transform: uppercase; - margin-bottom: 0.5rem; - } - - .nav-link a { - font-size: 1rem; - margin: 1px; - padding: 0.3rem 1rem; - font: inherit; - color: inherit; - text-decoration: none; - display: block; - } - - .nav-link a:hover, - .nav-link a:focus { - background-color: var(--theme-bg-hover); - } - - .nav-link a[aria-current='page'] { - color: var(--theme-text-accent); - background-color: var(--theme-bg-accent); - font-weight: 600; - } - - @media (min-width: 50em) { - .nav-groups { - padding: 0; - } - } -</style> - -<style is:global> - :root.theme-dark .nav-link a[aria-current='page'] { - color: hsla(var(--color-base-white), 100%, 1); - } -</style> diff --git a/examples/docs/src/components/PageContent/PageContent.astro b/examples/docs/src/components/PageContent/PageContent.astro deleted file mode 100644 index 24422b75a..000000000 --- a/examples/docs/src/components/PageContent/PageContent.astro +++ /dev/null @@ -1,51 +0,0 @@ ---- -import type { MarkdownHeading } from 'astro'; -import MoreMenu from '../RightSidebar/MoreMenu.astro'; -import TableOfContents from '../RightSidebar/TableOfContents'; - -type Props = { - title: string; - headings: MarkdownHeading[]; - githubEditUrl: string; -}; - -const { title, headings, githubEditUrl } = Astro.props; ---- - -<article id="article" class="content"> - <section class="main-section"> - <h1 class="content-title" id="overview">{title}</h1> - <nav class="block sm:hidden"> - <TableOfContents client:media="(max-width: 50em)" headings={headings} /> - </nav> - <slot /> - </section> - <nav class="block sm:hidden"> - <MoreMenu editHref={githubEditUrl} /> - </nav> -</article> - -<style> - .content { - padding: 0; - max-width: 75ch; - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - } - - .content > section { - margin-bottom: 4rem; - } - - .block { - display: block; - } - - @media (min-width: 50em) { - .sm\:hidden { - display: none; - } - } -</style> diff --git a/examples/docs/src/components/RightSidebar/MoreMenu.astro b/examples/docs/src/components/RightSidebar/MoreMenu.astro deleted file mode 100644 index 5dbf89678..000000000 --- a/examples/docs/src/components/RightSidebar/MoreMenu.astro +++ /dev/null @@ -1,79 +0,0 @@ ---- -import ThemeToggleButton from './ThemeToggleButton'; -import { COMMUNITY_INVITE_URL } from '../../consts'; - -type Props = { - editHref: string; -}; - -const { editHref } = Astro.props; -const showMoreSection = Boolean(COMMUNITY_INVITE_URL); ---- - -{showMoreSection && <h2 class="heading">More</h2>} -<ul> - { - editHref && ( - <li class={`header-link depth-2`}> - <a class="edit-on-github" href={editHref} target="_blank"> - <svg - aria-hidden="true" - focusable="false" - data-prefix="fas" - data-icon="pen" - class="svg-inline--fa fa-pen fa-w-16" - role="img" - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 512 512" - height="1em" - width="1em" - > - <path - fill="currentColor" - d="M290.74 93.24l128.02 128.02-277.99 277.99-114.14 12.6C11.35 513.54-1.56 500.62.14 485.34l12.7-114.22 277.9-277.88zm207.2-19.06l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.76 18.75-49.16 0-67.91z" - /> - </svg> - <span>Edit this page</span> - </a> - </li> - ) - } - { - COMMUNITY_INVITE_URL && ( - <li class={`header-link depth-2`}> - <a href={COMMUNITY_INVITE_URL} target="_blank"> - <svg - aria-hidden="true" - focusable="false" - data-prefix="fas" - data-icon="comment-alt" - class="svg-inline--fa fa-comment-alt fa-w-16" - role="img" - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 512 512" - height="1em" - width="1em" - > - <path - fill="currentColor" - d="M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 9.8 11.2 15.5 19.1 9.7L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64z" - /> - </svg> - <span>Join our community</span> - </a> - </li> - ) - } -</ul> -<div style="margin: 2rem 0; text-align: center;"> - <ThemeToggleButton client:visible /> -</div> - -<style> - .edit-on-github { - text-decoration: none; - font: inherit; - color: inherit; - font-size: 1rem; - } -</style> diff --git a/examples/docs/src/components/RightSidebar/RightSidebar.astro b/examples/docs/src/components/RightSidebar/RightSidebar.astro deleted file mode 100644 index 2a7190e50..000000000 --- a/examples/docs/src/components/RightSidebar/RightSidebar.astro +++ /dev/null @@ -1,34 +0,0 @@ ---- -import type { MarkdownHeading } from 'astro'; -import TableOfContents from './TableOfContents'; -import MoreMenu from './MoreMenu.astro'; - -type Props = { - headings: MarkdownHeading[]; - githubEditUrl: string; -}; - -const { headings, githubEditUrl } = Astro.props; ---- - -<nav class="sidebar-nav" aria-labelledby="grid-right"> - <div class="sidebar-nav-inner"> - <TableOfContents client:media="(min-width: 50em)" headings={headings} /> - <MoreMenu editHref={githubEditUrl} /> - </div> -</nav> - -<style> - .sidebar-nav { - width: 100%; - position: sticky; - top: 0; - } - - .sidebar-nav-inner { - height: 100%; - padding: 0; - padding-top: var(--doc-padding); - overflow: auto; - } -</style> diff --git a/examples/docs/src/components/RightSidebar/TableOfContents.tsx b/examples/docs/src/components/RightSidebar/TableOfContents.tsx deleted file mode 100644 index 962d64ec2..000000000 --- a/examples/docs/src/components/RightSidebar/TableOfContents.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import type { MarkdownHeading } from 'astro'; -import type { FunctionalComponent } from 'preact'; -import { unescape } from 'html-escaper'; -import { useState, useEffect, useRef } from 'preact/hooks'; - -type ItemOffsets = { - id: string; - topOffset: number; -}; - -const TableOfContents: FunctionalComponent<{ headings: MarkdownHeading[] }> = ({ - headings = [], -}) => { - const toc = useRef<HTMLUListElement>(); - const onThisPageID = 'on-this-page-heading'; - const itemOffsets = useRef<ItemOffsets[]>([]); - const [currentID, setCurrentID] = useState('overview'); - useEffect(() => { - const getItemOffsets = () => { - const titles = document.querySelectorAll('article :is(h1, h2, h3, h4)'); - itemOffsets.current = Array.from(titles).map((title) => ({ - id: title.id, - topOffset: title.getBoundingClientRect().top + window.scrollY, - })); - }; - - getItemOffsets(); - window.addEventListener('resize', getItemOffsets); - - return () => { - window.removeEventListener('resize', getItemOffsets); - }; - }, []); - - useEffect(() => { - if (!toc.current) return; - - const setCurrent: IntersectionObserverCallback = (entries) => { - for (const entry of entries) { - if (entry.isIntersecting) { - const { id } = entry.target; - if (id === onThisPageID) continue; - setCurrentID(entry.target.id); - break; - } - } - }; - - const observerOptions: IntersectionObserverInit = { - // Negative top margin accounts for `scroll-margin`. - // Negative bottom margin means heading needs to be towards top of viewport to trigger intersection. - rootMargin: '-100px 0% -66%', - threshold: 1, - }; - - const headingsObserver = new IntersectionObserver(setCurrent, observerOptions); - - // Observe all the headings in the main page content. - document.querySelectorAll('article :is(h1,h2,h3)').forEach((h) => headingsObserver.observe(h)); - - // Stop observing when the component is unmounted. - return () => headingsObserver.disconnect(); - }, [toc.current]); - - const onLinkClick = (e) => { - setCurrentID(e.target.getAttribute('href').replace('#', '')); - }; - - return ( - <> - <h2 id={onThisPageID} className="heading"> - On this page - </h2> - <ul ref={toc}> - {headings - .filter(({ depth }) => depth > 1 && depth < 4) - .map((heading) => ( - <li - className={`header-link depth-${heading.depth} ${ - currentID === heading.slug ? 'current-header-link' : '' - }`.trim()} - > - <a href={`#${heading.slug}`} onClick={onLinkClick}> - {unescape(heading.text)} - </a> - </li> - ))} - </ul> - </> - ); -}; - -export default TableOfContents; diff --git a/examples/docs/src/components/RightSidebar/ThemeToggleButton.css b/examples/docs/src/components/RightSidebar/ThemeToggleButton.css deleted file mode 100644 index dc5ba46d9..000000000 --- a/examples/docs/src/components/RightSidebar/ThemeToggleButton.css +++ /dev/null @@ -1,37 +0,0 @@ -.theme-toggle { - display: inline-flex; - align-items: center; - gap: 0.25em; - padding: 0.33em 0.67em; - border-radius: 99em; - background-color: var(--theme-code-inline-bg); -} - -.theme-toggle > label:focus-within { - outline: 2px solid transparent; - box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white; -} - -.theme-toggle > label { - color: var(--theme-code-inline-text); - position: relative; - display: flex; - align-items: center; - justify-content: center; - opacity: 0.5; -} - -.theme-toggle .checked { - color: var(--theme-accent); - opacity: 1; -} - -input[name='theme-toggle'] { - position: absolute; - opacity: 0; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: -1; -} diff --git a/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx b/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx deleted file mode 100644 index b9682aa00..000000000 --- a/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import type { FunctionalComponent } from 'preact'; -import { useState, useEffect } from 'preact/hooks'; -import './ThemeToggleButton.css'; - -const themes = ['light', 'dark']; - -const icons = [ - <svg - xmlns="http://www.w3.org/2000/svg" - width="20" - height="20" - viewBox="0 0 20 20" - fill="currentColor" - > - <path - fillRule="evenodd" - d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" - clipRule="evenodd" - /> - </svg>, - <svg - xmlns="http://www.w3.org/2000/svg" - width="20" - height="20" - viewBox="0 0 20 20" - fill="currentColor" - > - <path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" /> - </svg>, -]; - -const ThemeToggle: FunctionalComponent = () => { - const [theme, setTheme] = useState(() => { - if (import.meta.env.SSR) { - return undefined; - } - if (typeof localStorage !== undefined && localStorage.getItem('theme')) { - return localStorage.getItem('theme'); - } - if (window.matchMedia('(prefers-color-scheme: dark)').matches) { - return 'dark'; - } - return 'light'; - }); - - useEffect(() => { - const root = document.documentElement; - if (theme === 'light') { - root.classList.remove('theme-dark'); - } else { - root.classList.add('theme-dark'); - } - }, [theme]); - - return ( - <div className="theme-toggle"> - {themes.map((t, i) => { - const icon = icons[i]; - const checked = t === theme; - return ( - <label className={checked ? ' checked' : ''}> - {icon} - <input - type="radio" - name="theme-toggle" - checked={checked} - value={t} - title={`Use ${t} theme`} - aria-label={`Use ${t} theme`} - onChange={() => { - localStorage.setItem('theme', t); - setTheme(t); - }} - /> - </label> - ); - })} - </div> - ); -}; - -export default ThemeToggle; |