import * as React from 'react'; import classNames from 'classnames'; import * as allIcons from '@ant-design/icons'; import ReactIcon from '@ant-design/icons-react'; import createFromIconfontCN from './IconFont'; import { svgBaseProps, withThemeSuffix } from './utils'; import warning from '../_util/warning'; import { getTwoToneColor, setTwoToneColor } from './twoTonePrimaryColor'; // Initial setting ReactIcon.add(...Object.keys(allIcons).map((key) => (allIcons as any)[key])); setTwoToneColor('#1890ff'); export interface CustomIconComponentProps { width: string | number; height: string | number; fill: string; viewBox?: string; className?: string; style?: React.CSSProperties; ['aria-hidden']?: string; } export type ThemeType = 'filled' | 'outlined' | 'twoTone'; export interface IconProps { type?: string; className?: string; theme?: ThemeType; title?: string; onClick?: React.MouseEventHandler; component?: React.ComponentType; twoToneColor?: string; viewBox?: string; spin?: boolean; style?: React.CSSProperties; svgStyle?: React.CSSProperties; svgClassName?: string; prefixCls?: string; } const Icon: React.SFC = (props) => { const { // affect outter ... title, className, onClick, style, // affect inner ... type, component: Component, viewBox, spin, svgStyle = {}, // children children, // other theme, // default to outlined twoToneColor, } = props; warning( Boolean(type || Component || children), 'Icon should have `type` prop or `component` prop or `children`.', ); const classString = classNames({ [`anticon`]: true, [`anticon-${type}`]: Boolean(type), }, className); const svgClassString = classNames({ [`anticon-spin`]: !!spin || type === 'loading', }); // component > children > type if (Component) { const innerSvgProps: CustomIconComponentProps = { ...svgBaseProps, className: svgClassString, style: svgStyle, viewBox, }; if (!viewBox) { delete innerSvgProps.viewBox; } return ( {children} ); } if (children) { warning( Boolean(viewBox) || React.Children.count(children) === 1 && React.Children.only(children).type === 'use', 'Make sure that you provide correct `viewBox`' + ' prop (default `0 0 1024 1024`) to the icon.', ); const innerSvgProps: CustomIconComponentProps = { ...svgBaseProps, className: svgClassString, style: svgStyle, }; return ( {children} ); } if (typeof type === 'string') { let computedType = type; if (theme) { computedType = withThemeSuffix(type, theme); } // default outlined const computedType = withThemeSuffix( getTypeWithoutTheme(type), theme || 'outlined', ); return ( ); } return ( ); }; export type IconType = typeof Icon & { createFromIconfontCN: typeof createFromIconfontCN; getTwoToneColor: typeof getTwoToneColor; setTwoToneColor: typeof setTwoToneColor; }; Icon.displayName = 'Icon'; (Icon as IconType).createFromIconfontCN = createFromIconfontCN; (Icon as IconType).getTwoToneColor = getTwoToneColor; (Icon as IconType).setTwoToneColor = setTwoToneColor; export default Icon as IconType;