import React , { ReactNode , Ref , CSSProperties , DetailedHTMLProps , ComponentType } from 'react' ; import { BASE_CLASS_PREFIX } from '../env' ; import cls from 'classnames' ; import '../styles/icons.scss' ; export type IconSize = 'inherit' | 'extra-small' | 'small' | 'default' | 'large' | 'extra-large' ; export interface IconProps extends DetailedHTMLProps < React . HTMLAttributes < HTMLSpanElement > , HTMLSpanElement > { svg : ReactNode ; size ? : IconSize ; spin ? : boolean ; rotate ? : number ; prefixCls ? : string ; type ? : string ; } const Icon = React . forwardRef < HTMLSpanElement , IconProps > ( ( props , ref ) => { const { svg , spin = false , rotate , style , className , prefixCls = BASE_CLASS_PREFIX , type , size = 'default' , ... restProps } = props ; const classes = cls ( `${ prefixCls }-icon` , { [ `${ prefixCls }-icon-extra-small` ] : size === 'extra-small' , [ `${ prefixCls }-icon-small` ] : size === 'small' , [ `${ prefixCls }-icon-default` ] : size === 'default' , [ `${ prefixCls }-icon-large` ] : size === 'large' , [ `${ prefixCls }-icon-extra-large` ] : size === 'extra-large' , [ `${ prefixCls }-icon-spinning` ] : spin === true , [ `${ prefixCls }-icon-${ type }` ] : Boolean ( type ) } , className ) ; const outerStyle = { } ; if ( Number . isSafeInteger ( rotate ) ) { outerStyle . transform = `rotate(${ rotate }deg)` ; } Object . assign ( outerStyle , style ) ; return < span role = "img" ref = { ref } aria - label = { type } className = { classes } style = { outerStyle } { ... restProps } > { svg } < /span>; } ) ; Icon . elementType = 'Icon' ; const convertIcon = ( Svg , iconType ) => { const InnerIcon = React . forwardRef < HTMLSpanElement , Omit < IconProps , 'svg' | 'type' > > ( ( props , ref ) => < Icon svg = { React . createElement ( Svg ) } type = { iconType } ref = { ref as any } { ... props } / > ) ; InnerIcon . elementType = 'Icon' ; return InnerIcon ; } ; export { convertIcon } ; export default Icon ;