import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
ElementRef,
EventEmitter,
HostListener,
Input,
NgZone,
OnDestroy,
Output,
ViewChild,
} from '@angular/core';
import { filter, take, takeUntil } from 'rxjs/operators';
import { merge, Subject } from 'rxjs';
import { NbSelectedTimeModel } from './model';
import { NbPlatform } from '../cdk/platform/platform-service';
@Component({
selector: 'nb-timepicker-cell',
template: `
{{ value }}
`,
styleUrls: ['./timepicker-cell.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NbTimePickerCellComponent implements AfterViewInit, OnDestroy {
protected selectedChange$ = new Subject();
protected unselected$ = this.selectedChange$.pipe(filter((selected) => !selected));
protected destroy$ = new Subject();
_selected: boolean;
@Input() set selected(selected: boolean) {
if (selected) {
this._selected = selected;
this.scrollToElement();
}
this.selectedChange$.next(selected);
};
get selected(): boolean {
return this._selected;
}
@Input() value: string;
@Output() select: EventEmitter = new EventEmitter();
@ViewChild('valueContainer') valueContainerElement: ElementRef;
constructor(protected ngZone: NgZone,
protected platformService: NbPlatform) {
}
@HostListener('click')
onClick() {
this.select.emit({ value: this.value });
}
ngAfterViewInit(): void {
if (this.selected) {
// Since we render timepicker in the overlay, at the moment this hook called,
// timepicker could be not fully rendered and placed. Because of it, we're waiting for Angular
// to finish change detection run and only then scroll to the selected cell.
this.ngZone.onStable
.pipe(
take(1),
takeUntil(merge(this.unselected$, this.destroy$)))
.subscribe(() => this.scrollToElement());
}
}
protected scrollToElement() {
if (this.valueContainerElement && this.platformService.isBrowser) {
this.ngZone.runOutsideAngular(() =>
this.valueContainerElement.nativeElement.scrollIntoView({block: 'center'}));
}
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}