sellmate-design-system-react 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/components/SCallout/SCallout.cjs +76 -1
  2. package/dist/components/SCallout/SCallout.cjs.map +1 -1
  3. package/dist/components/SCallout/SCallout.d.ts +6 -2
  4. package/dist/components/SCallout/SCallout.js +76 -1
  5. package/dist/components/SCallout/SCallout.js.map +1 -1
  6. package/dist/components/SDraggableItem/SDraggableItem.cjs +3079 -0
  7. package/dist/components/SDraggableItem/SDraggableItem.cjs.map +1 -0
  8. package/dist/components/SDraggableItem/SDraggableItem.d.ts +33 -0
  9. package/dist/components/SDraggableItem/SDraggableItem.js +3077 -0
  10. package/dist/components/SDraggableItem/SDraggableItem.js.map +1 -0
  11. package/dist/components/SDraggableItem/index.d.ts +1 -0
  12. package/dist/components/SExpansionItem/SExpansionItem.cjs +6 -15
  13. package/dist/components/SExpansionItem/SExpansionItem.cjs.map +1 -1
  14. package/dist/components/SExpansionItem/SExpansionItem.js +6 -15
  15. package/dist/components/SExpansionItem/SExpansionItem.js.map +1 -1
  16. package/dist/components/SList/SList.cjs +38 -0
  17. package/dist/components/SList/SList.cjs.map +1 -0
  18. package/dist/components/SList/SList.d.ts +10 -0
  19. package/dist/components/SList/SList.js +36 -0
  20. package/dist/components/SList/SList.js.map +1 -0
  21. package/dist/components/SList/index.d.ts +1 -0
  22. package/dist/components/SListItem/SListItem.cjs +83 -0
  23. package/dist/components/SListItem/SListItem.cjs.map +1 -0
  24. package/dist/components/SListItem/SListItem.d.ts +26 -0
  25. package/dist/components/SListItem/SListItem.js +81 -0
  26. package/dist/components/SListItem/SListItem.js.map +1 -0
  27. package/dist/components/SListItem/index.d.ts +1 -0
  28. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.cjs +3414 -0
  29. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.cjs.map +1 -0
  30. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.d.ts +32 -0
  31. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.js +3392 -0
  32. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.js.map +1 -0
  33. package/dist/components/SSectionHeaderCard/index.d.ts +1 -0
  34. package/dist/index.cjs +815 -419
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.ts +4 -0
  37. package/dist/index.js +815 -423
  38. package/dist/index.js.map +1 -1
  39. package/dist/styles.css +336 -19
  40. package/dist/theme.css +14 -0
  41. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -6,10 +6,10 @@ var tailwindMerge = require('tailwind-merge');
6
6
  var react = require('react');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
  var reactDom = require('react-dom');
9
+ var RPopover2 = require('@radix-ui/react-popover');
9
10
  var client = require('react-dom/client');
10
11
  var RTooltip = require('@radix-ui/react-tooltip');
11
12
  var RDropdown = require('@radix-ui/react-dropdown-menu');
12
- var RPopover2 = require('@radix-ui/react-popover');
13
13
  var RSwitch = require('@radix-ui/react-switch');
14
14
  var RDialog = require('@radix-ui/react-dialog');
15
15
  var RCheckbox = require('@radix-ui/react-checkbox');
@@ -33,9 +33,9 @@ function _interopNamespace(e) {
33
33
  return Object.freeze(n);
34
34
  }
35
35
 
36
+ var RPopover2__namespace = /*#__PURE__*/_interopNamespace(RPopover2);
36
37
  var RTooltip__namespace = /*#__PURE__*/_interopNamespace(RTooltip);
37
38
  var RDropdown__namespace = /*#__PURE__*/_interopNamespace(RDropdown);
38
- var RPopover2__namespace = /*#__PURE__*/_interopNamespace(RPopover2);
39
39
  var RSwitch__namespace = /*#__PURE__*/_interopNamespace(RSwitch);
40
40
  var RDialog__namespace = /*#__PURE__*/_interopNamespace(RDialog);
41
41
  var RCheckbox__namespace = /*#__PURE__*/_interopNamespace(RCheckbox);
@@ -2920,6 +2920,227 @@ var SCard = react.forwardRef(function SCard2({ bordered = false, className, chil
2920
2920
  }
2921
2921
  );
2922
2922
  });
2923
+ var setRefs = (refs, value) => {
2924
+ refs.forEach((ref) => {
2925
+ if (typeof ref === "function") {
2926
+ ref(value);
2927
+ return;
2928
+ }
2929
+ if (ref) {
2930
+ ref.current = value;
2931
+ }
2932
+ });
2933
+ };
2934
+ function renderSlot(slot, state2) {
2935
+ return typeof slot === "function" ? slot(state2) : slot;
2936
+ }
2937
+ var SDraggableItemView = react.forwardRef(
2938
+ function SDraggableItemView2({
2939
+ title,
2940
+ trailing,
2941
+ accentStripe,
2942
+ bordered,
2943
+ selected,
2944
+ dense,
2945
+ dragging,
2946
+ disabled,
2947
+ hovered,
2948
+ dragHandleProps,
2949
+ onDragHandleMouseDown,
2950
+ className,
2951
+ ...rest
2952
+ }, ref) {
2953
+ const renderState = { hovered, dragging, disabled };
2954
+ const titleNode = renderSlot(title, renderState);
2955
+ const trailingNode = renderSlot(trailing, renderState);
2956
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2957
+ "div",
2958
+ {
2959
+ ref,
2960
+ "aria-disabled": disabled || void 0,
2961
+ "data-dragging": dragging || void 0,
2962
+ className: cn(
2963
+ "relative flex w-full items-center gap-(--cmp-listDraggableItem-gap) overflow-hidden px-(--cmp-listDraggableItem-paddingX) text-[12px] leading-[20px]",
2964
+ disabled ? "bg-(--cmp-listDraggableItem-bg-default) font-medium text-(--sys-color-disabled-text)" : selected ? "bg-(--cmp-listDraggableItem-bg-selected) font-bold text-(--cmp-listDraggableItem-text-selected)" : "bg-(--cmp-listDraggableItem-bg-default) font-medium text-(--cmp-listDraggableItem-text-default)",
2965
+ !disabled && !selected && !dragging && "hover:bg-(--cmp-listDraggableItem-bg-hover)",
2966
+ dense ? "h-[32px] py-(--cmp-listDraggableItem-paddingY-dense)" : "h-[40px] py-(--cmp-listDraggableItem-paddingY-normal)",
2967
+ bordered ? cn(
2968
+ "rounded-(--cmp-listDraggableItem-radius-bordered) border border-(--cmp-listDraggableItem-border-default)",
2969
+ !disabled && !selected && !dragging && "hover:border-(--cmp-listDraggableItem-bordered-border-hover)",
2970
+ !disabled && selected && !dragging && "border-(--cmp-listDraggableItem-bordered-border-selected)",
2971
+ !disabled && selected && dragging && "border-[length:var(--cmp-listDraggableItem-bordered-dragging-border-width)] border-(--cmp-listDraggableItem-bordered-dragging-border-color) bg-(--cmp-listDraggableItem-bordered-dragging-bg)"
2972
+ ) : "border-b border-(--cmp-listDraggableItem-border-default)",
2973
+ disabled && "cursor-not-allowed",
2974
+ className
2975
+ ),
2976
+ ...rest,
2977
+ children: [
2978
+ accentStripe && !bordered && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
2979
+ "span",
2980
+ {
2981
+ "aria-hidden": "true",
2982
+ className: "pointer-events-none absolute bottom-[-1px] left-0 top-0 w-(--cmp-listDraggableItem-accentStripe-width) bg-(--cmp-listDraggableItem-accentStripe-color)"
2983
+ }
2984
+ ),
2985
+ /* @__PURE__ */ jsxRuntime.jsx(
2986
+ "div",
2987
+ {
2988
+ ...dragHandleProps,
2989
+ role: dragHandleProps?.role ?? "button",
2990
+ tabIndex: dragHandleProps?.tabIndex ?? (disabled ? -1 : 0),
2991
+ "aria-label": dragHandleProps?.["aria-label"] ?? "\uB4DC\uB798\uADF8 \uD578\uB4E4",
2992
+ "aria-disabled": disabled || void 0,
2993
+ onMouseDown: onDragHandleMouseDown,
2994
+ className: cn(
2995
+ "flex size-[24px] shrink-0 select-none items-center justify-center rounded-[4px]",
2996
+ disabled ? "cursor-not-allowed opacity-0" : "cursor-grab hover:bg-black/5 active:cursor-grabbing",
2997
+ dragging && "bg-black/5",
2998
+ dragHandleProps?.className
2999
+ ),
3000
+ children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "drag", size: 16, color: "grey_65" })
3001
+ }
3002
+ ),
3003
+ /* @__PURE__ */ jsxRuntime.jsxs(
3004
+ "div",
3005
+ {
3006
+ className: cn(
3007
+ "flex min-w-0 flex-1 items-center gap-[8px]",
3008
+ dragging && "opacity-(--cmp-listDraggableItem-dragging-content-opacity)"
3009
+ ),
3010
+ children: [
3011
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: titleNode }),
3012
+ trailingNode
3013
+ ]
3014
+ }
3015
+ )
3016
+ ]
3017
+ }
3018
+ );
3019
+ }
3020
+ );
3021
+ var SDraggableItem = react.forwardRef(
3022
+ function SDraggableItem2({
3023
+ title,
3024
+ trailing,
3025
+ accentStripe = false,
3026
+ bordered = false,
3027
+ selected = false,
3028
+ dense = false,
3029
+ disabled = false,
3030
+ dragOverlay = true,
3031
+ dragOverlayOpacity = 0.75,
3032
+ dragHandleProps,
3033
+ onDragHandleMouseDown,
3034
+ className,
3035
+ onMouseEnter,
3036
+ onMouseLeave,
3037
+ ...rest
3038
+ }, ref) {
3039
+ const [hovered, setHovered] = react.useState(false);
3040
+ const [overlay, setOverlay] = react.useState(null);
3041
+ const rootRef = react.useRef(null);
3042
+ const overlayVisible = overlay != null;
3043
+ const handleMouseEnter = (event) => {
3044
+ if (!disabled) setHovered(true);
3045
+ onMouseEnter?.(event);
3046
+ };
3047
+ const handleMouseLeave = (event) => {
3048
+ setHovered(false);
3049
+ onMouseLeave?.(event);
3050
+ };
3051
+ const handleDragMouseDown = (event) => {
3052
+ if (disabled) return;
3053
+ const rect = rootRef.current?.getBoundingClientRect();
3054
+ if (dragOverlay && rect) {
3055
+ setOverlay({
3056
+ offsetX: event.clientX - rect.left,
3057
+ offsetY: event.clientY - rect.top,
3058
+ rect,
3059
+ x: event.clientX,
3060
+ y: event.clientY
3061
+ });
3062
+ }
3063
+ dragHandleProps?.onMouseDown?.(event);
3064
+ onDragHandleMouseDown?.(event);
3065
+ };
3066
+ react.useEffect(() => {
3067
+ if (!overlayVisible) return void 0;
3068
+ const handleMouseMove = (event) => {
3069
+ setOverlay(
3070
+ (current) => current ? {
3071
+ ...current,
3072
+ x: event.clientX,
3073
+ y: event.clientY
3074
+ } : current
3075
+ );
3076
+ };
3077
+ const handleMouseUp = () => {
3078
+ setOverlay(null);
3079
+ };
3080
+ window.addEventListener("mousemove", handleMouseMove);
3081
+ window.addEventListener("mouseup", handleMouseUp);
3082
+ return () => {
3083
+ window.removeEventListener("mousemove", handleMouseMove);
3084
+ window.removeEventListener("mouseup", handleMouseUp);
3085
+ };
3086
+ }, [overlayVisible]);
3087
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3088
+ /* @__PURE__ */ jsxRuntime.jsx(
3089
+ SDraggableItemView,
3090
+ {
3091
+ ref: (node) => setRefs([rootRef, ref], node),
3092
+ title,
3093
+ trailing,
3094
+ accentStripe,
3095
+ bordered,
3096
+ selected,
3097
+ dense,
3098
+ dragging: overlayVisible,
3099
+ disabled,
3100
+ hovered,
3101
+ dragHandleProps,
3102
+ onDragHandleMouseDown: handleDragMouseDown,
3103
+ onMouseEnter: handleMouseEnter,
3104
+ onMouseLeave: handleMouseLeave,
3105
+ className,
3106
+ ...rest
3107
+ }
3108
+ ),
3109
+ overlay && typeof document !== "undefined" && reactDom.createPortal(
3110
+ /* @__PURE__ */ jsxRuntime.jsx(
3111
+ "div",
3112
+ {
3113
+ className: "pointer-events-none fixed z-[999999]",
3114
+ style: {
3115
+ left: overlay.x - overlay.offsetX,
3116
+ opacity: dragOverlayOpacity,
3117
+ top: overlay.y - overlay.offsetY,
3118
+ width: overlay.rect.width
3119
+ },
3120
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3121
+ SDraggableItemView,
3122
+ {
3123
+ title,
3124
+ trailing,
3125
+ accentStripe,
3126
+ bordered,
3127
+ selected,
3128
+ dense,
3129
+ dragging: true,
3130
+ disabled,
3131
+ hovered: true,
3132
+ dragHandleProps,
3133
+ className
3134
+ }
3135
+ )
3136
+ }
3137
+ ),
3138
+ document.body
3139
+ )
3140
+ ] });
3141
+ }
3142
+ );
3143
+ SDraggableItem.displayName = "SDraggableItem";
2923
3144
  var SExpansionItem = react.forwardRef(
2924
3145
  function SExpansionItem2({
2925
3146
  title,
@@ -2946,7 +3167,7 @@ var SExpansionItem = react.forwardRef(
2946
3167
  {
2947
3168
  ref,
2948
3169
  className: cn(
2949
- "group/expansion-item overflow-hidden bg-[var(--cmp-listExpansionItem-title-bg-default)]",
3170
+ "group/expansion-item overflow-hidden bg-(--cmp-listExpansionItem-title-bg-default)",
2950
3171
  // TODO: expansionItem/bordered/radius 및 border intent 토큰 생성 후 고정값을 토큰으로 교체한다.
2951
3172
  bordered && "rounded-[8px] border border-[#E1E1E1] hover:border-[#AAAAAA] [&:has(>button:hover)]:border-[#AAAAAA]",
2952
3173
  bordered && isExpanded && "!border-[#93C4FF]",
@@ -2968,10 +3189,10 @@ var SExpansionItem = react.forwardRef(
2968
3189
  onToggle?.(next, event);
2969
3190
  },
2970
3191
  className: cn(
2971
- "flex w-full items-center justify-between border-0 text-left text-[14px] font-bold leading-[24px] text-[var(--cmp-listExpansionItem-title-text-default)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--sys-color-border-accent)] disabled:cursor-not-allowed disabled:text-[var(--sys-color-disabled-text)] cursor-pointer",
3192
+ "flex w-full cursor-pointer items-center justify-between border-0 text-left text-[14px] font-bold leading-[24px] text-(--cmp-listExpansionItem-title-text-default) focus-visible:outline focus-visible:outline-2 focus-visible:outline-(--sys-color-border-accent) disabled:cursor-not-allowed disabled:text-(--sys-color-disabled-text)",
2972
3193
  isExpanded && "border-b border-(--cmp-listExpansionItem-title-border)",
2973
3194
  !isExpanded && "hover:bg-(--cmp-listExpansionItem-title-bg-hover)",
2974
- dense ? "min-h-8 py-(--cmp-listExpansionItem-title-paddingY-dense)" : "min-h-10 py-(--cmp-listExpansionItem-title-paddingY-normal)",
3195
+ dense ? "h-[32px] py-(--cmp-listExpansionItem-title-paddingY-dense)" : "h-[40px] py-(--cmp-listExpansionItem-title-paddingY-normal)",
2975
3196
  "gap-(--cmp-listExpansionItem-title-gap)",
2976
3197
  "pr-(--cmp-listExpansionItem-title-paddingX)",
2977
3198
  depth === 2 ? "pl-[calc(var(--cmp-listExpansionItem-title-paddingX)+32px)]" : depth === 3 ? "pl-[calc(var(--cmp-listExpansionItem-title-paddingX)+64px)]" : "pl-(--cmp-listExpansionItem-title-paddingX)",
@@ -2985,7 +3206,7 @@ var SExpansionItem = react.forwardRef(
2985
3206
  "flex transition-transform duration-200 ease-out motion-reduce:transition-none",
2986
3207
  isExpanded && "rotate-180"
2987
3208
  ),
2988
- children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "caretDown", size: 12 })
3209
+ children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "caretDown", size: 12, color: "var(--sys-color-fg-quaternary)" })
2989
3210
  }
2990
3211
  ),
2991
3212
  leadingNode,
@@ -3000,19 +3221,10 @@ var SExpansionItem = react.forwardRef(
3000
3221
  id,
3001
3222
  "aria-hidden": !isExpanded,
3002
3223
  className: cn(
3003
- "grid overflow-hidden bg-[var(--cmp-listExpansionItem-body-bg)] transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none",
3224
+ "grid overflow-hidden bg-(--cmp-listExpansionItem-body-bg) transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none",
3004
3225
  isExpanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
3005
3226
  ),
3006
- children: /* @__PURE__ */ jsxRuntime.jsx(
3007
- "div",
3008
- {
3009
- className: cn(
3010
- "min-h-0 overflow-hidden",
3011
- bodyPadding && isExpanded && "p-(--cmp-listExpansionItem-body-padding)"
3012
- ),
3013
- children
3014
- }
3015
- )
3227
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(bodyPadding && "p-(--cmp-listExpansionItem-body-padding)"), children }) })
3016
3228
  }
3017
3229
  )
3018
3230
  ]
@@ -3020,69 +3232,182 @@ var SExpansionItem = react.forwardRef(
3020
3232
  );
3021
3233
  }
3022
3234
  );
3023
- var SDivider = react.forwardRef(function SDivider2({ vertical = false, className, style, ...rest }, ref) {
3235
+ var SList = react.forwardRef(function SList2({ className, children, useGap = false, usePadding = false, ...rest }, ref) {
3024
3236
  return /* @__PURE__ */ jsxRuntime.jsx(
3025
- "hr",
3237
+ "div",
3026
3238
  {
3027
3239
  ref,
3028
- "aria-orientation": vertical ? "vertical" : "horizontal",
3029
3240
  className: cn(
3030
- "shrink-0 border-0",
3031
- vertical ? "inline-block h-auto w-px self-stretch" : "block h-px w-full",
3241
+ useGap && "flex flex-col gap-(--cmp-list-group-gap)",
3242
+ usePadding && "p-(--cmp-list-group-padding)",
3032
3243
  className
3033
3244
  ),
3034
- style: { backgroundColor: "var(--sys-color-divider-default, #E1E1E1)", ...style },
3035
- ...rest
3245
+ ...rest,
3246
+ children
3036
3247
  }
3037
3248
  );
3038
3249
  });
3039
-
3040
- // src/lib/scrollbar.ts
3041
- var FIREFOX_SCROLLBAR_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-width:thin] supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_transparent]";
3042
- var SCROLLBAR_CLASS = `${FIREFOX_SCROLLBAR_CLASS} [&::-webkit-scrollbar]:h-[12px] [&::-webkit-scrollbar]:w-[12px] [&::-webkit-scrollbar]:bg-transparent [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:border-2 [&::-webkit-scrollbar-thumb]:border-solid [&::-webkit-scrollbar-thumb]:border-transparent [&::-webkit-scrollbar-thumb]:bg-[var(--color-grey-45)] [&::-webkit-scrollbar-thumb]:bg-clip-padding`;
3043
- var SCROLLBAR_HIDDEN_CLASS = "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden";
3044
- var SCROLLBAR_TRACK_BG_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_var(--color-grey-10)] [&::-webkit-scrollbar]:bg-[var(--color-grey-10)] [&::-webkit-scrollbar-track]:bg-[var(--color-grey-10)] [&::-webkit-scrollbar-corner]:bg-[var(--color-grey-10)]";
3045
- var SCROLLBAR_TRACK_BG_WHITE_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_var(--color-white)] [&::-webkit-scrollbar]:bg-[var(--color-white)] [&::-webkit-scrollbar-track]:bg-[var(--color-white)] [&::-webkit-scrollbar-corner]:bg-[var(--color-white)]";
3046
- var SCROLLBAR_TRACK_BORDER_CLASS = "[&::-webkit-scrollbar-track:vertical]:[border-left:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-track:horizontal]:[border-top:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-corner]:[border-top:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-corner]:[border-left:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-thumb:vertical]:[border-left-width:3px] [&::-webkit-scrollbar-thumb:horizontal]:[border-top-width:3px]";
3047
- var AXIS_CLASS = {
3048
- vertical: "overflow-x-hidden overflow-y-auto",
3049
- horizontal: "overflow-x-auto overflow-y-hidden",
3050
- both: "overflow-auto"
3051
- };
3052
- var SScrollArea = react.forwardRef(function SScrollArea2({
3053
- axis = "both",
3054
- background = false,
3250
+ SList.displayName = "SList";
3251
+ var SListItem = react.forwardRef(function SListItem2({
3252
+ title,
3253
+ depth = 1,
3254
+ leading,
3255
+ trailing,
3055
3256
  bordered = false,
3056
- maxHeight,
3057
- maxWidth,
3257
+ accentStripe = false,
3258
+ dense = false,
3259
+ disabled = false,
3058
3260
  className,
3059
- style,
3060
- children,
3261
+ onMouseEnter,
3262
+ onMouseLeave,
3061
3263
  ...rest
3062
3264
  }, ref) {
3063
- const mergedStyle = { ...style };
3064
- if (maxHeight) mergedStyle.maxHeight = maxHeight;
3065
- if (maxWidth) mergedStyle.maxWidth = maxWidth;
3066
- return /* @__PURE__ */ jsxRuntime.jsx(
3265
+ const [hovered, setHovered] = react.useState(false);
3266
+ const renderState = { hovered, disabled };
3267
+ const titleNode = typeof title === "function" ? title(renderState) : title;
3268
+ const leadingNode = typeof leading === "function" ? leading(renderState) : leading;
3269
+ const trailingNode = typeof trailing === "function" ? trailing(renderState) : trailing;
3270
+ const handleMouseEnter = (event) => {
3271
+ if (!disabled) setHovered(true);
3272
+ onMouseEnter?.(event);
3273
+ };
3274
+ const handleMouseLeave = (event) => {
3275
+ setHovered(false);
3276
+ onMouseLeave?.(event);
3277
+ };
3278
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3067
3279
  "div",
3068
3280
  {
3069
3281
  ref,
3282
+ "aria-disabled": disabled || void 0,
3283
+ onMouseEnter: handleMouseEnter,
3284
+ onMouseLeave: handleMouseLeave,
3070
3285
  className: cn(
3071
- AXIS_CLASS[axis],
3072
- SCROLLBAR_CLASS,
3073
- background && SCROLLBAR_TRACK_BG_CLASS,
3074
- bordered && SCROLLBAR_TRACK_BORDER_CLASS,
3286
+ "group/list-item relative flex w-full items-center justify-between bg-(--cmp-listItem-bg-default) text-left text-[14px] font-bold leading-[24px] text-(--cmp-listItem-text-default)",
3287
+ disabled ? "pointer-events-none cursor-not-allowed text-(--sys-color-disabled-text)" : "hover:bg-(--cmp-listItem-bg-hover)",
3288
+ dense ? "h-[32px] py-(--cmp-listItem-paddingY-dense)" : "h-[40px] py-(--cmp-listItem-paddingY-normal)",
3289
+ "gap-(--cmp-listItem-gap)",
3290
+ "pr-(--cmp-listItem-paddingX)",
3291
+ depth === 2 ? "pl-[calc(var(--cmp-listItem-paddingX)+32px)]" : depth === 3 ? "pl-[calc(var(--cmp-listItem-paddingX)+64px)]" : "pl-(--cmp-listItem-paddingX)",
3292
+ bordered ? "overflow-hidden rounded-(--cmp-listItem-radius-bordered) border border-(--cmp-listItem-border-default) hover:border-(--cmp-listItem-bordered-border-hover)" : "border-b border-(--cmp-listItem-border-default)",
3075
3293
  className
3076
3294
  ),
3077
- style: mergedStyle,
3078
3295
  ...rest,
3079
- children
3296
+ children: [
3297
+ accentStripe && !bordered && /* @__PURE__ */ jsxRuntime.jsx(
3298
+ "span",
3299
+ {
3300
+ "aria-hidden": "true",
3301
+ className: "pointer-events-none absolute bottom-[-1px] left-0 top-0 w-(--cmp-listItem-accentStripe-width) bg-(--cmp-listItem-accentStripe-color)"
3302
+ }
3303
+ ),
3304
+ leadingNode,
3305
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex min-w-0 flex-1 flex-col", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: titleNode }) }),
3306
+ trailingNode
3307
+ ]
3080
3308
  }
3081
3309
  );
3082
3310
  });
3311
+ SListItem.displayName = "SListItem";
3083
3312
 
3084
- // src/components/SScrollArea/scrollArea.config.ts
3085
- var SCROLL_AREA_AXES = ["vertical", "horizontal", "both"];
3313
+ // src/lib/floating-anim.ts
3314
+ var FLOATING_SLIDE_ANIM = [
3315
+ "data-[state=open]:data-[side=top]:animate-floating-in-top",
3316
+ "data-[state=delayed-open]:data-[side=top]:animate-floating-in-top",
3317
+ "data-[state=instant-open]:data-[side=top]:animate-floating-in-top",
3318
+ "data-[state=closed]:data-[side=top]:animate-floating-out-top",
3319
+ "data-[state=open]:data-[side=bottom]:animate-floating-in-bottom",
3320
+ "data-[state=delayed-open]:data-[side=bottom]:animate-floating-in-bottom",
3321
+ "data-[state=instant-open]:data-[side=bottom]:animate-floating-in-bottom",
3322
+ "data-[state=closed]:data-[side=bottom]:animate-floating-out-bottom",
3323
+ "data-[state=open]:data-[side=left]:animate-floating-in-left",
3324
+ "data-[state=delayed-open]:data-[side=left]:animate-floating-in-left",
3325
+ "data-[state=instant-open]:data-[side=left]:animate-floating-in-left",
3326
+ "data-[state=closed]:data-[side=left]:animate-floating-out-left",
3327
+ "data-[state=open]:data-[side=right]:animate-floating-in-right",
3328
+ "data-[state=delayed-open]:data-[side=right]:animate-floating-in-right",
3329
+ "data-[state=instant-open]:data-[side=right]:animate-floating-in-right",
3330
+ "data-[state=closed]:data-[side=right]:animate-floating-out-right"
3331
+ ].join(" ");
3332
+ var PortalContainerContext = react.createContext(null);
3333
+ var InsideModalContext = react.createContext(false);
3334
+ var PortalContainerProvider = PortalContainerContext.Provider;
3335
+ var InsideModalProvider = InsideModalContext.Provider;
3336
+ function usePortalContainer() {
3337
+ return react.useContext(PortalContainerContext) ?? void 0;
3338
+ }
3339
+ function useInsideModal() {
3340
+ return react.useContext(InsideModalContext);
3341
+ }
3342
+
3343
+ // src/lib/sanitize-inline-html.ts
3344
+ var ALLOWED_INLINE_TAGS = /* @__PURE__ */ new Set(["A", "B", "STRONG", "I", "EM", "BR", "SPAN"]);
3345
+ var ALLOWED_ATTRS_BY_TAG = {
3346
+ A: /* @__PURE__ */ new Set(["href", "target", "rel", "class"])
3347
+ };
3348
+ var COMMON_ALLOWED_ATTRS = /* @__PURE__ */ new Set(["class"]);
3349
+ var SAFE_HREF_RE = /^(https?:|mailto:|tel:|\/|#|\.)/i;
3350
+ var DROP_CONTENT_TAGS = /* @__PURE__ */ new Set([
3351
+ "SCRIPT",
3352
+ "STYLE",
3353
+ "IFRAME",
3354
+ "OBJECT",
3355
+ "EMBED",
3356
+ "META",
3357
+ "LINK",
3358
+ "BASE",
3359
+ "NOSCRIPT",
3360
+ // SVG/MATH 는 foreign-content 파싱 모드로 전환되어 재직렬화 시 다른 트리로
3361
+ // 재파싱될 수 있다(mXSS 벡터). 인라인 라벨에 필요 없으므로 통째로 제거한다.
3362
+ "SVG",
3363
+ "MATH",
3364
+ "TEMPLATE"
3365
+ ]);
3366
+ var escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
3367
+ var sanitizeNode = (node) => {
3368
+ if (node.nodeType === Node.COMMENT_NODE) {
3369
+ node.remove();
3370
+ return;
3371
+ }
3372
+ if (node.nodeType !== Node.ELEMENT_NODE) return;
3373
+ const element = node;
3374
+ const tagName = element.tagName;
3375
+ if (DROP_CONTENT_TAGS.has(tagName)) {
3376
+ element.remove();
3377
+ return;
3378
+ }
3379
+ Array.from(element.childNodes).forEach((child) => sanitizeNode(child));
3380
+ if (ALLOWED_INLINE_TAGS.has(tagName)) {
3381
+ if (element.hasAttribute("className")) {
3382
+ const val = element.getAttribute("className");
3383
+ element.removeAttribute("className");
3384
+ if (!element.hasAttribute("class")) element.setAttribute("class", val);
3385
+ }
3386
+ const allowedAttrs = ALLOWED_ATTRS_BY_TAG[tagName] ?? COMMON_ALLOWED_ATTRS;
3387
+ Array.from(element.attributes).forEach((attr) => {
3388
+ if (!allowedAttrs.has(attr.name)) element.removeAttribute(attr.name);
3389
+ });
3390
+ if (tagName === "A") {
3391
+ const href = element.getAttribute("href");
3392
+ if (href !== null && href !== "" && !SAFE_HREF_RE.test(href)) element.removeAttribute("href");
3393
+ if (element.hasAttribute("target")) {
3394
+ element.setAttribute("rel", "noopener noreferrer");
3395
+ }
3396
+ }
3397
+ return;
3398
+ }
3399
+ const parent = element.parentNode;
3400
+ if (parent == null) return;
3401
+ while (element.firstChild) parent.insertBefore(element.firstChild, element);
3402
+ parent.removeChild(element);
3403
+ };
3404
+ var sanitizeInlineHtml = (value) => {
3405
+ if (typeof document === "undefined") return escapeHtml(value);
3406
+ const template = document.createElement("template");
3407
+ template.innerHTML = value;
3408
+ Array.from(template.content.childNodes).forEach((child) => sanitizeNode(child));
3409
+ return template.innerHTML;
3410
+ };
3086
3411
 
3087
3412
  // src/components/STag/tag.config.ts
3088
3413
  var TAG_SHAPES = ["square", "pill"];
@@ -3176,9 +3501,418 @@ var STag = react.forwardRef(function STag2({
3176
3501
  }
3177
3502
  );
3178
3503
  });
3179
-
3180
- // src/components/SButton/button.config.ts
3181
- var BUTTON_COLORS = ["primary", "secondary", "neutral", "danger"];
3504
+ var SIZE = {
3505
+ xxs: { icon: 12, radius: "sm" },
3506
+ xs: { icon: 16, radius: "sm" },
3507
+ sm: { icon: 20, radius: "sm" },
3508
+ md: { icon: 24, radius: "md" },
3509
+ lg: { icon: 32, radius: "md" }
3510
+ };
3511
+ var TOOLTIP_HIDE_DELAY_MS = 100;
3512
+ function SGhostButton({
3513
+ icon,
3514
+ size = "sm",
3515
+ intent = "default",
3516
+ ariaLabel = "",
3517
+ ariaPressed,
3518
+ tooltipText,
3519
+ disabled = false,
3520
+ onClick,
3521
+ anchorClassName,
3522
+ anchorStyle,
3523
+ className,
3524
+ style
3525
+ }) {
3526
+ const portalContainer = usePortalContainer();
3527
+ const [open, setOpen] = react.useState(false);
3528
+ const hideTimer = react.useRef(void 0);
3529
+ const cancelHide = () => {
3530
+ if (hideTimer.current) {
3531
+ clearTimeout(hideTimer.current);
3532
+ hideTimer.current = void 0;
3533
+ }
3534
+ };
3535
+ const openNow = () => {
3536
+ cancelHide();
3537
+ setOpen(true);
3538
+ };
3539
+ const startHide = () => {
3540
+ cancelHide();
3541
+ hideTimer.current = setTimeout(() => setOpen(false), TOOLTIP_HIDE_DELAY_MS);
3542
+ };
3543
+ const s = SIZE[size];
3544
+ const contentColor = disabled ? intent === "inverse" ? "var(--cmp-ghostButton-inverse-disabled)" : "var(--cmp-ghostButton-icon-disabled)" : `var(--cmp-ghostButton-${intent}-content)`;
3545
+ const text = (tooltipText ?? "").trim();
3546
+ const hasTooltip = text !== "";
3547
+ const btn = /* @__PURE__ */ jsxRuntime.jsxs(
3548
+ "button",
3549
+ {
3550
+ type: "button",
3551
+ disabled,
3552
+ "aria-disabled": disabled ? "true" : void 0,
3553
+ "aria-label": ariaLabel.trim() || void 0,
3554
+ "aria-pressed": ariaPressed,
3555
+ tabIndex: disabled ? -1 : void 0,
3556
+ onClick: (e) => {
3557
+ if (disabled) {
3558
+ e.preventDefault();
3559
+ return;
3560
+ }
3561
+ onClick?.(e);
3562
+ },
3563
+ className: cn(
3564
+ "group/ghost-button relative box-border inline-flex items-center justify-center border-none bg-transparent p-0 transition-shadow",
3565
+ disabled ? "cursor-not-allowed" : "cursor-pointer",
3566
+ "focus-visible:outline-none focus-visible:shadow-[0_0_0_2px_var(--cmp-ghostButton-action-hover-bg)]",
3567
+ className
3568
+ ),
3569
+ style: {
3570
+ width: `var(--cmp-ghostButton-${size}-size)`,
3571
+ height: `var(--cmp-ghostButton-${size}-size)`,
3572
+ borderRadius: `var(--cmp-ghostButton-radius-${s.radius})`,
3573
+ ...style
3574
+ },
3575
+ children: [
3576
+ !disabled && /* @__PURE__ */ jsxRuntime.jsx(
3577
+ "span",
3578
+ {
3579
+ "aria-hidden": true,
3580
+ className: "pointer-events-none absolute inset-0 rounded-[inherit] opacity-0 transition-opacity duration-200 group-hover/ghost-button:opacity-5",
3581
+ style: { background: `var(--cmp-ghostButton-${intent}-hover-bg)` }
3582
+ }
3583
+ ),
3584
+ /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon, color: contentColor })
3585
+ ]
3586
+ }
3587
+ );
3588
+ if (!hasTooltip) return btn;
3589
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: setOpen, children: [
3590
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3591
+ "span",
3592
+ {
3593
+ className: cn("inline-flex", anchorClassName),
3594
+ style: anchorStyle,
3595
+ onMouseEnter: openNow,
3596
+ onMouseLeave: startHide,
3597
+ onFocus: openNow,
3598
+ onBlur: startHide,
3599
+ children: btn
3600
+ }
3601
+ ) }),
3602
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
3603
+ RPopover2__namespace.Content,
3604
+ {
3605
+ side: "top",
3606
+ sideOffset: 4,
3607
+ className: cn("z-50", FLOATING_SLIDE_ANIM),
3608
+ "aria-hidden": true,
3609
+ onOpenAutoFocus: (e) => e.preventDefault(),
3610
+ onMouseEnter: cancelHide,
3611
+ onMouseLeave: startHide,
3612
+ children: /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: "square", size: "xs", color: "grey", label: text })
3613
+ }
3614
+ ) })
3615
+ ] });
3616
+ }
3617
+ var HIDE_DELAY_MS = 100;
3618
+ function useBody(content, message = []) {
3619
+ if (content != null) return content;
3620
+ if (message.length === 0) return null;
3621
+ const singleLine = message.length === 1;
3622
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: message.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx(
3623
+ "div",
3624
+ {
3625
+ className: singleLine ? "leading-[24px]" : void 0,
3626
+ dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(line) }
3627
+ },
3628
+ i
3629
+ )) });
3630
+ }
3631
+ var STooltip = react.forwardRef(function STooltip2({
3632
+ content,
3633
+ message = [],
3634
+ trigger = "hover",
3635
+ placement = "top",
3636
+ tooltipType = "default",
3637
+ useClose = false,
3638
+ disabled = false,
3639
+ children,
3640
+ icon = "helpOutline",
3641
+ iconSize = 12,
3642
+ color = "#01BB4B",
3643
+ ariaLabel,
3644
+ className,
3645
+ triggerClassName,
3646
+ style
3647
+ }, ref) {
3648
+ const portalContainer = usePortalContainer();
3649
+ const [open, setOpen] = react.useState(false);
3650
+ const hideTimer = react.useRef(void 0);
3651
+ const cancelHide = () => {
3652
+ if (hideTimer.current) {
3653
+ clearTimeout(hideTimer.current);
3654
+ hideTimer.current = void 0;
3655
+ }
3656
+ };
3657
+ const openNow = () => {
3658
+ cancelHide();
3659
+ setOpen(true);
3660
+ };
3661
+ const startHide = () => {
3662
+ if (useClose) return;
3663
+ cancelHide();
3664
+ hideTimer.current = setTimeout(() => setOpen(false), HIDE_DELAY_MS);
3665
+ };
3666
+ react.useImperativeHandle(
3667
+ ref,
3668
+ () => ({
3669
+ show: () => {
3670
+ cancelHide();
3671
+ setOpen(true);
3672
+ },
3673
+ hide: () => {
3674
+ cancelHide();
3675
+ setOpen(false);
3676
+ }
3677
+ }),
3678
+ []
3679
+ );
3680
+ const body = useBody(content, message);
3681
+ const bg = `var(--cmp-tooltip-${tooltipType}-bg)`;
3682
+ const fg = `var(--cmp-tooltip-${tooltipType}-content)`;
3683
+ const triggerNode = children ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("inline-flex cursor-pointer", triggerClassName), "aria-label": ariaLabel, children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: iconSize, color }) });
3684
+ if (disabled || body == null) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: triggerNode });
3685
+ const isHover = trigger === "hover";
3686
+ const contentClass = cn(
3687
+ "z-50 w-fit whitespace-nowrap rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px] shadow-normal-sm",
3688
+ FLOATING_SLIDE_ANIM,
3689
+ className
3690
+ );
3691
+ const contentStyle = {
3692
+ background: bg,
3693
+ color: fg,
3694
+ fontWeight: tooltipType === "default" ? 500 : 700,
3695
+ ...style
3696
+ };
3697
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: setOpen, children: [
3698
+ isHover ? (
3699
+ // hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
3700
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3701
+ "span",
3702
+ {
3703
+ className: "inline-flex",
3704
+ onMouseEnter: openNow,
3705
+ onMouseLeave: startHide,
3706
+ onFocus: openNow,
3707
+ onBlur: startHide,
3708
+ children: triggerNode
3709
+ }
3710
+ ) })
3711
+ ) : /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Trigger, { asChild: true, children: triggerNode }),
3712
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
3713
+ RPopover2__namespace.Content,
3714
+ {
3715
+ side: placement,
3716
+ sideOffset: 8,
3717
+ className: contentClass,
3718
+ style: contentStyle,
3719
+ onOpenAutoFocus: (e) => e.preventDefault(),
3720
+ onInteractOutside: (e) => {
3721
+ if (useClose) e.preventDefault();
3722
+ },
3723
+ onEscapeKeyDown: (e) => {
3724
+ if (useClose) e.preventDefault();
3725
+ },
3726
+ onMouseEnter: isHover ? cancelHide : void 0,
3727
+ onMouseLeave: isHover ? startHide : void 0,
3728
+ children: [
3729
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-[12px]", children: [
3730
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: body }),
3731
+ useClose && /* @__PURE__ */ jsxRuntime.jsx(
3732
+ SGhostButton,
3733
+ {
3734
+ icon: "close",
3735
+ size: "xs",
3736
+ intent: tooltipType === "default" ? "inverse" : "default",
3737
+ ariaLabel: "\uB2EB\uAE30",
3738
+ className: "shrink-0",
3739
+ onClick: () => {
3740
+ cancelHide();
3741
+ setOpen(false);
3742
+ }
3743
+ }
3744
+ )
3745
+ ] }),
3746
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
3747
+ ]
3748
+ }
3749
+ ) })
3750
+ ] });
3751
+ });
3752
+ STooltip.displayName = "STooltip";
3753
+ var topBorderColorClass = {
3754
+ default: "bg-(--cmp-sectionHeaderCard-topBorder-color-default)",
3755
+ accent: "bg-(--cmp-sectionHeaderCard-topBorder-color-accent)"
3756
+ };
3757
+ var SSectionHeaderCardBody = react.forwardRef(
3758
+ function SSectionHeaderCardBody2({ className, children, ...rest }, ref) {
3759
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className, ...rest, children });
3760
+ }
3761
+ );
3762
+ var SSectionHeaderCardHeader = react.forwardRef(
3763
+ function SSectionHeaderCardHeader2({
3764
+ title,
3765
+ marker = false,
3766
+ required = false,
3767
+ helpText,
3768
+ subtitle,
3769
+ slot,
3770
+ thickness = false,
3771
+ className,
3772
+ ...rest
3773
+ }, ref) {
3774
+ const hasHelp = helpText != null && helpText.length > 0;
3775
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3776
+ thickness && /* @__PURE__ */ jsxRuntime.jsx(
3777
+ "div",
3778
+ {
3779
+ className: cn(
3780
+ "h-(--cmp-sectionHeaderCard-topBorder-thickness) w-full shrink-0",
3781
+ topBorderColorClass[thickness]
3782
+ )
3783
+ }
3784
+ ),
3785
+ /* @__PURE__ */ jsxRuntime.jsxs(
3786
+ "div",
3787
+ {
3788
+ ref,
3789
+ className: cn(
3790
+ "box-border flex h-[40px] w-full shrink-0 items-center gap-[8px] overflow-hidden border-b border-(--sys-color-border-default) bg-(--sys-color-bg-frame) px-[16px] py-[4px]",
3791
+ className
3792
+ ),
3793
+ ...rest,
3794
+ children: [
3795
+ marker && /* @__PURE__ */ jsxRuntime.jsx(SBadge, { color: "darkblue", className: "shrink-0" }),
3796
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 shrink-0 items-center gap-[8px]", children: [
3797
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate text-[12px] font-bold leading-[20px] text-(--sys-color-fg-brand)", children: title }),
3798
+ required && /* @__PURE__ */ jsxRuntime.jsx(
3799
+ SIcon,
3800
+ {
3801
+ name: "star",
3802
+ size: 16,
3803
+ color: "var(--sys-color-fg-accent)",
3804
+ className: "shrink-0"
3805
+ }
3806
+ ),
3807
+ hasHelp && /* @__PURE__ */ jsxRuntime.jsx(
3808
+ STooltip,
3809
+ {
3810
+ trigger: "hover",
3811
+ icon: "helpOutline",
3812
+ iconSize: 16,
3813
+ color: "var(--sys-color-fg-success)",
3814
+ message: helpText,
3815
+ triggerClassName: "shrink-0 rounded-[4px]"
3816
+ }
3817
+ )
3818
+ ] }),
3819
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate text-[12px] font-normal leading-[20px] text-(--sys-color-fg-secondary)", children: subtitle }),
3820
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex min-h-6 min-w-0 flex-1 items-center justify-end", children: slot })
3821
+ ]
3822
+ }
3823
+ )
3824
+ ] });
3825
+ }
3826
+ );
3827
+ var SSectionHeaderCardRoot = react.forwardRef(
3828
+ function SSectionHeaderCard({ className, children, ...rest }, ref) {
3829
+ return /* @__PURE__ */ jsxRuntime.jsx(
3830
+ "div",
3831
+ {
3832
+ ref,
3833
+ className: cn(
3834
+ "box-border flex w-full flex-col items-stretch overflow-hidden rounded-[8px] border border-(--sys-color-border-default) bg-(--sys-color-bg-frame)",
3835
+ className
3836
+ ),
3837
+ ...rest,
3838
+ children
3839
+ }
3840
+ );
3841
+ }
3842
+ );
3843
+ var SSectionHeaderCard2 = Object.assign(SSectionHeaderCardRoot, {
3844
+ Header: SSectionHeaderCardHeader,
3845
+ Body: SSectionHeaderCardBody
3846
+ });
3847
+ SSectionHeaderCardRoot.displayName = "SSectionHeaderCard";
3848
+ SSectionHeaderCardHeader.displayName = "SSectionHeaderCard.Header";
3849
+ SSectionHeaderCardBody.displayName = "SSectionHeaderCard.Body";
3850
+ var SDivider = react.forwardRef(function SDivider2({ vertical = false, className, style, ...rest }, ref) {
3851
+ return /* @__PURE__ */ jsxRuntime.jsx(
3852
+ "hr",
3853
+ {
3854
+ ref,
3855
+ "aria-orientation": vertical ? "vertical" : "horizontal",
3856
+ className: cn(
3857
+ "shrink-0 border-0",
3858
+ vertical ? "inline-block h-auto w-px self-stretch" : "block h-px w-full",
3859
+ className
3860
+ ),
3861
+ style: { backgroundColor: "var(--sys-color-divider-default, #E1E1E1)", ...style },
3862
+ ...rest
3863
+ }
3864
+ );
3865
+ });
3866
+
3867
+ // src/lib/scrollbar.ts
3868
+ var FIREFOX_SCROLLBAR_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-width:thin] supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_transparent]";
3869
+ var SCROLLBAR_CLASS = `${FIREFOX_SCROLLBAR_CLASS} [&::-webkit-scrollbar]:h-[12px] [&::-webkit-scrollbar]:w-[12px] [&::-webkit-scrollbar]:bg-transparent [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:border-2 [&::-webkit-scrollbar-thumb]:border-solid [&::-webkit-scrollbar-thumb]:border-transparent [&::-webkit-scrollbar-thumb]:bg-[var(--color-grey-45)] [&::-webkit-scrollbar-thumb]:bg-clip-padding`;
3870
+ var SCROLLBAR_HIDDEN_CLASS = "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden";
3871
+ var SCROLLBAR_TRACK_BG_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_var(--color-grey-10)] [&::-webkit-scrollbar]:bg-[var(--color-grey-10)] [&::-webkit-scrollbar-track]:bg-[var(--color-grey-10)] [&::-webkit-scrollbar-corner]:bg-[var(--color-grey-10)]";
3872
+ var SCROLLBAR_TRACK_BG_WHITE_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_var(--color-white)] [&::-webkit-scrollbar]:bg-[var(--color-white)] [&::-webkit-scrollbar-track]:bg-[var(--color-white)] [&::-webkit-scrollbar-corner]:bg-[var(--color-white)]";
3873
+ var SCROLLBAR_TRACK_BORDER_CLASS = "[&::-webkit-scrollbar-track:vertical]:[border-left:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-track:horizontal]:[border-top:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-corner]:[border-top:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-corner]:[border-left:1px_solid_var(--sys-color-border-default)] [&::-webkit-scrollbar-thumb:vertical]:[border-left-width:3px] [&::-webkit-scrollbar-thumb:horizontal]:[border-top-width:3px]";
3874
+ var AXIS_CLASS = {
3875
+ vertical: "overflow-x-hidden overflow-y-auto",
3876
+ horizontal: "overflow-x-auto overflow-y-hidden",
3877
+ both: "overflow-auto"
3878
+ };
3879
+ var SScrollArea = react.forwardRef(function SScrollArea2({
3880
+ axis = "both",
3881
+ background = false,
3882
+ bordered = false,
3883
+ maxHeight,
3884
+ maxWidth,
3885
+ className,
3886
+ style,
3887
+ children,
3888
+ ...rest
3889
+ }, ref) {
3890
+ const mergedStyle = { ...style };
3891
+ if (maxHeight) mergedStyle.maxHeight = maxHeight;
3892
+ if (maxWidth) mergedStyle.maxWidth = maxWidth;
3893
+ return /* @__PURE__ */ jsxRuntime.jsx(
3894
+ "div",
3895
+ {
3896
+ ref,
3897
+ className: cn(
3898
+ AXIS_CLASS[axis],
3899
+ SCROLLBAR_CLASS,
3900
+ background && SCROLLBAR_TRACK_BG_CLASS,
3901
+ bordered && SCROLLBAR_TRACK_BORDER_CLASS,
3902
+ className
3903
+ ),
3904
+ style: mergedStyle,
3905
+ ...rest,
3906
+ children
3907
+ }
3908
+ );
3909
+ });
3910
+
3911
+ // src/components/SScrollArea/scrollArea.config.ts
3912
+ var SCROLL_AREA_AXES = ["vertical", "horizontal", "both"];
3913
+
3914
+ // src/components/SButton/button.config.ts
3915
+ var BUTTON_COLORS = ["primary", "secondary", "neutral", "danger"];
3182
3916
  var BUTTON_SIZES = ["xs", "sm", "md", "lg"];
3183
3917
  var V = (path) => `var(--cmp-button-${path})`;
3184
3918
  function buttonPreset(color, outline) {
@@ -3360,7 +4094,13 @@ function renderItems(message, depth = 1) {
3360
4094
  className: cn("flex items-start", isDepth2 && "pl-[32px]"),
3361
4095
  children: [
3362
4096
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-[24px] shrink-0 text-center", "aria-hidden": true, children: isDepth2 ? "\u2022" : "-" }),
3363
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0 min-w-0 flex-1 break-words", children: m })
4097
+ /* @__PURE__ */ jsxRuntime.jsx(
4098
+ "p",
4099
+ {
4100
+ className: "m-0 min-w-0 flex-1 break-words",
4101
+ dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(m) }
4102
+ }
4103
+ )
3364
4104
  ]
3365
4105
  },
3366
4106
  `${depth}-${i}-${out.length}`
@@ -3663,36 +4403,6 @@ var loading = {
3663
4403
  setState({ open: false });
3664
4404
  }
3665
4405
  };
3666
-
3667
- // src/lib/floating-anim.ts
3668
- var FLOATING_SLIDE_ANIM = [
3669
- "data-[state=open]:data-[side=top]:animate-floating-in-top",
3670
- "data-[state=delayed-open]:data-[side=top]:animate-floating-in-top",
3671
- "data-[state=instant-open]:data-[side=top]:animate-floating-in-top",
3672
- "data-[state=closed]:data-[side=top]:animate-floating-out-top",
3673
- "data-[state=open]:data-[side=bottom]:animate-floating-in-bottom",
3674
- "data-[state=delayed-open]:data-[side=bottom]:animate-floating-in-bottom",
3675
- "data-[state=instant-open]:data-[side=bottom]:animate-floating-in-bottom",
3676
- "data-[state=closed]:data-[side=bottom]:animate-floating-out-bottom",
3677
- "data-[state=open]:data-[side=left]:animate-floating-in-left",
3678
- "data-[state=delayed-open]:data-[side=left]:animate-floating-in-left",
3679
- "data-[state=instant-open]:data-[side=left]:animate-floating-in-left",
3680
- "data-[state=closed]:data-[side=left]:animate-floating-out-left",
3681
- "data-[state=open]:data-[side=right]:animate-floating-in-right",
3682
- "data-[state=delayed-open]:data-[side=right]:animate-floating-in-right",
3683
- "data-[state=instant-open]:data-[side=right]:animate-floating-in-right",
3684
- "data-[state=closed]:data-[side=right]:animate-floating-out-right"
3685
- ].join(" ");
3686
- var PortalContainerContext = react.createContext(null);
3687
- var InsideModalContext = react.createContext(false);
3688
- var PortalContainerProvider = PortalContainerContext.Provider;
3689
- var InsideModalProvider = InsideModalContext.Provider;
3690
- function usePortalContainer() {
3691
- return react.useContext(PortalContainerContext) ?? void 0;
3692
- }
3693
- function useInsideModal() {
3694
- return react.useContext(InsideModalContext);
3695
- }
3696
4406
  var SIZE_CONFIG = {
3697
4407
  sm: {
3698
4408
  gap: 4,
@@ -3779,83 +4489,14 @@ var STextLink = react.forwardRef(function STextLink2({
3779
4489
  ]
3780
4490
  }
3781
4491
  );
3782
- const text = (tooltipText ?? "").trim();
3783
- if (text === "") return link;
3784
- return /* @__PURE__ */ jsxRuntime.jsx(RTooltip__namespace.Provider, { delayDuration: 200, children: /* @__PURE__ */ jsxRuntime.jsxs(RTooltip__namespace.Root, { children: [
3785
- /* @__PURE__ */ jsxRuntime.jsx(RTooltip__namespace.Trigger, { asChild: true, children: link }),
3786
- /* @__PURE__ */ jsxRuntime.jsx(RTooltip__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(RTooltip__namespace.Content, { side: "top", sideOffset: 4, className: cn("z-50", FLOATING_SLIDE_ANIM), children: /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: "square", size: "xs", color: "grey", label: text }) }) })
3787
- ] }) });
3788
- });
3789
-
3790
- // src/lib/sanitize-inline-html.ts
3791
- var ALLOWED_INLINE_TAGS = /* @__PURE__ */ new Set(["A", "B", "STRONG", "I", "EM", "BR", "SPAN"]);
3792
- var ALLOWED_ATTRS_BY_TAG = {
3793
- A: /* @__PURE__ */ new Set(["href", "target", "rel", "class"])
3794
- };
3795
- var COMMON_ALLOWED_ATTRS = /* @__PURE__ */ new Set(["class"]);
3796
- var SAFE_HREF_RE = /^(https?:|mailto:|tel:|\/|#|\.)/i;
3797
- var DROP_CONTENT_TAGS = /* @__PURE__ */ new Set([
3798
- "SCRIPT",
3799
- "STYLE",
3800
- "IFRAME",
3801
- "OBJECT",
3802
- "EMBED",
3803
- "META",
3804
- "LINK",
3805
- "BASE",
3806
- "NOSCRIPT",
3807
- // SVG/MATH 는 foreign-content 파싱 모드로 전환되어 재직렬화 시 다른 트리로
3808
- // 재파싱될 수 있다(mXSS 벡터). 인라인 라벨에 필요 없으므로 통째로 제거한다.
3809
- "SVG",
3810
- "MATH",
3811
- "TEMPLATE"
3812
- ]);
3813
- var escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
3814
- var sanitizeNode = (node) => {
3815
- if (node.nodeType === Node.COMMENT_NODE) {
3816
- node.remove();
3817
- return;
3818
- }
3819
- if (node.nodeType !== Node.ELEMENT_NODE) return;
3820
- const element = node;
3821
- const tagName = element.tagName;
3822
- if (DROP_CONTENT_TAGS.has(tagName)) {
3823
- element.remove();
3824
- return;
3825
- }
3826
- Array.from(element.childNodes).forEach((child) => sanitizeNode(child));
3827
- if (ALLOWED_INLINE_TAGS.has(tagName)) {
3828
- if (element.hasAttribute("className")) {
3829
- const val = element.getAttribute("className");
3830
- element.removeAttribute("className");
3831
- if (!element.hasAttribute("class")) element.setAttribute("class", val);
3832
- }
3833
- const allowedAttrs = ALLOWED_ATTRS_BY_TAG[tagName] ?? COMMON_ALLOWED_ATTRS;
3834
- Array.from(element.attributes).forEach((attr) => {
3835
- if (!allowedAttrs.has(attr.name)) element.removeAttribute(attr.name);
3836
- });
3837
- if (tagName === "A") {
3838
- const href = element.getAttribute("href");
3839
- if (href !== null && href !== "" && !SAFE_HREF_RE.test(href)) element.removeAttribute("href");
3840
- if (element.hasAttribute("target")) {
3841
- element.setAttribute("rel", "noopener noreferrer");
3842
- }
3843
- }
3844
- return;
3845
- }
3846
- const parent = element.parentNode;
3847
- if (parent == null) return;
3848
- while (element.firstChild) parent.insertBefore(element.firstChild, element);
3849
- parent.removeChild(element);
3850
- };
3851
- var sanitizeInlineHtml = (value) => {
3852
- if (typeof document === "undefined") return escapeHtml(value);
3853
- const template = document.createElement("template");
3854
- template.innerHTML = value;
3855
- Array.from(template.content.childNodes).forEach((child) => sanitizeNode(child));
3856
- return template.innerHTML;
3857
- };
3858
- var SIZE = {
4492
+ const text = (tooltipText ?? "").trim();
4493
+ if (text === "") return link;
4494
+ return /* @__PURE__ */ jsxRuntime.jsx(RTooltip__namespace.Provider, { delayDuration: 200, children: /* @__PURE__ */ jsxRuntime.jsxs(RTooltip__namespace.Root, { children: [
4495
+ /* @__PURE__ */ jsxRuntime.jsx(RTooltip__namespace.Trigger, { asChild: true, children: link }),
4496
+ /* @__PURE__ */ jsxRuntime.jsx(RTooltip__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(RTooltip__namespace.Content, { side: "top", sideOffset: 4, className: cn("z-50", FLOATING_SLIDE_ANIM), children: /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: "square", size: "xs", color: "grey", label: text }) }) })
4497
+ ] }) });
4498
+ });
4499
+ var SIZE2 = {
3859
4500
  xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth: 64, splitMinWidth: 72 },
3860
4501
  sm: {
3861
4502
  height: 28,
@@ -3941,7 +4582,7 @@ var SDropdownButton = react.forwardRef(
3941
4582
  }),
3942
4583
  []
3943
4584
  );
3944
- const s = SIZE[size];
4585
+ const s = SIZE2[size];
3945
4586
  const p = buttonPreset(color, outline);
3946
4587
  const colorVars = {
3947
4588
  "--dd-bg": disabled ? "var(--cmp-button-bg-disabled)" : p.bg,
@@ -4077,119 +4718,6 @@ var SDropdownButton = react.forwardRef(
4077
4718
  }
4078
4719
  );
4079
4720
  SDropdownButton.displayName = "SDropdownButton";
4080
- var SIZE2 = {
4081
- xxs: { icon: 12, radius: "sm" },
4082
- xs: { icon: 16, radius: "sm" },
4083
- sm: { icon: 20, radius: "sm" },
4084
- md: { icon: 24, radius: "md" },
4085
- lg: { icon: 32, radius: "md" }
4086
- };
4087
- var TOOLTIP_HIDE_DELAY_MS = 100;
4088
- function SGhostButton({
4089
- icon,
4090
- size = "sm",
4091
- intent = "default",
4092
- ariaLabel = "",
4093
- ariaPressed,
4094
- tooltipText,
4095
- disabled = false,
4096
- onClick,
4097
- anchorClassName,
4098
- anchorStyle,
4099
- className,
4100
- style
4101
- }) {
4102
- const portalContainer = usePortalContainer();
4103
- const [open, setOpen] = react.useState(false);
4104
- const hideTimer = react.useRef(void 0);
4105
- const cancelHide = () => {
4106
- if (hideTimer.current) {
4107
- clearTimeout(hideTimer.current);
4108
- hideTimer.current = void 0;
4109
- }
4110
- };
4111
- const openNow = () => {
4112
- cancelHide();
4113
- setOpen(true);
4114
- };
4115
- const startHide = () => {
4116
- cancelHide();
4117
- hideTimer.current = setTimeout(() => setOpen(false), TOOLTIP_HIDE_DELAY_MS);
4118
- };
4119
- const s = SIZE2[size];
4120
- const contentColor = disabled ? intent === "inverse" ? "var(--cmp-ghostButton-inverse-disabled)" : "var(--cmp-ghostButton-icon-disabled)" : `var(--cmp-ghostButton-${intent}-content)`;
4121
- const text = (tooltipText ?? "").trim();
4122
- const hasTooltip = text !== "";
4123
- const btn = /* @__PURE__ */ jsxRuntime.jsxs(
4124
- "button",
4125
- {
4126
- type: "button",
4127
- disabled,
4128
- "aria-disabled": disabled ? "true" : void 0,
4129
- "aria-label": ariaLabel.trim() || void 0,
4130
- "aria-pressed": ariaPressed,
4131
- tabIndex: disabled ? -1 : void 0,
4132
- onClick: (e) => {
4133
- if (disabled) {
4134
- e.preventDefault();
4135
- return;
4136
- }
4137
- onClick?.(e);
4138
- },
4139
- className: cn(
4140
- "group/ghost-button relative box-border inline-flex items-center justify-center border-none bg-transparent p-0 transition-shadow",
4141
- disabled ? "cursor-not-allowed" : "cursor-pointer",
4142
- "focus-visible:outline-none focus-visible:shadow-[0_0_0_2px_var(--cmp-ghostButton-action-hover-bg)]",
4143
- className
4144
- ),
4145
- style: {
4146
- width: `var(--cmp-ghostButton-${size}-size)`,
4147
- height: `var(--cmp-ghostButton-${size}-size)`,
4148
- borderRadius: `var(--cmp-ghostButton-radius-${s.radius})`,
4149
- ...style
4150
- },
4151
- children: [
4152
- !disabled && /* @__PURE__ */ jsxRuntime.jsx(
4153
- "span",
4154
- {
4155
- "aria-hidden": true,
4156
- className: "pointer-events-none absolute inset-0 rounded-[inherit] opacity-0 transition-opacity duration-200 group-hover/ghost-button:opacity-5",
4157
- style: { background: `var(--cmp-ghostButton-${intent}-hover-bg)` }
4158
- }
4159
- ),
4160
- /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.icon, color: contentColor })
4161
- ]
4162
- }
4163
- );
4164
- if (!hasTooltip) return btn;
4165
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: setOpen, children: [
4166
- /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4167
- "span",
4168
- {
4169
- className: cn("inline-flex", anchorClassName),
4170
- style: anchorStyle,
4171
- onMouseEnter: openNow,
4172
- onMouseLeave: startHide,
4173
- onFocus: openNow,
4174
- onBlur: startHide,
4175
- children: btn
4176
- }
4177
- ) }),
4178
- /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
4179
- RPopover2__namespace.Content,
4180
- {
4181
- side: "top",
4182
- sideOffset: 4,
4183
- className: cn("z-50", FLOATING_SLIDE_ANIM),
4184
- "aria-hidden": true,
4185
- onOpenAutoFocus: (e) => e.preventDefault(),
4186
- onMouseEnter: cancelHide,
4187
- onMouseLeave: startHide,
4188
- children: /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: "square", size: "xs", color: "grey", label: text })
4189
- }
4190
- ) })
4191
- ] });
4192
- }
4193
4721
  function SSwitch({
4194
4722
  value = false,
4195
4723
  leftLabel,
@@ -4271,142 +4799,6 @@ function SToggle({
4271
4799
  }
4272
4800
  );
4273
4801
  }
4274
- var HIDE_DELAY_MS = 100;
4275
- function useBody(content, message = []) {
4276
- if (content != null) return content;
4277
- if (message.length === 0) return null;
4278
- const singleLine = message.length === 1;
4279
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: message.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx(
4280
- "div",
4281
- {
4282
- className: singleLine ? "leading-[24px]" : void 0,
4283
- dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(line) }
4284
- },
4285
- i
4286
- )) });
4287
- }
4288
- var STooltip = react.forwardRef(function STooltip2({
4289
- content,
4290
- message = [],
4291
- trigger = "hover",
4292
- placement = "top",
4293
- tooltipType = "default",
4294
- useClose = false,
4295
- disabled = false,
4296
- children,
4297
- icon = "helpOutline",
4298
- iconSize = 12,
4299
- color = "#01BB4B",
4300
- ariaLabel,
4301
- className,
4302
- triggerClassName,
4303
- style
4304
- }, ref) {
4305
- const portalContainer = usePortalContainer();
4306
- const [open, setOpen] = react.useState(false);
4307
- const hideTimer = react.useRef(void 0);
4308
- const cancelHide = () => {
4309
- if (hideTimer.current) {
4310
- clearTimeout(hideTimer.current);
4311
- hideTimer.current = void 0;
4312
- }
4313
- };
4314
- const openNow = () => {
4315
- cancelHide();
4316
- setOpen(true);
4317
- };
4318
- const startHide = () => {
4319
- if (useClose) return;
4320
- cancelHide();
4321
- hideTimer.current = setTimeout(() => setOpen(false), HIDE_DELAY_MS);
4322
- };
4323
- react.useImperativeHandle(
4324
- ref,
4325
- () => ({
4326
- show: () => {
4327
- cancelHide();
4328
- setOpen(true);
4329
- },
4330
- hide: () => {
4331
- cancelHide();
4332
- setOpen(false);
4333
- }
4334
- }),
4335
- []
4336
- );
4337
- const body = useBody(content, message);
4338
- const bg = `var(--cmp-tooltip-${tooltipType}-bg)`;
4339
- const fg = `var(--cmp-tooltip-${tooltipType}-content)`;
4340
- const triggerNode = children ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("inline-flex cursor-pointer", triggerClassName), "aria-label": ariaLabel, children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: iconSize, color }) });
4341
- if (disabled || body == null) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: triggerNode });
4342
- const isHover = trigger === "hover";
4343
- const contentClass = cn(
4344
- "z-50 w-fit whitespace-nowrap rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px] shadow-normal-sm",
4345
- FLOATING_SLIDE_ANIM,
4346
- className
4347
- );
4348
- const contentStyle = {
4349
- background: bg,
4350
- color: fg,
4351
- fontWeight: tooltipType === "default" ? 500 : 700,
4352
- ...style
4353
- };
4354
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover2__namespace.Root, { open, onOpenChange: setOpen, children: [
4355
- isHover ? (
4356
- // hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
4357
- /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4358
- "span",
4359
- {
4360
- className: "inline-flex",
4361
- onMouseEnter: openNow,
4362
- onMouseLeave: startHide,
4363
- onFocus: openNow,
4364
- onBlur: startHide,
4365
- children: triggerNode
4366
- }
4367
- ) })
4368
- ) : /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Trigger, { asChild: true, children: triggerNode }),
4369
- /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
4370
- RPopover2__namespace.Content,
4371
- {
4372
- side: placement,
4373
- sideOffset: 8,
4374
- className: contentClass,
4375
- style: contentStyle,
4376
- onOpenAutoFocus: (e) => e.preventDefault(),
4377
- onInteractOutside: (e) => {
4378
- if (useClose) e.preventDefault();
4379
- },
4380
- onEscapeKeyDown: (e) => {
4381
- if (useClose) e.preventDefault();
4382
- },
4383
- onMouseEnter: isHover ? cancelHide : void 0,
4384
- onMouseLeave: isHover ? startHide : void 0,
4385
- children: [
4386
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-[12px]", children: [
4387
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: body }),
4388
- useClose && /* @__PURE__ */ jsxRuntime.jsx(
4389
- SGhostButton,
4390
- {
4391
- icon: "close",
4392
- size: "xs",
4393
- intent: tooltipType === "default" ? "inverse" : "default",
4394
- ariaLabel: "\uB2EB\uAE30",
4395
- className: "shrink-0",
4396
- onClick: () => {
4397
- cancelHide();
4398
- setOpen(false);
4399
- }
4400
- }
4401
- )
4402
- ] }),
4403
- /* @__PURE__ */ jsxRuntime.jsx(RPopover2__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
4404
- ]
4405
- }
4406
- ) })
4407
- ] });
4408
- });
4409
- STooltip.displayName = "STooltip";
4410
4802
  var BUTTON_PRESET = {
4411
4803
  default: { color: "primary", outline: false },
4412
4804
  accent: { color: "primary", outline: false },
@@ -8344,7 +8736,7 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
8344
8736
  const [display, setDisplay] = react.useState(() => formatWithCommas(numValue));
8345
8737
  const [ruleError, setRuleError] = react.useState("");
8346
8738
  const innerRef = react.useRef(null);
8347
- const setRefs = (el) => {
8739
+ const setRefs2 = (el) => {
8348
8740
  innerRef.current = el;
8349
8741
  if (typeof ref === "function") ref(el);
8350
8742
  else if (ref) ref.current = el;
@@ -8518,7 +8910,7 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
8518
8910
  /* @__PURE__ */ jsxRuntime.jsx(
8519
8911
  "input",
8520
8912
  {
8521
- ref: setRefs,
8913
+ ref: setRefs2,
8522
8914
  name,
8523
8915
  type: "text",
8524
8916
  inputMode: useDecimal ? "decimal" : "numeric",
@@ -12046,6 +12438,7 @@ exports.SConfirmModal = SConfirmModal;
12046
12438
  exports.SDatePicker = SDatePicker;
12047
12439
  exports.SDateRangePicker = SDateRangePicker;
12048
12440
  exports.SDivider = SDivider;
12441
+ exports.SDraggableItem = SDraggableItem;
12049
12442
  exports.SDropdownButton = SDropdownButton;
12050
12443
  exports.SExpansionItem = SExpansionItem;
12051
12444
  exports.SField = SField;
@@ -12060,6 +12453,8 @@ exports.SKeyValueTable = SKeyValueTable;
12060
12453
  exports.SLayout = SLayout;
12061
12454
  exports.SLayoutContext = SLayoutContext;
12062
12455
  exports.SLinearProgress = SLinearProgress;
12456
+ exports.SList = SList;
12457
+ exports.SListItem = SListItem;
12063
12458
  exports.SLoadingContainer = SLoadingContainer;
12064
12459
  exports.SLoadingModal = SLoadingModal;
12065
12460
  exports.SLoadingViewport = SLoadingViewport;
@@ -12074,6 +12469,7 @@ exports.SRadio = SRadio;
12074
12469
  exports.SRadioButton = SRadioButton;
12075
12470
  exports.SRadioGroup = SRadioGroup;
12076
12471
  exports.SScrollArea = SScrollArea;
12472
+ exports.SSectionHeaderCard = SSectionHeaderCard2;
12077
12473
  exports.SSelect = SSelect;
12078
12474
  exports.SStepper = SStepper;
12079
12475
  exports.SSwitch = SSwitch;