sellmate-design-system-react 9.0.0-beta.17 → 9.0.0-beta.19
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 +70 -0
- package/README.md +5 -0
- package/dist/components/SChipFilter/README.md +14 -5
- package/dist/components/SChipFilter/SChipFilter.d.ts +10 -3
- package/dist/components/SChipFilter/index.d.ts +1 -1
- package/dist/components/SDatePicker/README.md +5 -1
- package/dist/components/SDatePicker/SDatePicker.d.ts +20 -3
- package/dist/components/SDateRangePicker/README.md +2 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +9 -2
- package/dist/components/SDivider/README.md +2 -0
- package/dist/components/SDraggableItem/README.md +1 -0
- package/dist/components/SDraggableItem/SDraggableItem.d.ts +2 -0
- package/dist/components/SDraggableList/README.md +5 -0
- package/dist/components/SDraggableList/SDraggableList.d.ts +10 -0
- package/dist/components/SDraggableList/index.d.ts +1 -1
- package/dist/components/SGhostButton/README.md +2 -0
- package/dist/components/SIcon/SIcon.d.ts +1 -1
- package/dist/components/SIcon/icons.gen.d.ts +2 -0
- package/dist/components/STable/README.md +7 -1
- package/dist/components/STable/STable.d.ts +39 -5
- package/dist/components/STextLink/README.md +3 -0
- package/dist/components/STextLink/STextLink.d.ts +2 -0
- package/dist/index.cjs +463 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +463 -89
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +105 -7
- package/dist/llms.txt +70 -0
- package/dist/styles.css +16 -0
- package/eslint/lib/table-column.mjs +12 -3
- package/eslint/rules/table-column-width.mjs +3 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1203,6 +1203,45 @@ var Icon_close = (p) => {
|
|
|
1203
1203
|
}
|
|
1204
1204
|
);
|
|
1205
1205
|
};
|
|
1206
|
+
var Icon_company = (p) => {
|
|
1207
|
+
const { size = 24, ...rest } = p;
|
|
1208
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1209
|
+
"svg",
|
|
1210
|
+
{
|
|
1211
|
+
width: size,
|
|
1212
|
+
height: size,
|
|
1213
|
+
viewBox: "0 0 24 24",
|
|
1214
|
+
fill: "none",
|
|
1215
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1216
|
+
...rest,
|
|
1217
|
+
children: [
|
|
1218
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1219
|
+
"path",
|
|
1220
|
+
{
|
|
1221
|
+
d: "M14.25 8.5C14.6642 8.5 15 8.83579 15 9.25C15 9.66421 14.6642 10 14.25 10H9.75C9.33579 10 9 9.66421 9 9.25C9 8.83579 9.33579 8.5 9.75 8.5H14.25Z",
|
|
1222
|
+
fill: "currentColor"
|
|
1223
|
+
}
|
|
1224
|
+
),
|
|
1225
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1226
|
+
"path",
|
|
1227
|
+
{
|
|
1228
|
+
d: "M14.25 5.5C14.6642 5.5 15 5.83579 15 6.25C15 6.66421 14.6642 7 14.25 7H9.75C9.33579 7 9 6.66421 9 6.25C9 5.83579 9.33579 5.5 9.75 5.5H14.25Z",
|
|
1229
|
+
fill: "currentColor"
|
|
1230
|
+
}
|
|
1231
|
+
),
|
|
1232
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1233
|
+
"path",
|
|
1234
|
+
{
|
|
1235
|
+
fillRule: "evenodd",
|
|
1236
|
+
clipRule: "evenodd",
|
|
1237
|
+
d: "M16 2.25C16.9665 2.25 17.75 3.0335 17.75 4V6.25H20.25C21.2165 6.25 22 7.0335 22 8V20C22 20.9665 21.2165 21.75 20.25 21.75H3.75C2.7835 21.75 2 20.9665 2 20V10C2 9.0335 2.7835 8.25 3.75 8.25H6.25V4C6.25 3.0335 7.0335 2.25 8 2.25H16ZM3.75 9.75C3.61193 9.75 3.5 9.86193 3.5 10V20C3.5 20.1381 3.61193 20.25 3.75 20.25H6.25V9.75H3.75ZM8 3.75C7.86193 3.75 7.75 3.86193 7.75 4V20.25H9.25V16C9.25 15.0335 10.0335 14.25 11 14.25H13C13.9665 14.25 14.75 15.0335 14.75 16V20.25H16.25V4C16.25 3.86193 16.1381 3.75 16 3.75H8ZM11 15.75C10.8619 15.75 10.75 15.8619 10.75 16V20.25H13.25V16C13.25 15.8619 13.1381 15.75 13 15.75H11ZM17.75 20.25H20.25C20.3881 20.25 20.5 20.1381 20.5 20V8C20.5 7.86193 20.3881 7.75 20.25 7.75H17.75V20.25Z",
|
|
1238
|
+
fill: "currentColor"
|
|
1239
|
+
}
|
|
1240
|
+
)
|
|
1241
|
+
]
|
|
1242
|
+
}
|
|
1243
|
+
);
|
|
1244
|
+
};
|
|
1206
1245
|
var Icon_copy = (p) => {
|
|
1207
1246
|
const { size = 24, ...rest } = p;
|
|
1208
1247
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2426,6 +2465,27 @@ var Icon_row = (p) => {
|
|
|
2426
2465
|
}
|
|
2427
2466
|
);
|
|
2428
2467
|
};
|
|
2468
|
+
var Icon_rowDense = (p) => {
|
|
2469
|
+
const { size = 24, ...rest } = p;
|
|
2470
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2471
|
+
"svg",
|
|
2472
|
+
{
|
|
2473
|
+
width: size,
|
|
2474
|
+
height: size,
|
|
2475
|
+
viewBox: "0 0 24 24",
|
|
2476
|
+
fill: "none",
|
|
2477
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2478
|
+
...rest,
|
|
2479
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2480
|
+
"path",
|
|
2481
|
+
{
|
|
2482
|
+
d: "M7.25 2C7.66421 2 8 2.33579 8 2.75V21.25C8 21.6642 7.66421 22 7.25 22H5.75C5.33579 22 5 21.6642 5 21.25V2.75C5 2.33579 5.33579 2 5.75 2H7.25ZM12.75 2C13.1642 2 13.5 2.33579 13.5 2.75V21.25C13.5 21.6642 13.1642 22 12.75 22H11.25C10.8358 22 10.5 21.6642 10.5 21.25V2.75C10.5 2.33579 10.8358 2 11.25 2H12.75ZM18.25 2C18.6642 2 19 2.33579 19 2.75V21.25C19 21.6642 18.6642 22 18.25 22H16.75C16.3358 22 16 21.6642 16 21.25V2.75C16 2.33579 16.3358 2 16.75 2H18.25Z",
|
|
2483
|
+
fill: "currentColor"
|
|
2484
|
+
}
|
|
2485
|
+
)
|
|
2486
|
+
}
|
|
2487
|
+
);
|
|
2488
|
+
};
|
|
2429
2489
|
var Icon_save = (p) => {
|
|
2430
2490
|
const { size = 24, ...rest } = p;
|
|
2431
2491
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3074,6 +3134,7 @@ var ICONS = {
|
|
|
3074
3134
|
clockFill: Icon_clockFill,
|
|
3075
3135
|
clockOutline: Icon_clockOutline,
|
|
3076
3136
|
close: Icon_close,
|
|
3137
|
+
company: Icon_company,
|
|
3077
3138
|
copy: Icon_copy,
|
|
3078
3139
|
coupon: Icon_coupon,
|
|
3079
3140
|
dashboard: Icon_dashboard,
|
|
@@ -3111,6 +3172,7 @@ var ICONS = {
|
|
|
3111
3172
|
reset: Icon_reset,
|
|
3112
3173
|
robot: Icon_robot,
|
|
3113
3174
|
row: Icon_row,
|
|
3175
|
+
rowDense: Icon_rowDense,
|
|
3114
3176
|
save: Icon_save,
|
|
3115
3177
|
search: Icon_search,
|
|
3116
3178
|
send: Icon_send,
|
|
@@ -3429,6 +3491,7 @@ var SDraggableItemView = /* @__PURE__ */ react.forwardRef(
|
|
|
3429
3491
|
supportingText,
|
|
3430
3492
|
supportingTextPosition,
|
|
3431
3493
|
trailing,
|
|
3494
|
+
depth,
|
|
3432
3495
|
accentStripe,
|
|
3433
3496
|
bordered,
|
|
3434
3497
|
selected,
|
|
@@ -3440,6 +3503,7 @@ var SDraggableItemView = /* @__PURE__ */ react.forwardRef(
|
|
|
3440
3503
|
dragHandleProps,
|
|
3441
3504
|
onDragHandleMouseDown,
|
|
3442
3505
|
className,
|
|
3506
|
+
style,
|
|
3443
3507
|
...rest
|
|
3444
3508
|
}, ref) {
|
|
3445
3509
|
const renderState = { hovered, dragging, disabled };
|
|
@@ -3449,12 +3513,19 @@ var SDraggableItemView = /* @__PURE__ */ react.forwardRef(
|
|
|
3449
3513
|
const trailingNode = renderSlot(trailing, renderState);
|
|
3450
3514
|
const titleTypo = size === "sm" ? selected ? "typo-item-sm-selected" : "typo-item-sm-default" : selected ? "typo-item-md-selected" : "typo-item-md-default";
|
|
3451
3515
|
const paddingYClass = dense ? size === "sm" ? "py-(--cmp-listDraggableItem-paddingY-sm-dense)" : "py-(--cmp-listDraggableItem-paddingY-md-dense)" : size === "sm" ? "py-(--cmp-listDraggableItem-paddingY-sm-normal)" : "py-(--cmp-listDraggableItem-paddingY-md-normal)";
|
|
3516
|
+
const normalizedDepth = Math.max(1, Math.floor(depth));
|
|
3517
|
+
const depthOffset = (normalizedDepth - 1) * 20;
|
|
3518
|
+
const depthStyle = depthOffset === 0 ? style : {
|
|
3519
|
+
...style,
|
|
3520
|
+
paddingLeft: `calc(var(--cmp-listDraggableItem-paddingX) + ${depthOffset}px)`
|
|
3521
|
+
};
|
|
3452
3522
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3453
3523
|
"div",
|
|
3454
3524
|
{
|
|
3455
3525
|
ref,
|
|
3456
3526
|
"aria-disabled": disabled || void 0,
|
|
3457
3527
|
"data-dragging": dragging || void 0,
|
|
3528
|
+
style: depthStyle,
|
|
3458
3529
|
className: cn(
|
|
3459
3530
|
"relative flex w-full items-center gap-(--cmp-listDraggableItem-gap) overflow-hidden px-(--cmp-listDraggableItem-paddingX)",
|
|
3460
3531
|
titleTypo,
|
|
@@ -3543,6 +3614,7 @@ var SDraggableItemImpl = /* @__PURE__ */ react.forwardRef(function SDraggableIte
|
|
|
3543
3614
|
supportingText,
|
|
3544
3615
|
supportingTextPosition = "right",
|
|
3545
3616
|
trailing,
|
|
3617
|
+
depth = 1,
|
|
3546
3618
|
accentStripe = false,
|
|
3547
3619
|
bordered = false,
|
|
3548
3620
|
selected = false,
|
|
@@ -3616,6 +3688,7 @@ var SDraggableItemImpl = /* @__PURE__ */ react.forwardRef(function SDraggableIte
|
|
|
3616
3688
|
supportingText,
|
|
3617
3689
|
supportingTextPosition,
|
|
3618
3690
|
trailing,
|
|
3691
|
+
depth,
|
|
3619
3692
|
accentStripe,
|
|
3620
3693
|
bordered,
|
|
3621
3694
|
selected,
|
|
@@ -3651,6 +3724,7 @@ var SDraggableItemImpl = /* @__PURE__ */ react.forwardRef(function SDraggableIte
|
|
|
3651
3724
|
supportingText,
|
|
3652
3725
|
supportingTextPosition,
|
|
3653
3726
|
trailing,
|
|
3727
|
+
depth,
|
|
3654
3728
|
accentStripe,
|
|
3655
3729
|
bordered,
|
|
3656
3730
|
selected,
|
|
@@ -3900,6 +3974,42 @@ function reorder(items, fromIndex, toIndex) {
|
|
|
3900
3974
|
nextItems.splice(toIndex, 0, movedItem);
|
|
3901
3975
|
return nextItems;
|
|
3902
3976
|
}
|
|
3977
|
+
function clampDepth(depth, maxDepth) {
|
|
3978
|
+
return Math.max(1, Math.min(maxDepth, Math.floor(depth)));
|
|
3979
|
+
}
|
|
3980
|
+
function getSubtreeEnd(items, startIndex, getDepth) {
|
|
3981
|
+
const startDepth = getDepth(items[startIndex], startIndex);
|
|
3982
|
+
let endIndex = startIndex + 1;
|
|
3983
|
+
while (endIndex < items.length && getDepth(items[endIndex], endIndex) > startDepth) {
|
|
3984
|
+
endIndex += 1;
|
|
3985
|
+
}
|
|
3986
|
+
return endIndex;
|
|
3987
|
+
}
|
|
3988
|
+
function getInsertionIndex(items, target, getDepth) {
|
|
3989
|
+
if (target.intent === "before") return target.index;
|
|
3990
|
+
if (target.intent === "inside") return target.index + 1;
|
|
3991
|
+
return getSubtreeEnd(items, target.index, getDepth);
|
|
3992
|
+
}
|
|
3993
|
+
function moveWithDepth(items, fromIndex, target, getDepth, setDepth, maxDepth) {
|
|
3994
|
+
const fromEndIndex = getSubtreeEnd(items, fromIndex, getDepth);
|
|
3995
|
+
if (target.index >= fromIndex && target.index < fromEndIndex) return items;
|
|
3996
|
+
const movedItems = items.slice(fromIndex, fromEndIndex);
|
|
3997
|
+
const remainingItems = [...items.slice(0, fromIndex), ...items.slice(fromEndIndex)];
|
|
3998
|
+
const rawInsertionIndex = getInsertionIndex(items, target, getDepth);
|
|
3999
|
+
const insertionIndex = rawInsertionIndex > fromIndex ? rawInsertionIndex - movedItems.length : rawInsertionIndex;
|
|
4000
|
+
const sourceDepth = getDepth(items[fromIndex], fromIndex);
|
|
4001
|
+
const targetDepth = getDepth(items[target.index], target.index);
|
|
4002
|
+
const nextDepth = target.intent === "inside" ? targetDepth + 1 : targetDepth;
|
|
4003
|
+
const depthDelta = clampDepth(nextDepth, maxDepth) - sourceDepth;
|
|
4004
|
+
const nextMovedItems = setDepth && depthDelta !== 0 ? movedItems.map(
|
|
4005
|
+
(item, index) => setDepth(item, clampDepth(getDepth(item, fromIndex + index) + depthDelta, maxDepth))
|
|
4006
|
+
) : movedItems;
|
|
4007
|
+
return [
|
|
4008
|
+
...remainingItems.slice(0, insertionIndex),
|
|
4009
|
+
...nextMovedItems,
|
|
4010
|
+
...remainingItems.slice(insertionIndex)
|
|
4011
|
+
];
|
|
4012
|
+
}
|
|
3903
4013
|
function SDraggableListInner({
|
|
3904
4014
|
items,
|
|
3905
4015
|
getKey,
|
|
@@ -3909,6 +4019,10 @@ function SDraggableListInner({
|
|
|
3909
4019
|
defaultSelectedKey,
|
|
3910
4020
|
onSelectedKeyChange,
|
|
3911
4021
|
getDisabled,
|
|
4022
|
+
getDepth,
|
|
4023
|
+
setDepth,
|
|
4024
|
+
getCanHaveChildren,
|
|
4025
|
+
maxDepth = 3,
|
|
3912
4026
|
listId,
|
|
3913
4027
|
group: groupName,
|
|
3914
4028
|
useGap,
|
|
@@ -3918,19 +4032,24 @@ function SDraggableListInner({
|
|
|
3918
4032
|
const dragContext = useSDraggableGroup();
|
|
3919
4033
|
const dragGroup = groupName ?? dragContext?.defaultGroup;
|
|
3920
4034
|
const [draggingIndex, setDraggingIndex] = react.useState(null);
|
|
3921
|
-
const [
|
|
4035
|
+
const [dropTarget, setDropTarget] = react.useState(null);
|
|
3922
4036
|
const [internalSelectedKey, setInternalSelectedKey] = react.useState(
|
|
3923
4037
|
defaultSelectedKey
|
|
3924
4038
|
);
|
|
3925
4039
|
const listRef = react.useRef(null);
|
|
3926
4040
|
const fromIndexRef = react.useRef(null);
|
|
3927
4041
|
const currentSelectedKey = selectedKey ?? internalSelectedKey;
|
|
4042
|
+
const usesDepth = getDepth != null;
|
|
3928
4043
|
const startDrag = react.useCallback((event, index) => {
|
|
3929
4044
|
event.preventDefault();
|
|
3930
4045
|
fromIndexRef.current = index;
|
|
3931
4046
|
setDraggingIndex(index);
|
|
3932
|
-
|
|
4047
|
+
setDropTarget({ index, intent: "before" });
|
|
3933
4048
|
}, []);
|
|
4049
|
+
const readDepth = react.useCallback(
|
|
4050
|
+
(item, index) => clampDepth(getDepth?.(item, index) ?? 1, maxDepth),
|
|
4051
|
+
[getDepth, maxDepth]
|
|
4052
|
+
);
|
|
3934
4053
|
react.useEffect(() => {
|
|
3935
4054
|
if (dragContext || draggingIndex == null) return void 0;
|
|
3936
4055
|
const handleMouseMove = (event) => {
|
|
@@ -3938,25 +4057,65 @@ function SDraggableListInner({
|
|
|
3938
4057
|
"[data-draggable-list-item]"
|
|
3939
4058
|
);
|
|
3940
4059
|
if (!itemElements) return;
|
|
3941
|
-
let
|
|
3942
|
-
|
|
4060
|
+
let nextDropTarget = items.length === 0 ? { index: 0, intent: "before" } : { index: items.length - 1, intent: "after" };
|
|
4061
|
+
const draggingEndIndex = usesDepth && draggingIndex != null ? getSubtreeEnd(items, draggingIndex, readDepth) : draggingIndex + 1;
|
|
4062
|
+
let previousDropIndex = null;
|
|
4063
|
+
for (let index = 0; index < itemElements.length; index += 1) {
|
|
4064
|
+
const itemElement = itemElements[index];
|
|
3943
4065
|
const rect = itemElement.getBoundingClientRect();
|
|
3944
|
-
if (
|
|
3945
|
-
|
|
4066
|
+
if (index >= draggingIndex && index < draggingEndIndex) {
|
|
4067
|
+
if (event.clientY <= rect.bottom) {
|
|
4068
|
+
if (previousDropIndex != null) {
|
|
4069
|
+
nextDropTarget = { index: previousDropIndex, intent: "after" };
|
|
4070
|
+
} else {
|
|
4071
|
+
nextDropTarget = { index: draggingIndex, intent: "before" };
|
|
4072
|
+
}
|
|
4073
|
+
break;
|
|
4074
|
+
}
|
|
4075
|
+
continue;
|
|
3946
4076
|
}
|
|
3947
|
-
|
|
3948
|
-
|
|
4077
|
+
if (event.clientY < rect.top) {
|
|
4078
|
+
nextDropTarget = { index, intent: "before" };
|
|
4079
|
+
break;
|
|
4080
|
+
}
|
|
4081
|
+
if (event.clientY > rect.bottom) {
|
|
4082
|
+
previousDropIndex = index;
|
|
4083
|
+
nextDropTarget = { index, intent: "after" };
|
|
4084
|
+
continue;
|
|
4085
|
+
}
|
|
4086
|
+
const ratio = (event.clientY - rect.top) / rect.height;
|
|
4087
|
+
if (!usesDepth) {
|
|
4088
|
+
nextDropTarget = ratio < 0.5 ? { index, intent: "before" } : { index, intent: "after" };
|
|
4089
|
+
break;
|
|
4090
|
+
}
|
|
4091
|
+
const item = items[index];
|
|
4092
|
+
const canHaveChildren = (getCanHaveChildren?.(item, index) ?? true) && readDepth(item, index) < maxDepth;
|
|
4093
|
+
if (ratio < 0.25) {
|
|
4094
|
+
nextDropTarget = { index, intent: "before" };
|
|
4095
|
+
} else if (ratio > 0.75 || !canHaveChildren) {
|
|
4096
|
+
nextDropTarget = { index, intent: "after" };
|
|
4097
|
+
} else {
|
|
4098
|
+
nextDropTarget = { index, intent: "inside" };
|
|
4099
|
+
}
|
|
4100
|
+
break;
|
|
4101
|
+
}
|
|
4102
|
+
setDropTarget(nextDropTarget);
|
|
3949
4103
|
};
|
|
3950
4104
|
const handleMouseUp = () => {
|
|
3951
4105
|
const fromIndex = fromIndexRef.current;
|
|
3952
|
-
const
|
|
3953
|
-
if (fromIndex != null &&
|
|
3954
|
-
const
|
|
3955
|
-
|
|
4106
|
+
const nextDropTarget = dropTarget;
|
|
4107
|
+
if (fromIndex != null && nextDropTarget != null && items[nextDropTarget.index]) {
|
|
4108
|
+
const insertionIndex = getInsertionIndex(items, nextDropTarget, () => 1);
|
|
4109
|
+
const nextItems = usesDepth ? moveWithDepth(items, fromIndex, nextDropTarget, readDepth, setDepth, maxDepth) : reorder(
|
|
4110
|
+
items,
|
|
4111
|
+
fromIndex,
|
|
4112
|
+
insertionIndex > fromIndex ? insertionIndex - 1 : insertionIndex
|
|
4113
|
+
);
|
|
4114
|
+
if (nextItems !== items) onChange?.(nextItems);
|
|
3956
4115
|
}
|
|
3957
4116
|
fromIndexRef.current = null;
|
|
3958
4117
|
setDraggingIndex(null);
|
|
3959
|
-
|
|
4118
|
+
setDropTarget(null);
|
|
3960
4119
|
};
|
|
3961
4120
|
window.addEventListener("mousemove", handleMouseMove);
|
|
3962
4121
|
window.addEventListener("mouseup", handleMouseUp);
|
|
@@ -3964,12 +4123,25 @@ function SDraggableListInner({
|
|
|
3964
4123
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
3965
4124
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
3966
4125
|
};
|
|
3967
|
-
}, [
|
|
4126
|
+
}, [
|
|
4127
|
+
draggingIndex,
|
|
4128
|
+
dropTarget,
|
|
4129
|
+
items,
|
|
4130
|
+
onChange,
|
|
4131
|
+
dragContext,
|
|
4132
|
+
getDepth,
|
|
4133
|
+
usesDepth,
|
|
4134
|
+
readDepth,
|
|
4135
|
+
setDepth,
|
|
4136
|
+
maxDepth,
|
|
4137
|
+
getCanHaveChildren
|
|
4138
|
+
]);
|
|
3968
4139
|
if (dragContext && (!listId || !dragGroup)) {
|
|
3969
4140
|
throw new Error("SDraggableList: Provider \uC548\uC5D0\uC11C\uB294 group\uACFC listId\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
3970
4141
|
}
|
|
3971
4142
|
const groupDrop = dragContext?.drop;
|
|
3972
|
-
const currentDropIndex = dragContext ? groupDrop?.group === dragGroup && groupDrop?.listId === listId ? groupDrop?.index ?? null : null :
|
|
4143
|
+
const currentDropIndex = dragContext ? groupDrop?.group === dragGroup && groupDrop?.listId === listId ? groupDrop?.index ?? null : null : dropTarget?.index;
|
|
4144
|
+
const currentDropIntent = dragContext ? void 0 : dropTarget?.intent;
|
|
3973
4145
|
const isDropTarget = dragContext ? groupDrop?.group === dragGroup && groupDrop?.listId === listId : draggingIndex != null;
|
|
3974
4146
|
const showEmptyDrop = Boolean(dragContext && isDropTarget && items.length === 0);
|
|
3975
4147
|
const beforeIndicatorPosition = useGap ? "before:top-[-5px]" : "before:top-0";
|
|
@@ -4000,19 +4172,30 @@ function SDraggableListInner({
|
|
|
4000
4172
|
children: items.map((item, index) => {
|
|
4001
4173
|
const itemKey = getKey(item, index);
|
|
4002
4174
|
const disabled = getDisabled?.(item, index) ?? false;
|
|
4003
|
-
const
|
|
4004
|
-
const
|
|
4175
|
+
const depth = readDepth(item, index);
|
|
4176
|
+
const showBefore = isDropTarget && currentDropIndex === index && (dragContext || currentDropIntent === "before");
|
|
4177
|
+
const showInside = isDropTarget && currentDropIndex === index && !dragContext && usesDepth && currentDropIntent === "inside";
|
|
4178
|
+
const showAfter = isDropTarget && (dragContext ? currentDropIndex === items.length && index === items.length - 1 : currentDropIndex === index && currentDropIntent === "after");
|
|
4179
|
+
const selectItem = () => {
|
|
4180
|
+
if (disabled) return;
|
|
4181
|
+
setInternalSelectedKey(itemKey);
|
|
4182
|
+
onSelectedKeyChange?.(itemKey);
|
|
4183
|
+
};
|
|
4184
|
+
const handleItemKeyDown = (event) => {
|
|
4185
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
4186
|
+
event.preventDefault();
|
|
4187
|
+
selectItem();
|
|
4188
|
+
};
|
|
4005
4189
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4006
4190
|
"div",
|
|
4007
4191
|
{
|
|
4008
4192
|
"data-draggable-list-item": true,
|
|
4193
|
+
role: "button",
|
|
4194
|
+
tabIndex: disabled ? -1 : 0,
|
|
4009
4195
|
"aria-disabled": disabled || void 0,
|
|
4010
|
-
onClick:
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
onSelectedKeyChange?.(itemKey);
|
|
4014
|
-
},
|
|
4015
|
-
className: `relative ${showBefore ? `before:absolute before:left-0 before:right-0 ${beforeIndicatorPosition} before:z-10 before:h-[2px] before:bg-(--sys-color-border-accent) before:content-['']` : ""} ${showAfter ? `after:absolute after:left-0 after:right-0 ${afterIndicatorPosition} after:z-10 after:h-[2px] after:bg-(--sys-color-border-accent) after:content-['']` : ""}`,
|
|
4196
|
+
onClick: selectItem,
|
|
4197
|
+
onKeyDown: handleItemKeyDown,
|
|
4198
|
+
className: `relative ${showBefore ? `before:absolute before:left-0 before:right-0 ${beforeIndicatorPosition} before:z-10 before:h-[2px] before:bg-(--sys-color-border-accent) before:content-['']` : ""} ${showAfter ? `after:absolute after:left-0 after:right-0 ${afterIndicatorPosition} after:z-10 after:h-[2px] after:bg-(--sys-color-border-accent) after:content-['']` : ""} ${showInside ? "outline outline-2 outline-offset-[-2px] outline-(--sys-color-border-accent)" : ""}`,
|
|
4016
4199
|
children: renderItem(item, index, {
|
|
4017
4200
|
onDragHandleMouseDown: (event) => {
|
|
4018
4201
|
if (disabled) return;
|
|
@@ -4020,7 +4203,8 @@ function SDraggableListInner({
|
|
|
4020
4203
|
dragContext.startDrag(event, dragGroup, listId, index, itemKey);
|
|
4021
4204
|
} else startDrag(event, index);
|
|
4022
4205
|
},
|
|
4023
|
-
selected: currentSelectedKey === itemKey
|
|
4206
|
+
selected: currentSelectedKey === itemKey,
|
|
4207
|
+
depth
|
|
4024
4208
|
})
|
|
4025
4209
|
},
|
|
4026
4210
|
itemKey
|
|
@@ -6104,6 +6288,7 @@ var STextLink = /* @__PURE__ */ react.forwardRef(function STextLink2({
|
|
|
6104
6288
|
label = "",
|
|
6105
6289
|
icon,
|
|
6106
6290
|
iconColor,
|
|
6291
|
+
iconRotate,
|
|
6107
6292
|
labelClass,
|
|
6108
6293
|
rightArrow = "none",
|
|
6109
6294
|
underline = false,
|
|
@@ -6146,7 +6331,7 @@ var STextLink = /* @__PURE__ */ react.forwardRef(function STextLink2({
|
|
|
6146
6331
|
style: { gap: s.gap, color: contentColor, ...style },
|
|
6147
6332
|
...rest,
|
|
6148
6333
|
children: [
|
|
6149
|
-
icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.iconSize, color: resolvedIconColor }),
|
|
6334
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.iconSize, color: resolvedIconColor, rotate: iconRotate }),
|
|
6150
6335
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6151
6336
|
"span",
|
|
6152
6337
|
{
|
|
@@ -11124,11 +11309,13 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
11124
11309
|
noDataSlot,
|
|
11125
11310
|
isLoading = false,
|
|
11126
11311
|
dense = false,
|
|
11312
|
+
onDenseChange,
|
|
11127
11313
|
noHover = false,
|
|
11128
11314
|
pagination,
|
|
11129
11315
|
onPageChange,
|
|
11130
11316
|
useInternalPagination = false,
|
|
11131
11317
|
useRowsPerPageSelect = false,
|
|
11318
|
+
useDensityToggle = false,
|
|
11132
11319
|
rowsPerPageOption = DEFAULT_ROWS_PER_PAGE_OPTION,
|
|
11133
11320
|
onRowsPerPageChange,
|
|
11134
11321
|
useVirtualScroll = false,
|
|
@@ -11524,21 +11711,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
11524
11711
|
col.align === "right" && "justify-end"
|
|
11525
11712
|
),
|
|
11526
11713
|
children: col.renderHeader ? col.renderHeader(col, i) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11527
|
-
col.icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: col.icon, size: 16, color: col.iconColor }),
|
|
11528
11714
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: col.label }),
|
|
11529
|
-
isSortable && // 미정렬은 updown 을 default(회색)로 — 정렬할 수 있다는 것 자체가
|
|
11530
|
-
// 헤더에 보여야 한다. 정렬 중이면 action 색으로 올려 활성임을 알린다.
|
|
11531
|
-
// 라벨이 truncate 돼도 버튼은 남도록 shrink-0.
|
|
11532
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11533
|
-
SGhostButton,
|
|
11534
|
-
{
|
|
11535
|
-
size: "xxs",
|
|
11536
|
-
intent: sortDir ? "action" : "default",
|
|
11537
|
-
icon: sortDir === "asc" ? "arrowUp" : sortDir === "desc" ? "arrowDown" : "updown",
|
|
11538
|
-
ariaLabel: `${col.label} \uC815\uB82C`,
|
|
11539
|
-
onClick: () => toggleSort(col)
|
|
11540
|
-
}
|
|
11541
|
-
) }),
|
|
11542
11715
|
col.helpText && col.helpText.length > 0 && // 라벨이 좁아져 truncate 되더라도 아이콘까지 함께 줄어들면 안 되므로
|
|
11543
11716
|
// shrink-0 래퍼로 감싼다 (STooltip 의 className 은 본문 쪽으로 간다).
|
|
11544
11717
|
// 아이콘·크기·색은 SKeyValueTable 헤더 도움말과 동일하게 맞춘다.
|
|
@@ -11552,6 +11725,50 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
11552
11725
|
placement: "top",
|
|
11553
11726
|
message: col.helpText
|
|
11554
11727
|
}
|
|
11728
|
+
) }),
|
|
11729
|
+
col.editable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
11730
|
+
SIcon,
|
|
11731
|
+
{
|
|
11732
|
+
name: "pageEdit",
|
|
11733
|
+
size: 12,
|
|
11734
|
+
color: "var(--sys-color-link-accent)",
|
|
11735
|
+
label: "\uC218\uC815 \uAC00\uB2A5",
|
|
11736
|
+
className: "shrink-0"
|
|
11737
|
+
}
|
|
11738
|
+
),
|
|
11739
|
+
col.navigable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
11740
|
+
SIcon,
|
|
11741
|
+
{
|
|
11742
|
+
name: "pageMove",
|
|
11743
|
+
size: 12,
|
|
11744
|
+
color: "var(--sys-color-link-accent)",
|
|
11745
|
+
label: "\uB2E4\uB978 \uD654\uBA74\uC73C\uB85C \uC774\uB3D9",
|
|
11746
|
+
className: "shrink-0"
|
|
11747
|
+
}
|
|
11748
|
+
),
|
|
11749
|
+
col.required && // 라벨이 truncate 돼도 필수 표시는 남아야 하므로 shrink-0.
|
|
11750
|
+
// 아이콘·크기·색은 SKeyValueTable 헤더 필수 표시와 동일하게 맞춘다.
|
|
11751
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11752
|
+
SIcon,
|
|
11753
|
+
{
|
|
11754
|
+
name: "asterisk",
|
|
11755
|
+
size: 12,
|
|
11756
|
+
color: "var(--sys-color-fg-accent)",
|
|
11757
|
+
className: "shrink-0"
|
|
11758
|
+
}
|
|
11759
|
+
),
|
|
11760
|
+
isSortable && // 미정렬은 updown 을 default(회색)로 — 정렬할 수 있다는 것 자체가
|
|
11761
|
+
// 헤더에 보여야 한다. 정렬 중이면 action 색으로 올려 활성임을 알린다.
|
|
11762
|
+
// 라벨이 truncate 돼도 버튼은 남도록 shrink-0.
|
|
11763
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11764
|
+
SGhostButton,
|
|
11765
|
+
{
|
|
11766
|
+
size: "xxs",
|
|
11767
|
+
intent: sortDir ? "action" : "default",
|
|
11768
|
+
icon: sortDir === "asc" ? "arrowUp" : sortDir === "desc" ? "arrowDown" : "updown",
|
|
11769
|
+
ariaLabel: `${col.label} \uC815\uB82C`,
|
|
11770
|
+
onClick: () => toggleSort(col)
|
|
11771
|
+
}
|
|
11555
11772
|
) })
|
|
11556
11773
|
] })
|
|
11557
11774
|
}
|
|
@@ -11709,16 +11926,32 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
11709
11926
|
),
|
|
11710
11927
|
children: [
|
|
11711
11928
|
/* @__PURE__ */ jsxRuntime.jsx(SPagination, { currentPage: displayPage, lastPage, onPageChange: changePage }),
|
|
11712
|
-
useRowsPerPageSelect && /* @__PURE__ */ jsxRuntime.
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11929
|
+
(useDensityToggle || useRowsPerPageSelect) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute right-[10px] top-1/2 flex -translate-y-1/2 items-center gap-[12px]", children: [
|
|
11930
|
+
useDensityToggle && // 라벨·아이콘은 현재 밀도가 아니라 **누르면 되는 상태**를 가리킨다 (dense 면 "넓게 보기").
|
|
11931
|
+
// row·rowDense 는 세로 막대라 90도 돌려 가로 행으로 쓴다.
|
|
11932
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11933
|
+
STextLink,
|
|
11934
|
+
{
|
|
11935
|
+
size: "sm",
|
|
11936
|
+
icon: dense ? "row" : "rowDense",
|
|
11937
|
+
iconRotate: 90,
|
|
11938
|
+
iconColor: "var(--sys-color-fg-quaternary)",
|
|
11939
|
+
label: dense ? "\uB113\uAC8C \uBCF4\uAE30" : "\uC881\uAC8C \uBCF4\uAE30",
|
|
11940
|
+
onClick: () => onDenseChange?.(!dense)
|
|
11941
|
+
}
|
|
11942
|
+
),
|
|
11943
|
+
useDensityToggle && useRowsPerPageSelect && /* @__PURE__ */ jsxRuntime.jsx(SDivider, { vertical: true, className: "my-[6px]" }),
|
|
11944
|
+
useRowsPerPageSelect && /* @__PURE__ */ jsxRuntime.jsx(
|
|
11945
|
+
SSelect2,
|
|
11946
|
+
{
|
|
11947
|
+
options: rowsPerPageOption,
|
|
11948
|
+
value: useInternalPagination ? innerRowsPerPage : pagination?.rowsPerPage,
|
|
11949
|
+
emitValue: true,
|
|
11950
|
+
onValueChange: (v) => changeRowsPerPage(Number(v)),
|
|
11951
|
+
width: 128
|
|
11952
|
+
}
|
|
11953
|
+
)
|
|
11954
|
+
] })
|
|
11722
11955
|
]
|
|
11723
11956
|
}
|
|
11724
11957
|
)
|
|
@@ -12814,6 +13047,11 @@ function SCalendar({
|
|
|
12814
13047
|
}
|
|
12815
13048
|
);
|
|
12816
13049
|
}
|
|
13050
|
+
var MODE_NOUN = {
|
|
13051
|
+
date: "\uB0A0\uC9DC",
|
|
13052
|
+
month: "\uC6D4",
|
|
13053
|
+
year: "\uC5F0\uB3C4"
|
|
13054
|
+
};
|
|
12817
13055
|
var DATEPICKER_MODE_LIST_HEIGHT = 240;
|
|
12818
13056
|
var DATEPICKER_MODE_ITEM_HEIGHT = 28;
|
|
12819
13057
|
var YEAR_LIST_EDGE_BUFFER = 24;
|
|
@@ -13085,7 +13323,9 @@ function SDatePicker({
|
|
|
13085
13323
|
placeholder,
|
|
13086
13324
|
selectable,
|
|
13087
13325
|
disabled = false,
|
|
13326
|
+
clearable = false,
|
|
13088
13327
|
width,
|
|
13328
|
+
maxWidth,
|
|
13089
13329
|
name,
|
|
13090
13330
|
rules,
|
|
13091
13331
|
status,
|
|
@@ -13128,7 +13368,8 @@ function SDatePicker({
|
|
|
13128
13368
|
fieldMinW: 168,
|
|
13129
13369
|
// 값 길이가 YYYY-MM-DD 로 정해져 있어, width="100%" 를 받아도 행 전체로
|
|
13130
13370
|
// 늘어나지 않게 상한을 건다 (SKeyValueTable 이 모든 컨트롤에 100% 를 넘긴다).
|
|
13131
|
-
// px 가 아니라 등급이라 --cmp-field-width-* 가 바뀌면 함께
|
|
13371
|
+
// px 가 아니라 등급이라 --cmp-field-width-* 가 바뀌면 함께 따라간다.
|
|
13372
|
+
// 이 기본 상한이 걸리적거리는 자리(폭이 이미 좁게 정해진 팝오버 등)는 maxWidth prop 으로 덮는다
|
|
13132
13373
|
fieldMaxW: "lg",
|
|
13133
13374
|
fontSize: 14,
|
|
13134
13375
|
lineHeight: 24,
|
|
@@ -13149,6 +13390,10 @@ function SDatePicker({
|
|
|
13149
13390
|
if (rules && rules.length > 0) setRuleError(runRules(date, rules));
|
|
13150
13391
|
setOpen(false);
|
|
13151
13392
|
};
|
|
13393
|
+
const clear = () => {
|
|
13394
|
+
onValueChange?.(null);
|
|
13395
|
+
if (rules && rules.length > 0) setRuleError(runRules(null, rules));
|
|
13396
|
+
};
|
|
13152
13397
|
const selectListboxValue = (nextValue) => {
|
|
13153
13398
|
onValueChange?.(nextValue);
|
|
13154
13399
|
if (rules && rules.length > 0) setRuleError(runRules(nextValue, rules));
|
|
@@ -13172,20 +13417,31 @@ function SDatePicker({
|
|
|
13172
13417
|
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
13173
13418
|
width,
|
|
13174
13419
|
minWidth: dims.fieldMinW,
|
|
13175
|
-
maxWidth: dims.fieldMaxW,
|
|
13420
|
+
maxWidth: maxWidth ?? dims.fieldMaxW,
|
|
13176
13421
|
disabled,
|
|
13177
13422
|
className,
|
|
13178
13423
|
style,
|
|
13179
13424
|
children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover10__namespace.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
13180
13425
|
/* @__PURE__ */ jsxRuntime.jsx(RPopover10__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13181
|
-
"
|
|
13426
|
+
"div",
|
|
13182
13427
|
{
|
|
13183
|
-
|
|
13184
|
-
|
|
13185
|
-
disabled,
|
|
13428
|
+
role: "button",
|
|
13429
|
+
"aria-disabled": disabled,
|
|
13430
|
+
tabIndex: disabled ? -1 : 0,
|
|
13431
|
+
"data-name": name,
|
|
13186
13432
|
onFocus: () => setFocused(true),
|
|
13187
13433
|
onBlur: () => setFocused(false),
|
|
13188
|
-
|
|
13434
|
+
onKeyDown: (event) => {
|
|
13435
|
+
if (disabled) return;
|
|
13436
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
13437
|
+
event.preventDefault();
|
|
13438
|
+
setOpen(!open);
|
|
13439
|
+
}
|
|
13440
|
+
},
|
|
13441
|
+
className: cn(
|
|
13442
|
+
"flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
|
|
13443
|
+
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
13444
|
+
),
|
|
13189
13445
|
style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
|
|
13190
13446
|
children: [
|
|
13191
13447
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -13209,6 +13465,18 @@ function SDatePicker({
|
|
|
13209
13465
|
},
|
|
13210
13466
|
children: hasValue ? value : resolvedPlaceholder
|
|
13211
13467
|
}
|
|
13468
|
+
),
|
|
13469
|
+
clearable && hasValue && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
13470
|
+
SGhostButton,
|
|
13471
|
+
{
|
|
13472
|
+
icon: "close",
|
|
13473
|
+
size: "xxs",
|
|
13474
|
+
ariaLabel: `${MODE_NOUN[mode]} \uC9C0\uC6B0\uAE30`,
|
|
13475
|
+
onClick: (event) => {
|
|
13476
|
+
event.stopPropagation();
|
|
13477
|
+
clear();
|
|
13478
|
+
}
|
|
13479
|
+
}
|
|
13212
13480
|
)
|
|
13213
13481
|
]
|
|
13214
13482
|
}
|
|
@@ -13588,6 +13856,7 @@ function SDateRangePicker({
|
|
|
13588
13856
|
maxRange,
|
|
13589
13857
|
useTimePicker = false,
|
|
13590
13858
|
disabled = false,
|
|
13859
|
+
clearable = false,
|
|
13591
13860
|
width,
|
|
13592
13861
|
name,
|
|
13593
13862
|
rules,
|
|
@@ -13655,6 +13924,11 @@ function SDateRangePicker({
|
|
|
13655
13924
|
if (rules && rules.length > 0) setRuleError(runRules(r, rules));
|
|
13656
13925
|
if (!useTimePicker) setOpen(false);
|
|
13657
13926
|
};
|
|
13927
|
+
const clear = () => {
|
|
13928
|
+
setPendingStart(null);
|
|
13929
|
+
onValueChange?.(null);
|
|
13930
|
+
if (rules && rules.length > 0) setRuleError(runRules(null, rules));
|
|
13931
|
+
};
|
|
13658
13932
|
const resolvedPlaceholder = useTimePicker && placeholder === "YYYY-MM-DD ~ YYYY-MM-DD" ? "YYYY-MM-DD HH:mm ~ YYYY-MM-DD HH:mm" : placeholder;
|
|
13659
13933
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
13660
13934
|
SField,
|
|
@@ -13690,12 +13964,23 @@ function SDateRangePicker({
|
|
|
13690
13964
|
},
|
|
13691
13965
|
children: [
|
|
13692
13966
|
/* @__PURE__ */ jsxRuntime.jsx(RPopover10__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13693
|
-
"
|
|
13967
|
+
"div",
|
|
13694
13968
|
{
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
disabled,
|
|
13698
|
-
|
|
13969
|
+
role: "button",
|
|
13970
|
+
"aria-disabled": disabled,
|
|
13971
|
+
tabIndex: disabled ? -1 : 0,
|
|
13972
|
+
"data-name": name,
|
|
13973
|
+
onKeyDown: (event) => {
|
|
13974
|
+
if (disabled) return;
|
|
13975
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
13976
|
+
event.preventDefault();
|
|
13977
|
+
setOpen(!open);
|
|
13978
|
+
}
|
|
13979
|
+
},
|
|
13980
|
+
className: cn(
|
|
13981
|
+
"flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
|
|
13982
|
+
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
13983
|
+
),
|
|
13699
13984
|
style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
|
|
13700
13985
|
children: [
|
|
13701
13986
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -13726,6 +14011,18 @@ function SDateRangePicker({
|
|
|
13726
14011
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: endText })
|
|
13727
14012
|
] }) : resolvedPlaceholder
|
|
13728
14013
|
}
|
|
14014
|
+
),
|
|
14015
|
+
clearable && hasDisplay && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
14016
|
+
SGhostButton,
|
|
14017
|
+
{
|
|
14018
|
+
icon: "close",
|
|
14019
|
+
size: "xxs",
|
|
14020
|
+
ariaLabel: "\uAE30\uAC04 \uC9C0\uC6B0\uAE30",
|
|
14021
|
+
onClick: (event) => {
|
|
14022
|
+
event.stopPropagation();
|
|
14023
|
+
clear();
|
|
14024
|
+
}
|
|
14025
|
+
}
|
|
13729
14026
|
)
|
|
13730
14027
|
]
|
|
13731
14028
|
}
|
|
@@ -14990,6 +15287,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
14990
15287
|
);
|
|
14991
15288
|
const [openKey, setOpenKey] = react.useState(null);
|
|
14992
15289
|
const [addOpen, setAddOpen] = react.useState(false);
|
|
15290
|
+
const pendingOpenKeyRef = react.useRef(null);
|
|
14993
15291
|
const triggerRefs = react.useRef(/* @__PURE__ */ new Map());
|
|
14994
15292
|
const initializedDefaultsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
14995
15293
|
const prevOpenKeyRef = react.useRef(null);
|
|
@@ -15065,6 +15363,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15065
15363
|
const hasAddButton = fields.some(isAddableField);
|
|
15066
15364
|
const hasRightActions = hasAddButton || showReset;
|
|
15067
15365
|
const currentOpenField = fields.find((field) => field.key === openKey);
|
|
15366
|
+
const menuOpen = openKey != null || addOpen;
|
|
15068
15367
|
const editorPopoverStyle = react.useMemo(() => {
|
|
15069
15368
|
if (currentOpenField?.type === "keyword") {
|
|
15070
15369
|
return { width: CHIPFILTER_LISTBOX_WIDTH };
|
|
@@ -15123,7 +15422,13 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15123
15422
|
onAddFilter?.(key);
|
|
15124
15423
|
setAddOpen(false);
|
|
15125
15424
|
const field = fields.find((f) => f.key === key);
|
|
15126
|
-
if (field && !isInlineField(field))
|
|
15425
|
+
if (field && !isInlineField(field)) {
|
|
15426
|
+
pendingOpenKeyRef.current = key;
|
|
15427
|
+
requestAnimationFrame(() => {
|
|
15428
|
+
triggerRefs.current.get(key)?.focus();
|
|
15429
|
+
setOpenKey(key);
|
|
15430
|
+
});
|
|
15431
|
+
}
|
|
15127
15432
|
};
|
|
15128
15433
|
const rootStyle = react.useMemo(
|
|
15129
15434
|
() => ({
|
|
@@ -15166,6 +15471,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15166
15471
|
{
|
|
15167
15472
|
message,
|
|
15168
15473
|
open: invalidGroups.has(runGroupIndex),
|
|
15474
|
+
placement: menuOpen ? "top" : "bottom",
|
|
15169
15475
|
children: runBuffer
|
|
15170
15476
|
},
|
|
15171
15477
|
`group-${runGroupIndex}`
|
|
@@ -15179,14 +15485,16 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15179
15485
|
activeFields.forEach((field, index) => {
|
|
15180
15486
|
const inline = isInlineField(field);
|
|
15181
15487
|
const groupIndex = groupIndexByKey.get(field.key) ?? 0;
|
|
15182
|
-
const warning =
|
|
15488
|
+
const warning = invalidGroups.has(groupIndex);
|
|
15183
15489
|
const prevField = index > 0 ? activeFields[index - 1] : null;
|
|
15184
15490
|
const prevGroupIndex = prevField ? groupIndexByKey.get(prevField.key) ?? 0 : null;
|
|
15185
15491
|
const needsLeadingDivider = index === 0 ? false : inline || prevField != null && isInlineField(prevField) || groupIndex !== prevGroupIndex && groups[groupIndex]?.divider === true;
|
|
15492
|
+
const hoistDivider = needsLeadingDivider && groupIndex !== runGroupIndex;
|
|
15186
15493
|
if (groupIndex !== runGroupIndex) {
|
|
15187
15494
|
flushRun();
|
|
15188
15495
|
runGroupIndex = groupIndex;
|
|
15189
15496
|
}
|
|
15497
|
+
if (hoistDivider) nodes.push(/* @__PURE__ */ jsxRuntime.jsx(Divider, { inset: true }, `${field.key}-divider`));
|
|
15190
15498
|
const addable = isAddableField(field);
|
|
15191
15499
|
const showClear = addable || !isAtDefaultValue(field, values[field.key]);
|
|
15192
15500
|
const handleClear = () => {
|
|
@@ -15250,7 +15558,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15250
15558
|
field.key
|
|
15251
15559
|
);
|
|
15252
15560
|
runBuffer.push(
|
|
15253
|
-
needsLeadingDivider ? /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
15561
|
+
needsLeadingDivider && !hoistDivider ? /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
15254
15562
|
/* @__PURE__ */ jsxRuntime.jsx(Divider, { inset: true }),
|
|
15255
15563
|
node
|
|
15256
15564
|
] }, `${field.key}-wrap`) : node
|
|
@@ -15298,6 +15606,11 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15298
15606
|
side: "bottom",
|
|
15299
15607
|
align: "start",
|
|
15300
15608
|
sideOffset: 4,
|
|
15609
|
+
onCloseAutoFocus: (event) => {
|
|
15610
|
+
if (pendingOpenKeyRef.current == null) return;
|
|
15611
|
+
pendingOpenKeyRef.current = null;
|
|
15612
|
+
event.preventDefault();
|
|
15613
|
+
},
|
|
15301
15614
|
className: cn("z-50 min-w-[180px]", FLOATING_SLIDE_ANIM),
|
|
15302
15615
|
children: /* @__PURE__ */ jsxRuntime.jsx(ListBox, { children: inactiveFields.length > 0 ? inactiveFields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(MenuItem, { onClick: () => addField(field.key), children: field.label }, field.key)) : /* @__PURE__ */ jsxRuntime.jsx(EmptyItem, { children: "\uCD94\uAC00\uD560 \uD544\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }) })
|
|
15303
15616
|
}
|
|
@@ -15348,6 +15661,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15348
15661
|
value: values[currentOpenField.key],
|
|
15349
15662
|
disabled: disabled || currentOpenField.disabled,
|
|
15350
15663
|
onValueChange: (next) => emitValue(currentOpenField.key, next),
|
|
15664
|
+
onValueCommit: (next) => emitValueAndSearch(currentOpenField.key, next),
|
|
15351
15665
|
onClose: () => setOpenKey(null)
|
|
15352
15666
|
}
|
|
15353
15667
|
)
|
|
@@ -15375,9 +15689,20 @@ function Divider({ inset, top } = {}) {
|
|
|
15375
15689
|
function GroupTooltip({
|
|
15376
15690
|
message,
|
|
15377
15691
|
open,
|
|
15692
|
+
placement,
|
|
15378
15693
|
children
|
|
15379
15694
|
}) {
|
|
15380
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15695
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15696
|
+
STooltip2,
|
|
15697
|
+
{
|
|
15698
|
+
trigger: "none",
|
|
15699
|
+
open,
|
|
15700
|
+
placement,
|
|
15701
|
+
tooltipType: "warning",
|
|
15702
|
+
message: [message],
|
|
15703
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-[var(--cmp-chipFilter-chip-group)]", children })
|
|
15704
|
+
}
|
|
15705
|
+
);
|
|
15381
15706
|
}
|
|
15382
15707
|
function FilterChip({
|
|
15383
15708
|
field,
|
|
@@ -15487,6 +15812,7 @@ function EditorPanel({
|
|
|
15487
15812
|
value,
|
|
15488
15813
|
disabled,
|
|
15489
15814
|
onValueChange,
|
|
15815
|
+
onValueCommit,
|
|
15490
15816
|
onClose
|
|
15491
15817
|
}) {
|
|
15492
15818
|
const wrapsInPaddedTop = field.type === "date" || field.type === "period";
|
|
@@ -15506,7 +15832,8 @@ function EditorPanel({
|
|
|
15506
15832
|
field,
|
|
15507
15833
|
value,
|
|
15508
15834
|
disabled,
|
|
15509
|
-
onValueChange
|
|
15835
|
+
onValueChange,
|
|
15836
|
+
onValueCommit
|
|
15510
15837
|
}
|
|
15511
15838
|
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
15512
15839
|
FilterEditor,
|
|
@@ -15514,7 +15841,8 @@ function EditorPanel({
|
|
|
15514
15841
|
field,
|
|
15515
15842
|
value,
|
|
15516
15843
|
disabled,
|
|
15517
|
-
onValueChange
|
|
15844
|
+
onValueChange,
|
|
15845
|
+
onValueCommit
|
|
15518
15846
|
}
|
|
15519
15847
|
),
|
|
15520
15848
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -15566,7 +15894,8 @@ function FilterEditor({
|
|
|
15566
15894
|
field,
|
|
15567
15895
|
value,
|
|
15568
15896
|
disabled,
|
|
15569
|
-
onValueChange
|
|
15897
|
+
onValueChange,
|
|
15898
|
+
onValueCommit
|
|
15570
15899
|
}) {
|
|
15571
15900
|
if (field.type === "period") {
|
|
15572
15901
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -15597,7 +15926,8 @@ function FilterEditor({
|
|
|
15597
15926
|
field,
|
|
15598
15927
|
value: isKeywordValue(value) ? value : keywordEntries(value),
|
|
15599
15928
|
disabled,
|
|
15600
|
-
onValueChange
|
|
15929
|
+
onValueChange,
|
|
15930
|
+
onValueCommit
|
|
15601
15931
|
}
|
|
15602
15932
|
);
|
|
15603
15933
|
}
|
|
@@ -15639,7 +15969,9 @@ function DatePresetEditor({
|
|
|
15639
15969
|
onValueChange,
|
|
15640
15970
|
selectable: field.selectable,
|
|
15641
15971
|
disabled,
|
|
15642
|
-
placeholder: field.placeholder
|
|
15972
|
+
placeholder: field.placeholder,
|
|
15973
|
+
width: "100%",
|
|
15974
|
+
maxWidth: "100%"
|
|
15643
15975
|
}
|
|
15644
15976
|
);
|
|
15645
15977
|
}
|
|
@@ -15699,7 +16031,8 @@ function PeriodPresetEditor({
|
|
|
15699
16031
|
onValueChange: updateInputValue,
|
|
15700
16032
|
selectable: field.selectable,
|
|
15701
16033
|
disabled,
|
|
15702
|
-
width: "100%"
|
|
16034
|
+
width: "100%",
|
|
16035
|
+
maxWidth: "100%"
|
|
15703
16036
|
}
|
|
15704
16037
|
);
|
|
15705
16038
|
}
|
|
@@ -15712,19 +16045,18 @@ function PeriodPresetEditor({
|
|
|
15712
16045
|
onValueChange: updateInputValue,
|
|
15713
16046
|
selectable: field.selectable,
|
|
15714
16047
|
disabled,
|
|
15715
|
-
width: "100%"
|
|
16048
|
+
width: "100%",
|
|
16049
|
+
maxWidth: "100%"
|
|
15716
16050
|
}
|
|
15717
16051
|
);
|
|
15718
16052
|
}
|
|
15719
16053
|
if (selectedUnit === "quarter") {
|
|
15720
16054
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15721
|
-
|
|
16055
|
+
SRadioButton,
|
|
15722
16056
|
{
|
|
15723
16057
|
value: typeof periodValue.value === "number" ? periodValue.value : 1,
|
|
15724
16058
|
onValueChange: updateInputValue,
|
|
15725
|
-
emitValue: true,
|
|
15726
16059
|
disabled,
|
|
15727
|
-
width: "100%",
|
|
15728
16060
|
options: [
|
|
15729
16061
|
{ value: 1, label: "1\uBD84\uAE30" },
|
|
15730
16062
|
{ value: 2, label: "2\uBD84\uAE30" },
|
|
@@ -15736,13 +16068,11 @@ function PeriodPresetEditor({
|
|
|
15736
16068
|
}
|
|
15737
16069
|
if (selectedUnit === "half") {
|
|
15738
16070
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15739
|
-
|
|
16071
|
+
SRadioButton,
|
|
15740
16072
|
{
|
|
15741
16073
|
value: typeof periodValue.value === "string" ? periodValue.value : "first",
|
|
15742
16074
|
onValueChange: updateInputValue,
|
|
15743
|
-
emitValue: true,
|
|
15744
16075
|
disabled,
|
|
15745
|
-
width: "100%",
|
|
15746
16076
|
options: [
|
|
15747
16077
|
{ value: "first", label: "\uC0C1\uBC18\uAE30" },
|
|
15748
16078
|
{ value: "second", label: "\uD558\uBC18\uAE30" }
|
|
@@ -15759,7 +16089,8 @@ function PeriodPresetEditor({
|
|
|
15759
16089
|
onValueChange: updateInputValue,
|
|
15760
16090
|
selectable: field.selectable,
|
|
15761
16091
|
disabled,
|
|
15762
|
-
width: "100%"
|
|
16092
|
+
width: "100%",
|
|
16093
|
+
maxWidth: "100%"
|
|
15763
16094
|
}
|
|
15764
16095
|
);
|
|
15765
16096
|
}
|
|
@@ -15787,7 +16118,6 @@ function PeriodPresetEditor({
|
|
|
15787
16118
|
},
|
|
15788
16119
|
preset.value
|
|
15789
16120
|
)) }),
|
|
15790
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, className: "h-px w-full", style: { background: CHIPFILTER.listboxBorder } }),
|
|
15791
16121
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full [&>*]:w-full", children: renderInput() })
|
|
15792
16122
|
] });
|
|
15793
16123
|
}
|
|
@@ -15909,6 +16239,7 @@ function InlineDatePresetFilter({
|
|
|
15909
16239
|
) : badge)
|
|
15910
16240
|
] });
|
|
15911
16241
|
}
|
|
16242
|
+
var CSV_PASTE_SEPARATOR = /[,\r\n\t]+/;
|
|
15912
16243
|
var MATCH_MODE_OPTIONS = [
|
|
15913
16244
|
{ value: "contains", label: "\uD3EC\uD568" },
|
|
15914
16245
|
{ value: "exact", label: "\uC77C\uCE58" }
|
|
@@ -15921,20 +16252,61 @@ function KeywordEditor({
|
|
|
15921
16252
|
field,
|
|
15922
16253
|
value,
|
|
15923
16254
|
disabled,
|
|
15924
|
-
onValueChange
|
|
16255
|
+
onValueChange,
|
|
16256
|
+
onValueCommit
|
|
15925
16257
|
}) {
|
|
15926
16258
|
const entries3 = keywordEntries(value);
|
|
15927
16259
|
const [draft, setDraft] = react.useState("");
|
|
15928
16260
|
const [mode, setMode] = react.useState(
|
|
15929
16261
|
isKeywordValue(value) ? value.mode : "contains"
|
|
15930
16262
|
);
|
|
15931
|
-
const
|
|
15932
|
-
|
|
16263
|
+
const inputRef = react.useRef(null);
|
|
16264
|
+
react.useEffect(() => {
|
|
16265
|
+
if (disabled) return;
|
|
16266
|
+
inputRef.current?.focus();
|
|
16267
|
+
}, [disabled]);
|
|
16268
|
+
const emit3 = (nextEntries, nextMode = mode) => {
|
|
16269
|
+
onValueChange(field.matchModes ? { keywords: nextEntries, mode: nextMode } : nextEntries);
|
|
15933
16270
|
};
|
|
15934
|
-
const
|
|
16271
|
+
const commit = (nextEntries) => {
|
|
16272
|
+
onValueCommit(field.matchModes ? { keywords: nextEntries, mode } : nextEntries);
|
|
16273
|
+
};
|
|
16274
|
+
const changeMode = (next) => {
|
|
16275
|
+
setMode(next);
|
|
16276
|
+
emit3(entries3, next);
|
|
16277
|
+
};
|
|
16278
|
+
const newEntries = (candidates) => candidates.reduce((acc, raw) => {
|
|
15935
16279
|
const next = raw.trim();
|
|
15936
|
-
if (next === "" || entries3.includes(next)) return;
|
|
15937
|
-
|
|
16280
|
+
if (next === "" || entries3.includes(next) || acc.includes(next)) return acc;
|
|
16281
|
+
return [...acc, next];
|
|
16282
|
+
}, []);
|
|
16283
|
+
const addEntry = (raw) => {
|
|
16284
|
+
const added = newEntries([raw]);
|
|
16285
|
+
if (added.length === 0) {
|
|
16286
|
+
setDraft("");
|
|
16287
|
+
return;
|
|
16288
|
+
}
|
|
16289
|
+
commit([...entries3, ...added]);
|
|
16290
|
+
setDraft("");
|
|
16291
|
+
};
|
|
16292
|
+
const changeDraft = (next) => {
|
|
16293
|
+
if (field.input !== "csv" || !next.includes(",")) {
|
|
16294
|
+
setDraft(next);
|
|
16295
|
+
return;
|
|
16296
|
+
}
|
|
16297
|
+
const parts = next.split(",");
|
|
16298
|
+
const tail = parts.pop() ?? "";
|
|
16299
|
+
const added = newEntries(parts);
|
|
16300
|
+
if (added.length > 0) commit([...entries3, ...added]);
|
|
16301
|
+
setDraft(tail);
|
|
16302
|
+
};
|
|
16303
|
+
const onPaste = (event) => {
|
|
16304
|
+
if (field.input !== "csv") return;
|
|
16305
|
+
const text = event.clipboardData.getData("text");
|
|
16306
|
+
if (!CSV_PASTE_SEPARATOR.test(text)) return;
|
|
16307
|
+
event.preventDefault();
|
|
16308
|
+
const added = newEntries((draft + text).split(CSV_PASTE_SEPARATOR));
|
|
16309
|
+
if (added.length > 0) commit([...entries3, ...added]);
|
|
15938
16310
|
setDraft("");
|
|
15939
16311
|
};
|
|
15940
16312
|
const removeEntry = (entry) => {
|
|
@@ -15966,7 +16338,7 @@ function KeywordEditor({
|
|
|
15966
16338
|
options: field.excludeMode ? [...MATCH_MODE_OPTIONS, EXCLUDE_MATCH_MODE_OPTION] : MATCH_MODE_OPTIONS,
|
|
15967
16339
|
value: mode,
|
|
15968
16340
|
disabled,
|
|
15969
|
-
onValueChange: (next) =>
|
|
16341
|
+
onValueChange: (next) => changeMode(next)
|
|
15970
16342
|
}
|
|
15971
16343
|
)
|
|
15972
16344
|
] }),
|
|
@@ -15975,10 +16347,12 @@ function KeywordEditor({
|
|
|
15975
16347
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15976
16348
|
"input",
|
|
15977
16349
|
{
|
|
16350
|
+
ref: inputRef,
|
|
15978
16351
|
value: draft,
|
|
15979
16352
|
disabled,
|
|
15980
|
-
placeholder: field.placeholder ?? "\uC785\uB825 \uD6C4 Enter\uB85C \uCD94\uAC00",
|
|
15981
|
-
onChange: (event) =>
|
|
16353
|
+
placeholder: field.placeholder ?? (field.input === "csv" ? "\uB2E4\uC911 \uD0A4\uC6CC\uB4DC\uB294 \uCF64\uB9C8(,)\uB85C \uAD6C\uBD84" : "\uC785\uB825 \uD6C4 Enter\uB85C \uCD94\uAC00"),
|
|
16354
|
+
onChange: (event) => changeDraft(event.target.value),
|
|
16355
|
+
onPaste,
|
|
15982
16356
|
onKeyDown,
|
|
15983
16357
|
className: "min-w-0 flex-1 border-none bg-transparent text-[12px] leading-[20px] text-[color:var(--sys-color-field-text-default)] outline-none placeholder:text-[color:var(--sys-color-field-text-placeholder)] disabled:cursor-not-allowed"
|
|
15984
16358
|
}
|