react-anchor-navigation
Version:
React lightweight library for anchor scrolling and navigation tied to URL hash.
7 lines (6 loc) • 3.65 kB
JavaScript
/**
* @license react-anchor-navigation 0.2.7
* MIT License
* License: MIT
*/
;Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("react"),r=(e=t)&&"object"==typeof e&&"default"in e?e.default:e,n=()=>{},s=t.createContext({offset:0,sections:[],hash:"",registerSection:n,unregisterSection:n,setHash:n});function o(){return(o=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}function c(e,t){if(null==e)return{};var r,n,s=function(e,t){if(null==e)return{};var r,n,s={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(s[r]=e[r]);return s}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var a=["children","className","activeClassName"];var i="undefined"!=typeof addEventListener&&(()=>{var e=!1;try{var t=()=>{},r=Object.defineProperty({},"passive",{get:()=>e=!0});addEventListener("testPassive",t,r),removeEventListener("testPassive",t,r)}catch(e){}return e})();var l=(e,t)=>{var r=0,n=e;do{r+=n.offsetTop,n=n.offsetParent}while(n&&n!==t);return r},u=i&&{capture:!1,passive:!0};function f(e,r){t.useEffect(()=>{var t=t=>{var{blockScrollEvent:n,sections:s,scroller:o,offset:c}=e.current;if(!n&&s.length){var a=(o?o.scrollTop:window.pageYOffset||document.documentElement.scrollTop)+c;if(l(s[0],o)>a)t&&r("#",!1);else{var i=s.findIndex(e=>l(e,o)>a),u=-1===i?s[s.length-1]:s[Math.max(i-1,0)];u&&r("#".concat(u.id),!1)}}},n=function(e,t){var r=null;function n(){r||(r=setTimeout(()=>{r=null,e()},t))}return n.cancel=()=>{r&&(clearTimeout(r),r=null)},n}(t,100);return addEventListener("scroll",n,u),t(),()=>{removeEventListener("scroll",n,u),n.cancel()}},[])}var v=["children"];exports.AnchorContext=s,exports.AnchorLink=function(e){var{children:n,className:i,activeClassName:l}=e,u=c(e,a),{hash:f}=t.useContext(s),v=(i?"".concat(i," "):"")+(f===u.href?l:"");return r.createElement("a",o({},u,{className:v}),n)},exports.AnchorProvider=function(e){var{children:n,getScroller:o,offset:c=0}=e,a=t.useRef({offset:c,sections:[],blockScrollEvent:!1,scroller:null});o&&(a.current.scroller=o());var[i,u]=function(e){var[r,n]=t.useState("");return t.useEffect(()=>{var t=t=>{n(location.hash),t&&"hashchange"===t.type&&(e.current.blockScrollEvent=!0,setTimeout(()=>{e.current.blockScrollEvent=!1},100))};return addEventListener("hashchange",t,!1),addEventListener("popstate",t,!1),t(),()=>{removeEventListener("hashchange",t,!1),removeEventListener("popstate",t,!1)}},[]),[r,function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];n(e),"undefined"!=typeof history&&"undefined"!=typeof location&&(t||!("pushState"in history)?location.hash=e:history.pushState(null,e.substr(1),e))}]}(a);return f(a,u),r.createElement(s.Provider,{value:{offset:c,hash:i,sections:a.current.sections,setHash:u,registerSection:e=>{var{sections:t,scroller:r}=a.current;if(!t.includes(e)){var n=l(e,r),s=t.findIndex(e=>l(e,r)>n);-1===s?t.push(e):t.splice(s,0,e)}},unregisterSection:e=>{var t=a.current.sections.indexOf(e);-1!==t&&a.current.sections.splice(t,1)}}},n)},exports.AnchorSection=function(e){var{children:n}=e,a=c(e,v),{registerSection:i,unregisterSection:l}=t.useContext(s),u=t.useRef(null);return t.useEffect(()=>(u.current&&(i(u.current),a.id===location.hash.substr(1)&&u.current.scrollIntoView()),()=>{u.current&&l(u.current)}),[]),r.createElement(r.Fragment,null,r.createElement("b",o({},a,{ref:u})),n)};