@vaadin/grid 24.2.0-dev.f254716fe → 24.3.0-alpha2
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 +11 -11
- package/src/vaadin-grid-array-data-provider-mixin.js +1 -1
- package/src/vaadin-grid-column-group-mixin.d.ts +20 -0
- package/src/vaadin-grid-column-group-mixin.js +369 -0
- package/src/vaadin-grid-column-group.d.ts +4 -14
- package/src/vaadin-grid-column-group.js +8 -356
- package/src/vaadin-grid-column-mixin.d.ts +156 -0
- package/src/vaadin-grid-column-mixin.js +887 -0
- package/src/vaadin-grid-column.d.ts +11 -138
- package/src/vaadin-grid-column.js +6 -876
- package/src/vaadin-grid-data-provider-mixin.d.ts +6 -5
- package/src/vaadin-grid-data-provider-mixin.js +51 -20
- package/src/vaadin-grid-drag-and-drop-mixin.js +1 -1
- package/src/vaadin-grid-dynamic-columns-mixin.js +1 -1
- package/src/vaadin-grid-filter-column.js +5 -1
- package/src/vaadin-grid-filter-element-mixin.d.ts +34 -0
- package/src/vaadin-grid-filter-element-mixin.js +99 -0
- package/src/vaadin-grid-filter.d.ts +4 -21
- package/src/vaadin-grid-filter.js +8 -85
- package/src/vaadin-grid-keyboard-navigation-mixin.js +24 -4
- package/src/vaadin-grid-mixin.d.ts +218 -0
- package/src/vaadin-grid-mixin.js +1022 -0
- package/src/vaadin-grid-scroll-mixin.js +1 -1
- package/src/vaadin-grid-selection-column-base-mixin.d.ts +6 -0
- package/src/vaadin-grid-selection-column-base-mixin.js +151 -0
- package/src/vaadin-grid-selection-column.js +4 -1
- package/src/vaadin-grid-sort-column.js +5 -1
- package/src/vaadin-grid-sorter-mixin.d.ts +44 -0
- package/src/vaadin-grid-sorter-mixin.js +198 -0
- package/src/vaadin-grid-sorter.d.ts +3 -32
- package/src/vaadin-grid-sorter.js +8 -182
- package/src/vaadin-grid-tree-column-mixin.d.ts +19 -0
- package/src/vaadin-grid-tree-column-mixin.js +92 -0
- package/src/vaadin-grid-tree-column.d.ts +9 -7
- package/src/vaadin-grid-tree-column.js +7 -82
- package/src/vaadin-grid-tree-toggle.js +3 -1
- package/src/vaadin-grid.d.ts +5 -190
- package/src/vaadin-grid.js +7 -1018
- package/web-types.json +2311 -0
- package/web-types.lit.json +1007 -0
|
@@ -160,7 +160,7 @@ export const ScrollMixin = (superClass) =>
|
|
|
160
160
|
* @protected
|
|
161
161
|
*/
|
|
162
162
|
_scrollToFlatIndex(index) {
|
|
163
|
-
index = Math.min(this.
|
|
163
|
+
index = Math.min(this._flatSize - 1, Math.max(0, index));
|
|
164
164
|
this.__virtualizer.scrollToIndex(index);
|
|
165
165
|
this.__scrollIntoViewport(index);
|
|
166
166
|
}
|
|
@@ -35,6 +35,12 @@ export declare class GridSelectionColumnBaseMixinClass<TItem> {
|
|
|
35
35
|
*/
|
|
36
36
|
autoSelect: boolean;
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* When true, rows can be selected by dragging over the selection column.
|
|
40
|
+
* @attr {boolean} drag-select
|
|
41
|
+
*/
|
|
42
|
+
dragSelect: boolean;
|
|
43
|
+
|
|
38
44
|
/**
|
|
39
45
|
* Override to handle the user selecting all items.
|
|
40
46
|
*/
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright (c) 2016 - 2023 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
import { addListener } from '@vaadin/component-base/src/gestures.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* A mixin that provides basic functionality for the
|
|
@@ -60,6 +61,16 @@ export const GridSelectionColumnBaseMixin = (superClass) =>
|
|
|
60
61
|
value: false,
|
|
61
62
|
},
|
|
62
63
|
|
|
64
|
+
/**
|
|
65
|
+
* When true, rows can be selected by dragging over the selection column.
|
|
66
|
+
* @attr {boolean} drag-select
|
|
67
|
+
* @type {boolean}
|
|
68
|
+
*/
|
|
69
|
+
dragSelect: {
|
|
70
|
+
type: Boolean,
|
|
71
|
+
value: false,
|
|
72
|
+
},
|
|
73
|
+
|
|
63
74
|
/** @protected */
|
|
64
75
|
_indeterminate: Boolean,
|
|
65
76
|
|
|
@@ -110,6 +121,9 @@ export const GridSelectionColumnBaseMixin = (superClass) =>
|
|
|
110
121
|
root.appendChild(checkbox);
|
|
111
122
|
// Add listener after appending, so we can skip the initial change event
|
|
112
123
|
checkbox.addEventListener('checked-changed', this.__onSelectRowCheckedChanged.bind(this));
|
|
124
|
+
addListener(root, 'track', this.__onCellTrack.bind(this));
|
|
125
|
+
root.addEventListener('mousedown', this.__onCellMouseDown.bind(this));
|
|
126
|
+
root.addEventListener('click', this.__onCellClick.bind(this));
|
|
113
127
|
}
|
|
114
128
|
|
|
115
129
|
checkbox.__item = item;
|
|
@@ -155,6 +169,143 @@ export const GridSelectionColumnBaseMixin = (superClass) =>
|
|
|
155
169
|
}
|
|
156
170
|
}
|
|
157
171
|
|
|
172
|
+
/** @private */
|
|
173
|
+
__onCellTrack(event) {
|
|
174
|
+
if (!this.dragSelect) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
this.__dragCurrentY = event.detail.y;
|
|
178
|
+
this.__dragDy = event.detail.dy;
|
|
179
|
+
if (event.detail.state === 'start') {
|
|
180
|
+
const renderedRows = this._grid._getRenderedRows();
|
|
181
|
+
// Get the row where the drag started
|
|
182
|
+
const dragStartRow = renderedRows.find((row) => row.contains(event.currentTarget.assignedSlot));
|
|
183
|
+
// Whether to select or deselect the items on drag
|
|
184
|
+
this.__dragSelect = !this._grid._isSelected(dragStartRow._item);
|
|
185
|
+
// Store the index of the row where the drag started
|
|
186
|
+
this.__dragStartIndex = dragStartRow.index;
|
|
187
|
+
// Store the item of the row where the drag started
|
|
188
|
+
this.__dragStartItem = dragStartRow._item;
|
|
189
|
+
// Start the auto scroller
|
|
190
|
+
this.__dragAutoScroller();
|
|
191
|
+
} else if (event.detail.state === 'end') {
|
|
192
|
+
// if drag start and end stays within the same item, then toggle its state
|
|
193
|
+
if (this.__dragStartItem) {
|
|
194
|
+
if (this.__dragSelect) {
|
|
195
|
+
this._selectItem(this.__dragStartItem);
|
|
196
|
+
} else {
|
|
197
|
+
this._deselectItem(this.__dragStartItem);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// clear drag state after timeout, which allows preventing the
|
|
201
|
+
// subsequent click event if drag started and ended on the same item
|
|
202
|
+
setTimeout(() => {
|
|
203
|
+
this.__dragStartIndex = undefined;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** @private */
|
|
209
|
+
__onCellMouseDown(e) {
|
|
210
|
+
if (this.dragSelect) {
|
|
211
|
+
// Prevent text selection when starting to drag
|
|
212
|
+
e.preventDefault();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** @private */
|
|
217
|
+
__onCellClick(e) {
|
|
218
|
+
if (this.__dragStartIndex !== undefined) {
|
|
219
|
+
// Stop the click event if drag was enabled. This click event should
|
|
220
|
+
// only occur if drag started and stopped on the same item. In that case
|
|
221
|
+
// the selection state has already been toggled on drag end, and we
|
|
222
|
+
// don't want to toggle it again from clicking the checkbox or changing
|
|
223
|
+
// the active item.
|
|
224
|
+
e.preventDefault();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** @private */
|
|
229
|
+
__dragAutoScroller() {
|
|
230
|
+
if (this.__dragStartIndex === undefined) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// Get the row being hovered over
|
|
234
|
+
const renderedRows = this._grid._getRenderedRows();
|
|
235
|
+
const hoveredRow = renderedRows.find((row) => {
|
|
236
|
+
const rowRect = row.getBoundingClientRect();
|
|
237
|
+
return this.__dragCurrentY >= rowRect.top && this.__dragCurrentY <= rowRect.bottom;
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Get the index of the row being hovered over or the first/last
|
|
241
|
+
// visible row if hovering outside the grid
|
|
242
|
+
let hoveredIndex = hoveredRow ? hoveredRow.index : undefined;
|
|
243
|
+
const scrollableArea = this.__getScrollableArea();
|
|
244
|
+
if (this.__dragCurrentY < scrollableArea.top) {
|
|
245
|
+
hoveredIndex = this._grid._firstVisibleIndex;
|
|
246
|
+
} else if (this.__dragCurrentY > scrollableArea.bottom) {
|
|
247
|
+
hoveredIndex = this._grid._lastVisibleIndex;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (hoveredIndex !== undefined) {
|
|
251
|
+
// Select all items between the start and the current row
|
|
252
|
+
renderedRows.forEach((row) => {
|
|
253
|
+
if (
|
|
254
|
+
(hoveredIndex > this.__dragStartIndex && row.index >= this.__dragStartIndex && row.index <= hoveredIndex) ||
|
|
255
|
+
(hoveredIndex < this.__dragStartIndex && row.index <= this.__dragStartIndex && row.index >= hoveredIndex)
|
|
256
|
+
) {
|
|
257
|
+
if (this.__dragSelect) {
|
|
258
|
+
this._selectItem(row._item);
|
|
259
|
+
} else {
|
|
260
|
+
this._deselectItem(row._item);
|
|
261
|
+
}
|
|
262
|
+
this.__dragStartItem = undefined;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Start scrolling in the top/bottom 15% of the scrollable area
|
|
268
|
+
const scrollTriggerArea = scrollableArea.height * 0.15;
|
|
269
|
+
// Maximum number of pixels to scroll per iteration
|
|
270
|
+
const maxScrollAmount = 10;
|
|
271
|
+
|
|
272
|
+
if (this.__dragDy < 0 && this.__dragCurrentY < scrollableArea.top + scrollTriggerArea) {
|
|
273
|
+
const dy = scrollableArea.top + scrollTriggerArea - this.__dragCurrentY;
|
|
274
|
+
const percentage = Math.min(1, dy / scrollTriggerArea);
|
|
275
|
+
this._grid.$.table.scrollTop -= percentage * maxScrollAmount;
|
|
276
|
+
}
|
|
277
|
+
if (this.__dragDy > 0 && this.__dragCurrentY > scrollableArea.bottom - scrollTriggerArea) {
|
|
278
|
+
const dy = this.__dragCurrentY - (scrollableArea.bottom - scrollTriggerArea);
|
|
279
|
+
const percentage = Math.min(1, dy / scrollTriggerArea);
|
|
280
|
+
this._grid.$.table.scrollTop += percentage * maxScrollAmount;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Schedule the next auto scroll
|
|
284
|
+
setTimeout(() => this.__dragAutoScroller(), 10);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Gets the scrollable area of the grid as a bounding client rect. The
|
|
289
|
+
* scrollable area is the bounding rect of the grid minus the header and
|
|
290
|
+
* footer.
|
|
291
|
+
*
|
|
292
|
+
* @private
|
|
293
|
+
*/
|
|
294
|
+
__getScrollableArea() {
|
|
295
|
+
const gridRect = this._grid.$.table.getBoundingClientRect();
|
|
296
|
+
const headerRect = this._grid.$.header.getBoundingClientRect();
|
|
297
|
+
const footerRect = this._grid.$.footer.getBoundingClientRect();
|
|
298
|
+
|
|
299
|
+
return {
|
|
300
|
+
top: gridRect.top + headerRect.height,
|
|
301
|
+
bottom: gridRect.bottom - footerRect.height,
|
|
302
|
+
left: gridRect.left,
|
|
303
|
+
right: gridRect.right,
|
|
304
|
+
height: gridRect.height - headerRect.height - footerRect.height,
|
|
305
|
+
width: gridRect.width,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
158
309
|
/**
|
|
159
310
|
* Override to handle the user selecting all items.
|
|
160
311
|
* @protected
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import '@vaadin/checkbox/src/vaadin-checkbox.js';
|
|
7
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
7
8
|
import { GridColumn } from './vaadin-grid-column.js';
|
|
8
9
|
import { GridSelectionColumnBaseMixin } from './vaadin-grid-selection-column-base-mixin.js';
|
|
9
10
|
|
|
@@ -29,6 +30,8 @@ import { GridSelectionColumnBaseMixin } from './vaadin-grid-selection-column-bas
|
|
|
29
30
|
*
|
|
30
31
|
* __The default content can also be overridden__
|
|
31
32
|
*
|
|
33
|
+
* @customElement
|
|
34
|
+
* @extends GridColumn
|
|
32
35
|
* @mixes GridSelectionColumnBaseMixin
|
|
33
36
|
* @fires {CustomEvent} select-all-changed - Fired when the `selectAll` property changes.
|
|
34
37
|
*/
|
|
@@ -220,6 +223,6 @@ class GridSelectionColumn extends GridSelectionColumnBaseMixin(GridColumn) {
|
|
|
220
223
|
}
|
|
221
224
|
}
|
|
222
225
|
|
|
223
|
-
|
|
226
|
+
defineCustomElement(GridSelectionColumn);
|
|
224
227
|
|
|
225
228
|
export { GridSelectionColumn };
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import './vaadin-grid-sorter.js';
|
|
7
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
7
8
|
import { GridColumn } from './vaadin-grid-column.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -20,6 +21,9 @@ import { GridColumn } from './vaadin-grid-column.js';
|
|
|
20
21
|
* ```
|
|
21
22
|
*
|
|
22
23
|
* @fires {CustomEvent} direction-changed - Fired when the `direction` property changes.
|
|
24
|
+
*
|
|
25
|
+
* @customElement
|
|
26
|
+
* @extends GridColumn
|
|
23
27
|
*/
|
|
24
28
|
class GridSortColumn extends GridColumn {
|
|
25
29
|
static get is() {
|
|
@@ -113,6 +117,6 @@ class GridSortColumn extends GridColumn {
|
|
|
113
117
|
}
|
|
114
118
|
}
|
|
115
119
|
|
|
116
|
-
|
|
120
|
+
defineCustomElement(GridSortColumn);
|
|
117
121
|
|
|
118
122
|
export { GridSortColumn };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2016 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
|
+
|
|
8
|
+
export type GridSorterDirection = 'asc' | 'desc' | null;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Fired when the `path` or `direction` property changes.
|
|
12
|
+
*/
|
|
13
|
+
export type GridSorterChangedEvent = CustomEvent<{ shiftClick: boolean; fromSorterClick: boolean }>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Fired when the `direction` property changes.
|
|
17
|
+
*/
|
|
18
|
+
export type GridSorterDirectionChangedEvent = CustomEvent<{ value: GridSorterDirection }>;
|
|
19
|
+
|
|
20
|
+
export interface GridSorterCustomEventMap {
|
|
21
|
+
'sorter-changed': GridSorterChangedEvent;
|
|
22
|
+
|
|
23
|
+
'direction-changed': GridSorterDirectionChangedEvent;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface GridSorterEventMap extends HTMLElementEventMap, GridSorterCustomEventMap {}
|
|
27
|
+
|
|
28
|
+
export declare function GridSorterMixin<T extends Constructor<HTMLElement>>(
|
|
29
|
+
base: T,
|
|
30
|
+
): Constructor<GridSorterMixinClass> & T;
|
|
31
|
+
|
|
32
|
+
declare class GridSorterMixinClass {
|
|
33
|
+
/**
|
|
34
|
+
* JS Path of the property in the item used for sorting the data.
|
|
35
|
+
*/
|
|
36
|
+
path: string | null | undefined;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* How to sort the data.
|
|
40
|
+
* Possible values are `asc` to use an ascending algorithm, `desc` to sort the data in
|
|
41
|
+
* descending direction, or `null` for not sorting the data.
|
|
42
|
+
*/
|
|
43
|
+
direction: GridSorterDirection | null | undefined;
|
|
44
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2016 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
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
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A mixin providing common sorter functionality.
|
|
69
|
+
*
|
|
70
|
+
* @polymerMixin
|
|
71
|
+
*/
|
|
72
|
+
export const GridSorterMixin = (superClass) =>
|
|
73
|
+
class GridSorterMixinClass extends superClass {
|
|
74
|
+
static get properties() {
|
|
75
|
+
return {
|
|
76
|
+
/**
|
|
77
|
+
* JS Path of the property in the item used for sorting the data.
|
|
78
|
+
*/
|
|
79
|
+
path: String,
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* How to sort the data.
|
|
83
|
+
* Possible values are `asc` to use an ascending algorithm, `desc` to sort the data in
|
|
84
|
+
* descending direction, or `null` for not sorting the data.
|
|
85
|
+
* @type {GridSorterDirection | undefined}
|
|
86
|
+
*/
|
|
87
|
+
direction: {
|
|
88
|
+
type: String,
|
|
89
|
+
reflectToAttribute: true,
|
|
90
|
+
notify: true,
|
|
91
|
+
value: null,
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @type {number | null}
|
|
96
|
+
* @protected
|
|
97
|
+
*/
|
|
98
|
+
_order: {
|
|
99
|
+
type: Number,
|
|
100
|
+
value: null,
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
/** @private */
|
|
104
|
+
_isConnected: {
|
|
105
|
+
type: Boolean,
|
|
106
|
+
observer: '__isConnectedChanged',
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static get observers() {
|
|
112
|
+
return ['_pathOrDirectionChanged(path, direction)'];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** @protected */
|
|
116
|
+
ready() {
|
|
117
|
+
super.ready();
|
|
118
|
+
this.addEventListener('click', this._onClick.bind(this));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** @protected */
|
|
122
|
+
connectedCallback() {
|
|
123
|
+
super.connectedCallback();
|
|
124
|
+
this._isConnected = true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** @protected */
|
|
128
|
+
disconnectedCallback() {
|
|
129
|
+
super.disconnectedCallback();
|
|
130
|
+
this._isConnected = false;
|
|
131
|
+
|
|
132
|
+
if (!this.parentNode && this._grid) {
|
|
133
|
+
this._grid.__removeSorters([this]);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** @private */
|
|
138
|
+
_pathOrDirectionChanged() {
|
|
139
|
+
this.__dispatchSorterChangedEvenIfPossible();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** @private */
|
|
143
|
+
__isConnectedChanged(newValue, oldValue) {
|
|
144
|
+
if (oldValue === false) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
this.__dispatchSorterChangedEvenIfPossible();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** @private */
|
|
152
|
+
__dispatchSorterChangedEvenIfPossible() {
|
|
153
|
+
if (this.path === undefined || this.direction === undefined || !this._isConnected) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
this.dispatchEvent(
|
|
158
|
+
new CustomEvent('sorter-changed', {
|
|
159
|
+
detail: { shiftClick: Boolean(this._shiftClick), fromSorterClick: Boolean(this._fromSorterClick) },
|
|
160
|
+
bubbles: true,
|
|
161
|
+
composed: true,
|
|
162
|
+
}),
|
|
163
|
+
);
|
|
164
|
+
// Cleaning up as a programatically sorting can be done after some user interaction
|
|
165
|
+
this._fromSorterClick = false;
|
|
166
|
+
this._shiftClick = false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** @private */
|
|
170
|
+
_getDisplayOrder(order) {
|
|
171
|
+
return order === null ? '' : order + 1;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** @private */
|
|
175
|
+
_onClick(e) {
|
|
176
|
+
if (e.defaultPrevented) {
|
|
177
|
+
// Something else has already handled the click event, do nothing.
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const activeElement = this.getRootNode().activeElement;
|
|
182
|
+
if (this !== activeElement && this.contains(activeElement)) {
|
|
183
|
+
// Some focusable content inside the sorter was clicked, do nothing.
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
e.preventDefault();
|
|
188
|
+
this._shiftClick = e.shiftKey;
|
|
189
|
+
this._fromSorterClick = true;
|
|
190
|
+
if (this.direction === 'asc') {
|
|
191
|
+
this.direction = 'desc';
|
|
192
|
+
} else if (this.direction === 'desc') {
|
|
193
|
+
this.direction = null;
|
|
194
|
+
} else {
|
|
195
|
+
this.direction = 'asc';
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
@@ -5,26 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
7
7
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
8
|
+
import { type GridSorterEventMap, GridSorterMixin } from './vaadin-grid-sorter-mixin.js';
|
|
8
9
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Fired when the `path` or `direction` property changes.
|
|
13
|
-
*/
|
|
14
|
-
export type GridSorterChangedEvent = CustomEvent<{ shiftClick: boolean; fromSorterClick: boolean }>;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Fired when the `direction` property changes.
|
|
18
|
-
*/
|
|
19
|
-
export type GridSorterDirectionChangedEvent = CustomEvent<{ value: GridSorterDirection }>;
|
|
20
|
-
|
|
21
|
-
export interface GridSorterCustomEventMap {
|
|
22
|
-
'sorter-changed': GridSorterChangedEvent;
|
|
23
|
-
|
|
24
|
-
'direction-changed': GridSorterDirectionChangedEvent;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface GridSorterEventMap extends HTMLElementEventMap, GridSorterCustomEventMap {}
|
|
10
|
+
export * from './vaadin-grid-sorter-mixin.js';
|
|
28
11
|
|
|
29
12
|
/**
|
|
30
13
|
* `<vaadin-grid-sorter>` is a helper element for the `<vaadin-grid>` that provides out-of-the-box UI controls,
|
|
@@ -65,19 +48,7 @@ export interface GridSorterEventMap extends HTMLElementEventMap, GridSorterCusto
|
|
|
65
48
|
* @fires {CustomEvent} direction-changed - Fired when the `direction` property changes.
|
|
66
49
|
* @fires {CustomEvent} sorter-changed - Fired when the `path` or `direction` property changes.
|
|
67
50
|
*/
|
|
68
|
-
declare class GridSorter extends ThemableMixin(DirMixin(HTMLElement)) {
|
|
69
|
-
/**
|
|
70
|
-
* JS Path of the property in the item used for sorting the data.
|
|
71
|
-
*/
|
|
72
|
-
path: string | null | undefined;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* How to sort the data.
|
|
76
|
-
* Possible values are `asc` to use an ascending algorithm, `desc` to sort the data in
|
|
77
|
-
* descending direction, or `null` for not sorting the data.
|
|
78
|
-
*/
|
|
79
|
-
direction: GridSorterDirection | null | undefined;
|
|
80
|
-
|
|
51
|
+
declare class GridSorter extends GridSorterMixin(ThemableMixin(DirMixin(HTMLElement))) {
|
|
81
52
|
addEventListener<K extends keyof GridSorterEventMap>(
|
|
82
53
|
type: K,
|
|
83
54
|
listener: (this: GridSorter, ev: GridSorterEventMap[K]) => void,
|