apex-grid 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +338 -0
- package/LICENSE.md +125 -0
- package/README.md +64 -10
- package/components/cell.d.ts +30 -4
- package/components/cell.js +199 -53
- 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 +146 -36
- package/components/grid.js +442 -103
- 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 +7 -5
- package/components/header-row.js +11 -9
- package/components/header-row.js.map +1 -1
- package/components/header.js +32 -20
- package/components/header.js.map +1 -1
- package/components/row.d.ts +19 -3
- package/components/row.js +69 -23
- package/components/row.js.map +1 -1
- package/components/toolbar.js +2 -1
- package/components/toolbar.js.map +1 -1
- package/components/virtualizer.d.ts +40 -0
- package/components/virtualizer.js +116 -5
- package/components/virtualizer.js.map +1 -1
- package/controllers/dom.d.ts +4 -4
- package/controllers/dom.js +40 -22
- 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 +67 -13
- package/controllers/navigation.js +191 -51
- package/controllers/navigation.js.map +1 -1
- package/controllers/pagination.d.ts +6 -0
- package/controllers/pagination.js +10 -2
- 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 +20 -2
- package/controllers/row-pin.js +16 -9
- package/controllers/row-pin.js.map +1 -1
- package/controllers/row-reorder.d.ts +31 -11
- package/controllers/row-reorder.js +117 -37
- package/controllers/row-reorder.js.map +1 -1
- package/controllers/selection.d.ts +11 -4
- package/controllers/selection.js +26 -11
- package/controllers/selection.js.map +1 -1
- package/controllers/sort.d.ts +22 -2
- package/controllers/sort.js +29 -23
- package/controllers/sort.js.map +1 -1
- package/controllers/state.d.ts +56 -7
- package/controllers/state.js +76 -6
- 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 +3156 -277
- 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 +155 -81
- package/docs/classes/ApexGridPaginator.html +1 -1
- package/docs/classes/ApexGridToolbar.html +3 -3
- package/docs/functions/localize.html +2 -2
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +74 -11
- 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/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 +1 -1
- package/docs/interfaces/BaseApexEditorContext.html +1 -1
- package/docs/interfaces/BaseFilterExpression.html +2 -2
- package/docs/interfaces/CSVExportOptions.html +12 -4
- package/docs/interfaces/DataPipelineConfiguration.html +1 -1
- package/docs/interfaces/ExportOptions.html +5 -3
- package/docs/interfaces/GridExpansionConfiguration.html +6 -2
- package/docs/interfaces/GridRowReorderingConfiguration.html +1 -1
- package/docs/interfaces/PaginationState.html +1 -1
- 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 +3 -2
- package/docs/modules.html +1 -1
- package/docs/types/ExportSource.html +6 -4
- package/docs/types/OperandKeys.html +9 -0
- package/docs/variables/EN_LOCALE.html +2 -2
- package/i18n/en.d.ts +5 -0
- package/i18n/en.js +5 -0
- package/i18n/en.js.map +1 -1
- package/i18n/es.js +5 -0
- package/i18n/es.js.map +1 -1
- package/internal/column-types.d.ts +27 -1
- package/internal/column-types.js +75 -49
- 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 +39 -7
- package/internal/export.js +35 -34
- package/internal/export.js.map +1 -1
- package/internal/feature-module.d.ts +60 -3
- package/internal/feature-module.js +6 -0
- package/internal/feature-module.js.map +1 -1
- package/internal/index.d.ts +6 -4
- package/internal/index.js +5 -3
- 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 +17 -2
- 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 +13 -1
- 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 +8 -3
- 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/components/cell.d.ts
CHANGED
|
@@ -46,13 +46,30 @@ export default class ApexGridCell<T extends object> extends LitElement {
|
|
|
46
46
|
* auto-rendered selection + expansion columns ahead of the data columns.
|
|
47
47
|
*/
|
|
48
48
|
colindex: number;
|
|
49
|
+
/**
|
|
50
|
+
* The parent row's view index, set by the row. Changing it re-decorates the
|
|
51
|
+
* cell (decoration such as a range selection is positional), so a row that
|
|
52
|
+
* moves with the same data (sort, filter, an expand above it) never keeps a
|
|
53
|
+
* stale highlight.
|
|
54
|
+
*
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
rowIndex: number;
|
|
49
58
|
/**
|
|
50
59
|
* Reactive token forwarded from {@link StateController.decorationVersion}.
|
|
51
|
-
* Changing it re-
|
|
52
|
-
* re-
|
|
53
|
-
*
|
|
60
|
+
* Changing it re-applies module-driven cell decoration (e.g. while dragging a
|
|
61
|
+
* selection range) without re-rendering the cell content. Stays `0` for the
|
|
62
|
+
* community grid, so cells are never re-decorated there.
|
|
54
63
|
*/
|
|
55
64
|
decorationVersion: number;
|
|
65
|
+
/**
|
|
66
|
+
* Reactive token forwarded from {@link StateController.dataVersion}, bumped
|
|
67
|
+
* once per pipeline run. Re-renders only a cell that reads its row beyond
|
|
68
|
+
* its own value (see {@link shouldUpdate}).
|
|
69
|
+
*
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
dataVersion: number;
|
|
56
73
|
/**
|
|
57
74
|
* Reactive token forwarded from {@link EditingController.validationVersion}.
|
|
58
75
|
* Changing it re-runs {@link willUpdate} so the cell re-reads its validation
|
|
@@ -62,7 +79,16 @@ export default class ApexGridCell<T extends object> extends LitElement {
|
|
|
62
79
|
validationVersion: number;
|
|
63
80
|
connectedCallback(): void;
|
|
64
81
|
disconnectedCallback(): void;
|
|
65
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Skips the render when only positional or decoration tokens changed: the
|
|
84
|
+
* decoration is host attributes, so it is reconciled here and the cell
|
|
85
|
+
* template (type renderers, user templates) is not re-run. A cell that reads
|
|
86
|
+
* its row beyond {@link value} (a `cellTemplate`, which may read other fields
|
|
87
|
+
* or the row index, or the tree group cell, whose chevron shows the row's
|
|
88
|
+
* expansion) still renders when the row index or the data token moves.
|
|
89
|
+
*/
|
|
90
|
+
protected shouldUpdate(changed: PropertyValues<this>): boolean;
|
|
91
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
66
92
|
/**
|
|
67
93
|
* The inline error node surfaced when the cell is invalid. `role="alert"`
|
|
68
94
|
* announces the message when it appears, covering the cross-shadow gap where
|
package/components/cell.js
CHANGED
|
@@ -11,7 +11,7 @@ import { property, query } from 'lit/decorators.js';
|
|
|
11
11
|
import { gridStateContext } from '../controllers/state.js';
|
|
12
12
|
import { getColumnTypeRenderer } from '../internal/column-types.js';
|
|
13
13
|
import { registerComponent } from '../internal/register.js';
|
|
14
|
-
import { GRID_CELL_TAG } from '../internal/tags.js';
|
|
14
|
+
import { GRID_CELL_TAG, GRID_ROW_TAG } from '../internal/tags.js';
|
|
15
15
|
import { styles } from '../styles/body-cell/body-cell.css.js';
|
|
16
16
|
function isErrorLike(value) {
|
|
17
17
|
return (typeof value === 'object' &&
|
|
@@ -19,16 +19,64 @@ function isErrorLike(value) {
|
|
|
19
19
|
typeof value.code === 'string' &&
|
|
20
20
|
value.code.startsWith('#'));
|
|
21
21
|
}
|
|
22
|
+
function renderedRows(body) {
|
|
23
|
+
if (!body)
|
|
24
|
+
return [];
|
|
25
|
+
return Array.from(body.children).filter((element) => element.localName === GRID_ROW_TAG);
|
|
26
|
+
}
|
|
27
|
+
function tabTarget(count, from, keys, key, step, isFullWidth) {
|
|
28
|
+
const column = keys[keys.indexOf(key) + step];
|
|
29
|
+
if (column !== undefined)
|
|
30
|
+
return { row: from, column };
|
|
31
|
+
const wrapColumn = keys[step > 0 ? 0 : keys.length - 1];
|
|
32
|
+
for (let index = from + step; index >= 0 && index < count; index += step) {
|
|
33
|
+
if (!isFullWidth(index))
|
|
34
|
+
return { row: index, column: wrapColumn };
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
function nearestCellRow(count, start, step, isFullWidth) {
|
|
39
|
+
const origin = Math.min(Math.max(start, 0), count - 1);
|
|
40
|
+
for (let distance = 0; distance < count; distance++) {
|
|
41
|
+
for (const index of [origin + distance * step, origin - distance * step]) {
|
|
42
|
+
if (index >= 0 && index < count && !isFullWidth(index))
|
|
43
|
+
return index;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return -1;
|
|
47
|
+
}
|
|
48
|
+
function findRenderedCell(body, node) {
|
|
49
|
+
return renderedRows(body)
|
|
50
|
+
.find((row) => row.index === node.row)
|
|
51
|
+
?.cells.find((cell) => cell.column.key === node.column);
|
|
52
|
+
}
|
|
53
|
+
function scrollRowIntoRange(scroller, body, index) {
|
|
54
|
+
const rows = renderedRows(body).sort((a, b) => a.index - b.index);
|
|
55
|
+
const first = rows.at(0);
|
|
56
|
+
const last = rows.at(-1);
|
|
57
|
+
if (!first || !last)
|
|
58
|
+
return;
|
|
59
|
+
const top = first.getBoundingClientRect().top;
|
|
60
|
+
const height = (last.getBoundingClientRect().bottom - top) / (last.index - first.index + 1);
|
|
61
|
+
const view = scroller.getBoundingClientRect();
|
|
62
|
+
const rowCentre = top + (index - first.index + 0.5) * height;
|
|
63
|
+
scroller.scrollTop += rowCentre - (view.top + scroller.clientHeight / 2);
|
|
64
|
+
}
|
|
22
65
|
class ApexGridCell extends LitElement {
|
|
23
66
|
constructor() {
|
|
24
67
|
super(...arguments);
|
|
25
68
|
this.active = false;
|
|
26
69
|
this.editing = false;
|
|
27
70
|
this.colindex = 0;
|
|
71
|
+
this.rowIndex = -1;
|
|
28
72
|
this.decorationVersion = 0;
|
|
73
|
+
this.dataVersion = 0;
|
|
29
74
|
this.validationVersion = 0;
|
|
30
75
|
this.#decoratedKeys = [];
|
|
31
76
|
this.#errors = null;
|
|
77
|
+
this.#staged = false;
|
|
78
|
+
this.#resumed = null;
|
|
79
|
+
this.#reconnected = false;
|
|
32
80
|
this.#handleClick = (event) => {
|
|
33
81
|
if (this.isEditing) {
|
|
34
82
|
event.stopPropagation();
|
|
@@ -56,9 +104,7 @@ class ApexGridCell extends LitElement {
|
|
|
56
104
|
this.#startEdit();
|
|
57
105
|
};
|
|
58
106
|
this.#refocusAfterEdit = false;
|
|
59
|
-
this.#
|
|
60
|
-
return this.editingController.commitCell(value ?? this.#pendingValue);
|
|
61
|
-
};
|
|
107
|
+
this.#commit = () => this.editingController.commitCell();
|
|
62
108
|
this.#cancel = () => {
|
|
63
109
|
this.editingController.cancelCell();
|
|
64
110
|
};
|
|
@@ -68,7 +114,7 @@ class ApexGridCell extends LitElement {
|
|
|
68
114
|
case 'Enter':
|
|
69
115
|
event.preventDefault();
|
|
70
116
|
this.#refocusAfterEdit = true;
|
|
71
|
-
this.#
|
|
117
|
+
this.#commit();
|
|
72
118
|
return;
|
|
73
119
|
case 'Escape':
|
|
74
120
|
event.preventDefault();
|
|
@@ -76,24 +122,12 @@ class ApexGridCell extends LitElement {
|
|
|
76
122
|
this.#cancel();
|
|
77
123
|
return;
|
|
78
124
|
case 'Tab':
|
|
79
|
-
event
|
|
80
|
-
this.#refocusAfterEdit = true;
|
|
81
|
-
this.#commitWith();
|
|
125
|
+
this.#commitAndTab(event);
|
|
82
126
|
return;
|
|
83
127
|
default:
|
|
84
128
|
return;
|
|
85
129
|
}
|
|
86
130
|
};
|
|
87
|
-
this.#handleBlur = () => {
|
|
88
|
-
if (!this.isEditing)
|
|
89
|
-
return;
|
|
90
|
-
if (this.editingController.mode === 'cell') {
|
|
91
|
-
this.#commitWith();
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
this.editingController.commitCell(this.#pendingValue);
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
131
|
this.#handleCellKeydown = (event) => {
|
|
98
132
|
if (!this.isEditing)
|
|
99
133
|
return;
|
|
@@ -103,11 +137,8 @@ class ApexGridCell extends LitElement {
|
|
|
103
137
|
this.#cancel();
|
|
104
138
|
return;
|
|
105
139
|
}
|
|
106
|
-
if (event.key === 'Tab')
|
|
107
|
-
event
|
|
108
|
-
this.#refocusAfterEdit = true;
|
|
109
|
-
this.#commitWith();
|
|
110
|
-
}
|
|
140
|
+
if (event.key === 'Tab')
|
|
141
|
+
this.#commitAndTab(event);
|
|
111
142
|
};
|
|
112
143
|
this.#handleCellFocusOut = (event) => {
|
|
113
144
|
if (!this.isEditing)
|
|
@@ -115,26 +146,23 @@ class ApexGridCell extends LitElement {
|
|
|
115
146
|
const next = event.relatedTarget;
|
|
116
147
|
if (next && (this.contains(next) || this.shadowRoot?.contains(next)))
|
|
117
148
|
return;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
this.editingController.commitCell(this.#pendingValue);
|
|
123
|
-
}
|
|
149
|
+
this.#refocusAfterEdit = false;
|
|
150
|
+
this.#commit();
|
|
124
151
|
};
|
|
125
152
|
this.#handleTextInput = (event) => {
|
|
126
153
|
const target = event.target;
|
|
127
|
-
if (this
|
|
154
|
+
if (this.#isNumeric) {
|
|
128
155
|
const numeric = target.valueAsNumber;
|
|
129
|
-
this
|
|
156
|
+
this.editingController.setDraft(target.value === '' || Number.isNaN(numeric) ? null : numeric);
|
|
130
157
|
return;
|
|
131
158
|
}
|
|
132
|
-
this
|
|
159
|
+
this.editingController.setDraft(target.value);
|
|
133
160
|
};
|
|
134
|
-
this.#handleCheckboxChange = (event) => {
|
|
161
|
+
this.#handleCheckboxChange = async (event) => {
|
|
135
162
|
const target = event.target;
|
|
136
|
-
|
|
137
|
-
|
|
163
|
+
if (!(await this.editingController.commitCell(target.checked))) {
|
|
164
|
+
target.checked = !target.checked;
|
|
165
|
+
}
|
|
138
166
|
};
|
|
139
167
|
}
|
|
140
168
|
static get tagName() {
|
|
@@ -152,7 +180,7 @@ class ApexGridCell extends LitElement {
|
|
|
152
180
|
value: this.value,
|
|
153
181
|
};
|
|
154
182
|
if (this.isEditable) {
|
|
155
|
-
ctx.commit = (next) => this.editingController.commitImmediate(this.row.
|
|
183
|
+
ctx.commit = (next) => this.editingController.commitImmediate(this.row.data, this.column.key, next);
|
|
156
184
|
}
|
|
157
185
|
return ctx;
|
|
158
186
|
}
|
|
@@ -167,10 +195,18 @@ class ApexGridCell extends LitElement {
|
|
|
167
195
|
return false;
|
|
168
196
|
return this.editingController.isEditable(this.column);
|
|
169
197
|
}
|
|
198
|
+
get #inPinnedBand() {
|
|
199
|
+
const pin = this.state.rowPin;
|
|
200
|
+
return pin.hasPinnedRows && pin.enabled && pin.isPinned(this.row.data);
|
|
201
|
+
}
|
|
170
202
|
#decoratedKeys;
|
|
171
203
|
static #ERROR_ID = 'apex-cell-error';
|
|
172
204
|
#errors;
|
|
205
|
+
#staged;
|
|
206
|
+
#resumed;
|
|
207
|
+
#reconnected;
|
|
173
208
|
connectedCallback() {
|
|
209
|
+
this.#reconnected = this.hasUpdated && !this.isUpdatePending;
|
|
174
210
|
super.connectedCallback();
|
|
175
211
|
this.setAttribute('role', 'gridcell');
|
|
176
212
|
this.addEventListener('click', this.#handleClick);
|
|
@@ -185,7 +221,29 @@ class ApexGridCell extends LitElement {
|
|
|
185
221
|
this.removeEventListener('focusout', this.#handleCellFocusOut);
|
|
186
222
|
super.disconnectedCallback();
|
|
187
223
|
}
|
|
188
|
-
|
|
224
|
+
shouldUpdate(changed) {
|
|
225
|
+
const reconnected = this.#reconnected;
|
|
226
|
+
this.#reconnected = false;
|
|
227
|
+
if (!this.hasUpdated || (!changed.size && !reconnected))
|
|
228
|
+
return true;
|
|
229
|
+
const tree = this.state?.tree;
|
|
230
|
+
const readsRow = this.column.cellTemplate || (tree?.enabled && tree.isGroupColumn(this.column.key));
|
|
231
|
+
for (const key of changed.keys()) {
|
|
232
|
+
const token = key === 'rowIndex' || key === 'dataVersion';
|
|
233
|
+
if (key !== 'decorationVersion' && (readsRow || !token))
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
if (changed.has('decorationVersion') || changed.has('rowIndex'))
|
|
237
|
+
this.#applyDecoration();
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
willUpdate(changed) {
|
|
241
|
+
this.#applyStaged();
|
|
242
|
+
if (changed.has('editing')) {
|
|
243
|
+
this.#resumed = this.editing
|
|
244
|
+
? this.editingController.heldDraft(this.row.data, this.column.key)
|
|
245
|
+
: null;
|
|
246
|
+
}
|
|
189
247
|
if (this.colindex > 0) {
|
|
190
248
|
this.setAttribute('aria-colindex', String(this.colindex));
|
|
191
249
|
}
|
|
@@ -210,6 +268,20 @@ class ApexGridCell extends LitElement {
|
|
|
210
268
|
this.#applyValidation();
|
|
211
269
|
this.#applyDecoration();
|
|
212
270
|
}
|
|
271
|
+
#applyStaged() {
|
|
272
|
+
const staged = this.state?.editing?.activeRow
|
|
273
|
+
? this.editingController.stagedValues(this.row.data)
|
|
274
|
+
: null;
|
|
275
|
+
const key = this.column.key;
|
|
276
|
+
if (staged?.has(key)) {
|
|
277
|
+
this.value = staged.get(key);
|
|
278
|
+
this.#staged = true;
|
|
279
|
+
}
|
|
280
|
+
else if (this.#staged) {
|
|
281
|
+
this.#staged = false;
|
|
282
|
+
this.value = this.row.data[key];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
213
285
|
#applyValidation() {
|
|
214
286
|
const errors = this.state && this.row?.data
|
|
215
287
|
? (this.editingController?.getCellErrors(this.row.data, this.column.key) ?? null)
|
|
@@ -242,7 +314,7 @@ class ApexGridCell extends LitElement {
|
|
|
242
314
|
const decoration = this.state && this.row
|
|
243
315
|
? this.state.decorateCell({
|
|
244
316
|
row: this.row.data,
|
|
245
|
-
rowIndex: this.
|
|
317
|
+
rowIndex: this.#inPinnedBand ? -1 : this.rowIndex,
|
|
246
318
|
column: this.column,
|
|
247
319
|
value: this.value,
|
|
248
320
|
})
|
|
@@ -266,6 +338,8 @@ class ApexGridCell extends LitElement {
|
|
|
266
338
|
}
|
|
267
339
|
updated(changed) {
|
|
268
340
|
if (this.isEditing) {
|
|
341
|
+
if (!changed.has('editing'))
|
|
342
|
+
return;
|
|
269
343
|
const editor = this.editorElement;
|
|
270
344
|
editor?.focus();
|
|
271
345
|
if (editor instanceof HTMLInputElement) {
|
|
@@ -285,22 +359,94 @@ class ApexGridCell extends LitElement {
|
|
|
285
359
|
#startEdit() {
|
|
286
360
|
if (!this.row)
|
|
287
361
|
return;
|
|
288
|
-
this.editingController.
|
|
362
|
+
this.editingController.editRecord(this.row.data, this.column.key);
|
|
289
363
|
}
|
|
290
|
-
#pendingValue;
|
|
291
364
|
#refocusAfterEdit;
|
|
292
|
-
#
|
|
365
|
+
#commit;
|
|
293
366
|
#cancel;
|
|
367
|
+
#commitAndTab(event) {
|
|
368
|
+
event.preventDefault();
|
|
369
|
+
if (this.#inPinnedBand) {
|
|
370
|
+
this.#refocusAfterEdit = true;
|
|
371
|
+
void this.#commit();
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const step = event.shiftKey ? -1 : 1;
|
|
375
|
+
const host = this.state.host;
|
|
376
|
+
const body = this.row.parentElement;
|
|
377
|
+
const record = this.row.data;
|
|
378
|
+
const origin = this.row.index;
|
|
379
|
+
const key = this.column.key;
|
|
380
|
+
const columns = this.row.columns;
|
|
381
|
+
const keys = this.row.cells.map((cell) => cell.column.key);
|
|
382
|
+
const settle = async () => {
|
|
383
|
+
await host.updateComplete;
|
|
384
|
+
await body?.updateComplete;
|
|
385
|
+
await Promise.all(renderedRows(body).map((row) => row.updateComplete));
|
|
386
|
+
};
|
|
387
|
+
void this.#commit().then(async (committed) => {
|
|
388
|
+
if (!committed)
|
|
389
|
+
return;
|
|
390
|
+
await settle();
|
|
391
|
+
const items = host.pageItems;
|
|
392
|
+
const isFullWidth = (index) => items[index] == null ||
|
|
393
|
+
this.state.presentRow(items[index], { columns, rowIndex: index }) !== null;
|
|
394
|
+
const from = items.indexOf(record);
|
|
395
|
+
let target;
|
|
396
|
+
if (from >= 0) {
|
|
397
|
+
target = tabTarget(items.length, from, keys, key, step, isFullWidth) ?? {
|
|
398
|
+
row: from,
|
|
399
|
+
column: key,
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
const row = nearestCellRow(items.length, origin, step, isFullWidth);
|
|
404
|
+
target = row < 0 ? null : { row, column: key };
|
|
405
|
+
}
|
|
406
|
+
if (!target) {
|
|
407
|
+
body?.focus({ preventScroll: true });
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
this.state.active = target;
|
|
411
|
+
await settle();
|
|
412
|
+
let cell = findRenderedCell(body, target);
|
|
413
|
+
for (let attempt = 0; !cell && attempt < 3; attempt++) {
|
|
414
|
+
scrollRowIntoRange(host, body, target.row);
|
|
415
|
+
await new Promise(requestAnimationFrame);
|
|
416
|
+
await new Promise(requestAnimationFrame);
|
|
417
|
+
await settle();
|
|
418
|
+
cell = findRenderedCell(body, target);
|
|
419
|
+
}
|
|
420
|
+
if (!cell) {
|
|
421
|
+
body?.focus({ preventScroll: true });
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
cell.focus({ preventScroll: true });
|
|
425
|
+
cell.scrollIntoView({ block: 'nearest', inline: 'nearest' });
|
|
426
|
+
await new Promise(requestAnimationFrame);
|
|
427
|
+
await new Promise(requestAnimationFrame);
|
|
428
|
+
const active = this.state.active;
|
|
429
|
+
const dropped = !document.activeElement || document.activeElement === document.body;
|
|
430
|
+
if (dropped && active.row === target.row && active.column === target.column) {
|
|
431
|
+
findRenderedCell(body, target)?.focus({ preventScroll: true });
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
}
|
|
294
435
|
#handleKeydown;
|
|
295
|
-
#handleBlur;
|
|
296
436
|
#handleCellKeydown;
|
|
297
437
|
#handleCellFocusOut;
|
|
438
|
+
get #isNumeric() {
|
|
439
|
+
const type = this.column.type;
|
|
440
|
+
return type === 'number' || type === 'currency';
|
|
441
|
+
}
|
|
298
442
|
#handleTextInput;
|
|
299
443
|
#handleCheckboxChange;
|
|
444
|
+
get #editorValue() {
|
|
445
|
+
return this.#resumed ? this.#resumed.value : this.value;
|
|
446
|
+
}
|
|
300
447
|
renderDefaultEditor() {
|
|
301
|
-
const value = this
|
|
448
|
+
const value = this.#editorValue;
|
|
302
449
|
if (this.column.type === 'boolean') {
|
|
303
|
-
this.#pendingValue = Boolean(value);
|
|
304
450
|
return html `<input
|
|
305
451
|
type="checkbox"
|
|
306
452
|
part="editor"
|
|
@@ -308,11 +454,9 @@ class ApexGridCell extends LitElement {
|
|
|
308
454
|
?checked=${Boolean(value)}
|
|
309
455
|
@change=${this.#handleCheckboxChange}
|
|
310
456
|
@keydown=${this.#handleKeydown}
|
|
311
|
-
@blur=${this.#handleBlur}
|
|
312
457
|
/>`;
|
|
313
458
|
}
|
|
314
|
-
if (this
|
|
315
|
-
this.#pendingValue = value;
|
|
459
|
+
if (this.#isNumeric) {
|
|
316
460
|
return html `<input
|
|
317
461
|
type="number"
|
|
318
462
|
part="editor"
|
|
@@ -320,10 +464,8 @@ class ApexGridCell extends LitElement {
|
|
|
320
464
|
.value=${value == null ? '' : String(value)}
|
|
321
465
|
@input=${this.#handleTextInput}
|
|
322
466
|
@keydown=${this.#handleKeydown}
|
|
323
|
-
@blur=${this.#handleBlur}
|
|
324
467
|
/>`;
|
|
325
468
|
}
|
|
326
|
-
this.#pendingValue = value;
|
|
327
469
|
return html `<input
|
|
328
470
|
type="text"
|
|
329
471
|
part="editor"
|
|
@@ -331,7 +473,6 @@ class ApexGridCell extends LitElement {
|
|
|
331
473
|
.value=${value == null ? '' : String(value)}
|
|
332
474
|
@input=${this.#handleTextInput}
|
|
333
475
|
@keydown=${this.#handleKeydown}
|
|
334
|
-
@blur=${this.#handleBlur}
|
|
335
476
|
/>`;
|
|
336
477
|
}
|
|
337
478
|
renderEditor() {
|
|
@@ -340,17 +481,16 @@ class ApexGridCell extends LitElement {
|
|
|
340
481
|
parent: this,
|
|
341
482
|
row: this.row,
|
|
342
483
|
column: this.column,
|
|
343
|
-
value: this
|
|
484
|
+
value: this.#editorValue,
|
|
344
485
|
commit: (next) => this.editingController.commitCell(next),
|
|
345
486
|
cancel: () => this.editingController.cancelCell(),
|
|
487
|
+
setDraft: (next) => this.editingController.setDraft(next),
|
|
346
488
|
};
|
|
347
489
|
if (template) {
|
|
348
|
-
this.#pendingValue = this.value;
|
|
349
490
|
return template(ctx);
|
|
350
491
|
}
|
|
351
492
|
const typeRenderer = getColumnTypeRenderer(this.column.type);
|
|
352
493
|
if (typeRenderer?.editor) {
|
|
353
|
-
this.#pendingValue = this.value;
|
|
354
494
|
return typeRenderer.editor(ctx);
|
|
355
495
|
}
|
|
356
496
|
return this.renderDefaultEditor();
|
|
@@ -470,9 +610,15 @@ __decorate([
|
|
|
470
610
|
__decorate([
|
|
471
611
|
property({ attribute: false, type: Number })
|
|
472
612
|
], ApexGridCell.prototype, "colindex", void 0);
|
|
613
|
+
__decorate([
|
|
614
|
+
property({ attribute: false })
|
|
615
|
+
], ApexGridCell.prototype, "rowIndex", void 0);
|
|
473
616
|
__decorate([
|
|
474
617
|
property({ attribute: false, type: Number })
|
|
475
618
|
], ApexGridCell.prototype, "decorationVersion", void 0);
|
|
619
|
+
__decorate([
|
|
620
|
+
property({ attribute: false })
|
|
621
|
+
], ApexGridCell.prototype, "dataVersion", void 0);
|
|
476
622
|
__decorate([
|
|
477
623
|
property({ attribute: false, type: Number })
|
|
478
624
|
], ApexGridCell.prototype, "validationVersion", void 0);
|