From 3e56dc63a9604577a8c5ddbfc9820f33e76c1e24 Mon Sep 17 00:00:00 2001 From: gorkem-bwl Date: Fri, 28 Aug 2026 19:53:39 -0400 Subject: [PATCH] fix(client): correct StatBox hover and separate nested-control hover MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses review findings on the hover-states change. StatBox's hover was a no-op. `GradientBox` always paints an opaque `linear-gradient` via the `background` shorthand, which populates background-image and covers any `backgroundColor` beneath it, so the new hover was invisible — a regression from the `opacity: 0.95` it replaced. The overlay now layers onto the same gradient, and moves into `GradientBox` where `bg` is in scope, behind an `interactive` prop. The mobile card branch gated its cursor and hover on `onRowClick` alone, so expandable-row tables below the md breakpoint rendered cards that expand on click but showed no pointer and no hover — the exact inconsistency this change set out to fix, reintroduced on mobile. Both branches now share one `isInteractive` flag. The row action gear used the same overlay as the row beneath it. Alpha overlays compose, so it was not invisible as reported, but the resulting delta was 6 levels — too faint for a nested control. Adds `HOVER.CONTROL` (0.05) and an `action.controlHover` token for controls nested inside a hoverable row: the gear and the pagination arrows. Claude-Session: https://claude.ai/code/session_01AbYLvwpEaZFXktHVcqrFRd --- client/src/Components/actions-menu/index.tsx | 2 +- .../Components/design-elements/StatBox.tsx | 20 +++++++++---------- .../src/Components/design-elements/Table.tsx | 13 ++++++------ client/src/Utils/Theme/Palette.ts | 2 ++ client/src/Utils/Theme/Theme.ts | 2 ++ client/src/Utils/Theme/constants.ts | 3 ++- 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/client/src/Components/actions-menu/index.tsx b/client/src/Components/actions-menu/index.tsx index 726ef6821..2eca19cee 100644 --- a/client/src/Components/actions-menu/index.tsx +++ b/client/src/Components/actions-menu/index.tsx @@ -33,7 +33,7 @@ export const ActionsMenu = ({ items }: { items: ActionMenuItem[] }) => { onClick={handleClick} sx={{ "&:hover": { - backgroundColor: theme.palette.action.rowHover, + backgroundColor: theme.palette.action.controlHover, }, }} > diff --git a/client/src/Components/design-elements/StatBox.tsx b/client/src/Components/design-elements/StatBox.tsx index 81205e967..1543766fc 100644 --- a/client/src/Components/design-elements/StatBox.tsx +++ b/client/src/Components/design-elements/StatBox.tsx @@ -11,9 +11,10 @@ import type { SxProps } from "@mui/material"; type GradientBox = React.PropsWithChildren<{ palette?: PaletteKey; sx?: SxProps; + interactive?: boolean; }>; -export const GradientBox = ({ children, palette, sx }: GradientBox) => { +export const GradientBox = ({ children, palette, sx, interactive }: GradientBox) => { const theme = useTheme(); const isSmall = useMediaQuery(theme.breakpoints.down("md")); const isLight = theme.palette.mode === "light"; @@ -30,6 +31,12 @@ export const GradientBox = ({ children, palette, sx }: GradientBox) => { padding: `${theme.spacing(4)} ${theme.spacing(8)}`, width: isSmall ? `100%` : `calc(25% - (3 * ${theme.spacing(8)} / 4))`, background: bg, + ...(interactive && { + cursor: "pointer", + "&:hover": { + backgroundImage: `linear-gradient(${theme.palette.action.rowHover}, ${theme.palette.action.rowHover}), ${bg}`, + }, + }), ...sx, }} > @@ -62,15 +69,8 @@ export const StatBox = ({ return ( diff --git a/client/src/Components/design-elements/Table.tsx b/client/src/Components/design-elements/Table.tsx index e4e636f80..c57616740 100644 --- a/client/src/Components/design-elements/Table.tsx +++ b/client/src/Components/design-elements/Table.tsx @@ -79,6 +79,7 @@ export function DataTable< }; const isSmall = useMediaQuery(theme.breakpoints.down("md")); + const isInteractive = Boolean(onRowClick) || expandableRows; if (data.length === 0 || headers.length === 0) { return ( @@ -107,8 +108,8 @@ export function DataTable< borderColor: theme.palette.divider, borderRadius: theme.shape.borderRadius, padding: theme.spacing(LAYOUT.XS), - cursor: onRowClick ? "pointer" : "default", - ...(onRowClick && { + cursor: isInteractive ? "pointer" : "default", + ...(isInteractive && { "&:hover": { backgroundColor: theme.palette.action.rowHover, }, @@ -240,9 +241,9 @@ export function DataTable< return ( { @@ -328,7 +329,7 @@ function TablePaginationActions(props: TablePaginationActionsProps) { flexShrink: 0, ml: { xs: 0, md: 2.5 }, "& .MuiIconButton-root:not(.Mui-disabled):hover": { - backgroundColor: theme.palette.action.rowHover, + backgroundColor: theme.palette.action.controlHover, }, }} className="table-pagination-actions" @@ -432,7 +433,7 @@ function HasMoreTablePaginationActions(props: HasMoreTablePaginationActionsProps flexShrink: 0, ml: { xs: 0, md: 2.5 }, "& .MuiIconButton-root:not(.Mui-disabled):hover": { - backgroundColor: theme.palette.action.rowHover, + backgroundColor: theme.palette.action.controlHover, }, }} className="table-pagination-actions" diff --git a/client/src/Utils/Theme/Palette.ts b/client/src/Utils/Theme/Palette.ts index 9c9f4e04d..0d9168f8a 100644 --- a/client/src/Utils/Theme/Palette.ts +++ b/client/src/Utils/Theme/Palette.ts @@ -42,6 +42,7 @@ export const lightPalette = { }, action: { rowHover: alpha(colors.gray900, HOVER.ROW), + controlHover: alpha(colors.gray900, HOVER.CONTROL), }, secondary: { main: colors.gray200, @@ -71,6 +72,7 @@ export const darkPalette = { }, action: { rowHover: alpha("#FFFFFF", HOVER.ROW), + controlHover: alpha("#FFFFFF", HOVER.CONTROL), }, secondary: { main: colors.gray700, diff --git a/client/src/Utils/Theme/Theme.ts b/client/src/Utils/Theme/Theme.ts index b39ba4abb..9b95fb121 100644 --- a/client/src/Utils/Theme/Theme.ts +++ b/client/src/Utils/Theme/Theme.ts @@ -15,9 +15,11 @@ declare module "@mui/material/styles" { } interface TypeAction { rowHover: string; + controlHover: string; } interface TypeActionOptions { rowHover?: string; + controlHover?: string; } interface Palette { sidebar: { accent: string }; diff --git a/client/src/Utils/Theme/constants.ts b/client/src/Utils/Theme/constants.ts index c8641e7aa..70ddcd407 100644 --- a/client/src/Utils/Theme/constants.ts +++ b/client/src/Utils/Theme/constants.ts @@ -20,5 +20,6 @@ export const LAYOUT = { export const HOVER = { DARKEN: 0.06, // This is a coefficient for darkening function - ROW: 0.025, // Overlay alpha for hoverable rows, cards and icon buttons + ROW: 0.025, // Overlay alpha for hoverable rows and cards + CONTROL: 0.05, // Stronger overlay for controls nested inside a hoverable row } as const;