import { LiveAnnouncer } from '@angular/cdk/a11y' ; import { Component , ContentChild , EventEmitter , Input , OnDestroy , Output , TemplateRef } from '@angular/core' ; import { Subject } from 'rxjs' ; import { filter } from 'rxjs/operators' ; import { ReorderEvent } from '../../directives/reorderable/index' ; import { FacetClearButtonDirective } from './facet-clear-button/facet-clear-button.directive' ; import { FacetDeselect , FacetEvent } from './facet-events' ; import { FacetService } from './facet.service' ; import { Facet } from './models/facet' ; @ Component ( { selector : 'ux-facet-container' , templateUrl : './facet-container.component.html' , providers : [ FacetService ] , preserveWhitespaces : false } ) export class FacetContainerComponent implements OnDestroy { /** Defines the text displayed at the top of the Facet Container. */ @ Input ( ) header : string = 'Selected' ; /** Defines the text to display in the tooltip when hovering over the clear all button. */ @ Input ( ) clearTooltip : string = 'Clear All' ; /** Defines the text to display when there are no selected facets. */ @ Input ( ) emptyText : string = 'No Items' ; /** Determines if the facets can be reordered. */ @ Input ( ) facetsReorderable : boolean = false ; /** Allows a predefined set of Facets to be displayed. */ @ Input ( ) set facets ( facets ) { this . facetService . facets$ . next ( facets ) ; } get facets ( ) : Facet [ ] { return this . facetService . facets$ . value ; } /** Defines the aria-label for the clear all button. */ @ Input ( ) clearAriaLabel : string = 'Clear All' ; /** Defines the aria-label for the deselect facet button.. */ @ Input ( ) deselectFacetAriaLabel : string = 'Deselect Facet' ; /** If using two-way binding this array will update when the selected facets change. */ @ Output ( ) facetsChange : EventEmitter < Facet [ ] > = new EventEmitter < Facet [ ] > ( ) ; /**
     * This will be triggered when a facet is selected, deselected or all facets are deselected.
     * The event will be an instance of either `FacetSelect`, `FacetDeselect` or `FacetDeselectAll` and
     * will contain the facet being selected or deselected in a `facet` property
     * (deselect all will not contain affected facets). */ @ Output ( ) events : EventEmitter < FacetEvent > = new EventEmitter < FacetEvent > ( ) ; /** Allow a custom clear button */ @ ContentChild ( FacetClearButtonDirective , { read : TemplateRef , static : false } ) clearButton : TemplateRef < FacetClearButtonDirective > ; private _onDestroy = new Subject < void > ( ) ; constructor ( private _announcer , public facetService ) { facetService . facets$ . subscribe ( facets => this . facetsChange . next ( facets ) ) ; facetService . events$ . subscribe ( event => this . triggerEvent ( event ) ) ; facetService . events$ . pipe ( filter < FacetDeselect > ( event => event instanceof FacetDeselect ) ) . subscribe ( event => this . _announcer . announce ( `Option ${ event . facet . title } deselected.` , 'assertive' ) ) ; } ngOnDestroy ( ) { this . _onDestroy . next ( ) ; this . _onDestroy . complete ( ) ; } selectFacet ( facet ) { this . facetService . select ( facet ) ; } deselectFacet ( facet , tag ? ) { const idx = this . facets . findIndex ( selectedFacet => facet === selectedFacet ) ; if ( idx === - 1 ) { return ; } this . facetService . deselect ( facet ) ; this . _announcer . announce ( `Option ${ facet . title } deselected.` , 'assertive' ) ; if ( tag ) { const sibling = tag . previousElementSibling || tag . nextElementSibling ; if ( sibling ) { ( sibling as HTMLElement ) . focus ( ) ; } } } deselectAllFacets ( ) { this . facetService . deselectAll ( ) ; this . _announcer . announce ( 'All options deselected.' , 'assertive' ) ; } trackBy ( _index , facet ) { return facet . id || facet . title ; } shiftRight ( facet , element ) { if ( this . facetsReorderable === false ) { return ; } this . shiftFacet ( facet , 1 ) ; requestAnimationFrame ( ( ) => element . focus ( ) ) ; this . _announcer . announce ( `Option ${ facet . title } moved down.` ) ; } shiftLeft ( facet , element ) { if ( this . facetsReorderable === false ) { return ; } this . shiftFacet ( facet , - 1 ) ; requestAnimationFrame ( ( ) => element . focus ( ) ) ; this . _announcer . announce ( `Option ${ facet . title } moved up.` ) ; } private shiftFacet ( facet , distance ) { const index = this . facets . indexOf ( facet ) ; const target = index + distance ; if ( target < 0 || target === this . facets . length ) { return ; } this . facets . splice ( index , 1 ) ; this . facets . splice ( target , 0 , facet ) ; } private triggerEvent ( event ) { this . events . next ( event ) ; } } export interface FacetReorderEvent extends ReorderEvent { index : number ; }