/** @license Copyright (c) 2023 trading_peter */ import { LitElement, html, css } from 'lit'; class TpVSplitter extends LitElement { static get styles() { return [ css` :host { display: grid; grid-template-columns: 1fr var(--tp-splitter-width, 5px) 1fr; } :host([lefthidden]), :host([righthidden]) { grid-template-columns: 1fr !important; } [hidden] { display: none !important; } #left, #right { position: relative; overflow: hidden; } #splitter { background: var(--tp-splitter-line-color, #3b3b3b); cursor: col-resize; opacity: 1; } #splitter:hover { background: var(--tp-splitter-line-color-hover, #007dd1); opacity: 0.5; } ` ]; } render() { const { leftHidden, rightHidden } = this; return html`
`; } static get properties() { return { leftHidden: { type: Boolean }, rightHidden: { type: Boolean }, dragging: { type: Boolean }, minSideWidth: { type: Number }, lateResize: { type: Boolean }, initialLeftWidth: { type: String }, }; } constructor() { super(); this._disableDrag = this._disableDrag.bind(this); this._resize = this._resize.bind(this); this._bufferedDelta = 0; } get left() { return this.shadowRoot.querySelector('#left'); } get right() { return this.shadowRoot.querySelector('#right'); } get splitter() { return this.shadowRoot.querySelector('#splitter') } firstUpdated() { if (this.initialLeftWidth) { this.style.gridTemplateColumns = `${this.initialLeftWidth} var(--tp-splitter-width, 5px) 1fr`; } } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('mouseup', this._disableDrag) document.removeEventListener('mousemove', this._resize); document.body.style['userSelect'] = ''; } _enableDrag(e) { document.addEventListener('mouseup', this._disableDrag) document.addEventListener('mousemove', this._resize); document.body.style['userSelect'] = 'none'; this._startX = e.clientX; this._leftWidth = this.left.offsetWidth; this.dragging = true; } _disableDrag() { document.removeEventListener('mouseup', this._disableDrag) document.removeEventListener('mousemove', this._resize); document.body.style['userSelect'] = ''; this.dragging = false; let finalWidth; if (this.lateResize && this._bufferedDelta) { finalWidth = this._leftWidth + this._bufferedDelta; this.splitter.style.transform = ''; this.style.gridTemplateColumns = `${finalWidth}px 5px 1fr`; this._bufferedDelta = 0; } else { finalWidth = this.left.offsetWidth; } this.dispatchEvent(new CustomEvent('resize-done', { detail: finalWidth, bubbles: true, composed: true })); } _resize(e) { const delta = e.clientX - this._startX; const totalWidth = this.offsetWidth; const minWidth = this.minSideWidth || 0; const splitterWidth = parseInt(getComputedStyle(this).getPropertyValue('--tp-splitter-width')) || 5; // Calculate restricted delta const maxDelta = totalWidth - splitterWidth - minWidth - this._leftWidth; const minDelta = -this._leftWidth + minWidth; const restrictedDelta = Math.max(minDelta, Math.min(delta, maxDelta)); if (this.lateResize) { this._bufferedDelta = restrictedDelta; this.splitter.style.transform = `translateX(${this._bufferedDelta}px)`; return; } const newLeftWidth = this._leftWidth + restrictedDelta; this.style.gridTemplateColumns = `${newLeftWidth}px ${splitterWidth}px 1fr`; this.dispatchEvent(new CustomEvent('resized', { detail: null, bubbles: true, composed: true })); } } window.customElements.define('tp-vsplitter', TpVSplitter);