UNPKG

@clr/angular

Version:

Angular components for Clarity

90 lines 12 kB
/* * Copyright (c) 2016-2025 Broadcom. All Rights Reserved. * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. * This software is released under MIT license. * The full license information can be found in LICENSE in the root directory of this project. */ import { DOCUMENT, isPlatformBrowser } from '@angular/common'; import { Directive, Inject, Input, PLATFORM_ID, } from '@angular/core'; import { fromEvent, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { FOCUS_ON_VIEW_INIT } from './focus-on-view-init.provider'; import * as i0 from "@angular/core"; /* This directive is for guiding the document focus to the newly added content when its view is initialized so that assistive technologies can read its content. */ export class ClrFocusOnViewInit { constructor(el, platformId, focusOnViewInit, document, renderer, ngZone) { this.el = el; this.platformId = platformId; this.focusOnViewInit = focusOnViewInit; this.renderer = renderer; this.directFocus = true; // true if the element gets focused without need to set tabindex; this.destroy$ = new Subject(); this._isEnabled = focusOnViewInit; // Angular compiler doesn't understand the type Document // when working out the metadata for injectable parameters, // even though it understands the injection token DOCUMENT // https://github.com/angular/angular/issues/20351 this.document = document; ngZone.runOutsideAngular(() => fromEvent(el.nativeElement, 'focusout') .pipe(takeUntil(this.destroy$)) .subscribe(() => { if (!this.directFocus) { // manually set attributes and styles should be removed renderer.removeAttribute(el.nativeElement, 'tabindex'); renderer.setStyle(el.nativeElement, 'outline', null); } })); } set isEnabled(value) { if (this.focusOnViewInit && typeof value === 'boolean') { this._isEnabled = value; } } ngAfterViewInit() { this.focus(); } ngOnDestroy() { this.destroy$.next(); } focus() { if (!isPlatformBrowser(this.platformId)) { return; } if (!this._isEnabled) { return; } if (this.document && this.document.activeElement !== this.el.nativeElement) { this.el.nativeElement.focus(); if (this.document.activeElement !== this.el.nativeElement) { // if it's not directly focused now, it means it was a non-interactive element // so we need to give it a tabindex. this.directFocus = false; this.renderer.setAttribute(this.el.nativeElement, 'tabindex', '-1'); this.renderer.setStyle(this.el.nativeElement, 'outline', 'none'); this.el.nativeElement.focus(); } } } } ClrFocusOnViewInit.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFocusOnViewInit, deps: [{ token: i0.ElementRef }, { token: PLATFORM_ID }, { token: FOCUS_ON_VIEW_INIT }, { token: DOCUMENT }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); ClrFocusOnViewInit.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrFocusOnViewInit, selector: "[clrFocusOnViewInit]", inputs: { isEnabled: ["clrFocusOnViewInit", "isEnabled"] }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrFocusOnViewInit, decorators: [{ type: Directive, args: [{ selector: '[clrFocusOnViewInit]', }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: undefined, decorators: [{ type: Inject, args: [FOCUS_ON_VIEW_INIT] }] }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { isEnabled: [{ type: Input, args: ['clrFocusOnViewInit'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9jdXMtb24tdmlldy1pbml0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci9zcmMvdXRpbHMvZm9jdXMvZm9jdXMtb24tdmlldy1pbml0L2ZvY3VzLW9uLXZpZXctaW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE9BQU8sRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5RCxPQUFPLEVBRUwsU0FBUyxFQUVULE1BQU0sRUFDTixLQUFLLEVBR0wsV0FBVyxHQUVaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQzs7QUFFbkU7MkRBQzJEO0FBSTNELE1BQU0sT0FBTyxrQkFBa0I7SUFNN0IsWUFDVSxFQUEyQixFQUNOLFVBQWUsRUFDUixlQUF3QixFQUMxQyxRQUFhLEVBQ3ZCLFFBQW1CLEVBQzNCLE1BQWM7UUFMTixPQUFFLEdBQUYsRUFBRSxDQUF5QjtRQUNOLGVBQVUsR0FBVixVQUFVLENBQUs7UUFDUixvQkFBZSxHQUFmLGVBQWUsQ0FBUztRQUVwRCxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBVHJCLGdCQUFXLEdBQUcsSUFBSSxDQUFDLENBQUMsaUVBQWlFO1FBQ3JGLGFBQVEsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBV3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsZUFBZSxDQUFDO1FBRWxDLHdEQUF3RDtRQUN4RCwyREFBMkQ7UUFDM0QsMERBQTBEO1FBQzFELGtEQUFrRDtRQUNsRCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUV6QixNQUFNLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLENBQzVCLFNBQVMsQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQzthQUNwQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUM5QixTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ3JCLHVEQUF1RDtnQkFDdkQsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUN2RCxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO2FBQ3REO1FBQ0gsQ0FBQyxDQUFDLENBQ0wsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUNJLFNBQVMsQ0FBQyxLQUF1QjtRQUNuQyxJQUFJLElBQUksQ0FBQyxlQUFlLElBQUksT0FBTyxLQUFLLEtBQUssU0FBUyxFQUFFO1lBQ3RELElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1NBQ3pCO0lBQ0gsQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDZixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVPLEtBQUs7UUFDWCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQ3ZDLE9BQU87U0FDUjtRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ3BCLE9BQU87U0FDUjtRQUNELElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRTtZQUMxRSxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUM5QixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFO2dCQUN6RCw4RUFBOEU7Z0JBQzlFLG9DQUFvQztnQkFDcEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDcEUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUNqRSxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQzthQUMvQjtTQUNGO0lBQ0gsQ0FBQzs7K0dBcEVVLGtCQUFrQiw0Q0FRbkIsV0FBVyxhQUNYLGtCQUFrQixhQUNsQixRQUFRO21HQVZQLGtCQUFrQjsyRkFBbEIsa0JBQWtCO2tCQUg5QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxzQkFBc0I7aUJBQ2pDOzswQkFTSSxNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixNQUFNOzJCQUFDLGtCQUFrQjs7MEJBQ3pCLE1BQU07MkJBQUMsUUFBUTt5RkEwQmQsU0FBUztzQkFEWixLQUFLO3VCQUFDLG9CQUFvQiIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAyNSBCcm9hZGNvbS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFRoZSB0ZXJtIFwiQnJvYWRjb21cIiByZWZlcnMgdG8gQnJvYWRjb20gSW5jLiBhbmQvb3IgaXRzIHN1YnNpZGlhcmllcy5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UuXG4gKiBUaGUgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uIGNhbiBiZSBmb3VuZCBpbiBMSUNFTlNFIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgRE9DVU1FTlQsIGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIFBMQVRGT1JNX0lELFxuICBSZW5kZXJlcjIsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IEZPQ1VTX09OX1ZJRVdfSU5JVCB9IGZyb20gJy4vZm9jdXMtb24tdmlldy1pbml0LnByb3ZpZGVyJztcblxuLyogIFRoaXMgZGlyZWN0aXZlIGlzIGZvciBndWlkaW5nIHRoZSBkb2N1bWVudCBmb2N1cyB0byB0aGUgbmV3bHkgYWRkZWQgY29udGVudCB3aGVuIGl0cyB2aWV3IGlzIGluaXRpYWxpemVkXG4gICAgc28gdGhhdCBhc3Npc3RpdmUgdGVjaG5vbG9naWVzIGNhbiByZWFkIGl0cyBjb250ZW50LiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2NsckZvY3VzT25WaWV3SW5pdF0nLFxufSlcbmV4cG9ydCBjbGFzcyBDbHJGb2N1c09uVmlld0luaXQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudDtcbiAgcHJpdmF0ZSBkaXJlY3RGb2N1cyA9IHRydWU7IC8vIHRydWUgaWYgdGhlIGVsZW1lbnQgZ2V0cyBmb2N1c2VkIHdpdGhvdXQgbmVlZCB0byBzZXQgdGFiaW5kZXg7XG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIF9pc0VuYWJsZWQ6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBhbnksXG4gICAgQEluamVjdChGT0NVU19PTl9WSUVXX0lOSVQpIHByaXZhdGUgZm9jdXNPblZpZXdJbml0OiBib29sZWFuLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIGRvY3VtZW50OiBhbnksXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIG5nWm9uZTogTmdab25lXG4gICkge1xuICAgIHRoaXMuX2lzRW5hYmxlZCA9IGZvY3VzT25WaWV3SW5pdDtcblxuICAgIC8vIEFuZ3VsYXIgY29tcGlsZXIgZG9lc24ndCB1bmRlcnN0YW5kIHRoZSB0eXBlIERvY3VtZW50XG4gICAgLy8gd2hlbiB3b3JraW5nIG91dCB0aGUgbWV0YWRhdGEgZm9yIGluamVjdGFibGUgcGFyYW1ldGVycyxcbiAgICAvLyBldmVuIHRob3VnaCBpdCB1bmRlcnN0YW5kcyB0aGUgaW5qZWN0aW9uIHRva2VuIERPQ1VNRU5UXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9pc3N1ZXMvMjAzNTFcbiAgICB0aGlzLmRvY3VtZW50ID0gZG9jdW1lbnQ7XG5cbiAgICBuZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT5cbiAgICAgIGZyb21FdmVudChlbC5uYXRpdmVFbGVtZW50LCAnZm9jdXNvdXQnKVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5kaXJlY3RGb2N1cykge1xuICAgICAgICAgICAgLy8gbWFudWFsbHkgc2V0IGF0dHJpYnV0ZXMgYW5kIHN0eWxlcyBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAgICAgICAgcmVuZGVyZXIucmVtb3ZlQXR0cmlidXRlKGVsLm5hdGl2ZUVsZW1lbnQsICd0YWJpbmRleCcpO1xuICAgICAgICAgICAgcmVuZGVyZXIuc2V0U3R5bGUoZWwubmF0aXZlRWxlbWVudCwgJ291dGxpbmUnLCBudWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIEBJbnB1dCgnY2xyRm9jdXNPblZpZXdJbml0JylcbiAgc2V0IGlzRW5hYmxlZCh2YWx1ZTogYm9vbGVhbiB8IHN0cmluZykge1xuICAgIGlmICh0aGlzLmZvY3VzT25WaWV3SW5pdCAmJiB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgdGhpcy5faXNFbmFibGVkID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuZm9jdXMoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBmb2N1cygpIHtcbiAgICBpZiAoIWlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0aGlzLl9pc0VuYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuZG9jdW1lbnQgJiYgdGhpcy5kb2N1bWVudC5hY3RpdmVFbGVtZW50ICE9PSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgaWYgKHRoaXMuZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAhPT0gdGhpcy5lbC5uYXRpdmVFbGVtZW50KSB7XG4gICAgICAgIC8vIGlmIGl0J3Mgbm90IGRpcmVjdGx5IGZvY3VzZWQgbm93LCBpdCBtZWFucyBpdCB3YXMgYSBub24taW50ZXJhY3RpdmUgZWxlbWVudFxuICAgICAgICAvLyBzbyB3ZSBuZWVkIHRvIGdpdmUgaXQgYSB0YWJpbmRleC5cbiAgICAgICAgdGhpcy5kaXJlY3RGb2N1cyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsICd0YWJpbmRleCcsICctMScpO1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ291dGxpbmUnLCAnbm9uZScpO1xuICAgICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ==