mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-06-29 13:40:07 +00:00
Compare commits
20 Commits
refactor/s
...
react-boot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae0cd8a32f | ||
|
|
51c82cdfb3 | ||
|
|
8e087329b3 | ||
|
|
ee2885d055 | ||
|
|
901307e471 | ||
|
|
4ff5be706a | ||
|
|
f8a3fedbb2 | ||
|
|
0bf5831b4e | ||
|
|
dd0b8c6b0f | ||
|
|
8f028d9dd4 | ||
|
|
2c68f22646 | ||
|
|
02d566bb32 | ||
|
|
2b12045017 | ||
|
|
0cdf086d56 | ||
|
|
d4fa9a84e3 | ||
|
|
c84fc84b9e | ||
|
|
ad8cdde513 | ||
|
|
db19e7dd9b | ||
|
|
33b36e5108 | ||
|
|
7209441eb6 |
@@ -13,7 +13,7 @@ Rebuilt [react-bootstrap-table](https://github.com/AllenFang/react-bootstrap-tab
|
|||||||
* [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
|
* [`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-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 kernal module(SRP).
|
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).
|
||||||
|
|
||||||
## Migration
|
## 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 the user from legacy [`react-bootstrap-table`](https://github.com/AllenFang/react-bootstrap-table/), please have a look on [this](./docs/migration.md).
|
||||||
@@ -40,4 +40,4 @@ $ yarn storybook
|
|||||||
$ Go to localhost:6006
|
$ 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)**
|
**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)**
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ $ npm install react-bootstrap-table2-editor --save
|
|||||||
* [blurToSave](#blurToSave)
|
* [blurToSave](#blurToSave)
|
||||||
* [nonEditableRows](#nonEditableRows)
|
* [nonEditableRows](#nonEditableRows)
|
||||||
* [timeToCloseMessage](#timeToCloseMessage)
|
* [timeToCloseMessage](#timeToCloseMessage)
|
||||||
|
* [autoSelectText](#autoSelectText)
|
||||||
* [beforeSaveCell](#beforeSaveCell)
|
* [beforeSaveCell](#beforeSaveCell)
|
||||||
* [afterSaveCell](#afterSaveCell)
|
* [afterSaveCell](#afterSaveCell)
|
||||||
* [errorMessage](#errorMessage)
|
* [errorMessage](#errorMessage)
|
||||||
@@ -43,6 +44,11 @@ Default is `false`, enable it will be able to save the cell automatically when b
|
|||||||
### <a name='nonEditableRows'>cellEdit.nonEditableRows - [Function]</a>
|
### <a name='nonEditableRows'>cellEdit.nonEditableRows - [Function]</a>
|
||||||
`cellEdit.nonEditableRows` accept a callback function and expect return an array which used to restrict all the columns of some rows as non-editable. So the each item in return array should be rowkey(`keyField`)
|
`cellEdit.nonEditableRows` accept a callback function and expect return an array which used to restrict all the columns of some rows as non-editable. So the each item in return array should be rowkey(`keyField`)
|
||||||
|
|
||||||
|
### <a name='autoSelectText'>cellEdit.autoSelectText - [Bool]</a>
|
||||||
|
Default is false, when enable it, `react-bootstrap-table2` will help you to select the text in the text input automatically when editing.
|
||||||
|
|
||||||
|
> NOTE: This props only work for `text` and `textarea`.
|
||||||
|
|
||||||
### <a name='timeToCloseMessage'>cellEdit.timeToCloseMessage - [Function]</a>
|
### <a name='timeToCloseMessage'>cellEdit.timeToCloseMessage - [Function]</a>
|
||||||
If a [`column.validator`](./columns.md#validator) defined and the new value is invalid, `react-bootstrap-table2` will popup a alert at the bottom of editor. `cellEdit.timeToCloseMessage` is a chance to let you decide how long the alert should be stay. Default is 3000 millisecond.
|
If a [`column.validator`](./columns.md#validator) defined and the new value is invalid, `react-bootstrap-table2` will popup a alert at the bottom of editor. `cellEdit.timeToCloseMessage` is a chance to let you decide how long the alert should be stay. Default is 3000 millisecond.
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
* [onExpand](#onExpand)
|
* [onExpand](#onExpand)
|
||||||
* [onExpandAll](#onExpandAll)
|
* [onExpandAll](#onExpandAll)
|
||||||
* [showExpandColumn](#showExpandColumn)
|
* [showExpandColumn](#showExpandColumn)
|
||||||
|
* [onlyOneExpanding](#onlyOneExpanding)
|
||||||
* [expandColumnRenderer](#expandColumnRenderer)
|
* [expandColumnRenderer](#expandColumnRenderer)
|
||||||
* [expandHeaderColumnRenderer](#expandHeaderColumnRenderer)
|
* [expandHeaderColumnRenderer](#expandHeaderColumnRenderer)
|
||||||
|
|
||||||
@@ -127,3 +128,13 @@ const expandRow = {
|
|||||||
showExpandColumn: true
|
showExpandColumn: true
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <a name='onlyOneExpanding'>expandRow.onlyOneExpanding - [Bool]</a>
|
||||||
|
Default is `false`. Enable this will only allow one row get expand at the same time.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...
|
||||||
|
onlyOneExpanding: true
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
* [onSelect](#onSelect)
|
* [onSelect](#onSelect)
|
||||||
* [onSelectAll](#onSelectAll)
|
* [onSelectAll](#onSelectAll)
|
||||||
* [hideSelectColumn](#hideSelectColumn)
|
* [hideSelectColumn](#hideSelectColumn)
|
||||||
|
* [hideSelectAll](#hideSelectAll)
|
||||||
* [selectionRenderer](#selectionRenderer)
|
* [selectionRenderer](#selectionRenderer)
|
||||||
* [selectionHeaderRenderer](#selectionHeaderRenderer)
|
* [selectionHeaderRenderer](#selectionHeaderRenderer)
|
||||||
|
|
||||||
@@ -222,3 +223,13 @@ const selectRow = {
|
|||||||
bgColor: 'red'
|
bgColor: 'red'
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <a name='hideSelectAll'>selectRow.hideSelectAll - [Bool]</a>
|
||||||
|
Default is `false`, if you don't want to render the select all checkbox on the header of selection column, give this prop as `true`!
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
hideSelectAll: true
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import Adapter from 'enzyme-adapter-react-16.3';
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
import { configure } from 'enzyme';
|
import { configure } from 'enzyme';
|
||||||
|
|
||||||
const configureEnzyme = () => {
|
const configureEnzyme = () => {
|
||||||
|
|||||||
@@ -50,8 +50,8 @@
|
|||||||
"babel-preset-stage-0": "6.24.1",
|
"babel-preset-stage-0": "6.24.1",
|
||||||
"babel-register": "6.24.1",
|
"babel-register": "6.24.1",
|
||||||
"css-loader": "0.28.1",
|
"css-loader": "0.28.1",
|
||||||
"enzyme": "3.4.0",
|
"enzyme": "3.3.0",
|
||||||
"enzyme-adapter-react-16.3": "1.0.0",
|
"enzyme-adapter-react-16": "1.1.1",
|
||||||
"enzyme-to-json": "3.3.4",
|
"enzyme-to-json": "3.3.4",
|
||||||
"eslint": "4.5.0",
|
"eslint": "4.5.0",
|
||||||
"eslint-config-airbnb": "15.1.0",
|
"eslint-config-airbnb": "15.1.0",
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import createContext from './src/context';
|
import createContext from './src/context';
|
||||||
import bindRowLevelCellEdit from './src/row-binder';
|
import editingCellFactory from './src/editing-cell';
|
||||||
import createEditingCell from './src/editing-cell-binder';
|
|
||||||
import {
|
import {
|
||||||
EDITTYPE,
|
EDITTYPE,
|
||||||
|
CLICK_TO_CELL_EDIT,
|
||||||
DBCLICK_TO_CELL_EDIT,
|
DBCLICK_TO_CELL_EDIT,
|
||||||
DELAY_FOR_DBCLICK
|
DELAY_FOR_DBCLICK
|
||||||
} from './src/const';
|
} from './src/const';
|
||||||
|
|
||||||
export default (options = {}) => ({
|
export default (options = {}) => ({
|
||||||
createContext,
|
createContext,
|
||||||
createEditingCell,
|
editingCellFactory,
|
||||||
bindRowLevelCellEdit,
|
CLICK_TO_CELL_EDIT,
|
||||||
DBCLICK_TO_CELL_EDIT,
|
DBCLICK_TO_CELL_EDIT,
|
||||||
DELAY_FOR_DBCLICK,
|
DELAY_FOR_DBCLICK,
|
||||||
options
|
options
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table2-editor",
|
"name": "react-bootstrap-table2-editor",
|
||||||
"version": "1.0.1",
|
"version": "1.1.0",
|
||||||
"description": "it's the editor addon for react-bootstrap-table2",
|
"description": "it's the editor addon for react-bootstrap-table2",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -4,14 +4,15 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from './const';
|
import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from './const';
|
||||||
|
|
||||||
const CellEditContext = React.createContext();
|
|
||||||
|
|
||||||
export default (
|
export default (
|
||||||
_,
|
_,
|
||||||
dataOperator,
|
dataOperator,
|
||||||
isRemoteCellEdit,
|
isRemoteCellEdit,
|
||||||
handleCellChange
|
handleCellChange
|
||||||
) => {
|
) => {
|
||||||
|
let EditingCell;
|
||||||
|
const CellEditContext = React.createContext();
|
||||||
|
|
||||||
class CellEditProvider extends React.Component {
|
class CellEditProvider extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
data: PropTypes.array.isRequired,
|
data: PropTypes.array.isRequired,
|
||||||
@@ -31,6 +32,7 @@ export default (
|
|||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
EditingCell = props.cellEdit.editingCellFactory(_, props.cellEdit.options.onStartEdit);
|
||||||
this.startEditing = this.startEditing.bind(this);
|
this.startEditing = this.startEditing.bind(this);
|
||||||
this.escapeEditing = this.escapeEditing.bind(this);
|
this.escapeEditing = this.escapeEditing.bind(this);
|
||||||
this.completeEditing = this.completeEditing.bind(this);
|
this.completeEditing = this.completeEditing.bind(this);
|
||||||
@@ -100,6 +102,8 @@ export default (
|
|||||||
const {
|
const {
|
||||||
cellEdit: {
|
cellEdit: {
|
||||||
options: { nonEditableRows, errorMessage, ...optionsRest },
|
options: { nonEditableRows, errorMessage, ...optionsRest },
|
||||||
|
editingCellFactory,
|
||||||
|
createContext,
|
||||||
...cellEditRest
|
...cellEditRest
|
||||||
}
|
}
|
||||||
} = this.props;
|
} = this.props;
|
||||||
@@ -108,6 +112,7 @@ export default (
|
|||||||
...optionsRest,
|
...optionsRest,
|
||||||
...cellEditRest,
|
...cellEditRest,
|
||||||
...this.state,
|
...this.state,
|
||||||
|
EditingCell,
|
||||||
nonEditableRows: _.isDefined(nonEditableRows) ? nonEditableRows() : [],
|
nonEditableRows: _.isDefined(nonEditableRows) ? nonEditableRows() : [],
|
||||||
onStart: this.startEditing,
|
onStart: this.startEditing,
|
||||||
onEscape: this.escapeEditing,
|
onEscape: this.escapeEditing,
|
||||||
@@ -116,7 +121,7 @@ export default (
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<CellEditContext.Provider
|
<CellEditContext.Provider
|
||||||
value={ { ...newCellEdit } }
|
value={ { cellEdit: newCellEdit } }
|
||||||
>
|
>
|
||||||
{ this.props.children }
|
{ this.props.children }
|
||||||
</CellEditContext.Provider>
|
</CellEditContext.Provider>
|
||||||
@@ -124,8 +129,7 @@ export default (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
Provider: CellEditProvider
|
Provider: CellEditProvider,
|
||||||
|
Consumer: CellEditContext.Consumer
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Consumer = CellEditContext.Consumer;
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
|
||||||
import React from 'react';
|
|
||||||
import { Consumer } from './context';
|
|
||||||
import createEditingCell from './editing-cell';
|
|
||||||
|
|
||||||
export default (_, onStartEdit) => {
|
|
||||||
const EditingCell = createEditingCell(_, onStartEdit);
|
|
||||||
const renderWithEditingCell = (props, cellEdit) => {
|
|
||||||
const content = _.get(props.row, props.column.dataField);
|
|
||||||
let editCellstyle = props.column.editCellStyle || {};
|
|
||||||
let editCellclasses = props.column.editCellClasses;
|
|
||||||
if (_.isFunction(props.column.editCellStyle)) {
|
|
||||||
editCellstyle = props.column.editCellStyle(
|
|
||||||
content,
|
|
||||||
props.row,
|
|
||||||
props.rowIndex,
|
|
||||||
props.columnIndex
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (_.isFunction(props.column.editCellClasses)) {
|
|
||||||
editCellclasses = props.column.editCellClasses(
|
|
||||||
content,
|
|
||||||
props.row,
|
|
||||||
props.rowIndex,
|
|
||||||
props.columnIndex)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EditingCell
|
|
||||||
{ ...props }
|
|
||||||
className={ editCellclasses }
|
|
||||||
style={ editCellstyle }
|
|
||||||
{ ...cellEdit }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return props => (
|
|
||||||
<Consumer>
|
|
||||||
{ cellEdit => renderWithEditingCell(props, cellEdit) }
|
|
||||||
</Consumer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -24,6 +24,7 @@ export default (_, onStartEdit) =>
|
|||||||
onUpdate: PropTypes.func.isRequired,
|
onUpdate: PropTypes.func.isRequired,
|
||||||
onEscape: PropTypes.func.isRequired,
|
onEscape: PropTypes.func.isRequired,
|
||||||
timeToCloseMessage: PropTypes.number,
|
timeToCloseMessage: PropTypes.number,
|
||||||
|
autoSelectText: PropTypes.bool,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
style: PropTypes.object
|
style: PropTypes.object
|
||||||
}
|
}
|
||||||
@@ -31,6 +32,7 @@ export default (_, onStartEdit) =>
|
|||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
timeToCloseMessage: TIME_TO_CLOSE_MESSAGE,
|
timeToCloseMessage: TIME_TO_CLOSE_MESSAGE,
|
||||||
className: null,
|
className: null,
|
||||||
|
autoSelectText: false,
|
||||||
style: {}
|
style: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +123,7 @@ export default (_, onStartEdit) =>
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
let editor;
|
let editor;
|
||||||
const { row, column, className, style, rowIndex, columnIndex } = this.props;
|
const { row, column, className, style, rowIndex, columnIndex, autoSelectText } = this.props;
|
||||||
const { dataField } = column;
|
const { dataField } = column;
|
||||||
|
|
||||||
const value = _.get(row, dataField);
|
const value = _.get(row, dataField);
|
||||||
@@ -174,13 +176,13 @@ export default (_, onStartEdit) =>
|
|||||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.SELECT) {
|
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.SELECT) {
|
||||||
editor = <DropdownEditor { ...editorProps } />;
|
editor = <DropdownEditor { ...editorProps } />;
|
||||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.TEXTAREA) {
|
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.TEXTAREA) {
|
||||||
editor = <TextAreaEditor { ...editorProps } />;
|
editor = <TextAreaEditor { ...editorProps } autoSelectText={ autoSelectText } />;
|
||||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.CHECKBOX) {
|
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.CHECKBOX) {
|
||||||
editor = <CheckBoxEditor { ...editorProps } />;
|
editor = <CheckBoxEditor { ...editorProps } />;
|
||||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.DATE) {
|
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.DATE) {
|
||||||
editor = <DateEditor { ...editorProps } />;
|
editor = <DateEditor { ...editorProps } />;
|
||||||
} else {
|
} else {
|
||||||
editor = <TextEditor { ...editorProps } />;
|
editor = <TextEditor { ...editorProps } autoSelectText={ autoSelectText } />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
|
||||||
import React from 'react';
|
|
||||||
import { DELAY_FOR_DBCLICK, DBCLICK_TO_CELL_EDIT, CLICK_TO_CELL_EDIT } from './const';
|
|
||||||
import { Consumer } from './context';
|
|
||||||
|
|
||||||
export default (Component, selectRowEnabled) => {
|
|
||||||
const renderWithCellEdit = (props, cellEdit) => {
|
|
||||||
const key = props.value;
|
|
||||||
const editableRow = !(
|
|
||||||
cellEdit.nonEditableRows.length > 0 &&
|
|
||||||
cellEdit.nonEditableRows.indexOf(key) > -1
|
|
||||||
);
|
|
||||||
|
|
||||||
const attrs = {};
|
|
||||||
|
|
||||||
if (selectRowEnabled && cellEdit.mode === DBCLICK_TO_CELL_EDIT) {
|
|
||||||
attrs.DELAY_FOR_DBCLICK = DELAY_FOR_DBCLICK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Component
|
|
||||||
{ ...props }
|
|
||||||
{ ...attrs }
|
|
||||||
editingRowIdx={ cellEdit.ridx }
|
|
||||||
editingColIdx={ cellEdit.cidx }
|
|
||||||
editable={ editableRow }
|
|
||||||
onStart={ cellEdit.onStart }
|
|
||||||
clickToEdit={ cellEdit.mode === CLICK_TO_CELL_EDIT }
|
|
||||||
dbclickToEdit={ cellEdit.mode === DBCLICK_TO_CELL_EDIT }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
return props => (
|
|
||||||
<Consumer>
|
|
||||||
{ cellEdit => renderWithCellEdit(props, cellEdit) }
|
|
||||||
</Consumer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -5,9 +5,10 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
class TextEditor extends Component {
|
class TextEditor extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { defaultValue, didMount } = this.props;
|
const { defaultValue, didMount, autoSelectText } = this.props;
|
||||||
this.text.value = defaultValue;
|
this.text.value = defaultValue;
|
||||||
this.text.focus();
|
this.text.focus();
|
||||||
|
if (autoSelectText) this.text.select();
|
||||||
if (didMount) didMount();
|
if (didMount) didMount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ class TextEditor extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { defaultValue, didMount, className, ...rest } = this.props;
|
const { defaultValue, didMount, className, autoSelectText, ...rest } = this.props;
|
||||||
const editorClass = cs('form-control editor edit-text', className);
|
const editorClass = cs('form-control editor edit-text', className);
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
@@ -38,11 +39,13 @@ TextEditor.propTypes = {
|
|||||||
PropTypes.string,
|
PropTypes.string,
|
||||||
PropTypes.number
|
PropTypes.number
|
||||||
]),
|
]),
|
||||||
|
autoSelectText: PropTypes.bool,
|
||||||
didMount: PropTypes.func
|
didMount: PropTypes.func
|
||||||
};
|
};
|
||||||
TextEditor.defaultProps = {
|
TextEditor.defaultProps = {
|
||||||
className: null,
|
className: null,
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
|
autoSelectText: false,
|
||||||
didMount: undefined
|
didMount: undefined
|
||||||
};
|
};
|
||||||
export default TextEditor;
|
export default TextEditor;
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ class TextAreaEditor extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { defaultValue, didMount } = this.props;
|
const { defaultValue, didMount, autoSelectText } = this.props;
|
||||||
this.text.value = defaultValue;
|
this.text.value = defaultValue;
|
||||||
this.text.focus();
|
this.text.focus();
|
||||||
|
if (autoSelectText) this.text.select();
|
||||||
if (didMount) didMount();
|
if (didMount) didMount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ class TextAreaEditor extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { defaultValue, didMount, className, ...rest } = this.props;
|
const { defaultValue, didMount, className, autoSelectText, ...rest } = this.props;
|
||||||
const editorClass = cs('form-control editor edit-textarea', className);
|
const editorClass = cs('form-control editor edit-textarea', className);
|
||||||
return (
|
return (
|
||||||
<textarea
|
<textarea
|
||||||
@@ -52,11 +53,13 @@ TextAreaEditor.propTypes = {
|
|||||||
PropTypes.number
|
PropTypes.number
|
||||||
]),
|
]),
|
||||||
onKeyDown: PropTypes.func,
|
onKeyDown: PropTypes.func,
|
||||||
|
autoSelectText: PropTypes.bool,
|
||||||
didMount: PropTypes.func
|
didMount: PropTypes.func
|
||||||
};
|
};
|
||||||
TextAreaEditor.defaultProps = {
|
TextAreaEditor.defaultProps = {
|
||||||
className: '',
|
className: '',
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
|
autoSelectText: false,
|
||||||
onKeyDown: undefined,
|
onKeyDown: undefined,
|
||||||
didMount: undefined
|
didMount: undefined
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,210 +0,0 @@
|
|||||||
import 'jsdom-global/register';
|
|
||||||
import React from 'react';
|
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import _ from 'react-bootstrap-table-next/src/utils';
|
|
||||||
import op from 'react-bootstrap-table-next/src/store/operators';
|
|
||||||
|
|
||||||
import cellEditFactory from '../index';
|
|
||||||
import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from '../src/const';
|
|
||||||
import createCellEditContext from '../src/context';
|
|
||||||
import bindCellEditing from '../src/cell-binder';
|
|
||||||
|
|
||||||
describe('Cell Binder', () => {
|
|
||||||
let wrapper;
|
|
||||||
let cellEdit;
|
|
||||||
const data = [{
|
|
||||||
id: 1,
|
|
||||||
name: 'A'
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
name: 'B'
|
|
||||||
}];
|
|
||||||
let columns;
|
|
||||||
const rowIndex = 1;
|
|
||||||
const row = { id: 1, name: 'A' };
|
|
||||||
const keyField = 'id';
|
|
||||||
const columnIndex = 1;
|
|
||||||
|
|
||||||
const { Provider } = createCellEditContext(_, op, false, jest.fn());
|
|
||||||
const BaseComponent = () => null;
|
|
||||||
const WithCellEditComponent = bindCellEditing(
|
|
||||||
props => <BaseComponent { ...props } />,
|
|
||||||
keyField,
|
|
||||||
_
|
|
||||||
);
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
columns = [{
|
|
||||||
dataField: 'id',
|
|
||||||
text: 'ID'
|
|
||||||
}, {
|
|
||||||
dataField: 'name',
|
|
||||||
text: 'Name'
|
|
||||||
}];
|
|
||||||
});
|
|
||||||
|
|
||||||
describe(`if cellEdit.mode is ${CLICK_TO_CELL_EDIT}`, () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject correct props to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('clickToEdit')).toBeTruthy();
|
|
||||||
expect(wrapper.find(BaseComponent).prop('dbclickToEdit')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe(`if cellEdit.mode is ${DBCLICK_TO_CELL_EDIT}`, () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: DBCLICK_TO_CELL_EDIT });
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject correct props to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('clickToEdit')).toBeFalsy();
|
|
||||||
expect(wrapper.find(BaseComponent).prop('dbclickToEdit')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if column prop is a key column', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[0] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
editable
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject negative editable prop to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editable')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if editable prop is true(Row Level)', () => {
|
|
||||||
describe('but column.editable prop is false', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
columns[1].editable = false;
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
editable
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject negative editable prop to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editable')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('and column.editable prop is true or not defined', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
editable
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject positive editable prop to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editable')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if editable prop is false(Row Level)', () => {
|
|
||||||
describe('even if column.editable prop is true or not defined', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
columns[1].editable = true;
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
editable={ false }
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject negative editable prop to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editable')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if column.editable prop is a function', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
columns[1].editable = jest.fn().mockReturnValue(false);
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
editable
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call column.editable function correctly', () => {
|
|
||||||
expect(columns[1].editable).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject correct editable prop to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editable')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -3,13 +3,14 @@ import React from 'react';
|
|||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import _ from 'react-bootstrap-table-next/src/utils';
|
import _ from 'react-bootstrap-table-next/src/utils';
|
||||||
import dataOperator from 'react-bootstrap-table-next/src/store/operators';
|
import dataOperator from 'react-bootstrap-table-next/src/store/operators';
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next/src/bootstrap-table';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CLICK_TO_CELL_EDIT,
|
CLICK_TO_CELL_EDIT,
|
||||||
DBCLICK_TO_CELL_EDIT,
|
DBCLICK_TO_CELL_EDIT,
|
||||||
DELAY_FOR_DBCLICK
|
DELAY_FOR_DBCLICK
|
||||||
} from '../src/const';
|
} from '../src/const';
|
||||||
import createCellEditContext, { Consumer } from '../src/context';
|
import createCellEditContext from '../src/context';
|
||||||
import cellEditFactory from '../index';
|
import cellEditFactory from '../index';
|
||||||
|
|
||||||
describe('CellEditContext', () => {
|
describe('CellEditContext', () => {
|
||||||
@@ -41,7 +42,14 @@ describe('CellEditContext', () => {
|
|||||||
|
|
||||||
const defaultSelectRow = undefined;
|
const defaultSelectRow = undefined;
|
||||||
|
|
||||||
const mockBase = jest.fn((() => null));
|
const mockBase = jest.fn((props => (
|
||||||
|
<BootstrapTable
|
||||||
|
data={ data }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
{ ...props }
|
||||||
|
/>
|
||||||
|
)));
|
||||||
|
|
||||||
const handleCellChange = jest.fn();
|
const handleCellChange = jest.fn();
|
||||||
|
|
||||||
@@ -67,11 +75,11 @@ describe('CellEditContext', () => {
|
|||||||
selectRow={ selectRow }
|
selectRow={ selectRow }
|
||||||
data={ data }
|
data={ data }
|
||||||
>
|
>
|
||||||
<Consumer>
|
<CellEditContext.Consumer>
|
||||||
{
|
{
|
||||||
cellEditProps => mockBase(cellEditProps)
|
cellEditProps => mockBase(cellEditProps)
|
||||||
}
|
}
|
||||||
</Consumer>
|
</CellEditContext.Consumer>
|
||||||
</CellEditContext.Provider>
|
</CellEditContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -86,6 +94,10 @@ describe('CellEditContext', () => {
|
|||||||
expect(CellEditContext.Provider).toBeDefined();
|
expect(CellEditContext.Provider).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have correct Consumer property after calling createCellEditContext', () => {
|
||||||
|
expect(CellEditContext.Consumer).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
it('should have correct state.ridx', () => {
|
it('should have correct state.ridx', () => {
|
||||||
expect(wrapper.state().ridx).toBeNull();
|
expect(wrapper.state().ridx).toBeNull();
|
||||||
});
|
});
|
||||||
@@ -101,11 +113,14 @@ describe('CellEditContext', () => {
|
|||||||
it('should pass correct cell editing props to children element', () => {
|
it('should pass correct cell editing props to children element', () => {
|
||||||
expect(wrapper.length).toBe(1);
|
expect(wrapper.length).toBe(1);
|
||||||
expect(JSON.stringify(mockBase.mock.calls[0])).toEqual(JSON.stringify([{
|
expect(JSON.stringify(mockBase.mock.calls[0])).toEqual(JSON.stringify([{
|
||||||
...defaultCellEdit,
|
cellEdit: {
|
||||||
DBCLICK_TO_CELL_EDIT,
|
...defaultCellEdit,
|
||||||
DELAY_FOR_DBCLICK,
|
CLICK_TO_CELL_EDIT,
|
||||||
...wrapper.state(),
|
DBCLICK_TO_CELL_EDIT,
|
||||||
nonEditableRows: []
|
DELAY_FOR_DBCLICK,
|
||||||
|
...wrapper.state(),
|
||||||
|
nonEditableRows: []
|
||||||
|
}
|
||||||
}]));
|
}]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,147 +0,0 @@
|
|||||||
import 'jsdom-global/register';
|
|
||||||
import React from 'react';
|
|
||||||
import { mount, shallow } from 'enzyme';
|
|
||||||
import _ from 'react-bootstrap-table-next/src/utils';
|
|
||||||
|
|
||||||
import cellEditFactory from '../index';
|
|
||||||
import { CLICK_TO_CELL_EDIT } from '../src/const';
|
|
||||||
import createCellEditContext from '../src/context';
|
|
||||||
import bindEditingCell from '../src/editing-cell-binder';
|
|
||||||
|
|
||||||
describe('Cell Binder', () => {
|
|
||||||
let wrapper;
|
|
||||||
let cellEdit;
|
|
||||||
const data = [{
|
|
||||||
id: 1,
|
|
||||||
name: 'A'
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
name: 'B'
|
|
||||||
}];
|
|
||||||
let columns;
|
|
||||||
const rowIndex = 1;
|
|
||||||
const row = { id: 1, name: 'A' };
|
|
||||||
const keyField = 'id';
|
|
||||||
const columnIndex = 1;
|
|
||||||
|
|
||||||
const { Provider } = createCellEditContext(_);
|
|
||||||
const WithCellEditComponent = bindEditingCell(_);
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
columns = [{
|
|
||||||
dataField: 'id',
|
|
||||||
text: 'ID'
|
|
||||||
}, {
|
|
||||||
dataField: 'name',
|
|
||||||
text: 'Name'
|
|
||||||
}];
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if column.editCellClasses is defined as string', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
columns[1].editCellClasses = 'test-class-1';
|
|
||||||
wrapper = shallow(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
wrapper = wrapper.render();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject className target component correctly', () => {
|
|
||||||
expect(wrapper.hasClass(`${columns[1].editCellClasses}`)).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if column.editCellStyle is defined as object', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
columns[1].editCellStyle = { color: 'pink' };
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style target component correctly', () => {
|
|
||||||
expect(wrapper.find('.react-bootstrap-table-editing-cell').prop('style')).toEqual(columns[1].editCellStyle);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if column.editCellClasses is defined as function', () => {
|
|
||||||
const className = 'test-class-1';
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
columns[1].editCellClasses = jest.fn().mockReturnValue(className);
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject empty className and style to target component', () => {
|
|
||||||
expect(wrapper.find(className)).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call column.editCellClasses function correctly', () => {
|
|
||||||
expect(columns[1].editCellClasses).toHaveBeenCalledTimes(1);
|
|
||||||
expect(columns[1].editCellClasses).toHaveBeenCalledWith(
|
|
||||||
_.get(row, columns[1].dataField),
|
|
||||||
row,
|
|
||||||
rowIndex,
|
|
||||||
columnIndex
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if column.editCellStyle is defined as function', () => {
|
|
||||||
const style = { color: 'blue' };
|
|
||||||
beforeEach(() => {
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
columns[1].editCellStyle = jest.fn().mockReturnValue(style);
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent
|
|
||||||
row={ row }
|
|
||||||
column={ columns[1] }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ columnIndex }
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style target component correctly', () => {
|
|
||||||
expect(wrapper.find('.react-bootstrap-table-editing-cell').prop('style')).toEqual(style);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call column.editCellStyle function correctly', () => {
|
|
||||||
expect(columns[1].editCellStyle).toHaveBeenCalledTimes(1);
|
|
||||||
expect(columns[1].editCellStyle).toHaveBeenCalledWith(
|
|
||||||
_.get(row, columns[1].dataField),
|
|
||||||
row,
|
|
||||||
rowIndex,
|
|
||||||
columnIndex
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
import 'jsdom-global/register';
|
|
||||||
import React from 'react';
|
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import _ from 'react-bootstrap-table-next/src/utils';
|
|
||||||
import op from 'react-bootstrap-table-next/src/store/operators';
|
|
||||||
|
|
||||||
import cellEditFactory from '../index';
|
|
||||||
import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT, DELAY_FOR_DBCLICK } from '../src/const';
|
|
||||||
import createCellEditContext from '../src/context';
|
|
||||||
import bindCellEditing from '../src/row-binder';
|
|
||||||
|
|
||||||
describe('Row Binder', () => {
|
|
||||||
let wrapper;
|
|
||||||
let cellEdit;
|
|
||||||
const data = [{
|
|
||||||
id: 1,
|
|
||||||
name: 'A'
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
name: 'B'
|
|
||||||
}];
|
|
||||||
const row = { id: 1, name: 'A' };
|
|
||||||
const keyField = 'id';
|
|
||||||
const value = _.get(row, keyField);
|
|
||||||
|
|
||||||
const { Provider } = createCellEditContext(_, op, false, jest.fn());
|
|
||||||
const BaseComponent = () => null;
|
|
||||||
|
|
||||||
describe('if cellEdit.nonEditableRows is undefined', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const WithCellEditComponent = bindCellEditing(
|
|
||||||
props => <BaseComponent { ...props } />,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent value={ value } />
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject correct props to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editingRowIdx')).toBeNull();
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editingColIdx')).toBeNull();
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editable')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if cellEdit.nonEditableRows is defined', () => {
|
|
||||||
const nonEditableRows = jest.fn().mockReturnValue([value]);
|
|
||||||
describe('if value prop is match in one of cellEdit.nonEditableRows', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const WithCellEditComponent = bindCellEditing(
|
|
||||||
props => <BaseComponent { ...props } />,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT, nonEditableRows });
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent value={ value } />
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject correct editable prop as false to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editable')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if value prop is not match in one of cellEdit.nonEditableRows', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const WithCellEditComponent = bindCellEditing(
|
|
||||||
props => <BaseComponent { ...props } />,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT, nonEditableRows });
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent value={ 2 } />
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject correct editable prop as false to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editable')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe(`if selectRowEnabled argument is true and cellEdit.mode is ${DBCLICK_TO_CELL_EDIT}`, () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const WithCellEditComponent = bindCellEditing(
|
|
||||||
props => <BaseComponent { ...props } />,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
cellEdit = cellEditFactory({ mode: DBCLICK_TO_CELL_EDIT });
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent value={ value } />
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject correct DELAY_FOR_DBCLICK prop to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('DELAY_FOR_DBCLICK')).toEqual(DELAY_FOR_DBCLICK);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if cellEdit.ridx and cellEdit.cidx are defined', () => {
|
|
||||||
const ridx = 0;
|
|
||||||
const cidx = 1;
|
|
||||||
beforeEach(() => {
|
|
||||||
const WithCellEditComponent = bindCellEditing(
|
|
||||||
props => <BaseComponent { ...props } />,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
|
||||||
wrapper = mount(
|
|
||||||
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
|
||||||
<WithCellEditComponent value={ value } />
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
wrapper.instance().startEditing(ridx, cidx);
|
|
||||||
wrapper.update();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject correct editable prop as false to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editingRowIdx')).toEqual(ridx);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('editingColIdx')).toEqual(cidx);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
// import cellEditFactory from 'react-bootstrap-table2-editor';
|
import cellEditFactory from 'react-bootstrap-table2-editor';
|
||||||
import { productsGenerator } from 'utils/common';
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
const products = productsGenerator(2000);
|
const products = productsGenerator(5000);
|
||||||
|
|
||||||
const columns = [{
|
const columns = [{
|
||||||
dataField: 'id',
|
dataField: 'id',
|
||||||
@@ -17,41 +17,16 @@ const columns = [{
|
|||||||
text: 'Product Price'
|
text: 'Product Price'
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// cellEdit={ cellEditFactory({
|
export default () => (
|
||||||
// mode: 'click'
|
<div>
|
||||||
// }) }
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
// const expandRow = {
|
data={ products }
|
||||||
// renderer: row => (
|
columns={ columns }
|
||||||
// <div>
|
selectRow={ { mode: 'checkbox' } }
|
||||||
// <p>{ `This Expand row is belong to rowKey ${row.id}` }</p>
|
cellEdit={ cellEditFactory({
|
||||||
// <p>You can render anything here, also you can add additional data on every row object</p>
|
mode: 'click'
|
||||||
// <p>expandRow.renderer callback will pass the origin row object to you</p>
|
}) }
|
||||||
// </div>
|
/>
|
||||||
// )
|
</div>
|
||||||
// };
|
);
|
||||||
|
|
||||||
const selectRow = {
|
|
||||||
mode: 'checkbox',
|
|
||||||
clickToSelect: true,
|
|
||||||
bgColor: 'red'
|
|
||||||
// selected: [2],
|
|
||||||
// hideSelectColumn: true
|
|
||||||
// clickToEdit: true
|
|
||||||
};
|
|
||||||
|
|
||||||
/* eslint react/prefer-stateless-function: 0 */
|
|
||||||
export default class Table extends React.PureComponent {
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<BootstrapTable
|
|
||||||
keyField="id"
|
|
||||||
data={ products }
|
|
||||||
columns={ columns }
|
|
||||||
selectRow={ selectRow }
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
78
packages/react-bootstrap-table2-example/examples/cell-edit/auto-select-text-input-table.js
vendored
Normal file
78
packages/react-bootstrap-table2-example/examples/cell-edit/auto-select-text-input-table.js
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/* eslint react/prefer-stateless-function: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { jobsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const jobs = jobsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Job ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Job Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'owner',
|
||||||
|
text: 'Job Owner'
|
||||||
|
}, {
|
||||||
|
dataField: 'type',
|
||||||
|
text: 'Job Type',
|
||||||
|
editor: {
|
||||||
|
type: Type.TEXTAREA
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Job ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Job Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'owner',
|
||||||
|
text: 'Job Owner'
|
||||||
|
}, {
|
||||||
|
dataField: 'type',
|
||||||
|
text: 'Job Type',
|
||||||
|
editor: {
|
||||||
|
type: Type.TEXTAREA
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ jobs }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={
|
||||||
|
cellEditFactory({
|
||||||
|
mode: 'click',
|
||||||
|
autoSelectText: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Auto Select Text Input Field When Editing</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ jobs }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={
|
||||||
|
cellEditFactory({
|
||||||
|
mode: 'click',
|
||||||
|
autoSelectText: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -2,9 +2,9 @@ import React from 'react';
|
|||||||
|
|
||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
import Code from 'components/common/code-block';
|
import Code from 'components/common/code-block';
|
||||||
import { productsGenerator } from 'utils/common';
|
import { productsExpandRowsGenerator } from 'utils/common';
|
||||||
|
|
||||||
const products = productsGenerator();
|
const products = productsExpandRowsGenerator();
|
||||||
|
|
||||||
const columns = [{
|
const columns = [{
|
||||||
dataField: 'id',
|
dataField: 'id',
|
||||||
@@ -17,12 +17,8 @@ const columns = [{
|
|||||||
text: 'Product Price'
|
text: 'Product Price'
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const selectRow = {
|
|
||||||
mode: 'checkbox'
|
|
||||||
};
|
|
||||||
|
|
||||||
const expandRow = {
|
const expandRow = {
|
||||||
showExpandColumn: true,
|
onlyOneExpanding: true,
|
||||||
renderer: row => (
|
renderer: row => (
|
||||||
<div>
|
<div>
|
||||||
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p>
|
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p>
|
||||||
@@ -46,13 +42,7 @@ const columns = [{
|
|||||||
text: 'Product Price'
|
text: 'Product Price'
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const selectRow = {
|
|
||||||
mode: 'checkbox',
|
|
||||||
clickToSelect: true
|
|
||||||
};
|
|
||||||
|
|
||||||
const expandRow = {
|
const expandRow = {
|
||||||
showExpandColumn: true,
|
|
||||||
renderer: row => (
|
renderer: row => (
|
||||||
<div>
|
<div>
|
||||||
<p>{ \`This Expand row is belong to rowKey $\{row.id}\` }</p>
|
<p>{ \`This Expand row is belong to rowKey $\{row.id}\` }</p>
|
||||||
@@ -66,7 +56,7 @@ const expandRow = {
|
|||||||
keyField='id'
|
keyField='id'
|
||||||
data={ products }
|
data={ products }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
selectRow={ selectRow }
|
expandRow={ expandRow }
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -76,7 +66,6 @@ export default () => (
|
|||||||
keyField="id"
|
keyField="id"
|
||||||
data={ products }
|
data={ products }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
selectRow={ selectRow }
|
|
||||||
expandRow={ expandRow }
|
expandRow={ expandRow }
|
||||||
/>
|
/>
|
||||||
<Code>{ sourceCode }</Code>
|
<Code>{ sourceCode }</Code>
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
import cellEditFactory from 'react-bootstrap-table2-editor';
|
|
||||||
import Code from 'components/common/code-block';
|
import Code from 'components/common/code-block';
|
||||||
import { productsGenerator } from 'utils/common';
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
@@ -21,12 +20,11 @@ const columns = [{
|
|||||||
const selectRow = {
|
const selectRow = {
|
||||||
mode: 'checkbox',
|
mode: 'checkbox',
|
||||||
clickToSelect: true,
|
clickToSelect: true,
|
||||||
clickToEdit: true
|
hideSelectAll: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const sourceCode = `\
|
const sourceCode = `\
|
||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
import cellEditFactory from 'react-bootstrap-table2-editor';
|
|
||||||
|
|
||||||
const columns = [{
|
const columns = [{
|
||||||
dataField: 'id',
|
dataField: 'id',
|
||||||
@@ -42,28 +40,20 @@ const columns = [{
|
|||||||
const selectRow = {
|
const selectRow = {
|
||||||
mode: 'checkbox',
|
mode: 'checkbox',
|
||||||
clickToSelect: true,
|
clickToSelect: true,
|
||||||
clickToEdit: true
|
hideSelectAll: true
|
||||||
};
|
};
|
||||||
|
|
||||||
<BootstrapTable
|
<BootstrapTable
|
||||||
keyField="id"
|
keyField='id'
|
||||||
data={ products }
|
data={ products }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
selectRow={ selectRow }
|
selectRow={ selectRow }
|
||||||
cellEdit={ cellEditFactory({ mode: 'dbclick' }) }
|
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default () => (
|
export default () => (
|
||||||
<div>
|
<div>
|
||||||
<h3>Double click to edit cell</h3>
|
<BootstrapTable keyField="id" data={ products } columns={ columns } selectRow={ selectRow } />
|
||||||
<BootstrapTable
|
|
||||||
keyField="id"
|
|
||||||
data={ products }
|
|
||||||
columns={ columns }
|
|
||||||
selectRow={ selectRow }
|
|
||||||
cellEdit={ cellEditFactory({ mode: 'dbclick' }) }
|
|
||||||
/>
|
|
||||||
<Code>{ sourceCode }</Code>
|
<Code>{ sourceCode }</Code>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* eslint no-unused-vars: 0 */
|
/* eslint no-unused-vars: 0 */
|
||||||
/* eslint no-console: 0 */
|
/* eslint no-alert: 0 */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
@@ -21,10 +21,7 @@ const columns = [{
|
|||||||
|
|
||||||
const rowEvents = {
|
const rowEvents = {
|
||||||
onClick: (e, row, rowIndex) => {
|
onClick: (e, row, rowIndex) => {
|
||||||
console.log(`clicked on row with index: ${rowIndex}`);
|
alert(`clicked on row with index: ${rowIndex}`);
|
||||||
},
|
|
||||||
onMouseEnter: (e, row, rowIndex) => {
|
|
||||||
console.log(`enter on row with index: ${rowIndex}`);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,10 +41,7 @@ const columns = [{
|
|||||||
|
|
||||||
const rowEvents = {
|
const rowEvents = {
|
||||||
onClick: (e, row, rowIndex) => {
|
onClick: (e, row, rowIndex) => {
|
||||||
console.log(\`clicked on row with index: \${rowIndex}\`);
|
alert(\`clicked on row with index: \${rowIndex}\`);
|
||||||
},
|
|
||||||
onMouseEnter: (e, row, rowIndex) => {
|
|
||||||
console.log(\`enter on row with index: \${rowIndex}\`);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,7 +50,7 @@ const rowEvents = {
|
|||||||
|
|
||||||
export default () => (
|
export default () => (
|
||||||
<div>
|
<div>
|
||||||
<h3>Try to click or hover on any rows</h3>
|
<h3>Try to click on any rows</h3>
|
||||||
<BootstrapTable keyField="id" data={ products } columns={ columns } rowEvents={ rowEvents } />
|
<BootstrapTable keyField="id" data={ products } columns={ columns } rowEvents={ rowEvents } />
|
||||||
<Code>{ sourceCode }</Code>
|
<Code>{ sourceCode }</Code>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
83
packages/react-bootstrap-table2-example/examples/search/default-search.js
vendored
Normal file
83
packages/react-bootstrap-table2-example/examples/search/default-search.js
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/* 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 } = 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 } = 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={ { defaultSearch: '2101' } }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<h3>Input something at below input field:</h3>
|
||||||
|
<SearchBar { ...props.searchProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
search={ { defaultSearch: '2101' } }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<h3>Input something at below input field:</h3>
|
||||||
|
<SearchBar { ...props.searchProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table2-example",
|
"name": "react-bootstrap-table2-example",
|
||||||
"version": "1.0.4",
|
"version": "1.0.5",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -97,9 +97,9 @@ import CellEditHooks from 'examples/cell-edit/cell-edit-hooks-table';
|
|||||||
import CellEditValidator from 'examples/cell-edit/cell-edit-validator-table';
|
import CellEditValidator from 'examples/cell-edit/cell-edit-validator-table';
|
||||||
import CellEditStyleTable from 'examples/cell-edit/cell-edit-style-table';
|
import CellEditStyleTable from 'examples/cell-edit/cell-edit-style-table';
|
||||||
import CellEditClassTable from 'examples/cell-edit/cell-edit-class-table';
|
import CellEditClassTable from 'examples/cell-edit/cell-edit-class-table';
|
||||||
|
import AutoSelectTextInput from 'examples/cell-edit/auto-select-text-input-table';
|
||||||
import EditorStyleTable from 'examples/cell-edit/editor-style-table';
|
import EditorStyleTable from 'examples/cell-edit/editor-style-table';
|
||||||
import EditorClassTable from 'examples/cell-edit/editor-class-table';
|
import EditorClassTable from 'examples/cell-edit/editor-class-table';
|
||||||
import DBClickEditWithSelection from 'examples/cell-edit/dbclick-to-edit-with-selection-table';
|
|
||||||
import DropdownEditorTable from 'examples/cell-edit/dropdown-editor-table';
|
import DropdownEditorTable from 'examples/cell-edit/dropdown-editor-table';
|
||||||
import TextareaEditorTable from 'examples/cell-edit/textarea-editor-table';
|
import TextareaEditorTable from 'examples/cell-edit/textarea-editor-table';
|
||||||
import CheckboxEditorTable from 'examples/cell-edit/checkbox-editor-table';
|
import CheckboxEditorTable from 'examples/cell-edit/checkbox-editor-table';
|
||||||
@@ -113,10 +113,10 @@ import ClickToSelectTable from 'examples/row-selection/click-to-select';
|
|||||||
import DefaultSelectTable from 'examples/row-selection/default-select';
|
import DefaultSelectTable from 'examples/row-selection/default-select';
|
||||||
import SelectionManagement from 'examples/row-selection/selection-management';
|
import SelectionManagement from 'examples/row-selection/selection-management';
|
||||||
import ClickToSelectWithCellEditTable from 'examples/row-selection/click-to-select-with-cell-edit';
|
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 SelectionNoDataTable from 'examples/row-selection/selection-no-data';
|
||||||
import SelectionStyleTable from 'examples/row-selection/selection-style';
|
import SelectionStyleTable from 'examples/row-selection/selection-style';
|
||||||
import SelectionClassTable from 'examples/row-selection/selection-class';
|
import SelectionClassTable from 'examples/row-selection/selection-class';
|
||||||
|
import HideSelectAllTable from 'examples/row-selection/hide-select-all';
|
||||||
import CustomSelectionTable from 'examples/row-selection/custom-selection';
|
import CustomSelectionTable from 'examples/row-selection/custom-selection';
|
||||||
import NonSelectableRowsTable from 'examples/row-selection/non-selectable-rows';
|
import NonSelectableRowsTable from 'examples/row-selection/non-selectable-rows';
|
||||||
import SelectionBgColorTable from 'examples/row-selection/selection-bgcolor';
|
import SelectionBgColorTable from 'examples/row-selection/selection-bgcolor';
|
||||||
@@ -128,6 +128,7 @@ import BasicRowExpand from 'examples/row-expand';
|
|||||||
import RowExpandManagement from 'examples/row-expand/expand-management';
|
import RowExpandManagement from 'examples/row-expand/expand-management';
|
||||||
import NonExpandableRows from 'examples/row-expand/non-expandable-rows';
|
import NonExpandableRows from 'examples/row-expand/non-expandable-rows';
|
||||||
import ExpandColumn from 'examples/row-expand/expand-column';
|
import ExpandColumn from 'examples/row-expand/expand-column';
|
||||||
|
import ExpandOnlyOne from 'examples/row-expand/expand-only-one';
|
||||||
import CustomExpandColumn from 'examples/row-expand/custom-expand-column';
|
import CustomExpandColumn from 'examples/row-expand/custom-expand-column';
|
||||||
import ExpandHooks from 'examples/row-expand/expand-hooks';
|
import ExpandHooks from 'examples/row-expand/expand-hooks';
|
||||||
|
|
||||||
@@ -138,6 +139,7 @@ import CustomPaginationTable from 'examples/pagination/custom-pagination';
|
|||||||
|
|
||||||
// search
|
// search
|
||||||
import SearchTable from 'examples/search';
|
import SearchTable from 'examples/search';
|
||||||
|
import DefaultSearch from 'examples/search/default-search';
|
||||||
import DefaultCustomSearch from 'examples/search/default-custom-search';
|
import DefaultCustomSearch from 'examples/search/default-custom-search';
|
||||||
import FullyCustomSearch from 'examples/search/fully-custom-search';
|
import FullyCustomSearch from 'examples/search/fully-custom-search';
|
||||||
import SearchFormattedData from 'examples/search/search-formatted';
|
import SearchFormattedData from 'examples/search/search-formatted';
|
||||||
@@ -278,11 +280,11 @@ storiesOf('Cell Editing', module)
|
|||||||
.add('Cell Level Editable', () => <CellLevelEditable />)
|
.add('Cell Level Editable', () => <CellLevelEditable />)
|
||||||
.add('Rich Hook Functions', () => <CellEditHooks />)
|
.add('Rich Hook Functions', () => <CellEditHooks />)
|
||||||
.add('Validation', () => <CellEditValidator />)
|
.add('Validation', () => <CellEditValidator />)
|
||||||
|
.add('Auto Select Text Input', () => <AutoSelectTextInput />)
|
||||||
.add('Custom Cell Style', () => <CellEditStyleTable />)
|
.add('Custom Cell Style', () => <CellEditStyleTable />)
|
||||||
.add('Custom Cell Classes', () => <CellEditClassTable />)
|
.add('Custom Cell Classes', () => <CellEditClassTable />)
|
||||||
.add('Custom Editor Classes', () => <EditorClassTable />)
|
.add('Custom Editor Classes', () => <EditorClassTable />)
|
||||||
.add('Custom Editor Style', () => <EditorStyleTable />)
|
.add('Custom Editor Style', () => <EditorStyleTable />)
|
||||||
.add('DoubleClick to Edit with Selection', () => <DBClickEditWithSelection />)
|
|
||||||
.add('Dropdown Editor', () => <DropdownEditorTable />)
|
.add('Dropdown Editor', () => <DropdownEditorTable />)
|
||||||
.add('Textarea Editor', () => <TextareaEditorTable />)
|
.add('Textarea Editor', () => <TextareaEditorTable />)
|
||||||
.add('Checkbox Editor', () => <CheckboxEditorTable />)
|
.add('Checkbox Editor', () => <CheckboxEditorTable />)
|
||||||
@@ -297,10 +299,10 @@ storiesOf('Row Selection', module)
|
|||||||
.add('Default Select', () => <DefaultSelectTable />)
|
.add('Default Select', () => <DefaultSelectTable />)
|
||||||
.add('Selection Management', () => <SelectionManagement />)
|
.add('Selection Management', () => <SelectionManagement />)
|
||||||
.add('Click to Select and Edit Cell', () => <ClickToSelectWithCellEditTable />)
|
.add('Click to Select and Edit Cell', () => <ClickToSelectWithCellEditTable />)
|
||||||
.add('Row Select and Expand', () => <SelectionWithExpansionTable />)
|
|
||||||
.add('Selection without Data', () => <SelectionNoDataTable />)
|
.add('Selection without Data', () => <SelectionNoDataTable />)
|
||||||
.add('Selection Style', () => <SelectionStyleTable />)
|
.add('Selection Style', () => <SelectionStyleTable />)
|
||||||
.add('Selection Class', () => <SelectionClassTable />)
|
.add('Selection Class', () => <SelectionClassTable />)
|
||||||
|
.add('Hide Select All', () => <HideSelectAllTable />)
|
||||||
.add('Custom Selection', () => <CustomSelectionTable />)
|
.add('Custom Selection', () => <CustomSelectionTable />)
|
||||||
.add('Selection Background Color', () => <SelectionBgColorTable />)
|
.add('Selection Background Color', () => <SelectionBgColorTable />)
|
||||||
.add('Not Selectabled Rows', () => <NonSelectableRowsTable />)
|
.add('Not Selectabled Rows', () => <NonSelectableRowsTable />)
|
||||||
@@ -313,6 +315,7 @@ storiesOf('Row Expand', module)
|
|||||||
.add('Expand Management', () => <RowExpandManagement />)
|
.add('Expand Management', () => <RowExpandManagement />)
|
||||||
.add('Non Expandabled Rows', () => <NonExpandableRows />)
|
.add('Non Expandabled Rows', () => <NonExpandableRows />)
|
||||||
.add('Expand Indicator', () => <ExpandColumn />)
|
.add('Expand Indicator', () => <ExpandColumn />)
|
||||||
|
.add('Expand Only One Row at The Same Time', () => <ExpandOnlyOne />)
|
||||||
.add('Custom Expand Indicator', () => <CustomExpandColumn />)
|
.add('Custom Expand Indicator', () => <CustomExpandColumn />)
|
||||||
.add('Expand Hooks', () => <ExpandHooks />);
|
.add('Expand Hooks', () => <ExpandHooks />);
|
||||||
|
|
||||||
@@ -325,6 +328,7 @@ storiesOf('Pagination', module)
|
|||||||
storiesOf('Table Search', module)
|
storiesOf('Table Search', module)
|
||||||
.addDecorator(bootstrapStyle())
|
.addDecorator(bootstrapStyle())
|
||||||
.add('Basic Search Table', () => <SearchTable />)
|
.add('Basic Search Table', () => <SearchTable />)
|
||||||
|
.add('Default Search Table', () => <DefaultSearch />)
|
||||||
.add('Default Custom Search', () => <DefaultCustomSearch />)
|
.add('Default Custom Search', () => <DefaultCustomSearch />)
|
||||||
.add('Fully Custom Search', () => <FullyCustomSearch />)
|
.add('Fully Custom Search', () => <FullyCustomSearch />)
|
||||||
.add('Search Fromatted Value', () => <SearchFormattedData />)
|
.add('Search Fromatted Value', () => <SearchFormattedData />)
|
||||||
|
|||||||
@@ -63,6 +63,22 @@ const { SearchBar } = Search;
|
|||||||
|
|
||||||
### Search Options
|
### Search Options
|
||||||
|
|
||||||
|
#### defaultSearch - [string]
|
||||||
|
Accept a string that will be used for default searching when first time table render.
|
||||||
|
|
||||||
|
```js
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
search={ {
|
||||||
|
defaultSearch: 'search something here'
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
// ...
|
||||||
|
</ToolkitProvider>
|
||||||
|
```
|
||||||
|
|
||||||
#### searchFormatted - [bool]
|
#### searchFormatted - [bool]
|
||||||
If you want to search on the formatted data, you are supposed to enable this props. `react-bootstrap-table2` will check if you define the `column.formatter` when doing search.
|
If you want to search on the formatted data, you are supposed to enable this props. `react-bootstrap-table2` will check if you define the `column.formatter` when doing search.
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class ToolkitProvider extends statelessDrcorator(React.Component) {
|
|||||||
search: PropTypes.oneOfType([
|
search: PropTypes.oneOfType([
|
||||||
PropTypes.bool,
|
PropTypes.bool,
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
|
defaultSearch: PropTypes.string,
|
||||||
searchFormatted: PropTypes.bool
|
searchFormatted: PropTypes.bool
|
||||||
})
|
})
|
||||||
]),
|
]),
|
||||||
@@ -42,7 +43,7 @@ class ToolkitProvider extends statelessDrcorator(React.Component) {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
searchText: ''
|
searchText: typeof props.search === 'object' ? (props.search.defaultSearch || '') : ''
|
||||||
};
|
};
|
||||||
this._ = null;
|
this._ = null;
|
||||||
this.onSearch = this.onSearch.bind(this);
|
this.onSearch = this.onSearch.bind(this);
|
||||||
@@ -85,6 +86,7 @@ class ToolkitProvider extends statelessDrcorator(React.Component) {
|
|||||||
return (
|
return (
|
||||||
<ToolkitContext.Provider value={ {
|
<ToolkitContext.Provider value={ {
|
||||||
searchProps: {
|
searchProps: {
|
||||||
|
searchText: this.state.searchText,
|
||||||
onSearch: this.onSearch
|
onSearch: this.onSearch
|
||||||
},
|
},
|
||||||
csvProps: {
|
csvProps: {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table2-toolkit",
|
"name": "react-bootstrap-table2-toolkit",
|
||||||
"version": "1.0.3",
|
"version": "1.1.0",
|
||||||
"description": "The toolkit for react-bootstrap-table2",
|
"description": "The toolkit for react-bootstrap-table2",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export const save = (
|
|||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
FileSaver.saveAs(
|
FileSaver.saveAs(
|
||||||
new Blob(['\ufeff', content], { type: 'text/plain;charset=utf-8' }),
|
new Blob([content], { type: 'text/plain;charset=utf-8' }),
|
||||||
fileName,
|
fileName,
|
||||||
noAutoBOM
|
noAutoBOM
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ const SearchBar = ({
|
|||||||
style={ style }
|
style={ style }
|
||||||
onKeyUp={ () => debounceCallback() }
|
onKeyUp={ () => debounceCallback() }
|
||||||
className={ `form-control ${className}` }
|
className={ `form-control ${className}` }
|
||||||
|
defaultValue={ searchText }
|
||||||
placeholder={ placeholder || SearchBar.defaultProps.placeholder }
|
placeholder={ placeholder || SearchBar.defaultProps.placeholder }
|
||||||
{ ...rest }
|
{ ...rest }
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table-next",
|
"name": "react-bootstrap-table-next",
|
||||||
"version": "1.1.4",
|
"version": "1.2.0",
|
||||||
"description": "Next generation of react-bootstrap-table",
|
"description": "Next generation of react-bootstrap-table",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
181
packages/react-bootstrap-table2/src/body.js
vendored
181
packages/react-bootstrap-table2/src/body.js
vendored
@@ -3,104 +3,129 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import cs from 'classnames';
|
||||||
|
|
||||||
import _ from './utils';
|
import _ from './utils';
|
||||||
import Row from './simple-row';
|
import Row from './row';
|
||||||
import RowAggregator from './row-aggregator';
|
import ExpandRow from './row-expand/expand-row';
|
||||||
import RowSection from './row-section';
|
import RowSection from './row-section';
|
||||||
import Const from './const';
|
import Const from './const';
|
||||||
import bindSelection from './row-selection/row-binder';
|
|
||||||
import bindExpansion from './row-expand/row-binder';
|
|
||||||
|
|
||||||
class Body extends React.Component {
|
const Body = (props) => {
|
||||||
constructor(props) {
|
const {
|
||||||
super(props);
|
columns,
|
||||||
if (props.cellEdit.createContext) {
|
data,
|
||||||
this.EditingCell = props.cellEdit.createEditingCell(_, props.cellEdit.options.onStartEdit);
|
keyField,
|
||||||
|
isEmpty,
|
||||||
|
noDataIndication,
|
||||||
|
visibleColumnSize,
|
||||||
|
cellEdit,
|
||||||
|
selectRow,
|
||||||
|
selectedRowKeys,
|
||||||
|
rowStyle,
|
||||||
|
rowClasses,
|
||||||
|
rowEvents,
|
||||||
|
expandRow
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const {
|
||||||
|
bgColor,
|
||||||
|
nonSelectable
|
||||||
|
} = selectRow;
|
||||||
|
|
||||||
|
let content;
|
||||||
|
|
||||||
|
if (isEmpty) {
|
||||||
|
const indication = _.isFunction(noDataIndication) ? noDataIndication() : noDataIndication;
|
||||||
|
if (!indication) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
this.RowComponent = bindSelection(RowAggregator);
|
content = <RowSection content={ indication } colSpan={ visibleColumnSize } />;
|
||||||
}
|
} else {
|
||||||
|
const nonEditableRows = cellEdit.nonEditableRows || [];
|
||||||
|
content = data.map((row, index) => {
|
||||||
|
const key = _.get(row, keyField);
|
||||||
|
const editable = !(nonEditableRows.length > 0 && nonEditableRows.indexOf(key) > -1);
|
||||||
|
|
||||||
render() {
|
const selected = selectRow.mode !== Const.ROW_SELECT_DISABLED
|
||||||
const {
|
? selectedRowKeys.includes(key)
|
||||||
columns,
|
: null;
|
||||||
data,
|
|
||||||
keyField,
|
|
||||||
isEmpty,
|
|
||||||
noDataIndication,
|
|
||||||
visibleColumnSize,
|
|
||||||
cellEdit,
|
|
||||||
selectRow,
|
|
||||||
rowStyle,
|
|
||||||
rowClasses,
|
|
||||||
rowEvents,
|
|
||||||
expandRow
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
let content;
|
const attrs = rowEvents || {};
|
||||||
|
let style = _.isFunction(rowStyle) ? rowStyle(row, index) : rowStyle;
|
||||||
|
let classes = (_.isFunction(rowClasses) ? rowClasses(row, index) : rowClasses);
|
||||||
|
if (selected) {
|
||||||
|
const selectedStyle = _.isFunction(selectRow.style)
|
||||||
|
? selectRow.style(row, index)
|
||||||
|
: selectRow.style;
|
||||||
|
|
||||||
if (isEmpty) {
|
const selectedClasses = _.isFunction(selectRow.classes)
|
||||||
const indication = _.isFunction(noDataIndication) ? noDataIndication() : noDataIndication;
|
? selectRow.classes(row, index)
|
||||||
if (!indication) {
|
: selectRow.classes;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
content = <RowSection content={ indication } colSpan={ visibleColumnSize } />;
|
|
||||||
} else {
|
|
||||||
let RowComponent = Row;
|
|
||||||
const selectRowEnabled = selectRow.mode !== Const.ROW_SELECT_DISABLED;
|
|
||||||
const expandRowEnabled = !!expandRow.renderer;
|
|
||||||
|
|
||||||
const additionalRowProps = {};
|
style = {
|
||||||
if (expandRowEnabled) {
|
...style,
|
||||||
RowComponent = bindExpansion(RowAggregator, visibleColumnSize);
|
...selectedStyle
|
||||||
}
|
|
||||||
|
|
||||||
// if (selectRowEnabled) {
|
|
||||||
// RowComponent = bindSelection(expandRowEnabled ? RowComponent : RowAggregator);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (cellEdit.createContext) {
|
|
||||||
RowComponent = cellEdit.bindRowLevelCellEdit(RowComponent, selectRowEnabled, keyField, _);
|
|
||||||
additionalRowProps.EditingCellComponent = this.EditingCell;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectRowEnabled || expandRowEnabled) {
|
|
||||||
additionalRowProps.expandRow = expandRow;
|
|
||||||
additionalRowProps.selectRow = selectRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
content = data.map((row, index) => {
|
|
||||||
const key = _.get(row, keyField);
|
|
||||||
const baseRowProps = {
|
|
||||||
key,
|
|
||||||
row,
|
|
||||||
columns,
|
|
||||||
keyField,
|
|
||||||
cellEdit,
|
|
||||||
value: key,
|
|
||||||
rowIndex: index,
|
|
||||||
attrs: rowEvents || {},
|
|
||||||
...additionalRowProps
|
|
||||||
};
|
};
|
||||||
|
classes = cs(classes, selectedClasses);
|
||||||
|
|
||||||
baseRowProps.style = _.isFunction(rowStyle) ? rowStyle(row, index) : rowStyle;
|
if (bgColor) {
|
||||||
baseRowProps.className = (_.isFunction(rowClasses) ? rowClasses(row, index) : rowClasses);
|
style = style || {};
|
||||||
|
style.backgroundColor = _.isFunction(bgColor) ? bgColor(row, index) : bgColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return <this.RowComponent { ...baseRowProps } />;
|
const selectable = !nonSelectable || !nonSelectable.includes(key);
|
||||||
});
|
const expandable = expandRow && !expandRow.nonExpandable.includes(key);
|
||||||
}
|
const expanded = expandRow && expandRow.expanded.includes(key);
|
||||||
|
|
||||||
return (
|
const result = [
|
||||||
<tbody>{ content }</tbody>
|
<Row
|
||||||
);
|
key={ key }
|
||||||
|
row={ row }
|
||||||
|
keyField={ keyField }
|
||||||
|
rowIndex={ index }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
editable={ editable }
|
||||||
|
selectable={ selectable }
|
||||||
|
expandable={ expandable }
|
||||||
|
selected={ selected }
|
||||||
|
expanded={ expanded }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
expandRow={ expandRow }
|
||||||
|
style={ style }
|
||||||
|
className={ classes }
|
||||||
|
attrs={ attrs }
|
||||||
|
/>
|
||||||
|
];
|
||||||
|
|
||||||
|
if (expanded) {
|
||||||
|
result.push((
|
||||||
|
<ExpandRow
|
||||||
|
key={ `${key}-expanding` }
|
||||||
|
colSpan={ visibleColumnSize }
|
||||||
|
>
|
||||||
|
{ expandRow.renderer(row) }
|
||||||
|
</ExpandRow>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return (
|
||||||
|
<tbody>{ content }</tbody>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
Body.propTypes = {
|
Body.propTypes = {
|
||||||
keyField: PropTypes.string.isRequired,
|
keyField: PropTypes.string.isRequired,
|
||||||
data: PropTypes.array.isRequired,
|
data: PropTypes.array.isRequired,
|
||||||
columns: PropTypes.array.isRequired,
|
columns: PropTypes.array.isRequired,
|
||||||
selectRow: PropTypes.object
|
selectRow: PropTypes.object,
|
||||||
|
selectedRowKeys: PropTypes.array
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Body;
|
export default Body;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import Caption from './caption';
|
|||||||
import Body from './body';
|
import Body from './body';
|
||||||
import PropsBaseResolver from './props-resolver';
|
import PropsBaseResolver from './props-resolver';
|
||||||
import Const from './const';
|
import Const from './const';
|
||||||
|
import { getSelectionSummary } from './store/selection';
|
||||||
|
|
||||||
class BootstrapTable extends PropsBaseResolver(Component) {
|
class BootstrapTable extends PropsBaseResolver(Component) {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -55,9 +56,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
|
|||||||
rowClasses,
|
rowClasses,
|
||||||
wrapperClasses,
|
wrapperClasses,
|
||||||
rowEvents,
|
rowEvents,
|
||||||
selectRow,
|
selected
|
||||||
expandRow,
|
|
||||||
cellEdit
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const tableWrapperClass = cs('react-bootstrap-table', wrapperClasses);
|
const tableWrapperClass = cs('react-bootstrap-table', wrapperClasses);
|
||||||
@@ -69,7 +68,20 @@ class BootstrapTable extends PropsBaseResolver(Component) {
|
|||||||
'table-condensed': condensed
|
'table-condensed': condensed
|
||||||
}, classes);
|
}, classes);
|
||||||
|
|
||||||
|
const cellSelectionInfo = this.resolveSelectRowProps({
|
||||||
|
onRowSelect: this.props.onRowSelect
|
||||||
|
});
|
||||||
|
|
||||||
|
const { allRowsSelected, allRowsNotSelected } = getSelectionSummary(data, keyField, selected);
|
||||||
|
const headerCellSelectionInfo = this.resolveSelectRowPropsForHeader({
|
||||||
|
onAllRowsSelect: this.props.onAllRowsSelect,
|
||||||
|
selected,
|
||||||
|
allRowsSelected,
|
||||||
|
allRowsNotSelected
|
||||||
|
});
|
||||||
|
|
||||||
const tableCaption = (caption && <Caption>{ caption }</Caption>);
|
const tableCaption = (caption && <Caption>{ caption }</Caption>);
|
||||||
|
const expandRow = this.resolveExpandRowProps();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ tableWrapperClass }>
|
<div className={ tableWrapperClass }>
|
||||||
@@ -83,7 +95,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
|
|||||||
onSort={ this.props.onSort }
|
onSort={ this.props.onSort }
|
||||||
onFilter={ this.props.onFilter }
|
onFilter={ this.props.onFilter }
|
||||||
onExternalFilter={ this.props.onExternalFilter }
|
onExternalFilter={ this.props.onExternalFilter }
|
||||||
selectRow={ selectRow }
|
selectRow={ headerCellSelectionInfo }
|
||||||
expandRow={ expandRow }
|
expandRow={ expandRow }
|
||||||
/>
|
/>
|
||||||
<Body
|
<Body
|
||||||
@@ -93,8 +105,9 @@ class BootstrapTable extends PropsBaseResolver(Component) {
|
|||||||
isEmpty={ this.isEmpty() }
|
isEmpty={ this.isEmpty() }
|
||||||
visibleColumnSize={ this.visibleColumnSize() }
|
visibleColumnSize={ this.visibleColumnSize() }
|
||||||
noDataIndication={ noDataIndication }
|
noDataIndication={ noDataIndication }
|
||||||
cellEdit={ cellEdit }
|
cellEdit={ this.props.cellEdit || {} }
|
||||||
selectRow={ selectRow }
|
selectRow={ cellSelectionInfo }
|
||||||
|
selectedRowKeys={ selected }
|
||||||
expandRow={ expandRow }
|
expandRow={ expandRow }
|
||||||
rowStyle={ rowStyle }
|
rowStyle={ rowStyle }
|
||||||
rowClasses={ rowClasses }
|
rowClasses={ rowClasses }
|
||||||
@@ -130,13 +143,10 @@ BootstrapTable.propTypes = {
|
|||||||
filter: PropTypes.object,
|
filter: PropTypes.object,
|
||||||
cellEdit: PropTypes.object,
|
cellEdit: PropTypes.object,
|
||||||
selectRow: PropTypes.shape({
|
selectRow: PropTypes.shape({
|
||||||
mode: PropTypes.oneOf([
|
mode: PropTypes.oneOf([Const.ROW_SELECT_SINGLE, Const.ROW_SELECT_MULTIPLE]).isRequired,
|
||||||
Const.ROW_SELECT_SINGLE,
|
|
||||||
Const.ROW_SELECT_MULTIPLE,
|
|
||||||
Const.ROW_SELECT_DISABLED
|
|
||||||
]).isRequired,
|
|
||||||
clickToSelect: PropTypes.bool,
|
clickToSelect: PropTypes.bool,
|
||||||
clickToEdit: PropTypes.bool,
|
clickToEdit: PropTypes.bool,
|
||||||
|
hideSelectAll: PropTypes.bool,
|
||||||
onSelect: PropTypes.func,
|
onSelect: PropTypes.func,
|
||||||
onSelectAll: PropTypes.func,
|
onSelectAll: PropTypes.func,
|
||||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
style: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
||||||
@@ -147,16 +157,22 @@ BootstrapTable.propTypes = {
|
|||||||
selectionRenderer: PropTypes.func,
|
selectionRenderer: PropTypes.func,
|
||||||
selectionHeaderRenderer: PropTypes.func
|
selectionHeaderRenderer: PropTypes.func
|
||||||
}),
|
}),
|
||||||
|
onRowSelect: PropTypes.func,
|
||||||
|
onAllRowsSelect: PropTypes.func,
|
||||||
expandRow: PropTypes.shape({
|
expandRow: PropTypes.shape({
|
||||||
renderer: PropTypes.func,
|
renderer: PropTypes.func.isRequired,
|
||||||
expanded: PropTypes.array,
|
expanded: PropTypes.array,
|
||||||
onExpand: PropTypes.func,
|
onExpand: PropTypes.func,
|
||||||
onExpandAll: PropTypes.func,
|
onExpandAll: PropTypes.func,
|
||||||
nonExpandable: PropTypes.array,
|
nonExpandable: PropTypes.array,
|
||||||
showExpandColumn: PropTypes.bool,
|
showExpandColumn: PropTypes.bool,
|
||||||
|
onlyOneExpanding: PropTypes.bool,
|
||||||
expandColumnRenderer: PropTypes.func,
|
expandColumnRenderer: PropTypes.func,
|
||||||
expandHeaderColumnRenderer: PropTypes.func
|
expandHeaderColumnRenderer: PropTypes.func
|
||||||
}),
|
}),
|
||||||
|
onRowExpand: PropTypes.func,
|
||||||
|
onAllRowExpand: PropTypes.func,
|
||||||
|
isAnyExpands: PropTypes.bool,
|
||||||
rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
||||||
rowEvents: PropTypes.object,
|
rowEvents: PropTypes.object,
|
||||||
rowClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
rowClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
||||||
@@ -186,21 +202,7 @@ BootstrapTable.defaultProps = {
|
|||||||
bordered: true,
|
bordered: true,
|
||||||
hover: false,
|
hover: false,
|
||||||
condensed: false,
|
condensed: false,
|
||||||
noDataIndication: null,
|
noDataIndication: null
|
||||||
selectRow: {
|
|
||||||
mode: Const.ROW_SELECT_DISABLED,
|
|
||||||
selected: [],
|
|
||||||
hideSelectColumn: true
|
|
||||||
},
|
|
||||||
expandRow: {
|
|
||||||
renderer: undefined,
|
|
||||||
expanded: [],
|
|
||||||
nonExpandable: []
|
|
||||||
},
|
|
||||||
cellEdit: {
|
|
||||||
mode: null,
|
|
||||||
nonEditableRows: []
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BootstrapTable;
|
export default BootstrapTable;
|
||||||
|
|||||||
5
packages/react-bootstrap-table2/src/cell.js
vendored
5
packages/react-bootstrap-table2/src/cell.js
vendored
@@ -73,10 +73,7 @@ class Cell extends Component {
|
|||||||
formatExtraData
|
formatExtraData
|
||||||
} = column;
|
} = column;
|
||||||
const attrs = { ...rest };
|
const attrs = { ...rest };
|
||||||
let content = this.props.children;
|
let content = column.isDummyField ? null : _.get(row, dataField);
|
||||||
if (!content) {
|
|
||||||
content = column.isDummyField ? null : _.get(row, dataField);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formatter) {
|
if (formatter) {
|
||||||
content = column.formatter(content, row, rowIndex, formatExtraData);
|
content = column.formatter(content, row, rowIndex, formatExtraData);
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import React, { Component } from 'react';
|
|||||||
import _ from '../utils';
|
import _ from '../utils';
|
||||||
import createDataContext from './data-context';
|
import createDataContext from './data-context';
|
||||||
import createSortContext from './sort-context';
|
import createSortContext from './sort-context';
|
||||||
import SelectionContext from './selection-context';
|
import createSelectionContext from './selection-context';
|
||||||
import RowExpandContext from './row-expand-context';
|
import createRowExpandContext from './row-expand-context';
|
||||||
import remoteResolver from '../props-resolver/remote-resolver';
|
import remoteResolver from '../props-resolver/remote-resolver';
|
||||||
import { BootstrapContext } from './bootstrap';
|
import { BootstrapContext } from './bootstrap';
|
||||||
import dataOperator from '../store/operators';
|
import dataOperator from '../store/operators';
|
||||||
@@ -22,11 +22,11 @@ const withContext = Base =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (props.selectRow) {
|
if (props.selectRow) {
|
||||||
this.SelectionContext = SelectionContext;
|
this.SelectionContext = createSelectionContext(dataOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.expandRow) {
|
if (props.expandRow) {
|
||||||
this.RowExpandContext = RowExpandContext;
|
this.RowExpandContext = createRowExpandContext(dataOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.cellEdit && props.cellEdit.createContext) {
|
if (props.cellEdit && props.cellEdit.createContext) {
|
||||||
@@ -57,17 +57,23 @@ const withContext = Base =>
|
|||||||
renderBase() {
|
renderBase() {
|
||||||
return (
|
return (
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps,
|
filterProps,
|
||||||
searchProps,
|
searchProps,
|
||||||
sortProps,
|
sortProps,
|
||||||
paginationProps,
|
paginationProps,
|
||||||
|
expandProps,
|
||||||
|
selectionProps
|
||||||
) => (
|
) => (
|
||||||
<Base
|
<Base
|
||||||
{ ...this.props }
|
{ ...this.props }
|
||||||
|
{ ...selectionProps }
|
||||||
{ ...sortProps }
|
{ ...sortProps }
|
||||||
|
{ ...cellEditProps }
|
||||||
{ ...filterProps }
|
{ ...filterProps }
|
||||||
{ ...searchProps }
|
{ ...searchProps }
|
||||||
{ ...paginationProps }
|
{ ...paginationProps }
|
||||||
|
{ ...expandProps }
|
||||||
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -76,25 +82,32 @@ const withContext = Base =>
|
|||||||
renderWithSelectionCtx(base, baseProps) {
|
renderWithSelectionCtx(base, baseProps) {
|
||||||
return (
|
return (
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps,
|
filterProps,
|
||||||
searchProps,
|
searchProps,
|
||||||
sortProps,
|
sortProps,
|
||||||
paginationProps
|
paginationProps,
|
||||||
|
expandProps
|
||||||
) => (
|
) => (
|
||||||
<this.SelectionContext.Provider
|
<this.SelectionContext.Provider
|
||||||
{ ...baseProps }
|
{ ...baseProps }
|
||||||
selectRow={ this.props.selectRow }
|
selectRow={ this.props.selectRow }
|
||||||
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
||||||
>
|
>
|
||||||
{
|
<this.SelectionContext.Consumer>
|
||||||
base(
|
{
|
||||||
rootProps,
|
selectionProps => base(
|
||||||
filterProps,
|
rootProps,
|
||||||
searchProps,
|
cellEditProps,
|
||||||
sortProps,
|
filterProps,
|
||||||
paginationProps
|
searchProps,
|
||||||
)
|
sortProps,
|
||||||
}
|
paginationProps,
|
||||||
|
expandProps,
|
||||||
|
selectionProps
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</this.SelectionContext.Consumer>
|
||||||
</this.SelectionContext.Provider>
|
</this.SelectionContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -102,6 +115,7 @@ const withContext = Base =>
|
|||||||
renderWithRowExpandCtx(base, baseProps) {
|
renderWithRowExpandCtx(base, baseProps) {
|
||||||
return (
|
return (
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps,
|
filterProps,
|
||||||
searchProps,
|
searchProps,
|
||||||
sortProps,
|
sortProps,
|
||||||
@@ -112,15 +126,19 @@ const withContext = Base =>
|
|||||||
expandRow={ this.props.expandRow }
|
expandRow={ this.props.expandRow }
|
||||||
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
||||||
>
|
>
|
||||||
{
|
<this.RowExpandContext.Consumer>
|
||||||
base(
|
{
|
||||||
rootProps,
|
expandProps => base(
|
||||||
filterProps,
|
rootProps,
|
||||||
searchProps,
|
cellEditProps,
|
||||||
sortProps,
|
filterProps,
|
||||||
paginationProps
|
searchProps,
|
||||||
)
|
sortProps,
|
||||||
}
|
paginationProps,
|
||||||
|
expandProps
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</this.RowExpandContext.Consumer>
|
||||||
</this.RowExpandContext.Provider>
|
</this.RowExpandContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -128,6 +146,7 @@ const withContext = Base =>
|
|||||||
renderWithPaginationCtx(base) {
|
renderWithPaginationCtx(base) {
|
||||||
return (
|
return (
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps,
|
filterProps,
|
||||||
searchProps,
|
searchProps,
|
||||||
sortProps
|
sortProps
|
||||||
@@ -142,6 +161,7 @@ const withContext = Base =>
|
|||||||
{
|
{
|
||||||
paginationProps => base(
|
paginationProps => base(
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps,
|
filterProps,
|
||||||
searchProps,
|
searchProps,
|
||||||
sortProps,
|
sortProps,
|
||||||
@@ -156,6 +176,7 @@ const withContext = Base =>
|
|||||||
renderWithSortCtx(base, baseProps) {
|
renderWithSortCtx(base, baseProps) {
|
||||||
return (
|
return (
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps,
|
filterProps,
|
||||||
searchProps
|
searchProps
|
||||||
) => (
|
) => (
|
||||||
@@ -170,6 +191,7 @@ const withContext = Base =>
|
|||||||
{
|
{
|
||||||
sortProps => base(
|
sortProps => base(
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps,
|
filterProps,
|
||||||
searchProps,
|
searchProps,
|
||||||
sortProps,
|
sortProps,
|
||||||
@@ -183,6 +205,7 @@ const withContext = Base =>
|
|||||||
renderWithSearchCtx(base, baseProps) {
|
renderWithSearchCtx(base, baseProps) {
|
||||||
return (
|
return (
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps
|
filterProps
|
||||||
) => (
|
) => (
|
||||||
<this.SearchContext.Provider
|
<this.SearchContext.Provider
|
||||||
@@ -195,6 +218,7 @@ const withContext = Base =>
|
|||||||
{
|
{
|
||||||
searchProps => base(
|
searchProps => base(
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps,
|
filterProps,
|
||||||
searchProps
|
searchProps
|
||||||
)
|
)
|
||||||
@@ -205,7 +229,10 @@ const withContext = Base =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderWithFilterCtx(base, baseProps) {
|
renderWithFilterCtx(base, baseProps) {
|
||||||
return rootProps => (
|
return (
|
||||||
|
rootProps,
|
||||||
|
cellEditProps
|
||||||
|
) => (
|
||||||
<this.FilterContext.Provider
|
<this.FilterContext.Provider
|
||||||
{ ...baseProps }
|
{ ...baseProps }
|
||||||
ref={ n => this.filterContext = n }
|
ref={ n => this.filterContext = n }
|
||||||
@@ -215,6 +242,7 @@ const withContext = Base =>
|
|||||||
{
|
{
|
||||||
filterProps => base(
|
filterProps => base(
|
||||||
rootProps,
|
rootProps,
|
||||||
|
cellEditProps,
|
||||||
filterProps
|
filterProps
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -231,7 +259,11 @@ const withContext = Base =>
|
|||||||
cellEdit={ this.props.cellEdit }
|
cellEdit={ this.props.cellEdit }
|
||||||
data={ rootProps.getData() }
|
data={ rootProps.getData() }
|
||||||
>
|
>
|
||||||
{ base(rootProps) }
|
<this.CellEditContext.Consumer>
|
||||||
|
{
|
||||||
|
cellEditProps => base(rootProps, cellEditProps)
|
||||||
|
}
|
||||||
|
</this.CellEditContext.Consumer>
|
||||||
</this.CellEditContext.Provider>
|
</this.CellEditContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,90 +1,92 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
/* eslint react/prop-types: 0 */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import dataOperator from '../store/operators';
|
|
||||||
|
|
||||||
const RowExpandContext = React.createContext();
|
export default (
|
||||||
|
dataOperator
|
||||||
|
) => {
|
||||||
|
const RowExpandContext = React.createContext();
|
||||||
|
|
||||||
class RowExpandProvider extends React.Component {
|
class RowExpandProvider extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
children: PropTypes.node.isRequired,
|
children: PropTypes.node.isRequired,
|
||||||
data: PropTypes.array.isRequired,
|
data: PropTypes.array.isRequired,
|
||||||
keyField: PropTypes.string.isRequired
|
keyField: PropTypes.string.isRequired
|
||||||
}
|
|
||||||
|
|
||||||
state = { expanded: this.props.expandRow.expanded || [] };
|
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
|
||||||
if (nextProps.expandRow) {
|
|
||||||
this.setState(() => ({
|
|
||||||
expanded: nextProps.expandRow.expanded || this.state.expanded
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleRowExpand = (rowKey, expanded, rowIndex, e) => {
|
|
||||||
const { data, keyField, expandRow: { onExpand } } = this.props;
|
|
||||||
|
|
||||||
let currExpanded = [...this.state.expanded];
|
|
||||||
|
|
||||||
if (expanded) {
|
|
||||||
currExpanded.push(rowKey);
|
|
||||||
} else {
|
|
||||||
currExpanded = currExpanded.filter(value => value !== rowKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onExpand) {
|
state = { expanded: this.props.expandRow.expanded || [] };
|
||||||
const row = dataOperator.getRowByRowId(data, keyField, rowKey);
|
|
||||||
onExpand(row, expanded, rowIndex, e);
|
|
||||||
}
|
|
||||||
this.setState(() => ({ expanded: currExpanded }));
|
|
||||||
}
|
|
||||||
|
|
||||||
handleAllRowExpand = (e, expandAll) => {
|
componentWillReceiveProps(nextProps) {
|
||||||
const {
|
if (nextProps.expandRow) {
|
||||||
data,
|
this.setState(() => ({
|
||||||
keyField,
|
expanded: nextProps.expandRow.expanded || this.state.expanded
|
||||||
expandRow: {
|
}));
|
||||||
onExpandAll,
|
|
||||||
nonExpandable
|
|
||||||
}
|
}
|
||||||
} = this.props;
|
|
||||||
const { expanded } = this.state;
|
|
||||||
|
|
||||||
let currExpanded;
|
|
||||||
|
|
||||||
if (expandAll) {
|
|
||||||
currExpanded = expanded.concat(dataOperator.expandableKeys(data, keyField, nonExpandable));
|
|
||||||
} else {
|
|
||||||
currExpanded = expanded.filter(s => typeof data.find(d => d[keyField] === s) === 'undefined');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onExpandAll) {
|
handleRowExpand = (rowKey, expanded, rowIndex, e) => {
|
||||||
onExpandAll(expandAll, dataOperator.getExpandedRows(data, keyField, currExpanded), e);
|
const { data, keyField, expandRow: { onExpand, onlyOneExpanding } } = this.props;
|
||||||
|
|
||||||
|
let currExpanded = [...this.state.expanded];
|
||||||
|
|
||||||
|
if (expanded) {
|
||||||
|
if (onlyOneExpanding) currExpanded = [rowKey];
|
||||||
|
else currExpanded.push(rowKey);
|
||||||
|
} else {
|
||||||
|
currExpanded = currExpanded.filter(value => value !== rowKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onExpand) {
|
||||||
|
const row = dataOperator.getRowByRowId(data, keyField, rowKey);
|
||||||
|
onExpand(row, expanded, rowIndex, e);
|
||||||
|
}
|
||||||
|
this.setState(() => ({ expanded: currExpanded }));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState(() => ({ expanded: currExpanded }));
|
handleAllRowExpand = (e, expandAll) => {
|
||||||
}
|
const {
|
||||||
|
data,
|
||||||
|
keyField,
|
||||||
|
expandRow: {
|
||||||
|
onExpandAll,
|
||||||
|
nonExpandable
|
||||||
|
}
|
||||||
|
} = this.props;
|
||||||
|
const { expanded } = this.state;
|
||||||
|
|
||||||
render() {
|
let currExpanded;
|
||||||
const { data, keyField } = this.props;
|
|
||||||
return (
|
|
||||||
<RowExpandContext.Provider
|
|
||||||
value={ {
|
|
||||||
...this.props.expandRow,
|
|
||||||
expanded: this.state.expanded,
|
|
||||||
isAnyExpands: dataOperator.isAnyExpands(data, keyField, this.state.expanded),
|
|
||||||
onRowExpand: this.handleRowExpand,
|
|
||||||
onAllRowExpand: this.handleAllRowExpand
|
|
||||||
} }
|
|
||||||
>
|
|
||||||
{ this.props.children }
|
|
||||||
</RowExpandContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
if (expandAll) {
|
||||||
Provider: RowExpandProvider,
|
currExpanded = expanded.concat(dataOperator.expandableKeys(data, keyField, nonExpandable));
|
||||||
Consumer: RowExpandContext.Consumer
|
} else {
|
||||||
|
currExpanded = expanded.filter(s => typeof data.find(d => d[keyField] === s) === 'undefined');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onExpandAll) {
|
||||||
|
onExpandAll(expandAll, dataOperator.getExpandedRows(data, keyField, currExpanded), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(() => ({ expanded: currExpanded }));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { data, keyField } = this.props;
|
||||||
|
return (
|
||||||
|
<RowExpandContext.Provider
|
||||||
|
value={ {
|
||||||
|
isAnyExpands: dataOperator.isAnyExpands(data, keyField, this.state.expanded),
|
||||||
|
expanded: this.state.expanded,
|
||||||
|
onRowExpand: this.handleRowExpand,
|
||||||
|
onAllRowExpand: this.handleAllRowExpand
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
{ this.props.children }
|
||||||
|
</RowExpandContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
Provider: RowExpandProvider,
|
||||||
|
Consumer: RowExpandContext.Consumer
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,124 +3,113 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Const from '../const';
|
import Const from '../const';
|
||||||
|
|
||||||
import dataOperator from '../store/operators';
|
export default (
|
||||||
import { getSelectionSummary } from '../store/selection';
|
dataOperator
|
||||||
|
) => {
|
||||||
|
const SelectionContext = React.createContext();
|
||||||
|
|
||||||
const SelectionContext = React.createContext();
|
class SelectionProvider extends React.Component {
|
||||||
class SelectionProvider extends React.Component {
|
static propTypes = {
|
||||||
static propTypes = {
|
children: PropTypes.node.isRequired,
|
||||||
children: PropTypes.node.isRequired,
|
data: PropTypes.array.isRequired,
|
||||||
data: PropTypes.array.isRequired,
|
keyField: PropTypes.string.isRequired
|
||||||
keyField: PropTypes.string.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
if (props.registerExposedAPI) {
|
|
||||||
const getSelected = () => this.getSelected();
|
|
||||||
props.registerExposedAPI(getSelected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
state = { selected: (this.props.selectRow && this.props.selectRow.selected) || [] };
|
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
|
||||||
if (nextProps.selectRow) {
|
|
||||||
this.setState(() => ({
|
|
||||||
selected: nextProps.selectRow.selected || this.state.selected
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// exposed API
|
|
||||||
getSelected() {
|
|
||||||
return this.state.selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleRowSelect = (rowKey, checked, rowIndex, e) => {
|
|
||||||
const { data, keyField, selectRow: { mode, onSelect } } = this.props;
|
|
||||||
const { ROW_SELECT_SINGLE } = Const;
|
|
||||||
|
|
||||||
let currSelected = [...this.state.selected];
|
|
||||||
|
|
||||||
if (mode === ROW_SELECT_SINGLE) { // when select mode is radio
|
|
||||||
currSelected = [rowKey];
|
|
||||||
} else if (checked) { // when select mode is checkbox
|
|
||||||
currSelected.push(rowKey);
|
|
||||||
} else {
|
|
||||||
currSelected = currSelected.filter(value => value !== rowKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onSelect) {
|
constructor(props) {
|
||||||
const row = dataOperator.getRowByRowId(data, keyField, rowKey);
|
super(props);
|
||||||
onSelect(row, checked, rowIndex, e);
|
if (props.registerExposedAPI) {
|
||||||
}
|
const getSelected = () => this.getSelected();
|
||||||
|
props.registerExposedAPI(getSelected);
|
||||||
this.setState(() => ({ selected: currSelected }));
|
|
||||||
}
|
|
||||||
|
|
||||||
handleAllRowsSelect = (e, isUnSelect) => {
|
|
||||||
const {
|
|
||||||
data,
|
|
||||||
keyField,
|
|
||||||
selectRow: {
|
|
||||||
onSelectAll,
|
|
||||||
nonSelectable
|
|
||||||
}
|
}
|
||||||
} = this.props;
|
|
||||||
const { selected } = this.state;
|
|
||||||
|
|
||||||
let currSelected;
|
|
||||||
|
|
||||||
if (!isUnSelect) {
|
|
||||||
currSelected = selected.concat(dataOperator.selectableKeys(data, keyField, nonSelectable));
|
|
||||||
} else {
|
|
||||||
currSelected = selected.filter(s => typeof data.find(d => d[keyField] === s) === 'undefined');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onSelectAll) {
|
state = { selected: (this.props.selectRow && this.props.selectRow.selected) || [] };
|
||||||
onSelectAll(!isUnSelect, dataOperator.getSelectedRows(data, keyField, currSelected), e);
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
if (nextProps.selectRow) {
|
||||||
|
this.setState(() => ({
|
||||||
|
selected: nextProps.selectRow.selected || this.state.selected
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState(() => ({ selected: currSelected }));
|
// exposed API
|
||||||
|
getSelected() {
|
||||||
|
return this.state.selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleRowSelect = (rowKey, checked, rowIndex, e) => {
|
||||||
|
const { data, keyField, selectRow: { mode, onSelect } } = this.props;
|
||||||
|
const { ROW_SELECT_SINGLE } = Const;
|
||||||
|
|
||||||
|
let currSelected = [...this.state.selected];
|
||||||
|
|
||||||
|
if (mode === ROW_SELECT_SINGLE) { // when select mode is radio
|
||||||
|
currSelected = [rowKey];
|
||||||
|
} else if (checked) { // when select mode is checkbox
|
||||||
|
currSelected.push(rowKey);
|
||||||
|
} else {
|
||||||
|
currSelected = currSelected.filter(value => value !== rowKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onSelect) {
|
||||||
|
const row = dataOperator.getRowByRowId(data, keyField, rowKey);
|
||||||
|
onSelect(row, checked, rowIndex, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(() => ({ selected: currSelected }));
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAllRowsSelect = (e, isUnSelect) => {
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
keyField,
|
||||||
|
selectRow: {
|
||||||
|
onSelectAll,
|
||||||
|
nonSelectable
|
||||||
|
}
|
||||||
|
} = this.props;
|
||||||
|
const { selected } = this.state;
|
||||||
|
|
||||||
|
let currSelected;
|
||||||
|
|
||||||
|
if (!isUnSelect) {
|
||||||
|
currSelected = selected.concat(dataOperator.selectableKeys(data, keyField, nonSelectable));
|
||||||
|
} else {
|
||||||
|
currSelected = selected.filter(s => typeof data.find(d => d[keyField] === s) === 'undefined');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onSelectAll) {
|
||||||
|
onSelectAll(
|
||||||
|
!isUnSelect,
|
||||||
|
dataOperator.getSelectedRows(
|
||||||
|
data,
|
||||||
|
keyField,
|
||||||
|
isUnSelect ? this.state.selected : currSelected
|
||||||
|
),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(() => ({ selected: currSelected }));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<SelectionContext.Provider
|
||||||
|
value={ {
|
||||||
|
selected: this.state.selected,
|
||||||
|
onRowSelect: this.handleRowSelect,
|
||||||
|
onAllRowsSelect: this.handleAllRowsSelect
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
{ this.props.children }
|
||||||
|
</SelectionContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
render() {
|
Provider: SelectionProvider,
|
||||||
const {
|
Consumer: SelectionContext.Consumer
|
||||||
allRowsSelected,
|
};
|
||||||
allRowsNotSelected
|
|
||||||
} = getSelectionSummary(
|
|
||||||
this.props.data,
|
|
||||||
this.props.keyField,
|
|
||||||
this.state.selected
|
|
||||||
);
|
|
||||||
|
|
||||||
let checkedStatus;
|
|
||||||
|
|
||||||
// checkbox status depending on selected rows counts
|
|
||||||
if (allRowsSelected) checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
|
|
||||||
else if (allRowsNotSelected) checkedStatus = Const.CHECKBOX_STATUS_UNCHECKED;
|
|
||||||
else checkedStatus = Const.CHECKBOX_STATUS_INDETERMINATE;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SelectionContext.Provider
|
|
||||||
value={ {
|
|
||||||
...this.props.selectRow,
|
|
||||||
selected: this.state.selected,
|
|
||||||
onRowSelect: this.handleRowSelect,
|
|
||||||
onAllRowsSelect: this.handleAllRowsSelect,
|
|
||||||
allRowsSelected,
|
|
||||||
allRowsNotSelected,
|
|
||||||
checkedStatus
|
|
||||||
} }
|
|
||||||
>
|
|
||||||
{ this.props.children }
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
Provider: SelectionProvider,
|
|
||||||
Consumer: SelectionContext.Consumer
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ const HeaderCell = (props) => {
|
|||||||
|
|
||||||
if (headerStyle) {
|
if (headerStyle) {
|
||||||
cellStyle = _.isFunction(headerStyle) ? headerStyle(column, index) : headerStyle;
|
cellStyle = _.isFunction(headerStyle) ? headerStyle(column, index) : headerStyle;
|
||||||
|
cellStyle = cellStyle ? { ...cellStyle } : cellStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerTitle) {
|
if (headerTitle) {
|
||||||
|
|||||||
29
packages/react-bootstrap-table2/src/header.js
vendored
29
packages/react-bootstrap-table2/src/header.js
vendored
@@ -1,14 +1,15 @@
|
|||||||
/* eslint react/require-default-props: 0 */
|
/* eslint react/require-default-props: 0 */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import Const from './const';
|
||||||
|
|
||||||
import HeaderCell from './header-cell';
|
import HeaderCell from './header-cell';
|
||||||
import SelectionHeaderCell from './row-selection/selection-header-cell';
|
import SelectionHeaderCell from './row-selection/selection-header-cell';
|
||||||
import ExpandHeaderCell from './row-expand/expand-header-cell';
|
import ExpandHeaderCell from './row-expand/expand-header-cell';
|
||||||
import bindSelection from './row-selection/selection-header-cell-binder';
|
|
||||||
import bindExpansion from './row-expand/expand-header-cell-binder';
|
|
||||||
|
|
||||||
const Header = (props) => {
|
const Header = (props) => {
|
||||||
|
const { ROW_SELECT_DISABLED } = Const;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
className,
|
className,
|
||||||
columns,
|
columns,
|
||||||
@@ -22,24 +23,20 @@ const Header = (props) => {
|
|||||||
bootstrap4
|
bootstrap4
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
let SelectionHeaderCellComp = () => null;
|
|
||||||
let ExpansionHeaderCellComp = () => null;
|
|
||||||
|
|
||||||
if (expandRow.showExpandColumn) {
|
|
||||||
ExpansionHeaderCellComp = bindExpansion(ExpandHeaderCell);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectRow) {
|
|
||||||
SelectionHeaderCellComp = bindSelection(SelectionHeaderCell);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<thead>
|
<thead>
|
||||||
<tr className={ className }>
|
<tr className={ className }>
|
||||||
<ExpansionHeaderCellComp />
|
|
||||||
{
|
{
|
||||||
!selectRow.hideSelectColumn ?
|
(expandRow && expandRow.showExpandColumn)
|
||||||
<SelectionHeaderCellComp /> : null
|
? <ExpandHeaderCell
|
||||||
|
onAllRowExpand={ expandRow.onAllRowExpand }
|
||||||
|
anyExpands={ expandRow.isAnyExpands }
|
||||||
|
renderer={ expandRow.expandHeaderColumnRenderer }
|
||||||
|
/> : null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
(selectRow.mode !== ROW_SELECT_DISABLED && !selectRow.hideSelectColumn)
|
||||||
|
? <SelectionHeaderCell { ...selectRow } /> : null
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
columns.map((column, i) => {
|
columns.map((column, i) => {
|
||||||
|
|||||||
17
packages/react-bootstrap-table2/src/props-resolver/expand-row-resolver.js
vendored
Normal file
17
packages/react-bootstrap-table2/src/props-resolver/expand-row-resolver.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export default ExtendBase =>
|
||||||
|
class ExpandRowResolver extends ExtendBase {
|
||||||
|
resolveExpandRowProps() {
|
||||||
|
const { expandRow, expanded, onRowExpand, onAllRowExpand, isAnyExpands } = this.props;
|
||||||
|
if (expandRow) {
|
||||||
|
return {
|
||||||
|
...expandRow,
|
||||||
|
expanded,
|
||||||
|
onRowExpand,
|
||||||
|
onAllRowExpand,
|
||||||
|
isAnyExpands,
|
||||||
|
nonExpandable: expandRow.nonExpandable || []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
import ColumnResolver from './column-resolver';
|
import ColumnResolver from './column-resolver';
|
||||||
|
import ExpandRowResolver from './expand-row-resolver';
|
||||||
|
import Const from '../const';
|
||||||
|
import _ from '../utils';
|
||||||
|
|
||||||
export default ExtendBase =>
|
export default ExtendBase =>
|
||||||
class TableResolver extends ColumnResolver(ExtendBase) {
|
class TableResolver extends
|
||||||
|
ExpandRowResolver(ColumnResolver(ExtendBase)) {
|
||||||
validateProps() {
|
validateProps() {
|
||||||
const { keyField } = this.props;
|
const { keyField } = this.props;
|
||||||
if (!keyField) {
|
if (!keyField) {
|
||||||
@@ -15,4 +19,63 @@ export default ExtendBase =>
|
|||||||
isEmpty() {
|
isEmpty() {
|
||||||
return this.props.data.length === 0;
|
return this.props.data.length === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* props resolver for cell selection
|
||||||
|
* @param {Object} options - addtional options like callback which are about to merge into props
|
||||||
|
*
|
||||||
|
* @returns {Object} result - props for cell selections
|
||||||
|
* @returns {String} result.mode - input type of row selection or disabled.
|
||||||
|
*/
|
||||||
|
resolveSelectRowProps(options) {
|
||||||
|
const { selectRow } = this.props;
|
||||||
|
const { ROW_SELECT_DISABLED } = Const;
|
||||||
|
|
||||||
|
if (_.isDefined(selectRow)) {
|
||||||
|
return {
|
||||||
|
...selectRow,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
mode: ROW_SELECT_DISABLED
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* props resolver for header cell selection
|
||||||
|
* @param {Object} options - addtional options like callback which are about to merge into props
|
||||||
|
*
|
||||||
|
* @returns {Object} result - props for cell selections
|
||||||
|
* @returns {String} result.mode - input type of row selection or disabled.
|
||||||
|
* @returns {String} result.checkedStatus - checkbox status depending on selected rows counts
|
||||||
|
*/
|
||||||
|
resolveSelectRowPropsForHeader(options = {}) {
|
||||||
|
const { selectRow } = this.props;
|
||||||
|
const { allRowsSelected, allRowsNotSelected, ...rest } = options;
|
||||||
|
const {
|
||||||
|
ROW_SELECT_DISABLED, CHECKBOX_STATUS_CHECKED,
|
||||||
|
CHECKBOX_STATUS_INDETERMINATE, CHECKBOX_STATUS_UNCHECKED
|
||||||
|
} = Const;
|
||||||
|
|
||||||
|
if (_.isDefined(selectRow)) {
|
||||||
|
let checkedStatus;
|
||||||
|
|
||||||
|
// checkbox status depending on selected rows counts
|
||||||
|
if (allRowsSelected) checkedStatus = CHECKBOX_STATUS_CHECKED;
|
||||||
|
else if (allRowsNotSelected) checkedStatus = CHECKBOX_STATUS_UNCHECKED;
|
||||||
|
else checkedStatus = CHECKBOX_STATUS_INDETERMINATE;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...selectRow,
|
||||||
|
...rest,
|
||||||
|
checkedStatus
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
mode: ROW_SELECT_DISABLED
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
|
||||||
/* eslint react/no-array-index-key: 0 */
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
// import eventDelegater from './row-event-delegater';
|
|
||||||
import RowContent from './row-pure-content';
|
|
||||||
// import shouldRowUpdater from './row-should-updater';
|
|
||||||
|
|
||||||
/* eslint react/prefer-stateless-function: 0 */
|
|
||||||
class RowAggregatorContent extends Component {
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
className,
|
|
||||||
style,
|
|
||||||
attrs,
|
|
||||||
shouldUpdateRowContent,
|
|
||||||
...rest
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<tr style={ style } className={ className } { ...attrs }>
|
|
||||||
{ this.props.children }
|
|
||||||
<RowContent shouldUpdate={ shouldUpdateRowContent } { ...rest } />
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowAggregatorContent.propTypes = {
|
|
||||||
row: PropTypes.object.isRequired,
|
|
||||||
rowIndex: PropTypes.number.isRequired,
|
|
||||||
columns: PropTypes.array.isRequired,
|
|
||||||
style: PropTypes.object,
|
|
||||||
className: PropTypes.string,
|
|
||||||
attrs: PropTypes.object,
|
|
||||||
shouldUpdateRowContent: PropTypes.bool
|
|
||||||
};
|
|
||||||
|
|
||||||
RowAggregatorContent.defaultProps = {
|
|
||||||
editable: true,
|
|
||||||
style: {},
|
|
||||||
className: null,
|
|
||||||
attrs: {},
|
|
||||||
shouldUpdateRowContent: true
|
|
||||||
};
|
|
||||||
|
|
||||||
export default RowAggregatorContent;
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
|
||||||
/* eslint react/no-array-index-key: 0 */
|
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import _ from './utils';
|
|
||||||
import RowContent from './row-pure-content';
|
|
||||||
// import RowAggregatorContent from './row-aggregator-content';
|
|
||||||
import shouldRowUpdater from './row-should-updater';
|
|
||||||
import ExpandCell from './row-expand/expand-cell';
|
|
||||||
import SelectionCell from './row-selection/selection-cell';
|
|
||||||
// import Cell from './cell';
|
|
||||||
import eventDelegater from './row-event-delegater';
|
|
||||||
|
|
||||||
export default class RowAggregator extends shouldRowUpdater(eventDelegater(React.Component)) {
|
|
||||||
static propTypes = {
|
|
||||||
attrs: PropTypes.object,
|
|
||||||
style: PropTypes.object
|
|
||||||
}
|
|
||||||
static defaultProps = {
|
|
||||||
attrs: {},
|
|
||||||
style: {}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.clickNum = 0;
|
|
||||||
this.shouldUpdateRowContent = false;
|
|
||||||
this.createClickEventHandler = this.createClickEventHandler.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps) {
|
|
||||||
if (
|
|
||||||
this.props.selected !== nextProps.selected ||
|
|
||||||
this.props.expanded !== nextProps.expanded ||
|
|
||||||
this.props.selectable !== nextProps.selectable ||
|
|
||||||
this.shouldUpdateByWhenEditing(nextProps) ||
|
|
||||||
this.shouldUpdatedBySelfProps(nextProps)
|
|
||||||
) {
|
|
||||||
this.shouldUpdateRowContent = this.shouldUpdatedByNormalProps(nextProps);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
this.shouldUpdateRowContent = this.shouldUpdatedByNormalProps(nextProps);
|
|
||||||
|
|
||||||
return this.shouldUpdateRowContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
createClickEventHandler(cb) {
|
|
||||||
return (e) => {
|
|
||||||
const {
|
|
||||||
row,
|
|
||||||
selected,
|
|
||||||
keyField,
|
|
||||||
selectable,
|
|
||||||
expandable,
|
|
||||||
rowIndex,
|
|
||||||
expanded,
|
|
||||||
expandRow,
|
|
||||||
selectRow,
|
|
||||||
DELAY_FOR_DBCLICK
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const clickFn = () => {
|
|
||||||
if (cb) {
|
|
||||||
cb(e, row, rowIndex);
|
|
||||||
}
|
|
||||||
const key = _.get(row, keyField);
|
|
||||||
if (expandRow && expandable) {
|
|
||||||
expandRow.onRowExpand(key, !expanded, rowIndex, e);
|
|
||||||
}
|
|
||||||
if (selectRow.clickToSelect && selectable) {
|
|
||||||
selectRow.onRowSelect(key, !selected, rowIndex, e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (DELAY_FOR_DBCLICK) {
|
|
||||||
this.clickNum += 1;
|
|
||||||
_.debounce(() => {
|
|
||||||
if (this.clickNum === 1) {
|
|
||||||
clickFn();
|
|
||||||
}
|
|
||||||
this.clickNum = 0;
|
|
||||||
}, DELAY_FOR_DBCLICK)();
|
|
||||||
} else {
|
|
||||||
clickFn();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
row,
|
|
||||||
columns,
|
|
||||||
keyField,
|
|
||||||
rowIndex,
|
|
||||||
style,
|
|
||||||
className,
|
|
||||||
attrs,
|
|
||||||
selectRow,
|
|
||||||
expandRow,
|
|
||||||
expanded,
|
|
||||||
selected,
|
|
||||||
selectable,
|
|
||||||
...rest
|
|
||||||
} = this.props;
|
|
||||||
const key = _.get(row, keyField);
|
|
||||||
const { hideSelectColumn, clickToSelect } = selectRow;
|
|
||||||
const { showExpandColumn } = expandRow;
|
|
||||||
|
|
||||||
const newAttrs = this.delegate({ ...attrs });
|
|
||||||
if (clickToSelect || !!expandRow.renderer) {
|
|
||||||
newAttrs.onClick = this.createClickEventHandler(newAttrs.onClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<tr
|
|
||||||
style={ style }
|
|
||||||
className={ className }
|
|
||||||
{ ...newAttrs }
|
|
||||||
>
|
|
||||||
<td>123</td>
|
|
||||||
<td>12121212</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
// const content0 = _.get(row, columns[1].dataField);
|
|
||||||
// const content1 = _.get(row, columns[1].dataField);
|
|
||||||
// const content2 = _.get(row, columns[2].dataField);
|
|
||||||
// return (
|
|
||||||
// <tr
|
|
||||||
// style={ style }
|
|
||||||
// className={ className }
|
|
||||||
// onClick={ e => selectRow.onRowSelect(key, !selected, rowIndex, e) }
|
|
||||||
// >
|
|
||||||
// <td>1</td>
|
|
||||||
// <td>2</td>
|
|
||||||
// <td>3</td>
|
|
||||||
// <td>4</td>
|
|
||||||
// </tr>
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const newCols = [{ fake: true }, ...columns];
|
|
||||||
|
|
||||||
// return (
|
|
||||||
// <tr
|
|
||||||
// style={ style }
|
|
||||||
// className={ className }
|
|
||||||
// { ...newAttrs }
|
|
||||||
// >
|
|
||||||
// {
|
|
||||||
// newCols.map((column, i) => {
|
|
||||||
// if (column.fake) {
|
|
||||||
// return (
|
|
||||||
// <Cell
|
|
||||||
// key={ `${key}_${i}_sel}` }
|
|
||||||
// column={ {} }
|
|
||||||
// row={ {} }
|
|
||||||
// rowIndex={ rowIndex }
|
|
||||||
// columnIndex={ i }
|
|
||||||
// >
|
|
||||||
// <input type="checkbox" />
|
|
||||||
// </Cell>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// const content = _.get(row, column.dataField);
|
|
||||||
// return (
|
|
||||||
// <Cell
|
|
||||||
// key={ `${key}_${content}}` }
|
|
||||||
// row={ row }
|
|
||||||
// rowIndex={ rowIndex }
|
|
||||||
// column={ column }
|
|
||||||
// columnIndex={ i }
|
|
||||||
// />
|
|
||||||
// );
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// </tr>
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
|
import _ from './utils';
|
||||||
|
import Const from './const';
|
||||||
|
|
||||||
const events = [
|
const events = [
|
||||||
'onClick',
|
'onClick',
|
||||||
'onDoubleClick',
|
'onDoubleClick',
|
||||||
'onMouseEnter',
|
'onMouseEnter',
|
||||||
'onMouseLeave'
|
'onMouseLeave',
|
||||||
|
'onContextMenu'
|
||||||
];
|
];
|
||||||
|
|
||||||
export default ExtendBase =>
|
export default ExtendBase =>
|
||||||
@@ -11,6 +15,7 @@ export default ExtendBase =>
|
|||||||
super(props);
|
super(props);
|
||||||
this.clickNum = 0;
|
this.clickNum = 0;
|
||||||
this.createDefaultEventHandler = this.createDefaultEventHandler.bind(this);
|
this.createDefaultEventHandler = this.createDefaultEventHandler.bind(this);
|
||||||
|
this.createClickEventHandler = this.createClickEventHandler.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
createDefaultEventHandler(cb) {
|
createDefaultEventHandler(cb) {
|
||||||
@@ -20,11 +25,65 @@ export default ExtendBase =>
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createClickEventHandler(cb) {
|
||||||
|
return (e) => {
|
||||||
|
const {
|
||||||
|
row,
|
||||||
|
selected,
|
||||||
|
keyField,
|
||||||
|
selectable,
|
||||||
|
expandable,
|
||||||
|
rowIndex,
|
||||||
|
expanded,
|
||||||
|
expandRow,
|
||||||
|
selectRow,
|
||||||
|
cellEdit: {
|
||||||
|
mode,
|
||||||
|
DBCLICK_TO_CELL_EDIT,
|
||||||
|
DELAY_FOR_DBCLICK
|
||||||
|
}
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const clickFn = () => {
|
||||||
|
if (cb) {
|
||||||
|
cb(e, row, rowIndex);
|
||||||
|
}
|
||||||
|
const key = _.get(row, keyField);
|
||||||
|
if (expandRow && expandable) {
|
||||||
|
expandRow.onRowExpand(key, !expanded, rowIndex, e);
|
||||||
|
}
|
||||||
|
if (selectRow.mode !== Const.ROW_SELECT_DISABLED && selectable) {
|
||||||
|
selectRow.onRowSelect(key, !selected, rowIndex, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mode === DBCLICK_TO_CELL_EDIT && selectRow.clickToEdit) {
|
||||||
|
this.clickNum += 1;
|
||||||
|
_.debounce(() => {
|
||||||
|
if (this.clickNum === 1) {
|
||||||
|
clickFn();
|
||||||
|
}
|
||||||
|
this.clickNum = 0;
|
||||||
|
}, DELAY_FOR_DBCLICK)();
|
||||||
|
} else {
|
||||||
|
clickFn();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
delegate(attrs = {}) {
|
delegate(attrs = {}) {
|
||||||
const newAttrs = { ...attrs };
|
const newAttrs = {};
|
||||||
|
const { expandRow, selectRow } = this.props;
|
||||||
|
if (expandRow || (selectRow && selectRow.clickToSelect)) {
|
||||||
|
newAttrs.onClick = this.createClickEventHandler(attrs.onClick);
|
||||||
|
}
|
||||||
Object.keys(attrs).forEach((attr) => {
|
Object.keys(attrs).forEach((attr) => {
|
||||||
if (events.includes(attr)) {
|
if (!newAttrs[attr]) {
|
||||||
newAttrs[attr] = this.createDefaultEventHandler(attrs[attr]);
|
if (events.includes(attr)) {
|
||||||
|
newAttrs[attr] = this.createDefaultEventHandler(attrs[attr]);
|
||||||
|
} else {
|
||||||
|
newAttrs[attr] = attrs[attr];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return newAttrs;
|
return newAttrs;
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import ExpansionContext from '../contexts/row-expand-context';
|
|
||||||
|
|
||||||
export default Component => () => (
|
|
||||||
<ExpansionContext.Consumer>
|
|
||||||
{ expandRow => <Component { ...expandRow } /> }
|
|
||||||
</ExpansionContext.Consumer>
|
|
||||||
);
|
|
||||||
@@ -3,11 +3,11 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
export default class ExpansionHeaderCell extends Component {
|
export default class SelectionHeaderCell extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isAnyExpands: PropTypes.bool.isRequired,
|
anyExpands: PropTypes.bool.isRequired,
|
||||||
onAllRowExpand: PropTypes.func.isRequired,
|
onAllRowExpand: PropTypes.func.isRequired,
|
||||||
expandHeaderColumnRenderer: PropTypes.func
|
renderer: PropTypes.func
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -16,13 +16,13 @@ export default class ExpansionHeaderCell extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleCheckBoxClick(e) {
|
handleCheckBoxClick(e) {
|
||||||
const { isAnyExpands, onAllRowExpand } = this.props;
|
const { anyExpands, onAllRowExpand } = this.props;
|
||||||
|
|
||||||
onAllRowExpand(e, !isAnyExpands);
|
onAllRowExpand(e, !anyExpands);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isAnyExpands, expandHeaderColumnRenderer } = this.props;
|
const { anyExpands, renderer } = this.props;
|
||||||
const attrs = {
|
const attrs = {
|
||||||
onClick: this.handleCheckBoxClick
|
onClick: this.handleCheckBoxClick
|
||||||
};
|
};
|
||||||
@@ -30,9 +30,9 @@ export default class ExpansionHeaderCell extends Component {
|
|||||||
return (
|
return (
|
||||||
<th data-row-selection { ...attrs }>
|
<th data-row-selection { ...attrs }>
|
||||||
{
|
{
|
||||||
expandHeaderColumnRenderer ?
|
renderer ?
|
||||||
expandHeaderColumnRenderer({ isAnyExpands }) :
|
renderer({ isAnyExpands: anyExpands }) :
|
||||||
(isAnyExpands ? '(-)' : '(+)')
|
(anyExpands ? '(-)' : '(+)')
|
||||||
}
|
}
|
||||||
</th>
|
</th>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
|
||||||
import React from 'react';
|
|
||||||
import ExpandRow from './expand-row';
|
|
||||||
import ExpansionContext from '../contexts/row-expand-context';
|
|
||||||
|
|
||||||
export default (Component, visibleColumnSize) => {
|
|
||||||
const renderWithExpansion = (props, expandRow) => {
|
|
||||||
const key = props.value;
|
|
||||||
|
|
||||||
const expanded = expandRow.expanded.includes(key);
|
|
||||||
const expandable = !expandRow.nonExpandable || !expandRow.nonExpandable.includes(key);
|
|
||||||
|
|
||||||
return [
|
|
||||||
<Component
|
|
||||||
{ ...props }
|
|
||||||
key={ key }
|
|
||||||
expanded={ expanded }
|
|
||||||
expandable={ expandable }
|
|
||||||
expandRow={ { ...expandRow } }
|
|
||||||
/>,
|
|
||||||
expanded ? <ExpandRow
|
|
||||||
key={ `${key}-expanding` }
|
|
||||||
colSpan={ visibleColumnSize }
|
|
||||||
>
|
|
||||||
{ expandRow.renderer(props.row) }
|
|
||||||
</ExpandRow> : null
|
|
||||||
];
|
|
||||||
};
|
|
||||||
return props => (
|
|
||||||
<ExpansionContext.Consumer>
|
|
||||||
{ expandRow => renderWithExpansion(props, expandRow) }
|
|
||||||
</ExpansionContext.Consumer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
|
||||||
/* eslint react/no-array-index-key: 0 */
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import _ from './utils';
|
|
||||||
import Cell from './cell';
|
|
||||||
|
|
||||||
export default class RowContent extends React.Component {
|
|
||||||
// shouldComponentUpdate(nextProps) {
|
|
||||||
// return this.shouldUpdatedByNormalProps(nextProps);
|
|
||||||
// }
|
|
||||||
shouldComponentUpdate(nextProps) {
|
|
||||||
if (typeof this.props.shouldUpdate !== 'undefined') {
|
|
||||||
if (nextProps.shouldUpdate === this.props.shouldUpdate) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
row,
|
|
||||||
keyField,
|
|
||||||
columns,
|
|
||||||
rowIndex,
|
|
||||||
editable,
|
|
||||||
editingRowIdx,
|
|
||||||
editingColIdx,
|
|
||||||
onStart,
|
|
||||||
clickToEdit,
|
|
||||||
dbclickToEdit,
|
|
||||||
EditingCellComponent
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return columns.map((column, index) => {
|
|
||||||
if (!column.hidden) {
|
|
||||||
const { dataField } = column;
|
|
||||||
const content = _.get(row, dataField);
|
|
||||||
if (rowIndex === editingRowIdx && index === editingColIdx) {
|
|
||||||
return (
|
|
||||||
<EditingCellComponent
|
|
||||||
key={ `${content}-${index}-editing` }
|
|
||||||
row={ row }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
column={ column }
|
|
||||||
columnIndex={ index }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// render cell
|
|
||||||
let cellTitle;
|
|
||||||
let cellStyle = {};
|
|
||||||
const cellAttrs = {
|
|
||||||
..._.isFunction(column.attrs)
|
|
||||||
? column.attrs(content, row, rowIndex, index)
|
|
||||||
: column.attrs,
|
|
||||||
...column.events
|
|
||||||
};
|
|
||||||
|
|
||||||
const cellClasses = _.isFunction(column.classes)
|
|
||||||
? column.classes(content, row, rowIndex, index)
|
|
||||||
: column.classes;
|
|
||||||
|
|
||||||
if (column.style) {
|
|
||||||
cellStyle = _.isFunction(column.style)
|
|
||||||
? column.style(content, row, rowIndex, index)
|
|
||||||
: column.style;
|
|
||||||
cellStyle = Object.assign({}, cellStyle) || {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (column.title) {
|
|
||||||
cellTitle = _.isFunction(column.title)
|
|
||||||
? column.title(content, row, rowIndex, index)
|
|
||||||
: content;
|
|
||||||
cellAttrs.title = cellTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (column.align) {
|
|
||||||
cellStyle.textAlign =
|
|
||||||
_.isFunction(column.align)
|
|
||||||
? column.align(content, row, rowIndex, index)
|
|
||||||
: column.align;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cellClasses) cellAttrs.className = cellClasses;
|
|
||||||
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
|
|
||||||
|
|
||||||
let editableCell = _.isDefined(column.editable) ? column.editable : true;
|
|
||||||
if (column.dataField === keyField || !editable) editableCell = false;
|
|
||||||
if (_.isFunction(column.editable)) {
|
|
||||||
editableCell = column.editable(content, row, rowIndex, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Cell
|
|
||||||
key={ `${content}-${index}` }
|
|
||||||
row={ row }
|
|
||||||
editable={ editableCell }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columnIndex={ index }
|
|
||||||
column={ column }
|
|
||||||
onStart={ onStart }
|
|
||||||
clickToEdit={ clickToEdit }
|
|
||||||
dbclickToEdit={ dbclickToEdit }
|
|
||||||
{ ...cellAttrs }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
|
||||||
import React from 'react';
|
|
||||||
import cs from 'classnames';
|
|
||||||
import _ from '../utils';
|
|
||||||
import SelectionContext from '../contexts/selection-context';
|
|
||||||
|
|
||||||
export default (Component) => {
|
|
||||||
const renderWithSelection = (props, selectRow) => {
|
|
||||||
const key = props.value;
|
|
||||||
const selected = selectRow.selected.includes(key);
|
|
||||||
const selectable = !selectRow.nonSelectable || !selectRow.nonSelectable.includes(key);
|
|
||||||
|
|
||||||
let {
|
|
||||||
style,
|
|
||||||
className
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
if (selected) {
|
|
||||||
const selectedStyle = _.isFunction(selectRow.style)
|
|
||||||
? selectRow.style(props.row, props.rowIndex)
|
|
||||||
: selectRow.style;
|
|
||||||
|
|
||||||
const selectedClasses = _.isFunction(selectRow.classes)
|
|
||||||
? selectRow.classes(props.row, props.rowIndex)
|
|
||||||
: selectRow.classes;
|
|
||||||
|
|
||||||
style = {
|
|
||||||
...style,
|
|
||||||
...selectedStyle
|
|
||||||
};
|
|
||||||
className = cs(className, selectedClasses) || undefined;
|
|
||||||
|
|
||||||
if (selectRow.bgColor) {
|
|
||||||
style = style || {};
|
|
||||||
style.backgroundColor = _.isFunction(selectRow.bgColor)
|
|
||||||
? selectRow.bgColor(props.row, props.rowIndex)
|
|
||||||
: selectRow.bgColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Component
|
|
||||||
{ ...props }
|
|
||||||
style={ style }
|
|
||||||
className={ className }
|
|
||||||
selectRow={ selectRow }
|
|
||||||
selected={ selected }
|
|
||||||
selectable={ selectable }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
function withSelectionConsumer(props) {
|
|
||||||
return (
|
|
||||||
<SelectionContext.Consumer>
|
|
||||||
{ selectRow => renderWithSelection(props, selectRow) }
|
|
||||||
</SelectionContext.Consumer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
withSelectionConsumer.displayName = 'WithSelectionConsumer';
|
|
||||||
return withSelectionConsumer;
|
|
||||||
};
|
|
||||||
@@ -19,19 +19,15 @@ export default class SelectionCell extends Component {
|
|||||||
selectionRenderer: PropTypes.func
|
selectionRenderer: PropTypes.func
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor() {
|
||||||
super(props);
|
super();
|
||||||
this.handleClick = this.handleClick.bind(this);
|
this.handleClick = this.handleClick.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps) {
|
shouldComponentUpdate(nextProps) {
|
||||||
const shouldUpdate =
|
const { selected } = this.props;
|
||||||
this.props.selected !== nextProps.selected ||
|
|
||||||
this.props.rowKey !== nextProps.rowKey ||
|
|
||||||
this.props.rowIndex !== nextProps.rowIndex ||
|
|
||||||
this.props.disabled !== nextProps.disabled;
|
|
||||||
|
|
||||||
return shouldUpdate;
|
return nextProps.selected !== selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClick(e) {
|
handleClick(e) {
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import SelectionContext from '../contexts/selection-context';
|
|
||||||
|
|
||||||
export default Component => () => (
|
|
||||||
<SelectionContext.Consumer>
|
|
||||||
{ selectRow => <Component { ...selectRow } /> }
|
|
||||||
</SelectionContext.Consumer>
|
|
||||||
);
|
|
||||||
@@ -27,6 +27,7 @@ export default class SelectionHeaderCell extends Component {
|
|||||||
mode: PropTypes.string.isRequired,
|
mode: PropTypes.string.isRequired,
|
||||||
checkedStatus: PropTypes.string,
|
checkedStatus: PropTypes.string,
|
||||||
onAllRowsSelect: PropTypes.func,
|
onAllRowsSelect: PropTypes.func,
|
||||||
|
hideSelectAll: PropTypes.bool,
|
||||||
selectionHeaderRenderer: PropTypes.func
|
selectionHeaderRenderer: PropTypes.func
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +64,10 @@ export default class SelectionHeaderCell extends Component {
|
|||||||
CHECKBOX_STATUS_CHECKED, CHECKBOX_STATUS_INDETERMINATE, ROW_SELECT_MULTIPLE
|
CHECKBOX_STATUS_CHECKED, CHECKBOX_STATUS_INDETERMINATE, ROW_SELECT_MULTIPLE
|
||||||
} = Const;
|
} = Const;
|
||||||
|
|
||||||
const { mode, checkedStatus, selectionHeaderRenderer } = this.props;
|
const { mode, checkedStatus, selectionHeaderRenderer, hideSelectAll } = this.props;
|
||||||
|
if (hideSelectAll) {
|
||||||
|
return <th data-row-selection />;
|
||||||
|
}
|
||||||
|
|
||||||
const checked = checkedStatus === CHECKBOX_STATUS_CHECKED;
|
const checked = checkedStatus === CHECKBOX_STATUS_CHECKED;
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
|
||||||
import _ from './utils';
|
|
||||||
|
|
||||||
export default ExtendBase =>
|
|
||||||
class RowShouldUpdater extends ExtendBase {
|
|
||||||
shouldUpdateByWhenEditing(nextProps) {
|
|
||||||
return (
|
|
||||||
nextProps.editingRowIdx === nextProps.rowIndex ||
|
|
||||||
(this.props.editingRowIdx === nextProps.rowIndex &&
|
|
||||||
nextProps.editingRowIdx === null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldUpdatedBySelfProps(nextProps) {
|
|
||||||
return (
|
|
||||||
this.props.className !== nextProps.className ||
|
|
||||||
!_.isEqual(this.props.style, nextProps.style) ||
|
|
||||||
!_.isEqual(this.props.attrs, nextProps.attrs)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldUpdatedByNormalProps(nextProps) {
|
|
||||||
const shouldUpdate =
|
|
||||||
this.props.rowIndex !== nextProps.rowIndex ||
|
|
||||||
this.props.editable !== nextProps.editable ||
|
|
||||||
this.props.columns.length !== nextProps.columns.length ||
|
|
||||||
!_.isEqual(this.props.row, nextProps.row);
|
|
||||||
|
|
||||||
return shouldUpdate;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
183
packages/react-bootstrap-table2/src/row.js
vendored
Normal file
183
packages/react-bootstrap-table2/src/row.js
vendored
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
/* eslint react/no-array-index-key: 0 */
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import _ from './utils';
|
||||||
|
import Cell from './cell';
|
||||||
|
import SelectionCell from './row-selection/selection-cell';
|
||||||
|
import ExpandCell from './row-expand/expand-cell';
|
||||||
|
import eventDelegater from './row-event-delegater';
|
||||||
|
import Const from './const';
|
||||||
|
|
||||||
|
class Row extends eventDelegater(Component) {
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
row,
|
||||||
|
columns,
|
||||||
|
keyField,
|
||||||
|
rowIndex,
|
||||||
|
className,
|
||||||
|
style,
|
||||||
|
attrs,
|
||||||
|
cellEdit,
|
||||||
|
selected,
|
||||||
|
selectRow,
|
||||||
|
expanded,
|
||||||
|
expandRow,
|
||||||
|
selectable,
|
||||||
|
editable: editableRow
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const {
|
||||||
|
mode,
|
||||||
|
onStart,
|
||||||
|
EditingCell,
|
||||||
|
ridx: editingRowIdx,
|
||||||
|
cidx: editingColIdx,
|
||||||
|
CLICK_TO_CELL_EDIT,
|
||||||
|
DBCLICK_TO_CELL_EDIT,
|
||||||
|
...rest
|
||||||
|
} = cellEdit;
|
||||||
|
|
||||||
|
const key = _.get(row, keyField);
|
||||||
|
const { hideSelectColumn } = selectRow;
|
||||||
|
const { showExpandColumn } = expandRow || {};
|
||||||
|
const trAttrs = this.delegate(attrs);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr style={ style } className={ className } { ...trAttrs }>
|
||||||
|
{
|
||||||
|
showExpandColumn ? (
|
||||||
|
<ExpandCell
|
||||||
|
{ ...expandRow }
|
||||||
|
rowKey={ key }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
expanded={ expanded }
|
||||||
|
/>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
(selectRow.mode !== Const.ROW_SELECT_DISABLED && !hideSelectColumn)
|
||||||
|
? (
|
||||||
|
<SelectionCell
|
||||||
|
{ ...selectRow }
|
||||||
|
rowKey={ key }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
selected={ selected }
|
||||||
|
disabled={ !selectable }
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
columns.map((column, index) => {
|
||||||
|
if (!column.hidden) {
|
||||||
|
const { dataField } = column;
|
||||||
|
const content = _.get(row, dataField);
|
||||||
|
let editable = _.isDefined(column.editable) ? column.editable : true;
|
||||||
|
if (dataField === keyField || !editableRow) editable = false;
|
||||||
|
if (_.isFunction(column.editable)) {
|
||||||
|
editable = column.editable(content, row, rowIndex, index);
|
||||||
|
}
|
||||||
|
if (rowIndex === editingRowIdx && index === editingColIdx) {
|
||||||
|
let editCellstyle = column.editCellStyle || {};
|
||||||
|
let editCellclasses = column.editCellClasses;
|
||||||
|
if (_.isFunction(column.editCellStyle)) {
|
||||||
|
editCellstyle = column.editCellStyle(content, row, rowIndex, index);
|
||||||
|
}
|
||||||
|
if (_.isFunction(column.editCellClasses)) {
|
||||||
|
editCellclasses = column.editCellClasses(content, row, rowIndex, index);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<EditingCell
|
||||||
|
key={ `${content}-${index}` }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
column={ column }
|
||||||
|
columnIndex={ index }
|
||||||
|
className={ editCellclasses }
|
||||||
|
style={ editCellstyle }
|
||||||
|
{ ...rest }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// render cell
|
||||||
|
let cellTitle;
|
||||||
|
let cellStyle = {};
|
||||||
|
const cellAttrs = {
|
||||||
|
..._.isFunction(column.attrs)
|
||||||
|
? column.attrs(content, row, rowIndex, index)
|
||||||
|
: column.attrs,
|
||||||
|
...column.events
|
||||||
|
};
|
||||||
|
|
||||||
|
const cellClasses = _.isFunction(column.classes)
|
||||||
|
? column.classes(content, row, rowIndex, index)
|
||||||
|
: column.classes;
|
||||||
|
|
||||||
|
if (column.style) {
|
||||||
|
cellStyle = _.isFunction(column.style)
|
||||||
|
? column.style(content, row, rowIndex, index)
|
||||||
|
: column.style;
|
||||||
|
cellStyle = Object.assign({}, cellStyle) || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (column.title) {
|
||||||
|
cellTitle = _.isFunction(column.title)
|
||||||
|
? column.title(content, row, rowIndex, index)
|
||||||
|
: content;
|
||||||
|
cellAttrs.title = cellTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (column.align) {
|
||||||
|
cellStyle.textAlign =
|
||||||
|
_.isFunction(column.align)
|
||||||
|
? column.align(content, row, rowIndex, index)
|
||||||
|
: column.align;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cellClasses) cellAttrs.className = cellClasses;
|
||||||
|
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Cell
|
||||||
|
key={ `${content}-${index}` }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columnIndex={ index }
|
||||||
|
column={ column }
|
||||||
|
onStart={ onStart }
|
||||||
|
editable={ editable }
|
||||||
|
clickToEdit={ mode === CLICK_TO_CELL_EDIT }
|
||||||
|
dbclickToEdit={ mode === DBCLICK_TO_CELL_EDIT }
|
||||||
|
{ ...cellAttrs }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row.propTypes = {
|
||||||
|
row: PropTypes.object.isRequired,
|
||||||
|
rowIndex: PropTypes.number.isRequired,
|
||||||
|
columns: PropTypes.array.isRequired,
|
||||||
|
style: PropTypes.object,
|
||||||
|
className: PropTypes.string,
|
||||||
|
attrs: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
Row.defaultProps = {
|
||||||
|
editable: true,
|
||||||
|
style: {},
|
||||||
|
className: null,
|
||||||
|
attrs: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Row;
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
|
||||||
/* eslint react/no-array-index-key: 0 */
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import eventDelegater from './row-event-delegater';
|
|
||||||
import RowContent from './row-pure-content';
|
|
||||||
import shouldRowUpdater from './row-should-updater';
|
|
||||||
|
|
||||||
class Row extends shouldRowUpdater(eventDelegater(Component)) {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.shouldUpdateRowContent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps) {
|
|
||||||
this.shouldUpdateRowContent = this.shouldUpdatedByNormalProps(nextProps);
|
|
||||||
if (this.shouldUpdateRowContent) return true;
|
|
||||||
|
|
||||||
return this.shouldUpdatedBySelfProps(nextProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
className,
|
|
||||||
style,
|
|
||||||
attrs,
|
|
||||||
...rest
|
|
||||||
} = this.props;
|
|
||||||
const trAttrs = this.delegate(attrs);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<tr style={ style } className={ className } { ...trAttrs }>
|
|
||||||
<RowContent shouldUpdate={ this.shouldUpdateRowContent } { ...rest } />
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row.propTypes = {
|
|
||||||
row: PropTypes.object.isRequired,
|
|
||||||
rowIndex: PropTypes.number.isRequired,
|
|
||||||
columns: PropTypes.array.isRequired,
|
|
||||||
style: PropTypes.object,
|
|
||||||
className: PropTypes.string,
|
|
||||||
attrs: PropTypes.object
|
|
||||||
};
|
|
||||||
|
|
||||||
Row.defaultProps = {
|
|
||||||
editable: true,
|
|
||||||
style: {},
|
|
||||||
className: null,
|
|
||||||
attrs: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Row;
|
|
||||||
@@ -1,15 +1,11 @@
|
|||||||
import 'jsdom-global/register';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
|
|
||||||
import Body from '../src/body';
|
import Body from '../src/body';
|
||||||
import Row from '../src/row';
|
import Row from '../src/row';
|
||||||
import RowAggregator from '../src/row-aggregator';
|
|
||||||
import Const from '../src/const';
|
import Const from '../src/const';
|
||||||
import RowSection from '../src/row-section';
|
import RowSection from '../src/row-section';
|
||||||
import SelectionContext from '../src/contexts/selection-context';
|
|
||||||
import ExpansionContext from '../src/contexts/row-expand-context';
|
|
||||||
import mockBodyResolvedProps from './test-helpers/mock/body-resolved-props';
|
import mockBodyResolvedProps from './test-helpers/mock/body-resolved-props';
|
||||||
|
|
||||||
describe('Body', () => {
|
describe('Body', () => {
|
||||||
@@ -173,6 +169,92 @@ describe('Body', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when selectRow.style is defined', () => {
|
||||||
|
const selectedRowKey = data[0][keyField];
|
||||||
|
const selectedRowKeys = [selectedRowKey];
|
||||||
|
const selectedStyle = { backgroundColor: 'green', fontWeight: 'bold' };
|
||||||
|
const selectRow = { mode: 'radio', style: selectedStyle };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
keyField="id"
|
||||||
|
columns={ columns }
|
||||||
|
data={ data }
|
||||||
|
rowStyle={ rowStyle }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should rendering selected Row component with mixing selectRow.style correctly', () => {
|
||||||
|
const selectedRow = wrapper.find(Row).get(0);
|
||||||
|
expect(JSON.stringify(selectedRow.props.style)).toBe(JSON.stringify({
|
||||||
|
...rowStyle,
|
||||||
|
...selectedStyle
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and selectRow.bgColor is also defined', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow.bgColor = 'gray';
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
keyField="id"
|
||||||
|
columns={ columns }
|
||||||
|
data={ data }
|
||||||
|
rowStyle={ rowStyle }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should rendering selected Row component with mixing selectRow.style correctly', () => {
|
||||||
|
const selectedRow = wrapper.find(Row).get(0);
|
||||||
|
expect(JSON.stringify(selectedRow.props.style)).toBe(JSON.stringify({
|
||||||
|
...rowStyle,
|
||||||
|
...selectedStyle,
|
||||||
|
backgroundColor: selectRow.bgColor
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render selected Row component with correct style.backgroundColor', () => {
|
||||||
|
const selectedRow = wrapper.find(Row).get(0);
|
||||||
|
expect(selectedRow.props.style.backgroundColor).toEqual(selectRow.bgColor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when selectRow.bgColor is defined', () => {
|
||||||
|
const selectedRowKey = data[0][keyField];
|
||||||
|
const selectedRowKeys = [selectedRowKey];
|
||||||
|
const selectRow = { mode: 'radio', bgColor: 'gray' };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow.bgColor = 'gray';
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
keyField="id"
|
||||||
|
columns={ columns }
|
||||||
|
data={ data }
|
||||||
|
rowStyle={ rowStyle }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should rendering selected Row component with correct style', () => {
|
||||||
|
const selectedRow = wrapper.find(Row).get(0);
|
||||||
|
expect(JSON.stringify(selectedRow.props.style)).toBe(JSON.stringify({
|
||||||
|
...rowStyle,
|
||||||
|
backgroundColor: selectRow.bgColor
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when rowClasses prop is defined', () => {
|
describe('when rowClasses prop is defined', () => {
|
||||||
@@ -228,6 +310,31 @@ describe('Body', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when selectRow.classes is defined', () => {
|
||||||
|
const selectedRowKey = data[0][keyField];
|
||||||
|
const selectedRowKeys = [selectedRowKey];
|
||||||
|
const selectedClasses = 'selected-classes';
|
||||||
|
const selectRow = { mode: 'radio', classes: selectedClasses };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
keyField="id"
|
||||||
|
columns={ columns }
|
||||||
|
data={ data }
|
||||||
|
rowClasses={ rowClasses }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should rendering selected Row component with mixing selectRow.classes correctly', () => {
|
||||||
|
const selectedRow = wrapper.find(Row).get(0);
|
||||||
|
expect(selectedRow.props.className).toBe(`${rowClasses} ${selectedClasses}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when rowEvents prop is defined', () => {
|
describe('when rowEvents prop is defined', () => {
|
||||||
@@ -254,15 +361,11 @@ describe('Body', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when cellEdit.createContext props is defined', () => {
|
describe('when cellEdit.nonEditableRows props is defined', () => {
|
||||||
const CellComponent = () => null;
|
const nonEditableRows = [data[1].id];
|
||||||
const EditingCellComponent = () => null;
|
|
||||||
const RowComponent = props => <Row { ...props } />;
|
|
||||||
const cellEdit = {
|
const cellEdit = {
|
||||||
createContext: jest.fn(),
|
mode: Const.CLICK_TO_CELL_EDIT,
|
||||||
bindCellLevelCellEdit: jest.fn().mockReturnValue(CellComponent),
|
nonEditableRows
|
||||||
createEditingCell: jest.fn().mockReturnValue(EditingCellComponent),
|
|
||||||
bindRowLevelCellEdit: jest.fn().mockReturnValue(RowComponent)
|
|
||||||
};
|
};
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
@@ -276,19 +379,24 @@ describe('Body', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render Row Component correctly', () => {
|
it('should render Row component with correct editable prop', () => {
|
||||||
expect(wrapper.length).toBe(1);
|
expect(wrapper.length).toBe(1);
|
||||||
expect(cellEdit.bindCellLevelCellEdit).toHaveBeenCalledTimes(1);
|
const rows = wrapper.find(Row);
|
||||||
expect(cellEdit.createEditingCell).toHaveBeenCalledTimes(1);
|
for (let i = 0; i < rows.length; i += 1) {
|
||||||
expect(cellEdit.bindRowLevelCellEdit).toHaveBeenCalledTimes(1);
|
if (nonEditableRows.indexOf(rows.get(i).props.row[keyField]) > -1) {
|
||||||
expect(wrapper.find(RowComponent)).toHaveLength(2);
|
expect(rows.get(i).props.editable).toBeFalsy();
|
||||||
const aRowElement = wrapper.find(RowComponent).get(0);
|
} else {
|
||||||
expect(aRowElement.props.CellComponent).toBeDefined();
|
expect(rows.get(i).props.editable).toBeTruthy();
|
||||||
expect(aRowElement.props.EditingCellComponent).toBeDefined();
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when selectRow.mode is ROW_SELECT_DISABLED or expandRow.renderer is undefined', () => {
|
describe('when selectRow.mode is checkbox or radio (row was selectable)', () => {
|
||||||
|
const selectRow = { mode: 'checkbox' };
|
||||||
|
const selectedRowKey = data[0][keyField];
|
||||||
|
const selectedRowKeys = [selectedRowKey];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
<Body
|
<Body
|
||||||
@@ -296,64 +404,234 @@ describe('Body', () => {
|
|||||||
data={ data }
|
data={ data }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
keyField={ keyField }
|
keyField={ keyField }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
selectRow={ selectRow }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shouldn\'t render RowAggregator component', () => {
|
it('should render Row component with correct selected prop', () => {
|
||||||
expect(wrapper.find(RowAggregator)).toHaveLength(0);
|
const rows = wrapper.find(Row);
|
||||||
|
for (let i = 0; i < rows.length; i += 1) {
|
||||||
|
const row = rows.get(i);
|
||||||
|
expect(row.props.selected).toBe(selectedRowKeys.indexOf(row.props.row[keyField]) > -1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('when selectRow.mode is defined correctly', () => {
|
describe('if selectRow.style is defined as an object', () => {
|
||||||
const selectRow = { mode: 'checkbox' };
|
const style = { backgroundColor: 'red' };
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = mount(
|
selectRow.style = style;
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
wrapper = shallow(
|
||||||
<Body
|
<Body
|
||||||
{ ...mockBodyResolvedProps }
|
{ ...mockBodyResolvedProps }
|
||||||
data={ data }
|
data={ data }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
keyField={ keyField }
|
keyField={ keyField }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
selectRow={ selectRow }
|
selectRow={ selectRow }
|
||||||
/>
|
/>
|
||||||
</SelectionContext.Provider>
|
);
|
||||||
);
|
});
|
||||||
|
|
||||||
|
it('should render Row component with correct style prop', () => {
|
||||||
|
expect(JSON.stringify(wrapper.find(Row).get(0).props.style)).toBe(JSON.stringify(style));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render RowAggregator component correctly', () => {
|
describe('if selectRow.style is defined as a function', () => {
|
||||||
const rowAggregator = wrapper.find(RowAggregator);
|
const style = { backgroundColor: 'red' };
|
||||||
|
const styleCallBack = sinon.stub().returns(style);
|
||||||
|
|
||||||
expect(rowAggregator.get(0).props.selectRow.mode)
|
beforeEach(() => {
|
||||||
.not.toEqual(Const.ROW_SELECT_DISABLED);
|
selectRow.style = styleCallBack;
|
||||||
expect(rowAggregator.get(0).props.selected).toBeDefined();
|
wrapper = shallow(
|
||||||
expect(rowAggregator.get(0).props.selectable).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when expandRow.renderer is defined correctly', () => {
|
|
||||||
const expandRow = { renderer: jest.fn() };
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<ExpansionContext.Provider data={ data } keyField={ keyField } expandRow={ expandRow }>
|
|
||||||
<Body
|
<Body
|
||||||
{ ...mockBodyResolvedProps }
|
{ ...mockBodyResolvedProps }
|
||||||
data={ data }
|
data={ data }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
keyField={ keyField }
|
keyField={ keyField }
|
||||||
expandRow={ expandRow }
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
selectRow={ selectRow }
|
||||||
/>
|
/>
|
||||||
</ExpansionContext.Provider>
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling style callback correctly', () => {
|
||||||
|
expect(styleCallBack.callCount).toBe(1);
|
||||||
|
expect(styleCallBack.calledWith(data[0]), 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render Row component with correct style prop', () => {
|
||||||
|
expect(JSON.stringify(wrapper.find(Row).get(0).props.style)).toBe(JSON.stringify(style));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow.classes is defined as a string', () => {
|
||||||
|
const className = 'custom-class';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow.classes = className;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
data={ data }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render Row component with correct className prop', () => {
|
||||||
|
expect(wrapper.find(Row).get(0).props.className).toEqual(className);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow.classes is defined as a function', () => {
|
||||||
|
const className = 'custom-class';
|
||||||
|
const classesCallBack = sinon.stub().returns(className);
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow.classes = classesCallBack;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
data={ data }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling style callback correctly', () => {
|
||||||
|
expect(classesCallBack.callCount).toBe(1);
|
||||||
|
expect(classesCallBack.calledWith(data[0]), 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render Row component with correct style prop', () => {
|
||||||
|
expect(wrapper.find(Row).get(0).props.className).toEqual(className);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow.bgColor is defined as a string', () => {
|
||||||
|
const bgColor = 'red';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow.bgColor = bgColor;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
data={ data }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render Row component with correct style.backgroundColor prop', () => {
|
||||||
|
expect(wrapper.find(Row).get(0).props.style).toEqual({ backgroundColor: bgColor });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow.bgColor is defined as a string', () => {
|
||||||
|
const bgColor = 'red';
|
||||||
|
const bgColorCallBack = sinon.stub().returns(bgColor);
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow.bgColor = bgColorCallBack;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
data={ data }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling selectRow.bgColor callback correctly', () => {
|
||||||
|
expect(bgColorCallBack.calledOnce).toBeTruthy();
|
||||||
|
expect(bgColorCallBack.calledWith(data[0]), 1).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render Row component with correct style.backgroundColor prop', () => {
|
||||||
|
expect(wrapper.find(Row).get(0).props.style).toEqual({ backgroundColor: bgColor });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow.bgColor defined and selectRow.style.backgroundColor defined', () => {
|
||||||
|
const bgColor = 'yellow';
|
||||||
|
const style = { backgroundColor: 'red' };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow.style = style;
|
||||||
|
selectRow.bgColor = bgColor;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
data={ data }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should take selectRow.bgColor as higher priority', () => {
|
||||||
|
expect(wrapper.find(Row).get(0).props.style.backgroundColor).toBe(bgColor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow.nonSelectable is defined', () => {
|
||||||
|
const nonSelectableRowIndex = 1;
|
||||||
|
const nonSelectable = [data[nonSelectableRowIndex][keyField]];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow.nonSelectable = nonSelectable;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
data={ data }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
selectedRowKeys={ selectedRowKeys }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render Row component with correct selectable prop', () => {
|
||||||
|
expect(wrapper.find(Row).get(0).props.selectable).toBeTruthy();
|
||||||
|
expect(wrapper.find(Row).get(nonSelectableRowIndex).props.selectable).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when selectRow.mode is ROW_SELECT_DISABLED (row was un-selectable)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(
|
||||||
|
<Body
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
data={ data }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
selectedRowKeys={ [] }
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render RowAggregator component correctly', () => {
|
it('prop selected should be null', () => {
|
||||||
const rowAggregator = wrapper.find(RowAggregator);
|
expect(wrapper.find(Row).get(0).props.selected).toBeNull();
|
||||||
expect(rowAggregator.get(0).props.expandRow.renderer).toEqual(expandRow.renderer);
|
|
||||||
expect(rowAggregator.get(0).props.expanded).toBeDefined();
|
|
||||||
expect(rowAggregator.get(0).props.expandable).toBeDefined();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -111,10 +111,7 @@ describe('Context', () => {
|
|||||||
createContext: jest.fn().mockReturnValue({
|
createContext: jest.fn().mockReturnValue({
|
||||||
Provider: CellEditContext.Provider,
|
Provider: CellEditContext.Provider,
|
||||||
Consumer: CellEditContext.Consumer
|
Consumer: CellEditContext.Consumer
|
||||||
}),
|
})
|
||||||
bindCellLevelCellEdit: jest.fn().mockReturnValue(() => null),
|
|
||||||
createEditingCell: jest.fn().mockReturnValue(() => null),
|
|
||||||
bindRowLevelCellEdit: jest.fn().mockReturnValue(() => null)
|
|
||||||
};
|
};
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
<BootstrapTable
|
<BootstrapTable
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { shallow } from 'enzyme';
|
|||||||
|
|
||||||
import dataOperator from '../../src/store/operators';
|
import dataOperator from '../../src/store/operators';
|
||||||
import BootstrapTable from '../../src/bootstrap-table';
|
import BootstrapTable from '../../src/bootstrap-table';
|
||||||
import SelectionContext from '../../src/contexts/selection-context';
|
import createSelectionContext from '../../src/contexts/selection-context';
|
||||||
|
|
||||||
describe('DataContext', () => {
|
describe('DataContext', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
@@ -42,6 +42,7 @@ describe('DataContext', () => {
|
|||||||
const defaultSelectRow = {
|
const defaultSelectRow = {
|
||||||
mode: 'checkbox'
|
mode: 'checkbox'
|
||||||
};
|
};
|
||||||
|
const SelectionContext = createSelectionContext(dataOperator);
|
||||||
|
|
||||||
function shallowContext(selectRow = defaultSelectRow) {
|
function shallowContext(selectRow = defaultSelectRow) {
|
||||||
return (
|
return (
|
||||||
@@ -80,13 +81,9 @@ describe('DataContext', () => {
|
|||||||
it('should pass correct sort props to children element', () => {
|
it('should pass correct sort props to children element', () => {
|
||||||
expect(wrapper.length).toBe(1);
|
expect(wrapper.length).toBe(1);
|
||||||
expect(mockBase).toHaveBeenCalledWith({
|
expect(mockBase).toHaveBeenCalledWith({
|
||||||
...defaultSelectRow,
|
|
||||||
selected: wrapper.state().selected,
|
selected: wrapper.state().selected,
|
||||||
onRowSelect: wrapper.instance().handleRowSelect,
|
onRowSelect: wrapper.instance().handleRowSelect,
|
||||||
onAllRowsSelect: wrapper.instance().handleAllRowsSelect,
|
onAllRowsSelect: wrapper.instance().handleAllRowsSelect
|
||||||
allRowsNotSelected: true,
|
|
||||||
allRowsSelected: false,
|
|
||||||
checkedStatus: 'unchecked'
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -223,6 +220,25 @@ describe('DataContext', () => {
|
|||||||
it('should set state.selected correctly', () => {
|
it('should set state.selected correctly', () => {
|
||||||
expect(wrapper.state('selected')).toEqual(data.map(d => d[keyField]));
|
expect(wrapper.state('selected')).toEqual(data.map(d => d[keyField]));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when selectRow.onSelectAll is defined', () => {
|
||||||
|
const onSelectAll = jest.fn();
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext({
|
||||||
|
...defaultSelectRow,
|
||||||
|
onSelectAll
|
||||||
|
}));
|
||||||
|
wrapper.instance().handleAllRowsSelect(e, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call selectRow.onSelectAll correctly', () => {
|
||||||
|
expect(onSelectAll).toHaveBeenCalledWith(
|
||||||
|
true,
|
||||||
|
dataOperator.getSelectedRows(data, keyField, wrapper.state('selected')),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when isUnSelect argument is true', () => {
|
describe('when isUnSelect argument is true', () => {
|
||||||
@@ -237,24 +253,25 @@ describe('DataContext', () => {
|
|||||||
it('should set state.selected correctly', () => {
|
it('should set state.selected correctly', () => {
|
||||||
expect(wrapper.state('selected')).toEqual([]);
|
expect(wrapper.state('selected')).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('when selectRow.onSelectAll is defined', () => {
|
describe('when selectRow.onSelectAll is defined', () => {
|
||||||
const onSelectAll = jest.fn();
|
const onSelectAll = jest.fn();
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = shallow(shallowContext({
|
wrapper = shallow(shallowContext({
|
||||||
...defaultSelectRow,
|
...defaultSelectRow,
|
||||||
onSelectAll
|
selected: data.map(d => d[keyField]),
|
||||||
}));
|
onSelectAll
|
||||||
wrapper.instance().handleAllRowsSelect(e, false);
|
}));
|
||||||
});
|
wrapper.instance().handleAllRowsSelect(e, true);
|
||||||
|
});
|
||||||
|
|
||||||
it('should call selectRow.onSelectAll correctly', () => {
|
it('should call selectRow.onSelectAll correctly', () => {
|
||||||
expect(onSelectAll).toHaveBeenCalledWith(
|
expect(onSelectAll).toHaveBeenCalledWith(
|
||||||
true,
|
false,
|
||||||
dataOperator.getSelectedRows(data, keyField, wrapper.state('selected')),
|
dataOperator.getSelectedRows(data, keyField, data.map(d => d[keyField])),
|
||||||
e
|
e
|
||||||
);
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
import 'jsdom-global/register';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
|
|
||||||
import HeaderCell from '../src/header-cell';
|
import HeaderCell from '../src/header-cell';
|
||||||
import SelectionHeaderCell from '../src/row-selection/selection-header-cell';
|
import SelectionHeaderCell from '../src//row-selection/selection-header-cell';
|
||||||
import ExpandHeaderCell from '../src/row-expand/expand-header-cell';
|
|
||||||
import SelectionContext from '../src/contexts/selection-context';
|
|
||||||
import ExpansionContext from '../src/contexts/row-expand-context';
|
|
||||||
import Header from '../src/header';
|
import Header from '../src/header';
|
||||||
import Const from '../src/const';
|
import Const from '../src/const';
|
||||||
import mockHeaderResolvedProps from './test-helpers/mock/header-resolved-props';
|
import mockHeaderResolvedProps from './test-helpers/mock/header-resolved-props';
|
||||||
@@ -21,16 +17,6 @@ describe('Header', () => {
|
|||||||
text: 'Name'
|
text: 'Name'
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const data = [{
|
|
||||||
id: 1,
|
|
||||||
name: 'A'
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
name: 'B'
|
|
||||||
}];
|
|
||||||
|
|
||||||
const keyField = 'id';
|
|
||||||
|
|
||||||
describe('simplest header', () => {
|
describe('simplest header', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = shallow(<Header { ...mockHeaderResolvedProps } columns={ columns } />);
|
wrapper = shallow(<Header { ...mockHeaderResolvedProps } columns={ columns } />);
|
||||||
@@ -103,18 +89,12 @@ describe('Header', () => {
|
|||||||
describe('when selectRow.mode is radio (single selection)', () => {
|
describe('when selectRow.mode is radio (single selection)', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const selectRow = { mode: 'radio' };
|
const selectRow = { mode: 'radio' };
|
||||||
wrapper = mount(
|
wrapper = shallow(
|
||||||
<SelectionContext.Provider
|
<Header
|
||||||
data={ data }
|
{ ...mockHeaderResolvedProps }
|
||||||
keyField={ keyField }
|
columns={ columns }
|
||||||
selectRow={ selectRow }
|
selectRow={ selectRow }
|
||||||
>
|
/>
|
||||||
<Header
|
|
||||||
{ ...mockHeaderResolvedProps }
|
|
||||||
columns={ columns }
|
|
||||||
selectRow={ selectRow }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -125,18 +105,12 @@ describe('Header', () => {
|
|||||||
describe('when selectRow.hideSelectColumn is true', () => {
|
describe('when selectRow.hideSelectColumn is true', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const selectRow = { mode: 'radio', hideSelectColumn: true };
|
const selectRow = { mode: 'radio', hideSelectColumn: true };
|
||||||
wrapper = mount(
|
wrapper = shallow(
|
||||||
<SelectionContext.Provider
|
<Header
|
||||||
data={ data }
|
{ ...mockHeaderResolvedProps }
|
||||||
keyField={ keyField }
|
columns={ columns }
|
||||||
selectRow={ selectRow }
|
selectRow={ selectRow }
|
||||||
>
|
/>
|
||||||
<Header
|
|
||||||
{ ...mockHeaderResolvedProps }
|
|
||||||
columns={ columns }
|
|
||||||
selectRow={ selectRow }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -172,18 +146,12 @@ describe('Header', () => {
|
|||||||
describe('when selectRow.mode is checkbox (multiple selection)', () => {
|
describe('when selectRow.mode is checkbox (multiple selection)', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const selectRow = { mode: 'checkbox' };
|
const selectRow = { mode: 'checkbox' };
|
||||||
wrapper = mount(
|
wrapper = shallow(
|
||||||
<SelectionContext.Provider
|
<Header
|
||||||
data={ data }
|
{ ...mockHeaderResolvedProps }
|
||||||
keyField={ keyField }
|
columns={ columns }
|
||||||
selectRow={ selectRow }
|
selectRow={ selectRow }
|
||||||
>
|
/>
|
||||||
<Header
|
|
||||||
{ ...mockHeaderResolvedProps }
|
|
||||||
columns={ columns }
|
|
||||||
selectRow={ selectRow }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -194,18 +162,12 @@ describe('Header', () => {
|
|||||||
describe('when selectRow.hideSelectColumn is true', () => {
|
describe('when selectRow.hideSelectColumn is true', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const selectRow = { mode: 'checkbox', hideSelectColumn: true };
|
const selectRow = { mode: 'checkbox', hideSelectColumn: true };
|
||||||
wrapper = mount(
|
wrapper = shallow(
|
||||||
<SelectionContext.Provider
|
<Header
|
||||||
data={ data }
|
{ ...mockHeaderResolvedProps }
|
||||||
keyField={ keyField }
|
columns={ columns }
|
||||||
selectRow={ selectRow }
|
selectRow={ selectRow }
|
||||||
>
|
/>
|
||||||
<Header
|
|
||||||
{ ...mockHeaderResolvedProps }
|
|
||||||
columns={ columns }
|
|
||||||
selectRow={ selectRow }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -215,44 +177,4 @@ describe('Header', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('expandRow', () => {
|
|
||||||
describe('when expandRow.showExpandColumn is false', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = shallow(
|
|
||||||
<Header
|
|
||||||
{ ...mockHeaderResolvedProps }
|
|
||||||
columns={ columns }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not render <ExpandHeaderCell />', () => {
|
|
||||||
expect(wrapper.find(ExpandHeaderCell).length).toBe(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when expandRow.showExpandColumn is true', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const expandRow = { renderer: jest.fn(), expanded: [], showExpandColumn: true };
|
|
||||||
wrapper = mount(
|
|
||||||
<ExpansionContext.Provider
|
|
||||||
data={ data }
|
|
||||||
keyField={ keyField }
|
|
||||||
expandRow={ expandRow }
|
|
||||||
>
|
|
||||||
<Header
|
|
||||||
{ ...mockHeaderResolvedProps }
|
|
||||||
columns={ columns }
|
|
||||||
expandRow={ expandRow }
|
|
||||||
/>
|
|
||||||
</ExpansionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render <ExpandHeaderCell /> correctly', () => {
|
|
||||||
expect(wrapper.find(ExpandHeaderCell).length).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import sinon from 'sinon';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
|
|
||||||
import { extendTo } from '../test-helpers/mock-component';
|
import { extendTo } from '../test-helpers/mock-component';
|
||||||
import baseResolver from '../../src/props-resolver/index';
|
import baseResolver from '../../src/props-resolver/index';
|
||||||
|
import Const from '../../src/const';
|
||||||
|
|
||||||
describe('TableResolver', () => {
|
describe('TableResolver', () => {
|
||||||
const keyField = 'id';
|
const keyField = 'id';
|
||||||
@@ -69,4 +71,231 @@ describe('TableResolver', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('resolveSelectRowProps', () => {
|
||||||
|
let cellSelectionInfo;
|
||||||
|
let selectRow;
|
||||||
|
|
||||||
|
describe('if selectRow was not defined', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns
|
||||||
|
}, null);
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
cellSelectionInfo = wrapper.instance().resolveSelectRowProps();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return object', () => {
|
||||||
|
expect(cellSelectionInfo).toBeDefined();
|
||||||
|
expect(cellSelectionInfo.constructor).toEqual(Object);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain mode in ROW_SELECT_DISABLED', () => {
|
||||||
|
expect(cellSelectionInfo.mode).toEqual(Const.ROW_SELECT_DISABLED);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow was defined', () => {
|
||||||
|
describe('when mode was defined', () => {
|
||||||
|
it('should return object which contains ROW_SELECT_SINGLE if mode is radio', () => {
|
||||||
|
selectRow = { mode: 'radio' };
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns, selectRow
|
||||||
|
}, null);
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
cellSelectionInfo = wrapper.instance().resolveSelectRowProps();
|
||||||
|
|
||||||
|
expect(cellSelectionInfo).toBeDefined();
|
||||||
|
expect(cellSelectionInfo.constructor).toEqual(Object);
|
||||||
|
expect(cellSelectionInfo.mode).toEqual(Const.ROW_SELECT_SINGLE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return object which contains ROW_SELECT_MULTIPLE if mode is checkbox', () => {
|
||||||
|
selectRow = { mode: 'checkbox' };
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns, selectRow
|
||||||
|
}, null);
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
cellSelectionInfo = wrapper.instance().resolveSelectRowProps();
|
||||||
|
|
||||||
|
expect(cellSelectionInfo).toBeDefined();
|
||||||
|
expect(cellSelectionInfo.constructor).toEqual(Object);
|
||||||
|
expect(cellSelectionInfo.mode).toEqual(Const.ROW_SELECT_MULTIPLE);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when options were given', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = {};
|
||||||
|
const mockOptions = {
|
||||||
|
foo: 'test',
|
||||||
|
bar: sinon.stub()
|
||||||
|
};
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns, selectRow
|
||||||
|
}, null);
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
cellSelectionInfo = wrapper.instance().resolveSelectRowProps(mockOptions);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return object which contain options', () => {
|
||||||
|
expect(cellSelectionInfo).toEqual(expect.objectContaining({
|
||||||
|
foo: 'test',
|
||||||
|
bar: expect.any(Function)
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveSelectRowPropsForHeader', () => {
|
||||||
|
let headerCellSelectionInfo;
|
||||||
|
let selectRow;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns
|
||||||
|
}, null);
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
headerCellSelectionInfo = wrapper.instance().resolveSelectRowPropsForHeader();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow was not defined', () => {
|
||||||
|
it('should return object', () => {
|
||||||
|
expect(headerCellSelectionInfo).toBeDefined();
|
||||||
|
expect(headerCellSelectionInfo.constructor).toEqual(Object);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain mode in ROW_SELECT_DISABLED', () => {
|
||||||
|
expect(headerCellSelectionInfo.mode).toEqual(Const.ROW_SELECT_DISABLED);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow was defined', () => {
|
||||||
|
describe('when mode was defined', () => {
|
||||||
|
it('should return object which contains ROW_SELECT_SINGLE if mode is radio', () => {
|
||||||
|
selectRow = { mode: 'radio' };
|
||||||
|
const selectedRowKeys = [];
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns, selectedRowKeys, selectRow
|
||||||
|
}, null);
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
headerCellSelectionInfo = wrapper.instance().resolveSelectRowPropsForHeader();
|
||||||
|
|
||||||
|
expect(headerCellSelectionInfo).toBeDefined();
|
||||||
|
expect(headerCellSelectionInfo.constructor).toEqual(Object);
|
||||||
|
expect(headerCellSelectionInfo.mode).toEqual(Const.ROW_SELECT_SINGLE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return object which contains ROW_SELECT_MULTIPLE if mode is checkbox', () => {
|
||||||
|
selectRow = { mode: 'checkbox' };
|
||||||
|
const selectedRowKeys = [];
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns, selectedRowKeys, selectRow
|
||||||
|
}, null);
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
headerCellSelectionInfo = wrapper.instance().resolveSelectRowPropsForHeader();
|
||||||
|
|
||||||
|
expect(headerCellSelectionInfo).toBeDefined();
|
||||||
|
expect(headerCellSelectionInfo.constructor).toEqual(Object);
|
||||||
|
expect(headerCellSelectionInfo.mode).toEqual(Const.ROW_SELECT_MULTIPLE);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when options were given', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = {};
|
||||||
|
const mockOptions = {
|
||||||
|
foo: 'test',
|
||||||
|
bar: sinon.stub(),
|
||||||
|
allRowsSelected: false,
|
||||||
|
selected: []
|
||||||
|
};
|
||||||
|
const selectedRowKeys = [];
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns, selectedRowKeys, selectRow
|
||||||
|
}, null);
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
headerCellSelectionInfo = wrapper.instance().resolveSelectRowPropsForHeader(mockOptions);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return object which contain specified options', () => {
|
||||||
|
expect(headerCellSelectionInfo).toEqual(expect.objectContaining({
|
||||||
|
foo: 'test',
|
||||||
|
bar: expect.any(Function)
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if options.allRowsSelected is true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = {};
|
||||||
|
const selectedRowKeys = [1, 2];
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns, selectRow
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
|
||||||
|
headerCellSelectionInfo = wrapper.instance().resolveSelectRowPropsForHeader({
|
||||||
|
allRowsSelected: true,
|
||||||
|
selected: selectedRowKeys
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return checkedStatus which eqauls to checked', () => {
|
||||||
|
expect(headerCellSelectionInfo).toEqual(expect.objectContaining({
|
||||||
|
checkedStatus: Const.CHECKBOX_STATUS_CHECKED
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if options.allRowsSelected and options.allRowsNotSelected both are false', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = {};
|
||||||
|
const selectedRowKeys = [1];
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns, selectRow
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
headerCellSelectionInfo = wrapper.instance().resolveSelectRowPropsForHeader({
|
||||||
|
allRowsSelected: false,
|
||||||
|
allRowsNotSelected: false,
|
||||||
|
selected: selectedRowKeys
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return checkedStatus which eqauls to indeterminate', () => {
|
||||||
|
expect(headerCellSelectionInfo).toEqual(expect.objectContaining({
|
||||||
|
checkedStatus: Const.CHECKBOX_STATUS_INDETERMINATE
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if options.allRowsNotSelected is true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = {};
|
||||||
|
const selectedRowKeys = [];
|
||||||
|
const mockElement = React.createElement(BootstrapTableMock, {
|
||||||
|
data, keyField, columns, selectRow
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
wrapper = shallow(mockElement);
|
||||||
|
|
||||||
|
headerCellSelectionInfo = wrapper.instance().resolveSelectRowPropsForHeader({
|
||||||
|
allRowsSelected: false,
|
||||||
|
allRowsNotSelected: true,
|
||||||
|
selected: selectedRowKeys
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return checkedStatus which eqauls to unchecked', () => {
|
||||||
|
expect(headerCellSelectionInfo).toEqual(expect.objectContaining({
|
||||||
|
checkedStatus: Const.CHECKBOX_STATUS_UNCHECKED
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,296 +0,0 @@
|
|||||||
import 'jsdom-global/register';
|
|
||||||
import React from 'react';
|
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import mockBodyResolvedProps from './test-helpers/mock/body-resolved-props';
|
|
||||||
import SelectionContext from '../src/contexts/selection-context';
|
|
||||||
import ExpansionContext from '../src/contexts/row-expand-context';
|
|
||||||
import bindSelection from '../src/row-selection/row-binder';
|
|
||||||
import bindExpansion from '../src/row-expand/row-binder';
|
|
||||||
import ExpandCell from '../src/row-expand/expand-cell';
|
|
||||||
import SelectionCell from '../src/row-selection/selection-cell';
|
|
||||||
import RowAggregator from '../src/row-aggregator';
|
|
||||||
import Row from '../src/row';
|
|
||||||
|
|
||||||
describe('Row Aggregator', () => {
|
|
||||||
let wrapper;
|
|
||||||
let rowAggregator;
|
|
||||||
const RowAggregatorWithSelection = bindSelection(RowAggregator);
|
|
||||||
const RowAggregatorWithExpansion = bindExpansion(RowAggregator);
|
|
||||||
|
|
||||||
const data = [{
|
|
||||||
id: 1,
|
|
||||||
name: 'A'
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
name: 'B'
|
|
||||||
}, {
|
|
||||||
id: 3,
|
|
||||||
name: 'C'
|
|
||||||
}];
|
|
||||||
const columns = [{
|
|
||||||
dataField: 'id',
|
|
||||||
text: 'ID'
|
|
||||||
}, {
|
|
||||||
dataField: 'name',
|
|
||||||
text: 'Name'
|
|
||||||
}];
|
|
||||||
const rowIndex = 1;
|
|
||||||
const row = data[rowIndex];
|
|
||||||
const keyField = 'id';
|
|
||||||
|
|
||||||
const getBaseProps = () => ({
|
|
||||||
row,
|
|
||||||
value: row[keyField],
|
|
||||||
columns,
|
|
||||||
keyField,
|
|
||||||
rowIndex,
|
|
||||||
...mockBodyResolvedProps
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when selectRow is enable', () => {
|
|
||||||
describe('if props.selectRow.hideSelectColumn is false', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const selectRow = { mode: 'radio' };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<RowAggregatorWithSelection { ...getBaseProps() } />
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render RowAggregator correctly', () => {
|
|
||||||
rowAggregator = wrapper.find(RowAggregator);
|
|
||||||
expect(rowAggregator).toHaveLength(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render selection column correctly', () => {
|
|
||||||
const selectionCell = wrapper.find(SelectionCell);
|
|
||||||
expect(selectionCell).toHaveLength(1);
|
|
||||||
expect(selectionCell.props().selected).toEqual(rowAggregator.props().selected);
|
|
||||||
expect(selectionCell.props().disabled).toEqual(!rowAggregator.props().selectable);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if props.selectRow.hideSelectColumn is true', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const selectRow = { mode: 'radio', hideSelectColumn: true };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<RowAggregatorWithSelection { ...getBaseProps() } />
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render RowAggregator correctly', () => {
|
|
||||||
rowAggregator = wrapper.find(RowAggregator);
|
|
||||||
expect(rowAggregator).toHaveLength(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not render selection column', () => {
|
|
||||||
const selectionCell = wrapper.find(SelectionCell);
|
|
||||||
expect(selectionCell).toHaveLength(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if props.selectRow.clickToSelect is defined', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const selectRow = { mode: 'radio', clickToSelect: true };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<RowAggregatorWithSelection { ...getBaseProps() } />
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render RowAggregator correctly', () => {
|
|
||||||
rowAggregator = wrapper.find(RowAggregator);
|
|
||||||
expect(rowAggregator).toHaveLength(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add onClick prop to Row Component', () => {
|
|
||||||
const rowComp = wrapper.find(Row);
|
|
||||||
expect(rowComp).toHaveLength(1);
|
|
||||||
expect(rowComp.props().attrs.onClick).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when expandRow is enable', () => {
|
|
||||||
describe('if props.expandRow.showExpandColumn is false', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const expandRow = { renderer: jest.fn() };
|
|
||||||
wrapper = mount(
|
|
||||||
<ExpansionContext.Provider data={ data } keyField={ keyField } expandRow={ expandRow }>
|
|
||||||
<RowAggregatorWithExpansion { ...getBaseProps() } />
|
|
||||||
</ExpansionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render RowAggregator correctly', () => {
|
|
||||||
rowAggregator = wrapper.find(RowAggregator);
|
|
||||||
expect(rowAggregator).toHaveLength(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not render expansion column', () => {
|
|
||||||
const expandCell = wrapper.find(ExpandCell);
|
|
||||||
expect(expandCell).toHaveLength(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if props.expandRow.showExpandColumn is true', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const expandRow = { renderer: jest.fn(), showExpandColumn: true };
|
|
||||||
wrapper = mount(
|
|
||||||
<ExpansionContext.Provider data={ data } keyField={ keyField } expandRow={ expandRow }>
|
|
||||||
<RowAggregatorWithExpansion { ...getBaseProps() } />
|
|
||||||
</ExpansionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render RowAggregator correctly', () => {
|
|
||||||
rowAggregator = wrapper.find(RowAggregator);
|
|
||||||
expect(rowAggregator).toHaveLength(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render expansion column correctly', () => {
|
|
||||||
const expandCell = wrapper.find(ExpandCell);
|
|
||||||
expect(expandCell).toHaveLength(1);
|
|
||||||
expect(expandCell.props().expanded).toEqual(rowAggregator.props().expanded);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('createClickEventHandler', () => {
|
|
||||||
describe('if props.attrs.onClick is defined', () => {
|
|
||||||
const attrs = { onClick: jest.fn() };
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
const selectRow = { mode: 'radio' };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<RowAggregatorWithSelection { ...getBaseProps() } attrs={ attrs } />
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
wrapper.find('tr').simulate('click');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call attrs.onClick correctly', () => {
|
|
||||||
expect(attrs.onClick).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if props.selectRow.clickToSelect is true', () => {
|
|
||||||
const selectRow = { mode: 'radio', clickToSelect: true };
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<RowAggregatorWithSelection { ...getBaseProps() } />
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
wrapper.find(RowAggregator).props().selectRow.onRowSelect = jest.fn();
|
|
||||||
wrapper.find('tr').simulate('click');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call selectRow.onRowSelect correctly', () => {
|
|
||||||
expect(wrapper.find(RowAggregator).props().selectRow.onRowSelect).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if props.selectRow.clickToSelect is true', () => {
|
|
||||||
describe('but selectable props is false', () => {
|
|
||||||
const selectRow = { mode: 'radio', clickToSelect: true, nonSelectable: [row[keyField]] };
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<RowAggregatorWithSelection { ...getBaseProps() } />
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
wrapper.find(RowAggregator).props().selectRow.onRowSelect = jest.fn();
|
|
||||||
wrapper.find('tr').simulate('click');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call selectRow.onRowSelect correctly', () => {
|
|
||||||
expect(wrapper.find(RowAggregator).props().selectRow.onRowSelect)
|
|
||||||
.toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if props.expandRow.renderer is defined', () => {
|
|
||||||
describe('but expandable props is false', () => {
|
|
||||||
const expandRow = { renderer: jest.fn(), nonExpandable: [row[keyField]] };
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<ExpansionContext.Provider data={ data } keyField={ keyField } expandRow={ expandRow }>
|
|
||||||
<RowAggregatorWithExpansion { ...getBaseProps() } />
|
|
||||||
</ExpansionContext.Provider>
|
|
||||||
);
|
|
||||||
wrapper.find(RowAggregator).props().expandRow.onRowExpand = jest.fn();
|
|
||||||
wrapper.find('tr').simulate('click');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call expandRow.onRowExpand correctly', () => {
|
|
||||||
expect(wrapper.find(RowAggregator).props().expandRow.onRowExpand)
|
|
||||||
.toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if props.expandRow.renderer is defined', () => {
|
|
||||||
const expandRow = { renderer: jest.fn() };
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<ExpansionContext.Provider data={ data } keyField={ keyField } expandRow={ expandRow }>
|
|
||||||
<RowAggregatorWithExpansion { ...getBaseProps() } />
|
|
||||||
</ExpansionContext.Provider>
|
|
||||||
);
|
|
||||||
wrapper.find(RowAggregator).props().expandRow.onRowExpand = jest.fn();
|
|
||||||
wrapper.find('tr').simulate('click');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call expandRow.onRowExpand correctly', () => {
|
|
||||||
expect(wrapper.find(RowAggregator).props().expandRow.onRowExpand).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if props.attrs.onClick and props.expandRow.renderer both are defined', () => {
|
|
||||||
const attrs = { onClick: jest.fn() };
|
|
||||||
const expandRow = { renderer: jest.fn() };
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<ExpansionContext.Provider data={ data } keyField={ keyField } expandRow={ expandRow }>
|
|
||||||
<RowAggregatorWithExpansion { ...getBaseProps() } attrs={ attrs } />
|
|
||||||
</ExpansionContext.Provider>
|
|
||||||
);
|
|
||||||
wrapper.find(RowAggregator).props().expandRow.onRowExpand = jest.fn();
|
|
||||||
wrapper.find('tr').simulate('click');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call attrs.onClick and expandRow.onRowExpand correctly', () => {
|
|
||||||
expect(attrs.onClick).toHaveBeenCalledTimes(1);
|
|
||||||
expect(wrapper.find(RowAggregator).props().expandRow.onRowExpand).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if props.attrs.onClick and props.selectRow.clickToSelect both are defined', () => {
|
|
||||||
const attrs = { onClick: jest.fn() };
|
|
||||||
const selectRow = { mode: 'radio', clickToSelect: true };
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<RowAggregatorWithSelection { ...getBaseProps() } attrs={ attrs } />
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
wrapper.find(RowAggregator).props().selectRow.onRowSelect = jest.fn();
|
|
||||||
wrapper.find('tr').simulate('click');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call attrs.onClick and selectRow.onRowSelect correctly', () => {
|
|
||||||
expect(attrs.onClick).toHaveBeenCalledTimes(1);
|
|
||||||
expect(wrapper.find(RowAggregator).props().selectRow.onRowSelect).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,414 +0,0 @@
|
|||||||
import 'jsdom-global/register';
|
|
||||||
import React from 'react';
|
|
||||||
import { mount } from 'enzyme';
|
|
||||||
|
|
||||||
import SelectionContext from '../../src/contexts/selection-context';
|
|
||||||
import bindSelection from '../../src/row-selection/row-binder';
|
|
||||||
|
|
||||||
describe('Selection Row Binder', () => {
|
|
||||||
let wrapper;
|
|
||||||
let selectRow;
|
|
||||||
const BaseComponent = () => null;
|
|
||||||
const WithSelectionComponent = bindSelection(props => <BaseComponent { ...props } />);
|
|
||||||
|
|
||||||
const data = [{
|
|
||||||
id: 1,
|
|
||||||
name: 'A'
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
name: 'B'
|
|
||||||
}, {
|
|
||||||
id: 3,
|
|
||||||
name: 'C'
|
|
||||||
}];
|
|
||||||
const rowIndex = 1;
|
|
||||||
const row = data[rowIndex];
|
|
||||||
const keyField = 'id';
|
|
||||||
const value = row[keyField];
|
|
||||||
|
|
||||||
describe('if current row is selected', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow = { mode: 'checkbox', selected: [data[rowIndex][keyField]] };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject selected prop as true to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('selected')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if current row is not selected', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow = { mode: 'checkbox', selected: [] };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject selected prop as false to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('selected')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if current row is selectable', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow = { mode: 'checkbox', nonSelectable: [] };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject selectable prop as true to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('selectable')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if current row is non selectable', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow = { mode: 'checkbox', nonSelectable: [data[rowIndex][keyField]] };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject selectable prop as false to target component', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('selectable')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if current row is selected', () => {
|
|
||||||
const selectedStyle = { backgroundColor: 'green', fontWeight: 'bold' };
|
|
||||||
describe('when selectRow.style is defined as an object', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow = { mode: 'checkbox', selected: [data[rowIndex][keyField]], style: selectedStyle };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop correctly', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('style')).toEqual(selectedStyle);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('and props.style is also defined', () => {
|
|
||||||
const componentStype = { fontSize: '16px' };
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
style={ componentStype }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop correctly', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('style')).toEqual({
|
|
||||||
...selectedStyle,
|
|
||||||
...componentStype
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('and selectRow.bgColor is also defined as an object', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow.bgColor = 'gray';
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop with correct backgroundColor', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('style')).toEqual({
|
|
||||||
...selectedStyle,
|
|
||||||
backgroundColor: selectRow.bgColor
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('and selectRow.bgColor is also defined as a function', () => {
|
|
||||||
const color = 'gray';
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow.bgColor = jest.fn().mockReturnValue(color);
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop with correct backgroundColor', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('style')).toEqual({
|
|
||||||
...selectedStyle,
|
|
||||||
backgroundColor: color
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call selectRow.bgColor function correctly', () => {
|
|
||||||
expect(selectRow.bgColor).toHaveBeenCalledTimes(1);
|
|
||||||
expect(selectRow.bgColor).toHaveBeenCalledWith(row, rowIndex);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when selectRow.style is defined as a function', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow = { mode: 'checkbox', selected: [data[rowIndex][keyField]], style: jest.fn().mockReturnValue(selectedStyle) };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop correctly', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('style')).toEqual(selectedStyle);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call selectRow.style function correctly', () => {
|
|
||||||
expect(selectRow.style).toHaveBeenCalledTimes(1);
|
|
||||||
expect(selectRow.style).toHaveBeenCalledWith(row, rowIndex);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('and props.style is also defined', () => {
|
|
||||||
const componentStype = { fontSize: '16px' };
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
style={ componentStype }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop correctly', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('style')).toEqual({
|
|
||||||
...selectedStyle,
|
|
||||||
...componentStype
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('and selectRow.bgColor is also defined as an object', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow.bgColor = 'gray';
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop with correct backgroundColor', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('style')).toEqual({
|
|
||||||
...selectedStyle,
|
|
||||||
backgroundColor: selectRow.bgColor
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('and selectRow.bgColor is also defined as a function', () => {
|
|
||||||
const color = 'gray';
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow.bgColor = jest.fn().mockReturnValue(color);
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop with correct backgroundColor', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('style')).toEqual({
|
|
||||||
...selectedStyle,
|
|
||||||
backgroundColor: color
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call selectRow.bgColor function correctly', () => {
|
|
||||||
expect(selectRow.bgColor).toHaveBeenCalledTimes(1);
|
|
||||||
expect(selectRow.bgColor).toHaveBeenCalledWith(row, rowIndex);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if current row is selected', () => {
|
|
||||||
const selectedClassName = 'select-classname';
|
|
||||||
describe('when selectRow.style is defined as an object', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow = { mode: 'checkbox', selected: [data[rowIndex][keyField]], classes: selectedClassName };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject className prop correctly', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('className')).toEqual(selectedClassName);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('and props.className is also defined', () => {
|
|
||||||
const componentClassName = 'component-classname';
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
className={ componentClassName }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop correctly', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('className')).toEqual(`${componentClassName} ${selectedClassName}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when selectRow.style is defined as a function', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
selectRow = { mode: 'checkbox', selected: [data[rowIndex][keyField]], classes: jest.fn().mockReturnValue(selectedClassName) };
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject className prop correctly', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('className')).toEqual(selectedClassName);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call selectRow.classes function correctly', () => {
|
|
||||||
expect(selectRow.classes).toHaveBeenCalledTimes(1);
|
|
||||||
expect(selectRow.classes).toHaveBeenCalledWith(row, rowIndex);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('and props.className is also defined', () => {
|
|
||||||
const componentClassName = 'component-classname';
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = mount(
|
|
||||||
<SelectionContext.Provider data={ data } keyField={ keyField } selectRow={ selectRow }>
|
|
||||||
<WithSelectionComponent
|
|
||||||
row={ row }
|
|
||||||
value={ value }
|
|
||||||
keyField={ keyField }
|
|
||||||
rowIndex={ rowIndex }
|
|
||||||
className={ componentClassName }
|
|
||||||
/>
|
|
||||||
</SelectionContext.Provider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inject style prop correctly', () => {
|
|
||||||
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
|
||||||
expect(wrapper.find(BaseComponent).prop('className')).toEqual(`${componentClassName} ${selectedClassName}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -104,6 +104,22 @@ describe('<SelectionHeaderCell />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('render', () => {
|
describe('render', () => {
|
||||||
|
describe('when props.hideSelectAll is true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
|
||||||
|
|
||||||
|
wrapper = shallow(
|
||||||
|
<SelectionHeaderCell mode="checkbox" checkedStatus={ checkedStatus } hideSelectAll />
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render empty th element', () => {
|
||||||
|
expect(wrapper.find('th').length).toBe(1);
|
||||||
|
expect(wrapper.find('th[data-row-selection]').length).toBe(1);
|
||||||
|
expect(wrapper.find(CheckBox).length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('when props.mode is radio', () => {
|
describe('when props.mode is radio', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
|
const checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { shallow } from 'enzyme';
|
|||||||
|
|
||||||
import Cell from '../src/cell';
|
import Cell from '../src/cell';
|
||||||
import Row from '../src/row';
|
import Row from '../src/row';
|
||||||
|
import Const from '../src/const';
|
||||||
|
import SelectionCell from '../src//row-selection/selection-cell';
|
||||||
import mockBodyResolvedProps from './test-helpers/mock/body-resolved-props';
|
import mockBodyResolvedProps from './test-helpers/mock/body-resolved-props';
|
||||||
|
|
||||||
let defaultColumns = [{
|
let defaultColumns = [{
|
||||||
@@ -100,50 +102,395 @@ describe('Row', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when CellComponent prop is defined', () => {
|
describe('when cellEdit prop is defined', () => {
|
||||||
const CellComponent = () => null;
|
let columns;
|
||||||
|
let cellEdit;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
columns = defaultColumns;
|
||||||
|
cellEdit = {
|
||||||
|
mode: 'click',
|
||||||
|
CLICK_TO_CELL_EDIT: 'click',
|
||||||
|
DBCLICK_TO_CELL_EDIT: 'dbclick'
|
||||||
|
};
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
<Row
|
<Row
|
||||||
{ ...mockBodyResolvedProps }
|
{ ...mockBodyResolvedProps }
|
||||||
rowIndex={ rowIndex }
|
|
||||||
columns={ defaultColumns }
|
|
||||||
row={ row }
|
row={ row }
|
||||||
CellComponent={ CellComponent }
|
|
||||||
/>);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render CellComponent successfully', () => {
|
|
||||||
expect(wrapper.length).toBe(1);
|
|
||||||
expect(wrapper.find(CellComponent)).toHaveLength(defaultColumns.length);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when editingRowIdx and editingColIdx prop is defined', () => {
|
|
||||||
const editingRowIdx = rowIndex;
|
|
||||||
const editingColIdx = 1;
|
|
||||||
const EditingCellComponent = () => null;
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = shallow(
|
|
||||||
<Row
|
|
||||||
{ ...mockBodyResolvedProps }
|
|
||||||
rowIndex={ rowIndex }
|
rowIndex={ rowIndex }
|
||||||
columns={ defaultColumns }
|
columns={ columns }
|
||||||
row={ row }
|
keyField={ keyField }
|
||||||
EditingCellComponent={ EditingCellComponent }
|
cellEdit={ cellEdit }
|
||||||
editingRowIdx={ editingRowIdx }
|
/>
|
||||||
editingColIdx={ editingColIdx }
|
);
|
||||||
/>);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render EditingCell component correctly', () => {
|
afterEach(() => {
|
||||||
const EditingCell = wrapper.find(EditingCellComponent);
|
columns = undefined;
|
||||||
|
cellEdit = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Cell component should receive correct editable props', () => {
|
||||||
expect(wrapper.length).toBe(1);
|
expect(wrapper.length).toBe(1);
|
||||||
expect(EditingCell).toHaveLength(1);
|
for (let i = 0; i < columns.length; i += 1) {
|
||||||
expect(EditingCell.prop('row')).toEqual(row);
|
const column = columns[i];
|
||||||
expect(EditingCell.prop('rowIndex')).toEqual(editingRowIdx);
|
if (column.dataField === keyField) {
|
||||||
expect(EditingCell.prop('column')).toEqual(defaultColumns[editingColIdx]);
|
expect(wrapper.find(Cell).get(i).props.editable).toBeFalsy();
|
||||||
expect(EditingCell.prop('columnIndex')).toEqual(editingColIdx);
|
} else {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.editable).toBeTruthy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Cell component should receive correct clickToEdit props', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
for (let i = 0; i < columns.length; i += 1) {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.clickToEdit).toBeTruthy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Cell component should receive correct dbclickToEdit props', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
for (let i = 0; i < columns.length; i += 1) {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.dbclickToEdit).toBeFalsy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when props.cellEdit.mode is dbclick', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cellEdit.mode = cellEdit.DBCLICK_TO_CELL_EDIT;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Cell component should receive correct clickToEdit props', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
for (let i = 0; i < columns.length; i += 1) {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.clickToEdit).toBeFalsy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Cell component should receive correct dbclickToEdit props', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
for (let i = 0; i < columns.length; i += 1) {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.dbclickToEdit).toBeTruthy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and column.editable defined false', () => {
|
||||||
|
const nonEditableColIndex = 1;
|
||||||
|
beforeEach(() => {
|
||||||
|
columns[nonEditableColIndex].editable = false;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Cell component should receive correct editable props', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
for (let i = 0; i < columns.length; i += 1) {
|
||||||
|
const column = columns[i];
|
||||||
|
if (i === nonEditableColIndex || column.dataField === keyField) {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.editable).toBeFalsy();
|
||||||
|
} else {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.editable).toBeTruthy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and column.editable defined as function', () => {
|
||||||
|
const nonEditableColIndex = 1;
|
||||||
|
let editableCallBack;
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
editableCallBack.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('which return false', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
editableCallBack = sinon.stub().returns(false);
|
||||||
|
columns[nonEditableColIndex].editable = editableCallBack;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('column.editable callback function should be called once', () => {
|
||||||
|
expect(editableCallBack.callCount).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Cell component should receive correct editable props', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
for (let i = 0; i < columns.length; i += 1) {
|
||||||
|
const column = columns[i];
|
||||||
|
if (i === nonEditableColIndex || column.dataField === keyField) {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.editable).toBeFalsy();
|
||||||
|
} else {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.editable).toBeTruthy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('which return true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
editableCallBack = sinon.stub().returns(true);
|
||||||
|
columns[nonEditableColIndex].editable = editableCallBack;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('column.editable callback function should be called once', () => {
|
||||||
|
expect(editableCallBack.callCount).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Cell component should receive correct editable props', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
for (let i = 0; i < columns.length; i += 1) {
|
||||||
|
const column = columns[i];
|
||||||
|
if (column.dataField === keyField) {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.editable).toBeFalsy();
|
||||||
|
} else {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.editable).toBeTruthy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Means user defined cellEdit.nonEditableRows
|
||||||
|
// and some rows will be treated as noneditable by this rules
|
||||||
|
describe('when editable prop is false', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
editable={ false }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('All the Cell components should be noneditable', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
for (let i = 0; i < columns.length; i += 1) {
|
||||||
|
expect(wrapper.find(Cell).get(i).props.editable).toBeFalsy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Means a cell now is undering editing
|
||||||
|
describe('when cellEdit.ridx and cellEdit.cidx is defined', () => {
|
||||||
|
const EditingCell = () => null;
|
||||||
|
describe('and cellEdit.ridx is match to current row index', () => {
|
||||||
|
const editingColIndex = 1;
|
||||||
|
beforeEach(() => {
|
||||||
|
cellEdit.ridx = rowIndex;
|
||||||
|
cellEdit.cidx = editingColIndex;
|
||||||
|
cellEdit.onUpdate = sinon.stub();
|
||||||
|
cellEdit.onEscape = sinon.stub();
|
||||||
|
cellEdit.EditingCell = EditingCell;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
editable={ false }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render EditingCell correctly', () => {
|
||||||
|
const complexComponents = wrapper.find('tr').children().findWhere(
|
||||||
|
n => n.type().name === 'Cell' || n.type().name === 'EditingCell');
|
||||||
|
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
expect(wrapper.find(EditingCell).length).toBe(1);
|
||||||
|
expect(complexComponents.at(editingColIndex).type()).toEqual(EditingCell);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if column.editCellStyle defined as object', () => {
|
||||||
|
const definedStyleColIndex = editingColIndex;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
columns[definedStyleColIndex].editCellStyle = { backgroundColor: 'red' };
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should also rendering EditingCell with correct style object', () => {
|
||||||
|
expect(wrapper.find(EditingCell).length).toBe(1);
|
||||||
|
expect(wrapper.find(EditingCell).props().style)
|
||||||
|
.toEqual(columns[definedStyleColIndex].editCellStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if column.editCellStyle defined as function', () => {
|
||||||
|
const definedStyleColIndex = editingColIndex;
|
||||||
|
const customStyle = { backgroundColor: 'red' };
|
||||||
|
let editCellStyleCallBack;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
editCellStyleCallBack = sinon.stub().returns(customStyle);
|
||||||
|
columns[definedStyleColIndex].editCellStyle = editCellStyleCallBack;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling custom column.editCellStyle callback correctly', () => {
|
||||||
|
expect(editCellStyleCallBack.callCount).toBe(1);
|
||||||
|
expect(
|
||||||
|
editCellStyleCallBack.calledWith(
|
||||||
|
row[columns[editingColIndex].dataField], row, rowIndex, editingColIndex)
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should also rendering EditingCell with correct style object', () => {
|
||||||
|
expect(wrapper.find(EditingCell).length).toBe(1);
|
||||||
|
expect(wrapper.find(EditingCell).props().style).toEqual(customStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if column.editCellClasses defined as string', () => {
|
||||||
|
const definedStyleColIndex = editingColIndex;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
columns[definedStyleColIndex].editCellClasses = 'custom-class';
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should also rendering EditingCell with correct class', () => {
|
||||||
|
expect(wrapper.find(EditingCell).length).toBe(1);
|
||||||
|
expect(wrapper.find(EditingCell).props().className)
|
||||||
|
.toEqual(columns[definedStyleColIndex].editCellClasses);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if column.editCellClasses defined as function', () => {
|
||||||
|
const definedStyleColIndex = editingColIndex;
|
||||||
|
const customClass = 'custom-class';
|
||||||
|
let editCellClassesCallBack;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
editCellClassesCallBack = sinon.stub().returns(customClass);
|
||||||
|
columns[definedStyleColIndex].editCellClasses = editCellClassesCallBack;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling custom column.editCellStyle callback correctly', () => {
|
||||||
|
expect(editCellClassesCallBack.callCount).toBe(1);
|
||||||
|
expect(
|
||||||
|
editCellClassesCallBack.calledWith(
|
||||||
|
row[columns[editingColIndex].dataField], row, rowIndex, editingColIndex)
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should also rendering EditingCell with correct class', () => {
|
||||||
|
expect(wrapper.find(EditingCell).length).toBe(1);
|
||||||
|
expect(wrapper.find(EditingCell).props().className).toEqual(customClass);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and cellEdit.ridx is not match to current row index', () => {
|
||||||
|
const editingColIndex = 1;
|
||||||
|
beforeEach(() => {
|
||||||
|
cellEdit.ridx = 3;
|
||||||
|
cellEdit.cidx = editingColIndex;
|
||||||
|
cellEdit.onUpdate = sinon.stub();
|
||||||
|
cellEdit.onEscape = sinon.stub();
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
row={ row }
|
||||||
|
rowIndex={ 1 }
|
||||||
|
columns={ columns }
|
||||||
|
keyField={ keyField }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
editable={ false }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render any EditingCell component', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
expect(wrapper.find(EditingCell).length).toBe(0);
|
||||||
|
expect(wrapper.find(Cell).length).toBe(columns.length);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -195,6 +542,348 @@ describe('Row', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('selectRow', () => {
|
||||||
|
let selectRow;
|
||||||
|
|
||||||
|
describe('when selectRow.mode is ROW_SELECT_DISABLED (row is not able to select)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render <SelectionCell />', () => {
|
||||||
|
expect(wrapper.find(SelectionCell).length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when selectRow.mode was defined (single or multiple selection)', () => {
|
||||||
|
describe('if selectRow.mode is radio (single selection)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = { mode: 'radio' };
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selected
|
||||||
|
selectable
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render <SelectionCell />', () => {
|
||||||
|
expect(wrapper.find(SelectionCell).length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render <SelectionCell /> with correct props', () => {
|
||||||
|
expect(wrapper.find(SelectionCell).props().selected).toBeTruthy();
|
||||||
|
expect(wrapper.find(SelectionCell).props().disabled).toBeFalsy();
|
||||||
|
expect(wrapper.find(SelectionCell).props().mode).toEqual(selectRow.mode);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when selectRow.hideSelectColumn is true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = { mode: 'radio', hideSelectColumn: true };
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render <SelectionCell />', () => {
|
||||||
|
expect(wrapper.find(SelectionCell).length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow.mode is checkbox (multiple selection)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = { mode: 'checkbox' };
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selected
|
||||||
|
selectable
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render <SelectionCell />', () => {
|
||||||
|
expect(wrapper.find(SelectionCell).length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render <SelectionCell /> with correct props', () => {
|
||||||
|
expect(wrapper.find(SelectionCell).props().selected).toBeTruthy();
|
||||||
|
expect(wrapper.find(SelectionCell).props().disabled).toBeFalsy();
|
||||||
|
expect(wrapper.find(SelectionCell).props().mode).toEqual(selectRow.mode);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when selectRow.hideSelectColumn is true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = { mode: 'checkbox', hideSelectColumn: true };
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render <SelectionCell />', () => {
|
||||||
|
expect(wrapper.find(SelectionCell).length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectable prop is false', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = { mode: 'checkbox' };
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
keyField={ keyField }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selectable={ false }
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render SelectionCell component with correct disable prop correctly', () => {
|
||||||
|
expect(wrapper.find(SelectionCell).length).toBe(1);
|
||||||
|
expect(wrapper.find(SelectionCell).prop('disabled')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectable prop is true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = { mode: 'checkbox' };
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
keyField={ keyField }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selectable
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render SelectionCell component with correct disable prop correctly', () => {
|
||||||
|
expect(wrapper.find(SelectionCell).length).toBe(1);
|
||||||
|
expect(wrapper.find(SelectionCell).prop('disabled')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow.clickToSelect is true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
selectRow = { mode: 'checkbox' };
|
||||||
|
selectRow.clickToSelect = true;
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selected
|
||||||
|
selectable
|
||||||
|
/>);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render Row component successfully with onClick event', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
expect(wrapper.find('tr').prop('onClick')).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleRowClick', () => {
|
||||||
|
let selectRow;
|
||||||
|
let onRowSelectCallBack;
|
||||||
|
|
||||||
|
describe('selectable prop is false', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
onRowSelectCallBack = sinon.stub();
|
||||||
|
selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true,
|
||||||
|
onRowSelect: onRowSelectCallBack
|
||||||
|
};
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selected
|
||||||
|
selectable={ false }
|
||||||
|
/>);
|
||||||
|
wrapper.find('tr').simulate('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not calling selectRow.onRowSelect callback', () => {
|
||||||
|
expect(onRowSelectCallBack.callCount).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('selectable prop is true', () => {
|
||||||
|
describe('and selected prop is true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
onRowSelectCallBack = sinon.stub();
|
||||||
|
selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true,
|
||||||
|
onRowSelect: onRowSelectCallBack
|
||||||
|
};
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
keyField={ keyField }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selected
|
||||||
|
selectable
|
||||||
|
/>);
|
||||||
|
wrapper.find('tr').simulate('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling selectRow.onRowSelect callback', () => {
|
||||||
|
expect(onRowSelectCallBack.callCount).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling selectRow.onRowSelect with correct argument', () => {
|
||||||
|
expect(onRowSelectCallBack.calledWith(row[keyField], false, rowIndex)).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and selected prop is false', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
onRowSelectCallBack = sinon.stub();
|
||||||
|
selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true,
|
||||||
|
onRowSelect: onRowSelectCallBack
|
||||||
|
};
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
keyField={ keyField }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
selected={ false }
|
||||||
|
selectable
|
||||||
|
/>);
|
||||||
|
wrapper.find('tr').simulate('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling selectRow.onRowSelect callback', () => {
|
||||||
|
expect(onRowSelectCallBack.callCount).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling selectRow.onRowSelect with correct argument', () => {
|
||||||
|
expect(onRowSelectCallBack.calledWith(row[keyField], true, rowIndex)).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if cellEdit.mode is dbclick and selectRow.clickToEdit is true', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
onRowSelectCallBack = sinon.stub();
|
||||||
|
const cellEdit = {
|
||||||
|
mode: Const.DBCLICK_TO_CELL_EDIT,
|
||||||
|
ridx: undefined,
|
||||||
|
cidx: undefined,
|
||||||
|
onStart: sinon.stub()
|
||||||
|
};
|
||||||
|
selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true,
|
||||||
|
clickToEdit: true,
|
||||||
|
onRowSelect: onRowSelectCallBack
|
||||||
|
};
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
keyField={ keyField }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
selected
|
||||||
|
selectable
|
||||||
|
/>);
|
||||||
|
// console.log(wrapper.instance());
|
||||||
|
const rowClick = wrapper.instance().createClickEventHandler();
|
||||||
|
rowClick();
|
||||||
|
rowClick();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should increase clickNum as 2', () => {
|
||||||
|
expect(wrapper.instance().clickNum).toEqual(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when attrs.onClick prop is defined', () => {
|
||||||
|
const customClickCallBack = sinon.stub();
|
||||||
|
const attrs = { onClick: customClickCallBack };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
onRowSelectCallBack = sinon.stub();
|
||||||
|
selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true,
|
||||||
|
onRowSelect: onRowSelectCallBack
|
||||||
|
};
|
||||||
|
wrapper = shallow(
|
||||||
|
<Row
|
||||||
|
{ ...mockBodyResolvedProps }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columns={ defaultColumns }
|
||||||
|
row={ row }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
attrs={ attrs }
|
||||||
|
selected
|
||||||
|
selectable
|
||||||
|
/>);
|
||||||
|
wrapper.find('tr').simulate('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling attrs.onClick callback', () => {
|
||||||
|
expect(customClickCallBack.callCount).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calling selectRow.onRowSelect callback', () => {
|
||||||
|
expect(onRowSelectCallBack.callCount).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('when column.style prop is defined', () => {
|
describe('when column.style prop is defined', () => {
|
||||||
let columns;
|
let columns;
|
||||||
const columnIndex = 1;
|
const columnIndex = 1;
|
||||||
|
|||||||
@@ -1,25 +1,16 @@
|
|||||||
import Const from '../../../src/const';
|
import Const from '../../../src/const';
|
||||||
|
|
||||||
const { ROW_SELECT_DISABLED } = Const;
|
const { ROW_SELECT_DISABLED, UNABLE_TO_CELL_EDIT } = Const;
|
||||||
|
|
||||||
export const rowSelectionResolvedProps = {
|
export const rowSelectionResolvedProps = {
|
||||||
mode: ROW_SELECT_DISABLED,
|
mode: ROW_SELECT_DISABLED
|
||||||
selected: [],
|
|
||||||
hideSelectColumn: true
|
|
||||||
};
|
|
||||||
|
|
||||||
export const expandRowResolvedProps = {
|
|
||||||
renderer: undefined,
|
|
||||||
expanded: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const cellEditResolvedProps = {
|
export const cellEditResolvedProps = {
|
||||||
mode: null,
|
mode: UNABLE_TO_CELL_EDIT
|
||||||
nonEditableRows: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
cellEdit: cellEditResolvedProps,
|
cellEdit: cellEditResolvedProps,
|
||||||
expandRow: expandRowResolvedProps,
|
|
||||||
selectRow: rowSelectionResolvedProps
|
selectRow: rowSelectionResolvedProps
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,17 +3,9 @@ import Const from '../../../src/const';
|
|||||||
const { ROW_SELECT_DISABLED } = Const;
|
const { ROW_SELECT_DISABLED } = Const;
|
||||||
|
|
||||||
export const rowSelectionResolvedProps = {
|
export const rowSelectionResolvedProps = {
|
||||||
mode: ROW_SELECT_DISABLED,
|
mode: ROW_SELECT_DISABLED
|
||||||
selected: [],
|
|
||||||
hideSelectColumn: true
|
|
||||||
};
|
|
||||||
|
|
||||||
export const expandRowResolvedProps = {
|
|
||||||
renderer: undefined,
|
|
||||||
expanded: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
selectRow: rowSelectionResolvedProps,
|
selectRow: rowSelectionResolvedProps
|
||||||
expandRow: expandRowResolvedProps
|
|
||||||
};
|
};
|
||||||
|
|||||||
91
yarn.lock
91
yarn.lock
@@ -332,14 +332,6 @@ array-unique@^0.3.2:
|
|||||||
version "0.3.2"
|
version "0.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
|
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
|
||||||
|
|
||||||
array.prototype.flat@^1.2.1:
|
|
||||||
version "1.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.1.tgz#812db8f02cad24d3fab65dd67eabe3b8903494a4"
|
|
||||||
dependencies:
|
|
||||||
define-properties "^1.1.2"
|
|
||||||
es-abstract "^1.10.0"
|
|
||||||
function-bind "^1.1.1"
|
|
||||||
|
|
||||||
arrify@^1.0.0, arrify@^1.0.1:
|
arrify@^1.0.0, arrify@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
|
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
|
||||||
@@ -2700,26 +2692,24 @@ entities@^1.1.1, entities@~1.1.1:
|
|||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
|
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
|
||||||
|
|
||||||
enzyme-adapter-react-16.3@1.0.0:
|
enzyme-adapter-react-16@1.1.1:
|
||||||
version "1.0.0"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16.3/-/enzyme-adapter-react-16.3-1.0.0.tgz#d3992301aba46c8cceab21c1d201e85f01c93bfc"
|
resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.1.1.tgz#a8f4278b47e082fbca14f5bfb1ee50ee650717b4"
|
||||||
dependencies:
|
dependencies:
|
||||||
enzyme-adapter-utils "^1.5.0"
|
enzyme-adapter-utils "^1.3.0"
|
||||||
function.prototype.name "^1.1.0"
|
lodash "^4.17.4"
|
||||||
object.assign "^4.1.0"
|
object.assign "^4.0.4"
|
||||||
object.values "^1.0.4"
|
object.values "^1.0.4"
|
||||||
prop-types "^15.6.2"
|
prop-types "^15.6.0"
|
||||||
react-is "^16.4.1"
|
|
||||||
react-reconciler "^0.7.0"
|
react-reconciler "^0.7.0"
|
||||||
react-test-renderer "~16.3.0-0"
|
react-test-renderer "^16.0.0-0"
|
||||||
|
|
||||||
enzyme-adapter-utils@^1.5.0:
|
enzyme-adapter-utils@^1.3.0:
|
||||||
version "1.5.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.5.0.tgz#a020ab3ae79bb1c85e1d51f48f35e995e0eed810"
|
resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.4.0.tgz#c403b81e8eb9953658569e539780964bdc98de62"
|
||||||
dependencies:
|
dependencies:
|
||||||
function.prototype.name "^1.1.0"
|
|
||||||
object.assign "^4.1.0"
|
object.assign "^4.1.0"
|
||||||
prop-types "^15.6.2"
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
enzyme-to-json@3.3.4:
|
enzyme-to-json@3.3.4:
|
||||||
version "3.3.4"
|
version "3.3.4"
|
||||||
@@ -2727,21 +2717,20 @@ enzyme-to-json@3.3.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lodash "^4.17.4"
|
lodash "^4.17.4"
|
||||||
|
|
||||||
enzyme@3.4.0:
|
enzyme@3.3.0:
|
||||||
version "3.4.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.4.0.tgz#085c66fe647d8c9c4becd1fee3042c040cda88a6"
|
resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.3.0.tgz#0971abd167f2d4bf3f5bd508229e1c4b6dc50479"
|
||||||
dependencies:
|
dependencies:
|
||||||
array.prototype.flat "^1.2.1"
|
|
||||||
cheerio "^1.0.0-rc.2"
|
cheerio "^1.0.0-rc.2"
|
||||||
function.prototype.name "^1.1.0"
|
function.prototype.name "^1.0.3"
|
||||||
has "^1.0.3"
|
has "^1.0.1"
|
||||||
is-boolean-object "^1.0.0"
|
is-boolean-object "^1.0.0"
|
||||||
is-callable "^1.1.4"
|
is-callable "^1.1.3"
|
||||||
is-number-object "^1.0.3"
|
is-number-object "^1.0.3"
|
||||||
is-string "^1.0.4"
|
is-string "^1.0.4"
|
||||||
is-subset "^0.1.1"
|
is-subset "^0.1.1"
|
||||||
lodash "^4.17.4"
|
lodash "^4.17.4"
|
||||||
object-inspect "^1.6.0"
|
object-inspect "^1.5.0"
|
||||||
object-is "^1.0.1"
|
object-is "^1.0.1"
|
||||||
object.assign "^4.1.0"
|
object.assign "^4.1.0"
|
||||||
object.entries "^1.0.4"
|
object.entries "^1.0.4"
|
||||||
@@ -2761,16 +2750,6 @@ error-ex@^1.2.0, error-ex@^1.3.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-arrayish "^0.2.1"
|
is-arrayish "^0.2.1"
|
||||||
|
|
||||||
es-abstract@^1.10.0:
|
|
||||||
version "1.12.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
|
|
||||||
dependencies:
|
|
||||||
es-to-primitive "^1.1.1"
|
|
||||||
function-bind "^1.1.1"
|
|
||||||
has "^1.0.1"
|
|
||||||
is-callable "^1.1.3"
|
|
||||||
is-regex "^1.0.4"
|
|
||||||
|
|
||||||
es-abstract@^1.6.1, es-abstract@^1.7.0:
|
es-abstract@^1.6.1, es-abstract@^1.7.0:
|
||||||
version "1.10.0"
|
version "1.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
|
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
|
||||||
@@ -3520,7 +3499,7 @@ function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
|
|||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||||
|
|
||||||
function.prototype.name@^1.1.0:
|
function.prototype.name@^1.0.3:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
|
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3994,12 +3973,6 @@ has@^1.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
function-bind "^1.0.2"
|
function-bind "^1.0.2"
|
||||||
|
|
||||||
has@^1.0.3:
|
|
||||||
version "1.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
|
||||||
dependencies:
|
|
||||||
function-bind "^1.1.1"
|
|
||||||
|
|
||||||
hash-base@^2.0.0:
|
hash-base@^2.0.0:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1"
|
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1"
|
||||||
@@ -4350,10 +4323,6 @@ is-callable@^1.1.1, is-callable@^1.1.3:
|
|||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
|
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
|
||||||
|
|
||||||
is-callable@^1.1.4:
|
|
||||||
version "1.1.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
|
|
||||||
|
|
||||||
is-ci@^1.0.10:
|
is-ci@^1.0.10:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5"
|
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5"
|
||||||
@@ -6033,7 +6002,7 @@ object-hash@^1.1.4:
|
|||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.2.0.tgz#e96af0e96981996a1d47f88ead8f74f1ebc4422b"
|
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.2.0.tgz#e96af0e96981996a1d47f88ead8f74f1ebc4422b"
|
||||||
|
|
||||||
object-inspect@^1.6.0:
|
object-inspect@^1.5.0:
|
||||||
version "1.6.0"
|
version "1.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
|
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
|
||||||
|
|
||||||
@@ -6792,13 +6761,6 @@ prop-types@^15.6.0:
|
|||||||
loose-envify "^1.3.1"
|
loose-envify "^1.3.1"
|
||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
|
|
||||||
prop-types@^15.6.2:
|
|
||||||
version "15.6.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
|
|
||||||
dependencies:
|
|
||||||
loose-envify "^1.3.1"
|
|
||||||
object-assign "^4.1.1"
|
|
||||||
|
|
||||||
proxy-addr@~2.0.2:
|
proxy-addr@~2.0.2:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
|
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
|
||||||
@@ -6967,10 +6929,6 @@ react-dom@16.3.2:
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
prop-types "^15.6.0"
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
react-is@^16.3.2, react-is@^16.4.1:
|
|
||||||
version "16.4.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.2.tgz#84891b56c2b6d9efdee577cc83501dfc5ecead88"
|
|
||||||
|
|
||||||
react-reconciler@^0.7.0:
|
react-reconciler@^0.7.0:
|
||||||
version "0.7.0"
|
version "0.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.7.0.tgz#9614894103e5f138deeeb5eabaf3ee80eb1d026d"
|
resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.7.0.tgz#9614894103e5f138deeeb5eabaf3ee80eb1d026d"
|
||||||
@@ -6987,14 +6945,13 @@ react-test-renderer@16.0.0:
|
|||||||
fbjs "^0.8.16"
|
fbjs "^0.8.16"
|
||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
|
|
||||||
react-test-renderer@~16.3.0-0:
|
react-test-renderer@^16.0.0-0:
|
||||||
version "16.3.2"
|
version "16.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.3.2.tgz#3d1ed74fda8db42521fdf03328e933312214749a"
|
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.2.0.tgz#bddf259a6b8fcd8555f012afc8eacc238872a211"
|
||||||
dependencies:
|
dependencies:
|
||||||
fbjs "^0.8.16"
|
fbjs "^0.8.16"
|
||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
prop-types "^15.6.0"
|
prop-types "^15.6.0"
|
||||||
react-is "^16.3.2"
|
|
||||||
|
|
||||||
react@16.3.2:
|
react@16.3.2:
|
||||||
version "16.3.2"
|
version "16.3.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user