style: final consistency pass — theme, responsive, animations
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { Inter, Merriweather, JetBrains_Mono } from 'next/font/google'
|
||||
import { ThemeProvider } from '@wrksz/themes/next'
|
||||
import { Providers } from './providers'
|
||||
import './globals.css'
|
||||
import 'katex/dist/katex.min.css'
|
||||
import { Header } from '@/components/layout/Header'
|
||||
|
||||
@@ -8,7 +8,7 @@ export default function NotFound() {
|
||||
<div className="text-center">
|
||||
<p className="font-mono text-sm text-ink-soft mb-4">404</p>
|
||||
<h1 className="font-sans text-4xl font-bold tracking-tight text-ink mb-4">Page not found</h1>
|
||||
<p className="text-ink-soft mb-8">The page you're looking for doesn't exist.</p>
|
||||
<p className="text-ink-soft mb-8">The page you{`'`}re looking for doesn{`'`}t exist.</p>
|
||||
<Link href="/" className="inline-block rounded-lg bg-ink px-6 py-3 text-sm font-medium text-canvas hover:opacity-80 transition-opacity">
|
||||
Go home
|
||||
</Link>
|
||||
|
||||
@@ -8,10 +8,8 @@ interface TOCItem {
|
||||
level: number;
|
||||
}
|
||||
|
||||
export function TableOfContents() {
|
||||
function useHeadings(): TOCItem[] {
|
||||
const [headings, setHeadings] = useState<TOCItem[]>([]);
|
||||
const [activeId, setActiveId] = useState("");
|
||||
const observerRef = useRef<IntersectionObserver | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const elements = Array.from(
|
||||
@@ -24,8 +22,19 @@ export function TableOfContents() {
|
||||
level: el.tagName === "H2" ? 2 : 3,
|
||||
}));
|
||||
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
setHeadings(parsed);
|
||||
}, []);
|
||||
|
||||
return headings;
|
||||
}
|
||||
|
||||
export function TableOfContents() {
|
||||
const [activeId, setActiveId] = useState("");
|
||||
const observerRef = useRef<IntersectionObserver | null>(null);
|
||||
const headings = useHeadings();
|
||||
|
||||
useEffect(() => {
|
||||
observerRef.current = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
@@ -37,6 +46,10 @@ export function TableOfContents() {
|
||||
{ rootMargin: "-20% 0px -70% 0px", threshold: 0 }
|
||||
);
|
||||
|
||||
const elements = Array.from(
|
||||
document.querySelectorAll("article h2, article h3")
|
||||
) as HTMLElement[];
|
||||
|
||||
elements.forEach((el) => observerRef.current?.observe(el));
|
||||
|
||||
return () => observerRef.current?.disconnect();
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from 'path'
|
||||
import matter from 'gray-matter'
|
||||
import { compileMDX } from 'next-mdx-remote/rsc'
|
||||
import { cache } from 'react'
|
||||
import { useMDXComponents } from '@/mdx-components'
|
||||
import { useMDXComponents as getMDXComponents } from '@/mdx-components'
|
||||
import remarkMath from 'remark-math'
|
||||
import remarkGfm from 'remark-gfm'
|
||||
import rehypeKatex from 'rehype-katex'
|
||||
@@ -58,7 +58,7 @@ export const getPost = async (slug: string): Promise<Post | null> => {
|
||||
const filePath = path.join(postsDirectory, file)
|
||||
const raw = await fs.readFile(filePath, 'utf8')
|
||||
const { data, content } = matter(raw)
|
||||
const components = useMDXComponents({})
|
||||
const components = getMDXComponents({})
|
||||
|
||||
const { content: compiledContent } = await compileMDX({
|
||||
source: content,
|
||||
|
||||
Reference in New Issue
Block a user