in src/data-table/data-table.tsx [242:397]
function Header(props: HeaderProps) {
const [css, theme] = useStyletron();
const [startResizePos, setStartResizePos] = React.useState(0);
const [endResizePos, setEndResizePos] = React.useState(0);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const headerCellRef = React.useRef<any>(null);
const RULER_OFFSET = 2;
const isResizingThisColumn = props.resizeIndex === props.index;
const isResizing = props.resizeIndex >= 0;
// @ts-ignore
function getPositionX(el) {
if (__BROWSER__) {
const rect = el.getBoundingClientRect();
return rect.left + window.scrollX;
}
return 0;
}
React.useLayoutEffect(() => {
function handleMouseMove(event: MouseEvent) {
if (isResizingThisColumn) {
event.preventDefault();
if (headerCellRef.current) {
const left = getPositionX(headerCellRef.current);
const width = event.clientX - left - 5;
const max = Math.ceil(props.resizeMaxWidth);
const min = Math.ceil(props.resizeMinWidth);
if (min === max) {
return;
}
if (width >= min && width <= max) {
setEndResizePos(event.clientX - RULER_OFFSET);
}
if (width < min) {
setEndResizePos(left + min - RULER_OFFSET);
}
if (width > max) {
setEndResizePos(max - width - RULER_OFFSET);
}
}
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function handleMouseUp(event: MouseEvent) {
props.onResize(props.index, endResizePos - startResizePos);
props.onResizeIndexChange(-1);
setStartResizePos(0);
setEndResizePos(0);
}
if (__BROWSER__) {
if (isResizingThisColumn) {
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
}
}
return () => {
if (__BROWSER__) {
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
}
};
}, [
isResizingThisColumn,
setEndResizePos,
setStartResizePos,
setEndResizePos,
props.onResize,
props.onResizeIndexChange,
props.index,
endResizePos,
startResizePos,
headerCellRef.current,
]);
return (
<React.Fragment>
<HeaderCell
ref={headerCellRef}
index={props.index}
sortable={props.isSortable}
isHovered={!isResizing && props.hoverIndex === props.index}
isSelectable={props.isSelectable && props.index === 0}
isSelectedAll={props.isSelectedAll}
isSelectedIndeterminate={props.isSelectedIndeterminate}
onMouseEnter={() => {
if (!isResizing) {
props.onMouseEnter(props.index);
}
}}
onMouseLeave={() => {
if (!isResizing) {
props.onMouseLeave();
}
}}
onSelectAll={props.onSelectMany}
onSelectNone={props.onSelectNone}
onSort={props.onSort}
// @ts-ignore
sortDirection={props.sortIndex === props.index ? props.sortDirection : null}
title={props.columnTitle}
/>
{props.resizableColumnWidths && (
<div
className={css({
position: 'relative',
display: 'flex',
alignItems: 'center',
})}
>
<div
role="presentation"
onMouseDown={(event) => {
props.onResizeIndexChange(props.index);
const x = getPositionX(event.target);
setStartResizePos(x);
setEndResizePos(x);
}}
className={css({
// @ts-ignore
backgroundColor: isResizingThisColumn ? theme.colors.contentPrimary : null,
cursor: 'ew-resize',
position: 'absolute',
height: '100%',
width: '3px',
':hover': {
backgroundColor: theme.colors.contentPrimary,
},
})}
style={{
right: `${(RULER_OFFSET + endResizePos - startResizePos) * -1}px`,
}}
>
{isResizingThisColumn && (
<div
className={css({
backgroundColor: theme.colors.contentPrimary,
position: 'absolute',
height: `${props.tableHeight}px`,
right: '1px',
width: '1px',
})}
/>
)}
</div>
</div>
)}
</React.Fragment>
);
}