@vaadin/grid 25.0.0-alpha2 → 25.0.0-alpha21
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/all-imports.js +1 -1
- package/package.json +12 -13
- package/src/array-data-provider.js +9 -2
- package/src/lit/column-renderer-directives.d.ts +0 -1
- package/src/styles/vaadin-grid-base-styles.d.ts +8 -0
- package/src/styles/vaadin-grid-base-styles.js +677 -0
- package/src/styles/vaadin-grid-filter-base-styles.d.ts +8 -0
- package/src/styles/vaadin-grid-filter-base-styles.js +18 -0
- package/src/styles/vaadin-grid-sorter-base-styles.d.ts +8 -0
- package/src/styles/vaadin-grid-sorter-base-styles.js +76 -0
- package/src/styles/vaadin-grid-tree-toggle-base-styles.d.ts +8 -0
- package/src/styles/vaadin-grid-tree-toggle-base-styles.js +76 -0
- package/src/vaadin-grid-a11y-mixin.js +26 -10
- package/src/vaadin-grid-column-auto-width-mixin.js +9 -6
- package/src/vaadin-grid-column-mixin.d.ts +1 -0
- package/src/vaadin-grid-column-mixin.js +1 -16
- package/src/vaadin-grid-column-reordering-mixin.js +2 -2
- package/src/vaadin-grid-data-provider-mixin.js +33 -85
- package/src/vaadin-grid-drag-and-drop-mixin.js +3 -0
- package/src/vaadin-grid-event-context-mixin.d.ts +2 -0
- package/src/vaadin-grid-event-context-mixin.js +1 -0
- package/src/vaadin-grid-filter-element-mixin.js +0 -17
- package/src/vaadin-grid-filter.js +7 -1
- package/src/vaadin-grid-helpers.js +9 -0
- package/src/vaadin-grid-keyboard-navigation-mixin.js +2 -6
- package/src/vaadin-grid-mixin.d.ts +1 -0
- package/src/vaadin-grid-mixin.js +64 -32
- package/src/vaadin-grid-row-details-mixin.js +5 -5
- package/src/vaadin-grid-scroll-mixin.js +57 -77
- package/src/vaadin-grid-selection-column-base-mixin.d.ts +1 -1
- package/src/vaadin-grid-selection-column-base-mixin.js +1 -1
- package/src/vaadin-grid-selection-column.d.ts +2 -0
- package/src/vaadin-grid-selection-column.js +2 -1
- package/src/vaadin-grid-sort-column.d.ts +2 -0
- package/src/vaadin-grid-sorter-mixin.js +0 -60
- package/src/vaadin-grid-sorter.d.ts +3 -3
- package/src/vaadin-grid-sorter.js +10 -4
- package/src/vaadin-grid-tree-column-mixin.js +2 -7
- package/src/vaadin-grid-tree-toggle-mixin.js +0 -77
- package/src/vaadin-grid-tree-toggle.d.ts +4 -4
- package/src/vaadin-grid-tree-toggle.js +13 -5
- package/src/vaadin-grid.d.ts +2 -1
- package/src/vaadin-grid.js +6 -3
- package/vaadin-grid-column-group.js +1 -1
- package/vaadin-grid-column.js +1 -1
- package/vaadin-grid-filter-column.js +1 -1
- package/vaadin-grid-filter.js +1 -1
- package/vaadin-grid-selection-column.js +1 -1
- package/vaadin-grid-sort-column.js +1 -1
- package/vaadin-grid-sorter.js +1 -1
- package/vaadin-grid-tree-column.js +1 -1
- package/vaadin-grid-tree-toggle.js +1 -1
- package/vaadin-grid.js +1 -1
- package/web-types.json +13 -13
- package/web-types.lit.json +12 -12
- package/src/vaadin-grid-styles.js +0 -389
- package/theme/lumo/all-imports.d.ts +0 -11
- package/theme/lumo/all-imports.js +0 -11
- package/theme/lumo/vaadin-grid-column-group.d.ts +0 -1
- package/theme/lumo/vaadin-grid-column-group.js +0 -1
- package/theme/lumo/vaadin-grid-column.d.ts +0 -1
- package/theme/lumo/vaadin-grid-column.js +0 -1
- package/theme/lumo/vaadin-grid-filter-column.d.ts +0 -2
- package/theme/lumo/vaadin-grid-filter-column.js +0 -2
- package/theme/lumo/vaadin-grid-filter.d.ts +0 -2
- package/theme/lumo/vaadin-grid-filter.js +0 -2
- package/theme/lumo/vaadin-grid-selection-column.d.ts +0 -2
- package/theme/lumo/vaadin-grid-selection-column.js +0 -2
- package/theme/lumo/vaadin-grid-sort-column.d.ts +0 -2
- package/theme/lumo/vaadin-grid-sort-column.js +0 -2
- package/theme/lumo/vaadin-grid-sorter-styles.d.ts +0 -3
- package/theme/lumo/vaadin-grid-sorter-styles.js +0 -52
- package/theme/lumo/vaadin-grid-sorter.d.ts +0 -2
- package/theme/lumo/vaadin-grid-sorter.js +0 -2
- package/theme/lumo/vaadin-grid-styles.d.ts +0 -6
- package/theme/lumo/vaadin-grid-styles.js +0 -405
- package/theme/lumo/vaadin-grid-tree-column.d.ts +0 -2
- package/theme/lumo/vaadin-grid-tree-column.js +0 -2
- package/theme/lumo/vaadin-grid-tree-toggle-styles.d.ts +0 -3
- package/theme/lumo/vaadin-grid-tree-toggle-styles.js +0 -81
- package/theme/lumo/vaadin-grid-tree-toggle.d.ts +0 -2
- package/theme/lumo/vaadin-grid-tree-toggle.js +0 -2
- package/theme/lumo/vaadin-grid.d.ts +0 -2
- package/theme/lumo/vaadin-grid.js +0 -2
package/src/vaadin-grid-mixin.js
CHANGED
|
@@ -5,15 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { TabindexMixin } from '@vaadin/a11y-base/src/tabindex-mixin.js';
|
|
7
7
|
import { animationFrame, microTask } from '@vaadin/component-base/src/async.js';
|
|
8
|
-
import {
|
|
9
|
-
isAndroid,
|
|
10
|
-
isChrome,
|
|
11
|
-
isFirefox,
|
|
12
|
-
isIOS,
|
|
13
|
-
isSafari,
|
|
14
|
-
isTouch,
|
|
15
|
-
supportsAdoptingStyleSheets,
|
|
16
|
-
} from '@vaadin/component-base/src/browser-utils.js';
|
|
8
|
+
import { isAndroid, isChrome, isFirefox, isIOS, isSafari, isTouch } from '@vaadin/component-base/src/browser-utils.js';
|
|
17
9
|
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
18
10
|
import { getClosestElement } from '@vaadin/component-base/src/dom-utils.js';
|
|
19
11
|
import { SlotObserver } from '@vaadin/component-base/src/slot-observer.js';
|
|
@@ -36,6 +28,7 @@ import {
|
|
|
36
28
|
iterateRowCells,
|
|
37
29
|
updateBooleanRowStates,
|
|
38
30
|
updateCellsPart,
|
|
31
|
+
updateState,
|
|
39
32
|
} from './vaadin-grid-helpers.js';
|
|
40
33
|
import { KeyboardNavigationMixin } from './vaadin-grid-keyboard-navigation-mixin.js';
|
|
41
34
|
import { RowDetailsMixin } from './vaadin-grid-row-details-mixin.js';
|
|
@@ -263,13 +256,21 @@ export const GridMixin = (superClass) =>
|
|
|
263
256
|
scrollContainer: this.$.items,
|
|
264
257
|
scrollTarget: this.$.table,
|
|
265
258
|
reorderElements: true,
|
|
259
|
+
// Grid rows have a CSS-defined minimum height, so the virtualizer's height
|
|
260
|
+
// placeholder logic can be disabled. This helps save reflows which might
|
|
261
|
+
// otherwise be triggered by this logic because it reads the row height
|
|
262
|
+
// right after updating the rows' content.
|
|
263
|
+
__disableHeightPlaceholder: true,
|
|
266
264
|
});
|
|
267
265
|
|
|
268
|
-
new ResizeObserver(() =>
|
|
266
|
+
new ResizeObserver(() => {
|
|
269
267
|
setTimeout(() => {
|
|
270
268
|
this.__updateColumnsBodyContentHidden();
|
|
271
|
-
})
|
|
272
|
-
|
|
269
|
+
});
|
|
270
|
+
// Updating data can change the visibility of the scroll bar. Therefore,
|
|
271
|
+
// the scroll position has to be recalculated.
|
|
272
|
+
this.__updateHorizontalScrollPosition();
|
|
273
|
+
}).observe(this.$.table);
|
|
273
274
|
|
|
274
275
|
const minHeightObserver = new ResizeObserver(() =>
|
|
275
276
|
setTimeout(() => {
|
|
@@ -353,7 +354,7 @@ export const GridMixin = (superClass) =>
|
|
|
353
354
|
row.setAttribute('role', 'row');
|
|
354
355
|
row.setAttribute('tabindex', '-1');
|
|
355
356
|
if (this._columnTree) {
|
|
356
|
-
this.
|
|
357
|
+
this.__initRow(row, this._columnTree[this._columnTree.length - 1], 'body', false, true);
|
|
357
358
|
}
|
|
358
359
|
rows.push(row);
|
|
359
360
|
}
|
|
@@ -465,9 +466,9 @@ export const GridMixin = (superClass) =>
|
|
|
465
466
|
* @param {?string} section
|
|
466
467
|
* @param {boolean} isColumnRow
|
|
467
468
|
* @param {boolean} noNotify
|
|
468
|
-
* @
|
|
469
|
+
* @private
|
|
469
470
|
*/
|
|
470
|
-
|
|
471
|
+
__initRow(row, columns, section = 'body', isColumnRow = false, noNotify = false) {
|
|
471
472
|
const contentsFragment = document.createDocumentFragment();
|
|
472
473
|
|
|
473
474
|
iterateRowCells(row, (cell) => {
|
|
@@ -637,6 +638,7 @@ export const GridMixin = (superClass) =>
|
|
|
637
638
|
|
|
638
639
|
// Make sure the section has a tabbable element
|
|
639
640
|
this._resetKeyboardNavigation();
|
|
641
|
+
this._a11yUpdateGridSize(this.size, this._columnTree, this.__emptyState);
|
|
640
642
|
}
|
|
641
643
|
|
|
642
644
|
/** @private */
|
|
@@ -647,10 +649,15 @@ export const GridMixin = (superClass) =>
|
|
|
647
649
|
return;
|
|
648
650
|
}
|
|
649
651
|
|
|
652
|
+
row.index = index;
|
|
653
|
+
|
|
650
654
|
this._updateRowOrderParts(row, index);
|
|
651
655
|
|
|
652
656
|
this._a11yUpdateRowRowindex(row, index);
|
|
653
|
-
|
|
657
|
+
|
|
658
|
+
this.__ensureRowItem(row);
|
|
659
|
+
this.__ensureRowHierarchy(row);
|
|
660
|
+
this.__updateRow(row);
|
|
654
661
|
}
|
|
655
662
|
|
|
656
663
|
/** @private */
|
|
@@ -691,7 +698,7 @@ export const GridMixin = (superClass) =>
|
|
|
691
698
|
*/
|
|
692
699
|
_renderColumnTree(columnTree) {
|
|
693
700
|
iterateChildren(this.$.items, (row) => {
|
|
694
|
-
this.
|
|
701
|
+
this.__initRow(row, columnTree[columnTree.length - 1], 'body', false, true);
|
|
695
702
|
|
|
696
703
|
const model = this.__getRowModel(row);
|
|
697
704
|
this._updateRowOrderParts(row);
|
|
@@ -718,7 +725,7 @@ export const GridMixin = (superClass) =>
|
|
|
718
725
|
}
|
|
719
726
|
|
|
720
727
|
iterateChildren(this.$.header, (headerRow, index, rows) => {
|
|
721
|
-
this.
|
|
728
|
+
this.__initRow(headerRow, columnTree[index], 'header', index === columnTree.length - 1);
|
|
722
729
|
|
|
723
730
|
const cells = getBodyRowCells(headerRow);
|
|
724
731
|
updateCellsPart(cells, 'first-header-row-cell', index === 0);
|
|
@@ -726,7 +733,7 @@ export const GridMixin = (superClass) =>
|
|
|
726
733
|
});
|
|
727
734
|
|
|
728
735
|
iterateChildren(this.$.footer, (footerRow, index, rows) => {
|
|
729
|
-
this.
|
|
736
|
+
this.__initRow(footerRow, columnTree[columnTree.length - 1 - index], 'footer', index === 0);
|
|
730
737
|
|
|
731
738
|
const cells = getBodyRowCells(footerRow);
|
|
732
739
|
updateCellsPart(cells, 'first-footer-row-cell', index === 0);
|
|
@@ -734,7 +741,7 @@ export const GridMixin = (superClass) =>
|
|
|
734
741
|
});
|
|
735
742
|
|
|
736
743
|
// Sizer rows
|
|
737
|
-
this.
|
|
744
|
+
this.__initRow(this.$.sizer, columnTree[columnTree.length - 1]);
|
|
738
745
|
|
|
739
746
|
this._resizeHandler();
|
|
740
747
|
this._frozenCellsChanged();
|
|
@@ -749,10 +756,38 @@ export const GridMixin = (superClass) =>
|
|
|
749
756
|
|
|
750
757
|
/**
|
|
751
758
|
* @param {!HTMLElement} row
|
|
752
|
-
* @param {
|
|
753
|
-
* @
|
|
759
|
+
* @param {boolean} loading
|
|
760
|
+
* @private
|
|
754
761
|
*/
|
|
755
|
-
|
|
762
|
+
__updateRowLoading(row, loading) {
|
|
763
|
+
const cells = getBodyRowCells(row);
|
|
764
|
+
|
|
765
|
+
// Row state attribute
|
|
766
|
+
updateState(row, 'loading', loading);
|
|
767
|
+
|
|
768
|
+
// Cells part attribute
|
|
769
|
+
updateCellsPart(cells, 'loading-row-cell', loading);
|
|
770
|
+
|
|
771
|
+
if (loading) {
|
|
772
|
+
// Run style generators for the loading row to have custom names cleared
|
|
773
|
+
this._generateCellClassNames(row);
|
|
774
|
+
this._generateCellPartNames(row);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* @param {!HTMLElement} row
|
|
780
|
+
* @private
|
|
781
|
+
*/
|
|
782
|
+
__updateRow(row) {
|
|
783
|
+
const item = this.__getRowItem(row);
|
|
784
|
+
if (item) {
|
|
785
|
+
this.__updateRowLoading(row, false);
|
|
786
|
+
} else {
|
|
787
|
+
this.__updateRowLoading(row, true);
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
|
|
756
791
|
row._item = item;
|
|
757
792
|
const model = this.__getRowModel(row);
|
|
758
793
|
|
|
@@ -813,9 +848,10 @@ export const GridMixin = (superClass) =>
|
|
|
813
848
|
return {
|
|
814
849
|
index: row.index,
|
|
815
850
|
item: row._item,
|
|
816
|
-
level: this.
|
|
851
|
+
level: this.__getRowLevel(row),
|
|
817
852
|
expanded: this._isExpanded(row._item),
|
|
818
853
|
selected: this._isSelected(row._item),
|
|
854
|
+
hasChildren: this._hasChildren(row._item),
|
|
819
855
|
detailsOpened: !!this.rowDetailsRenderer && this._isDetailsOpened(row._item),
|
|
820
856
|
};
|
|
821
857
|
}
|
|
@@ -929,15 +965,11 @@ export const GridMixin = (superClass) =>
|
|
|
929
965
|
|
|
930
966
|
// The style is set to host instead of the scroller so that the value can be overridden by the user with "grid { min-height: 0 }"
|
|
931
967
|
// Prefer setting style in adopted style sheet to avoid the need to add a confusing inline style on the host element
|
|
932
|
-
|
|
933
|
-
if (!this.__minHeightStyleSheet && supportsAdoptingStyleSheets) {
|
|
968
|
+
if (!this.__minHeightStyleSheet) {
|
|
934
969
|
this.__minHeightStyleSheet = new CSSStyleSheet();
|
|
935
|
-
this.shadowRoot.adoptedStyleSheets
|
|
936
|
-
}
|
|
937
|
-
if (this.__minHeightStyleSheet) {
|
|
938
|
-
this.__minHeightStyleSheet.replaceSync(`:host { --_grid-min-height: ${minHeight}px; }`);
|
|
939
|
-
} else {
|
|
940
|
-
this.style.setProperty('--_grid-min-height', `${minHeight}px`);
|
|
970
|
+
this.shadowRoot.adoptedStyleSheets.push(this.__minHeightStyleSheet);
|
|
941
971
|
}
|
|
972
|
+
|
|
973
|
+
this.__minHeightStyleSheet.replaceSync(`:host { --_grid-min-height: ${minHeight}px; }`);
|
|
942
974
|
}
|
|
943
975
|
};
|
|
@@ -85,7 +85,7 @@ export const RowDetailsMixin = (superClass) =>
|
|
|
85
85
|
// Only update the rows if the column tree has already been initialized
|
|
86
86
|
iterateChildren(this.$.items, (row) => {
|
|
87
87
|
if (!row.querySelector('[part~=details-cell]')) {
|
|
88
|
-
this.
|
|
88
|
+
this.__initRow(row, this._columnTree[this._columnTree.length - 1]);
|
|
89
89
|
const isDetailsOpened = this._isDetailsOpened(row._item);
|
|
90
90
|
this._toggleDetailsCell(row, isDetailsOpened);
|
|
91
91
|
}
|
|
@@ -98,13 +98,13 @@ export const RowDetailsMixin = (superClass) =>
|
|
|
98
98
|
iterateChildren(this.$.items, (row) => {
|
|
99
99
|
// Re-renders the row to possibly close the previously opened details.
|
|
100
100
|
if (row.hasAttribute('details-opened')) {
|
|
101
|
-
this.
|
|
101
|
+
this.__updateRow(row);
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
// Re-renders the row to open the details when a row details renderer is provided.
|
|
106
106
|
if (rowDetailsRenderer && this._isDetailsOpened(row._item)) {
|
|
107
|
-
this.
|
|
107
|
+
this.__updateRow(row);
|
|
108
108
|
}
|
|
109
109
|
});
|
|
110
110
|
}
|
|
@@ -124,7 +124,7 @@ export const RowDetailsMixin = (superClass) =>
|
|
|
124
124
|
|
|
125
125
|
/**
|
|
126
126
|
* @param {!HTMLElement} row
|
|
127
|
-
* @param {
|
|
127
|
+
* @param {boolean} detailsOpened
|
|
128
128
|
* @protected
|
|
129
129
|
*/
|
|
130
130
|
_toggleDetailsCell(row, detailsOpened) {
|
|
@@ -140,7 +140,7 @@ export const RowDetailsMixin = (superClass) =>
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
// Assigns a renderer when the details cell is opened.
|
|
143
|
-
// The details cell content is rendered later in the `
|
|
143
|
+
// The details cell content is rendered later in the `__updateRow` method.
|
|
144
144
|
if (this.rowDetailsRenderer) {
|
|
145
145
|
cell._renderer = this.rowDetailsRenderer;
|
|
146
146
|
}
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { isElementHidden } from '@vaadin/a11y-base';
|
|
7
|
-
import {
|
|
7
|
+
import { microTask, timeOut } from '@vaadin/component-base/src/async.js';
|
|
8
8
|
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
9
9
|
import { getNormalizedScrollLeft } from '@vaadin/component-base/src/dir-utils.js';
|
|
10
|
+
import { OverflowController } from '@vaadin/component-base/src/overflow-controller.js';
|
|
10
11
|
import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
|
|
11
12
|
|
|
12
13
|
const timeouts = {
|
|
@@ -122,10 +123,23 @@ export const ScrollMixin = (superClass) =>
|
|
|
122
123
|
const row = composedPath[composedPath.indexOf(this.$.items) - 1];
|
|
123
124
|
|
|
124
125
|
if (row) {
|
|
125
|
-
//
|
|
126
|
-
// Don't change scroll position if the user is interacting with the mouse
|
|
126
|
+
// Don't change scroll position if the user is interacting with the mouse.
|
|
127
127
|
if (!this._isMousedown) {
|
|
128
|
-
|
|
128
|
+
// Make sure the focused element (row, cell, or focusable element inside a cell)
|
|
129
|
+
// is inside the viewport. If the whole row fits into the viewport, then scroll
|
|
130
|
+
// the row into view. This ensures that labels, helper texts and other related
|
|
131
|
+
// elements of focusable elements within cells also become visible. When the row
|
|
132
|
+
// is larger than the viewport, scroll the focus event target into the viewport.
|
|
133
|
+
// This works better when focusing elements within cells, which could otherwise
|
|
134
|
+
// still be outside the viewport when scrolling to the top or bottom of the row.
|
|
135
|
+
const tableHeight = this.$.table.clientHeight;
|
|
136
|
+
const headerHeight = this.$.header.clientHeight;
|
|
137
|
+
const footerHeight = this.$.footer.clientHeight;
|
|
138
|
+
const viewportHeight = tableHeight - headerHeight - footerHeight;
|
|
139
|
+
const isRowLargerThanViewport = row.clientHeight > viewportHeight;
|
|
140
|
+
const scrollTarget = isRowLargerThanViewport ? e.target : row;
|
|
141
|
+
|
|
142
|
+
this.__scrollIntoViewport(scrollTarget);
|
|
129
143
|
}
|
|
130
144
|
|
|
131
145
|
if (!this.$.table.contains(e.relatedTarget)) {
|
|
@@ -137,6 +151,9 @@ export const ScrollMixin = (superClass) =>
|
|
|
137
151
|
});
|
|
138
152
|
|
|
139
153
|
this.$.table.addEventListener('scroll', () => this._afterScroll());
|
|
154
|
+
|
|
155
|
+
this.__overflowController = new OverflowController(this, this.$.table);
|
|
156
|
+
this.addController(this.__overflowController);
|
|
140
157
|
}
|
|
141
158
|
|
|
142
159
|
/**
|
|
@@ -144,7 +161,6 @@ export const ScrollMixin = (superClass) =>
|
|
|
144
161
|
* @override
|
|
145
162
|
*/
|
|
146
163
|
_onResize() {
|
|
147
|
-
this._updateOverflow();
|
|
148
164
|
this.__updateHorizontalScrollPosition();
|
|
149
165
|
|
|
150
166
|
// For Firefox, manually restore last scroll position when grid becomes
|
|
@@ -171,25 +187,27 @@ export const ScrollMixin = (superClass) =>
|
|
|
171
187
|
_scrollToFlatIndex(index) {
|
|
172
188
|
index = Math.min(this._flatSize - 1, Math.max(0, index));
|
|
173
189
|
this.__virtualizer.scrollToIndex(index);
|
|
174
|
-
this.
|
|
190
|
+
const rowElement = [...this.$.items.children].find((child) => child.index === index);
|
|
191
|
+
this.__scrollIntoViewport(rowElement);
|
|
175
192
|
}
|
|
176
193
|
|
|
177
194
|
/**
|
|
178
|
-
* Makes sure the
|
|
179
|
-
*
|
|
195
|
+
* Makes sure the given element is fully inside the visible viewport,
|
|
196
|
+
* taking header/footer into account.
|
|
180
197
|
* @private
|
|
181
198
|
*/
|
|
182
|
-
__scrollIntoViewport(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
199
|
+
__scrollIntoViewport(element) {
|
|
200
|
+
if (!element) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const dstRect = element.getBoundingClientRect();
|
|
205
|
+
const footerTop = this.$.footer.getBoundingClientRect().top;
|
|
206
|
+
const headerBottom = this.$.header.getBoundingClientRect().bottom;
|
|
207
|
+
if (dstRect.bottom > footerTop) {
|
|
208
|
+
this.$.table.scrollTop += dstRect.bottom - footerTop;
|
|
209
|
+
} else if (dstRect.top < headerBottom) {
|
|
210
|
+
this.$.table.scrollTop -= headerBottom - dstRect.top;
|
|
193
211
|
}
|
|
194
212
|
}
|
|
195
213
|
|
|
@@ -217,8 +235,6 @@ export const ScrollMixin = (superClass) =>
|
|
|
217
235
|
this._hideTooltip(true);
|
|
218
236
|
}
|
|
219
237
|
|
|
220
|
-
this._updateOverflow();
|
|
221
|
-
|
|
222
238
|
this._debounceColumnContentVisibility = Debouncer.debounce(
|
|
223
239
|
this._debounceColumnContentVisibility,
|
|
224
240
|
timeOut.after(timeouts.UPDATE_CONTENT_VISIBILITY),
|
|
@@ -345,58 +361,6 @@ export const ScrollMixin = (superClass) =>
|
|
|
345
361
|
this.__updateColumnsBodyContentHidden();
|
|
346
362
|
}
|
|
347
363
|
|
|
348
|
-
/** @private */
|
|
349
|
-
_updateOverflow() {
|
|
350
|
-
this._debounceOverflow = Debouncer.debounce(this._debounceOverflow, animationFrame, () => {
|
|
351
|
-
this.__doUpdateOverflow();
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/** @private */
|
|
356
|
-
__doUpdateOverflow() {
|
|
357
|
-
// Set overflow styling attributes
|
|
358
|
-
let overflow = '';
|
|
359
|
-
const table = this.$.table;
|
|
360
|
-
if (table.scrollTop < table.scrollHeight - table.clientHeight) {
|
|
361
|
-
overflow += ' bottom';
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
if (table.scrollTop > 0) {
|
|
365
|
-
overflow += ' top';
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
const scrollLeft = getNormalizedScrollLeft(table, this.getAttribute('dir'));
|
|
369
|
-
if (scrollLeft > 0) {
|
|
370
|
-
overflow += ' start';
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
if (scrollLeft < table.scrollWidth - table.clientWidth) {
|
|
374
|
-
overflow += ' end';
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
if (this.__isRTL) {
|
|
378
|
-
overflow = overflow.replace(/start|end/giu, (matched) => {
|
|
379
|
-
return matched === 'start' ? 'end' : 'start';
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// TODO: Remove "right" and "left" values in the next major.
|
|
384
|
-
if (table.scrollLeft < table.scrollWidth - table.clientWidth) {
|
|
385
|
-
overflow += ' right';
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
if (table.scrollLeft > 0) {
|
|
389
|
-
overflow += ' left';
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
const value = overflow.trim();
|
|
393
|
-
if (value.length > 0 && this.getAttribute('overflow') !== value) {
|
|
394
|
-
this.setAttribute('overflow', value);
|
|
395
|
-
} else if (value.length === 0 && this.hasAttribute('overflow')) {
|
|
396
|
-
this.removeAttribute('overflow');
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
364
|
/** @protected */
|
|
401
365
|
_frozenCellsChanged() {
|
|
402
366
|
this._debouncerCacheElements = Debouncer.debounce(this._debouncerCacheElements, microTask, () => {
|
|
@@ -476,6 +440,7 @@ export const ScrollMixin = (superClass) =>
|
|
|
476
440
|
|
|
477
441
|
// Position frozen cells
|
|
478
442
|
const x = this.__isRTL ? normalizedScrollLeft + clientWidth - scrollWidth : scrollLeft;
|
|
443
|
+
this.__horizontalScrollPosition = x;
|
|
479
444
|
const transformFrozen = `translate(${x}px, 0)`;
|
|
480
445
|
this._frozenCells.forEach((cell) => {
|
|
481
446
|
cell.style.transform = transformFrozen;
|
|
@@ -511,10 +476,25 @@ export const ScrollMixin = (superClass) =>
|
|
|
511
476
|
}
|
|
512
477
|
});
|
|
513
478
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
this
|
|
479
|
+
const focusedRow = this.shadowRoot.querySelector("[part~='row']:focus");
|
|
480
|
+
if (focusedRow) {
|
|
481
|
+
// Update the horizontal scroll position property of the focused row
|
|
482
|
+
this.__updateRowScrollPositionProperty(focusedRow);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Synchronizes the internal `--_grid-horizontal-scroll-position` CSS property
|
|
488
|
+
* of the given row with the current horizontal scroll position of the grid.
|
|
489
|
+
* @private
|
|
490
|
+
*/
|
|
491
|
+
__updateRowScrollPositionProperty(row) {
|
|
492
|
+
if (row instanceof HTMLTableRowElement === false) {
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
const newValue = `${this.__horizontalScrollPosition}px`;
|
|
496
|
+
if (row.style.getPropertyValue('--_grid-horizontal-scroll-position') !== newValue) {
|
|
497
|
+
row.style.setProperty('--_grid-horizontal-scroll-position', newValue);
|
|
518
498
|
}
|
|
519
499
|
}
|
|
520
500
|
|
|
@@ -28,7 +28,7 @@ export declare class GridSelectionColumnBaseMixinClass<TItem> {
|
|
|
28
28
|
selectAll: boolean;
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* When true, the active gets automatically selected.
|
|
31
|
+
* When true, the active item gets automatically selected.
|
|
32
32
|
* @attr {boolean} auto-select
|
|
33
33
|
*/
|
|
34
34
|
autoSelect: boolean;
|
|
@@ -34,6 +34,8 @@ export * from './vaadin-grid-selection-column-mixin.js';
|
|
|
34
34
|
* selection for all the items at once.
|
|
35
35
|
*
|
|
36
36
|
* __The default content can also be overridden__
|
|
37
|
+
*
|
|
38
|
+
* @fires {CustomEvent} select-all-changed - Fired when the `selectAll` property changes.
|
|
37
39
|
*/
|
|
38
40
|
declare class GridSelectionColumn<TItem = GridDefaultItem> extends HTMLElement {}
|
|
39
41
|
|
|
@@ -30,8 +30,9 @@ import { GridSelectionColumnMixin } from './vaadin-grid-selection-column-mixin.j
|
|
|
30
30
|
*
|
|
31
31
|
* __The default content can also be overridden__
|
|
32
32
|
*
|
|
33
|
-
* @customElement
|
|
34
33
|
* @fires {CustomEvent} select-all-changed - Fired when the `selectAll` property changes.
|
|
34
|
+
*
|
|
35
|
+
* @customElement
|
|
35
36
|
* @extends GridColumn
|
|
36
37
|
* @mixes GridSelectionColumnMixin
|
|
37
38
|
*/
|
|
@@ -21,6 +21,8 @@ export * from './vaadin-grid-sort-column-mixin.js';
|
|
|
21
21
|
* <vaadin-grid-column>
|
|
22
22
|
* ...
|
|
23
23
|
* ```
|
|
24
|
+
*
|
|
25
|
+
* @fires {CustomEvent} direction-changed - Fired when the `direction` property changes.
|
|
24
26
|
*/
|
|
25
27
|
declare class GridSortColumn<TItem = GridDefaultItem> extends HTMLElement {}
|
|
26
28
|
|
|
@@ -3,66 +3,6 @@
|
|
|
3
3
|
* Copyright (c) 2016 - 2025 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
7
|
-
|
|
8
|
-
const template = document.createElement('template');
|
|
9
|
-
|
|
10
|
-
template.innerHTML = `
|
|
11
|
-
<style>
|
|
12
|
-
@font-face {
|
|
13
|
-
font-family: 'vaadin-grid-sorter-icons';
|
|
14
|
-
src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAQwAA0AAAAABuwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAEFAAAABkAAAAcfep+mUdERUYAAAP4AAAAHAAAAB4AJwAOT1MvMgAAAZgAAAA/AAAAYA8TBPpjbWFwAAAB7AAAAFUAAAFeF1fZ4mdhc3AAAAPwAAAACAAAAAgAAAAQZ2x5ZgAAAlgAAABcAAAAnMvguMloZWFkAAABMAAAAC8AAAA2C5Ap72hoZWEAAAFgAAAAHQAAACQGbQPHaG10eAAAAdgAAAAUAAAAHAoAAABsb2NhAAACRAAAABIAAAASAIwAYG1heHAAAAGAAAAAFgAAACAACwAKbmFtZQAAArQAAAECAAACZxWCgKhwb3N0AAADuAAAADUAAABZCrApUXicY2BkYGAA4rDECVrx/DZfGbhZGEDgyqNPOxH0/wNMq5kPALkcDEwgUQBWRA0dAHicY2BkYGA+8P8AAwMLAwgwrWZgZEAFbABY4QM8AAAAeJxjYGRgYOAAQiYGEICQSAAAAi8AFgAAeJxjYGY6yziBgZWBgWkm0xkGBoZ+CM34msGYkZMBFTAKoAkwODAwvmRiPvD/AIMDMxCD1CDJKjAwAgBktQsXAHicY2GAAMZQCM0EwqshbAALxAEKeJxjYGBgZoBgGQZGBhCIAPIYwXwWBhsgzcXAwcAEhIwMCi+Z/v/9/x+sSuElA4T9/4k4K1gHFwMMMILMY2QDYmaoABOQYGJABUA7WBiGNwAAJd4NIQAAAAAAAAAACAAIABAAGAAmAEAATgAAeJyNjLENgDAMBP9tIURJwQCMQccSZgk2i5fIYBDAidJjycXr7x5EPwE2wY8si7jmyBNXGo/bNBerxJNrpxhbO3/fEFpx8ZICpV+ghxJ74fAMe+h7Ox14AbrsHB14nK2QQWrDMBRER4mTkhQK3ZRQKOgCNk7oGQqhhEIX2WSlWEI1BAlkJ5CDdNsj5Ey9Rncdi38ES+jzNJo/HwTgATcoDEthhY3wBHc4CE+pfwsX5F/hGe7Vo/AcK/UhvMSz+mGXKhZU6pww8ISz3oWn1BvhgnwTnuEJf8Jz1OpFeIlX9YULDLdFi4ASHolkSR0iuYdjLak1vAequBhj21D61Nqyi6l3qWybGPjySbPHGScGJl6dP58MYcQRI0bts7mjebBqrFENH7t3qWtj0OuqHnXcW7b0HOTZFnKryRGW2hFX1m0O2vEM3opNMfTau+CS6Z3Vx6veNnEXY6jwDxhsc2gAAHicY2BiwA84GBgYmRiYGJkZmBlZGFkZ2djScyoLMgzZS/MyDQwMwLSrpYEBlIbxjQDrzgsuAAAAAAEAAf//AA94nGNgZGBg4AFiMSBmYmAEQnYgZgHzGAAD6wA2eJxjYGBgZACCKyoz1cD0o087YTQATOcIewAAAA==) format('woff');
|
|
15
|
-
font-weight: normal;
|
|
16
|
-
font-style: normal;
|
|
17
|
-
}
|
|
18
|
-
</style>
|
|
19
|
-
`;
|
|
20
|
-
|
|
21
|
-
document.head.appendChild(template.content);
|
|
22
|
-
|
|
23
|
-
registerStyles(
|
|
24
|
-
'vaadin-grid-sorter',
|
|
25
|
-
css`
|
|
26
|
-
:host {
|
|
27
|
-
display: inline-flex;
|
|
28
|
-
cursor: pointer;
|
|
29
|
-
max-width: 100%;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
[part='content'] {
|
|
33
|
-
flex: 1 1 auto;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
[part='indicators'] {
|
|
37
|
-
position: relative;
|
|
38
|
-
align-self: center;
|
|
39
|
-
flex: none;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
[part='order'] {
|
|
43
|
-
display: inline;
|
|
44
|
-
vertical-align: super;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
[part='indicators']::before {
|
|
48
|
-
font-family: 'vaadin-grid-sorter-icons';
|
|
49
|
-
display: inline-block;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
:host(:not([direction])) [part='indicators']::before {
|
|
53
|
-
content: '\\e901';
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
:host([direction='asc']) [part='indicators']::before {
|
|
57
|
-
content: '\\e900';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
:host([direction='desc']) [part='indicators']::before {
|
|
61
|
-
content: '\\e902';
|
|
62
|
-
}
|
|
63
|
-
`,
|
|
64
|
-
{ moduleId: 'vaadin-grid-sorter-styles' },
|
|
65
|
-
);
|
|
66
6
|
|
|
67
7
|
/**
|
|
68
8
|
* A mixin providing common sorter functionality.
|
|
@@ -41,9 +41,9 @@ export * from './vaadin-grid-sorter-mixin.js';
|
|
|
41
41
|
*
|
|
42
42
|
* The following state attributes are available for styling:
|
|
43
43
|
*
|
|
44
|
-
* Attribute | Description
|
|
45
|
-
*
|
|
46
|
-
* `direction`
|
|
44
|
+
* Attribute | Description
|
|
45
|
+
* -------------|---------------------------
|
|
46
|
+
* `direction` | Sort direction of a sorter
|
|
47
47
|
*
|
|
48
48
|
* @fires {CustomEvent} direction-changed - Fired when the `direction` property changes.
|
|
49
49
|
* @fires {CustomEvent} sorter-changed - Fired when the `path` or `direction` property changes.
|
|
@@ -8,6 +8,8 @@ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
|
8
8
|
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
9
9
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
10
10
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin';
|
|
11
|
+
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
|
|
12
|
+
import { gridSorterStyles } from './styles/vaadin-grid-sorter-base-styles.js';
|
|
11
13
|
import { GridSorterMixin } from './vaadin-grid-sorter-mixin.js';
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -42,9 +44,9 @@ import { GridSorterMixin } from './vaadin-grid-sorter-mixin.js';
|
|
|
42
44
|
*
|
|
43
45
|
* The following state attributes are available for styling:
|
|
44
46
|
*
|
|
45
|
-
* Attribute | Description
|
|
46
|
-
*
|
|
47
|
-
* `direction`
|
|
47
|
+
* Attribute | Description
|
|
48
|
+
* -------------|---------------------------
|
|
49
|
+
* `direction` | Sort direction of a sorter
|
|
48
50
|
*
|
|
49
51
|
* @fires {CustomEvent} direction-changed - Fired when the `direction` property changes.
|
|
50
52
|
* @fires {CustomEvent} sorter-changed - Fired when the `path` or `direction` property changes.
|
|
@@ -55,11 +57,15 @@ import { GridSorterMixin } from './vaadin-grid-sorter-mixin.js';
|
|
|
55
57
|
* @mixes ThemableMixin
|
|
56
58
|
* @mixes DirMixin
|
|
57
59
|
*/
|
|
58
|
-
class GridSorter extends GridSorterMixin(ThemableMixin(DirMixin(PolylitMixin(LitElement)))) {
|
|
60
|
+
class GridSorter extends GridSorterMixin(ThemableMixin(DirMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
|
|
59
61
|
static get is() {
|
|
60
62
|
return 'vaadin-grid-sorter';
|
|
61
63
|
}
|
|
62
64
|
|
|
65
|
+
static get styles() {
|
|
66
|
+
return gridSorterStyles;
|
|
67
|
+
}
|
|
68
|
+
|
|
63
69
|
/** @protected */
|
|
64
70
|
render() {
|
|
65
71
|
return html`
|
|
@@ -37,7 +37,7 @@ export const GridTreeColumnMixin = (superClass) =>
|
|
|
37
37
|
*
|
|
38
38
|
* @private
|
|
39
39
|
*/
|
|
40
|
-
__defaultRenderer(root, _column, { item, expanded, level }) {
|
|
40
|
+
__defaultRenderer(root, _column, { item, expanded, level, hasChildren }) {
|
|
41
41
|
let toggle = root.firstElementChild;
|
|
42
42
|
if (!toggle) {
|
|
43
43
|
toggle = document.createElement('vaadin-grid-tree-toggle');
|
|
@@ -48,7 +48,7 @@ export const GridTreeColumnMixin = (superClass) =>
|
|
|
48
48
|
toggle.__item = item;
|
|
49
49
|
toggle.__rendererExpanded = expanded;
|
|
50
50
|
toggle.expanded = expanded;
|
|
51
|
-
toggle.leaf =
|
|
51
|
+
toggle.leaf = !hasChildren;
|
|
52
52
|
toggle.textContent = this.__getToggleContent(this.path, item);
|
|
53
53
|
toggle.level = level;
|
|
54
54
|
}
|
|
@@ -83,11 +83,6 @@ export const GridTreeColumnMixin = (superClass) =>
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
/** @private */
|
|
87
|
-
__isLeafItem(item, itemHasChildrenPath) {
|
|
88
|
-
return !item || !item[itemHasChildrenPath];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
86
|
/** @private */
|
|
92
87
|
__getToggleContent(path, item) {
|
|
93
88
|
return path && get(path, item);
|