ERP-node/docs/ycshin-node/MST[계획]-다중선택-라벨표시.md

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 컴포넌트 사용으로 프로젝트 일관성 유지