-
Notifications
You must be signed in to change notification settings - Fork 0
feat: mds 2.0 스토리북 설정 #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
f15f9d1
dd61c5b
fad8dc2
01ba2a8
00204c3
9613210
35d44a5
8f30783
f347bce
502d282
5cde83a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import { resolve } from "node:path"; | ||
| import type { StorybookConfig } from "@storybook/react-vite"; | ||
| import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; | ||
| import { mergeConfig } from "vite"; | ||
|
|
||
| const repoRoot = resolve(process.cwd(), "../.."); | ||
|
|
||
| const config: StorybookConfig = { | ||
| stories: [ | ||
| "../stories/**/*.mdx", | ||
| "../stories/**/*.stories.@(ts|tsx)", | ||
| { | ||
| directory: resolve(repoRoot, "packages/ui/src"), | ||
| files: "**/*.stories.@(ts|tsx)", | ||
| titlePrefix: "Components", | ||
| }, | ||
| { | ||
| directory: resolve(repoRoot, "packages/design-tokens/src"), | ||
| files: "**/*.stories.@(ts|tsx|mdx)", | ||
| titlePrefix: "Design Tokens", | ||
| }, | ||
| ], | ||
| addons: [ | ||
| "@storybook/addon-essentials", | ||
| "@storybook/addon-docs", | ||
| "@storybook/addon-a11y", | ||
| "@storybook/addon-themes", | ||
| ], | ||
| framework: { | ||
| name: "@storybook/react-vite", | ||
| options: {}, | ||
| }, | ||
| typescript: { | ||
| reactDocgen: "react-docgen-typescript", | ||
| }, | ||
| docs: { | ||
| defaultName: "소개", | ||
| }, | ||
| viteFinal: (viteConfig) => | ||
| mergeConfig(viteConfig, { | ||
| plugins: [vanillaExtractPlugin()], | ||
| }), | ||
| }; | ||
|
|
||
| export default config; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| body { | ||
| font-family: | ||
| "SUIT", -apple-system, BlinkMacSystemFont, "Pretendard", "Segoe UI", | ||
|
wuzoo marked this conversation as resolved.
Outdated
|
||
| sans-serif; | ||
| color: var(--color-foreground); | ||
| background: var(--color-background); | ||
| } | ||
|
|
||
| /** TODO(@wuzoo): 다크모드 static color 피드백 */ | ||
| .theme-dark { | ||
| --color-background: #0f1012; | ||
| --color-foreground: #f9fafb; | ||
| --color-foreground-muted: #b0b8c1; | ||
| --color-border: #333d4b; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { withThemeByClassName } from "@storybook/addon-themes"; | ||
| import type { Preview } from "@storybook/react"; | ||
| import "@makers/design-tokens/tokens.css"; | ||
| import "./preview.css"; | ||
|
|
||
| const preview: Preview = { | ||
| decorators: [ | ||
| withThemeByClassName({ | ||
| themes: { light: "theme-light", dark: "theme-dark" }, | ||
| defaultTheme: "light", | ||
| }), | ||
| ], | ||
| parameters: { | ||
| layout: "centered", | ||
| controls: { | ||
| matchers: { color: /(background|color)$/i, date: /Date$/i }, | ||
| }, | ||
| options: { | ||
| storySort: { | ||
| method: "alphabetical", | ||
| order: ["Introduction", "Design Tokens", "Components"], | ||
| }, | ||
| }, | ||
| backgrounds: { disable: true }, | ||
| docs: { | ||
| toc: true, | ||
| }, | ||
| }, | ||
| tags: ["autodocs"], | ||
| }; | ||
|
|
||
| export default preview; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| { | ||
| "name": "@makers/storybook", | ||
| "version": "0.0.0", | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "dev": "storybook dev -p 6006 --no-open", | ||
| "build": "storybook build --output-dir storybook-static", | ||
| "typecheck": "tsc --noEmit" | ||
| }, | ||
| "dependencies": { | ||
| "@makers/design-tokens": "workspace:*", | ||
| "@makers/ui": "workspace:*", | ||
| "react": "^18.3.1", | ||
| "react-dom": "^18.3.1" | ||
| }, | ||
| "devDependencies": { | ||
| "@chromatic-com/storybook": "^3.2.0", | ||
| "@makers/tsconfig": "workspace:*", | ||
| "@storybook/addon-a11y": "^8.4.7", | ||
| "@storybook/addon-docs": "^8.4.7", | ||
| "@storybook/addon-essentials": "^8.4.7", | ||
| "@storybook/addon-themes": "^8.4.7", | ||
| "@storybook/react": "^8.4.7", | ||
| "@storybook/react-vite": "^8.4.7", | ||
| "@vanilla-extract/vite-plugin": "^4.0.19", | ||
| "@types/node": "^22.0.0", | ||
| "@types/react": "^18.3.0", | ||
| "@types/react-dom": "^18.3.0", | ||
| "@vitejs/plugin-react": "^4.3.4", | ||
| "storybook": "^8.4.7", | ||
| "typescript": "^5.6.0", | ||
| "vite": "^5.4.11" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { Meta } from "@storybook/blocks"; | ||
|
|
||
| <Meta title="Introduction" /> | ||
|
|
||
| # Makers Design System | ||
|
|
||
| SOPT 사내 조직인 Makers의 디자인 시스템 2.0 버전입니다. | ||
|
|
||
| ## 구조 | ||
|
|
||
| - **Design Tokens** — 색상, 간격, 타이포그래피 등 시스템의 원시 값 | ||
| - **Components** — `@makers/ui` 가 제공하는 React 컴포넌트 | ||
|
|
||
| ## 설치 | ||
|
|
||
| 1. 디자인 토큰, UI 컴포넌트 | ||
|
|
||
| ```bash | ||
| pnpm add @makers/ui @makers/design-tokens | ||
| ``` | ||
|
|
||
| 2. Peer Dependencies | ||
|
|
||
| `react`와 `react-dom` 18 버전 이상이 필요합니다. | ||
|
|
||
| ```bash | ||
| pnpm add react react-dom | ||
| ``` | ||
|
|
||
| ## 컴포넌트 목록 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "extends": "@makers/tsconfig/library.json", | ||
| "include": [".storybook/**/*.ts", ".storybook/**/*.tsx", "vite.config.ts"], | ||
| "compilerOptions": { | ||
| "types": ["vite/client", "node", "react"] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; | ||
| import react from "@vitejs/plugin-react"; | ||
| import { defineConfig } from "vite"; | ||
|
|
||
| export default defineConfig({ | ||
| plugins: [react(), vanillaExtractPlugin()], | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "$schema": "https://json.schemastore.org/tsconfig", | ||
| "compilerOptions": { | ||
| "target": "ES2022", | ||
| "lib": ["ES2022"], | ||
| "module": "ESNext", | ||
| "moduleResolution": "Bundler", | ||
| "esModuleInterop": true, | ||
| "resolveJsonModule": true, | ||
| "isolatedModules": true, | ||
| "verbatimModuleSyntax": true, | ||
| "skipLibCheck": true, | ||
| "strict": true, | ||
| "noUncheckedIndexedAccess": true, | ||
| "noImplicitOverride": true, | ||
| "forceConsistentCasingInFileNames": true | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "$schema": "https://json.schemastore.org/tsconfig", | ||
| "extends": "./base.json", | ||
| "compilerOptions": { | ||
| "lib": ["ES2022", "DOM", "DOM.Iterable"], | ||
| "jsx": "react-jsx" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| { | ||
| "name": "@makers/tsconfig", | ||
| "version": "0.0.0", | ||
| "private": true | ||
| "private": true, | ||
| "files": ["base.json", "library.json"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,11 +7,18 @@ | |
| "format": "biome format --write .", | ||
| "lint": "biome lint .", | ||
| "release": "changeset publish", | ||
| "versioning": "changeset version && pnpm install --lockfile-only" | ||
| "versioning": "changeset version && pnpm install --lockfile-only", | ||
| "storybook": "pnpm --filter @makers/storybook dev", | ||
| "storybook:build": "pnpm --filter @makers/storybook build", | ||
| "typecheck": "pnpm -r typecheck", | ||
| "scaffold:component": "tsx scripts/scaffold-component.ts" | ||
| }, | ||
| "devDependencies": { | ||
| "@biomejs/biome": "^2.4.6", | ||
| "@changesets/cli": "^2.27.0", | ||
| "@inquirer/prompts": "^7.2.0", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런건 첨보네요 ㄷㄷ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오 이거 신기하네요
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cli 프롬프트에서 컴포넌트명을 입력받기 위해서 사용했어요. |
||
| "@types/node": "^22.19.17", | ||
| "tsx": "^4.21.0", | ||
| "typescript": "^5.6.0" | ||
| }, | ||
| "packageManager": "pnpm@10.26.2", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import type { Meta, StoryObj } from "@storybook/react"; | ||
| import { baseColor } from "./color"; | ||
|
|
||
| interface SwatchProps { | ||
| name: string; | ||
| value: string; | ||
| } | ||
|
|
||
| function Swatch({ name, value }: SwatchProps) { | ||
| return ( | ||
| <div style={{ display: "flex", alignItems: "center", gap: 12, padding: 8 }}> | ||
| <div | ||
| style={{ | ||
| width: 48, | ||
| height: 48, | ||
| borderRadius: 8, | ||
| background: value, | ||
| border: "1px solid #e5e8eb", | ||
| }} | ||
| /> | ||
| <div> | ||
| <div style={{ fontWeight: 600 }}>{name}</div> | ||
| <div style={{ fontFamily: "monospace", color: "#6b7684" }}>{value}</div> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| function ColorGrid() { | ||
| return ( | ||
| <div | ||
| style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8 }} | ||
| > | ||
| {Object.entries(baseColor).map(([name, value]) => ( | ||
| <Swatch key={name} name={name} value={value} /> | ||
| ))} | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| const meta: Meta<typeof ColorGrid> = { | ||
| title: "Base/Color", | ||
| component: ColorGrid, | ||
| parameters: { layout: "padded" }, | ||
| }; | ||
|
|
||
| export default meta; | ||
|
|
||
| export const Palette: StoryObj<typeof ColorGrid> = {}; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| export const baseColor = { | ||
| white: "#ffffff", | ||
| black: "#000000", | ||
| gray50: "#f9fafb", | ||
| gray100: "#f2f4f6", | ||
| gray200: "#e5e8eb", | ||
| gray300: "#d1d6db", | ||
| gray400: "#b0b8c1", | ||
| gray500: "#8b95a1", | ||
| gray600: "#6b7684", | ||
| gray700: "#4e5968", | ||
| gray800: "#333d4b", | ||
| gray900: "#191f28", | ||
| blue500: "#3182f6", | ||
| blue600: "#2272eb", | ||
| red500: "#f04452", | ||
| green500: "#00c896", | ||
| yellow500: "#f5a623", | ||
| } as const; | ||
|
|
||
| export type BaseColor = keyof typeof baseColor; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export * from "./color"; | ||
| export * from "./space"; | ||
| export * from "./typography"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import type { Meta, StoryObj } from "@storybook/react"; | ||
| import { space } from "./space"; | ||
|
|
||
| function SpaceScale() { | ||
| return ( | ||
| <div style={{ display: "flex", flexDirection: "column", gap: 8 }}> | ||
| {Object.entries(space).map(([token, value]) => ( | ||
| <div | ||
| key={token} | ||
| style={{ display: "flex", alignItems: "center", gap: 12 }} | ||
| > | ||
| <div style={{ width: 48, fontFamily: "monospace" }}>{token}</div> | ||
| <div style={{ background: "#3182f6", height: 16, width: value }} /> | ||
| <div style={{ color: "#6b7684" }}>{value}</div> | ||
| </div> | ||
| ))} | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| const meta: Meta<typeof SpaceScale> = { | ||
| title: "Base/Space", | ||
| component: SpaceScale, | ||
| parameters: { layout: "padded" }, | ||
| }; | ||
|
|
||
| export default meta; | ||
|
|
||
| export const Scale: StoryObj<typeof SpaceScale> = {}; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| export const space = { | ||
| "0": "0px", | ||
| "1": "2px", | ||
| "2": "4px", | ||
| "3": "8px", | ||
| "4": "12px", | ||
| "5": "16px", | ||
| "6": "20px", | ||
| "7": "24px", | ||
| "8": "32px", | ||
| "9": "40px", | ||
| "10": "48px", | ||
| } as const; | ||
|
|
||
| export type Space = keyof typeof space; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
단순 궁금증으로 이전에 design-system을 만들때 각 제품처에서 다른 css 라이브러리를 쓰다보니 스타일주입이나 interface에서 차이 및 제한이 있던 걸로 기억하는데 vanilla extract css 써도 괜찮은지, 생각하신 부분이 있으신지 궁금합니다!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제품처에서는 style prop을 사용하는 걸로 계획하고 있어요. emotion을 대부분 쓸텐데 디자인시스템에서 제공하는 컴포넌트를 커스텀하고 싶을 때는 style로 주입하도록이요.
ds에서 제공하는 컴포넌트들은 바익을 쓰기 때문이 일단 런타임이랑 상관없고 빌드타임에 className이 들어갈테고, 제품처에서 주입하는 style 객체들은 런타임에 할당돼요.
css는 cascading으로 우선순위가 판단되기 때문에 사용처에서 인라인으로 주입한 style 속성의 css가 우선적으로 반영될거에요.