• 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

1.27
/projects/igniteui-angular/src/lib/slider/thumb/thumb-slider.component.ts
1
import {
2
    Component,
3
    Input,
4
    HostListener,
5
    ElementRef,
6
    HostBinding,
7
    Output,
8
    EventEmitter,
9
    OnInit,
10
    OnDestroy,
11
    TemplateRef,
12
    booleanAttribute
13
} from '@angular/core';
14
import { takeUntil } from 'rxjs/operators';
15
import { SliderHandle } from '../slider.common';
16
import { Subject } from 'rxjs';
17
import { IgxDirectionality } from '../../services/direction/directionality';
18
import { NgClass } from '@angular/common';
19

20
/**
21
 * @hidden
22
 */
23
@Component({
24
    selector: 'igx-thumb',
25
    templateUrl: 'thumb-slider.component.html',
26
    imports: [NgClass]
27
})
28
export class IgxSliderThumbComponent implements OnInit, OnDestroy {
2✔
29
    @Input()
30
    public value: any;
31

32
    @Input({ transform: booleanAttribute })
33
    public continuous: boolean;
34

35
    @Input()
36
    public thumbLabelVisibilityDuration: number;
37

38
    @Input({ transform: booleanAttribute })
39
    public disabled: boolean;
40

41
    @Input()
42
    public onPan: Subject<number>;
43

44
    @Input()
45
    public stepDistance: number;
46

47
    @Input()
48
    public step: number;
49

50
    @Input()
51
    public templateRef: TemplateRef<any>;
52

53
    @Input()
54
    public context: any;
55

56
    @Input()
57
    public type: SliderHandle;
58

59
    @Input({ transform: booleanAttribute })
60
    public deactiveState: boolean;
61

62
    @Input()
63
    public min: number;
64

65
    @Input()
66
    public max: number;
67

68
    @Input()
69
    public labels: any[];
70

71
    @Output()
UNCOV
72
    public thumbValueChange = new EventEmitter<number>();
×
73

74
    @Output()
UNCOV
75
    public thumbChange = new EventEmitter<any>();
×
76

77
    @Output()
UNCOV
78
    public thumbBlur = new EventEmitter<void>();
×
79

80
    @Output()
UNCOV
81
    public hoverChange = new EventEmitter<boolean>();
×
82

83
    @HostBinding('attr.tabindex')
UNCOV
84
    public tabindex = 0;
×
85

86
    @HostBinding('attr.role')
UNCOV
87
    public role = 'slider';
×
88

89
    @HostBinding('attr.aria-valuenow')
90
    public get ariaValueNow() {
UNCOV
91
        return this.value;
×
92
    }
93

94
    @HostBinding('attr.aria-valuemin')
95
    public get ariaValueMin() {
UNCOV
96
        return this.min;
×
97
    }
98

99
    @HostBinding('attr.aria-valuemax')
100
    public get ariaValueMax() {
UNCOV
101
        return this.max;
×
102
    }
103

104
    @HostBinding('attr.aria-valuetext')
105
    public get ariaValueText() {
UNCOV
106
        if (this.labels && this.labels[this.value] !== undefined) {
×
UNCOV
107
            return this.labels[this.value];
×
108
        }
UNCOV
109
        return this.value;
×
110
    }
111

112
    @HostBinding('attr.aria-label')
113
    public get ariaLabelAttr() {
UNCOV
114
        return `Slider thumb ${this.type}`;
×
115
    }
116

117
    @HostBinding('attr.aria-orientation')
UNCOV
118
    public ariaOrientation = 'horizontal';
×
119

120
    @HostBinding(`attr.aria-disabled`)
121
    public get ariaDisabled() {
UNCOV
122
        return this.disabled;
×
123
    }
124

125
    @HostBinding('attr.z-index')
UNCOV
126
    public zIndex = 0;
×
127

128
    @HostBinding('class.igx-slider-thumb-to--focused')
UNCOV
129
    public focused = false;
×
130

131
    @HostBinding('class.igx-slider-thumb-from')
132
    public get thumbFromClass() {
UNCOV
133
        return this.type === SliderHandle.FROM;
×
134
    }
135

136
    @HostBinding('class.igx-slider-thumb-to')
137
    public get thumbToClass() {
UNCOV
138
        return this.type === SliderHandle.TO;
×
139
    }
140

141
    @HostBinding('class.igx-slider-thumb-from--active')
142
    public get thumbFromActiveClass() {
UNCOV
143
        return this.type === SliderHandle.FROM && this._isActive;
×
144
    }
145

146
    @HostBinding('class.igx-slider-thumb-to--active')
147
    public get thumbToActiveClass() {
UNCOV
148
        return this.type === SliderHandle.TO && this._isActive;
×
149
    }
150

151
    @HostBinding('class.igx-slider-thumb-from--disabled')
152
    public get thumbFromDisabledClass() {
UNCOV
153
        return this.type === SliderHandle.FROM && this.disabled;
×
154
    }
155

156
    @HostBinding('class.igx-slider-thumb-to--disabled')
157
    public get thumbToDisabledClass() {
UNCOV
158
        return this.type === SliderHandle.TO && this.disabled;
×
159
    }
160

161
    @HostBinding('class.igx-slider-thumb-from--pressed')
162
    public get thumbFromPressedClass() {
UNCOV
163
        return this.type === SliderHandle.FROM && this.isActive && this._isPressed;
×
164
    }
165

166
    @HostBinding('class.igx-slider-thumb-to--pressed')
167
    public get thumbToPressedClass() {
UNCOV
168
        return this.type === SliderHandle.TO && this.isActive && this._isPressed;
×
169
    }
170

171
    public get getDotClass() {
UNCOV
172
        return {
×
173
            'igx-slider-thumb-from__dot': this.type === SliderHandle.FROM,
174
            'igx-slider-thumb-to__dot': this.type === SliderHandle.TO
175
        };
176
    }
177

UNCOV
178
    public isActive = false;
×
179

180
    public get nativeElement() {
UNCOV
181
        return this._elementRef.nativeElement;
×
182
    }
183

184
    public get destroy(): Subject<boolean> {
UNCOV
185
        return this._destroy$;
×
186
    }
187

UNCOV
188
    private _isActive = false;
×
UNCOV
189
    private _isPressed = false;
×
UNCOV
190
    private _destroy$ = new Subject<boolean>();
×
191

192
    private get thumbPositionX() {
UNCOV
193
        const thumbBounderies = this.nativeElement.getBoundingClientRect();
×
UNCOV
194
        const thumbCenter = (thumbBounderies.right - thumbBounderies.left) / 2;
×
UNCOV
195
        return thumbBounderies.left + thumbCenter;
×
196
    }
197

UNCOV
198
    constructor(private _elementRef: ElementRef, private _dir: IgxDirectionality) { }
×
199

200
    @HostListener('pointerenter')
201
    public onPointerEnter() {
202
        this.focused = false;
×
203
        this.hoverChange.emit(true);
×
204
    }
205

206
    @HostListener('pointerleave')
207
    public onPointerLeave() {
208
        this.hoverChange.emit(false);
×
209
    }
210

211
    @HostListener('keyup', ['$event'])
212
    public onKeyUp(event: KeyboardEvent) {
213
        event.stopPropagation();
×
214
        this.focused = true;
×
215
    }
216

217
    @HostListener('keydown', ['$event'])
218
    public onKeyDown(event: KeyboardEvent) {
UNCOV
219
        if (this.disabled) {
×
UNCOV
220
            return;
×
221
        }
222

UNCOV
223
        let increment = 0;
×
UNCOV
224
        const stepWithDir = (rtl: boolean) => rtl ? this.step * -1 : this.step;
×
UNCOV
225
        if (event.key.endsWith('Left')) {
×
UNCOV
226
            increment = stepWithDir(!this._dir.rtl);
×
UNCOV
227
        } else if (event.key.endsWith('Right')) {
×
UNCOV
228
            increment = stepWithDir(this._dir.rtl);
×
229
        } else {
UNCOV
230
            return;
×
231
        }
232

UNCOV
233
        this.thumbChange.emit();
×
UNCOV
234
        this.thumbValueChange.emit(increment);
×
235
    }
236

237
    @HostListener('blur')
238
    public onBlur() {
UNCOV
239
        this.isActive = false;
×
UNCOV
240
        this.zIndex = 0;
×
UNCOV
241
        this.focused = false;
×
UNCOV
242
        this.thumbBlur.emit();
×
243
    }
244

245
    @HostListener('focus')
246
    public onFocusListener() {
UNCOV
247
        this.isActive = true;
×
UNCOV
248
        this.zIndex = 1;
×
249
    }
250

251
    /**
252
     * @hidden
253
     */
254
    public ngOnInit() {
UNCOV
255
        this.onPan
×
256
            .pipe(takeUntil(this._destroy$))
257
            .subscribe(mouseX =>
UNCOV
258
                this.updateThumbValue(mouseX)
×
259
            );
260
    }
261

262
    /**
263
     * @hidden
264
     */
265
    public ngOnDestroy() {
UNCOV
266
        this._destroy$.next(true);
×
UNCOV
267
        this._destroy$.complete();
×
268
    }
269

270
    /**
271
     * Show thumb label and ripple.
272
     */
273
    public showThumbIndicators() {
UNCOV
274
        this.toggleThumbIndicators(true);
×
275
    }
276

277
    /**
278
     * Hide thumb label and ripple.
279
     */
280
    public hideThumbIndicators() {
UNCOV
281
        this.toggleThumbIndicators(false);
×
282
    }
283

284
    private updateThumbValue(mouseX: number) {
UNCOV
285
        const updateValue = this.calculateTrackUpdate(mouseX);
×
UNCOV
286
        if (this.isActive && updateValue !== 0) {
×
UNCOV
287
            this.thumbValueChange.emit(updateValue);
×
288
        }
289
    }
290

291
    private calculateTrackUpdate(mouseX: number): number {
UNCOV
292
        const scaleX = this._dir.rtl ? this.thumbPositionX - mouseX : mouseX - this.thumbPositionX;
×
UNCOV
293
        const stepDistanceCenter = this.stepDistance / 2;
×
294

295
        // If the thumb scale range (slider update) is less thàn a half step,
296
        // the position stays the same.
UNCOV
297
        const scaleXPositive = Math.abs(scaleX);
×
UNCOV
298
        if (scaleXPositive < stepDistanceCenter) {
×
UNCOV
299
            return 0;
×
300
        }
301

UNCOV
302
        return this.stepToProceed(scaleX, this.stepDistance);
×
303
    }
304

305
    private stepToProceed(scaleX, stepDist) {
UNCOV
306
        return Math.round(scaleX / stepDist) * this.step;
×
307
    }
308

309
    private toggleThumbIndicators(visible: boolean) {
UNCOV
310
        this._isPressed = visible;
×
311

UNCOV
312
        if (this.continuous || this.deactiveState) {
×
UNCOV
313
            this._isActive = false;
×
314
        } else {
UNCOV
315
            this._isActive = visible;
×
316
        }
317

318
    }
319
}
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