You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Storybook与React中为图标传递属性

解决Storybook + React中SVG图标传递颜色、尺寸Props的方案

1. 先让SVG图标支持接收Props

你当前的ICONS是直接渲染静态组件,没法传参数,得改成能动态接收props的函数形式:

const ICONS = {
  icon: (props) => <Icon {...props} />,
  icon2: (props) => <Icon2 {...props} />
};

关键前提:确保SVG内部的path或图形元素设置了fill="currentColor",这样才能通过color属性控制图标颜色;如果是尺寸,SVG要支持通过width/height调整大小(默认导入的SVG组件都支持)。

2. 在Storybook中添加图标控制参数

修改argTypes,新增颜色、尺寸的控制面板:

export default {
  title: "Components/Button",
  component: Button,
  argTypes: {
    handleClick: { action: "handleClick" },
    icon: {
      control: {
        type: "select",
        options: [undefined, ...Object.keys(ICONS)],
      },
    },
    iconColor: {
      control: "color",
      description: "设置图标颜色"
    },
    iconSize: {
      control: "number",
      description: "设置图标尺寸(单位:px)",
      defaultValue: 24
    }
  },
};

3. 修改Template传递Props给图标

把Storybook的控制参数传递给选中的图标组件:

const Template = ({ iconName, iconColor, iconSize, ...rest }) => {
  const IconComponent = ICONS[iconName];
  const icon = IconComponent ? (
    <IconComponent 
      style={{ 
        color: iconColor, 
        width: `${iconSize}px`, 
        height: `${iconSize}px` 
      }} 
    />
  ) : undefined;
  return <Button icon={icon} {...rest} />;
};

如果你的SVG是自己封装的、支持独立的color/size props,也可以直接传:

<IconComponent color={iconColor} size={iconSize} />

4. (可选)在Button组件内处理图标Props

如果不想在Template里处理,也可以把iconColor/iconSize传给Button,再通过React.cloneElement给图标追加属性:
修改Button.js:

import React from 'react';

// 确保Button组件接收iconColor、iconSize作为props
const Button = ({ handleClick, style, size, disabled, icon, content, iconColor, iconSize }) => {
  const styledIcon = icon ? React.cloneElement(icon, {
    style: {
      color: iconColor,
      width: `${iconSize}px`,
      height: `${iconSize}px`,
      ...icon.props.style
    }
  }) : null;

  return (
    <button
      onClick={handleClick}
      style={style}
      className={`button ${size === "m" ? "button-m" : "button-s"}`}
      disabled={disabled}
    >
      <div>{styledIcon}</div>
      <span
        style={styleButton}
        className={size === "m" ? "button-content-m" : "button-content-s"}
      >
        {content}
      </span>
    </button>
  );
};

内容的提问来源于stack exchange,提问作者AlanLipschutz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:30:44