@farmzone/fz-react-ui 1.0.1 → 1.0.2
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 +313 -149
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -82
- package/dist/index.d.ts +88 -82
- package/dist/index.js +313 -149
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -909,7 +909,7 @@ var SELECT_BORDER_COLORS = {
|
|
|
909
909
|
};
|
|
910
910
|
function Select2(props) {
|
|
911
911
|
const {
|
|
912
|
-
|
|
912
|
+
containerClassName,
|
|
913
913
|
options,
|
|
914
914
|
placeholder = "\uC120\uD0DD\uD574 \uC8FC\uC138\uC694",
|
|
915
915
|
triggerClassName,
|
|
@@ -939,7 +939,7 @@ function Select2(props) {
|
|
|
939
939
|
onChange("");
|
|
940
940
|
onReset?.();
|
|
941
941
|
};
|
|
942
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-0.5",
|
|
942
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-0.5", containerClassName ?? "w-30"), children: [
|
|
943
943
|
label && /* @__PURE__ */ jsx(
|
|
944
944
|
"label",
|
|
945
945
|
{
|
|
@@ -1022,6 +1022,7 @@ function Radio(props) {
|
|
|
1022
1022
|
checked,
|
|
1023
1023
|
onChange,
|
|
1024
1024
|
disabled = false,
|
|
1025
|
+
disabledMessage,
|
|
1025
1026
|
checkColor = DEFAULT_CHECK_COLOR,
|
|
1026
1027
|
unCheckColor = DEFAULT_UNCHECK_COLOR,
|
|
1027
1028
|
labelClassName,
|
|
@@ -1070,23 +1071,29 @@ function Radio(props) {
|
|
|
1070
1071
|
}
|
|
1071
1072
|
)
|
|
1072
1073
|
] });
|
|
1074
|
+
const withTooltip = (node) => {
|
|
1075
|
+
if (!disabled || !disabledMessage) return node;
|
|
1076
|
+
return /* @__PURE__ */ jsx(Tooltip2, { content: disabledMessage, position: "bottom", asChild: true, sideOffset: 4, children: /* @__PURE__ */ jsx("span", { className: "inline-flex", children: node }) });
|
|
1077
|
+
};
|
|
1073
1078
|
if (onChange !== void 0 && checked !== void 0) {
|
|
1074
|
-
return
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1079
|
+
return withTooltip(
|
|
1080
|
+
/* @__PURE__ */ jsx(
|
|
1081
|
+
RadioGroupPrimitive.Root,
|
|
1082
|
+
{
|
|
1083
|
+
name,
|
|
1084
|
+
value: checked ? value : "",
|
|
1085
|
+
onValueChange: (newValue) => {
|
|
1086
|
+
if (newValue === value) {
|
|
1087
|
+
onChange(value);
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1090
|
+
disabled,
|
|
1091
|
+
children: control
|
|
1092
|
+
}
|
|
1093
|
+
)
|
|
1087
1094
|
);
|
|
1088
1095
|
}
|
|
1089
|
-
return control;
|
|
1096
|
+
return withTooltip(control);
|
|
1090
1097
|
}
|
|
1091
1098
|
function RadioGroup(props) {
|
|
1092
1099
|
const {
|
|
@@ -1122,6 +1129,7 @@ function RadioGroup(props) {
|
|
|
1122
1129
|
value: option.value,
|
|
1123
1130
|
label: option.label,
|
|
1124
1131
|
disabled: disabled || option.disabled,
|
|
1132
|
+
disabledMessage: option.disabled ? option.disabledMessage : void 0,
|
|
1125
1133
|
checkColor,
|
|
1126
1134
|
unCheckColor,
|
|
1127
1135
|
labelClassName,
|
|
@@ -1926,6 +1934,28 @@ function parseLocalYmd(ymd) {
|
|
|
1926
1934
|
if (dt.getFullYear() !== y || dt.getMonth() !== mo || dt.getDate() !== d) return null;
|
|
1927
1935
|
return dt;
|
|
1928
1936
|
}
|
|
1937
|
+
function canSelectToday(options) {
|
|
1938
|
+
const today = options.now ?? /* @__PURE__ */ new Date();
|
|
1939
|
+
const todayYmd = formatDate(today);
|
|
1940
|
+
if (options.maxDate && isCalendarDayAfterMax(today, options.maxDate)) {
|
|
1941
|
+
return false;
|
|
1942
|
+
}
|
|
1943
|
+
if (!options.range) {
|
|
1944
|
+
return true;
|
|
1945
|
+
}
|
|
1946
|
+
if (options.isSelectingEnd) {
|
|
1947
|
+
const start = options.rangeStart?.trim() ?? "";
|
|
1948
|
+
if (start.length === 10 && todayYmd < start) {
|
|
1949
|
+
return false;
|
|
1950
|
+
}
|
|
1951
|
+
return true;
|
|
1952
|
+
}
|
|
1953
|
+
const end = options.rangeEnd?.trim() ?? "";
|
|
1954
|
+
if (end.length === 10 && todayYmd > end) {
|
|
1955
|
+
return false;
|
|
1956
|
+
}
|
|
1957
|
+
return true;
|
|
1958
|
+
}
|
|
1929
1959
|
function isCalendarDayAfterMax(date, maxYmd) {
|
|
1930
1960
|
const max = parseLocalYmd(maxYmd);
|
|
1931
1961
|
if (!max) return false;
|
|
@@ -1982,6 +2012,105 @@ function validateAndFormatInput(input) {
|
|
|
1982
2012
|
}
|
|
1983
2013
|
return `${year}-${month}-${day}`;
|
|
1984
2014
|
}
|
|
2015
|
+
|
|
2016
|
+
// src/components/DatePicker/calendar/config/default.ts
|
|
2017
|
+
var DEFAULT_CALENDAR_YEAR_HALF_SPAN = 25;
|
|
2018
|
+
var CALENDAR_WEEKDAY_LABELS = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
|
|
2019
|
+
var CALENDAR_RANGE_HINT = {
|
|
2020
|
+
start: "\uC2DC\uC791 \uB0A0\uC9DC\uB97C \uC120\uD0DD\uD558\uC138\uC694",
|
|
2021
|
+
end: "\uC885\uB8CC \uB0A0\uC9DC\uB97C \uC120\uD0DD\uD558\uC138\uC694"
|
|
2022
|
+
};
|
|
2023
|
+
var CALENDAR_PORTAL_Z_INDEX = Z_INDEX.CALENDAR_PORTAL;
|
|
2024
|
+
var CALENDAR_SELECT_CLASSNAMES = {
|
|
2025
|
+
containerClass: "w-20 shrink-0",
|
|
2026
|
+
triggerClassName: "h-8 px-2 py-1 text-sm cursor-pointer",
|
|
2027
|
+
contentClassName: "min-w-[5rem]"
|
|
2028
|
+
};
|
|
2029
|
+
var CALENDAR_PANEL_BASE_CLASS = "bg-white border border-gray-300 rounded-lg shadow-lg p-3 min-w-[280px]";
|
|
2030
|
+
var CALENDAR_PANEL_ANCHORED_CLASS = `${CALENDAR_PANEL_BASE_CLASS} absolute z-50`;
|
|
2031
|
+
var YEAR_SELECT_CONTENT_EXTRA_CLASS = "year-select-content custom-view-scrollbar max-h-50 overflow-y-auto";
|
|
2032
|
+
var YEAR_SELECT_OPEN_CONTENT_SELECTOR = ".year-select-content[data-state='open']";
|
|
2033
|
+
var SELECT_ITEM_CHECKED_SELECTOR = "[data-slot='select-item'][data-state='checked']";
|
|
2034
|
+
|
|
2035
|
+
// src/components/DatePicker/calendar/config/calendar.ts
|
|
2036
|
+
function parseYmdDateString(value) {
|
|
2037
|
+
if (value.length !== 10) return null;
|
|
2038
|
+
return parseLocalYmd(value);
|
|
2039
|
+
}
|
|
2040
|
+
function resolveCalendarYearBounds(anchorYear, calendarYearRange) {
|
|
2041
|
+
const fallbackMin = anchorYear - DEFAULT_CALENDAR_YEAR_HALF_SPAN;
|
|
2042
|
+
const fallbackMax = anchorYear + DEFAULT_CALENDAR_YEAR_HALF_SPAN;
|
|
2043
|
+
const rawMin = calendarYearRange?.minYear?.trim();
|
|
2044
|
+
const rawMax = calendarYearRange?.maxYear?.trim();
|
|
2045
|
+
if (rawMin === void 0 || rawMin === "" || rawMax === void 0 || rawMax === "") {
|
|
2046
|
+
return { minYear: fallbackMin, maxYear: fallbackMax };
|
|
2047
|
+
}
|
|
2048
|
+
const minParsed = Number.parseInt(rawMin, 10);
|
|
2049
|
+
const maxParsed = Number.parseInt(rawMax, 10);
|
|
2050
|
+
if (Number.isNaN(minParsed) || Number.isNaN(maxParsed) || minParsed > maxParsed) {
|
|
2051
|
+
return { minYear: fallbackMin, maxYear: fallbackMax };
|
|
2052
|
+
}
|
|
2053
|
+
return { minYear: minParsed, maxYear: maxParsed };
|
|
2054
|
+
}
|
|
2055
|
+
function buildCalendarYearSelectOptions(maxDate, anchorYear = (/* @__PURE__ */ new Date()).getFullYear(), calendarYearRange) {
|
|
2056
|
+
const { minYear, maxYear } = resolveCalendarYearBounds(anchorYear, calendarYearRange);
|
|
2057
|
+
const maxSelectableYear = maxDate ? parseLocalYmd(maxDate)?.getFullYear() ?? null : null;
|
|
2058
|
+
const options = [];
|
|
2059
|
+
for (let y = maxYear; y >= minYear; y--) {
|
|
2060
|
+
options.push({
|
|
2061
|
+
value: String(y),
|
|
2062
|
+
label: `${y}\uB144`,
|
|
2063
|
+
disabled: maxSelectableYear !== null && y > maxSelectableYear
|
|
2064
|
+
});
|
|
2065
|
+
}
|
|
2066
|
+
return options;
|
|
2067
|
+
}
|
|
2068
|
+
function buildCalendarMonthSelectOptions(viewYear, maxDate) {
|
|
2069
|
+
const maxDateParsed = maxDate ? parseLocalYmd(maxDate) : null;
|
|
2070
|
+
const maxYear = maxDateParsed?.getFullYear() ?? null;
|
|
2071
|
+
const maxMonth = maxDateParsed !== null && maxDateParsed !== void 0 ? maxDateParsed.getMonth() + 1 : null;
|
|
2072
|
+
const isMaxYear = maxYear !== null && viewYear === maxYear;
|
|
2073
|
+
const options = [];
|
|
2074
|
+
for (let m = 1; m <= 12; m++) {
|
|
2075
|
+
options.push({
|
|
2076
|
+
value: String(m),
|
|
2077
|
+
label: `${m}\uC6D4`,
|
|
2078
|
+
disabled: isMaxYear && maxMonth !== null && m > maxMonth
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
return options;
|
|
2082
|
+
}
|
|
2083
|
+
function getCalendarMonthGrid(year, monthIndex) {
|
|
2084
|
+
const firstDay = new Date(year, monthIndex, 1);
|
|
2085
|
+
const daysInMonth = new Date(year, monthIndex + 1, 0).getDate();
|
|
2086
|
+
const leadingEmpty = firstDay.getDay();
|
|
2087
|
+
const totalCells = leadingEmpty + daysInMonth;
|
|
2088
|
+
const trailingEmpty = totalCells % 7 === 0 ? 0 : 7 - totalCells % 7;
|
|
2089
|
+
return { leadingEmpty, daysInMonth, trailingEmpty };
|
|
2090
|
+
}
|
|
2091
|
+
function disableNextCalendarMonth(year, monthIndex, maxDate) {
|
|
2092
|
+
if (maxDate === void 0) return false;
|
|
2093
|
+
return isCalendarDayAfterMax(new Date(year, monthIndex + 1, 1), maxDate);
|
|
2094
|
+
}
|
|
2095
|
+
function scrollOpenYearSelectCheckedIntoView() {
|
|
2096
|
+
requestAnimationFrame(() => {
|
|
2097
|
+
const root2 = document.querySelector(YEAR_SELECT_OPEN_CONTENT_SELECTOR);
|
|
2098
|
+
if (!(root2 instanceof HTMLElement)) return;
|
|
2099
|
+
const checkedItem = root2.querySelector(SELECT_ITEM_CHECKED_SELECTOR);
|
|
2100
|
+
if (!(checkedItem instanceof HTMLElement)) return;
|
|
2101
|
+
checkedItem.scrollIntoView({ block: "start" });
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
2104
|
+
function dayCellButtonClass(opts) {
|
|
2105
|
+
const { isToday, isSelected, isInRange, isRangeStart, isRangeEnd, interactiveDisabled } = opts;
|
|
2106
|
+
const parts = ["w-8 h-8 text-sm flex items-center justify-center rounded-2xl transition-colors"];
|
|
2107
|
+
if (isToday) parts.push("bg-gray-100");
|
|
2108
|
+
if (isSelected && !isToday) parts.push("bg-neutral-200 text-gray-700");
|
|
2109
|
+
if (isInRange && !isToday) parts.push("bg-gray-100/90");
|
|
2110
|
+
if ((isRangeStart || isRangeEnd) && !isToday) parts.push("bg-neutral-300 text-gray-700 opacity-100");
|
|
2111
|
+
parts.push(interactiveDisabled ? "opacity-20 cursor-not-allowed" : "hover:bg-blue-100 cursor-pointer");
|
|
2112
|
+
return parts.filter(Boolean).join(" ").trim();
|
|
2113
|
+
}
|
|
1985
2114
|
function RenderCalendar(props) {
|
|
1986
2115
|
const {
|
|
1987
2116
|
currentDate,
|
|
@@ -1996,133 +2125,163 @@ function RenderCalendar(props) {
|
|
|
1996
2125
|
goToNextMonth,
|
|
1997
2126
|
onYearChange,
|
|
1998
2127
|
onMonthChange,
|
|
2128
|
+
onSelectOpenChange,
|
|
1999
2129
|
editDateSelect = true,
|
|
2000
2130
|
datePosition = "bottom",
|
|
2001
|
-
|
|
2131
|
+
maxDate,
|
|
2132
|
+
calendarYearRange,
|
|
2133
|
+
calendarSelectContainerClass,
|
|
2134
|
+
floating = false,
|
|
2135
|
+
showTodayButton = true
|
|
2002
2136
|
} = props;
|
|
2003
2137
|
const year = currentDate.getFullYear();
|
|
2004
|
-
const
|
|
2005
|
-
const
|
|
2006
|
-
const
|
|
2007
|
-
const
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
const
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
}
|
|
2015
|
-
const lastDay = new Date(year, month + 1, 0);
|
|
2016
|
-
const startDate = new Date(firstDay);
|
|
2017
|
-
startDate.setDate(startDate.getDate() - firstDay.getDay());
|
|
2018
|
-
const endDate = new Date(lastDay);
|
|
2019
|
-
endDate.setDate(endDate.getDate() + (6 - endDate.getDay()));
|
|
2020
|
-
const totalDays = Math.ceil((endDate.getTime() - startDate.getTime()) / (1e3 * 60 * 60 * 24)) + 1;
|
|
2138
|
+
const monthIndex = currentDate.getMonth();
|
|
2139
|
+
const anchorYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
2140
|
+
const disableNextMonth = disableNextCalendarMonth(year, monthIndex, maxDate);
|
|
2141
|
+
const { leadingEmpty, daysInMonth, trailingEmpty } = getCalendarMonthGrid(year, monthIndex);
|
|
2142
|
+
const yearOptions = buildCalendarYearSelectOptions(maxDate, anchorYear, calendarYearRange);
|
|
2143
|
+
const monthOptions = buildCalendarMonthSelectOptions(year, maxDate);
|
|
2144
|
+
const todayFormatted = formatDate(/* @__PURE__ */ new Date());
|
|
2145
|
+
const selectedSingleYmd = range ? null : inputValue;
|
|
2146
|
+
const rangeStartYmd = rangeStart.trim();
|
|
2147
|
+
const rangeEndYmd = rangeEnd.trim();
|
|
2021
2148
|
const days = [];
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
for (let i = 0; i < totalDays; i++) {
|
|
2028
|
-
const date = new Date(startDate);
|
|
2029
|
-
date.setDate(startDate.getDate() + i);
|
|
2149
|
+
for (let i = 0; i < leadingEmpty; i++) {
|
|
2150
|
+
days.push(/* @__PURE__ */ jsx("div", { className: "size-8", "aria-hidden": true }, `lead-${i}`));
|
|
2151
|
+
}
|
|
2152
|
+
for (let d = 1; d <= daysInMonth; d++) {
|
|
2153
|
+
const date = new Date(year, monthIndex, d);
|
|
2030
2154
|
const dateFormatted = formatDate(date);
|
|
2031
|
-
const isToday = dateFormatted ===
|
|
2032
|
-
const isSelected = dateFormatted ===
|
|
2155
|
+
const isToday = dateFormatted === todayFormatted;
|
|
2156
|
+
const isSelected = dateFormatted === selectedSingleYmd;
|
|
2033
2157
|
const isInRange = isDateInRange(date, range, rangeStart, rangeEnd);
|
|
2034
|
-
const
|
|
2035
|
-
const
|
|
2036
|
-
const
|
|
2037
|
-
const
|
|
2038
|
-
|
|
2039
|
-
const
|
|
2158
|
+
const isRangeStartFlag = Boolean(range && dateFormatted === rangeStart);
|
|
2159
|
+
const isRangeEndFlag = Boolean(range && dateFormatted === rangeEnd);
|
|
2160
|
+
const isBeforeRangeStart = range && isSelectingEnd && rangeStartYmd.length === 10 && dateFormatted < rangeStartYmd;
|
|
2161
|
+
const isAfterRangeEnd = range && !isSelectingEnd && rangeEndYmd.length === 10 && dateFormatted > rangeEndYmd;
|
|
2162
|
+
const isGreyedForRange = Boolean(isBeforeRangeStart || isAfterRangeEnd);
|
|
2163
|
+
const isPastMax = maxDate ? isCalendarDayAfterMax(date, maxDate) : false;
|
|
2040
2164
|
days.push(
|
|
2041
2165
|
/* @__PURE__ */ jsx(
|
|
2042
2166
|
"button",
|
|
2043
2167
|
{
|
|
2168
|
+
type: "button",
|
|
2044
2169
|
onClick: () => handleDateSelect(date),
|
|
2045
|
-
disabled:
|
|
2046
|
-
className:
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
children: date.getDate()
|
|
2170
|
+
disabled: isGreyedForRange || isPastMax,
|
|
2171
|
+
className: dayCellButtonClass({
|
|
2172
|
+
isToday,
|
|
2173
|
+
isSelected: Boolean(isSelected),
|
|
2174
|
+
isInRange,
|
|
2175
|
+
isRangeStart: isRangeStartFlag,
|
|
2176
|
+
isRangeEnd: isRangeEndFlag,
|
|
2177
|
+
interactiveDisabled: isGreyedForRange || isPastMax
|
|
2178
|
+
}),
|
|
2179
|
+
children: d
|
|
2056
2180
|
},
|
|
2057
|
-
|
|
2181
|
+
d
|
|
2058
2182
|
)
|
|
2059
2183
|
);
|
|
2060
2184
|
}
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
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
|
-
|
|
2185
|
+
for (let i = 0; i < trailingEmpty; i++) {
|
|
2186
|
+
days.push(/* @__PURE__ */ jsx("div", { className: "size-8", "aria-hidden": true }, `trail-${i}`));
|
|
2187
|
+
}
|
|
2188
|
+
const calendarPositionClass = !floating && range && calendarPosition === "end" ? "right-0" : !floating ? "left-0" : "";
|
|
2189
|
+
const datePositionClass = floating ? "" : datePosition === "top" ? "bottom-full mb-1" : "top-full mt-1";
|
|
2190
|
+
const panelClass = floating ? CALENDAR_PANEL_BASE_CLASS : cn(CALENDAR_PANEL_ANCHORED_CLASS, datePositionClass, calendarPositionClass);
|
|
2191
|
+
const handleYearSelectOpenChange = (open) => {
|
|
2192
|
+
onSelectOpenChange?.(open);
|
|
2193
|
+
if (open) scrollOpenYearSelectCheckedIntoView();
|
|
2194
|
+
};
|
|
2195
|
+
const sel = CALENDAR_SELECT_CLASSNAMES;
|
|
2196
|
+
const containerClass = cn(sel.containerClass, calendarSelectContainerClass);
|
|
2197
|
+
const stopBubble = (e) => e.stopPropagation();
|
|
2198
|
+
const isTodaySelectable = canSelectToday({
|
|
2199
|
+
maxDate,
|
|
2200
|
+
range,
|
|
2201
|
+
isSelectingEnd,
|
|
2202
|
+
rangeStart,
|
|
2203
|
+
rangeEnd
|
|
2204
|
+
});
|
|
2205
|
+
return /* @__PURE__ */ jsxs("div", { className: panelClass, onClick: stopBubble, onMouseDown: stopBubble, children: [
|
|
2206
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center justify-between", children: [
|
|
2207
|
+
/* @__PURE__ */ jsx(
|
|
2208
|
+
"button",
|
|
2209
|
+
{
|
|
2210
|
+
type: "button",
|
|
2211
|
+
onClick: goToPreviousMonth,
|
|
2212
|
+
className: "cursor-pointer rounded p-1 hover:bg-gray-100",
|
|
2213
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" })
|
|
2214
|
+
}
|
|
2215
|
+
),
|
|
2216
|
+
editDateSelect ? /* @__PURE__ */ jsxs(
|
|
2217
|
+
"div",
|
|
2218
|
+
{
|
|
2219
|
+
role: "presentation",
|
|
2220
|
+
className: "flex items-center gap-2",
|
|
2221
|
+
onClick: stopBubble,
|
|
2222
|
+
onMouseDown: stopBubble,
|
|
2223
|
+
children: [
|
|
2224
|
+
/* @__PURE__ */ jsx(
|
|
2225
|
+
Select2,
|
|
2226
|
+
{
|
|
2227
|
+
value: year.toString(),
|
|
2228
|
+
options: yearOptions,
|
|
2229
|
+
onChange: (value) => onYearChange(Number.parseInt(value, 10)),
|
|
2230
|
+
containerClassName: containerClass,
|
|
2231
|
+
triggerClassName: sel.triggerClassName,
|
|
2232
|
+
contentClassName: cn(YEAR_SELECT_CONTENT_EXTRA_CLASS, sel.contentClassName),
|
|
2233
|
+
disableScrollButtonEvents: true,
|
|
2234
|
+
onOpenChange: handleYearSelectOpenChange
|
|
2235
|
+
}
|
|
2236
|
+
),
|
|
2237
|
+
/* @__PURE__ */ jsx(
|
|
2238
|
+
Select2,
|
|
2239
|
+
{
|
|
2240
|
+
value: (monthIndex + 1).toString(),
|
|
2241
|
+
options: monthOptions,
|
|
2242
|
+
onChange: (value) => onMonthChange(Number.parseInt(value, 10) - 1),
|
|
2243
|
+
containerClassName: containerClass,
|
|
2244
|
+
triggerClassName: sel.triggerClassName,
|
|
2245
|
+
contentClassName: sel.contentClassName,
|
|
2246
|
+
onOpenChange: (open) => onSelectOpenChange?.(open)
|
|
2247
|
+
}
|
|
2248
|
+
)
|
|
2249
|
+
]
|
|
2250
|
+
}
|
|
2251
|
+
) : /* @__PURE__ */ jsxs("h3", { className: "text-lg font-semibold", children: [
|
|
2252
|
+
year,
|
|
2253
|
+
"\uB144 ",
|
|
2254
|
+
monthIndex + 1,
|
|
2255
|
+
"\uC6D4"
|
|
2256
|
+
] }),
|
|
2257
|
+
/* @__PURE__ */ jsx(
|
|
2258
|
+
"button",
|
|
2259
|
+
{
|
|
2260
|
+
type: "button",
|
|
2261
|
+
onClick: goToNextMonth,
|
|
2262
|
+
disabled: disableNextMonth,
|
|
2263
|
+
className: cn(
|
|
2264
|
+
"rounded p-1",
|
|
2265
|
+
disableNextMonth ? "cursor-not-allowed opacity-30" : "cursor-pointer hover:bg-gray-100"
|
|
2266
|
+
),
|
|
2267
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
|
|
2268
|
+
}
|
|
2269
|
+
)
|
|
2270
|
+
] }),
|
|
2271
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 grid grid-cols-7 gap-1", children: CALENDAR_WEEKDAY_LABELS.map((day) => /* @__PURE__ */ jsx("div", { className: "py-2 text-center text-sm font-medium text-gray-500", children: day }, day)) }),
|
|
2272
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-2", children: days }),
|
|
2273
|
+
range && /* @__PURE__ */ jsx("div", { className: "mt-3 text-sm text-gray-600", children: /* @__PURE__ */ jsx("p", { className: "text-center", children: isSelectingEnd ? CALENDAR_RANGE_HINT.end : CALENDAR_RANGE_HINT.start }) }),
|
|
2274
|
+
showTodayButton && isTodaySelectable && /* @__PURE__ */ jsx("div", { className: "-mx-3 -mb-3 mt-3 flex items-center justify-center border-t border-gray-200 py-2", children: /* @__PURE__ */ jsx(
|
|
2275
|
+
"button",
|
|
2276
|
+
{
|
|
2277
|
+
type: "button",
|
|
2278
|
+
onClick: () => handleDateSelect(/* @__PURE__ */ new Date()),
|
|
2279
|
+
className: "cursor-pointer text-sm text-gray-800 hover:text-main",
|
|
2280
|
+
children: "Today"
|
|
2281
|
+
}
|
|
2282
|
+
) })
|
|
2283
|
+
] });
|
|
2123
2284
|
}
|
|
2124
|
-
|
|
2125
|
-
// src/components/DatePicker/calendar/hooks/useCalendarState.ts
|
|
2126
2285
|
function useCalendarState(props) {
|
|
2127
2286
|
const { datePosition = "bottom", disabled = false, calendarRef } = props;
|
|
2128
2287
|
const [isCalendarOpen, setIsCalendarOpen] = useState(false);
|
|
@@ -2219,11 +2378,15 @@ function useFloatingCalendarPosition(anchorRef, isOpen2, placement, align = "sta
|
|
|
2219
2378
|
setStyle({ ...base, top: rect.bottom + CALENDAR_GAP });
|
|
2220
2379
|
}
|
|
2221
2380
|
};
|
|
2381
|
+
const handleScroll = (e) => {
|
|
2382
|
+
if (e.target?.closest?.('[data-slot="select-content"]')) return;
|
|
2383
|
+
update();
|
|
2384
|
+
};
|
|
2222
2385
|
update();
|
|
2223
|
-
window.addEventListener("scroll",
|
|
2386
|
+
window.addEventListener("scroll", handleScroll, true);
|
|
2224
2387
|
window.addEventListener("resize", update);
|
|
2225
2388
|
return () => {
|
|
2226
|
-
window.removeEventListener("scroll",
|
|
2389
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
2227
2390
|
window.removeEventListener("resize", update);
|
|
2228
2391
|
};
|
|
2229
2392
|
}, [isOpen2, placement, align, anchorRef]);
|
|
@@ -6531,7 +6694,7 @@ function CascadingSelectFieldInner(props) {
|
|
|
6531
6694
|
disabled,
|
|
6532
6695
|
hasError,
|
|
6533
6696
|
options: toSelectOptions(primaryOptions),
|
|
6534
|
-
|
|
6697
|
+
containerClassName: firstSelectClass.containerClassName,
|
|
6535
6698
|
triggerClassName: firstSelectClass.triggerClassName,
|
|
6536
6699
|
canReset: true,
|
|
6537
6700
|
onChange: (nextPrimary) => {
|
|
@@ -6548,7 +6711,7 @@ function CascadingSelectFieldInner(props) {
|
|
|
6548
6711
|
disabled: disabled || !primary || secondaryOptions.length === 0,
|
|
6549
6712
|
hasError,
|
|
6550
6713
|
options: toSelectOptions(secondaryOptions),
|
|
6551
|
-
|
|
6714
|
+
containerClassName: secondSelectClass.containerClassName,
|
|
6552
6715
|
triggerClassName: secondSelectClass.triggerClassName,
|
|
6553
6716
|
canReset: true,
|
|
6554
6717
|
onChange: (nextSecondary) => {
|
|
@@ -6592,7 +6755,8 @@ function DateField(props) {
|
|
|
6592
6755
|
readOnly = false,
|
|
6593
6756
|
className = "w-40",
|
|
6594
6757
|
datePosition = "bottom",
|
|
6595
|
-
disableFutureDates = false
|
|
6758
|
+
disableFutureDates = false,
|
|
6759
|
+
calendarSelectContainerClass = "w-20"
|
|
6596
6760
|
} = config;
|
|
6597
6761
|
const maxDate = disableFutureDates ? formatDate(/* @__PURE__ */ new Date()) : void 0;
|
|
6598
6762
|
if (readOnly) {
|
|
@@ -6609,7 +6773,8 @@ function DateField(props) {
|
|
|
6609
6773
|
className: "w-full",
|
|
6610
6774
|
validation: hasError,
|
|
6611
6775
|
datePosition,
|
|
6612
|
-
maxDate
|
|
6776
|
+
maxDate,
|
|
6777
|
+
calendarSelectContainerClass
|
|
6613
6778
|
}
|
|
6614
6779
|
) });
|
|
6615
6780
|
}
|
|
@@ -6799,7 +6964,9 @@ function RadioField(props) {
|
|
|
6799
6964
|
containerClassName: cn2("justify-start", fieldControlWrapClass(className)),
|
|
6800
6965
|
options: options.map((option) => ({
|
|
6801
6966
|
label: option.label,
|
|
6802
|
-
value: String(option.value)
|
|
6967
|
+
value: String(option.value),
|
|
6968
|
+
disabled: option.disabled,
|
|
6969
|
+
disabledMessage: option.disabledMessage
|
|
6803
6970
|
}))
|
|
6804
6971
|
}
|
|
6805
6972
|
);
|
|
@@ -6837,7 +7004,7 @@ function SelectField(props) {
|
|
|
6837
7004
|
disabled,
|
|
6838
7005
|
hasError,
|
|
6839
7006
|
options: selectOptions,
|
|
6840
|
-
|
|
7007
|
+
containerClassName: "flex w-full min-w-0 max-w-full items-center",
|
|
6841
7008
|
className: "w-full min-w-0",
|
|
6842
7009
|
triggerClassName: cn2(
|
|
6843
7010
|
"h-8 w-full min-w-0 max-w-full rounded border bg-white px-2 py-1 text-sm shadow-none",
|
|
@@ -6949,11 +7116,12 @@ function SelectWithInputField(props) {
|
|
|
6949
7116
|
disabled,
|
|
6950
7117
|
hasError,
|
|
6951
7118
|
options: toSelectOptions(options),
|
|
6952
|
-
|
|
7119
|
+
containerClassName: selectClass.containerClassName,
|
|
6953
7120
|
triggerClassName: selectClass.triggerClassName,
|
|
6954
7121
|
onChange: (nextPrefix) => {
|
|
6955
7122
|
setSelectedPrefix(nextPrefix);
|
|
6956
7123
|
updateCombined(nextPrefix, inputPart);
|
|
7124
|
+
onBlur();
|
|
6957
7125
|
}
|
|
6958
7126
|
}
|
|
6959
7127
|
),
|
|
@@ -7088,7 +7256,7 @@ function useBlurValidation(name, options) {
|
|
|
7088
7256
|
(value, fieldOnChange) => {
|
|
7089
7257
|
markHadValueIfFilled(value);
|
|
7090
7258
|
fieldOnChange(value);
|
|
7091
|
-
if (options.revalidateOnChange || shouldValidateEmptyOnChange(value)) {
|
|
7259
|
+
if (options.revalidateOnChange || options.validateEmptyOnChange && shouldValidateEmptyOnChange(value)) {
|
|
7092
7260
|
void trigger(name);
|
|
7093
7261
|
}
|
|
7094
7262
|
void triggerRelatedFields();
|
|
@@ -7096,6 +7264,7 @@ function useBlurValidation(name, options) {
|
|
|
7096
7264
|
[
|
|
7097
7265
|
markHadValueIfFilled,
|
|
7098
7266
|
options.revalidateOnChange,
|
|
7267
|
+
options.validateEmptyOnChange,
|
|
7099
7268
|
shouldValidateEmptyOnChange,
|
|
7100
7269
|
trigger,
|
|
7101
7270
|
name,
|
|
@@ -7116,9 +7285,7 @@ var REVALIDATE_ON_CHANGE_TYPES = /* @__PURE__ */ new Set([
|
|
|
7116
7285
|
"radio",
|
|
7117
7286
|
"switch",
|
|
7118
7287
|
"select",
|
|
7119
|
-
"date",
|
|
7120
7288
|
"cascading-select",
|
|
7121
|
-
"select-with-input",
|
|
7122
7289
|
"input-with-button",
|
|
7123
7290
|
"address"
|
|
7124
7291
|
]);
|
|
@@ -7139,14 +7306,15 @@ function FormFieldRow(props) {
|
|
|
7139
7306
|
const { control } = useFormContext();
|
|
7140
7307
|
const { isSubmitted } = useFormState({ control });
|
|
7141
7308
|
const { name, label, type = "input", required = false, renderCustomField, contentAlign = "left" } = config;
|
|
7309
|
+
const revalidateOnChange = REVALIDATE_ON_CHANGE_TYPES.has(type);
|
|
7142
7310
|
const { handleBlur, handleChange } = useBlurValidation(name, {
|
|
7143
7311
|
required,
|
|
7144
|
-
revalidateOnChange
|
|
7312
|
+
revalidateOnChange,
|
|
7313
|
+
validateEmptyOnChange: revalidateOnChange,
|
|
7145
7314
|
revalidateFields: config.revalidateFields
|
|
7146
7315
|
});
|
|
7147
7316
|
const showError = Boolean(fieldState.error?.message) && (isSubmitted || fieldState.isTouched);
|
|
7148
7317
|
const isTextarea = type === "textarea";
|
|
7149
|
-
const revalidateOnChange = REVALIDATE_ON_CHANGE_TYPES.has(type);
|
|
7150
7318
|
const wrappedField = wrapFieldHandlers(field, {
|
|
7151
7319
|
onBlur: () => handleBlur(() => field.onBlur()),
|
|
7152
7320
|
onChange: (value) => {
|
|
@@ -7251,6 +7419,7 @@ function rowPropsToFieldConfig(props) {
|
|
|
7251
7419
|
canReset,
|
|
7252
7420
|
datePosition,
|
|
7253
7421
|
disableFutureDates,
|
|
7422
|
+
calendarSelectContainerClass,
|
|
7254
7423
|
revalidateFields,
|
|
7255
7424
|
renderCustomField,
|
|
7256
7425
|
colspan,
|
|
@@ -7281,6 +7450,7 @@ function rowPropsToFieldConfig(props) {
|
|
|
7281
7450
|
canReset,
|
|
7282
7451
|
datePosition,
|
|
7283
7452
|
disableFutureDates,
|
|
7453
|
+
calendarSelectContainerClass,
|
|
7284
7454
|
revalidateFields,
|
|
7285
7455
|
renderCustomField,
|
|
7286
7456
|
colspan,
|
|
@@ -7440,14 +7610,7 @@ function PageFilter(props) {
|
|
|
7440
7610
|
const rowGap2 = index !== 0 ? option.label ? gap : 5 : 0;
|
|
7441
7611
|
switch (option.type) {
|
|
7442
7612
|
case "input":
|
|
7443
|
-
return /* @__PURE__ */ jsx(LabeledFilterOption, { label: option.label, gap: rowGap2, children: /* @__PURE__ */ jsx(
|
|
7444
|
-
Input2,
|
|
7445
|
-
{
|
|
7446
|
-
placeholder: option.placeholder,
|
|
7447
|
-
value: currentValue,
|
|
7448
|
-
onChange: handleInputChange(optionKey)
|
|
7449
|
-
}
|
|
7450
|
-
) }, String(optionKey));
|
|
7613
|
+
return /* @__PURE__ */ jsx(LabeledFilterOption, { label: option.label, gap: rowGap2, children: /* @__PURE__ */ jsx(Input2, { placeholder: option.placeholder, value: currentValue, onChange: handleInputChange(optionKey) }) }, String(optionKey));
|
|
7451
7614
|
case "select":
|
|
7452
7615
|
return /* @__PURE__ */ jsx(LabeledFilterOption, { label: option.label, gap: rowGap2, children: /* @__PURE__ */ jsx(
|
|
7453
7616
|
Select2,
|
|
@@ -7455,7 +7618,8 @@ function PageFilter(props) {
|
|
|
7455
7618
|
value: currentValue,
|
|
7456
7619
|
onChange: handleSelectChange(optionKey),
|
|
7457
7620
|
options: option.options,
|
|
7458
|
-
placeholder: "\uC120\uD0DD
|
|
7621
|
+
placeholder: "\uC120\uD0DD",
|
|
7622
|
+
containerClassName: option.containerClassName ?? "w-30"
|
|
7459
7623
|
}
|
|
7460
7624
|
) }, String(optionKey));
|
|
7461
7625
|
case "radio":
|