vgapp 1.2.5 → 1.2.6

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 (42) hide show
  1. package/CHANGELOG.md +58 -35
  2. package/agents.md +2 -2
  3. package/app/modules/base-module.js +87 -10
  4. package/app/modules/vgalert/js/vgalert.js +3 -3
  5. package/app/modules/vgdynamictable/index.js +5 -0
  6. package/app/modules/vgdynamictable/js/editable.js +438 -0
  7. package/app/modules/vgdynamictable/js/expandable.js +248 -0
  8. package/app/modules/vgdynamictable/js/filters.js +450 -0
  9. package/app/modules/vgdynamictable/js/fixed.js +566 -0
  10. package/app/modules/vgdynamictable/js/options.js +646 -0
  11. package/app/modules/vgdynamictable/js/pagination.js +623 -0
  12. package/app/modules/vgdynamictable/js/search.js +82 -0
  13. package/app/modules/vgdynamictable/js/skeleton.js +136 -0
  14. package/app/modules/vgdynamictable/js/sortable.js +442 -0
  15. package/app/modules/vgdynamictable/js/summary-footer.js +284 -0
  16. package/app/modules/vgdynamictable/js/table-remote.js +821 -0
  17. package/app/modules/vgdynamictable/js/table-state.js +243 -0
  18. package/app/modules/vgdynamictable/js/table-url-state.js +444 -0
  19. package/app/modules/vgdynamictable/js/utils/common.js +48 -0
  20. package/app/modules/vgdynamictable/js/vgdynamictable.js +3829 -0
  21. package/app/modules/vgdynamictable/js/viewport.js +322 -0
  22. package/app/modules/vgdynamictable/readme.md +251 -0
  23. package/app/modules/vgdynamictable/scss/_actions.scss +193 -0
  24. package/app/modules/vgdynamictable/scss/_pagination.scss +183 -0
  25. package/app/modules/vgdynamictable/scss/_skeleton.scss +60 -0
  26. package/app/modules/vgdynamictable/scss/_sortable.scss +63 -0
  27. package/app/modules/vgdynamictable/scss/_table.scss +157 -0
  28. package/app/modules/vgdynamictable/scss/_variables.scss +130 -0
  29. package/app/modules/vgdynamictable/scss/vgdynamictable.scss +267 -0
  30. package/app/modules/vgrangeslider/index.js +3 -0
  31. package/app/modules/vgrangeslider/js/skins.js +222 -0
  32. package/app/modules/vgrangeslider/js/vgrangeslider.js +704 -0
  33. package/app/modules/vgrangeslider/readme.md +523 -0
  34. package/app/modules/vgrangeslider/scss/_variables.scss +53 -0
  35. package/app/modules/vgrangeslider/scss/vgrangeslider.scss +240 -0
  36. package/app/utils/js/components/ajax.js +116 -7
  37. package/build/vgapp.css +2 -3246
  38. package/build/vgapp.css.map +1 -1
  39. package/build/vgapp.js +2 -30
  40. package/index.js +2 -0
  41. package/index.scss +6 -0
  42. package/package.json +1 -1
@@ -0,0 +1,566 @@
1
+ const fixedColumnsMethods = {
2
+ _getFixedColumnsConfigRaw() {
3
+ const fixedOptions = this._params && this._params.fixed && typeof this._params.fixed === 'object'
4
+ ? this._params.fixed
5
+ : {};
6
+ const optionRaw = fixedOptions.columns;
7
+ const attrRaw = this._element
8
+ ? this._element.getAttribute('data-fixed-columns')
9
+ : null;
10
+ const raw = attrRaw !== null && attrRaw !== undefined && String(attrRaw).trim() !== ''
11
+ ? attrRaw
12
+ : optionRaw;
13
+ return String(raw || '').trim();
14
+ },
15
+
16
+ _hasFixedColumnsConfig() {
17
+ const attr = this._getFixedColumnsConfigRaw();
18
+ if (attr !== '') {
19
+ return true;
20
+ }
21
+ const headers = this._element && this._element.tHead
22
+ ? Array.from(this._element.tHead.querySelectorAll('th'))
23
+ : [];
24
+ return headers.some((header) => {
25
+ const fixedAttr = String(header.getAttribute('data-fixed') || '').toLowerCase().trim();
26
+ const fixedColumnAttr = String(header.getAttribute('data-fixed-column') || '').toLowerCase().trim();
27
+ return fixedAttr === 'left' || fixedAttr === 'right' || fixedColumnAttr === 'left' || fixedColumnAttr === 'right';
28
+ });
29
+ },
30
+
31
+ _buildFixedColumnsStateMap(fixed) {
32
+ const state = new Map();
33
+ const left = Array.isArray(fixed && fixed.left) ? fixed.left : [];
34
+ const right = Array.isArray(fixed && fixed.right) ? fixed.right : [];
35
+ left.forEach((index) => {
36
+ if (Number.isInteger(index) && index >= 0) {
37
+ state.set(index, 'left');
38
+ }
39
+ });
40
+ right.forEach((index) => {
41
+ if (Number.isInteger(index) && index >= 0 && !state.has(index)) {
42
+ state.set(index, 'right');
43
+ }
44
+ });
45
+ return state;
46
+ },
47
+
48
+ _collectFixedColumnsTransitions(nextState) {
49
+ const previousState = this._fixedColumnsLastStateMap instanceof Map
50
+ ? this._fixedColumnsLastStateMap
51
+ : new Map();
52
+ const transitions = [];
53
+ nextState.forEach((side, index) => {
54
+ if (previousState.get(index) !== side) {
55
+ transitions.push({ index, side });
56
+ }
57
+ });
58
+ this._fixedColumnsLastStateMap = nextState;
59
+ return transitions;
60
+ },
61
+
62
+ _applyFixedColumnsLayout() {
63
+ if (!this._element) {
64
+ return;
65
+ }
66
+ const suppressFixedColumns = Boolean(this._fixedColumnsSuppressed);
67
+
68
+ const sourceHeaders = this._element.tHead ? Array.from(this._element.tHead.querySelectorAll('th')) : [];
69
+ const sourceFixedRaw = this._getFixedColumnsByHeaders(sourceHeaders, {
70
+ parseTableAttr: true,
71
+ fallbackByPosition: true,
72
+ });
73
+ const sourceFixed = suppressFixedColumns
74
+ ? { left: [], right: [] }
75
+ : this._applyMobileFixedColumnsGuard(this._element, sourceFixedRaw);
76
+ const hasSourceFixed = sourceFixed.left.length > 0 || sourceFixed.right.length > 0;
77
+ this._element.classList.toggle('table-fixed-cols', hasSourceFixed);
78
+ if (this._parent) {
79
+ this._parent.classList.toggle('table-fixed-cols', hasSourceFixed);
80
+ }
81
+ const sourceFixedTransitions = this._collectFixedColumnsTransitions(
82
+ this._buildFixedColumnsStateMap(sourceFixed)
83
+ );
84
+ this._applyFixedColumnsToTable(this._element, sourceFixed, {
85
+ includeBody: true,
86
+ emitAction: true,
87
+ transitionedColumns: sourceFixedTransitions,
88
+ });
89
+ this._toggleFixedColumnsScrollBinding(hasSourceFixed);
90
+
91
+ const cloneTable = this._cloneStickyState && this._cloneStickyState.table
92
+ ? this._cloneStickyState.table
93
+ : null;
94
+ if (cloneTable) {
95
+ const cloneHeaders = cloneTable.tHead ? Array.from(cloneTable.tHead.querySelectorAll('th')) : [];
96
+ const cloneFixedRaw = this._getFixedColumnsByHeaders(cloneHeaders, {
97
+ parseTableAttr: false,
98
+ fallbackByPosition: false,
99
+ });
100
+ const cloneFixed = hasSourceFixed
101
+ ? this._applyMobileFixedColumnsGuard(cloneTable, cloneFixedRaw)
102
+ : { left: [], right: [] };
103
+ this._applyFixedColumnsToTable(cloneTable, cloneFixed, {
104
+ includeBody: false,
105
+ emitAction: false,
106
+ });
107
+ }
108
+ this._rebuildFixedColumnsCellsCache();
109
+ this._syncFixedColumnsScroll({ immediate: true });
110
+ },
111
+
112
+ _applyMobileFixedColumnsGuard(table, fixed) {
113
+ const next = {
114
+ left: Array.isArray(fixed && fixed.left) ? fixed.left.slice() : [],
115
+ right: Array.isArray(fixed && fixed.right) ? fixed.right.slice() : [],
116
+ };
117
+ if (!this._isTouchDevice()) {
118
+ return next;
119
+ }
120
+ const viewportMetrics = this._getViewportWidthMetrics();
121
+ const viewportWidth = viewportMetrics
122
+ ? viewportMetrics.effectiveWidth
123
+ : (table ? table.getBoundingClientRect().width : 0);
124
+ const isMobileViewport = viewportWidth > 0 && viewportWidth <= 768;
125
+ if (!isMobileViewport) {
126
+ return next;
127
+ }
128
+
129
+ const fixedIndexes = next.left.concat(next.right);
130
+ if (fixedIndexes.length <= 0) {
131
+ return next;
132
+ }
133
+ if (fixedIndexes.length > 1) {
134
+ return { left: [], right: [] };
135
+ }
136
+
137
+ const headerCells = table && table.tHead ? Array.from(table.tHead.querySelectorAll('th')) : [];
138
+ const fixedIndex = fixedIndexes[0];
139
+ const header = Number.isInteger(fixedIndex) && fixedIndex >= 0 && fixedIndex < headerCells.length
140
+ ? headerCells[fixedIndex]
141
+ : null;
142
+ if (!header) {
143
+ return next;
144
+ }
145
+
146
+ const columnWidth = header.getBoundingClientRect().width || 0;
147
+ if (columnWidth > viewportWidth * 0.5) {
148
+ return { left: [], right: [] };
149
+ }
150
+
151
+ return next;
152
+ },
153
+
154
+ _getFixedColumnsByHeaders(headers, options = {}) {
155
+ const list = Array.isArray(headers) ? headers : [];
156
+ const parseTableAttr = options.parseTableAttr !== false;
157
+ const fallbackByPosition = options.fallbackByPosition !== false;
158
+ const byField = new Map();
159
+ const leftSet = new Set();
160
+ const rightSet = new Set();
161
+ const autoIndexes = [];
162
+
163
+ list.forEach((header, index) => {
164
+ const field = String(header.getAttribute('data-field') || '').trim();
165
+ if (field !== '') {
166
+ byField.set(field, index);
167
+ }
168
+ });
169
+
170
+ list.forEach((header, index) => {
171
+ const fixedAttr = String(header.getAttribute('data-fixed') || '').toLowerCase().trim();
172
+ const fixedColumnAttr = String(header.getAttribute('data-fixed-column') || '').toLowerCase().trim();
173
+ const side = fixedAttr === 'left' || fixedAttr === 'right'
174
+ ? fixedAttr
175
+ : (fixedColumnAttr === 'left' || fixedColumnAttr === 'right' ? fixedColumnAttr : '');
176
+ if (side === 'left') {
177
+ leftSet.add(index);
178
+ } else if (side === 'right') {
179
+ rightSet.add(index);
180
+ } else if (!parseTableAttr) {
181
+ const clonedSide = String(header.getAttribute('data-fixed-side') || '').toLowerCase().trim();
182
+ if (clonedSide === 'left') {
183
+ leftSet.add(index);
184
+ } else if (clonedSide === 'right') {
185
+ rightSet.add(index);
186
+ }
187
+ }
188
+ });
189
+
190
+ if (parseTableAttr && this._element) {
191
+ const attrRaw = this._getFixedColumnsConfigRaw();
192
+ if (attrRaw !== '') {
193
+ const groups = attrRaw.split(';').map((item) => item.trim()).filter(Boolean);
194
+ groups.forEach((group) => {
195
+ const sideMatch = group.match(/^(left|right)\s*:\s*(.+)$/i);
196
+ const explicitSide = sideMatch ? sideMatch[1].toLowerCase() : '';
197
+ const valuesRaw = sideMatch ? sideMatch[2] : group;
198
+ const values = valuesRaw.split(',').map((item) => item.trim()).filter(Boolean);
199
+ values.forEach((name) => {
200
+ const index = byField.has(name) ? byField.get(name) : Number.parseInt(name, 10);
201
+ if (!Number.isInteger(index) || index < 0 || index >= list.length) {
202
+ return;
203
+ }
204
+ if (explicitSide === 'left') {
205
+ leftSet.add(index);
206
+ } else if (explicitSide === 'right') {
207
+ rightSet.add(index);
208
+ } else {
209
+ autoIndexes.push(index);
210
+ }
211
+ });
212
+ });
213
+ }
214
+ }
215
+
216
+ autoIndexes.forEach((index) => {
217
+ if (leftSet.has(index) || rightSet.has(index)) {
218
+ return;
219
+ }
220
+ const distanceLeft = index;
221
+ const distanceRight = Math.max(0, list.length - 1 - index);
222
+ if (distanceLeft <= distanceRight || !fallbackByPosition) {
223
+ leftSet.add(index);
224
+ return;
225
+ }
226
+ rightSet.add(index);
227
+ });
228
+
229
+ const left = Array.from(leftSet).sort((a, b) => a - b);
230
+ const right = Array.from(rightSet)
231
+ .filter((index) => !leftSet.has(index))
232
+ .sort((a, b) => a - b);
233
+
234
+ return { left, right };
235
+ },
236
+
237
+ _applyFixedColumnsToTable(table, fixed, options = {}) {
238
+ if (!table) {
239
+ return;
240
+ }
241
+ const includeBody = options.includeBody !== false;
242
+ const shouldEmitAction = options.emitAction !== false;
243
+ const transitionedColumns = Array.isArray(options.transitionedColumns)
244
+ ? options.transitionedColumns
245
+ : [];
246
+ const sections = [];
247
+ if (table.tHead) {
248
+ sections.push(table.tHead);
249
+ }
250
+ if (includeBody && table.tBodies && table.tBodies.length) {
251
+ sections.push(...Array.from(table.tBodies));
252
+ }
253
+ if (includeBody && table.tFoot) {
254
+ sections.push(table.tFoot);
255
+ }
256
+
257
+ const rows = [];
258
+ sections.forEach((section) => {
259
+ rows.push(...Array.from(section.rows || []));
260
+ });
261
+ const hasFixed = fixed && (fixed.left.length > 0 || fixed.right.length > 0);
262
+ rows.forEach((row) => {
263
+ Array.from(row.cells || []).forEach((cell) => {
264
+ cell.removeAttribute('data-fixed-side');
265
+ cell.removeAttribute('data-fixed-edge');
266
+ cell.removeAttribute('data-fixed-shift');
267
+ cell.removeAttribute('data-fixed-shadow');
268
+ cell.removeAttribute('data-fixed-overlap');
269
+ cell.style.removeProperty('z-index');
270
+ cell.style.removeProperty('transform');
271
+ });
272
+ });
273
+
274
+ if (!hasFixed) {
275
+ return;
276
+ }
277
+
278
+ const headerCells = table.tHead ? Array.from(table.tHead.querySelectorAll('th')) : [];
279
+ const tableRect = table.getBoundingClientRect();
280
+ const viewportMetrics = this._getViewportWidthMetrics();
281
+ const viewportWidth = viewportMetrics
282
+ ? viewportMetrics.effectiveWidth
283
+ : tableRect.width;
284
+ const metrics = {};
285
+ headerCells.forEach((cell, index) => {
286
+ const rect = cell.getBoundingClientRect();
287
+ metrics[index] = {
288
+ width: Math.max(0, rect.width),
289
+ left: Math.max(0, rect.left - tableRect.left),
290
+ height: Math.max(0, rect.height),
291
+ top: Math.max(0, rect.top - tableRect.top),
292
+ };
293
+ });
294
+ const leftOffsets = {};
295
+ let leftOffset = 0;
296
+ fixed.left.forEach((index) => {
297
+ const width = metrics[index] ? metrics[index].width : 0;
298
+ leftOffsets[index] = leftOffset;
299
+ leftOffset += width;
300
+ });
301
+
302
+ const rightOffsets = {};
303
+ let rightOffset = 0;
304
+ fixed.right.slice().sort((a, b) => b - a).forEach((index) => {
305
+ const width = metrics[index] ? metrics[index].width : 0;
306
+ rightOffsets[index] = rightOffset;
307
+ rightOffset += width;
308
+ });
309
+
310
+ const leftEdgeIndex = fixed.left.length ? fixed.left[fixed.left.length - 1] : -1;
311
+ const rightEdgeIndex = fixed.right.length ? fixed.right[0] : -1;
312
+ rows.forEach((row) => {
313
+ const isHeaderRow = row.parentElement && row.parentElement.tagName === 'THEAD';
314
+ const zIndex = isHeaderRow ? 6 : 2;
315
+
316
+ fixed.left.forEach((index) => {
317
+ const cell = row.cells && row.cells[index] ? row.cells[index] : null;
318
+ if (!cell) {
319
+ return;
320
+ }
321
+ const metric = metrics[index] || { left: 0 };
322
+ const baseShift = leftOffsets[index] - metric.left;
323
+ cell.setAttribute('data-fixed-side', 'left');
324
+ cell.setAttribute('data-fixed-shift', String(baseShift));
325
+ cell.style.zIndex = String(zIndex);
326
+ if (index === leftEdgeIndex) {
327
+ cell.setAttribute('data-fixed-edge', 'right');
328
+ }
329
+ });
330
+
331
+ fixed.right.forEach((index) => {
332
+ const cell = row.cells && row.cells[index] ? row.cells[index] : null;
333
+ if (!cell) {
334
+ return;
335
+ }
336
+ const metric = metrics[index] || { left: 0, width: 0 };
337
+ const desiredLeft = viewportWidth - rightOffsets[index] - metric.width;
338
+ const baseShift = desiredLeft - metric.left;
339
+ cell.setAttribute('data-fixed-side', 'right');
340
+ cell.setAttribute('data-fixed-shift', String(baseShift));
341
+ cell.style.zIndex = String(zIndex);
342
+ if (index === rightEdgeIndex) {
343
+ cell.setAttribute('data-fixed-edge', 'left');
344
+ }
345
+ });
346
+ });
347
+
348
+ if (!shouldEmitAction || typeof this._emitAction !== 'function' || !transitionedColumns.length) {
349
+ return;
350
+ }
351
+
352
+ transitionedColumns.forEach((entry) => {
353
+ const index = Number.isInteger(entry && entry.index) ? entry.index : -1;
354
+ const side = entry && (entry.side === 'left' || entry.side === 'right')
355
+ ? entry.side
356
+ : '';
357
+ const headerCell = index >= 0 && index < headerCells.length
358
+ ? headerCells[index]
359
+ : null;
360
+ if (!headerCell || !side) {
361
+ return;
362
+ }
363
+
364
+ const metric = metrics[index] || { left: 0, width: 0, top: 0, height: 0 };
365
+ const width = metric.width || 0;
366
+ const height = metric.height || 0;
367
+ const left = side === 'left'
368
+ ? (leftOffsets[index] || 0)
369
+ : Math.max(0, viewportWidth - (rightOffsets[index] || 0) - width);
370
+ const right = side === 'right'
371
+ ? (rightOffsets[index] || 0)
372
+ : Math.max(0, viewportWidth - left - width);
373
+ const top = metric.top || 0;
374
+ const bottom = Math.max(0, tableRect.height - top - height);
375
+ const field = String(headerCell.getAttribute('data-field') || '').trim();
376
+ const fallbackBaseShift = left - (metric.left || 0);
377
+ const attrBaseShift = Number.parseFloat(headerCell.getAttribute('data-fixed-shift') || '');
378
+ const baseShift = Number.isFinite(attrBaseShift) ? attrBaseShift : fallbackBaseShift;
379
+ const scrollLeft = this._tableViewport ? (this._tableViewport.scrollLeft || 0) : 0;
380
+ const fixedAtTs = Date.now();
381
+
382
+ this._emitAction('columnfixed', {
383
+ columnIndex: index,
384
+ side,
385
+ phase: 'fixed',
386
+ field,
387
+ column: {
388
+ index,
389
+ side,
390
+ field,
391
+ width,
392
+ height,
393
+ element: headerCell,
394
+ },
395
+ offsets: {
396
+ left,
397
+ right,
398
+ top,
399
+ bottom,
400
+ },
401
+ shift: {
402
+ base: baseShift,
403
+ current: baseShift + scrollLeft,
404
+ scrollLeft,
405
+ },
406
+ fixedAt: {
407
+ timestamp: fixedAtTs,
408
+ iso: new Date(fixedAtTs).toISOString(),
409
+ },
410
+ });
411
+ });
412
+ },
413
+
414
+ _toggleFixedColumnsScrollBinding(enabled) {
415
+ if (!this._tableViewport) {
416
+ this._resetFixedColumnsScrollSyncState();
417
+ return;
418
+ }
419
+ if (enabled && !this._fixedColumnsScrollBound) {
420
+ this._tableViewport.addEventListener('scroll', this._boundFixedColumnsScroll, { passive: true });
421
+ this._fixedColumnsScrollBound = true;
422
+ return;
423
+ }
424
+ if (!enabled && this._fixedColumnsScrollBound) {
425
+ this._tableViewport.removeEventListener('scroll', this._boundFixedColumnsScroll);
426
+ this._fixedColumnsScrollBound = false;
427
+ }
428
+ if (!enabled) {
429
+ this._resetFixedColumnsScrollSyncState();
430
+ }
431
+ },
432
+
433
+ _resetFixedColumnsScrollSyncState() {
434
+ if (this._fixedColumnsSyncFrame && typeof window !== 'undefined' && typeof window.cancelAnimationFrame === 'function') {
435
+ window.cancelAnimationFrame(this._fixedColumnsSyncFrame);
436
+ }
437
+ this._fixedColumnsSyncFrame = 0;
438
+ this._fixedColumnsLastScrollLeft = 0;
439
+ this._fixedColumnsLastAppliedScrollLeft = Number.NaN;
440
+ this._fixedColumnsLastShadowStateKey = '';
441
+ this._fixedColumnsCellsCache = [];
442
+ this._fixedColumnsShadowTargetsCache = [];
443
+ this._fixedColumnsLastStateMap = new Map();
444
+ },
445
+
446
+ _rebuildFixedColumnsCellsCache() {
447
+ const tables = [this._element];
448
+ if (this._cloneStickyState && this._cloneStickyState.table) {
449
+ tables.push(this._cloneStickyState.table);
450
+ }
451
+ const normalizedTables = tables.filter(Boolean);
452
+ this._fixedColumnsCellsCache = normalizedTables
453
+ .map((table) => {
454
+ return Array.from(table.querySelectorAll('[data-fixed-side][data-fixed-shift]'))
455
+ .map((cell) => {
456
+ const baseShift = Number.parseFloat(cell.getAttribute('data-fixed-shift') || '0');
457
+ return {
458
+ cell,
459
+ baseShift: Number.isFinite(baseShift) ? baseShift : 0,
460
+ };
461
+ });
462
+ })
463
+ .filter((cells) => cells.length > 0);
464
+ this._fixedColumnsShadowTargetsCache = normalizedTables
465
+ .map((table) => {
466
+ return {
467
+ table,
468
+ edges: Array.from(table.querySelectorAll('[data-fixed-edge]')),
469
+ fixedCells: Array.from(table.querySelectorAll('[data-fixed-side]')),
470
+ };
471
+ })
472
+ .filter((entry) => entry.edges.length > 0 || entry.fixedCells.length > 0);
473
+ this._fixedColumnsLastAppliedScrollLeft = Number.NaN;
474
+ this._fixedColumnsLastShadowStateKey = '';
475
+ },
476
+
477
+ _syncFixedColumnsScroll(options = {}) {
478
+ if (!this._tableViewport) {
479
+ return;
480
+ }
481
+
482
+ const nextScrollLeft = this._tableViewport.scrollLeft || 0;
483
+ this._fixedColumnsLastScrollLeft = nextScrollLeft;
484
+ const immediate = Boolean(options && options.immediate);
485
+ if (!immediate && this._fixedColumnsLastAppliedScrollLeft === nextScrollLeft) {
486
+ return;
487
+ }
488
+ if (immediate || typeof window === 'undefined' || typeof window.requestAnimationFrame !== 'function') {
489
+ this._flushFixedColumnsScrollSync(nextScrollLeft);
490
+ return;
491
+ }
492
+ if (this._fixedColumnsSyncFrame) {
493
+ return;
494
+ }
495
+ this._fixedColumnsSyncFrame = window.requestAnimationFrame(() => {
496
+ this._fixedColumnsSyncFrame = 0;
497
+ this._flushFixedColumnsScrollSync(this._fixedColumnsLastScrollLeft);
498
+ });
499
+ },
500
+
501
+ _flushFixedColumnsScrollSync(scrollLeft) {
502
+ if (!this._fixedColumnsCellsCache.length) {
503
+ this._rebuildFixedColumnsCellsCache();
504
+ }
505
+ this._fixedColumnsCellsCache.forEach((cells) => {
506
+ cells.forEach(({ cell, baseShift }) => {
507
+ if (!cell || !cell.isConnected) {
508
+ return;
509
+ }
510
+ const shift = baseShift + scrollLeft;
511
+ cell.style.transform = `translate3d(${shift}px, 0px, 0px)`;
512
+ });
513
+ });
514
+ this._fixedColumnsLastAppliedScrollLeft = scrollLeft;
515
+ this._syncFixedColumnsShadows();
516
+ },
517
+
518
+ _syncFixedColumnsShadows() {
519
+ if (!Array.isArray(this._fixedColumnsShadowTargetsCache) || !this._fixedColumnsShadowTargetsCache.length) {
520
+ this._rebuildFixedColumnsCellsCache();
521
+ }
522
+ const targets = Array.isArray(this._fixedColumnsShadowTargetsCache)
523
+ ? this._fixedColumnsShadowTargetsCache
524
+ : [];
525
+ if (!targets.length) {
526
+ return;
527
+ }
528
+
529
+ const viewport = this._tableViewport;
530
+ const canScroll = Boolean(viewport && viewport.scrollWidth > viewport.clientWidth + 1);
531
+ const scrollLeft = viewport ? (viewport.scrollLeft || 0) : 0;
532
+ const maxScrollLeft = viewport ? Math.max(0, viewport.scrollWidth - viewport.clientWidth) : 0;
533
+ const showLeftFixedShadow = canScroll && scrollLeft > 0;
534
+ const showRightFixedShadow = canScroll && scrollLeft < maxScrollLeft - 1;
535
+ const nextStateKey = `${showLeftFixedShadow ? 1 : 0}:${showRightFixedShadow ? 1 : 0}`;
536
+ if (this._fixedColumnsLastShadowStateKey === nextStateKey) {
537
+ return;
538
+ }
539
+ this._fixedColumnsLastShadowStateKey = nextStateKey;
540
+
541
+ targets.forEach(({ edges, fixedCells }) => {
542
+ edges.forEach((cell) => {
543
+ const edge = String(cell.getAttribute('data-fixed-edge') || '').toLowerCase().trim();
544
+ const shouldShow = (edge === 'right' && showLeftFixedShadow) || (edge === 'left' && showRightFixedShadow);
545
+ if (shouldShow) {
546
+ cell.setAttribute('data-fixed-shadow', '1');
547
+ } else {
548
+ cell.removeAttribute('data-fixed-shadow');
549
+ }
550
+ });
551
+
552
+ fixedCells.forEach((cell) => {
553
+ const side = String(cell.getAttribute('data-fixed-side') || '').toLowerCase().trim();
554
+ const hasOverlap = (side === 'left' && showLeftFixedShadow) || (side === 'right' && showRightFixedShadow);
555
+ if (hasOverlap) {
556
+ cell.setAttribute('data-fixed-overlap', '1');
557
+ } else {
558
+ cell.removeAttribute('data-fixed-overlap');
559
+ }
560
+ });
561
+ });
562
+ },
563
+ };
564
+
565
+ export default fixedColumnsMethods;
566
+