storybook์ UI ์ปดํฌ๋ํธ ๊ฐ๋ฐ ๋๊ตฌ์ด๋ค.
์ค์ ์ปดํฌ๋ํธ์ ์ผ์ผํ ์คํ์ผ์ ์
ํ ํ์ ์์ด,
๋ค์ํ ์ปดํฌ๋ํธ๋ค์ ๋ฐ๋ก ๋ง๋ค์ด์ ์ ์ฉ์์ผ ๋ณผ ์ ์๋ค.
์ค์น
npx storybook init
์คํ
npx storybook init
torybook ์ค์น๊ฐ ์๋ฃ๋๋ฉด, /.storybook
ํด๋์ /src/stories
ํด๋๊ฐ ์์ฑ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
/.storybook
ํด๋์๋ Storybook ๊ด๋ จ ์ค์ ํ์ผ์ด,
/src/stories
ํด๋์๋ Storybook ์์ ํ์ผ๋ค์ด ๋ค์ด์์ต๋๋ค.
import React from "react";
// title์ h1 ์์์ textContent, textColor์ ๊ธ์์์ด ๋๋ props์
๋๋ค.
const Title = ({title, textColor}) => (
<h1 style={{color: textColor}}>{title}</h1>
);
export default Title;
์ฐ์ Title ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ฏ๋ก ๋ถ๋ฌ์จ๋ค.
export default { title: component: argTypes: ... }
title :
์ปดํฌ๋ํธ ์ด๋ฆ์ผ๋ก, '/'๋ฅผ ๋ฃ์ด ์นดํ ๊ณ ๋ฆฌํ ํ ์ ์์ต๋๋ค.
์ดํ ์์์์ ์กฐ๊ธ ๋ ์์ธํ ์ค๋ช ํฉ๋๋ค.component :
์ด๋ค ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ ธ์์ ์คํ ๋ฆฌ๋ก ๋ง๋ค ๊ฒ์ธ์ง ๋ช ์ํฉ๋๋ค.argTypes :
์ปดํฌ๋ํธ์ ํ์ํ ์ ๋ฌ์ธ์์ ์ข ๋ฅ์ ํ์ ์ ์ ํด์ค๋๋ค.
์ง๊ธ์ title, textColor์ด๋ผ๋ ์ ๋ฌ์ธ์์ text ํ์ ์ด ํ์ํจ์ ์๋ฏธํฉ๋๋ค.
import Title from "./Title";
//export default์๋ story์ ์ ํ json ํ์ผ์ฒ๋ผ ์์์ ๋ช
์ธํ๋ค๊ณ ์๊ฐํ์.
export default {
title: "Practice/Title",
component: Title,
argTypes: {
title: { control: "text" },
textColor: {control: "text"}
}
}
// ํ
ํ๋ฆฟ์ผ๋ก props๋ฅผ ์ ๋ฌ๋ฐ์ ๋ด๋ ค์ฃผ์.
// ํ
ํ๋ฆฟ์ ๋ง๋ค์ด์ค๋๋ค. ์ด ํ
ํ๋ฆฟ์์๋
// Title ์ปดํฌ๋ํธ๊ฐ args๋ฅผ ์ ๋ฌ๋ฐ์ props๋ก ๋ด๋ ค์ค๋๋ค.
const Template = (args) => <Title {...args} />
// Storybook์์ ํ์ธํ๊ณ ์ถ์ ์ปดํฌ๋ํธ๋ export const๋ก ์์ฑํฉ๋๋ค.
// ํ
ํ๋ฆฟ์ ์ฌ์ฉํ์ฌ Storybook์ ๋ฃ์ด์ค ์คํ ๋ฆฌ๋ฅผ ํ๋ ๋ง๋ค์ด์ฃผ์์ต๋๋ค.
// Template.bins({}); ๋ ์ ํด์ง ๋ฌธ๋ฒ์ด๋ผ๊ณ ์๊ฐํ๊ณ ์ฌ์ฉํ์๋ฉด ๋ฉ๋๋ค.
export const RedTitle = Template.bind({});
// ๋ง๋ค์ด์ค ์คํ ๋ฆฌ์ ์ ๋ฌ์ธ์๋ฅผ ์์ฑํด์ค๋๋ค.
RedTitle.args= {
title: "Red Title",
textColor: "red"
}
// ์คํ ๋ฆฌ๋ฅผ ํ๋ ๋ ๋ง๋ญ๋๋ค.
export const BlueTitle = Template.bind({});
// ์คํ ๋ฆฌ์ ์ ๋ฌ์ธ์๋ฅผ ์์ฑํด์ค๋๋ค.
BlueTitle.args= {
title: "Blue Title",
textColor: "blue"
}
export const PinkTitle = Template.bind({});
PinkTitle.args = {
title: "Pink Title",
textColor: 'pink'
}
export const StorybookTitle = (args) =>{
return <Title {...args} />
}
์ ์์ ์๋ ๋ค๋ฅด๊ฒ, ์ด๋ฒ์๋ ๊ธฐ๋ณธ๊ฐ ์ธ์๋ฅผ ์ค์ ํด๋์๋ค.
import React from "react";
import styled from 'styled-components';
// ์ฌ๊ธฐ์๋ ์ปดํฌ๋ํธ์ ๊ธฐ๋ณธ์ผ๋ก ์ ๋ฌํ ์ธ์๊ฐ์ ์์ฑํ๋ค.
const StyledButton = styled.button`
background: ${(props) => props.color || "pink"};
width : ${(props)=> (props.size === 'big'? '200px':'100px')};
height: ${(props)=> (props.size === 'big'?'80px':'40px')}
`
// ์ปดํฌ๋ํธ ๋ด๋ถ์, ๊ธฐ๋ณธ๊ฐ๋ค์ ์ ์ฉ์ํจ ์ปดํฌ๋ํธ๋ฅผ ๋ฃ์ด์ export ํด์ฃผ์๋ค.
const Button = ({color,size,text}) => (
<StyledButton color={color} size={size} >{text}</StyledButton>
);
export default Button
// ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์ต๋๋ค.
import Button from "./Button";
// ์์์ ๋ช
์ธํ๊ธฐ. title, component, argTypes
export default {
title: "Practice/Button",
component: Button,
argTypes: {
color: { control: 'color'},
size: { control: { type:'radio', options : ['big', 'small'] }},
text: { control: 'text'}
}
};
// ํ
ํ๋ฆฟ์ผ๋ก ์ธ์ ์ ๋ฌ
const Template = (args) => <Button {...args}></Button>
export const StorybookButton = (args) => (
<Button {...args}></Button>
)
export const defaultButton = Template.bind({});
defaultButton.args = {
// ์๋ฌด ์ธ์๋ฅผ ์ฃผ์ง ์์๋๋, js ํ์ผ์์ ๊ธฐ๋ณธ์ผ๋ก ์ค์ ํ pink ๋ฐฐ๊ฒฝ์ด ๋์ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
// ์์ ์์ฑํ StorybookButton๊ณผ ์ ์ฌํ ๋ฏ ํ๋ค.
}
export const RedButton = Template.bind({});
RedButton.args = {
title: "RedButton",
size:'2em',
color:'red' //์ฌ๊ธฐ์๋ ์์์ ์ง์ ํด์ฃผ๋ ์์์ด ๋ฐ์๋์ด ๋์ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
}