@clr/angular
Version:
Angular components for Clarity
89 lines • 12 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* 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 = this.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
this.renderer.removeAttribute(this.el.nativeElement, 'tabindex');
this.renderer.setStyle(this.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9jdXMtb24tdmlldy1pbml0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci9zcmMvdXRpbHMvZm9jdXMvZm9jdXMtb24tdmlldy1pbml0L2ZvY3VzLW9uLXZpZXctaW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlELE9BQU8sRUFFTCxTQUFTLEVBRVQsTUFBTSxFQUNOLEtBQUssRUFHTCxXQUFXLEdBRVosTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLCtCQUErQixDQUFDOztBQUVuRTsyREFDMkQ7QUFJM0QsTUFBTSxPQUFPLGtCQUFrQjtJQU03QixZQUNVLEVBQWMsRUFDTyxVQUFlLEVBQ1IsZUFBd0IsRUFDMUMsUUFBYSxFQUN2QixRQUFtQixFQUMzQixNQUFjO1FBTE4sT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUNPLGVBQVUsR0FBVixVQUFVLENBQUs7UUFDUixvQkFBZSxHQUFmLGVBQWUsQ0FBUztRQUVwRCxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBVHJCLGdCQUFXLEdBQUcsSUFBSSxDQUFDLENBQUMsaUVBQWlFO1FBQ3JGLGFBQVEsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBV3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztRQUV2Qyx3REFBd0Q7UUFDeEQsMkRBQTJEO1FBQzNELDBEQUEwRDtRQUMxRCxrREFBa0Q7UUFDbEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFFekIsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxDQUM1QixTQUFTLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUM7YUFDcEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDOUIsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNyQix1REFBdUQ7Z0JBQ3ZELElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUNqRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDaEU7UUFDSCxDQUFDLENBQUMsQ0FDTCxDQUFDO0lBQ0osQ0FBQztJQUVELElBQ0ksU0FBUyxDQUFDLEtBQXVCO1FBQ25DLElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTLEVBQUU7WUFDdEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7U0FDekI7SUFDSCxDQUFDO0lBRUQsZUFBZTtRQUNiLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNmLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRU8sS0FBSztRQUNYLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDdkMsT0FBTztTQUNSO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDcEIsT0FBTztTQUNSO1FBQ0QsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFO1lBQzFFLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzlCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUU7Z0JBQ3pELDhFQUE4RTtnQkFDOUUsb0NBQW9DO2dCQUNwQyxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztnQkFDekIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNwRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2pFLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQy9CO1NBQ0Y7SUFDSCxDQUFDOzsrR0FwRVUsa0JBQWtCLDRDQVFuQixXQUFXLGFBQ1gsa0JBQWtCLGFBQ2xCLFFBQVE7bUdBVlAsa0JBQWtCOzJGQUFsQixrQkFBa0I7a0JBSDlCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLHNCQUFzQjtpQkFDakM7OzBCQVNJLE1BQU07MkJBQUMsV0FBVzs7MEJBQ2xCLE1BQU07MkJBQUMsa0JBQWtCOzswQkFDekIsTUFBTTsyQkFBQyxRQUFRO3lGQTBCZCxTQUFTO3NCQURaLEtBQUs7dUJBQUMsb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDIzIFZNd2FyZSwgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogVGhpcyBzb2Z0d2FyZSBpcyByZWxlYXNlZCB1bmRlciBNSVQgbGljZW5zZS5cbiAqIFRoZSBmdWxsIGxpY2Vuc2UgaW5mb3JtYXRpb24gY2FuIGJlIGZvdW5kIGluIExJQ0VOU0UgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgcHJvamVjdC5cbiAqL1xuXG5pbXBvcnQgeyBET0NVTUVOVCwgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uRGVzdHJveSxcbiAgUExBVEZPUk1fSUQsXG4gIFJlbmRlcmVyMixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgRk9DVVNfT05fVklFV19JTklUIH0gZnJvbSAnLi9mb2N1cy1vbi12aWV3LWluaXQucHJvdmlkZXInO1xuXG4vKiAgVGhpcyBkaXJlY3RpdmUgaXMgZm9yIGd1aWRpbmcgdGhlIGRvY3VtZW50IGZvY3VzIHRvIHRoZSBuZXdseSBhZGRlZCBjb250ZW50IHdoZW4gaXRzIHZpZXcgaXMgaW5pdGlhbGl6ZWRcbiAgICBzbyB0aGF0IGFzc2lzdGl2ZSB0ZWNobm9sb2dpZXMgY2FuIHJlYWQgaXRzIGNvbnRlbnQuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbY2xyRm9jdXNPblZpZXdJbml0XScsXG59KVxuZXhwb3J0IGNsYXNzIENsckZvY3VzT25WaWV3SW5pdCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50O1xuICBwcml2YXRlIGRpcmVjdEZvY3VzID0gdHJ1ZTsgLy8gdHJ1ZSBpZiB0aGUgZWxlbWVudCBnZXRzIGZvY3VzZWQgd2l0aG91dCBuZWVkIHRvIHNldCB0YWJpbmRleDtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgX2lzRW5hYmxlZDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogYW55LFxuICAgIEBJbmplY3QoRk9DVVNfT05fVklFV19JTklUKSBwcml2YXRlIGZvY3VzT25WaWV3SW5pdDogYm9vbGVhbixcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBkb2N1bWVudDogYW55LFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBuZ1pvbmU6IE5nWm9uZVxuICApIHtcbiAgICB0aGlzLl9pc0VuYWJsZWQgPSB0aGlzLmZvY3VzT25WaWV3SW5pdDtcblxuICAgIC8vIEFuZ3VsYXIgY29tcGlsZXIgZG9lc24ndCB1bmRlcnN0YW5kIHRoZSB0eXBlIERvY3VtZW50XG4gICAgLy8gd2hlbiB3b3JraW5nIG91dCB0aGUgbWV0YWRhdGEgZm9yIGluamVjdGFibGUgcGFyYW1ldGVycyxcbiAgICAvLyBldmVuIHRob3VnaCBpdCB1bmRlcnN0YW5kcyB0aGUgaW5qZWN0aW9uIHRva2VuIERPQ1VNRU5UXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9pc3N1ZXMvMjAzNTFcbiAgICB0aGlzLmRvY3VtZW50ID0gZG9jdW1lbnQ7XG5cbiAgICBuZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT5cbiAgICAgIGZyb21FdmVudChlbC5uYXRpdmVFbGVtZW50LCAnZm9jdXNvdXQnKVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5kaXJlY3RGb2N1cykge1xuICAgICAgICAgICAgLy8gbWFudWFsbHkgc2V0IGF0dHJpYnV0ZXMgYW5kIHN0eWxlcyBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVBdHRyaWJ1dGUodGhpcy5lbC5uYXRpdmVFbGVtZW50LCAndGFiaW5kZXgnKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbC5uYXRpdmVFbGVtZW50LCAnb3V0bGluZScsIG51bGwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgQElucHV0KCdjbHJGb2N1c09uVmlld0luaXQnKVxuICBzZXQgaXNFbmFibGVkKHZhbHVlOiBib29sZWFuIHwgc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuZm9jdXNPblZpZXdJbml0ICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aGlzLl9pc0VuYWJsZWQgPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5mb2N1cygpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gIH1cblxuICBwcml2YXRlIGZvY3VzKCkge1xuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuX2lzRW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5kb2N1bWVudCAmJiB0aGlzLmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgIT09IHRoaXMuZWwubmF0aXZlRWxlbWVudCkge1xuICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICBpZiAodGhpcy5kb2N1bWVudC5hY3RpdmVFbGVtZW50ICE9PSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgLy8gaWYgaXQncyBub3QgZGlyZWN0bHkgZm9jdXNlZCBub3csIGl0IG1lYW5zIGl0IHdhcyBhIG5vbi1pbnRlcmFjdGl2ZSBlbGVtZW50XG4gICAgICAgIC8vIHNvIHdlIG5lZWQgdG8gZ2l2ZSBpdCBhIHRhYmluZGV4LlxuICAgICAgICB0aGlzLmRpcmVjdEZvY3VzID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ3RhYmluZGV4JywgJy0xJyk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5lbC5uYXRpdmVFbGVtZW50LCAnb3V0bGluZScsICdub25lJyk7XG4gICAgICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19