Skip to content

Comments

Feat(client): 개발 QA 1차(사이드바 카테고리 이모지 카운트 수정) #134

Merged
jjangminii merged 1 commit intodevelopfrom
fix/#133/category-emoji-count
Sep 20, 2025
Merged

Feat(client): 개발 QA 1차(사이드바 카테고리 이모지 카운트 수정) #134
jjangminii merged 1 commit intodevelopfrom
fix/#133/category-emoji-count

Conversation

@jjangminii
Copy link
Collaborator

@jjangminii jjangminii commented Sep 20, 2025

📌 Related Issues

관련된 Issue를 태그해주세요. (e.g. - close #25)

📄 Tasks

  • 사이드바 카테고리 이모지 카운트 2개로 반영되는 이슈 수정

⭐ PR Point (To Reviewer)

📷 Screenshot

Summary by CodeRabbit

  • 버그 수정
    • 카테고리 이름 길이 계산을 글자(그래핌) 기준으로 처리해 이모지·한글 결합 문자에서 실제 보이는 글자 수와 검증 결과가 불일치하던 문제를 수정했습니다.
    • 빈 값 판정과 최대 글자수 초과/정확히 도달 검증을 그래핌 기준으로 일관되게 적용해, 의도치 않게 입력이 차단되거나 통과되던 사례를 해소했습니다.
    • 다양한 환경에서도 동일한 길이 판단이 이루어져 입력 유효성의 신뢰성과 사용자 경험이 개선되었습니다.

@jjangminii jjangminii linked an issue Sep 20, 2025 that may be closed by this pull request
@vercel
Copy link

vercel bot commented Sep 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
pinback-client-client Ready Ready Preview Comment Sep 20, 2025 6:06am
pinback-client-landing Ready Ready Preview Comment Sep 20, 2025 6:06am

@coderabbitai
Copy link

coderabbitai bot commented Sep 20, 2025

Walkthrough

사용자 입력 카테고리명 길이 검증을 코드포인트 기반에서 그래프림(문자 소구성) 기반으로 전환했습니다. 이를 위해 graphemeLength 유틸을 추가하고, PopupPortal 내 모든 length 비교 로직을 graphemeLength 결과로 대체했습니다. 공개 API 변경은 없습니다.

Changes

Cohort / File(s) Summary
Sidebar Popup Validation (grapheme 적용)
apps/client/src/shared/components/sidebar/PopupPortal.tsx
카테고리명 검증 시 value.lengthgraphemeLength로 변경. 빈값, 한도 초과, 경계값(=== MAX_LEN) 판단을 모두 그래프림 길이로 재구성. 차단 조건도 동일하게 갱신.
Grapheme 유틸 추가
apps/client/src/shared/utils/grapheme.ts
Intl.Segmenter(ko, grapheme) 기반 길이 계산 유틸 graphemeLength(s: string) 추가. 미지원 환경에서는 Array.from(s).length로 폴백.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

fix

Suggested reviewers

  • jllee000
  • constantly-dev

Poem

토끼는 글자 셈을 새로 배웠지 🥕
이모지 두 칸? 아니야, 한 숨결이지!
Segmenter 타고 폴짝폴짝,
카테고리 이름도 딱맞게 쏙!
틀림없는 길이로, 버그는 퍽—퍽!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed 제목은 PR의 핵심 변경사항인 "사이드바 카테고리 이모지 카운트 수정"을 명확히 담고 있어 의도를 잘 전달합니다; 접두사 "Feat(client):"도 적절하게 사용되었으며 "개발 QA 1차"라는 부가 문구는 다소 부수적이지만 혼동을 주지 않습니다.
Linked Issues Check ✅ Passed 이 PR은 이모지 두 글자 카운트 문제 해결([#133])을 목표로 하며 raw_summary에 따르면 graphemeLength 유틸 추가와 PopupPortal.tsx의 길이 검사 교체를 통해 해당 목표를 직접 구현하고 있어 [#133] 요구사항은 충족됩니다; 링크된 다른 이슈([#25] 프로그레스바)는 이번 PR 범위와 무관하며 PR 설명에도 close #133만 명시되어 있습니다.
Out of Scope Changes Check ✅ Passed 변경 파일이 apps/client/src/shared/components/sidebar/PopupPortal.tsx와 apps/client/src/shared/utils/grapheme.ts으로 한정되어 있으며 두 변경 모두 이모지 길이 계산 수정과 직접적으로 연관되어 있어 요구사항 외의 무관한 변경은 확인되지 않습니다.
Description Check ✅ Passed PR 설명은 템플릿의 필수 섹션인 관련 이슈와 작업 항목을 채우고 있으며 "close #133"과 변경 요약이 포함되어 있어 주요 정보는 충족됩니다; PR Point와 스크린샷은 비어 있으나 필수 항목은 아니므로 전체적으로 충분합니다.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/#133/category-emoji-count

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jjangminii jjangminii self-assigned this Sep 20, 2025
@github-actions github-actions bot added the fix 버그 수정하라 러브버그 label Sep 20, 2025
@github-actions
Copy link

✅ Storybook chromatic 배포 확인:
🐿️ storybook

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/client/src/shared/components/sidebar/PopupPortal.tsx (1)

5-77: 카테고리/이름 길이 검사에서 .length 사용을 graphemeLength로 교체하세요

PopupPortal는 graphemeLength를 사용하고 있으나, 리포지토리에서 문자열 길이 검사에 .length를 여전히 사용하는 코드가 발견되었습니다(유니코드/이모지 등에서 잘못된 길이 판단 발생). 아래 위치를 문자열 글자수 검사는 graphemeLength로 대체하세요.

  • apps/client/src/shared/components/cardEditModal/CardEditModal.tsx — if (categoryTitle.length > 20) { … } (약 58행) → graphemeLength(categoryTitle.trim()) 기준으로 변경 필요.
  • apps/client/src/pages/remind/Remind.tsx, apps/client/src/pages/myBookmark/MyBookmark.tsx — articles.length > 0 등은 배열 길이 검사이므로 변경 불필요.
🧹 Nitpick comments (6)
apps/client/src/shared/utils/grapheme.ts (4)

1-7: 폴백 정확도 개선: 코드포인트 카운트 대신 진짜 ‘grapheme’ 분할 사용 제안

Intl.Segmenter 미지원 환경에서 Array.from(s).length는 코드포인트 길이라 '❤️', '👍🏻', '🇰🇷', '👨‍👩‍👧‍👦', 분해된 한글 자모(가) 등이 여전히 2개 이상으로 집계될 수 있습니다. QA 이슈(#133)가 특정 환경에서 재발할 여지가 있습니다. Segmenter가 없을 때는 경량 라이브러리(graphemer 또는 grapheme-splitter)로 폴리필을 권장합니다.

다음과 같이 대체를 제안합니다(예: graphemer):

+import GraphemeSplitter from 'graphemer';
 const _seg =
   typeof Intl !== 'undefined' && Intl.Segmenter
-    ? new Intl.Segmenter('ko', { granularity: 'grapheme' })
+    ? new Intl.Segmenter(undefined, { granularity: 'grapheme' })
     : null;

-export const graphemeLength = (s: string) =>
-  _seg ? Array.from(_seg.segment(s)).length : Array.from(s).length;
+const _splitter = _seg ? null : new GraphemeSplitter();
+
+export const graphemeLength = (s: string) => {
+  if (_seg) {
+    // 비용 줄이기: 배열 생성 없이 카운트
+    let n = 0;
+    for (const _ of _seg.segment(s)) n++;
+    return n;
+  }
+  return _splitter!.countGraphemes(s);
+};

3-3: 로케일 하드코딩 불필요

grapheme 분할은 로케일 비의존적(UAX #29)이라 'ko'를 고정하지 않아도 됩니다. 런타임 기본값(undefined) 사용이 안전합니다. 위 diff에 반영했습니다.


6-7: 미세 최적화: Array.from 할당 제거

Segmenter 사용 시 매 타이핑마다 배열·세그먼트 객체를 생성합니다. for-of 루프로 카운트하면 동등한 가독성으로 할당을 줄일 수 있습니다. 위 diff에 포함했습니다.


6-7: 크로스‑환경 검증 케이스 제안

다음 값이 모두 1로 카운트되는지(특히 Segmenter 미지원 환경) 테스트 추가를 권합니다: '😊', '👍🏻', '❤️', '🇰🇷', '👨‍👩‍👧‍👦', '가'(분해 자모). 필요 시 테스트 코드 초안 제공 가능합니다.

apps/client/src/shared/components/sidebar/PopupPortal.tsx (2)

46-49: trim 이후 그래프림 길이 사용 일관성 확인

중복 검사와 동일하게 trim된 value를 기준으로 glen을 계산한 점 좋습니다. categoryList의 name이 미리 trim/정규화(NFC)되어 있는지도 한번만 확인 부탁드립니다(공백/정규화 차이로 오탑재 방지).


77-77: 차단 조건 적용 OK. 버튼 상태 동기화 여부 확인

onRightClick에서만 차단하면 사용자는 버튼이 활성처럼 보여 혼동할 수 있습니다. 디자인 시스템 Popup이 비활성화 프롭을 제공한다면 함께 전달하여 시각적 피드백을 동기화하는 것을 권장합니다.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01b4e51 and 9a85fb9.

📒 Files selected for processing (2)
  • apps/client/src/shared/components/sidebar/PopupPortal.tsx (4 hunks)
  • apps/client/src/shared/utils/grapheme.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/client/src/shared/components/sidebar/PopupPortal.tsx (1)
apps/client/src/shared/utils/grapheme.ts (1)
  • graphemeLength (6-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: storybook
🔇 Additional comments (2)
apps/client/src/shared/components/sidebar/PopupPortal.tsx (2)

5-5: graphemeLength 도입 적절합니다

카테고리명 길이 판단의 소스 오브 트루스를 통일해 이슈 #133의 근본 원인(이모지 카운트)을 해결합니다.


62-66: 경계값 처리(L==MAX, L>MAX) 깔끔합니다

MAX일 때 가이드만 표시하고 오류 UI/차단은 하지 않는 흐름이 UX에 부합합니다.

@jjangminii jjangminii merged commit 4031b94 into develop Sep 20, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix 버그 수정하라 러브버그

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fix] sp1 QA 카테고리 이모지

1 participant