@uniai-fe/uds-primitives 0.11.0 → 0.12.1
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.
- package/README.md +38 -453
- package/dist/styles.css +370 -327
- package/package.json +2 -2
- package/src/components/input/index.tsx +1 -1
- package/src/components/input/markup/time/Template.tsx +412 -0
- package/src/components/input/markup/time/Trigger.tsx +233 -0
- package/src/components/input/markup/time/index.tsx +9 -2
- package/src/components/input/styles/time.scss +160 -317
- package/src/components/input/styles/variables.scss +9 -47
- package/src/components/input/types/time.ts +263 -120
- package/src/components/time-picker/img/minus.svg +3 -0
- package/src/components/time-picker/img/plus.svg +3 -0
- package/src/components/time-picker/index.scss +1 -0
- package/src/components/time-picker/index.tsx +11 -0
- package/src/components/time-picker/markup/Footer.tsx +53 -0
- package/src/components/time-picker/markup/HourSection.tsx +72 -0
- package/src/components/time-picker/markup/MinuteSection.tsx +68 -0
- package/src/components/time-picker/markup/Summary.tsx +19 -0
- package/src/components/time-picker/markup/Template.tsx +86 -0
- package/src/components/time-picker/markup/index.tsx +10 -0
- package/src/components/time-picker/styles/index.scss +2 -0
- package/src/components/time-picker/styles/template.scss +174 -0
- package/src/components/time-picker/styles/variables.scss +64 -0
- package/src/components/time-picker/types/index.ts +1 -0
- package/src/components/time-picker/types/time-picker.ts +193 -0
- package/src/components/time-picker/utils/index.ts +1 -0
- package/src/components/time-picker/utils/time.ts +110 -0
- package/src/index.scss +1 -0
- package/src/index.tsx +1 -0
- package/src/components/input/markup/time/Picker.tsx +0 -378
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
import type { PopoverProps, ScrollAreaProps } from "@mantine/core";
|
|
2
1
|
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "
|
|
8
|
-
import type { ComponentPropsWithoutRef, FocusEvent, ReactNode } from "react";
|
|
2
|
+
ComponentPropsWithoutRef,
|
|
3
|
+
FocusEvent,
|
|
4
|
+
KeyboardEvent,
|
|
5
|
+
ReactNode,
|
|
6
|
+
} from "react";
|
|
9
7
|
import type { UseFormRegisterReturn } from "react-hook-form";
|
|
10
8
|
import type { FormFieldWidth } from "../../form/types/props";
|
|
9
|
+
import type {
|
|
10
|
+
TimePickerFormat,
|
|
11
|
+
TimePickerPeriod,
|
|
12
|
+
TimePickerUnit,
|
|
13
|
+
} from "../../time-picker/types";
|
|
11
14
|
import type { InputPriority, InputSize, InputState } from "./foundation";
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
|
-
* Input Time icon
|
|
17
|
+
* Input Time icon 위치.
|
|
18
|
+
* @typedef {"left" | "right"} InputTimeIconPosition
|
|
15
19
|
*/
|
|
16
20
|
export type InputTimeIconPosition = "left" | "right";
|
|
17
21
|
|
|
18
22
|
/**
|
|
19
|
-
* Input
|
|
23
|
+
* Input Time hidden input props.
|
|
20
24
|
*/
|
|
21
25
|
export type InputTimeHiddenInputProps = Omit<
|
|
22
26
|
ComponentPropsWithoutRef<"input">,
|
|
@@ -24,7 +28,201 @@ export type InputTimeHiddenInputProps = Omit<
|
|
|
24
28
|
>;
|
|
25
29
|
|
|
26
30
|
/**
|
|
27
|
-
* Input
|
|
31
|
+
* Input Time draft field 값.
|
|
32
|
+
* @property {string} hours 시 입력값
|
|
33
|
+
* @property {string} minutes 분 입력값
|
|
34
|
+
* @property {string} seconds 초 입력값
|
|
35
|
+
*/
|
|
36
|
+
export interface InputTimeDraftFields {
|
|
37
|
+
/**
|
|
38
|
+
* 시 입력값.
|
|
39
|
+
*/
|
|
40
|
+
hours: string;
|
|
41
|
+
/**
|
|
42
|
+
* 분 입력값.
|
|
43
|
+
*/
|
|
44
|
+
minutes: string;
|
|
45
|
+
/**
|
|
46
|
+
* 초 입력값.
|
|
47
|
+
*/
|
|
48
|
+
seconds: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Input Time 편집 중인 시간 값.
|
|
53
|
+
* @property {InputTimeDraftFields} fields 시·분·초 입력값
|
|
54
|
+
* @property {"am" | "pm"} period 오전·오후 구분
|
|
55
|
+
*/
|
|
56
|
+
export interface InputTimeDraft {
|
|
57
|
+
/**
|
|
58
|
+
* 시·분·초 입력값.
|
|
59
|
+
*/
|
|
60
|
+
fields: InputTimeDraftFields;
|
|
61
|
+
/**
|
|
62
|
+
* "am" | "pm".
|
|
63
|
+
*/
|
|
64
|
+
period: TimePickerPeriod;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Input Time trigger field 값.
|
|
69
|
+
* @see InputTimeDraftFields
|
|
70
|
+
*/
|
|
71
|
+
export type InputTimeTriggerFields = InputTimeDraftFields;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Input Time Trigger props.
|
|
75
|
+
* @property {InputTimeTriggerFields} fields 시·분·초 입력값
|
|
76
|
+
* @property {"am" | "pm"} period 오전·오후 구분
|
|
77
|
+
* @property {"hours" | "minutes" | "seconds" | null} activeUnit 현재 활성 단위
|
|
78
|
+
* @property {"primary" | "secondary" | "tertiary" | "table"} priority input priority
|
|
79
|
+
* @property {"small" | "medium" | "large"} size input size
|
|
80
|
+
* @property {"default" | "active" | "focused" | "success" | "error" | "disabled" | "loading"} state input state
|
|
81
|
+
* @property {"12h" | "24h"} format 표시 형식
|
|
82
|
+
* @property {boolean} withSeconds 초 field 노출 여부
|
|
83
|
+
* @property {boolean} disabled 비활성화 여부
|
|
84
|
+
* @property {boolean} readOnly 읽기 전용 여부
|
|
85
|
+
* @property {ReactNode} icon clock icon
|
|
86
|
+
* @property {"left" | "right"} iconPosition clock icon 위치
|
|
87
|
+
* @property {string} iconLabel clock icon 접근성 라벨
|
|
88
|
+
* @property {string} hoursInputLabel 시 input 접근성 라벨
|
|
89
|
+
* @property {string} minutesInputLabel 분 input 접근성 라벨
|
|
90
|
+
* @property {string} secondsInputLabel 초 input 접근성 라벨
|
|
91
|
+
* @property {string} amPmInputLabel 오전·오후 input 접근성 라벨
|
|
92
|
+
* @property {string} hoursPlaceholder 시 placeholder
|
|
93
|
+
* @property {string} minutesPlaceholder 분 placeholder
|
|
94
|
+
* @property {string} secondsPlaceholder 초 placeholder
|
|
95
|
+
* @property {(unit: "hours" | "minutes" | "seconds", value: string) => void} onFieldChange field 변경 핸들러
|
|
96
|
+
* @property {(unit: "hours" | "minutes" | "seconds", event: FocusEvent<HTMLInputElement>) => void} onFieldFocus field focus 핸들러
|
|
97
|
+
* @property {(unit: "hours" | "minutes" | "seconds") => void} onFieldBlur field blur 핸들러
|
|
98
|
+
* @property {(unit: "hours" | "minutes" | "seconds", event: KeyboardEvent<HTMLInputElement>) => void} onFieldKeyDown field keyboard 핸들러
|
|
99
|
+
* @property {(period: "am" | "pm") => void} onPeriodChange 오전·오후 변경 핸들러
|
|
100
|
+
* @property {(amount: 1 | -1) => void} onStep 활성 단위 증감 핸들러
|
|
101
|
+
* @property {(event: FocusEvent<HTMLDivElement>) => void} onRootBlur root blur 핸들러
|
|
102
|
+
*/
|
|
103
|
+
export interface InputTimeTriggerProps extends Omit<
|
|
104
|
+
ComponentPropsWithoutRef<"div">,
|
|
105
|
+
"onBlur" | "onFocus"
|
|
106
|
+
> {
|
|
107
|
+
/**
|
|
108
|
+
* 시·분·초 입력값.
|
|
109
|
+
*/
|
|
110
|
+
fields: InputTimeTriggerFields;
|
|
111
|
+
/**
|
|
112
|
+
* "am" | "pm".
|
|
113
|
+
*/
|
|
114
|
+
period: TimePickerPeriod;
|
|
115
|
+
/**
|
|
116
|
+
* "hours" | "minutes" | "seconds" | null.
|
|
117
|
+
*/
|
|
118
|
+
activeUnit: TimePickerUnit | null;
|
|
119
|
+
/**
|
|
120
|
+
* "primary" | "secondary" | "tertiary" | "table".
|
|
121
|
+
*/
|
|
122
|
+
priority: InputPriority;
|
|
123
|
+
/**
|
|
124
|
+
* "small" | "medium" | "large".
|
|
125
|
+
*/
|
|
126
|
+
size: InputSize;
|
|
127
|
+
/**
|
|
128
|
+
* "default" | "active" | "focused" | "success" | "error" | "disabled" | "loading".
|
|
129
|
+
*/
|
|
130
|
+
state: InputState;
|
|
131
|
+
/**
|
|
132
|
+
* "12h" | "24h".
|
|
133
|
+
*/
|
|
134
|
+
format: TimePickerFormat;
|
|
135
|
+
/**
|
|
136
|
+
* 초 field 노출 여부.
|
|
137
|
+
*/
|
|
138
|
+
withSeconds: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* 비활성화 여부.
|
|
141
|
+
*/
|
|
142
|
+
disabled: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* 읽기 전용 여부.
|
|
145
|
+
*/
|
|
146
|
+
readOnly: boolean;
|
|
147
|
+
/**
|
|
148
|
+
* clock icon.
|
|
149
|
+
*/
|
|
150
|
+
icon: ReactNode;
|
|
151
|
+
/**
|
|
152
|
+
* "left" | "right".
|
|
153
|
+
*/
|
|
154
|
+
iconPosition: InputTimeIconPosition;
|
|
155
|
+
/**
|
|
156
|
+
* clock icon 접근성 라벨.
|
|
157
|
+
*/
|
|
158
|
+
iconLabel: string;
|
|
159
|
+
/**
|
|
160
|
+
* 시 input 접근성 라벨.
|
|
161
|
+
*/
|
|
162
|
+
hoursInputLabel: string;
|
|
163
|
+
/**
|
|
164
|
+
* 분 input 접근성 라벨.
|
|
165
|
+
*/
|
|
166
|
+
minutesInputLabel: string;
|
|
167
|
+
/**
|
|
168
|
+
* 초 input 접근성 라벨.
|
|
169
|
+
*/
|
|
170
|
+
secondsInputLabel: string;
|
|
171
|
+
/**
|
|
172
|
+
* 오전·오후 input 접근성 라벨.
|
|
173
|
+
*/
|
|
174
|
+
amPmInputLabel: string;
|
|
175
|
+
/**
|
|
176
|
+
* 시 placeholder.
|
|
177
|
+
*/
|
|
178
|
+
hoursPlaceholder: string;
|
|
179
|
+
/**
|
|
180
|
+
* 분 placeholder.
|
|
181
|
+
*/
|
|
182
|
+
minutesPlaceholder: string;
|
|
183
|
+
/**
|
|
184
|
+
* 초 placeholder.
|
|
185
|
+
*/
|
|
186
|
+
secondsPlaceholder: string;
|
|
187
|
+
/**
|
|
188
|
+
* field 변경 핸들러.
|
|
189
|
+
*/
|
|
190
|
+
onFieldChange: (unit: TimePickerUnit, value: string) => void;
|
|
191
|
+
/**
|
|
192
|
+
* field focus 핸들러.
|
|
193
|
+
*/
|
|
194
|
+
onFieldFocus: (
|
|
195
|
+
unit: TimePickerUnit,
|
|
196
|
+
event: FocusEvent<HTMLInputElement>,
|
|
197
|
+
) => void;
|
|
198
|
+
/**
|
|
199
|
+
* field blur 핸들러.
|
|
200
|
+
*/
|
|
201
|
+
onFieldBlur: (unit: TimePickerUnit) => void;
|
|
202
|
+
/**
|
|
203
|
+
* field keyboard 핸들러.
|
|
204
|
+
*/
|
|
205
|
+
onFieldKeyDown: (
|
|
206
|
+
unit: TimePickerUnit,
|
|
207
|
+
event: KeyboardEvent<HTMLInputElement>,
|
|
208
|
+
) => void;
|
|
209
|
+
/**
|
|
210
|
+
* 오전·오후 변경 핸들러.
|
|
211
|
+
*/
|
|
212
|
+
onPeriodChange: (period: TimePickerPeriod) => void;
|
|
213
|
+
/**
|
|
214
|
+
* 활성 단위 증감 핸들러.
|
|
215
|
+
*/
|
|
216
|
+
onStep: (amount: 1 | -1) => void;
|
|
217
|
+
/**
|
|
218
|
+
* root blur 핸들러.
|
|
219
|
+
*/
|
|
220
|
+
onRootBlur: (event: FocusEvent<HTMLDivElement>) => void;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Input Time Template props.
|
|
225
|
+
* 저장값은 24시간 `HH:mm` 또는 `HH:mm:ss` 문자열을 사용한다.
|
|
28
226
|
* @property {string} [value] 제어형 시간 값
|
|
29
227
|
* @property {string} [defaultValue] 비제어 초기 시간 값
|
|
30
228
|
* @property {(value:string)=>void} [onChange] 값 변경 핸들러
|
|
@@ -32,234 +230,179 @@ export type InputTimeHiddenInputProps = Omit<
|
|
|
32
230
|
* @property {string} [name] form name
|
|
33
231
|
* @property {string} [form] form id
|
|
34
232
|
* @property {UseFormRegisterReturn} [register] react-hook-form register 결과
|
|
35
|
-
* @property {
|
|
36
|
-
* @property {
|
|
37
|
-
* @property {
|
|
233
|
+
* @property {"primary" | "secondary" | "tertiary" | "table"} [priority] input priority
|
|
234
|
+
* @property {"small" | "medium" | "large"} [size] input size
|
|
235
|
+
* @property {"default" | "active" | "focused" | "success" | "error" | "disabled" | "loading"} [state] input state
|
|
38
236
|
* @property {boolean} [block] width 100% 여부
|
|
39
|
-
* @property {"full" | "fit" | "fill" | "auto" | number | string} [width] width preset
|
|
237
|
+
* @property {"full" | "fit" | "fill" | "auto" | number | string} [width] width preset
|
|
40
238
|
* @property {string} [className] root className
|
|
41
239
|
* @property {boolean} [disabled] disabled 여부
|
|
42
240
|
* @property {boolean} [readOnly] readOnly 여부
|
|
43
241
|
* @property {boolean} [required] required 여부
|
|
44
242
|
* @property {string} [id] root id
|
|
45
|
-
* @property {"12h" | "24h"} [format]
|
|
46
|
-
* @property {boolean} [withSeconds]
|
|
47
|
-
* @property {boolean} [
|
|
48
|
-
* @property {
|
|
49
|
-
* @property {
|
|
50
|
-
* @property {
|
|
51
|
-
* @property {number} [hoursStep] hour step
|
|
52
|
-
* @property {number} [minutesStep] minute step
|
|
53
|
-
* @property {number} [secondsStep] second step
|
|
243
|
+
* @property {"12h" | "24h"} [format] 표시 형식
|
|
244
|
+
* @property {boolean} [withSeconds] 초 field 노출 여부
|
|
245
|
+
* @property {boolean} [clearable] 삭제 액션 노출 여부
|
|
246
|
+
* @property {number} [hoursStep] 시 증감 단위
|
|
247
|
+
* @property {number} [minutesStep] 분 증감 단위
|
|
248
|
+
* @property {number} [secondsStep] 초 증감 단위
|
|
54
249
|
* @property {ReactNode} [icon] clock icon override
|
|
55
250
|
* @property {"left" | "right"} [iconPosition] clock icon 위치
|
|
56
251
|
* @property {string} [iconLabel] clock icon 접근성 라벨
|
|
57
|
-
* @property {
|
|
58
|
-
* @property {
|
|
59
|
-
* @property {
|
|
60
|
-
* @property {string} [
|
|
61
|
-
* @property {string} [
|
|
62
|
-
* @property {string} [
|
|
63
|
-
* @property {string} [
|
|
64
|
-
* @property {
|
|
65
|
-
* @property {string} [hoursPlaceholder] hour placeholder
|
|
66
|
-
* @property {string} [minutesPlaceholder] minute placeholder
|
|
67
|
-
* @property {string} [secondsPlaceholder] second placeholder
|
|
68
|
-
* @property {TimePickerPasteSplit} [pasteSplit] paste parser
|
|
69
|
-
* @property {TimePickerPresets} [presets] dropdown preset
|
|
70
|
-
* @property {number} [maxDropdownContentHeight] dropdown 최대 높이
|
|
71
|
-
* @property {ScrollAreaProps} [scrollAreaProps] dropdown scroll area 옵션
|
|
72
|
-
* @property {boolean} [reverseTimeControlsList] dropdown control 역순 여부
|
|
252
|
+
* @property {InputTimeHiddenInputProps} [hiddenInputProps] hidden input props
|
|
253
|
+
* @property {string} [hoursInputLabel] 시 input 접근성 라벨
|
|
254
|
+
* @property {string} [minutesInputLabel] 분 input 접근성 라벨
|
|
255
|
+
* @property {string} [secondsInputLabel] 초 input 접근성 라벨
|
|
256
|
+
* @property {string} [amPmInputLabel] 오전/오후 접근성 라벨
|
|
257
|
+
* @property {string} [hoursPlaceholder] 시 placeholder
|
|
258
|
+
* @property {string} [minutesPlaceholder] 분 placeholder
|
|
259
|
+
* @property {string} [secondsPlaceholder] 초 placeholder
|
|
73
260
|
* @property {(event:FocusEvent<HTMLInputElement>)=>void} [onFocus] focus 핸들러
|
|
74
261
|
* @property {(event:FocusEvent<HTMLDivElement>)=>void} [onBlur] blur 핸들러
|
|
75
262
|
*/
|
|
76
|
-
export interface
|
|
263
|
+
export interface InputTimeTemplateProps {
|
|
77
264
|
/**
|
|
78
|
-
* 제어형 시간
|
|
265
|
+
* 제어형 시간 값.
|
|
79
266
|
*/
|
|
80
267
|
value?: string;
|
|
81
268
|
/**
|
|
82
|
-
* 비제어 초기 시간
|
|
269
|
+
* 비제어 초기 시간 값.
|
|
83
270
|
*/
|
|
84
271
|
defaultValue?: string;
|
|
85
272
|
/**
|
|
86
|
-
* 값 변경
|
|
273
|
+
* 값 변경 핸들러.
|
|
87
274
|
*/
|
|
88
275
|
onChange?: (value: string) => void;
|
|
89
276
|
/**
|
|
90
|
-
* 값 변경
|
|
277
|
+
* 값 변경 별칭.
|
|
91
278
|
*/
|
|
92
279
|
onValueChange?: (value: string) => void;
|
|
93
280
|
/**
|
|
94
|
-
* form name
|
|
281
|
+
* form name.
|
|
95
282
|
*/
|
|
96
283
|
name?: string;
|
|
97
284
|
/**
|
|
98
|
-
* form id
|
|
285
|
+
* form id.
|
|
99
286
|
*/
|
|
100
287
|
form?: string;
|
|
101
288
|
/**
|
|
102
|
-
* react-hook-form register
|
|
289
|
+
* react-hook-form register 결과.
|
|
103
290
|
*/
|
|
104
291
|
register?: UseFormRegisterReturn;
|
|
105
292
|
/**
|
|
106
|
-
*
|
|
293
|
+
* "primary" | "secondary" | "tertiary" | "table".
|
|
107
294
|
*/
|
|
108
295
|
priority?: InputPriority;
|
|
109
296
|
/**
|
|
110
|
-
*
|
|
297
|
+
* "small" | "medium" | "large".
|
|
111
298
|
*/
|
|
112
299
|
size?: InputSize;
|
|
113
300
|
/**
|
|
114
|
-
*
|
|
301
|
+
* "default" | "active" | "focused" | "success" | "error" | "disabled" | "loading".
|
|
115
302
|
*/
|
|
116
303
|
state?: InputState;
|
|
117
304
|
/**
|
|
118
|
-
* width 100%
|
|
305
|
+
* width 100% 여부.
|
|
119
306
|
*/
|
|
120
307
|
block?: boolean;
|
|
121
308
|
/**
|
|
122
|
-
*
|
|
309
|
+
* "full" | "fit" | "fill" | "auto" | number | string.
|
|
123
310
|
*/
|
|
124
311
|
width?: FormFieldWidth;
|
|
125
312
|
/**
|
|
126
|
-
* root className
|
|
313
|
+
* root className.
|
|
127
314
|
*/
|
|
128
315
|
className?: string;
|
|
129
316
|
/**
|
|
130
|
-
* disabled
|
|
317
|
+
* disabled 여부.
|
|
131
318
|
*/
|
|
132
319
|
disabled?: boolean;
|
|
133
320
|
/**
|
|
134
|
-
* readOnly
|
|
321
|
+
* readOnly 여부.
|
|
135
322
|
*/
|
|
136
323
|
readOnly?: boolean;
|
|
137
324
|
/**
|
|
138
|
-
* required
|
|
325
|
+
* required 여부.
|
|
139
326
|
*/
|
|
140
327
|
required?: boolean;
|
|
141
328
|
/**
|
|
142
|
-
* root id
|
|
329
|
+
* root id.
|
|
143
330
|
*/
|
|
144
331
|
id?: string;
|
|
145
332
|
/**
|
|
146
|
-
*
|
|
333
|
+
* "12h" | "24h".
|
|
147
334
|
*/
|
|
148
335
|
format?: TimePickerFormat;
|
|
149
336
|
/**
|
|
150
|
-
*
|
|
337
|
+
* 초 field 노출 여부.
|
|
151
338
|
*/
|
|
152
339
|
withSeconds?: boolean;
|
|
153
340
|
/**
|
|
154
|
-
*
|
|
155
|
-
*/
|
|
156
|
-
withDropdown?: boolean;
|
|
157
|
-
/**
|
|
158
|
-
* clear 버튼 노출 여부
|
|
341
|
+
* 삭제 액션 노출 여부.
|
|
159
342
|
*/
|
|
160
343
|
clearable?: boolean;
|
|
161
344
|
/**
|
|
162
|
-
*
|
|
163
|
-
*/
|
|
164
|
-
min?: string;
|
|
165
|
-
/**
|
|
166
|
-
* 최대 시간 값
|
|
167
|
-
*/
|
|
168
|
-
max?: string;
|
|
169
|
-
/**
|
|
170
|
-
* hour step
|
|
345
|
+
* 시 증감 단위.
|
|
171
346
|
*/
|
|
172
347
|
hoursStep?: number;
|
|
173
348
|
/**
|
|
174
|
-
*
|
|
349
|
+
* 분 증감 단위.
|
|
175
350
|
*/
|
|
176
351
|
minutesStep?: number;
|
|
177
352
|
/**
|
|
178
|
-
*
|
|
353
|
+
* 초 증감 단위.
|
|
179
354
|
*/
|
|
180
355
|
secondsStep?: number;
|
|
181
356
|
/**
|
|
182
|
-
* clock icon override
|
|
357
|
+
* clock icon override.
|
|
183
358
|
*/
|
|
184
359
|
icon?: ReactNode;
|
|
185
360
|
/**
|
|
186
|
-
*
|
|
361
|
+
* "left" | "right".
|
|
187
362
|
*/
|
|
188
363
|
iconPosition?: InputTimeIconPosition;
|
|
189
364
|
/**
|
|
190
|
-
* clock icon 접근성
|
|
365
|
+
* clock icon 접근성 라벨.
|
|
191
366
|
*/
|
|
192
367
|
iconLabel?: string;
|
|
193
368
|
/**
|
|
194
|
-
*
|
|
195
|
-
*/
|
|
196
|
-
clearButtonLabel?: string;
|
|
197
|
-
/**
|
|
198
|
-
* Mantine Popover 옵션
|
|
199
|
-
*/
|
|
200
|
-
popoverProps?: PopoverProps;
|
|
201
|
-
/**
|
|
202
|
-
* hidden input 옵션
|
|
369
|
+
* hidden input props.
|
|
203
370
|
*/
|
|
204
371
|
hiddenInputProps?: InputTimeHiddenInputProps;
|
|
205
372
|
/**
|
|
206
|
-
*
|
|
373
|
+
* 시 input 접근성 라벨.
|
|
207
374
|
*/
|
|
208
375
|
hoursInputLabel?: string;
|
|
209
376
|
/**
|
|
210
|
-
*
|
|
377
|
+
* 분 input 접근성 라벨.
|
|
211
378
|
*/
|
|
212
379
|
minutesInputLabel?: string;
|
|
213
380
|
/**
|
|
214
|
-
*
|
|
381
|
+
* 초 input 접근성 라벨.
|
|
215
382
|
*/
|
|
216
383
|
secondsInputLabel?: string;
|
|
217
384
|
/**
|
|
218
|
-
*
|
|
385
|
+
* 오전/오후 접근성 라벨.
|
|
219
386
|
*/
|
|
220
387
|
amPmInputLabel?: string;
|
|
221
388
|
/**
|
|
222
|
-
*
|
|
223
|
-
*/
|
|
224
|
-
amPmLabels?: TimePickerAmPmLabels;
|
|
225
|
-
/**
|
|
226
|
-
* hour placeholder
|
|
389
|
+
* 시 placeholder.
|
|
227
390
|
*/
|
|
228
391
|
hoursPlaceholder?: string;
|
|
229
392
|
/**
|
|
230
|
-
*
|
|
393
|
+
* 분 placeholder.
|
|
231
394
|
*/
|
|
232
395
|
minutesPlaceholder?: string;
|
|
233
396
|
/**
|
|
234
|
-
*
|
|
397
|
+
* 초 placeholder.
|
|
235
398
|
*/
|
|
236
399
|
secondsPlaceholder?: string;
|
|
237
400
|
/**
|
|
238
|
-
*
|
|
239
|
-
*/
|
|
240
|
-
pasteSplit?: TimePickerPasteSplit;
|
|
241
|
-
/**
|
|
242
|
-
* dropdown preset
|
|
243
|
-
*/
|
|
244
|
-
presets?: TimePickerPresets;
|
|
245
|
-
/**
|
|
246
|
-
* dropdown 최대 높이
|
|
247
|
-
*/
|
|
248
|
-
maxDropdownContentHeight?: number;
|
|
249
|
-
/**
|
|
250
|
-
* dropdown scroll area 옵션
|
|
251
|
-
*/
|
|
252
|
-
scrollAreaProps?: ScrollAreaProps;
|
|
253
|
-
/**
|
|
254
|
-
* dropdown control 역순 여부
|
|
255
|
-
*/
|
|
256
|
-
reverseTimeControlsList?: boolean;
|
|
257
|
-
/**
|
|
258
|
-
* focus 핸들러
|
|
401
|
+
* focus 핸들러.
|
|
259
402
|
*/
|
|
260
403
|
onFocus?: (event: FocusEvent<HTMLInputElement>) => void;
|
|
261
404
|
/**
|
|
262
|
-
* blur
|
|
405
|
+
* blur 핸들러.
|
|
263
406
|
*/
|
|
264
407
|
onBlur?: (event: FocusEvent<HTMLDivElement>) => void;
|
|
265
408
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2ZM8 11.2002C7.55817 11.2002 7.2002 11.5582 7.2002 12C7.2002 12.4418 7.55817 12.7998 8 12.7998H16C16.4418 12.7998 16.7998 12.4418 16.7998 12C16.7998 11.5582 16.4418 11.2002 16 11.2002H8Z" fill="#3A3C46"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2ZM12 7.20508C11.5582 7.20508 11.2002 7.56306 11.2002 8.00488V11.2051H8C7.55817 11.2051 7.2002 11.5631 7.2002 12.0049C7.2002 12.4467 7.55817 12.8047 8 12.8047H11.2002V16.0049C11.2002 16.4467 11.5582 16.8047 12 16.8047C12.4418 16.8047 12.7998 16.4467 12.7998 16.0049V12.8047H16C16.4418 12.8047 16.7998 12.4467 16.7998 12.0049C16.7998 11.5631 16.4418 11.2051 16 11.2051H12.7998V8.00488C12.7998 7.56306 12.4418 7.20508 12 7.20508Z" fill="#3A3C46"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@use "./styles/index.scss";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimePicker; 시간 선택 패널 카테고리 배럴.
|
|
3
|
+
* @desc
|
|
4
|
+
* - `TimePicker.Template`: 시간·분 선택과 footer action을 제공한다.
|
|
5
|
+
* - `TimePickerUtils`: 시간 파싱·직렬화·증감 유틸리티다.
|
|
6
|
+
*/
|
|
7
|
+
import "./index.scss";
|
|
8
|
+
|
|
9
|
+
export * from "./markup";
|
|
10
|
+
export * as TimePickerUtils from "./utils";
|
|
11
|
+
export type * from "./types";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Button } from "../../button";
|
|
2
|
+
import type { TimePickerFooterProps } from "../types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* TimePicker Footer; 삭제와 적용 action을 렌더한다.
|
|
6
|
+
* @component
|
|
7
|
+
* @param {TimePickerFooterProps} props
|
|
8
|
+
* @param {boolean} props.clearable 삭제 action 노출 여부
|
|
9
|
+
* @param {boolean} props.disabled 비활성화 여부
|
|
10
|
+
* @param {() => void} props.onClear 삭제 핸들러
|
|
11
|
+
* @param {() => void} props.onApply 적용 핸들러
|
|
12
|
+
* @returns {ReactNode} TimePicker footer
|
|
13
|
+
* @example
|
|
14
|
+
* <TimePickerFooter
|
|
15
|
+
* clearable
|
|
16
|
+
* disabled={false}
|
|
17
|
+
* onClear={onClear}
|
|
18
|
+
* onApply={onApply}
|
|
19
|
+
* />
|
|
20
|
+
*/
|
|
21
|
+
export default function TimePickerFooter({
|
|
22
|
+
clearable,
|
|
23
|
+
disabled,
|
|
24
|
+
onClear,
|
|
25
|
+
onApply,
|
|
26
|
+
}: TimePickerFooterProps) {
|
|
27
|
+
return (
|
|
28
|
+
<footer className="time-picker-template-footer">
|
|
29
|
+
{clearable ? (
|
|
30
|
+
<button
|
|
31
|
+
type="button"
|
|
32
|
+
className="time-picker-clear-action"
|
|
33
|
+
disabled={disabled}
|
|
34
|
+
onClick={onClear}
|
|
35
|
+
>
|
|
36
|
+
삭제하기
|
|
37
|
+
</button>
|
|
38
|
+
) : (
|
|
39
|
+
<span />
|
|
40
|
+
)}
|
|
41
|
+
<Button.Default
|
|
42
|
+
type="button"
|
|
43
|
+
priority="primary"
|
|
44
|
+
fill="solid"
|
|
45
|
+
size="large"
|
|
46
|
+
disabled={disabled}
|
|
47
|
+
onClick={onApply}
|
|
48
|
+
>
|
|
49
|
+
적용하기
|
|
50
|
+
</Button.Default>
|
|
51
|
+
</footer>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { SegmentedControl } from "../../segmented-control";
|
|
2
|
+
import type { TimePickerHourSectionProps } from "../types";
|
|
3
|
+
|
|
4
|
+
const HOURS_12 = Array.from({ length: 12 }, (_, index) => index + 1);
|
|
5
|
+
const HOURS_24 = Array.from({ length: 24 }, (_, index) => index);
|
|
6
|
+
const PERIOD_OPTIONS = [
|
|
7
|
+
{ value: "am", label: "오전" },
|
|
8
|
+
{ value: "pm", label: "오후" },
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* TimePicker Hour Section; 오전·오후와 시 선택 grid를 렌더한다.
|
|
13
|
+
* @component
|
|
14
|
+
* @param {TimePickerHourSectionProps} props
|
|
15
|
+
* @param {"12h" | "24h"} props.format 표시 형식
|
|
16
|
+
* @param {number | null} props.selectedHour 선택한 표시 시
|
|
17
|
+
* @param {"am" | "pm"} props.period 오전·오후
|
|
18
|
+
* @param {boolean} props.disabled 비활성화 여부
|
|
19
|
+
* @param {(hours: number) => void} props.onHourSelect 시 선택 핸들러
|
|
20
|
+
* @param {(period: "am" | "pm") => void} props.onPeriodChange 오전·오후 변경 핸들러
|
|
21
|
+
* @returns {ReactNode} 시간 선택 section
|
|
22
|
+
* @example
|
|
23
|
+
* <TimePickerHourSection
|
|
24
|
+
* format="12h"
|
|
25
|
+
* selectedHour={9}
|
|
26
|
+
* period="am"
|
|
27
|
+
* disabled={false}
|
|
28
|
+
* onHourSelect={onHourSelect}
|
|
29
|
+
* onPeriodChange={onPeriodChange}
|
|
30
|
+
* />
|
|
31
|
+
*/
|
|
32
|
+
export default function TimePickerHourSection({
|
|
33
|
+
format,
|
|
34
|
+
selectedHour,
|
|
35
|
+
period,
|
|
36
|
+
disabled,
|
|
37
|
+
onHourSelect,
|
|
38
|
+
onPeriodChange,
|
|
39
|
+
}: TimePickerHourSectionProps) {
|
|
40
|
+
const hours = format === "12h" ? HOURS_12 : HOURS_24;
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<section className="time-picker-template-section">
|
|
44
|
+
<h3>시간 선택</h3>
|
|
45
|
+
{format === "12h" ? (
|
|
46
|
+
<SegmentedControl
|
|
47
|
+
className="time-picker-period-control"
|
|
48
|
+
options={PERIOD_OPTIONS}
|
|
49
|
+
ariaLabel="오전 또는 오후 선택"
|
|
50
|
+
value={period}
|
|
51
|
+
onValueChange={nextPeriod =>
|
|
52
|
+
onPeriodChange(nextPeriod === "pm" ? "pm" : "am")
|
|
53
|
+
}
|
|
54
|
+
/>
|
|
55
|
+
) : null}
|
|
56
|
+
<div className="time-picker-option-grid">
|
|
57
|
+
{hours.map(hour => (
|
|
58
|
+
<button
|
|
59
|
+
key={`time-picker/hour/${hour}`}
|
|
60
|
+
type="button"
|
|
61
|
+
className="time-picker-option"
|
|
62
|
+
aria-pressed={selectedHour === hour}
|
|
63
|
+
disabled={disabled}
|
|
64
|
+
onClick={() => onHourSelect(hour)}
|
|
65
|
+
>
|
|
66
|
+
{hour}:00
|
|
67
|
+
</button>
|
|
68
|
+
))}
|
|
69
|
+
</div>
|
|
70
|
+
</section>
|
|
71
|
+
);
|
|
72
|
+
}
|