68 lines
1.7 KiB
TypeScript
68 lines
1.7 KiB
TypeScript
import type { MouseEvent, ReactNode } from 'react';
|
|
import type { ColumnType } from 'antd/es/table';
|
|
|
|
export const MIN_COL_WIDTH = 48;
|
|
export const MAX_COL_WIDTH = 960;
|
|
|
|
export function clampColWidth(n: number): number {
|
|
return Math.min(MAX_COL_WIDTH, Math.max(MIN_COL_WIDTH, Math.round(n)));
|
|
}
|
|
|
|
export function beginColumnResize(
|
|
e: MouseEvent,
|
|
startWidth: number,
|
|
onMove: (width: number) => void,
|
|
onEnd: (width: number) => void,
|
|
) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
const startX = e.clientX;
|
|
let latest = clampColWidth(startWidth);
|
|
let moved = false;
|
|
document.body.classList.add('admin-col-resizing');
|
|
|
|
const onMouseMove = (ev: globalThis.MouseEvent) => {
|
|
moved = true;
|
|
latest = clampColWidth(startWidth + ev.clientX - startX);
|
|
onMove(latest);
|
|
};
|
|
const onMouseUp = () => {
|
|
document.removeEventListener('mousemove', onMouseMove);
|
|
document.removeEventListener('mouseup', onMouseUp);
|
|
document.body.classList.remove('admin-col-resizing');
|
|
if (moved) onEnd(latest);
|
|
};
|
|
document.addEventListener('mousemove', onMouseMove);
|
|
document.addEventListener('mouseup', onMouseUp);
|
|
}
|
|
|
|
export function withResizeTitle<T>(
|
|
title: ColumnType<T>['title'],
|
|
onMouseDown: (e: MouseEvent) => void,
|
|
): ColumnType<T>['title'] {
|
|
const handle: ReactNode = (
|
|
<span
|
|
role="separator"
|
|
aria-orientation="vertical"
|
|
aria-label="拖动调整列宽"
|
|
className="admin-col-resize-handle"
|
|
onClick={(ev) => ev.stopPropagation()}
|
|
onMouseDown={onMouseDown}
|
|
/>
|
|
);
|
|
if (typeof title === 'function') {
|
|
return (props) => (
|
|
<>
|
|
{title(props)}
|
|
{handle}
|
|
</>
|
|
);
|
|
}
|
|
return (
|
|
<>
|
|
{title}
|
|
{handle}
|
|
</>
|
|
);
|
|
}
|