스토리북 Cheatsheet¶
Storybook - 고립
에서 UI를 빌드Storybook은 UI 구성 요소 및 페이지 구축을위한 frontend 워크샵입니다. 모든 앱을 실행하지 않고도 하드투-레흐 주 및 가장자리 케이스를 개발 및 공유하는 데 도움이됩니다. 팀의 수천은 UI 개발, 테스트 및 문서에 사용됩니다.
본문 바로가기¶
설치하기¶
빠른 시작¶
카지노사이트
수동 설치¶
카지노사이트
Framework-Specific 설정¶
카지노사이트
프로젝트 구조¶
카지노사이트
시작하기¶
기본 스토리¶
카지노사이트
구성 요소 예¶
카지노사이트
스토리북¶
카지노사이트
관련 기사¶
스토리 구조¶
카지노사이트
스토리 Naming¶
카지노사이트
다수 성분¶
카지노사이트
스토리 매개 변수¶
ο 회원 관리
스토리 형식¶
CSF 3.0 (현재)¶
카지노사이트
CSF 2.0 (라이시)¶
카지노사이트
사용자 정의 렌더링 기능¶
카지노사이트
기능 재생¶
카지노사이트
통제 & 활동¶
ArgTypes 구성¶
카지노사이트
한국어¶
카지노사이트
고급 컨트롤¶
카지노사이트
더 보기¶
필수 Addons¶
카지노사이트
접근성 addon¶
오프화이트
Viewport 추가¶
카지노사이트
디자인 토큰 Addon¶
오프화이트
주문 Addons¶
카지노사이트
제품 설명¶
주요 구성¶
카지노사이트
미리보기 구성¶
카지노사이트
환경 변수¶
카지노사이트
인기 있는¶
제품 정보 이름 *¶
카지노사이트
다크 테마¶
카지노사이트
테마 전환¶
// .storybook/preview.js
import { themes } from '@storybook/theming';
export const parameters = {
docs: {
theme: themes.light,
},
darkMode: {
// Override the default dark theme
dark: { ...themes.dark, appBg: 'black' },
// Override the default light theme
light: { ...themes.normal, appBg: 'white' },
// Set the initial theme
current: 'light',
// Disable the addon for specific stories
stylePreview: true,
},
};
// Global decorator for theme switching
export const decorators = [
(Story, context) => {
const theme = context.globals.theme || 'light';
return (
<div className={`theme-${theme}`}>
<Story />
</div>
);
},
];
// Global types for theme switcher
export const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme for components',
defaultValue: 'light',
toolbar: {
icon: 'circlehollow',
items: [
{ value: 'light', icon: 'sun', title: 'Light' },
{ value: 'dark', icon: 'moon', title: 'Dark' },
],
showName: true,
},
},
};
```의 경우
## 제품정보
### 연락처
```javascript
// .storybook/test-runner.js
const { getStoryContext } = require('@storybook/test-runner');
module.exports = {
async postRender(page, context) {
const storyContext = await getStoryContext(page, context);
// Skip visual tests for specific stories
if (storyContext.parameters?.skipVisualTest) {
return;
}
// Take screenshot
const image = await page.screenshot();
expect(image).toMatchImageSnapshot({
customSnapshotIdentifier: context.id,
});
},
};
// In stories
export const VisualTest = {
args: {
label: 'Visual Test Button',
},
parameters: {
// Skip this story in visual tests
skipVisualTest: true,
},
};
```에 대하여
### Interaction 테스트
```javascript
// Button.stories.js
import { userEvent, within, expect } from '@storybook/test';
export const InteractionTest = {
args: {
label: 'Click me',
},
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);
// Find elements
const button = canvas.getByRole('button', { name: /click me/i });
// Simulate interactions
await userEvent.click(button);
// Assertions
await expect(args.onClick).toHaveBeenCalled();
// Check DOM changes
await expect(button).toHaveClass('clicked');
// Wait for async operations
await canvas.findByText('Success!');
},
};
export const FormInteraction = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
// Fill form
const emailInput = canvas.getByLabelText(/email/i);
const passwordInput = canvas.getByLabelText(/password/i);
const submitButton = canvas.getByRole('button', { name: /submit/i });
await userEvent.type(emailInput, 'user@example.com');
await userEvent.type(passwordInput, 'password123');
await userEvent.click(submitButton);
// Check results
await expect(canvas.getByText(/success/i)).toBeInTheDocument();
},
};
```의 경우
### Stories를 가진 단위 테스트
```javascript
// Button.test.js
import { render, screen } from '@testing-library/react';
import { composeStories } from '@storybook/testing-react';
import * as stories from './Button.stories';
const { Primary, Secondary, Large } = composeStories(stories);
describe('Button', () => {
test('renders primary button', () => {
render(<Primary />);
expect(screen.getByRole('button')).toHaveClass('storybook-button--primary');
});
test('renders secondary button', () => {
render(<Secondary />);
expect(screen.getByRole('button')).not.toHaveClass('storybook-button--primary');
});
test('renders large button', () => {
render(<Large />);
expect(screen.getByRole('button')).toHaveClass('storybook-button--large');
});
});
```에 대하여
### Accessibility 테스트
```javascript
// a11y.test.js
import { axe, toHaveNoViolations } from 'jest-axe';
import { render } from '@testing-library/react';
import { composeStories } from '@storybook/testing-react';
import * as stories from './Button.stories';
expect.extend(toHaveNoViolations);
const { Primary, Secondary } = composeStories(stories);
describe('Button Accessibility', () => {
test('Primary button should not have accessibility violations', async () => {
const { container } = render(<Primary />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
test('Secondary button should not have accessibility violations', async () => {
const { container } = render(<Secondary />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
```의 경우
## 회사연혁
### 자동 문서
카지노사이트
### 회사연혁
카지노사이트
### 사이트맵 회사연혁
```mdx
<!-- Button.stories.mdx -->
import { Meta, Story, Canvas, ArgsTable, Description } from '@storybook/addon-docs';
import { Button } from './Button';
<Meta title="Example/Button" component={Button} />
# Button
<Description of={Button} />
## Examples
### Primary Button
<Canvas>
<Story name="Primary" args={{ primary: true, label: 'Button' }}>
{(args) => <Button {...args} />}
</Story>
</Canvas>
### Secondary Button
<Canvas>
<Story name="Secondary" args={{ label: 'Button' }}>
{(args) => <Button {...args} />}
</Story>
</Canvas>
## Props
<ArgsTable of={Button} />
## Usage Guidelines
- Use primary buttons sparingly, typically one per page
- Secondary buttons can be used multiple times
- Always provide meaningful labels
- Consider accessibility when choosing colors
## Code Example
```jsx의 경우
'./Button'에서 { Button } 가져오기;
함수 MyComponent() {
반환 (
<div>
<Button primary onClick={() => alert('Primary clicked!')}>
초등학교
</버튼>
<Button onClick={() => alert('Secondary clicked!')}>
두 번째 행동
</버튼>
</div>
·
이름 *
카지노사이트
### 문서화
```javascript
// .storybook/main.js
module.exports = {
stories: [
'../src/**/*.stories.@(js|jsx|ts|tsx)',
'../docs/**/*.stories.mdx', // Documentation stories
],
};
// docs/Introduction.stories.mdx
import { Meta } from '@storybook/addon-docs';
<Meta title="Introduction" />
# Design System
Welcome to our design system documentation.
## Getting Started
This Storybook contains all the components, patterns, and guidelines for our design system.
### Installation
```bash의 경우
npm @company/design-system 설치
Usage¶
jsx의 경우
import { Button, 입력, 카드 '@company/design-system';
Principles¶
- Consistency - Maintain visual and functional consistency
- Accessibility - Ensure all components are accessible
- Performance - Optimize for speed and efficiency
- Flexibility - Support customization and theming ```의 경우
계정 만들기¶
정적 빌드¶
```bash
Build Storybook for deployment¶
npm run build-storybook
Output directory¶
ls storybook-static/
Serve locally¶
npx http-server storybook-static ```의 경우
Netlify 배포¶
카지노사이트
Vercel 배포¶
json
// vercel.json
{
"buildCommand": "npm run build-storybook",
"outputDirectory": "storybook-static",
"framework": null
}의 경우
GitHub 페이지¶
```yaml
.github/workflows/storybook.yml¶
name: Build and Deploy Storybook
on: push: branches: [ main ]
jobs: build-and-deploy: runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '16'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build Storybook
run: npm run build-storybook
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./storybook-static
```를 호출합니다.
Docker 배포¶
```dockerfile
Dockerfile¶
FROM node:16-alpine as builder
WORKDIR /app COPY package*.json ./ RUN npm ci
COPY . . RUN npm run build-storybook
FROM nginx:alpine COPY --from=builder /app/storybook-static /usr/share/nginx/html COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ```의 경우
AWS S3 + 클라우드프론트¶
```bash
Build and deploy to S3¶
npm run build-storybook aws s3 sync storybook-static/ s3://my-storybook-bucket --delete aws cloudfront create-invalidation --distribution-id ABCD1234 --paths "/*" ```로
고급 기능¶
웹팩 구성¶
카지노사이트
사용자 정의 Babel 구성¶
오프화이트
환경 특정 구성¶
카지노사이트
사용자 정의 관리자 UI¶
__CODE_BLOCK_49_로그
- 연혁¶
Lazy 선적¶
카지노사이트
번들 최적화¶
```javascript // .storybook/main.js module.exports = { webpackFinal: async (config) => { // Code splitting config.optimization.splitChunks = { chunks: 'all', cacheGroups: { vendor: { test: /[\/]node_modules[\/]/, name: 'vendors', chunks: 'all', }, }, };
// Tree shaking
config.optimization.usedExports = true;
config.optimization.sideEffects = false;
return config;
}, }; ```를 호출합니다.
메모리 최적화¶
```javascript // .storybook/preview.js export const parameters = { // Reduce memory usage options: { storySort: { method: 'alphabetical', order: ['Introduction', 'Components', 'Pages'], locales: 'en-US', }, },
// Disable source code addon for better performance docs: { source: { state: 'closed', }, }, };
// Cleanup decorators export const decorators = [ (Story, context) => { // Cleanup on story change React.useEffect(() => { return () => { // Cleanup logic }; }, [context.id]);
return <Story />;
}, ]; ```의 경우
통합¶
Design Tools 통합¶
카지노사이트
테스트 통합¶
카지노사이트
CI/CD 통합¶
```yaml
.github/workflows/storybook-tests.yml¶
name: Storybook Tests on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '16' cache: 'npm'
- run: npm ci
- run: npm run build-storybook --quiet
- run: npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
"npx http-server storybook-static --port 6006 --silent" \
"npx wait-on http://127.0.0.1:6006 && npm run test-storybook"
```로
문제 해결¶
일반적인 문제¶
카지노사이트
Debug 모드¶
카지노사이트
성능 문제¶
카지노사이트
문제 해결¶
```bash
Clear all caches¶
rm -rf node_modules/.cache rm -rf storybook-static npm run build-storybook
Check for conflicting dependencies¶
npm ls
Update Storybook¶
npx storybook@latest upgrade ```에
최고의 연습¶
회사소개¶
- ** 구조 **: 일관된 naming 패턴 사용
- Logical Grouping: 그룹 관련 부품
- **Clear Naming **: descriptive 스토리 이름
- 문: 포괄적인 문서
Component 개발¶
- Isolation: 고립에 있는 분대 개발
- **Props 공용영역 **: 명확하고, 일관된 버팀대 공용영역
- 기본값: sensible defaults 제공
- Error Handling: 우아한 핸들 가장자리 케이스
시험 전략¶
- Visual 테스트: 시각적 회귀 테스트
- Interaction 테스트: 시험 사용자 상호 작용
- Accessibility Testing: 구성 요소가 접근 가능
- ** 단위 테스트 **: 시험 성분 logic
성능 최적화¶
- **Lazy 로딩 **: 게으른 적재를 위한 이야기 상점 v7
- ** 번들 분할 **: 웹팩 구성 최적화
- ** 메모리 관리 **: 자주 묻는 질문
- **빌딩 최적화 **: Minimize 빌드 시간
팀 협업¶
- Design System: 일관된 디자인 시스템을 유지
- 문: 문서 유지
- ** 코드 리뷰**: 스토리 및 구성 요소 검토
- Automation: Automate 테스트 및 배포
제품정보¶
Storybook은 현대 frontend 개발을 위한 필수 도구입니다.
- Component Isolation: UI 컴포넌트를 독립적으로 개발 및 테스트
- Visual Documentation: 디자인 시스템의 생활 문서 작성
- Interactive Development: 실시간 피드백을 가진 구성 요소 구축
- ** 테스트 통합 **: 비주얼, 상호 작용 및 접근성 테스트
- **팀 협업 **: 팀과 이해관계자 간의 공유 구성
- Design System Management: 일관된 UI 패턴 유지
핵심 이점은 더 빠른 발달 주기, 더 나은 성분 질, 개량한 팀 협력 및 포괄적인 문서 포함합니다. Storybook은 모든 주요 프론트 엔드 프레임 워크를 지원하며 addons 및 구성을 통해 광범위한 사용자 정의 옵션을 제공합니다.
<문서> 기능 copyToClipboard () 이름 * const 명령어 = document.querySelectorAll('code'); let allCommands = ''; 명령. forEach(cmd =>의 경우 모든Commands +=cmd.textContent + navigator.clipboard.write텍스(allCommands); alert('모든 명령은 클립보드에 복사!'); 이름 *
함수 생성PDF() { 창. 인쇄 (); 이름 *