{"version":3,"file":"taiga-ui-kit-directives-data-list-dropdown-manager.mjs","sources":["../../../projects/kit/directives/data-list-dropdown-manager/data-list-dropdown-manager.directive.ts","../../../projects/kit/directives/data-list-dropdown-manager/taiga-ui-kit-directives-data-list-dropdown-manager.ts"],"sourcesContent":["import type {AfterViewInit, QueryList} from '@angular/core';\nimport {ContentChildren, DestroyRef, Directive, ElementRef, inject} from '@angular/core';\nimport {takeUntilDestroyed} from '@angular/core/rxjs-interop';\nimport {EMPTY_QUERY} from '@taiga-ui/cdk/constants';\nimport {\n    tuiPreventDefault,\n    tuiQueryListChanges,\n    tuiTypedFromEvent,\n} from '@taiga-ui/cdk/observables';\nimport {tuiGetClosestFocusable} from '@taiga-ui/cdk/utils/focus';\nimport {tuiPure} from '@taiga-ui/cdk/utils/miscellaneous';\nimport {TuiDropdownDirective} from '@taiga-ui/core/directives/dropdown';\nimport type {Observable} from 'rxjs';\nimport {\n    debounceTime,\n    EMPTY,\n    filter,\n    map,\n    merge,\n    shareReplay,\n    switchMap,\n    take,\n    tap,\n} from 'rxjs';\n\n@Directive({\n    standalone: true,\n    selector: 'tui-data-list[tuiDataListDropdownManager]',\n})\nexport class TuiDataListDropdownManager implements AfterViewInit {\n    @ContentChildren(TuiDropdownDirective, {descendants: true})\n    private readonly dropdowns: QueryList<TuiDropdownDirective> = EMPTY_QUERY;\n\n    @ContentChildren(TuiDropdownDirective, {read: ElementRef, descendants: true})\n    private readonly els: QueryList<ElementRef<HTMLElement>> = EMPTY_QUERY;\n\n    private readonly destroyRef = inject(DestroyRef);\n\n    public ngAfterViewInit(): void {\n        this.right$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((index) => {\n            this.tryToFocus(index);\n        });\n\n        merge(this.immediate$, this.debounce$)\n            .pipe(\n                switchMap((active) => {\n                    this.dropdowns.forEach((dropdown, index) => {\n                        dropdown.toggle(index === active);\n                    });\n\n                    const element = this.els.get(active);\n                    const dropdown = this.dropdowns.get(active);\n                    const ref = dropdown?.ref();\n\n                    if (!element || !dropdown || !ref) {\n                        return EMPTY;\n                    }\n\n                    const {nativeElement} = ref.location;\n                    const mouseEnter$ = tuiTypedFromEvent(\n                        nativeElement,\n                        'mouseenter',\n                    ).pipe(take(1));\n                    const esc$ = merge(\n                        tuiTypedFromEvent(element.nativeElement, 'keydown'),\n                        tuiTypedFromEvent(nativeElement, 'keydown'),\n                    ).pipe(filter(({key}) => key === 'Escape'));\n\n                    return merge(mouseEnter$, esc$).pipe(\n                        tap((event) => {\n                            if (dropdown.ref()) {\n                                event.stopPropagation();\n                            }\n\n                            element.nativeElement.focus();\n                            dropdown.toggle('offsetX' in event);\n                        }),\n                    );\n                }),\n                takeUntilDestroyed(this.destroyRef),\n            )\n            .subscribe();\n    }\n\n    @tuiPure\n    private get elements$(): Observable<readonly HTMLElement[]> {\n        return tuiQueryListChanges(this.els).pipe(\n            map((array) => array.map(({nativeElement}) => nativeElement)),\n            shareReplay({bufferSize: 1, refCount: true}),\n        );\n    }\n\n    @tuiPure\n    private get right$(): Observable<number> {\n        return this.elements$.pipe(\n            switchMap((elements) =>\n                merge(\n                    ...elements.map((element, index) =>\n                        tuiTypedFromEvent(element, 'keydown').pipe(\n                            filter(({key}) => key === 'ArrowRight'),\n                            tuiPreventDefault(),\n                            map(() => index),\n                        ),\n                    ),\n                ),\n            ),\n        );\n    }\n\n    @tuiPure\n    private get immediate$(): Observable<number> {\n        return this.elements$.pipe(\n            switchMap((elements) =>\n                merge(\n                    ...elements.map((element, index) =>\n                        tuiTypedFromEvent(element, 'click').pipe(map(() => index)),\n                    ),\n                ),\n            ),\n        );\n    }\n\n    @tuiPure\n    private get debounce$(): Observable<number> {\n        return this.elements$.pipe(\n            switchMap((elements) =>\n                merge(\n                    ...elements.map((element, index) =>\n                        merge(\n                            tuiTypedFromEvent(element, 'focus'),\n                            tuiTypedFromEvent(element, 'blur'),\n                        ).pipe(\n                            filter(({relatedTarget}) =>\n                                this.notInDropdown(relatedTarget, index),\n                            ),\n                            map(({type}) => (type === 'focus' ? index : NaN)),\n                        ),\n                    ),\n                ),\n            ),\n            debounceTime(300),\n        );\n    }\n\n    private notInDropdown(element: EventTarget | null, index: number): boolean {\n        return !this.dropdowns\n            .get(index)\n            ?.ref()\n            ?.location.nativeElement.contains(element);\n    }\n\n    private tryToFocus(index: number): void {\n        const content = this.dropdowns.get(index)?.ref()?.location.nativeElement;\n\n        if (!content) {\n            return;\n        }\n\n        // First item is focus trap\n        const focusTrap = tuiGetClosestFocusable({initial: content, root: content});\n        const item = tuiGetClosestFocusable({\n            initial: focusTrap || content,\n            root: content,\n        });\n\n        item?.focus();\n    }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}