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.
package/LICENSE CHANGED
@@ -1 +1,2 @@
1
- MIT
1
+ The MIT License
2
+
@@ -1985,6 +1985,7 @@ class DataManager {
1985
1985
  sortable: false,
1986
1986
  focusable: false,
1987
1987
  dropdown: false,
1988
+ sticky: true,
1988
1989
  width: 32
1989
1990
  };
1990
1991
  this.columns.push(cell);
@@ -1993,16 +1994,14 @@ class DataManager {
1993
1994
  if (this.options.serialNoColumn && !this.hasColumnById('_rowIndex')) {
1994
1995
  let cell = {
1995
1996
  id: '_rowIndex',
1996
- content: '',
1997
+ content: this.options.serialNoColumnLabel || '',
1997
1998
  align: 'center',
1998
1999
  editable: false,
1999
- resizable: false,
2000
+ resizable: true,
2000
2001
  focusable: false,
2001
- dropdown: false
2002
+ dropdown: false,
2003
+ sticky: true
2002
2004
  };
2003
- if (this.options.data.length > 1000) {
2004
- cell.resizable = true;
2005
- }
2006
2005
  this.columns.push(cell);
2007
2006
  }
2008
2007
  }
@@ -2586,6 +2585,7 @@ class CellManager {
2586
2585
  this.bindKeyboardSelection();
2587
2586
  this.bindCopyCellContents();
2588
2587
  this.bindMouseEvents();
2588
+ this.bindWheelEvents();
2589
2589
  this.bindTreeEvents();
2590
2590
  }
2591
2591
 
@@ -2634,6 +2634,7 @@ class CellManager {
2634
2634
  }
2635
2635
 
2636
2636
  this.focusCell($cell);
2637
+ sessionStorage.setItem('dt-last-nav-method', 'key');
2637
2638
  return true;
2638
2639
  };
2639
2640
 
@@ -2742,6 +2743,12 @@ class CellManager {
2742
2743
  $.on(this.bodyScrollable, 'mousemove', '.dt-cell', throttle$1(selectArea, 50));
2743
2744
  }
2744
2745
 
2746
+ bindWheelEvents() {
2747
+ $.on(this.bodyScrollable, 'wheel', (e) => {
2748
+ sessionStorage.setItem('dt-last-nav-method', 'scroll');
2749
+ });
2750
+ }
2751
+
2745
2752
  bindTreeEvents() {
2746
2753
  $.on(this.bodyScrollable, 'click', '.dt-tree-node__toggle', (e, $toggle) => {
2747
2754
  const $cell = $.closest('.dt-cell', $toggle);
@@ -2866,11 +2873,13 @@ class CellManager {
2866
2873
  // this function is called after hyperlist renders the rows after scroll,
2867
2874
  // focusCell calls clearSelection which resets the area selection
2868
2875
  // so a flag to skip it
2869
- // we also skip DOM focus and scroll to cell
2870
- // because it fights with the user scroll
2876
+ // we skip scroll to cell
2877
+ // and also skip DOM focus (if user is scrolling) because it fights with the user scroll
2878
+ const skipDOMFocus = sessionStorage.getItem('dt-last-nav-method') !== 'key';
2879
+
2871
2880
  this.focusCell($cell, {
2881
+ skipDOMFocus,
2872
2882
  skipClearSelection: 1,
2873
- skipDOMFocus: 1,
2874
2883
  skipScrollToCell: 1
2875
2884
  });
2876
2885
  }
@@ -3267,6 +3276,7 @@ class CellManager {
3267
3276
  }
3268
3277
 
3269
3278
  this.focusCell($cell);
3279
+ sessionStorage.setItem('dt-last-nav-method', 'key');
3270
3280
  return true;
3271
3281
  }
3272
3282
 
@@ -3365,8 +3375,15 @@ class CellManager {
3365
3375
  });
3366
3376
 
3367
3377
  const row = this.datamanager.getRow(rowIndex);
3378
+ const column = cell.column || this.datamanager.getColumn(colIndex) || {};
3368
3379
 
3369
3380
  const isBodyCell = !(isHeader || isFilter || isTotalRow);
3381
+ const isSticky = Boolean(column.sticky);
3382
+ const stickyColumns = this.datamanager.getColumns().filter(col => col.sticky);
3383
+ const lastStickyColumn = stickyColumns[stickyColumns.length - 1];
3384
+ const isLastStickyColumn = isSticky &&
3385
+ lastStickyColumn &&
3386
+ lastStickyColumn.colIndex === colIndex;
3370
3387
 
3371
3388
  const className = [
3372
3389
  'dt-cell',
@@ -3376,7 +3393,10 @@ class CellManager {
3376
3393
  isHeader ? 'dt-cell--header' : '',
3377
3394
  isHeader ? `dt-cell--header-${colIndex}` : '',
3378
3395
  isFilter ? 'dt-cell--filter' : '',
3379
- isBodyCell && (row && row.meta.isTreeNodeClose) ? 'dt-cell--tree-close' : ''
3396
+ isBodyCell && (row && row.meta.isTreeNodeClose) ? 'dt-cell--tree-close' : '',
3397
+ isSticky ? 'dt-cell--sticky' : '',
3398
+ isSticky && !isBodyCell ? 'dt-cell--sticky-top' : '',
3399
+ isLastStickyColumn ? 'dt-cell--sticky-last' : ''
3380
3400
  ].join(' ');
3381
3401
 
3382
3402
  return `
@@ -3574,7 +3594,7 @@ class ColumnManager {
3574
3594
  });
3575
3595
 
3576
3596
  $.on(this.$dropdownList, 'click', '.dt-dropdown__list-item', (e, $item) => {
3577
- if (!this._dropdownActiveColIndex) return;
3597
+ if (this._dropdownActiveColIndex == null) return;
3578
3598
  const dropdownItems = this.options.headerDropdown;
3579
3599
  const { index } = $.data($item);
3580
3600
  const colIndex = this._dropdownActiveColIndex;
@@ -3589,6 +3609,11 @@ class ColumnManager {
3589
3609
  _this.hideDropdown();
3590
3610
  }
3591
3611
 
3612
+ this.stickDropdownIndex = this.options.headerDropdown
3613
+ .findIndex(item => item.stickyAction === 'stick');
3614
+ this.unstickDropdownIndex = this.options.headerDropdown
3615
+ .findIndex(item => item.stickyAction === 'unstick');
3616
+
3592
3617
  this.hideDropdown();
3593
3618
  }
3594
3619
 
@@ -3605,6 +3630,7 @@ class ColumnManager {
3605
3630
  const $cell = $.closest('.dt-cell', e.target);
3606
3631
  const { colIndex } = $.data($cell);
3607
3632
  this._dropdownActiveColIndex = colIndex;
3633
+ this.updateStickyDropdownItems(this.getColumn(colIndex));
3608
3634
  }
3609
3635
 
3610
3636
  hideDropdown() {
@@ -3785,6 +3811,20 @@ class ColumnManager {
3785
3811
  });
3786
3812
  }
3787
3813
 
3814
+ setColumnSticky(colIndex, sticky) {
3815
+ const column = this.getColumn(colIndex);
3816
+ if (!column || column.sticky === sticky) {
3817
+ return;
3818
+ }
3819
+
3820
+ this.instance.freeze();
3821
+ this.datamanager.updateColumn(colIndex, { sticky });
3822
+
3823
+ this.refreshHeader();
3824
+ this.rowmanager.refreshRows()
3825
+ .then(() => this.instance.unfreeze());
3826
+ }
3827
+
3788
3828
  switchColumn(oldIndex, newIndex) {
3789
3829
  this.instance.freeze();
3790
3830
  this.datamanager.switchColumn(oldIndex, newIndex)
@@ -3974,6 +4014,23 @@ class ColumnManager {
3974
4014
  toggleDropdownItem(index) {
3975
4015
  $('.dt-dropdown__list', this.instance.dropdownContainer).children[index].classList.toggle('dt-hidden');
3976
4016
  }
4017
+
4018
+ updateStickyDropdownItems(column) {
4019
+ if (!column) return;
4020
+ if (this.stickDropdownIndex === -1 || this.unstickDropdownIndex === -1) return;
4021
+
4022
+ const stickItem = this.$dropdownList.children[this.stickDropdownIndex];
4023
+ const unstickItem = this.$dropdownList.children[this.unstickDropdownIndex];
4024
+ if (!(stickItem && unstickItem)) return;
4025
+
4026
+ if (column.sticky) {
4027
+ stickItem.classList.add('dt-hidden');
4028
+ unstickItem.classList.remove('dt-hidden');
4029
+ } else {
4030
+ stickItem.classList.remove('dt-hidden');
4031
+ unstickItem.classList.add('dt-hidden');
4032
+ }
4033
+ }
3977
4034
  }
3978
4035
 
3979
4036
  class RowManager {
@@ -4841,12 +4898,26 @@ class BodyRenderer {
4841
4898
  }
4842
4899
 
4843
4900
  render() {
4844
- const rows = this.datamanager.getRowsForView();
4901
+ const rows = this.getRowsToRender();
4845
4902
  this.renderRows(rows);
4846
4903
  // setDimensions requires atleast 1 row to exist in dom
4847
4904
  this.instance.setDimensions();
4848
4905
  }
4849
4906
 
4907
+ // Keep the current tree expand/collapse state on a full re-render
4908
+ getRowsToRender() {
4909
+ const rows = this.datamanager.getRowsForView();
4910
+ let closedIndent = null;
4911
+ return rows.filter(row => {
4912
+ const { indent, isTreeNodeClose } = row.meta;
4913
+ if (closedIndent !== null && indent > closedIndent) {
4914
+ return false;
4915
+ }
4916
+ closedIndent = isTreeNodeClose ? indent : null;
4917
+ return true;
4918
+ });
4919
+ }
4920
+
4850
4921
  renderFooter() {
4851
4922
  if (!this.options.showTotalRow) return;
4852
4923
 
@@ -4976,6 +5047,7 @@ class Style {
4976
5047
 
4977
5048
  bindScrollHeader() {
4978
5049
  this._settingHeaderPosition = false;
5050
+ this.updateStickyTopPositions(0);
4979
5051
 
4980
5052
  $.on(this.bodyScrollable, 'scroll', (e) => {
4981
5053
  if (this._settingHeaderPosition) return;
@@ -4983,7 +5055,8 @@ class Style {
4983
5055
  this._settingHeaderPosition = true;
4984
5056
 
4985
5057
  requestAnimationFrame(() => {
4986
- const left = -e.target.scrollLeft;
5058
+ const scrollLeft = e.target.scrollLeft;
5059
+ const left = -scrollLeft;
4987
5060
 
4988
5061
  $.style(this.header, {
4989
5062
  transform: `translateX(${left}px)`
@@ -4991,6 +5064,7 @@ class Style {
4991
5064
  $.style(this.footer, {
4992
5065
  transform: `translateX(${left}px)`
4993
5066
  });
5067
+ this.updateStickyTopPositions(scrollLeft);
4994
5068
  this._settingHeaderPosition = false;
4995
5069
  if (this.instance.noData) {
4996
5070
  $.style($('.no-data-message'), {
@@ -5088,6 +5162,8 @@ class Style {
5088
5162
  this.setupColumnWidth();
5089
5163
  this.distributeRemainingWidth();
5090
5164
  this.setColumnStyle();
5165
+ this.setStickyColumnStyle();
5166
+ this.updateStickyTopPositions(this.bodyScrollable.scrollLeft || 0);
5091
5167
  this.setBodyStyle();
5092
5168
  }
5093
5169
 
@@ -5245,6 +5321,8 @@ class Style {
5245
5321
  this.columnmanager.setColumnHeaderWidth(column.colIndex);
5246
5322
  this.columnmanager.setColumnWidth(column.colIndex);
5247
5323
  });
5324
+ this.setStickyColumnStyle();
5325
+ this.updateStickyTopPositions(this.bodyScrollable.scrollLeft || 0);
5248
5326
  }
5249
5327
 
5250
5328
  setBodyStyle() {
@@ -5306,6 +5384,56 @@ class Style {
5306
5384
  return $(`.dt-cell--col-${colIndex}`, this.header);
5307
5385
  }
5308
5386
 
5387
+ setStickyColumnStyle() {
5388
+ if (!this.datamanager || !this.datamanager.getColumns) return;
5389
+
5390
+ const stickySelectors = [];
5391
+ let stickyOffset = 0;
5392
+ let normalOffset = 0;
5393
+
5394
+ this.datamanager.getColumns().forEach((column) => {
5395
+ const $headerCell = this.getColumnHeaderElement(column.colIndex);
5396
+ const renderedWidth = $headerCell ? $headerCell.offsetWidth : column.width;
5397
+
5398
+ if (column.sticky) {
5399
+ const selector = `.dt-cell--col-${column.colIndex}.dt-cell--sticky`;
5400
+ const style = {
5401
+ left: `${stickyOffset}px`
5402
+ };
5403
+
5404
+ column.stickyLeft = stickyOffset;
5405
+ column.stickyScrollTrigger = normalOffset - stickyOffset;
5406
+ column.renderedWidth = renderedWidth;
5407
+ this.setStyle(selector, style);
5408
+ stickySelectors.push(selector);
5409
+ stickyOffset += renderedWidth;
5410
+ }
5411
+ normalOffset += renderedWidth;
5412
+ });
5413
+
5414
+ const staleSelectors = (this._stickySelectors || [])
5415
+ .filter(selector => !stickySelectors.includes(selector));
5416
+
5417
+ staleSelectors.forEach(selector => this.removeStyle(selector));
5418
+ this._stickySelectors = stickySelectors;
5419
+ }
5420
+
5421
+ updateStickyTopPositions(scrollLeft) {
5422
+ if (!this.datamanager || !this.datamanager.getColumns) return;
5423
+
5424
+ const stickyColumns = this.datamanager.getColumns().filter(column => column.sticky);
5425
+
5426
+ stickyColumns.forEach((column) => {
5427
+ const trigger = Math.max(0, column.stickyScrollTrigger || 0);
5428
+ const compensation = Math.max(0, scrollLeft - trigger);
5429
+ const cells = $.each(`.dt-cell--col-${column.colIndex}.dt-cell--sticky-top`, this.wrapper) || [];
5430
+
5431
+ $.style(cells, {
5432
+ transform: compensation ? `translateX(${compensation}px)` : ''
5433
+ });
5434
+ });
5435
+ }
5436
+
5309
5437
  getRowIndexColumnWidth() {
5310
5438
  const rowCount = this.datamanager.getRowCount();
5311
5439
  const padding = 22;
@@ -5369,7 +5497,11 @@ class Keyboard {
5369
5497
  }
5370
5498
  }
5371
5499
 
5500
+ var Freeze = "Freeze";
5501
+ var Unfreeze = "Unfreeze";
5372
5502
  var en = {
5503
+ Freeze: Freeze,
5504
+ Unfreeze: Unfreeze,
5373
5505
  "Sort Ascending": "Sort Ascending",
5374
5506
  "Sort Descending": "Sort Descending",
5375
5507
  "Reset sorting": "Reset sorting",
@@ -5379,7 +5511,11 @@ var en = {
5379
5511
  "{count} rows selected": {"1":"{count} row selected","default":"{count} rows selected"}
5380
5512
  };
5381
5513
 
5514
+ var Freeze$1 = "Bevriezen";
5515
+ var Unfreeze$1 = "Ontdooien";
5382
5516
  var de = {
5517
+ Freeze: Freeze$1,
5518
+ Unfreeze: Unfreeze$1,
5383
5519
  "Sort Ascending": "Aufsteigend sortieren",
5384
5520
  "Sort Descending": "Absteigend sortieren",
5385
5521
  "Reset sorting": "Sortierung zurücksetzen",
@@ -5389,7 +5525,11 @@ var de = {
5389
5525
  "{count} rows selected": {"1":"{count} Zeile ausgewählt","default":"{count} Zeilen ausgewählt"}
5390
5526
  };
5391
5527
 
5528
+ var Freeze$2 = "Geler";
5529
+ var Unfreeze$2 = "Dégeler";
5392
5530
  var fr = {
5531
+ Freeze: Freeze$2,
5532
+ Unfreeze: Unfreeze$2,
5393
5533
  "Sort Ascending": "Trier par ordre croissant",
5394
5534
  "Sort Descending": "Trier par ordre décroissant",
5395
5535
  "Reset sorting": "Réinitialiser le tri",
@@ -5399,7 +5539,11 @@ var fr = {
5399
5539
  "{count} rows selected": {"1":"{count} ligne sélectionnée","default":"{count} lignes sélectionnées"}
5400
5540
  };
5401
5541
 
5542
+ var Freeze$3 = "Congelare";
5543
+ var Unfreeze$3 = "Dégeler";
5402
5544
  var it = {
5545
+ Freeze: Freeze$3,
5546
+ Unfreeze: Unfreeze$3,
5403
5547
  "Sort Ascending": "Ordinamento ascendente",
5404
5548
  "Sort Descending": "Ordinamento decrescente",
5405
5549
  "Reset sorting": "Azzeramento ordinamento",
@@ -5681,6 +5825,22 @@ function getDefaultOptions(instance) {
5681
5825
  action: function (column) {
5682
5826
  this.removeColumn(column.colIndex);
5683
5827
  }
5828
+ },
5829
+ {
5830
+ label: instance.translate('Freeze'),
5831
+ stickyAction: 'stick',
5832
+ display: 'hidden',
5833
+ action: function (column) {
5834
+ this.setColumnSticky(column.colIndex, true);
5835
+ }
5836
+ },
5837
+ {
5838
+ label: instance.translate('Unfreeze'),
5839
+ stickyAction: 'unstick',
5840
+ display: 'hidden',
5841
+ action: function (column) {
5842
+ this.setColumnSticky(column.colIndex, false);
5843
+ }
5684
5844
  }
5685
5845
  ],
5686
5846
  events: {
@@ -5705,6 +5865,7 @@ function getDefaultOptions(instance) {
5705
5865
  freezeMessage: '',
5706
5866
  getEditor: null,
5707
5867
  serialNoColumn: true,
5868
+ serialNoColumnLabel: '',
5708
5869
  checkboxColumn: false,
5709
5870
  clusterize: true,
5710
5871
  logs: false,
@@ -5936,6 +6097,10 @@ class DataTable {
5936
6097
  this.columnmanager.removeColumn(colIndex);
5937
6098
  }
5938
6099
 
6100
+ setColumnSticky(colIndex, sticky) {
6101
+ this.columnmanager.setColumnSticky(colIndex, sticky);
6102
+ }
6103
+
5939
6104
  scrollToLastColumn() {
5940
6105
  this.datatableWrapper.scrollLeft = 9999;
5941
6106
  }
@@ -6015,7 +6180,7 @@ var unpkg = "dist/melondtable.min.js";
6015
6180
  var jsdelivr = "dist/melondtable.min.js";
6016
6181
  var scripts = {"start":"yarn run dev","build":"rollup -c && NODE_ENV=production rollup -c","dev":"rollup -c -w","cy:server":"http-server -p 8989","cy:open":"cypress open","cy:run":"cypress run","test":"start-server-and-test cy:server http://localhost:8989 cy:run","test-local":"start-server-and-test cy:server http://localhost:8989 cy:open","travis-deploy-once":"travis-deploy-once","semantic-release":"semantic-release","lint":"eslint src","lint-and-build":"yarn lint && yarn build","commit":"npx git-cz"};
6017
6182
  var files = ["dist","src"];
6018
- var devDependencies = {"autoprefixer":"^9.0.0","chai":"3.5.0","cypress":"^9.2.0","cz-conventional-changelog":"^2.1.0","deepmerge":"^2.0.1","eslint":"^5.0.1","eslint-config-airbnb":"^16.1.0","eslint-config-airbnb-base":"^12.1.0","eslint-plugin-import":"^2.11.0","http-server":"^0.11.1","mocha":"3.3.0","postcss-custom-properties":"^7.0.0","postcss-nested":"^3.0.0","rollup":"^0.59.4","rollup-plugin-commonjs":"^8.3.0","rollup-plugin-eslint":"^4.0.0","rollup-plugin-json":"^2.3.0","rollup-plugin-node-resolve":"^3.0.3","rollup-plugin-postcss":"^1.2.8","rollup-plugin-uglify-es":"^0.0.1","semantic-release":"^17.1.1","start-server-and-test":"^1.4.1","travis-deploy-once":"^5.0.1"};
6183
+ var devDependencies = {"autoprefixer":"^9.0.0","chai":"3.5.0","cypress":"^9.2.0","cz-conventional-changelog":"^2.1.0","deepmerge":"^2.0.1","eslint":"^5.0.1","eslint-config-airbnb":"^16.1.0","eslint-config-airbnb-base":"^12.1.0","eslint-plugin-import":"^2.11.0","http-server":"^0.11.1","mocha":"3.3.0","postcss-custom-properties":"^7.0.0","postcss-nested":"^3.0.0","rollup":"^0.59.4","rollup-plugin-commonjs":"^8.3.0","rollup-plugin-eslint":"^4.0.0","rollup-plugin-json":"^2.3.0","rollup-plugin-node-resolve":"^3.0.3","rollup-plugin-postcss":"^1.2.8","rollup-plugin-uglify-es":"^0.0.1","semantic-release":"^25.0.3","start-server-and-test":"^1.4.1","travis-deploy-once":"^5.0.1"};
6019
6184
  var repository = {"type":"git","url":"https://github.com/amonak/melondtable.git"};
6020
6185
  var keywords = ["datatable","data","grid","table"];
6021
6186
  var author = "Alphamonak Solutions";
@@ -19,6 +19,7 @@
19
19
  --dt-header-cell-bg: #fff;
20
20
  --dt-header-cell-bg: var(--dt-cell-bg);
21
21
  --dt-no-data-message-width: 90px;
22
+ --dt-scroll-left: 0px;
22
23
  }
23
24
 
24
25
  .datatable *, .datatable *::after, .datatable *::before {
@@ -79,7 +80,7 @@
79
80
  display: none;
80
81
  }
81
82
 
82
- .dt-row:last-child:not(.dt-row-filter) {
83
+ .dt-row:last-child:not(.dt-row-filter) .dt-cell {
83
84
  border-bottom: 1px solid #d1d8dd;
84
85
  border-bottom: 1px solid var(--dt-border-color);
85
86
  }
@@ -88,7 +89,7 @@
88
89
  border: 1px solid #d1d8dd;
89
90
  border: 1px solid var(--dt-border-color);
90
91
  border-bottom: none;
91
- border-right: none;
92
+ border-left: none;
92
93
  position: relative;
93
94
  outline: none;
94
95
  padding: 0;
@@ -106,8 +107,14 @@
106
107
  -moz-user-select: none;
107
108
  -ms-user-select: none;
108
109
  user-select: none;
110
+
109
111
  }
110
112
 
113
+ .dt-cell:first-child {
114
+ border-left: 1px solid #d1d8dd;
115
+ border-left: 1px solid var(--dt-border-color);
116
+ }
117
+
111
118
  .dt-cell__content {
112
119
  padding: 0.5rem;
113
120
  padding: var(--dt-spacer-2);
@@ -198,6 +205,29 @@
198
205
  border-right: 1px solid var(--dt-border-color);
199
206
  }
200
207
 
208
+ .dt-cell--sticky {
209
+ position: -webkit-sticky;
210
+ position: sticky;
211
+ left: 0;
212
+ z-index: 1;
213
+ }
214
+
215
+ .dt-cell--sticky-top {
216
+ z-index: 4;
217
+ will-change: transform;
218
+ }
219
+
220
+ .dt-cell--sticky-last::after {
221
+ content: '';
222
+ position: absolute;
223
+ top: 0;
224
+ right: -1px;
225
+ width: 8px;
226
+ height: 100%;
227
+ pointer-events: none;
228
+ box-shadow: 4px 0 6px -4px rgba(15, 23, 42, 0.2);
229
+ }
230
+
201
231
  .datatable[dir=rtl] .dt-cell__resize-handle {
202
232
  right: unset;
203
233
  left: -3px;
@@ -235,7 +265,7 @@
235
265
  .dt-dropdown__list {
236
266
  position: fixed;
237
267
  min-width: 8rem;
238
- z-index: 1;
268
+ z-index: 10;
239
269
  cursor: pointer;
240
270
  background-color: #fff;
241
271
  background-color: var(--dt-cell-bg);
@@ -279,6 +309,7 @@
279
309
  left: 50%;
280
310
  -webkit-transform: translateX(-50%);
281
311
  transform: translateX(-50%);
312
+ z-index: 5;
282
313
  }
283
314
 
284
315
  .dt-toast__message {