import { TpTable } from "./tp-table"; export default class ColumnMover { constructor(wrap, handleSelector) { this._handleSelector = handleSelector; this._mouseDown = this._mouseDown.bind(this); this._dragging = this._dragging.bind(this); this._draggingEnd = this._draggingEnd.bind(this); this._trackingStarted = false; // Amount of pixels the handle must be moved before its registered as a tracking gesture. this.threshold = 5; wrap.addEventListener('mousedown', this._mouseDown, true); } _mouseDown(e) { const handle = e.composedPath().find(node => node.matches && node.matches(this._handleSelector)); if (!handle) return; e.stopPropagation(); e.preventDefault(); this._cHandle = handle; this._startX = e.pageX; this._watchDrag(); } _watchDrag() { window.addEventListener('mousemove', this._dragging); window.addEventListener('mouseup', this._draggingEnd); } _stopWatchDrag() { window.removeEventListener('mousemove', this._dragging); window.removeEventListener('mouseup', this._draggingEnd); } _dragging(e) { if (this._trackingStarted === false && Math.abs(e.pageX - this._startX) >= this.threshold) { this._trackingStarted = true; this._showClone(); this._clearSelection(); } if (this._trackingStarted === true) { this._positionClone(e.pageX, e.pageY); this._cHandle.dispatchEvent(new CustomEvent('track-move', { detail: { target: this._cHandle, state: 'track', x: e.pageX, y: e.pageX }, bubbles: true, composed: true })); } } _draggingEnd(e) { this._trackingStarted = false; this._cHandle.dispatchEvent(new CustomEvent('track-move', { detail: { target: this._cHandle, state: 'end', x: e.pageX, y: e.pageX }, bubbles: true, composed: true })); this._stopWatchDrag(); this._cHandle = null; this._startX = 0; this._clearSelection(); this._clone.remove(); this._clone = null; if (this._indicator) { this._indicator.remove(); this._indicator = null; } } _clearSelection() { const sel = window.getSelection ? window.getSelection() : document.selection; if (sel) { if (sel.removeAllRanges) { sel.removeAllRanges(); } else if (sel.empty) { sel.empty(); } } } /** * Show indicator to visualize where a column would be dropped after releasing the mouse. * @param {number} x X-coordinate * @param {number} y Y-coordinate */ showIndicator(x, y) { if (!this._indicator) { const icon = document.createElement('tp-icon'); icon.icon = TpTable.downIcon; icon.style.position = 'fixed'; icon.style.left = '0px'; icon.style.right = '0px'; icon.style.zIndex = '100000'; document.body.appendChild(icon); this._indicator = icon; } const rect = this._indicator.getBoundingClientRect(); this._indicator.style.transform = `translate(${x - ((rect.right - rect.left) / 2)}px, ${y - rect.height}px)`; } _showClone() { const div = document.createElement('div'); div.style.background = 'rgba(255, 255, 255, 0.6)'; div.style.border = 'solid 1px rgba(255, 255, 255, 0.8)'; div.style.padding = '5px 10px'; div.style.borderRadius = '2px'; div.style.position = 'fixed'; div.style.zIndex = '99999'; div.style.left = '0px'; div.style.top = '0px'; div.style.display = 'flex'; div.style.alignItems = 'center'; div.style.justifyContent = 'center'; div.innerHTML = this._cHandle.column.label; this._clone = div; document.body.appendChild(div); } _positionClone(x, y) { this._clone.style.transform = `translate(${x + 10}px, ${y}px)`; } }