melondtable 1.19.0 → 1.20.7

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.
@@ -93,7 +93,7 @@ export default class ColumnManager {
93
93
  });
94
94
 
95
95
  $.on(this.$dropdownList, 'click', '.dt-dropdown__list-item', (e, $item) => {
96
- if (!this._dropdownActiveColIndex) return;
96
+ if (this._dropdownActiveColIndex == null) return;
97
97
  const dropdownItems = this.options.headerDropdown;
98
98
  const { index } = $.data($item);
99
99
  const colIndex = this._dropdownActiveColIndex;
@@ -108,6 +108,11 @@ export default class ColumnManager {
108
108
  _this.hideDropdown();
109
109
  }
110
110
 
111
+ this.stickDropdownIndex = this.options.headerDropdown
112
+ .findIndex(item => item.stickyAction === 'stick');
113
+ this.unstickDropdownIndex = this.options.headerDropdown
114
+ .findIndex(item => item.stickyAction === 'unstick');
115
+
111
116
  this.hideDropdown();
112
117
  }
113
118
 
@@ -124,6 +129,7 @@ export default class ColumnManager {
124
129
  const $cell = $.closest('.dt-cell', e.target);
125
130
  const { colIndex } = $.data($cell);
126
131
  this._dropdownActiveColIndex = colIndex;
132
+ this.updateStickyDropdownItems(this.getColumn(colIndex));
127
133
  }
128
134
 
129
135
  hideDropdown() {
@@ -304,6 +310,20 @@ export default class ColumnManager {
304
310
  });
305
311
  }
306
312
 
313
+ setColumnSticky(colIndex, sticky) {
314
+ const column = this.getColumn(colIndex);
315
+ if (!column || column.sticky === sticky) {
316
+ return;
317
+ }
318
+
319
+ this.instance.freeze();
320
+ this.datamanager.updateColumn(colIndex, { sticky });
321
+
322
+ this.refreshHeader();
323
+ this.rowmanager.refreshRows()
324
+ .then(() => this.instance.unfreeze());
325
+ }
326
+
307
327
  switchColumn(oldIndex, newIndex) {
308
328
  this.instance.freeze();
309
329
  this.datamanager.switchColumn(oldIndex, newIndex)
@@ -493,4 +513,21 @@ export default class ColumnManager {
493
513
  toggleDropdownItem(index) {
494
514
  $('.dt-dropdown__list', this.instance.dropdownContainer).children[index].classList.toggle('dt-hidden');
495
515
  }
516
+
517
+ updateStickyDropdownItems(column) {
518
+ if (!column) return;
519
+ if (this.stickDropdownIndex === -1 || this.unstickDropdownIndex === -1) return;
520
+
521
+ const stickItem = this.$dropdownList.children[this.stickDropdownIndex];
522
+ const unstickItem = this.$dropdownList.children[this.unstickDropdownIndex];
523
+ if (!(stickItem && unstickItem)) return;
524
+
525
+ if (column.sticky) {
526
+ stickItem.classList.add('dt-hidden');
527
+ unstickItem.classList.remove('dt-hidden');
528
+ } else {
529
+ stickItem.classList.remove('dt-hidden');
530
+ unstickItem.classList.add('dt-hidden');
531
+ }
532
+ }
496
533
  }
@@ -62,6 +62,7 @@ export default class DataManager {
62
62
  sortable: false,
63
63
  focusable: false,
64
64
  dropdown: false,
65
+ sticky: true,
65
66
  width: 32
66
67
  };
67
68
  this.columns.push(cell);
@@ -70,16 +71,14 @@ export default class DataManager {
70
71
  if (this.options.serialNoColumn && !this.hasColumnById('_rowIndex')) {
71
72
  let cell = {
72
73
  id: '_rowIndex',
73
- content: '',
74
+ content: this.options.serialNoColumnLabel || '',
74
75
  align: 'center',
75
76
  editable: false,
76
- resizable: false,
77
+ resizable: true,
77
78
  focusable: false,
78
- dropdown: false
79
+ dropdown: false,
80
+ sticky: true
79
81
  };
80
- if (this.options.data.length > 1000) {
81
- cell.resizable = true;
82
- }
83
82
  this.columns.push(cell);
84
83
  }
85
84
  }
package/src/datatable.js CHANGED
@@ -222,6 +222,10 @@ class DataTable {
222
222
  this.columnmanager.removeColumn(colIndex);
223
223
  }
224
224
 
225
+ setColumnSticky(colIndex, sticky) {
226
+ this.columnmanager.setColumnSticky(colIndex, sticky);
227
+ }
228
+
225
229
  scrollToLastColumn() {
226
230
  this.datatableWrapper.scrollLeft = 9999;
227
231
  }
package/src/defaults.js CHANGED
@@ -30,6 +30,22 @@ export default function getDefaultOptions(instance) {
30
30
  action: function (column) {
31
31
  this.removeColumn(column.colIndex);
32
32
  }
33
+ },
34
+ {
35
+ label: instance.translate('Freeze'),
36
+ stickyAction: 'stick',
37
+ display: 'hidden',
38
+ action: function (column) {
39
+ this.setColumnSticky(column.colIndex, true);
40
+ }
41
+ },
42
+ {
43
+ label: instance.translate('Unfreeze'),
44
+ stickyAction: 'unstick',
45
+ display: 'hidden',
46
+ action: function (column) {
47
+ this.setColumnSticky(column.colIndex, false);
48
+ }
33
49
  }
34
50
  ],
35
51
  events: {
@@ -54,6 +70,7 @@ export default function getDefaultOptions(instance) {
54
70
  freezeMessage: '',
55
71
  getEditor: null,
56
72
  serialNoColumn: true,
73
+ serialNoColumnLabel: '',
57
74
  checkboxColumn: false,
58
75
  clusterize: true,
59
76
  logs: false,
package/src/style.css CHANGED
@@ -17,6 +17,7 @@
17
17
  --dt-toast-message-border: none;
18
18
  --dt-header-cell-bg: var(--dt-cell-bg);
19
19
  --dt-no-data-message-width: 90px;
20
+ --dt-scroll-left: 0px;
20
21
  }
21
22
 
22
23
  .datatable {
@@ -69,7 +70,7 @@
69
70
  display: none;
70
71
  }
71
72
 
72
- &:last-child:not(.dt-row-filter) {
73
+ &:last-child:not(.dt-row-filter) .dt-cell {
73
74
  border-bottom: 1px solid var(--dt-border-color);
74
75
  }
75
76
  }
@@ -77,7 +78,7 @@
77
78
  .dt-cell {
78
79
  border: 1px solid var(--dt-border-color);
79
80
  border-bottom: none;
80
- border-right: none;
81
+ border-left: none;
81
82
  position: relative;
82
83
  outline: none;
83
84
  padding: 0;
@@ -91,6 +92,10 @@
91
92
  background-clip: padding-box;
92
93
  user-select: none;
93
94
 
95
+ &:first-child {
96
+ border-left: 1px solid var(--dt-border-color);
97
+ }
98
+
94
99
  &__content {
95
100
  padding: var(--dt-spacer-2);
96
101
  border: var(--dt-focus-border-width) solid transparent;
@@ -170,6 +175,29 @@
170
175
  &:last-child {
171
176
  border-right: 1px solid var(--dt-border-color);
172
177
  }
178
+
179
+ &--sticky {
180
+ position: sticky;
181
+ left: 0;
182
+ z-index: 1;
183
+ }
184
+
185
+ &--sticky-top {
186
+ z-index: 4;
187
+ will-change: transform;
188
+ }
189
+
190
+ &--sticky-last::after {
191
+ content: '';
192
+ position: absolute;
193
+ top: 0;
194
+ right: -1px;
195
+ width: 8px;
196
+ height: 100%;
197
+ pointer-events: none;
198
+ box-shadow: 4px 0 6px -4px rgba(15, 23, 42, 0.2);
199
+ }
200
+
173
201
  }
174
202
 
175
203
  .datatable[dir=rtl] .dt-cell__resize-handle {
@@ -207,7 +235,7 @@
207
235
  &__list {
208
236
  position: fixed;
209
237
  min-width: 8rem;
210
- z-index: 1;
238
+ z-index: 10;
211
239
  cursor: pointer;
212
240
  background-color: var(--dt-cell-bg);
213
241
  border-radius: var(--dt-border-radius);
@@ -245,6 +273,7 @@
245
273
  bottom: var(--dt-spacer-3);
246
274
  left: 50%;
247
275
  transform: translateX(-50%);
276
+ z-index: 5;
248
277
 
249
278
  &__message {
250
279
  display: inline-block;
package/src/style.js CHANGED
@@ -41,6 +41,7 @@ export default class Style {
41
41
 
42
42
  bindScrollHeader() {
43
43
  this._settingHeaderPosition = false;
44
+ this.updateStickyTopPositions(0);
44
45
 
45
46
  $.on(this.bodyScrollable, 'scroll', (e) => {
46
47
  if (this._settingHeaderPosition) return;
@@ -48,7 +49,8 @@ export default class Style {
48
49
  this._settingHeaderPosition = true;
49
50
 
50
51
  requestAnimationFrame(() => {
51
- const left = -e.target.scrollLeft;
52
+ const scrollLeft = e.target.scrollLeft;
53
+ const left = -scrollLeft;
52
54
 
53
55
  $.style(this.header, {
54
56
  transform: `translateX(${left}px)`
@@ -56,6 +58,7 @@ export default class Style {
56
58
  $.style(this.footer, {
57
59
  transform: `translateX(${left}px)`
58
60
  });
61
+ this.updateStickyTopPositions(scrollLeft);
59
62
  this._settingHeaderPosition = false;
60
63
  if (this.instance.noData) {
61
64
  $.style($('.no-data-message'), {
@@ -153,6 +156,8 @@ export default class Style {
153
156
  this.setupColumnWidth();
154
157
  this.distributeRemainingWidth();
155
158
  this.setColumnStyle();
159
+ this.setStickyColumnStyle();
160
+ this.updateStickyTopPositions(this.bodyScrollable.scrollLeft || 0);
156
161
  this.setBodyStyle();
157
162
  }
158
163
 
@@ -310,6 +315,8 @@ export default class Style {
310
315
  this.columnmanager.setColumnHeaderWidth(column.colIndex);
311
316
  this.columnmanager.setColumnWidth(column.colIndex);
312
317
  });
318
+ this.setStickyColumnStyle();
319
+ this.updateStickyTopPositions(this.bodyScrollable.scrollLeft || 0);
313
320
  }
314
321
 
315
322
  setBodyStyle() {
@@ -371,6 +378,56 @@ export default class Style {
371
378
  return $(`.dt-cell--col-${colIndex}`, this.header);
372
379
  }
373
380
 
381
+ setStickyColumnStyle() {
382
+ if (!this.datamanager || !this.datamanager.getColumns) return;
383
+
384
+ const stickySelectors = [];
385
+ let stickyOffset = 0;
386
+ let normalOffset = 0;
387
+
388
+ this.datamanager.getColumns().forEach((column) => {
389
+ const $headerCell = this.getColumnHeaderElement(column.colIndex);
390
+ const renderedWidth = $headerCell ? $headerCell.offsetWidth : column.width;
391
+
392
+ if (column.sticky) {
393
+ const selector = `.dt-cell--col-${column.colIndex}.dt-cell--sticky`;
394
+ const style = {
395
+ left: `${stickyOffset}px`
396
+ };
397
+
398
+ column.stickyLeft = stickyOffset;
399
+ column.stickyScrollTrigger = normalOffset - stickyOffset;
400
+ column.renderedWidth = renderedWidth;
401
+ this.setStyle(selector, style);
402
+ stickySelectors.push(selector);
403
+ stickyOffset += renderedWidth;
404
+ }
405
+ normalOffset += renderedWidth;
406
+ });
407
+
408
+ const staleSelectors = (this._stickySelectors || [])
409
+ .filter(selector => !stickySelectors.includes(selector));
410
+
411
+ staleSelectors.forEach(selector => this.removeStyle(selector));
412
+ this._stickySelectors = stickySelectors;
413
+ }
414
+
415
+ updateStickyTopPositions(scrollLeft) {
416
+ if (!this.datamanager || !this.datamanager.getColumns) return;
417
+
418
+ const stickyColumns = this.datamanager.getColumns().filter(column => column.sticky);
419
+
420
+ stickyColumns.forEach((column) => {
421
+ const trigger = Math.max(0, column.stickyScrollTrigger || 0);
422
+ const compensation = Math.max(0, scrollLeft - trigger);
423
+ const cells = $.each(`.dt-cell--col-${column.colIndex}.dt-cell--sticky-top`, this.wrapper) || [];
424
+
425
+ $.style(cells, {
426
+ transform: compensation ? `translateX(${compensation}px)` : ''
427
+ });
428
+ });
429
+ }
430
+
374
431
  getRowIndexColumnWidth() {
375
432
  const rowCount = this.datamanager.getRowCount();
376
433
  const padding = 22;
@@ -3,6 +3,8 @@
3
3
  "Sort Descending": "Sort Descending",
4
4
  "Reset sorting": "Reset sorting",
5
5
  "Remove column": "Remove column",
6
+ "Freeze": "Freeze",
7
+ "Unfreeze": "Unfreeze",
6
8
  "No Data": "No Data",
7
9
  "{count} cells copied": {
8
10
  "1": "{count} cell copied",
@@ -3,6 +3,8 @@
3
3
  "Sort Descending": "Trier par ordre décroissant",
4
4
  "Reset sorting": "Réinitialiser le tri",
5
5
  "Remove column": "Supprimer colonne",
6
+ "Freeze": "Geler",
7
+ "Unfreeze": "Dégeler",
6
8
  "No Data": "Pas de données",
7
9
  "{count} cells copied": {
8
10
  "1": "{count} cellule copiée",
@@ -13,3 +13,4 @@
13
13
  "default": "{count} linhas selecionadas"
14
14
  }
15
15
  }
16
+
@@ -13,3 +13,4 @@
13
13
  "default": "{count} safu zilizochaguliwa"
14
14
  }
15
15
  }
16
+