840 lines
29 KiB
JavaScript
840 lines
29 KiB
JavaScript
import { styled, css } from '@mui/material/styles';
|
|
import { gridClasses as c, gridClassesOverrides } from "../../constants/gridClasses.mjs";
|
|
import { vars } from "../../constants/cssVariables.mjs";
|
|
import { useGridSelector } from "../../hooks/utils/useGridSelector.mjs";
|
|
import { useGridPrivateApiContext } from "../../hooks/utils/useGridPrivateApiContext.mjs";
|
|
const columnSeparatorTargetSize = 10;
|
|
const columnSeparatorOffset = -5;
|
|
const focusOutlineWidth = 1;
|
|
const separatorIconDragStyles = {
|
|
width: 3,
|
|
rx: 1.5,
|
|
x: 10.5
|
|
};
|
|
|
|
// Emotion thinks it knows better than us which selector we should use.
|
|
// https://github.com/emotion-js/emotion/issues/1105#issuecomment-1722524968
|
|
const ignoreSsrWarning = '/* emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason */';
|
|
const shouldShowBorderTopRightRadiusSelector = apiRef => !apiRef.current.state.dimensions.isReady ? apiRef.current.state.dimensions.scrollbarSize === 0 : apiRef.current.state.dimensions.hasScrollX && (!apiRef.current.state.dimensions.hasScrollY || apiRef.current.state.dimensions.scrollbarSize === 0);
|
|
export const GridRootStyles = styled('div', {
|
|
name: 'MuiDataGrid',
|
|
slot: 'Root',
|
|
overridesResolver: (props, styles) => {
|
|
// Root overrides
|
|
const overrides = [styles.root];
|
|
gridClassesOverrides.root.forEach(key => {
|
|
if (styles[key] !== undefined) {
|
|
overrides.push({
|
|
[`&.${c[key]}`]: styles[key]
|
|
});
|
|
}
|
|
});
|
|
|
|
// Child element overrides
|
|
// - Only declare overrides here for class names that are not applied to `styled` components.
|
|
// - For `styled` components, declare overrides in the component itself.
|
|
gridClassesOverrides.children.forEach(key => {
|
|
if (styles[key] !== undefined) {
|
|
overrides.push({
|
|
[`& .${c[key]}`]: styles[key]
|
|
});
|
|
}
|
|
});
|
|
return overrides;
|
|
}
|
|
})(() => {
|
|
const apiRef = useGridPrivateApiContext();
|
|
const shouldShowBorderTopRightRadius = useGridSelector(apiRef, shouldShowBorderTopRightRadiusSelector);
|
|
const baseBackground = vars.colors.background.base;
|
|
const headerBackground = vars.header.background.base;
|
|
const pinnedBackground = vars.cell.background.pinned;
|
|
const hoverColor = removeOpacity(vars.colors.interactive.hover);
|
|
const hoverOpacity = vars.colors.interactive.hoverOpacity;
|
|
const selectedColor = vars.colors.interactive.selected;
|
|
const selectedOpacity = vars.colors.interactive.selectedOpacity;
|
|
const selectedHoverColor = selectedColor;
|
|
const selectedHoverOpacity = `calc(${selectedOpacity} + ${hoverOpacity})`;
|
|
const fallbackColors = {
|
|
hover: vars.colors.interactive.hover,
|
|
selected: selectedColor,
|
|
selectedHover: selectedColor
|
|
};
|
|
const hoverBackground = mix(baseBackground, hoverColor, hoverOpacity, fallbackColors.hover);
|
|
const selectedBackground = mix(baseBackground, selectedColor, selectedOpacity, fallbackColors.selected);
|
|
const selectedHoverBackground = mix(baseBackground, selectedHoverColor, selectedHoverOpacity, fallbackColors.selectedHover);
|
|
const pinnedHoverBackground = mix(pinnedBackground, hoverColor, hoverOpacity, fallbackColors.hover);
|
|
const pinnedSelectedBackground = mix(pinnedBackground, selectedColor, selectedOpacity, fallbackColors.selected);
|
|
const pinnedSelectedHoverBackground = mix(pinnedBackground, selectedHoverColor, selectedHoverOpacity, fallbackColors.selectedHover);
|
|
const getPinnedBackgroundStyles = backgroundColor => ({
|
|
[`& .${c['cell--pinnedLeft']}, & .${c['cell--pinnedRight']}`]: {
|
|
backgroundColor,
|
|
'&.Mui-selected': {
|
|
backgroundColor: mix(backgroundColor, selectedBackground, selectedOpacity, fallbackColors.selected),
|
|
'&:hover': {
|
|
backgroundColor: mix(backgroundColor, selectedHoverBackground, selectedHoverOpacity, fallbackColors.selectedHover)
|
|
}
|
|
}
|
|
}
|
|
});
|
|
const pinnedHoverStyles = getPinnedBackgroundStyles(pinnedHoverBackground);
|
|
const pinnedSelectedStyles = getPinnedBackgroundStyles(pinnedSelectedBackground);
|
|
const pinnedSelectedHoverStyles = getPinnedBackgroundStyles(pinnedSelectedHoverBackground);
|
|
const selectedStyles = {
|
|
backgroundColor: selectedBackground,
|
|
'&:hover': {
|
|
backgroundColor: selectedHoverBackground,
|
|
// Reset on touch devices, it doesn't add specificity
|
|
'@media (hover: none)': {
|
|
backgroundColor: selectedBackground
|
|
}
|
|
}
|
|
};
|
|
const gridStyle = {
|
|
'--unstable_DataGrid-radius': vars.radius.base,
|
|
'--unstable_DataGrid-headWeight': vars.typography.fontWeight.medium,
|
|
'--DataGrid-rowBorderColor': vars.colors.border.base,
|
|
'--DataGrid-cellOffsetMultiplier': 2,
|
|
'--DataGrid-width': '0px',
|
|
'--DataGrid-hasScrollX': '0',
|
|
'--DataGrid-hasScrollY': '0',
|
|
'--DataGrid-scrollbarSize': '10px',
|
|
'--DataGrid-rowWidth': '0px',
|
|
'--DataGrid-columnsTotalWidth': '0px',
|
|
'--DataGrid-leftPinnedWidth': '0px',
|
|
'--DataGrid-rightPinnedWidth': '0px',
|
|
'--DataGrid-headerHeight': '0px',
|
|
'--DataGrid-headersTotalHeight': '0px',
|
|
'--DataGrid-topContainerHeight': '0px',
|
|
'--DataGrid-bottomContainerHeight': '0px',
|
|
'--DataGrid-horizontalFiller': '0px',
|
|
flex: 1,
|
|
boxSizing: 'border-box',
|
|
position: 'relative',
|
|
borderWidth: '1px',
|
|
borderStyle: 'solid',
|
|
borderColor: vars.colors.border.base,
|
|
borderRadius: 'var(--unstable_DataGrid-radius)',
|
|
backgroundColor: vars.colors.background.base,
|
|
color: vars.colors.foreground.base,
|
|
font: vars.typography.font.body,
|
|
outline: 'none',
|
|
height: '100%',
|
|
display: 'flex',
|
|
minWidth: 0,
|
|
// See https://github.com/mui/mui-x/issues/8547
|
|
minHeight: 0,
|
|
flexDirection: 'column',
|
|
overflow: 'hidden',
|
|
transform: 'translate(0, 0)',
|
|
// Create a stacking context to keep scrollbars from showing on top
|
|
|
|
[`& .${c.virtualScroller}`]: {
|
|
overflowAnchor: 'none' // Keep the same scrolling position
|
|
},
|
|
// Use `css` tagged template so the ignore-comment remains a sibling of the
|
|
// `:first-child` rule in the stylis AST. Previously, the comment was embedded
|
|
// in the object-key selector, which got separated from the rule during
|
|
// pre-serialization when `styleOverrides` were applied, re-triggering Emotion's
|
|
// unsafe-selector SSR warning. https://github.com/emotion-js/emotion/issues/1105
|
|
[`.${c.main}`]: css`
|
|
& > *:first-child ${ignoreSsrWarning} {
|
|
border-top-left-radius: var(--unstable_DataGrid-radius);
|
|
border-top-right-radius: var(--unstable_DataGrid-radius);
|
|
}
|
|
`,
|
|
[`&.${c.autoHeight}`]: {
|
|
height: 'auto'
|
|
},
|
|
[`&.${c.autosizing}`]: {
|
|
[`& .${c.columnHeaderTitleContainerContent} > *`]: {
|
|
overflow: 'visible !important'
|
|
},
|
|
'@media (hover: hover)': {
|
|
[`& .${c.menuIcon}`]: {
|
|
width: '0 !important',
|
|
visibility: 'hidden !important'
|
|
}
|
|
},
|
|
[`& .${c.cell}`]: {
|
|
overflow: 'visible !important',
|
|
whiteSpace: 'nowrap',
|
|
minWidth: 'max-content !important',
|
|
maxWidth: 'max-content !important'
|
|
},
|
|
[`& .${c.groupingCriteriaCell}`]: {
|
|
width: 'unset'
|
|
},
|
|
[`& .${c.treeDataGroupingCell}`]: {
|
|
width: 'unset'
|
|
},
|
|
[`& .${c['columnHeader--filter']}`]: {
|
|
flex: 'none !important',
|
|
width: 'unset !important'
|
|
},
|
|
[`& .${c.multiSelectCell}`]: {
|
|
width: 'max-content',
|
|
overflow: 'visible'
|
|
},
|
|
[`& .${c['multiSelectCellChip--hidden']}`]: {
|
|
display: 'inline-flex'
|
|
},
|
|
[`& .${c.multiSelectCellOverflow}`]: {
|
|
display: 'none'
|
|
}
|
|
},
|
|
[`&.${c.withSidePanel}`]: {
|
|
flexDirection: 'row'
|
|
},
|
|
[`& .${c.mainContent}`]: {
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
overflow: 'hidden',
|
|
flex: 1
|
|
},
|
|
[`& .${c.columnHeader}, & .${c.cell}`]: {
|
|
WebkitTapHighlightColor: 'transparent',
|
|
padding: '0 10px',
|
|
boxSizing: 'border-box'
|
|
},
|
|
[`& .${c.columnHeader}:focus-within, & .${c.cell}:focus-within`]: {
|
|
outline: `solid ${setOpacity(vars.colors.interactive.focus, 0.5)} ${focusOutlineWidth}px`,
|
|
outlineOffset: focusOutlineWidth * -1
|
|
},
|
|
[`& .${c.columnHeader}:focus, & .${c.cell}:focus`]: {
|
|
outline: `solid ${vars.colors.interactive.focus} ${focusOutlineWidth}px`,
|
|
outlineOffset: focusOutlineWidth * -1
|
|
},
|
|
// Hide the column separator when:
|
|
// - the column is focused and has an outline
|
|
// - the next column is focused and has an outline
|
|
// - the column has a left or right border
|
|
// - the next column is pinned right and has a left border
|
|
[`& .${c.columnHeader}:focus,
|
|
& .${c['columnHeader--withLeftBorder']},
|
|
& .${c['columnHeader--withRightBorder']},
|
|
& .${c['columnHeader--siblingFocused']}
|
|
`]: {
|
|
[`& .${c.columnSeparator}`]: {
|
|
opacity: 0
|
|
},
|
|
// Show resizable separators at all times on touch devices
|
|
'@media (hover: none)': {
|
|
[`& .${c['columnSeparator--resizable']}`]: {
|
|
opacity: 1
|
|
}
|
|
},
|
|
[`& .${c['columnSeparator--resizable']}:hover`]: {
|
|
opacity: 1
|
|
}
|
|
},
|
|
[`&.${c['root--noToolbar']} [aria-rowindex="1"] [aria-colindex="1"]`]: {
|
|
borderTopLeftRadius: 'calc(var(--unstable_DataGrid-radius) - 1px)'
|
|
},
|
|
[`&.${c['root--noToolbar']} [aria-rowindex="1"] .${c['columnHeader--last']}`]: {
|
|
borderTopRightRadius: shouldShowBorderTopRightRadius ? 'calc(var(--unstable_DataGrid-radius) - 1px)' : undefined
|
|
},
|
|
[`& .${c.columnHeaderCheckbox}, & .${c.cellCheckbox}`]: {
|
|
padding: 0,
|
|
justifyContent: 'center',
|
|
alignItems: 'center'
|
|
},
|
|
[`& .${c.columnHeader}`]: {
|
|
position: 'relative',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
backgroundColor: headerBackground,
|
|
flex: '0 0 auto'
|
|
},
|
|
[`& .${c.columnHeader} .${c.sortButton}`]: {
|
|
backgroundColor: vars.header.background.base
|
|
},
|
|
[`& .${c['columnHeader--filter']}`]: {
|
|
paddingTop: 8,
|
|
paddingBottom: 8,
|
|
paddingRight: 5,
|
|
minHeight: 'min-content',
|
|
overflow: 'hidden'
|
|
},
|
|
[`&.${c['root--densityCompact']} .${c['columnHeader--filter']}`]: {
|
|
paddingTop: 4,
|
|
paddingBottom: 4
|
|
},
|
|
[`& .${c['virtualScroller--hasScrollX']} .${c['columnHeader--last']}`]: {
|
|
overflow: 'hidden'
|
|
},
|
|
[`& .${c['pivotPanelField--sorted']} .${c.iconButtonContainer},
|
|
& .${c['columnHeader--sorted']} .${c.iconButtonContainer},
|
|
& .${c['columnHeader--filtered']} .${c.iconButtonContainer}`]: {
|
|
visibility: 'visible',
|
|
width: 'auto'
|
|
},
|
|
[`& .${c.pivotPanelField}:not(.${c['pivotPanelField--sorted']}) .${c.sortButton},
|
|
& .${c.columnHeader}:not(.${c['columnHeader--sorted']}) .${c.sortButton}`]: {
|
|
opacity: 0,
|
|
transition: vars.transition(['opacity'], {
|
|
duration: vars.transitions.duration.short
|
|
})
|
|
},
|
|
[`& .${c.columnHeaderTitleContainer}`]: {
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: vars.spacing(0.25),
|
|
minWidth: 0,
|
|
flex: 1,
|
|
whiteSpace: 'nowrap',
|
|
overflow: 'hidden'
|
|
},
|
|
[`& .${c.columnHeaderTitleContainerContent}`]: {
|
|
overflow: 'hidden',
|
|
display: 'flex',
|
|
alignItems: 'center'
|
|
},
|
|
[`& .${c['columnHeader--filledGroup']} .${c.columnHeaderTitleContainer}`]: {
|
|
borderBottomWidth: '1px',
|
|
borderBottomStyle: 'solid',
|
|
boxSizing: 'border-box'
|
|
},
|
|
[`& .${c.sortIcon}, & .${c.filterIcon}`]: {
|
|
fontSize: 'inherit'
|
|
},
|
|
[`& .${c['columnHeader--sortable']}`]: {
|
|
cursor: 'pointer'
|
|
},
|
|
[`& .${c['columnHeader--alignCenter']} .${c.columnHeaderTitleContainer}`]: {
|
|
justifyContent: 'center'
|
|
},
|
|
[`& .${c['columnHeader--alignRight']} .${c.columnHeaderDraggableContainer}, & .${c['columnHeader--alignRight']} .${c.columnHeaderTitleContainer}`]: {
|
|
flexDirection: 'row-reverse'
|
|
},
|
|
[`& .${c['columnHeader--alignCenter']} .${c.menuIcon}`]: {
|
|
marginLeft: 'auto'
|
|
},
|
|
[`& .${c['columnHeader--alignRight']} .${c.menuIcon}`]: {
|
|
marginRight: 'auto',
|
|
marginLeft: -5
|
|
},
|
|
[`& .${c['columnHeader--moving']}`]: {
|
|
backgroundColor: hoverBackground
|
|
},
|
|
[`& .${c['columnHeader--pinnedLeft']}, & .${c['columnHeader--pinnedRight']}`]: {
|
|
position: 'sticky',
|
|
zIndex: 40,
|
|
// Should be above the column separator
|
|
background: vars.header.background.base
|
|
},
|
|
[`& .${c.columnSeparator}`]: {
|
|
position: 'absolute',
|
|
overflow: 'hidden',
|
|
zIndex: 30,
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
maxWidth: columnSeparatorTargetSize,
|
|
color: vars.colors.border.base
|
|
},
|
|
[`& .${c.columnHeaders}`]: {
|
|
width: 'var(--DataGrid-rowWidth)',
|
|
backgroundColor: headerBackground
|
|
},
|
|
'@media (hover: hover)': {
|
|
[`& .${c.columnHeader}:hover`]: {
|
|
[`& .${c.menuIcon}`]: {
|
|
width: 'auto',
|
|
visibility: 'visible'
|
|
},
|
|
[`& .${c.iconButtonContainer}`]: {
|
|
visibility: 'visible',
|
|
width: 'auto'
|
|
}
|
|
},
|
|
[`& .${c.columnHeader}:not(.${c['columnHeader--sorted']}):hover .${c.sortButton},
|
|
& .${c.pivotPanelField}:not(.${c['pivotPanelField--sorted']}):hover .${c.sortButton},
|
|
& .${c.pivotPanelField}:not(.${c['pivotPanelField--sorted']}) .${c.sortButton}:focus-visible`]: {
|
|
opacity: 1
|
|
},
|
|
// Add opacity only to the button content to avoid affecting the background color
|
|
[`& .${c.columnHeader}:not(.${c['columnHeader--sorted']}):hover .${c.sortButton} > *,
|
|
& .${c.pivotPanelField}:not(.${c['pivotPanelField--sorted']}):hover .${c.sortButton} > *,
|
|
& .${c.pivotPanelField}:not(.${c['pivotPanelField--sorted']}) .${c.sortButton}:focus-visible > *`]: {
|
|
opacity: 0.78
|
|
},
|
|
[`& .${c.pivotPanelFieldActionContainer} button:hover`]: {
|
|
backgroundColor: vars.colors.background.base
|
|
}
|
|
},
|
|
'@media (hover: none)': {
|
|
[`& .${c.columnHeader} .${c.menuIcon}`]: {
|
|
width: 'auto',
|
|
visibility: 'visible'
|
|
},
|
|
[`& .${c.columnHeader}:focus,
|
|
& .${c['columnHeader--siblingFocused']}`]: {
|
|
[`.${c['columnSeparator--resizable']}`]: {
|
|
color: vars.colors.foreground.accent
|
|
}
|
|
},
|
|
[`& .${c.pivotPanelField}:not(.${c['pivotPanelField--sorted']}) .${c.sortButton}`]: {
|
|
opacity: 0.78
|
|
}
|
|
},
|
|
// Hide the column separator when the column has border and it is not resizable
|
|
// In this case, this column separator may block interaction with the separator from the adjacent column that is resizable
|
|
[`& .${c['columnHeader--withLeftBorder']} .${c['columnSeparator--sideLeft']}:not(.${c['columnSeparator--resizable']}), & .${c['columnHeader--withRightBorder']} .${c['columnSeparator--sideRight']}:not(.${c['columnSeparator--resizable']})`]: {
|
|
display: 'none'
|
|
},
|
|
[`& .${c['columnSeparator--sideLeft']}`]: {
|
|
left: columnSeparatorOffset
|
|
},
|
|
[`& .${c['columnSeparator--sideRight']}`]: {
|
|
right: columnSeparatorOffset
|
|
},
|
|
[`& .${c['columnHeader--withRightBorder']} .${c['columnSeparator--sideLeft']}`]: {
|
|
left: columnSeparatorOffset - 0.5
|
|
},
|
|
[`& .${c['columnHeader--withRightBorder']} .${c['columnSeparator--sideRight']}`]: {
|
|
right: columnSeparatorOffset - 0.5
|
|
},
|
|
[`& .${c['columnSeparator--resizable']}`]: {
|
|
cursor: 'col-resize',
|
|
touchAction: 'none',
|
|
[`&.${c['columnSeparator--resizing']}`]: {
|
|
color: vars.colors.foreground.accent
|
|
},
|
|
// Always appear as draggable on touch devices
|
|
'@media (hover: none)': {
|
|
[`& .${c.iconSeparator} rect`]: separatorIconDragStyles
|
|
},
|
|
'@media (hover: hover)': {
|
|
'&:hover': {
|
|
color: vars.colors.foreground.accent,
|
|
[`& .${c.iconSeparator} rect`]: separatorIconDragStyles
|
|
}
|
|
},
|
|
'& svg': {
|
|
pointerEvents: 'none'
|
|
}
|
|
},
|
|
[`& .${c.iconSeparator}`]: {
|
|
color: 'inherit',
|
|
transition: vars.transition(['color', 'width'], {
|
|
duration: vars.transitions.duration.short
|
|
})
|
|
},
|
|
[`& .${c.menuIcon}`]: {
|
|
width: 0,
|
|
visibility: 'hidden',
|
|
fontSize: 20,
|
|
marginRight: -5,
|
|
display: 'flex',
|
|
alignItems: 'center'
|
|
},
|
|
[`.${c.menuOpen}`]: {
|
|
visibility: 'visible',
|
|
width: 'auto'
|
|
},
|
|
[`& .${c.headerFilterRow}`]: {
|
|
[`& .${c.columnHeader}, & .${c.scrollbarFiller}`]: {
|
|
boxSizing: 'border-box',
|
|
borderBottom: '1px solid var(--DataGrid-rowBorderColor)'
|
|
}
|
|
},
|
|
/* Bottom border of the top-container */
|
|
[`& .${c['row--borderBottom']} .${c.columnHeader},
|
|
& .${c['row--borderBottom']} .${c.filler},
|
|
& .${c['row--borderBottom']} .${c.scrollbarFiller}`]: {
|
|
borderBottom: `1px solid var(--DataGrid-rowBorderColor)`
|
|
},
|
|
[`& .${c['row--borderBottom']} .${c.cell}`]: {
|
|
borderBottom: `1px solid var(--rowBorderColor)`
|
|
},
|
|
/* Row styles */
|
|
[`.${c.row}`]: {
|
|
display: 'flex',
|
|
position: 'relative',
|
|
width: 'var(--DataGrid-rowWidth)',
|
|
breakInside: 'avoid',
|
|
// Avoid the row to be broken in two different print pages.
|
|
|
|
'--rowBorderColor': 'var(--DataGrid-rowBorderColor)',
|
|
[`&.${c['row--firstVisible']}`]: {
|
|
'--rowBorderColor': 'transparent'
|
|
},
|
|
'&:hover': {
|
|
backgroundColor: hoverBackground,
|
|
// Reset on touch devices, it doesn't add specificity
|
|
'@media (hover: none)': {
|
|
backgroundColor: 'transparent'
|
|
}
|
|
},
|
|
[`&.${c.rowSkeleton}:hover`]: {
|
|
backgroundColor: 'transparent'
|
|
},
|
|
'&.Mui-selected': selectedStyles
|
|
},
|
|
/* Cell styles */
|
|
[`& .${c.cell}`]: {
|
|
flex: '0 0 auto',
|
|
height: 'var(--height)',
|
|
width: 'var(--width)',
|
|
lineHeight: 'calc(var(--height) - 1px)',
|
|
// -1px for the border
|
|
|
|
boxSizing: 'border-box',
|
|
borderTop: `1px solid var(--rowBorderColor)`,
|
|
overflow: 'hidden',
|
|
whiteSpace: 'nowrap',
|
|
textOverflow: 'ellipsis',
|
|
'&.Mui-selected': selectedStyles
|
|
},
|
|
/* Default range border styles using box-shadow to avoid layout shift */
|
|
[`& .${c.cell}.Mui-selected`]: {
|
|
'--range-top': '0 0 0 0 transparent',
|
|
'--range-bottom': '0 0 0 0 transparent',
|
|
'--range-left': '0 0 0 0 transparent',
|
|
'--range-right': '0 0 0 0 transparent',
|
|
boxShadow: 'var(--range-top), var(--range-bottom), var(--range-left), var(--range-right)'
|
|
},
|
|
[`& .${c['cell--rangeTop']}`]: {
|
|
'--range-top': `inset 0 2px 0 0 ${vars.colors.interactive.focus}`
|
|
},
|
|
[`& .${c['cell--rangeBottom']}`]: {
|
|
'--range-bottom': `inset 0 -2px 0 0 ${vars.colors.interactive.focus}`
|
|
},
|
|
[`& .${c['cell--rangeLeft']}`]: {
|
|
'--range-left': `inset 2px 0 0 0 ${vars.colors.interactive.focus}`
|
|
},
|
|
[`& .${c['cell--rangeRight']}`]: {
|
|
'--range-right': `inset -2px 0 0 0 ${vars.colors.interactive.focus}`
|
|
},
|
|
[`& .${c['virtualScrollerContent--overflowed']} .${c['row--lastVisible']} .${c.cell}`]: {
|
|
borderTopColor: 'transparent'
|
|
},
|
|
[`& .${c.pinnedRows} .${c.row}, .${c.aggregationRowOverlayWrapper} .${c.row}`]: {
|
|
backgroundColor: pinnedBackground,
|
|
'&:hover': {
|
|
backgroundColor: pinnedHoverBackground
|
|
}
|
|
},
|
|
[`& .${c['pinnedRows--top']} :first-of-type`]: {
|
|
[`& .${c.cell}, .${c.scrollbarFiller}`]: {
|
|
borderTop: 'none'
|
|
}
|
|
},
|
|
[`&.${c['root--disableUserSelection']}`]: {
|
|
userSelect: 'none'
|
|
},
|
|
[`& .${c['row--dynamicHeight']} > .${c.cell}`]: {
|
|
whiteSpace: 'initial',
|
|
lineHeight: 'inherit'
|
|
},
|
|
[`& .${c['row--dynamicHeight']}`]: {
|
|
[`& .${c.multiSelectCell}, .${c.editMultiSelectCell}`]: {
|
|
flexWrap: 'wrap'
|
|
}
|
|
},
|
|
[`& .${c.cell}[aria-rowspan]:not([aria-rowspan="1"])`]: {
|
|
[`& .${c.multiSelectCell}`]: {
|
|
alignItems: 'flex-start',
|
|
alignContent: 'flex-start',
|
|
flexWrap: 'wrap',
|
|
paddingTop: 8
|
|
},
|
|
[`& .${c['multiSelectCellChip--hidden']}`]: {
|
|
display: 'inline-flex'
|
|
},
|
|
[`& .${c.multiSelectCellOverflow}`]: {
|
|
display: 'none'
|
|
}
|
|
},
|
|
[`& .${c.cellEmpty}`]: {
|
|
flex: 1,
|
|
padding: 0,
|
|
height: 'unset'
|
|
},
|
|
[`& .${c.cell}.${c['cell--selectionMode']}`]: {
|
|
cursor: 'default'
|
|
},
|
|
[`& .${c.cell}.${c['cell--editing']}`]: {
|
|
padding: 1,
|
|
display: 'flex',
|
|
boxShadow: vars.shadows.base,
|
|
backgroundColor: vars.colors.background.overlay,
|
|
'&:focus-within': {
|
|
outline: `${focusOutlineWidth}px solid ${vars.colors.interactive.focus}`,
|
|
outlineOffset: focusOutlineWidth * -1
|
|
}
|
|
},
|
|
[`& .${c['cell--editing']}`]: {
|
|
'& .MuiInputBase-root': {
|
|
height: '100%'
|
|
}
|
|
},
|
|
[`& .${c['row--editing']}`]: {
|
|
boxShadow: vars.shadows.base
|
|
},
|
|
[`& .${c['row--editing']} .${c.cell}`]: {
|
|
boxShadow: 'none',
|
|
backgroundColor: vars.colors.background.overlay
|
|
},
|
|
[`& .${c.editBooleanCell}`]: {
|
|
display: 'flex',
|
|
height: '100%',
|
|
width: '100%',
|
|
alignItems: 'center',
|
|
justifyContent: 'center'
|
|
},
|
|
[`& .${c.booleanCell}[data-value="true"]`]: {
|
|
color: vars.colors.foreground.muted
|
|
},
|
|
[`& .${c.booleanCell}[data-value="false"]`]: {
|
|
color: vars.colors.foreground.disabled
|
|
},
|
|
[`& .${c.actionsCell}`]: {
|
|
display: 'inline-flex',
|
|
alignItems: 'center',
|
|
gridGap: vars.spacing(1)
|
|
},
|
|
[`& .${c.rowReorderCell}`]: {
|
|
display: 'inline-flex',
|
|
flex: 1,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
opacity: vars.colors.interactive.disabledOpacity
|
|
},
|
|
[`& .${c['rowReorderCell--draggable']}`]: {
|
|
cursor: 'grab',
|
|
opacity: 1
|
|
},
|
|
[`& .${c.rowReorderCellContainer}`]: {
|
|
padding: 0,
|
|
display: 'flex',
|
|
alignItems: 'stretch'
|
|
},
|
|
[`.${c.withBorderColor}`]: {
|
|
borderColor: vars.colors.border.base
|
|
},
|
|
[`& .${c['cell--withLeftBorder']}, & .${c['columnHeader--withLeftBorder']}`]: {
|
|
borderLeftColor: 'var(--DataGrid-rowBorderColor)',
|
|
borderLeftWidth: '1px',
|
|
borderLeftStyle: 'solid'
|
|
},
|
|
[`& .${c['cell--withRightBorder']}, & .${c['columnHeader--withRightBorder']}`]: {
|
|
borderRightColor: 'var(--DataGrid-rowBorderColor)',
|
|
borderRightWidth: '1px',
|
|
borderRightStyle: 'solid'
|
|
},
|
|
[`& .${c['cell--flex']}`]: {
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
lineHeight: 'inherit'
|
|
},
|
|
[`& .${c['cell--textLeft']}`]: {
|
|
textAlign: 'left',
|
|
justifyContent: 'flex-start'
|
|
},
|
|
[`& .${c['cell--textRight']}`]: {
|
|
textAlign: 'right',
|
|
justifyContent: 'flex-end'
|
|
},
|
|
[`& .${c['cell--textCenter']}`]: {
|
|
textAlign: 'center',
|
|
justifyContent: 'center'
|
|
},
|
|
[`& .${c['cell--pinnedLeft']}, & .${c['cell--pinnedRight']}`]: {
|
|
position: 'sticky',
|
|
zIndex: 30,
|
|
background: vars.cell.background.pinned,
|
|
'&.Mui-selected': {
|
|
backgroundColor: pinnedSelectedBackground
|
|
}
|
|
},
|
|
[`& .${c.row}`]: {
|
|
'&:hover': pinnedHoverStyles,
|
|
'&.Mui-selected': pinnedSelectedStyles,
|
|
'&.Mui-selected:hover': pinnedSelectedHoverStyles
|
|
},
|
|
[`& .${c.cellOffsetLeft}`]: {
|
|
flex: '0 0 auto',
|
|
display: 'inline-block'
|
|
},
|
|
[`& .${c.cellSkeleton}`]: {
|
|
flex: '0 0 auto',
|
|
height: '100%',
|
|
display: 'inline-flex',
|
|
alignItems: 'center'
|
|
},
|
|
[`& .${c.columnHeaderDraggableContainer}`]: {
|
|
display: 'flex',
|
|
width: '100%',
|
|
height: '100%'
|
|
},
|
|
[`& .${c.rowReorderCellPlaceholder}`]: {
|
|
display: 'none'
|
|
},
|
|
[`& .${c['columnHeader--dragging']}`]: {
|
|
background: vars.colors.background.overlay,
|
|
padding: '0 12px',
|
|
borderRadius: 'var(--unstable_DataGrid-radius)',
|
|
opacity: vars.colors.interactive.disabledOpacity
|
|
},
|
|
[`& .${c['row--dragging']}`]: {
|
|
background: vars.colors.background.overlay,
|
|
padding: '0 12px',
|
|
borderRadius: 'var(--unstable_DataGrid-radius)',
|
|
border: '1px solid var(--DataGrid-rowBorderColor)',
|
|
color: vars.colors.foreground.base,
|
|
transform: 'translateZ(0)',
|
|
[`& .${c.rowReorderCellPlaceholder}`]: {
|
|
padding: '0 6px',
|
|
display: 'flex'
|
|
}
|
|
},
|
|
[`& .${c.treeDataGroupingCell}`]: {
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
width: '100%'
|
|
},
|
|
[`& .${c.treeDataGroupingCellToggle}`]: {
|
|
flex: '0 0 28px',
|
|
alignSelf: 'stretch',
|
|
marginRight: vars.spacing(2)
|
|
},
|
|
[`& .${c.treeDataGroupingCellLoadingContainer}, .${c.groupingCriteriaCellLoadingContainer}`]: {
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
height: '100%'
|
|
},
|
|
[`& .${c.groupingCriteriaCell}`]: {
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
width: '100%'
|
|
},
|
|
[`& .${c.groupingCriteriaCellToggle}`]: {
|
|
flex: '0 0 28px',
|
|
alignSelf: 'stretch',
|
|
marginRight: vars.spacing(2)
|
|
},
|
|
/* ScrollbarFiller styles */
|
|
[`& .${c.columnHeaders} .${c.scrollbarFiller}`]: {
|
|
backgroundColor: headerBackground
|
|
},
|
|
[`.${c.scrollbarFiller}`]: {
|
|
minWidth: 'calc(var(--DataGrid-hasScrollY) * var(--DataGrid-scrollbarSize))',
|
|
alignSelf: 'stretch',
|
|
backgroundColor: headerBackground,
|
|
[`&.${c['scrollbarFiller--pinnedRight']}`]: {
|
|
position: 'sticky',
|
|
zIndex: 40,
|
|
// Should be above the column separator
|
|
right: 0
|
|
}
|
|
},
|
|
[`& .${c.filler}`]: {
|
|
flex: '1 0 auto'
|
|
},
|
|
[`& .${c['filler--borderBottom']}`]: {
|
|
borderBottom: '1px solid var(--DataGrid-rowBorderColor)'
|
|
},
|
|
[`& .${c['filler--horizontal']}`]: {
|
|
width: 'var(--DataGrid-horizontalFiller)'
|
|
},
|
|
[`& .${c.columnHeaders} .${c.filler}`]: {
|
|
backgroundColor: headerBackground
|
|
},
|
|
/* Used when skeleton/no columns overlay is visible */
|
|
[`& .${c['main--hiddenContent']}`]: {
|
|
[`& .${c.virtualScrollerRenderZone}`]: {
|
|
// We use visibility hidden so that the virtual scroller content retains its height.
|
|
// Position fixed is used to remove the virtual scroller content from the flow.
|
|
// https://github.com/mui/mui-x/issues/14061
|
|
visibility: 'hidden'
|
|
},
|
|
// Hide grid content
|
|
[`& .${c.pinnedRows}`]: {
|
|
display: 'none'
|
|
}
|
|
},
|
|
/* Fill handle styles */
|
|
[`& .${c['cell--withFillHandle']}`]: {
|
|
position: 'relative',
|
|
'&::after': {
|
|
content: '""',
|
|
position: 'absolute',
|
|
bottom: 0,
|
|
insetInlineEnd: 0,
|
|
width: 7,
|
|
height: 7,
|
|
backgroundColor: vars.colors.interactive.focus,
|
|
cursor: 'crosshair',
|
|
zIndex: 50
|
|
}
|
|
},
|
|
[`& .${c['cell--fillPreview']}`]: {
|
|
backgroundColor: `color-mix(in srgb, ${vars.colors.interactive.focus} 8%, transparent)`
|
|
},
|
|
[`& .${c['cell--fillPreviewTop']}`]: {
|
|
borderTop: `1px dashed ${vars.colors.interactive.focus}`
|
|
},
|
|
[`& .${c['cell--fillPreviewBottom']}`]: {
|
|
borderBottom: `1px dashed ${vars.colors.interactive.focus}`
|
|
},
|
|
[`& .${c['cell--fillPreviewLeft']}`]: {
|
|
borderLeft: `1px dashed ${vars.colors.interactive.focus}`
|
|
},
|
|
[`& .${c['cell--fillPreviewRight']}`]: {
|
|
borderRight: `1px dashed ${vars.colors.interactive.focus}`
|
|
},
|
|
[`& .${c['row--beingDragged']}`]: {
|
|
color: vars.colors.foreground.disabled,
|
|
'&:hover': {
|
|
backgroundColor: 'transparent'
|
|
}
|
|
},
|
|
/* Controlled layout overrides (absolute positioning for pinned elements) */
|
|
[`& .${c['virtualizer--layoutControlled']} .${c['columnHeader--pinnedLeft']},
|
|
& .${c['virtualizer--layoutControlled']} .${c['columnHeader--pinnedRight']}`]: {
|
|
position: 'absolute',
|
|
height: 'var(--height)'
|
|
},
|
|
[`& .${c['virtualizer--layoutControlled']} .${c['cell--pinnedLeft']},
|
|
& .${c['virtualizer--layoutControlled']} .${c['cell--pinnedRight']}`]: {
|
|
position: 'absolute'
|
|
},
|
|
[`& .${c['virtualizer--layoutControlled']} .${c.row}`]: {
|
|
position: 'static'
|
|
},
|
|
[`& .${c['virtualizer--layoutControlled']} .${c['scrollbarFiller--pinnedRight']}`]: {
|
|
position: 'absolute',
|
|
height: 'var(--height)'
|
|
},
|
|
[`& .${c['virtualizer--layoutControlled']} .${c.virtualScrollerRenderZone}`]: {
|
|
position: 'static',
|
|
width: 'fit-content'
|
|
},
|
|
[`& .${c['virtualizer--layoutControlled']} .${c['container--top']}`]: {
|
|
width: 'fit-content'
|
|
},
|
|
[`& .${c['virtualizer--layoutControlled']} .${c['container--bottom']}`]: {
|
|
width: 'fit-content'
|
|
}
|
|
};
|
|
return gridStyle;
|
|
});
|
|
function setOpacity(color, opacity) {
|
|
return `rgba(from ${color} r g b / ${opacity})`;
|
|
}
|
|
function removeOpacity(color) {
|
|
return setOpacity(color, 1);
|
|
}
|
|
export const supportsColorMix = typeof CSS !== 'undefined' && typeof CSS.supports === 'function' && CSS.supports('color', 'color-mix(in srgb, red 50%, blue 50%)');
|
|
export const colorMixIfSupported = (colorMixValue, fallback) => {
|
|
if (!supportsColorMix) {
|
|
return fallback;
|
|
}
|
|
return colorMixValue;
|
|
};
|
|
function mix(background, overlay, opacity, fallback) {
|
|
return colorMixIfSupported(`color-mix(in srgb,${background}, ${overlay} calc(${opacity} * 100%))`, fallback);
|
|
} |