@vaadin/vaadin-grid 5.9.0 → 5.9.1

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/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "repository": "vaadin/vaadin-grid",
16
16
  "homepage": "https://vaadin.com/components",
17
17
  "name": "@vaadin/vaadin-grid",
18
- "version": "5.9.0",
18
+ "version": "5.9.1",
19
19
  "main": "vaadin-grid.js",
20
20
  "author": "Vaadin Ltd",
21
21
  "license": "Apache-2.0",
@@ -319,7 +319,15 @@ export const ColumnBaseMixin = superClass => class ColumnBaseMixin extends super
319
319
  }
320
320
 
321
321
  cells.forEach(cell => {
322
- const model = this._grid.__getRowModel(cell.parentElement);
322
+ const parent = cell.parentElement;
323
+
324
+ // When a column is made hidden and shown again, in some instances it breaks rendering of rows for grid
325
+ // this happens when parent element of cell is null, which might not be set correctly during rendering
326
+ // the newly shown column, this check simply avoid that case
327
+ if (!parent) {
328
+ return;
329
+ }
330
+ const model = this._grid.__getRowModel(parent);
323
331
 
324
332
  if (renderer) {
325
333
  cell._renderer = renderer;
@@ -87,7 +87,7 @@ export const DragAndDropMixin = superClass => class DragAndDropMixin extends sup
87
87
 
88
88
  static get observers() {
89
89
  return [
90
- '_dragDropAccessChanged(rowsDraggable, dropMode, dragFilter, dropFilter)'
90
+ '_dragDropAccessChanged(rowsDraggable, dropMode, dragFilter, dropFilter, loading)'
91
91
  ];
92
92
  }
93
93
 
@@ -297,13 +297,17 @@ export const DragAndDropMixin = superClass => class DragAndDropMixin extends sup
297
297
 
298
298
  /** @private */
299
299
  __getViewportRows() {
300
- const headerBottom = this.$.header.getBoundingClientRect().bottom;
301
- const footerTop = this.$.footer.getBoundingClientRect().top;
302
- return Array.from(this.$.items.children)
303
- .filter(row => {
304
- const rowRect = row.getBoundingClientRect();
305
- return rowRect.bottom > headerBottom && rowRect.top < footerTop;
306
- });
300
+ // Workaround an IE11 bug where the `getBoundingClientRect` for header/footer
301
+ // might return incorrect values
302
+ this.$.header.style.outline = '0px solid transparent';
303
+ const scrollerRect = this.$.scroller.getBoundingClientRect();
304
+ const headerBottom = Math.max(this.$.header.getBoundingClientRect().bottom, scrollerRect.top);
305
+ const footerTop = Math.min(this.$.footer.getBoundingClientRect().top, scrollerRect.bottom);
306
+
307
+ return Array.from(this.$.items.children).filter((row) => {
308
+ const rowRect = row.getBoundingClientRect();
309
+ return rowRect.bottom > headerBottom && rowRect.top < footerTop;
310
+ });
307
311
  }
308
312
 
309
313
  /** @protected */
@@ -382,8 +386,9 @@ export const DragAndDropMixin = superClass => class DragAndDropMixin extends sup
382
386
  * @protected
383
387
  */
384
388
  _filterDragAndDrop(row, model) {
385
- const dragDisabled = !this.rowsDraggable || (this.dragFilter && !this.dragFilter(model));
386
- const dropDisabled = !this.dropMode || (this.dropFilter && !this.dropFilter(model));
389
+ const loading = this.loading || row.hasAttribute('loading');
390
+ const dragDisabled = !this.rowsDraggable || loading || (this.dragFilter && !this.dragFilter(model));
391
+ const dropDisabled = !this.dropMode || loading || (this.dropFilter && !this.dropFilter(model));
387
392
 
388
393
  const draggableElements = window.ShadyDOM
389
394
  ? [row]
@@ -79,7 +79,13 @@ class GridScrollerElement extends PolymerIronList {
79
79
  this._scrollingToIndex = true;
80
80
  index = Math.min(Math.max(index, 0), this._effectiveSize - 1);
81
81
  this.$.table.scrollTop = index / this._effectiveSize * (this.$.table.scrollHeight - this.$.table.offsetHeight);
82
+
83
+ // We need to run the iron-list scroll handler here in order to recalculate the scaling from effective size to
84
+ // virtual size after changing the scroll position. However we don't want to trigger updates to the items / rows
85
+ // in this step, which could result in data provider requests for the previous viewport
86
+ this._preventItemUpdates = true;
82
87
  this._scrollHandler();
88
+ this._preventItemUpdates = false;
83
89
 
84
90
  if (this._accessIronListAPI(() => this._maxScrollTop) && this._virtualCount < this._effectiveSize) {
85
91
  this._adjustVirtualIndexOffset(1000000);
@@ -256,6 +262,10 @@ class GridScrollerElement extends PolymerIronList {
256
262
  * @protected
257
263
  */
258
264
  _assignModels(itemSet) {
265
+ // Skip here if internal flag for preventing item updates is set
266
+ if (this._preventItemUpdates) {
267
+ return;
268
+ }
259
269
  this._iterateItems((pidx, vidx) => {
260
270
  const el = this._physicalItems[pidx];
261
271
  this._toggleAttribute('hidden', vidx >= this._effectiveSize, el);
@@ -322,7 +322,7 @@ class GridElement extends
322
322
  }
323
323
 
324
324
  static get version() {
325
- return '5.9.0';
325
+ return '5.9.1';
326
326
  }
327
327
 
328
328
  static get observers() {
@@ -461,37 +461,70 @@ class GridElement extends
461
461
  }
462
462
  }
463
463
 
464
+ /** @private */
465
+ __getIntrinsicWidth(col) {
466
+ const initialWidth = col.width;
467
+ const initialFlexGrow = col.flexGrow;
468
+
469
+ col.width = 'auto';
470
+ col.flexGrow = 0;
471
+
472
+ // Note: _allCells only contains cells which are currently rendered in DOM
473
+ const width = col._allCells
474
+ .reduce((width, cell) => {
475
+ // Add 1px buffer to the offset width to avoid too narrow columns (sub-pixel rendering)
476
+ return Math.max(width, cell.offsetWidth + 1);
477
+ }, 0);
478
+
479
+ col.flexGrow = initialFlexGrow;
480
+ col.width = initialWidth;
481
+
482
+ return width;
483
+ }
484
+
485
+ /** @private */
486
+ __getDistributedWidth(col, innerColumn) {
487
+ if (col == null || col === this) {
488
+ return 0;
489
+ }
490
+
491
+ const columnWidth = Math.max(this.__getIntrinsicWidth(col), this.__getDistributedWidth(col.parentElement, col));
492
+
493
+ // we're processing a regular grid-column and not a grid-column-group
494
+ if (!innerColumn) {
495
+ return columnWidth;
496
+ }
497
+
498
+ // At the end, the width of each vaadin-grid-column-group is determined by the sum of the width of its children.
499
+ // Here we determine how much space the vaadin-grid-column-group actually needs to render properly and then we distribute that space
500
+ // to its children, so when we actually do the summation it will be rendered properly.
501
+ // Check out vaadin-grid-column-group:_updateFlexAndWidth
502
+ const columnGroup = col;
503
+ const columnGroupWidth = columnWidth;
504
+ const sumOfWidthOfAllChildColumns = columnGroup._visibleChildColumns
505
+ .map((col) => this.__getIntrinsicWidth(col))
506
+ .reduce((sum, curr) => sum + curr, 0);
507
+
508
+ const extraNecessarySpaceForGridColumnGroup = Math.max(0, columnGroupWidth - sumOfWidthOfAllChildColumns);
509
+
510
+ // The distribution of the extra necessary space is done according to the intrinsic width of each child column.
511
+ // Lets say we need 100 pixels of extra space for the grid-column-group to render properly
512
+ // it has two grid-column children, |100px|300px| in total 400px
513
+ // the first column gets 25px of the additional space (100/400)*100 = 25
514
+ // the second column gets the 75px of the additional space (300/400)*100 = 75
515
+ const proportionOfExtraSpace = this.__getIntrinsicWidth(innerColumn) / sumOfWidthOfAllChildColumns;
516
+ const shareOfInnerColumnFromNecessaryExtraSpace = proportionOfExtraSpace * extraNecessarySpaceForGridColumnGroup;
517
+
518
+ return this.__getIntrinsicWidth(innerColumn) + shareOfInnerColumnFromNecessaryExtraSpace;
519
+ }
520
+
464
521
  /**
465
522
  * @param {!Array<!GridColumnElement>} cols the columns to auto size based on their content width
466
523
  * @private
467
524
  */
468
525
  _recalculateColumnWidths(cols) {
469
- // Note: The `cols.forEach()` loops below could be implemented as a single loop but this has been
470
- // split for performance reasons to batch these similar actions [write/read] together to avoid
471
- // unnecessary layout trashing.
472
-
473
- // [write] Set automatic width for all cells (breaks column alignment)
474
- cols.forEach(col => {
475
- col.width = 'auto';
476
- col._origFlexGrow = col.flexGrow;
477
- col.flexGrow = 0;
478
- });
479
- // [read] Measure max cell width in each column
480
- cols.forEach(col => {
481
- col._currentWidth = 0;
482
- // Note: _allCells only contains cells which are currently rendered in DOM
483
- col._allCells.forEach(c => {
484
- // Add 1px buffer to the offset width to avoid too narrow columns (sub-pixel rendering)
485
- const cellWidth = c.offsetWidth + 1;
486
- col._currentWidth = Math.max(col._currentWidth, cellWidth);
487
- });
488
- });
489
- // [write] Set column widths to fit widest measured content
490
- cols.forEach(col => {
491
- col.width = `${col._currentWidth}px`;
492
- col.flexGrow = col._origFlexGrow;
493
- col._currentWidth = undefined;
494
- col._origFlexGrow = undefined;
526
+ cols.forEach((col) => {
527
+ col.width = `${this.__getDistributedWidth(col)}px`;
495
528
  });
496
529
  }
497
530