Storybook은 UI 컴포넌트 개발을 할때 뛰어난 UI를 체계적이고 효율적으로 구축 할 수 있도록 도와주는 유용한 tool입니다. 이 포스팅에서는 storybook 사용과 관련해서는 설명하지 않고,이미 사용하고 있는 storybook을 어떻게 잘 활용할지에 대한 몇가지 방법들에 대해 포스팅 하겠습니다. 또한 storybook 5.2 버전 이상에서는 Component Story Format (CSF) 형식으로 stories를 작성하도록 권장하고 있는데요, 이 환경 에서의 활용방법 위주로 포스팅 된 점 참고 부탁드립니다.
storybook에서는 아래에서 볼수 있듯, 다양한 기능들을 활용할 수 있게 공식적으로 addon들을 제공하고 있습니다. 그 중 유용하게 사용한 몇가지 addon들을 소개해 드리겠습니다.
프론트엔드 개발을 하다보면, 다양한 반응형에 대응을 해야할 때가 있습니다. 따라서, 스토리북을 활용하여 개발을 할때에도 이러한 반응형 UI에 따른, 컴포넌트의 스토리를 확인해야 할 경우들이 있는데요. 이 때 유용하게 사용할 수 있는 addon이 viewport addon 입니다.
설치
npm i --save-dev @storybook/addon-viewport
yarn add -D @storybook/addon-viewport
설정방법
module.exports = {
addons: ["@storybook/addon-viewport/register"],
};
제공하는 기능은 아래와 같이 요약할 수 있습니다.
- 다양한 viewport 설정할수 있게 configuration 하기
맨처음, storybook viewport addon을 설정하게 되면 이곳 에 있는 MINIMAL_VIEWPORTS 들만 보여지게 됩니다.
//storybook/addons/viewport/src/defaults.ts
export const MINIMAL_VIEWPORTS: ViewportMap = {
mobile1: {
name: "Small mobile",
styles: {
height: "568px",
width: "320px",
},
type: "mobile",
},
mobile2: {
name: "Large mobile",
styles: {
height: "896px",
width: "414px",
},
type: "mobile",
},
tablet: {
name: "Tablet",
styles: {
height: "1112px",
width: "834px",
},
type: "tablet",
},
};
따라서, 좀 더 다양한 viewport에서 story들을 확인하고 싶다면 storybook에서 제공하는 INITIAL_VIEWPORTS를 활용해 수정해주어도 되고,
// .storybook/preview.js
import { addParameters } from "@storybook/react";
import { INITIAL_VIEWPORTS } from "@storybook/addon-viewport";
addParameters({
viewport: {
viewports: INITIAL_VIEWPORTS,
},
});
아래와 같이 viewport 리스트를 custom해 넣어주어도 됩니다.
import { addParameters } from "@storybook/react";
const customViewports = {
kindleFire2: {
name: "Kindle Fire 2",
styles: {
width: "600px",
height: "963px",
},
},
kindleFireHD: {
name: "Kindle Fire HD",
styles: {
width: "533px",
height: "801px",
},
},
};
addParameters({
viewport: { viewports: customViewports },
});
- defaultViewport 적용하기
아래와 같이 default로 보여지고 싶은 viewport를 정해 넣어주기만 하면됩니다. 유의할점은 적용되어 있는 viewportList 내에서 적용을 해야한다는 점입니다.
맨 처음엔 이곳의 MINIMAL VIEWPORTS 로 리스트들이 적용되어 있어, 이 안에서 적용을 해주어야 하고, 만약 INITIAL_VIEWPORT를 viewports에 적용해 주었다면, iphonex, iphone6 등등 다양한 viewport를 default viewport로 적용이 가능해집니다.
맨 처음 설정되어있는 viewport에서 default viewport 적용
// storybook/preview.js
// 맨 처음 설정되어있는 viewport에서 default viewport 적용
import { addParameters } from "@storybook/react";
addParameters({
viewport: {
defaultViewport: "mobile1",
},
});
추가한 viewport가 있을때 default viewport 적용
// 추가한 viewport가 있을때 default viewport 적용
import { addParameters } from "@storybook/react";
import { INITIAL_VIEWPORTS } from "@storybook/addon-viewport";
addParameters({
viewport: {
viewports: INITIAL_VIEWPORTS,
defaultViewport: "iphonex",
},
});
- 개별 컴포넌트 story별 viewport 적용하기
전체 프로젝트에 적용하지 않고 각각의 story별로, 데스크탑에서 쓰는 컴포넌트라면 데스크탑 viewport를, 모바일에서만 쓰는 컴포넌트라면 모바일 viewport를 적용할수도 있게 됩니다. 물론,여기서도 역시 default viewport로 설정한 key가 적용한 viewport list에 있어야 합니다.
개별 story 파일
export default {
title: 'Stories',
parameters: {
viewport: { defaultViewport: 'iphone6' },
};
};
export const myStory = () => <div />;
myStory.story = {
parameters: {
viewport: { defaultViewport: 'iphonex' },
},
};
knobs addon은 다양한 input들을 동적으로 넣어주어 컴포넌트와 상호작용 할 수 있도록 도와주는 addon입니다. 또한 넘겨준 prop 에 따라 어떤 결과물을 보여주는지 바로바로 확인하고 싶을 때 Knobs 를 사용하면 매우 유용합니다.
설치
npm i --save-dev @storybook/addon-knobs
yarn add @storybook/addon-knobs --dev
설정방법
.storybook/main.js 파일
module.exports = {
addons: ["@storybook/addon-knobs/register"],
};
사용가능한 knobs들은 아래와 같은데요, available knobs section을 가시면 사용가능한 knobs들에 대한 더 자세한 설명을 볼 수 있습니다.
아래는 text와 object knobs를 사용하여 테스트한 예제입니다.
import React from "react";
import { withKnobs, text, object } from "@storybook/addon-knobs";
import Button from "./index";
export default {
title: "DesignSystem|atoms/Button",
decorators: [withKnobs],
component: Button,
};
export const defaultButton = () => {
const styleObj = object("style object", {
backgroundColor: "#ffffff",
color: "#000000",
});
return (
<Button style={styleObj}>{text("버튼텍스트", "Hello Storybook")}</Button>
);
};
아래 첨부한 예제에서 확인할수 있듯, 텍스트와 object가 동적으로 스토리북 상에서 바뀌는 것을 확인 할 수 있습니다.
이러한 다양한 knobs들을 토대로 UI 컴포넌트를 테스트 해볼 수 있게 되는데, Storybook 공식 knobs 예제 사이트에 가시면 다양한 활용 예제들을 확인 할 수 있습니다.
접근성이 좋은 애플리케이션이란 모든 사람이 앱을 이해하고 탐색하고 상호 작용할 수 있음을 의미합니다. 온라인에서는 탭 키 및 screen reader를 사용하여 사이트를 탐색하는 등의 콘텐츠에 액세스 할 수있는 방법등을 제공하는것을 의미하는데요, 이러한 접근성과 관련해 UI 컴포넌트들을 접근성있게 개발할수 있도록 도와주는 a11y addon이라는 addon이 있습니다. 이를 확인해 볼수 있는 간단한 예제와 함께 설명을 드리겠습니다.
관련해서 읽어보면 좋을 글
설치
npm i --save-dev @storybook/addon-a11y
yarn add @storybook/addon-a11y --dev
설정방법
.storybook/main.js 파일
module.exports = {
addons: ["@storybook/addon-a11y/register"],
};
import React from "react";
import { withKnobs, text, object } from "@storybook/addon-knobs";
import { withA11y } from "@storybook/addon-a11y";
import Button from "./index";
export default {
title: "DesignSystem|atoms/Button",
decorators: [withKnobs, withA11y],
component: Button,
};
export const accessible = () => <button>Accessible 버튼</button>;
export const inaccessible = () => (
<button style={{ backgroundColor: "red", color: "darkRed" }}>
Inaccessible 버튼
</button>
);
accsible한 버튼은 accsessible 테스트를 통과 한 반면,
아래와 같이 시각적으로 적절히 배경색과 글자색이 적용되지않은 버튼은 아래와 같은 경고가 뜨게 됩니다.
뜬 경고에 대해 간단히 간단히 요약하자면, 글꼴의 색과 문서의 배경 색이 어느 정도의 명도 대비를 지녀야 하는지에 대한 지침인데요, 화면에서 볼 수 있듯 배경색과 글꼴색이 적절히 대비되지 않아 시각적 접근성에 위배된다고 경고를 하게됩니다.
따라서 배경색을 적절히 바꿔주면 아래와 같이 통과를 하게 됩니다.
위에서 설명한 간단한 시각적인 접근성 테스트 말고도, 이 addon을 사용하면 다양하게 접근성에 위배되는 사항들에 대해 테스트를 해볼수 있게 됩니다.
위와 같이 addon을 추가하는것 이외에도 다양하게 storybook을 custom 하는 방법들이 있는데요, 그 중 몇가지를 소개하면 아래와 같습니다.
프로젝트의 구조를 잡듯이, storybook 내에서도 story들의 구조를 잡는 방법도 있습니다.
[folder 구조잡기]
/ 를 사용해 폴더를 명시해줄수 있고, /를 계속 추가해주면 folder역시 계속 생기게 되어, 폴더구조를 정리할수 있습니다.
export default {
title: "atoms/Button",
component: Button,
};
[root 이름 노출]
| 앞에 root에 해당하는 네이밍을 적어주면 됩니다.
export default {
title: "DesignSystem|atoms/Button",
component: Button,
};
회사 내에서 혹은 사이드프로젝트 등에서도 storybook을 자주 활용하게 되는데, 프로젝트 성격에 맞게 storybook의 테마를 꾸밀수 있습니다.
기본제공 테마 사용
//.storybook/preview.js
import { addParameters } from "@storybook/react";
import { themes } from "@storybook/theming";
addParameters({
options: {
theme: themes.dark,
},
});
직접 theme 만들어 사용
//yourTheme
import { create } from "@storybook/theming/create";
export default create({
base: "light",
colorPrimary: "hotpink",
colorSecondary: "deepskyblue",
// UI
appBg: "white",
appContentBg: "silver",
appBorderColor: "grey",
appBorderRadius: 4,
// Typography
fontBase: '"Open Sans", sans-serif',
fontCode: "monospace",
// Text colors
textColor: "black",
textInverseColor: "rgba(255,255,255,0.9)",
// Toolbar default and active colors
barTextColor: "silver",
barSelectedColor: "black",
barBg: "hotpink",
// Form colors
inputBg: "white",
inputBorder: "silver",
inputTextColor: "black",
inputBorderRadius: 4,
brandTitle: "My custom storybook",
brandUrl: "https://example.com",
brandImage: "https://placehold.it/350x150",
});
//.storybook/preview.js
import { addons } from "@storybook/addons";
import yourTheme from "./yourTheme";
addons.setConfig({
theme: yourTheme,
});
위에서 설명한것 이외에도 storybook을 활용할 수 있는 방법은 무궁무진 합니다. 다른 좋은 사례들이 있으면 공유해주시면 감사하겠습니다 :)
storybook 사용시 참고하면 좋을 글들