UNPKG

@douyinfe/semi-ui

Version:

A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.

375 lines (374 loc) 13.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _isEqual2 = _interopRequireDefault(require("lodash/isEqual")); var _merge2 = _interopRequireDefault(require("lodash/merge")); var _omit2 = _interopRequireDefault(require("lodash/omit")); var _set2 = _interopRequireDefault(require("lodash/set")); var _noop2 = _interopRequireDefault(require("lodash/noop")); var _get2 = _interopRequireDefault(require("lodash/get")); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireDefault(require("prop-types")); var _constants = require("@douyinfe/semi-foundation/lib/cjs/table/constants"); var _cellFoundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/table/cellFoundation")); var _utils = require("@douyinfe/semi-foundation/lib/cjs/table/utils"); var _baseComponent = _interopRequireDefault(require("../_base/baseComponent")); var _tableContext = _interopRequireDefault(require("./table-context")); var _utils2 = require("./utils"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function isInvalidRenderCellText(text) { return text && ! /*#__PURE__*/_react.default.isValidElement(text) && Object.prototype.toString.call(text) === '[object Object]'; } class TableCell extends _baseComponent.default { get adapter() { var _this = this; return Object.assign(Object.assign({}, super.adapter), { notifyClick: function () { const { onClick } = _this.props; if (typeof onClick === 'function') { onClick(...arguments); } } }); } constructor(props) { super(props); this.setRef = ref => this.ref = ref; this.handleClick = e => { this.foundation.handleClick(e); const customCellProps = this.adapter.getCache('customCellProps'); if (customCellProps && typeof customCellProps.onClick === 'function') { customCellProps.onClick(e); } }; this.ref = /*#__PURE__*/(0, _react.createRef)(); this.foundation = new _cellFoundation.default(this.adapter); } /** * Control whether to execute the render function of the cell * 1. Scenes that return true * - The cell contains the selection state, you need to calculate whether its selection state has changed during selection * - The cell contains the folding state, it needs to be calculated when the folding state has changed * 2. Scenarios that return false * - Cells without table operation operation status, only need to judge that their props have changed * At this time, the update of the table cell is controlled by the user. At this time, its update will not affect other cells * * 控制是否执行cell的render函数 * 1. 返回true的场景 * - cell内包含选择状态,需要在选择时计算它的选择态是否发生变化 * - cell内包含折叠状态,需要在折叠时计算它的折叠态是否发生了变化 * 2. 返回false的场景 * - 没有table操作操作状态的cell,只需判断自己的props发生了变化 * 此时table cell的更新由用户自己控制,此时它的更新不会影响其他cell * * @param {*} nextProps * @returns */ shouldComponentUpdate(nextProps) { const props = this.props; const { column, expandIcon } = props; const cellInSelectionColumn = (0, _utils.isSelectionColumn)(column); const { shouldCellUpdate } = column; if (typeof shouldCellUpdate === 'function') { return shouldCellUpdate(nextProps, props); } // The expand button may be in a separate column or in the first data column const columnHasExpandIcon = (0, _utils.isExpandedColumn)(column) || expandIcon; if ((cellInSelectionColumn || columnHasExpandIcon) && !(0, _isEqual2.default)(nextProps, this.props)) { return true; } else { const omitProps = ['selected', 'expanded', 'expandIcon', 'disabled']; const propsOmitSelected = (0, _omit2.default)(props, omitProps); const nextPropsOmitSelected = (0, _omit2.default)(nextProps, omitProps); if (!(0, _isEqual2.default)(nextPropsOmitSelected, propsOmitSelected)) { return true; } } return false; } componentDidUpdate() { this.props.onDidUpdate(this.ref); } getTdProps() { const { record, index, column = {}, fixedLeft, fixedRight, width, height } = this.props; let tdProps = {}; let customCellProps = {}; const { direction } = this.context; const isRTL = direction === 'rtl'; const fixedLeftFlag = fixedLeft || typeof fixedLeft === 'number'; const fixedRightFlag = fixedRight || typeof fixedRight === 'number'; if (fixedLeftFlag) { (0, _set2.default)(tdProps, isRTL ? 'style.right' : 'style.left', typeof fixedLeft === 'number' ? fixedLeft : 0); } else if (fixedRightFlag) { (0, _set2.default)(tdProps, isRTL ? 'style.left' : 'style.right', typeof fixedRight === 'number' ? fixedRight : 0); } if (width != null) { (0, _set2.default)(tdProps, 'style.width', width); } if (height != null) { (0, _set2.default)(tdProps, 'style.height', height); } if (column.onCell) { customCellProps = column.onCell(record, index); this.adapter.setCache('customCellProps', Object.assign({}, customCellProps)); tdProps = Object.assign(Object.assign({}, tdProps), (0, _omit2.default)(customCellProps, ['style', 'className', 'onClick'])); const customCellStyle = (0, _get2.default)(customCellProps, 'style') || {}; tdProps.style = Object.assign(Object.assign({}, tdProps.style), customCellStyle); } if (column.align) { const textAlign = (0, _utils.getRTLAlign)(column.align, direction); const justifyContent = (0, _utils.getRTLFlexAlign)(column.align, direction); tdProps.style = Object.assign(Object.assign({}, tdProps.style), { textAlign, justifyContent }); } return { tdProps, customCellProps }; } /** * We should return undefined if no dataIndex is specified, but in order to * be compatible with object-path's behavior, we return the record object instead. */ renderText(tdProps) { const { record, indentSize, prefixCls, indent, index, expandIcon, renderExpandIcon, column = {}, hovered } = this.props; const { dataIndex, render, useFullRender } = column; let text, colSpan, rowSpan; if (typeof dataIndex === 'number') { text = (0, _get2.default)(record, dataIndex); } else if (!dataIndex || dataIndex.length === 0) { text = record; } else { text = (0, _get2.default)(record, dataIndex); } const indentText = indent && indentSize ? (/*#__PURE__*/_react.default.createElement("span", { style: { paddingLeft: `${indentSize * indent}px` }, className: `${prefixCls}-row-indent indent-level-${indent}` })) : null; // column.render const realExpandIcon = typeof renderExpandIcon === 'function' ? renderExpandIcon(record) : expandIcon; if (render) { const renderOptions = { expandIcon: realExpandIcon, isHovering: hovered }; // column.useFullRender if (useFullRender) { const { renderSelection } = this.context; const realSelection = typeof renderSelection === 'function' ? renderSelection(record) : null; Object.assign(renderOptions, { selection: realSelection, indentText }); } text = render(text, record, index, renderOptions); if (isInvalidRenderCellText(text)) { tdProps = text.props ? (0, _merge2.default)(tdProps, text.props) : tdProps; colSpan = tdProps.colSpan; rowSpan = tdProps.rowSpan; text = text.children; } } return { text, indentText, rowSpan, colSpan, realExpandIcon, tdProps }; } renderInner(text, indentText, realExpandIcon) { const { prefixCls, isSection, expandIcon, column = {} } = this.props; const { tableWidth, anyColumnFixed } = this.context; const { useFullRender } = column; let inner = null; if (useFullRender) { inner = text; } else { inner = [/*#__PURE__*/_react.default.createElement(_react.Fragment, { key: 'indentText' }, indentText), /*#__PURE__*/_react.default.createElement(_react.Fragment, { key: 'expandIcon' }, expandIcon ? realExpandIcon : null), /*#__PURE__*/_react.default.createElement(_react.Fragment, { key: 'text' }, text)]; } if (isSection) { inner = /*#__PURE__*/_react.default.createElement("div", { className: (0, _classnames.default)(`${prefixCls}-section-inner`), style: { width: anyColumnFixed ? (0, _utils2.amendTableWidth)(tableWidth) : undefined } }, inner); } return inner; } render() { const { prefixCls, column = {}, component: BodyCell, fixedLeft, fixedRight, lastFixedLeft, firstFixedRight, colIndex } = this.props; const { direction } = this.context; const isRTL = direction === 'rtl'; const { className, ellipsis } = column; const fixedLeftFlag = fixedLeft || typeof fixedLeft === 'number'; const fixedRightFlag = fixedRight || typeof fixedRight === 'number'; const { tdProps, customCellProps } = this.getTdProps(); const renderTextResult = this.renderText(tdProps); let { text } = renderTextResult; const { indentText, rowSpan, colSpan, realExpandIcon, tdProps: newTdProps } = renderTextResult; let title; const shouldShowTitle = (0, _utils.shouldShowEllipsisTitle)(ellipsis); if (shouldShowTitle) { if (typeof text === 'string') { title = text; } } if (rowSpan === 0 || colSpan === 0) { return null; } if (isInvalidRenderCellText(text)) { text = null; } const inner = this.renderInner(text, indentText, realExpandIcon); let isFixedLeft, isFixedLeftLast, isFixedRight, isFixedRightFirst; if (isRTL) { isFixedLeft = fixedRightFlag; isFixedLeftLast = firstFixedRight; isFixedRight = fixedLeftFlag; isFixedRightFirst = lastFixedLeft; } else { isFixedLeft = fixedLeftFlag; isFixedLeftLast = lastFixedLeft; isFixedRight = fixedRightFlag; isFixedRightFirst = firstFixedRight; } const columnCls = (0, _classnames.default)(className, `${prefixCls}-row-cell`, (0, _get2.default)(customCellProps, 'className'), { [`${prefixCls}-cell-fixed-left`]: isFixedLeft, [`${prefixCls}-cell-fixed-left-last`]: isFixedLeftLast, [`${prefixCls}-cell-fixed-right`]: isFixedRight, [`${prefixCls}-cell-fixed-right-first`]: isFixedRightFirst, [`${prefixCls}-row-cell-ellipsis`]: ellipsis }); return /*#__PURE__*/_react.default.createElement(BodyCell, Object.assign({ role: "gridcell", "aria-colindex": colIndex + 1, className: columnCls, onClick: this.handleClick, title: title }, newTdProps, { ref: this.setRef }), inner); } } exports.default = TableCell; TableCell.contextType = _tableContext.default; TableCell.defaultProps = { indent: 0, indentSize: _constants.numbers.DEFAULT_INDENT_WIDTH, onClick: _noop2.default, prefixCls: _constants.cssClasses.PREFIX, component: 'td', onDidUpdate: _noop2.default, column: {} }; TableCell.propTypes = { record: _propTypes.default.object, prefixCls: _propTypes.default.string, index: _propTypes.default.number, fixedLeft: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.number]), lastFixedLeft: _propTypes.default.bool, fixedRight: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.number]), firstFixedRight: _propTypes.default.bool, indent: _propTypes.default.number, indentSize: _propTypes.default.number, column: _propTypes.default.object, expandIcon: _propTypes.default.any, renderExpandIcon: _propTypes.default.func, hideExpandedColumn: _propTypes.default.bool, component: _propTypes.default.any, onClick: _propTypes.default.func, onDidUpdate: _propTypes.default.func, isSection: _propTypes.default.bool, width: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), height: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), selected: _propTypes.default.bool, expanded: _propTypes.default.bool, colIndex: _propTypes.default.number, hovered: _propTypes.default.bool };