implement expand row sketch

This commit is contained in:
AllenFang 2018-06-24 13:12:23 +08:00
parent 6eaffe1993
commit 35b1e37940
10 changed files with 198 additions and 16 deletions

View File

@ -7,6 +7,7 @@ import cs from 'classnames';
import _ from './utils';
import Row from './row';
import ExpandRow from './row-expand/expand-row';
import RowSection from './row-section';
import Const from './const';
@ -23,7 +24,8 @@ const Body = (props) => {
selectedRowKeys,
rowStyle,
rowClasses,
rowEvents
rowEvents,
expandRow
} = props;
const {
@ -74,8 +76,10 @@ const Body = (props) => {
}
const selectable = !nonSelectable || !nonSelectable.includes(key);
const expandable = expandRow && !expandRow.nonExpandable.includes(key);
const expanded = expandRow && expandRow.expanded.includes(key);
return (
const result = [
<Row
key={ key }
row={ row }
@ -85,13 +89,29 @@ const Body = (props) => {
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;
});
}

View File

@ -97,6 +97,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
cellEdit={ this.props.cellEdit || {} }
selectRow={ cellSelectionInfo }
selectedRowKeys={ selected }
expandRow={ this.resolveExpandRowProps() }
rowStyle={ rowStyle }
rowClasses={ rowClasses }
rowEvents={ rowEvents }
@ -145,6 +146,14 @@ BootstrapTable.propTypes = {
}),
onRowSelect: PropTypes.func,
onAllRowsSelect: PropTypes.func,
expandRow: PropTypes.shape({
renderer: PropTypes.func.isRequired,
expanded: PropTypes.array,
nonExpandable: PropTypes.array,
showExpandColumn: PropTypes.bool,
expandColumnRenderer: PropTypes.func
}),
onRowExpand: PropTypes.func,
rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
rowEvents: PropTypes.object,
rowClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

View File

@ -5,6 +5,7 @@ import _ from '../utils';
import createDataContext from './data-context';
import createSortContext from './sort-context';
import createSelectionContext from './selection-context';
import createRowExpandContext from './row-expand-context';
import remoteResolver from '../props-resolver/remote-resolver';
import dataOperator from '../store/operators';
@ -23,6 +24,10 @@ const withContext = Base =>
this.SelectionContext = createSelectionContext(dataOperator);
}
if (props.expandRow) {
this.RowExpandContext = createRowExpandContext(dataOperator);
}
if (props.cellEdit && props.cellEdit.createContext) {
this.CellEditContext = props.cellEdit.createContext(
_, dataOperator, this.isRemoteCellEdit, this.handleRemoteCellChange);
@ -52,6 +57,7 @@ const withContext = Base =>
searchProps,
sortProps,
paginationProps,
expandProps,
selectionProps
) => (
<Base
@ -62,6 +68,7 @@ const withContext = Base =>
{ ...filterProps }
{ ...searchProps }
{ ...paginationProps }
{ ...expandProps }
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
/>
);
@ -74,7 +81,8 @@ const withContext = Base =>
filterProps,
searchProps,
sortProps,
paginationProps
paginationProps,
expandProps
) => (
<this.SelectionContext.Provider
{ ...baseProps }
@ -90,6 +98,7 @@ const withContext = Base =>
searchProps,
sortProps,
paginationProps,
expandProps,
selectionProps
)
}
@ -98,6 +107,37 @@ const withContext = Base =>
);
}
renderWithRowExpandCtx(base, baseProps) {
return (
rootProps,
cellEditProps,
filterProps,
searchProps,
sortProps,
paginationProps
) => (
<this.RowExpandContext.Provider
{ ...baseProps }
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>
</this.RowExpandContext.Provider>
);
}
renderWithPaginationCtx(base) {
return (
rootProps,
@ -232,6 +272,10 @@ const withContext = Base =>
base = this.renderWithSelectionCtx(base, baseProps);
}
if (this.RowExpandContext) {
base = this.renderWithRowExpandCtx(base, baseProps);
}
if (this.PaginationContext) {
base = this.renderWithPaginationCtx(base, baseProps);
}

View File

@ -0,0 +1,62 @@
/* eslint react/prop-types: 0 */
import React from 'react';
import PropTypes from 'prop-types';
export default (
dataOperator
) => {
const RowExpandContext = React.createContext();
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 || [] };
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 }));
}
render() {
return (
<RowExpandContext.Provider
value={ {
expanded: this.state.expanded,
onRowExpand: this.handleRowExpand
} }
>
{ this.props.children }
</RowExpandContext.Provider>
);
}
}
return {
Provider: RowExpandProvider,
Consumer: RowExpandContext.Consumer
};
};

View File

@ -1,10 +1,13 @@
export default ExtendBase =>
class ColumnResolver extends ExtendBase {
visibleColumnSize(includeSelectColumn = true) {
const columnLen = this.props.columns.filter(c => !c.hidden).length;
let columnLen = this.props.columns.filter(c => !c.hidden).length;
if (!includeSelectColumn) return columnLen;
if (this.props.selectRow && !this.props.selectRow.hideSelectColumn) {
return columnLen + 1;
columnLen += 1;
}
if (this.props.expandRow && this.props.expandRow.showExpandColumn) {
columnLen += 1;
}
return columnLen;
}

View File

@ -0,0 +1,15 @@
export default ExtendBase =>
class ExpandRowResolver extends ExtendBase {
resolveExpandRowProps() {
const { expandRow, expanded, onRowExpand } = this.props;
if (expandRow) {
return {
...expandRow,
expanded,
onRowExpand,
nonExpandable: expandRow.nonExpandable || []
};
}
return null;
}
};

View File

@ -1,9 +1,11 @@
import ColumnResolver from './column-resolver';
import ExpandRowResolver from './expand-row-resolver';
import Const from '../const';
import _ from '../utils';
export default ExtendBase =>
class TableResolver extends ColumnResolver(ExtendBase) {
class TableResolver extends
ExpandRowResolver(ColumnResolver(ExtendBase)) {
validateProps() {
const { keyField } = this.props;
if (!keyField) {

View File

@ -1,4 +1,5 @@
import _ from './utils';
import Const from './const';
const events = [
'onClick',
@ -30,11 +31,11 @@ export default ExtendBase =>
selected,
keyField,
selectable,
expandable,
rowIndex,
selectRow: {
onRowSelect,
clickToEdit
},
expanded,
expandRow,
selectRow,
cellEdit: {
mode,
DBCLICK_TO_CELL_EDIT,
@ -46,13 +47,16 @@ export default ExtendBase =>
if (cb) {
cb(e, row, rowIndex);
}
if (selectable) {
const key = _.get(row, keyField);
onRowSelect(key, !selected, rowIndex, e);
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 && clickToEdit) {
if (mode === DBCLICK_TO_CELL_EDIT && selectRow.clickToEdit) {
this.clickNum += 1;
_.debounce(() => {
if (this.clickNum === 1) {
@ -68,7 +72,8 @@ export default ExtendBase =>
delegate(attrs = {}) {
const newAttrs = {};
if (this.props.selectRow && this.props.selectRow.clickToSelect) {
const { expandRow, selectRow } = this.props;
if (expandRow || (selectRow && selectRow.clickToSelect)) {
newAttrs.onClick = this.createClickEventHandler(attrs.onClick);
}
Object.keys(attrs).forEach((attr) => {

View File

@ -0,0 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
const ExpandRow = ({ children, ...rest }) => (
<tr className="expanding-row">
<td { ...rest }>{ children }</td>
</tr>
);
ExpandRow.propTypes = {
children: PropTypes.node
};
ExpandRow.defaultProps = {
children: null
};
export default ExpandRow;

View File

@ -30,6 +30,10 @@
text-align: center;
}
tr.expanding-row {
padding: 5px;
}
td.react-bootstrap-table-editing-cell {
.animated {
animation-fill-mode: both;