Repository: SOPT-all/36-COLLABORATION-WEB-GOODOC
Pull request #27: Feat: 채팅 뷰 버튼 컴포넌트 구현
Author: login: heeyyeon
Labels: name: ✨Feature
description: 기능 개발
name: 🐹희연
Created: 2025-05-14T17:51:51Z | Merged: 2025-05-15T08:01:26Z

# 🩺 Pull requests
### 📍 작업한 이슈번호
- #21

### 💻 작업한 내용
- 채팅 뷰 공통 컴포넌트 구현

### 📢 PR Point
- 버튼 태그에 유틸리티 스타일 적용이 안되어서 직접 rem 단위로 스타일 적용을 해주었습니다.. 이 부분은 원인 더 찾아보겠습니다!!

###  💭 기타
tsconfig.json 설정에서 strict 옵션이 비활성화되어 있다는 에러 메시지가 떠서 아래와 같은 옵션 추가해 주었습니다
<img width="1348" alt="image" src="https://github.com/user-attachments/assets/56a67fd0-551b-4d49-afbe-deac22f94857" />

```
  "compilerOptions": {
    "strict": true, 
    "forceConsistentCasingInFileNames": true
  },
```

### 📸 스크린샷
<img width="233" alt="스크린샷 2025-05-15 오전 2 20 09" src="https://github.com/user-attachments/assets/e4d5b081-073c-4717-95ab-543c42c5b9fc" />
<img width="372" alt="스크린샷 2025-05-15 오전 2 24 27" src="https://github.com/user-attachments/assets/517909ea-6121-4456-ae5f-b353845657ce" />




Diff:
diff --git a/src/pages/chat/components/Button.tsx b/src/pages/chat/components/Button.tsx
new file mode 100644
index 0000000..86574c7
--- /dev/null
+++ b/src/pages/chat/components/Button.tsx
@@ -0,0 +1,19 @@
+interface ButtonProps {
+  label: string;
+  onClick: () => void;
+  variant?: 'primary' | 'secondary';
+}
+
+const Button: React.FC<ButtonProps> = ({ label, onClick, variant = 'primary' }) => {
+  const buttonStyles = variant === 'primary' ? 'bg-Blue-3 text-Mainblue' : 'bg-Mainblue text-White';
+  return (
+    <button
+      onClick={onClick}
+      className={`${buttonStyles} w-[115px] h-[40px] border-none rounded-[.5rem]`}
+    >
+      <div className="title-semi-14">{label}</div>
+    </button>
+  );
+};
+
+export default Button;
diff --git a/src/shared/styles/theme.css b/src/shared/styles/theme.css
index afdc533..270a4d0 100644
--- a/src/shared/styles/theme.css
+++ b/src/shared/styles/theme.css
@@ -50,7 +50,7 @@
   }
 
   .title-semi-14 {
-    @apply text-[0.875rem] leading-[1.125rem];
+    @apply text-[0.875rem] leading-[1.125rem]; 
     font-weight: 600; /* semibold */
   }
 
@@ -107,77 +107,77 @@
   }
 
   /* Main Colors */
-  .text-Mainblue { color: #0073F9; }
-  .bg-Mainblue { background-color: #0073F9; }
+  .text-Mainblue { color: #0073F9 !important; }
+  .bg-Mainblue { background-color: #0073F9 !important; }
 
-  .text-Blue-1 { color: #E8EDFF; }
-  .bg-Blue-1 { background-color: #E8EDFF; }
+  .text-Blue-1 { color: #E8EDFF !important; }
+  .bg-Blue-1 { background-color: #E8EDFF !important; }
 
-  .text-Blue-2 { color: #F5F8FF; }
-  .bg-Blue-2 { background-color: #F5F8FF; }
+  .text-Blue-2 { color: #F5F8FF !important; }
+  .bg-Blue-2 { background-color: #F5F8FF !important; }
 
-  .text-Blue-3 { color: #E2F0FF; }
-  .bg-Blue-3 { background-color: #E2F0FF; }
+  .text-Blue-3 { color: #E2F0FF !important; }
+  .bg-Blue-3 { background-color: #E2F0FF !important; }
 
-  .text-SoftGreen { color: #2CAB6F; }
-  .bg-SoftGreen { background-color: #2CAB6F; }
+  .text-SoftGreen { color: #2CAB6F !important; }
+  .bg-SoftGreen { background-color: #2CAB6F !important; }
 
-  .text-ErrorRed { color: #FF3033; }
-  .bg-ErrorRed { background-color: #FF3033; }
+  .text-ErrorRed { color: #FF3033 !important; }
+  .bg-ErrorRed { background-color: #FF3033 !important; }
 
-  .text-SoftRed { color: #FFDDDD; }
-  .bg-SoftRed { background-color: #FFDDDD; }
+  .text-SoftRed { color: #FFDDDD !important; }
+  .bg-SoftRed { background-color: #FFDDDD !important; }
 
 
   /* Grays */
-  .text-SoftBlack { color: #393939; }
-  .bg-SoftBlack { background-color: #393939; }
+  .text-SoftBlack { color: #393939 !important; }
+  .bg-SoftBlack { background-color: #393939 !important; }
 
-  .text-WGray { color: #5B5E62; }
-  .bg-WGray { background-color: #5B5E62; }
+  .text-WGray { color: #5B5E62 !important; }
+  .bg-WGray { background-color: #5B5E62 !important; }
 
-  .text-WGray-1 { color: #828690; }
-  .bg-WGray-1 { background-color: #828690; }
+  .text-WGray-1 { color: #828690 !important; }
+  .bg-WGray-1 { background-color: #828690 !important; }
 
-  .text-WGray-2 { color: #F1F1F1; }
-  .bg-WGray-2 { background-color: #F1F1F1; }
+  .text-WGray-2 { color: #F1F1F1 !important; }
+  .bg-WGray-2 { background-color: #F1F1F1 !important; }
 
-  .text-WGray-3 { color: #F6F7F9; }
-  .bg-WGray-3 { background-color: #F6F7F9; }
+  .text-WGray-3 { color: #F6F7F9 !important; }
+  .bg-WGray-3 { background-color: #F6F7F9 !important; }
 
-  .text-WGray-4 { color: #F9F9F9; }
-  .bg-WGray-4 { background-color: #F9F9F9; }
+  .text-WGray-4 { color: #F9F9F9 !important; }
+  .bg-WGray-4 { background-color: #F9F9F9 !important; }
 
-  .text-Black { color: #000000; }
-  .bg-Black { background-color: #000000; }
+  .text-Black { color: #000000 !important; }
+  .bg-Black { background-color: #000000 !important; }
 
-  .text-CGray { color: #16171C; }
-  .bg-CGray { background-color: #16171C; }
+  .text-CGray { color: #16171C !important; }
+  .bg-CGray { background-color: #16171C !important; }
 
-  .text-CGray-1 { color: #30343F; }
-  .bg-CGray-1 { background-color: #30343F; }
+  .text-CGray-1 { color: #30343F !important; }
+  .bg-CGray-1 { background-color: #30343F !important; }
 
-  .text-CGray-2 { color: #434956; }
-  .bg-CGray-2 { background-color: #434956; }
+  .text-CGray-2 { color: #434956 !important; }
+  .bg-CGray-2 { background-color: #434956 !important; }
 
-  .text-CGray-3 { color: #5D6373; }
-  .bg-CGray-3 { background-color: #5D6373; }
+  .text-CGray-3 { color: #5D6373 !important; }
+  .bg-CGray-3 { background-color: #5D6373 !important; }
 
-  .text-CGray-4 { color: #808699; }
-  .bg-CGray-4 { background-color: #808699; }
+  .text-CGray-4 { color: #808699 !important; }
+  .bg-CGray-4 { background-color: #808699 !important; }
 
-  .text-CGray-5 { color: #A8ABBD; }
-  .bg-CGray-5 { background-color: #A8ABBD; }
+  .text-CGray-5 { color: #A8ABBD !important; }
+  .bg-CGray-5 { background-color: #A8ABBD !important; }
 
-  .text-CGray-6 { color: #CACED8; }
-  .bg-CGray-6 { background-color: #CACED8; }
+  .text-CGray-6 { color: #CACED8 !important; }
+  .bg-CGray-6 { background-color: #CACED8 !important; }
 
-  .text-CGray-7 { color: #ECEDF0; }
-  .bg-CGray-7 { background-color: #ECEDF0; }
+  .text-CGray-7 { color: #ECEDF0 !important; }
+  .bg-CGray-7 { background-color: #ECEDF0 !important; }
 
-  .text-CGray-8 { color: #F2F3F4; }
-  .bg-CGray-8 { background-color: #F2F3F4; }
+  .text-CGray-8 { color: #F2F3F4 !important; }
+  .bg-CGray-8 { background-color: #F2F3F4 !important; }
 
-  .text-White { color: #FFFFFF; }
-  .bg-White { background-color: #FFFFFF; }
+  .text-White { color: #FFFFFF !important; }
+  .bg-White { background-color: #FFFFFF !important; }
 }
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 1ffef60..7b4713d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,4 +1,8 @@
 {
+  "compilerOptions": {
+    "strict": true, 
+    "forceConsistentCasingInFileNames": true
+  },
   "files": [],
   "references": [
     { "path": "./tsconfig.app.json" },


Reviews:
user: login: jisooooooooooo
body: 고생하셨습니다~~👍🏻👍🏻
코멘트 몇 개만 확인해 주시면 될 거 같아요 >"<
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-15T01:35:53Z
user: login: heeyyeon
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T03:16:26Z
user: login: mmaybei
body: 굿! 고생하셨어요 😎
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-15T07:42:57Z

Review comments:
diff_hunk: @@ -0,0 +1,19 @@
+interface ButtonProps {
+  label: string;
+  onClick: () => void;
+  variant?: 'primary' | 'secondary';
+}
+
+const Button: React.FC<ButtonProps> = ({ label, onClick, variant = 'primary' }) => {
+  const buttonStyles = variant === 'primary' ? 'bg-Blue-3 text-Mainblue' : 'bg-Mainblue text-white';
+  return (
+    <button
+      onClick={onClick}
+      className={`${buttonStyles} text-[.875rem] leading-[.5rem] font-600 w-[7.1875rem] h-[2.5rem] rounded-[.5rem] p-[1rem] sm:p-[1.25rem] gap-[.25rem] border-none`}
path: src/pages/chat/components/Button.tsx
user: login: jisooooooooooo
body: 폰트 두께가 적용이 안 되는 거 같은데 font-600말고 font-semibold로 바꾸면 적용될 거 같고 텍스트 관련 스타일을 분리해서 아래 코드처럼 작성하면 유틸리티 클래스도 적용할 수 있을 거 같아요!
```ts
<button onClick={onClick} className="~">
  <div className="title-semi-14">{label}</div>
</button>
```
`p-[1rem] sm:p-[1.25rem]` 이 부분은 반응형 생각하신 건지 궁금하고
지금 패딩값이 하나도 통일되어 있는 거 같은데 
`py-[1rem] px-[1.25rem]` 이런 식으로 다르게 넣어줘야 할 거 같은데 확인 한 번 해주세요~!

혹시 gap은 넣으신 이유가 있을까요?
created_at: 2025-05-15T01:06:04Z
author_association: COLLABORATOR
path: src/shared/styles/theme.css
user: login: jisooooooooooo
body: 저도 이 부분은 다른 방법 찾아보겠습니다!
created_at: 2025-05-15T01:32:14Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,19 @@
+interface ButtonProps {
+  label: string;
+  onClick: () => void;
+  variant?: 'primary' | 'secondary';
+}
+
+const Button: React.FC<ButtonProps> = ({ label, onClick, variant = 'primary' }) => {
+  const buttonStyles = variant === 'primary' ? 'bg-Blue-3 text-Mainblue' : 'bg-Mainblue text-white';
+  return (
+    <button
+      onClick={onClick}
+      className={`${buttonStyles} text-[.875rem] leading-[.5rem] font-600 w-[7.1875rem] h-[2.5rem] rounded-[.5rem] p-[1rem] sm:p-[1.25rem] gap-[.25rem] border-none`}
path: src/pages/chat/components/Button.tsx
user: login: heeyyeon
body: 헉!! 버튼 태그에는 커스텀 폰트 적용이 안돼서 font-600으로 넣었던 건데, 라벨에 div 태그 생성해서 폰트 넣어주지 잘 적용이 됩니다!! 감사합니다ㅎㅎ🫶🏻
또 다시 보니 패딩 값을 적용하면 내부 텍스트가 길이에 따라 넘쳐버려서 패딩 대신에 넓이랑 높이 값만 설정하는 걸로 해야할 것 같습니다. 패딩 값은 제외하겠습니다! (gap이랑 sm:p-[1.25rem]은 지우고 pr 올렸어야 했는데 같이 올려버렸어요ㅎㅎ.. 이 부분도 지우겠습니다) 아래 코드로 수정해서 다시 pr 올릴게요 꼼꼼한 리뷰 감사합니다!

 ```
<button
      onClick={onClick}
      className={`${buttonStyles} w-[115px] h-[40px] rounded-[.5rem] border-none`}
>
      <div className="title-semi-14">{label}</div>
</button>
```

created_at: 2025-05-15T03:16:26Z
author_association: MEMBER

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-14T17:54:40Z
body: ### 빌드 결과
빌드 성공 🎉
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-15T03:20:15Z
body: ### 빌드 결과
빌드 성공 🎉
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-15T04:17:55Z
body: ### 빌드 결과
빌드 성공 🎉
author_association: NONE