* allow user to customize class for header cell

* add corresponding story

* allow user to customize inline-style for header cell

* add corresponding story

* [test] unit test for headerStyle

* [test] unit test for headerClasses

* update Document
This commit is contained in:
ChunMing, Chen
2017-09-02 06:15:34 -05:00
committed by Allen
parent 9f9f78e73b
commit 67c37e95f9
6 changed files with 281 additions and 5 deletions
+27
View File
@@ -16,6 +16,8 @@ Available properties in a column object:
* [headerTitle](#headerTitle)
* [headerEvents](#headerEvents)
* [headerAlign](#headerAlign)
* [headerClasses](#headerClasses)
* [headerStyle](#headerStyle)
Following is a most simplest and basic usage:
@@ -93,6 +95,20 @@ In addition, `classes` also accept a callback function which have more power to
* `row`
* `colIndex`
## <a name='headerClasses'>column.headerClasses - [String | Function]</a>
It's availabe to have customized class on table header column:
```js
{
// omit...
headerClasses: 'id-custom-cell'
}
```
In addition, similar to [`column.classes`](#classes), `headerClasses` also accept a callback function which have more power to custom the css class on header column. This callback function take two arguments and a string is expect to return:
* `column`
* `colIndex`
## <a name='style'>column.style - [Object | Function]</a>
It's availabe to have custom class on table column:
@@ -104,6 +120,17 @@ It's availabe to have custom class on table column:
```
`style` like [`column.classes`](#classes), it accept a callback function too and have same arguments: `cell`, `row` and `colIndex`.
## <a name='headerStyle'>column.headerStyle - [Object | Function]</a>
It's availabe to have customized inline-style on table header column:
```js
{
// omit...
headerStyle: { backgroundColor: 'green' }
}
```
`headerStyle` like [`column.headerClasses`](#headerClasses), it accept a callback function as well and have same arguments: `column` and `colIndex`.
## <a name='title'>column.title - [Bool | Function]</a>
`react-bootstrap-table2` is disable [`HTML title`](https://www.w3schools.com/tags/tag_title.asp) as default. You can assign `title` as `true` to enable the HTML title on table column. In addition, you can custom the title via a callback function:
@@ -0,0 +1,62 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import { BootstrapTable } from 'react-bootstrap-table2';
const products = [];
function addProducts(quantity) {
const startId = products.length;
for (let i = 0; i < quantity; i += 1) {
const id = startId + i;
products.push({
id,
name: `Item name ${id}`,
price: 2100 + i
});
}
}
addProducts(5);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
headerClasses: 'demo-row-odd'
}, {
dataField: 'price',
text: 'Product Price',
headerClasses: (column, colIndex) => {
if (colIndex % 2 === 0) return 'demo-row-even';
return 'demo-row-odd';
}
}];
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } />
<pre className="prettyprint lang-js"><code className="language-javascript">{`
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
headerClasses: 'demo-row-odd'
}, {
dataField: 'price',
text: 'Product Price',
headerClasses: (column, colIndex) => {
if (colIndex % 2 === 0) return 'demo-row-even';
return 'demo-row-odd';
}
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } />
`}
</code></pre>
</div>
);
@@ -0,0 +1,78 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import { BootstrapTable } from 'react-bootstrap-table2';
const products = [];
function addProducts(quantity) {
const startId = products.length;
for (let i = 0; i < quantity; i += 1) {
const id = startId + i;
products.push({
id,
name: `Item name ${id}`,
price: 2100 + i
});
}
}
addProducts(5);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
headerStyle: {
backgroundColor: '#fea'
}
}, {
dataField: 'price',
text: 'Product Price',
headerStyle: (column, colIndex) => {
if (colIndex % 2 === 0) {
return {
backgroundColor: '#bbe'
};
}
return {
backgroundColor: '#fea'
};
}
}];
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } />
<pre className="prettyprint lang-js"><code className="language-javascript">{`
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
headerStyle: {
backgroundColor: '#fea'
}
}, {
dataField: 'price',
text: 'Product Price',
headerStyle: (column, colIndex) => {
if (colIndex % 2 === 0) {
return {
backgroundColor: '#bbe'
};
}
return {
backgroundColor: '#fea'
};
}
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } />
`}
</code></pre>
</div>
);
+5 -1
View File
@@ -26,6 +26,8 @@ import HeaderColumnFormatTable from 'examples/header-columns/column-format-table
import HeaderColumnAlignTable from 'examples/header-columns/column-align-table';
import HeaderColumnTitleTable from 'examples/header-columns/column-title-table';
import HeaderColumnEventTable from 'examples/header-columns/column-event-table';
import HeaderColumnClassTable from 'examples/header-columns/column-class-table';
import HeaderColumnStyleTable from 'examples/header-columns/column-style-table';
// css style
import 'bootstrap/dist/css/bootstrap.min.css';
@@ -59,4 +61,6 @@ storiesOf('Work on Header Columns', module)
.add('Column Formatter', () => <HeaderColumnFormatTable />)
.add('Column Align', () => <HeaderColumnAlignTable />)
.add('Column Title', () => <HeaderColumnTitleTable />)
.add('Column Event', () => <HeaderColumnEventTable />);
.add('Column Event', () => <HeaderColumnEventTable />)
.add('Customize Column Class', () => <HeaderColumnClassTable />)
.add('Customize Column Style', () => <HeaderColumnStyleTable />);
+13 -4
View File
@@ -11,23 +11,32 @@ const HeaderCell = ({ column, index }) => {
headerTitle,
headerAlign,
headerFormatter,
headerEvents
headerEvents,
headerClasses,
headerStyle
} = column;
const attrs = {
...headerEvents
};
const headerStyle = {};
const children = headerFormatter ? headerFormatter(column, index) : text;
const cellClasses = _.isFunction(headerClasses) ? headerClasses(column, index) : headerClasses;
let cellStyle = {};
if (headerStyle) {
cellStyle = _.isFunction(headerStyle) ? headerStyle(column, index) : headerStyle;
}
if (headerTitle) {
attrs.title = _.isFunction(headerTitle) ? headerTitle(column, index) : text;
}
if (headerAlign) {
headerStyle.textAlign = _.isFunction(headerAlign) ? headerAlign(column, index) : headerAlign;
cellStyle.textAlign = _.isFunction(headerAlign) ? headerAlign(column, index) : headerAlign;
}
attrs.style = headerStyle;
attrs.style = cellStyle;
attrs.className = cellClasses;
if (hidden) {
attrs.style.display = 'none';
@@ -191,4 +191,100 @@ describe('HeaderCell', () => {
expect(column.headerEvents.onClick.callCount).toBe(1);
});
});
describe('when column.headerStyle prop is defined', () => {
let column;
beforeEach(() => {
column = {
dataField: 'id',
text: 'ID'
};
});
describe('when headerStyle is an object', () => {
beforeEach(() => {
column.headerStyle = { backgroundColor: 'red' };
wrapper = shallow(<HeaderCell column={ column } index={ index } />);
});
it('should render successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.find('th').prop('style')).toEqual(column.headerStyle);
});
});
describe('when headerStyle is a function', () => {
const returnStyle = { backgroundColor: 'red' };
let styleCallBack;
beforeEach(() => {
styleCallBack = sinon.stub()
.withArgs(column, index)
.returns(returnStyle);
column.headerStyle = styleCallBack;
wrapper = shallow(<HeaderCell column={ column } index={ index } />);
});
afterEach(() => { styleCallBack.reset(); });
it('should render successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.find('th').prop('style')).toEqual(returnStyle);
});
it('should call custom style function correctly', () => {
expect(styleCallBack.callCount).toBe(1);
expect(styleCallBack.calledWith(column, index)).toBe(true);
});
});
});
describe('when column.headerClasses prop is defined', () => {
let column;
beforeEach(() => {
column = {
dataField: 'id',
text: 'ID'
};
});
describe('when headerClasses is an object', () => {
beforeEach(() => {
column.headerClasses = 'td-test-class';
wrapper = shallow(<HeaderCell column={ column } index={ index } />);
});
it('should render successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.hasClass(column.headerClasses)).toBe(true);
});
});
describe('when headerClasses is a function', () => {
const returnClasses = 'td-test-class';
let classesCallBack;
beforeEach(() => {
classesCallBack = sinon.stub()
.withArgs(column, index)
.returns(returnClasses);
column.headerClasses = classesCallBack;
wrapper = shallow(<HeaderCell column={ column } index={ index } />);
});
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(column, index)).toBe(true);
});
});
});
});