Skip to content

Commit

Permalink
chore: new version of fix
Browse files Browse the repository at this point in the history
  • Loading branch information
nsbarsukov committed Apr 19, 2022
1 parent 21c0ed5 commit 44a95aa
Showing 1 changed file with 55 additions and 32 deletions.
87 changes: 55 additions & 32 deletions projects/kit/components/slider/slider-readonly.directive.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,82 @@
import {
ChangeDetectorRef,
Directive,
HostListener,
Inject,
Input,
Optional,
Self,
} from '@angular/core';
import {NgControl} from '@angular/forms';
import {DOCUMENT} from '@angular/common';
import {Directive, ElementRef, HostListener, Inject, Input} from '@angular/core';
import {
tuiCoerceBooleanProperty,
tuiDefaultProp,
TuiDestroyService,
watch,
typedFromEvent,
} from '@taiga-ui/cdk';
import {Observable} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
import {combineLatest, merge, Observable} from 'rxjs';
import {filter, mapTo, takeUntil, tap} from 'rxjs/operators';

import {TuiSliderComponent} from './slider.component';
const SLIDER_INTERACTION_KEYS = new Set([
'ArrowLeft',
'ArrowRight',
'ArrowUp',
'ArrowDown',
'Home',
'End',
'PageUp',
'PageDown',
]);

/**
* Native <input type='range' readonly> doesn't work.
* This directive imitates this native behaviour.
*/
// @dynamic
@Directive({
selector: 'input[tuiSlider][readonly]',
providers: [TuiDestroyService],
})
export class TuiSliderReadonlyDirective {
private lastValue = this.slider.value;

@Input()
@tuiDefaultProp()
readonly: '' | boolean = true;

constructor(
@Optional()
@Self()
@Inject(NgControl)
readonly ngControl: NgControl | null,
@Inject(ChangeDetectorRef) changeDetectorRef: ChangeDetectorRef,
@Inject(TuiDestroyService) destroy$: Observable<unknown>,
@Inject(TuiSliderComponent) private readonly slider: TuiSliderComponent,
@Inject(ElementRef) elementRef: ElementRef<HTMLInputElement>,
@Inject(DOCUMENT) documentRef: Document,
@Inject(TuiDestroyService)
destroy$: Observable<unknown>,
) {
ngControl?.valueChanges
?.pipe(watch(changeDetectorRef), takeUntil(destroy$))
.subscribe(() => {
this.lastValue = this.slider.value;
});
const touchStart$ = typedFromEvent(elementRef.nativeElement, 'touchstart', {
passive: false,
});
const touchMove$ = typedFromEvent(documentRef, 'touchmove', {
passive: false,
});
const touchEnd$ = typedFromEvent(documentRef, 'touchend', {
passive: true,
});

const shouldPreventMove$ = merge(
touchStart$.pipe(
tap(e => this.preventEvent(e)),
mapTo(true),
),
touchEnd$.pipe(mapTo(false)),
);

combineLatest([touchMove$, shouldPreventMove$])
.pipe(
filter(([_, shouldPreventMove]) => shouldPreventMove),
takeUntil(destroy$),
)
.subscribe(([moveEvent]) => this.preventEvent(moveEvent));
}

@HostListener('mousedown', ['$event'])
preventEvent(event: Event) {
if (tuiCoerceBooleanProperty(this.readonly) && event.cancelable) {
event.preventDefault();
}
}

@HostListener('input')
onInput() {
if (tuiCoerceBooleanProperty(this.readonly)) {
this.slider.value = this.lastValue;
@HostListener('keydown', ['$event'])
preventKeyboardInteraction(event: KeyboardEvent) {
if (SLIDER_INTERACTION_KEYS.has(event.key)) {
this.preventEvent(event);
}
}
}

0 comments on commit 44a95aa

Please sign in to comment.