Skip to content

Commit

Permalink
feat(module:icon): add injectiontoken config and default twotone color (
Browse files Browse the repository at this point in the history
  • Loading branch information
Wendell authored and vthinkxie committed Oct 26, 2018
1 parent 8bc488e commit bea1d05
Show file tree
Hide file tree
Showing 14 changed files with 211 additions and 58 deletions.
4 changes: 4 additions & 0 deletions README-zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ $ npm run site:start

浏览器会自动打开。

## 🗺 Road Map

查看 [这个 issue](https://github.com/NG-ZORRO/ng-zorro-antd/issues/2025) 来了解我们 2018 下半年的开发计划。

## 🤝 如何贡献

[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/NG-ZORRO/ng-zorro-antd/pulls)
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ $ npm run site:start

Browser would open automatically.

## 🗺 Road Map

Check [this issue](https://github.com/NG-ZORRO/ng-zorro-antd/issues/2025) to read our plans for later 2018.

## 🤝 Contributing

[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/NG-ZORRO/ng-zorro-antd/pulls)
Expand Down
55 changes: 41 additions & 14 deletions components/icon/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,25 @@ We are still adding two-tone icons right now, syncing to [antd](https://ant.desi
| `[type]` | Type of the ant design icon | string | - |
| `[theme]` | Type of the ant design icon | `fill 丨 outline 丨 twotone` | `outline` |
| `[spin]` | Rotate icon with animation | `boolean` | `false` |
| `[twoToneColor]` |Only support the two-tone icon. Specific the primary color. | `string (hex color)` | - |
| `[twoToneColor]` | Only support the two-tone icon. Specific the primary color. | `string (hex color)` | - |
| `[iconfont]` | Type of the icon from iconfont | string | - |

### NzIconService

| Methods | Description | Parameters |
| Methods/Properties | Description | Parameters |
| -------- | ----------- | ---- |
| `twoToneColor` | To set the default primary color of twotone icons, use Ant Design's official blue by default | `TwoToneColorPaletteSetter` |
| `addIcon()` | To import icons statically | `IconDefinition` |
| `fetchFromIconfont()` | To get icon assets from fonticon | `NzIconfontOption` |
| `changeAssetsSource()` | To change the location of your icon assets, so that you can deploy these icons wherever you want | `string` |

### InjectionToken

| Token | Description | Parameters |
| ----- | --- | ---- |
| `NZ_ICONS` | To import icons statically | `IconDefinition[]`, `useValue` |
| `NZ_ICON_DEFAULT_TWOTONE_COLOR` | To set the default primary color of twotone icons, use Ant Design's official blue by default | `string (hex color)`, `useValue` |

### SVG icons

After `1.7.0` version,we synced to Ant Design `3.9.x` and replaced font icons with svg icons which bring benefits below:
Expand Down Expand Up @@ -65,21 +73,40 @@ All the icons will be rendered to `<svg>`, and styles and classes applied to `<i

As for icons provided by Ant Design, there are two ways of importing them into your project.

Static loading. By registering icons to `NzIconService` you load icons statically. The icons would be compiled into your bundles. Do it in constructors or `AppInitService` (recommended).
Static loading. By registering icons to `AppModule` you load icons statically.

```ts
import { ApartmentOutline } from '@ant-design/icons-angular/icons';
import { NzIconService } from 'ng-zorro-antd';

export class AppComponent implements OnInit, AfterViewInit {
constructor(private iconService: NzIconService) {
// Import what you need.
this.iconService.addIcon(ApartmentOutline);
}
import { IconDefinition } from '@ant-design/icons-angular';
import { AccountBookFill, AlertFill, AlertOutline } from '@ant-design/icons-angular/icons';
import { NgZorroAntdModule, NZ_ICON_DEFAULT_TWOTONE_COLOR, NZ_ICONS } from 'ng-zorro-antd';
// import * as AllIcons from '@ant-design/icons-angular/icons';

// Import what you need. RECOMMENDED. ✔️
const icons: IconDefinition[] = [ AccountBookFill, AlertOutline, AlertFill ];
// Import all. NOT RECOMMENDED. ❌
// const antDesignIcons = AllIcons as {
// [key: string]: IconDefinition;
// };
// const icons: IconDefinition[] = Object.keys(antDesignIcons).map(key => antDesignIcons[key])

@NgModule({
declarations: [
AppComponent
],
imports : [
NgZorroAntdModule,
],
providers : [
{ provide: NZ_ICON_DEFAULT_TWOTONE_COLOR, useValue: '#00ff00' }, // If not provided, Ant Design's official blue would be used
{ provide: NZ_ICONS, useValue: icons }
],
bootstrap : [ AppComponent ]
})
export class AppModule {
}
```

Static loading would increase your bundle's size so we recommend use dynamic importing as much as you can. You can track this [issue](https://github.com/ant-design/ant-design/issues/12011) of Ant Design for more details.
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. You can track this [issue](https://github.com/ant-design/ant-design/issues/12011) of Ant Design for more details.

> Icons used by `NG-ZORRO` itself are imported statically to increase loading speed. However, icons demonstrated on the official website are loaded dynamically.
Expand All @@ -101,11 +128,11 @@ We provide a schematic to fix this. Just simply run `ng g ng-zorro-antd:fix-icon

You can call `changeAssetsSource()` of `NzIconService` to change the location of your icon assets, so that you can deploy these icon assets to cdn. The parameter you passed would be add in front of `assets/`.

Let's assume that you deploy static assets under `https://mycdn.alibaba-inc.com/assets`. You can call `changeAssetsSource('https://mycdn.alibaba-inc.com/')` to tell NG-ZORRO that all your resources are located there.
Let's assume that you deploy static assets under `https://mycdn.somecdn.com/icons/assets`. You can call `changeAssetsSource('https://mycdn.somecdn.com/icons')` to tell NG-ZORRO that all your resources are located there.

Please call this in component's constructor or `AppInitService`.

### Set TwoTone Color
### Set Default TwoTone Color

When using the two-tone icons, you can change the property of `NzIconService` to specify the primary color: `this.iconService.twoToneColor = { primaryColor: '#1890ff' }`.

Expand Down
55 changes: 42 additions & 13 deletions components/icon/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,25 @@ hasPageDemo: true
| `[type]` | 图标类型,遵循图标的命名规范 | string | - |
| `[theme]` | 图标主题风格。可选实心、描线、双色等主题风格,适用于官方图标 | `fill 丨 outline 丨 twotone` | `outline` |
| `[spin]` | 是否有旋转动画 | `boolean` | `false` |
| `[twoToneColor]` | 仅适用双色图标设置双色图标的主要颜色 | `string (十六进制颜色)` | - |
| `[twoToneColor]` | 仅适用双色图标设置双色图标的主要颜色,仅对当前 icon 生效 | `string (十六进制颜色)` | - |
| `[iconfont]` | 指定来自 IconFont 的图标类型 | string | - |

### NzIconService

| 方法/属性 | 说明 | 参数 |
| -------- | ----------- | ---- |
| `twoToneColor` | 用于设置双色图标的默认主题色,不设置即为 Ant Design 原生主题蓝色 | `TwoToneColorPaletteSetter` |
| `addIcon()` | 用于静态引入图标,可传入多个值(或者用数组解构赋值) | `IconDefinition` |
| `fetchFromIconfont()` | 用于从 FontIcon 获取图标资源文件 | `NzIconfontOption` |
| `changeAssetsSource()` | 用于修改动态加载 icon 的资源前缀,使得你可以部署图标资源到你想要的任何位置,例如 cdn | `string` |

### InjectionToken

| Token | 说明 | 参数 |
| ----- | --- | ---- |
| `NZ_ICONS` | 用于静态引入图标,传入数组 | `IconDefinition[]`, `useValue` |
| `NZ_ICON_DEFAULT_TWOTONE_COLOR` | 用于设置双色图标的默认主题色,不设置即为 Ant Design 原生主题蓝色 | `string (十六进制颜色)`, `useValue` |

### SVG 图标

`1.7.0` 版本开始,我们与 Ant Design `3.9.x` 同步,使用了 svg 图标替换了原先的 font 图标,从而带来了以下优势:
Expand Down Expand Up @@ -66,21 +74,40 @@ NG-ZORRO 之前并没有图标组件,而是提供了基于字体文件的解

对于 Ant Design 提供的图标,我们提供了两种方式来加载图标资源文件。

静态加载,通过在 `NzIconService` 中注册图标来实现静态引入,引入后的文件会被打包到 `.js` 文件中。在 constructor 里或者在 `AppInitService`(推荐),例如:
静态加载,`AppModule` 里加入你需要的图标(推荐)或者是全部的图标,例如:

```ts
import { ApartmentOutline } from '@ant-design/icons-angular/icons';
import { NzIconService } from 'ng-zorro-antd';

export class AppComponent implements OnInit, AfterViewInit {
constructor(private iconService: NzIconService) {
// Import what you need.
this.iconService.addIcon(ApartmentOutline);
}
import { IconDefinition } from '@ant-design/icons-angular';
import { AccountBookFill, AlertFill, AlertOutline } from '@ant-design/icons-angular/icons';
import { NgZorroAntdModule, NZ_ICON_DEFAULT_TWOTONE_COLOR, NZ_ICONS } from 'ng-zorro-antd';
// import * as AllIcons from '@ant-design/icons-angular/icons';

// 引入你需要的图标,比如你需要 fill 主题的 AccountBook Alert 和 outline 主题的 Alert,推荐 ✔️
const icons: IconDefinition[] = [ AccountBookFill, AlertOutline, AlertFill ];
// 全量引入,不推荐 ❌
// const antDesignIcons = AllIcons as {
// [key: string]: IconDefinition;
// };
// const icons: IconDefinition[] = Object.keys(antDesignIcons).map(key => antDesignIcons[key])

@NgModule({
declarations: [
AppComponent
],
imports : [
NgZorroAntdModule,
],
providers : [
{ provide: NZ_ICON_DEFAULT_TWOTONE_COLOR, useValue: '#00ff00' }, // 不提供的话,即为 Ant Design 的主题蓝色
{ provide: NZ_ICONS, useValue: icons }
],
bootstrap : [ AppComponent ]
})
export class AppModule {
}
```

静态引入会增加包体积,所以我们建议尽可能地使用动态加载,如果要静态加载,也仅仅加载你需要用到的 icon,具体请看 Ant Design 的 [issue](https://github.com/ant-design/ant-design/issues/12011)
本质上是调用了 `NzIconService``addIcon` 方法,引入后的文件会被打包到 `.js` 文件中。静态引入会增加包体积,所以我们建议尽可能地使用动态加载,如果要静态加载,也仅仅加载你需要用到的图标,具体请看 Ant Design 的 [issue](https://github.com/ant-design/ant-design/issues/12011)

> 为了加快渲染速度,`NG-ZORRO` 本身用到的 icon 是静态引入的。而官网的图标是动态引入的。
Expand All @@ -102,13 +129,15 @@ export class AppComponent implements OnInit, AfterViewInit {

你可以通过 `NzIconService``changeAssetsSource()` 方法来修改图标资源的位置,这样你就可以部署这些资源到 cdn 上。你的参数会被直接添加到 `assets/` 的前面。

例如,你在 `https://mycdn.alibaba-inc.com/assets` 目录下部署了静态资源文件,那么你就可以通过调用 `changeAssetsSource('https://mycdn.alibaba-inc.com/')`,来告诉 NG-ZORRO 从这个位置动态加载图标资源。
例如,你在 `https://mycdn.somecdn.com/icons/assets` 目录下部署了静态资源文件,那么你就可以通过调用 `changeAssetsSource('https://mycdn.somecdn.com/icons')`,来告诉 NG-ZORRO 从这个位置动态加载图标资源。

请在 constructor 里或者在 `AppInitService` 里调用这个方法。

### 双色图标主色

对于双色图标,可以通过修改 `this.iconService.twoToneColor = { primaryColor: '#1890ff' }` 来全局设置图标主色。你还可以访问这个属性获取当前的全局主色。
对于双色图标,可以通过修改 `this.iconService.twoToneColor = { primaryColor: '#1890ff' }` 来全局设置图标主色。你还可以访问这个属性获取当前的全局主色。还可以通过 `InjectionToken` 进行设置。

对于单个图标传入的参数有最高的优先级。

### 自定义 font 图标

Expand Down
28 changes: 24 additions & 4 deletions components/icon/nz-icon.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DOCUMENT } from '@angular/common';
import { HttpBackend } from '@angular/common/http';
import { Inject, Injectable, Optional, RendererFactory2 } from '@angular/core';
import { isDevMode, Inject, Injectable, InjectionToken, Optional, RendererFactory2 } from '@angular/core';
import { IconDefinition, IconService } from '@ant-design/icons-angular';
import {
CalendarOutline,
Expand All @@ -15,7 +15,7 @@ import {
DoubleRightOutline,
DownOutline,
ExclamationCircleFill,
ExclamationCircleOutline,
ExclamationCircleOutline, FilterFill,
InfoCircleFill,
InfoCircleOutline,
LeftOutline,
Expand All @@ -31,6 +31,10 @@ export interface NzIconfontOption {
scriptUrl: string;
}

export const NZ_ICONS = new InjectionToken('nz_icons');
export const NZ_ICON_DEFAULT_TWOTONE_COLOR = new InjectionToken('nz_icon_default_twotone_color');
export const DEFAULT_TWOTONE_COLOR = '#1890ff';

/**
* It should be a global singleton, otherwise registered icons could not be found.
*/
Expand Down Expand Up @@ -72,13 +76,16 @@ export class NzIconService extends IconService {
return this._createSVGElementFromString(`<svg><use xlink:href="${type}"></svg>`);
}

// tslint:disable:no-any
constructor(
protected _rendererFactory: RendererFactory2,
@Optional() protected _handler: HttpBackend,
// tslint:disable:no-any
@Optional() @Inject(DOCUMENT) protected _document: any
@Optional() @Inject(DOCUMENT) protected _document: any,
@Optional() @Inject(NZ_ICONS) private _icons: IconDefinition[],
@Optional() @Inject(NZ_ICON_DEFAULT_TWOTONE_COLOR) private _defaultColor: string
) {
super(_rendererFactory, _handler, _document);

const iconsUsedByZorro: IconDefinition[] = [
CalendarOutline,
CheckCircleFill,
Expand All @@ -93,6 +100,7 @@ export class NzIconService extends IconService {
DownOutline,
ExclamationCircleFill,
ExclamationCircleOutline,
FilterFill,
InfoCircleFill,
InfoCircleOutline,
LeftOutline,
Expand All @@ -104,5 +112,17 @@ export class NzIconService extends IconService {
UpOutline
];
this.addIcon(...iconsUsedByZorro);

if (this._icons) { this.addIcon(...this._icons); }

let primaryColor = DEFAULT_TWOTONE_COLOR;
if (this._defaultColor) {
if (this._defaultColor.startsWith('#')) {
primaryColor = this._defaultColor;
} else {
if (isDevMode()) { console.error('[NG-ZORRO] twotone color must be a hex color!'); }
}
}
this.twoToneColor = { primaryColor };
}
}
58 changes: 55 additions & 3 deletions components/icon/nz-icon.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { async, fakeAsync, tick, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { LoadingOutline, QuestionCircleOutline, QuestionOutline } from '@ant-design/icons-angular/icons';
import { LeftOutline, LoadingOutline, QuestionCircleOutline, QuestionOutline, RightOutline } from '@ant-design/icons-angular/icons';
import { NzIconDirective } from './nz-icon.directive';
import { NzIconModule } from './nz-icon.module';
import { NzIconService } from './nz-icon.service';
import { NzIconService, NZ_ICON_DEFAULT_TWOTONE_COLOR, NZ_ICONS } from './nz-icon.service';

describe('icon', () => {
let testComponent;
Expand Down Expand Up @@ -122,6 +122,57 @@ describe('icon', () => {
});
});

describe('icon static importing', () => {
let testComponent;
let fixture;
let icons;

it('should support injected icons and default color', fakeAsync(() => {
TestBed.configureTestingModule({
imports : [ CommonModule, NzIconModule ],
declarations: [ NzTestIconExtensionsComponent ],
providers : [ { provide: NZ_ICONS, useValue: [ LeftOutline, RightOutline ] }, { provide: NZ_ICON_DEFAULT_TWOTONE_COLOR, useValue: '#3344cc' } ]
});

fixture = TestBed.createComponent(NzTestIconExtensionsComponent);
testComponent = fixture.debugElement.componentInstance;
icons = fixture.debugElement.queryAll(By.directive(NzIconDirective));

fixture.detectChanges();
tick(1000);
fixture.detectChanges();

testComponent.type = 'left';

fixture.detectChanges();
tick(1000);
fixture.detectChanges();

expect(icons[ 0 ].nativeElement.querySelector('svg')).not.toBe(null);
expect(icons[ 0 ].componentInstance.type).toBe('left');
expect(icons[ 0 ].componentInstance._iconService.twoToneColor.primaryColor).toBe('#3344cc');
}));

it('should not set non-hashed-started-with string', fakeAsync(() => {
TestBed.configureTestingModule({
imports : [ CommonModule, NzIconModule ],
declarations: [ NzTestIconExtensionsComponent ],
providers : [ { provide: NZ_ICONS, useValue: [ LeftOutline, RightOutline ] }, { provide: NZ_ICON_DEFAULT_TWOTONE_COLOR, useValue: '3344cc' } ]
});

fixture = TestBed.createComponent(NzTestIconExtensionsComponent);
testComponent = fixture.debugElement.componentInstance;
icons = fixture.debugElement.queryAll(By.directive(NzIconDirective));

fixture.detectChanges();
tick(1000);
fixture.detectChanges();

expect(icons[ 0 ].componentInstance._iconService.twoToneColor.primaryColor).not.toBe('3344cc');
expect(icons[ 0 ].componentInstance._iconService.twoToneColor.primaryColor).toBe('#1890ff');
}));
});

@Component({
selector: 'nz-test-icon-extensions',
template: `
Expand All @@ -144,7 +195,8 @@ export class NzTestIconExtensionsComponent {
template: `
<i nz-icon style="color: hotpink;">
<svg>
<path d="M923 283.6c-13.4-31.1-32.6-58.9-56.9-82.8-24.3-23.8-52.5-42.4-84-55.5-32.5-13.5-66.9-20.3-102.4-20.3-49.3 0-97.4 13.5-139.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 55.5-24.4 23.9-43.5 51.7-56.9 82.8-13.9 32.3-21 66.6-21 101.9 0 33.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 101.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 20.3-103.3 0.1-35.3-7-69.6-20.9-101.9z"/>
<path
d="M923 283.6c-13.4-31.1-32.6-58.9-56.9-82.8-24.3-23.8-52.5-42.4-84-55.5-32.5-13.5-66.9-20.3-102.4-20.3-49.3 0-97.4 13.5-139.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 55.5-24.4 23.9-43.5 51.7-56.9 82.8-13.9 32.3-21 66.6-21 101.9 0 33.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 101.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 20.3-103.3 0.1-35.3-7-69.6-20.9-101.9z"/>
</svg>
</i>
`
Expand Down
2 changes: 1 addition & 1 deletion components/notification/demo/custom-icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { NzNotificationService } from 'ng-zorro-antd';
<ng-template #template>
<div class="ant-notification-notice-content">
<div class="ant-notification-notice-with-icon">
<span class="ant-notification-notice-icon"><i nz-icon type="smile-circle" style="color: rgb(16, 142, 233);"></i></span>
<span class="ant-notification-notice-icon"><i nz-icon type="smile" style="color: rgb(16, 142, 233);"></i></span>
<div class="ant-notification-notice-message">Notification Title</div>
<div class="ant-notification-notice-description">
This is the content of the notification. This is the content of the notification. This is the content of the notification.
Expand Down
2 changes: 1 addition & 1 deletion components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"dependencies": {
"date-fns": "^1.29.0",
"@angular/cdk": "^6.0.0",
"@ant-design/icons-angular": "^1.0.0"
"@ant-design/icons-angular": "^1.0.1"
},
"peerDependencies": {
"@angular/animations": "^6.0.0",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
},
"dependencies": {
"@angular/cdk": "^6.0.0",
"@ant-design/icons-angular": "^1.0.0",
"@ant-design/icons-angular": "^1.0.1",
"date-fns": "^1.29.0"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit bea1d05

Please sign in to comment.