【发布时间】:2021-08-13 11:08:14
【问题描述】:
我有什么
采用以下Icon 组件,该组件旨在采用icon='star' 并渲染适当的SVG。
目前看起来像这样:
import React from "react";
export type IconType = 'star' | 'portfolio' | 'contact';
export type IconSize = 'sm' | 'md' | 'lg';
interface IconProps {
icon: IconType,
size?: IconSize,
}
const iconPaths: Record<IconType, JSX.Element> = {
star: (<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" />),
portfolio: (<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 13v-1m4 1v-3m4 3V8M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z" />),
contact: (<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />),
}
const sizeClasses: Record<IconSize, string> = {
sm: 'w-6 h-6',
md: 'w-12 h-12',
lg: 'w-20 h-20',
}
const Icon: React.FC<IconProps> = ({
icon,
size,
}) => {
const path = iconPaths[icon];
const sizeClass = size ? sizeClasses[size] : '';
return (
<svg
xmlns="http://www.w3.org/2000/svg"
className={`${ sizeClass } block mx-auto`}
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
{ path }
</svg>
);
};
export default Icon;
但我不喜欢那样。
- 它将特定的
className强加在 svg 上。 - 不允许用户随意修改 svg。
- 好像有点不灵活。
我想要什么
我希望能够以一种简单地隐藏路径的方式使用此图标,而将其余的留给我。像这样的:
<Icon icon="star" className={/* whatever I want */} otherAttributes="..." />
任何其他道具将被转发到该 svg。我怎样才能让我的IconProps 接口接受任何可以放在svg 上的东西?
【问题讨论】:
标签: reactjs typescript tsx