From 1c07b6cbd39f036765eaed2ac45749d645517d25 Mon Sep 17 00:00:00 2001 From: Allen Date: Tue, 22 Aug 2017 10:35:13 -0500 Subject: [PATCH] Implement custom style/class on cell (#20) fix #19 --- packages/react-bootstrap-table2/src/cell.js | 27 ++++- packages/react-bootstrap-table2/src/row.js | 3 +- packages/react-bootstrap-table2/src/utils.js | 7 +- .../react-bootstrap-table2/test/cell.test.js | 114 +++++++++++++++++- 4 files changed, 138 insertions(+), 13 deletions(-) diff --git a/packages/react-bootstrap-table2/src/cell.js b/packages/react-bootstrap-table2/src/cell.js index ef70d54..a585d20 100644 --- a/packages/react-bootstrap-table2/src/cell.js +++ b/packages/react-bootstrap-table2/src/cell.js @@ -3,20 +3,35 @@ import PropTypes from 'prop-types'; import _ from './utils'; -const Cell = ({ row, rowIndex, column }) => { - let content = _.get(row, column.dataField); - if (column.formatter) { - content = column.formatter(content, row, rowIndex, column.formatExtraData); +const Cell = ({ row, rowIndex, column, columnIndex }) => { + const { + dataField, + formatter, + formatExtraData, + style, + classes + } = column; + let content = _.get(row, dataField); + const cellStyle = _.isFunction(style) ? style(content, row, columnIndex) : style; + const cellClasses = _.isFunction(classes) ? classes(content, row, columnIndex) : classes; + if (formatter) { + content = column.formatter(content, row, rowIndex, formatExtraData); } + + const attrs = { + style: cellStyle, + className: cellClasses + }; return ( - { content } + { content } ); }; Cell.propTypes = { row: PropTypes.object.isRequired, rowIndex: PropTypes.number.isRequired, - column: PropTypes.object.isRequired + column: PropTypes.object.isRequired, + columnIndex: PropTypes.number.isRequired }; export default Cell; diff --git a/packages/react-bootstrap-table2/src/row.js b/packages/react-bootstrap-table2/src/row.js index fdaad04..842127c 100644 --- a/packages/react-bootstrap-table2/src/row.js +++ b/packages/react-bootstrap-table2/src/row.js @@ -7,12 +7,13 @@ import Cell from './cell'; const Row = ({ row, rowIndex, columns }) => ( { - columns.map(column => + columns.map((column, index) => ( )) diff --git a/packages/react-bootstrap-table2/src/utils.js b/packages/react-bootstrap-table2/src/utils.js index 42a3cb5..bee745a 100644 --- a/packages/react-bootstrap-table2/src/utils.js +++ b/packages/react-bootstrap-table2/src/utils.js @@ -13,6 +13,11 @@ function get(target, field) { return result; } +function isFunction(obj) { + return obj && (typeof obj === 'function'); +} + export default { - get + get, + isFunction }; diff --git a/packages/react-bootstrap-table2/test/cell.test.js b/packages/react-bootstrap-table2/test/cell.test.js index 0649ca5..45157c2 100644 --- a/packages/react-bootstrap-table2/test/cell.test.js +++ b/packages/react-bootstrap-table2/test/cell.test.js @@ -18,16 +18,16 @@ describe('Cell', () => { }; beforeEach(() => { - wrapper = shallow(); + wrapper = shallow(); }); it('should render successfully', () => { expect(wrapper.length).toBe(1); - expect(wrapper.contains({ row[column.dataField] })).toBe(true); + expect(wrapper.text()).toEqual(row[column.dataField].toString()); }); }); - describe('when formatter prop is defined', () => { + describe('when column.formatter prop is defined', () => { const rowIndex = 1; const column = { dataField: 'id', @@ -41,14 +41,16 @@ describe('Cell', () => { column.formatter = formatter; // defined column formatter beforeEach(() => { - wrapper = shallow(); + wrapper = shallow( + ); }); afterEach(() => { formatter.reset(); }); it('should render successfully', () => { expect(wrapper.length).toBe(1); - expect(wrapper.contains(

{ row[column.dataField] }

)).toBe(true); + expect(wrapper.find('h3').length).toBe(1); + expect(wrapper.text()).toEqual(row[column.dataField].toString()); }); it('should call custom formatter correctly', () => { @@ -57,4 +59,106 @@ describe('Cell', () => { row, rowIndex, column.formatExtraData)).toBe(true); }); }); + + describe('when column.style prop is defined', () => { + let column; + const columnIndex = 1; + + beforeEach(() => { + column = { + dataField: 'id', + text: 'ID' + }; + }); + + describe('when style is an object', () => { + beforeEach(() => { + column.style = { backgroundColor: 'red' }; + wrapper = shallow( + ); + }); + + it('should render successfully', () => { + expect(wrapper.length).toBe(1); + expect(wrapper.find('td').prop('style')).toEqual(column.style); + }); + }); + + describe('when style is a function', () => { + const returnStyle = { backgroundColor: 'red' }; + let styleCallBack; + + beforeEach(() => { + styleCallBack = sinon.stub() + .withArgs(row[column.dataField], row, columnIndex) + .returns(returnStyle); + column.style = styleCallBack; + wrapper = shallow( + ); + }); + + afterEach(() => { styleCallBack.reset(); }); + + it('should render successfully', () => { + expect(wrapper.length).toBe(1); + expect(wrapper.find('td').prop('style')).toEqual(returnStyle); + }); + + it('should call custom style function correctly', () => { + expect(styleCallBack.callCount).toBe(1); + expect(styleCallBack.calledWith(row[column.dataField], row, columnIndex)).toBe(true); + }); + }); + }); + + describe('when column.classes prop is defined', () => { + let column; + const columnIndex = 1; + + beforeEach(() => { + column = { + dataField: 'id', + text: 'ID' + }; + }); + + describe('when classes is an object', () => { + beforeEach(() => { + column.classes = 'td-test-class'; + wrapper = shallow( + ); + }); + + it('should render successfully', () => { + expect(wrapper.length).toBe(1); + expect(wrapper.hasClass(column.classes)).toBe(true); + }); + }); + + describe('when classes is a function', () => { + const returnClasses = 'td-test-class'; + let classesCallBack; + + beforeEach(() => { + classesCallBack = sinon.stub() + .withArgs(row[column.dataField], row, columnIndex) + .returns(returnClasses); + column.classes = classesCallBack; + wrapper = shallow( + ); + }); + + afterEach(() => { classesCallBack.reset(); }); + + it('should render successfully', () => { + expect(wrapper.length).toBe(1); + expect(wrapper.hasClass(returnClasses)).toBe(true); + }); + + it('should call custom classes function correctly', () => { + expect(classesCallBack.callCount).toBe(1); + expect(classesCallBack.calledWith(row[column.dataField], row, columnIndex)).toBe(true); + }); + }); + }); });