sellmate-design-system-react 9.0.0-beta.40 → 9.0.0-beta.42
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/AGENTS.md +41 -20
- package/dist/components/SBarcodeInput/README.md +3 -3
- package/dist/components/SBarcodeInput/SBarcodeInput.d.ts +3 -1
- package/dist/components/SChipInput/README.md +1 -1
- package/dist/components/SChipInput/SChipInput.d.ts +1 -1
- package/dist/components/SConfirmModal/README.md +3 -11
- package/dist/components/SConfirmModal/SConfirmModal.d.ts +16 -8
- package/dist/components/SConfirmModal/index.d.ts +1 -1
- package/dist/components/SDateRangePicker/README.md +2 -2
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +4 -4
- package/dist/components/SEditor/EditorBody.d.ts +1 -1
- package/dist/components/SEditor/README.md +4 -4
- package/dist/components/SEditor/SEditor.d.ts +3 -3
- package/dist/components/SField/README.md +2 -2
- package/dist/components/SField/SField.d.ts +8 -2
- package/dist/components/SFilePicker/README.md +3 -3
- package/dist/components/SFilePicker/SFilePicker.d.ts +4 -4
- package/dist/components/SForm/README.md +1 -1
- package/dist/components/SForm/SForm.d.ts +2 -2
- package/dist/components/SGnb/README.md +7 -7
- package/dist/components/SGnb/SGnb.d.ts +9 -9
- package/dist/components/SGnb/gnb.config.d.ts +2 -2
- package/dist/components/SImage/README.md +1 -1
- package/dist/components/SImage/SImage.d.ts +2 -2
- package/dist/components/SInput/README.md +3 -3
- package/dist/components/SInput/SInput.d.ts +3 -3
- package/dist/components/SLayout/README.md +1 -1
- package/dist/components/SLayout/SLayout.d.ts +2 -2
- package/dist/components/SList/README.md +10 -2
- package/dist/components/SList/SList.d.ts +7 -3
- package/dist/components/SList/index.d.ts +1 -1
- package/dist/components/SLoadingModal/README.md +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.d.ts +2 -2
- package/dist/components/SModal/README.md +1 -1
- package/dist/components/SNumberInput/README.md +5 -5
- package/dist/components/SNumberInput/SNumberInput.d.ts +5 -3
- package/dist/components/SPage/README.md +42 -3
- package/dist/components/SPage/SPage.d.ts +16 -1
- package/dist/components/SPage/SPageHeader.d.ts +19 -8
- package/dist/components/SPage/index.d.ts +1 -1
- package/dist/components/SPage/page-column.d.ts +11 -2
- package/dist/components/SPage/page-width.d.ts +23 -0
- package/dist/components/SPage/page.config.d.ts +18 -0
- package/dist/components/SPopup/README.md +8 -2
- package/dist/components/SPopup/SPopup.d.ts +7 -3
- package/dist/components/SPopup/index.d.ts +1 -1
- package/dist/components/SSearchInput/README.md +3 -3
- package/dist/components/SSearchInput/SSearchInput.d.ts +3 -3
- package/dist/components/SSelect/README.md +5 -5
- package/dist/components/SSelect/SSelect.d.ts +14 -6
- package/dist/components/SSplitter/README.md +2 -2
- package/dist/components/SSplitter/SSplitter.d.ts +7 -3
- package/dist/components/SSwitch/README.md +0 -1
- package/dist/components/SSwitch/SSwitch.d.ts +1 -3
- package/dist/components/STable/README.md +8 -9
- package/dist/components/STable/STable.d.ts +9 -11
- package/dist/components/STabs/README.md +1 -1
- package/dist/components/STabs/STabs.d.ts +2 -2
- package/dist/components/STextLink/README.md +1 -1
- package/dist/components/STextLink/STextLink.d.ts +1 -1
- package/dist/components/STextarea/README.md +3 -3
- package/dist/components/STextarea/STextarea.d.ts +3 -3
- package/dist/components/STimePicker/README.md +1 -1
- package/dist/components/STimePicker/STimePicker.d.ts +4 -4
- package/dist/components/STimeRangePicker/README.md +1 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.d.ts +4 -4
- package/dist/components/SToast/README.md +1 -1
- package/dist/components/SToast/SToast.d.ts +2 -2
- package/dist/components/STooltip/README.md +1 -1
- package/dist/components/STooltip/STooltip.d.ts +1 -1
- package/dist/components/STree/README.md +4 -4
- package/dist/components/STree/STree.d.ts +17 -5
- package/dist/index.cjs +365 -248
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +364 -249
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +170 -106
- package/dist/llms.txt +41 -20
- package/dist/styles.css +9 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3413,7 +3413,7 @@ var SImage = /* @__PURE__ */ react.forwardRef(function SImage2({
|
|
|
3413
3413
|
position = "50% 50%",
|
|
3414
3414
|
loading: loading2 = "lazy",
|
|
3415
3415
|
loadingShowDelay = 0,
|
|
3416
|
-
|
|
3416
|
+
showSpinner = true,
|
|
3417
3417
|
loadingSlot,
|
|
3418
3418
|
errorSlot,
|
|
3419
3419
|
imgProps,
|
|
@@ -3449,7 +3449,7 @@ var SImage = /* @__PURE__ */ react.forwardRef(function SImage2({
|
|
|
3449
3449
|
}, [status, loadingShowDelay, src]);
|
|
3450
3450
|
const isEmpty = !src;
|
|
3451
3451
|
const showFallback = isEmpty || status === "error";
|
|
3452
|
-
const
|
|
3452
|
+
const spinnerShown = !isEmpty && status === "loading" && showSpinner && spinnerVisible;
|
|
3453
3453
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3454
3454
|
"div",
|
|
3455
3455
|
{
|
|
@@ -3488,7 +3488,7 @@ var SImage = /* @__PURE__ */ react.forwardRef(function SImage2({
|
|
|
3488
3488
|
}
|
|
3489
3489
|
),
|
|
3490
3490
|
showFallback && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 flex items-center justify-center", children: errorSlot ?? /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "image", size: EMPTY_ICON_SIZE, color: "var(--cmp-image-icon)" }) }),
|
|
3491
|
-
|
|
3491
|
+
spinnerShown && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 flex items-center justify-center", children: loadingSlot ?? /* @__PURE__ */ jsxRuntime.jsx(SCircleProgress, { indeterminate: true, type: "neutral", size: SPINNER_SIZE }) })
|
|
3492
3492
|
]
|
|
3493
3493
|
}
|
|
3494
3494
|
);
|
|
@@ -4080,6 +4080,10 @@ var SDivider = /* @__PURE__ */ react.forwardRef(function SDivider2({ vertical =
|
|
|
4080
4080
|
}
|
|
4081
4081
|
);
|
|
4082
4082
|
});
|
|
4083
|
+
var PADDING_CLASS = {
|
|
4084
|
+
default: "p-(--cmp-list-group-padding)",
|
|
4085
|
+
none: ""
|
|
4086
|
+
};
|
|
4083
4087
|
var dividerStyle = { backgroundColor: "var(--cmp-listItem-border-default)" };
|
|
4084
4088
|
function hasBorderedChild(children) {
|
|
4085
4089
|
let bordered = false;
|
|
@@ -4105,15 +4109,15 @@ function withDividers(children) {
|
|
|
4105
4109
|
]
|
|
4106
4110
|
);
|
|
4107
4111
|
}
|
|
4108
|
-
var SListImpl = /* @__PURE__ */ react.forwardRef(function SList({ className, children,
|
|
4109
|
-
const showDivider = !
|
|
4112
|
+
var SListImpl = /* @__PURE__ */ react.forwardRef(function SList({ className, children, gap = false, padding = "none", ...rest }, ref) {
|
|
4113
|
+
const showDivider = !gap && !hasBorderedChild(children);
|
|
4110
4114
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4111
4115
|
"div",
|
|
4112
4116
|
{
|
|
4113
4117
|
ref,
|
|
4114
4118
|
className: cn(
|
|
4115
|
-
|
|
4116
|
-
|
|
4119
|
+
gap && "flex flex-col gap-(--cmp-list-group-gap)",
|
|
4120
|
+
PADDING_CLASS[padding],
|
|
4117
4121
|
className
|
|
4118
4122
|
),
|
|
4119
4123
|
...rest,
|
|
@@ -4358,7 +4362,7 @@ function SDraggableListInner({
|
|
|
4358
4362
|
maxDepth = 3,
|
|
4359
4363
|
listId,
|
|
4360
4364
|
group: groupName,
|
|
4361
|
-
|
|
4365
|
+
gap,
|
|
4362
4366
|
className,
|
|
4363
4367
|
...rest
|
|
4364
4368
|
}, ref) {
|
|
@@ -4373,7 +4377,7 @@ function SDraggableListInner({
|
|
|
4373
4377
|
const fromIndexRef = react.useRef(null);
|
|
4374
4378
|
const currentSelectedKey = selectedKey ?? internalSelectedKey;
|
|
4375
4379
|
const usesDepth = getDepth != null;
|
|
4376
|
-
const depthEnabled = usesDepth && !
|
|
4380
|
+
const depthEnabled = usesDepth && !gap;
|
|
4377
4381
|
const groupDragging = dragContext?.dragging;
|
|
4378
4382
|
const draggedSubtreeStart = dragContext ? groupDragging?.listId === listId ? groupDragging?.index ?? null : null : draggingIndex;
|
|
4379
4383
|
const startDrag = react.useCallback((event, index) => {
|
|
@@ -4487,11 +4491,11 @@ function SDraggableListInner({
|
|
|
4487
4491
|
borderTop: "2px solid var(--sys-color-fg-accentLight)",
|
|
4488
4492
|
left: getIndicatorOffset(depth),
|
|
4489
4493
|
right: 0,
|
|
4490
|
-
top:
|
|
4494
|
+
top: gap ? -5 : 0
|
|
4491
4495
|
});
|
|
4492
4496
|
const afterIndicatorStyle = (depth) => ({
|
|
4493
4497
|
borderTop: "2px solid var(--sys-color-fg-accentLight)",
|
|
4494
|
-
bottom:
|
|
4498
|
+
bottom: gap ? -5 : -1,
|
|
4495
4499
|
left: getIndicatorOffset(depth),
|
|
4496
4500
|
right: 0
|
|
4497
4501
|
});
|
|
@@ -4514,7 +4518,7 @@ function SDraggableListInner({
|
|
|
4514
4518
|
{
|
|
4515
4519
|
ref: setListRef,
|
|
4516
4520
|
...rest,
|
|
4517
|
-
|
|
4521
|
+
gap,
|
|
4518
4522
|
className: `${className ?? ""} ${dragContext ? "min-h-[40px]" : ""} ${showEmptyDrop ? "relative before:absolute before:left-0 before:right-0 before:top-0 before:z-10 before:h-[2px] before:bg-(--sys-color-fg-accentLight) before:content-['']" : ""}`,
|
|
4519
4523
|
"data-drag-active": dragActive || void 0,
|
|
4520
4524
|
"data-draggable-group": dragContext ? dragGroup : void 0,
|
|
@@ -5099,7 +5103,11 @@ var STag = /* @__PURE__ */ react.forwardRef(function STag2({
|
|
|
5099
5103
|
...rest,
|
|
5100
5104
|
children: [
|
|
5101
5105
|
icon && iconLeft && iconNode,
|
|
5102
|
-
label &&
|
|
5106
|
+
label && // leading-none: 태그는 min-height 로 높이가 정해지고 flex 가 세로 중앙 정렬하므로
|
|
5107
|
+
// 레이블에 line-height 가 필요 없다. 오히려 line-height 를 주면 브라우저가
|
|
5108
|
+
// 폰트 ascent/descent 를 정수 px 로 반올림한 뒤 남는 half-leading 을 내림 처리해
|
|
5109
|
+
// 베이스라인이 최대 1px 위로 밀린다(xs 에서 특히 눈에 띈다).
|
|
5110
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex min-w-0 items-center justify-center leading-none", children: label }),
|
|
5103
5111
|
icon && !iconLeft && iconNode
|
|
5104
5112
|
]
|
|
5105
5113
|
}
|
|
@@ -5352,7 +5360,7 @@ function STreeAllItem({
|
|
|
5352
5360
|
var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
5353
5361
|
node,
|
|
5354
5362
|
depth = 1,
|
|
5355
|
-
|
|
5363
|
+
last = true,
|
|
5356
5364
|
ancestorLast = [],
|
|
5357
5365
|
expanded = false,
|
|
5358
5366
|
selected = false,
|
|
@@ -5420,7 +5428,7 @@ var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
|
5420
5428
|
size,
|
|
5421
5429
|
depth,
|
|
5422
5430
|
hasChildren,
|
|
5423
|
-
isLast,
|
|
5431
|
+
isLast: last,
|
|
5424
5432
|
ancestorLast
|
|
5425
5433
|
}
|
|
5426
5434
|
),
|
|
@@ -5488,7 +5496,7 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
5488
5496
|
defaultExpandedIds,
|
|
5489
5497
|
selectable = true,
|
|
5490
5498
|
size = "sm",
|
|
5491
|
-
|
|
5499
|
+
showSelectAll = false,
|
|
5492
5500
|
cascadeSelection = true,
|
|
5493
5501
|
guideline = true,
|
|
5494
5502
|
border = true,
|
|
@@ -5511,7 +5519,7 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
5511
5519
|
const allSelected = selectableIds.length > 0 && selectableIds.every((id) => selectedSet.has(id));
|
|
5512
5520
|
const someSelected = selectableIds.some((id) => selectedSet.has(id));
|
|
5513
5521
|
const allIndeterminate = someSelected && !allSelected;
|
|
5514
|
-
const showAllItem = selectable &&
|
|
5522
|
+
const showAllItem = selectable && showSelectAll;
|
|
5515
5523
|
const updateExpanded = (node) => {
|
|
5516
5524
|
const next = new Set(currentExpandedIds);
|
|
5517
5525
|
if (next.has(node.id)) next.delete(node.id);
|
|
@@ -5555,7 +5563,7 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
5555
5563
|
{
|
|
5556
5564
|
node,
|
|
5557
5565
|
depth,
|
|
5558
|
-
isLast,
|
|
5566
|
+
last: isLast,
|
|
5559
5567
|
ancestorLast,
|
|
5560
5568
|
expanded: isExpanded,
|
|
5561
5569
|
selected,
|
|
@@ -5699,7 +5707,7 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
|
|
|
5699
5707
|
placement = "top",
|
|
5700
5708
|
sideOffset = 8,
|
|
5701
5709
|
tooltipType = "default",
|
|
5702
|
-
|
|
5710
|
+
showClose = false,
|
|
5703
5711
|
disabled = false,
|
|
5704
5712
|
children,
|
|
5705
5713
|
icon = "helpOutline",
|
|
@@ -5734,7 +5742,7 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
|
|
|
5734
5742
|
setOpenState(true);
|
|
5735
5743
|
};
|
|
5736
5744
|
const startHide = () => {
|
|
5737
|
-
if (
|
|
5745
|
+
if (showClose) return;
|
|
5738
5746
|
cancelHide();
|
|
5739
5747
|
hideTimer.current = setTimeout(() => setOpenState(false), HIDE_DELAY_MS);
|
|
5740
5748
|
};
|
|
@@ -5785,7 +5793,7 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
|
|
|
5785
5793
|
return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: setOpenState, children: [
|
|
5786
5794
|
isNone ? (
|
|
5787
5795
|
// 트리거 없음: children 을 래퍼 없이 그대로 앵커로 쓴다 (소비자 레이아웃 보존).
|
|
5788
|
-
// mouse/focus 핸들러가 없으므로
|
|
5796
|
+
// mouse/focus 핸들러가 없으므로 showClose 없이도 자동 닫힘이 발생하지 않는다.
|
|
5789
5797
|
/* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: triggerNode })
|
|
5790
5798
|
) : isHover ? (
|
|
5791
5799
|
// hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
|
|
@@ -5810,10 +5818,10 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
|
|
|
5810
5818
|
style: contentStyle,
|
|
5811
5819
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
5812
5820
|
onInteractOutside: (e) => {
|
|
5813
|
-
if (
|
|
5821
|
+
if (showClose || isNone) e.preventDefault();
|
|
5814
5822
|
},
|
|
5815
5823
|
onEscapeKeyDown: (e) => {
|
|
5816
|
-
if (
|
|
5824
|
+
if (showClose || isNone) e.preventDefault();
|
|
5817
5825
|
},
|
|
5818
5826
|
onMouseEnter: isHover ? cancelHide : void 0,
|
|
5819
5827
|
onMouseLeave: isHover ? startHide : void 0,
|
|
@@ -5821,7 +5829,7 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
|
|
|
5821
5829
|
children: [
|
|
5822
5830
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-[12px]", children: [
|
|
5823
5831
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: body }),
|
|
5824
|
-
|
|
5832
|
+
showClose && !isNone && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5825
5833
|
SGhostButton,
|
|
5826
5834
|
{
|
|
5827
5835
|
icon: "close",
|
|
@@ -6078,7 +6086,7 @@ var SSplitterRoot = /* @__PURE__ */ react.forwardRef(function SSplitter({
|
|
|
6078
6086
|
onValueChange,
|
|
6079
6087
|
unit = "%",
|
|
6080
6088
|
limits,
|
|
6081
|
-
|
|
6089
|
+
updateWhileDragging = false,
|
|
6082
6090
|
vertical = false,
|
|
6083
6091
|
disabled = false,
|
|
6084
6092
|
dividerClassName,
|
|
@@ -6108,8 +6116,8 @@ var SSplitterRoot = /* @__PURE__ */ react.forwardRef(function SSplitter({
|
|
|
6108
6116
|
const [minLimit, maxLimit] = limits ?? SSPLITTER_DEFAULT_LIMITS[unit];
|
|
6109
6117
|
const stateRef = react.useRef({ committedValue, unit, vertical, minLimit, maxLimit });
|
|
6110
6118
|
stateRef.current = { committedValue, unit, vertical, minLimit, maxLimit };
|
|
6111
|
-
const emitRef = react.useRef({ onValueChange,
|
|
6112
|
-
emitRef.current = { onValueChange,
|
|
6119
|
+
const emitRef = react.useRef({ onValueChange, updateWhileDragging, isControlled });
|
|
6120
|
+
emitRef.current = { onValueChange, updateWhileDragging, isControlled };
|
|
6113
6121
|
const measure = react.useCallback(() => {
|
|
6114
6122
|
const el = rootRef.current;
|
|
6115
6123
|
if (!el) return 0;
|
|
@@ -6148,7 +6156,7 @@ var SSplitterRoot = /* @__PURE__ */ react.forwardRef(function SSplitter({
|
|
|
6148
6156
|
const delta = (isVertical ? moveEvent.clientY : moveEvent.clientX) - startPos;
|
|
6149
6157
|
latest = clamp4(startValue + multiplier * delta, containerSize);
|
|
6150
6158
|
setDragValue(latest);
|
|
6151
|
-
if (emitRef.current.
|
|
6159
|
+
if (emitRef.current.updateWhileDragging) commit(latest);
|
|
6152
6160
|
};
|
|
6153
6161
|
const endDrag = () => {
|
|
6154
6162
|
document.removeEventListener("mousemove", onMove);
|
|
@@ -6585,7 +6593,7 @@ var STextLink = /* @__PURE__ */ react.forwardRef(function STextLink2({
|
|
|
6585
6593
|
icon,
|
|
6586
6594
|
iconColor,
|
|
6587
6595
|
iconRotate,
|
|
6588
|
-
|
|
6596
|
+
labelClassName,
|
|
6589
6597
|
rightArrow = "none",
|
|
6590
6598
|
rightArrowRotate,
|
|
6591
6599
|
underline = false,
|
|
@@ -6632,7 +6640,7 @@ var STextLink = /* @__PURE__ */ react.forwardRef(function STextLink2({
|
|
|
6632
6640
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6633
6641
|
"span",
|
|
6634
6642
|
{
|
|
6635
|
-
className: cn(
|
|
6643
|
+
className: cn(labelClassName),
|
|
6636
6644
|
style: disabled ? { color: "var(--cmp-textLink-content-disabled)" } : void 0,
|
|
6637
6645
|
children: label || children
|
|
6638
6646
|
}
|
|
@@ -6898,13 +6906,12 @@ function SSwitch({
|
|
|
6898
6906
|
value = false,
|
|
6899
6907
|
leftLabel,
|
|
6900
6908
|
rightLabel,
|
|
6901
|
-
label,
|
|
6902
6909
|
disabled = false,
|
|
6903
6910
|
onValueChange,
|
|
6904
6911
|
className,
|
|
6905
6912
|
style
|
|
6906
6913
|
}) {
|
|
6907
|
-
const right = rightLabel
|
|
6914
|
+
const right = rightLabel;
|
|
6908
6915
|
const renderLabel = (text) => text ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[12px] font-medium leading-[20px]", children: text }) : null;
|
|
6909
6916
|
const trackBg = disabled ? value ? "var(--cmp-switch-bg-disabled-on)" : "var(--cmp-switch-bg-disabled-off)" : value ? "var(--cmp-switch-bg-on)" : "var(--cmp-switch-bg-off)";
|
|
6910
6917
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -7788,7 +7795,7 @@ function SPopover({
|
|
|
7788
7795
|
STextLink,
|
|
7789
7796
|
{
|
|
7790
7797
|
label: leftLinkLabel,
|
|
7791
|
-
|
|
7798
|
+
labelClassName: leftLinkLabelClass,
|
|
7792
7799
|
onClick: onLeftLinkClick
|
|
7793
7800
|
}
|
|
7794
7801
|
),
|
|
@@ -7811,14 +7818,18 @@ function SPopover({
|
|
|
7811
7818
|
) })
|
|
7812
7819
|
] });
|
|
7813
7820
|
}
|
|
7821
|
+
var BODY_PADDING_CLASS2 = {
|
|
7822
|
+
default: "p-(--sys-space-panel-padding-default)",
|
|
7823
|
+
none: ""
|
|
7824
|
+
};
|
|
7814
7825
|
var SPopup = /* @__PURE__ */ react.forwardRef(function SPopup2({
|
|
7815
7826
|
popupTitle = "",
|
|
7816
7827
|
type = "default",
|
|
7817
|
-
|
|
7828
|
+
showFooter = false,
|
|
7818
7829
|
submitButton,
|
|
7819
7830
|
onSubmit,
|
|
7820
7831
|
footerLeft,
|
|
7821
|
-
|
|
7832
|
+
padding = "default",
|
|
7822
7833
|
children,
|
|
7823
7834
|
className,
|
|
7824
7835
|
style
|
|
@@ -7853,7 +7864,7 @@ var SPopup = /* @__PURE__ */ react.forwardRef(function SPopup2({
|
|
|
7853
7864
|
{
|
|
7854
7865
|
className: cn(
|
|
7855
7866
|
"box-border min-h-0 flex-1 overflow-auto",
|
|
7856
|
-
|
|
7867
|
+
BODY_PADDING_CLASS2[padding],
|
|
7857
7868
|
SCROLLBAR_CLASS,
|
|
7858
7869
|
SCROLLBAR_TRACK_BG_CLASS,
|
|
7859
7870
|
SCROLLBAR_TRACK_BORDER_CLASS
|
|
@@ -7861,7 +7872,7 @@ var SPopup = /* @__PURE__ */ react.forwardRef(function SPopup2({
|
|
|
7861
7872
|
children
|
|
7862
7873
|
}
|
|
7863
7874
|
),
|
|
7864
|
-
|
|
7875
|
+
showFooter && /* @__PURE__ */ jsxRuntime.jsx(SFooter, { left: footerLeft, button: { ...submitButton, onClick: onSubmit } })
|
|
7865
7876
|
]
|
|
7866
7877
|
}
|
|
7867
7878
|
);
|
|
@@ -8157,17 +8168,15 @@ var TYPE_ICON_COLOR = {
|
|
|
8157
8168
|
negative: "var(--cmp-modal-confirm-negative-icon)",
|
|
8158
8169
|
default: ""
|
|
8159
8170
|
};
|
|
8160
|
-
var
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
|
-
|
|
8164
|
-
danger_outline_md: { color: "danger", outline: true },
|
|
8165
|
-
neutral_outline_md: { color: "neutral", outline: true }
|
|
8171
|
+
var MAIN_BUTTON_COLOR = {
|
|
8172
|
+
positive: "primary",
|
|
8173
|
+
negative: "danger",
|
|
8174
|
+
default: "neutral"
|
|
8166
8175
|
};
|
|
8167
|
-
var
|
|
8168
|
-
positive:
|
|
8169
|
-
negative:
|
|
8170
|
-
default:
|
|
8176
|
+
var MAIN_BUTTON_OUTLINE = {
|
|
8177
|
+
positive: false,
|
|
8178
|
+
negative: false,
|
|
8179
|
+
default: true
|
|
8171
8180
|
};
|
|
8172
8181
|
function SConfirmModal({
|
|
8173
8182
|
open,
|
|
@@ -8175,7 +8184,7 @@ function SConfirmModal({
|
|
|
8175
8184
|
persistent = false,
|
|
8176
8185
|
type = "positive",
|
|
8177
8186
|
modalTitle = "",
|
|
8178
|
-
|
|
8187
|
+
titleClassName,
|
|
8179
8188
|
topMessage = [],
|
|
8180
8189
|
bottomMessage = [],
|
|
8181
8190
|
tagLabel,
|
|
@@ -8187,14 +8196,15 @@ function SConfirmModal({
|
|
|
8187
8196
|
optionSlot,
|
|
8188
8197
|
contentSlot,
|
|
8189
8198
|
mainButtonLabel = "\uD655\uC778",
|
|
8190
|
-
|
|
8199
|
+
mainButtonOutline,
|
|
8191
8200
|
subButtonLabel,
|
|
8192
8201
|
onOk,
|
|
8193
8202
|
onCancel,
|
|
8194
8203
|
onClose
|
|
8195
8204
|
}) {
|
|
8196
8205
|
const iconName = TYPE_ICON[type];
|
|
8197
|
-
const
|
|
8206
|
+
const mainColor = MAIN_BUTTON_COLOR[type];
|
|
8207
|
+
const mainOutline = mainButtonOutline ?? MAIN_BUTTON_OUTLINE[type];
|
|
8198
8208
|
const [settled, setSettled] = react.useState(false);
|
|
8199
8209
|
react.useEffect(() => {
|
|
8200
8210
|
if (open) setSettled(false);
|
|
@@ -8228,7 +8238,7 @@ function SConfirmModal({
|
|
|
8228
8238
|
{
|
|
8229
8239
|
className: cn(
|
|
8230
8240
|
"text-center text-[18px] font-bold leading-[30px] text-[color:var(--cmp-modal-confirm-title-color)]",
|
|
8231
|
-
|
|
8241
|
+
titleClassName
|
|
8232
8242
|
),
|
|
8233
8243
|
children: modalTitle
|
|
8234
8244
|
}
|
|
@@ -8275,7 +8285,8 @@ function SConfirmModal({
|
|
|
8275
8285
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8276
8286
|
SButton,
|
|
8277
8287
|
{
|
|
8278
|
-
|
|
8288
|
+
color: mainColor,
|
|
8289
|
+
outline: mainOutline,
|
|
8279
8290
|
size: "md",
|
|
8280
8291
|
disabled: settled,
|
|
8281
8292
|
onClick: () => settle(onOk),
|
|
@@ -8394,7 +8405,7 @@ function SLoadingModal({
|
|
|
8394
8405
|
state: state2 = "loading",
|
|
8395
8406
|
progress,
|
|
8396
8407
|
message,
|
|
8397
|
-
|
|
8408
|
+
showButton = false,
|
|
8398
8409
|
buttonLabel,
|
|
8399
8410
|
onButtonClick,
|
|
8400
8411
|
width = 520,
|
|
@@ -8402,7 +8413,7 @@ function SLoadingModal({
|
|
|
8402
8413
|
}) {
|
|
8403
8414
|
const resolvedMessage = message ?? DEFAULT_MESSAGE[state2];
|
|
8404
8415
|
const lines = Array.isArray(resolvedMessage) ? resolvedMessage : resolvedMessage ? [resolvedMessage] : [];
|
|
8405
|
-
const
|
|
8416
|
+
const buttonVisible = showButton || state2 === "error";
|
|
8406
8417
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8407
8418
|
SModalContainer,
|
|
8408
8419
|
{
|
|
@@ -8424,7 +8435,7 @@ function SLoadingModal({
|
|
|
8424
8435
|
},
|
|
8425
8436
|
i
|
|
8426
8437
|
)) }),
|
|
8427
|
-
|
|
8438
|
+
buttonVisible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8428
8439
|
SButton,
|
|
8429
8440
|
{
|
|
8430
8441
|
color: "neutral",
|
|
@@ -9160,7 +9171,11 @@ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutE
|
|
|
9160
9171
|
var SPageColumnContext = /* @__PURE__ */ react.createContext(null);
|
|
9161
9172
|
function SPageColumn({ full, children }) {
|
|
9162
9173
|
const [scrolled, setScrolled] = react.useState(false);
|
|
9163
|
-
const
|
|
9174
|
+
const [contentWidth, setContentWidth] = react.useState("full");
|
|
9175
|
+
const value = react.useMemo(
|
|
9176
|
+
() => ({ scrolled, setScrolled, contentWidth, setContentWidth }),
|
|
9177
|
+
[scrolled, contentWidth]
|
|
9178
|
+
);
|
|
9164
9179
|
return /* @__PURE__ */ jsxRuntime.jsx(SPageColumnContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9165
9180
|
"div",
|
|
9166
9181
|
{
|
|
@@ -9183,7 +9198,7 @@ function useSLayout() {
|
|
|
9183
9198
|
var SLayout = /* @__PURE__ */ react.forwardRef(function SLayout2({
|
|
9184
9199
|
type = "box",
|
|
9185
9200
|
header = "fix",
|
|
9186
|
-
|
|
9201
|
+
showRail = false,
|
|
9187
9202
|
folded,
|
|
9188
9203
|
defaultFolded = false,
|
|
9189
9204
|
onFoldedChange,
|
|
@@ -9212,12 +9227,12 @@ var SLayout = /* @__PURE__ */ react.forwardRef(function SLayout2({
|
|
|
9212
9227
|
() => ({
|
|
9213
9228
|
type,
|
|
9214
9229
|
header: effectiveHeader,
|
|
9215
|
-
|
|
9230
|
+
showRail,
|
|
9216
9231
|
folded: currentFolded,
|
|
9217
9232
|
setFolded,
|
|
9218
9233
|
registerNav
|
|
9219
9234
|
}),
|
|
9220
|
-
[type, effectiveHeader,
|
|
9235
|
+
[type, effectiveHeader, showRail, currentFolded, setFolded, registerNav]
|
|
9221
9236
|
);
|
|
9222
9237
|
const isFullHeader = effectiveHeader === "full";
|
|
9223
9238
|
const minWidthStyle = {
|
|
@@ -9466,12 +9481,12 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
9466
9481
|
header: headerProp,
|
|
9467
9482
|
color = "light",
|
|
9468
9483
|
items,
|
|
9469
|
-
|
|
9484
|
+
showRail: useRailProp,
|
|
9470
9485
|
value = "",
|
|
9471
9486
|
onValueChange,
|
|
9472
9487
|
onRailChange,
|
|
9473
9488
|
folded: foldedProp,
|
|
9474
|
-
|
|
9489
|
+
onFoldedChange,
|
|
9475
9490
|
onLauncherClick,
|
|
9476
9491
|
logo,
|
|
9477
9492
|
topContent,
|
|
@@ -9494,8 +9509,8 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
9494
9509
|
const layout = react.useContext(SLayoutContext);
|
|
9495
9510
|
const type = typeProp ?? layout?.type ?? "box";
|
|
9496
9511
|
const folded = foldedProp ?? layout?.folded ?? false;
|
|
9497
|
-
const
|
|
9498
|
-
const railHasLeaf =
|
|
9512
|
+
const showRail = useRailProp ?? layout?.showRail ?? false;
|
|
9513
|
+
const railHasLeaf = showRail && items.some((item4) => !item4.children || item4.children.length === 0);
|
|
9499
9514
|
const header = railHasLeaf ? "full" : headerProp ?? layout?.header ?? "fix";
|
|
9500
9515
|
const H = GNB_HEADER[header];
|
|
9501
9516
|
const M = GNB_MENU[type];
|
|
@@ -9603,7 +9618,7 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
9603
9618
|
};
|
|
9604
9619
|
const handleFoldToggle = () => {
|
|
9605
9620
|
const next = !folded;
|
|
9606
|
-
|
|
9621
|
+
onFoldedChange?.(next);
|
|
9607
9622
|
if (foldedProp === void 0) layout?.setFolded(next);
|
|
9608
9623
|
};
|
|
9609
9624
|
const renderRailItem = (item4) => {
|
|
@@ -9762,9 +9777,9 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
9762
9777
|
] }, item4.value)
|
|
9763
9778
|
);
|
|
9764
9779
|
};
|
|
9765
|
-
const railItems =
|
|
9766
|
-
const menuItems =
|
|
9767
|
-
const showMenu = !
|
|
9780
|
+
const railItems = showRail ? items : [];
|
|
9781
|
+
const menuItems = showRail ? items.find((item4) => item4.value === activeRail)?.children ?? [] : items;
|
|
9782
|
+
const showMenu = !showRail || menuItems.length > 0;
|
|
9768
9783
|
const [uncontrolledMenuWidth, setUncontrolledMenuWidth] = react.useState(
|
|
9769
9784
|
() => defaultMenuWidth ?? GNB_MENU_WIDTH
|
|
9770
9785
|
);
|
|
@@ -9772,7 +9787,7 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
9772
9787
|
const committedMenuWidth = menuWidthProp ?? uncontrolledMenuWidth;
|
|
9773
9788
|
const menuWidth = clampGnbMenuWidth(dragMenuWidth ?? committedMenuWidth);
|
|
9774
9789
|
const [resizing, setResizing] = react.useState(false);
|
|
9775
|
-
const bodyWidth = (
|
|
9790
|
+
const bodyWidth = (showRail ? GNB_RAIL_WIDTH : 0) + (showMenu ? menuWidth : 0);
|
|
9776
9791
|
const registerNav = layout?.registerNav;
|
|
9777
9792
|
useIsomorphicLayoutEffect(() => {
|
|
9778
9793
|
if (!registerNav) return;
|
|
@@ -10045,7 +10060,7 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
10045
10060
|
transition: `transform ${GNB_FOLD_MS}ms ease-out, ${hideAfterSlide(folded)}`
|
|
10046
10061
|
},
|
|
10047
10062
|
children: [
|
|
10048
|
-
|
|
10063
|
+
showRail && // 레일 컬럼 — 스크롤되는 아이템 목록(nav)을 가운데 두고 위아래에 고정 슬롯(top/footer)을 붙인다.
|
|
10049
10064
|
// 두 슬롯은 내비게이션이 아니므로 nav(landmark) 밖에 두고, 컬럼 폭·구분선·배경은 이 래퍼가
|
|
10050
10065
|
// 전체 높이에 걸쳐 책임진다(그래야 슬롯 자리까지 배경·오른쪽 선이 이어진다).
|
|
10051
10066
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -10621,12 +10636,26 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
|
|
|
10621
10636
|
}
|
|
10622
10637
|
);
|
|
10623
10638
|
});
|
|
10639
|
+
|
|
10640
|
+
// src/components/SPage/page-width.ts
|
|
10641
|
+
var MIN_CONTENT_WIDTH = `calc(var(${SLAYOUT_MIN_WIDTH_VAR}, 0px) - 100cqw + 100%)`;
|
|
10642
|
+
var SURPLUS = `max(0px, calc(100cqw - var(${SLAYOUT_MIN_WIDTH_VAR}, 0px)))`;
|
|
10643
|
+
var HALF_SURPLUS = `max(0px, calc((100cqw - var(${SLAYOUT_MIN_WIDTH_VAR}, 0px)) / 2))`;
|
|
10644
|
+
var contentWidthStyle = (mode) => {
|
|
10645
|
+
switch (mode) {
|
|
10646
|
+
case "fixed":
|
|
10647
|
+
return { marginRight: SURPLUS };
|
|
10648
|
+
case "fixedCenter":
|
|
10649
|
+
return { marginLeft: HALF_SURPLUS, marginRight: HALF_SURPLUS };
|
|
10650
|
+
default:
|
|
10651
|
+
return void 0;
|
|
10652
|
+
}
|
|
10653
|
+
};
|
|
10624
10654
|
var BACKGROUND_CLASS = {
|
|
10625
10655
|
frame: "bg-[var(--sys-color-bg-frame)]",
|
|
10626
10656
|
neutral: "bg-[var(--sys-color-bg-neutralLight)]",
|
|
10627
10657
|
screen: "bg-[var(--sys-color-bg-screen)]"
|
|
10628
10658
|
};
|
|
10629
|
-
var MIN_CONTENT_WIDTH = `calc(var(${SLAYOUT_MIN_WIDTH_VAR}, 0px) - 100cqw + 100%)`;
|
|
10630
10659
|
var NATIVE_SCROLLBAR_BACKGROUND_CLASS = {
|
|
10631
10660
|
frame: `${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`,
|
|
10632
10661
|
neutral: `${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_WHITE_CLASS}`,
|
|
@@ -10773,6 +10802,7 @@ var SPage = /* @__PURE__ */ react.forwardRef(function SPage2({
|
|
|
10773
10802
|
scrollEndSpacing = false,
|
|
10774
10803
|
overlayScrollbar = false,
|
|
10775
10804
|
contentHeight = "auto",
|
|
10805
|
+
contentWidth = "full",
|
|
10776
10806
|
className,
|
|
10777
10807
|
style,
|
|
10778
10808
|
children,
|
|
@@ -10782,6 +10812,12 @@ var SPage = /* @__PURE__ */ react.forwardRef(function SPage2({
|
|
|
10782
10812
|
const layout = react.useContext(SLayoutContext);
|
|
10783
10813
|
const column = react.useContext(SPageColumnContext);
|
|
10784
10814
|
const gridStyle = layout?.header === "full" && !column ? { gridArea: "page" } : void 0;
|
|
10815
|
+
const setColumnContentWidth = column?.setContentWidth;
|
|
10816
|
+
useIsomorphicLayoutEffect(() => {
|
|
10817
|
+
if (!setColumnContentWidth) return;
|
|
10818
|
+
setColumnContentWidth(contentWidth);
|
|
10819
|
+
return () => setColumnContentWidth("full");
|
|
10820
|
+
}, [setColumnContentWidth, contentWidth]);
|
|
10785
10821
|
const scrollRef = react.useRef(null);
|
|
10786
10822
|
const setMainRef = react.useCallback(
|
|
10787
10823
|
(node) => {
|
|
@@ -10796,6 +10832,7 @@ var SPage = /* @__PURE__ */ react.forwardRef(function SPage2({
|
|
|
10796
10832
|
setColumnScrolled?.(e.currentTarget.scrollTop > 0);
|
|
10797
10833
|
};
|
|
10798
10834
|
const fill = contentHeight === "fill";
|
|
10835
|
+
const fixedWidthStyle = layout ? contentWidthStyle(contentWidth) : void 0;
|
|
10799
10836
|
const main = /* @__PURE__ */ jsxRuntime.jsx(
|
|
10800
10837
|
"main",
|
|
10801
10838
|
{
|
|
@@ -10811,7 +10848,14 @@ var SPage = /* @__PURE__ */ react.forwardRef(function SPage2({
|
|
|
10811
10848
|
style: !overlayScrollbar ? { ...gridStyle, ...style } : style,
|
|
10812
10849
|
onScroll: handleScroll,
|
|
10813
10850
|
...rest,
|
|
10814
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10851
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10852
|
+
"div",
|
|
10853
|
+
{
|
|
10854
|
+
className: cn(fill && "h-full"),
|
|
10855
|
+
style: { minWidth: MIN_CONTENT_WIDTH, ...fixedWidthStyle },
|
|
10856
|
+
children
|
|
10857
|
+
}
|
|
10858
|
+
)
|
|
10815
10859
|
}
|
|
10816
10860
|
);
|
|
10817
10861
|
if (!overlayScrollbar) return main;
|
|
@@ -10834,20 +10878,24 @@ var SPage = /* @__PURE__ */ react.forwardRef(function SPage2({
|
|
|
10834
10878
|
// src/components/SPage/page.config.ts
|
|
10835
10879
|
var PAGE_BACKGROUNDS = ["frame", "neutral", "screen"];
|
|
10836
10880
|
var PAGE_CONTENT_HEIGHTS = ["auto", "fill"];
|
|
10881
|
+
var PAGE_CONTENT_WIDTHS = ["full", "fixed", "fixedCenter"];
|
|
10882
|
+
var PAGE_HEADER_VARIANTS = ["plain", "bar"];
|
|
10837
10883
|
var SPageHeader = /* @__PURE__ */ withDisplayName(
|
|
10838
|
-
react.forwardRef(function SPageHeader2({ title, subText,
|
|
10884
|
+
react.forwardRef(function SPageHeader2({ title, subText, variant, onBack, slot, scrolled, className, style, ...rest }, ref) {
|
|
10839
10885
|
const hasBack = onBack != null;
|
|
10886
|
+
const bar = variant === "bar";
|
|
10840
10887
|
const column = react.useContext(SPageColumnContext);
|
|
10841
10888
|
const isScrolled = scrolled ?? column?.scrolled ?? false;
|
|
10842
|
-
|
|
10889
|
+
const rowStyle = column ? contentWidthStyle(column.contentWidth) : void 0;
|
|
10890
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10843
10891
|
"header",
|
|
10844
10892
|
{
|
|
10845
10893
|
ref,
|
|
10846
10894
|
className: cn(
|
|
10847
|
-
"relative z-10 box-border flex shrink-0 items-center
|
|
10848
|
-
// 배경은 두 베리에이션이 같은 흰 면이다 —
|
|
10895
|
+
"relative z-10 box-border flex shrink-0 items-center px-(--cmp-pageHeader-paddingX)",
|
|
10896
|
+
// 배경은 두 베리에이션이 같은 흰 면이다 — variant 가 가르는 것은 높이·구분선·서브 텍스트 자리다.
|
|
10849
10897
|
// plain 에는 전용 배경 토큰이 없어 시스템 흰 표면을 쓴다(토큰이 생기면 그것으로 갈아끼운다).
|
|
10850
|
-
|
|
10898
|
+
bar ? "h-(--cmp-pageHeader-bar-height) border-b border-(--cmp-pageHeader-bar-border) bg-(--cmp-pageHeader-bar-bg) py-(--cmp-pageHeader-bar-paddingY)" : cn(
|
|
10851
10899
|
// 스크롤되면 그림자를 더해 콘텐츠 위에 뜬 것처럼 보이게 한다.
|
|
10852
10900
|
"bg-(--sys-color-bg-frame) pt-(--cmp-pageHeader-plain-paddingTop) pb-(--cmp-pageHeader-plain-paddingBottom)",
|
|
10853
10901
|
isScrolled && "shadow-floating"
|
|
@@ -10856,33 +10904,40 @@ var SPageHeader = /* @__PURE__ */ withDisplayName(
|
|
|
10856
10904
|
),
|
|
10857
10905
|
style,
|
|
10858
10906
|
...rest,
|
|
10859
|
-
children:
|
|
10860
|
-
|
|
10861
|
-
|
|
10862
|
-
|
|
10863
|
-
|
|
10864
|
-
|
|
10865
|
-
|
|
10866
|
-
|
|
10867
|
-
|
|
10868
|
-
|
|
10869
|
-
|
|
10870
|
-
|
|
10871
|
-
|
|
10872
|
-
|
|
10873
|
-
|
|
10874
|
-
"flex min-w-0 flex-1 items-center",
|
|
10875
|
-
fix ? "flex-row gap-(--cmp-pageHeader-gap)" : "flex-col items-start gap-(--cmp-pageHeader-plain-title-gap)",
|
|
10876
|
-
!hasBack && "pl-(--cmp-pageHeader-title-paddingLeft)"
|
|
10907
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10908
|
+
"div",
|
|
10909
|
+
{
|
|
10910
|
+
className: "flex min-w-0 flex-1 items-center gap-(--cmp-pageHeader-gap)",
|
|
10911
|
+
style: rowStyle,
|
|
10912
|
+
children: [
|
|
10913
|
+
hasBack && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10914
|
+
SGhostButton,
|
|
10915
|
+
{
|
|
10916
|
+
icon: "chevronLeft",
|
|
10917
|
+
size: "xs",
|
|
10918
|
+
ariaLabel: "\uB4A4\uB85C\uAC00\uAE30",
|
|
10919
|
+
onClick: onBack,
|
|
10920
|
+
className: "shrink-0"
|
|
10921
|
+
}
|
|
10877
10922
|
),
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10923
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
10924
|
+
"div",
|
|
10925
|
+
{
|
|
10926
|
+
className: cn(
|
|
10927
|
+
"flex min-w-0 flex-1 items-center",
|
|
10928
|
+
bar ? "flex-row gap-(--cmp-pageHeader-gap)" : "flex-col items-start gap-(--cmp-pageHeader-plain-title-gap)",
|
|
10929
|
+
!hasBack && "pl-(--cmp-pageHeader-title-paddingLeft)"
|
|
10930
|
+
),
|
|
10931
|
+
children: [
|
|
10932
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-heading-lg min-w-0 truncate text-(--cmp-pageHeader-title-text)", children: title }),
|
|
10933
|
+
subText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-md-default min-w-0 truncate text-(--cmp-pageHeader-subtitle-text)", children: subText })
|
|
10934
|
+
]
|
|
10935
|
+
}
|
|
10936
|
+
),
|
|
10937
|
+
slot && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex shrink-0 items-center", children: slot })
|
|
10938
|
+
]
|
|
10939
|
+
}
|
|
10940
|
+
)
|
|
10886
10941
|
}
|
|
10887
10942
|
);
|
|
10888
10943
|
}),
|
|
@@ -10912,13 +10967,13 @@ function STabs({
|
|
|
10912
10967
|
value,
|
|
10913
10968
|
tabs,
|
|
10914
10969
|
onValueChange,
|
|
10915
|
-
|
|
10970
|
+
sub = false,
|
|
10916
10971
|
vertical = false,
|
|
10917
10972
|
className,
|
|
10918
10973
|
style
|
|
10919
10974
|
}) {
|
|
10920
10975
|
const blue = TAB_MAIN_COLORS.selected.border;
|
|
10921
|
-
const isVertical =
|
|
10976
|
+
const isVertical = sub && vertical;
|
|
10922
10977
|
const tabRefs = react.useRef([]);
|
|
10923
10978
|
const moveTo = (target) => {
|
|
10924
10979
|
if (target < 0 || target >= tabs.length) return;
|
|
@@ -10926,7 +10981,7 @@ function STabs({
|
|
|
10926
10981
|
tabRefs.current[target]?.focus();
|
|
10927
10982
|
};
|
|
10928
10983
|
const containerStyle = { ...style };
|
|
10929
|
-
if (!
|
|
10984
|
+
if (!sub) containerStyle.borderBottom = `1px solid ${blue}`;
|
|
10930
10985
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10931
10986
|
"div",
|
|
10932
10987
|
{
|
|
@@ -10934,9 +10989,9 @@ function STabs({
|
|
|
10934
10989
|
"aria-orientation": isVertical ? "vertical" : "horizontal",
|
|
10935
10990
|
className: cn(
|
|
10936
10991
|
// main(가로): baseline(하단 divider)이 100% 너비로 채워지도록 w-full
|
|
10937
|
-
|
|
10992
|
+
sub ? "inline-flex w-fit" : "flex w-full",
|
|
10938
10993
|
isVertical ? "flex-col items-stretch" : "flex-row",
|
|
10939
|
-
|
|
10994
|
+
sub ? isVertical ? "gap-[16px]" : "gap-[24px]" : "gap-[4px]",
|
|
10940
10995
|
className
|
|
10941
10996
|
),
|
|
10942
10997
|
style: containerStyle,
|
|
@@ -10944,7 +10999,7 @@ function STabs({
|
|
|
10944
10999
|
const selected = tab.value === value;
|
|
10945
11000
|
const select = () => onValueChange?.(tab.value);
|
|
10946
11001
|
let tabStyle;
|
|
10947
|
-
if (
|
|
11002
|
+
if (sub) {
|
|
10948
11003
|
tabStyle = {
|
|
10949
11004
|
height: 20,
|
|
10950
11005
|
paddingBottom: 4,
|
|
@@ -12314,6 +12369,7 @@ var ALIGN = {
|
|
|
12314
12369
|
center: "center",
|
|
12315
12370
|
end: "flex-end"
|
|
12316
12371
|
};
|
|
12372
|
+
var FOCUS_RING_SHADOW = "0px 0px 4px 0px #0071ff66";
|
|
12317
12373
|
var cssLen = (v) => v === void 0 || v === "" || v === 0 ? void 0 : typeof v === "number" ? `${v}px` : v;
|
|
12318
12374
|
var SField = /* @__PURE__ */ react.forwardRef(function SField2({
|
|
12319
12375
|
name,
|
|
@@ -12380,7 +12436,11 @@ var SField = /* @__PURE__ */ react.forwardRef(function SField2({
|
|
|
12380
12436
|
const addonWidth = effectiveAddonLabel !== "" ? cssLen(labelWidth) : void 0;
|
|
12381
12437
|
const maxWidthValue = fieldWidthValue(maxWidth);
|
|
12382
12438
|
const resolvedMaxWidth = maxWidthValue === void 0 || effectiveAddonLabel === "" ? maxWidthValue : addonWidth ? `calc(${maxWidthValue} + ${addonWidth})` : void 0;
|
|
12383
|
-
const borderColor = borderless ? "transparent" : disabled ? "var(--color-grey-45)" :
|
|
12439
|
+
const borderColor = borderless ? "transparent" : disabled ? "var(--color-grey-45)" : (
|
|
12440
|
+
// focus·hover(제어 prop) 가 error/pass 보다 우선 — 실제 :hover/:focus-within 클래스도
|
|
12441
|
+
// 같은 순서로 --field-bc 를 덮으므로, prop 으로 흉내 낸 상태도 그와 같게 둔다.
|
|
12442
|
+
interactive && (focused || hovered) ? "var(--sys-color-field-border-focus)" : resolvedSuccess ? "var(--sys-color-field-border-success)" : resolvedError ? "var(--sys-color-field-border-danger)" : "var(--sys-color-field-border-default)"
|
|
12443
|
+
);
|
|
12384
12444
|
const bgColor = borderless ? "transparent" : disabled ? "var(--color-grey-30)" : readOnly ? "var(--sys-color-field-bg-readOnly)" : "var(--sys-color-field-bg-default)";
|
|
12385
12445
|
const textColor = disabled ? "var(--color-grey-65)" : readOnly ? "var(--sys-color-field-text-readOnly)" : "var(--sys-color-field-text-default)";
|
|
12386
12446
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -12458,7 +12518,7 @@ var SField = /* @__PURE__ */ react.forwardRef(function SField2({
|
|
|
12458
12518
|
// @ts-expect-error CSS 변수
|
|
12459
12519
|
"--field-bc": borderColor,
|
|
12460
12520
|
// focused/hovered prop이 명시된 경우 강조를 즉시 반영
|
|
12461
|
-
...interactive && !borderless && focused ? { boxShadow:
|
|
12521
|
+
...interactive && !borderless && (focused || hovered) ? { boxShadow: FOCUS_RING_SHADOW } : {},
|
|
12462
12522
|
...multiline ? { minHeight: s.height } : { height: s.height },
|
|
12463
12523
|
"borderRadius": s.radius,
|
|
12464
12524
|
"background": bgColor,
|
|
@@ -12527,7 +12587,7 @@ var SSearchInput = /* @__PURE__ */ react.forwardRef(function SSearchInput2({
|
|
|
12527
12587
|
width,
|
|
12528
12588
|
focused,
|
|
12529
12589
|
hovered,
|
|
12530
|
-
|
|
12590
|
+
inputClassName,
|
|
12531
12591
|
inputStyle,
|
|
12532
12592
|
className,
|
|
12533
12593
|
style,
|
|
@@ -12588,7 +12648,7 @@ var SSearchInput = /* @__PURE__ */ react.forwardRef(function SSearchInput2({
|
|
|
12588
12648
|
// type="search" 의 브라우저 기본 취소 버튼은 clearable 과 겹치므로 지운다
|
|
12589
12649
|
"h-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--sys-color-field-text-placeholder)] disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:hidden",
|
|
12590
12650
|
AUTOFILL_RESET_CLASS,
|
|
12591
|
-
|
|
12651
|
+
inputClassName
|
|
12592
12652
|
),
|
|
12593
12653
|
style: {
|
|
12594
12654
|
// fontSize/lineHeight 는 컨테이너에서 상속 (원본 font-size: inherit)
|
|
@@ -12663,12 +12723,12 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12663
12723
|
value,
|
|
12664
12724
|
onValueChange,
|
|
12665
12725
|
onOpenChange,
|
|
12666
|
-
|
|
12726
|
+
valueAsPrimitive = false,
|
|
12667
12727
|
name,
|
|
12668
12728
|
options = [],
|
|
12669
12729
|
type = "default",
|
|
12670
|
-
|
|
12671
|
-
|
|
12730
|
+
showSearch = false,
|
|
12731
|
+
showSelectAll = false,
|
|
12672
12732
|
allSelectedLabel = "\uC804\uCCB4",
|
|
12673
12733
|
placeholder = "\uC120\uD0DD",
|
|
12674
12734
|
disabled = false,
|
|
@@ -12708,12 +12768,13 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12708
12768
|
const dismissedByPointerRef = react.useRef(false);
|
|
12709
12769
|
const alignSelectedTopRef = react.useRef(false);
|
|
12710
12770
|
const selectedAnchorRef = react.useRef(-1);
|
|
12771
|
+
const rangeAnchorRef = react.useRef(null);
|
|
12711
12772
|
const flat = react.useMemo(() => flattenOptions(options), [options]);
|
|
12712
12773
|
const selectable = react.useMemo(() => selectableOptions(flat), [flat]);
|
|
12713
12774
|
const hasLeaf = react.useMemo(() => flat.some((o) => !o.isGroup), [flat]);
|
|
12714
12775
|
const allOptionsDisabled = hasLeaf && selectable.length === 0;
|
|
12715
12776
|
const effectiveDisabled = disabled || allOptionsDisabled;
|
|
12716
|
-
const
|
|
12777
|
+
const searchVisible = showSearch && selectable.length >= SEARCH_THRESHOLD;
|
|
12717
12778
|
const labelByValue = react.useMemo(() => new Map(flat.map((o) => [o.value, o.label])), [flat]);
|
|
12718
12779
|
const rawByValue = react.useMemo(() => new Map(flat.map((o) => [o.value, o.raw])), [flat]);
|
|
12719
12780
|
const optionByValue = react.useMemo(
|
|
@@ -12730,9 +12791,9 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12730
12791
|
const emit3 = (next) => {
|
|
12731
12792
|
if (!onValueChange) return;
|
|
12732
12793
|
const mapped = next.map(
|
|
12733
|
-
(v) =>
|
|
12794
|
+
(v) => valueAsPrimitive ? rawByValue.get(v) ?? v : optionByValue.get(v) ?? { value: v, label: v }
|
|
12734
12795
|
);
|
|
12735
|
-
onValueChange(multi ? mapped : mapped[0] ?? (
|
|
12796
|
+
onValueChange(multi ? mapped : mapped[0] ?? (valueAsPrimitive ? "" : null));
|
|
12736
12797
|
};
|
|
12737
12798
|
const commitOpen = (next, valueForRules) => {
|
|
12738
12799
|
setOpen(next);
|
|
@@ -12779,12 +12840,12 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12779
12840
|
resetValidation: () => setRuleError("")
|
|
12780
12841
|
});
|
|
12781
12842
|
const filtered = react.useMemo(() => {
|
|
12782
|
-
if (!
|
|
12843
|
+
if (!searchVisible || search.trim() === "") return flat;
|
|
12783
12844
|
const q = search.trim().toLowerCase();
|
|
12784
12845
|
return flat.filter(
|
|
12785
12846
|
(o) => o.isGroup || (isHtmlLabel(o.label) ? extractText(o.label) : o.label).toLowerCase().includes(q)
|
|
12786
12847
|
);
|
|
12787
|
-
}, [flat, search,
|
|
12848
|
+
}, [flat, search, searchVisible]);
|
|
12788
12849
|
const allValues = selectable.map((o) => o.value);
|
|
12789
12850
|
const allSelected = allValues.length > 0 && allValues.every((v) => selected.includes(v));
|
|
12790
12851
|
const hasItems = filtered.some((o) => !o.isGroup);
|
|
@@ -12797,7 +12858,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12797
12858
|
}, [filtered]);
|
|
12798
12859
|
const navigableItems = react.useMemo(() => {
|
|
12799
12860
|
const items = [];
|
|
12800
|
-
if (multi &&
|
|
12861
|
+
if (multi && showSelectAll && allValues.length > 0) {
|
|
12801
12862
|
items.push({ key: "__select_all__", isSelectAll: true });
|
|
12802
12863
|
}
|
|
12803
12864
|
filtered.forEach((o, i) => {
|
|
@@ -12808,11 +12869,11 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12808
12869
|
if (leafValues.length === 0) return;
|
|
12809
12870
|
items.push({ key: `__group_${i}__`, isGroup: true, leafValues });
|
|
12810
12871
|
} else {
|
|
12811
|
-
items.push({ key: o.value, value: o.value });
|
|
12872
|
+
items.push({ key: o.value, value: o.value, index: i });
|
|
12812
12873
|
}
|
|
12813
12874
|
});
|
|
12814
12875
|
return items;
|
|
12815
|
-
}, [allValues.length, filtered, groupLeafValues, multi,
|
|
12876
|
+
}, [allValues.length, filtered, groupLeafValues, multi, showSelectAll]);
|
|
12816
12877
|
const selectedAnchorIndex = react.useMemo(() => {
|
|
12817
12878
|
if (selected.length === 0) return -1;
|
|
12818
12879
|
const selectedSet = new Set(selected);
|
|
@@ -12833,20 +12894,36 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12833
12894
|
emit3([]);
|
|
12834
12895
|
if (rules && rules.length > 0) setRuleError(runRules(multi ? [] : "", rules));
|
|
12835
12896
|
};
|
|
12836
|
-
const handleSelect = (nextValue) => {
|
|
12897
|
+
const handleSelect = (nextValue, index, extend = false) => {
|
|
12837
12898
|
if (multi) {
|
|
12838
|
-
const
|
|
12839
|
-
|
|
12899
|
+
const anchor = rangeAnchorRef.current;
|
|
12900
|
+
if (extend && anchor != null && anchor !== index && filtered[anchor]?.isGroup === false) {
|
|
12901
|
+
const [from, to] = anchor < index ? [anchor, index] : [index, anchor];
|
|
12902
|
+
const selectedSet = new Set(selected);
|
|
12903
|
+
const shouldSelect = selectedSet.has(filtered[anchor].value);
|
|
12904
|
+
const rangeValues = filtered.slice(from, to + 1).filter((o) => !o.isGroup && !o.disabled).map((o) => o.value);
|
|
12905
|
+
const inRange = new Set(rangeValues);
|
|
12906
|
+
emit3(
|
|
12907
|
+
shouldSelect ? [...selected, ...rangeValues.filter((v) => !selectedSet.has(v))] : selected.filter((v) => !inRange.has(v))
|
|
12908
|
+
);
|
|
12909
|
+
return;
|
|
12910
|
+
}
|
|
12911
|
+
rangeAnchorRef.current = index;
|
|
12912
|
+
emit3(
|
|
12913
|
+
selected.includes(nextValue) ? selected.filter((v) => v !== nextValue) : [...selected, nextValue]
|
|
12914
|
+
);
|
|
12840
12915
|
return;
|
|
12841
12916
|
}
|
|
12842
12917
|
emit3([nextValue]);
|
|
12843
12918
|
commitOpen(false, [nextValue]);
|
|
12844
12919
|
};
|
|
12845
12920
|
const handleSelectAll = () => {
|
|
12921
|
+
rangeAnchorRef.current = null;
|
|
12846
12922
|
emit3(allSelected ? [] : allValues);
|
|
12847
12923
|
};
|
|
12848
12924
|
const handleToggleGroup = (leafValues) => {
|
|
12849
12925
|
if (leafValues.length === 0) return;
|
|
12926
|
+
rangeAnchorRef.current = null;
|
|
12850
12927
|
const selectedSet = new Set(selected);
|
|
12851
12928
|
const allSelectedInGroup = leafValues.every((v) => selectedSet.has(v));
|
|
12852
12929
|
if (allSelectedInGroup) {
|
|
@@ -12864,6 +12941,9 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12864
12941
|
const anchor = alignSelectedTopRef.current ? selectedAnchorRef.current : -1;
|
|
12865
12942
|
setFocusedIndex(anchor >= 0 ? anchor : 0);
|
|
12866
12943
|
}, [open, search, navigableItems.length]);
|
|
12944
|
+
react.useEffect(() => {
|
|
12945
|
+
rangeAnchorRef.current = null;
|
|
12946
|
+
}, [open, search]);
|
|
12867
12947
|
react.useLayoutEffect(() => {
|
|
12868
12948
|
if (!open || focusedIndex < 0 || !listEl) return;
|
|
12869
12949
|
const focusedEl = listEl.querySelector('[data-select-focused="true"]');
|
|
@@ -12891,7 +12971,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12891
12971
|
return current <= 0 ? navigableItems.length - 1 : current - 1;
|
|
12892
12972
|
});
|
|
12893
12973
|
};
|
|
12894
|
-
const selectFocusedItem = () => {
|
|
12974
|
+
const selectFocusedItem = (extend = false) => {
|
|
12895
12975
|
if (focusedIndex < 0 || focusedIndex >= navigableItems.length) return;
|
|
12896
12976
|
const focused = navigableItems[focusedIndex];
|
|
12897
12977
|
if (focused.isSelectAll) {
|
|
@@ -12902,7 +12982,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12902
12982
|
handleToggleGroup(focused.leafValues ?? []);
|
|
12903
12983
|
return;
|
|
12904
12984
|
}
|
|
12905
|
-
handleSelect(focused.value);
|
|
12985
|
+
handleSelect(focused.value, focused.index, extend);
|
|
12906
12986
|
};
|
|
12907
12987
|
const handleKeyDown = (event) => {
|
|
12908
12988
|
if (!open) {
|
|
@@ -12924,7 +13004,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
12924
13004
|
}
|
|
12925
13005
|
if (event.key === "Enter") {
|
|
12926
13006
|
event.preventDefault();
|
|
12927
|
-
selectFocusedItem();
|
|
13007
|
+
selectFocusedItem(event.shiftKey);
|
|
12928
13008
|
return;
|
|
12929
13009
|
}
|
|
12930
13010
|
if (event.key === "Escape") {
|
|
@@ -13040,7 +13120,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
13040
13120
|
viewportPadding: 24,
|
|
13041
13121
|
fit: !dropdownWidth,
|
|
13042
13122
|
onOpenAutoFocus: (event) => {
|
|
13043
|
-
if (!
|
|
13123
|
+
if (!searchVisible) {
|
|
13044
13124
|
event.preventDefault();
|
|
13045
13125
|
return;
|
|
13046
13126
|
}
|
|
@@ -13073,7 +13153,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
13073
13153
|
style: { maxHeight: clampToAvailableHeight(dropdownHeight, POPOVER_AVAILABLE_HEIGHT) },
|
|
13074
13154
|
onMouseLeave: () => setFocusedIndex(-1),
|
|
13075
13155
|
children: [
|
|
13076
|
-
|
|
13156
|
+
searchVisible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
13077
13157
|
"div",
|
|
13078
13158
|
{
|
|
13079
13159
|
ref: searchBarRef,
|
|
@@ -13099,7 +13179,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
13099
13179
|
selected,
|
|
13100
13180
|
groupLeafValues,
|
|
13101
13181
|
focusedValue: navigableItems[focusedIndex]?.key,
|
|
13102
|
-
showSelectAll: multi &&
|
|
13182
|
+
showSelectAll: multi && showSelectAll && allValues.length > 0,
|
|
13103
13183
|
selectAllLabel: allSelectedLabel,
|
|
13104
13184
|
selectAllSelected: allSelected,
|
|
13105
13185
|
onSelectAll: handleSelectAll,
|
|
@@ -13269,7 +13349,7 @@ function ItemList({
|
|
|
13269
13349
|
style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: padLeft },
|
|
13270
13350
|
onMouseEnter: () => onHoverValue(o.value),
|
|
13271
13351
|
onMouseLeave: () => onHoverValue(null),
|
|
13272
|
-
onClick: () => onSelect(o.value),
|
|
13352
|
+
onClick: (event) => onSelect(o.value, idx, event.shiftKey),
|
|
13273
13353
|
children: [
|
|
13274
13354
|
multi && /* @__PURE__ */ jsxRuntime.jsx(
|
|
13275
13355
|
CheckboxBox,
|
|
@@ -13356,19 +13436,19 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13356
13436
|
stickyColumn,
|
|
13357
13437
|
radius = "default",
|
|
13358
13438
|
bordered = true,
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13439
|
+
emptyLabel = "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
13440
|
+
emptySlot,
|
|
13441
|
+
loading: loading2 = false,
|
|
13362
13442
|
dense = false,
|
|
13363
13443
|
onDenseChange,
|
|
13364
|
-
|
|
13444
|
+
hoverable = true,
|
|
13365
13445
|
pagination,
|
|
13366
13446
|
onPageChange,
|
|
13367
|
-
|
|
13368
|
-
|
|
13447
|
+
internalPagination = false,
|
|
13448
|
+
showRowsPerPageSelect = false,
|
|
13369
13449
|
rowsPerPageOption = DEFAULT_ROWS_PER_PAGE_OPTION,
|
|
13370
13450
|
onRowsPerPageChange,
|
|
13371
|
-
|
|
13451
|
+
virtualScroll = false,
|
|
13372
13452
|
rowHeight,
|
|
13373
13453
|
virtualBuffer = 5,
|
|
13374
13454
|
virtualEndThreshold = 10,
|
|
@@ -13449,6 +13529,8 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13449
13529
|
setColumnWidths(visibleCols.map(colWidthFromDef));
|
|
13450
13530
|
}, [colSignature]);
|
|
13451
13531
|
const selectedKeys = react.useMemo(() => new Set(selected.map((r) => r[rowKey])), [selected, rowKey]);
|
|
13532
|
+
const rangeAnchorRef = react.useRef(null);
|
|
13533
|
+
const shiftPressedRef = react.useRef(false);
|
|
13452
13534
|
const isRowSelected = react.useCallback(
|
|
13453
13535
|
(row) => selectedKeys.has(row[rowKey]),
|
|
13454
13536
|
[selectedKeys, rowKey]
|
|
@@ -13507,16 +13589,16 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13507
13589
|
setHeaderGutter(el.offsetWidth - el.clientWidth);
|
|
13508
13590
|
setScrolledLeft(el.scrollLeft > 0);
|
|
13509
13591
|
setScrolledRight(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
|
|
13510
|
-
if (
|
|
13592
|
+
if (virtualScroll) {
|
|
13511
13593
|
const { start, end } = calcRange(el.scrollTop, el.clientHeight);
|
|
13512
13594
|
setVsRange((prev) => prev.start === start && prev.end === end ? prev : { start, end });
|
|
13513
13595
|
}
|
|
13514
|
-
}, [
|
|
13596
|
+
}, [virtualScroll, calcRange]);
|
|
13515
13597
|
react.useEffect(() => {
|
|
13516
13598
|
handleScroll();
|
|
13517
|
-
}, [handleScroll, rowCount, columnWidths,
|
|
13599
|
+
}, [handleScroll, rowCount, columnWidths, loading2, height]);
|
|
13518
13600
|
react.useEffect(() => {
|
|
13519
|
-
if (!
|
|
13601
|
+
if (!virtualScroll) return;
|
|
13520
13602
|
cbRef.current.onVirtualUpdate?.({ from: vsRange.start, to: vsRange.end });
|
|
13521
13603
|
const threshold = Math.max(1, virtualEndThreshold);
|
|
13522
13604
|
if (vsRange.end >= Math.max(0, rowCount - threshold) && lastReachEndRef.current !== rowCount) {
|
|
@@ -13528,7 +13610,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13528
13610
|
threshold
|
|
13529
13611
|
});
|
|
13530
13612
|
}
|
|
13531
|
-
}, [vsRange,
|
|
13613
|
+
}, [vsRange, virtualScroll, rowCount, virtualEndThreshold]);
|
|
13532
13614
|
const getStickyStyle = react.useCallback(
|
|
13533
13615
|
(colIdx) => {
|
|
13534
13616
|
const leftOffset = columnWidths.slice(0, colIdx).reduce((a, b) => a + b, selectable ? SELECTABLE_COLUMN_WIDTH : 0);
|
|
@@ -13553,7 +13635,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13553
13635
|
isRowSelected,
|
|
13554
13636
|
getIsAllChecked,
|
|
13555
13637
|
getPaginationInfo: () => {
|
|
13556
|
-
if (!
|
|
13638
|
+
if (!internalPagination || !pagination) return null;
|
|
13557
13639
|
const startIndex = (currentPage - 1) * innerRowsPerPage;
|
|
13558
13640
|
return {
|
|
13559
13641
|
startIndex,
|
|
@@ -13584,7 +13666,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13584
13666
|
getIsAllChecked,
|
|
13585
13667
|
getStickyStyle,
|
|
13586
13668
|
setRowCount,
|
|
13587
|
-
|
|
13669
|
+
internalPagination,
|
|
13588
13670
|
pagination,
|
|
13589
13671
|
currentPage,
|
|
13590
13672
|
innerRowsPerPage,
|
|
@@ -13623,31 +13705,37 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13623
13705
|
},
|
|
13624
13706
|
[visibleCols]
|
|
13625
13707
|
);
|
|
13626
|
-
const pageInfo =
|
|
13708
|
+
const pageInfo = internalPagination && pagination ? {
|
|
13627
13709
|
startIndex: (currentPage - 1) * innerRowsPerPage,
|
|
13628
13710
|
endIndex: (currentPage - 1) * innerRowsPerPage + innerRowsPerPage
|
|
13629
13711
|
} : null;
|
|
13630
13712
|
let bodyRows = rows;
|
|
13631
13713
|
let topSpacer = 0;
|
|
13632
13714
|
let bottomSpacer = 0;
|
|
13633
|
-
|
|
13715
|
+
let rowOffset = 0;
|
|
13716
|
+
if (virtualScroll) {
|
|
13634
13717
|
bodyRows = rows.slice(vsRange.start, vsRange.end);
|
|
13718
|
+
rowOffset = vsRange.start;
|
|
13635
13719
|
topSpacer = vsRange.start * effectiveRowHeight;
|
|
13636
13720
|
bottomSpacer = Math.max(0, (rowCount - vsRange.end) * effectiveRowHeight);
|
|
13637
13721
|
} else if (pageInfo) {
|
|
13638
13722
|
bodyRows = rows.slice(pageInfo.startIndex, pageInfo.endIndex);
|
|
13723
|
+
rowOffset = pageInfo.startIndex;
|
|
13639
13724
|
}
|
|
13640
|
-
const isNoData = rowCount === 0 && !
|
|
13641
|
-
const showNoDataSlot = isNoData &&
|
|
13642
|
-
const showPagination = !
|
|
13643
|
-
const lastPage =
|
|
13644
|
-
const displayPage =
|
|
13725
|
+
const isNoData = rowCount === 0 && !loading2;
|
|
13726
|
+
const showNoDataSlot = isNoData && emptySlot != null;
|
|
13727
|
+
const showPagination = !virtualScroll && (pagination != null || internalPagination);
|
|
13728
|
+
const lastPage = internalPagination ? Math.max(1, Math.ceil(rowCount / (innerRowsPerPage || 1))) : pagination?.lastPage ?? Math.max(1, Math.ceil(rowCount / (pagination?.rowsPerPage ?? 10)));
|
|
13729
|
+
const displayPage = internalPagination ? currentPage : pagination?.page ?? 1;
|
|
13730
|
+
react.useEffect(() => {
|
|
13731
|
+
rangeAnchorRef.current = null;
|
|
13732
|
+
}, [displayPage]);
|
|
13645
13733
|
const changePage = (p) => {
|
|
13646
|
-
if (
|
|
13734
|
+
if (internalPagination) setCurrentPage(p);
|
|
13647
13735
|
onPageChange?.(p);
|
|
13648
13736
|
};
|
|
13649
13737
|
const changeRowsPerPage = (perPage) => {
|
|
13650
|
-
if (
|
|
13738
|
+
if (internalPagination) {
|
|
13651
13739
|
setInnerRowsPerPage(perPage);
|
|
13652
13740
|
const newLast = Math.max(1, Math.ceil(rowCount / (perPage || 1)));
|
|
13653
13741
|
setCurrentPage((cp) => cp > newLast ? newLast : cp);
|
|
@@ -13656,6 +13744,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13656
13744
|
};
|
|
13657
13745
|
const headerCheck = getIsAllChecked(bodyRows);
|
|
13658
13746
|
const toggleAll = () => {
|
|
13747
|
+
rangeAnchorRef.current = null;
|
|
13659
13748
|
if (headerCheck === true) {
|
|
13660
13749
|
const pageKeys = new Set(bodyRows.map((r) => r[rowKey]));
|
|
13661
13750
|
onSelectedChange?.(selected.filter((r) => !pageKeys.has(r[rowKey])));
|
|
@@ -13664,7 +13753,23 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13664
13753
|
onSelectedChange?.([...selected, ...add]);
|
|
13665
13754
|
}
|
|
13666
13755
|
};
|
|
13667
|
-
const toggleRow = (row) => {
|
|
13756
|
+
const toggleRow = (row, index) => {
|
|
13757
|
+
const anchor = rangeAnchorRef.current;
|
|
13758
|
+
const anchorAlive = anchor != null && anchor.index !== index && rows[anchor.index]?.[rowKey] === anchor.key;
|
|
13759
|
+
if (shiftPressedRef.current && anchor != null && anchorAlive) {
|
|
13760
|
+
const [from, to] = anchor.index < index ? [anchor.index, index] : [index, anchor.index];
|
|
13761
|
+
const shouldSelect = selectedKeys.has(anchor.key);
|
|
13762
|
+
const range = rows.slice(from, to + 1);
|
|
13763
|
+
if (shouldSelect) {
|
|
13764
|
+
const add = range.filter((r) => !selectedKeys.has(r[rowKey]));
|
|
13765
|
+
onSelectedChange?.([...selected, ...add]);
|
|
13766
|
+
} else {
|
|
13767
|
+
const keys = new Set(range.map((r) => r[rowKey]));
|
|
13768
|
+
onSelectedChange?.(selected.filter((r) => !keys.has(r[rowKey])));
|
|
13769
|
+
}
|
|
13770
|
+
return;
|
|
13771
|
+
}
|
|
13772
|
+
rangeAnchorRef.current = { index, key: row[rowKey] };
|
|
13668
13773
|
if (selectedKeys.has(row[rowKey]))
|
|
13669
13774
|
onSelectedChange?.(selected.filter((r) => r[rowKey] !== row[rowKey]));
|
|
13670
13775
|
else onSelectedChange?.([...selected, row]);
|
|
@@ -13771,7 +13876,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13771
13876
|
!height && "min-h-0 grow",
|
|
13772
13877
|
radiusClass,
|
|
13773
13878
|
// 원본 sd-table__scroll-container--loading/--no-data: 로딩·데이터 없음 시 인터랙션 차단
|
|
13774
|
-
(
|
|
13879
|
+
(loading2 || rowCount === 0) && "pointer-events-none"
|
|
13775
13880
|
),
|
|
13776
13881
|
style: {
|
|
13777
13882
|
height,
|
|
@@ -13971,7 +14076,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13971
14076
|
)
|
|
13972
14077
|
}
|
|
13973
14078
|
),
|
|
13974
|
-
showNoDataSlot ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(bodyScrollClass, "pointer-events-auto bg-white"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full min-h-[60px] w-full items-center justify-center", children:
|
|
14079
|
+
showNoDataSlot ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(bodyScrollClass, "pointer-events-auto bg-white"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full min-h-[60px] w-full items-center justify-center", children: emptySlot }) }) : (
|
|
13975
14080
|
/* 바디: 세로 스크롤은 이 컨테이너에만 생긴다 (헤더 제외) */
|
|
13976
14081
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13977
14082
|
"div",
|
|
@@ -13981,7 +14086,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13981
14086
|
className: cn(
|
|
13982
14087
|
bodyScrollClass,
|
|
13983
14088
|
// 원본 sd-table__scroll-container--loading/--no-data: 로딩·데이터 없음 시 스크롤 차단
|
|
13984
|
-
(
|
|
14089
|
+
(loading2 || rowCount === 0) && "overflow-hidden"
|
|
13985
14090
|
),
|
|
13986
14091
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13987
14092
|
"table",
|
|
@@ -13991,7 +14096,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
13991
14096
|
children: [
|
|
13992
14097
|
colgroup,
|
|
13993
14098
|
/* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
|
|
13994
|
-
|
|
14099
|
+
virtualScroll && topSpacer > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { "aria-hidden": true, style: { height: topSpacer }, children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalColSpan, className: "p-0" }) }),
|
|
13995
14100
|
rowCount === 0 ? null : bodyRows.map((row, ri) => {
|
|
13996
14101
|
const isSel = selectedKeys.has(row[rowKey]);
|
|
13997
14102
|
const rowBg = "bg-white";
|
|
@@ -14001,10 +14106,10 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
14001
14106
|
onClick: () => onRowClick?.(row),
|
|
14002
14107
|
className: cn(
|
|
14003
14108
|
"group/table-row",
|
|
14004
|
-
|
|
14109
|
+
hoverable && "hover:bg-[var(--color-grey-05)]",
|
|
14005
14110
|
onRowClick && "cursor-pointer"
|
|
14006
14111
|
),
|
|
14007
|
-
style: { height:
|
|
14112
|
+
style: { height: virtualScroll ? effectiveRowHeight : rowH },
|
|
14008
14113
|
children: [
|
|
14009
14114
|
selectable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
14010
14115
|
"td",
|
|
@@ -14013,7 +14118,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
14013
14118
|
// 원본 .td--selected: 48px 고정폭, 항상 left sticky, 체크박스 중앙정렬
|
|
14014
14119
|
"sticky left-0 z-[2] border-b border-solid border-[color:var(--cmp-table-border-color)] align-middle",
|
|
14015
14120
|
rowBg,
|
|
14016
|
-
|
|
14121
|
+
hoverable && "group-hover/table-row:bg-[var(--color-grey-05)]",
|
|
14017
14122
|
stickyLeft === 0 && scrolledLeft && "shadow-[5px_0_8px_0_rgba(34,34,34,0.1)]"
|
|
14018
14123
|
),
|
|
14019
14124
|
style: {
|
|
@@ -14022,7 +14127,17 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
14022
14127
|
maxWidth: SELECTABLE_COLUMN_WIDTH
|
|
14023
14128
|
},
|
|
14024
14129
|
onClick: (e) => e.stopPropagation(),
|
|
14025
|
-
|
|
14130
|
+
onClickCapture: (e) => {
|
|
14131
|
+
shiftPressedRef.current = e.shiftKey;
|
|
14132
|
+
if (e.shiftKey) window.getSelection()?.removeAllRanges();
|
|
14133
|
+
},
|
|
14134
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex select-none items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
14135
|
+
SCheckbox,
|
|
14136
|
+
{
|
|
14137
|
+
value: isSel,
|
|
14138
|
+
onValueChange: () => toggleRow(row, rowOffset + ri)
|
|
14139
|
+
}
|
|
14140
|
+
) })
|
|
14026
14141
|
}
|
|
14027
14142
|
),
|
|
14028
14143
|
visibleCols.map((col, i) => {
|
|
@@ -14031,7 +14146,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
14031
14146
|
// 셀 배경은 흰색으로 채워 뒤 배경이 비치지 않게 하고, hover 시 행 배경(grey_05)을 따른다.
|
|
14032
14147
|
"overflow-hidden text-ellipsis whitespace-nowrap border-b border-solid border-[color:var(--cmp-table-border-color)] text-[12px] leading-[20px] text-[color:var(--sys-color-fg-primary)]",
|
|
14033
14148
|
rowBg,
|
|
14034
|
-
|
|
14149
|
+
hoverable && "group-hover/table-row:bg-[var(--color-grey-05)]",
|
|
14035
14150
|
stickyShadowClass(i),
|
|
14036
14151
|
typeof col.tdClass === "function" ? col.tdClass(row) : col.tdClass
|
|
14037
14152
|
);
|
|
@@ -14065,7 +14180,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
14065
14180
|
row[rowKey] ?? ri
|
|
14066
14181
|
);
|
|
14067
14182
|
}),
|
|
14068
|
-
|
|
14183
|
+
virtualScroll && bottomSpacer > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { "aria-hidden": true, style: { height: bottomSpacer }, children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalColSpan, className: "p-0" }) })
|
|
14069
14184
|
] })
|
|
14070
14185
|
]
|
|
14071
14186
|
}
|
|
@@ -14081,13 +14196,13 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
14081
14196
|
className: "pointer-events-none absolute left-0 right-0 top-0 z-[31] h-[var(--cmp-table-header-height)] bg-white/60"
|
|
14082
14197
|
}
|
|
14083
14198
|
),
|
|
14084
|
-
!showNoDataSlot && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute bottom-0 left-0 right-0 top-[var(--cmp-table-header-height)] z-[30] flex items-center justify-center bg-white/60 text-[12px] text-[color:var(--color-grey-65)]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-[60px] w-full items-center justify-center", children:
|
|
14199
|
+
!showNoDataSlot && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute bottom-0 left-0 right-0 top-[var(--cmp-table-header-height)] z-[30] flex items-center justify-center bg-white/60 text-[12px] text-[color:var(--color-grey-65)]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-[60px] w-full items-center justify-center", children: emptyLabel }) })
|
|
14085
14200
|
] }),
|
|
14086
|
-
|
|
14201
|
+
loading2 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-white/60", children: /* @__PURE__ */ jsxRuntime.jsx(SCircleProgress, { indeterminate: true }) })
|
|
14087
14202
|
]
|
|
14088
14203
|
}
|
|
14089
14204
|
),
|
|
14090
|
-
(showPagination ||
|
|
14205
|
+
(showPagination || showRowsPerPageSelect) && // 원본 sd-table__pagination: 테이블 하단에 이어붙는 회색 바(높이 48px, margin-top:-1px로 테두리 겹침).
|
|
14091
14206
|
// SPagination은 전체 폭 기준 중앙, rows-per-page SSelect는 우측에 absolute 배치해 중앙 정렬을 유지한다.
|
|
14092
14207
|
// 루트 높이가 확정된 경우(테이블이 남은 영역을 채우는 배치) 페이지네이션 바가
|
|
14093
14208
|
// 눌리지 않도록 shrink-0으로 48px를 보장한다.
|
|
@@ -14103,7 +14218,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
14103
14218
|
),
|
|
14104
14219
|
children: [
|
|
14105
14220
|
showPagination && /* @__PURE__ */ jsxRuntime.jsx(SPagination, { currentPage: displayPage, lastPage, onPageChange: changePage }),
|
|
14106
|
-
|
|
14221
|
+
showRowsPerPageSelect && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute right-[10px] top-1/2 flex -translate-y-1/2 items-center gap-[12px]", children: [
|
|
14107
14222
|
dense && /* @__PURE__ */ jsxRuntime.jsx(
|
|
14108
14223
|
STextLink,
|
|
14109
14224
|
{
|
|
@@ -14120,8 +14235,8 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
14120
14235
|
SSelect2,
|
|
14121
14236
|
{
|
|
14122
14237
|
options: rowsPerPageOption,
|
|
14123
|
-
value:
|
|
14124
|
-
|
|
14238
|
+
value: internalPagination ? innerRowsPerPage : pagination?.rowsPerPage,
|
|
14239
|
+
valueAsPrimitive: true,
|
|
14125
14240
|
onValueChange: (v) => changeRowsPerPage(Number(v)),
|
|
14126
14241
|
width: 128
|
|
14127
14242
|
}
|
|
@@ -14269,7 +14384,7 @@ var SInput = /* @__PURE__ */ react.forwardRef(function SInput2({
|
|
|
14269
14384
|
status,
|
|
14270
14385
|
focused,
|
|
14271
14386
|
hovered,
|
|
14272
|
-
|
|
14387
|
+
inputClassName,
|
|
14273
14388
|
inputStyle,
|
|
14274
14389
|
label,
|
|
14275
14390
|
labelWidth,
|
|
@@ -14369,7 +14484,7 @@ var SInput = /* @__PURE__ */ react.forwardRef(function SInput2({
|
|
|
14369
14484
|
className: cn(
|
|
14370
14485
|
"h-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--sys-color-field-text-placeholder)] disabled:cursor-not-allowed",
|
|
14371
14486
|
AUTOFILL_RESET_CLASS,
|
|
14372
|
-
|
|
14487
|
+
inputClassName
|
|
14373
14488
|
),
|
|
14374
14489
|
style: {
|
|
14375
14490
|
// fontSize/lineHeight 는 컨테이너에서 상속 (원본 font-size: inherit)
|
|
@@ -14426,7 +14541,7 @@ var STextarea = /* @__PURE__ */ react.forwardRef(function STextarea2({
|
|
|
14426
14541
|
status,
|
|
14427
14542
|
focused,
|
|
14428
14543
|
hovered,
|
|
14429
|
-
|
|
14544
|
+
textareaClassName,
|
|
14430
14545
|
textareaStyle,
|
|
14431
14546
|
label,
|
|
14432
14547
|
labelWidth,
|
|
@@ -14506,7 +14621,7 @@ var STextarea = /* @__PURE__ */ react.forwardRef(function STextarea2({
|
|
|
14506
14621
|
className: cn(
|
|
14507
14622
|
"w-full resize-y border-0 bg-transparent outline-none placeholder:text-[color:var(--sys-color-field-text-placeholder)] disabled:cursor-not-allowed",
|
|
14508
14623
|
AUTOFILL_RESET_CLASS,
|
|
14509
|
-
|
|
14624
|
+
textareaClassName
|
|
14510
14625
|
),
|
|
14511
14626
|
style: {
|
|
14512
14627
|
minHeight: 100,
|
|
@@ -14551,8 +14666,8 @@ var formatInputWithCommas = (value) => {
|
|
|
14551
14666
|
const formattedInt = addCommas(intPart === "" ? "0" : intPart);
|
|
14552
14667
|
return `${isNeg ? "-" : ""}${formattedInt}${hasDecimal ? `.${decPart}` : ""}`;
|
|
14553
14668
|
};
|
|
14554
|
-
var getDecimalLimit = (
|
|
14555
|
-
if (!
|
|
14669
|
+
var getDecimalLimit = (allowDecimal, maxDecimalLength) => {
|
|
14670
|
+
if (!allowDecimal || maxDecimalLength === void 0 || !Number.isFinite(maxDecimalLength)) {
|
|
14556
14671
|
return void 0;
|
|
14557
14672
|
}
|
|
14558
14673
|
return Math.max(0, Math.floor(maxDecimalLength));
|
|
@@ -14581,12 +14696,12 @@ var SNumberInput = /* @__PURE__ */ react.forwardRef(function SNumberInput2({
|
|
|
14581
14696
|
min = Number.NEGATIVE_INFINITY,
|
|
14582
14697
|
max = Number.POSITIVE_INFINITY,
|
|
14583
14698
|
step = 1,
|
|
14584
|
-
|
|
14585
|
-
|
|
14699
|
+
showButton = false,
|
|
14700
|
+
allowDecimal = false,
|
|
14586
14701
|
maxDecimalLength,
|
|
14587
14702
|
inputPrefix = "",
|
|
14588
14703
|
inputSuffix = "",
|
|
14589
|
-
|
|
14704
|
+
inputClassName,
|
|
14590
14705
|
inputStyle,
|
|
14591
14706
|
autoFocus,
|
|
14592
14707
|
onFocus,
|
|
@@ -14616,7 +14731,7 @@ var SNumberInput = /* @__PURE__ */ react.forwardRef(function SNumberInput2({
|
|
|
14616
14731
|
}, ref) {
|
|
14617
14732
|
const p = PAD3[size];
|
|
14618
14733
|
const padX = `var(--cmp-numberInput-${size}-paddingX)`;
|
|
14619
|
-
const decimalLimit = getDecimalLimit(
|
|
14734
|
+
const decimalLimit = getDecimalLimit(allowDecimal, maxDecimalLength);
|
|
14620
14735
|
const numValue = applyDecimalLimit(toNumber(value), decimalLimit);
|
|
14621
14736
|
const [display, setDisplay] = react.useState(() => formatWithCommas(numValue));
|
|
14622
14737
|
const [ruleError, setRuleError] = react.useState("");
|
|
@@ -14699,7 +14814,7 @@ var SNumberInput = /* @__PURE__ */ react.forwardRef(function SNumberInput2({
|
|
|
14699
14814
|
setDisplayWithCaret(cleaned, logicalCaret);
|
|
14700
14815
|
return;
|
|
14701
14816
|
}
|
|
14702
|
-
if (!
|
|
14817
|
+
if (!allowDecimal && cleaned.includes(".")) {
|
|
14703
14818
|
resetRejectedInput(target, logicalCaret);
|
|
14704
14819
|
return;
|
|
14705
14820
|
}
|
|
@@ -14787,12 +14902,12 @@ var SNumberInput = /* @__PURE__ */ react.forwardRef(function SNumberInput2({
|
|
|
14787
14902
|
style: {
|
|
14788
14903
|
// 원본 sd-number-input: content gap = padding-x 토큰 (gap 토큰 아님)
|
|
14789
14904
|
gap: `var(--cmp-numberInput-${size}-paddingX)`,
|
|
14790
|
-
padding: `0 ${
|
|
14905
|
+
padding: `0 ${showButton ? padX : `calc(${padX} * 2)`}`,
|
|
14791
14906
|
fontSize: p.fontSize,
|
|
14792
14907
|
lineHeight: `${p.lineHeight}px`
|
|
14793
14908
|
},
|
|
14794
14909
|
children: [
|
|
14795
|
-
|
|
14910
|
+
showButton && stepper("dec"),
|
|
14796
14911
|
inputPrefix !== "" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", style: { color: affixColor }, children: inputPrefix }),
|
|
14797
14912
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
14798
14913
|
"input",
|
|
@@ -14800,7 +14915,7 @@ var SNumberInput = /* @__PURE__ */ react.forwardRef(function SNumberInput2({
|
|
|
14800
14915
|
ref: setRefs2,
|
|
14801
14916
|
name,
|
|
14802
14917
|
type: "text",
|
|
14803
|
-
inputMode:
|
|
14918
|
+
inputMode: allowDecimal ? "decimal" : "numeric",
|
|
14804
14919
|
value: display,
|
|
14805
14920
|
placeholder,
|
|
14806
14921
|
disabled,
|
|
@@ -14831,11 +14946,11 @@ var SNumberInput = /* @__PURE__ */ react.forwardRef(function SNumberInput2({
|
|
|
14831
14946
|
// (h-full 이면 input 내부 텍스트 센터링을 브라우저가 수행해 1px 어긋날 수 있음)
|
|
14832
14947
|
"min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--cmp-numberInput-text-placeholder)] disabled:cursor-not-allowed",
|
|
14833
14948
|
AUTOFILL_RESET_CLASS,
|
|
14834
|
-
|
|
14949
|
+
inputClassName
|
|
14835
14950
|
),
|
|
14836
14951
|
style: {
|
|
14837
14952
|
// fontSize/lineHeight 는 컨테이너에서 상속
|
|
14838
|
-
textAlign:
|
|
14953
|
+
textAlign: showButton ? "center" : "right",
|
|
14839
14954
|
color: disabled ? "var(--cmp-numberInput-text-disabled)" : "var(--cmp-numberInput-text-default)",
|
|
14840
14955
|
...inputStyle
|
|
14841
14956
|
},
|
|
@@ -14845,7 +14960,7 @@ var SNumberInput = /* @__PURE__ */ react.forwardRef(function SNumberInput2({
|
|
|
14845
14960
|
),
|
|
14846
14961
|
valueTooltip.tooltip,
|
|
14847
14962
|
inputSuffix !== "" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", style: { color: affixColor }, children: inputSuffix }),
|
|
14848
|
-
|
|
14963
|
+
showButton && stepper("inc")
|
|
14849
14964
|
]
|
|
14850
14965
|
}
|
|
14851
14966
|
)
|
|
@@ -15683,7 +15798,7 @@ function RangeCalendar({
|
|
|
15683
15798
|
value,
|
|
15684
15799
|
selectable,
|
|
15685
15800
|
maxRange,
|
|
15686
|
-
|
|
15801
|
+
showTimePicker = false,
|
|
15687
15802
|
onSelect,
|
|
15688
15803
|
onPendingStartChange,
|
|
15689
15804
|
onViewChange
|
|
@@ -15702,7 +15817,7 @@ function RangeCalendar({
|
|
|
15702
15817
|
const [eM, setEM] = react.useState(splitDateTime(value?.[1]).minute);
|
|
15703
15818
|
const lastEmitted = react.useRef("");
|
|
15704
15819
|
react.useEffect(() => {
|
|
15705
|
-
if (
|
|
15820
|
+
if (showTimePicker && JSON.stringify(value) === lastEmitted.current) return;
|
|
15706
15821
|
const s = splitDateTime(value?.[0]);
|
|
15707
15822
|
const e = splitDateTime(value?.[1]);
|
|
15708
15823
|
setStart(s.date);
|
|
@@ -15711,7 +15826,7 @@ function RangeCalendar({
|
|
|
15711
15826
|
setSM(s.minute);
|
|
15712
15827
|
setEH(e.hour);
|
|
15713
15828
|
setEM(e.minute);
|
|
15714
|
-
}, [value,
|
|
15829
|
+
}, [value, showTimePicker]);
|
|
15715
15830
|
const setBase = (ny, nm) => {
|
|
15716
15831
|
setY(ny);
|
|
15717
15832
|
setM(nm);
|
|
@@ -15759,7 +15874,7 @@ function RangeCalendar({
|
|
|
15759
15874
|
const pad = (v) => String(Number(v) || 0).padStart(2, "0");
|
|
15760
15875
|
const emit3 = (dateStart, dateEnd, time) => {
|
|
15761
15876
|
const t = time ?? { sH, sM, eH, eM };
|
|
15762
|
-
const range =
|
|
15877
|
+
const range = showTimePicker ? [`${dateStart} ${pad(t.sH)}:${pad(t.sM)}`, `${dateEnd} ${pad(t.eH)}:${pad(t.eM)}`] : [dateStart, dateEnd];
|
|
15763
15878
|
lastEmitted.current = JSON.stringify(range);
|
|
15764
15879
|
onSelect(range);
|
|
15765
15880
|
};
|
|
@@ -15769,7 +15884,7 @@ function RangeCalendar({
|
|
|
15769
15884
|
setStart(d);
|
|
15770
15885
|
setEnd(null);
|
|
15771
15886
|
setHover(null);
|
|
15772
|
-
if (
|
|
15887
|
+
if (showTimePicker) {
|
|
15773
15888
|
setSH("00");
|
|
15774
15889
|
setSM("00");
|
|
15775
15890
|
setEH("23");
|
|
@@ -15780,7 +15895,7 @@ function RangeCalendar({
|
|
|
15780
15895
|
}
|
|
15781
15896
|
setEnd(d);
|
|
15782
15897
|
onPendingStartChange?.(null);
|
|
15783
|
-
emit3(start, d,
|
|
15898
|
+
emit3(start, d, showTimePicker ? { sH, sM, eH: "23", eM: "59" } : void 0);
|
|
15784
15899
|
};
|
|
15785
15900
|
const changeTime = (which, part, raw) => {
|
|
15786
15901
|
const digits = raw.replace(/\D/g, "").slice(0, 2);
|
|
@@ -15951,7 +16066,7 @@ function RangeCalendar({
|
|
|
15951
16066
|
// 높이는 고정이 아니라 하한이다 — 5주/6주 달을 오갈 때의 높이 흔들림만 막으면 되고,
|
|
15952
16067
|
// 창이 좁아 패널이 가로 스크롤될 때는 스크롤바 높이만큼 늘어날 수 있어야 한다.
|
|
15953
16068
|
// (단일 달 SCalendar 도 min-h 를 쓴다)
|
|
15954
|
-
|
|
16069
|
+
showTimePicker ? "h-auto" : "min-h-[364px]"
|
|
15955
16070
|
),
|
|
15956
16071
|
children: [
|
|
15957
16072
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center", children: [
|
|
@@ -15984,7 +16099,7 @@ function RangeCalendar({
|
|
|
15984
16099
|
]
|
|
15985
16100
|
}
|
|
15986
16101
|
),
|
|
15987
|
-
|
|
16102
|
+
showTimePicker && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
15988
16103
|
/* @__PURE__ */ jsxRuntime.jsx(SDivider, {}),
|
|
15989
16104
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-[var(--cmp-datepicker-calendar-time-gap)]", children: [
|
|
15990
16105
|
renderTimeSection("start", start, "\uBD80\uD130"),
|
|
@@ -16003,7 +16118,7 @@ function SDateRangePicker({
|
|
|
16003
16118
|
placeholder = "YYYY-MM-DD ~ YYYY-MM-DD",
|
|
16004
16119
|
selectable,
|
|
16005
16120
|
maxRange,
|
|
16006
|
-
|
|
16121
|
+
showTimePicker = false,
|
|
16007
16122
|
disabled = false,
|
|
16008
16123
|
clearable = false,
|
|
16009
16124
|
width,
|
|
@@ -16071,14 +16186,14 @@ function SDateRangePicker({
|
|
|
16071
16186
|
setPendingStart(null);
|
|
16072
16187
|
onValueChange?.(r);
|
|
16073
16188
|
if (rules && rules.length > 0) setRuleError(runRules(r, rules));
|
|
16074
|
-
if (!
|
|
16189
|
+
if (!showTimePicker) setOpen(false);
|
|
16075
16190
|
};
|
|
16076
16191
|
const clear = () => {
|
|
16077
16192
|
setPendingStart(null);
|
|
16078
16193
|
onValueChange?.(null);
|
|
16079
16194
|
if (rules && rules.length > 0) setRuleError(runRules(null, rules));
|
|
16080
16195
|
};
|
|
16081
|
-
const resolvedPlaceholder =
|
|
16196
|
+
const resolvedPlaceholder = showTimePicker && placeholder === "YYYY-MM-DD ~ YYYY-MM-DD" ? "YYYY-MM-DD HH:mm ~ YYYY-MM-DD HH:mm" : placeholder;
|
|
16082
16197
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
16083
16198
|
SField,
|
|
16084
16199
|
{
|
|
@@ -16192,7 +16307,7 @@ function SDateRangePicker({
|
|
|
16192
16307
|
value: value ?? null,
|
|
16193
16308
|
selectable,
|
|
16194
16309
|
maxRange,
|
|
16195
|
-
|
|
16310
|
+
showTimePicker,
|
|
16196
16311
|
onSelect: select,
|
|
16197
16312
|
onPendingStartChange: setPendingStart,
|
|
16198
16313
|
onViewChange
|
|
@@ -16364,7 +16479,7 @@ function SFilePicker({
|
|
|
16364
16479
|
hovered = false,
|
|
16365
16480
|
inline = false,
|
|
16366
16481
|
multiple = false,
|
|
16367
|
-
|
|
16482
|
+
showMultipleListBox = false,
|
|
16368
16483
|
accept,
|
|
16369
16484
|
maxFileSize,
|
|
16370
16485
|
maxTotalSize,
|
|
@@ -16464,7 +16579,7 @@ function SFilePicker({
|
|
|
16464
16579
|
const iconSize = size === "md" ? 20 : 16;
|
|
16465
16580
|
const gapCls = size === "md" ? "gap-[var(--cmp-filepicker-md-gap)]" : "gap-[var(--cmp-filepicker-sm-gap)]";
|
|
16466
16581
|
const inlinePlaceholder = inline && !disabled && !hasFiles;
|
|
16467
|
-
const showListbox = multiple &&
|
|
16582
|
+
const showListbox = multiple && showMultipleListBox;
|
|
16468
16583
|
const filesArr = multiple ? files : [];
|
|
16469
16584
|
const contentInner = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16470
16585
|
"div",
|
|
@@ -16551,7 +16666,7 @@ function SFilePicker({
|
|
|
16551
16666
|
}
|
|
16552
16667
|
)
|
|
16553
16668
|
] }) : contentInner;
|
|
16554
|
-
const chips = multiple && !
|
|
16669
|
+
const chips = multiple && !showMultipleListBox && filesArr.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-[8px] flex flex-wrap gap-[8px]", children: filesArr.map((f, i) => /* @__PURE__ */ jsxRuntime.jsx(SChip2, { value: f.name, editable: false, onRemove: () => removeChip(i) }, i)) });
|
|
16555
16670
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style, children: [
|
|
16556
16671
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16557
16672
|
SField,
|
|
@@ -16763,7 +16878,7 @@ function SToast({
|
|
|
16763
16878
|
link,
|
|
16764
16879
|
linkLabel,
|
|
16765
16880
|
buttonLabel,
|
|
16766
|
-
|
|
16881
|
+
showClose = false,
|
|
16767
16882
|
type = "default",
|
|
16768
16883
|
onClose,
|
|
16769
16884
|
onButtonClick,
|
|
@@ -16823,7 +16938,7 @@ function SToast({
|
|
|
16823
16938
|
onClick: (e) => onButtonClick?.(e)
|
|
16824
16939
|
}
|
|
16825
16940
|
),
|
|
16826
|
-
|
|
16941
|
+
showClose && /* @__PURE__ */ jsxRuntime.jsx(
|
|
16827
16942
|
SGhostButton,
|
|
16828
16943
|
{
|
|
16829
16944
|
icon: "close",
|
|
@@ -17078,7 +17193,7 @@ var SToastContainer = /* @__PURE__ */ react.forwardRef(
|
|
|
17078
17193
|
);
|
|
17079
17194
|
}
|
|
17080
17195
|
);
|
|
17081
|
-
var SForm = /* @__PURE__ */ react.forwardRef(function SForm2({
|
|
17196
|
+
var SForm = /* @__PURE__ */ react.forwardRef(function SForm2({ formClassName, onSubmit, onValidationError, children, className, style }, ref) {
|
|
17082
17197
|
const formRef = react.useRef(null);
|
|
17083
17198
|
const fieldsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
17084
17199
|
const register = react.useCallback((entry) => {
|
|
@@ -17146,7 +17261,7 @@ var SForm = /* @__PURE__ */ react.forwardRef(function SForm2({ formClass, onSubm
|
|
|
17146
17261
|
{
|
|
17147
17262
|
ref: formRef,
|
|
17148
17263
|
onSubmit: handleSubmit,
|
|
17149
|
-
className: cn(
|
|
17264
|
+
className: cn(formClassName, className),
|
|
17150
17265
|
style,
|
|
17151
17266
|
noValidate: true,
|
|
17152
17267
|
children
|
|
@@ -18995,7 +19110,7 @@ var EditorBody = /* @__PURE__ */ react.forwardRef(function EditorBody2({
|
|
|
18995
19110
|
toolbar,
|
|
18996
19111
|
bubbleMenu,
|
|
18997
19112
|
onImageUpload,
|
|
18998
|
-
|
|
19113
|
+
editorClassName,
|
|
18999
19114
|
editorStyle
|
|
19000
19115
|
}, ref) {
|
|
19001
19116
|
const placeholderRef = react.useRef(placeholder);
|
|
@@ -19079,7 +19194,7 @@ var EditorBody = /* @__PURE__ */ react.forwardRef(function EditorBody2({
|
|
|
19079
19194
|
SCROLLBAR_CLASS,
|
|
19080
19195
|
SEDITOR_CONTENT_CLASS,
|
|
19081
19196
|
disabled && "cursor-not-allowed",
|
|
19082
|
-
|
|
19197
|
+
editorClassName
|
|
19083
19198
|
),
|
|
19084
19199
|
style: { ...editorContentStyle({ minHeight, maxHeight, disabled }), ...editorStyle },
|
|
19085
19200
|
children: /* @__PURE__ */ jsxRuntime.jsx(api.EditorContent, { editor, className: "h-full" })
|
|
@@ -19205,7 +19320,7 @@ var SEditor = /* @__PURE__ */ react.forwardRef(function SEditor2({
|
|
|
19205
19320
|
focused,
|
|
19206
19321
|
hovered,
|
|
19207
19322
|
name,
|
|
19208
|
-
|
|
19323
|
+
editorClassName,
|
|
19209
19324
|
editorStyle,
|
|
19210
19325
|
onFocus,
|
|
19211
19326
|
onBlur,
|
|
@@ -19334,7 +19449,7 @@ var SEditor = /* @__PURE__ */ react.forwardRef(function SEditor2({
|
|
|
19334
19449
|
"div",
|
|
19335
19450
|
{
|
|
19336
19451
|
"aria-busy": true,
|
|
19337
|
-
className: cn("min-w-0 flex-1 overflow-y-auto", SCROLLBAR_CLASS,
|
|
19452
|
+
className: cn("min-w-0 flex-1 overflow-y-auto", SCROLLBAR_CLASS, editorClassName),
|
|
19338
19453
|
style: { ...editorContentStyle({ minHeight, maxHeight, disabled }), ...editorStyle },
|
|
19339
19454
|
children: (value ?? defaultValue ?? "") === "" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--sys-color-field-text-placeholder)" }, children: placeholder })
|
|
19340
19455
|
}
|
|
@@ -19359,7 +19474,7 @@ var SEditor = /* @__PURE__ */ react.forwardRef(function SEditor2({
|
|
|
19359
19474
|
toolbar: resolvedToolbar,
|
|
19360
19475
|
bubbleMenu: resolvedBubbleMenu,
|
|
19361
19476
|
onImageUpload,
|
|
19362
|
-
|
|
19477
|
+
editorClassName,
|
|
19363
19478
|
editorStyle
|
|
19364
19479
|
}
|
|
19365
19480
|
) })
|
|
@@ -19812,23 +19927,23 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
19812
19927
|
}
|
|
19813
19928
|
setOpenKey(key);
|
|
19814
19929
|
};
|
|
19815
|
-
const
|
|
19930
|
+
const valueAsPrimitive = (key, nextValue) => {
|
|
19816
19931
|
const next = { ...values, [key]: nextValue };
|
|
19817
19932
|
onValueChange?.(next);
|
|
19818
19933
|
onFilterChange?.({ key, value: nextValue, values: next });
|
|
19819
19934
|
return next;
|
|
19820
19935
|
};
|
|
19821
19936
|
const emitValueAndSearch = (key, nextValue) => {
|
|
19822
|
-
runSearch(
|
|
19937
|
+
runSearch(valueAsPrimitive(key, nextValue));
|
|
19823
19938
|
};
|
|
19824
19939
|
const clearValue = (key) => {
|
|
19825
19940
|
const field = fields.find((f) => f.key === key);
|
|
19826
19941
|
const def = field ? resolveFieldDefault(field) : void 0;
|
|
19827
|
-
runSearch(
|
|
19942
|
+
runSearch(valueAsPrimitive(key, def !== void 0 ? def : null));
|
|
19828
19943
|
};
|
|
19829
19944
|
const removeField = (key) => {
|
|
19830
19945
|
keywordDraftRef.current = null;
|
|
19831
|
-
const nextValues =
|
|
19946
|
+
const nextValues = valueAsPrimitive(key, null);
|
|
19832
19947
|
dismissedRef.current.add(key);
|
|
19833
19948
|
setInternalActiveKeys((current) => current.filter((activeKey) => activeKey !== key));
|
|
19834
19949
|
if (openKey === key) setOpenKey(null);
|
|
@@ -20068,7 +20183,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
20068
20183
|
icon: "reset",
|
|
20069
20184
|
iconColor: "grey_80",
|
|
20070
20185
|
label: "\uAC80\uC0C9 \uCD08\uAE30\uD654",
|
|
20071
|
-
|
|
20186
|
+
labelClassName: "text-grey-80",
|
|
20072
20187
|
disabled: disabled || !canReset,
|
|
20073
20188
|
onClick: reset,
|
|
20074
20189
|
className: cn(
|
|
@@ -20106,7 +20221,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
20106
20221
|
field: currentOpenField,
|
|
20107
20222
|
value: values[currentOpenField.key],
|
|
20108
20223
|
disabled: disabled || currentOpenField.disabled,
|
|
20109
|
-
onValueChange: (next) =>
|
|
20224
|
+
onValueChange: (next) => valueAsPrimitive(currentOpenField.key, next),
|
|
20110
20225
|
onValueCommit: (next) => emitValueAndSearch(currentOpenField.key, next),
|
|
20111
20226
|
onDraftChange: (text) => {
|
|
20112
20227
|
keywordDraftRef.current = text.trim() === "" ? null : { key: currentOpenField.key, text };
|
|
@@ -20310,7 +20425,7 @@ function EditorPanel({
|
|
|
20310
20425
|
{
|
|
20311
20426
|
size: "sm",
|
|
20312
20427
|
label: allSelected ? "\uC120\uD0DD \uD574\uC81C" : "\uC804\uCCB4 \uC120\uD0DD",
|
|
20313
|
-
|
|
20428
|
+
labelClassName: "font-bold",
|
|
20314
20429
|
disabled,
|
|
20315
20430
|
onClick: toggleSelectAll,
|
|
20316
20431
|
style: { color: "var(--sys-color-fg-secondary)" }
|
|
@@ -20333,7 +20448,7 @@ function EditorPanel({
|
|
|
20333
20448
|
{
|
|
20334
20449
|
size: "sm",
|
|
20335
20450
|
label: "\uAC80\uC0C9",
|
|
20336
|
-
|
|
20451
|
+
labelClassName: "font-bold",
|
|
20337
20452
|
onClick: onClose,
|
|
20338
20453
|
style: { color: CHIPFILTER.chipAppliedValue }
|
|
20339
20454
|
}
|
|
@@ -21067,7 +21182,7 @@ var SChipInput = /* @__PURE__ */ react.forwardRef(function SChipInput2({
|
|
|
21067
21182
|
name,
|
|
21068
21183
|
rules,
|
|
21069
21184
|
error,
|
|
21070
|
-
|
|
21185
|
+
showReset = false,
|
|
21071
21186
|
maxCount,
|
|
21072
21187
|
metaPlacement = "end",
|
|
21073
21188
|
duplicateLabel,
|
|
@@ -21202,7 +21317,7 @@ var SChipInput = /* @__PURE__ */ react.forwardRef(function SChipInput2({
|
|
|
21202
21317
|
commit(values.slice(0, -1));
|
|
21203
21318
|
}
|
|
21204
21319
|
};
|
|
21205
|
-
const showResetLink =
|
|
21320
|
+
const showResetLink = showReset && values.length > 0;
|
|
21206
21321
|
const showMaxCount = maxCount != null;
|
|
21207
21322
|
const showMetaInfo = showResetLink || showMaxCount;
|
|
21208
21323
|
const closeDropdown = () => {
|
|
@@ -21522,7 +21637,7 @@ var SBarcodeInput = /* @__PURE__ */ react.forwardRef(
|
|
|
21522
21637
|
hovered,
|
|
21523
21638
|
prefix,
|
|
21524
21639
|
suffix,
|
|
21525
|
-
|
|
21640
|
+
inputClassName,
|
|
21526
21641
|
inputStyle,
|
|
21527
21642
|
label,
|
|
21528
21643
|
labelWidth,
|
|
@@ -21613,7 +21728,7 @@ var SBarcodeInput = /* @__PURE__ */ react.forwardRef(
|
|
|
21613
21728
|
className: cn(
|
|
21614
21729
|
"h-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--cmp-textinput-text-placeholder)] disabled:cursor-not-allowed",
|
|
21615
21730
|
AUTOFILL_RESET_CLASS,
|
|
21616
|
-
|
|
21731
|
+
inputClassName
|
|
21617
21732
|
),
|
|
21618
21733
|
style: {
|
|
21619
21734
|
fontSize: f.fontSize,
|
|
@@ -21707,7 +21822,7 @@ var TIME_SELECTOR_WIDTH = 136;
|
|
|
21707
21822
|
var MERIDIEM_TIME_SELECTOR_WIDTH = 154;
|
|
21708
21823
|
function TimeSelector({
|
|
21709
21824
|
value,
|
|
21710
|
-
|
|
21825
|
+
showMeridiem,
|
|
21711
21826
|
minuteStep,
|
|
21712
21827
|
onChange
|
|
21713
21828
|
}) {
|
|
@@ -21721,7 +21836,7 @@ function TimeSelector({
|
|
|
21721
21836
|
setMinute(parsed.minute);
|
|
21722
21837
|
}, [parsed.hour, parsed.minute]);
|
|
21723
21838
|
const meridiem = hour >= 12 ? "PM" : "AM";
|
|
21724
|
-
const displayHour =
|
|
21839
|
+
const displayHour = showMeridiem ? hour % 12 === 0 ? 12 : hour % 12 : hour;
|
|
21725
21840
|
const commit = (nextHour, nextMinute) => {
|
|
21726
21841
|
const h = clampTimePart(nextHour, 0, 23);
|
|
21727
21842
|
const m = clampTimePart(nextMinute, 0, 59);
|
|
@@ -21752,8 +21867,8 @@ function TimeSelector({
|
|
|
21752
21867
|
setInputDraft((prev) => ({ ...prev, [part]: String(currentValue).padStart(2, "0") }));
|
|
21753
21868
|
};
|
|
21754
21869
|
const commitHourDraft = (draft) => {
|
|
21755
|
-
const clamped = clampTimePart(Number(draft),
|
|
21756
|
-
const nextHour =
|
|
21870
|
+
const clamped = clampTimePart(Number(draft), showMeridiem ? 1 : 0, showMeridiem ? 12 : 23);
|
|
21871
|
+
const nextHour = showMeridiem ? meridiem === "PM" ? clamped === 12 ? 12 : clamped + 12 : clamped === 12 ? 0 : clamped : clamped;
|
|
21757
21872
|
commit(nextHour, minute);
|
|
21758
21873
|
return clamped;
|
|
21759
21874
|
};
|
|
@@ -21854,7 +21969,7 @@ function TimeSelector({
|
|
|
21854
21969
|
boxShadow: "4px 8px 16px -4px rgba(34,34,34,0.1), 0 0 24px -6px rgba(34,34,34,0.12)"
|
|
21855
21970
|
},
|
|
21856
21971
|
children: [
|
|
21857
|
-
|
|
21972
|
+
showMeridiem && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21858
21973
|
"div",
|
|
21859
21974
|
{
|
|
21860
21975
|
className: "flex items-center justify-center",
|
|
@@ -21881,7 +21996,7 @@ function TimeSelector({
|
|
|
21881
21996
|
}) })
|
|
21882
21997
|
}
|
|
21883
21998
|
),
|
|
21884
|
-
|
|
21999
|
+
showMeridiem && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px w-full bg-[var(--sys-color-divider-default)]" }),
|
|
21885
22000
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
21886
22001
|
"div",
|
|
21887
22002
|
{
|
|
@@ -21922,7 +22037,7 @@ function STimePicker({
|
|
|
21922
22037
|
placeholder = "00:00",
|
|
21923
22038
|
disabled = false,
|
|
21924
22039
|
clearable = false,
|
|
21925
|
-
|
|
22040
|
+
showMeridiem,
|
|
21926
22041
|
minuteStep = 1,
|
|
21927
22042
|
width,
|
|
21928
22043
|
name,
|
|
@@ -21950,8 +22065,8 @@ function STimePicker({
|
|
|
21950
22065
|
const [ruleError, setRuleError] = react.useState("");
|
|
21951
22066
|
const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
|
|
21952
22067
|
const normalized = value ? formatTimeValue(parseTimeValue(value).hour, parseTimeValue(value).minute) : null;
|
|
21953
|
-
const
|
|
21954
|
-
const displayText = formatTimeDisplay(normalized,
|
|
22068
|
+
const effectiveShowMeridiem = showMeridiem ?? type === "midday";
|
|
22069
|
+
const displayText = formatTimeDisplay(normalized, effectiveShowMeridiem ? "midday" : "default");
|
|
21955
22070
|
const hasValue = normalized != null && normalized !== "";
|
|
21956
22071
|
useFormField({
|
|
21957
22072
|
name,
|
|
@@ -21968,7 +22083,7 @@ function STimePicker({
|
|
|
21968
22083
|
if (disabled) return;
|
|
21969
22084
|
if (next) {
|
|
21970
22085
|
const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
|
|
21971
|
-
const selectorWidth =
|
|
22086
|
+
const selectorWidth = effectiveShowMeridiem ? MERIDIEM_TIME_SELECTOR_WIDTH : TIME_SELECTOR_WIDTH;
|
|
21972
22087
|
setPopoverAlignOffset(Math.max(0, (triggerWidth - selectorWidth) / 2));
|
|
21973
22088
|
}
|
|
21974
22089
|
setOpen(next);
|
|
@@ -22078,7 +22193,7 @@ function STimePicker({
|
|
|
22078
22193
|
TimeSelector,
|
|
22079
22194
|
{
|
|
22080
22195
|
value: normalized,
|
|
22081
|
-
|
|
22196
|
+
showMeridiem: effectiveShowMeridiem,
|
|
22082
22197
|
minuteStep,
|
|
22083
22198
|
onChange: commitValue
|
|
22084
22199
|
}
|
|
@@ -22121,7 +22236,7 @@ var MIDDAY_FIELD_MAX_WIDTH = {
|
|
|
22121
22236
|
};
|
|
22122
22237
|
function RangeTimeSelector({
|
|
22123
22238
|
value,
|
|
22124
|
-
|
|
22239
|
+
showMeridiem,
|
|
22125
22240
|
minuteStep,
|
|
22126
22241
|
rangeOrder,
|
|
22127
22242
|
onChange
|
|
@@ -22134,7 +22249,7 @@ function RangeTimeSelector({
|
|
|
22134
22249
|
const getMeridiem = (side) => getParts(side).hour >= 12 ? "PM" : "AM";
|
|
22135
22250
|
const getDisplayHour = (side) => {
|
|
22136
22251
|
const { hour } = getParts(side);
|
|
22137
|
-
if (!
|
|
22252
|
+
if (!showMeridiem) return hour;
|
|
22138
22253
|
const displayHour = hour % 12;
|
|
22139
22254
|
return displayHour === 0 ? 12 : displayHour;
|
|
22140
22255
|
};
|
|
@@ -22197,10 +22312,10 @@ function RangeTimeSelector({
|
|
|
22197
22312
|
setInputDraft((prev) => ({ ...prev, [key]: String(currentValue).padStart(2, "0") }));
|
|
22198
22313
|
};
|
|
22199
22314
|
const commitHourDraft = (side, draft) => {
|
|
22200
|
-
const clamped = clampTimePart(Number(draft),
|
|
22315
|
+
const clamped = clampTimePart(Number(draft), showMeridiem ? 1 : 0, showMeridiem ? 12 : 23);
|
|
22201
22316
|
const parts = getParts(side);
|
|
22202
22317
|
const meridiem = getMeridiem(side);
|
|
22203
|
-
const nextHour =
|
|
22318
|
+
const nextHour = showMeridiem ? meridiem === "PM" ? clamped === 12 ? 12 : clamped + 12 : clamped === 12 ? 0 : clamped : clamped;
|
|
22204
22319
|
commit(side, nextHour, parts.minute);
|
|
22205
22320
|
return clamped;
|
|
22206
22321
|
};
|
|
@@ -22308,7 +22423,7 @@ function RangeTimeSelector({
|
|
|
22308
22423
|
style: { gap: "var(--cmp-timepicker-selector-range-heading-gap)" },
|
|
22309
22424
|
children: [
|
|
22310
22425
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-nowrap text-center text-[12px] font-bold leading-[20px] text-[var(--cmp-timepicker-selector-range-heading-color)]", children: title }),
|
|
22311
|
-
|
|
22426
|
+
showMeridiem && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "isolate flex", children: ["AM", "PM"].map((item4, index) => {
|
|
22312
22427
|
const selected = item4 === getMeridiem(side);
|
|
22313
22428
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22314
22429
|
"button",
|
|
@@ -22386,7 +22501,7 @@ function STimeRangePicker({
|
|
|
22386
22501
|
placeholder = "00:00 ~ 23:59",
|
|
22387
22502
|
disabled = false,
|
|
22388
22503
|
clearable = false,
|
|
22389
|
-
|
|
22504
|
+
showMeridiem,
|
|
22390
22505
|
minuteStep = 1,
|
|
22391
22506
|
rangeOrder = "strict",
|
|
22392
22507
|
width,
|
|
@@ -22415,10 +22530,10 @@ function STimeRangePicker({
|
|
|
22415
22530
|
const [ruleError, setRuleError] = react.useState("");
|
|
22416
22531
|
const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
|
|
22417
22532
|
const normalized = normalizeTimeRangeValue(value ?? null, rangeOrder);
|
|
22418
|
-
const
|
|
22533
|
+
const effectiveShowMeridiem = showMeridiem ?? type === "midday";
|
|
22419
22534
|
const displayText = formatTimeRangeDisplay(
|
|
22420
22535
|
normalized,
|
|
22421
|
-
|
|
22536
|
+
effectiveShowMeridiem ? "midday" : "default"
|
|
22422
22537
|
);
|
|
22423
22538
|
const hasValue = normalized != null && normalized[0] !== "" && normalized[1] !== "";
|
|
22424
22539
|
useFormField({
|
|
@@ -22464,8 +22579,8 @@ function STimeRangePicker({
|
|
|
22464
22579
|
focused: focused || open,
|
|
22465
22580
|
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
22466
22581
|
width,
|
|
22467
|
-
minWidth:
|
|
22468
|
-
maxWidth:
|
|
22582
|
+
minWidth: effectiveShowMeridiem ? MIDDAY_FIELD_MIN_WIDTH[size] : dims.fieldMinWidth,
|
|
22583
|
+
maxWidth: effectiveShowMeridiem ? MIDDAY_FIELD_MAX_WIDTH[size] : dims.fieldMaxWidth,
|
|
22469
22584
|
disabled,
|
|
22470
22585
|
className,
|
|
22471
22586
|
style,
|
|
@@ -22545,7 +22660,7 @@ function STimeRangePicker({
|
|
|
22545
22660
|
RangeTimeSelector,
|
|
22546
22661
|
{
|
|
22547
22662
|
value: normalized,
|
|
22548
|
-
|
|
22663
|
+
showMeridiem: effectiveShowMeridiem,
|
|
22549
22664
|
minuteStep,
|
|
22550
22665
|
rangeOrder,
|
|
22551
22666
|
onChange: commitValue
|
|
@@ -22591,6 +22706,8 @@ exports.ICONS = ICONS;
|
|
|
22591
22706
|
exports.IMAGE_FITS = IMAGE_FITS;
|
|
22592
22707
|
exports.PAGE_BACKGROUNDS = PAGE_BACKGROUNDS;
|
|
22593
22708
|
exports.PAGE_CONTENT_HEIGHTS = PAGE_CONTENT_HEIGHTS;
|
|
22709
|
+
exports.PAGE_CONTENT_WIDTHS = PAGE_CONTENT_WIDTHS;
|
|
22710
|
+
exports.PAGE_HEADER_VARIANTS = PAGE_HEADER_VARIANTS;
|
|
22594
22711
|
exports.RangeCalendar = RangeCalendar;
|
|
22595
22712
|
exports.SAccountListBox = SAccountListBox;
|
|
22596
22713
|
exports.SActionModal = SActionModal;
|