Commit b60f523c authored by zhangwenshuai's avatar zhangwenshuai

merge

parents 6b02a9e0 e8b42d8a
...@@ -90,6 +90,7 @@ const DragFixed = (props: any) => { ...@@ -90,6 +90,7 @@ const DragFixed = (props: any) => {
dividerWrap.style.display = 'none'; dividerWrap.style.display = 'none';
// 滑块wrap移除hovered样式 // 滑块wrap移除hovered样式
handleWrap.classList.remove(styles.hovered); handleWrap.classList.remove(styles.hovered);
handleWrap.style.top = `${initTop}px`;
handleWrap.style.left = fixedWidth; handleWrap.style.left = fixedWidth;
// 滑块隐藏 // 滑块隐藏
handle.style.opacity = 0; handle.style.opacity = 0;
......
@import '../common';
.draggableDiv{
cursor: move;
}
\ No newline at end of file
import React, { useCallback, useRef } from 'react';
import classNames from 'classnames';
const DragSorted = (props: any) => {
const {
className, style, columnName, orderNo, onDropFinish, onScroll,
} = props;
// 长按计时器
const timer: any = useRef(null);
// 表格滚动计时器
const timerInterval: any = useRef(null);
// 表格
const container: any = document.querySelector('#tableContainer');
// 拖拽列时的影子div
const columnCopyDiv: any = document.querySelector('#columnCopyDiv');
// 分割线wrap
const dividerWrap: any = document.querySelector('#dividerWrap');
// 分割线
const divider: any = document.querySelector('#divider');
// 左侧固定列分割线
const leftFixedHandleWrap: any = document.querySelector('#leftFixedHandleWrap');
// 监听鼠标移动
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 columnCopyDivRect = columnCopyDiv.getBoundingClientRect();
const columnCopyDivWidth = columnCopyDivRect.width;
const columnCopyDivX = columnCopyDivRect.x;
// 影子div中间点的x坐标
const columnCopyDivMid = columnCopyDivX + columnCopyDivWidth / 2;
draggableColumns.forEach((dom) => {
const domRect = dom.getBoundingClientRect();
if (columnCopyDivMid > domRect.x && columnCopyDivMid < domRect.x + domRect.width) {
// 影子div中点在投放目标中
divider.style.left = `${domRect.x - tableRect.x}px`;
// 收集投放目标的信息
const dropColumn = dom.getAttribute('data-column-name') || '';
const dropColumnOrder = dom.getAttribute('data-column-order') || '';
divider.setAttribute('data-drop-column', dropColumn);
divider.setAttribute('data-drop-order', dropColumnOrder);
}
});
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) {
dir = 'right';
step = 100;
} else if (e.clientX > tableRect.right - 100) {
dir = 'right';
step = 10;
} else if (e.clientX < leftFixedHandleWrapRect.x + 100) {
dir = 'left';
step = 10;
} else if (e.clientX < leftFixedHandleWrapRect.x + 30) {
dir = 'left';
step = 100;
} else {
dir = '';
}
if (dir) {
// 需要滚动,如果已有计时器,先清除再重新设置计时器
if (timerInterval.current) {
clearInterval(timerInterval.current);
}
timerInterval.current = setInterval(() => {
onScroll(dir, step);
}, 350);
} else {
// 需要停止,清除已有计时器
// eslint-disable-next-line no-lonely-if
if (timerInterval.current) {
clearInterval(timerInterval.current);
timerInterval.current = null;
}
}
}
}, []);
// 监听鼠标抬起
const onMouseUp = useCallback(() => {
// 清空计时器
if (timer.current) {
clearTimeout(timer.current);
timer.current = null;
}
if (timerInterval.current) {
clearInterval(timerInterval.current);
timerInterval.current = null;
}
// 移除全局事件
document.body.removeEventListener('mousemove', onMouseMove, false);
document.body.removeEventListener('mouseup', onMouseUp, false);
// 停止拖动时隐藏影子div
columnCopyDiv.style.display = 'none';
dividerWrap.style.display = 'none';
// 获取分割线上挂载的拖动列和投放列信息
const dragColumn = divider.getAttribute('data-drag-column');
const dragColumnOrder = divider.getAttribute('data-drag-order');
const dropColumn = divider.getAttribute('data-drop-column');
const dropColumnOrder = divider.getAttribute('data-drop-order');
// 没有列信息
if (!dragColumn || !dropColumn) {
return;
}
// 没有拖动
if (Number(dropColumnOrder) === Number(dragColumnOrder)) {
return;
}
// 拖动没有产生移动
if (Number(dropColumnOrder) - Number(dragColumnOrder) === 1) {
return;
}
// 拖动回调
if (typeof onDropFinish === 'function') {
onDropFinish(
{ columnName: dragColumn, orderNo: Number(dragColumnOrder) },
{ columnName: dropColumn, orderNo: Number(dropColumnOrder) },
);
}
}, [onDropFinish]);
// 监听鼠标按下
const onMouseDown = useCallback(
(e) => {
// 没有拖拽回调,默认不支持拖拽事件
if (!onDropFinish) {
return;
}
// 不是左键点击不作处理
if (e.button !== 0) {
return;
}
// 表格初始位置x点
const originLeft = container.getBoundingClientRect().x || 0;
// 拖动列矩形
const targetRect = e.currentTarget.getBoundingClientRect();
const curX = e.clientX;
// 500ms长按事件,表示想要拖拽
timer.current = setTimeout(() => {
// 影子div显示
columnCopyDiv.style.display = 'block';
// 影子div初始x位置=拖动列x点-表格x点
columnCopyDiv.style.left = `${targetRect.x - originLeft}px`;
// 影子div宽度=拖动列宽度
columnCopyDiv.style.width = `${targetRect.width}px`;
// 鼠标x点与拖动列x点之间的距离(记录下来方便后续使用)
const detaX = curX - targetRect.x;
columnCopyDiv.setAttribute('data-deta-x', String(detaX));
// 分割线初始位置为当前列
divider.style.left = `${targetRect.x - originLeft}px`;
dividerWrap.style.display = 'block';
// 给分割线设置拖动列信息,移除投放列信息
divider.setAttribute('data-drag-column', columnName);
divider.setAttribute('data-drag-order', orderNo);
divider.removeAttribute('data-drop-column');
divider.removeAttribute('data-drop-order');
// 全局添加监听鼠标移动和松开事件
document.body.addEventListener('mousemove', onMouseMove, false);
document.body.addEventListener('mouseup', onMouseUp, false);
}, 500);
// 阻止默认行为
e.preventDefault();
},
[columnName, orderNo],
);
return (
<div
className={classNames('draggableColumn', className)}
style={style}
onMouseDown={onMouseDown}
onMouseUp={onMouseUp}
data-column-name={columnName}
data-column-order={orderNo}
>
{props.children}
</div>
);
};
export default DragSorted;
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
border: 1px solid @borderColor; border: 1px solid @borderColor;
overflow: hidden;
&.scroll { &.scroll {
height: 100%; height: 100%;
.loading { .loading {
...@@ -114,8 +115,9 @@ ...@@ -114,8 +115,9 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: rgba(255, 255, 255, 0.4); background-color: rgba(255, 255, 255, 0.4);
z-index: 20; z-index: 4;
display: none; display: none;
pointer-events: none;
.widthHandle { .widthHandle {
position: absolute; position: absolute;
cursor: ew-resize; cursor: ew-resize;
...@@ -134,3 +136,13 @@ ...@@ -134,3 +136,13 @@
z-index: 1; z-index: 1;
background: #ececec; background: #ececec;
} }
.columnCopyDiv{
position: absolute;
top: 0;
bottom: 0;
background: rgba(0,0,0,0.3);
z-index: 5;
//pointer-events: none;
display: none;
cursor: grab;
}
...@@ -11,6 +11,7 @@ import { TableProps, TableState, ColumnProps, RowProps } from './interface'; ...@@ -11,6 +11,7 @@ import { TableProps, TableState, ColumnProps, RowProps } from './interface';
import Column from './Column'; import Column from './Column';
import Cell from './Cell'; import Cell from './Cell';
import LeftDragFixed from './DragFixed'; import LeftDragFixed from './DragFixed';
import DragSorted from './DragSorted';
import { getMergeClassName, getMergeStyle } from '../utils/utils'; import { getMergeClassName, getMergeStyle } from '../utils/utils';
import { Consumer } from './context'; import { Consumer } from './context';
...@@ -282,14 +283,31 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -282,14 +283,31 @@ export default class AirTable extends Component<TableProps, TableState> {
}, },
); );
}; };
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('已经到最右侧了')
return;
}
this.grid4.scrollToPosition({ scrollLeft: this.grid4.state.scrollLeft + step });
} else {
if (this.grid4.state.scrollLeft <= 0) {
console.log('已经到最左侧了')
return;
}
this.grid4.scrollToPosition({ scrollLeft: this.grid4.state.scrollLeft - step });
}
}
}
// 渲染表头 // 渲染表头
renderHeaderCell = ( renderHeaderCell = (
{ showColumns, position }: { showColumns: ColumnProps[]; position?: string }, { showColumns, position }: { showColumns: ColumnProps[]; position?: string },
{ columnIndex, key, style }: any, { columnIndex, key, style }: any,
) => { ) => {
if (showColumns.length === 0) return null; if (showColumns.length === 0) return null;
const { sortConfig, showIndex, rowSelection, dataSource } = this.props; const { sortConfig, showIndex, rowSelection, dataSource, onDragSorted } = this.props;
const { const {
columnType = 1, columnType = 1,
columnName, columnName,
...@@ -299,9 +317,10 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -299,9 +317,10 @@ export default class AirTable extends Component<TableProps, TableState> {
questionText, questionText,
icon, icon,
requiredFlag, requiredFlag,
orderNo,
} = showColumns[columnIndex]; } = showColumns[columnIndex];
return ( return (
<div className={styles.headerCell} key={key} style={style}> <DragSorted columnName={columnName} orderNo={orderNo} onDropFinish={onDragSorted} onScroll={this.onScrollHor} className={styles.headerCell} key={key} style={style}>
<ResizableBox <ResizableBox
width={style.width} width={style.width}
handle={ handle={
...@@ -334,7 +353,7 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -334,7 +353,7 @@ export default class AirTable extends Component<TableProps, TableState> {
required={requiredFlag} required={requiredFlag}
/> />
</ResizableBox> </ResizableBox>
</div> </DragSorted>
); );
}; };
...@@ -438,6 +457,8 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -438,6 +457,8 @@ export default class AirTable extends Component<TableProps, TableState> {
const { overscanColumnCount, overscanRowCount, rowHeight, headerHeight, columnWidth } = this.config; const { overscanColumnCount, overscanRowCount, rowHeight, headerHeight, columnWidth } = this.config;
const scrollbarWidth = scrollbarSize() || 0; const scrollbarWidth = scrollbarSize() || 0;
const showColumns = this.memoizeColumns(columns); const showColumns = this.memoizeColumns(columns);
const leftColumns = this.memoizeLeftColumns(columns); const leftColumns = this.memoizeLeftColumns(columns);
const rightColumns = this.memoizeRightColumns(columns); const rightColumns = this.memoizeRightColumns(columns);
// 有隐藏列时,修正数据与列头不匹配问题 // 有隐藏列时,修正数据与列头不匹配问题
...@@ -451,13 +472,8 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -451,13 +472,8 @@ export default class AirTable extends Component<TableProps, TableState> {
const rowCount = showData.length; const rowCount = showData.length;
const leftWidth = this.memoizeLeftWidth(leftColumns, showColumns); const leftWidth = this.memoizeLeftWidth(leftColumns, showColumns);
const rightWidth = this.memoizeLeftWidth(rightColumns, showColumns); const rightWidth = this.memoizeLeftWidth(rightColumns, showColumns);
// let totalHeight: number = rowCount * rowHeight;
let totalHeight: number = tableHeight - headerHeight; let totalHeight: number = tableHeight - headerHeight;
const { totalWidth } = this.memoizeTotalWidth(showColumns); const { totalWidth } = this.memoizeTotalWidth(showColumns);
// if (rowCount > 0 && totalWidth > tableWidth) {
// // totalHeight = rowCount * rowHeight + scrollbarWidth;
// totalHeight = tableHeight + scrollbarWidth;
// }
let realWidth = tableWidth; let realWidth = tableWidth;
let paddingRight = 0; let paddingRight = 0;
if (rowCount > 0 && rowCount * rowHeight > totalHeight) { if (rowCount > 0 && rowCount * rowHeight > totalHeight) {
...@@ -470,6 +486,7 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -470,6 +486,7 @@ export default class AirTable extends Component<TableProps, TableState> {
<ScrollSync> <ScrollSync>
{({ onScroll, scrollLeft, scrollTop }: any) => { {({ onScroll, scrollLeft, scrollTop }: any) => {
return ( return (
<div <div
className={ className={
this.props.onScroll this.props.onScroll
...@@ -489,7 +506,9 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -489,7 +506,9 @@ export default class AirTable extends Component<TableProps, TableState> {
className={styles.leftSideContainer} className={styles.leftSideContainer}
style={{ style={{
width: `${leftWidth}px`, width: `${leftWidth}px`,
height: `${totalHeight - scrollbarWidth + headerHeight}px`, height: `${totalHeight -
scrollbarWidth +
headerHeight}px`,
}} }}
> >
{ {
...@@ -580,7 +599,8 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -580,7 +599,8 @@ export default class AirTable extends Component<TableProps, TableState> {
// 中部表头 // 中部表头
<div <div
style={{ style={{
backgroundColor: 'rgba(246, 246, 246, 1)', backgroundColor:
'rgba(246, 246, 246, 1)',
height: headerHeight, height: headerHeight,
width, width,
}} }}
...@@ -590,20 +610,28 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -590,20 +610,28 @@ export default class AirTable extends Component<TableProps, TableState> {
this.grid3 = dom; this.grid3 = dom;
}} }}
className={styles.headerGrid} className={styles.headerGrid}
overscanColumnCount={overscanColumnCount} overscanColumnCount={
columnWidth={this.getColumnWidth.bind(this, { overscanColumnCount
columns: showColumns, }
showColumns, columnWidth={this.getColumnWidth.bind(
})} this,
{
columns: showColumns,
showColumns,
},
)}
columnCount={columnCount} columnCount={columnCount}
width={width} width={width}
rowHeight={headerHeight} rowHeight={headerHeight}
rowCount={1} rowCount={1}
height={headerHeight} height={headerHeight}
scrollLeft={scrollLeft} scrollLeft={scrollLeft}
cellRenderer={this.renderHeaderCell.bind(this, { cellRenderer={this.renderHeaderCell.bind(
showColumns, this,
})} {
showColumns,
},
)}
/> />
</div> </div>
} }
...@@ -612,11 +640,6 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -612,11 +640,6 @@ export default class AirTable extends Component<TableProps, TableState> {
<div <div
style={{ style={{
height: totalHeight, height: totalHeight,
// height: height - headerHeight,
// minHeight:
// !dataSource || dataSource.length === 0
// ? '300px'
// : 'auto',
width: tableWidth, width: tableWidth,
}} }}
> >
...@@ -626,39 +649,54 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -626,39 +649,54 @@ export default class AirTable extends Component<TableProps, TableState> {
this.grid4 = dom; this.grid4 = dom;
}} }}
className={styles.centerGrid} className={styles.centerGrid}
overscanColumnCount={overscanColumnCount} overscanColumnCount={
overscanRowCount={overscanRowCount} overscanColumnCount
columnWidth={this.getColumnWidth.bind(this, { }
columns: showColumns, overscanRowCount={
showColumns, overscanRowCount
})} }
columnWidth={this.getColumnWidth.bind(
this,
{
columns: showColumns,
showColumns,
},
)}
columnCount={columnCount} columnCount={columnCount}
width={realWidth} width={realWidth}
rowHeight={rowHeight} rowHeight={rowHeight}
rowCount={rowCount} rowCount={rowCount}
onScroll={(...arg: Array<Object>) => { onScroll={(
...arg: Array<Object>
) => {
onScroll(...arg); onScroll(...arg);
this.onScroll(arg[0]); this.onScroll(arg[0]);
}} }}
scrollTop={scrollTop} scrollTop={scrollTop}
height={totalHeight} height={totalHeight}
cellRenderer={this.renderBodyCell.bind(this, { cellRenderer={this.renderBodyCell.bind(
showColumns, this,
showData, {
position: 'center', showColumns,
})} showData,
position: 'center',
},
)}
/> />
) : ( ) : (
columnCount > 0 && columnCount > 0 &&
!loading && ( !loading && (
<Empty <Empty
className={styles.defaultEmpty} className={
description={ styles.defaultEmpty
noDataPlaceholder || locale.empty }
} description={
/> noDataPlaceholder ||
) locale.empty
)} }
/>
)
)}
</div> </div>
} }
</div> </div>
...@@ -671,7 +709,9 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -671,7 +709,9 @@ export default class AirTable extends Component<TableProps, TableState> {
className={styles.rightSideContainer} className={styles.rightSideContainer}
style={{ style={{
width: `${rightWidth}px`, width: `${rightWidth}px`,
height: `${totalHeight - scrollbarWidth + headerHeight}px`, height: `${totalHeight -
scrollbarWidth +
headerHeight}px`,
}} }}
> >
{ {
...@@ -745,7 +785,10 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -745,7 +785,10 @@ export default class AirTable extends Component<TableProps, TableState> {
</div> </div>
)} )}
<div className={styles.fillHandleWrapper} /> <div className={styles.fillHandleWrapper} />
<div className={styles.loading} style={{ top: `${totalHeight / 2}px` }}> <div
className={styles.loading}
style={{ top: `${totalHeight / 2}px` }}
>
{loading && (loadComp ? loadComp : <Spin />)} {loading && (loadComp ? loadComp : <Spin />)}
</div> </div>
<div <div
...@@ -763,6 +806,7 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -763,6 +806,7 @@ export default class AirTable extends Component<TableProps, TableState> {
}} }}
/> />
</div> </div>
<div id="columnCopyDiv" className={styles.columnCopyDiv} draggable={true} />
</div> </div>
); );
}} }}
......
...@@ -84,11 +84,11 @@ class AirTable extends React.Component<CommonProps, CommonState> { ...@@ -84,11 +84,11 @@ class AirTable extends React.Component<CommonProps, CommonState> {
showCondition, showCondition,
canFixed, canFixed,
id, id,
onDragSorted,
} = this.props; } = this.props;
const sortConfig = const sortConfig = operateConfig
operateConfig && && operateConfig.menusGroup
operateConfig.menusGroup && && operateConfig.menusGroup.find((item: any) => {
operateConfig.menusGroup.find((item: any) => {
return item.type === 'sort'; return item.type === 'sort';
}); });
return ( return (
...@@ -139,6 +139,7 @@ class AirTable extends React.Component<CommonProps, CommonState> { ...@@ -139,6 +139,7 @@ class AirTable extends React.Component<CommonProps, CommonState> {
contentMenu={contentMenu} contentMenu={contentMenu}
loadComp={loadComp} loadComp={loadComp}
canFixed={canFixed} canFixed={canFixed}
onDragSorted={onDragSorted}
/> />
</div> </div>
</div> </div>
......
...@@ -76,6 +76,7 @@ export interface TableProps extends LoadConfigProps { ...@@ -76,6 +76,7 @@ export interface TableProps extends LoadConfigProps {
canFixed?: boolean;// 是否可以拖拽自定义固定列 canFixed?: boolean;// 是否可以拖拽自定义固定列
canSorted?: boolean;// 是否可以拖拽自定义列排序 canSorted?: boolean;// 是否可以拖拽自定义列排序
canResized?: boolean;// 是否可以拖拽自定义列伸缩 canResized?: boolean;// 是否可以拖拽自定义列伸缩
onDragSorted?:Function;// 拖拽更改列排序回调
} }
export interface TableState { export interface TableState {
columns: ColumnProps[]; columns: ColumnProps[];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment