vue3-columns-resizable
Version:
Vue 3 directive to resize HTML table columns
79 lines (78 loc) • 3.03 kB
JavaScript
const y = /* @__PURE__ */ new WeakMap();
function g(n) {
if (typeof document > "u") return;
const i = n.nodeName;
if (!["TABLE", "THEAD"].includes(i)) return;
const s = i === "TABLE" ? n : n.parentElement;
if (!s) return;
const p = s.querySelector("thead"), o = Array.from(p?.querySelectorAll("th") ?? []);
if (o.length === 0) return;
s.style.position = "relative";
const l = document.createElement("div");
l.className = "vue3-columns-resizable", l.style.position = "relative", s.parentElement?.insertBefore(l, s);
let d = !1, a = 0, v = !1;
const m = [];
o.forEach((r, t) => {
if (t + 1 >= o.length) return;
const e = document.createElement("div");
e.className = "columns-resize-bar", e.style.position = "absolute", e.style.top = "0", e.style.width = "8px", e.style.cursor = "col-resize", e.style.zIndex = "1", e.addEventListener("mousedown", () => {
d = !0, a = t, document.body.style.cursor = "col-resize", document.body.style.userSelect = "none";
}), m[t] = e, l.appendChild(e);
});
const b = (r) => parseFloat(r) || 0, E = () => {
if (d) return;
const r = s.offsetWidth, t = i === "TABLE" ? s.offsetHeight : p?.offsetHeight ?? 0;
r === 0 || t === 0 || (l.style.width = `${r}px`, v || (o.forEach((e) => {
e.style.width = `${e.offsetWidth}px`;
}), v = !0), o.forEach((e, c) => {
const u = m[c], f = o[c + 1];
!u || !f || (u.style.height = `${t}px`, u.style.left = `${f.offsetLeft - 4}px`);
}));
}, x = () => {
d && (d = !1, document.body.style.cursor = "", document.body.style.userSelect = "", o.forEach((r, t) => {
const e = m[t], c = o[t + 1];
r.style.width = `${r.offsetWidth}px`, e && c && (e.style.left = `${c.offsetLeft - 4}px`);
}));
}, h = (r) => {
if (!d) return;
const t = o[a], e = o[a + 1], c = m[a];
if (!t || !e || !c) return;
const u = r.movementX, f = b(t.style.width) + u, L = b(e.style.width) - u;
t.style.width = `${f}px`, e.style.width = `${L}px`, c.style.left = `${e.offsetLeft - 4 + u}px`, n.dispatchEvent(
new CustomEvent("column-resized", {
detail: {
index: a,
width: f,
nextIndex: a + 1,
nextWidth: L
},
bubbles: !0
})
);
};
document.addEventListener("mouseup", x), l.addEventListener("mousemove", h), s.addEventListener("mousemove", h);
let w = requestAnimationFrame(() => {
w = requestAnimationFrame(E);
});
const z = typeof ResizeObserver < "u" ? new ResizeObserver(() => E()) : null;
return z?.observe(s), () => {
cancelAnimationFrame(w), z?.disconnect(), document.removeEventListener("mouseup", x), l.removeEventListener("mousemove", h), s.removeEventListener("mousemove", h), l.remove();
};
}
const A = {
mounted(n) {
const i = g(n);
i && y.set(n, { cleanup: i });
},
unmounted(n) {
const i = y.get(n);
i && (i.cleanup(), y.delete(n));
}
}, T = {
install(n) {
n.directive("columns-resizable", A);
}
};
export {
T as default
};