4.3 KiB
4.3 KiB
[계획서] V2Select 다중 선택 드롭다운 - 선택 항목 표시 개선
개요
모든 화면에서 다중 선택 가능한 드롭다운(V2Select - DropdownSelect)의 선택 항목 표시 방식을 개선합니다.
현재 동작
- 다중 선택 시
"3개 선택됨"같은 텍스트만 표시 - 어떤 항목이 선택되었는지 드롭다운을 열어야만 확인 가능
현재 코드 (V2Select.tsx - DropdownSelect, 174~178행)
{selectedLabels.length > 0
? multiple
? `${selectedLabels.length}개 선택됨`
: selectedLabels[0]
: placeholder}
변경 후 동작
1. 선택된 항목 라벨을 쉼표로 연결하여 한 줄로 표시
- 예:
"구매품, 판매품, 재고품" truncate(text-overflow: ellipsis)로 필드 너비를 넘으면 말줄임(...) 처리- 무조건 한 줄 표시, 넘치면
...으로 숨김
2. 텍스트가 말줄임(...) 처리될 때만 호버 툴팁 표시
- 필드 너비를 넘어서
...으로 잘릴 때만 툴팁 활성화 - 필드 내에 전부 보이면 툴팁 불필요
- 툴팁 내용은 세로 나열로 각 항목을 한눈에 확인 가능
- 툴팁은 딜레이 없이 즉시 표시
시각적 동작 예시
| 상태 | 필드 내 표시 | 호버 시 툴팁 |
|---|---|---|
| 미선택 | 선택 (placeholder) |
없음 |
| 1개 선택 | 구매품 |
없음 |
| 3개 선택 (필드 내 수용) | 구매품, 판매품, 재고품 |
없음 (잘리지 않으므로) |
| 5개 선택 (필드 넘침) | 구매품, 판매품, 재고품, 외... |
구매품 / 판매품 / 재고품 / 외주품 / 반제품 (세로 나열) |
변경 대상
- 파일:
frontend/components/v2/V2Select.tsx - 컴포넌트:
DropdownSelect내부 표시 텍스트 부분 (170~178행) - 적용 범위:
DropdownSelect를 사용하는 모든 화면 (품목정보, 기타 모든 모달 포함) - 변경 규모: 약 30줄 내외 소규모 변경
코드 설계
추가 import
import { useRef, useEffect, useState } from "react";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
말줄임 감지 로직
// 텍스트가 잘리는지(truncated) 감지
const textRef = useRef<HTMLSpanElement>(null);
const [isTruncated, setIsTruncated] = useState(false);
useEffect(() => {
const el = textRef.current;
if (el) {
setIsTruncated(el.scrollWidth > el.clientWidth);
}
}, [selectedLabels]);
수정 코드 (DropdownSelect 내부, 170~178행 대체)
const displayText = selectedLabels.length > 0
? (multiple ? selectedLabels.join(", ") : selectedLabels[0])
: placeholder;
const isPlaceholder = selectedLabels.length === 0;
// 렌더링 부분
{isTruncated && multiple ? (
<TooltipProvider delayDuration={0}>
<Tooltip>
<TooltipTrigger asChild>
<span
ref={textRef}
className={cn("truncate flex-1 text-left", isPlaceholder && "text-muted-foreground")}
{...(isPlaceholder ? { "data-placeholder": placeholder } : {})}
>
{displayText}
</span>
</TooltipTrigger>
<TooltipContent side="top" className="max-w-[300px]">
<div className="space-y-0.5 text-xs">
{selectedLabels.map((label, i) => (
<div key={i}>{label}</div>
))}
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
) : (
<span
ref={textRef}
className={cn("truncate flex-1 text-left", isPlaceholder && "text-muted-foreground")}
{...(isPlaceholder ? { "data-placeholder": placeholder } : {})}
>
{displayText}
</span>
)}
설계 원칙
- 기존 단일 선택 동작은 변경하지 않음
DropdownSelect공통 컴포넌트 수정이므로 모든 화면에 자동 적용- 무조건 한 줄 표시, 넘치면
...으로 말줄임 - 툴팁은 텍스트가 실제로 잘릴 때(
scrollWidth > clientWidth)만 표시 - 툴팁 내용은 세로 나열로 각 항목 확인 용이
- 툴팁 딜레이 없음 (
delayDuration={0}) - shadcn 표준 Tooltip 컴포넌트 사용으로 프로젝트 일관성 유지