import { getFlexiblePositions , ThyPlacement } from 'ngx-tethys/core' ; import { TinyDate } from 'ngx-tethys/util' ; import { CdkConnectedOverlay , CdkOverlayOrigin , ConnectedOverlayPositionChange } from '@angular/cdk/overlay' ; import { AfterViewInit , ChangeDetectionStrategy , ChangeDetectorRef , Component , ElementRef , EventEmitter , Input , Output , ViewChild } from '@angular/core' ; import { DateHelperService } from './date-helper.service' ; import { CompatibleValue , RangePartType } from './standard-types' ; @ Component ( { selector : 'thy-picker' , exportAs : 'thyPicker' , templateUrl : './picker.component.html' , changeDetection : ChangeDetectionStrategy . OnPush } ) export class ThyPickerComponent implements AfterViewInit { @ Input ( ) isRange = false ; @ Input ( ) open : boolean | undefined = undefined ; @ Input ( ) disabled : boolean ; @ Input ( ) placeholder : string | string [ ] ; @ Input ( ) readonly : boolean ; @ Input ( ) allowClear : boolean ; @ Input ( ) autoFocus : boolean ; @ Input ( ) className : string ; @ Input ( ) format : string ; @ Input ( ) size : 'sm' | 'xs' | 'lg' | 'md' | 'default' ; @ Input ( ) value : TinyDate | TinyDate [ ] | null ; @ Input ( ) suffixIcon : string ; @ Input ( ) placement : ThyPlacement = 'bottomLeft' ; @ Output ( ) readonly valueChange = new EventEmitter < TinyDate | TinyDate [ ] | null > ( ) ; @ Output ( ) readonly openChange = new EventEmitter < boolean > ( ) ; @ ViewChild ( 'origin' , { static : true } ) origin : CdkOverlayOrigin ; @ ViewChild ( CdkConnectedOverlay , { static : true } ) cdkConnectedOverlay : CdkConnectedOverlay ; @ ViewChild ( 'pickerInput' , { static : true } ) pickerInput : ElementRef ; prefixCls = 'thy-calendar' ; animationOpenState = false ; overlayOpen = false ; overlayPositions = getFlexiblePositions ( this . placement , 4 ) ; get realOpenState ( ) : boolean { return this . isOpenHandledByUser ( ) ? ! ! this . open : this . overlayOpen ; } constructor ( private changeDetector , private dateHelper ) { } ngAfterViewInit ( ) { this . overlayPositions = getFlexiblePositions ( this . placement , 4 ) ; if ( this . autoFocus ) { this . focus ( ) ; } } focus ( ) { this . pickerInput . nativeElement . focus ( ) ; } showOverlay ( ) { if ( ! this . realOpenState ) { this . overlayOpen = true ; if ( this . realOpenState ) { this . animationOpenState = true ; } this . openChange . emit ( this . overlayOpen ) ; setTimeout ( ( ) => { if ( this . cdkConnectedOverlay && this . cdkConnectedOverlay . overlayRef ) { this . cdkConnectedOverlay . overlayRef . updatePosition ( ) ; } } ) ; } } hideOverlay ( ) { if ( this . realOpenState ) { this . overlayOpen = false ; if ( ! this . realOpenState ) { this . animationOpenState = false ; } this . openChange . emit ( this . overlayOpen ) ; this . focus ( ) ; } } onClickInputBox ( ) { if ( ! this . disabled && ! this . readonly && ! this . isOpenHandledByUser ( ) ) { this . showOverlay ( ) ; } } onClickBackdrop ( ) { this . hideOverlay ( ) ; } onOverlayDetach ( ) { this . hideOverlay ( ) ; } onPositionChange ( position ) { this . changeDetector . detectChanges ( ) ; } onClickClear ( event ) { event . preventDefault ( ) ; event . stopPropagation ( ) ; this . value = this . isRange ? [ ] : null ; this . valueChange . emit ( this . value ) ; } getPartTypeIndex ( partType ) { return { left : 0 , right : 1 } [ partType ] ; } isEmptyValue ( value ) { if ( value === null ) { return true ; } else if ( this . isRange ) { return ! value || ! Array . isArray ( value ) || value . every ( val => ! val ) ; } else { return ! value ; } } isOpenHandledByUser ( ) { return this . open !== undefined ; } getReadableValue ( ) { let value ; if ( this . isRange ) { const start = this . value [ 0 ] ? this . dateHelper . format ( this . value [ 0 ] . nativeDate , this . format ) : '' ; const end = this . value [ 1 ] ? this . dateHelper . format ( this . value [ 1 ] . nativeDate , this . format ) : '' ; return start && end ? `${ start } ~ ${ end }` : null ; } else { value = this . value as TinyDate ; return value ? this . dateHelper . format ( value . nativeDate , this . format ) : null ; } } getPlaceholder ( ) { return this . isRange && this . placeholder && Array . isArray ( this . placeholder ) ? ( this . placeholder as string [ ] ) . join ( ' ~ ' ) : ( this . placeholder as string ) ; } }