@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.
Files changed (30) hide show
  1. package/README.md +38 -453
  2. package/dist/styles.css +370 -327
  3. package/package.json +2 -2
  4. package/src/components/input/index.tsx +1 -1
  5. package/src/components/input/markup/time/Template.tsx +412 -0
  6. package/src/components/input/markup/time/Trigger.tsx +233 -0
  7. package/src/components/input/markup/time/index.tsx +9 -2
  8. package/src/components/input/styles/time.scss +160 -317
  9. package/src/components/input/styles/variables.scss +9 -47
  10. package/src/components/input/types/time.ts +263 -120
  11. package/src/components/time-picker/img/minus.svg +3 -0
  12. package/src/components/time-picker/img/plus.svg +3 -0
  13. package/src/components/time-picker/index.scss +1 -0
  14. package/src/components/time-picker/index.tsx +11 -0
  15. package/src/components/time-picker/markup/Footer.tsx +53 -0
  16. package/src/components/time-picker/markup/HourSection.tsx +72 -0
  17. package/src/components/time-picker/markup/MinuteSection.tsx +68 -0
  18. package/src/components/time-picker/markup/Summary.tsx +19 -0
  19. package/src/components/time-picker/markup/Template.tsx +86 -0
  20. package/src/components/time-picker/markup/index.tsx +10 -0
  21. package/src/components/time-picker/styles/index.scss +2 -0
  22. package/src/components/time-picker/styles/template.scss +174 -0
  23. package/src/components/time-picker/styles/variables.scss +64 -0
  24. package/src/components/time-picker/types/index.ts +1 -0
  25. package/src/components/time-picker/types/time-picker.ts +193 -0
  26. package/src/components/time-picker/utils/index.ts +1 -0
  27. package/src/components/time-picker/utils/time.ts +110 -0
  28. package/src/index.scss +1 -0
  29. package/src/index.tsx +1 -0
  30. package/src/components/input/markup/time/Picker.tsx +0 -378
@@ -0,0 +1,68 @@
1
+ import MinusIcon from "../img/minus.svg";
2
+ import PlusIcon from "../img/plus.svg";
3
+ import type { TimePickerMinuteSectionProps } from "../types";
4
+
5
+ const MINUTES = Array.from({ length: 12 }, (_, index) => index * 5);
6
+
7
+ /**
8
+ * TimePicker Minute Section; 1분 stepper와 5분 선택 grid를 렌더한다.
9
+ * @component
10
+ * @param {TimePickerMinuteSectionProps} props
11
+ * @param {number | null} props.selectedMinute 선택한 분
12
+ * @param {boolean} props.disabled 비활성화 여부
13
+ * @param {(amount: 1 | -1) => void} props.onMinuteStep 1분 증감 핸들러
14
+ * @param {(minutes: number) => void} props.onMinuteSelect 분 선택 핸들러
15
+ * @returns {ReactNode} 분 선택 section
16
+ * @example
17
+ * <TimePickerMinuteSection
18
+ * selectedMinute={30}
19
+ * disabled={false}
20
+ * onMinuteStep={onMinuteStep}
21
+ * onMinuteSelect={onMinuteSelect}
22
+ * />
23
+ */
24
+ export default function TimePickerMinuteSection({
25
+ selectedMinute,
26
+ disabled,
27
+ onMinuteStep,
28
+ onMinuteSelect,
29
+ }: TimePickerMinuteSectionProps) {
30
+ return (
31
+ <section className="time-picker-template-section">
32
+ <h3>분 선택</h3>
33
+ <div className="time-picker-minute-stepper">
34
+ <button
35
+ type="button"
36
+ aria-label="1분 증가"
37
+ disabled={disabled}
38
+ onClick={() => onMinuteStep(1)}
39
+ >
40
+ <PlusIcon aria-hidden="true" />
41
+ </button>
42
+ <strong>{String(selectedMinute ?? 0).padStart(2, "0")}분</strong>
43
+ <button
44
+ type="button"
45
+ aria-label="1분 감소"
46
+ disabled={disabled}
47
+ onClick={() => onMinuteStep(-1)}
48
+ >
49
+ <MinusIcon aria-hidden="true" />
50
+ </button>
51
+ </div>
52
+ <div className="time-picker-option-grid">
53
+ {MINUTES.map(minute => (
54
+ <button
55
+ key={`time-picker/minute/${minute}`}
56
+ type="button"
57
+ className="time-picker-option"
58
+ aria-pressed={selectedMinute === minute}
59
+ disabled={disabled}
60
+ onClick={() => onMinuteSelect(minute)}
61
+ >
62
+ {String(minute).padStart(2, "0")}
63
+ </button>
64
+ ))}
65
+ </div>
66
+ </section>
67
+ );
68
+ }
@@ -0,0 +1,19 @@
1
+ import type { TimePickerSummaryProps } from "../types";
2
+
3
+ /**
4
+ * TimePicker Summary; 현재 선택한 시간을 표시한다.
5
+ * @component
6
+ * @param {TimePickerSummaryProps} props
7
+ * @param {string} props.summary 선택한 시간 표시값
8
+ * @returns {ReactNode} 선택 시간 요약
9
+ * @example
10
+ * <TimePickerSummary summary="09:30 오전" />
11
+ */
12
+ export default function TimePickerSummary({ summary }: TimePickerSummaryProps) {
13
+ return (
14
+ <div className="time-picker-summary">
15
+ <span>선택한 시간</span>
16
+ <strong>{summary}</strong>
17
+ </div>
18
+ );
19
+ }
@@ -0,0 +1,86 @@
1
+ "use client";
2
+
3
+ import type { TimePickerTemplateProps } from "../types";
4
+ import { getTimePeriod, parseTimeValue, toDisplayHour } from "../utils";
5
+ import TimePickerFooter from "./Footer";
6
+ import TimePickerHourSection from "./HourSection";
7
+ import TimePickerMinuteSection from "./MinuteSection";
8
+ import TimePickerSummary from "./Summary";
9
+
10
+ /**
11
+ * TimePicker Template; Figma의 시간·분 선택과 footer action을 렌더한다.
12
+ * @component
13
+ * @param {TimePickerTemplateProps} props
14
+ * @param {string} props.value 24시간 형식 시간 값
15
+ * @param {"12h" | "24h"} props.format 표시 형식
16
+ * @param {boolean} props.clearable 삭제 action 노출 여부
17
+ * @param {boolean} props.disabled 비활성화 여부
18
+ * @param {(hours: number) => void} props.onHourSelect 시 선택 핸들러
19
+ * @param {(minutes: number) => void} props.onMinuteSelect 분 선택 핸들러
20
+ * @param {(period: "am" | "pm") => void} props.onPeriodChange 오전·오후 변경 핸들러
21
+ * @param {(amount: 1 | -1) => void} props.onMinuteStep 1분 증감 핸들러
22
+ * @param {() => void} props.onClear 삭제 핸들러
23
+ * @param {() => void} props.onApply 적용 핸들러
24
+ * @returns {ReactNode} 시간 선택 panel
25
+ * @example
26
+ * <TimePicker.Template
27
+ * value="09:30"
28
+ * format="24h"
29
+ * clearable
30
+ * disabled={false}
31
+ * onHourSelect={onHourSelect}
32
+ * onMinuteSelect={onMinuteSelect}
33
+ * onPeriodChange={onPeriodChange}
34
+ * onMinuteStep={onMinuteStep}
35
+ * onClear={onClear}
36
+ * onApply={onApply}
37
+ * />
38
+ */
39
+ export default function TimePickerTemplate({
40
+ value,
41
+ format,
42
+ clearable,
43
+ disabled,
44
+ onHourSelect,
45
+ onMinuteSelect,
46
+ onPeriodChange,
47
+ onMinuteStep,
48
+ onClear,
49
+ onApply,
50
+ }: TimePickerTemplateProps) {
51
+ const parts = parseTimeValue(value);
52
+ const selectedHour = parts ? toDisplayHour(parts.hours, format) : null;
53
+ const selectedMinute = parts?.minutes ?? null;
54
+ const period = parts ? getTimePeriod(parts.hours) : "am";
55
+ const summary = parts
56
+ ? `${String(selectedHour).padStart(2, "0")}:${String(parts.minutes).padStart(2, "0")}${
57
+ format === "12h" ? ` ${period === "am" ? "오전" : "오후"}` : ""
58
+ }`
59
+ : "--";
60
+
61
+ return (
62
+ <div className="time-picker-template">
63
+ <TimePickerSummary summary={summary} />
64
+ <TimePickerHourSection
65
+ format={format}
66
+ selectedHour={selectedHour}
67
+ period={period}
68
+ disabled={disabled}
69
+ onHourSelect={onHourSelect}
70
+ onPeriodChange={onPeriodChange}
71
+ />
72
+ <TimePickerMinuteSection
73
+ selectedMinute={selectedMinute}
74
+ disabled={disabled}
75
+ onMinuteStep={onMinuteStep}
76
+ onMinuteSelect={onMinuteSelect}
77
+ />
78
+ <TimePickerFooter
79
+ clearable={clearable}
80
+ disabled={disabled}
81
+ onClear={onClear}
82
+ onApply={onApply}
83
+ />
84
+ </div>
85
+ );
86
+ }
@@ -0,0 +1,10 @@
1
+ import TimePickerTemplate from "./Template";
2
+
3
+ /**
4
+ * TimePicker; 시간 선택 namespace.
5
+ * @desc
6
+ * - `TimePicker.Template`: 시간·분 선택과 footer action을 제공한다.
7
+ */
8
+ export const TimePicker = {
9
+ Template: TimePickerTemplate,
10
+ };
@@ -0,0 +1,2 @@
1
+ @use "./variables.scss";
2
+ @use "./template.scss";
@@ -0,0 +1,174 @@
1
+ .time-picker-template {
2
+ display: flex;
3
+ flex-direction: column;
4
+ max-height: min(
5
+ var(--time-picker-template-max-height),
6
+ calc(100vh - var(--time-picker-template-viewport-gap))
7
+ );
8
+ overflow-y: auto;
9
+ gap: var(--time-picker-template-gap);
10
+ padding: var(--time-picker-template-padding);
11
+ color: var(--time-picker-template-text-color);
12
+ }
13
+
14
+ .time-picker-summary {
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: center;
18
+ flex-direction: column;
19
+ gap: var(--time-picker-summary-gap);
20
+ height: var(--time-picker-summary-height);
21
+ padding-block: var(--time-picker-summary-padding-block);
22
+ border: var(--time-picker-option-border-width) solid
23
+ var(--time-picker-summary-border-color);
24
+ border-radius: var(--time-picker-summary-radius);
25
+ background-color: var(--time-picker-summary-surface-color);
26
+ color: var(--time-picker-summary-border-color);
27
+ text-align: center;
28
+
29
+ span {
30
+ font-size: var(--time-picker-summary-label-size);
31
+ line-height: var(--time-picker-summary-label-line-height);
32
+ font-weight: var(--time-picker-summary-label-weight);
33
+ letter-spacing: var(--time-picker-summary-label-letter-spacing);
34
+ }
35
+
36
+ strong {
37
+ font-size: var(--time-picker-summary-value-size);
38
+ line-height: var(--time-picker-summary-value-line-height);
39
+ font-weight: var(--time-picker-summary-value-weight);
40
+ letter-spacing: var(--time-picker-summary-value-letter-spacing);
41
+ }
42
+ }
43
+
44
+ .time-picker-template-section {
45
+ display: flex;
46
+ flex-direction: column;
47
+ gap: var(--time-picker-template-section-gap);
48
+
49
+ h3 {
50
+ margin: 0;
51
+ font-size: var(--time-picker-template-heading-size);
52
+ line-height: var(--time-picker-template-heading-line-height);
53
+ font-weight: var(--time-picker-template-heading-weight);
54
+ }
55
+ }
56
+
57
+ .time-picker-period-control.segmented-control {
58
+ --segmented-height: var(--time-picker-period-height);
59
+ --segmented-padding: var(--time-picker-period-padding);
60
+ --segmented-radius: var(--time-picker-period-radius);
61
+ --segmented-bg: var(--time-picker-period-surface-color);
62
+ --segmented-indicator-bg: var(--time-picker-period-item-surface-color);
63
+ --segmented-indicator-shadow: var(--time-picker-period-item-shadow);
64
+ --segmented-label-color: var(--time-picker-period-item-color);
65
+ --segmented-label-active-color: var(--time-picker-period-item-color);
66
+ --segmented-gap: 0px;
67
+ --segmented-item-font-size: var(--time-picker-period-item-font-size);
68
+ --segmented-item-font-weight: var(--time-picker-period-item-font-weight);
69
+ --segmented-item-line-height: var(--time-picker-period-item-line-height);
70
+ width: 100%;
71
+ height: var(--time-picker-period-height);
72
+ border-radius: var(--time-picker-period-radius);
73
+
74
+ .segmented-control-indicator,
75
+ .segmented-control-button {
76
+ border-radius: var(--time-picker-period-item-radius);
77
+ }
78
+
79
+ .segmented-control-list {
80
+ width: 100%;
81
+ height: 100%;
82
+ }
83
+
84
+ .segmented-control-item {
85
+ display: flex;
86
+ flex: 1;
87
+ }
88
+
89
+ .segmented-control-button {
90
+ height: 100%;
91
+ }
92
+
93
+ .segmented-control-label {
94
+ letter-spacing: 0;
95
+ }
96
+ }
97
+
98
+ .time-picker-option-grid {
99
+ display: grid;
100
+ grid-template-columns: repeat(4, 1fr);
101
+ gap: var(--time-picker-option-gap);
102
+ }
103
+
104
+ .time-picker-option {
105
+ min-width: 0;
106
+ height: var(--time-picker-option-height);
107
+ padding: 0;
108
+ border: var(--time-picker-option-border-width) solid
109
+ var(--time-picker-option-border-color);
110
+ border-radius: var(--time-picker-option-radius);
111
+ background-color: var(--time-picker-option-surface-color);
112
+ color: var(--time-picker-option-color);
113
+ font-size: var(--time-picker-option-font-size);
114
+ line-height: var(--time-picker-option-line-height);
115
+ cursor: pointer;
116
+
117
+ &:where([aria-pressed="true"]) {
118
+ border-color: var(--time-picker-option-selected-color);
119
+ background-color: var(--time-picker-option-selected-surface-color);
120
+ color: var(--time-picker-option-selected-color);
121
+ }
122
+ }
123
+
124
+ .time-picker-minute-stepper {
125
+ display: flex;
126
+ align-items: center;
127
+ justify-content: center;
128
+ gap: var(--time-picker-minute-stepper-gap);
129
+ height: var(--time-picker-minute-stepper-height);
130
+ border-radius: var(--time-picker-minute-stepper-radius);
131
+ background-color: var(--time-picker-minute-stepper-surface-color);
132
+ text-align: center;
133
+
134
+ strong {
135
+ font-size: var(--time-picker-minute-value-size);
136
+ line-height: var(--time-picker-minute-value-line-height);
137
+ font-weight: var(--time-picker-minute-value-weight);
138
+ }
139
+
140
+ button {
141
+ display: flex;
142
+ align-items: center;
143
+ justify-content: center;
144
+ width: var(--time-picker-minute-control-size);
145
+ height: var(--time-picker-minute-control-size);
146
+ padding: 0;
147
+ border: 0;
148
+ background-color: transparent;
149
+ cursor: pointer;
150
+
151
+ svg {
152
+ width: 100%;
153
+ height: 100%;
154
+ }
155
+ }
156
+ }
157
+
158
+ .time-picker-template-footer {
159
+ display: flex;
160
+ align-items: center;
161
+ justify-content: space-between;
162
+ gap: var(--time-picker-template-footer-gap);
163
+ }
164
+
165
+ .time-picker-clear-action {
166
+ margin: 0;
167
+ padding: 0;
168
+ border: 0;
169
+ background-color: transparent;
170
+ color: var(--time-picker-clear-color);
171
+ font-size: var(--time-picker-clear-size);
172
+ line-height: var(--time-picker-clear-line-height);
173
+ cursor: pointer;
174
+ }
@@ -0,0 +1,64 @@
1
+ :root {
2
+ --time-picker-template-max-height: 800px;
3
+ --time-picker-template-viewport-gap: var(--spacing-gap-8);
4
+ --time-picker-template-padding: var(--spacing-padding-6);
5
+ --time-picker-template-gap: var(--spacing-gap-6);
6
+ --time-picker-template-section-gap: var(--spacing-gap-5);
7
+ --time-picker-template-text-color: var(--color-label-standard);
8
+ --time-picker-template-heading-size: var(--font-heading-small-size);
9
+ --time-picker-template-heading-line-height: var(
10
+ --font-heading-small-line-height
11
+ );
12
+ --time-picker-template-heading-weight: var(--font-heading-small-weight);
13
+ --time-picker-summary-height: 82px;
14
+ --time-picker-summary-padding-block: var(--spacing-padding-5);
15
+ --time-picker-summary-gap: var(--spacing-gap-3);
16
+ --time-picker-summary-radius: var(--theme-radius-large-2);
17
+ --time-picker-summary-surface-color: var(--color-surface-standard);
18
+ --time-picker-summary-border-color: var(--color-cool-gray-20);
19
+ --time-picker-summary-label-size: var(--font-body-xsmall-size);
20
+ --time-picker-summary-label-line-height: var(--font-body-xsmall-line-height);
21
+ --time-picker-summary-label-weight: var(--font-body-xsmall-weight);
22
+ --time-picker-summary-label-letter-spacing: var(
23
+ --font-body-xsmall-letter-spacing
24
+ );
25
+ --time-picker-summary-value-size: var(--font-heading-small-size);
26
+ --time-picker-summary-value-line-height: var(--font-body-large-line-height);
27
+ --time-picker-summary-value-weight: var(--font-heading-small-weight);
28
+ --time-picker-summary-value-letter-spacing: 0.2px;
29
+ --time-picker-option-gap: var(--spacing-gap-5);
30
+ --time-picker-option-height: var(--theme-size-medium-1);
31
+ --time-picker-option-border-width: 1px;
32
+ --time-picker-option-border-color: var(--color-border-standard-cool-gray);
33
+ --time-picker-option-radius: var(--theme-radius-medium-3);
34
+ --time-picker-option-surface-color: var(--color-common-100);
35
+ --time-picker-option-color: var(--color-label-standard);
36
+ --time-picker-option-selected-color: var(--color-primary-default);
37
+ --time-picker-option-selected-surface-color: var(--color-neutral-99);
38
+ --time-picker-option-font-size: var(--font-body-xsmall-size);
39
+ --time-picker-option-line-height: var(--font-body-xsmall-line-height);
40
+ --time-picker-period-height: var(--theme-size-medium-1);
41
+ --time-picker-period-padding: var(--spacing-padding-1);
42
+ --time-picker-period-radius: var(--theme-radius-large-1);
43
+ --time-picker-period-item-radius: var(--theme-radius-medium-4);
44
+ --time-picker-period-surface-color: var(--color-cool-gray-85);
45
+ --time-picker-period-item-surface-color: var(--color-common-100);
46
+ --time-picker-period-item-color: var(--color-label-standard);
47
+ --time-picker-period-item-shadow:
48
+ 0 2px 8px rgba(0, 0, 0, 0.06), 0 0 4px rgba(0, 0, 0, 0.12);
49
+ --time-picker-period-item-font-size: var(--font-body-xsmall-size);
50
+ --time-picker-period-item-font-weight: var(--font-body-medium-weight);
51
+ --time-picker-period-item-line-height: var(--font-body-xsmall-line-height);
52
+ --time-picker-minute-stepper-height: var(--theme-size-medium-1);
53
+ --time-picker-minute-stepper-gap: var(--spacing-gap-13);
54
+ --time-picker-minute-stepper-radius: var(--theme-radius-large-1);
55
+ --time-picker-minute-stepper-surface-color: var(--color-cool-gray-85);
56
+ --time-picker-minute-control-size: var(--theme-size-small-2);
57
+ --time-picker-minute-value-size: var(--font-body-xsmall-size);
58
+ --time-picker-minute-value-line-height: var(--font-body-xsmall-line-height);
59
+ --time-picker-minute-value-weight: var(--font-body-medium-weight);
60
+ --time-picker-template-footer-gap: var(--spacing-gap-6);
61
+ --time-picker-clear-color: var(--color-error);
62
+ --time-picker-clear-size: var(--font-body-xsmall-size);
63
+ --time-picker-clear-line-height: var(--font-body-xsmall-line-height);
64
+ }
@@ -0,0 +1 @@
1
+ export type * from "./time-picker";
@@ -0,0 +1,193 @@
1
+ /**
2
+ * TimePicker 표시 형식.
3
+ * @typedef {"12h" | "24h"} TimePickerFormat
4
+ */
5
+ export type TimePickerFormat = "12h" | "24h";
6
+
7
+ /**
8
+ * TimePicker 오전·오후 구분.
9
+ * @typedef {"am" | "pm"} TimePickerPeriod
10
+ */
11
+ export type TimePickerPeriod = "am" | "pm";
12
+
13
+ /**
14
+ * TimePicker 시간 단위.
15
+ * @typedef {"hours" | "minutes" | "seconds"} TimePickerUnit
16
+ */
17
+ export type TimePickerUnit = "hours" | "minutes" | "seconds";
18
+
19
+ /**
20
+ * TimePicker 시간 값 구성.
21
+ * @property {number} hours 시
22
+ * @property {number} minutes 분
23
+ * @property {number} seconds 초
24
+ */
25
+ export interface TimePickerParts {
26
+ /**
27
+ * 시.
28
+ */
29
+ hours: number;
30
+ /**
31
+ * 분.
32
+ */
33
+ minutes: number;
34
+ /**
35
+ * 초.
36
+ */
37
+ seconds: number;
38
+ }
39
+
40
+ /**
41
+ * TimePicker Template props.
42
+ * @property {string} value 24시간 형식 시간 값
43
+ * @property {"12h" | "24h"} format 표시 형식
44
+ * @property {boolean} clearable 삭제 action 노출 여부
45
+ * @property {boolean} disabled 비활성화 여부
46
+ * @property {(hours: number) => void} onHourSelect 시 선택 핸들러
47
+ * @property {(minutes: number) => void} onMinuteSelect 분 선택 핸들러
48
+ * @property {(period: "am" | "pm") => void} onPeriodChange 오전·오후 변경 핸들러
49
+ * @property {(amount: 1 | -1) => void} onMinuteStep 1분 증감 핸들러
50
+ * @property {() => void} onClear 삭제 핸들러
51
+ * @property {() => void} onApply 적용 핸들러
52
+ */
53
+ export interface TimePickerTemplateProps {
54
+ /**
55
+ * 24시간 형식 시간 값.
56
+ */
57
+ value: string;
58
+ /**
59
+ * "12h" | "24h".
60
+ */
61
+ format: TimePickerFormat;
62
+ /**
63
+ * 삭제 action 노출 여부.
64
+ */
65
+ clearable: boolean;
66
+ /**
67
+ * 비활성화 여부.
68
+ */
69
+ disabled: boolean;
70
+ /**
71
+ * 시 선택 핸들러.
72
+ */
73
+ onHourSelect: (hours: number) => void;
74
+ /**
75
+ * 분 선택 핸들러.
76
+ */
77
+ onMinuteSelect: (minutes: number) => void;
78
+ /**
79
+ * 오전·오후 변경 핸들러.
80
+ */
81
+ onPeriodChange: (period: TimePickerPeriod) => void;
82
+ /**
83
+ * 1분 증감 핸들러.
84
+ */
85
+ onMinuteStep: (amount: 1 | -1) => void;
86
+ /**
87
+ * 삭제 핸들러.
88
+ */
89
+ onClear: () => void;
90
+ /**
91
+ * 적용 핸들러.
92
+ */
93
+ onApply: () => void;
94
+ }
95
+
96
+ /**
97
+ * TimePicker Summary props.
98
+ * @property {string} summary 선택한 시간 표시값
99
+ */
100
+ export interface TimePickerSummaryProps {
101
+ /**
102
+ * 선택한 시간 표시값.
103
+ */
104
+ summary: string;
105
+ }
106
+
107
+ /**
108
+ * TimePicker Hour Section props.
109
+ * @property {"12h" | "24h"} format 표시 형식
110
+ * @property {number | null} selectedHour 선택한 표시 시
111
+ * @property {"am" | "pm"} period 오전·오후 구분
112
+ * @property {boolean} disabled 비활성화 여부
113
+ * @property {(hours: number) => void} onHourSelect 시 선택 핸들러
114
+ * @property {(period: "am" | "pm") => void} onPeriodChange 오전·오후 변경 핸들러
115
+ */
116
+ export interface TimePickerHourSectionProps {
117
+ /**
118
+ * "12h" | "24h".
119
+ */
120
+ format: TimePickerFormat;
121
+ /**
122
+ * 선택한 표시 시.
123
+ */
124
+ selectedHour: number | null;
125
+ /**
126
+ * "am" | "pm".
127
+ */
128
+ period: TimePickerPeriod;
129
+ /**
130
+ * 비활성화 여부.
131
+ */
132
+ disabled: boolean;
133
+ /**
134
+ * 시 선택 핸들러.
135
+ */
136
+ onHourSelect: (hours: number) => void;
137
+ /**
138
+ * 오전·오후 변경 핸들러.
139
+ */
140
+ onPeriodChange: (period: TimePickerPeriod) => void;
141
+ }
142
+
143
+ /**
144
+ * TimePicker Minute Section props.
145
+ * @property {number | null} selectedMinute 선택한 분
146
+ * @property {boolean} disabled 비활성화 여부
147
+ * @property {(amount: 1 | -1) => void} onMinuteStep 1분 증감 핸들러
148
+ * @property {(minutes: number) => void} onMinuteSelect 분 선택 핸들러
149
+ */
150
+ export interface TimePickerMinuteSectionProps {
151
+ /**
152
+ * 선택한 분.
153
+ */
154
+ selectedMinute: number | null;
155
+ /**
156
+ * 비활성화 여부.
157
+ */
158
+ disabled: boolean;
159
+ /**
160
+ * 1분 증감 핸들러.
161
+ */
162
+ onMinuteStep: (amount: 1 | -1) => void;
163
+ /**
164
+ * 분 선택 핸들러.
165
+ */
166
+ onMinuteSelect: (minutes: number) => void;
167
+ }
168
+
169
+ /**
170
+ * TimePicker Footer props.
171
+ * @property {boolean} clearable 삭제 action 노출 여부
172
+ * @property {boolean} disabled 비활성화 여부
173
+ * @property {() => void} onClear 삭제 핸들러
174
+ * @property {() => void} onApply 적용 핸들러
175
+ */
176
+ export interface TimePickerFooterProps {
177
+ /**
178
+ * 삭제 action 노출 여부.
179
+ */
180
+ clearable: boolean;
181
+ /**
182
+ * 비활성화 여부.
183
+ */
184
+ disabled: boolean;
185
+ /**
186
+ * 삭제 핸들러.
187
+ */
188
+ onClear: () => void;
189
+ /**
190
+ * 적용 핸들러.
191
+ */
192
+ onApply: () => void;
193
+ }
@@ -0,0 +1 @@
1
+ export * from "./time";