feat: add LoadingBar component with loading animation
This commit is contained in:
37
apps/frontend/src/components/ui/loading-bar.tsx
Normal file
37
apps/frontend/src/components/ui/loading-bar.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { useRouterState } from "@tanstack/react-router";
|
||||
import { useIsFetching, useIsMutating } from "@tanstack/react-query";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function LoadingBar() {
|
||||
const isNavigating = useRouterState({ select: (s) => s.status === "pending" });
|
||||
const isFetching = useIsFetching();
|
||||
const isMutating = useIsMutating();
|
||||
|
||||
const [visible, setVisible] = useState(false);
|
||||
const timerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
|
||||
|
||||
const loading = isNavigating || isFetching > 0 || isMutating > 0;
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
timerRef.current = setTimeout(() => setVisible(true), 200);
|
||||
} else {
|
||||
clearTimeout(timerRef.current);
|
||||
setVisible(false);
|
||||
}
|
||||
return () => clearTimeout(timerRef.current);
|
||||
}, [loading]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"fixed top-0 left-0 right-0 z-[100] h-0.5 transition-opacity duration-300",
|
||||
visible ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div className="loading-bar h-full w-full bg-primary" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user