-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDefaultTextField.tsx
More file actions
93 lines (87 loc) · 2.99 KB
/
DefaultTextField.tsx
File metadata and controls
93 lines (87 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { ButtonHTMLAttributes, ChangeEvent, forwardRef, ReactElement, KeyboardEvent, FocusEvent } from 'react';
type Button = ReactElement<ButtonHTMLAttributes<HTMLButtonElement>>;
interface DefaultTextFieldProps {
label?: string;
detail?: string;
value?: string;
leftText?: string;
rightContent?: Button;
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
onKeyDown?: (e: KeyboardEvent<HTMLInputElement>) => void;
onFocus?: (e: FocusEvent<HTMLInputElement>) => void;
onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
placeholder?: string;
errorMessage?: string;
errorPosition?: 'bottom' | 'right';
className?: string;
labelClassName?: string;
detailClassName?: string;
disabled?: boolean;
maxLength?: number;
}
const DefaultTextField = forwardRef<HTMLInputElement, DefaultTextFieldProps>(
(
{
label,
detail,
value,
leftText,
rightContent,
onChange,
onKeyDown,
onFocus,
onBlur,
placeholder = '',
className = '',
labelClassName = '',
errorMessage,
errorPosition = 'bottom',
detailClassName = '',
disabled = false,
maxLength,
...rest
},
ref
) => {
return (
<div>
<label className={`block px-1 text-sm font-semibold text-gray-700 ${labelClassName}`}>{label}</label>
<label className={`block px-1 mb-1 font-medium text-placeholderText sm:text-10 md:text-13 ${detailClassName}`}>
{detail}
</label>
<div className="flex items-center justify-center relative">
{leftText && <div className="w-24 text-base font-bold whitespace-nowrap">{leftText}</div>}
<div className="relative w-full">
<input
ref={ref}
value={value}
onChange={onChange}
onKeyDown={onKeyDown}
onFocus={onFocus}
onBlur={onBlur}
placeholder={placeholder}
disabled={disabled}
{...rest}
className={`w-full h-11 px-3 py-2 border ${
errorMessage ? 'border-red-500' : 'border-placeholderText'
} rounded-[6px] text-sm placeholder:text-placeholderText outline-none ${className}`}
/>
{errorMessage && errorPosition === 'right' && (
<>
{/* 데스크탑일 때만 오른쪽에 보이기 */}
<p className="hidden md:block absolute left-full top-1/2 -translate-y-1/2 ml-2 text-xs text-red-500 whitespace-nowrap">
{errorMessage}
</p>
{/* 모바일에서는 아래에 표시 */}
<p className="md:hidden mt-1 text-xs text-red-500">{errorMessage}</p>
</>
)}
</div>
{rightContent && <div className="ml-3">{rightContent}</div>}
</div>
{errorMessage && errorPosition !== 'right' && <p className="mt-1 text-xs text-red-500">{errorMessage}</p>}
</div>
);
}
);
export default DefaultTextField;