import classNames from 'classnames'; import * as allIcons from '@ant-design/icons/lib/dist'; import VueIcon from '@ant-design/icons-vue'; import PropTypes from '../_util/vue-types'; import createFromIconfontCN from './IconFont'; import { svgBaseProps, withThemeSuffix, removeTypeTheme, getThemeFromTypeName, alias, } from './utils'; import warning from '../_util/warning'; import { getTwoToneColor, setTwoToneColor } from './twoTonePrimaryColor'; import { filterEmpty, getClass } from '../_util/props-util'; // Initial setting VueIcon.add(...Object.keys(allIcons).map(key => allIcons[key])); setTwoToneColor('#1890ff'); const defaultTheme = 'outlined'; let dangerousTheme; const Icon = { functional: true, name: 'AIcon', props: { type: PropTypes.string, component: PropTypes.any, viewBox: PropTypes.any, spin: PropTypes.bool.def(false), theme: PropTypes.oneOf(['filled', 'outlined', 'twoTone']), twoToneColor: PropTypes.string, }, render(h, context) { const { props, slots, listeners, data } = context; const { // affect inner ... 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`.', ); 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 = {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, }; innerNode = ( {children} ); } 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 = ( ); } // functional component not support nativeOn,https://github.com/vuejs/vue/issues/7526 const iProps = { ...data, on: { ...listeners, ...data.nativeOn }, class: classString, staticClass: '', }; return {innerNode}; }, }; Icon.createFromIconfontCN = createFromIconfontCN; Icon.getTwoToneColor = getTwoToneColor; Icon.setTwoToneColor = setTwoToneColor; /* istanbul ignore next */ Icon.install = function(Vue) { Vue.component(Icon.name, Icon); }; export default Icon;