diff --git a/packages/grid/data-grid/package.json b/packages/grid/data-grid/package.json index 03341002a85cb..d498c5d235e4c 100644 --- a/packages/grid/data-grid/package.json +++ b/packages/grid/data-grid/package.json @@ -39,8 +39,7 @@ }, "peerDependencies": { "@material-ui/core": "^4.9.12", - "react": "^16.8.0", - "styled-components": "^5.1.0" + "react": "^16.8.0" }, "setupFiles": [ "/src/setupTests.js" diff --git a/packages/grid/data-grid/src/DataGrid.tsx b/packages/grid/data-grid/src/DataGrid.tsx index 93c38ff3f4c9d..bae2546a4c300 100644 --- a/packages/grid/data-grid/src/DataGrid.tsx +++ b/packages/grid/data-grid/src/DataGrid.tsx @@ -35,7 +35,7 @@ const DataGrid2 = React.forwardRef(function DataG return ( { - return apiRef!.current.subscribeEvent(COMPONENT_ERROR, errorHandler); - }, [apiRef]); + React.useEffect(() => apiRef!.current.subscribeEvent(COMPONENT_ERROR, errorHandler), [apiRef]); React.useEffect(() => { apiRef!.current.showError(props.error); @@ -166,8 +166,7 @@ export const GridComponent = React.forwardRef ( ( -
{customComponents.renderError(errorProps)}
+
+ {customComponents.renderError(errorProps)} +
)} > {customComponents.headerComponent} -
+
- + diff --git a/packages/grid/x-grid-modules/src/components/cell.tsx b/packages/grid/x-grid-modules/src/components/cell.tsx index 573eab80a18ab..caf0fa74267bd 100644 --- a/packages/grid/x-grid-modules/src/components/cell.tsx +++ b/packages/grid/x-grid-modules/src/components/cell.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { Alignement, CellValue } from '../models'; import { CELL_CSS_CLASS } from '../constants/cssClassesConstants'; import { classnames } from '../utils'; +import { OptionsContext } from './options-context'; export interface GridCellProps { field?: string; @@ -16,6 +17,11 @@ export interface GridCellProps { rowIndex?: number; } +const alignPropToCssClass = { + center: 'MuiDataGrid-cellCenter', + right: 'MuiDataGrid-cellRight', +}; + export const Cell: React.FC = React.memo( ({ value, @@ -33,10 +39,11 @@ export const Cell: React.FC = React.memo( const cssClasses = classnames( CELL_CSS_CLASS, cssClass, - { 'with-border': showRightBorder }, - align !== 'left' ? align : '', + { 'MuiDataGrid-withBorder': showRightBorder }, + align && align !== 'left' ? alignPropToCssClass[align] : '', ); const valueToRender = formattedValue || value; + const { rowHeight } = React.useContext(OptionsContext); return (
= React.memo( data-colindex={colIndex} data-rowindex={rowIndex} aria-colindex={colIndex} - style={{ minWidth: width, maxWidth: width }} + style={{ + minWidth: width, + maxWidth: width, + lineHeight: `${rowHeight - 1}px`, + minHeight: rowHeight, + maxHeight: rowHeight, + }} tabIndex={tabIndex} > {children || valueToRender?.toString()} diff --git a/packages/grid/x-grid-modules/src/components/checkbox-renderer.tsx b/packages/grid/x-grid-modules/src/components/checkbox-renderer.tsx index e9e1616cbbe9e..dd97db4e6940a 100644 --- a/packages/grid/x-grid-modules/src/components/checkbox-renderer.tsx +++ b/packages/grid/x-grid-modules/src/components/checkbox-renderer.tsx @@ -1,14 +1,9 @@ import * as React from 'react'; import Checkbox from '@material-ui/core/Checkbox'; -import styled from 'styled-components'; import { SelectionChangeParams } from '../models/params/selectionChangeParams'; import { ColParams } from '../models/params/colParams'; import { CellParams } from '../models/params/cellParams'; -const CheckboxInputContainer = styled.div` - display: block; -`; - export const HeaderCheckbox: React.FC = React.memo(({ api }) => { const [isChecked, setChecked] = React.useState(false); const [isIndeterminate, setIndeterminate] = React.useState(false); @@ -31,16 +26,18 @@ export const HeaderCheckbox: React.FC = React.memo(({ api }) => { React.useEffect(() => { return api.onSelectionChange(selectionChange); }, [api, selectionChange]); + return ( - +
- +
); }); HeaderCheckbox.displayName = 'HeaderCheckbox'; @@ -51,14 +48,15 @@ export const CellCheckboxRenderer: React.FC = React.memo(({ api, row }; return ( - +
- +
); }); CellCheckboxRenderer.displayName = 'CellCheckboxRenderer'; diff --git a/packages/grid/x-grid-modules/src/components/column-header-item.tsx b/packages/grid/x-grid-modules/src/components/column-header-item.tsx index 688cf4ce4465a..5359cadb0a432 100644 --- a/packages/grid/x-grid-modules/src/components/column-header-item.tsx +++ b/packages/grid/x-grid-modules/src/components/column-header-item.tsx @@ -6,23 +6,30 @@ import { classnames } from '../utils'; import { ColumnHeaderSortIcon } from './column-header-sort-icon'; import { ColumnHeaderTitle } from './column-header-title'; import { ColumnHeaderSeparator } from './column-header-separator'; +import { OptionsContext } from './options-context'; interface ColumnHeaderItemProps { column: ColDef; - headerHeight: number; colIndex: number; onResizeColumn?: (c: any) => void; } - +const headerAlignPropToCss = { + center: 'MuiDataGrid-colCellCenter', + right: 'MuiDataGrid-colCellRight', +}; export const ColumnHeaderItem = React.memo( - ({ column, colIndex, headerHeight, onResizeColumn }: ColumnHeaderItemProps) => { + ({ column, colIndex, onResizeColumn }: ColumnHeaderItemProps) => { const api = React.useContext(ApiContext); + const { headerHeight, showColumnRightBorder } = React.useContext(OptionsContext); const cssClass = classnames( HEADER_CELL_CSS_CLASS, + showColumnRightBorder ? 'MuiDataGrid-withBorder' : '', column.headerClassName, - column.headerAlign !== 'left' ? column.headerAlign : '', - { sortable: column.sortable }, + column.headerAlign && column.headerAlign !== 'left' + ? headerAlignPropToCss[column.headerAlign] + : '', + { 'MuiDataGrid-colCellSortable': column.sortable }, ); let headerComponent: React.ReactElement | null = null; @@ -35,7 +42,7 @@ export const ColumnHeaderItem = React.memo( }); } - const onResize = onResizeColumn ? () => onResizeColumn(column) : undefined; + const handleResize = onResizeColumn ? () => onResizeColumn(column) : undefined; const width = column.width!; @@ -82,7 +89,7 @@ export const ColumnHeaderItem = React.memo( hide={column.hideSortIcons} /> )} - +
); }, diff --git a/packages/grid/x-grid-modules/src/components/column-header-separator.tsx b/packages/grid/x-grid-modules/src/components/column-header-separator.tsx index 8100747468444..779270f6593e7 100644 --- a/packages/grid/x-grid-modules/src/components/column-header-separator.tsx +++ b/packages/grid/x-grid-modules/src/components/column-header-separator.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { useIcons } from '../hooks/utils/useIcons'; +import { OptionsContext } from './options-context'; export interface ColumnHeaderSeparatorProps { resizable: boolean | undefined; @@ -9,15 +10,23 @@ export interface ColumnHeaderSeparatorProps { export const ColumnHeaderSeparator: React.FC = React.memo( ({ onResize, resizable }) => { const icons = useIcons(); + const { showColumnRightBorder, headerHeight } = React.useContext(OptionsContext); const resizeIconProps = { - className: `icon separator ${resizable ? 'resizable' : ''}`, + className: `MuiDataGrid-iconSeparator ${resizable ? 'MuiDataGrid-resizable' : ''}`, ...(resizable && onResize ? { onMouseDown: onResize } : {}), }; const icon = React.createElement(icons!.columnResize!, resizeIconProps); - return
{icon}
; + return ( +
+ {icon} +
+ ); }, ); ColumnHeaderSeparator.displayName = 'ColumnHeaderSeparator'; diff --git a/packages/grid/x-grid-modules/src/components/column-header-sort-icon.tsx b/packages/grid/x-grid-modules/src/components/column-header-sort-icon.tsx index b0406b9bba9bc..b907817293f4b 100644 --- a/packages/grid/x-grid-modules/src/components/column-header-sort-icon.tsx +++ b/packages/grid/x-grid-modules/src/components/column-header-sort-icon.tsx @@ -10,10 +10,10 @@ export interface ColumnHeaderSortIconProps { hide?: boolean; } -const getIcon = (icons: IconsOptions, direction: SortDirection): React.ReactNode => - direction === 'asc' - ? React.createElement(icons!.columnSortedAscending!) - : React.createElement(icons!.columnSortedDescending!); +function getIcon(icons: IconsOptions, direction: SortDirection) { + const Icon = direction === 'asc' ? icons!.columnSortedAscending! : icons!.columnSortedDescending!; + return ; +} export const ColumnHeaderSortIcon: React.FC = React.memo( ({ direction, index, hide }) => { @@ -24,7 +24,7 @@ export const ColumnHeaderSortIcon: React.FC = React.m } return ( - + {index != null && ( diff --git a/packages/grid/x-grid-modules/src/components/column-header-title.tsx b/packages/grid/x-grid-modules/src/components/column-header-title.tsx index beb14b48268e5..92e765e2bd586 100644 --- a/packages/grid/x-grid-modules/src/components/column-header-title.tsx +++ b/packages/grid/x-grid-modules/src/components/column-header-title.tsx @@ -11,7 +11,7 @@ const ColumnHeaderInnerTitle = React.forwardRef< return (
diff --git a/packages/grid/x-grid-modules/src/components/column-headers.tsx b/packages/grid/x-grid-modules/src/components/column-headers.tsx index 75a95047b2376..c69012ea0133e 100644 --- a/packages/grid/x-grid-modules/src/components/column-headers.tsx +++ b/packages/grid/x-grid-modules/src/components/column-headers.tsx @@ -6,17 +6,15 @@ import { LeftEmptyCell, RightEmptyCell } from './cell'; export interface ColumnHeadersItemCollectionProps { columns: Columns; - headerHeight: number; onResizeColumn?: (col: ColDef) => void; } export const ColumnHeaderItemCollection: React.FC = React.memo( - ({ headerHeight, onResizeColumn, columns }) => { + ({ onResizeColumn, columns }) => { const items = columns.map((col, idx) => ( )); @@ -29,15 +27,14 @@ ColumnHeaderItemCollection.displayName = 'ColumnHeaderItemCollection'; export interface ColumnsHeaderProps { columns: Columns; hasScrollX: boolean; - headerHeight: number; onResizeColumn?: (col: ColDef) => void; renderCtx: Partial | null; } export const ColumnsHeader = React.memo( React.forwardRef( - ({ columns, hasScrollX, headerHeight, onResizeColumn, renderCtx }, columnsHeaderRef) => { - const wrapperCssClasses = `material-col-cell-wrapper ${hasScrollX ? 'scroll' : ''}`; + ({ columns, hasScrollX, onResizeColumn, renderCtx }, columnsHeaderRef) => { + const wrapperCssClasses = `MuiDataGrid-colCellWrapper ${hasScrollX ? 'scroll' : ''}`; const api = React.useContext(ApiContext); if (!api) { @@ -75,11 +72,7 @@ export const ColumnsHeader = React.memo( style={{ minWidth: renderCtx?.totalSizes?.width }} > - +
); diff --git a/packages/grid/x-grid-modules/src/components/options-context.ts b/packages/grid/x-grid-modules/src/components/options-context.ts index af482c2ec6c49..72aae12b895a6 100644 --- a/packages/grid/x-grid-modules/src/components/options-context.ts +++ b/packages/grid/x-grid-modules/src/components/options-context.ts @@ -1,4 +1,4 @@ import * as React from 'react'; -import { GridOptions } from '../models'; +import { DEFAULT_GRID_OPTIONS, GridOptions } from '../models'; -export const OptionsContext = React.createContext(undefined); +export const OptionsContext = React.createContext(DEFAULT_GRID_OPTIONS); diff --git a/packages/grid/x-grid-modules/src/components/row-cells.tsx b/packages/grid/x-grid-modules/src/components/row-cells.tsx index 253034bd29ec8..139f6ba28d6de 100644 --- a/packages/grid/x-grid-modules/src/components/row-cells.tsx +++ b/packages/grid/x-grid-modules/src/components/row-cells.tsx @@ -85,7 +85,7 @@ export const RowCells: React.FC = React.memo((props) => { let cellComponent: React.ReactElement | null = null; if (column.renderCell) { cellComponent = column.renderCell(cellParams); - cssClassProp = { cssClass: `${cssClassProp.cssClass} with-renderer` }; + cssClassProp = { cssClass: `${cssClassProp.cssClass} MuiDataGrid-cellWithRenderer` }; } const cellProps: GridCellProps & { children: any } = { diff --git a/packages/grid/x-grid-modules/src/components/row-count.tsx b/packages/grid/x-grid-modules/src/components/row-count.tsx index 6894e1604c6a0..ee8cf4f9f30c1 100644 --- a/packages/grid/x-grid-modules/src/components/row-count.tsx +++ b/packages/grid/x-grid-modules/src/components/row-count.tsx @@ -4,5 +4,5 @@ export const RowCount: React.FC<{ rowCount: number }> = ({ rowCount }) => { if (rowCount === 0) { return null; } - return
Total Rows: {rowCount.toLocaleString()}
; + return
Total Rows: {rowCount.toLocaleString()}
; }; diff --git a/packages/grid/x-grid-modules/src/components/row.tsx b/packages/grid/x-grid-modules/src/components/row.tsx index 42a2554bfefa6..3646cd3a6b1d8 100644 --- a/packages/grid/x-grid-modules/src/components/row.tsx +++ b/packages/grid/x-grid-modules/src/components/row.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; import { RowId } from '../models'; import { ROW_CSS_CLASS } from '../constants/cssClassesConstants'; +import { OptionsContext } from './options-context'; +import { classnames } from '../utils'; export interface RowProps { id: RowId; @@ -10,17 +12,22 @@ export interface RowProps { } export const Row: React.FC = ({ selected, id, className, rowIndex, children }) => { - const cssClasses = (selected ? 'selected ' : ' ') + (className || ''); const ariaRowIndex = rowIndex + 2; // 1 for the header row and 1 as it's 1 based + const { rowHeight } = React.useContext(OptionsContext); + return (
{children}
diff --git a/packages/grid/x-grid-modules/src/components/selected-row-count.tsx b/packages/grid/x-grid-modules/src/components/selected-row-count.tsx index d7371040ed6c3..795eb7968879a 100644 --- a/packages/grid/x-grid-modules/src/components/selected-row-count.tsx +++ b/packages/grid/x-grid-modules/src/components/selected-row-count.tsx @@ -1,13 +1,19 @@ import * as React from 'react'; -export const SelectedRowCount: React.FC<{ selectedRowCount: number }> = ({ selectedRowCount }) => { +interface SelectedRowCountProps { + selectedRowCount: number; +} + +export function SelectedRowCount(props: SelectedRowCountProps) { + const { selectedRowCount } = props; + if (selectedRowCount === 0) { return null; } return ( -
+
{`${selectedRowCount.toLocaleString()} ${selectedRowCount > 1 ? 'rows' : 'row'} selected`}
); -}; +} diff --git a/packages/grid/x-grid-modules/src/components/sticky-container.tsx b/packages/grid/x-grid-modules/src/components/sticky-container.tsx index 84947d7d493cb..f085e0d8d9627 100644 --- a/packages/grid/x-grid-modules/src/components/sticky-container.tsx +++ b/packages/grid/x-grid-modules/src/components/sticky-container.tsx @@ -3,7 +3,7 @@ import { ElementSize } from '../models'; export const StickyContainer: React.FC = ({ height, width, children }) => (
{ + const borderColor = + theme.palette.type === 'light' + ? lighten(fade(theme.palette.divider, 1), 0.88) + : darken(fade(theme.palette.divider, 1), 0.68); + + return { + root: { + flex: 1, + boxSizing: 'border-box', + position: 'relative', + border: `1px solid ${borderColor}`, + borderRadius: theme.shape.borderRadius, + outline: 'none', + display: 'flex', + flexDirection: 'column', + '& *, & *::before, & *::after': { + boxSizing: 'inherit', + }, + '& .MuiDataGrid-mainGridContainer': { + position: 'relative', + flexGrow: 1, + display: 'flex', + flexDirection: 'column', + }, + '& .MuiDataGrid-overlay': { + display: 'flex', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 15, + alignSelf: 'center', + alignItems: 'center', + zIndex: 10, + }, + '& .MuiDataGrid-overlayContent': { + flex: 1, + display: 'flex', + justifyContent: 'center', + }, + '& .MuiDataGrid-columnsContainer': { + position: 'absolute', + top: 0, + left: 0, + right: 0, + overflow: 'hidden', + display: 'flex', + flexDirection: 'column', + borderBottom: `1px solid ${borderColor}`, + zIndex: 100, + }, + '& .MuiDataGrid-colCellWrapper': { + display: 'flex', + width: '100%', + alignItems: 'center', + }, + '& .MuiDataGrid-colCell, & .MuiDataGrid-cell': { + WebkitTapHighlightColor: 'transparent', + ...theme.typography.body2, + lineHeight: null, + padding: theme.spacing(0, 2), + }, + '& .MuiDataGrid-colCell:focus, & .MuiDataGrid-cell:focus': { + outline: 'dotted', + outlineWidth: 1, + outlineOffset: -2, + }, + '& .MuiDataGrid-colCellCheckbox, & .MuiDataGrid-cellCheckbox': { + padding: 0, + }, + '& .MuiDataGrid-colCell': { + position: 'relative', + display: 'flex', + }, + '& .MuiDataGrid-colCellSortable': { + cursor: 'pointer', + }, + '& .MuiDataGrid-sortIcon': { + fontSize: 18, + }, + '& .MuiDataGrid-colCellCenter': { + justifyContent: 'center', + }, + '& .MuiDataGrid-colCellRight': { + justifyContent: 'flex-end', + }, + '& .MuiDataGrid-colCellTitle': { + textOverflow: 'ellipsis', + overflow: 'hidden', + whiteSpace: 'nowrap', + color: theme.palette.text.primary, + fontWeight: theme.typography.fontWeightMedium, + }, + '& .MuiDataGrid-columnSeparator': { + position: 'absolute', + right: -12, + zIndex: 100, + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + }, + '& .MuiDataGrid-iconSeparator': { + color: borderColor, + }, + '& .MuiDataGrid-columnSeparator:hover .MuiDataGrid-resizable': { + cursor: 'col-resize', + color: 'inherit', + }, + '& .MuiDataGrid-colCellWrapper.scroll .MuiDataGrid-colCell:last-child': { + borderRight: 'none', + }, + '& .MuiDataGrid-dataContainer': { + position: 'relative', + flexGrow: 1, + display: 'flex', + flexDirection: 'column', + }, + '& .MuiDataGrid-window': { + position: 'absolute', + bottom: 0, + left: 0, + right: 0, + overflowX: 'auto', + }, + '& .MuiDataGrid-viewport': { + position: 'sticky', + top: 0, + left: 0, + display: 'flex', + flexDirection: 'column', + overflow: 'hidden', + }, + '& .MuiDataGrid-row': { + display: 'flex', + width: 'fit-content', + '&:hover': { + backgroundColor: theme.palette.action.hover, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, + }, + '&.Mui-selected': { + backgroundColor: fade(theme.palette.primary.main, theme.palette.action.selectedOpacity), + '&:hover': { + backgroundColor: fade( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, + ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: fade( + theme.palette.primary.main, + theme.palette.action.selectedOpacity, + ), + }, + }, + }, + }, + '& .MuiDataGrid-cell': { + display: 'block', + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + borderBottom: `1px solid ${borderColor}`, + }, + // The very last cell + '& .MuiDataGrid-colCellWrapper .MuiDataGrid-cell': { + borderBottom: 'none', + }, + '& .MuiDataGrid-cellWithRenderer': { + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + }, + '& .MuiDataGrid-withBorder': { + borderRight: `1px solid ${borderColor}`, + }, + '& .MuiDataGrid-cellRight': { + textAlign: 'right', + }, + '& .MuiDataGrid-cellCenter': { + textAlign: 'center', + }, + '& .MuiDataGrid-footer': { + display: 'flex', + justifyContent: 'space-between', + }, + '& .MuiDataGrid-rowCount, & .MuiDataGrid-selectedRowCount': { + alignItems: 'center', + ...theme.typography.body2, + display: 'none', + paddingLeft: theme.spacing(2), + [theme.breakpoints.up('md')]: { + minHeight: 52, // Match TablePagination min height + display: 'flex', + }, + }, + }, + }; + }, + { name: 'MuiDataGrid' }, +); diff --git a/packages/grid/x-grid-modules/src/components/styled-wrappers/columns-container.tsx b/packages/grid/x-grid-modules/src/components/styled-wrappers/columns-container.tsx index df4293688d0fe..3846b5d5a20cb 100644 --- a/packages/grid/x-grid-modules/src/components/styled-wrappers/columns-container.tsx +++ b/packages/grid/x-grid-modules/src/components/styled-wrappers/columns-container.tsx @@ -2,8 +2,17 @@ import * as React from 'react'; import { DivProps } from './grid-root'; import { classnames } from '../../utils'; -export const ColumnsContainer = React.forwardRef((props, ref) => { - const { className, ...other } = props; - return
; -}); +export const ColumnsContainer = React.forwardRef( + (props, ref) => { + const { className, height, style, ...other } = props; + return ( +
+ ); + }, +); ColumnsContainer.displayName = 'ColumnsContainer'; diff --git a/packages/grid/x-grid-modules/src/components/styled-wrappers/data-container.tsx b/packages/grid/x-grid-modules/src/components/styled-wrappers/data-container.tsx index a390dba409b34..ebc47c87aafbb 100644 --- a/packages/grid/x-grid-modules/src/components/styled-wrappers/data-container.tsx +++ b/packages/grid/x-grid-modules/src/components/styled-wrappers/data-container.tsx @@ -4,6 +4,8 @@ import { classnames } from '../../utils'; export const DataContainer = React.forwardRef((props, ref) => { const { className, ...other } = props; - return
; + return ( +
+ ); }); DataContainer.displayName = 'DataContainer'; diff --git a/packages/grid/x-grid-modules/src/components/styled-wrappers/footer.tsx b/packages/grid/x-grid-modules/src/components/styled-wrappers/footer.tsx index be1c7e09bbaa1..c6b6cc3b6b8a4 100644 --- a/packages/grid/x-grid-modules/src/components/styled-wrappers/footer.tsx +++ b/packages/grid/x-grid-modules/src/components/styled-wrappers/footer.tsx @@ -4,6 +4,6 @@ import { classnames } from '../../utils'; export const Footer = React.forwardRef((props, ref) => { const { className, ...other } = props; - return
; + return
; }); Footer.displayName = 'Footer'; diff --git a/packages/grid/x-grid-modules/src/components/styled-wrappers/grid-root.tsx b/packages/grid/x-grid-modules/src/components/styled-wrappers/grid-root.tsx index e1c5cf9f9a678..aa10c12f978af 100644 --- a/packages/grid/x-grid-modules/src/components/styled-wrappers/grid-root.tsx +++ b/packages/grid/x-grid-modules/src/components/styled-wrappers/grid-root.tsx @@ -1,257 +1,12 @@ import * as React from 'react'; -import styled from 'styled-components'; -import { GridOptions } from '../../models'; import { classnames } from '../../utils'; +import { useStyles } from './GridRootStyles'; export type DivProps = React.HTMLAttributes; -export interface GridRootProps { - options: GridOptions; -} +export const GridRoot = React.forwardRef(function GridRoot(props, ref) { + const { className, ...other } = props; + const classes = useStyles(); -export const RootStyle = styled.div` - box-sizing: border-box; - * { - box-sizing: border-box; - } - &.grid-root { - position: relative; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, - Cantarell, 'Helvetica Neue', sans-serif; - border: 1px solid #bdc3c7; - border-radius: 4px; - outline: none; - display: flex; - flex: 1; - flex-direction: column; - - .main-grid-container { - position: relative; - flex-grow: 1; - flex-direction: column; - display: flex; - } - .watermark { - position: absolute; - pointer-events: none; - color: #8282829e; - z-index: 100000; - width: 100%; - text-align: center; - bottom: 50%; - right: 0; - letter-spacing: 5px; - font-size: 24px; - } - .footer { - display: flex; - justify-content: space-between; - flex-direction: row; - padding: 0 16px; - } - .row-count, - .selected-row-count { - display: flex; - align-items: center; - font-size: 0.875rem; - font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif; - font-weight: 400; - line-height: 1.43; - letter-spacing: 0.01071em; - min-height: 48px; - } - @media (max-width: 650px) { - .row-count, - .selected-row-count { - display: none; - } - } - .material-cell:focus, - .material-col-cell:focus { - outline: dashed; - outline-color: black; - outline-width: 2px; - outline-offset: -3px; - } - .overlay { - top: ${(p) => p.options.headerHeight}px; - } - .columns-container { - position: absolute; - top: 0; - left: 0; - right: 0; - overflow-x: hidden; - overflow-y: hidden; - display: flex; - flex-direction: column; - border-bottom: 1px solid #bdc3c7; - z-index: 100; - - min-height: ${(p) => p.options.headerHeight}px; - max-height: ${(p) => p.options.headerHeight}px; - line-height: ${(p) => p.options.headerHeight}px; - - background-color: #f9f9f9; - color: #000000; - font-weight: 600; - font-size: 12px; - - .material-col-cell-wrapper { - display: flex; - width: 100%; - align-items: center; - - .material-col-cell { - position: relative; - display: flex; - padding: 0 16px; - border-right: ${(p) => (p.options.showColumnRightBorder ? '1px solid #bdc3c7' : 'none')}; - - &.sortable { - cursor: pointer; - } - - &.center { - justify-content: center; - } - - &.right { - justify-content: flex-end; - } - - .title { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - } - & > .icon, - .sort-icon > .icon { - min-height: ${(p) => p.options.headerHeight}px; - } - .column-separator { - position: absolute; - right: -12px; - z-index: 100; - display: flex; - flex-direction: column; - justify-content: center; - min-height: ${(p) => p.options.headerHeight}px; - opacity: ${(p) => (p.options.showColumnRightBorder ? 0 : 1)}; - - .icon.separator { - color: #bdc3c7; - } - &:hover .separator.resizable { - cursor: col-resize; - color: inherit; - } - } - * { - max-height: ${(p) => p.options.headerHeight}px; - } - &.checkbox-selection-header-cell .checkbox-input { - padding: 12px; - } - } - &.scroll .material-col-cell:last-child { - border-right: none; - } - } - } - .data-container { - position: relative; - flex-grow: 1; - display: flex; - flex-direction: column; - } - .window { - position: absolute; - top: ${(p) => p.options.headerHeight}px; - bottom: 0px; - left: 0px; - right: 0px; - overflow-y: ${(p) => (p.options.autoHeight ? 'hidden' : 'auto')}; - overflow-x: auto; - - .viewport { - position: sticky; - top: 0px; - left: 0px; - display: flex; - flex-direction: column; - overflow: hidden; - } - .material-row { - display: flex; - width: fit-content; - max-height: ${(p) => p.options.rowHeight}px; - min-height: ${(p) => p.options.rowHeight}px; - background-color: #fff; - - &.even { - background-color: #fff; - } - - &.odd { - background-color: #fcfcfc; - } - - &:hover { - cursor: pointer; - background-color: #4b99ec52; - } - &.selected { - background-color: #4a98ec; - color: #fff; - } - - .material-cell { - display: block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - padding: 0 16px; - line-height: ${(p) => p.options.rowHeight - 1}px; /* 1 = border bottom; */ - max-height: ${(p) => p.options.rowHeight}px; - min-height: ${(p) => p.options.rowHeight}px; - font-size: 12px; - border-bottom: 1px solid #bdc3c7; - - &.with-renderer { - display: flex; - flex-direction: column; - justify-content: center; - } - &.with-border { - border-right: 1px solid #bdc3c7; - } - &.right { - text-align: right; - } - &.center { - text-align: center; - } - &.checkbox-selection-cell .checkbox-input { - padding: 12px; - } - } - } - } - } -`; -RootStyle.displayName = 'RootStyle'; - -export const GridRoot = React.forwardRef((props, ref) => { - const { options, className, ...other } = props; - - return ( - - ); + return
; }); -GridRoot.displayName = 'GridRoot'; diff --git a/packages/grid/x-grid-modules/src/components/styled-wrappers/window-overlay.tsx b/packages/grid/x-grid-modules/src/components/styled-wrappers/window-overlay.tsx index d0b14f3b74200..b6d722006e787 100644 --- a/packages/grid/x-grid-modules/src/components/styled-wrappers/window-overlay.tsx +++ b/packages/grid/x-grid-modules/src/components/styled-wrappers/window-overlay.tsx @@ -1,32 +1,19 @@ import * as React from 'react'; -import styled from 'styled-components'; import { classnames } from '../../utils'; import { DivProps } from './grid-root'; - -export const Overlay = styled.div` - display: flex; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 15px; - align-self: center; - align-items: center; - z-index: 10; - - .content { - flex: 1; - display: flex; - justify-content: center; - } -`; +import { OptionsContext } from '../options-context'; export function GridOverlay(props: DivProps) { const { className, children, ...other } = props; + const options = React.useContext(OptionsContext); return ( - -
{children}
-
+
+
{children}
+
); } GridOverlay.displayName = 'GridOverlay'; diff --git a/packages/grid/x-grid-modules/src/components/styled-wrappers/window.tsx b/packages/grid/x-grid-modules/src/components/styled-wrappers/window.tsx index c86bb5ad18341..d13a9cfb9f9aa 100644 --- a/packages/grid/x-grid-modules/src/components/styled-wrappers/window.tsx +++ b/packages/grid/x-grid-modules/src/components/styled-wrappers/window.tsx @@ -1,9 +1,18 @@ import * as React from 'react'; import { DivProps } from './grid-root'; import { classnames } from '../../utils'; +import { OptionsContext } from '../options-context'; export const Window = React.forwardRef((props, ref) => { + const { headerHeight, autoHeight } = React.useContext(OptionsContext); const { className, ...other } = props; - return
; + return ( +
+ ); }); Window.displayName = 'Window'; diff --git a/packages/grid/x-grid-modules/src/components/viewport.tsx b/packages/grid/x-grid-modules/src/components/viewport.tsx index 6812460c11542..23d9ad1b151ab 100644 --- a/packages/grid/x-grid-modules/src/components/viewport.tsx +++ b/packages/grid/x-grid-modules/src/components/viewport.tsx @@ -27,7 +27,7 @@ export const Viewport: ViewportType = React.forwardRef ( = ({ licenseStatus }) => { return null; } - return
{getLicenseErrorMessage(licenseStatus)}
; + return ( +
+ {' '} + {getLicenseErrorMessage(licenseStatus)}{' '} +
+ ); }; diff --git a/packages/grid/x-grid-modules/src/constants/cssClassesConstants.ts b/packages/grid/x-grid-modules/src/constants/cssClassesConstants.ts index 15cb9162cff4e..c5012161cdcda 100644 --- a/packages/grid/x-grid-modules/src/constants/cssClassesConstants.ts +++ b/packages/grid/x-grid-modules/src/constants/cssClassesConstants.ts @@ -1,6 +1,5 @@ // CSS_CLASSES_CONSTANTS -export const CELL_CSS_CLASS = 'material-cell'; -export const ROW_CSS_CLASS = 'material-row'; -export const HEADER_CELL_CSS_CLASS = 'material-col-cell'; -export const ROOT_CSS_CLASS = 'grid-root'; +export const CELL_CSS_CLASS = 'MuiDataGrid-cell'; +export const ROW_CSS_CLASS = 'MuiDataGrid-row'; +export const HEADER_CELL_CSS_CLASS = 'MuiDataGrid-colCell'; export const DATA_CONTAINER_CSS_CLASS = 'data-container'; diff --git a/packages/grid/x-grid-modules/src/hooks/features/useComponents.tsx b/packages/grid/x-grid-modules/src/hooks/features/useComponents.tsx index d992ebf2f50d0..62266c85a97e5 100644 --- a/packages/grid/x-grid-modules/src/hooks/features/useComponents.tsx +++ b/packages/grid/x-grid-modules/src/hooks/features/useComponents.tsx @@ -9,8 +9,9 @@ import { InternalColumns, Rows, } from '../../models'; -import { LoadingOverlay, NoRowMessage } from '../../components'; import { ErrorMessage } from '../../components/error-message'; +import { LoadingOverlay } from '../../components/loading-overlay'; +import { NoRowMessage } from '../../components/no-row-message'; export const useComponents = ( columns: InternalColumns, diff --git a/packages/grid/x-grid-modules/src/hooks/root/useEvents.ts b/packages/grid/x-grid-modules/src/hooks/root/useEvents.ts index 8fec4a71fce53..07ad3a757e3bf 100644 --- a/packages/grid/x-grid-modules/src/hooks/root/useEvents.ts +++ b/packages/grid/x-grid-modules/src/hooks/root/useEvents.ts @@ -66,6 +66,9 @@ export function useEvents( if (isCell(elem)) { const cellEl = findParentElementFromClassName(elem, CELL_CSS_CLASS)! as HTMLElement; const rowEl = findParentElementFromClassName(elem, ROW_CSS_CLASS)! as HTMLElement; + if (rowEl == null) { + return null; + } const id = getIdFromRowElem(rowEl); const rowModel = apiRef.current.getRowFromId(id); const rowIndex = apiRef.current.getRowIndexFromId(id); diff --git a/packages/grid/x-grid-modules/src/index.ts b/packages/grid/x-grid-modules/src/index.ts index d887c60492594..ef348dc7f82bb 100644 --- a/packages/grid/x-grid-modules/src/index.ts +++ b/packages/grid/x-grid-modules/src/index.ts @@ -6,4 +6,4 @@ export * from './utils'; export * from './GridComponentProps'; export * from './GridComponent'; -export { useOptionsProp } from '@material-ui/x-grid-modules/hooks/utils/useOptionsProp'; +export * from './hooks/utils/useOptionsProp'; diff --git a/packages/grid/x-grid-modules/src/models/colDef/checkboxSelection.tsx b/packages/grid/x-grid-modules/src/models/colDef/checkboxSelection.tsx index 45eaf7f92a93f..c0ba3cac8b200 100644 --- a/packages/grid/x-grid-modules/src/models/colDef/checkboxSelection.tsx +++ b/packages/grid/x-grid-modules/src/models/colDef/checkboxSelection.tsx @@ -6,7 +6,7 @@ export const checkboxSelectionColDef: ColDef = { field: '__check__', description: 'Select Multiple Rows', type: 'checkboxSelection', - width: 80, + width: 48, align: 'center', headerAlign: 'center', resizable: true, @@ -15,6 +15,6 @@ export const checkboxSelectionColDef: ColDef = { valueGetter: (params) => params.rowModel.selected, renderHeader: (params) => , renderCell: (params) => , - cellClassName: 'checkbox-selection-cell', - headerClassName: 'checkbox-selection-header-cell', + cellClassName: 'MuiDataGrid-cellCheckbox', + headerClassName: 'MuiDataGrid-colCellCheckbox', }; diff --git a/packages/grid/x-grid-modules/src/utils/domUtils.ts b/packages/grid/x-grid-modules/src/utils/domUtils.ts index d178e8e28ef8b..d8919b37b81fc 100644 --- a/packages/grid/x-grid-modules/src/utils/domUtils.ts +++ b/packages/grid/x-grid-modules/src/utils/domUtils.ts @@ -2,7 +2,6 @@ import { CELL_CSS_CLASS, DATA_CONTAINER_CSS_CLASS, HEADER_CELL_CSS_CLASS, - ROOT_CSS_CLASS, } from '../constants/cssClassesConstants'; import { CellIndexCoordinates } from '../models/rows'; @@ -37,7 +36,7 @@ export function getFieldFromHeaderElem(colCellEl: Element): string { } export function findCellElementsFromCol(col: HTMLElement): NodeListOf | null { const field = getDataFromElem(col, 'field'); - const root = findParentElementFromClassName(col, ROOT_CSS_CLASS); + const root = findParentElementFromClassName(col, 'MuiDataGrid-root'); if (!root) { throw new Error('Material-UI: The root element is not found.'); } @@ -46,10 +45,10 @@ export function findCellElementsFromCol(col: HTMLElement): NodeListOf | } export function findGridRootFromCurrent(elem: Element): HTMLDivElement | null { - if (elem.classList.contains(ROOT_CSS_CLASS)) { + if (elem.classList.contains('MuiDataGrid-root')) { return elem as HTMLDivElement; } - const root = findParentElementFromClassName(elem, ROOT_CSS_CLASS); + const root = findParentElementFromClassName(elem, 'MuiDataGrid-root'); return root as HTMLDivElement; } diff --git a/packages/grid/x-grid/package.json b/packages/grid/x-grid/package.json index ddb191a939209..36dc567b091ca 100644 --- a/packages/grid/x-grid/package.json +++ b/packages/grid/x-grid/package.json @@ -32,8 +32,7 @@ }, "peerDependencies": { "@material-ui/core": "^4.9.12", - "react": "^16.8.0", - "styled-components": "^5.1.0" + "react": "^16.8.0" }, "scripts": { "precommit": "npm run lint", diff --git a/packages/grid/x-grid/src/XGrid.test.tsx b/packages/grid/x-grid/src/XGrid.test.tsx index 32f6eb9820353..15b4b6a3f93dd 100644 --- a/packages/grid/x-grid/src/XGrid.test.tsx +++ b/packages/grid/x-grid/src/XGrid.test.tsx @@ -201,15 +201,15 @@ describe('', () => { const row = document.querySelector('[role="row"][aria-rowindex="2"]'); const checkbox = row!.querySelector('input'); - expect(row).to.not.have.class('selected'); + expect(row).to.not.have.class('Mui-selected'); expect(checkbox).to.have.property('checked', false); fireEvent.click(screen.getByRole('cell', { name: 'Nike' })); - expect(row).to.have.class('selected'); + expect(row).to.have.class('Mui-selected'); expect(checkbox).to.have.property('checked', true); fireEvent.click(screen.getByRole('cell', { name: 'Nike' })); - expect(row).to.not.have.class('selected'); + expect(row).to.not.have.class('Mui-selected'); expect(checkbox).to.have.property('checked', false); }); }); diff --git a/packages/storybook/.storybook/main.js b/packages/storybook/.storybook/main.js index 07b37aa61a013..9b2ae97376fbc 100644 --- a/packages/storybook/.storybook/main.js +++ b/packages/storybook/.storybook/main.js @@ -33,7 +33,6 @@ module.exports = { } ], }); - if (__DEV__) { config.module.rules.push({ test: /\.(js|ts|tsx)$/, diff --git a/packages/storybook/integration/staticStories.test.ts b/packages/storybook/integration/staticStories.test.ts index 7f03695711419..a80bd1eafb518 100644 --- a/packages/storybook/integration/staticStories.test.ts +++ b/packages/storybook/integration/staticStories.test.ts @@ -28,7 +28,7 @@ const stories = [ path: '/story/x-grid-tests-selection--multiple-select-with-checkbox-no-click', beforeTest: async (page) => { await page.click( - '.grid-root .window .material-row:first-child .material-cell.checkbox-selection-cell .checkbox-input', + '.grid-root .window .material-row:first-child .material-cell.MuiDataGrid-cellCheckbox .checkbox-input', ); }, },