Skip to content

Commit

Permalink
fix: the Loader gets triggered on navigation to link in another tab (#6
Browse files Browse the repository at this point in the history
…) and refactored the code a bit.
  • Loading branch information
TheSGJ committed Mar 16, 2023
1 parent 857b3ed commit ee479df
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 49 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,9 @@
### Updated

- Refactor the code in `useEffect` hook, removed the `next/script`

## v1.2.2

### Fixed

- Fix the Loader gets triggered on navigation to link in another tab
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@ If no props are passed to `<NextTopLoader />`, below is the default configuratio
- `crawl`: auto increamenting behaviour for the TopLoader.
- `showSpinner`: to show spinner or not.

After passing the props reload the your next.js page once in the browser, to see changes for `<NextTopLoader />` ( This is because NextTopLoader uses built-in history api in browser for indicating progress. )
[![Sponsor me on GitHub](https://img.shields.io/badge/Sponsor%20me%20on-GitHub-brightgreen)](https://github.com/sponsors/TheSGJ)

[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/thesgj)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nextjs-toploader",
"version": "1.2.1",
"version": "1.2.2",
"description": "A Next.js Top Loading Bar component made using nprogress, works with Next.js 13.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
95 changes: 48 additions & 47 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface NextTopLoaderProps {
*/
crawlSpeed?: number;
/**
* The height for the TopLoader.
* The height for the TopLoader in pixels (px).
* @default 3
*/
height?: number;
Expand All @@ -53,74 +53,75 @@ export interface NextTopLoaderProps {
speed?: number;
}

const NextTopLoader = (props: NextTopLoaderProps) => {
const color = '#29d';
const height = 3;
const NextTopLoader = ({
color,
height,
showSpinner,
crawl,
crawlSpeed,
initialPosition,
easing,
speed,
}: NextTopLoaderProps) => {
const defaultColor = '#29d';
const defaultHeight = 3;

const styles = (
<style>
{`#nprogress{pointer-events:none}#nprogress .bar{background:${
props.color ? props.color : color
color ?? defaultColor
};position:fixed;z-index:1031;top:0;left:0;width:100%;height:${
props.height ? props.height : height
height ?? defaultHeight
}px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px ${
props.color ? props.color : color
color ?? defaultColor
},0 0 5px ${
props.color ? props.color : color
color ?? defaultColor
};opacity:1;-webkit-transform:rotate(3deg) translate(0px,-4px);-ms-transform:rotate(3deg) translate(0px,-4px);transform:rotate(3deg) translate(0px,-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:${
props.color ? props.color : color
color ?? defaultColor
};border-left-color:${
props.color ? props.color : color
color ?? defaultColor
};border-radius:50%;-webkit-animation:nprogress-spinner 400ms linear infinite;animation:nprogress-spinner 400ms linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}`}
</style>
);

React.useEffect(() => {
if (props.showSpinner !== undefined) {
NProgress.configure({ showSpinner: props.showSpinner });
}
if (props.crawl !== undefined) {
NProgress.configure({ trickle: props.crawl });
}
if (props.crawlSpeed !== undefined) {
NProgress.configure({ trickleSpeed: props.crawlSpeed });
}
if (props.initialPosition !== undefined) {
NProgress.configure({ minimum: props.initialPosition });
}
if (props.easing !== undefined) {
NProgress.configure({ easing: props.easing });
}
if (props.speed !== undefined) {
NProgress.configure({ speed: props.speed });
NProgress.configure({
showSpinner: showSpinner ?? true,
trickle: crawl ?? true,
trickleSpeed: crawlSpeed ?? 200,
minimum: initialPosition ?? 0.08,
easing: easing ?? 'ease',
speed: speed ?? 200,
});

function isAnchorOfCurrentUrl(currentUrl: string, newUrl: string) {
const currentUrlObj = new URL(currentUrl);
const newUrlObj = new URL(newUrl);
// Compare hostname, pathname, and search parameters
if (
currentUrlObj.hostname === newUrlObj.hostname &&
currentUrlObj.pathname === newUrlObj.pathname &&
currentUrlObj.search === newUrlObj.search
) {
// Check if the new URL is just an anchor of the current URL page
const currentHash = currentUrlObj.hash;
const newHash = newUrlObj.hash;
return (
currentHash !== newHash && currentUrlObj.href.replace(currentHash, '') === newUrlObj.href.replace(newHash, '')
);
}
return false;
}

// eslint-disable-next-line no-var
var npgclass = document.querySelectorAll('html');
let navLinks = document.querySelectorAll('a');
navLinks.forEach((navLink) => {
navLink.addEventListener('click', (event: MouseEvent) => {
let currentUrl = window.location.href;
let newUrl = (event.currentTarget as HTMLAnchorElement).href;
let isExternalLink = (event.currentTarget as HTMLAnchorElement).target === "_blank";
function isAnchorOfCurrentUrl(currentUrl: string, newUrl: string) {
const currentUrlObj = new URL(currentUrl);
const newUrlObj = new URL(newUrl);
// Compare hostname, pathname, and search parameters
if (
currentUrlObj.hostname === newUrlObj.hostname &&
currentUrlObj.pathname === newUrlObj.pathname &&
currentUrlObj.search === newUrlObj.search
) {
// Check if the new URL is just an anchor of the current URL page
const currentHash = currentUrlObj.hash;
const newHash = newUrlObj.hash;
return (
currentHash !== newHash &&
currentUrlObj.href.replace(currentHash, '') === newUrlObj.href.replace(newHash, '')
);
}
return false;
}
const isExternalLink = (event.currentTarget as HTMLAnchorElement).target === '_blank';

const isAnchor = isAnchorOfCurrentUrl(currentUrl, newUrl);
if (newUrl === currentUrl || isAnchor || isExternalLink) {
NProgress.start();
Expand Down

0 comments on commit ee479df

Please sign in to comment.