ffr-components
Version:
Fiori styled UI components
437 lines (384 loc) • 15.2 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import classnames from 'classnames';
import React from 'react';
import { isLeadingCheckbox, LeadingCheckbox } from './LeadingCheckboxRenderer';
import { calculateRowKey, isDefaultFocusAble, generateTableIndex } from './tableUtil';
import oType, { KeyCode } from '../utils';
import Icon from '../icon';
import { REF_TYPE } from './constant';
import { connect } from './TableContext';
var ENTER_MODE = {
expandAble: 'expandAble'
};
var indent = 16;
var Row =
/*#__PURE__*/
function (_React$Component) {
_inherits(Row, _React$Component);
function Row(props) {
var _this;
_classCallCheck(this, Row);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Row).call(this, props));
_this.updateRow = function () {
return _this.forceUpdate();
};
_this.updateExpanding = function (attribute, keys) {
var key = _this.state.key;
var shouldExpand = keys.indexOf(key) >= 0;
_this.expanded = _this.expanded || shouldExpand;
_this.setState({
expanding: shouldExpand
});
};
_this.updateHoverState = function (attribute, isHover) {
var currentHover = _this.state.currentHover;
if (isHover !== currentHover) {
_this.setState({
currentHover: isHover
});
}
};
_this.onMouseEnterRow = function (e) {
var _this$props = _this.props,
tableContext = _this$props.tableContext,
rowKey = _this$props.rowKey;
tableContext.updateCurrentHoverRow(rowKey);
};
_this.onMouseLeaveRow = function (e) {
var tableContext = _this.props.tableContext;
tableContext.updateCurrentHoverRow(null);
};
_this.renderColumn = function (col) {
var _this$props2 = _this.props,
rowData = _this$props2.rowData,
rowIndex = _this$props2.rowIndex;
var key = col.key || col.attribute;
var content = null;
if (col.attribute) {
content = rowData[col.attribute];
}
if (oType.isFunction(col.render)) {
content = col.render(content, rowData, rowIndex);
}
return React.createElement("td", {
key: key
}, content);
};
_this.expandHandler = function (e) {
var tableContext = _this.props.tableContext;
var _this$state = _this.state,
expanding = _this$state.expanding,
key = _this$state.key;
_this.expanded = _this.expanded || expanding;
_this.setState({
expanding: !expanding
});
if (_this.isTreeControlTable()) {
tableContext.updateExpandedRowkeys(key, !expanding);
}
};
_this.renderChildren = function () {
var _this$props3 = _this.props,
rowData = _this$props3.rowData,
childName = _this$props3.childName,
columns = _this$props3.columns,
childLevel = _this$props3.childLevel,
hide = _this$props3.hide,
defaultExpandAll = _this$props3.defaultExpandAll,
fixed = _this$props3.fixed,
handleMoveFocus = _this$props3.handleMoveFocus,
expandedDataKeys = _this$props3.expandedDataKeys,
dataKey = _this$props3.dataKey;
var expanding = _this.state.expanding;
if (expanding) {
return InnerRenderer({
data: rowData[childName],
lastLine: columns,
fixed: fixed,
childName: childName,
defaultExpandAll: defaultExpandAll,
handleMoveFocus: handleMoveFocus,
expandedDataKeys: expandedDataKeys,
childLevel: childLevel + 1,
hide: hide,
dataKey: dataKey
});
} else if (_this.expanded) {
return InnerRenderer({
data: rowData[childName],
lastLine: columns,
fixed: fixed,
childName: childName,
defaultExpandAll: defaultExpandAll,
handleMoveFocus: handleMoveFocus,
expandedDataKeys: expandedDataKeys,
childLevel: childLevel + 1,
hide: true,
dataKey: dataKey
});
}
return null;
};
_this.isTreeControlTable = function () {
// check whether has expand controller: the expand controll always in the left most table
var _this$props4 = _this.props,
tableContext = _this$props4.tableContext,
fixed = _this$props4.fixed;
return fixed === 'left' && tableContext.hasLeftFixedContentTable() || !tableContext.hasLeftFixedTable() && fixed === undefined && tableContext.hasRightFixedTable() || !tableContext.hasFixedTable();
};
_this.componentDidUpdate = function (preProps) {
var _preProps$expandedDat = preProps.expandedDataKeys,
preExpandedDataKeys = _preProps$expandedDat === void 0 ? [] : _preProps$expandedDat;
var _this$props5 = _this.props,
_this$props5$expanded = _this$props5.expandedDataKeys,
expandedDataKeys = _this$props5$expanded === void 0 ? [] : _this$props5$expanded,
tableContext = _this$props5.tableContext,
rowKey = _this$props5.rowKey;
if (_this.isTreeControlTable() && (preExpandedDataKeys !== expandedDataKeys || preExpandedDataKeys.length !== expandedDataKeys.length)) {
if (expandedDataKeys.indexOf(rowKey) >= 0 && !_this.state.expanding) {
_this.expanded = true;
_this.setState({
expanding: true
});
tableContext.updateExpandedRowkeys(rowKey, true);
}
}
};
_this.handleCellKeyDown = function (e) {
var handleMoveFocus = _this.props.handleMoveFocus;
var keyCode = e.keyCode,
altKey = e.altKey;
var enterMode = e.target.getAttribute('data-enter');
if (keyCode === KeyCode.ENTER && !altKey) {
if (enterMode === ENTER_MODE.expandAble) {
_this.expandHandler();
}
} else if (handleMoveFocus) {
handleMoveFocus(e);
}
};
var _rowData = props.rowData,
_childName = props.childName,
_defaultExpandAll = props.defaultExpandAll,
_tableContext = props.tableContext,
_fixed = props.fixed,
_rowKey = props.rowKey;
_this.state = {
currentHover: false,
expanding: Array.isArray(_rowData[_childName]) && _defaultExpandAll
};
_this.fullKey = _fixed ? "".concat(_fixed, "/").concat(_rowKey) : _rowKey;
_this.rowRef = React.createRef();
_this.expanded = Array.isArray(_rowData[_childName]) && _defaultExpandAll;
if (Array.isArray(_rowData[_childName]) && !_this.isTreeControlTable() && _tableContext.hasFixedTable()) {
_tableContext.subscribe('expandedRowkeys', _this.updateExpanding);
}
if (_tableContext.hasFixedTable()) {
_tableContext.subscribe('currentHoverRow', _this.updateHoverState, _this.fullKey);
}
if (_tableContext.store.selectionColumn) {
_tableContext.subscribe('selectedRecords', _this.updateRow, _this.fullKey);
}
return _this;
}
_createClass(Row, [{
key: "componentDidMount",
value: function componentDidMount() {
var _this$props6 = this.props,
rowData = _this$props6.rowData,
childName = _this$props6.childName,
defaultExpandAll = _this$props6.defaultExpandAll,
tableContext = _this$props6.tableContext,
rowKey = _this$props6.rowKey;
if (tableContext.hasFixedTable()) {
var _this$rowRef$current = this.rowRef.current,
clientHeight = _this$rowRef$current.clientHeight,
offsetHeight = _this$rowRef$current.offsetHeight;
tableContext.updateRowHeight(Math.max(clientHeight, offsetHeight));
}
if (Array.isArray(rowData[childName]) && defaultExpandAll && this.isTreeControlTable()) {
tableContext.updateExpandedRowkeys(rowKey, true);
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
var tableContext = this.props.tableContext;
tableContext.unsubscribe('expandedRowkeys', this.updateExpanding);
if (tableContext.hasFixedTable()) {
tableContext.unsubscribe('currentHoverRow', this.updateHoverState, this.fullKey);
}
tableContext.unsubscribe('selectedRecords', this.updateRow, this.fullKey);
}
}, {
key: "render",
value: function render() {
var _this2 = this;
var _this$props7 = this.props,
columns = _this$props7.columns,
contentRowHeight = _this$props7.contentRowHeight,
rowData = _this$props7.rowData,
rowIndex = _this$props7.rowIndex,
tableContext = _this$props7.tableContext,
childName = _this$props7.childName,
showChildIndent = _this$props7.showChildIndent,
childLevel = _this$props7.childLevel,
hide = _this$props7.hide,
fixed = _this$props7.fixed,
tableID = _this$props7.tableID,
rowKey = _this$props7.rowKey;
var _this$state2 = this.state,
expanding = _this$state2.expanding,
currentHover = _this$state2.currentHover;
var style = contentRowHeight > 0 ? {
height: contentRowHeight
} : {};
var levelIndent = indent * childLevel;
var selectedRecords = tableContext.getSelectedRecords();
var isChecked = !!selectedRecords[rowKey];
var enterMode = '';
var isSectionLine = false;
if (hide) {
style.display = 'none';
} // const { [childName]: aChildren, ...pureBizData } = rowData; // this can not support during UT
var aChildren = rowData[childName];
if (Array.isArray(aChildren) && rowData && Object.keys(rowData).filter(function (k) {
return k !== childName;
}).length === 1) {
isSectionLine = true;
}
var classname = classnames('fd-table__row', {
'ffr-table-row-hover': currentHover,
'ffr-table-selected': isChecked,
'ffr-table-selected-hover': isChecked && currentHover,
'ffr-tbl-section': isSectionLine
});
var mouseEvent = tableContext.hasFixedTable() ? {
onMouseEnter: this.onMouseEnterRow,
onMouseLeave: this.onMouseLeaveRow
} : {};
return React.createElement(React.Fragment, null, React.createElement("tr", _extends({
ref: this.rowRef,
style: style
}, mouseEvent, {
key: rowKey,
className: classname,
role: "row"
}), columns.map(function (col, inx) {
var columnKey = col.key || col.attribute;
var tdStyle = {};
var content = null;
if (isLeadingCheckbox(col)) {
content = React.createElement(LeadingCheckbox, {
rowData: rowData,
rowKey: rowKey,
isChecked: isChecked,
disabled: isSectionLine
});
} else {
if (col.attribute) {
content = React.createElement("span", null, rowData[col.attribute]);
}
if (oType.isFunction(col.render)) {
content = React.createElement("span", null, col.render(content, rowData, rowIndex));
}
if (tableContext.hasFixedTable() && !fixed) {
tdStyle.whiteSpace = 'nowrap';
}
if (inx === 0 && _this2.isTreeControlTable()) {
if (!oType.isUndefined(childName) && Array.isArray(rowData[childName])) {
enterMode = ENTER_MODE.expandAble;
tdStyle.whiteSpace = 'nowrap';
content = React.createElement(React.Fragment, null, React.createElement("span", {
style: {
marginLeft: levelIndent
}
}), React.createElement(Icon, {
glyph: expanding ? 'navigation-down-arrow' : 'navigation-right-arrow',
className: "ffr-table-expand-arrow",
onClick: _this2.expandHandler
}), content);
} else if (showChildIndent || childLevel > 0) {
tdStyle.whiteSpace = 'nowrap';
content = React.createElement(React.Fragment, null, React.createElement("span", {
className: "ffr-align-toggle",
style: {
marginLeft: levelIndent
}
}), content);
}
}
}
var tabIndex = rowIndex === 0 && isDefaultFocusAble(tableContext, fixed, inx) ? 0 : -1;
var dataIndex = generateTableIndex(REF_TYPE.body, fixed, rowIndex, inx);
if (tabIndex === 0) {
tableContext.updateBodyFocusIndex(dataIndex);
}
return (// eslint-disable-next-line
React.createElement("td", {
key: columnKey || inx,
style: tdStyle,
role: "gridcell",
"data-enter": enterMode,
className: "fd-table__cell",
onKeyDown: _this2.handleCellKeyDown,
tabIndex: tabIndex,
"data-index": dataIndex,
"aria-labelledby": "".concat(tableID, "-l0-h").concat(inx)
}, content)
);
})), this.renderChildren());
}
}]);
return Row;
}(React.Component);
var TableRow = connect('contentRowHeight', 'childName', 'tableID')(Row);
export default TableRow;
export var InnerRenderer = function InnerRenderer(_ref) {
var lastLine = _ref.lastLine,
childName = _ref.childName,
fixed = _ref.fixed,
defaultExpandAll = _ref.defaultExpandAll,
handleMoveFocus = _ref.handleMoveFocus,
dataKey = _ref.dataKey,
_ref$expandedDataKeys = _ref.expandedDataKeys,
expandedDataKeys = _ref$expandedDataKeys === void 0 ? [] : _ref$expandedDataKeys,
_ref$data = _ref.data,
data = _ref$data === void 0 ? [] : _ref$data,
_ref$childLevel = _ref.childLevel,
childLevel = _ref$childLevel === void 0 ? 0 : _ref$childLevel,
_ref$hide = _ref.hide,
hide = _ref$hide === void 0 ? false : _ref$hide;
var showChildIndent = childName && data.some(function (_data) {
return _data[childName] !== undefined;
});
return data.map(function (rowData, index) {
/*
must calculate row key here, since when sort table, all data will be
re-ordered, each data can not match real table row, so must set key
to rowKey, but not use index
*/
var rowKey = calculateRowKey(dataKey, rowData, index);
return React.createElement(TableRow, {
handleMoveFocus: handleMoveFocus,
rowData: rowData,
rowIndex: index,
key: rowKey,
rowKey: rowKey,
columns: lastLine,
showChildIndent: showChildIndent,
childLevel: childLevel,
hide: hide,
defaultExpandAll: defaultExpandAll,
fixed: fixed,
expandedDataKeys: expandedDataKeys,
dataKey: dataKey
});
});
};
export var RowsRenderer = connect('dataKey')(InnerRenderer);