• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IgniteUI / igniteui-webcomponents / 24070777061

07 Apr 2026 07:56AM UTC coverage: 98.397% (+0.04%) from 98.361%
24070777061

Pull #2164

github

web-flow
Merge 446426949 into f74b953a9
Pull Request #2164: refactor(combo): overhaul selection, data pipeline, and component architecture

5548 of 5831 branches covered (95.15%)

Branch coverage included in aggregate %.

927 of 941 new or added lines in 26 files covered. (98.51%)

1 existing line in 1 file now uncovered.

39192 of 39638 relevant lines covered (98.87%)

1502.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.27
/src/components/combo/controllers/data.ts
1
import type { ReactiveController } from 'lit';
8✔
2

8✔
3
import FilterDataOperation from '../operations/filter.js';
8✔
4
import GroupDataOperation from '../operations/group.js';
8✔
5
import type {
8✔
6
  ComboHost,
8✔
7
  ComboRecord,
8✔
8
  FilteringOptions,
8✔
9
  GroupingOptions,
8✔
10
  Keys,
8✔
11
} from '../types.js';
8✔
12

8✔
13
/* blazorSuppress */
8✔
14
export class DataState<T extends object> implements ReactiveController {
8✔
15
  //#region Internal state
8✔
16
  private readonly _host: ComboHost<T>;
8✔
17
  private readonly _filtering = new FilterDataOperation<T>();
8✔
18
  private readonly _grouping = new GroupDataOperation<T>();
8✔
19
  private _compareCollator: Intl.Collator;
8✔
20

8✔
21
  private _dataState: ComboRecord<T>[] = [];
8✔
22
  private _searchTerm = '';
8✔
23
  private _dirty = true;
8✔
24

8✔
25
  //#endregion
8✔
26

8✔
27
  //#region Public state accessors
8✔
28

8✔
29
  /** The current state of the data in the combo component. */
8✔
30
  public get dataState(): Readonly<ComboRecord<T>[]> {
8✔
31
    return this._dataState;
8✔
32
  }
8✔
33

8✔
34
  /**
8✔
35
   * Sets the current search term used for filtering the data.
8✔
36
   * Triggers a data pipeline run if the value changes.
8✔
37
   */
8✔
38
  public set searchTerm(value: string) {
8✔
39
    if (this._searchTerm !== value) {
80✔
40
      this._searchTerm = value;
21✔
41
      this.invalidate();
21✔
42
    }
21✔
43
  }
80✔
44

8✔
45
  /** The current search term used for filtering the data. */
8✔
46
  public get searchTerm(): string {
8✔
47
    return this._searchTerm;
746✔
48
  }
746✔
49

8✔
50
  /** The current filtering options for the combo component. */
8✔
51
  public get filteringOptions(): FilteringOptions<T> {
8✔
52
    return this._host.filteringOptions;
139✔
53
  }
139✔
54

8✔
55
  /** The current grouping options for the combo component. */
8✔
56
  public get groupingOptions(): GroupingOptions<T> {
8✔
57
    return {
139✔
58
      valueKey: this._host.valueKey,
139✔
59
      displayKey: this._host.displayKey,
139✔
60
      groupKey: this._host.groupKey as Keys<T>,
139✔
61
      direction: this._host.groupSorting,
139✔
62
    };
139✔
63
  }
139✔
64

8✔
65
  /** The current collator used for comparing values. */
8✔
66
  public get compareCollator(): Intl.Collator {
8✔
67
    return this._compareCollator;
96✔
68
  }
96✔
69

8✔
70
  //#endregion
8✔
71

8✔
72
  //#region Lifecycle and pipeline management
8✔
73

8✔
74
  constructor(host: ComboHost<T>) {
8✔
75
    this._host = host;
103✔
76
    this._host.addController(this);
103✔
77
    this._compareCollator = new Intl.Collator(this._host.locale);
103✔
78
  }
103✔
79

8✔
80
  /**
8✔
81
   * Lit lifecycle hook - runs before rendering.
8✔
82
   * Executes pipeline if any changes were batched.
8✔
83
   * @internal
8✔
84
   */
8✔
85
  public hostUpdate(): void {
8✔
86
    this._runPipelineIfDirty();
344✔
87
  }
344✔
88

8✔
89
  /**
8✔
90
   * Marks the data state as dirty, triggering a pipeline run before next render.
8✔
91
   * This batches multiple changes into a single pipeline execution.
8✔
92
   */
8✔
93
  private _markDirty(): void {
8✔
94
    if (!this._dirty) {
139✔
95
      this._dirty = true;
36✔
96
      this._host.requestUpdate();
36✔
97
    }
36✔
98
  }
139✔
99

8✔
100
  /**
8✔
101
   * Executes the data pipeline if marked dirty.
8✔
102
   * Called during the update lifecycle to batch changes.
8✔
103
   */
8✔
104
  private _runPipelineIfDirty(): void {
8✔
105
    if (this._dirty) {
344✔
106
      this._dataState = this._apply(Array.from(this._host.data));
139✔
107
      this._dirty = false;
139✔
108
    }
139✔
109
  }
344✔
110

8✔
111
  //#endregion
8✔
112

8✔
113
  //#region Internal pipeline operations
8✔
114

8✔
115
  /**
8✔
116
   * Initial indexing of the data - converts raw data items into ComboRecord format with metadata.
8✔
117
   */
8✔
118
  private _index(data: T[]): ComboRecord<T>[] {
8✔
119
    return data.map((item, index) => ({
139✔
120
      value: item,
815✔
121
      header: false,
815✔
122
      dataIndex: index,
815✔
123
    }));
139✔
124
  }
139✔
125

8✔
126
  /**
8✔
127
   * Applies the data pipeline: indexing, filtering, and grouping.
8✔
128
   */
8✔
129
  private _apply(data: T[]): ComboRecord<T>[] {
8✔
130
    let records = this._index(data);
139✔
131
    records = this._filtering.apply(records, this);
139✔
132
    records = this._grouping.apply(records, this);
139✔
133

139✔
134
    return records;
139✔
135
  }
139✔
136

8✔
137
  //#endregion
8✔
138

8✔
139
  //#region Public API for host component
8✔
140

8✔
141
  /**
8✔
142
   * Updates the collator when locale changes.
8✔
143
   */
8✔
144
  public updateLocale(locale: string): void {
8✔
NEW
145
    this._compareCollator = new Intl.Collator(locale);
×
NEW
146
    this._markDirty();
×
NEW
147
  }
×
148

8✔
149
  /**
8✔
150
   * Marks data as dirty when host properties that affect data change.
8✔
151
   */
8✔
152
  public invalidate(): void {
8✔
153
    this._markDirty();
139✔
154
  }
139✔
155

8✔
156
  //#endregion
8✔
157
}
8✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc