@ehfuse/mui-form-controls 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +169 -0
  3. package/dist/AddressTextField.d.ts +10 -0
  4. package/dist/Autocomplete.d.ts +10 -0
  5. package/dist/BizNumTextField.d.ts +10 -0
  6. package/dist/CardNumTextField.d.ts +11 -0
  7. package/dist/Checkbox.d.ts +10 -0
  8. package/dist/ClearTextField.d.ts +22 -0
  9. package/dist/DateRange.d.ts +9 -0
  10. package/dist/DateTextField.d.ts +11 -0
  11. package/dist/DateTimeTextField.d.ts +11 -0
  12. package/dist/EmailTextField.d.ts +10 -0
  13. package/dist/JuminTextField.d.ts +10 -0
  14. package/dist/LabelSelect.d.ts +10 -0
  15. package/dist/NumberTextField.d.ts +11 -0
  16. package/dist/PasswordTextField.d.ts +10 -0
  17. package/dist/PhoneTextField.d.ts +11 -0
  18. package/dist/RadioGroup.d.ts +10 -0
  19. package/dist/SearchTextField.d.ts +33 -0
  20. package/dist/Select.d.ts +10 -0
  21. package/dist/Slider.d.ts +10 -0
  22. package/dist/Switch.d.ts +10 -0
  23. package/dist/TextArea.d.ts +24 -0
  24. package/dist/TextAreaTextField.d.ts +24 -0
  25. package/dist/TimeTextField.d.ts +11 -0
  26. package/dist/VerificationCodeTextField.d.ts +10 -0
  27. package/dist/components/ColonBox.d.ts +23 -0
  28. package/dist/components/GroupedInputWrapper.d.ts +36 -0
  29. package/dist/components/SimpleCalendar.d.ts +45 -0
  30. package/dist/components/TimePicker.d.ts +26 -0
  31. package/dist/components/TimeSelector.d.ts +24 -0
  32. package/dist/components/index.d.ts +4 -0
  33. package/dist/hooks/index.d.ts +12 -0
  34. package/dist/hooks/useGroupedInput.d.ts +48 -0
  35. package/dist/hooks/useKoreanHolidays.d.ts +29 -0
  36. package/dist/hooks/useTextFieldBase.d.ts +47 -0
  37. package/dist/icons/CalendarIcon.d.ts +10 -0
  38. package/dist/icons/ChevronLeft.d.ts +8 -0
  39. package/dist/icons/ChevronRight.d.ts +8 -0
  40. package/dist/icons/ClockIcon.d.ts +13 -0
  41. package/dist/icons/ColonIcon.d.ts +13 -0
  42. package/dist/icons/CopyIcon.d.ts +12 -0
  43. package/dist/icons/DashIcon.d.ts +12 -0
  44. package/dist/icons/card-icons.d.ts +21 -0
  45. package/dist/icons/email-icons.d.ts +27 -0
  46. package/dist/icons/index.d.ts +8 -0
  47. package/dist/index.d.ts +33 -0
  48. package/dist/index.js +443 -0
  49. package/dist/index.js.map +7 -0
  50. package/dist/index.mjs +443 -0
  51. package/dist/index.mjs.map +7 -0
  52. package/dist/label-select/LabelSelect.d.ts +9 -0
  53. package/dist/label-select/index.d.ts +9 -0
  54. package/dist/label-select/types.d.ts +38 -0
  55. package/dist/types.d.ts +406 -0
  56. package/dist/utils/biznum.d.ts +12 -0
  57. package/dist/utils/card.d.ts +17 -0
  58. package/dist/utils/date.d.ts +114 -0
  59. package/dist/utils/datetime.d.ts +37 -0
  60. package/dist/utils/email.d.ts +15 -0
  61. package/dist/utils/index.d.ts +17 -0
  62. package/dist/utils/jumin.d.ts +27 -0
  63. package/dist/utils/number.d.ts +15 -0
  64. package/dist/utils/password.d.ts +17 -0
  65. package/dist/utils/phone.d.ts +17 -0
  66. package/dist/utils/time.d.ts +27 -0
  67. package/package.json +78 -0
@@ -0,0 +1,9 @@
1
+ /**
2
+ * LabelSelect.tsx
3
+ *
4
+ * @license Proprietary License (독점 라이선스)
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ import { LabelSelectProps } from "./types";
9
+ export declare function LabelSelect(props: LabelSelectProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * mui-label-select
3
+ *
4
+ * @license Proprietary License (독점 라이선스)
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ export { LabelSelect } from "./LabelSelect";
9
+ export type { LabelSelectProps, LabelSelectOption, SelectChangeEvent, } from "./types";
@@ -0,0 +1,38 @@
1
+ /**
2
+ * types.ts
3
+ *
4
+ * @license Proprietary License (독점 라이선스)
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ import type { SxProps, Theme, FormControlProps } from "@mui/material";
9
+ import { SelectProps, SelectChangeEvent } from "@mui/material";
10
+ import { InputBaseComponentProps } from "@mui/material/InputBase";
11
+ import type { CSSProperties } from "react";
12
+ import type { FormLike } from "../types";
13
+ export interface LabelSelectOption {
14
+ value: string | number;
15
+ label: string;
16
+ }
17
+ export interface LabelSelectProps extends Omit<SelectProps, "value" | "onChange" | "defaultValue" | "form"> {
18
+ size?: "small" | "medium";
19
+ label: string;
20
+ value?: string | number;
21
+ onChange?: (event: SelectChangeEvent<string | number>) => void;
22
+ options: LabelSelectOption[];
23
+ form?: FormLike | null;
24
+ inputProps?: InputBaseComponentProps;
25
+ enableWheel?: boolean;
26
+ showLabel?: boolean;
27
+ emptyLabel?: string;
28
+ defaultValue?: string | number;
29
+ readOnly?: boolean;
30
+ readonly?: boolean;
31
+ showEmptyOption?: boolean;
32
+ className?: string;
33
+ style?: CSSProperties;
34
+ sx?: SxProps<Theme>;
35
+ formControlProps?: Omit<FormControlProps, "children">;
36
+ name?: string;
37
+ }
38
+ export type { SelectChangeEvent };
@@ -0,0 +1,406 @@
1
+ /**
2
+ * types.ts
3
+ *
4
+ * @license MIT
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ import * as React from "react";
9
+ import type { TextFieldProps as MuiTextFieldProps } from "@mui/material/TextField";
10
+ import type { SxProps, Theme } from "@mui/material/styles";
11
+ import type { CheckboxProps as MuiCheckboxProps } from "@mui/material/Checkbox";
12
+ import type { SwitchProps as MuiSwitchProps } from "@mui/material/Switch";
13
+ import type { RadioGroupProps as MuiRadioGroupProps } from "@mui/material/RadioGroup";
14
+ import type { SliderProps as MuiSliderProps } from "@mui/material/Slider";
15
+ import type { AutocompleteProps as MuiAutocompleteProps } from "@mui/material/Autocomplete";
16
+ import type { SelectProps as MuiSelectProps, SelectChangeEvent } from "@mui/material/Select";
17
+ import type { FormControlProps } from "@mui/material/FormControl";
18
+ import type { InputBaseComponentProps } from "@mui/material/InputBase";
19
+ export type TextFieldProps = MuiTextFieldProps;
20
+ export type PopoverOrigin = {
21
+ vertical: "top" | "center" | "bottom";
22
+ horizontal: "left" | "center" | "right";
23
+ };
24
+ /**
25
+ * 모든 TextField 공통 Props
26
+ */
27
+ export type FormLike = {
28
+ useFormValue: (name: string) => unknown;
29
+ handleFormChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
30
+ };
31
+ export type BaseTextFieldProps = {
32
+ readonly?: boolean;
33
+ debounce?: number;
34
+ form?: FormLike | null;
35
+ };
36
+ export type TextAreaProps = BaseTextFieldProps & {
37
+ label?: string;
38
+ value?: string;
39
+ name?: string;
40
+ onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
41
+ onBlur?: (e: React.FocusEvent<HTMLTextAreaElement>) => void;
42
+ onFocus?: (e: React.FocusEvent<HTMLTextAreaElement>) => void;
43
+ minRows?: number;
44
+ maxRows?: number;
45
+ placeholder?: string;
46
+ disabled?: boolean;
47
+ fullWidth?: boolean;
48
+ sx?: SxProps<Theme>;
49
+ inputProps?: React.TextareaHTMLAttributes<HTMLTextAreaElement>;
50
+ inputRef?: React.Ref<HTMLTextAreaElement>;
51
+ };
52
+ export type CheckboxProps = Omit<MuiCheckboxProps, "checked" | "onChange" | "form"> & BaseTextFieldProps & {
53
+ name?: string;
54
+ checked?: boolean;
55
+ label?: React.ReactNode;
56
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => void;
57
+ };
58
+ export type SwitchProps = Omit<MuiSwitchProps, "checked" | "onChange" | "form"> & BaseTextFieldProps & {
59
+ name?: string;
60
+ checked?: boolean;
61
+ label?: React.ReactNode;
62
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => void;
63
+ };
64
+ export type RadioOption = {
65
+ value: string;
66
+ label: React.ReactNode;
67
+ disabled?: boolean;
68
+ };
69
+ export type RadioGroupProps = Omit<MuiRadioGroupProps, "onChange" | "form"> & BaseTextFieldProps & {
70
+ name?: string;
71
+ value?: string;
72
+ label?: React.ReactNode;
73
+ options: RadioOption[];
74
+ disabled?: boolean;
75
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string) => void;
76
+ };
77
+ export type DateRangeProps = BaseTextFieldProps & {
78
+ startName?: string;
79
+ endName?: string;
80
+ startLabel?: string;
81
+ endLabel?: string;
82
+ startValue?: string;
83
+ endValue?: string;
84
+ onStartChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
85
+ onEndChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
86
+ fullWidth?: boolean;
87
+ size?: "small" | "medium";
88
+ readonly?: boolean;
89
+ gap?: number;
90
+ startProps?: Omit<DateTextFieldProps, "name" | "value" | "onChange" | "form">;
91
+ endProps?: Omit<DateTextFieldProps, "name" | "value" | "onChange" | "form">;
92
+ };
93
+ export type SliderProps = Omit<MuiSliderProps, "value" | "onChange" | "form"> & BaseTextFieldProps & {
94
+ name?: string;
95
+ label?: React.ReactNode;
96
+ value?: number | number[];
97
+ onChange?: (event: Event, value: number | number[]) => void;
98
+ };
99
+ export type AutocompleteOption = {
100
+ value: string | number;
101
+ label: string;
102
+ };
103
+ export type AutocompleteProps = Omit<MuiAutocompleteProps<AutocompleteOption, false, false, false>, "renderInput" | "options" | "value" | "onChange"> & BaseTextFieldProps & {
104
+ name?: string;
105
+ label?: string;
106
+ options: AutocompleteOption[];
107
+ value?: string | number | null;
108
+ onChange?: (value: string | number | null) => void;
109
+ fullWidth?: boolean;
110
+ size?: "small" | "medium";
111
+ readonly?: boolean;
112
+ textFieldProps?: Omit<TextFieldProps, "label" | "value" | "onChange">;
113
+ };
114
+ export type LabelSelectOption = {
115
+ value: string | number;
116
+ label: string;
117
+ };
118
+ export type SelectOption = {
119
+ value: string | number;
120
+ label: string;
121
+ };
122
+ export type LabelSelectProps = Omit<MuiSelectProps, "value" | "onChange" | "defaultValue" | "form"> & BaseTextFieldProps & {
123
+ label: string;
124
+ value?: string | number;
125
+ onChange?: (event: SelectChangeEvent<string | number>) => void;
126
+ options: LabelSelectOption[];
127
+ inputProps?: InputBaseComponentProps;
128
+ enableWheel?: boolean;
129
+ showLabel?: boolean;
130
+ emptyLabel?: string;
131
+ readOnly?: boolean;
132
+ showEmptyOption?: boolean;
133
+ fullWidth?: boolean;
134
+ formControlProps?: Omit<FormControlProps, "children">;
135
+ name?: string;
136
+ };
137
+ export type SelectProps = Omit<MuiSelectProps, "value" | "onChange" | "defaultValue" | "form"> & BaseTextFieldProps & {
138
+ value?: string | number;
139
+ onChange?: (event: SelectChangeEvent<string | number>) => void;
140
+ options: SelectOption[];
141
+ inputProps?: InputBaseComponentProps;
142
+ enableWheel?: boolean;
143
+ emptyLabel?: string;
144
+ readOnly?: boolean;
145
+ showEmptyOption?: boolean;
146
+ fullWidth?: boolean;
147
+ formControlProps?: Omit<FormControlProps, "children">;
148
+ name?: string;
149
+ };
150
+ export type { SelectChangeEvent };
151
+ /**
152
+ * 유효성 검사 기능을 가진 TextField 공통 Props
153
+ */
154
+ export type ValidatableTextFieldProps = {
155
+ onValidationChange?: (isValid: boolean) => void;
156
+ invalidBorderColor?: string;
157
+ };
158
+ export type SearchTextFieldProps = TextFieldProps & BaseTextFieldProps & {
159
+ loading?: boolean;
160
+ searchIcon?: boolean;
161
+ searchIconColor?: string;
162
+ clearIcon?: boolean;
163
+ clearIconColor?: string;
164
+ spellCheck?: boolean;
165
+ onClear?: () => void;
166
+ };
167
+ export type ClearTextFieldProps = TextFieldProps & BaseTextFieldProps & {
168
+ clearIcon?: boolean;
169
+ spellCheck?: boolean;
170
+ onClear?: () => void;
171
+ };
172
+ /**
173
+ * 비밀번호 유효성 검사 규칙
174
+ */
175
+ export type PasswordValidationRules = {
176
+ minLength?: number;
177
+ maxLength?: number;
178
+ requireUppercase?: boolean;
179
+ requireLowercase?: boolean;
180
+ requireNumber?: boolean;
181
+ requireSpecialChar?: boolean;
182
+ specialChars?: string;
183
+ };
184
+ /**
185
+ * 유효성 검사 결과
186
+ */
187
+ export type PasswordValidationResult = {
188
+ isValid: boolean;
189
+ errors: {
190
+ minLength?: boolean;
191
+ maxLength?: boolean;
192
+ requireUppercase?: boolean;
193
+ requireLowercase?: boolean;
194
+ requireNumber?: boolean;
195
+ requireSpecialChar?: boolean;
196
+ };
197
+ };
198
+ export type PasswordTextFieldProps = Omit<TextFieldProps, "type"> & BaseTextFieldProps & Omit<ValidatableTextFieldProps, "onValidationChange"> & {
199
+ showToggle?: boolean;
200
+ validationRules?: PasswordValidationRules;
201
+ onValidationChange?: (result: PasswordValidationResult) => void;
202
+ };
203
+ /**
204
+ * 전화번호 포맷 타입
205
+ */
206
+ export type PhoneFormat = "010-0000-0000" | "010-000-0000" | "02-000-0000" | "02-0000-0000" | "000-000-0000" | "000-0000-0000" | "0000-0000";
207
+ export type PhoneTextFieldProps = Omit<TextFieldProps, "type"> & BaseTextFieldProps & ValidatableTextFieldProps & {
208
+ autoFormat?: boolean;
209
+ includeDash?: boolean;
210
+ prefix?: string;
211
+ format?: PhoneFormat;
212
+ };
213
+ /**
214
+ * 숫자 텍스트 필드 타입
215
+ */
216
+ export type NumberTextFieldProps = Omit<TextFieldProps, "type"> & BaseTextFieldProps & {
217
+ thousandSeparator?: boolean;
218
+ decimalLength?: number;
219
+ decimalFixed?: boolean;
220
+ textAlign?: "left" | "center" | "right";
221
+ min?: number;
222
+ max?: number;
223
+ negative?: boolean;
224
+ negativeStyles?: React.CSSProperties;
225
+ prefix?: string;
226
+ suffix?: string;
227
+ showSuffix?: "always" | "hasValue";
228
+ selectOnFocus?: boolean;
229
+ };
230
+ export interface AddressTextFieldProps extends Omit<TextFieldProps, "type">, BaseTextFieldProps {
231
+ spellCheck?: boolean;
232
+ }
233
+ /** Daum 우편번호 API 응답 데이터 타입 */
234
+ export interface DaumPostcodeData {
235
+ address: string;
236
+ addressType: "R" | "J";
237
+ bname: string;
238
+ buildingName: string;
239
+ apartment: "Y" | "N";
240
+ zonecode: string;
241
+ jibunAddress: string;
242
+ roadAddress: string;
243
+ autoJibunAddress: string;
244
+ autoRoadAddress: string;
245
+ sido: string;
246
+ sigungu: string;
247
+ sigunguCode: string;
248
+ roadnameCode: string;
249
+ bcode: string;
250
+ roadname: string;
251
+ bname1: string;
252
+ bname2: string;
253
+ hname: string;
254
+ query: string;
255
+ userLanguageType: "K" | "E";
256
+ userSelectedType: "R" | "J";
257
+ noSelected: "Y" | "N";
258
+ }
259
+ /**
260
+ * 주민등록번호에서 추출한 정보
261
+ */
262
+ export type JuminInfo = {
263
+ value: string;
264
+ isValid: boolean;
265
+ birthDate: string | null;
266
+ gender: "male" | "female" | null;
267
+ isForeigner: boolean | null;
268
+ region: string | null;
269
+ };
270
+ /**
271
+ * 주민등록번호 텍스트 필드 타입
272
+ */
273
+ export type JuminTextFieldProps = Omit<TextFieldProps, "type" | "onChange" | "value"> & BaseTextFieldProps & ValidatableTextFieldProps & {
274
+ value?: string;
275
+ mask?: boolean;
276
+ maskColor?: string;
277
+ validateChecksum?: boolean;
278
+ fontSize?: string | number;
279
+ fontColor?: string;
280
+ fontFamily?: string;
281
+ onChange?: (info: JuminInfo) => void;
282
+ };
283
+ /**
284
+ * 커스텀 도메인 정의 (아이콘 포함)
285
+ */
286
+ export type CustomDomain = {
287
+ domain: string;
288
+ icon?: React.ReactNode;
289
+ };
290
+ /**
291
+ * 이메일 텍스트 필드 타입
292
+ */
293
+ export type EmailTextFieldProps = Omit<TextFieldProps, "type"> & BaseTextFieldProps & ValidatableTextFieldProps & {
294
+ domains?: string[];
295
+ extraDomains?: (string | CustomDomain)[];
296
+ suggestions?: boolean;
297
+ showLogos?: boolean;
298
+ };
299
+ /**
300
+ * 인증번호 입력 타입
301
+ */
302
+ export type VerificationCodeType = "numeric" | "alpha" | "alphanumeric";
303
+ /**
304
+ * 시간 포맷 타입
305
+ */
306
+ export type TimeFormat = "HH:mm" | "HH:mm:ss" | "hh:mm" | "hh:mm:ss";
307
+ /**
308
+ * 시간 텍스트 필드 타입
309
+ */
310
+ export type TimeTextFieldProps = Omit<TextFieldProps, "type"> & BaseTextFieldProps & Pick<ValidatableTextFieldProps, "invalidBorderColor"> & {
311
+ format?: TimeFormat;
312
+ minTime?: string;
313
+ maxTime?: string;
314
+ clockIcon?: boolean;
315
+ minuteStep?: number;
316
+ secondStep?: number;
317
+ hideDisabledTime?: boolean;
318
+ fontSize?: string | number;
319
+ fontColor?: string;
320
+ fontFamily?: string;
321
+ };
322
+ /**
323
+ * 날짜 포맷 타입
324
+ */
325
+ export type DateFormat = "YYYY-MM-DD" | "YYYY.MM.DD" | "YYYY/MM/DD" | "YYYY-MM" | "YYYY.MM" | "YYYY/MM" | "MM-DD-YYYY" | "MM.DD.YYYY" | "MM/DD/YYYY" | "MM-DD" | "MM.DD" | "MM/DD" | "DD-MM-YYYY" | "DD.MM.YYYY" | "DD/MM/YYYY" | "DD-MM" | "DD.MM" | "DD/MM" | "YY-MM-DD" | "YY.MM.DD" | "YY/MM/DD" | "YY-MM" | "YY.MM" | "YY/MM";
326
+ /**
327
+ * 날짜 텍스트 필드 타입
328
+ */
329
+ export type DateTextFieldProps = Omit<TextFieldProps, "type"> & BaseTextFieldProps & Pick<ValidatableTextFieldProps, "invalidBorderColor"> & {
330
+ format?: DateFormat;
331
+ separator?: string;
332
+ minDate?: Date;
333
+ maxDate?: Date;
334
+ holidays?: Date[];
335
+ holidayColor?: string;
336
+ calendarIcon?: boolean;
337
+ selectedColor?: string;
338
+ showToday?: boolean;
339
+ calendarAnchorOrigin?: PopoverOrigin;
340
+ calendarTransformOrigin?: PopoverOrigin;
341
+ calendarContainer?: HTMLElement;
342
+ onCalendarDismiss?: () => void;
343
+ onCalendarOpen?: () => void;
344
+ onCalendarClose?: () => void;
345
+ };
346
+ /**
347
+ * 인증번호 텍스트 필드 타입
348
+ */
349
+ export type VerificationCodeTextFieldProps = Omit<TextFieldProps, "type"> & BaseTextFieldProps & Pick<ValidatableTextFieldProps, "invalidBorderColor"> & {
350
+ length?: number;
351
+ type?: VerificationCodeType;
352
+ fontSize?: number;
353
+ fontColor?: string;
354
+ fontFamily?: string;
355
+ dotSize?: number;
356
+ caretColor?: string;
357
+ onComplete?: (value: string) => void;
358
+ };
359
+ /**
360
+ * 사업자등록번호 텍스트 필드 타입
361
+ */
362
+ export type BizNumTextFieldProps = Omit<TextFieldProps, "type" | "value"> & BaseTextFieldProps & ValidatableTextFieldProps & {
363
+ value?: string;
364
+ includeDash?: boolean;
365
+ validate?: boolean;
366
+ copyIcon?: boolean;
367
+ fontSize?: string | number;
368
+ fontColor?: string;
369
+ fontFamily?: string;
370
+ };
371
+ /**
372
+ * 카드번호 텍스트 필드 타입
373
+ */
374
+ export type CardNumTextFieldProps = Omit<TextFieldProps, "type" | "value"> & BaseTextFieldProps & ValidatableTextFieldProps & {
375
+ value?: string;
376
+ maskColor?: string;
377
+ fontSize?: string | number;
378
+ fontColor?: string;
379
+ fontFamily?: string;
380
+ validate?: boolean;
381
+ onCardBrandChange?: (brand: string | null) => void;
382
+ logoIcon?: boolean;
383
+ };
384
+ /**
385
+ * 날짜시간 포맷 타입
386
+ */
387
+ export type DateTimeFormat = "YYYY-MM-DD HH:mm" | "YYYY-MM-DD HH:mm:ss" | "YYYY-MM-DD hh:mm" | "YYYY-MM-DD hh:mm:ss" | "YYYY.MM.DD HH:mm" | "YYYY.MM.DD HH:mm:ss" | "YYYY.MM.DD hh:mm" | "YYYY.MM.DD hh:mm:ss" | "YYYY/MM/DD HH:mm" | "YYYY/MM/DD HH:mm:ss" | "YYYY/MM/DD hh:mm" | "YYYY/MM/DD hh:mm:ss";
388
+ /**
389
+ * 날짜시간 텍스트 필드 타입
390
+ */
391
+ export type DateTimeTextFieldProps = Omit<TextFieldProps, "type"> & BaseTextFieldProps & Pick<ValidatableTextFieldProps, "invalidBorderColor"> & {
392
+ format?: DateTimeFormat;
393
+ dateSeparator?: string;
394
+ minDateTime?: Date;
395
+ maxDateTime?: Date;
396
+ minTime?: string;
397
+ maxTime?: string;
398
+ holidays?: Date[];
399
+ holidayColor?: string;
400
+ calendarIcon?: boolean;
401
+ selectedColor?: string;
402
+ showToday?: boolean;
403
+ minuteStep?: number;
404
+ secondStep?: number;
405
+ hideDisabledTime?: boolean;
406
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * biznum.ts - 사업자번호 관련 유틸리티 함수
3
+ *
4
+ * @license MIT
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ /**
9
+ * 사업자번호 유효성 검사 (검증 알고리즘)
10
+ * 사업자등록번호는 10자리 숫자이며, 마지막 자리가 검증번호입니다.
11
+ */
12
+ export declare function validateBusinessNumber(value: string): boolean;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * card.ts - 카드번호 관련 유틸리티 함수
3
+ *
4
+ * @license MIT
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ /** 카드 브랜드 타입 */
9
+ export type CardBrand = "visa" | "mastercard" | "amex" | "jcb" | "diners" | "discover" | "unionpay" | "bc" | null;
10
+ /**
11
+ * 카드번호 유효성 검사 (Luhn 알고리즘)
12
+ */
13
+ export declare function validateCardNumber(value: string): boolean;
14
+ /**
15
+ * 카드 브랜드 감지 (국제 브랜드 기준)
16
+ */
17
+ export declare function detectCardBrand(value: string): CardBrand;
@@ -0,0 +1,114 @@
1
+ /**
2
+ * date.ts - 날짜 관련 유틸리티 함수
3
+ *
4
+ * @license MIT
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ import type { DateFormat, DateTimeFormat } from "../types";
9
+ /**
10
+ * 윤년 체크
11
+ */
12
+ export declare function isLeapYear(year: number): boolean;
13
+ /**
14
+ * 해당 월의 말일 계산
15
+ */
16
+ export declare function getDaysInMonth(year: number, month: number): number;
17
+ /**
18
+ * 날짜 포맷에 따른 구분자 가져오기
19
+ */
20
+ export declare function getSeparator(format: DateFormat): string;
21
+ /**
22
+ * 날짜 자동 포맷팅 함수
23
+ */
24
+ export declare function formatDate(value: string, format: DateFormat): string;
25
+ /**
26
+ * 포맷에 따른 최대 길이 계산
27
+ */
28
+ export declare function getMaxLength(format: DateFormat): number;
29
+ /**
30
+ * 포맷에 따른 완성 숫자 길이
31
+ */
32
+ export declare function getCompleteLength(format: DateFormat): number;
33
+ /**
34
+ * 날짜 문자열에서 연/월/일 추출
35
+ */
36
+ export declare function parseDateParts(value: string, format: DateFormat): {
37
+ year: number;
38
+ month: number;
39
+ day: number;
40
+ } | null;
41
+ /**
42
+ * 날짜 유효성 검사
43
+ */
44
+ export declare function validateDate(value: string, format: DateFormat, minDate?: Date, maxDate?: Date): boolean;
45
+ /**
46
+ * 날짜 문자열을 Date 객체로 변환
47
+ */
48
+ export declare function parseToDate(value: string, format: DateFormat): Date | null;
49
+ /**
50
+ * 날짜 값 제한 (년/월/일)
51
+ */
52
+ export declare function clampDateValue(value: string, type: "year" | "month" | "day", yearValue?: string, monthValue?: string): string;
53
+ /**
54
+ * DateTimeFormat에서 DateFormat 부분 추출
55
+ */
56
+ export declare function extractDateFormat(format: DateTimeFormat): DateFormat;
57
+ /**
58
+ * 초 필드가 있는지 확인
59
+ */
60
+ export declare function hasSecondField(format: DateTimeFormat): boolean;
61
+ /**
62
+ * 입력된 숫자를 유효한 범위로 보정 (날짜용)
63
+ */
64
+ export declare function constrainDateNumbers(numbers: string, format: DateFormat): string;
65
+ /**
66
+ * 날짜 자동 포맷팅 함수 (DateTimeTextField용)
67
+ */
68
+ export declare function formatDateValue(value: string, format: DateFormat): string;
69
+ /**
70
+ * 날짜 포맷을 밑줄 placeholder로 변환
71
+ */
72
+ export declare function formatToPlaceholder(format: DateFormat): string;
73
+ /**
74
+ * 클릭 위치에 따라 선택할 영역의 시작/끝 인덱스 반환
75
+ */
76
+ export declare function getSegmentRange(cursorPos: number, format: DateFormat): {
77
+ start: number;
78
+ end: number;
79
+ };
80
+ /**
81
+ * 포맷에 연도가 포함되어 있는지 확인
82
+ * - YYYY 또는 YY가 포함되어 있으면 연도가 있는 포맷
83
+ */
84
+ export declare function hasYearInFormat(format: DateFormat): boolean;
85
+ /**
86
+ * 포맷이 2자리 연도(YY)를 사용하는지 확인
87
+ */
88
+ export declare function has2DigitYear(format: DateFormat): boolean;
89
+ /**
90
+ * 2자리 연도를 4자리 연도로 변환
91
+ * - 50 이상이면 1900년대, 50 미만이면 2000년대
92
+ */
93
+ export declare function convertYY2YYYY(yy: number): number;
94
+ /**
95
+ * 포맷에서 날짜 파싱 (연도 없는 포맷 지원, internalYear 활용)
96
+ */
97
+ export declare function parseDateWithInternalYear(formattedValue: string, format: DateFormat, internalYear?: number | null): {
98
+ year: number;
99
+ month: number;
100
+ day: number;
101
+ } | null;
102
+ /**
103
+ * 달력 선택 또는 입력값을 출력용 문자열로 변환 (연도가 없는 포맷이어도 연도 포함)
104
+ * @param formattedValue - 포맷된 날짜 문자열 (예: "12-25")
105
+ * @param format - 날짜 포맷
106
+ * @param separator - 출력 구분자
107
+ * @param internalYear - 내부적으로 관리하는 연도 (연도 없는 포맷용)
108
+ * @returns 출력용 날짜 문자열 (항상 연도 포함, 예: "2024-12-25")
109
+ */
110
+ export declare function buildDateOutputValue(formattedValue: string, format: DateFormat, separator: string, internalYear?: number | null): string;
111
+ /**
112
+ * Date 객체에서 포맷에 맞는 숫자 문자열 생성
113
+ */
114
+ export declare function dateToNumbers(date: Date, format: DateFormat): string;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * datetime.ts - 날짜시간 관련 유틸리티 함수
3
+ *
4
+ * @license MIT
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ import { TimeFormat } from "../types";
9
+ /**
10
+ * 윤년 체크
11
+ */
12
+ export declare function isLeapYear(year: number): boolean;
13
+ /**
14
+ * 해당 월의 말일 계산
15
+ */
16
+ export declare function getDaysInMonth(year: number, month: number): number;
17
+ /**
18
+ * 포맷에 따른 필드 개수 (2: 시:분, 3: 시:분:초)
19
+ */
20
+ export declare function getTimeFieldCount(format: TimeFormat): number;
21
+ /**
22
+ * 12시간 형식인지 확인
23
+ */
24
+ export declare function is12HourFormat(format: string): boolean;
25
+ /**
26
+ * 시간 유효성 검사
27
+ * @param formatOrIs12Hour - TimeFormat 문자열 또는 12시간제 여부 boolean
28
+ */
29
+ export declare function validateTime(hour: string, minute: string, second: string, formatOrIs12Hour: TimeFormat | boolean, minTime?: string, maxTime?: string): boolean;
30
+ /**
31
+ * 날짜 값 제한 (년/월/일)
32
+ */
33
+ export declare function clampDateValue(value: string, type: "year" | "month" | "day", yearValue?: string, monthValue?: string): string;
34
+ /**
35
+ * 시간 값 제한 (시/분/초)
36
+ */
37
+ export declare function clampTimeValue(value: string, type: "hour" | "minute" | "second", is12Hour?: boolean): string;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * email.ts - 이메일 관련 유틸리티 함수
3
+ *
4
+ * @license MIT
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ /**
9
+ * 기본 도메인 제안 목록
10
+ */
11
+ export declare const DEFAULT_EMAIL_DOMAINS: string[];
12
+ /**
13
+ * 이메일 유효성 검사
14
+ */
15
+ export declare function validateEmail(email: string): boolean;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * utils/index.ts
3
+ *
4
+ * @license MIT
5
+ * @copyright 2025 김영진 (Kim Young Jin)
6
+ * @author 김영진 (ehfuse@gmail.com)
7
+ */
8
+ export { isLeapYear, getDaysInMonth, getSeparator, formatDate, getMaxLength, getCompleteLength, parseDateParts, validateDate, parseToDate, clampDateValue, extractDateFormat, hasSecondField, constrainDateNumbers, formatDateValue, formatToPlaceholder, getSegmentRange, hasYearInFormat, has2DigitYear, convertYY2YYYY, parseDateWithInternalYear, buildDateOutputValue, dateToNumbers, } from "./date";
9
+ export { getTimeFieldCount, is12HourFormat, validateTime, clampTimeValue, } from "./time";
10
+ export { formatNumber, parseNumber } from "./number";
11
+ export { DEFAULT_EMAIL_DOMAINS, validateEmail } from "./email";
12
+ export { formatPhoneNumber, getPhoneMaxLength } from "./phone";
13
+ export { DEFAULT_SPECIAL_CHARS, DEFAULT_PASSWORD_VALIDATION_RULES, validatePassword, } from "./password";
14
+ export { validateBusinessNumber } from "./biznum";
15
+ export { validateCardNumber, detectCardBrand } from "./card";
16
+ export type { CardBrand } from "./card";
17
+ export { REGION_MAP, extractJuminInfo, validateJuminChecksum, validateJuminBirthDate, } from "./jumin";