이번에 새로운 디자이너님과 협업을 하게 되었는데, 초기 단계부터 시작하는 거라서 처음부터 디자인 시스템을 잡고 가기로 했습니다.
이전 프로젝트에서 경험했던 문제들:
- 디자이너: "개발자들이 피그마와 다르게 구현해요"
- 개발자: "디자인이 개발 중에 자주 바뀌어요"
- 공통: 스크린샷 주고받기, 반복적인 확인 과정
- 결과: 소통 비용 증가, 일관성 부족
그래서 이번에는 다르게 접근하기로 했습니다: 처음부터 Storybook으로 디자인 시스템을 구축하고, 체계적인 협업 프로세스를 만들어보기로 했습니다.
이 포스트에서는 Next.js에서 Storybook을 설치하고 디자이너와 협업하기 위한 초기 세팅 과정을 공유하겠습니다.
🎯 Storybook 도입 계획과 기대 효과
해결하고 싶은 문제들:
- 디자인-개발 간 소통 비용 최소화
- 컴포넌트 일관성 확보
- 실시간 디자인 리뷰 환경 구축
기대하는 효과:
- 피드백 시간 단축 (스크린샷 공유 → 실시간 확인)
- 디자인 일관성 향상 (통합 컴포넌트 라이브러리)
- 개발 효율성 증대 (컴포넌트 재사용)
🚀 Next.js 프로젝트에 Storybook 설정하기
1. Storybook 설치
# Next.js 프로젝트 루트에서
npx storybook@latest init
Next.js를 자동 감지하고 필요한 설정을 완료해줍니다.
2. Styled-Components 연동
컴포넌트별 스타일 캡슐화로 디자이너가 직관적으로 이해할 수 있습니다:
npm install styled-components
npm install --save-dev @storybook/addon-styled-components babel-plugin-styled-components
테마 설정
// src/styles/theme.js
export const theme = {
colors: {
primary: '#007bff',
secondary: '#6c757d',
success: '#28a745',
danger: '#dc3545',
gray: {
100: '#f8f9fa',
300: '#dee2e6',
500: '#6c757d',
900: '#212529'
}
},
spacing: {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px'
},
breakpoints: {
mobile: '0px',
tablet: '768px',
desktop: '1024px'
},
// 미디어 쿼리 헬퍼
media: {
tablet: '@media (min-width: 768px)',
desktop: '@media (min-width: 1024px)'
}
};
3. 반응형 설정
3단계 브레이크포인트로 설정:
// .storybook/preview.js
export const parameters = {
viewport: {
viewports: {
mobile: {
name: 'Mobile',
styles: { width: '375px', height: '812px' }
},
tablet: {
name: 'Tablet',
styles: { width: '768px', height: '1024px' }
},
desktop: {
name: 'Desktop',
styles: { width: '1280px', height: '800px' }
}
}
}
};
🎨 디자이너 친화적인 컴포넌트 스토리 작성
Button 컴포넌트 예시
// src/components/Button.jsx
import styled from 'styled-components';
const StyledButton = styled.button`
padding: ${props => props.theme.spacing.sm} ${props => props.theme.spacing.md};
font-size: ${props => props.theme.typography.fontSize.sm};
border: none;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
/* 크기별 스타일 */
${props => props.size === 'small' && `
padding: ${props.theme.spacing.xs} ${props.theme.spacing.sm};
`}
${props => props.size === 'large' && `
padding: ${props.theme.spacing.md} ${props.theme.spacing.lg};
font-size: ${props.theme.typography.fontSize.lg};
`}
/* 변형별 스타일 */
${props => props.variant === 'primary' && `
background-color: ${props.theme.colors.primary};
color: white;
&:hover { background-color: #0056b3; }
`}
/* 반응형 */
${props => props.theme.media.tablet} {
padding: ${props => props.theme.spacing.md} ${props => props.theme.spacing.lg};
}
`;
export default function Button({
variant = 'primary',
size = 'medium',
children,
...props
}) {
return (
<StyledButton variant={variant} size={size} {...props}>
{children}
</StyledButton>
);
}
디자이너가 조작하기 쉬운 스토리
// src/components/Button.stories.js
export default {
title: 'Components/Button',
component: Button,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
variant: {
description: '버튼의 스타일 변형',
control: 'select',
options: ['primary', 'secondary']
},
size: {
description: '버튼의 크기',
control: 'select',
options: ['small', 'medium', 'large']
}
}
};
export const Primary = {
args: {
variant: 'primary',
children: '확인'
}
};
export const AllSizes = {
render: () => (
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
<Button size="small">작은 버튼</Button>
<Button size="medium">보통 버튼</Button>
<Button size="large">큰 버튼</Button>
</div>
)
};
🔗 피그마와 Storybook 연동하기
피그마 애드온 설치
npm install --save-dev @storybook/addon-design
피그마 링크 연동
각 컴포넌트의 피그마 링크를 연결하면 Design 탭에서 원본 디자인과 구현을 나 란히 비교할 수 있습니다:
// Button.stories.js
export default {
title: 'Components/Button',
component: Button,
parameters: {
design: {
type: 'figma',
url: 'https://www.figma.com/file/ABC123/Design-System?node-id=123%3A456'
}
}
};