diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 12f2782d..d75ecae0 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -1,3 +1,4 @@ + language: "ko-KR" early_access: false diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index c1e3862f..9ebd00fc 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -38,9 +38,13 @@ jobs: - name: Publish to Chromatic id: chromatic - run: pnpm chromatic - env: - CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + uses: chromaui/action@latest + with: + projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + workingDir: packages/timo-design-system + buildScriptName: build:storybook + onlyChanged: true + exitZeroOnChanges: true - name: Comment Storybook preview link on PR if: success() diff --git a/packages/tailwind-config/tokens/colors.css b/packages/tailwind-config/tokens/colors.css index 1deec929..ae3ada7b 100644 --- a/packages/tailwind-config/tokens/colors.css +++ b/packages/tailwind-config/tokens/colors.css @@ -1,21 +1,23 @@ @theme { - --color-timo-blue-50: #F1F6FE; - --color-timo-blue-75: #C6D8FC; - --color-timo-blue-100: #AEC8FB; - --color-timo-blue-200: #8CB0F9; - --color-timo-blue-300: #74A0F8; + --color-timo-blue-50: #f1f6fe; + --color-timo-blue-65: #dee9ff; + --color-timo-blue-75: #c6d8fc; + --color-timo-blue-100: #aec8fb; + --color-timo-blue-200: #8cb0f9; + --color-timo-blue-300: #74a0f8; - --color-timo-gray-300: #F5F5F5; - --color-timo-gray-500: #E6E8E8; - --color-timo-gray-600: #D8D8D8; - --color-timo-gray-700: #9F9F9F; - --color-timo-gray-800: #757575; - --color-timo-gray-900: #3F3F3F; + --color-timo-gray-200: #fbfbfb; + --color-timo-gray-300: #f5f5f5; + --color-timo-gray-500: #e6e8e8; + --color-timo-gray-600: #d8d8d8; + --color-timo-gray-700: #9f9f9f; + --color-timo-gray-800: #757575; + --color-timo-gray-900: #3f3f3f; - --color-timo-yellow-300: #F2FC9F; - - --color-timo-black: #121212; - --color-timo-red: #FF6650; - --color-timo-orange: #FFB157; - --color-timo-green: #9FDDA9; -} \ No newline at end of file + --color-timo-yellow-300: #f2fc9f; + + --color-timo-black: #121212; + --color-timo-red: #ff6650; + --color-timo-orange: #ffb157; + --color-timo-gray: #bebebe; +} diff --git a/packages/tailwind-config/tokens/typography.css b/packages/tailwind-config/tokens/typography.css index 83e5b15e..099da0d6 100644 --- a/packages/tailwind-config/tokens/typography.css +++ b/packages/tailwind-config/tokens/typography.css @@ -2,11 +2,27 @@ --font-pretendard: var(--font-family-pretendard), sans-serif; /* Headline */ + + --typo-size-headline-b-50: 50px; + --typo-line-height-headline-b-50: 1.5; + --typo-letter-spacing-headline-b-50: -0.03em; + --typo-font-weight-headline-b-50: 700; + + --typo-size-headline-b-40: 40px; + --typo-line-height-headline-b-40: 1.5; + --typo-letter-spacing-headline-b-40: -0.03em; + --typo-font-weight-headline-b-40: 700; + --typo-size-headline-b-30: 30px; --typo-line-height-headline-b-30: 1.5; --typo-letter-spacing-headline-b-30: -0.03em; --typo-font-weight-headline-b-30: 700; + --typo-size-headline-m-26: 26px; + --typo-line-height-headline-m-26: 1.5; + --typo-letter-spacing-headline-m-26: -0.03em; + --typo-font-weight-headline-m-26: 500; + --typo-size-headline-b-24: 24px; --typo-line-height-headline-b-24: 1.5; --typo-letter-spacing-headline-b-24: -0.03em; @@ -22,6 +38,11 @@ --typo-letter-spacing-headline-b-20: -0.03em; --typo-font-weight-headline-b-20: 700; + --typo-size-headline-m-20: 20px; + --typo-line-height-headline-m-20: 1.5; + --typo-letter-spacing-headline-m-20: -0.03em; + --typo-font-weight-headline-m-20: 500; + --typo-size-headline-b-18: 18px; --typo-line-height-headline-b-18: 1.5; --typo-letter-spacing-headline-b-18: -0.03em; @@ -90,4 +111,4 @@ line-height: --value(--typo-line-height-*); letter-spacing: --value(--typo-letter-spacing-*); font-weight: --value(--typo-font-weight-*); -} \ No newline at end of file +} diff --git a/packages/timo-design-system/.storybook/manager-head.html b/packages/timo-design-system/.storybook/manager-head.html new file mode 100644 index 00000000..e0495580 --- /dev/null +++ b/packages/timo-design-system/.storybook/manager-head.html @@ -0,0 +1,21 @@ + diff --git a/packages/timo-design-system/.storybook/manager.ts b/packages/timo-design-system/.storybook/manager.ts new file mode 100644 index 00000000..1d565afb --- /dev/null +++ b/packages/timo-design-system/.storybook/manager.ts @@ -0,0 +1,7 @@ +import { addons } from "@storybook/manager-api"; + +import { timoTheme } from "./theme"; + +addons.setConfig({ + theme: timoTheme, +}); diff --git a/packages/timo-design-system/.storybook/preview.ts b/packages/timo-design-system/.storybook/preview.ts index 10bd36ee..bb861596 100644 --- a/packages/timo-design-system/.storybook/preview.ts +++ b/packages/timo-design-system/.storybook/preview.ts @@ -1,7 +1,26 @@ +import React from "react"; + +import type { Preview } from "@storybook/react"; + import "../src/styles/globals.css"; -import type { Preview } from "@storybook/react-vite"; const preview: Preview = { + decorators: [ + (Story) => + React.createElement( + "div", + { + style: { + padding: "2rem", + display: "flex", + justifyContent: "center", + alignItems: "center", + minHeight: "120px", + }, + }, + React.createElement(Story), + ), + ], parameters: { controls: { matchers: { @@ -21,7 +40,7 @@ const preview: Preview = { styles: { width: "1280px", height: "900px" }, }, }, - defaultViewport: "desktop", + defaultViewport: "responsive", }, layout: "centered", backgrounds: { diff --git a/packages/timo-design-system/.storybook/theme.ts b/packages/timo-design-system/.storybook/theme.ts new file mode 100644 index 00000000..f8154c02 --- /dev/null +++ b/packages/timo-design-system/.storybook/theme.ts @@ -0,0 +1,42 @@ +import { create } from "@storybook/theming"; + +export const timoTheme = create({ + base: "light", + + brandImage: "/timo-logo/timo-logo.png", + brandTitle: "TIMO DESIGN SYSTEM", + brandUrl: "https://timo.kr", + brandTarget: "_blank", + + // 배경 + colorPrimary: "#74A0F8", + colorSecondary: "#8CB0F9", + + // UI + appBg: "#f5f5f5", + appContentBg: "#ffffff", + appPreviewBg: "#ffffff", + appBorderColor: "#e5e5e5", + appBorderRadius: 10, + + // 텍스트 + textColor: "#1f1f1f", + textMutedColor: "#757575", + textInverseColor: "#ffffff", + + // 툴바 + barTextColor: "#525252", + barHoverColor: "#8CB0F9", + barSelectedColor: "#74a0f8", + barBg: "#ffffff", + + // 인풋 + inputBg: "#ffffff", + inputBorder: "#e5e5e5", + inputTextColor: "#1f1f1f", + inputBorderRadius: 6, + + // 버튼 + buttonBg: "#f5f5f5", + buttonBorder: "#e5e5e5", +}); diff --git a/packages/timo-design-system/.storybook/typings.d.ts b/packages/timo-design-system/.storybook/typings.d.ts new file mode 100644 index 00000000..cbe652db --- /dev/null +++ b/packages/timo-design-system/.storybook/typings.d.ts @@ -0,0 +1 @@ +declare module "*.css"; diff --git a/packages/timo-design-system/package.json b/packages/timo-design-system/package.json index cc41ce8b..9bd12733 100644 --- a/packages/timo-design-system/package.json +++ b/packages/timo-design-system/package.json @@ -25,8 +25,10 @@ "@storybook/addon-essentials": "8.6.14", "@storybook/addon-interactions": "8.6.14", "@storybook/addon-links": "^8.6.14", + "@storybook/manager-api": "^8.6.14", "@storybook/react": "8.6.14", "@storybook/react-vite": "^8.6.14", + "@storybook/theming": "^8.6.14", "@tailwindcss/postcss": "^4.3.1", "@types/node": "^22.15.3", "@types/react": "19.2.2", diff --git a/packages/timo-design-system/public/timo-logo/timo-logo.png b/packages/timo-design-system/public/timo-logo/timo-logo.png new file mode 100644 index 00000000..d2439a84 Binary files /dev/null and b/packages/timo-design-system/public/timo-logo/timo-logo.png differ diff --git a/packages/timo-design-system/src/components/index.ts b/packages/timo-design-system/src/components/index.ts index ef907737..9ae8ca5a 100644 --- a/packages/timo-design-system/src/components/index.ts +++ b/packages/timo-design-system/src/components/index.ts @@ -1,2 +1,4 @@ export { Color } from "./color/Color"; export { Typography } from "./typography/Typography"; +export { Tag } from "./tag/Tag"; +export { PriorityIcon } from "./priority-icon/PriorityIcon"; diff --git a/packages/timo-design-system/src/components/priority-icon/PriorityIcon.stories.tsx b/packages/timo-design-system/src/components/priority-icon/PriorityIcon.stories.tsx new file mode 100644 index 00000000..8b5b7e5e --- /dev/null +++ b/packages/timo-design-system/src/components/priority-icon/PriorityIcon.stories.tsx @@ -0,0 +1,91 @@ +import { PriorityIcon, type Priority } from "./PriorityIcon"; + +import type { Meta, StoryObj } from "@storybook/react"; + +const meta = { + title: "Components/PriorityIcon", + component: PriorityIcon, + parameters: { + layout: "centered", + }, + argTypes: { + priority: { + control: "select", + options: ["매우중요", "중요", "보통", "낮음", "Disable", "white", "blue"], + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const 매우중요: Story = { + args: { priority: "매우중요" }, +}; + +export const 중요: Story = { + args: { priority: "중요" }, +}; + +export const 보통: Story = { + args: { priority: "보통" }, +}; + +export const 낮음: Story = { + args: { priority: "낮음" }, +}; + +export const Disable: Story = { + args: { priority: "Disable" }, +}; + +export const white: Story = { + args: { priority: "white" }, + parameters: { + backgrounds: { + default: "dark", + values: [ + { name: "light-gray", value: "#F5F5F5" }, + { name: "dark", value: "#333333" }, + { name: "white", value: "#FFFFFF" }, + ], + }, + }, +}; +export const blue: Story = { + args: { priority: "blue" }, +}; + +const ALL_PRIORITIES: Priority[] = [ + "매우중요", + "중요", + "보통", + "낮음", + "Disable", + "white", + "blue", +]; + +export const AllPriorities: Story = { + args: { priority: "매우중요" }, + parameters: { + backgrounds: { + default: "light-gray", + values: [ + { name: "light-gray", value: "#F5F5F5" }, + { name: "dark", value: "#333333" }, + { name: "white", value: "#FFFFFF" }, + ], + }, + }, + render: () => ( +
+ {ALL_PRIORITIES.map((priority) => ( +
+ + {priority} +
+ ))} +
+ ), +}; diff --git a/packages/timo-design-system/src/components/priority-icon/PriorityIcon.tsx b/packages/timo-design-system/src/components/priority-icon/PriorityIcon.tsx new file mode 100644 index 00000000..83a235fb --- /dev/null +++ b/packages/timo-design-system/src/components/priority-icon/PriorityIcon.tsx @@ -0,0 +1,32 @@ +import { cn } from "../../lib"; + +export type Priority = + | "매우중요" + | "중요" + | "보통" + | "낮음" + | "Disable" + | "white" + | "blue"; + +const PRIORITY_COLOR: Record = { + 매우중요: "bg-timo-red", + 중요: "bg-timo-orange", + 보통: "bg-timo-gray-600", + 낮음: "bg-timo-black", + Disable: "bg-timo-gray-500", + white: "bg-white", + blue: "bg-timo-blue-300", +}; + +export interface PriorityIconProps { + priority: Priority; +} + +export const PriorityIcon = ({ priority }: PriorityIconProps) => { + return ( +
+ ); +}; diff --git a/packages/timo-design-system/src/components/tag/Tag.stories.tsx b/packages/timo-design-system/src/components/tag/Tag.stories.tsx new file mode 100644 index 00000000..6e61d914 --- /dev/null +++ b/packages/timo-design-system/src/components/tag/Tag.stories.tsx @@ -0,0 +1,33 @@ +import { Tag } from "./Tag"; + +import type { Meta, StoryObj } from "@storybook/react"; + +const meta = { + title: "Components/Tag", + component: Tag, + parameters: { + layout: "centered", + }, + argTypes: { + text: { + control: "text", + description: "태그에 표시될 텍스트", + }, + variant: { + control: "select", + options: ["default", "blue"], + description: "태그 스타일 베리언트", + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { text: "과제", variant: "default" }, +}; + +export const Blue: Story = { + args: { text: "과제", variant: "blue" }, +}; diff --git a/packages/timo-design-system/src/components/tag/Tag.tsx b/packages/timo-design-system/src/components/tag/Tag.tsx new file mode 100644 index 00000000..96e6efe3 --- /dev/null +++ b/packages/timo-design-system/src/components/tag/Tag.tsx @@ -0,0 +1,25 @@ +export type TagVariant = "default" | "blue"; + +export interface TagProps { + text: string; + variant?: TagVariant; +} + +export const Tag = ({ text, variant = "default" }: TagProps) => { + const isBlue = variant === "blue"; + return ( +
+ + {text} + +
+ ); +}; diff --git a/packages/timo-design-system/src/components/typography/Typography.tsx b/packages/timo-design-system/src/components/typography/Typography.tsx index d4c42514..6db0a831 100644 --- a/packages/timo-design-system/src/components/typography/Typography.tsx +++ b/packages/timo-design-system/src/components/typography/Typography.tsx @@ -18,7 +18,7 @@ export const Typography = ({ }} >
- 가나다라마 Aa + 계획 실행의 과정을 함께하는 Timo
; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: {}, +}; diff --git a/turbo/generators/templates/component/component.tsx.hbs b/turbo/generators/templates/component/component.tsx.hbs index d2beb1eb..5e80ae06 100644 --- a/turbo/generators/templates/component/component.tsx.hbs +++ b/turbo/generators/templates/component/component.tsx.hbs @@ -1,4 +1,4 @@ -interface {{pascalCase name}}Props { +export interface {{pascalCase name}}Props { className?: string; }