@uniai-fe/uds-primitives 0.2.1 → 0.2.3
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 +1 -1
- package/dist/styles.css +391 -81
- package/package.json +17 -8
- package/src/components/button/index.tsx +0 -2
- package/src/components/button/markup/Base.tsx +22 -1
- package/src/components/button/styles/button.scss +24 -2
- package/src/components/button/styles/variables.scss +4 -0
- package/src/components/button/types/index.ts +7 -0
- package/src/components/{input/img/calendar → calendar/img}/calendar.svg +5 -0
- package/src/components/calendar/index.tsx +5 -3
- package/src/components/calendar/markup/Core.tsx +67 -0
- package/src/components/calendar/markup/Icon.tsx +20 -0
- package/src/components/calendar/markup/Root.tsx +126 -0
- package/src/components/calendar/markup/index.tsx +24 -2
- package/src/components/calendar/markup/layout/Body.tsx +12 -0
- package/src/components/calendar/markup/layout/Container.tsx +43 -0
- package/src/components/calendar/markup/layout/Footer.tsx +12 -0
- package/src/components/calendar/markup/layout/Header.tsx +12 -0
- package/src/components/calendar/styles/index.scss +2 -0
- package/src/components/calendar/styles/layout.scss +21 -0
- package/src/components/calendar/styles/mantine-calendar.scss +240 -0
- package/src/components/calendar/types/calendar.ts +208 -0
- package/src/components/calendar/types/index.ts +1 -4
- package/src/components/calendar/utils/index.ts +1 -4
- package/src/components/calendar/utils/value-mapper.ts +24 -0
- package/src/components/checkbox/markup/Checkbox.tsx +31 -25
- package/src/components/dropdown/markup/index.tsx +10 -1
- package/src/components/input/hooks/index.ts +1 -0
- package/src/components/input/hooks/useAddress.ts +247 -0
- package/src/components/input/index.scss +5 -1
- package/src/components/input/markup/address/Button.tsx +65 -0
- package/src/components/input/markup/address/Template.tsx +135 -0
- package/src/components/input/markup/address/index.ts +9 -0
- package/src/components/input/markup/date/Template.tsx +181 -0
- package/src/components/input/markup/date/Trigger.tsx +79 -0
- package/src/components/input/markup/date/button/ApplyButton.tsx +38 -0
- package/src/components/input/markup/date/button/ClearButton.tsx +36 -0
- package/src/components/input/markup/date/button/TodayButton.tsx +36 -0
- package/src/components/input/markup/date/footer/Container.tsx +24 -0
- package/src/components/input/markup/date/footer/Template.tsx +36 -0
- package/src/components/input/markup/date/footer/UtilContainer.tsx +23 -0
- package/src/components/input/markup/date/footer/index.ts +3 -0
- package/src/components/input/markup/date/index.tsx +27 -0
- package/src/components/input/markup/foundation/Input.tsx +20 -1
- package/src/components/input/markup/index.tsx +4 -4
- package/src/components/input/styles/address.scss +24 -0
- package/src/components/input/styles/date.scss +45 -0
- package/src/components/input/styles/foundation.scss +28 -2
- package/src/components/input/styles/variables.scss +4 -0
- package/src/components/input/types/address.ts +249 -0
- package/src/components/input/types/date.ts +366 -0
- package/src/components/input/types/foundation.ts +6 -0
- package/src/components/input/types/index.ts +2 -1
- package/src/components/input/utils/address.ts +165 -0
- package/src/components/input/utils/date.ts +61 -0
- package/src/components/input/utils/index.tsx +2 -0
- package/src/components/pop-over/index.scss +1 -0
- package/src/components/pop-over/index.tsx +4 -0
- package/src/components/pop-over/markup/Content.tsx +77 -0
- package/src/components/pop-over/markup/Root.tsx +28 -0
- package/src/components/pop-over/markup/Trigger.tsx +26 -0
- package/src/components/pop-over/markup/index.tsx +17 -0
- package/src/components/pop-over/styles/base.scss +5 -0
- package/src/components/pop-over/styles/content.scss +24 -0
- package/src/components/pop-over/styles/index.scss +2 -0
- package/src/components/pop-over/types/index.ts +1 -0
- package/src/components/pop-over/types/pop-over.ts +86 -0
- package/src/components/radio/markup/Radio.tsx +10 -2
- package/src/components/radio/markup/RadioCard.tsx +6 -1
- package/src/components/radio/markup/RadioCardGroup.tsx +6 -1
- package/src/components/select/markup/Default.tsx +2 -0
- package/src/components/select/markup/foundation/Container.tsx +23 -0
- package/src/components/select/markup/multiple/Multiple.tsx +2 -0
- package/src/components/select/styles/select.scss +25 -2
- package/src/components/select/styles/variables.scss +4 -0
- package/src/components/select/types/props.ts +24 -5
- package/src/index.scss +1 -0
- package/src/index.tsx +3 -1
- package/src/init/mantine.css +5 -0
- package/src/init/mantine.ts +2 -0
- package/src/components/input/markup/calendar/Base.tsx +0 -329
- package/src/components/input/markup/calendar/index.tsx +0 -8
- package/src/components/input/styles/calendar.scss +0 -110
- package/src/components/input/styles/index.scss +0 -4
- package/src/components/input/types/calendar.ts +0 -208
- /package/src/components/{input/img/calendar → calendar/img}/chevron-down.svg +0 -0
- /package/src/components/{input/img/calendar → calendar/img}/chevron-left.svg +0 -0
- /package/src/components/{input/img/calendar → calendar/img}/chevron-right.svg +0 -0
- /package/src/components/{input/img/calendar → calendar/img}/chevron-up.svg +0 -0
|
@@ -1,12 +1,35 @@
|
|
|
1
1
|
.select {
|
|
2
2
|
display: flex;
|
|
3
|
-
width:
|
|
3
|
+
width: var(--select-width);
|
|
4
|
+
flex: var(--select-flex);
|
|
4
5
|
flex-direction: column;
|
|
5
6
|
gap: var(--spacing-gap-2);
|
|
7
|
+
min-width: 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.select[data-width="auto"] {
|
|
11
|
+
--select-width: auto;
|
|
12
|
+
--select-flex: 0 1 auto;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.select[data-width="fill"] {
|
|
16
|
+
--select-width: auto;
|
|
17
|
+
--select-flex: 1 1 0%;
|
|
6
18
|
}
|
|
7
19
|
|
|
20
|
+
.select[data-width="full"],
|
|
8
21
|
.select-block {
|
|
9
|
-
width: 100%;
|
|
22
|
+
--select-width: 100%;
|
|
23
|
+
--select-flex: 0 0 100%;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.select[data-width="fit"] {
|
|
27
|
+
--select-width: fit-content;
|
|
28
|
+
--select-flex: 0 0 auto;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.select[data-width="custom"] {
|
|
32
|
+
--select-flex: 0 0 auto;
|
|
10
33
|
}
|
|
11
34
|
|
|
12
35
|
.select-button {
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/* Select tokens mapped to Input primary tokens for visual parity */
|
|
2
2
|
:root {
|
|
3
|
+
/* layout presets */
|
|
4
|
+
--select-width: 100%;
|
|
5
|
+
--select-flex: 0 1 auto;
|
|
6
|
+
|
|
3
7
|
--select-primary-height-small: var(--input-default-height-small);
|
|
4
8
|
--select-primary-height-medium: var(--input-default-height-medium);
|
|
5
9
|
--select-primary-height-large: var(--input-default-height-large);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
DropdownContainerProps,
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
DropdownRootProps,
|
|
8
8
|
DropdownTemplateItem,
|
|
9
9
|
} from "../../dropdown/types";
|
|
10
|
+
import type { FormFieldWidth } from "../../form/types";
|
|
10
11
|
import type { SelectPriority, SelectSize, SelectState } from "./base";
|
|
11
12
|
import type {
|
|
12
13
|
SelectTriggerDefaultProps,
|
|
@@ -82,7 +83,7 @@ export interface SelectComponentState {
|
|
|
82
83
|
* @property {ReactNode} children trigger/Dropdown 등 내부 콘텐츠
|
|
83
84
|
* @property {boolean} [block] block 여부
|
|
84
85
|
*/
|
|
85
|
-
export interface SelectContainerProps {
|
|
86
|
+
export interface SelectContainerProps extends HTMLAttributes<HTMLDivElement> {
|
|
86
87
|
/**
|
|
87
88
|
* 사용자 정의 className
|
|
88
89
|
*/
|
|
@@ -95,6 +96,21 @@ export interface SelectContainerProps {
|
|
|
95
96
|
* block 여부
|
|
96
97
|
*/
|
|
97
98
|
block?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* width preset
|
|
101
|
+
*/
|
|
102
|
+
width?: FormFieldWidth;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Select width 옵션
|
|
107
|
+
* @property {FormFieldWidth} [width] width preset 옵션
|
|
108
|
+
*/
|
|
109
|
+
export interface SelectWidthOption {
|
|
110
|
+
/**
|
|
111
|
+
* width preset 옵션
|
|
112
|
+
*/
|
|
113
|
+
width?: FormFieldWidth;
|
|
98
114
|
}
|
|
99
115
|
|
|
100
116
|
/**
|
|
@@ -103,7 +119,8 @@ export interface SelectContainerProps {
|
|
|
103
119
|
*/
|
|
104
120
|
export type SelectProps = SelectStyleOptions &
|
|
105
121
|
SelectValueOptions &
|
|
106
|
-
SelectComponentState
|
|
122
|
+
SelectComponentState &
|
|
123
|
+
SelectWidthOption;
|
|
107
124
|
|
|
108
125
|
/**
|
|
109
126
|
* Select dropdown option; Dropdown.Template item 계약을 그대로 따른다.
|
|
@@ -194,7 +211,8 @@ export interface SelectDefaultComponentProps
|
|
|
194
211
|
extends
|
|
195
212
|
SelectTriggerDefaultProps,
|
|
196
213
|
SelectDropdownConfigProps,
|
|
197
|
-
SelectDropdownBehaviorProps
|
|
214
|
+
SelectDropdownBehaviorProps,
|
|
215
|
+
SelectWidthOption {}
|
|
198
216
|
|
|
199
217
|
/**
|
|
200
218
|
* Select.Multiple 컴포넌트 props
|
|
@@ -206,4 +224,5 @@ export interface SelectMultipleComponentProps
|
|
|
206
224
|
extends
|
|
207
225
|
SelectTriggerMultipleProps,
|
|
208
226
|
SelectDropdownConfigProps,
|
|
209
|
-
SelectDropdownBehaviorProps
|
|
227
|
+
SelectDropdownBehaviorProps,
|
|
228
|
+
SelectWidthOption {}
|
package/src/index.scss
CHANGED
package/src/index.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Mantine 날짜 생태계와 dayjs 설정을 한 번만 초기화한다.
|
|
2
2
|
import "./init/dayjs";
|
|
3
|
+
import "./init/mantine";
|
|
3
4
|
// ThemeProvider는 foundation provider에서만 export한다(one-source 규칙).
|
|
4
5
|
|
|
5
6
|
// 루트 배럴: 카테고리별 export를 집계한다.
|
|
@@ -12,6 +13,7 @@ export * from "./components/select";
|
|
|
12
13
|
export * from "./components/tab";
|
|
13
14
|
export * from "./components/navigation";
|
|
14
15
|
export * from "./components/dropdown";
|
|
16
|
+
export * from "./components/pop-over";
|
|
15
17
|
export * from "./components/drawer";
|
|
16
18
|
export * from "./components/scrollbar";
|
|
17
19
|
export * from "./components/calendar";
|
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
DatePicker,
|
|
5
|
-
type DatePickerStylesNames,
|
|
6
|
-
type DatePickerType,
|
|
7
|
-
} from "@mantine/dates";
|
|
8
|
-
import { useUncontrolled } from "@mantine/hooks";
|
|
9
|
-
import type { ChangeEvent, FocusEvent } from "react";
|
|
10
|
-
import { forwardRef, useCallback, useMemo } from "react";
|
|
11
|
-
import { Button } from "../../../button";
|
|
12
|
-
import ChevronLeftIcon from "../../img/calendar/chevron-left.svg";
|
|
13
|
-
import ChevronRightIcon from "../../img/calendar/chevron-right.svg";
|
|
14
|
-
import type {
|
|
15
|
-
InputCalendarActionButtonProps,
|
|
16
|
-
InputCalendarProps,
|
|
17
|
-
InputCalendarValue,
|
|
18
|
-
} from "../../types";
|
|
19
|
-
import { dayjs } from "../../../../init/dayjs";
|
|
20
|
-
|
|
21
|
-
const DATE_FORMAT = "YYYY-MM-DD";
|
|
22
|
-
type CalendarValue = InputCalendarValue<DatePickerType>;
|
|
23
|
-
|
|
24
|
-
const DATE_PICKER_CLASS_NAMES = {
|
|
25
|
-
calendar: "input-calendar-panel",
|
|
26
|
-
datePickerRoot: "input-calendar-root",
|
|
27
|
-
calendarHeader: "input-calendar-header",
|
|
28
|
-
calendarHeaderControl: "input-calendar-header-control",
|
|
29
|
-
calendarHeaderLevel: "input-calendar-header-level",
|
|
30
|
-
day: "input-calendar-day",
|
|
31
|
-
weekday: "input-calendar-weekday",
|
|
32
|
-
weekdaysRow: "input-calendar-weekdays",
|
|
33
|
-
monthRow: "input-calendar-month-row",
|
|
34
|
-
monthCell: "input-calendar-month-cell",
|
|
35
|
-
month: "input-calendar-month",
|
|
36
|
-
monthThead: "input-calendar-month-thead",
|
|
37
|
-
monthTbody: "input-calendar-month-tbody",
|
|
38
|
-
} as Partial<Record<DatePickerStylesNames, string>>;
|
|
39
|
-
|
|
40
|
-
const DEFAULT_ACTION_LABELS: Record<"clear" | "today" | "apply", string> = {
|
|
41
|
-
clear: "삭제",
|
|
42
|
-
today: "오늘",
|
|
43
|
-
apply: "적용하기",
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const createEmptyValue = (type: DatePickerType): CalendarValue => {
|
|
47
|
-
if (type === "range") {
|
|
48
|
-
return [null, null];
|
|
49
|
-
}
|
|
50
|
-
if (type === "multiple") {
|
|
51
|
-
return [];
|
|
52
|
-
}
|
|
53
|
-
return null;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const serializeValue = (value: CalendarValue, type: DatePickerType) => {
|
|
57
|
-
if (type === "range" || type === "multiple") {
|
|
58
|
-
return JSON.stringify(value ?? createEmptyValue(type));
|
|
59
|
-
}
|
|
60
|
-
return (value as string) ?? "";
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const formatDate = (date: Date | string | null) =>
|
|
64
|
-
date ? dayjs(date).format(DATE_FORMAT) : null;
|
|
65
|
-
|
|
66
|
-
const mapValueToPicker = (value: CalendarValue, type: DatePickerType) => {
|
|
67
|
-
if (type === "range") {
|
|
68
|
-
const [start, end] = (value ?? [null, null]) as InputCalendarValue<"range">;
|
|
69
|
-
return [
|
|
70
|
-
start ? dayjs(start).toDate() : null,
|
|
71
|
-
end ? dayjs(end).toDate() : null,
|
|
72
|
-
];
|
|
73
|
-
}
|
|
74
|
-
if (type === "multiple") {
|
|
75
|
-
return ((value ?? []) as InputCalendarValue<"multiple">).map(entry =>
|
|
76
|
-
entry ? dayjs(entry).toDate() : null,
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
if (typeof value === "string" && value) {
|
|
80
|
-
return dayjs(value).toDate();
|
|
81
|
-
}
|
|
82
|
-
return null;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const parseValueFromPicker = (
|
|
86
|
-
value: unknown,
|
|
87
|
-
type: DatePickerType,
|
|
88
|
-
): CalendarValue => {
|
|
89
|
-
if (type === "range") {
|
|
90
|
-
const [start, end] = (value as [Date | null, Date | null]) ?? [null, null];
|
|
91
|
-
return [formatDate(start), formatDate(end)] as CalendarValue;
|
|
92
|
-
}
|
|
93
|
-
if (type === "multiple") {
|
|
94
|
-
return ((value as (Date | null)[]) || []).map(entry =>
|
|
95
|
-
formatDate(entry),
|
|
96
|
-
) as CalendarValue;
|
|
97
|
-
}
|
|
98
|
-
return formatDate((value as Date | null) ?? null);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
const getTodayValue = (type: DatePickerType): CalendarValue => {
|
|
102
|
-
const today = dayjs().format(DATE_FORMAT);
|
|
103
|
-
if (type === "range") {
|
|
104
|
-
return [today, today];
|
|
105
|
-
}
|
|
106
|
-
if (type === "multiple") {
|
|
107
|
-
return [today];
|
|
108
|
-
}
|
|
109
|
-
return today;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const resolveAction = (
|
|
113
|
-
action: InputCalendarActionButtonProps | undefined,
|
|
114
|
-
key: keyof typeof DEFAULT_ACTION_LABELS,
|
|
115
|
-
) => {
|
|
116
|
-
const visible = action?.visible ?? true;
|
|
117
|
-
if (!visible) return null;
|
|
118
|
-
return {
|
|
119
|
-
label: action?.label ?? DEFAULT_ACTION_LABELS[key],
|
|
120
|
-
disabled: action?.disabled ?? false,
|
|
121
|
-
};
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const InputCalendarBase = forwardRef<
|
|
125
|
-
HTMLDivElement,
|
|
126
|
-
InputCalendarProps<DatePickerType>
|
|
127
|
-
>(
|
|
128
|
-
// DatePickerType 유니언을 명시해 range/multiple 비교 로직 타입 오류를 방지한다.
|
|
129
|
-
(props, ref) => {
|
|
130
|
-
const {
|
|
131
|
-
mode = "date",
|
|
132
|
-
type = "default",
|
|
133
|
-
columns = 1,
|
|
134
|
-
value,
|
|
135
|
-
defaultValue,
|
|
136
|
-
onChange,
|
|
137
|
-
onValueChange,
|
|
138
|
-
onClear,
|
|
139
|
-
onToday,
|
|
140
|
-
onApply,
|
|
141
|
-
readOnly,
|
|
142
|
-
disabled,
|
|
143
|
-
datePickerProps,
|
|
144
|
-
actions,
|
|
145
|
-
name,
|
|
146
|
-
register,
|
|
147
|
-
} = props;
|
|
148
|
-
|
|
149
|
-
const [calendarValue, setCalendarValue] = useUncontrolled<CalendarValue>({
|
|
150
|
-
value,
|
|
151
|
-
defaultValue,
|
|
152
|
-
finalValue: createEmptyValue(type),
|
|
153
|
-
onChange: changedValue => {
|
|
154
|
-
onChange?.(changedValue as InputCalendarValue<typeof type>);
|
|
155
|
-
onValueChange?.(changedValue as InputCalendarValue<typeof type>);
|
|
156
|
-
},
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
const serializedValue = useMemo(
|
|
160
|
-
() => serializeValue(calendarValue, type),
|
|
161
|
-
[calendarValue, type],
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
const emitRegisterChange = useCallback(
|
|
165
|
-
(nextValue: CalendarValue) => {
|
|
166
|
-
if (!register?.onChange) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const syntheticEvent = {
|
|
171
|
-
target: {
|
|
172
|
-
name: register.name,
|
|
173
|
-
value: serializeValue(nextValue, type),
|
|
174
|
-
},
|
|
175
|
-
currentTarget: {
|
|
176
|
-
name: register.name,
|
|
177
|
-
value: serializeValue(nextValue, type),
|
|
178
|
-
},
|
|
179
|
-
} as unknown as ChangeEvent<HTMLInputElement>;
|
|
180
|
-
|
|
181
|
-
register.onChange(syntheticEvent);
|
|
182
|
-
},
|
|
183
|
-
[register, type],
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
const updateValue = useCallback(
|
|
187
|
-
(nextValue: CalendarValue) => {
|
|
188
|
-
setCalendarValue(nextValue as InputCalendarValue<typeof type>);
|
|
189
|
-
emitRegisterChange(nextValue);
|
|
190
|
-
},
|
|
191
|
-
[emitRegisterChange, setCalendarValue],
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
const handleDateChange = useCallback(
|
|
195
|
-
(next: unknown) => {
|
|
196
|
-
const normalized = parseValueFromPicker(next, type);
|
|
197
|
-
updateValue(normalized);
|
|
198
|
-
},
|
|
199
|
-
[type, updateValue],
|
|
200
|
-
);
|
|
201
|
-
|
|
202
|
-
const handleClear = () => {
|
|
203
|
-
updateValue(createEmptyValue(type));
|
|
204
|
-
onClear?.();
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const handleToday = () => {
|
|
208
|
-
updateValue(getTodayValue(type));
|
|
209
|
-
onToday?.();
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
const handleApply = () => {
|
|
213
|
-
onApply?.(calendarValue as InputCalendarValue<typeof type>);
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
const resolvedClear = resolveAction(actions?.clear, "clear");
|
|
217
|
-
const resolvedToday = resolveAction(actions?.today, "today");
|
|
218
|
-
const resolvedApply = resolveAction(actions?.apply, "apply");
|
|
219
|
-
|
|
220
|
-
const isInteractive = !(readOnly || disabled);
|
|
221
|
-
const hiddenName = register?.name ?? name;
|
|
222
|
-
|
|
223
|
-
const handleHiddenRef = useCallback(
|
|
224
|
-
(node: HTMLInputElement | null) => {
|
|
225
|
-
if (register?.ref) {
|
|
226
|
-
register.ref(node);
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
[register],
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
const handleHiddenBlur = (event: FocusEvent<HTMLInputElement>) => {
|
|
233
|
-
register?.onBlur?.(event);
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
if (mode !== "date" && process.env.NODE_ENV !== "production") {
|
|
237
|
-
console.warn("InputCalendarBase: 현재 date 모드만 지원합니다.");
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const singleRangeProps =
|
|
241
|
-
type === "range"
|
|
242
|
-
? {
|
|
243
|
-
allowSingleDateInRange: true,
|
|
244
|
-
}
|
|
245
|
-
: {};
|
|
246
|
-
|
|
247
|
-
return (
|
|
248
|
-
<div
|
|
249
|
-
ref={ref}
|
|
250
|
-
className="input-calendar"
|
|
251
|
-
data-mode={mode}
|
|
252
|
-
data-type={type}
|
|
253
|
-
data-columns={columns}
|
|
254
|
-
data-disabled={disabled ? "true" : undefined}
|
|
255
|
-
>
|
|
256
|
-
{hiddenName ? (
|
|
257
|
-
<input
|
|
258
|
-
type="hidden"
|
|
259
|
-
name={hiddenName}
|
|
260
|
-
value={serializedValue}
|
|
261
|
-
readOnly
|
|
262
|
-
ref={handleHiddenRef}
|
|
263
|
-
onBlur={handleHiddenBlur}
|
|
264
|
-
/>
|
|
265
|
-
) : null}
|
|
266
|
-
<div className="input-calendar-container">
|
|
267
|
-
<DatePicker
|
|
268
|
-
classNames={DATE_PICKER_CLASS_NAMES}
|
|
269
|
-
value={mapValueToPicker(calendarValue, type) as never}
|
|
270
|
-
onChange={handleDateChange as never}
|
|
271
|
-
type={type}
|
|
272
|
-
numberOfColumns={columns}
|
|
273
|
-
nextIcon={<ChevronRightIcon />}
|
|
274
|
-
previousIcon={<ChevronLeftIcon />}
|
|
275
|
-
// Mantine DatePicker에는 disabled prop이 없어 data-disabled로 상단에서 제어한다.
|
|
276
|
-
{...(datePickerProps ?? {})}
|
|
277
|
-
{...singleRangeProps}
|
|
278
|
-
/>
|
|
279
|
-
<div className="input-calendar-footer">
|
|
280
|
-
<div className="input-calendar-footer-actions">
|
|
281
|
-
{resolvedClear ? (
|
|
282
|
-
<Button.Default
|
|
283
|
-
fill="outlined"
|
|
284
|
-
size="small"
|
|
285
|
-
priority="tertiary"
|
|
286
|
-
disabled={!isInteractive || resolvedClear.disabled}
|
|
287
|
-
onClick={handleClear}
|
|
288
|
-
className="input-calendar-action-button"
|
|
289
|
-
>
|
|
290
|
-
{resolvedClear.label}
|
|
291
|
-
</Button.Default>
|
|
292
|
-
) : (
|
|
293
|
-
<span />
|
|
294
|
-
)}
|
|
295
|
-
{resolvedToday ? (
|
|
296
|
-
<Button.Default
|
|
297
|
-
fill="outlined"
|
|
298
|
-
size="small"
|
|
299
|
-
priority="secondary"
|
|
300
|
-
disabled={!isInteractive || resolvedToday.disabled}
|
|
301
|
-
onClick={handleToday}
|
|
302
|
-
className="input-calendar-action-button"
|
|
303
|
-
>
|
|
304
|
-
{resolvedToday.label}
|
|
305
|
-
</Button.Default>
|
|
306
|
-
) : null}
|
|
307
|
-
</div>
|
|
308
|
-
{resolvedApply ? (
|
|
309
|
-
<Button.Default
|
|
310
|
-
fill="solid"
|
|
311
|
-
size="large"
|
|
312
|
-
priority="primary"
|
|
313
|
-
disabled={!isInteractive || resolvedApply.disabled}
|
|
314
|
-
onClick={handleApply}
|
|
315
|
-
className="input-calendar-apply"
|
|
316
|
-
>
|
|
317
|
-
{resolvedApply.label}
|
|
318
|
-
</Button.Default>
|
|
319
|
-
) : null}
|
|
320
|
-
</div>
|
|
321
|
-
</div>
|
|
322
|
-
</div>
|
|
323
|
-
);
|
|
324
|
-
},
|
|
325
|
-
);
|
|
326
|
-
|
|
327
|
-
InputCalendarBase.displayName = "InputCalendarBase";
|
|
328
|
-
|
|
329
|
-
export { InputCalendarBase };
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
.input-calendar {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: column;
|
|
4
|
-
gap: var(--spacing-gap-6, 20px);
|
|
5
|
-
width: 100%;
|
|
6
|
-
|
|
7
|
-
&[data-disabled="true"] {
|
|
8
|
-
opacity: 0.6;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.input-calendar-container {
|
|
13
|
-
background-color: var(--color-common-100, #fff);
|
|
14
|
-
border-radius: var(--theme-radius-large-3, 16px);
|
|
15
|
-
box-shadow:
|
|
16
|
-
0 4px 20px rgba(0, 0, 0, 0.16),
|
|
17
|
-
0 0 2px rgba(0, 0, 0, 0.12);
|
|
18
|
-
padding: var(--spacing-padding-10, 32px) var(--spacing-padding-6, 16px)
|
|
19
|
-
var(--spacing-padding-6, 16px);
|
|
20
|
-
display: flex;
|
|
21
|
-
flex-direction: column;
|
|
22
|
-
gap: var(--spacing-gap-5, 16px);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.input-calendar-root {
|
|
26
|
-
width: 100%;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.input-calendar-panel {
|
|
30
|
-
width: 100%;
|
|
31
|
-
border-radius: var(--theme-radius-large-1, 12px);
|
|
32
|
-
background-color: transparent;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.input-calendar-header {
|
|
36
|
-
display: flex;
|
|
37
|
-
align-items: center;
|
|
38
|
-
justify-content: space-between;
|
|
39
|
-
padding-inline: var(--spacing-padding-6, 16px);
|
|
40
|
-
margin-bottom: var(--spacing-gap-4, 12px);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.input-calendar-header-control {
|
|
44
|
-
width: 24px;
|
|
45
|
-
height: 24px;
|
|
46
|
-
display: inline-flex;
|
|
47
|
-
align-items: center;
|
|
48
|
-
justify-content: center;
|
|
49
|
-
border-radius: 999px;
|
|
50
|
-
background: transparent;
|
|
51
|
-
color: var(--color-label-strong, #18191b);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.input-calendar-header-level {
|
|
55
|
-
font-size: var(--font-heading-small-size, 19px);
|
|
56
|
-
font-weight: var(--font-heading-small-weight, 600);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.input-calendar-weekdays {
|
|
60
|
-
display: grid;
|
|
61
|
-
grid-template-columns: repeat(7, minmax(0, 1fr));
|
|
62
|
-
padding-bottom: var(--spacing-padding-2, 4px);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.input-calendar-weekday {
|
|
66
|
-
text-transform: none;
|
|
67
|
-
font-size: var(--font-heading-xxsmall-size, 15px);
|
|
68
|
-
color: var(--color-label-alternative, #afb1b6);
|
|
69
|
-
text-align: center;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.input-calendar-day {
|
|
73
|
-
width: 44px;
|
|
74
|
-
height: 44px;
|
|
75
|
-
border-radius: var(--theme-radius-large-1, 12px);
|
|
76
|
-
justify-self: center;
|
|
77
|
-
font-size: var(--font-body-medium-size, 17px);
|
|
78
|
-
color: var(--color-label-strong, #3d3f43);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.input-calendar-footer {
|
|
82
|
-
display: flex;
|
|
83
|
-
flex-direction: column;
|
|
84
|
-
gap: var(--spacing-gap-4, 12px);
|
|
85
|
-
width: 100%;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.input-calendar-footer-actions {
|
|
89
|
-
display: flex;
|
|
90
|
-
align-items: center;
|
|
91
|
-
justify-content: space-between;
|
|
92
|
-
gap: var(--spacing-gap-3, 8px);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.input-calendar-action-button {
|
|
96
|
-
width: 100%;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.input-calendar-footer-actions > :first-child {
|
|
100
|
-
flex: 1 1 auto;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.input-calendar-footer-actions > :last-child {
|
|
104
|
-
flex: 1 1 auto;
|
|
105
|
-
justify-content: flex-end;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.input-calendar-apply {
|
|
109
|
-
width: 100%;
|
|
110
|
-
}
|