如何在Storybook中为React组件添加可切换图标?
解决ItemsList组件在Storybook中选择图标的问题
1. 调整组件定义
先优化组件的灵活性,支持无图标状态,同时处理列表项的渲染逻辑:
// ItemsList.tsx import React, { ReactElement, ReactNode } from 'react'; import { myIcon1 } from 'src/icons/Icon1'; import { myIcon2 } from 'src/icons/Icon2'; interface ItemsListProps { // 设为可选,支持无图标场景 icon?: ReactElement; header: string; // 新增links属性,直接传入字符串数组生成列表项 links?: string[]; children?: ReactNode; } export const ItemsList = ({ icon, header, links, children }: ItemsListProps) => ( <div> {/* 仅当有图标时渲染 */} {icon && <span className="icon-container">{icon}</span>} <div className="header-text">{header}</div> <ul> {/* 优先使用自定义children,没有则用links生成列表项 */} {children ?? links?.map((link, index) => ( <li key={index}>{link}</li> ))} </ul> </div> );
2. 修改Storybook配置
在Story中建立图标选项与实际组件的映射,将控制面板的字符串选项转换为React元素:
// ItemsList.story.jsx import { ItemsList } from './ItemsList'; // 导入需要的图标组件 import { myIcon1 } from 'src/icons/Icon1'; import { myIcon2 } from 'src/icons/Icon2'; export default { title: 'ItemsList', component: ItemsList, argTypes: { icon: { control: { type: 'radio', options: ['no icon', 'icon 1', 'icon 2'] }, description: '选择要显示的图标', }, header: { type: 'string', defaultValue: 'Header', }, links: { type: 'array', name: '链接列表', defaultValue: ['link 1', 'link 2', 'link 3'], }, }, }; // 建立图标选项和组件的映射关系 const iconMap = { 'icon 1': <myIcon1 />, 'icon 2': <myIcon2 />, 'no icon': null, }; const Template = (args) => { // 将字符串类型的icon参数转换为对应的React元素 const transformedArgs = { ...args, icon: iconMap[args.icon], }; return <ItemsList {...transformedArgs} />; }; export const Default = Template.bind({}); Default.args = { icon: 'no icon', header: 'Header', links: ['link 1', 'link 2', 'link 3'], };
关键说明
- 组件侧:新增
links属性简化列表项传入,同时保留children支持自定义内容,兼顾易用性和灵活性;将icon设为可选,适配无图标场景。 - Story侧:通过
iconMap把控制面板的字符串选项映射为实际图标组件,在Template中完成参数转换,实现可视化选择图标的需求。
内容的提问来源于stack exchange,提问作者Will Black
相关产品推荐
相关产品推荐

