Skip to content

Commit

Permalink
feat(module:icon): add provideNzIcon and provideNzIconPatch API (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Laffery committed Jul 25, 2024
1 parent bef12e6 commit b22672d
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 96 deletions.
61 changes: 39 additions & 22 deletions components/icon/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ import { NzIconModule } from 'ng-zorro-antd/icon';
### [nz-icon]:standalone

| Property | Description | Type | Default | Global Config |
| ------------------ | ----------------------------------------------------------- | ------------------------------ | ----------- | ------------- |
|--------------------|-------------------------------------------------------------|--------------------------------|-------------|---------------|
| `[nzType]` | Type of the ant design icon | `string` | - |
| `[nzTheme]` | Type of the ant design icon | `'fill'\|'outline'\|'twotone'` | `'outline'` ||
| `[nzTheme]` | Type of the ant design icon | `'fill'\|'outline'\|'twotone'` | `'outline'` | |
| `[nzSpin]` | Rotate icon with animation | `boolean` | `false` |
| `[nzTwotoneColor]` | Only support the two-tone icon. Specific the primary color. | `string (hex color)` | - ||
| `[nzTwotoneColor]` | Only support the two-tone icon. Specific the primary color. | `string (hex color)` | - | |
| `[nzIconfont]` | Type of the icon from iconfont | `string` | - |
| `[nzRotate]` | Rotate degrees | `number` | - |

### NzIconService

| Methods/Properties | Description | Parameters |
| ---------------------- | ------------------------------------------------------------------------------------------------ | ------------------------ |
|------------------------|--------------------------------------------------------------------------------------------------|--------------------------|
| `addIcon()` | To import icons statically | `IconDefinition` |
| `addIconLiteral()` | To statically import custom icons | `string`, `string (SVG)` |
| `fetchFromIconfont()` | To get icon assets from fonticon | `NzIconfontOption` |
Expand All @@ -47,9 +47,9 @@ We synced to Ant Design and replaced font icons with svg icons which bring benef
- Support multiple colors for icon.
- No need to change built-in icons with overriding styles by providing more props in component.

You can join in [this dicussion of Ant Design](https://github.com/ant-design/ant-design/issues/10353).
You can join in [this discussion of Ant Design](https://github.com/ant-design/ant-design/issues/10353).

NG-ZORRO hadn't provided an icon component. Instead, icon based on font files was provided. We make this new directive compatible to old API. If you make no changes to your existing code, old icons would be dynamically loaded as `outline` icons. But the best pratice is always to use `nz-icon` directive and specify the `theme` prop.
NG-ZORRO hadn't provided an icon component. Instead, icon based on font files was provided. We make this new directive compatible to old API. If you make no changes to your existing code, old icons would be dynamically loaded as `outline`icons. But the best practice is always to use `nz-icon` directive and specify the `theme` prop.

```html
<span nz-icon [nzType]="'star'" [nzTheme]="'fill'"></span>
Expand All @@ -74,7 +74,7 @@ import { NzIconModule } from 'ng-zorro-antd/icon';
// Import what you need. RECOMMENDED. ✔️
import { AccountBookFill, AlertFill, AlertOutline } from '@ant-design/icons-angular/icons';

const icons: IconDefinition[] = [ AccountBookFill, AlertOutline, AlertFill ];
const icons: IconDefinition[] = [AccountBookFill, AlertOutline, AlertFill];

// Import all. NOT RECOMMENDED. ❌
// import * as AllIcons from '@ant-design/icons-angular/icons';
Expand All @@ -85,28 +85,23 @@ const icons: IconDefinition[] = [ AccountBookFill, AlertOutline, AlertFill ];
// const icons: IconDefinition[] = Object.keys(antDesignIcons).map(key => antDesignIcons[key])

@NgModule({
declarations: [
AppComponent
],
imports: [
NzIconModule.forRoot(icons),
]
bootstrap: [ AppComponent ]
declarations: [AppComponent],
imports: [NzIconModule.forRoot(icons)],
bootstrap: [AppComponent]
})
export class AppModule {}
```

For standalone mode, you register icons in `app.config.ts` like this:
For standalone mode, you can register icons in `app.config.ts` with `provideNzIcons` API:

```typescript
import { importProvidersFrom } from '@angular/core';
import { provideNzIcons } from 'ng-zorro-antd/icon';

export const appConfig = {
providers: [importProvidersFrom(NzIconModule.forRoot(icons))]
providers: [provideNzIcons(icons)]
}
```


Actually this calls `addIcon` of `NzIconService`. Icons imported would be bundled into your `.js` files. Static loading would increase your bundle's size so we recommend use dynamic importing as much as you can.

> Icons used by `NG-ZORRO` itself are imported statically to increase loading speed. However, icons demonstrated on the official website are loaded dynamically.
Expand Down Expand Up @@ -136,6 +131,8 @@ Please call this in component's constructor or `AppInitService`.
Sometimes, you want to import icons in lazy modules to avoid increasing the size of the main.js. You can use `NzIconModule.forChild`.

```typescript
import { NzIconModule } from 'ng-zorro-antd/icon';

@NgModule({
imports: [CommonModule, NzIconModule.forChild([QuestionOutline])]
})
Expand All @@ -144,15 +141,35 @@ class ChildModule {}

When `ChildModule` get loaded, the icon QuestionOutline would be usable across the application.

For standalone mode, you can import icons in `providers` of the standalone component or router with `provideNzIconsPatch` API.

```typescript
import { NzIconModule, provideNzIconsPatch } from 'ng-zorro-antd/icon';

// in xxx.component.ts
@Component({
standalone: true,
imports: [NzIconModule],
providers: [provideNzIconsPatch([QuestionOutline])]
})
class ChildComponent {}

// or in xxx.routes.ts
const routes: Routes = [{
path: '',
providers: [provideNzIconsPatch([QuestionOutline])],
}]
```

### Set Default TwoTone Color

When using the two-tone icons, you provide a global configuration like `{ nzIcon: { nzTwotoneColor: 'xxx' } }` via `NzConfigService` or call corresponding `set` method to change two default twotone color.
When using the two-tone icons, you provide a global configuration like `{ nzIcon: { nzTwotoneColor: 'xxx' } }`via `NzConfigService` or call corresponding `set` method to change to default twotone color.

### Custom Font Icon

We added a `fetchFromIconfont` method function to help developer using their own icons deployed at [iconfont.cn](http://iconfont.cn/) in a convenient way.

> This method is specified for iconfont.cn.
> This method is specified for [iconfont.cn](http://iconfont.cn/).
```typescript
this._iconService.fetchFromIconfont({
Expand All @@ -164,12 +181,12 @@ this._iconService.fetchFromIconfont({
<span nz-icon [nzIconfont]="'icon-tuichu'"></span>
```

It create a component that uses SVG sprites in essence.
It creates a component that uses SVG sprites in essence.

The following option are available:

| Property | Description | Type | Default |
| ----------- | ----------------------------------------- | -------- | ------- |
|-------------|-------------------------------------------|----------|---------|
| `scriptUrl` | The URL generated by iconfont.cn project. | `string` | - |

The property scriptUrl should be set to import the svg sprite symbols.
Expand Down
38 changes: 27 additions & 11 deletions components/icon/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,24 +86,20 @@ const icons: IconDefinition[] = [ AccountBookFill, AlertOutline, AlertFill ];
// const icons: IconDefinition[] = Object.keys(antDesignIcons).map(key => antDesignIcons[key])

@NgModule({
declarations: [
AppComponent
],
imports: [
NzIconModule.forRoot(icons)
]
bootstrap: [ AppComponent ]
declarations: [AppComponent],
imports: [NzIconModule.forRoot(icons)],
bootstrap: [AppComponent]
})
export class AppModule {}
```

在 standalone 模式下,你可以在 `app.config.ts` 中引入这些图标
在 standalone 模式下,你可以在 `app.config.ts` 中使用 `provideNzIcons` 引入这些图标

```typescript
import { importProvidersFrom } from '@angular/core';
import { provideNzIcons } from 'ng-zorro-antd/icon';

export const appConfig = {
providers: [importProvidersFrom(NzIconModule.forRoot(icons))]
providers: [provideNzIcons(icons)]
}
```

Expand Down Expand Up @@ -146,13 +142,33 @@ class ChildModule {}

当然,不要忘记在 `NZ_ICONS` 中删除该图标。

在 Standalone 模式下,你可以在懒加载的组件中或路由的 `providers` 中使用 `provideNzIconsPatch` 来补充图标:

```typescript
import { NzIconModule, provideNzIconsPatch } from 'ng-zorro-antd/icon';

// 在 xxx.component.ts 中
@Component({
standalone: true,
imports: [NzIconModule],
providers: [provideNzIconsPatch([QuestionOutline])]
})
class ChildComponent {}

// 或 在 xxx.routes.ts 中
const routes: Routes = [{
path: '',
providers: [provideNzIconsPatch([QuestionOutline])],
}]
```

### 双色图标主色

对于双色图标,可以通过提供全局配置 `{ nzIcon: { nzTwotoneColor: 'xxx' } }``NzConfigService` 的对应方法修改来全局设置图标主色。

### 自定义 font 图标

我们提供了一个 `fetchFromIconfont` 方法,方便开发者调用在 iconfont.cn 上自行管理的图标。
我们提供了一个 `fetchFromIconfont` 方法,方便开发者调用在 [iconfont.cn](http://iconfont.cn/) 上自行管理的图标。

```typescript
this._iconService.fetchFromIconfont({
Expand Down
17 changes: 3 additions & 14 deletions components/icon/icon.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ModuleWithProviders, NgModule } from '@angular/core';
import { IconDefinition } from '@ant-design/icons-angular';

import { NzIconDirective } from './icon.directive';
import { NZ_ICONS, NZ_ICONS_PATCH, NzIconPatchService } from './icon.service';
import { provideNzIcons, provideNzIconsPatch } from './provide-icons';

@NgModule({
imports: [NzIconDirective],
Expand All @@ -18,25 +18,14 @@ export class NzIconModule {
static forRoot(icons: IconDefinition[]): ModuleWithProviders<NzIconModule> {
return {
ngModule: NzIconModule,
providers: [
{
provide: NZ_ICONS,
useValue: icons
}
]
providers: [provideNzIcons(icons)]
};
}

static forChild(icons: IconDefinition[]): ModuleWithProviders<NzIconModule> {
return {
ngModule: NzIconModule,
providers: [
NzIconPatchService,
{
provide: NZ_ICONS_PATCH,
useValue: icons
}
]
providers: [provideNzIconsPatch(icons)]
};
}
}
39 changes: 37 additions & 2 deletions components/icon/icon.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, DebugElement, NgModule } from '@angular/core';
import { ComponentFixture, fakeAsync, inject, tick, waitForAsync } from '@angular/core/testing';
import { ComponentFixture, TestBed, fakeAsync, inject, tick, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import {
Expand All @@ -18,6 +18,7 @@ import { ComponentBed, createComponentBed } from 'ng-zorro-antd/core/testing/com
import { NzIconDirective } from './icon.directive';
import { NzIconModule } from './icon.module';
import { NzIconService, NZ_ICONS } from './icon.service';
import { provideNzIcons, provideNzIconsPatch } from './provide-icons';

describe('nz-icon', () => {
describe('basics', () => {
Expand Down Expand Up @@ -210,7 +211,7 @@ describe('nz-icon', () => {
nzConfigService!.set('icon', { nzTwotoneColor: '#234567' });
expect(icons[0].componentInstance.iconService.twoToneColor.primaryColor).toBe('#234567');

// Should ignore falsy value.
// Should ignore invalid value.
nzConfigService!.set('icon', { nzTwotoneColor: '234567' });
expect(icons[0].componentInstance.iconService.twoToneColor.primaryColor).not.toBe('234567');
expect(icons[0].componentInstance.iconService.twoToneColor.primaryColor).toBe('#1890ff');
Expand All @@ -236,6 +237,29 @@ describe('nz-icon', () => {
expect(icons[1].nativeElement.classList.contains('anticon-question')).toBe(true);
});
});

describe('[standalone] injection on multi places with provideNzIcon', () => {
let fixture: ComponentFixture<NzTestIconMultiInjectionStandaloneComponent>;
let icons: DebugElement[];

beforeEach(() => {
TestBed.configureTestingModule({
imports: [NzTestIconMultiInjectionStandaloneComponent],
providers: [provideNzIcons([HomeOutline])]
}).compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(NzTestIconMultiInjectionStandaloneComponent);
fixture.detectChanges();
});

it('should support forRoot and forChild', () => {
icons = fixture.debugElement.queryAll(By.directive(NzIconDirective));
expect(icons[0].nativeElement.classList.contains('anticon-home')).toBe(true);
expect(icons[1].nativeElement.classList.contains('anticon-question')).toBe(true);
});
});
});

@Component({
Expand Down Expand Up @@ -297,3 +321,14 @@ class ChildModule {}
`
})
class NzTestIconMultiInjectionComponent {}

@Component({
standalone: true,
imports: [NzIconModule],
providers: [provideNzIconsPatch([QuestionOutline])],
template: `
<span nz-icon nzType="home"></span>
<span nz-icon nzType="question"></span>
`
})
class NzTestIconMultiInjectionStandaloneComponent {}
39 changes: 39 additions & 0 deletions components/icon/provide-icons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* 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
*/

import { EnvironmentProviders, makeEnvironmentProviders, Provider } from '@angular/core';

import { IconDefinition } from '@ant-design/icons-angular';

import { NZ_ICONS, NZ_ICONS_PATCH, NzIconPatchService } from './icon.service';

/**
* Provide icon definitions for NzIcon in root
*
* @param icons Icon definitions
*/
export const provideNzIcons = (icons: IconDefinition[]): EnvironmentProviders => {
return makeEnvironmentProviders([
{
provide: NZ_ICONS,
useValue: icons
}
]);
};

/**
* Provide icon definitions for NzIcon in feature module or standalone component
*
* @param icons Icon definitions
*/
export const provideNzIconsPatch = (icons: IconDefinition[]): Provider[] => {
return [
NzIconPatchService,
{
provide: NZ_ICONS_PATCH,
useValue: icons
}
];
};
1 change: 1 addition & 0 deletions components/icon/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from './icon.module';
export * from './icon.directive';
export * from './icon.service';
export * from './icons';
export * from './provide-icons';
Loading

0 comments on commit b22672d

Please sign in to comment.