diff --git a/components/apolloTable/component/DragSorted.tsx b/components/apolloTable/component/DragSorted.tsx index 53b66a74e6abb3175ab25461037f0d6be801132b..39806062a21a7b67fd3fa6aa6400b616ed2a60aa 100644 --- a/components/apolloTable/component/DragSorted.tsx +++ b/components/apolloTable/component/DragSorted.tsx @@ -19,23 +19,36 @@ const DragSorted = (props: any) => { const divider: any = document.querySelector('#divider'); // 左侧固定列分割线 const leftFixedHandleWrap: any = document.querySelector('#leftFixedHandleWrap'); + const rightFixedHandleWrap: any = document.querySelector('#rightFixedHandleWrap'); // 监听鼠标移动 const onMouseMove = useCallback((e) => { const tableRect = container.getBoundingClientRect(); const detaX = columnCopyDiv.getAttribute('data-deta-x'); // 所有列 const draggableColumns = document.querySelectorAll('.draggableColumn'); - const leftFixedHandleWrapRect = leftFixedHandleWrap.getBoundingClientRect(); + const leftFixedHandleWrapRectX = (leftFixedHandleWrap && leftFixedHandleWrap.getBoundingClientRect().x) || 0; + const rightFixedHandleWrapRectX = (rightFixedHandleWrap && rightFixedHandleWrap.getBoundingClientRect().x) || tableRect.right; const columnCopyDivRect = columnCopyDiv.getBoundingClientRect(); const columnCopyDivWidth = columnCopyDivRect.width; const columnCopyDivX = columnCopyDivRect.x; // 影子div中间点的x坐标 const columnCopyDivMid = columnCopyDivX + columnCopyDivWidth / 2; - + const left = e.clientX - tableRect.x - Number(detaX); + // 影子div随鼠标移动 + // 鼠标在左侧固定列与右侧固定列之间有效 + if (e.clientX > leftFixedHandleWrapRectX && e.clientX < rightFixedHandleWrapRectX) { + columnCopyDiv.style.left = `${left}px`; + } draggableColumns.forEach((dom) => { const domRect = dom.getBoundingClientRect(); - if (columnCopyDivMid > domRect.x && columnCopyDivMid < domRect.x + domRect.width) { + // 当前节点在左侧固定列与右侧固定列之间有效 + if ( + domRect.x > leftFixedHandleWrapRectX + && domRect.x < rightFixedHandleWrapRectX + && columnCopyDivMid > domRect.x + && columnCopyDivMid < domRect.x + domRect.width + ) { // 影子div中点在投放目标中 divider.style.left = `${domRect.x - tableRect.x}px`; // 收集投放目标的信息 @@ -46,24 +59,20 @@ const DragSorted = (props: any) => { } }); - const left = e.clientX - tableRect.x - Number(detaX); - // 影子div随鼠标移动 - columnCopyDiv.style.left = `${left}px`; - if (typeof onScroll === 'function') { let dir = ''; let step = 10; - // 设置鼠标超出表格左右两侧时的滚动事件 - if (e.clientX > tableRect.right - 30) { + // 设置鼠标超出表格左右固定列两侧时的滚动事件 + if (columnCopyDivX + columnCopyDivWidth > rightFixedHandleWrapRectX - 50) { dir = 'right'; step = 100; - } else if (e.clientX > tableRect.right - 100) { + } else if (columnCopyDivX + columnCopyDivWidth > rightFixedHandleWrapRectX - 100) { dir = 'right'; - step = 10; - } else if (e.clientX < leftFixedHandleWrapRect.x + 100) { + step = 30; + } else if (columnCopyDivX < leftFixedHandleWrapRectX + 100) { dir = 'left'; - step = 10; - } else if (e.clientX < leftFixedHandleWrapRect.x + 30) { + step = 30; + } else if (columnCopyDivX < leftFixedHandleWrapRectX + 50) { dir = 'left'; step = 100; } else { diff --git a/components/apolloTable/component/RightDragFixed.tsx b/components/apolloTable/component/RightDragFixed.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b9e60c697a76b9a1f44f5a8dbe42f49159cbe4e3 --- /dev/null +++ b/components/apolloTable/component/RightDragFixed.tsx @@ -0,0 +1,166 @@ +import React from 'react'; +import { ResizableBox } from 'react-resizable'; +import styles from './DragFixed.less'; + +const DragFixed = (props: any) => { + const { + initLeft, + initTop, + onResizeStart, + tableWidth, + showColumns, + columnWidth, + columns, + onResizeStop, + scrollbarWidth, + } = props; + // 表格 + const container: any = document.querySelector('#tableContainer'); + // 滑块wrap + const handleWrap: any = document.querySelector('#rightFixedHandleWrap'); + // 滑块 + const handle: any = document.querySelector('#rightFixedHandle'); + // 分割线wrap + const dividerWrap: any = document.querySelector('#dividerWrap'); + // 分割线 + const divider: any = document.querySelector('#divider'); + const onMouseEnterWrap = (e: any) => { + // 滑块wrap添加hovered样式 + handleWrap.classList.add(styles.hovered); + // 滑块初始化位置,显示 + handle.style.top = `${e.clientY}px`; + handle.style.opacity = 1; + }; + + const onMouseMoveWrap = (e: any) => { + // 滑块位置跟随鼠标上下移动 + handle.style.top = `${e.clientY}px`; + }; + + const onMouseLeaveWrap = () => { + // 滑块wrap移除hovered样式 + handleWrap.classList.remove(styles.hovered); + // 滑块隐藏 + handle.style.opacity = 0; + }; + + const onResizeStartHandle = (e: any) => { + if (typeof onResizeStart === 'function') { + onResizeStart(); + } + const originLeft = container.getBoundingClientRect().x || 0; + handleWrap.style.top = 0; + handleWrap.style.left = `${e.x - originLeft}px`; + }; + + const onResizeHandle = (e: any) => { + const containerRect: any = container.getBoundingClientRect(); + let inTableRight = containerRect.right - e.x; + // left不能超过表格一半宽度 + if (inTableRight > tableWidth / 2) { + inTableRight = tableWidth / 2; + } + let fixedWidth = 0; + let index = 0; + // 计算固定列宽度及索引 + for (let i = showColumns.length - 1; i >= 0; i--) { + fixedWidth += showColumns[i].width || columnWidth; + if (fixedWidth > inTableRight) { + index = i; + break; + } + } + let rightHandleLeft = fixedWidth - (showColumns[index].width || columnWidth); + // if (inTableRight > fixedWidth - (showColumns[index].width || columnWidth) / 2) { + // // left位于当前列中间偏右 + // rightHandleLeft = fixedWidth; + // } else { + // // left位于当前列中间偏左 + // rightHandleLeft = fixedWidth - (showColumns[index].width || columnWidth); + // } + // 拖动时显示分割线 + dividerWrap.style.display = 'block'; + // 分割线取列的边侧位置 + divider.style.left = `${containerRect.width - scrollbarWidth - rightHandleLeft}px`; + // 拖动线取鼠标位置 + handleWrap.style.left = `${containerRect.width - scrollbarWidth - inTableRight}px`; + // 滑动过程中滑块始终显示 + // 滑块wrap添加hovered样式 + handleWrap.classList.add(styles.hovered); + // 滑块初始化位置,显示 + handle.style.opacity = 1; + }; + + const onResizeStopHandle = () => { + // 当前固定列宽度为分割线的left + const fixedWidth: string = divider.style.left; + // 样式转数值 + const fixedWidthNum: string = fixedWidth.slice(0, -2); + // 分隔线wrap隐藏 + dividerWrap.style.display = 'none'; + // 滑块wrap移除hovered样式 + handleWrap.classList.remove(styles.hovered); + handleWrap.style.top = `${initTop}px`; + handleWrap.style.left = fixedWidth; + // 滑块隐藏 + handle.style.opacity = 0; + + let leftFixedWidth = 0; + const fixedCol: any = {}; + // 计算获取固定列 + for (let i = showColumns.length - 1; i >= 0; i--) { + leftFixedWidth += showColumns[i].width || columnWidth; + if (leftFixedWidth <= tableWidth + scrollbarWidth - Number(fixedWidthNum)) { + fixedCol[showColumns[i].columnName] = 1; + } else { + break; + } + } + const newColumns: any = []; + // 为固定列增加fixed属性 + columns.map((item: any) => { + if (fixedCol[item.columnName] === 1) { + item.fixed = 'right'; + } else { + if (item.fixed === 'right') { + item.fixed = ''; + } + } + newColumns.push(item); + }); + if (typeof onResizeStop === 'function') { + onResizeStop({ columns: newColumns }); + } + }; + + return ( +
+ { + e.stopPropagation(); + }} + /> + } + onResizeStart={onResizeStartHandle} + onResize={onResizeHandle} + onResizeStop={onResizeStopHandle} + draggableOpts={{ enableUserSelectHack: false }} + /> +
+ ); +}; +export default DragFixed; diff --git a/components/apolloTable/component/Table.less b/components/apolloTable/component/Table.less index 1146620bff234c6e61bdaf9a454a0cc8c6027022..4d8dfffc52b5ea84c9b46410acb592b8a44b7a3e 100644 --- a/components/apolloTable/component/Table.less +++ b/components/apolloTable/component/Table.less @@ -141,7 +141,7 @@ top: 0; bottom: 0; background: rgba(0,0,0,0.3); - z-index: 5; + //z-index: 5; //pointer-events: none; display: none; cursor: grab; diff --git a/components/apolloTable/component/Table.tsx b/components/apolloTable/component/Table.tsx index a80902e1db3b103804484b20286e59915fd7cffe..e51e95672faa0083b7d56bb4cfc4fecb63c7fa5d 100644 --- a/components/apolloTable/component/Table.tsx +++ b/components/apolloTable/component/Table.tsx @@ -11,6 +11,7 @@ import { TableProps, TableState, ColumnProps, RowProps } from './interface'; import Column from './Column'; import Cell from './Cell'; import LeftDragFixed from './DragFixed'; +import RightDragFixed from './RightDragFixed'; import DragSorted from './DragSorted'; import { getMergeClassName, getMergeStyle } from '../utils/utils'; import { Consumer } from './context'; @@ -266,8 +267,7 @@ export default class AirTable extends Component { // 拖拽自定义固定列前置动作 onResizeStartLeftDragFixed = () => { // 拖动开始,将表格滚动回最左端 - if (this.grid3 && this.grid4) { - this.grid3.scrollToPosition({ scrollLeft: 0 }); + if (this.grid4) { this.grid4.scrollToPosition({ scrollLeft: 0 }); } }; @@ -283,24 +283,33 @@ export default class AirTable extends Component { }, ); }; + // 拖拽自定义固定列前置动作 + onResizeStartRightDragFixed = () => { + // 拖动开始,将表格滚动回最右端 + const { columns } = this.state; + const showColumns = this.memoizeColumns(columns); + if (this.grid4) { + this.grid4.scrollToCell({ columnIndex: showColumns.length - 1 }); + } + }; onScrollHor = (direction: string, step: number) => { // 拖动超过视图范围,将表格左右滚动 if (this.grid4) { if (direction === 'right') { if (this.grid4.state.scrollLeft >= this.grid4.getTotalColumnsWidth() - this.state.tableWidth - 100) { - console.log('已经到最右侧了') + console.log('已经到最右侧了'); return; } this.grid4.scrollToPosition({ scrollLeft: this.grid4.state.scrollLeft + step }); } else { if (this.grid4.state.scrollLeft <= 0) { - console.log('已经到最左侧了') + console.log('已经到最左侧了'); return; } this.grid4.scrollToPosition({ scrollLeft: this.grid4.state.scrollLeft - step }); } } - } + }; // 渲染表头 renderHeaderCell = ( { showColumns, position }: { showColumns: ColumnProps[]; position?: string }, @@ -320,7 +329,15 @@ export default class AirTable extends Component { orderNo, } = showColumns[columnIndex]; return ( - + { const scrollbarWidth = scrollbarSize() || 0; const showColumns = this.memoizeColumns(columns); - const leftColumns = this.memoizeLeftColumns(columns); const rightColumns = this.memoizeRightColumns(columns); // 有隐藏列时,修正数据与列头不匹配问题 @@ -486,7 +502,6 @@ export default class AirTable extends Component { {({ onScroll, scrollLeft, scrollTop }: any) => { return ( -
{ className={styles.leftSideContainer} style={{ width: `${leftWidth}px`, - height: `${totalHeight - - scrollbarWidth + - headerHeight}px`, + height: `${totalHeight - scrollbarWidth + headerHeight}px`, }} > { @@ -599,8 +612,7 @@ export default class AirTable extends Component { // 中部表头
{ this.grid3 = dom; }} className={styles.headerGrid} - overscanColumnCount={ - overscanColumnCount - } - columnWidth={this.getColumnWidth.bind( - this, - { - columns: showColumns, - showColumns, - }, - )} + overscanColumnCount={overscanColumnCount} + columnWidth={this.getColumnWidth.bind(this, { + columns: showColumns, + showColumns, + })} columnCount={columnCount} width={width} rowHeight={headerHeight} rowCount={1} height={headerHeight} scrollLeft={scrollLeft} - cellRenderer={this.renderHeaderCell.bind( - this, - { - showColumns, - }, - )} + cellRenderer={this.renderHeaderCell.bind(this, { + showColumns, + })} />
} @@ -649,54 +653,39 @@ export default class AirTable extends Component { this.grid4 = dom; }} className={styles.centerGrid} - overscanColumnCount={ - overscanColumnCount - } - overscanRowCount={ - overscanRowCount - } - columnWidth={this.getColumnWidth.bind( - this, - { - columns: showColumns, - showColumns, - }, - )} + overscanColumnCount={overscanColumnCount} + overscanRowCount={overscanRowCount} + columnWidth={this.getColumnWidth.bind(this, { + columns: showColumns, + showColumns, + })} columnCount={columnCount} width={realWidth} rowHeight={rowHeight} rowCount={rowCount} - onScroll={( - ...arg: Array - ) => { + onScroll={(...arg: Array) => { onScroll(...arg); this.onScroll(arg[0]); }} scrollTop={scrollTop} height={totalHeight} - cellRenderer={this.renderBodyCell.bind( - this, - { - showColumns, - showData, - position: 'center', - }, - )} + cellRenderer={this.renderBodyCell.bind(this, { + showColumns, + showData, + position: 'center', + })} /> ) : ( - columnCount > 0 && - !loading && ( - - ) - )} + columnCount > 0 && + !loading && ( + + ) + )} } @@ -704,14 +693,26 @@ export default class AirTable extends Component { }} + {canFixed && ( + + )} {totalWidth > tableWidth && rightCount > 0 && (
{ @@ -785,10 +786,7 @@ export default class AirTable extends Component {
)}
-
+
{loading && (loadComp ? loadComp : )}