feat: add smooth scroll animation to TOC navigation with reduced-motion support
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useState, useRef } from "react";
|
import { useEffect, useState, useRef, type MouseEvent } from "react";
|
||||||
|
|
||||||
interface TOCItem {
|
interface TOCItem {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -55,6 +55,22 @@ export function TableOfContents() {
|
|||||||
return () => observerRef.current?.disconnect();
|
return () => observerRef.current?.disconnect();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleLinkClick = (e: MouseEvent<HTMLAnchorElement>, id: string) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const target = document.getElementById(id);
|
||||||
|
if (!target) return;
|
||||||
|
|
||||||
|
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||||
|
|
||||||
|
if (prefersReducedMotion) {
|
||||||
|
window.history.pushState(null, '', `#${id}`);
|
||||||
|
target.scrollIntoView({ behavior: 'auto' });
|
||||||
|
} else {
|
||||||
|
target.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
window.history.pushState(null, '', `#${id}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (headings.length === 0) return null;
|
if (headings.length === 0) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -67,6 +83,7 @@ export function TableOfContents() {
|
|||||||
<li key={heading.id}>
|
<li key={heading.id}>
|
||||||
<a
|
<a
|
||||||
href={`#${heading.id}`}
|
href={`#${heading.id}`}
|
||||||
|
onClick={(e) => handleLinkClick(e, heading.id)}
|
||||||
className={`block text-sm transition-colors ${
|
className={`block text-sm transition-colors ${
|
||||||
heading.level === 3 ? "pl-3 text-ink-soft" : "text-ink"
|
heading.level === 3 ? "pl-3 text-ink-soft" : "text-ink"
|
||||||
} ${activeId === heading.id ? "font-semibold text-accent" : ""}`}
|
} ${activeId === heading.id ? "font-semibold text-accent" : ""}`}
|
||||||
|
|||||||
Reference in New Issue
Block a user