ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
396 lines (387 loc) • 18.1 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, inject, Injectable, NgZone, ChangeDetectorRef, DestroyRef, PendingTasks, PLATFORM_ID, ElementRef, Renderer2, input, booleanAttribute, numberAttribute, computed, effect, 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, IconBase } 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();
this.addIcon(...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: "22.0.6", ngImport: i0, type: NzIconService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzIconService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzIconService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [] });
const NZ_ICONS_PATCH = new InjectionToken('nz_icons_patch');
class NzIconPatchService {
extraIcons = inject(NZ_ICONS_PATCH, { self: true });
rootIconService = inject(NzIconService);
patched = false;
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: "22.0.6", ngImport: i0, type: NzIconPatchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzIconPatchService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzIconPatchService, decorators: [{
type: Injectable
}] });
/**
* 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 IconBase {
ngZone = inject(NgZone);
changeDetectorRef = inject(ChangeDetectorRef);
destroyRef = inject(DestroyRef);
pendingTasks = inject(PendingTasks);
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
el = inject(ElementRef).nativeElement;
renderer = inject(Renderer2);
iconService = inject(NzIconService);
nzType = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "nzType" }] : /* istanbul ignore next */ []));
nzTheme = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "nzTheme" }] : /* istanbul ignore next */ []));
nzTwotoneColor = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "nzTwotoneColor" }] : /* istanbul ignore next */ []));
nzSpin = input(false, { ...(ngDevMode ? { debugName: "nzSpin" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
nzRotate = input(0, { ...(ngDevMode ? { debugName: "nzRotate" } : /* istanbul ignore next */ {}), transform: numberAttribute });
nzIconfont = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "nzIconfont" }] : /* istanbul ignore next */ []));
hostClass = computed(() => {
const type = this.nzType();
const spin = this.nzSpin();
const cls = ['anticon'];
if (type) {
cls.push(`anticon-${type}`);
}
if (spin || type === 'loading') {
cls.push('anticon-spin');
}
return cls;
}, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "hostClass" }] : /* istanbul ignore next */ []));
get selfRenderMeta() {
return {
type: this.nzType(),
theme: this.nzTheme(),
twoToneColor: this.nzTwotoneColor()
};
}
constructor() {
super();
inject(NzIconPatchService, { optional: true })?.doPatch();
let renderedIcon = false;
effect(() => {
void this.nzType();
void this.nzTwotoneColor();
void this.nzTheme();
// This is used to reduce the number of change detections
// while the icon is being loaded asynchronously.
if (this.nzType()) {
renderedIcon = true;
this.ngZone.runOutsideAngular(() => this.changeIcon2());
}
else if (renderedIcon) {
renderedIcon = false;
this._clearSVGElement();
}
});
effect(() => {
void this.nzRotate();
this.handleRotate(this.el.firstChild);
});
effect(() => {
const iconfont = this.nzIconfont();
if (iconfont) {
this._setSVGElement(this.iconService.createIconfontIcon(`#${iconfont}`));
}
});
}
/**
* If custom content is provided, try to normalize SVG elements.
*/
ngAfterContentChecked() {
if (!this.nzType()) {
const children = this.el.children;
for (let index = children.length - 1; index >= 0; index--) {
const child = children[index];
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: svg => {
// 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 (svg) {
this.setSVGData(svg);
this.handleRotate(svg);
}
});
},
error: warn
});
}
handleRotate(svg) {
if (!svg) {
return;
}
const rotate = this.nzRotate();
if (rotate) {
this.renderer.setAttribute(svg, 'style', `transform: rotate(${rotate}deg)`);
}
else {
this.renderer.removeAttribute(svg, 'style');
}
}
setSVGData(svg) {
this.renderer.setAttribute(svg, 'data-icon', this.nzType());
this.renderer.setAttribute(svg, 'aria-hidden', 'true');
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: NzIconDirective, isStandalone: true, selector: "nz-icon,[nz-icon]", inputs: { nzType: { classPropertyName: "nzType", publicName: "nzType", isSignal: true, isRequired: false, transformFunction: null }, nzTheme: { classPropertyName: "nzTheme", publicName: "nzTheme", isSignal: true, isRequired: false, transformFunction: null }, nzTwotoneColor: { classPropertyName: "nzTwotoneColor", publicName: "nzTwotoneColor", isSignal: true, isRequired: false, transformFunction: null }, nzSpin: { classPropertyName: "nzSpin", publicName: "nzSpin", isSignal: true, isRequired: false, transformFunction: null }, nzRotate: { classPropertyName: "nzRotate", publicName: "nzRotate", isSignal: true, isRequired: false, transformFunction: null }, nzIconfont: { classPropertyName: "nzIconfont", publicName: "nzIconfont", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "img" }, properties: { "class": "hostClass()", "attr.aria-label": "nzType()" } }, exportAs: ["nzIcon"], usesInheritance: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzIconDirective, decorators: [{
type: Directive,
args: [{
selector: 'nz-icon,[nz-icon]',
exportAs: 'nzIcon',
host: {
role: 'img',
'[class]': `hostClass()`,
'[attr.aria-label]': 'nzType()'
}
}]
}], ctorParameters: () => [], propDecorators: { nzType: [{ type: i0.Input, args: [{ isSignal: true, alias: "nzType", required: false }] }], nzTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "nzTheme", required: false }] }], nzTwotoneColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "nzTwotoneColor", required: false }] }], nzSpin: [{ type: i0.Input, args: [{ isSignal: true, alias: "nzSpin", required: false }] }], nzRotate: [{ type: i0.Input, args: [{ isSignal: true, alias: "nzRotate", required: false }] }], nzIconfont: [{ type: i0.Input, args: [{ isSignal: true, alias: "nzIconfont", required: false }] }] } });
/**
* 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: "22.0.6", ngImport: i0, type: NzIconModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.6", ngImport: i0, type: NzIconModule, imports: [NzIconDirective], exports: [NzIconDirective] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzIconModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", 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