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

IgniteUI / igniteui-angular / 13331632524

14 Feb 2025 02:51PM CUT coverage: 22.015% (-69.6%) from 91.622%
13331632524

Pull #15372

github

web-flow
Merge d52d57714 into bcb78ae0a
Pull Request #15372: chore(*): test ci passing

1990 of 15592 branches covered (12.76%)

431 of 964 new or added lines in 18 files covered. (44.71%)

19956 existing lines in 307 files now uncovered.

6452 of 29307 relevant lines covered (22.02%)

249.17 hits per line

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

62.5
/projects/igniteui-angular/src/lib/drop-down/drop-down.base.ts
1
import {
2
    Input, HostBinding, ElementRef, QueryList, Output, EventEmitter, ChangeDetectorRef, Directive,
3
    OnInit,
4
    Inject
5
} from '@angular/core';
6

7
import { Navigate, ISelectionEventArgs } from './drop-down.common';
8
import { IDropDownList } from './drop-down.common';
9
import { DropDownActionKey } from './drop-down.common';
10
import { IgxDropDownItemBaseDirective } from './drop-down-item.base';
11
import { DOCUMENT } from '@angular/common';
12

13
let NEXT_ID = 0;
2✔
14

15
/**
16
 * An abstract class, defining a drop-down component, with:
17
 * Properties for display styles and classes
18
 * A collection items of type `IgxDropDownItemBaseDirective`
19
 * Properties and methods for navigating (highlighting/focusing) items from the collection
20
 * Properties and methods for selecting items from the collection
21
 */
22
@Directive()
23
export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit {
2✔
24
    /**
25
     * Emitted when item selection is changing, before the selection completes
26
     *
27
     * ```html
28
     * <igx-drop-down (selectionChanging)='handleSelection()'></igx-drop-down>
29
     * ```
30
     */
31
    @Output()
32
    public selectionChanging = new EventEmitter<ISelectionEventArgs>();
183✔
33

34
    /**
35
     *  Gets/Sets the width of the drop down
36
     *
37
     * ```typescript
38
     * // get
39
     * let myDropDownCurrentWidth = this.dropdown.width;
40
     * ```
41
     * ```html
42
     * <!--set-->
43
     * <igx-drop-down [width]='160px'></igx-drop-down>
44
     * ```
45
     */
46
    @Input()
47
    public width: string;
48

49
    /**
50
     * Gets/Sets the height of the drop down
51
     *
52
     * ```typescript
53
     * // get
54
     * let myDropDownCurrentHeight = this.dropdown.height;
55
     * ```
56
     * ```html
57
     * <!--set-->
58
     * <igx-drop-down [height]='400px'></igx-drop-down>
59
     * ```
60
     */
61
    @Input()
62
    public height: string;
63

64
    /**
65
     * Gets/Sets the drop down's id
66
     *
67
     * ```typescript
68
     * // get
69
     * let myDropDownCurrentId = this.dropdown.id;
70
     * ```
71
     * ```html
72
     * <!--set-->
73
     * <igx-drop-down [id]='newDropDownId'></igx-drop-down>
74
     * ```
75
     */
76
    @HostBinding('attr.id')
77
    @Input()
78
    public get id(): string {
79
        return this._id;
×
80
    }
81
    public set id(value: string) {
82
        this._id = value;
×
83
    }
84

85
    /**
86
     * Gets/Sets the drop down's container max height.
87
     *
88
     * ```typescript
89
     * // get
90
     * let maxHeight = this.dropdown.maxHeight;
91
     * ```
92
     * ```html
93
     * <!--set-->
94
     * <igx-drop-down [maxHeight]='200px'></igx-drop-down>
95
     * ```
96
     */
97
    @Input()
98
    @HostBinding('style.maxHeight')
99
    public maxHeight = null;
183✔
100

101
    /**
102
     * @hidden @internal
103
     */
104
    @HostBinding('class.igx-drop-down')
105
    public cssClass = true;
183✔
106

107
    /**
108
     * Get all non-header items
109
     *
110
     * ```typescript
111
     * let myDropDownItems = this.dropdown.items;
112
     * ```
113
     */
114
    public get items(): IgxDropDownItemBaseDirective[] {
115
        const items: IgxDropDownItemBaseDirective[] = [];
579✔
116
        if (this.children !== undefined) {
579✔
117
            for (const child of this.children.toArray()) {
485✔
118
                if (!child.isHeader) {
2,102✔
119
                    items.push(child);
2,102✔
120
                }
121
            }
122
        }
123

124
        return items;
579✔
125
    }
126

127
    /**
128
     * Get all header items
129
     *
130
     * ```typescript
131
     * let myDropDownHeaderItems = this.dropdown.headers;
132
     * ```
133
     */
134
    public get headers(): IgxDropDownItemBaseDirective[] {
UNCOV
135
        const headers: IgxDropDownItemBaseDirective[] = [];
×
UNCOV
136
        if (this.children !== undefined) {
×
UNCOV
137
            for (const child of this.children.toArray()) {
×
UNCOV
138
                if (child.isHeader) {
×
UNCOV
139
                    headers.push(child);
×
140
                }
141
            }
142
        }
143

UNCOV
144
        return headers;
×
145
    }
146

147
    /**
148
     * Get dropdown html element
149
     *
150
     * ```typescript
151
     * let myDropDownElement = this.dropdown.element;
152
     * ```
153
     */
154
    public get element() {
155
        return this.elementRef.nativeElement;
162✔
156
    }
157
    /**
158
     * @hidden @internal
159
     * Get dropdown's html element of its scroll container
160
     */
161
    public get scrollContainer(): HTMLElement {
162
        return this.element;
×
163
    }
164

165
    /**
166
     * @hidden
167
     * @internal
168
     */
169
    public children: QueryList<IgxDropDownItemBaseDirective>;
170

171
    protected _width;
172
    protected _height;
173
    protected _focusedItem: any = null;
183✔
174
    protected _id = `igx-drop-down-${NEXT_ID++}`;
183✔
175
    protected computedStyles;
176

177
    /**
178
     * Gets if the dropdown is collapsed
179
     */
180
    public abstract readonly collapsed: boolean;
181

182
    constructor(
183
        protected elementRef: ElementRef,
183✔
184
        protected cdr: ChangeDetectorRef,
183✔
185
        @Inject(DOCUMENT) public document: any) {}
183✔
186

187
    public ngOnInit(): void {
188
        this.computedStyles = this.document.defaultView.getComputedStyle(this.elementRef.nativeElement);
89✔
189
    }
190

191
    /** Keydown Handler */
192
    public onItemActionKey(key: DropDownActionKey, event?: Event) {
UNCOV
193
        switch (key) {
×
194
            case DropDownActionKey.ENTER:
195
            case DropDownActionKey.SPACE:
UNCOV
196
                this.selectItem(this.focusedItem, event);
×
UNCOV
197
                break;
×
198
            case DropDownActionKey.ESCAPE:
199
        }
200
    }
201

202
    /**
203
     * Emits selectionChanging with the target item & event
204
     *
205
     * @hidden @internal
206
     * @param newSelection the item selected
207
     * @param event the event that triggered the call
208
     */
209
    public selectItem(newSelection?: IgxDropDownItemBaseDirective, event?: Event, emit = true) {  // eslint-disable-line
×
210
        this.selectionChanging.emit({
×
211
            newSelection,
212
            oldSelection: null,
213
            cancel: false
214
        });
215
    }
216

217
    /**
218
     * @hidden @internal
219
     */
220
    public get focusedItem(): IgxDropDownItemBaseDirective {
221
        return this._focusedItem;
×
222
    }
223

224
    /**
225
     * @hidden @internal
226
     */
227
    public set focusedItem(item: IgxDropDownItemBaseDirective) {
228
        this._focusedItem = item;
×
229
    }
230

231
    /**
232
     * Navigates to the item on the specified index
233
     *
234
     * @param newIndex number - the index of the item in the `items` collection
235
     */
236
    public navigateItem(newIndex: number) {
237
        if (newIndex !== -1) {
39✔
238
            const oldItem = this._focusedItem;
39✔
239
            const newItem = this.items[newIndex];
39✔
240
            if (oldItem) {
39!
UNCOV
241
                oldItem.focused = false;
×
242
            }
243
            this.focusedItem = newItem;
39✔
244
            this.scrollToHiddenItem(newItem);
39✔
245
            this.focusedItem.focused = true;
39✔
246
        }
247
    }
248

249
    /**
250
     * @hidden @internal
251
     */
252
    public navigateFirst() {
253
        this.navigate(Navigate.Down, -1);
39✔
254
    }
255

256
    /**
257
     * @hidden @internal
258
     */
259
    public navigateLast() {
UNCOV
260
        this.navigate(Navigate.Up, this.items.length);
×
261
    }
262

263
    /**
264
     * @hidden @internal
265
     */
266
    public navigateNext() {
UNCOV
267
        this.navigate(Navigate.Down);
×
268
    }
269

270
    /**
271
     * @hidden @internal
272
     */
273
    public navigatePrev() {
UNCOV
274
        this.navigate(Navigate.Up);
×
275
    }
276

277
    protected scrollToHiddenItem(newItem: IgxDropDownItemBaseDirective) {
278
        const elementRect = newItem.element.nativeElement.getBoundingClientRect();
39✔
279
        const parentRect = this.scrollContainer.getBoundingClientRect();
39✔
280
        if (parentRect.top > elementRect.top) {
39!
UNCOV
281
            this.scrollContainer.scrollTop -= (parentRect.top - elementRect.top);
×
282
        }
283

284
        if (parentRect.bottom < elementRect.bottom) {
39!
UNCOV
285
            this.scrollContainer.scrollTop += (elementRect.bottom - parentRect.bottom);
×
286
        }
287
    }
288

289
    protected navigate(direction: Navigate, currentIndex?: number) {
290
        let index = -1;
39✔
291
        if (this._focusedItem) {
39!
UNCOV
292
            index = currentIndex ? currentIndex : this.focusedItem.itemIndex;
×
293
        }
294
        const newIndex = this.getNearestSiblingFocusableItemIndex(index, direction);
39✔
295
        this.navigateItem(newIndex);
39✔
296
    }
297

298
    protected getNearestSiblingFocusableItemIndex(startIndex: number, direction: Navigate): number {
299
        let index = startIndex;
39✔
300
        const items = this.items;
39✔
301
        while (items[index + direction] && items[index + direction].disabled) {
39✔
UNCOV
302
            index += direction;
×
303
        }
304

305
        index += direction;
39✔
306
        if (index >= 0 && index < items.length) {
39!
307
            return index;
39✔
308
        } else {
UNCOV
309
            return -1;
×
310
        }
311
    }
312
}
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

© 2025 Coveralls, Inc