/* part: split (behaviour) — the drag half of split.css.
*
* Derived from common/ui/src/components/SplitPane.vue's pointer handlers. Plain
* DOM, no framework, no build step, no imports: a (or paste it; it self-starts)
*
*
*
* data-split marks the element. Required.
* data-size (default 1) initial size of the anchored pane
* data-mode ratio | px (default ratio)
* data-anchor first | second (default first)
* data-min / data-max clamps, in the same unit as data-size
*
* Direction comes from the `horizontal` / `vertical` class, so CSS and JS
* cannot disagree about it.
*/
(function () {
'use strict'
function setup(root) {
var divider = root.querySelector(':scope > .split-divider')
if (!divider) return // no divider: a fixed split, deliberately
var first = root.querySelector(':scope > .split-first')
var second = root.querySelector(':scope > .split-second')
if (!first || !second) return
var horizontal = !root.classList.contains('vertical')
var mode = root.dataset.mode === 'px' ? 'px' : 'ratio'
var anchor = root.dataset.anchor === 'second' ? 'second' : 'first'
var size = parseFloat(root.dataset.size)
if (isNaN(size)) size = 1
var min = parseFloat(root.dataset.min)
if (isNaN(min)) min = mode === 'px' ? 0 : 0.1
var max = parseFloat(root.dataset.max)
if (isNaN(max)) max = mode === 'px' ? Infinity : 10
var sized = anchor === 'second' ? second : first
var flexed = anchor === 'second' ? first : second
var dragging = false
var startPos = 0
function apply() {
flexed.style.flex = '1'
if (mode === 'px') {
sized.style.flex = '0 0 auto'
sized.style[horizontal ? 'width' : 'height'] = size + 'px'
} else {
sized.style.flex = String(size)
}
}
divider.addEventListener('pointerdown', function (e) {
dragging = true
startPos = horizontal ? e.clientX : e.clientY
divider.classList.add('dragging')
divider.setPointerCapture(e.pointerId)
})
divider.addEventListener('pointermove', function (e) {
if (!dragging) return
var pos = horizontal ? e.clientX : e.clientY
var delta = pos - startPos
startPos = pos
// Dragging right/down grows the first pane. When the SECOND pane is the
// anchored one, that same gesture must shrink it, so invert.
if (anchor === 'second') delta = -delta
// Ratio mode is unitless, so pixels are scaled into it. The two constants
// are the SFC's, kept rather than re-derived: they are what the existing
// panes were tuned against, and vertical drags cover less travel.
var step = mode === 'px' ? delta : delta * (horizontal ? 0.01 : 0.02)
size = Math.max(min, Math.min(max, size + step))
apply()
})
function end(e) {
if (!dragging) return
dragging = false
divider.classList.remove('dragging')
if (e && e.pointerId !== undefined && divider.hasPointerCapture(e.pointerId)) {
divider.releasePointerCapture(e.pointerId)
}
}
divider.addEventListener('pointerup', end)
divider.addEventListener('pointercancel', end)
apply()
}
function start() {
var panes = document.querySelectorAll('[data-split]')
for (var i = 0; i < panes.length; i++) setup(panes[i])
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', start)
} else {
start()
}
})()