From 921d69c4dd7759e88cc0607d664f6a496b41461a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=A0=95=EC=9B=90?= Date: Wed, 4 Feb 2026 19:56:49 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EB=82=B4=EC=9A=A9?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icons/kebab/kebabLarge.svg | 5 + src/assets/icons/kebab/kebabSmall.svg | 5 + .../comment/CommentCard.stories.tsx | 137 ++++++++++++++++++ src/components/comment/CommentCard.tsx | 40 +++++ src/components/comment/index.ts | 2 + .../comment/styles/CommentCard.module.css | 66 +++++++++ src/components/comment/types/types.ts | 18 +++ 7 files changed, 273 insertions(+) create mode 100644 src/assets/icons/kebab/kebabLarge.svg create mode 100644 src/assets/icons/kebab/kebabSmall.svg create mode 100644 src/components/comment/CommentCard.stories.tsx create mode 100644 src/components/comment/CommentCard.tsx create mode 100644 src/components/comment/index.ts create mode 100644 src/components/comment/styles/CommentCard.module.css create mode 100644 src/components/comment/types/types.ts diff --git a/src/assets/icons/kebab/kebabLarge.svg b/src/assets/icons/kebab/kebabLarge.svg new file mode 100644 index 0000000..ed76545 --- /dev/null +++ b/src/assets/icons/kebab/kebabLarge.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/icons/kebab/kebabSmall.svg b/src/assets/icons/kebab/kebabSmall.svg new file mode 100644 index 0000000..a883b49 --- /dev/null +++ b/src/assets/icons/kebab/kebabSmall.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/comment/CommentCard.stories.tsx b/src/components/comment/CommentCard.stories.tsx new file mode 100644 index 0000000..4122d3d --- /dev/null +++ b/src/components/comment/CommentCard.stories.tsx @@ -0,0 +1,137 @@ +import type { Meta, StoryObj } from '@storybook/nextjs-vite'; + +import { fn } from 'storybook/test'; + +import CommentCard from './CommentCard'; + +const meta = { + title: 'Components/CommentCard', + component: CommentCard, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + args: { + name: '안해나', + content: '오늘 할 일 목록을 정리했습니다.', + date: '2025.01.15', + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; + +export const WithProfileImage: Story = { + args: { + profileImage: ( +
+ ), + }, +}; + +export const WithIcon: Story = { + args: { + profileImage: ( +
+ ), + icon: ( + + ), + }, +}; + +export const WithActions: Story = { + args: { + profileImage: ( +
+ ), + icon: ( + + ), + actions: ( +
+ + +
+ ), + }, +}; + +export const Overview: Story = { + render: () => ( +
+ + + } + /> + + } + icon={} + actions={ +
+ 취소 + 수정하기 +
+ } + /> +
+ ), + parameters: { + controls: { disable: true }, + }, +}; diff --git a/src/components/comment/CommentCard.tsx b/src/components/comment/CommentCard.tsx new file mode 100644 index 0000000..e892a8b --- /dev/null +++ b/src/components/comment/CommentCard.tsx @@ -0,0 +1,40 @@ +import styles from './styles/CommentCard.module.css'; +import type { CommentCardProps } from './types/types'; + +/** + * 댓글 카드 컴포넌트. + * 프로필 이미지, 이름, 내용, 날짜를 표시합니다. + * icon 슬롯에 케밥 메뉴를, actions 슬롯에 수정/취소 버튼을 주입할 수 있습니다. + */ +export default function CommentCard({ + profileImage, + name, + content, + date, + dateTime, + icon, + actions, +}: CommentCardProps) { + return ( +
+ {profileImage && ( + + )} +
+
+ {name} + {icon} +
+

{content}

+
+ + {actions} +
+
+
+ ); +} diff --git a/src/components/comment/index.ts b/src/components/comment/index.ts new file mode 100644 index 0000000..3db9baa --- /dev/null +++ b/src/components/comment/index.ts @@ -0,0 +1,2 @@ +export { default as CommentCard } from './CommentCard'; +export type { CommentCardProps } from './types/types'; diff --git a/src/components/comment/styles/CommentCard.module.css b/src/components/comment/styles/CommentCard.module.css new file mode 100644 index 0000000..9e8f735 --- /dev/null +++ b/src/components/comment/styles/CommentCard.module.css @@ -0,0 +1,66 @@ +.card { + display: flex; + gap: 12px; +} + +.avatar { + flex-shrink: 0; +} + +.body { + flex: 1; + min-width: 0; + display: flex; + flex-direction: column; + gap: 4px; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.name { + font-weight: 600; + font-size: 14px; + color: var(--color-text-tertiary); +} + +.content { + font-weight: 500; + font-size: 14px; + color: var(--color-text-secondary); + margin: 0; +} + +.footer { + display: flex; + justify-content: space-between; + align-items: center; +} + +.date { + font-weight: 400; + font-size: 12px; + color: var(--color-text-disabled); +} + +@media (max-width: 375px) { + .card { + gap: 8px; + } + + .avatar { + width: 24px; + height: 24px; + } + + .name { + font-size: 12px; + } + + .content { + font-size: 13px; + } +} diff --git a/src/components/comment/types/types.ts b/src/components/comment/types/types.ts new file mode 100644 index 0000000..8c4508a --- /dev/null +++ b/src/components/comment/types/types.ts @@ -0,0 +1,18 @@ +import type { ReactNode } from 'react'; + +export type CommentCardProps = { + /** 프로필 이미지 (ReactNode로 자유롭게 주입, 예: ``) */ + profileImage?: ReactNode; + /** 댓글 작성자 이름 */ + name: string; + /** 댓글 본문 내용 */ + content: string; + /** 화면에 표시할 날짜 텍스트 (예: "2024년 7월 29일") */ + date: string; + /** `