sellmate-design-system-react 9.0.0-beta.18 → 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/dist/index.js CHANGED
@@ -3463,6 +3463,7 @@ var SDraggableItemView = /* @__PURE__ */ forwardRef(
3463
3463
  supportingText,
3464
3464
  supportingTextPosition,
3465
3465
  trailing,
3466
+ depth,
3466
3467
  accentStripe,
3467
3468
  bordered,
3468
3469
  selected,
@@ -3474,6 +3475,7 @@ var SDraggableItemView = /* @__PURE__ */ forwardRef(
3474
3475
  dragHandleProps,
3475
3476
  onDragHandleMouseDown,
3476
3477
  className,
3478
+ style,
3477
3479
  ...rest
3478
3480
  }, ref) {
3479
3481
  const renderState = { hovered, dragging, disabled };
@@ -3483,12 +3485,19 @@ var SDraggableItemView = /* @__PURE__ */ forwardRef(
3483
3485
  const trailingNode = renderSlot(trailing, renderState);
3484
3486
  const titleTypo = size === "sm" ? selected ? "typo-item-sm-selected" : "typo-item-sm-default" : selected ? "typo-item-md-selected" : "typo-item-md-default";
3485
3487
  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)";
3488
+ const normalizedDepth = Math.max(1, Math.floor(depth));
3489
+ const depthOffset = (normalizedDepth - 1) * 20;
3490
+ const depthStyle = depthOffset === 0 ? style : {
3491
+ ...style,
3492
+ paddingLeft: `calc(var(--cmp-listDraggableItem-paddingX) + ${depthOffset}px)`
3493
+ };
3486
3494
  return /* @__PURE__ */ jsxs(
3487
3495
  "div",
3488
3496
  {
3489
3497
  ref,
3490
3498
  "aria-disabled": disabled || void 0,
3491
3499
  "data-dragging": dragging || void 0,
3500
+ style: depthStyle,
3492
3501
  className: cn(
3493
3502
  "relative flex w-full items-center gap-(--cmp-listDraggableItem-gap) overflow-hidden px-(--cmp-listDraggableItem-paddingX)",
3494
3503
  titleTypo,
@@ -3577,6 +3586,7 @@ var SDraggableItemImpl = /* @__PURE__ */ forwardRef(function SDraggableItem({
3577
3586
  supportingText,
3578
3587
  supportingTextPosition = "right",
3579
3588
  trailing,
3589
+ depth = 1,
3580
3590
  accentStripe = false,
3581
3591
  bordered = false,
3582
3592
  selected = false,
@@ -3650,6 +3660,7 @@ var SDraggableItemImpl = /* @__PURE__ */ forwardRef(function SDraggableItem({
3650
3660
  supportingText,
3651
3661
  supportingTextPosition,
3652
3662
  trailing,
3663
+ depth,
3653
3664
  accentStripe,
3654
3665
  bordered,
3655
3666
  selected,
@@ -3685,6 +3696,7 @@ var SDraggableItemImpl = /* @__PURE__ */ forwardRef(function SDraggableItem({
3685
3696
  supportingText,
3686
3697
  supportingTextPosition,
3687
3698
  trailing,
3699
+ depth,
3688
3700
  accentStripe,
3689
3701
  bordered,
3690
3702
  selected,
@@ -3934,6 +3946,42 @@ function reorder(items, fromIndex, toIndex) {
3934
3946
  nextItems.splice(toIndex, 0, movedItem);
3935
3947
  return nextItems;
3936
3948
  }
3949
+ function clampDepth(depth, maxDepth) {
3950
+ return Math.max(1, Math.min(maxDepth, Math.floor(depth)));
3951
+ }
3952
+ function getSubtreeEnd(items, startIndex, getDepth) {
3953
+ const startDepth = getDepth(items[startIndex], startIndex);
3954
+ let endIndex = startIndex + 1;
3955
+ while (endIndex < items.length && getDepth(items[endIndex], endIndex) > startDepth) {
3956
+ endIndex += 1;
3957
+ }
3958
+ return endIndex;
3959
+ }
3960
+ function getInsertionIndex(items, target, getDepth) {
3961
+ if (target.intent === "before") return target.index;
3962
+ if (target.intent === "inside") return target.index + 1;
3963
+ return getSubtreeEnd(items, target.index, getDepth);
3964
+ }
3965
+ function moveWithDepth(items, fromIndex, target, getDepth, setDepth, maxDepth) {
3966
+ const fromEndIndex = getSubtreeEnd(items, fromIndex, getDepth);
3967
+ if (target.index >= fromIndex && target.index < fromEndIndex) return items;
3968
+ const movedItems = items.slice(fromIndex, fromEndIndex);
3969
+ const remainingItems = [...items.slice(0, fromIndex), ...items.slice(fromEndIndex)];
3970
+ const rawInsertionIndex = getInsertionIndex(items, target, getDepth);
3971
+ const insertionIndex = rawInsertionIndex > fromIndex ? rawInsertionIndex - movedItems.length : rawInsertionIndex;
3972
+ const sourceDepth = getDepth(items[fromIndex], fromIndex);
3973
+ const targetDepth = getDepth(items[target.index], target.index);
3974
+ const nextDepth = target.intent === "inside" ? targetDepth + 1 : targetDepth;
3975
+ const depthDelta = clampDepth(nextDepth, maxDepth) - sourceDepth;
3976
+ const nextMovedItems = setDepth && depthDelta !== 0 ? movedItems.map(
3977
+ (item, index) => setDepth(item, clampDepth(getDepth(item, fromIndex + index) + depthDelta, maxDepth))
3978
+ ) : movedItems;
3979
+ return [
3980
+ ...remainingItems.slice(0, insertionIndex),
3981
+ ...nextMovedItems,
3982
+ ...remainingItems.slice(insertionIndex)
3983
+ ];
3984
+ }
3937
3985
  function SDraggableListInner({
3938
3986
  items,
3939
3987
  getKey,
@@ -3943,6 +3991,10 @@ function SDraggableListInner({
3943
3991
  defaultSelectedKey,
3944
3992
  onSelectedKeyChange,
3945
3993
  getDisabled,
3994
+ getDepth,
3995
+ setDepth,
3996
+ getCanHaveChildren,
3997
+ maxDepth = 3,
3946
3998
  listId,
3947
3999
  group: groupName,
3948
4000
  useGap,
@@ -3952,19 +4004,24 @@ function SDraggableListInner({
3952
4004
  const dragContext = useSDraggableGroup();
3953
4005
  const dragGroup = groupName ?? dragContext?.defaultGroup;
3954
4006
  const [draggingIndex, setDraggingIndex] = useState(null);
3955
- const [dropIndex, setDropIndex] = useState(null);
4007
+ const [dropTarget, setDropTarget] = useState(null);
3956
4008
  const [internalSelectedKey, setInternalSelectedKey] = useState(
3957
4009
  defaultSelectedKey
3958
4010
  );
3959
4011
  const listRef = useRef(null);
3960
4012
  const fromIndexRef = useRef(null);
3961
4013
  const currentSelectedKey = selectedKey ?? internalSelectedKey;
4014
+ const usesDepth = getDepth != null;
3962
4015
  const startDrag = useCallback((event, index) => {
3963
4016
  event.preventDefault();
3964
4017
  fromIndexRef.current = index;
3965
4018
  setDraggingIndex(index);
3966
- setDropIndex(index);
4019
+ setDropTarget({ index, intent: "before" });
3967
4020
  }, []);
4021
+ const readDepth = useCallback(
4022
+ (item, index) => clampDepth(getDepth?.(item, index) ?? 1, maxDepth),
4023
+ [getDepth, maxDepth]
4024
+ );
3968
4025
  useEffect(() => {
3969
4026
  if (dragContext || draggingIndex == null) return void 0;
3970
4027
  const handleMouseMove = (event) => {
@@ -3972,25 +4029,65 @@ function SDraggableListInner({
3972
4029
  "[data-draggable-list-item]"
3973
4030
  );
3974
4031
  if (!itemElements) return;
3975
- let nextDropIndex = items.length;
3976
- itemElements.forEach((itemElement, index) => {
4032
+ let nextDropTarget = items.length === 0 ? { index: 0, intent: "before" } : { index: items.length - 1, intent: "after" };
4033
+ const draggingEndIndex = usesDepth && draggingIndex != null ? getSubtreeEnd(items, draggingIndex, readDepth) : draggingIndex + 1;
4034
+ let previousDropIndex = null;
4035
+ for (let index = 0; index < itemElements.length; index += 1) {
4036
+ const itemElement = itemElements[index];
3977
4037
  const rect = itemElement.getBoundingClientRect();
3978
- if (event.clientY < rect.top + rect.height / 2 && nextDropIndex === items.length) {
3979
- nextDropIndex = index;
4038
+ if (index >= draggingIndex && index < draggingEndIndex) {
4039
+ if (event.clientY <= rect.bottom) {
4040
+ if (previousDropIndex != null) {
4041
+ nextDropTarget = { index: previousDropIndex, intent: "after" };
4042
+ } else {
4043
+ nextDropTarget = { index: draggingIndex, intent: "before" };
4044
+ }
4045
+ break;
4046
+ }
4047
+ continue;
3980
4048
  }
3981
- });
3982
- setDropIndex(nextDropIndex);
4049
+ if (event.clientY < rect.top) {
4050
+ nextDropTarget = { index, intent: "before" };
4051
+ break;
4052
+ }
4053
+ if (event.clientY > rect.bottom) {
4054
+ previousDropIndex = index;
4055
+ nextDropTarget = { index, intent: "after" };
4056
+ continue;
4057
+ }
4058
+ const ratio = (event.clientY - rect.top) / rect.height;
4059
+ if (!usesDepth) {
4060
+ nextDropTarget = ratio < 0.5 ? { index, intent: "before" } : { index, intent: "after" };
4061
+ break;
4062
+ }
4063
+ const item = items[index];
4064
+ const canHaveChildren = (getCanHaveChildren?.(item, index) ?? true) && readDepth(item, index) < maxDepth;
4065
+ if (ratio < 0.25) {
4066
+ nextDropTarget = { index, intent: "before" };
4067
+ } else if (ratio > 0.75 || !canHaveChildren) {
4068
+ nextDropTarget = { index, intent: "after" };
4069
+ } else {
4070
+ nextDropTarget = { index, intent: "inside" };
4071
+ }
4072
+ break;
4073
+ }
4074
+ setDropTarget(nextDropTarget);
3983
4075
  };
3984
4076
  const handleMouseUp = () => {
3985
4077
  const fromIndex = fromIndexRef.current;
3986
- const nextDropIndex = dropIndex;
3987
- if (fromIndex != null && nextDropIndex != null) {
3988
- const toIndex = nextDropIndex > fromIndex ? nextDropIndex - 1 : nextDropIndex;
3989
- if (fromIndex !== toIndex) onChange?.(reorder(items, fromIndex, toIndex));
4078
+ const nextDropTarget = dropTarget;
4079
+ if (fromIndex != null && nextDropTarget != null && items[nextDropTarget.index]) {
4080
+ const insertionIndex = getInsertionIndex(items, nextDropTarget, () => 1);
4081
+ const nextItems = usesDepth ? moveWithDepth(items, fromIndex, nextDropTarget, readDepth, setDepth, maxDepth) : reorder(
4082
+ items,
4083
+ fromIndex,
4084
+ insertionIndex > fromIndex ? insertionIndex - 1 : insertionIndex
4085
+ );
4086
+ if (nextItems !== items) onChange?.(nextItems);
3990
4087
  }
3991
4088
  fromIndexRef.current = null;
3992
4089
  setDraggingIndex(null);
3993
- setDropIndex(null);
4090
+ setDropTarget(null);
3994
4091
  };
3995
4092
  window.addEventListener("mousemove", handleMouseMove);
3996
4093
  window.addEventListener("mouseup", handleMouseUp);
@@ -3998,12 +4095,25 @@ function SDraggableListInner({
3998
4095
  window.removeEventListener("mousemove", handleMouseMove);
3999
4096
  window.removeEventListener("mouseup", handleMouseUp);
4000
4097
  };
4001
- }, [draggingIndex, dropIndex, items, onChange, dragContext]);
4098
+ }, [
4099
+ draggingIndex,
4100
+ dropTarget,
4101
+ items,
4102
+ onChange,
4103
+ dragContext,
4104
+ getDepth,
4105
+ usesDepth,
4106
+ readDepth,
4107
+ setDepth,
4108
+ maxDepth,
4109
+ getCanHaveChildren
4110
+ ]);
4002
4111
  if (dragContext && (!listId || !dragGroup)) {
4003
4112
  throw new Error("SDraggableList: Provider \uC548\uC5D0\uC11C\uB294 group\uACFC listId\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.");
4004
4113
  }
4005
4114
  const groupDrop = dragContext?.drop;
4006
- const currentDropIndex = dragContext ? groupDrop?.group === dragGroup && groupDrop?.listId === listId ? groupDrop?.index ?? null : null : dropIndex;
4115
+ const currentDropIndex = dragContext ? groupDrop?.group === dragGroup && groupDrop?.listId === listId ? groupDrop?.index ?? null : null : dropTarget?.index;
4116
+ const currentDropIntent = dragContext ? void 0 : dropTarget?.intent;
4007
4117
  const isDropTarget = dragContext ? groupDrop?.group === dragGroup && groupDrop?.listId === listId : draggingIndex != null;
4008
4118
  const showEmptyDrop = Boolean(dragContext && isDropTarget && items.length === 0);
4009
4119
  const beforeIndicatorPosition = useGap ? "before:top-[-5px]" : "before:top-0";
@@ -4034,19 +4144,30 @@ function SDraggableListInner({
4034
4144
  children: items.map((item, index) => {
4035
4145
  const itemKey = getKey(item, index);
4036
4146
  const disabled = getDisabled?.(item, index) ?? false;
4037
- const showBefore = isDropTarget && currentDropIndex === index;
4038
- const showAfter = isDropTarget && currentDropIndex === items.length && index === items.length - 1;
4147
+ const depth = readDepth(item, index);
4148
+ const showBefore = isDropTarget && currentDropIndex === index && (dragContext || currentDropIntent === "before");
4149
+ const showInside = isDropTarget && currentDropIndex === index && !dragContext && usesDepth && currentDropIntent === "inside";
4150
+ const showAfter = isDropTarget && (dragContext ? currentDropIndex === items.length && index === items.length - 1 : currentDropIndex === index && currentDropIntent === "after");
4151
+ const selectItem = () => {
4152
+ if (disabled) return;
4153
+ setInternalSelectedKey(itemKey);
4154
+ onSelectedKeyChange?.(itemKey);
4155
+ };
4156
+ const handleItemKeyDown = (event) => {
4157
+ if (event.key !== "Enter" && event.key !== " ") return;
4158
+ event.preventDefault();
4159
+ selectItem();
4160
+ };
4039
4161
  return /* @__PURE__ */ jsx(
4040
4162
  "div",
4041
4163
  {
4042
4164
  "data-draggable-list-item": true,
4165
+ role: "button",
4166
+ tabIndex: disabled ? -1 : 0,
4043
4167
  "aria-disabled": disabled || void 0,
4044
- onClick: () => {
4045
- if (disabled) return;
4046
- setInternalSelectedKey(itemKey);
4047
- onSelectedKeyChange?.(itemKey);
4048
- },
4049
- 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-['']` : ""}`,
4168
+ onClick: selectItem,
4169
+ onKeyDown: handleItemKeyDown,
4170
+ 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)" : ""}`,
4050
4171
  children: renderItem(item, index, {
4051
4172
  onDragHandleMouseDown: (event) => {
4052
4173
  if (disabled) return;
@@ -4054,7 +4175,8 @@ function SDraggableListInner({
4054
4175
  dragContext.startDrag(event, dragGroup, listId, index, itemKey);
4055
4176
  } else startDrag(event, index);
4056
4177
  },
4057
- selected: currentSelectedKey === itemKey
4178
+ selected: currentSelectedKey === itemKey,
4179
+ depth
4058
4180
  })
4059
4181
  },
4060
4182
  itemKey
@@ -15902,13 +16024,11 @@ function PeriodPresetEditor({
15902
16024
  }
15903
16025
  if (selectedUnit === "quarter") {
15904
16026
  return /* @__PURE__ */ jsx(
15905
- SSelect2,
16027
+ SRadioButton,
15906
16028
  {
15907
16029
  value: typeof periodValue.value === "number" ? periodValue.value : 1,
15908
16030
  onValueChange: updateInputValue,
15909
- emitValue: true,
15910
16031
  disabled,
15911
- width: "100%",
15912
16032
  options: [
15913
16033
  { value: 1, label: "1\uBD84\uAE30" },
15914
16034
  { value: 2, label: "2\uBD84\uAE30" },
@@ -15920,13 +16040,11 @@ function PeriodPresetEditor({
15920
16040
  }
15921
16041
  if (selectedUnit === "half") {
15922
16042
  return /* @__PURE__ */ jsx(
15923
- SSelect2,
16043
+ SRadioButton,
15924
16044
  {
15925
16045
  value: typeof periodValue.value === "string" ? periodValue.value : "first",
15926
16046
  onValueChange: updateInputValue,
15927
- emitValue: true,
15928
16047
  disabled,
15929
- width: "100%",
15930
16048
  options: [
15931
16049
  { value: "first", label: "\uC0C1\uBC18\uAE30" },
15932
16050
  { value: "second", label: "\uD558\uBC18\uAE30" }
@@ -15972,7 +16090,6 @@ function PeriodPresetEditor({
15972
16090
  },
15973
16091
  preset.value
15974
16092
  )) }),
15975
- /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "h-px w-full", style: { background: CHIPFILTER.listboxBorder } }),
15976
16093
  /* @__PURE__ */ jsx("div", { className: "w-full [&>*]:w-full", children: renderInput() })
15977
16094
  ] });
15978
16095
  }