diff --git a/packages/react-bootstrap-table2-example/examples/basic/large-table.js b/packages/react-bootstrap-table2-example/examples/basic/large-table.js index f25beae..a4138bb 100644 --- a/packages/react-bootstrap-table2-example/examples/basic/large-table.js +++ b/packages/react-bootstrap-table2-example/examples/basic/large-table.js @@ -1,10 +1,10 @@ import React from 'react'; 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'; -const products = productsGenerator(5); +const products = productsGenerator(2000); const columns = [{ dataField: 'id', @@ -17,15 +17,41 @@ const columns = [{ text: 'Product Price' }]; -export default () => ( -
- -
-); +// cellEdit={ cellEditFactory({ +// mode: 'click' +// }) } + +// const expandRow = { +// renderer: row => ( +//
+//

{ `This Expand row is belong to rowKey ${row.id}` }

+//

You can render anything here, also you can add additional data on every row object

+//

expandRow.renderer callback will pass the origin row object to you

+//
+// ) +// }; + +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 ( +
+ +
+ ); + } +} diff --git a/packages/react-bootstrap-table2/src/body.js b/packages/react-bootstrap-table2/src/body.js index 8c83eaa..a66d3bf 100644 --- a/packages/react-bootstrap-table2/src/body.js +++ b/packages/react-bootstrap-table2/src/body.js @@ -5,7 +5,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import _ from './utils'; -import Row from './row'; +import Row from './simple-row'; import RowAggregator from './row-aggregator'; import RowSection from './row-section'; import Const from './const'; @@ -18,6 +18,7 @@ class Body extends React.Component { if (props.cellEdit.createContext) { this.EditingCell = props.cellEdit.createEditingCell(_, props.cellEdit.options.onStartEdit); } + this.RowComponent = bindSelection(RowAggregator); } render() { @@ -54,9 +55,9 @@ class Body extends React.Component { RowComponent = bindExpansion(RowAggregator, visibleColumnSize); } - if (selectRowEnabled) { - RowComponent = bindSelection(expandRowEnabled ? RowComponent : RowAggregator); - } + // if (selectRowEnabled) { + // RowComponent = bindSelection(expandRowEnabled ? RowComponent : RowAggregator); + // } if (cellEdit.createContext) { RowComponent = cellEdit.bindRowLevelCellEdit(RowComponent, selectRowEnabled, keyField, _); @@ -85,7 +86,7 @@ class Body extends React.Component { baseRowProps.style = _.isFunction(rowStyle) ? rowStyle(row, index) : rowStyle; baseRowProps.className = (_.isFunction(rowClasses) ? rowClasses(row, index) : rowClasses); - return ; + return ; }); } diff --git a/packages/react-bootstrap-table2/src/cell.js b/packages/react-bootstrap-table2/src/cell.js index e6f2149..a799024 100644 --- a/packages/react-bootstrap-table2/src/cell.js +++ b/packages/react-bootstrap-table2/src/cell.js @@ -73,7 +73,10 @@ class Cell extends Component { formatExtraData } = column; const attrs = { ...rest }; - let content = column.isDummyField ? null : _.get(row, dataField); + let content = this.props.children; + if (!content) { + content = column.isDummyField ? null : _.get(row, dataField); + } if (formatter) { content = column.formatter(content, row, rowIndex, formatExtraData); diff --git a/packages/react-bootstrap-table2/src/row-aggregator-content.js b/packages/react-bootstrap-table2/src/row-aggregator-content.js new file mode 100644 index 0000000..0b3321d --- /dev/null +++ b/packages/react-bootstrap-table2/src/row-aggregator-content.js @@ -0,0 +1,48 @@ +/* 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 ( + + { this.props.children } + + + ); + } +} + +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; diff --git a/packages/react-bootstrap-table2/src/row-aggregator.js b/packages/react-bootstrap-table2/src/row-aggregator.js index f9438b3..86e6f11 100644 --- a/packages/react-bootstrap-table2/src/row-aggregator.js +++ b/packages/react-bootstrap-table2/src/row-aggregator.js @@ -3,34 +3,45 @@ import React from 'react'; import PropTypes from 'prop-types'; import _ from './utils'; -import Row from './row'; +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 shouldRowUpdater from './row-should-updater'; +// import Cell from './cell'; +import eventDelegater from './row-event-delegater'; -export default class RowAggregator extends shouldRowUpdater(React.Component) { +export default class RowAggregator extends shouldRowUpdater(eventDelegater(React.Component)) { static propTypes = { - attrs: PropTypes.object + attrs: PropTypes.object, + style: PropTypes.object } static defaultProps = { - attrs: {} + attrs: {}, + style: {} } constructor(props) { super(props); this.clickNum = 0; + this.shouldUpdateRowContent = false; this.createClickEventHandler = this.createClickEventHandler.bind(this); } shouldComponentUpdate(nextProps) { - const shouldUpdate = + if ( this.props.selected !== nextProps.selected || this.props.expanded !== nextProps.expanded || this.props.selectable !== nextProps.selectable || this.shouldUpdateByWhenEditing(nextProps) || - this.shouldUpdatedByNormalProps(nextProps); + this.shouldUpdatedBySelfProps(nextProps) + ) { + this.shouldUpdateRowContent = this.shouldUpdatedByNormalProps(nextProps); + return true; + } + this.shouldUpdateRowContent = this.shouldUpdatedByNormalProps(nextProps); - return shouldUpdate; + return this.shouldUpdateRowContent; } createClickEventHandler(cb) { @@ -91,53 +102,77 @@ export default class RowAggregator extends shouldRowUpdater(React.Component) { selectable, ...rest } = this.props; - const key = _.get(row, keyField); const { hideSelectColumn, clickToSelect } = selectRow; const { showExpandColumn } = expandRow; - const newAttrs = { ...attrs }; + const newAttrs = this.delegate({ ...attrs }); if (clickToSelect || !!expandRow.renderer) { - newAttrs.onClick = this.createClickEventHandler(attrs.onClick); + newAttrs.onClick = this.createClickEventHandler(newAttrs.onClick); } return ( - - { - showExpandColumn ? ( - - ) : null - } - { - !hideSelectColumn - ? ( - - ) - : null - } - + 123 + 12121212 + ); + // const content0 = _.get(row, columns[1].dataField); + // const content1 = _.get(row, columns[1].dataField); + // const content2 = _.get(row, columns[2].dataField); + // return ( + // selectRow.onRowSelect(key, !selected, rowIndex, e) } + // > + // 1 + // 2 + // 3 + // 4 + // + // ); + + // const newCols = [{ fake: true }, ...columns]; + + // return ( + // + // { + // newCols.map((column, i) => { + // if (column.fake) { + // return ( + // + // + // + // ); + // } + // const content = _.get(row, column.dataField); + // return ( + // + // ); + // }) + // } + // + // ); } } diff --git a/packages/react-bootstrap-table2/src/row-pure-content.js b/packages/react-bootstrap-table2/src/row-pure-content.js new file mode 100644 index 0000000..0cb6a17 --- /dev/null +++ b/packages/react-bootstrap-table2/src/row-pure-content.js @@ -0,0 +1,113 @@ +/* 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 ( + + ); + } + // 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 ( + + ); + } + return false; + }); + } +} diff --git a/packages/react-bootstrap-table2/src/row-selection/row-binder.js b/packages/react-bootstrap-table2/src/row-selection/row-binder.js index 27982a0..8b8152d 100644 --- a/packages/react-bootstrap-table2/src/row-selection/row-binder.js +++ b/packages/react-bootstrap-table2/src/row-selection/row-binder.js @@ -43,15 +43,20 @@ export default (Component) => { { ...props } style={ style } className={ className } - selectRow={ { ...selectRow } } + selectRow={ selectRow } selected={ selected } selectable={ selectable } /> ); }; - return props => ( - - { selectRow => renderWithSelection(props, selectRow) } - - ); + function withSelectionConsumer(props) { + return ( + + { selectRow => renderWithSelection(props, selectRow) } + + ); + } + + withSelectionConsumer.displayName = 'WithSelectionConsumer'; + return withSelectionConsumer; }; diff --git a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js index 8d46da1..fc63c53 100644 --- a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js +++ b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js @@ -19,17 +19,17 @@ export default class SelectionCell extends Component { selectionRenderer: PropTypes.func } - constructor() { - super(); + constructor(props) { + super(props); this.handleClick = this.handleClick.bind(this); } shouldComponentUpdate(nextProps) { const shouldUpdate = - this.props.rowIndex !== nextProps.rowIndex || this.props.selected !== nextProps.selected || - this.props.disabled !== nextProps.disabled || - this.props.rowKey !== nextProps.rowKey; + this.props.rowKey !== nextProps.rowKey || + this.props.rowIndex !== nextProps.rowIndex || + this.props.disabled !== nextProps.disabled; return shouldUpdate; } diff --git a/packages/react-bootstrap-table2/src/row-should-updater.js b/packages/react-bootstrap-table2/src/row-should-updater.js index 17c9947..5f343bc 100644 --- a/packages/react-bootstrap-table2/src/row-should-updater.js +++ b/packages/react-bootstrap-table2/src/row-should-updater.js @@ -11,14 +11,20 @@ export default ExtendBase => ); } + 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.className !== nextProps.className || this.props.editable !== nextProps.editable || this.props.columns.length !== nextProps.columns.length || - !_.isEqual(this.props.row, nextProps.row) || - !_.isEqual(this.props.style, nextProps.style); + !_.isEqual(this.props.row, nextProps.row); return shouldUpdate; } diff --git a/packages/react-bootstrap-table2/src/row.js b/packages/react-bootstrap-table2/src/row.js deleted file mode 100644 index f04caed..0000000 --- a/packages/react-bootstrap-table2/src/row.js +++ /dev/null @@ -1,146 +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 _ from './utils'; -import Cell from './cell'; -import eventDelegater from './row-event-delegater'; -import shouldRowUpdater from './row-should-updater'; - -class Row extends shouldRowUpdater(eventDelegater(Component)) { - shouldComponentUpdate(nextProps) { - console.log('lol'); - const shouldUpdate = - nextProps.shouldUpdate || - this.shouldUpdateByWhenEditing(nextProps) || - this.shouldUpdatedByNormalProps(nextProps); - - return shouldUpdate; - } - - render() { - const { - row, - keyField, - columns, - rowIndex, - className, - style, - attrs, - editable, - editingRowIdx, - editingColIdx, - onStart, - clickToEdit, - dbclickToEdit - } = this.props; - const trAttrs = this.delegate(attrs); - - return ( - - { this.props.children } - { - columns.map((column, index) => { - if (!column.hidden) { - const { dataField } = column; - const content = _.get(row, dataField); - if (rowIndex === editingRowIdx && index === editingColIdx) { - const EditingCell = this.props.EditingCellComponent; - return ( - - ); - } - // 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 ( - - ); - } - return false; - }) - } - - ); - } -} - -Row.propTypes = { - row: PropTypes.object.isRequired, - rowIndex: PropTypes.number.isRequired, - columns: PropTypes.array.isRequired, - style: PropTypes.object, - className: PropTypes.string, - attrs: PropTypes.object, - shouldUpdate: PropTypes.bool -}; - -Row.defaultProps = { - editable: true, - style: {}, - className: null, - attrs: {}, - shouldUpdate: false -}; - -export default Row; diff --git a/packages/react-bootstrap-table2/src/simple-row.js b/packages/react-bootstrap-table2/src/simple-row.js new file mode 100644 index 0000000..b584f74 --- /dev/null +++ b/packages/react-bootstrap-table2/src/simple-row.js @@ -0,0 +1,56 @@ +/* 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 ( + + + + ); + } +} + +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;