mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-06-29 13:40:07 +00:00
Compare commits
184 Commits
feature/st
...
react-boot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60eb47dc9e | ||
|
|
d74ecb63b4 | ||
|
|
2c6cc915f0 | ||
|
|
a1457dfe59 | ||
|
|
036c3fdc32 | ||
|
|
55eea6f337 | ||
|
|
7c259cd1ee | ||
|
|
1e164bb3f4 | ||
|
|
8a7c1def5b | ||
|
|
77b8ed53bf | ||
|
|
6bc54ef3ec | ||
|
|
6168bd7532 | ||
|
|
36fa9b8630 | ||
|
|
737922a5a4 | ||
|
|
0f37fae23d | ||
|
|
ce7e05d7f9 | ||
|
|
067006eb72 | ||
|
|
8fa10e3b6f | ||
|
|
e2e6c51d40 | ||
|
|
fb724331d3 | ||
|
|
160dede412 | ||
|
|
363a43251f | ||
|
|
8ad0e65679 | ||
|
|
6d5cca0047 | ||
|
|
204e75c9c2 | ||
|
|
fc27c56cbb | ||
|
|
8436edba7e | ||
|
|
3606fa3b7b | ||
|
|
73e8701bde | ||
|
|
6d2493d537 | ||
|
|
1a1f6969cb | ||
|
|
d47a3757b8 | ||
|
|
ba7512969e | ||
|
|
955ee17939 | ||
|
|
497bf44192 | ||
|
|
fcefcf8c84 | ||
|
|
04e3af0bbb | ||
|
|
9f47fa009c | ||
|
|
0edf9c8891 | ||
|
|
df5024892c | ||
|
|
4448c3f28c | ||
|
|
196ae33295 | ||
|
|
7f1b7a6c97 | ||
|
|
a6ccafcc75 | ||
|
|
06d87299a3 | ||
|
|
5891ec1b93 | ||
|
|
c5d9e04c2c | ||
|
|
dba3da28c1 | ||
|
|
a0e09cd804 | ||
|
|
d0e70f7246 | ||
|
|
b93c683f17 | ||
|
|
f80e1ea66c | ||
|
|
7642bfa1a3 | ||
|
|
8f304a849f | ||
|
|
956f1cef4d | ||
|
|
c45deee590 | ||
|
|
2aab4301dd | ||
|
|
43aa280761 | ||
|
|
3af30a0265 | ||
|
|
4b8b8b261e | ||
|
|
e44782f222 | ||
|
|
921e8c7ecc | ||
|
|
a3b3ce0dc4 | ||
|
|
e9f08d278d | ||
|
|
b4973c826c | ||
|
|
33c026c7e2 | ||
|
|
6cac7f6dc8 | ||
|
|
da5b93c3cf | ||
|
|
3ffccce1fe | ||
|
|
09f21e8130 | ||
|
|
bf0c5c43a2 | ||
|
|
c01f45a719 | ||
|
|
d26c13b9be | ||
|
|
d84fd5c801 | ||
|
|
8e940112f5 | ||
|
|
6070d150a9 | ||
|
|
dab6f1b206 | ||
|
|
2a497194e7 | ||
|
|
f5f17897fd | ||
|
|
2932b8a1b8 | ||
|
|
93103e5ca0 | ||
|
|
a7c2a49182 | ||
|
|
cd27ff98ff | ||
|
|
4d815894e6 | ||
|
|
d9ff201373 | ||
|
|
8e142de332 | ||
|
|
322605f14e | ||
|
|
3156e01dd6 | ||
|
|
052284a163 | ||
|
|
3cd8efffb9 | ||
|
|
447d69cae5 | ||
|
|
cacc28e1bc | ||
|
|
d7f84a9da5 | ||
|
|
63c2630f46 | ||
|
|
903dd2e5c8 | ||
|
|
964faa53e3 | ||
|
|
8fb5364cc2 | ||
|
|
8b89b3de0e | ||
|
|
4506a3dea2 | ||
|
|
ecea3efdaa | ||
|
|
8bef7eb348 | ||
|
|
408a004f58 | ||
|
|
bf46dfa026 | ||
|
|
f1b39e3dd6 | ||
|
|
029cd3ab6f | ||
|
|
1c68892a7b | ||
|
|
1bf3fa50db | ||
|
|
9988e790c1 | ||
|
|
bb071c98f9 | ||
|
|
9c5d8aac62 | ||
|
|
7c79b64985 | ||
|
|
16f89989f0 | ||
|
|
58cfdacfd1 | ||
|
|
78d5164056 | ||
|
|
bd2ce5abf0 | ||
|
|
416fcf08d4 | ||
|
|
0c650c0682 | ||
|
|
7d30804da9 | ||
|
|
782c630e58 | ||
|
|
22cc79961f | ||
|
|
a83b3d0d78 | ||
|
|
340ddb8722 | ||
|
|
32e455e65f | ||
|
|
6c0fc2748c | ||
|
|
973ece8b39 | ||
|
|
0a94f3ce39 | ||
|
|
0ca8e54ce2 | ||
|
|
69d534e26c | ||
|
|
c2a30cb716 | ||
|
|
83dc888d17 | ||
|
|
41da9afbcb | ||
|
|
91816fcc01 | ||
|
|
620309115f | ||
|
|
297f3e0c4f | ||
|
|
d42a10bbae | ||
|
|
5c52412542 | ||
|
|
a5f74cecfe | ||
|
|
a30a8fd96b | ||
|
|
424dbea270 | ||
|
|
b261c33e37 | ||
|
|
7dbdc1943b | ||
|
|
d4be1675db | ||
|
|
d3161f02eb | ||
|
|
28ba6d5677 | ||
|
|
4ddbfd4972 | ||
|
|
d84dc46ff1 | ||
|
|
e0163625d4 | ||
|
|
24ab58a464 | ||
|
|
6e19368733 | ||
|
|
bc4697bf95 | ||
|
|
9d2a6a1b23 | ||
|
|
bb752fcec8 | ||
|
|
aedd1f5942 | ||
|
|
5a5f10f609 | ||
|
|
e041a3d736 | ||
|
|
f175fd4186 | ||
|
|
5a6b7e122d | ||
|
|
a7ae524c49 | ||
|
|
a23599f52f | ||
|
|
c50853b16d | ||
|
|
3f74542c98 | ||
|
|
47aa41b8fa | ||
|
|
67ed2e6c80 | ||
|
|
794a97956d | ||
|
|
78ca01bb1a | ||
|
|
b79dbc80f6 | ||
|
|
3f21a67620 | ||
|
|
9e3ae385ce | ||
|
|
c6ea19fe8a | ||
|
|
a5b42dca92 | ||
|
|
28f3c33db3 | ||
|
|
2530a70c00 | ||
|
|
569dd61463 | ||
|
|
68264b45ce | ||
|
|
e251068657 | ||
|
|
e4fbb284b4 | ||
|
|
a6afc9d9a8 | ||
|
|
a0ba41c103 | ||
|
|
4a16cb314d | ||
|
|
98a04a5710 | ||
|
|
c22a2a1d71 | ||
|
|
9bc25c9d3e | ||
|
|
4554db02d2 | ||
|
|
b7fac973d2 |
43
README.md
43
README.md
@@ -1,43 +1,52 @@
|
||||
# react-bootstrap-table2
|
||||
|
||||
[](https://travis-ci.org/react-bootstrap-table/react-bootstrap-table2)
|
||||
Rebuilt [react-bootstrap-table](https://github.com/AllenFang/react-bootstrap-table)
|
||||
Rebuilt of [react-bootstrap-table](https://github.com/AllenFang/react-bootstrap-table)
|
||||
|
||||
> `react-bootstrap-table2`'s npm module name is [**`react-bootstrap-table-next`**](https://www.npmjs.com/package/react-bootstrap-table-next) due to some guys already used it
|
||||
> Note that `react-bootstrap-table2`'s npm module name is [**`react-bootstrap-table-next`**](https://www.npmjs.com/package/react-bootstrap-table-next) due to the name being already taken.
|
||||
|
||||
`react-bootstrap-table2` separate some functionalities from core modules to other modules like following:
|
||||
`react-bootstrap-table2` separates some functionalities from its core modules to other modules as listed in the following:
|
||||
|
||||
* [`react-bootstrap-table-next`](https://www.npmjs.com/package/react-bootstrap-table-next)
|
||||
* [`react-bootstrap-table2-filter`](https://www.npmjs.com/package/react-bootstrap-table2-filter)
|
||||
* [`react-bootstrap-table2-editor`](https://www.npmjs.com/package/react-bootstrap-table2-editor)
|
||||
* [`react-bootstrap-table2-paginator`](https://www.npmjs.com/package/react-bootstrap-table2-paginator)
|
||||
* [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
|
||||
* [`react-bootstrap-table2-toolkit`](https://www.npmjs.com/package/react-bootstrap-table2-toolkit)
|
||||
- [`react-bootstrap-table-next`](https://www.npmjs.com/package/react-bootstrap-table-next)
|
||||
- [`react-bootstrap-table2-filter`](https://www.npmjs.com/package/react-bootstrap-table2-filter)
|
||||
- [`react-bootstrap-table2-editor`](https://www.npmjs.com/package/react-bootstrap-table2-editor)
|
||||
- [`react-bootstrap-table2-paginator`](https://www.npmjs.com/package/react-bootstrap-table2-paginator)
|
||||
- [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
|
||||
- [`react-bootstrap-table2-toolkit`](https://www.npmjs.com/package/react-bootstrap-table2-toolkit)
|
||||
|
||||
This can help your application with less bundled size and also help us have clean design to avoid handling to much logic in kernel module(SRP).
|
||||
Not only does this reduce the bundle size of your apps but also helps us have a cleaner design to avoid handling too much logic in the kernel module(SRP).
|
||||
|
||||
## Migration
|
||||
If you are the user from legacy [`react-bootstrap-table`](https://github.com/AllenFang/react-bootstrap-table/), please have a look on [this](./docs/migration.md).
|
||||
|
||||
If you are coming from the legacy [`react-bootstrap-table`](https://github.com/AllenFang/react-bootstrap-table/), please check out the [migration guide](./docs/migration.md).
|
||||
|
||||
## Usage
|
||||
|
||||
See [getting started](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/getting-started.html).
|
||||
|
||||
## Online Demo
|
||||
|
||||
See `react-bootstrap-table2` [storybook](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html).
|
||||
|
||||
## Roadmap
|
||||
See [release plans](https://react-bootstrap-table.github.io/react-bootstrap-table2/blog/2018/01/24/release-plan.html).
|
||||
|
||||
## Development
|
||||
Please check [development guide](./docs/development.md).
|
||||
|
||||
## How should I run storybook example in my local?
|
||||
Please check the [development guide](./docs/development.md).
|
||||
|
||||
## Running storybook example on your local machine
|
||||
|
||||
```sh
|
||||
# Clone the repo
|
||||
$ git clone https://github.com/react-bootstrap-table/react-bootstrap-table2.git
|
||||
|
||||
# change dir to the cloned repo
|
||||
$ cd react-bootstrap-table2
|
||||
|
||||
# Install all dependencies with yarn
|
||||
$ yarn install
|
||||
|
||||
# Start the stroybook server, then go to localhost:6006
|
||||
$ yarn storybook
|
||||
$ Go to localhost:6006
|
||||
|
||||
```
|
||||
|
||||
**Storybook examples: [`packages/react-bootstrap-table2-example/examples`](https://github.com/react-bootstrap-table/react-bootstrap-table2/tree/master/packages/react-bootstrap-table2-example/examples)**
|
||||
|
||||
@@ -27,11 +27,13 @@
|
||||
* [rowStyle](#rowStyle)
|
||||
* [rowClasses](#rowClasses)
|
||||
* [rowEvents](#rowEvents)
|
||||
* [hiddenRows](#hiddenRows)
|
||||
* [defaultSorted](#defaultSorted)
|
||||
* [defaultSortDirection](#defaultSortDirection)
|
||||
* [pagination](#pagination)
|
||||
* [filter](#filter)
|
||||
* [onTableChange](#onTableChange)
|
||||
* [onDataSizeChange](#onDataSizeChange)
|
||||
|
||||
### <a name='keyField'>keyField(**required**) - [String]</a>
|
||||
Tells `react-bootstrap-table2` which column is unique.
|
||||
@@ -181,6 +183,14 @@ const rowEvents = {
|
||||
<BootstrapTable data={ data } columns={ columns } rowEvents={ rowEvents } />
|
||||
```
|
||||
|
||||
### <a name='hiddenRows'>hiddenRows - [Array]</a>
|
||||
Hide rows, this props accept an array of row keys:
|
||||
|
||||
```js
|
||||
const hiddenRows = [1, 4];
|
||||
<BootstrapTable data={ data } columns={ columns } hiddenRows={ hiddenRows } />
|
||||
```
|
||||
|
||||
### <a name='defaultSorted'>defaultSorted - [Array]</a>
|
||||
`defaultSorted` accept an object array which allow you to define the default sort columns when first render.
|
||||
|
||||
@@ -308,4 +318,20 @@ Following is a shape of `newState`
|
||||
newValue
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### <a name='onDataSizeChange'>onDataSizeChange - [Function]</a>
|
||||
This callback function will be called only when data size change by search/filter etc. This function have one argument which is an object contains below props:
|
||||
|
||||
* `dataSize`: The new data size
|
||||
|
||||
```js
|
||||
handleDataChange = ({ dataSize }) => {
|
||||
this.setState({ rowCount: dataSize });
|
||||
}
|
||||
|
||||
<BootstrapTable
|
||||
onDataSizeChange={ handleDataChange }
|
||||
....
|
||||
/>
|
||||
```
|
||||
@@ -69,7 +69,7 @@ const cellEdit: {
|
||||
// omit...
|
||||
beforeSaveCell(oldValue, newValue, row, column, done) {
|
||||
setTimeout(() => {
|
||||
if (confirm('Do you want to accep this change?')) {
|
||||
if (confirm('Do you want to accept this change?')) {
|
||||
done(); // contine to save the changes
|
||||
} else {
|
||||
done(false); // reject the changes
|
||||
|
||||
168
docs/columns.md
168
docs/columns.md
@@ -30,6 +30,14 @@ Available properties in a column object:
|
||||
* [headerAttrs](#headerAttrs)
|
||||
* [headerSortingClasses](#headerSortingClasses)
|
||||
* [headerSortingStyle](#headerSortingStyle)
|
||||
* [footer](#footer)
|
||||
* [footerFormatter](#footerFormatter)
|
||||
* [footerClasses](#footerClasses)
|
||||
* [footerStyle](#footerStyle)
|
||||
* [footerTitle](#footerTitle)
|
||||
* [footerEvents](#footerEvents)
|
||||
* [footerAlign](#footerAlign)
|
||||
* [footerAttrs](#footerAttrs)
|
||||
* [editable](#editable)
|
||||
* [validator](#validator)
|
||||
* [editCellStyle](#editCellStyle)
|
||||
@@ -156,7 +164,7 @@ Enable the column sort via a `true` value given.
|
||||
```
|
||||
|
||||
## <a name='sortCaret'>column.sortCaret - [Function]</a>
|
||||
Use`column.sortCaret` to custom the sort caret. This callback function accept two arguments: `order` and `column`
|
||||
Use`column.sortCaret` to customize the sort caret. This callback function accept two arguments: `order` and `column`
|
||||
|
||||
```js
|
||||
{
|
||||
@@ -302,7 +310,7 @@ A new `Object` will be the result of element headerStyle.
|
||||
A new `String` will be the result of element title.
|
||||
|
||||
## <a name='headerTitle'>column.headerTitle - [Bool | Function]</a>
|
||||
`headerTitle` is only for the title on header column, default is disable. The usage almost same as [`column.title`](#title),
|
||||
Configure the title on header column, default is disable. The usage almost same as [`column.title`](#title),
|
||||
|
||||
```js
|
||||
{
|
||||
@@ -518,6 +526,162 @@ const sortingHeaderStyle = {
|
||||
};
|
||||
```
|
||||
|
||||
### <a name='footer'>footer - [String | Function]</a>
|
||||
Give a string to render the string value on the footer column.
|
||||
|
||||
```js
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footerAlign: 'center',
|
||||
footer: 'Footer 1'
|
||||
}, .....];
|
||||
```
|
||||
|
||||
This prop also accept a function:
|
||||
|
||||
```js
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: column => column.reduce((acc, item) => acc + item, 0)
|
||||
}
|
||||
```
|
||||
|
||||
## <a name='footerFormatter'>column.footerFormatter - [Function]</a>
|
||||
`footerFormatter` allow you to customize the table footer column and only accept a callback function which take two arguments and a JSX/String are expected for return.
|
||||
|
||||
* `column`
|
||||
* `columnIndex`
|
||||
|
||||
## <a name='footerClasses'>column.footerClasses - [String | Function]</a>
|
||||
It's similar to [`column.classes`](#classes), `footerClasses` is available to have customized class on table footer column:
|
||||
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
footerClasses: 'id-custom-cell'
|
||||
}
|
||||
```
|
||||
Furthermore, it also accept a callback function which takes 2 arguments and a `String` is expect to return:
|
||||
|
||||
```js
|
||||
{
|
||||
footerClasses: function callback(column, colIndex) { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Parameters**
|
||||
* `column`: The value of current column.
|
||||
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||
|
||||
## <a name='footerStyle'>column.footerStyle - [Object | Function]</a>
|
||||
Customized the inline-style on table footer column:
|
||||
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
footerStyle: { backgroundColor: 'green' }
|
||||
}
|
||||
```
|
||||
|
||||
Moreover, it also accept a callback function which takes **2** arguments and an `Object` is expect to return:
|
||||
|
||||
```js
|
||||
{
|
||||
footerStyle: function callback(column, colIndex) { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Parameters**
|
||||
* `column`: The value of current column.
|
||||
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||
|
||||
## <a name='footerTitle'>column.footerTitle - [Bool | Function]</a>
|
||||
Configure the title on footer column, default is disable. The usage is almost same as [`column.title`](#title),
|
||||
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
footerTitle: true
|
||||
}
|
||||
```
|
||||
|
||||
It's also available to custom via a callback function:
|
||||
```js
|
||||
{
|
||||
footerTitle: function callback(column, colIndex) { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Parameters**
|
||||
* `column`: The value of current column.
|
||||
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||
|
||||
## <a name='footerEvents'>column.footerEvents - [Object]</a>
|
||||
`footerEvents` same as [`column.events`](#events) but it is for footer column:
|
||||
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
footerEvents: {
|
||||
onClick: e => { ... }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## <a name='footerAlign'>column.footerAlign - [String | Function]</a>
|
||||
It's almost same as [`column.align`](#align), but it's for the [CSS text-align](https://www.w3schools.com/cssref/pr_text_text-align.asp) on footer column.
|
||||
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
footerAlign: 'center'
|
||||
}
|
||||
```
|
||||
|
||||
Also, you can custom the align by a callback function:
|
||||
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
footerAlign: (column, colIndex) => {
|
||||
// column is an object and perform itself
|
||||
// return custom title here
|
||||
}
|
||||
}
|
||||
```
|
||||
**Parameters**
|
||||
* `column`: The value of current column.
|
||||
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||
|
||||
## <a name='footerAttrs'>column.footerAttrs - [Object | Function]</a>
|
||||
`footerAttrs` is similar to [`column.attrs`](#attrs) but it works for footer column.
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
footerAttrs: {
|
||||
title: 'bar',
|
||||
'data-test': 'foo'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Additionally, customize the header attributes by a **2** arguments callback function:
|
||||
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
footerAttrs: (column, colIndex) => ({
|
||||
// return customized HTML attribute here
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
**Parameters**
|
||||
* `column`: The value of current column.
|
||||
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||
|
||||
## <a name='editable'>column.editable - [Bool | Function]</a>
|
||||
`column.editable` default is true, means every column is editable if you configure [`cellEdit`](./README.md#cellEdit). But you can disable some columns editable via setting `false`.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ Currently, **I still can't implement all the mainly features in legacy `react-bo
|
||||
* [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
|
||||
* Overlay/Loading Addons
|
||||
* [`react-bootstrap-table2-toolkit`](https://www.npmjs.com/package/react-bootstrap-table2-toolkit)
|
||||
* Table Toolkits, like search, csv etc.
|
||||
* Table Toolkits, like search, csv, column toggle etc.
|
||||
|
||||
This can help your application with less bundled size and also help `react-bootstrap-table2` have clean design to avoid handling to much logic in kernel module(SRP). Hence, which means you probably need to install above addons when you need specific features.
|
||||
|
||||
@@ -113,14 +113,12 @@ Please see [available pagination configurations](https://react-bootstrap-table.g
|
||||
|
||||
Remember to install [`react-bootstrap-table2-paginator`](https://www.npmjs.com/package/react-bootstrap-table2-paginator) firstly.
|
||||
|
||||
No big changes for pagination, but still can't custom the pagination list, button and sizePerPage dropdown.
|
||||
|
||||
## Table Search
|
||||
The usage of search functionality is a little bit different from legacy search. The mainly different thing is developer have to render the search input field, we do believe it will be very flexible for all the developers who want to custom the search position or search field itself.
|
||||
|
||||
- [x] Custom search component and position
|
||||
- [x] Custom search value
|
||||
- [ ] Clear search
|
||||
- [x] Clear search
|
||||
- [ ] Multiple search
|
||||
- [ ] Strict search
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Row expand
|
||||
`react-bootstrap-table2` supports the row expand feature. By passing prop `expandRow` to enable this functionality.
|
||||
|
||||
> Default is click to expand/collapse a row. In addition, we don't support any way to chagne this mechanism!
|
||||
> Default is click to expand/collapse a row. In addition, we don't support any way to change this mechanism!
|
||||
|
||||
## Required
|
||||
* [renderer (**required**)](#renderer)
|
||||
@@ -15,6 +15,7 @@
|
||||
* [showExpandColumn](#showExpandColumn)
|
||||
* [onlyOneExpanding](#onlyOneExpanding)
|
||||
* [expandByColumnOnly](#expandByColumnOnly)
|
||||
* [expandColumnPosition](#expandColumnPosition)
|
||||
* [expandColumnRenderer](#expandColumnRenderer)
|
||||
* [expandHeaderColumnRenderer](#expandHeaderColumnRenderer)
|
||||
|
||||
@@ -92,13 +93,16 @@ const expandRow = {
|
||||
```
|
||||
|
||||
### <a name='expandColumnRenderer'>expandRow.expandColumnRenderer - [Function]</a>
|
||||
Provide a callback function which allow you to custom the expand indicator. This callback only have one argument which is an object and contain one property `expanded` which indicate if current row is expanded
|
||||
Provide a callback function which allow you to custom the expand indicator. This callback only have one argument which is an object and contain these properties:
|
||||
* `expanded`: If current row is expanded or not
|
||||
* `rowKey`: Current row key
|
||||
* `expandable`: If currnet row is expandable or not
|
||||
|
||||
|
||||
```js
|
||||
const expandRow = {
|
||||
renderer: (row) => ...
|
||||
expandColumnRenderer: ({ expanded }) => (
|
||||
expandColumnRenderer: ({ expanded, rowKey, expandable }) => (
|
||||
// ....
|
||||
)
|
||||
};
|
||||
@@ -150,3 +154,14 @@ const expandRow = {
|
||||
expandByColumnOnly: true
|
||||
};
|
||||
```
|
||||
|
||||
### <a name='expandColumnPosition'>expandRow.expandColumnPosition - [String]</a>
|
||||
Default is `left`. You can give this as `right` for rendering expand column in the right side.
|
||||
|
||||
```js
|
||||
const expandRow = {
|
||||
renderer: (row) => ...,
|
||||
showExpandColumn: true,
|
||||
expandColumnPosition: 'right'
|
||||
};
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
# Row selection
|
||||
`react-bootstrap-table2` supports the row selection feature. By passing prop `selectRow` to enable row selection. When you enable this feature, `react-bootstrap-table2` will append a new selection column at first.
|
||||
`react-bootstrap-table2` supports the row selection feature. By passing prop `selectRow` to enable row selection. When you enable this feature, `react-bootstrap-table2` will prepend a new selection column.
|
||||
|
||||
## Required
|
||||
* [mode (**required**)](#mode)
|
||||
@@ -20,6 +20,7 @@
|
||||
* [hideSelectAll](#hideSelectAll)
|
||||
* [selectionRenderer](#selectionRenderer)
|
||||
* [selectionHeaderRenderer](#selectionHeaderRenderer)
|
||||
* [headerColumnStyle](#headerColumnStyle)
|
||||
|
||||
### <a name="mode">selectRow.mode - [String]</a>
|
||||
|
||||
@@ -176,7 +177,7 @@ Provide a callback function which allow you to custom the checkbox/radio box. Th
|
||||
```js
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
selectionRenderer: ({ mode, checked, disabled }) => (
|
||||
selectionRenderer: ({ mode, checked, disabled, rowIndex }) => (
|
||||
// ....
|
||||
)
|
||||
};
|
||||
@@ -198,6 +199,31 @@ const selectRow = {
|
||||
|
||||
> By default, `react-bootstrap-table2` will help you to handle the click event, it's not necessary to handle again by developer.
|
||||
|
||||
|
||||
### <a name='headerColumnStyle'>selectRow.headerColumnStyle - [Object | Function]</a>
|
||||
A way to custome the selection header cell. `headerColumnStyle` not only accept a simple style object but also a callback function for more flexible customization:
|
||||
|
||||
### Style Object
|
||||
|
||||
```js
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
headerColumnStyle: { backgroundColor: 'blue' }
|
||||
};
|
||||
```
|
||||
|
||||
### Callback Function
|
||||
|
||||
```js
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
headerColumnStyle: (status) => (
|
||||
// status available value is checked, indeterminate and unchecked
|
||||
return { backgroundColor: 'blue' };
|
||||
)
|
||||
};
|
||||
```
|
||||
|
||||
### <a name='onSelect'>selectRow.onSelect - [Function]</a>
|
||||
This callback function will be called when a row is select/unselect and pass following three arguments:
|
||||
`row`, `isSelect`, `rowIndex` and `e`.
|
||||
@@ -211,18 +237,44 @@ const selectRow = {
|
||||
};
|
||||
```
|
||||
|
||||
> If you want to reject current select action, just return `false`:
|
||||
|
||||
```js
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
onSelect: (row, isSelect, rowIndex, e) => {
|
||||
if (SOME_CONDITION) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### <a name='onSelectAll'>selectRow.onSelectAll - [Function]</a>
|
||||
This callback function will be called when select/unselect all and it only work when you configure [`selectRow.mode`](#mode) as `checkbox`.
|
||||
|
||||
```js
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
onSelectAll: (isSelect, results, e) => {
|
||||
onSelectAll: (isSelect, rows, e) => {
|
||||
// ...
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
> If you want to control the final selection result, just return a row key array:
|
||||
|
||||
```js
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
onSelectAll: (isSelect, rows, e) => {
|
||||
if (isSelect && SOME_CONDITION) {
|
||||
return [1, 3, 4]; // finally, key 1, 3, 4 will being selected
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### <a name='hideSelectColumn'>selectRow.hideSelectColumn - [Bool]</a>
|
||||
Default is `false`, if you don't want to have a selection column, give this prop as `true`
|
||||
|
||||
|
||||
@@ -89,7 +89,8 @@
|
||||
"jest": {
|
||||
"collectCoverageFrom": [
|
||||
"packages/*/src/**/*.js",
|
||||
"packages/*/index.js"
|
||||
"packages/*/index.js",
|
||||
"!packages/react-bootstrap-table2-example/**/*.js"
|
||||
],
|
||||
"roots": [
|
||||
"<rootDir>/packages"
|
||||
|
||||
@@ -132,7 +132,7 @@ const columns = [
|
||||
if (typeof cell !== 'object') {
|
||||
dateObj = new Date(cell);
|
||||
}
|
||||
return `${('0' + dateObj.getDate()).slice(-2)}/${('0' + (dateObj.getMonth() + 1)).slice(-2)}/${dateObj.getFullYear()}`;
|
||||
return `${('0' + dateObj.getUTCDate()).slice(-2)}/${('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/${dateObj.getUTCFullYear()}`;
|
||||
},
|
||||
editor: {
|
||||
type: Type.DATE
|
||||
@@ -173,16 +173,16 @@ If you feel above predefined editors are not satisfied to your requirement, you
|
||||
|
||||
* `editorProps`: Some useful attributes you can use on DOM editor, like class, style etc.
|
||||
* `value`: Current cell value
|
||||
* `row`: Current row data
|
||||
* `column`: Current column definition
|
||||
* `rowIndex`: Current row index
|
||||
* `row`: Current row data
|
||||
* `column`: Current column definition
|
||||
* `rowIndex`: Current row index
|
||||
* `columnIndex`: Current column index
|
||||
|
||||
> Note when implement a custom React editor component, this component should have a **getValue** function which return current value on editor
|
||||
|
||||
> Note when you want to save value, you can call **editorProps.onUpdate** function
|
||||
|
||||
Following is a short example:
|
||||
Following is a short example:
|
||||
|
||||
```js
|
||||
class QualityRanger extends React.Component {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-editor",
|
||||
"version": "1.2.1",
|
||||
"version": "1.2.3",
|
||||
"description": "it's the editor addon for react-bootstrap-table2",
|
||||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
||||
|
||||
const EditorIndicator = ({ invalidMessage }) =>
|
||||
(
|
||||
<div className="alert alert-danger fade in">
|
||||
<div className="alert alert-danger in" role="alert">
|
||||
<strong>{ invalidMessage }</strong>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -9,6 +9,7 @@ const sourceStylePath = path.join(__dirname, '../../react-bootstrap-table2/style
|
||||
const paginationStylePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/style');
|
||||
const filterStylePath = path.join(__dirname, '../../react-bootstrap-table2-filter/style');
|
||||
const toolkitSourcePath = path.join(__dirname, '../../react-bootstrap-table2-toolkit/index.js');
|
||||
const toolkitStylePath = path.join(__dirname, '../../react-bootstrap-table2-toolkit/style');
|
||||
const storyPath = path.join(__dirname, '../stories');
|
||||
const examplesPath = path.join(__dirname, '../examples');
|
||||
const srcPath = path.join(__dirname, '../src');
|
||||
@@ -43,7 +44,13 @@ const loaders = [{
|
||||
}, {
|
||||
test: /\.scss$/,
|
||||
use: ['style-loader', 'css-loader', 'sass-loader'],
|
||||
include: [storyPath, sourceStylePath, paginationStylePath, filterStylePath],
|
||||
include: [
|
||||
storyPath,
|
||||
sourceStylePath,
|
||||
paginationStylePath,
|
||||
filterStylePath,
|
||||
toolkitStylePath
|
||||
],
|
||||
}, {
|
||||
test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/,
|
||||
loader: 'url-loader?limit=100000',
|
||||
|
||||
@@ -45,8 +45,12 @@ class ExposedFunctionTable extends React.Component {
|
||||
console.log(this.node.table.props.data);
|
||||
}
|
||||
|
||||
handleGetCurrentData = () => {
|
||||
console.log(this.node.table.props.data);
|
||||
}
|
||||
|
||||
handleGetSelectedData = () => {
|
||||
console.log(this.node.selectionContext.state.selected);
|
||||
console.log(this.node.selectionContext.selected);
|
||||
}
|
||||
|
||||
handleGetExpandedData = () => {
|
||||
@@ -117,7 +121,7 @@ export default class ExposedFunctionTable extends React.Component {
|
||||
}
|
||||
|
||||
handleGetSelectedData = () => {
|
||||
console.log(this.node.selectionContext.state.selected);
|
||||
console.log(this.node.selectionContext.selected);
|
||||
}
|
||||
|
||||
handleGetExpandedData = () => {
|
||||
|
||||
81
packages/react-bootstrap-table2-example/examples/bootstrap4/column-toggle.js
vendored
Normal file
81
packages/react-bootstrap-table2-example/examples/bootstrap4/column-toggle.js
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { ToggleList } = ColumnToggle;
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const { ToggleList } = ColumnToggle;
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
90
packages/react-bootstrap-table2-example/examples/bootstrap4/toolkits.js
vendored
Normal file
90
packages/react-bootstrap-table2-example/examples/bootstrap4/toolkits.js
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { Search, CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { SearchBar, ClearSearchButton } = Search;
|
||||
const { ExportCSVButton } = CSVExport;
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { Search, CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const { SearchBar, ClearSearchButton } = Search;
|
||||
const { ExportCSVButton } = CSVExport;
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
search
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<h3>Input something at below input field:</h3>
|
||||
<SearchBar { ...props.searchProps } />
|
||||
<ClearSearchButton { ...props.searchProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
search
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<h3>Input something at below input field:</h3>
|
||||
<SearchBar { ...props.searchProps } />
|
||||
<ClearSearchButton { ...props.searchProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
@@ -18,6 +18,11 @@ class QualityRanger extends React.Component {
|
||||
static defaultProps = {
|
||||
value: 0
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.range.focus();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return parseInt(this.range.value, 10);
|
||||
}
|
||||
@@ -103,7 +108,7 @@ const columns = [{
|
||||
}, {
|
||||
dataField: 'quality',
|
||||
text: 'Product Quality',
|
||||
editorRenderer: (editorProps, value, row, rowIndex, columnIndex) => (
|
||||
editorRenderer: (editorProps, value, row, column, rowIndex, columnIndex) => (
|
||||
<QualityRanger { ...editorProps } value={ value } />
|
||||
)
|
||||
}];
|
||||
|
||||
@@ -23,7 +23,7 @@ const columns = [{
|
||||
if (typeof cell !== 'object') {
|
||||
dateObj = new Date(cell);
|
||||
}
|
||||
return `${('0' + dateObj.getDate()).slice(-2)}/${('0' + (dateObj.getMonth() + 1)).slice(-2)}/${dateObj.getFullYear()}`;
|
||||
return `${('0' + dateObj.getUTCDate()).slice(-2)}/${('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/${dateObj.getUTCFullYear()}`;
|
||||
},
|
||||
editor: {
|
||||
type: Type.DATE
|
||||
@@ -48,7 +48,7 @@ const columns = [{
|
||||
if (typeof cell !== 'object') {
|
||||
dateObj = new Date(cell);
|
||||
}
|
||||
return \`$\{('0' + dateObj.getDate()).slice(-2)}/$\{('0' + (dateObj.getMonth() + 1)).slice(-2)}/$\{dateObj.getFullYear()}\`;
|
||||
return \`$\{('0' + dateObj.getUTCDate()).slice(-2)}/$\{('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/$\{dateObj.getUTCFullYear()}\`;
|
||||
},
|
||||
editor: {
|
||||
type: Type.DATE
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import React from 'react';
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import filterFactory, { textFilter, dateFilter } from 'react-bootstrap-table2-filter';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
import { stockGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(8);
|
||||
const products = stockGenerator(8);
|
||||
|
||||
let nameFilter;
|
||||
let priceFilter;
|
||||
let stockDateFilter;
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
@@ -22,25 +23,36 @@ const columns = [{
|
||||
})
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
text: 'Price',
|
||||
filter: textFilter({
|
||||
getFilter: (filter) => {
|
||||
priceFilter = filter;
|
||||
}
|
||||
})
|
||||
}, {
|
||||
dataField: 'inStockDate',
|
||||
text: 'InStock Date',
|
||||
formatter: cell => cell.toString(),
|
||||
filter: dateFilter({
|
||||
getFilter: (filter) => {
|
||||
stockDateFilter = filter;
|
||||
}
|
||||
})
|
||||
}];
|
||||
|
||||
const handleClick = () => {
|
||||
nameFilter('');
|
||||
priceFilter('');
|
||||
stockDateFilter();
|
||||
};
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import filterFactory, { textFilter, dateFilter } from 'react-bootstrap-table2-filter';
|
||||
|
||||
let nameFilter;
|
||||
let priceFilter;
|
||||
let stockDateFilter;
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
@@ -55,17 +67,27 @@ const columns = [{
|
||||
})
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
text: 'Price',
|
||||
filter: textFilter({
|
||||
getFilter: (filter) => {
|
||||
priceFilter = filter;
|
||||
}
|
||||
})
|
||||
}, {
|
||||
dataField: 'inStockDate',
|
||||
text: 'InStock Date',
|
||||
formatter: cell => cell.toString(),
|
||||
filter: dateFilter({
|
||||
getFilter: (filter) => {
|
||||
stockDateFilter = filter;
|
||||
}
|
||||
})
|
||||
}];
|
||||
|
||||
const handleClick = () => {
|
||||
nameFilter('');
|
||||
priceFilter('');
|
||||
stockDateFilter();
|
||||
};
|
||||
|
||||
export default () => (
|
||||
|
||||
81
packages/react-bootstrap-table2-example/examples/column-filter/custom-filter-logic.js
vendored
Normal file
81
packages/react-bootstrap-table2-example/examples/column-filter/custom-filter-logic.js
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/* eslint eqeqeq: 0 */
|
||||
import React from 'react';
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(8);
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
|
||||
class Table extends React.Component {
|
||||
filterByPrice = filterVal =>
|
||||
products.filter(product => product.price == filterVal);
|
||||
|
||||
render() {
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter()
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
filter: textFilter({
|
||||
onFilter: this.filterByPrice
|
||||
})
|
||||
}];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default class Table extends React.Component {
|
||||
filterByPrice = filterVal =>
|
||||
products.filter(product => product.price == filterVal);
|
||||
|
||||
render() {
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter()
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
filter: textFilter({
|
||||
onFilter: this.filterByPrice
|
||||
})
|
||||
}];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Implement a eq filter on product price column</h2>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
57
packages/react-bootstrap-table2-example/examples/column-filter/filter-hooks.js
vendored
Normal file
57
packages/react-bootstrap-table2-example/examples/column-filter/filter-hooks.js
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/* eslint no-console: 0 */
|
||||
import React from 'react';
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(8);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter()
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
filter: textFilter({
|
||||
onFilter: filterVal => console.log(`Filter Value: ${filterVal}`)
|
||||
})
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter()
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
filter: textFilter({
|
||||
onFilter: filterVal => console.log(\`Filter Value: $\{filterVal}\`)
|
||||
})
|
||||
}];
|
||||
|
||||
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,70 @@
|
||||
/* eslint max-len: 0 */
|
||||
import React from 'react';
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsQualityGenerator } from 'utils/common';
|
||||
|
||||
const products = productsQualityGenerator(6);
|
||||
|
||||
const selectOptions = [
|
||||
{ value: 0, label: 'good' },
|
||||
{ value: 1, label: 'Bad' },
|
||||
{ value: 2, label: 'unknown' }
|
||||
];
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'quality',
|
||||
text: 'Product Quailty',
|
||||
formatter: cell => selectOptions.find(opt => opt.value === cell).label,
|
||||
filter: selectFilter({
|
||||
options: selectOptions
|
||||
})
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
|
||||
|
||||
const selectOptions = [
|
||||
{ value: 0, label: 'good' },
|
||||
{ value: 1, label: 'Bad' },
|
||||
{ value: 2, label: 'unknown' }
|
||||
];
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'quality',
|
||||
text: 'Product Quailty',
|
||||
formatter: cell => selectOptions.find(opt => opt.value === cell).label,
|
||||
filter: selectFilter({
|
||||
options: selectOptions
|
||||
})
|
||||
}];
|
||||
|
||||
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<h3><code>selectFilter.options</code> accept an Array and we keep that order when rendering the options</h3>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
135
packages/react-bootstrap-table2-example/examples/column-toggle/custom-toggle-list.js
vendored
Normal file
135
packages/react-bootstrap-table2-example/examples/column-toggle/custom-toggle-list.js
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columnsdt = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const CustomToggleList = ({
|
||||
columns,
|
||||
onColumnToggle,
|
||||
toggles
|
||||
}) => (
|
||||
<div className="btn-group btn-group-toggle btn-group-vertical" data-toggle="buttons">
|
||||
{
|
||||
columns
|
||||
.map(column => ({
|
||||
...column,
|
||||
toggle: toggles[column.dataField]
|
||||
}))
|
||||
.map(column => (
|
||||
<button
|
||||
type="button"
|
||||
key={ column.dataField }
|
||||
className={ \`btn btn-warning \${column.toggle ? 'active' : ''}\` }
|
||||
data-toggle="button"
|
||||
aria-pressed={ column.toggle ? 'true' : 'false' }
|
||||
onClick={ () => onColumnToggle(column.dataField) }
|
||||
>
|
||||
{ column.text }
|
||||
</button>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columnsdt }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<CustomToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
const CustomToggleList = ({
|
||||
columns,
|
||||
onColumnToggle,
|
||||
toggles
|
||||
}) => (
|
||||
<div className="btn-group btn-group-toggle btn-group-vertical" data-toggle="buttons">
|
||||
{
|
||||
columns
|
||||
.map(column => ({
|
||||
...column,
|
||||
toggle: toggles[column.dataField]
|
||||
}))
|
||||
.map(column => (
|
||||
<button
|
||||
type="button"
|
||||
key={ column.dataField }
|
||||
className={ `btn btn-warning ${column.toggle ? 'active' : ''}` }
|
||||
data-toggle="button"
|
||||
aria-pressed={ column.toggle ? 'true' : 'false' }
|
||||
onClick={ () => onColumnToggle(column.dataField) }
|
||||
>
|
||||
{ column.text }
|
||||
</button>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columnsdt }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<CustomToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
81
packages/react-bootstrap-table2-example/examples/column-toggle/default-visibility.js
vendored
Normal file
81
packages/react-bootstrap-table2-example/examples/column-toggle/default-visibility.js
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { ToggleList } = ColumnToggle;
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
hidden: true
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
hidden: true
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const { ToggleList } = ColumnToggle;
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
hidden: true
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
hidden: true
|
||||
}];
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable { ...props.baseProps } />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable { ...props.baseProps } />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
81
packages/react-bootstrap-table2-example/examples/column-toggle/index.js
vendored
Normal file
81
packages/react-bootstrap-table2-example/examples/column-toggle/index.js
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { ToggleList } = ColumnToggle;
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const { ToggleList } = ColumnToggle;
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList { ...props.columnToggleProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
91
packages/react-bootstrap-table2-example/examples/column-toggle/styling-toggle-list.js
vendored
Normal file
91
packages/react-bootstrap-table2-example/examples/column-toggle/styling-toggle-list.js
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { ToggleList } = ColumnToggle;
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const { ToggleList } = ColumnToggle;
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList
|
||||
contextual="success"
|
||||
className="list-custom-class"
|
||||
btnClassName="list-btn-custom-class"
|
||||
{ ...props.columnToggleProps }
|
||||
/>
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
columnToggle
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ToggleList
|
||||
contextual="success"
|
||||
className="list-custom-class"
|
||||
btnClassName="list-btn-custom-class"
|
||||
{ ...props.columnToggleProps }
|
||||
/>
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
@@ -2,9 +2,9 @@ import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
import { productsGenerator, withOnSale } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
const products = withOnSale(productsGenerator());
|
||||
|
||||
function priceFormatter(cell, row) {
|
||||
if (row.onSale) {
|
||||
|
||||
@@ -11,141 +11,13 @@ const products = [
|
||||
{ id: 14, name: 'Item 14', price: 14.5, inStock: true }
|
||||
];
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
},
|
||||
{
|
||||
dataField: 'inStock',
|
||||
text: 'In Stock',
|
||||
formatter: (cellContent, row) => (
|
||||
<div className="checkbox disabled">
|
||||
<label>
|
||||
<input type="checkbox" checked={ row.inStock } disabled />
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
dataField: 'df1',
|
||||
isDummyField: true,
|
||||
text: 'Action 1',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
dataField: 'df2',
|
||||
isDummyField: true,
|
||||
text: 'Action 2',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
},
|
||||
{
|
||||
dataField: 'inStock',
|
||||
text: 'In Stock',
|
||||
formatter: (cellContent, row) => (
|
||||
<div className="checkbox disabled">
|
||||
<label>
|
||||
<input type="checkbox" checked={ row.inStock } disabled />
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
dataField: 'df1',
|
||||
isDummyField: true,
|
||||
text: 'Action 1',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
dataField: 'df2',
|
||||
isDummyField: true,
|
||||
text: 'Action 2',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
class ProductList extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { products };
|
||||
this.state = { products, count: 0 };
|
||||
}
|
||||
|
||||
toggleInStock = () => {
|
||||
@@ -163,17 +35,96 @@ class ProductList extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
formatter: (cell, row, rowIndex, extraData) => (
|
||||
<div>
|
||||
<span>ID: {row.id}</span>
|
||||
<br />
|
||||
<span>state: {extraData}</span>
|
||||
</div>
|
||||
),
|
||||
formatExtraData: this.state.count
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
},
|
||||
{
|
||||
dataField: 'inStock',
|
||||
text: 'In Stock',
|
||||
formatter: (cellContent, row) => (
|
||||
<div className="checkbox disabled">
|
||||
<label>
|
||||
<input type="checkbox" checked={ row.inStock } disabled />
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
dataField: 'df1',
|
||||
isDummyField: true,
|
||||
text: 'Action 1',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
dataField: 'df2',
|
||||
isDummyField: true,
|
||||
text: 'Action 2',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="h2">Products</h1>
|
||||
<h3>Action 1 and Action 2 are dummy column</h3>
|
||||
<button onClick={ this.toggleInStock } className="btn btn-primary">
|
||||
Toggle item 13 stock status
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-success"
|
||||
onClick={ () => this.setState(() => ({ count: this.state.count + 1 })) }
|
||||
>
|
||||
Click me to Increase counter
|
||||
</button>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ this.state.products }
|
||||
columns={ columns }
|
||||
/>
|
||||
<button onClick={ this.toggleInStock } className="btn btn-primary">
|
||||
Toggle item 13 stock status
|
||||
</button>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -183,7 +134,7 @@ class ProductList extends React.Component {
|
||||
class ProductList extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { products };
|
||||
this.state = { products, count: 0 };
|
||||
}
|
||||
|
||||
toggleInStock = () => {
|
||||
@@ -200,13 +151,95 @@ class ProductList extends React.Component {
|
||||
this.setState(curr => ({ ...curr, products: newProducts }));
|
||||
};
|
||||
|
||||
counter = () => {
|
||||
this.setState(curr => ({ ...curr, count: this.state.count + 1 }));
|
||||
}
|
||||
|
||||
render() {
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
formatter: (cell, row, rowIndex, extraData) => (
|
||||
<div>
|
||||
<span>ID: {row.id}</span>
|
||||
<br />
|
||||
<span>Counter: {extraData}</span>
|
||||
</div>
|
||||
),
|
||||
formatExtraData: this.state.count
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
},
|
||||
{
|
||||
dataField: 'inStock',
|
||||
text: 'In Stock',
|
||||
formatter: (cellContent, row) => (
|
||||
<div className="checkbox disabled">
|
||||
<label>
|
||||
<input type="checkbox" checked={ row.inStock } disabled />
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
dataField: 'df1',
|
||||
isDummyField: true,
|
||||
text: 'Action 1',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
dataField: 'df2',
|
||||
isDummyField: true,
|
||||
text: 'Action 2',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3>Action 1 and Action 2 are dummy column</h3>
|
||||
<button onClick={ this.toggleInStock } className="btn btn-primary">
|
||||
Toggle item 13 stock status
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-success"
|
||||
onClick={ this.counter }
|
||||
>
|
||||
Click me to Increase counter
|
||||
</button>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ this.state.products }
|
||||
|
||||
102
packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js
vendored
Normal file
102
packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { CSVExport, Search } from 'react-bootstrap-table2-toolkit';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { SearchBar } = Search;
|
||||
const { ExportCSVButton } = CSVExport;
|
||||
const products = productsGenerator(150);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter()
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { CSVExport, Search } from 'react-bootstrap-table2-toolkit';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
|
||||
const { SearchBar } = Search;
|
||||
const { ExportCSVButton } = CSVExport;
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
clickToSelect: true
|
||||
};
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
exportCSV={ { onlyExportFiltered: true, exportAll: false } }
|
||||
search
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||
<hr />
|
||||
<SearchBar { ...props.searchProps } />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
pagination={ paginationFactory() }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<h3>Export all the filtered/searched rows</h3>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
exportCSV={ { onlyExportFiltered: true, exportAll: false } }
|
||||
search
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||
<hr />
|
||||
<SearchBar { ...props.searchProps } />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
pagination={ paginationFactory() }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
151
packages/react-bootstrap-table2-example/examples/data/data-change-listener.js
vendored
Normal file
151
packages/react-bootstrap-table2-example/examples/data/data-change-listener.js
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/* eslint react/no-multi-comp: 0 */
|
||||
import React from 'react';
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter()
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
filter: textFilter()
|
||||
}];
|
||||
|
||||
const sourceCode1 = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
|
||||
class Case1 extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { rowCount: products.length };
|
||||
}
|
||||
|
||||
handleDataChange = ({ dataSize }) => {
|
||||
this.setState({ rowCount: dataSize });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h5>Row Count:<span className="badge">{ this.state.rowCount }</span></h5>
|
||||
<BootstrapTable
|
||||
onDataSizeChange={ this.handleDataChange }
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
`;
|
||||
|
||||
const sourceCode2 = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
|
||||
class Case2 extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { rowCount: products.length };
|
||||
}
|
||||
|
||||
handleDataChange = ({ dataSize }) => {
|
||||
this.setState({ rowCount: dataSize });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h5>Row Count:<span className="badge">{ this.state.rowCount }</span></h5>
|
||||
<BootstrapTable
|
||||
onDataSizeChange={ this.handleDataChange }
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
pagination={ paginationFactory() }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
`;
|
||||
|
||||
const products1 = productsGenerator(8);
|
||||
class WithoutPaginationCase extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { rowCount: products1.length };
|
||||
}
|
||||
|
||||
handleDataChange = ({ dataSize }) => {
|
||||
this.setState({ rowCount: dataSize });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h3>Without Pagination Case</h3>
|
||||
<h5>Row Count:<span className="badge">{ this.state.rowCount }</span></h5>
|
||||
<BootstrapTable
|
||||
onDataSizeChange={ this.handleDataChange }
|
||||
keyField="id"
|
||||
data={ products1 }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
<Code>{ sourceCode2 }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const products2 = productsGenerator(88);
|
||||
class WithPaginationCase extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { rowCount: products2.length };
|
||||
}
|
||||
|
||||
handleDataChange = ({ dataSize }) => {
|
||||
this.setState({ rowCount: dataSize });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h3>Without Pagination Case</h3>
|
||||
<h5>Row Count:<span className="badge">{ this.state.rowCount }</span></h5>
|
||||
<BootstrapTable
|
||||
onDataSizeChange={ this.handleDataChange }
|
||||
keyField="id"
|
||||
data={ products2 }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
pagination={ paginationFactory() }
|
||||
/>
|
||||
<Code>{ sourceCode1 }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<WithoutPaginationCase />
|
||||
<WithPaginationCase />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const ProductList = (props) => {
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter({
|
||||
defaultValue: '1'
|
||||
})
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
filter: textFilter()
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={ { paddingTop: '20px' } }>
|
||||
<h1 className="h2">Products</h1>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ props.products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default class DataContainer extends React.Component {
|
||||
state = {
|
||||
products: productsGenerator(3)
|
||||
};
|
||||
|
||||
loadData = () => {
|
||||
this.setState({
|
||||
products: productsGenerator(14)
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
onClick={ this.loadData }
|
||||
style={ {
|
||||
fontSize: '20px',
|
||||
position: 'absolute',
|
||||
left: '200px',
|
||||
top: '40px'
|
||||
} }
|
||||
>
|
||||
Load Data
|
||||
</button>
|
||||
<ProductList products={ this.state.products } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { SearchBar } = Search;
|
||||
const ProductList = (props) => {
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={ { paddingTop: '20px' } }>
|
||||
<h1 className="h2">Products</h1>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ props.products }
|
||||
columns={ columns }
|
||||
search={ { defaultSearch: '2101' } }
|
||||
>
|
||||
{
|
||||
toolkitprops => (
|
||||
<div>
|
||||
<SearchBar { ...toolkitprops.searchProps } />
|
||||
<BootstrapTable
|
||||
striped
|
||||
hover
|
||||
{ ...toolkitprops.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default class DataContainer extends React.Component {
|
||||
state = {
|
||||
products: productsGenerator(3)
|
||||
};
|
||||
|
||||
loadData = () => {
|
||||
this.setState({
|
||||
products: productsGenerator(14)
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
onClick={ this.loadData }
|
||||
style={ {
|
||||
fontSize: '20px',
|
||||
position: 'absolute',
|
||||
left: '200px',
|
||||
top: '40px'
|
||||
} }
|
||||
>
|
||||
Load Data
|
||||
</button>
|
||||
<ProductList products={ this.state.products } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
68
packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-filter.js
vendored
Normal file
68
packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-filter.js
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const ProductList = (props) => {
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter()
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
filter: textFilter()
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={ { paddingTop: '20px' } }>
|
||||
<h1 className="h2">Products</h1>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ props.products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default class DataContainer extends React.Component {
|
||||
state = {
|
||||
products: []
|
||||
};
|
||||
|
||||
loadData = () => {
|
||||
this.setState({
|
||||
products: productsGenerator()
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
onClick={ this.loadData }
|
||||
style={ {
|
||||
fontSize: '20px',
|
||||
position: 'absolute',
|
||||
left: '200px',
|
||||
top: '40px'
|
||||
} }
|
||||
>
|
||||
Load Data
|
||||
</button>
|
||||
<ProductList products={ this.state.products } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const ProductList = (props) => {
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter({
|
||||
defaultValue: '6'
|
||||
})
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
filter: textFilter()
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={ { paddingTop: '20px' } }>
|
||||
<h1 className="h2">Products</h1>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ props.products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
pagination={ paginationFactory() }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default class DataContainer extends React.Component {
|
||||
state = {
|
||||
products: productsGenerator(60)
|
||||
};
|
||||
|
||||
loadData = () => {
|
||||
this.setState({
|
||||
products: productsGenerator(14)
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
onClick={ this.loadData }
|
||||
style={ {
|
||||
fontSize: '20px',
|
||||
position: 'absolute',
|
||||
left: '200px',
|
||||
top: '40px'
|
||||
} }
|
||||
>
|
||||
Load Data
|
||||
</button>
|
||||
<ProductList products={ this.state.products } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
80
packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-search.js
vendored
Normal file
80
packages/react-bootstrap-table2-example/examples/data/load-data-on-the-fly-with-search.js
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { SearchBar } = Search;
|
||||
const ProductList = (props) => {
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={ { paddingTop: '20px' } }>
|
||||
<h1 className="h2">Products</h1>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ props.products }
|
||||
columns={ columns }
|
||||
search
|
||||
>
|
||||
{
|
||||
toolkitprops => (
|
||||
<div>
|
||||
<SearchBar { ...toolkitprops.searchProps } />
|
||||
<BootstrapTable
|
||||
striped
|
||||
hover
|
||||
{ ...toolkitprops.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default class DataContainer extends React.Component {
|
||||
state = {
|
||||
products: []
|
||||
};
|
||||
|
||||
loadData = () => {
|
||||
this.setState({
|
||||
products: productsGenerator()
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
onClick={ this.loadData }
|
||||
style={ {
|
||||
fontSize: '20px',
|
||||
position: 'absolute',
|
||||
left: '200px',
|
||||
top: '40px'
|
||||
} }
|
||||
>
|
||||
Load Data
|
||||
</button>
|
||||
<ProductList products={ this.state.products } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
53
packages/react-bootstrap-table2-example/examples/footer/column-align-table.js
vendored
Normal file
53
packages/react-bootstrap-table2-example/examples/footer/column-align-table.js
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footerAlign: 'center',
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footerAlign: (column, colIndex) => 'right',
|
||||
footer: 'Footer 2'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footerAlign: 'center',
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footerAlign: (column, colIndex) => 'right',
|
||||
footer: 'Footer 2'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}];
|
||||
|
||||
<BootstrapTable keyField='id' data={ products } columns={ columns } />
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
54
packages/react-bootstrap-table2-example/examples/footer/column-attrs-table.js
vendored
Normal file
54
packages/react-bootstrap-table2-example/examples/footer/column-attrs-table.js
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
/* eslint no-alert: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1',
|
||||
footerAttrs: { title: 'ID footer column' }
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2',
|
||||
footerAttrs: (column, colIndex) => ({ 'data-test': `customized data ${colIndex}` })
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1',
|
||||
footerAttrs: { title: 'ID footer column' }
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2',
|
||||
footerAttrs: (column, colIndex) => ({ 'data-test': \`customized data \${colIndex}\` })
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}];
|
||||
|
||||
<BootstrapTable keyField='id' data={ products } columns={ columns } />
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
60
packages/react-bootstrap-table2-example/examples/footer/column-class-table.js
vendored
Normal file
60
packages/react-bootstrap-table2-example/examples/footer/column-class-table.js
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
/* eslint no-alert: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2',
|
||||
footerClasses: 'demo-row-odd'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3',
|
||||
footerClasses: (column, colIndex) => {
|
||||
if (colIndex % 2 === 0) return 'demo-row-even';
|
||||
return 'demo-row-odd';
|
||||
}
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2',
|
||||
footerClasses: 'demo-row-odd'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3',
|
||||
footerClasses: (column, colIndex) => {
|
||||
if (colIndex % 2 === 0) return 'demo-row-even';
|
||||
return 'demo-row-odd';
|
||||
}
|
||||
}];
|
||||
|
||||
<BootstrapTable keyField='id' data={ products } columns={ columns } />
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
56
packages/react-bootstrap-table2-example/examples/footer/column-event-table.js
vendored
Normal file
56
packages/react-bootstrap-table2-example/examples/footer/column-event-table.js
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
/* eslint no-alert: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footerEvents: {
|
||||
onClick: () => alert('Click on Product ID footer column')
|
||||
},
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footerEvents: {
|
||||
onClick: () => alert('Click on Product ID footer column')
|
||||
},
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}];
|
||||
|
||||
<BootstrapTable keyField='id' data={ products } columns={ columns } />
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
67
packages/react-bootstrap-table2-example/examples/footer/column-format-table.js
vendored
Normal file
67
packages/react-bootstrap-table2-example/examples/footer/column-format-table.js
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
function priceFormatter(column, colIndex) {
|
||||
return (
|
||||
<h5>
|
||||
<strong>$$ {column.text} $$</strong>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3',
|
||||
footerFormatter: priceFormatter
|
||||
}
|
||||
];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
function priceFormatter(column, colIndex) {
|
||||
return (
|
||||
<h5><strong>$$ { column.text } $$</strong></h5>
|
||||
);
|
||||
}
|
||||
|
||||
const columns = [
|
||||
// omit...
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3',
|
||||
footerFormatter: priceFormatter
|
||||
}];
|
||||
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
/>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{sourceCode}</Code>
|
||||
</div>
|
||||
);
|
||||
76
packages/react-bootstrap-table2-example/examples/footer/column-style-table.js
vendored
Normal file
76
packages/react-bootstrap-table2-example/examples/footer/column-style-table.js
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
/* eslint no-alert: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2',
|
||||
footerStyle: {
|
||||
backgroundColor: '#c8e6c9'
|
||||
}
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3',
|
||||
footerStyle: (column, colIndex) => {
|
||||
if (colIndex % 2 === 0) {
|
||||
return {
|
||||
backgroundColor: '#81c784'
|
||||
};
|
||||
}
|
||||
return {
|
||||
backgroundColor: '#c8e6c9'
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2',
|
||||
footerStyle: {
|
||||
backgroundColor: '#c8e6c9'
|
||||
}
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3',
|
||||
footerStyle: (column, colIndex) => {
|
||||
if (colIndex % 2 === 0) {
|
||||
return {
|
||||
backgroundColor: '#81c784'
|
||||
};
|
||||
}
|
||||
return {
|
||||
backgroundColor: '#c8e6c9'
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
||||
<BootstrapTable keyField='id' data={ products } columns={ columns } />
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
53
packages/react-bootstrap-table2-example/examples/footer/column-title-table.js
vendored
Normal file
53
packages/react-bootstrap-table2-example/examples/footer/column-title-table.js
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footerTitle: true,
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footerTitle: (column, colIndex) => `this is custom title for ${column.text}`,
|
||||
footer: 'Footer 2'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footerTitle: true,
|
||||
footer: 'Footer 1'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footerTitle: (column, colIndex) => \`this is custom title for \${column.text}\`,
|
||||
footer: 'Footer 2'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}];
|
||||
|
||||
<BootstrapTable keyField='id' data={ products } columns={ columns } />
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
61
packages/react-bootstrap-table2-example/examples/footer/footer-class-table.js
vendored
Normal file
61
packages/react-bootstrap-table2-example/examples/footer/footer-class-table.js
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}
|
||||
];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}
|
||||
];
|
||||
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
footerClasses="footer-class"
|
||||
/>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } footerClasses="footer-class" />
|
||||
<Code>{sourceCode}</Code>
|
||||
</div>
|
||||
);
|
||||
52
packages/react-bootstrap-table2-example/examples/footer/function-footer.js
vendored
Normal file
52
packages/react-bootstrap-table2-example/examples/footer/function-footer.js
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: columnData => columnData.reduce((acc, item) => acc + item, 0)
|
||||
}
|
||||
];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [
|
||||
// omit...
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: columnData => columnData.reduce((acc, item) => acc + item, 0)
|
||||
}];
|
||||
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
/>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{sourceCode}</Code>
|
||||
</div>
|
||||
);
|
||||
52
packages/react-bootstrap-table2-example/examples/footer/simple-footer.js
vendored
Normal file
52
packages/react-bootstrap-table2-example/examples/footer/simple-footer.js
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
footer: 'Footer 1'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
footer: 'Footer 2'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}
|
||||
];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [
|
||||
// omit...
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
footer: 'Footer 3'
|
||||
}];
|
||||
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
/>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{sourceCode}</Code>
|
||||
</div>
|
||||
);
|
||||
106
packages/react-bootstrap-table2-example/examples/pagination/custom-page-button.js
vendored
Normal file
106
packages/react-bootstrap-table2-example/examples/pagination/custom-page-button.js
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
/* eslint react/prop-types: 0 */
|
||||
/* eslint jsx-a11y/href-no-hash: 0 */
|
||||
/* eslint no-unused-vars: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(87);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
// ...
|
||||
|
||||
const pageButtonRenderer = ({
|
||||
page,
|
||||
active,
|
||||
disable,
|
||||
title,
|
||||
onPageChange
|
||||
}) => {
|
||||
const handleClick = (e) => {
|
||||
e.preventDefault();
|
||||
onPageChange(page);
|
||||
};
|
||||
const activeStyle = {};
|
||||
if (active) {
|
||||
activeStyle.backgroundColor = 'black';
|
||||
activeStyle.color = 'white';
|
||||
} else {
|
||||
activeStyle.backgroundColor = 'gray';
|
||||
activeStyle.color = 'black';
|
||||
}
|
||||
if (typeof page === 'string') {
|
||||
activeStyle.backgroundColor = 'white';
|
||||
activeStyle.color = 'black';
|
||||
}
|
||||
return (
|
||||
<li className="page-item">
|
||||
<a href="#" onClick={ handleClick } style={ activeStyle }>{ page }</a>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
const options = {
|
||||
pageButtonRenderer
|
||||
};
|
||||
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory(options) } />
|
||||
`;
|
||||
|
||||
const pageButtonRenderer = ({
|
||||
page,
|
||||
active,
|
||||
disable,
|
||||
title,
|
||||
onPageChange
|
||||
}) => {
|
||||
const handleClick = (e) => {
|
||||
e.preventDefault();
|
||||
onPageChange(page);
|
||||
};
|
||||
const activeStyle = {};
|
||||
if (active) {
|
||||
activeStyle.backgroundColor = 'black';
|
||||
activeStyle.color = 'white';
|
||||
} else {
|
||||
activeStyle.backgroundColor = 'gray';
|
||||
activeStyle.color = 'black';
|
||||
}
|
||||
if (typeof page === 'string') {
|
||||
activeStyle.backgroundColor = 'white';
|
||||
activeStyle.color = 'black';
|
||||
}
|
||||
return (
|
||||
<li className="page-item">
|
||||
<a href="#" onClick={ handleClick } style={ activeStyle }>{ page }</a>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
const options = {
|
||||
pageButtonRenderer
|
||||
};
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory(options) } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
159
packages/react-bootstrap-table2-example/examples/pagination/custom-page-list-with-search.js
vendored
Normal file
159
packages/react-bootstrap-table2-example/examples/pagination/custom-page-list-with-search.js
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(40);
|
||||
const { SearchBar } = Search;
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
|
||||
class Table extends React.Component {
|
||||
state = { products }
|
||||
|
||||
loadData = () => {
|
||||
this.setState({ products: productsGenerator(17) });
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = {
|
||||
custom: true,
|
||||
paginationSize: 4,
|
||||
pageStartIndex: 1,
|
||||
firstPageText: 'First',
|
||||
prePageText: 'Back',
|
||||
nextPageText: 'Next',
|
||||
lastPageText: 'Last',
|
||||
nextPageTitle: 'First page',
|
||||
prePageTitle: 'Pre page',
|
||||
firstPageTitle: 'Next page',
|
||||
lastPageTitle: 'Last page',
|
||||
showTotal: true,
|
||||
totalSize: this.state.products.length
|
||||
};
|
||||
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
||||
<div>
|
||||
<button className="btn btn-default" onClick={ this.loadData }>Load Another Data</button>
|
||||
<PaginationListStandalone { ...paginationProps } />
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
columns={ columns }
|
||||
data={ this.state.products }
|
||||
search
|
||||
>
|
||||
{
|
||||
toolkitprops => (
|
||||
<div>
|
||||
<SearchBar { ...toolkitprops.searchProps } />
|
||||
<BootstrapTable
|
||||
striped
|
||||
hover
|
||||
{ ...toolkitprops.baseProps }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<PaginationListStandalone { ...paginationProps } />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>PaginationProvider will care the data size change. You dont do anything</h2>
|
||||
<PaginationProvider
|
||||
pagination={
|
||||
paginationFactory(options)
|
||||
}
|
||||
>
|
||||
{ contentTable }
|
||||
</PaginationProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div >
|
||||
);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default class Table extends React.Component {
|
||||
state = { products }
|
||||
|
||||
loadData = () => {
|
||||
this.setState({ products: productsGenerator(17) });
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = {
|
||||
custom: true,
|
||||
paginationSize: 4,
|
||||
pageStartIndex: 1,
|
||||
firstPageText: 'First',
|
||||
prePageText: 'Back',
|
||||
nextPageText: 'Next',
|
||||
lastPageText: 'Last',
|
||||
nextPageTitle: 'First page',
|
||||
prePageTitle: 'Pre page',
|
||||
firstPageTitle: 'Next page',
|
||||
lastPageTitle: 'Last page',
|
||||
showTotal: true,
|
||||
totalSize: this.state.products.length
|
||||
};
|
||||
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
||||
<div>
|
||||
<button className="btn btn-default" onClick={ this.loadData }>Load Another Data</button>
|
||||
<PaginationListStandalone { ...paginationProps } />
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
columns={ columns }
|
||||
data={ this.state.products }
|
||||
search
|
||||
>
|
||||
{
|
||||
toolkitprops => (
|
||||
<div>
|
||||
<SearchBar { ...toolkitprops.searchProps } />
|
||||
<BootstrapTable
|
||||
striped
|
||||
hover
|
||||
{ ...toolkitprops.baseProps }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<PaginationListStandalone { ...paginationProps } />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>PaginationProvider will care the data size change. You dont do anything</h2>
|
||||
<PaginationProvider
|
||||
pagination={
|
||||
paginationFactory(options)
|
||||
}
|
||||
>
|
||||
{ contentTable }
|
||||
</PaginationProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div >
|
||||
);
|
||||
}
|
||||
}
|
||||
78
packages/react-bootstrap-table2-example/examples/pagination/custom-page-list.js
vendored
Normal file
78
packages/react-bootstrap-table2-example/examples/pagination/custom-page-list.js
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
/* eslint react/prop-types: 0 */
|
||||
/* eslint jsx-a11y/href-no-hash: 0 */
|
||||
/* eslint jsx-a11y/no-noninteractive-element-interactions: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(87);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
// ...
|
||||
|
||||
const pageListRenderer = ({
|
||||
pages,
|
||||
onPageChange
|
||||
}) => {
|
||||
const pageWithoutIndication = pages.filter(p => typeof p.page !== 'string');
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
pageWithoutIndication.map(p => (
|
||||
<button className="btn btn-success" onClick={ () => onPageChange(p.page) }>{ p.page }</button>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const options = {
|
||||
pageListRenderer
|
||||
};
|
||||
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory(options) } />
|
||||
`;
|
||||
|
||||
const pageListRenderer = ({
|
||||
pages,
|
||||
onPageChange
|
||||
}) => {
|
||||
const pageWithoutIndication = pages.filter(p => typeof p.page !== 'string');
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
pageWithoutIndication.map(p => (
|
||||
<button className="btn btn-success" onClick={ () => onPageChange(p.page) }>{ p.page }</button>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const options = {
|
||||
pageListRenderer
|
||||
};
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory(options) } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
96
packages/react-bootstrap-table2-example/examples/pagination/custom-size-per-page-option.js
vendored
Normal file
96
packages/react-bootstrap-table2-example/examples/pagination/custom-size-per-page-option.js
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
/* eslint jsx-a11y/href-no-hash: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(87);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
// ...
|
||||
|
||||
const sizePerPageOptionRenderer = ({
|
||||
text,
|
||||
page,
|
||||
onSizePerPageChange
|
||||
}) => (
|
||||
<li
|
||||
key={ text }
|
||||
role="presentation"
|
||||
className="dropdown-item"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
tabIndex="-1"
|
||||
role="menuitem"
|
||||
data-page={ page }
|
||||
onMouseDown={ (e) => {
|
||||
e.preventDefault();
|
||||
onSizePerPageChange(page);
|
||||
} }
|
||||
style={ { color: 'red' } }
|
||||
>
|
||||
{ text }
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
|
||||
const options = {
|
||||
sizePerPageOptionRenderer
|
||||
};
|
||||
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory(options) } />
|
||||
`;
|
||||
|
||||
const sizePerPageOptionRenderer = ({
|
||||
text,
|
||||
page,
|
||||
onSizePerPageChange
|
||||
}) => (
|
||||
<li
|
||||
key={ text }
|
||||
role="presentation"
|
||||
className="dropdown-item"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
tabIndex="-1"
|
||||
role="menuitem"
|
||||
data-page={ page }
|
||||
onMouseDown={ (e) => {
|
||||
e.preventDefault();
|
||||
onSizePerPageChange(page);
|
||||
} }
|
||||
style={ { color: 'red' } }
|
||||
>
|
||||
{ text }
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
|
||||
const options = {
|
||||
sizePerPageOptionRenderer
|
||||
};
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory(options) } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
89
packages/react-bootstrap-table2-example/examples/pagination/custom-size-per-page.js
vendored
Normal file
89
packages/react-bootstrap-table2-example/examples/pagination/custom-size-per-page.js
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
/* eslint jsx-a11y/href-no-hash: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(87);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
// ...
|
||||
|
||||
const sizePerPageRenderer = ({
|
||||
options,
|
||||
currSizePerPage,
|
||||
onSizePerPageChange
|
||||
}) => (
|
||||
<div className="btn-group" role="group">
|
||||
{
|
||||
options.map((option) => {
|
||||
const isSelect = currSizePerPage === \`$\{option.page}\`;
|
||||
return (
|
||||
<button
|
||||
key={ option.text }
|
||||
type="button"
|
||||
onClick={ () => onSizePerPageChange(option.page) }
|
||||
className={ \`btn $\{isSelect ? 'btn-secondary' : 'btn-warning'}\` }
|
||||
>
|
||||
{ option.text }
|
||||
</button>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
const options = {
|
||||
sizePerPageRenderer
|
||||
};
|
||||
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory(options) } />s
|
||||
`;
|
||||
|
||||
const sizePerPageRenderer = ({
|
||||
options,
|
||||
currSizePerPage,
|
||||
onSizePerPageChange
|
||||
}) => (
|
||||
<div className="btn-group" role="group">
|
||||
{
|
||||
options.map(option => (
|
||||
<button
|
||||
key={ option.text }
|
||||
type="button"
|
||||
onClick={ () => onSizePerPageChange(option.page) }
|
||||
className={ `btn ${currSizePerPage === `${option.page}` ? 'btn-secondary' : 'btn-warning'}` }
|
||||
>
|
||||
{ option.text }
|
||||
</button>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
const options = {
|
||||
sizePerPageRenderer
|
||||
};
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory(options) } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
181
packages/react-bootstrap-table2-example/examples/pagination/custome-page-list-with-filter.js
vendored
Normal file
181
packages/react-bootstrap-table2-example/examples/pagination/custome-page-list-with-filter.js
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
import filterFactory, { textFilter, selectFilter } from 'react-bootstrap-table2-filter';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsQualityGenerator } from 'utils/common';
|
||||
|
||||
const products = productsQualityGenerator(21);
|
||||
|
||||
const selectOptions = {
|
||||
0: 'good',
|
||||
1: 'Bad',
|
||||
2: 'unknown'
|
||||
};
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter()
|
||||
}, {
|
||||
dataField: 'quality',
|
||||
text: 'Product Quailty',
|
||||
formatter: cell => selectOptions[cell],
|
||||
filter: selectFilter({
|
||||
options: selectOptions,
|
||||
defaultValue: 0
|
||||
})
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
import filterFactory, { textFilter, selectFilter } from 'react-bootstrap-table2-filter';
|
||||
|
||||
const selectOptions = {
|
||||
0: 'good',
|
||||
1: 'Bad',
|
||||
2: 'unknown'
|
||||
};
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
filter: textFilter()
|
||||
}, {
|
||||
dataField: 'quality',
|
||||
text: 'Product Quailty',
|
||||
formatter: cell => selectOptions[cell],
|
||||
filter: selectFilter({
|
||||
options: selectOptions,
|
||||
defaultValue: 0
|
||||
})
|
||||
}];
|
||||
|
||||
class Table extends React.Component {
|
||||
state = { products }
|
||||
|
||||
loadData = () => {
|
||||
this.setState({ products: productsQualityGenerator(40, 7) });
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = {
|
||||
custom: true,
|
||||
paginationSize: 4,
|
||||
pageStartIndex: 1,
|
||||
firstPageText: 'First',
|
||||
prePageText: 'Back',
|
||||
nextPageText: 'Next',
|
||||
lastPageText: 'Last',
|
||||
nextPageTitle: 'First page',
|
||||
prePageTitle: 'Pre page',
|
||||
firstPageTitle: 'Next page',
|
||||
lastPageTitle: 'Last page',
|
||||
showTotal: true,
|
||||
totalSize: this.state.products.length
|
||||
};
|
||||
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
||||
<div>
|
||||
<button className="btn btn-default" onClick={ this.loadData }>Load Another Data</button>
|
||||
<PaginationListStandalone { ...paginationProps } />
|
||||
<div>
|
||||
<div>
|
||||
<BootstrapTable
|
||||
striped
|
||||
hover
|
||||
keyField="id"
|
||||
data={ this.state.products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<PaginationListStandalone { ...paginationProps } />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>PaginationProvider will care the data size change. You dont do anything</h2>
|
||||
<PaginationProvider
|
||||
pagination={
|
||||
paginationFactory(options)
|
||||
}
|
||||
>
|
||||
{ contentTable }
|
||||
</PaginationProvider>
|
||||
</div >
|
||||
);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default class Table extends React.Component {
|
||||
state = { products }
|
||||
|
||||
loadData = () => {
|
||||
this.setState({ products: productsQualityGenerator(40, 7) });
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = {
|
||||
custom: true,
|
||||
paginationSize: 4,
|
||||
pageStartIndex: 1,
|
||||
firstPageText: 'First',
|
||||
prePageText: 'Back',
|
||||
nextPageText: 'Next',
|
||||
lastPageText: 'Last',
|
||||
nextPageTitle: 'First page',
|
||||
prePageTitle: 'Pre page',
|
||||
firstPageTitle: 'Next page',
|
||||
lastPageTitle: 'Last page',
|
||||
showTotal: true,
|
||||
totalSize: this.state.products.length
|
||||
};
|
||||
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
||||
<div>
|
||||
<button className="btn btn-default" onClick={ this.loadData }>Load Another Data</button>
|
||||
<PaginationListStandalone { ...paginationProps } />
|
||||
<div>
|
||||
<div>
|
||||
<BootstrapTable
|
||||
striped
|
||||
hover
|
||||
keyField="id"
|
||||
data={ this.state.products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<PaginationListStandalone { ...paginationProps } />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>PaginationProvider will care the data size change. You dont do anything</h2>
|
||||
<PaginationProvider
|
||||
pagination={
|
||||
paginationFactory(options)
|
||||
}
|
||||
>
|
||||
{ contentTable }
|
||||
</PaginationProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div >
|
||||
);
|
||||
}
|
||||
}
|
||||
166
packages/react-bootstrap-table2-example/examples/pagination/fully-custom-pagination.js
vendored
Normal file
166
packages/react-bootstrap-table2-example/examples/pagination/fully-custom-pagination.js
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider } from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(87);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const options = {
|
||||
custom: true,
|
||||
totalSize: products.length
|
||||
};
|
||||
|
||||
class FullyCustomPagination extends React.Component {
|
||||
handleNextPage = ({
|
||||
page,
|
||||
onPageChange
|
||||
}) => () => {
|
||||
onPageChange(page + 1);
|
||||
}
|
||||
|
||||
handlePrevPage = ({
|
||||
page,
|
||||
onPageChange
|
||||
}) => () => {
|
||||
onPageChange(page - 1);
|
||||
}
|
||||
|
||||
handleSizePerPage = ({
|
||||
page,
|
||||
onSizePerPageChange
|
||||
}, newSizePerPage) => {
|
||||
onSizePerPageChange(newSizePerPage, page);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<div>
|
||||
<p>Current Page: { paginationProps.page }</p>
|
||||
<p>Current SizePerPage: { paginationProps.sizePerPage }</p>
|
||||
</div>
|
||||
<div className="btn-group" role="group">
|
||||
<button className="btn btn-primary" onClick={ this.handleNextPage(paginationProps) }>Next Page</button>
|
||||
<button className="btn btn-success" onClick={ this.handlePrevPage(paginationProps) }>Prev Page</button>
|
||||
<button className="btn btn-danger" onClick={ () => this.handleSizePerPage(paginationProps, 10) }>Size Per Page: 10</button>
|
||||
<button className="btn btn-warning" onClick={ () => this.handleSizePerPage(paginationProps, 25) }>Size Per Page: 25</button>
|
||||
</div>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const options = {
|
||||
custom: true,
|
||||
totalSize: products.length
|
||||
};
|
||||
|
||||
export default class FullyCustomPagination extends React.Component {
|
||||
handleNextPage = ({
|
||||
page,
|
||||
onPageChange
|
||||
}) => () => {
|
||||
onPageChange(page + 1);
|
||||
}
|
||||
|
||||
handlePrevPage = ({
|
||||
page,
|
||||
onPageChange
|
||||
}) => () => {
|
||||
onPageChange(page - 1);
|
||||
}
|
||||
|
||||
handleSizePerPage = ({
|
||||
page,
|
||||
onSizePerPageChange
|
||||
}, newSizePerPage) => {
|
||||
onSizePerPageChange(newSizePerPage, page);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<div>
|
||||
<p>Current Page: { paginationProps.page }</p>
|
||||
<p>Current SizePerPage: { paginationProps.sizePerPage }</p>
|
||||
</div>
|
||||
<div className="btn-group" role="group">
|
||||
<button className="btn btn-primary" onClick={ this.handleNextPage(paginationProps) }>Next Page</button>
|
||||
<button className="btn btn-success" onClick={ this.handlePrevPage(paginationProps) }>Prev Page</button>
|
||||
<button className="btn btn-danger" onClick={ () => this.handleSizePerPage(paginationProps, 10) }>Size Per Page: 10</button>
|
||||
<button className="btn btn-warning" onClick={ () => this.handleSizePerPage(paginationProps, 25) }>Size Per Page: 25</button>
|
||||
</div>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
150
packages/react-bootstrap-table2-example/examples/pagination/pagination-with-dynamic-data.js
vendored
Normal file
150
packages/react-bootstrap-table2-example/examples/pagination/pagination-with-dynamic-data.js
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
|
||||
class BookList extends React.Component {
|
||||
state = {
|
||||
books: [
|
||||
{ id: '1', name: 'Book 1' },
|
||||
{ id: '2', name: 'Book 2' },
|
||||
{ id: '3', name: 'Book 3' },
|
||||
{ id: '4', name: 'Book 4' },
|
||||
{ id: '5', name: 'Book 5' },
|
||||
{ id: '6', name: 'Book 6' }
|
||||
]
|
||||
};
|
||||
|
||||
deleteBookWithId = () => {
|
||||
const lastOneId = this.state.books.length;
|
||||
const updatedBooks = this.state.books.filter(m => m.id !== lastOneId.toString());
|
||||
this.setState({ books: updatedBooks });
|
||||
};
|
||||
|
||||
addBook = () => {
|
||||
const lastOneId = this.state.books.length + 1;
|
||||
this.setState({ books: [...this.state.books, {
|
||||
id: \`$\{lastOneId}\`, name: \`Book $\{lastOneId}\`
|
||||
}] });
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = {
|
||||
// pageStartIndex: 0,
|
||||
sizePerPage: 5,
|
||||
hideSizePerPage: true,
|
||||
hidePageListOnlyOnePage: true
|
||||
};
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
Cell: row => (
|
||||
<div>
|
||||
<span title={ row.value }>{ row.value }</span>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ this.state.books }
|
||||
columns={ columns }
|
||||
pagination={ paginationFactory(options) }
|
||||
/>
|
||||
<button className="btn btn-default" onClick={ () => this.deleteBookWithId() }>
|
||||
delete last one book
|
||||
</button>
|
||||
<button className="btn btn-default" onClick={ () => this.addBook() }>
|
||||
Add a book to the end
|
||||
</button>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
`;
|
||||
|
||||
export default class BookList extends React.Component {
|
||||
state = {
|
||||
books: [
|
||||
{ id: '1', name: 'Book 1' },
|
||||
{ id: '2', name: 'Book 2' },
|
||||
{ id: '3', name: 'Book 3' },
|
||||
{ id: '4', name: 'Book 4' },
|
||||
{ id: '5', name: 'Book 5' },
|
||||
{ id: '6', name: 'Book 6' },
|
||||
{ id: '7', name: 'Book 6' },
|
||||
{ id: '8', name: 'Book 6' },
|
||||
{ id: '9', name: 'Book 6' },
|
||||
{ id: '10', name: 'Book 6' },
|
||||
{ id: '11', name: 'Book 6' }
|
||||
]
|
||||
};
|
||||
|
||||
deleteBookWithId = () => {
|
||||
const lastOneId = this.state.books.length;
|
||||
const updatedBooks = this.state.books.filter(m => m.id !== lastOneId.toString());
|
||||
this.setState({ books: updatedBooks });
|
||||
};
|
||||
|
||||
addBook = () => {
|
||||
const lastOneId = this.state.books.length + 1;
|
||||
this.setState({ books: [...this.state.books, {
|
||||
id: `${lastOneId}`, name: `Book ${lastOneId}`
|
||||
}] });
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = {
|
||||
// pageStartIndex: 0,
|
||||
sizePerPage: 5,
|
||||
hideSizePerPage: true,
|
||||
hidePageListOnlyOnePage: true
|
||||
};
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
Cell: row => (
|
||||
<div>
|
||||
<span title={ row.value }>{ row.value }</span>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ this.state.books }
|
||||
columns={ columns }
|
||||
pagination={ paginationFactory(options) }
|
||||
/>
|
||||
<button className="btn btn-default" onClick={ () => this.deleteBookWithId() }>
|
||||
delete last one book
|
||||
</button>
|
||||
<button className="btn btn-default" onClick={ () => this.addBook() }>
|
||||
Add a book to the end
|
||||
</button>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
190
packages/react-bootstrap-table2-example/examples/pagination/remote-standalone-pagination.js
vendored
Normal file
190
packages/react-bootstrap-table2-example/examples/pagination/remote-standalone-pagination.js
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
/* eslint react/no-multi-comp: 0 */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(87);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
// ...
|
||||
const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
|
||||
<div>
|
||||
<PaginationProvider
|
||||
pagination={
|
||||
paginationFactory({
|
||||
custom: true,
|
||||
page,
|
||||
sizePerPage,
|
||||
totalSize
|
||||
})
|
||||
}
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<div>
|
||||
<p>Current Page: { paginationProps.page }</p>
|
||||
<p>Current SizePerPage: { paginationProps.sizePerPage }</p>
|
||||
</div>
|
||||
<div>
|
||||
<PaginationListStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
</div>
|
||||
<BootstrapTable
|
||||
remote
|
||||
keyField="id"
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
onTableChange={ onTableChange }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
</div>
|
||||
);
|
||||
|
||||
class Container extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
page: 1,
|
||||
data: products.slice(0, 10),
|
||||
sizePerPage: 10
|
||||
};
|
||||
}
|
||||
|
||||
handleTableChange = (type, { page, sizePerPage }) => {
|
||||
const currentIndex = (page - 1) * sizePerPage;
|
||||
setTimeout(() => {
|
||||
this.setState(() => ({
|
||||
page,
|
||||
data: products.slice(currentIndex, currentIndex + sizePerPage),
|
||||
sizePerPage
|
||||
}));
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data, sizePerPage, page } = this.state;
|
||||
return (
|
||||
<RemotePagination
|
||||
data={ data }
|
||||
page={ page }
|
||||
sizePerPage={ sizePerPage }
|
||||
totalSize={ products.length }
|
||||
onTableChange={ this.handleTableChange }
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
|
||||
<div>
|
||||
<PaginationProvider
|
||||
pagination={
|
||||
paginationFactory({
|
||||
custom: true,
|
||||
page,
|
||||
sizePerPage,
|
||||
totalSize
|
||||
})
|
||||
}
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<div>
|
||||
<p>Current Page: { paginationProps.page }</p>
|
||||
<p>Current SizePerPage: { paginationProps.sizePerPage }</p>
|
||||
</div>
|
||||
<div>
|
||||
<PaginationListStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
</div>
|
||||
<BootstrapTable
|
||||
remote
|
||||
keyField="id"
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
onTableChange={ onTableChange }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
|
||||
RemotePagination.propTypes = {
|
||||
data: PropTypes.array.isRequired,
|
||||
page: PropTypes.number.isRequired,
|
||||
totalSize: PropTypes.number.isRequired,
|
||||
sizePerPage: PropTypes.number.isRequired,
|
||||
onTableChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
class Container extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
page: 1,
|
||||
data: products.slice(0, 10),
|
||||
sizePerPage: 10
|
||||
};
|
||||
}
|
||||
|
||||
handleTableChange = (type, { page, sizePerPage }) => {
|
||||
const currentIndex = (page - 1) * sizePerPage;
|
||||
setTimeout(() => {
|
||||
this.setState(() => ({
|
||||
page,
|
||||
data: products.slice(currentIndex, currentIndex + sizePerPage),
|
||||
sizePerPage
|
||||
}));
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data, sizePerPage, page } = this.state;
|
||||
return (
|
||||
<RemotePagination
|
||||
data={ data }
|
||||
page={ page }
|
||||
sizePerPage={ sizePerPage }
|
||||
totalSize={ products.length }
|
||||
onTableChange={ this.handleTableChange }
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Container;
|
||||
102
packages/react-bootstrap-table2-example/examples/pagination/standalone-pagination-list.js
vendored
Normal file
102
packages/react-bootstrap-table2-example/examples/pagination/standalone-pagination-list.js
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(87);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const options = {
|
||||
custom: true,
|
||||
totalSize: products.length
|
||||
};
|
||||
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<PaginationListStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
`;
|
||||
|
||||
const options = {
|
||||
custom: true,
|
||||
totalSize: products.length
|
||||
};
|
||||
// const pagination = paginationFactory(options);
|
||||
|
||||
export default class StandalonePaginationList extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<PaginationListStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
107
packages/react-bootstrap-table2-example/examples/pagination/standalone-pagination-total.js
vendored
Normal file
107
packages/react-bootstrap-table2-example/examples/pagination/standalone-pagination-total.js
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationTotalStandalone, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(87);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, PaginationTotalStandalone, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const options = {
|
||||
custom: true,
|
||||
totalSize: products.length
|
||||
};
|
||||
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<PaginationTotalStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
<PaginationListStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
`;
|
||||
|
||||
const options = {
|
||||
custom: true,
|
||||
totalSize: products.length
|
||||
};
|
||||
|
||||
export default class StandalonePaginationList extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<PaginationTotalStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
<PaginationListStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
103
packages/react-bootstrap-table2-example/examples/pagination/standalone-size-per-page.js
vendored
Normal file
103
packages/react-bootstrap-table2-example/examples/pagination/standalone-size-per-page.js
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, SizePerPageDropdownStandalone } from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(87);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory, { PaginationProvider, SizePerPageDropdownStandalone } from 'react-bootstrap-table2-paginator';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const options = {
|
||||
custom: true,
|
||||
totalSize: products.length
|
||||
};
|
||||
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<SizePerPageDropdownStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
`;
|
||||
|
||||
const options = {
|
||||
custom: true,
|
||||
totalSize: products.length
|
||||
};
|
||||
// const pagination = paginationFactory(options);
|
||||
|
||||
export default class StandaloneSizePerPage extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<SizePerPageDropdownStandalone
|
||||
{ ...paginationProps }
|
||||
btnContextual="btn btn-primary"
|
||||
/>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
/* eslint no-unused-vars: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
@@ -33,7 +34,7 @@ const expandRow = {
|
||||
}
|
||||
return <b>+</b>;
|
||||
},
|
||||
expandColumnRenderer: ({ expanded }) => {
|
||||
expandColumnRenderer: ({ expanded, rowKey, expandable }) => {
|
||||
if (expanded) {
|
||||
return (
|
||||
<b>-</b>
|
||||
|
||||
@@ -51,7 +51,8 @@ const expandRow = {
|
||||
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||
</div>
|
||||
),
|
||||
showExpandColumn: true
|
||||
showExpandColumn: true,
|
||||
expandByColumnOnly: true
|
||||
};
|
||||
|
||||
<BootstrapTable
|
||||
|
||||
76
packages/react-bootstrap-table2-example/examples/row-expand/expand-column-position.js
vendored
Normal file
76
packages/react-bootstrap-table2-example/examples/row-expand/expand-column-position.js
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsExpandRowsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsExpandRowsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const expandRow = {
|
||||
renderer: row => (
|
||||
<div>
|
||||
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p>
|
||||
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||
</div>
|
||||
),
|
||||
showExpandColumn: true,
|
||||
expandColumnPosition: 'right'
|
||||
};
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const expandRow = {
|
||||
renderer: row => (
|
||||
<div>
|
||||
<p>{ \`This Expand row is belong to rowKey $\{row.id}\` }</p>
|
||||
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||
</div>
|
||||
),
|
||||
showExpandColumn: true,
|
||||
expandColumnPosition: 'right'
|
||||
};
|
||||
|
||||
<BootstrapTable
|
||||
keyField='id'
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
expandRow={ expandRow }
|
||||
/>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
expandRow={ expandRow }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
@@ -43,6 +43,7 @@ const columns = [{
|
||||
}];
|
||||
|
||||
const expandRow = {
|
||||
onlyOneExpanding: true,
|
||||
renderer: row => (
|
||||
<div>
|
||||
<p>{ \`This Expand row is belong to rowKey $\{row.id}\` }</p>
|
||||
|
||||
@@ -25,6 +25,7 @@ const expandRow = {
|
||||
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||
</div>
|
||||
),
|
||||
showExpandColumn: true,
|
||||
nonExpandable: [1, 3]
|
||||
};
|
||||
|
||||
@@ -50,6 +51,7 @@ const expandRow = {
|
||||
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||
</div>
|
||||
),
|
||||
showExpandColumn: true,
|
||||
nonExpandable: [1, 3]
|
||||
};
|
||||
|
||||
|
||||
111
packages/react-bootstrap-table2-example/examples/row-selection/header-style.js
vendored
Normal file
111
packages/react-bootstrap-table2-example/examples/row-selection/header-style.js
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(2);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const selectRow1 = {
|
||||
mode: 'checkbox',
|
||||
clickToSelect: true,
|
||||
headerColumnStyle: {
|
||||
backgroundColor: 'blue'
|
||||
}
|
||||
};
|
||||
|
||||
const sourceCode1 = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = ...
|
||||
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
clickToSelect: true,
|
||||
headerColumnStyle: {
|
||||
backgroundColor: 'blue'
|
||||
}
|
||||
};
|
||||
|
||||
<BootstrapTable
|
||||
keyField='id'
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
selectRow={ selectRow }
|
||||
/>
|
||||
`;
|
||||
|
||||
const selectRow2 = {
|
||||
mode: 'checkbox',
|
||||
clickToSelect: true,
|
||||
headerColumnStyle: (status) => {
|
||||
if (status === 'checked') {
|
||||
return {
|
||||
backgroundColor: 'yellow'
|
||||
};
|
||||
} else if (status === 'indeterminate') {
|
||||
return {
|
||||
backgroundColor: 'pink'
|
||||
};
|
||||
} else if (status === 'unchecked') {
|
||||
return {
|
||||
backgroundColor: 'grey'
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
const sourceCode2 = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = ...
|
||||
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
clickToSelect: true,
|
||||
headerColumnStyle: (status) => {
|
||||
if (status === 'checked') {
|
||||
return {
|
||||
backgroundColor: 'yellow'
|
||||
};
|
||||
} else if (status === 'indeterminate') {
|
||||
return {
|
||||
backgroundColor: 'pink'
|
||||
};
|
||||
} else if (status === 'unchecked') {
|
||||
return {
|
||||
backgroundColor: 'grey'
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
<BootstrapTable
|
||||
keyField='id'
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
selectRow={ selectRow }
|
||||
/>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } selectRow={ selectRow1 } />
|
||||
<Code>{ sourceCode1 }</Code>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } selectRow={ selectRow2 } />
|
||||
<Code>{ sourceCode2 }</Code>
|
||||
</div>
|
||||
);
|
||||
88
packages/react-bootstrap-table2-example/examples/row-selection/selection-advance-management.js
vendored
Normal file
88
packages/react-bootstrap-table2-example/examples/row-selection/selection-advance-management.js
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/* eslint no-alert: 0 */
|
||||
/* eslint consistent-return: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
class AdvSelectionManagment extends React.Component {
|
||||
handleOnSelect = (row, isSelect) => {
|
||||
if (isSelect && row.id < 3) {
|
||||
alert('Oops, You can not select Product ID which less than 3');
|
||||
return false; // return false to deny current select action
|
||||
}
|
||||
return true; // return true or dont return to approve current select action
|
||||
}
|
||||
|
||||
handleOnSelectAll = (isSelect, rows) => {
|
||||
if (isSelect) {
|
||||
return rows.filter(r => r.id >= 3).map(r => r.id);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
clickToSelect: true,
|
||||
onSelect: this.handleOnSelect,
|
||||
onSelectAll: this.handleOnSelectAll
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<h3>You can not select Product ID less than 3</h3>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } selectRow={ selectRow } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default class AdvSelectionManagment extends React.Component {
|
||||
handleOnSelect = (row, isSelect) => {
|
||||
if (isSelect && row.id < 3) {
|
||||
alert('Oops, You can not select Product ID which less than 3');
|
||||
return false; // return false to deny current select action
|
||||
}
|
||||
return true; // return true or dont return to approve current select action
|
||||
}
|
||||
|
||||
handleOnSelectAll = (isSelect, rows) => {
|
||||
if (isSelect) {
|
||||
return rows.filter(r => r.id >= 3).map(r => r.id);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
clickToSelect: true,
|
||||
onSelect: this.handleOnSelect,
|
||||
onSelectAll: this.handleOnSelectAll
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<h3>You can not select Product ID less than 3</h3>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } selectRow={ selectRow } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
57
packages/react-bootstrap-table2-example/examples/rows/row-hidden.js
vendored
Normal file
57
packages/react-bootstrap-table2-example/examples/rows/row-hidden.js
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/* eslint no-unused-vars: 0 */
|
||||
/* eslint no-console: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const rowEvents = {
|
||||
onClick: (e, row, rowIndex) => {
|
||||
console.log(`clicked on row with index: ${rowIndex}`);
|
||||
},
|
||||
onMouseEnter: (e, row, rowIndex) => {
|
||||
console.log(`enter on row with index: ${rowIndex}`);
|
||||
}
|
||||
};
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const hiddenRowKeys = [1, 3];
|
||||
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } hiddenRows={ hiddenRowKeys } />
|
||||
`;
|
||||
|
||||
const hiddenRowKeys = [1, 3];
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } hiddenRows={ hiddenRowKeys } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
86
packages/react-bootstrap-table2-example/examples/search/clear-search-button.js
vendored
Normal file
86
packages/react-bootstrap-table2-example/examples/search/clear-search-button.js
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { SearchBar, ClearSearchButton } = Search;
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const { SearchBar, ClearSearchButton } = Search;
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
search
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<h3>Input something at below input field:</h3>
|
||||
<SearchBar { ...props.searchProps } />
|
||||
<ClearSearchButton { ...props.searchProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
search
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<h3>Input something at below input field:</h3>
|
||||
<SearchBar { ...props.searchProps } />
|
||||
<ClearSearchButton { ...props.searchProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-example",
|
||||
"version": "1.0.8",
|
||||
"version": "1.0.25",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* eslint no-mixed-operators: 0 */
|
||||
/* eslint no-param-reassign: 0 */
|
||||
|
||||
/**
|
||||
* products generator for stories
|
||||
@@ -22,10 +23,16 @@ export const productsGenerator = (quantity = 5, callback) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const productsQualityGenerator = (quantity = 5) =>
|
||||
export const withOnSale = rows => rows.map((row) => {
|
||||
if (row.id > 2) row.onSale = false;
|
||||
else row.onSale = true;
|
||||
return row;
|
||||
});
|
||||
|
||||
export const productsQualityGenerator = (quantity = 5, factor = 0) =>
|
||||
Array.from({ length: quantity }, (value, index) => ({
|
||||
id: index,
|
||||
name: `Item name ${index}`,
|
||||
id: index + factor,
|
||||
name: `Item name ${index + factor}`,
|
||||
quality: index % 3
|
||||
}));
|
||||
|
||||
@@ -63,6 +70,7 @@ export const stockGenerator = (quantity = 5) =>
|
||||
Array.from({ length: quantity }, (value, index) => ({
|
||||
id: index,
|
||||
name: `Todo item ${index}`,
|
||||
price: Math.floor((Math.random() * 2) + 1),
|
||||
inStockDate:
|
||||
new Date(startDate.getTime() + Math.random() * (endDate.getTime() - startDate.getTime()))
|
||||
}));
|
||||
|
||||
@@ -20,6 +20,8 @@ import TabIndexCellTable from 'examples/basic/tabindex-column';
|
||||
import Bootstrap4DefaultSortTable from 'examples/bootstrap4/sort';
|
||||
import Bootstrap4RowSelectionTable from 'examples/bootstrap4/row-selection';
|
||||
import Bootstrap4PaginationTable from 'examples/bootstrap4/pagination';
|
||||
import Bootstrap4ColumnToggleTable from 'examples/bootstrap4/column-toggle';
|
||||
import ToolkitsTable from 'examples/bootstrap4/toolkits';
|
||||
|
||||
// work on columns
|
||||
import NestedDataTable from 'examples/columns/nested-data-table';
|
||||
@@ -45,6 +47,18 @@ import HeaderColumnStyleTable from 'examples/header-columns/column-style-table';
|
||||
import HeaderColumnAttrsTable from 'examples/header-columns/column-attrs-table';
|
||||
import HeaderClassTable from 'examples/header-columns/header-class-table';
|
||||
|
||||
// footer
|
||||
import SimpleFooter from 'examples/footer/simple-footer';
|
||||
import FunctionFooter from 'examples/footer/function-footer';
|
||||
import FooterClassTable from 'examples/footer/footer-class-table';
|
||||
import FooterColumnFormatTable from 'examples/footer/column-format-table';
|
||||
import FooterColumnAlignTable from 'examples/footer/column-align-table';
|
||||
import FooterColumnTitleTable from 'examples/footer/column-title-table.js';
|
||||
import FooterColumnEventsTable from 'examples/footer/column-event-table.js';
|
||||
import FooterColumnClassTable from 'examples/footer/column-class-table.js';
|
||||
import FooterColumnStyleTable from 'examples/footer/column-style-table.js';
|
||||
import FooterColumnAttrsTable from 'examples/footer/column-attrs-table.js';
|
||||
|
||||
// column filter
|
||||
import TextFilter from 'examples/column-filter/text-filter';
|
||||
import TextFilterWithDefaultValue from 'examples/column-filter/text-filter-default-value';
|
||||
@@ -55,6 +69,7 @@ import CustomFilterValue from 'examples/column-filter/custom-filter-value';
|
||||
import SelectFilter from 'examples/column-filter/select-filter';
|
||||
import SelectFilterWithDefaultValue from 'examples/column-filter/select-filter-default-value';
|
||||
import SelectFilterComparator from 'examples/column-filter/select-filter-like-comparator';
|
||||
import SelectFilterWithPreservedOptionsOrder from 'examples/column-filter/select-filter-preserve-option-order';
|
||||
import CustomSelectFilter from 'examples/column-filter/custom-select-filter';
|
||||
import MultiSelectFilter from 'examples/column-filter/multi-select-filter';
|
||||
import MultiSelectFilterDefaultValue from 'examples/column-filter/multi-select-filter-default-value';
|
||||
@@ -73,11 +88,14 @@ import ProgrammaticallyMultiSelectFilter from 'examples/column-filter/programmat
|
||||
import CustomFilter from 'examples/column-filter/custom-filter';
|
||||
import AdvanceCustomFilter from 'examples/column-filter/advance-custom-filter';
|
||||
import ClearAllFilters from 'examples/column-filter/clear-all-filters';
|
||||
import FilterHooks from 'examples/column-filter/filter-hooks';
|
||||
import CustomFilterLogic from 'examples/column-filter/custom-filter-logic';
|
||||
|
||||
// work on rows
|
||||
import RowStyleTable from 'examples/rows/row-style';
|
||||
import RowClassTable from 'examples/rows/row-class';
|
||||
import RowEventTable from 'examples/rows/row-event';
|
||||
import RowHiddenTable from 'examples/rows/row-hidden';
|
||||
|
||||
// table sort
|
||||
import EnableSortTable from 'examples/sort/enable-sort-table';
|
||||
@@ -118,11 +136,13 @@ import MultipleSelectionTable from 'examples/row-selection/multiple-selection';
|
||||
import ClickToSelectTable from 'examples/row-selection/click-to-select';
|
||||
import DefaultSelectTable from 'examples/row-selection/default-select';
|
||||
import SelectionManagement from 'examples/row-selection/selection-management';
|
||||
import AdvanceSelectionManagement from 'examples/row-selection/selection-advance-management';
|
||||
import ClickToSelectWithCellEditTable from 'examples/row-selection/click-to-select-with-cell-edit';
|
||||
import SelectionWithExpansionTable from 'examples/row-selection/selection-with-expansion';
|
||||
import SelectionNoDataTable from 'examples/row-selection/selection-no-data';
|
||||
import SelectionStyleTable from 'examples/row-selection/selection-style';
|
||||
import SelectionClassTable from 'examples/row-selection/selection-class';
|
||||
import HeaderStyleTable from 'examples/row-selection/header-style';
|
||||
import HideSelectAllTable from 'examples/row-selection/hide-select-all';
|
||||
import CustomSelectionTable from 'examples/row-selection/custom-selection';
|
||||
import NonSelectableRowsTable from 'examples/row-selection/non-selectable-rows';
|
||||
@@ -138,15 +158,29 @@ import ExpandColumn from 'examples/row-expand/expand-column';
|
||||
import OnlyExpandByColumn from 'examples/row-expand/expand-by-column-only.js';
|
||||
import ExpandOnlyOne from 'examples/row-expand/expand-only-one';
|
||||
import CustomExpandColumn from 'examples/row-expand/custom-expand-column';
|
||||
import ExpandColumnPosition from 'examples/row-expand/expand-column-position';
|
||||
import ExpandHooks from 'examples/row-expand/expand-hooks';
|
||||
|
||||
// pagination
|
||||
import PaginationTable from 'examples/pagination';
|
||||
import PaginationHooksTable from 'examples/pagination/pagination-hooks';
|
||||
import PaginationWithDynamicData from 'examples/pagination/pagination-with-dynamic-data';
|
||||
import CustomPaginationTable from 'examples/pagination/custom-pagination';
|
||||
import CustomPageButtonTable from 'examples/pagination/custom-page-button';
|
||||
import CustomSizePerPageOptionTable from 'examples/pagination/custom-size-per-page-option';
|
||||
import CustomSizePerPageTable from 'examples/pagination/custom-size-per-page';
|
||||
import CustomPageListTable from 'examples/pagination/custom-page-list';
|
||||
import StandalonePaginationList from 'examples/pagination/standalone-pagination-list';
|
||||
import StandaloneSizePerPage from 'examples/pagination/standalone-size-per-page';
|
||||
import StandalonePaginationTotal from 'examples/pagination/standalone-pagination-total';
|
||||
import FullyCustomPaginationTable from 'examples/pagination/fully-custom-pagination';
|
||||
import RemoteStandalonePaginationTable from 'examples/pagination/remote-standalone-pagination';
|
||||
import CustomePaginationWithFilter from 'examples/pagination/custome-page-list-with-filter';
|
||||
import CustomePaginationWithSearch from 'examples/pagination/custom-page-list-with-search';
|
||||
|
||||
// search
|
||||
import SearchTable from 'examples/search';
|
||||
import ClearSearchButton from 'examples/search/clear-search-button';
|
||||
import DefaultSearch from 'examples/search/default-search';
|
||||
import DefaultCustomSearch from 'examples/search/default-custom-search';
|
||||
import FullyCustomSearch from 'examples/search/fully-custom-search';
|
||||
@@ -159,11 +193,18 @@ import CSVFormatter from 'examples/csv/csv-column-formatter';
|
||||
import CustomCSVHeader from 'examples/csv/custom-csv-header';
|
||||
import HideCSVColumn from 'examples/csv/hide-column';
|
||||
import ExportOnlySelected from 'examples/csv/export-only-selected';
|
||||
import ExportOnlyFiltered from 'examples/csv/export-only-filtered';
|
||||
import CSVColumnType from 'examples/csv/csv-column-type';
|
||||
import CustomCSVButton from 'examples/csv/custom-csv-button';
|
||||
import ExportCustomData from 'examples/csv/export-custom-data';
|
||||
import CustomCSV from 'examples/csv/custom-csv';
|
||||
|
||||
// Column toggle
|
||||
import BasicColumnToggle from 'examples/column-toggle';
|
||||
import DefaultVisibility from 'examples/column-toggle/default-visibility';
|
||||
import StylingColumnToggle from 'examples/column-toggle/styling-toggle-list';
|
||||
import CustomToggleList from 'examples/column-toggle/custom-toggle-list';
|
||||
|
||||
// loading overlay
|
||||
import EmptyTableOverlay from 'examples/loading-overlay/empty-table-overlay';
|
||||
import TableOverlay from 'examples/loading-overlay/table-overlay';
|
||||
@@ -176,18 +217,26 @@ import RemoteSearch from 'examples/remote/remote-search';
|
||||
import RemoteCellEdit from 'examples/remote/remote-celledit';
|
||||
import RemoteAll from 'examples/remote/remote-all';
|
||||
|
||||
// data
|
||||
import DataChangeListener from 'examples/data/data-change-listener';
|
||||
import LoadDataWithFilter from 'examples/data/load-data-on-the-fly-with-filter';
|
||||
import LoadDataWithDefaultFilter from 'examples/data/load-data-on-the-fly-with-default-filter';
|
||||
import LoadDataWithSearch from 'examples/data/load-data-on-the-fly-with-search';
|
||||
import LoadDataWithDefaultSearch from 'examples/data/load-data-on-the-fly-with-default-search';
|
||||
import LoadDataWithPaginationAndFilter from 'examples/data/load-data-on-the-fly-with-pagination-and-filter';
|
||||
|
||||
// css style
|
||||
import 'stories/stylesheet/tomorrow.min.css';
|
||||
import 'stories/stylesheet/storybook.scss';
|
||||
import '../../react-bootstrap-table2/style/react-bootstrap-table2.scss';
|
||||
import '../../react-bootstrap-table2-paginator/style/react-bootstrap-table2-paginator.scss';
|
||||
import '../../react-bootstrap-table2-filter/style/react-bootstrap-table2-filter.scss';
|
||||
import '../../react-bootstrap-table2-toolkit/style/react-bootstrap-table2-toolkit.scss';
|
||||
|
||||
// import bootstrap style by given version
|
||||
import bootstrapStyle, { BOOTSTRAP_VERSION } from './bootstrap-style';
|
||||
|
||||
storiesOf('Welcome', module)
|
||||
.add('react bootstrap table 2 ', () => <Welcome />);
|
||||
storiesOf('Welcome', module).add('react bootstrap table 2 ', () => <Welcome />);
|
||||
|
||||
storiesOf('Basic Table', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
@@ -205,7 +254,9 @@ storiesOf('Bootstrap 4', module)
|
||||
.addDecorator(bootstrapStyle(BOOTSTRAP_VERSION.FOUR))
|
||||
.add('Sort table with bootstrap 4', () => <Bootstrap4DefaultSortTable />)
|
||||
.add('Row selection table with bootstrap 4', () => <Bootstrap4RowSelectionTable />)
|
||||
.add('Pagination table with bootstrap 4', () => <Bootstrap4PaginationTable />);
|
||||
.add('Pagination table with bootstrap 4', () => <Bootstrap4PaginationTable />)
|
||||
.add('Column Toggle with bootstrap 4', () => <Bootstrap4ColumnToggleTable />)
|
||||
.add('toolkits Table bootstrap 4', () => <ToolkitsTable />);
|
||||
|
||||
storiesOf('Work on Columns', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
@@ -262,14 +313,31 @@ storiesOf('Column Filter', module)
|
||||
.add('Programmatically Multi Select Filter', () => <ProgrammaticallyMultiSelectFilter />)
|
||||
.add('Custom Filter', () => <CustomFilter />)
|
||||
.add('Advance Custom Filter', () => <AdvanceCustomFilter />)
|
||||
.add('Clear All Filters', () => <ClearAllFilters />);
|
||||
.add('Preserved Option Order on Select Filter', () => <SelectFilterWithPreservedOptionsOrder />)
|
||||
.add('Clear All Filters', () => <ClearAllFilters />)
|
||||
.add('Filter Hooks', () => <FilterHooks />)
|
||||
.add('Implement custom filter logic', () => <CustomFilterLogic />);
|
||||
|
||||
storiesOf('Work on Rows', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
.add('Customize Row Style', () => <RowStyleTable />)
|
||||
.add('Customize Row Class', () => <RowClassTable />)
|
||||
.add('Hide Rows', () => <RowHiddenTable />)
|
||||
.add('Row Event', () => <RowEventTable />);
|
||||
|
||||
storiesOf('Footer', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
.add('Simple Footer', () => <SimpleFooter />)
|
||||
.add('Function Footer', () => <FunctionFooter />)
|
||||
.add('Column Formatter', () => <FooterColumnFormatTable />)
|
||||
.add('Column Align', () => <FooterColumnAlignTable />)
|
||||
.add('Column Title', () => <FooterColumnTitleTable />)
|
||||
.add('Column Events', () => <FooterColumnEventsTable />)
|
||||
.add('Customize Column Class', () => <FooterColumnClassTable />)
|
||||
.add('Customize Column Style', () => <FooterColumnStyleTable />)
|
||||
.add('Customize Column HTML attribute', () => <FooterColumnAttrsTable />)
|
||||
.add('Footer Class', () => <FooterClassTable />);
|
||||
|
||||
storiesOf('Sort Table', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
.add('Enable Sort', () => <EnableSortTable />)
|
||||
@@ -312,11 +380,13 @@ storiesOf('Row Selection', module)
|
||||
.add('Click to Select', () => <ClickToSelectTable />)
|
||||
.add('Default Select', () => <DefaultSelectTable />)
|
||||
.add('Selection Management', () => <SelectionManagement />)
|
||||
.add('Advance Selection Management', () => <AdvanceSelectionManagement />)
|
||||
.add('Click to Select and Edit Cell', () => <ClickToSelectWithCellEditTable />)
|
||||
.add('Row Select and Expand', () => <SelectionWithExpansionTable />)
|
||||
.add('Selection without Data', () => <SelectionNoDataTable />)
|
||||
.add('Selection Style', () => <SelectionStyleTable />)
|
||||
.add('Selection Class', () => <SelectionClassTable />)
|
||||
.add('Custom Selection Column Header Style', () => <HeaderStyleTable />)
|
||||
.add('Hide Select All', () => <HideSelectAllTable />)
|
||||
.add('Custom Selection', () => <CustomSelectionTable />)
|
||||
.add('Selection Background Color', () => <SelectionBgColorTable />)
|
||||
@@ -333,23 +403,44 @@ storiesOf('Row Expand', module)
|
||||
.add('Only Expand by Indicator', () => <OnlyExpandByColumn />)
|
||||
.add('Expand Only One Row at The Same Time', () => <ExpandOnlyOne />)
|
||||
.add('Custom Expand Indicator', () => <CustomExpandColumn />)
|
||||
.add('Expand Column Position', () => <ExpandColumnPosition />)
|
||||
.add('Expand Hooks', () => <ExpandHooks />);
|
||||
|
||||
storiesOf('Pagination', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
.add('Basic Pagination Table', () => <PaginationTable />)
|
||||
.add('Pagination Hooks', () => <PaginationHooksTable />)
|
||||
.add('Custom Pagination', () => <CustomPaginationTable />);
|
||||
.add('Pagination with Dynamic Data', () => <PaginationWithDynamicData />)
|
||||
.add('Custom Pagination', () => <CustomPaginationTable />)
|
||||
.add('Custom Page Button', () => <CustomPageButtonTable />)
|
||||
.add('Custom Page List', () => <CustomPageListTable />)
|
||||
.add('Custom SizePerPage Option', () => <CustomSizePerPageOptionTable />)
|
||||
.add('Custom SizePerPage', () => <CustomSizePerPageTable />)
|
||||
.add('Standalone Pagination List', () => <StandalonePaginationList />)
|
||||
.add('Standalone SizePerPage Dropdown', () => <StandaloneSizePerPage />)
|
||||
.add('Standalone Pagination Total', () => <StandalonePaginationTotal />)
|
||||
.add('Fully Custom Pagination', () => <FullyCustomPaginationTable />)
|
||||
.add('Remote Fully Custom Pagination', () => <RemoteStandalonePaginationTable />)
|
||||
.add('Custom Pagination with Filter', () => <CustomePaginationWithFilter />)
|
||||
.add('Custom Pagination with Search', () => <CustomePaginationWithSearch />);
|
||||
|
||||
storiesOf('Table Search', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
.add('Basic Search Table', () => <SearchTable />)
|
||||
.add('Clear Search Button', () => <ClearSearchButton />)
|
||||
.add('Default Search Table', () => <DefaultSearch />)
|
||||
.add('Default Custom Search', () => <DefaultCustomSearch />)
|
||||
.add('Fully Custom Search', () => <FullyCustomSearch />)
|
||||
.add('Search Fromatted Value', () => <SearchFormattedData />)
|
||||
.add('Custom Search Value', () => <CustomSearchValue />);
|
||||
|
||||
storiesOf('Column Toggle', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
.add('Basic Column Toggle', () => <BasicColumnToggle />)
|
||||
.add('Default Visibility', () => <DefaultVisibility />)
|
||||
.add('Styling Column Toggle', () => <StylingColumnToggle />)
|
||||
.add('Custom Column Toggle', () => <CustomToggleList />);
|
||||
|
||||
storiesOf('Export CSV', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
.add('Basic Export CSV', () => <ExportCSV />)
|
||||
@@ -357,6 +448,7 @@ storiesOf('Export CSV', module)
|
||||
.add('Custom CSV Header', () => <CustomCSVHeader />)
|
||||
.add('Hide CSV Column', () => <HideCSVColumn />)
|
||||
.add('Only Export Selected Rows', () => <ExportOnlySelected />)
|
||||
.add('Only Export Filtered/Searched Rows', () => <ExportOnlyFiltered />)
|
||||
.add('CSV Column Type', () => <CSVColumnType />)
|
||||
.add('Custom CSV Button', () => <CustomCSVButton />)
|
||||
.add('Export Custom Data', () => <ExportCustomData />)
|
||||
@@ -375,3 +467,12 @@ storiesOf('Remote', module)
|
||||
.add('Remote Search', () => <RemoteSearch />)
|
||||
.add('Remote Cell Editing', () => <RemoteCellEdit />)
|
||||
.add('Remote All', () => <RemoteAll />);
|
||||
|
||||
storiesOf('Data', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
.add('Data Change Listener', () => <DataChangeListener />)
|
||||
.add('Load data with Filter', () => <LoadDataWithFilter />)
|
||||
.add('Load data with Default Filter', () => <LoadDataWithDefaultFilter />)
|
||||
.add('Load data with Search', () => <LoadDataWithSearch />)
|
||||
.add('Load data with Default Search', () => <LoadDataWithDefaultSearch />)
|
||||
.add('Load data with Filter and Pagination', () => <LoadDataWithPaginationAndFilter />);
|
||||
|
||||
@@ -13,4 +13,8 @@
|
||||
|
||||
.header-class {
|
||||
background-color: $green-lighten-4;
|
||||
}
|
||||
|
||||
.footer-class {
|
||||
background-color: $green-lighten-4;
|
||||
}
|
||||
@@ -115,6 +115,27 @@ const qualityFilter = selectFilter({
|
||||
// omit...
|
||||
```
|
||||
|
||||
> Note, the selectOptions can be an array also:
|
||||
|
||||
```js
|
||||
const selectOptions = [
|
||||
{ value: 0, label: 'good' },
|
||||
{ value: 1, label: 'Bad' },
|
||||
{ value: 2, label: 'unknown' }
|
||||
];
|
||||
const columns = [
|
||||
..., {
|
||||
dataField: 'quality',
|
||||
text: 'Product Quailty',
|
||||
formatter: cell => selectOptions.find(opt => opt.value === cell).label,
|
||||
filter: selectFilter({
|
||||
options: selectOptions
|
||||
})
|
||||
}];
|
||||
```
|
||||
|
||||
The benifit is `react-bootstrap-table2` will render the select options by the order of array.
|
||||
|
||||
## MultiSelect Filter
|
||||
|
||||
A quick example:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-filter",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.9",
|
||||
"description": "it's a column filter addon for react-bootstrap-table2",
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -18,7 +18,7 @@ const legalComparators = [
|
||||
];
|
||||
|
||||
function dateParser(d) {
|
||||
return `${d.getFullYear()}-${('0' + (d.getMonth() + 1)).slice(-2)}-${('0' + d.getDate()).slice(-2)}`;
|
||||
return `${d.getUTCFullYear()}-${('0' + (d.getUTCMonth() + 1)).slice(-2)}-${('0' + d.getUTCDate()).slice(-2)}`;
|
||||
}
|
||||
|
||||
class DateFilter extends Component {
|
||||
@@ -42,10 +42,11 @@ class DateFilter extends Component {
|
||||
// export onFilter function to allow users to access
|
||||
if (getFilter) {
|
||||
getFilter((filterVal) => {
|
||||
this.dateFilterComparator.value = filterVal.comparator;
|
||||
this.inputDate.value = dateParser(filterVal.date);
|
||||
const nullableFilterVal = filterVal || { date: null, comparator: null };
|
||||
this.dateFilterComparator.value = nullableFilterVal.comparator;
|
||||
this.inputDate.value = nullableFilterVal.date ? dateParser(nullableFilterVal.date) : null;
|
||||
|
||||
this.applyFilter(filterVal.date, filterVal.comparator);
|
||||
this.applyFilter(nullableFilterVal.date, nullableFilterVal.comparator);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -131,24 +132,35 @@ class DateFilter extends Component {
|
||||
className={ `filter date-filter ${className}` }
|
||||
style={ style }
|
||||
>
|
||||
<select
|
||||
ref={ n => this.dateFilterComparator = n }
|
||||
style={ comparatorStyle }
|
||||
className={ `date-filter-comparator form-control ${comparatorClassName}` }
|
||||
onChange={ this.onChangeComparator }
|
||||
defaultValue={ defaultValue ? defaultValue.comparator : '' }
|
||||
<label
|
||||
className="filter-label"
|
||||
htmlFor={ `date-filter-comparator-${text}` }
|
||||
>
|
||||
{ this.getComparatorOptions() }
|
||||
</select>
|
||||
<input
|
||||
ref={ n => this.inputDate = n }
|
||||
className={ `filter date-filter-input form-control ${dateClassName}` }
|
||||
style={ dateStyle }
|
||||
type="date"
|
||||
onChange={ this.onChangeDate }
|
||||
placeholder={ placeholder || `Enter ${text}...` }
|
||||
defaultValue={ this.getDefaultDate() }
|
||||
/>
|
||||
<span className="sr-only">Filter comparator</span>
|
||||
<select
|
||||
ref={ n => this.dateFilterComparator = n }
|
||||
id={ `date-filter-comparator-${text}` }
|
||||
style={ comparatorStyle }
|
||||
className={ `date-filter-comparator form-control ${comparatorClassName}` }
|
||||
onChange={ this.onChangeComparator }
|
||||
defaultValue={ defaultValue ? defaultValue.comparator : '' }
|
||||
>
|
||||
{ this.getComparatorOptions() }
|
||||
</select>
|
||||
</label>
|
||||
<label htmlFor={ `date-filter-column-${text}` }>
|
||||
<span className="sr-only">Enter ${ text }</span>
|
||||
<input
|
||||
ref={ n => this.inputDate = n }
|
||||
id={ `date-filter-column-${text}` }
|
||||
className={ `filter date-filter-input form-control ${dateClassName}` }
|
||||
style={ dateStyle }
|
||||
type="date"
|
||||
onChange={ this.onChangeDate }
|
||||
placeholder={ placeholder || `Enter ${text}...` }
|
||||
defaultValue={ this.getDefaultDate() }
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -111,18 +111,25 @@ class MultiSelectFilter extends Component {
|
||||
`filter select-filter form-control ${className} ${this.state.isSelected ? '' : 'placeholder-selected'}`;
|
||||
|
||||
return (
|
||||
<select
|
||||
{ ...rest }
|
||||
ref={ n => this.selectInput = n }
|
||||
style={ style }
|
||||
multiple
|
||||
className={ selectClass }
|
||||
onChange={ this.filter }
|
||||
onClick={ e => e.stopPropagation() }
|
||||
defaultValue={ defaultValue !== undefined ? defaultValue : '' }
|
||||
<label
|
||||
className="filter-label"
|
||||
htmlFor={ `multiselect-filter-column-${column.text}` }
|
||||
>
|
||||
{ this.getOptions() }
|
||||
</select>
|
||||
<span className="sr-only">Filter by {column.text}</span>
|
||||
<select
|
||||
{ ...rest }
|
||||
ref={ n => this.selectInput = n }
|
||||
id={ `multiselect-filter-column-${column.text}` }
|
||||
style={ style }
|
||||
multiple
|
||||
className={ selectClass }
|
||||
onChange={ this.filter }
|
||||
onClick={ e => e.stopPropagation() }
|
||||
defaultValue={ defaultValue !== undefined ? defaultValue : '' }
|
||||
>
|
||||
{ this.getOptions() }
|
||||
</select>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,35 +173,53 @@ class NumberFilter extends Component {
|
||||
className={ `filter number-filter ${className}` }
|
||||
style={ style }
|
||||
>
|
||||
<select
|
||||
ref={ n => this.numberFilterComparator = n }
|
||||
style={ comparatorStyle }
|
||||
className={ `number-filter-comparator form-control ${comparatorClassName}` }
|
||||
onChange={ this.onChangeComparator }
|
||||
defaultValue={ defaultValue ? defaultValue.comparator : '' }
|
||||
<label
|
||||
className="filter-label"
|
||||
htmlFor={ `number-filter-comparator-${column.text}` }
|
||||
>
|
||||
{ this.getComparatorOptions() }
|
||||
</select>
|
||||
<span className="sr-only">Filter comparator</span>
|
||||
<select
|
||||
ref={ n => this.numberFilterComparator = n }
|
||||
style={ comparatorStyle }
|
||||
id={ `number-filter-comparator-${column.text}` }
|
||||
className={ `number-filter-comparator form-control ${comparatorClassName}` }
|
||||
onChange={ this.onChangeComparator }
|
||||
defaultValue={ defaultValue ? defaultValue.comparator : '' }
|
||||
>
|
||||
{ this.getComparatorOptions() }
|
||||
</select>
|
||||
</label>
|
||||
{
|
||||
options ?
|
||||
<select
|
||||
ref={ n => this.numberFilter = n }
|
||||
style={ numberStyle }
|
||||
className={ selectClass }
|
||||
onChange={ this.onChangeNumberSet }
|
||||
defaultValue={ defaultValue ? defaultValue.number : '' }
|
||||
<label
|
||||
className="filter-label"
|
||||
htmlFor={ `number-filter-column-${column.text}` }
|
||||
>
|
||||
{ this.getNumberOptions() }
|
||||
</select> :
|
||||
<input
|
||||
ref={ n => this.numberFilter = n }
|
||||
type="number"
|
||||
style={ numberStyle }
|
||||
className={ `number-filter-input form-control ${numberClassName}` }
|
||||
placeholder={ placeholder || `Enter ${column.text}...` }
|
||||
onChange={ this.onChangeNumber }
|
||||
defaultValue={ defaultValue ? defaultValue.number : '' }
|
||||
/>
|
||||
<span className="sr-only">{`Select ${column.text}`}</span>
|
||||
<select
|
||||
ref={ n => this.numberFilter = n }
|
||||
id={ `number-filter-column-${column.text}` }
|
||||
style={ numberStyle }
|
||||
className={ selectClass }
|
||||
onChange={ this.onChangeNumberSet }
|
||||
defaultValue={ defaultValue ? defaultValue.number : '' }
|
||||
>
|
||||
{ this.getNumberOptions() }
|
||||
</select>
|
||||
</label> :
|
||||
<label htmlFor={ `number-filter-column-${column.text}` }>
|
||||
<span className="sr-only">{`Enter ${column.text}`}</span>
|
||||
<input
|
||||
ref={ n => this.numberFilter = n }
|
||||
id={ `number-filter-column-${column.text}` }
|
||||
type="number"
|
||||
style={ numberStyle }
|
||||
className={ `number-filter-input form-control ${numberClassName}` }
|
||||
placeholder={ placeholder || `Enter ${column.text}...` }
|
||||
onChange={ this.onChangeNumber }
|
||||
defaultValue={ defaultValue ? defaultValue.number : '' }
|
||||
/>
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,6 +7,20 @@ import { LIKE, EQ } from '../comparison';
|
||||
import { FILTER_TYPE } from '../const';
|
||||
|
||||
function optionsEquals(currOpts, prevOpts) {
|
||||
if (Array.isArray(currOpts)) {
|
||||
if (currOpts.length === prevOpts.length) {
|
||||
for (let i = 0; i < currOpts.length; i += 1) {
|
||||
if (
|
||||
currOpts[i].value !== prevOpts[i].value ||
|
||||
currOpts[i].label !== prevOpts[i].label
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const keys = Object.keys(currOpts);
|
||||
for (let i = 0; i < keys.length; i += 1) {
|
||||
if (currOpts[keys[i]] !== prevOpts[keys[i]]) {
|
||||
@@ -16,11 +30,21 @@ function optionsEquals(currOpts, prevOpts) {
|
||||
return Object.keys(currOpts).length === Object.keys(prevOpts).length;
|
||||
}
|
||||
|
||||
function getOptionValue(options, key) {
|
||||
if (Array.isArray(options)) {
|
||||
const result = options
|
||||
.filter(({ label }) => label === key)
|
||||
.map(({ value }) => value);
|
||||
return result[0];
|
||||
}
|
||||
return options[key];
|
||||
}
|
||||
|
||||
class SelectFilter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.filter = this.filter.bind(this);
|
||||
const isSelected = props.options[props.defaultValue] !== undefined;
|
||||
const isSelected = getOptionValue(props.options, props.defaultValue) !== undefined;
|
||||
this.state = { isSelected };
|
||||
}
|
||||
|
||||
@@ -66,9 +90,14 @@ class SelectFilter extends Component {
|
||||
<option key="-1" value="">{ placeholder || `Select ${column.text}...` }</option>
|
||||
));
|
||||
}
|
||||
Object.keys(options).forEach(key =>
|
||||
optionTags.push(<option key={ key } value={ key }>{ options[key] }</option>)
|
||||
);
|
||||
if (Array.isArray(options)) {
|
||||
options.forEach(({ value, label }) =>
|
||||
optionTags.push(<option key={ value } value={ value }>{ label }</option>));
|
||||
} else {
|
||||
Object.keys(options).forEach(key =>
|
||||
optionTags.push(<option key={ key } value={ key }>{ options[key] }</option>)
|
||||
);
|
||||
}
|
||||
return optionTags;
|
||||
}
|
||||
|
||||
@@ -110,17 +139,24 @@ class SelectFilter extends Component {
|
||||
`filter select-filter form-control ${className} ${this.state.isSelected ? '' : 'placeholder-selected'}`;
|
||||
|
||||
return (
|
||||
<select
|
||||
{ ...rest }
|
||||
ref={ n => this.selectInput = n }
|
||||
style={ style }
|
||||
className={ selectClass }
|
||||
onChange={ this.filter }
|
||||
onClick={ e => e.stopPropagation() }
|
||||
defaultValue={ defaultValue !== undefined ? defaultValue : '' }
|
||||
<label
|
||||
className="filter-label"
|
||||
htmlFor={ `select-filter-column-${column.text}` }
|
||||
>
|
||||
{ this.getOptions() }
|
||||
</select>
|
||||
<span className="sr-only">Filter by { column.text }</span>
|
||||
<select
|
||||
{ ...rest }
|
||||
ref={ n => this.selectInput = n }
|
||||
id={ `select-filter-column-${column.text}` }
|
||||
style={ style }
|
||||
className={ selectClass }
|
||||
onChange={ this.filter }
|
||||
onClick={ e => e.stopPropagation() }
|
||||
defaultValue={ defaultValue !== undefined ? defaultValue : '' }
|
||||
>
|
||||
{ this.getOptions() }
|
||||
</select>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -128,7 +164,7 @@ class SelectFilter extends Component {
|
||||
SelectFilter.propTypes = {
|
||||
onFilter: PropTypes.func.isRequired,
|
||||
column: PropTypes.object.isRequired,
|
||||
options: PropTypes.object.isRequired,
|
||||
options: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
|
||||
comparator: PropTypes.oneOf([LIKE, EQ]),
|
||||
placeholder: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
|
||||
@@ -94,17 +94,24 @@ class TextFilter extends Component {
|
||||
|
||||
// stopPropagation for onClick event is try to prevent sort was triggered.
|
||||
return (
|
||||
<input
|
||||
{ ...rest }
|
||||
ref={ n => this.input = n }
|
||||
type="text"
|
||||
className={ `filter text-filter form-control ${className}` }
|
||||
style={ style }
|
||||
onChange={ this.filter }
|
||||
onClick={ this.handleClick }
|
||||
placeholder={ placeholder || `Enter ${text}...` }
|
||||
value={ this.state.value }
|
||||
/>
|
||||
<label
|
||||
className="filter-label"
|
||||
htmlFor={ `text-filter-column-${text}` }
|
||||
>
|
||||
<span className="sr-only">Filter by {text}</span>
|
||||
<input
|
||||
{ ...rest }
|
||||
ref={ n => this.input = n }
|
||||
type="text"
|
||||
id={ `text-filter-column-${text}` }
|
||||
className={ `filter text-filter form-control ${className}` }
|
||||
style={ style }
|
||||
onChange={ this.filter }
|
||||
onClick={ this.handleClick }
|
||||
placeholder={ placeholder || `Enter ${text}...` }
|
||||
value={ this.state.value }
|
||||
/>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,14 +17,18 @@ export default (
|
||||
class FilterProvider extends React.Component {
|
||||
static propTypes = {
|
||||
data: PropTypes.array.isRequired,
|
||||
columns: PropTypes.array.isRequired
|
||||
columns: PropTypes.array.isRequired,
|
||||
dataChangeListener: PropTypes.object
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.currFilters = {};
|
||||
this.onFilter = this.onFilter.bind(this);
|
||||
this.doFilter = this.doFilter.bind(this);
|
||||
this.onExternalFilter = this.onExternalFilter.bind(this);
|
||||
this.data = props.data;
|
||||
this.isEmitDataChange = false;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -33,6 +37,15 @@ export default (
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// let nextData = nextProps.data;
|
||||
if (!isRemoteFiltering() && !_.isEqual(nextProps.data, this.data)) {
|
||||
this.doFilter(nextProps, undefined, this.isEmitDataChange);
|
||||
} else {
|
||||
this.data = nextProps.data;
|
||||
}
|
||||
}
|
||||
|
||||
onFilter(column, filterType, initialize = false) {
|
||||
return (filterVal) => {
|
||||
// watch out here if migration to context API, #334
|
||||
@@ -64,7 +77,11 @@ export default (
|
||||
return;
|
||||
}
|
||||
|
||||
this.forceUpdate();
|
||||
let result;
|
||||
if (filter.props.onFilter) {
|
||||
result = filter.props.onFilter(filterVal);
|
||||
}
|
||||
this.doFilter(this.props, result);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,14 +91,29 @@ export default (
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
let { data } = this.props;
|
||||
if (!isRemoteFiltering()) {
|
||||
data = filters(data, this.props.columns, _)(this.currFilters);
|
||||
getFiltered() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
doFilter(props, customResult, ignoreEmitDataChange = false) {
|
||||
let result = customResult;
|
||||
|
||||
const { dataChangeListener, data, columns } = props;
|
||||
result = result || filters(data, columns, _)(this.currFilters);
|
||||
this.data = result;
|
||||
if (dataChangeListener && !ignoreEmitDataChange) {
|
||||
this.isEmitDataChange = true;
|
||||
dataChangeListener.emit('filterChanged', result.length);
|
||||
} else {
|
||||
this.isEmitDataChange = false;
|
||||
this.forceUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<FilterContext.Provider value={ {
|
||||
data,
|
||||
data: this.data,
|
||||
onFilter: this.onFilter,
|
||||
onExternalFilter: this.onExternalFilter
|
||||
} }
|
||||
|
||||
@@ -98,9 +98,9 @@ export const filterByDate = _ => (
|
||||
customFilterValue
|
||||
) => {
|
||||
if (!date || !comparator) return data;
|
||||
const filterDate = date.getDate();
|
||||
const filterMonth = date.getMonth();
|
||||
const filterYear = date.getFullYear();
|
||||
const filterDate = date.getUTCDate();
|
||||
const filterMonth = date.getUTCMonth();
|
||||
const filterYear = date.getUTCFullYear();
|
||||
|
||||
return data.filter((row) => {
|
||||
let valid = true;
|
||||
@@ -114,9 +114,9 @@ export const filterByDate = _ => (
|
||||
cell = new Date(cell);
|
||||
}
|
||||
|
||||
const targetDate = cell.getDate();
|
||||
const targetMonth = cell.getMonth();
|
||||
const targetYear = cell.getFullYear();
|
||||
const targetDate = cell.getUTCDate();
|
||||
const targetMonth = cell.getUTCMonth();
|
||||
const targetYear = cell.getUTCFullYear();
|
||||
|
||||
|
||||
switch (comparator) {
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
.react-bootstrap-table > table > thead > tr > th .filter-label {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.react-bootstrap-table > table > thead > tr > th .filter {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@ describe('FilterContext', () => {
|
||||
const handleFilterChange = jest.fn();
|
||||
|
||||
function shallowContext(
|
||||
enableRemote = false
|
||||
enableRemote = false,
|
||||
tableColumns = columns,
|
||||
dataChangeListener,
|
||||
) {
|
||||
mockBase.mockReset();
|
||||
handleFilterChange.mockReset();
|
||||
@@ -56,8 +58,9 @@ describe('FilterContext', () => {
|
||||
|
||||
return (
|
||||
<FilterContext.Provider
|
||||
columns={ columns }
|
||||
columns={ tableColumns }
|
||||
data={ data }
|
||||
dataChangeListener={ dataChangeListener }
|
||||
>
|
||||
<FilterContext.Consumer>
|
||||
{
|
||||
@@ -225,6 +228,84 @@ describe('FilterContext', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('if filter.props.onFilter is defined', () => {
|
||||
const filterVal = '3';
|
||||
const onFilter = jest.fn();
|
||||
const customColumns = columns.map((column, i) => {
|
||||
if (i === 1) {
|
||||
return {
|
||||
...column,
|
||||
filter: textFilter({ onFilter })
|
||||
};
|
||||
}
|
||||
return column;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext(false, customColumns));
|
||||
wrapper.render();
|
||||
instance = wrapper.instance();
|
||||
});
|
||||
|
||||
it('should call filter.props.onFilter correctly', () => {
|
||||
instance.onFilter(customColumns[1], FILTER_TYPE.TEXT)(filterVal);
|
||||
expect(onFilter).toHaveBeenCalledTimes(1);
|
||||
expect(onFilter).toHaveBeenCalledWith(filterVal);
|
||||
});
|
||||
});
|
||||
|
||||
describe('if filter.props.onFilter is defined and return an undefined data', () => {
|
||||
const mockReturn = [{
|
||||
id: 1,
|
||||
name: 'A'
|
||||
}];
|
||||
const filterVal = 'A';
|
||||
const onFilter = jest.fn().mockReturnValue(mockReturn);
|
||||
const customColumns = columns.map((column, i) => {
|
||||
if (i === 1) {
|
||||
return {
|
||||
...column,
|
||||
filter: textFilter({ onFilter })
|
||||
};
|
||||
}
|
||||
return column;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext(false, customColumns));
|
||||
wrapper.render();
|
||||
instance = wrapper.instance();
|
||||
});
|
||||
|
||||
it('should call filter.props.onFilter correctly', () => {
|
||||
instance.onFilter(customColumns[1], FILTER_TYPE.TEXT)(filterVal);
|
||||
expect(onFilter).toHaveBeenCalledTimes(1);
|
||||
expect(onFilter).toHaveBeenCalledWith(filterVal);
|
||||
});
|
||||
|
||||
it('should set data correctly', () => {
|
||||
instance.onFilter(customColumns[1], FILTER_TYPE.TEXT)(filterVal);
|
||||
expect(instance.data).toEqual(mockReturn);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when props.dataChangeListener is defined', () => {
|
||||
const filterVal = '3';
|
||||
const newDataLength = 0;
|
||||
const dataChangeListener = { emit: jest.fn() };
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext(false, columns, dataChangeListener));
|
||||
wrapper.render();
|
||||
instance = wrapper.instance();
|
||||
});
|
||||
|
||||
it('should call dataChangeListener.emit correctly', () => {
|
||||
instance.onFilter(columns[1], FILTER_TYPE.TEXT)(filterVal);
|
||||
expect(dataChangeListener.emit).toHaveBeenCalledWith('filterChanged', newDataLength);
|
||||
});
|
||||
});
|
||||
|
||||
describe('combination', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext());
|
||||
|
||||
@@ -11,10 +11,10 @@ export default options => loading =>
|
||||
componentDidMount() {
|
||||
if (loading) {
|
||||
const { wrapper } = this.overlay;
|
||||
const masker = wrapper.firstChild;
|
||||
const headerDOM = wrapper.parentElement.querySelector('thead');
|
||||
const bodyDOM = wrapper.parentElement.querySelector('tbody');
|
||||
const captionDOM = wrapper.parentElement.querySelector('caption');
|
||||
const masker = wrapper.current.firstChild;
|
||||
const headerDOM = wrapper.current.parentElement.querySelector('thead');
|
||||
const bodyDOM = wrapper.current.parentElement.querySelector('tbody');
|
||||
const captionDOM = wrapper.current.parentElement.querySelector('caption');
|
||||
|
||||
let marginTop = window.getComputedStyle(headerDOM).height;
|
||||
if (captionDOM) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-overlay",
|
||||
"version": "1.0.0",
|
||||
"version": "2.0.0",
|
||||
"description": "it's a loading overlay addons for react-bootstrap-table2",
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
@@ -37,7 +37,7 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"react-loading-overlay": "0.2.8"
|
||||
"react-loading-overlay": "1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prop-types": "^15.0.0",
|
||||
|
||||
@@ -2,199 +2,351 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
asap@~2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
|
||||
base64-js@^1.0.2:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886"
|
||||
|
||||
buffer@^5.0.3:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.0.8.tgz#84daa52e7cf2fa8ce4195bc5cf0f7809e0930b24"
|
||||
"@babel/helper-module-imports@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d"
|
||||
integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==
|
||||
dependencies:
|
||||
base64-js "^1.0.2"
|
||||
ieee754 "^1.1.4"
|
||||
"@babel/types" "^7.0.0"
|
||||
|
||||
chain-function@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
|
||||
css-color-keywords@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
|
||||
|
||||
css-to-react-native@^2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.0.4.tgz#cf4cc407558b3474d4ba8be1a2cd3b6ce713101b"
|
||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.4.2":
|
||||
version "7.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.4.tgz#dc2e34982eb236803aa27a07fea6857af1b9171d"
|
||||
integrity sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg==
|
||||
dependencies:
|
||||
css-color-keywords "^1.0.0"
|
||||
fbjs "^0.8.5"
|
||||
postcss-value-parser "^3.3.0"
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
dom-helpers@^3.2.0:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a"
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
||||
"@babel/types@^7.0.0":
|
||||
version "7.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0"
|
||||
integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==
|
||||
dependencies:
|
||||
iconv-lite "~0.4.13"
|
||||
esutils "^2.0.2"
|
||||
lodash "^4.17.11"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
fbjs@^0.8.16, fbjs@^0.8.5, fbjs@^0.8.9:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
"@emotion/cache@^10.0.9":
|
||||
version "10.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.9.tgz#e0c7b7a289f7530edcfad4dcf3858bd2e5700a6f"
|
||||
integrity sha512-f7MblpE2xoimC4fCMZ9pivmsIn7hyWRIvY75owMDi8pdOSeh+w5tH3r4hBJv/LLrwiMM7cTQURqTPcYoL5pWnw==
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
"@emotion/sheet" "0.9.2"
|
||||
"@emotion/stylis" "0.8.3"
|
||||
"@emotion/utils" "0.11.1"
|
||||
"@emotion/weak-memoize" "0.2.2"
|
||||
|
||||
has-flag@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
|
||||
"@emotion/hash@0.7.1":
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.1.tgz#9833722341379fb7d67f06a4b00ab3c37913da53"
|
||||
integrity sha512-OYpa/Sg+2GDX+jibUfpZVn1YqSVRpYmTLF2eyAfrFTIJSbwyIrc+YscayoykvaOME/wV4BV0Sa0yqdMrgse6mA==
|
||||
|
||||
hoist-non-react-statics@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
|
||||
"@emotion/memoize@0.7.1":
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f"
|
||||
integrity sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==
|
||||
|
||||
iconv-lite@~0.4.13:
|
||||
version "0.4.19"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
||||
|
||||
ieee754@^1.1.4:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
|
||||
|
||||
is-function@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
|
||||
|
||||
is-plain-object@^2.0.1:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
|
||||
"@emotion/serialize@^0.11.6":
|
||||
version "0.11.6"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.6.tgz#78be8b9ee9ff49e0196233ba6ec1c1768ba1e1fc"
|
||||
integrity sha512-n4zVv2qGLmspF99jaEUwnMV0fnEGsyUMsC/8KZKUSUTZMYljHE+j+B6rSD8PIFtaUIhHaxCG2JawN6L+OgLN0Q==
|
||||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
"@emotion/hash" "0.7.1"
|
||||
"@emotion/memoize" "0.7.1"
|
||||
"@emotion/unitless" "0.7.3"
|
||||
"@emotion/utils" "0.11.1"
|
||||
csstype "^2.5.7"
|
||||
|
||||
is-stream@^1.0.1:
|
||||
"@emotion/sheet@0.9.2":
|
||||
version "0.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.2.tgz#74e5c6b5e489a1ba30ab246ab5eedd96916487c4"
|
||||
integrity sha512-pVBLzIbC/QCHDKJF2E82V2H/W/B004mDFQZiyo/MSR+VC4pV5JLG0TF/zgQDFvP3fZL/5RTPGEmXlYJBMUuJ+A==
|
||||
|
||||
"@emotion/stylis@0.8.3":
|
||||
version "0.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.3.tgz#3ca7e9bcb31b3cb4afbaeb66156d86ee85e23246"
|
||||
integrity sha512-M3nMfJ6ndJMYloSIbYEBq6G3eqoYD41BpDOxreE8j0cb4fzz/5qvmqU9Mb2hzsXcCnIlGlWhS03PCzVGvTAe0Q==
|
||||
|
||||
"@emotion/unitless@0.7.3":
|
||||
version "0.7.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.3.tgz#6310a047f12d21a1036fb031317219892440416f"
|
||||
integrity sha512-4zAPlpDEh2VwXswwr/t8xGNDGg8RQiPxtxZ3qQEXyQsBV39ptTdESCjuBvGze1nLMVrxmTIKmnO/nAV8Tqjjzg==
|
||||
|
||||
"@emotion/utils@0.11.1":
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.1.tgz#8529b7412a6eb4b48bdf6e720cc1b8e6e1e17628"
|
||||
integrity sha512-8M3VN0hetwhsJ8dH8VkVy7xo5/1VoBsDOk/T4SJOeXwTO1c4uIqVNx2qyecLFnnUWD5vvUqHQ1gASSeUN6zcTg==
|
||||
|
||||
"@emotion/weak-memoize@0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.2.tgz#63985d3d8b02530e0869962f4da09142ee8e200e"
|
||||
integrity sha512-n/VQ4mbfr81aqkx/XmVicOLjviMuy02eenSdJY33SVA7S2J42EU0P1H0mOogfYedb3wXA0d/LVtBrgTSm04WEA==
|
||||
|
||||
argparse@^1.0.7:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
|
||||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
babel-plugin-emotion@^10.0.9:
|
||||
version "10.0.9"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.9.tgz#04a0404d5a4084d5296357a393d344c0f8303ae4"
|
||||
integrity sha512-IfWP12e9/wHtWHxVTzD692Nbcmrmcz2tip7acp6YUqtrP7slAyr5B+69hyZ8jd55GsyNSZwryNnmuDEVe0j+7w==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
"@emotion/hash" "0.7.1"
|
||||
"@emotion/memoize" "0.7.1"
|
||||
"@emotion/serialize" "^0.11.6"
|
||||
babel-plugin-macros "^2.0.0"
|
||||
babel-plugin-syntax-jsx "^6.18.0"
|
||||
convert-source-map "^1.5.0"
|
||||
escape-string-regexp "^1.0.5"
|
||||
find-root "^1.1.0"
|
||||
source-map "^0.5.7"
|
||||
|
||||
babel-plugin-macros@^2.0.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.5.1.tgz#4a119ac2c2e19b458c259b9accd7ee34fd57ec6f"
|
||||
integrity sha512-xN3KhAxPzsJ6OQTktCanNpIFnnMsCV+t8OloKxIL72D6+SUZYFn9qfklPgef5HyyDtzYZqqb+fs1S12+gQY82Q==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.4.2"
|
||||
cosmiconfig "^5.2.0"
|
||||
resolve "^1.10.0"
|
||||
|
||||
babel-plugin-syntax-jsx@^6.18.0:
|
||||
version "6.18.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
||||
integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
|
||||
|
||||
caller-callsite@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134"
|
||||
integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=
|
||||
dependencies:
|
||||
callsites "^2.0.0"
|
||||
|
||||
caller-path@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4"
|
||||
integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=
|
||||
dependencies:
|
||||
caller-callsite "^2.0.0"
|
||||
|
||||
callsites@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
|
||||
integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
|
||||
|
||||
convert-source-map@^1.5.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
|
||||
integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==
|
||||
dependencies:
|
||||
safe-buffer "~5.1.1"
|
||||
|
||||
cosmiconfig@^5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
|
||||
integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
|
||||
dependencies:
|
||||
import-fresh "^2.0.0"
|
||||
is-directory "^0.3.1"
|
||||
js-yaml "^3.13.1"
|
||||
parse-json "^4.0.0"
|
||||
|
||||
create-emotion@^10.0.9:
|
||||
version "10.0.9"
|
||||
resolved "https://registry.yarnpkg.com/create-emotion/-/create-emotion-10.0.9.tgz#290c2036126171c9566fa24f49c9241d54625138"
|
||||
integrity sha512-sLKD4bIiTs8PpEqr5vlCoV5lsYE4QOBYEUWaD0R+VGRMCvBKHmYlvLJXsL99Kdc4YEFAFwipi2bbncnvv6UxRg==
|
||||
dependencies:
|
||||
"@emotion/cache" "^10.0.9"
|
||||
"@emotion/serialize" "^0.11.6"
|
||||
"@emotion/sheet" "0.9.2"
|
||||
"@emotion/utils" "0.11.1"
|
||||
|
||||
csstype@^2.5.7:
|
||||
version "2.6.4"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.4.tgz#d585a6062096e324e7187f80e04f92bd0f00e37f"
|
||||
integrity sha512-lAJUJP3M6HxFXbqtGRc0iZrdyeN+WzOWeY0q/VnFzI+kqVrYIzC7bWlKqCW7oCIdzoPkvfp82EVvrTlQ8zsWQg==
|
||||
|
||||
dom-helpers@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
|
||||
integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
|
||||
emotion@^10.0.1:
|
||||
version "10.0.9"
|
||||
resolved "https://registry.yarnpkg.com/emotion/-/emotion-10.0.9.tgz#2c37598af13df31dcd35a1957eaa8830f368c066"
|
||||
integrity sha512-IMFwwWlU2TDt7eh4v6dm58E8VHAYOitqRbVoazQdxIu9/0CAH4a3UrTMnZSlWQAo09MrRRlKfgQFHswnj40meQ==
|
||||
dependencies:
|
||||
babel-plugin-emotion "^10.0.9"
|
||||
create-emotion "^10.0.9"
|
||||
|
||||
error-ex@^1.3.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
||||
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
esprima@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=
|
||||
|
||||
find-root@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
|
||||
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
|
||||
|
||||
isobject@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
import-fresh@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
|
||||
integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY=
|
||||
dependencies:
|
||||
node-fetch "^1.0.1"
|
||||
whatwg-fetch ">=0.10.0"
|
||||
caller-path "^2.0.0"
|
||||
resolve-from "^3.0.0"
|
||||
|
||||
js-tokens@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
||||
is-arrayish@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
is-directory@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
|
||||
integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
js-yaml@^3.13.1:
|
||||
version "3.13.1"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
||||
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
|
||||
dependencies:
|
||||
js-tokens "^3.0.0"
|
||||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
node-fetch@^1.0.1:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||
json-parse-better-errors@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
|
||||
integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
|
||||
|
||||
lodash@^4.17.11:
|
||||
version "4.17.11"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
|
||||
|
||||
loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
postcss-value-parser@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15"
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
parse-json@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
|
||||
integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
error-ex "^1.3.1"
|
||||
json-parse-better-errors "^1.0.1"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6:
|
||||
version "15.6.0"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
|
||||
prop-types@^15.6.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.3.1"
|
||||
loose-envify "^1.4.0"
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.8.1"
|
||||
|
||||
react-loading-overlay@0.2.8:
|
||||
version "0.2.8"
|
||||
resolved "https://registry.yarnpkg.com/react-loading-overlay/-/react-loading-overlay-0.2.8.tgz#c1c5531c9cfa4be6caca6b9aa0c1eb19e22b03fe"
|
||||
react-is@^16.8.1:
|
||||
version "16.8.6"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
|
||||
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
|
||||
|
||||
react-lifecycles-compat@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-loading-overlay@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-loading-overlay/-/react-loading-overlay-1.0.1.tgz#ee3b1ad56c45bb2f1ba46d4820ba0d06cd319a91"
|
||||
integrity sha512-aUjtZ8tNXBSx+MbD2SQs0boPbeTAGTh+I5U9nWjDzMasKlYr58RJpr57c8W7uApeLpOkAGbInExRi6GamNC2bA==
|
||||
dependencies:
|
||||
prop-types "^15.5.10"
|
||||
react-transition-group "^1.2.1"
|
||||
styled-components "^2.1.2"
|
||||
emotion "^10.0.1"
|
||||
prop-types "^15.6.2"
|
||||
react-transition-group "^2.5.0"
|
||||
|
||||
react-transition-group@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6"
|
||||
react-transition-group@^2.5.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
|
||||
integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==
|
||||
dependencies:
|
||||
chain-function "^1.0.0"
|
||||
dom-helpers "^3.2.0"
|
||||
loose-envify "^1.3.1"
|
||||
prop-types "^15.5.6"
|
||||
warning "^3.0.0"
|
||||
dom-helpers "^3.4.0"
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
|
||||
setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
regenerator-runtime@^0.13.2:
|
||||
version "0.13.2"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447"
|
||||
integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==
|
||||
|
||||
styled-components@^2.1.2:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.2.4.tgz#dd87fd3dafd359e7a0d570aec1bd07d691c0b5a2"
|
||||
dependencies:
|
||||
buffer "^5.0.3"
|
||||
css-to-react-native "^2.0.3"
|
||||
fbjs "^0.8.9"
|
||||
hoist-non-react-statics "^1.2.0"
|
||||
is-function "^1.0.1"
|
||||
is-plain-object "^2.0.1"
|
||||
prop-types "^15.5.4"
|
||||
stylis "^3.4.0"
|
||||
supports-color "^3.2.3"
|
||||
|
||||
stylis@^3.4.0:
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.4.5.tgz#d7b9595fc18e7b9c8775eca8270a9a1d3e59806e"
|
||||
|
||||
supports-color@^3.2.3:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
|
||||
dependencies:
|
||||
has-flag "^1.0.0"
|
||||
|
||||
ua-parser-js@^0.7.9:
|
||||
version "0.7.17"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
|
||||
|
||||
warning@^3.0.0:
|
||||
resolve-from@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
|
||||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
|
||||
integrity sha1-six699nWiBvItuZTM17rywoYh0g=
|
||||
|
||||
whatwg-fetch@>=0.10.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
|
||||
resolve@^1.10.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232"
|
||||
integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==
|
||||
dependencies:
|
||||
path-parse "^1.0.6"
|
||||
|
||||
safe-buffer@~5.1.1:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
source-map@^0.5.7:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
|
||||
|
||||
@@ -37,4 +37,210 @@ import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
|
||||
## Customization
|
||||
|
||||
See [pagination props](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html)
|
||||
### Basic Customization
|
||||
|
||||
`react-bootstrap-table2` give some simple ways to customize something like text, styling etc, following is all the props we support for basic customization:
|
||||
|
||||
* [paginationSize](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationpaginationsize-number)
|
||||
* [sizePerPageList](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationsizeperpagelist-array)
|
||||
* [withFirstAndLast](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationwithfirstandlast-bool)
|
||||
* [alwaysShowAllBtns](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationalwaysshowallbtns-bool)
|
||||
* [firstPageText](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationfirstpagetext-any)
|
||||
* [prePageText](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationprepagetext-any)
|
||||
* [nextPageText](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationnextpagetext-any)
|
||||
* [lastPageText](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationlastpagetext-any)
|
||||
* [firstPageTitle](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationfirstpagetitle-any)
|
||||
* [prePageTitle](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationprepagetitle-any)
|
||||
* [nextPageTitle](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationnextpagetitle-any)
|
||||
* [lastPageTitle](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationlastpagetitle-any)
|
||||
* [hideSizePerPage](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationhidesizeperpage-bool)
|
||||
* [hidePageListOnlyOnePage](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationhidepagelistonlyonepage-bool)
|
||||
* [showTotal](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationshowtotal-bool)
|
||||
|
||||
You can check [this online demo](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html?selectedKind=Pagination&selectedStory=Custom%20Pagination&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybook%2Factions%2Factions-panel) for above props usage.
|
||||
|
||||
### Advance Customization
|
||||
|
||||
Sometime, you may feel above props is not satisfied with your requirement, don't worry, we provide following renderer for each part of pagination:
|
||||
|
||||
* [pageListRenderer](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationpagelistrenderer-function)
|
||||
* [pageButtonRenderer](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationpagebuttonrenderer-function)
|
||||
* [sizePerPageRenderer](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationsizeperpagerenderer-function)
|
||||
* [sizePerPageOptionRenderer](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationsizeperpageoptionrenderer-function)
|
||||
* [paginationTotalRenderer](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html#paginationpaginationtotalrenderer-function)
|
||||
|
||||
### Fully Customization
|
||||
|
||||
If you want to customize the pagination component completely, you may get interesting on following solutions:
|
||||
|
||||
* Standalone
|
||||
* Non-standalone
|
||||
|
||||
`react-bootstrap-table2-paginator` have a `PaginationProvider` which is a react context and that will be easier to customize the pagination components under the scope of `PaginationProvider`. Let's introduce it step by step:
|
||||
|
||||
#### 1. Import PaginationProvider
|
||||
|
||||
```js
|
||||
import paginationFactory, { PaginationProvider } from 'react-bootstrap-table2-paginator';
|
||||
|
||||
```
|
||||
|
||||
#### 2. Declare custom and totalSize in pagination option:
|
||||
|
||||
```js
|
||||
const paginationOption = {
|
||||
custom: true,
|
||||
totalSize: products.length
|
||||
};
|
||||
```
|
||||
|
||||
#### 3. Render PaginationProvider
|
||||
|
||||
```js
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
.....
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
```
|
||||
|
||||
`PaginationProvider` actually is a wrapper for the concumser of react context, so that now you have to get the props from context provide then render to your compoennt and `BootstrapTable`:
|
||||
|
||||
* `paginationProps`: this include everything about pagination, you will use it when you render standalone component or your custom component.
|
||||
* `paginationTableProps`: you don't need to know about this, but you have to render this as props to `BootstrapTable`.
|
||||
|
||||
So far, your customization pagination is supposed to look like it:
|
||||
```js
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
```
|
||||
|
||||
Now, you have to choose which solution you like: standalone or non-standalone ?
|
||||
|
||||
#### 4.1 Use Standalone Component
|
||||
`react-bootstrap-table2-paginator` provider three standalone components:
|
||||
|
||||
* Size Per Page Dropdwn Standalone
|
||||
* Pagination List Standalone
|
||||
* Pagination Total Standalone
|
||||
|
||||
When render each standalone, you just need to pass the `paginationProps` props to standalone component:
|
||||
|
||||
```js
|
||||
import paginationFactory, {
|
||||
PaginationProvider,
|
||||
PaginationListStandalone,
|
||||
SizePerPageDropdownStandalone,
|
||||
PaginationTotalStandalone
|
||||
} from 'react-bootstrap-table2-paginator';
|
||||
|
||||
<PaginationProvider
|
||||
pagination={ paginationFactory(options) }
|
||||
>
|
||||
{
|
||||
({
|
||||
paginationProps,
|
||||
paginationTableProps
|
||||
}) => (
|
||||
<div>
|
||||
<SizePerPageDropdownStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
<PaginationTotalStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
{ ...paginationTableProps }
|
||||
/>
|
||||
<PaginationListStandalone
|
||||
{ ...paginationProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PaginationProvider>
|
||||
```
|
||||
|
||||
That's it!! The benifit for using standalone is you can much easier to render the standalone component in any posistion. In the future, we will implement more featue like applying `style`, `className` etc on standalone components.
|
||||
|
||||
##### Customizable props for `PaginationListStandalone`
|
||||
* N/A
|
||||
|
||||
##### Customizable props for `SizePerPageDropdownStandalone`
|
||||
* `open`: `true` to make dropdown show.
|
||||
* `hidden`: `true` to hide the size per page dropdown.
|
||||
* `btnContextual`: Set the button contextual
|
||||
* `variation`: Variation for dropdown, available value is `dropdown` and `dropup`.
|
||||
* `className`: Custom the class on size per page dropdown
|
||||
|
||||
##### Customizable props for `SizePerPageDropdownStandalone`
|
||||
* N/A
|
||||
|
||||
#### 4.2 Customization Everything
|
||||
|
||||
If you choose to custom the pagination component by yourself, the `paginationProps` will be important for you. Becasue you have to know for example how to change page or what's the current page etc. Hence, following is all the props in `paginationProps` object:
|
||||
|
||||
```js
|
||||
page,
|
||||
sizePerPage,
|
||||
pageStartIndex,
|
||||
hidePageListOnlyOnePage,
|
||||
hideSizePerPage,
|
||||
alwaysShowAllBtns,
|
||||
withFirstAndLast,
|
||||
dataSize,
|
||||
sizePerPageList,
|
||||
paginationSize,
|
||||
showTotal,
|
||||
pageListRenderer,
|
||||
pageButtonRenderer,
|
||||
sizePerPageRenderer,
|
||||
paginationTotalRenderer,
|
||||
sizePerPageOptionRenderer,
|
||||
firstPageText,
|
||||
prePageText,
|
||||
nextPageText,
|
||||
lastPageText,
|
||||
prePageTitle,
|
||||
nextPageTitle,
|
||||
firstPageTitle,
|
||||
lastPageTitle,
|
||||
onPageChange,
|
||||
onSizePerPageChange
|
||||
```
|
||||
|
||||
In most of case, `page`, `sizePerPage`, `onPageChange` and `onSizePerPageChange` are most important things for developer.
|
||||
|
||||
* `page`: Current page.
|
||||
* `sizePerPage`: Current size per page.
|
||||
* `onPageChange`: Call it when you nede to change page. This function accept one number argument which indicate the new page
|
||||
* `onSizePerPageChange`: Call it when you nede to change size per page. This function accept two number argument which indicate the new sizePerPage and new page
|
||||
|
||||
[Here](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html?selectedKind=Pagination&selectedStory=Fully%20Custom%20Pagination&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybook%2Factions%2Factions-panel) is a online example.
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
import createContext from './src/context';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import createBaseContext from './src/state-context';
|
||||
import createDataContext from './src/data-context';
|
||||
import PaginationListStandalone from './src/pagination-list-standalone';
|
||||
import SizePerPageDropdownStandalone from './src/size-per-page-dropdown-standalone';
|
||||
import PaginationTotalStandalone from './src/pagination-total-standalone';
|
||||
|
||||
export default (options = {}) => ({
|
||||
createContext,
|
||||
createContext: createDataContext,
|
||||
options
|
||||
});
|
||||
|
||||
const { Provider, Consumer } = createBaseContext();
|
||||
|
||||
const CustomizableProvider = props => (
|
||||
<Provider { ...props }>
|
||||
<Consumer>{ paginationProps => props.children(paginationProps) }</Consumer>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
CustomizableProvider.propTypes = {
|
||||
children: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export const PaginationProvider = CustomizableProvider;
|
||||
export { PaginationListStandalone, SizePerPageDropdownStandalone, PaginationTotalStandalone };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-paginator",
|
||||
"version": "1.0.3",
|
||||
"version": "2.0.6",
|
||||
"description": "it's the pagination addon for react-bootstrap-table2",
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
/* eslint react/require-default-props: 0 */
|
||||
/* eslint no-lonely-if: 0 */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Const from './const';
|
||||
import { BootstrapContext } from './bootstrap';
|
||||
import Pagination from './pagination';
|
||||
import { getByCurrPage, alignPage } from './page';
|
||||
|
||||
export default (
|
||||
isRemotePagination,
|
||||
handleRemotePageChange
|
||||
) => {
|
||||
const PaginationContext = React.createContext();
|
||||
|
||||
class PaginationProvider extends React.Component {
|
||||
static propTypes = {
|
||||
data: PropTypes.array.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleChangePage = this.handleChangePage.bind(this);
|
||||
this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
|
||||
|
||||
let currPage;
|
||||
let currSizePerPage;
|
||||
const { options } = props.pagination;
|
||||
const sizePerPageList = options.sizePerPageList || Const.SIZE_PER_PAGE_LIST;
|
||||
|
||||
// initialize current page
|
||||
if (typeof options.page !== 'undefined') {
|
||||
currPage = options.page;
|
||||
} else if (typeof options.pageStartIndex !== 'undefined') {
|
||||
currPage = options.pageStartIndex;
|
||||
} else {
|
||||
currPage = Const.PAGE_START_INDEX;
|
||||
}
|
||||
|
||||
// initialize current sizePerPage
|
||||
if (typeof options.sizePerPage !== 'undefined') {
|
||||
currSizePerPage = options.sizePerPage;
|
||||
} else if (typeof sizePerPageList[0] === 'object') {
|
||||
currSizePerPage = sizePerPageList[0].value;
|
||||
} else {
|
||||
currSizePerPage = sizePerPageList[0];
|
||||
}
|
||||
|
||||
this.currPage = currPage;
|
||||
this.currSizePerPage = currSizePerPage;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
let needNewState = false;
|
||||
let { currPage } = this;
|
||||
const { currSizePerPage } = this;
|
||||
const { onPageChange } = nextProps.pagination.options;
|
||||
|
||||
const pageStartIndex = typeof nextProps.pagination.options.pageStartIndex !== 'undefined' ?
|
||||
nextProps.pagination.options.pageStartIndex : Const.PAGE_START_INDEX;
|
||||
|
||||
// user should align the page when the page is not fit to the data size when remote enable
|
||||
if (!isRemotePagination()) {
|
||||
const newPage = alignPage(nextProps.data, currPage, currSizePerPage, pageStartIndex);
|
||||
if (currPage !== newPage) {
|
||||
currPage = newPage;
|
||||
needNewState = true;
|
||||
}
|
||||
} else {
|
||||
this.currPage = nextProps.pagination.options.page;
|
||||
this.currSizePerPage = nextProps.pagination.options.sizePerPage;
|
||||
}
|
||||
|
||||
if (needNewState) {
|
||||
if (onPageChange) {
|
||||
onPageChange(currPage, currSizePerPage);
|
||||
}
|
||||
this.currPage = currPage;
|
||||
this.currSizePerPage = currSizePerPage;
|
||||
}
|
||||
}
|
||||
|
||||
handleChangePage(currPage) {
|
||||
const { currSizePerPage } = this;
|
||||
const { pagination: { options } } = this.props;
|
||||
|
||||
if (options.onPageChange) {
|
||||
options.onPageChange(currPage, currSizePerPage);
|
||||
}
|
||||
|
||||
this.currPage = currPage;
|
||||
|
||||
if (isRemotePagination()) {
|
||||
handleRemotePageChange(currPage, currSizePerPage);
|
||||
return;
|
||||
}
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
handleChangeSizePerPage(currSizePerPage, currPage) {
|
||||
const { pagination: { options } } = this.props;
|
||||
|
||||
if (options.onSizePerPageChange) {
|
||||
options.onSizePerPageChange(currSizePerPage, currPage);
|
||||
}
|
||||
|
||||
this.currPage = currPage;
|
||||
this.currSizePerPage = currSizePerPage;
|
||||
|
||||
if (isRemotePagination()) {
|
||||
handleRemotePageChange(currPage, currSizePerPage);
|
||||
return;
|
||||
}
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
render() {
|
||||
let { data } = this.props;
|
||||
const { pagination: { options }, bootstrap4 } = this.props;
|
||||
const { currPage, currSizePerPage } = this;
|
||||
const withFirstAndLast = typeof options.withFirstAndLast === 'undefined' ?
|
||||
Const.With_FIRST_AND_LAST : options.withFirstAndLast;
|
||||
const alwaysShowAllBtns = typeof options.alwaysShowAllBtns === 'undefined' ?
|
||||
Const.SHOW_ALL_PAGE_BTNS : options.alwaysShowAllBtns;
|
||||
const hideSizePerPage = typeof options.hideSizePerPage === 'undefined' ?
|
||||
Const.HIDE_SIZE_PER_PAGE : options.hideSizePerPage;
|
||||
const hidePageListOnlyOnePage = typeof options.hidePageListOnlyOnePage === 'undefined' ?
|
||||
Const.HIDE_PAGE_LIST_ONLY_ONE_PAGE : options.hidePageListOnlyOnePage;
|
||||
const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
|
||||
Const.PAGE_START_INDEX : options.pageStartIndex;
|
||||
|
||||
data = isRemotePagination() ?
|
||||
data :
|
||||
getByCurrPage(
|
||||
data,
|
||||
currPage,
|
||||
currSizePerPage,
|
||||
pageStartIndex
|
||||
);
|
||||
|
||||
return (
|
||||
<PaginationContext.Provider value={ { data } }>
|
||||
{ this.props.children }
|
||||
<BootstrapContext.Provider value={ { bootstrap4 } }>
|
||||
<Pagination
|
||||
key="pagination"
|
||||
dataSize={ options.totalSize || this.props.data.length }
|
||||
currPage={ currPage }
|
||||
currSizePerPage={ currSizePerPage }
|
||||
onPageChange={ this.handleChangePage }
|
||||
onSizePerPageChange={ this.handleChangeSizePerPage }
|
||||
sizePerPageList={ options.sizePerPageList || Const.SIZE_PER_PAGE_LIST }
|
||||
paginationSize={ options.paginationSize || Const.PAGINATION_SIZE }
|
||||
pageStartIndex={ pageStartIndex }
|
||||
withFirstAndLast={ withFirstAndLast }
|
||||
alwaysShowAllBtns={ alwaysShowAllBtns }
|
||||
hideSizePerPage={ hideSizePerPage }
|
||||
hidePageListOnlyOnePage={ hidePageListOnlyOnePage }
|
||||
showTotal={ options.showTotal }
|
||||
paginationTotalRenderer={ options.paginationTotalRenderer }
|
||||
firstPageText={ options.firstPageText || Const.FIRST_PAGE_TEXT }
|
||||
prePageText={ options.prePageText || Const.PRE_PAGE_TEXT }
|
||||
nextPageText={ options.nextPageText || Const.NEXT_PAGE_TEXT }
|
||||
lastPageText={ options.lastPageText || Const.LAST_PAGE_TEXT }
|
||||
prePageTitle={ options.prePageTitle || Const.PRE_PAGE_TITLE }
|
||||
nextPageTitle={ options.nextPageTitle || Const.NEXT_PAGE_TITLE }
|
||||
firstPageTitle={ options.firstPageTitle || Const.FIRST_PAGE_TITLE }
|
||||
lastPageTitle={ options.lastPageTitle || Const.LAST_PAGE_TITLE }
|
||||
/>
|
||||
</BootstrapContext.Provider>
|
||||
</PaginationContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
Provider: PaginationProvider,
|
||||
Consumer: PaginationContext.Consumer
|
||||
};
|
||||
};
|
||||
108
packages/react-bootstrap-table2-paginator/src/data-context.js
vendored
Normal file
108
packages/react-bootstrap-table2-paginator/src/data-context.js
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
/* eslint react/require-default-props: 0 */
|
||||
/* eslint no-lonely-if: 0 */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Const from './const';
|
||||
import { BootstrapContext } from './bootstrap';
|
||||
import Pagination from './pagination';
|
||||
import { getByCurrPage, alignPage } from './page';
|
||||
import createBaseContext from './state-context';
|
||||
|
||||
const { Provider } = createBaseContext();
|
||||
|
||||
const PaginationDataContext = React.createContext();
|
||||
|
||||
class PaginationDataProvider extends Provider {
|
||||
static propTypes = {
|
||||
data: PropTypes.array.isRequired,
|
||||
remoteEmitter: PropTypes.object.isRequired,
|
||||
isRemotePagination: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
super.componentWillReceiveProps(nextProps);
|
||||
const { currSizePerPage } = this;
|
||||
const { custom, onPageChange } = nextProps.pagination.options;
|
||||
|
||||
const pageStartIndex = typeof nextProps.pagination.options.pageStartIndex !== 'undefined' ?
|
||||
nextProps.pagination.options.pageStartIndex : Const.PAGE_START_INDEX;
|
||||
|
||||
// user should align the page when the page is not fit to the data size when remote enable
|
||||
if (!this.isRemotePagination() && !custom) {
|
||||
const newPage = alignPage(
|
||||
nextProps.data.length,
|
||||
this.props.data.length,
|
||||
this.currPage,
|
||||
currSizePerPage,
|
||||
pageStartIndex
|
||||
);
|
||||
|
||||
if (this.currPage !== newPage) {
|
||||
if (onPageChange) {
|
||||
onPageChange(newPage, currSizePerPage);
|
||||
}
|
||||
this.currPage = newPage;
|
||||
}
|
||||
}
|
||||
if (nextProps.onDataSizeChange && nextProps.data.length !== this.props.data.length) {
|
||||
nextProps.onDataSizeChange({ dataSize: nextProps.data.length });
|
||||
}
|
||||
}
|
||||
|
||||
isRemotePagination = () => this.props.isRemotePagination();
|
||||
|
||||
renderDefaultPagination = () => {
|
||||
if (!this.props.pagination.options.custom) {
|
||||
const {
|
||||
bootstrap4,
|
||||
page: currPage,
|
||||
sizePerPage: currSizePerPage,
|
||||
dataSize,
|
||||
...rest
|
||||
} = this.getPaginationProps();
|
||||
return (
|
||||
<BootstrapContext.Provider value={ { bootstrap4 } }>
|
||||
<Pagination
|
||||
{ ...rest }
|
||||
key="pagination"
|
||||
dataSize={ dataSize || this.props.data.length }
|
||||
currPage={ currPage }
|
||||
currSizePerPage={ currSizePerPage }
|
||||
/>
|
||||
</BootstrapContext.Provider>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
let { data } = this.props;
|
||||
const { pagination: { options } } = this.props;
|
||||
const { currPage, currSizePerPage } = this;
|
||||
const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
|
||||
Const.PAGE_START_INDEX : options.pageStartIndex;
|
||||
|
||||
data = this.isRemotePagination() ?
|
||||
data :
|
||||
getByCurrPage(
|
||||
data,
|
||||
currPage,
|
||||
currSizePerPage,
|
||||
pageStartIndex
|
||||
);
|
||||
|
||||
return (
|
||||
<PaginationDataContext.Provider value={ { data, setRemoteEmitter: this.setRemoteEmitter } }>
|
||||
{ this.props.children }
|
||||
{ this.renderDefaultPagination() }
|
||||
</PaginationDataContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => ({
|
||||
Provider: PaginationDataProvider,
|
||||
Consumer: PaginationDataContext.Consumer
|
||||
});
|
||||
@@ -20,13 +20,14 @@ class PageButton extends Component {
|
||||
page,
|
||||
title,
|
||||
active,
|
||||
disabled
|
||||
disabled,
|
||||
className
|
||||
} = this.props;
|
||||
const classes = cs({
|
||||
active,
|
||||
disabled,
|
||||
'page-item': true
|
||||
});
|
||||
}, className);
|
||||
|
||||
return (
|
||||
<li className={ classes } title={ title }>
|
||||
@@ -41,6 +42,7 @@ PageButton.propTypes = {
|
||||
page: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
|
||||
active: PropTypes.bool.isRequired,
|
||||
disabled: PropTypes.bool.isRequired,
|
||||
className: PropTypes.string,
|
||||
title: PropTypes.string
|
||||
};
|
||||
|
||||
|
||||
@@ -8,16 +8,10 @@ export default ExtendBase =>
|
||||
return (currPage - 1) < pageStartIndex ? pageStartIndex : currPage - 1;
|
||||
}
|
||||
|
||||
goToNextPage() {
|
||||
const { currPage } = this.props;
|
||||
const { lastPage } = this.state;
|
||||
return (currPage + 1) > lastPage ? lastPage : currPage + 1;
|
||||
}
|
||||
|
||||
initialState() {
|
||||
const totalPages = this.calculateTotalPage();
|
||||
const lastPage = this.calculateLastPage(totalPages);
|
||||
return { totalPages, lastPage, dropdownOpen: false };
|
||||
return { totalPages, lastPage };
|
||||
}
|
||||
|
||||
calculateTotalPage(sizePerPage = this.props.currSizePerPage, dataSize = this.props.dataSize) {
|
||||
@@ -47,8 +41,9 @@ export default ExtendBase =>
|
||||
}
|
||||
|
||||
calculatePages(
|
||||
totalPages = this.state.totalPages,
|
||||
lastPage = this.state.lastPage) {
|
||||
totalPages,
|
||||
lastPage
|
||||
) {
|
||||
const {
|
||||
currPage,
|
||||
paginationSize,
|
||||
@@ -61,7 +56,7 @@ export default ExtendBase =>
|
||||
alwaysShowAllBtns
|
||||
} = this.props;
|
||||
|
||||
let pages;
|
||||
let pages = [];
|
||||
let endPage = totalPages;
|
||||
if (endPage <= 0) return [];
|
||||
|
||||
@@ -73,28 +68,46 @@ export default ExtendBase =>
|
||||
startPage = endPage - paginationSize + 1;
|
||||
}
|
||||
|
||||
if (startPage !== pageStartIndex && totalPages > paginationSize && withFirstAndLast) {
|
||||
if (alwaysShowAllBtns) {
|
||||
if (withFirstAndLast) {
|
||||
pages = [firstPageText, prePageText];
|
||||
} else {
|
||||
pages = [prePageText];
|
||||
}
|
||||
}
|
||||
|
||||
if (startPage !== pageStartIndex &&
|
||||
totalPages > paginationSize &&
|
||||
withFirstAndLast &&
|
||||
pages.length === 0
|
||||
) {
|
||||
pages = [firstPageText, prePageText];
|
||||
} else if (totalPages > 1 || alwaysShowAllBtns) {
|
||||
} else if (totalPages > 1 && pages.length === 0) {
|
||||
pages = [prePageText];
|
||||
} else {
|
||||
pages = [];
|
||||
}
|
||||
|
||||
for (let i = startPage; i <= endPage; i += 1) {
|
||||
if (i >= pageStartIndex) pages.push(i);
|
||||
}
|
||||
|
||||
if (endPage <= lastPage && pages.length > 1) {
|
||||
if (alwaysShowAllBtns || (endPage <= lastPage && pages.length > 1)) {
|
||||
pages.push(nextPageText);
|
||||
}
|
||||
if (endPage !== lastPage && withFirstAndLast) {
|
||||
if ((endPage !== lastPage && withFirstAndLast) || (withFirstAndLast && alwaysShowAllBtns)) {
|
||||
pages.push(lastPageText);
|
||||
}
|
||||
|
||||
// if ((endPage <= lastPage && pages.length > 1) || alwaysShowAllBtns) {
|
||||
// pages.push(nextPageText);
|
||||
// }
|
||||
// if (endPage !== lastPage && withFirstAndLast) {
|
||||
// pages.push(lastPageText);
|
||||
// }
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
calculatePageStatus(pages = [], lastPage = this.state.lastPage) {
|
||||
calculatePageStatus(pages = [], lastPage) {
|
||||
const {
|
||||
currPage,
|
||||
pageStartIndex,
|
||||
@@ -140,8 +153,8 @@ export default ExtendBase =>
|
||||
calculateSizePerPageStatus() {
|
||||
const { sizePerPageList } = this.props;
|
||||
return sizePerPageList.map((_sizePerPage) => {
|
||||
const pageText = _sizePerPage.text || _sizePerPage;
|
||||
const pageNumber = _sizePerPage.value || _sizePerPage;
|
||||
const pageText = typeof _sizePerPage.text !== 'undefined' ? _sizePerPage.text : _sizePerPage;
|
||||
const pageNumber = typeof _sizePerPage.value !== 'undefined' ? _sizePerPage.value : _sizePerPage;
|
||||
return {
|
||||
text: `${pageText}`,
|
||||
page: pageNumber
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import Const from './const';
|
||||
|
||||
const getNormalizedPage = (
|
||||
page,
|
||||
pageStartIndex
|
||||
@@ -18,15 +20,21 @@ const startIndex = (
|
||||
) => end - (sizePerPage - 1);
|
||||
|
||||
export const alignPage = (
|
||||
data,
|
||||
dataSize,
|
||||
prevDataSize,
|
||||
page,
|
||||
sizePerPage,
|
||||
pageStartIndex
|
||||
) => {
|
||||
const dataSize = data.length;
|
||||
|
||||
if (page < pageStartIndex || page > (Math.floor(dataSize / sizePerPage) + pageStartIndex)) {
|
||||
return pageStartIndex;
|
||||
if (prevDataSize < dataSize) return page;
|
||||
if (page < pageStartIndex) return pageStartIndex;
|
||||
if (dataSize <= 0) return pageStartIndex;
|
||||
if ((page >= (Math.floor(dataSize / sizePerPage) + pageStartIndex)) && pageStartIndex === 1) {
|
||||
return Math.ceil(dataSize / sizePerPage);
|
||||
}
|
||||
if (page >= Math.floor(dataSize / sizePerPage) && pageStartIndex === 0) {
|
||||
const newPage = Math.ceil(dataSize / sizePerPage);
|
||||
return newPage - Math.abs((Const.PAGE_START_INDEX - pageStartIndex));
|
||||
}
|
||||
return page;
|
||||
};
|
||||
|
||||
77
packages/react-bootstrap-table2-paginator/src/pagination-handler.js
vendored
Normal file
77
packages/react-bootstrap-table2-paginator/src/pagination-handler.js
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import pageResolver from './page-resolver';
|
||||
|
||||
export default WrappedComponent =>
|
||||
class PaginationHandler extends pageResolver(Component) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleChangePage = this.handleChangePage.bind(this);
|
||||
this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
|
||||
this.state = this.initialState();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { dataSize, currSizePerPage } = nextProps;
|
||||
if (currSizePerPage !== this.props.currSizePerPage || dataSize !== this.props.dataSize) {
|
||||
const totalPages = this.calculateTotalPage(currSizePerPage, dataSize);
|
||||
const lastPage = this.calculateLastPage(totalPages);
|
||||
this.setState({ totalPages, lastPage });
|
||||
}
|
||||
}
|
||||
|
||||
handleChangeSizePerPage(sizePerPage) {
|
||||
const { currSizePerPage, onSizePerPageChange } = this.props;
|
||||
const selectedSize = typeof sizePerPage === 'string' ? parseInt(sizePerPage, 10) : sizePerPage;
|
||||
let { currPage } = this.props;
|
||||
if (selectedSize !== currSizePerPage) {
|
||||
const newTotalPages = this.calculateTotalPage(selectedSize);
|
||||
const newLastPage = this.calculateLastPage(newTotalPages);
|
||||
if (currPage > newLastPage) currPage = newLastPage;
|
||||
onSizePerPageChange(selectedSize, currPage);
|
||||
}
|
||||
}
|
||||
|
||||
handleChangePage(newPage) {
|
||||
let page;
|
||||
const {
|
||||
currPage,
|
||||
pageStartIndex,
|
||||
prePageText,
|
||||
nextPageText,
|
||||
lastPageText,
|
||||
firstPageText,
|
||||
onPageChange
|
||||
} = this.props;
|
||||
const { lastPage } = this.state;
|
||||
|
||||
if (newPage === prePageText) {
|
||||
page = this.backToPrevPage();
|
||||
} else if (newPage === nextPageText) {
|
||||
page = (currPage + 1) > lastPage ? lastPage : currPage + 1;
|
||||
} else if (newPage === lastPageText) {
|
||||
page = lastPage;
|
||||
} else if (newPage === firstPageText) {
|
||||
page = pageStartIndex;
|
||||
} else {
|
||||
page = parseInt(newPage, 10);
|
||||
}
|
||||
if (page !== currPage) {
|
||||
onPageChange(page);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<WrappedComponent
|
||||
{ ...this.props }
|
||||
lastPage={ this.state.lastPage }
|
||||
totalPages={ this.state.totalPages }
|
||||
onPageChange={ this.handleChangePage }
|
||||
onSizePerPageChange={ this.handleChangeSizePerPage }
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
24
packages/react-bootstrap-table2-paginator/src/pagination-list-adapter.js
vendored
Normal file
24
packages/react-bootstrap-table2-paginator/src/pagination-list-adapter.js
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import pageResolver from './page-resolver';
|
||||
import PaginationList from './pagination-list';
|
||||
|
||||
const paginationListAdapter = WrappedComponent =>
|
||||
class PaginationListAdapter extends pageResolver(Component) {
|
||||
render() {
|
||||
const { lastPage, totalPages, pageButtonRenderer, onPageChange } = this.props;
|
||||
const pages = this.calculatePageStatus(this.calculatePages(totalPages, lastPage), lastPage);
|
||||
return (
|
||||
<WrappedComponent
|
||||
pageButtonRenderer={ pageButtonRenderer }
|
||||
onPageChange={ onPageChange }
|
||||
pages={ pages }
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const PaginationListWithAdapter = paginationListAdapter(PaginationList);
|
||||
export default paginationListAdapter;
|
||||
12
packages/react-bootstrap-table2-paginator/src/pagination-list-standalone.js
vendored
Normal file
12
packages/react-bootstrap-table2-paginator/src/pagination-list-standalone.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import PaginationList from './pagination-list';
|
||||
import standaloneAdapter from './standalone-adapter';
|
||||
import PaginationHandler from './pagination-handler';
|
||||
import paginationListAdapter from './pagination-list-adapter';
|
||||
|
||||
const PaginationListStandalone = props => (
|
||||
<PaginationList { ...props } />
|
||||
);
|
||||
|
||||
export default
|
||||
standaloneAdapter(PaginationHandler(paginationListAdapter(PaginationListStandalone)));
|
||||
@@ -6,13 +6,21 @@ import PageButton from './page-button';
|
||||
const PaginatonList = props => (
|
||||
<ul className="pagination react-bootstrap-table-page-btns-ul">
|
||||
{
|
||||
props.pages.map(pageProps => (
|
||||
<PageButton
|
||||
key={ pageProps.page }
|
||||
{ ...pageProps }
|
||||
onPageChange={ props.onPageChange }
|
||||
/>
|
||||
))
|
||||
props.pages.map((pageProps) => {
|
||||
if (props.pageButtonRenderer) {
|
||||
return props.pageButtonRenderer({
|
||||
...pageProps,
|
||||
onPageChange: props.onPageChange
|
||||
});
|
||||
}
|
||||
return (
|
||||
<PageButton
|
||||
key={ pageProps.page }
|
||||
{ ...pageProps }
|
||||
onPageChange={ props.onPageChange }
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
);
|
||||
@@ -24,7 +32,12 @@ PaginatonList.propTypes = {
|
||||
disable: PropTypes.bool,
|
||||
title: PropTypes.string
|
||||
})).isRequired,
|
||||
onPageChange: PropTypes.func.isRequired
|
||||
onPageChange: PropTypes.func.isRequired,
|
||||
pageButtonRenderer: PropTypes.func
|
||||
};
|
||||
|
||||
PaginatonList.defaultProps = {
|
||||
pageButtonRenderer: null
|
||||
};
|
||||
|
||||
export default PaginatonList;
|
||||
|
||||
24
packages/react-bootstrap-table2-paginator/src/pagination-total-adapter.js
vendored
Normal file
24
packages/react-bootstrap-table2-paginator/src/pagination-total-adapter.js
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import pageResolver from './page-resolver';
|
||||
import PaginationTotal from './pagination-total';
|
||||
|
||||
const paginationTotalAdapter = WrappedComponent =>
|
||||
class PaginationTotalAdapter extends pageResolver(Component) {
|
||||
render() {
|
||||
const [from, to] = this.calculateFromTo();
|
||||
return (
|
||||
<WrappedComponent
|
||||
from={ from }
|
||||
to={ to }
|
||||
dataSize={ this.props.dataSize }
|
||||
paginationTotalRenderer={ this.props.paginationTotalRenderer }
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const PaginationTotalWithAdapter = paginationTotalAdapter(PaginationTotal);
|
||||
export default paginationTotalAdapter;
|
||||
11
packages/react-bootstrap-table2-paginator/src/pagination-total-standalone.js
vendored
Normal file
11
packages/react-bootstrap-table2-paginator/src/pagination-total-standalone.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import PaginationTotal from './pagination-total';
|
||||
import standaloneAdapter from './standalone-adapter';
|
||||
import paginationTotalAdapter from './pagination-total-adapter';
|
||||
|
||||
const PaginationTotalStandalone = props => (
|
||||
<PaginationTotal { ...props } />
|
||||
);
|
||||
|
||||
export default
|
||||
standaloneAdapter(paginationTotalAdapter(PaginationTotalStandalone));
|
||||
@@ -1,16 +1,26 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const PaginationTotal = props => (
|
||||
<span className="react-bootstrap-table-pagination-total">
|
||||
Showing rows { props.from } to { props.to + 1 } of { props.dataSize }
|
||||
</span>
|
||||
);
|
||||
const PaginationTotal = (props) => {
|
||||
if (props.paginationTotalRenderer) {
|
||||
return props.paginationTotalRenderer(props.from, props.to, props.dataSize);
|
||||
}
|
||||
return (
|
||||
<span className="react-bootstrap-table-pagination-total">
|
||||
Showing rows { props.from } to { props.to } of { props.dataSize }
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
PaginationTotal.propTypes = {
|
||||
from: PropTypes.number.isRequired,
|
||||
to: PropTypes.number.isRequired,
|
||||
dataSize: PropTypes.number.isRequired
|
||||
dataSize: PropTypes.number.isRequired,
|
||||
paginationTotalRenderer: PropTypes.func
|
||||
};
|
||||
|
||||
PaginationTotal.defaultProps = {
|
||||
paginationTotalRenderer: undefined
|
||||
};
|
||||
|
||||
export default PaginationTotal;
|
||||
|
||||
@@ -4,118 +4,36 @@ import cs from 'classnames';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import pageResolver from './page-resolver';
|
||||
import SizePerPageDropDown from './size-per-page-dropdown';
|
||||
import PaginationList from './pagination-list';
|
||||
import PaginationTotal from './pagination-total';
|
||||
import paginationHandler from './pagination-handler';
|
||||
import { SizePerPageDropdownWithAdapter } from './size-per-page-dropdown-adapter';
|
||||
import { PaginationListWithAdapter } from './pagination-list-adapter';
|
||||
import { PaginationTotalWithAdapter } from './pagination-total-adapter';
|
||||
import Const from './const';
|
||||
|
||||
class Pagination extends pageResolver(Component) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.closeDropDown = this.closeDropDown.bind(this);
|
||||
this.toggleDropDown = this.toggleDropDown.bind(this);
|
||||
this.handleChangePage = this.handleChangePage.bind(this);
|
||||
this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
|
||||
this.state = this.initialState();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { dataSize, currSizePerPage } = nextProps;
|
||||
if (currSizePerPage !== this.props.currSizePerPage || dataSize !== this.props.dataSize) {
|
||||
const totalPages = this.calculateTotalPage(currSizePerPage, dataSize);
|
||||
const lastPage = this.calculateLastPage(totalPages);
|
||||
this.setState({ totalPages, lastPage });
|
||||
}
|
||||
}
|
||||
|
||||
toggleDropDown() {
|
||||
const dropdownOpen = !this.state.dropdownOpen;
|
||||
this.setState(() => {
|
||||
return { dropdownOpen };
|
||||
});
|
||||
}
|
||||
|
||||
closeDropDown() {
|
||||
this.setState(() => {
|
||||
return { dropdownOpen: false };
|
||||
});
|
||||
}
|
||||
|
||||
handleChangeSizePerPage(sizePerPage) {
|
||||
const { currSizePerPage, onSizePerPageChange } = this.props;
|
||||
const selectedSize = typeof sizePerPage === 'string' ? parseInt(sizePerPage, 10) : sizePerPage;
|
||||
let { currPage } = this.props;
|
||||
if (selectedSize !== currSizePerPage) {
|
||||
const newTotalPages = this.calculateTotalPage(selectedSize);
|
||||
const newLastPage = this.calculateLastPage(newTotalPages);
|
||||
if (currPage > newLastPage) currPage = newLastPage;
|
||||
onSizePerPageChange(selectedSize, currPage);
|
||||
}
|
||||
this.closeDropDown();
|
||||
}
|
||||
|
||||
handleChangePage(newPage) {
|
||||
let page;
|
||||
render() {
|
||||
const {
|
||||
currPage,
|
||||
pageStartIndex,
|
||||
prePageText,
|
||||
nextPageText,
|
||||
lastPageText,
|
||||
firstPageText,
|
||||
onPageChange
|
||||
// keepSizePerPageState
|
||||
} = this.props;
|
||||
const { lastPage } = this.state;
|
||||
|
||||
if (newPage === prePageText) {
|
||||
page = this.backToPrevPage();
|
||||
} else if (newPage === nextPageText) {
|
||||
page = (currPage + 1) > lastPage ? lastPage : currPage + 1;
|
||||
} else if (newPage === lastPageText) {
|
||||
page = lastPage;
|
||||
} else if (newPage === firstPageText) {
|
||||
page = pageStartIndex;
|
||||
} else {
|
||||
page = parseInt(newPage, 10);
|
||||
}
|
||||
|
||||
// if (keepSizePerPageState) { this.closeDropDown(); }
|
||||
|
||||
if (page !== currPage) {
|
||||
onPageChange(page);
|
||||
}
|
||||
}
|
||||
|
||||
defaultTotal = (from, to, size) => (
|
||||
<PaginationTotal
|
||||
from={ from }
|
||||
to={ to }
|
||||
dataSize={ size }
|
||||
/>
|
||||
);
|
||||
|
||||
setTotal = (from, to, size, total) => {
|
||||
if (total && (typeof total === 'function')) {
|
||||
return total(from, to, size);
|
||||
}
|
||||
|
||||
return this.defaultTotal(from, to, size);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { totalPages, lastPage, dropdownOpen: open } = this.state;
|
||||
const {
|
||||
showTotal,
|
||||
dataSize,
|
||||
pageListRenderer,
|
||||
pageButtonRenderer,
|
||||
paginationTotalRenderer,
|
||||
hidePageListOnlyOnePage,
|
||||
totalPages,
|
||||
lastPage,
|
||||
onPageChange,
|
||||
sizePerPageList,
|
||||
currSizePerPage,
|
||||
hideSizePerPage,
|
||||
hidePageListOnlyOnePage
|
||||
sizePerPageRenderer,
|
||||
sizePerPageOptionRenderer,
|
||||
onSizePerPageChange,
|
||||
...rest
|
||||
} = this.props;
|
||||
const pages = this.calculatePageStatus(this.calculatePages(totalPages), lastPage);
|
||||
const [from, to] = this.calculateFromTo();
|
||||
|
||||
const pages = this.calculatePageStatus(this.calculatePages(totalPages, lastPage), lastPage);
|
||||
const pageListClass = cs(
|
||||
'react-bootstrap-table-pagination-list',
|
||||
'col-md-6 col-xs-6 col-sm-6 col-lg-6', {
|
||||
@@ -124,32 +42,44 @@ class Pagination extends pageResolver(Component) {
|
||||
return (
|
||||
<div className="row react-bootstrap-table-pagination">
|
||||
<div className="col-md-6 col-xs-6 col-sm-6 col-lg-6">
|
||||
{
|
||||
sizePerPageList.length > 1 && !hideSizePerPage ?
|
||||
(
|
||||
<SizePerPageDropDown
|
||||
currSizePerPage={ `${currSizePerPage}` }
|
||||
options={ this.calculateSizePerPageStatus() }
|
||||
onSizePerPageChange={ this.handleChangeSizePerPage }
|
||||
onClick={ this.toggleDropDown }
|
||||
onBlur={ this.closeDropDown }
|
||||
open={ open }
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
<SizePerPageDropdownWithAdapter
|
||||
sizePerPageList={ sizePerPageList }
|
||||
currSizePerPage={ currSizePerPage }
|
||||
hideSizePerPage={ hideSizePerPage }
|
||||
sizePerPageRenderer={ sizePerPageRenderer }
|
||||
sizePerPageOptionRenderer={ sizePerPageOptionRenderer }
|
||||
onSizePerPageChange={ onSizePerPageChange }
|
||||
/>
|
||||
{
|
||||
showTotal ?
|
||||
this.setTotal(
|
||||
from,
|
||||
to,
|
||||
dataSize,
|
||||
paginationTotalRenderer
|
||||
) : null
|
||||
<PaginationTotalWithAdapter
|
||||
currPage={ currPage }
|
||||
currSizePerPage={ currSizePerPage }
|
||||
pageStartIndex={ pageStartIndex }
|
||||
dataSize={ dataSize }
|
||||
paginationTotalRenderer={ paginationTotalRenderer }
|
||||
/> : null
|
||||
}
|
||||
</div>
|
||||
<div className={ pageListClass }>
|
||||
<PaginationList pages={ pages } onPageChange={ this.handleChangePage } />
|
||||
</div>
|
||||
{
|
||||
pageListRenderer ? pageListRenderer({
|
||||
pages,
|
||||
onPageChange
|
||||
}) : (
|
||||
<div className={ pageListClass }>
|
||||
<PaginationListWithAdapter
|
||||
{ ...rest }
|
||||
currPage={ currPage }
|
||||
currSizePerPage={ currSizePerPage }
|
||||
pageStartIndex={ pageStartIndex }
|
||||
lastPage={ lastPage }
|
||||
totalPages={ totalPages }
|
||||
pageButtonRenderer={ pageButtonRenderer }
|
||||
onPageChange={ onPageChange }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -165,7 +95,11 @@ Pagination.propTypes = {
|
||||
pageStartIndex: PropTypes.number,
|
||||
paginationSize: PropTypes.number,
|
||||
showTotal: PropTypes.bool,
|
||||
pageListRenderer: PropTypes.func,
|
||||
pageButtonRenderer: PropTypes.func,
|
||||
sizePerPageRenderer: PropTypes.func,
|
||||
paginationTotalRenderer: PropTypes.func,
|
||||
sizePerPageOptionRenderer: PropTypes.func,
|
||||
firstPageText: PropTypes.string,
|
||||
prePageText: PropTypes.string,
|
||||
nextPageText: PropTypes.string,
|
||||
@@ -186,7 +120,11 @@ Pagination.defaultProps = {
|
||||
withFirstAndLast: Const.With_FIRST_AND_LAST,
|
||||
alwaysShowAllBtns: Const.SHOW_ALL_PAGE_BTNS,
|
||||
showTotal: Const.SHOW_TOTAL,
|
||||
pageListRenderer: null,
|
||||
pageButtonRenderer: null,
|
||||
sizePerPageRenderer: null,
|
||||
paginationTotalRenderer: Const.PAGINATION_TOTAL,
|
||||
sizePerPageOptionRenderer: null,
|
||||
firstPageText: Const.FIRST_PAGE_TEXT,
|
||||
prePageText: Const.PRE_PAGE_TEXT,
|
||||
nextPageText: Const.NEXT_PAGE_TEXT,
|
||||
@@ -200,4 +138,4 @@ Pagination.defaultProps = {
|
||||
hidePageListOnlyOnePage: Const.HIDE_PAGE_LIST_ONLY_ONE_PAGE
|
||||
};
|
||||
|
||||
export default Pagination;
|
||||
export default paginationHandler(Pagination);
|
||||
|
||||
68
packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-adapter.js
vendored
Normal file
68
packages/react-bootstrap-table2-paginator/src/size-per-page-dropdown-adapter.js
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import pageResolver from './page-resolver';
|
||||
import SizePerPageDropDown from './size-per-page-dropdown';
|
||||
|
||||
const sizePerPageDropdownAdapter = WrappedComponent =>
|
||||
class SizePerPageDropdownAdapter extends pageResolver(Component) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.closeDropDown = this.closeDropDown.bind(this);
|
||||
this.toggleDropDown = this.toggleDropDown.bind(this);
|
||||
this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
|
||||
this.state = { dropdownOpen: false };
|
||||
}
|
||||
|
||||
toggleDropDown() {
|
||||
const dropdownOpen = !this.state.dropdownOpen;
|
||||
this.setState(() => ({ dropdownOpen }));
|
||||
}
|
||||
|
||||
closeDropDown() {
|
||||
this.setState(() => ({ dropdownOpen: false }));
|
||||
}
|
||||
|
||||
handleChangeSizePerPage(sizePerPage) {
|
||||
this.props.onSizePerPageChange(sizePerPage);
|
||||
this.closeDropDown();
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
sizePerPageList,
|
||||
currSizePerPage,
|
||||
hideSizePerPage,
|
||||
sizePerPageRenderer,
|
||||
sizePerPageOptionRenderer
|
||||
} = this.props;
|
||||
const { dropdownOpen: open } = this.state;
|
||||
|
||||
if (sizePerPageList.length > 1 && !hideSizePerPage) {
|
||||
if (sizePerPageRenderer) {
|
||||
return sizePerPageRenderer({
|
||||
options: this.calculateSizePerPageStatus(),
|
||||
currSizePerPage: `${currSizePerPage}`,
|
||||
onSizePerPageChange: this.handleChangeSizePerPage
|
||||
});
|
||||
}
|
||||
return (
|
||||
<WrappedComponent
|
||||
{ ...this.props }
|
||||
currSizePerPage={ `${currSizePerPage}` }
|
||||
options={ this.calculateSizePerPageStatus() }
|
||||
optionRenderer={ sizePerPageOptionRenderer }
|
||||
onSizePerPageChange={ this.handleChangeSizePerPage }
|
||||
onClick={ this.toggleDropDown }
|
||||
onBlur={ this.closeDropDown }
|
||||
open={ open }
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const SizePerPageDropdownWithAdapter = sizePerPageDropdownAdapter(SizePerPageDropDown);
|
||||
export default sizePerPageDropdownAdapter;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user