diff --git a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js index bec0ef0..e7571a2 100644 --- a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js +++ b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js @@ -5,6 +5,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Const from '../const'; +import { BootstrapContext } from '../contexts/bootstrap'; export default class SelectionCell extends Component { static propTypes = { @@ -59,21 +60,28 @@ export default class SelectionCell extends Component { } = this.props; return ( - + { - selectionRenderer ? selectionRenderer({ - mode: inputType, - checked: selected, - disabled - }) : ( - + ({ bootstrap4 }) => ( + + { + selectionRenderer ? selectionRenderer({ + mode: inputType, + checked: selected, + disabled + }) : ( + + ) + } + ) } - + ); } } diff --git a/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js b/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js index c031a72..169740f 100644 --- a/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js +++ b/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js @@ -2,11 +2,13 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Const from '../const'; +import { BootstrapContext } from '../contexts/bootstrap'; -export const CheckBox = ({ checked, indeterminate }) => ( +export const CheckBox = ({ className, checked, indeterminate }) => ( { if (input) input.indeterminate = indeterminate; // eslint-disable-line no-param-reassign } } @@ -15,7 +17,8 @@ export const CheckBox = ({ checked, indeterminate }) => ( CheckBox.propTypes = { checked: PropTypes.bool.isRequired, - indeterminate: PropTypes.bool.isRequired + indeterminate: PropTypes.bool.isRequired, + className: PropTypes.string }; export default class SelectionHeaderCell extends Component { @@ -67,26 +70,36 @@ export default class SelectionHeaderCell extends Component { const attrs = {}; let content; - if (selectionHeaderRenderer) { - content = selectionHeaderRenderer({ - mode, - checked, - indeterminate - }); - attrs.onClick = this.handleCheckBoxClick; - } else if (mode === ROW_SELECT_MULTIPLE) { - content = ( - - ); + if (selectionHeaderRenderer || mode === ROW_SELECT_MULTIPLE) { attrs.onClick = this.handleCheckBoxClick; } return ( - { content } + + { + ({ bootstrap4 }) => { + if (selectionHeaderRenderer) { + content = selectionHeaderRenderer({ + mode, + checked, + indeterminate + }); + } else if (mode === ROW_SELECT_MULTIPLE) { + content = ( + + ); + } + return ( + { content } + ); + } + } + ); } } diff --git a/packages/react-bootstrap-table2/style/react-bootstrap-table2.scss b/packages/react-bootstrap-table2/style/react-bootstrap-table2.scss index 498b012..5974e45 100644 --- a/packages/react-bootstrap-table2/style/react-bootstrap-table2.scss +++ b/packages/react-bootstrap-table2/style/react-bootstrap-table2.scss @@ -59,6 +59,11 @@ width: 30px; } + th > .selection-input-4, + td > .selection-input-4 { + margin: -4px; + } + td.react-bs-table-no-data { text-align: center; } diff --git a/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js b/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js index 02e9d85..d3c9eac 100644 --- a/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js +++ b/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js @@ -1,7 +1,9 @@ +import 'jsdom-global/register'; import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; +import { shallowWithContext } from '../test-helpers/new-context'; import SelectionCell from '../../src/row-selection/selection-cell'; describe('', () => { @@ -52,14 +54,14 @@ describe('', () => { describe('when disabled prop is false', () => { beforeEach(() => { - wrapper = shallow( + wrapper = shallowWithContext( + />, { bootstrap4: false } ); wrapper.find('td').simulate('click'); }); @@ -78,7 +80,7 @@ describe('', () => { describe('when disabled prop is true', () => { beforeEach(() => { - wrapper = shallow( + wrapper = shallowWithContext( ', () => { rowIndex={ rowIndex } onRowSelect={ mockOnRowSelect } disabled - /> + />, { bootstrap4: false } ); wrapper.find('td').simulate('click'); }); @@ -102,14 +104,14 @@ describe('', () => { describe('if selectRow.mode is radio', () => { beforeEach(() => { - wrapper = shallow( + wrapper = shallowWithContext( + />, { bootstrap4: false } ); }); @@ -118,38 +120,27 @@ describe('', () => { wrapper.find('td').simulate('click'); expect(mockOnRowSelect.callCount).toBe(1); expect(mockOnRowSelect.calledWith(rowKey, true, rowIndex)).toBe(true); - - // second click - wrapper.find('td').simulate('click'); - expect(mockOnRowSelect.callCount).toBe(2); - expect(mockOnRowSelect.calledWith(rowKey, true, rowIndex)).toBe(true); }); }); describe('if selectRow.mode is checkbox', () => { beforeEach(() => { - wrapper = shallow( + wrapper = shallowWithContext( + />, { bootstrap4: false } ); }); it('should be called with correct paramters', () => { // first click - wrapper.setProps({ selected: true }); wrapper.find('td').simulate('click'); expect(mockOnRowSelect.callCount).toBe(1); - expect(mockOnRowSelect.calledWith(rowKey, false, rowIndex)).toBe(true); - - // second click - wrapper.setProps({ selected: false }); - wrapper.find('td').simulate('click'); - expect(mockOnRowSelect.callCount).toBe(2); - expect(mockOnRowSelect.calledWith(rowKey, true, rowIndex)).toBe(true); + expect(mockOnRowSelect.calledWith(rowKey, false, rowIndex, undefined)).toBe(true); }); }); }); @@ -159,33 +150,33 @@ describe('', () => { const selected = true; beforeEach(() => { - wrapper = shallow( + wrapper = shallowWithContext( + />, { bootstrap4: false } ); }); it('should render component correctly', () => { expect(wrapper.find('td').length).toBe(1); - expect(wrapper.find('input').length).toBe(1); + expect(wrapper.find('input')).toHaveLength(1); expect(wrapper.find('input').get(0).props.type).toBe(mode); expect(wrapper.find('input').get(0).props.checked).toBe(selected); }); describe('when disabled prop give as true', () => { beforeEach(() => { - wrapper = shallow( + wrapper = shallowWithContext( + />, { bootstrap4: false } ); }); @@ -200,14 +191,14 @@ describe('', () => { beforeEach(() => { selectionRenderer.mockClear(); - wrapper = shallow( + wrapper = shallowWithContext( + />, { bootstrap4: false } ); }); @@ -224,5 +215,23 @@ describe('', () => { }); }); }); + + describe('when bootstrap4 context is true', () => { + beforeEach(() => { + wrapper = shallowWithContext( + , { bootstrap4: true } + ); + }); + + it('should render component correctly', () => { + expect(wrapper.find('td').length).toBe(1); + expect(wrapper.find('.selection-input-4')).toHaveLength(1); + }); + }); }); }); diff --git a/packages/react-bootstrap-table2/test/row-selection/selection-header-cell.test.js b/packages/react-bootstrap-table2/test/row-selection/selection-header-cell.test.js index 73571d4..4423dbf 100644 --- a/packages/react-bootstrap-table2/test/row-selection/selection-header-cell.test.js +++ b/packages/react-bootstrap-table2/test/row-selection/selection-header-cell.test.js @@ -2,6 +2,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; +import { shallowWithContext } from '../test-helpers/new-context'; import Const from '../../src/const'; import SelectionHeaderCell, { CheckBox } from '../../src/row-selection/selection-header-cell'; @@ -11,7 +12,7 @@ describe('', () => { describe('shouldComponentUpdate', () => { describe('when props.mode is radio', () => { it('should not update component', () => { - wrapper = shallow(); + wrapper = shallow(, { bootstrap4: false }); expect(wrapper.instance().shouldComponentUpdate({})).toBe(false); }); @@ -24,7 +25,9 @@ describe('', () => { const nextProps = { checkedStatus }; wrapper = shallow( - ); + , + { bootstrap4: false } + ); expect(wrapper.instance().shouldComponentUpdate(nextProps)).toBe(false); }); @@ -37,7 +40,9 @@ describe('', () => { const nextProps = { checkedStatus }; wrapper = shallow( - ); + , + { bootstrap4: false } + ); expect(wrapper.instance().shouldComponentUpdate(nextProps)).toBe(true); }); @@ -57,12 +62,14 @@ describe('', () => { describe('if props.mode is radio', () => { beforeEach(() => { - wrapper = shallow( + wrapper = shallowWithContext( ); + />, + { bootstrap4: false } + ); }); it('should do nothing', () => { @@ -75,12 +82,14 @@ describe('', () => { describe('if props.mode is checkbox', () => { beforeEach(() => { - wrapper = shallow( + wrapper = shallowWithContext( ); + />, + { bootstrap4: false } + ); }); it('should call handleCheckBoxClick', () => { @@ -98,7 +107,10 @@ describe('', () => { beforeEach(() => { const checkedStatus = Const.CHECKBOX_STATUS_CHECKED; - wrapper = shallow(); + wrapper = shallowWithContext( + , + { bootstrap4: false } + ); }); it('should not render checkbox', () => { @@ -112,7 +124,10 @@ describe('', () => { const checkedStatus = Const.CHECKBOX_STATUS_CHECKED; beforeEach(() => { - wrapper = shallow(); + wrapper = shallowWithContext( + , + { bootstrap4: false } + ); }); it('should render checkbox', () => { @@ -134,12 +149,13 @@ describe('', () => { beforeEach(() => { selectionHeaderRenderer.mockClear(); - wrapper = shallow( + wrapper = shallowWithContext( + />, + { bootstrap4: false } ); }); @@ -156,6 +172,22 @@ describe('', () => { }); }); }); + + describe('when bootstrap4 context is true', () => { + beforeEach(() => { + const checkedStatus = Const.CHECKBOX_STATUS_CHECKED; + + wrapper = shallowWithContext( + , + { bootstrap4: true } + ); + }); + + it('should not render checkbox', () => { + expect(wrapper.find('th').length).toBe(1); + expect(wrapper.find('.selection-input-4').length).toBe(1); + }); + }); }); });