UNPKG

react-table-column-resizer

Version:

Place in between `td` tags to automatically add resizing functionality.

148 lines (147 loc) 5.35 kB
//Author: Bibin Antony, Nik M //https://github.com/bibinantony1998/react-table-column-resizer import React from 'react'; export default class ColumnResizer extends React.Component { constructor(props) { super(props); this.startDrag = this.startDrag.bind(this); this.endDrag = this.endDrag.bind(this); this.onMouseMove = this.onMouseMove.bind(this); this.dragging = false; this.mouseX = 0; this.startPos = 0; this.startWidthPrev = 0; this.lastDraggedWidth = 0; this.draggedCol = null; this.resizeRef = /*#__PURE__*/React.createRef(); } startDrag() { if (this.props.disabled) { return; } this.draggedCol = this.props.id; if (this.props.resizeStart && this.draggedCol === this.props.id) { this.props.resizeStart(); } this.dragging = true; this.startPos = this.mouseX; this.startWidthPrev = 0; if (this.resizeRef.current) { let prevSibling = this.resizeRef.current.previousSibling; if (prevSibling) { this.startWidthPrev = prevSibling.clientWidth; } } } endDrag() { if (this.props.disabled) { return; } this.dragging = false; if (this.props.resizeEnd && this.draggedCol === this.props.id) { this.props.resizeEnd(this.lastDraggedWidth); } this.draggedCol = null; } onMouseMove(e) { if (this.props.disabled) { return; } this.mouseX = e.touches ? e.touches[0].screenX : e.screenX; if (!this.dragging) { return; } const ele = this.resizeRef.current; const moveDiff = this.startPos - this.mouseX; let newPrev = this.startWidthPrev - moveDiff; if ((!this.props.minWidth || newPrev >= this.props.minWidth) && (!this.props.maxWidth || newPrev <= this.props.maxWidth)) { ele.previousSibling.style.width = newPrev + 'px'; ele.previousSibling.style.minWidth = newPrev + 'px'; ele.previousSibling.style.maxWidth = newPrev + 'px'; ele.previousSibling.style.setProperty('--column_resize_before_width', newPrev + 'px'); this.lastDraggedWidth = newPrev; } } componentDidMount() { const ele = this.resizeRef.current; if (ele) { if (this.props.defaultWidth) { ele.previousSibling.style.minWidth = this.props.defaultWidth + 'px'; ele.previousSibling.style.width = this.props.defaultWidth + 'px'; ele.previousSibling.style.maxWidth = this.props.defaultWidth + 'px'; ele.previousSibling.style.setProperty('--column_resize_before_width', this.props.defaultWidth + 'px'); } else if (this.props.minWidth) { ele.previousSibling.style.minWidth = this.props.minWidth + 'px'; ele.previousSibling.style.width = this.props.minWidth + 'px'; ele.previousSibling.style.maxWidth = this.props.minWidth + 'px'; ele.previousSibling.style.setProperty('--column_resize_before_width', this.props.minWidth + 'px'); } } if (this.props.disabled) { if (this.props.defaultWidth && ele) { ele.previousSibling.style.minWidth = this.props.defaultWidth + 'px'; ele.previousSibling.style.width = this.props.defaultWidth + 'px'; ele.previousSibling.style.maxWidth = this.props.defaultWidth + 'px'; ele.previousSibling.style.setProperty('--column_resize_before_width', this.props.defaultWidth + 'px'); } if (this.props.maxWidth && ele) { ele.previousSibling.style.maxWidth = this.props.maxWidth + 'px'; } return; } this.addEventListenersToDocument(); } componentWillUnmount() { if (this.props.disabled) { return; } this.removeEventListenersFromDocument(); } componentDidUpdate(prevProps, prevState) { if (prevProps.disabled && !this.props.disabled) { this.addEventListenersToDocument(); } if (!prevProps.disabled && this.props.disabled) { this.removeEventListenersFromDocument(); } } addEventListenersToDocument() { document.addEventListener('mousemove', this.onMouseMove); document.addEventListener('mouseup', this.endDrag); document.addEventListener("touchmove", this.onMouseMove); document.addEventListener("touchend", this.endDrag); } removeEventListenersFromDocument() { document.removeEventListener('mousemove', this.onMouseMove); document.removeEventListener('mouseup', this.endDrag); document.removeEventListener('touchmove', this.onMouseMove); document.removeEventListener('touchend', this.endDrag); } render() { var style = { userSelect: "none" }; if (!this.props.disabled) { style.cursor = 'ew-resize'; } if (this.props.className === "") { style.width = '6px'; style.backgroundColor = 'rgba(0, 0, 0, 0.1)'; } return /*#__PURE__*/React.createElement("th", { ref: this.resizeRef, style: style, disabled: this.props.disabled, rowSpan: this.props.rowSpan ? this.props.rowSpan : 1, colSpan: this.props.colSpan ? this.props.colSpan : 1, className: `column_resizer_own_class ${this.props.disabled ? "disabled_column_resize" : ""} ${this.props.className}`, onMouseDown: !this.props.disabled ? this.startDrag : null, onTouchStart: !this.props.disabled ? this.startDrag : null }); } } ColumnResizer.defaultProps = { disabled: false, minWidth: 0, className: "" };