UNPKG

highlight-scroll

Version:

A lightweight and efficient Scroll Highlight plugin for Alpine.js, helping you track active sections on scroll.

2 lines (1 loc) 3.31 kB
function a(c={}){return function(i){let p=c.offset??50,S=c.highlightClasses??"ease-in-out text-blue-500 scale-110 dark:text-blue-500 transition-all";i.store("HighlightScroll",{groups:{},getGroup(t){return t||(t="default"),this.groups[t]||(this.groups[t]={scrollEl:window,offset:c.offset??50,highlightClasses:c.highlightClasses??"ease-in-out text-blue-500 scale-110 dark:text-blue-500 transition-all",items:[],sections:[]}),this.groups[t]},setGroupOptions({group:t="default",offset:o,highlightClasses:e}){let l=this.getGroup(t);typeof o<"u"&&(l.offset=o),typeof e<"u"&&(l.highlightClasses=e)},setScrollable({group:t="default",el:o}){let e=this.getGroup(t);e.scrollEl=o},registerItem({group:t="default",el:o,target:e}){this.getGroup(t).items.push({el:o,target:e})},registerSection({group:t="default",el:o,id:e}){this.getGroup(t).sections.push({el:o,id:e})},onScroll(t="default"){let o=this.getGroup(t),e=o.scrollEl;if(!e)return;let l=e===window?window.scrollY:e.scrollTop,r="";for(let s=0;s<o.sections.length;s++){let f=o.sections[s],n=o.sections[s+1],h=f.el.offsetTop-o.offset,d=n?n.el.offsetTop-o.offset:1/0;if(l>=h&&l<d){r=f.id;break}}for(let s of o.items)s.el.classList.remove(...o.highlightClasses.split(" "));if(r){let s=o.items.find(f=>f.target===r);s&&s.el.classList.add(...o.highlightClasses.split(" "))}},smoothScrollTo({group:t="default",target:o}){let e=this.getGroup(t),l=e.scrollEl,r=document.getElementById(o);if(!r)return;let s=r.offsetTop-e.offset;l===window?window.scrollTo({top:s,behavior:"smooth"}):l.scrollTo({top:s,behavior:"smooth"})}});function g({expression:t,evaluate:o,defaultProp:e}){if(!t||!t.trim())return{};try{let l=o(t);return typeof l=="string"?{[e]:l}:l&&typeof l=="object"?l:{[e]:t}}catch{return{[e]:t}}}i.directive("scroll-group",(t,{expression:o},{evaluate:e})=>{let l=g({expression:o,evaluate:e,defaultProp:"group"}),r=l.group||"default";i.store("HighlightScroll").setGroupOptions({group:r,offset:l.offset,highlightClasses:l.highlightClasses}),t.dataset.scrollGroup=r}),i.directive("scroll-container",(t,{expression:o},{evaluate:e})=>{let r=g({expression:o,evaluate:e,defaultProp:"group"}).group||u(t)||"default";i.store("HighlightScroll").setScrollable({group:r,el:t}),t.addEventListener("scroll",()=>{i.store("HighlightScroll").onScroll(r)}),i.store("HighlightScroll").onScroll(r)}),i.directive("scroll-item",(t,{expression:o},{evaluate:e})=>{let l;typeof o=="string"?l=g({expression:o,evaluate:e,defaultProp:"target"}):l=o;let r=l.group||u(t),s=l.target||l.id;s&&(i.store("HighlightScroll").registerItem({group:r,el:t,target:s}),t.addEventListener("click",()=>{i.store("HighlightScroll").smoothScrollTo({group:r,target:s})}))}),i.directive("scroll-section",(t,{expression:o},{evaluate:e})=>{let l;typeof o=="string"?l=g({expression:o,evaluate:e,defaultProp:"id"}):l=o;let r=l.group||u(t),s=l.id;s&&(t.id||(t.id=s),i.store("HighlightScroll").registerSection({group:r,el:t,id:s}))}),window.addEventListener("scroll",()=>{i.store("HighlightScroll").getGroup("default").scrollEl===window&&i.store("HighlightScroll").onScroll("default")}),i.store("HighlightScroll").getGroup("default").scrollEl===window&&i.store("HighlightScroll").onScroll("default");function u(t){let o=t.closest("[data-scroll-group]");return o?o.dataset.scrollGroup:"default"}}}var H=a;export{H as default};