import { Guid } from './../../shared/Utilities/Guid' ; import { KeyCodes } from './../../shared/models/constants' ; import { PortalResources } from './../../shared/models/portal-resources' ; import { Component , OnChanges , SimpleChanges , Input , Output , ViewChild , ElementRef } from '@angular/core' ; import { Subject } from 'rxjs/Subject' ; import { TranslateService } from '@ngx-translate/core' ; type Role = undefined | 'switch' | 'button' ; type LabelFormt = undefined | 'name' | 'stateName' | 'nameAndStateName' | 'mergedStateNames' ; @ Component ( { selector : 'slide-toggle' , templateUrl : './slide-toggle.component.html' , styleUrls : [ './slide-toggle.component.scss' ] , } ) export class SlideToggleComponent implements OnChanges { @ Output ( ) change = new Subject < boolean > ( ) ; @ Input ( ) disabled : boolean = false ; @ Input ( ) on : boolean = false ; @ Input ( ) isCommand : boolean = false ; @ Input ( ) name : string ; @ Input ( ) stateNames : { on : string ; off : string ; } ; @ Input ( ) displayLabelFormat : LabelFormt ; @ Input ( ) ariaLabelFormat : LabelFormt ; public role : Role ; public ariaLabel : string ; public ariaChecked : boolean = null ; public ariaPressed : boolean = null ; public displayLabel : string ; @ Input ( ) id : string ; private _initialized : boolean = false ; @ ViewChild ( 'toggleContainer' ) toggleContainer : ElementRef ; constructor ( private _translateService ) { this . id = Guid . newGuid ( ) ; } ngOnChanges ( changes ) { this . role = this . role || ( this . isCommand ? 'button' : 'switch' ) ; this . displayLabelFormat = this . displayLabelFormat || 'stateName' ; this . ariaLabelFormat = this . ariaLabelFormat || 'name' ; if ( ! this . _initialized || ! ! changes [ 'on' ] ) { this . _updateLabelAndAriaAttributes ( ) ; } this . _initialized = true ; } private _updateLabelAndAriaAttributes ( ) { const stateNames = this . _getStateNames ( ) ; const state = this . on ? 1 : 0 ; switch ( this . displayLabelFormat ) { case 'name' : this . displayLabel = this . name || stateNames [ state ] ; break ; case 'stateName' : this . displayLabel = stateNames [ state ] ; break ; case 'nameAndStateName' : this . displayLabel = ( this . name ? this . name + ': ' : '' ) + stateNames [ state ] ; break ; case 'mergedStateNames' : this . displayLabel = ! stateNames . isFallback ? stateNames . combined : this . name || stateNames [ state ] ; break ; default : break ; } let ariaLabel = '' ; let ariaChecked = null ; let ariaPressed = null ; let addSuffix = false ; if ( this . role === 'button' ) { ariaPressed = null ; switch ( this . ariaLabelFormat ) { case 'name' : if ( this . name ) { addSuffix = true ; ariaLabel = this . name ; ariaPressed = this . on ; } else { ariaLabel = stateNames [ state ] ; } break ; case 'stateName' : ariaLabel = stateNames [ state ] ; break ; case 'nameAndStateName' : ariaLabel = ( this . name ? this . name + ': ' : '' ) + stateNames [ state ] ; break ; case 'mergedStateNames' : if ( ! stateNames . isFallback ) { addSuffix = true ; ariaLabel = stateNames . combined ; ariaPressed = this . on ; } else if ( this . name ) { addSuffix = true ; ariaLabel = this . name ; ariaPressed = this . on ; } else { ariaLabel = stateNames [ state ] ; } break ; default : break ; } } else if ( this . role === 'switch' ) { ariaChecked = this . on ; switch ( this . ariaLabelFormat ) { case 'name' : addSuffix = true ; ariaLabel = this . name || stateNames . combined ; break ; case 'mergedStateNames' : addSuffix = true ; ariaLabel = stateNames . combined ; break ; default : break ; } } this . ariaLabel = ariaLabel + ( addSuffix ? ' toggle' : '' ) ; this . ariaPressed = ariaPressed ; this . ariaChecked = ariaChecked ; } private _getStateNames ( ) { let stateNames = { isFallback : ! this . stateNames || ! this . stateNames . on || ! this . stateNames . off , combined : '' , } ; stateNames [ 0 ] = stateNames . isFallback ? this . _translateService . instant ( PortalResources . disabled ) : this . stateNames . off ; stateNames [ 1 ] = stateNames . isFallback ? this . _translateService . instant ( PortalResources . enabled ) : this . stateNames . on ; stateNames . combined = stateNames [ 0 ] + '/' + stateNames [ 1 ] ; return stateNames ; } onClick ( event ) { this . _toggle ( ) ; } onKeyPress ( event ) { if ( event . keyCode === KeyCodes . space ) { this . _toggle ( ) ; event . preventDefault ( ) ; } } private _toggle ( ) { if ( ! this . disabled ) { this . on = ! this . on ; this . _updateLabelAndAriaAttributes ( ) ; this . change . next ( this . on ) ; } } }