HeadTable.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { get, noop } from 'lodash';
  4. import classnames from 'classnames';
  5. import ColGroup from './ColGroup';
  6. import TableHeader from './TableHeader';
  7. import { Fixed, TableComponents, Scroll, BodyScrollEvent, ColumnProps, OnHeaderRow, Sticky } from './interface';
  8. export interface HeadTableProps {
  9. tableLayout?: 'fixed' | 'auto';
  10. bodyHasScrollBar?: boolean;
  11. columns?: ColumnProps[];
  12. components?: TableComponents;
  13. dataSource?: Record<string, any>[];
  14. fixed?: Fixed;
  15. handleBodyScroll?: React.EventHandler<BodyScrollEvent>;
  16. prefixCls?: string;
  17. forwardedRef?: React.MutableRefObject<HTMLDivElement> | ((instance: any) => void);
  18. scroll?: Scroll;
  19. selectedRowKeysSet: Set<any>;
  20. showHeader?: boolean;
  21. onDidUpdate?: (ref: React.MutableRefObject<any>) => void;
  22. onHeaderRow?: OnHeaderRow<any>;
  23. sticky?: Sticky
  24. }
  25. /**
  26. * When there are fixed columns, the header is rendered as a separate Table
  27. */
  28. class HeadTable extends React.PureComponent<HeadTableProps> {
  29. static propTypes = {
  30. tableLayout: PropTypes.string,
  31. bodyHasScrollBar: PropTypes.bool,
  32. columns: PropTypes.array,
  33. components: PropTypes.object,
  34. dataSource: PropTypes.array,
  35. fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
  36. handleBodyScroll: PropTypes.func,
  37. prefixCls: PropTypes.string,
  38. forwardedRef: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
  39. scroll: PropTypes.shape({
  40. x: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.bool]),
  41. y: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  42. }),
  43. selectedRowKeysSet: PropTypes.instanceOf(Set).isRequired, // Useful when update is selected
  44. showHeader: PropTypes.bool,
  45. onDidUpdate: PropTypes.func,
  46. onHeaderRow: PropTypes.func,
  47. };
  48. static defaultProps = {
  49. handleBodyScroll: noop,
  50. };
  51. constructor(props: HeadTableProps = { selectedRowKeysSet: new Set() }) {
  52. super(props);
  53. }
  54. render() {
  55. const {
  56. scroll,
  57. prefixCls,
  58. fixed,
  59. forwardedRef,
  60. handleBodyScroll,
  61. columns,
  62. components,
  63. onDidUpdate,
  64. showHeader,
  65. tableLayout,
  66. bodyHasScrollBar,
  67. sticky
  68. } = this.props;
  69. if (!showHeader) {
  70. return null;
  71. }
  72. const Table = get(components, 'header.outer', 'table') as unknown as typeof React.Component;
  73. const x = get(scroll, 'x');
  74. const headStyle: Partial<React.CSSProperties> = {};
  75. const tableStyle: { width?: number | string } = {};
  76. if (x && !fixed) {
  77. tableStyle.width = x;
  78. }
  79. if (bodyHasScrollBar) {
  80. headStyle.overflowY = 'scroll';
  81. }
  82. const colgroup = <ColGroup columns={columns} prefixCls={prefixCls} />;
  83. const tableHeader = (
  84. <TableHeader {...this.props} columns={columns} components={components} onDidUpdate={onDidUpdate} />
  85. );
  86. const headTableCls = classnames(`${prefixCls}-header`, {
  87. [`${prefixCls}-header-sticky`]: sticky,
  88. });
  89. const stickyTop = get(sticky, 'top', 0);
  90. if (typeof stickyTop === 'number') {
  91. headStyle.top = stickyTop;
  92. }
  93. return (
  94. <div
  95. key="headTable"
  96. style={headStyle}
  97. className={headTableCls}
  98. ref={forwardedRef}
  99. onScroll={handleBodyScroll}
  100. >
  101. <Table
  102. style={tableStyle}
  103. className={classnames(prefixCls, {
  104. [`${prefixCls}-fixed`]: tableLayout === 'fixed',
  105. })}
  106. >
  107. {colgroup}
  108. {tableHeader}
  109. </Table>
  110. </div>
  111. );
  112. }
  113. }
  114. export default React.forwardRef<HTMLDivElement, HeadTableProps>((props, ref) => <HeadTable {...props} forwardedRef={ref} />);