import * as i0 from '@angular/core';
import { InjectionToken, inject, Injectable, NgZone, ChangeDetectorRef, Renderer2, DestroyRef, PendingTasks, PLATFORM_ID, numberAttribute, booleanAttribute, Input, Directive, makeEnvironmentProviders, NgModule } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { Subject, debounceTime, animationFrameScheduler, asapScheduler, finalize } from 'rxjs';
import { IconService, IconDirective } from '@ant-design/icons-angular';
import { warn } from 'ng-zorro-antd/core/logger';
import { wrapIntoObservable } from 'ng-zorro-antd/core/util';
import { Platform } from '@angular/cdk/platform';
import { NzConfigService, onConfigChangeEventForComponent } from 'ng-zorro-antd/core/config';
import { BarsOutline, CalendarOutline, CaretUpFill, CaretUpOutline, CaretDownFill, CaretDownOutline, CheckCircleFill, CheckCircleOutline, CheckOutline, ClockCircleOutline, CloseCircleOutline, CloseCircleFill, CloseOutline, CopyOutline, DeleteOutline, DoubleLeftOutline, DoubleRightOutline, DownOutline, EditOutline, EllipsisOutline, ExclamationCircleFill, ExclamationCircleOutline, EyeOutline, EyeInvisibleOutline, FileFill, FileOutline, FilterFill, InfoCircleFill, InfoCircleOutline, LeftOutline, LoadingOutline, PaperClipOutline, QuestionCircleOutline, RightOutline, RotateRightOutline, RotateLeftOutline, StarFill, SearchOutline, UploadOutline, VerticalAlignTopOutline, UpOutline, SwapOutline, SwapRightOutline, ZoomInOutline, ZoomOutOutline } from '@ant-design/icons-angular/icons';

/**
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
 */
const NZ_ICONS_USED_BY_ZORRO = [
    BarsOutline,
    CalendarOutline,
    CaretUpFill,
    CaretUpOutline,
    CaretDownFill,
    CaretDownOutline,
    CheckCircleFill,
    CheckCircleOutline,
    CheckOutline,
    ClockCircleOutline,
    CloseCircleOutline,
    CloseCircleFill,
    CloseOutline,
    CopyOutline,
    DeleteOutline,
    DoubleLeftOutline,
    DoubleRightOutline,
    DownOutline,
    EditOutline,
    EllipsisOutline,
    ExclamationCircleFill,
    ExclamationCircleOutline,
    EyeOutline,
    EyeInvisibleOutline,
    FileFill,
    FileOutline,
    FilterFill,
    InfoCircleFill,
    InfoCircleOutline,
    LeftOutline,
    LoadingOutline,
    PaperClipOutline,
    QuestionCircleOutline,
    RightOutline,
    RotateRightOutline,
    RotateLeftOutline,
    StarFill,
    SearchOutline,
    StarFill,
    UploadOutline,
    VerticalAlignTopOutline,
    UpOutline,
    SwapOutline,
    SwapRightOutline,
    ZoomInOutline,
    ZoomOutOutline
];

/**
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
 */
const NZ_ICONS = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'nz-icons' : '');
const NZ_ICON_DEFAULT_TWOTONE_COLOR = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'nz-icon-default-twotone-color' : '');
const DEFAULT_TWOTONE_COLOR = '#1890ff';
/**
 * It should be a global singleton, otherwise registered icons could not be found.
 */
class NzIconService extends IconService {
    nzConfigService = inject(NzConfigService);
    platform = inject(Platform);
    configUpdated$ = new Subject();
    get _disableDynamicLoading() {
        return !this.platform.isBrowser;
    }
    iconfontCache = new Set();
    normalizeSvgElement(svg) {
        if (!svg.getAttribute('viewBox')) {
            this._renderer.setAttribute(svg, 'viewBox', '0 0 1024 1024');
        }
        if (!svg.getAttribute('width') || !svg.getAttribute('height')) {
            this._renderer.setAttribute(svg, 'width', '1em');
            this._renderer.setAttribute(svg, 'height', '1em');
        }
        if (!svg.getAttribute('fill')) {
            this._renderer.setAttribute(svg, 'fill', 'currentColor');
        }
    }
    fetchFromIconfont(opt) {
        const { scriptUrl } = opt;
        if (this._document && !this.iconfontCache.has(scriptUrl)) {
            const script = this._renderer.createElement('script');
            this._renderer.setAttribute(script, 'src', scriptUrl);
            this._renderer.setAttribute(script, 'data-namespace', scriptUrl.replace(/^(https?|http):/g, ''));
            this._renderer.appendChild(this._document.body, script);
            this.iconfontCache.add(scriptUrl);
        }
    }
    createIconfontIcon(type) {
        return this._createSVGElementFromString(`<svg><use xlink:href="${type}"></svg>`);
    }
    constructor() {
        super([...NZ_ICONS_USED_BY_ZORRO, ...(inject(NZ_ICONS, { optional: true }) || [])]);
        this.onConfigChange();
        this.configDefaultTwotoneColor();
        this.configDefaultTheme();
    }
    onConfigChange() {
        onConfigChangeEventForComponent('icon', () => {
            this.configDefaultTwotoneColor();
            this.configDefaultTheme();
            this.configUpdated$.next();
        });
    }
    configDefaultTheme() {
        const iconConfig = this.getConfig();
        this.defaultTheme = iconConfig.nzTheme || 'outline';
    }
    configDefaultTwotoneColor() {
        const iconConfig = this.getConfig();
        const defaultTwotoneColor = iconConfig.nzTwotoneColor || DEFAULT_TWOTONE_COLOR;
        let primaryColor = DEFAULT_TWOTONE_COLOR;
        if (defaultTwotoneColor) {
            if (defaultTwotoneColor.startsWith('#')) {
                primaryColor = defaultTwotoneColor;
            }
            else {
                warn('Twotone color must be a hex color!');
            }
        }
        this.twoToneColor = { primaryColor };
    }
    getConfig() {
        return this.nzConfigService.getConfigForComponent('icon') || {};
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [] });
const NZ_ICONS_PATCH = new InjectionToken('nz_icons_patch');
class NzIconPatchService {
    rootIconService;
    patched = false;
    extraIcons = inject(NZ_ICONS_PATCH, { self: true });
    constructor(rootIconService) {
        this.rootIconService = rootIconService;
    }
    doPatch() {
        if (this.patched) {
            return;
        }
        this.extraIcons.forEach(iconDefinition => this.rootIconService.addIcon(iconDefinition));
        this.patched = true;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconPatchService, deps: [{ token: NzIconService }], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconPatchService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconPatchService, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: NzIconService }] });

/**
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
 */
class NzIconDirective extends IconDirective {
    iconService;
    ngZone = inject(NgZone);
    changeDetectorRef = inject(ChangeDetectorRef);
    renderer = inject(Renderer2);
    destroyRef = inject(DestroyRef);
    pendingTasks = inject(PendingTasks);
    isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
    nzSpin = false;
    nzRotate = 0;
    set nzType(value) {
        this.type = value;
    }
    set nzTheme(value) {
        this.theme = value;
    }
    set nzTwotoneColor(value) {
        this.twoToneColor = value;
    }
    set nzIconfont(value) {
        this.iconfont = value;
    }
    hostClass;
    el;
    iconfont;
    constructor(iconService) {
        super(iconService);
        this.iconService = iconService;
        inject(NzIconPatchService, { optional: true })?.doPatch();
        this.el = this._elementRef.nativeElement;
    }
    ngOnChanges(changes) {
        const { nzType, nzTwotoneColor, nzTheme, nzRotate } = changes;
        if (nzType || nzTwotoneColor || nzTheme) {
            // This is used to reduce the number of change detections
            // while the icon is being loaded asynchronously.
            this.ngZone.runOutsideAngular(() => this.changeIcon2());
        }
        else if (nzRotate) {
            this.handleRotate(this.el.firstChild);
        }
        else {
            this._setSVGElement(this.iconService.createIconfontIcon(`#${this.iconfont}`));
        }
    }
    /**
     * If custom content is provided, try to normalize SVG elements.
     */
    ngAfterContentChecked() {
        if (!this.type) {
            const children = this.el.children;
            let length = children.length;
            if (!this.type && children.length) {
                while (length--) {
                    const child = children[length];
                    if (child.tagName.toLowerCase() === 'svg') {
                        this.iconService.normalizeSvgElement(child);
                    }
                }
            }
        }
    }
    /**
     * Replacement of `changeIcon` for more modifications.
     */
    changeIcon2() {
        // It is used to hydrate the icon component properly when
        // zoneless change detection is used in conjunction with server-side rendering.
        const removeTask = this.pendingTasks.add();
        const svgOrRemove$ = wrapIntoObservable(this._changeIcon()).pipe(
        // We need to individually debounce the icon rendering on each animation
        // frame to prevent frame drops when many icons are being rendered on the
        // page, such as in a `@for` loop.
        debounceTime(0, this.isBrowser ? animationFrameScheduler : asapScheduler), takeUntilDestroyed(this.destroyRef), finalize(removeTask));
        svgOrRemove$.subscribe({
            next: svgOrRemove => {
                // Get back into the Angular zone after completing all the tasks.
                // Since we manually run change detection locally, we have to re-enter
                // the zone because the change detection might also be run on other local
                // components, leading them to handle template functions outside of the Angular zone.
                this.ngZone.run(() => {
                    // The _changeIcon method would call Renderer to remove the element of the old icon,
                    // which would call `markElementAsRemoved` eventually,
                    // so we should call `detectChanges` to tell Angular remove the DOM node.
                    // #7186
                    this.changeDetectorRef.detectChanges();
                    if (svgOrRemove) {
                        this.setSVGData(svgOrRemove);
                        this.handleRotate(svgOrRemove);
                    }
                });
            },
            error: warn
        });
    }
    handleRotate(svg) {
        if (this.nzRotate) {
            this.renderer.setAttribute(svg, 'style', `transform: rotate(${this.nzRotate}deg)`);
        }
        else {
            this.renderer.removeAttribute(svg, 'style');
        }
    }
    setSVGData(svg) {
        this.renderer.setAttribute(svg, 'data-icon', this.type);
        this.renderer.setAttribute(svg, 'aria-hidden', 'true');
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconDirective, deps: [{ token: NzIconService }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.3.0", type: NzIconDirective, isStandalone: true, selector: "nz-icon,[nz-icon]", inputs: { nzSpin: ["nzSpin", "nzSpin", booleanAttribute], nzRotate: ["nzRotate", "nzRotate", numberAttribute], nzType: "nzType", nzTheme: "nzTheme", nzTwotoneColor: "nzTwotoneColor", nzIconfont: "nzIconfont" }, host: { attributes: { "role": "img" }, properties: { "class": "'anticon-' + type", "class.anticon-spin": "nzSpin || type === 'loading'", "attr.aria-label": "type" }, classAttribute: "anticon" }, exportAs: ["nzIcon"], usesInheritance: true, usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'nz-icon,[nz-icon]',
                    exportAs: 'nzIcon',
                    host: {
                        class: 'anticon',
                        '[class]': `'anticon-' + type`,
                        '[class.anticon-spin]': `nzSpin || type === 'loading'`,
                        role: 'img',
                        '[attr.aria-label]': 'type'
                    }
                }]
        }], ctorParameters: () => [{ type: NzIconService }], propDecorators: { nzSpin: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], nzRotate: [{
                type: Input,
                args: [{ transform: numberAttribute }]
            }], nzType: [{
                type: Input
            }], nzTheme: [{
                type: Input
            }], nzTwotoneColor: [{
                type: Input
            }], nzIconfont: [{
                type: Input
            }] } });

/**
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
 */
/**
 * Provide icon definitions for NzIcon in root
 *
 * @param icons Icon definitions
 */
const provideNzIcons = (icons) => {
    return makeEnvironmentProviders([
        {
            provide: NZ_ICONS,
            useValue: icons
        }
    ]);
};
/**
 * Provide icon definitions for NzIcon in feature module or standalone component
 *
 * @param icons Icon definitions
 */
const provideNzIconsPatch = (icons) => {
    return [
        NzIconPatchService,
        {
            provide: NZ_ICONS_PATCH,
            useValue: icons
        }
    ];
};

/**
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
 */
class NzIconModule {
    static forRoot(icons) {
        return {
            ngModule: NzIconModule,
            providers: [provideNzIcons(icons)]
        };
    }
    static forChild(icons) {
        return {
            ngModule: NzIconModule,
            providers: [provideNzIconsPatch(icons)]
        };
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.0", ngImport: i0, type: NzIconModule, imports: [NzIconDirective], exports: [NzIconDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzIconModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [NzIconDirective],
                    exports: [NzIconDirective]
                }]
        }] });

/**
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
 */

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

export { DEFAULT_TWOTONE_COLOR, NZ_ICONS, NZ_ICONS_PATCH, NZ_ICONS_USED_BY_ZORRO, NZ_ICON_DEFAULT_TWOTONE_COLOR, NzIconDirective, NzIconModule, NzIconPatchService, NzIconService, provideNzIcons, provideNzIconsPatch };
//# sourceMappingURL=ng-zorro-antd-icon.mjs.map
