UNPKG

@taiga-ui/cdk

Version:

Base library for creating Angular components and applications using Taiga UI principles regarding of actual visual appearance

63 lines (59 loc) 2.99 kB
import { DOCUMENT } from '@angular/common'; import * as i0 from '@angular/core'; import { inject, Directive } from '@angular/core'; import { tuiInjectElement, tuiIsHTMLElement, tuiContainsOrAfter } from '@taiga-ui/cdk/utils/dom'; import { tuiGetFocused, tuiGetClosestFocusable } from '@taiga-ui/cdk/utils/focus'; class TuiFocusTrap { constructor() { this.doc = inject(DOCUMENT); this.el = tuiInjectElement(); this.activeElement = null; this.initialized = false; /** * This would cause currently focused element to lose focus, * but it might cause ExpressionChanged error due to potential HostBinding. * Microtask keeps it in the same frame but allows change detection to run */ Promise.resolve().then(() => { /** * The same event can synchronously close already opened focus trap and open another one. * All focus traps have microtask inside its `ngOnDestroy` – * they should be resolved before enabling of new focus trap. * Don't enable any new event listeners before `initialized` is equal to `true`! */ this.initialized = true; this.activeElement = tuiGetFocused(this.doc); this.el.focus(); }); } ngOnDestroy() { this.initialized = false; if (tuiIsHTMLElement(this.activeElement)) { this.activeElement.focus(); } } onFocusIn(node) { const { firstElementChild } = this.el; if (!tuiContainsOrAfter(this.el, node) && firstElementChild) { tuiGetClosestFocusable({ initial: firstElementChild, root: this.el })?.focus(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiFocusTrap, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiFocusTrap, isStandalone: true, selector: "[tuiFocusTrap]", host: { attributes: { "tabIndex": "0" }, listeners: { "pointerdown": "$event.currentTarget?.removeAttribute(\"tabindex\")", "window:focusin.zoneless": "initialized && onFocusIn($event.target)" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiFocusTrap, decorators: [{ type: Directive, args: [{ selector: '[tuiFocusTrap]', host: { tabIndex: '0', '(pointerdown)': '$event.currentTarget?.removeAttribute("tabindex")', '(window:focusin.zoneless)': 'initialized && onFocusIn($event.target)', }, }] }], ctorParameters: () => [] }); /** * Generated bundle index. Do not edit. */ export { TuiFocusTrap }; //# sourceMappingURL=taiga-ui-cdk-directives-focus-trap.mjs.map