129 lines
4.0 KiB
TypeScript
129 lines
4.0 KiB
TypeScript
import {
|
|
AfterViewInit,
|
|
ChangeDetectorRef,
|
|
Component,
|
|
ElementRef,
|
|
EventEmitter,
|
|
HostListener,
|
|
Input,
|
|
OnInit,
|
|
Output,
|
|
ViewChild
|
|
} from '@angular/core';
|
|
import {AbstractControl} from '@angular/forms';
|
|
import {InputComponent} from "../input/input.component";
|
|
import {ClickEvent} from "../../utils/click/click-outside-or-esc.directive";
|
|
|
|
@Component({
|
|
selector: '[search-input]',
|
|
template: `
|
|
<div *ngIf="initialized" class="uk-flex uk-flex-right uk-width-1-1">
|
|
<div #searchInput click-outside-or-esc (clickOutside)="click($event)" class="search-input" [class.focused]="input.focused"
|
|
[class.collapsed]="hidden" [ngClass]="searchInputClass">
|
|
<div class="uk-flex uk-flex-middle">
|
|
<div class="uk-width-expand">
|
|
<div #input [class.uk-hidden]="hidden" input [formInput]="searchControl" [inputClass]="'search'+(iconPosition === 'left'?' icon-left':'')" [disabledIcon]="null"
|
|
[placeholder]="{label: placeholder, static: true}" [value]="value" (valueChange)="valueChange.emit($event)"
|
|
[disabled]="disabled" [showOptionsOnEmpty]="false" [type]="(options.length > 0?'autocomplete_soft':'text')" [options]="options"></div>
|
|
</div>
|
|
<div [class.uk-hidden]="(!searchControl?.value && !value) || disabled" class="uk-width-auto">
|
|
<button class="uk-close uk-icon" (click)="reset()">
|
|
<icon name="close" [flex]="true"></icon>
|
|
</button>
|
|
</div>
|
|
<div class="uk-width-auto" [class.uk-flex-first]="iconPosition === 'left'">
|
|
<div class="search-icon" [class.disabled]="disabled" (click)="search($event)">
|
|
<icon name="search" [flex]="true" [ratio]="ratio"></icon>
|
|
</div>
|
|
</div>
|
|
<div class="uk-width-auto filters-toggle">
|
|
<ng-content select="[filters-toggle]"></ng-content>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`
|
|
})
|
|
export class SearchInputComponent implements OnInit, AfterViewInit {
|
|
@Input() disabled: boolean = false;
|
|
@Input() searchInputClass: string = 'inner';
|
|
@Input() iconPosition: 'left' | 'right' = 'right';
|
|
@Input() searchControl: AbstractControl;
|
|
@Input() value: string;
|
|
@Output() valueChange = new EventEmitter<string>();
|
|
@Input() options: string[] = [];
|
|
@Input() placeholder: string;
|
|
@Input() expandable: boolean = false;
|
|
@Output() searchEmitter: EventEmitter<void> = new EventEmitter<void>();
|
|
@ViewChild('searchInput') searchInput: ElementRef;
|
|
@ViewChild('input') input: InputComponent;
|
|
public expanded: boolean = true;
|
|
public initialized: boolean = false;
|
|
public ratio: number = 1;
|
|
|
|
constructor(private cdr: ChangeDetectorRef) {
|
|
}
|
|
|
|
@HostListener('window:keydown.enter', ['$event'])
|
|
enter(event: KeyboardEvent) {
|
|
if(this.input.focused && !this.input.opened) {
|
|
event.preventDefault();
|
|
this.search(event);
|
|
} else {
|
|
this.input.enter(event);
|
|
event.stopPropagation();
|
|
this.search(event);
|
|
}
|
|
}
|
|
|
|
click(event: ClickEvent) {
|
|
if(this.expandable && !this.disabled) {
|
|
this.expand(!event.clicked);
|
|
}
|
|
}
|
|
|
|
ngOnInit() {
|
|
this.expanded = !this.expandable;
|
|
this.initialized = true;
|
|
}
|
|
|
|
ngAfterViewInit() {
|
|
if(typeof document !== 'undefined') {
|
|
this.ratio = Number.parseFloat(getComputedStyle(this.searchInput.nativeElement).getPropertyValue('--search-input-icon-ratio'));
|
|
}
|
|
}
|
|
|
|
expand(value: boolean) {
|
|
this.expanded = value;
|
|
this.cdr.detectChanges();
|
|
if(this.expanded) {
|
|
this.input.focus(true);
|
|
}
|
|
}
|
|
|
|
public search(event) {
|
|
if(!this.disabled) {
|
|
this.searchEmitter.emit();
|
|
if(this.expandable) {
|
|
this.expand(!this.expanded);
|
|
}
|
|
event.stopPropagation();
|
|
}
|
|
}
|
|
|
|
public reset() {
|
|
if(this.searchControl){
|
|
this.searchControl.setValue('');
|
|
} else {
|
|
this.valueChange.emit('');
|
|
}
|
|
setTimeout(() => {
|
|
this.input.focus(true);
|
|
}, 100)
|
|
}
|
|
|
|
get hidden(): boolean {
|
|
return !this.expanded && (!this.searchControl?.value && !this.value);
|
|
}
|
|
}
|