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.

225 lines 8.33 kB
import _findIndex from "lodash/findIndex"; import _omit from "lodash/omit"; import _set from "lodash/set"; import _map from "lodash/map"; import _noop from "lodash/noop"; import _get from "lodash/get"; var __rest = this && this.__rest || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import React from 'react'; import classnames from 'classnames'; import PropTypes from 'prop-types'; import { cssClasses } from '@douyinfe/semi-foundation/lib/es/table/constants'; import { arrayAdd, isFirstFixedRight, isLastLeftFixed, isFixedLeft, isFixedRight, sliceColumnsByLevel, getRTLAlign } from '@douyinfe/semi-foundation/lib/es/table/utils'; import BaseComponent from '../_base/baseComponent'; import TableContext from './table-context'; import Tooltip from '../tooltip'; import LocaleConsumer from '../locale/localeConsumer'; import { getNextSortOrder } from './utils'; export default class TableHeaderRow extends BaseComponent { get adapter() { return Object.assign({}, super.adapter); } constructor(props) { super(props); this.cacheRef = node => { this.headerNode = node; if (node && this.context.setHeadWidths) { const { prefixCls, row, index } = this.props; const cellSelector = `.${prefixCls}-row-head`; const heads = node && node.querySelectorAll && node.querySelectorAll(cellSelector); this.context.setHeadWidths(_map(heads, (head, headIndex) => { let configWidth = _get(row, [headIndex, 'column', 'width']); const key = _get(row, [headIndex, 'column', 'key']); if (typeof configWidth !== 'number') { configWidth = head && head.getBoundingClientRect().width || 0; } return { width: configWidth, key }; }), index); } }; this.headerNode = null; } componentDidUpdate(prevProps) { if (prevProps.columns !== this.props.columns && this.headerNode) { this.cacheRef(this.headerNode); } } render() { const { components, row, prefixCls, onHeaderRow, index, style, columns } = this.props; const { getCellWidths, direction } = this.context; const isRTL = direction === 'rtl'; const slicedColumns = sliceColumnsByLevel(columns, index); const headWidths = getCellWidths(slicedColumns); const HeaderRow = _get(components, 'header.row', 'tr'); const HeaderCell = _get(components, 'header.cell', 'th'); const rowProps = onHeaderRow(columns, index) || {}; _set(rowProps, 'className', classnames(_get(rowProps, 'className'), `${prefixCls}-row`)); const cells = _map(row, (cell, cellIndex) => { const { column } = cell, cellProps = __rest(cell, ["column"]); const customProps = typeof column.onHeaderCell === 'function' ? column.onHeaderCell(column, cellIndex, index) : {}; let cellStyle = Object.assign({}, customProps.style); if (column.align) { const textAlign = getRTLAlign(column.align, direction); cellStyle = Object.assign(Object.assign({}, cellStyle), { textAlign }); customProps.className = classnames(customProps.className, column.className, { [`${prefixCls}-align-${textAlign}`]: Boolean(textAlign) }); } let fixedLeft, fixedRight, fixedLeftLast, fixedRightFirst; if (isRTL) { fixedLeft = isFixedRight(column); fixedRight = isFixedLeft(column); fixedLeftLast = isFirstFixedRight(slicedColumns, column); fixedRightFirst = isLastLeftFixed(slicedColumns, column); } else { fixedLeft = isFixedLeft(column); fixedRight = isFixedRight(column); fixedLeftLast = isLastLeftFixed(slicedColumns, column); fixedRightFirst = isFirstFixedRight(slicedColumns, column); } customProps.className = classnames(`${prefixCls}-row-head`, column.className, customProps.className, // `${prefixCls}-fixed-columns`, { [`${prefixCls}-cell-fixed-left`]: fixedLeft, [`${prefixCls}-cell-fixed-left-last`]: fixedLeftLast, [`${prefixCls}-cell-fixed-right`]: fixedRight, [`${prefixCls}-cell-fixed-right-first`]: fixedRightFirst, [`${prefixCls}-row-head-ellipsis`]: column.ellipsis, [`${prefixCls}-row-head-clickSort`]: column.clickToSort }); if (headWidths.length && slicedColumns.length) { const indexOfSlicedColumns = _findIndex(slicedColumns, item => item && item.key != null && item.key === column.key); if (indexOfSlicedColumns > -1) { if (isFixedLeft(column)) { const xPositionKey = isRTL ? 'right' : 'left'; cellStyle = Object.assign(Object.assign({}, cellStyle), { position: 'sticky', [xPositionKey]: arrayAdd(headWidths, 0, indexOfSlicedColumns) }); } else if (isFixedRight(column)) { const xPositionKey = isRTL ? 'left' : 'right'; cellStyle = Object.assign(Object.assign({}, cellStyle), { position: 'sticky', [xPositionKey]: arrayAdd(headWidths, indexOfSlicedColumns + 1) }); } } } Object.assign(cellProps, { resize: column.resize }); const props = _omit(Object.assign(Object.assign({}, cellProps), customProps), ['colStart', 'colEnd', 'hasSubColumns', 'parents', 'level']); const { rowSpan, colSpan } = props; if (rowSpan === 0 || colSpan === 0) { return null; } if (typeof column.clickToSort === 'function') { if (props.onClick) { const onClick = props.onClick; props.onClick = e => { onClick(e); column.clickToSort(e); }; } else { props.onClick = column.clickToSort; } } if (typeof column.mouseDown === 'function') { if (props.onMouseDown) { const onMouseDown = props.onMouseDown; props.onMouseDown = e => { onMouseDown(e); column.mouseDown(e); }; } else { props.onMouseDown = column.mouseDown; } } const headerCellNode = /*#__PURE__*/React.createElement(HeaderCell, Object.assign({ role: "columnheader", "aria-colindex": cellIndex + 1 }, props, { style: cellStyle, key: column.key || column.dataIndex || cellIndex })); if (typeof column.clickToSort === 'function' && column.showSortTip === true) { let content = getNextSortOrder(column.sortOrder); return /*#__PURE__*/React.createElement(LocaleConsumer, { componentName: "Table", key: column.key || column.dataIndex || cellIndex }, (locale, localeCode) => (/*#__PURE__*/React.createElement(Tooltip, { content: locale[content] }, headerCellNode))); } return headerCellNode; }); return ( /*#__PURE__*/ // @ts-ignore no need to do complex ts type checking and qualification React.createElement(HeaderRow, Object.assign({ role: "row", "aria-rowindex": index + 1 }, rowProps, { style: style, ref: this.cacheRef }), cells) ); } } TableHeaderRow.contextType = TableContext; TableHeaderRow.propTypes = { components: PropTypes.object, row: PropTypes.array, prefixCls: PropTypes.string, onHeaderRow: PropTypes.func, index: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), style: PropTypes.object, columns: PropTypes.array, fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]), selectedRowKeysSet: PropTypes.instanceOf(Set).isRequired }; TableHeaderRow.defaultProps = { onHeaderRow: _noop, prefixCls: cssClasses.PREFIX, columns: [], components: { header: { wrapper: 'thead', row: 'tr', cell: 'th' } } };