feat: update icon
parent
3a2977a2ed
commit
3c4cc8ea77
|
@ -15,6 +15,7 @@ Use tag `<Icon />` to create an icon and set its type in the `type` prop. Specif
|
|||
<a-icon type="setting" theme="filled" />
|
||||
<a-icon type="smile" theme="outlined" />
|
||||
<a-icon type="sync" spin />
|
||||
<a-icon type="smile" :rotate="180" />
|
||||
<a-icon type="loading" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
| style | Style properties of icon, like `fontSize` and `color` | CSSProperties | - |
|
||||
| theme | Theme of the ant design icon | 'filled' \| 'outlined' \| 'twoTone' | 'outlined' |
|
||||
| spin | Rotate icon with animation | boolean | false |
|
||||
| rotate | Rotate degrees (added in 1.40.0, not working in IE9) | number | - |
|
||||
| component | The component used for the root node. This will override the **`type`** property. | ComponentType<CustomIconComponentProps\> | - |
|
||||
| twoToneColor | Only support the two-tone icon. Specific the primary color. | string (hex color) | - |
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
alias,
|
||||
} from './utils';
|
||||
import warning from '../_util/warning';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
import { getTwoToneColor, setTwoToneColor } from './twoTonePrimaryColor';
|
||||
import { filterEmpty, getClass } from '../_util/props-util';
|
||||
|
||||
|
@ -20,109 +21,146 @@ setTwoToneColor('#1890ff');
|
|||
const defaultTheme = 'outlined';
|
||||
let dangerousTheme;
|
||||
|
||||
function renderIcon(h, locale, context) {
|
||||
const { props, slots, listeners, data } = context;
|
||||
const {
|
||||
// affect inner <svg>...</svg>
|
||||
type,
|
||||
component: Component,
|
||||
viewBox,
|
||||
spin,
|
||||
// other
|
||||
theme, // default to outlined
|
||||
twoToneColor,
|
||||
rotate,
|
||||
tabIndex,
|
||||
} = props;
|
||||
const slotsMap = slots();
|
||||
let children = filterEmpty(slotsMap.default);
|
||||
children = children.length === 0 ? undefined : children;
|
||||
warning(
|
||||
Boolean(type || Component || children),
|
||||
'Icon should have `type` prop or `component` prop or `children`.',
|
||||
);
|
||||
|
||||
const classString = classNames({
|
||||
...getClass(context),
|
||||
[`anticon`]: true,
|
||||
[`anticon-${type}`]: !!type,
|
||||
});
|
||||
|
||||
const svgClassString = classNames({
|
||||
[`anticon-spin`]: !!spin || type === 'loading',
|
||||
});
|
||||
|
||||
const svgStyle = rotate
|
||||
? {
|
||||
msTransform: `rotate(${rotate}deg)`,
|
||||
transform: `rotate(${rotate}deg)`,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
let innerNode;
|
||||
|
||||
// component > children > type
|
||||
if (Component) {
|
||||
const innerSvgProps = {
|
||||
attrs: {
|
||||
...svgBaseProps,
|
||||
style: svgStyle,
|
||||
viewBox,
|
||||
},
|
||||
class: svgClassString,
|
||||
};
|
||||
if (!viewBox) {
|
||||
delete innerSvgProps.attrs.viewBox;
|
||||
}
|
||||
|
||||
innerNode = <Component {...innerSvgProps}>{children}</Component>;
|
||||
}
|
||||
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,
|
||||
};
|
||||
innerNode = (
|
||||
<svg {...innerSvgProps} viewBox={viewBox}>
|
||||
{children}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
let computedType = type;
|
||||
if (theme) {
|
||||
const themeInName = getThemeFromTypeName(type);
|
||||
warning(
|
||||
!themeInName || theme === themeInName,
|
||||
`The icon name '${type}' already specify a theme '${themeInName}',` +
|
||||
` the 'theme' prop '${theme}' will be ignored.`,
|
||||
);
|
||||
}
|
||||
computedType = withThemeSuffix(
|
||||
removeTypeTheme(alias(computedType)),
|
||||
dangerousTheme || theme || defaultTheme,
|
||||
);
|
||||
innerNode = (
|
||||
<VueIcon
|
||||
class={svgClassString}
|
||||
type={computedType}
|
||||
primaryColor={twoToneColor}
|
||||
style={svgStyle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
let iconTabIndex = tabIndex;
|
||||
if (iconTabIndex === undefined && ('click' in listeners)) {
|
||||
iconTabIndex = -1;
|
||||
}
|
||||
const { attrs, ...restDataProps } = data;
|
||||
// functional component not support nativeOn,https://github.com/vuejs/vue/issues/7526
|
||||
const iProps = {
|
||||
...restDataProps,
|
||||
attrs: {
|
||||
...attrs,
|
||||
'aria-label': type && `${locale.icon}: ${type}`,
|
||||
tabIndex: iconTabIndex,
|
||||
},
|
||||
on: { ...listeners, ...data.nativeOn },
|
||||
class: classString,
|
||||
staticClass: '',
|
||||
};
|
||||
return <i {...iProps}>{innerNode}</i>;
|
||||
}
|
||||
|
||||
const Icon = {
|
||||
functional: true,
|
||||
name: 'AIcon',
|
||||
props: {
|
||||
tabIndex: PropTypes.number,
|
||||
type: PropTypes.string,
|
||||
component: PropTypes.any,
|
||||
viewBox: PropTypes.any,
|
||||
spin: PropTypes.bool.def(false),
|
||||
rotate: PropTypes.number,
|
||||
theme: PropTypes.oneOf(['filled', 'outlined', 'twoTone']),
|
||||
twoToneColor: PropTypes.string,
|
||||
role: PropTypes.string,
|
||||
},
|
||||
render(h, context) {
|
||||
const { props, slots, listeners, data } = context;
|
||||
const {
|
||||
// affect inner <svg>...</svg>
|
||||
type,
|
||||
component: Component,
|
||||
viewBox,
|
||||
spin,
|
||||
// other
|
||||
theme, // default to outlined
|
||||
twoToneColor,
|
||||
} = props;
|
||||
const slotsMap = slots();
|
||||
let children = filterEmpty(slotsMap.default);
|
||||
children = children.length === 0 ? undefined : children;
|
||||
warning(
|
||||
Boolean(type || Component || children),
|
||||
'Icon should have `type` prop or `component` prop or `children`.',
|
||||
return (
|
||||
<LocaleReceiver
|
||||
componentName="Icon"
|
||||
scopedSlots={{ default: (locale) => renderIcon(h, locale, context) }}
|
||||
/>
|
||||
);
|
||||
|
||||
const classString = classNames({
|
||||
...getClass(context),
|
||||
[`anticon`]: true,
|
||||
[`anticon-${type}`]: !!type,
|
||||
});
|
||||
|
||||
const svgClassString = classNames({
|
||||
[`anticon-spin`]: !!spin || type === 'loading',
|
||||
});
|
||||
|
||||
let innerNode;
|
||||
|
||||
// component > children > type
|
||||
if (Component) {
|
||||
const innerSvgProps = {
|
||||
attrs: {
|
||||
...svgBaseProps,
|
||||
viewBox,
|
||||
},
|
||||
class: svgClassString,
|
||||
};
|
||||
if (!viewBox) {
|
||||
delete innerSvgProps.attrs.viewBox;
|
||||
}
|
||||
|
||||
innerNode = <Component {...innerSvgProps}>{children}</Component>;
|
||||
}
|
||||
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,
|
||||
};
|
||||
innerNode = (
|
||||
<svg {...innerSvgProps} viewBox={viewBox}>
|
||||
{children}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
let computedType = type;
|
||||
if (theme) {
|
||||
const themeInName = getThemeFromTypeName(type);
|
||||
warning(
|
||||
!themeInName || theme === themeInName,
|
||||
`The icon name '${type}' already specify a theme '${themeInName}',` +
|
||||
` the 'theme' prop '${theme}' will be ignored.`,
|
||||
);
|
||||
}
|
||||
computedType = withThemeSuffix(
|
||||
removeTypeTheme(alias(computedType)),
|
||||
dangerousTheme || theme || defaultTheme,
|
||||
);
|
||||
innerNode = (
|
||||
<VueIcon class={svgClassString} type={computedType} primaryColor={twoToneColor} />
|
||||
);
|
||||
}
|
||||
// functional component not support nativeOn,https://github.com/vuejs/vue/issues/7526
|
||||
const iProps = {
|
||||
...data,
|
||||
on: { ...listeners, ...data.nativeOn },
|
||||
class: classString,
|
||||
staticClass: '',
|
||||
};
|
||||
return <i {...iProps}>{innerNode}</i>;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
| style | 设置图标的样式,例如 `fontSize` 和 `color` | CSSProperties | - |
|
||||
| theme | 图标主题风格。可选实心、描线、双色等主题风格,适用于官方图标 | 'filled' \| 'outlined' \| 'twoTone' | 'outlined' |
|
||||
| spin | 是否有旋转动画 | boolean | false |
|
||||
| rotate | 图标旋转角度(1.40.0 后新增,IE9 无效) | number | - |
|
||||
| component | 控制如何渲染图标,通常是一个渲染根标签为 `<svg>` 的 `Vue` 组件,**会使 `type` 属性失效** | ComponentType<CustomIconComponentProps\> | - |
|
||||
| twoToneColor | 仅适用双色图标。设置双色图标的主要颜色 | string (十六进制颜色) | - |
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import PropTypes from '../_util/vue-types';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
import defaultLocale from '../locale-provider/default';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
|
||||
import Spin from '../spin';
|
||||
|
|
Loading…
Reference in New Issue