/ tutorials / laplace-dirichlet
Sign in
tutorials / laplace-dirichlet
laplace-dirichlet / src / App.tsx
92 lines · 3.1 KBCodeBlameHistory
088be4cAn interactive tutorial on the Dirichlet problem, accuracy against costJeremy Magland 1import { useCallback, useEffect, useState } from 'react'
2import ChapterView from './ui/ChapterView.tsx'
3import LibraryView from './ui/LibraryView.tsx'
4import { CHAPTERS } from './chapters/index.ts'
6const PARTS = ['One dimension', 'Two dimensions', 'Beyond the square'] as const
8function readHash(): string {
9 const h = window.location.hash.replace(/^#\/?/, '')
10 return h === '' ? CHAPTERS[0].id : h
13export default function App() {
14 const [route, setRoute] = useState(readHash)
15 useEffect(() => {
16 const on = () => setRoute(readHash())
17 window.addEventListener('hashchange', on)
18 return () => window.removeEventListener('hashchange', on)
19 }, [])
21 const go = useCallback((id: string) => {
22 window.location.hash = `/${id}`
23 window.scrollTo({ top: 0 })
24 }, [])
26 const chapter = CHAPTERS.find((c) => c.id === route)
27 const index = CHAPTERS.findIndex((c) => c.id === route)
29 return (
30 <div className="app">
31 <nav className="sidebar">
32 <div className="brand">
33 <div className="brand-title">The Dirichlet problem</div>
34 <div className="brand-sub">accuracy against cost, in the browser</div>
35 </div>
36 {PARTS.map((part) => (
37 <div className="nav-part" key={part}>
38 <div className="nav-part-title">{part}</div>
39 <ol>
40 {CHAPTERS.filter((c) => c.part === part).map((c) => (
41 <li key={c.id}>
42 <button className={c.id === route ? 'nav-item active' : 'nav-item'} onClick={() => go(c.id)}>
43 <span className="nav-num">{CHAPTERS.indexOf(c) + 1}</span>
44 {c.nav}
45 </button>
46 </li>
47 ))}
48 </ol>
49 </div>
50 ))}
51 <div className="nav-part">
52 <div className="nav-part-title">Reference</div>
53 <ol>
54 <li>
55 <button className={route === 'library' ? 'nav-item active' : 'nav-item'} onClick={() => go('library')}>
56 <span className="nav-num" />
57 shared MATLAB library
58 </button>
59 </li>
60 </ol>
61 </div>
62 <div className="nav-foot">
63 MATLAB syntax runs in your browser through <a href="https://numbl.org">numbl</a>. Nothing is installed and
64 nothing is sent anywhere.
65 </div>
66 </nav>
68 <main className="main">
69 {route === 'library' ? (
70 <LibraryView />
71 ) : chapter ? (
72 <>
73 <ChapterView chapter={chapter} />
74 <nav className="pager">
75 {index > 0 && (
76 <button onClick={() => go(CHAPTERS[index - 1].id)}>
77 &larr; {CHAPTERS[index - 1].nav}
78 </button>
79 )}
80 <span className="lab-bar-gap" />
81 {index < CHAPTERS.length - 1 && (
82 <button onClick={() => go(CHAPTERS[index + 1].id)}>{CHAPTERS[index + 1].nav} &rarr;</button>
83 )}
84 </nav>
85 </>
86 ) : (
87 <p className="lab-error">no such chapter: {route}</p>
88 )}
89 </main>
90 </div>
91 )
↑↓ move↵openescclose