@vaadin/grid 23.3.3 → 24.0.0-alpha10
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 +10 -10
- package/src/all-imports.js +1 -1
- package/src/array-data-provider.js +1 -1
- package/src/lit/column-renderer-directives.d.ts +1 -1
- package/src/lit/column-renderer-directives.js +1 -1
- package/src/lit/renderer-directives.d.ts +1 -1
- package/src/lit/renderer-directives.js +1 -1
- package/src/vaadin-grid-a11y-mixin.js +12 -9
- package/src/vaadin-grid-active-item-mixin.d.ts +1 -1
- package/src/vaadin-grid-active-item-mixin.js +5 -3
- package/src/vaadin-grid-array-data-provider-mixin.d.ts +1 -1
- package/src/vaadin-grid-array-data-provider-mixin.js +1 -1
- package/src/vaadin-grid-column-group.d.ts +1 -1
- package/src/vaadin-grid-column-group.js +17 -17
- package/src/vaadin-grid-column-reordering-mixin.d.ts +1 -1
- package/src/vaadin-grid-column-reordering-mixin.js +7 -9
- package/src/vaadin-grid-column-resizing-mixin.js +6 -5
- package/src/vaadin-grid-column.d.ts +1 -1
- package/src/vaadin-grid-column.js +48 -34
- package/src/vaadin-grid-data-provider-mixin.d.ts +1 -1
- package/src/vaadin-grid-data-provider-mixin.js +33 -7
- package/src/vaadin-grid-drag-and-drop-mixin.d.ts +1 -1
- package/src/vaadin-grid-drag-and-drop-mixin.js +23 -18
- package/src/vaadin-grid-dynamic-columns-mixin.js +5 -4
- package/src/vaadin-grid-event-context-mixin.d.ts +1 -1
- package/src/vaadin-grid-event-context-mixin.js +1 -1
- package/src/vaadin-grid-filter-column.d.ts +1 -1
- package/src/vaadin-grid-filter-column.js +1 -2
- package/src/vaadin-grid-filter-mixin.js +1 -1
- package/src/vaadin-grid-filter.d.ts +3 -2
- package/src/vaadin-grid-filter.js +27 -22
- package/src/vaadin-grid-helpers.js +104 -1
- package/src/vaadin-grid-keyboard-navigation-mixin.js +35 -34
- package/src/vaadin-grid-row-details-mixin.d.ts +1 -1
- package/src/vaadin-grid-row-details-mixin.js +5 -4
- package/src/vaadin-grid-scroll-mixin.d.ts +1 -1
- package/src/vaadin-grid-scroll-mixin.js +10 -9
- package/src/vaadin-grid-selection-column.d.ts +1 -1
- package/src/vaadin-grid-selection-column.js +1 -1
- package/src/vaadin-grid-selection-mixin.d.ts +1 -1
- package/src/vaadin-grid-selection-mixin.js +1 -1
- package/src/vaadin-grid-sort-column.d.ts +1 -1
- package/src/vaadin-grid-sort-column.js +1 -1
- package/src/vaadin-grid-sort-mixin.d.ts +1 -1
- package/src/vaadin-grid-sort-mixin.js +1 -1
- package/src/vaadin-grid-sorter.d.ts +1 -1
- package/src/vaadin-grid-sorter.js +1 -1
- package/src/vaadin-grid-styles.js +1 -1
- package/src/vaadin-grid-styling-mixin.d.ts +38 -2
- package/src/vaadin-grid-styling-mixin.js +77 -6
- package/src/vaadin-grid-tree-column.d.ts +1 -8
- package/src/vaadin-grid-tree-column.js +2 -25
- package/src/vaadin-grid-tree-toggle.d.ts +1 -1
- package/src/vaadin-grid-tree-toggle.js +1 -1
- package/src/vaadin-grid.d.ts +57 -25
- package/src/vaadin-grid.js +131 -79
- package/theme/lumo/vaadin-grid-styles.js +14 -14
- package/theme/material/vaadin-grid-styles.js +1 -1
- package/web-types.json +15 -26
- package/web-types.lit.json +11 -11
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2016 -
|
|
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, updateRowStates } from './vaadin-grid-helpers.js';
|
|
7
|
+
|
|
6
8
|
const DropMode = {
|
|
7
9
|
BETWEEN: 'between',
|
|
8
10
|
ON_TOP: 'on-top',
|
|
@@ -126,7 +128,7 @@ export const DragAndDropMixin = (superClass) =>
|
|
|
126
128
|
// Safari doesn't position drag images from transformed
|
|
127
129
|
// elements properly so we need to switch to use top temporarily
|
|
128
130
|
const transform = row.style.transform;
|
|
129
|
-
row.style.top = /translateY\((.*)\)
|
|
131
|
+
row.style.top = /translateY\((.*)\)/u.exec(transform)[1];
|
|
130
132
|
row.style.transform = 'none';
|
|
131
133
|
requestAnimationFrame(() => {
|
|
132
134
|
row.style.top = '';
|
|
@@ -154,13 +156,14 @@ export const DragAndDropMixin = (superClass) =>
|
|
|
154
156
|
// Set the default transfer data
|
|
155
157
|
e.dataTransfer.setData('text', this.__formatDefaultTransferData(rows));
|
|
156
158
|
|
|
157
|
-
row
|
|
159
|
+
updateRowStates(row, { dragstart: rows.length > 1 ? `${rows.length}` : '' });
|
|
158
160
|
this.style.setProperty('--_grid-drag-start-x', `${e.clientX - rowRect.left + 20}px`);
|
|
159
161
|
this.style.setProperty('--_grid-drag-start-y', `${e.clientY - rowRect.top + 10}px`);
|
|
160
162
|
|
|
161
163
|
requestAnimationFrame(() => {
|
|
162
|
-
row
|
|
163
|
-
this.
|
|
164
|
+
updateRowStates(row, { dragstart: null });
|
|
165
|
+
this.style.setProperty('--_grid-drag-start-x', '');
|
|
166
|
+
this.style.setProperty('--_grid-drag-start-y', '');
|
|
164
167
|
});
|
|
165
168
|
|
|
166
169
|
const event = new CustomEvent('grid-dragstart', {
|
|
@@ -252,7 +255,7 @@ export const DragAndDropMixin = (superClass) =>
|
|
|
252
255
|
} else if (row) {
|
|
253
256
|
this._dragOverItem = row._item;
|
|
254
257
|
if (row.getAttribute('dragover') !== this._dropLocation) {
|
|
255
|
-
row
|
|
258
|
+
updateRowStates(row, { dragover: this._dropLocation }, true);
|
|
256
259
|
}
|
|
257
260
|
} else {
|
|
258
261
|
this._clearDragStyles();
|
|
@@ -306,7 +309,9 @@ export const DragAndDropMixin = (superClass) =>
|
|
|
306
309
|
/** @protected */
|
|
307
310
|
_clearDragStyles() {
|
|
308
311
|
this.removeAttribute('dragover');
|
|
309
|
-
|
|
312
|
+
iterateChildren(this.$.items, (row) => {
|
|
313
|
+
updateRowStates(row, { dragover: null }, true);
|
|
314
|
+
});
|
|
310
315
|
}
|
|
311
316
|
|
|
312
317
|
/** @private */
|
|
@@ -368,11 +373,11 @@ export const DragAndDropMixin = (superClass) =>
|
|
|
368
373
|
* the conditions change.
|
|
369
374
|
*/
|
|
370
375
|
filterDragAndDrop() {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
.forEach((row) => {
|
|
376
|
+
iterateChildren(this.$.items, (row) => {
|
|
377
|
+
if (!row.hidden) {
|
|
374
378
|
this._filterDragAndDrop(row, this.__getRowModel(row));
|
|
375
|
-
}
|
|
379
|
+
}
|
|
380
|
+
});
|
|
376
381
|
}
|
|
377
382
|
|
|
378
383
|
/**
|
|
@@ -385,18 +390,18 @@ export const DragAndDropMixin = (superClass) =>
|
|
|
385
390
|
const dragDisabled = !this.rowsDraggable || loading || (this.dragFilter && !this.dragFilter(model));
|
|
386
391
|
const dropDisabled = !this.dropMode || loading || (this.dropFilter && !this.dropFilter(model));
|
|
387
392
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
draggableElements.forEach((e) => {
|
|
393
|
+
iterateChildren(row, (cell) => {
|
|
391
394
|
if (dragDisabled) {
|
|
392
|
-
|
|
395
|
+
cell._content.removeAttribute('draggable');
|
|
393
396
|
} else {
|
|
394
|
-
|
|
397
|
+
cell._content.setAttribute('draggable', true);
|
|
395
398
|
}
|
|
396
399
|
});
|
|
397
400
|
|
|
398
|
-
row
|
|
399
|
-
|
|
401
|
+
updateRowStates(row, {
|
|
402
|
+
'drag-disabled': !!dragDisabled,
|
|
403
|
+
'drop-disabled': !!dropDisabled,
|
|
404
|
+
});
|
|
400
405
|
}
|
|
401
406
|
|
|
402
407
|
/**
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2016 -
|
|
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 { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
|
|
7
7
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
8
8
|
import { timeOut } from '@vaadin/component-base/src/async.js';
|
|
9
9
|
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
10
|
+
import { updateCellState } from './vaadin-grid-helpers.js';
|
|
10
11
|
|
|
11
12
|
function arrayEquals(arr1, arr2) {
|
|
12
13
|
if (!arr1 || !arr2 || arr1.length !== arr2.length) {
|
|
@@ -160,8 +161,8 @@ export const DynamicColumnsMixin = (superClass) =>
|
|
|
160
161
|
return a._column._order - b._column._order;
|
|
161
162
|
})
|
|
162
163
|
.forEach((cell, cellIndex, children) => {
|
|
163
|
-
cell
|
|
164
|
-
cell
|
|
164
|
+
updateCellState(cell, 'first-column', cellIndex === 0);
|
|
165
|
+
updateCellState(cell, 'last-column', cellIndex === children.length - 1);
|
|
165
166
|
});
|
|
166
167
|
}
|
|
167
168
|
|
|
@@ -171,6 +172,6 @@ export const DynamicColumnsMixin = (superClass) =>
|
|
|
171
172
|
* @protected
|
|
172
173
|
*/
|
|
173
174
|
_isColumnElement(node) {
|
|
174
|
-
return node.nodeType === Node.ELEMENT_NODE && /\bcolumn\b
|
|
175
|
+
return node.nodeType === Node.ELEMENT_NODE && /\bcolumn\b/u.test(node.localName);
|
|
175
176
|
}
|
|
176
177
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2016 -
|
|
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 -
|
|
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 -
|
|
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-filter.js';
|
|
@@ -60,7 +60,6 @@ class GridFilterColumn extends GridColumn {
|
|
|
60
60
|
if (!filter) {
|
|
61
61
|
filter = document.createElement('vaadin-grid-filter');
|
|
62
62
|
textField = document.createElement('vaadin-text-field');
|
|
63
|
-
textField.setAttribute('slot', 'filter');
|
|
64
63
|
textField.setAttribute('theme', 'small');
|
|
65
64
|
textField.setAttribute('style', 'max-width: 100%;');
|
|
66
65
|
textField.setAttribute('focus-target', '');
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2016 -
|
|
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 { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Fired when the `value` property changes.
|
|
@@ -40,7 +41,7 @@ export interface GridFilterEventMap extends HTMLElementEventMap, GridFilterCusto
|
|
|
40
41
|
*
|
|
41
42
|
* @fires {CustomEvent} value-changed - Fired when the `value` property changes.
|
|
42
43
|
*/
|
|
43
|
-
declare class GridFilter extends HTMLElement {
|
|
44
|
+
declare class GridFilter extends ControllerMixin(HTMLElement) {
|
|
44
45
|
/**
|
|
45
46
|
* JS Path of the property in the item used for filtering the data.
|
|
46
47
|
*/
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2016 -
|
|
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/text-field/src/vaadin-text-field.js';
|
|
7
7
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
8
8
|
import { timeOut } from '@vaadin/component-base/src/async.js';
|
|
9
|
+
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
9
10
|
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
11
|
+
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* `<vaadin-grid-filter>` is a helper element for the `<vaadin-grid>` that provides out-of-the-box UI controls,
|
|
@@ -35,7 +37,7 @@ import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
|
35
37
|
*
|
|
36
38
|
* @extends HTMLElement
|
|
37
39
|
*/
|
|
38
|
-
class GridFilter extends
|
|
40
|
+
class GridFilter extends ControllerMixin(PolymerElement) {
|
|
39
41
|
static get template() {
|
|
40
42
|
return html`
|
|
41
43
|
<style>
|
|
@@ -44,14 +46,12 @@ class GridFilter extends class extends PolymerElement {} {
|
|
|
44
46
|
max-width: 100%;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
::slotted(*) {
|
|
48
50
|
width: 100%;
|
|
49
51
|
box-sizing: border-box;
|
|
50
52
|
}
|
|
51
53
|
</style>
|
|
52
|
-
<slot
|
|
53
|
-
<vaadin-text-field id="filter" value="{{value}}"></vaadin-text-field>
|
|
54
|
-
</slot>
|
|
54
|
+
<slot></slot>
|
|
55
55
|
`;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -75,39 +75,42 @@ class GridFilter extends class extends PolymerElement {} {
|
|
|
75
75
|
},
|
|
76
76
|
|
|
77
77
|
/** @private */
|
|
78
|
-
|
|
78
|
+
_textField: {
|
|
79
|
+
type: Object,
|
|
80
|
+
},
|
|
79
81
|
};
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
/** @protected */
|
|
83
|
-
connectedCallback() {
|
|
84
|
-
super.connectedCallback();
|
|
85
|
-
this._connected = true;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
84
|
static get observers() {
|
|
89
|
-
return ['_filterChanged(path, value,
|
|
85
|
+
return ['_filterChanged(path, value, _textField)'];
|
|
90
86
|
}
|
|
91
87
|
|
|
92
88
|
/** @protected */
|
|
93
89
|
ready() {
|
|
94
90
|
super.ready();
|
|
95
91
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
92
|
+
this._filterController = new SlotController(this, '', 'vaadin-text-field', {
|
|
93
|
+
initializer: (field) => {
|
|
94
|
+
field.addEventListener('value-changed', (e) => {
|
|
95
|
+
this.value = e.detail.value;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
this._textField = field;
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
this.addController(this._filterController);
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
/** @private */
|
|
104
|
-
_filterChanged(path, value,
|
|
105
|
-
if (path === undefined || value === undefined || !
|
|
105
|
+
_filterChanged(path, value, textField) {
|
|
106
|
+
if (path === undefined || value === undefined || !textField) {
|
|
106
107
|
return;
|
|
107
108
|
}
|
|
108
109
|
if (this._previousValue === undefined && value === '') {
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
112
|
+
|
|
113
|
+
textField.value = value;
|
|
111
114
|
this._previousValue = value;
|
|
112
115
|
|
|
113
116
|
this._debouncerFilterChanged = Debouncer.debounce(this._debouncerFilterChanged, timeOut.after(200), () => {
|
|
@@ -116,7 +119,9 @@ class GridFilter extends class extends PolymerElement {} {
|
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
focus() {
|
|
119
|
-
this
|
|
122
|
+
if (this._textField) {
|
|
123
|
+
this._textField.focus();
|
|
124
|
+
}
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
|
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2016 -
|
|
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 { addValueToAttribute, removeValueFromAttribute } from '@vaadin/component-base/src/dom-utils.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {HTMLTableRowElement} row the table row
|
|
10
|
+
* @return {HTMLTableCellElement[]} array of cells
|
|
11
|
+
*/
|
|
12
|
+
export function getBodyRowCells(row) {
|
|
13
|
+
return Array.from(row.querySelectorAll('[part~="cell"]:not([part~="details-cell"])'));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {HTMLElement} container the DOM element with children
|
|
18
|
+
* @param {Function} callback function to call on each child
|
|
19
|
+
*/
|
|
20
|
+
export function iterateChildren(container, callback) {
|
|
21
|
+
[...container.children].forEach(callback);
|
|
22
|
+
}
|
|
6
23
|
|
|
7
24
|
/**
|
|
8
25
|
* @param {Array<Object>} columns array of columns to be modified
|
|
@@ -21,3 +38,89 @@ export function updateColumnOrders(columns, scope, baseOrder) {
|
|
|
21
38
|
c += 1;
|
|
22
39
|
});
|
|
23
40
|
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {!HTMLElement} element
|
|
44
|
+
* @param {string} attribute
|
|
45
|
+
* @param {boolean | string | null | undefined} value
|
|
46
|
+
*/
|
|
47
|
+
export function updateState(element, attribute, value) {
|
|
48
|
+
switch (typeof value) {
|
|
49
|
+
case 'boolean':
|
|
50
|
+
element.toggleAttribute(attribute, value);
|
|
51
|
+
break;
|
|
52
|
+
case 'string':
|
|
53
|
+
element.setAttribute(attribute, value);
|
|
54
|
+
break;
|
|
55
|
+
default:
|
|
56
|
+
// Value set to null / undefined
|
|
57
|
+
element.removeAttribute(attribute);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {!HTMLElement} element
|
|
64
|
+
* @param {boolean | string | null | undefined} value
|
|
65
|
+
* @param {string} part
|
|
66
|
+
*/
|
|
67
|
+
export function updatePart(element, value, part) {
|
|
68
|
+
if (value || value === '') {
|
|
69
|
+
addValueToAttribute(element, 'part', part);
|
|
70
|
+
} else {
|
|
71
|
+
removeValueFromAttribute(element, 'part', part);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {HTMLTableCellElement[]} cells
|
|
77
|
+
* @param {string} part
|
|
78
|
+
* @param {boolean | string | null | undefined} value
|
|
79
|
+
*/
|
|
80
|
+
export function updateCellsPart(cells, part, value) {
|
|
81
|
+
cells.forEach((cell) => {
|
|
82
|
+
updatePart(cell, value, part);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {!HTMLElement} row
|
|
88
|
+
* @param {Object} states
|
|
89
|
+
* @param {boolean} appendValue
|
|
90
|
+
*/
|
|
91
|
+
export function updateRowStates(row, states, appendValue) {
|
|
92
|
+
const cells = getBodyRowCells(row);
|
|
93
|
+
|
|
94
|
+
Object.entries(states).forEach(([state, value]) => {
|
|
95
|
+
// Row state attribute
|
|
96
|
+
updateState(row, state, value);
|
|
97
|
+
|
|
98
|
+
const rowPart = appendValue ? `${state}-${value}-row` : `${state}-row`;
|
|
99
|
+
|
|
100
|
+
// Row part attribute
|
|
101
|
+
updatePart(row, value, rowPart);
|
|
102
|
+
|
|
103
|
+
// Cells part attribute
|
|
104
|
+
updateCellsPart(cells, `${rowPart}-cell`, value);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @param {!HTMLElement} cell
|
|
110
|
+
* @param {string} attribute
|
|
111
|
+
* @param {boolean | string | null | undefined} value
|
|
112
|
+
* @param {string} part
|
|
113
|
+
* @param {?string} oldPart
|
|
114
|
+
*/
|
|
115
|
+
export function updateCellState(cell, attribute, value, part, oldPart) {
|
|
116
|
+
// Toggle state attribute on the cell
|
|
117
|
+
updateState(cell, attribute, value);
|
|
118
|
+
|
|
119
|
+
// Remove old part from the attribute
|
|
120
|
+
if (oldPart) {
|
|
121
|
+
updatePart(cell, false, oldPart);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Add new part to the cell attribute
|
|
125
|
+
updatePart(cell, value, part || `${attribute}-cell`);
|
|
126
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2016 -
|
|
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 =
|
|
312
|
+
dx = isRTL ? -1 : 1;
|
|
312
313
|
break;
|
|
313
314
|
case 'ArrowLeft':
|
|
314
|
-
dx =
|
|
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 =
|
|
365
|
-
const backwardsKey =
|
|
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)$/
|
|
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)
|
|
727
|
+
if (!/^( |SpaceBar)$/u.test(e.key) || this.interacting) {
|
|
727
728
|
return;
|
|
728
729
|
}
|
|
729
730
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2016 -
|
|
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,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2016 -
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 -
|
|
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 -
|
|
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.
|
|
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/
|
|
171
|
+
overflow = overflow.replace(/start|end/giu, (matched) => {
|
|
171
172
|
return matched === 'start' ? 'end' : 'start';
|
|
172
173
|
});
|
|
173
174
|
}
|
|
@@ -255,7 +256,7 @@ export const ScrollMixin = (superClass) =>
|
|
|
255
256
|
const scrollWidth = this.$.table.scrollWidth;
|
|
256
257
|
const clientWidth = this.$.table.clientWidth;
|
|
257
258
|
const scrollLeft = Math.max(0, this.$.table.scrollLeft);
|
|
258
|
-
const normalizedScrollLeft =
|
|
259
|
+
const normalizedScrollLeft = getNormalizedScrollLeft(this.$.table, this.getAttribute('dir'));
|
|
259
260
|
|
|
260
261
|
// Position header, footer and items container
|
|
261
262
|
const transform = `translate(${-scrollLeft}px, 0)`;
|