Reputation: 85
I currently struggle to finish a story in React story for one of my components : (images below)
My component receives a props from a parent, a boolean and a function to modify this boolean. When I click on a button it should change the value of this boolean (false to true or true to false). I can't seem to test this behaviour on storybook. I don't know if I do things the right way, but it seems impossible to pass a function from my .Stories filecode to my component to test it.
My question is : Am i doing things the right way and is storybook built for this kind of test ?
story file code :
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',
};
My component code :
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>
);
};
Upvotes: 5
Views: 24462
Reputation: 10662
You can add useState
in the Template
function because it's a react component but, make sure that you send these values to the ModelCard
component properly.
const Template: ComponentStory<typeof ModelCard> = (args) => {
const [ecoDesigned, setEcoDesigned] = useState(false);
return <ModelCard {...args} ecoDesigned={ecoDesigned} setEcoDesigned={setEcoDesigned}/>;
};
The args
object will have all the default props. So, you should make sure that these are overwritten.
Upvotes: 11