import * as i0 from '@angular/core';
import { input, output, inject, ElementRef, DestroyRef, Directive, NgModule } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { resizeObservable } from '@fundamental-ngx/cdk/utils';
import { debounceTime } from 'rxjs';

/**
 * A directive designed to help navigation elements determine the element currently in view of the user.
 */
class ScrollSpyDirective {
    constructor() {
        /**
         * An array of tags to track.
         */
        this.trackedTags = input([], ...(ngDevMode ? [{ debugName: "trackedTags" }] : []));
        /**
         * Whether events are still fired if there is no tag present on the user's screen.
         */
        this.fireEmpty = input(false, ...(ngDevMode ? [{ debugName: "fireEmpty" }] : []));
        /**
         * A number that represent at what location in the container the event is fired.
         * 0.5 would fire the events in the middle of the container,
         * 0 for the top and 1 for the bottom.
         */
        this.targetPercent = input(0, ...(ngDevMode ? [{ debugName: "targetPercent" }] : []));
        /**
         * Number that represents the offset in pixels for fired target. `100` value means that the event will be fired for
         * target that is 100 pixels below the spy container.
         */
        this.targetOffset = input(0, ...(ngDevMode ? [{ debugName: "targetOffset" }] : []));
        /**
         * Whether to disable scroll spy
         */
        this.scrollSpyDisabled = input(false, ...(ngDevMode ? [{ debugName: "scrollSpyDisabled" }] : []));
        /**
         * Event fired on the scroll element when a new item becomes activated by the scrollspy .
         * The returned value is the HTMLElement itself, or undefined when no element is active.
         */
        this.spyChange = output();
        /** @hidden */
        this._elRef = inject(ElementRef);
        /** @hidden */
        this._destroyRef = inject(DestroyRef);
    }
    /** @hidden */
    onScroll(event, forced = false) {
        if (this.scrollSpyDisabled()) {
            return;
        }
        let spiedTag;
        const target = (event?.target || this._elRef.nativeElement);
        const children = this._elRef.nativeElement.children;
        const [firstChild] = children;
        const childrenLength = children.length;
        const targetScrollTop = target.scrollTop;
        const targetOffsetTop = firstChild.offsetTop + this.targetOffset();
        for (let i = 0; i < childrenLength; i++) {
            const element = children[i];
            if (this.trackedTags().some((tag) => tag.toLocaleUpperCase() === element.tagName.toLocaleUpperCase())) {
                if (element.offsetTop - targetOffsetTop <=
                    targetScrollTop + target.offsetHeight * this.targetPercent()) {
                    spiedTag = element;
                }
            }
        }
        if (forced || ((spiedTag || this.fireEmpty()) && spiedTag !== this._currentActive)) {
            this._currentActive = spiedTag;
            this.spyChange.emit(this._currentActive);
        }
    }
    /** @hidden */
    ngOnInit() {
        // When the spy container being resized, re-evaluate scroll position.
        resizeObservable(this._elRef.nativeElement)
            .pipe(debounceTime(30), takeUntilDestroyed(this._destroyRef))
            .subscribe(() => {
            this.onScroll(undefined, true);
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ScrollSpyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: ScrollSpyDirective, isStandalone: true, selector: "[fdScrollSpy]", inputs: { trackedTags: { classPropertyName: "trackedTags", publicName: "trackedTags", isSignal: true, isRequired: false, transformFunction: null }, fireEmpty: { classPropertyName: "fireEmpty", publicName: "fireEmpty", isSignal: true, isRequired: false, transformFunction: null }, targetPercent: { classPropertyName: "targetPercent", publicName: "targetPercent", isSignal: true, isRequired: false, transformFunction: null }, targetOffset: { classPropertyName: "targetOffset", publicName: "targetOffset", isSignal: true, isRequired: false, transformFunction: null }, scrollSpyDisabled: { classPropertyName: "scrollSpyDisabled", publicName: "scrollSpyDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { spyChange: "spyChange" }, host: { listeners: { "scroll": "onScroll($event)" } }, exportAs: ["fdScrollSpy"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ScrollSpyDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fdScrollSpy]',
                    host: {
                        '(scroll)': 'onScroll($event)'
                    },
                    exportAs: 'fdScrollSpy'
                }]
        }], propDecorators: { trackedTags: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackedTags", required: false }] }], fireEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "fireEmpty", required: false }] }], targetPercent: [{ type: i0.Input, args: [{ isSignal: true, alias: "targetPercent", required: false }] }], targetOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "targetOffset", required: false }] }], scrollSpyDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollSpyDisabled", required: false }] }], spyChange: [{ type: i0.Output, args: ["spyChange"] }] } });

/**
 * @deprecated
 * Use direct `ScrollSpyDirective` import.
 */
class ScrollSpyModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ScrollSpyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.0", ngImport: i0, type: ScrollSpyModule, imports: [ScrollSpyDirective], exports: [ScrollSpyDirective] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ScrollSpyModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ScrollSpyModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [ScrollSpyDirective],
                    exports: [ScrollSpyDirective]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { ScrollSpyDirective, ScrollSpyModule };
//# sourceMappingURL=fundamental-ngx-core-scroll-spy.mjs.map
