zp-bee
Version: 
zp-bee,是一款基于 Dumi,由 React + TypeScript 开发的组件库 🎉。
682 lines (601 loc) • 24.9 kB
JavaScript
import "antd/es/affix/style";
import _Affix from "antd/es/affix";
import "antd/es/table/style";
import _Table from "antd/es/table";
import "antd/es/pagination/style";
import _Pagination from "antd/es/pagination";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
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, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import isVisible from 'rc-util/es/Dom/isVisible';
import { useVT } from '../virtualized-antd-table';
var _document = document;
export var Resizable = function Resizable(props) {
  var children = props.children,
      className = props.className,
      onMouseMove = props.onMouseMove,
      onMouseDown = props.onMouseDown,
      onMouseOut = props.onMouseOut,
      p = __rest(props, ["children", "className", "onMouseMove", "onMouseDown", "onMouseOut"]);
  var handleClick = function handleClick(e) {
    e.stopPropagation();
  };
  return /*#__PURE__*/React.cloneElement(children, Object.assign(Object.assign({}, p), {
    className: "".concat(className ? "".concat(className, " ") : '', "react-resizable"),
    children: /*#__PURE__*/React.createElement(React.Fragment, null, children.props.children, /*#__PURE__*/React.createElement("span", {
      className: "react-resizable-handle",
      onMouseMove: onMouseMove,
      onMouseDown: onMouseDown,
      onMouseOut: onMouseOut
    }))
  }));
};
var MyTable = function MyTable(_a) {
  var columns = _a.columns,
      dataSource = _a.dataSource,
      storeColumnNamePrefix = _a.storeColumnNamePrefix,
      pagination = _a.pagination,
      _a$sticky = _a.sticky,
      sticky = _a$sticky === void 0 ? false : _a$sticky,
      _a$affixPagination = _a.affixPagination,
      affixPagination = _a$affixPagination === void 0 ? true : _a$affixPagination,
      summaryRow = _a.summaryRow,
      settingNode = _a.settingNode,
      settingNodeRender = _a.settingNodeRender,
      _a$isUnusualOrder = _a.isUnusualOrder,
      isUnusualOrder = _a$isUnusualOrder === void 0 ? false : _a$isUnusualOrder,
      footerNode = _a.footerNode,
      scroll = _a.scroll,
      _a$isVirtualList = _a.isVirtualList,
      isVirtualList = _a$isVirtualList === void 0 ? false : _a$isVirtualList,
      propsComponents = _a.components,
      _a$closeResizeHeader = _a.closeResizeHeader,
      closeResizeHeader = _a$closeResizeHeader === void 0 ? false : _a$closeResizeHeader,
      onVirtualScroll = _a.onVirtualScroll,
      _a$autoFix = _a.autoFix,
      autoFix = _a$autoFix === void 0 ? true : _a$autoFix,
      bindRef = _a.bindRef,
      restProps = __rest(_a, ["columns", "dataSource", "storeColumnNamePrefix", "pagination", "sticky", "affixPagination", "summaryRow", "settingNode", "settingNodeRender", "isUnusualOrder", "footerNode", "scroll", "isVirtualList", "components", "closeResizeHeader", "onVirtualScroll", "autoFix", "bindRef"]);
  var _useState = useState(columns),
      _useState2 = _slicedToArray(_useState, 2),
      packagedColumns = _useState2[0],
      setPackagedColumns = _useState2[1];
  var _useState3 = useState(scroll || {}),
      _useState4 = _slicedToArray(_useState3, 2),
      packageScroll = _useState4[0],
      setPackageScroll = _useState4[1];
  var packagedColumnsRef = useRef();
  var _useState5 = useState(true),
      _useState6 = _slicedToArray(_useState5, 2),
      paginationVisible = _useState6[0],
      setPaginationVisible = _useState6[1];
  var purePaginationRef = useRef();
  var resizeProxyRef = useRef();
  var containerRef = useRef();
  var paginationRef = useRef(null);
  var _useRef = useRef({
    dataSrc: []
  }),
      currentInstance = _useRef.current;
  paginationRef.current = pagination;
  var dragging = useRef(false);
  var draggingColumn = useRef(null);
  var ResizableTitle = useCallback(function (props) {
    var onResize = props.onResize,
        onResizeStop = props.onResizeStop,
        className = props.className,
        restProps = __rest(props, ["onResize", "onResizeStop", "className"]);
    var handleMouseMove = function handleMouseMove(column, event, onResizeStop) {
      // if (!column.resizable) return;
      // if (column.subColumns && column.subColumns.length) return;
      if (!dragging.current) {
        var target = event.target;
        while (target && target.tagName !== 'TH') {
          target = target.parentNode;
        }
        if (!target) {
          return;
        }
        var rect = target.getBoundingClientRect();
        var bodyStyle = containerRef.current.style; // 如果是最后一个th 则返回
        if (target.nextSibling && target.nextSibling.getAttribute('class').includes('ant-table-cell-scrollbar') || target.parentNode.lastChild === target) {
          bodyStyle.cursor = '';
          draggingColumn.current = null;
          return;
        }
        if (rect.width > 12 && rect.right - event.pageX < 8) {
          bodyStyle.cursor = 'col-resize';
          draggingColumn.current = Object.assign(Object.assign({}, column), {
            realWidth: rect.width
          });
        } else {
          bodyStyle.cursor = '';
          draggingColumn.current = null;
        }
      }
    };
    var handleMouseDown = function handleMouseDown(column, event, onResizeStop) {
      if (draggingColumn.current) {
        dragging.current = true; // const { table } = this.context;
        // const { el: tableEl, resizeProxy } = table;
        var tableLeft = containerRef.current.getBoundingClientRect().left;
        var columnEl = event.target;
        while (columnEl && columnEl.tagName !== 'TH') {
          columnEl = columnEl.parentNode;
        }
        var columnRect = columnEl.getBoundingClientRect(); // 最小宽度40px
        var minLeft = columnRect.left - tableLeft + 40;
        columnEl.classList.add('noclick');
        var startMouseLeft = event.clientX;
        var startLeft = columnRect.right - tableLeft;
        var startColumnLeft = columnRect.left - tableLeft;
        resizeProxyRef.current.style.visibility = 'visible';
        resizeProxyRef.current.style.left = startLeft - 20 + 'px';
        containerRef.current.onselectstart = function () {
          return false;
        };
        containerRef.current.ondragstart = function () {
          return false;
        };
        var _handleMouseMove = function _handleMouseMove(event) {
          var deltaLeft = event.clientX - startMouseLeft;
          var proxyLeft = startLeft + deltaLeft;
          resizeProxyRef.current.style.left = Math.max(minLeft, proxyLeft) - 20 + 'px';
        };
        var handleMouseUp = function handleMouseUp(event) {
          if (dragging.current) {
            event.stopPropagation();
            var finalLeft = parseInt(resizeProxyRef.current.style.left, 10) + 20;
            var columnWidth = finalLeft - startColumnLeft;
            var oldWidth = draggingColumn.current.realWidth;
            containerRef.current.style.cursor = '';
            resizeProxyRef.current.style.visibility = 'hidden';
            containerRef.current.removeEventListener('mousemove', _handleMouseMove);
            containerRef.current.removeEventListener('mouseup', handleMouseUp);
            containerRef.current.onselectstart = null;
            containerRef.current.ondragstart = null; // 计算出来的值大于0才可以调整
            if (columnWidth > 0) {
              onResizeStop && onResizeStop(columnWidth);
            }
            setTimeout(function () {
              columnEl.classList.remove('noclick');
            });
            dragging.current = false;
            draggingColumn.current = null;
          }
        };
        containerRef.current.addEventListener('mousemove', _handleMouseMove);
        containerRef.current.addEventListener('mouseup', handleMouseUp);
      }
    };
    var handleMouseOut = function handleMouseOut() {
      containerRef.current.style.cursor = '';
    };
    return /*#__PURE__*/React.createElement(Resizable, {
      className: className,
      onMouseMove: function onMouseMove(e) {
        return handleMouseMove(restProps, e, onResizeStop);
      },
      onMouseDown: function onMouseDown(e) {
        return handleMouseDown(restProps, e, onResizeStop);
      },
      onMouseOut: function onMouseOut(e) {
        return handleMouseOut();
      }
    }, /*#__PURE__*/React.createElement("th", Object.assign({}, restProps)));
  }, []); // 视口监听器
  var observer = useRef();
  var initObserver = function initObserver() {
    observer.current = new IntersectionObserver(function (entries) {
      entries.forEach(function (entry) {
        // 元素可见时更新状态
        if (isVisible(containerRef.current)) {
          setPaginationVisible(entry.isIntersecting);
        }
      });
    });
    if (purePaginationRef.current) {
      observer.current.observe(purePaginationRef.current);
    }
  };
  var resetObserver = function resetObserver() {
    // 状态更新,页面卸载时,去除视口监听
    if (observer.current) {
      observer.current.disconnect();
    }
  };
  var handleColsResizeStop = function handleColsResizeStop(index, pIndex) {
    return function (newWidth, nextIndex) {
      var resultIndex = nextIndex !== null && nextIndex !== void 0 ? nextIndex : index;
      var nextColumns = _toConsumableArray(packagedColumnsRef.current);
      if (pIndex) {
        nextColumns[pIndex].children[resultIndex] = Object.assign(Object.assign({}, nextColumns[pIndex].children[resultIndex]), {
          width: newWidth
        });
      } else {
        nextColumns[resultIndex] = Object.assign(Object.assign({}, nextColumns[resultIndex]), {
          width: newWidth
        });
      } // 重新设置表格的滚动宽度
      var _calculateWidth = calculateWidth(nextColumns),
          scrollX = _calculateWidth.scrollX,
          bodyWidth = _calculateWidth.bodyWidth; // 横向超出了 则设置scroll中的x值
      if (scrollX) {
        setPackageScroll(Object.assign({}, packageScroll, {
          x: bodyWidth
        }));
      } else {
        delete packageScroll.x;
        setPackageScroll(packageScroll);
      }
      setPackagedColumns(nextColumns);
      var memorySize = "".concat(newWidth); // 存入store中
      if (storeColumnNamePrefix) {
        if (pIndex) {
          window.localStorage.setItem("".concat(storeColumnNamePrefix, "_").concat(nextColumns[pIndex].children[resultIndex].dataIndex), memorySize);
        } else {
          window.localStorage.setItem("".concat(storeColumnNamePrefix, "_").concat(nextColumns[resultIndex].dataIndex), memorySize);
        }
      }
    };
  };
  var dataSrc = useMemo(function () {
    return summaryRow ? [].concat(_toConsumableArray(dataSource), [Object.assign(Object.assign({}, summaryRow), {
      __isSummaryRow: true
    })]) : dataSource;
  }, [dataSource, summaryRow]);
  var queryColumns = useCallback(function () {
    var tempColumns = _toConsumableArray(columns);
    if (!tempColumns.length) {
      if (settingNode) {
        // 仅有设置按钮 且有自定义render
        if (settingNodeRender) {
          tempColumns.unshift({
            title: settingNode,
            dataIndex: '__dataIndex',
            align: 'center',
            width: 40,
            render: settingNodeRender
          });
        } else {
          tempColumns.unshift({
            title: settingNode,
            dataIndex: '__dataIndex',
            align: 'center',
            width: 40,
            render: function render(text, record, index) {
              var _a, _b, _c, _d;
              if (isUnusualOrder) {
                return {
                  children: record.unusualOrder,
                  props: {
                    rowSpan: record.rowSpan
                  }
                };
              } else {
                return index + 1 + ((_b = (_a = paginationRef.current) === null || _a === void 0 ? void 0 : _a.pageSize) !== null && _b !== void 0 ? _b : 10) * (((_d = (_c = paginationRef.current) === null || _c === void 0 ? void 0 : _c.current) !== null && _d !== void 0 ? _d : 1) - 1);
              }
            }
          });
        }
        setPackagedColumns(tempColumns);
        return;
      }
      setPackagedColumns([]);
      return;
    }
    if (summaryRow || settingNode) {
      // 有合计行
      if (summaryRow) {
        tempColumns = tempColumns.map(function (column) {
          return Object.assign(Object.assign({}, column), {
            render: function render(text, record, index) {
              if (record.__isSummaryRow) {
                // 如果此行是合计行,直接返回文字
                return text;
              } else {
                if (column.render) {
                  // 不是合计行,且column有render属性,使用传入的render
                  return column.render(text, record, index);
                } else {
                  // 不是合计行,且column没有render属性,直接返回文本
                  return text;
                }
              }
            }
          });
        }); // 有合计行则显示序号列,合计行显示总计
        tempColumns.unshift({
          title: settingNode || '',
          fixed: tempColumns[0].fixed === 'left' ? 'left' : '',
          dataIndex: '__dataIndex',
          align: 'center',
          width: 40,
          render: function render(text, record, index) {
            var _a, _b, _c, _d;
            if (record.__isSummaryRow) {
              return '总计';
            } else {
              if (isUnusualOrder) {
                return {
                  children: record.unusualOrder,
                  props: {
                    rowSpan: record.rowSpan
                  }
                };
              } else {
                return index + 1 + ((_b = (_a = paginationRef.current) === null || _a === void 0 ? void 0 : _a.pageSize) !== null && _b !== void 0 ? _b : 10) * (((_d = (_c = paginationRef.current) === null || _c === void 0 ? void 0 : _c.current) !== null && _d !== void 0 ? _d : 1) - 1);
              }
            }
          }
        });
      } else if (settingNode) {
        // 仅有设置按钮
        if (settingNodeRender) {
          tempColumns.unshift({
            title: settingNode,
            fixed: tempColumns[0].fixed === 'left' ? 'left' : '',
            dataIndex: '__dataIndex',
            align: 'center',
            width: 40,
            render: settingNodeRender
          });
        } else {
          tempColumns.unshift({
            title: settingNode,
            fixed: tempColumns[0].fixed === 'left' ? 'left' : '',
            dataIndex: '__dataIndex',
            align: 'center',
            width: 40,
            render: function render(text, record, index) {
              var _a, _b, _c, _d;
              if (isUnusualOrder) {
                return {
                  children: record.unusualOrder,
                  props: {
                    rowSpan: record.rowSpan
                  }
                };
              } else {
                return index + 1 + ((_b = (_a = paginationRef.current) === null || _a === void 0 ? void 0 : _a.pageSize) !== null && _b !== void 0 ? _b : 10) * (((_d = (_c = paginationRef.current) === null || _c === void 0 ? void 0 : _c.current) !== null && _d !== void 0 ? _d : 1) - 1);
              }
            }
          });
        }
      }
    }
    var setColumnsLocalWidth = function setColumnsLocalWidth(columns, pIndex) {
      return columns.map(function (column, index) {
        var memorySize; // 有store存储前缀,取存储值为column的宽度
        if (storeColumnNamePrefix) {
          var sizeColumns = window.localStorage.getItem("".concat(storeColumnNamePrefix, "_").concat(column.dataIndex));
          memorySize = sizeColumns ? Number(sizeColumns) : sizeColumns;
        }
        return Object.assign(Object.assign({}, column), {
          width: memorySize || column.width,
          minWidth: column.width || column.minWidth,
          children: setColumnsLocalWidth(column.children || [], index),
          onHeaderCell: function onHeaderCell(column) {
            return {
              width: column.width,
              dataIndex: column.dataIndex,
              onResizeStop: handleColsResizeStop(index, pIndex)
            };
          }
        });
      });
    };
    tempColumns = setColumnsLocalWidth(tempColumns, null);
    var _calculateWidth2 = calculateWidth(tempColumns),
        scrollX = _calculateWidth2.scrollX,
        bodyWidth = _calculateWidth2.bodyWidth; // 横向超出了 则设置scroll中的x值
    if (scrollX) {
      setPackageScroll(Object.assign({}, packageScroll, {
        x: bodyWidth
      }));
    } else {
      delete packageScroll.x;
      setPackageScroll(packageScroll);
    }
    setPackagedColumns(tempColumns);
  }, [columns, summaryRow, settingNode, scroll, packageScroll]);
  useEffect(function () {
    queryColumns();
  }, [columns, summaryRow, settingNode]);
  useEffect(function () {
    packagedColumnsRef.current = packagedColumns;
  }, [packagedColumns]);
  useEffect(function () {
    if (affixPagination) {
      initObserver();
    }
    return resetObserver;
  }, [affixPagination, paginationVisible]);
  var calculateWidth = function calculateWidth(columns) {
    var gutterWidth = 15;
    var rowSelection = restProps.rowSelection;
    var bodyMinWidth = columns.reduce(function (pre, col) {
      return pre + (col.width || col.minWidth);
    }, rowSelection ? 50 : 0);
    var bodyWidth = containerRef.current.clientWidth;
    var scrollX;
    var fixedWidth;
    var rightFixedWidth; // 判断是否全部都设置了width值 如果全部设置了 则去除最后一列的width值 使得表格自适应且不按比例划分宽度
    // 如果最后需要删除的列fixed 则向前寻找最后一个非fixed的去除width值
    if (autoFix) {
      if (columns && columns.length > 1 && columns.every(function (item) {
        return item.width;
      })) {
        for (var i = columns.length - 1; i > -1; i--) {
          if (!columns[i].fixed) {
            delete columns[i].width;
            break;
          }
        }
      }
    } // mutate props (TableStore's state[columns])
    var flexColumns = columns.filter(function (column) {
      return typeof column.width !== 'number';
    });
    if (flexColumns.length) {
      if (bodyMinWidth < bodyWidth - gutterWidth) {
        // no scroll bar
        scrollX = false;
        var totalFlexWidth = bodyWidth - gutterWidth - bodyMinWidth;
        if (flexColumns.length === 1) {
          flexColumns[0].realWidth = flexColumns[0].minWidth + totalFlexWidth;
        } else {
          var allColumnsWidth = flexColumns.reduce(function (pre, col) {
            return pre + col.minWidth;
          }, 0);
          var flexWidthPerPixel = totalFlexWidth / allColumnsWidth;
          var widthWithoutFirst = 0;
          flexColumns.forEach(function (column, index) {
            if (index === 0) return;
            var flexWidth = Math.floor(column.minWidth * flexWidthPerPixel);
            widthWithoutFirst += flexWidth;
            column.realWidth = column.minWidth + flexWidth;
          });
          flexColumns[0].realWidth = flexColumns[0].minWidth + totalFlexWidth - widthWithoutFirst;
        }
      } else {
        // have horizontal scroll bar
        scrollX = true;
        flexColumns.forEach(function (column) {
          column.realWidth = column.minWidth;
        });
      }
      bodyWidth = Math.max(bodyMinWidth, bodyWidth);
    } else {
      scrollX = bodyMinWidth > bodyWidth;
      bodyWidth = bodyMinWidth;
    } // if (fixedColumns.length) {
    //   fixedWidth = fixedColumns.reduce((pre, col) => pre + col.realWidth, 0);
    // }
    // if (rightFixedColumns.length) {
    //   rightFixedWidth = rightFixedColumns.reduce((pre, col) => pre + col.realWidth, 0);
    // }
    return {
      scrollX: scrollX,
      bodyWidth: bodyWidth,
      fixedWidth: fixedWidth,
      rightFixedWidth: rightFixedWidth
    };
  };
  var PaginationNode = function PaginationNode() {
    return /*#__PURE__*/React.createElement(_Pagination, Object.assign({
      size: "small",
      current: pagination === null || pagination === void 0 ? void 0 : pagination.current,
      pageSize: pagination === null || pagination === void 0 ? void 0 : pagination.pageSize,
      pageSizeOptions: ['10', '20', '30', '40', '100', '200'],
      total: pagination === null || pagination === void 0 ? void 0 : pagination.total,
      showTotal: function showTotal(total) {
        return "\u5171".concat(total, "\u6761\u8BB0\u5F55");
      },
      showSizeChanger: true
    }, pagination));
  };
  var _useVT = useVT(function () {
    return {
      scroll: (scroll === null || scroll === void 0 ? void 0 : scroll.y) ? {
        y: scroll === null || scroll === void 0 ? void 0 : scroll.y
      } : {
        y: 600
      },
      onScroll: function onScroll() {
        var _a, _b; // 当开启虚拟滚动且方法存在时回调
        if (((_a = vtRef === null || vtRef === void 0 ? void 0 : vtRef.current) === null || _a === void 0 ? void 0 : _a.getDataSourceIndex) && onVirtualScroll) {
          var _vtRef$current$getDat = vtRef.current.getDataSourceIndex(),
              _vtRef$current$getDat2 = _slicedToArray(_vtRef$current$getDat, 2),
              startIndex = _vtRef$current$getDat2[0],
              endIndex = _vtRef$current$getDat2[1];
          onVirtualScroll && onVirtualScroll((_b = currentInstance === null || currentInstance === void 0 ? void 0 : currentInstance.dataSrc) === null || _b === void 0 ? void 0 : _b.slice(startIndex, endIndex + 1), startIndex, endIndex);
        }
      }
    };
  }, [scroll === null || scroll === void 0 ? void 0 : scroll.y]),
      _useVT2 = _slicedToArray(_useVT, 3),
      vt = _useVT2[0],
      setVt = _useVT2[1],
      vtRef = _useVT2[2];
  useEffect(function () {
    if (propsComponents) {
      // @ts-ignore
      setVt(propsComponents);
    }
  }, []);
  useEffect(function () {
    if (vtRef) {
      bindRef && bindRef(vtRef);
    }
  }, [vtRef]);
  var memoVtComponents = useMemo(function () {
    setPackageScroll(scroll);
    return Object.assign(Object.assign({}, (scroll === null || scroll === void 0 ? void 0 : scroll.y) && vt), {
      header: {
        cell: closeResizeHeader ? null : ResizableTitle
      }
    });
  }, [scroll === null || scroll === void 0 ? void 0 : scroll.y]);
  var components = useMemo(function () {
    return Object.assign(Object.assign({}, propsComponents), {
      header: {
        cell: closeResizeHeader ? null : ResizableTitle
      }
    });
  }, [scroll, propsComponents]);
  currentInstance.dataSrc = dataSrc;
  return /*#__PURE__*/React.createElement("div", {
    className: "beeTableContainer",
    ref: containerRef
  }, /*#__PURE__*/React.createElement(_Table, Object.assign({}, restProps, {
    className: "oneHeader",
    columns: packagedColumns,
    dataSource: dataSrc,
    sticky: sticky,
    pagination: false,
    scroll: packageScroll,
    components: isVirtualList ? memoVtComponents : components
  })), pagination && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    ref: purePaginationRef,
    className: "purePagination",
    style: paginationVisible ? footerNode ? {
      display: 'flex',
      justifyContent: 'space-between',
      alignItems: 'center'
    } : {
      display: 'block'
    } : {
      visibility: affixPagination ? 'hidden' : 'visible'
    }
  }, footerNode, /*#__PURE__*/React.createElement(PaginationNode, null)), !paginationVisible && affixPagination && /*#__PURE__*/React.createElement(_Affix, {
    offsetBottom: 15,
    style: {
      zIndex: 10
    }
  }, /*#__PURE__*/React.createElement("div", {
    className: "scrollFooter"
  }, /*#__PURE__*/React.createElement("div", {
    className: "footer",
    style: footerNode ? {} : {
      justifyContent: 'flex-end'
    }
  }, footerNode, /*#__PURE__*/React.createElement(PaginationNode, null))))), /*#__PURE__*/React.createElement("div", {
    className: "tableColumnResizeProxy",
    ref: resizeProxyRef,
    style: {
      visibility: 'hidden'
    }
  }, /*#__PURE__*/React.createElement("div", null)));
};
export default MyTable;