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

IgniteUI / igniteui-angular / 14729512507

29 Apr 2025 10:54AM CUT coverage: 91.654% (+0.05%) from 91.607%
14729512507

Pull #15616

github

web-flow
Merge f66caa5a4 into 5f255b263
Pull Request #15616: refactor(tests): removing configureTestSuite()

13410 of 15685 branches covered (85.5%)

26948 of 29402 relevant lines covered (91.65%)

34451.44 hits per line

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

37.65
/projects/igniteui-angular/src/lib/grids/selection/drag-select.directive.ts
1
import { Directive, Input, Output, EventEmitter, ElementRef, OnDestroy, NgZone, OnInit, booleanAttribute } from '@angular/core';
2
import { interval, Observable, Subscription, Subject, animationFrameScheduler } from 'rxjs';
3
import { filter, takeUntil } from 'rxjs/operators';
4

5
enum DragScrollDirection {
3✔
6
    NONE,
3✔
7
    LEFT,
3✔
8
    TOP,
3✔
9
    RIGHT,
3✔
10
    BOTTOM,
3✔
11
    TOPLEFT,
3✔
12
    TOPRIGHT,
3✔
13
    BOTTOMLEFT,
3✔
14
    BOTTOMRIGHT
3✔
15
}
16

17
/**
18
 * An internal directive encapsulating the drag scroll behavior in the grid.
19
 *
20
 * @hidden @internal
21
 */
22
@Directive({
23
    selector: '[igxGridDragSelect]',
24
    standalone: true
25
})
26
export class IgxGridDragSelectDirective implements OnInit, OnDestroy {
3✔
27

28
    @Output()
29
    public dragStop = new EventEmitter<boolean>();
3,570✔
30

31
    @Output()
32
    public dragScroll = new EventEmitter<{ left: number; top: number }>();
3,570✔
33

34
    @Input({ alias: 'igxGridDragSelect', transform: booleanAttribute })
35
    public get activeDrag(): boolean {
36
        return this._activeDrag;
×
37
    }
38

39
    public set activeDrag(val: boolean) {
40
        if (val !== this._activeDrag) {
3,642✔
41
            this.unsubscribe();
3,642✔
42
            this._activeDrag = val;
3,642✔
43
        }
44
    }
45

46
    public get nativeElement() {
47
        return this.ref.nativeElement;
14,218✔
48
    }
49

50
    protected end$ = new Subject<any>();
3,570✔
51
    protected lastDirection = DragScrollDirection.NONE;
3,570✔
52
    protected _interval$: Observable<any>;
53
    protected _sub: Subscription;
54

55
    private _activeDrag: boolean;
56

57
    constructor(private ref: ElementRef<HTMLElement>, private zone: NgZone) {
3,570✔
58
        this._interval$ = interval(0, animationFrameScheduler).pipe(
3,570✔
59
            takeUntil(this.end$),
60
            filter(() => this.activeDrag)
×
61
        );
62
    }
63

64
    public ngOnInit() {
65
        this.zone.runOutsideAngular(() => {
3,570✔
66
            this.nativeElement.addEventListener('pointerover', this.startDragSelection);
3,570✔
67
            this.nativeElement.addEventListener('pointerleave', this.stopDragSelection);
3,570✔
68
        });
69
    }
70

71
    public ngOnDestroy() {
72
        this.zone.runOutsideAngular(() => {
3,539✔
73
            this.nativeElement.removeEventListener('pointerover', this.startDragSelection);
3,539✔
74
            this.nativeElement.removeEventListener('pointerleave', this.stopDragSelection);
3,539✔
75
        });
76
        this.unsubscribe();
3,539✔
77
        this.end$.complete();
3,539✔
78
    }
79

80

81
    protected startDragSelection = (ev: PointerEvent) => {
3,570✔
82
        if (!this.activeDrag) {
×
83
            return;
×
84
        }
85

86
        const x = ev.clientX;
×
87
        const y = ev.clientY;
×
88
        const { direction, delta } = this._measureDimensions(x, y);
×
89

90
        if (direction === this.lastDirection) {
×
91
            return;
×
92
        }
93

94
        this.unsubscribe();
×
95
        this._sub = this._interval$.subscribe(() => this.dragScroll.emit(delta));
×
96
        this.lastDirection = direction;
×
97
    };
98

99
    protected stopDragSelection = () => {
3,570✔
100
        if (!this.activeDrag) {
×
101
            return;
×
102
        }
103

104
        this.dragStop.emit(false);
×
105
        this.unsubscribe();
×
106
        this.lastDirection = DragScrollDirection.NONE;
×
107
    };
108

109
    protected _measureDimensions(x: number, y: number): { direction: DragScrollDirection; delta: { left: number; top: number } } {
110
        let direction: DragScrollDirection;
111
        let delta = { left: 0, top: 0 };
×
112
        const { left, top, width, height } = this.nativeElement.getBoundingClientRect();
×
113
        const RATIO = 0.15;
×
114

115
        const offsetX = Math.trunc(x - left);
×
116
        const offsetY = Math.trunc(y - top);
×
117

118
        const leftDirection = offsetX <= width * RATIO;
×
119
        const rightDirection = offsetX >= width * (1 - RATIO);
×
120
        const topDirection = offsetY <= height * RATIO;
×
121
        const bottomDirection = offsetY >= height * (1 - RATIO);
×
122

123
        if (topDirection && leftDirection) {
×
124
            direction = DragScrollDirection.TOPLEFT;
×
125
            delta = { left: -1, top: -1 };
×
126
        } else if (topDirection && rightDirection) {
×
127
            direction = DragScrollDirection.TOPRIGHT;
×
128
            delta = { left: 1, top: -1 };
×
129
        } else if (bottomDirection && leftDirection) {
×
130
            direction = DragScrollDirection.BOTTOMLEFT;
×
131
            delta = { left: -1, top: 1 };
×
132
        } else if (bottomDirection && rightDirection) {
×
133
            direction = DragScrollDirection.BOTTOMRIGHT;
×
134
            delta = { top: 1, left: 1 };
×
135
        } else if (topDirection) {
×
136
            direction = DragScrollDirection.TOP;
×
137
            delta.top = -1;
×
138
        } else if (bottomDirection) {
×
139
            direction = DragScrollDirection.BOTTOM;
×
140
            delta.top = 1;
×
141
        } else if (leftDirection) {
×
142
            direction = DragScrollDirection.LEFT;
×
143
            delta.left = -1;
×
144
        } else if (rightDirection) {
×
145
            direction = DragScrollDirection.RIGHT;
×
146
            delta.left = 1;
×
147
        } else {
148
            direction = DragScrollDirection.NONE;
×
149
        }
150

151
        return { direction, delta };
×
152

153
    }
154

155
    protected unsubscribe() {
156
        if (this._sub) {
7,181!
157
            this._sub.unsubscribe();
×
158
        }
159
    }
160
}
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