Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
8 changes: 4 additions & 4 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import type { StorybookConfig } from "@storybook/nextjs-vite";
const require = createRequire(import.meta.url);

const config: StorybookConfig = {
stories: ["../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
"@chromatic-com/storybook",
"@storybook/addon-docs",
stories: [
"../src/**/*.mdx",
"../src/**/*.stories.@(js|jsx|mjs|ts|tsx)",
],
addons: ["@chromatic-com/storybook", "@storybook/addon-docs"],
framework: "@storybook/nextjs-vite",
staticDirs: ["../public"],

Expand Down
4 changes: 4 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import type { Preview } from "@storybook/nextjs-vite";
import { INITIAL_VIEWPORTS } from "storybook/viewport";

const preview: Preview = {
parameters: {
viewport: {
options: INITIAL_VIEWPORTS,
},
controls: {
matchers: {
color: /(background|color)$/i,
Expand Down
2 changes: 1 addition & 1 deletion .vscode/workspace.code-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"StoryBook": {
"prefix": ["!sb", "!storybook"],
"body": [
"import type { Meta, StoryObj } from '@storybook/react-vite';\n",
"import type { Meta, StoryObj } from '@storybook/nextjs-vite';\n",

"const meta: Meta<typeof ${1:Component}> = {",
" component: ${1:Component},",
Expand Down
29 changes: 29 additions & 0 deletions src/entities/feed/ui/FeedCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FeedCard } from "./FeedCard";
import type { Meta, StoryObj } from "@storybook/nextjs-vite";
import { expect, userEvent, within } from "storybook/test";

const meta: Meta<typeof FeedCard> = {
component: FeedCard,
};

export default meta;
type Story = StoryObj<typeof FeedCard>;

export const Default: Story = {
args: {},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const likeButton = canvas.getByRole("button", { name: "좋아요" });

const heartIcon = likeButton.querySelector("svg") as SVGSVGElement;
await userEvent.click(heartIcon);

const unlikeButton = canvas.getByRole("button", { name: "좋아요 취소" });
await expect(unlikeButton).toBeInTheDocument();

await userEvent.click(heartIcon);

const likeButtonAgain = canvas.getByRole("button", { name: "좋아요" });
await expect(likeButtonAgain).toBeInTheDocument();
},
};
70 changes: 70 additions & 0 deletions src/shared/ui/badge/Badge.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as BadgeStories from "./Badge.stories";
import {
Meta,
Canvas,
Controls,
Story,
Description,
ArgTypes,
Source,
} from "@storybook/addon-docs/blocks";

<Meta of={BadgeStories} />

# Badge

상태나 카테고리를 나타내는 작은 라벨 컴포넌트입니다.

<Canvas of={BadgeStories.Default} />

## Props

<Controls />

## Examples

### Variants

`Badge` 컴포넌트는 5가지 스타일(`primary`, `secondary`, `success`, `danger`,`warning`)을 지원합니다.

<Canvas of={BadgeStories.Variants} />

<Source
language="tsx"
code={`
<Badge variant="primary">primary</Badge>
<Badge variant="secondary">secondary</Badge>
<Badge variant="success">success</Badge>
<Badge variant="danger">danger</Badge>
<Badge variant="warning">warning</Badge>
`}
/>

<br />

### Sizes

`Badge` 컴포넌트는 3가지 크기(`sm`, `md`, `lg`)를 지원합니다.

<Canvas of={BadgeStories.Sizes} />

<Source
language="tsx"
code={`
<Badge size="small">Small</Badge>
<Badge size="medium">Medium</Badge>
<Badge size="large">Large</Badge>
`}
/>

<br />

## 사용 가이드 (Usage)

`children` prop을 통해 뱃지 텍스트를 전달합니다.

```tsx
<Badge variant="primary" size="medium">
뱃지 텍스트
</Badge>
```
38 changes: 38 additions & 0 deletions src/shared/ui/badge/Badge.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Badge } from "./Badge";
import type { Meta, StoryObj } from "@storybook/nextjs-vite";

const meta: Meta<typeof Badge> = {
title: "design-system/Badge",
component: Badge,
};

export default meta;
type Story = StoryObj<typeof Badge>;

export const Default: Story = {
args: { children: "뱃지입니다." },
};

export const Variants: Story = {
args: { children: "variants" },
render: () => (
<div style={{ display: "flex", flexDirection: "row", gap: "10px" }}>
<Badge variant="primary">primary</Badge>
<Badge variant="secondary">secondary</Badge>
<Badge variant="success">success</Badge>
<Badge variant="danger">danger</Badge>
<Badge variant="warning">warning</Badge>
</div>
),
};

export const Sizes: Story = {
args: { children: "size" },
render: () => (
<div style={{ display: "flex", flexDirection: "row", gap: "10px" }}>
<Badge size="large">Large</Badge>
<Badge size="medium">Medium</Badge>
<Badge size="small">Small</Badge>
</div>
),
};
48 changes: 48 additions & 0 deletions src/shared/ui/header/Header.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Header } from "./Header";
import type { Meta, StoryObj } from "@storybook/nextjs-vite";
import { expect, userEvent, within } from "storybook/test";

const meta: Meta<typeof Header> = {
title: "shared/Header",
component: Header,
parameters: {
layout: "fullscreen",
nextjs: {
appDirectory: true,
navigation: {
pathname: "/",
},
},
},
};

export default meta;
type Story = StoryObj<typeof Header>;

export const Desktop: Story = {};

export const Mobile: Story = {
globals: {
viewport: {
value: "iphone12",
isRotated: false,
},
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);

const menuButton = canvas.getByRole("button", { name: "메뉴 열기" });

await expect(menuButton).toBeInTheDocument();

await userEvent.click(menuButton);

const closeButton = canvas.getByRole("button", { name: "닫기" });

await expect(closeButton).toBeVisible();

await userEvent.click(closeButton);

await expect(menuButton).toBeInTheDocument();
},
};
Loading