@x-plat/design-system 0.4.1 → 0.4.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/dist/components/Calendar/index.cjs +132 -69
- package/dist/components/Calendar/index.css +40 -23
- package/dist/components/Calendar/index.d.cts +0 -13
- package/dist/components/Calendar/index.d.ts +0 -13
- package/dist/components/Calendar/index.js +133 -70
- package/dist/components/DatePicker/index.cjs +126 -37
- package/dist/components/DatePicker/index.css +54 -15
- package/dist/components/DatePicker/index.js +127 -38
- package/dist/components/ImageSelector/index.css +1 -0
- package/dist/components/Modal/index.css +4 -8
- package/dist/components/index.cjs +258 -106
- package/dist/components/index.css +95 -38
- package/dist/components/index.js +262 -110
- package/dist/index.cjs +258 -106
- package/dist/index.css +95 -38
- package/dist/index.js +264 -112
- package/package.json +1 -1
|
@@ -1091,6 +1091,10 @@ var Calendar = (props) => {
|
|
|
1091
1091
|
setYear,
|
|
1092
1092
|
setMonth
|
|
1093
1093
|
} = useCalendar(yearProp, monthProp);
|
|
1094
|
+
const [pickerMode, setPickerMode] = import_react2.default.useState("days");
|
|
1095
|
+
const [yearRangeStart, setYearRangeStart] = import_react2.default.useState(
|
|
1096
|
+
Math.floor(year / 12) * 12
|
|
1097
|
+
);
|
|
1094
1098
|
import_react2.default.useEffect(() => {
|
|
1095
1099
|
if (yearProp !== void 0) setYear(yearProp);
|
|
1096
1100
|
}, [yearProp, setYear]);
|
|
@@ -1098,22 +1102,54 @@ var Calendar = (props) => {
|
|
|
1098
1102
|
if (monthProp !== void 0) setMonth(monthProp);
|
|
1099
1103
|
}, [monthProp, setMonth]);
|
|
1100
1104
|
const handlePrev = () => {
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
+
if (pickerMode === "days") {
|
|
1106
|
+
goToPrevMonth();
|
|
1107
|
+
const prevMonth = month === 0 ? 11 : month - 1;
|
|
1108
|
+
const prevYear = month === 0 ? year - 1 : year;
|
|
1109
|
+
onMonthChange?.(prevYear, prevMonth);
|
|
1110
|
+
} else if (pickerMode === "months") {
|
|
1111
|
+
setYear(year - 1);
|
|
1112
|
+
onMonthChange?.(year - 1, month);
|
|
1113
|
+
} else {
|
|
1114
|
+
setYearRangeStart((s) => s - 12);
|
|
1115
|
+
}
|
|
1105
1116
|
};
|
|
1106
1117
|
const handleNext = () => {
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1118
|
+
if (pickerMode === "days") {
|
|
1119
|
+
goToNextMonth();
|
|
1120
|
+
const nextMonth = month === 11 ? 0 : month + 1;
|
|
1121
|
+
const nextYear = month === 11 ? year + 1 : year;
|
|
1122
|
+
onMonthChange?.(nextYear, nextMonth);
|
|
1123
|
+
} else if (pickerMode === "months") {
|
|
1124
|
+
setYear(year + 1);
|
|
1125
|
+
onMonthChange?.(year + 1, month);
|
|
1126
|
+
} else {
|
|
1127
|
+
setYearRangeStart((s) => s + 12);
|
|
1128
|
+
}
|
|
1111
1129
|
};
|
|
1112
1130
|
const handleToday = () => {
|
|
1113
1131
|
goToToday();
|
|
1132
|
+
setPickerMode("days");
|
|
1114
1133
|
const today = /* @__PURE__ */ new Date();
|
|
1115
1134
|
onMonthChange?.(today.getFullYear(), today.getMonth());
|
|
1116
1135
|
};
|
|
1136
|
+
const handleTitleClick = () => {
|
|
1137
|
+
if (pickerMode === "days") setPickerMode("months");
|
|
1138
|
+
else if (pickerMode === "months") {
|
|
1139
|
+
setYearRangeStart(Math.floor(year / 12) * 12);
|
|
1140
|
+
setPickerMode("years");
|
|
1141
|
+
}
|
|
1142
|
+
};
|
|
1143
|
+
const handleMonthSelect = (m) => {
|
|
1144
|
+
setMonth(m);
|
|
1145
|
+
setPickerMode("days");
|
|
1146
|
+
onMonthChange?.(year, m);
|
|
1147
|
+
};
|
|
1148
|
+
const handleYearSelect = (y) => {
|
|
1149
|
+
setYear(y);
|
|
1150
|
+
setPickerMode("months");
|
|
1151
|
+
onMonthChange?.(y, month);
|
|
1152
|
+
};
|
|
1117
1153
|
const isDisabled = (date) => {
|
|
1118
1154
|
if (minDate && date < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) return true;
|
|
1119
1155
|
if (maxDate && date > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())) return true;
|
|
@@ -1121,6 +1157,8 @@ var Calendar = (props) => {
|
|
|
1121
1157
|
};
|
|
1122
1158
|
const getEventsForDay = (date) => events.filter((e) => isSameDay(e.date, date));
|
|
1123
1159
|
const weekdays = WEEKDAY_LABELS[locale];
|
|
1160
|
+
const monthLabels = MONTH_LABELS[locale];
|
|
1161
|
+
const titleText = pickerMode === "days" ? locale === "ko" ? `${year}\uB144 ${monthLabels[month]}` : `${monthLabels[month]} ${year}` : pickerMode === "months" ? `${year}` : `${yearRangeStart} - ${yearRangeStart + 11}`;
|
|
1124
1162
|
return /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)(
|
|
1125
1163
|
"div",
|
|
1126
1164
|
{
|
|
@@ -1128,29 +1166,71 @@ var Calendar = (props) => {
|
|
|
1128
1166
|
style: selectedColor ? { "--calendar-selected-color": `var(--${selectedColor})` } : void 0,
|
|
1129
1167
|
children: [
|
|
1130
1168
|
/* @__PURE__ */ (0, import_jsx_runtime295.jsxs)("div", { className: "calendar-header", children: [
|
|
1131
|
-
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("button", { className: "calendar-nav", onClick: handlePrev, "aria-label": "\uC774\uC804
|
|
1132
|
-
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("
|
|
1133
|
-
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("button", { className: "calendar-nav", onClick: handleNext, "aria-label": "\uB2E4\uC74C
|
|
1169
|
+
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("button", { className: "calendar-nav", onClick: handlePrev, "aria-label": "\uC774\uC804", children: /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(ChevronLeftIcon_default, {}) }),
|
|
1170
|
+
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("button", { className: "calendar-title", onClick: handleTitleClick, type: "button", children: titleText }),
|
|
1171
|
+
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("button", { className: "calendar-nav", onClick: handleNext, "aria-label": "\uB2E4\uC74C", children: /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(ChevronRightIcon_default, {}) }),
|
|
1134
1172
|
showToday && /* @__PURE__ */ (0, import_jsx_runtime295.jsx)("button", { className: "calendar-today-btn", onClick: handleToday, children: locale === "ko" ? "\uC624\uB298" : "Today" })
|
|
1135
1173
|
] }),
|
|
1136
|
-
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("div", { className: "calendar-
|
|
1137
|
-
|
|
1174
|
+
pickerMode === "years" && /* @__PURE__ */ (0, import_jsx_runtime295.jsx)("div", { className: "calendar-picker-grid", children: Array.from({ length: 12 }, (_, i) => {
|
|
1175
|
+
const y = yearRangeStart + i;
|
|
1176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(
|
|
1177
|
+
"button",
|
|
1178
|
+
{
|
|
1179
|
+
type: "button",
|
|
1180
|
+
className: clsx_default("calendar-picker-cell", y === year && "active"),
|
|
1181
|
+
onClick: () => handleYearSelect(y),
|
|
1182
|
+
children: y
|
|
1183
|
+
},
|
|
1184
|
+
y
|
|
1185
|
+
);
|
|
1186
|
+
}) }),
|
|
1187
|
+
pickerMode === "months" && /* @__PURE__ */ (0, import_jsx_runtime295.jsx)("div", { className: "calendar-picker-grid", children: monthLabels.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(
|
|
1188
|
+
"button",
|
|
1138
1189
|
{
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
i === 6 && "saturday"
|
|
1143
|
-
),
|
|
1190
|
+
type: "button",
|
|
1191
|
+
className: clsx_default("calendar-picker-cell", i === month && "active"),
|
|
1192
|
+
onClick: () => handleMonthSelect(i),
|
|
1144
1193
|
children: label
|
|
1145
1194
|
},
|
|
1146
|
-
|
|
1195
|
+
i
|
|
1147
1196
|
)) }),
|
|
1148
|
-
/* @__PURE__ */ (0, import_jsx_runtime295.
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1197
|
+
pickerMode === "days" && /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)(import_jsx_runtime295.Fragment, { children: [
|
|
1198
|
+
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("div", { className: "calendar-weekdays", children: weekdays.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(
|
|
1199
|
+
"div",
|
|
1200
|
+
{
|
|
1201
|
+
className: clsx_default(
|
|
1202
|
+
"calendar-weekday",
|
|
1203
|
+
i === 0 && "sunday",
|
|
1204
|
+
i === 6 && "saturday"
|
|
1205
|
+
),
|
|
1206
|
+
children: label
|
|
1207
|
+
},
|
|
1208
|
+
label
|
|
1209
|
+
)) }),
|
|
1210
|
+
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("div", { className: "calendar-grid", children: days.map((day, idx) => {
|
|
1211
|
+
const dayEvents = getEventsForDay(day.date);
|
|
1212
|
+
const disabled = isDisabled(day.date);
|
|
1213
|
+
const isSelected = selectedDate ? isSameDay(day.date, selectedDate) : false;
|
|
1214
|
+
if (renderDay) {
|
|
1215
|
+
return /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(
|
|
1216
|
+
"div",
|
|
1217
|
+
{
|
|
1218
|
+
className: clsx_default(
|
|
1219
|
+
"calendar-day",
|
|
1220
|
+
!day.isCurrentMonth && "outside",
|
|
1221
|
+
disabled && "disabled",
|
|
1222
|
+
isSelected && "selected",
|
|
1223
|
+
day.isToday && "today"
|
|
1224
|
+
),
|
|
1225
|
+
onClick: () => {
|
|
1226
|
+
if (!disabled && day.isCurrentMonth) onSelect?.(day.date);
|
|
1227
|
+
},
|
|
1228
|
+
children: renderDay(day, dayEvents)
|
|
1229
|
+
},
|
|
1230
|
+
idx
|
|
1231
|
+
);
|
|
1232
|
+
}
|
|
1233
|
+
return /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)(
|
|
1154
1234
|
"div",
|
|
1155
1235
|
{
|
|
1156
1236
|
className: clsx_default(
|
|
@@ -1158,57 +1238,40 @@ var Calendar = (props) => {
|
|
|
1158
1238
|
!day.isCurrentMonth && "outside",
|
|
1159
1239
|
disabled && "disabled",
|
|
1160
1240
|
isSelected && "selected",
|
|
1161
|
-
day.isToday && "today"
|
|
1241
|
+
day.isToday && "today",
|
|
1242
|
+
day.isSunday && "sunday",
|
|
1243
|
+
day.isSaturday && "saturday"
|
|
1162
1244
|
),
|
|
1163
1245
|
onClick: () => {
|
|
1164
1246
|
if (!disabled && day.isCurrentMonth) onSelect?.(day.date);
|
|
1165
1247
|
},
|
|
1166
|
-
children:
|
|
1248
|
+
children: [
|
|
1249
|
+
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("span", { className: "calendar-day-number", children: day.day }),
|
|
1250
|
+
dayEvents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)("div", { className: "calendar-day-events", children: [
|
|
1251
|
+
dayEvents.slice(0, 3).map((event, ei) => /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(
|
|
1252
|
+
"span",
|
|
1253
|
+
{
|
|
1254
|
+
className: "calendar-event-dot",
|
|
1255
|
+
style: { backgroundColor: event.color ?? "var(--xplat-blue-500)" },
|
|
1256
|
+
title: event.label,
|
|
1257
|
+
onClick: (e) => {
|
|
1258
|
+
e.stopPropagation();
|
|
1259
|
+
onEventClick?.(event);
|
|
1260
|
+
}
|
|
1261
|
+
},
|
|
1262
|
+
ei
|
|
1263
|
+
)),
|
|
1264
|
+
dayEvents.length > 3 && /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)("span", { className: "calendar-event-more", children: [
|
|
1265
|
+
"+",
|
|
1266
|
+
dayEvents.length - 3
|
|
1267
|
+
] })
|
|
1268
|
+
] })
|
|
1269
|
+
]
|
|
1167
1270
|
},
|
|
1168
1271
|
idx
|
|
1169
1272
|
);
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
"div",
|
|
1173
|
-
{
|
|
1174
|
-
className: clsx_default(
|
|
1175
|
-
"calendar-day",
|
|
1176
|
-
!day.isCurrentMonth && "outside",
|
|
1177
|
-
disabled && "disabled",
|
|
1178
|
-
isSelected && "selected",
|
|
1179
|
-
day.isToday && "today",
|
|
1180
|
-
day.isSunday && "sunday",
|
|
1181
|
-
day.isSaturday && "saturday"
|
|
1182
|
-
),
|
|
1183
|
-
onClick: () => {
|
|
1184
|
-
if (!disabled && day.isCurrentMonth) onSelect?.(day.date);
|
|
1185
|
-
},
|
|
1186
|
-
children: [
|
|
1187
|
-
/* @__PURE__ */ (0, import_jsx_runtime295.jsx)("span", { className: "calendar-day-number", children: day.day }),
|
|
1188
|
-
dayEvents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)("div", { className: "calendar-day-events", children: [
|
|
1189
|
-
dayEvents.slice(0, 3).map((event, ei) => /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(
|
|
1190
|
-
"span",
|
|
1191
|
-
{
|
|
1192
|
-
className: "calendar-event-dot",
|
|
1193
|
-
style: { backgroundColor: event.color ?? "var(--xplat-blue-500)" },
|
|
1194
|
-
title: event.label,
|
|
1195
|
-
onClick: (e) => {
|
|
1196
|
-
e.stopPropagation();
|
|
1197
|
-
onEventClick?.(event);
|
|
1198
|
-
}
|
|
1199
|
-
},
|
|
1200
|
-
ei
|
|
1201
|
-
)),
|
|
1202
|
-
dayEvents.length > 3 && /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)("span", { className: "calendar-event-more", children: [
|
|
1203
|
-
"+",
|
|
1204
|
-
dayEvents.length - 3
|
|
1205
|
-
] })
|
|
1206
|
-
] })
|
|
1207
|
-
]
|
|
1208
|
-
},
|
|
1209
|
-
idx
|
|
1210
|
-
);
|
|
1211
|
-
}) })
|
|
1273
|
+
}) })
|
|
1274
|
+
] })
|
|
1212
1275
|
]
|
|
1213
1276
|
}
|
|
1214
1277
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* src/components/Calendar/calendar.scss */
|
|
2
2
|
.lib-xplat-calendar {
|
|
3
3
|
width: 100%;
|
|
4
|
-
min-width:
|
|
4
|
+
min-width: 200px;
|
|
5
5
|
user-select: none;
|
|
6
6
|
container-type: inline-size;
|
|
7
7
|
}
|
|
@@ -17,6 +17,15 @@
|
|
|
17
17
|
color: var(--xplat-neutral-900);
|
|
18
18
|
min-width: 120px;
|
|
19
19
|
text-align: center;
|
|
20
|
+
background: none;
|
|
21
|
+
border: none;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
padding: 0.25rem 0.5rem;
|
|
24
|
+
border-radius: 0.375rem;
|
|
25
|
+
transition: background-color 0.15s;
|
|
26
|
+
}
|
|
27
|
+
.lib-xplat-calendar .calendar-title:hover {
|
|
28
|
+
background-color: var(--xplat-neutral-100);
|
|
20
29
|
}
|
|
21
30
|
.lib-xplat-calendar .calendar-nav {
|
|
22
31
|
display: flex;
|
|
@@ -106,33 +115,17 @@
|
|
|
106
115
|
color: var(--xplat-neutral-300);
|
|
107
116
|
}
|
|
108
117
|
.lib-xplat-calendar .calendar-day.today .calendar-day-number {
|
|
109
|
-
position: relative;
|
|
110
118
|
font-weight: 700;
|
|
111
119
|
color: var(--xplat-blue-600);
|
|
112
120
|
}
|
|
113
|
-
.lib-xplat-calendar .calendar-day.today .calendar-day-number::before {
|
|
114
|
-
content: "";
|
|
115
|
-
position: absolute;
|
|
116
|
-
top: 50%;
|
|
117
|
-
left: -6px;
|
|
118
|
-
transform: translateY(-50%);
|
|
119
|
-
width: 4px;
|
|
120
|
-
height: 4px;
|
|
121
|
-
border-radius: 50%;
|
|
122
|
-
background-color: var(--xplat-blue-600);
|
|
123
|
-
}
|
|
124
121
|
.lib-xplat-calendar .calendar-day.selected {
|
|
125
|
-
|
|
122
|
+
box-shadow: inset 0 0 0 1.5px var(--calendar-selected-color, var(--xplat-neutral-500));
|
|
126
123
|
}
|
|
127
124
|
.lib-xplat-calendar .calendar-day.selected .calendar-day-number {
|
|
128
|
-
|
|
129
|
-
font-weight: 600;
|
|
125
|
+
font-weight: 700;
|
|
130
126
|
}
|
|
131
127
|
.lib-xplat-calendar .calendar-day.selected:hover {
|
|
132
|
-
background-color: color-mix(in srgb, var(--calendar-selected-color, var(--xplat-neutral-
|
|
133
|
-
}
|
|
134
|
-
.lib-xplat-calendar .calendar-day.selected.today .calendar-day-number::before {
|
|
135
|
-
background-color: var(--xplat-white);
|
|
128
|
+
background-color: color-mix(in srgb, var(--calendar-selected-color, var(--xplat-neutral-500)) 10%, transparent);
|
|
136
129
|
}
|
|
137
130
|
.lib-xplat-calendar .calendar-day.sunday:not(.outside) .calendar-day-number {
|
|
138
131
|
color: var(--xplat-red-500);
|
|
@@ -140,9 +133,6 @@
|
|
|
140
133
|
.lib-xplat-calendar .calendar-day.saturday:not(.outside) .calendar-day-number {
|
|
141
134
|
color: var(--xplat-blue-500);
|
|
142
135
|
}
|
|
143
|
-
.lib-xplat-calendar .calendar-day.selected .calendar-day-number {
|
|
144
|
-
color: var(--xplat-white);
|
|
145
|
-
}
|
|
146
136
|
.lib-xplat-calendar .calendar-day-number {
|
|
147
137
|
font-size: clamp(0.75rem, 2.5cqi, 1rem);
|
|
148
138
|
line-height: 1;
|
|
@@ -166,3 +156,30 @@
|
|
|
166
156
|
color: var(--xplat-neutral-400);
|
|
167
157
|
line-height: 1;
|
|
168
158
|
}
|
|
159
|
+
.lib-xplat-calendar .calendar-picker-grid {
|
|
160
|
+
display: grid;
|
|
161
|
+
grid-template-columns: repeat(3, 1fr);
|
|
162
|
+
gap: 0.5rem;
|
|
163
|
+
padding: 0.5rem 0;
|
|
164
|
+
}
|
|
165
|
+
.lib-xplat-calendar .calendar-picker-cell {
|
|
166
|
+
display: flex;
|
|
167
|
+
align-items: center;
|
|
168
|
+
justify-content: center;
|
|
169
|
+
padding: 0.5rem;
|
|
170
|
+
border: none;
|
|
171
|
+
border-radius: 0.375rem;
|
|
172
|
+
background: none;
|
|
173
|
+
font-size: clamp(0.75rem, 2.5cqi, 0.9375rem);
|
|
174
|
+
color: var(--xplat-neutral-700);
|
|
175
|
+
cursor: pointer;
|
|
176
|
+
transition: background-color 0.15s;
|
|
177
|
+
}
|
|
178
|
+
.lib-xplat-calendar .calendar-picker-cell:hover {
|
|
179
|
+
background-color: var(--xplat-neutral-100);
|
|
180
|
+
}
|
|
181
|
+
.lib-xplat-calendar .calendar-picker-cell.active {
|
|
182
|
+
background-color: var(--xplat-neutral-900);
|
|
183
|
+
color: var(--xplat-white);
|
|
184
|
+
font-weight: 600;
|
|
185
|
+
}
|
|
@@ -29,31 +29,18 @@ interface CalendarEvent {
|
|
|
29
29
|
data?: unknown;
|
|
30
30
|
}
|
|
31
31
|
interface CalendarProps {
|
|
32
|
-
/** 초기 연도 */
|
|
33
32
|
year?: number;
|
|
34
|
-
/** 초기 월 (0-11) */
|
|
35
33
|
month?: number;
|
|
36
|
-
/** 선택된 날짜 */
|
|
37
34
|
selectedDate?: Date | null;
|
|
38
|
-
/** 날짜 선택 콜백 */
|
|
39
35
|
onSelect?: (date: Date) => void;
|
|
40
|
-
/** 월 변경 콜백 */
|
|
41
36
|
onMonthChange?: (year: number, month: number) => void;
|
|
42
|
-
/** 이벤트 목록 */
|
|
43
37
|
events?: CalendarEvent[];
|
|
44
|
-
/** 날짜별 커스텀 렌더 */
|
|
45
38
|
renderDay?: (day: CalendarDay, events: CalendarEvent[]) => React.ReactNode;
|
|
46
|
-
/** 이벤트 클릭 콜백 */
|
|
47
39
|
onEventClick?: (event: CalendarEvent) => void;
|
|
48
|
-
/** 언어 */
|
|
49
40
|
locale?: "ko" | "en";
|
|
50
|
-
/** 최소 선택 가능 날짜 */
|
|
51
41
|
minDate?: Date;
|
|
52
|
-
/** 최대 선택 가능 날짜 */
|
|
53
42
|
maxDate?: Date;
|
|
54
|
-
/** 선택 날짜 색상 (CSS 변수명, 예: "xplat-blue-500") */
|
|
55
43
|
selectedColor?: string;
|
|
56
|
-
/** 오늘 버튼 표시 */
|
|
57
44
|
showToday?: boolean;
|
|
58
45
|
className?: string;
|
|
59
46
|
}
|
|
@@ -29,31 +29,18 @@ interface CalendarEvent {
|
|
|
29
29
|
data?: unknown;
|
|
30
30
|
}
|
|
31
31
|
interface CalendarProps {
|
|
32
|
-
/** 초기 연도 */
|
|
33
32
|
year?: number;
|
|
34
|
-
/** 초기 월 (0-11) */
|
|
35
33
|
month?: number;
|
|
36
|
-
/** 선택된 날짜 */
|
|
37
34
|
selectedDate?: Date | null;
|
|
38
|
-
/** 날짜 선택 콜백 */
|
|
39
35
|
onSelect?: (date: Date) => void;
|
|
40
|
-
/** 월 변경 콜백 */
|
|
41
36
|
onMonthChange?: (year: number, month: number) => void;
|
|
42
|
-
/** 이벤트 목록 */
|
|
43
37
|
events?: CalendarEvent[];
|
|
44
|
-
/** 날짜별 커스텀 렌더 */
|
|
45
38
|
renderDay?: (day: CalendarDay, events: CalendarEvent[]) => React.ReactNode;
|
|
46
|
-
/** 이벤트 클릭 콜백 */
|
|
47
39
|
onEventClick?: (event: CalendarEvent) => void;
|
|
48
|
-
/** 언어 */
|
|
49
40
|
locale?: "ko" | "en";
|
|
50
|
-
/** 최소 선택 가능 날짜 */
|
|
51
41
|
minDate?: Date;
|
|
52
|
-
/** 최대 선택 가능 날짜 */
|
|
53
42
|
maxDate?: Date;
|
|
54
|
-
/** 선택 날짜 색상 (CSS 변수명, 예: "xplat-blue-500") */
|
|
55
43
|
selectedColor?: string;
|
|
56
|
-
/** 오늘 버튼 표시 */
|
|
57
44
|
showToday?: boolean;
|
|
58
45
|
className?: string;
|
|
59
46
|
}
|