| 390 | } |
| 391 | |
| 392 | export function MobileOnPageNav({children}) { |
| 393 | let {currentPage} = useRouter(); |
| 394 | let [selected, setSelected] = useState(''); |
| 395 | useEffect(() => { |
| 396 | let elements = Array.from(document.querySelectorAll('article [data-anchor-link]')); |
| 397 | elements.reverse(); |
| 398 | let visible = new Set(); |
| 399 | let observer = new IntersectionObserver( |
| 400 | entries => { |
| 401 | for (let entry of entries) { |
| 402 | if (entry.isIntersecting) { |
| 403 | visible.add(entry.target); |
| 404 | } else { |
| 405 | visible.delete(entry.target); |
| 406 | } |
| 407 | } |
| 408 | |
| 409 | let lastVisible = elements.find(e => visible.has(e)); |
| 410 | if (lastVisible) { |
| 411 | setSelected('#' + lastVisible.id!); |
| 412 | } else { |
| 413 | setSelected('#' + elements.at(-1)!.id); |
| 414 | } |
| 415 | }, |
| 416 | { |
| 417 | rootMargin: '9999999px 0px -100% 0px', |
| 418 | // @ts-ignore |
| 419 | scrollMargin: '0px 0px 62px 0px', |
| 420 | threshold: 0.5 |
| 421 | } |
| 422 | ); |
| 423 | |
| 424 | for (let element of elements) { |
| 425 | observer.observe(element); |
| 426 | } |
| 427 | |
| 428 | return () => observer.disconnect(); |
| 429 | }, [currentPage]); |
| 430 | |
| 431 | return ( |
| 432 | <Picker aria-label="Table of contents" value={selected} isQuiet size="L"> |
| 433 | {children} |
| 434 | </Picker> |
| 435 | ); |
| 436 | } |