@vaadin/grid 24.2.0-dev.f254716fe → 24.2.0

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.
@@ -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
- customElements.define(GridSelectionColumn.is, GridSelectionColumn);
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
- customElements.define(GridSortColumn.is, GridSortColumn);
120
+ defineCustomElement(GridSortColumn);
117
121
 
118
122
  export { GridSortColumn };
@@ -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 { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
7
+ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
7
8
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
8
9
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
9
10
 
@@ -61,6 +62,7 @@ document.head.appendChild(template.content);
61
62
  * @fires {CustomEvent} direction-changed - Fired when the `direction` property changes.
62
63
  * @fires {CustomEvent} sorter-changed - Fired when the `path` or `direction` property changes.
63
64
  *
65
+ * @customElement
64
66
  * @extends HTMLElement
65
67
  */
66
68
  class GridSorter extends ThemableMixin(DirMixin(PolymerElement)) {
@@ -245,6 +247,6 @@ class GridSorter extends ThemableMixin(DirMixin(PolymerElement)) {
245
247
  }
246
248
  }
247
249
 
248
- customElements.define(GridSorter.is, GridSorter);
250
+ defineCustomElement(GridSorter);
249
251
 
250
252
  export { GridSorter };
@@ -4,6 +4,8 @@
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-tree-toggle.js';
7
+ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
8
+ import { get } from '@vaadin/component-base/src/path-utils.js';
7
9
  import { GridColumn } from './vaadin-grid-column.js';
8
10
 
9
11
  /**
@@ -18,6 +20,8 @@ import { GridColumn } from './vaadin-grid-column.js';
18
20
  * <vaadin-grid-column>
19
21
  * ...
20
22
  * ```
23
+ * @customElement
24
+ * @extends GridColumn
21
25
  */
22
26
  class GridTreeColumn extends GridColumn {
23
27
  static get is() {
@@ -101,10 +105,10 @@ class GridTreeColumn extends GridColumn {
101
105
 
102
106
  /** @private */
103
107
  __getToggleContent(path, item) {
104
- return path && this.get(path, item);
108
+ return path && get(path, item);
105
109
  }
106
110
  }
107
111
 
108
- customElements.define(GridTreeColumn.is, GridTreeColumn);
112
+ defineCustomElement(GridTreeColumn);
109
113
 
110
114
  export { GridTreeColumn };
@@ -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 { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
7
+ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
7
8
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
8
9
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
9
10
  import { isFocusable } from './vaadin-grid-active-item-mixin.js';
@@ -71,6 +72,7 @@ document.head.appendChild(template.content);
71
72
  *
72
73
  * @fires {CustomEvent} expanded-changed - Fired when the `expanded` property changes.
73
74
  *
75
+ * @customElement
74
76
  * @extends HTMLElement
75
77
  * @mixes ThemableMixin
76
78
  */
@@ -207,6 +209,6 @@ class GridTreeToggle extends ThemableMixin(DirMixin(PolymerElement)) {
207
209
  }
208
210
  }
209
211
 
210
- customElements.define(GridTreeToggle.is, GridTreeToggle);
212
+ defineCustomElement(GridTreeToggle);
211
213
 
212
214
  export { GridTreeToggle };
@@ -4,165 +4,16 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import type { DisabledMixinClass } from '@vaadin/a11y-base/src/disabled-mixin.js';
7
+ import type { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js';
7
8
  import type { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js';
8
9
  import type { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
9
10
  import type { ThemePropertyMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
10
- import type { ActiveItemMixinClass } from './vaadin-grid-active-item-mixin.js';
11
- import type { ArrayDataProviderMixinClass } from './vaadin-grid-array-data-provider-mixin.js';
12
- import type { GridColumn } from './vaadin-grid-column.js';
13
- import { GridBodyRenderer, GridHeaderFooterRenderer } from './vaadin-grid-column.js';
14
- import type { ColumnReorderingMixinClass } from './vaadin-grid-column-reordering-mixin.js';
15
- import type { DataProviderMixinClass } from './vaadin-grid-data-provider-mixin.js';
16
- import {
17
- GridDataProvider,
18
- GridDataProviderCallback,
19
- GridDataProviderParams,
20
- GridFilterDefinition,
21
- GridSorterDefinition,
22
- GridSorterDirection,
23
- } from './vaadin-grid-data-provider-mixin.js';
24
- import type { DragAndDropMixinClass } from './vaadin-grid-drag-and-drop-mixin.js';
25
- import { GridDragAndDropFilter, GridDropLocation, GridDropMode } from './vaadin-grid-drag-and-drop-mixin.js';
26
- import type { EventContextMixinClass } from './vaadin-grid-event-context-mixin.js';
27
- import { GridEventContext } from './vaadin-grid-event-context-mixin.js';
28
- import type { RowDetailsMixinClass } from './vaadin-grid-row-details-mixin.js';
29
- import { GridRowDetailsRenderer } from './vaadin-grid-row-details-mixin.js';
30
- import type { ScrollMixinClass } from './vaadin-grid-scroll-mixin.js';
31
- import type { SelectionMixinClass } from './vaadin-grid-selection-mixin.js';
32
- import type { SortMixinClass } from './vaadin-grid-sort-mixin.js';
33
- import type {
34
- GridCellClassNameGenerator,
35
- GridCellPartNameGenerator,
36
- StylingMixinClass,
37
- } from './vaadin-grid-styling-mixin.js';
11
+ import type { GridEventMap, GridMixinClass } from './vaadin-grid-mixin.js';
38
12
 
39
- export {
40
- GridBodyRenderer,
41
- GridCellClassNameGenerator,
42
- GridCellPartNameGenerator,
43
- GridDataProvider,
44
- GridDataProviderCallback,
45
- GridDataProviderParams,
46
- GridDragAndDropFilter,
47
- GridDropLocation,
48
- GridDropMode,
49
- GridEventContext,
50
- GridFilterDefinition,
51
- GridHeaderFooterRenderer,
52
- GridRowDetailsRenderer,
53
- GridSorterDefinition,
54
- GridSorterDirection,
55
- };
13
+ export * from './vaadin-grid-mixin.js';
56
14
 
57
15
  export type GridDefaultItem = any;
58
16
 
59
- export interface GridItemModel<TItem> {
60
- index: number;
61
- item: TItem;
62
- selected?: boolean;
63
- expanded?: boolean;
64
- level?: number;
65
- detailsOpened?: boolean;
66
- }
67
-
68
- /**
69
- * Fired when the `activeItem` property changes.
70
- */
71
- export type GridActiveItemChangedEvent<TItem> = CustomEvent<{ value: TItem | null | undefined }>;
72
-
73
- /**
74
- * Fired when the cell is activated with click or keyboard.
75
- */
76
- export type GridCellActivateEvent<TItem> = CustomEvent<{ model: GridItemModel<TItem> }>;
77
-
78
- /**
79
- * Fired when a cell is focused with click or keyboard navigation.
80
- */
81
- export type GridCellFocusEvent<TItem> = CustomEvent<{ context: GridEventContext<TItem> }>;
82
-
83
- /**
84
- * Fired when the columns in the grid are reordered.
85
- */
86
- export type GridColumnReorderEvent<TItem> = CustomEvent<{ columns: Array<GridColumn<TItem>> }>;
87
-
88
- /**
89
- * Fired when the grid column resize is finished.
90
- */
91
- export type GridColumnResizeEvent<TItem> = CustomEvent<{ resizedColumn: GridColumn<TItem> }>;
92
-
93
- /**
94
- * Fired when the `dataProvider` property changes.
95
- */
96
- export type GridDataProviderChangedEvent<TItem> = CustomEvent<{ value: GridDataProvider<TItem> }>;
97
-
98
- /**
99
- * Fired when the `expandedItems` property changes.
100
- */
101
- export type GridExpandedItemsChangedEvent<TItem> = CustomEvent<{ value: TItem[] }>;
102
-
103
- /**
104
- * Fired when starting to drag grid rows.
105
- */
106
- export type GridDragStartEvent<TItem> = CustomEvent<{
107
- draggedItems: TItem[];
108
- setDraggedItemsCount(count: number): void;
109
- setDragData(type: string, data: string): void;
110
- }>;
111
-
112
- /**
113
- * Fired when a drop occurs on top of the grid.
114
- */
115
- export type GridDropEvent<TItem> = CustomEvent<{
116
- dropTargetItem: TItem;
117
- dropLocation: GridDropLocation;
118
- dragData: Array<{ type: string; data: string }>;
119
- }>;
120
-
121
- /**
122
- * Fired when the `loading` property changes.
123
- */
124
- export type GridLoadingChangedEvent = CustomEvent<{ value: boolean }>;
125
-
126
- /**
127
- * Fired when the `selectedItems` property changes.
128
- */
129
- export type GridSelectedItemsChangedEvent<TItem> = CustomEvent<{ value: TItem[] }>;
130
-
131
- /**
132
- * Fired when the `size` property changes.
133
- */
134
- export type GridSizeChangedEvent = CustomEvent<{ value: number }>;
135
-
136
- export interface GridCustomEventMap<TItem> {
137
- 'active-item-changed': GridActiveItemChangedEvent<TItem>;
138
-
139
- 'cell-activate': GridCellActivateEvent<TItem>;
140
-
141
- 'cell-focus': GridCellFocusEvent<TItem>;
142
-
143
- 'column-reorder': GridColumnReorderEvent<TItem>;
144
-
145
- 'column-resize': GridColumnResizeEvent<TItem>;
146
-
147
- 'data-provider-changed': GridDataProviderChangedEvent<TItem>;
148
-
149
- 'expanded-items-changed': GridExpandedItemsChangedEvent<TItem>;
150
-
151
- 'grid-dragstart': GridDragStartEvent<TItem>;
152
-
153
- 'grid-dragend': Event;
154
-
155
- 'grid-drop': GridDropEvent<TItem>;
156
-
157
- 'loading-changed': GridLoadingChangedEvent;
158
-
159
- 'selected-items-changed': GridSelectedItemsChangedEvent<TItem>;
160
-
161
- 'size-changed': GridSizeChangedEvent;
162
- }
163
-
164
- export interface GridEventMap<TItem> extends HTMLElementEventMap, GridCustomEventMap<TItem> {}
165
-
166
17
  /**
167
18
  * `<vaadin-grid>` is a free, high quality data grid / data table Web Component. The content of the
168
19
  * the grid can be populated by using renderer callback function.
@@ -400,33 +251,6 @@ export interface GridEventMap<TItem> extends HTMLElementEventMap, GridCustomEven
400
251
  * @fires {CustomEvent} size-changed - Fired when the `size` property changes.
401
252
  */
402
253
  declare class Grid<TItem = GridDefaultItem> extends HTMLElement {
403
- /**
404
- * If true, the grid's height is defined by its rows.
405
- *
406
- * Effectively, this disables the grid's virtual scrolling so that all the rows are rendered in the DOM at once.
407
- * If the grid has a large number of items, using the feature is discouraged to avoid performance issues.
408
- * @attr {boolean} all-rows-visible
409
- */
410
- allRowsVisible: boolean;
411
-
412
- /**
413
- * Updates the `width` of all columns which have `autoWidth` set to `true`.
414
- */
415
- recalculateColumnWidths(): void;
416
-
417
- /**
418
- * Requests an update for the content of cells.
419
- *
420
- * While performing the update, the following renderers are invoked:
421
- * - `Grid.rowDetailsRenderer`
422
- * - `GridColumn.renderer`
423
- * - `GridColumn.headerRenderer`
424
- * - `GridColumn.footerRenderer`
425
- *
426
- * It is not guaranteed that the update happens immediately (synchronously) after it is requested.
427
- */
428
- requestContentUpdate(): void;
429
-
430
254
  addEventListener<K extends keyof GridEventMap<TItem>>(
431
255
  type: K,
432
256
  listener: (this: Grid<TItem>, ev: GridEventMap<TItem>[K]) => void,
@@ -445,17 +269,8 @@ interface Grid<TItem = GridDefaultItem>
445
269
  ElementMixinClass,
446
270
  ThemableMixinClass,
447
271
  ThemePropertyMixinClass,
448
- ActiveItemMixinClass<TItem>,
449
- ArrayDataProviderMixinClass<TItem>,
450
- DataProviderMixinClass<TItem>,
451
- RowDetailsMixinClass<TItem>,
452
- ScrollMixinClass,
453
- SelectionMixinClass<TItem>,
454
- SortMixinClass,
455
- ColumnReorderingMixinClass,
456
- EventContextMixinClass<TItem>,
457
- StylingMixinClass<TItem>,
458
- DragAndDropMixinClass<TItem> {}
272
+ ControllerMixinClass,
273
+ GridMixinClass<TItem> {}
459
274
 
460
275
  declare global {
461
276
  interface HTMLElementTagNameMap {