|
1 | | -import { useState } from 'react'; |
2 | | -import { ChevronRight, Terminal, Cpu, Shield, Zap, Users, Database, FileCode, BookOpen } from 'lucide-react'; |
| 1 | +import { useState, useEffect, useRef } from 'react'; |
| 2 | +import { Terminal, Cpu, Shield, Zap, Users, Database, FileCode, BookOpen } from 'lucide-react'; |
3 | 3 | import { CodeBlock } from '../components/CodeBlock'; |
4 | 4 | import clsx from 'clsx'; |
5 | 5 |
|
@@ -56,6 +56,36 @@ function Callout({ type, title, children }: { type: 'info' | 'warning' | 'tip'; |
56 | 56 |
|
57 | 57 | export function LearnPage() { |
58 | 58 | const [activeSection, setActiveSection] = useState('introduction'); |
| 59 | + const mainRef = useRef<HTMLElement>(null); |
| 60 | + |
| 61 | + // Track which section is currently visible using Intersection Observer |
| 62 | + useEffect(() => { |
| 63 | + const observerOptions = { |
| 64 | + root: mainRef.current, |
| 65 | + rootMargin: '-20% 0px -70% 0px', // Trigger when section is in upper portion of viewport |
| 66 | + threshold: 0, |
| 67 | + }; |
| 68 | + |
| 69 | + const observerCallback: IntersectionObserverCallback = (entries) => { |
| 70 | + entries.forEach((entry) => { |
| 71 | + if (entry.isIntersecting) { |
| 72 | + setActiveSection(entry.target.id); |
| 73 | + } |
| 74 | + }); |
| 75 | + }; |
| 76 | + |
| 77 | + const observer = new IntersectionObserver(observerCallback, observerOptions); |
| 78 | + |
| 79 | + // Observe all section elements |
| 80 | + sections.forEach((section) => { |
| 81 | + const element = document.getElementById(section.id); |
| 82 | + if (element) { |
| 83 | + observer.observe(element); |
| 84 | + } |
| 85 | + }); |
| 86 | + |
| 87 | + return () => observer.disconnect(); |
| 88 | + }, []); |
59 | 89 |
|
60 | 90 | const scrollToSection = (id: string) => { |
61 | 91 | setActiveSection(id); |
@@ -94,7 +124,7 @@ export function LearnPage() { |
94 | 124 | </aside> |
95 | 125 |
|
96 | 126 | {/* Main content - Article */} |
97 | | - <main className="flex-1 overflow-auto bg-[#010409]"> |
| 127 | + <main ref={mainRef} className="flex-1 overflow-auto bg-[#010409]"> |
98 | 128 | <div className="max-w-3xl mx-auto px-16 py-20"> |
99 | 129 | <article className="space-y-6"> |
100 | 130 | {/* Introduction */} |
|
0 commit comments