/** * Tailwind CSS 기반 Input 컴포넌트 공통 스타일 */ export const INPUT_CLASSES = { // 기본 input 스타일 base: ` w-full h-9 px-3 py-2 text-sm border border-input rounded-md bg-background text-foreground transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 placeholder:text-muted-foreground max-w-full box-border `, // 선택된 상태 selected: ` ring-2 ring-primary/20 `, // 라벨 스타일 label: ` absolute -top-6 left-0 text-xs font-medium text-foreground `, // 필수 표시 required: ` ml-0.5 text-destructive `, // 컨테이너 container: ` relative w-full h-full max-w-full box-border `, // textarea textarea: ` min-h-[80px] w-full px-3 py-2 text-sm border border-input rounded-md bg-background text-foreground transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 resize-none max-w-full box-border `, // select select: ` h-9 w-full px-3 py-2 text-sm border border-input rounded-md bg-background text-foreground transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 cursor-pointer max-w-full box-border `, // flex 컨테이너 (email, tel, url 등) flexContainer: ` flex items-center gap-2 w-full h-full max-w-full box-border `, // 구분자 (@ , ~ 등) separator: ` text-sm font-medium text-muted-foreground `, // Currency 통화 기호 currencySymbol: ` text-sm font-semibold text-green-600 pl-2 `, // Currency input currencyInput: ` flex-1 h-9 px-3 py-2 text-sm font-semibold text-right border border-input rounded-md bg-background text-green-600 transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 `, // Percentage 퍼센트 기호 percentageSymbol: ` text-sm font-semibold text-blue-600 pr-2 `, // Percentage input percentageInput: ` flex-1 h-9 px-3 py-2 text-sm font-semibold text-right border border-input rounded-md bg-background text-blue-600 transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 `, }; /** * 클래스명 결합 유틸리티 */ export function cn(...classes: (string | boolean | undefined)[]): string { return classes.filter(Boolean).join(" ").replace(/\s+/g, " ").trim(); } /** * Input 클래스 생성기 */ export function getInputClasses(isSelected?: boolean, isDisabled?: boolean): string { return cn(INPUT_CLASSES.base, isSelected && INPUT_CLASSES.selected, isDisabled && "opacity-60"); }