디엠티 랩스 사내 디자인 시스템
Base UI(@base-ui/react)를 베이스로 한 React 컴포넌트 라이브러리입니다. 로고, UI 컴포넌트, 패턴, 차트, 인증 컴포넌트를 제공합니다.
https://design.dilato.kr/ 스토리북을 참고하세요.
소비 프로젝트에서 DILATO Design System을 사용하는 방법입니다.
체크리스트 요약
| 단계 | 작업 |
|---|---|
| 1 | 패키지 설치 (GitHub 또는 workspace) |
| 2 | Tailwind v4 + PostCSS 설정 |
| 3 | CSS import (메인 CSS 최상단에 2줄) |
| 4 | Layout에 TooltipProvider + Toaster 추가 |
| 5 | 컴포넌트는 서브패스별 import 사용 |
LLM/코드 생성 도구용 상세 가이드: docs/LLM_CONSUMER_GUIDE.md (구 readme.llm.md)
i18n: 라벨·검증 문구 등은 컴포넌트별 선택 props로 주입할 수 있고, 생략 시 한국어 기본값을 씁니다. 인증 폼은 auth/README.md의 i18n 절, DataTablePagination은 messages, FileUploadSection·TreeView 등은 해당 파일의 props 타입을 참고하세요.
GitHub에서 설치:
{
"dependencies": {
"@dmtPlatformInMarch/dilato-design-system": "github:dmtPlatformInMarch/DILATO-Design-System"
}
}Monorepo (workspace):
{
"dependencies": {
"@dmtPlatformInMarch/dilato-design-system": "workspace:*"
}
}npm install패키지명이 길어 @dilato/*로 짧게 사용하려면 tsconfig.json에 추가합니다:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@dilato/*": ["./node_modules/@dmtPlatformInMarch/dilato-design-system/*"]
}
}
}→ import { Button } from "@dilato/ui" 등으로 사용 가능. 자세한 내용은 docs/LLM_CONSUMER_GUIDE.md 참고.
의존성 추가
npm install -D tailwindcss @tailwindcss/postcss tailwindcss-animate- Tailwind CSS v4,
@tailwindcss/postcss,tailwindcss-animate필수 - peer: React 18/19, (선택) Next.js 15/16
PostCSS 설정 – postcss.config.mjs:
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
};
export default config;소비 프로젝트 메인 CSS 파일 (예: app/globals.css) 최상단에 다음 2줄을 추가합니다:
@import "@dmtPlatformInMarch/dilato-design-system/styles";
@import "@dmtPlatformInMarch/dilato-design-system/tailwind.css";| 항목 | 역할 |
|---|---|
styles |
Pretendard 폰트, Tailwind, Sonner, 시맨틱 토큰(색상·텍스트), 원시 색 @theme (bg-mint-50, text-violet-600 등) |
tailwind.css |
DS dist 스캔 (@source) – DS 컴포넌트 클래스가 번들에 포함되도록 함 |
솔루션·납품 브랜드로 시맨틱 토큰만 바꾸는 방법은 docs/CONSUMER_BRAND_TOKENS.md를 참고하세요.
Tooltip과 Toast를 사용하려면 Root Layout에 Provider를 추가합니다:
import { TooltipProvider, Toaster } from "@dmtPlatformInMarch/dilato-design-system/ui";
export default function RootLayout({ children }) {
return (
<html lang="ko">
<body>
<TooltipProvider>
{children}
<Toaster />
</TooltipProvider>
</body>
</html>
);
}서브패스별로 import 합니다. Base UI 직접 import는 사용하지 않습니다.
// UI 컴포넌트
import { Button, Card, Input, Label } from "@dmtPlatformInMarch/dilato-design-system/ui";
// 패턴 (Form, DataTable 등 – "use client" 필요)
import { Form, DataTable, Header, Footer } from "@dmtPlatformInMarch/dilato-design-system/patterns";
// 로고, 차트 등
import { DmtLogo } from "@dmtPlatformInMarch/dilato-design-system/logo";
import { D3LineChart } from "@dmtPlatformInMarch/dilato-design-system/charts";- CSS: 위 2줄(
styles,tailwind.css)만 import.token-variables,token-text-styles,primitive-theme는styles에 포함되며 직접 import하지 않음. - Base UI:
@base-ui/react직접 import 금지. DS 컴포넌트만 사용. - 패턴: Form, DataTable 등은
"use client"필요. - Input/Combobox: HTML
size와 충돌하므로paddingSizeprop 사용. Select, NumberField는size사용. - Size 조합: Button sm + Input default, Button default + Input lg 권장. docs/LLM_CONSUMER_GUIDE.md 참고.
디자인 시스템 레포지토리를 직접 수정·개발할 때 참고하는 가이드입니다.
# 의존성 설치
npm install
# Storybook 실행
npm run storybook
# 빌드
npm run build
# 린트
npm run lint디자인 변경은 직접 src/tokens를 손으로 수정하지 말고, Figma export를 기준으로 반영합니다.
- Figma에서 토큰을 export하여
@.figma/tokens.collection.json을 최신 상태로 덮어씁니다. - 아래 스크립트로 source token 파일을 재생성합니다.
npm run tokens:figma이 단계에서 아래 파일이 Figma export 기준으로 갱신됩니다.
src/tokens/primitive-colors.tssrc/tokens/primitive-typography.tssrc/tokens/semantic-colors.tssrc/tokens/semantic-text-styles.ts
Figma @.figma/tokens.collection.json에서 변경할 수 있는 범위는 아래와 같습니다.
| Figma 토큰 범위 | 반영 파일 | 변경 예시 |
|---|---|---|
primitive.color.* |
src/tokens/primitive-colors.ts |
브랜드 팔레트, gray/mint/blue/violet/rose/yellow 스케일 |
primitive.fontSize, primitive.fontWeight, primitive.letterSpacing |
src/tokens/primitive-typography.ts |
폰트 크기, 굵기, 자간 |
semantic.colors.light.*, semantic.colors.dark.* |
src/tokens/semantic-colors.ts |
primary, background, mutedForeground, inputBg 등 역할별 색상 |
semantic.text.* |
src/tokens/semantic-text-styles.ts |
heading-1, body-small, caption 등 텍스트 스타일. lineHeight는 px 기준 절대값 |
반대로 아래 항목은 현재 Figma export로 직접 바꾸지 않고 코드에서 유지합니다.
| 코드 유지 범위 | 위치 | 비고 |
|---|---|---|
| 시맨틱 그라데이션 | src/tokens/semantic-colors.ts |
semanticGradientsLight, semanticGradientsDark |
| 모션 토큰 | src/tokens/motion-styles.ts |
transition, clickable, popup motion 등 |
- CSS 변수와 텍스트 utility를 다시 생성합니다.
npm run tokens:csstoken-variables.css: 시맨틱 색상 CSS 변수primitive-theme.css: 원시 팔레트 Tailwind@theme(primitive-colors.ts→bg-mint-*,text-violet-*등)token-text-styles.css: 텍스트@utility클래스
- 로컬에서 UI를 확인합니다.
npm run dev
npm run storybook- 배포 전 최종 검증을 진행합니다.
npm run build컴포넌트를 개발하고 테스트하기 위해 Storybook을 사용합니다.
npm run storybook브라우저에서 http://localhost:6006로 접속하여 컴포넌트를 확인할 수 있습니다.
모든 Story 파일은 .storybook/stories/ 폴더에 작성합니다 (서브폴더: ui/, patterns/, tokens/ 등).
// .storybook/stories/ui/Button.stories.tsx
import type { Meta, StoryObj } from "@storybook/react";
import { Button } from "../../ui/button";
const meta: Meta<typeof Button> = {
title: "UI/Button",
component: Button,
tags: ["autodocs"],
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Default: Story = {
args: {
children: "Button",
},
};- 해당 폴더(
logo,ui,patterns,charts,auth)에 컴포넌트 파일 생성 - 폴더의
index.ts에 export 추가 .storybook/stories/폴더에 Story 파일 생성
이 레포를 Git 의존성으로 설치할 때 prepare 스크립트가 자동으로 빌드를 실행합니다. 로컬 개발 시에는 직접 실행하세요:
npm run build- tsup으로
dist/에 CJS(.js), ESM(.mjs), 타입 선언(.d.ts)이 생성됩니다. - entry:
index.ts,logo/index.ts,ui/index.ts,patterns/index.ts,charts/index.ts,auth/index.ts
DILATO-Design-System/
├── logo/ # 로고 컴포넌트
├── ui/ # Base UI 기반 공식 UI 컴포넌트
├── patterns/ # DataTable, Form, TreeView 등 복합 패턴
├── charts/ # D3 기반 차트 컴포넌트
├── auth/ # Dilato Platform 전용 인증 컴포넌트
├── layouts/ # Header, Footer 등 레이아웃
├── .storybook/ # Storybook 설정 및 스토리 파일
│ ├── stories/ # 모든 Story 파일
│ ├── main.ts # Storybook 메인 설정
│ └── preview.tsx # Storybook 프리뷰 설정
├── src/
│ ├── lib/ # 유틸리티 함수 (cn 등)
│ ├── tokens/ # 디자인 토큰
│ │ ├── primitive-colors.ts # 원시 색 팔레트 (mint, blue, gray 등)
│ │ ├── primitive-typography.ts # 원시 타이포그래피
│ │ ├── semantic-colors.ts # 시맨틱 색상 (primary, background 등)
│ │ ├── semantic-text-styles.ts # 시맨틱 텍스트 스타일
│ │ └── motion-styles.ts # 모션 variants, transition
│ └── styles/ # 전역 스타일
│ ├── globals.css # 메인 진입점 (토큰 import)
│ ├── token-variables.css # 시맨틱 색상 CSS 변수 (자동 생성)
│ ├── token-text-styles.css # 텍스트 @utility (자동 생성)
│ ├── primitive-theme.css # 원시 색 @theme (자동 생성)
│ └── tailwind.css # Tailwind v4 @source
├── scripts/
│ ├── generate-token-css.ts # semantic-colors → token-variables.css
│ ├── generate-text-styles.ts # semantic-text-styles → token-text-styles.css
│ └── generate-primitive-theme-css.ts
├── tailwind.preset.js # Tailwind 색상/테마 확장
├── package.json
├── tsconfig.json
└── README.md
- 원시 토큰 →
src/tokens/primitive-colors.ts,primitive-typography.ts - 시맨틱 토큰 →
src/tokens/semantic-colors.ts,semantic-text-styles.ts - 빌드 스크립트 →
npm run tokens:css실행 시:token-variables.css(--background, --primary 등 CSS 변수)token-text-styles.css(@utility typo-heading-1 등)primitive-theme.css(mint, blue, gray, violet, yellow, rose × 50–900 →bg-mint-50등)
- Tailwind 매핑 →
globals.css@theme +tailwind.preset.js에서var(--primary)→primary등 연결 - 컴포넌트 →
ui/에서 Tailwind 클래스(bg-primary,typo-heading-1) 사용
| 구분 | 컴포넌트 |
|---|---|
| RSC 가능 (서버 컴포넌트) | Card, Input, Textarea, Badge, Divider, Skeleton, LoadingIndicator (motion·Base UI·hooks 없음) |
클라이언트 전용 ("use client") |
Button, Accordion, Dialog, Select, DropdownMenu, Checkbox, Tabs, Form, DataTable 등 (motion, Base UI, hooks 사용) |
페이지에서는 항상 @/ui 등 DS 래퍼를 사용하며, Base UI를 직접 import하지 않습니다.
| 구분 | 위치 |
|---|---|
| 원시 색 팔레트 | src/tokens/primitive-colors.ts (mint, blue, gray 등) |
| 원시 색 Tailwind | primitive-colors.ts → primitive-theme.css (@theme → bg-mint-50, text-violet-600 등) |
| 시맨틱 색상 | src/tokens/semantic-colors.ts → token-variables.css (--background, --primary 등) |
| Tailwind 매핑 | tailwind.preset.js, globals.css @theme |
| 시맨틱 텍스트 | semantic-text-styles.ts → token-text-styles.css (@utility typo-heading-1 등) |
스타일 작성 기준
- variant/size: CVA + Tailwind (
bg-primary,text-primary-foreground등) - 색상: UI는 시맨틱 클래스 우선 (
bg-primary,text-muted-foreground). 차트·강조 등에만 원시 팔레트bg-mint-*,text-violet-*등 사용. 직접var(--primary)작성은 지양. - 타이포그래피:
typo-heading-1,typo-body,typo-body-small등 @utility 클래스
DS 진입점: ui/index.ts에서 Button, Card, Input 등 re-export. @/ui 또는 패키지 경로로 import.
DS 표준 props 예시 (Button): variant, size, round, asChild, loading
참고용 예시 파일
- variant/size 패턴:
ui/button.tsx,ui/badge.tsx(CVA + Tailwind) - Base UI + motion 래핑:
ui/dialog.tsx,ui/accordion.tsx,ui/select.tsx - 순수 스타일 컴포넌트:
ui/card.tsx,ui/input.tsx
모션 토큰: src/tokens/motion-styles.ts (motionTransition, clickable, getPopupMotionVariants 등)
SSR/Hydration 안전 패턴
- Collapsible/Accordion 패널처럼 초기 HTML에 포함되는 모션:
initial={false}사용 (accordion, slide-menu 참고) - 포털 팝업(Select, Dropdown, Combobox):
getPopupMotionVariants로 initial/open/closed 적용
피해야 할 패턴: SSR에 포함되는 컴포넌트에서 initial={{ opacity: 0 }} 등 서버/클라이언트 결과가 달라질 수 있는 값 사용 → hydration 경고나 화면 깜빡임 발생 가능.
로고 컴포넌트 모음
import { DmtLogo, LogoStandard, LogoBlue } from "@dmtPlatformInMarch/dilato-design-system/logo";Base UI 기반의 기본 UI 컴포넌트
- Button, Badge, Card, Input, Textarea
- Accordion, Dialog, Select, DropdownMenu, Combobox
- Checkbox, RadioGroup, Tabs, Tooltip, HoverCard
- Tooltip: 소비 프로젝트에서
모바일 = Popover/데스크톱 = Tooltip처럼 직접 분기할 필요가 없습니다. DS가(pointer: coarse)(터치 위주)일 때 내부적으로 Base UIPopover로 열리고, 그 외에는 기존 Tooltip입니다. 루트forcePointerMode로 스토리북·테스트에서만 강제할 수 있습니다. - Toast - Sonner 기반.
Toaster추가 후showSuccessToast/showErrorToast(@/src/lib/toast) 권장 - 등등...
재사용 가능한 패턴 컴포넌트
- Header (
logoSlot으로 솔루션 로고; 클릭·라우팅은 슬롯 내부 또는onLogoClick등으로 구성) - Footer (
logoSlot,footerMainSlot— 회사정보·문의·링크 블록 대체 시 앱에서 문구 책임) - Sidebar
- 등등...
@dmtPlatformInMarch/dilato-design-system/layouts에서 AppShell(headerProps, footerProps, 선택 solutionLogoSlot) — 헤더·푸터 로고를 한 번에 넘길 때 solutionLogoSlot; 헤더/푸터만 다르면 각각 logoSlot 우선.
D3 기반 차트 컴포넌트
- LineChart
- BarChart
- PieChart
- 등등...
Dilato Platform 전용 인증 컴포넌트 (준비 중)
import "@dmtPlatformInMarch/dilato-design-system/auth";Private - 디엠티 랩스 내부 사용 전용
이 프로젝트는 디엠티 랩스 사내 프로젝트입니다. 기여하려면 팀에 문의하세요.
문의사항이 있으시면 팀에 연락해주세요.