import type { DIconBaseProps } from './useIconDefinition';
import type { AbstractNode, IconDefinition } from '@ant-design/icons-svg/es/types';
import React from 'react';
import { useIconContext, useIconProps } from './hooks';
import { useIconDefinition } from './useIconDefinition';
interface DRenderIconOptions {
placeholders: {
primaryColor: string;
secondaryColor: string;
};
extraSVGAttrs?: React.SVGAttributes<SVGElement> & { ref: React.ForwardedRef<SVGSVGElement> };
}
function renderIconDefinition(icond: IconDefinition, options: DRenderIconOptions): JSX.Element {
if (typeof icond.icon === 'function') {
const placeholders = options.placeholders;
return renderAbstractNode(icond.icon(placeholders.primaryColor, placeholders.secondaryColor), options);
}
return renderAbstractNode(icond.icon, options);
}
function renderAbstractNode(node: AbstractNode, options: DRenderIconOptions): JSX.Element {
const props: any = Object.assign(node.attrs, node.tag === 'svg' ? options.extraSVGAttrs ?? {} : {});
const children = (node.children ?? []).map((child) => renderAbstractNode(child, options));
return React.createElement(node.tag, props, ...children);
}
export interface DIconContextData {
props?: Omit<DIconProps, 'dIcon'>;
className: (theme: DIconProps['dTheme']) => string;
twoToneColor: (theme: DIconProps['dTheme']) => [string, string];
}
export const DIconContext = React.createContext<DIconContextData | null>(null);
export interface DIconProps extends Omit<DIconBaseProps, 'children'> {
dTwoToneColor?: [string, string];
dIcon: IconDefinition;
}
function Icon(props: DIconProps, ref: React.ForwardedRef<SVGSVGElement>): JSX.Element | null {
const {
dTheme,
dTwoToneColor,
dIcon,
...restProps
} = useIconProps(props);
const context = useIconContext();
const twoToneColorByTheme = context.twoToneColor;
const twoToneColor = dTwoToneColor ?? twoToneColorByTheme(dTheme);
const svgProps = useIconDefinition({ ...restProps, dTheme });
return renderIconDefinition(dIcon, {
placeholders: {
primaryColor: twoToneColor[0],
secondaryColor: twoToneColor[1],
},
extraSVGAttrs: { ref, ...svgProps },
});
}
export const DIcon = React.forwardRef(Icon);