39 lines
1.1 KiB
TypeScript
39 lines
1.1 KiB
TypeScript
import { createElement, type ReactElement, type SVGProps } from 'react';
|
|
import type { IconNode } from 'lucide';
|
|
|
|
interface LucideIconProps extends SVGProps<SVGSVGElement> {
|
|
icon: IconNode;
|
|
size?: number;
|
|
}
|
|
|
|
const toReactPropName = (name: string) => name.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
|
|
const LucideIcon = ({ icon, ...props }: LucideIconProps): ReactElement => {
|
|
const svgProps = {
|
|
...props,
|
|
xmlns: 'http://www.w3.org/2000/svg',
|
|
fill: 'none',
|
|
stroke: 'currentColor',
|
|
strokeWidth: 2,
|
|
strokeLinecap: 'round',
|
|
strokeLinejoin: 'round',
|
|
viewBox: '0 0 24 24',
|
|
};
|
|
|
|
const children = icon.map((node, index) => {
|
|
const [tag, attrs] = node;
|
|
const reactAttrs = Object.entries(attrs).reduce<Record<string, string | number | undefined>>(
|
|
(acc, [name, value]) => {
|
|
acc[toReactPropName(name)] = value;
|
|
return acc;
|
|
},
|
|
{},
|
|
);
|
|
|
|
return createElement(tag, { key: `${tag}-${index}`, ...reactAttrs });
|
|
});
|
|
|
|
return createElement('svg', svgProps, children);
|
|
};
|
|
|
|
export default LucideIcon;
|