This commit is contained in:
Pascal Fischer
2023-05-10 00:46:38 +02:00
parent c15d7607e2
commit 6131138e65
13 changed files with 476 additions and 25 deletions

View File

@@ -0,0 +1,273 @@
import { useCallback, useEffect, useState } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import clsx from 'clsx'
import { Logo, Logomark } from '@/components/Logo'
import { MobileNavigation } from '@/components/MobileNavigation'
import { Prose } from '@/components/Prose'
import { Search } from '@/components/Search'
import {HeroPattern} from "@/components/HeroPattern";
import {NavigationDocs} from "@/components/NavigationDocs";
import {Header} from "@/components/Header";
import {NavigationAPI} from "@/components/NavigationAPI";
import {motion} from "framer-motion";
import {Footer} from "@/components/Footer";
const navigation = [
{
title: 'Introduction',
links: [
{ title: 'Getting started', href: '/' },
{ title: 'Installation', href: '/docs/installation' },
],
},
{
title: 'Core concepts',
links: [
{ title: 'Understanding caching', href: '/docs/understanding-caching' },
{
title: 'Predicting user behavior',
href: '/docs/predicting-user-behavior',
},
{ title: 'Basics of time-travel', href: '/docs/basics-of-time-travel' },
{
title: 'Introduction to string theory',
href: '/docs/introduction-to-string-theory',
},
{ title: 'The butterfly effect', href: '/docs/the-butterfly-effect' },
],
},
{
title: 'Advanced guides',
links: [
{ title: 'Writing plugins', href: '/docs/writing-plugins' },
{ title: 'Neuralink integration', href: '/docs/neuralink-integration' },
{ title: 'Temporal paradoxes', href: '/docs/temporal-paradoxes' },
{ title: 'Testing', href: '/docs/testing' },
{ title: 'Compile-time caching', href: '/docs/compile-time-caching' },
{
title: 'Predictive data generation',
href: '/docs/predictive-data-generation',
},
],
},
{
title: 'API reference',
links: [
{ title: 'CacheAdvance.predict()', href: '/docs/cacheadvance-predict' },
{ title: 'CacheAdvance.flush()', href: '/docs/cacheadvance-flush' },
{ title: 'CacheAdvance.revert()', href: '/docs/cacheadvance-revert' },
{ title: 'CacheAdvance.regret()', href: '/docs/cacheadvance-regret' },
],
},
{
title: 'Contributing',
links: [
{ title: 'How to contribute', href: '/docs/how-to-contribute' },
{ title: 'Architecture guide', href: '/docs/architecture-guide' },
{ title: 'Design principles', href: '/docs/design-principles' },
],
},
]
function GitHubIcon(props) {
return (
<svg aria-hidden="true" viewBox="0 0 16 16" {...props}>
<path d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z" />
</svg>
)
}
// function Header({ navigation }) {
// let [isScrolled, setIsScrolled] = useState(false)
//
// useEffect(() => {
// function onScroll() {
// setIsScrolled(window.scrollY > 0)
// }
// onScroll()
// window.addEventListener('scroll', onScroll, { passive: true })
// return () => {
// window.removeEventListener('scroll', onScroll)
// }
// }, [])
//
// return (
// <header
// className={clsx(
// 'sticky top-0 z-50 flex flex-wrap items-center justify-between bg-white px-4 py-5 shadow-md shadow-slate-900/5 transition duration-500 dark:shadow-none sm:px-6 lg:px-8',
// isScrolled
// ? 'dark:bg-slate-900/95 dark:backdrop-blur dark:[@supports(backdrop-filter:blur(0))]:bg-slate-900/75'
// : 'dark:bg-transparent'
// )}
// >
// <div className="mr-6 flex lg:hidden">
// <MobileNavigation navigation={navigation} />
// </div>
// <div className="relative flex flex-grow basis-0 items-center">
// <Link href="/" aria-label="Home page">
// <Logomark className="h-9 w-9 lg:hidden" />
// <Logo className="hidden h-9 w-auto fill-slate-700 dark:fill-sky-100 lg:block" />
// </Link>
// </div>
// <div className="-my-5 mr-6 sm:mr-8 md:mr-0">
// <Search />
// </div>
// <div className="relative flex basis-0 justify-end gap-6 sm:gap-8 md:flex-grow">
// <Link href="https://github.com" className="group" aria-label="GitHub">
// <GitHubIcon className="h-6 w-6 fill-slate-400 group-hover:fill-slate-500 dark:group-hover:fill-slate-300" />
// </Link>
// </div>
// </header>
// )
// }
function useTableOfContents(tableOfContents) {
let [currentSection, setCurrentSection] = useState(tableOfContents[0]?.id)
let getHeadings = useCallback((tableOfContents) => {
return tableOfContents
.flatMap((node) => [node.id, ...node.children.map((child) => child.id)])
.map((id) => {
let el = document.getElementById(id)
if (!el) return
let style = window.getComputedStyle(el)
let scrollMt = parseFloat(style.scrollMarginTop)
let top = window.scrollY + el.getBoundingClientRect().top - scrollMt
return { id, top }
})
}, [])
useEffect(() => {
if (tableOfContents.length === 0) return
let headings = getHeadings(tableOfContents)
function onScroll() {
let top = window.scrollY
let current = headings[0].id
for (let heading of headings) {
if (top >= heading.top) {
current = heading.id
} else {
break
}
}
setCurrentSection(current)
}
window.addEventListener('scroll', onScroll, { passive: true })
onScroll()
return () => {
window.removeEventListener('scroll', onScroll)
}
}, [getHeadings, tableOfContents])
return currentSection
}
export function LayoutDocs({ children, title, tableOfContents }) {
let router = useRouter()
let isHomePage = router.pathname === '/'
let allLinks = navigation.flatMap((section) => section.links)
let linkIndex = allLinks.findIndex((link) => link.href === router.pathname)
let previousPage = allLinks[linkIndex - 1]
let nextPage = allLinks[linkIndex + 1]
let section = navigation.find((section) =>
section.links.find((link) => link.href === router.pathname)
)
let currentSection = useTableOfContents(tableOfContents)
function isActive(section) {
if (section.id === currentSection) {
return true
}
if (!section.children) {
return false
}
return section.children.findIndex(isActive) > -1
}
return (
<>
{/*<Header navigation={navigation} />*/}
<HeroPattern/>
<div className="relative mx-auto flex max-w-8xl justify-center sm:px-2 lg:px-8 xl:px-12 lg:ml-72 xl:ml-80">
<motion.header
layoutScroll
className="contents lg:pointer-events-none lg:fixed lg:inset-0 lg:z-40 lg:flex"
>
<div className="contents lg:pointer-events-auto lg:block lg:w-72 lg:overflow-y-auto lg:border-r lg:border-zinc-900/10 lg:px-6 lg:pb-8 lg:pt-4 lg:dark:border-white/10 xl:w-80">
<div className="hidden lg:flex">
<Link href="/" aria-label="Home">
<Logo className="h-6" />
</Link>
</div>
<Header />
<NavigationDocs className="hidden lg:mt-10 lg:block" />
</div>
</motion.header>
<div className="min-w-0 max-w-2xl flex-auto px-4 py-16 lg:max-w-none lg:pl-8 lg:pr-0 xl:px-16">
<main className="py-16">
<Prose as="article">{children}</Prose>
</main>
<Footer />
</div>
<div className="hidden xl:sticky xl:top-[4.5rem] xl:-mr-6 xl:block xl:h-[calc(100vh-4.5rem)] xl:flex-none xl:overflow-y-auto xl:py-16 xl:pr-6">
<nav aria-labelledby="on-this-page-title" className="w-56">
{tableOfContents.length > 0 && (
<>
{/*<h2*/}
{/* id="on-this-page-title"*/}
{/* className="font-display text-sm font-medium text-slate-900 dark:text-white"*/}
{/*>*/}
{/* On this page*/}
{/*</h2>*/}
<ol role="list" className="mt-4 space-y-3 text-sm">
{tableOfContents.map((section) => (
<li key={section.id}>
<h3>
<Link
href={`#${section.id}`}
className={clsx(
isActive(section)
? 'text-orange-500'
: 'font-normal text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-300'
)}
>
{section.title}
</Link>
</h3>
{section.children.length > 0 && (
<ol
role="list"
className="mt-2 space-y-3 pl-5 text-slate-500 dark:text-slate-400"
>
{section.children.map((subSection) => (
<li key={subSection.id}>
<Link
href={`#${subSection.id}`}
className={
isActive(subSection)
? 'text-orange-500'
: 'hover:text-slate-600 dark:hover:text-slate-300'
}
>
{subSection.title}
</Link>
</li>
))}
</ol>
)}
</li>
))}
</ol>
</>
)}
</nav>
</div>
</div>
</>
)
}