@vaadin/grid 22.0.0-alpha7
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 +190 -0
- package/README.md +79 -0
- package/all-imports.js +1 -0
- package/package.json +58 -0
- package/src/all-imports.js +14 -0
- package/src/array-data-provider.js +145 -0
- package/src/interfaces.d.ts +75 -0
- package/src/vaadin-grid-a11y-mixin.js +158 -0
- package/src/vaadin-grid-active-item-mixin.d.ts +19 -0
- package/src/vaadin-grid-active-item-mixin.js +117 -0
- package/src/vaadin-grid-array-data-provider-mixin.d.ts +16 -0
- package/src/vaadin-grid-array-data-provider-mixin.js +75 -0
- package/src/vaadin-grid-column-group.d.ts +54 -0
- package/src/vaadin-grid-column-group.js +320 -0
- package/src/vaadin-grid-column-reordering-mixin.d.ts +19 -0
- package/src/vaadin-grid-column-reordering-mixin.js +387 -0
- package/src/vaadin-grid-column-resizing-mixin.js +111 -0
- package/src/vaadin-grid-column.d.ts +133 -0
- package/src/vaadin-grid-column.js +745 -0
- package/src/vaadin-grid-data-provider-mixin.d.ts +108 -0
- package/src/vaadin-grid-data-provider-mixin.js +520 -0
- package/src/vaadin-grid-drag-and-drop-mixin.d.ts +69 -0
- package/src/vaadin-grid-drag-and-drop-mixin.js +433 -0
- package/src/vaadin-grid-dynamic-columns-mixin.js +180 -0
- package/src/vaadin-grid-event-context-mixin.d.ts +33 -0
- package/src/vaadin-grid-event-context-mixin.js +57 -0
- package/src/vaadin-grid-filter-column.d.ts +35 -0
- package/src/vaadin-grid-filter-column.js +120 -0
- package/src/vaadin-grid-filter-mixin.js +76 -0
- package/src/vaadin-grid-filter.d.ts +67 -0
- package/src/vaadin-grid-filter.js +125 -0
- package/src/vaadin-grid-helpers.js +23 -0
- package/src/vaadin-grid-keyboard-navigation-mixin.js +891 -0
- package/src/vaadin-grid-row-details-mixin.d.ts +44 -0
- package/src/vaadin-grid-row-details-mixin.js +200 -0
- package/src/vaadin-grid-scroll-mixin.d.ts +18 -0
- package/src/vaadin-grid-scroll-mixin.js +202 -0
- package/src/vaadin-grid-selection-column.d.ts +71 -0
- package/src/vaadin-grid-selection-column.js +285 -0
- package/src/vaadin-grid-selection-mixin.d.ts +30 -0
- package/src/vaadin-grid-selection-mixin.js +93 -0
- package/src/vaadin-grid-sort-column.d.ts +63 -0
- package/src/vaadin-grid-sort-column.js +118 -0
- package/src/vaadin-grid-sort-mixin.d.ts +15 -0
- package/src/vaadin-grid-sort-mixin.js +139 -0
- package/src/vaadin-grid-sorter.d.ts +94 -0
- package/src/vaadin-grid-sorter.js +230 -0
- package/src/vaadin-grid-styles.js +297 -0
- package/src/vaadin-grid-styling-mixin.d.ts +37 -0
- package/src/vaadin-grid-styling-mixin.js +71 -0
- package/src/vaadin-grid-tree-column.d.ts +36 -0
- package/src/vaadin-grid-tree-column.js +119 -0
- package/src/vaadin-grid-tree-toggle.d.ts +104 -0
- package/src/vaadin-grid-tree-toggle.js +205 -0
- package/src/vaadin-grid.d.ts +397 -0
- package/src/vaadin-grid.js +1004 -0
- package/theme/lumo/all-imports.js +11 -0
- package/theme/lumo/vaadin-grid-column-group.js +1 -0
- package/theme/lumo/vaadin-grid-column.js +1 -0
- package/theme/lumo/vaadin-grid-filter-column.js +2 -0
- package/theme/lumo/vaadin-grid-filter.js +2 -0
- package/theme/lumo/vaadin-grid-selection-column.js +2 -0
- package/theme/lumo/vaadin-grid-sort-column.js +2 -0
- package/theme/lumo/vaadin-grid-sorter-styles.js +53 -0
- package/theme/lumo/vaadin-grid-sorter.js +2 -0
- package/theme/lumo/vaadin-grid-styles.js +378 -0
- package/theme/lumo/vaadin-grid-tree-column.js +2 -0
- package/theme/lumo/vaadin-grid-tree-toggle-styles.js +112 -0
- package/theme/lumo/vaadin-grid-tree-toggle.js +2 -0
- package/theme/lumo/vaadin-grid.js +9 -0
- package/theme/material/all-imports.js +11 -0
- package/theme/material/vaadin-grid-column-group.js +1 -0
- package/theme/material/vaadin-grid-column.js +1 -0
- package/theme/material/vaadin-grid-filter-column.js +2 -0
- package/theme/material/vaadin-grid-filter.js +2 -0
- package/theme/material/vaadin-grid-selection-column.js +2 -0
- package/theme/material/vaadin-grid-sort-column.js +2 -0
- package/theme/material/vaadin-grid-sorter-styles.js +72 -0
- package/theme/material/vaadin-grid-sorter.js +2 -0
- package/theme/material/vaadin-grid-styles.js +252 -0
- package/theme/material/vaadin-grid-tree-column.js +2 -0
- package/theme/material/vaadin-grid-tree-toggle-styles.js +42 -0
- package/theme/material/vaadin-grid-tree-toggle.js +2 -0
- package/theme/material/vaadin-grid.js +2 -0
- package/vaadin-grid-column-group.d.ts +1 -0
- package/vaadin-grid-column-group.js +3 -0
- package/vaadin-grid-column.d.ts +1 -0
- package/vaadin-grid-column.js +3 -0
- package/vaadin-grid-filter-column.d.ts +1 -0
- package/vaadin-grid-filter-column.js +3 -0
- package/vaadin-grid-filter.d.ts +1 -0
- package/vaadin-grid-filter.js +3 -0
- package/vaadin-grid-selection-column.d.ts +1 -0
- package/vaadin-grid-selection-column.js +3 -0
- package/vaadin-grid-sort-column.d.ts +1 -0
- package/vaadin-grid-sort-column.js +3 -0
- package/vaadin-grid-sorter.d.ts +1 -0
- package/vaadin-grid-sorter.js +3 -0
- package/vaadin-grid-tree-column.d.ts +1 -0
- package/vaadin-grid-tree-column.js +3 -0
- package/vaadin-grid-tree-toggle.d.ts +1 -0
- package/vaadin-grid-tree-toggle.js +3 -0
- package/vaadin-grid.d.ts +3 -0
- package/vaadin-grid.js +4 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { GridRowDetailsRenderer } from './interfaces';
|
|
2
|
+
|
|
3
|
+
declare function RowDetailsMixin<TItem, T extends new (...args: any[]) => {}>(
|
|
4
|
+
base: T
|
|
5
|
+
): T & RowDetailsMixinConstructor<TItem>;
|
|
6
|
+
|
|
7
|
+
interface RowDetailsMixinConstructor<TItem> {
|
|
8
|
+
new (...args: any[]): RowDetailsMixin<TItem>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface RowDetailsMixin<TItem> {
|
|
12
|
+
/**
|
|
13
|
+
* An array containing references to items with open row details.
|
|
14
|
+
*/
|
|
15
|
+
detailsOpenedItems: Array<TItem>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Custom function for rendering the content of the row details.
|
|
19
|
+
* Receives three arguments:
|
|
20
|
+
*
|
|
21
|
+
* - `root` The row details content DOM element. Append your content to it.
|
|
22
|
+
* - `grid` The `<vaadin-grid>` element.
|
|
23
|
+
* - `model` The object with the properties related with
|
|
24
|
+
* the rendered item, contains:
|
|
25
|
+
* - `model.index` The index of the item.
|
|
26
|
+
* - `model.item` The item.
|
|
27
|
+
* - `model.level` The number of the item's tree sublevel, starts from 0.
|
|
28
|
+
* - `model.expanded` True if the item's tree sublevel is expanded.
|
|
29
|
+
* - `model.selected` True if the item is selected.
|
|
30
|
+
*/
|
|
31
|
+
rowDetailsRenderer: GridRowDetailsRenderer<TItem> | null | undefined;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Open the details row of a given item.
|
|
35
|
+
*/
|
|
36
|
+
openItemDetails(item: TItem): void;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Close the details row of a given item.
|
|
40
|
+
*/
|
|
41
|
+
closeItemDetails(item: TItem): void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { RowDetailsMixin, RowDetailsMixinConstructor };
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @polymerMixin
|
|
9
|
+
*/
|
|
10
|
+
export const RowDetailsMixin = (superClass) =>
|
|
11
|
+
class RowDetailsMixin extends superClass {
|
|
12
|
+
static get properties() {
|
|
13
|
+
return {
|
|
14
|
+
/**
|
|
15
|
+
* An array containing references to items with open row details.
|
|
16
|
+
* @type {!Array<!GridItem>}
|
|
17
|
+
*/
|
|
18
|
+
detailsOpenedItems: {
|
|
19
|
+
type: Array,
|
|
20
|
+
value: function () {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Custom function for rendering the content of the row details.
|
|
27
|
+
* Receives three arguments:
|
|
28
|
+
*
|
|
29
|
+
* - `root` The row details content DOM element. Append your content to it.
|
|
30
|
+
* - `grid` The `<vaadin-grid>` element.
|
|
31
|
+
* - `model` The object with the properties related with
|
|
32
|
+
* the rendered item, contains:
|
|
33
|
+
* - `model.index` The index of the item.
|
|
34
|
+
* - `model.item` The item.
|
|
35
|
+
* - `model.level` The number of the item's tree sublevel, starts from 0.
|
|
36
|
+
* - `model.expanded` True if the item's tree sublevel is expanded.
|
|
37
|
+
* - `model.selected` True if the item is selected.
|
|
38
|
+
*
|
|
39
|
+
* @type {GridRowDetailsRenderer | null | undefined}
|
|
40
|
+
*/
|
|
41
|
+
rowDetailsRenderer: Function,
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @type {!Array<!HTMLElement> | undefined}
|
|
45
|
+
* @protected
|
|
46
|
+
*/
|
|
47
|
+
_detailsCells: {
|
|
48
|
+
type: Array
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static get observers() {
|
|
54
|
+
return [
|
|
55
|
+
'_detailsOpenedItemsChanged(detailsOpenedItems.*, rowDetailsRenderer)',
|
|
56
|
+
'_rowDetailsRendererChanged(rowDetailsRenderer)'
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** @protected */
|
|
61
|
+
ready() {
|
|
62
|
+
super.ready();
|
|
63
|
+
|
|
64
|
+
this._detailsCellResizeObserver = new ResizeObserver((entries) => {
|
|
65
|
+
entries.forEach(({ target: cell }) => {
|
|
66
|
+
this._updateDetailsCellHeight(cell.parentElement);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// This workaround is needed until Safari also supports
|
|
70
|
+
// ResizeObserver.observe with {box: 'border-box'}
|
|
71
|
+
this.__virtualizer.__adapter._resizeHandler();
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** @private */
|
|
76
|
+
_rowDetailsRendererChanged(rowDetailsRenderer) {
|
|
77
|
+
if (!rowDetailsRenderer) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (this._columnTree) {
|
|
82
|
+
// Only update the rows if the column tree has already been initialized
|
|
83
|
+
Array.from(this.$.items.children).forEach((row) => {
|
|
84
|
+
if (!row.querySelector('[part~=details-cell]')) {
|
|
85
|
+
this._updateRow(row, this._columnTree[this._columnTree.length - 1]);
|
|
86
|
+
this._a11yUpdateRowDetailsOpened(row, false);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** @private */
|
|
93
|
+
_detailsOpenedItemsChanged(changeRecord, rowDetailsRenderer) {
|
|
94
|
+
// Skip to avoid duplicate work of both “.splices” and “.length” updates.
|
|
95
|
+
if (changeRecord.path === 'detailsOpenedItems.length' || !changeRecord.value) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[...this.$.items.children].forEach((row) => {
|
|
100
|
+
// Re-renders the row to possibly close the previously opened details.
|
|
101
|
+
if (row.hasAttribute('details-opened')) {
|
|
102
|
+
this._updateItem(row, row._item);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Re-renders the row to open the details when a row details renderer is provided.
|
|
107
|
+
if (rowDetailsRenderer && this._isDetailsOpened(row._item)) {
|
|
108
|
+
this._updateItem(row, row._item);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {!HTMLElement} cell
|
|
116
|
+
* @protected
|
|
117
|
+
*/
|
|
118
|
+
_configureDetailsCell(cell) {
|
|
119
|
+
cell.setAttribute('part', 'cell details-cell');
|
|
120
|
+
// Freeze the details cell, so that it does not scroll horizontally
|
|
121
|
+
// with the normal cells. This way it looks less weird.
|
|
122
|
+
cell.toggleAttribute('frozen', true);
|
|
123
|
+
|
|
124
|
+
this._detailsCellResizeObserver.observe(cell);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @param {!HTMLElement} row
|
|
129
|
+
* @param {!GridItem} item
|
|
130
|
+
* @protected
|
|
131
|
+
*/
|
|
132
|
+
_toggleDetailsCell(row, detailsOpened) {
|
|
133
|
+
const cell = row.querySelector('[part~="details-cell"]');
|
|
134
|
+
if (!cell) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
cell.hidden = !detailsOpened;
|
|
139
|
+
|
|
140
|
+
if (cell.hidden) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Assigns a renderer when the details cell is opened.
|
|
145
|
+
// The details cell content is rendered later in the `_updateItem` method.
|
|
146
|
+
if (this.rowDetailsRenderer) {
|
|
147
|
+
cell._renderer = this.rowDetailsRenderer;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** @protected */
|
|
152
|
+
_updateDetailsCellHeight(row) {
|
|
153
|
+
const cell = row.querySelector('[part~="details-cell"]');
|
|
154
|
+
if (!cell) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (cell.hidden) {
|
|
159
|
+
row.style.removeProperty('padding-bottom');
|
|
160
|
+
} else {
|
|
161
|
+
row.style.setProperty('padding-bottom', `${cell.offsetHeight}px`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** @protected */
|
|
166
|
+
_updateDetailsCellHeights() {
|
|
167
|
+
[...this.$.items.children].forEach((row) => {
|
|
168
|
+
this._updateDetailsCellHeight(row);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @param {!GridItem} item
|
|
174
|
+
* @return {boolean}
|
|
175
|
+
* @protected
|
|
176
|
+
*/
|
|
177
|
+
_isDetailsOpened(item) {
|
|
178
|
+
return this.detailsOpenedItems && this._getItemIndexInArray(item, this.detailsOpenedItems) !== -1;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Open the details row of a given item.
|
|
183
|
+
* @param {!GridItem} item
|
|
184
|
+
*/
|
|
185
|
+
openItemDetails(item) {
|
|
186
|
+
if (!this._isDetailsOpened(item)) {
|
|
187
|
+
this.detailsOpenedItems = [...this.detailsOpenedItems, item];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Close the details row of a given item.
|
|
193
|
+
* @param {!GridItem} item
|
|
194
|
+
*/
|
|
195
|
+
closeItemDetails(item) {
|
|
196
|
+
if (this._isDetailsOpened(item)) {
|
|
197
|
+
this.detailsOpenedItems = this.detailsOpenedItems.filter((i) => !this._itemsEqual(i, item));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare function ScrollMixin<T extends new (...args: any[]) => {}>(base: T): T & ScrollMixinConstructor;
|
|
2
|
+
|
|
3
|
+
interface ScrollMixinConstructor {
|
|
4
|
+
new (...args: any[]): ScrollMixin;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface ScrollMixin {
|
|
8
|
+
/**
|
|
9
|
+
* Scroll to a specific row index in the virtual list. Note that the row index is
|
|
10
|
+
* not always the same for any particular item. For example, sorting/filtering/expanding
|
|
11
|
+
* or collapsing hierarchical items can affect the row index related to an item.
|
|
12
|
+
*
|
|
13
|
+
* @param index Row index to scroll to
|
|
14
|
+
*/
|
|
15
|
+
scrollToIndex(index: number): void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { ScrollMixin, ScrollMixinConstructor };
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
7
|
+
import { animationFrame, timeOut, microTask } from '@vaadin/component-base/src/async.js';
|
|
8
|
+
|
|
9
|
+
const timeouts = {
|
|
10
|
+
SCROLLING: 500
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @polymerMixin
|
|
15
|
+
*/
|
|
16
|
+
export const ScrollMixin = (superClass) =>
|
|
17
|
+
class ScrollMixin extends superClass {
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
/**
|
|
21
|
+
* Cached array of frozen cells
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
_frozenCells: {
|
|
25
|
+
type: Array,
|
|
26
|
+
value: () => []
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
/** @private */
|
|
30
|
+
_rowWithFocusedElement: Element
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Override (from iron-scroll-target-behavior) to avoid document scroll
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
set _scrollTop(top) {
|
|
39
|
+
this.$.table.scrollTop = top;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** @private */
|
|
43
|
+
get _scrollTop() {
|
|
44
|
+
return this.$.table.scrollTop;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** @private */
|
|
48
|
+
get _scrollLeft() {
|
|
49
|
+
return this.$.table.scrollLeft;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** @protected */
|
|
53
|
+
ready() {
|
|
54
|
+
super.ready();
|
|
55
|
+
|
|
56
|
+
// Preserve accessor to the legacy scrolling functionality
|
|
57
|
+
this.$.outerscroller = document.createElement('div');
|
|
58
|
+
|
|
59
|
+
this.scrollTarget = this.$.table;
|
|
60
|
+
|
|
61
|
+
this.$.items.addEventListener('focusin', (e) => {
|
|
62
|
+
const itemsIndex = e.composedPath().indexOf(this.$.items);
|
|
63
|
+
this._rowWithFocusedElement = e.composedPath()[itemsIndex - 1];
|
|
64
|
+
});
|
|
65
|
+
this.$.items.addEventListener('focusout', () => (this._rowWithFocusedElement = undefined));
|
|
66
|
+
|
|
67
|
+
this.$.table.addEventListener('scroll', () => this._afterScroll());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Scroll to a specific row index in the virtual list. Note that the row index is
|
|
72
|
+
* not always the same for any particular item. For example, sorting/filtering/expanding
|
|
73
|
+
* or collapsing hierarchical items can affect the row index related to an item.
|
|
74
|
+
*
|
|
75
|
+
* @param {number} index Row index to scroll to
|
|
76
|
+
*/
|
|
77
|
+
scrollToIndex(index) {
|
|
78
|
+
index = Math.min(this._effectiveSize - 1, Math.max(0, index));
|
|
79
|
+
this.__virtualizer.scrollToIndex(index);
|
|
80
|
+
this.__scrollIntoViewport(index);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Makes sure the row with the given index (if found in the DOM) is fully
|
|
85
|
+
* inside the visible viewport, taking header/footer into account.
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
__scrollIntoViewport(index) {
|
|
89
|
+
const rowElement = [...this.$.items.children].find((child) => child.index === index);
|
|
90
|
+
if (rowElement) {
|
|
91
|
+
const dstRect = rowElement.getBoundingClientRect();
|
|
92
|
+
const footerTop = this.$.footer.getBoundingClientRect().top;
|
|
93
|
+
const headerBottom = this.$.header.getBoundingClientRect().bottom;
|
|
94
|
+
if (dstRect.bottom > footerTop) {
|
|
95
|
+
this.$.table.scrollTop += dstRect.bottom - footerTop;
|
|
96
|
+
} else if (dstRect.top < headerBottom) {
|
|
97
|
+
this.$.table.scrollTop -= headerBottom - dstRect.top;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** @private */
|
|
103
|
+
_scheduleScrolling() {
|
|
104
|
+
if (!this._scrollingFrame) {
|
|
105
|
+
// Defer setting state attributes to avoid Edge hiccups
|
|
106
|
+
this._scrollingFrame = requestAnimationFrame(() => this.$.scroller.toggleAttribute('scrolling', true));
|
|
107
|
+
}
|
|
108
|
+
this._debounceScrolling = Debouncer.debounce(this._debounceScrolling, timeOut.after(timeouts.SCROLLING), () => {
|
|
109
|
+
cancelAnimationFrame(this._scrollingFrame);
|
|
110
|
+
delete this._scrollingFrame;
|
|
111
|
+
this.$.scroller.toggleAttribute('scrolling', false);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** @private */
|
|
116
|
+
_afterScroll() {
|
|
117
|
+
this.__updateHorizontalScrollPosition();
|
|
118
|
+
|
|
119
|
+
if (!this.hasAttribute('reordering')) {
|
|
120
|
+
this._scheduleScrolling();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this._updateOverflow();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** @private */
|
|
127
|
+
_updateOverflow() {
|
|
128
|
+
// Set overflow styling attributes
|
|
129
|
+
let overflow = '';
|
|
130
|
+
const table = this.$.table;
|
|
131
|
+
if (table.scrollTop < table.scrollHeight - table.clientHeight) {
|
|
132
|
+
overflow += ' bottom';
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (table.scrollTop > 0) {
|
|
136
|
+
overflow += ' top';
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (table.scrollLeft < table.scrollWidth - table.clientWidth) {
|
|
140
|
+
overflow += ' right';
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (table.scrollLeft > 0) {
|
|
144
|
+
overflow += ' left';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this._debounceOverflow = Debouncer.debounce(this._debounceOverflow, animationFrame, () => {
|
|
148
|
+
const value = overflow.trim();
|
|
149
|
+
if (value.length > 0 && this.getAttribute('overflow') !== value) {
|
|
150
|
+
this.setAttribute('overflow', value);
|
|
151
|
+
} else if (value.length == 0 && this.hasAttribute('overflow')) {
|
|
152
|
+
this.removeAttribute('overflow');
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** @protected */
|
|
158
|
+
_frozenCellsChanged() {
|
|
159
|
+
this._debouncerCacheElements = Debouncer.debounce(this._debouncerCacheElements, microTask, () => {
|
|
160
|
+
Array.from(this.shadowRoot.querySelectorAll('[part~="cell"]')).forEach(function (cell) {
|
|
161
|
+
cell.style.transform = '';
|
|
162
|
+
});
|
|
163
|
+
this._frozenCells = Array.prototype.slice.call(this.$.table.querySelectorAll('[frozen]'));
|
|
164
|
+
this.__updateHorizontalScrollPosition();
|
|
165
|
+
});
|
|
166
|
+
this._updateLastFrozen();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** @protected */
|
|
170
|
+
_updateLastFrozen() {
|
|
171
|
+
if (!this._columnTree) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const columnsRow = this._columnTree[this._columnTree.length - 1].slice(0);
|
|
176
|
+
columnsRow.sort((a, b) => {
|
|
177
|
+
return a._order - b._order;
|
|
178
|
+
});
|
|
179
|
+
const lastFrozen = columnsRow.reduce((prev, col, index) => {
|
|
180
|
+
col._lastFrozen = false;
|
|
181
|
+
return col.frozen && !col.hidden ? index : prev;
|
|
182
|
+
}, undefined);
|
|
183
|
+
if (lastFrozen !== undefined) {
|
|
184
|
+
columnsRow[lastFrozen]._lastFrozen = true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** @private */
|
|
189
|
+
__updateHorizontalScrollPosition() {
|
|
190
|
+
this.$.table.style.setProperty('--_grid-horizontal-scroll-position', -this._scrollLeft + 'px');
|
|
191
|
+
|
|
192
|
+
if (this.__isRTL) {
|
|
193
|
+
// Translating the sticky sections using a CSS variable works nicely on LTR.
|
|
194
|
+
// On RTL, it causes jumpy behavior (on Desktop Safari) so we need to translate manually.
|
|
195
|
+
const x = this.__getNormalizedScrollLeft(this.$.table) + this.$.table.clientWidth - this.$.table.scrollWidth;
|
|
196
|
+
const transform = `translate(${x}px, 0)`;
|
|
197
|
+
for (let i = 0; i < this._frozenCells.length; i++) {
|
|
198
|
+
this._frozenCells[i].style.transform = transform;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { GridDefaultItem } from './interfaces';
|
|
2
|
+
import { GridColumn } from './vaadin-grid-column.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fired when the `selectAll` property changes.
|
|
6
|
+
*/
|
|
7
|
+
export type GridSelectionColumnSelectAllChangedEvent = CustomEvent<{ value: boolean }>;
|
|
8
|
+
|
|
9
|
+
export interface GridSelectionColumnCustomEventMap {
|
|
10
|
+
'select-all-changed': GridSelectionColumnSelectAllChangedEvent;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface GridSelectionColumnEventMap extends HTMLElementEventMap, GridSelectionColumnCustomEventMap {}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* `<vaadin-grid-selection-column>` is a helper element for the `<vaadin-grid>`
|
|
17
|
+
* that provides default renderers and functionality for item selection.
|
|
18
|
+
*
|
|
19
|
+
* #### Example:
|
|
20
|
+
* ```html
|
|
21
|
+
* <vaadin-grid items="[[items]]">
|
|
22
|
+
* <vaadin-grid-selection-column frozen auto-select></vaadin-grid-selection-column>
|
|
23
|
+
*
|
|
24
|
+
* <vaadin-grid-column>
|
|
25
|
+
* ...
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* By default the selection column displays `<vaadin-checkbox>` elements in the
|
|
29
|
+
* column cells. The checkboxes in the body rows toggle selection of the corresponding row items.
|
|
30
|
+
*
|
|
31
|
+
* When the grid data is provided as an array of [`items`](#/elements/vaadin-grid#property-items),
|
|
32
|
+
* the column header gets an additional checkbox that can be used for toggling
|
|
33
|
+
* selection for all the items at once.
|
|
34
|
+
*
|
|
35
|
+
* __The default content can also be overridden__
|
|
36
|
+
*
|
|
37
|
+
* @fires {CustomEvent} select-all-changed - Fired when the `selectAll` property changes.
|
|
38
|
+
*/
|
|
39
|
+
declare class GridSelectionColumn<TItem = GridDefaultItem> extends GridColumn<TItem> {
|
|
40
|
+
/**
|
|
41
|
+
* When true, all the items are selected.
|
|
42
|
+
* @attr {boolean} select-all
|
|
43
|
+
*/
|
|
44
|
+
selectAll: boolean;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* When true, the active gets automatically selected.
|
|
48
|
+
* @attr {boolean} auto-select
|
|
49
|
+
*/
|
|
50
|
+
autoSelect: boolean;
|
|
51
|
+
|
|
52
|
+
addEventListener<K extends keyof GridSelectionColumnEventMap>(
|
|
53
|
+
type: K,
|
|
54
|
+
listener: (this: GridSelectionColumn<TItem>, ev: GridSelectionColumnEventMap[K]) => void,
|
|
55
|
+
options?: boolean | AddEventListenerOptions
|
|
56
|
+
): void;
|
|
57
|
+
|
|
58
|
+
removeEventListener<K extends keyof GridSelectionColumnEventMap>(
|
|
59
|
+
type: K,
|
|
60
|
+
listener: (this: GridSelectionColumn<TItem>, ev: GridSelectionColumnEventMap[K]) => void,
|
|
61
|
+
options?: boolean | EventListenerOptions
|
|
62
|
+
): void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
declare global {
|
|
66
|
+
interface HTMLElementTagNameMap {
|
|
67
|
+
'vaadin-grid-selection-column': GridSelectionColumn<GridDefaultItem>;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { GridSelectionColumn };
|