index.js 2.97 KB
Newer Older
1
import { ConfigProvider, Table } from 'antd';
2
import classNames from 'classnames';
涂茜's avatar
涂茜 committed
3
import PropTypes from 'prop-types';
4
import React, { useContext, useEffect, useRef, useState } from 'react';
5 6
import { Resizable } from 'react-resizable';
import 'react-resizable/css/styles.css';
7 8
import './index.less';

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
// 调整table表头
const ResizeableTitle = (props) => {
  const { onResize, width, resize, ...restProps } = props;
  if (!width || !resize) {
    return <th {...restProps} />;
  }

  return (
    <Resizable
      width={width}
      height={0}
      onResize={onResize}
      draggableOpts={{ enableUserSelectHack: false }}
    >
      <th {...restProps} />
    </Resizable>
  );
};

28
const BasicTable = (props) => {
29
  const tableRef = useRef(null);
30 31
  const [cols, setCols] = useState(props.columns);
  const [columns, setColumns] = useState(props.columns);
32 33
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('basic-table');
李纪文's avatar
李纪文 committed
34
  const pagination = typeof props.pagination !== 'undefined' ? props.pagination : {};
35 36 37 38 39
  const showTotal = (total) => {
    return `共 ${Math.ceil(
      total / (props.pagination ? props.pagination.pageSize || 10 : 10),
    )} 页 / 共 ${total} 条记录`;
  };
李纪文's avatar
李纪文 committed
40

41 42 43 44 45 46 47 48 49 50 51 52
  // 定义头部组件
  const components = {
    header: {
      cell: ResizeableTitle,
    },
  };

  // 处理拖拽
  const handleResize =
    (index) =>
    (e, { size }) => {
      const nextColumns = [...cols];
李纪文's avatar
李纪文 committed
53 54 55
      const { minWidth, maxWidth } = nextColumns[index];
      if (minWidth && size.width <= minWidth) return false;
      if (maxWidth && size.width >= maxWidth) return false;
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
      // 拖拽是调整宽度
      nextColumns[index] = {
        ...nextColumns[index],
        width: size.width,
      };
      setCols(nextColumns);
    };

  useEffect(() => {
    setColumns(
      (cols || []).map((col, index) => ({
        ...col,
        onHeaderCell: (column) => ({
          width: column.width,
          resize: column.resize || false,
          onResize: handleResize(index),
        }),
      })),
    );
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [cols]);
77 78 79 80 81 82
  const renderEmpty = () => {
    let height = tableRef.current?.clientHeight;
    // 表格高度减 表头 减padding
    height = height ? (props.showHeader === false ? height - 15 - 32 : height - 60 - 32) : 200;
    return <div style={{ height: height }} />;
  };
李纪文's avatar
李纪文 committed
83 84 85 86
  useEffect(() => {
    setCols(props.columns);
  }, [props.columns]);

87
  return (
88 89 90 91 92 93 94 95 96 97 98
    <ConfigProvider renderEmpty={renderEmpty}>
      <Table
        ref={tableRef}
        className={classNames(prefixCls)}
        scroll={{ y: 'calc(100% - 40px)' }}
        components={components}
        {...props}
        columns={columns}
        pagination={pagination ? { showTotal, ...pagination } : pagination}
      />
    </ConfigProvider>
99
  );
100 101 102 103 104 105 106 107 108 109 110 111 112
};

BasicTable.defaultProps = {
  columns: [],
  dataSource: [],
};

BasicTable.propTypes = {
  columns: PropTypes.array,
  dataSource: PropTypes.array,
};

export default BasicTable;