diff --git a/packages/react-bootstrap-table2/src/body.js b/packages/react-bootstrap-table2/src/body.js index eb4138a..4da1be7 100644 --- a/packages/react-bootstrap-table2/src/body.js +++ b/packages/react-bootstrap-table2/src/body.js @@ -7,10 +7,10 @@ import PropTypes from 'prop-types'; import _ from './utils'; import Row from './row'; import RowAggregator from './row-aggregator'; -import ExpandRow from './row-expand/expand-row'; import RowSection from './row-section'; import Const from './const'; import bindSelection from './row-selection/row-binder'; +import bindExpansion from './row-expand/row-binder'; const Body = (props) => { const { @@ -40,10 +40,13 @@ const Body = (props) => { let RowComponent = Row; const nonEditableRows = cellEdit.nonEditableRows || []; const selectRowEnabled = selectRow.mode !== Const.ROW_SELECT_DISABLED; - const expandRowEnabled = !!expandRow; + const expandRowEnabled = !!expandRow.renderer; + if (expandRowEnabled) { + RowComponent = bindExpansion(RowAggregator, visibleColumnSize); + } if (selectRowEnabled) { - RowComponent = bindSelection(RowAggregator); + RowComponent = bindSelection(expandRowEnabled ? RowComponent : RowAggregator); } content = data.map((row, index) => { @@ -55,12 +58,9 @@ const Body = (props) => { const classes = (_.isFunction(rowClasses) ? rowClasses(row, index) : rowClasses); // refine later - const expanded = expandRowEnabled && expandRow.expanded.includes(key); - - // refine later - const result = [ + const result = selectRowEnabled || expandRowEnabled ? - { className={ classes } attrs={ attrs } cellEdit={ cellEdit } - selectRowEnabled={ selectRowEnabled } - expandRowEnabled={ expandRowEnabled } - /> : - ) : + ( { style={ style } className={ classes } attrs={ attrs } - /> - ]; - - if (expanded) { - result.push(( - - { expandRow.renderer(row) } - - )); - } + />); return result; }); diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js index 1fd09b6..53ee947 100644 --- a/packages/react-bootstrap-table2/src/bootstrap-table.js +++ b/packages/react-bootstrap-table2/src/bootstrap-table.js @@ -147,7 +147,7 @@ BootstrapTable.propTypes = { selectionHeaderRenderer: PropTypes.func }), expandRow: PropTypes.shape({ - renderer: PropTypes.func.isRequired, + renderer: PropTypes.func, expanded: PropTypes.array, onExpand: PropTypes.func, onExpandAll: PropTypes.func, @@ -156,9 +156,6 @@ BootstrapTable.propTypes = { expandColumnRenderer: PropTypes.func, expandHeaderColumnRenderer: PropTypes.func }), - onRowExpand: PropTypes.func, - onAllRowExpand: PropTypes.func, - isAnyExpands: PropTypes.bool, rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]), rowEvents: PropTypes.object, rowClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), @@ -191,7 +188,12 @@ BootstrapTable.defaultProps = { noDataIndication: null, selectRow: { mode: Const.ROW_SELECT_DISABLED, - selected: [] + selected: [], + hideSelectColumn: true + }, + expandRow: { + renderer: undefined, + expanded: [] } }; diff --git a/packages/react-bootstrap-table2/src/contexts/index.js b/packages/react-bootstrap-table2/src/contexts/index.js index 08942d0..ae2046a 100644 --- a/packages/react-bootstrap-table2/src/contexts/index.js +++ b/packages/react-bootstrap-table2/src/contexts/index.js @@ -5,7 +5,7 @@ import _ from '../utils'; import createDataContext from './data-context'; import createSortContext from './sort-context'; import SelectionContext from './selection-context'; -import createRowExpandContext from './row-expand-context'; +import RowExpandContext from './row-expand-context'; import remoteResolver from '../props-resolver/remote-resolver'; import { BootstrapContext } from './bootstrap'; import dataOperator from '../store/operators'; @@ -26,7 +26,7 @@ const withContext = Base => } if (props.expandRow) { - this.RowExpandContext = createRowExpandContext(dataOperator); + this.RowExpandContext = RowExpandContext; } if (props.cellEdit && props.cellEdit.createContext) { @@ -62,7 +62,6 @@ const withContext = Base => searchProps, sortProps, paginationProps, - expandProps ) => ( { ...filterProps } { ...searchProps } { ...paginationProps } - { ...expandProps } data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) } /> ); @@ -84,8 +82,7 @@ const withContext = Base => filterProps, searchProps, sortProps, - paginationProps, - expandProps + paginationProps ) => ( filterProps, searchProps, sortProps, - paginationProps, - expandProps + paginationProps ) } @@ -121,19 +117,16 @@ const withContext = Base => expandRow={ this.props.expandRow } data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) } > - - { - expandProps => base( - rootProps, - cellEditProps, - filterProps, - searchProps, - sortProps, - paginationProps, - expandProps - ) - } - + { + base( + rootProps, + cellEditProps, + filterProps, + searchProps, + sortProps, + paginationProps + ) + } ); } diff --git a/packages/react-bootstrap-table2/src/contexts/row-expand-context.js b/packages/react-bootstrap-table2/src/contexts/row-expand-context.js index d6b1702..94e1a03 100644 --- a/packages/react-bootstrap-table2/src/contexts/row-expand-context.js +++ b/packages/react-bootstrap-table2/src/contexts/row-expand-context.js @@ -1,91 +1,90 @@ /* eslint react/prop-types: 0 */ import React from 'react'; import PropTypes from 'prop-types'; +import dataOperator from '../store/operators'; -export default ( - dataOperator -) => { - const RowExpandContext = React.createContext(); +const RowExpandContext = React.createContext(); - class RowExpandProvider extends React.Component { - static propTypes = { - children: PropTypes.node.isRequired, - data: PropTypes.array.isRequired, - keyField: PropTypes.string.isRequired - } +class RowExpandProvider extends React.Component { + static propTypes = { + children: PropTypes.node.isRequired, + data: PropTypes.array.isRequired, + keyField: PropTypes.string.isRequired + } - state = { expanded: this.props.expandRow.expanded || [] }; + 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) { - const row = dataOperator.getRowByRowId(data, keyField, rowKey); - onExpand(row, expanded, rowIndex, e); - } - this.setState(() => ({ expanded: currExpanded })); - } - - handleAllRowExpand = (e, expandAll) => { - const { - data, - keyField, - 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) { - onExpandAll(expandAll, dataOperator.getExpandedRows(data, keyField, currExpanded), e); - } - - this.setState(() => ({ expanded: currExpanded })); - } - - render() { - const { data, keyField } = this.props; - return ( - - { this.props.children } - - ); + componentWillReceiveProps(nextProps) { + if (nextProps.expandRow) { + this.setState(() => ({ + expanded: nextProps.expandRow.expanded || this.state.expanded + })); } } - return { - Provider: RowExpandProvider, - Consumer: RowExpandContext.Consumer - }; + + 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) { + const row = dataOperator.getRowByRowId(data, keyField, rowKey); + onExpand(row, expanded, rowIndex, e); + } + this.setState(() => ({ expanded: currExpanded })); + } + + handleAllRowExpand = (e, expandAll) => { + const { + data, + keyField, + 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) { + onExpandAll(expandAll, dataOperator.getExpandedRows(data, keyField, currExpanded), e); + } + + this.setState(() => ({ expanded: currExpanded })); + } + + render() { + const { data, keyField } = this.props; + return ( + + { this.props.children } + + ); + } +} + +export default { + Provider: RowExpandProvider, + Consumer: RowExpandContext.Consumer }; diff --git a/packages/react-bootstrap-table2/src/header.js b/packages/react-bootstrap-table2/src/header.js index 9120c77..06a38a3 100644 --- a/packages/react-bootstrap-table2/src/header.js +++ b/packages/react-bootstrap-table2/src/header.js @@ -1,16 +1,14 @@ /* eslint react/require-default-props: 0 */ import React from 'react'; import PropTypes from 'prop-types'; -import Const from './const'; import HeaderCell from './header-cell'; import SelectionHeaderCell from './row-selection/selection-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 { ROW_SELECT_DISABLED } = Const; - const { className, columns, @@ -24,7 +22,12 @@ const Header = (props) => { bootstrap4 } = props; - let SelectionHeaderCellComp = () => {}; + let SelectionHeaderCellComp = () => null; + let ExpansionHeaderCellComp = () => null; + + if (expandRow.showExpandColumn) { + ExpansionHeaderCellComp = bindExpansion(ExpandHeaderCell); + } if (selectRow) { SelectionHeaderCellComp = bindSelection(SelectionHeaderCell); @@ -33,16 +36,9 @@ const Header = (props) => { return ( + { - (expandRow && expandRow.showExpandColumn) - ? : null - } - { - (selectRow.mode !== ROW_SELECT_DISABLED && !selectRow.hideSelectColumn) ? + !selectRow.hideSelectColumn ? : null } { diff --git a/packages/react-bootstrap-table2/src/row-aggregator.js b/packages/react-bootstrap-table2/src/row-aggregator.js index fc36355..e72f6a1 100644 --- a/packages/react-bootstrap-table2/src/row-aggregator.js +++ b/packages/react-bootstrap-table2/src/row-aggregator.js @@ -48,7 +48,7 @@ export default class RowAggregator extends React.Component { if (expandRow && expandable) { expandRow.onRowExpand(key, !expanded, rowIndex, e); } - if (selectable) { + if (selectRow.clickToSelect && selectable) { selectRow.onRowSelect(key, !selected, rowIndex, e); } }; @@ -79,22 +79,20 @@ export default class RowAggregator extends React.Component { cellEdit, selectRow, expandRow, + expanded, selected, - selectable, - expandRowEnabled + selectable } = this.props; const key = _.get(row, keyField); - const { hideSelectColumn } = selectRow; - const { showExpandColumn } = expandRow || {}; + const { hideSelectColumn, clickToSelect } = selectRow; + const { showExpandColumn } = expandRow; const nonEditableRows = cellEdit.nonEditableRows || []; const editable = !(nonEditableRows.length > 0 && nonEditableRows.indexOf(key) > -1); - // const expandable = expandRowEnabled && !expandRow.nonExpandable.includes(key); - const expanded = expandRowEnabled && expandRow.expanded.includes(key); const newAttrs = { ...attrs }; - if (selectRow.clickToSelect || expandRowEnabled) { + if (clickToSelect || !!expandRow.renderer) { newAttrs.onClick = this.createClickEventHandler(attrs.onClick); } diff --git a/packages/react-bootstrap-table2/src/row-expand/expand-header-cell-binder.js b/packages/react-bootstrap-table2/src/row-expand/expand-header-cell-binder.js new file mode 100644 index 0000000..4460b44 --- /dev/null +++ b/packages/react-bootstrap-table2/src/row-expand/expand-header-cell-binder.js @@ -0,0 +1,8 @@ +import React from 'react'; +import ExpansionContext from '../contexts/row-expand-context'; + +export default Component => () => ( + + { expandRow => } + +); diff --git a/packages/react-bootstrap-table2/src/row-expand/expand-header-cell.js b/packages/react-bootstrap-table2/src/row-expand/expand-header-cell.js index 65c099b..e30fd9a 100644 --- a/packages/react-bootstrap-table2/src/row-expand/expand-header-cell.js +++ b/packages/react-bootstrap-table2/src/row-expand/expand-header-cell.js @@ -3,11 +3,11 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -export default class SelectionHeaderCell extends Component { +export default class ExpansionHeaderCell extends Component { static propTypes = { - anyExpands: PropTypes.bool.isRequired, + isAnyExpands: PropTypes.bool.isRequired, onAllRowExpand: PropTypes.func.isRequired, - renderer: PropTypes.func + expandHeaderColumnRenderer: PropTypes.func } constructor() { @@ -16,13 +16,13 @@ export default class SelectionHeaderCell extends Component { } handleCheckBoxClick(e) { - const { anyExpands, onAllRowExpand } = this.props; + const { isAnyExpands, onAllRowExpand } = this.props; - onAllRowExpand(e, !anyExpands); + onAllRowExpand(e, !isAnyExpands); } render() { - const { anyExpands, renderer } = this.props; + const { isAnyExpands, expandHeaderColumnRenderer } = this.props; const attrs = { onClick: this.handleCheckBoxClick }; @@ -30,9 +30,9 @@ export default class SelectionHeaderCell extends Component { return ( { - renderer ? - renderer({ isAnyExpands: anyExpands }) : - (anyExpands ? '(-)' : '(+)') + expandHeaderColumnRenderer ? + expandHeaderColumnRenderer({ isAnyExpands }) : + (isAnyExpands ? '(-)' : '(+)') } ); diff --git a/packages/react-bootstrap-table2/src/row-expand/row-binder.js b/packages/react-bootstrap-table2/src/row-expand/row-binder.js new file mode 100644 index 0000000..64eda2c --- /dev/null +++ b/packages/react-bootstrap-table2/src/row-expand/row-binder.js @@ -0,0 +1,35 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; +import _ from '../utils'; +import ExpandRow from './expand-row'; +import ExpansionContext from '../contexts/row-expand-context'; + +export default (Component, visibleColumnSize) => { + const renderWithExpansion = (props, expandRow) => { + const key = _.get(props.row, props.keyField); + + const expanded = expandRow.expanded.includes(key); + const expandable = !expandRow.nonExpandable || !expandRow.nonExpandable.includes(key); + + return [ + , + expanded ? + { expandRow.renderer(props.row) } + : null + ]; + }; + return props => ( + + { expandRow => renderWithExpansion(props, expandRow) } + + ); +};