Skip to content

Commit

Permalink
Merge pull request #25 from lorikku/add-manual-trigger
Browse files Browse the repository at this point in the history
Added manual control possibility over holy loader
  • Loading branch information
tomcru authored Apr 23, 2024
2 parents 2c8f30b + a873138 commit 80b3792
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 23 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,28 @@ export default function RootLayout({ children }) {
}
```

### Programmatic Control (Client Components)

Have an async operation before an eventual route change? You might be interested in holy-loader's manual controls. These only work in client components!

```typescript
'use client';

import { startHolyLoader, stopHolyLoader } from 'holy-loader';

try {
startHolyLoader(); // Trigger the loader beforehand
await signOut(); // Example async operation
} catch (error) {
stopHolyLoader(); // Stop the loader on error
// Handle the error
} finally {
stopHolyLoader(); // Stop the loader after the operation, and potentially do something else
/* OR */
router.push('/'); // Navigate to the desired route, which will automatically stop the loader
}
```

## Common issues

Prevent triggering the loader when clicking a Button within a Next link:
Expand Down
14 changes: 7 additions & 7 deletions src/HolyProgress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,23 +184,23 @@ export class HolyProgress {
* @public
* @returns {HolyProgress} The current instance for chaining methods.
*/
public start = (): HolyProgress => {
public readonly start = (): HolyProgress => {
if (this.status === null) {
this.setTo(0);
}

this.startTrickle();
this.startTrickle();

if (this.settings.showSpinner === true) {
this.createSpinner();
if (this.settings.showSpinner === true) {
this.createSpinner();
}
}

return this;
};

/**
* Performs automatic incrementation of the progress bar.
* This function is recursive and continues to increment the progress at intervals defined by `sppeed`.
* This function is recursive and continues to increment the progress at intervals defined by `speed`.
* @private
*/
private readonly startTrickle = (): void => {
Expand All @@ -219,7 +219,7 @@ export class HolyProgress {
* @public
* @returns {HolyProgress} The current instance for chaining methods.
*/
public complete = (): HolyProgress => this.setTo(1);
public readonly complete = (): HolyProgress => this.setTo(1);

/**
* Calculates an increment value based on the current status of the progress.
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ export const DEFAULTS = {
showSpinner: false,
boxShadow: undefined,
};

export const START_HOLY_EVENT = 'holy-progress-start';
export const STOP_HOLY_EVENT = 'holy-progress-stop';
60 changes: 44 additions & 16 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import * as React from 'react';
import { HolyProgress } from './HolyProgress';
import { DEFAULTS } from './constants';
import { DEFAULTS, START_HOLY_EVENT, STOP_HOLY_EVENT } from './constants';

export interface HolyLoaderProps {
/**
Expand Down Expand Up @@ -97,6 +97,20 @@ export const isSameHost = (currentUrl: string, newUrl: string): boolean => {
);
};

/**
* Dispatches the event to manually start the HolyLoader progress bar.
*/
export const startHolyLoader = (): void => {
document.dispatchEvent(new Event(START_HOLY_EVENT));
};

/**
* Dispatches the event to manually stop the HolyLoader progress bar.
*/
export const stopHolyLoader = (): void => {
document.dispatchEvent(new Event(STOP_HOLY_EVENT));
};

/**
* HolyLoader is a React component that provides a customizable top-loading progress bar.
*
Expand All @@ -113,18 +127,26 @@ const HolyLoader = ({
boxShadow = DEFAULTS.boxShadow,
showSpinner = DEFAULTS.showSpinner,
}: HolyLoaderProps): null => {
React.useEffect(() => {
let holyProgress: HolyProgress;
const holyProgressRef = React.useRef<HolyProgress | null>(null);

React.useEffect(() => {
const startProgress = (): void => {
if (holyProgressRef.current === null) {
return;
}

try {
holyProgress.start();
holyProgressRef.current.start();
} catch (error) {}
};

const stopProgress = (): void => {
if (holyProgressRef.current === null) {
return;
}

try {
holyProgress.complete();
holyProgressRef.current.complete();
} catch (error) {}
};

Expand Down Expand Up @@ -192,25 +214,31 @@ const HolyLoader = ({
};

try {
holyProgress = new HolyProgress({
color,
height,
initialPosition,
easing,
speed,
zIndex,
boxShadow,
showSpinner,
});
if (holyProgressRef.current === null) {
holyProgressRef.current = new HolyProgress({
color,
height,
initialPosition,
easing,
speed,
zIndex,
boxShadow,
showSpinner,
});
}

document.addEventListener('click', handleClick);
document.addEventListener(START_HOLY_EVENT, startProgress);
document.addEventListener(STOP_HOLY_EVENT, stopProgress);
stopProgressOnHistoryUpdate();
} catch (error) {}

return () => {
document.removeEventListener('click', handleClick);
document.removeEventListener(START_HOLY_EVENT, startProgress);
document.removeEventListener(STOP_HOLY_EVENT, stopProgress);
};
}, []);
}, [holyProgressRef]);

return null;
};
Expand Down

0 comments on commit 80b3792

Please sign in to comment.