Files
personal-admin-2026/apps/frontend/src/components/ui/loading-bar.tsx
Jose Selesan 5b6ccf0fa6 chore: add Biome for lint and fix all lint errors
- Install @biomejs/biome as devDependency at root
- Configure biome.json with 2-space indent, double quotes, Tailwind CSS support
- Add lint/lint:fix/format/format:fix scripts to root and app package.json
- Fix noNonNullAssertion: env vars extracted to variables with suppression, <div role=button> replaced with <button>
- Fix noUnusedVariables: remove unused destructured vars
- Fix useIterableCallbackReturn: arrow functions with block body
- Fix noExplicitAny: recharts Tooltip formatters
- Fix noLabelWithoutControl: add htmlFor+id or use <span> for non-input labels
- Fix noStaticElementInteractions/useKeyWithClickEvents: role+keyboard events for overlays
- Fix noArrayIndexKey: use error string as key
- Fix CSS parse: enable tailwindDirectives parser
- Normalize formatting across 80 files with biome check --write
2026-06-04 10:48:07 -03:00

40 lines
1.1 KiB
TypeScript

import { useIsFetching, useIsMutating } from "@tanstack/react-query";
import { useRouterState } from "@tanstack/react-router";
import { useEffect, useRef, useState } from "react";
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>
);
}