Setup
$ npx create-react-app example-story-book
$ cd example-story-book
$ npm install @storybook/react --save-dev
story book μ€μ μ μν΄ .storybook ν΄λ μλμ config νμΌμ μΆκ°ν©λλ€.
// .storybook/config.js
import { configure } from "@storybook/react";
configure(require.context("../docs", true, /\.stories\.js$/), module);
config νμΌμΆκ° ν story component λ€μ λμ docs ν΄λλ₯Ό μΆκ°ν΄μ£ΌμΈμ
docs ν΄λμ story component λ€μ *.stories.js
μ΄λΌλ ν¨ν΄μ μ΄λ¦μ κ°μ§λλ€.
storybook μμ μ 곡ν΄μ£Όλ demo button μ μΆκ°ν΄λ³΄κ² μ΅λλ€.
// docs/button.stories.js
import React from "react";
import { storiesOf } from "@storybook/react";
import { Button } from "@storybook/react/demo";
export default { title: "Button" };
storiesOf("Button Component", module)
.add("withText", () => <Button>Hello Button</Button>)
.add("withEmoji", () => (
<Button>
<span role="img" aria-label="so cool">
π π π π―
</span>
</Button>
));
storiesOf λ μ»΄ν¬λνΈλ₯Ό μ€ν 리 λ¨μλ‘ λ
ΈμΆ ν μ μκ² λμμ€λλ€.
ν¬κ² Button Component λΌλ μ€ν λ¦¬λ‘ λ¬Άμ΄ λ
ΈμΆν©λλ€.
μ€νμ μν΄ package.json μ scripts μ storybook λͺ
λ Ήμ΄λ₯Ό μΆκ°ν©λλ€.
// package.json
"scripts": {
"docs": "start-storybook"
}
μ°λ¦¬κ° μμͺ½μμ story μ μΆκ°νλ button μ»΄ν¬λνΈλ₯Ό νμΈ ν μ μμ΅λλ€.
μ΄λ₯Ό μ΄μ©νλ©΄ μνμ λ°λ₯Έ μ»΄ν¬λνΈ λ³ν λλ λμμΈ μ μ©μ¬λΆλ₯Ό 미리 νμΈ ν μ μμ΅λλ€.
Component μΆκ°ν΄λ³΄κΈ°
styled-components λ₯Ό μ΄μ©νμ¬ μ§μ ꡬμ±ν΄λ³΄κ² μ΅λλ€.
$ npm install --save styled-components
src ν΄λ μλμ input.js λΌλ component λ₯Ό λ§λ€μ΄μ£ΌμΈμ
// src/input.js
import styled, { css } from "styled-components";
const BaseInput = styled.input`
width: 100%;
padding: 14px;
border-radius: 2px;
border: solid 1px #efefef;
background-color: #ffffff;
font-size: 16px;
outline: none;
box-sizing: border-box;
${({ focus }) =>
focus &&
css`
border: solid 1px #ff30ac;
`}
`;
export default BaseInput;
input μ focus props μ λ°λΌ border style μ΄ λ³ν©λλ€. ν΄λΉ component λ₯Ό story book μ μΆκ°ν©λλ€.
// docs/input.stories.js
import React from "react";
import { storiesOf } from "@storybook/react";
import Input from "../src/input";
export default { title: "Button" };
storiesOf("Input", module)
.add("Base Input", () => <Input />)
.add("Focus Input", () => <Input focus />);
Addon
addon μ μΆκ°νλ©΄ κΈ°λ³Έλμ μΈ μ¬λ¬κ°μ§ μμ
μ ν μ μμ΅λλ€.
$ npm install -D @storybook/addon-knobs @storybook/addon-knobs/register
.storybook ν΄λμ addons.js νμΌμ μΆκ°νμ¬ addons λ₯Ό λ±λ‘ν©λλ€.
// .storybook/addons.js
import "@storybook/addon-knobs/register";
config νμΌμλ μΆκ°ν΄μΌν©λλ€.
// .storybook/config.js
import { configure, addDecorator } from "@storybook/react";
import { withKnobs } from "@storybook/addon-knobs";
addDecorator(withKnobs);
configure(require.context("../docs", true, /\.stories\.js$/), module);
addon κΈ°λ₯μΌλ‘ input μ focus λ₯Ό μ‘°μ νλλ‘ μΆκ°ν΄λ³΄κ² μ΅λλ€.
// docs/input.stories.js
import React from "react";
import { storiesOf } from "@storybook/react";
import { boolean } from "@storybook/addon-knobs";
import Input from "../src/input";
storiesOf("Input", module)
.add("Base Input", () => <Input focus={boolean("ν¬μ»€μ€", false)} />)
.add("Focus Input", () => <Input focus />);
λ°°ν¬
Storybook μ λ°°ν¬ν Github Repo λ₯Ό λ§λ€μ΄μ£ΌμΈμ
Github page μ κ°λ¨νκ² λ°°ν¬ν μ μκ² λμμ£Όλ λͺ¨λμ μ€μΉν΄μΌν©λλ€.
$ npm i @storybook/storybook-deployer --save-dev
μ€μΉν λ°°ν¬ λͺ
λ Ήμ΄λ₯Ό λ±λ‘ν©λλ€.
// package.json
"scripts": {
"docs": "start-storybook",
"deploy": "storybook-to-ghpages"
}
μμ£Ό κ°λ¨νκ² λ°°ν¬κ° κ°λ₯ν©λλ€.
λ°°ν¬ κ²°κ³Όλ¬Όμ <github name>.github.io/<repo name>
μ μ κ²½μ° https://appear.github.io/example-storybook μ
λλ€.