UNPKG

uiik

Version:

A UI interactions kit includes draggable, splittable, rotatable, selectable, etc.

1,149 lines (1,138 loc) 144 kB
/** * uiik v1.4.2 * A UI interactions kit includes draggable, splittable, rotatable, selectable, etc. * https://github.com/holyhigh2/uiik * c) 2021-2026 @holyhigh2 may be freely distributed under the MIT license */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('myfx/collection'), require('myfx/is'), require('myfx/object'), require('myfx/tree'), require('myfx'), require('myfx/array'), require('myfx/string'), require('myfx/utils')) : typeof define === 'function' && define.amd ? define(['exports', 'myfx/collection', 'myfx/is', 'myfx/object', 'myfx/tree', 'myfx', 'myfx/array', 'myfx/string', 'myfx/utils'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.uiik = {}, global.collection, global.is, global.object, global.tree, global.myfx, global.array, global.string, global.utils)); })(this, (function (exports, collection, is, object, tree, myfx, array, string, utils) { 'use strict'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ function __classPrivateFieldGet(receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); } function __classPrivateFieldSet(receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; const UtMap = new WeakMap(); class UiiTransform { constructor(el, useTransform = true) { this.angle = 0; this.el = el; this.useTransform = useTransform; this.normalize(el); UtMap.set(el, this); } normalize(el) { let { offx, offy } = normalize(el || this.el, this.useTransform); this.offx = offx * -1; this.offy = offy * -1; return this; } moveTo(x, y) { this.x = x; this.y = y; (this.useTransform ? transformMoveTo : moveTo)(this.el, this.x + this.offx, this.y + this.offy); } moveToX(x) { this.x = x; (this.useTransform ? transformMoveTo : moveTo)(this.el, this.x + this.offx, NaN); } moveToY(y) { this.y = y; (this.useTransform ? transformMoveTo : moveTo)(this.el, NaN, this.y + this.offy); } rotateTo(deg, cx, cy) { this.angle = deg; rotateTo(this.el, deg, cx, cy); } } function normalize(el, useTransform) { const style = window.getComputedStyle(el); let offx = 0, offy = 0; let x = 0, y = 0; let mx = 0, my = 0; if (el instanceof HTMLElement) { x = parseFloat(style.left) || 0; y = parseFloat(style.top) || 0; mx = parseFloat(style.marginLeft) || 0; my = parseFloat(style.marginTop) || 0; } else { x = parseFloat(object.get(el, "x.baseVal.value") || object.get(el, "cx.baseVal.value")) || 0; y = parseFloat(object.get(el, "y.baseVal.value") || object.get(el, "cy.baseVal.value")) || 0; } if (useTransform) { (offx = x), (offy = y); } else { (offx = 0), (offy = 0); } return { offx: offx + mx, offy: offy + my }; } function wrapper(el, useTransform = true) { let ut = UtMap.get(el); if (ut) return ut.normalize(el); return new UiiTransform(el, useTransform); } function transformMove(transofrmStr, x, y, unit = false) { if (!is.isNumber(x) || is.isNaN(x)) { return (`translateY(${y}${unit ? "px" : ""}) ` + transofrmStr.replace(/translateY\([^)]+?\)/, "").trim()); } if (!is.isNumber(y) || is.isNaN(x)) { return (`translateX(${x}${unit ? "px" : ""}) ` + transofrmStr.replace(/translateX\([^)]+?\)/, "").trim()); } return (`translate(${x}${unit ? "px" : ""},${y}${unit ? "px" : ""}) ` + transofrmStr.replace(/translate\([^)]+?\)/, "").trim()); } function getTranslate(el) { let xVal = NaN, yVal = NaN; let transformStr = ""; if (el instanceof SVGGraphicsElement) { transformStr = el.getAttribute("transform") || ""; if (!transformStr) { xVal = parseFloat(object.get(el, "x.baseVal.value") || object.get(el, "cx.baseVal.value")) || 0; yVal = parseFloat(object.get(el, "y.baseVal.value") || object.get(el, "cy.baseVal.value")) || 0; } } else { let style = el.style; transformStr = style.transform || ""; } EXP_GET_TRANSLATE.lastIndex = 0; const xy = EXP_GET_TRANSLATE.exec(transformStr); if (xy && xy.groups) { xVal = parseFloat(xy.groups.x); yVal = parseFloat(xy.groups.y); } else { EXP_GET_TRANSLATE_XY.lastIndex = 0; const xy = EXP_GET_TRANSLATE_XY.exec(transformStr); if (xy && xy.groups) { if (xy.groups.dir == "X") { xVal = parseFloat(xy.groups.v); } else { yVal = parseFloat(xy.groups.v); } } } return { x: xVal, y: yVal }; } function moveTo(el, x, y) { if (el instanceof SVGGraphicsElement) { if (x) el.setAttribute("x", x + ""); if (y) el.setAttribute("y", y + ""); } else { let style = el.style; if (x) style.left = x + "px"; if (y) style.top = y + "px"; } } function transformMoveTo(el, x, y) { if (el instanceof SVGGraphicsElement) { el.setAttribute("transform", transformMove(el.getAttribute("transform") || "", x || 0, y || 0)); } else { let style = el.style; style.transform = transformMove(style.transform || "", x || 0, y || 0, true); } } const EXP_GET_TRANSLATE = /translate\(\s*(?<x>[\d.-]+)\D*,\s*(?<y>[\d.-]+)\D*\)/gim; const EXP_GET_TRANSLATE_XY = /translate(?<dir>X|Y)\(\s*(?<v>[\d.-]+)\D*\)/gim; function moveBy(el, x, y) { const xy = getTranslate(el); if (el instanceof SVGGraphicsElement) { el.setAttribute("transform", transformMove(el.getAttribute("transform") || "", xy.x + x, xy.y + y)); } else { let style = el.style; style.transform = transformMove(style.transform || "", xy.x + x, xy.y + y, true); } } function rotateTo(el, deg, cx, cy) { if (el instanceof SVGGraphicsElement) { let transformStr = el.getAttribute("transform") || ""; let originPos = is.isDefined(cx) && is.isDefined(cy); let origin = ""; if (originPos) { if (el.x instanceof SVGAnimatedLength) { cx += el.x.animVal.value; cy += el.y.animVal.value; } else if (el.cx instanceof SVGAnimatedLength) { cx += el.cx.animVal.value; cy += el.cy.animVal.value; } origin = `,${cx},${cy}`; } transformStr = transformStr.replace(/rotate\([^)]+?\)/, "") + ` rotate(${deg}${origin})`; el.setAttribute("transform", transformStr); } else { let style = el.style; style.transform = style.transform .replace(/rotate\([^)]+?\)/, "") .replace(/rotateZ\([^)]+?\)/, "") + " rotateZ(" + deg + "deg)"; } } const ONE_ANG = Math.PI / 180; const ONE_RAD = 180 / Math.PI; const THRESHOLD = 3; function getBox(child, parent) { const rect = child.getBoundingClientRect(); const rs = { x: 0, y: 0, w: rect.width, h: rect.height }; parent = parent || child.offsetParent || child.ownerSVGElement || child.parentElement || document.body; const parentRect = parent.getBoundingClientRect(); const parentStyle = window.getComputedStyle(parent); const parentBorderLeft = parseFloat(parentStyle.borderLeftWidth); const parentBorderTop = parseFloat(parentStyle.borderTopWidth); rs.x = rect.x - parentRect.x + parent.scrollLeft; rs.y = rect.y - parentRect.y + parent.scrollTop; if (child instanceof SVGElement) ; else { rs.x -= parentBorderLeft; rs.y -= parentBorderTop; } return rs; } function getPointOffset(e, pos) { let ox = e.offsetX || 0, oy = e.offsetY || 0; if (e.target instanceof SVGElement) { ox -= pos.x; oy -= pos.y; } return [ox, oy]; } function isSVGEl(el) { return el instanceof SVGElement; } const EDGE_THRESHOLD = 5; const DRAGGING_RULE = "body * { pointer-events: none; }"; let lockSheet; function lockPage() { lockSheet = getFirstSS(); lockSheet === null || lockSheet === void 0 ? void 0 : lockSheet.insertRule(DRAGGING_RULE, 0); } function unlockPage() { lockSheet === null || lockSheet === void 0 ? void 0 : lockSheet.deleteRule(0); } function getFirstSS() { if (document.styleSheets.length < 1) { document.head.appendChild(document.createElement("style")); } const sheet = collection.find(document.styleSheets, (ss) => !ss.href); if (!sheet) { document.head.appendChild(document.createElement("style")); } return sheet || collection.find(document.styleSheets, (ss) => !ss.href); } let cursor = { html: "", body: "" }; function saveCursor() { cursor.body = document.body.style.cursor; cursor.html = document.documentElement.style.cursor; } function setCursor(cursor) { document.body.style.cursor = document.documentElement.style.cursor = cursor; } function restoreCursor() { document.body.style.cursor = cursor.body; document.documentElement.style.cursor = cursor.html; } function getStyleXy(el) { const style = window.getComputedStyle(el); let x = 0, y = 0; if (el instanceof SVGGraphicsElement) { x = parseFloat(style.x || style.cx) || 0; y = parseFloat(style.y || style.cy) || 0; } else { x = parseFloat(style.left) || 0; y = parseFloat(style.top) || 0; } return { x, y }; } function getStyleSize(el, cStyle) { if ("getBBox" in el) { let { width, height } = el.getBBox(); return { w: width, h: height }; } if (!cStyle) cStyle = window.getComputedStyle(el); const w = parseFloat(cStyle.width); const h = parseFloat(cStyle.height); return { w, h }; } function getMatrixInfo(el, recur = false) { const rs = { scale: 1, angle: 0, x: 0, y: 0 }; let a = 1, b = 0; let elCStyle = window.getComputedStyle(el); let matrix = new DOMMatrix(elCStyle.transform); if (recur) { let p = el.parentElement; while (p && p.tagName !== "BODY" && p.tagName.toLowerCase() !== "svg") { let pCStyle = window.getComputedStyle(p); const pMatrix = new DOMMatrix(pCStyle.transform); matrix = matrix.multiply(pMatrix); p = p.parentElement; } } if (matrix) { a = matrix.a; b = matrix.b; matrix.c; matrix.d; rs.x = matrix.e; rs.y = matrix.f; } rs.scale = Math.sqrt(a * a + b * b); rs.angle = Math.round(Math.atan2(b, a) * (180 / Math.PI)); return rs; } function getPointInContainer(event, el, elRect, elCStyle, matrixInfo) { if (!elRect) { elRect = el.getBoundingClientRect(); } let rx = elRect.x, ry = elRect.y; if (!elCStyle) { elCStyle = window.getComputedStyle(el); } if (!matrixInfo) { matrixInfo = getMatrixInfo(el, true); } const scale = matrixInfo.scale; let x = event.clientX - rx - (parseFloat(elCStyle.borderLeftWidth) || 0) * scale + el.scrollLeft * scale; let y = event.clientY - ry - (parseFloat(elCStyle.borderTopWidth) || 0) * scale + el.scrollTop * scale; return { x: x / scale, y: y / scale, scale }; } function getRectInContainer(el, container, matrixInfo) { const elRect = el.getBoundingClientRect(); const containerRect = container.getBoundingClientRect(); const elCStyle = window.getComputedStyle(container); matrixInfo = matrixInfo || getMatrixInfo(container, true); const scale = matrixInfo.scale; let x = elRect.x - containerRect.x - (parseFloat(elCStyle.borderLeftWidth) || 0) * scale + container.scrollLeft * scale; let y = elRect.y - containerRect.y - (parseFloat(elCStyle.borderTopWidth) || 0) * scale + container.scrollTop * scale; return { x: x / scale, y: y / scale, w: elRect.width / scale, h: elRect.height / scale, }; } function getRectCenter(el, matrixInfo) { const panelRect = getRectInContainer(el, el.parentElement, matrixInfo); let x = Math.round(panelRect.x + panelRect.w / 2); let y = Math.round(panelRect.y + panelRect.h / 2); return { x, y }; } function getCenterXy(el, ox, oy) { const cStyle = window.getComputedStyle(el); const center = cStyle.transformOrigin; const centerPair = center.split(" "); ox = ox || parseFloat(centerPair[0]); oy = oy || parseFloat(centerPair[1]); const shadowDom = el.cloneNode(); rotateTo(shadowDom, 0); const parentEl = el.parentElement; let startX = 0, startY = 0; if (parentEl) { parentEl.appendChild(shadowDom); const offsetXY = getRectInContainer(shadowDom, parentEl); (startX = offsetXY.x), (startY = offsetXY.y); parentEl.removeChild(shadowDom); } return { sx: startX, sy: startY, x: startX + ox, y: startY + oy, ox, oy }; } function getCenterXySVG(el, ox, oy) { let elRect = el.getBoundingClientRect(); let svgRect = el.ownerSVGElement.getBoundingClientRect(); let x = elRect.x - svgRect.x; let y = elRect.y - svgRect.y; const shadowDom = el.cloneNode(); rotateTo(shadowDom, 0); const parentEl = el.parentElement; if (parentEl) { parentEl.appendChild(shadowDom); const offsetXY = getRectInContainer(shadowDom, parentEl); (offsetXY.x), (offsetXY.y); parentEl.removeChild(shadowDom); } return { sx: x, sy: y, x: x + ox, y: y + oy, ox, oy }; } function getVertex(el, ox, oy) { const cStyle = window.getComputedStyle(el); const w = parseFloat(cStyle.width); const h = parseFloat(cStyle.height); const { originX, originY } = parseOxy(ox, oy, w, h); const { x, y, sx, sy } = el instanceof SVGGraphicsElement ? getCenterXySVG(el, originX, originY) : getCenterXy(el); const { angle } = getMatrixInfo(el); return calcVertex(w, h, x, y, sx, sy, angle * ONE_ANG); } function calcVertex(w, h, cx, cy, sx, sy, radian) { let originVertex = [ { x: 0, y: 0 }, { x: w, y: 0 }, { x: 0, y: h }, { x: w, y: h }, ]; return collection.map(originVertex, ({ x, y }) => { const nx = (x - cx + sx) * Math.cos(radian) - (y - cy + sy) * Math.sin(radian); const ny = (x - cx + sx) * Math.sin(radian) + (y - cy + sy) * Math.cos(radian); return { x: cx + nx, y: cy + ny }; }); } function parseOxy(ox, oy, w, h, el) { let originX = 0, originY = 0; let transformOrigin; if (is.isString(ox)) { originX = (parseFloat(ox) / 100) * w; } else if (is.isNumber(ox)) { originX = ox; } else if (el) { if (!transformOrigin) transformOrigin = window.getComputedStyle(el).transformOrigin; const centerPair = transformOrigin.split(" "); originX = parseFloat(centerPair[0]); } if (is.isString(oy)) { originY = (parseFloat(oy) / 100) * h; } else if (is.isNumber(oy)) { originY = oy; } else if (el) { if (!transformOrigin) transformOrigin = window.getComputedStyle(el).transformOrigin; const centerPair = transformOrigin.split(" "); originY = parseFloat(centerPair[1]); } return { originX, originY }; } function normalizeVector(x, y) { let len = Math.sqrt(x * x + y * y); return { x: x / len, y: y / len }; } function isVisible(el) { let rect = el.getBoundingClientRect(); if (rect.width === 0 || rect.height === 0) { return false; } return true; } var _Uii_listeners; const UII_KEY = '__uii_target_'; const UII_MAP = {}; let UiiSn = 0; class Uii { constructor(ele, opts) { var _a; this.enabled = true; _Uii_listeners.set(this, []); this.opts = opts || {}; this.opts.mouseButton = this.opts.mouseButton || 'left'; this.opts.eventCapture = (_a = this.opts.eventCapture) !== null && _a !== void 0 ? _a : true; if (is.isArrayLike(ele) && !is.isString(ele)) { this.ele = collection.map(ele, (el) => { let e = is.isString(el) ? document.querySelector(el) : el; if (!is.isElement(e)) { console.error('Invalid element "' + el + '"'); return false; } return e; }); } else { if (is.isString(ele)) { this.eleString = ele; } const el = is.isString(ele) ? document.querySelectorAll(ele) : ele; if (!is.isElement(el) && !is.isArrayLike(el)) { console.error('Invalid element "' + ele + '"'); return; } this.ele = is.isArrayLike(el) ? collection.toArray(el) : [el]; } let uid = UiiSn++ + ''; UII_MAP[uid] = this; this._bindUiik(uid); } destroy() { collection.each(__classPrivateFieldGet(this, _Uii_listeners, "f"), (ev) => { ev[0].removeEventListener(ev[1], ev[2], ev[3]); }); __classPrivateFieldSet(this, _Uii_listeners, [], "f"); } addPointerDown(el, pointerDown) { const onPointerDown = pointerDown; const uiiOptions = this.opts; let threshold = 0; let toLockPage = true; this.registerEvent(el, "mousedown", (e) => { var _a; if (uiiOptions.mouseButton) { switch (uiiOptions.mouseButton) { case "left": if (e.button != 0) return; break; case "right": if (e.button != 2) return; break; } } let t = e.target; if (!t) return; const hasCursor = !is.isEmpty(object.get(uiiOptions, "cursor.active")); const currentStyle = el.style; const currentCStyle = window.getComputedStyle(el); const currentRect = el.getBoundingClientRect(); let dragging = false; const originPosX = e.clientX; const originPosY = e.clientY; if (hasCursor) { saveCursor(); } let onPointerStart; let onPointerMove; let onPointerEnd; const toBreak = !!onPointerDown({ onPointerMove: (pm) => { onPointerMove = pm; }, onPointerStart: (ps) => { onPointerStart = ps; }, onPointerEnd: (pe) => { onPointerEnd = pe; }, ev: e, pointX: e.clientX, pointY: e.clientY, target: t, currentTarget: el, currentStyle, currentCStyle, currentRect, }); if (toBreak) { e.preventDefault(); return false; } let target = tree.closest(t, (node) => node && object.get(node, UII_KEY), "parentElement"); if (target) { let uiiInstance = UII_MAP[object.get(target, UII_KEY)]; threshold = uiiInstance.opts.threshold || 0; toLockPage = (_a = uiiInstance.opts.lockPage) !== null && _a !== void 0 ? _a : true; } let matrixInfo = getMatrixInfo(el, true); const pointerMove = (ev) => { const offX = (ev.clientX - originPosX) / matrixInfo.scale; const offY = (ev.clientY - originPosY) / matrixInfo.scale; if (!dragging) { if (Math.abs(offX) > threshold || Math.abs(offY) > threshold) { dragging = true; if (toLockPage) { lockPage(); } if (hasCursor) { setCursor(uiiOptions.cursor.active); } onPointerStart && onPointerStart({ ev }); } else { ev.preventDefault(); return false; } } onPointerMove && onPointerMove({ ev, pointX: ev.clientX, pointY: ev.clientY, offX, offY, currentStyle, currentCStyle, }); }; const pointerEnd = (ev) => { document.removeEventListener("mousemove", pointerMove, false); document.removeEventListener("mouseup", pointerEnd, false); window.removeEventListener("blur", pointerEnd, false); if (dragging) { if (toLockPage) { unlockPage(); } if (hasCursor) { restoreCursor(); } onPointerEnd && onPointerEnd({ ev, currentStyle }); } }; document.addEventListener("mousemove", pointerMove); document.addEventListener("mouseup", pointerEnd); window.addEventListener("blur", pointerEnd); e.preventDefault(); return false; }, this.opts.eventCapture); } registerEvent(el, event, hook, useCapture = false) { const wrapper = ((ev) => { if (!this.enabled) return; hook(ev); }).bind(this); el.addEventListener(event, wrapper, useCapture); __classPrivateFieldGet(this, _Uii_listeners, "f").push([el, event, wrapper, useCapture]); } disable() { this.enabled = false; } enable() { this.enabled = true; } getOptions() { return this.opts; } getOption(name) { return this.opts[name]; } setOptions(options) { object.assign(this.opts, options); this.onOptionChanged(this.opts); } setOption(name, value) { this.opts[name] = value; this.onOptionChanged(this.opts); } _bindUiik(uid) { collection.each(this.ele, el => { object.set(el, UII_KEY, uid); }); } onOptionChanged(opts) { } } _Uii_listeners = new WeakMap(); var _Splittable_instances, _Splittable_checkDirection, _Splittable_bindHandle; const CLASS_SPLITTABLE = "uii-splittable"; const CLASS_SPLITTABLE_HANDLE = "uii-splittable-handle"; const CLASS_SPLITTABLE_HANDLE_GHOST = "uii-splittable-handle-ghost"; const CLASS_SPLITTABLE_HANDLE_ACTIVE = "uii-splittable-handle-active"; const CLASS_SPLITTABLE_V = "uii-splittable-v"; const CLASS_SPLITTABLE_H = "uii-splittable-h"; function getRootEl(el, root) { let rs = el.parentNode; while (rs && rs.parentNode !== root) { rs = rs.parentNode; } return rs; } class Splittable extends Uii { constructor(container, opts) { super(container, object.assign({ handleSize: 10, minSize: 0, sticky: false, inside: false, ghost: false }, opts)); _Splittable_instances.add(this); collection.each(this.ele, con => { const pos = window.getComputedStyle(con).position; if (pos === "static" || is.isBlank(pos)) { con.style.position = "relative"; } con.classList.toggle(CLASS_SPLITTABLE, true); const handleDoms = is.isString(this.opts.handle) ? con.querySelectorAll(this.opts.handle) : is.isArray(this.opts.handle) ? this.opts.handle : this.opts.handle ? [this.opts.handle] : []; const children = collection.reject(con.children, c => { if (collection.includes(handleDoms, c)) return true; return false; }); const dir = __classPrivateFieldGet(this, _Splittable_instances, "m", _Splittable_checkDirection).call(this, con); con.classList.toggle(dir === 'v' ? CLASS_SPLITTABLE_V : CLASS_SPLITTABLE_H, true); const minSizeAry = collection.map(children, (c, i) => { if (is.isArray(this.opts.minSize)) { return this.opts.minSize[i] || 0; } else { return this.opts.minSize; } }); const stickyAry = collection.map(children, (c, i) => { if (is.isArray(this.opts.sticky)) { return this.opts.sticky[i] || false; } else { return this.opts.sticky; } }); if (is.isEmpty(handleDoms)) { const len = children.length - 1; for (let i = 0; i < len; i++) { __classPrivateFieldGet(this, _Splittable_instances, "m", _Splittable_bindHandle).call(this, minSizeAry.slice(i, i + 2), stickyAry.slice(i, i + 2), this.opts, dir, children[i], children[i + 1]); } } else { collection.each(handleDoms, (h, i) => { var _a; const isRoot = (_a = h.parentElement) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_SPLITTABLE); let dom1, dom2; if (isRoot) { dom1 = h.previousElementSibling; dom2 = h.nextElementSibling; } else { let domCon = getRootEl(h, con); let domL = domCon.previousElementSibling; let domR = domCon.nextElementSibling; let hasDomLHandle = is.isString(this.opts.handle) ? domL === null || domL === void 0 ? void 0 : domL.querySelector(this.opts.handle) : domL === null || domL === void 0 ? void 0 : domL.contains(h); if (domL && !hasDomLHandle) { dom1 = domL; dom2 = domCon; } else { dom1 = domCon; dom2 = domR; } } __classPrivateFieldGet(this, _Splittable_instances, "m", _Splittable_bindHandle).call(this, minSizeAry.slice(i, i + 2), stickyAry.slice(i, i + 2), this.opts, dir, dom1, dom2, h); }); } }); } } _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Splittable_checkDirection(container) { let dir = 'h'; let cStyle = window.getComputedStyle(container); if (cStyle.display === 'inline-flex') return dir; if (cStyle.display === 'flex' && cStyle.flexDirection === 'row') return dir; const child = container.children[0]; let lastY = child.offsetTop; let lastH = child.offsetHeight; collection.each(container.children, (c) => { if (c.offsetTop > lastH + lastY) { dir = 'v'; return false; } }); return dir; }, _Splittable_bindHandle = function _Splittable_bindHandle(minSizeAry, stickyAry, opts, dir, dom1, dom2, handle) { var _a, _b; const handleSize = opts.handleSize; if (!handle) { handle = document.createElement('div'); let initPos = 0; if (!opts.inside) { initPos = (dir === 'v' ? dom2.offsetTop : dom2.offsetLeft); } if (!isVisible(dom2)) { (_a = dom2.parentElement) === null || _a === void 0 ? void 0 : _a.addEventListener('mouseenter', () => { initPos = (dir === 'v' ? dom2.offsetTop : dom2.offsetLeft); handle.style.left = initPos - handleSize / 2 + 'px'; }, { once: true }); } const sensorHCss = `width:${handleSize}px;height:100%;top:0;left:${initPos - handleSize / 2}px;z-index:9;`; const sensorVCss = `height:${handleSize}px;width:100%;left:0;top:${initPos - handleSize / 2}px;z-index:9;`; handle.style.cssText = 'position: absolute;' + (dir === 'v' ? sensorVCss : sensorHCss); if (opts.inside) { dom2.appendChild(handle); } (_b = dom2.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(handle, dom2); } handle.style.cursor = dir === 'v' ? 's-resize' : 'e-resize'; handle.dataset.cursor = handle.style.cursor; handle.classList.add(CLASS_SPLITTABLE_HANDLE); const minSize1 = minSizeAry[0]; const minSize2 = minSizeAry[1]; let sticky1 = stickyAry[0]; let sticky2 = stickyAry[1]; const onStart = opts.onStart; const onSplit = opts.onSplit; const onEnd = opts.onEnd; const onSticky = opts.onSticky; const onClone = opts.onClone; const oneSideMode = opts.oneSideMode; const updateStart = !oneSideMode || oneSideMode === 'start'; const updateEnd = !oneSideMode || oneSideMode === 'end'; this.addPointerDown(handle, ({ currentTarget, onPointerStart, onPointerMove, onPointerEnd }) => { let originSize = 0; let originSize1 = 0; let splitterSize = 1; let blockSize = 0; switch (dir) { case 'v': originSize = dom1.offsetHeight; originSize1 = dom2.offsetHeight; splitterSize = currentTarget.offsetHeight; break; case 'h': originSize = dom1.offsetWidth; originSize1 = dom2.offsetWidth; splitterSize = currentTarget.offsetWidth; break; } blockSize = splitterSize + originSize + originSize1; const dom1Style = dom1.style; const dom2Style = dom2.style; const ghost = opts.ghost; const ghostClass = opts.ghostClass; const ghostTo = opts.ghostTo; let ghostNode = null; let sticked = 'none'; if (originSize < minSize1 / 2) { sticked = 'start'; } else if (blockSize - originSize - splitterSize < minSize2 / 2) { sticked = 'end'; } let startPos = dir === 'v' ? dom1.offsetTop : dom1.offsetLeft; let ds1, anotherSize; onPointerStart(function (args) { const { ev } = args; currentTarget.classList.add(CLASS_SPLITTABLE_HANDLE_ACTIVE); if (ghost) { ghostNode = currentTarget.cloneNode(true); ghostNode.style.opacity = '0.3'; ghostNode.style.pointerEvents = 'none'; ghostNode.classList.add(CLASS_SPLITTABLE_HANDLE_GHOST); if (ghostNode) { if (ghostClass) { ghostNode.className = ghostNode.className.replace(ghostClass, '') + ' ' + ghostClass; } let ghostParent = ghostTo ? (is.isString(ghostTo) ? document.querySelector(ghostTo) : ghostTo) : currentTarget.parentNode; ghostParent.appendChild(ghostNode); onClone && onClone({ clone: ghostNode }, ev); } } onStart && onStart({ size1: originSize, size2: originSize1 }, ev); }); onPointerMove((args) => { const { ev, offX, offY, currentStyle } = args; let doSticky = false; ds1 = dir === 'v' ? originSize + offY : originSize + offX; if (ds1 < minSize1 / 2 && sticky1 && minSize1 > 0) { if (sticked == 'none') { doSticky = true; sticked = 'start'; } ds1 = 0; } else if (ds1 < minSize1) { ds1 = minSize1; if (sticked == 'start' && sticky1) { doSticky = true; sticked = 'none'; } } else if (blockSize - ds1 - splitterSize < minSize2 / 2 && sticky2) { if (sticked == 'none') { doSticky = true; sticked = 'end'; } ds1 = blockSize - splitterSize; } else if (blockSize - ds1 - splitterSize < minSize2) { ds1 = blockSize - minSize2 - splitterSize; if (sticked == 'end' && sticky2) { doSticky = true; sticked = 'none'; } } anotherSize = blockSize - ds1 - splitterSize; if (ghostNode) { if (dir === 'v') { ghostNode.style.top = startPos + ds1 - splitterSize / 2 + 'px'; } else { ghostNode.style.left = startPos + ds1 - splitterSize / 2 + 'px'; } } else { const updateProp = dir === 'v' ? 'height' : 'width'; if (updateStart) { dom1Style.setProperty(updateProp, ds1 + 'px', 'important'); } if (updateEnd) { dom2Style.setProperty(updateProp, anotherSize + 'px', 'important'); } if (doSticky) { onSticky && onSticky({ size1: ds1, size2: anotherSize, position: sticked }, ev); } if (dir === 'v') { currentStyle.top = dom2.offsetTop - splitterSize / 2 + 'px'; } else { currentStyle.left = dom2.offsetLeft - splitterSize / 2 + 'px'; } } onSplit && onSplit({ size1: ds1, size2: anotherSize }, ev); }); onPointerEnd((args) => { var _a; const { ev, currentStyle } = args; switch (dir) { case 'v': originSize = (dom1 === null || dom1 === void 0 ? void 0 : dom1.offsetHeight) || -1; originSize1 = (dom2 === null || dom2 === void 0 ? void 0 : dom2.offsetHeight) || -1; break; case 'h': originSize = (dom1 === null || dom1 === void 0 ? void 0 : dom1.offsetWidth) || -1; originSize1 = (dom2 === null || dom2 === void 0 ? void 0 : dom2.offsetWidth) || -1; break; } handle === null || handle === void 0 ? void 0 : handle.classList.remove(CLASS_SPLITTABLE_HANDLE_ACTIVE); if (ghostNode) { const updateProp = dir === 'v' ? 'height' : 'width'; if (updateStart) { dom1Style.setProperty(updateProp, ds1 + 'px', 'important'); } if (updateEnd) { dom2Style.setProperty(updateProp, anotherSize + 'px', 'important'); } if (dir === 'v') { currentStyle.top = startPos + ds1 - splitterSize / 2 + 'px'; } else { currentStyle.left = startPos + ds1 - splitterSize / 2 + 'px'; } (_a = ghostNode.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(ghostNode); } onEnd && onEnd({ size1: originSize, size2: originSize1 }, ev); }); }); }; function newSplittable(container, opts) { return new Splittable(container, opts); } const CLASS_RESIZABLE_HANDLE = "uii-resizable-handle"; const CLASS_RESIZABLE_HANDLE_DIR = "uii-resizable-handle-"; const CLASS_RESIZABLE_HANDLE_ACTIVE = "uii-resizable-handle-active"; const CLASS_RESIZABLE_GHOST = "uii-resizable-ghost"; const EXP_DIR = new RegExp(CLASS_RESIZABLE_HANDLE_DIR + "(?<dir>[nesw]+)"); class Resizable extends Uii { constructor(els, opts) { super(els, object.assign({ handleSize: 8, minSize: 50, ghost: false, offset: 0, }, opts)); collection.each(this.ele, (el) => { let tmp = el; if (tmp._uiik_resizable) { tmp._uiik_resizable.destroy(); return false; } }); collection.each(this.ele, (el) => { el._uiik_resizable = this; this.initHandle(el); }); } bindHandle(handle, dir, panel, opts) { const onStart = opts.onStart; const onResize = opts.onResize; const onEnd = opts.onEnd; const onClone = opts.onClone; const uiik = this; this.addPointerDown(handle, ({ ev, onPointerStart, onPointerMove, onPointerEnd }) => { const onPointerDown = opts.onPointerDown; if (onPointerDown && onPointerDown(ev) === false) return true; let container = panel.parentElement; let matrixInfo = getMatrixInfo(panel, true); const offset = getRectInContainer(panel, container, matrixInfo); const offsetParentRect = container.getBoundingClientRect(); const offsetParentCStyle = window.getComputedStyle(container); let setOrigin = !(panel instanceof SVGGraphicsElement) && matrixInfo.angle != 0; const { w, h } = getStyleSize(panel); const originW = w; const originH = h; const originX = offset.x; const originY = offset.y; let changeW = false; let changeH = false; let changeX = false; let changeY = false; let toTransformOrigin = ""; switch (dir) { case "s": changeH = true; break; case "e": changeW = true; break; case "se": changeW = true; changeH = true; break; case "n": changeX = true; changeY = true; changeH = true; toTransformOrigin = "0 0"; break; case "w": changeX = true; changeY = true; changeW = true; toTransformOrigin = "0 0"; break; case "sw": case "ne": case "nw": changeX = true; changeY = true; changeW = true; changeH = true; toTransformOrigin = "0 0"; break; } let minWidth = 1; let minHeight = 1; let maxWidth = 9999; let maxHeight = 9999; if (is.isArray(opts.minSize)) { minWidth = opts.minSize[0]; minHeight = opts.minSize[1]; } else if (is.isNumber(opts.minSize)) { minWidth = opts.minSize; minHeight = opts.minSize; } if (is.isArray(opts.maxSize)) { maxWidth = opts.maxSize[0]; maxHeight = opts.maxSize[1]; } else if (is.isNumber(opts.maxSize)) { maxWidth = opts.maxSize; maxHeight = opts.maxSize; } const ghost = opts.ghost; const ghostClass = opts.ghostClass; let ghostNode = null; const aspectRatio = opts.aspectRatio; const panelStyle = panel.style; let style = panelStyle; let currentW = originW; let currentH = originH; let transform; let lastX = 0, lastY = 0; let originalTransformOrigin = ""; let vertexBeforeTransform; let currentVertex; let refPoint; let k1; let sX = 0, sY = 0; let startPointXy; onPointerStart(function (args) { var _a; const { ev } = args; handle.classList.add(CLASS_RESIZABLE_HANDLE_ACTIVE); if (ghost) { if (is.isFunction(ghost)) { ghostNode = ghost(panel); } else { ghostNode = panel.cloneNode(true); ghostNode.style.opacity = "0.3"; ghostNode.style.pointerEvents = "none"; } if (ghostNode) { if (ghostClass) { ghostNode.classList.add(ghostClass); } ghostNode.classList.toggle(CLASS_RESIZABLE_GHOST, true); (_a = panel.parentNode) === null || _a === void 0 ? void 0 : _a.appendChild(ghostNode); transform = wrapper(ghostNode); onClone && onClone({ clone: ghostNode }, ev); } style = ghostNode === null || ghostNode === void 0 ? void 0 : ghostNode.style; } else { transform = wrapper(panel); } const cStyle = window.getComputedStyle(panel); const w = parseFloat(cStyle.width); const h = parseFloat(cStyle.height); const oxy = parseOxy(opts.ox, opts.oy, w, h); oxy.originX; oxy.originY; const panelRect = getRectInContainer(panel, panel.parentElement, matrixInfo); let centerX = Math.round(panelRect.x + panelRect.w / 2); let centerY = Math.