refine expand row consumer

This commit is contained in:
AllenFang 2018-08-18 17:50:36 +08:00
parent 9d4acaedd1
commit 7f7deff37f
9 changed files with 181 additions and 162 deletions

View File

@ -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 ?
<RowComponent
(<RowComponent
key={ key }
row={ row }
keyField={ keyField }
@ -70,10 +70,10 @@ const Body = (props) => {
className={ classes }
attrs={ attrs }
cellEdit={ cellEdit }
selectRowEnabled={ selectRowEnabled }
expandRowEnabled={ expandRowEnabled }
/> :
<RowComponent
selectRow={ selectRow }
expandRow={ expandRow }
/>) :
(<RowComponent
key={ key }
row={ row }
keyField={ keyField }
@ -84,19 +84,7 @@ const Body = (props) => {
style={ style }
className={ classes }
attrs={ attrs }
/>
];
if (expanded) {
result.push((
<ExpandRow
key={ `${key}-expanding` }
colSpan={ visibleColumnSize }
>
{ expandRow.renderer(row) }
</ExpandRow>
));
}
/>);
return result;
});

View File

@ -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: []
}
};

View File

@ -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
) => (
<Base
{ ...this.props }
@ -71,7 +70,6 @@ const withContext = Base =>
{ ...filterProps }
{ ...searchProps }
{ ...paginationProps }
{ ...expandProps }
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
/>
);
@ -84,8 +82,7 @@ const withContext = Base =>
filterProps,
searchProps,
sortProps,
paginationProps,
expandProps
paginationProps
) => (
<this.SelectionContext.Provider
{ ...baseProps }
@ -99,8 +96,7 @@ const withContext = Base =>
filterProps,
searchProps,
sortProps,
paginationProps,
expandProps
paginationProps
)
}
</this.SelectionContext.Provider>
@ -121,19 +117,16 @@ const withContext = Base =>
expandRow={ this.props.expandRow }
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
>
<this.RowExpandContext.Consumer>
{
expandProps => base(
rootProps,
cellEditProps,
filterProps,
searchProps,
sortProps,
paginationProps,
expandProps
)
}
</this.RowExpandContext.Consumer>
{
base(
rootProps,
cellEditProps,
filterProps,
searchProps,
sortProps,
paginationProps
)
}
</this.RowExpandContext.Provider>
);
}

View File

@ -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 (
<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>
);
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 (
<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 {
Provider: RowExpandProvider,
Consumer: RowExpandContext.Consumer
};

View File

@ -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 (
<thead>
<tr className={ className }>
<ExpansionHeaderCellComp />
{
(expandRow && expandRow.showExpandColumn)
? <ExpandHeaderCell
onAllRowExpand={ expandRow.onAllRowExpand }
anyExpands={ expandRow.isAnyExpands }
renderer={ expandRow.expandHeaderColumnRenderer }
/> : null
}
{
(selectRow.mode !== ROW_SELECT_DISABLED && !selectRow.hideSelectColumn) ?
!selectRow.hideSelectColumn ?
<SelectionHeaderCellComp /> : null
}
{

View File

@ -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);
}

View File

@ -0,0 +1,8 @@
import React from 'react';
import ExpansionContext from '../contexts/row-expand-context';
export default Component => () => (
<ExpansionContext.Consumer>
{ expandRow => <Component { ...expandRow } /> }
</ExpansionContext.Consumer>
);

View File

@ -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 (
<th data-row-selection { ...attrs }>
{
renderer ?
renderer({ isAnyExpands: anyExpands }) :
(anyExpands ? '(-)' : '(+)')
expandHeaderColumnRenderer ?
expandHeaderColumnRenderer({ isAnyExpands }) :
(isAnyExpands ? '(-)' : '(+)')
}
</th>
);

View File

@ -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 [
<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>
);
};