index.js 2.57 KB
import React, { useContext, useState, useEffect } from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { Table, ConfigProvider } from 'antd';
import { Resizable } from 'react-resizable';
import 'react-resizable/css/styles.css';
import './index.less';

// 调整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>
  );
};

const BasicTable = (props) => {
  const [cols, setCols] = useState(props.columns);
  const [columns, setColumns] = useState(props.columns);
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('basic-table');
  const pagination = typeof props.pagination !== 'undefined' ? props.pagination : {};

  const showTotal = (total) => {
    return `共 ${Math.ceil(
      total / (props.pagination ? props.pagination.pageSize || 10 : 10),
    )} 页 / 共 ${total} 条记录`;
  };

  // 定义头部组件
  const components = {
    header: {
      cell: ResizeableTitle,
    },
  };

  // 处理拖拽
  const handleResize =
    (index) =>
    (e, { size }) => {
      const nextColumns = [...cols];
      const { minWidth, maxWidth } = nextColumns[index];
      if (minWidth && size.width <= minWidth) return false;
      if (maxWidth && size.width >= maxWidth) return false;
      // 拖拽是调整宽度
      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]);

  useEffect(() => {
    setCols(props.columns);
  }, [props.columns]);

  return (
    <Table
      className={classNames(prefixCls)}
      scroll={{ y: 'calc(100% - 40px)' }}
      components={components}
      {...props}
      columns={columns}
      pagination={pagination ? { showTotal, ...pagination } : pagination}
    />
  );
};

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

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

export default BasicTable;