diff --git a/build/config.js b/build/config.js index 7ff43da6b..dd8c036d7 100644 --- a/build/config.js +++ b/build/config.js @@ -1,5 +1,5 @@ module.exports = { dev: { - componentName: 'grid', // dev components + componentName: 'icon', // dev components }, }; diff --git a/components/icon/__tests__/__snapshots__/index.test.js.snap b/components/icon/__tests__/__snapshots__/index.test.js.snap index 8fc73497d..2be697654 100644 --- a/components/icon/__tests__/__snapshots__/index.test.js.snap +++ b/components/icon/__tests__/__snapshots__/index.test.js.snap @@ -2,8 +2,12 @@ exports[`Icon \`component\` prop can access to svg defs if has children 1`] = ` `; @@ -58,9 +62,9 @@ exports[`Icon should support pass svg paths as children 1`] = ` `; exports[`Icon should support svg vue component 1`] = ` - `; diff --git a/components/icon/__tests__/index.test.js b/components/icon/__tests__/index.test.js index 719737a00..18ccb8526 100644 --- a/components/icon/__tests__/index.test.js +++ b/components/icon/__tests__/index.test.js @@ -3,8 +3,11 @@ import Icon from '..'; import VueIcon from '@ant-design/icons-vue'; import { getThemeFromTypeName, withThemeSuffix } from '../utils'; import { cloneElement } from '../../_util/vnode'; +import mountTest from '../../../tests/shared/mountTest'; describe('Icon', () => { + mountTest(Icon); + it('should render to a ...', () => { const wrapper = mount({ render() { @@ -119,7 +122,7 @@ describe('Icon', () => { return ; }, }); - expect(errorSpy).not.toBeCalled(); + expect(errorSpy).not.toHaveBeenCalled(); }); it('warns', () => { @@ -129,7 +132,7 @@ describe('Icon', () => { }, }); expect(errorSpy).toBeCalledWith( - "Warning: The icon name 'clock-circle-o' already specify a theme 'outlined', the 'theme' prop 'filled' will be ignored.", + "Warning: [antdv: Icon] The icon name 'clock-circle-o' already specify a theme 'outlined', the 'theme' prop 'filled' will be ignored.", ); }); }); diff --git a/components/icon/demo/index.vue b/components/icon/demo/index.vue index b79a34ae2..547b4c80d 100644 --- a/components/icon/demo/index.vue +++ b/components/icon/demo/index.vue @@ -13,14 +13,10 @@ const md = { ## 设计师专属 安装 [Kitchen Sketch 插件 �](https://kitchen.alipay.com),就可以一键拖拽使用 Ant Design 和 Iconfont 的海量图标,还可以关联自有项目。 ## 图标列表 -> 点击图标即可复制代码。 -新版图标可能略有缺失,我们还在持续补充中。 `, us: `# Icon Semantic vector graphics. ## List of icons -> Click the icon and copy the code. -We are still adding two-tone icons right now. `, }; export default { diff --git a/components/icon/demo/two-tone.md b/components/icon/demo/two-tone.md index cfb2c63b9..077d0c657 100644 --- a/components/icon/demo/two-tone.md +++ b/components/icon/demo/two-tone.md @@ -5,7 +5,7 @@ #### Two-tone icon and colorful icon -Specific them property `theme` to `twoTone` to render two-tone icons. You can also set the primary color. +Specify the property `theme` to `twoTone` to render two-tone icons. You can also set the primary color. ```tpl diff --git a/components/icon/index.en-US.md b/components/icon/index.en-US.md index 6f5602124..fa4798c28 100644 --- a/components/icon/index.en-US.md +++ b/components/icon/index.en-US.md @@ -4,26 +4,30 @@ | --- | --- | --- | --- | | type | Type of the ant design icon | string | - | | style | Style properties of icon, like `fontSize` and `color` | CSSProperties | - | -| theme | Theme of the ant design icon | 'filled' \| 'outlined' \| 'twoTone' | 'outlined' | +| theme | Theme variant of the icon | 'filled' \| 'outlined' \| 'twoTone' | 'outlined' | | spin | Rotate icon with animation | boolean | false | | rotate | Rotate degrees (added in 1.4.0, not working in IE9) | number | - | | component | The component used for the root node. This will override the **`type`** property. | ComponentType | - | | twoToneColor | Only support the two-tone icon. Specific the primary color. | string (hex color) | - | +> Note: icon rendering priority of the Icon component is component > children > type. When props is passed, the higher priority item will work, and the lower priority item will be invalid. + ### SVG icons -We introduced SVG icons in `1.2.0` version replacing font icons which brings benefits below: +We introduced SVG icons in version `1.2.0`, replacing font icons. This has the following benefits: -- Complete offline usage of icon, no dependency of CDN font icon file and no more empty square during downloading than no need to deploy icon font files locally either. -- Much more display accuracy in lower-level screens. -- Support multiple colors for icon. -- No need to change built-in icons with overriding styles by providing more props in component. +- Complete offline usage of icons, without dependency on a CDN-hosted font icon file (No more empty square during downloading and no need to deploy icon font files locally either!) +- Much more display accuracy on lower-resolution screens +- The ability to choose icon color +- No need to change built-in icons with overriding styles by providing more props in component -More discussion of SVG icon reference to [#10353](https://github.com/ant-design/ant-design/issues/10353). +More discussion of SVG icon reference at [#10353](https://github.com/ant-design/ant-design/issues/10353). -> ⚠️ About the extra bundle size brought by all SVG icons we imported in 1.2.0, we will provide new API to allow developers importing icons as your need, you can trace [#12011](https://github.com/ant-design/ant-design/issues/12011) for further progress. +> ⚠️ Given the extra bundle size caused by all SVG icons imported in 1.2.0, we will provide a new API to allow developers to import icons as needed, you can track [#12011](https://github.com/ant-design/ant-design/issues/12011) for updates. +> +> While you wait, you can use [webpack plugin](https://github.com/Beven91/webpack-ant-icon-loader) from the community to chunk the icon file. -The properties `theme`, `component` and `twoToneColor` are added in `1.2.0`. The best practice is to pass the property `theme` to every `` components. +The properties `theme`, `component` and `twoToneColor` were added in `1.2.0`. The best practice is to pass the property `theme` to every `` component. ```html diff --git a/components/icon/index.js b/components/icon/index.js index 114dd3020..c7d5cf488 100644 --- a/components/icon/index.js +++ b/components/icon/index.js @@ -41,6 +41,7 @@ function renderIcon(h, locale, context) { children = children.length === 0 ? undefined : children; warning( Boolean(type || Component || children), + 'Icon', 'Icon should have `type` prop or `component` prop or `children`.', ); @@ -61,68 +62,71 @@ function renderIcon(h, locale, context) { } : undefined; - let innerNode; + const innerSvgProps = { + attrs: { + ...svgBaseProps, + viewBox, + }, + class: svgClassString, + style: svgStyle, + }; + if (!viewBox) { + delete innerSvgProps.attrs.viewBox; + } - // component > children > type - if (Component) { - const innerSvgProps = { - attrs: { - ...svgBaseProps, - viewBox, - }, - class: svgClassString, - style: svgStyle, - }; - if (!viewBox) { - delete innerSvgProps.attrs.viewBox; + const renderInnerNode = () => { + // component > children > type + if (Component) { + return {children}; } - - innerNode = {children}; - } - if (children) { - warning( - Boolean(viewBox) || (children.length === 1 && children[0].tag === 'use'), - 'Make sure that you provide correct `viewBox`' + - ' prop (default `0 0 1024 1024`) to the icon.', - ); - const innerSvgProps = { - attrs: { - ...svgBaseProps, - }, - class: svgClassString, - style: svgStyle, - }; - innerNode = ( - - {children} - - ); - } - - if (typeof type === 'string') { - let computedType = type; - if (theme) { - const themeInName = getThemeFromTypeName(type); + if (children) { warning( - !themeInName || theme === themeInName, - `The icon name '${type}' already specify a theme '${themeInName}',` + - ` the 'theme' prop '${theme}' will be ignored.`, + Boolean(viewBox) || (children.length === 1 && children[0].tag === 'use'), + 'Icon', + 'Make sure that you provide correct `viewBox`' + + ' prop (default `0 0 1024 1024`) to the icon.', + ); + const innerSvgProps = { + attrs: { + ...svgBaseProps, + }, + class: svgClassString, + style: svgStyle, + }; + return ( + + {children} + ); } - computedType = withThemeSuffix( - removeTypeTheme(alias(computedType)), - dangerousTheme || theme || defaultTheme, - ); - innerNode = ( - - ); - } + + if (typeof type === 'string') { + let computedType = type; + if (theme) { + const themeInName = getThemeFromTypeName(type); + warning( + !themeInName || theme === themeInName, + 'Icon', + `The icon name '${type}' already specify a theme '${themeInName}',` + + ` the 'theme' prop '${theme}' will be ignored.`, + ); + } + computedType = withThemeSuffix( + removeTypeTheme(alias(computedType)), + dangerousTheme || theme || defaultTheme, + ); + + return ( + + ); + } + }; let iconTabIndex = tabIndex; if (iconTabIndex === undefined && 'click' in listeners) { iconTabIndex = -1; @@ -140,7 +144,7 @@ function renderIcon(h, locale, context) { class: classString, staticClass: '', }; - return {innerNode}; + return {renderInnerNode()}; } const Icon = { diff --git a/components/icon/index.zh-CN.md b/components/icon/index.zh-CN.md index cfa3f3a65..dcc292a11 100644 --- a/components/icon/index.zh-CN.md +++ b/components/icon/index.zh-CN.md @@ -10,6 +10,8 @@ | component | 控制如何渲染图标,通常是一个渲染根标签为 `` 的 `Vue` 组件,**会使 `type` 属性失效** | ComponentType | - | | twoToneColor | 仅适用双色图标。设置双色图标的主要颜色 | string (十六进制颜色) | - | +> 注意:Icon 组件中图标渲染的优先级为 component > children > type, 传入 props 时,优先级高的直接生效,优先级低的则失效。 + ### SVG 图标 在 `1.2.0` 之后,我们使用了 SVG 图标替换了原先的 font 图标,从而带来了以下优势: @@ -21,7 +23,7 @@ 更多讨论可参考:[#10353](https://github.com/ant-design/ant-design/issues/10353)。 -> ⚠️ 1.2.0 之后我们全量引入了所有图标,导致 antd 默认的包体积有一定增加,我们会在不远的未来增加新的 API 来实现图标的按需使用,更多相关讨论可关注:[#12011](https://github.com/ant-design/ant-design/issues/12011)。 +> ⚠️ 1.2.0 之后我们全量引入了所有图标,导致 antd 默认的包体积有一定增加,我们会在不远的未来增加新的 API 来实现图标的按需使用,更多相关讨论可关注:[#12011](https://github.com/ant-design/ant-design/issues/12011)。在此之前,你可以通过来自社区同学的 [webpack 插件](https://github.com/Beven91/webpack-ant-icon-loader)将图标文件拆分。 其中 `theme`, `component`, `twoToneColor` 是 `1.2.x` 版本新增加的属性。最佳实践是给使用的 `` 组件传入属性 `theme` 以明确图标的主题风格。例如: diff --git a/components/icon/utils.js b/components/icon/utils.js index 45dac5a7a..1a48df9b2 100644 --- a/components/icon/utils.js +++ b/components/icon/utils.js @@ -42,17 +42,36 @@ export function withThemeSuffix(type, theme) { } else if (theme === 'twoTone') { result += '-twotone'; } else { - warning(false, `This icon '${type}' has unknown theme '${theme}'`); + warning(false, 'Icon', `This icon '${type}' has unknown theme '${theme}'`); } return result; } // For alias or compatibility export function alias(type) { + let newType = type; switch (type) { case 'cross': - return 'close'; + newType = 'close'; + break; + // https://github.com/ant-design/ant-design/issues/13007 + case 'interation': + newType = 'interaction'; + break; + // https://github.com/ant-design/ant-design/issues/16810 + case 'canlendar': + newType = 'calendar'; + break; + // https://github.com/ant-design/ant-design/issues/17448 + case 'colum-height': + newType = 'column-height'; + break; default: } - return type; + warning( + newType === type, + 'Icon', + `Icon '${type}' was a typo and is now deprecated, please use '${newType}' instead.`, + ); + return newType; } diff --git a/site/theme/template/IconDisplay/CopyableIcon.vue b/site/theme/template/IconDisplay/CopyableIcon.vue index ececa30ca..0910972b2 100644 --- a/site/theme/template/IconDisplay/CopyableIcon.vue +++ b/site/theme/template/IconDisplay/CopyableIcon.vue @@ -13,7 +13,12 @@