import { Component , ElementRef , EventEmitter , Input , Output , ViewChild , } from '@angular/core' ; import { FormsModule , ReactiveFormsModule , FormGroup , FormBuilder , Validators } from '@angular/forms' ; import { Router } from '@angular/router' ; import { Observable } from 'rxjs/Observable' ; import { Subscription } from 'rxjs/Subscription' ; import { BehaviorSubject } from 'rxjs/BehaviorSubject' ; import { ClientService } from '../../services/client' ; import { content } from '../../../../config/code-gov-config.json' ; const banner = content . home . banner ; const description = window . innerWidth > 500 ? banner . search_description_text : banner . search_description_text_mobile ; /**
 * Class representing a search component for repositories.
 */ @ Component ( { selector : 'search-input' , template : require ( './search-input.template.html' ) , styles : [ require ( './search-input.style.scss' ) ] , host : { '(window:click)' : 'onBlurHandler($event)' } , } ) export class SearchInputComponent { @ Input ( ) queryValue = '' ; @ Output ( ) queryValueChange = new EventEmitter ( ) ; @ Input ( ) autofocus = false ; @ Input ( ) name : string ; @ Input ( ) ngModel : any ; @ Input ( ) description : string = description ; @ Input ( ) placeholder : string = content . home . banner . search_placeholder_text ; @ ViewChild ( 'query' ) queryElement : ElementRef ; @ ViewChild ( 'searchInput' ) searchInputElement : ElementRef ; public autocompleteVisible : boolean = false ; public queryInputValue : string = '' ; termResultsObservable : Observable < Array < any > > ; private termResultsReturnedSource = new BehaviorSubject < Array < any > > ( [ ] ) ; constructor param { ClientService } clientService constructor ( private clientService ) { this . termResultsObservable = this . termResultsReturnedSource . asObservable ( ) ; } return { boolean } hasQuery ( ) { return this . queryInputValue . length > 0 ; } /**
     * On initialization of the ReposSearchComponent
     */ ngOnInit ( ) { this . queryInputValue = this . queryValue ; } /**
     * After everything has been added to the DOM
     */ ngAfterViewInit ( ) { if ( this . autofocus ) { this . queryElement . nativeElement . focus ( ) ; } } param { Event } event return { void } onKey ( event ) { this . queryInputValue = event . target . value ; if ( this . queryInputValue && this . queryInputValue . length >= 1 ) { this . clientService . suggest ( this . queryInputValue , 5 ) . subscribe ( results => { this . termResultsReturnedSource . next ( results ) ; } ) ; } else { this . termResultsReturnedSource . next ( [ ] ) ; } if ( event . code === 'Escape' || event . code === 'Enter' ) { event . target . blur ( ) ; this . hideAutocomplete ( ) ; } } /**
     * Show the autocomplete dropdown.
     */ showAutocomplete ( ) { this . autocompleteVisible = true ; } /**
     * Hide the autocomplete dropdown.
     */ hideAutocomplete ( ) { this . autocompleteVisible = false ; } /**
     * Triggered whenever a suggestion is selected from the autocomplete.
     */ handleSuggestionSelected ( suggestion ) { this . hideAutocomplete ( ) ; } param { Event } event return { void } onBlurHandler ( event ) { const inputDoesNotHaveFocus = window . document . activeElement !== this . queryElement . nativeElement ; const clickIsOutsideForm = ! this . searchInputElement . nativeElement . contains ( event . target ) ; if ( inputDoesNotHaveFocus && clickIsOutsideForm ) { this . hideAutocomplete ( ) ; } } focus ( ) { this . queryElement . nativeElement . focus ( ) ; } blur ( ) { this . queryElement . nativeElement . blur ( ) ; } change ( newValue ) { this . queryValue = newValue ; this . queryValueChange . emit ( newValue ) ; } private propagateChange = ( _ ) => { } ; }