Skip to content

Commit

Permalink
feat(core): add iOS support to TuiDropdownContextDirective
Browse files Browse the repository at this point in the history
  • Loading branch information
MillerSvt committed Feb 12, 2024
1 parent b0841d3 commit f2efb78
Showing 1 changed file with 57 additions and 1 deletion.
58 changes: 57 additions & 1 deletion projects/core/directives/dropdown/dropdown-context.directive.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {Directive, HostListener, Inject} from '@angular/core';
import {Directive, HostBinding, HostListener, Inject} from '@angular/core';
import {
EMPTY_CLIENT_RECT,
TUI_IS_IOS,
TUI_TOUCH_SUPPORTED,
TuiActiveZoneDirective,
tuiPointToClientRect,
} from '@taiga-ui/cdk';
Expand All @@ -17,6 +19,9 @@ function activeZoneFilter(this: TuiDropdownContextDirective, target: Element): b
return !this.activeZone.contains(target);
}

const TAP_DELAY = 700;
const MOVE_THRESHOLD = 15;

@Directive({
selector: '[tuiDropdown][tuiDropdownContext]',
providers: [
Expand All @@ -29,16 +34,28 @@ export class TuiDropdownContextDirective extends TuiDriver implements TuiRectAcc
private readonly stream$ = new Subject<boolean>();

private currentRect = EMPTY_CLIENT_RECT;
private longTapTimeout: any = NaN;

readonly type = 'dropdown';

constructor(
@Inject(TuiActiveZoneDirective)
readonly activeZone: TuiActiveZoneDirective,
@Inject(TUI_IS_IOS)
readonly isIOS: boolean,
@Inject(TUI_TOUCH_SUPPORTED)
readonly isTouch: boolean,
) {
super(subscriber => this.stream$.subscribe(subscriber));
}

@HostBinding('style.user-select')
@HostBinding('style.-webkit-touch-callout')
@HostBinding('style.-webkit-user-select')
get userSelect(): string | null {
return this.isTouch ? 'none' : null;
}

@HostListener('contextmenu.prevent.stop', ['$event.clientX', '$event.clientY'])
onContextMenu(x: number, y: number): void {
this.currentRect = tuiPointToClientRect(x, y);
Expand All @@ -51,6 +68,45 @@ export class TuiDropdownContextDirective extends TuiDriver implements TuiRectAcc
@HostListener('document:keydown.esc', ['$event.currentTarget'])
closeDropdown(): void {
this.stream$.next(false);
this.currentRect = EMPTY_CLIENT_RECT;
}

@HostListener('touchmove.silent.passive', [
'$event.touches[0].clientX',
'$event.touches[0].clientY',
])
onTouchMove(x: number, y: number): void {
if (
this.isIOS &&
this.isTouch &&
this.currentRect !== EMPTY_CLIENT_RECT &&
Math.hypot(x - this.currentRect.x, y - this.currentRect.y) > MOVE_THRESHOLD
) {
this.onTouchEnd();
}
}

@HostListener('touchstart.silent.passive', [
'$event.touches[0].clientX',
'$event.touches[0].clientY',
])
onTouchStart(x: number, y: number): void {
if (!this.isIOS || !this.isTouch || this.currentRect !== EMPTY_CLIENT_RECT) {
return;
}

this.currentRect = tuiPointToClientRect(x, y);
this.longTapTimeout = setTimeout(() => {
this.stream$.next(true);
}, TAP_DELAY);
}

@HostListener('touchend.silent.passive')
@HostListener('touchcancel.silent.passive')
onTouchEnd(): void {
if (this.isIOS && this.isTouch) {
clearTimeout(this.longTapTimeout);
}
}

getClientRect(): ClientRect {
Expand Down

0 comments on commit f2efb78

Please sign in to comment.