igniteui-grid-lite 0.9.0 → 0.11.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/components/cell.d.ts +11 -15
- package/components/cell.js +14 -3
- package/components/cell.js.map +1 -1
- package/components/column.d.ts +2 -2
- package/components/column.js.map +1 -1
- package/components/filter-row.d.ts +5 -3
- package/components/filter-row.js +97 -67
- package/components/filter-row.js.map +1 -1
- package/components/grid.d.ts +49 -8
- package/components/grid.js +116 -79
- package/components/grid.js.map +1 -1
- package/components/header-row.d.ts +1 -2
- package/components/header-row.js +6 -8
- package/components/header-row.js.map +1 -1
- package/components/header.d.ts +9 -0
- package/components/header.js +37 -28
- package/components/header.js.map +1 -1
- package/components/row.d.ts +4 -4
- package/components/row.js +15 -4
- package/components/row.js.map +1 -1
- package/controllers/data-operation.d.ts +1 -7
- package/controllers/data-operation.js +7 -24
- package/controllers/data-operation.js.map +1 -1
- package/controllers/dom.d.ts +16 -9
- package/controllers/dom.js +71 -20
- package/controllers/dom.js.map +1 -1
- package/controllers/filter.d.ts +17 -13
- package/controllers/filter.js +51 -61
- package/controllers/filter.js.map +1 -1
- package/controllers/navigation.d.ts +13 -18
- package/controllers/navigation.js +71 -76
- package/controllers/navigation.js.map +1 -1
- package/controllers/resize.d.ts +11 -17
- package/controllers/resize.js +20 -16
- package/controllers/resize.js.map +1 -1
- package/controllers/sort.d.ts +13 -6
- package/controllers/sort.js +39 -41
- package/controllers/sort.js.map +1 -1
- package/controllers/state.d.ts +18 -19
- package/controllers/state.js +31 -35
- package/controllers/state.js.map +1 -1
- package/custom-elements.json +970 -488
- package/docs/igniteui-grid-lite.json +1293 -782
- package/index.d.ts +1 -1
- package/index.js.map +1 -1
- package/internal/a11y.d.ts +26 -0
- package/internal/a11y.js +24 -0
- package/internal/a11y.js.map +1 -0
- package/internal/body-focus.d.ts +6 -0
- package/internal/body-focus.js +46 -0
- package/internal/body-focus.js.map +1 -0
- package/internal/constants.d.ts +6 -2
- package/internal/constants.js +3 -4
- package/internal/constants.js.map +1 -1
- package/internal/element-from-event-path.d.ts +1 -1
- package/internal/element-from-event-path.js +2 -9
- package/internal/element-from-event-path.js.map +1 -1
- package/internal/normalize-case.d.ts +5 -1
- package/internal/normalize-case.js +2 -1
- package/internal/normalize-case.js.map +1 -1
- package/internal/part-map.js +9 -17
- package/internal/part-map.js.map +1 -1
- package/internal/tags.d.ts +1 -2
- package/internal/tags.js +1 -2
- package/internal/tags.js.map +1 -1
- package/internal/types.d.ts +19 -8
- package/internal/types.js.map +1 -1
- package/internal/utils.d.ts +7 -8
- package/internal/utils.js +22 -5
- package/internal/utils.js.map +1 -1
- package/internal/watch.js +8 -9
- package/internal/watch.js.map +1 -1
- package/operations/base.js +3 -2
- package/operations/base.js.map +1 -1
- package/operations/filter/state.d.ts +0 -1
- package/operations/filter/state.js +2 -8
- package/operations/filter/state.js.map +1 -1
- package/operations/filter/tree.d.ts +1 -2
- package/operations/filter/tree.js +2 -7
- package/operations/filter/tree.js.map +1 -1
- package/operations/filter/types.d.ts +1 -1
- package/operations/filter/types.js.map +1 -1
- package/operations/filter.js +16 -3
- package/operations/filter.js.map +1 -1
- package/operations/sort/types.d.ts +1 -1
- package/operations/sort/types.js.map +1 -1
- package/operations/sort.d.ts +0 -1
- package/operations/sort.js +12 -10
- package/operations/sort.js.map +1 -1
- package/package.json +2 -3
- package/styles/header-cell/header-cell.css.js +1 -1
- package/styles/header-cell/header-cell.css.js.map +1 -1
- package/styles/themes/filtering-row-themes.js +2 -30
- package/styles/themes/filtering-row-themes.js.map +1 -1
- package/styles/themes/grid-header-themes.js +2 -20
- package/styles/themes/grid-header-themes.js.map +1 -1
- package/styles/themes/grid-themes.js +10 -31
- package/styles/themes/grid-themes.js.map +1 -1
- package/styles/themes/grid.base.css.js +1 -1
- package/styles/themes/grid.base.css.js.map +1 -1
- package/styles/themes/shared/grid.common.css.js +1 -1
- package/styles/themes/shared/grid.common.css.js.map +1 -1
- package/components/virtualizer.d.ts +0 -12
- package/components/virtualizer.js +0 -20
- package/components/virtualizer.js.map +0 -1
- package/internal/virt-flow-layout.d.ts +0 -4
- package/internal/virt-flow-layout.js +0 -15
- package/internal/virt-flow-layout.js.map +0 -1
|
@@ -1,115 +1,110 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { NO_SCROLL, SENTINEL_NODE } from '../internal/constants.js';
|
|
2
|
+
import { clamp, visibleColumns } from '../internal/utils.js';
|
|
3
|
+
const SCROLL_NEAREST = { block: 'nearest' };
|
|
4
|
+
export function activeNodeFor(active, index) {
|
|
5
|
+
return active.row === index ? active : SENTINEL_NODE;
|
|
6
|
+
}
|
|
3
7
|
export class NavigationController {
|
|
4
8
|
get _virtualizer() {
|
|
5
|
-
return this.
|
|
9
|
+
return this._dom.virtualizer;
|
|
6
10
|
}
|
|
7
11
|
get nextNode() {
|
|
8
|
-
|
|
9
|
-
return node === SENTINEL_NODE
|
|
12
|
+
return this._active === SENTINEL_NODE
|
|
10
13
|
? { column: this._firstColumn, row: 0 }
|
|
11
|
-
: { ...
|
|
14
|
+
: { ...this._active };
|
|
12
15
|
}
|
|
13
16
|
get _columns() {
|
|
14
|
-
return this._state.columns;
|
|
17
|
+
return visibleColumns(this._state.columns);
|
|
15
18
|
}
|
|
16
19
|
get _firstColumn() {
|
|
17
|
-
return this.
|
|
18
|
-
}
|
|
19
|
-
getPreviousColumn(key) {
|
|
20
|
-
return this._columns[Math.max(this._columns.indexOf(this._state.host.getColumn(key)) - 1, 0)]
|
|
21
|
-
.field;
|
|
22
|
-
}
|
|
23
|
-
getNextColumn(key) {
|
|
24
|
-
return this._columns[Math.min(this._columns.indexOf(this._state.host.getColumn(key)) + 1, this._columns.length - 1)].field;
|
|
20
|
+
return this._columns.at(0)?.field ?? SENTINEL_NODE.column;
|
|
25
21
|
}
|
|
26
22
|
queryRowByIndex(index) {
|
|
27
|
-
return
|
|
23
|
+
return this._dom.rows.find((row) => row.index === index);
|
|
24
|
+
}
|
|
25
|
+
#queryCell(node) {
|
|
26
|
+
return this.queryRowByIndex(node.row)?.cells.find((cell) => cell.column.field === node.column);
|
|
28
27
|
}
|
|
29
28
|
scrollToCell(node) {
|
|
30
|
-
|
|
31
|
-
if (row) {
|
|
32
|
-
row.cells
|
|
33
|
-
.find((cell) => cell.column.field === node.column)
|
|
34
|
-
?.scrollIntoView({ block: 'nearest' });
|
|
35
|
-
}
|
|
29
|
+
this.#queryCell(node)?.scrollIntoView(SCROLL_NEAREST);
|
|
36
30
|
}
|
|
37
31
|
get active() {
|
|
38
32
|
return this._active;
|
|
39
33
|
}
|
|
40
34
|
set active(node) {
|
|
35
|
+
const previous = this._active;
|
|
41
36
|
this._active = node ?? SENTINEL_NODE;
|
|
42
|
-
this
|
|
43
|
-
this._navigationState.set('current', node);
|
|
37
|
+
this.#updateActiveRows(previous);
|
|
44
38
|
this._state.host.requestUpdate();
|
|
45
39
|
}
|
|
46
|
-
|
|
40
|
+
#updateActiveRows(previous) {
|
|
41
|
+
for (const row of this._dom.rows) {
|
|
42
|
+
if (row.index === previous.row || row.index === this._active.row) {
|
|
43
|
+
row.activeNode = activeNodeFor(this._active, row.index);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async #focusActiveCell() {
|
|
48
|
+
const node = this._active;
|
|
49
|
+
let row = this.queryRowByIndex(node.row);
|
|
50
|
+
if (!row) {
|
|
51
|
+
await this._virtualizer?.layoutComplete;
|
|
52
|
+
row = this.queryRowByIndex(node.row);
|
|
53
|
+
}
|
|
54
|
+
await row?.updateComplete;
|
|
55
|
+
if (node !== this._active) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.#queryCell(node)?.focus(NO_SCROLL);
|
|
59
|
+
}
|
|
60
|
+
constructor(_state, _dom) {
|
|
47
61
|
this._state = _state;
|
|
48
|
-
this.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
this._dom = _dom;
|
|
63
|
+
this.handlers = new Map([
|
|
64
|
+
['ArrowDown', () => this.#moveToRow(this.nextNode.row + 1)],
|
|
65
|
+
['ArrowUp', () => this.#moveToRow(this.nextNode.row - 1)],
|
|
66
|
+
['ArrowLeft', () => this.#moveToColumn(-1)],
|
|
67
|
+
['ArrowRight', () => this.#moveToColumn(1)],
|
|
68
|
+
['Home', () => this.#moveToRow(0)],
|
|
69
|
+
['End', () => this.#moveToRow(this._state.host.totalItems - 1)],
|
|
70
|
+
]);
|
|
57
71
|
this._active = SENTINEL_NODE;
|
|
58
72
|
this._state.host.addController(this);
|
|
59
73
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.
|
|
74
|
+
#moveToRow(row) {
|
|
75
|
+
const clamped = clamp(row, 0, this._state.host.totalItems - 1);
|
|
76
|
+
this.active = Object.assign(this.nextNode, { row: clamped });
|
|
77
|
+
this._virtualizer?.scrollToIndex(clamped, SCROLL_NEAREST);
|
|
63
78
|
}
|
|
64
|
-
|
|
65
|
-
this.active = Object.assign(this.nextNode, { row: this._state.host.totalItems - 1 });
|
|
66
|
-
this._virtualizer?.element(this.active.row)?.scrollIntoView({ block: 'nearest' });
|
|
67
|
-
}
|
|
68
|
-
arrowDown() {
|
|
69
|
-
const next = this.nextNode;
|
|
70
|
-
this.active = Object.assign(next, {
|
|
71
|
-
row: Math.min(next.row + 1, this._state.host.totalItems - 1),
|
|
72
|
-
});
|
|
73
|
-
this._virtualizer?.element(next.row)?.scrollIntoView({ block: 'nearest' });
|
|
74
|
-
}
|
|
75
|
-
arrowUp() {
|
|
76
|
-
const next = this.nextNode;
|
|
77
|
-
this.active = Object.assign(next, { row: Math.max(0, next.row - 1) });
|
|
78
|
-
this._virtualizer?.element(next.row)?.scrollIntoView({ block: 'nearest' });
|
|
79
|
-
}
|
|
80
|
-
arrowLeft() {
|
|
79
|
+
#moveToColumn(offset) {
|
|
81
80
|
const next = this.nextNode;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const next = this.nextNode;
|
|
87
|
-
this.active = Object.assign(next, { column: this.getNextColumn(next.column) });
|
|
81
|
+
const columns = this._columns;
|
|
82
|
+
const index = columns.findIndex((column) => column.field === next.column);
|
|
83
|
+
const target = clamp(index + offset, 0, columns.length - 1);
|
|
84
|
+
this.active = Object.assign(next, { column: columns[target].field });
|
|
88
85
|
this.scrollToCell(this.active);
|
|
89
86
|
}
|
|
90
87
|
hostDisconnected() {
|
|
91
88
|
this.active = SENTINEL_NODE;
|
|
92
|
-
this._navigationState = NAVIGATION_STATE;
|
|
93
89
|
}
|
|
94
90
|
navigate(event) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
const handler = this.handlers.get(event.key);
|
|
92
|
+
if (!handler || this._columns.length === 0 || this._state.host.totalItems === 0) {
|
|
93
|
+
return;
|
|
98
94
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
completePromise = item && this._virtualizer?.layoutComplete;
|
|
95
|
+
event.preventDefault();
|
|
96
|
+
handler();
|
|
97
|
+
this.#focusActiveCell();
|
|
98
|
+
}
|
|
99
|
+
async navigateTo(row, options) {
|
|
100
|
+
const { column, activate } = options ?? {};
|
|
101
|
+
if (activate) {
|
|
102
|
+
this.active = Object.assign(this.nextNode, column ? { row, column } : { row });
|
|
108
103
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (column)
|
|
104
|
+
await this._virtualizer?.scrollToIndex(row, SCROLL_NEAREST);
|
|
105
|
+
if (column) {
|
|
112
106
|
this.scrollToCell({ row, column });
|
|
107
|
+
}
|
|
113
108
|
}
|
|
114
109
|
}
|
|
115
110
|
//# sourceMappingURL=navigation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/controllers/navigation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAInD,MAAM,OAAO,oBAAoB;IAY/B,IAAc,YAAY;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;IACjC,CAAC;IAKD,IAAc,QAAQ;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;QACnD,OAAO,IAAI,KAAK,aAAa;YAC3B,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,EAAE;YACvC,CAAC,CAAE,EAAE,GAAG,IAAI,EAAoB,CAAC;IACrC,CAAC;IAED,IAAc,QAAQ;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,IAAc,YAAY;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,KAAK,IAAI,EAAE,CAAC;IACpD,CAAC;IAES,iBAAiB,CAAC,GAAY;QACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;aAC3F,KAAK,CAAC;IACX,CAAC;IAES,aAAa,CAAC,GAAY;QAClC,OAAO,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAE,CAAC,GAAG,CAAC,EAC3D,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CACzB,CACF,CAAC,KAAK,CAAC;IACV,CAAC;IAES,eAAe,CAAC,KAAa;QACrC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAC7E,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CACG,CAAC;IACpC,CAAC;IAES,YAAY,CAAC,IAAmB;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE3C,IAAI,GAAG,EAAE,CAAC;YACR,GAAG,CAAC,KAAK;iBACN,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC;gBAClD,EAAE,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAwB,CAAC;IACvC,CAAC;IAED,IAAW,MAAM,CAAC,IAAmB;QACnC,IAAI,CAAC,OAAO,GAAG,IAAI,IAAI,aAAa,CAAC;QACrC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IACnC,CAAC;IAED,YAAsB,MAA0B;QAA1B,WAAM,GAAN,MAAM,CAAoB;QA1EtC,aAAQ,GAAG,IAAI,GAAG,CAC1B,MAAM,CAAC,OAAO,CAAC;YACb,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC,CACH,CAAC;QAMQ,qBAAgB,GAAG,gBAAgB,CAAC;QACpC,YAAO,GAAG,aAAa,CAAC;QA2DhC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAES,IAAI;QACZ,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpF,CAAC;IAES,GAAG;QACX,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC,CAAC;QACrF,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpF,CAAC;IAES,SAAS;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAE3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;YAChC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;SAC7D,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7E,CAAC;IAES,OAAO;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7E,CAAC;IAES,SAAS;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAES,UAAU;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/E,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAEM,gBAAgB;QACrB,IAAI,CAAC,MAAM,GAAG,aAA8B,CAAC;QAC7C,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAEM,QAAQ,CAAC,KAAoB;QAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,GAAW,EAAE,MAAgB,EAAE,QAAQ,GAAG,KAAK;QACrE,IAAI,QAAQ;YAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QAG1E,IAAI,IAAI,GAAoD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QACtF,IAAI,eAA0C,CAAC;QAE/C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YACvC,eAAe,GAAG,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC;QAC9D,CAAC;QAED,IAAI,EAAE,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC3C,MAAM,eAAe,CAAC;QACtB,IAAI,MAAM;YAAE,IAAI,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;CACF","sourcesContent":["import type { ReactiveController } from 'lit';\nimport type IgcGridLiteRow from '../components/row.js';\nimport { NAVIGATION_STATE, SENTINEL_NODE } from '../internal/constants.js';\nimport { GRID_ROW_TAG } from '../internal/tags.js';\nimport type { ActiveNode, Keys } from '../internal/types.js';\nimport type { StateController } from './state.js';\n\nexport class NavigationController<T extends object> implements ReactiveController {\n protected handlers = new Map(\n Object.entries({\n ArrowDown: this.arrowDown,\n ArrowUp: this.arrowUp,\n ArrowLeft: this.arrowLeft,\n ArrowRight: this.arrowRight,\n Home: this.home,\n End: this.end,\n })\n );\n\n protected get _virtualizer() {\n return this._state.virtualizer;\n }\n\n protected _navigationState = NAVIGATION_STATE;\n protected _active = SENTINEL_NODE;\n\n protected get nextNode() {\n const node = this._navigationState.get('current')!;\n return node === SENTINEL_NODE\n ? { column: this._firstColumn, row: 0 }\n : ({ ...node } as ActiveNode<T>);\n }\n\n protected get _columns() {\n return this._state.columns;\n }\n\n protected get _firstColumn() {\n return this._state.host.getColumn(0)!.field ?? '';\n }\n\n protected getPreviousColumn(key: Keys<T>) {\n return this._columns[Math.max(this._columns.indexOf(this._state.host.getColumn(key)!) - 1, 0)]\n .field;\n }\n\n protected getNextColumn(key: Keys<T>) {\n return this._columns[\n Math.min(\n this._columns.indexOf(this._state.host.getColumn(key)!) + 1,\n this._columns.length - 1\n )\n ].field;\n }\n\n protected queryRowByIndex(index: number) {\n return Array.from(this._virtualizer?.querySelectorAll(GRID_ROW_TAG) ?? []).find(\n (row) => row.index === index\n ) as unknown as IgcGridLiteRow<T>;\n }\n\n protected scrollToCell(node: ActiveNode<T>) {\n const row = this.queryRowByIndex(node.row);\n\n if (row) {\n row.cells\n .find((cell) => cell.column.field === node.column)\n ?.scrollIntoView({ block: 'nearest' });\n }\n }\n\n public get active(): ActiveNode<T> {\n return this._active as ActiveNode<T>;\n }\n\n public set active(node: ActiveNode<T>) {\n this._active = node ?? SENTINEL_NODE;\n this._navigationState.set('previous', this._active);\n this._navigationState.set('current', node);\n this._state.host.requestUpdate();\n }\n\n constructor(protected _state: StateController<T>) {\n this._state.host.addController(this);\n }\n\n protected home() {\n this.active = Object.assign(this.nextNode, { row: 0 });\n this._virtualizer?.element(this.active.row)?.scrollIntoView({ block: 'nearest' });\n }\n\n protected end() {\n this.active = Object.assign(this.nextNode, { row: this._state.host.totalItems - 1 });\n this._virtualizer?.element(this.active.row)?.scrollIntoView({ block: 'nearest' });\n }\n\n protected arrowDown() {\n const next = this.nextNode;\n\n this.active = Object.assign(next, {\n row: Math.min(next.row + 1, this._state.host.totalItems - 1),\n });\n this._virtualizer?.element(next.row)?.scrollIntoView({ block: 'nearest' });\n }\n\n protected arrowUp() {\n const next = this.nextNode;\n this.active = Object.assign(next, { row: Math.max(0, next.row - 1) });\n this._virtualizer?.element(next.row)?.scrollIntoView({ block: 'nearest' });\n }\n\n protected arrowLeft() {\n const next = this.nextNode;\n this.active = Object.assign(next, { column: this.getPreviousColumn(next.column) });\n this.scrollToCell(this.active);\n }\n\n protected arrowRight() {\n const next = this.nextNode;\n this.active = Object.assign(next, { column: this.getNextColumn(next.column) });\n this.scrollToCell(this.active);\n }\n\n public hostDisconnected() {\n this.active = SENTINEL_NODE as ActiveNode<T>;\n this._navigationState = NAVIGATION_STATE;\n }\n\n public navigate(event: KeyboardEvent) {\n if (this.handlers.has(event.key)) {\n event.preventDefault();\n this.handlers.get(event.key)!.call(this);\n }\n }\n\n public async navigateTo(row: number, column?: Keys<T>, activate = false) {\n if (activate) this.active = Object.assign(this.nextNode, { row, column });\n\n // attempt to resolve row in DOM first as a check if layout change will be needed\n let item: Pick<HTMLElement, 'scrollIntoView'> | undefined = this.queryRowByIndex(row);\n let completePromise: Promise<void> | undefined;\n\n if (!item) {\n item = this._virtualizer?.element(row);\n completePromise = item && this._virtualizer?.layoutComplete;\n }\n\n item?.scrollIntoView({ block: 'nearest' });\n await completePromise;\n if (column) this.scrollToCell({ row, column });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/controllers/navigation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { NO_SCROLL, SENTINEL_NODE } from '../internal/constants.js';\nimport type { ActiveNode, NavigateToOptions } from '../internal/types.js';\nimport { clamp, visibleColumns } from '../internal/utils.js';\nimport type { GridDOMController } from './dom.js';\nimport type { StateController } from './state.js';\n\n/** Minimal scroll that shows the target. */\nconst SCROLL_NEAREST: ScrollIntoViewOptions = { block: 'nearest' };\n\n/** The active node a row at `index` receives: only the active row sees it. */\nexport function activeNodeFor<T extends object>(active: ActiveNode<T>, index: number) {\n return active.row === index ? active : (SENTINEL_NODE as ActiveNode<T>);\n}\n\nexport class NavigationController<T extends object> implements ReactiveController {\n protected handlers = new Map<string, () => void>([\n ['ArrowDown', () => this.#moveToRow(this.nextNode.row + 1)],\n ['ArrowUp', () => this.#moveToRow(this.nextNode.row - 1)],\n ['ArrowLeft', () => this.#moveToColumn(-1)],\n ['ArrowRight', () => this.#moveToColumn(1)],\n ['Home', () => this.#moveToRow(0)],\n ['End', () => this.#moveToRow(this._state.host.totalItems - 1)],\n ]);\n\n protected get _virtualizer() {\n return this._dom.virtualizer;\n }\n\n protected _active = SENTINEL_NODE as ActiveNode<T>;\n\n protected get nextNode() {\n return this._active === SENTINEL_NODE\n ? ({ column: this._firstColumn, row: 0 } as ActiveNode<T>)\n : ({ ...this._active } as ActiveNode<T>);\n }\n\n protected get _columns() {\n return visibleColumns(this._state.columns);\n }\n\n protected get _firstColumn() {\n return this._columns.at(0)?.field ?? SENTINEL_NODE.column;\n }\n\n protected queryRowByIndex(index: number) {\n return this._dom.rows.find((row) => row.index === index);\n }\n\n /** The rendered cell at `node`, if its row and column are in the DOM. */\n #queryCell(node: ActiveNode<T>) {\n return this.queryRowByIndex(node.row)?.cells.find((cell) => cell.column.field === node.column);\n }\n\n protected scrollToCell(node: ActiveNode<T>) {\n this.#queryCell(node)?.scrollIntoView(SCROLL_NEAREST);\n }\n\n public get active(): ActiveNode<T> {\n return this._active;\n }\n\n public set active(node: ActiveNode<T>) {\n const previous = this._active;\n\n this._active = node ?? SENTINEL_NODE;\n this.#updateActiveRows(previous);\n this._state.host.requestUpdate();\n }\n\n /** Updates only the rows entering or leaving the active state. */\n #updateActiveRows(previous: ActiveNode<T>): void {\n for (const row of this._dom.rows) {\n if (row.index === previous.row || row.index === this._active.row) {\n row.activeNode = activeNodeFor(this._active, row.index);\n }\n }\n }\n\n /** Moves DOM focus onto the active cell when it is rendered (roving focus). */\n async #focusActiveCell(): Promise<void> {\n const node = this._active;\n let row = this.queryRowByIndex(node.row);\n\n // Row not rendered yet: wait for layout.\n if (!row) {\n await this._virtualizer?.layoutComplete;\n row = this.queryRowByIndex(node.row);\n }\n\n await row?.updateComplete;\n\n // A newer navigation replaced this one during the render wait.\n if (node !== this._active) {\n return;\n }\n\n this.#queryCell(node)?.focus(NO_SCROLL);\n }\n\n constructor(\n protected _state: StateController<T>,\n protected _dom: GridDOMController<T>\n ) {\n this._state.host.addController(this);\n }\n\n /** Activates `row` (clamped to the data range) and scrolls it into view. */\n #moveToRow(row: number) {\n const clamped = clamp(row, 0, this._state.host.totalItems - 1);\n\n this.active = Object.assign(this.nextNode, { row: clamped });\n this._virtualizer?.scrollToIndex(clamped, SCROLL_NEAREST);\n }\n\n /**\n * Steps the active column by `offset`, clamping at the visible ends. A hidden\n * or missing key (index -1) lands on the first visible column.\n */\n #moveToColumn(offset: -1 | 1) {\n const next = this.nextNode;\n const columns = this._columns;\n\n const index = columns.findIndex((column) => column.field === next.column);\n const target = clamp(index + offset, 0, columns.length - 1);\n\n this.active = Object.assign(next, { column: columns[target].field });\n this.scrollToCell(this.active);\n }\n\n public hostDisconnected() {\n this.active = SENTINEL_NODE as ActiveNode<T>;\n }\n\n public navigate(event: KeyboardEvent) {\n const handler = this.handlers.get(event.key);\n\n // Nothing to move to without a visible column or a data row.\n if (!handler || this._columns.length === 0 || this._state.host.totalItems === 0) {\n return;\n }\n\n event.preventDefault();\n handler();\n this.#focusActiveCell();\n }\n\n public async navigateTo(row: number, options?: NavigateToOptions<T>) {\n const { column, activate } = options ?? {};\n\n if (activate) {\n // Without an explicit column, activation keeps the one from `nextNode`.\n this.active = Object.assign(this.nextNode, column ? { row, column } : { row });\n }\n\n await this._virtualizer?.scrollToIndex(row, SCROLL_NEAREST);\n\n if (column) {\n this.scrollToCell({ row, column });\n }\n }\n}\n"]}
|
package/controllers/resize.d.ts
CHANGED
|
@@ -1,27 +1,21 @@
|
|
|
1
|
-
import { nothing
|
|
1
|
+
import { nothing } from 'lit';
|
|
2
2
|
import type IgcGridLiteHeader from '../components/header.js';
|
|
3
|
-
import type { ColumnConfiguration
|
|
4
|
-
|
|
3
|
+
import type { ColumnConfiguration } from '../internal/types.js';
|
|
4
|
+
import type { GridDOMController } from './dom.js';
|
|
5
|
+
import type { StateController } from './state.js';
|
|
6
|
+
export declare class ResizeController<T extends object> {
|
|
5
7
|
#private;
|
|
6
|
-
protected
|
|
7
|
-
|
|
8
|
+
protected _state: StateController<T>;
|
|
9
|
+
protected _dom: GridDOMController<T>;
|
|
10
|
+
constructor(_state: StateController<T>, _dom: GridDOMController<T>);
|
|
8
11
|
indicatorActive: boolean;
|
|
9
12
|
indicatorOffset: number;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
13
|
-
* @param header the
|
|
14
|
-
*/
|
|
13
|
+
protected get host(): import("../internal/types.js").GridHost<T>;
|
|
14
|
+
/** Starts a column resize: shows the indicator and aligns it with the header. */
|
|
15
15
|
start(header: IgcGridLiteHeader<T>): void;
|
|
16
|
-
/**
|
|
17
|
-
* Stops and resets the resizing state.
|
|
18
|
-
*/
|
|
16
|
+
/** Hides the indicator. */
|
|
19
17
|
stop(): void;
|
|
20
18
|
resize(column: ColumnConfiguration<T>, width: number, sizerOffset?: number): void;
|
|
21
19
|
autosize(column: ColumnConfiguration<T>, header: IgcGridLiteHeader<T>): Promise<void>;
|
|
22
|
-
hostConnected(): void;
|
|
23
|
-
/**
|
|
24
|
-
* Renders the resize indicator in the grid.
|
|
25
|
-
*/
|
|
26
20
|
renderIndicator(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
27
21
|
}
|
package/controllers/resize.js
CHANGED
|
@@ -2,42 +2,46 @@ import { html, nothing } from 'lit';
|
|
|
2
2
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
3
3
|
import { MIN_COL_RESIZE_WIDTH } from '../internal/constants.js';
|
|
4
4
|
export class ResizeController {
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
5
|
+
constructor(_state, _dom) {
|
|
6
|
+
this._state = _state;
|
|
7
|
+
this._dom = _dom;
|
|
7
8
|
this.indicatorActive = false;
|
|
8
9
|
this.indicatorOffset = 0;
|
|
9
|
-
|
|
10
|
+
}
|
|
11
|
+
get host() {
|
|
12
|
+
return this._state.host;
|
|
10
13
|
}
|
|
11
14
|
#maxSize(key, headerWidth) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
const widths = this._dom.rows.map((row) => row.cells.find((cell) => cell.column.field === key)?.offsetWidth ?? 0);
|
|
16
|
+
return Math.max(MIN_COL_RESIZE_WIDTH, headerWidth, ...widths);
|
|
17
|
+
}
|
|
18
|
+
#setWidth(column, width) {
|
|
19
|
+
this._state.setColumnWidth(column.field, width);
|
|
20
|
+
}
|
|
21
|
+
#indicatorChanged() {
|
|
22
|
+
this.host.requestUpdate();
|
|
23
|
+
this._state.updateObservers();
|
|
16
24
|
}
|
|
17
25
|
start(header) {
|
|
18
26
|
this.indicatorActive = true;
|
|
19
27
|
this.indicatorOffset = header.offsetLeft + header.offsetWidth;
|
|
20
|
-
this
|
|
28
|
+
this.#indicatorChanged();
|
|
21
29
|
}
|
|
22
30
|
stop() {
|
|
23
31
|
this.indicatorActive = false;
|
|
24
|
-
this
|
|
32
|
+
this.#indicatorChanged();
|
|
25
33
|
}
|
|
26
34
|
resize(column, width, sizerOffset) {
|
|
27
35
|
if (sizerOffset) {
|
|
28
36
|
this.indicatorOffset = sizerOffset;
|
|
29
37
|
}
|
|
30
|
-
column
|
|
31
|
-
this.host.requestUpdate();
|
|
38
|
+
this.#setWidth(column, `${width}px`);
|
|
32
39
|
}
|
|
33
40
|
async autosize(column, header) {
|
|
34
|
-
column
|
|
35
|
-
this.host.requestUpdate();
|
|
41
|
+
this.#setWidth(column, 'max-content');
|
|
36
42
|
await this.host.updateComplete;
|
|
37
|
-
column
|
|
38
|
-
this.host.requestUpdate();
|
|
43
|
+
this.#setWidth(column, `${this.#maxSize(column.field, header.offsetWidth)}px`);
|
|
39
44
|
}
|
|
40
|
-
hostConnected() { }
|
|
41
45
|
renderIndicator() {
|
|
42
46
|
return this.indicatorActive
|
|
43
47
|
? html `<div
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../src/controllers/resize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../src/controllers/resize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAKhE,MAAM,OAAO,gBAAgB;IAC3B,YACY,MAA0B,EAC1B,IAA0B;QAD1B,WAAM,GAAN,MAAM,CAAoB;QAC1B,SAAI,GAAJ,IAAI,CAAsB;QAG/B,oBAAe,GAAG,KAAK,CAAC;QACxB,oBAAe,GAAG,CAAC,CAAC;IAHxB,CAAC;IAKJ,IAAc,IAAI;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,QAAQ,CAAC,GAAY,EAAE,WAAmB;QAExC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC/B,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,GAAG,CAAC,EAAE,WAAW,IAAI,CAAC,CAC/E,CAAC;QAEF,OAAO,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,CAAC;IAChE,CAAC;IAED,SAAS,CAAC,MAA8B,EAAE,KAAa;QACrD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAGD,iBAAiB;QACf,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;IAChC,CAAC;IAGM,KAAK,CAAC,MAA4B;QACvC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;QAC9D,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAGM,IAAI;QACT,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAEM,MAAM,CAAC,MAA8B,EAAE,KAAa,EAAE,WAAoB;QAC/E,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC;QACrC,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC;IACvC,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,MAA8B,EAAE,MAA4B;QAEhF,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACtC,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;QAE/B,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACjF,CAAC;IAEM,eAAe;QACpB,OAAO,IAAI,CAAC,eAAe;YACzB,CAAC,CAAC,IAAI,CAAA;;kBAEM,QAAQ,CAAC;gBACf,SAAS,EAAE,cAAc,IAAI,CAAC,eAAe,KAAK;aACnD,CAAC;gBACI;YACV,CAAC,CAAC,OAAO,CAAC;IACd,CAAC;CACF","sourcesContent":["import { html, nothing } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport type IgcGridLiteHeader from '../components/header.js';\nimport { MIN_COL_RESIZE_WIDTH } from '../internal/constants.js';\nimport type { ColumnConfiguration, Keys } from '../internal/types.js';\nimport type { GridDOMController } from './dom.js';\nimport type { StateController } from './state.js';\n\nexport class ResizeController<T extends object> {\n constructor(\n protected _state: StateController<T>,\n protected _dom: GridDOMController<T>\n ) {}\n\n public indicatorActive = false;\n public indicatorOffset = 0;\n\n protected get host() {\n return this._state.host;\n }\n\n #maxSize(key: Keys<T>, headerWidth: number) {\n // A rendered row may lack the cell, e.g. for a just hidden column.\n const widths = this._dom.rows.map(\n (row) => row.cells.find((cell) => cell.column.field === key)?.offsetWidth ?? 0\n );\n\n return Math.max(MIN_COL_RESIZE_WIDTH, headerWidth, ...widths);\n }\n\n #setWidth(column: ColumnConfiguration<T>, width: string) {\n this._state.setColumnWidth(column.field, width);\n }\n\n /** The grid renders the indicator. Each header renders its `resizing` part. */\n #indicatorChanged() {\n this.host.requestUpdate();\n this._state.updateObservers();\n }\n\n /** Starts a column resize: shows the indicator and aligns it with the header. */\n public start(header: IgcGridLiteHeader<T>) {\n this.indicatorActive = true;\n this.indicatorOffset = header.offsetLeft + header.offsetWidth;\n this.#indicatorChanged();\n }\n\n /** Hides the indicator. */\n public stop() {\n this.indicatorActive = false;\n this.#indicatorChanged();\n }\n\n public resize(column: ColumnConfiguration<T>, width: number, sizerOffset?: number) {\n if (sizerOffset) {\n this.indicatorOffset = sizerOffset;\n }\n\n this.#setWidth(column, `${width}px`);\n }\n\n public async autosize(column: ColumnConfiguration<T>, header: IgcGridLiteHeader<T>) {\n // Measure the column at its natural size first, then pin the result in pixels.\n this.#setWidth(column, 'max-content');\n await this.host.updateComplete;\n\n this.#setWidth(column, `${this.#maxSize(column.field, header.offsetWidth)}px`);\n }\n\n public renderIndicator() {\n return this.indicatorActive\n ? html`<div\n part=\"resize-indicator\"\n style=${styleMap({\n transform: `translateX(${this.indicatorOffset}px)`,\n })}\n ></div>`\n : nothing;\n }\n}\n"]}
|
package/controllers/sort.d.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ColumnConfiguration, GridHost, Keys } from '../internal/types.js';
|
|
1
|
+
import type { ColumnConfiguration, Keys } from '../internal/types.js';
|
|
3
2
|
import type { SortingExpression, SortState } from '../operations/sort/types.js';
|
|
4
|
-
|
|
3
|
+
import type { StateController } from './state.js';
|
|
4
|
+
export declare class SortController<T extends object> {
|
|
5
5
|
#private;
|
|
6
|
-
protected
|
|
7
|
-
constructor(
|
|
6
|
+
protected _state: StateController<T>;
|
|
7
|
+
constructor(_state: StateController<T>);
|
|
8
8
|
state: SortState<T>;
|
|
9
|
+
protected get host(): import("../internal/types.js").GridHost<T>;
|
|
9
10
|
sortFromHeaderClick(column: ColumnConfiguration<T>): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Returns the expression the next sort operation would apply for `column`.
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* A candidate copy. The stored state changes only on commit through
|
|
16
|
+
* {@link SortController._sort}.
|
|
17
|
+
*/
|
|
10
18
|
prepareExpression(column: ColumnConfiguration<T>): SortingExpression<T>;
|
|
11
19
|
reset(key?: Keys<T>): void;
|
|
12
20
|
protected _sort(expressions: SortingExpression<T> | SortingExpression<T>[]): void;
|
|
13
21
|
sort(expressions: SortingExpression<T> | SortingExpression<T>[]): void;
|
|
14
|
-
hostConnected(): void;
|
|
15
22
|
}
|
package/controllers/sort.js
CHANGED
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
import { PIPELINE } from '../internal/constants.js';
|
|
2
2
|
import { asArray } from '../internal/utils.js';
|
|
3
|
+
const NEXT_DIRECTION = {
|
|
4
|
+
ascending: 'descending',
|
|
5
|
+
descending: 'none',
|
|
6
|
+
none: 'ascending',
|
|
7
|
+
};
|
|
3
8
|
export class SortController {
|
|
4
|
-
constructor(
|
|
5
|
-
this.
|
|
9
|
+
constructor(_state) {
|
|
10
|
+
this._state = _state;
|
|
6
11
|
this.state = new Map();
|
|
7
|
-
|
|
12
|
+
}
|
|
13
|
+
get host() {
|
|
14
|
+
return this._state.host;
|
|
8
15
|
}
|
|
9
16
|
get #isMultipleSort() {
|
|
10
17
|
return this.host.sortingOptions.mode === 'multiple';
|
|
11
18
|
}
|
|
12
|
-
get #isTriStateSort() {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
19
|
#resolveSortOptions(column) {
|
|
16
|
-
|
|
17
|
-
caseSensitive: false,
|
|
18
|
-
comparer:
|
|
20
|
+
return {
|
|
21
|
+
caseSensitive: column?.sortingCaseSensitive ?? false,
|
|
22
|
+
comparer: column?.sortConfiguration?.comparer,
|
|
19
23
|
};
|
|
20
|
-
if (!column) {
|
|
21
|
-
return expr;
|
|
22
|
-
}
|
|
23
|
-
return Object.assign(expr, {
|
|
24
|
-
caseSensitive: column.sortingCaseSensitive,
|
|
25
|
-
comparer: column.sortConfiguration?.comparer,
|
|
26
|
-
});
|
|
27
24
|
}
|
|
28
25
|
#createDefaultExpression(key) {
|
|
29
26
|
const column = this.host.getColumn(key);
|
|
@@ -33,17 +30,6 @@ export class SortController {
|
|
|
33
30
|
...this.#resolveSortOptions(column),
|
|
34
31
|
};
|
|
35
32
|
}
|
|
36
|
-
#orderBy(dir) {
|
|
37
|
-
return this.#isTriStateSort
|
|
38
|
-
? dir === 'ascending'
|
|
39
|
-
? 'descending'
|
|
40
|
-
: dir === 'descending'
|
|
41
|
-
? 'none'
|
|
42
|
-
: 'ascending'
|
|
43
|
-
: dir === 'ascending'
|
|
44
|
-
? 'descending'
|
|
45
|
-
: 'ascending';
|
|
46
|
-
}
|
|
47
33
|
#emitSortingEvent(detail) {
|
|
48
34
|
return this.host.emitEvent('sorting', { detail, cancelable: true });
|
|
49
35
|
}
|
|
@@ -51,9 +37,11 @@ export class SortController {
|
|
|
51
37
|
return this.host.emitEvent('sorted', { detail });
|
|
52
38
|
}
|
|
53
39
|
#setExpression(expression) {
|
|
54
|
-
expression.direction === 'none'
|
|
55
|
-
|
|
56
|
-
|
|
40
|
+
if (expression.direction === 'none') {
|
|
41
|
+
this.reset(expression.key);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.state.set(expression.key, { ...expression });
|
|
57
45
|
}
|
|
58
46
|
async sortFromHeaderClick(column) {
|
|
59
47
|
const expression = this.prepareExpression(column);
|
|
@@ -64,31 +52,41 @@ export class SortController {
|
|
|
64
52
|
this.reset();
|
|
65
53
|
}
|
|
66
54
|
this._sort(expression);
|
|
67
|
-
await this.host.
|
|
55
|
+
await this.host._pipelineComplete;
|
|
68
56
|
this.#emitSortedEvent(expression);
|
|
69
57
|
}
|
|
70
58
|
prepareExpression(column) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return
|
|
74
|
-
direction: this.#orderBy(expr.direction),
|
|
75
|
-
...this.#resolveSortOptions(column),
|
|
76
|
-
});
|
|
59
|
+
const expr = this.state.get(column.field);
|
|
60
|
+
if (!expr) {
|
|
61
|
+
return this.#createDefaultExpression(column.field);
|
|
77
62
|
}
|
|
78
|
-
return
|
|
63
|
+
return {
|
|
64
|
+
...expr,
|
|
65
|
+
direction: NEXT_DIRECTION[expr.direction],
|
|
66
|
+
...this.#resolveSortOptions(column),
|
|
67
|
+
};
|
|
79
68
|
}
|
|
80
69
|
reset(key) {
|
|
81
|
-
|
|
70
|
+
if (key === undefined) {
|
|
71
|
+
this.state.clear();
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.state.delete(key);
|
|
75
|
+
}
|
|
76
|
+
this._state.updateObservers();
|
|
82
77
|
}
|
|
83
78
|
_sort(expressions) {
|
|
84
79
|
for (const expr of asArray(expressions)) {
|
|
85
80
|
this.#setExpression(expr);
|
|
86
81
|
}
|
|
82
|
+
this._state.updateObservers();
|
|
87
83
|
this.host.requestUpdate(PIPELINE);
|
|
88
84
|
}
|
|
89
85
|
sort(expressions) {
|
|
90
|
-
this._sort(asArray(expressions).map((expr) =>
|
|
86
|
+
this._sort(asArray(expressions).map((expr) => ({
|
|
87
|
+
...(this.state.get(expr.key) ?? this.#createDefaultExpression(expr.key)),
|
|
88
|
+
...expr,
|
|
89
|
+
})));
|
|
91
90
|
}
|
|
92
|
-
hostConnected() { }
|
|
93
91
|
}
|
|
94
92
|
//# sourceMappingURL=sort.js.map
|
package/controllers/sort.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/controllers/sort.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/controllers/sort.ts"],"names":[],"mappings":"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","sourcesContent":["import { PIPELINE } from '../internal/constants.js';\nimport type { ColumnConfiguration, Keys } from '../internal/types.js';\nimport { asArray } from '../internal/utils.js';\nimport type { SortingDirection, SortingExpression, SortState } from '../operations/sort/types.js';\nimport type { StateController } from './state.js';\n\n/** Tri-state cycle: ascending -> descending -> none -> ascending. */\nconst NEXT_DIRECTION: Record<SortingDirection, SortingDirection> = {\n ascending: 'descending',\n descending: 'none',\n none: 'ascending',\n};\n\nexport class SortController<T extends object> {\n constructor(protected _state: StateController<T>) {}\n\n public state: SortState<T> = new Map();\n\n protected get host() {\n return this._state.host;\n }\n\n get #isMultipleSort() {\n return this.host.sortingOptions.mode === 'multiple';\n }\n\n #resolveSortOptions(column?: ColumnConfiguration<T>): Partial<SortingExpression<T>> {\n return {\n caseSensitive: column?.sortingCaseSensitive ?? false,\n comparer: column?.sortConfiguration?.comparer,\n } as Partial<SortingExpression<T>>;\n }\n\n #createDefaultExpression(key: Keys<T>) {\n const column = this.host.getColumn(key);\n\n return {\n key,\n direction: 'ascending',\n ...this.#resolveSortOptions(column),\n } as SortingExpression<T>;\n }\n\n #emitSortingEvent(detail: SortingExpression<T>) {\n return this.host.emitEvent('sorting', { detail, cancelable: true });\n }\n\n #emitSortedEvent(detail: SortingExpression<T>) {\n return this.host.emitEvent('sorted', { detail });\n }\n\n #setExpression(expression: SortingExpression<T>) {\n if (expression.direction === 'none') {\n this.reset(expression.key);\n return;\n }\n\n this.state.set(expression.key, { ...expression });\n }\n\n public async sortFromHeaderClick(column: ColumnConfiguration<T>) {\n const expression = this.prepareExpression(column);\n\n if (!this.#emitSortingEvent(expression)) {\n return;\n }\n\n if (!this.#isMultipleSort) {\n this.reset();\n }\n\n this._sort(expression);\n\n await this.host._pipelineComplete;\n this.#emitSortedEvent(expression);\n }\n\n /**\n * Returns the expression the next sort operation would apply for `column`.\n *\n * @remarks\n * A candidate copy. The stored state changes only on commit through\n * {@link SortController._sort}.\n */\n public prepareExpression(column: ColumnConfiguration<T>): SortingExpression<T> {\n const expr = this.state.get(column.field);\n\n if (!expr) {\n return this.#createDefaultExpression(column.field);\n }\n\n return {\n ...expr,\n direction: NEXT_DIRECTION[expr.direction],\n ...this.#resolveSortOptions(column),\n };\n }\n\n public reset(key?: Keys<T>) {\n if (key === undefined) {\n this.state.clear();\n } else {\n this.state.delete(key);\n }\n\n // Headers render the sort indicator from this state.\n this._state.updateObservers();\n }\n\n protected _sort(expressions: SortingExpression<T> | SortingExpression<T>[]) {\n for (const expr of asArray(expressions)) {\n this.#setExpression(expr);\n }\n\n this._state.updateObservers();\n this.host.requestUpdate(PIPELINE);\n }\n\n public sort(expressions: SortingExpression<T> | SortingExpression<T>[]) {\n // Merge into copies. Only `#setExpression` replaces the stored expression.\n this._sort(\n asArray(expressions).map((expr) => ({\n ...(this.state.get(expr.key) ?? this.#createDefaultExpression(expr.key)),\n ...expr,\n }))\n );\n }\n}\n"]}
|
package/controllers/state.d.ts
CHANGED
|
@@ -1,41 +1,40 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type
|
|
3
|
-
import type IgcGridLiteHeaderRow from '../components/header-row.js';
|
|
4
|
-
import type IgcGridLiteRow from '../components/row.js';
|
|
5
|
-
import type IgcVirtualizer from '../components/virtualizer.js';
|
|
6
|
-
import type { ActiveNode, ColumnConfiguration, GridHost } from '../internal/types.js';
|
|
1
|
+
import type { ActiveNode, ColumnConfiguration, GridHost, Keys } from '../internal/types.js';
|
|
2
|
+
import type { GridDOMController } from './dom.js';
|
|
7
3
|
import { FilterController } from './filter.js';
|
|
8
4
|
import { NavigationController } from './navigation.js';
|
|
9
5
|
import { ResizeController } from './resize.js';
|
|
10
6
|
import { SortController } from './sort.js';
|
|
11
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Holds the column configuration of the grid and owns the controllers for its
|
|
9
|
+
* data operations. Column objects are immutable: each change produces new objects
|
|
10
|
+
* and a new array, so consumers can dirty-check by identity.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Not a reactive controller: it has no host lifecycle. All DOM concerns live in
|
|
14
|
+
* {@link GridDOMController}.
|
|
15
|
+
*/
|
|
16
|
+
declare class StateController<T extends object> {
|
|
12
17
|
private _columns;
|
|
13
18
|
private readonly _observersCallback;
|
|
14
|
-
/** The grid host element. */
|
|
15
19
|
readonly host: GridHost<T>;
|
|
16
20
|
readonly sorting: SortController<T>;
|
|
17
21
|
readonly filtering: FilterController<T>;
|
|
18
22
|
readonly navigation: NavigationController<T>;
|
|
19
23
|
readonly resizing: ResizeController<T>;
|
|
20
24
|
get columns(): ColumnConfiguration<T>[];
|
|
21
|
-
/** Returns the header row element of the grid. */
|
|
22
|
-
get headerRow(): IgcGridLiteHeaderRow<T> | null;
|
|
23
|
-
/** Returns the filter row element of the grid. */
|
|
24
|
-
get filterRow(): IgcFilterRow<T> | null;
|
|
25
|
-
/** Returns the data row elements of the grid. */
|
|
26
|
-
get rows(): IgcGridLiteRow<T>[];
|
|
27
|
-
/** Returns the virtualizer element of the grid. */
|
|
28
|
-
get virtualizer(): IgcVirtualizer | null;
|
|
29
25
|
/** The currently active node in the grid. */
|
|
30
26
|
get active(): ActiveNode<T>;
|
|
31
27
|
/** Sets the currently active node in the grid. */
|
|
32
28
|
set active(node: ActiveNode<T>);
|
|
33
|
-
constructor(host: GridHost<T>, observersCallback: () => void);
|
|
34
|
-
|
|
29
|
+
constructor(host: GridHost<T>, dom: GridDOMController<T>, observersCallback: () => void);
|
|
30
|
+
/** Pings the state consumers (headers, header row, filter row). Call at mutation points only. */
|
|
31
|
+
updateObservers(): void;
|
|
35
32
|
setColumnConfiguration(columns: ColumnConfiguration<T>[]): void;
|
|
36
33
|
setAutoColumnConfiguration(): void;
|
|
37
34
|
updateColumnsConfiguration(config: ColumnConfiguration<T>[]): void;
|
|
35
|
+
/** Replaces one column's width. Skips the pipeline: resize drags call this per pointer move. */
|
|
36
|
+
setColumnWidth(field: Keys<T>, width: string): void;
|
|
38
37
|
}
|
|
39
|
-
declare function createStateController<T extends object>(host: GridHost<T>, observersCallback: () => void): StateController<T>;
|
|
38
|
+
declare function createStateController<T extends object>(host: GridHost<T>, dom: GridDOMController<T>, observersCallback: () => void): StateController<T>;
|
|
40
39
|
export type { StateController };
|
|
41
40
|
export { createStateController };
|