콘텐츠로 이동

스토리북 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

  1. Consistency - Maintain visual and functional consistency
  2. Accessibility - Ensure all components are accessible
  3. Performance - Optimize for speed and efficiency
  4. 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() { 창. 인쇄 (); 이름 *