apex-grid 3.5.0 → 4.0.0-beta.1
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/CHANGELOG.md +573 -0
- package/LICENSE.md +125 -0
- package/README.md +143 -23
- package/components/cell.d.ts +43 -5
- package/components/cell.js +225 -64
- package/components/cell.js.map +1 -1
- package/components/filter-row.d.ts +2 -0
- package/components/filter-row.js +82 -28
- package/components/filter-row.js.map +1 -1
- package/components/grid.d.ts +281 -49
- package/components/grid.js +600 -159
- package/components/grid.js.map +1 -1
- package/components/group-header-row.js +28 -25
- package/components/group-header-row.js.map +1 -1
- package/components/header-row.d.ts +6 -10
- package/components/header-row.js +12 -28
- package/components/header-row.js.map +1 -1
- package/components/header.js +71 -22
- package/components/header.js.map +1 -1
- package/components/paginator.d.ts +20 -5
- package/components/paginator.js +54 -17
- package/components/paginator.js.map +1 -1
- package/components/row.d.ts +19 -3
- package/components/row.js +211 -56
- package/components/row.js.map +1 -1
- package/components/toolbar.d.ts +5 -1
- package/components/toolbar.js +6 -2
- package/components/toolbar.js.map +1 -1
- package/components/virtualize-rows.d.ts +38 -0
- package/components/virtualize-rows.js +286 -0
- package/components/virtualize-rows.js.map +1 -0
- package/components/virtualizer.d.ts +111 -1
- package/components/virtualizer.js +192 -5
- package/components/virtualizer.js.map +1 -1
- package/controllers/dom.d.ts +14 -7
- package/controllers/dom.js +45 -27
- package/controllers/dom.js.map +1 -1
- package/controllers/editing.d.ts +104 -37
- package/controllers/editing.js +230 -78
- package/controllers/editing.js.map +1 -1
- package/controllers/expansion.d.ts +14 -5
- package/controllers/expansion.js +24 -1
- package/controllers/expansion.js.map +1 -1
- package/controllers/filter.d.ts +10 -2
- package/controllers/filter.js +62 -17
- package/controllers/filter.js.map +1 -1
- package/controllers/history.d.ts +45 -8
- package/controllers/history.js +58 -20
- package/controllers/history.js.map +1 -1
- package/controllers/navigation.d.ts +130 -13
- package/controllers/navigation.js +474 -60
- package/controllers/navigation.js.map +1 -1
- package/controllers/pagination.d.ts +13 -6
- package/controllers/pagination.js +29 -22
- package/controllers/pagination.js.map +1 -1
- package/controllers/reorder.js +38 -22
- package/controllers/reorder.js.map +1 -1
- package/controllers/resize.d.ts +17 -2
- package/controllers/resize.js +16 -6
- package/controllers/resize.js.map +1 -1
- package/controllers/row-pin.d.ts +26 -2
- package/controllers/row-pin.js +24 -11
- package/controllers/row-pin.js.map +1 -1
- package/controllers/row-reorder.d.ts +40 -12
- package/controllers/row-reorder.js +137 -43
- package/controllers/row-reorder.js.map +1 -1
- package/controllers/selection.d.ts +33 -4
- package/controllers/selection.js +49 -11
- package/controllers/selection.js.map +1 -1
- package/controllers/sort.d.ts +22 -2
- package/controllers/sort.js +30 -25
- package/controllers/sort.js.map +1 -1
- package/controllers/state.d.ts +74 -7
- package/controllers/state.js +117 -36
- package/controllers/state.js.map +1 -1
- package/controllers/tree.d.ts +15 -10
- package/controllers/tree.js +0 -0
- package/controllers/tree.js.map +1 -1
- package/custom-elements.json +5091 -1023
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/highlight.css +15 -8
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/ApexGrid.html +233 -87
- package/docs/classes/ApexGridPaginator.html +39 -8
- package/docs/classes/ApexGridToolbar.html +11 -7
- package/docs/functions/localize.html +2 -2
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +159 -26
- package/docs/interfaces/ApexCellValidationFailedEvent.html +3 -2
- package/docs/interfaces/ApexCellValueChangedEvent.html +4 -2
- package/docs/interfaces/ApexCellValueChangingEvent.html +3 -2
- package/docs/interfaces/ApexGridEventMap.html +5 -2
- package/docs/interfaces/ApexPageChangedEvent.html +3 -1
- package/docs/interfaces/ApexRowEditEndedEvent.html +2 -1
- package/docs/interfaces/ApexRowEditStartedEvent.html +2 -1
- package/docs/interfaces/ApexRowMovingEvent.html +9 -3
- package/docs/interfaces/ApexRowPinningEvent.html +1 -1
- package/docs/interfaces/ApexTreeRowExpandedEvent.html +4 -1
- package/docs/interfaces/ApexTreeRowExpandingEvent.html +4 -1
- package/docs/interfaces/BaseApexCellContext.html +18 -5
- package/docs/interfaces/BaseApexEditorContext.html +20 -5
- package/docs/interfaces/BaseFilterExpression.html +3 -3
- package/docs/interfaces/CSVExportOptions.html +12 -4
- package/docs/interfaces/DataPipelineConfiguration.html +4 -9
- package/docs/interfaces/ExportOptions.html +5 -3
- package/docs/interfaces/GridExpansionConfiguration.html +6 -2
- package/docs/interfaces/GridRowReorderingConfiguration.html +1 -1
- package/docs/interfaces/GridSelectionConfiguration.html +19 -4
- package/docs/interfaces/PaginationConfiguration.html +11 -4
- package/docs/interfaces/PaginationState.html +4 -2
- package/docs/interfaces/SetStateResult.html +3 -2
- package/docs/interfaces/ValidatorContext.html +7 -2
- package/docs/media/_token-values.scss +118 -0
- package/docs/media/package.json +9 -5
- package/docs/modules.html +1 -1
- package/docs/types/DataPipelineParams.html +2 -2
- package/docs/types/ExportSource.html +6 -4
- package/docs/types/OperandKeys.html +9 -0
- package/docs/types/PaginationMode.html +5 -4
- package/docs/variables/EN_LOCALE.html +2 -2
- package/i18n/en.d.ts +7 -0
- package/i18n/en.js +7 -0
- package/i18n/en.js.map +1 -1
- package/i18n/es.js +7 -0
- package/i18n/es.js.map +1 -1
- package/internal/column-types.d.ts +38 -2
- package/internal/column-types.js +83 -55
- package/internal/column-types.js.map +1 -1
- package/internal/constants.d.ts +1 -2
- package/internal/constants.js +0 -4
- package/internal/constants.js.map +1 -1
- package/internal/document-styles.d.ts +30 -0
- package/internal/document-styles.js +48 -0
- package/internal/document-styles.js.map +1 -0
- package/internal/export.d.ts +45 -7
- package/internal/export.js +39 -34
- package/internal/export.js.map +1 -1
- package/internal/feature-module.d.ts +67 -3
- package/internal/feature-module.js +6 -0
- package/internal/feature-module.js.map +1 -1
- package/internal/flip.d.ts +28 -16
- package/internal/flip.js +42 -10
- package/internal/flip.js.map +1 -1
- package/internal/index.d.ts +7 -5
- package/internal/index.js +6 -4
- package/internal/index.js.map +1 -1
- package/internal/normalize-case.d.ts +8 -1
- package/internal/normalize-case.js +3 -2
- package/internal/normalize-case.js.map +1 -1
- package/internal/state-snapshot.d.ts +60 -8
- package/internal/state-snapshot.js +87 -19
- package/internal/state-snapshot.js.map +1 -1
- package/internal/types.d.ts +92 -21
- package/internal/types.js.map +1 -1
- package/internal/utils.d.ts +34 -6
- package/internal/utils.js +30 -21
- package/internal/utils.js.map +1 -1
- package/internal/validators.js +1 -0
- package/internal/validators.js.map +1 -1
- package/operations/filter/operands/number.js +9 -6
- package/operations/filter/operands/number.js.map +1 -1
- package/operations/filter/operands/string.js +2 -3
- package/operations/filter/operands/string.js.map +1 -1
- package/operations/filter/types.d.ts +14 -2
- package/operations/filter/types.js.map +1 -1
- package/operations/filter.d.ts +6 -0
- package/operations/filter.js +23 -7
- package/operations/filter.js.map +1 -1
- package/operations/quick-filter.js +2 -5
- package/operations/quick-filter.js.map +1 -1
- package/operations/sort.d.ts +21 -2
- package/operations/sort.js +41 -14
- package/operations/sort.js.map +1 -1
- package/package.json +9 -4
- package/setup.d.ts +11 -0
- package/setup.js +9 -19
- package/setup.js.map +1 -1
- package/styles/_token-values.css.d.ts +1 -0
- package/styles/_token-values.css.js +3 -0
- package/styles/_token-values.css.js.map +1 -0
- package/styles/_tokens.css.js +1 -1
- package/styles/_tokens.css.js.map +1 -1
- package/styles/body-cell/body-cell.css.js +1 -1
- package/styles/body-cell/body-cell.css.js.map +1 -1
- package/styles/body-cell/cell-renderers.css.js +1 -1
- package/styles/body-cell/cell-renderers.css.js.map +1 -1
- package/styles/body-row/body-row.css.js +1 -1
- package/styles/body-row/body-row.css.js.map +1 -1
- package/styles/document-tokens.css.d.ts +1 -0
- package/styles/document-tokens.css.js +3 -0
- package/styles/document-tokens.css.js.map +1 -0
- package/styles/filter-row/filter-row.css.js +1 -1
- package/styles/filter-row/filter-row.css.js.map +1 -1
- package/styles/grid/_grid.base.css.js +1 -1
- package/styles/grid/_grid.base.css.js.map +1 -1
- package/styles/grid/grid.css.js +1 -1
- package/styles/grid/grid.css.js.map +1 -1
- package/styles/group-header-row/group-header-row.css.js +1 -1
- package/styles/group-header-row/group-header-row.css.js.map +1 -1
- package/styles/header-cell/header-cell.css.js +1 -1
- package/styles/header-cell/header-cell.css.js.map +1 -1
- package/styles/header-row/header-row.base.css.js +1 -1
- package/styles/header-row/header-row.base.css.js.map +1 -1
- package/styles/paginator/paginator.css.js +1 -1
- package/styles/paginator/paginator.css.js.map +1 -1
- package/styles/toolbar/toolbar.css.js +1 -1
- package/styles/toolbar/toolbar.css.js.map +1 -1
- package/tokens.css +78 -0
- package/LICENSE +0 -80
- package/docs/media/LICENSE +0 -80
- package/docs/media/_tokens.scss +0 -214
- package/operations/pagination.d.ts +0 -19
- package/operations/pagination.js +0 -12
- package/operations/pagination.js.map +0 -1
package/components/grid.js
CHANGED
|
@@ -4,22 +4,26 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
+
var _a;
|
|
7
8
|
import { ContextProvider } from '@lit/context';
|
|
8
9
|
import { html, nothing } from 'lit';
|
|
9
10
|
import { eventOptions, property, query, queryAll, state } from 'lit/decorators.js';
|
|
10
11
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
11
12
|
import { DataOperationsController } from '../controllers/data-operation.js';
|
|
12
13
|
import { GridDOMController } from '../controllers/dom.js';
|
|
14
|
+
import { viewIndexer } from '../controllers/history.js';
|
|
15
|
+
import { DEFAULT_PAGINATION } from '../controllers/pagination.js';
|
|
13
16
|
import { gridStateContext, StateController } from '../controllers/state.js';
|
|
14
17
|
import { localize as resolveLocaleText, } from '../i18n/index.js';
|
|
15
18
|
import { DEFAULT_COLUMN_CONFIG, PIPELINE, SENTINEL_NODE } from '../internal/constants.js';
|
|
19
|
+
import { adoptGridDocumentStyles } from '../internal/document-styles.js';
|
|
16
20
|
import { buildCSV, downloadBlob, } from '../internal/export.js';
|
|
17
21
|
import { EventEmitterBase } from '../internal/mixins/event-emitter.js';
|
|
18
22
|
import { registerComponent } from '../internal/register.js';
|
|
19
23
|
import { columnSchema, operandsByType } from '../internal/state-schema.js';
|
|
20
|
-
import { applyColumnLayout, deserializeFilter, resolveRowRefs, serializeColumnLayout, serializeFilter, serializeRowRefs, serializeSort, } from '../internal/state-snapshot.js';
|
|
24
|
+
import { applyColumnLayout, deserializeFilter, resolveFilterOperand, resolveRowRefs, SET_STATE_SLICES, serializeColumnLayout, serializeFilter, serializeRowRefs, serializeSort, } from '../internal/state-snapshot.js';
|
|
21
25
|
import { GRID_TAG } from '../internal/tags.js';
|
|
22
|
-
import { asArray, autoGenerateColumns, getDisplayColumns
|
|
26
|
+
import { asArray, autoGenerateColumns, getDisplayColumns } from '../internal/utils.js';
|
|
23
27
|
import { watch } from '../internal/watch.js';
|
|
24
28
|
import { styles as gridStyles } from '../styles/grid/grid.css.js';
|
|
25
29
|
import ApexGridCell from './cell.js';
|
|
@@ -29,20 +33,37 @@ import ApexGridHeaderRow from './header-row.js';
|
|
|
29
33
|
import ApexGridPaginator from './paginator.js';
|
|
30
34
|
import ApexGridRow from './row.js';
|
|
31
35
|
import ApexGridToolbar from './toolbar.js';
|
|
32
|
-
import ApexVirtualizer from './virtualizer.js';
|
|
33
|
-
const
|
|
36
|
+
import ApexVirtualizer, { quietResizeObserverLoopNotice } from './virtualizer.js';
|
|
37
|
+
const SORT_DIRECTIONS = ['ascending', 'descending', 'none'];
|
|
38
|
+
const VIEW_SHAPING_SLICES = new Set([
|
|
34
39
|
'columns',
|
|
35
|
-
'sort',
|
|
36
40
|
'filter',
|
|
37
41
|
'quickFilter',
|
|
38
42
|
'modules',
|
|
39
|
-
'rowOrder',
|
|
40
43
|
'tree',
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
'
|
|
44
|
-
'
|
|
45
|
-
]
|
|
44
|
+
]);
|
|
45
|
+
const VIEW_SHAPING_PROPERTIES = new Map([
|
|
46
|
+
['data', null],
|
|
47
|
+
['quickFilter', null],
|
|
48
|
+
['pagination', ['enabled', 'mode', 'pageSize', 'totalItems']],
|
|
49
|
+
['tree', ['enabled', 'getDataPath', 'defaultExpanded']],
|
|
50
|
+
['dataPipelineConfiguration', ['sort', 'filter', 'quickFilter']],
|
|
51
|
+
]);
|
|
52
|
+
function viewShapeChanged(fields, before, after) {
|
|
53
|
+
if (Object.is(before, after))
|
|
54
|
+
return false;
|
|
55
|
+
if (!fields)
|
|
56
|
+
return true;
|
|
57
|
+
const a = (before ?? {});
|
|
58
|
+
const b = (after ?? {});
|
|
59
|
+
return fields.some((field) => !Object.is(a[field], b[field]));
|
|
60
|
+
}
|
|
61
|
+
function keyChanged(key, previous) {
|
|
62
|
+
return key.some((value, i) => value !== previous[i]);
|
|
63
|
+
}
|
|
64
|
+
function warnDropped(message) {
|
|
65
|
+
console.warn(`[apex-grid] ${message}`);
|
|
66
|
+
}
|
|
46
67
|
export class ApexGrid extends EventEmitterBase {
|
|
47
68
|
constructor() {
|
|
48
69
|
super(...arguments);
|
|
@@ -55,36 +76,75 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
55
76
|
});
|
|
56
77
|
this.dataState = [];
|
|
57
78
|
this.columns = [];
|
|
58
|
-
this
|
|
79
|
+
this.#data = [];
|
|
59
80
|
this.autoGenerate = false;
|
|
60
81
|
this.sortConfiguration = {
|
|
61
82
|
multiple: true,
|
|
62
83
|
triState: true,
|
|
63
84
|
};
|
|
64
|
-
this
|
|
85
|
+
this.#quickFilter = '';
|
|
86
|
+
this.#quickFilterWrites = 0;
|
|
65
87
|
this.showQuickFilter = false;
|
|
66
88
|
this.showExport = false;
|
|
67
89
|
this.columnReordering = false;
|
|
68
90
|
this.columnSeparator = true;
|
|
91
|
+
this.#rowRecycling = _a.defaultRowRecycling;
|
|
69
92
|
this.coordinateHints = false;
|
|
70
93
|
this.columnMenu = true;
|
|
71
|
-
this
|
|
72
|
-
this.#
|
|
94
|
+
this.showHeader = true;
|
|
95
|
+
this.#bodyKey = [];
|
|
96
|
+
this.#bodyRows = [];
|
|
97
|
+
this.#pageKey = [];
|
|
98
|
+
this.#pageItems = [];
|
|
99
|
+
this.#viewChangePending = false;
|
|
100
|
+
this.#shapingPending = false;
|
|
101
|
+
this.#pipelineRun = 0;
|
|
102
|
+
this.#pipelineSettled = Promise.resolve();
|
|
103
|
+
this.#settlePipeline = null;
|
|
104
|
+
this.#pinKey = [];
|
|
105
|
+
this.#stateChangedListeners = new Map();
|
|
73
106
|
this.#lastStateJson = null;
|
|
107
|
+
this.#labelObserver = new MutationObserver(() => this.requestUpdate());
|
|
74
108
|
}
|
|
75
109
|
static get tagName() {
|
|
76
110
|
return GRID_TAG;
|
|
77
111
|
}
|
|
78
112
|
static { this.styles = gridStyles; }
|
|
113
|
+
static { this.defaultRowRecycling = globalThis.__apexRowKeying !== 'item'; }
|
|
79
114
|
static register() {
|
|
80
|
-
registerComponent(
|
|
115
|
+
registerComponent(_a, ApexVirtualizer, ApexGridRow, ApexGridGroupHeaderRow, ApexGridHeaderRow, ApexFilterRow, ApexGridPaginator, ApexGridToolbar);
|
|
81
116
|
}
|
|
82
117
|
createStateController() {
|
|
83
118
|
return new StateController(this);
|
|
84
119
|
}
|
|
120
|
+
#data;
|
|
121
|
+
get data() {
|
|
122
|
+
return this.#data;
|
|
123
|
+
}
|
|
124
|
+
set data(value) {
|
|
125
|
+
if (value == null && !this.#data.length)
|
|
126
|
+
return;
|
|
127
|
+
this.#data = value ?? [];
|
|
128
|
+
}
|
|
129
|
+
get quickFilter() {
|
|
130
|
+
return this.#quickFilter;
|
|
131
|
+
}
|
|
132
|
+
set quickFilter(value) {
|
|
133
|
+
this.#quickFilter = value;
|
|
134
|
+
this.#quickFilterWrites++;
|
|
135
|
+
}
|
|
136
|
+
#quickFilter;
|
|
137
|
+
#quickFilterWrites;
|
|
85
138
|
localize(key, params, fallback) {
|
|
86
139
|
return resolveLocaleText(this.localeText, key, params, fallback);
|
|
87
140
|
}
|
|
141
|
+
get rowRecycling() {
|
|
142
|
+
return this.#rowRecycling;
|
|
143
|
+
}
|
|
144
|
+
set rowRecycling(value) {
|
|
145
|
+
this.#rowRecycling = value ?? _a.defaultRowRecycling;
|
|
146
|
+
}
|
|
147
|
+
#rowRecycling;
|
|
88
148
|
get selectedRows() {
|
|
89
149
|
return this.stateController.selection.selectedRows();
|
|
90
150
|
}
|
|
@@ -160,26 +220,50 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
160
220
|
isTreeRowExpanded(row) {
|
|
161
221
|
return this.stateController.tree.isExpanded(row);
|
|
162
222
|
}
|
|
223
|
+
#pendingSort;
|
|
224
|
+
#pendingFilter;
|
|
163
225
|
set sortExpressions(expressions) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
226
|
+
this.#pendingSort = [...(expressions ?? [])];
|
|
227
|
+
this.requestUpdate(PIPELINE);
|
|
167
228
|
}
|
|
168
229
|
get sortExpressions() {
|
|
230
|
+
if (this.#pendingSort)
|
|
231
|
+
return [...this.#pendingSort];
|
|
169
232
|
return Array.from(this.stateController.sorting.state.values());
|
|
170
233
|
}
|
|
171
234
|
set filterExpressions(expressions) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
235
|
+
this.#pendingFilter = [...(expressions ?? [])];
|
|
236
|
+
this.#markViewChange();
|
|
175
237
|
}
|
|
176
238
|
get filterExpressions() {
|
|
239
|
+
if (this.#pendingFilter) {
|
|
240
|
+
return this.#pendingFilter.map((each) => {
|
|
241
|
+
const resolved = this.#resolveFilter(each);
|
|
242
|
+
return typeof resolved === 'string' ? each : resolved;
|
|
243
|
+
});
|
|
244
|
+
}
|
|
177
245
|
const expressions = [];
|
|
178
246
|
for (const each of this.stateController.filtering.state.values) {
|
|
179
247
|
expressions.push(...each.all);
|
|
180
248
|
}
|
|
181
249
|
return expressions;
|
|
182
250
|
}
|
|
251
|
+
#resolveFilter(each) {
|
|
252
|
+
const column = each ? this.getColumn(each.key) : undefined;
|
|
253
|
+
if (!column)
|
|
254
|
+
return `filter: unknown column "${String(each?.key)}"; dropped`;
|
|
255
|
+
const defaults = this.stateController.filtering.getDefaultExpression(column);
|
|
256
|
+
const named = each.condition ?? defaults.condition;
|
|
257
|
+
const condition = typeof named === 'string' ? resolveFilterOperand(column, named) : named;
|
|
258
|
+
if (!condition)
|
|
259
|
+
return `filter: unknown operand "${named}" for "${String(each.key)}"; dropped`;
|
|
260
|
+
return {
|
|
261
|
+
...defaults,
|
|
262
|
+
...each,
|
|
263
|
+
condition,
|
|
264
|
+
criteria: each.criteria ?? 'and',
|
|
265
|
+
};
|
|
266
|
+
}
|
|
183
267
|
get rows() {
|
|
184
268
|
return Array.from(this._rows);
|
|
185
269
|
}
|
|
@@ -190,31 +274,75 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
190
274
|
return getDisplayColumns(this.columns);
|
|
191
275
|
}
|
|
192
276
|
get totalItems() {
|
|
193
|
-
|
|
194
|
-
|
|
277
|
+
return this.stateController.pagination.totalItems;
|
|
278
|
+
}
|
|
279
|
+
get bodyRows() {
|
|
280
|
+
const { rowPin, dataVersion } = this.stateController;
|
|
281
|
+
const key = [this.dataState, dataVersion, rowPin.version, rowPin.enabled];
|
|
282
|
+
if (keyChanged(key, this.#bodyKey)) {
|
|
283
|
+
this.#bodyKey = key;
|
|
284
|
+
this.#bodyRows = rowPin.hasPinnedRows
|
|
285
|
+
? this.dataState.filter((row) => !rowPin.isPinned(row))
|
|
286
|
+
: this.dataState;
|
|
195
287
|
}
|
|
196
|
-
return this
|
|
288
|
+
return this.#bodyRows;
|
|
197
289
|
}
|
|
290
|
+
#bodyKey;
|
|
291
|
+
#bodyRows;
|
|
198
292
|
get pageItems() {
|
|
199
|
-
const
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
293
|
+
const { pagination, dataVersion } = this.stateController;
|
|
294
|
+
const key = [
|
|
295
|
+
this.bodyRows,
|
|
296
|
+
dataVersion,
|
|
297
|
+
pagination.enabled,
|
|
298
|
+
this.pagination?.mode,
|
|
299
|
+
pagination.page,
|
|
300
|
+
pagination.pageSize,
|
|
301
|
+
];
|
|
302
|
+
if (keyChanged(key, this.#pageKey)) {
|
|
303
|
+
this.#pageKey = key;
|
|
304
|
+
const base = this.bodyRows;
|
|
305
|
+
const { page, pageSize } = pagination;
|
|
306
|
+
this.#pageItems =
|
|
307
|
+
!pagination.enabled || this.pagination?.mode === 'remote' || !pageSize
|
|
308
|
+
? base
|
|
309
|
+
: base.slice(page * pageSize, (page + 1) * pageSize);
|
|
310
|
+
}
|
|
311
|
+
return this.#pageItems;
|
|
212
312
|
}
|
|
313
|
+
#pageKey;
|
|
314
|
+
#pageItems;
|
|
213
315
|
get page() {
|
|
214
316
|
return this.stateController.pagination.page;
|
|
215
317
|
}
|
|
216
318
|
set page(value) {
|
|
217
|
-
this
|
|
319
|
+
if (this.#viewStale) {
|
|
320
|
+
this.stateController.pagination.page = Number.isFinite(value)
|
|
321
|
+
? Math.max(0, Math.trunc(value))
|
|
322
|
+
: 0;
|
|
323
|
+
this.requestUpdate(PIPELINE);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
this.stateController.pagination.gotoPage(value);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
#viewChangePending;
|
|
330
|
+
#shapingPending;
|
|
331
|
+
get #viewStale() {
|
|
332
|
+
return !this.hasUpdated || this.#viewChangePending || this.#shapingPending;
|
|
333
|
+
}
|
|
334
|
+
#markViewChange() {
|
|
335
|
+
this.#viewChangePending = true;
|
|
336
|
+
this.requestUpdate(PIPELINE);
|
|
337
|
+
}
|
|
338
|
+
requestUpdate(name, oldValue, options, useNewValue, newValue) {
|
|
339
|
+
const fields = name === undefined ? undefined : VIEW_SHAPING_PROPERTIES.get(name);
|
|
340
|
+
if (this.hasUpdated &&
|
|
341
|
+
fields !== undefined &&
|
|
342
|
+
viewShapeChanged(fields, oldValue, useNewValue ? newValue : this[name])) {
|
|
343
|
+
this.#viewChangePending = true;
|
|
344
|
+
}
|
|
345
|
+
super.requestUpdate(name, oldValue, options, useNewValue, newValue);
|
|
218
346
|
}
|
|
219
347
|
get pageSize() {
|
|
220
348
|
return this.stateController.pagination.pageSize;
|
|
@@ -228,21 +356,31 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
228
356
|
watchColumns(_, newConfig = []) {
|
|
229
357
|
this.columns = newConfig.map((config) => ({ ...DEFAULT_COLUMN_CONFIG, ...config }));
|
|
230
358
|
}
|
|
359
|
+
historyRecords() {
|
|
360
|
+
return this.data;
|
|
361
|
+
}
|
|
231
362
|
dataChanged() {
|
|
232
363
|
let next = [...this.data];
|
|
233
364
|
autoGenerateColumns(this);
|
|
365
|
+
this.stateController?.history?.reconcile(() => this.historyRecords());
|
|
234
366
|
this.stateController?.tree?.resetForDataChange();
|
|
367
|
+
const carry = (rows) => this.#carryRows(rows);
|
|
368
|
+
this.stateController?.rowReorder.resetForDataChange(carry);
|
|
369
|
+
this.stateController?.rowPin.resetForDataChange(carry);
|
|
235
370
|
if (this.stateController?.tree?.enabled) {
|
|
236
371
|
next = this.stateController.tree.process(next);
|
|
237
372
|
}
|
|
238
373
|
this.dataState = this.stateController ? this.stateController.applyModuleTransforms(next) : next;
|
|
239
|
-
if (this.hasUpdated)
|
|
240
|
-
this.
|
|
241
|
-
}
|
|
374
|
+
if (this.hasUpdated)
|
|
375
|
+
this.requestUpdate(PIPELINE);
|
|
242
376
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this.
|
|
377
|
+
#carryRows(rows) {
|
|
378
|
+
const rowId = this.rowId;
|
|
379
|
+
const records = [...this.historyRecords()];
|
|
380
|
+
if (rowId)
|
|
381
|
+
return resolveRowRefs(serializeRowRefs(rows, [], rowId), records, rowId);
|
|
382
|
+
const present = new Set(records);
|
|
383
|
+
return rows.filter((row) => present.has(row));
|
|
246
384
|
}
|
|
247
385
|
paginationChanged() {
|
|
248
386
|
const ctrl = this.stateController?.pagination;
|
|
@@ -255,63 +393,169 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
255
393
|
if (typeof next.page === 'number') {
|
|
256
394
|
ctrl.page = next.page;
|
|
257
395
|
}
|
|
258
|
-
if (this.hasUpdated)
|
|
259
|
-
this.
|
|
260
|
-
}
|
|
396
|
+
if (this.hasUpdated)
|
|
397
|
+
this.requestUpdate(PIPELINE);
|
|
261
398
|
}
|
|
262
399
|
quickFilterChanged() {
|
|
263
|
-
if (this.hasUpdated)
|
|
264
|
-
this.
|
|
400
|
+
if (this.hasUpdated || this.quickFilter)
|
|
401
|
+
this.requestUpdate(PIPELINE);
|
|
402
|
+
}
|
|
403
|
+
treeChanged(previous) {
|
|
404
|
+
if (!viewShapeChanged(VIEW_SHAPING_PROPERTIES.get('tree'), previous, this.tree))
|
|
405
|
+
return;
|
|
406
|
+
this.stateController.tree.resetForDataChange();
|
|
407
|
+
this.requestUpdate(PIPELINE);
|
|
408
|
+
}
|
|
409
|
+
#pipelineRun;
|
|
410
|
+
#pipelineSettled;
|
|
411
|
+
#settlePipeline;
|
|
412
|
+
pipeline() {
|
|
413
|
+
if (!this.#settlePipeline) {
|
|
414
|
+
this.#pipelineSettled = new Promise((settle) => {
|
|
415
|
+
this.#settlePipeline = settle;
|
|
416
|
+
});
|
|
265
417
|
}
|
|
418
|
+
return this.#runPipeline(++this.#pipelineRun);
|
|
266
419
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
this.
|
|
420
|
+
async #runPipeline(run) {
|
|
421
|
+
try {
|
|
422
|
+
this.#flushPendingExpressions();
|
|
423
|
+
if (this.#viewChangePending || !this.hasUpdated)
|
|
424
|
+
this.#shapingPending = true;
|
|
425
|
+
this.#viewChangePending = false;
|
|
426
|
+
const next = await this.dataController.apply([...this.data], this.stateController);
|
|
427
|
+
if (run !== this.#pipelineRun)
|
|
428
|
+
return;
|
|
429
|
+
this.dataState = next;
|
|
430
|
+
this.stateController.dataVersion++;
|
|
431
|
+
this.stateController.pagination.reclamp();
|
|
278
432
|
}
|
|
279
|
-
|
|
280
|
-
this
|
|
433
|
+
finally {
|
|
434
|
+
if (run === this.#pipelineRun) {
|
|
435
|
+
this.#settlePipeline?.();
|
|
436
|
+
this.#settlePipeline = null;
|
|
437
|
+
if (this.#shapingPending) {
|
|
438
|
+
this.#shapingPending = false;
|
|
439
|
+
this.#baselineStateIfUnset();
|
|
440
|
+
}
|
|
441
|
+
}
|
|
281
442
|
}
|
|
282
|
-
|
|
283
|
-
|
|
443
|
+
}
|
|
444
|
+
async pipelineSettled() {
|
|
445
|
+
await this.updateComplete;
|
|
446
|
+
let settled;
|
|
447
|
+
do {
|
|
448
|
+
settled = this.#pipelineSettled;
|
|
449
|
+
await settled;
|
|
450
|
+
await this.updateComplete;
|
|
451
|
+
} while (settled !== this.#pipelineSettled);
|
|
452
|
+
}
|
|
453
|
+
#flushPendingExpressions() {
|
|
454
|
+
const sort = this.#pendingSort;
|
|
455
|
+
const filter = this.#pendingFilter;
|
|
456
|
+
this.#pendingSort = undefined;
|
|
457
|
+
this.#pendingFilter = undefined;
|
|
458
|
+
if (sort)
|
|
459
|
+
this.#replaceSort(sort, warnDropped);
|
|
460
|
+
if (filter)
|
|
461
|
+
this.#replaceFilter(filter);
|
|
462
|
+
}
|
|
463
|
+
#replaceSort(entries, warn) {
|
|
464
|
+
this.stateController.sorting.reset();
|
|
465
|
+
const valid = [];
|
|
466
|
+
for (const entry of entries) {
|
|
467
|
+
const { direction, ...rest } = (entry ?? {});
|
|
468
|
+
if (typeof entry !== 'object' || entry === null || !this.getColumn(rest.key)) {
|
|
469
|
+
warn(`sort: unknown column "${String(rest.key)}"; dropped`);
|
|
470
|
+
}
|
|
471
|
+
else if (direction === undefined) {
|
|
472
|
+
valid.push(rest);
|
|
473
|
+
}
|
|
474
|
+
else if (SORT_DIRECTIONS.includes(direction)) {
|
|
475
|
+
valid.push(entry);
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
warn(`sort: invalid direction "${String(direction)}"; dropped`);
|
|
479
|
+
}
|
|
284
480
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
481
|
+
if (valid.length)
|
|
482
|
+
this.sort(valid);
|
|
483
|
+
this.requestUpdate(PIPELINE);
|
|
484
|
+
}
|
|
485
|
+
#replaceFilter(entries) {
|
|
486
|
+
this.#markViewChange();
|
|
487
|
+
this.stateController.filtering.reset();
|
|
488
|
+
if (entries.length)
|
|
489
|
+
this.filter([...entries]);
|
|
490
|
+
}
|
|
491
|
+
willUpdate(changed) {
|
|
492
|
+
super.willUpdate(changed);
|
|
493
|
+
const { rowPin, pagination } = this.stateController;
|
|
494
|
+
const key = [rowPin.version, rowPin.enabled];
|
|
495
|
+
if (keyChanged(key, this.#pinKey)) {
|
|
496
|
+
this.#pinKey = key;
|
|
497
|
+
if (!changed.has(PIPELINE) && !this.#viewStale)
|
|
498
|
+
pagination.reclamp();
|
|
293
499
|
}
|
|
500
|
+
}
|
|
501
|
+
#pinKey;
|
|
502
|
+
updated() {
|
|
503
|
+
this.#viewChangePending = false;
|
|
504
|
+
this.#syncBodyTabStop();
|
|
505
|
+
this.stateController.navigation.reconcileFocus();
|
|
294
506
|
this.#emitStateChangedIfNeeded();
|
|
295
507
|
}
|
|
296
|
-
#autoAriaLabel;
|
|
297
508
|
#stateChangedListeners;
|
|
298
509
|
#lastStateJson;
|
|
299
510
|
addEventListener(type, listener, options) {
|
|
300
|
-
if (type === 'stateChanged')
|
|
301
|
-
this.#
|
|
302
|
-
this.#lastStateJson = this.hasUpdated ? JSON.stringify(this.getState()) : null;
|
|
303
|
-
}
|
|
511
|
+
if (type === 'stateChanged' && listener)
|
|
512
|
+
this.#trackStateChangedListener(listener, options);
|
|
304
513
|
super.addEventListener(type, listener, options);
|
|
305
514
|
}
|
|
515
|
+
#trackStateChangedListener(listener, options) {
|
|
516
|
+
const capture = typeof options === 'boolean' ? options : Boolean(options?.capture);
|
|
517
|
+
const captures = this.#stateChangedListeners.get(listener) ?? new Map();
|
|
518
|
+
if (!captures.has(capture) && !options?.signal?.aborted) {
|
|
519
|
+
if (!this.#stateChangedListeners.size) {
|
|
520
|
+
this.#lastStateJson = this.hasUpdated ? JSON.stringify(this.getState()) : null;
|
|
521
|
+
}
|
|
522
|
+
const token = {};
|
|
523
|
+
captures.set(capture, token);
|
|
524
|
+
this.#stateChangedListeners.set(listener, captures);
|
|
525
|
+
const forget = () => this.#forgetStateChangedListener(listener, capture, token);
|
|
526
|
+
if (typeof options === 'object') {
|
|
527
|
+
if (options.once) {
|
|
528
|
+
HTMLElement.prototype.addEventListener.call(this, 'stateChanged', forget, {
|
|
529
|
+
capture,
|
|
530
|
+
once: true,
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
options.signal?.addEventListener('abort', forget, { once: true });
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
#forgetStateChangedListener(listener, capture, token) {
|
|
538
|
+
const captures = this.#stateChangedListeners.get(listener);
|
|
539
|
+
if (!captures || (token && captures.get(capture) !== token))
|
|
540
|
+
return;
|
|
541
|
+
captures.delete(capture);
|
|
542
|
+
if (!captures.size)
|
|
543
|
+
this.#stateChangedListeners.delete(listener);
|
|
544
|
+
}
|
|
306
545
|
removeEventListener(type, listener, options) {
|
|
307
|
-
if (type === 'stateChanged') {
|
|
308
|
-
|
|
546
|
+
if (type === 'stateChanged' && listener) {
|
|
547
|
+
const capture = typeof options === 'boolean' ? options : Boolean(options?.capture);
|
|
548
|
+
this.#forgetStateChangedListener(listener, capture);
|
|
309
549
|
}
|
|
310
550
|
super.removeEventListener(type, listener, options);
|
|
311
551
|
}
|
|
312
552
|
#emitStateChangedIfNeeded() {
|
|
313
|
-
if (this.#stateChangedListeners
|
|
553
|
+
if (!this.#stateChangedListeners.size)
|
|
554
|
+
return;
|
|
555
|
+
if (this.#lastStateJson === null) {
|
|
556
|
+
this.#baselineStateIfUnset();
|
|
314
557
|
return;
|
|
558
|
+
}
|
|
315
559
|
const snapshot = this.getState();
|
|
316
560
|
const json = JSON.stringify(snapshot);
|
|
317
561
|
if (json === this.#lastStateJson)
|
|
@@ -319,6 +563,20 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
319
563
|
this.#lastStateJson = json;
|
|
320
564
|
this.emitEvent('stateChanged', { detail: { state: snapshot } });
|
|
321
565
|
}
|
|
566
|
+
#baselineStateIfUnset() {
|
|
567
|
+
if (this.#lastStateJson === null && this.#stateChangedListeners.size && !this.#shapingPending) {
|
|
568
|
+
this.#lastStateJson = JSON.stringify(this.getState());
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
connectedCallback() {
|
|
572
|
+
super.connectedCallback();
|
|
573
|
+
adoptGridDocumentStyles(this);
|
|
574
|
+
quietResizeObserverLoopNotice();
|
|
575
|
+
this.#labelObserver.observe(this, {
|
|
576
|
+
attributeFilter: ['aria-label', 'aria-labelledby', 'aria-describedby'],
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
#labelObserver;
|
|
322
580
|
firstUpdated() {
|
|
323
581
|
if (typeof getComputedStyle === 'function' && getComputedStyle(this).display !== 'grid') {
|
|
324
582
|
console.warn('[apex-grid] Host `display` has been overridden. The grid requires ' +
|
|
@@ -328,26 +586,44 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
328
586
|
}
|
|
329
587
|
}
|
|
330
588
|
filter(config) {
|
|
331
|
-
this
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
589
|
+
if (this.#pendingFilter) {
|
|
590
|
+
const added = asArray(config);
|
|
591
|
+
this.#pendingFilter.push(...added);
|
|
592
|
+
if (added.length)
|
|
593
|
+
this.#markViewChange();
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
const expressions = [];
|
|
597
|
+
for (const each of asArray(config)) {
|
|
598
|
+
const resolved = this.#resolveFilter(each);
|
|
599
|
+
if (typeof resolved === 'string')
|
|
600
|
+
warnDropped(resolved);
|
|
601
|
+
else
|
|
602
|
+
expressions.push(resolved);
|
|
603
|
+
}
|
|
604
|
+
if (!expressions.length)
|
|
605
|
+
return;
|
|
606
|
+
this.#markViewChange();
|
|
607
|
+
this.stateController.filtering.filter(expressions);
|
|
337
608
|
}
|
|
338
609
|
sort(expressions) {
|
|
610
|
+
if (this.#pendingSort) {
|
|
611
|
+
this.#pendingSort.push(...asArray(expressions));
|
|
612
|
+
this.requestUpdate(PIPELINE);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
339
615
|
this.stateController.sorting.sort(expressions);
|
|
340
616
|
}
|
|
341
617
|
getState(options) {
|
|
342
618
|
const rowId = options?.rowId ?? this.rowId;
|
|
343
|
-
const pinned = this.stateController.rowPin.
|
|
619
|
+
const pinned = this.stateController.rowPin.pins;
|
|
344
620
|
const manualOrder = this.stateController.rowReorder.getManualOrder();
|
|
345
621
|
return {
|
|
346
622
|
version: 1,
|
|
347
623
|
columns: serializeColumnLayout(this.columns),
|
|
348
624
|
sort: serializeSort(this.sortExpressions),
|
|
349
625
|
filter: serializeFilter(this.filterExpressions),
|
|
350
|
-
quickFilter: this.quickFilter,
|
|
626
|
+
quickFilter: this.quickFilter ?? '',
|
|
351
627
|
pagination: { page: this.page, pageSize: this.pageSize },
|
|
352
628
|
selection: serializeRowRefs(this.selectedRows, this.data, rowId),
|
|
353
629
|
expansion: serializeRowRefs(this.expandedRows, this.data, rowId),
|
|
@@ -367,7 +643,7 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
367
643
|
columns: this.columns.map((column) => columnSchema(column)),
|
|
368
644
|
capabilities: {
|
|
369
645
|
sort: {
|
|
370
|
-
directions:
|
|
646
|
+
directions: SORT_DIRECTIONS.filter((direction) => direction !== 'none'),
|
|
371
647
|
multi: Boolean(this.sortConfiguration?.multiple),
|
|
372
648
|
},
|
|
373
649
|
filter: { operandsByType: operandsByType(this.columns) },
|
|
@@ -384,6 +660,7 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
384
660
|
const strict = options?.strict ?? false;
|
|
385
661
|
const applied = [];
|
|
386
662
|
const warnings = [];
|
|
663
|
+
const viewSettled = !this.#viewStale;
|
|
387
664
|
const warn = (message) => {
|
|
388
665
|
if (strict)
|
|
389
666
|
throw new Error(`[apex-grid] setState: ${message}`);
|
|
@@ -410,31 +687,23 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
410
687
|
}
|
|
411
688
|
const columns = asArray(state.columns, 'columns');
|
|
412
689
|
if (columns) {
|
|
690
|
+
const unkeyed = columns.filter((entry) => typeof entry?.key !== 'string').length;
|
|
691
|
+
if (unkeyed)
|
|
692
|
+
warn(`columns: ${unkeyed} entr${unkeyed === 1 ? 'y' : 'ies'} without a key; dropped`);
|
|
413
693
|
this.columns = applyColumnLayout(this.columns, columns);
|
|
414
694
|
applied.push('columns');
|
|
415
695
|
}
|
|
416
696
|
const sort = asArray(state.sort, 'sort');
|
|
417
697
|
if (sort) {
|
|
418
|
-
this
|
|
419
|
-
|
|
420
|
-
for (const entry of sort) {
|
|
421
|
-
if (this.getColumn(entry.key)) {
|
|
422
|
-
valid.push(entry);
|
|
423
|
-
}
|
|
424
|
-
else {
|
|
425
|
-
warn(`sort: unknown column "${entry.key}"; dropped`);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
if (valid.length)
|
|
429
|
-
this.sort(valid);
|
|
698
|
+
this.#pendingSort = undefined;
|
|
699
|
+
this.#replaceSort(sort, warn);
|
|
430
700
|
applied.push('sort');
|
|
431
701
|
}
|
|
432
702
|
const filter = asArray(state.filter, 'filter');
|
|
433
703
|
if (filter) {
|
|
434
|
-
this
|
|
704
|
+
this.#pendingFilter = undefined;
|
|
435
705
|
const expressions = deserializeFilter(filter, (key) => this.getColumn(key), (snapshot, reason) => warn(`filter: "${snapshot.key}" dropped (${reason})`));
|
|
436
|
-
|
|
437
|
-
this.filter(expressions);
|
|
706
|
+
this.#replaceFilter(expressions);
|
|
438
707
|
applied.push('filter');
|
|
439
708
|
}
|
|
440
709
|
if (state.quickFilter !== undefined) {
|
|
@@ -449,6 +718,7 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
449
718
|
if (state.modules !== undefined) {
|
|
450
719
|
if (state.modules && typeof state.modules === 'object') {
|
|
451
720
|
this.stateController.restoreModuleState(state.modules);
|
|
721
|
+
this.#markViewChange();
|
|
452
722
|
applied.push('modules');
|
|
453
723
|
}
|
|
454
724
|
else {
|
|
@@ -476,13 +746,22 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
476
746
|
if (state.treeExpanded !== undefined || state.treeExpandedKeys !== undefined) {
|
|
477
747
|
const refs = asArray(state.treeExpanded, 'treeExpanded') ?? [];
|
|
478
748
|
const keys = asArray(state.treeExpandedKeys, 'treeExpandedKeys') ?? [];
|
|
479
|
-
this.stateController.tree.restoreExpansion(resolveCounted(refs, 'treeExpanded'), keys);
|
|
749
|
+
this.stateController.tree.restoreExpansion(resolveCounted(refs, 'treeExpanded'), keys.filter((key) => typeof key === 'string'));
|
|
750
|
+
this.#markViewChange();
|
|
480
751
|
applied.push('tree');
|
|
481
752
|
}
|
|
482
753
|
const expansion = asArray(state.expansion, 'expansion');
|
|
483
754
|
if (expansion) {
|
|
484
|
-
|
|
485
|
-
|
|
755
|
+
const ctrl = this.stateController.expansion;
|
|
756
|
+
const predicate = this.expansion?.isExpandable;
|
|
757
|
+
const rows = resolveCounted(expansion, 'expansion');
|
|
758
|
+
const expected = predicate ? rows.filter((row) => predicate(row)) : rows;
|
|
759
|
+
if (this.#replaceRows('expansion', ctrl.enabled, expected, warn, () => {
|
|
760
|
+
void ctrl.replaceExpansion(expected);
|
|
761
|
+
return ctrl.expandedRows();
|
|
762
|
+
})) {
|
|
763
|
+
applied.push('expansion');
|
|
764
|
+
}
|
|
486
765
|
}
|
|
487
766
|
if (state.rowPinning !== undefined) {
|
|
488
767
|
const pinning = state.rowPinning;
|
|
@@ -496,8 +775,19 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
496
775
|
}
|
|
497
776
|
const selection = asArray(state.selection, 'selection');
|
|
498
777
|
if (selection) {
|
|
499
|
-
|
|
500
|
-
|
|
778
|
+
const ctrl = this.stateController.selection;
|
|
779
|
+
const resolved = resolveCounted(selection, 'selection');
|
|
780
|
+
const rows = ctrl.selectable(resolved);
|
|
781
|
+
if (rows.length < resolved.length) {
|
|
782
|
+
warn(`selection: ${resolved.length - rows.length} row(s) are not selectable; skipped`);
|
|
783
|
+
}
|
|
784
|
+
const expected = ctrl.mode === 'single' ? rows.slice(0, 1) : rows;
|
|
785
|
+
if (this.#replaceRows('selection', ctrl.enabled, expected, warn, () => {
|
|
786
|
+
void ctrl.replaceSelection(expected);
|
|
787
|
+
return ctrl.selectedRows();
|
|
788
|
+
})) {
|
|
789
|
+
applied.push('selection');
|
|
790
|
+
}
|
|
501
791
|
}
|
|
502
792
|
if (state.pagination !== undefined) {
|
|
503
793
|
const pagination = state.pagination;
|
|
@@ -514,10 +804,13 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
514
804
|
if (page !== undefined) {
|
|
515
805
|
if (typeof page === 'number' && Number.isFinite(page)) {
|
|
516
806
|
const requested = Math.trunc(page);
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
807
|
+
const reshaped = applied.some((slice) => VIEW_SHAPING_SLICES.has(slice));
|
|
808
|
+
const ctrl = this.stateController.pagination;
|
|
809
|
+
const next = viewSettled && !reshaped ? ctrl.clamp(requested) : Math.max(0, requested);
|
|
810
|
+
if (next !== requested) {
|
|
811
|
+
warn(`pagination: page ${requested} out of range; clamped to ${next}`);
|
|
520
812
|
}
|
|
813
|
+
ctrl.page = next;
|
|
521
814
|
}
|
|
522
815
|
else {
|
|
523
816
|
warn(`pagination: invalid page ${String(page)}; ignored`);
|
|
@@ -533,13 +826,37 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
533
826
|
const skipped = SET_STATE_SLICES.filter((slice) => !applied.includes(slice));
|
|
534
827
|
return { applied, skipped, warnings };
|
|
535
828
|
}
|
|
829
|
+
#replaceRows(label, enabled, expected, warn, replace) {
|
|
830
|
+
if (!enabled) {
|
|
831
|
+
if (expected.length)
|
|
832
|
+
warn(`${label}: the feature is disabled on this grid; skipped`);
|
|
833
|
+
return !expected.length;
|
|
834
|
+
}
|
|
835
|
+
const actual = new Set(replace());
|
|
836
|
+
const took = actual.size === new Set(expected).size && expected.every((row) => actual.has(row));
|
|
837
|
+
if (!took)
|
|
838
|
+
warn(`${label}: the change was cancelled by a listener; skipped`);
|
|
839
|
+
return took;
|
|
840
|
+
}
|
|
536
841
|
clearSort(key) {
|
|
842
|
+
if (this.#pendingSort && key !== undefined) {
|
|
843
|
+
this.#pendingSort = this.#pendingSort.filter((each) => each.key !== key);
|
|
844
|
+
}
|
|
845
|
+
else {
|
|
846
|
+
this.#pendingSort = undefined;
|
|
847
|
+
}
|
|
537
848
|
this.stateController.sorting.reset(key);
|
|
538
849
|
this.requestUpdate(PIPELINE);
|
|
539
850
|
}
|
|
540
851
|
clearFilter(key) {
|
|
852
|
+
if (this.#pendingFilter && key !== undefined) {
|
|
853
|
+
this.#pendingFilter = this.#pendingFilter.filter((each) => each.key !== key);
|
|
854
|
+
}
|
|
855
|
+
else {
|
|
856
|
+
this.#pendingFilter = undefined;
|
|
857
|
+
}
|
|
858
|
+
this.#markViewChange();
|
|
541
859
|
this.stateController.filtering.reset(key);
|
|
542
|
-
this.requestUpdate(PIPELINE);
|
|
543
860
|
}
|
|
544
861
|
gotoPage(page) {
|
|
545
862
|
return this.stateController.pagination.gotoPage(page);
|
|
@@ -563,15 +880,21 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
563
880
|
const next = value ?? '';
|
|
564
881
|
if (next === this.quickFilter)
|
|
565
882
|
return false;
|
|
883
|
+
const previous = this.quickFilter;
|
|
884
|
+
const writes = this.#quickFilterWrites;
|
|
566
885
|
const proceed = this.emitEvent('quickFilterChanging', {
|
|
567
|
-
detail: { value:
|
|
886
|
+
detail: { value: previous, nextValue: next },
|
|
568
887
|
cancelable: true,
|
|
569
888
|
});
|
|
570
889
|
if (!proceed)
|
|
571
890
|
return false;
|
|
572
|
-
this
|
|
573
|
-
|
|
574
|
-
|
|
891
|
+
if (this.#quickFilterWrites === writes)
|
|
892
|
+
this.quickFilter = next;
|
|
893
|
+
if (this.quickFilter === previous)
|
|
894
|
+
return false;
|
|
895
|
+
const pageReset = this.stateController.pagination.resetPage();
|
|
896
|
+
await this.pipelineSettled();
|
|
897
|
+
await pageReset;
|
|
575
898
|
this.emitEvent('quickFilterChanged', { detail: { value: this.quickFilter } });
|
|
576
899
|
return true;
|
|
577
900
|
}
|
|
@@ -643,16 +966,22 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
643
966
|
return tally;
|
|
644
967
|
const editing = this.stateController.editing;
|
|
645
968
|
const items = this.pageItems;
|
|
969
|
+
const indexOf = viewIndexer(items, edits.length);
|
|
970
|
+
const version = editing.validationVersion;
|
|
646
971
|
this.stateController.history.beginBatch();
|
|
647
972
|
try {
|
|
648
|
-
for (const { rowIndex, column, value } of edits) {
|
|
649
|
-
const record = items
|
|
973
|
+
for (const { row, rowIndex, column, value } of edits) {
|
|
974
|
+
const record = row ?? items[rowIndex];
|
|
650
975
|
const config = this.getColumn(column);
|
|
651
|
-
if (!record ||
|
|
976
|
+
if (!record ||
|
|
977
|
+
!config ||
|
|
978
|
+
!editing.isEditable(config) ||
|
|
979
|
+
!this.stateController.isDataRow(record)) {
|
|
652
980
|
tally.skipped += 1;
|
|
653
981
|
continue;
|
|
654
982
|
}
|
|
655
|
-
|
|
983
|
+
const index = row ? indexOf(row) : rowIndex;
|
|
984
|
+
tally[editing.applyCellEdit(index, column, record, value)] += 1;
|
|
656
985
|
}
|
|
657
986
|
}
|
|
658
987
|
finally {
|
|
@@ -660,6 +989,8 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
660
989
|
}
|
|
661
990
|
if (tally.applied > 0)
|
|
662
991
|
this.requestUpdate(PIPELINE);
|
|
992
|
+
else if (editing.validationVersion !== version)
|
|
993
|
+
this.requestUpdate();
|
|
663
994
|
return tally;
|
|
664
995
|
}
|
|
665
996
|
cancelEdit() {
|
|
@@ -731,22 +1062,20 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
731
1062
|
const target = this.columns[toIndex];
|
|
732
1063
|
if ((source.pinned ?? null) !== (target.pinned ?? null))
|
|
733
1064
|
return false;
|
|
734
|
-
const proceed = this.emitEvent('columnMoving', {
|
|
735
|
-
detail: { key: fromKey, fromIndex, toKey, position },
|
|
736
|
-
cancelable: true,
|
|
737
|
-
});
|
|
738
|
-
if (!proceed)
|
|
739
|
-
return false;
|
|
740
1065
|
const next = this.columns.slice();
|
|
741
1066
|
const [moved] = next.splice(fromIndex, 1);
|
|
742
1067
|
let insertIndex = next.findIndex((column) => column.key === toKey);
|
|
743
|
-
if (insertIndex < 0)
|
|
744
|
-
return false;
|
|
745
1068
|
if (position === 'after')
|
|
746
1069
|
insertIndex += 1;
|
|
747
1070
|
next.splice(insertIndex, 0, moved);
|
|
748
1071
|
if (next.every((column, index) => column === this.columns[index]))
|
|
749
1072
|
return false;
|
|
1073
|
+
const proceed = this.emitEvent('columnMoving', {
|
|
1074
|
+
detail: { key: fromKey, fromIndex, toKey, position },
|
|
1075
|
+
cancelable: true,
|
|
1076
|
+
});
|
|
1077
|
+
if (!proceed)
|
|
1078
|
+
return false;
|
|
750
1079
|
this.columns = next;
|
|
751
1080
|
await this.updateComplete;
|
|
752
1081
|
const resolvedIndex = this.columns.findIndex((column) => column.key === fromKey);
|
|
@@ -755,8 +1084,43 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
755
1084
|
});
|
|
756
1085
|
return true;
|
|
757
1086
|
}
|
|
1087
|
+
ownsEvent(event) {
|
|
1088
|
+
for (const node of event.composedPath()) {
|
|
1089
|
+
if (node === this || node === this.scrollContainer)
|
|
1090
|
+
return true;
|
|
1091
|
+
if (node instanceof _a || node instanceof ApexVirtualizer)
|
|
1092
|
+
return false;
|
|
1093
|
+
}
|
|
1094
|
+
return false;
|
|
1095
|
+
}
|
|
1096
|
+
#syncBodyTabStop() {
|
|
1097
|
+
const body = this.scrollContainer;
|
|
1098
|
+
if (!body)
|
|
1099
|
+
return;
|
|
1100
|
+
const active = this.stateController.active;
|
|
1101
|
+
body.tabIndex = active !== SENTINEL_NODE && body.isRendered(active.row) ? -1 : 0;
|
|
1102
|
+
}
|
|
1103
|
+
bodyRangeChanged(event) {
|
|
1104
|
+
const { first, last } = event;
|
|
1105
|
+
this.#syncBodyTabStop();
|
|
1106
|
+
const focused = this.renderRoot instanceof ShadowRoot ? this.renderRoot.activeElement : null;
|
|
1107
|
+
if (focused instanceof ApexGridRow &&
|
|
1108
|
+
focused.parentElement === this.scrollContainer &&
|
|
1109
|
+
(focused.index < first || focused.index > last)) {
|
|
1110
|
+
this.scrollContainer.focus({ preventScroll: true });
|
|
1111
|
+
}
|
|
1112
|
+
this.stateController.navigation.reconcileFocus();
|
|
1113
|
+
}
|
|
1114
|
+
#ownCell(event) {
|
|
1115
|
+
if (!this.ownsEvent(event))
|
|
1116
|
+
return undefined;
|
|
1117
|
+
return event.composedPath().find((el) => el instanceof ApexGridCell);
|
|
1118
|
+
}
|
|
758
1119
|
bodyClickHandler(event) {
|
|
759
|
-
|
|
1120
|
+
if (!this.ownsEvent(event))
|
|
1121
|
+
return;
|
|
1122
|
+
const path = event.composedPath();
|
|
1123
|
+
const target = path.find((el) => el instanceof ApexGridCell);
|
|
760
1124
|
if (target) {
|
|
761
1125
|
this.stateController.active = {
|
|
762
1126
|
column: target.column.key,
|
|
@@ -765,26 +1129,43 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
765
1129
|
if (!target.editing)
|
|
766
1130
|
target.focus({ preventScroll: true });
|
|
767
1131
|
}
|
|
1132
|
+
else {
|
|
1133
|
+
const row = path.find((el) => el instanceof ApexGridRow);
|
|
1134
|
+
const cell = row?.presentedCell;
|
|
1135
|
+
if (row && cell && path.includes(cell)) {
|
|
1136
|
+
const { column } = this.stateController.active;
|
|
1137
|
+
this.stateController.active = { column, row: row.index };
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
768
1140
|
}
|
|
769
1141
|
bodyKeydownHandler(event) {
|
|
1142
|
+
if (!this.ownsEvent(event))
|
|
1143
|
+
return;
|
|
770
1144
|
const origin = event.composedPath()[0];
|
|
771
1145
|
const fromBody = this.scrollContainer.isSameNode(event.target);
|
|
772
|
-
const fromCell = origin instanceof ApexGridCell && !origin.editing
|
|
1146
|
+
const fromCell = (origin instanceof ApexGridCell && !origin.editing) ||
|
|
1147
|
+
(event.target instanceof ApexGridRow && event.target.presentedCell === origin);
|
|
773
1148
|
if (fromBody || fromCell) {
|
|
774
1149
|
this.stateController.navigation.navigate(event);
|
|
775
1150
|
}
|
|
776
1151
|
}
|
|
777
1152
|
bodyFocusHandler(event) {
|
|
778
|
-
|
|
779
|
-
|
|
1153
|
+
const navigation = this.stateController.navigation;
|
|
1154
|
+
navigation.focusEntered(event, this.ownsEvent(event));
|
|
1155
|
+
if (this.scrollContainer.isSameNode(event.target) &&
|
|
1156
|
+
navigation.forwardsBodyFocus) {
|
|
1157
|
+
navigation.focusActiveCell();
|
|
780
1158
|
}
|
|
781
1159
|
}
|
|
1160
|
+
bodyFocusOutHandler(event) {
|
|
1161
|
+
this.stateController.navigation.focusLeft(event, this.ownsEvent(event));
|
|
1162
|
+
}
|
|
782
1163
|
bodyPointerHandler(event) {
|
|
783
1164
|
if (this.stateController.modules.size === 0)
|
|
784
1165
|
return;
|
|
785
1166
|
if (event.type === 'pointermove' && event.buttons === 0)
|
|
786
1167
|
return;
|
|
787
|
-
const target = event
|
|
1168
|
+
const target = this.#ownCell(event);
|
|
788
1169
|
if (!target?.row)
|
|
789
1170
|
return;
|
|
790
1171
|
const kind = event.type === 'pointerdown' ? 'down' : event.type === 'pointerup' ? 'up' : 'over';
|
|
@@ -804,6 +1185,7 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
804
1185
|
return nothing;
|
|
805
1186
|
return html `
|
|
806
1187
|
<apex-grid-group-header-row
|
|
1188
|
+
?data-visually-hidden=${!this.showHeader}
|
|
807
1189
|
style=${styleMap(this.DOM.columnSizes)}
|
|
808
1190
|
.columns=${this.DOM.displayColumns}
|
|
809
1191
|
.pinOffsets=${this.DOM.pinOffsets}
|
|
@@ -814,6 +1196,7 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
814
1196
|
renderHeaderRow() {
|
|
815
1197
|
return html `
|
|
816
1198
|
<apex-grid-header-row
|
|
1199
|
+
?data-visually-hidden=${!this.showHeader}
|
|
817
1200
|
style=${styleMap(this.DOM.columnSizes)}
|
|
818
1201
|
.columns=${this.DOM.displayColumns}
|
|
819
1202
|
.pinOffsets=${this.DOM.pinOffsets}
|
|
@@ -824,45 +1207,42 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
824
1207
|
renderBody() {
|
|
825
1208
|
return html `
|
|
826
1209
|
<apex-virtualizer
|
|
1210
|
+
role="rowgroup"
|
|
827
1211
|
.items=${this.pageItems}
|
|
828
1212
|
.renderItem=${this.DOM.rowRenderer}
|
|
1213
|
+
.rowMode=${this.rowRecycling ? 'slot' : 'item'}
|
|
829
1214
|
@click=${this.bodyClickHandler}
|
|
830
1215
|
@keydown=${this.bodyKeydownHandler}
|
|
831
1216
|
@focusin=${this.bodyFocusHandler}
|
|
1217
|
+
@focusout=${this.bodyFocusOutHandler}
|
|
1218
|
+
@rangeChanged=${this.bodyRangeChanged}
|
|
832
1219
|
@pointerdown=${this.bodyPointerHandler}
|
|
833
1220
|
@pointermove=${this.bodyPointerHandler}
|
|
834
1221
|
@pointerup=${this.bodyPointerHandler}
|
|
835
1222
|
></apex-virtualizer>
|
|
836
1223
|
`;
|
|
837
1224
|
}
|
|
838
|
-
get headerRowCount() {
|
|
839
|
-
return this.columnGroupDepth + 1 + (this.columns.some((column) => column.filter) ? 1 : 0);
|
|
840
|
-
}
|
|
841
1225
|
renderPinnedTop() {
|
|
842
1226
|
const rowPin = this.stateController.rowPin;
|
|
843
|
-
if (!rowPin.enabled)
|
|
844
|
-
return nothing;
|
|
845
1227
|
const rows = rowPin.pinnedRows.top;
|
|
846
1228
|
if (rows.length === 0)
|
|
847
1229
|
return nothing;
|
|
848
1230
|
return html `<div part="pinned-rows pinned-top">
|
|
849
|
-
${rows.map((data, i) => this.DOM.pinnedRowRenderer(data, i, this.headerRowCount))}
|
|
1231
|
+
${rows.map((data, i) => this.DOM.pinnedRowRenderer(data, i, this.DOM.headerRowCount))}
|
|
850
1232
|
</div>`;
|
|
851
1233
|
}
|
|
852
1234
|
renderPinnedBottom() {
|
|
853
1235
|
const rowPin = this.stateController.rowPin;
|
|
854
|
-
if (!rowPin.enabled)
|
|
855
|
-
return nothing;
|
|
856
1236
|
const rows = rowPin.pinnedRows.bottom;
|
|
857
1237
|
if (rows.length === 0)
|
|
858
1238
|
return nothing;
|
|
859
|
-
const offset = this.headerRowCount + rowPin.pinnedRows.top.length + this.pageItems.length;
|
|
1239
|
+
const offset = this.DOM.headerRowCount + rowPin.pinnedRows.top.length + this.pageItems.length;
|
|
860
1240
|
return html `<div part="pinned-rows pinned-bottom">
|
|
861
1241
|
${rows.map((data, i) => this.DOM.pinnedRowRenderer(data, i, offset))}
|
|
862
1242
|
</div>`;
|
|
863
1243
|
}
|
|
864
1244
|
renderFilterRow() {
|
|
865
|
-
return this.columns.some((column) => column.filter)
|
|
1245
|
+
return this.showHeader && this.columns.some((column) => column.filter)
|
|
866
1246
|
? html `<apex-filter-row></apex-filter-row>`
|
|
867
1247
|
: nothing;
|
|
868
1248
|
}
|
|
@@ -871,22 +1251,27 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
871
1251
|
return nothing;
|
|
872
1252
|
}
|
|
873
1253
|
return html `<apex-grid-toolbar
|
|
1254
|
+
part="toolbar-host"
|
|
1255
|
+
exportparts="toolbar,toolbar-search,search-field,search-icon,search-input,toolbar-actions,toolbar-action,export,export-trigger,export-icon,export-caret,export-menu,export-menu-item"
|
|
874
1256
|
.value=${this.quickFilter}
|
|
875
1257
|
.showQuickFilter=${this.showQuickFilter}
|
|
876
1258
|
.showExport=${this.showExport}
|
|
877
1259
|
@apex-quick-filter=${(event) => {
|
|
878
1260
|
event.stopPropagation();
|
|
879
1261
|
this.setQuickFilter(event.detail);
|
|
1262
|
+
if (this.quickFilter !== event.detail)
|
|
1263
|
+
event.preventDefault();
|
|
880
1264
|
}}
|
|
881
1265
|
></apex-grid-toolbar>`;
|
|
882
1266
|
}
|
|
883
1267
|
renderPaginator() {
|
|
884
1268
|
if (!this.stateController.pagination.enabled)
|
|
885
1269
|
return nothing;
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
1270
|
+
return html `<apex-grid-paginator
|
|
1271
|
+
part="paginator-host"
|
|
1272
|
+
exportparts="paginator,paginator-size,paginator-info,paginator-controls,paginator-page,paginator-button,paginator-first,paginator-prev,paginator-next,paginator-last"
|
|
1273
|
+
.pageSizeOptions=${this.pagination?.pageSizeOptions ?? DEFAULT_PAGINATION.pageSizeOptions}
|
|
1274
|
+
></apex-grid-paginator>`;
|
|
890
1275
|
}
|
|
891
1276
|
renderLiveRegion() {
|
|
892
1277
|
return html `<div
|
|
@@ -899,6 +1284,22 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
899
1284
|
${this.stateController.announcement}
|
|
900
1285
|
</div>`;
|
|
901
1286
|
}
|
|
1287
|
+
renderColumnDragGhost() {
|
|
1288
|
+
const state = this.stateController.reordering.state;
|
|
1289
|
+
if (!state)
|
|
1290
|
+
return nothing;
|
|
1291
|
+
return html `<div
|
|
1292
|
+
part="drag-ghost"
|
|
1293
|
+
style=${styleMap({
|
|
1294
|
+
left: `${state.ghostX}px`,
|
|
1295
|
+
top: `${state.ghostY}px`,
|
|
1296
|
+
width: `${state.ghostWidth}px`,
|
|
1297
|
+
height: `${state.ghostHeight}px`,
|
|
1298
|
+
})}
|
|
1299
|
+
>
|
|
1300
|
+
${state.label}
|
|
1301
|
+
</div>`;
|
|
1302
|
+
}
|
|
902
1303
|
renderRowDragGhost() {
|
|
903
1304
|
const ghost = this.stateController.rowReorder.ghost;
|
|
904
1305
|
if (!ghost)
|
|
@@ -928,18 +1329,45 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
928
1329
|
>`)}
|
|
929
1330
|
</div>`;
|
|
930
1331
|
}
|
|
1332
|
+
#refs(attr) {
|
|
1333
|
+
const root = this.getRootNode();
|
|
1334
|
+
const found = (this.getAttribute(attr) ?? '')
|
|
1335
|
+
.split(/\s+/)
|
|
1336
|
+
.flatMap((id) => (id && root.getElementById?.(id)) || []);
|
|
1337
|
+
return found.length ? found : null;
|
|
1338
|
+
}
|
|
1339
|
+
renderTable() {
|
|
1340
|
+
const state = this.stateController;
|
|
1341
|
+
const { top, bottom } = state.rowPin.pinnedRows;
|
|
1342
|
+
const selection = state.selection;
|
|
1343
|
+
const labelledBy = this.#refs('aria-labelledby');
|
|
1344
|
+
const describedBy = this.#refs('aria-describedby');
|
|
1345
|
+
const copy = (refs) => !('ariaLabelledByElements' in Element.prototype) &&
|
|
1346
|
+
refs?.map((el) => el.textContent?.trim()).join(' ');
|
|
1347
|
+
return html `<div
|
|
1348
|
+
part="table"
|
|
1349
|
+
role=${state.hierarchical ? 'treegrid' : 'grid'}
|
|
1350
|
+
aria-rowcount=${this.DOM.headerRowCount + top.length + this.pageItems.length + bottom.length}
|
|
1351
|
+
aria-colcount=${state.colCount}
|
|
1352
|
+
aria-multiselectable=${selection.enabled && selection.mode === 'multiple' ? 'true' : nothing}
|
|
1353
|
+
aria-label=${copy(labelledBy) || this.getAttribute('aria-label') || this.localize('grid.label')}
|
|
1354
|
+
aria-description=${copy(describedBy) || nothing}
|
|
1355
|
+
.ariaLabelledByElements=${labelledBy}
|
|
1356
|
+
.ariaDescribedByElements=${describedBy}
|
|
1357
|
+
>
|
|
1358
|
+
${this.renderGroupHeaderRow()} ${this.renderHeaderRow()} ${this.renderPinnedTop()}
|
|
1359
|
+
${this.renderBody()} ${this.renderPinnedBottom()}
|
|
1360
|
+
</div>`;
|
|
1361
|
+
}
|
|
931
1362
|
render() {
|
|
932
1363
|
return html `
|
|
933
1364
|
${this.stateController.resizing.renderIndicator()}
|
|
934
1365
|
${this.renderToolbar()}
|
|
935
|
-
${this.
|
|
936
|
-
${this.renderHeaderRow()}
|
|
1366
|
+
${this.renderTable()}
|
|
937
1367
|
${this.renderFilterRow()}
|
|
938
|
-
${this.renderPinnedTop()}
|
|
939
|
-
${this.renderBody()}
|
|
940
|
-
${this.renderPinnedBottom()}
|
|
941
1368
|
${this.renderPaginator()}
|
|
942
1369
|
${this.renderLiveRegion()}
|
|
1370
|
+
${this.renderColumnDragGhost()}
|
|
943
1371
|
${this.renderRowDragGhost()}
|
|
944
1372
|
`;
|
|
945
1373
|
}
|
|
@@ -947,6 +1375,7 @@ export class ApexGrid extends EventEmitterBase {
|
|
|
947
1375
|
this.stateController.setAnnouncement(message);
|
|
948
1376
|
}
|
|
949
1377
|
}
|
|
1378
|
+
_a = ApexGrid;
|
|
950
1379
|
__decorate([
|
|
951
1380
|
query(ApexVirtualizer.tagName)
|
|
952
1381
|
], ApexGrid.prototype, "scrollContainer", void 0);
|
|
@@ -973,7 +1402,7 @@ __decorate([
|
|
|
973
1402
|
], ApexGrid.prototype, "columns", void 0);
|
|
974
1403
|
__decorate([
|
|
975
1404
|
property({ attribute: false })
|
|
976
|
-
], ApexGrid.prototype, "data",
|
|
1405
|
+
], ApexGrid.prototype, "data", null);
|
|
977
1406
|
__decorate([
|
|
978
1407
|
property({ attribute: false })
|
|
979
1408
|
], ApexGrid.prototype, "rowId", void 0);
|
|
@@ -991,7 +1420,7 @@ __decorate([
|
|
|
991
1420
|
], ApexGrid.prototype, "pagination", void 0);
|
|
992
1421
|
__decorate([
|
|
993
1422
|
property({ type: String, attribute: 'quick-filter' })
|
|
994
|
-
], ApexGrid.prototype, "quickFilter",
|
|
1423
|
+
], ApexGrid.prototype, "quickFilter", null);
|
|
995
1424
|
__decorate([
|
|
996
1425
|
property({ type: Boolean, attribute: 'show-quick-filter' })
|
|
997
1426
|
], ApexGrid.prototype, "showQuickFilter", void 0);
|
|
@@ -1007,6 +1436,9 @@ __decorate([
|
|
|
1007
1436
|
__decorate([
|
|
1008
1437
|
property({ type: Boolean, attribute: 'column-separator', reflect: true })
|
|
1009
1438
|
], ApexGrid.prototype, "columnSeparator", void 0);
|
|
1439
|
+
__decorate([
|
|
1440
|
+
property({ attribute: 'row-recycling', converter: (value) => value !== 'false' })
|
|
1441
|
+
], ApexGrid.prototype, "rowRecycling", null);
|
|
1010
1442
|
__decorate([
|
|
1011
1443
|
property({ attribute: false })
|
|
1012
1444
|
], ApexGrid.prototype, "editing", void 0);
|
|
@@ -1028,6 +1460,9 @@ __decorate([
|
|
|
1028
1460
|
__decorate([
|
|
1029
1461
|
property({ attribute: false })
|
|
1030
1462
|
], ApexGrid.prototype, "columnMenu", void 0);
|
|
1463
|
+
__decorate([
|
|
1464
|
+
property({ attribute: 'show-header', converter: (value) => value !== 'false' })
|
|
1465
|
+
], ApexGrid.prototype, "showHeader", void 0);
|
|
1031
1466
|
__decorate([
|
|
1032
1467
|
property({ attribute: false })
|
|
1033
1468
|
], ApexGrid.prototype, "columnGroups", void 0);
|
|
@@ -1052,16 +1487,22 @@ __decorate([
|
|
|
1052
1487
|
__decorate([
|
|
1053
1488
|
watch('data')
|
|
1054
1489
|
], ApexGrid.prototype, "dataChanged", null);
|
|
1055
|
-
__decorate([
|
|
1056
|
-
watch(PIPELINE)
|
|
1057
|
-
], ApexGrid.prototype, "pipeline", null);
|
|
1058
1490
|
__decorate([
|
|
1059
1491
|
watch('pagination')
|
|
1060
1492
|
], ApexGrid.prototype, "paginationChanged", null);
|
|
1061
1493
|
__decorate([
|
|
1062
1494
|
watch('quickFilter')
|
|
1063
1495
|
], ApexGrid.prototype, "quickFilterChanged", null);
|
|
1496
|
+
__decorate([
|
|
1497
|
+
watch('tree', { waitUntilFirstUpdate: true })
|
|
1498
|
+
], ApexGrid.prototype, "treeChanged", null);
|
|
1499
|
+
__decorate([
|
|
1500
|
+
watch(PIPELINE)
|
|
1501
|
+
], ApexGrid.prototype, "pipeline", null);
|
|
1064
1502
|
__decorate([
|
|
1065
1503
|
eventOptions({ capture: true })
|
|
1066
1504
|
], ApexGrid.prototype, "bodyClickHandler", null);
|
|
1505
|
+
__decorate([
|
|
1506
|
+
eventOptions({ capture: true })
|
|
1507
|
+
], ApexGrid.prototype, "bodyFocusOutHandler", null);
|
|
1067
1508
|
//# sourceMappingURL=grid.js.map
|