mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
fix: improve docs example (#4355)
* fix: improve docs example * final touches * chore: prettier * lockfile * ci? * downgrade types node * fresh lockfile * lockfile and npmrc * remove debug log * Merge branch 'main' into docs-template-ts * merging lockfiles suck * update lockfile * satisfy linter
This commit is contained in:
parent
046bfd908d
commit
feb88afb8c
22 changed files with 1067 additions and 890 deletions
1
.npmrc
1
.npmrc
|
@ -2,6 +2,7 @@
|
||||||
prefer-workspace-packages=true
|
prefer-workspace-packages=true
|
||||||
link-workspace-packages=true
|
link-workspace-packages=true
|
||||||
save-workspace-protocol=false # This prevents the examples to have the `workspace:` prefix
|
save-workspace-protocol=false # This prevents the examples to have the `workspace:` prefix
|
||||||
|
auto-install-peers=false
|
||||||
|
|
||||||
shamefully-hoist=true
|
shamefully-hoist=true
|
||||||
# TODO: We would like to move to individual opt-in hoisting, but Astro was not originally
|
# TODO: We would like to move to individual opt-in hoisting, but Astro was not originally
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
|
"check": "astro check && tsc",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
|
@ -20,6 +21,8 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/preact": "^1.0.2",
|
"@astrojs/preact": "^1.0.2",
|
||||||
|
"@types/node": "^18.0.0",
|
||||||
|
"@types/react-dom": "^18.0.0",
|
||||||
"@astrojs/react": "^1.1.0",
|
"@astrojs/react": "^1.1.0",
|
||||||
"astro": "^1.1.1"
|
"astro": "^1.1.1"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
---
|
---
|
||||||
// fetch all commits for just this page's path
|
// fetch all commits for just this page's path
|
||||||
const path = 'docs/' + Astro.props.path;
|
type Props = {
|
||||||
const url = `https://api.github.com/repos/withastro/astro/commits?path=${path}`;
|
path: string;
|
||||||
const commitsURL = `https://github.com/withastro/astro/commits/main/${path}`;
|
};
|
||||||
|
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}`;
|
||||||
|
|
||||||
async function getCommits(url) {
|
type Commit = {
|
||||||
|
author: {
|
||||||
|
id: string;
|
||||||
|
login: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
async function getCommits(url: string) {
|
||||||
try {
|
try {
|
||||||
const token = import.meta.env.SNOWPACK_PUBLIC_GITHUB_TOKEN;
|
const token = import.meta.env.SNOWPACK_PUBLIC_GITHUB_TOKEN ?? 'hello';
|
||||||
if (!token) {
|
if (!token) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Cannot find "SNOWPACK_PUBLIC_GITHUB_TOKEN" used for escaping rate-limiting.'
|
'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) {
|
} catch (e) {
|
||||||
console.warn(`[error] /src/components/AvatarList.astro
|
console.warn(`[error] /src/components/AvatarList.astro
|
||||||
${e?.message ?? e}`);
|
${(e as any)?.message ?? e}`);
|
||||||
return new Array();
|
return [] as Commit[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeDups(arr) {
|
function removeDups(arr: Commit[]) {
|
||||||
if (!arr) {
|
const map = new Map<string, Commit['author']>();
|
||||||
return new Array();
|
|
||||||
}
|
|
||||||
let map = new Map();
|
|
||||||
|
|
||||||
for (let item of arr) {
|
for (let item of arr) {
|
||||||
let author = item.author;
|
const author = item.author;
|
||||||
// Deduplicate based on author.id
|
// Deduplicate based on author.id
|
||||||
map.set(author.id, { login: author.login, id: 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);
|
const data = await getCommits(url);
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
---
|
---
|
||||||
import AvatarList from './AvatarList.astro';
|
import AvatarList from './AvatarList.astro';
|
||||||
const { path } = Astro.props;
|
type Props = {
|
||||||
|
path: string;
|
||||||
|
};
|
||||||
|
const { path } = Astro.props as Props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<AvatarList {path} />
|
<AvatarList path={path} />
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
footer {
|
footer {
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
padding: 2rem 0;
|
padding: 2rem;
|
||||||
border-top: 3px solid var(--theme-divider);
|
border-top: 3px solid var(--theme-divider);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,35 +1,32 @@
|
||||||
---
|
---
|
||||||
import { SITE, OPEN_GRAPH } from '../config';
|
import { SITE, OPEN_GRAPH, Frontmatter } from '../config';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
frontmatter: any;
|
frontmatter: Frontmatter;
|
||||||
site: any;
|
canonicalUrl: URL;
|
||||||
canonicalURL: URL | string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
|
const { frontmatter, canonicalUrl } = Astro.props as Props;
|
||||||
const { frontmatter = {} } = Astro.props;
|
const formattedContentTitle = `${frontmatter.title} 🚀 ${SITE.title}`;
|
||||||
const formattedContentTitle = frontmatter.title
|
const imageSrc = frontmatter.image?.src ?? OPEN_GRAPH.image.src;
|
||||||
? `${frontmatter.title} 🚀 ${SITE.title}`
|
|
||||||
: SITE.title;
|
|
||||||
const imageSrc = frontmatter?.image?.src ?? OPEN_GRAPH.image.src;
|
|
||||||
const canonicalImageSrc = new URL(imageSrc, Astro.site);
|
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 -->
|
<!-- Page Metadata -->
|
||||||
<link rel="canonical" href={canonicalURL} />
|
<link rel="canonical" href={canonicalUrl} />
|
||||||
|
|
||||||
<!-- OpenGraph Tags -->
|
<!-- OpenGraph Tags -->
|
||||||
<meta property="og:title" content={formattedContentTitle} />
|
<meta property="og:title" content={formattedContentTitle} />
|
||||||
<meta property="og:type" content="article" />
|
<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:locale" content={frontmatter.ogLocale ?? SITE.defaultLanguage} />
|
||||||
<meta property="og:image" content={canonicalImageSrc} />
|
<meta property="og:image" content={canonicalImageSrc} />
|
||||||
<meta property="og:image:alt" content={imageAlt} />
|
<meta property="og:image:alt" content={imageAlt} />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
property="og:description"
|
property="og:description"
|
||||||
content={frontmatter.description ? frontmatter.description : SITE.description}
|
content={frontmatter.description ?? SITE.description}
|
||||||
/>
|
/>
|
||||||
<meta property="og:site_name" content={SITE.title} />
|
<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:card" content="summary_large_image" />
|
||||||
<meta name="twitter:site" content={OPEN_GRAPH.twitter} />
|
<meta name="twitter:site" content={OPEN_GRAPH.twitter} />
|
||||||
<meta name="twitter:title" content={formattedContentTitle} />
|
<meta name="twitter:title" content={formattedContentTitle} />
|
||||||
<meta
|
<meta name="twitter:description" content={frontmatter.description ?? SITE.description} />
|
||||||
name="twitter:description"
|
|
||||||
content={frontmatter.description ? frontmatter.description : SITE.description}
|
|
||||||
/>
|
|
||||||
<meta name="twitter:image" content={canonicalImageSrc} />
|
<meta name="twitter:image" content={canonicalImageSrc} />
|
||||||
<meta name="twitter:image:alt" content={imageAlt} />
|
<meta name="twitter:image:alt" content={imageAlt} />
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
---
|
---
|
||||||
const { size } = Astro.props;
|
type Props = {
|
||||||
|
size: number;
|
||||||
|
};
|
||||||
|
const { size } = Astro.props as Props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
|
@ -14,6 +17,7 @@ const { size } = Astro.props;
|
||||||
#flame {
|
#flame {
|
||||||
fill: var(--theme-text-accent);
|
fill: var(--theme-text-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
#a {
|
#a {
|
||||||
fill: var(--theme-text-accent);
|
fill: var(--theme-text-accent);
|
||||||
}
|
}
|
||||||
|
@ -24,11 +28,13 @@ const { size } = Astro.props;
|
||||||
fill-rule="evenodd"
|
fill-rule="evenodd"
|
||||||
clip-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"
|
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
|
<path
|
||||||
id="flame"
|
id="flame"
|
||||||
fill-rule="evenodd"
|
fill-rule="evenodd"
|
||||||
clip-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"
|
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>
|
</svg>
|
||||||
|
|
|
@ -7,8 +7,12 @@ import SidebarToggle from './SidebarToggle';
|
||||||
import LanguageSelect from './LanguageSelect';
|
import LanguageSelect from './LanguageSelect';
|
||||||
import Search from './Search';
|
import Search from './Search';
|
||||||
|
|
||||||
const { currentPage } = Astro.props;
|
type Props = {
|
||||||
const lang = currentPage && getLanguageFromURL(currentPage);
|
currentPage: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const { currentPage } = Astro.props as Props;
|
||||||
|
const lang = getLanguageFromURL(currentPage);
|
||||||
---
|
---
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
|
@ -25,11 +29,9 @@ const lang = currentPage && getLanguageFromURL(currentPage);
|
||||||
</div>
|
</div>
|
||||||
<div style="flex-grow: 1;"></div>
|
<div style="flex-grow: 1;"></div>
|
||||||
{KNOWN_LANGUAGE_CODES.length > 1 && <LanguageSelect lang={lang} client:idle />}
|
{KNOWN_LANGUAGE_CODES.length > 1 && <LanguageSelect lang={lang} client:idle />}
|
||||||
{CONFIG.ALGOLIA && (
|
<div class="search-item">
|
||||||
<div class="search-item">
|
<Search client:idle />
|
||||||
<Search client:idle />
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
@ -101,14 +103,17 @@ const lang = currentPage && getLanguageFromURL(currentPage);
|
||||||
position: static;
|
position: static;
|
||||||
padding: 2rem 0rem;
|
padding: 2rem 0rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
width: auto;
|
width: auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo h1 {
|
.logo h1 {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-toggle {
|
.menu-toggle {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -129,9 +134,11 @@ const lang = currentPage && getLanguageFromURL(currentPage);
|
||||||
display: flex;
|
display: flex;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.search-item > *) {
|
:global(.search-item > *) {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 50em) {
|
@media (min-width: 50em) {
|
||||||
.search-item {
|
.search-item {
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import type { FunctionalComponent } from 'preact';
|
/** @jsxImportSource react */
|
||||||
import { h } from 'preact';
|
import type { FunctionComponent } from 'react';
|
||||||
import './LanguageSelect.css';
|
import './LanguageSelect.css';
|
||||||
import { KNOWN_LANGUAGES, langPathRegex } from '../../languages';
|
import { KNOWN_LANGUAGES, langPathRegex } from '../../languages';
|
||||||
|
|
||||||
const LanguageSelect: FunctionalComponent<{ lang: string }> = ({ lang }) => {
|
const LanguageSelect: FunctionComponent<{ lang: string }> = ({ lang }) => {
|
||||||
return (
|
return (
|
||||||
<div class="language-select-wrapper">
|
<div className="language-select-wrapper">
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
|
@ -25,7 +25,7 @@ const LanguageSelect: FunctionalComponent<{ lang: string }> = ({ lang }) => {
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<select
|
<select
|
||||||
class="language-select"
|
className="language-select"
|
||||||
value={lang}
|
value={lang}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const newLang = e.target.value;
|
const newLang = e.target.value;
|
||||||
|
@ -34,9 +34,9 @@ const LanguageSelect: FunctionalComponent<{ lang: string }> = ({ lang }) => {
|
||||||
window.location.pathname = '/' + newLang + actualDest;
|
window.location.pathname = '/' + newLang + actualDest;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Object.keys(KNOWN_LANGUAGES).map((key) => {
|
{Object.entries(KNOWN_LANGUAGES).map(([key, value]) => {
|
||||||
return (
|
return (
|
||||||
<option value={KNOWN_LANGUAGES[key]}>
|
<option value={value}>
|
||||||
<span>{key}</span>
|
<span>{key}</span>
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
/* jsxImportSource: react */
|
/** @jsxImportSource react */
|
||||||
import { useState, useCallback, useRef } from 'react';
|
import { useState, useCallback, useRef } from 'react';
|
||||||
import * as CONFIG from '../../config';
|
import { ALGOLIA } from '../../config';
|
||||||
import '@docsearch/css/dist/style.css';
|
import '@docsearch/css';
|
||||||
import './Search.css';
|
import './Search.css';
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
import * as docSearchReact from '@docsearch/react';
|
|
||||||
// @ts-ignore
|
|
||||||
import { createPortal } from 'react-dom';
|
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() {
|
export default function Search() {
|
||||||
const DocSearchModal = docSearchReact.DocSearchModal || docSearchReact.default.DocSearchModal;
|
|
||||||
|
|
||||||
const useDocSearchKeyboardEvents =
|
|
||||||
docSearchReact.useDocSearchKeyboardEvents || docSearchReact.default.useDocSearchKeyboardEvents;
|
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const searchButtonRef = useRef();
|
const searchButtonRef = useRef<HTMLButtonElement>(null);
|
||||||
const [initialQuery, setInitialQuery] = useState(null);
|
const [initialQuery, setInitialQuery] = useState('');
|
||||||
|
|
||||||
const onOpen = useCallback(() => {
|
const onOpen = useCallback(() => {
|
||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
|
@ -73,9 +73,9 @@ export default function Search() {
|
||||||
initialQuery={initialQuery}
|
initialQuery={initialQuery}
|
||||||
initialScrollY={window.scrollY}
|
initialScrollY={window.scrollY}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
indexName={(CONFIG as any).ALGOLIA.indexName}
|
indexName={ALGOLIA.indexName}
|
||||||
appId={(CONFIG as any).ALGOLIA.appId}
|
appId={ALGOLIA.appId}
|
||||||
apiKey={(CONFIG as any).ALGOLIA.apiKey}
|
apiKey={ALGOLIA.apiKey}
|
||||||
transformItems={(items) => {
|
transformItems={(items) => {
|
||||||
return items.map((item) => {
|
return items.map((item) => {
|
||||||
// We transform the absolute URL into a relative URL to
|
// We transform the absolute URL into a relative URL to
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
/** @jsxImportSource preact */
|
||||||
import type { FunctionalComponent } from 'preact';
|
import type { FunctionalComponent } from 'preact';
|
||||||
import { h, Fragment } from 'preact';
|
|
||||||
import { useState, useEffect } from 'preact/hooks';
|
import { useState, useEffect } from 'preact/hooks';
|
||||||
|
|
||||||
const MenuToggle: FunctionalComponent = () => {
|
const MenuToggle: FunctionalComponent = () => {
|
||||||
const [sidebarShown, setSidebarShown] = useState(false);
|
const [sidebarShown, setSidebarShown] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const body = document.getElementsByTagName('body')[0];
|
const body = document.querySelector('body')!;
|
||||||
if (sidebarShown) {
|
if (sidebarShown) {
|
||||||
body.classList.add('mobile-sidebar-toggle');
|
body.classList.add('mobile-sidebar-toggle');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
---
|
||||||
|
type Props = {};
|
||||||
|
---
|
||||||
|
|
||||||
<a href="#article" class="sr-only focus:not-sr-only skiplink"><span>Skip to Content</span></a>
|
<a href="#article" class="sr-only focus:not-sr-only skiplink"><span>Skip to Content</span></a>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -1,44 +1,34 @@
|
||||||
---
|
---
|
||||||
import { getLanguageFromURL } from '../../languages';
|
import { getLanguageFromURL } from '../../languages';
|
||||||
import { SIDEBAR } from '../../config';
|
import { SIDEBAR } from '../../config';
|
||||||
const { currentPage } = Astro.props;
|
|
||||||
|
type Props = {
|
||||||
|
currentPage: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const { currentPage } = Astro.props as Props;
|
||||||
const currentPageMatch = currentPage.slice(1);
|
const currentPageMatch = currentPage.slice(1);
|
||||||
const langCode = getLanguageFromURL(currentPage);
|
const langCode = getLanguageFromURL(currentPage);
|
||||||
// SIDEBAR is a flat array. Group it by sections to properly render.
|
const sidebar = SIDEBAR[langCode];
|
||||||
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;
|
|
||||||
}, []);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<nav aria-labelledby="grid-left">
|
<nav aria-labelledby="grid-left">
|
||||||
<ul class="nav-groups">
|
<ul class="nav-groups">
|
||||||
{sidebarSections.map((section) => (
|
{Object.entries(sidebar).map(([header, children]) => (
|
||||||
<li>
|
<li>
|
||||||
<div class="nav-group">
|
<div class="nav-group">
|
||||||
<h2 class="nav-group-title">{section.text}</h2>
|
<h2>{header}</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{section.children.map((child) => (
|
{children.map((child) => {
|
||||||
<li class="nav-link">
|
const url = Astro.site?.pathname + child.link;
|
||||||
<a
|
return (
|
||||||
href={`${Astro.site.pathname}${child.link}`}
|
<li class="nav-link">
|
||||||
aria-current={`${currentPageMatch === child.link ? 'page' : 'false'}`}
|
<a href={url} aria-current={currentPageMatch === child.link ? 'page' : false}>
|
||||||
>
|
{child.text}
|
||||||
{child.text}
|
</a>
|
||||||
</a>
|
</li>
|
||||||
</li>
|
);
|
||||||
))}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@ -47,7 +37,7 @@ const sidebarSections = SIDEBAR[langCode].reduce((col, item, i) => {
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
window.addEventListener('DOMContentLoaded', (event) => {
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
var target = document.querySelector('[aria-current="page"]');
|
var target = document.querySelector('[aria-current="page"]');
|
||||||
if (target && target.offsetTop > window.innerHeight - 100) {
|
if (target && target.offsetTop > window.innerHeight - 100) {
|
||||||
document.querySelector('.nav-groups').scrollTop = target.offsetTop;
|
document.querySelector('.nav-groups').scrollTop = target.offsetTop;
|
||||||
|
@ -60,6 +50,7 @@ const sidebarSections = SIDEBAR[langCode].reduce((col, item, i) => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-groups {
|
.nav-groups {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
|
@ -98,6 +89,7 @@ const sidebarSections = SIDEBAR[langCode].reduce((col, item, i) => {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link a:hover,
|
.nav-link a:hover,
|
||||||
.nav-link a:focus {
|
.nav-link a:focus {
|
||||||
background-color: var(--theme-bg-hover);
|
background-color: var(--theme-bg-hover);
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
---
|
---
|
||||||
|
import type { Frontmatter } from '../../config';
|
||||||
import MoreMenu from '../RightSidebar/MoreMenu.astro';
|
import MoreMenu from '../RightSidebar/MoreMenu.astro';
|
||||||
import TableOfContents from '../RightSidebar/TableOfContents';
|
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;
|
const title = frontmatter.title;
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -10,7 +18,7 @@ const title = frontmatter.title;
|
||||||
<section class="main-section">
|
<section class="main-section">
|
||||||
<h1 class="content-title" id="overview">{title}</h1>
|
<h1 class="content-title" id="overview">{title}</h1>
|
||||||
<nav class="block sm:hidden">
|
<nav class="block sm:hidden">
|
||||||
<TableOfContents client:media="(max-width: 50em)" {headings} />
|
<TableOfContents client:media="(max-width: 50em)" headings={headings} />
|
||||||
</nav>
|
</nav>
|
||||||
<slot />
|
<slot />
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
---
|
---
|
||||||
import ThemeToggleButton from './ThemeToggleButton';
|
import ThemeToggleButton from './ThemeToggleButton';
|
||||||
import * as CONFIG from '../../config';
|
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>}
|
{showMoreSection && <h2 class="heading">More</h2>}
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
---
|
---
|
||||||
import TableOfContents from './TableOfContents';
|
import TableOfContents from './TableOfContents';
|
||||||
import MoreMenu from './MoreMenu.astro';
|
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">
|
<nav class="sidebar-nav" aria-labelledby="grid-right">
|
||||||
<div class="sidebar-nav-inner">
|
<div class="sidebar-nav-inner">
|
||||||
<TableOfContents client:media="(min-width: 50em)" {headings} />
|
<TableOfContents client:media="(min-width: 50em)" headings={headings} />
|
||||||
<MoreMenu editHref={githubEditUrl} />
|
<MoreMenu editHref={githubEditUrl} />
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
import type { FunctionalComponent } from 'preact';
|
import type { FunctionalComponent } from 'preact';
|
||||||
import { h, Fragment } from 'preact';
|
|
||||||
import { useState, useEffect, useRef } from 'preact/hooks';
|
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[] }> = ({
|
const TableOfContents: FunctionalComponent<{ headings: MarkdownHeading[] }> = ({
|
||||||
headings = [],
|
headings = [],
|
||||||
}) => {
|
}) => {
|
||||||
const itemOffsets = useRef([]);
|
const itemOffsets = useRef<ItemOffsets[]>([]);
|
||||||
const [activeId, setActiveId] = useState<string>(undefined);
|
// FIXME: Not sure what this state is doing. It was never set to anything truthy.
|
||||||
|
const [activeId] = useState<string>('');
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getItemOffsets = () => {
|
const getItemOffsets = () => {
|
||||||
const titles = document.querySelectorAll('article :is(h1, h2, h3, h4)');
|
const titles = document.querySelectorAll('article :is(h1, h2, h3, h4)');
|
||||||
|
@ -27,16 +32,16 @@ const TableOfContents: FunctionalComponent<{ headings: MarkdownHeading[] }> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h2 class="heading">On this page</h2>
|
<h2 className="heading">On this page</h2>
|
||||||
<ul>
|
<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>
|
<a href="#overview">Overview</a>
|
||||||
</li>
|
</li>
|
||||||
{headings
|
{headings
|
||||||
.filter(({ depth }) => depth > 1 && depth < 4)
|
.filter(({ depth }) => depth > 1 && depth < 4)
|
||||||
.map((heading) => (
|
.map((heading) => (
|
||||||
<li
|
<li
|
||||||
class={`heading-link depth-${heading.depth} ${
|
className={`heading-link depth-${heading.depth} ${
|
||||||
activeId === heading.slug ? 'active' : ''
|
activeId === heading.slug ? 'active' : ''
|
||||||
}`.trim()}
|
}`.trim()}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import type { FunctionalComponent } from 'preact';
|
import type { FunctionalComponent } from 'preact';
|
||||||
import { h, Fragment } from 'preact';
|
|
||||||
import { useState, useEffect } from 'preact/hooks';
|
import { useState, useEffect } from 'preact/hooks';
|
||||||
import './ThemeToggleButton.css';
|
import './ThemeToggleButton.css';
|
||||||
|
|
||||||
|
@ -35,7 +34,7 @@ const ThemeToggle: FunctionalComponent = () => {
|
||||||
if (import.meta.env.SSR) {
|
if (import.meta.env.SSR) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
|
if (typeof localStorage !== undefined && localStorage.getItem('theme')) {
|
||||||
return localStorage.getItem('theme');
|
return localStorage.getItem('theme');
|
||||||
}
|
}
|
||||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
@ -54,7 +53,7 @@ const ThemeToggle: FunctionalComponent = () => {
|
||||||
}, [theme]);
|
}, [theme]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="theme-toggle">
|
<div className="theme-toggle">
|
||||||
{themes.map((t, i) => {
|
{themes.map((t, i) => {
|
||||||
const icon = icons[i];
|
const icon = icons[i];
|
||||||
const checked = t === theme;
|
const checked = t === theme;
|
||||||
|
|
|
@ -14,33 +14,44 @@ export const OPEN_GRAPH = {
|
||||||
twitter: 'astrodotbuild',
|
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 = {
|
export const KNOWN_LANGUAGES = {
|
||||||
English: 'en',
|
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/tree/main/examples/docs`;
|
||||||
// export const GITHUB_EDIT_URL = `https://github.com/withastro/astro/blob/main/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.
|
// See "Algolia" section of the README for more information.
|
||||||
// export const ALGOLIA = {
|
export const ALGOLIA = {
|
||||||
// indexName: 'XXXXXXXXXX',
|
indexName: 'XXXXXXXXXX',
|
||||||
// appId: 'XXXXXXXXXX',
|
appId: 'XXXXXXXXXX',
|
||||||
// apiKey: 'XXXXXXXXXX',
|
apiKey: 'XXXXXXXXXX',
|
||||||
// }
|
};
|
||||||
|
|
||||||
export const SIDEBAR = {
|
export type Sidebar = Record<
|
||||||
en: [
|
typeof KNOWN_LANGUAGE_CODES[number],
|
||||||
{ text: '', header: true },
|
Record<string, { text: string; link: string }[]>
|
||||||
{ text: 'Section Header', header: true },
|
>;
|
||||||
{ text: 'Introduction', link: 'en/introduction' },
|
export const SIDEBAR: Sidebar = {
|
||||||
{ text: 'Page 2', link: 'en/page-2' },
|
en: {
|
||||||
{ text: 'Page 3', link: 'en/page-3' },
|
'Section Header': [
|
||||||
|
{ text: 'Introduction', link: 'en/introduction' },
|
||||||
{ text: 'Another Section', header: true },
|
{ text: 'Page 2', link: 'en/page-2' },
|
||||||
{ text: 'Page 4', link: 'en/page-4' },
|
{ text: 'Page 3', link: 'en/page-3' },
|
||||||
],
|
],
|
||||||
|
'Another Section': [{ text: 'Page 4', link: 'en/page-4' }],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 const langPathRegex = /\/([a-z]{2}-?[A-Z]{0,2})\//;
|
||||||
|
|
||||||
export function getLanguageFromURL(pathname: string) {
|
export function getLanguageFromURL(pathname: string) {
|
||||||
const langCodeMatch = pathname.match(langPathRegex);
|
const langCodeMatch = pathname.match(langPathRegex);
|
||||||
return langCodeMatch ? langCodeMatch[1] : 'en';
|
const langCode = langCodeMatch ? langCodeMatch[1] : 'en';
|
||||||
|
return langCode as typeof KNOWN_LANGUAGE_CODES[number];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,18 +6,25 @@ import PageContent from '../components/PageContent/PageContent.astro';
|
||||||
import LeftSidebar from '../components/LeftSidebar/LeftSidebar.astro';
|
import LeftSidebar from '../components/LeftSidebar/LeftSidebar.astro';
|
||||||
import RightSidebar from '../components/RightSidebar/RightSidebar.astro';
|
import RightSidebar from '../components/RightSidebar/RightSidebar.astro';
|
||||||
import * as CONFIG from '../config';
|
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 canonicalURL = new URL(Astro.url.pathname, Astro.site);
|
||||||
const currentPage = Astro.url.pathname;
|
const currentPage = Astro.url.pathname;
|
||||||
const currentFile = `src/pages${currentPage.replace(/\/$/, '')}.md`;
|
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">
|
<html dir={frontmatter.dir ?? 'ltr'} lang={frontmatter.lang ?? 'en-us'} class="initial">
|
||||||
<head>
|
<head>
|
||||||
<HeadCommon />
|
<HeadCommon />
|
||||||
<HeadSEO {frontmatter} canonicalURL={canonicalURL} />
|
<HeadSEO frontmatter={frontmatter} canonicalUrl={canonicalURL} />
|
||||||
<title>
|
<title>
|
||||||
{frontmatter.title ? `${frontmatter.title} 🚀 ${CONFIG.SITE.title}` : CONFIG.SITE.title}
|
{frontmatter.title ? `${frontmatter.title} 🚀 ${CONFIG.SITE.title}` : CONFIG.SITE.title}
|
||||||
</title>
|
</title>
|
||||||
|
@ -29,31 +36,36 @@ const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + current
|
||||||
--gutter: 0.5rem;
|
--gutter: 0.5rem;
|
||||||
--doc-padding: 2rem;
|
--doc-padding: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout {
|
.layout {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-auto-flow: column;
|
grid-auto-flow: column;
|
||||||
grid-template-columns:
|
grid-template-columns: minmax(var(--gutter), 1fr) minmax(0, var(--max-width)) minmax(
|
||||||
minmax(var(--gutter), 1fr)
|
var(--gutter),
|
||||||
minmax(0, var(--max-width))
|
1fr
|
||||||
minmax(var(--gutter), 1fr);
|
);
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout :global(> *) {
|
.layout :global(> *) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-sidebar {
|
.grid-sidebar {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-left {
|
#grid-left {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
background-color: var(--theme-bg);
|
background-color: var(--theme-bg);
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-main {
|
#grid-main {
|
||||||
padding: var(--doc-padding) var(--gutter);
|
padding: var(--doc-padding) var(--gutter);
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
|
@ -61,24 +73,27 @@ const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + current
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-right {
|
#grid-right {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.mobile-sidebar-toggle) {
|
:global(.mobile-sidebar-toggle) {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.mobile-sidebar-toggle) #grid-left {
|
:global(.mobile-sidebar-toggle) #grid-left {
|
||||||
display: block;
|
display: block;
|
||||||
top: 2rem;
|
top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 50em) {
|
@media (min-width: 50em) {
|
||||||
.layout {
|
.layout {
|
||||||
overflow: initial;
|
overflow: initial;
|
||||||
grid-template-columns:
|
grid-template-columns: 20rem minmax(0, var(--max-width));
|
||||||
20rem
|
|
||||||
minmax(0, var(--max-width));
|
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-left {
|
#grid-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-left: 2rem;
|
padding-left: 2rem;
|
||||||
|
@ -89,14 +104,12 @@ const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + current
|
||||||
|
|
||||||
@media (min-width: 72em) {
|
@media (min-width: 72em) {
|
||||||
.layout {
|
.layout {
|
||||||
grid-template-columns:
|
grid-template-columns: 20rem minmax(0, var(--max-width)) 18rem;
|
||||||
20rem
|
|
||||||
minmax(0, var(--max-width))
|
|
||||||
18rem;
|
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-right {
|
#grid-right {
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -106,19 +119,20 @@ const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + current
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<Header {currentPage} />
|
<Header currentPage={currentPage} />
|
||||||
<main class="layout">
|
<main class="layout">
|
||||||
<aside id="grid-left" class="grid-sidebar" title="Site Navigation">
|
<aside id="grid-left" class="grid-sidebar" title="Site Navigation">
|
||||||
<LeftSidebar {currentPage} />
|
<LeftSidebar currentPage={currentPage} />
|
||||||
</aside>
|
</aside>
|
||||||
<div id="grid-main">
|
<div id="grid-main">
|
||||||
<PageContent {frontmatter} {headings} {githubEditUrl}>
|
<PageContent frontmatter={frontmatter} headings={headings} githubEditUrl={githubEditUrl}>
|
||||||
<slot />
|
<slot />
|
||||||
</PageContent>
|
</PageContent>
|
||||||
</div>
|
</div>
|
||||||
<aside id="grid-right" class="grid-sidebar" title="Table of Contents">
|
<aside id="grid-right" class="grid-sidebar" title="Table of Contents">
|
||||||
<RightSidebar {headings} {githubEditUrl} />
|
<RightSidebar headings={headings} githubEditUrl={githubEditUrl} />
|
||||||
</aside>
|
</aside>
|
||||||
</main>
|
</main>
|
||||||
|
<Footer path={currentFile} />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/base"
|
"extends": "astro/tsconfigs/base",
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "preserve",
|
||||||
|
"skipLibCheck": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
1560
pnpm-lock.yaml
1560
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue