UNPKG

angular-input-focus

Version:
104 lines 11.6 kB
import { Directive, Input, Inject, PLATFORM_ID } from '@angular/core'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { isPlatformBrowser } from '@angular/common'; import * as i0 from "@angular/core"; /** * An angular focus directive. * ## Usage * For autofocus-like functionality, use like this: * <input [libFocus]="true"...> * * You can also pass an `EventEmitter<boolean>` as `setFocus` like so: * <input [libFocus]="false" [setFocus]="focusEvent">` * * Whenever your `focusEvent` emits a value, your element will focus/blur depending on * whether it is true or false. */ export class AngularInputFocusDirective { constructor(el, cd, zone, platformId) { this.el = el; this.cd = cd; this.zone = zone; /** * Indicates whether the current platform is a web browser. Used because our `focus` * implementation is specific to the DOM. Set in constructor. */ this.isRunningInBrowser = null; /** * When set to true, directive will mimick `autofocus` like functionality for your input. */ this.focus = false; /** * Set to true if you want to run outside angular and skip change detection. If you're not using * Angular Material, you can pretty safely set to "true". */ this.skipChangeDetection = false; /** * A subject that will emit a value when we should unsubscribe to our observables. */ this.killSubscriptions = new Subject(); this.isRunningInBrowser = isPlatformBrowser(platformId); } /** * When you emit a true value, the input will gain focus. If false, the input will blur. */ set setFocus(value) { // Unsubscribe from any previous subs this.killSubscriptions.next(); value.pipe(takeUntil(this.killSubscriptions)).subscribe(focus => this.setFocusOnElement(focus)); } /** * Set the focus on the target element. * @param focus Should the element have focus? */ setFocusOnElement(focus) { // If we aren't in a browser, there's nothing to do since our implementation is DOM-specific. // If we don't have a nativeElement, we have nothing to do either. if (this.isRunningInBrowser === false || !this.el.nativeElement) { return; } // Running outside angular zone to not trigger change detection unless we want to. this.zone.runOutsideAngular(() => { if (focus === true) { this.el.nativeElement.focus(); } else { this.el.nativeElement.blur(); } if (!this.skipChangeDetection) { this.cd.detectChanges(); } }); } ngAfterViewInit() { if (this.focus === true) { // After view init, if focus is set, focus element to mimick autofocus functionality. this.setFocusOnElement(true); } } ngOnDestroy() { this.killSubscriptions.next(); this.killSubscriptions.complete(); } } AngularInputFocusDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: AngularInputFocusDirective, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Directive }); AngularInputFocusDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.6", type: AngularInputFocusDirective, selector: "[libFocus]", inputs: { focus: ["libFocus", "focus"], setFocus: "setFocus", skipChangeDetection: "skipChangeDetection" }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: AngularInputFocusDirective, decorators: [{ type: Directive, args: [{ selector: '[libFocus]' }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }]; }, propDecorators: { focus: [{ type: Input, args: ['libFocus'] }], setFocus: [{ type: Input, args: ['setFocus'] }], skipChangeDetection: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1pbnB1dC1mb2N1cy5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWlucHV0LWZvY3VzL3NyYy9saWIvYW5ndWxhci1pbnB1dC1mb2N1cy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxLQUFLLEVBQW1DLE1BQU0sRUFBRSxXQUFXLEVBQW9DLE1BQU0sZUFBZSxDQUFDO0FBQ3JKLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDOztBQU1wRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sT0FBTywwQkFBMEI7SUF1RHJDLFlBQW9CLEVBQWMsRUFBVSxFQUFxQixFQUFVLElBQVksRUFBdUIsVUFBa0I7UUFBNUcsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUFVLE9BQUUsR0FBRixFQUFFLENBQW1CO1FBQVUsU0FBSSxHQUFKLElBQUksQ0FBUTtRQXREdkY7OztXQUdHO1FBQ0ssdUJBQWtCLEdBQVksSUFBSSxDQUFDO1FBRTNDOztXQUVHO1FBQ2dCLFVBQUssR0FBRyxLQUFLLENBQUM7UUFXakM7OztXQUdHO1FBQ00sd0JBQW1CLEdBQUcsS0FBSyxDQUFDO1FBRXJDOztXQUVHO1FBQ0ssc0JBQWlCLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQTBCeEMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUE3Q0Q7O09BRUc7SUFDSCxJQUF1QixRQUFRLENBQUMsS0FBNEI7UUFDMUQscUNBQXFDO1FBQ3JDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM5QixLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ2xHLENBQUM7SUFhRDs7O09BR0c7SUFDSyxpQkFBaUIsQ0FBQyxLQUFjO1FBQ3RDLDZGQUE2RjtRQUM3RixrRUFBa0U7UUFDbEUsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEtBQUssS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUU7WUFDL0QsT0FBTztTQUNSO1FBQ0Qsa0ZBQWtGO1FBQ2xGLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQy9CLElBQUksS0FBSyxLQUFLLElBQUksRUFBRTtnQkFDbEIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7YUFDL0I7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7YUFDOUI7WUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFO2dCQUM3QixJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDO2FBQ3pCO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBTUQsZUFBZTtRQUNiLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUU7WUFDdkIscUZBQXFGO1lBQ3JGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUM5QjtJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNwQyxDQUFDOzt1SEFyRVUsMEJBQTBCLG1HQXVENEQsV0FBVzsyR0F2RGpHLDBCQUEwQjsyRkFBMUIsMEJBQTBCO2tCQWhCdEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsWUFBWTtpQkFDdkI7OzBCQXFFMkYsTUFBTTsyQkFBQyxXQUFXOzRDQTdDekYsS0FBSztzQkFBdkIsS0FBSzt1QkFBQyxVQUFVO2dCQUtNLFFBQVE7c0JBQTlCLEtBQUs7dUJBQUMsVUFBVTtnQkFVUixtQkFBbUI7c0JBQTNCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBOZ1pvbmUsIEV2ZW50RW1pdHRlciwgT25EZXN0cm95LCBJbmplY3QsIFBMQVRGT1JNX0lELCBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3RvclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbbGliRm9jdXNdJ1xufSlcblxuLyoqXG4gKiBBbiBhbmd1bGFyIGZvY3VzIGRpcmVjdGl2ZS5cbiAqICMjIFVzYWdlXG4gKiBGb3IgYXV0b2ZvY3VzLWxpa2UgZnVuY3Rpb25hbGl0eSwgdXNlIGxpa2UgdGhpczpcbiAqIDxpbnB1dCBbbGliRm9jdXNdPVwidHJ1ZVwiLi4uPlxuICogXG4gKiBZb3UgY2FuIGFsc28gcGFzcyBhbiBgRXZlbnRFbWl0dGVyPGJvb2xlYW4+YCBhcyBgc2V0Rm9jdXNgIGxpa2Ugc286XG4gKiA8aW5wdXQgW2xpYkZvY3VzXT1cImZhbHNlXCIgW3NldEZvY3VzXT1cImZvY3VzRXZlbnRcIj5gXG4gKiBcbiAqIFdoZW5ldmVyIHlvdXIgYGZvY3VzRXZlbnRgIGVtaXRzIGEgdmFsdWUsIHlvdXIgZWxlbWVudCB3aWxsIGZvY3VzL2JsdXIgZGVwZW5kaW5nIG9uXG4gKiB3aGV0aGVyIGl0IGlzIHRydWUgb3IgZmFsc2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBBbmd1bGFySW5wdXRGb2N1c0RpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgY3VycmVudCBwbGF0Zm9ybSBpcyBhIHdlYiBicm93c2VyLiBVc2VkIGJlY2F1c2Ugb3VyIGBmb2N1c2AgXG4gICAqIGltcGxlbWVudGF0aW9uIGlzIHNwZWNpZmljIHRvIHRoZSBET00uIFNldCBpbiBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIHByaXZhdGUgaXNSdW5uaW5nSW5Ccm93c2VyOiBib29sZWFuID0gbnVsbDtcblxuICAvKipcbiAgICogV2hlbiBzZXQgdG8gdHJ1ZSwgZGlyZWN0aXZlIHdpbGwgbWltaWNrIGBhdXRvZm9jdXNgIGxpa2UgZnVuY3Rpb25hbGl0eSBmb3IgeW91ciBpbnB1dC5cbiAgICovXG4gIEBJbnB1dCgnbGliRm9jdXMnKSBmb2N1cyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGVuIHlvdSBlbWl0IGEgdHJ1ZSB2YWx1ZSwgdGhlIGlucHV0IHdpbGwgZ2FpbiBmb2N1cy4gSWYgZmFsc2UsIHRoZSBpbnB1dCB3aWxsIGJsdXIuXG4gICAqL1xuICBASW5wdXQoJ3NldEZvY3VzJykgc2V0IHNldEZvY3VzKHZhbHVlOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4pIHtcbiAgICAvLyBVbnN1YnNjcmliZSBmcm9tIGFueSBwcmV2aW91cyBzdWJzXG4gICAgdGhpcy5raWxsU3Vic2NyaXB0aW9ucy5uZXh0KCk7XG4gICAgdmFsdWUucGlwZSh0YWtlVW50aWwodGhpcy5raWxsU3Vic2NyaXB0aW9ucykpLnN1YnNjcmliZShmb2N1cyA9PiB0aGlzLnNldEZvY3VzT25FbGVtZW50KGZvY3VzKSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRvIHRydWUgaWYgeW91IHdhbnQgdG8gcnVuIG91dHNpZGUgYW5ndWxhciBhbmQgc2tpcCBjaGFuZ2UgZGV0ZWN0aW9uLiBJZiB5b3UncmUgbm90IHVzaW5nXG4gICAqIEFuZ3VsYXIgTWF0ZXJpYWwsIHlvdSBjYW4gcHJldHR5IHNhZmVseSBzZXQgdG8gXCJ0cnVlXCIuXG4gICAqL1xuICBASW5wdXQoKSBza2lwQ2hhbmdlRGV0ZWN0aW9uID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEEgc3ViamVjdCB0aGF0IHdpbGwgZW1pdCBhIHZhbHVlIHdoZW4gd2Ugc2hvdWxkIHVuc3Vic2NyaWJlIHRvIG91ciBvYnNlcnZhYmxlcy5cbiAgICovXG4gIHByaXZhdGUga2lsbFN1YnNjcmlwdGlvbnMgPSBuZXcgU3ViamVjdCgpO1xuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGZvY3VzIG9uIHRoZSB0YXJnZXQgZWxlbWVudC5cbiAgICogQHBhcmFtIGZvY3VzIFNob3VsZCB0aGUgZWxlbWVudCBoYXZlIGZvY3VzP1xuICAgKi9cbiAgcHJpdmF0ZSBzZXRGb2N1c09uRWxlbWVudChmb2N1czogYm9vbGVhbikge1xuICAgIC8vIElmIHdlIGFyZW4ndCBpbiBhIGJyb3dzZXIsIHRoZXJlJ3Mgbm90aGluZyB0byBkbyBzaW5jZSBvdXIgaW1wbGVtZW50YXRpb24gaXMgRE9NLXNwZWNpZmljLlxuICAgIC8vIElmIHdlIGRvbid0IGhhdmUgYSBuYXRpdmVFbGVtZW50LCB3ZSBoYXZlIG5vdGhpbmcgdG8gZG8gZWl0aGVyLlxuICAgIGlmICh0aGlzLmlzUnVubmluZ0luQnJvd3NlciA9PT0gZmFsc2UgfHwgIXRoaXMuZWwubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSdW5uaW5nIG91dHNpZGUgYW5ndWxhciB6b25lIHRvIG5vdCB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb24gdW5sZXNzIHdlIHdhbnQgdG8uXG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGlmIChmb2N1cyA9PT0gdHJ1ZSkge1xuICAgICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5ibHVyKCk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuc2tpcENoYW5nZURldGVjdGlvbikge1xuICAgICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIHpvbmU6IE5nWm9uZSwgQEluamVjdChQTEFURk9STV9JRCkgcGxhdGZvcm1JZDogc3RyaW5nKSB7XG4gICAgdGhpcy5pc1J1bm5pbmdJbkJyb3dzZXIgPSBpc1BsYXRmb3JtQnJvd3NlcihwbGF0Zm9ybUlkKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBpZiAodGhpcy5mb2N1cyA9PT0gdHJ1ZSkge1xuICAgICAgLy8gQWZ0ZXIgdmlldyBpbml0LCBpZiBmb2N1cyBpcyBzZXQsIGZvY3VzIGVsZW1lbnQgdG8gbWltaWNrIGF1dG9mb2N1cyBmdW5jdGlvbmFsaXR5LlxuICAgICAgdGhpcy5zZXRGb2N1c09uRWxlbWVudCh0cnVlKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmtpbGxTdWJzY3JpcHRpb25zLm5leHQoKTtcbiAgICB0aGlzLmtpbGxTdWJzY3JpcHRpb25zLmNvbXBsZXRlKCk7XG4gIH1cbn0iXX0=