sellmate-design-system-react 8.0.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3191,6 +3191,7 @@ var SDraggableItemView = /* @__PURE__ */ react.forwardRef(
3191
3191
  bordered,
3192
3192
  selected,
3193
3193
  dense,
3194
+ size,
3194
3195
  dragging,
3195
3196
  disabled,
3196
3197
  hovered,
@@ -3204,6 +3205,8 @@ var SDraggableItemView = /* @__PURE__ */ react.forwardRef(
3204
3205
  const supportingTextNode = renderSlot(supportingText, renderState);
3205
3206
  const hasSupportingText = supportingTextNode != null && supportingTextNode !== "";
3206
3207
  const trailingNode = renderSlot(trailing, renderState);
3208
+ const titleTypo = size === "sm" ? selected ? "typo-item-sm-selected" : "typo-item-sm-default" : selected ? "typo-item-md-selected" : "typo-item-md-default";
3209
+ 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)";
3207
3210
  return /* @__PURE__ */ jsxRuntime.jsxs(
3208
3211
  "div",
3209
3212
  {
@@ -3211,10 +3214,12 @@ var SDraggableItemView = /* @__PURE__ */ react.forwardRef(
3211
3214
  "aria-disabled": disabled || void 0,
3212
3215
  "data-dragging": dragging || void 0,
3213
3216
  className: cn(
3214
- "relative flex w-full items-center gap-(--cmp-listDraggableItem-gap) overflow-hidden px-(--cmp-listDraggableItem-paddingX) text-[12px] leading-[20px]",
3215
- 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)",
3217
+ "relative flex w-full items-center gap-(--cmp-listDraggableItem-gap) overflow-hidden px-(--cmp-listDraggableItem-paddingX)",
3218
+ titleTypo,
3219
+ disabled ? "bg-(--cmp-listDraggableItem-bg-default) text-(--sys-color-disabled-text)" : selected ? "bg-(--cmp-listDraggableItem-bg-selected) text-(--cmp-listDraggableItem-text-selected)" : "bg-(--cmp-listDraggableItem-bg-default) text-(--cmp-listDraggableItem-text-default)",
3216
3220
  !disabled && !selected && !dragging && "hover:bg-(--cmp-listDraggableItem-bg-hover)",
3217
- hasSupportingText && supportingTextPosition === "bottom" ? dense ? "min-h-[52px] py-(--cmp-listDraggableItem-paddingY-dense)" : "min-h-[60px] py-(--cmp-listDraggableItem-paddingY-normal)" : dense ? "h-[32px] py-(--cmp-listDraggableItem-paddingY-dense)" : "h-[40px] py-(--cmp-listDraggableItem-paddingY-normal)",
3221
+ hasSupportingText && supportingTextPosition === "bottom" ? dense ? "min-h-[52px]" : "min-h-[60px]" : dense ? "h-[32px]" : "h-[40px]",
3222
+ paddingYClass,
3218
3223
  bordered ? cn(
3219
3224
  "rounded-(--cmp-listDraggableItem-radius-bordered) border border-(--cmp-listDraggableItem-border-default)",
3220
3225
  !disabled && !selected && !dragging && "hover:border-(--cmp-listDraggableItem-bordered-border-hover)",
@@ -3272,7 +3277,7 @@ var SDraggableItemView = /* @__PURE__ */ react.forwardRef(
3272
3277
  "span",
3273
3278
  {
3274
3279
  className: cn(
3275
- "min-w-0 truncate text-[12px] font-normal leading-[20px] text-(--sys-color-fg-secondary)",
3280
+ "typo-body-sm-default min-w-0 truncate text-(--sys-color-fg-secondary)",
3276
3281
  supportingTextPosition === "right" && "flex-1"
3277
3282
  ),
3278
3283
  children: supportingTextNode
@@ -3300,6 +3305,7 @@ var SDraggableItemImpl = /* @__PURE__ */ react.forwardRef(function SDraggableIte
3300
3305
  selected = false,
3301
3306
  dragging = false,
3302
3307
  dense = false,
3308
+ size = "sm",
3303
3309
  disabled = false,
3304
3310
  dragOverlay = true,
3305
3311
  dragOverlayOpacity = 0.75,
@@ -3371,6 +3377,7 @@ var SDraggableItemImpl = /* @__PURE__ */ react.forwardRef(function SDraggableIte
3371
3377
  bordered,
3372
3378
  selected,
3373
3379
  dense,
3380
+ size,
3374
3381
  dragging: dragging || overlayVisible,
3375
3382
  disabled,
3376
3383
  hovered,
@@ -3405,6 +3412,7 @@ var SDraggableItemImpl = /* @__PURE__ */ react.forwardRef(function SDraggableIte
3405
3412
  bordered,
3406
3413
  selected,
3407
3414
  dense,
3415
+ size,
3408
3416
  dragging: true,
3409
3417
  disabled,
3410
3418
  hovered: true,
@@ -3756,6 +3764,7 @@ var SExpansionItem = /* @__PURE__ */ react.forwardRef(
3756
3764
  interaction,
3757
3765
  accentStripe = false,
3758
3766
  dense = false,
3767
+ size = "sm",
3759
3768
  disabled = false,
3760
3769
  onToggle,
3761
3770
  className,
@@ -3771,6 +3780,7 @@ var SExpansionItem = /* @__PURE__ */ react.forwardRef(
3771
3780
  const hasChevronInteraction = interaction === "chevron";
3772
3781
  const showInteractionChevron = hasChevronInteraction && !disabled && (isSelected || hovered);
3773
3782
  const interactionChevronColor = isSelected ? "var(--sys-color-fg-brand)" : "var(--sys-color-fg-quaternary)";
3783
+ const titleTypo = size === "sm" ? isExpanded ? "typo-item-sm-selected" : "typo-item-sm-default" : isExpanded ? "typo-item-md-selected" : "typo-item-md-default";
3774
3784
  const reportExpandedDescendant = react.useCallback(
3775
3785
  (delta) => {
3776
3786
  setExpandedDescendantCount((current) => Math.max(0, current + delta));
@@ -3828,7 +3838,8 @@ var SExpansionItem = /* @__PURE__ */ react.forwardRef(
3828
3838
  onToggle?.(next, event);
3829
3839
  },
3830
3840
  className: cn(
3831
- "group/expansion-item-button 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)",
3841
+ "group/expansion-item-button flex w-full cursor-pointer items-center justify-between border-0 text-left 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)",
3842
+ titleTypo,
3832
3843
  isExpanded && "border-b border-(--cmp-listExpansionItem-title-border)",
3833
3844
  hasChevronInteraction ? "hover:bg-(--sys-color-bg-neutralBright)" : !isExpanded && "hover:bg-(--cmp-listExpansionItem-title-bg-hover)",
3834
3845
  hasSupportingText && supportingTextPosition === "bottom" ? dense ? "min-h-[52px] py-(--cmp-listExpansionItem-title-paddingY-dense)" : "min-h-[60px] py-(--cmp-listExpansionItem-title-paddingY-normal)" : dense ? "h-[32px] py-(--cmp-listExpansionItem-title-paddingY-dense)" : "h-[40px] py-(--cmp-listExpansionItem-title-paddingY-normal)",
@@ -3865,7 +3876,7 @@ var SExpansionItem = /* @__PURE__ */ react.forwardRef(
3865
3876
  "span",
3866
3877
  {
3867
3878
  className: cn(
3868
- "min-w-0 truncate text-[12px] font-normal leading-[20px] text-(--sys-color-fg-secondary)",
3879
+ "typo-body-sm-default min-w-0 truncate text-(--sys-color-fg-secondary)",
3869
3880
  supportingTextPosition === "right" && "flex-1"
3870
3881
  ),
3871
3882
  children: supportingText
@@ -3909,6 +3920,7 @@ var SListItemImpl = /* @__PURE__ */ react.forwardRef(function SListItem({
3909
3920
  interaction,
3910
3921
  accentStripe = false,
3911
3922
  dense = false,
3923
+ size = "sm",
3912
3924
  disabled = false,
3913
3925
  className,
3914
3926
  onMouseEnter,
@@ -3927,6 +3939,7 @@ var SListItemImpl = /* @__PURE__ */ react.forwardRef(function SListItem({
3927
3939
  const hasChevronInteraction = interaction === "chevron";
3928
3940
  const showInteractionChevron = hasChevronInteraction && isInteractive && (isSelected || hovered);
3929
3941
  const interactionChevronColor = isSelected ? "var(--sys-color-fg-brand)" : "var(--sys-color-fg-quaternary)";
3942
+ const titleTypo = size === "sm" ? isSelected ? "typo-item-sm-selected" : "typo-item-sm-default" : isSelected ? "typo-item-md-selected" : "typo-item-md-default";
3930
3943
  const handleMouseEnter = (event) => {
3931
3944
  if (isInteractive) setHovered(true);
3932
3945
  onMouseEnter?.(event);
@@ -3943,7 +3956,8 @@ var SListItemImpl = /* @__PURE__ */ react.forwardRef(function SListItem({
3943
3956
  onMouseEnter: handleMouseEnter,
3944
3957
  onMouseLeave: handleMouseLeave,
3945
3958
  className: cn(
3946
- "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)",
3959
+ "group/list-item relative flex w-full items-center justify-between bg-(--cmp-listItem-bg-default) text-left text-(--cmp-listItem-text-default)",
3960
+ titleTypo,
3947
3961
  disabled ? "pointer-events-none cursor-not-allowed text-(--sys-color-disabled-text)" : isSelected ? cn(
3948
3962
  "cursor-pointer text-(--cmp-listItem-text-selected)",
3949
3963
  "bg-(--cmp-listItem-bg-selected)"
@@ -3984,7 +3998,7 @@ var SListItemImpl = /* @__PURE__ */ react.forwardRef(function SListItem({
3984
3998
  "span",
3985
3999
  {
3986
4000
  className: cn(
3987
- "min-w-0 truncate text-[12px] font-normal leading-[20px] text-(--sys-color-fg-secondary)",
4001
+ "typo-body-sm-default min-w-0 truncate text-(--sys-color-fg-secondary)",
3988
4002
  supportingTextPosition === "right" && "flex-1"
3989
4003
  ),
3990
4004
  children: supportingTextNode
@@ -7057,6 +7071,8 @@ function SLoadingModal({
7057
7071
  );
7058
7072
  }
7059
7073
  var CLOSE_ANIMATION_DURATION2 = 300;
7074
+ var RESIZE_KEY_STEP = { normal: 10, large: 50 };
7075
+ var RESIZE_HIT_WIDTH = "calc(var(--cmp-splitter-border-width) + var(--cmp-splitter-border-padding) * 2)";
7060
7076
  function toPx(value, percentBase) {
7061
7077
  if (typeof value === "number") return value;
7062
7078
  if (typeof value !== "string") return void 0;
@@ -7094,6 +7110,7 @@ function SDrawer({
7094
7110
  resizable = false,
7095
7111
  minWidth,
7096
7112
  maxWidth,
7113
+ onWidthChange,
7097
7114
  footerLeft,
7098
7115
  button,
7099
7116
  children,
@@ -7106,11 +7123,16 @@ function SDrawer({
7106
7123
  const [portalContainer, setPortalContainer] = react.useState(null);
7107
7124
  const backdropPointerDownRef = react.useRef(false);
7108
7125
  const contentRef = react.useRef(null);
7126
+ const panelRef = react.useRef(null);
7109
7127
  const stackRegistrationRef = react.useRef(null);
7110
7128
  const resizeCleanupRef = react.useRef(null);
7111
- const resizeStateRef = react.useRef(null);
7112
7129
  const [layerIndex, setLayerIndex] = react.useState(null);
7113
7130
  const [currentWidth, setCurrentWidth] = react.useState(width);
7131
+ const [resizing, setResizing] = react.useState(false);
7132
+ const [measuredWidth, setMeasuredWidth] = react.useState(null);
7133
+ const [viewportWidth, setViewportWidth] = react.useState(
7134
+ () => typeof window === "undefined" ? void 0 : window.innerWidth
7135
+ );
7114
7136
  react.useEffect(() => {
7115
7137
  setCurrentWidth(width);
7116
7138
  }, [width]);
@@ -7126,6 +7148,22 @@ function SDrawer({
7126
7148
  react.useEffect(() => {
7127
7149
  return () => resizeCleanupRef.current?.();
7128
7150
  }, []);
7151
+ react.useEffect(() => {
7152
+ if (!rendered) return;
7153
+ const sync = () => setViewportWidth(window.innerWidth);
7154
+ sync();
7155
+ window.addEventListener("resize", sync);
7156
+ return () => window.removeEventListener("resize", sync);
7157
+ }, [rendered]);
7158
+ react.useEffect(() => {
7159
+ const panel = panelRef.current;
7160
+ if (!resizable || !rendered || !panel || typeof ResizeObserver === "undefined") return;
7161
+ const observer = new ResizeObserver(
7162
+ () => setMeasuredWidth(Math.round(panel.getBoundingClientRect().width))
7163
+ );
7164
+ observer.observe(panel);
7165
+ return () => observer.disconnect();
7166
+ }, [resizable, rendered]);
7129
7167
  react.useEffect(() => {
7130
7168
  if (!open) {
7131
7169
  setEntered(false);
@@ -7167,41 +7205,80 @@ function SDrawer({
7167
7205
  }
7168
7206
  onOpenChange?.(false);
7169
7207
  };
7208
+ const resizeBounds = () => {
7209
+ const limit = viewportWidth;
7210
+ if (limit === void 0) return { min: void 0, max: void 0 };
7211
+ const min = toPx(minWidth, limit);
7212
+ const max = toPx(maxWidth, limit);
7213
+ return {
7214
+ min: min === void 0 ? void 0 : Math.min(min, limit),
7215
+ max: max === void 0 ? limit : Math.min(max, limit)
7216
+ };
7217
+ };
7218
+ const commitWidth = (next, startWidth) => {
7219
+ const { min, max } = resizeBounds();
7220
+ const clamped = Math.round(clamp3(next, min, max));
7221
+ setCurrentWidth(clamped);
7222
+ if (clamped !== Math.round(startWidth)) onWidthChange?.(clamped);
7223
+ };
7170
7224
  const handleResizeStart = (event) => {
7225
+ if (typeof document === "undefined") return;
7226
+ const panel = panelRef.current;
7227
+ if (!panel) return;
7171
7228
  event.preventDefault();
7172
7229
  event.stopPropagation();
7173
- const panel = contentRef.current?.querySelector("[data-s-drawer-panel]");
7174
- if (!panel) return;
7175
- resizeStateRef.current = {
7176
- startX: event.clientX,
7177
- startWidth: panel.getBoundingClientRect().width,
7178
- minWidth: toPx(minWidth, window.innerWidth),
7179
- maxWidth: toPx(maxWidth, window.innerWidth)
7180
- };
7230
+ event.currentTarget.focus();
7231
+ const startX = event.clientX;
7232
+ const startWidth = panel.getBoundingClientRect().width;
7233
+ const { min, max } = resizeBounds();
7234
+ let latest = startWidth;
7235
+ const { body } = document;
7236
+ const previousCursor = body.style.cursor;
7237
+ const previousUserSelect = body.style.userSelect;
7181
7238
  const onMove = (moveEvent) => {
7182
- const resizeState = resizeStateRef.current;
7183
- if (!resizeState) return;
7184
- const nextWidth = resizeState.startWidth + resizeState.startX - moveEvent.clientX;
7185
- setCurrentWidth(clamp3(nextWidth, resizeState.minWidth, resizeState.maxWidth));
7239
+ latest = Math.round(clamp3(startWidth + (startX - moveEvent.clientX), min, max));
7240
+ setCurrentWidth(latest);
7186
7241
  };
7187
- resizeCleanupRef.current?.();
7188
- const previousCursor = document.body.style.cursor;
7189
- const previousUserSelect = document.body.style.userSelect;
7190
7242
  const cleanupResize = () => {
7191
- resizeStateRef.current = null;
7192
- document.body.style.cursor = previousCursor;
7193
- document.body.style.userSelect = previousUserSelect;
7243
+ body.style.cursor = previousCursor;
7244
+ body.style.userSelect = previousUserSelect;
7194
7245
  document.removeEventListener("mousemove", onMove);
7195
7246
  document.removeEventListener("mouseup", cleanupResize);
7196
7247
  resizeCleanupRef.current = null;
7248
+ setResizing(false);
7249
+ commitWidth(latest, startWidth);
7197
7250
  };
7251
+ resizeCleanupRef.current?.();
7198
7252
  resizeCleanupRef.current = cleanupResize;
7199
- document.body.style.cursor = "col-resize";
7200
- document.body.style.userSelect = "none";
7253
+ body.style.cursor = "col-resize";
7254
+ body.style.userSelect = "none";
7201
7255
  document.addEventListener("mousemove", onMove);
7202
7256
  document.addEventListener("mouseup", cleanupResize);
7257
+ setResizing(true);
7258
+ };
7259
+ const handleResizeKeyDown = (event) => {
7260
+ const panel = panelRef.current;
7261
+ if (!panel) return;
7262
+ const startWidth = panel.getBoundingClientRect().width;
7263
+ const { min, max } = resizeBounds();
7264
+ const step = RESIZE_KEY_STEP[event.shiftKey ? "large" : "normal"];
7265
+ let next = null;
7266
+ if (event.key === "ArrowLeft") next = startWidth + step;
7267
+ else if (event.key === "ArrowRight") next = startWidth - step;
7268
+ else if (event.key === "Home" && min !== void 0) next = min;
7269
+ else if (event.key === "End" && max !== void 0) next = max;
7270
+ if (next === null) return;
7271
+ event.preventDefault();
7272
+ commitWidth(next, startWidth);
7203
7273
  };
7204
7274
  const modalHost = getModalHost();
7275
+ const resizeValueNow = measuredWidth ?? (typeof currentWidth === "number" ? Math.round(currentWidth) : void 0);
7276
+ const { min: resizeMinPx, max: resizeMaxPx } = resizeBounds();
7277
+ const resizeValueMin = resizeMinPx === void 0 ? void 0 : Math.round(resizeMinPx);
7278
+ const resizeValueMax = resizeMaxPx === void 0 ? void 0 : Math.round(resizeMaxPx);
7279
+ const appliedWidth = typeof currentWidth === "number" && viewportWidth !== void 0 ? Math.min(currentWidth, viewportWidth) : currentWidth;
7280
+ const appliedMinWidth = resizeMinPx ?? minWidth;
7281
+ const appliedMaxWidth = resizeMaxPx ?? maxWidth;
7205
7282
  return /* @__PURE__ */ jsxRuntime.jsx(RDialog__namespace.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(RDialog__namespace.Portal, { container: modalHost, forceMount: rendered ? true : void 0, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pointer-events-none absolute inset-0", style: { zIndex: layerIndex ?? 0 }, children: [
7206
7283
  /* @__PURE__ */ jsxRuntime.jsx(
7207
7284
  RDialog__namespace.Overlay,
@@ -7243,6 +7320,7 @@ function SDrawer({
7243
7320
  /* @__PURE__ */ jsxRuntime.jsxs(
7244
7321
  "div",
7245
7322
  {
7323
+ ref: panelRef,
7246
7324
  className: cn(
7247
7325
  "pointer-events-auto relative flex h-full max-w-full translate-x-full flex-col overflow-hidden bg-[var(--cmp-drawer-bg)] shadow-[var(--shadow-overlay)] transition-transform duration-300 ease-out data-[state=open]:translate-x-0 data-[state=closed]:translate-x-full",
7248
7326
  shaking && "animate-drawer-shake",
@@ -7250,20 +7328,45 @@ function SDrawer({
7250
7328
  ),
7251
7329
  "data-s-drawer-panel": true,
7252
7330
  "data-state": open && entered ? "open" : "closed",
7253
- style: { width: currentWidth, minWidth, maxWidth, ...style },
7331
+ style: {
7332
+ width: appliedWidth,
7333
+ minWidth: appliedMinWidth,
7334
+ maxWidth: appliedMaxWidth,
7335
+ ...style
7336
+ },
7254
7337
  onAnimationEnd: (event) => {
7255
7338
  if (event.animationName === "drawer-shake") setShaking(false);
7256
7339
  },
7257
7340
  children: [
7258
- resizable && /* @__PURE__ */ jsxRuntime.jsx(
7259
- "button",
7341
+ resizable && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
7342
+ "div",
7260
7343
  {
7261
- type: "button",
7344
+ role: "separator",
7345
+ "aria-orientation": "vertical",
7262
7346
  "aria-label": "Drawer \uB108\uBE44 \uC870\uC808",
7263
- className: "absolute inset-y-0 left-0 z-[1] w-[8px] -translate-x-1/2 cursor-col-resize touch-none border-0 bg-transparent p-0",
7264
- onMouseDown: handleResizeStart
7347
+ "aria-valuenow": resizeValueNow,
7348
+ "aria-valuemin": resizeValueMin,
7349
+ "aria-valuemax": resizeValueMax,
7350
+ "aria-valuetext": resizeValueNow === void 0 ? void 0 : `${resizeValueNow}px`,
7351
+ tabIndex: 0,
7352
+ onMouseDown: handleResizeStart,
7353
+ onKeyDown: handleResizeKeyDown,
7354
+ className: "group absolute inset-y-0 left-0 z-[1] flex cursor-col-resize touch-none justify-start outline-none",
7355
+ style: { width: RESIZE_HIT_WIDTH },
7356
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7357
+ "span",
7358
+ {
7359
+ "aria-hidden": true,
7360
+ className: cn(
7361
+ // 평상시엔 자리만 잡고 칠하지 않는다 — 색이 붙는 것 자체가 조절 가능하다는 신호다.
7362
+ "w-(--cmp-splitter-border-width) transition-colors",
7363
+ "group-hover:bg-(--cmp-splitter-border-color) group-focus-visible:bg-(--cmp-splitter-border-color)",
7364
+ resizing && "bg-(--cmp-splitter-border-color)"
7365
+ )
7366
+ }
7367
+ )
7265
7368
  }
7266
- ),
7369
+ ) }),
7267
7370
  /* @__PURE__ */ jsxRuntime.jsx(
7268
7371
  SOverlayHeader,
7269
7372
  {
@@ -7936,8 +8039,11 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
7936
8039
  onLauncherClick,
7937
8040
  logo,
7938
8041
  topContent,
8042
+ railTop,
7939
8043
  railFooter,
8044
+ menuTop,
7940
8045
  menuFooter,
8046
+ foldedTop,
7941
8047
  foldedFooter,
7942
8048
  resizable = false,
7943
8049
  menuWidth: menuWidthProp,
@@ -8446,6 +8552,7 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
8446
8552
  ] })
8447
8553
  }
8448
8554
  ),
8555
+ railFolded && foldedTop && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-[24px] flex shrink-0 items-center justify-center", children: foldedTop }),
8449
8556
  /* @__PURE__ */ jsxRuntime.jsxs(
8450
8557
  "div",
8451
8558
  {
@@ -8463,9 +8570,9 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
8463
8570
  transition: `transform ${GNB_FOLD_MS}ms ease-out, ${hideAfterSlide(folded)}`
8464
8571
  },
8465
8572
  children: [
8466
- useRail && // 레일 컬럼 — 스크롤되는 아이템 목록(nav) 하단 고정 footer 를 한 컬럼에 담는다.
8467
- // footer 내비게이션이 아니므로 nav(landmark) 밖에 두고, 컬럼 폭·구분선·배경은 이 래퍼가
8468
- // 전체 높이에 걸쳐 책임진다(그래야 footer 자리까지 배경·오른쪽 선이 이어진다).
8573
+ useRail && // 레일 컬럼 — 스크롤되는 아이템 목록(nav) 가운데 두고 위아래에 고정 슬롯(top/footer)을 붙인다.
8574
+ // 슬롯은 내비게이션이 아니므로 nav(landmark) 밖에 두고, 컬럼 폭·구분선·배경은 이 래퍼가
8575
+ // 전체 높이에 걸쳐 책임진다(그래야 슬롯 자리까지 배경·오른쪽 선이 이어진다).
8469
8576
  /* @__PURE__ */ jsxRuntime.jsxs(
8470
8577
  "div",
8471
8578
  {
@@ -8476,6 +8583,7 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
8476
8583
  backgroundColor: C.panelBg
8477
8584
  },
8478
8585
  children: [
8586
+ railTop && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: railTop }),
8479
8587
  /* @__PURE__ */ jsxRuntime.jsx(
8480
8588
  "nav",
8481
8589
  {
@@ -8503,6 +8611,7 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
8503
8611
  borderRight: isFull ? rightBorder : void 0
8504
8612
  },
8505
8613
  children: [
8614
+ menuTop && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: menuTop }),
8506
8615
  /* @__PURE__ */ jsxRuntime.jsx(
8507
8616
  "nav",
8508
8617
  {