@toolbox-web/grid 2.3.0 → 2.4.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.
Files changed (102) hide show
  1. package/all.d.ts +1 -0
  2. package/all.js +2 -2
  3. package/all.js.map +1 -1
  4. package/index.js +1 -1
  5. package/index.js.map +1 -1
  6. package/lib/core/grid.d.ts +2 -1
  7. package/lib/core/internal/diagnostics.d.ts +5 -1
  8. package/lib/core/internal/dom-builder.d.ts +0 -25
  9. package/lib/core/internal/drag-drop-registry.d.ts +66 -0
  10. package/lib/core/internal/render-scheduler.d.ts +9 -8
  11. package/lib/core/plugin/base-plugin.d.ts +23 -0
  12. package/lib/core/plugin/plugin-manager.d.ts +9 -0
  13. package/lib/core/types.d.ts +67 -46
  14. package/lib/features/registry.js.map +1 -1
  15. package/lib/features/reorder-rows.d.ts +3 -3
  16. package/lib/features/reorder-rows.js +1 -1
  17. package/lib/features/reorder-rows.js.map +1 -1
  18. package/lib/features/row-drag-drop.d.ts +9 -0
  19. package/lib/features/row-drag-drop.js +2 -0
  20. package/lib/features/row-drag-drop.js.map +1 -0
  21. package/lib/features/server-side.js.map +1 -1
  22. package/lib/plugins/clipboard/index.js +1 -1
  23. package/lib/plugins/clipboard/index.js.map +1 -1
  24. package/lib/plugins/column-virtualization/index.js +1 -1
  25. package/lib/plugins/column-virtualization/index.js.map +1 -1
  26. package/lib/plugins/context-menu/index.js +1 -1
  27. package/lib/plugins/context-menu/index.js.map +1 -1
  28. package/lib/plugins/editing/index.js +1 -1
  29. package/lib/plugins/editing/index.js.map +1 -1
  30. package/lib/plugins/export/ExportPlugin.d.ts +89 -0
  31. package/lib/plugins/export/index.d.ts +3 -2
  32. package/lib/plugins/export/index.js +1 -1
  33. package/lib/plugins/export/index.js.map +1 -1
  34. package/lib/plugins/export/types.d.ts +30 -0
  35. package/lib/plugins/filtering/index.js +1 -1
  36. package/lib/plugins/filtering/index.js.map +1 -1
  37. package/lib/plugins/grouping-columns/index.js +1 -1
  38. package/lib/plugins/grouping-columns/index.js.map +1 -1
  39. package/lib/plugins/grouping-rows/index.js +2 -2
  40. package/lib/plugins/grouping-rows/index.js.map +1 -1
  41. package/lib/plugins/master-detail/index.js +1 -1
  42. package/lib/plugins/master-detail/index.js.map +1 -1
  43. package/lib/plugins/multi-sort/index.js +1 -1
  44. package/lib/plugins/multi-sort/index.js.map +1 -1
  45. package/lib/plugins/pinned-columns/index.js +1 -1
  46. package/lib/plugins/pinned-columns/index.js.map +1 -1
  47. package/lib/plugins/pinned-rows/index.js +1 -1
  48. package/lib/plugins/pinned-rows/index.js.map +1 -1
  49. package/lib/plugins/pivot/index.js +1 -1
  50. package/lib/plugins/pivot/index.js.map +1 -1
  51. package/lib/plugins/print/index.js +1 -1
  52. package/lib/plugins/print/index.js.map +1 -1
  53. package/lib/plugins/reorder-columns/index.js +1 -1
  54. package/lib/plugins/reorder-columns/index.js.map +1 -1
  55. package/lib/plugins/reorder-rows/RowReorderPlugin.d.ts +14 -156
  56. package/lib/plugins/reorder-rows/index.d.ts +10 -4
  57. package/lib/plugins/reorder-rows/index.js +1 -1
  58. package/lib/plugins/reorder-rows/index.js.map +1 -1
  59. package/lib/plugins/reorder-rows/types.d.ts +9 -86
  60. package/lib/plugins/responsive/index.js +1 -1
  61. package/lib/plugins/responsive/index.js.map +1 -1
  62. package/lib/plugins/row-drag-drop/RowDragDropPlugin.d.ts +106 -0
  63. package/lib/plugins/row-drag-drop/index.d.ts +9 -0
  64. package/lib/plugins/row-drag-drop/index.js +2 -0
  65. package/lib/plugins/row-drag-drop/index.js.map +1 -0
  66. package/lib/plugins/row-drag-drop/types.d.ts +255 -0
  67. package/lib/plugins/selection/index.js +1 -1
  68. package/lib/plugins/selection/index.js.map +1 -1
  69. package/lib/plugins/server-side/ServerSidePlugin.d.ts +13 -0
  70. package/lib/plugins/server-side/datasource-types.d.ts +54 -7
  71. package/lib/plugins/server-side/datasource.d.ts +10 -2
  72. package/lib/plugins/server-side/index.d.ts +1 -1
  73. package/lib/plugins/server-side/index.js +1 -1
  74. package/lib/plugins/server-side/index.js.map +1 -1
  75. package/lib/plugins/server-side/types.d.ts +1 -1
  76. package/lib/plugins/shared/drag-drop-protocol.d.ts +98 -0
  77. package/lib/plugins/tooltip/index.js +1 -1
  78. package/lib/plugins/tooltip/index.js.map +1 -1
  79. package/lib/plugins/tree/TreePlugin.d.ts +19 -6
  80. package/lib/plugins/tree/index.js +1 -1
  81. package/lib/plugins/tree/index.js.map +1 -1
  82. package/lib/plugins/undo-redo/index.js +1 -1
  83. package/lib/plugins/undo-redo/index.js.map +1 -1
  84. package/lib/plugins/visibility/index.js +1 -1
  85. package/lib/plugins/visibility/index.js.map +1 -1
  86. package/package.json +1 -1
  87. package/umd/grid.all.umd.js +1 -1
  88. package/umd/grid.all.umd.js.map +1 -1
  89. package/umd/grid.umd.js +1 -1
  90. package/umd/grid.umd.js.map +1 -1
  91. package/umd/plugins/export.umd.js +1 -1
  92. package/umd/plugins/export.umd.js.map +1 -1
  93. package/umd/plugins/reorder-rows.umd.js +1 -1
  94. package/umd/plugins/reorder-rows.umd.js.map +1 -1
  95. package/umd/plugins/row-drag-drop.umd.js +2 -0
  96. package/umd/plugins/row-drag-drop.umd.js.map +1 -0
  97. package/umd/plugins/selection.umd.js +1 -1
  98. package/umd/plugins/selection.umd.js.map +1 -1
  99. package/umd/plugins/server-side.umd.js +1 -1
  100. package/umd/plugins/server-side.umd.js.map +1 -1
  101. package/umd/plugins/tree.umd.js +1 -1
  102. package/umd/plugins/tree.umd.js.map +1 -1
@@ -1,164 +1,22 @@
1
- import { BaseGridPlugin } from '../../core/plugin/base-plugin';
2
- import { ColumnConfig } from '../../core/types';
3
- import { RowReorderConfig } from './types';
4
- /** Field name for the drag handle column */
5
- export declare const ROW_DRAG_HANDLE_FIELD = "__tbw_row_drag";
6
1
  /**
7
- * Row Reorder Plugin for tbw-grid
2
+ * Row Reordering Plugin (deprecated alias).
8
3
  *
9
- * Enables row reordering via keyboard shortcuts (Ctrl+Up/Down) and drag-drop.
10
- * Supports validation callbacks and debounced keyboard moves.
4
+ * `RowReorderPlugin` is now an alias for `RowDragDropPlugin`, which is
5
+ * a strict superset: same intra-grid behaviour, plus opt-in cross-grid drag
6
+ * via `dropZone`. Migration is mechanical:
11
7
  *
12
- * ## Installation
8
+ * ```diff
9
+ * - import { RowReorderPlugin } from '@toolbox-web/grid/plugins/reorder-rows';
10
+ * + import { RowDragDropPlugin } from '@toolbox-web/grid/plugins/row-drag-drop';
13
11
  *
14
- * ```ts
15
- * import { RowReorderPlugin } from '@toolbox-web/grid/plugins/reorder-rows';
12
+ * - new RowReorderPlugin(cfg);
13
+ * + new RowDragDropPlugin(cfg);
16
14
  * ```
17
15
  *
18
- * ## Keyboard Shortcuts
16
+ * The legacy `canMove` callback continues to work — it is mapped internally.
19
17
  *
20
- * | Key | Action |
21
- * |-----|--------|
22
- * | `Ctrl + ↑` | Move focused row up |
23
- * | `Ctrl + ↓` | Move focused row down |
24
- *
25
- * ## Events
26
- *
27
- * | Event | Detail | Cancelable | Description |
28
- * |-------|--------|------------|-------------|
29
- * | `row-move` | {@link RowMoveDetail} | Yes | Fired when a row move is attempted |
30
- *
31
- * @example Basic Row Reordering
32
- * ```ts
33
- * import { queryGrid } from '@toolbox-web/grid';
34
- * import { RowReorderPlugin } from '@toolbox-web/grid/plugins/reorder-rows';
35
- *
36
- * const grid = queryGrid('tbw-grid');
37
- * grid.gridConfig = {
38
- * columns: [
39
- * { field: 'id', header: 'ID' },
40
- * { field: 'name', header: 'Name' },
41
- * ],
42
- * plugins: [new RowReorderPlugin()],
43
- * };
44
- *
45
- * grid.on('row-move', ({ fromIndex, toIndex }) => {
46
- * console.log('Row moved from', fromIndex, 'to', toIndex);
47
- * });
48
- * ```
49
- *
50
- * @example With Validation
51
- * ```ts
52
- * new RowReorderPlugin({
53
- * canMove: (row, fromIndex, toIndex, direction) => {
54
- * // Prevent moving locked rows
55
- * return !row.locked;
56
- * },
57
- * })
58
- * ```
59
- *
60
- * @see {@link RowReorderConfig} for all configuration options
61
- * @see {@link RowMoveDetail} for the event detail structure
18
+ * @deprecated Use `RowDragDropPlugin` from `@toolbox-web/grid/plugins/row-drag-drop`.
19
+ * This module will be removed in V3.
62
20
  */
63
- export declare class RowReorderPlugin extends BaseGridPlugin<RowReorderConfig> {
64
- #private;
65
- /** @internal */
66
- readonly name = "reorderRows";
67
- /** @internal */
68
- readonly aliases: readonly ["rowReorder"];
69
- /** @internal */
70
- readonly styles: string;
71
- /** @internal */
72
- protected get defaultConfig(): Partial<RowReorderConfig>;
73
- /**
74
- * Resolve animation type from plugin config.
75
- * Uses base class isAnimationEnabled to respect grid-level settings.
76
- */
77
- private get animationType();
78
- private isDragging;
79
- private draggedRowIndex;
80
- private dropRowIndex;
81
- private pendingMove;
82
- private debounceTimer;
83
- /** Column index to use when flushing pending move */
84
- private lastFocusCol;
85
- /** @internal */
86
- attach(grid: import('../../core/plugin/base-plugin').GridElement): void;
87
- /** @internal */
88
- detach(): void;
89
- /** @internal */
90
- processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
91
- /** @internal */
92
- afterRender(): void;
93
- /**
94
- * Handle Ctrl+Arrow keyboard shortcuts for row reordering.
95
- * @internal
96
- */
97
- onKeyDown(event: KeyboardEvent): boolean | void;
98
- /**
99
- * Flush pending keyboard moves when user clicks a cell.
100
- * This commits the move immediately so focus works correctly.
101
- * @internal
102
- */
103
- onCellClick(): void;
104
- /**
105
- * Move a row to a new position programmatically.
106
- * @param fromIndex - Current index of the row
107
- * @param toIndex - Target index
108
- */
109
- moveRow(fromIndex: number, toIndex: number): void;
110
- /**
111
- * Check if a row can be moved to a position.
112
- * Consults both the user-provided `canMove` callback and the plugin query system
113
- * (`canMoveRow` query) — GroupingRows blocks group header moves, Tree blocks
114
- * parent node moves.
115
- * @param fromIndex - Current index of the row
116
- * @param toIndex - Target index
117
- */
118
- canMoveRow(fromIndex: number, toIndex: number): boolean;
119
- /**
120
- * Set up delegated drag-and-drop listeners on the grid element.
121
- * Uses event delegation so recycled/virtualized rows work without rebinding.
122
- */
123
- private setupDelegatedDragListeners;
124
- /**
125
- * Handle debounced keyboard moves.
126
- * Rows move immediately for visual feedback, but the event emission is debounced.
127
- */
128
- private handleKeyboardMove;
129
- /**
130
- * Flush the pending move by emitting the event.
131
- * Called when debounce timer fires or user clicks elsewhere.
132
- */
133
- private flushPendingMove;
134
- /**
135
- * Execute a row move and emit the event.
136
- */
137
- private executeMove;
138
- /**
139
- * Capture row positions before reorder.
140
- * Maps visual row index to its top position.
141
- */
142
- private captureRowPositions;
143
- /**
144
- * Apply FLIP animation for row reorder.
145
- * Uses CSS transitions - JS sets initial transform and toggles class.
146
- * @param oldPositions - Row positions captured before DOM change
147
- * @param fromIndex - Original index of moved row
148
- * @param toIndex - New index of moved row
149
- */
150
- private animateFLIP;
151
- /**
152
- * Get the row index from a row element by checking data-row attribute on cells.
153
- * This is consistent with how other plugins retrieve row indices.
154
- */
155
- private getRowIndex;
156
- /**
157
- * Clear all drag-related classes from rows.
158
- */
159
- private clearDragClasses;
160
- /**
161
- * Clear the debounce timer.
162
- */
163
- private clearDebounceTimer;
164
- }
21
+ export { ROW_DRAG_HANDLE_FIELD, RowDragDropPlugin as RowReorderPlugin } from '../row-drag-drop/RowDragDropPlugin';
22
+ export type { RowMoveDetail } from '../row-drag-drop/types';
@@ -1,8 +1,14 @@
1
1
  /**
2
- * Reorder Rows Plugin Entry Point
3
- * Re-exports plugin class and types for tree-shakeable imports.
2
+ * Reorder Rows Plugin Entry Point (deprecated alias)
3
+ *
4
+ * Re-exports the deprecated `RowReorderPlugin` alias and its config type.
5
+ * `ROW_DRAG_HANDLE_FIELD` and `RowMoveDetail` are intentionally NOT
6
+ * re-exported here — they are exported from
7
+ * `@toolbox-web/grid/plugins/row-drag-drop` to avoid the `all` barrel
8
+ * double-exporting the same symbol.
4
9
  *
5
10
  * @module Plugins/Reorder Rows
11
+ * @deprecated Use `@toolbox-web/grid/plugins/row-drag-drop` instead.
6
12
  */
7
- export { ROW_DRAG_HANDLE_FIELD, RowReorderPlugin } from './RowReorderPlugin';
8
- export type { RowMoveDetail, RowReorderConfig } from './types';
13
+ export { RowReorderPlugin } from './RowReorderPlugin';
14
+ export type { RowReorderConfig } from './types';
@@ -1,2 +1,2 @@
1
- const e="editing",t="dragging";function r(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function o(e,t,o,i){return`${r(o,i)} ${e}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(e)}`}const i="__otorp__|__retteGenifed__|__retteSenifed__|rotcurtsnoc|wodniw|sihTlabolg|labolg|ssecorp|noitcnuF|tropmi|lave|tcelfeR|yxorP|rorrE|stnemugra|tnemucod|noitacol|eikooc|egarotSlacol|egarotSnoisses|BDdexedni|hctef|tseuqeRpttHLMX|tekcoSbeW|rekroW|rekroWderahS|rekroWecivreS|renepo|tnerap|pot|semarf|fles".split("|").map(e=>e.split("").reverse().join(""));new RegExp(`__(proto|defineGetter|defineSetter)|${i.slice(3).join("|")}|this\\b`);const n=new Set("script|iframe|object|embed|form|input|button|textarea|select|link|meta|base|style|template|slot|portal|frame|frameset|applet|noscript|noembed|plaintext|xmp|listing".split("|")),s=/^on\w+$/i,a=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),l=/^\s*(javascript|vbscript|data|blob):/i;function c(e){if(!e||"string"!=typeof e)return"";if(-1===e.indexOf("<"))return e;const t=document.createElement("template");return t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const o of r){const e=o.tagName.toLowerCase();if(n.has(e)){t.push(o);continue}if("svg"===e||"http://www.w3.org/2000/svg"===o.namespaceURI){if(Array.from(o.attributes).some(e=>s.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(o);continue}}const r=[];for(const t of o.attributes){const e=t.name.toLowerCase();s.test(e)?r.push(t.name):(a.has(e)&&l.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name)}r.forEach(e=>o.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}document.createElement("template").innerHTML='<div class="cell" role="gridcell" part="cell"></div>';function d(t,r){if(t._virtualization?.enabled){const{rowHeight:e,container:r,viewportEl:o}=t._virtualization,i=r,n=o?.clientHeight??i?.clientHeight??0;if(i&&n>0){const r=t._focusRow*e;r<i.scrollTop?i.scrollTop=r:r+e>i.scrollTop+n&&(i.scrollTop=r-n+e)}}const o=void 0!==t._activeEditRows&&-1!==t._activeEditRows||!!t._isGridEditMode;var i;o||t.refreshVirtualWindow(!1),(i=t._bodyEl)&&i.querySelectorAll(".cell-focus").forEach(e=>e.classList.remove("cell-focus")),Array.from(t._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach(e=>{e.setAttribute("aria-selected","false")});const n=t._focusRow,s=t._virtualization.start??0,a=t._virtualization.end??t._rows.length;if(n>=s&&n<a){const i=t._bodyEl.querySelectorAll(".data-grid-row")[n-s];let a=i?.children[t._focusCol];if(a&&a.classList?.contains("cell")||(a=i?.querySelector(`.cell[data-col="${t._focusCol}"]`)??i?.querySelector(".cell[data-col]")),a){a.classList.add("cell-focus"),a.setAttribute("aria-selected","true");const n=t.querySelector(".tbw-scroll-area");if(n&&a&&(!o||r?.forceHorizontalScroll)){const e=t._getHorizontalScrollOffsets?.(i??void 0,a)??{left:0,right:0};if(!e.skipScroll){const t=a.getBoundingClientRect(),r=n.getBoundingClientRect(),o=t.left-r.left+n.scrollLeft,i=o+t.width,s=n.scrollLeft+e.left,l=n.scrollLeft+n.clientWidth-e.right;o<s?n.scrollLeft=o-e.left:i>l&&(n.scrollLeft=i-n.clientWidth+e.right)}}if(o&&a.classList.contains(e)){const e=a.querySelector('input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])');if(e&&document.activeElement!==e)try{e.focus({preventScroll:!0})}catch{}}else if(o&&!a.contains(document.activeElement)){a.hasAttribute("tabindex")||a.setAttribute("tabindex","-1");try{a.focus({preventScroll:!0})}catch{}}else o||document.activeElement!==t&&t.focus({preventScroll:!0})}}}document.createElement("template").innerHTML='<div class="data-grid-row" role="row" part="row"></div>';const g='<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>',u={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:g,filterActive:g,print:"🖨️"};class h{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}attach(e){this.#e?.abort(),this.#e=new AbortController,this.grid=e,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#e?.abort(),this.#e=void 0}getPlugin(e){return this.grid?.getPlugin(e)}emit(e,t){this.grid?.dispatchEvent?.(new CustomEvent(e,{detail:t,bubbles:!0}))}emitCancelable(e,t){const r=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(r),r.defaultPrevented}on(e,t){this.grid?._pluginManager?.subscribe(this,e,t)}off(e){this.grid?._pluginManager?.unsubscribe(this,e)}emitPluginEvent(e,t){this.grid?._pluginManager?.emitPluginEvent(e,t)}broadcast(e,t){this.emitPluginEvent(e,t),this.emit(e,t)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}requestVirtualRefresh(){this.grid?.requestVirtualRefresh?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid?._hostElement}get disconnectSignal(){return this.#e?.signal??this.grid?.disconnectSignal}get gridIcons(){const e=this.grid?.gridConfig?.icons??{};return{...u,...e}}get isAnimationEnabled(){const e=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===e||"off"===e)return!1;if(!0===e||"on"===e)return!0;const t=this.gridElement;if(t){return"0"!==getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const e=this.gridElement;if(e){const t=getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(),r=parseInt(t,10);if(!isNaN(r))return r}return 200}setIcon(e,t,r){e.dataset.icon=t.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===t?e.dataset.expanded="":"expand"===t&&delete e.dataset.expanded;const o=this.#t(t,r);void 0!==o?"string"==typeof o?e.innerHTML=c(o):o instanceof HTMLElement&&(e.innerHTML="",e.appendChild(o.cloneNode(!0))):e.innerHTML=""}#t(e,t){return void 0!==t?t:this.grid?.gridConfig?.icons?.[e]}updateSortIndicator(e,t){e.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove();const r=document.createElement("span");r.setAttribute("part","sort-indicator"),r.className="sort-indicator",t?(e.setAttribute("aria-sort","asc"===t?"ascending":"descending"),e.setAttribute("data-sort",t),this.setIcon(r,"asc"===t?"sortAsc":"sortDesc")):(e.setAttribute("aria-sort","none"),e.removeAttribute("data-sort"),this.setIcon(r,"sortNone"));const o=e.querySelector(".tbw-filter-btn")??e.querySelector(".resize-handle");return o?e.insertBefore(r,o):e.appendChild(r),r}warn(e,t){void 0!==t?console.warn(o(e,t,this.gridElement.id,this.name)):console.warn(`${r(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(e,t){throw new Error(o(e,t,this.gridElement.id,this.name))}}const f="__tbw_row_drag";class w extends h{name="reorderRows";aliases=["rowReorder"];styles='@layer tbw-plugins{[data-field=__tbw_row_drag]{display:flex;align-items:center;justify-content:center}.dg-row-drag-handle{display:flex;align-items:center;justify-content:center;min-width:1em;min-height:1em;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}}';get defaultConfig(){return{enableKeyboard:!0,showDragHandle:!0,dragHandlePosition:"left",dragHandleWidth:40,debounceMs:150,animation:"flip"}}get animationType(){return!!this.isAnimationEnabled&&(void 0!==this.config.animation?this.config.animation:"flip")}isDragging=!1;draggedRowIndex=null;dropRowIndex=null;pendingMove=null;debounceTimer=null;lastFocusCol=0;get#r(){return this.grid}attach(e){super.attach(e),this.setupDelegatedDragListeners()}detach(){this.clearDebounceTimer(),this.isDragging=!1,this.draggedRowIndex=null,this.dropRowIndex=null,this.pendingMove=null}processColumns(e){if(!this.config.showDragHandle)return[...e];const t={field:f,header:"",width:this.config.dragHandleWidth??40,resizable:!1,sortable:!1,filterable:!1,lockPosition:!0,utility:!0,viewRenderer:()=>{const e=document.createElement("div");return e.className="dg-row-drag-handle",e.setAttribute("aria-label","Drag to reorder"),e.setAttribute("role","button"),e.setAttribute("tabindex","-1"),e.draggable=!0,this.setIcon(e,"dragHandle"),e}};return"right"===this.config.dragHandlePosition?[...e,t]:[t,...e]}afterRender(){}onKeyDown(e){if(!this.config.enableKeyboard)return;if(!e.ctrlKey||"ArrowUp"!==e.key&&"ArrowDown"!==e.key)return;const t=this.#r,r=t._focusRow,o=t._rows??this.sourceRows;if(r<0||r>=o.length)return;const i="ArrowUp"===e.key?"up":"down",n="up"===i?r-1:r+1;if(n<0||n>=o.length)return;const s=o[r];return this.canMoveRow(r,n)?(this.handleKeyboardMove(s,r,n,i,t._focusCol),e.preventDefault(),e.stopPropagation(),!0):void 0}onCellClick(){this.flushPendingMove()}moveRow(e,t){const r=[...this.sourceRows];if(e<0||e>=r.length)return;if(t<0||t>=r.length)return;if(e===t)return;const o=r[e];this.canMoveRow(e,t)&&this.executeMove(o,e,t,"keyboard")}canMoveRow(e,t){const r=this.sourceRows;if(e<0||e>=r.length)return!1;if(t<0||t>=r.length)return!1;if(e===t)return!1;const o=r[e],i=this.grid?.query?.("canMoveRow",o);if(Array.isArray(i)&&i.includes(!1))return!1;if(!this.config.canMove)return!0;const n=t<e?"up":"down";return this.config.canMove(r[e],e,t,n)}setupDelegatedDragListeners(){const e=this.gridElement;if(!e)return;const r=this.disconnectSignal;e.addEventListener("dragstart",e=>{const r=e,o=r.target.closest(".dg-row-drag-handle");if(!o)return;const i=o.closest(".data-grid-row");if(!i)return;const n=this.getRowIndex(i);n<0||(this.isDragging=!0,this.draggedRowIndex=n,r.dataTransfer&&(r.dataTransfer.effectAllowed="move",r.dataTransfer.setData("text/plain",String(n))),i.classList.add(t))},{signal:r}),e.addEventListener("dragend",()=>{this.isDragging=!1,this.draggedRowIndex=null,this.dropRowIndex=null,this.clearDragClasses()},{signal:r}),e.addEventListener("dragover",e=>{const t=e;if(!this.isDragging||null===this.draggedRowIndex)return;const r=t.target.closest(".data-grid-row");if(!r)return;t.preventDefault();const o=this.getRowIndex(r);if(o<0||o===this.draggedRowIndex)return;const i=r.getBoundingClientRect(),n=i.top+i.height/2,s=t.clientY<n;this.dropRowIndex=s?o:o+1,r.classList.add("drop-target"),r.classList.toggle("drop-before",s),r.classList.toggle("drop-after",!s)},{signal:r}),e.addEventListener("dragleave",e=>{const t=e.target.closest(".data-grid-row");t&&t.classList.remove("drop-target","drop-before","drop-after")},{signal:r}),e.addEventListener("drop",e=>{e.preventDefault();const t=this.draggedRowIndex;let r=this.dropRowIndex;if(this.isDragging&&null!==t&&null!==r&&(r>t&&r--,t!==r)){const e=this.sourceRows[t];this.canMoveRow(t,r)&&this.executeMove(e,t,r,"drag")}},{signal:r})}handleKeyboardMove(e,t,r,o,i){this.pendingMove?this.pendingMove.currentIndex=r:this.pendingMove={originalIndex:t,currentIndex:r,row:e},this.lastFocusCol=i;const n=this.#r,s=[...n._rows??this.sourceRows],[a]=s.splice(t,1);s.splice(r,0,a),n._rows=s,n._focusRow=r,n._focusCol=i,n.refreshVirtualWindow(!0),d(n),this.clearDebounceTimer(),this.debounceTimer=setTimeout(()=>{this.flushPendingMove()},this.config.debounceMs??300)}flushPendingMove(){if(this.clearDebounceTimer(),!this.pendingMove)return;const{originalIndex:e,currentIndex:t,row:r}=this.pendingMove;if(this.pendingMove=null,e===t)return;const o={row:r,fromIndex:e,toIndex:t,rows:[...this.sourceRows],source:"keyboard"};if(this.emitCancelable("row-move",o)){const r=[...this.sourceRows],[o]=r.splice(t,1);r.splice(e,0,o);const i=this.#r;i._rows=r,i._focusRow=e,i._focusCol=this.lastFocusCol,i.refreshVirtualWindow(!0),d(i)}}executeMove(e,t,r,o){const i=[...this.sourceRows],[n]=i.splice(t,1);i.splice(r,0,n);const s={row:e,fromIndex:t,toIndex:r,rows:i,source:o};if(!this.emitCancelable("row-move",s))if("flip"===this.animationType&&this.gridElement){const e=this.captureRowPositions();this.grid.rows=i,requestAnimationFrame(()=>{this.gridElement.offsetHeight,this.animateFLIP(e,t,r)})}else this.grid.rows=i}captureRowPositions(){const e=/* @__PURE__ */new Map;return this.gridElement?.querySelectorAll(".data-grid-row").forEach(t=>{const r=this.getRowIndex(t);r>=0&&e.set(r,t.getBoundingClientRect().top)}),e}animateFLIP(e,t,r){const o=this.gridElement;if(!o||0===e.size)return;const i=Math.min(t,r),n=Math.max(t,r),s=[];if(o.querySelectorAll(".data-grid-row").forEach(o=>{const a=o,l=this.getRowIndex(a);if(l<0||l<i||l>n)return;let c;c=l===r?t:t<r?l+1:l-1;const d=e.get(c);if(void 0===d)return;const g=d-a.getBoundingClientRect().top;Math.abs(g)>1&&s.push({el:a,deltaY:g})}),0===s.length)return;s.forEach(({el:e,deltaY:t})=>{e.style.transform=`translateY(${t}px)`}),o.offsetHeight;const a=this.animationDuration;requestAnimationFrame(()=>{s.forEach(({el:e})=>{e.classList.add("flip-animating"),e.style.transform=""}),setTimeout(()=>{s.forEach(({el:e})=>{e.style.transform="",e.classList.remove("flip-animating")})},a+50)})}getRowIndex(e){const t=e.querySelector(".cell[data-row]");return t?parseInt(t.getAttribute("data-row")??"-1",10):-1}clearDragClasses(){this.gridElement?.querySelectorAll(".data-grid-row").forEach(e=>{e.classList.remove(t,"drop-target","drop-before","drop-after")})}clearDebounceTimer(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null)}}export{f as ROW_DRAG_HANDLE_FIELD,w as RowReorderPlugin};
1
+ const e="editing",t="dragging",r=/* @__PURE__ */new Map;function o(e){const t=r.get(e);if(!t)return;if(t.hasPrimitives)return;const o=[];for(const r of t.refs){const e=r.deref();if(void 0===e)return;o.push(e)}return o}function i(e){r.delete(e)}function n(){if("undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID)return crypto.randomUUID();if("undefined"!=typeof crypto&&"function"==typeof crypto.getRandomValues){const e=new Uint32Array(2);return crypto.getRandomValues(e),`drag-${Date.now().toString(36)}-${e[0].toString(36)}${e[1].toString(36)}`}return`drag-${Date.now().toString(36)}-${(++s).toString(36)}`}let s=0;function a(e,t){return`[tbw-grid${e?`#${e}`:""}${t?`:${t}`:""}]`}function d(e,t,r,o){return`${a(r,o)} ${e}: ${t}\n\n → More info: ${function(e){return`https://toolboxjs.com/grid/errors#${e.toLowerCase()}`}(e)}`}const c="__otorp__|__retteGenifed__|__retteSenifed__|rotcurtsnoc|wodniw|sihTlabolg|labolg|ssecorp|noitcnuF|tropmi|lave|tcelfeR|yxorP|rorrE|stnemugra|tnemucod|noitacol|eikooc|egarotSlacol|egarotSnoisses|BDdexedni|hctef|tseuqeRpttHLMX|tekcoSbeW|rekroW|rekroWderahS|rekroWecivreS|renepo|tnerap|pot|semarf|fles".split("|").map(e=>e.split("").reverse().join(""));new RegExp(`__(proto|defineGetter|defineSetter)|${c.slice(3).join("|")}|this\\b`);const l=new Set("script|iframe|object|embed|form|input|button|textarea|select|link|meta|base|style|template|slot|portal|frame|frameset|applet|noscript|noembed|plaintext|xmp|listing".split("|")),g=/^on\w+$/i,u=new Set("href|src|action|formaction|data|srcdoc|xlink:href|poster|srcset".split("|")),f=/^\s*(javascript|vbscript|data|blob):/i;function h(e){if(!e||"string"!=typeof e)return"";if(-1===e.indexOf("<"))return e;const t=document.createElement("template");return t.innerHTML=e,function(e){const t=[],r=e.querySelectorAll("*");for(const o of r){const e=o.tagName.toLowerCase();if(l.has(e)){t.push(o);continue}if("svg"===e||"http://www.w3.org/2000/svg"===o.namespaceURI){if(Array.from(o.attributes).some(e=>g.test(e.name)||"href"===e.name||"xlink:href"===e.name)){t.push(o);continue}}const r=[];for(const t of o.attributes){const e=t.name.toLowerCase();g.test(e)?r.push(t.name):(u.has(e)&&f.test(t.value)||"style"===e&&/expression\s*\(|javascript:|behavior\s*:/i.test(t.value))&&r.push(t.name)}r.forEach(e=>o.removeAttribute(e))}t.forEach(e=>e.remove())}(t.content),t.innerHTML}document.createElement("template").innerHTML='<div class="cell" role="gridcell" part="cell"></div>';function p(t,r){if(t._virtualization?.enabled){const{rowHeight:e,container:r,viewportEl:o}=t._virtualization,i=r,n=o?.clientHeight??i?.clientHeight??0;if(i&&n>0){const r=t._focusRow*e;r<i.scrollTop?i.scrollTop=r:r+e>i.scrollTop+n&&(i.scrollTop=r-n+e)}}const o=void 0!==t._activeEditRows&&-1!==t._activeEditRows||!!t._isGridEditMode;var i;o||t.refreshVirtualWindow(!1),(i=t._bodyEl)&&i.querySelectorAll(".cell-focus").forEach(e=>e.classList.remove("cell-focus")),Array.from(t._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach(e=>{e.setAttribute("aria-selected","false")});const n=t._focusRow,s=t._virtualization.start??0,a=t._virtualization.end??t._rows.length;if(n>=s&&n<a){const i=t._bodyEl.querySelectorAll(".data-grid-row")[n-s];let a=i?.children[t._focusCol];if(a&&a.classList?.contains("cell")||(a=i?.querySelector(`.cell[data-col="${t._focusCol}"]`)??i?.querySelector(".cell[data-col]")),a){a.classList.add("cell-focus"),a.setAttribute("aria-selected","true");const n=t.querySelector(".tbw-scroll-area");if(n&&a&&(!o||r?.forceHorizontalScroll)){const e=t._getHorizontalScrollOffsets?.(i??void 0,a)??{left:0,right:0};if(!e.skipScroll){const t=a.getBoundingClientRect(),r=n.getBoundingClientRect(),o=t.left-r.left+n.scrollLeft,i=o+t.width,s=n.scrollLeft+e.left,d=n.scrollLeft+n.clientWidth-e.right;o<s?n.scrollLeft=o-e.left:i>d&&(n.scrollLeft=i-n.clientWidth+e.right)}}if(o&&a.classList.contains(e)){const e=a.querySelector('input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])');if(e&&document.activeElement!==e)try{e.focus({preventScroll:!0})}catch{}}else if(o&&!a.contains(document.activeElement)){a.hasAttribute("tabindex")||a.setAttribute("tabindex","-1");try{a.focus({preventScroll:!0})}catch{}}else o||document.activeElement!==t&&t.focus({preventScroll:!0})}}}document.createElement("template").innerHTML='<div class="data-grid-row" role="row" part="row"></div>';const w={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:"",filterActive:"",print:"🖨️"};class m{static dependencies;static manifest;aliases;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}mergeConfigsFrom(e){if(0===e.length)return;const t={...this.userConfig},r={};for(const o of Object.keys(t))r[o]=this;for(const o of e){const e=o.userConfig;for(const[i,n]of Object.entries(e)){if(void 0===n)continue;if(!(i in t)){t[i]=n,r[i]=o;continue}if(t[i]===n)continue;const e=r[i]?.constructor.name??this.constructor.name,s=o.constructor.name,a=d("TBW025",`Cannot merge plugin configs for "${this.name}": conflicting value for "${i}" supplied by both ${e} and ${s}. Pass the option on a single instance, or remove the duplicate.`,void 0,this.name);throw new Error(a)}}Object.assign(this.userConfig,t)}attach(e){this.#e?.abort(),this.#e=new AbortController,this.grid=e,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#e?.abort(),this.#e=void 0}getPlugin(e){return this.grid?.getPlugin(e)}emit(e,t){this.grid?.dispatchEvent?.(new CustomEvent(e,{detail:t,bubbles:!0}))}emitCancelable(e,t){const r=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(r),r.defaultPrevented}on(e,t){this.grid?._pluginManager?.subscribe(this,e,t)}off(e){this.grid?._pluginManager?.unsubscribe(this,e)}emitPluginEvent(e,t){this.grid?._pluginManager?.emitPluginEvent(e,t)}broadcast(e,t){this.emitPluginEvent(e,t),this.emit(e,t)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}requestVirtualRefresh(){this.grid?.requestVirtualRefresh?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid?._hostElement}get disconnectSignal(){return this.#e?.signal??this.grid?.disconnectSignal}get gridIcons(){const e=this.grid?.gridConfig?.icons??{};return{...w,...e}}get isAnimationEnabled(){const e=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===e||"off"===e)return!1;if(!0===e||"on"===e)return!0;const t=this.gridElement;if(t){return"0"!==getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const e=this.gridElement;if(e){const t=getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(),r=parseInt(t,10);if(!isNaN(r))return r}return 200}setIcon(e,t,r){e.dataset.icon=t.replace(/([A-Z])/g,"-$1").toLowerCase(),"collapse"===t?e.dataset.expanded="":"expand"===t&&delete e.dataset.expanded;const o=this.#t(t,r);void 0!==o?"string"==typeof o?e.innerHTML=h(o):o instanceof HTMLElement&&(e.innerHTML="",e.appendChild(o.cloneNode(!0))):e.innerHTML=""}#t(e,t){return void 0!==t?t:this.grid?.gridConfig?.icons?.[e]}updateSortIndicator(e,t){e.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove();const r=document.createElement("span");r.setAttribute("part","sort-indicator"),r.className="sort-indicator",t?(e.setAttribute("aria-sort","asc"===t?"ascending":"descending"),e.setAttribute("data-sort",t),this.setIcon(r,"asc"===t?"sortAsc":"sortDesc")):(e.setAttribute("aria-sort","none"),e.removeAttribute("data-sort"),this.setIcon(r,"sortNone"));const o=e.querySelector(".tbw-filter-btn")??e.querySelector(".resize-handle");return o?e.insertBefore(r,o):e.appendChild(r),r}warn(e,t){void 0!==t?console.warn(d(e,t,this.gridElement.id,this.name)):console.warn(`${a(this.gridElement.id,this.name)} ${e}`)}throwDiagnostic(e,t){throw new Error(d(e,t,this.gridElement.id,this.name))}}let b=null;function v(){return b}function y(){b=null}const I="application/x-tbw-grid-rows+json";function x(e){const t=e.match(/^application\/x-tbw-grid-rows\+json;zone=(.*)$/);if(!t)return null;try{return decodeURIComponent(t[1])}catch{return t[1]}}function R(e){return JSON.stringify(e)}function E(e,t,r,o){if(!e)return{overIndex:null,insertIndex:o,isBefore:!1};const i=r(e);if(i<0)return{overIndex:null,insertIndex:o,isBefore:!1};const n=e.getBoundingClientRect(),s=t<n.top+n.height/2;return{overIndex:i,insertIndex:s?i:i+1,isBefore:s}}class D extends m{name="rowDragDrop";aliases=["reorderRows","rowReorder"];styles='@layer tbw-plugins{[data-field=__tbw_row_drag]{display:flex;align-items:center;justify-content:center}.dg-row-drag-handle{display:flex;align-items:center;justify-content:center;min-width:1em;min-height:1em;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}.tbw-row-drag-count{position:fixed;top:-1000px;left:-1000px;pointer-events:none;background:var(--tbw-row-reorder-indicator, var(--tbw-color-accent));color:var(--tbw-color-accent-fg);font:600 12px/1.4 system-ui,sans-serif;border-radius:999px;padding:2px 8px;box-shadow:0 2px 6px var(--tbw-color-shadow);z-index:9999}.data-grid-row.drop-target{position:relative}.data-grid-row.drop-target.drop-before:before,.data-grid-row.drop-target.drop-after:after{content:"";position:absolute;left:0;right:0;height:var(--tbw-drop-indicator-width, 2px);background-color:var(--tbw-drop-indicator-color, var(--tbw-row-reorder-indicator, var(--tbw-color-accent)));z-index:10;pointer-events:none}.data-grid-row.drop-target.drop-before:before{top:0}.data-grid-row.drop-target.drop-after:after{bottom:0}.tbw-grid--drop-target-active{outline:2px dashed var(--tbw-drop-indicator-color, var(--tbw-color-accent));outline-offset:-2px}.tbw-grid--drop-target-rejected{outline:2px dashed var(--tbw-color-danger);outline-offset:-2px}.tbw-grid--auto-scrolling{cursor:ns-resize}.data-grid-row.flip-animating{transition:transform var(--tbw-animation-duration, .2s) ease-out;will-change:transform;z-index:1}}';static manifest={events:[{type:"row-move",description:"Intra-grid row reorder.",cancelable:!0},{type:"row-drag-start",description:"Cross-grid drag started on this grid.",cancelable:!0},{type:"row-drag-end",description:"Drag finished on this grid (regardless of outcome)."},{type:"row-drop",description:"Cross-grid drop landing on this grid.",cancelable:!0},{type:"row-transfer",description:"Cross-grid transfer completed (fires on both grids)."}]};get defaultConfig(){return{enableKeyboard:!0,showDragHandle:!0,dragHandlePosition:"left",dragHandleWidth:40,debounceMs:150,animation:"flip",operation:"move",autoScroll:!0}}get animationType(){return!!this.isAnimationEnabled&&(void 0!==this.config.animation?this.config.animation:"flip")}isDragging=!1;draggedRowIndex=null;draggedRows=[];draggedIndices=[];dragSessionId=null;dragAccepted=!1;dropRowIndex=null;pendingMove=null;debounceTimer=null;lastFocusCol=0;autoScroller=null;gridId="";get internalGrid(){return this.grid}attach(e){super.attach(e);const t=this.gridElement;t&&(this.gridId=t.id||`tbw-grid-${n().slice(0,8)}`,t.id||(t.id=this.gridId),this.setupDelegatedDragListeners())}detach(){this.clearDebounceTimer(),this.autoScroller?.stop(),this.autoScroller=null,this.dragSessionId&&i(this.dragSessionId),y(),this.resetDragState(),super.detach()}processColumns(e){if(!this.config.showDragHandle)return[...e];const t={field:"__tbw_row_drag",header:"",width:this.config.dragHandleWidth??40,resizable:!1,sortable:!1,filterable:!1,lockPosition:!0,utility:!0,viewRenderer:()=>{const e=document.createElement("div");return e.className="dg-row-drag-handle",e.setAttribute("aria-label","Drag to reorder"),e.setAttribute("role","button"),e.setAttribute("tabindex","-1"),e.draggable=!0,this.setIcon(e,"dragHandle"),e}};return"right"===this.config.dragHandlePosition?[...e,t]:[t,...e]}afterRender(){}onKeyDown(e){if(!this.config.enableKeyboard)return;if(!e.ctrlKey||"ArrowUp"!==e.key&&"ArrowDown"!==e.key)return;const t=this.internalGrid,r=t._focusRow,o=t._rows??this.sourceRows;if(r<0||r>=o.length)return;const i="up"===("ArrowUp"===e.key?"up":"down")?r-1:r+1;if(i<0||i>=o.length)return;const n=o[r];return this.canMoveRow(r,i)?(this.handleKeyboardMove(n,r,i,t._focusCol),e.preventDefault(),e.stopPropagation(),!0):void 0}onCellClick(){this.flushPendingMove()}moveRow(e,t){const r=[...this.sourceRows];e<0||e>=r.length||t<0||t>=r.length||e!==t&&this.canMoveRow(e,t)&&this.executeIntraGridMove(r[e],e,t,"keyboard")}canMoveRow(e,t){const r=this.internalGrid._rows??this.sourceRows;if(e<0||e>=r.length)return!1;if(t<0||t>=r.length)return!1;if(e===t)return!1;const o=r[e],i=this.grid?.query?.("canMoveRow",o);if(Array.isArray(i)&&i.includes(!1))return!1;if(this.config.canDrag&&!this.config.canDrag(o,e))return!1;if(this.config.canMove){const r=t<e?"up":"down";if(!this.config.canMove(o,e,t,r))return!1}if(this.config.canDrop){const r={sessionId:"intra",sourceGridId:this.gridId,dropZone:this.config.dropZone??"",rows:[o],rowIndices:[e],operation:"move"};if(!this.config.canDrop(r,t))return!1}return!0}setupDelegatedDragListeners(){const e=this.gridElement;if(!e)return;const t=this.disconnectSignal;e.addEventListener("dragstart",e=>this.onDragStart(e),{signal:t}),e.addEventListener("dragend",()=>this.onDragEnd(),{signal:t}),e.addEventListener("dragover",e=>this.onDragOver(e),{signal:t}),e.addEventListener("dragleave",e=>this.onDragLeave(e),{signal:t}),e.addEventListener("drop",e=>this.onDrop(e),{signal:t})}onDragStart(e){const o=e.target.closest(".dg-row-drag-handle");if(!o)return;const i=o.closest(".data-grid-row");if(!i)return;const s=this.getRowIndex(i);if(s<0)return;const{rows:a,indices:d}=this.resolveDraggedRows(s);if(0===a.length)return;if(this.config.canDrag&&!this.config.canDrag(a[0],s))return void e.preventDefault();const c=this.config.operation??"move",l=this.config.dropZone??"",g=n(),u={rows:a,indices:d,operation:c,dropZone:l};if(this.emitCancelable("row-drag-start",u))return void e.preventDefault();this.isDragging=!0,this.draggedRowIndex=s,this.draggedRows=a,this.draggedIndices=d,this.dragSessionId=g,this.dragAccepted=!1;const f=this.config.serializeRow??(e=>e),h={sessionId:g,sourceGridId:this.gridId,dropZone:l,rows:a.map(f),rowIndices:d,operation:c};if(e.dataTransfer){e.dataTransfer.effectAllowed="copy"===c?"copyMove":"move";try{e.dataTransfer.setData(I,R(h)),l&&e.dataTransfer.setData(`${I};zone=${encodeURIComponent(l)}`,R(h)),e.dataTransfer.setData("text/plain",function(e,t){const r=t.filter(e=>!e.utility&&"string"==typeof e.field&&""!==e.field),o=[];for(const i of e){const e=r.map(e=>{const t=i[e.field];return null==t?"":String(t).replace(/[\t\r\n]+/g," ")});o.push(e.join("\t"))}return o.join("\n")}(a,this.columns))}catch{}if(a.length>1){const t=document.createElement("div");t.className="tbw-row-drag-count",t.textContent=`${a.length} rows`,document.body.appendChild(t);try{e.dataTransfer.setDragImage(t,10,10)}catch{}setTimeout(()=>t.remove(),0)}}!function(e,t,o){const i=[];let n=!1;for(const r of t)null!==r&&"object"==typeof r?i.push(new WeakRef(r)):n=!0;r.set(e,{refs:i,hasPrimitives:n,meta:o})}(g,a),function(e,t){b={sessionId:e,payload:t}}(g,h),i.classList.add(t),this.gridElement.classList.add("tbw-grid--drag-source")}onDragOver(e){const t=e.dataTransfer;if(!t)return;const r=t.types?Array.from(t.types):[];if(!function(e){for(const t of e)if(t===I||t.startsWith(`${I};`))return!0;return!1}(r)&&!this.isDragging)return;const o=this.config.dropZone??"",i=v(),n=this.isDragging&&i?.payload.sourceGridId===this.gridId;if(!n){if(!o)return;const e=function(e,t){for(const r of e)if(x(r)===t)return r;return null}(r,o);if(!(e||i&&i.payload.dropZone===o))return}e.preventDefault(),t&&(t.dropEffect=i?.payload.operation??this.config.operation??"move");const s=e.target.closest(".data-grid-row"),a=this.internalGrid._rows??[],d=E(s,e.clientY,e=>this.getRowIndex(e),a.length);if(n&&null!==d.overIndex&&d.overIndex===this.draggedRowIndex)this.clearDropTargetClasses();else{if(i&&this.config.canDrop){const e=this.config.canDrop(i.payload,d.insertIndex);if(this.gridElement.classList.toggle("tbw-grid--drop-target-active",e),this.gridElement.classList.toggle("tbw-grid--drop-target-rejected",!e),!e)return void this.clearDropTargetClasses()}else this.gridElement.classList.add("tbw-grid--drop-target-active");this.dropRowIndex=d.insertIndex,this.applyDropPositionClasses(s,d.isBefore),!1!==this.config.autoScroll&&(this.ensureAutoScroller(),this.autoScroller?.onPointerMove(e.clientY))}}onDragLeave(e){const t=e.target.closest(".data-grid-row");t&&t.classList.remove("drop-target","drop-before","drop-after"),e.currentTarget&&!this.gridElement.contains(e.relatedTarget)&&(this.gridElement.classList.remove("tbw-grid--drop-target-active","tbw-grid--drop-target-rejected"),this.autoScroller?.stop())}onDrop(e){e.preventDefault(),this.autoScroller?.stop(),this.gridElement.classList.remove("tbw-grid--drop-target-active","tbw-grid--drop-target-rejected"),this.clearDropTargetClasses();const t=e.dataTransfer;if(!t)return;const r=v();let i=r?.payload??null,n=null;if(i){const e=o(i.sessionId);e&&(n=e)}else{if(i=function(e){if(!e)return null;try{const t=JSON.parse(e);if("string"!=typeof t?.sessionId||"string"!=typeof t?.sourceGridId||"string"!=typeof t?.dropZone||!Array.isArray(t?.rows)||!Array.isArray(t?.rowIndices)||"move"!==t.operation&&"copy"!==t.operation)return null;for(const e of t.rowIndices)if("number"!=typeof e||!Number.isInteger(e)||e<0)return null;return t}catch{return null}}(t.getData(I)),i){const e=o(i.sessionId);e&&(n=e)}}if(!i)return;const s=e.target.closest(".data-grid-row"),a=this.internalGrid._rows??[],d=E(s,e.clientY,e=>this.getRowIndex(e),a.length);let c=this.dropRowIndex??d.insertIndex;const l=i.sourceGridId===this.gridId,g=this.config.dropZone??"";if(l){const e=i.rowIndices[0];if(1===i.rowIndices.length&&c>e&&c--,e===c)return;const t=(n??i.rows)[0];if(!this.canMoveRow(e,c))return;return void this.executeIntraGridMove(t,e,c,"drag")}if(!g||g!==i.dropZone)return;if(this.config.canDrop&&!this.config.canDrop(i,c))return this.gridElement.classList.add("tbw-grid--drop-target-rejected"),void setTimeout(()=>this.gridElement.classList.remove("tbw-grid--drop-target-rejected"),200);const u=this.config.deserializeRow??(e=>e),f=n??i.rows.map(e=>u(e)),h={payload:i,sourceGridId:i.sourceGridId,targetIndex:c,operation:i.operation};if(this.emitCancelable("row-drop",h))return;const p=[...a];if(p.splice(c,0,...f),this.grid.rows=p,"move"===i.operation){const e=document.getElementById(i.sourceGridId);if(e){const t=(e._rows??e.rows??[]).slice(),r=[...i.rowIndices].sort((e,t)=>t-e);for(const e of r)e>=0&&e<t.length&&t.splice(e,1);e.rows=t}}const w=this.findPeerOnGrid(i.sourceGridId);w&&(w.dragAccepted=!0);const m={rows:f,fromGridId:i.sourceGridId,toGridId:this.gridId,fromIndices:i.rowIndices,toIndex:c,operation:i.operation};this.emit("row-transfer",m),w?.emitTransfer(m)}onDragEnd(){if(this.dragSessionId&&i(this.dragSessionId),y(),this.autoScroller?.stop(),this.gridElement.classList.remove("tbw-grid--drag-source"),this.isDragging){const e={rows:this.draggedRows,indices:this.draggedIndices,accepted:this.dragAccepted};this.emit("row-drag-end",e)}this.clearDragClasses(),this.resetDragState()}emitTransfer(e){this.emit("row-transfer",e)}findPeerOnGrid(e){const t=document.getElementById(e);return t?.getPluginByName?t.getPluginByName("rowDragDrop")??null:null}resolveDraggedRows(e){const t=this.internalGrid._rows??this.sourceRows,r=t[e],o=this.grid?.getPluginByName?.("selection");if(o?.getSelectedRowIndices){const r=o.getSelectedRowIndices();if(r.includes(e)&&r.length>1){const e=[...r].sort((e,t)=>e-t);return{rows:e.map(e=>t[e]),indices:e}}}return{rows:[r],indices:[e]}}ensureAutoScroller(){if(this.autoScroller)return;const e=this.gridElement.querySelector(".rows-viewport");if(!e)return;const t="object"==typeof this.config.autoScroll?this.config.autoScroll:void 0;this.autoScroller=function(e,t={},r){const o=t.edgeSize??60,i=t.speed??8,n=t.maxSpeed??24;let s=null,a=null,d=!1;const c=e=>{e!==d&&(d=e,r?.(e))},l=()=>{if(s=null,null===a)return void c(!1);const t=e.getBoundingClientRect();let r=0;if(a<t.top+o){const e=1-Math.max(0,a-t.top)/o;r=-Math.round(i+(n-i)*e)}else if(a>t.bottom-o){const e=1-Math.max(0,t.bottom-a)/o;r=Math.round(i+(n-i)*e)}if(0===r)return void c(!1);const d=e.scrollTop;e.scrollTop=d+r,e.scrollTop!==d?(c(!0),s=requestAnimationFrame(l)):c(!1)};return{onPointerMove(e){a=e,null===s&&(s=requestAnimationFrame(l))},stop(){null!==s&&(cancelAnimationFrame(s),s=null),a=null,c(!1)},get isScrolling(){return d}}}(e,t,e=>{this.gridElement.classList.toggle("tbw-grid--auto-scrolling",e)})}applyDropPositionClasses(e,t){this.clearDropTargetClasses(),e&&(e.classList.add("drop-target"),e.classList.toggle("drop-before",t),e.classList.toggle("drop-after",!t))}clearDropTargetClasses(){this.gridElement?.querySelectorAll(".data-grid-row.drop-target").forEach(e=>{e.classList.remove("drop-target","drop-before","drop-after")})}clearDragClasses(){this.gridElement?.querySelectorAll(".data-grid-row").forEach(e=>{e.classList.remove(t,"drop-target","drop-before","drop-after")})}resetDragState(){this.isDragging=!1,this.draggedRowIndex=null,this.draggedRows=[],this.draggedIndices=[],this.dragSessionId=null,this.dragAccepted=!1,this.dropRowIndex=null,this.pendingMove=null}getRowIndex(e){const t=e.querySelector(".cell[data-row]");return t?parseInt(t.getAttribute("data-row")??"-1",10):-1}clearDebounceTimer(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null)}handleKeyboardMove(e,t,r,o){this.pendingMove?this.pendingMove.currentIndex=r:this.pendingMove={originalIndex:t,currentIndex:r,row:e},this.lastFocusCol=o;const i=this.internalGrid,n=[...i._rows??this.sourceRows],[s]=n.splice(t,1);n.splice(r,0,s),i._rows=n,i._focusRow=r,i._focusCol=o,i.refreshVirtualWindow(!0),p(i),this.clearDebounceTimer(),this.debounceTimer=setTimeout(()=>this.flushPendingMove(),this.config.debounceMs??300)}flushPendingMove(){if(this.clearDebounceTimer(),!this.pendingMove)return;const{originalIndex:e,currentIndex:t,row:r}=this.pendingMove;if(this.pendingMove=null,e===t)return;const o=this.internalGrid,i={row:r,fromIndex:e,toIndex:t,rows:[...o._rows??this.sourceRows],source:"keyboard"};this.emitCancelable("row-move",i)&&(o._rows=[...this.sourceRows],o._focusRow=e,o._focusCol=this.lastFocusCol,o.refreshVirtualWindow(!0),p(o))}executeIntraGridMove(e,t,r,o){const i=[...this.sourceRows],[n]=i.splice(t,1);i.splice(r,0,n);const s={row:e,fromIndex:t,toIndex:r,rows:i,source:o};if(!this.emitCancelable("row-move",s))if("flip"===this.animationType&&this.gridElement){const e=this.captureRowPositions();this.grid.rows=i,requestAnimationFrame(()=>{this.gridElement.offsetHeight,this.animateFLIP(e,t,r)})}else this.grid.rows=i}captureRowPositions(){const e=/* @__PURE__ */new Map;return this.gridElement?.querySelectorAll(".data-grid-row").forEach(t=>{const r=this.getRowIndex(t);r>=0&&e.set(r,t.getBoundingClientRect().top)}),e}animateFLIP(e,t,r){const o=this.gridElement;if(!o||0===e.size)return;const i=Math.min(t,r),n=Math.max(t,r),s=[];if(o.querySelectorAll(".data-grid-row").forEach(o=>{const a=o,d=this.getRowIndex(a);if(d<0||d<i||d>n)return;let c;c=d===r?t:t<r?d+1:d-1;const l=e.get(c);if(void 0===l)return;const g=l-a.getBoundingClientRect().top;Math.abs(g)>1&&s.push({el:a,deltaY:g})}),0===s.length)return;s.forEach(({el:e,deltaY:t})=>{e.style.transform=`translateY(${t}px)`}),o.offsetHeight;const a=this.animationDuration;requestAnimationFrame(()=>{s.forEach(({el:e})=>{e.classList.add("flip-animating"),e.style.transform=""}),setTimeout(()=>{s.forEach(({el:e})=>{e.style.transform="",e.classList.remove("flip-animating")})},a+50)})}}export{D as RowReorderPlugin};
2
2
  //# sourceMappingURL=index.js.map