Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGrid] refactor: theme to CSS variables #15704

Merged
merged 47 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
af5bdf9
refactor: theme => css variables
romgrk Dec 2, 2024
339768b
lint
romgrk Dec 2, 2024
90c1fc2
lint
romgrk Dec 2, 2024
1fc98c6
feat: breakpoints
romgrk Dec 3, 2024
15484db
feat: breakpoints
romgrk Dec 3, 2024
9a5014e
refactor: theme.spacing => vars.spacing
romgrk Dec 3, 2024
bf20ed3
refactor: zIndex
romgrk Dec 3, 2024
71c993f
refactor: finish t.spacing()
romgrk Dec 3, 2024
b1054ec
refactor: finish all but GRS
romgrk Dec 4, 2024
41b1451
lint
romgrk Dec 4, 2024
9d718e2
Merge branch 'master' into feat-agnostic-css-variables
romgrk Dec 4, 2024
4e83cb6
fix: missing variables
romgrk Dec 4, 2024
f0645af
refactor: GridRootStyles
romgrk Dec 4, 2024
07e64a0
refactor: GRS: more colors
romgrk Dec 4, 2024
4670236
refactor: more ergonomic API
romgrk Dec 4, 2024
4bccecc
lint
romgrk Dec 6, 2024
1de35d9
lint
romgrk Dec 6, 2024
4822768
draft: test reverting text color
romgrk Dec 6, 2024
f643319
lint
romgrk Dec 9, 2024
734d8e7
draft: try remove style
romgrk Dec 9, 2024
3dc38ef
Revert "draft: try remove style"
romgrk Dec 9, 2024
cd34948
Revert "refactor: GRS: more colors"
romgrk Dec 9, 2024
cc48bd1
refactor: GRS: main colors
romgrk Dec 9, 2024
8311425
refactor: GRS(2): colors
romgrk Dec 9, 2024
2476462
refactor: GRS(3): colors
romgrk Dec 9, 2024
736948b
refactor: GRS(4): colors
romgrk Dec 9, 2024
2973e5c
refactor: GRS(5): focus color
romgrk Dec 9, 2024
802c642
refactor: GRS: complete
romgrk Dec 9, 2024
e7e253a
Merge branch 'master' into feat-agnostic-css-variables
romgrk Dec 12, 2024
23d3ad4
draft: split CSS variables
romgrk Dec 12, 2024
414f359
Merge branch 'master' into feat-agnostic-css-variables
romgrk Jan 7, 2025
00c953d
Revert "draft: split CSS variables"
romgrk Jan 8, 2025
cf98e2c
Merge branch 'master' into feat-agnostic-css-variables
romgrk Jan 8, 2025
ae48775
fix: conflict marker
romgrk Jan 8, 2025
c3d77de
fix: css variables accessible from root
romgrk Jan 8, 2025
b678c19
lint
romgrk Jan 8, 2025
fb4edf8
lint
romgrk Jan 8, 2025
685e935
ci: run (empty commit)
romgrk Jan 9, 2025
02f2f1c
Update packages/x-data-grid/src/components/panel/GridPanelFooter.tsx
romgrk Jan 9, 2025
dc9b984
Merge branch 'master' into feat-agnostic-css-variables
romgrk Jan 9, 2025
8d21805
Merge branch 'feat-agnostic-css-variables' of github.com:romgrk/mui-x…
romgrk Jan 9, 2025
049a999
ci: run (empty commit)
romgrk Jan 9, 2025
a9c8b65
fix: quickfilter outside of root
romgrk Jan 9, 2025
2d961be
lint
romgrk Jan 9, 2025
249ee63
refactor: useThemeVariablesClassName => useCSSVariablesClass
romgrk Jan 9, 2025
a0b8119
ci: run (empty commit)
romgrk Jan 10, 2025
83655b4
ci: run (empty commit)
romgrk Jan 10, 2025
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
Prev Previous commit
Next Next commit
refactor: GridRootStyles
  • Loading branch information
romgrk committed Dec 4, 2024
commit f0645afd9f900717752a84334acae276f6a5fa5e
4 changes: 2 additions & 2 deletions packages/x-data-grid-pro/src/components/GridColumnHeaders.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { styled } from '@mui/material/styles';
import { GridBaseColumnHeaders, UseGridColumnHeadersProps } from '@mui/x-data-grid/internals';
import { vars, GridBaseColumnHeaders, UseGridColumnHeadersProps } from '@mui/x-data-grid/internals';
import { useGridColumnHeaders } from '../hooks/features/columnHeaders/useGridColumnHeaders';

const Filler = styled('div')({
flex: 1,
backgroundColor: 'var(--DataGrid-containerBackground)',
backgroundColor: `var(${vars.colors.background.base})`,
});

export interface GridColumnHeadersProps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import clsx from 'clsx';
import composeClasses from '@mui/utils/composeClasses';
import { Theme, SxProps, styled } from '@mui/system';
import type { DataGridProcessedProps } from '../../models/props/DataGridProps';
import { vars } from '../../constants/cssVariables';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';

Expand Down Expand Up @@ -34,7 +35,7 @@ const GridOverlayRoot = styled('div', {
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'var(--unstable_DataGrid-overlayBackground)',
backgroundColor: `var(${vars.colors.background.backdrop})`,
});

const GridOverlay = React.forwardRef<HTMLDivElement, GridOverlayProps>(function GridOverlay(
Expand Down
165 changes: 69 additions & 96 deletions packages/x-data-grid/src/components/containers/GridRootStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,6 @@ import { gridDimensionsSelector } from '../../hooks/features/dimensions/gridDime

export type OwnerState = DataGridProcessedProps;

function getBorderColor(theme: Theme) {
if (theme.vars) {
return theme.vars.palette.TableCell.border;
}
if (theme.palette.mode === 'light') {
return lighten(alpha(theme.palette.divider, 1), 0.88);
}
return darken(alpha(theme.palette.divider, 1), 0.68);
}

const columnHeaderStyles = {
[`& .${c.iconButtonContainer}`]: {
visibility: 'visible',
Expand Down Expand Up @@ -144,63 +134,43 @@ export const GridRootStyles = styled('div', {
const apiRef = useGridPrivateApiContext();
const dimensions = useGridSelector(apiRef, gridDimensionsSelector);

const borderColor = getBorderColor(t);
const baseBackground = `var(${vars.colors.background.base})`;
const pinnedBackground = `var(${vars.colors.background.pinned})`;

const containerBackground = t.vars
? t.vars.palette.background.default
: (t.mixins.MuiDataGrid?.containerBackground ?? t.palette.background.default);
const hoverColor = `var(${vars.colors.interactive.hover})`;
const hoverOpacity = `var(${vars.colors.interactive.hoverOpacity})`;
const selectedColor = `var(${vars.colors.interactive.selected})`;
const selectedOpacity = `var(${vars.colors.interactive.selectedOpacity})`;
const selectedHoverColor = selectedColor;
const selectedHoverOpacity = `calc(${selectedOpacity} + ${hoverOpacity})`;

const pinnedBackground = t.mixins.MuiDataGrid?.pinnedBackground ?? containerBackground;
const hoverBackground = mix(baseBackground, hoverColor, hoverOpacity);
const selectedBackground = mix(baseBackground, selectedColor, selectedOpacity);
const selectedHoverBackground = mix(baseBackground, selectedHoverColor, selectedHoverOpacity);

const overlayBackground = t.vars
? `rgba(${t.vars.palette.background.defaultChannel} / ${t.vars.palette.action.disabledOpacity})`
: alpha(t.palette.background.default, t.palette.action.disabledOpacity);

const hoverOpacity = (t.vars || t).palette.action.hoverOpacity;
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} / ${selectedHoverOpacity})`
: alpha(t.palette.primary.main, selectedHoverOpacity);

const blendFn = t.vars ? blendCssVars : blend;
const pinnedHoverBackground = mix(pinnedBackground, hoverColor, hoverOpacity);
const pinnedSelectedBackground = mix(pinnedBackground, selectedColor, selectedOpacity);
const pinnedSelectedHoverBackground = mix(
pinnedBackground,
selectedHoverColor,
selectedHoverOpacity,
);

const getPinnedBackgroundStyles = (backgroundColor: string) => ({
[`& .${c['cell--pinnedLeft']}, & .${c['cell--pinnedRight']}`]: {
backgroundColor,
'&.Mui-selected': {
backgroundColor: blendFn(backgroundColor, selectedBackground, selectedOpacity),
backgroundColor: mix(backgroundColor, selectedBackground, selectedOpacity),
'&:hover': {
backgroundColor: blendFn(backgroundColor, selectedBackground, selectedHoverOpacity),
backgroundColor: mix(backgroundColor, selectedHoverBackground, 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 pinnedHoverStyles = getPinnedBackgroundStyles(pinnedHoverBackground);
const pinnedSelectedStyles = getPinnedBackgroundStyles(pinnedSelectedBackground);
const pinnedSelectedHoverStyles = getPinnedBackgroundStyles(pinnedSelectedHoverBackground);

const selectedStyles = {
backgroundColor: selectedBackground,
Expand All @@ -218,11 +188,8 @@ export const GridRootStyles = styled('div', {

'--unstable_DataGrid-radius': `var(${vars.radius.base})`,
'--unstable_DataGrid-headWeight': `var(${vars.typography.fontWeight.medium})`,
'--unstable_DataGrid-overlayBackground': overlayBackground,

'--DataGrid-containerBackground': containerBackground,
'--DataGrid-pinnedBackground': pinnedBackground,
'--DataGrid-rowBorderColor': borderColor,
'--DataGrid-rowBorderColor': `var(${vars.colors.border.base})`,

'--DataGrid-cellOffsetMultiplier': 2,
'--DataGrid-width': '0px',
Expand All @@ -243,7 +210,7 @@ export const GridRootStyles = styled('div', {
position: 'relative',
borderWidth: '1px',
borderStyle: 'solid',
borderColor,
borderColor: `var(${vars.colors.border.base})`,
borderRadius: 'var(--unstable_DataGrid-radius)',
color: (t.vars || t).palette.text.primary,
...t.typography.body2,
Expand Down Expand Up @@ -409,7 +376,7 @@ export const GridRootStyles = styled('div', {
[`& .${c['columnHeader--pinnedLeft']}, & .${c['columnHeader--pinnedRight']}`]: {
position: 'sticky',
zIndex: 4, // Should be above the column separator
background: 'var(--DataGrid-pinnedBackground)',
background: `var(${vars.colors.background.pinned})`,
},
[`& .${c.columnSeparator}`]: {
position: 'absolute',
Expand All @@ -420,7 +387,7 @@ export const GridRootStyles = styled('div', {
justifyContent: 'center',
alignItems: 'center',
maxWidth: columnSeparatorTargetSize,
color: borderColor,
color: `var(${vars.colors.border.base})`,
},
[`& .${c.columnHeaders}`]: {
width: 'var(--DataGrid-rowWidth)',
Expand Down Expand Up @@ -521,7 +488,7 @@ export const GridRootStyles = styled('div', {
},

'&:hover': {
backgroundColor: (t.vars || t).palette.action.hover,
backgroundColor: hoverBackground,
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent',
Expand All @@ -534,7 +501,7 @@ export const GridRootStyles = styled('div', {
},
[`& .${c['container--top']}, & .${c['container--bottom']}`]: {
'[role=row]': {
background: 'var(--DataGrid-containerBackground)',
background: `var(${vars.colors.background.base})`,
},
},

Expand Down Expand Up @@ -628,7 +595,7 @@ export const GridRootStyles = styled('div', {
alignItems: 'stretch',
},
[`.${c.withBorderColor}`]: {
borderColor,
borderColor: `var(${vars.colors.border.base})`,
},
[`& .${c['cell--withLeftBorder']}, & .${c['columnHeader--withLeftBorder']}`]: {
borderLeftColor: 'var(--DataGrid-rowBorderColor)',
Expand Down Expand Up @@ -660,9 +627,9 @@ export const GridRootStyles = styled('div', {
[`& .${c['cell--pinnedLeft']}, & .${c['cell--pinnedRight']}`]: {
position: 'sticky',
zIndex: 3,
background: 'var(--DataGrid-pinnedBackground)',
background: `var(${vars.colors.background.pinned})`,
'&.Mui-selected': {
backgroundColor: pinnedSelectedBackgroundColor,
backgroundColor: pinnedSelectedBackground,
},
},
[`& .${c.virtualScrollerContent} .${c.row}`]: {
Expand Down Expand Up @@ -742,7 +709,7 @@ export const GridRootStyles = styled('div', {
borderBottom: '1px solid var(--DataGrid-rowBorderColor)',
},
[`&.${c['scrollbarFiller--pinnedRight']}`]: {
backgroundColor: 'var(--DataGrid-pinnedBackground)',
backgroundColor: `var(${vars.colors.background.pinned})`,
position: 'sticky',
right: 0,
},
Expand Down Expand Up @@ -775,24 +742,40 @@ export const GridRootStyles = styled('div', {
});

function transformMaterialUITheme(t: Theme) {
const borderColor = getBorderColor(t);

const backgroundBase =
t.mixins.MuiDataGrid?.containerBackground ?? (t.vars || t).palette.background.default;
const backgroundPinned = t.mixins.MuiDataGrid?.pinnedBackground ?? backgroundBase;
const backgroundBackdrop = t.vars
? `rgba(${t.vars.palette.background.defaultChannel} / ${t.vars.palette.action.disabledOpacity})`
: alpha(t.palette.background.default, t.palette.action.disabledOpacity);

const selectedColor = t.vars
? `rgb(${t.vars.palette.primary.mainChannel})`
: t.palette.primary.main;

return {
[vars.spacingUnit]: t.spacing(1),

[vars.colors.background.base]: t.palette.background.default,
[vars.colors.border.base]: borderColor,
[vars.colors.background.base]: backgroundBase,
[vars.colors.background.pinned]: backgroundPinned,
[vars.colors.background.overlay]: t.palette.background.paper,
[vars.colors.background.backdrop]: backgroundBackdrop,
[vars.colors.foreground.base]: t.palette.text.primary,
[vars.colors.foreground.muted]: t.palette.text.secondary,
[vars.colors.foreground.accent]: t.palette.primary.dark,
[vars.colors.foreground.disabled]: t.palette.text.disabled,
[vars.colors.interactive.hover]: t.palette.action.hover,

[vars.colors.interactive.hover]: removeOpacity(t.palette.action.hover),
[vars.colors.interactive.hoverOpacity]: t.palette.action.hoverOpacity,
[vars.colors.interactive.focus]: t.palette.action.focus,
[vars.colors.interactive.focus]: removeOpacity(t.palette.action.focus),
[vars.colors.interactive.focusOpacity]: t.palette.action.focusOpacity,
[vars.colors.interactive.disabled]: t.palette.action.disabled,
[vars.colors.interactive.disabled]: removeOpacity(t.palette.action.disabled),
[vars.colors.interactive.disabledOpacity]: t.palette.action.disabledOpacity,
[vars.colors.interactive.selected]: t.palette.action.selected,
[vars.colors.interactive.selected]: selectedColor,
[vars.colors.interactive.selectedOpacity]: t.palette.action.selectedOpacity,
[vars.colors.border.base]: t.palette.divider,

[vars.radius.base]:
typeof t.shape.borderRadius === 'number' ? `${t.shape.borderRadius}px` : t.shape.borderRadius,
Expand Down Expand Up @@ -825,30 +808,20 @@ function transformMaterialUITheme(t: Theme) {
};
}

/**
* Blend a transparent overlay color with a background color, resulting in a single
* RGB color.
*/
function blend(background: string, overlay: string, opacity: number, gamma: number = 1) {
const f = (b: number, o: number) =>
Math.round((b ** (1 / gamma) * (1 - opacity) + o ** (1 / gamma) * opacity) ** gamma);

const backgroundColor = decomposeColor(background);
const overlayColor = decomposeColor(overlay);

const rgb = [
f(backgroundColor.values[0], overlayColor.values[0]),
f(backgroundColor.values[1], overlayColor.values[1]),
f(backgroundColor.values[2], overlayColor.values[2]),
] as const;

return recomposeColor({
type: 'rgb',
values: rgb as any,
});
function getBorderColor(theme: Theme) {
if (theme.vars) {
return theme.vars.palette.TableCell.border;
}
if (theme.palette.mode === 'light') {
return lighten(alpha(theme.palette.divider, 1), 0.88);
}
return darken(alpha(theme.palette.divider, 1), 0.68);
}

function removeOpacity(color: string) {
return `rgb(from ${color} r g b / 1)`;
}

const removeOpacity = (color: string) => `rgb(from ${color} r g b / 1)`;
function blendCssVars(background: string, overlay: string, opacity: string | number) {
return `color-mix(in srgb,${background}, ${removeOpacity(overlay)} calc(${opacity} * 100%))`;
function mix(background: string, overlay: string, opacity: number | string) {
return `color-mix(in srgb,${background}, ${overlay} calc(${opacity} * 100%))`;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { styled } from '@mui/system';
import { fastMemo } from '@mui/x-internals/fastMemo';
import { vars } from '../../constants/cssVariables';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { gridDimensionsSelector } from '../../hooks/features/dimensions';
Expand All @@ -18,7 +19,7 @@ const Pinned = styled('div')({
height: '100%',
boxSizing: 'border-box',
borderTop: '1px solid var(--rowBorderColor)',
backgroundColor: 'var(--DataGrid-pinnedBackground)',
backgroundColor: `var(${vars.colors.background.pinned})`,
});
const PinnedLeft = styled(Pinned)({
left: 0,
Expand Down
10 changes: 7 additions & 3 deletions packages/x-data-grid/src/constants/cssVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ export const vars = {

/* Variables */
colors: {
border: {
base: '--DataGrid-t-colors-border-base',
},
foreground: {
cherniavskii marked this conversation as resolved.
Show resolved Hide resolved
base: '--DataGrid-t-colors-foreground-base',
muted: '--DataGrid-t-colors-foreground-muted',
Expand All @@ -37,7 +40,11 @@ export const vars = {
},
background: {
base: '--DataGrid-t-colors-background-base',
// FIXME(kenan): validate `pinned`
pinned: '--DataGrid-t-colors-background-pinned',
KenanYusuf marked this conversation as resolved.
Show resolved Hide resolved
// FIXME(kenan): validate `overlay` and `backdrop`
overlay: '--DataGrid-t-colors-background-overlay',
backdrop: '--DataGrid-t-colors-background-backdrop',
},
interactive: {
hover: '--DataGrid-t-colors-interactive-hover',
Expand All @@ -49,9 +56,6 @@ export const vars = {
selected: '--DataGrid-t-colors-interactive-selected',
selectedOpacity: '--DataGrid-t-colors-interactive-selected-opacity',
},
border: {
base: '--DataGrid-t-colors-border-base',
},
},
radius: {
base: '--DataGrid-t-radius-base',
Expand Down
Loading