import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Inject, Input, OnChanges, OnDestroy, Output, Renderer2, ViewChild, } from '@angular/core'; import { DropdownBoxOptionsInterface, } from './../../models/index'; import { openVerticallyFade, } from './../../helpers/animations/index'; @Component({ animations: [ openVerticallyFade(), ], changeDetection: ChangeDetectionStrategy.OnPush, selector: 'dropdown-box-v2-component', styleUrls: [ './dropdown-box-v2.component.scss', ], templateUrl: 'dropdown-box-v2.component.template.pug', }) export class DropdownBoxV2Component implements OnChanges, OnDestroy { @ViewChild('dropDownRoot') public dropDownRoot: ElementRef; public isOpen = false; public selectedOption: DropdownBoxOptionsInterface; public selectorClicked = false; @Input() public dropdownLabel: string; @Input() public optionHeader: string; @Input() public placeholder: string; @Input() public value: string; @Input() public options: DropdownBoxOptionsInterface[]; @Input() public useUnitSwitcher = false; @Input() public units = ['Cm', 'Inch']; @Input() public selectedUnit: string = this.units[1]; @Output() public onChange = new EventEmitter(); public get applyMinHeight() { return Boolean(this.options.length > 4); } public rendererWindowUnlisten: () => void; constructor( @Inject('window') private _window: Window, private _renderer: Renderer2, private _changeDetectorRef: ChangeDetectorRef, ) {} public onClickOutside(event) { if ( !this.dropDownRoot.nativeElement.contains(event.target) ) { this.isOpen = false; } if (!this.isOpen) { this.rendererWindowUnlisten(); this.rendererWindowUnlisten = undefined; } this._changeDetectorRef.markForCheck(); } public ngOnChanges() { this.selectedOption = this.options.find( (option) => option.value === this.value, ); } public ngOnDestroy() { if (this.rendererWindowUnlisten) { this.rendererWindowUnlisten(); } } public onClick( selectedValue: string, selectedLabel: string, selectedLabelUnit0: string = null, selectedLabelUnit1: string = null, ) { if (this.selectorClicked) { this.selectorClicked = false; return; } if (this.rendererWindowUnlisten) { this.rendererWindowUnlisten(); this.rendererWindowUnlisten = undefined; } this.isOpen = !this.isOpen; this.rendererWindowUnlisten = this._renderer.listen( this._window, 'click', this.onClickOutside.bind(this), ); if ( (selectedLabel && !this.selectedOption) || (selectedLabel && (selectedLabel !== this.getOptionLabel(this.selectedOption))) ) { this._setValue(selectedValue, selectedLabel, selectedLabelUnit0, selectedLabelUnit1); } } public onSwitcherClick(unitSelected: any) { this.selectorClicked = true; this.selectedUnit = unitSelected; } public getOptionLabel(option: DropdownBoxOptionsInterface) { if (!this.useUnitSwitcher) { return option.label; } else if (this.selectedUnit === this.units[0]) { return option.labelUnit0; } else if (this.selectedUnit === this.units[1]) { return option.labelUnit1; } } private _setValue( newValue: string, newLabel: string, selectedLabelUnit0: string, selectedLabelUnit1: string, ) { this.selectedOption = { label: newLabel, labelUnit0: this.useUnitSwitcher && selectedLabelUnit0, labelUnit1: this.useUnitSwitcher && selectedLabelUnit1, value: newValue, } as DropdownBoxOptionsInterface; this.onChange.emit(newValue); if (this.rendererWindowUnlisten) { this.rendererWindowUnlisten(); this.rendererWindowUnlisten = undefined; } } }