React Storybook 在 args 中传递函数
React Storybook passing functions in args
我目前正在努力为我的一个组件在 React 故事中完成一个故事:(下图)
我的组件从父级接收一个道具、一个布尔值和一个修改此布尔值的函数。当我点击一个按钮时,它应该改变这个布尔值(false 到 true 或 true 到 false)。
我似乎无法在故事书中测试这种行为。我不知道我是否以正确的方式做事,但似乎不可能将函数从我的 .Stories 文件代码传递到我的组件以对其进行测试。
我的问题是:我做事的方式是否正确?故事书是否专为此类测试而设计?
故事文件代码:
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { ModelCard } from './';
export default {
title: 'ModelCard',
component: ModelCard,
argTypes: {
yearProduct: { control : 'text'},
ecoDesigned: { control: 'boolean'},
titleProduct: {control: 'text'},
photoProduct: {control: 'text'},
setEcoDesigned: {action: 'clicked'}
}
} as ComponentMeta<typeof ModelCard>;
const Template: ComponentStory<typeof ModelCard> = (args) => <ModelCard {...args}/>;
export const ModelCardCompleteControls = Template.bind({});
ModelCardCompleteControls.args = {
yearProduct: '2018',
ecoDesigned: false,
titleProduct: '66180 - W200 S | 1019507 - ATHLLE Watches or Stopwatche 7026 2021 | GEDS',
photoProduct: 'https://picsum.photos/200',
};
我的组件代码:
import React from 'react';
import { useState } from 'react';
import { VtmnButton, VtmnIcon } from '@vtmn/react';
import { EcoDesignedDot } from './EcoDesignedDot';
import './modelcard.scss';
interface ModelCardProps {
photoProduct: string;
yearProduct: string,
titleProduct: string,
ecoDesigned: boolean;
setEcoDesigned: (ecoDesigned: boolean) => void;
}
export const ModelCard = ({ yearProduct, titleProduct, photoProduct, ecoDesigned, setEcoDesigned }: ModelCardProps) => {
const [open, setOpen] = useState(false);
return (
<article className="model-card">
<section className="vtmn-grid vtmn-grid-cols-12 vtmn-items-center vtmn-space-y-5">
<p className="vtmn-col-span-1">{yearProduct}</p>
<img className="vtmn-col-span-1"
style={{ borderRadius: 5 }}
src={photoProduct} width={60}
height={60} />
<p className="vtmn-col-span-6">{titleProduct}</p>
<div className="vtmn-col-span-3">
<EcoDesignedDot ecoDesigned={ecoDesigned}/>
</div>
<div className="vtmn-col-span-1" onClick={() => setOpen(!open)}>
<VtmnIcon value="arrow-up-s-line" className={open ? 'reversed_angle' : 'original_angle'} />
</div>
</section>
<section className="vtmn-grid vtmn-grid-cols-12">
{
open && <div className="vtmn-col-start-3 vtmn-col-span-5">
<p>
Votre produit est-il éco-design ?
</p>
<VtmnButton onClick={() => setEcoDesigned(true)} variant={ecoDesigned ? 'primary' : 'secondary'} size="medium">Oui</VtmnButton> // This is what I'm talking about
<VtmnButton onClick={() => setEcoDesigned(false)} variant={ecoDesigned ? 'secondary' : 'primary'} size="medium">Non</VtmnButton> // This is what I'm talking about
</div>
}
</section>
</article>
);
};
您可以在 Template
函数中添加 useState
因为它是一个 React 组件,但是请确保将这些值正确地发送到 ModelCard
组件。
const Template: ComponentStory<typeof ModelCard> = (args) => {
const [ecoDesigned, setEcoDesigned] = useState(false);
return <ModelCard {...args} ecoDesigned={ecoDesigned} setEcoDesigned={setEcoDesigned}/>;
};
args
对象将拥有所有默认道具。所以,你应该确保这些被覆盖。
我目前正在努力为我的一个组件在 React 故事中完成一个故事:(下图)
我的组件从父级接收一个道具、一个布尔值和一个修改此布尔值的函数。当我点击一个按钮时,它应该改变这个布尔值(false 到 true 或 true 到 false)。 我似乎无法在故事书中测试这种行为。我不知道我是否以正确的方式做事,但似乎不可能将函数从我的 .Stories 文件代码传递到我的组件以对其进行测试。
我的问题是:我做事的方式是否正确?故事书是否专为此类测试而设计?
故事文件代码:
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { ModelCard } from './';
export default {
title: 'ModelCard',
component: ModelCard,
argTypes: {
yearProduct: { control : 'text'},
ecoDesigned: { control: 'boolean'},
titleProduct: {control: 'text'},
photoProduct: {control: 'text'},
setEcoDesigned: {action: 'clicked'}
}
} as ComponentMeta<typeof ModelCard>;
const Template: ComponentStory<typeof ModelCard> = (args) => <ModelCard {...args}/>;
export const ModelCardCompleteControls = Template.bind({});
ModelCardCompleteControls.args = {
yearProduct: '2018',
ecoDesigned: false,
titleProduct: '66180 - W200 S | 1019507 - ATHLLE Watches or Stopwatche 7026 2021 | GEDS',
photoProduct: 'https://picsum.photos/200',
};
我的组件代码:
import React from 'react';
import { useState } from 'react';
import { VtmnButton, VtmnIcon } from '@vtmn/react';
import { EcoDesignedDot } from './EcoDesignedDot';
import './modelcard.scss';
interface ModelCardProps {
photoProduct: string;
yearProduct: string,
titleProduct: string,
ecoDesigned: boolean;
setEcoDesigned: (ecoDesigned: boolean) => void;
}
export const ModelCard = ({ yearProduct, titleProduct, photoProduct, ecoDesigned, setEcoDesigned }: ModelCardProps) => {
const [open, setOpen] = useState(false);
return (
<article className="model-card">
<section className="vtmn-grid vtmn-grid-cols-12 vtmn-items-center vtmn-space-y-5">
<p className="vtmn-col-span-1">{yearProduct}</p>
<img className="vtmn-col-span-1"
style={{ borderRadius: 5 }}
src={photoProduct} width={60}
height={60} />
<p className="vtmn-col-span-6">{titleProduct}</p>
<div className="vtmn-col-span-3">
<EcoDesignedDot ecoDesigned={ecoDesigned}/>
</div>
<div className="vtmn-col-span-1" onClick={() => setOpen(!open)}>
<VtmnIcon value="arrow-up-s-line" className={open ? 'reversed_angle' : 'original_angle'} />
</div>
</section>
<section className="vtmn-grid vtmn-grid-cols-12">
{
open && <div className="vtmn-col-start-3 vtmn-col-span-5">
<p>
Votre produit est-il éco-design ?
</p>
<VtmnButton onClick={() => setEcoDesigned(true)} variant={ecoDesigned ? 'primary' : 'secondary'} size="medium">Oui</VtmnButton> // This is what I'm talking about
<VtmnButton onClick={() => setEcoDesigned(false)} variant={ecoDesigned ? 'secondary' : 'primary'} size="medium">Non</VtmnButton> // This is what I'm talking about
</div>
}
</section>
</article>
);
};
您可以在 Template
函数中添加 useState
因为它是一个 React 组件,但是请确保将这些值正确地发送到 ModelCard
组件。
const Template: ComponentStory<typeof ModelCard> = (args) => {
const [ecoDesigned, setEcoDesigned] = useState(false);
return <ModelCard {...args} ecoDesigned={ecoDesigned} setEcoDesigned={setEcoDesigned}/>;
};
args
对象将拥有所有默认道具。所以,你应该确保这些被覆盖。