/* ============================================================================ * 서명전에 — TDS ProgressStepper 컴포넌트 * · ProgressBar 와 Stepper 가 결합된 형태 — 단계별 진행 상태를 * 가로로 한 눈에 보여줘요. * · 2 서브: * ProgressStepper — 컨테이너 (variant / paddingTop / activeStepIndex / checkForFinish) * ProgressStep — 자식 (title / icon) * * · ProgressStepperProps: * variant * "compact" | "icon" (필수) * paddingTop "default" | "wide" (기본 "default" → 16px / "wide" → 24px) * activeStepIndex number (기본 0) * checkForFinish boolean (icon variant 한정) (기본 false) * className, style, id 패스스루 * * · ProgressStepProps: * title string (옵셔널) — 없으면 마커만 표시 * icon ReactNode (icon variant 한정) — 없으면 1-based 숫자 표시 * className, style, id 패스스루 * * · 단계 상태 (활성 인덱스 기준): * idx < active → "past" (완료, blue-400) * idx === active → "current" (현재, blue-400 + ring 강조) * idx > active → "future" (미완료, grey) * * · checkForFinish + variant=icon + state=past → 체크 SVG 아이콘 자동. * * · 구현 메모: ProgressStep 은 React.cloneElement 로 부모에서 내부 * prop (__idx / __total / __state / __variant / __checkForFinish) 을 * 주입받아요. 사용자는 신경 쓸 필요 없음. * ========================================================================== */ const __STEPPER_VARIANTS = { compact: 1, icon: 1 }; const __STEPPER_PT = { default: 1, wide: 1 }; // ----- 체크 아이콘 (SVG 인라인) ----- function __StepperCheckSvg() { return ( ); } // ============================================================================= // ProgressStepper — 컨테이너 // ============================================================================= function ProgressStepper({ variant, paddingTop = "default", activeStepIndex = 0, checkForFinish = false, className = "", style, id, children, ...rest }) { // variant 검증 — 필수 if (!__STEPPER_VARIANTS[variant]) { if (window.console && console.warn) { console.warn( `[ProgressStepper] \`variant\` 는 필수예요 — "compact" | "icon". 받은 값: ${variant}` ); } } const safeVariant = __STEPPER_VARIANTS[variant] ? variant : "compact"; // paddingTop 검증 if (!__STEPPER_PT[paddingTop]) { if (window.console && console.warn) { console.warn( `[ProgressStepper] \`paddingTop\` 은 "default" | "wide" 만 가능해요. 받은 값: ${paddingTop}` ); } } const safePt = __STEPPER_PT[paddingTop] ? paddingTop : "default"; // checkForFinish — variant=icon 일 때만 의미 있음 if (checkForFinish && safeVariant !== "icon") { if (window.console && console.warn) { console.warn( `[ProgressStepper] \`checkForFinish\` 는 \`variant="icon"\` 일 때만 사용할 수 있어요.` ); } } const safeCheckForFinish = !!checkForFinish && safeVariant === "icon"; // 자식만 ProgressStep 으로 — null/false 같은 빈 자식 제외 const steps = React.Children.toArray(children).filter(Boolean); const total = steps.length; // activeStepIndex 정규화 — 음수 / total 초과 보정 const safeActive = typeof activeStepIndex === "number" && Number.isFinite(activeStepIndex) ? Math.max(0, Math.min(total - 1, Math.round(activeStepIndex))) : 0; const cls = [ "tds-stepper", `tds-stepper--variant-${safeVariant}`, `tds-stepper--pt-${safePt}`, className, ].filter(Boolean).join(" "); return (