@uniai-fe/uds-primitives 0.12.7 → 0.12.8

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.
@@ -46,6 +46,14 @@ const defaultClockIcon = (
46
46
  </svg>
47
47
  );
48
48
 
49
+ /**
50
+ * Input Time Utility; 24시간 저장 문자열을 trigger draft로 변환한다.
51
+ * @utility
52
+ * @param {string} value `HH:mm` 또는 `HH:mm:ss` 저장값
53
+ * @param {"12h" | "24h"} format 표시 형식
54
+ * @desc 유효하지 않거나 빈 저장값은 빈 field와 `am` period로 초기화한다.
55
+ * @return {InputTimeDraft} 표시용 field 문자열과 period
56
+ */
49
57
  const getInputTimeDraft = (
50
58
  value: string,
51
59
  format: "12h" | "24h",
@@ -73,11 +81,43 @@ const getInputTimeDraft = (
73
81
  * 저장값은 24시간 `HH:mm` 또는 `HH:mm:ss` 문자열로 유지한다.
74
82
  * @component
75
83
  * @param {InputTimeTemplateProps} props
76
- * @param {"primary" | "secondary" | "tertiary" | "table"} [props.priority="primary"] input priority
77
- * @param {"small" | "medium" | "large"} [props.size="medium"] input size
78
- * @param {"12h" | "24h"} [props.format="24h"] 표시 형식
79
- * @param {boolean} [props.withSeconds=false] field 노출 여부
80
- * @returns {ReactNode} 시간 입력과 선택 panel
84
+ * @property {string} [props.value] 제어형 24시간 저장값
85
+ * @property {string} [props.defaultValue] 비제어 초기 24시간 저장값
86
+ * @property {(value: string) => void} [props.onChange] 변경 핸들러
87
+ * @property {(value: string) => void} [props.onValueChange] 변경 별칭
88
+ * @property {string} [props.name] hidden input form name
89
+ * @property {string} [props.form] hidden input form id
90
+ * @property {UseFormRegisterReturn} [props.register] hidden input react-hook-form register 결과
91
+ * @property {"primary" | "secondary" | "tertiary" | "table"} [props.priority="primary"] input priority
92
+ * @property {"small" | "medium" | "large"} [props.size="medium"] input size
93
+ * @property {"default" | "active" | "focused" | "success" | "error" | "disabled" | "loading"} [props.state="default"] input state
94
+ * @property {boolean} [props.block=false] width 100% 여부
95
+ * @property {"full" | "fit" | "fill" | "auto" | number | string} [props.width] width preset 또는 custom width
96
+ * @property {string} [props.className] root className
97
+ * @property {boolean} [props.disabled] disabled 여부
98
+ * @property {boolean} [props.readOnly=false] readOnly 여부
99
+ * @property {boolean} [props.required] hidden input required 여부
100
+ * @property {string} [props.id] trigger root id
101
+ * @property {"12h" | "24h"} [props.format="24h"] 표시 형식
102
+ * @property {boolean} [props.withSeconds=false] 초 field 노출 여부
103
+ * @property {boolean} [props.clearable=true] 삭제 action 노출 여부
104
+ * @property {number} [props.hoursStep=1] 시 증감 단위
105
+ * @property {number} [props.minutesStep=5] 분 증감 단위
106
+ * @property {number} [props.secondsStep=1] 초 증감 단위
107
+ * @property {ReactNode} [props.icon] clock icon override
108
+ * @property {"left" | "right"} [props.iconPosition] clock icon 위치
109
+ * @property {string} [props.iconLabel="시간 선택"] clock icon 접근성 라벨
110
+ * @property {InputTimeHiddenInputProps} [props.hiddenInputProps] hidden input native props
111
+ * @property {string} [props.hoursInputLabel="시"] 시 input 접근성 라벨
112
+ * @property {string} [props.minutesInputLabel="분"] 분 input 접근성 라벨
113
+ * @property {string} [props.secondsInputLabel="초"] 초 input 접근성 라벨
114
+ * @property {string} [props.amPmInputLabel="오전 또는 오후"] 오전·오후 input 접근성 라벨
115
+ * @property {string} [props.hoursPlaceholder="HH"] 시 placeholder
116
+ * @property {string} [props.minutesPlaceholder="MM"] 분 placeholder
117
+ * @property {string} [props.secondsPlaceholder="SS"] 초 placeholder
118
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [props.onFocus] field focus 핸들러
119
+ * @property {(event: FocusEvent<HTMLDivElement>) => void} [props.onBlur] trigger root blur 핸들러
120
+ * @desc 표시 draft를 편집·정규화하고 TimePicker 선택값과 hidden input 저장값을 동기화한다.
81
121
  */
82
122
  const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
83
123
  (
@@ -136,6 +176,7 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
136
176
  getInputTimeDraft(value ?? defaultValue ?? "", format),
137
177
  );
138
178
 
179
+ // 외부 value 또는 표시 형식 변경 시 저장값을 기준으로 편집 draft를 다시 계산한다.
139
180
  useEffect(() => {
140
181
  setDraft(getInputTimeDraft(timeValue, format));
141
182
  }, [format, timeValue]);
@@ -165,6 +206,13 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
165
206
  ? { width: widthValue }
166
207
  : undefined;
167
208
 
209
+ /**
210
+ * Input Time Utility; RHF hidden input 변경 이벤트 동기화 함수.
211
+ * @utility
212
+ * @param {string} nextValue 다음 24시간 저장값
213
+ * @desc 표시 field와 분리된 hidden input register에 synthetic change를 전달한다.
214
+ * @return {void}
215
+ */
168
216
  const emitRegisterChange = useCallback(
169
217
  (nextValue: string) => {
170
218
  register?.onChange({
@@ -175,6 +223,13 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
175
223
  [register],
176
224
  );
177
225
 
226
+ /**
227
+ * Input Time Utility; 시간 저장값 갱신 함수.
228
+ * @utility
229
+ * @param {string} nextValue 다음 24시간 저장값
230
+ * @desc draft, controlled/uncontrolled value와 RHF 저장값을 같은 값으로 동기화한다.
231
+ * @return {void}
232
+ */
178
233
  const updateValue = useCallback(
179
234
  (nextValue: string) => {
180
235
  setDraft(getInputTimeDraft(nextValue, format));
@@ -184,6 +239,13 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
184
239
  [emitRegisterChange, format, setTimeValue],
185
240
  );
186
241
 
242
+ /**
243
+ * Input Time Utility; 완성된 trigger draft를 저장값으로 commit한다.
244
+ * @utility
245
+ * @param {InputTimeDraft} nextDraft 다음 field 문자열과 period
246
+ * @desc 필요한 field가 두 자리이고 범위가 유효할 때만 24시간 문자열로 직렬화한다.
247
+ * @return {void}
248
+ */
187
249
  const commitDraft = useCallback(
188
250
  (nextDraft: InputTimeDraft) => {
189
251
  const { hours, minutes, seconds } = nextDraft.fields;
@@ -224,6 +286,14 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
224
286
  [format, updateValue, withSeconds],
225
287
  );
226
288
 
289
+ /**
290
+ * Input Time Utility; field 입력 정규화 함수.
291
+ * @utility
292
+ * @param {"hours" | "minutes" | "seconds"} unit 변경 단위
293
+ * @param {string} rawValue 입력 문자열
294
+ * @desc 숫자 두 자리만 draft에 남기고 완성된 값은 즉시 commit한다.
295
+ * @return {void}
296
+ */
227
297
  const handleFieldChange = (unit: TimePickerUnit, rawValue: string) => {
228
298
  const nextValue = rawValue.replace(/\D/g, "").slice(0, 2);
229
299
  const nextDraft = {
@@ -243,6 +313,13 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
243
313
  onFocus?.(event);
244
314
  };
245
315
 
316
+ /**
317
+ * Input Time Utility; field blur 정규화 함수.
318
+ * @utility
319
+ * @param {"hours" | "minutes" | "seconds"} unit blur 단위
320
+ * @desc 빈 field는 유지하고 입력값은 단위·표시 형식 범위로 clamp한 뒤 commit한다.
321
+ * @return {void}
322
+ */
246
323
  const handleFieldBlur = (unit: TimePickerUnit) => {
247
324
  const currentValue = draft.fields[unit];
248
325
  if (!currentValue) {
@@ -262,6 +339,14 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
262
339
  commitDraft(nextDraft);
263
340
  };
264
341
 
342
+ /**
343
+ * Input Time Utility; field 방향키 증감 함수.
344
+ * @utility
345
+ * @param {"hours" | "minutes" | "seconds"} unit 활성 단위
346
+ * @param {KeyboardEvent<HTMLInputElement>} event field keyboard event
347
+ * @desc 위·아래 방향키만 단위별 step으로 순환 증감한다.
348
+ * @return {void}
349
+ */
265
350
  const handleFieldKeyDown = (
266
351
  unit: TimePickerUnit,
267
352
  event: KeyboardEvent<HTMLInputElement>,
@@ -280,6 +365,13 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
280
365
  updateValue(stepTimeValue(timeValue, unit, amount * step, withSeconds));
281
366
  };
282
367
 
368
+ /**
369
+ * Input Time Utility; trigger stepper 증감 함수.
370
+ * @utility
371
+ * @param {1 | -1} amount 증감 방향
372
+ * @desc focus된 단위가 있을 때만 해당 단위 step으로 저장값을 순환 증감한다.
373
+ * @return {void}
374
+ */
283
375
  const handleStep = (amount: 1 | -1) => {
284
376
  if (!activeUnit) {
285
377
  return;
@@ -300,6 +392,13 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
300
392
  updateValue(nextValue);
301
393
  };
302
394
 
395
+ /**
396
+ * Input Time Utility; TimePicker 시 선택 반영 함수.
397
+ * @utility
398
+ * @param {number} hours 선택한 표시 시
399
+ * @desc 12시간제는 현재 draft period를 결합해 24시간 저장 시로 변환한다.
400
+ * @return {void}
401
+ */
303
402
  const handleHourSelect = (hours: number) => {
304
403
  const parts = parseTimeValue(timeValue) ?? {
305
404
  hours: 0,
@@ -324,6 +423,13 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
324
423
  updateValue(serializeTimeValue({ ...parts, minutes }, withSeconds));
325
424
  };
326
425
 
426
+ /**
427
+ * Input Time Utility; trigger root blur와 RHF touched 상태 동기화 함수.
428
+ * @utility
429
+ * @param {FocusEvent<HTMLDivElement>} event trigger root blur event
430
+ * @desc root 내부 focus 이동은 무시하고 외부로 벗어날 때만 register와 소비자 callback을 호출한다.
431
+ * @return {void}
432
+ */
327
433
  const handleRootBlur = (event: FocusEvent<HTMLDivElement>) => {
328
434
  if (
329
435
  event.relatedTarget instanceof Node &&
@@ -339,6 +445,13 @@ const InputTimeTemplate = forwardRef<HTMLDivElement, InputTimeTemplateProps>(
339
445
  onBlur?.(event);
340
446
  };
341
447
 
448
+ /**
449
+ * Input Time Utility; TimePicker panel open 상태 갱신 함수.
450
+ * @utility
451
+ * @param {boolean} nextOpen 다음 open 상태
452
+ * @desc disabled 또는 readOnly 상태에서는 panel을 열지 않는다.
453
+ * @return {void}
454
+ */
342
455
  const handleOpenChange = (nextOpen: boolean) => {
343
456
  setIsOpen(nextOpen && !isDisabled && !readOnly);
344
457
  };
@@ -12,7 +12,34 @@ import type { InputTimeTriggerProps } from "../../types";
12
12
  * Input Time trigger; 시·분·초 field와 focus 단위 stepper를 렌더한다.
13
13
  * @component
14
14
  * @param {InputTimeTriggerProps} props
15
- * @returns {ReactNode} 시간 입력 trigger
15
+ * @property {InputTimeTriggerFields} props.fields 시·분·초 입력값
16
+ * @property {"am" | "pm"} props.period 오전·오후 구분
17
+ * @property {"hours" | "minutes" | "seconds" | null} props.activeUnit 현재 활성 단위
18
+ * @property {"primary" | "secondary" | "tertiary" | "table"} props.priority input priority
19
+ * @property {"small" | "medium" | "large"} props.size input size
20
+ * @property {"default" | "active" | "focused" | "success" | "error" | "disabled" | "loading"} props.state input state
21
+ * @property {"12h" | "24h"} props.format 표시 형식
22
+ * @property {boolean} props.withSeconds 초 field 노출 여부
23
+ * @property {boolean} props.disabled 비활성화 여부
24
+ * @property {boolean} props.readOnly 읽기 전용 여부
25
+ * @property {ReactNode} props.icon clock icon
26
+ * @property {"left" | "right"} props.iconPosition clock icon 위치
27
+ * @property {string} props.iconLabel clock icon 접근성 라벨
28
+ * @property {string} props.hoursInputLabel 시 input 접근성 라벨
29
+ * @property {string} props.minutesInputLabel 분 input 접근성 라벨
30
+ * @property {string} props.secondsInputLabel 초 input 접근성 라벨
31
+ * @property {string} props.amPmInputLabel 오전·오후 input 접근성 라벨
32
+ * @property {string} props.hoursPlaceholder 시 placeholder
33
+ * @property {string} props.minutesPlaceholder 분 placeholder
34
+ * @property {string} props.secondsPlaceholder 초 placeholder
35
+ * @property {(unit: "hours" | "minutes" | "seconds", value: string) => void} props.onFieldChange field 변경 핸들러
36
+ * @property {(unit: "hours" | "minutes" | "seconds", event: FocusEvent<HTMLInputElement>) => void} props.onFieldFocus field focus 핸들러
37
+ * @property {(unit: "hours" | "minutes" | "seconds") => void} props.onFieldBlur field blur 핸들러
38
+ * @property {(unit: "hours" | "minutes" | "seconds", event: KeyboardEvent<HTMLInputElement>) => void} props.onFieldKeyDown field keyboard 핸들러
39
+ * @property {(period: "am" | "pm") => void} props.onPeriodChange 오전·오후 변경 핸들러
40
+ * @property {(amount: 1 | -1) => void} props.onStep 활성 단위 증감 핸들러
41
+ * @property {(event: FocusEvent<HTMLDivElement>) => void} props.onRootBlur root blur 핸들러
42
+ * @desc field별 입력과 focus를 Template의 draft·commit pipeline으로 전달한다.
16
43
  */
17
44
  const InputTimeTrigger = forwardRef<HTMLDivElement, InputTimeTriggerProps>(
18
45
  (
@@ -73,7 +100,13 @@ const InputTimeTrigger = forwardRef<HTMLDivElement, InputTimeTriggerProps>(
73
100
  const onClockClick = () => {
74
101
  hoursRef.current?.focus();
75
102
  };
76
- // PopOver.Trigger가 주입한 click은 clock button에서만 popup toggle로 위임한다.
103
+ /**
104
+ * Input Time Utility; PopOver trigger click 위임 함수.
105
+ * @utility
106
+ * @param {MouseEvent<HTMLDivElement>} event trigger root click event
107
+ * @desc field 편집 click은 panel을 toggle하지 않고 clock button click만 PopOver에 전달한다.
108
+ * @return {void}
109
+ */
77
110
  const onRootClick = (event: MouseEvent<HTMLDivElement>) => {
78
111
  if (
79
112
  event.target instanceof Element &&
@@ -1,4 +1,9 @@
1
- import type { MouseEvent, ReactNode } from "react";
1
+ import type {
2
+ ComponentPropsWithoutRef,
3
+ FocusEvent,
4
+ MouseEvent,
5
+ ReactNode,
6
+ } from "react";
2
7
  import type { UseFormRegisterReturn } from "react-hook-form";
3
8
  import type {
4
9
  CalendarColumns,
@@ -10,7 +15,18 @@ import type {
10
15
  CalendarRangeValue,
11
16
  CalendarValue,
12
17
  } from "../../calendar";
13
- import type { InputPriority, InputState } from "./foundation";
18
+ import type { FormFieldWidth } from "../../form/types/props";
19
+ import type { InputPriority, InputSize, InputState } from "./foundation";
20
+
21
+ /**
22
+ * Input Date hidden input props.
23
+ * @typedef {Omit<ComponentPropsWithoutRef<"input">, "type" | "value" | "defaultValue" | "name">} InputCalendarHiddenInputProps
24
+ * @desc Template이 고정하는 type, value, defaultValue와 name을 제외한 native hidden input 계약
25
+ */
26
+ export type InputCalendarHiddenInputProps = Omit<
27
+ ComponentPropsWithoutRef<"input">,
28
+ "type" | "value" | "defaultValue" | "name"
29
+ >;
14
30
 
15
31
  /**
16
32
  * Calendar trigger(Input) 영역에서 필요한 속성 묶음.
@@ -22,8 +38,14 @@ import type { InputPriority, InputState } from "./foundation";
22
38
  * @property {boolean} [disabled] disabled 여부
23
39
  * @property {boolean} [readOnly] readOnly 여부
24
40
  * @property {string} [placeholder] trigger 내부 placeholder
25
- * @property {InputPriority} [priority] trigger input priority
26
- * @property {InputState} [state] trigger input state
41
+ * @property {"primary" | "secondary" | "tertiary" | "table"} [priority] trigger input priority
42
+ * @property {"small" | "medium" | "large"} [size] trigger input size
43
+ * @property {"default" | "active" | "focused" | "success" | "error" | "disabled" | "loading"} [state] trigger input state
44
+ * @property {boolean} [block] trigger width 100% 여부
45
+ * @property {"full" | "fit" | "fill" | "auto" | number | string} [width] trigger width preset 또는 custom width
46
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [onFocus] trigger focus 핸들러
47
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [onBlur] trigger blur 핸들러
48
+ * @desc Date trigger의 표시·상호작용 입력 계약. Template의 name/register는 hidden input 저장에 사용한다.
27
49
  */
28
50
  export interface InputCalendarTriggerProps {
29
51
  /**
@@ -59,16 +81,38 @@ export interface InputCalendarTriggerProps {
59
81
  * - table일 때 Trigger는 left icon 배치를 사용한다.
60
82
  */
61
83
  priority?: InputPriority;
84
+ /**
85
+ * "small" | "medium" | "large".
86
+ */
87
+ size?: InputSize;
62
88
  /**
63
89
  * trigger input state
64
90
  */
65
91
  state?: InputState;
92
+ /**
93
+ * trigger width 100% 여부.
94
+ */
95
+ block?: boolean;
96
+ /**
97
+ * "full" | "fit" | "fill" | "auto" | number | string.
98
+ */
99
+ width?: FormFieldWidth;
100
+ /**
101
+ * trigger focus 핸들러.
102
+ */
103
+ onFocus?: (event: FocusEvent<HTMLInputElement>) => void;
104
+ /**
105
+ * trigger blur 핸들러.
106
+ */
107
+ onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
66
108
  }
67
109
 
68
110
  /**
69
111
  * Trigger view에서만 사용하는 부가 props.
70
112
  * @property {string} [className] trigger root className
71
113
  * @property {string} [displayValue] 표시 값 문자열
114
+ * @see InputCalendarTriggerProps
115
+ * @desc 기본 Date trigger가 InputFoundation.Base에 전달하는 view 계약
72
116
  */
73
117
  export interface InputCalendarTriggerViewProps extends InputCalendarTriggerProps {
74
118
  /**
@@ -90,8 +134,14 @@ export interface InputCalendarTriggerViewProps extends InputCalendarTriggerProps
90
134
  * @property {boolean} [disabled] disabled 여부
91
135
  * @property {boolean} [readOnly] readOnly 여부
92
136
  * @property {(event: MouseEvent<Element>) => void} [onClick] 트리거 클릭 핸들러
93
- * @property {InputPriority} [priority] trigger input priority
94
- * @property {InputState} [state] trigger input state
137
+ * @property {"primary" | "secondary" | "tertiary" | "table"} [priority] trigger input priority
138
+ * @property {"small" | "medium" | "large"} [size] trigger input size
139
+ * @property {"default" | "active" | "focused" | "success" | "error" | "disabled" | "loading"} [state] trigger input state
140
+ * @property {boolean} [block] trigger width 100% 여부
141
+ * @property {"full" | "fit" | "fill" | "auto" | number | string} [width] trigger width preset 또는 custom width
142
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [onFocus] trigger focus 핸들러
143
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [onBlur] trigger blur 핸들러
144
+ * @desc custom Date trigger에 전달하는 표시·상호작용 계약
95
145
  */
96
146
  export interface InputCalendarTriggerRenderProps {
97
147
  /**
@@ -127,57 +177,92 @@ export interface InputCalendarTriggerRenderProps {
127
177
  * - table일 때 Trigger는 left icon 배치를 사용한다.
128
178
  */
129
179
  priority?: InputPriority;
180
+ /**
181
+ * "small" | "medium" | "large".
182
+ */
183
+ size?: InputSize;
130
184
  /**
131
185
  * trigger input state
132
186
  */
133
187
  state?: InputState;
188
+ /**
189
+ * trigger width 100% 여부.
190
+ */
191
+ block?: boolean;
192
+ /**
193
+ * "full" | "fit" | "fill" | "auto" | number | string.
194
+ */
195
+ width?: FormFieldWidth;
196
+ /**
197
+ * trigger focus 핸들러.
198
+ */
199
+ onFocus?: (event: FocusEvent<HTMLInputElement>) => void;
200
+ /**
201
+ * trigger blur 핸들러.
202
+ */
203
+ onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
134
204
  }
135
205
 
136
206
  /**
137
207
  * Input Calendar core props.
138
- * @property {CalendarMode} [mode="date"] 날짜/시간 모드
139
- * @property {CalendarColumns} [columns=1] 동시에 노출할 달력 열 수
140
- * @property {CalendarValue} [value] 제어형 값
141
- * @property {CalendarValue} [defaultValue] 비제어 초기값
142
- * @property {CalendarOnChange} [onChange] 값 변경 핸들러(직렬화 문자열 기준)
143
- * @property {CalendarOnChange} [onValueChange] onChange 별칭(추가 파이프라인용)
208
+ * @property {"date" | "date-time" | "time"} [mode="date"] Calendar layout mode. 선택 body는 date로 유지된다.
209
+ * @property {1 | 2} [columns=1] 동시에 노출할 달력 열 수
210
+ * @property {string | null} [value] 제어형 값
211
+ * @property {string | null} [defaultValue] 비제어 초기값
212
+ * @property {(value: string | null) => void} [onChange] 값 변경 핸들러(직렬화 문자열 기준)
213
+ * @property {(value: string | null) => void} [onValueChange] onChange 별칭(추가 파이프라인용)
144
214
  * @property {boolean} [readOnly] 읽기 전용 여부
145
215
  * @property {boolean} [disabled] disabled 여부
146
216
  * @property {CalendarDatePickerProps} [datePickerProps] Mantine DatePicker 직접 옵션
147
- * @property {InputPriority} [priority] trigger input priority
148
- * @property {InputState} [state] trigger input state
217
+ * @property {string} [id] trigger id
218
+ * @property {string} [name] hidden input form name
219
+ * @property {UseFormRegisterReturn} [register] hidden input react-hook-form register 결과
220
+ * @property {string} [placeholder] trigger 내부 placeholder
221
+ * @property {(event: MouseEvent<Element>) => void} [onClick] trigger 클릭 핸들러
222
+ * @property {"primary" | "secondary" | "tertiary" | "table"} [priority] trigger input priority
223
+ * @property {"small" | "medium" | "large"} [size] trigger input size
224
+ * @property {"default" | "active" | "focused" | "success" | "error" | "disabled" | "loading"} [state] trigger input state
225
+ * @property {boolean} [block] trigger width 100% 여부
226
+ * @property {"full" | "fit" | "fill" | "auto" | number | string} [width] trigger width preset 또는 custom width
227
+ * @property {string} [form] hidden input이 연결될 form id
228
+ * @property {boolean} [required] hidden input required 여부
229
+ * @property {InputCalendarHiddenInputProps} [hiddenInputProps] Template 고정값을 제외한 hidden input native props
230
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [onFocus] trigger focus 핸들러
231
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [onBlur] trigger blur 핸들러와 RHF touched 동기화 진입점
149
232
  * @property {ReactNode} [header] 커스텀 header 콘텐츠
150
233
  * @property {ReactNode} [footer] 커스텀 footer 콘텐츠
151
234
  * @property {InputCalendarTexts} [texts] 기본 Date 문구
152
- * @property {unknown} [timePicker] TimePicker 확장용 예약 슬롯(현재 미구현)
235
+ * @property {unknown} [timePicker] 미구현 compatibility prop. 시간 선택에는 Input.Time.Template을 사용한다.
153
236
  * @property {boolean} [calendarOpened] calendar 열림 제어 여부
154
237
  * @property {(open: boolean) => void} [onCalendarOpen] calendar 열림 변경 이벤트
155
238
  * @property {ReactNode} [trigger] 커스텀 trigger 슬롯
156
239
  * @property {(props: InputCalendarTriggerRenderProps) => ReactNode} [renderTrigger] 커스텀 trigger 렌더 함수
240
+ * @desc 단일 날짜 trigger, Calendar와 hidden form storage를 조합하는 공개 계약
157
241
  */
158
242
  export interface InputCalendarProps extends InputCalendarTriggerProps {
159
243
  /**
160
- * 날짜/시간 모드
244
+ * "date" | "date-time" | "time".
245
+ * Calendar layout의 data-mode만 지정하며 선택 body는 date로 유지된다.
161
246
  */
162
247
  mode?: CalendarMode;
163
248
  /**
164
- * 동시에 노출할 달력 열 수
249
+ * 1 | 2.
165
250
  */
166
251
  columns?: CalendarColumns;
167
252
  /**
168
- * 제어형
253
+ * string | null.
169
254
  */
170
255
  value?: CalendarValue;
171
256
  /**
172
- * 비제어 초기값
257
+ * string | null.
173
258
  */
174
259
  defaultValue?: CalendarValue;
175
260
  /**
176
- * 변경 핸들러
261
+ * (value: string | null) => void.
177
262
  */
178
263
  onChange?: CalendarOnChange;
179
264
  /**
180
- * onChange 별칭; 외부 파이프라인 시 사용
265
+ * (value: string | null) => void. onChange 별칭으로 외부 파이프라인에 사용한다.
181
266
  */
182
267
  onValueChange?: CalendarOnChange;
183
268
  /**
@@ -205,8 +290,8 @@ export interface InputCalendarProps extends InputCalendarTriggerProps {
205
290
  */
206
291
  texts?: InputCalendarTexts;
207
292
  /**
208
- * TimePicker 확장용 예약 슬롯(현재 미구현).
209
- * 추후 Calendar Body 조합 확장 시점에 구체 타입을 확정한다.
293
+ * TimePicker 확장용 미구현 compatibility prop.
294
+ * @deprecated 시간 선택에는 Input.Time.Template을 사용한다.
210
295
  */
211
296
  timePicker?: unknown;
212
297
  /**
@@ -226,14 +311,26 @@ export interface InputCalendarProps extends InputCalendarTriggerProps {
226
311
  * 커스텀 trigger 렌더 함수
227
312
  */
228
313
  renderTrigger?: (props: InputCalendarTriggerRenderProps) => ReactNode;
314
+ /**
315
+ * hidden input이 연결될 form id.
316
+ */
317
+ form?: string;
318
+ /**
319
+ * hidden input required 여부.
320
+ */
321
+ required?: boolean;
322
+ /**
323
+ * Template 고정값을 제외한 hidden input native props.
324
+ */
325
+ hiddenInputProps?: InputCalendarHiddenInputProps;
229
326
  }
230
327
 
231
328
  /**
232
329
  * Input Calendar Range Template props.
233
- * @property {CalendarRangeValue} [value] 제어형 range 값
234
- * @property {CalendarRangeValue} [defaultValue] 비제어 range 초기값
235
- * @property {CalendarRangeOnChange} [onChange] range 값 변경 핸들러
236
- * @property {CalendarRangeOnChange} [onValueChange] onChange 별칭
330
+ * @property {[string | null, string | null]} [value] 제어형 range 값
331
+ * @property {[string | null, string | null]} [defaultValue] 비제어 range 초기값
332
+ * @property {(value: [string | null, string | null]) => void} [onChange] range 값 변경 핸들러
333
+ * @property {(value: [string | null, string | null]) => void} [onValueChange] onChange 별칭
237
334
  * @property {boolean} [readOnly] 읽기 전용 여부
238
335
  * @property {boolean} [disabled] disabled 여부
239
336
  * @property {CalendarRangeDatePickerProps} [datePickerProps] Mantine range DatePicker 옵션
@@ -242,8 +339,17 @@ export interface InputCalendarProps extends InputCalendarTriggerProps {
242
339
  * @property {UseFormRegisterReturn} [startRegister] 시작일 react-hook-form register 결과
243
340
  * @property {UseFormRegisterReturn} [endRegister] 종료일 react-hook-form register 결과
244
341
  * @property {string} [placeholder] trigger 내부 placeholder
245
- * @property {InputPriority} [priority] trigger input priority
246
- * @property {InputState} [state] trigger input state
342
+ * @property {"primary" | "secondary" | "tertiary" | "table"} [priority] trigger input priority
343
+ * @property {"small" | "medium" | "large"} [size] trigger input size
344
+ * @property {"default" | "active" | "focused" | "success" | "error" | "disabled" | "loading"} [state] trigger input state
345
+ * @property {boolean} [block] trigger width 100% 여부
346
+ * @property {"full" | "fit" | "fill" | "auto" | number | string} [width] trigger width preset 또는 custom width
347
+ * @property {string} [form] start/end hidden input이 연결될 공통 form id
348
+ * @property {boolean} [required] start/end hidden input required 여부
349
+ * @property {InputCalendarHiddenInputProps} [startHiddenInputProps] 시작일 hidden input native props
350
+ * @property {InputCalendarHiddenInputProps} [endHiddenInputProps] 종료일 hidden input native props
351
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [onFocus] trigger focus 핸들러
352
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [onBlur] trigger blur 핸들러와 RHF touched 동기화 진입점
247
353
  * @property {ReactNode} [header] 커스텀 header 콘텐츠
248
354
  * @property {ReactNode} [footer] 커스텀 footer 콘텐츠
249
355
  * @property {InputCalendarTexts} [texts] 기본 Date 문구
@@ -253,22 +359,23 @@ export interface InputCalendarProps extends InputCalendarTriggerProps {
253
359
  * @property {ReactNode} [trigger] 커스텀 trigger 슬롯
254
360
  * @property {(props: InputCalendarTriggerRenderProps) => ReactNode} [renderTrigger] 커스텀 trigger 렌더 함수
255
361
  * @property {(event: MouseEvent<Element>) => void} [onClick] trigger 클릭 핸들러
362
+ * @desc 기간 trigger, Calendar.Range와 start/end hidden form storage를 조합하는 공개 계약
256
363
  */
257
364
  export interface InputCalendarRangeProps {
258
365
  /**
259
- * 제어형 range
366
+ * [string | null, string | null].
260
367
  */
261
368
  value?: CalendarRangeValue;
262
369
  /**
263
- * 비제어 range 초기값
370
+ * [string | null, string | null].
264
371
  */
265
372
  defaultValue?: CalendarRangeValue;
266
373
  /**
267
- * range 변경 핸들러
374
+ * (value: [string | null, string | null]) => void.
268
375
  */
269
376
  onChange?: CalendarRangeOnChange;
270
377
  /**
271
- * onChange 별칭; 외부 파이프라인 시 사용
378
+ * (value: [string | null, string | null]) => void. onChange 별칭으로 외부 파이프라인에 사용한다.
272
379
  */
273
380
  onValueChange?: CalendarRangeOnChange;
274
381
  /**
@@ -308,10 +415,46 @@ export interface InputCalendarRangeProps {
308
415
  * - table일 때 Trigger는 left icon 배치를 사용한다.
309
416
  */
310
417
  priority?: InputPriority;
418
+ /**
419
+ * "small" | "medium" | "large".
420
+ */
421
+ size?: InputSize;
311
422
  /**
312
423
  * trigger input state
313
424
  */
314
425
  state?: InputState;
426
+ /**
427
+ * trigger width 100% 여부.
428
+ */
429
+ block?: boolean;
430
+ /**
431
+ * "full" | "fit" | "fill" | "auto" | number | string.
432
+ */
433
+ width?: FormFieldWidth;
434
+ /**
435
+ * start/end hidden input이 연결될 공통 form id.
436
+ */
437
+ form?: string;
438
+ /**
439
+ * start/end hidden input required 여부.
440
+ */
441
+ required?: boolean;
442
+ /**
443
+ * 시작일 hidden input native props.
444
+ */
445
+ startHiddenInputProps?: InputCalendarHiddenInputProps;
446
+ /**
447
+ * 종료일 hidden input native props.
448
+ */
449
+ endHiddenInputProps?: InputCalendarHiddenInputProps;
450
+ /**
451
+ * trigger focus 핸들러.
452
+ */
453
+ onFocus?: (event: FocusEvent<HTMLInputElement>) => void;
454
+ /**
455
+ * trigger blur 핸들러.
456
+ */
457
+ onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
315
458
  /**
316
459
  * 커스텀 header 콘텐츠
317
460
  */
@@ -21,6 +21,8 @@ export type InputTimeIconPosition = "left" | "right";
21
21
 
22
22
  /**
23
23
  * Input Time hidden input props.
24
+ * @typedef {Omit<ComponentPropsWithoutRef<"input">, "type" | "value" | "defaultValue" | "name">} InputTimeHiddenInputProps
25
+ * @desc Template이 고정하는 type, value, defaultValue와 name을 제외한 native hidden input 계약
24
26
  */
25
27
  export type InputTimeHiddenInputProps = Omit<
26
28
  ComponentPropsWithoutRef<"input">,
@@ -32,6 +34,7 @@ export type InputTimeHiddenInputProps = Omit<
32
34
  * @property {string} hours 시 입력값
33
35
  * @property {string} minutes 분 입력값
34
36
  * @property {string} seconds 초 입력값
37
+ * @desc 입력 field에 표시하는 시·분·초 draft 문자열
35
38
  */
36
39
  export interface InputTimeDraftFields {
37
40
  /**
@@ -52,6 +55,7 @@ export interface InputTimeDraftFields {
52
55
  * Input Time 편집 중인 시간 값.
53
56
  * @property {InputTimeDraftFields} fields 시·분·초 입력값
54
57
  * @property {"am" | "pm"} period 오전·오후 구분
58
+ * @desc 저장값 commit 전의 field 문자열과 12시간제 period 상태
55
59
  */
56
60
  export interface InputTimeDraft {
57
61
  /**
@@ -99,6 +103,7 @@ export type InputTimeTriggerFields = InputTimeDraftFields;
99
103
  * @property {(period: "am" | "pm") => void} onPeriodChange 오전·오후 변경 핸들러
100
104
  * @property {(amount: 1 | -1) => void} onStep 활성 단위 증감 핸들러
101
105
  * @property {(event: FocusEvent<HTMLDivElement>) => void} onRootBlur root blur 핸들러
106
+ * @desc 시·분·초 field, period, stepper와 clock action을 렌더링하기 위한 trigger 계약
102
107
  */
103
108
  export interface InputTimeTriggerProps extends Omit<
104
109
  ComponentPropsWithoutRef<"div">,
@@ -225,8 +230,8 @@ export interface InputTimeTriggerProps extends Omit<
225
230
  * 저장값은 24시간 `HH:mm` 또는 `HH:mm:ss` 문자열을 사용한다.
226
231
  * @property {string} [value] 제어형 시간 값
227
232
  * @property {string} [defaultValue] 비제어 초기 시간 값
228
- * @property {(value:string)=>void} [onChange] 값 변경 핸들러
229
- * @property {(value:string)=>void} [onValueChange] 값 변경 별칭
233
+ * @property {(value: string) => void} [onChange] 값 변경 핸들러
234
+ * @property {(value: string) => void} [onValueChange] 값 변경 별칭
230
235
  * @property {string} [name] form name
231
236
  * @property {string} [form] form id
232
237
  * @property {UseFormRegisterReturn} [register] react-hook-form register 결과
@@ -257,8 +262,9 @@ export interface InputTimeTriggerProps extends Omit<
257
262
  * @property {string} [hoursPlaceholder] 시 placeholder
258
263
  * @property {string} [minutesPlaceholder] 분 placeholder
259
264
  * @property {string} [secondsPlaceholder] 초 placeholder
260
- * @property {(event:FocusEvent<HTMLInputElement>)=>void} [onFocus] focus 핸들러
261
- * @property {(event:FocusEvent<HTMLDivElement>)=>void} [onBlur] blur 핸들러
265
+ * @property {(event: FocusEvent<HTMLInputElement>) => void} [onFocus] focus 핸들러
266
+ * @property {(event: FocusEvent<HTMLDivElement>) => void} [onBlur] blur 핸들러
267
+ * @desc 시간 trigger, TimePicker panel과 24시간 문자열 hidden form storage를 조합하는 공개 계약
262
268
  */
263
269
  export interface InputTimeTemplateProps {
264
270
  /**