• 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

12.73
/projects/igniteui-angular/src/lib/select/select-navigation.directive.ts
1
import { IgxDropDownItemNavigationDirective } from '../drop-down/drop-down-navigation.directive';
2
import { Directive, Input, OnDestroy } from '@angular/core';
3
import { Subscription, timer } from 'rxjs';
4
import { IgxSelectItemComponent } from './select-item.component';
5
import { IgxSelectBase } from './select.common';
6

7
/** @hidden @internal */
8
@Directive({
9
    selector: '[igxSelectItemNavigation]',
10
    standalone: true
11
})
12
export class IgxSelectItemNavigationDirective extends IgxDropDownItemNavigationDirective implements OnDestroy {
2✔
13
    protected override _target: IgxSelectBase = null;
94✔
14

15
    @Input('igxSelectItemNavigation')
16
    public override get target(): IgxSelectBase {
UNCOV
17
        return this._target;
×
18
    }
19
    public override set target(target: IgxSelectBase) {
20
        this._target = target ? target : this.dropdown as IgxSelectBase;
94!
21
    }
22

23
    constructor() {
24
        super(null);
94✔
25
    }
26

27
    /** Captures keydown events and calls the appropriate handlers on the target component */
28
    public override handleKeyDown(event: KeyboardEvent) {
UNCOV
29
        if (!event) {
×
30
            return;
×
31
        }
32

UNCOV
33
        const key = event.key.toLowerCase();
×
UNCOV
34
        if (event.altKey && (key === 'arrowdown' || key === 'arrowup' || key === 'down' || key === 'up')) {
×
UNCOV
35
            this.target.toggle();
×
UNCOV
36
            return;
×
37
        }
38

UNCOV
39
        if (this.target.collapsed) {
×
UNCOV
40
            switch (key) {
×
41
                case 'space':
42
                case 'spacebar':
43
                case ' ':
44
                case 'enter':
UNCOV
45
                    event.preventDefault();
×
UNCOV
46
                    this.target.open();
×
UNCOV
47
                    return;
×
48
                case 'arrowdown':
49
                case 'down':
UNCOV
50
                    this.target.navigateNext();
×
UNCOV
51
                    this.target.selectItem(this.target.focusedItem);
×
UNCOV
52
                    event.preventDefault();
×
UNCOV
53
                    return;
×
54
                case 'arrowup':
55
                case 'up':
UNCOV
56
                    this.target.navigatePrev();
×
UNCOV
57
                    this.target.selectItem(this.target.focusedItem);
×
UNCOV
58
                    event.preventDefault();
×
UNCOV
59
                    return;
×
60
                default:
UNCOV
61
                    break;
×
62
            }
UNCOV
63
        } else if (key === 'tab' || event.shiftKey && key === 'tab') {
×
UNCOV
64
            this.target.close();
×
65
        }
66

UNCOV
67
        super.handleKeyDown(event);
×
UNCOV
68
        this.captureKey(event);
×
69
    }
70

71
    private inputStream = '';
94✔
72
    private clearStream$ = Subscription.EMPTY;
94✔
73

74
    public captureKey(event: KeyboardEvent) {
75
        // relying only on key, available on all major browsers:
76
        // https://caniuse.com/#feat=keyboardevent-key (IE/Edge quirk doesn't affect letter typing)
UNCOV
77
        if (!event || !event.key || event.key.length > 1 || event.key === ' ' || event.key === 'spacebar') {
×
78
            // ignore longer keys ('Alt', 'ArrowDown', etc) AND spacebar (used of open/close)
UNCOV
79
            return;
×
80
        }
81

UNCOV
82
        this.clearStream$.unsubscribe();
×
UNCOV
83
        this.clearStream$ = timer(500).subscribe(() => {
×
UNCOV
84
            this.inputStream = '';
×
85
        });
86

UNCOV
87
        this.inputStream += event.key;
×
UNCOV
88
        const focusedItem = this.target.focusedItem as IgxSelectItemComponent;
×
89

90
        // select the item
UNCOV
91
        if (focusedItem && this.inputStream.length > 1 && focusedItem.itemText.toLowerCase().startsWith(this.inputStream.toLowerCase())) {
×
UNCOV
92
            return;
×
93
        }
UNCOV
94
        this.activateItemByText(this.inputStream);
×
95
    }
96

97
    public activateItemByText(text: string) {
UNCOV
98
        const items = this.target.items as IgxSelectItemComponent[];
×
99

100
        // ^ this is focused OR selected if the dd is closed
101

UNCOV
102
        let nextItem = this.findNextItem(items, text);
×
103

104
        // If there is no such an item starting with the current text input stream AND the last Char in the input stream
105
        // is the same as the first one, find next item starting with the same first Char.
106
        // Covers cases of holding down the same key Ex: "pppppp" that iterates trough list items starting with "p".
UNCOV
107
        if (!nextItem && text.charAt(0) === text.charAt(text.length - 1)) {
×
UNCOV
108
            text = text.slice(0, 1);
×
UNCOV
109
            nextItem = this.findNextItem(items, text);
×
110
        }
111

112
        // If there is no other item to be found, do not change the active item.
UNCOV
113
        if (!nextItem) {
×
UNCOV
114
            return;
×
115
        }
116

UNCOV
117
        if (this.target.collapsed) {
×
UNCOV
118
            this.target.selectItem(nextItem);
×
119
        }
UNCOV
120
        this.target.navigateItem(items.indexOf(nextItem));
×
121
    }
122

123
    public ngOnDestroy(): void {
124
        this.clearStream$.unsubscribe();
94✔
125
    }
126

127
    private findNextItem(items: IgxSelectItemComponent[],  text: string) {
UNCOV
128
        const activeItemIndex = items.indexOf(this.target.focusedItem as IgxSelectItemComponent) || 0;
×
129

130
        // Match next item in ddl items and wrap around if needed
UNCOV
131
        return items.slice(activeItemIndex + 1).find(x => !x.disabled && (x.itemText.toLowerCase().startsWith(text.toLowerCase()))) ||
×
UNCOV
132
            items.slice(0, activeItemIndex).find(x => !x.disabled && (x.itemText.toLowerCase().startsWith(text.toLowerCase())));
×
133
    }
134
}
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