import React, { ReactNode, 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, HTMLSpanElement> { svg: ReactNode; size?: IconSize; spin?: boolean; rotate?: number; prefixCls?: string; type?: string; } const Icon = React.forwardRef((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", // 8x8 [`${prefixCls}-icon-small`]: size === "small", // 12x12 [`${prefixCls}-icon-default`]: size === "default", // 16x16 [`${prefixCls}-icon-large`]: size === "large", // 20x20 [`${prefixCls}-icon-extra-large`]: size === "extra-large", // 24x24 [`${prefixCls}-icon-spinning`]: spin === true, [`${prefixCls}-icon-${type}`]: Boolean(type) }, className ); const outerStyle: CSSProperties = {}; if (Number.isSafeInteger(rotate)) { outerStyle.transform = `rotate(${rotate}deg)`; } Object.assign(outerStyle, style); return ( {svg} ); }); Icon.displayName = "Icon"; // @ts-expect-error Custom property for icon type detection // custom icon case Icon.elementType = "Icon"; const convertIcon = (Svg: ComponentType, iconType: string) => { const InnerIcon = React.forwardRef>((props, ref) => ( } {...props} /> )); InnerIcon.displayName = `Icon(${iconType})`; // @ts-expect-error Custom property for icon type detection // builtin icon case InnerIcon.elementType = "Icon"; return InnerIcon; }; export { convertIcon }; export default Icon;