@@ -12,6 +12,8 @@ import {
12
12
import { IconDirective } from '@ant-design/icons-angular' ;
13
13
import { NzIconService } from './nz-icon.service' ;
14
14
15
+ const iconTypeRE = / ^ a n t i c o n \- \w / ;
16
+
15
17
/**
16
18
* This directive extends IconDirective to provide:
17
19
*
@@ -32,78 +34,113 @@ export class NzIconDirective extends IconDirective implements OnInit, OnChanges,
32
34
33
35
/**
34
36
* In order to make this directive compatible to old API, we had do some ugly stuff here.
35
- * Should be removed in next major version.
37
+ * TODO: Should be removed in next major version.
36
38
*/
37
39
private _classChangeHandler ( className : string ) : void {
38
- if ( ! className ) { return ; }
39
-
40
- const forceSpin = className . indexOf ( 'anticon-spin' ) > - 1 ;
41
- const classArr = className . split ( / \s / ) ;
42
- let anticonType = classArr . filter ( cls => cls !== 'anticon' && cls !== 'anticon-spin' && cls . match ( / ^ a n t i c o n \- \w / ) ) [ 0 ] ;
40
+ if ( className ) {
41
+ const iconType = className
42
+ . split ( / \s / )
43
+ . filter ( cls => cls !== 'anticon' && cls !== 'anticon-spin' && ! ! cls . match ( iconTypeRE ) ) [ 0 ] ;
43
44
44
- if ( ! anticonType ) { return ; }
45
+ if ( ! iconType ) {
46
+ return ;
47
+ }
45
48
46
- anticonType = anticonType . replace ( 'anticon-' , '' ) ;
47
- if ( anticonType . includes ( 'verticle' ) ) {
48
- anticonType = anticonType . replace ( 'verticle' , 'vertical' ) ;
49
- if ( ! this . _iconService . warnedAboutVertical ) {
50
- console . warn ( '[NG-ZORRO]' , `'verticle' is misspelled, would be corrected in the next major version.` ) ;
51
- this . _iconService . warnedAboutVertical = true ;
49
+ let parsedIconType = iconType . replace ( 'anticon-' , '' ) ;
50
+ if ( parsedIconType . includes ( 'verticle' ) ) {
51
+ parsedIconType = parsedIconType . replace ( 'verticle' , 'vertical' ) ;
52
+ this . _warnAPI ( 'cross' ) ;
52
53
}
53
- }
54
- if ( anticonType . startsWith ( 'cross' ) ) {
55
- anticonType = anticonType . replace ( 'cross' , 'close' ) ;
56
- if ( ! this . _iconService . warnedAboutCross ) {
57
- console . warn ( '[NG-ZORRO]' , `'cross' icon is replaced by 'close' icon.` ) ;
58
- this . _iconService . warnedAboutCross = true ;
54
+ if ( parsedIconType . startsWith ( 'cross' ) ) {
55
+ parsedIconType = parsedIconType . replace ( 'cross' , 'close' ) ;
56
+ this . _warnAPI ( 'vertical' ) ;
59
57
}
60
- }
61
- if ( ! ( anticonType . endsWith ( '-o' ) || anticonType . endsWith ( '-fill' ) || anticonType . endsWith ( '-twotone' ) ) ) {
62
- anticonType += '-o' ;
63
- }
64
58
65
- if ( this . type !== anticonType ) {
66
- this . type = anticonType ;
67
- this . _changeIcon ( ) . catch ( err => {
59
+ // Only change icon when icon type does change.
60
+ if ( this . type !== parsedIconType ) {
61
+ this . type = parsedIconType ;
62
+ this . _changeIcon ( ) . catch ( err => {
68
63
console . warn ( '[NG-ZORRO]' , `You can find more about this error on http://ng.ant.design/components/icon/en\n` , err ) ;
69
64
} ) ;
65
+ }
70
66
}
71
67
}
72
68
73
- private _warnAPI ( ) : void {
74
- if ( isDevMode ( ) && ! this . _iconService . warnedAboutAPI ) {
75
- console . warn ( '[NG-ZORRO]' , `<i class="anticon"></i> would be deprecated soon. Please use <i nz-icon type=""></i> API.` ) ;
69
+ /**
70
+ * In order to make this directive compatible to old API, we had do some ugly stuff here.
71
+ * TODO: Should be removed in next major version.
72
+ */
73
+ private _warnAPI ( type : 'old' | 'cross' | 'vertical' ) : void {
74
+ if ( isDevMode ( ) ) {
75
+ if ( type === 'old' && ! this . _iconService . warnedAboutAPI ) {
76
+ console . warn ( '[NG-ZORRO]' , `<i class="anticon"></i> would be deprecated soon. Please use <i nz-icon type=""></i> API.` ) ;
77
+ this . _iconService . warnedAboutAPI = true ;
78
+ }
79
+ if ( type === 'cross' && ! this . _iconService . warnedAboutCross ) {
80
+ console . warn ( '[NG-ZORRO]' , `'cross' icon is replaced by 'close' icon.` ) ;
81
+ this . _iconService . warnedAboutCross = true ;
82
+ }
83
+ if ( type === 'vertical' && ! this . _iconService . warnedAboutVertical ) {
84
+ console . warn ( '[NG-ZORRO]' , `'verticle' is misspelled, would be corrected in the next major version.` ) ;
85
+ this . _iconService . warnedAboutVertical = true ;
86
+ }
76
87
}
77
- this . _iconService . warnedAboutAPI = true ;
78
88
}
79
89
80
- private _addExtraModifications ( svg : SVGElement ) : void {
81
- if ( this . spin || this . type === 'loading' ) {
82
- this . _renderer . addClass ( this . _el , 'anticon-spin' ) ;
90
+ private _toggleSpin ( svg : SVGElement ) : void {
91
+ if ( ( this . spin || this . type === 'loading' ) && ! this . _el . classList . contains ( 'anticon-spin' ) ) {
92
+ this . _renderer . addClass ( svg , 'anticon-spin' ) ;
83
93
} else {
84
- this . _renderer . removeClass ( this . _el , 'anticon-spin' ) ;
94
+ this . _renderer . removeClass ( svg , 'anticon-spin' ) ;
95
+ }
96
+ }
97
+
98
+ private _setClassName ( ) : void {
99
+ // If there's not an anticon class, usually a new API icon, get the icon class name back.
100
+ // anticon should be added before other class names.
101
+ if ( this . _el && typeof this . type === 'string' ) {
102
+ const iconClassNameArr = this . _el . className . split ( / \s / ) ;
103
+ const oldTypeNameIndex = iconClassNameArr . findIndex ( cls => cls !== 'anticon' && cls !== 'anticon-spin' && ! ! cls . match ( iconTypeRE ) ) ;
104
+
105
+ if ( oldTypeNameIndex !== - 1 ) {
106
+ iconClassNameArr . splice ( oldTypeNameIndex , 1 , `anticon-${ this . type } ` ) ;
107
+ this . _renderer . setAttribute ( this . _el , 'class' , iconClassNameArr . join ( ' ' ) ) ;
108
+ } else {
109
+ this . _renderer . addClass ( this . _el , `anticon-${ this . type } ` ) ;
110
+ }
85
111
}
86
112
}
87
113
88
- private _getIconNameBack ( ) : void {
114
+ private _setSVGData ( svg : SVGElement ) : void {
89
115
if ( typeof this . type === 'string' ) {
90
- this . _renderer . addClass ( this . _elementRef . nativeElement , `anticon-${ this . type } ` ) ;
116
+ this . _renderer . setAttribute ( svg , 'data-icon' , this . type ) ;
117
+ this . _renderer . setAttribute ( svg , 'aria-hidden' , 'true' ) ;
91
118
}
92
119
}
93
120
121
+ private _addExtraModifications ( svg : SVGElement ) : void {
122
+ this . _toggleSpin ( svg ) ;
123
+ this . _setSVGData ( svg ) ;
124
+ }
125
+
94
126
constructor ( public _iconService : NzIconService , public _elementRef : ElementRef , public _renderer : Renderer2 ) {
95
- super ( _iconService , _elementRef , _renderer ) ; // NzIconService extends IconService so IconDirective won't complain.
127
+ super ( _iconService , _elementRef , _renderer ) ;
96
128
}
97
129
98
130
ngOnChanges ( ) : void {
99
131
if ( ! this . iconfont ) {
100
- this . _getIconNameBack ( ) ; // Should get back classNames immediately.
132
+ // For ant design icons.
133
+ this . _setClassName ( ) ;
101
134
this . _changeIcon ( ) . then ( svg => {
102
135
this . _addExtraModifications ( svg ) ;
103
- } ) . catch ( ( ) => {
104
- console . warn ( '[NG-ZORRO]' , `You can find more about this error on http://ng.ant.design/components/icon/en` ) ;
136
+ } ) . catch ( ( err ) => {
137
+ if ( err ) {
138
+ console . error ( err ) ;
139
+ console . warn ( '[NG-ZORRO]' , `You can find more about this error on http://ng.ant.design/components/icon/en` ) ;
140
+ }
105
141
} ) ;
106
142
} else {
143
+ // For iconfont icons.
107
144
this . _setSVGElement ( this . _iconService . createIconfontIcon ( `#${ this . iconfont } ` ) ) ;
108
145
}
109
146
}
@@ -113,8 +150,10 @@ export class NzIconDirective extends IconDirective implements OnInit, OnChanges,
113
150
*/
114
151
ngOnInit ( ) : void {
115
152
this . _el = this . _elementRef . nativeElement ;
153
+
154
+ // Make the component compatible to old class="anticon" API.
116
155
if ( this . _el && ! this . type ) {
117
- this . _warnAPI ( ) ;
156
+ this . _warnAPI ( 'old' ) ;
118
157
this . _classChangeHandler ( this . _el . className ) ;
119
158
this . _classNameObserver = new MutationObserver ( ( mutations : MutationRecord [ ] ) => {
120
159
mutations
@@ -127,6 +166,10 @@ export class NzIconDirective extends IconDirective implements OnInit, OnChanges,
127
166
if ( ! this . _el . classList . contains ( 'anticon' ) ) {
128
167
this . _renderer . setAttribute ( this . _el , 'class' , `anticon ${ this . _el . className } ` ) ;
129
168
}
169
+
170
+ if ( this . type ) {
171
+ this . _setClassName ( ) ;
172
+ }
130
173
}
131
174
132
175
ngOnDestroy ( ) : void {
@@ -141,8 +184,7 @@ export class NzIconDirective extends IconDirective implements OnInit, OnChanges,
141
184
ngAfterContentChecked ( ) : void {
142
185
const children = ( this . _elementRef . nativeElement as HTMLElement ) . children ;
143
186
if ( children && children . length && ! this . type ) {
144
- const child = children [ 0 ] ;
145
- this . _iconService . normalizeSvgElement ( child as SVGElement ) ;
187
+ this . _iconService . normalizeSvgElement ( children [ 0 ] as SVGElement ) ;
146
188
}
147
189
}
148
190
}
0 commit comments