diff --git a/packages/react-bootstrap-table2-editor/index.js b/packages/react-bootstrap-table2-editor/index.js index 0bc57b5..a4b4e65 100644 --- a/packages/react-bootstrap-table2-editor/index.js +++ b/packages/react-bootstrap-table2-editor/index.js @@ -1,16 +1,18 @@ import createContext from './src/context'; -import editingCellFactory from './src/editing-cell'; +import bindCellLevelCellEdit from './src/cell-binder'; +import bindRowLevelCellEdit from './src/row-binder'; +import createEditingCell from './src/editing-cell-binder'; import { EDITTYPE, - CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT, DELAY_FOR_DBCLICK } from './src/const'; export default (options = {}) => ({ createContext, - editingCellFactory, - CLICK_TO_CELL_EDIT, + createEditingCell, + bindCellLevelCellEdit, + bindRowLevelCellEdit, DBCLICK_TO_CELL_EDIT, DELAY_FOR_DBCLICK, options diff --git a/packages/react-bootstrap-table2-editor/src/cell-binder.js b/packages/react-bootstrap-table2-editor/src/cell-binder.js new file mode 100644 index 0000000..6ef110a --- /dev/null +++ b/packages/react-bootstrap-table2-editor/src/cell-binder.js @@ -0,0 +1,38 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; +import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from './const'; + +import { Consumer } from './context'; + +export default (Component, keyField, _) => { + const renderWithCellEdit = (props, cellEdit) => { + const content = _.get(props.row, props.column.dataField); + const editableRow = props.editable; + + let editable = _.isDefined(props.column.editable) ? props.column.editable : true; + if (props.column.dataField === keyField || !editableRow) editable = false; + if (_.isFunction(props.column.editable)) { + editable = props.column.editable( + content, + props.row, + props.rowIndex, + props.columnIndex + ); + } + + return ( + + ); + }; + return props => ( + + { cellEdit => renderWithCellEdit(props, cellEdit) } + + ); +}; diff --git a/packages/react-bootstrap-table2-editor/src/context.js b/packages/react-bootstrap-table2-editor/src/context.js index 5437cca..7011137 100644 --- a/packages/react-bootstrap-table2-editor/src/context.js +++ b/packages/react-bootstrap-table2-editor/src/context.js @@ -4,15 +4,14 @@ import React from 'react'; import PropTypes from 'prop-types'; import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from './const'; +const CellEditContext = React.createContext(); + export default ( _, dataOperator, isRemoteCellEdit, handleCellChange ) => { - let EditingCell; - const CellEditContext = React.createContext(); - class CellEditProvider extends React.Component { static propTypes = { data: PropTypes.array.isRequired, @@ -32,7 +31,6 @@ export default ( constructor(props) { super(props); - EditingCell = props.cellEdit.editingCellFactory(_, props.cellEdit.options.onStartEdit); this.startEditing = this.startEditing.bind(this); this.escapeEditing = this.escapeEditing.bind(this); this.completeEditing = this.completeEditing.bind(this); @@ -102,7 +100,6 @@ export default ( const { cellEdit: { options: { nonEditableRows, errorMessage, ...optionsRest }, - editingCellFactory, createContext, ...cellEditRest } @@ -112,7 +109,6 @@ export default ( ...optionsRest, ...cellEditRest, ...this.state, - EditingCell, nonEditableRows: _.isDefined(nonEditableRows) ? nonEditableRows() : [], onStart: this.startEditing, onEscape: this.escapeEditing, @@ -121,7 +117,7 @@ export default ( return ( { this.props.children } @@ -129,7 +125,8 @@ export default ( } } return { - Provider: CellEditProvider, - Consumer: CellEditContext.Consumer + Provider: CellEditProvider }; }; + +export const Consumer = CellEditContext.Consumer; diff --git a/packages/react-bootstrap-table2-editor/src/editing-cell-binder.js b/packages/react-bootstrap-table2-editor/src/editing-cell-binder.js new file mode 100644 index 0000000..6d3b079 --- /dev/null +++ b/packages/react-bootstrap-table2-editor/src/editing-cell-binder.js @@ -0,0 +1,43 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; +import { Consumer } from './context'; +import createEditingCell from './editing-cell'; + +export default (_) => { + 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) + ; + } + const EditingCell = createEditingCell(_); + return ( + + ); + }; + + return props => ( + + { cellEdit => renderWithEditingCell(props, cellEdit) } + + ); +}; diff --git a/packages/react-bootstrap-table2-editor/src/row-binder.js b/packages/react-bootstrap-table2-editor/src/row-binder.js new file mode 100644 index 0000000..b2e308c --- /dev/null +++ b/packages/react-bootstrap-table2-editor/src/row-binder.js @@ -0,0 +1,35 @@ +/* eslint react/prop-types: 0 */ +import React from 'react'; +import { DELAY_FOR_DBCLICK, DBCLICK_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 ( + + ); + }; + return props => ( + + { cellEdit => renderWithCellEdit(props, cellEdit) } + + ); +}; diff --git a/packages/react-bootstrap-table2/src/body.js b/packages/react-bootstrap-table2/src/body.js index 4da1be7..03582ce 100644 --- a/packages/react-bootstrap-table2/src/body.js +++ b/packages/react-bootstrap-table2/src/body.js @@ -6,6 +6,7 @@ import PropTypes from 'prop-types'; import _ from './utils'; import Row from './row'; +import Cell from './cell'; import RowAggregator from './row-aggregator'; import RowSection from './row-section'; import Const from './const'; @@ -38,55 +39,49 @@ const Body = (props) => { content = ; } else { let RowComponent = Row; - const nonEditableRows = cellEdit.nonEditableRows || []; const selectRowEnabled = selectRow.mode !== Const.ROW_SELECT_DISABLED; const expandRowEnabled = !!expandRow.renderer; + const additionalRowProps = {}; if (expandRowEnabled) { RowComponent = bindExpansion(RowAggregator, visibleColumnSize); } + if (selectRowEnabled) { RowComponent = bindSelection(expandRowEnabled ? RowComponent : RowAggregator); } + if (cellEdit.createContext) { + const CellComponent = cellEdit.bindCellLevelCellEdit(Cell, keyField, _); + const EditingCell = cellEdit.createEditingCell(_, cellEdit.options.onStartEdit); + RowComponent = cellEdit.bindRowLevelCellEdit(RowComponent, selectRowEnabled); + additionalRowProps.CellComponent = CellComponent; + additionalRowProps.EditingCellComponent = EditingCell; + } + + if (selectRowEnabled || expandRowEnabled) { + additionalRowProps.expandRow = expandRow; + additionalRowProps.selectRow = selectRow; + } + content = data.map((row, index) => { const key = _.get(row, keyField); - const editable = !(nonEditableRows.length > 0 && nonEditableRows.indexOf(key) > -1); + const baseRowProps = { + key, + row, + columns, + keyField, + cellEdit, + value: key, + rowIndex: index, + attrs: rowEvents || {}, + ...additionalRowProps + }; - const attrs = rowEvents || {}; - const style = _.isFunction(rowStyle) ? rowStyle(row, index) : rowStyle; - const classes = (_.isFunction(rowClasses) ? rowClasses(row, index) : rowClasses); + baseRowProps.style = _.isFunction(rowStyle) ? rowStyle(row, index) : rowStyle; + baseRowProps.className = (_.isFunction(rowClasses) ? rowClasses(row, index) : rowClasses); - // refine later - const result = - selectRowEnabled || expandRowEnabled ? - () : - (); - - return result; + return ; }); } diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js index ea78c32..fb5663c 100644 --- a/packages/react-bootstrap-table2/src/bootstrap-table.js +++ b/packages/react-bootstrap-table2/src/bootstrap-table.js @@ -56,7 +56,8 @@ class BootstrapTable extends PropsBaseResolver(Component) { wrapperClasses, rowEvents, selectRow, - expandRow + expandRow, + cellEdit } = this.props; const tableWrapperClass = cs('react-bootstrap-table', wrapperClasses); @@ -92,7 +93,7 @@ class BootstrapTable extends PropsBaseResolver(Component) { isEmpty={ this.isEmpty() } visibleColumnSize={ this.visibleColumnSize() } noDataIndication={ noDataIndication } - cellEdit={ this.props.cellEdit || {} } + cellEdit={ cellEdit } selectRow={ selectRow } expandRow={ expandRow } rowStyle={ rowStyle } @@ -195,6 +196,10 @@ BootstrapTable.defaultProps = { renderer: undefined, expanded: [], nonExpandable: [] + }, + cellEdit: { + mode: null, + nonEditableRows: [] } }; diff --git a/packages/react-bootstrap-table2/src/contexts/index.js b/packages/react-bootstrap-table2/src/contexts/index.js index ae2046a..ffebb93 100644 --- a/packages/react-bootstrap-table2/src/contexts/index.js +++ b/packages/react-bootstrap-table2/src/contexts/index.js @@ -57,7 +57,6 @@ const withContext = Base => renderBase() { return ( rootProps, - cellEditProps, filterProps, searchProps, sortProps, @@ -66,7 +65,6 @@ const withContext = Base => renderWithSelectionCtx(base, baseProps) { return ( rootProps, - cellEditProps, filterProps, searchProps, sortProps, @@ -92,7 +89,6 @@ const withContext = Base => { base( rootProps, - cellEditProps, filterProps, searchProps, sortProps, @@ -106,7 +102,6 @@ const withContext = Base => renderWithRowExpandCtx(base, baseProps) { return ( rootProps, - cellEditProps, filterProps, searchProps, sortProps, @@ -120,7 +115,6 @@ const withContext = Base => { base( rootProps, - cellEditProps, filterProps, searchProps, sortProps, @@ -134,7 +128,6 @@ const withContext = Base => renderWithPaginationCtx(base) { return ( rootProps, - cellEditProps, filterProps, searchProps, sortProps @@ -149,7 +142,6 @@ const withContext = Base => { paginationProps => base( rootProps, - cellEditProps, filterProps, searchProps, sortProps, @@ -164,7 +156,6 @@ const withContext = Base => renderWithSortCtx(base, baseProps) { return ( rootProps, - cellEditProps, filterProps, searchProps ) => ( @@ -179,7 +170,6 @@ const withContext = Base => { sortProps => base( rootProps, - cellEditProps, filterProps, searchProps, sortProps, @@ -193,7 +183,6 @@ const withContext = Base => renderWithSearchCtx(base, baseProps) { return ( rootProps, - cellEditProps, filterProps ) => ( { searchProps => base( rootProps, - cellEditProps, filterProps, searchProps ) @@ -217,10 +205,7 @@ const withContext = Base => } renderWithFilterCtx(base, baseProps) { - return ( - rootProps, - cellEditProps - ) => ( + return rootProps => ( this.filterContext = n } @@ -230,7 +215,6 @@ const withContext = Base => { filterProps => base( rootProps, - cellEditProps, filterProps ) } @@ -247,11 +231,7 @@ const withContext = Base => cellEdit={ this.props.cellEdit } data={ rootProps.getData() } > - - { - cellEditProps => base(rootProps, cellEditProps) - } - + { base(rootProps) } ); } diff --git a/packages/react-bootstrap-table2/src/row-aggregator.js b/packages/react-bootstrap-table2/src/row-aggregator.js index e72f6a1..5d709c5 100644 --- a/packages/react-bootstrap-table2/src/row-aggregator.js +++ b/packages/react-bootstrap-table2/src/row-aggregator.js @@ -33,11 +33,7 @@ export default class RowAggregator extends React.Component { expanded, expandRow, selectRow, - cellEdit: { - mode, - DBCLICK_TO_CELL_EDIT, - DELAY_FOR_DBCLICK - } + DELAY_FOR_DBCLICK } = this.props; const clickFn = () => { @@ -53,7 +49,7 @@ export default class RowAggregator extends React.Component { } }; - if (mode === DBCLICK_TO_CELL_EDIT && selectRow.clickToEdit) { + if (DELAY_FOR_DBCLICK) { this.clickNum += 1; _.debounce(() => { if (this.clickNum === 1) { @@ -76,21 +72,18 @@ export default class RowAggregator extends React.Component { style, className, attrs, - cellEdit, selectRow, expandRow, expanded, selected, - selectable + selectable, + ...rest } = this.props; const key = _.get(row, keyField); const { hideSelectColumn, clickToSelect } = selectRow; const { showExpandColumn } = expandRow; - const nonEditableRows = cellEdit.nonEditableRows || []; - const editable = !(nonEditableRows.length > 0 && nonEditableRows.indexOf(key) > -1); - const newAttrs = { ...attrs }; if (clickToSelect || !!expandRow.renderer) { newAttrs.onClick = this.createClickEventHandler(attrs.onClick); @@ -103,11 +96,10 @@ export default class RowAggregator extends React.Component { keyField={ keyField } rowIndex={ rowIndex } columns={ columns } - cellEdit={ cellEdit } - editable={ editable } style={ style } className={ className } attrs={ newAttrs } + { ...rest } > { showExpandColumn ? ( diff --git a/packages/react-bootstrap-table2/src/row-expand/row-binder.js b/packages/react-bootstrap-table2/src/row-expand/row-binder.js index 64eda2c..77f5e36 100644 --- a/packages/react-bootstrap-table2/src/row-expand/row-binder.js +++ b/packages/react-bootstrap-table2/src/row-expand/row-binder.js @@ -1,12 +1,11 @@ /* 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 key = props.value; const expanded = expandRow.expanded.includes(key); const expandable = !expandRow.nonExpandable || !expandRow.nonExpandable.includes(key); 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 f0ad227..68c97f5 100644 --- a/packages/react-bootstrap-table2/src/row-selection/row-binder.js +++ b/packages/react-bootstrap-table2/src/row-selection/row-binder.js @@ -6,7 +6,7 @@ import SelectionContext from '../contexts/selection-context'; export default (Component) => { const renderWithSelection = (props, selectRow) => { - const key = _.get(props.row, props.keyField); + const key = props.value; const selected = selectRow.selected.includes(key); const selectable = !selectRow.nonSelectable || !selectRow.nonSelectable.includes(key); diff --git a/packages/react-bootstrap-table2/src/row.js b/packages/react-bootstrap-table2/src/row.js index 8de768f..c41da6c 100644 --- a/packages/react-bootstrap-table2/src/row.js +++ b/packages/react-bootstrap-table2/src/row.js @@ -12,25 +12,15 @@ class Row extends eventDelegater(Component) { const { row, columns, - keyField, rowIndex, className, style, attrs, - cellEdit, - editable: editableRow + editable, + editingRowIdx, + editingColIdx } = this.props; - - const { - mode, - onStart, - EditingCell, - ridx: editingRowIdx, - cidx: editingColIdx, - CLICK_TO_CELL_EDIT, - DBCLICK_TO_CELL_EDIT, - ...rest - } = cellEdit; + const CellComponent = this.props.CellComponent || Cell; const trAttrs = this.delegate(attrs); return ( @@ -41,20 +31,8 @@ class Row extends eventDelegater(Component) { 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); - } + const EditingCell = this.props.EditingCellComponent; return ( ); } @@ -108,16 +83,13 @@ class Row extends eventDelegater(Component) { if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle; return ( - );