@hortonstudio/main 1.8.1 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/autoInit/accessibility.js +40 -13
- package/package.json +1 -1
|
@@ -672,34 +672,61 @@ export function init() {
|
|
|
672
672
|
// Set up IntersectionObserver for active state (Webflow-style)
|
|
673
673
|
const sections = Array.from(h2Headings).map(heading => heading.parentElement);
|
|
674
674
|
const tocLinks = tocList.querySelectorAll('a');
|
|
675
|
+
let currentActive = null;
|
|
675
676
|
|
|
676
|
-
const
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
};
|
|
677
|
+
const updateActiveLink = () => {
|
|
678
|
+
const windowHeight = window.innerHeight;
|
|
679
|
+
const trigger = windowHeight * 0.75; // 25% from bottom
|
|
680
680
|
|
|
681
|
-
|
|
682
|
-
entries.forEach(entry => {
|
|
683
|
-
if (entry.isIntersecting) {
|
|
684
|
-
const sectionId = entry.target.id;
|
|
681
|
+
let newActive = null;
|
|
685
682
|
|
|
686
|
-
|
|
687
|
-
|
|
683
|
+
// Find the last section whose top is above the trigger point
|
|
684
|
+
for (let i = sections.length - 1; i >= 0; i--) {
|
|
685
|
+
const rect = sections[i].getBoundingClientRect();
|
|
686
|
+
if (rect.top <= trigger) {
|
|
687
|
+
newActive = sections[i].id;
|
|
688
|
+
break;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
688
691
|
|
|
689
|
-
|
|
692
|
+
// Only update if active section changed
|
|
693
|
+
if (newActive !== currentActive) {
|
|
694
|
+
currentActive = newActive;
|
|
695
|
+
|
|
696
|
+
// Remove all is-active
|
|
697
|
+
tocLinks.forEach(link => link.classList.remove('is-active'));
|
|
698
|
+
|
|
699
|
+
// Add to current
|
|
700
|
+
if (currentActive) {
|
|
690
701
|
const activeLink = Array.from(tocLinks).find(link =>
|
|
691
|
-
link.getAttribute('href') === `#${
|
|
702
|
+
link.getAttribute('href') === `#${currentActive}`
|
|
692
703
|
);
|
|
693
704
|
if (activeLink) {
|
|
694
705
|
activeLink.classList.add('is-active');
|
|
695
706
|
}
|
|
696
707
|
}
|
|
697
|
-
}
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
const observerOptions = {
|
|
712
|
+
rootMargin: '0px 0px -75% 0px',
|
|
713
|
+
threshold: 0
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
const observer = new IntersectionObserver(() => {
|
|
717
|
+
updateActiveLink();
|
|
698
718
|
}, observerOptions);
|
|
699
719
|
|
|
700
720
|
// Observe all sections
|
|
701
721
|
sections.forEach(section => observer.observe(section));
|
|
702
722
|
|
|
723
|
+
// Also update on scroll for smoother tracking
|
|
724
|
+
let scrollTimeout;
|
|
725
|
+
window.addEventListener('scroll', () => {
|
|
726
|
+
if (scrollTimeout) clearTimeout(scrollTimeout);
|
|
727
|
+
scrollTimeout = setTimeout(updateActiveLink, 50);
|
|
728
|
+
});
|
|
729
|
+
|
|
703
730
|
});
|
|
704
731
|
}
|
|
705
732
|
|