@toolbox-web/grid 1.6.2 → 1.8.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/README.md +51 -15
- package/all.js +267 -158
- package/all.js.map +1 -1
- package/index.js +866 -722
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +68 -1
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/internal/header.d.ts.map +1 -1
- package/lib/core/plugin/base-plugin.d.ts +182 -1
- package/lib/core/plugin/base-plugin.d.ts.map +1 -1
- package/lib/core/plugin/index.d.ts +1 -1
- package/lib/core/plugin/index.d.ts.map +1 -1
- package/lib/core/plugin/plugin-manager.d.ts +56 -1
- package/lib/core/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/core/plugin/types.d.ts +36 -0
- package/lib/core/plugin/types.d.ts.map +1 -1
- package/lib/core/types.d.ts +1349 -31
- package/lib/core/types.d.ts.map +1 -1
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.js +140 -87
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +64 -7
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
- package/lib/plugins/context-menu/index.js +123 -65
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts +6 -1
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +95 -13
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/export/index.js +91 -34
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/FilteringPlugin.d.ts +6 -1
- package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
- package/lib/plugins/filtering/index.js +192 -123
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +57 -0
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +7 -2
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-rows/index.js +142 -60
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +69 -12
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +70 -13
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +3 -3
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/pinned-columns/index.js +106 -36
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +57 -0
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +57 -0
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/print/PrintPlugin.d.ts.map +1 -1
- package/lib/plugins/print/index.js +58 -1
- package/lib/plugins/print/index.js.map +1 -1
- package/lib/plugins/reorder/ReorderPlugin.d.ts.map +1 -1
- package/lib/plugins/reorder/column-drag.d.ts +2 -2
- package/lib/plugins/reorder/index.js +68 -17
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/responsive/ResponsivePlugin.d.ts +6 -1
- package/lib/plugins/responsive/ResponsivePlugin.d.ts.map +1 -1
- package/lib/plugins/responsive/index.js +125 -54
- package/lib/plugins/responsive/index.js.map +1 -1
- package/lib/plugins/row-reorder/index.js +169 -112
- package/lib/plugins/row-reorder/index.js.map +1 -1
- package/lib/plugins/selection/SelectionPlugin.d.ts +14 -2
- package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
- package/lib/plugins/selection/index.js +84 -7
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js +79 -22
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/TreePlugin.d.ts +7 -1
- package/lib/plugins/tree/TreePlugin.d.ts.map +1 -1
- package/lib/plugins/tree/index.js +140 -58
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts +6 -1
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts.map +1 -1
- package/lib/plugins/undo-redo/index.js +79 -10
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +57 -0
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/public.d.ts +80 -2
- package/public.d.ts.map +1 -1
- package/umd/grid.all.umd.js +25 -25
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +15 -15
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/clipboard.umd.js +5 -5
- package/umd/plugins/clipboard.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +1 -1
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/editing.umd.js +1 -1
- package/umd/plugins/editing.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +2 -2
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/pinned-columns.umd.js +1 -1
- package/umd/plugins/pinned-columns.umd.js.map +1 -1
- package/umd/plugins/print.umd.js +1 -1
- package/umd/plugins/print.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/responsive.umd.js +1 -1
- package/umd/plugins/responsive.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +2 -2
- package/umd/plugins/selection.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
- package/umd/plugins/undo-redo.umd.js +1 -1
- package/umd/plugins/undo-redo.umd.js.map +1 -1
|
@@ -5,27 +5,27 @@ const m = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[
|
|
|
5
5
|
R.innerHTML = '<div class="cell" role="gridcell" part="cell"></div>';
|
|
6
6
|
const E = document.createElement("template");
|
|
7
7
|
E.innerHTML = '<div class="data-grid-row" role="row" part="row"></div>';
|
|
8
|
-
function
|
|
8
|
+
function b(l, e) {
|
|
9
9
|
if (l._virtualization?.enabled) {
|
|
10
|
-
const { rowHeight:
|
|
10
|
+
const { rowHeight: i, container: n, viewportEl: c } = l._virtualization, a = n, u = c?.clientHeight ?? a?.clientHeight ?? 0;
|
|
11
11
|
if (a && u > 0) {
|
|
12
|
-
const d = l._focusRow *
|
|
13
|
-
d < a.scrollTop ? a.scrollTop = d : d +
|
|
12
|
+
const d = l._focusRow * i;
|
|
13
|
+
d < a.scrollTop ? a.scrollTop = d : d + i > a.scrollTop + u && (a.scrollTop = d - u + i);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const t = l._activeEditRows !== void 0 && l._activeEditRows !== -1;
|
|
17
|
+
t || l.refreshVirtualWindow(!1), v(l._bodyEl), Array.from(l._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((i) => {
|
|
18
|
+
i.setAttribute("aria-selected", "false");
|
|
19
19
|
});
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
const
|
|
23
|
-
let n =
|
|
24
|
-
if ((!n || !n.classList?.contains("cell")) && (n =
|
|
20
|
+
const r = l._focusRow, o = l._virtualization.start ?? 0, s = l._virtualization.end ?? l._rows.length;
|
|
21
|
+
if (r >= o && r < s) {
|
|
22
|
+
const i = l._bodyEl.querySelectorAll(".data-grid-row")[r - o];
|
|
23
|
+
let n = i?.children[l._focusCol];
|
|
24
|
+
if ((!n || !n.classList?.contains("cell")) && (n = i?.querySelector(`.cell[data-col="${l._focusCol}"]`) ?? i?.querySelector(".cell[data-col]")), n) {
|
|
25
25
|
n.classList.add("cell-focus"), n.setAttribute("aria-selected", "true");
|
|
26
26
|
const c = l.querySelector(".tbw-scroll-area");
|
|
27
|
-
if (c && n && !
|
|
28
|
-
const a = l._getHorizontalScrollOffsets?.(
|
|
27
|
+
if (c && n && !t) {
|
|
28
|
+
const a = l._getHorizontalScrollOffsets?.(i ?? void 0, n) ?? { left: 0, right: 0 };
|
|
29
29
|
if (!a.skipScroll) {
|
|
30
30
|
const u = n.getBoundingClientRect(), d = c.getBoundingClientRect(), g = u.left - d.left + c.scrollLeft, h = g + u.width, w = c.scrollLeft + a.left, f = c.scrollLeft + c.clientWidth - a.right;
|
|
31
31
|
g < w ? c.scrollLeft = g - a.left : h > f && (c.scrollLeft = h - c.clientWidth + a.right);
|
|
@@ -48,7 +48,7 @@ function p(l, e) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
const
|
|
51
|
+
const p = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', _ = {
|
|
52
52
|
expand: "▶",
|
|
53
53
|
collapse: "▼",
|
|
54
54
|
sortAsc: "▲",
|
|
@@ -57,11 +57,11 @@ const b = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentCo
|
|
|
57
57
|
submenuArrow: "▶",
|
|
58
58
|
dragHandle: "⋮⋮",
|
|
59
59
|
toolPanel: "☰",
|
|
60
|
-
filter:
|
|
61
|
-
filterActive:
|
|
60
|
+
filter: p,
|
|
61
|
+
filterActive: p,
|
|
62
62
|
print: "🖨️"
|
|
63
63
|
};
|
|
64
|
-
class
|
|
64
|
+
class y {
|
|
65
65
|
/**
|
|
66
66
|
* Plugin dependencies - declare other plugins this one requires.
|
|
67
67
|
*
|
|
@@ -188,16 +188,73 @@ class _ {
|
|
|
188
188
|
/**
|
|
189
189
|
* Emit a custom event from the grid.
|
|
190
190
|
*/
|
|
191
|
-
emit(e,
|
|
192
|
-
this.grid?.dispatchEvent?.(new CustomEvent(e, { detail:
|
|
191
|
+
emit(e, t) {
|
|
192
|
+
this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: t, bubbles: !0 }));
|
|
193
193
|
}
|
|
194
194
|
/**
|
|
195
195
|
* Emit a cancelable custom event from the grid.
|
|
196
196
|
* @returns `true` if the event was cancelled (preventDefault called), `false` otherwise
|
|
197
197
|
*/
|
|
198
|
-
emitCancelable(e,
|
|
199
|
-
const
|
|
200
|
-
return this.grid?.dispatchEvent?.(
|
|
198
|
+
emitCancelable(e, t) {
|
|
199
|
+
const r = new CustomEvent(e, { detail: t, bubbles: !0, cancelable: !0 });
|
|
200
|
+
return this.grid?.dispatchEvent?.(r), r.defaultPrevented;
|
|
201
|
+
}
|
|
202
|
+
// =========================================================================
|
|
203
|
+
// Event Bus - Plugin-to-Plugin Communication
|
|
204
|
+
// =========================================================================
|
|
205
|
+
/**
|
|
206
|
+
* Subscribe to an event from another plugin.
|
|
207
|
+
* The subscription is automatically cleaned up when this plugin is detached.
|
|
208
|
+
*
|
|
209
|
+
* @category Plugin Development
|
|
210
|
+
* @param eventType - The event type to listen for (e.g., 'filter-change')
|
|
211
|
+
* @param callback - The callback to invoke when the event is emitted
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* // In attach() or other initialization
|
|
216
|
+
* this.on('filter-change', (detail) => {
|
|
217
|
+
* console.log('Filter changed:', detail);
|
|
218
|
+
* });
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
on(e, t) {
|
|
222
|
+
this.grid?._pluginManager?.subscribe(this, e, t);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Unsubscribe from a plugin event.
|
|
226
|
+
*
|
|
227
|
+
* @category Plugin Development
|
|
228
|
+
* @param eventType - The event type to stop listening for
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* this.off('filter-change');
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
off(e) {
|
|
236
|
+
this.grid?._pluginManager?.unsubscribe(this, e);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Emit an event to other plugins via the Event Bus.
|
|
240
|
+
* This is for inter-plugin communication only; it does NOT dispatch DOM events.
|
|
241
|
+
* Use `emit()` to dispatch DOM events that external consumers can listen to.
|
|
242
|
+
*
|
|
243
|
+
* @category Plugin Development
|
|
244
|
+
* @param eventType - The event type to emit (should be declared in manifest.events)
|
|
245
|
+
* @param detail - The event payload
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```typescript
|
|
249
|
+
* // Emit to other plugins (not DOM)
|
|
250
|
+
* this.emitPluginEvent('filter-change', { field: 'name', value: 'Alice' });
|
|
251
|
+
*
|
|
252
|
+
* // For DOM events that consumers can addEventListener to:
|
|
253
|
+
* this.emit('filter-change', { field: 'name', value: 'Alice' });
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
256
|
+
emitPluginEvent(e, t) {
|
|
257
|
+
this.grid?._pluginManager?.emitPluginEvent(e, t);
|
|
201
258
|
}
|
|
202
259
|
/**
|
|
203
260
|
* Request a re-render of the grid.
|
|
@@ -285,7 +342,7 @@ class _ {
|
|
|
285
342
|
*/
|
|
286
343
|
get gridIcons() {
|
|
287
344
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
288
|
-
return { ...
|
|
345
|
+
return { ..._, ...e };
|
|
289
346
|
}
|
|
290
347
|
// #region Animation Helpers
|
|
291
348
|
/**
|
|
@@ -308,8 +365,8 @@ class _ {
|
|
|
308
365
|
const e = this.grid?.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
309
366
|
if (e === !1 || e === "off") return !1;
|
|
310
367
|
if (e === !0 || e === "on") return !0;
|
|
311
|
-
const
|
|
312
|
-
return
|
|
368
|
+
const t = this.gridElement;
|
|
369
|
+
return t ? getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
313
370
|
}
|
|
314
371
|
/**
|
|
315
372
|
* Get the animation duration in milliseconds from CSS variable.
|
|
@@ -326,8 +383,8 @@ class _ {
|
|
|
326
383
|
get animationDuration() {
|
|
327
384
|
const e = this.gridElement;
|
|
328
385
|
if (e) {
|
|
329
|
-
const
|
|
330
|
-
if (!isNaN(
|
|
386
|
+
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), r = parseInt(t, 10);
|
|
387
|
+
if (!isNaN(r)) return r;
|
|
331
388
|
}
|
|
332
389
|
return 200;
|
|
333
390
|
}
|
|
@@ -340,8 +397,8 @@ class _ {
|
|
|
340
397
|
* @param pluginOverride - Optional plugin-level override
|
|
341
398
|
* @returns The resolved icon value
|
|
342
399
|
*/
|
|
343
|
-
resolveIcon(e,
|
|
344
|
-
return
|
|
400
|
+
resolveIcon(e, t) {
|
|
401
|
+
return t !== void 0 ? t : this.gridIcons[e];
|
|
345
402
|
}
|
|
346
403
|
/**
|
|
347
404
|
* Set an icon value on an element.
|
|
@@ -350,8 +407,8 @@ class _ {
|
|
|
350
407
|
* @param element - The element to set the icon on
|
|
351
408
|
* @param icon - The icon value (string or HTMLElement)
|
|
352
409
|
*/
|
|
353
|
-
setIcon(e,
|
|
354
|
-
typeof
|
|
410
|
+
setIcon(e, t) {
|
|
411
|
+
typeof t == "string" ? e.innerHTML = t : t instanceof HTMLElement && (e.innerHTML = "", e.appendChild(t.cloneNode(!0)));
|
|
355
412
|
}
|
|
356
413
|
/**
|
|
357
414
|
* Log a warning message.
|
|
@@ -362,7 +419,7 @@ class _ {
|
|
|
362
419
|
// #endregion
|
|
363
420
|
}
|
|
364
421
|
const C = '@layer tbw-plugins{.dg-row-drag-handle{display:flex;align-items:center;justify-content:center;cursor:grab;-webkit-user-select:none;user-select:none;color:var(--tbw-row-reorder-handle-color, var(--tbw-color-fg-muted));transition:color var(--tbw-transition-duration, .12s) var(--tbw-transition-ease, ease);font-size:var(--tbw-font-size, 1em);letter-spacing:-2px}.dg-row-drag-handle:hover{color:var(--tbw-row-reorder-handle-hover, var(--tbw-color-fg))}.dg-row-drag-handle:active{cursor:grabbing}.data-grid-row.dragging{opacity:.6}.data-grid-row.drop-target{position:relative}.data-grid-row.drop-target.drop-before:before{content:"";position:absolute;top:0;left:0;right:0;height:2px;background-color:var(--tbw-row-reorder-indicator, var(--tbw-color-accent));z-index:10}.data-grid-row.drop-target.drop-after:after{content:"";position:absolute;bottom:0;left:0;right:0;height:2px;background-color:var(--tbw-row-reorder-indicator, var(--tbw-color-accent));z-index:10}.data-grid-row.keyboard-moving{background-color:var(--tbw-row-reorder-moving-bg, var(--tbw-focus-background));box-shadow:0 0 0 1px var(--tbw-row-reorder-moving-border, var(--tbw-color-accent)) inset}.data-grid-row.flip-animating{transition:transform var(--tbw-animation-duration, .2s) ease-out;will-change:transform;z-index:1}}', A = "__tbw_row_drag";
|
|
365
|
-
class L extends
|
|
422
|
+
class L extends y {
|
|
366
423
|
/** @internal */
|
|
367
424
|
name = "rowReorder";
|
|
368
425
|
/** @internal */
|
|
@@ -405,7 +462,7 @@ class L extends _ {
|
|
|
405
462
|
processColumns(e) {
|
|
406
463
|
if (!this.config.showDragHandle)
|
|
407
464
|
return [...e];
|
|
408
|
-
const
|
|
465
|
+
const t = {
|
|
409
466
|
field: A,
|
|
410
467
|
header: "",
|
|
411
468
|
width: this.config.dragHandleWidth ?? 40,
|
|
@@ -418,25 +475,25 @@ class L extends _ {
|
|
|
418
475
|
utility: !0
|
|
419
476
|
},
|
|
420
477
|
viewRenderer: () => {
|
|
421
|
-
const
|
|
422
|
-
return
|
|
478
|
+
const r = document.createElement("div");
|
|
479
|
+
return r.className = "dg-row-drag-handle", r.setAttribute("aria-label", "Drag to reorder"), r.setAttribute("role", "button"), r.setAttribute("tabindex", "-1"), r.draggable = !0, this.setIcon(r, this.resolveIcon("dragHandle")), r;
|
|
423
480
|
}
|
|
424
481
|
};
|
|
425
|
-
return this.config.dragHandlePosition === "right" ? [...e,
|
|
482
|
+
return this.config.dragHandlePosition === "right" ? [...e, t] : [t, ...e];
|
|
426
483
|
}
|
|
427
484
|
/** @internal */
|
|
428
485
|
afterRender() {
|
|
429
486
|
if (!this.config.showDragHandle) return;
|
|
430
487
|
const e = this.gridElement;
|
|
431
488
|
if (!e) return;
|
|
432
|
-
e.querySelectorAll(".dg-row-drag-handle").forEach((
|
|
433
|
-
const s =
|
|
489
|
+
e.querySelectorAll(".dg-row-drag-handle").forEach((o) => {
|
|
490
|
+
const s = o;
|
|
434
491
|
if (s.getAttribute("data-drag-bound")) return;
|
|
435
492
|
s.setAttribute("data-drag-bound", "true");
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
}), e.querySelectorAll(".data-grid-row").forEach((
|
|
439
|
-
const s =
|
|
493
|
+
const i = s.closest(".data-grid-row");
|
|
494
|
+
i && this.setupHandleDragListeners(s, i);
|
|
495
|
+
}), e.querySelectorAll(".data-grid-row").forEach((o) => {
|
|
496
|
+
const s = o;
|
|
440
497
|
s.getAttribute("data-drop-bound") || (s.setAttribute("data-drop-bound", "true"), this.setupRowDropListeners(s));
|
|
441
498
|
});
|
|
442
499
|
}
|
|
@@ -447,13 +504,13 @@ class L extends _ {
|
|
|
447
504
|
onKeyDown(e) {
|
|
448
505
|
if (!this.config.enableKeyboard || !e.ctrlKey || e.key !== "ArrowUp" && e.key !== "ArrowDown")
|
|
449
506
|
return;
|
|
450
|
-
const
|
|
451
|
-
if (
|
|
452
|
-
const s = e.key === "ArrowUp" ? "up" : "down",
|
|
453
|
-
if (
|
|
454
|
-
const n =
|
|
455
|
-
if (!(this.config.canMove && !this.config.canMove(n,
|
|
456
|
-
return this.handleKeyboardMove(n,
|
|
507
|
+
const t = this.grid, r = t._focusRow, o = t._rows ?? this.sourceRows;
|
|
508
|
+
if (r < 0 || r >= o.length) return;
|
|
509
|
+
const s = e.key === "ArrowUp" ? "up" : "down", i = s === "up" ? r - 1 : r + 1;
|
|
510
|
+
if (i < 0 || i >= o.length) return;
|
|
511
|
+
const n = o[r];
|
|
512
|
+
if (!(this.config.canMove && !this.config.canMove(n, r, i, s)))
|
|
513
|
+
return this.handleKeyboardMove(n, r, i, s, t._focusCol), e.preventDefault(), e.stopPropagation(), !0;
|
|
457
514
|
}
|
|
458
515
|
/**
|
|
459
516
|
* Flush pending keyboard moves when user clicks a cell.
|
|
@@ -470,33 +527,33 @@ class L extends _ {
|
|
|
470
527
|
* @param fromIndex - Current index of the row
|
|
471
528
|
* @param toIndex - Target index
|
|
472
529
|
*/
|
|
473
|
-
moveRow(e,
|
|
474
|
-
const
|
|
475
|
-
if (e < 0 || e >=
|
|
476
|
-
const
|
|
477
|
-
this.config.canMove && !this.config.canMove(s, e,
|
|
530
|
+
moveRow(e, t) {
|
|
531
|
+
const r = [...this.sourceRows];
|
|
532
|
+
if (e < 0 || e >= r.length || t < 0 || t >= r.length || e === t) return;
|
|
533
|
+
const o = t < e ? "up" : "down", s = r[e];
|
|
534
|
+
this.config.canMove && !this.config.canMove(s, e, t, o) || this.executeMove(s, e, t, "keyboard");
|
|
478
535
|
}
|
|
479
536
|
/**
|
|
480
537
|
* Check if a row can be moved to a position.
|
|
481
538
|
* @param fromIndex - Current index of the row
|
|
482
539
|
* @param toIndex - Target index
|
|
483
540
|
*/
|
|
484
|
-
canMoveRow(e,
|
|
485
|
-
const
|
|
486
|
-
if (e < 0 || e >=
|
|
541
|
+
canMoveRow(e, t) {
|
|
542
|
+
const r = this.sourceRows;
|
|
543
|
+
if (e < 0 || e >= r.length || t < 0 || t >= r.length || e === t) return !1;
|
|
487
544
|
if (!this.config.canMove) return !0;
|
|
488
|
-
const
|
|
489
|
-
return this.config.canMove(
|
|
545
|
+
const o = t < e ? "up" : "down";
|
|
546
|
+
return this.config.canMove(r[e], e, t, o);
|
|
490
547
|
}
|
|
491
548
|
// #endregion
|
|
492
549
|
// #region Private Methods
|
|
493
550
|
/**
|
|
494
551
|
* Set up drag start/end listeners on the drag handle element.
|
|
495
552
|
*/
|
|
496
|
-
setupHandleDragListeners(e,
|
|
497
|
-
e.addEventListener("dragstart", (
|
|
498
|
-
const
|
|
499
|
-
|
|
553
|
+
setupHandleDragListeners(e, t) {
|
|
554
|
+
e.addEventListener("dragstart", (r) => {
|
|
555
|
+
const o = this.getRowIndex(t);
|
|
556
|
+
o < 0 || (this.isDragging = !0, this.draggedRowIndex = o, r.dataTransfer && (r.dataTransfer.effectAllowed = "move", r.dataTransfer.setData("text/plain", String(o))), t.classList.add("dragging"));
|
|
500
557
|
}), e.addEventListener("dragend", () => {
|
|
501
558
|
this.isDragging = !1, this.draggedRowIndex = null, this.dropRowIndex = null, this.clearDragClasses();
|
|
502
559
|
});
|
|
@@ -506,21 +563,21 @@ class L extends _ {
|
|
|
506
563
|
* All rows are valid drop targets during drag operations.
|
|
507
564
|
*/
|
|
508
565
|
setupRowDropListeners(e) {
|
|
509
|
-
e.addEventListener("dragover", (
|
|
510
|
-
if (
|
|
511
|
-
const
|
|
512
|
-
if (
|
|
513
|
-
const
|
|
514
|
-
this.dropRowIndex =
|
|
566
|
+
e.addEventListener("dragover", (t) => {
|
|
567
|
+
if (t.preventDefault(), !this.isDragging || this.draggedRowIndex === null) return;
|
|
568
|
+
const r = this.getRowIndex(e);
|
|
569
|
+
if (r < 0 || r === this.draggedRowIndex) return;
|
|
570
|
+
const o = e.getBoundingClientRect(), s = o.top + o.height / 2, i = t.clientY < s;
|
|
571
|
+
this.dropRowIndex = i ? r : r + 1, e.classList.add("drop-target"), e.classList.toggle("drop-before", i), e.classList.toggle("drop-after", !i);
|
|
515
572
|
}), e.addEventListener("dragleave", () => {
|
|
516
573
|
e.classList.remove("drop-target", "drop-before", "drop-after");
|
|
517
|
-
}), e.addEventListener("drop", (
|
|
518
|
-
|
|
519
|
-
const
|
|
520
|
-
let
|
|
521
|
-
if (!(!this.isDragging ||
|
|
522
|
-
const
|
|
523
|
-
(!this.config.canMove || this.config.canMove(
|
|
574
|
+
}), e.addEventListener("drop", (t) => {
|
|
575
|
+
t.preventDefault();
|
|
576
|
+
const r = this.draggedRowIndex;
|
|
577
|
+
let o = this.dropRowIndex;
|
|
578
|
+
if (!(!this.isDragging || r === null || o === null) && (o > r && o--, r !== o)) {
|
|
579
|
+
const i = this.sourceRows[r], n = o < r ? "up" : "down";
|
|
580
|
+
(!this.config.canMove || this.config.canMove(i, r, o, n)) && this.executeMove(i, r, o, "drag");
|
|
524
581
|
}
|
|
525
582
|
});
|
|
526
583
|
}
|
|
@@ -528,14 +585,14 @@ class L extends _ {
|
|
|
528
585
|
* Handle debounced keyboard moves.
|
|
529
586
|
* Rows move immediately for visual feedback, but the event emission is debounced.
|
|
530
587
|
*/
|
|
531
|
-
handleKeyboardMove(e,
|
|
532
|
-
this.pendingMove ? this.pendingMove.currentIndex =
|
|
533
|
-
originalIndex:
|
|
534
|
-
currentIndex:
|
|
588
|
+
handleKeyboardMove(e, t, r, o, s) {
|
|
589
|
+
this.pendingMove ? this.pendingMove.currentIndex = r : this.pendingMove = {
|
|
590
|
+
originalIndex: t,
|
|
591
|
+
currentIndex: r,
|
|
535
592
|
row: e
|
|
536
593
|
}, this.lastFocusCol = s;
|
|
537
|
-
const
|
|
538
|
-
n.splice(
|
|
594
|
+
const i = this.grid, n = [...i._rows ?? this.sourceRows], [c] = n.splice(t, 1);
|
|
595
|
+
n.splice(r, 0, c), i._rows = n, i._focusRow = r, i._focusCol = s, i.refreshVirtualWindow(!0), b(i), this.clearDebounceTimer(), this.debounceTimer = setTimeout(() => {
|
|
539
596
|
this.flushPendingMove();
|
|
540
597
|
}, this.config.debounceMs ?? 300);
|
|
541
598
|
}
|
|
@@ -545,40 +602,40 @@ class L extends _ {
|
|
|
545
602
|
*/
|
|
546
603
|
flushPendingMove() {
|
|
547
604
|
if (this.clearDebounceTimer(), !this.pendingMove) return;
|
|
548
|
-
const { originalIndex: e, currentIndex:
|
|
549
|
-
if (this.pendingMove = null, e ===
|
|
550
|
-
const
|
|
551
|
-
row:
|
|
605
|
+
const { originalIndex: e, currentIndex: t, row: r } = this.pendingMove;
|
|
606
|
+
if (this.pendingMove = null, e === t) return;
|
|
607
|
+
const o = {
|
|
608
|
+
row: r,
|
|
552
609
|
fromIndex: e,
|
|
553
|
-
toIndex:
|
|
610
|
+
toIndex: t,
|
|
554
611
|
rows: [...this.sourceRows],
|
|
555
612
|
source: "keyboard"
|
|
556
613
|
};
|
|
557
|
-
if (this.emitCancelable("row-move",
|
|
558
|
-
const
|
|
559
|
-
|
|
614
|
+
if (this.emitCancelable("row-move", o)) {
|
|
615
|
+
const i = [...this.sourceRows], [n] = i.splice(t, 1);
|
|
616
|
+
i.splice(e, 0, n);
|
|
560
617
|
const c = this.grid;
|
|
561
|
-
c._rows =
|
|
618
|
+
c._rows = i, c._focusRow = e, c._focusCol = this.lastFocusCol, c.refreshVirtualWindow(!0), b(c);
|
|
562
619
|
}
|
|
563
620
|
}
|
|
564
621
|
/**
|
|
565
622
|
* Execute a row move and emit the event.
|
|
566
623
|
*/
|
|
567
|
-
executeMove(e,
|
|
568
|
-
const s = [...this.sourceRows], [
|
|
569
|
-
s.splice(
|
|
624
|
+
executeMove(e, t, r, o) {
|
|
625
|
+
const s = [...this.sourceRows], [i] = s.splice(t, 1);
|
|
626
|
+
s.splice(r, 0, i);
|
|
570
627
|
const n = {
|
|
571
628
|
row: e,
|
|
572
|
-
fromIndex:
|
|
573
|
-
toIndex:
|
|
629
|
+
fromIndex: t,
|
|
630
|
+
toIndex: r,
|
|
574
631
|
rows: s,
|
|
575
|
-
source:
|
|
632
|
+
source: o
|
|
576
633
|
};
|
|
577
634
|
if (!this.emitCancelable("row-move", n))
|
|
578
635
|
if (this.animationType === "flip" && this.gridElement) {
|
|
579
636
|
const a = this.captureRowPositions();
|
|
580
637
|
this.grid.rows = s, requestAnimationFrame(() => {
|
|
581
|
-
this.gridElement.offsetHeight, this.animateFLIP(a,
|
|
638
|
+
this.gridElement.offsetHeight, this.animateFLIP(a, t, r);
|
|
582
639
|
});
|
|
583
640
|
} else
|
|
584
641
|
this.grid.rows = s;
|
|
@@ -589,9 +646,9 @@ class L extends _ {
|
|
|
589
646
|
*/
|
|
590
647
|
captureRowPositions() {
|
|
591
648
|
const e = /* @__PURE__ */ new Map();
|
|
592
|
-
return this.gridElement?.querySelectorAll(".data-grid-row").forEach((
|
|
593
|
-
const
|
|
594
|
-
|
|
649
|
+
return this.gridElement?.querySelectorAll(".data-grid-row").forEach((t) => {
|
|
650
|
+
const r = this.getRowIndex(t);
|
|
651
|
+
r >= 0 && e.set(r, t.getBoundingClientRect().top);
|
|
595
652
|
}), e;
|
|
596
653
|
}
|
|
597
654
|
/**
|
|
@@ -601,15 +658,15 @@ class L extends _ {
|
|
|
601
658
|
* @param fromIndex - Original index of moved row
|
|
602
659
|
* @param toIndex - New index of moved row
|
|
603
660
|
*/
|
|
604
|
-
animateFLIP(e,
|
|
605
|
-
const
|
|
606
|
-
if (!
|
|
607
|
-
const s = Math.min(
|
|
608
|
-
if (
|
|
661
|
+
animateFLIP(e, t, r) {
|
|
662
|
+
const o = this.gridElement;
|
|
663
|
+
if (!o || e.size === 0) return;
|
|
664
|
+
const s = Math.min(t, r), i = Math.max(t, r), n = [];
|
|
665
|
+
if (o.querySelectorAll(".data-grid-row").forEach((a) => {
|
|
609
666
|
const u = a, d = this.getRowIndex(u);
|
|
610
|
-
if (d < 0 || d < s || d >
|
|
667
|
+
if (d < 0 || d < s || d > i) return;
|
|
611
668
|
let g;
|
|
612
|
-
d ===
|
|
669
|
+
d === r ? g = t : t < r ? g = d + 1 : g = d - 1;
|
|
613
670
|
const h = e.get(g);
|
|
614
671
|
if (h === void 0) return;
|
|
615
672
|
const w = u.getBoundingClientRect().top, f = h - w;
|
|
@@ -617,7 +674,7 @@ class L extends _ {
|
|
|
617
674
|
}), n.length === 0) return;
|
|
618
675
|
n.forEach(({ el: a, deltaY: u }) => {
|
|
619
676
|
a.style.transform = `translateY(${u}px)`;
|
|
620
|
-
}),
|
|
677
|
+
}), o.offsetHeight;
|
|
621
678
|
const c = this.animationDuration;
|
|
622
679
|
requestAnimationFrame(() => {
|
|
623
680
|
n.forEach(({ el: a }) => {
|
|
@@ -634,8 +691,8 @@ class L extends _ {
|
|
|
634
691
|
* This is consistent with how other plugins retrieve row indices.
|
|
635
692
|
*/
|
|
636
693
|
getRowIndex(e) {
|
|
637
|
-
const
|
|
638
|
-
return
|
|
694
|
+
const t = e.querySelector(".cell[data-row]");
|
|
695
|
+
return t ? parseInt(t.getAttribute("data-row") ?? "-1", 10) : -1;
|
|
639
696
|
}
|
|
640
697
|
/**
|
|
641
698
|
* Clear all drag-related classes from rows.
|