UNPKG

@taiga-ui/kit

Version:

Taiga UI Angular main components kit

82 lines (78 loc) 4.75 kB
import * as i0 from '@angular/core'; import { inject, DestroyRef, contentChildren, ElementRef, Directive } from '@angular/core'; import { toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { tuiTypedFromEvent, tuiPreventDefault } from '@taiga-ui/cdk/observables'; import { tuiGetClosestFocusable } from '@taiga-ui/cdk/utils/focus'; import { TuiDropdownDirective } from '@taiga-ui/core/portals/dropdown'; import { map, shareReplay, switchMap, merge, filter, debounceTime, EMPTY, take, tap } from 'rxjs'; class TuiDataListDropdownManager { constructor() { this.destroyRef = inject(DestroyRef); this.dropdowns = contentChildren(TuiDropdownDirective, { descendants: true, }); this.els = contentChildren(TuiDropdownDirective, { read: ElementRef, descendants: true, }); this.elements$ = toObservable(this.els).pipe(map((array) => array.map(({ nativeElement }) => nativeElement)), shareReplay({ bufferSize: 1, refCount: true })); this.right$ = this.elements$.pipe(switchMap((elements) => merge(...elements.map((element, index) => tuiTypedFromEvent(element, 'keydown').pipe(filter(({ key }) => key === 'ArrowRight'), tuiPreventDefault(), map(() => index)))))); this.immediate$ = this.elements$.pipe(switchMap((elements) => merge(...elements.map((element, index) => tuiTypedFromEvent(element, 'click').pipe(map(() => index)))))); this.debounce$ = this.elements$.pipe(switchMap((elements) => merge(...elements.map((element, index) => merge(tuiTypedFromEvent(element, 'focus'), tuiTypedFromEvent(element, 'blur')).pipe(filter(({ relatedTarget }) => this.notInDropdown(relatedTarget, index)), map(({ type }) => (type === 'focus' ? index : Number.NaN)))))), debounceTime(300)); } ngAfterViewInit() { this.right$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((index) => { this.tryToFocus(index); }); merge(this.immediate$, this.debounce$) .pipe(switchMap((active) => { this.dropdowns().forEach((dropdown, index) => { dropdown.toggle(index === active); }); const element = this.els()[active]; const dropdown = this.dropdowns()[active]; const ref = dropdown?.ref(); if (!element || !dropdown || !ref) { return EMPTY; } const { nativeElement } = ref.location; const mouseEnter$ = tuiTypedFromEvent(nativeElement, 'mouseenter').pipe(take(1)); const esc$ = merge(tuiTypedFromEvent(element.nativeElement, 'keydown'), tuiTypedFromEvent(nativeElement, 'keydown')).pipe(filter(({ key }) => key === 'Escape')); return merge(mouseEnter$, esc$).pipe(tap((event) => { if (dropdown.ref()) { event.stopPropagation(); } element.nativeElement.focus(); dropdown.toggle('offsetX' in event); })); }), takeUntilDestroyed(this.destroyRef)) .subscribe(); } notInDropdown(element, index) { return !this.dropdowns()[index]?.ref()?.location.nativeElement.contains(element); } tryToFocus(index) { const content = this.dropdowns()[index]?.ref()?.location.nativeElement; if (!content) { return; } // First item is focus trap const focusTrap = tuiGetClosestFocusable({ initial: content, root: content }); const item = tuiGetClosestFocusable({ initial: focusTrap || content, root: content, }); item?.focus(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiDataListDropdownManager, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "19.2.21", type: TuiDataListDropdownManager, isStandalone: true, selector: "tui-data-list[tuiDataListDropdownManager]", queries: [{ propertyName: "dropdowns", predicate: TuiDropdownDirective, descendants: true, isSignal: true }, { propertyName: "els", predicate: TuiDropdownDirective, descendants: true, read: ElementRef, isSignal: true }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: TuiDataListDropdownManager, decorators: [{ type: Directive, args: [{ selector: 'tui-data-list[tuiDataListDropdownManager]' }] }] }); /** * Generated bundle index. Do not edit. */ export { TuiDataListDropdownManager }; //# sourceMappingURL=taiga-ui-kit-directives-data-list-dropdown-manager.mjs.map