import React, { CSSProperties, DetailedHTMLProps } from 'react';
export type IconSize = { size: '16' | '20' | '24' | '32' | '40' };
type IconSize1 = {
size: '16';
};
type IconSize2 = {
size?: '20';
};
type IconSize3 = {
size: '24';
};
type IconSize4 = {
size: '32';
};
type IconSize5 = {
size: '40';
};
type IconSizeAll = IconSize1 | IconSize2 | IconSize3 | IconSize4 | IconSize5;
export interface IconProps
extends DetailedHTMLProps, HTMLSpanElement> {
svg: React.ReactElement;
spin?: boolean;
rotate?: number;
type?: string;
}
type IconProps2 = IconProps & IconSizeAll;
const Icon = React.forwardRef((props, ref) => {
const { svg, rotate, style, type, color, size = '20', ...restProps } = props;
/**
* span 에 기본 lineHeight 가 있으므로 오버라이드 해야함.
* */
const overrideStyle: Pick = { style: { lineHeight: 0, ...style } };
const svgComponent = React.cloneElement(svg, { color, size, style: overrideStyle.style });
const outerStyle: CSSProperties = {};
if (Number.isSafeInteger(rotate)) outerStyle.transform = `rotate(${rotate}deg)`;
Object.assign(outerStyle, style);
return (
{svgComponent}
);
});
// @ts-ignore
Icon.elementType = 'Icon';
type SvgFn1 = (props: React.SVGProps & IconSize1) => JSX.Element;
type SvgFn2 = (props: React.SVGProps & IconSize2) => JSX.Element;
type SvgFn3 = (props: React.SVGProps & IconSize3) => JSX.Element;
type SvgFn4 = (props: React.SVGProps & IconSize4) => JSX.Element;
type SvgFn5 = (props: React.SVGProps & IconSize5) => JSX.Element;
type SvgFn = SvgFn1 | SvgFn2 | SvgFn3 | SvgFn4 | SvgFn5;
const convertIcon = (Svg: SvgFn, iconType: string) => {
/**
* 일단 size default 로 아이콘 컴포넌트를 만든 다음, cloneElement 로 props 를 바꾼다.
* */
const PreEvaluatedSvgComponent = Svg as SvgFn2;
const InnerIcon = React.forwardRef<
HTMLSpanElement,
Omit & TSize
>((props, ref) => (
} type={iconType} ref={ref as any} {...props} />
));
// @ts-ignore
InnerIcon.elementType = 'Icon';
return InnerIcon;
};
export { convertIcon };
export default Icon;