igniteui-grid-lite 0.9.0 → 0.10.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 +8 -0
- package/components/cell.js +12 -1
- 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 +7 -2
- package/components/filter-row.js +87 -52
- package/components/filter-row.js.map +1 -1
- package/components/grid.d.ts +49 -3
- package/components/grid.js +102 -62
- package/components/grid.js.map +1 -1
- package/components/header-row.d.ts +1 -2
- package/components/header-row.js +4 -7
- package/components/header-row.js.map +1 -1
- package/components/header.d.ts +9 -0
- package/components/header.js +36 -23
- package/components/header.js.map +1 -1
- package/components/row.d.ts +4 -1
- package/components/row.js +12 -1
- package/components/row.js.map +1 -1
- package/components/virtualizer.d.ts +3 -1
- package/components/virtualizer.js +36 -7
- package/components/virtualizer.js.map +1 -1
- package/controllers/data-operation.d.ts +0 -4
- package/controllers/data-operation.js +7 -22
- package/controllers/data-operation.js.map +1 -1
- package/controllers/dom.d.ts +28 -9
- package/controllers/dom.js +70 -20
- package/controllers/dom.js.map +1 -1
- package/controllers/filter.d.ts +20 -4
- package/controllers/filter.js +39 -55
- package/controllers/filter.js.map +1 -1
- package/controllers/navigation.d.ts +10 -10
- package/controllers/navigation.js +68 -53
- package/controllers/navigation.js.map +1 -1
- package/controllers/resize.d.ts +8 -8
- package/controllers/resize.js +23 -14
- package/controllers/resize.js.map +1 -1
- package/controllers/sort.d.ts +12 -3
- package/controllers/sort.js +25 -32
- package/controllers/sort.js.map +1 -1
- package/controllers/state.d.ts +28 -18
- package/controllers/state.js +20 -26
- package/controllers/state.js.map +1 -1
- package/custom-elements.json +874 -243
- package/docs/igniteui-grid-lite.json +1339 -818
- package/index.d.ts +1 -1
- package/index.js.map +1 -1
- package/internal/a11y.d.ts +29 -0
- package/internal/a11y.js +24 -0
- package/internal/a11y.js.map +1 -0
- package/internal/constants.d.ts +3 -2
- package/internal/constants.js +1 -4
- package/internal/constants.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 +2 -2
- package/internal/tags.js +2 -2
- package/internal/tags.js.map +1 -1
- package/internal/types.d.ts +13 -1
- package/internal/types.js.map +1 -1
- package/internal/utils.d.ts +3 -0
- package/internal/utils.js +17 -4
- package/internal/utils.js.map +1 -1
- package/internal/watch.js +8 -9
- package/internal/watch.js.map +1 -1
- package/operations/base.js +2 -1
- package/operations/base.js.map +1 -1
- package/operations/filter/state.js +2 -5
- 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.js +13 -1
- package/operations/filter.js.map +1 -1
- package/operations/sort.d.ts +0 -1
- package/operations/sort.js +7 -9
- package/operations/sort.js.map +1 -1
- package/package.json +2 -2
- 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/controllers/resize.js
CHANGED
|
@@ -2,40 +2,49 @@ 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
|
this.host.addController(this);
|
|
10
11
|
}
|
|
12
|
+
get host() {
|
|
13
|
+
return this._state.host;
|
|
14
|
+
}
|
|
11
15
|
#maxSize(key, headerWidth) {
|
|
12
|
-
const max = this.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
const max = this._dom.rows.reduce((prev, row) => {
|
|
17
|
+
const cell = row.cells.find((cell) => cell.column.field === key);
|
|
18
|
+
return cell && cell.offsetWidth > prev ? cell.offsetWidth : prev;
|
|
19
|
+
}, 0);
|
|
20
|
+
return Math.max(MIN_COL_RESIZE_WIDTH, max, headerWidth);
|
|
21
|
+
}
|
|
22
|
+
#setWidth(column, width) {
|
|
23
|
+
this._state.setColumnWidth(column.field, width);
|
|
24
|
+
}
|
|
25
|
+
#indicatorChanged() {
|
|
26
|
+
this.host.requestUpdate();
|
|
27
|
+
this._state.updateObservers();
|
|
16
28
|
}
|
|
17
29
|
start(header) {
|
|
18
30
|
this.indicatorActive = true;
|
|
19
31
|
this.indicatorOffset = header.offsetLeft + header.offsetWidth;
|
|
20
|
-
this
|
|
32
|
+
this.#indicatorChanged();
|
|
21
33
|
}
|
|
22
34
|
stop() {
|
|
23
35
|
this.indicatorActive = false;
|
|
24
|
-
this
|
|
36
|
+
this.#indicatorChanged();
|
|
25
37
|
}
|
|
26
38
|
resize(column, width, sizerOffset) {
|
|
27
39
|
if (sizerOffset) {
|
|
28
40
|
this.indicatorOffset = sizerOffset;
|
|
29
41
|
}
|
|
30
|
-
column
|
|
31
|
-
this.host.requestUpdate();
|
|
42
|
+
this.#setWidth(column, `${width}px`);
|
|
32
43
|
}
|
|
33
44
|
async autosize(column, header) {
|
|
34
|
-
column
|
|
35
|
-
this.host.requestUpdate();
|
|
45
|
+
this.#setWidth(column, 'max-content');
|
|
36
46
|
await this.host.updateComplete;
|
|
37
|
-
column
|
|
38
|
-
this.host.requestUpdate();
|
|
47
|
+
this.#setWidth(column, `${this.#maxSize(column.field, header.offsetWidth)}px`);
|
|
39
48
|
}
|
|
40
49
|
hostConnected() { }
|
|
41
50
|
renderIndicator() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../src/controllers/resize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAA2B,MAAM,KAAK,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../src/controllers/resize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAA2B,MAAM,KAAK,CAAC;AAC7D,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;QAK/B,oBAAe,GAAG,KAAK,CAAC;QACxB,oBAAe,GAAG,CAAC,CAAC;QAJzB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAKD,IAAc,IAAI;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,QAAQ,CAAC,GAAY,EAAE,WAAmB;QAExC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC9C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC;YACjE,OAAO,IAAI,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;QACnE,CAAC,EAAE,CAAC,CAAC,CAAC;QAEN,OAAO,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;IAC1D,CAAC;IAGD,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;IAKM,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,aAAa,KAAI,CAAC;IAKlB,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, type ReactiveController } 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> implements ReactiveController {\n constructor(\n protected _state: StateController<T>,\n protected _dom: GridDOMController<T>\n ) {\n this.host.addController(this);\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 not carry a cell for the column (e.g. it was just hidden).\n const max = this._dom.rows.reduce((prev, row) => {\n const cell = row.cells.find((cell) => cell.column.field === key);\n return cell && cell.offsetWidth > prev ? cell.offsetWidth : prev;\n }, 0);\n\n return Math.max(MIN_COL_RESIZE_WIDTH, max, headerWidth);\n }\n\n /** Column objects are immutable. Widths are set through the state. */\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 /**\n * Stops and resets the resizing state.\n */\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 hostConnected() {}\n\n /**\n * Renders the resize indicator in the grid.\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,12 +1,21 @@
|
|
|
1
1
|
import type { ReactiveController } from 'lit';
|
|
2
|
-
import type { ColumnConfiguration,
|
|
2
|
+
import type { ColumnConfiguration, Keys } from '../internal/types.js';
|
|
3
3
|
import type { SortingExpression, SortState } from '../operations/sort/types.js';
|
|
4
|
+
import type { StateController } from './state.js';
|
|
4
5
|
export declare class SortController<T extends object> implements ReactiveController {
|
|
5
6
|
#private;
|
|
6
|
-
protected
|
|
7
|
-
constructor(
|
|
7
|
+
protected _state: StateController<T>;
|
|
8
|
+
constructor(_state: StateController<T>);
|
|
8
9
|
state: SortState<T>;
|
|
10
|
+
protected get host(): import("../internal/types.js").GridHost<T>;
|
|
9
11
|
sortFromHeaderClick(column: ColumnConfiguration<T>): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the expression the next sort operation would apply for `column`.
|
|
14
|
+
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* The result is a candidate copy - the stored state is only updated once the
|
|
17
|
+
* operation is committed through {@link SortController._sort}.
|
|
18
|
+
*/
|
|
10
19
|
prepareExpression(column: ColumnConfiguration<T>): SortingExpression<T>;
|
|
11
20
|
reset(key?: Keys<T>): void;
|
|
12
21
|
protected _sort(expressions: SortingExpression<T> | SortingExpression<T>[]): void;
|
package/controllers/sort.js
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
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
|
this.host.addController(this);
|
|
8
13
|
}
|
|
14
|
+
get host() {
|
|
15
|
+
return this._state.host;
|
|
16
|
+
}
|
|
9
17
|
get #isMultipleSort() {
|
|
10
18
|
return this.host.sortingOptions.mode === 'multiple';
|
|
11
19
|
}
|
|
12
|
-
get #isTriStateSort() {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
20
|
#resolveSortOptions(column) {
|
|
16
|
-
|
|
17
|
-
caseSensitive: false,
|
|
18
|
-
comparer:
|
|
21
|
+
return {
|
|
22
|
+
caseSensitive: column?.sortingCaseSensitive ?? false,
|
|
23
|
+
comparer: column?.sortConfiguration?.comparer,
|
|
19
24
|
};
|
|
20
|
-
if (!column) {
|
|
21
|
-
return expr;
|
|
22
|
-
}
|
|
23
|
-
return Object.assign(expr, {
|
|
24
|
-
caseSensitive: column.sortingCaseSensitive,
|
|
25
|
-
comparer: column.sortConfiguration?.comparer,
|
|
26
|
-
});
|
|
27
25
|
}
|
|
28
26
|
#createDefaultExpression(key) {
|
|
29
27
|
const column = this.host.getColumn(key);
|
|
@@ -33,17 +31,6 @@ export class SortController {
|
|
|
33
31
|
...this.#resolveSortOptions(column),
|
|
34
32
|
};
|
|
35
33
|
}
|
|
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
34
|
#emitSortingEvent(detail) {
|
|
48
35
|
return this.host.emitEvent('sorting', { detail, cancelable: true });
|
|
49
36
|
}
|
|
@@ -64,30 +51,36 @@ export class SortController {
|
|
|
64
51
|
this.reset();
|
|
65
52
|
}
|
|
66
53
|
this._sort(expression);
|
|
67
|
-
await this.host.
|
|
54
|
+
await this.host._pipelineComplete;
|
|
68
55
|
this.#emitSortedEvent(expression);
|
|
69
56
|
}
|
|
70
57
|
prepareExpression(column) {
|
|
71
58
|
if (this.state.has(column.field)) {
|
|
72
59
|
const expr = this.state.get(column.field);
|
|
73
|
-
return
|
|
74
|
-
|
|
60
|
+
return {
|
|
61
|
+
...expr,
|
|
62
|
+
direction: NEXT_DIRECTION[expr.direction],
|
|
75
63
|
...this.#resolveSortOptions(column),
|
|
76
|
-
}
|
|
64
|
+
};
|
|
77
65
|
}
|
|
78
66
|
return this.#createDefaultExpression(column.field);
|
|
79
67
|
}
|
|
80
68
|
reset(key) {
|
|
81
|
-
key ? this.state.delete(key) : this.state.clear();
|
|
69
|
+
key !== undefined ? this.state.delete(key) : this.state.clear();
|
|
70
|
+
this._state.updateObservers();
|
|
82
71
|
}
|
|
83
72
|
_sort(expressions) {
|
|
84
73
|
for (const expr of asArray(expressions)) {
|
|
85
74
|
this.#setExpression(expr);
|
|
86
75
|
}
|
|
76
|
+
this._state.updateObservers();
|
|
87
77
|
this.host.requestUpdate(PIPELINE);
|
|
88
78
|
}
|
|
89
79
|
sort(expressions) {
|
|
90
|
-
this._sort(asArray(expressions).map((expr) =>
|
|
80
|
+
this._sort(asArray(expressions).map((expr) => ({
|
|
81
|
+
...(this.state.get(expr.key) ?? this.#createDefaultExpression(expr.key)),
|
|
82
|
+
...expr,
|
|
83
|
+
})));
|
|
91
84
|
}
|
|
92
85
|
hostConnected() { }
|
|
93
86
|
}
|
package/controllers/sort.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/controllers/sort.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/controllers/sort.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport { 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> implements ReactiveController {\n constructor(protected _state: StateController<T>) {\n this.host.addController(this);\n }\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 expression.direction === 'none'\n ? this.reset(expression.key)\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 * The result is a candidate copy - the stored state is only updated once the\n * operation is committed through {@link SortController._sort}.\n */\n public prepareExpression(column: ColumnConfiguration<T>): SortingExpression<T> {\n if (this.state.has(column.field)) {\n const expr = this.state.get(column.field)!;\n\n return {\n ...expr,\n direction: NEXT_DIRECTION[expr.direction],\n ...this.#resolveSortOptions(column),\n };\n }\n\n // Initial state\n return this.#createDefaultExpression(column.field);\n }\n\n public reset(key?: Keys<T>) {\n key !== undefined ? this.state.delete(key) : this.state.clear();\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 public hostConnected() {}\n}\n"]}
|
package/controllers/state.d.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
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
19
|
/** The grid host element. */
|
|
@@ -18,24 +23,29 @@ declare class StateController<T extends object> implements ReactiveController {
|
|
|
18
23
|
readonly navigation: NavigationController<T>;
|
|
19
24
|
readonly resizing: ResizeController<T>;
|
|
20
25
|
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
26
|
/** The currently active node in the grid. */
|
|
30
27
|
get active(): ActiveNode<T>;
|
|
31
28
|
/** Sets the currently active node in the grid. */
|
|
32
29
|
set active(node: ActiveNode<T>);
|
|
33
|
-
constructor(host: GridHost<T>, observersCallback: () => void);
|
|
34
|
-
|
|
30
|
+
constructor(host: GridHost<T>, dom: GridDOMController<T>, observersCallback: () => void);
|
|
31
|
+
/**
|
|
32
|
+
* Notifies the state context consumers (headers, header row, filter row) that
|
|
33
|
+
* their render inputs changed. Called at the mutation points only, never on
|
|
34
|
+
* each host update.
|
|
35
|
+
*/
|
|
36
|
+
updateObservers(): void;
|
|
35
37
|
setColumnConfiguration(columns: ColumnConfiguration<T>[]): void;
|
|
36
38
|
setAutoColumnConfiguration(): void;
|
|
37
39
|
updateColumnsConfiguration(config: ColumnConfiguration<T>[]): void;
|
|
40
|
+
/**
|
|
41
|
+
* Replaces the width of a single column with a new configuration object.
|
|
42
|
+
*
|
|
43
|
+
* @remarks
|
|
44
|
+
* Width has no effect on the data pipeline, so no pipeline run is scheduled.
|
|
45
|
+
* Resize drags call this on each pointer move.
|
|
46
|
+
*/
|
|
47
|
+
setColumnWidth(field: Keys<T>, width: string): void;
|
|
38
48
|
}
|
|
39
|
-
declare function createStateController<T extends object>(host: GridHost<T>, observersCallback: () => void): StateController<T>;
|
|
49
|
+
declare function createStateController<T extends object>(host: GridHost<T>, dom: GridDOMController<T>, observersCallback: () => void): StateController<T>;
|
|
40
50
|
export type { StateController };
|
|
41
51
|
export { createStateController };
|
package/controllers/state.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PIPELINE } from '../internal/constants.js';
|
|
2
|
-
import { GRID_BODY, GRID_FILTER_ROW_TAG, GRID_HEADER_ROW_TAG, GRID_ROW_TAG, } from '../internal/tags.js';
|
|
3
2
|
import { createColumnConfiguration, setColumnsFromData } from '../internal/utils.js';
|
|
4
3
|
import { FilterController } from './filter.js';
|
|
5
4
|
import { NavigationController } from './navigation.js';
|
|
@@ -9,42 +8,28 @@ class StateController {
|
|
|
9
8
|
get columns() {
|
|
10
9
|
return this._columns;
|
|
11
10
|
}
|
|
12
|
-
get headerRow() {
|
|
13
|
-
return this.host.renderRoot.querySelector(GRID_HEADER_ROW_TAG);
|
|
14
|
-
}
|
|
15
|
-
get filterRow() {
|
|
16
|
-
return this.host.renderRoot.querySelector(GRID_FILTER_ROW_TAG);
|
|
17
|
-
}
|
|
18
|
-
get rows() {
|
|
19
|
-
return Array.from(this.host.renderRoot.querySelectorAll(GRID_ROW_TAG));
|
|
20
|
-
}
|
|
21
|
-
get virtualizer() {
|
|
22
|
-
return this.host.renderRoot.querySelector(GRID_BODY);
|
|
23
|
-
}
|
|
24
11
|
get active() {
|
|
25
12
|
return this.navigation.active;
|
|
26
13
|
}
|
|
27
14
|
set active(node) {
|
|
28
15
|
this.navigation.active = node;
|
|
29
16
|
}
|
|
30
|
-
constructor(host, observersCallback) {
|
|
17
|
+
constructor(host, dom, observersCallback) {
|
|
31
18
|
this._columns = [];
|
|
32
19
|
this._observersCallback = observersCallback;
|
|
33
20
|
this.host = host;
|
|
34
|
-
this.
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
38
|
-
this.resizing = new ResizeController(this.host);
|
|
21
|
+
this.sorting = new SortController(this);
|
|
22
|
+
this.filtering = new FilterController(this, dom);
|
|
23
|
+
this.navigation = new NavigationController(this, dom);
|
|
24
|
+
this.resizing = new ResizeController(this, dom);
|
|
39
25
|
}
|
|
40
|
-
|
|
41
|
-
this.
|
|
42
|
-
this.virtualizer?.requestUpdate();
|
|
26
|
+
updateObservers() {
|
|
27
|
+
this._observersCallback.call(this.host);
|
|
43
28
|
}
|
|
44
29
|
setColumnConfiguration(columns) {
|
|
45
30
|
this._columns = columns.map((column) => createColumnConfiguration(column));
|
|
46
31
|
this.filtering.resolveConditions();
|
|
47
|
-
this.
|
|
32
|
+
this.updateObservers();
|
|
48
33
|
this.host.requestUpdate(PIPELINE);
|
|
49
34
|
}
|
|
50
35
|
setAutoColumnConfiguration() {
|
|
@@ -65,12 +50,21 @@ class StateController {
|
|
|
65
50
|
}
|
|
66
51
|
}
|
|
67
52
|
this._columns = [...this._columns];
|
|
68
|
-
this.
|
|
53
|
+
this.updateObservers();
|
|
69
54
|
this.host.requestUpdate(PIPELINE);
|
|
70
55
|
}
|
|
56
|
+
setColumnWidth(field, width) {
|
|
57
|
+
const index = this._columns.findIndex((column) => column.field === field);
|
|
58
|
+
if (index === -1) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this._columns = this._columns.with(index, { ...this._columns[index], width });
|
|
62
|
+
this.updateObservers();
|
|
63
|
+
this.host.requestUpdate();
|
|
64
|
+
}
|
|
71
65
|
}
|
|
72
|
-
function createStateController(host, observersCallback) {
|
|
73
|
-
return new StateController(host, observersCallback);
|
|
66
|
+
function createStateController(host, dom, observersCallback) {
|
|
67
|
+
return new StateController(host, dom, observersCallback);
|
|
74
68
|
}
|
|
75
69
|
export { createStateController };
|
|
76
70
|
//# sourceMappingURL=state.js.map
|
package/controllers/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/controllers/state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/controllers/state.ts"],"names":[],"mappings":"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","sourcesContent":["import { PIPELINE } from '../internal/constants.js';\nimport type { ActiveNode, ColumnConfiguration, GridHost, Keys } from '../internal/types.js';\nimport { createColumnConfiguration, setColumnsFromData } from '../internal/utils.js';\nimport type { GridDOMController } from './dom.js';\nimport { FilterController } from './filter.js';\nimport { NavigationController } from './navigation.js';\nimport { ResizeController } from './resize.js';\nimport { SortController } from './sort.js';\n\n/**\n * Holds the column configuration of the grid and owns the controllers for its\n * data operations. Column objects are immutable: each change produces new objects\n * and a new array, so consumers can dirty-check by identity.\n *\n * @remarks\n * Not a reactive controller: it has no host lifecycle. All DOM concerns live in\n * {@link GridDOMController}.\n */\nclass StateController<T extends object> {\n private _columns: ColumnConfiguration<T>[] = [];\n private readonly _observersCallback: () => void;\n\n /** The grid host element. */\n public readonly host: GridHost<T>;\n\n public readonly sorting: SortController<T>;\n public readonly filtering: FilterController<T>;\n public readonly navigation: NavigationController<T>;\n public readonly resizing: ResizeController<T>;\n\n public get columns(): ColumnConfiguration<T>[] {\n return this._columns;\n }\n\n /** The currently active node in the grid. */\n public get active(): ActiveNode<T> {\n return this.navigation.active;\n }\n\n /** Sets the currently active node in the grid. */\n public set active(node: ActiveNode<T>) {\n this.navigation.active = node;\n }\n\n constructor(host: GridHost<T>, dom: GridDOMController<T>, observersCallback: () => void) {\n this._observersCallback = observersCallback;\n this.host = host;\n\n this.sorting = new SortController(this);\n this.filtering = new FilterController(this, dom);\n this.navigation = new NavigationController(this, dom);\n this.resizing = new ResizeController(this, dom);\n }\n\n /**\n * Notifies the state context consumers (headers, header row, filter row) that\n * their render inputs changed. Called at the mutation points only, never on\n * each host update.\n */\n public updateObservers(): void {\n this._observersCallback.call(this.host);\n }\n\n public setColumnConfiguration(columns: ColumnConfiguration<T>[]): void {\n this._columns = columns.map((column) => createColumnConfiguration(column));\n this.filtering.resolveConditions();\n this.updateObservers();\n this.host.requestUpdate(PIPELINE);\n }\n\n public setAutoColumnConfiguration(): void {\n if (this.host.autoGenerate && this.host.data.length > 0) {\n this._columns = setColumnsFromData(this.host.data[0]);\n this.filtering.resolveConditions();\n this.host.requestUpdate(PIPELINE);\n }\n }\n\n public updateColumnsConfiguration(config: ColumnConfiguration<T>[]): void {\n // NOTE: The in-place writes are load-bearing. Consumers holding the current\n // array (header row, DOM controller) must see the new column objects in this\n // update cycle; rebuilding the array delivers them one cycle late.\n for (const columnConfig of config) {\n const existing = this._columns.findIndex((column) => column.field === columnConfig.field);\n if (existing !== -1) {\n this._columns[existing] = {\n ...this._columns[existing],\n ...createColumnConfiguration(columnConfig),\n };\n }\n }\n\n this._columns = [...this._columns];\n this.updateObservers();\n this.host.requestUpdate(PIPELINE);\n }\n\n /**\n * Replaces the width of a single column with a new configuration object.\n *\n * @remarks\n * Width has no effect on the data pipeline, so no pipeline run is scheduled.\n * Resize drags call this on each pointer move.\n */\n public setColumnWidth(field: Keys<T>, width: string): void {\n const index = this._columns.findIndex((column) => column.field === field);\n\n if (index === -1) {\n return;\n }\n\n this._columns = this._columns.with(index, { ...this._columns[index], width });\n this.updateObservers();\n this.host.requestUpdate();\n }\n}\n\nfunction createStateController<T extends object>(\n host: GridHost<T>,\n dom: GridDOMController<T>,\n observersCallback: () => void\n): StateController<T> {\n return new StateController<T>(host, dom, observersCallback);\n}\n\nexport type { StateController };\nexport { createStateController };\n"]}
|