@farmzone/fz-react-ui 1.0.0 → 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 +436 -200
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -82
- package/dist/index.d.ts +93 -82
- package/dist/index.js +436 -200
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -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,130 +2125,163 @@ function RenderCalendar(props) {
|
|
|
1996
2125
|
goToNextMonth,
|
|
1997
2126
|
onYearChange,
|
|
1998
2127
|
onMonthChange,
|
|
2128
|
+
onSelectOpenChange,
|
|
1999
2129
|
editDateSelect = true,
|
|
2000
|
-
datePosition = "bottom"
|
|
2130
|
+
datePosition = "bottom",
|
|
2131
|
+
maxDate,
|
|
2132
|
+
calendarYearRange,
|
|
2133
|
+
calendarSelectContainerClass,
|
|
2134
|
+
floating = false,
|
|
2135
|
+
showTodayButton = true
|
|
2001
2136
|
} = props;
|
|
2002
2137
|
const year = currentDate.getFullYear();
|
|
2003
|
-
const
|
|
2004
|
-
const
|
|
2005
|
-
const
|
|
2006
|
-
const
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
const
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
}
|
|
2014
|
-
const lastDay = new Date(year, month + 1, 0);
|
|
2015
|
-
const startDate = new Date(firstDay);
|
|
2016
|
-
startDate.setDate(startDate.getDate() - firstDay.getDay());
|
|
2017
|
-
const endDate = new Date(lastDay);
|
|
2018
|
-
endDate.setDate(endDate.getDate() + (6 - endDate.getDay()));
|
|
2019
|
-
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();
|
|
2020
2148
|
const days = [];
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
for (let i = 0; i < totalDays; i++) {
|
|
2027
|
-
const date = new Date(startDate);
|
|
2028
|
-
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);
|
|
2029
2154
|
const dateFormatted = formatDate(date);
|
|
2030
|
-
const isToday = dateFormatted ===
|
|
2031
|
-
const isSelected = dateFormatted ===
|
|
2155
|
+
const isToday = dateFormatted === todayFormatted;
|
|
2156
|
+
const isSelected = dateFormatted === selectedSingleYmd;
|
|
2032
2157
|
const isInRange = isDateInRange(date, range, rangeStart, rangeEnd);
|
|
2033
|
-
const
|
|
2034
|
-
const
|
|
2035
|
-
const
|
|
2036
|
-
const
|
|
2037
|
-
|
|
2038
|
-
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;
|
|
2039
2164
|
days.push(
|
|
2040
2165
|
/* @__PURE__ */ jsx(
|
|
2041
2166
|
"button",
|
|
2042
2167
|
{
|
|
2168
|
+
type: "button",
|
|
2043
2169
|
onClick: () => handleDateSelect(date),
|
|
2044
|
-
disabled:
|
|
2045
|
-
className:
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
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
|
|
2055
2180
|
},
|
|
2056
|
-
|
|
2181
|
+
d
|
|
2057
2182
|
)
|
|
2058
2183
|
);
|
|
2059
2184
|
}
|
|
2060
|
-
|
|
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
|
-
|
|
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
|
+
] });
|
|
2120
2284
|
}
|
|
2121
|
-
|
|
2122
|
-
// src/components/DatePicker/calendar/hooks/useCalendarState.ts
|
|
2123
2285
|
function useCalendarState(props) {
|
|
2124
2286
|
const { datePosition = "bottom", disabled = false, calendarRef } = props;
|
|
2125
2287
|
const [isCalendarOpen, setIsCalendarOpen] = useState(false);
|
|
@@ -2216,11 +2378,15 @@ function useFloatingCalendarPosition(anchorRef, isOpen2, placement, align = "sta
|
|
|
2216
2378
|
setStyle({ ...base, top: rect.bottom + CALENDAR_GAP });
|
|
2217
2379
|
}
|
|
2218
2380
|
};
|
|
2381
|
+
const handleScroll = (e) => {
|
|
2382
|
+
if (e.target?.closest?.('[data-slot="select-content"]')) return;
|
|
2383
|
+
update();
|
|
2384
|
+
};
|
|
2219
2385
|
update();
|
|
2220
|
-
window.addEventListener("scroll",
|
|
2386
|
+
window.addEventListener("scroll", handleScroll, true);
|
|
2221
2387
|
window.addEventListener("resize", update);
|
|
2222
2388
|
return () => {
|
|
2223
|
-
window.removeEventListener("scroll",
|
|
2389
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
2224
2390
|
window.removeEventListener("resize", update);
|
|
2225
2391
|
};
|
|
2226
2392
|
}, [isOpen2, placement, align, anchorRef]);
|
|
@@ -2258,6 +2424,7 @@ function DatePickerRange(props) {
|
|
|
2258
2424
|
disabled = false,
|
|
2259
2425
|
maxDate,
|
|
2260
2426
|
calendarYearRange,
|
|
2427
|
+
calendarSelectContainerClass,
|
|
2261
2428
|
showTodayButton = true
|
|
2262
2429
|
} = props;
|
|
2263
2430
|
const [inputs, setInputs] = useState({ start: startValue, end: endValue });
|
|
@@ -2394,6 +2561,7 @@ function DatePickerRange(props) {
|
|
|
2394
2561
|
datePosition: autoDatePosition,
|
|
2395
2562
|
maxDate,
|
|
2396
2563
|
calendarYearRange,
|
|
2564
|
+
calendarSelectContainerClass,
|
|
2397
2565
|
showTodayButton
|
|
2398
2566
|
}
|
|
2399
2567
|
)
|
|
@@ -2473,6 +2641,7 @@ function DatePickerSingle(props) {
|
|
|
2473
2641
|
disabled = false,
|
|
2474
2642
|
maxDate,
|
|
2475
2643
|
calendarYearRange,
|
|
2644
|
+
calendarSelectContainerClass,
|
|
2476
2645
|
onBlur,
|
|
2477
2646
|
showTodayButton = true
|
|
2478
2647
|
} = props;
|
|
@@ -2565,6 +2734,7 @@ function DatePickerSingle(props) {
|
|
|
2565
2734
|
datePosition: autoDatePosition,
|
|
2566
2735
|
maxDate,
|
|
2567
2736
|
calendarYearRange,
|
|
2737
|
+
calendarSelectContainerClass,
|
|
2568
2738
|
showTodayButton
|
|
2569
2739
|
}
|
|
2570
2740
|
)
|
|
@@ -2623,6 +2793,7 @@ function DatePicker(props) {
|
|
|
2623
2793
|
disabled,
|
|
2624
2794
|
maxDate,
|
|
2625
2795
|
calendarYearRange,
|
|
2796
|
+
calendarSelectContainerClass,
|
|
2626
2797
|
showTodayButton
|
|
2627
2798
|
} = props;
|
|
2628
2799
|
if (isRange) {
|
|
@@ -2640,6 +2811,7 @@ function DatePicker(props) {
|
|
|
2640
2811
|
disabled,
|
|
2641
2812
|
maxDate,
|
|
2642
2813
|
calendarYearRange,
|
|
2814
|
+
calendarSelectContainerClass,
|
|
2643
2815
|
showTodayButton
|
|
2644
2816
|
}
|
|
2645
2817
|
);
|
|
@@ -2659,6 +2831,7 @@ function DatePicker(props) {
|
|
|
2659
2831
|
disabled,
|
|
2660
2832
|
maxDate,
|
|
2661
2833
|
calendarYearRange,
|
|
2834
|
+
calendarSelectContainerClass,
|
|
2662
2835
|
showTodayButton,
|
|
2663
2836
|
onBlur
|
|
2664
2837
|
}
|
|
@@ -3524,7 +3697,7 @@ function TableFooter(props) {
|
|
|
3524
3697
|
const { paginationInfo, renderLeft, renderRight } = props;
|
|
3525
3698
|
return /* @__PURE__ */ jsx("div", { className: "w-full", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-4 min-h-16", children: [
|
|
3526
3699
|
/* @__PURE__ */ jsx("div", { className: "flex justify-start flex-1 min-w-0", children: renderLeft }),
|
|
3527
|
-
paginationInfo && /* @__PURE__ */ jsx("div", { className: "
|
|
3700
|
+
paginationInfo && /* @__PURE__ */ jsx("div", { className: "px-5", children: /* @__PURE__ */ jsx(Pagination, { ...paginationInfo }) }),
|
|
3528
3701
|
/* @__PURE__ */ jsx("div", { className: "flex justify-end flex-1 min-w-0", children: renderRight })
|
|
3529
3702
|
] }) });
|
|
3530
3703
|
}
|
|
@@ -3680,7 +3853,7 @@ function useTableFixed(columns, isHeader = false) {
|
|
|
3680
3853
|
window.addEventListener("resize", onResize);
|
|
3681
3854
|
const firstKey = columns[0]?.key;
|
|
3682
3855
|
const cell = firstKey ? document.getElementById(`${firstKey}${isHeader ? "-header" : "-body"}`) : null;
|
|
3683
|
-
const tableEl = cell?.closest("table") || document.querySelector("table.table-
|
|
3856
|
+
const tableEl = cell?.closest("table") || document.querySelector("table.table-fixed");
|
|
3684
3857
|
if (tableEl && "ResizeObserver" in window) {
|
|
3685
3858
|
resizeObserverRef.current = new ResizeObserver(handleResize);
|
|
3686
3859
|
resizeObserverRef.current.observe(tableEl);
|
|
@@ -3767,19 +3940,14 @@ function TableHeader(props) {
|
|
|
3767
3940
|
const columns = useMemo(() => {
|
|
3768
3941
|
return customColumns.map((column) => {
|
|
3769
3942
|
const { key } = column;
|
|
3770
|
-
const
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
if (key === "__checkbox__") {
|
|
3778
|
-
return "center";
|
|
3779
|
-
}
|
|
3780
|
-
return column.align ?? "left";
|
|
3943
|
+
const isCheckbox = key === "__checkbox__";
|
|
3944
|
+
return {
|
|
3945
|
+
...column,
|
|
3946
|
+
width: isCheckbox ? "40px" : column.width,
|
|
3947
|
+
minWidth: isCheckbox ? "40px" : column.minWidth ?? column.width,
|
|
3948
|
+
maxWidth: isCheckbox ? "40px" : column.maxWidth,
|
|
3949
|
+
align: isCheckbox ? "center" : column.align ?? "left"
|
|
3781
3950
|
};
|
|
3782
|
-
return { ...column, width: getWidth(), align: getAlign() };
|
|
3783
3951
|
});
|
|
3784
3952
|
}, [customColumns]);
|
|
3785
3953
|
const { getColumnFixedStyle } = useTableFixed(columns, true);
|
|
@@ -4252,11 +4420,11 @@ function SkeletonTd(props) {
|
|
|
4252
4420
|
return /* @__PURE__ */ jsx(
|
|
4253
4421
|
"td",
|
|
4254
4422
|
{
|
|
4255
|
-
className: "px-2 py-[6.8px] whitespace-nowrap text-sm border-r border-b border-gray-200/70 last:border-r-0
|
|
4423
|
+
className: `${col.key === "__checkbox__" ? "p-0" : "px-2 py-[6.8px]"} whitespace-nowrap text-sm border-r border-b border-gray-200/70 last:border-r-0`,
|
|
4256
4424
|
style: {
|
|
4257
4425
|
width: col.width,
|
|
4258
4426
|
minWidth: col.minWidth || col.width,
|
|
4259
|
-
maxWidth: col.maxWidth || col.width
|
|
4427
|
+
maxWidth: col.key === "__checkbox__" ? col.maxWidth || col.width : void 0
|
|
4260
4428
|
},
|
|
4261
4429
|
children: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-4", children: showSquare ? /* @__PURE__ */ jsx(Skeleton, { className: "size-4 rounded-xs" }) : /* @__PURE__ */ jsx(Skeleton, { className: "h-1.5 rounded-sm", style: { width: "calc(100% - 20px)" } }) })
|
|
4262
4430
|
}
|
|
@@ -4337,7 +4505,7 @@ function getAlignStyle(align) {
|
|
|
4337
4505
|
return align === "left" ? "flex-start" : align === "center" ? "center" : "flex-end";
|
|
4338
4506
|
}
|
|
4339
4507
|
function applyColDefaults(col) {
|
|
4340
|
-
const width = col.key === "__checkbox__" ? "40px" : col.width ?? col.minWidth
|
|
4508
|
+
const width = col.key === "__checkbox__" ? "40px" : col.width ?? col.minWidth;
|
|
4341
4509
|
const align = col.key === "__checkbox__" ? "center" : col.align ?? "left";
|
|
4342
4510
|
return { ...col, width, align };
|
|
4343
4511
|
}
|
|
@@ -4786,17 +4954,18 @@ function Table(props) {
|
|
|
4786
4954
|
const { width, minWidth, maxWidth, align } = col;
|
|
4787
4955
|
const fixedStyle = isPinned ? getColumnFixedStyleRef.current(col) : void 0;
|
|
4788
4956
|
const cellContent = col.render ? col.render(record[col.key], record, rowIdx) : String(record[col.key] ?? "");
|
|
4957
|
+
const isCheckbox = col.key === "__checkbox__";
|
|
4789
4958
|
return /* @__PURE__ */ jsx(
|
|
4790
4959
|
"td",
|
|
4791
4960
|
{
|
|
4792
4961
|
id: `${col.key}-body`,
|
|
4793
4962
|
"data-row-cell": "true",
|
|
4794
4963
|
"data-col-key": col.key,
|
|
4795
|
-
className: "px-2 py-[6.8px] whitespace-nowrap text-sm text-gray-900 border-r border-b border-gray-200 last:border-r-0 bg-inherit group-hover:bg-gray-100 transition-all
|
|
4964
|
+
className: `${isCheckbox ? "p-0" : "px-2 py-[6.8px]"} whitespace-nowrap text-sm text-gray-900 border-r border-b border-gray-200 last:border-r-0 bg-inherit group-hover:bg-gray-100 transition-all`,
|
|
4796
4965
|
style: {
|
|
4797
4966
|
width,
|
|
4798
4967
|
minWidth: minWidth || width,
|
|
4799
|
-
maxWidth: maxWidth || width,
|
|
4968
|
+
maxWidth: isCheckbox ? maxWidth || width : void 0,
|
|
4800
4969
|
...fixedStyle
|
|
4801
4970
|
},
|
|
4802
4971
|
onClick: (event) => {
|
|
@@ -4892,7 +5061,7 @@ function Table(props) {
|
|
|
4892
5061
|
ref: scrollRef,
|
|
4893
5062
|
className: "relative w-full overflow-y-auto overflow-x-auto custom-view-scrollbar bg-white",
|
|
4894
5063
|
style: { height: `${tableHeight}px` },
|
|
4895
|
-
children: /* @__PURE__ */ jsxs("table", { className: "w-full table-
|
|
5064
|
+
children: /* @__PURE__ */ jsxs("table", { className: "w-full table-fixed", children: [
|
|
4896
5065
|
/* @__PURE__ */ jsx(
|
|
4897
5066
|
TableHeader,
|
|
4898
5067
|
{
|
|
@@ -5992,6 +6161,7 @@ var FORM_CONTROL_CLASS = "h-8 w-full rounded border border-gray-300 bg-white px-
|
|
|
5992
6161
|
function formControlClass(hasError, extra) {
|
|
5993
6162
|
return cn2(FORM_CONTROL_CLASS, FORM_CONTROL_FOCUS_CLASS, hasError && FORM_FIELD_ERROR_BORDER_CLASS, extra);
|
|
5994
6163
|
}
|
|
6164
|
+
var FIELD_READONLY_TEXT_CLASS = "text-sm text-gray-800 leading-tight";
|
|
5995
6165
|
function fieldControlWrapClass(className) {
|
|
5996
6166
|
return className ? cn2("min-w-0 shrink-0", className) : "min-w-0 w-full";
|
|
5997
6167
|
}
|
|
@@ -6338,6 +6508,7 @@ function AddressField(props) {
|
|
|
6338
6508
|
const {
|
|
6339
6509
|
placeholder = "\uC8FC\uC18C\uB97C \uAC80\uC0C9\uD558\uC138\uC694",
|
|
6340
6510
|
disabled = false,
|
|
6511
|
+
readOnly = false,
|
|
6341
6512
|
className = "",
|
|
6342
6513
|
addressDetailKey,
|
|
6343
6514
|
addressClassNames
|
|
@@ -6352,6 +6523,9 @@ function AddressField(props) {
|
|
|
6352
6523
|
searchButtonRef.current?.click();
|
|
6353
6524
|
}
|
|
6354
6525
|
}, [isFocused]);
|
|
6526
|
+
if (readOnly) {
|
|
6527
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: String(value ?? "") || "\u2014" }) });
|
|
6528
|
+
}
|
|
6355
6529
|
const handleComplete = (data) => {
|
|
6356
6530
|
isAddressSelectedRef.current = true;
|
|
6357
6531
|
const nextAddress = data.roadAddress || data.address;
|
|
@@ -6470,12 +6644,12 @@ function CascadingSelectField(props) {
|
|
|
6470
6644
|
}
|
|
6471
6645
|
function CascadingSelectFieldInner(props) {
|
|
6472
6646
|
const {
|
|
6473
|
-
field: { onChange, value },
|
|
6647
|
+
field: { onChange, onBlur, value },
|
|
6474
6648
|
config,
|
|
6475
6649
|
hasError = false,
|
|
6476
6650
|
cascadingSelect
|
|
6477
6651
|
} = props;
|
|
6478
|
-
const { disabled = false, className = "", cascadingSelectClassNames } = config;
|
|
6652
|
+
const { disabled = false, readOnly = false, className = "", cascadingSelectClassNames } = config;
|
|
6479
6653
|
const {
|
|
6480
6654
|
primaryOptions,
|
|
6481
6655
|
getSecondaryOptions,
|
|
@@ -6489,10 +6663,17 @@ function CascadingSelectFieldInner(props) {
|
|
|
6489
6663
|
[formValue, getSecondaryOptions, separator]
|
|
6490
6664
|
);
|
|
6491
6665
|
useLayoutEffect(() => {
|
|
6666
|
+
if (readOnly) return;
|
|
6492
6667
|
if (normalizedFormValue !== formValue) {
|
|
6493
6668
|
onChange(normalizedFormValue);
|
|
6494
6669
|
}
|
|
6495
|
-
}, [formValue, normalizedFormValue, onChange]);
|
|
6670
|
+
}, [formValue, normalizedFormValue, onChange, readOnly]);
|
|
6671
|
+
if (readOnly) {
|
|
6672
|
+
const primaryLabel = primaryOptions.find((o) => String(o.value) === primary)?.label ?? primary;
|
|
6673
|
+
const secondaryLabel = secondary ? secondaryOptions.find((o) => String(o.value) === secondary)?.label ?? secondary : "";
|
|
6674
|
+
const displayText = secondaryLabel ? `${primaryLabel} ${secondaryLabel}` : primaryLabel || "\u2014";
|
|
6675
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: displayText }) });
|
|
6676
|
+
}
|
|
6496
6677
|
const updateValue = (nextPrimary, nextSecondary) => {
|
|
6497
6678
|
onChange(createCascadingSelectValue(nextPrimary, nextSecondary, separator));
|
|
6498
6679
|
};
|
|
@@ -6513,11 +6694,12 @@ function CascadingSelectFieldInner(props) {
|
|
|
6513
6694
|
disabled,
|
|
6514
6695
|
hasError,
|
|
6515
6696
|
options: toSelectOptions(primaryOptions),
|
|
6516
|
-
|
|
6697
|
+
containerClassName: firstSelectClass.containerClassName,
|
|
6517
6698
|
triggerClassName: firstSelectClass.triggerClassName,
|
|
6518
6699
|
canReset: true,
|
|
6519
6700
|
onChange: (nextPrimary) => {
|
|
6520
6701
|
updateValue(nextPrimary, "");
|
|
6702
|
+
if (!nextPrimary) onBlur();
|
|
6521
6703
|
}
|
|
6522
6704
|
}
|
|
6523
6705
|
),
|
|
@@ -6529,11 +6711,12 @@ function CascadingSelectFieldInner(props) {
|
|
|
6529
6711
|
disabled: disabled || !primary || secondaryOptions.length === 0,
|
|
6530
6712
|
hasError,
|
|
6531
6713
|
options: toSelectOptions(secondaryOptions),
|
|
6532
|
-
|
|
6714
|
+
containerClassName: secondSelectClass.containerClassName,
|
|
6533
6715
|
triggerClassName: secondSelectClass.triggerClassName,
|
|
6534
6716
|
canReset: true,
|
|
6535
6717
|
onChange: (nextSecondary) => {
|
|
6536
6718
|
updateValue(primary, nextSecondary);
|
|
6719
|
+
onBlur();
|
|
6537
6720
|
}
|
|
6538
6721
|
}
|
|
6539
6722
|
)
|
|
@@ -6544,7 +6727,11 @@ function CheckboxField(props) {
|
|
|
6544
6727
|
field: { onChange, value },
|
|
6545
6728
|
config
|
|
6546
6729
|
} = props;
|
|
6547
|
-
const { disabled = false, checkboxLabel, className = "" } = config;
|
|
6730
|
+
const { disabled = false, readOnly = false, checkboxLabel, className = "" } = config;
|
|
6731
|
+
if (readOnly) {
|
|
6732
|
+
const text = value ? checkboxLabel ?? "\uC120\uD0DD\uB428" : "\u2014";
|
|
6733
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: text }) });
|
|
6734
|
+
}
|
|
6548
6735
|
return /* @__PURE__ */ jsx(
|
|
6549
6736
|
Checkbox,
|
|
6550
6737
|
{
|
|
@@ -6565,11 +6752,16 @@ function DateField(props) {
|
|
|
6565
6752
|
const {
|
|
6566
6753
|
placeholder = "YYYY-MM-DD",
|
|
6567
6754
|
disabled = false,
|
|
6755
|
+
readOnly = false,
|
|
6568
6756
|
className = "w-40",
|
|
6569
6757
|
datePosition = "bottom",
|
|
6570
|
-
disableFutureDates = false
|
|
6758
|
+
disableFutureDates = false,
|
|
6759
|
+
calendarSelectContainerClass = "w-20"
|
|
6571
6760
|
} = config;
|
|
6572
6761
|
const maxDate = disableFutureDates ? formatDate(/* @__PURE__ */ new Date()) : void 0;
|
|
6762
|
+
if (readOnly) {
|
|
6763
|
+
return /* @__PURE__ */ jsx("div", { className: cn2("flex items-center", fieldControlWrapClass(className)), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: String(value ?? "") || "\u2014" }) });
|
|
6764
|
+
}
|
|
6573
6765
|
return /* @__PURE__ */ jsx("div", { className: cn2("flex items-center", fieldControlWrapClass(className)), children: /* @__PURE__ */ jsx(
|
|
6574
6766
|
DatePicker,
|
|
6575
6767
|
{
|
|
@@ -6581,7 +6773,8 @@ function DateField(props) {
|
|
|
6581
6773
|
className: "w-full",
|
|
6582
6774
|
validation: hasError,
|
|
6583
6775
|
datePosition,
|
|
6584
|
-
maxDate
|
|
6776
|
+
maxDate,
|
|
6777
|
+
calendarSelectContainerClass
|
|
6585
6778
|
}
|
|
6586
6779
|
) });
|
|
6587
6780
|
}
|
|
@@ -6597,11 +6790,17 @@ function InputField(props) {
|
|
|
6597
6790
|
readOnly = false,
|
|
6598
6791
|
maxLength,
|
|
6599
6792
|
className = "",
|
|
6600
|
-
type = "input"
|
|
6793
|
+
type = "input",
|
|
6794
|
+
numbersOnly = false
|
|
6601
6795
|
} = config;
|
|
6602
6796
|
const inputType = type === "email" ? "email" : type === "password" ? "password" : "text";
|
|
6797
|
+
if (readOnly) {
|
|
6798
|
+
const text = type === "password" ? value ? "**********" : "" : String(value ?? "") || "";
|
|
6799
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: text }) });
|
|
6800
|
+
}
|
|
6603
6801
|
const handleChange = (e) => {
|
|
6604
|
-
|
|
6802
|
+
const value2 = numbersOnly ? e.target.value.replace(/\D/g, "") : e.target.value;
|
|
6803
|
+
onChange(value2);
|
|
6605
6804
|
};
|
|
6606
6805
|
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx(
|
|
6607
6806
|
Input2,
|
|
@@ -6632,7 +6831,7 @@ function InputWithButtonField(props) {
|
|
|
6632
6831
|
placeholder = "\uC870\uD68C \uBC84\uD2BC\uC73C\uB85C \uC120\uD0DD",
|
|
6633
6832
|
disabled = false,
|
|
6634
6833
|
className = "",
|
|
6635
|
-
readOnly =
|
|
6834
|
+
readOnly = false,
|
|
6636
6835
|
inputWithButton,
|
|
6637
6836
|
onClickInputWithButton
|
|
6638
6837
|
} = config;
|
|
@@ -6641,13 +6840,16 @@ function InputWithButtonField(props) {
|
|
|
6641
6840
|
if (disabled) return;
|
|
6642
6841
|
onClickInputWithButton?.();
|
|
6643
6842
|
};
|
|
6843
|
+
if (readOnly) {
|
|
6844
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: String(value ?? "") || "\u2014" }) });
|
|
6845
|
+
}
|
|
6644
6846
|
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxs("div", { className: "flex w-full min-w-0 items-center gap-2", children: [
|
|
6645
6847
|
/* @__PURE__ */ jsx(
|
|
6646
6848
|
Input2,
|
|
6647
6849
|
{
|
|
6648
6850
|
placeholder,
|
|
6649
6851
|
value: String(value ?? ""),
|
|
6650
|
-
readOnly,
|
|
6852
|
+
readOnly: true,
|
|
6651
6853
|
disabled,
|
|
6652
6854
|
bare: true,
|
|
6653
6855
|
className: formControlClass(hasError),
|
|
@@ -6687,6 +6889,9 @@ function NumberField(props) {
|
|
|
6687
6889
|
}
|
|
6688
6890
|
};
|
|
6689
6891
|
const displayValue = value != null && value !== "" ? isMoney ? formatNumberWithCommas(value) : String(value) : "";
|
|
6892
|
+
if (readOnly) {
|
|
6893
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: displayValue || "\u2014" }) });
|
|
6894
|
+
}
|
|
6690
6895
|
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx(
|
|
6691
6896
|
Input2,
|
|
6692
6897
|
{
|
|
@@ -6716,6 +6921,9 @@ function PhoneField(props) {
|
|
|
6716
6921
|
const handleChange = (e) => {
|
|
6717
6922
|
onChange(formatPhoneNumber(e.target.value));
|
|
6718
6923
|
};
|
|
6924
|
+
if (readOnly) {
|
|
6925
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: String(value ?? "") || "\u2014" }) });
|
|
6926
|
+
}
|
|
6719
6927
|
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx(
|
|
6720
6928
|
Input2,
|
|
6721
6929
|
{
|
|
@@ -6740,7 +6948,11 @@ function RadioField(props) {
|
|
|
6740
6948
|
field: { onChange, value, name },
|
|
6741
6949
|
config
|
|
6742
6950
|
} = props;
|
|
6743
|
-
const { disabled = false, options = [], className = "" } = config;
|
|
6951
|
+
const { disabled = false, readOnly = false, options = [], className = "" } = config;
|
|
6952
|
+
if (readOnly) {
|
|
6953
|
+
const label = options.find((o) => String(o.value) === String(value ?? ""))?.label ?? String(value ?? "");
|
|
6954
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: label || "\u2014" }) });
|
|
6955
|
+
}
|
|
6744
6956
|
return /* @__PURE__ */ jsx(
|
|
6745
6957
|
RadioGroup,
|
|
6746
6958
|
{
|
|
@@ -6752,7 +6964,9 @@ function RadioField(props) {
|
|
|
6752
6964
|
containerClassName: cn2("justify-start", fieldControlWrapClass(className)),
|
|
6753
6965
|
options: options.map((option) => ({
|
|
6754
6966
|
label: option.label,
|
|
6755
|
-
value: String(option.value)
|
|
6967
|
+
value: String(option.value),
|
|
6968
|
+
disabled: option.disabled,
|
|
6969
|
+
disabledMessage: option.disabledMessage
|
|
6756
6970
|
}))
|
|
6757
6971
|
}
|
|
6758
6972
|
);
|
|
@@ -6772,11 +6986,16 @@ function SelectField(props) {
|
|
|
6772
6986
|
const {
|
|
6773
6987
|
placeholder = "\uC120\uD0DD\uD558\uC138\uC694",
|
|
6774
6988
|
disabled = false,
|
|
6989
|
+
readOnly = false,
|
|
6775
6990
|
options = [],
|
|
6776
6991
|
className = "",
|
|
6777
6992
|
canReset = false
|
|
6778
6993
|
} = config;
|
|
6779
6994
|
const selectOptions = toSelectOptions2(options);
|
|
6995
|
+
if (readOnly) {
|
|
6996
|
+
const label = selectOptions.find((o) => o.value === String(value ?? ""))?.label ?? String(value ?? "");
|
|
6997
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: label || "\u2014" }) });
|
|
6998
|
+
}
|
|
6780
6999
|
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx(
|
|
6781
7000
|
Select2,
|
|
6782
7001
|
{
|
|
@@ -6785,7 +7004,7 @@ function SelectField(props) {
|
|
|
6785
7004
|
disabled,
|
|
6786
7005
|
hasError,
|
|
6787
7006
|
options: selectOptions,
|
|
6788
|
-
|
|
7007
|
+
containerClassName: "flex w-full min-w-0 max-w-full items-center",
|
|
6789
7008
|
className: "w-full min-w-0",
|
|
6790
7009
|
triggerClassName: cn2(
|
|
6791
7010
|
"h-8 w-full min-w-0 max-w-full rounded border bg-white px-2 py-1 text-sm shadow-none",
|
|
@@ -6823,16 +7042,6 @@ function combineSelectWithInputValue(prefix, input) {
|
|
|
6823
7042
|
return `${prefix}${input}`;
|
|
6824
7043
|
}
|
|
6825
7044
|
var DEFAULT_SELECT_TRIGGER = "h-8 rounded border bg-white px-2 text-sm shadow-none min-w-[5rem]";
|
|
6826
|
-
function resolveSelectWithInputState(formValue, defaultPrefix, options) {
|
|
6827
|
-
const parsed = parseSelectWithInputValue(formValue, defaultPrefix);
|
|
6828
|
-
const validPrefixes = new Set(options.map((opt) => String(opt.value)));
|
|
6829
|
-
const prefix = validPrefixes.has(parsed.prefix) ? parsed.prefix : defaultPrefix;
|
|
6830
|
-
return {
|
|
6831
|
-
prefix,
|
|
6832
|
-
inputPart: parsed.input,
|
|
6833
|
-
normalizedFormValue: combineSelectWithInputValue(prefix, parsed.input)
|
|
6834
|
-
};
|
|
6835
|
-
}
|
|
6836
7045
|
function SelectWithInputField(props) {
|
|
6837
7046
|
const {
|
|
6838
7047
|
field: { onChange, onBlur, value },
|
|
@@ -6841,37 +7050,58 @@ function SelectWithInputField(props) {
|
|
|
6841
7050
|
} = props;
|
|
6842
7051
|
const {
|
|
6843
7052
|
disabled = false,
|
|
7053
|
+
readOnly = false,
|
|
6844
7054
|
options = [],
|
|
6845
7055
|
maxLength,
|
|
6846
7056
|
className = "",
|
|
6847
7057
|
selectWithInput,
|
|
6848
7058
|
selectWithInputClassNames
|
|
6849
7059
|
} = config;
|
|
6850
|
-
const
|
|
7060
|
+
const validationCtx = useSubmitFormValidation();
|
|
7061
|
+
const numbersOnly = selectWithInput?.numbersOnly ?? selectWithInput?.inputMode !== "text";
|
|
6851
7062
|
const defaultPrefix = String(options[0]?.value ?? "");
|
|
6852
7063
|
const numberInputRef = useRef(null);
|
|
6853
7064
|
const formValue = String(value ?? "");
|
|
6854
|
-
const { prefix, inputPart, normalizedFormValue } = useMemo(
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
7065
|
+
const { prefix, inputPart, normalizedFormValue } = useMemo(() => {
|
|
7066
|
+
const parsed = parseSelectWithInputValue(formValue, defaultPrefix);
|
|
7067
|
+
const validPrefixes = new Set(options.map((opt) => String(opt.value)));
|
|
7068
|
+
const resolvedPrefix = validPrefixes.has(parsed.prefix) ? parsed.prefix : defaultPrefix;
|
|
7069
|
+
return {
|
|
7070
|
+
prefix: resolvedPrefix,
|
|
7071
|
+
inputPart: parsed.input,
|
|
7072
|
+
normalizedFormValue: combineSelectWithInputValue(resolvedPrefix, parsed.input)
|
|
7073
|
+
};
|
|
7074
|
+
}, [defaultPrefix, formValue, options]);
|
|
7075
|
+
const [selectedPrefix, setSelectedPrefix] = useState(prefix);
|
|
7076
|
+
const [prevFormValue, setPrevFormValue] = useState(formValue);
|
|
7077
|
+
if (prevFormValue !== formValue) {
|
|
7078
|
+
setPrevFormValue(formValue);
|
|
7079
|
+
setSelectedPrefix(formValue ? prefix : defaultPrefix);
|
|
7080
|
+
}
|
|
6858
7081
|
useLayoutEffect(() => {
|
|
6859
|
-
if (
|
|
7082
|
+
if (readOnly) return;
|
|
7083
|
+
if (formValue && normalizedFormValue !== formValue) {
|
|
6860
7084
|
onChange(normalizedFormValue);
|
|
6861
7085
|
}
|
|
6862
|
-
}, [formValue, normalizedFormValue, onChange]);
|
|
7086
|
+
}, [formValue, normalizedFormValue, onChange, readOnly]);
|
|
7087
|
+
if (readOnly) {
|
|
7088
|
+
const prefixLabel = options.find((o) => String(o.value) === prefix)?.label ?? prefix;
|
|
7089
|
+
const displayText = inputPart ? `${prefixLabel} ${inputPart}` : prefix ? prefixLabel : "\u2014";
|
|
7090
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: displayText || "\u2014" }) });
|
|
7091
|
+
}
|
|
6863
7092
|
const updateCombined = (nextPrefix, nextInput) => {
|
|
6864
7093
|
onChange(combineSelectWithInputValue(nextPrefix, nextInput));
|
|
6865
7094
|
};
|
|
6866
7095
|
const normalizeInput = (raw) => {
|
|
6867
|
-
if (
|
|
6868
|
-
return raw.replace(/\D+/g, "");
|
|
6869
|
-
}
|
|
7096
|
+
if (numbersOnly) return raw.replace(/\D+/g, "");
|
|
6870
7097
|
return raw;
|
|
6871
7098
|
};
|
|
6872
7099
|
const handleInputChange = (raw) => {
|
|
6873
7100
|
const normalized = normalizeInput(raw.normalize("NFKC"));
|
|
6874
|
-
|
|
7101
|
+
if (normalized) {
|
|
7102
|
+
validationCtx?.markFieldHadValue(String(config.name));
|
|
7103
|
+
}
|
|
7104
|
+
updateCombined(selectedPrefix, normalized);
|
|
6875
7105
|
};
|
|
6876
7106
|
const selectClass = resolveSelectClassNameProp(selectWithInputClassNames?.selectClassName, {
|
|
6877
7107
|
containerClassName: "shrink-0",
|
|
@@ -6881,15 +7111,17 @@ function SelectWithInputField(props) {
|
|
|
6881
7111
|
/* @__PURE__ */ jsx(
|
|
6882
7112
|
Select2,
|
|
6883
7113
|
{
|
|
6884
|
-
value:
|
|
7114
|
+
value: selectedPrefix,
|
|
6885
7115
|
placeholder: "\uC120\uD0DD",
|
|
6886
7116
|
disabled,
|
|
6887
7117
|
hasError,
|
|
6888
7118
|
options: toSelectOptions(options),
|
|
6889
|
-
|
|
7119
|
+
containerClassName: selectClass.containerClassName,
|
|
6890
7120
|
triggerClassName: selectClass.triggerClassName,
|
|
6891
7121
|
onChange: (nextPrefix) => {
|
|
7122
|
+
setSelectedPrefix(nextPrefix);
|
|
6892
7123
|
updateCombined(nextPrefix, inputPart);
|
|
7124
|
+
onBlur();
|
|
6893
7125
|
}
|
|
6894
7126
|
}
|
|
6895
7127
|
),
|
|
@@ -6907,7 +7139,7 @@ function SelectWithInputField(props) {
|
|
|
6907
7139
|
},
|
|
6908
7140
|
onBlur: (e) => {
|
|
6909
7141
|
const normalized = normalizeInput(e.target.value.normalize("NFKC"));
|
|
6910
|
-
|
|
7142
|
+
updateCombined(selectedPrefix, normalized);
|
|
6911
7143
|
onBlur();
|
|
6912
7144
|
}
|
|
6913
7145
|
}
|
|
@@ -6919,7 +7151,10 @@ function SwitchField(props) {
|
|
|
6919
7151
|
field: { onChange, value },
|
|
6920
7152
|
config
|
|
6921
7153
|
} = props;
|
|
6922
|
-
const { disabled = false, className = "" } = config;
|
|
7154
|
+
const { disabled = false, readOnly = false, className = "" } = config;
|
|
7155
|
+
if (readOnly) {
|
|
7156
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: value ? "\uCF1C\uC9D0" : "\uAEBC\uC9D0" }) });
|
|
7157
|
+
}
|
|
6923
7158
|
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx(BaseSwitch, { checked: Boolean(value), onCheckedChange: onChange, disabled }) });
|
|
6924
7159
|
}
|
|
6925
7160
|
function TextareaField(props) {
|
|
@@ -6932,6 +7167,9 @@ function TextareaField(props) {
|
|
|
6932
7167
|
const handleChange = (e) => {
|
|
6933
7168
|
onChange(e.target.value);
|
|
6934
7169
|
};
|
|
7170
|
+
if (readOnly) {
|
|
7171
|
+
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx("span", { className: cn2(FIELD_READONLY_TEXT_CLASS, "whitespace-pre-wrap"), children: String(value ?? "") || "\u2014" }) });
|
|
7172
|
+
}
|
|
6935
7173
|
return /* @__PURE__ */ jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsx(
|
|
6936
7174
|
Textarea,
|
|
6937
7175
|
{
|
|
@@ -7018,7 +7256,7 @@ function useBlurValidation(name, options) {
|
|
|
7018
7256
|
(value, fieldOnChange) => {
|
|
7019
7257
|
markHadValueIfFilled(value);
|
|
7020
7258
|
fieldOnChange(value);
|
|
7021
|
-
if (options.revalidateOnChange || shouldValidateEmptyOnChange(value)) {
|
|
7259
|
+
if (options.revalidateOnChange || options.validateEmptyOnChange && shouldValidateEmptyOnChange(value)) {
|
|
7022
7260
|
void trigger(name);
|
|
7023
7261
|
}
|
|
7024
7262
|
void triggerRelatedFields();
|
|
@@ -7026,6 +7264,7 @@ function useBlurValidation(name, options) {
|
|
|
7026
7264
|
[
|
|
7027
7265
|
markHadValueIfFilled,
|
|
7028
7266
|
options.revalidateOnChange,
|
|
7267
|
+
options.validateEmptyOnChange,
|
|
7029
7268
|
shouldValidateEmptyOnChange,
|
|
7030
7269
|
trigger,
|
|
7031
7270
|
name,
|
|
@@ -7046,9 +7285,7 @@ var REVALIDATE_ON_CHANGE_TYPES = /* @__PURE__ */ new Set([
|
|
|
7046
7285
|
"radio",
|
|
7047
7286
|
"switch",
|
|
7048
7287
|
"select",
|
|
7049
|
-
"date",
|
|
7050
7288
|
"cascading-select",
|
|
7051
|
-
"select-with-input",
|
|
7052
7289
|
"input-with-button",
|
|
7053
7290
|
"address"
|
|
7054
7291
|
]);
|
|
@@ -7069,14 +7306,15 @@ function FormFieldRow(props) {
|
|
|
7069
7306
|
const { control } = useFormContext();
|
|
7070
7307
|
const { isSubmitted } = useFormState({ control });
|
|
7071
7308
|
const { name, label, type = "input", required = false, renderCustomField, contentAlign = "left" } = config;
|
|
7309
|
+
const revalidateOnChange = REVALIDATE_ON_CHANGE_TYPES.has(type);
|
|
7072
7310
|
const { handleBlur, handleChange } = useBlurValidation(name, {
|
|
7073
7311
|
required,
|
|
7074
|
-
revalidateOnChange
|
|
7312
|
+
revalidateOnChange,
|
|
7313
|
+
validateEmptyOnChange: revalidateOnChange,
|
|
7075
7314
|
revalidateFields: config.revalidateFields
|
|
7076
7315
|
});
|
|
7077
7316
|
const showError = Boolean(fieldState.error?.message) && (isSubmitted || fieldState.isTouched);
|
|
7078
7317
|
const isTextarea = type === "textarea";
|
|
7079
|
-
const revalidateOnChange = REVALIDATE_ON_CHANGE_TYPES.has(type);
|
|
7080
7318
|
const wrappedField = wrapFieldHandlers(field, {
|
|
7081
7319
|
onBlur: () => handleBlur(() => field.onBlur()),
|
|
7082
7320
|
onChange: (value) => {
|
|
@@ -7177,9 +7415,11 @@ function rowPropsToFieldConfig(props) {
|
|
|
7177
7415
|
options,
|
|
7178
7416
|
className,
|
|
7179
7417
|
allowDecimal,
|
|
7418
|
+
numbersOnly,
|
|
7180
7419
|
canReset,
|
|
7181
7420
|
datePosition,
|
|
7182
7421
|
disableFutureDates,
|
|
7422
|
+
calendarSelectContainerClass,
|
|
7183
7423
|
revalidateFields,
|
|
7184
7424
|
renderCustomField,
|
|
7185
7425
|
colspan,
|
|
@@ -7206,9 +7446,11 @@ function rowPropsToFieldConfig(props) {
|
|
|
7206
7446
|
options,
|
|
7207
7447
|
className,
|
|
7208
7448
|
allowDecimal,
|
|
7449
|
+
numbersOnly,
|
|
7209
7450
|
canReset,
|
|
7210
7451
|
datePosition,
|
|
7211
7452
|
disableFutureDates,
|
|
7453
|
+
calendarSelectContainerClass,
|
|
7212
7454
|
revalidateFields,
|
|
7213
7455
|
renderCustomField,
|
|
7214
7456
|
colspan,
|
|
@@ -7368,14 +7610,7 @@ function PageFilter(props) {
|
|
|
7368
7610
|
const rowGap2 = index !== 0 ? option.label ? gap : 5 : 0;
|
|
7369
7611
|
switch (option.type) {
|
|
7370
7612
|
case "input":
|
|
7371
|
-
return /* @__PURE__ */ jsx(LabeledFilterOption, { label: option.label, gap: rowGap2, children: /* @__PURE__ */ jsx(
|
|
7372
|
-
Input2,
|
|
7373
|
-
{
|
|
7374
|
-
placeholder: option.placeholder,
|
|
7375
|
-
value: currentValue,
|
|
7376
|
-
onChange: handleInputChange(optionKey)
|
|
7377
|
-
}
|
|
7378
|
-
) }, 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));
|
|
7379
7614
|
case "select":
|
|
7380
7615
|
return /* @__PURE__ */ jsx(LabeledFilterOption, { label: option.label, gap: rowGap2, children: /* @__PURE__ */ jsx(
|
|
7381
7616
|
Select2,
|
|
@@ -7383,7 +7618,8 @@ function PageFilter(props) {
|
|
|
7383
7618
|
value: currentValue,
|
|
7384
7619
|
onChange: handleSelectChange(optionKey),
|
|
7385
7620
|
options: option.options,
|
|
7386
|
-
placeholder: "\uC120\uD0DD
|
|
7621
|
+
placeholder: "\uC120\uD0DD",
|
|
7622
|
+
containerClassName: option.containerClassName ?? "w-30"
|
|
7387
7623
|
}
|
|
7388
7624
|
) }, String(optionKey));
|
|
7389
7625
|
case "radio":
|