mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2025-10-16 11:55:39 +00:00
fix selection column broken when bootstrap4
This commit is contained in:
parent
f7ba8e377d
commit
c0416fc307
@ -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 (
|
||||
<td onClick={ this.handleClick }>
|
||||
<BootstrapContext.Consumer>
|
||||
{
|
||||
selectionRenderer ? selectionRenderer({
|
||||
mode: inputType,
|
||||
checked: selected,
|
||||
disabled
|
||||
}) : (
|
||||
<input
|
||||
type={ inputType }
|
||||
checked={ selected }
|
||||
disabled={ disabled }
|
||||
/>
|
||||
({ bootstrap4 }) => (
|
||||
<td onClick={ this.handleClick }>
|
||||
{
|
||||
selectionRenderer ? selectionRenderer({
|
||||
mode: inputType,
|
||||
checked: selected,
|
||||
disabled
|
||||
}) : (
|
||||
<input
|
||||
type={ inputType }
|
||||
checked={ selected }
|
||||
disabled={ disabled }
|
||||
className={ bootstrap4 ? 'selection-input-4' : '' }
|
||||
/>
|
||||
)
|
||||
}
|
||||
</td>
|
||||
)
|
||||
}
|
||||
</td>
|
||||
</BootstrapContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 }) => (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={ checked }
|
||||
className={ className }
|
||||
ref={ (input) => {
|
||||
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 = (
|
||||
<CheckBox
|
||||
{ ...this.props }
|
||||
checked={ checked }
|
||||
indeterminate={ indeterminate }
|
||||
/>
|
||||
);
|
||||
if (selectionHeaderRenderer || mode === ROW_SELECT_MULTIPLE) {
|
||||
attrs.onClick = this.handleCheckBoxClick;
|
||||
}
|
||||
|
||||
return (
|
||||
<th data-row-selection { ...attrs }>{ content }</th>
|
||||
<BootstrapContext.Consumer>
|
||||
{
|
||||
({ bootstrap4 }) => {
|
||||
if (selectionHeaderRenderer) {
|
||||
content = selectionHeaderRenderer({
|
||||
mode,
|
||||
checked,
|
||||
indeterminate
|
||||
});
|
||||
} else if (mode === ROW_SELECT_MULTIPLE) {
|
||||
content = (
|
||||
<CheckBox
|
||||
{ ...this.props }
|
||||
checked={ checked }
|
||||
className={ bootstrap4 ? 'selection-input-4' : '' }
|
||||
indeterminate={ indeterminate }
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<th data-row-selection { ...attrs }>{ content }</th>
|
||||
);
|
||||
}
|
||||
}
|
||||
</BootstrapContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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('<SelectionCell />', () => {
|
||||
@ -52,14 +54,14 @@ describe('<SelectionCell />', () => {
|
||||
|
||||
describe('when disabled prop is false', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionCell
|
||||
selected
|
||||
rowKey={ rowKey }
|
||||
mode={ mode }
|
||||
rowIndex={ rowIndex }
|
||||
onRowSelect={ mockOnRowSelect }
|
||||
/>
|
||||
/>, { bootstrap4: false }
|
||||
);
|
||||
wrapper.find('td').simulate('click');
|
||||
});
|
||||
@ -78,7 +80,7 @@ describe('<SelectionCell />', () => {
|
||||
|
||||
describe('when disabled prop is true', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionCell
|
||||
selected
|
||||
rowKey={ rowKey }
|
||||
@ -86,7 +88,7 @@ describe('<SelectionCell />', () => {
|
||||
rowIndex={ rowIndex }
|
||||
onRowSelect={ mockOnRowSelect }
|
||||
disabled
|
||||
/>
|
||||
/>, { bootstrap4: false }
|
||||
);
|
||||
wrapper.find('td').simulate('click');
|
||||
});
|
||||
@ -102,14 +104,14 @@ describe('<SelectionCell />', () => {
|
||||
|
||||
describe('if selectRow.mode is radio', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionCell
|
||||
selected
|
||||
rowKey={ rowKey }
|
||||
mode="radio"
|
||||
rowIndex={ rowIndex }
|
||||
onRowSelect={ mockOnRowSelect }
|
||||
/>
|
||||
/>, { bootstrap4: false }
|
||||
);
|
||||
});
|
||||
|
||||
@ -118,38 +120,27 @@ describe('<SelectionCell />', () => {
|
||||
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(
|
||||
<SelectionCell
|
||||
rowKey={ rowKey }
|
||||
mode="checkbox"
|
||||
rowIndex={ rowIndex }
|
||||
selected
|
||||
onRowSelect={ mockOnRowSelect }
|
||||
/>
|
||||
/>, { 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('<SelectionCell />', () => {
|
||||
const selected = true;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionCell
|
||||
rowKey={ 1 }
|
||||
mode={ mode }
|
||||
rowIndex={ rowIndex }
|
||||
selected={ selected }
|
||||
/>
|
||||
/>, { 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(
|
||||
<SelectionCell
|
||||
rowKey={ 1 }
|
||||
mode={ mode }
|
||||
rowIndex={ rowIndex }
|
||||
selected={ selected }
|
||||
disabled
|
||||
/>
|
||||
/>, { bootstrap4: false }
|
||||
);
|
||||
});
|
||||
|
||||
@ -200,14 +191,14 @@ describe('<SelectionCell />', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
selectionRenderer.mockClear();
|
||||
wrapper = shallow(
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionCell
|
||||
rowKey={ 1 }
|
||||
mode={ mode }
|
||||
rowIndex={ rowIndex }
|
||||
selected={ selected }
|
||||
selectionRenderer={ selectionRenderer }
|
||||
/>
|
||||
/>, { bootstrap4: false }
|
||||
);
|
||||
});
|
||||
|
||||
@ -224,5 +215,23 @@ describe('<SelectionCell />', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when bootstrap4 context is true', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionCell
|
||||
rowKey={ 1 }
|
||||
mode={ mode }
|
||||
rowIndex={ rowIndex }
|
||||
selected={ selected }
|
||||
/>, { bootstrap4: true }
|
||||
);
|
||||
});
|
||||
|
||||
it('should render component correctly', () => {
|
||||
expect(wrapper.find('td').length).toBe(1);
|
||||
expect(wrapper.find('.selection-input-4')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -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('<SelectionHeaderCell />', () => {
|
||||
describe('shouldComponentUpdate', () => {
|
||||
describe('when props.mode is radio', () => {
|
||||
it('should not update component', () => {
|
||||
wrapper = shallow(<SelectionHeaderCell mode="radio" />);
|
||||
wrapper = shallow(<SelectionHeaderCell mode="radio" />, { bootstrap4: false });
|
||||
|
||||
expect(wrapper.instance().shouldComponentUpdate({})).toBe(false);
|
||||
});
|
||||
@ -24,7 +25,9 @@ describe('<SelectionHeaderCell />', () => {
|
||||
const nextProps = { checkedStatus };
|
||||
|
||||
wrapper = shallow(
|
||||
<SelectionHeaderCell mode="checkbox" checkedStatus={ checkedStatus } />);
|
||||
<SelectionHeaderCell mode="checkbox" checkedStatus={ checkedStatus } />,
|
||||
{ bootstrap4: false }
|
||||
);
|
||||
|
||||
expect(wrapper.instance().shouldComponentUpdate(nextProps)).toBe(false);
|
||||
});
|
||||
@ -37,7 +40,9 @@ describe('<SelectionHeaderCell />', () => {
|
||||
const nextProps = { checkedStatus };
|
||||
|
||||
wrapper = shallow(
|
||||
<SelectionHeaderCell mode="checkbox" checkedStatus={ CHECKBOX_STATUS_INDETERMINATE } />);
|
||||
<SelectionHeaderCell mode="checkbox" checkedStatus={ CHECKBOX_STATUS_INDETERMINATE } />,
|
||||
{ bootstrap4: false }
|
||||
);
|
||||
|
||||
expect(wrapper.instance().shouldComponentUpdate(nextProps)).toBe(true);
|
||||
});
|
||||
@ -57,12 +62,14 @@ describe('<SelectionHeaderCell />', () => {
|
||||
|
||||
describe('if props.mode is radio', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionHeaderCell
|
||||
mode="radio"
|
||||
checkedStatus={ Const.CHECKBOX_STATUS_CHECKED }
|
||||
onAllRowsSelect={ mockOnAllRowsSelect }
|
||||
/>);
|
||||
/>,
|
||||
{ bootstrap4: false }
|
||||
);
|
||||
});
|
||||
|
||||
it('should do nothing', () => {
|
||||
@ -75,12 +82,14 @@ describe('<SelectionHeaderCell />', () => {
|
||||
|
||||
describe('if props.mode is checkbox', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionHeaderCell
|
||||
mode="checkbox"
|
||||
checkedStatus={ Const.CHECKBOX_STATUS_CHECKED }
|
||||
onAllRowsSelect={ mockOnAllRowsSelect }
|
||||
/>);
|
||||
/>,
|
||||
{ bootstrap4: false }
|
||||
);
|
||||
});
|
||||
|
||||
it('should call handleCheckBoxClick', () => {
|
||||
@ -98,7 +107,10 @@ describe('<SelectionHeaderCell />', () => {
|
||||
beforeEach(() => {
|
||||
const checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
|
||||
|
||||
wrapper = shallow(<SelectionHeaderCell mode="radio" checkedStatus={ checkedStatus } />);
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionHeaderCell mode="radio" checkedStatus={ checkedStatus } />,
|
||||
{ bootstrap4: false }
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render checkbox', () => {
|
||||
@ -112,7 +124,10 @@ describe('<SelectionHeaderCell />', () => {
|
||||
const checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<SelectionHeaderCell mode="checkbox" checkedStatus={ checkedStatus } />);
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionHeaderCell mode="checkbox" checkedStatus={ checkedStatus } />,
|
||||
{ bootstrap4: false }
|
||||
);
|
||||
});
|
||||
|
||||
it('should render checkbox', () => {
|
||||
@ -134,12 +149,13 @@ describe('<SelectionHeaderCell />', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
selectionHeaderRenderer.mockClear();
|
||||
wrapper = shallow(
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionHeaderCell
|
||||
mode="checkbox"
|
||||
checkedStatus={ checkedStatus }
|
||||
selectionHeaderRenderer={ selectionHeaderRenderer }
|
||||
/>
|
||||
/>,
|
||||
{ bootstrap4: false }
|
||||
);
|
||||
});
|
||||
|
||||
@ -156,6 +172,22 @@ describe('<SelectionHeaderCell />', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when bootstrap4 context is true', () => {
|
||||
beforeEach(() => {
|
||||
const checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
|
||||
|
||||
wrapper = shallowWithContext(
|
||||
<SelectionHeaderCell mode="checkbox" checkedStatus={ checkedStatus } />,
|
||||
{ bootstrap4: true }
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render checkbox', () => {
|
||||
expect(wrapper.find('th').length).toBe(1);
|
||||
expect(wrapper.find('.selection-input-4').length).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user