fix(client): correct StatBox hover and separate nested-control hover
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
This commit is contained in:
1 parent
9a6602b9e1
commit
3e56dc63a9
6 files changed
+24
-18
No files matched your search
@@ -33,7 +33,7 @@ export const ActionsMenu = ({ items }: { items: ActionMenuItem[] }) => {
|
||||
onClick={handleClick}
|
||||
sx={{
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.action.rowHover,
|
||||
backgroundColor: theme.palette.action.controlHover,
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -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 (
|
||||
<GradientBox
|
||||
palette={palette}
|
||||
sx={{
|
||||
...(sx as object),
|
||||
...(onClick
|
||||
? {
|
||||
cursor: "pointer",
|
||||
"&:hover": { backgroundColor: theme.palette.action.rowHover },
|
||||
}
|
||||
: {}),
|
||||
}}
|
||||
interactive={Boolean(onClick)}
|
||||
sx={{ ...(sx as object) }}
|
||||
>
|
||||
<Stack onClick={onClick}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: theme.spacing(2) }}>
|
||||
|
||||
@@ -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 (
|
||||
<Fragment key={key}>
|
||||
<TableRow
|
||||
className={onRowClick || expandableRows ? "is-clickable" : undefined}
|
||||
className={isInteractive ? "is-clickable" : undefined}
|
||||
sx={{
|
||||
cursor: onRowClick || expandableRows ? "pointer" : "default",
|
||||
cursor: isInteractive ? "pointer" : "default",
|
||||
...(getRowSx?.(row) as object),
|
||||
}}
|
||||
onClick={() => {
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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;
|
||||
Reference in new issue
Block a user