@vaadin/grid 23.1.0-alpha4 → 23.1.0-beta3
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/lit.d.ts +2 -0
- package/lit.js +2 -0
- package/package.json +12 -9
- package/src/array-data-provider.js +2 -2
- package/src/lit/column-renderer-directives.d.ts +152 -0
- package/src/lit/column-renderer-directives.js +149 -0
- package/src/lit/renderer-directives.d.ts +62 -0
- package/src/lit/renderer-directives.js +70 -0
- package/src/vaadin-grid-column-group.js +35 -32
- package/src/vaadin-grid-column-reordering-mixin.js +2 -2
- package/src/vaadin-grid-column.js +1 -1
- package/src/vaadin-grid-data-provider-mixin.js +3 -3
- package/src/vaadin-grid-dynamic-columns-mixin.js +1 -1
- package/src/vaadin-grid-filter-mixin.js +1 -3
- package/src/vaadin-grid-helpers.js +1 -1
- package/src/vaadin-grid-keyboard-navigation-mixin.js +6 -3
- package/src/vaadin-grid-row-details-mixin.js +1 -3
- package/src/vaadin-grid-scroll-mixin.js +0 -3
- package/src/vaadin-grid-selection-column.js +1 -1
- package/src/vaadin-grid-selection-mixin.js +19 -5
- package/src/vaadin-grid-sort-mixin.js +2 -6
- package/src/vaadin-grid-styling-mixin.js +1 -1
- package/src/vaadin-grid.d.ts +2 -2
- package/src/vaadin-grid.js +5 -4
package/lit.d.ts
ADDED
package/lit.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/grid",
|
|
3
|
-
"version": "23.1.0-
|
|
3
|
+
"version": "23.1.0-beta3",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
"all-imports.js",
|
|
24
24
|
"src",
|
|
25
25
|
"theme",
|
|
26
|
+
"lit.js",
|
|
27
|
+
"lit.d.ts",
|
|
26
28
|
"vaadin-*.d.ts",
|
|
27
29
|
"vaadin-*.js"
|
|
28
30
|
],
|
|
@@ -41,19 +43,20 @@
|
|
|
41
43
|
"dependencies": {
|
|
42
44
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
43
45
|
"@polymer/polymer": "^3.0.0",
|
|
44
|
-
"@vaadin/checkbox": "23.1.0-
|
|
45
|
-
"@vaadin/component-base": "23.1.0-
|
|
46
|
-
"@vaadin/
|
|
47
|
-
"@vaadin/
|
|
48
|
-
"@vaadin/vaadin-
|
|
49
|
-
"@vaadin/vaadin-
|
|
46
|
+
"@vaadin/checkbox": "23.1.0-beta3",
|
|
47
|
+
"@vaadin/component-base": "23.1.0-beta3",
|
|
48
|
+
"@vaadin/lit-renderer": "23.1.0-beta3",
|
|
49
|
+
"@vaadin/text-field": "23.1.0-beta3",
|
|
50
|
+
"@vaadin/vaadin-lumo-styles": "23.1.0-beta3",
|
|
51
|
+
"@vaadin/vaadin-material-styles": "23.1.0-beta3",
|
|
52
|
+
"@vaadin/vaadin-themable-mixin": "23.1.0-beta3"
|
|
50
53
|
},
|
|
51
54
|
"devDependencies": {
|
|
52
55
|
"@esm-bundle/chai": "^4.3.4",
|
|
53
|
-
"@vaadin/polymer-legacy-adapter": "23.1.0-
|
|
56
|
+
"@vaadin/polymer-legacy-adapter": "23.1.0-beta3",
|
|
54
57
|
"@vaadin/testing-helpers": "^0.3.2",
|
|
55
58
|
"lit": "^2.0.0",
|
|
56
59
|
"sinon": "^13.0.2"
|
|
57
60
|
},
|
|
58
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "c787ceb8a312f88631c6d429ff320d5f89b1b838"
|
|
59
62
|
}
|
|
@@ -25,12 +25,12 @@ function checkPaths(arrayToCheck, action, items) {
|
|
|
25
25
|
for (const i in arrayToCheck) {
|
|
26
26
|
const path = arrayToCheck[i].path;
|
|
27
27
|
|
|
28
|
-
//
|
|
28
|
+
// Skip simple paths
|
|
29
29
|
if (!path || path.indexOf('.') === -1) {
|
|
30
30
|
continue;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const parentProperty = path.replace(/\.[^.]*$/, ''); //
|
|
33
|
+
const parentProperty = path.replace(/\.[^.]*$/, ''); // A.b.c -> a.b
|
|
34
34
|
if (get(parentProperty, items[0]) === undefined) {
|
|
35
35
|
console.warn(`Path "${path}" used for ${action} does not exist in all of the items, ${action} is disabled.`);
|
|
36
36
|
result = false;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
/* eslint-disable max-classes-per-file */
|
|
7
|
+
import { TemplateResult } from 'lit';
|
|
8
|
+
import { DirectiveResult } from 'lit/directive';
|
|
9
|
+
import { LitRenderer, LitRendererDirective } from '@vaadin/lit-renderer';
|
|
10
|
+
import { GridItemModel } from '../vaadin-grid.js';
|
|
11
|
+
import { GridColumn } from '../vaadin-grid-column.js';
|
|
12
|
+
|
|
13
|
+
export type GridColumnBodyLitRenderer<TItem> = (
|
|
14
|
+
item: TItem,
|
|
15
|
+
model: GridItemModel<TItem>,
|
|
16
|
+
column: GridColumn,
|
|
17
|
+
) => TemplateResult;
|
|
18
|
+
|
|
19
|
+
export type GridColumnHeaderLitRenderer = (column: GridColumn) => TemplateResult;
|
|
20
|
+
export type GridColumnFooterLitRenderer = (column: GridColumn) => TemplateResult;
|
|
21
|
+
|
|
22
|
+
declare abstract class AbstractGridColumnRendererDirective<R extends LitRenderer> extends LitRendererDirective<
|
|
23
|
+
GridColumn,
|
|
24
|
+
R
|
|
25
|
+
> {
|
|
26
|
+
/**
|
|
27
|
+
* A property to that the renderer callback will be assigned.
|
|
28
|
+
*/
|
|
29
|
+
abstract rendererProperty: 'renderer' | 'headerRenderer' | 'footerRenderer';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Adds the renderer callback to the grid column.
|
|
33
|
+
*/
|
|
34
|
+
addRenderer(): void;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Runs the renderer callback on the grid column.
|
|
38
|
+
*/
|
|
39
|
+
runRenderer(): void;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Removes the renderer callback from the grid column.
|
|
43
|
+
*/
|
|
44
|
+
removeRenderer(): void;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export declare class GridColumnBodyRendererDirective<TItem> extends AbstractGridColumnRendererDirective<
|
|
48
|
+
GridColumnBodyLitRenderer<TItem>
|
|
49
|
+
> {
|
|
50
|
+
rendererProperty: 'renderer';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export declare class GridColumnHeaderRendererDirective extends AbstractGridColumnRendererDirective<GridColumnHeaderLitRenderer> {
|
|
54
|
+
rendererProperty: 'headerRenderer';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export declare class GridColumnFooterRendererDirective extends AbstractGridColumnRendererDirective<GridColumnFooterLitRenderer> {
|
|
58
|
+
rendererProperty: 'footerRenderer';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* A Lit directive for rendering the content of the column's body cells.
|
|
63
|
+
*
|
|
64
|
+
* The directive accepts a renderer callback returning a Lit template and assigns it to the grid column
|
|
65
|
+
* via the `renderer` property. The renderer is called for each column's body cell when assigned and whenever
|
|
66
|
+
* a single dependency or an array of dependencies changes.
|
|
67
|
+
* It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
|
|
68
|
+
*
|
|
69
|
+
* Dependencies can be a single value or an array of values.
|
|
70
|
+
* Values are checked against previous values with strict equality (`===`),
|
|
71
|
+
* so the check won't detect nested property changes inside objects or arrays.
|
|
72
|
+
* When dependencies are provided as an array, each item is checked against the previous value
|
|
73
|
+
* at the same index with strict equality. Nested arrays are also checked only by strict
|
|
74
|
+
* equality.
|
|
75
|
+
*
|
|
76
|
+
* Example of usage:
|
|
77
|
+
* ```js
|
|
78
|
+
* `<vaadin-grid-column
|
|
79
|
+
* ${columnBodyRenderer((item, model, column) => html`...`)}
|
|
80
|
+
* ></vaadin-grid-column>`
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @param renderer the renderer callback.
|
|
84
|
+
* @param dependencies a single dependency or an array of dependencies
|
|
85
|
+
* which trigger a re-render when changed.
|
|
86
|
+
*/
|
|
87
|
+
export declare function columnBodyRenderer<TItem>(
|
|
88
|
+
renderer: GridColumnBodyLitRenderer<TItem>,
|
|
89
|
+
dependencies?: unknown,
|
|
90
|
+
): DirectiveResult<typeof GridColumnBodyRendererDirective>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* A Lit directive for rendering the content of the column's header cell.
|
|
94
|
+
*
|
|
95
|
+
* The directive accepts a renderer callback returning a Lit template and assigns it to the grid column
|
|
96
|
+
* via the `headerRenderer` property. The renderer is called once when assigned and whenever
|
|
97
|
+
* a single dependency or an array of dependencies changes.
|
|
98
|
+
* It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
|
|
99
|
+
*
|
|
100
|
+
* Dependencies can be a single value or an array of values.
|
|
101
|
+
* Values are checked against previous values with strict equality (`===`),
|
|
102
|
+
* so the check won't detect nested property changes inside objects or arrays.
|
|
103
|
+
* When dependencies are provided as an array, each item is checked against the previous value
|
|
104
|
+
* at the same index with strict equality. Nested arrays are also checked only by strict
|
|
105
|
+
* equality.
|
|
106
|
+
*
|
|
107
|
+
* Example of usage:
|
|
108
|
+
* ```js
|
|
109
|
+
* `<vaadin-grid-column
|
|
110
|
+
* ${columnHeaderRenderer((column) => html`...`)}
|
|
111
|
+
* ></vaadin-grid-column>`
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* @param renderer the renderer callback.
|
|
115
|
+
* @param dependencies a single dependency or an array of dependencies
|
|
116
|
+
* which trigger a re-render when changed.
|
|
117
|
+
*/
|
|
118
|
+
export declare function columnHeaderRenderer(
|
|
119
|
+
renderer: GridColumnHeaderLitRenderer,
|
|
120
|
+
dependencies?: unknown,
|
|
121
|
+
): DirectiveResult<typeof GridColumnHeaderRendererDirective>;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* A Lit directive for rendering the content of the column's footer cell.
|
|
125
|
+
*
|
|
126
|
+
* The directive accepts a renderer callback returning a Lit template and assigns it to the grid column
|
|
127
|
+
* via the `footerRenderer` property. The renderer is called once when assigned and whenever
|
|
128
|
+
* a single dependency or an array of dependencies changes.
|
|
129
|
+
* It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
|
|
130
|
+
*
|
|
131
|
+
* Dependencies can be a single value or an array of values.
|
|
132
|
+
* Values are checked against previous values with strict equality (`===`),
|
|
133
|
+
* so the check won't detect nested property changes inside objects or arrays.
|
|
134
|
+
* When dependencies are provided as an array, each item is checked against the previous value
|
|
135
|
+
* at the same index with strict equality. Nested arrays are also checked only by strict
|
|
136
|
+
* equality.
|
|
137
|
+
*
|
|
138
|
+
* Example of usage:
|
|
139
|
+
* ```js
|
|
140
|
+
* `<vaadin-grid-column
|
|
141
|
+
* ${columnFooterRenderer((column) => html`...`)}
|
|
142
|
+
* ></vaadin-grid-column>`
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @param renderer the renderer callback.
|
|
146
|
+
* @param dependencies a single dependency or an array of dependencies
|
|
147
|
+
* which trigger a re-render when changed.
|
|
148
|
+
*/
|
|
149
|
+
export declare function columnFooterRenderer(
|
|
150
|
+
renderer: GridColumnFooterLitRenderer,
|
|
151
|
+
dependencies?: unknown,
|
|
152
|
+
): DirectiveResult<typeof GridColumnFooterRendererDirective>;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
/* eslint-disable max-classes-per-file */
|
|
7
|
+
import { directive } from 'lit/directive.js';
|
|
8
|
+
import { microTask } from '@vaadin/component-base/src/async.js';
|
|
9
|
+
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
10
|
+
import { LitRendererDirective } from '@vaadin/lit-renderer';
|
|
11
|
+
import { CONTENT_UPDATE_DEBOUNCER } from './renderer-directives.js';
|
|
12
|
+
|
|
13
|
+
class AbstractGridColumnRendererDirective extends LitRendererDirective {
|
|
14
|
+
/**
|
|
15
|
+
* A property to that the renderer callback will be assigned.
|
|
16
|
+
*
|
|
17
|
+
* @abstract
|
|
18
|
+
*/
|
|
19
|
+
rendererProperty;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Adds the renderer callback to the grid column.
|
|
23
|
+
*/
|
|
24
|
+
addRenderer() {
|
|
25
|
+
this.element[this.rendererProperty] = (root, column) => {
|
|
26
|
+
this.renderRenderer(root, column);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Runs the renderer callback on the grid column.
|
|
32
|
+
*/
|
|
33
|
+
runRenderer() {
|
|
34
|
+
const grid = this.element._grid;
|
|
35
|
+
|
|
36
|
+
grid[CONTENT_UPDATE_DEBOUNCER] = Debouncer.debounce(grid[CONTENT_UPDATE_DEBOUNCER], microTask, () => {
|
|
37
|
+
grid.requestContentUpdate();
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Removes the renderer callback from the grid column.
|
|
43
|
+
*/
|
|
44
|
+
removeRenderer() {
|
|
45
|
+
this.element[this.rendererProperty] = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export class GridColumnBodyRendererDirective extends AbstractGridColumnRendererDirective {
|
|
50
|
+
rendererProperty = 'renderer';
|
|
51
|
+
|
|
52
|
+
addRenderer() {
|
|
53
|
+
this.element[this.rendererProperty] = (root, column, model) => {
|
|
54
|
+
this.renderRenderer(root, model.item, model, column);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export class GridColumnHeaderRendererDirective extends AbstractGridColumnRendererDirective {
|
|
60
|
+
rendererProperty = 'headerRenderer';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class GridColumnFooterRendererDirective extends AbstractGridColumnRendererDirective {
|
|
64
|
+
rendererProperty = 'footerRenderer';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A Lit directive for rendering the content of the column's body cells.
|
|
69
|
+
*
|
|
70
|
+
* The directive accepts a renderer callback returning a Lit template and assigns it to the grid column
|
|
71
|
+
* via the `renderer` property. The renderer is called for each column's body cell when assigned and whenever
|
|
72
|
+
* a single dependency or an array of dependencies changes.
|
|
73
|
+
* It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
|
|
74
|
+
*
|
|
75
|
+
* Dependencies can be a single value or an array of values.
|
|
76
|
+
* Values are checked against previous values with strict equality (`===`),
|
|
77
|
+
* so the check won't detect nested property changes inside objects or arrays.
|
|
78
|
+
* When dependencies are provided as an array, each item is checked against the previous value
|
|
79
|
+
* at the same index with strict equality. Nested arrays are also checked only by strict
|
|
80
|
+
* equality.
|
|
81
|
+
*
|
|
82
|
+
* Example of usage:
|
|
83
|
+
* ```js
|
|
84
|
+
* `<vaadin-grid-column
|
|
85
|
+
* ${columnBodyRenderer((item, model, column) => html`...`)}
|
|
86
|
+
* ></vaadin-grid-column>`
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @param renderer the renderer callback.
|
|
90
|
+
* @param dependencies a single dependency or an array of dependencies
|
|
91
|
+
* which trigger a re-render when changed.
|
|
92
|
+
*/
|
|
93
|
+
export const columnBodyRenderer = directive(GridColumnBodyRendererDirective);
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* A Lit directive for rendering the content of the column's header cell.
|
|
97
|
+
*
|
|
98
|
+
* The directive accepts a renderer callback returning a Lit template and assigns it to the grid column
|
|
99
|
+
* via the `headerRenderer` property. The renderer is called once when assigned and whenever
|
|
100
|
+
* a single dependency or an array of dependencies changes.
|
|
101
|
+
* It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
|
|
102
|
+
*
|
|
103
|
+
* Dependencies can be a single value or an array of values.
|
|
104
|
+
* Values are checked against previous values with strict equality (`===`),
|
|
105
|
+
* so the check won't detect nested property changes inside objects or arrays.
|
|
106
|
+
* When dependencies are provided as an array, each item is checked against the previous value
|
|
107
|
+
* at the same index with strict equality. Nested arrays are also checked only by strict
|
|
108
|
+
* equality.
|
|
109
|
+
*
|
|
110
|
+
* Example of usage:
|
|
111
|
+
* ```js
|
|
112
|
+
* `<vaadin-grid-column
|
|
113
|
+
* ${columnHeaderRenderer((column) => html`...`)}
|
|
114
|
+
* ></vaadin-grid-column>`
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* @param renderer the renderer callback.
|
|
118
|
+
* @param dependencies a single dependency or an array of dependencies
|
|
119
|
+
* which trigger a re-render when changed.
|
|
120
|
+
*/
|
|
121
|
+
export const columnHeaderRenderer = directive(GridColumnHeaderRendererDirective);
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* A Lit directive for rendering the content of the column's footer cell.
|
|
125
|
+
*
|
|
126
|
+
* The directive accepts a renderer callback returning a Lit template and assigns it to the grid column
|
|
127
|
+
* via the `footerRenderer` property. The renderer is called once when assigned and whenever
|
|
128
|
+
* a single dependency or an array of dependencies changes.
|
|
129
|
+
* It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
|
|
130
|
+
*
|
|
131
|
+
* Dependencies can be a single value or an array of values.
|
|
132
|
+
* Values are checked against previous values with strict equality (`===`),
|
|
133
|
+
* so the check won't detect nested property changes inside objects or arrays.
|
|
134
|
+
* When dependencies are provided as an array, each item is checked against the previous value
|
|
135
|
+
* at the same index with strict equality. Nested arrays are also checked only by strict
|
|
136
|
+
* equality.
|
|
137
|
+
*
|
|
138
|
+
* Example of usage:
|
|
139
|
+
* ```js
|
|
140
|
+
* `<vaadin-grid-column
|
|
141
|
+
* ${columnFooterRenderer((column) => html`...`)}
|
|
142
|
+
* ></vaadin-grid-column>`
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @param renderer the renderer callback.
|
|
146
|
+
* @param dependencies a single dependency or an array of dependencies
|
|
147
|
+
* which trigger a re-render when changed.
|
|
148
|
+
*/
|
|
149
|
+
export const columnFooterRenderer = directive(GridColumnFooterRendererDirective);
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { TemplateResult } from 'lit';
|
|
7
|
+
import { DirectiveResult } from 'lit/directive';
|
|
8
|
+
import { LitRendererDirective } from '@vaadin/lit-renderer';
|
|
9
|
+
import { Grid, GridItemModel } from '../vaadin-grid.js';
|
|
10
|
+
|
|
11
|
+
export type GridRowDetailsLitRenderer<TItem> = (item: TItem, model: GridItemModel<TItem>, grid: Grid) => TemplateResult;
|
|
12
|
+
|
|
13
|
+
export declare class GridRowDetailsRendererDirective<TItem> extends LitRendererDirective<
|
|
14
|
+
Grid,
|
|
15
|
+
GridRowDetailsLitRenderer<TItem>
|
|
16
|
+
> {
|
|
17
|
+
/**
|
|
18
|
+
* Adds the row details renderer callback to the grid.
|
|
19
|
+
*/
|
|
20
|
+
addRenderer(): void;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Runs the row details renderer callback on the grid.
|
|
24
|
+
*/
|
|
25
|
+
runRenderer(): void;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Removes the row details renderer callback from the grid.
|
|
29
|
+
*/
|
|
30
|
+
removeRenderer(): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A Lit directive for rendering the content of the row details cell.
|
|
35
|
+
*
|
|
36
|
+
* The directive accepts a renderer callback returning a Lit template and assigns it to the grid
|
|
37
|
+
* via the `rowDetailsRenderer` property. The renderer is called for each grid item that is in `detailsOpened`
|
|
38
|
+
* when assigned and whenever a single dependency or an array of dependencies changes.
|
|
39
|
+
* It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
|
|
40
|
+
*
|
|
41
|
+
* Dependencies can be a single value or an array of values.
|
|
42
|
+
* Values are checked against previous values with strict equality (`===`),
|
|
43
|
+
* so the check won't detect nested property changes inside objects or arrays.
|
|
44
|
+
* When dependencies are provided as an array, each item is checked against the previous value
|
|
45
|
+
* at the same index with strict equality. Nested arrays are also checked only by strict
|
|
46
|
+
* equality.
|
|
47
|
+
*
|
|
48
|
+
* Example of usage:
|
|
49
|
+
* ```js
|
|
50
|
+
* `<vaadin-grid
|
|
51
|
+
* ${gridRowDetailsRenderer((item, model, grid) => html`...`)}
|
|
52
|
+
* ></vaadin-grid>`
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @param renderer the renderer callback.
|
|
56
|
+
* @param dependencies a single dependency or an array of dependencies
|
|
57
|
+
* which trigger a re-render when changed.
|
|
58
|
+
*/
|
|
59
|
+
export declare function gridRowDetailsRenderer<TItem>(
|
|
60
|
+
renderer: GridRowDetailsLitRenderer<TItem>,
|
|
61
|
+
dependencies?: unknown,
|
|
62
|
+
): DirectiveResult<typeof GridRowDetailsRendererDirective>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2022 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { directive } from 'lit/directive.js';
|
|
7
|
+
import { microTask } from '@vaadin/component-base/src/async.js';
|
|
8
|
+
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
9
|
+
import { LitRendererDirective } from '@vaadin/lit-renderer';
|
|
10
|
+
|
|
11
|
+
export const CONTENT_UPDATE_DEBOUNCER = Symbol('contentUpdateDebouncer');
|
|
12
|
+
|
|
13
|
+
export class GridRowDetailsRendererDirective extends LitRendererDirective {
|
|
14
|
+
/**
|
|
15
|
+
* Adds the row details renderer callback to the grid.
|
|
16
|
+
*/
|
|
17
|
+
addRenderer() {
|
|
18
|
+
this.element.rowDetailsRenderer = (root, grid, model) => {
|
|
19
|
+
this.renderRenderer(root, model.item, model, grid);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Runs the row details renderer callback on the grid.
|
|
25
|
+
*/
|
|
26
|
+
runRenderer() {
|
|
27
|
+
this.element[CONTENT_UPDATE_DEBOUNCER] = Debouncer.debounce(
|
|
28
|
+
this.element[CONTENT_UPDATE_DEBOUNCER],
|
|
29
|
+
microTask,
|
|
30
|
+
() => {
|
|
31
|
+
this.element.requestContentUpdate();
|
|
32
|
+
},
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Removes the row details renderer callback from the grid.
|
|
38
|
+
*/
|
|
39
|
+
removeRenderer() {
|
|
40
|
+
this.element.rowDetailsRenderer = null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A Lit directive for rendering the content of the row details cell.
|
|
46
|
+
*
|
|
47
|
+
* The directive accepts a renderer callback returning a Lit template and assigns it to the grid
|
|
48
|
+
* via the `rowDetailsRenderer` property. The renderer is called for each grid item that is in `detailsOpened`
|
|
49
|
+
* when assigned and whenever a single dependency or an array of dependencies changes.
|
|
50
|
+
* It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
|
|
51
|
+
*
|
|
52
|
+
* Dependencies can be a single value or an array of values.
|
|
53
|
+
* Values are checked against previous values with strict equality (`===`),
|
|
54
|
+
* so the check won't detect nested property changes inside objects or arrays.
|
|
55
|
+
* When dependencies are provided as an array, each item is checked against the previous value
|
|
56
|
+
* at the same index with strict equality. Nested arrays are also checked only by strict
|
|
57
|
+
* equality.
|
|
58
|
+
*
|
|
59
|
+
* Example of usage:
|
|
60
|
+
* ```js
|
|
61
|
+
* `<vaadin-grid
|
|
62
|
+
* ${gridRowDetailsRenderer((item, model, grid) => html`...`)}
|
|
63
|
+
* ></vaadin-grid>`
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @param renderer the renderer callback.
|
|
67
|
+
* @param dependencies a single dependency or an array of dependencies
|
|
68
|
+
* which trigger a re-render when changed.
|
|
69
|
+
*/
|
|
70
|
+
export const gridRowDetailsRenderer = directive(GridRowDetailsRendererDirective);
|
|
@@ -50,7 +50,7 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
|
|
|
50
50
|
return {
|
|
51
51
|
/** @private */
|
|
52
52
|
_childColumns: {
|
|
53
|
-
value
|
|
53
|
+
value() {
|
|
54
54
|
return this._getChildColumns(this);
|
|
55
55
|
},
|
|
56
56
|
},
|
|
@@ -85,12 +85,9 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
|
|
|
85
85
|
|
|
86
86
|
static get observers() {
|
|
87
87
|
return [
|
|
88
|
-
'_updateVisibleChildColumns(_childColumns)',
|
|
89
|
-
'_childColumnsChanged(_childColumns)',
|
|
90
88
|
'_groupFrozenChanged(frozen, _rootColumns)',
|
|
91
89
|
'_groupFrozenToEndChanged(frozenToEnd, _rootColumns)',
|
|
92
|
-
'_groupHiddenChanged(hidden
|
|
93
|
-
'_visibleChildColumnsChanged(_visibleChildColumns)',
|
|
90
|
+
'_groupHiddenChanged(hidden)',
|
|
94
91
|
'_colSpanChanged(_colSpan, _headerCell, _footerCell)',
|
|
95
92
|
'_groupOrderChanged(_order, _rootColumns)',
|
|
96
93
|
'_groupReorderStatusChanged(_reorderStatus, _rootColumns)',
|
|
@@ -120,9 +117,12 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
|
|
|
120
117
|
*/
|
|
121
118
|
_columnPropChanged(path, value) {
|
|
122
119
|
if (path === 'hidden') {
|
|
123
|
-
|
|
120
|
+
// Prevent synchronization of the hidden state to child columns.
|
|
121
|
+
// If the group is currently auto-hidden, and one column is made visible,
|
|
122
|
+
// we don't want the other columns to become visible as well.
|
|
123
|
+
this._preventHiddenSynchronization = true;
|
|
124
124
|
this._updateVisibleChildColumns(this._childColumns);
|
|
125
|
-
this.
|
|
125
|
+
this._preventHiddenSynchronization = false;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
if (/flexGrow|width|hidden|_childColumns/.test(path)) {
|
|
@@ -205,14 +205,8 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
|
|
|
205
205
|
/** @private */
|
|
206
206
|
_updateVisibleChildColumns(childColumns) {
|
|
207
207
|
this._visibleChildColumns = Array.prototype.filter.call(childColumns, (col) => !col.hidden);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
/** @private */
|
|
211
|
-
_childColumnsChanged(childColumns) {
|
|
212
|
-
if (!this._autoHidden && this.hidden) {
|
|
213
|
-
Array.prototype.forEach.call(childColumns, (column) => (column.hidden = true));
|
|
214
|
-
this._updateVisibleChildColumns(childColumns);
|
|
215
|
-
}
|
|
208
|
+
this._colSpan = this._visibleChildColumns.length;
|
|
209
|
+
this._updateAutoHidden();
|
|
216
210
|
}
|
|
217
211
|
|
|
218
212
|
/** @protected */
|
|
@@ -258,26 +252,31 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
|
|
|
258
252
|
}
|
|
259
253
|
|
|
260
254
|
/** @private */
|
|
261
|
-
_groupHiddenChanged(hidden
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
255
|
+
_groupHiddenChanged(hidden) {
|
|
256
|
+
// When initializing the hidden property, only sync hidden state to columns
|
|
257
|
+
// if group is actually hidden. Otherwise, we could override a hidden column
|
|
258
|
+
// to be visible.
|
|
259
|
+
// We always want to run this though if the property is actually changed.
|
|
260
|
+
if (hidden || this.__groupHiddenInitialized) {
|
|
261
|
+
this._synchronizeHidden();
|
|
266
262
|
}
|
|
263
|
+
this.__groupHiddenInitialized = true;
|
|
264
|
+
}
|
|
267
265
|
|
|
268
|
-
|
|
266
|
+
/** @private */
|
|
267
|
+
_updateAutoHidden() {
|
|
268
|
+
const wasAutoHidden = this._autoHidden;
|
|
269
|
+
this._autoHidden = (this._visibleChildColumns || []).length === 0;
|
|
270
|
+
// Only modify hidden state if group was auto-hidden, or becomes auto-hidden
|
|
271
|
+
if (wasAutoHidden || this._autoHidden) {
|
|
272
|
+
this.hidden = this._autoHidden;
|
|
273
|
+
}
|
|
269
274
|
}
|
|
270
275
|
|
|
271
276
|
/** @private */
|
|
272
|
-
|
|
273
|
-
this.
|
|
274
|
-
|
|
275
|
-
if (!this._ignoreVisibleChildColumns) {
|
|
276
|
-
if (visibleChildColumns.length === 0) {
|
|
277
|
-
this._autoHidden = this.hidden = true;
|
|
278
|
-
} else if (this.hidden && this._autoHidden) {
|
|
279
|
-
this._autoHidden = this.hidden = false;
|
|
280
|
-
}
|
|
277
|
+
_synchronizeHidden() {
|
|
278
|
+
if (this._childColumns && !this._preventHiddenSynchronization) {
|
|
279
|
+
this._childColumns.forEach((column) => (column.hidden = this.hidden));
|
|
281
280
|
}
|
|
282
281
|
}
|
|
283
282
|
|
|
@@ -313,10 +312,14 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
|
|
|
313
312
|
info.addedNodes.filter(this._isColumnElement).length > 0 ||
|
|
314
313
|
info.removedNodes.filter(this._isColumnElement).length > 0
|
|
315
314
|
) {
|
|
316
|
-
|
|
315
|
+
// Prevent synchronization of the hidden state to child columns.
|
|
316
|
+
// If the group is currently auto-hidden, and a visible column is added,
|
|
317
|
+
// we don't want the other columns to become visible as well.
|
|
318
|
+
this._preventHiddenSynchronization = true;
|
|
317
319
|
this._rootColumns = this._getChildColumns(this);
|
|
318
320
|
this._childColumns = this._rootColumns;
|
|
319
|
-
this.
|
|
321
|
+
this._updateVisibleChildColumns(this._childColumns);
|
|
322
|
+
this._preventHiddenSynchronization = false;
|
|
320
323
|
|
|
321
324
|
// Update the column tree with microtask timing to avoid shady style scope issues
|
|
322
325
|
microTask.run(() => {
|
|
@@ -318,8 +318,8 @@ export const ColumnReorderingMixin = (superClass) =>
|
|
|
318
318
|
const differentColumns = column1 !== column2;
|
|
319
319
|
const sameParent = column1.parentElement === column2.parentElement;
|
|
320
320
|
const sameFrozen =
|
|
321
|
-
(column1.frozen && column2.frozen) || //
|
|
322
|
-
(column1.frozenToEnd && column2.frozenToEnd) || //
|
|
321
|
+
(column1.frozen && column2.frozen) || // Both columns are frozen
|
|
322
|
+
(column1.frozenToEnd && column2.frozenToEnd) || // Both columns are frozen to end
|
|
323
323
|
(!column1.frozen && !column1.frozenToEnd && !column2.frozen && !column2.frozenToEnd);
|
|
324
324
|
return differentColumns && sameParent && sameFrozen;
|
|
325
325
|
}
|
|
@@ -172,7 +172,7 @@ export const DataProviderMixin = (superClass) =>
|
|
|
172
172
|
*/
|
|
173
173
|
_cache: {
|
|
174
174
|
type: Object,
|
|
175
|
-
value
|
|
175
|
+
value() {
|
|
176
176
|
const cache = new ItemCache(this);
|
|
177
177
|
return cache;
|
|
178
178
|
},
|
|
@@ -344,7 +344,7 @@ export const DataProviderMixin = (superClass) =>
|
|
|
344
344
|
* @protected
|
|
345
345
|
*/
|
|
346
346
|
_loadPage(page, cache) {
|
|
347
|
-
//
|
|
347
|
+
// Make sure same page isn't requested multiple times.
|
|
348
348
|
if (!cache.pendingRequests[page] && this.dataProvider) {
|
|
349
349
|
this._setLoading(true);
|
|
350
350
|
cache.pendingRequests[page] = true;
|
|
@@ -466,7 +466,7 @@ export const DataProviderMixin = (superClass) =>
|
|
|
466
466
|
/** @protected */
|
|
467
467
|
_ensureFirstPageLoaded() {
|
|
468
468
|
if (!this._hasData) {
|
|
469
|
-
//
|
|
469
|
+
// Load data before adding rows to make sure they have content when
|
|
470
470
|
// rendered for the first time.
|
|
471
471
|
this._loadPage(0, this._cache);
|
|
472
472
|
}
|
|
@@ -16,7 +16,7 @@ function arrayEquals(arr1, arr2) {
|
|
|
16
16
|
for (let i = 0, l = arr1.length; i < l; i++) {
|
|
17
17
|
// Check if we have nested arrays
|
|
18
18
|
if (arr1[i] instanceof Array && arr2[i] instanceof Array) {
|
|
19
|
-
//
|
|
19
|
+
// Recurse into the nested arrays
|
|
20
20
|
if (!arrayEquals(arr1[i], arr2[i])) {
|
|
21
21
|
return false;
|
|
22
22
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
export function updateColumnOrders(columns, scope, baseOrder) {
|
|
13
13
|
let c = 1;
|
|
14
14
|
columns.forEach((column) => {
|
|
15
|
-
//
|
|
15
|
+
// Avoid multiples of 10 because they introduce and extra zero and
|
|
16
16
|
// causes the underlying calculations for child order goes wrong
|
|
17
17
|
if (c % 10 === 0) {
|
|
18
18
|
c += 1;
|
|
@@ -617,6 +617,11 @@ export const KeyboardNavigationMixin = (superClass) =>
|
|
|
617
617
|
_onTabKeyDown(e) {
|
|
618
618
|
const focusTarget = this._predictFocusStepTarget(e.composedPath()[0], e.shiftKey ? -1 : 1);
|
|
619
619
|
|
|
620
|
+
// Can be undefined if grid has tabindex
|
|
621
|
+
if (!focusTarget) {
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
|
|
620
625
|
// Prevent focus-trap logic from intercepting the event.
|
|
621
626
|
e.stopPropagation();
|
|
622
627
|
|
|
@@ -734,9 +739,7 @@ export const KeyboardNavigationMixin = (superClass) =>
|
|
|
734
739
|
if (cell) {
|
|
735
740
|
// Fire a public event for cell.
|
|
736
741
|
const context = this.getEventContext(e);
|
|
737
|
-
cell.dispatchEvent(
|
|
738
|
-
new CustomEvent('cell-focus', { bubbles: true, composed: true, detail: { context: context } }),
|
|
739
|
-
);
|
|
742
|
+
cell.dispatchEvent(new CustomEvent('cell-focus', { bubbles: true, composed: true, detail: { context } }));
|
|
740
743
|
}
|
|
741
744
|
}
|
|
742
745
|
|
|
@@ -63,9 +63,6 @@ export const ScrollMixin = (superClass) =>
|
|
|
63
63
|
ready() {
|
|
64
64
|
super.ready();
|
|
65
65
|
|
|
66
|
-
// Preserve accessor to the legacy scrolling functionality
|
|
67
|
-
this.$.outerscroller = document.createElement('div');
|
|
68
|
-
|
|
69
66
|
this.scrollTarget = this.$.table;
|
|
70
67
|
|
|
71
68
|
this.$.items.addEventListener('focusin', (e) => {
|
|
@@ -20,11 +20,20 @@ export const SelectionMixin = (superClass) =>
|
|
|
20
20
|
notify: true,
|
|
21
21
|
value: () => [],
|
|
22
22
|
},
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Set of selected item ids
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
__selectedKeys: {
|
|
29
|
+
type: Object,
|
|
30
|
+
value: () => new Set(),
|
|
31
|
+
},
|
|
23
32
|
};
|
|
24
33
|
}
|
|
25
34
|
|
|
26
35
|
static get observers() {
|
|
27
|
-
return ['
|
|
36
|
+
return ['_updateSelectedKeys(itemIdPath, selectedItems.*)'];
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
/**
|
|
@@ -33,7 +42,7 @@ export const SelectionMixin = (superClass) =>
|
|
|
33
42
|
* @protected
|
|
34
43
|
*/
|
|
35
44
|
_isSelected(item) {
|
|
36
|
-
return this.
|
|
45
|
+
return this.__selectedKeys.has(this.getItemId(item));
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
/**
|
|
@@ -68,8 +77,7 @@ export const SelectionMixin = (superClass) =>
|
|
|
68
77
|
* @protected
|
|
69
78
|
*/
|
|
70
79
|
_toggleItem(item) {
|
|
71
|
-
|
|
72
|
-
if (index === -1) {
|
|
80
|
+
if (!this._isSelected(item)) {
|
|
73
81
|
this.selectItem(item);
|
|
74
82
|
} else {
|
|
75
83
|
this.deselectItem(item);
|
|
@@ -77,7 +85,13 @@ export const SelectionMixin = (superClass) =>
|
|
|
77
85
|
}
|
|
78
86
|
|
|
79
87
|
/** @private */
|
|
80
|
-
|
|
88
|
+
_updateSelectedKeys() {
|
|
89
|
+
const selectedItems = this.selectedItems || [];
|
|
90
|
+
this.__selectedKeys = new Set();
|
|
91
|
+
selectedItems.forEach((item) => {
|
|
92
|
+
this.__selectedKeys.add(this.getItemId(item));
|
|
93
|
+
});
|
|
94
|
+
|
|
81
95
|
this.requestContentUpdate();
|
|
82
96
|
}
|
|
83
97
|
|
|
@@ -27,17 +27,13 @@ export const SortMixin = (superClass) =>
|
|
|
27
27
|
*/
|
|
28
28
|
_sorters: {
|
|
29
29
|
type: Array,
|
|
30
|
-
value:
|
|
31
|
-
return [];
|
|
32
|
-
},
|
|
30
|
+
value: () => [],
|
|
33
31
|
},
|
|
34
32
|
|
|
35
33
|
/** @private */
|
|
36
34
|
_previousSorters: {
|
|
37
35
|
type: Array,
|
|
38
|
-
value:
|
|
39
|
-
return [];
|
|
40
|
-
},
|
|
36
|
+
value: () => [],
|
|
41
37
|
},
|
|
42
38
|
};
|
|
43
39
|
}
|
|
@@ -49,7 +49,7 @@ export const StylingMixin = (superClass) =>
|
|
|
49
49
|
*/
|
|
50
50
|
generateCellClassNames() {
|
|
51
51
|
Array.from(this.$.items.children)
|
|
52
|
-
.filter((row) => !row.hidden)
|
|
52
|
+
.filter((row) => !row.hidden && !row.hasAttribute('loading'))
|
|
53
53
|
.forEach((row) => this._generateCellClassNames(row, this.__getRowModel(row)));
|
|
54
54
|
}
|
|
55
55
|
|
package/src/vaadin-grid.d.ts
CHANGED
|
@@ -95,8 +95,8 @@ export type GridExpandedItemsChangedEvent<TItem> = CustomEvent<{ value: TItem[]
|
|
|
95
95
|
*/
|
|
96
96
|
export type GridDragStartEvent<TItem> = CustomEvent<{
|
|
97
97
|
draggedItems: TItem[];
|
|
98
|
-
setDraggedItemsCount
|
|
99
|
-
setDragData
|
|
98
|
+
setDraggedItemsCount(count: number): void;
|
|
99
|
+
setDragData(type: string, data: string): void;
|
|
100
100
|
}>;
|
|
101
101
|
|
|
102
102
|
/**
|
package/src/vaadin-grid.js
CHANGED
|
@@ -558,7 +558,7 @@ class Grid extends ElementMixin(
|
|
|
558
558
|
|
|
559
559
|
const columnWidth = Math.max(this.__getIntrinsicWidth(col), this.__getDistributedWidth(col.parentElement, col));
|
|
560
560
|
|
|
561
|
-
//
|
|
561
|
+
// We're processing a regular grid-column and not a grid-column-group
|
|
562
562
|
if (!innerColumn) {
|
|
563
563
|
return columnWidth;
|
|
564
564
|
}
|
|
@@ -897,7 +897,8 @@ class Grid extends ElementMixin(
|
|
|
897
897
|
}
|
|
898
898
|
|
|
899
899
|
__updateFooterPositioning() {
|
|
900
|
-
|
|
900
|
+
// TODO: fixed in Firefox 99, remove when we can drop Firefox ESR 91 support
|
|
901
|
+
if (this._firefox && parseFloat(navigator.userAgent.match(/Firefox\/(\d{2,3}.\d)/)[1]) < 99) {
|
|
901
902
|
// Sticky (or translated) footer in a flexbox host doesn't get included in
|
|
902
903
|
// the scroll height calculation on FF. This is a workaround for the issue.
|
|
903
904
|
this.$.items.style.paddingBottom = 0;
|
|
@@ -989,14 +990,14 @@ class Grid extends ElementMixin(
|
|
|
989
990
|
*/
|
|
990
991
|
requestContentUpdate() {
|
|
991
992
|
if (this._columnTree) {
|
|
992
|
-
//
|
|
993
|
+
// Header and footer renderers
|
|
993
994
|
this._columnTree.forEach((level) => {
|
|
994
995
|
level.forEach((column) => {
|
|
995
996
|
column._renderHeaderAndFooter();
|
|
996
997
|
});
|
|
997
998
|
});
|
|
998
999
|
|
|
999
|
-
//
|
|
1000
|
+
// Body and row details renderers
|
|
1000
1001
|
this.__updateVisibleRows();
|
|
1001
1002
|
}
|
|
1002
1003
|
}
|