65 lines
2.5 KiB
TypeScript
65 lines
2.5 KiB
TypeScript
import { ChangeDetectionStrategy, Component, HostListener, Input, ViewChild } from '@angular/core';
|
|
import { debounceTime, distinctUntilChanged, map, tap } from 'rxjs/operators';
|
|
import { BehaviorSubject } from 'rxjs';
|
|
import { SpotlightSearchAction } from '@components/spotlight-search/spotlight-search-action';
|
|
import { MatMenuTrigger } from '@angular/material/menu';
|
|
|
|
@Component({
|
|
selector: 'redaction-spotlight-search [actions]',
|
|
templateUrl: './spotlight-search.component.html',
|
|
styleUrls: ['./spotlight-search.component.scss'],
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
})
|
|
export class SpotlightSearchComponent {
|
|
@Input() actions: readonly SpotlightSearchAction[];
|
|
@Input() placeholder?: string;
|
|
readonly valueChanges$ = new BehaviorSubject<string>('');
|
|
@ViewChild(MatMenuTrigger) private readonly _menuTrigger!: MatMenuTrigger;
|
|
readonly showActions$ = this.valueChanges$.pipe(
|
|
debounceTime(300),
|
|
map(value => value !== ''),
|
|
tap(show => (show ? this._menuTrigger.openMenu() : this._menuTrigger.closeMenu())),
|
|
);
|
|
private readonly _currentActionIdx$ = new BehaviorSubject(0);
|
|
readonly currentActionIdx$ = this._currentActionIdx$.asObservable().pipe(distinctUntilChanged());
|
|
|
|
get shownActions(): readonly SpotlightSearchAction[] {
|
|
return this.actions.filter(a => !a.hide?.());
|
|
}
|
|
|
|
private get _currentActionIdx(): number {
|
|
return this._currentActionIdx$.getValue();
|
|
}
|
|
|
|
openMenuIfValue(): void {
|
|
const value = this.valueChanges$.getValue();
|
|
if (value && value !== '') {
|
|
this._menuTrigger.openMenu();
|
|
}
|
|
}
|
|
|
|
executeCurrentAction(): void {
|
|
this.shownActions[this._currentActionIdx].action(this.valueChanges$.getValue());
|
|
}
|
|
|
|
@HostListener('keydown.arrowDown', ['$event'])
|
|
@HostListener('keydown.arrowUp', ['$event'])
|
|
handleKeyDown(event: KeyboardEvent): void {
|
|
event.preventDefault();
|
|
}
|
|
|
|
@HostListener('keyup.arrowDown', ['$event'])
|
|
handleKeyUpArrowDown(event: KeyboardEvent): void {
|
|
this.handleKeyDown(event);
|
|
const index = this._currentActionIdx + 1;
|
|
this._currentActionIdx$.next(index >= this.shownActions.length ? 0 : index);
|
|
}
|
|
|
|
@HostListener('keyup.arrowUp', ['$event'])
|
|
handleKeyUpArrowUp(event: KeyboardEvent): void {
|
|
this.handleKeyDown(event);
|
|
const index = this._currentActionIdx - 1;
|
|
this._currentActionIdx$.next(index < 0 ? this.shownActions.length - 1 : index);
|
|
}
|
|
}
|