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 } = 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(type)), dangerousTheme || theme || defaultTheme, ) innerNode = ( ) } 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