From fda3d362896450d48692a5e2c66309916a53a245 Mon Sep 17 00:00:00 2001 From: Andrey Churkin Date: Thu, 30 May 2019 10:42:14 +0300 Subject: [PATCH] fix(react-grid): Fixed column cell of selected row is not highlighted (#2042) * fix(react-grid): Fixed column cell of selected row is not highlighted * add tests * add test --- .../src/templates/table-fixed-cell.jsx | 21 +++++----- .../src/templates/table-fixed-cell.test.jsx | 11 +++++ .../src/templates/table-fixed-cell.jsx | 25 +++++++----- .../src/templates/table-fixed-cell.test.jsx | 10 +++++ .../src/templates/table-select-row.jsx | 12 ++++-- .../src/templates/table-select-row.test.jsx | 9 +++++ .../src/templates/table-fixed-cell.jsx | 37 ++++++++++------- .../src/templates/table-fixed-cell.test.jsx | 10 +++++ .../src/templates/table-select-row.jsx | 40 ++++++++++++++----- .../src/templates/table-select-row.test.jsx | 11 +++-- .../src/utils/get-selection-color.jsx | 7 ++++ .../src/plugins/table-fixed-columns.tsx | 5 ++- .../table-fixed-columns.types.ts | 2 + packages/dx-styles/dx-grid-bs4.scss | 3 ++ 14 files changed, 150 insertions(+), 53 deletions(-) create mode 100644 packages/dx-react-grid-material-ui/src/utils/get-selection-color.jsx diff --git a/packages/dx-react-grid-bootstrap3/src/templates/table-fixed-cell.jsx b/packages/dx-react-grid-bootstrap3/src/templates/table-fixed-cell.jsx index 30ec330aa3..42553201a8 100644 --- a/packages/dx-react-grid-bootstrap3/src/templates/table-fixed-cell.jsx +++ b/packages/dx-react-grid-bootstrap3/src/templates/table-fixed-cell.jsx @@ -19,11 +19,12 @@ export class FixedCell extends React.PureComponent { render() { const { component: CellPlaceholder, - side, + position, + selected, showLeftDivider, showRightDivider, + side, style, - position, ...restProps } = this.props; const { backgroundColor, borderColor } = this.context; @@ -32,16 +33,16 @@ export class FixedCell extends React.PureComponent { return ( @@ -52,17 +53,19 @@ export class FixedCell extends React.PureComponent { FixedCell.contextType = ThemeColors; FixedCell.propTypes = { - style: PropTypes.object, component: PropTypes.func.isRequired, - side: PropTypes.string.isRequired, position: PropTypes.number, + selected: PropTypes.bool, showLeftDivider: PropTypes.bool, showRightDivider: PropTypes.bool, + side: PropTypes.string.isRequired, + style: PropTypes.object, }; FixedCell.defaultProps = { - style: null, + position: undefined, + selected: false, showLeftDivider: false, showRightDivider: false, - position: undefined, + style: null, }; diff --git a/packages/dx-react-grid-bootstrap3/src/templates/table-fixed-cell.test.jsx b/packages/dx-react-grid-bootstrap3/src/templates/table-fixed-cell.test.jsx index 2ba4cd1d4f..65b3c4251e 100644 --- a/packages/dx-react-grid-bootstrap3/src/templates/table-fixed-cell.test.jsx +++ b/packages/dx-react-grid-bootstrap3/src/templates/table-fixed-cell.test.jsx @@ -83,6 +83,17 @@ describe('FixedCell', () => { }); }); + it('should not apply background color for selected cells', () => { + const tree = mount(( + + + + )); + + expect(tree.childAt(0).prop('style').backgroundColor) + .toBeFalsy(); + }); + it('should pass rest props to the root element', () => { const tree = shallow(( diff --git a/packages/dx-react-grid-bootstrap4/src/templates/table-fixed-cell.jsx b/packages/dx-react-grid-bootstrap4/src/templates/table-fixed-cell.jsx index 14e42c91ff..b71743f0e5 100644 --- a/packages/dx-react-grid-bootstrap4/src/templates/table-fixed-cell.jsx +++ b/packages/dx-react-grid-bootstrap4/src/templates/table-fixed-cell.jsx @@ -6,29 +6,30 @@ import { BodyColorContext } from './layout'; export class FixedCell extends React.PureComponent { render() { const { + className, component: CellPlaceholder, - side, + position, + selected, showLeftDivider, showRightDivider, - className, + side, style, - position, ...restProps } = this.props; - const backgroundColor = this.context; + const backgroundColor = selected ? 'inherit' : this.context; return ( @@ -40,18 +41,20 @@ FixedCell.contextType = BodyColorContext; FixedCell.propTypes = { className: PropTypes.string, - style: PropTypes.object, component: PropTypes.func.isRequired, - side: PropTypes.string.isRequired, position: PropTypes.number, + selected: PropTypes.bool, showLeftDivider: PropTypes.bool, showRightDivider: PropTypes.bool, + side: PropTypes.string.isRequired, + style: PropTypes.object, }; FixedCell.defaultProps = { className: undefined, - style: null, + position: undefined, + selected: false, showLeftDivider: false, showRightDivider: false, - position: undefined, + style: null, }; diff --git a/packages/dx-react-grid-bootstrap4/src/templates/table-fixed-cell.test.jsx b/packages/dx-react-grid-bootstrap4/src/templates/table-fixed-cell.test.jsx index 6924c25d96..8433930503 100644 --- a/packages/dx-react-grid-bootstrap4/src/templates/table-fixed-cell.test.jsx +++ b/packages/dx-react-grid-bootstrap4/src/templates/table-fixed-cell.test.jsx @@ -19,6 +19,16 @@ describe('FixedCell', () => { .toBeTruthy(); }); + it('should apply inherit background color for selected cells', () => { + const tree = shallow(( + + )); + + expect(tree.prop('style')).toMatchObject({ + backgroundColor: 'inherit', + }); + }); + it('should apply left border if left divider exists', () => { const tree = shallow(( diff --git a/packages/dx-react-grid-bootstrap4/src/templates/table-select-row.jsx b/packages/dx-react-grid-bootstrap4/src/templates/table-select-row.jsx index 02b4c42a02..ec07dd62a7 100644 --- a/packages/dx-react-grid-bootstrap4/src/templates/table-select-row.jsx +++ b/packages/dx-react-grid-bootstrap4/src/templates/table-select-row.jsx @@ -1,5 +1,6 @@ import * as React from 'react'; import * as PropTypes from 'prop-types'; +import classNames from 'classnames'; export const TableSelectRow = ({ selected, @@ -7,10 +8,13 @@ export const TableSelectRow = ({ style, onToggle, selectByRowClick, + className, }) => ( { if (!selectByRowClick) return; e.stopPropagation(); @@ -22,17 +26,19 @@ export const TableSelectRow = ({ ); TableSelectRow.propTypes = { - selected: PropTypes.bool, children: PropTypes.node, + className: PropTypes.string, onToggle: PropTypes.func, selectByRowClick: PropTypes.bool, + selected: PropTypes.bool, style: PropTypes.object, }; TableSelectRow.defaultProps = { children: null, + className: undefined, onToggle: () => {}, - selected: false, selectByRowClick: false, + selected: false, style: null, }; diff --git a/packages/dx-react-grid-bootstrap4/src/templates/table-select-row.test.jsx b/packages/dx-react-grid-bootstrap4/src/templates/table-select-row.test.jsx index eb0165a612..d9911dd2f0 100644 --- a/packages/dx-react-grid-bootstrap4/src/templates/table-select-row.test.jsx +++ b/packages/dx-react-grid-bootstrap4/src/templates/table-select-row.test.jsx @@ -30,6 +30,15 @@ describe('Table Select Row', () => { expect(tree.find('tr').hasClass('table-active')).toBeTruthy(); }); + it('should pass className to the root element', () => { + const tree = shallow(( + + )); + + expect(tree.is('.custom-class')) + .toBeTruthy(); + }); + it('should handle row click', () => { const onToggleMock = jest.fn(); const event = { stopPropagation: jest.fn() }; diff --git a/packages/dx-react-grid-material-ui/src/templates/table-fixed-cell.jsx b/packages/dx-react-grid-material-ui/src/templates/table-fixed-cell.jsx index 9aa1b30978..1ec075c3b5 100644 --- a/packages/dx-react-grid-material-ui/src/templates/table-fixed-cell.jsx +++ b/packages/dx-react-grid-material-ui/src/templates/table-fixed-cell.jsx @@ -4,40 +4,45 @@ import classNames from 'classnames'; import { withStyles } from '@material-ui/core/styles'; const styles = theme => ({ + dividerRight: { + borderRight: `1px solid ${theme.palette.divider}`, + }, + dividerLeft: { + borderLeft: `1px solid ${theme.palette.divider}`, + }, fixedCell: { backgroundColor: theme.palette.background.paper, position: 'sticky', zIndex: 300, backgroundClip: 'padding-box', }, - dividerRight: { - borderRight: `1px solid ${theme.palette.divider}`, - }, - dividerLeft: { - borderLeft: `1px solid ${theme.palette.divider}`, + selected: { + backgroundColor: 'inherit', }, }); class FixedCellBase extends React.PureComponent { render() { const { + className, + classes, component: CellPlaceholder, - side, + position, + selected, showLeftDivider, showRightDivider, - className, - classes, + side, style, - position, ...restProps } = this.props; return ( { classes = getClasses(); }); + it('should apply selected styles for selected cell', () => { + const tree = shallow(( + + )); + + expect(tree.is(`.${classes.selected}`)) + .toBeTruthy(); + }); + + it('should apply left border if left divider exists', () => { const tree = shallow(( diff --git a/packages/dx-react-grid-material-ui/src/templates/table-select-row.jsx b/packages/dx-react-grid-material-ui/src/templates/table-select-row.jsx index 45130d1f8c..935348ec4c 100644 --- a/packages/dx-react-grid-material-ui/src/templates/table-select-row.jsx +++ b/packages/dx-react-grid-material-ui/src/templates/table-select-row.jsx @@ -1,15 +1,30 @@ import * as React from 'react'; import * as PropTypes from 'prop-types'; +import classNames from 'classnames'; import TableRow from '@material-ui/core/TableRow'; +import { withStyles } from '@material-ui/core/styles'; +import getSelectionColor from '../utils/get-selection-color'; -export const TableSelectRow = ({ - selected, selectByRowClick, onToggle, - row, tableRow, tableColumn, +const styles = theme => ({ + selected: { + backgroundColor: getSelectionColor(theme), + }, +}); + +const TableSelectRowBase = ({ children, + classes, + className, + onToggle, + row, + selectByRowClick, + selected, + tableColumn, + tableRow, ...restProps }) => ( { if (!selectByRowClick) return; e.stopPropagation(); @@ -21,22 +36,27 @@ export const TableSelectRow = ({ ); -TableSelectRow.propTypes = { +TableSelectRowBase.propTypes = { children: PropTypes.node, + className: PropTypes.string, + classes: PropTypes.object.isRequired, onToggle: PropTypes.func, - selected: PropTypes.bool, - selectByRowClick: PropTypes.bool, row: PropTypes.any, + selectByRowClick: PropTypes.bool, + selected: PropTypes.bool, tableColumn: PropTypes.object, tableRow: PropTypes.object, }; -TableSelectRow.defaultProps = { +TableSelectRowBase.defaultProps = { children: undefined, + className: undefined, onToggle: () => {}, - selected: false, - selectByRowClick: false, row: undefined, + selectByRowClick: false, + selected: false, tableColumn: undefined, tableRow: undefined, }; + +export const TableSelectRow = withStyles(styles, { name: 'TableSelectRow' })(TableSelectRowBase); diff --git a/packages/dx-react-grid-material-ui/src/templates/table-select-row.test.jsx b/packages/dx-react-grid-material-ui/src/templates/table-select-row.test.jsx index ffb5df73a1..9fe65fbfaf 100644 --- a/packages/dx-react-grid-material-ui/src/templates/table-select-row.test.jsx +++ b/packages/dx-react-grid-material-ui/src/templates/table-select-row.test.jsx @@ -1,6 +1,6 @@ import * as React from 'react'; import TableRowMUI from '@material-ui/core/TableRow'; -import { createShallow } from '@material-ui/core/test-utils'; +import { createShallow, getClasses } from '@material-ui/core/test-utils'; import { TableSelectRow } from './table-select-row'; const defaultProps = { @@ -11,9 +11,11 @@ const defaultProps = { describe('TableSelectRow', () => { let shallow; + let classes; beforeAll(() => { - shallow = createShallow({ }); + shallow = createShallow({ dive: true }); + classes = getClasses(); }); it('should have correct selected prop', () => { @@ -23,7 +25,7 @@ describe('TableSelectRow', () => { /> )); - expect(tree.find(TableRowMUI).prop('selected')) + expect(tree.is(`.${classes.selected}`)) .toBeFalsy(); tree = shallow(( @@ -32,7 +34,8 @@ describe('TableSelectRow', () => { selected /> )); - expect(tree.find(TableRowMUI).prop('selected')) + + expect(tree.is(`.${classes.selected}`)) .toBeTruthy(); }); diff --git a/packages/dx-react-grid-material-ui/src/utils/get-selection-color.jsx b/packages/dx-react-grid-material-ui/src/utils/get-selection-color.jsx new file mode 100644 index 0000000000..dce6e56d9a --- /dev/null +++ b/packages/dx-react-grid-material-ui/src/utils/get-selection-color.jsx @@ -0,0 +1,7 @@ +import { darken, fade, lighten } from '@material-ui/core/styles/colorManipulator'; + +export default theme => ( + theme.palette.type === 'light' + ? lighten(fade(theme.palette.action.selected, 1), 0.96) + : darken(fade(theme.palette.action.selected, 1), 0.68) +); diff --git a/packages/dx-react-grid/src/plugins/table-fixed-columns.tsx b/packages/dx-react-grid/src/plugins/table-fixed-columns.tsx index 7a36a039ce..14e450dad6 100644 --- a/packages/dx-react-grid/src/plugins/table-fixed-columns.tsx +++ b/packages/dx-react-grid/src/plugins/table-fixed-columns.tsx @@ -98,7 +98,9 @@ class TableFixedColumnsBase extends React.PureComponent {(params: TableCellProps) => ( - {({ tableColumns, tableHeaderColumnChains }) => { + {({ tableColumns, tableHeaderColumnChains, selection }) => { + const selected: boolean = selection && + selection.indexOf(params.tableRow.rowId) !== -1; const { tableColumnDimensions } = this.state; const fixedColumnProps = calculateFixedColumnProps( params, @@ -113,6 +115,7 @@ class TableFixedColumnsBase extends React.PureComponent ); }} diff --git a/packages/dx-react-grid/src/types/column-operations/table-fixed-columns.types.ts b/packages/dx-react-grid/src/types/column-operations/table-fixed-columns.types.ts index f786b5cf00..5f515a5b3f 100644 --- a/packages/dx-react-grid/src/types/column-operations/table-fixed-columns.types.ts +++ b/packages/dx-react-grid/src/types/column-operations/table-fixed-columns.types.ts @@ -14,6 +14,8 @@ export namespace TableFixedColumns { showRightDivider: boolean; /** Specifies the fixed cell's position. */ position: number; + /** @internal */ + selected: boolean; } } diff --git a/packages/dx-styles/dx-grid-bs4.scss b/packages/dx-styles/dx-grid-bs4.scss index ef2bf6015b..5ca0551a6a 100644 --- a/packages/dx-styles/dx-grid-bs4.scss +++ b/packages/dx-styles/dx-grid-bs4.scss @@ -207,6 +207,9 @@ button.dx-g-bs4-table-edit-command-cell { height: 16px; fill: currentColor; } +.table-active, .table-active>td, .table-active>th { + background-color: #f5f5f5; +} .dx-g-bs4-fixed-cell { z-index: 300; background-clip: padding-box;