Skip to content

Commit

Permalink
[DataGrid] Replace style-components with @material-ui/styles (#168)
Browse files Browse the repository at this point in the history
* remove style-components

* fix rollup build

* fix import

* convert styles to jss

* fix style

* more cleanup

* prettier

* lint

* fix font styles and fix hover header error

* remove some specificity on css

* fix prettier

* Update packages/grid/x-grid-modules/src/components/styled-wrappers/getStyles.ts

Co-authored-by: Olivier Tassinari <[email protected]>

* cleanup styling

* fix dependency no cycle

* prettier

* small cleanup

* prettier

* refactor styles and selector

* fix test

* fix DataGrid resizing

* replace class name that doesn't exist

* remove all double spaces

* generate a global class names

* remove dead code

* all in with MuiDataGrid for the CSS

* polish CSS

* start to reproduce https://material-ui.com/components/tables/\#simple-table

But I won't have time to push it further today. For tomorrow 😴

* Material Design spec

* improve footer display

Co-authored-by: Olivier Tassinari <[email protected]>
  • Loading branch information
dtassone and oliviertassinari authored Sep 10, 2020
1 parent 8651b35 commit 13b4a58
Show file tree
Hide file tree
Showing 36 changed files with 384 additions and 366 deletions.
3 changes: 1 addition & 2 deletions packages/grid/data-grid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
"<rootDir>/src/setupTests.js"
Expand Down
2 changes: 1 addition & 1 deletion packages/grid/data-grid/src/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const DataGrid2 = React.forwardRef<HTMLDivElement, DataGridProps>(function DataG
return (
<GridComponent
ref={ref}
className={classnames('data-grid', className)}
className={classnames('MuiDataGrid-root', className)}
pageSize={pageSize}
{...other}
{...FORCED_PROPS}
Expand Down
3 changes: 1 addition & 2 deletions packages/grid/x-grid-modules/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,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",
Expand Down
20 changes: 10 additions & 10 deletions packages/grid/x-grid-modules/src/GridComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {
} from './hooks/features';
import { DEFAULT_GRID_OPTIONS, ElementSize, RootContainerRef } from './models';
import { COMPONENT_ERROR, DATA_CONTAINER_CSS_CLASS } from './constants';
import { ColumnsContainer, DataContainer, GridRoot } from './components/styled-wrappers';
import { GridRoot } from './components/styled-wrappers/grid-root';
import { DataContainer } from './components/styled-wrappers/data-container';
import { ColumnsContainer } from './components/styled-wrappers/columns-container';
import { useVirtualRows } from './hooks/virtualization';
import {
ApiContext,
Expand Down Expand Up @@ -71,9 +73,7 @@ export const GridComponent = React.forwardRef<HTMLDivElement, GridComponentProps
// We are handling error here, to set up the handler as early as possible and be able to catch error thrown at init time.
setErrorState(args);
};
React.useEffect(() => {
return apiRef!.current.subscribeEvent(COMPONENT_ERROR, errorHandler);
}, [apiRef]);
React.useEffect(() => apiRef!.current.subscribeEvent(COMPONENT_ERROR, errorHandler), [apiRef]);

React.useEffect(() => {
apiRef!.current.showError(props.error);
Expand Down Expand Up @@ -166,8 +166,7 @@ export const GridComponent = React.forwardRef<HTMLDivElement, GridComponentProps
{(size: any) => (
<GridRoot
ref={handleRef}
className={`material-grid MuiGrid ${props.className || ''}`}
options={internalOptions}
className={props.className}
style={{ width: size.width, height: getTotalHeight(size) }}
role="grid"
aria-colcount={internalColumns.visible.length}
Expand All @@ -182,20 +181,21 @@ export const GridComponent = React.forwardRef<HTMLDivElement, GridComponentProps
api={apiRef!}
logger={gridLogger}
render={(errorProps) => (
<div className="main-grid-container">{customComponents.renderError(errorProps)}</div>
<div className="MuiDataGrid-mainGridContainer">
{customComponents.renderError(errorProps)}
</div>
)}
>
<ApiContext.Provider value={apiRef}>
<OptionsContext.Provider value={internalOptions}>
{customComponents.headerComponent}
<div className="main-grid-container">
<div className="MuiDataGrid-mainGridContainer">
<Watermark licenseStatus={props.licenseStatus} />
<ColumnsContainer ref={columnsContainerRef}>
<ColumnsContainer ref={columnsContainerRef} height={internalOptions.headerHeight}>
<ColumnsHeader
ref={columnsHeaderRef}
columns={internalColumns.visible || []}
hasScrollX={!!renderCtx?.hasScrollX}
headerHeight={internalOptions.headerHeight}
onResizeColumn={onResizeColumn}
renderCtx={renderCtx}
/>
Expand Down
19 changes: 16 additions & 3 deletions packages/grid/x-grid-modules/src/components/cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -16,6 +17,11 @@ export interface GridCellProps {
rowIndex?: number;
}

const alignPropToCssClass = {
center: 'MuiDataGrid-cellCenter',
right: 'MuiDataGrid-cellRight',
};

export const Cell: React.FC<GridCellProps> = React.memo(
({
value,
Expand All @@ -33,10 +39,11 @@ export const Cell: React.FC<GridCellProps> = 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 (
<div
Expand All @@ -47,7 +54,13 @@ export const Cell: React.FC<GridCellProps> = 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()}
Expand Down
20 changes: 9 additions & 11 deletions packages/grid/x-grid-modules/src/components/checkbox-renderer.tsx
Original file line number Diff line number Diff line change
@@ -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<ColParams> = React.memo(({ api }) => {
const [isChecked, setChecked] = React.useState(false);
const [isIndeterminate, setIndeterminate] = React.useState(false);
Expand All @@ -31,16 +26,18 @@ export const HeaderCheckbox: React.FC<ColParams> = React.memo(({ api }) => {
React.useEffect(() => {
return api.onSelectionChange(selectionChange);
}, [api, selectionChange]);

return (
<CheckboxInputContainer>
<div>
<Checkbox
indeterminate={isIndeterminate}
checked={isChecked}
onChange={handleChange}
className="checkbox-input"
className="MuiDataGrid-checkboxInput"
color="primary"
inputProps={{ 'aria-label': 'Select All Rows checkbox' }}
/>
</CheckboxInputContainer>
</div>
);
});
HeaderCheckbox.displayName = 'HeaderCheckbox';
Expand All @@ -51,14 +48,15 @@ export const CellCheckboxRenderer: React.FC<CellParams> = React.memo(({ api, row
};

return (
<CheckboxInputContainer>
<div>
<Checkbox
checked={!!value}
onChange={handleChange}
className="checkbox-input"
className="MuiDataGrid-checkboxInput"
color="primary"
inputProps={{ 'aria-label': 'Select Row checkbox' }}
/>
</CheckboxInputContainer>
</div>
);
});
CellCheckboxRenderer.displayName = 'CellCheckboxRenderer';
21 changes: 14 additions & 7 deletions packages/grid/x-grid-modules/src/components/column-header-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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!;

Expand Down Expand Up @@ -82,7 +89,7 @@ export const ColumnHeaderItem = React.memo(
hide={column.hideSortIcons}
/>
)}
<ColumnHeaderSeparator resizable={column.resizable} onResize={onResize} />
<ColumnHeaderSeparator resizable={column.resizable} onResize={handleResize} />
</div>
);
},
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -9,15 +10,23 @@ export interface ColumnHeaderSeparatorProps {
export const ColumnHeaderSeparator: React.FC<ColumnHeaderSeparatorProps> = 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 <div className="column-separator">{icon}</div>;
return (
<div
className="MuiDataGrid-columnSeparator"
style={{ minHeight: headerHeight, opacity: showColumnRightBorder ? 0 : 1 }}
>
{icon}
</div>
);
},
);
ColumnHeaderSeparator.displayName = 'ColumnHeaderSeparator';
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Icon className="MuiDataGrid-sortIcon" />;
}

export const ColumnHeaderSortIcon: React.FC<ColumnHeaderSortIconProps> = React.memo(
({ direction, index, hide }) => {
Expand All @@ -24,7 +24,7 @@ export const ColumnHeaderSortIcon: React.FC<ColumnHeaderSortIconProps> = React.m
}

return (
<span className="sort-icon">
<span>
{index != null && (
<Badge badgeContent={index} color="default">
<IconButton aria-label="Sort" size="small">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const ColumnHeaderInnerTitle = React.forwardRef<
return (
<div
ref={ref}
className={classnames('title', className)}
className={classnames('MuiDataGrid-colCellTitle', className)}
aria-label={String(other.children)}
{...other}
/>
Expand Down
15 changes: 4 additions & 11 deletions packages/grid/x-grid-modules/src/components/column-headers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<ColumnHeadersItemCollectionProps> = React.memo(
({ headerHeight, onResizeColumn, columns }) => {
({ onResizeColumn, columns }) => {
const items = columns.map((col, idx) => (
<ColumnHeaderItem
key={col.field}
column={col}
colIndex={idx}
headerHeight={headerHeight}
onResizeColumn={onResizeColumn}
/>
));
Expand All @@ -29,15 +27,14 @@ ColumnHeaderItemCollection.displayName = 'ColumnHeaderItemCollection';
export interface ColumnsHeaderProps {
columns: Columns;
hasScrollX: boolean;
headerHeight: number;
onResizeColumn?: (col: ColDef) => void;
renderCtx: Partial<RenderContextProps> | null;
}

export const ColumnsHeader = React.memo(
React.forwardRef<HTMLDivElement, ColumnsHeaderProps>(
({ 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) {
Expand Down Expand Up @@ -75,11 +72,7 @@ export const ColumnsHeader = React.memo(
style={{ minWidth: renderCtx?.totalSizes?.width }}
>
<LeftEmptyCell key="left-empty" width={renderCtx?.leftEmptyWidth} />
<ColumnHeaderItemCollection
columns={renderedCols}
onResizeColumn={onResizeColumn}
headerHeight={headerHeight}
/>
<ColumnHeaderItemCollection columns={renderedCols} onResizeColumn={onResizeColumn} />
<RightEmptyCell key="right-empty" width={renderCtx?.rightEmptyWidth} />
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -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<GridOptions | undefined>(undefined);
export const OptionsContext = React.createContext<GridOptions>(DEFAULT_GRID_OPTIONS);
2 changes: 1 addition & 1 deletion packages/grid/x-grid-modules/src/components/row-cells.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export const RowCells: React.FC<RowCellsProps> = 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 } = {
Expand Down
2 changes: 1 addition & 1 deletion packages/grid/x-grid-modules/src/components/row-count.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export const RowCount: React.FC<{ rowCount: number }> = ({ rowCount }) => {
if (rowCount === 0) {
return null;
}
return <div className="row-count">Total Rows: {rowCount.toLocaleString()}</div>;
return <div className="MuiDataGrid-rowCount">Total Rows: {rowCount.toLocaleString()}</div>;
};
Loading

0 comments on commit 13b4a58

Please sign in to comment.