[React/CSS] Storybook

ko9612ยท2022๋…„ 8์›” 26์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
15/28

๐Ÿ” Stotybook


CDD ๊ฐœ๋ฐœ ๋„๊ตฌ ์ค‘ ํ•˜๋‚˜๋กœ, ๊ฐ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋”ฐ๋กœ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๊ตฌ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋…๋ฆฝ์ ์ธ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๊ณ  UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง‘์ค‘์ ์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ, ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฌธ์„œํ™”ํ•˜๊ณ , ๋‹ค์–‘ํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‹œ๊ฐํ™”ํ•˜์—ฌ ์‚ฌ์ „์— ๋ฒ„๊ทธ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.



๐Ÿ‘€ Setting


  1. ํ„ฐ๋ฏธ๋„์— npx create-react-app <ํ”„๋กœ์ ํŠธ ๋ช…> ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด ์„ค์น˜ํ•œ ํ›„, ์ƒˆ๋กœ์šด react ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

  1. react ํ”„๋กœ์ ํŠธ ํด๋” ์•ˆ์—์„œ npx storybook init ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด storybook์„ ์„ค์น˜ํ•œ๋‹ค.


    ./storybook = storybook ๊ด€๋ จ ์„ค์ • ํŒŒ์ผ
    /src/stories = storybook ์˜ˆ์‹œ ํŒŒ์ผ๋“ค

  1. npm run storybook ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด storybook์„ ์‹คํ–‰ํ•œ๋‹ค.



๐Ÿ‘€ ์‹ค์Šต ์˜ˆ์‹œ


  1. src ํด๋”์— Title.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ , React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด exportํ•œ๋‹ค.
import React from "react";

// title์€ h1 ์š”์†Œ์˜ textContent, textColor์€ ๊ธ€์ž์ƒ‰์ด ๋˜๋Š” props ์ด๋‹ค.
const Title = ({title, textColor}) => (
<h1 style={{color: textColor}}>{title}</h1>
);

export default Title;

  1. ๊ฐ™์€ ์œ„์น˜์ธ src ํด๋”์— Title.stories.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.(์ž๋™์œผ๋กœ ์Šคํ† ๋ฆฌ๋กœ ์ธ์‹)
// ์•ž์—์„œ ์ž‘์„ฑํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
import Title from "./Title";

// title : ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„, '/'๋ฅผ ๋„ฃ์–ด ์นดํ…Œ๊ณ ๋ฆฌํ™” ๊ฐ€๋Šฅ.
// component : ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์Šคํ† ๋ฆฌ๋กœ ๋งŒ๋“ค ๊ฒƒ์ธ์ง€ ๋ช…์‹œํ•œ๋‹ค.
// argTypes : ์ปดํฌ๋„ŒํŠธ์— ํ•„์š”ํ•œ ์ „๋‹ฌ์ธ์ž์˜ ์ข…๋ฅ˜์™€ ํƒ€์ž…์„ ์ •ํ•œ๋‹ค.
//            title, textColor์ด๋ผ๋Š” ์ „๋‹ฌ์ธ์ž์— text ํƒ€์ž…์ด ํ•„์š”ํ•จ์„ ์˜๋ฏธํ•จ.
export default {
    title: "Practice/Title", 
    component: Title,
    argTypes: {
        title: { control: "text" },
        textColor: {control: "text"}
    }
}

// Title ์ปดํฌ๋„ŒํŠธ๊ฐ€ args๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ props๋กœ ๋‚ด๋ ค์ฃผ๋Š” ํ…œํ”Œ๋ฆฟ์„ ์ƒ์„ฑํ•œ๋‹ค.
const Template = (args) => <Title {...args} />


// Storybook์—์„œ ํ™•์ธํ•˜๊ณ  ์‹ถ์€ ์ปดํฌ๋„ŒํŠธ๋Š” export const๋กœ ์ž‘์„ฑํ•œ๋‹ค.
// Template.bins({}); ๋Š” ์ •ํ•ด์ง„ ๋ฌธ๋ฒ•

// ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜์—ฌ Storybook์— ๋„ฃ์„ ์Šคํ† ๋ฆฌ ์ƒ์„ฑ
export const RedTitle = Template.bind({});

// ๋งŒ๋“ค์–ด์ค€ ์Šคํ† ๋ฆฌ์˜ ์ „๋‹ฌ์ธ์ž๋ฅผ ์ž‘์„ฑ
// 1. RedTitle
RedTitle.args= {
    title: "Red Title",
    textColor: "red"
}

// ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜์—ฌ Storybook์— ๋„ฃ์„ ์Šคํ† ๋ฆฌ ์ƒ์„ฑ 2.
// 2. BlueTitle
export const BlueTitle = Template.bind({});

// ๋งŒ๋“ค์–ด์ค€ ์Šคํ† ๋ฆฌ์˜ ์ „๋‹ฌ์ธ์ž๋ฅผ ์ž‘์„ฑ2
BlueTitle.args= {
    title: "Blue Title",
    textColor: "blue"
}

// ์ „๋‹ฌ์ธ์ž๋ฅผ ์ง์ ‘ ๋ฐ›๋Š” ์Šคํ† ๋ฆฌ ์ƒ์„ฑ
// 3. UserTitle
export const StorybookTitle = (args) =>{
    return <Title {...args} />
}



    1. RedTitle


    1. BlueTitle


    1. UserTitle(์ „๋‹ฌ์ธ์ž๋ฅผ ์ง์ ‘ ์ž…๋ ฅ)



โœ” Styled Components๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์Šคํ† ๋ฆฌ๋กœ ๋งŒ๋“ค๊ธฐ


  1. Button.js ํŒŒ์ผ ์ƒ์„ฑ
import React from "react";
import styled from "styled-components"

const StyledButton = styled.button`
// props.color๊ฐ€ ์žˆ์œผ๋ฉด props.color, ์•„๋‹ˆ๋ฉด ํฐ์ƒ‰์„ ๋ฐฐ๊ฒฝ์ƒ‰์œผ๋กœ
background: ${(props) => props.color || "white" };
// props.size๊ฐ€ bug์ด๋ฉด 200px, ์•„๋‹ˆ๋ฉด 100px๋ฅผ ๋„ˆ๋น„๋กœ
width: ${(props) => (props.size === "big" ? "200px" : "100px") };
// props.size๊ฐ€ "big"์ด๋ฉด 80px, ์•„๋‹ˆ๋ฉด 40px๋ฅผ ๋†’์ด๋กœ
height: ${(props) => (props.size === "big" ? "80px" : "40px") };
`

const Button = ({color, size, text}) => (
// ์œ„์—์„œ ์ž‘์„ฑํ•œ props + text๋ฅผ ๋ฐ›์•„ textContent๋กœ ์‚ฌ์šฉ
<StyledButton color={color} size={size}>{text}</StyledButton>
);

export default Button;

  1. Button.stories.js ํŒŒ์ผ ์ƒ์„ฑ
// ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
import Button from "./Button";

export default {
    title: "Practice/Button",
    component: Button,
    argTypes: {
        color: { control: 'color'},
        size: { control: { type:'radio', options : ['big', 'small'] }},
        text: { control: 'text'}
    }
};

export const StorybookButton = (args) => (
    <Button {...args}></Button>
)






Reference: ์ฝ”๋“œ์Šคํ…Œ์ด์ธ 

0๊ฐœ์˜ ๋Œ“๊ธ€