| 371 | } |
| 372 | |
| 373 | export function MobileOnPageNav({children}) { |
| 374 | let {currentPage} = useRouter(); |
| 375 | let [selected, setSelected] = useState(''); |
| 376 | useEffect(() => { |
| 377 | let elements = Array.from(document.querySelectorAll('article [data-anchor-link]')); |
| 378 | elements.reverse(); |
| 379 | let visible = new Set(); |
| 380 | let observer = new IntersectionObserver( |
| 381 | entries => { |
| 382 | for (let entry of entries) { |
| 383 | if (entry.isIntersecting) { |
| 384 | visible.add(entry.target); |
| 385 | } else { |
| 386 | visible.delete(entry.target); |
| 387 | } |
| 388 | } |
| 389 | |
| 390 | let lastVisible = elements.find(e => visible.has(e)); |
| 391 | if (lastVisible) { |
| 392 | setSelected('#' + lastVisible.id!); |
| 393 | } else { |
| 394 | setSelected('#' + elements.at(-1)!.id); |
| 395 | } |
| 396 | }, |
| 397 | { |
| 398 | rootMargin: '9999999px 0px -100% 0px', |
| 399 | // @ts-ignore |
| 400 | scrollMargin: '0px 0px 62px 0px', |
| 401 | threshold: 0.5 |
| 402 | } |
| 403 | ); |
| 404 | |
| 405 | for (let element of elements) { |
| 406 | observer.observe(element); |
| 407 | } |
| 408 | |
| 409 | return () => observer.disconnect(); |
| 410 | }, [currentPage]); |
| 411 | |
| 412 | return ( |
| 413 | <Picker aria-label="Table of contents" value={selected} isQuiet size="L"> |
| 414 | {children} |
| 415 | </Picker> |
| 416 | ); |
| 417 | } |