@farmzone/fz-react-ui 1.0.1 → 1.0.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/index.cjs +832 -351
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +97 -84
- package/dist/index.d.ts +97 -84
- package/dist/index.js +832 -351
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tw.css +2 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -242,6 +242,32 @@ function TooltipContent({
|
|
|
242
242
|
}
|
|
243
243
|
) });
|
|
244
244
|
}
|
|
245
|
+
|
|
246
|
+
// src/config/zIndex.ts
|
|
247
|
+
var Z_INDEX = {
|
|
248
|
+
TABLE_COL_STICKY: 1,
|
|
249
|
+
TABLE_FIXED_CELL: 5,
|
|
250
|
+
TABLE_FIXED_HEADER_CELL: 10,
|
|
251
|
+
LOCAL_OVERLAY: 10,
|
|
252
|
+
LAYOUT_HEADER: 20,
|
|
253
|
+
DROPDOWN_LOCAL: 20,
|
|
254
|
+
SIDEBAR_CONTAINER: 30,
|
|
255
|
+
SIDEBAR_BACKDROP: 40,
|
|
256
|
+
SIDEBAR: 50,
|
|
257
|
+
DROPDOWN: 50,
|
|
258
|
+
CALENDAR_ANCHORED: 50,
|
|
259
|
+
LOADING_OVERLAY_DEFAULT: 50,
|
|
260
|
+
DRAWING_CANVAS_1: 51,
|
|
261
|
+
DRAWING_CANVAS_2: 52,
|
|
262
|
+
DRAWING: 53,
|
|
263
|
+
MODAL_OVERLAY: 54,
|
|
264
|
+
MODAL: 55,
|
|
265
|
+
CALENDAR_PORTAL: 60,
|
|
266
|
+
TOOLTIP: 70,
|
|
267
|
+
SELECT_CONTENT: 100,
|
|
268
|
+
TOP: 9999,
|
|
269
|
+
MODAL_Z_STEP: 10
|
|
270
|
+
};
|
|
245
271
|
function Tooltip2(props) {
|
|
246
272
|
const {
|
|
247
273
|
children,
|
|
@@ -253,6 +279,7 @@ function Tooltip2(props) {
|
|
|
253
279
|
arrowClassName = "",
|
|
254
280
|
contentClassName = "",
|
|
255
281
|
contentStyle = {},
|
|
282
|
+
containerStyle,
|
|
256
283
|
offsetX = 0,
|
|
257
284
|
offsetY = 2,
|
|
258
285
|
delayDuration = 0,
|
|
@@ -272,7 +299,9 @@ function Tooltip2(props) {
|
|
|
272
299
|
sideOffset,
|
|
273
300
|
collisionPadding: 8,
|
|
274
301
|
style: {
|
|
275
|
-
|
|
302
|
+
zIndex: Z_INDEX.TOOLTIP,
|
|
303
|
+
transform: `translateX(${offsetX}px) translateY(${translateY}px)`,
|
|
304
|
+
...containerStyle
|
|
276
305
|
},
|
|
277
306
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-[5px] break-words whitespace-normal", style: contentStyle, children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: contentClassName, children: [
|
|
278
307
|
content && /* @__PURE__ */ jsxRuntime.jsx("span", { children: content }),
|
|
@@ -943,7 +972,7 @@ var SELECT_BORDER_COLORS = {
|
|
|
943
972
|
};
|
|
944
973
|
function Select2(props) {
|
|
945
974
|
const {
|
|
946
|
-
|
|
975
|
+
containerClassName,
|
|
947
976
|
options,
|
|
948
977
|
placeholder = "\uC120\uD0DD\uD574 \uC8FC\uC138\uC694",
|
|
949
978
|
triggerClassName,
|
|
@@ -973,7 +1002,7 @@ function Select2(props) {
|
|
|
973
1002
|
onChange("");
|
|
974
1003
|
onReset?.();
|
|
975
1004
|
};
|
|
976
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-0.5",
|
|
1005
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-0.5", containerClassName ?? "w-30"), children: [
|
|
977
1006
|
label && /* @__PURE__ */ jsxRuntime.jsx(
|
|
978
1007
|
"label",
|
|
979
1008
|
{
|
|
@@ -1056,6 +1085,7 @@ function Radio(props) {
|
|
|
1056
1085
|
checked,
|
|
1057
1086
|
onChange,
|
|
1058
1087
|
disabled = false,
|
|
1088
|
+
disabledMessage,
|
|
1059
1089
|
checkColor = DEFAULT_CHECK_COLOR,
|
|
1060
1090
|
unCheckColor = DEFAULT_UNCHECK_COLOR,
|
|
1061
1091
|
labelClassName,
|
|
@@ -1104,23 +1134,29 @@ function Radio(props) {
|
|
|
1104
1134
|
}
|
|
1105
1135
|
)
|
|
1106
1136
|
] });
|
|
1137
|
+
const withTooltip = (node) => {
|
|
1138
|
+
if (!disabled || !disabledMessage) return node;
|
|
1139
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Tooltip2, { content: disabledMessage, position: "bottom", asChild: true, sideOffset: 4, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex", children: node }) });
|
|
1140
|
+
};
|
|
1107
1141
|
if (onChange !== void 0 && checked !== void 0) {
|
|
1108
|
-
return
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1142
|
+
return withTooltip(
|
|
1143
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1144
|
+
RadioGroupPrimitive__namespace.Root,
|
|
1145
|
+
{
|
|
1146
|
+
name,
|
|
1147
|
+
value: checked ? value : "",
|
|
1148
|
+
onValueChange: (newValue) => {
|
|
1149
|
+
if (newValue === value) {
|
|
1150
|
+
onChange(value);
|
|
1151
|
+
}
|
|
1152
|
+
},
|
|
1153
|
+
disabled,
|
|
1154
|
+
children: control
|
|
1155
|
+
}
|
|
1156
|
+
)
|
|
1121
1157
|
);
|
|
1122
1158
|
}
|
|
1123
|
-
return control;
|
|
1159
|
+
return withTooltip(control);
|
|
1124
1160
|
}
|
|
1125
1161
|
function RadioGroup(props) {
|
|
1126
1162
|
const {
|
|
@@ -1156,6 +1192,7 @@ function RadioGroup(props) {
|
|
|
1156
1192
|
value: option.value,
|
|
1157
1193
|
label: option.label,
|
|
1158
1194
|
disabled: disabled || option.disabled,
|
|
1195
|
+
disabledMessage: option.disabled ? option.disabledMessage : void 0,
|
|
1159
1196
|
checkColor,
|
|
1160
1197
|
unCheckColor,
|
|
1161
1198
|
labelClassName,
|
|
@@ -1311,31 +1348,6 @@ function Spinner(props) {
|
|
|
1311
1348
|
}
|
|
1312
1349
|
);
|
|
1313
1350
|
}
|
|
1314
|
-
|
|
1315
|
-
// src/config/zIndex.ts
|
|
1316
|
-
var Z_INDEX = {
|
|
1317
|
-
TABLE_COL_STICKY: 1,
|
|
1318
|
-
TABLE_FIXED_CELL: 5,
|
|
1319
|
-
TABLE_FIXED_HEADER_CELL: 10,
|
|
1320
|
-
LOCAL_OVERLAY: 10,
|
|
1321
|
-
LAYOUT_HEADER: 20,
|
|
1322
|
-
DROPDOWN_LOCAL: 20,
|
|
1323
|
-
SIDEBAR_CONTAINER: 30,
|
|
1324
|
-
SIDEBAR_BACKDROP: 40,
|
|
1325
|
-
SIDEBAR: 50,
|
|
1326
|
-
DROPDOWN: 50,
|
|
1327
|
-
CALENDAR_ANCHORED: 50,
|
|
1328
|
-
LOADING_OVERLAY_DEFAULT: 50,
|
|
1329
|
-
DRAWING_CANVAS_1: 51,
|
|
1330
|
-
DRAWING_CANVAS_2: 52,
|
|
1331
|
-
DRAWING: 53,
|
|
1332
|
-
MODAL_OVERLAY: 54,
|
|
1333
|
-
MODAL: 55,
|
|
1334
|
-
CALENDAR_PORTAL: 60,
|
|
1335
|
-
SELECT_CONTENT: 100,
|
|
1336
|
-
TOP: 9999,
|
|
1337
|
-
MODAL_Z_STEP: 10
|
|
1338
|
-
};
|
|
1339
1351
|
function LoadingOverlay(props) {
|
|
1340
1352
|
const {
|
|
1341
1353
|
isVisible,
|
|
@@ -1950,16 +1962,43 @@ function ToastProvider() {
|
|
|
1950
1962
|
}
|
|
1951
1963
|
|
|
1952
1964
|
// src/components/DatePicker/config/utils.ts
|
|
1965
|
+
function makeLocalDate(year, monthIndex, day) {
|
|
1966
|
+
const d = /* @__PURE__ */ new Date(0);
|
|
1967
|
+
d.setFullYear(year, monthIndex, day);
|
|
1968
|
+
return d;
|
|
1969
|
+
}
|
|
1953
1970
|
function parseLocalYmd(ymd) {
|
|
1954
1971
|
const m = ymd.trim().match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
1955
1972
|
if (!m) return null;
|
|
1956
1973
|
const y = Number(m[1]);
|
|
1957
1974
|
const mo = Number(m[2]) - 1;
|
|
1958
1975
|
const d = Number(m[3]);
|
|
1959
|
-
const dt =
|
|
1976
|
+
const dt = makeLocalDate(y, mo, d);
|
|
1960
1977
|
if (dt.getFullYear() !== y || dt.getMonth() !== mo || dt.getDate() !== d) return null;
|
|
1961
1978
|
return dt;
|
|
1962
1979
|
}
|
|
1980
|
+
function canSelectToday(options) {
|
|
1981
|
+
const today = options.now ?? /* @__PURE__ */ new Date();
|
|
1982
|
+
const todayYmd = formatDate(today);
|
|
1983
|
+
if (options.maxDate && isCalendarDayAfterMax(today, options.maxDate)) {
|
|
1984
|
+
return false;
|
|
1985
|
+
}
|
|
1986
|
+
if (!options.range) {
|
|
1987
|
+
return true;
|
|
1988
|
+
}
|
|
1989
|
+
if (options.isSelectingEnd) {
|
|
1990
|
+
const start = options.rangeStart?.trim() ?? "";
|
|
1991
|
+
if (start.length === 10 && todayYmd < start) {
|
|
1992
|
+
return false;
|
|
1993
|
+
}
|
|
1994
|
+
return true;
|
|
1995
|
+
}
|
|
1996
|
+
const end = options.rangeEnd?.trim() ?? "";
|
|
1997
|
+
if (end.length === 10 && todayYmd > end) {
|
|
1998
|
+
return false;
|
|
1999
|
+
}
|
|
2000
|
+
return true;
|
|
2001
|
+
}
|
|
1963
2002
|
function isCalendarDayAfterMax(date, maxYmd) {
|
|
1964
2003
|
const max = parseLocalYmd(maxYmd);
|
|
1965
2004
|
if (!max) return false;
|
|
@@ -1968,7 +2007,7 @@ function isCalendarDayAfterMax(date, maxYmd) {
|
|
|
1968
2007
|
return ax > bx;
|
|
1969
2008
|
}
|
|
1970
2009
|
function formatDate(date) {
|
|
1971
|
-
const year = date.getFullYear();
|
|
2010
|
+
const year = String(date.getFullYear()).padStart(4, "0");
|
|
1972
2011
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
1973
2012
|
const day = String(date.getDate()).padStart(2, "0");
|
|
1974
2013
|
return `${year}-${month}-${day}`;
|
|
@@ -1987,7 +2026,6 @@ function validateAndFormatInput(input) {
|
|
|
1987
2026
|
if (numbers.length === 0) return "";
|
|
1988
2027
|
const clampYear = (raw) => {
|
|
1989
2028
|
const n = parseInt(raw, 10);
|
|
1990
|
-
if (n < 1) return "0001";
|
|
1991
2029
|
if (n > 9999) return "9999";
|
|
1992
2030
|
return raw;
|
|
1993
2031
|
};
|
|
@@ -2010,12 +2048,111 @@ function validateAndFormatInput(input) {
|
|
|
2010
2048
|
let day = dayRaw;
|
|
2011
2049
|
if (day.length === 2) {
|
|
2012
2050
|
const dayNum = parseInt(day, 10);
|
|
2013
|
-
const lastDayOfMonth =
|
|
2051
|
+
const lastDayOfMonth = makeLocalDate(parseInt(year, 10), parseInt(month, 10), 0).getDate();
|
|
2014
2052
|
if (dayNum < 1) day = "01";
|
|
2015
2053
|
else if (dayNum > lastDayOfMonth) day = lastDayOfMonth.toString().padStart(2, "0");
|
|
2016
2054
|
}
|
|
2017
2055
|
return `${year}-${month}-${day}`;
|
|
2018
2056
|
}
|
|
2057
|
+
|
|
2058
|
+
// src/components/DatePicker/calendar/config/default.ts
|
|
2059
|
+
var DEFAULT_CALENDAR_YEAR_HALF_SPAN = 50;
|
|
2060
|
+
var CALENDAR_WEEKDAY_LABELS = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
|
|
2061
|
+
var CALENDAR_RANGE_HINT = {
|
|
2062
|
+
start: "\uC2DC\uC791 \uB0A0\uC9DC\uB97C \uC120\uD0DD\uD558\uC138\uC694",
|
|
2063
|
+
end: "\uC885\uB8CC \uB0A0\uC9DC\uB97C \uC120\uD0DD\uD558\uC138\uC694"
|
|
2064
|
+
};
|
|
2065
|
+
var CALENDAR_PORTAL_Z_INDEX = Z_INDEX.CALENDAR_PORTAL;
|
|
2066
|
+
var CALENDAR_SELECT_CLASSNAMES = {
|
|
2067
|
+
containerClass: "w-20 shrink-0",
|
|
2068
|
+
triggerClassName: "h-8 px-2 py-1 text-sm cursor-pointer",
|
|
2069
|
+
contentClassName: "min-w-[5rem]"
|
|
2070
|
+
};
|
|
2071
|
+
var CALENDAR_PANEL_BASE_CLASS = "bg-white border border-gray-300 rounded-lg shadow-lg p-3 min-w-[280px]";
|
|
2072
|
+
var CALENDAR_PANEL_ANCHORED_CLASS = `${CALENDAR_PANEL_BASE_CLASS} absolute z-50`;
|
|
2073
|
+
var YEAR_SELECT_CONTENT_EXTRA_CLASS = "year-select-content custom-view-scrollbar max-h-50 overflow-y-auto";
|
|
2074
|
+
var YEAR_SELECT_OPEN_CONTENT_SELECTOR = ".year-select-content[data-state='open']";
|
|
2075
|
+
var SELECT_ITEM_CHECKED_SELECTOR = "[data-slot='select-item'][data-state='checked']";
|
|
2076
|
+
|
|
2077
|
+
// src/components/DatePicker/calendar/config/calendar.ts
|
|
2078
|
+
function parseYmdDateString(value) {
|
|
2079
|
+
if (value.length !== 10) return null;
|
|
2080
|
+
return parseLocalYmd(value);
|
|
2081
|
+
}
|
|
2082
|
+
function resolveCalendarYearBounds(anchorYear, calendarYearRange) {
|
|
2083
|
+
const fallbackMin = Math.max(0, anchorYear - DEFAULT_CALENDAR_YEAR_HALF_SPAN);
|
|
2084
|
+
const fallbackMax = anchorYear + DEFAULT_CALENDAR_YEAR_HALF_SPAN;
|
|
2085
|
+
const rawMin = calendarYearRange?.minYear?.trim();
|
|
2086
|
+
const rawMax = calendarYearRange?.maxYear?.trim();
|
|
2087
|
+
if (rawMin === void 0 || rawMin === "" || rawMax === void 0 || rawMax === "") {
|
|
2088
|
+
return { minYear: fallbackMin, maxYear: fallbackMax };
|
|
2089
|
+
}
|
|
2090
|
+
const minParsed = Number.parseInt(rawMin, 10);
|
|
2091
|
+
const maxParsed = Number.parseInt(rawMax, 10);
|
|
2092
|
+
if (Number.isNaN(minParsed) || Number.isNaN(maxParsed) || minParsed > maxParsed) {
|
|
2093
|
+
return { minYear: fallbackMin, maxYear: fallbackMax };
|
|
2094
|
+
}
|
|
2095
|
+
return { minYear: Math.max(0, minParsed), maxYear: maxParsed };
|
|
2096
|
+
}
|
|
2097
|
+
function buildCalendarYearSelectOptions(maxDate, anchorYear = (/* @__PURE__ */ new Date()).getFullYear(), calendarYearRange) {
|
|
2098
|
+
const { minYear, maxYear } = resolveCalendarYearBounds(anchorYear, calendarYearRange);
|
|
2099
|
+
const maxSelectableYear = maxDate ? parseLocalYmd(maxDate)?.getFullYear() ?? null : null;
|
|
2100
|
+
const options = [];
|
|
2101
|
+
for (let y = maxYear; y >= minYear; y--) {
|
|
2102
|
+
options.push({
|
|
2103
|
+
value: String(y),
|
|
2104
|
+
label: `${String(y).padStart(4, "0")}\uB144`,
|
|
2105
|
+
disabled: maxSelectableYear !== null && y > maxSelectableYear
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2108
|
+
return options;
|
|
2109
|
+
}
|
|
2110
|
+
function buildCalendarMonthSelectOptions(viewYear, maxDate) {
|
|
2111
|
+
const maxDateParsed = maxDate ? parseLocalYmd(maxDate) : null;
|
|
2112
|
+
const maxYear = maxDateParsed?.getFullYear() ?? null;
|
|
2113
|
+
const maxMonth = maxDateParsed !== null && maxDateParsed !== void 0 ? maxDateParsed.getMonth() + 1 : null;
|
|
2114
|
+
const isMaxYear = maxYear !== null && viewYear === maxYear;
|
|
2115
|
+
const options = [];
|
|
2116
|
+
for (let m = 1; m <= 12; m++) {
|
|
2117
|
+
options.push({
|
|
2118
|
+
value: String(m),
|
|
2119
|
+
label: `${m}\uC6D4`,
|
|
2120
|
+
disabled: isMaxYear && maxMonth !== null && m > maxMonth
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2123
|
+
return options;
|
|
2124
|
+
}
|
|
2125
|
+
function getCalendarMonthGrid(year, monthIndex) {
|
|
2126
|
+
const firstDay = makeLocalDate(year, monthIndex, 1);
|
|
2127
|
+
const daysInMonth = makeLocalDate(year, monthIndex + 1, 0).getDate();
|
|
2128
|
+
const leadingEmpty = firstDay.getDay();
|
|
2129
|
+
const totalCells = leadingEmpty + daysInMonth;
|
|
2130
|
+
const trailingEmpty = totalCells % 7 === 0 ? 0 : 7 - totalCells % 7;
|
|
2131
|
+
return { leadingEmpty, daysInMonth, trailingEmpty };
|
|
2132
|
+
}
|
|
2133
|
+
function disableNextCalendarMonth(year, monthIndex, maxDate) {
|
|
2134
|
+
if (maxDate === void 0) return false;
|
|
2135
|
+
return isCalendarDayAfterMax(makeLocalDate(year, monthIndex + 1, 1), maxDate);
|
|
2136
|
+
}
|
|
2137
|
+
function scrollOpenYearSelectCheckedIntoView() {
|
|
2138
|
+
requestAnimationFrame(() => {
|
|
2139
|
+
const root2 = document.querySelector(YEAR_SELECT_OPEN_CONTENT_SELECTOR);
|
|
2140
|
+
if (!(root2 instanceof HTMLElement)) return;
|
|
2141
|
+
const checkedItem = root2.querySelector(SELECT_ITEM_CHECKED_SELECTOR);
|
|
2142
|
+
if (!(checkedItem instanceof HTMLElement)) return;
|
|
2143
|
+
checkedItem.scrollIntoView({ block: "start" });
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
2146
|
+
function dayCellButtonClass(opts) {
|
|
2147
|
+
const { isToday, isSelected, isInRange, isRangeStart, isRangeEnd, interactiveDisabled } = opts;
|
|
2148
|
+
const parts = ["w-8 h-8 text-sm flex items-center justify-center rounded-2xl transition-colors"];
|
|
2149
|
+
if (isToday) parts.push("bg-gray-100");
|
|
2150
|
+
if (isSelected && !isToday) parts.push("bg-neutral-200 text-gray-700");
|
|
2151
|
+
if (isInRange && !isToday) parts.push("bg-gray-100/90");
|
|
2152
|
+
if ((isRangeStart || isRangeEnd) && !isToday) parts.push("bg-neutral-300 text-gray-700 opacity-100");
|
|
2153
|
+
parts.push(interactiveDisabled ? "opacity-20 cursor-not-allowed" : "hover:bg-blue-100 cursor-pointer");
|
|
2154
|
+
return parts.filter(Boolean).join(" ").trim();
|
|
2155
|
+
}
|
|
2019
2156
|
function RenderCalendar(props) {
|
|
2020
2157
|
const {
|
|
2021
2158
|
currentDate,
|
|
@@ -2030,133 +2167,163 @@ function RenderCalendar(props) {
|
|
|
2030
2167
|
goToNextMonth,
|
|
2031
2168
|
onYearChange,
|
|
2032
2169
|
onMonthChange,
|
|
2170
|
+
onSelectOpenChange,
|
|
2033
2171
|
editDateSelect = true,
|
|
2034
2172
|
datePosition = "bottom",
|
|
2035
|
-
|
|
2173
|
+
maxDate,
|
|
2174
|
+
calendarYearRange,
|
|
2175
|
+
calendarSelectContainerClass,
|
|
2176
|
+
floating = false,
|
|
2177
|
+
showTodayButton = true
|
|
2036
2178
|
} = props;
|
|
2037
2179
|
const year = currentDate.getFullYear();
|
|
2038
|
-
const
|
|
2039
|
-
const
|
|
2040
|
-
const
|
|
2041
|
-
const
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
const
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
}
|
|
2049
|
-
const lastDay = new Date(year, month + 1, 0);
|
|
2050
|
-
const startDate = new Date(firstDay);
|
|
2051
|
-
startDate.setDate(startDate.getDate() - firstDay.getDay());
|
|
2052
|
-
const endDate = new Date(lastDay);
|
|
2053
|
-
endDate.setDate(endDate.getDate() + (6 - endDate.getDay()));
|
|
2054
|
-
const totalDays = Math.ceil((endDate.getTime() - startDate.getTime()) / (1e3 * 60 * 60 * 24)) + 1;
|
|
2180
|
+
const monthIndex = currentDate.getMonth();
|
|
2181
|
+
const anchorYear = year;
|
|
2182
|
+
const disableNextMonth = disableNextCalendarMonth(year, monthIndex, maxDate);
|
|
2183
|
+
const { leadingEmpty, daysInMonth, trailingEmpty } = getCalendarMonthGrid(year, monthIndex);
|
|
2184
|
+
const yearOptions = buildCalendarYearSelectOptions(maxDate, anchorYear, calendarYearRange);
|
|
2185
|
+
const monthOptions = buildCalendarMonthSelectOptions(year, maxDate);
|
|
2186
|
+
const todayFormatted = formatDate(/* @__PURE__ */ new Date());
|
|
2187
|
+
const selectedSingleYmd = range ? null : inputValue;
|
|
2188
|
+
const rangeStartYmd = rangeStart.trim();
|
|
2189
|
+
const rangeEndYmd = rangeEnd.trim();
|
|
2055
2190
|
const days = [];
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
for (let i = 0; i < totalDays; i++) {
|
|
2062
|
-
const date = new Date(startDate);
|
|
2063
|
-
date.setDate(startDate.getDate() + i);
|
|
2191
|
+
for (let i = 0; i < leadingEmpty; i++) {
|
|
2192
|
+
days.push(/* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-8", "aria-hidden": true }, `lead-${i}`));
|
|
2193
|
+
}
|
|
2194
|
+
for (let d = 1; d <= daysInMonth; d++) {
|
|
2195
|
+
const date = makeLocalDate(year, monthIndex, d);
|
|
2064
2196
|
const dateFormatted = formatDate(date);
|
|
2065
|
-
const isToday = dateFormatted ===
|
|
2066
|
-
const isSelected = dateFormatted ===
|
|
2197
|
+
const isToday = dateFormatted === todayFormatted;
|
|
2198
|
+
const isSelected = dateFormatted === selectedSingleYmd;
|
|
2067
2199
|
const isInRange = isDateInRange(date, range, rangeStart, rangeEnd);
|
|
2068
|
-
const
|
|
2069
|
-
const
|
|
2070
|
-
const
|
|
2071
|
-
const
|
|
2072
|
-
|
|
2073
|
-
const
|
|
2200
|
+
const isRangeStartFlag = Boolean(range && dateFormatted === rangeStart);
|
|
2201
|
+
const isRangeEndFlag = Boolean(range && dateFormatted === rangeEnd);
|
|
2202
|
+
const isBeforeRangeStart = range && isSelectingEnd && rangeStartYmd.length === 10 && dateFormatted < rangeStartYmd;
|
|
2203
|
+
const isAfterRangeEnd = range && !isSelectingEnd && rangeEndYmd.length === 10 && dateFormatted > rangeEndYmd;
|
|
2204
|
+
const isGreyedForRange = Boolean(isBeforeRangeStart || isAfterRangeEnd);
|
|
2205
|
+
const isPastMax = maxDate ? isCalendarDayAfterMax(date, maxDate) : false;
|
|
2074
2206
|
days.push(
|
|
2075
2207
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2076
2208
|
"button",
|
|
2077
2209
|
{
|
|
2210
|
+
type: "button",
|
|
2078
2211
|
onClick: () => handleDateSelect(date),
|
|
2079
|
-
disabled:
|
|
2080
|
-
className:
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
children: date.getDate()
|
|
2212
|
+
disabled: isGreyedForRange || isPastMax,
|
|
2213
|
+
className: dayCellButtonClass({
|
|
2214
|
+
isToday,
|
|
2215
|
+
isSelected: Boolean(isSelected),
|
|
2216
|
+
isInRange,
|
|
2217
|
+
isRangeStart: isRangeStartFlag,
|
|
2218
|
+
isRangeEnd: isRangeEndFlag,
|
|
2219
|
+
interactiveDisabled: isGreyedForRange || isPastMax
|
|
2220
|
+
}),
|
|
2221
|
+
children: d
|
|
2090
2222
|
},
|
|
2091
|
-
|
|
2223
|
+
d
|
|
2092
2224
|
)
|
|
2093
2225
|
);
|
|
2094
2226
|
}
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2227
|
+
for (let i = 0; i < trailingEmpty; i++) {
|
|
2228
|
+
days.push(/* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-8", "aria-hidden": true }, `trail-${i}`));
|
|
2229
|
+
}
|
|
2230
|
+
const calendarPositionClass = !floating && range && calendarPosition === "end" ? "right-0" : !floating ? "left-0" : "";
|
|
2231
|
+
const datePositionClass = floating ? "" : datePosition === "top" ? "bottom-full mb-1" : "top-full mt-1";
|
|
2232
|
+
const panelClass = floating ? CALENDAR_PANEL_BASE_CLASS : cn(CALENDAR_PANEL_ANCHORED_CLASS, datePositionClass, calendarPositionClass);
|
|
2233
|
+
const handleYearSelectOpenChange = (open) => {
|
|
2234
|
+
onSelectOpenChange?.(open);
|
|
2235
|
+
if (open) scrollOpenYearSelectCheckedIntoView();
|
|
2236
|
+
};
|
|
2237
|
+
const sel = CALENDAR_SELECT_CLASSNAMES;
|
|
2238
|
+
const containerClass = cn(sel.containerClass, calendarSelectContainerClass);
|
|
2239
|
+
const stopBubble = (e) => e.stopPropagation();
|
|
2240
|
+
const isTodaySelectable = canSelectToday({
|
|
2241
|
+
maxDate,
|
|
2242
|
+
range,
|
|
2243
|
+
isSelectingEnd,
|
|
2244
|
+
rangeStart,
|
|
2245
|
+
rangeEnd
|
|
2246
|
+
});
|
|
2247
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: panelClass, onClick: stopBubble, onMouseDown: stopBubble, children: [
|
|
2248
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1 flex items-center justify-between", children: [
|
|
2249
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2250
|
+
"button",
|
|
2251
|
+
{
|
|
2252
|
+
type: "button",
|
|
2253
|
+
onClick: goToPreviousMonth,
|
|
2254
|
+
className: "cursor-pointer rounded p-1 hover:bg-gray-100",
|
|
2255
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "size-4" })
|
|
2256
|
+
}
|
|
2257
|
+
),
|
|
2258
|
+
editDateSelect ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2259
|
+
"div",
|
|
2260
|
+
{
|
|
2261
|
+
role: "presentation",
|
|
2262
|
+
className: "flex items-center gap-2",
|
|
2263
|
+
onClick: stopBubble,
|
|
2264
|
+
onMouseDown: stopBubble,
|
|
2265
|
+
children: [
|
|
2266
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2267
|
+
Select2,
|
|
2268
|
+
{
|
|
2269
|
+
value: year.toString(),
|
|
2270
|
+
options: yearOptions,
|
|
2271
|
+
onChange: (value) => onYearChange(Number.parseInt(value, 10)),
|
|
2272
|
+
containerClassName: containerClass,
|
|
2273
|
+
triggerClassName: sel.triggerClassName,
|
|
2274
|
+
contentClassName: cn(YEAR_SELECT_CONTENT_EXTRA_CLASS, sel.contentClassName),
|
|
2275
|
+
disableScrollButtonEvents: true,
|
|
2276
|
+
onOpenChange: handleYearSelectOpenChange
|
|
2277
|
+
}
|
|
2278
|
+
),
|
|
2279
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2280
|
+
Select2,
|
|
2281
|
+
{
|
|
2282
|
+
value: (monthIndex + 1).toString(),
|
|
2283
|
+
options: monthOptions,
|
|
2284
|
+
onChange: (value) => onMonthChange(Number.parseInt(value, 10) - 1),
|
|
2285
|
+
containerClassName: containerClass,
|
|
2286
|
+
triggerClassName: sel.triggerClassName,
|
|
2287
|
+
contentClassName: sel.contentClassName,
|
|
2288
|
+
onOpenChange: (open) => onSelectOpenChange?.(open)
|
|
2289
|
+
}
|
|
2290
|
+
)
|
|
2291
|
+
]
|
|
2292
|
+
}
|
|
2293
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "text-lg font-semibold", children: [
|
|
2294
|
+
String(year).padStart(4, "0"),
|
|
2295
|
+
"\uB144 ",
|
|
2296
|
+
monthIndex + 1,
|
|
2297
|
+
"\uC6D4"
|
|
2298
|
+
] }),
|
|
2299
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2300
|
+
"button",
|
|
2301
|
+
{
|
|
2302
|
+
type: "button",
|
|
2303
|
+
onClick: goToNextMonth,
|
|
2304
|
+
disabled: disableNextMonth,
|
|
2305
|
+
className: cn(
|
|
2306
|
+
"rounded p-1",
|
|
2307
|
+
disableNextMonth ? "cursor-not-allowed opacity-30" : "cursor-pointer hover:bg-gray-100"
|
|
2308
|
+
),
|
|
2309
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-4" })
|
|
2310
|
+
}
|
|
2311
|
+
)
|
|
2312
|
+
] }),
|
|
2313
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 grid grid-cols-7 gap-1", children: CALENDAR_WEEKDAY_LABELS.map((day) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2 text-center text-sm font-medium text-gray-500", children: day }, day)) }),
|
|
2314
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 gap-2", children: days }),
|
|
2315
|
+
range && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 text-sm text-gray-600", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center", children: isSelectingEnd ? CALENDAR_RANGE_HINT.end : CALENDAR_RANGE_HINT.start }) }),
|
|
2316
|
+
showTodayButton && isTodaySelectable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "-mx-3 -mb-3 mt-3 flex items-center justify-center border-t border-gray-200 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2317
|
+
"button",
|
|
2318
|
+
{
|
|
2319
|
+
type: "button",
|
|
2320
|
+
onClick: () => handleDateSelect(/* @__PURE__ */ new Date()),
|
|
2321
|
+
className: "cursor-pointer text-sm text-gray-800 hover:text-main",
|
|
2322
|
+
children: "Today"
|
|
2323
|
+
}
|
|
2324
|
+
) })
|
|
2325
|
+
] });
|
|
2157
2326
|
}
|
|
2158
|
-
|
|
2159
|
-
// src/components/DatePicker/calendar/hooks/useCalendarState.ts
|
|
2160
2327
|
function useCalendarState(props) {
|
|
2161
2328
|
const { datePosition = "bottom", disabled = false, calendarRef } = props;
|
|
2162
2329
|
const [isCalendarOpen, setIsCalendarOpen] = React6.useState(false);
|
|
@@ -2205,16 +2372,16 @@ function useCalendarState(props) {
|
|
|
2205
2372
|
setIsCalendarOpen(false);
|
|
2206
2373
|
};
|
|
2207
2374
|
const goToPreviousMonth = () => {
|
|
2208
|
-
setCurrentDate(
|
|
2375
|
+
setCurrentDate(makeLocalDate(currentDate.getFullYear(), currentDate.getMonth() - 1, 1));
|
|
2209
2376
|
};
|
|
2210
2377
|
const goToNextMonth = () => {
|
|
2211
|
-
setCurrentDate(
|
|
2378
|
+
setCurrentDate(makeLocalDate(currentDate.getFullYear(), currentDate.getMonth() + 1, 1));
|
|
2212
2379
|
};
|
|
2213
2380
|
const handleYearChange = (year) => {
|
|
2214
|
-
setCurrentDate(
|
|
2381
|
+
setCurrentDate(makeLocalDate(year, currentDate.getMonth(), 1));
|
|
2215
2382
|
};
|
|
2216
2383
|
const handleMonthChange = (month) => {
|
|
2217
|
-
setCurrentDate(
|
|
2384
|
+
setCurrentDate(makeLocalDate(currentDate.getFullYear(), month, 1));
|
|
2218
2385
|
};
|
|
2219
2386
|
return {
|
|
2220
2387
|
isCalendarOpen,
|
|
@@ -2253,11 +2420,15 @@ function useFloatingCalendarPosition(anchorRef, isOpen2, placement, align = "sta
|
|
|
2253
2420
|
setStyle({ ...base, top: rect.bottom + CALENDAR_GAP });
|
|
2254
2421
|
}
|
|
2255
2422
|
};
|
|
2423
|
+
const handleScroll = (e) => {
|
|
2424
|
+
if (e.target?.closest?.('[data-slot="select-content"]')) return;
|
|
2425
|
+
update();
|
|
2426
|
+
};
|
|
2256
2427
|
update();
|
|
2257
|
-
window.addEventListener("scroll",
|
|
2428
|
+
window.addEventListener("scroll", handleScroll, true);
|
|
2258
2429
|
window.addEventListener("resize", update);
|
|
2259
2430
|
return () => {
|
|
2260
|
-
window.removeEventListener("scroll",
|
|
2431
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
2261
2432
|
window.removeEventListener("resize", update);
|
|
2262
2433
|
};
|
|
2263
2434
|
}, [isOpen2, placement, align, anchorRef]);
|
|
@@ -2337,6 +2508,7 @@ function DatePickerRange(props) {
|
|
|
2337
2508
|
return;
|
|
2338
2509
|
}
|
|
2339
2510
|
onRangeChange?.(formatted, endInputValue);
|
|
2511
|
+
if (isCalendarOpen && calendarPosition === "start") navigateToDateValue(formatted);
|
|
2340
2512
|
} else if (formatted.length === 0) {
|
|
2341
2513
|
onRangeChange?.(formatted, endInputValue);
|
|
2342
2514
|
}
|
|
@@ -2350,6 +2522,7 @@ function DatePickerRange(props) {
|
|
|
2350
2522
|
return;
|
|
2351
2523
|
}
|
|
2352
2524
|
onRangeChange?.(startInputValue, formatted);
|
|
2525
|
+
if (isCalendarOpen && calendarPosition === "end") navigateToDateValue(formatted);
|
|
2353
2526
|
} else if (formatted.length === 0) {
|
|
2354
2527
|
onRangeChange?.(startInputValue, formatted);
|
|
2355
2528
|
}
|
|
@@ -2524,6 +2697,7 @@ function DatePickerSingle(props) {
|
|
|
2524
2697
|
autoDatePosition,
|
|
2525
2698
|
containerRef,
|
|
2526
2699
|
toggleCalendar,
|
|
2700
|
+
navigateToDateValue,
|
|
2527
2701
|
closeCalendar,
|
|
2528
2702
|
goToPreviousMonth,
|
|
2529
2703
|
goToNextMonth,
|
|
@@ -2541,7 +2715,7 @@ function DatePickerSingle(props) {
|
|
|
2541
2715
|
const dateMatch = formatted.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
2542
2716
|
if (dateMatch) {
|
|
2543
2717
|
const [, year, month, day] = dateMatch;
|
|
2544
|
-
const date =
|
|
2718
|
+
const date = makeLocalDate(
|
|
2545
2719
|
Number.parseInt(year, 10),
|
|
2546
2720
|
Number.parseInt(month, 10) - 1,
|
|
2547
2721
|
Number.parseInt(day, 10)
|
|
@@ -2553,6 +2727,7 @@ function DatePickerSingle(props) {
|
|
|
2553
2727
|
return;
|
|
2554
2728
|
}
|
|
2555
2729
|
onChange?.(formatted);
|
|
2730
|
+
if (isCalendarOpen) navigateToDateValue(formatted);
|
|
2556
2731
|
}
|
|
2557
2732
|
}
|
|
2558
2733
|
} else {
|
|
@@ -3489,9 +3664,10 @@ function ConfirmModal(props) {
|
|
|
3489
3664
|
] }),
|
|
3490
3665
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-8 items-center justify-end gap-2", children: [
|
|
3491
3666
|
!isHideOkButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3492
|
-
|
|
3667
|
+
DebouncedButton,
|
|
3493
3668
|
{
|
|
3494
3669
|
ref: okButtonRef,
|
|
3670
|
+
debounceDelay: 500,
|
|
3495
3671
|
variant: "outline",
|
|
3496
3672
|
onClick: handleOkClick,
|
|
3497
3673
|
className: "focus-visible:ring-2 focus-visible:ring-blue-400 focus-visible:ring-offset-1",
|
|
@@ -6565,7 +6741,7 @@ function CascadingSelectFieldInner(props) {
|
|
|
6565
6741
|
disabled,
|
|
6566
6742
|
hasError,
|
|
6567
6743
|
options: toSelectOptions(primaryOptions),
|
|
6568
|
-
|
|
6744
|
+
containerClassName: firstSelectClass.containerClassName,
|
|
6569
6745
|
triggerClassName: firstSelectClass.triggerClassName,
|
|
6570
6746
|
canReset: true,
|
|
6571
6747
|
onChange: (nextPrimary) => {
|
|
@@ -6582,7 +6758,7 @@ function CascadingSelectFieldInner(props) {
|
|
|
6582
6758
|
disabled: disabled || !primary || secondaryOptions.length === 0,
|
|
6583
6759
|
hasError,
|
|
6584
6760
|
options: toSelectOptions(secondaryOptions),
|
|
6585
|
-
|
|
6761
|
+
containerClassName: secondSelectClass.containerClassName,
|
|
6586
6762
|
triggerClassName: secondSelectClass.triggerClassName,
|
|
6587
6763
|
canReset: true,
|
|
6588
6764
|
onChange: (nextSecondary) => {
|
|
@@ -6626,7 +6802,8 @@ function DateField(props) {
|
|
|
6626
6802
|
readOnly = false,
|
|
6627
6803
|
className = "w-40",
|
|
6628
6804
|
datePosition = "bottom",
|
|
6629
|
-
disableFutureDates = false
|
|
6805
|
+
disableFutureDates = false,
|
|
6806
|
+
calendarSelectContainerClass = "w-20"
|
|
6630
6807
|
} = config;
|
|
6631
6808
|
const maxDate = disableFutureDates ? formatDate(/* @__PURE__ */ new Date()) : void 0;
|
|
6632
6809
|
if (readOnly) {
|
|
@@ -6643,7 +6820,8 @@ function DateField(props) {
|
|
|
6643
6820
|
className: "w-full",
|
|
6644
6821
|
validation: hasError,
|
|
6645
6822
|
datePosition,
|
|
6646
|
-
maxDate
|
|
6823
|
+
maxDate,
|
|
6824
|
+
calendarSelectContainerClass
|
|
6647
6825
|
}
|
|
6648
6826
|
) });
|
|
6649
6827
|
}
|
|
@@ -6833,7 +7011,9 @@ function RadioField(props) {
|
|
|
6833
7011
|
containerClassName: cn2("justify-start", fieldControlWrapClass(className)),
|
|
6834
7012
|
options: options.map((option) => ({
|
|
6835
7013
|
label: option.label,
|
|
6836
|
-
value: String(option.value)
|
|
7014
|
+
value: String(option.value),
|
|
7015
|
+
disabled: option.disabled,
|
|
7016
|
+
disabledMessage: option.disabledMessage
|
|
6837
7017
|
}))
|
|
6838
7018
|
}
|
|
6839
7019
|
);
|
|
@@ -6871,7 +7051,7 @@ function SelectField(props) {
|
|
|
6871
7051
|
disabled,
|
|
6872
7052
|
hasError,
|
|
6873
7053
|
options: selectOptions,
|
|
6874
|
-
|
|
7054
|
+
containerClassName: "flex w-full min-w-0 max-w-full items-center",
|
|
6875
7055
|
className: "w-full min-w-0",
|
|
6876
7056
|
triggerClassName: cn2(
|
|
6877
7057
|
"h-8 w-full min-w-0 max-w-full rounded border bg-white px-2 py-1 text-sm shadow-none",
|
|
@@ -6983,11 +7163,12 @@ function SelectWithInputField(props) {
|
|
|
6983
7163
|
disabled,
|
|
6984
7164
|
hasError,
|
|
6985
7165
|
options: toSelectOptions(options),
|
|
6986
|
-
|
|
7166
|
+
containerClassName: selectClass.containerClassName,
|
|
6987
7167
|
triggerClassName: selectClass.triggerClassName,
|
|
6988
7168
|
onChange: (nextPrefix) => {
|
|
6989
7169
|
setSelectedPrefix(nextPrefix);
|
|
6990
7170
|
updateCombined(nextPrefix, inputPart);
|
|
7171
|
+
onBlur();
|
|
6991
7172
|
}
|
|
6992
7173
|
}
|
|
6993
7174
|
),
|
|
@@ -7122,7 +7303,7 @@ function useBlurValidation(name, options) {
|
|
|
7122
7303
|
(value, fieldOnChange) => {
|
|
7123
7304
|
markHadValueIfFilled(value);
|
|
7124
7305
|
fieldOnChange(value);
|
|
7125
|
-
if (options.revalidateOnChange || shouldValidateEmptyOnChange(value)) {
|
|
7306
|
+
if (options.revalidateOnChange || options.validateEmptyOnChange && shouldValidateEmptyOnChange(value)) {
|
|
7126
7307
|
void trigger(name);
|
|
7127
7308
|
}
|
|
7128
7309
|
void triggerRelatedFields();
|
|
@@ -7130,6 +7311,7 @@ function useBlurValidation(name, options) {
|
|
|
7130
7311
|
[
|
|
7131
7312
|
markHadValueIfFilled,
|
|
7132
7313
|
options.revalidateOnChange,
|
|
7314
|
+
options.validateEmptyOnChange,
|
|
7133
7315
|
shouldValidateEmptyOnChange,
|
|
7134
7316
|
trigger,
|
|
7135
7317
|
name,
|
|
@@ -7150,9 +7332,7 @@ var REVALIDATE_ON_CHANGE_TYPES = /* @__PURE__ */ new Set([
|
|
|
7150
7332
|
"radio",
|
|
7151
7333
|
"switch",
|
|
7152
7334
|
"select",
|
|
7153
|
-
"date",
|
|
7154
7335
|
"cascading-select",
|
|
7155
|
-
"select-with-input",
|
|
7156
7336
|
"input-with-button",
|
|
7157
7337
|
"address"
|
|
7158
7338
|
]);
|
|
@@ -7173,14 +7353,15 @@ function FormFieldRow(props) {
|
|
|
7173
7353
|
const { control } = reactHookForm.useFormContext();
|
|
7174
7354
|
const { isSubmitted } = reactHookForm.useFormState({ control });
|
|
7175
7355
|
const { name, label, type = "input", required = false, renderCustomField, contentAlign = "left" } = config;
|
|
7356
|
+
const revalidateOnChange = REVALIDATE_ON_CHANGE_TYPES.has(type);
|
|
7176
7357
|
const { handleBlur, handleChange } = useBlurValidation(name, {
|
|
7177
7358
|
required,
|
|
7178
|
-
revalidateOnChange
|
|
7359
|
+
revalidateOnChange,
|
|
7360
|
+
validateEmptyOnChange: revalidateOnChange,
|
|
7179
7361
|
revalidateFields: config.revalidateFields
|
|
7180
7362
|
});
|
|
7181
7363
|
const showError = Boolean(fieldState.error?.message) && (isSubmitted || fieldState.isTouched);
|
|
7182
7364
|
const isTextarea = type === "textarea";
|
|
7183
|
-
const revalidateOnChange = REVALIDATE_ON_CHANGE_TYPES.has(type);
|
|
7184
7365
|
const wrappedField = wrapFieldHandlers(field, {
|
|
7185
7366
|
onBlur: () => handleBlur(() => field.onBlur()),
|
|
7186
7367
|
onChange: (value) => {
|
|
@@ -7285,6 +7466,7 @@ function rowPropsToFieldConfig(props) {
|
|
|
7285
7466
|
canReset,
|
|
7286
7467
|
datePosition,
|
|
7287
7468
|
disableFutureDates,
|
|
7469
|
+
calendarSelectContainerClass,
|
|
7288
7470
|
revalidateFields,
|
|
7289
7471
|
renderCustomField,
|
|
7290
7472
|
colspan,
|
|
@@ -7315,6 +7497,7 @@ function rowPropsToFieldConfig(props) {
|
|
|
7315
7497
|
canReset,
|
|
7316
7498
|
datePosition,
|
|
7317
7499
|
disableFutureDates,
|
|
7500
|
+
calendarSelectContainerClass,
|
|
7318
7501
|
revalidateFields,
|
|
7319
7502
|
renderCustomField,
|
|
7320
7503
|
colspan,
|
|
@@ -7479,7 +7662,10 @@ function PageFilter(props) {
|
|
|
7479
7662
|
{
|
|
7480
7663
|
placeholder: option.placeholder,
|
|
7481
7664
|
value: currentValue,
|
|
7482
|
-
onChange: handleInputChange(optionKey)
|
|
7665
|
+
onChange: handleInputChange(optionKey),
|
|
7666
|
+
onKeyDown: (e) => {
|
|
7667
|
+
if (e.key === "Enter") handleSubmit();
|
|
7668
|
+
}
|
|
7483
7669
|
}
|
|
7484
7670
|
) }, String(optionKey));
|
|
7485
7671
|
case "select":
|
|
@@ -7489,7 +7675,8 @@ function PageFilter(props) {
|
|
|
7489
7675
|
value: currentValue,
|
|
7490
7676
|
onChange: handleSelectChange(optionKey),
|
|
7491
7677
|
options: option.options,
|
|
7492
|
-
placeholder: "\uC120\uD0DD
|
|
7678
|
+
placeholder: "\uC120\uD0DD",
|
|
7679
|
+
containerClassName: option.containerClassName ?? "w-30"
|
|
7493
7680
|
}
|
|
7494
7681
|
) }, String(optionKey));
|
|
7495
7682
|
case "radio":
|
|
@@ -7554,9 +7741,84 @@ function PageFilter(props) {
|
|
|
7554
7741
|
}
|
|
7555
7742
|
);
|
|
7556
7743
|
}
|
|
7744
|
+
var VARIANT_STYLES = {
|
|
7745
|
+
light: {
|
|
7746
|
+
container: "bg-white border-b border-gray-200",
|
|
7747
|
+
activeTab: "bg-gray-50 border-gray-200 text-gray-800 shadow-sm",
|
|
7748
|
+
inactiveTab: "bg-white border-gray-100 text-gray-400 hover:text-gray-600 hover:border-gray-200 hover:bg-gray-50",
|
|
7749
|
+
activeText: "font-semibold text-gray-800",
|
|
7750
|
+
inactiveText: "font-normal",
|
|
7751
|
+
indicator: "bg-blue-500",
|
|
7752
|
+
closeBtn: "hover:bg-gray-300/60",
|
|
7753
|
+
plusBtnArea: "border-l border-gray-100 bg-white",
|
|
7754
|
+
plusBtn: "text-gray-400 hover:text-gray-600 hover:bg-gray-100",
|
|
7755
|
+
fadeOpacity: 0.12,
|
|
7756
|
+
tabPy: "py-1.5",
|
|
7757
|
+
tabPx: "px-3",
|
|
7758
|
+
tabTextSize: "text-xs",
|
|
7759
|
+
scrollPadding: "px-3 pt-1.5",
|
|
7760
|
+
rounded: "rounded-t-md"
|
|
7761
|
+
},
|
|
7762
|
+
dark: {
|
|
7763
|
+
container: "bg-gray-900 border-b border-gray-700",
|
|
7764
|
+
activeTab: "bg-gray-800 border-gray-600 text-white shadow-sm",
|
|
7765
|
+
inactiveTab: "bg-gray-900 border-gray-700/50 text-gray-500 hover:text-gray-300 hover:border-gray-600 hover:bg-gray-800",
|
|
7766
|
+
activeText: "font-semibold text-white",
|
|
7767
|
+
inactiveText: "font-normal",
|
|
7768
|
+
indicator: "bg-indigo-400",
|
|
7769
|
+
closeBtn: "hover:bg-gray-600/60",
|
|
7770
|
+
plusBtnArea: "border-l border-gray-700 bg-gray-900",
|
|
7771
|
+
plusBtn: "text-gray-500 hover:text-gray-300 hover:bg-gray-700",
|
|
7772
|
+
fadeOpacity: 0.4,
|
|
7773
|
+
tabPy: "py-1.5",
|
|
7774
|
+
tabPx: "px-3",
|
|
7775
|
+
tabTextSize: "text-xs",
|
|
7776
|
+
scrollPadding: "px-3 pt-1.5",
|
|
7777
|
+
rounded: "rounded-t-md"
|
|
7778
|
+
},
|
|
7779
|
+
"system-light": {
|
|
7780
|
+
container: "bg-gray-200 border-b border-gray-300",
|
|
7781
|
+
activeTab: "bg-white border-gray-300 text-slate-800 shadow-sm",
|
|
7782
|
+
inactiveTab: "bg-transparent border-gray-300/80 text-slate-500 hover:text-slate-700 hover:bg-gray-200 hover:border-gray-300",
|
|
7783
|
+
activeText: "font-semibold text-slate-800",
|
|
7784
|
+
inactiveText: "font-medium",
|
|
7785
|
+
indicator: "bg-[#2b2b2b]",
|
|
7786
|
+
closeBtn: "hover:bg-gray-300",
|
|
7787
|
+
plusBtnArea: "border-l border-gray-300 bg-gray-200",
|
|
7788
|
+
plusBtn: "text-slate-400 hover:text-slate-600 hover:bg-gray-300",
|
|
7789
|
+
fadeOpacity: 0.15,
|
|
7790
|
+
tabPy: "py-2.5",
|
|
7791
|
+
tabPx: "px-5",
|
|
7792
|
+
tabTextSize: "text-sm",
|
|
7793
|
+
scrollPadding: "px-3 pt-2",
|
|
7794
|
+
rounded: "rounded-t-none"
|
|
7795
|
+
},
|
|
7796
|
+
"system-dark": {
|
|
7797
|
+
container: "bg-slate-900 border-b border-slate-700",
|
|
7798
|
+
activeTab: "bg-slate-800 border-slate-600 text-slate-100 shadow-sm",
|
|
7799
|
+
inactiveTab: "bg-transparent border-slate-700/50 text-slate-400 hover:text-slate-200 hover:bg-slate-800/60 hover:border-slate-700",
|
|
7800
|
+
activeText: "font-semibold text-slate-100",
|
|
7801
|
+
inactiveText: "font-medium",
|
|
7802
|
+
indicator: "bg-indigo-400",
|
|
7803
|
+
closeBtn: "hover:bg-slate-600/60",
|
|
7804
|
+
plusBtnArea: "border-l border-slate-700 bg-slate-900",
|
|
7805
|
+
plusBtn: "text-slate-400 hover:text-slate-200 hover:bg-slate-700",
|
|
7806
|
+
fadeOpacity: 0.45,
|
|
7807
|
+
tabPy: "py-2.5",
|
|
7808
|
+
tabPx: "px-5",
|
|
7809
|
+
tabTextSize: "text-sm",
|
|
7810
|
+
scrollPadding: "px-4 pt-2",
|
|
7811
|
+
rounded: "rounded-t-none"
|
|
7812
|
+
}
|
|
7813
|
+
};
|
|
7557
7814
|
var PLUS_BTN_WIDTH = 36;
|
|
7815
|
+
function easedFade(dir, opacity) {
|
|
7816
|
+
const c = (t) => `rgba(0,0,0,${(opacity * t).toFixed(3)})`;
|
|
7817
|
+
return `linear-gradient(${dir}, ${c(1)} 0%, ${c(0.72)} 20%, ${c(0.38)} 45%, ${c(0.1)} 70%, transparent 100%)`;
|
|
7818
|
+
}
|
|
7558
7819
|
function MultiTabBar(props) {
|
|
7559
|
-
const { tabs, activeTabId, onTabClick, onTabClose, onTabAdd } = props;
|
|
7820
|
+
const { tabs, activeTabId, onTabClick, onTabClose, onTabAdd, variant = "light", primaryColor } = props;
|
|
7821
|
+
const s = VARIANT_STYLES[variant];
|
|
7560
7822
|
const scrollRef = React6.useRef(null);
|
|
7561
7823
|
const tabRefs = React6.useRef(/* @__PURE__ */ new Map());
|
|
7562
7824
|
const [showLeftFade, setShowLeftFade] = React6.useState(false);
|
|
@@ -7609,13 +7871,23 @@ function MultiTabBar(props) {
|
|
|
7609
7871
|
const handleStopDrag = () => {
|
|
7610
7872
|
isDragging.current = false;
|
|
7611
7873
|
};
|
|
7874
|
+
React6.useEffect(() => {
|
|
7875
|
+
const el = scrollRef.current;
|
|
7876
|
+
if (!el) return;
|
|
7877
|
+
const onWheel = (e) => {
|
|
7878
|
+
e.preventDefault();
|
|
7879
|
+
el.scrollLeft += e.deltaY || e.deltaX;
|
|
7880
|
+
};
|
|
7881
|
+
el.addEventListener("wheel", onWheel, { passive: false });
|
|
7882
|
+
return () => el.removeEventListener("wheel", onWheel);
|
|
7883
|
+
}, []);
|
|
7612
7884
|
if (tabs.length === 0) return null;
|
|
7613
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
7885
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-shrink-0 w-full overflow-hidden ${s.container}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-stretch", children: [
|
|
7614
7886
|
showLeftFade && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7615
7887
|
"div",
|
|
7616
7888
|
{
|
|
7617
7889
|
className: "absolute left-0 top-0 bottom-0 w-10 pointer-events-none z-10",
|
|
7618
|
-
style: { background: "
|
|
7890
|
+
style: { background: easedFade("to right", s.fadeOpacity) }
|
|
7619
7891
|
}
|
|
7620
7892
|
),
|
|
7621
7893
|
showRightFade && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7624,7 +7896,7 @@ function MultiTabBar(props) {
|
|
|
7624
7896
|
className: "absolute top-0 bottom-0 w-10 pointer-events-none z-10",
|
|
7625
7897
|
style: {
|
|
7626
7898
|
right: PLUS_BTN_WIDTH,
|
|
7627
|
-
background: "
|
|
7899
|
+
background: easedFade("to left", s.fadeOpacity)
|
|
7628
7900
|
}
|
|
7629
7901
|
}
|
|
7630
7902
|
),
|
|
@@ -7632,7 +7904,7 @@ function MultiTabBar(props) {
|
|
|
7632
7904
|
"div",
|
|
7633
7905
|
{
|
|
7634
7906
|
ref: scrollRef,
|
|
7635
|
-
className:
|
|
7907
|
+
className: `flex-1 min-w-0 flex items-end gap-0.5 ${s.scrollPadding} overflow-x-auto [&::-webkit-scrollbar]:hidden`,
|
|
7636
7908
|
style: { scrollbarWidth: "none" },
|
|
7637
7909
|
onScroll: updateFades,
|
|
7638
7910
|
onMouseDown: handleMouseDown,
|
|
@@ -7653,17 +7925,23 @@ function MultiTabBar(props) {
|
|
|
7653
7925
|
if (!isActive) onTabClick(tab.id);
|
|
7654
7926
|
},
|
|
7655
7927
|
className: `
|
|
7656
|
-
group relative flex items-center gap-1.5
|
|
7657
|
-
rounded
|
|
7928
|
+
group relative flex items-center gap-1.5 ${s.tabPx} ${s.tabPy} flex-shrink-0
|
|
7929
|
+
${s.rounded} border border-b-0 cursor-pointer select-none
|
|
7658
7930
|
transition-colors duration-100
|
|
7659
|
-
${isActive ?
|
|
7931
|
+
${isActive ? s.activeTab : s.inactiveTab}
|
|
7660
7932
|
`,
|
|
7661
7933
|
children: [
|
|
7662
|
-
isActive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7934
|
+
isActive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7935
|
+
"div",
|
|
7936
|
+
{
|
|
7937
|
+
className: `absolute top-0 left-0 right-0 h-0.5 ${s.rounded} ${s.indicator}`,
|
|
7938
|
+
style: primaryColor ? { backgroundColor: primaryColor } : void 0
|
|
7939
|
+
}
|
|
7940
|
+
),
|
|
7663
7941
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7664
7942
|
"span",
|
|
7665
7943
|
{
|
|
7666
|
-
className:
|
|
7944
|
+
className: `${s.tabTextSize} max-w-35 truncate leading-none ${isActive ? s.activeText : s.inactiveText}`,
|
|
7667
7945
|
children: tab.label
|
|
7668
7946
|
}
|
|
7669
7947
|
),
|
|
@@ -7676,7 +7954,8 @@ function MultiTabBar(props) {
|
|
|
7676
7954
|
},
|
|
7677
7955
|
className: `
|
|
7678
7956
|
flex-shrink-0 w-3.5 h-3.5 flex items-center justify-center
|
|
7679
|
-
rounded
|
|
7957
|
+
rounded transition-all duration-100 cursor-pointer
|
|
7958
|
+
${s.closeBtn}
|
|
7680
7959
|
${isActive ? "opacity-100" : "opacity-40 group-hover:opacity-60"}
|
|
7681
7960
|
`,
|
|
7682
7961
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 10, strokeWidth: 2.5 })
|
|
@@ -7692,14 +7971,14 @@ function MultiTabBar(props) {
|
|
|
7692
7971
|
onTabAdd && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7693
7972
|
"div",
|
|
7694
7973
|
{
|
|
7695
|
-
className:
|
|
7974
|
+
className: `flex-shrink-0 flex items-center justify-center ${s.plusBtnArea}`,
|
|
7696
7975
|
style: { width: PLUS_BTN_WIDTH },
|
|
7697
7976
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7698
7977
|
"button",
|
|
7699
7978
|
{
|
|
7700
7979
|
onClick: onTabAdd,
|
|
7701
7980
|
title: "\uD604\uC7AC \uD398\uC774\uC9C0\uB97C \uC0C8 \uD0ED\uC73C\uB85C \uC5F4\uAE30",
|
|
7702
|
-
className:
|
|
7981
|
+
className: `w-6 h-6 flex items-center justify-center rounded cursor-pointer transition-colors ${s.plusBtn}`,
|
|
7703
7982
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { size: 13, strokeWidth: 2 })
|
|
7704
7983
|
}
|
|
7705
7984
|
)
|
|
@@ -8484,19 +8763,212 @@ function FileUploader(props) {
|
|
|
8484
8763
|
/* @__PURE__ */ jsxRuntime.jsx(FilePreviewViewer, { ...viewer.viewerProps, fileTypes, fileNames: files.map((f) => f.name) })
|
|
8485
8764
|
] });
|
|
8486
8765
|
}
|
|
8766
|
+
var VARIANT_STYLES2 = {
|
|
8767
|
+
light: {
|
|
8768
|
+
aside: "bg-white border-r border-gray-200",
|
|
8769
|
+
sectionTitle: "text-xs font-semibold text-gray-500 tracking-wider mb-3",
|
|
8770
|
+
itemActive: "bg-blue-50 text-blue-600",
|
|
8771
|
+
itemInactive: "text-gray-700 hover:bg-gray-100",
|
|
8772
|
+
subItemActive: "text-blue-600 font-medium",
|
|
8773
|
+
subItemInactive: "text-gray-600 hover:bg-gray-50 hover:text-gray-900",
|
|
8774
|
+
childGroupBorder: "border-gray-100",
|
|
8775
|
+
childActive: "bg-blue-50 text-blue-600 font-medium",
|
|
8776
|
+
childInactive: "text-gray-600 hover:bg-gray-50 hover:text-gray-900",
|
|
8777
|
+
grandchildActive: "bg-blue-50 text-blue-600 font-medium",
|
|
8778
|
+
grandchildInactive: "text-gray-500 hover:bg-gray-50 hover:text-gray-900",
|
|
8779
|
+
collapseBtn: "bg-gray-50 hover:bg-gray-100",
|
|
8780
|
+
collapseIcon: "var(--color-sub-darkgray)",
|
|
8781
|
+
rounded: "rounded-lg",
|
|
8782
|
+
itemPy: "py-2",
|
|
8783
|
+
childPy: "py-1.5",
|
|
8784
|
+
grandchildPy: "py-1",
|
|
8785
|
+
itemFont: "font-semibold",
|
|
8786
|
+
itemTextSize: "text-sm",
|
|
8787
|
+
grandchildTextSize: "text-xs",
|
|
8788
|
+
iconClass: "w-4 h-4 flex-shrink-0",
|
|
8789
|
+
activeItemStyle: {},
|
|
8790
|
+
activeChildStyle: {},
|
|
8791
|
+
activeGrandchildStyle: {}
|
|
8792
|
+
},
|
|
8793
|
+
dark: {
|
|
8794
|
+
aside: "bg-gray-900 border-r border-gray-700",
|
|
8795
|
+
sectionTitle: "text-xs font-semibold text-gray-400 tracking-wider mb-3",
|
|
8796
|
+
itemActive: "bg-gray-700 text-white",
|
|
8797
|
+
itemInactive: "text-gray-300 hover:bg-gray-800",
|
|
8798
|
+
subItemActive: "text-blue-400 font-medium",
|
|
8799
|
+
subItemInactive: "text-gray-400 hover:bg-gray-800 hover:text-gray-100",
|
|
8800
|
+
childGroupBorder: "border-gray-700",
|
|
8801
|
+
childActive: "bg-gray-700 text-white font-medium",
|
|
8802
|
+
childInactive: "text-gray-400 hover:bg-gray-800 hover:text-gray-100",
|
|
8803
|
+
grandchildActive: "bg-gray-700 text-blue-400 font-medium",
|
|
8804
|
+
grandchildInactive: "text-gray-500 hover:bg-gray-800 hover:text-gray-100",
|
|
8805
|
+
collapseBtn: "bg-gray-800 hover:bg-gray-700",
|
|
8806
|
+
collapseIcon: "#9ca3af",
|
|
8807
|
+
rounded: "rounded-lg",
|
|
8808
|
+
itemPy: "py-2",
|
|
8809
|
+
childPy: "py-1.5",
|
|
8810
|
+
grandchildPy: "py-1",
|
|
8811
|
+
itemFont: "font-semibold",
|
|
8812
|
+
itemTextSize: "text-sm",
|
|
8813
|
+
grandchildTextSize: "text-xs",
|
|
8814
|
+
iconClass: "w-4 h-4 flex-shrink-0",
|
|
8815
|
+
activeItemStyle: {},
|
|
8816
|
+
activeChildStyle: {},
|
|
8817
|
+
activeGrandchildStyle: {}
|
|
8818
|
+
},
|
|
8819
|
+
"system-dark": {
|
|
8820
|
+
aside: "bg-slate-900 border-r border-slate-700",
|
|
8821
|
+
sectionTitle: "text-[10px] font-bold text-slate-500 uppercase tracking-[0.12em] mb-2 pb-2 border-b border-slate-700/70",
|
|
8822
|
+
itemActive: "bg-slate-800 text-white",
|
|
8823
|
+
itemInactive: "text-slate-300 hover:bg-slate-800/60 hover:text-white",
|
|
8824
|
+
subItemActive: "text-slate-100 font-medium",
|
|
8825
|
+
subItemInactive: "text-slate-400 hover:bg-slate-800/50 hover:text-slate-200",
|
|
8826
|
+
childGroupBorder: "border-slate-700/60",
|
|
8827
|
+
childActive: "bg-slate-800/70 text-slate-100 font-medium",
|
|
8828
|
+
childInactive: "text-slate-400 hover:bg-slate-800/50 hover:text-slate-200",
|
|
8829
|
+
grandchildActive: "text-slate-100 font-medium",
|
|
8830
|
+
grandchildInactive: "text-slate-500 hover:bg-slate-800/50 hover:text-slate-200",
|
|
8831
|
+
collapseBtn: "bg-slate-800 hover:bg-slate-700",
|
|
8832
|
+
collapseIcon: "#94a3b8",
|
|
8833
|
+
rounded: "rounded-none",
|
|
8834
|
+
itemPy: "py-3",
|
|
8835
|
+
childPy: "py-[10px]",
|
|
8836
|
+
grandchildPy: "py-2",
|
|
8837
|
+
itemFont: "font-medium",
|
|
8838
|
+
itemTextSize: "text-sm",
|
|
8839
|
+
grandchildTextSize: "text-xs",
|
|
8840
|
+
iconClass: "w-4.5 h-4.5 flex-shrink-0",
|
|
8841
|
+
activeItemStyle: { borderLeft: "3px solid #818cf8", paddingLeft: "9px" },
|
|
8842
|
+
activeChildStyle: { borderLeft: "2px solid #818cf8", paddingLeft: "14px" },
|
|
8843
|
+
activeGrandchildStyle: { borderLeft: "2px solid #818cf8", paddingLeft: "10px" }
|
|
8844
|
+
},
|
|
8845
|
+
"system-light": {
|
|
8846
|
+
aside: "bg-gray-50 border-r border-gray-200",
|
|
8847
|
+
sectionTitle: "text-[10px] font-bold text-slate-400 uppercase tracking-[0.12em] mb-2 pb-2 border-b border-gray-200",
|
|
8848
|
+
itemActive: "font-medium",
|
|
8849
|
+
itemInactive: "text-slate-700 hover:bg-gray-100",
|
|
8850
|
+
subItemActive: "text-[#2b2b2b] font-medium",
|
|
8851
|
+
subItemInactive: "text-slate-500 hover:bg-gray-100 hover:text-slate-800",
|
|
8852
|
+
childGroupBorder: "border-gray-200",
|
|
8853
|
+
childActive: "font-medium",
|
|
8854
|
+
childInactive: "text-slate-500 hover:bg-gray-100 hover:text-slate-800",
|
|
8855
|
+
grandchildActive: "text-[#2b2b2b] font-medium",
|
|
8856
|
+
grandchildInactive: "text-slate-500 hover:bg-gray-100 hover:text-slate-800",
|
|
8857
|
+
collapseBtn: "bg-gray-100 hover:bg-gray-200",
|
|
8858
|
+
collapseIcon: "#64748b",
|
|
8859
|
+
rounded: "rounded-none",
|
|
8860
|
+
itemPy: "py-3",
|
|
8861
|
+
childPy: "py-[10px]",
|
|
8862
|
+
grandchildPy: "py-2",
|
|
8863
|
+
itemFont: "font-medium",
|
|
8864
|
+
itemTextSize: "text-[15px]",
|
|
8865
|
+
grandchildTextSize: "text-sm",
|
|
8866
|
+
iconClass: "w-4.5 h-4.5 flex-shrink-0",
|
|
8867
|
+
activeItemStyle: {
|
|
8868
|
+
color: "#2b2b2b",
|
|
8869
|
+
backgroundColor: "color-mix(in srgb, #2b2b2b 10%, transparent)",
|
|
8870
|
+
borderLeft: "3px solid #2b2b2b",
|
|
8871
|
+
paddingLeft: "9px"
|
|
8872
|
+
},
|
|
8873
|
+
activeChildStyle: {
|
|
8874
|
+
color: "#2b2b2b",
|
|
8875
|
+
backgroundColor: "color-mix(in srgb, #2b2b2b 10%, transparent)",
|
|
8876
|
+
borderLeft: "2px solid #2b2b2b",
|
|
8877
|
+
paddingLeft: "14px"
|
|
8878
|
+
},
|
|
8879
|
+
activeGrandchildStyle: {
|
|
8880
|
+
color: "#2b2b2b",
|
|
8881
|
+
backgroundColor: "color-mix(in srgb, #2b2b2b 10%, transparent)",
|
|
8882
|
+
borderLeft: "2px solid #2b2b2b",
|
|
8883
|
+
paddingLeft: "10px"
|
|
8884
|
+
}
|
|
8885
|
+
}
|
|
8886
|
+
};
|
|
8887
|
+
function tintedStyle(color) {
|
|
8888
|
+
return {
|
|
8889
|
+
color,
|
|
8890
|
+
backgroundColor: `color-mix(in srgb, ${color} 12%, transparent)`
|
|
8891
|
+
};
|
|
8892
|
+
}
|
|
8893
|
+
function textStyle(color) {
|
|
8894
|
+
return { color };
|
|
8895
|
+
}
|
|
8896
|
+
function solidStyle(color) {
|
|
8897
|
+
return {
|
|
8898
|
+
backgroundColor: `color-mix(in srgb, ${color} 25%, transparent)`,
|
|
8899
|
+
color: "#ffffff",
|
|
8900
|
+
boxShadow: `inset 3px 0 0 ${color}`
|
|
8901
|
+
};
|
|
8902
|
+
}
|
|
8903
|
+
var ACCENT_APPLIERS = {
|
|
8904
|
+
light: {
|
|
8905
|
+
itemActive: tintedStyle,
|
|
8906
|
+
subItemActive: textStyle,
|
|
8907
|
+
childActive: tintedStyle,
|
|
8908
|
+
grandchildActive: textStyle
|
|
8909
|
+
},
|
|
8910
|
+
dark: {
|
|
8911
|
+
itemActive: textStyle,
|
|
8912
|
+
subItemActive: textStyle,
|
|
8913
|
+
childActive: textStyle,
|
|
8914
|
+
grandchildActive: textStyle
|
|
8915
|
+
},
|
|
8916
|
+
"system-dark": {
|
|
8917
|
+
itemActive: (c) => ({
|
|
8918
|
+
...solidStyle(c),
|
|
8919
|
+
boxShadow: void 0,
|
|
8920
|
+
borderLeft: `3px solid ${c}`,
|
|
8921
|
+
paddingLeft: "9px"
|
|
8922
|
+
}),
|
|
8923
|
+
subItemActive: textStyle,
|
|
8924
|
+
childActive: (c) => ({
|
|
8925
|
+
...solidStyle(c),
|
|
8926
|
+
boxShadow: void 0,
|
|
8927
|
+
borderLeft: `2px solid ${c}`,
|
|
8928
|
+
paddingLeft: "14px"
|
|
8929
|
+
}),
|
|
8930
|
+
grandchildActive: (c) => ({
|
|
8931
|
+
...textStyle(c),
|
|
8932
|
+
borderLeft: `2px solid ${c}`,
|
|
8933
|
+
paddingLeft: "10px"
|
|
8934
|
+
})
|
|
8935
|
+
},
|
|
8936
|
+
"system-light": {
|
|
8937
|
+
itemActive: (c) => ({
|
|
8938
|
+
...tintedStyle(c),
|
|
8939
|
+
borderLeft: `3px solid ${c}`,
|
|
8940
|
+
paddingLeft: "9px"
|
|
8941
|
+
}),
|
|
8942
|
+
subItemActive: textStyle,
|
|
8943
|
+
childActive: (c) => ({
|
|
8944
|
+
...tintedStyle(c),
|
|
8945
|
+
borderLeft: `2px solid ${c}`,
|
|
8946
|
+
paddingLeft: "14px"
|
|
8947
|
+
}),
|
|
8948
|
+
grandchildActive: (c) => ({
|
|
8949
|
+
...tintedStyle(c),
|
|
8950
|
+
borderLeft: `2px solid ${c}`,
|
|
8951
|
+
paddingLeft: "10px"
|
|
8952
|
+
})
|
|
8953
|
+
}
|
|
8954
|
+
};
|
|
8487
8955
|
function Sidebar(props) {
|
|
8488
8956
|
const navigate = reactRouter.useNavigate();
|
|
8489
|
-
const {
|
|
8957
|
+
const {
|
|
8958
|
+
onClose,
|
|
8959
|
+
menuSections,
|
|
8960
|
+
header,
|
|
8961
|
+
className,
|
|
8962
|
+
showCollapseButton = false,
|
|
8963
|
+
variant = "light",
|
|
8964
|
+
primaryColor
|
|
8965
|
+
} = props;
|
|
8490
8966
|
const { pathname } = reactRouter.useLocation();
|
|
8491
8967
|
const [isCollapsed, setIsCollapsed] = React6.useState(false);
|
|
8492
|
-
const [isContentVisible, setIsContentVisible] = React6.useState(true);
|
|
8493
8968
|
const [expandedItems, setExpandedItems] = React6.useState(/* @__PURE__ */ new Set());
|
|
8494
8969
|
const [expandedSubItems, setExpandedSubItems] = React6.useState(/* @__PURE__ */ new Set());
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
const timer = setTimeout(() => setIsContentVisible(true), 300);
|
|
8498
|
-
return () => clearTimeout(timer);
|
|
8499
|
-
}, [isCollapsed]);
|
|
8970
|
+
const s = VARIANT_STYLES2[variant];
|
|
8971
|
+
const applier = ACCENT_APPLIERS[variant];
|
|
8500
8972
|
React6.useEffect(() => {
|
|
8501
8973
|
menuSections.forEach((section) => {
|
|
8502
8974
|
section.items.forEach((item) => {
|
|
@@ -8547,167 +9019,178 @@ function Sidebar(props) {
|
|
|
8547
9019
|
window.open(path, "_blank", "noopener,noreferrer");
|
|
8548
9020
|
} else if (path !== "") {
|
|
8549
9021
|
navigate(path);
|
|
8550
|
-
onClose();
|
|
9022
|
+
onClose?.();
|
|
8551
9023
|
}
|
|
8552
9024
|
};
|
|
8553
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
{
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
}
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
|
|
8579
|
-
"
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8585
|
-
|
|
8586
|
-
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
8596
|
-
|
|
8597
|
-
|
|
8598
|
-
|
|
8599
|
-
|
|
8600
|
-
|
|
8601
|
-
|
|
8602
|
-
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
|
|
8607
|
-
/* @__PURE__ */ jsxRuntime.jsx(item.icon, { className: "w-4 h-4 flex-shrink-0" }),
|
|
8608
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: item.label }),
|
|
8609
|
-
item.children && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8610
|
-
"svg",
|
|
8611
|
-
{
|
|
8612
|
-
className: `w-4 h-4 transition-transform ${expandedItems.has(item.label) ? "rotate-90" : ""}`,
|
|
8613
|
-
fill: "none",
|
|
8614
|
-
stroke: "currentColor",
|
|
8615
|
-
viewBox: "0 0 24 24",
|
|
8616
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
|
|
8617
|
-
}
|
|
8618
|
-
),
|
|
8619
|
-
item.path?.includes("https") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8620
|
-
"svg",
|
|
8621
|
-
{
|
|
8622
|
-
className: "w-4 h-4 flex-shrink-0 text-gray-400",
|
|
8623
|
-
fill: "none",
|
|
8624
|
-
stroke: "currentColor",
|
|
8625
|
-
viewBox: "0 0 24 24",
|
|
8626
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8627
|
-
"path",
|
|
9025
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9026
|
+
"aside",
|
|
9027
|
+
{
|
|
9028
|
+
className: `
|
|
9029
|
+
${isCollapsed ? "w-11 min-w-11" : "min-w-60 w-62"}
|
|
9030
|
+
transition-[width,min-width] duration-300 ease-in-out
|
|
9031
|
+
hide-scrollbar relative h-screen shrink-0 overflow-y-auto overflow-x-hidden
|
|
9032
|
+
${s.aside}
|
|
9033
|
+
${className ?? ""}
|
|
9034
|
+
`,
|
|
9035
|
+
children: [
|
|
9036
|
+
showCollapseButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9037
|
+
"button",
|
|
9038
|
+
{
|
|
9039
|
+
onClick: () => setIsCollapsed((prev) => !prev),
|
|
9040
|
+
className: `absolute top-4 right-2 z-20 w-6.5 h-6.5 rounded-full flex items-center justify-center transition-colors cursor-pointer ${s.collapseBtn}`,
|
|
9041
|
+
children: isCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRightClose, { size: 18, color: primaryColor ?? s.collapseIcon }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeftClose, { size: 18, color: primaryColor ?? s.collapseIcon })
|
|
9042
|
+
}
|
|
9043
|
+
),
|
|
9044
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9045
|
+
"div",
|
|
9046
|
+
{
|
|
9047
|
+
className: `transition-opacity duration-200 ease-in-out ${isCollapsed ? "opacity-0 pointer-events-none select-none" : "opacity-100"} ${variant === "system-dark" || variant === "system-light" ? "px-1 py-6" : "px-4 py-6"}`,
|
|
9048
|
+
style: { transitionDelay: isCollapsed ? "0ms" : "150ms" },
|
|
9049
|
+
children: [
|
|
9050
|
+
header && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6 mt-2", children: header }),
|
|
9051
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "space-y-6", children: menuSections.map((section, sectionIndex) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
9052
|
+
section.title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: s.sectionTitle, children: section.title }),
|
|
9053
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: section.items.map((item) => {
|
|
9054
|
+
const isActive = !item.children && pathname === item.path;
|
|
9055
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
9056
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9057
|
+
"button",
|
|
9058
|
+
{
|
|
9059
|
+
onClick: () => {
|
|
9060
|
+
if (item.children) {
|
|
9061
|
+
toggleExpand(item.label);
|
|
9062
|
+
} else if (item.path) {
|
|
9063
|
+
handleItemClick(item.path);
|
|
9064
|
+
}
|
|
9065
|
+
},
|
|
9066
|
+
className: `
|
|
9067
|
+
w-full text-left flex items-center gap-2 px-3 ${s.itemPy} ${s.rounded} ${s.itemTextSize} ${s.itemFont} transition-colors cursor-pointer
|
|
9068
|
+
${isActive ? s.itemActive : s.itemInactive}
|
|
9069
|
+
`,
|
|
9070
|
+
style: {
|
|
9071
|
+
...isActive ? s.activeItemStyle : {},
|
|
9072
|
+
...isActive && primaryColor ? applier.itemActive(primaryColor) : {}
|
|
9073
|
+
},
|
|
9074
|
+
children: [
|
|
9075
|
+
/* @__PURE__ */ jsxRuntime.jsx(item.icon, { className: s.iconClass }),
|
|
9076
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: item.label }),
|
|
9077
|
+
item.children && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9078
|
+
"svg",
|
|
8628
9079
|
{
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
9080
|
+
className: `w-4 h-4 transition-transform ${expandedItems.has(item.label) ? "rotate-90" : ""}`,
|
|
9081
|
+
fill: "none",
|
|
9082
|
+
stroke: "currentColor",
|
|
9083
|
+
viewBox: "0 0 24 24",
|
|
9084
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
|
|
9085
|
+
}
|
|
9086
|
+
),
|
|
9087
|
+
item.path?.includes("https") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9088
|
+
"svg",
|
|
9089
|
+
{
|
|
9090
|
+
className: "w-4 h-4 flex-shrink-0 opacity-50",
|
|
9091
|
+
fill: "none",
|
|
9092
|
+
stroke: "currentColor",
|
|
9093
|
+
viewBox: "0 0 24 24",
|
|
9094
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9095
|
+
"path",
|
|
9096
|
+
{
|
|
9097
|
+
strokeLinecap: "round",
|
|
9098
|
+
strokeLinejoin: "round",
|
|
9099
|
+
strokeWidth: 2,
|
|
9100
|
+
d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
|
|
9101
|
+
}
|
|
9102
|
+
)
|
|
8633
9103
|
}
|
|
8634
9104
|
)
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
"svg",
|
|
8658
|
-
{
|
|
8659
|
-
className: `w-3 h-3 transition-transform ${isSubExpanded ? "rotate-90" : ""}`,
|
|
8660
|
-
fill: "none",
|
|
8661
|
-
stroke: "currentColor",
|
|
8662
|
-
viewBox: "0 0 24 24",
|
|
8663
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8664
|
-
"path",
|
|
9105
|
+
]
|
|
9106
|
+
}
|
|
9107
|
+
),
|
|
9108
|
+
item.children && expandedItems.has(item.label) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `ml-5 mt-0.5 space-y-0.5 border-l ${s.childGroupBorder}`, children: item.children.map((child, childIndex) => {
|
|
9109
|
+
if (child.children && child.children.length > 0) {
|
|
9110
|
+
const subKey = `${item.label}::${child.label}`;
|
|
9111
|
+
const isSubExpanded = expandedSubItems.has(subKey);
|
|
9112
|
+
const isSubActive = child.children.some((gc) => gc.path === pathname);
|
|
9113
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
9114
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9115
|
+
"button",
|
|
9116
|
+
{
|
|
9117
|
+
onClick: () => toggleSubExpand(subKey),
|
|
9118
|
+
className: `
|
|
9119
|
+
w-full text-left flex items-center justify-between pl-4 pr-3 ${s.childPy} ${s.rounded} ${s.itemTextSize} transition-colors cursor-pointer
|
|
9120
|
+
${isSubActive ? s.subItemActive : s.subItemInactive}
|
|
9121
|
+
`,
|
|
9122
|
+
style: isSubActive && primaryColor ? applier.subItemActive(primaryColor) : void 0,
|
|
9123
|
+
children: [
|
|
9124
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: child.label }),
|
|
9125
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9126
|
+
"svg",
|
|
8665
9127
|
{
|
|
8666
|
-
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
9128
|
+
className: `w-3 h-3 transition-transform ${isSubExpanded ? "rotate-90" : ""}`,
|
|
9129
|
+
fill: "none",
|
|
9130
|
+
stroke: "currentColor",
|
|
9131
|
+
viewBox: "0 0 24 24",
|
|
9132
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9133
|
+
"path",
|
|
9134
|
+
{
|
|
9135
|
+
strokeLinecap: "round",
|
|
9136
|
+
strokeLinejoin: "round",
|
|
9137
|
+
strokeWidth: 2,
|
|
9138
|
+
d: "M9 5l7 7-7 7"
|
|
9139
|
+
}
|
|
9140
|
+
)
|
|
8670
9141
|
}
|
|
8671
9142
|
)
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
|
|
9143
|
+
]
|
|
9144
|
+
}
|
|
9145
|
+
),
|
|
9146
|
+
isSubExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-3 mt-0.5 space-y-0.5 pl-2", children: child.children.map((grandchild) => {
|
|
9147
|
+
const isGrandchildActive = pathname === grandchild.path;
|
|
9148
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9149
|
+
"button",
|
|
9150
|
+
{
|
|
9151
|
+
onClick: () => handleItemClick(grandchild.path),
|
|
9152
|
+
className: `
|
|
9153
|
+
w-full text-left px-3 ${s.grandchildPy} ${s.rounded} ${s.grandchildTextSize} transition-colors cursor-pointer
|
|
9154
|
+
${isGrandchildActive ? s.grandchildActive : s.grandchildInactive}
|
|
9155
|
+
`,
|
|
9156
|
+
style: {
|
|
9157
|
+
...isGrandchildActive ? s.activeGrandchildStyle : {},
|
|
9158
|
+
...isGrandchildActive && primaryColor ? applier.grandchildActive(primaryColor) : {}
|
|
9159
|
+
},
|
|
9160
|
+
children: grandchild.label
|
|
9161
|
+
},
|
|
9162
|
+
grandchild.path
|
|
9163
|
+
);
|
|
9164
|
+
}) })
|
|
9165
|
+
] }, child.label);
|
|
9166
|
+
}
|
|
9167
|
+
const isChildActive = pathname === child.path;
|
|
9168
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8678
9169
|
"button",
|
|
8679
9170
|
{
|
|
8680
|
-
onClick: () => handleItemClick(
|
|
9171
|
+
onClick: () => handleItemClick(child.path ?? ""),
|
|
8681
9172
|
className: `
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
9173
|
+
w-full text-left pl-4 pr-3 ${s.childPy} ${s.rounded} ${s.itemTextSize} transition-colors cursor-pointer
|
|
9174
|
+
${isChildActive ? s.childActive : s.childInactive}
|
|
9175
|
+
`,
|
|
9176
|
+
style: {
|
|
9177
|
+
...isChildActive ? s.activeChildStyle : {},
|
|
9178
|
+
...isChildActive && primaryColor ? applier.childActive(primaryColor) : {}
|
|
9179
|
+
},
|
|
9180
|
+
children: child.label
|
|
8686
9181
|
},
|
|
8687
|
-
|
|
8688
|
-
)
|
|
8689
|
-
|
|
8690
|
-
}
|
|
8691
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8692
|
-
"button",
|
|
8693
|
-
{
|
|
8694
|
-
onClick: () => handleItemClick(child.path ?? ""),
|
|
8695
|
-
className: `
|
|
8696
|
-
w-full text-left px-3 py-1.5 rounded-lg text-sm transition-colors cursor-pointer
|
|
8697
|
-
${pathname === child.path ? "bg-blue-50 text-blue-600 font-medium" : "text-gray-600 hover:bg-gray-50 hover:text-gray-900"}
|
|
8698
|
-
`,
|
|
8699
|
-
children: child.label
|
|
8700
|
-
},
|
|
8701
|
-
childIndex
|
|
8702
|
-
);
|
|
9182
|
+
childIndex
|
|
9183
|
+
);
|
|
9184
|
+
}) })
|
|
9185
|
+
] }, item.label);
|
|
8703
9186
|
}) })
|
|
8704
|
-
] },
|
|
8705
|
-
]
|
|
8706
|
-
|
|
8707
|
-
|
|
8708
|
-
|
|
8709
|
-
|
|
8710
|
-
|
|
9187
|
+
] }, section.title ?? sectionIndex)) })
|
|
9188
|
+
]
|
|
9189
|
+
}
|
|
9190
|
+
)
|
|
9191
|
+
]
|
|
9192
|
+
}
|
|
9193
|
+
);
|
|
8711
9194
|
}
|
|
8712
9195
|
function useDetailController(params = {}) {
|
|
8713
9196
|
const { mode: controlledMode, onModeChange } = params;
|
|
@@ -9004,10 +9487,7 @@ function DetailModalFrame(props) {
|
|
|
9004
9487
|
const isEditMode = controller.mode === "edit";
|
|
9005
9488
|
const canEdit = Boolean(editSchema && (editFields || renderEditBody));
|
|
9006
9489
|
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { isOpen: open, onClose: handleClose, contentClassName: cn("max-w-2xl", contentClassName), children: [
|
|
9007
|
-
/* @__PURE__ */ jsxRuntime.
|
|
9008
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-semibold text-gray-900", children: title }),
|
|
9009
|
-
!isEditMode && canEdit && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", size: "sm", onClick: handleEdit, children: "\uC218\uC815" })
|
|
9010
|
-
] }),
|
|
9490
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModalHeader, { className: "flex flex-row items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-semibold text-gray-900", children: title }) }),
|
|
9011
9491
|
/* @__PURE__ */ jsxRuntime.jsxs(ModalBody, { className: "flex-1 min-h-0 overflow-hidden p-0 flex flex-col", children: [
|
|
9012
9492
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9013
9493
|
DetailContent,
|
|
@@ -9027,8 +9507,9 @@ function DetailModalFrame(props) {
|
|
|
9027
9507
|
] }),
|
|
9028
9508
|
/* @__PURE__ */ jsxRuntime.jsx(ModalFooter, { className: "flex justify-end gap-2", children: isEditMode ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
9029
9509
|
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: handleCancelEdit, disabled: controller.isSaving, children: "\uCDE8\uC18C" }),
|
|
9030
|
-
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", form: controller.formId, variant: "save", disabled: controller.isSaving, children:
|
|
9510
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", form: controller.formId, variant: "save", disabled: controller.isSaving, children: "\uC800\uC7A5" })
|
|
9031
9511
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
9512
|
+
canEdit && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: handleEdit, children: "\uC218\uC815" }),
|
|
9032
9513
|
renderFooterExtra,
|
|
9033
9514
|
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: handleClose, children: "\uB2EB\uAE30" })
|
|
9034
9515
|
] }) })
|