@uniai-fe/uds-primitives 0.10.4 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +38 -452
  2. package/dist/styles.css +1233 -508
  3. package/package.json +3 -3
  4. package/src/components/button/markup/Base.tsx +1 -1
  5. package/src/components/button/styles/button.scss +84 -1
  6. package/src/components/button/styles/variables.scss +73 -0
  7. package/src/components/button/types/options.ts +8 -0
  8. package/src/components/button/types/props.ts +30 -6
  9. package/src/components/input/markup/address/Button.tsx +1 -1
  10. package/src/components/input/markup/time/Template.tsx +423 -0
  11. package/src/components/input/markup/time/Trigger.tsx +289 -0
  12. package/src/components/input/markup/time/index.tsx +2 -2
  13. package/src/components/input/styles/time.scss +160 -317
  14. package/src/components/input/styles/variables.scss +9 -47
  15. package/src/components/input/types/time.ts +61 -120
  16. package/src/components/time-picker/img/minus.svg +3 -0
  17. package/src/components/time-picker/img/plus.svg +3 -0
  18. package/src/components/time-picker/index.scss +1 -0
  19. package/src/components/time-picker/index.tsx +11 -0
  20. package/src/components/time-picker/markup/Footer.tsx +71 -0
  21. package/src/components/time-picker/markup/HourSection.tsx +99 -0
  22. package/src/components/time-picker/markup/MinuteSection.tsx +86 -0
  23. package/src/components/time-picker/markup/Summary.tsx +24 -0
  24. package/src/components/time-picker/markup/Template.tsx +86 -0
  25. package/src/components/time-picker/markup/index.tsx +10 -0
  26. package/src/components/time-picker/styles/index.scss +2 -0
  27. package/src/components/time-picker/styles/template.scss +174 -0
  28. package/src/components/time-picker/styles/variables.scss +64 -0
  29. package/src/components/time-picker/types/index.ts +1 -0
  30. package/src/components/time-picker/types/time-picker.ts +94 -0
  31. package/src/components/time-picker/utils/index.ts +1 -0
  32. package/src/components/time-picker/utils/time.ts +110 -0
  33. package/src/index.scss +1 -0
  34. package/src/index.tsx +1 -0
  35. package/src/components/input/markup/time/Picker.tsx +0 -378
@@ -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,94 @@
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
+ }
@@ -0,0 +1 @@
1
+ export * from "./time";
@@ -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
@@ -22,5 +22,6 @@
22
22
  @use "./components/switch";
23
23
  @use "./components/tab";
24
24
  @use "./components/table";
25
+ @use "./components/time-picker";
25
26
  @use "./components/toast";
26
27
  @use "./components/tooltip";
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";