(sectionStore: StoreApi<SectionState>)
| 63 | } |
| 64 | |
| 65 | function useVisibleSections(sectionStore: StoreApi<SectionState>) { |
| 66 | let setVisibleSections = useStore(sectionStore, (s) => s.setVisibleSections) |
| 67 | let sections = useStore(sectionStore, (s) => s.sections) |
| 68 | |
| 69 | useEffect(() => { |
| 70 | function checkVisibleSections() { |
| 71 | let { innerHeight, scrollY } = window |
| 72 | let newVisibleSections = [] |
| 73 | |
| 74 | for ( |
| 75 | let sectionIndex = 0; |
| 76 | sectionIndex < sections.length; |
| 77 | sectionIndex++ |
| 78 | ) { |
| 79 | let { id, headingRef, offsetRem = 0 } = sections[sectionIndex] |
| 80 | |
| 81 | if (!headingRef?.current) { |
| 82 | continue |
| 83 | } |
| 84 | |
| 85 | let offset = remToPx(offsetRem) |
| 86 | let top = headingRef.current.getBoundingClientRect().top + scrollY |
| 87 | |
| 88 | if (sectionIndex === 0 && top - offset > scrollY) { |
| 89 | newVisibleSections.push('_top') |
| 90 | } |
| 91 | |
| 92 | let nextSection = sections[sectionIndex + 1] |
| 93 | let bottom = |
| 94 | (nextSection?.headingRef?.current?.getBoundingClientRect().top ?? |
| 95 | Infinity) + |
| 96 | scrollY - |
| 97 | remToPx(nextSection?.offsetRem ?? 0) |
| 98 | |
| 99 | if ( |
| 100 | (top > scrollY && top < scrollY + innerHeight) || |
| 101 | (bottom > scrollY && bottom < scrollY + innerHeight) || |
| 102 | (top <= scrollY && bottom >= scrollY + innerHeight) |
| 103 | ) { |
| 104 | newVisibleSections.push(id) |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | setVisibleSections(newVisibleSections) |
| 109 | } |
| 110 | |
| 111 | let raf = window.requestAnimationFrame(() => checkVisibleSections()) |
| 112 | window.addEventListener('scroll', checkVisibleSections, { passive: true }) |
| 113 | window.addEventListener('resize', checkVisibleSections) |
| 114 | |
| 115 | return () => { |
| 116 | window.cancelAnimationFrame(raf) |
| 117 | window.removeEventListener('scroll', checkVisibleSections) |
| 118 | window.removeEventListener('resize', checkVisibleSections) |
| 119 | } |
| 120 | }, [setVisibleSections, sections]) |
| 121 | } |
| 122 |
no test coverage detected