LogoSEO Jing
  • All Posts
  • SEO Jing
  • okayJing
  • KD Team
  • CLAB Coreteam
  • Study

Contact Me

© 2026 SEOJing. All rights reserved.

DevLogSEO JingInsight

디자인 시스템을 구축할 때 주의할 점

2026년 3월 14일·4분 읽기

디자인 시스템이란

컴포넌트, 디자인 토큰(색상·간격·타이포그래피), 규칙을 하나의 패키지로 통일해서 여러 앱에서 일관된 UI를 만드는 체계다. 이 프로젝트에서는 packages/ui가 그 역할을 한다.


파일 구조 — 컴포넌트 단위로 폴더 분리

packages/ui/src/
├── paper/
│   ├── paper.tsx          ← 컴포넌트 본체
│   ├── paper.types.ts     ← 타입 정의
│   ├── paper.constants.ts ← 디자인 토큰 매핑
│   ├── paper-error.tsx    ← 에러 바운더리
│   ├── paper.stories.tsx  ← Storybook 스토리
│   └── index.ts           ← 배럴 export
└── index.ts               ← 패키지 진입점

이렇게 하면: - 컴포넌트끼리 의존성이 명확 - 타입·상수·스토리가 함께 있어서 찾기 쉬움 - index.ts 배럴로 외부에서 import {Paper} from "@app/ui" 가능


디자인 토큰 — CSS 변수로 관리

globals.css의 @theme 블록에 색상·간격·폰트·애니메이션을 정의하고, 컴포넌트에서는 Tailwind 유틸리티로 참조한다. 하드코딩된 값 대신 토큰을 쓰면 테마 변경이 한 곳에서 가능.


컴포넌트 API 설계 — props를 제한된 프리셋으로

ts
export const PAPER_PADDINGS: Record<string, string> = {
  none: "p-0",
  sm: "p-3",
  md: "p-6",
  lg: "p-8",
  xl: "p-12",
};

사용자가 임의 값을 넣는 게 아니라 padding="md" 같은 프리셋을 선택하게 한다. 일관성이 보장되고, 타입 자동완성도 된다.


유의할 점

서버 컴포넌트 vs 클라이언트 컴포넌트

Next.js(vinext) 환경에서 "use client"를 붙이면 해당 컴포넌트와 그 하위 트리가 클라이언트 번들에 포함된다. 디자인 시스템에서는:

  • useState, useEffect 등 훅이 필요한 컴포넌트만 "use client" - 순수 렌더링 컴포넌트(ArticleHeader, Subtitle, Paragraph 등)는 서버 컴포넌트로 유지

CSS 애니메이션에서 transform 충돌

같은 요소에 두 개의 애니메이션을 걸면 둘 다 transform을 건드릴 때 마지막 것만 적용된다. 해결법: - 별도 DOM 레이어로 분리 (바깥 div에 이동, 안쪽 div에 회전) - 또는 하나의 키프레임에 모든 transform을 합침

Tailwind v4 @theme 토큰과 클래스 매핑

-animate-elliptic-in: ...으로 등록하면 animate-elliptic-in 클래스가 자동 생성된다. 키프레임 이름과 토큰 이름이 일치하지 않아도 되지만, 토큰 값 안에서 참조하는 키프레임 이름은 @keyframes 정의와 정확히 일치해야 한다.


Skeleton 구조

tsx
function PaperSkeleton() {
  return (
    <div className="mx-2 animate-pulse rounded-lg bg-gray-200 dark:bg-gray-800">
      <div className="aspect-[1/1.414] w-full" />
    </div>
  );
}

실제 콘텐츠가 로딩되기 전에 보여주는 뼈대(placeholder) UI다. 콘텐츠와 비슷한 형태를 가진 회색 박스에 animate-pulse를 적용한다.

로딩 방식사용자 경험
아무것도 안 보임"고장났나?"
스피너"로딩 중이구나"
Skeleton"곧 콘텐츠가 채워지겠구나" — 체감 로딩 시간 감소

Skeleton은 최종 레이아웃과 같은 공간을 미리 차지하므로 레이아웃 시프트(CLS)가 없다. React Suspense의 fallback으로 연결하면 콘텐츠 로딩 중에는 스켈레톤이 보이다가, 로딩 완료 시 실제 컴포넌트로 교체된다.

Post Q&A

오케이징에게 물어보기

디자인 시스템을 구축할 때 주의할 점 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!

0/500

포스트 목록

/SEOJing/devLog/insight
파일 10개, 폴더 0개
엄청난 피드백생각보다 어려웠던 댓글, 완독 로컬스토리지디자인 시스템을 구축할 때 주의할 점폰트는 왜 메인 페이지에서만 적용이 안되고 있었을까?MDX DOM 트리 파싱하기MDX 관련 이슈 노트결국 Node.js 까지 와버렸다전체적인 플로우Storybook으로 디자인 시스템 테스팅하기MDX가 뭘까?

같은 섹션의 대표 이미지

10 posts · latest first
SEO Jing26. 03. 15.

엄청난 피드백.

CLI 코드 리뷰에서 받은 피드백과 전체 코드 수정 계획을 정리했다.

26. 03. 15.SEOJing
SEO Jing26. 03. 15.

생각보다 어려웠던 댓글, 완독 로컬스토리지.

localStorage만으로 글 읽기 추적, 스크롤 진행률, 댓글 감지를 구현한 과정을 정리했다.

26. 03. 15.SEOJing
SEO Jing26. 03. 15.

MDX 관련 이슈 노트.

블로그 디테일 페이지에서 MDX를 렌더링하기 위해 검토한 라이브러리들과 최종 선택 과정.

26. 03. 15.SEOJing
SEO Jing26. 03. 14.

디자인 시스템을 구축할 때 주의할 점.

디자인 시스템 구현 시 파일 구조, 디자인 토큰, 유의 사항을 정리했다.

26. 03. 14.SEOJing
SEO Jing26. 03. 14.

폰트는 왜 메인 페이지에서만 적용이 안되고 있었을까?.

Tailwind v4 환경에서 폰트가 메인 페이지에서만 적용되지 않던 원인과 Hydration Mismatch 이슈를 정리했다.

26. 03. 14.SEOJing
SEO Jing26. 03. 14.

MDX DOM 트리 파싱하기.

MDX 파일의 경로 탐색 로직과 콘텐츠 트리 생성 과정을 정리했다.

26. 03. 14.SEOJing
SEO Jing26. 03. 14.

결국 Node.js 까지 와버렸다.

MDX 파일 구조를 JSON으로 변환하기 위해 Node.js의 fs 모듈을 배워봤다.

26. 03. 14.SEOJing
SEO Jing26. 03. 13.

전체적인 플로우.

SEO Jing 프로젝트의 기술 스택 선정과 전체적인 개발 플로우 정리.

26. 03. 13.SEOJing
SEO Jing26. 03. 13.

Storybook으로 디자인 시스템 테스팅하기.

Storybook의 사용법과 디자인 시스템 개발에서의 장점을 정리했다.

26. 03. 13.SEOJing
SEO Jing26. 03. 13.

MDX가 뭘까?.

MDX의 개념과 블로그에서 활용하는 이유를 정리했다.

26. 03. 13.SEOJing