@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
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
TimePickerFormat,
|
|
3
|
+
TimePickerParts,
|
|
4
|
+
TimePickerPeriod,
|
|
5
|
+
TimePickerUnit,
|
|
6
|
+
} from "../types";
|
|
7
|
+
|
|
8
|
+
const padTimePart = (value: number) => String(value).padStart(2, "0");
|
|
9
|
+
|
|
10
|
+
const wrapTimePart = (value: number, limit: number) =>
|
|
11
|
+
((value % limit) + limit) % limit;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* TimePicker Utility; 24시간 문자열을 시간 값으로 파싱한다.
|
|
15
|
+
* @param {string} value HH:mm 또는 HH:mm:ss 값
|
|
16
|
+
* @returns {TimePickerParts | null} 파싱 결과
|
|
17
|
+
*/
|
|
18
|
+
export const parseTimeValue = (value: string): TimePickerParts | null => {
|
|
19
|
+
const match = /^(\d{2}):(\d{2})(?::(\d{2}))?$/.exec(value);
|
|
20
|
+
if (!match) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const hours = Number(match[1]);
|
|
25
|
+
const minutes = Number(match[2]);
|
|
26
|
+
const seconds = Number(match[3] ?? 0);
|
|
27
|
+
if (hours > 23 || minutes > 59 || seconds > 59) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return { hours, minutes, seconds };
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* TimePicker Utility; 시간 값을 24시간 문자열로 직렬화한다.
|
|
36
|
+
* @param {TimePickerParts} parts 시간 값
|
|
37
|
+
* @param {boolean} withSeconds 초 포함 여부
|
|
38
|
+
* @returns {string} HH:mm 또는 HH:mm:ss 값
|
|
39
|
+
*/
|
|
40
|
+
export const serializeTimeValue = (
|
|
41
|
+
parts: TimePickerParts,
|
|
42
|
+
withSeconds: boolean,
|
|
43
|
+
) =>
|
|
44
|
+
[parts.hours, parts.minutes, ...(withSeconds ? [parts.seconds] : [])]
|
|
45
|
+
.map(padTimePart)
|
|
46
|
+
.join(":");
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* TimePicker Utility; 지정 단위만 순환 증감한다.
|
|
50
|
+
* @param {string} value 시간 값
|
|
51
|
+
* @param {TimePickerUnit} unit 증감 단위
|
|
52
|
+
* @param {number} amount 증감량
|
|
53
|
+
* @param {boolean} withSeconds 초 포함 여부
|
|
54
|
+
* @returns {string} 증감한 시간 값
|
|
55
|
+
*/
|
|
56
|
+
export const stepTimeValue = (
|
|
57
|
+
value: string,
|
|
58
|
+
unit: TimePickerUnit,
|
|
59
|
+
amount: number,
|
|
60
|
+
withSeconds: boolean,
|
|
61
|
+
) => {
|
|
62
|
+
const parts = parseTimeValue(value) ?? {
|
|
63
|
+
hours: 0,
|
|
64
|
+
minutes: 0,
|
|
65
|
+
seconds: 0,
|
|
66
|
+
};
|
|
67
|
+
const limit = unit === "hours" ? 24 : 60;
|
|
68
|
+
return serializeTimeValue(
|
|
69
|
+
{ ...parts, [unit]: wrapTimePart(parts[unit] + amount, limit) },
|
|
70
|
+
withSeconds,
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* TimePicker Utility; 저장 시를 표시 시로 변환한다.
|
|
76
|
+
* @param {number} hours 24시간 시 값
|
|
77
|
+
* @param {TimePickerFormat} format 표시 형식
|
|
78
|
+
* @returns {number} 표시 시 값
|
|
79
|
+
*/
|
|
80
|
+
export const toDisplayHour = (hours: number, format: TimePickerFormat) =>
|
|
81
|
+
format === "12h" ? hours % 12 || 12 : hours;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* TimePicker Utility; 24시간 시 값의 오전·오후를 반환한다.
|
|
85
|
+
* @param {number} hours 24시간 시 값
|
|
86
|
+
* @returns {TimePickerPeriod} 오전·오후
|
|
87
|
+
*/
|
|
88
|
+
export const getTimePeriod = (hours: number): TimePickerPeriod =>
|
|
89
|
+
hours >= 12 ? "pm" : "am";
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* TimePicker Utility; 오전·오후를 24시간 저장값에 반영한다.
|
|
93
|
+
* @param {string} value 시간 값
|
|
94
|
+
* @param {TimePickerPeriod} period 오전·오후
|
|
95
|
+
* @param {boolean} withSeconds 초 포함 여부
|
|
96
|
+
* @returns {string} 변경한 시간 값
|
|
97
|
+
*/
|
|
98
|
+
export const setTimePeriod = (
|
|
99
|
+
value: string,
|
|
100
|
+
period: TimePickerPeriod,
|
|
101
|
+
withSeconds: boolean,
|
|
102
|
+
) => {
|
|
103
|
+
const parts = parseTimeValue(value) ?? {
|
|
104
|
+
hours: 0,
|
|
105
|
+
minutes: 0,
|
|
106
|
+
seconds: 0,
|
|
107
|
+
};
|
|
108
|
+
const hours = (parts.hours % 12) + (period === "pm" ? 12 : 0);
|
|
109
|
+
return serializeTimeValue({ ...parts, hours }, withSeconds);
|
|
110
|
+
};
|
package/src/index.scss
CHANGED
package/src/index.tsx
CHANGED
|
@@ -28,6 +28,7 @@ export * from "./components/spinner";
|
|
|
28
28
|
export * from "./components/switch";
|
|
29
29
|
export * from "./components/tab";
|
|
30
30
|
export * from "./components/table";
|
|
31
|
+
export * from "./components/time-picker";
|
|
31
32
|
export * from "./components/toast";
|
|
32
33
|
export * from "./components/tooltip";
|
|
33
34
|
export type * from "./types";
|
|
@@ -1,378 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { TimePicker as MantineTimePicker } from "@mantine/dates";
|
|
4
|
-
import { useUncontrolled } from "@mantine/hooks";
|
|
5
|
-
import clsx from "clsx";
|
|
6
|
-
import type { CSSProperties, ChangeEvent, FocusEvent, MouseEvent } from "react";
|
|
7
|
-
import { forwardRef, useCallback, useRef, useState } from "react";
|
|
8
|
-
import type { TimePickerStylesNames } from "@mantine/dates";
|
|
9
|
-
import {
|
|
10
|
-
getFormFieldWidthAttr,
|
|
11
|
-
getFormFieldWidthValue,
|
|
12
|
-
} from "../../../form/utils/form-field";
|
|
13
|
-
import type { InputTimePickerProps } from "../../types";
|
|
14
|
-
import ClockIcon from "../../img/clock.svg";
|
|
15
|
-
import ResetIcon from "../../img/reset.svg";
|
|
16
|
-
|
|
17
|
-
const INPUT_TIME_CLASS_NAMES = {
|
|
18
|
-
input: "input-time-input",
|
|
19
|
-
wrapper: "input-time-wrapper",
|
|
20
|
-
section: "input-time-section",
|
|
21
|
-
fieldsRoot: "input-time-fields-root",
|
|
22
|
-
fieldsGroup: "input-time-fields-group",
|
|
23
|
-
field: "input-time-field",
|
|
24
|
-
dropdown: "input-time-dropdown",
|
|
25
|
-
controlsListGroup: "input-time-controls-list-group",
|
|
26
|
-
controlsList: "input-time-controls-list",
|
|
27
|
-
control: "input-time-option",
|
|
28
|
-
presetControl: "input-time-preset-option",
|
|
29
|
-
presetsGroup: "input-time-presets-group",
|
|
30
|
-
presetsGroupLabel: "input-time-presets-group-label",
|
|
31
|
-
scrollarea: "input-time-scrollarea",
|
|
32
|
-
} satisfies Partial<Record<TimePickerStylesNames, string>>;
|
|
33
|
-
|
|
34
|
-
const INPUT_TIME_DROPDOWN_CONTENT_HEIGHT = 200;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Input Time Picker; Mantine TimePicker 기반 UDS adapter.
|
|
38
|
-
* `Input.Time.Picker` public namespace에서 사용하며 Calendar/date 하위에 속하지 않는다.
|
|
39
|
-
* @component
|
|
40
|
-
* @param {InputTimePickerProps} props
|
|
41
|
-
* @param {string} [props.value] 제어형 시간 값
|
|
42
|
-
* @param {string} [props.defaultValue] 비제어 초기 시간 값
|
|
43
|
-
* @param {(value:string)=>void} [props.onChange] 값 변경 핸들러
|
|
44
|
-
* @param {(value:string)=>void} [props.onValueChange] 값 변경 별칭
|
|
45
|
-
* @param {UseFormRegisterReturn} [props.register] react-hook-form register 결과
|
|
46
|
-
* @param {"primary" | "secondary" | "tertiary" | "table"} [props.priority="primary"] input priority
|
|
47
|
-
* @param {"small" | "medium" | "large"} [props.size="medium"] input size
|
|
48
|
-
* @param {"default" | "active" | "focused" | "success" | "error" | "disabled" | "loading"} [props.state="default"] input state
|
|
49
|
-
* @param {"12h" | "24h"} [props.format="24h"] 표시/입력 시간 포맷
|
|
50
|
-
* @param {boolean} [props.withSeconds=false] seconds 입력 노출 여부
|
|
51
|
-
* @param {boolean} [props.withDropdown=false] dropdown 노출 여부
|
|
52
|
-
* @param {boolean} [props.clearable=true] clear 버튼 노출 여부
|
|
53
|
-
* @param {"left" | "right"} [props.iconPosition] clock icon 위치
|
|
54
|
-
*/
|
|
55
|
-
const InputTimePicker = forwardRef<HTMLDivElement, InputTimePickerProps>(
|
|
56
|
-
(
|
|
57
|
-
{
|
|
58
|
-
value,
|
|
59
|
-
defaultValue,
|
|
60
|
-
onChange,
|
|
61
|
-
onValueChange,
|
|
62
|
-
name,
|
|
63
|
-
form,
|
|
64
|
-
register,
|
|
65
|
-
priority = "primary",
|
|
66
|
-
size = "medium",
|
|
67
|
-
state: stateProp = "default",
|
|
68
|
-
block = false,
|
|
69
|
-
width,
|
|
70
|
-
className,
|
|
71
|
-
disabled,
|
|
72
|
-
readOnly,
|
|
73
|
-
required,
|
|
74
|
-
id,
|
|
75
|
-
format = "24h",
|
|
76
|
-
withSeconds = false,
|
|
77
|
-
withDropdown = false,
|
|
78
|
-
clearable = true,
|
|
79
|
-
min,
|
|
80
|
-
max,
|
|
81
|
-
hoursStep,
|
|
82
|
-
minutesStep,
|
|
83
|
-
secondsStep,
|
|
84
|
-
icon,
|
|
85
|
-
iconPosition,
|
|
86
|
-
iconLabel = "시간 선택",
|
|
87
|
-
clearButtonLabel = "시간 지우기",
|
|
88
|
-
popoverProps,
|
|
89
|
-
hiddenInputProps,
|
|
90
|
-
hoursInputLabel,
|
|
91
|
-
minutesInputLabel,
|
|
92
|
-
secondsInputLabel,
|
|
93
|
-
amPmInputLabel,
|
|
94
|
-
amPmLabels,
|
|
95
|
-
hoursPlaceholder,
|
|
96
|
-
minutesPlaceholder,
|
|
97
|
-
secondsPlaceholder,
|
|
98
|
-
pasteSplit,
|
|
99
|
-
presets,
|
|
100
|
-
maxDropdownContentHeight,
|
|
101
|
-
scrollAreaProps,
|
|
102
|
-
reverseTimeControlsList,
|
|
103
|
-
onFocus,
|
|
104
|
-
onBlur,
|
|
105
|
-
},
|
|
106
|
-
ref,
|
|
107
|
-
) => {
|
|
108
|
-
const hoursInputRef = useRef<HTMLInputElement | null>(null);
|
|
109
|
-
const [isFocused, setIsFocused] = useState(false);
|
|
110
|
-
const [timeValue, setTimeValue] = useUncontrolled<string>({
|
|
111
|
-
value,
|
|
112
|
-
defaultValue,
|
|
113
|
-
finalValue: "",
|
|
114
|
-
onChange: nextValue => {
|
|
115
|
-
onChange?.(nextValue);
|
|
116
|
-
onValueChange?.(nextValue);
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
const emitRegisterChange = useCallback(
|
|
121
|
-
(nextValue: string) => {
|
|
122
|
-
if (!register?.onChange) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
const syntheticEvent = {
|
|
126
|
-
target: {
|
|
127
|
-
name: register.name,
|
|
128
|
-
value: nextValue,
|
|
129
|
-
},
|
|
130
|
-
currentTarget: {
|
|
131
|
-
name: register.name,
|
|
132
|
-
value: nextValue,
|
|
133
|
-
},
|
|
134
|
-
} as unknown as ChangeEvent<HTMLInputElement>;
|
|
135
|
-
register.onChange(syntheticEvent);
|
|
136
|
-
},
|
|
137
|
-
[register],
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
const emitRegisterBlur = useCallback(
|
|
141
|
-
(nextValue: string) => {
|
|
142
|
-
if (!register?.onBlur) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
const syntheticEvent = {
|
|
146
|
-
target: {
|
|
147
|
-
name: register.name,
|
|
148
|
-
value: nextValue,
|
|
149
|
-
},
|
|
150
|
-
currentTarget: {
|
|
151
|
-
name: register.name,
|
|
152
|
-
value: nextValue,
|
|
153
|
-
},
|
|
154
|
-
} as unknown as FocusEvent<HTMLInputElement>;
|
|
155
|
-
register.onBlur(syntheticEvent);
|
|
156
|
-
},
|
|
157
|
-
[register],
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
const currentState = disabled ? "disabled" : stateProp;
|
|
161
|
-
const isDisabled =
|
|
162
|
-
currentState === "disabled" || currentState === "loading";
|
|
163
|
-
const visualState =
|
|
164
|
-
priority === "tertiary"
|
|
165
|
-
? isDisabled
|
|
166
|
-
? "disabled"
|
|
167
|
-
: "default"
|
|
168
|
-
: !isDisabled && isFocused
|
|
169
|
-
? "active"
|
|
170
|
-
: currentState;
|
|
171
|
-
const resolvedIconPosition =
|
|
172
|
-
iconPosition ?? (priority === "table" ? "left" : "right");
|
|
173
|
-
const resolvedBlock =
|
|
174
|
-
block || (priority === "table" && width === undefined);
|
|
175
|
-
const widthAttr =
|
|
176
|
-
width !== undefined
|
|
177
|
-
? getFormFieldWidthAttr(width)
|
|
178
|
-
: resolvedBlock
|
|
179
|
-
? "full"
|
|
180
|
-
: undefined;
|
|
181
|
-
const widthValue =
|
|
182
|
-
width !== undefined ? getFormFieldWidthValue(width) : undefined;
|
|
183
|
-
const dropdownContentHeight =
|
|
184
|
-
maxDropdownContentHeight ?? INPUT_TIME_DROPDOWN_CONTENT_HEIGHT;
|
|
185
|
-
const containerStyle: CSSProperties | undefined =
|
|
186
|
-
widthValue !== undefined || maxDropdownContentHeight !== undefined
|
|
187
|
-
? ({
|
|
188
|
-
"--input-time-width": widthValue,
|
|
189
|
-
"--input-time-dropdown-content-height":
|
|
190
|
-
maxDropdownContentHeight !== undefined
|
|
191
|
-
? `${maxDropdownContentHeight}px`
|
|
192
|
-
: undefined,
|
|
193
|
-
} as CSSProperties)
|
|
194
|
-
: undefined;
|
|
195
|
-
const resolvedIcon = icon === undefined ? <ClockIcon /> : icon;
|
|
196
|
-
const showClearButton = Boolean(
|
|
197
|
-
clearable && timeValue && isFocused && !isDisabled && !readOnly,
|
|
198
|
-
);
|
|
199
|
-
const reserveClearSpace = Boolean(clearable && !isDisabled && !readOnly);
|
|
200
|
-
const rightSectionWidth =
|
|
201
|
-
resolvedIconPosition === "right"
|
|
202
|
-
? reserveClearSpace
|
|
203
|
-
? "var(--input-time-section-width-with-clear)"
|
|
204
|
-
: "var(--input-time-section-width)"
|
|
205
|
-
: showClearButton
|
|
206
|
-
? "var(--input-time-section-width)"
|
|
207
|
-
: undefined;
|
|
208
|
-
|
|
209
|
-
const handleChange = (nextValue: string) => {
|
|
210
|
-
setTimeValue(nextValue);
|
|
211
|
-
emitRegisterChange(nextValue);
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
const handleFocus = (event: FocusEvent<HTMLInputElement>) => {
|
|
215
|
-
setIsFocused(true);
|
|
216
|
-
onFocus?.(event);
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
const handleBlur = (event: FocusEvent<HTMLDivElement>) => {
|
|
220
|
-
setIsFocused(false);
|
|
221
|
-
emitRegisterBlur(timeValue);
|
|
222
|
-
onBlur?.(event);
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
const handleIconClick = (event: MouseEvent<HTMLButtonElement>) => {
|
|
226
|
-
event.preventDefault();
|
|
227
|
-
if (isDisabled || readOnly) {
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
hoursInputRef.current?.focus();
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
const handleClearClick = (event: MouseEvent<HTMLButtonElement>) => {
|
|
234
|
-
event.preventDefault();
|
|
235
|
-
if (isDisabled || readOnly) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
handleChange("");
|
|
239
|
-
hoursInputRef.current?.focus();
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
const iconButton = resolvedIcon ? (
|
|
243
|
-
<button
|
|
244
|
-
type="button"
|
|
245
|
-
className="input-time-section-button input-time-icon-button"
|
|
246
|
-
tabIndex={-1}
|
|
247
|
-
aria-label={iconLabel}
|
|
248
|
-
aria-disabled={isDisabled || readOnly ? true : undefined}
|
|
249
|
-
onMouseDown={event => event.preventDefault()}
|
|
250
|
-
onClick={handleIconClick}
|
|
251
|
-
>
|
|
252
|
-
<span className="input-time-icon-graphic" aria-hidden="true">
|
|
253
|
-
{resolvedIcon}
|
|
254
|
-
</span>
|
|
255
|
-
</button>
|
|
256
|
-
) : null;
|
|
257
|
-
|
|
258
|
-
const clearButton = showClearButton ? (
|
|
259
|
-
<button
|
|
260
|
-
type="button"
|
|
261
|
-
className="input-time-section-button input-time-clear-button"
|
|
262
|
-
tabIndex={-1}
|
|
263
|
-
aria-label={clearButtonLabel}
|
|
264
|
-
onMouseDown={event => event.preventDefault()}
|
|
265
|
-
onClick={handleClearClick}
|
|
266
|
-
>
|
|
267
|
-
<ResetIcon aria-hidden="true" />
|
|
268
|
-
</button>
|
|
269
|
-
) : null;
|
|
270
|
-
|
|
271
|
-
const rightSection =
|
|
272
|
-
resolvedIconPosition === "right" ? (
|
|
273
|
-
<span className="input-time-section-group">
|
|
274
|
-
{clearButton}
|
|
275
|
-
{iconButton}
|
|
276
|
-
</span>
|
|
277
|
-
) : (
|
|
278
|
-
clearButton
|
|
279
|
-
);
|
|
280
|
-
const resolvedScrollAreaProps = {
|
|
281
|
-
h: "var(--input-time-dropdown-content-height)",
|
|
282
|
-
mah: "var(--input-time-dropdown-content-height)",
|
|
283
|
-
...scrollAreaProps,
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
return (
|
|
287
|
-
<div
|
|
288
|
-
id={id}
|
|
289
|
-
className={clsx("input-time", className)}
|
|
290
|
-
data-priority={priority}
|
|
291
|
-
data-size={size}
|
|
292
|
-
data-state={visualState}
|
|
293
|
-
data-readonly={readOnly ? "true" : undefined}
|
|
294
|
-
data-block={resolvedBlock ? "true" : undefined}
|
|
295
|
-
data-icon-position={resolvedIconPosition}
|
|
296
|
-
data-has-value={timeValue ? "true" : "false"}
|
|
297
|
-
data-clearable={reserveClearSpace ? "true" : undefined}
|
|
298
|
-
data-has-clear={showClearButton ? "true" : undefined}
|
|
299
|
-
data-width={widthAttr}
|
|
300
|
-
style={containerStyle}
|
|
301
|
-
>
|
|
302
|
-
<MantineTimePicker
|
|
303
|
-
ref={ref}
|
|
304
|
-
className="input-time-picker"
|
|
305
|
-
classNames={INPUT_TIME_CLASS_NAMES}
|
|
306
|
-
value={timeValue}
|
|
307
|
-
onChange={handleChange}
|
|
308
|
-
name={register ? undefined : name}
|
|
309
|
-
form={register ? undefined : form}
|
|
310
|
-
required={required}
|
|
311
|
-
disabled={isDisabled}
|
|
312
|
-
readOnly={readOnly}
|
|
313
|
-
format={format}
|
|
314
|
-
withSeconds={withSeconds}
|
|
315
|
-
withDropdown={withDropdown}
|
|
316
|
-
clearable={false}
|
|
317
|
-
min={min}
|
|
318
|
-
max={max}
|
|
319
|
-
hoursStep={hoursStep}
|
|
320
|
-
minutesStep={minutesStep}
|
|
321
|
-
secondsStep={secondsStep}
|
|
322
|
-
hoursInputLabel={hoursInputLabel}
|
|
323
|
-
minutesInputLabel={minutesInputLabel}
|
|
324
|
-
secondsInputLabel={secondsInputLabel}
|
|
325
|
-
amPmInputLabel={amPmInputLabel}
|
|
326
|
-
amPmLabels={amPmLabels}
|
|
327
|
-
hoursPlaceholder={hoursPlaceholder}
|
|
328
|
-
minutesPlaceholder={minutesPlaceholder}
|
|
329
|
-
secondsPlaceholder={secondsPlaceholder}
|
|
330
|
-
pasteSplit={pasteSplit}
|
|
331
|
-
presets={presets}
|
|
332
|
-
maxDropdownContentHeight={dropdownContentHeight}
|
|
333
|
-
scrollAreaProps={resolvedScrollAreaProps}
|
|
334
|
-
reverseTimeControlsList={reverseTimeControlsList}
|
|
335
|
-
popoverProps={{
|
|
336
|
-
width: "target",
|
|
337
|
-
withinPortal: false,
|
|
338
|
-
...popoverProps,
|
|
339
|
-
}}
|
|
340
|
-
hiddenInputProps={register ? undefined : hiddenInputProps}
|
|
341
|
-
size="sm"
|
|
342
|
-
variant="unstyled"
|
|
343
|
-
withErrorStyles={false}
|
|
344
|
-
aria-invalid={visualState === "error" ? true : undefined}
|
|
345
|
-
leftSection={resolvedIconPosition === "left" ? iconButton : undefined}
|
|
346
|
-
rightSection={rightSection}
|
|
347
|
-
leftSectionWidth={
|
|
348
|
-
resolvedIconPosition === "left"
|
|
349
|
-
? "var(--input-time-left-section-width)"
|
|
350
|
-
: undefined
|
|
351
|
-
}
|
|
352
|
-
rightSectionWidth={rightSectionWidth}
|
|
353
|
-
leftSectionPointerEvents={
|
|
354
|
-
resolvedIconPosition === "left" ? "auto" : undefined
|
|
355
|
-
}
|
|
356
|
-
rightSectionPointerEvents={rightSection ? "auto" : undefined}
|
|
357
|
-
hoursRef={hoursInputRef}
|
|
358
|
-
onFocus={handleFocus}
|
|
359
|
-
onBlur={handleBlur}
|
|
360
|
-
/>
|
|
361
|
-
{register ? (
|
|
362
|
-
<input
|
|
363
|
-
{...hiddenInputProps}
|
|
364
|
-
{...register}
|
|
365
|
-
type="hidden"
|
|
366
|
-
name={register.name}
|
|
367
|
-
form={form ?? hiddenInputProps?.form}
|
|
368
|
-
value={timeValue}
|
|
369
|
-
/>
|
|
370
|
-
) : null}
|
|
371
|
-
</div>
|
|
372
|
-
);
|
|
373
|
-
},
|
|
374
|
-
);
|
|
375
|
-
|
|
376
|
-
InputTimePicker.displayName = "InputTimePicker";
|
|
377
|
-
|
|
378
|
-
export default InputTimePicker;
|