@svgrid/grid 2.7.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/{GridMenus-C4oLsJyj.js → GridMenus-DMihUtma.js} +1 -1
- package/dist/cdn/{GridMenus-yEivjNwl.js → GridMenus-nmNDj1a3.js} +1 -1
- package/dist/cdn/{row-drag-touch-Ddaa-QeB.js → row-drag-touch-CycRR65n.js} +12 -10
- package/dist/cdn/{src-COC0vnpg.js → src-B_YS5AOc.js} +12 -12
- package/dist/cdn/{src-pYGV2rMR.js → src-DYXXpuSk.js} +12 -12
- package/dist/cdn/svgrid.js +1 -1
- package/dist/cdn/svgrid.svelte-external.js +1 -1
- package/dist/row-drag-touch.d.ts +5 -1
- package/dist/row-drag-touch.js +15 -4
- package/dist/row-drag.js +7 -3
- package/package.json +1 -1
- package/src/row-drag-touch.ts +226 -211
- package/src/row-drag.test.ts +49 -1
- package/src/row-drag.ts +7 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gn as e, fo as t, po as n } from "./src-
|
|
1
|
+
import { Gn as e, fo as t, po as n } from "./src-B_YS5AOc.js";
|
|
2
2
|
import { E as r, F as i, G as a, H as o, I as s, L as c, N as l, Q as u, U as d, V as f, X as p, Y as m, Z as h, _ as g, at as _, b as v, d as y, et as b, f as x, ft as S, g as ee, h as C, it as w, j as T, k as E, lt as D, m as O, mt as te, nt as k, o as ne, pt as A, st as j, t as M, tt as N, u as P, ut as re, v as F, w as ie } from "./disclose-version-Dr7rEVv-.js";
|
|
3
3
|
import { S as ae, _ as oe, j as se, k as ce } from "./editor-registry-BhgE3S84.js";
|
|
4
4
|
import { o as le } from "./SvDateTimePicker-BWwpfB_o.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gn as e, fo as t, po as n } from "./src-
|
|
1
|
+
import { Gn as e, fo as t, po as n } from "./src-DYXXpuSk.js";
|
|
2
2
|
import { S as r, _ as i, j as a, k as o } from "./editor-registry-BhgE3S84.js";
|
|
3
3
|
import { o as s } from "./SvDateTimePicker-Bivn8dAP.js";
|
|
4
4
|
import * as c from "svelte/internal/client";
|
|
@@ -57,11 +57,11 @@ function e(e) {
|
|
|
57
57
|
!n || e.pointerId !== n.pointerId || c(!1);
|
|
58
58
|
}
|
|
59
59
|
return {
|
|
60
|
-
start(r, i) {
|
|
60
|
+
start(r, i, a) {
|
|
61
61
|
if (!e.managed() || n) return;
|
|
62
|
-
let
|
|
63
|
-
if (
|
|
64
|
-
let
|
|
62
|
+
let s = e.originalAt(i);
|
|
63
|
+
if (s == null) return;
|
|
64
|
+
let c = r.currentTarget;
|
|
65
65
|
n = {
|
|
66
66
|
pointerId: r.pointerId,
|
|
67
67
|
rowIndex: i,
|
|
@@ -70,17 +70,19 @@ function e(e) {
|
|
|
70
70
|
started: !1,
|
|
71
71
|
timer: null,
|
|
72
72
|
scrollFrame: null,
|
|
73
|
-
scroller:
|
|
74
|
-
root:
|
|
75
|
-
}, window.addEventListener("pointermove", l, { passive: !1 }), window.addEventListener("pointerup", u), window.addEventListener("pointercancel", d), window.addEventListener("touchmove", o, { passive: !1 })
|
|
73
|
+
scroller: c?.closest?.(".sv-grid-container") ?? null,
|
|
74
|
+
root: c?.closest?.(".sv-grid-root") ?? null
|
|
75
|
+
}, window.addEventListener("pointermove", l, { passive: !1 }), window.addEventListener("pointerup", u), window.addEventListener("pointercancel", d), window.addEventListener("touchmove", o, { passive: !1 });
|
|
76
|
+
let f = a == null ? 0 : Math.max(0, performance.now() - a);
|
|
77
|
+
n.timer = setTimeout(() => {
|
|
76
78
|
if (n) {
|
|
77
79
|
n.started = !0, n.timer = null, n.root?.classList.add("sv-grid-row-drag-active");
|
|
78
80
|
try {
|
|
79
|
-
|
|
81
|
+
c?.setPointerCapture?.(r.pointerId);
|
|
80
82
|
} catch {}
|
|
81
|
-
e.openBus(
|
|
83
|
+
e.openBus(s), t.rowDragActive = !0, t.rowDropIndex = i, t.rowDropSide = "before";
|
|
82
84
|
}
|
|
83
|
-
}, 350);
|
|
85
|
+
}, Math.max(0, 350 - f));
|
|
84
86
|
},
|
|
85
87
|
destroy() {
|
|
86
88
|
c(!1);
|
|
@@ -3535,18 +3535,18 @@ function Dr(e) {
|
|
|
3535
3535
|
}
|
|
3536
3536
|
if (y) return;
|
|
3537
3537
|
y = !0;
|
|
3538
|
-
let r = e.pointerId, i = e.clientX, a = e.clientY, o = !1;
|
|
3539
|
-
function
|
|
3540
|
-
window.removeEventListener("pointermove",
|
|
3541
|
-
}
|
|
3542
|
-
function c(e) {
|
|
3543
|
-
e.pointerId === r && Math.abs(e.clientY - a) + Math.abs(e.clientX - i) > 10 && (o = !0, s());
|
|
3538
|
+
let r = e.pointerId, i = e.clientX, a = e.clientY, o = performance.now(), s = !1;
|
|
3539
|
+
function c() {
|
|
3540
|
+
window.removeEventListener("pointermove", l), window.removeEventListener("pointerup", u), window.removeEventListener("pointercancel", u);
|
|
3544
3541
|
}
|
|
3545
3542
|
function l(e) {
|
|
3546
|
-
e.pointerId === r && (
|
|
3543
|
+
e.pointerId === r && Math.abs(e.clientY - a) + Math.abs(e.clientX - i) > 10 && (s = !0, c());
|
|
3544
|
+
}
|
|
3545
|
+
function u(e) {
|
|
3546
|
+
e.pointerId === r && (s = !0, c());
|
|
3547
3547
|
}
|
|
3548
|
-
window.addEventListener("pointermove",
|
|
3549
|
-
let
|
|
3548
|
+
window.addEventListener("pointermove", l, { passive: !0 }), window.addEventListener("pointerup", u), window.addEventListener("pointercancel", u);
|
|
3549
|
+
let d = {
|
|
3550
3550
|
pointerId: e.pointerId,
|
|
3551
3551
|
pointerType: e.pointerType,
|
|
3552
3552
|
clientX: e.clientX,
|
|
@@ -3554,8 +3554,8 @@ function Dr(e) {
|
|
|
3554
3554
|
currentTarget: e.currentTarget,
|
|
3555
3555
|
preventDefault: () => {}
|
|
3556
3556
|
};
|
|
3557
|
-
import("./row-drag-touch-
|
|
3558
|
-
y = !1,
|
|
3557
|
+
import("./row-drag-touch-CycRR65n.js").then((e) => {
|
|
3558
|
+
y = !1, c(), !(s || !n()) && (v = e.createTouchDrag(b()), v.start(d, t, o));
|
|
3559
3559
|
});
|
|
3560
3560
|
}
|
|
3561
3561
|
return {
|
|
@@ -8188,7 +8188,7 @@ function Qs(e, t) {
|
|
|
8188
8188
|
E(() => {
|
|
8189
8189
|
u(ee) || (o.editingEnabled || o.editingCell || o.fullRowEdit) && import("./SvGridCellEditor-Ba7rY3eu.js").then((e) => B(ee, e.default, !0));
|
|
8190
8190
|
}), E(() => {
|
|
8191
|
-
(o.tooltip || o.columnMenuFor || o.contextMenuFor || o.filterMenuFor || o.operatorMenuFor || o.inSuggestFor || o.chooseColumnsPos) && !u(x) && import("./GridMenus-
|
|
8191
|
+
(o.tooltip || o.columnMenuFor || o.contextMenuFor || o.filterMenuFor || o.operatorMenuFor || o.inSuggestFor || o.chooseColumnsPos) && !u(x) && import("./GridMenus-DMihUtma.js").then((e) => B(x, e.default, !0));
|
|
8192
8192
|
});
|
|
8193
8193
|
let M = J(() => !!o.pivotConfig && o.pivotModeOn), N = J(() => o.pivotResult), F = J(() => o.allRowsBeforePagination.filter((e) => !o.isGroupRow(e)).map((e) => e.original)), oe = J(() => o.filterRowValues), ce = J(() => o.filterMenuValues), ue = J(() => o.showTooltipFor), Y = J(() => o.hideTooltip), $ = J(() => o.findHits), he = J(() => o.headerHeight), _e = J(() => p.columnResize === !0), ve = J(() => o.selectionColumnWidth), xe = J(() => o.rowNumberColumnWidth), Ce = J(() => o.showRowNumbersEffective), we = J(() => o.columnMenuFor), Te = J(() => o.filterMenuFor), Ee = J(() => o.operatorMenuFor), Ae = J(() => o.viewportWidth), je = J(() => o.viewportHeight), Me = J(() => o.scrollMetrics), Pe = J(() => o.hasVerticalOverflow), Fe = J(() => o.showGlobalFilterEffective), Ie = J(() => o.showFilterRowEffective), Le = J(() => o.showInlineColumnFilterEffective), Re = J(() => o.showRowSelectionEffective), ze = J(() => o.rowSummariesEnabled), Be = J(() => o.grid), Ve = J(() => o.allColumns), He = J(() => o.headerGroups), Ue = J(() => o.groupHeaderRowsWindowed), We = J(() => o.cellPinStyle), Ge = J(() => o.isColumnPinned), Ke = J(() => o.colDragId), qe = J(() => o.colDropOnId), Je = J(() => o.colDropSide), Ye = J(() => o.onColumnHeaderDragStart), Xe = J(() => o.onColumnHeaderDragOver), Ze = J(() => o.onColumnHeaderDragLeave), Qe = J(() => o.onColumnHeaderDrop), $e = J(() => o.onColumnHeaderDragEnd), et = J(() => p.rowDragManaged === !0), tt = J(() => o.rowDropIndex), nt = J(() => o.rowDropSide), rt = J(() => o.onRowDragStart), it = J(() => o.onRowDragOver), at = J(() => o.onRowDragLeave), ot = J(() => o.onRowDrop), st = J(() => o.onRowsContainerDragOver), ct = J(() => o.onRowsContainerDrop), lt = J(() => o.onRowDragEnd), ut = J(() => o.onRowPointerDown);
|
|
8194
8194
|
function dt(e) {
|
|
@@ -3537,18 +3537,18 @@ function Tn(e) {
|
|
|
3537
3537
|
}
|
|
3538
3538
|
if (y) return;
|
|
3539
3539
|
y = !0;
|
|
3540
|
-
let r = e.pointerId, i = e.clientX, a = e.clientY, o = !1;
|
|
3541
|
-
function
|
|
3542
|
-
window.removeEventListener("pointermove",
|
|
3543
|
-
}
|
|
3544
|
-
function c(e) {
|
|
3545
|
-
e.pointerId === r && Math.abs(e.clientY - a) + Math.abs(e.clientX - i) > 10 && (o = !0, s());
|
|
3540
|
+
let r = e.pointerId, i = e.clientX, a = e.clientY, o = performance.now(), s = !1;
|
|
3541
|
+
function c() {
|
|
3542
|
+
window.removeEventListener("pointermove", l), window.removeEventListener("pointerup", u), window.removeEventListener("pointercancel", u);
|
|
3546
3543
|
}
|
|
3547
3544
|
function l(e) {
|
|
3548
|
-
e.pointerId === r && (
|
|
3545
|
+
e.pointerId === r && Math.abs(e.clientY - a) + Math.abs(e.clientX - i) > 10 && (s = !0, c());
|
|
3546
|
+
}
|
|
3547
|
+
function u(e) {
|
|
3548
|
+
e.pointerId === r && (s = !0, c());
|
|
3549
3549
|
}
|
|
3550
|
-
window.addEventListener("pointermove",
|
|
3551
|
-
let
|
|
3550
|
+
window.addEventListener("pointermove", l, { passive: !0 }), window.addEventListener("pointerup", u), window.addEventListener("pointercancel", u);
|
|
3551
|
+
let d = {
|
|
3552
3552
|
pointerId: e.pointerId,
|
|
3553
3553
|
pointerType: e.pointerType,
|
|
3554
3554
|
clientX: e.clientX,
|
|
@@ -3556,8 +3556,8 @@ function Tn(e) {
|
|
|
3556
3556
|
currentTarget: e.currentTarget,
|
|
3557
3557
|
preventDefault: () => {}
|
|
3558
3558
|
};
|
|
3559
|
-
import("./row-drag-touch-
|
|
3560
|
-
y = !1,
|
|
3559
|
+
import("./row-drag-touch-CycRR65n.js").then((e) => {
|
|
3560
|
+
y = !1, c(), !(s || !n()) && (v = e.createTouchDrag(b()), v.start(d, t, o));
|
|
3561
3561
|
});
|
|
3562
3562
|
}
|
|
3563
3563
|
return {
|
|
@@ -8190,7 +8190,7 @@ function Jo(e, t) {
|
|
|
8190
8190
|
V.user_effect(() => {
|
|
8191
8191
|
V.get(w) || (a.editingEnabled || a.editingCell || a.fullRowEdit) && import("./SvGridCellEditor-AXL8cHGO.js").then((e) => V.set(w, e.default, !0));
|
|
8192
8192
|
}), V.user_effect(() => {
|
|
8193
|
-
(a.tooltip || a.columnMenuFor || a.contextMenuFor || a.filterMenuFor || a.operatorMenuFor || a.inSuggestFor || a.chooseColumnsPos) && !V.get(y) && import("./GridMenus-
|
|
8193
|
+
(a.tooltip || a.columnMenuFor || a.contextMenuFor || a.filterMenuFor || a.operatorMenuFor || a.inSuggestFor || a.chooseColumnsPos) && !V.get(y) && import("./GridMenus-nmNDj1a3.js").then((e) => V.set(y, e.default, !0));
|
|
8194
8194
|
});
|
|
8195
8195
|
let T = V.derived(() => !!a.pivotConfig && a.pivotModeOn), E = V.derived(() => a.pivotResult), D = V.derived(() => a.allRowsBeforePagination.filter((e) => !a.isGroupRow(e)).map((e) => e.original)), O = V.derived(() => a.filterRowValues), k = V.derived(() => a.filterMenuValues), A = V.derived(() => a.showTooltipFor), j = V.derived(() => a.hideTooltip), M = V.derived(() => a.findHits), N = V.derived(() => a.headerHeight), P = V.derived(() => o.columnResize === !0), F = V.derived(() => a.selectionColumnWidth), I = V.derived(() => a.rowNumberColumnWidth), L = V.derived(() => a.showRowNumbersEffective), ee = V.derived(() => a.columnMenuFor), R = V.derived(() => a.filterMenuFor), te = V.derived(() => a.operatorMenuFor), z = V.derived(() => a.viewportWidth), B = V.derived(() => a.viewportHeight), ne = V.derived(() => a.scrollMetrics), H = V.derived(() => a.hasVerticalOverflow), re = V.derived(() => a.showGlobalFilterEffective), ie = V.derived(() => a.showFilterRowEffective), ae = V.derived(() => a.showInlineColumnFilterEffective), U = V.derived(() => a.showRowSelectionEffective), W = V.derived(() => a.rowSummariesEnabled), oe = V.derived(() => a.grid), se = V.derived(() => a.allColumns), ce = V.derived(() => a.headerGroups), le = V.derived(() => a.groupHeaderRowsWindowed), ue = V.derived(() => a.cellPinStyle), de = V.derived(() => a.isColumnPinned), fe = V.derived(() => a.colDragId), pe = V.derived(() => a.colDropOnId), me = V.derived(() => a.colDropSide), he = V.derived(() => a.onColumnHeaderDragStart), ge = V.derived(() => a.onColumnHeaderDragOver), _e = V.derived(() => a.onColumnHeaderDragLeave), ve = V.derived(() => a.onColumnHeaderDrop), ye = V.derived(() => a.onColumnHeaderDragEnd), be = V.derived(() => o.rowDragManaged === !0), xe = V.derived(() => a.rowDropIndex), Se = V.derived(() => a.rowDropSide), Ce = V.derived(() => a.onRowDragStart), we = V.derived(() => a.onRowDragOver), Te = V.derived(() => a.onRowDragLeave), Ee = V.derived(() => a.onRowDrop), De = V.derived(() => a.onRowsContainerDragOver), Oe = V.derived(() => a.onRowsContainerDrop), ke = V.derived(() => a.onRowDragEnd), Ae = V.derived(() => a.onRowPointerDown);
|
|
8196
8196
|
function je(e) {
|
package/dist/cdn/svgrid.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as ee, c as te, d as e, f as ne, h as re, i as t, l as n, m as r, n as i, o as a, p as o, r as s, s as c, t as l, u } from "./export-format-Cv1Dll6k.js";
|
|
2
|
-
import { $ as d, $a as f, $i as p, $n as m, $o as h, $r as g, $t as _, A as v, Aa as y, Ai as b, An as x, Ao as S, Ar as C, At as w, B as T, Ba as E, Bi as D, Bn as O, Bo as k, Br as A, Bt as j, C as M, Ca as N, Ci as P, Cn as F, Co as I, Cr as L, Ct as R, D as z, Da as B, Di as V, Dn as H, Do as U, Dr as W, Dt as G, E as K, Ea as q, Ei as J, En as Y, Eo as X, Er as ie, Et as ae, F as oe, Fa as se, Fi as ce, Fn as le, Fo as ue, Fr as de, Ft as fe, G as pe, Ga as me, Gi as he, Gn as ge, Go as _e, Gr as ve, Gt as ye, H as be, Ha as xe, Hi as Se, Hn as Ce, Ho as we, Hr as Te, Ht as Ee, I as De, Ia as Oe, Ii as ke, In as Ae, Io as je, Ir as Me, It as Ne, J as Pe, Ja as Fe, Ji as Ie, Jn as Le, Jo as Re, Jr as ze, Jt as Be, K as Ve, Ka as He, Ki as Ue, Kn as We, Ko as Ge, Kr as Ke, Kt as qe, L as Je, La as Ye, Li as Xe, Ln as Ze, Lo as Qe, Lr as $e, Lt as et, M as tt, Ma as nt, Mi as rt, Mn as it, Mo as at, Mr as ot, Mt as st, N as ct, Na as lt, Ni as ut, Nn as dt, No as ft, Nr as pt, Nt as mt, O as ht, Oa as gt, Oi as _t, On as vt, Oo as yt, Or as bt, Ot as xt, P as St, Pa as Ct, Pi as wt, Pn as Tt, Po as Et, Pr as Dt, Pt as Ot, Q as kt, Qa as At, Qi as jt, Qn as Mt, Qo as Nt, Qr as Pt, Qt as Ft, R as It, Ra as Lt, Ri as Rt, Rn as zt, Ro as Bt, Rr as Vt, Rt as Ht, S as Ut, Sa as Wt, Si as Gt, Sn as Kt, So as qt, Sr as Jt, St as Yt, T as Xt, Ta as Zt, Ti as Qt, Tn as $t, To as en, Tr as tn, Tt as nn, U as rn, Ua as an, Ui as on, Un as sn, Uo as cn, Ur as ln, Ut as un, V as dn, Va as fn, Vi as pn, Vn as mn, Vo as hn, Vr as gn, Vt as _n, W as vn, Wa as yn, Wi as bn, Wn as xn, Wo as Sn, Wr as Cn, Wt as wn, X as Tn, Xa as En, Xi as Dn, Xn as On, Xo as kn, Xr as An, Xt as jn, Y as Mn, Ya as Nn, Yi as Pn, Yn as Fn, Yo as In, Yr as Ln, Yt as Rn, Z as zn, Za as Bn, Zi as Vn, Zn as Hn, Zo as Un, Zr as Wn, Zt as Gn, _ as Kn, _a as qn, _i as Jn, _n as Yn, _o as Xn, _r as Zn, _t as Qn, a as $n, aa as er, ai as tr, an as nr, ao as rr, ar as ir, at as ar, b as or, ba as sr, bi as cr, bn as lr, bo as ur, br as dr, bt as fr, c as pr, ca as mr, ci as hr, cn as gr, co as _r, cr as vr, ct as yr, d as br, da as xr, di as Sr, dn as Cr, do as wr, dr as Tr, dt as Er, ea as Dr, ei as Or, en as kr, eo as Ar, er as jr, es as Mr, et as Nr, f as Pr, fa as Fr, fi as Ir, fn as Lr, fo as Rr, fr as zr, ft as Br, g as Vr, ga as Hr, gi as Ur, gn as Wr, go as Gr, gr as Kr, gt as qr, h as Jr, ha as Yr, hi as Xr, hn as Zr, ho as Z, hr as Qr, ht as $r, i as ei, ia as ti, ii as ni, in as ri, io as ii, ir as ai, it as oi, j as si, ja as ci, ji as li, jn as ui, jo as di, jr as fi, jt as pi, k as mi, ka as hi, ki as gi, kn as _i, ko as vi, kr as yi, kt as bi, l as xi, la as Si, li as Ci, ln as wi, lo as Ti, lr as Ei, lt as Di, m as Oi, ma as ki, mi as Ai, mn as ji, mo as Mi, mr as Ni, mt as Pi, n as Fi, na as Ii, ni as Li, nn as Ri, no as zi, nr as Bi, nt as Vi, o as Hi, oa as Ui, oi as Wi, on as Gi, oo as Ki, or as qi, ot as Ji, p as Yi, pa as Xi, pi as Zi, pn as Qi, po as $i, pr as ea, pt as ta, q as na, qa as ra, qi as ia, qn as aa, qo as oa, qr as sa, qt as ca, r as la, ra as ua, ri as da, rn as fa, ro as pa, rr as ma, rt as ha, s as ga, sa as _a, si as va, sn as ya, so as ba, sr as xa, st as Sa, t as Ca, ta as wa, ti as Ta, tn as Ea, to as Da, tr as Oa, ts as ka, tt as Aa, u as ja, ua as Ma, ui as Na, un as Pa, uo as Fa, ur as Ia, ut as La, v as Ra, va as za, vi as Ba, vn as Va, vo as Ha, vr as Ua, vt as Wa, w as Ga, wa as Ka, wi as qa, wn as Ja, wo as Ya, wr as Xa, wt as Za, x as Qa, xa as $a, xi as eo, xn as to, xo as no, xr as ro, xt as io, y as ao, ya as oo, yi as so, yn as co, yo as lo, yr as uo, yt as fo, z as po, za as mo, zi as ho, zn as go, zo as _o, zr as vo, zt as yo } from "./src-
|
|
2
|
+
import { $ as d, $a as f, $i as p, $n as m, $o as h, $r as g, $t as _, A as v, Aa as y, Ai as b, An as x, Ao as S, Ar as C, At as w, B as T, Ba as E, Bi as D, Bn as O, Bo as k, Br as A, Bt as j, C as M, Ca as N, Ci as P, Cn as F, Co as I, Cr as L, Ct as R, D as z, Da as B, Di as V, Dn as H, Do as U, Dr as W, Dt as G, E as K, Ea as q, Ei as J, En as Y, Eo as X, Er as ie, Et as ae, F as oe, Fa as se, Fi as ce, Fn as le, Fo as ue, Fr as de, Ft as fe, G as pe, Ga as me, Gi as he, Gn as ge, Go as _e, Gr as ve, Gt as ye, H as be, Ha as xe, Hi as Se, Hn as Ce, Ho as we, Hr as Te, Ht as Ee, I as De, Ia as Oe, Ii as ke, In as Ae, Io as je, Ir as Me, It as Ne, J as Pe, Ja as Fe, Ji as Ie, Jn as Le, Jo as Re, Jr as ze, Jt as Be, K as Ve, Ka as He, Ki as Ue, Kn as We, Ko as Ge, Kr as Ke, Kt as qe, L as Je, La as Ye, Li as Xe, Ln as Ze, Lo as Qe, Lr as $e, Lt as et, M as tt, Ma as nt, Mi as rt, Mn as it, Mo as at, Mr as ot, Mt as st, N as ct, Na as lt, Ni as ut, Nn as dt, No as ft, Nr as pt, Nt as mt, O as ht, Oa as gt, Oi as _t, On as vt, Oo as yt, Or as bt, Ot as xt, P as St, Pa as Ct, Pi as wt, Pn as Tt, Po as Et, Pr as Dt, Pt as Ot, Q as kt, Qa as At, Qi as jt, Qn as Mt, Qo as Nt, Qr as Pt, Qt as Ft, R as It, Ra as Lt, Ri as Rt, Rn as zt, Ro as Bt, Rr as Vt, Rt as Ht, S as Ut, Sa as Wt, Si as Gt, Sn as Kt, So as qt, Sr as Jt, St as Yt, T as Xt, Ta as Zt, Ti as Qt, Tn as $t, To as en, Tr as tn, Tt as nn, U as rn, Ua as an, Ui as on, Un as sn, Uo as cn, Ur as ln, Ut as un, V as dn, Va as fn, Vi as pn, Vn as mn, Vo as hn, Vr as gn, Vt as _n, W as vn, Wa as yn, Wi as bn, Wn as xn, Wo as Sn, Wr as Cn, Wt as wn, X as Tn, Xa as En, Xi as Dn, Xn as On, Xo as kn, Xr as An, Xt as jn, Y as Mn, Ya as Nn, Yi as Pn, Yn as Fn, Yo as In, Yr as Ln, Yt as Rn, Z as zn, Za as Bn, Zi as Vn, Zn as Hn, Zo as Un, Zr as Wn, Zt as Gn, _ as Kn, _a as qn, _i as Jn, _n as Yn, _o as Xn, _r as Zn, _t as Qn, a as $n, aa as er, ai as tr, an as nr, ao as rr, ar as ir, at as ar, b as or, ba as sr, bi as cr, bn as lr, bo as ur, br as dr, bt as fr, c as pr, ca as mr, ci as hr, cn as gr, co as _r, cr as vr, ct as yr, d as br, da as xr, di as Sr, dn as Cr, do as wr, dr as Tr, dt as Er, ea as Dr, ei as Or, en as kr, eo as Ar, er as jr, es as Mr, et as Nr, f as Pr, fa as Fr, fi as Ir, fn as Lr, fo as Rr, fr as zr, ft as Br, g as Vr, ga as Hr, gi as Ur, gn as Wr, go as Gr, gr as Kr, gt as qr, h as Jr, ha as Yr, hi as Xr, hn as Zr, ho as Z, hr as Qr, ht as $r, i as ei, ia as ti, ii as ni, in as ri, io as ii, ir as ai, it as oi, j as si, ja as ci, ji as li, jn as ui, jo as di, jr as fi, jt as pi, k as mi, ka as hi, ki as gi, kn as _i, ko as vi, kr as yi, kt as bi, l as xi, la as Si, li as Ci, ln as wi, lo as Ti, lr as Ei, lt as Di, m as Oi, ma as ki, mi as Ai, mn as ji, mo as Mi, mr as Ni, mt as Pi, n as Fi, na as Ii, ni as Li, nn as Ri, no as zi, nr as Bi, nt as Vi, o as Hi, oa as Ui, oi as Wi, on as Gi, oo as Ki, or as qi, ot as Ji, p as Yi, pa as Xi, pi as Zi, pn as Qi, po as $i, pr as ea, pt as ta, q as na, qa as ra, qi as ia, qn as aa, qo as oa, qr as sa, qt as ca, r as la, ra as ua, ri as da, rn as fa, ro as pa, rr as ma, rt as ha, s as ga, sa as _a, si as va, sn as ya, so as ba, sr as xa, st as Sa, t as Ca, ta as wa, ti as Ta, tn as Ea, to as Da, tr as Oa, ts as ka, tt as Aa, u as ja, ua as Ma, ui as Na, un as Pa, uo as Fa, ur as Ia, ut as La, v as Ra, va as za, vi as Ba, vn as Va, vo as Ha, vr as Ua, vt as Wa, w as Ga, wa as Ka, wi as qa, wn as Ja, wo as Ya, wr as Xa, wt as Za, x as Qa, xa as $a, xi as eo, xn as to, xo as no, xr as ro, xt as io, y as ao, ya as oo, yi as so, yn as co, yo as lo, yr as uo, yt as fo, z as po, za as mo, zi as ho, zn as go, zo as _o, zr as vo, zt as yo } from "./src-B_YS5AOc.js";
|
|
3
3
|
import { a as bo, i as xo, n as So, o as Co, r as wo, s as To, t as Eo } from "./editor-registry-BhgE3S84.js";
|
|
4
4
|
import { A as Do, C as Oo, D as ko, E as Ao, F as jo, I as Mo, L as No, M as Po, N as Fo, O as Io, P as Lo, R as Ro, S as zo, T as Bo, _ as Vo, a as Ho, b as Uo, c as Wo, d as Go, f as Ko, g as qo, h as Jo, i as Yo, j as Xo, k as Zo, l as Qo, m as $o, n as es, o as ts, p as ns, r as rs, s as is, t as as, u as os, v as ss, w as cs, x as ls, y as us, z as ds } from "./date-format-DZT7T1wf.js";
|
|
5
5
|
import { i as fs, n as ps, r as ms, t as hs } from "./popover-P-9P2YYn.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as ee, c as te, d as e, f as ne, h as re, i as t, l as n, m as r, n as i, o as a, p as o, r as s, s as c, t as l, u } from "./export-format-Cv1Dll6k.js";
|
|
2
|
-
import { $ as d, $a as f, $i as p, $n as m, $o as h, $r as g, $t as _, A as v, Aa as y, Ai as b, An as x, Ao as S, Ar as C, At as w, B as T, Ba as E, Bi as D, Bn as O, Bo as k, Br as A, Bt as j, C as M, Ca as N, Ci as P, Cn as F, Co as I, Cr as L, Ct as R, D as z, Da as B, Di as V, Dn as H, Do as U, Dr as W, Dt as G, E as K, Ea as q, Ei as J, En as Y, Eo as X, Er as ie, Et as ae, F as oe, Fa as se, Fi as ce, Fn as le, Fo as ue, Fr as de, Ft as fe, G as pe, Ga as me, Gi as he, Gn as ge, Go as _e, Gr as ve, Gt as ye, H as be, Ha as xe, Hi as Se, Hn as Ce, Ho as we, Hr as Te, Ht as Ee, I as De, Ia as Oe, Ii as ke, In as Ae, Io as je, Ir as Me, It as Ne, J as Pe, Ja as Fe, Ji as Ie, Jn as Le, Jo as Re, Jr as ze, Jt as Be, K as Ve, Ka as He, Ki as Ue, Kn as We, Ko as Ge, Kr as Ke, Kt as qe, L as Je, La as Ye, Li as Xe, Ln as Ze, Lo as Qe, Lr as $e, Lt as et, M as tt, Ma as nt, Mi as rt, Mn as it, Mo as at, Mr as ot, Mt as st, N as ct, Na as lt, Ni as ut, Nn as dt, No as ft, Nr as pt, Nt as mt, O as ht, Oa as gt, Oi as _t, On as vt, Oo as yt, Or as bt, Ot as xt, P as St, Pa as Ct, Pi as wt, Pn as Tt, Po as Et, Pr as Dt, Pt as Ot, Q as kt, Qa as At, Qi as jt, Qn as Mt, Qo as Nt, Qr as Pt, Qt as Ft, R as It, Ra as Lt, Ri as Rt, Rn as zt, Ro as Bt, Rr as Vt, Rt as Ht, S as Ut, Sa as Wt, Si as Gt, Sn as Kt, So as qt, Sr as Jt, St as Yt, T as Xt, Ta as Zt, Ti as Qt, Tn as $t, To as en, Tr as tn, Tt as nn, U as rn, Ua as an, Ui as on, Un as sn, Uo as cn, Ur as ln, Ut as un, V as dn, Va as fn, Vi as pn, Vn as mn, Vo as hn, Vr as gn, Vt as _n, W as vn, Wa as yn, Wi as bn, Wn as xn, Wo as Sn, Wr as Cn, Wt as wn, X as Tn, Xa as En, Xi as Dn, Xn as On, Xo as kn, Xr as An, Xt as jn, Y as Mn, Ya as Nn, Yi as Pn, Yn as Fn, Yo as In, Yr as Ln, Yt as Rn, Z as zn, Za as Bn, Zi as Vn, Zn as Hn, Zo as Un, Zr as Wn, Zt as Gn, _ as Kn, _a as qn, _i as Jn, _n as Yn, _o as Xn, _r as Zn, _t as Qn, a as $n, aa as er, ai as tr, an as nr, ao as rr, ar as ir, at as ar, b as or, ba as sr, bi as cr, bn as lr, bo as ur, br as dr, bt as fr, c as pr, ca as mr, ci as hr, cn as gr, co as _r, cr as vr, ct as yr, d as br, da as xr, di as Sr, dn as Cr, do as wr, dr as Tr, dt as Er, ea as Dr, ei as Or, en as kr, eo as Ar, er as jr, es as Mr, et as Nr, f as Pr, fa as Fr, fi as Ir, fn as Lr, fo as Rr, fr as zr, ft as Br, g as Vr, ga as Hr, gi as Ur, gn as Wr, go as Gr, gr as Kr, gt as qr, h as Jr, ha as Yr, hi as Xr, hn as Zr, ho as Z, hr as Qr, ht as $r, i as ei, ia as ti, ii as ni, in as ri, io as ii, ir as ai, it as oi, j as si, ja as ci, ji as li, jn as ui, jo as di, jr as fi, jt as pi, k as mi, ka as hi, ki as gi, kn as _i, ko as vi, kr as yi, kt as bi, l as xi, la as Si, li as Ci, ln as wi, lo as Ti, lr as Ei, lt as Di, m as Oi, ma as ki, mi as Ai, mn as ji, mo as Mi, mr as Ni, mt as Pi, n as Fi, na as Ii, ni as Li, nn as Ri, no as zi, nr as Bi, nt as Vi, o as Hi, oa as Ui, oi as Wi, on as Gi, oo as Ki, or as qi, ot as Ji, p as Yi, pa as Xi, pi as Zi, pn as Qi, po as $i, pr as ea, pt as ta, q as na, qa as ra, qi as ia, qn as aa, qo as oa, qr as sa, qt as ca, r as la, ra as ua, ri as da, rn as fa, ro as pa, rr as ma, rt as ha, s as ga, sa as _a, si as va, sn as ya, so as ba, sr as xa, st as Sa, t as Ca, ta as wa, ti as Ta, tn as Ea, to as Da, tr as Oa, ts as ka, tt as Aa, u as ja, ua as Ma, ui as Na, un as Pa, uo as Fa, ur as Ia, ut as La, v as Ra, va as za, vi as Ba, vn as Va, vo as Ha, vr as Ua, vt as Wa, w as Ga, wa as Ka, wi as qa, wn as Ja, wo as Ya, wr as Xa, wt as Za, x as Qa, xa as $a, xi as eo, xn as to, xo as no, xr as ro, xt as io, y as ao, ya as oo, yi as so, yn as co, yo as lo, yr as uo, yt as fo, z as po, za as mo, zi as ho, zn as go, zo as _o, zr as vo, zt as yo } from "./src-
|
|
2
|
+
import { $ as d, $a as f, $i as p, $n as m, $o as h, $r as g, $t as _, A as v, Aa as y, Ai as b, An as x, Ao as S, Ar as C, At as w, B as T, Ba as E, Bi as D, Bn as O, Bo as k, Br as A, Bt as j, C as M, Ca as N, Ci as P, Cn as F, Co as I, Cr as L, Ct as R, D as z, Da as B, Di as V, Dn as H, Do as U, Dr as W, Dt as G, E as K, Ea as q, Ei as J, En as Y, Eo as X, Er as ie, Et as ae, F as oe, Fa as se, Fi as ce, Fn as le, Fo as ue, Fr as de, Ft as fe, G as pe, Ga as me, Gi as he, Gn as ge, Go as _e, Gr as ve, Gt as ye, H as be, Ha as xe, Hi as Se, Hn as Ce, Ho as we, Hr as Te, Ht as Ee, I as De, Ia as Oe, Ii as ke, In as Ae, Io as je, Ir as Me, It as Ne, J as Pe, Ja as Fe, Ji as Ie, Jn as Le, Jo as Re, Jr as ze, Jt as Be, K as Ve, Ka as He, Ki as Ue, Kn as We, Ko as Ge, Kr as Ke, Kt as qe, L as Je, La as Ye, Li as Xe, Ln as Ze, Lo as Qe, Lr as $e, Lt as et, M as tt, Ma as nt, Mi as rt, Mn as it, Mo as at, Mr as ot, Mt as st, N as ct, Na as lt, Ni as ut, Nn as dt, No as ft, Nr as pt, Nt as mt, O as ht, Oa as gt, Oi as _t, On as vt, Oo as yt, Or as bt, Ot as xt, P as St, Pa as Ct, Pi as wt, Pn as Tt, Po as Et, Pr as Dt, Pt as Ot, Q as kt, Qa as At, Qi as jt, Qn as Mt, Qo as Nt, Qr as Pt, Qt as Ft, R as It, Ra as Lt, Ri as Rt, Rn as zt, Ro as Bt, Rr as Vt, Rt as Ht, S as Ut, Sa as Wt, Si as Gt, Sn as Kt, So as qt, Sr as Jt, St as Yt, T as Xt, Ta as Zt, Ti as Qt, Tn as $t, To as en, Tr as tn, Tt as nn, U as rn, Ua as an, Ui as on, Un as sn, Uo as cn, Ur as ln, Ut as un, V as dn, Va as fn, Vi as pn, Vn as mn, Vo as hn, Vr as gn, Vt as _n, W as vn, Wa as yn, Wi as bn, Wn as xn, Wo as Sn, Wr as Cn, Wt as wn, X as Tn, Xa as En, Xi as Dn, Xn as On, Xo as kn, Xr as An, Xt as jn, Y as Mn, Ya as Nn, Yi as Pn, Yn as Fn, Yo as In, Yr as Ln, Yt as Rn, Z as zn, Za as Bn, Zi as Vn, Zn as Hn, Zo as Un, Zr as Wn, Zt as Gn, _ as Kn, _a as qn, _i as Jn, _n as Yn, _o as Xn, _r as Zn, _t as Qn, a as $n, aa as er, ai as tr, an as nr, ao as rr, ar as ir, at as ar, b as or, ba as sr, bi as cr, bn as lr, bo as ur, br as dr, bt as fr, c as pr, ca as mr, ci as hr, cn as gr, co as _r, cr as vr, ct as yr, d as br, da as xr, di as Sr, dn as Cr, do as wr, dr as Tr, dt as Er, ea as Dr, ei as Or, en as kr, eo as Ar, er as jr, es as Mr, et as Nr, f as Pr, fa as Fr, fi as Ir, fn as Lr, fo as Rr, fr as zr, ft as Br, g as Vr, ga as Hr, gi as Ur, gn as Wr, go as Gr, gr as Kr, gt as qr, h as Jr, ha as Yr, hi as Xr, hn as Zr, ho as Z, hr as Qr, ht as $r, i as ei, ia as ti, ii as ni, in as ri, io as ii, ir as ai, it as oi, j as si, ja as ci, ji as li, jn as ui, jo as di, jr as fi, jt as pi, k as mi, ka as hi, ki as gi, kn as _i, ko as vi, kr as yi, kt as bi, l as xi, la as Si, li as Ci, ln as wi, lo as Ti, lr as Ei, lt as Di, m as Oi, ma as ki, mi as Ai, mn as ji, mo as Mi, mr as Ni, mt as Pi, n as Fi, na as Ii, ni as Li, nn as Ri, no as zi, nr as Bi, nt as Vi, o as Hi, oa as Ui, oi as Wi, on as Gi, oo as Ki, or as qi, ot as Ji, p as Yi, pa as Xi, pi as Zi, pn as Qi, po as $i, pr as ea, pt as ta, q as na, qa as ra, qi as ia, qn as aa, qo as oa, qr as sa, qt as ca, r as la, ra as ua, ri as da, rn as fa, ro as pa, rr as ma, rt as ha, s as ga, sa as _a, si as va, sn as ya, so as ba, sr as xa, st as Sa, t as Ca, ta as wa, ti as Ta, tn as Ea, to as Da, tr as Oa, ts as ka, tt as Aa, u as ja, ua as Ma, ui as Na, un as Pa, uo as Fa, ur as Ia, ut as La, v as Ra, va as za, vi as Ba, vn as Va, vo as Ha, vr as Ua, vt as Wa, w as Ga, wa as Ka, wi as qa, wn as Ja, wo as Ya, wr as Xa, wt as Za, x as Qa, xa as $a, xi as eo, xn as to, xo as no, xr as ro, xt as io, y as ao, ya as oo, yi as so, yn as co, yo as lo, yr as uo, yt as fo, z as po, za as mo, zi as ho, zn as go, zo as _o, zr as vo, zt as yo } from "./src-DYXXpuSk.js";
|
|
3
3
|
import { a as bo, i as xo, n as So, o as Co, r as wo, s as To, t as Eo } from "./editor-registry-BhgE3S84.js";
|
|
4
4
|
import { A as Do, C as Oo, D as ko, E as Ao, F as jo, I as Mo, L as No, M as Po, N as Fo, O as Io, P as Lo, R as Ro, S as zo, T as Bo, _ as Vo, a as Ho, b as Uo, c as Wo, d as Go, f as Ko, g as qo, h as Jo, i as Yo, j as Xo, k as Zo, l as Qo, m as $o, n as es, o as ts, p as ns, r as rs, s as is, t as as, u as os, v as ss, w as cs, x as ls, y as us, z as ds } from "./date-format-CcP1tafP.js";
|
|
5
5
|
import { i as fs, n as ps, r as ms, t as hs } from "./popover-P-9P2YYn.js";
|
package/dist/row-drag-touch.d.ts
CHANGED
|
@@ -12,7 +12,11 @@ export type TouchDragDeps = {
|
|
|
12
12
|
};
|
|
13
13
|
/** What {@link createTouchDrag} returns. */
|
|
14
14
|
export type TouchDragHandle = {
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* @param pressStartedAt `performance.now()` at the pointerdown that began
|
|
17
|
+
* this press. Defaults to now. See the long-press comment in `start`.
|
|
18
|
+
*/
|
|
19
|
+
start: (e: PointerEvent, rowIndex: number, pressStartedAt?: number) => void;
|
|
16
20
|
destroy: () => void;
|
|
17
21
|
};
|
|
18
22
|
export declare function createTouchDrag(deps: TouchDragDeps): TouchDragHandle;
|
package/dist/row-drag-touch.js
CHANGED
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
// `onRowDragEnd` payload cannot drift between mouse and touch.
|
|
9
9
|
//
|
|
10
10
|
// Loaded with `import()` on the first touch that lands on a draggable row, so
|
|
11
|
-
// desktop users never download it. The 350 ms long press below
|
|
12
|
-
//
|
|
11
|
+
// desktop users never download it. The 350 ms long press below absorbs the
|
|
12
|
+
// fetch rather than following it: `start` takes the pointerdown timestamp and
|
|
13
|
+
// subtracts the time already spent waiting, so a fetch that finishes inside the
|
|
14
|
+
// press costs the user nothing.
|
|
13
15
|
//
|
|
14
16
|
// A touch that starts on a row must still be able to SCROLL the grid, so the
|
|
15
17
|
// drag only begins after a long press; moving before that threshold hands the
|
|
@@ -138,7 +140,7 @@ export function createTouchDrag(deps) {
|
|
|
138
140
|
}
|
|
139
141
|
return {
|
|
140
142
|
/** Begin a press that may become a drag. Caller has already checked touch. */
|
|
141
|
-
start(e, rowIndex) {
|
|
143
|
+
start(e, rowIndex, pressStartedAt) {
|
|
142
144
|
if (!deps.managed() || touch)
|
|
143
145
|
return;
|
|
144
146
|
const row = deps.originalAt(rowIndex);
|
|
@@ -160,6 +162,15 @@ export function createTouchDrag(deps) {
|
|
|
160
162
|
window.addEventListener("pointerup", onPointerUp);
|
|
161
163
|
window.addEventListener("pointercancel", onPointerCancel);
|
|
162
164
|
window.addEventListener("touchmove", blockTouchScroll, { passive: false });
|
|
165
|
+
// The long press is measured from when the finger LANDED, not from when
|
|
166
|
+
// this module finished loading. `row-drag.ts` fetches it with import() on
|
|
167
|
+
// the first touch, and that fetch is not free - measured at ~190 ms cold.
|
|
168
|
+
// Starting the clock here would make the real cost `fetch + 350 ms`, so a
|
|
169
|
+
// user on a slow connection would have to hold noticeably longer for
|
|
170
|
+
// their first drag than for every one after it. Subtracting the elapsed
|
|
171
|
+
// time keeps it at 350 ms from the finger's point of view, which is what
|
|
172
|
+
// the comment at the top of this file has always claimed.
|
|
173
|
+
const waited = pressStartedAt == null ? 0 : Math.max(0, performance.now() - pressStartedAt);
|
|
163
174
|
touch.timer = setTimeout(() => {
|
|
164
175
|
if (!touch)
|
|
165
176
|
return;
|
|
@@ -176,7 +187,7 @@ export function createTouchDrag(deps) {
|
|
|
176
187
|
ctx.rowDragActive = true;
|
|
177
188
|
ctx.rowDropIndex = rowIndex;
|
|
178
189
|
ctx.rowDropSide = "before";
|
|
179
|
-
}, LONG_PRESS_MS);
|
|
190
|
+
}, Math.max(0, LONG_PRESS_MS - waited));
|
|
180
191
|
},
|
|
181
192
|
destroy() {
|
|
182
193
|
end(false);
|
package/dist/row-drag.js
CHANGED
|
@@ -202,8 +202,8 @@ export function createRowDrag(ctx) {
|
|
|
202
202
|
}
|
|
203
203
|
// Touch drag (#66) lives in its own module and is fetched on the first touch
|
|
204
204
|
// that lands on a draggable row, so desktop never downloads it. The 350 ms
|
|
205
|
-
// long press inside it
|
|
206
|
-
//
|
|
205
|
+
// long press inside it absorbs the fetch: the press clock starts at
|
|
206
|
+
// pointerdown here, so the fetch is free unless it outlasts the press.
|
|
207
207
|
let touchDrag = null;
|
|
208
208
|
let touchLoading = false;
|
|
209
209
|
function touchDeps() {
|
|
@@ -252,6 +252,10 @@ export function createRowDrag(ctx) {
|
|
|
252
252
|
const pid = e.pointerId;
|
|
253
253
|
const startX = e.clientX;
|
|
254
254
|
const startY = e.clientY;
|
|
255
|
+
// Handed to the touch module so its long press is counted from HERE, not
|
|
256
|
+
// from whenever the import below resolves. Without it the first touch drag
|
|
257
|
+
// of a session costs `fetch + 350 ms` while every later one costs 350 ms.
|
|
258
|
+
const pressStartedAt = performance.now();
|
|
255
259
|
let aborted = false;
|
|
256
260
|
function stopWatching() {
|
|
257
261
|
window.removeEventListener("pointermove", onEarlyMove);
|
|
@@ -292,7 +296,7 @@ export function createRowDrag(ctx) {
|
|
|
292
296
|
if (aborted || !managed())
|
|
293
297
|
return;
|
|
294
298
|
touchDrag = m.createTouchDrag(touchDeps());
|
|
295
|
-
touchDrag.start(snapshot, rowIndex);
|
|
299
|
+
touchDrag.start(snapshot, rowIndex, pressStartedAt);
|
|
296
300
|
});
|
|
297
301
|
}
|
|
298
302
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svgrid/grid",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Svelte 5-native data grid and data table. Headless-first engine with virtual scrolling for 100k+ rows, Excel-style filtering, inline editing, grouping, tree data, pivot, and server-side data. Drop-in <SvGrid> component. TypeScript, SSR-ready.",
|
|
5
5
|
"author": "jQWidgets <boikom@jqwidgets.com>",
|
|
6
6
|
"license": "MIT",
|
package/src/row-drag-touch.ts
CHANGED
|
@@ -1,211 +1,226 @@
|
|
|
1
|
-
// Touch / pointer row dragging (#66).
|
|
2
|
-
//
|
|
3
|
-
// HTML5 drag events do not exist for touch input on iOS Safari or Android
|
|
4
|
-
// Chrome - `dragstart` never fires - so the drag path in `row-drag.ts` is dead
|
|
5
|
-
// on a phone. This is a second INPUT path onto the same model: it populates the
|
|
6
|
-
// same cross-grid `bus` and the same `rowDropIndex` / `rowDropSide`, and commits
|
|
7
|
-
// through the same `commitDropOnRow`, so reorder, cross-grid hand-off and the
|
|
8
|
-
// `onRowDragEnd` payload cannot drift between mouse and touch.
|
|
9
|
-
//
|
|
10
|
-
// Loaded with `import()` on the first touch that lands on a draggable row, so
|
|
11
|
-
// desktop users never download it. The 350 ms long press below
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
/**
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
touch.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
deps.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
1
|
+
// Touch / pointer row dragging (#66).
|
|
2
|
+
//
|
|
3
|
+
// HTML5 drag events do not exist for touch input on iOS Safari or Android
|
|
4
|
+
// Chrome - `dragstart` never fires - so the drag path in `row-drag.ts` is dead
|
|
5
|
+
// on a phone. This is a second INPUT path onto the same model: it populates the
|
|
6
|
+
// same cross-grid `bus` and the same `rowDropIndex` / `rowDropSide`, and commits
|
|
7
|
+
// through the same `commitDropOnRow`, so reorder, cross-grid hand-off and the
|
|
8
|
+
// `onRowDragEnd` payload cannot drift between mouse and touch.
|
|
9
|
+
//
|
|
10
|
+
// Loaded with `import()` on the first touch that lands on a draggable row, so
|
|
11
|
+
// desktop users never download it. The 350 ms long press below absorbs the
|
|
12
|
+
// fetch rather than following it: `start` takes the pointerdown timestamp and
|
|
13
|
+
// subtracts the time already spent waiting, so a fetch that finishes inside the
|
|
14
|
+
// press costs the user nothing.
|
|
15
|
+
//
|
|
16
|
+
// A touch that starts on a row must still be able to SCROLL the grid, so the
|
|
17
|
+
// drag only begins after a long press; moving before that threshold hands the
|
|
18
|
+
// gesture back to the browser.
|
|
19
|
+
|
|
20
|
+
/** Everything the touch path needs from the `createRowDrag` closure. */
|
|
21
|
+
export type TouchDragDeps = {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
ctx: any;
|
|
24
|
+
managed: () => boolean;
|
|
25
|
+
originalAt: (rowIndex: number) => unknown;
|
|
26
|
+
commitDropOnRow: (rowIndex: number, side: "before" | "after") => void;
|
|
27
|
+
clearIndicators: () => void;
|
|
28
|
+
cancelPendingLeave: () => void;
|
|
29
|
+
/** Publish the dragged row on the shared cross-grid bus. */
|
|
30
|
+
openBus: (row: unknown) => void;
|
|
31
|
+
closeBus: () => void;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const LONG_PRESS_MS = 350;
|
|
35
|
+
/** Movement (px) before the long press is treated as a scroll instead. */
|
|
36
|
+
const SCROLL_SLOP_PX = 10;
|
|
37
|
+
/** Distance from an edge (px) at which the grid starts auto-scrolling. */
|
|
38
|
+
const EDGE_PX = 48;
|
|
39
|
+
const EDGE_SPEED_PX = 12;
|
|
40
|
+
|
|
41
|
+
type TouchState = {
|
|
42
|
+
pointerId: number;
|
|
43
|
+
rowIndex: number;
|
|
44
|
+
startX: number;
|
|
45
|
+
startY: number;
|
|
46
|
+
started: boolean;
|
|
47
|
+
timer: ReturnType<typeof setTimeout> | null;
|
|
48
|
+
scrollFrame: number | null;
|
|
49
|
+
scroller: HTMLElement | null;
|
|
50
|
+
root: HTMLElement | null;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** What {@link createTouchDrag} returns. */
|
|
54
|
+
export type TouchDragHandle = {
|
|
55
|
+
/**
|
|
56
|
+
* @param pressStartedAt `performance.now()` at the pointerdown that began
|
|
57
|
+
* this press. Defaults to now. See the long-press comment in `start`.
|
|
58
|
+
*/
|
|
59
|
+
start: (e: PointerEvent, rowIndex: number, pressStartedAt?: number) => void;
|
|
60
|
+
destroy: () => void;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export function createTouchDrag(deps: TouchDragDeps): TouchDragHandle {
|
|
64
|
+
const { ctx } = deps;
|
|
65
|
+
let touch: TouchState | null = null;
|
|
66
|
+
|
|
67
|
+
/** Resolve the row under a viewport point, and which half of it. */
|
|
68
|
+
function rowAtPoint(x: number, y: number): { index: number; side: "before" | "after" } | null {
|
|
69
|
+
const el = document.elementFromPoint(x, y) as HTMLElement | null;
|
|
70
|
+
const tr = el?.closest?.("tr.sv-grid-row") as HTMLElement | null;
|
|
71
|
+
if (!tr) return null;
|
|
72
|
+
const marker = tr.querySelector<HTMLElement>("[data-svgrid-row]");
|
|
73
|
+
const raw = marker?.dataset.svgridRow;
|
|
74
|
+
if (raw == null) return null;
|
|
75
|
+
const index = Number(raw);
|
|
76
|
+
if (!Number.isFinite(index)) return null;
|
|
77
|
+
const rect = tr.getBoundingClientRect();
|
|
78
|
+
return { index, side: y < rect.top + rect.height / 2 ? "before" : "after" };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function stopEdgeScroll() {
|
|
82
|
+
if (touch?.scrollFrame != null) {
|
|
83
|
+
cancelAnimationFrame(touch.scrollFrame);
|
|
84
|
+
touch.scrollFrame = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Keep scrolling while the finger is parked near the top or bottom edge. */
|
|
89
|
+
function edgeScroll(clientY: number) {
|
|
90
|
+
const scroller = touch?.scroller;
|
|
91
|
+
if (!touch || !scroller) return;
|
|
92
|
+
const rect = scroller.getBoundingClientRect();
|
|
93
|
+
let dy = 0;
|
|
94
|
+
if (clientY < rect.top + EDGE_PX) dy = -EDGE_SPEED_PX;
|
|
95
|
+
else if (clientY > rect.bottom - EDGE_PX) dy = EDGE_SPEED_PX;
|
|
96
|
+
stopEdgeScroll();
|
|
97
|
+
if (dy === 0) return;
|
|
98
|
+
const step = () => {
|
|
99
|
+
if (!touch?.started) return;
|
|
100
|
+
scroller.scrollTop += dy;
|
|
101
|
+
// Re-hit-test as rows move under a stationary finger, otherwise the
|
|
102
|
+
// indicator freezes on whichever row happened to be there at touch time.
|
|
103
|
+
const hit = rowAtPoint(touch.startX, clientY);
|
|
104
|
+
if (hit) {
|
|
105
|
+
ctx.rowDropIndex = hit.index;
|
|
106
|
+
ctx.rowDropSide = hit.side;
|
|
107
|
+
}
|
|
108
|
+
touch.scrollFrame = requestAnimationFrame(step);
|
|
109
|
+
};
|
|
110
|
+
touch.scrollFrame = requestAnimationFrame(step);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// `pointermove.preventDefault()` does NOT stop iOS scrolling; only a
|
|
114
|
+
// non-passive `touchmove` does. Registered for the life of the drag.
|
|
115
|
+
function blockTouchScroll(e: TouchEvent) {
|
|
116
|
+
if (touch?.started) e.preventDefault();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function detach() {
|
|
120
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
121
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
122
|
+
window.removeEventListener("pointercancel", onPointerCancel);
|
|
123
|
+
window.removeEventListener("touchmove", blockTouchScroll);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function end(commit: boolean) {
|
|
127
|
+
if (!touch) return;
|
|
128
|
+
const t = touch;
|
|
129
|
+
if (t.timer) clearTimeout(t.timer);
|
|
130
|
+
stopEdgeScroll();
|
|
131
|
+
touch = null;
|
|
132
|
+
detach();
|
|
133
|
+
t.root?.classList.remove("sv-grid-row-drag-active");
|
|
134
|
+
if (!t.started) return;
|
|
135
|
+
if (commit && ctx.rowDropIndex != null) {
|
|
136
|
+
deps.commitDropOnRow(
|
|
137
|
+
ctx.rowDropIndex as number,
|
|
138
|
+
(ctx.rowDropSide ?? "before") as "before" | "after",
|
|
139
|
+
);
|
|
140
|
+
} else {
|
|
141
|
+
deps.clearIndicators();
|
|
142
|
+
deps.closeBus();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function onPointerMove(e: PointerEvent) {
|
|
147
|
+
if (!touch || e.pointerId !== touch.pointerId) return;
|
|
148
|
+
if (!touch.started) {
|
|
149
|
+
// Still inside the long press: a real move means the user is scrolling.
|
|
150
|
+
const moved = Math.abs(e.clientY - touch.startY) + Math.abs(e.clientX - touch.startX);
|
|
151
|
+
if (moved > SCROLL_SLOP_PX) end(false);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
e.preventDefault();
|
|
155
|
+
const hit = rowAtPoint(e.clientX, e.clientY);
|
|
156
|
+
if (hit) {
|
|
157
|
+
deps.cancelPendingLeave();
|
|
158
|
+
ctx.rowDropIndex = hit.index;
|
|
159
|
+
ctx.rowDropSide = hit.side;
|
|
160
|
+
}
|
|
161
|
+
touch.startX = e.clientX;
|
|
162
|
+
edgeScroll(e.clientY);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function onPointerUp(e: PointerEvent) {
|
|
166
|
+
if (!touch || e.pointerId !== touch.pointerId) return;
|
|
167
|
+
end(true);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function onPointerCancel(e: PointerEvent) {
|
|
171
|
+
if (!touch || e.pointerId !== touch.pointerId) return;
|
|
172
|
+
end(false);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
/** Begin a press that may become a drag. Caller has already checked touch. */
|
|
177
|
+
start(e: PointerEvent, rowIndex: number, pressStartedAt?: number) {
|
|
178
|
+
if (!deps.managed() || touch) return;
|
|
179
|
+
const row = deps.originalAt(rowIndex);
|
|
180
|
+
if (row == null) return;
|
|
181
|
+
const target = e.currentTarget as HTMLElement | null;
|
|
182
|
+
touch = {
|
|
183
|
+
pointerId: e.pointerId,
|
|
184
|
+
rowIndex,
|
|
185
|
+
startX: e.clientX,
|
|
186
|
+
startY: e.clientY,
|
|
187
|
+
started: false,
|
|
188
|
+
timer: null,
|
|
189
|
+
scrollFrame: null,
|
|
190
|
+
scroller: target?.closest?.<HTMLElement>(".sv-grid-container") ?? null,
|
|
191
|
+
root: target?.closest?.<HTMLElement>(".sv-grid-root") ?? null,
|
|
192
|
+
};
|
|
193
|
+
window.addEventListener("pointermove", onPointerMove, { passive: false });
|
|
194
|
+
window.addEventListener("pointerup", onPointerUp);
|
|
195
|
+
window.addEventListener("pointercancel", onPointerCancel);
|
|
196
|
+
window.addEventListener("touchmove", blockTouchScroll, { passive: false });
|
|
197
|
+
// The long press is measured from when the finger LANDED, not from when
|
|
198
|
+
// this module finished loading. `row-drag.ts` fetches it with import() on
|
|
199
|
+
// the first touch, and that fetch is not free - measured at ~190 ms cold.
|
|
200
|
+
// Starting the clock here would make the real cost `fetch + 350 ms`, so a
|
|
201
|
+
// user on a slow connection would have to hold noticeably longer for
|
|
202
|
+
// their first drag than for every one after it. Subtracting the elapsed
|
|
203
|
+
// time keeps it at 350 ms from the finger's point of view, which is what
|
|
204
|
+
// the comment at the top of this file has always claimed.
|
|
205
|
+
const waited = pressStartedAt == null ? 0 : Math.max(0, performance.now() - pressStartedAt);
|
|
206
|
+
touch.timer = setTimeout(() => {
|
|
207
|
+
if (!touch) return;
|
|
208
|
+
touch.started = true;
|
|
209
|
+
touch.timer = null;
|
|
210
|
+
touch.root?.classList.add("sv-grid-row-drag-active");
|
|
211
|
+
try {
|
|
212
|
+
target?.setPointerCapture?.(e.pointerId);
|
|
213
|
+
} catch {
|
|
214
|
+
// Not every environment implements pointer capture (tests, old WebViews).
|
|
215
|
+
}
|
|
216
|
+
deps.openBus(row);
|
|
217
|
+
ctx.rowDragActive = true;
|
|
218
|
+
ctx.rowDropIndex = rowIndex;
|
|
219
|
+
ctx.rowDropSide = "before";
|
|
220
|
+
}, Math.max(0, LONG_PRESS_MS - waited));
|
|
221
|
+
},
|
|
222
|
+
destroy() {
|
|
223
|
+
end(false);
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
}
|
package/src/row-drag.test.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Because the bus is shared, we can create TWO fake ctxs (two grids) and drive
|
|
7
7
|
* a genuine grid-to-grid move without mounting anything.
|
|
8
8
|
*/
|
|
9
|
-
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
9
|
+
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'
|
|
10
10
|
import { createRowDrag, rowDropZone } from './row-drag'
|
|
11
11
|
|
|
12
12
|
type AnyCtx = Record<string, any>
|
|
@@ -252,6 +252,19 @@ describe('createRowDrag - drop indicator during virtualized scroll (#69)', () =>
|
|
|
252
252
|
describe('createRowDrag - touch (#66)', () => {
|
|
253
253
|
const wait = (ms: number) => new Promise((r) => setTimeout(r, ms))
|
|
254
254
|
|
|
255
|
+
// `row-drag.ts` fetches the touch module with import() on the first touch,
|
|
256
|
+
// and that fetch is not free: measured at ~190 ms the first time a worker
|
|
257
|
+
// loads it, against the 400 ms budget the tests below allow for a 350 ms
|
|
258
|
+
// press. That left 50 ms of headroom and made this the only flaky suite in
|
|
259
|
+
// the run - green alone, red once the other 200 files were competing for the
|
|
260
|
+
// same worker. Warming the module here means the waits below measure the
|
|
261
|
+
// long press, which is what they are for, instead of racing the loader.
|
|
262
|
+
// The press-clock behaviour that the cold fetch exposed has its own test at
|
|
263
|
+
// the bottom of this block.
|
|
264
|
+
beforeAll(async () => {
|
|
265
|
+
await import('./row-drag-touch')
|
|
266
|
+
})
|
|
267
|
+
|
|
255
268
|
// `stubRowAt` replaces a global. Without restoring it, every later test in
|
|
256
269
|
// the worker inherits a fake elementFromPoint - which showed up as an
|
|
257
270
|
// intermittent failure elsewhere in the suite, not here.
|
|
@@ -293,10 +306,15 @@ describe('createRowDrag - touch (#66)', () => {
|
|
|
293
306
|
it('does not start until the long press elapses', async () => {
|
|
294
307
|
const ctx = makeCtx([{ id: 1, title: 'a' }, { id: 2, title: 'b' }], P)
|
|
295
308
|
const d = createRowDrag(ctx)
|
|
309
|
+
const pressedAt = performance.now()
|
|
296
310
|
d.onRowPointerDown(pointer('touch', 10), 0)
|
|
297
311
|
expect(ctx.rowDragActive).toBe(false)
|
|
298
312
|
await wait(400)
|
|
299
313
|
expect(ctx.rowDragActive).toBe(true)
|
|
314
|
+
// The name of this test is the assertion: it has to have WAITED. Without
|
|
315
|
+
// this line the test passes just as happily if the press threshold is
|
|
316
|
+
// deleted and the drag starts on contact.
|
|
317
|
+
expect(performance.now() - pressedAt).toBeGreaterThanOrEqual(340)
|
|
300
318
|
d.destroyRowDrag()
|
|
301
319
|
})
|
|
302
320
|
|
|
@@ -350,4 +368,34 @@ describe('createRowDrag - touch (#66)', () => {
|
|
|
350
368
|
expect((ctx.internalData as Task[]).map((r) => r.id)).toEqual([1, 2])
|
|
351
369
|
expect(ctx.rowDragActive).toBe(false)
|
|
352
370
|
})
|
|
371
|
+
|
|
372
|
+
// The press threshold is counted from the pointerdown, not from the moment
|
|
373
|
+
// the lazily-imported touch module finished loading. Driving createTouchDrag
|
|
374
|
+
// directly is the only way to state that: through createRowDrag the fetch
|
|
375
|
+
// latency is whatever the machine happens to do that run, which is exactly
|
|
376
|
+
// the non-determinism this behaviour exists to cancel out.
|
|
377
|
+
it('counts the long press from the pointerdown, not from when the module loaded', async () => {
|
|
378
|
+
const { createTouchDrag } = await import('./row-drag-touch')
|
|
379
|
+
const rows: Task[] = [{ id: 1, title: 'a' }, { id: 2, title: 'b' }]
|
|
380
|
+
const ctx = makeCtx(rows, P)
|
|
381
|
+
const handle = createTouchDrag({
|
|
382
|
+
ctx,
|
|
383
|
+
managed: () => true,
|
|
384
|
+
originalAt: (i: number) => (ctx.internalData as Task[])[i],
|
|
385
|
+
commitDropOnRow: () => {},
|
|
386
|
+
clearIndicators: () => {},
|
|
387
|
+
cancelPendingLeave: () => {},
|
|
388
|
+
openBus: () => {},
|
|
389
|
+
closeBus: () => {},
|
|
390
|
+
})
|
|
391
|
+
|
|
392
|
+
// 300 ms of the 350 ms press already went on fetching this module, so only
|
|
393
|
+
// ~50 ms of it is left. Before the fix the clock restarted here and the
|
|
394
|
+
// user paid 650 ms for their first drag of the session.
|
|
395
|
+
handle.start(pointer('touch', 10), 0, performance.now() - 300)
|
|
396
|
+
expect(ctx.rowDragActive).toBe(false)
|
|
397
|
+
await wait(150)
|
|
398
|
+
expect(ctx.rowDragActive).toBe(true)
|
|
399
|
+
handle.destroy()
|
|
400
|
+
})
|
|
353
401
|
})
|
package/src/row-drag.ts
CHANGED
|
@@ -217,8 +217,8 @@ export function createRowDrag<TFeatures, TData>(ctx: any) {
|
|
|
217
217
|
|
|
218
218
|
// Touch drag (#66) lives in its own module and is fetched on the first touch
|
|
219
219
|
// that lands on a draggable row, so desktop never downloads it. The 350 ms
|
|
220
|
-
// long press inside it
|
|
221
|
-
//
|
|
220
|
+
// long press inside it absorbs the fetch: the press clock starts at
|
|
221
|
+
// pointerdown here, so the fetch is free unless it outlasts the press.
|
|
222
222
|
let touchDrag: import("./row-drag-touch").TouchDragHandle | null = null;
|
|
223
223
|
let touchLoading = false;
|
|
224
224
|
|
|
@@ -268,6 +268,10 @@ export function createRowDrag<TFeatures, TData>(ctx: any) {
|
|
|
268
268
|
const pid = e.pointerId;
|
|
269
269
|
const startX = e.clientX;
|
|
270
270
|
const startY = e.clientY;
|
|
271
|
+
// Handed to the touch module so its long press is counted from HERE, not
|
|
272
|
+
// from whenever the import below resolves. Without it the first touch drag
|
|
273
|
+
// of a session costs `fetch + 350 ms` while every later one costs 350 ms.
|
|
274
|
+
const pressStartedAt = performance.now();
|
|
271
275
|
let aborted = false;
|
|
272
276
|
function stopWatching() {
|
|
273
277
|
window.removeEventListener("pointermove", onEarlyMove);
|
|
@@ -306,7 +310,7 @@ export function createRowDrag<TFeatures, TData>(ctx: any) {
|
|
|
306
310
|
stopWatching();
|
|
307
311
|
if (aborted || !managed()) return;
|
|
308
312
|
touchDrag = m.createTouchDrag(touchDeps());
|
|
309
|
-
touchDrag.start(snapshot, rowIndex);
|
|
313
|
+
touchDrag.start(snapshot, rowIndex, pressStartedAt);
|
|
310
314
|
});
|
|
311
315
|
}
|
|
312
316
|
|