Skip to content

Commit

Permalink
Merge pull request #145 from prgrms-web-devcourse-final-project/feature/
Browse files Browse the repository at this point in the history
#62

feature: ChatBubble 컴포넌트 개발
  • Loading branch information
ppyom authored Nov 29, 2024
2 parents 964eb18 + 562a756 commit dcedccd
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 10 deletions.
30 changes: 30 additions & 0 deletions src/components/organisms/ChatBubble/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Image } from "components/atoms";
import { ChatMessage } from "components/organisms";
import type { IChat } from "types";
import { ChatBubbleWrapper, ChatMessagesWrapper } from "./styled";

export interface IChatBubbleProps {
/** 채팅리스트 */
chats: IChat[];
/** 채팅 보낸 유저가 나인지 타인인지 구분 */
isMe: boolean;
/** 프로필 이미지 URL 경로 */
imgUrl?: string;
}

export const ChatBubble = ({ chats, isMe, imgUrl }: IChatBubbleProps) => {
return (
<ChatBubbleWrapper isMe={isMe}>
{!isMe && <Image type="round" url={imgUrl} alt="프로필 이미지" />}
<ChatMessagesWrapper>
{chats.map((chat, idx) => (
<ChatMessage
key={`chat_${isMe ? "me" : "other"}_${chat.createdAt}_${idx}`}
isMe={isMe}
{...chat}
/>
))}
</ChatMessagesWrapper>
</ChatBubbleWrapper>
);
};
55 changes: 55 additions & 0 deletions src/components/organisms/ChatBubble/stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { Meta, StoryObj } from "@storybook/react";
import { ChatBubble } from ".";

const meta: Meta<typeof ChatBubble> = {
title: "Organisms/ChatBubble",
component: ChatBubble,
tags: ["autodocs"],
argTypes: {},
args: {
chats: [
{
msg: "네이버 로그인 버튼 디자인가이드",
isLastMsg: false,
isRead: false,
createdAt: new Date().toString(),
},
{
msg: "버튼의 형태는 네이버 고유의 이미지를 해치지 않는 범위 내에서 유연하게 디자인을 변경할 수 있습니다.",
isLastMsg: false,
isRead: false,
createdAt: new Date().toString(),
},
{
msg: "표시되는 메시지는 네이버 로그인 목적에 부합한다면 한글이나 영문 상관없이 변경할 수 있습니다.",
isLastMsg: false,
isRead: false,
createdAt: new Date().toString(),
},
{
msg: "로그인 버튼에 사용하는 네이버 로고 타입은 다음의 규정을 따릅니다. N 로고 타입을 사용하고 로고를 기준으로 최소한의 여백 공간을 확보하여 적용합니다. 로고의 형태를 변경하거나 다른 형태와의 조합은 금지합니다.",
isLastMsg: true,
isRead: false,
createdAt: new Date().toString(),
},
],
},
};

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
isMe: false,
imgUrl: "https://github.com/ppyom.png",
},
};

export const MyBubble: Story = {
args: {
isMe: true,
imgUrl: "https://github.com/ppyom.png",
},
};

export default meta;
21 changes: 21 additions & 0 deletions src/components/organisms/ChatBubble/styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styled from "@emotion/styled";
import { ImageWrapper } from "components/atoms/Image/styled";
import type { IChatBubbleProps } from ".";

export const ChatMessagesWrapper: ReturnType<typeof styled.div> = styled.div`
flex: 1;
display: flex;
flex-direction: column;
gap: 0.25rem;
`;

export const ChatBubbleWrapper: ReturnType<
typeof styled.div<Pick<IChatBubbleProps, "isMe">>
> = styled.div<Pick<IChatBubbleProps, "isMe">>`
display: flex;
flex-direction: ${({ isMe }) => (isMe ? "row-reverse" : "row")};
gap: 0.25rem;
${ImageWrapper} {
width: 40px;
}
`;
13 changes: 3 additions & 10 deletions src/components/organisms/ChatMessage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import { Text } from "components/atoms";
import { getTime } from "utils";
import type { IChat } from "types";
import {
ChatMessageWrapper,
MessageInfoWrapper,
MessageWrapper,
} from "./styled";
import { getTime } from "utils";

export interface IChatMessageProps {
/** 채팅 메시지 내용 */
msg: string;
export interface IChatMessageProps extends IChat {
/** 채팅 보낸 유저가 나인지 타인인지 구분 */
isMe: boolean;
/** 해당 채팅이 그룹에서 마지막 메시지인지 구분,(시간 표시 유무 구분)*/
isLastMsg: boolean;
/** 해당 채팅을 읽었는지 구분 */
isRead: boolean;
/** 해당 메시지 보낸 시간 */
createdAt: string;
}

export const ChatMessage = ({
Expand Down
15 changes: 15 additions & 0 deletions src/components/organisms/ChatMessage/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ const meta: Meta<typeof ChatMessage> = {
title: "Organisms/ChatMessage",
component: ChatMessage,
tags: ["autodocs"],
argTypes: {
msg: {
description: "채팅 메시지 내용",
},
isLastMsg: {
description:
"해당 채팅이 그룹에서 마지막 메시지인지 구분,(시간 표시 유무 구분)",
},
isRead: {
description: "해당 채팅을 읽었는지 구분",
},
createdAt: {
description: "해당 메시지 보낸 시간",
},
},
};

type Story = StoryObj<typeof meta>;
Expand Down
3 changes: 3 additions & 0 deletions src/components/organisms/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export { Map } from "./Map";
export { PostImageItem } from "./PostImageItem";
export { SearchHistoryItem } from "./SearchHistoryItem";

export { ChatMessage } from "./ChatMessage";
export { ChatBubble } from "./ChatBubble";
10 changes: 10 additions & 0 deletions src/types/chat.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface IChat {
/** 채팅 메시지 내용 */
msg: string;
/** 해당 채팅이 그룹에서 마지막 메시지인지 구분,(시간 표시 유무 구분)*/
isLastMsg: boolean;
/** 해당 채팅을 읽었는지 구분 */
isRead: boolean;
/** 해당 메시지 보낸 시간 */
createdAt: string;
}
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./selectOption";
export * from "./navMenu";
export * from "./notification";
export * from "./user";
export * from "./chat";

0 comments on commit dcedccd

Please sign in to comment.