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.
Files changed (86) hide show
  1. package/components/cell.d.ts +8 -0
  2. package/components/cell.js +12 -1
  3. package/components/cell.js.map +1 -1
  4. package/components/column.d.ts +2 -2
  5. package/components/column.js.map +1 -1
  6. package/components/filter-row.d.ts +7 -2
  7. package/components/filter-row.js +87 -52
  8. package/components/filter-row.js.map +1 -1
  9. package/components/grid.d.ts +49 -3
  10. package/components/grid.js +102 -62
  11. package/components/grid.js.map +1 -1
  12. package/components/header-row.d.ts +1 -2
  13. package/components/header-row.js +4 -7
  14. package/components/header-row.js.map +1 -1
  15. package/components/header.d.ts +9 -0
  16. package/components/header.js +36 -23
  17. package/components/header.js.map +1 -1
  18. package/components/row.d.ts +4 -1
  19. package/components/row.js +12 -1
  20. package/components/row.js.map +1 -1
  21. package/components/virtualizer.d.ts +3 -1
  22. package/components/virtualizer.js +36 -7
  23. package/components/virtualizer.js.map +1 -1
  24. package/controllers/data-operation.d.ts +0 -4
  25. package/controllers/data-operation.js +7 -22
  26. package/controllers/data-operation.js.map +1 -1
  27. package/controllers/dom.d.ts +28 -9
  28. package/controllers/dom.js +70 -20
  29. package/controllers/dom.js.map +1 -1
  30. package/controllers/filter.d.ts +20 -4
  31. package/controllers/filter.js +39 -55
  32. package/controllers/filter.js.map +1 -1
  33. package/controllers/navigation.d.ts +10 -10
  34. package/controllers/navigation.js +68 -53
  35. package/controllers/navigation.js.map +1 -1
  36. package/controllers/resize.d.ts +8 -8
  37. package/controllers/resize.js +23 -14
  38. package/controllers/resize.js.map +1 -1
  39. package/controllers/sort.d.ts +12 -3
  40. package/controllers/sort.js +25 -32
  41. package/controllers/sort.js.map +1 -1
  42. package/controllers/state.d.ts +28 -18
  43. package/controllers/state.js +20 -26
  44. package/controllers/state.js.map +1 -1
  45. package/custom-elements.json +874 -243
  46. package/docs/igniteui-grid-lite.json +1339 -818
  47. package/index.d.ts +1 -1
  48. package/index.js.map +1 -1
  49. package/internal/a11y.d.ts +29 -0
  50. package/internal/a11y.js +24 -0
  51. package/internal/a11y.js.map +1 -0
  52. package/internal/constants.d.ts +3 -2
  53. package/internal/constants.js +1 -4
  54. package/internal/constants.js.map +1 -1
  55. package/internal/normalize-case.d.ts +5 -1
  56. package/internal/normalize-case.js +2 -1
  57. package/internal/normalize-case.js.map +1 -1
  58. package/internal/part-map.js +9 -17
  59. package/internal/part-map.js.map +1 -1
  60. package/internal/tags.d.ts +2 -2
  61. package/internal/tags.js +2 -2
  62. package/internal/tags.js.map +1 -1
  63. package/internal/types.d.ts +13 -1
  64. package/internal/types.js.map +1 -1
  65. package/internal/utils.d.ts +3 -0
  66. package/internal/utils.js +17 -4
  67. package/internal/utils.js.map +1 -1
  68. package/internal/watch.js +8 -9
  69. package/internal/watch.js.map +1 -1
  70. package/operations/base.js +2 -1
  71. package/operations/base.js.map +1 -1
  72. package/operations/filter/state.js +2 -5
  73. package/operations/filter/state.js.map +1 -1
  74. package/operations/filter/tree.d.ts +1 -2
  75. package/operations/filter/tree.js +2 -7
  76. package/operations/filter/tree.js.map +1 -1
  77. package/operations/filter.js +13 -1
  78. package/operations/filter.js.map +1 -1
  79. package/operations/sort.d.ts +0 -1
  80. package/operations/sort.js +7 -9
  81. package/operations/sort.js.map +1 -1
  82. package/package.json +2 -2
  83. package/styles/themes/grid.base.css.js +1 -1
  84. package/styles/themes/grid.base.css.js.map +1 -1
  85. package/styles/themes/shared/grid.common.css.js +1 -1
  86. package/styles/themes/shared/grid.common.css.js.map +1 -1
@@ -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(host) {
6
- this.host = host;
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.host.rows
13
- .map((row) => row.cells.find((cell) => cell.column.field === key))
14
- .reduce((prev, current) => (current.offsetWidth > prev ? current.offsetWidth : prev), 0);
15
- return Math.max(...[MIN_COL_RESIZE_WIDTH, max, headerWidth]);
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.host.requestUpdate();
32
+ this.#indicatorChanged();
21
33
  }
22
34
  stop() {
23
35
  this.indicatorActive = false;
24
- this.host.requestUpdate();
36
+ this.#indicatorChanged();
25
37
  }
26
38
  resize(column, width, sizerOffset) {
27
39
  if (sizerOffset) {
28
40
  this.indicatorOffset = sizerOffset;
29
41
  }
30
- column.width = `${width}px`;
31
- this.host.requestUpdate();
42
+ this.#setWidth(column, `${width}px`);
32
43
  }
33
44
  async autosize(column, header) {
34
- column.width = 'max-content';
35
- this.host.requestUpdate();
45
+ this.#setWidth(column, 'max-content');
36
46
  await this.host.updateComplete;
37
- column.width = `${this.#maxSize(column.field, header.offsetWidth)}px`;
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;AAGhE,MAAM,OAAO,gBAAgB;IAC3B,YAAsB,IAAiB;QAAjB,SAAI,GAAJ,IAAI,CAAa;QAIhC,oBAAe,GAAG,KAAK,CAAC;QACxB,oBAAe,GAAG,CAAC,CAAC;QAJzB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAKD,QAAQ,CAAC,GAAY,EAAE,WAAmB;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI;aACvB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,GAAG,CAAE,CAAC;aAClE,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAE3F,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,oBAAoB,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/D,CAAC;IAOM,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,IAAI,CAAC,aAAa,EAAE,CAAC;IAC5B,CAAC;IAKM,IAAI;QACT,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IAC5B,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,MAAM,CAAC,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IAC5B,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,MAA8B,EAAE,MAA4B;QAChF,MAAM,CAAC,KAAK,GAAG,aAAa,CAAC;QAE7B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;QAE/B,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;QACtE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IAC5B,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, GridHost, Keys } from '../internal/types.js';\n\nexport class ResizeController<T extends object> implements ReactiveController {\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public indicatorActive = false;\n public indicatorOffset = 0;\n\n #maxSize(key: Keys<T>, headerWidth: number) {\n const max = this.host.rows\n .map((row) => row.cells.find((cell) => cell.column.field === key)!)\n .reduce((prev, current) => (current.offsetWidth > prev ? current.offsetWidth : prev), 0);\n\n return Math.max(...[MIN_COL_RESIZE_WIDTH, max, headerWidth]);\n }\n\n /**\n * Begins resizing a column by showing and positioning the resize indicator in relation to the column.\n *\n * @param header the\n */\n public start(header: IgcGridLiteHeader<T>) {\n this.indicatorActive = true;\n this.indicatorOffset = header.offsetLeft + header.offsetWidth;\n this.host.requestUpdate();\n }\n\n /**\n * Stops and resets the resizing state.\n */\n public stop() {\n this.indicatorActive = false;\n this.host.requestUpdate();\n }\n\n public resize(column: ColumnConfiguration<T>, width: number, sizerOffset?: number) {\n if (sizerOffset) {\n this.indicatorOffset = sizerOffset;\n }\n\n column.width = `${width}px`;\n this.host.requestUpdate();\n }\n\n public async autosize(column: ColumnConfiguration<T>, header: IgcGridLiteHeader<T>) {\n column.width = 'max-content';\n\n this.host.requestUpdate();\n await this.host.updateComplete;\n\n column.width = `${this.#maxSize(column.field, header.offsetWidth)}px`;\n this.host.requestUpdate();\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"]}
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"]}
@@ -1,12 +1,21 @@
1
1
  import type { ReactiveController } from 'lit';
2
- import type { ColumnConfiguration, GridHost, Keys } from '../internal/types.js';
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 host: GridHost<T>;
7
- constructor(host: GridHost<T>);
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;
@@ -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(host) {
5
- this.host = host;
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
- const expr = {
17
- caseSensitive: false,
18
- comparer: undefined,
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.updateComplete;
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 Object.assign(expr, {
74
- direction: this.#orderBy(expr.direction),
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) => Object.assign(this.state.get(expr.key) ?? this.#createDefaultExpression(expr.key), 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
  }
@@ -1 +1 @@
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, GridHost, Keys } from '../internal/types.js';\nimport { asArray } from '../internal/utils.js';\nimport type { SortingDirection, SortingExpression, SortState } from '../operations/sort/types.js';\n\nexport class SortController<T extends object> implements ReactiveController {\n constructor(protected host: GridHost<T>) {\n this.host.addController(this);\n }\n\n public state: SortState<T> = new Map();\n\n get #isMultipleSort() {\n return this.host.sortingOptions.mode === 'multiple';\n }\n\n get #isTriStateSort() {\n return true;\n }\n\n #resolveSortOptions(column?: ColumnConfiguration<T>) {\n const expr: Pick<SortingExpression<T>, 'caseSensitive' | 'comparer'> = {\n caseSensitive: false,\n comparer: undefined,\n };\n\n if (!column) {\n return expr as Partial<SortingExpression<T>>;\n }\n\n return Object.assign(expr, {\n caseSensitive: column.sortingCaseSensitive,\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 #orderBy(dir?: SortingDirection): SortingDirection {\n return this.#isTriStateSort\n ? dir === 'ascending'\n ? 'descending'\n : dir === 'descending'\n ? 'none'\n : 'ascending'\n : dir === 'ascending'\n ? 'descending'\n : 'ascending';\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.updateComplete;\n this.#emitSortedEvent(expression);\n }\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 Object.assign(expr, {\n direction: this.#orderBy(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 ? this.state.delete(key) : this.state.clear();\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.host.requestUpdate(PIPELINE);\n }\n\n public sort(expressions: SortingExpression<T> | SortingExpression<T>[]) {\n this._sort(\n asArray(expressions).map((expr) =>\n Object.assign(this.state.get(expr.key) ?? this.#createDefaultExpression(expr.key), expr)\n )\n );\n }\n\n public hostConnected() {}\n}\n"]}
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"]}
@@ -1,14 +1,19 @@
1
- import type { ReactiveController } from 'lit';
2
- import type IgcFilterRow from '../components/filter-row.js';
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
- declare class StateController<T extends object> implements ReactiveController {
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
- hostUpdate(): void;
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 };
@@ -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.host.addController(this);
35
- this.sorting = new SortController(this.host);
36
- this.filtering = new FilterController(this);
37
- this.navigation = new NavigationController(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
- hostUpdate() {
41
- this.headerRow?.requestUpdate();
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._observersCallback.call(this.host);
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._observersCallback.call(this.host);
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
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/controllers/state.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\nimport type IgcFilterRow from '../components/filter-row.js';\nimport type IgcGridLiteHeaderRow from '../components/header-row.js';\nimport type IgcGridLiteRow from '../components/row.js';\nimport type IgcVirtualizer from '../components/virtualizer.js';\nimport { PIPELINE } from '../internal/constants.js';\nimport {\n GRID_BODY,\n GRID_FILTER_ROW_TAG,\n GRID_HEADER_ROW_TAG,\n GRID_ROW_TAG,\n} from '../internal/tags.js';\nimport type { ActiveNode, ColumnConfiguration, GridHost } from '../internal/types.js';\nimport { createColumnConfiguration, setColumnsFromData } from '../internal/utils.js';\nimport { FilterController } from './filter.js';\nimport { NavigationController } from './navigation.js';\nimport { ResizeController } from './resize.js';\nimport { SortController } from './sort.js';\n\nclass StateController<T extends object> implements ReactiveController {\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 /** Returns the header row element of the grid. */\n public get headerRow(): IgcGridLiteHeaderRow<T> | null {\n return this.host.renderRoot.querySelector<IgcGridLiteHeaderRow<T>>(GRID_HEADER_ROW_TAG);\n }\n\n /** Returns the filter row element of the grid. */\n public get filterRow(): IgcFilterRow<T> | null {\n return this.host.renderRoot.querySelector<IgcFilterRow<T>>(GRID_FILTER_ROW_TAG);\n }\n\n /** Returns the data row elements of the grid. */\n public get rows(): IgcGridLiteRow<T>[] {\n return Array.from(this.host.renderRoot.querySelectorAll<IgcGridLiteRow<T>>(GRID_ROW_TAG));\n }\n\n /** Returns the virtualizer element of the grid. */\n public get virtualizer(): IgcVirtualizer | null {\n return this.host.renderRoot.querySelector(GRID_BODY);\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>, observersCallback: () => void) {\n this._observersCallback = observersCallback;\n this.host = host;\n this.host.addController(this);\n\n this.sorting = new SortController(this.host);\n this.filtering = new FilterController(this);\n this.navigation = new NavigationController(this);\n this.resizing = new ResizeController(this.host);\n }\n\n public hostUpdate(): void {\n this.headerRow?.requestUpdate();\n this.virtualizer?.requestUpdate();\n }\n\n public setColumnConfiguration(columns: ColumnConfiguration<T>[]): void {\n this._columns = columns.map((column) => createColumnConfiguration(column));\n this.filtering.resolveConditions();\n this._observersCallback.call(this.host);\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 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._observersCallback.call(this.host);\n this.host.requestUpdate(PIPELINE);\n }\n}\n\nfunction createStateController<T extends object>(\n host: GridHost<T>,\n observersCallback: () => void\n): StateController<T> {\n return new StateController<T>(host, observersCallback);\n}\n\nexport type { StateController };\nexport { createStateController };\n"]}
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"]}