@vaadin/grid 24.0.0-alpha1 → 24.0.0-alpha11

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.
Files changed (63) hide show
  1. package/all-imports.d.ts +10 -0
  2. package/all-imports.js +11 -0
  3. package/package.json +11 -10
  4. package/src/all-imports.js +1 -1
  5. package/src/array-data-provider.js +1 -1
  6. package/src/lit/column-renderer-directives.d.ts +1 -1
  7. package/src/lit/column-renderer-directives.js +1 -1
  8. package/src/lit/renderer-directives.d.ts +1 -1
  9. package/src/lit/renderer-directives.js +1 -1
  10. package/src/vaadin-grid-a11y-mixin.js +12 -9
  11. package/src/vaadin-grid-active-item-mixin.d.ts +1 -1
  12. package/src/vaadin-grid-active-item-mixin.js +10 -5
  13. package/src/vaadin-grid-array-data-provider-mixin.d.ts +1 -1
  14. package/src/vaadin-grid-array-data-provider-mixin.js +1 -1
  15. package/src/vaadin-grid-column-group.d.ts +1 -1
  16. package/src/vaadin-grid-column-group.js +17 -17
  17. package/src/vaadin-grid-column-reordering-mixin.d.ts +1 -1
  18. package/src/vaadin-grid-column-reordering-mixin.js +8 -10
  19. package/src/vaadin-grid-column-resizing-mixin.js +6 -5
  20. package/src/vaadin-grid-column.d.ts +1 -1
  21. package/src/vaadin-grid-column.js +54 -40
  22. package/src/vaadin-grid-data-provider-mixin.d.ts +1 -1
  23. package/src/vaadin-grid-data-provider-mixin.js +34 -7
  24. package/src/vaadin-grid-drag-and-drop-mixin.d.ts +1 -1
  25. package/src/vaadin-grid-drag-and-drop-mixin.js +23 -18
  26. package/src/vaadin-grid-dynamic-columns-mixin.js +5 -4
  27. package/src/vaadin-grid-event-context-mixin.d.ts +1 -1
  28. package/src/vaadin-grid-event-context-mixin.js +1 -1
  29. package/src/vaadin-grid-filter-column.d.ts +1 -1
  30. package/src/vaadin-grid-filter-column.js +1 -2
  31. package/src/vaadin-grid-filter-mixin.js +1 -1
  32. package/src/vaadin-grid-filter.d.ts +3 -2
  33. package/src/vaadin-grid-filter.js +27 -22
  34. package/src/vaadin-grid-helpers.js +104 -1
  35. package/src/vaadin-grid-keyboard-navigation-mixin.js +48 -35
  36. package/src/vaadin-grid-row-details-mixin.d.ts +2 -6
  37. package/src/vaadin-grid-row-details-mixin.js +5 -4
  38. package/src/vaadin-grid-scroll-mixin.d.ts +1 -1
  39. package/src/vaadin-grid-scroll-mixin.js +18 -10
  40. package/src/vaadin-grid-selection-column.d.ts +1 -1
  41. package/src/vaadin-grid-selection-column.js +1 -1
  42. package/src/vaadin-grid-selection-mixin.d.ts +1 -1
  43. package/src/vaadin-grid-selection-mixin.js +1 -1
  44. package/src/vaadin-grid-sort-column.d.ts +1 -1
  45. package/src/vaadin-grid-sort-column.js +1 -1
  46. package/src/vaadin-grid-sort-mixin.d.ts +10 -1
  47. package/src/vaadin-grid-sort-mixin.js +22 -6
  48. package/src/vaadin-grid-sorter.d.ts +7 -2
  49. package/src/vaadin-grid-sorter.js +18 -2
  50. package/src/vaadin-grid-styles.js +5 -1
  51. package/src/vaadin-grid-styling-mixin.d.ts +38 -2
  52. package/src/vaadin-grid-styling-mixin.js +78 -6
  53. package/src/vaadin-grid-tree-column.d.ts +1 -8
  54. package/src/vaadin-grid-tree-column.js +2 -25
  55. package/src/vaadin-grid-tree-toggle.d.ts +1 -1
  56. package/src/vaadin-grid-tree-toggle.js +2 -2
  57. package/src/vaadin-grid.d.ts +100 -50
  58. package/src/vaadin-grid.js +198 -105
  59. package/theme/lumo/vaadin-grid-styles.js +14 -14
  60. package/theme/lumo/vaadin-grid.js +0 -7
  61. package/theme/material/vaadin-grid-styles.js +1 -1
  62. package/web-types.json +33 -26
  63. package/web-types.lit.json +18 -11
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import { addValueToAttribute, removeValueFromAttribute } from '@vaadin/component-base/src/dom-utils.js';
@@ -77,6 +77,33 @@ export const KeyboardNavigationMixin = (superClass) =>
77
77
  };
78
78
  }
79
79
 
80
+ /** @private */
81
+ get __rowFocusMode() {
82
+ return (
83
+ this.__isRow(this._itemsFocusable) || this.__isRow(this._headerFocusable) || this.__isRow(this._footerFocusable)
84
+ );
85
+ }
86
+
87
+ set __rowFocusMode(value) {
88
+ ['_itemsFocusable', '_footerFocusable', '_headerFocusable'].forEach((prop) => {
89
+ const focusable = this[prop];
90
+ if (value) {
91
+ const parent = focusable && focusable.parentElement;
92
+ if (this.__isCell(focusable)) {
93
+ // Cell itself focusable (default)
94
+ this[prop] = parent;
95
+ } else if (this.__isCell(parent)) {
96
+ // Focus button mode is enabled for the column,
97
+ // button element inside the cell is focusable.
98
+ this[prop] = parent.parentElement;
99
+ }
100
+ } else if (!value && this.__isRow(focusable)) {
101
+ const cell = focusable.firstElementChild;
102
+ this[prop] = cell._focusButton || cell;
103
+ }
104
+ });
105
+ }
106
+
80
107
  /** @protected */
81
108
  ready() {
82
109
  super.ready();
@@ -108,33 +135,6 @@ export const KeyboardNavigationMixin = (superClass) =>
108
135
  });
109
136
  }
110
137
 
111
- /** @private */
112
- get __rowFocusMode() {
113
- return (
114
- this.__isRow(this._itemsFocusable) || this.__isRow(this._headerFocusable) || this.__isRow(this._footerFocusable)
115
- );
116
- }
117
-
118
- set __rowFocusMode(value) {
119
- ['_itemsFocusable', '_footerFocusable', '_headerFocusable'].forEach((prop) => {
120
- const focusable = this[prop];
121
- if (value) {
122
- const parent = focusable && focusable.parentElement;
123
- if (this.__isCell(focusable)) {
124
- // Cell itself focusable (default)
125
- this[prop] = parent;
126
- } else if (this.__isCell(parent)) {
127
- // Focus button mode is enabled for the column,
128
- // button element inside the cell is focusable.
129
- this[prop] = parent.parentElement;
130
- }
131
- } else if (!value && this.__isRow(focusable)) {
132
- const cell = focusable.firstElementChild;
133
- this[prop] = cell._focusButton || cell;
134
- }
135
- });
136
- }
137
-
138
138
  /** @private */
139
139
  _focusableChanged(focusable, oldFocusable) {
140
140
  if (oldFocusable) {
@@ -300,6 +300,7 @@ export const KeyboardNavigationMixin = (superClass) =>
300
300
  e.preventDefault();
301
301
 
302
302
  const visibleItemsCount = this._lastVisibleIndex - this._firstVisibleIndex - 1;
303
+ const isRTL = this.__isRTL;
303
304
 
304
305
  // Handle keyboard interaction as defined in:
305
306
  // https://w3c.github.io/aria-practices/#keyboard-interaction-24
@@ -308,10 +309,10 @@ export const KeyboardNavigationMixin = (superClass) =>
308
309
  dy = 0;
309
310
  switch (key) {
310
311
  case 'ArrowRight':
311
- dx = this.__isRTL ? -1 : 1;
312
+ dx = isRTL ? -1 : 1;
312
313
  break;
313
314
  case 'ArrowLeft':
314
- dx = this.__isRTL ? 1 : -1;
315
+ dx = isRTL ? 1 : -1;
315
316
  break;
316
317
  case 'Home':
317
318
  if (this.__rowFocusMode) {
@@ -361,8 +362,8 @@ export const KeyboardNavigationMixin = (superClass) =>
361
362
  return;
362
363
  }
363
364
 
364
- const forwardsKey = this.__isRTL ? 'ArrowLeft' : 'ArrowRight';
365
- const backwardsKey = this.__isRTL ? 'ArrowRight' : 'ArrowLeft';
365
+ const forwardsKey = isRTL ? 'ArrowLeft' : 'ArrowRight';
366
+ const backwardsKey = isRTL ? 'ArrowRight' : 'ArrowLeft';
366
367
  if (key === forwardsKey) {
367
368
  // "Right Arrow:"
368
369
  if (this.__rowFocusMode) {
@@ -585,7 +586,7 @@ export const KeyboardNavigationMixin = (superClass) =>
585
586
  const localTarget = e.composedPath()[0];
586
587
  const localTargetIsTextInput =
587
588
  localTarget.localName === 'input' &&
588
- !/^(button|checkbox|color|file|image|radio|range|reset|submit)$/i.test(localTarget.type);
589
+ !/^(button|checkbox|color|file|image|radio|range|reset|submit)$/iu.test(localTarget.type);
589
590
 
590
591
  let wantInteracting;
591
592
  switch (key) {
@@ -723,7 +724,7 @@ export const KeyboardNavigationMixin = (superClass) =>
723
724
 
724
725
  /** @private */
725
726
  _onKeyUp(e) {
726
- if (!/^( |SpaceBar)$/.test(e.key) || this.interacting) {
727
+ if (!/^( |SpaceBar)$/u.test(e.key) || this.interacting) {
727
728
  return;
728
729
  }
729
730
 
@@ -732,7 +733,14 @@ export const KeyboardNavigationMixin = (superClass) =>
732
733
  const cell = e.composedPath()[0];
733
734
  if (cell._content && cell._content.firstElementChild) {
734
735
  const wasNavigating = this.hasAttribute('navigating');
735
- cell._content.firstElementChild.click();
736
+ cell._content.firstElementChild.dispatchEvent(
737
+ new MouseEvent('click', {
738
+ shiftKey: e.shiftKey,
739
+ bubbles: true,
740
+ composed: true,
741
+ cancelable: true,
742
+ }),
743
+ );
736
744
  this.toggleAttribute('navigating', wasNavigating);
737
745
  }
738
746
  }
@@ -773,6 +781,11 @@ export const KeyboardNavigationMixin = (superClass) =>
773
781
  /** @private */
774
782
  _onContentFocusIn(e) {
775
783
  const { section, cell, row } = this._getGridEventLocation(e);
784
+
785
+ if (!cell && !this.__rowFocusMode) {
786
+ return;
787
+ }
788
+
776
789
  this._detectInteracting(e);
777
790
 
778
791
  if (section && (cell || row)) {
@@ -1,16 +1,12 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import type { Constructor } from '@open-wc/dedupe-mixin';
7
7
  import type { Grid, GridItemModel } from './vaadin-grid.js';
8
8
 
9
- export type GridRowDetailsRenderer<TItem> = (
10
- root: HTMLElement,
11
- grid?: Grid<TItem>,
12
- model?: GridItemModel<TItem>,
13
- ) => void;
9
+ export type GridRowDetailsRenderer<TItem> = (root: HTMLElement, grid: Grid<TItem>, model: GridItemModel<TItem>) => void;
14
10
 
15
11
  export declare function RowDetailsMixin<TItem, T extends Constructor<HTMLElement>>(
16
12
  base: T,
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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 { iterateChildren } from './vaadin-grid-helpers.js';
6
7
 
7
8
  /**
8
9
  * @polymerMixin
@@ -78,7 +79,7 @@ export const RowDetailsMixin = (superClass) =>
78
79
 
79
80
  if (this._columnTree) {
80
81
  // Only update the rows if the column tree has already been initialized
81
- Array.from(this.$.items.children).forEach((row) => {
82
+ iterateChildren(this.$.items, (row) => {
82
83
  if (!row.querySelector('[part~=details-cell]')) {
83
84
  this._updateRow(row, this._columnTree[this._columnTree.length - 1]);
84
85
  const isDetailsOpened = this._isDetailsOpened(row._item);
@@ -95,7 +96,7 @@ export const RowDetailsMixin = (superClass) =>
95
96
  return;
96
97
  }
97
98
 
98
- [...this.$.items.children].forEach((row) => {
99
+ iterateChildren(this.$.items, (row) => {
99
100
  // Re-renders the row to possibly close the previously opened details.
100
101
  if (row.hasAttribute('details-opened')) {
101
102
  this._updateItem(row, row._item);
@@ -162,7 +163,7 @@ export const RowDetailsMixin = (superClass) =>
162
163
 
163
164
  /** @protected */
164
165
  _updateDetailsCellHeights() {
165
- [...this.$.items.children].forEach((row) => {
166
+ iterateChildren(this.$.items, (row) => {
166
167
  this._updateDetailsCellHeight(row);
167
168
  });
168
169
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import { animationFrame, microTask, timeOut } from '@vaadin/component-base/src/async.js';
7
7
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
8
+ import { getNormalizedScrollLeft } from '@vaadin/component-base/src/dir-utils.js';
8
9
  import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
9
10
 
10
11
  const timeouts = {
@@ -41,6 +42,11 @@ export const ScrollMixin = (superClass) =>
41
42
  };
42
43
  }
43
44
 
45
+ /** @private */
46
+ get _scrollLeft() {
47
+ return this.$.table.scrollLeft;
48
+ }
49
+
44
50
  /** @private */
45
51
  get _scrollTop() {
46
52
  return this.$.table.scrollTop;
@@ -54,11 +60,6 @@ export const ScrollMixin = (superClass) =>
54
60
  this.$.table.scrollTop = top;
55
61
  }
56
62
 
57
- /** @private */
58
- get _scrollLeft() {
59
- return this.$.table.scrollLeft;
60
- }
61
-
62
63
  /** @protected */
63
64
  ready() {
64
65
  super.ready();
@@ -157,7 +158,7 @@ export const ScrollMixin = (superClass) =>
157
158
  overflow += ' top';
158
159
  }
159
160
 
160
- const scrollLeft = this.__getNormalizedScrollLeft(table);
161
+ const scrollLeft = getNormalizedScrollLeft(table, this.getAttribute('dir'));
161
162
  if (scrollLeft > 0) {
162
163
  overflow += ' start';
163
164
  }
@@ -167,7 +168,7 @@ export const ScrollMixin = (superClass) =>
167
168
  }
168
169
 
169
170
  if (this.__isRTL) {
170
- overflow = overflow.replace(/start|end/gi, (matched) => {
171
+ overflow = overflow.replace(/start|end/giu, (matched) => {
171
172
  return matched === 'start' ? 'end' : 'start';
172
173
  });
173
174
  }
@@ -201,10 +202,17 @@ export const ScrollMixin = (superClass) =>
201
202
  this._frozenToEndCells = Array.prototype.slice.call(this.$.table.querySelectorAll('[frozen-to-end]'));
202
203
  this.__updateHorizontalScrollPosition();
203
204
  });
204
- this._updateFrozenColumn();
205
+ this._debounceUpdateFrozenColumn();
205
206
  }
206
207
 
207
208
  /** @protected */
209
+ _debounceUpdateFrozenColumn() {
210
+ this.__debounceUpdateFrozenColumn = Debouncer.debounce(this.__debounceUpdateFrozenColumn, microTask, () =>
211
+ this._updateFrozenColumn(),
212
+ );
213
+ }
214
+
215
+ /** @private */
208
216
  _updateFrozenColumn() {
209
217
  if (!this._columnTree) {
210
218
  return;
@@ -248,7 +256,7 @@ export const ScrollMixin = (superClass) =>
248
256
  const scrollWidth = this.$.table.scrollWidth;
249
257
  const clientWidth = this.$.table.clientWidth;
250
258
  const scrollLeft = Math.max(0, this.$.table.scrollLeft);
251
- const normalizedScrollLeft = this.__getNormalizedScrollLeft(this.$.table);
259
+ const normalizedScrollLeft = getNormalizedScrollLeft(this.$.table, this.getAttribute('dir'));
252
260
 
253
261
  // Position header, footer and items container
254
262
  const transform = `translate(${-scrollLeft}px, 0)`;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import type { GridDefaultItem } from './vaadin-grid.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import '@vaadin/checkbox/src/vaadin-checkbox.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import type { GridDefaultItem } from './vaadin-grid.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import './vaadin-grid-sorter.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import type { Constructor } from '@open-wc/dedupe-mixin';
@@ -36,4 +36,13 @@ export declare class SortMixinClass {
36
36
  * @attr {string} multi-sort-priority
37
37
  */
38
38
  multiSortPriority: 'append' | 'prepend';
39
+
40
+ /**
41
+ * When `true`, Shift-clicking an unsorted column's sorter adds it to the multi-sort.
42
+ * Shift + Space does the same action via keyboard. This property has precedence over the
43
+ * `multiSort` property. If `multiSortOnShiftClick` is true, the multiSort property is effectively ignored.
44
+ *
45
+ * @attr {boolean} multi-sort-on-shift-click
46
+ */
47
+ multiSortOnShiftClick: boolean;
39
48
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
 
@@ -42,6 +42,19 @@ export const SortMixin = (superClass) =>
42
42
  value: () => defaultMultiSortPriority,
43
43
  },
44
44
 
45
+ /**
46
+ * When `true`, Shift-clicking an unsorted column's sorter adds it to the multi-sort.
47
+ * Shift + Space does the same action via keyboard. This property has precedence over the
48
+ * `multiSort` property. If `multiSortOnShiftClick` is true, the multiSort property is effectively ignored.
49
+ *
50
+ * @attr {boolean} multi-sort-on-shift-click
51
+ * @type {boolean}
52
+ */
53
+ multiSortOnShiftClick: {
54
+ type: Boolean,
55
+ value: false,
56
+ },
57
+
45
58
  /**
46
59
  * @type {!Array<!GridSorterDefinition>}
47
60
  * @protected
@@ -81,7 +94,7 @@ export const SortMixin = (superClass) =>
81
94
  const sorter = e.target;
82
95
  e.stopPropagation();
83
96
  sorter._grid = this;
84
- this.__updateSorter(sorter);
97
+ this.__updateSorter(sorter, e.detail.shiftClick, e.detail.fromSorterClick);
85
98
  this.__applySorters();
86
99
  }
87
100
 
@@ -126,22 +139,25 @@ export const SortMixin = (superClass) =>
126
139
  }
127
140
 
128
141
  /** @private */
129
- __updateSorter(sorter) {
142
+ __updateSorter(sorter, shiftClick, fromSorterClick) {
130
143
  if (!sorter.direction && this._sorters.indexOf(sorter) === -1) {
131
144
  return;
132
145
  }
133
146
 
134
147
  sorter._order = null;
135
148
 
136
- if (this.multiSort) {
149
+ if (
150
+ (this.multiSort && (!this.multiSortOnShiftClick || !fromSorterClick)) ||
151
+ (this.multiSortOnShiftClick && shiftClick)
152
+ ) {
137
153
  if (this.multiSortPriority === 'append') {
138
154
  this.__appendSorter(sorter);
139
155
  } else {
140
156
  this.__prependSorter(sorter);
141
157
  }
142
- } else if (sorter.direction) {
158
+ } else if (sorter.direction || this.multiSortOnShiftClick) {
143
159
  const otherSorters = this._sorters.filter((s) => s !== sorter);
144
- this._sorters = [sorter];
160
+ this._sorters = sorter.direction ? [sorter] : [];
145
161
  otherSorters.forEach((sorter) => {
146
162
  sorter._order = null;
147
163
  sorter.direction = null;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
@@ -8,13 +8,18 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
8
8
 
9
9
  export type GridSorterDirection = 'asc' | 'desc' | null;
10
10
 
11
+ /**
12
+ * Fired when the `path` or `direction` property changes.
13
+ */
14
+ export type GridSorterChangedEvent = CustomEvent<{ shiftClick: boolean; fromSorterClick: boolean }>;
15
+
11
16
  /**
12
17
  * Fired when the `direction` property changes.
13
18
  */
14
19
  export type GridSorterDirectionChangedEvent = CustomEvent<{ value: GridSorterDirection }>;
15
20
 
16
21
  export interface GridSorterCustomEventMap {
17
- 'sorter-changed': Event;
22
+ 'sorter-changed': GridSorterChangedEvent;
18
23
 
19
24
  'direction-changed': GridSorterDirectionChangedEvent;
20
25
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
@@ -202,7 +202,16 @@ class GridSorter extends ThemableMixin(DirMixin(PolymerElement)) {
202
202
  return;
203
203
  }
204
204
 
205
- this.dispatchEvent(new CustomEvent('sorter-changed', { bubbles: true, composed: true }));
205
+ this.dispatchEvent(
206
+ new CustomEvent('sorter-changed', {
207
+ detail: { shiftClick: Boolean(this._shiftClick), fromSorterClick: Boolean(this._fromSorterClick) },
208
+ bubbles: true,
209
+ composed: true,
210
+ }),
211
+ );
212
+ // Cleaning up as a programatically sorting can be done after some user interaction
213
+ this._fromSorterClick = false;
214
+ this._shiftClick = false;
206
215
  }
207
216
 
208
217
  /** @private */
@@ -212,6 +221,11 @@ class GridSorter extends ThemableMixin(DirMixin(PolymerElement)) {
212
221
 
213
222
  /** @private */
214
223
  _onClick(e) {
224
+ if (e.defaultPrevented) {
225
+ // Something else has already handled the click event, do nothing.
226
+ return;
227
+ }
228
+
215
229
  const activeElement = this.getRootNode().activeElement;
216
230
  if (this !== activeElement && this.contains(activeElement)) {
217
231
  // Some focusable content inside the sorter was clicked, do nothing.
@@ -219,6 +233,8 @@ class GridSorter extends ThemableMixin(DirMixin(PolymerElement)) {
219
233
  }
220
234
 
221
235
  e.preventDefault();
236
+ this._shiftClick = e.shiftKey;
237
+ this._fromSorterClick = true;
222
238
  if (this.direction === 'asc') {
223
239
  this.direction = 'desc';
224
240
  } else if (this.direction === 'desc') {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
@@ -248,6 +248,10 @@ registerStyles(
248
248
  transform: none;
249
249
  }
250
250
 
251
+ [first-frozen-to-end] {
252
+ margin-inline-start: auto;
253
+ }
254
+
251
255
  /* Hide resize handle if scrolled to end */
252
256
  :host(:not([overflow~='end'])) [first-frozen-to-end] [part~='resize-handle'] {
253
257
  display: none;
@@ -1,13 +1,18 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
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
6
  import type { Constructor } from '@open-wc/dedupe-mixin';
7
7
  import type { GridItemModel } from './vaadin-grid.js';
8
8
  import type { GridColumn } from './vaadin-grid-column.js';
9
9
 
10
- export type GridCellClassNameGenerator<TItem> = (column: GridColumn<TItem>, model: GridItemModel<TItem>) => string;
10
+ export type GridCellPartNameGenerator<TItem> = (column: GridColumn<TItem>, model: GridItemModel<TItem>) => string;
11
+
12
+ /**
13
+ * @deprecated Use `GridPartCellGenerator` type and `cellPartNameGenerator` API instead.
14
+ */
15
+ export type GridCellClassNameGenerator<TItem> = GridCellPartNameGenerator<TItem>;
11
16
 
12
17
  export declare function StylingMixin<TItem, T extends Constructor<HTMLElement>>(
13
18
  base: T,
@@ -29,14 +34,45 @@ export declare class StylingMixinClass<TItem> {
29
34
  * - `model.expanded` Sublevel toggle state.
30
35
  * - `model.level` Level of the tree represented with a horizontal offset of the toggle button.
31
36
  * - `model.selected` Selected state.
37
+ *
38
+ * @deprecated Use `cellPartNameGenerator` instead.
32
39
  */
33
40
  cellClassNameGenerator: GridCellClassNameGenerator<TItem> | null | undefined;
34
41
 
42
+ /**
43
+ * A function that allows generating CSS `part` names for grid cells in Shadow DOM based
44
+ * on their row and column, for styling from outside using the `::part()` selector.
45
+ *
46
+ * The return value should be the generated part name as a string, or multiple part names
47
+ * separated by whitespace characters.
48
+ *
49
+ * Receives two arguments:
50
+ * - `column` The `<vaadin-grid-column>` element (`undefined` for details-cell).
51
+ * - `model` The object with the properties related with
52
+ * the rendered item, contains:
53
+ * - `model.index` The index of the item.
54
+ * - `model.item` The item.
55
+ * - `model.expanded` Sublevel toggle state.
56
+ * - `model.level` Level of the tree represented with a horizontal offset of the toggle button.
57
+ * - `model.selected` Selected state.
58
+ */
59
+ cellPartNameGenerator: GridCellPartNameGenerator<TItem> | null | undefined;
60
+
35
61
  /**
36
62
  * Runs the `cellClassNameGenerator` for the visible cells.
37
63
  * If the generator depends on varying conditions, you need to
38
64
  * call this function manually in order to update the styles when
39
65
  * the conditions change.
66
+ *
67
+ * @deprecated Use `cellPartNameGenerator` and `generateCellPartNames()` instead.
40
68
  */
41
69
  generateCellClassNames(): void;
70
+
71
+ /**
72
+ * Runs the `cellPastNameGenerator` for the visible cells.
73
+ * If the generator depends on varying conditions, you need to
74
+ * call this function manually in order to update the styles when
75
+ * the conditions change.
76
+ */
77
+ generateCellPartNames(): void;
42
78
  }