New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

react-top-progress

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-top-progress - npm Package Compare versions

Comparing version
0.1.1
to
1.0.0
demo_react_top_progress.webp

Sorry, the diff of this file is not supported yet

+33
-4

@@ -1,6 +0,18 @@

import * as react_jsx_runtime from 'react/jsx-runtime';
import React, { CSSProperties } from 'react';
interface TopProgressProps {
progress?: number;
color?: string;
shadow?: boolean;
height?: number;
background?: string;
style?: CSSProperties;
containerStyle?: CSSProperties;
shadowStyle?: CSSProperties;
transitionTime?: number;
loaderSpeed?: number;
waitingTime?: number;
className?: string;
containerClassName?: string;
onLoaderFinished?: () => void;
showGlow?: boolean;

@@ -10,8 +22,25 @@ glowColor?: string;

}
declare const TopProgress: ({ color, height, showGlow, glowColor, zIndex, }: TopProgressProps) => react_jsx_runtime.JSX.Element | null;
interface TopProgressRef {
start: (loaderType?: "continuous" | "static") => void;
continuousStart: (startingValue?: number, refreshRate?: number) => void;
staticStart: (startingValue?: number) => void;
complete: () => void;
increase: (value: number) => void;
decrease: (value: number) => void;
getProgress: () => number | null;
set: (value: number) => void;
}
declare const TopProgress: React.ForwardRefExoticComponent<TopProgressProps & React.RefAttributes<TopProgressRef>>;
declare const startProgress: () => void;
declare const startProgress: (type?: "continuous" | "static") => void;
declare const continuousStart: (startingValue?: number, refreshRate?: number) => void;
declare const staticStart: (startingValue?: number) => void;
declare const finishProgress: () => void;
declare const completeProgress: () => void;
declare const increaseProgress: (value: number) => void;
declare const decreaseProgress: (value: number) => void;
declare const getProgress: () => number | null;
declare const setProgress: (value: number) => void;
declare const withProgress: <T>(promise: Promise<T>) => Promise<T>;
export { TopProgress, finishProgress, startProgress, withProgress };
export { TopProgress, type TopProgressProps, type TopProgressRef, completeProgress, continuousStart, decreaseProgress, finishProgress, getProgress, increaseProgress, setProgress, startProgress, staticStart, withProgress };

@@ -1,6 +0,18 @@

import * as react_jsx_runtime from 'react/jsx-runtime';
import React, { CSSProperties } from 'react';
interface TopProgressProps {
progress?: number;
color?: string;
shadow?: boolean;
height?: number;
background?: string;
style?: CSSProperties;
containerStyle?: CSSProperties;
shadowStyle?: CSSProperties;
transitionTime?: number;
loaderSpeed?: number;
waitingTime?: number;
className?: string;
containerClassName?: string;
onLoaderFinished?: () => void;
showGlow?: boolean;

@@ -10,8 +22,25 @@ glowColor?: string;

}
declare const TopProgress: ({ color, height, showGlow, glowColor, zIndex, }: TopProgressProps) => react_jsx_runtime.JSX.Element | null;
interface TopProgressRef {
start: (loaderType?: "continuous" | "static") => void;
continuousStart: (startingValue?: number, refreshRate?: number) => void;
staticStart: (startingValue?: number) => void;
complete: () => void;
increase: (value: number) => void;
decrease: (value: number) => void;
getProgress: () => number | null;
set: (value: number) => void;
}
declare const TopProgress: React.ForwardRefExoticComponent<TopProgressProps & React.RefAttributes<TopProgressRef>>;
declare const startProgress: () => void;
declare const startProgress: (type?: "continuous" | "static") => void;
declare const continuousStart: (startingValue?: number, refreshRate?: number) => void;
declare const staticStart: (startingValue?: number) => void;
declare const finishProgress: () => void;
declare const completeProgress: () => void;
declare const increaseProgress: (value: number) => void;
declare const decreaseProgress: (value: number) => void;
declare const getProgress: () => number | null;
declare const setProgress: (value: number) => void;
declare const withProgress: <T>(promise: Promise<T>) => Promise<T>;
export { TopProgress, finishProgress, startProgress, withProgress };
export { TopProgress, type TopProgressProps, type TopProgressRef, completeProgress, continuousStart, decreaseProgress, finishProgress, getProgress, increaseProgress, setProgress, startProgress, staticStart, withProgress };
+180
-67

@@ -25,4 +25,11 @@ "use strict";

TopProgress: () => TopProgress,
completeProgress: () => completeProgress,
continuousStart: () => continuousStart,
decreaseProgress: () => decreaseProgress,
finishProgress: () => finishProgress,
getProgress: () => getProgress,
increaseProgress: () => increaseProgress,
setProgress: () => setProgress,
startProgress: () => startProgress,
staticStart: () => staticStart,
withProgress: () => withProgress

@@ -41,2 +48,7 @@ });

hideTimer = null;
config = {
transitionTime: 300,
loaderSpeed: 500,
waitingTime: 1e3
};
subscribe(listener) {

@@ -52,17 +64,32 @@ this.listeners.add(listener);

}
start() {
if (this.value !== null) return;
start(loaderType = "continuous") {
if (loaderType === "static") {
this.staticStart();
} else {
this.continuousStart();
}
}
continuousStart(startingValue, refreshRate) {
this.cleanup();
this.value = 10;
this.value = startingValue !== void 0 ? startingValue : Math.floor(Math.random() * 10) + 20;
this.notify();
this.interval = setInterval(() => {
if (this.value !== null) {
const amount = Math.max(0.5, (95 - this.value) / 10);
this.value = Math.min(this.value + amount, 95);
if (this.value !== null && this.value < 90) {
const inc = Math.floor(Math.random() * 8) + 2;
this.value = Math.min(this.value + inc, 90);
this.notify();
}
}, 200);
}, refreshRate || this.config.loaderSpeed);
}
staticStart(startingValue) {
this.cleanup();
this.value = startingValue !== void 0 ? startingValue : Math.floor(Math.random() * 20) + 30;
this.notify();
}
complete() {
this.finish();
}
finish() {
this.cleanup();
if (this.value === null) return;
this.value = 100;

@@ -73,4 +100,25 @@ this.notify();

this.notify();
}, 400);
}, this.config.waitingTime);
}
set(value) {
this.cleanup();
this.value = value;
this.notify();
if (value >= 100) {
this.finish();
}
}
increase(amount) {
if (this.value !== null) {
this.value = Math.min(this.value + amount, 100);
this.notify();
if (this.value === 100) this.finish();
}
}
decrease(amount) {
if (this.value !== null) {
this.value = Math.max(0, this.value - amount);
this.notify();
}
}
cleanup() {

@@ -83,7 +131,17 @@ if (this.interval) clearInterval(this.interval);

}
getProgress() {
return this.value;
}
};
var progressStore = new ProgressStore();
var useProgressStore = () => progressStore;
var startProgress = () => progressStore.start();
var startProgress = (type) => progressStore.start(type);
var continuousStart = (startingValue, refreshRate) => progressStore.continuousStart(startingValue, refreshRate);
var staticStart = (startingValue) => progressStore.staticStart(startingValue);
var finishProgress = () => progressStore.finish();
var completeProgress = () => progressStore.complete();
var increaseProgress = (value) => progressStore.increase(value);
var decreaseProgress = (value) => progressStore.decrease(value);
var getProgress = () => progressStore.getProgress();
var setProgress = (value) => progressStore.set(value);
var withProgress = async (promise) => {

@@ -103,67 +161,122 @@ startProgress();

var import_jsx_runtime = require("react/jsx-runtime");
var TopProgress = ({
color = "#29D",
// Still the default flat color, but can now accept "linear-gradient(...)"
height = 3,
showGlow = true,
glowColor,
zIndex = 9999
}) => {
const store = useProgressStore();
const [progress, setProgress] = (0, import_react.useState)(store.getValue());
(0, import_react.useEffect)(() => {
return store.subscribe(setProgress);
}, [store]);
if (progress === null) {
return null;
var TopProgress = (0, import_react.forwardRef)(
({
progress: controlledProgress,
color = "red",
shadow = true,
height = 2,
background = "transparent",
style,
containerStyle,
shadowStyle,
transitionTime = 300,
loaderSpeed = 500,
waitingTime = 1e3,
className,
containerClassName,
onLoaderFinished,
showGlow,
glowColor,
zIndex = 9999
}, ref) => {
const store = useProgressStore();
const [internalProgress, setInternalProgress] = (0, import_react.useState)(
store.getValue()
);
(0, import_react.useImperativeHandle)(ref, () => ({
start: (type) => store.start(type),
continuousStart: (s, r) => store.continuousStart(s, r),
staticStart: (s) => store.staticStart(s),
complete: () => store.complete(),
increase: (v) => store.increase(v),
decrease: (v) => store.decrease(v),
getProgress: () => store.getProgress(),
set: (v) => store.set(v)
}));
(0, import_react.useEffect)(() => {
store.config.transitionTime = transitionTime;
store.config.loaderSpeed = loaderSpeed;
store.config.waitingTime = waitingTime;
}, [transitionTime, loaderSpeed, waitingTime, store]);
(0, import_react.useEffect)(() => {
return store.subscribe(setInternalProgress);
}, [store]);
const progress = controlledProgress !== void 0 ? controlledProgress : internalProgress;
(0, import_react.useEffect)(() => {
if (progress === 100 && onLoaderFinished) {
onLoaderFinished();
}
}, [progress, onLoaderFinished]);
if (progress === null) {
return null;
}
const isGradient = color.includes("gradient(");
const backgroundStyle = isGradient ? { backgroundImage: color } : { backgroundColor: color };
const useShadow = showGlow !== void 0 ? showGlow : shadow;
const computedGlowColor = glowColor || (isGradient ? "rgba(41, 216, 255, 0.4)" : color);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
className: containerClassName,
style: {
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: `${height}px`,
backgroundColor: background,
zIndex,
pointerEvents: "none",
...containerStyle
},
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
className,
style: {
width: `${progress}%`,
height: "100%",
...backgroundStyle,
transition: `width ${loaderSpeed}ms cubic-bezier(0.4, 0, 0.2, 1), opacity ${transitionTime}ms ease`,
opacity: progress === 100 ? 0 : 1,
transform: "translateZ(0)",
...style
},
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
style: {
display: useShadow ? "block" : "none",
position: "absolute",
right: 0,
top: 0,
width: 100,
height: "100%",
boxShadow: `0 0 10px ${computedGlowColor}, 0 0 5px ${computedGlowColor}`,
opacity: 1,
transform: "rotate(3deg) translate(0px, -4px)",
...shadowStyle
}
}
)
}
)
}
);
}
const isGradient = color.includes("gradient(");
const backgroundStyle = isGradient ? { backgroundImage: color } : { backgroundColor: color };
const computedGlowColor = glowColor || (isGradient ? "rgba(41, 216, 255, 0.4)" : color);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
style: {
position: "fixed",
top: 0,
left: 0,
width: `${progress}%`,
height: `${height}px`,
...backgroundStyle,
// Box shadow generates a beautiful diffused glow underneath the progress bar
boxShadow: showGlow ? `0 0 10px ${computedGlowColor}, 0 0 5px ${computedGlowColor}` : "none",
// Smooth and performant 60fps CSS transitions
transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease",
opacity: progress === 100 ? 0 : 1,
zIndex,
// Force hardware acceleration for paint performance
transform: "translateZ(0)",
// Don't intercept clicks
pointerEvents: "none"
},
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
style: {
display: showGlow ? "block" : "none",
position: "absolute",
right: 0,
top: 0,
width: 100,
height: "100%",
boxShadow: `0 0 10px ${computedGlowColor}, 0 0 5px ${computedGlowColor}`,
opacity: 1,
transform: "rotate(3deg) translate(0px, -4px)"
}
}
)
}
);
};
);
TopProgress.displayName = "TopProgress";
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
TopProgress,
completeProgress,
continuousStart,
decreaseProgress,
finishProgress,
getProgress,
increaseProgress,
setProgress,
startProgress,
staticStart,
withProgress
});
"use client";
// src/TopProgress.tsx
import { useEffect, useState } from "react";
import {
useEffect,
useState,
forwardRef,
useImperativeHandle
} from "react";

@@ -12,2 +17,7 @@ // src/progressStore.ts

hideTimer = null;
config = {
transitionTime: 300,
loaderSpeed: 500,
waitingTime: 1e3
};
subscribe(listener) {

@@ -23,17 +33,32 @@ this.listeners.add(listener);

}
start() {
if (this.value !== null) return;
start(loaderType = "continuous") {
if (loaderType === "static") {
this.staticStart();
} else {
this.continuousStart();
}
}
continuousStart(startingValue, refreshRate) {
this.cleanup();
this.value = 10;
this.value = startingValue !== void 0 ? startingValue : Math.floor(Math.random() * 10) + 20;
this.notify();
this.interval = setInterval(() => {
if (this.value !== null) {
const amount = Math.max(0.5, (95 - this.value) / 10);
this.value = Math.min(this.value + amount, 95);
if (this.value !== null && this.value < 90) {
const inc = Math.floor(Math.random() * 8) + 2;
this.value = Math.min(this.value + inc, 90);
this.notify();
}
}, 200);
}, refreshRate || this.config.loaderSpeed);
}
staticStart(startingValue) {
this.cleanup();
this.value = startingValue !== void 0 ? startingValue : Math.floor(Math.random() * 20) + 30;
this.notify();
}
complete() {
this.finish();
}
finish() {
this.cleanup();
if (this.value === null) return;
this.value = 100;

@@ -44,4 +69,25 @@ this.notify();

this.notify();
}, 400);
}, this.config.waitingTime);
}
set(value) {
this.cleanup();
this.value = value;
this.notify();
if (value >= 100) {
this.finish();
}
}
increase(amount) {
if (this.value !== null) {
this.value = Math.min(this.value + amount, 100);
this.notify();
if (this.value === 100) this.finish();
}
}
decrease(amount) {
if (this.value !== null) {
this.value = Math.max(0, this.value - amount);
this.notify();
}
}
cleanup() {

@@ -54,7 +100,17 @@ if (this.interval) clearInterval(this.interval);

}
getProgress() {
return this.value;
}
};
var progressStore = new ProgressStore();
var useProgressStore = () => progressStore;
var startProgress = () => progressStore.start();
var startProgress = (type) => progressStore.start(type);
var continuousStart = (startingValue, refreshRate) => progressStore.continuousStart(startingValue, refreshRate);
var staticStart = (startingValue) => progressStore.staticStart(startingValue);
var finishProgress = () => progressStore.finish();
var completeProgress = () => progressStore.complete();
var increaseProgress = (value) => progressStore.increase(value);
var decreaseProgress = (value) => progressStore.decrease(value);
var getProgress = () => progressStore.getProgress();
var setProgress = (value) => progressStore.set(value);
var withProgress = async (promise) => {

@@ -74,66 +130,121 @@ startProgress();

import { jsx } from "react/jsx-runtime";
var TopProgress = ({
color = "#29D",
// Still the default flat color, but can now accept "linear-gradient(...)"
height = 3,
showGlow = true,
glowColor,
zIndex = 9999
}) => {
const store = useProgressStore();
const [progress, setProgress] = useState(store.getValue());
useEffect(() => {
return store.subscribe(setProgress);
}, [store]);
if (progress === null) {
return null;
var TopProgress = forwardRef(
({
progress: controlledProgress,
color = "red",
shadow = true,
height = 2,
background = "transparent",
style,
containerStyle,
shadowStyle,
transitionTime = 300,
loaderSpeed = 500,
waitingTime = 1e3,
className,
containerClassName,
onLoaderFinished,
showGlow,
glowColor,
zIndex = 9999
}, ref) => {
const store = useProgressStore();
const [internalProgress, setInternalProgress] = useState(
store.getValue()
);
useImperativeHandle(ref, () => ({
start: (type) => store.start(type),
continuousStart: (s, r) => store.continuousStart(s, r),
staticStart: (s) => store.staticStart(s),
complete: () => store.complete(),
increase: (v) => store.increase(v),
decrease: (v) => store.decrease(v),
getProgress: () => store.getProgress(),
set: (v) => store.set(v)
}));
useEffect(() => {
store.config.transitionTime = transitionTime;
store.config.loaderSpeed = loaderSpeed;
store.config.waitingTime = waitingTime;
}, [transitionTime, loaderSpeed, waitingTime, store]);
useEffect(() => {
return store.subscribe(setInternalProgress);
}, [store]);
const progress = controlledProgress !== void 0 ? controlledProgress : internalProgress;
useEffect(() => {
if (progress === 100 && onLoaderFinished) {
onLoaderFinished();
}
}, [progress, onLoaderFinished]);
if (progress === null) {
return null;
}
const isGradient = color.includes("gradient(");
const backgroundStyle = isGradient ? { backgroundImage: color } : { backgroundColor: color };
const useShadow = showGlow !== void 0 ? showGlow : shadow;
const computedGlowColor = glowColor || (isGradient ? "rgba(41, 216, 255, 0.4)" : color);
return /* @__PURE__ */ jsx(
"div",
{
className: containerClassName,
style: {
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: `${height}px`,
backgroundColor: background,
zIndex,
pointerEvents: "none",
...containerStyle
},
children: /* @__PURE__ */ jsx(
"div",
{
className,
style: {
width: `${progress}%`,
height: "100%",
...backgroundStyle,
transition: `width ${loaderSpeed}ms cubic-bezier(0.4, 0, 0.2, 1), opacity ${transitionTime}ms ease`,
opacity: progress === 100 ? 0 : 1,
transform: "translateZ(0)",
...style
},
children: /* @__PURE__ */ jsx(
"div",
{
style: {
display: useShadow ? "block" : "none",
position: "absolute",
right: 0,
top: 0,
width: 100,
height: "100%",
boxShadow: `0 0 10px ${computedGlowColor}, 0 0 5px ${computedGlowColor}`,
opacity: 1,
transform: "rotate(3deg) translate(0px, -4px)",
...shadowStyle
}
}
)
}
)
}
);
}
const isGradient = color.includes("gradient(");
const backgroundStyle = isGradient ? { backgroundImage: color } : { backgroundColor: color };
const computedGlowColor = glowColor || (isGradient ? "rgba(41, 216, 255, 0.4)" : color);
return /* @__PURE__ */ jsx(
"div",
{
style: {
position: "fixed",
top: 0,
left: 0,
width: `${progress}%`,
height: `${height}px`,
...backgroundStyle,
// Box shadow generates a beautiful diffused glow underneath the progress bar
boxShadow: showGlow ? `0 0 10px ${computedGlowColor}, 0 0 5px ${computedGlowColor}` : "none",
// Smooth and performant 60fps CSS transitions
transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease",
opacity: progress === 100 ? 0 : 1,
zIndex,
// Force hardware acceleration for paint performance
transform: "translateZ(0)",
// Don't intercept clicks
pointerEvents: "none"
},
children: /* @__PURE__ */ jsx(
"div",
{
style: {
display: showGlow ? "block" : "none",
position: "absolute",
right: 0,
top: 0,
width: 100,
height: "100%",
boxShadow: `0 0 10px ${computedGlowColor}, 0 0 5px ${computedGlowColor}`,
opacity: 1,
transform: "rotate(3deg) translate(0px, -4px)"
}
}
)
}
);
};
);
TopProgress.displayName = "TopProgress";
export {
TopProgress,
completeProgress,
continuousStart,
decreaseProgress,
finishProgress,
getProgress,
increaseProgress,
setProgress,
startProgress,
staticStart,
withProgress
};
{
"name": "react-top-progress",
"version": "0.1.1",
"version": "1.0.0",
"description": "A lightweight modern top loading progress bar for React",

@@ -10,3 +10,3 @@ "main": "dist/index.js",

"dist",
"demo_react_top_progress.png"
"demo_react_top_progress.webp"
],

@@ -13,0 +13,0 @@ "keywords": [

+51
-45
# react-top-progress
![Demo of react-top-progress](demo_react_top_progress.png)
**<a href="https://react-test-progress.vercel.app/" target="_blank">👉 View Live Demo</a>**
**[👉 View Live Demo](https://react-test-progress.vercel.app/)**
A lightweight, modern, and performant top loading progress bar for React. Built for seamless user experiences with zero dependencies!
A lightweight, modern, and performant top loading progress bar for React.
Perfect for Next.js App Router, Vite, and standard SPA architectures.
Perfect for Next.js App Router, Vite, and standard single-page applications.
## Features
- **0 dependencies**: Tiny footprint (~1kb gzipped).
- **Realistic loading feel**: Increments incrementally like real network requests.
- **Premium DX**: Controlled programmatically with simple `startProgress` / `finishProgress` API.
- **Gradient & Glow Support**: Fully customizable colors, shadow pegs, and effects.
- **Performant**: Uses `transform` hardware acceleration and `cubic-bezier` transitions.
- **0 Dependencies**: Tiny footprint (~1.8kb gzipped).
- **Advanced Loaders**: `continuous` and `static` start modes matching network logic.
- **Premium DX**: Controlled programmatically with simple global API hooks, or direct React `ref`.
- **Customizable**: Add gradients, background container colors, custom CSS classes, and glows.
- **Performant**: Uses `transform: translateZ(0)` hardware acceleration and `cubic-bezier` CSS transitions.
- **TypeScript ready**: Full types included.
- **React 18+ & Next.js ready**: Contains `"use client"` where necessary.

@@ -37,6 +34,4 @@ ## Installation

### 1. Add the component to your root layout/app
At the top level of your application (like Next.js `app/layout.tsx` or Vite `src/App.tsx`), render the component.
At the top level of your application (like Next.js `app/layout.tsx` or Vite `src/App.tsx`), render the `<TopProgress />` component.
```tsx

@@ -57,50 +52,61 @@ import { TopProgress } from "react-top-progress";

### 2. Control it programmatically
## Built-in Methods
Import the API from anywhere in your app to trigger the progress bar manually!
You can trigger the loader from anywhere in your codebase by importing the functions globally, or via a React `ref` assigned to `<TopProgress ref={myRef} />`.
| Method | Parameters | Description |
| ------ | ---------- | ----------- |
| `start(loaderType?)` | `"continuous" \| "static"` | Starts the loading indicator. Default is continuous. |
| `continuousStart(startingValue?, refreshRate?)` | `number`, `number` | Starts with a random value (20-30), then slowly ticks up (2-10) repetitively. Reaches max 90%. |
| `staticStart(startingValue?)` | `number` | Starts the loader with a random static value between 30-50, waiting for completion. |
| `complete()` / `finishProgress()` | | Instantly pushes the indicator to 100% and gracefully fades it out. |
| `increase(value)` | `number` | Manually increments the loader by a specific amount. |
| `decrease(value)` | `number` | Manually decrements the loader by a specific amount. |
| `setProgress(value)` | `number` | Hardsets to a specific progress percentage. |
| `getProgress()` | | Returns the current progress percentage (0 - 100). |
| `withProgress(promise)`| `Promise<T>` | Wraps an asynchronous action. `startProgress()` executes automatically before and completes automatically afterward. |
### Global Usage Example
```tsx
import { startProgress, finishProgress } from "react-top-progress";
import { startProgress, finishProgress, withProgress } from "react-top-progress";
async function handleAction() {
startProgress();
async function fetchData() {
startProgress("continuous");
try {
await someHeavyTask();
await apiCall();
} finally {
finishProgress();
finishProgress(); // alias of complete()
}
}
```
### 3. The `withProgress` Utility
For an even better Developer Experience, simply wrap your promises securely with `withProgress`!
```tsx
import { withProgress } from "react-top-progress";
async function handleFetch() {
const data = await withProgress(fetch("/api/data"));
console.log(data);
}
// Or functionally wrap promises for ultimate DX:
const loadProfile = () => withProgress(fetch("/api/profile"));
```
## Customization API
## Component Properties
The `TopProgress` component accepts the following props:
You can customize `<TopProgress />` passing any of the following props:
| Prop | Type | Default | Description |
| ----------- | --------- | ----------- | ------------------------------------------------------------------------------------------------------------ |
| `color` | `string` | `"#29D"` | Flat hex color or `linear-gradient(...)` function string |
| `height` | `number` | `3` | Height of the progress bar in pixels |
| `showGlow` | `boolean` | `true` | Whether to display the premium box-shadow drop-glow and trailing peg |
| `glowColor` | `string` | `undefined` | Optionally override the color of the glow effect. By default, it infers realistically from your main `color` |
| `zIndex` | `number` | `9999` | The z-index stacking context level. |
| Property | Type | Default | Description |
| -------- | ---- | ------- | ----------- |
| `progress` | `number` | | Hardset the progress (0-100) if you want to bypass the internal store and control state yourself. |
| `color` | `string` | `"red"` | Background color of the bar. Accepts `linear-gradient(...)` or hex codes. |
| `height` | `number` | `2` | Height of the progress bar in pixels. |
| `shadow` | `boolean` | `true` | Appends a glorious trailing drop-glow peg matching the bar's color tracking its head. |
| `background` | `string` | `"transparent"` | Fills the container div's background layer under the progress element. |
| `transitionTime` | `number` | `300` | Fade transition time (ms) for the fade-out completion sequence. |
| `loaderSpeed` | `number` | `500` | Loader width transition speed (ms). |
| `waitingTime` | `number` | `1000` | The delay time (ms) loader waits at 100% width before fading entirely out. |
| `style` | `CSSProperties` | | Inject custom JSX styles directly onto the loader element. |
| `className` | `string` | | Apply a specific custom CSS class to the loader element. |
| `containerStyle` | `CSSProperties` | | Configure inline styles for the fixed `<div />` wrapper container. |
| `containerClassName` | `string` | | Custom CSS class applied onto the wrapper container. |
| `onLoaderFinished` | `() => void` | | A callback function executing precisely when the loader fully hits 100% max width. |
## Credits & Inspiration
## Credits
Designed for the modern web. Inspired by the classic `nprogress` and Next.js' `nextjs-toploader`. Ideal when you need explicit control without relying solely on framework routing events.
Inspired by standard `nprogress` and optimized libraries like `react-top-loading-bar` / `nextjs-toploader`, rewritten entirely from scratch for the cleanest Developer Experience.
## License
MIT

Sorry, the diff of this file is not supported yet