4.3 KiB
4.3 KiB
[맥락노트] V2Select 다중 선택 드롭다운 - 선택 항목 표시 개선
왜 이 작업을 하는가
- 사용자가 수정 모달에서 다중 선택 드롭다운을 사용할 때
"3개 선택됨"만 보임 - 드롭다운을 다시 열어봐야만 무엇이 선택됐는지 확인 가능 → UX 불편
- 선택 항목을 직접 보여주고, 넘치면 툴팁으로 확인할 수 있게 개선
핵심 결정 사항과 근거
1. "n개 선택됨" → 라벨 쉼표 나열
- 결정:
"구매품, 판매품, 재고품"형태로 표시 - 근거: 사용자가 드롭다운을 열지 않아도 선택 내용을 바로 확인 가능
2. 무조건 한 줄, 넘치면 말줄임(...)
- 결정: 여러 줄 줄바꿈 없이 한 줄 고정,
truncate로 오버플로우 처리 - 근거: 드롭다운 필드 높이가 고정되어 있어 여러 줄 표시 시 레이아웃이 깨짐
3. 텍스트가 잘릴 때만 툴팁 표시
- 결정:
scrollWidth > clientWidth비교로 실제 잘림 여부 감지 후 툴팁 활성화 - 근거: 전부 보이는데 툴팁이 뜨면 오히려 방해. 필요할 때만 보여야 함
- 대안 검토: "2개 이상이면 항상 툴팁" → 기각 (불필요한 툴팁 발생)
4. 툴팁 내용은 세로 나열
- 결정: 툴팁 안에서 항목을 줄바꿈으로 세로 나열
- 근거: 가로 나열 시 툴팁도 길어져서 읽기 어려움. 세로가 한눈에 파악하기 좋음
5. 툴팁 딜레이 0ms
- 결정:
delayDuration={0}즉시 표시 - 근거: 사용자가 "무엇을 선택했는지" 확인하려는 의도적 행동이므로 즉시 응답해야 함
6. Radix Tooltip 대신 커스텀 호버 툴팁 사용
- 결정: Radix Tooltip을 사용하지 않고
onMouseEnter/onMouseLeave로 직접 제어 - 근거: Radix Tooltip + Popover 조합은 이벤트 충돌 발생. 내부 배치든 외부 래핑이든 Popover가 호버를 가로챔
- 시도 1: Tooltip을 Button 안에 배치 → Popover가 이벤트 가로챔 (실패)
- 시도 2: Radix 공식 패턴 (TooltipTrigger > PopoverTrigger > Button 체이닝) → 여전히 동작 안 함 (실패)
- 최종: wrapper div에 마우스 이벤트 + 절대 위치 div로 툴팁 렌더링 (성공)
- 추가: Popover 열릴 때
setHoverTooltip(false)로 툴팁 자동 숨김
8. 선택 항목 표시 순서는 드롭다운 옵션 순서 기준
- 결정: 사용자가 클릭한 순서가 아닌 드롭다운 옵션 목록 순서대로 표시
- 근거: 선택 순서대로 보여주면 매번 순서가 달라져서 혼란. 옵션 순서 기준이 일관적이고 예측 가능
- 구현:
selectedValues.map(...)→safeOptions.filter(...).map(...)으로 변경
9. DropdownSelect 공통 컴포넌트 수정
- 결정: 특정 화면이 아닌
DropdownSelect자체를 수정 - 근거: 품목정보뿐 아니라 모든 화면에서 동일한 문제가 있으므로 공통 해결
관련 파일 위치
| 구분 | 파일 경로 | 설명 |
|---|---|---|
| 수정 대상 | frontend/components/v2/V2Select.tsx |
DropdownSelect 컴포넌트 (170~178행) |
| 타입 정의 | frontend/types/v2-components.ts |
V2SelectProps, SelectOption 타입 |
| UI 컴포넌트 | frontend/components/ui/tooltip.tsx |
shadcn Tooltip 컴포넌트 |
| 렌더러 | frontend/lib/registry/components/v2-select/V2SelectRenderer.tsx |
V2Select를 레지스트리에 연결 |
| 수정 모달 | frontend/components/screen/EditModal.tsx |
공통 편집 모달 |
기술 참고
truncate 감지 방식
scrollWidth: 텍스트의 실제 전체 너비 (보이지 않는 부분 포함)
clientWidth: 요소의 보이는 너비
scrollWidth > clientWidth → 텍스트가 잘리고 있음 (... 표시 중)
selectedLabels 계산 흐름
value (string[]) → selectedValues → safeOptions에서 label 매칭 → selectedLabels (string[])
selectedLabels는 이미DropdownSelect내부에서useMemo로 계산됨 (126~130행)- 추가 데이터 fetching 불필요, 기존 값을
.join(", ")로 결합하면 됨