sellmate-design-system-react 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs +180 -37
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +6 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.js +180 -37
- package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
- package/dist/components/SGnb/SGnb.cjs +124 -54
- package/dist/components/SGnb/SGnb.cjs.map +1 -1
- package/dist/components/SGnb/SGnb.d.ts +7 -1
- package/dist/components/SGnb/SGnb.js +125 -55
- package/dist/components/SGnb/SGnb.js.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs +180 -37
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.js +180 -37
- package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
- package/dist/components/SLayout/SLayout.cjs +21 -6
- package/dist/components/SLayout/SLayout.cjs.map +1 -1
- package/dist/components/SLayout/SLayout.d.ts +17 -2
- package/dist/components/SLayout/SLayout.js +21 -6
- package/dist/components/SLayout/SLayout.js.map +1 -1
- package/dist/components/SPage/SPage.cjs +21 -6
- package/dist/components/SPage/SPage.cjs.map +1 -1
- package/dist/components/SPage/SPage.js +21 -6
- package/dist/components/SPage/SPage.js.map +1 -1
- package/dist/index.cjs +303 -90
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +303 -90
- package/dist/index.js.map +1 -1
- package/dist/styles.css +61 -0
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -5041,15 +5041,30 @@ var SLayout = forwardRef(function SLayout2({
|
|
|
5041
5041
|
},
|
|
5042
5042
|
[isControlled, onFoldedChange]
|
|
5043
5043
|
);
|
|
5044
|
+
const [gnbState, setGnbState] = useState({ forceFull: false, menuVisible: true });
|
|
5045
|
+
const reportGnbState = useCallback(
|
|
5046
|
+
(next) => setGnbState(
|
|
5047
|
+
(prev) => prev.forceFull === next.forceFull && prev.menuVisible === next.menuVisible ? prev : next
|
|
5048
|
+
),
|
|
5049
|
+
[]
|
|
5050
|
+
);
|
|
5051
|
+
const effectiveHeader = header === "full" || gnbState.forceFull ? "full" : "fix";
|
|
5044
5052
|
const ctx = useMemo(
|
|
5045
|
-
() => ({
|
|
5046
|
-
|
|
5053
|
+
() => ({
|
|
5054
|
+
type,
|
|
5055
|
+
header: effectiveHeader,
|
|
5056
|
+
useRail,
|
|
5057
|
+
folded: currentFolded,
|
|
5058
|
+
setFolded,
|
|
5059
|
+
reportGnbState
|
|
5060
|
+
}),
|
|
5061
|
+
[type, effectiveHeader, useRail, currentFolded, setFolded, reportGnbState]
|
|
5047
5062
|
);
|
|
5048
|
-
const isFullHeader =
|
|
5049
|
-
const gnbColumnWidth = useRail ? GNB_RAIL_WIDTH + GNB_MENU_WIDTH :
|
|
5063
|
+
const isFullHeader = effectiveHeader === "full";
|
|
5064
|
+
const gnbColumnWidth = (useRail ? GNB_RAIL_WIDTH : 0) + (gnbState.menuVisible ? GNB_MENU_WIDTH : 0);
|
|
5050
5065
|
const frameStyle = isFullHeader ? {
|
|
5051
5066
|
gridTemplateColumns: `${currentFolded ? 0 : gnbColumnWidth}px 1fr`,
|
|
5052
|
-
gridTemplateRows: `${GNB_HEADER[
|
|
5067
|
+
gridTemplateRows: `${GNB_HEADER[effectiveHeader].topHeight} 1fr`,
|
|
5053
5068
|
// 메뉴가 미끄러지는 동안 페이지 열도 같은 길이로 따라와야 한 덩어리로 읽힌다.
|
|
5054
5069
|
// (fix 는 SGnb 가 제 폭을 직접 전환하므로 프레임이 손댈 게 없다)
|
|
5055
5070
|
transition: `grid-template-columns ${GNB_FOLD_MS}ms ease-out`
|
|
@@ -5059,7 +5074,7 @@ var SLayout = forwardRef(function SLayout2({
|
|
|
5059
5074
|
{
|
|
5060
5075
|
ref,
|
|
5061
5076
|
"data-type": type,
|
|
5062
|
-
"data-header":
|
|
5077
|
+
"data-header": effectiveHeader,
|
|
5063
5078
|
className: cn(
|
|
5064
5079
|
"box-border h-full overflow-hidden",
|
|
5065
5080
|
isFullHeader ? "grid" : "flex flex-row",
|
|
@@ -5092,9 +5107,10 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5092
5107
|
}, ref) {
|
|
5093
5108
|
const layout = useContext(SLayoutContext);
|
|
5094
5109
|
const type = typeProp ?? layout?.type ?? "box";
|
|
5095
|
-
const header = headerProp ?? layout?.header ?? "fix";
|
|
5096
5110
|
const folded = foldedProp ?? layout?.folded ?? false;
|
|
5097
5111
|
const useRail = useRailProp ?? layout?.useRail ?? false;
|
|
5112
|
+
const railHasLeaf = useRail && items.some((item) => !item.children || item.children.length === 0);
|
|
5113
|
+
const header = railHasLeaf ? "full" : headerProp ?? layout?.header ?? "fix";
|
|
5098
5114
|
const H = GNB_HEADER[header];
|
|
5099
5115
|
const M = GNB_MENU[type];
|
|
5100
5116
|
const C = GNB_COLORS[color];
|
|
@@ -5282,7 +5298,11 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5282
5298
|
};
|
|
5283
5299
|
const railItems = useRail ? items : [];
|
|
5284
5300
|
const menuItems = useRail ? items.find((item) => item.value === activeRail)?.children ?? [] : items;
|
|
5285
|
-
const
|
|
5301
|
+
const showMenu = !useRail || menuItems.length > 0;
|
|
5302
|
+
const bodyWidth = (useRail ? GNB_RAIL_WIDTH : 0) + (showMenu ? GNB_MENU_WIDTH : 0);
|
|
5303
|
+
useEffect(() => {
|
|
5304
|
+
layout?.reportGnbState({ forceFull: railHasLeaf, menuVisible: showMenu });
|
|
5305
|
+
}, [layout, railHasLeaf, showMenu]);
|
|
5286
5306
|
const railFolded = folded && header === "fix";
|
|
5287
5307
|
const rootWidth = header === "full" ? "100%" : folded ? GNB_COMMON.foldWidth : bodyWidth;
|
|
5288
5308
|
const rootStyle = {
|
|
@@ -5292,6 +5312,13 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5292
5312
|
...style
|
|
5293
5313
|
};
|
|
5294
5314
|
const hideAfterSlide = (hidden) => `visibility 0s linear ${hidden ? `${GNB_FOLD_MS}ms` : "0s"}`;
|
|
5315
|
+
const foldInline = !!logo;
|
|
5316
|
+
const sideFoldStyle = {
|
|
5317
|
+
opacity: railFolded ? 0 : 1,
|
|
5318
|
+
position: railFolded ? "absolute" : "static",
|
|
5319
|
+
visibility: railFolded ? "hidden" : "visible",
|
|
5320
|
+
transition: `opacity ${GNB_FOLD_MS}ms ease-out, ${hideAfterSlide(railFolded)}`
|
|
5321
|
+
};
|
|
5295
5322
|
return /* @__PURE__ */ jsxs(
|
|
5296
5323
|
"div",
|
|
5297
5324
|
{
|
|
@@ -5303,12 +5330,14 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5303
5330
|
"data-color": color,
|
|
5304
5331
|
...rest,
|
|
5305
5332
|
children: [
|
|
5306
|
-
/* @__PURE__ */
|
|
5333
|
+
/* @__PURE__ */ jsx(
|
|
5307
5334
|
"div",
|
|
5308
5335
|
{
|
|
5309
5336
|
className: "relative box-border flex shrink-0 items-center overflow-hidden",
|
|
5310
5337
|
style: {
|
|
5311
5338
|
height: H.topHeight,
|
|
5339
|
+
// 인라인 간격은 컨테이너 gap 대신 각 요소 margin 으로 준다 — 런처↔폴드(8px)와
|
|
5340
|
+
// 폴드↔로고(top-gap)를 다르게 두기 위함. 접히면 런처·로고가 흐름에서 빠져 margin 도 무의미해진다.
|
|
5312
5341
|
padding: `0 ${railFolded ? GNB_RAIL.padding : H.topPaddingX}`,
|
|
5313
5342
|
borderBottom: `1px solid ${C.topBorder}`,
|
|
5314
5343
|
backgroundColor: C.panelBg,
|
|
@@ -5317,49 +5346,90 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5317
5346
|
// 아이콘 버튼은 자체 ghostButton 토큰을 쓰므로, 이 색은 logo 슬롯 상속용
|
|
5318
5347
|
color: C.itemColorDefault
|
|
5319
5348
|
},
|
|
5320
|
-
children:
|
|
5321
|
-
(
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5349
|
+
children: foldInline ? (
|
|
5350
|
+
// 런처(있을 때)·폴드·로고를 흐름에 나란히 둔다 → 폴드 버튼이 (런처와) 로고 사이에 선다.
|
|
5351
|
+
// 접히면 런처·로고가 페이드하며 흐름에서 빠지고(sideFoldStyle), 폴드 버튼만 남아 레일 가운데에 선다.
|
|
5352
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5353
|
+
onLauncherClick && /* @__PURE__ */ jsx(
|
|
5354
|
+
SGhostButton,
|
|
5355
|
+
{
|
|
5356
|
+
icon: "launcher",
|
|
5357
|
+
size: "xs",
|
|
5358
|
+
intent: color === "dark" ? "inverse" : "default",
|
|
5359
|
+
ariaLabel: "app launcher",
|
|
5360
|
+
onClick: onLauncherClick,
|
|
5361
|
+
className: "shrink-0",
|
|
5362
|
+
style: { ...sideFoldStyle, marginRight: "8px" }
|
|
5363
|
+
}
|
|
5364
|
+
),
|
|
5365
|
+
/* @__PURE__ */ jsx(
|
|
5366
|
+
SGhostButton,
|
|
5367
|
+
{
|
|
5368
|
+
icon: "sidebar",
|
|
5369
|
+
size: "xs",
|
|
5370
|
+
intent: color === "dark" ? "inverse" : "default",
|
|
5371
|
+
ariaLabel: "toggle navigation",
|
|
5372
|
+
ariaPressed: folded,
|
|
5373
|
+
onClick: handleFoldToggle,
|
|
5374
|
+
className: "shrink-0"
|
|
5375
|
+
}
|
|
5376
|
+
),
|
|
5377
|
+
/* @__PURE__ */ jsx(
|
|
5378
|
+
"div",
|
|
5379
|
+
{
|
|
5380
|
+
className: "flex shrink-0 items-center",
|
|
5381
|
+
style: { height: H.logoHeight, marginLeft: H.topGap, ...sideFoldStyle },
|
|
5382
|
+
children: logo
|
|
5383
|
+
}
|
|
5384
|
+
)
|
|
5385
|
+
] })
|
|
5386
|
+
) : (
|
|
5387
|
+
// 런처·로고는 좌측 그룹(흐름에서 빼 폭 축소 중 폴드 버튼을 밀어내지 않는다),
|
|
5388
|
+
// 폴드 버튼은 우측 끝(ml-auto)이라 폭·패딩이 줄면 저절로 레일 가운데에 선다.
|
|
5389
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5390
|
+
(onLauncherClick || logo) && /* @__PURE__ */ jsxs(
|
|
5391
|
+
"div",
|
|
5392
|
+
{
|
|
5393
|
+
className: "absolute inset-y-0 flex items-center",
|
|
5394
|
+
style: {
|
|
5395
|
+
left: H.topPaddingX,
|
|
5396
|
+
gap: H.topGap,
|
|
5397
|
+
opacity: railFolded ? 0 : 1,
|
|
5398
|
+
transition: `opacity ${GNB_FOLD_MS}ms ease-out, ${hideAfterSlide(railFolded)}, transform ${GNB_FOLD_MS}ms ease-out`,
|
|
5399
|
+
// 메뉴와 같은 방향으로 빠지되, 좁은 레일 안에서 꼬리가 비치지 않게 페이드가 거리를 대신한다
|
|
5400
|
+
transform: railFolded ? `translateX(-${H.topPaddingX})` : "none",
|
|
5401
|
+
visibility: railFolded ? "hidden" : "visible"
|
|
5402
|
+
},
|
|
5403
|
+
children: [
|
|
5404
|
+
onLauncherClick && /* @__PURE__ */ jsx(
|
|
5405
|
+
SGhostButton,
|
|
5406
|
+
{
|
|
5407
|
+
icon: "launcher",
|
|
5408
|
+
size: "xs",
|
|
5409
|
+
intent: color === "dark" ? "inverse" : "default",
|
|
5410
|
+
ariaLabel: "app launcher",
|
|
5411
|
+
onClick: onLauncherClick,
|
|
5412
|
+
className: "shrink-0"
|
|
5413
|
+
}
|
|
5414
|
+
),
|
|
5415
|
+
logo && /* @__PURE__ */ jsx("div", { className: "flex items-center", style: { height: H.logoHeight }, children: logo })
|
|
5416
|
+
]
|
|
5417
|
+
}
|
|
5418
|
+
),
|
|
5419
|
+
/* @__PURE__ */ jsx(
|
|
5420
|
+
SGhostButton,
|
|
5421
|
+
{
|
|
5422
|
+
icon: "sidebar",
|
|
5423
|
+
size: "xs",
|
|
5424
|
+
intent: color === "dark" ? "inverse" : "default",
|
|
5425
|
+
ariaLabel: "toggle navigation",
|
|
5426
|
+
ariaPressed: folded,
|
|
5427
|
+
onClick: handleFoldToggle,
|
|
5428
|
+
className: "ml-auto shrink-0"
|
|
5429
|
+
}
|
|
5430
|
+
)
|
|
5431
|
+
] })
|
|
5432
|
+
)
|
|
5363
5433
|
}
|
|
5364
5434
|
),
|
|
5365
5435
|
/* @__PURE__ */ jsxs(
|
|
@@ -5395,7 +5465,7 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5395
5465
|
children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", style: { gap: GNB_RAIL.gap }, children: railItems.map(renderRailItem) })
|
|
5396
5466
|
}
|
|
5397
5467
|
),
|
|
5398
|
-
/* @__PURE__ */ jsx(
|
|
5468
|
+
showMenu && /* @__PURE__ */ jsx(
|
|
5399
5469
|
"nav",
|
|
5400
5470
|
{
|
|
5401
5471
|
"aria-label": ariaLabel,
|
|
@@ -8060,25 +8130,45 @@ function SDatePicker({
|
|
|
8060
8130
|
}
|
|
8061
8131
|
);
|
|
8062
8132
|
}
|
|
8133
|
+
function splitDateTime(v) {
|
|
8134
|
+
if (!v) return { date: null, hour: "00", minute: "00" };
|
|
8135
|
+
const [date = "", time = ""] = v.split(" ");
|
|
8136
|
+
const [hour = "00", minute = "00"] = time.split(":");
|
|
8137
|
+
return { date: date || null, hour, minute };
|
|
8138
|
+
}
|
|
8063
8139
|
function RangeCalendar({
|
|
8064
8140
|
value,
|
|
8065
8141
|
selectable,
|
|
8066
8142
|
maxRange,
|
|
8143
|
+
useTimePicker = false,
|
|
8067
8144
|
onSelect,
|
|
8068
8145
|
onPendingStartChange,
|
|
8069
8146
|
onViewChange
|
|
8070
8147
|
}) {
|
|
8071
8148
|
const today = todayStr();
|
|
8072
|
-
const
|
|
8149
|
+
const initial = splitDateTime(value?.[0]);
|
|
8150
|
+
const base = initial.date || today;
|
|
8073
8151
|
const [y, setY] = useState(Number(base.split("-")[0]));
|
|
8074
8152
|
const [m, setM] = useState(Number(base.split("-")[1]));
|
|
8075
|
-
const [start, setStart] = useState(
|
|
8076
|
-
const [end, setEnd] = useState(value?.[1]
|
|
8153
|
+
const [start, setStart] = useState(initial.date);
|
|
8154
|
+
const [end, setEnd] = useState(splitDateTime(value?.[1]).date);
|
|
8077
8155
|
const [hover, setHover] = useState(null);
|
|
8156
|
+
const [sH, setSH] = useState(initial.hour);
|
|
8157
|
+
const [sM, setSM] = useState(initial.minute);
|
|
8158
|
+
const [eH, setEH] = useState(splitDateTime(value?.[1]).hour);
|
|
8159
|
+
const [eM, setEM] = useState(splitDateTime(value?.[1]).minute);
|
|
8160
|
+
const lastEmitted = useRef("");
|
|
8078
8161
|
useEffect(() => {
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8162
|
+
if (useTimePicker && JSON.stringify(value) === lastEmitted.current) return;
|
|
8163
|
+
const s = splitDateTime(value?.[0]);
|
|
8164
|
+
const e = splitDateTime(value?.[1]);
|
|
8165
|
+
setStart(s.date);
|
|
8166
|
+
setEnd(e.date);
|
|
8167
|
+
setSH(s.hour);
|
|
8168
|
+
setSM(s.minute);
|
|
8169
|
+
setEH(e.hour);
|
|
8170
|
+
setEM(e.minute);
|
|
8171
|
+
}, [value, useTimePicker]);
|
|
8082
8172
|
const setBase = (ny, nm) => {
|
|
8083
8173
|
setY(ny);
|
|
8084
8174
|
setM(nm);
|
|
@@ -8122,18 +8212,53 @@ function RangeCalendar({
|
|
|
8122
8212
|
const hasRange = !!(rStart && rEnd && rStart !== rEnd);
|
|
8123
8213
|
const inRange = (d) => !!(rStart && rEnd && d > rStart && d < rEnd);
|
|
8124
8214
|
const RANGE_BG = "var(--cmp-datepicker-calendar-range-bg)";
|
|
8215
|
+
const pad = (v) => String(Number(v) || 0).padStart(2, "0");
|
|
8216
|
+
const emit2 = (dateStart, dateEnd, time) => {
|
|
8217
|
+
const t = time ?? { sH, sM, eH, eM };
|
|
8218
|
+
const range = useTimePicker ? [`${dateStart} ${pad(t.sH)}:${pad(t.sM)}`, `${dateEnd} ${pad(t.eH)}:${pad(t.eM)}`] : [dateStart, dateEnd];
|
|
8219
|
+
lastEmitted.current = JSON.stringify(range);
|
|
8220
|
+
onSelect(range);
|
|
8221
|
+
};
|
|
8125
8222
|
const click = (d) => {
|
|
8126
8223
|
if (isDisabled(d)) return;
|
|
8127
8224
|
if (!start || complete || d < start) {
|
|
8128
8225
|
setStart(d);
|
|
8129
8226
|
setEnd(null);
|
|
8130
8227
|
setHover(null);
|
|
8228
|
+
if (useTimePicker) {
|
|
8229
|
+
setSH("00");
|
|
8230
|
+
setSM("00");
|
|
8231
|
+
setEH("23");
|
|
8232
|
+
setEM("59");
|
|
8233
|
+
}
|
|
8131
8234
|
onPendingStartChange?.(d);
|
|
8132
8235
|
return;
|
|
8133
8236
|
}
|
|
8134
8237
|
setEnd(d);
|
|
8135
8238
|
onPendingStartChange?.(null);
|
|
8136
|
-
|
|
8239
|
+
emit2(start, d, useTimePicker ? { sH, sM, eH: "23", eM: "59" } : void 0);
|
|
8240
|
+
};
|
|
8241
|
+
const changeTime = (which, part, raw) => {
|
|
8242
|
+
const digits = raw.replace(/\D/g, "").slice(0, 2);
|
|
8243
|
+
const max = part === "h" ? 23 : 59;
|
|
8244
|
+
const next = digits !== "" && Number(digits) > max ? String(max) : digits;
|
|
8245
|
+
const nextTime = { sH, sM, eH, eM };
|
|
8246
|
+
if (which === "start") nextTime[part === "h" ? "sH" : "sM"] = next;
|
|
8247
|
+
else nextTime[part === "h" ? "eH" : "eM"] = next;
|
|
8248
|
+
setSH(nextTime.sH);
|
|
8249
|
+
setSM(nextTime.sM);
|
|
8250
|
+
setEH(nextTime.eH);
|
|
8251
|
+
setEM(nextTime.eM);
|
|
8252
|
+
if (start && end) emit2(start, end, nextTime);
|
|
8253
|
+
};
|
|
8254
|
+
const blurTime = (which, part) => {
|
|
8255
|
+
if (which === "start") {
|
|
8256
|
+
if (part === "h") setSH(pad(sH));
|
|
8257
|
+
else setSM(pad(sM));
|
|
8258
|
+
} else {
|
|
8259
|
+
if (part === "h") setEH(pad(eH));
|
|
8260
|
+
else setEM(pad(eM));
|
|
8261
|
+
}
|
|
8137
8262
|
};
|
|
8138
8263
|
const GRID_COLS = "grid grid-cols-[repeat(7,var(--cmp-datepicker-calendar-day-width))]";
|
|
8139
8264
|
const renderPanel = (gy, gm, isLeft) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-[var(--cmp-datepicker-calendar-gap)]", children: [
|
|
@@ -8208,35 +8333,120 @@ function RangeCalendar({
|
|
|
8208
8333
|
);
|
|
8209
8334
|
}) })
|
|
8210
8335
|
] });
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8336
|
+
const renderTimeSection = (which, date, suffix) => {
|
|
8337
|
+
const active = !!date;
|
|
8338
|
+
const [yy = "", mm = "", dd = ""] = date ? date.split("-") : [];
|
|
8339
|
+
const hour = which === "start" ? sH : eH;
|
|
8340
|
+
const minute = which === "start" ? sM : eM;
|
|
8341
|
+
const num = (n, strip) => active && n !== "" ? strip ? String(Number(n)) : n : "-";
|
|
8342
|
+
const INPUT_CLS = "h-[var(--cmp-datepicker-sm-height)] w-[40px] rounded-[var(--cmp-datepicker-sm-radius)] border border-solid border-[color:var(--cmp-datepicker-border-default)] bg-[var(--cmp-datepicker-bg-default)] text-center text-[12px] font-medium leading-[20px] text-[color:var(--cmp-datepicker-text-default)] outline-none placeholder:text-[color:var(--cmp-datepicker-text-disabled)] focus:border-[color:var(--cmp-datepicker-border-focus)] disabled:cursor-not-allowed";
|
|
8343
|
+
const LABEL = "text-[color:var(--cmp-datepicker-calendar-time-date-label)]";
|
|
8344
|
+
const UNIT = "text-[color:var(--cmp-datepicker-calendar-time-date-unit)]";
|
|
8345
|
+
return /* @__PURE__ */ jsxs(
|
|
8346
|
+
"div",
|
|
8347
|
+
{
|
|
8348
|
+
className: cn(
|
|
8349
|
+
"flex flex-1 items-center justify-center gap-[var(--cmp-datepicker-calendar-time-section-gap)] rounded-[var(--cmp-datepicker-calendar-time-radius)] px-[var(--cmp-datepicker-calendar-time-paddingX)] py-[var(--cmp-datepicker-calendar-time-paddingY)] text-[12px] font-medium leading-[20px]",
|
|
8350
|
+
active ? "bg-[var(--cmp-datepicker-calendar-time-bg-selected)]" : "bg-[var(--cmp-datepicker-calendar-time-bg-default)]"
|
|
8351
|
+
),
|
|
8352
|
+
children: [
|
|
8353
|
+
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[var(--cmp-datepicker-calendar-time-date-gap)]", children: [
|
|
8354
|
+
/* @__PURE__ */ jsx("span", { className: LABEL, children: num(yy, false) }),
|
|
8355
|
+
/* @__PURE__ */ jsx("span", { className: UNIT, children: "\uB144" }),
|
|
8356
|
+
/* @__PURE__ */ jsx("span", { className: LABEL, children: num(mm, true) }),
|
|
8357
|
+
/* @__PURE__ */ jsx("span", { className: UNIT, children: "\uC6D4" }),
|
|
8358
|
+
/* @__PURE__ */ jsx("span", { className: LABEL, children: num(dd, true) }),
|
|
8359
|
+
/* @__PURE__ */ jsx("span", { className: UNIT, children: "\uC77C" })
|
|
8360
|
+
] }),
|
|
8361
|
+
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[var(--cmp-datepicker-calendar-time-unit-gap)]", children: [
|
|
8362
|
+
/* @__PURE__ */ jsx(
|
|
8363
|
+
"input",
|
|
8364
|
+
{
|
|
8365
|
+
type: "text",
|
|
8366
|
+
inputMode: "numeric",
|
|
8367
|
+
maxLength: 2,
|
|
8368
|
+
"aria-label": `${suffix} \uC2DC`,
|
|
8369
|
+
disabled: !active,
|
|
8370
|
+
value: active ? hour : "",
|
|
8371
|
+
placeholder: "--",
|
|
8372
|
+
onChange: (e) => changeTime(which, "h", e.target.value),
|
|
8373
|
+
onBlur: () => blurTime(which, "h"),
|
|
8374
|
+
className: INPUT_CLS
|
|
8375
|
+
}
|
|
8376
|
+
),
|
|
8377
|
+
/* @__PURE__ */ jsx("span", { className: LABEL, children: ":" }),
|
|
8378
|
+
/* @__PURE__ */ jsx(
|
|
8379
|
+
"input",
|
|
8380
|
+
{
|
|
8381
|
+
type: "text",
|
|
8382
|
+
inputMode: "numeric",
|
|
8383
|
+
maxLength: 2,
|
|
8384
|
+
"aria-label": `${suffix} \uBD84`,
|
|
8385
|
+
disabled: !active,
|
|
8386
|
+
value: active ? minute : "",
|
|
8387
|
+
placeholder: "--",
|
|
8388
|
+
onChange: (e) => changeTime(which, "m", e.target.value),
|
|
8389
|
+
onBlur: () => blurTime(which, "m"),
|
|
8390
|
+
className: INPUT_CLS
|
|
8391
|
+
}
|
|
8392
|
+
)
|
|
8393
|
+
] }),
|
|
8394
|
+
/* @__PURE__ */ jsx("span", { className: UNIT, children: suffix })
|
|
8395
|
+
]
|
|
8396
|
+
}
|
|
8397
|
+
);
|
|
8398
|
+
};
|
|
8399
|
+
return /* @__PURE__ */ jsxs(
|
|
8400
|
+
"div",
|
|
8401
|
+
{
|
|
8402
|
+
className: cn(
|
|
8403
|
+
"inline-flex flex-col gap-[var(--cmp-datepicker-calendar-gap)] rounded-[var(--cmp-datepicker-calendar-radius)] bg-[var(--cmp-datepicker-calendar-bg)] p-[var(--cmp-datepicker-calendar-paddingXY)] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.2)] select-none",
|
|
8404
|
+
useTimePicker ? "h-auto" : "h-[364px]"
|
|
8236
8405
|
),
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
8406
|
+
children: [
|
|
8407
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
|
|
8408
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-[var(--cmp-datepicker-calendar-gap)] text-[14px] font-medium leading-[24px]", children: [
|
|
8409
|
+
/* @__PURE__ */ jsx(SGhostButton, { icon: "chevronLeft", size: "xxs", ariaLabel: "prevYear", onClick: goPrevYear }),
|
|
8410
|
+
/* @__PURE__ */ jsx("span", { className: "inline-flex min-w-[40px] items-center justify-center text-center", children: y }),
|
|
8411
|
+
/* @__PURE__ */ jsx(SGhostButton, { icon: "chevronRight", size: "xxs", ariaLabel: "nextYear", onClick: goNextYear })
|
|
8412
|
+
] }),
|
|
8413
|
+
/* @__PURE__ */ jsx(
|
|
8414
|
+
"button",
|
|
8415
|
+
{
|
|
8416
|
+
type: "button",
|
|
8417
|
+
onClick: goToday,
|
|
8418
|
+
className: "absolute right-0 h-[24px] min-w-[37px] cursor-pointer bg-transparent text-center text-[12px] font-medium leading-[24px] text-[color:var(--cmp-datepicker-calendar-day-default-text)] hover:underline",
|
|
8419
|
+
children: "\uC624\uB298"
|
|
8420
|
+
}
|
|
8421
|
+
)
|
|
8422
|
+
] }),
|
|
8423
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-[var(--cmp-datepicker-calendar-range-panelGap)]", children: [
|
|
8424
|
+
renderPanel(y, m, true),
|
|
8425
|
+
/* @__PURE__ */ jsx(
|
|
8426
|
+
"span",
|
|
8427
|
+
{
|
|
8428
|
+
className: "w-px shrink-0 self-stretch bg-[var(--cmp-datepicker-calendar-range-divider)]",
|
|
8429
|
+
"aria-hidden": true
|
|
8430
|
+
}
|
|
8431
|
+
),
|
|
8432
|
+
renderPanel(nextMonthYM.year, nextMonthYM.month, false)
|
|
8433
|
+
] }),
|
|
8434
|
+
useTimePicker && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8435
|
+
/* @__PURE__ */ jsx(
|
|
8436
|
+
"span",
|
|
8437
|
+
{
|
|
8438
|
+
className: "h-px w-full bg-[var(--cmp-datepicker-calendar-range-divider)]",
|
|
8439
|
+
"aria-hidden": true
|
|
8440
|
+
}
|
|
8441
|
+
),
|
|
8442
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-[var(--cmp-datepicker-calendar-time-gap)]", children: [
|
|
8443
|
+
renderTimeSection("start", start, "\uBD80\uD130"),
|
|
8444
|
+
renderTimeSection("end", end, "\uAE4C\uC9C0")
|
|
8445
|
+
] })
|
|
8446
|
+
] })
|
|
8447
|
+
]
|
|
8448
|
+
}
|
|
8449
|
+
);
|
|
8240
8450
|
}
|
|
8241
8451
|
function SDateRangePicker({
|
|
8242
8452
|
value,
|
|
@@ -8246,6 +8456,7 @@ function SDateRangePicker({
|
|
|
8246
8456
|
placeholder = "YYYY-MM-DD ~ YYYY-MM-DD",
|
|
8247
8457
|
selectable,
|
|
8248
8458
|
maxRange,
|
|
8459
|
+
useTimePicker = false,
|
|
8249
8460
|
disabled = false,
|
|
8250
8461
|
width,
|
|
8251
8462
|
name,
|
|
@@ -8289,8 +8500,9 @@ function SDateRangePicker({
|
|
|
8289
8500
|
setPendingStart(null);
|
|
8290
8501
|
onValueChange?.(r);
|
|
8291
8502
|
if (rules && rules.length > 0) setRuleError(runRules(r, rules));
|
|
8292
|
-
setOpen(false);
|
|
8503
|
+
if (!useTimePicker) setOpen(false);
|
|
8293
8504
|
};
|
|
8505
|
+
const resolvedPlaceholder = useTimePicker && placeholder === "YYYY-MM-DD ~ YYYY-MM-DD" ? "YYYY-MM-DD HH:mm ~ YYYY-MM-DD HH:mm" : placeholder;
|
|
8294
8506
|
return /* @__PURE__ */ jsx(
|
|
8295
8507
|
SField,
|
|
8296
8508
|
{
|
|
@@ -8357,7 +8569,7 @@ function SDateRangePicker({
|
|
|
8357
8569
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-right", children: startText }),
|
|
8358
8570
|
/* @__PURE__ */ jsx("span", { className: "px-[4px]", children: "~" }),
|
|
8359
8571
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: endText })
|
|
8360
|
-
] }) :
|
|
8572
|
+
] }) : resolvedPlaceholder
|
|
8361
8573
|
}
|
|
8362
8574
|
)
|
|
8363
8575
|
]
|
|
@@ -8376,6 +8588,7 @@ function SDateRangePicker({
|
|
|
8376
8588
|
value: value ?? null,
|
|
8377
8589
|
selectable,
|
|
8378
8590
|
maxRange,
|
|
8591
|
+
useTimePicker,
|
|
8379
8592
|
onSelect: select,
|
|
8380
8593
|
onPendingStartChange: setPendingStart,
|
|
8381
8594
|
onViewChange
|