import { Directive , ElementRef , HostListener , OnInit } from '@angular/core' ; @ Directive ( { selector : '[mask]' , } ) export class MaskDirective implements OnInit { private navigationKeys = [ 'Backspace' , 'Delete' , 'Tab' , 'Escape' , 'Enter' , 'Home' , 'End' , 'ArrowLeft' , 'ArrowRight' , 'Clear' , 'Copy' , 'Paste' , ] ; inputElement : HTMLInputElement ; regex : RegExp = new RegExp ( '' ) ; constructor ( public el ) { this . inputElement = el . nativeElement ; } ngOnInit ( ) { this . regex = new RegExp ( this . inputElement . pattern ) ; } @ HostListener ( 'keydown' , [ '$event' ] ) onKeyDown ( e ) { if ( this . navigationKeys . indexOf ( e . key ) > - 1 || ( ( e . key === 'a' || e . code === 'KeyA' ) && e . ctrlKey === true ) || ( ( e . key === 'c' || e . code === 'KeyC' ) && e . ctrlKey === true ) || ( ( e . key === 'v' || e . code === 'KeyV' ) && e . ctrlKey === true ) || ( ( e . key === 'x' || e . code === 'KeyX' ) && e . ctrlKey === true ) || ( ( e . key === 'a' || e . code === 'KeyA' ) && e . metaKey === true ) || ( ( e . key === 'c' || e . code === 'KeyC' ) && e . metaKey === true ) || ( ( e . key === 'v' || e . code === 'KeyV' ) && e . metaKey === true ) || ( ( e . key === 'x' || e . code === 'KeyX' ) && e . metaKey === true ) ) { return ; } const newValue = this . forecastValue ( e . key ) ; if ( ! this . regex . test ( newValue ) ) { e . preventDefault ( ) ; } } private forecastValue ( key ) { const selectionStart = this . inputElement . selectionStart ?? 0 ; const selectionEnd = this . inputElement . selectionEnd ?? 0 ; const oldValue = this . inputElement . value ; const selection = oldValue . substring ( selectionStart , selectionEnd ) ; return selection ? oldValue . replace ( selection , key ) : oldValue . substring ( 0 , selectionStart ) + key + oldValue . substring ( selectionStart ) ; } }