Skip to content

Commit 3c4cc8e

Browse files
committed
feat: update icon
1 parent 3a2977a commit 3c4cc8e

File tree

5 files changed

+131
-92
lines changed

5 files changed

+131
-92
lines changed

components/icon/demo/basic.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Use tag `<Icon />` to create an icon and set its type in the `type` prop. Specif
1515
<a-icon type="setting" theme="filled" />
1616
<a-icon type="smile" theme="outlined" />
1717
<a-icon type="sync" spin />
18+
<a-icon type="smile" :rotate="180" />
1819
<a-icon type="loading" />
1920
</div>
2021
</template>

components/icon/index.en-US.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
| style | Style properties of icon, like `fontSize` and `color` | CSSProperties | - |
77
| theme | Theme of the ant design icon | 'filled' \| 'outlined' \| 'twoTone' | 'outlined' |
88
| spin | Rotate icon with animation | boolean | false |
9+
| rotate | Rotate degrees (added in 1.40.0, not working in IE9) | number | - |
910
| component | The component used for the root node. This will override the **`type`** property. | ComponentType<CustomIconComponentProps\> | - |
1011
| twoToneColor | Only support the two-tone icon. Specific the primary color. | string (hex color) | - |
1112

components/icon/index.js

Lines changed: 128 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
alias,
1212
} from './utils';
1313
import warning from '../_util/warning';
14+
import LocaleReceiver from '../locale-provider/LocaleReceiver';
1415
import { getTwoToneColor, setTwoToneColor } from './twoTonePrimaryColor';
1516
import { filterEmpty, getClass } from '../_util/props-util';
1617

@@ -20,109 +21,146 @@ setTwoToneColor('#1890ff');
2021
const defaultTheme = 'outlined';
2122
let dangerousTheme;
2223

24+
function renderIcon(h, locale, context) {
25+
const { props, slots, listeners, data } = context;
26+
const {
27+
// affect inner <svg>...</svg>
28+
type,
29+
component: Component,
30+
viewBox,
31+
spin,
32+
// other
33+
theme, // default to outlined
34+
twoToneColor,
35+
rotate,
36+
tabIndex,
37+
} = props;
38+
const slotsMap = slots();
39+
let children = filterEmpty(slotsMap.default);
40+
children = children.length === 0 ? undefined : children;
41+
warning(
42+
Boolean(type || Component || children),
43+
'Icon should have `type` prop or `component` prop or `children`.',
44+
);
45+
46+
const classString = classNames({
47+
...getClass(context),
48+
[`anticon`]: true,
49+
[`anticon-${type}`]: !!type,
50+
});
51+
52+
const svgClassString = classNames({
53+
[`anticon-spin`]: !!spin || type === 'loading',
54+
});
55+
56+
const svgStyle = rotate
57+
? {
58+
msTransform: `rotate(${rotate}deg)`,
59+
transform: `rotate(${rotate}deg)`,
60+
}
61+
: undefined;
62+
63+
let innerNode;
64+
65+
// component > children > type
66+
if (Component) {
67+
const innerSvgProps = {
68+
attrs: {
69+
...svgBaseProps,
70+
style: svgStyle,
71+
viewBox,
72+
},
73+
class: svgClassString,
74+
};
75+
if (!viewBox) {
76+
delete innerSvgProps.attrs.viewBox;
77+
}
78+
79+
innerNode = <Component {...innerSvgProps}>{children}</Component>;
80+
}
81+
if (children) {
82+
warning(
83+
Boolean(viewBox) || (children.length === 1 && children[0].tag === 'use'),
84+
'Make sure that you provide correct `viewBox`' +
85+
' prop (default `0 0 1024 1024`) to the icon.',
86+
);
87+
const innerSvgProps = {
88+
attrs: {
89+
...svgBaseProps,
90+
},
91+
class: svgClassString,
92+
};
93+
innerNode = (
94+
<svg {...innerSvgProps} viewBox={viewBox}>
95+
{children}
96+
</svg>
97+
);
98+
}
99+
100+
if (typeof type === 'string') {
101+
let computedType = type;
102+
if (theme) {
103+
const themeInName = getThemeFromTypeName(type);
104+
warning(
105+
!themeInName || theme === themeInName,
106+
`The icon name '${type}' already specify a theme '${themeInName}',` +
107+
` the 'theme' prop '${theme}' will be ignored.`,
108+
);
109+
}
110+
computedType = withThemeSuffix(
111+
removeTypeTheme(alias(computedType)),
112+
dangerousTheme || theme || defaultTheme,
113+
);
114+
innerNode = (
115+
<VueIcon
116+
class={svgClassString}
117+
type={computedType}
118+
primaryColor={twoToneColor}
119+
style={svgStyle}
120+
/>
121+
);
122+
}
123+
let iconTabIndex = tabIndex;
124+
if (iconTabIndex === undefined && ('click' in listeners)) {
125+
iconTabIndex = -1;
126+
}
127+
const { attrs, ...restDataProps } = data;
128+
// functional component not support nativeOn,https://github.com/vuejs/vue/issues/7526
129+
const iProps = {
130+
...restDataProps,
131+
attrs: {
132+
...attrs,
133+
'aria-label': type && `${locale.icon}: ${type}`,
134+
tabIndex: iconTabIndex,
135+
},
136+
on: { ...listeners, ...data.nativeOn },
137+
class: classString,
138+
staticClass: '',
139+
};
140+
return <i {...iProps}>{innerNode}</i>;
141+
}
142+
23143
const Icon = {
24144
functional: true,
25145
name: 'AIcon',
26146
props: {
147+
tabIndex: PropTypes.number,
27148
type: PropTypes.string,
28149
component: PropTypes.any,
29150
viewBox: PropTypes.any,
30151
spin: PropTypes.bool.def(false),
152+
rotate: PropTypes.number,
31153
theme: PropTypes.oneOf(['filled', 'outlined', 'twoTone']),
32154
twoToneColor: PropTypes.string,
155+
role: PropTypes.string,
33156
},
34157
render(h, context) {
35-
const { props, slots, listeners, data } = context;
36-
const {
37-
// affect inner <svg>...</svg>
38-
type,
39-
component: Component,
40-
viewBox,
41-
spin,
42-
// other
43-
theme, // default to outlined
44-
twoToneColor,
45-
} = props;
46-
const slotsMap = slots();
47-
let children = filterEmpty(slotsMap.default);
48-
children = children.length === 0 ? undefined : children;
49-
warning(
50-
Boolean(type || Component || children),
51-
'Icon should have `type` prop or `component` prop or `children`.',
158+
return (
159+
<LocaleReceiver
160+
componentName="Icon"
161+
scopedSlots={{ default: (locale) => renderIcon(h, locale, context) }}
162+
/>
52163
);
53-
54-
const classString = classNames({
55-
...getClass(context),
56-
[`anticon`]: true,
57-
[`anticon-${type}`]: !!type,
58-
});
59-
60-
const svgClassString = classNames({
61-
[`anticon-spin`]: !!spin || type === 'loading',
62-
});
63-
64-
let innerNode;
65-
66-
// component > children > type
67-
if (Component) {
68-
const innerSvgProps = {
69-
attrs: {
70-
...svgBaseProps,
71-
viewBox,
72-
},
73-
class: svgClassString,
74-
};
75-
if (!viewBox) {
76-
delete innerSvgProps.attrs.viewBox;
77-
}
78-
79-
innerNode = <Component {...innerSvgProps}>{children}</Component>;
80-
}
81-
if (children) {
82-
warning(
83-
Boolean(viewBox) || (children.length === 1 && children[0].tag === 'use'),
84-
'Make sure that you provide correct `viewBox`' +
85-
' prop (default `0 0 1024 1024`) to the icon.',
86-
);
87-
const innerSvgProps = {
88-
attrs: {
89-
...svgBaseProps,
90-
},
91-
class: svgClassString,
92-
};
93-
innerNode = (
94-
<svg {...innerSvgProps} viewBox={viewBox}>
95-
{children}
96-
</svg>
97-
);
98-
}
99-
100-
if (typeof type === 'string') {
101-
let computedType = type;
102-
if (theme) {
103-
const themeInName = getThemeFromTypeName(type);
104-
warning(
105-
!themeInName || theme === themeInName,
106-
`The icon name '${type}' already specify a theme '${themeInName}',` +
107-
` the 'theme' prop '${theme}' will be ignored.`,
108-
);
109-
}
110-
computedType = withThemeSuffix(
111-
removeTypeTheme(alias(computedType)),
112-
dangerousTheme || theme || defaultTheme,
113-
);
114-
innerNode = (
115-
<VueIcon class={svgClassString} type={computedType} primaryColor={twoToneColor} />
116-
);
117-
}
118-
// functional component not support nativeOn,https://github.com/vuejs/vue/issues/7526
119-
const iProps = {
120-
...data,
121-
on: { ...listeners, ...data.nativeOn },
122-
class: classString,
123-
staticClass: '',
124-
};
125-
return <i {...iProps}>{innerNode}</i>;
126164
},
127165
};
128166

components/icon/index.zh-CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
| style | 设置图标的样式,例如 `fontSize``color` | CSSProperties | - |
88
| theme | 图标主题风格。可选实心、描线、双色等主题风格,适用于官方图标 | 'filled' \| 'outlined' \| 'twoTone' | 'outlined' |
99
| spin | 是否有旋转动画 | boolean | false |
10+
| rotate | 图标旋转角度(1.40.0 后新增,IE9 无效) | number | - |
1011
| component | 控制如何渲染图标,通常是一个渲染根标签为 `<svg>``Vue` 组件,**会使 `type` 属性失效** | ComponentType<CustomIconComponentProps\> | - |
1112
| twoToneColor | 仅适用双色图标。设置双色图标的主要颜色 | string (十六进制颜色) | - |
1213

components/list/index.jsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import PropTypes from '../_util/vue-types';
22
import classNames from 'classnames';
33
import omit from 'omit.js';
4-
import LocaleReceiver from '../locale-provider/LocaleReceiver';
5-
import defaultLocale from '../locale-provider/default';
64
import { ConfigConsumerProps } from '../config-provider';
75

86
import Spin from '../spin';

0 commit comments

Comments
 (0)