From 064f4daa88588255e2328dc64294e2e11644aea1 Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Tue, 1 Apr 2025 10:19:37 +0300 Subject: [PATCH 1/3] fix(timepicker): allowing better scroll on touchpads #6292 --- .../lib/time-picker/time-picker.directives.ts | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.directives.ts b/projects/igniteui-angular/src/lib/time-picker/time-picker.directives.ts index dc416613062..eda74acff65 100644 --- a/projects/igniteui-angular/src/lib/time-picker/time-picker.directives.ts +++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.directives.ts @@ -34,6 +34,14 @@ export class IgxItemListDirective implements OnInit, OnDestroy { public isActive: boolean; + private readonly SCROLL_THRESHOLD = 15; + private readonly PAN_THRESHOLD = 10; + + /** + * accumulates wheel scrolls and triggers a change action above SCROLL_THRESHOLD + */ + private scrollAccumulator = 0; + constructor( @Inject(IGX_TIME_PICKER_COMPONENT) public timePicker: IgxTimePickerBase, private elementRef: ElementRef, @@ -170,9 +178,10 @@ export class IgxItemListDirective implements OnInit, OnDestroy { event.preventDefault(); event.stopPropagation(); - const delta = event.deltaY; - if (delta !== 0) { - this.nextItem(delta); + this.scrollAccumulator += event.deltaY; + if (Math.abs(this.scrollAccumulator) > this.SCROLL_THRESHOLD) { + this.nextItem(this.scrollAccumulator); + this.scrollAccumulator = 0; } } @@ -180,14 +189,24 @@ export class IgxItemListDirective implements OnInit, OnDestroy { * @hidden @internal */ public ngOnInit() { - const hammerOptions: HammerOptions = { recognizers: [[HammerGesturesManager.Hammer?.Pan, { direction: HammerGesturesManager.Hammer?.DIRECTION_VERTICAL, threshold: 10 }]] }; + const hammerOptions: HammerOptions = { + recognizers: [ + [ + HammerGesturesManager.Hammer?.Pan, + { + direction: HammerGesturesManager.Hammer?.DIRECTION_VERTICAL, + threshold: this.PAN_THRESHOLD + } + ] + ] + }; this.touchManager.addEventListener(this.elementRef.nativeElement, 'pan', this.onPanMove, hammerOptions); } /** * @hidden @internal */ - public ngOnDestroy() { + public ngOnDestroy() { this.touchManager.destroy(); } @@ -355,7 +374,7 @@ export class IgxTimeItemDirective { private getHourPart(date: Date): string { const inputDateParts = DateTimeUtil.parseDateTimeFormat(this.timePicker.appliedFormat); const hourPart = inputDateParts.find(element => element.type === 'hours'); - const ampmPart = inputDateParts.find(element =>element.format.indexOf('a') !== -1 || element.format === 'tt'); + const ampmPart = inputDateParts.find(element => element.format.indexOf('a') !== -1 || element.format === 'tt'); const hour = DateTimeUtil.getPartValue(date, hourPart, hourPart.format.length); if (ampmPart) { const ampm = DateTimeUtil.getPartValue(date, ampmPart, ampmPart.format.length); From 97a90e2ca5fbba4c72e93c8c8203ca6100d80c61 Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Mon, 7 Jul 2025 13:59:58 +0300 Subject: [PATCH 2/3] fix(pickers): adding logic for date editor/picker, slowing scroll down further --- .../date-time-editor.directive.ts | 15 +++++++++++---- .../src/lib/time-picker/time-picker.directives.ts | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.ts b/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.ts index 8e7a9f912a4..e83e71fb928 100644 --- a/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.ts @@ -229,7 +229,10 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh @Output() public validationFailed = new EventEmitter(); + + private readonly SCROLL_THRESHOLD = 50; private _inputFormat: string; + private _scrollAccumulator = 0; private _displayFormat: string; private _oldValue: Date; private _dateValue: Date; @@ -314,10 +317,14 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh } event.preventDefault(); event.stopPropagation(); - if (event.deltaY > 0) { - this.decrement(); - } else { - this.increment(); + this._scrollAccumulator += event.deltaY; + if (Math.abs(this._scrollAccumulator) > this.SCROLL_THRESHOLD) { + if (this._scrollAccumulator < 0) { + this.decrement(); + } else { + this.increment(); + } + this._scrollAccumulator = 0; } } diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.directives.ts b/projects/igniteui-angular/src/lib/time-picker/time-picker.directives.ts index eda74acff65..3ce96e93073 100644 --- a/projects/igniteui-angular/src/lib/time-picker/time-picker.directives.ts +++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.directives.ts @@ -34,7 +34,7 @@ export class IgxItemListDirective implements OnInit, OnDestroy { public isActive: boolean; - private readonly SCROLL_THRESHOLD = 15; + private readonly SCROLL_THRESHOLD = 50; private readonly PAN_THRESHOLD = 10; /** From e373a13a2deffa7b09a9f6b8d13c23b9a6cddc68 Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Tue, 8 Jul 2025 16:53:23 +0300 Subject: [PATCH 3/3] test(date-picker): changing test to accommodate wheel accumulator --- .../date-time-editor/date-time-editor.directive.spec.ts | 8 +++++++- .../date-time-editor/date-time-editor.directive.ts | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.spec.ts index 3ea35f42e65..2046959e78d 100644 --- a/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.spec.ts @@ -1123,7 +1123,13 @@ describe('IgxDateTimeEditor', () => { inputElement.triggerEventHandler('focus', {}); fixture.detectChanges(); dateTimeEditorDirective.nativeElement.setSelectionRange(1, 1); - inputElement.triggerEventHandler('wheel', new WheelEvent('wheel', { deltaY: 1 })); + // typical wheel scrolls are 120px and the date-editor employs touchpad-friendly implementation + // that accumulates to 50 before incrementing/decrementing + // we'll test the behavior by doing two scrolls with the first one not expected to trigger a change + inputElement.triggerEventHandler('wheel', new WheelEvent('wheel', { deltaY: 20 })); + fixture.detectChanges(); + expect(dateTimeEditorDirective.value.getDate()).toEqual(today.getDate()); + inputElement.triggerEventHandler('wheel', new WheelEvent('wheel', { deltaY: 40 })); fixture.detectChanges(); expect(dateTimeEditorDirective.value.getDate()).toEqual(today.getDate() - 1); })); diff --git a/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.ts b/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.ts index e83e71fb928..8f9c8a06e1d 100644 --- a/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.directive.ts @@ -319,7 +319,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh event.stopPropagation(); this._scrollAccumulator += event.deltaY; if (Math.abs(this._scrollAccumulator) > this.SCROLL_THRESHOLD) { - if (this._scrollAccumulator < 0) { + if (this._scrollAccumulator > 0) { this.decrement(); } else { this.increment();