diff --git a/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts b/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts index 755b116f5df74..634fbdad61b93 100644 --- a/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts +++ b/packages/x-data-grid-premium/src/hooks/features/cellSelection/useGridCellSelection.ts @@ -293,7 +293,8 @@ export const useGridCellSelection = ( } const { x: mouseX, y: mouseY } = mousePosition.current; - const { height, width } = dimensions.viewportInnerSize; + const { width, height: viewportOuterHeight } = dimensions.viewportOuterSize; + const height = viewportOuterHeight - totalHeaderHeight; let deltaX = 0; let deltaY = 0; @@ -330,7 +331,7 @@ export const useGridCellSelection = ( } autoScroll(); - }, [apiRef, dimensions]); + }, [apiRef, dimensions, totalHeaderHeight]); const handleCellMouseOver = React.useCallback>( (params, event) => { @@ -354,7 +355,8 @@ export const useGridCellSelection = ( } const { x, y } = virtualScrollerRect; - const { height, width } = dimensions.viewportInnerSize; + const { width, height: viewportOuterHeight } = dimensions.viewportOuterSize; + const height = viewportOuterHeight - totalHeaderHeight; const mouseX = event.clientX - x; const mouseY = event.clientY - y - totalHeaderHeight; mousePosition.current = { x: mouseX, y: mouseY }; diff --git a/packages/x-data-grid/src/components/containers/GridRootStyles.ts b/packages/x-data-grid/src/components/containers/GridRootStyles.ts index c0549e40a8c0a..f66edba975eac 100644 --- a/packages/x-data-grid/src/components/containers/GridRootStyles.ts +++ b/packages/x-data-grid/src/components/containers/GridRootStyles.ts @@ -157,25 +157,47 @@ export const GridRootStyles = styled('div', { const hoverColor = (t.vars || t).palette.action.hover; const selectedOpacity = (t.vars || t).palette.action.selectedOpacity; + const selectedHoverOpacity = t.vars + ? (`calc(${hoverOpacity} + ${selectedOpacity})` as unknown as number) // TODO: Improve type + : hoverOpacity + selectedOpacity; const selectedBackground = t.vars ? `rgba(${t.vars.palette.primary.mainChannel} / ${selectedOpacity})` : alpha(t.palette.primary.main, selectedOpacity); const selectedHoverBackground = t.vars - ? `rgba(${t.vars.palette.primary.mainChannel} / calc( - ${t.vars.palette.action.selectedOpacity} + - ${t.vars.palette.action.hoverOpacity} - ))` - : alpha( - t.palette.primary.main, - t.palette.action.selectedOpacity + t.palette.action.hoverOpacity, - ); + ? `rgba(${t.vars.palette.primary.mainChannel} / ${selectedHoverOpacity})` + : alpha(t.palette.primary.main, selectedHoverOpacity); const blendFn = t.vars ? blendCssVars : blend; - const pinnedHoverBackground = blendFn(pinnedBackground, hoverColor, hoverOpacity); - const pinnedSelectedBackground = blendFn(pinnedBackground, selectedBackground, selectedOpacity); - const pinnedSelectedHoverBackground = blendFn(pinnedSelectedBackground, hoverColor, hoverOpacity); + const getPinnedBackgroundStyles = (backgroundColor: string) => ({ + [`& .${c['cell--pinnedLeft']}, & .${c['cell--pinnedRight']}`]: { + backgroundColor, + '&.Mui-selected': { + backgroundColor: blendFn(backgroundColor, selectedBackground, selectedOpacity), + '&:hover': { + backgroundColor: blendFn(backgroundColor, selectedBackground, selectedHoverOpacity), + }, + }, + }, + }); + + const pinnedBackgroundColor = blendFn(pinnedBackground, hoverColor, hoverOpacity); + const pinnedHoverStyles = getPinnedBackgroundStyles(pinnedBackgroundColor); + + const pinnedSelectedBackgroundColor = blendFn( + pinnedBackground, + selectedBackground, + selectedOpacity, + ); + const pinnedSelectedStyles = getPinnedBackgroundStyles(pinnedSelectedBackgroundColor); + + const pinnedSelectedHoverBackgroundColor = blendFn( + pinnedBackground, + selectedHoverBackground, + selectedHoverOpacity, + ); + const pinnedSelectedHoverStyles = getPinnedBackgroundStyles(pinnedSelectedHoverBackgroundColor); const selectedStyles = { backgroundColor: selectedBackground, @@ -632,23 +654,14 @@ export const GridRootStyles = styled('div', { position: 'sticky', zIndex: 3, background: 'var(--DataGrid-pinnedBackground)', + '&.Mui-selected': { + backgroundColor: pinnedSelectedBackgroundColor, + }, }, [`& .${c.virtualScrollerContent} .${c.row}`]: { - '&:hover': { - [`& .${c['cell--pinnedLeft']}, & .${c['cell--pinnedRight']}`]: { - backgroundColor: pinnedHoverBackground, - }, - }, - [`&.Mui-selected`]: { - [`& .${c['cell--pinnedLeft']}, & .${c['cell--pinnedRight']}`]: { - backgroundColor: pinnedSelectedBackground, - }, - '&:hover': { - [`& .${c['cell--pinnedLeft']}, & .${c['cell--pinnedRight']}`]: { - backgroundColor: pinnedSelectedHoverBackground, - }, - }, - }, + '&:hover': pinnedHoverStyles, + '&.Mui-selected': pinnedSelectedStyles, + '&.Mui-selected:hover': pinnedSelectedHoverStyles, }, [`& .${c.cellOffsetLeft}`]: { flex: '0 0 auto', @@ -778,6 +791,6 @@ function blend(background: string, overlay: string, opacity: number, gamma: numb } const removeOpacity = (color: string) => `rgb(from ${color} r g b / 1)`; -function blendCssVars(background: string, overlay: string, opacity: number) { +function blendCssVars(background: string, overlay: string, opacity: string | number) { return `color-mix(in srgb,${background}, ${removeOpacity(overlay)} calc(${opacity} * 100%))`; } diff --git a/packages/x-data-grid/src/hooks/features/scroll/useGridScroll.ts b/packages/x-data-grid/src/hooks/features/scroll/useGridScroll.ts index 798ffd854c01b..f8628fa5451c4 100644 --- a/packages/x-data-grid/src/hooks/features/scroll/useGridScroll.ts +++ b/packages/x-data-grid/src/hooks/features/scroll/useGridScroll.ts @@ -21,24 +21,24 @@ import { gridDimensionsSelector } from '../dimensions'; // Logic copied from https://www.w3.org/TR/wai-aria-practices/examples/listbox/js/listbox.js // Similar to https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView function scrollIntoView(dimensions: { - clientHeight: number; - scrollTop: number; - offsetHeight: number; - offsetTop: number; + containerSize: number; + scrollPosition: number; + elementSize: number; + elementOffset: number; }) { - const { clientHeight, scrollTop, offsetHeight, offsetTop } = dimensions; + const { containerSize, scrollPosition, elementSize, elementOffset } = dimensions; - const elementBottom = offsetTop + offsetHeight; + const elementEnd = elementOffset + elementSize; // Always scroll to top when cell is higher than viewport to avoid scroll jump // See https://github.com/mui/mui-x/issues/4513 and https://github.com/mui/mui-x/issues/4514 - if (offsetHeight > clientHeight) { - return offsetTop; + if (elementSize > containerSize) { + return elementOffset; } - if (elementBottom - clientHeight > scrollTop) { - return elementBottom - clientHeight; + if (elementEnd - containerSize > scrollPosition) { + return elementEnd - containerSize; } - if (offsetTop < scrollTop) { - return offsetTop; + if (elementOffset < scrollPosition) { + return elementOffset; } return undefined; } @@ -96,10 +96,10 @@ export const useGridScroll = ( } // When using RTL, `scrollLeft` becomes negative, so we must ensure that we only compare values. scrollCoordinates.left = scrollIntoView({ - clientHeight: dimensions.viewportInnerSize.width, - scrollTop: Math.abs(virtualScrollerRef.current!.scrollLeft), - offsetHeight: cellWidth, - offsetTop: columnPositions[params.colIndex], + containerSize: dimensions.viewportOuterSize.width, + scrollPosition: Math.abs(virtualScrollerRef.current!.scrollLeft), + elementSize: cellWidth, + elementOffset: columnPositions[params.colIndex], }); } if (params.rowIndex !== undefined) { @@ -116,10 +116,10 @@ export const useGridScroll = ( : rowsMeta.currentPageTotalHeight - rowsMeta.positions[elementIndex]; scrollCoordinates.top = scrollIntoView({ - clientHeight: dimensions.viewportInnerSize.height, - scrollTop: virtualScrollerRef.current!.scrollTop, - offsetHeight: targetOffsetHeight, - offsetTop: rowsMeta.positions[elementIndex], + containerSize: dimensions.viewportInnerSize.height, + scrollPosition: virtualScrollerRef.current!.scrollTop, + elementSize: targetOffsetHeight, + elementOffset: rowsMeta.positions[elementIndex], }); }