Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions components/ConnectButton/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Skeleton } from "@livepeer/design-system";

const ConnectButtonSkeleton = () => (
<Skeleton
css={{
height: "40px",
minWidth: "145px",
width: "145px",
borderRadius: "8px",
display: "inline-block",
}}
/>
);

export default ConnectButtonSkeleton;
81 changes: 81 additions & 0 deletions components/OrchestratorList/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Box, Flex, Skeleton } from "@livepeer/design-system";

const OrchestratorListSkeleton = () => {
return (
<Box
css={{
border: "1px solid $colors$neutral4",
backgroundColor: "$panel",
borderRadius: "$4",
}}
>
{/* Input section skeleton */}
<Box
css={{
marginTop: "$4",
marginLeft: "$5",
marginBottom: "$4",
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The input-section spacing here doesn’t match the real Table input wrapper: components/Table/index.tsx applies marginTop: "$4" and marginLeft: "$5" but no wrapper marginBottom. The extra marginBottom: "$4" in the skeleton makes it taller than the real OrchestratorList header area, which can cause a vertical layout shift when swapping from skeleton to the actual table.

Suggested change
marginBottom: "$4",

Copilot uses AI. Check for mistakes.
}}
>
<Flex css={{ alignItems: "center", marginBottom: "$2" }}>
<Skeleton css={{ width: 20, height: 20, borderRadius: "$2" }} />
<Skeleton css={{ width: 200, height: 16, marginLeft: "$2" }} />
</Flex>
<Flex css={{ gap: "$2", marginBottom: "$2" }}>
<Skeleton css={{ width: 120, height: 32, borderRadius: "$2" }} />
<Skeleton css={{ width: 120, height: 32, borderRadius: "$2" }} />
<Skeleton css={{ width: 120, height: 32, borderRadius: "$2" }} />
</Flex>
</Box>

{/* Table header skeleton */}
<Box
css={{ padding: "$3 $5", borderBottom: "1px solid $colors$neutral4" }}
>
<Flex css={{ gap: "$4" }}>
<Skeleton css={{ width: 150, height: 16 }} />
Comment on lines +31 to +36
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This skeleton doesn’t replicate the Table layout constraints (notably the overflowX: "auto" wrapper and minWidth: 960 table width in components/Table/index.tsx). On narrow viewports this can reintroduce CLS when the real OrchestratorList mounts and suddenly forces horizontal scrolling/min-width. Consider matching the Table wrapper structure/constraints so the skeleton and real table occupy the same space.

Copilot uses AI. Check for mistakes.
<Skeleton css={{ width: 120, height: 16 }} />
<Skeleton css={{ width: 120, height: 16 }} />
<Skeleton css={{ width: 100, height: 16 }} />
<Skeleton css={{ width: 100, height: 16 }} />
</Flex>
</Box>

{/* Table rows skeleton (10 rows) */}
{Array.from({ length: 10 }).map((_, i) => (
<Box
key={i}
css={{
padding: "$3 $5",
borderBottom: i < 9 ? "1px solid $colors$neutral4" : "none",
}}
>
<Flex css={{ gap: "$4", alignItems: "center" }}>
<Skeleton css={{ width: 150, height: 40, borderRadius: "$2" }} />
<Skeleton css={{ width: 120, height: 20 }} />
<Skeleton css={{ width: 120, height: 20 }} />
<Skeleton css={{ width: 100, height: 20 }} />
<Skeleton css={{ width: 100, height: 20 }} />
</Flex>
</Box>
))}

{/* Pagination skeleton */}
<Flex
css={{
paddingTop: "$4",
paddingBottom: "$4",
alignItems: "center",
justifyContent: "center",
gap: "$3",
}}
>
<Skeleton css={{ width: 20, height: 20, borderRadius: "$2" }} />
<Skeleton css={{ width: 100, height: 16 }} />
<Skeleton css={{ width: 20, height: 20, borderRadius: "$2" }} />
</Flex>
</Box>
);
};

export default OrchestratorListSkeleton;
16 changes: 4 additions & 12 deletions layouts/main.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import AppBar from "@components/AppBar";

Check failure on line 1 in layouts/main.tsx

View workflow job for this annotation

GitHub Actions / lint-and-test

Run autofix to sort these imports!
import Drawer from "@components/Drawer";
import Hamburger from "@components/Hamburger";
import InactiveWarning from "@components/InactiveWarning";
Expand Down Expand Up @@ -57,7 +57,7 @@
} from "react";
import { isMobile } from "react-device-detect";
import ReactGA from "react-ga";
import { useWindowSize } from "react-use";

import { Chain } from "viem";

import {
Expand Down Expand Up @@ -108,8 +108,11 @@
children?: React.ReactNode;
}>;

import ConnectButtonSkeleton from "../components/ConnectButton/Skeleton";

const ConnectButton = dynamic(() => import("../components/ConnectButton"), {
ssr: false,
loading: () => <ConnectButtonSkeleton />,
Comment on lines +111 to +115
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConnectButtonSkeleton is imported mid-file (after non-import statements) and via a relative path. With simple-import-sort/imports enforced, this will fail lint and also deviates from the existing @components/* import convention in this file. Move the import into the main import block and use the @components/ConnectButton/Skeleton alias so imports can be sorted correctly.

Copilot uses AI. Check for mistakes.
});

const Claim = dynamic(() => import("../components/Claim"), { ssr: false });
Expand All @@ -134,7 +137,6 @@
const activeChain = useActiveChain();
const [drawerOpen, setDrawerOpen] = useState(false);
const [bannerActive, setBannerActive] = useState<boolean>(false);
const { width } = useWindowSize();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drawer open on mobile leaves body.overflow hidden after window resize to desktop, preventing page scrolling

Fix on Vercel

const ref = useRef(null);
const currentRound = useCurrentRoundData();
const pendingFeesAndStake = usePendingFeesAndStakeData(accountAddress);
Expand Down Expand Up @@ -208,16 +210,6 @@
return () => window.removeEventListener("storage", onStorage);
}, [isReady, isBannerDisabledByQuery]);

useEffect(() => {
if (width >= 1200) {
document.body.removeAttribute("style");
}

if (width < 1200 && drawerOpen) {
document.body.style.overflow = "hidden";
}
}, [drawerOpen, width]);

useEffect(() => {
ReactGA.set({
customBrowserType: !isMobile
Expand Down
7 changes: 2 additions & 5 deletions pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import "react-circular-progressbar/dist/styles.css";

Check failure on line 1 in pages/index.tsx

View workflow job for this annotation

GitHub Actions / lint-and-test

Run autofix to sort these imports!

import ErrorComponent from "@components/Error";
import type { Group } from "@components/ExplorerChart";
import ExplorerChart from "@components/ExplorerChart";
import OrchestratorList from "@components/OrchestratorList";
import RoundStatus from "@components/RoundStatus";
import OrchestratorListSkeleton from "@components/OrchestratorList/Skeleton";
Comment on lines 7 to +8
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import order here is no longer sorted (@components/OrchestratorList/Skeleton comes after @components/RoundStatus). With simple-import-sort/imports enforced in this repo, this will fail lint; re-run import sorting so the new skeleton import is placed in the correct order within the @components/* group.

Suggested change
import RoundStatus from "@components/RoundStatus";
import OrchestratorListSkeleton from "@components/OrchestratorList/Skeleton";
import OrchestratorListSkeleton from "@components/OrchestratorList/Skeleton";
import RoundStatus from "@components/RoundStatus";

Copilot uses AI. Check for mistakes.
import Spinner from "@components/Spinner";
import TransactionsList, {
FILTERED_EVENT_TYPENAMES,
Expand Down Expand Up @@ -461,11 +462,7 @@
protocolData={protocol?.protocol}
/>
) : (
<Box
css={{ padding: "$4", textAlign: "center", opacity: 0.6 }}
>
Loading orchestrators…
</Box>
<OrchestratorListSkeleton />
)}
</Box>
)}
Expand Down
Loading