sellmate-design-system-react 0.8.4 → 0.10.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.
@@ -32,6 +32,21 @@ export interface SGnbProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'>
32
32
  onLauncherClick?: () => void;
33
33
  /** 상단바 로고 영역 (slot) */
34
34
  logo?: ReactNode;
35
+ /**
36
+ * 레일 하단 고정 슬롯. 레일 아이템이 많아 넘치면 아이템 목록(ul)만 스크롤되고
37
+ * 이 슬롯은 레일 하단에 붙어 고정된다. useRail 일 때만 렌더된다.
38
+ */
39
+ railFooter?: ReactNode;
40
+ /**
41
+ * 메뉴 하단 고정 슬롯. 메뉴 아이템이 많아 넘치면 메뉴 목록(ul)만 스크롤되고
42
+ * 이 슬롯은 메뉴 하단에 붙어 고정된다. 메뉴가 렌더될 때만(showMenu) 나타난다.
43
+ */
44
+ menuFooter?: ReactNode;
45
+ /**
46
+ * 접힘(fix 레일) 하단 고정 슬롯. 접으면 본문이 빠져나가며 rail/menu footer 도 사라지므로,
47
+ * 48px 폴드 레일 바닥에 붙는 별도 슬롯이다. header="fix" 로 접혔을 때만 나타난다.
48
+ */
49
+ foldedFooter?: ReactNode;
35
50
  /** 메뉴 landmark(nav) 의 접근성 레이블. 한 화면에 nav 가 여럿일 때 구분한다. */
36
51
  ariaLabel?: string;
37
52
  }
@@ -16,6 +16,10 @@ function cn(...inputs) {
16
16
  return twMerge(clsx(inputs));
17
17
  }
18
18
 
19
+ // src/lib/scrollbar.ts
20
+ var FIREFOX_SCROLLBAR_CLASS = "supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-width:thin] supports-[not_selector(::-webkit-scrollbar)]:[scrollbar-color:var(--color-grey-45)_transparent]";
21
+ 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`;
22
+
19
23
  // src/lib/floating-anim.ts
20
24
  var FLOATING_SLIDE_ANIM = [
21
25
  "data-[state=open]:data-[side=top]:animate-floating-in-top",
@@ -3292,6 +3296,9 @@ var SGnb = forwardRef(function SGnb2({
3292
3296
  onFoldChange,
3293
3297
  onLauncherClick,
3294
3298
  logo,
3299
+ railFooter,
3300
+ menuFooter,
3301
+ foldedFooter,
3295
3302
  ariaLabel = "global navigation",
3296
3303
  className,
3297
3304
  style,
@@ -3445,7 +3452,7 @@ var SGnb = forwardRef(function SGnb2({
3445
3452
  className: "shrink-0"
3446
3453
  }
3447
3454
  ),
3448
- /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap flex flex-no-wrap items-center", children: [
3455
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap flex items-center", children: [
3449
3456
  depth > 1 && iconBranch ? /* @__PURE__ */ jsx(
3450
3457
  "div",
3451
3458
  {
@@ -3656,42 +3663,77 @@ var SGnb = forwardRef(function SGnb2({
3656
3663
  transition: `transform ${GNB_FOLD_MS}ms ease-out, ${hideAfterSlide(folded)}`
3657
3664
  },
3658
3665
  children: [
3659
- useRail && // 레일도 내비게이션 landmark nav 세워야 aria-label(레일) 스크린리더에 노출된다
3660
- // (role 없는 ul aria-label 영역명으로 읽히지 않는다). 메뉴 nav 와는 레이블로 구분된다.
3661
- /* @__PURE__ */ jsx(
3662
- "nav",
3666
+ useRail && // 레일 컬럼스크롤되는 아이템 목록(nav) 하단 고정 footer 를 한 컬럼에 담는다.
3667
+ // footer 내비게이션이 아니므로 nav(landmark) 밖에 두고, 컬럼 폭·구분선·배경은 래퍼가
3668
+ // 전체 높이에 걸쳐 책임진다(그래야 footer 자리까지 배경·오른쪽 선이 이어진다).
3669
+ /* @__PURE__ */ jsxs(
3670
+ "div",
3663
3671
  {
3664
- "aria-label": `${ariaLabel} rail`,
3665
- className: "flex shrink-0 flex-col overflow-y-auto",
3672
+ className: "flex shrink-0 flex-col overflow-hidden",
3666
3673
  style: {
3667
3674
  width: GNB_RAIL_WIDTH,
3668
- padding: GNB_RAIL.padding,
3669
3675
  borderRight: `1px solid ${C.topBorder}`,
3670
3676
  backgroundColor: C.panelBg,
3671
3677
  pointerEvents: "auto"
3672
3678
  },
3673
- children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", style: { gap: GNB_RAIL.gap }, children: railItems.map(renderRailItem) })
3679
+ children: [
3680
+ /* @__PURE__ */ jsx(
3681
+ "nav",
3682
+ {
3683
+ "aria-label": `${ariaLabel} rail`,
3684
+ className: cn(
3685
+ "flex min-h-0 flex-1 flex-col overflow-x-hidden overflow-y-auto",
3686
+ SCROLLBAR_CLASS
3687
+ ),
3688
+ style: { padding: GNB_RAIL.padding },
3689
+ children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", style: { gap: GNB_RAIL.gap }, children: railItems.map(renderRailItem) })
3690
+ }
3691
+ ),
3692
+ railFooter && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: railFooter })
3693
+ ]
3674
3694
  }
3675
3695
  ),
3676
- showMenu && /* @__PURE__ */ jsx(
3677
- "nav",
3696
+ showMenu && /* @__PURE__ */ jsxs(
3697
+ "div",
3678
3698
  {
3679
- "aria-label": ariaLabel,
3680
- className: "flex shrink-0 flex-col overflow-y-auto",
3699
+ className: "flex shrink-0 flex-col overflow-hidden",
3681
3700
  style: {
3682
3701
  width: GNB_MENU_WIDTH,
3683
- paddingTop: M.bodyPaddingY,
3684
- paddingBottom: M.bodyPaddingY,
3685
3702
  backgroundColor: C.panelBg,
3686
3703
  // full 은 상단바가 전폭이라 루트가 오른쪽 선을 못 그린다 → 메뉴 오른쪽(페이지 경계)이 대신 그린다.
3687
3704
  borderRight: header === "full" ? rightBorder : void 0,
3688
3705
  pointerEvents: "auto"
3689
3706
  },
3690
- children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", children: menuItems.map((item) => renderItem(item, 1)) })
3707
+ children: [
3708
+ /* @__PURE__ */ jsx(
3709
+ "nav",
3710
+ {
3711
+ "aria-label": ariaLabel,
3712
+ className: cn(
3713
+ "flex min-h-0 flex-1 flex-col overflow-x-hidden overflow-y-auto",
3714
+ SCROLLBAR_CLASS
3715
+ ),
3716
+ style: {
3717
+ paddingTop: M.bodyPaddingY,
3718
+ paddingBottom: M.bodyPaddingY
3719
+ },
3720
+ children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", children: menuItems.map((item) => renderItem(item, 1)) })
3721
+ }
3722
+ ),
3723
+ menuFooter && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: menuFooter })
3724
+ ]
3691
3725
  }
3692
3726
  )
3693
3727
  ]
3694
3728
  }
3729
+ ),
3730
+ railFolded && foldedFooter && /* @__PURE__ */ jsx(
3731
+ "div",
3732
+ {
3733
+ className: "flex shrink-0 items-center justify-center mb-[24px]",
3734
+ style: { pointerEvents: "auto" },
3735
+ children: foldedFooter
3736
+ }
3695
3737
  )
3696
3738
  ]
3697
3739
  }