@loword/loword-design-system 0.1.2 → 0.2.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 (36) hide show
  1. package/dist/components/LDBreadCrumb/LDBreadCrumb.d.ts +8 -4
  2. package/dist/components/LDBreadCrumb/LDBreadCrumb.d.ts.map +1 -1
  3. package/dist/components/LDBreadCrumb/LDBreadCrumb.js +4 -3
  4. package/dist/components/LDCarousel/CarouselBase.d.ts +5 -0
  5. package/dist/components/LDCarousel/CarouselBase.d.ts.map +1 -1
  6. package/dist/components/LDCarousel/CarouselBase.js +21 -0
  7. package/dist/components/LDCarousel/LDCarousel.d.ts +2 -2
  8. package/dist/components/LDCarousel/LDCarousel.d.ts.map +1 -1
  9. package/dist/components/LDCarousel/LDCarousel.js +1 -1
  10. package/dist/components/LDLNB/LDLNB.d.ts +6 -3
  11. package/dist/components/LDLNB/LDLNB.d.ts.map +1 -1
  12. package/dist/components/LDLNB/LDLNB.js +23 -7
  13. package/dist/components/LDLNB/LNBBase.d.ts +9 -1
  14. package/dist/components/LDLNB/LNBBase.d.ts.map +1 -1
  15. package/dist/components/LDLNB/LNBBase.js +14 -5
  16. package/dist/components/LDTable/LDTable.d.ts +2 -1
  17. package/dist/components/LDTable/LDTable.d.ts.map +1 -1
  18. package/dist/components/LDTable/LDTable.js +1 -1
  19. package/dist/components/LDTable/LDTanstackTable.d.ts +13 -1
  20. package/dist/components/LDTable/LDTanstackTable.d.ts.map +1 -1
  21. package/dist/components/LDTable/LDTanstackTable.js +32 -10
  22. package/dist/components/LDTable/TableBase.d.ts +2 -1
  23. package/dist/components/LDTable/TableBase.d.ts.map +1 -1
  24. package/dist/components/LDTable/TableBase.js +2 -2
  25. package/dist/components/LDTable/TableRowDnd.d.ts +26 -0
  26. package/dist/components/LDTable/TableRowDnd.d.ts.map +1 -0
  27. package/dist/components/LDTable/TableRowDnd.js +40 -0
  28. package/dist/index.css +54 -10
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -0
  32. package/dist/utils/utils.d.ts +6 -0
  33. package/dist/utils/utils.d.ts.map +1 -1
  34. package/dist/utils/utils.js +7 -5
  35. package/package.json +21 -1
  36. package/src/styles/carousel.css +10 -1
@@ -1,4 +1,4 @@
1
- import { type ReactNode } from 'react';
1
+ import { type ElementType, type ReactNode } from 'react';
2
2
  import { type ButtonSize } from '../../components/LDButton/LDButton.js';
3
3
  export interface LDBreadCrumbItem {
4
4
  /** 항목에 표시할 텍스트 */
@@ -12,11 +12,15 @@ export interface LDBreadCrumbItem {
12
12
  }
13
13
  export interface LDBreadCrumbProps {
14
14
  items: LDBreadCrumbItem[];
15
+ /** 링크 렌더 엘리먼트 (기본 `next/link`. 다른 라우터를 쓰면 교체한다) */
16
+ as?: ElementType;
15
17
  size?: ButtonSize;
16
18
  separator?: ReactNode;
17
19
  className?: string;
18
20
  }
19
21
  interface LDBreadCrumbLinkProps extends Omit<React.ComponentProps<'a'>, 'color'> {
22
+ /** 링크 렌더 엘리먼트 (기본 `next/link`. 다른 라우터를 쓰면 교체한다) */
23
+ as?: ElementType;
20
24
  size?: ButtonSize;
21
25
  icon?: ReactNode;
22
26
  }
@@ -28,11 +32,11 @@ interface LDBreadCrumbSeparatorProps extends React.ComponentProps<'li'> {
28
32
  size?: ButtonSize;
29
33
  }
30
34
  declare const LDBreadCrumb: {
31
- ({ items, size, separator, className, }: LDBreadCrumbProps): import("react/jsx-runtime").JSX.Element;
35
+ ({ items, as, size, separator, className, }: LDBreadCrumbProps): import("react/jsx-runtime").JSX.Element;
32
36
  Root: ({ className, ...props }: React.ComponentProps<"nav">) => import("react/jsx-runtime").JSX.Element;
33
- List: ({ className, ...props }: React.ComponentProps /** 항목에 표시할 텍스트 */<"ol">) => import("react/jsx-runtime").JSX.Element;
37
+ List: ({ className, ...props }: React.ComponentProps<"ol">) => import("react/jsx-runtime").JSX.Element;
34
38
  Item: ({ className, ...props }: React.ComponentProps<"li">) => import("react/jsx-runtime").JSX.Element;
35
- Link: ({ size, icon, className, ...props }: LDBreadCrumbLinkProps) => import("react/jsx-runtime").JSX.Element;
39
+ Link: ({ as, size, icon, className, ...props }: LDBreadCrumbLinkProps) => import("react/jsx-runtime").JSX.Element;
36
40
  Page: ({ size, icon, className, children, ...props }: LDBreadCrumbPageProps) => import("react/jsx-runtime").JSX.Element;
37
41
  Separator: ({ size, className, ...props }: LDBreadCrumbSeparatorProps) => import("react/jsx-runtime").JSX.Element;
38
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"LDBreadCrumb.d.ts","sourceRoot":"","sources":["../../../src/components/LDBreadCrumb/LDBreadCrumb.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGjD,OAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAI3E,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6BD,UAAU,qBAAsB,SAAQ,IAAI,CAC1C,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EACzB,OAAO,CACR;IACC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,UAAU,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC;IAClE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,UAAU,0BAA2B,SAAQ,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;IACrE,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAuDD,QAAA,MAAM,YAAY;6CAKf,iBAAiB;oCA5HQ,MAAO,cAAc;oCAIhC,MAAO,cACtB,CAAA,kBAAkB;oCA+DmB,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;gDAS9D,qBAAqB;0DAqBrB,qBAAqB;+CAcrB,0BAA0B;CA4C5B,CAAC;AASF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"LDBreadCrumb.d.ts","sourceRoot":"","sources":["../../../src/components/LDBreadCrumb/LDBreadCrumb.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGnE,OAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAI3E,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,mDAAmD;IACnD,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6BD,UAAU,qBAAsB,SAAQ,IAAI,CAC1C,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EACzB,OAAO,CACR;IACC,mDAAmD;IACnD,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,UAAU,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC;IAClE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,UAAU,0BAA2B,SAAQ,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;IACrE,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAwDD,QAAA,MAAM,YAAY;iDAMf,iBAAiB;oCAnI2B,MAAO,cAAc;oCAEZ,MACtD,cAAc;oCAsEuB,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;oDAU9D,qBAAqB;0DAqBrB,qBAAqB;+CAcrB,0BAA0B;CA8C5B,CAAC;AASF,eAAe,YAAY,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import NextLink from 'next/link';
2
3
  import { Fragment } from 'react';
3
4
  import BreadCrumbBase from '../../components/LDBreadCrumb/BreadCrumbBase.js';
4
5
  import LDButton from '../../components/LDButton/LDButton.js';
@@ -31,11 +32,11 @@ const separatorIconSizeClasses = {
31
32
  // gap은 항목·구분자를 나란히 놓는 List(ol)가 담당한다.
32
33
  // li의 자식은 Link 또는 Page 하나뿐이라 여기에 gap을 줘도 효과가 없다.
33
34
  const Item = ({ className, ...props }) => (_jsx(BreadCrumbBase.Item, { className: className, ...props }));
34
- const Link = ({ size = 'small', icon, className, ...props }) => (_jsx(LDButton, { as: "a", variant: "ghost", color: "neutral", size: size, leftIcon: icon, className: cn('flex h-auto min-w-0 flex-row gap-0.5 px-0 regular text-neutral700 hover:bg-transparent active:bg-transparent', className), ...props }));
35
+ const Link = ({ as = NextLink, size = 'small', icon, className, ...props }) => (_jsx(LDButton, { as: as, variant: "ghost", color: "neutral", size: size, leftIcon: icon, className: cn('flex h-auto min-w-0 flex-row gap-0.5 px-0 regular text-neutral700 hover:bg-transparent active:bg-transparent', className), ...props }));
35
36
  const Page = ({ size = 'small', icon, className, children, ...props }) => (_jsxs(BreadCrumbBase.Page, { className: cn(textSizeClasses[size], 'gap-0.5 text-neutral700', className), ...props, children: [_jsx(RenderIcon, { className: iconSizeClasses[size], children: icon }), children] }));
36
37
  const Separator = ({ size = 'small', className, ...props }) => (_jsx(BreadCrumbBase.Separator, { className: cn(separatorIconSizeClasses[size], 'text-neutral700', className), ...props }));
37
- const LDBreadCrumb = ({ items, size = 'small', separator, className, }) => {
38
- return (_jsx(BreadCrumbBase.Root, { children: _jsx(BreadCrumbBase.List, { className: cn('gap-xs', className), children: items.map((item, index) => (_jsxs(Fragment, { children: [_jsx(Item, { children: item.href ? (_jsx(Link, { href: item.href, icon: item.icon, size: size, className: item.className, children: item.label })) : (_jsx(Page, { icon: item.icon, size: size, className: item.className, children: item.label })) }), index < items.length - 1 && (_jsx(Separator, { size: size, children: separator }))] }, `${item.label}-${index}`))) }) }));
38
+ const LDBreadCrumb = ({ items, as, size = 'small', separator, className, }) => {
39
+ return (_jsx(BreadCrumbBase.Root, { children: _jsx(BreadCrumbBase.List, { className: cn('gap-xs', className), children: items.map((item, index) => (_jsxs(Fragment, { children: [_jsx(Item, { children: item.href ? (_jsx(Link, { as: as, href: item.href, icon: item.icon, size: size, className: item.className, children: item.label })) : (_jsx(Page, { icon: item.icon, size: size, className: item.className, children: item.label })) }), index < items.length - 1 && (_jsx(Separator, { size: size, children: separator }))] }, `${item.label}-${index}`))) }) }));
39
40
  };
40
41
  LDBreadCrumb.Root = BreadCrumbBase.Root;
41
42
  LDBreadCrumb.List = BreadCrumbBase.List;
@@ -35,6 +35,11 @@ interface CarouselContextType {
35
35
  }
36
36
  /** 외부에서 캐러셀 컨트롤(emblaApi)에 접근하고 싶을 때 사용하는 훅 */
37
37
  export declare const useCarousel: () => CarouselContextType;
38
+ /**
39
+ * `useCarousel`과 같지만 Root 밖에서도 던지지 않고 `null`을 준다.
40
+ * 같은 컴포넌트가 슬라이드로도 쓰이고 단독으로도 쓰이는 경우에 필요하다.
41
+ */
42
+ export declare const useOptionalCarousel: () => CarouselContextType | null;
38
43
  export interface RootProps {
39
44
  orientation?: CarouselOrientation;
40
45
  loop?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDCarousel/CarouselBase.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CarouselBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDCarousel/CarouselBase.tsx"],"names":[],"mappings":"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"}
@@ -16,6 +16,11 @@ const useCarouselContext = () => {
16
16
  };
17
17
  /** 외부에서 캐러셀 컨트롤(emblaApi)에 접근하고 싶을 때 사용하는 훅 */
18
18
  export const useCarousel = useCarouselContext;
19
+ /**
20
+ * `useCarousel`과 같지만 Root 밖에서도 던지지 않고 `null`을 준다.
21
+ * 같은 컴포넌트가 슬라이드로도 쓰이고 단독으로도 쓰이는 경우에 필요하다.
22
+ */
23
+ export const useOptionalCarousel = () => useContext(CarouselContext);
19
24
  const Root = ({ orientation = 'horizontal', loop = false, autoplay = false, autoScroll = false, autoHeight = false, align = 'start', containScroll = 'trimSnaps', options, gap = 16, className, style, children, }) => {
20
25
  // 자동 이동 플러그인 조립. autoScroll(연속 흐름)이 설정되면 autoplay(스텝형)보다 우선.
21
26
  const plugins = [];
@@ -73,6 +78,22 @@ const Root = ({ orientation = 'horizontal', loop = false, autoplay = false, auto
73
78
  emblaApi.off('reInit', onReInitSnaps);
74
79
  };
75
80
  }, [emblaApi, onSelect]);
81
+ // 웹폰트가 나중에 적용되면 글자 높이가 바뀌면서 슬라이드 높이도 달라진다.
82
+ // embla의 ResizeObserver는 가로 축(axis.measureSize)만 보기 때문에 스스로 다시 재지 않고,
83
+ // AutoHeight는 init 때 잰 값을 그대로 쓰므로 트랙이 폰트 적용 전 높이에 고정된다.
84
+ // 그러면 overflow: hidden에 카드 아래 테두리가 잘리므로, 폰트가 준비되면 한 번 더 재게 한다.
85
+ useEffect(() => {
86
+ if (!emblaApi || !document.fonts)
87
+ return;
88
+ let isCancelled = false;
89
+ document.fonts.ready.then(() => {
90
+ if (!isCancelled)
91
+ emblaApi.reInit();
92
+ });
93
+ return () => {
94
+ isCancelled = true;
95
+ };
96
+ }, [emblaApi]);
76
97
  const scrollPrev = useCallback(() => emblaApi?.scrollPrev(), [emblaApi]);
77
98
  const scrollNext = useCallback(() => emblaApi?.scrollNext(), [emblaApi]);
78
99
  const scrollTo = useCallback((index) => emblaApi?.scrollTo(index), [emblaApi]);
@@ -23,8 +23,8 @@ export interface LDCarouselProps {
23
23
  /** embla 세부 옵션. 스크롤이 너무 빠르면 `duration`을 키우세요(기본 25, 클수록 느리고 부드러움).
24
24
  * 드래그 민감도는 `dragThreshold`(드래그 인식 거리)·`dragFree`(스냅 없이 자유 스크롤)로 조절합니다. */
25
25
  options?: RootProps['options'];
26
- /** 이전/다음 화살표 위치. 'top'(상단)·'side'(좌우)·'none'(숨김). 기본 'top' */
27
- arrowPosition?: 'top' | 'side' | 'none';
26
+ /** 이전/다음 화살표 위치. 'top'(상단)·'side'(좌우)·'bottom'(dots와 같은 줄 우측)·'none'(숨김). 기본 'top' */
27
+ arrowPosition?: 'top' | 'side' | 'bottom' | 'none';
28
28
  showDots?: boolean;
29
29
  /** "현재 / 전체" 숫자 표시. 기본 false */
30
30
  showCounter?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"LDCarousel.d.ts","sourceRoot":"","sources":["../../../src/components/LDCarousel/LDCarousel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAErE,OAAqB,EACnB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACf,MAAM,sCAAsC,CAAC;AAG9C,MAAM,WAAW,eAAe;IAC9B,uBAAuB;IACvB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,gCAAgC;IAChC,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,sBAAsB;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrE,0DAA0D;IAC1D,UAAU,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACrC,yDAAyD;IACzD,UAAU,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACrC,sCAAsC;IACtC,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAC3B,8FAA8F;IAC9F,aAAa,CAAC,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;IAC3C;+EAC2E;IAC3E,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/B,8DAA8D;IAC9D,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,mCAAmC;IACnC,IAAI,CAAC,EAAE;QACL;8DACsD;QACtD,IAAI,EAAE,MAAM,CAAC;QACb,8EAA8E;QAC9E,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;KACtB,CAAC;IACF,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,wCAAwC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,QAAA,MAAM,UAAU;2NAoBb,eAAe;;;;;;;;;;CA0FjB,CAAC;AAYF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"LDCarousel.d.ts","sourceRoot":"","sources":["../../../src/components/LDCarousel/LDCarousel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAErE,OAAqB,EACnB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACf,MAAM,sCAAsC,CAAC;AAG9C,MAAM,WAAW,eAAe;IAC9B,uBAAuB;IACvB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,gCAAgC;IAChC,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,sBAAsB;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrE,0DAA0D;IAC1D,UAAU,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACrC,yDAAyD;IACzD,UAAU,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACrC,sCAAsC;IACtC,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAC3B,8FAA8F;IAC9F,aAAa,CAAC,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;IAC3C;+EAC2E;IAC3E,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/B,sFAAsF;IACtF,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,mCAAmC;IACnC,IAAI,CAAC,EAAE;QACL;8DACsD;QACtD,IAAI,EAAE,MAAM,CAAC;QACb,8EAA8E;QAC9E,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;KACtB,CAAC;IACF,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,wCAAwC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,QAAA,MAAM,UAAU;2NAoBb,eAAe;;;;;;;;;;CAsGjB,CAAC;AAYF,eAAe,UAAU,CAAC"}
@@ -19,7 +19,7 @@ const LDCarousel = ({ slides, orientation = 'horizontal', loop = false, autoplay
19
19
  'ld-carousel__nav-clearance-y'), children: [arrowPosition === 'side' && _jsx(CarouselBase.Prev, {}), _jsx(CarouselBase.Viewport, { className: cn('w-full', viewportClassName), children: _jsx(CarouselBase.Container, { children: columns.map((column, i) => (_jsx(CarouselBase.Slide, { slidesPerView: slidesPerView, index: i, total: columns.length, className: slideClassName, children: rows <= 1 ? (slides[i]) : (_jsx("div", { className: "grid h-full items-start", style: {
20
20
  gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`,
21
21
  rowGap: gap,
22
- }, children: column.map((slideIndex) => (_jsx(Fragment, { children: slides[slideIndex] }, slideIndex))) })) }, i))) }) }), arrowPosition === 'side' && _jsx(CarouselBase.Next, {})] }), (showDots || showCounter) && (_jsxs("div", { className: "flex items-center justify-center gap-3", children: [showDots && (_jsx(CarouselBase.Dots, { className: isVertical ? 'flex-col' : undefined })), showCounter && _jsx(CarouselBase.Counter, {})] }))] }) }));
22
+ }, children: column.map((slideIndex) => (_jsx(Fragment, { children: slides[slideIndex] }, slideIndex))) })) }, i))) }) }), arrowPosition === 'side' && _jsx(CarouselBase.Next, {})] }), (showDots || showCounter || arrowPosition === 'bottom') && (_jsxs("div", { className: "grid grid-cols-[1fr_auto_1fr] items-center gap-3", children: [_jsx("span", {}), _jsxs("div", { className: "flex items-center justify-center gap-3", children: [showDots && (_jsx(CarouselBase.Dots, { className: isVertical ? 'flex-col' : undefined })), showCounter && _jsx(CarouselBase.Counter, {})] }), arrowPosition === 'bottom' && (_jsx("div", { className: "justify-self-end", children: _jsx(CarouselBase.TopArrows, {}) }))] }))] }) }));
23
23
  };
24
24
  LDCarousel.Root = CarouselBase.Root;
25
25
  LDCarousel.Viewport = CarouselBase.Viewport;
@@ -5,7 +5,7 @@ export interface LDLNBProps {
5
5
  items: INavItem[];
6
6
  /** 현재 경로 (active 판별용) */
7
7
  pathname: string;
8
- /** MenuItem 렌더 엘리먼트 (라우터 Link 주입용, 기본 'a') */
8
+ /** MenuItem 렌더 엘리먼트 (기본 `next/link`. 다른 라우터를 쓰면 교체한다) */
9
9
  as?: ElementType;
10
10
  /** 항목 이동 시 콜백 (라우터 push 등). 모바일에서는 이후 Drawer가 자동으로 닫힘 */
11
11
  onNavigate?: (path: string) => void;
@@ -19,9 +19,12 @@ export interface LDLNBProps {
19
19
  handleLogout?: () => void;
20
20
  /** 데스크탑 사이드바 초기 접힘 상태 */
21
21
  defaultCollapsed?: boolean;
22
- /** 데스크탑 사이드바 기본이자 최대(펼침) 너비(px). 기본 300 */
22
+ /**
23
+ * 사이드바 기본이자 최대(펼침) 너비(px).
24
+ * 생략하면 뷰포트에 따라 PC 400 / 태블릿 280을 쓴다.
25
+ */
23
26
  size?: number;
24
- /** 드래그로 줄일 수 있는 최소 너비(px). 기본 240 */
27
+ /** 드래그로 줄일 수 있는 최소 너비(px). 기본 200 */
25
28
  minWidth?: number;
26
29
  /** 모바일 Drawer가 열리는 방향 (기본 'left') */
27
30
  drawerDirection?: 'left' | 'right';
@@ -1 +1 @@
1
- {"version":3,"file":"LDLNB.d.ts","sourceRoot":"","sources":["../../../src/components/LDLNB/LDLNB.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIpD,OAAgB,EAAE,KAAK,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAIpE,MAAM,WAAW,UAAU;IACzB,kBAAkB;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,yDAAyD;IACzD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,qBAAqB;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAKD;;;;GAIG;AACH,QAAA,MAAM,KAAK,GAAI,yKAgBZ,UAAU,4CA2FZ,CAAC;AAEF,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"LDLNB.d.ts","sourceRoot":"","sources":["../../../src/components/LDLNB/LDLNB.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIpD,OAAgB,EAAE,KAAK,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAIpE,MAAM,WAAW,UAAU;IACzB,kBAAkB;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,yDAAyD;IACzD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,qBAAqB;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD;;;;GAIG;AACH,QAAA,MAAM,KAAK,GAAI,yKAgBZ,UAAU,4CAqGZ,CAAC;AAEF,eAAe,KAAK,CAAC"}
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Menu as MenuIcon } from 'lucide-react';
4
+ import Link from 'next/link';
4
5
  import { useEffect, useState } from 'react';
5
6
  import LDDrawer from '../../components/LDDrawer/LDDrawer.js';
6
7
  import LNBBase from '../../components/LDLNB/LNBBase.js';
@@ -8,27 +9,42 @@ import cn from '../../utils/cn.js';
8
9
  import { isActivePath } from '../../utils/utils.js';
9
10
  // mobile: variant(max-width: calc(--size_md - 1px) = 767px)와 동일 기준
10
11
  const MOBILE_QUERY = '(max-width: 767px)';
12
+ // tablet: variant(--size_md 768px ~ calc(--size_lg - 1px) 991px)와 동일 기준
13
+ const TABLET_QUERY = '(min-width: 768px) and (max-width: 991px)';
14
+ // 태블릿은 화면 자체가 좁아 PC와 같은 400px면 본문을 절반 가까이 먹는다.
15
+ const PC_SIZE = 400;
16
+ const TABLET_SIZE = 280;
11
17
  /**
12
18
  * 반응형 LNB. 데스크탑에서는 인라인 사이드바, 모바일(<768px)에서는 햄버거 버튼 +
13
19
  * Drawer 오버레이(기본 왼쪽, `drawerDirection`으로 조정)로 자동 전환된다.
14
20
  * 뷰포트 감지는 내부에서 처리한다.
15
21
  */
16
- const LDLNB = ({ items, pathname, as, onNavigate, name, email, profileImage, handleLogout, defaultCollapsed = false, size = 400, minWidth = 200, drawerDirection = 'left', triggerClassName, className, children, }) => {
22
+ const LDLNB = ({ items, pathname, as = Link, onNavigate, name, email, profileImage, handleLogout, defaultCollapsed = false, size, minWidth = 200, drawerDirection = 'left', triggerClassName, className, children, }) => {
17
23
  const [isMobile, setIsMobile] = useState(false);
24
+ const [isTablet, setIsTablet] = useState(false);
18
25
  const [open, setOpen] = useState(false);
19
26
  useEffect(() => {
20
- const mql = window.matchMedia(MOBILE_QUERY);
21
- const sync = () => setIsMobile(mql.matches);
27
+ const mobileMql = window.matchMedia(MOBILE_QUERY);
28
+ const tabletMql = window.matchMedia(TABLET_QUERY);
29
+ const sync = () => {
30
+ setIsMobile(mobileMql.matches);
31
+ setIsTablet(tabletMql.matches);
32
+ };
22
33
  sync();
23
- mql.addEventListener('change', sync);
24
- return () => mql.removeEventListener('change', sync);
34
+ mobileMql.addEventListener('change', sync);
35
+ tabletMql.addEventListener('change', sync);
36
+ return () => {
37
+ mobileMql.removeEventListener('change', sync);
38
+ tabletMql.removeEventListener('change', sync);
39
+ };
25
40
  }, []);
26
- const nav = (isMobile) => (_jsx(LNBBase.Provider, { isMobile: isMobile, items: items, pathname: pathname, defaultCollapsed: isMobile ? false : defaultCollapsed, size: size, minWidth: minWidth, children: _jsxs(LNBBase.Root, { className: className, children: [_jsx(LNBBase.Header, { name: name, email: email, profileImage: profileImage, handleLogout: handleLogout }), isMobile && children, _jsx(LNBBase.Content, { children: items.map((group) => (_jsx(LNBBase.Group, { label: group.label, noSlider: group.noSlider, children: _jsx(LNBBase.Menu, { label: group.label, noSlider: group.noSlider, tabCount: group.tabs?.length ?? 0, children: group.tabs?.map((tab) => (_jsx(LNBBase.MenuItem, { as: as, href: tab.path, icon: tab.icon, isActive: isActivePath(pathname, tab.path), onClick: () => {
41
+ const resolvedSize = size ?? (isTablet ? TABLET_SIZE : PC_SIZE);
42
+ const nav = (isMobile) => (_jsx(LNBBase.Provider, { isMobile: isMobile, items: items, pathname: pathname, defaultCollapsed: isMobile ? false : defaultCollapsed, size: resolvedSize, minWidth: minWidth, children: _jsxs(LNBBase.Root, { className: className, trigger: _jsx(LNBBase.Trigger, {}), children: [_jsx(LNBBase.Header, { name: name, email: email, profileImage: profileImage, handleLogout: handleLogout }), isMobile && children, _jsx(LNBBase.Content, { children: items.map((group) => (_jsx(LNBBase.Group, { label: group.label, noSlider: group.noSlider, children: _jsx(LNBBase.Menu, { label: group.label, noSlider: group.noSlider, tabCount: group.tabs?.length ?? 0, children: group.tabs?.map((tab) => (_jsx(LNBBase.MenuItem, { as: as, href: tab.path, icon: tab.icon, isActive: isActivePath(pathname, tab.path), onClick: () => {
27
43
  onNavigate?.(tab.path);
28
44
  setOpen(false);
29
45
  }, children: tab.label }, tab.path))) }) }, group.label))) }), _jsx(LNBBase.ResizeWidthBar, { className: "absolute inset-y-0 right-0" })] }) }));
30
46
  if (!isMobile)
31
47
  return nav(false);
32
- return (_jsx(LDDrawer, { title: "\uC804\uCCB4 \uBA54\uB274", direction: drawerDirection, open: open, onOpenChange: setOpen, className: "w-full max-w-none p-0", trigger: _jsx("button", { type: "button", "aria-label": "\uBA54\uB274 \uC5F4\uAE30", className: cn('flex size-10 cursor-pointer items-center justify-center text-neutral500 ld-transition hover:text-mono900', triggerClassName), children: _jsx(MenuIcon, { size: 20 }) }), children: _jsx("div", { className: "pt-6", children: nav(true) }) }));
48
+ return (_jsx(LDDrawer, { title: "\uC804\uCCB4 \uBA54\uB274", direction: drawerDirection, open: open, onOpenChange: setOpen, className: "w-full max-w-none p-0", trigger: _jsx("button", { type: "button", "aria-label": "\uBA54\uB274 \uC5F4\uAE30", className: cn('flex size-10 cursor-pointer items-center justify-center text-neutral500 ld-transition hover:text-neutral900', triggerClassName), children: _jsx(MenuIcon, { size: 20 }) }), children: _jsx("div", { className: "pt-6", children: nav(true) }) }));
33
49
  };
34
50
  export default LDLNB;
@@ -22,6 +22,14 @@ interface ProviderProps {
22
22
  interface RootProps {
23
23
  children: ReactNode;
24
24
  className?: string;
25
+ /**
26
+ * 패널 **바깥**(오른쪽 여백)에 띄울 요소. `Trigger`를 넣는 자리다.
27
+ *
28
+ * 스크롤 컨테이너 안에 두면 `overflow-y-auto`가 가로축까지 `auto`로 만들어
29
+ * 패널 밖으로 나간 부분이 잘린다. 그래서 children이 아니라 별도 슬롯으로 받아
30
+ * 스크롤 컨테이너 바깥, 위치 기준이 되는 relative 래퍼 직속으로 렌더한다.
31
+ */
32
+ trigger?: ReactNode;
25
33
  }
26
34
  interface TriggerProps {
27
35
  className?: string;
@@ -61,7 +69,7 @@ interface IResizeWidthBar {
61
69
  }
62
70
  declare const LNBBase: {
63
71
  Provider: ({ children, isMobile, items, pathname, size, defaultCollapsed, minWidth, }: ProviderProps) => import("react/jsx-runtime").JSX.Element;
64
- Root: ({ children, className }: RootProps) => import("react/jsx-runtime").JSX.Element;
72
+ Root: ({ children, className, trigger }: RootProps) => import("react/jsx-runtime").JSX.Element;
65
73
  Trigger: ({ className }: TriggerProps) => import("react/jsx-runtime").JSX.Element | null;
66
74
  Header: ({ name, email, profileImage, handleLogout }: HeaderProps) => import("react/jsx-runtime").JSX.Element;
67
75
  Content: ({ children, className }: ContentProps) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"LNBBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDLNB/LNBBase.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,WAAW,EAEX,SAAS,EAEV,MAAM,OAAO,CAAC;AAoBf,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAiDD,UAAU,aAAa;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAuFD,UAAU,SAAS;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+BD,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAqCD,UAAU,YAAY;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD,UAAU,UAAU;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuCD,UAAU,SAAS;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA6BD,UAAU,aAAa;IACrB,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAgCD,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgDD,QAAA,MAAM,OAAO;2FAjXV,aAAa;oCAkFuB,SAAS;6BAiChB,YAAY;0DA+BiB,WAAW;uCAwC9B,YAAY;2CAsBR,UAAU;oDA4CG,SAAS;iFA6CjE,aAAa;oCA0BuB,eAAe;CAwDrD,CAAC;AAEF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"LNBBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDLNB/LNBBase.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,WAAW,EAEX,SAAS,EAEV,MAAM,OAAO,CAAC;AAoBf,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAiDD,UAAU,aAAa;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA6FD,UAAU,SAAS;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAgCD,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAqCD,UAAU,YAAY;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD,UAAU,UAAU;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuCD,UAAU,SAAS;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA6BD,UAAU,aAAa;IACrB,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAgCD,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAmDD,QAAA,MAAM,OAAO;2FApYV,aAAa;6CAgGgC,SAAS;6BAkCzB,YAAY;0DAgCiB,WAAW;uCAwC9B,YAAY;2CAsBR,UAAU;oDA4CG,SAAS;iFA6CjE,aAAa;oCA0BuB,eAAe;CA2DrD,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -36,6 +36,11 @@ const Provider = ({ children, isMobile, items = [], pathname = '', size = DEFAUL
36
36
  setOpenGroups((prev) => prev.includes(label) ? prev.filter((g) => g !== label) : [...prev, label]);
37
37
  }, []);
38
38
  const isGroupOpen = useCallback((label) => openGroups.includes(label), [openGroups]);
39
+ // size(펼침 기본 너비)는 뷰포트 구간에 따라 바뀐다. width는 useState 초기값이라
40
+ // 그대로 두면 마운트 시점 값에 고정되므로, size가 바뀌면 새 기본값으로 맞춘다.
41
+ useEffect(() => {
42
+ setWidth(size);
43
+ }, [size]);
39
44
  useEffect(() => {
40
45
  if (!isMobile)
41
46
  return;
@@ -73,17 +78,17 @@ const Provider = ({ children, isMobile, items = [], pathname = '', size = DEFAUL
73
78
  const widthContextValue = useMemo(() => ({ width, setWidth, isResizing, setIsResizing }), [width, isResizing]);
74
79
  return (_jsx(LNBContext, { value: contextValue, children: _jsx(LNBWidthContext, { value: widthContextValue, children: children }) }));
75
80
  };
76
- const Root = ({ children, className }) => {
81
+ const Root = ({ children, className, trigger }) => {
77
82
  const { isMobile, collapsed } = useLNBContext();
78
83
  const { width, isResizing } = useLNBWidthContext();
79
- return (_jsx("div", { className: cn('relative mobile:w-full', !isResizing && 'ld-transition', collapsed ? 'w-[60px]' : `w-[${width}px]`, className), style: collapsed || isMobile ? undefined : { width }, children: _jsx("div", { className: cn('size-full bg-mono50 mobile:bg-white', 'h-[calc(100vh-64px)] mobile:h-auto mobile:overflow-hidden', 'scrollbar-hide flex scrollbar-hover flex-col gap-md overflow-y-auto p-sm mobile:py-0'), children: children }) }));
84
+ return (_jsxs("div", { className: cn('relative mobile:w-full', !isResizing && 'ld-transition', collapsed ? 'w-[60px]' : `w-[${width}px]`, className), style: collapsed || isMobile ? undefined : { width }, children: [trigger, _jsx("div", { className: cn('size-full bg-mono50 mobile:bg-white', 'h-[calc(100vh-64px)] mobile:h-auto mobile:overflow-hidden', 'scrollbar-hide flex scrollbar-hover flex-col gap-md overflow-y-auto p-sm mobile:py-0'), children: children })] }));
80
85
  };
81
86
  const Trigger = ({ className }) => {
82
87
  const { isMobile, collapsed, toggleCollapsed } = useLNBContext();
83
88
  const Icon = collapsed ? PanelLeftOpen : PanelLeftClose;
84
89
  if (isMobile)
85
90
  return null;
86
- return (_jsx("button", { type: "button", onClick: toggleCollapsed, className: cn('absolute top-0 -right-10 z-10', 'flex size-10 items-center justify-center', 'text-neutral500', 'cursor-pointer ld-transition hover:text-mono900', className), "aria-label": collapsed ? '사이드바 펼치기' : '사이드바 접기', children: _jsx(Icon, { size: 16 }) }));
91
+ return (_jsx("button", { type: "button", onClick: toggleCollapsed, className: cn('absolute top-0 -right-10 z-10', 'flex size-10 items-center justify-center', 'text-neutral500', 'cursor-pointer ld-transition hover:text-neutral900', className), "aria-label": collapsed ? '사이드바 펼치기' : '사이드바 접기', children: _jsx(Icon, { size: 20 }) }));
87
92
  };
88
93
  const Header = ({ name, email, profileImage, handleLogout }) => {
89
94
  const { collapsed } = useLNBContext();
@@ -112,7 +117,7 @@ const Menu = ({ children, label, noSlider, tabCount = 0 }) => {
112
117
  };
113
118
  const MenuItem = ({ as: Comp = 'a', href, isActive, children, icon, className, ...rest }) => {
114
119
  const { collapsed } = useLNBContext();
115
- return (_jsxs(Comp, { href: href, className: cn('flex w-full items-center gap-sm p-sm display16 bold mobile:display14 mobile:medium', 'cursor-pointer rounded-[5px] text-neutral500 ld-transition hover:bg-mono300 hover:text-mono900', 'overflow-hidden whitespace-nowrap', collapsed && 'justify-center', isActive &&
120
+ return (_jsxs(Comp, { href: href, className: cn('flex w-full items-center gap-sm p-sm display16 bold mobile:display14 mobile:medium', 'cursor-pointer rounded-[5px] text-neutral500 ld-transition hover:bg-neutral100 hover:text-neutral900', 'overflow-hidden whitespace-nowrap', collapsed && 'justify-center', isActive &&
116
121
  'bg-tintBlue text-blue400 hover:bg-tintBlue hover:text-blue400', className), ...rest, children: [_jsx(RenderIcon, { className: "icon-md", children: icon }), !collapsed && children] }));
117
122
  };
118
123
  const ResizeWidthBar = ({ className }) => {
@@ -142,7 +147,11 @@ const ResizeWidthBar = ({ className }) => {
142
147
  document.body.addEventListener('mousemove', onMouseMove);
143
148
  document.body.addEventListener('mouseup', onMouseUp, { once: true });
144
149
  };
145
- return (_jsx("div", { className: cn('group flex w-1 translate-x-1 justify-start ld-transition', className), onMouseDown: handleResizeWidth, children: _jsx("div", { className: "h-full w-px -translate-x-px ld-transition group-hover:cursor-col-resize group-hover:bg-lb500" }) }));
150
+ return (
151
+ // 히트 영역은 12px. 잡히는 폭이 1px 선 그대로면 커서를 맞추기가 어렵다는
152
+ // 피드백이 있어, 보이는 선은 1px로 두고 경계선을 가운데 두는 12px 띠로 넓혔다.
153
+ // cursor도 이 바깥 요소에 준다 — 안쪽 1px에만 걸면 그 1px 위에서만 커서가 바뀐다.
154
+ _jsx("div", { className: cn('group flex w-3 translate-x-1.5 cursor-col-resize justify-center', className), onMouseDown: handleResizeWidth, children: _jsx("div", { className: "h-full w-px ld-transition group-hover:bg-lb500" }) }));
146
155
  };
147
156
  // ── Export ──
148
157
  const LNBBase = {
@@ -1,4 +1,4 @@
1
- import { type CSSProperties, type ReactNode } from 'react';
1
+ import { type CSSProperties, type ReactNode, type Ref } from 'react';
2
2
  import { IClassNames } from '../../components/LDTable/LDTanstackTable.js';
3
3
  export interface LDTableProps {
4
4
  /** 테이블 콘텐츠 (LDTable.Header, LDTable.Body 등) */
@@ -30,6 +30,7 @@ declare const LDTable: {
30
30
  Body: ({ className, children, ...props }: React.HTMLAttributes<HTMLTableSectionElement>) => import("react/jsx-runtime").JSX.Element;
31
31
  Row: ({ className, children, ...props }: React.HTMLAttributes<HTMLTableRowElement> & {
32
32
  selected?: boolean;
33
+ ref?: Ref<HTMLTableRowElement>;
33
34
  }) => import("react/jsx-runtime").JSX.Element;
34
35
  Cell: ({ className, children, ...props }: React.TdHTMLAttributes<HTMLTableCellElement>) => import("react/jsx-runtime").JSX.Element;
35
36
  };
@@ -1 +1 @@
1
- {"version":3,"file":"LDTable.d.ts","sourceRoot":"","sources":["../../../src/components/LDTable/LDTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAInE,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,QAAQ,EAAE,SAAS,CAAC;IACpB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,sCAAsC;IACtC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,mBAAmB;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uBAAuB;IACvB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,uBAAuB;IACvB,UAAU,CAAC,EAAE,WAAW,CAAC;CAQ1B;AAED,QAAA,MAAM,OAAO;yHAWV,YAAY;gDAgFZ,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC;mDAgB7C,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC;oDAUzC,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;8CAa5C,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC;6CAU7C,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC,GAAG;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE;8CAgBlE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;CA5G9C,CAAC;AA4HF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"LDTable.d.ts","sourceRoot":"","sources":["../../../src/components/LDTable/LDTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAErE,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAInE,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,QAAQ,EAAE,SAAS,CAAC;IACpB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,sCAAsC;IACtC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,mBAAmB;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uBAAuB;IACvB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,uBAAuB;IACvB,UAAU,CAAC,EAAE,WAAW,CAAC;CAQ1B;AAED,QAAA,MAAM,OAAO;yHAWV,YAAY;gDAyFZ,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC;mDAgB7C,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC;oDAUzC,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;8CAa5C,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC;6CAU7C,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC,GAAG;QAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,GAAG,CAAC,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;KAChC;8CAgBE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;CA/G9C,CAAC;AA+HF,eAAe,OAAO,CAAC"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import TableBase from '../../components/LDTable/TableBase.js';
3
3
  import cn from '../../utils/cn.js';
4
4
  const LDTable = ({ children, title, totalCount, rightSideContents, footer, isEmpty = false, emptyMessage = '조회하신 데이터가 없습니다.', columnCount, style, classNames, }) => {
5
- return (_jsxs("div", { className: cn('flex h-full flex-col justify-between gap-md', classNames?.wrapper), children: [_jsx(Toolbar, { title: title, totalCount: totalCount, rightSideContents: rightSideContents, className: classNames?.toolbar }), _jsx("div", { className: cn('relative w-full overflow-auto', classNames?.scroll), children: _jsxs(TableBase.Root, { className: cn('w-full', classNames?.root), style: style, children: [children, isEmpty && columnCount && (_jsx(TableBase.Body, { className: classNames?.tbody, children: _jsx(TableBase.Row, { className: classNames?.row, children: _jsx(TableBase.Cell, { colSpan: columnCount, className: cn('h-48 text-center'), children: emptyMessage }) }) }))] }) }), footer] }));
5
+ return (_jsxs("div", { className: cn('flex h-full flex-col justify-between gap-md', classNames?.wrapper), children: [_jsx(Toolbar, { title: title, totalCount: totalCount, rightSideContents: rightSideContents, className: classNames?.toolbar }), _jsx("div", { "aria-label": title ?? 'table', className: cn('relative w-full overflow-auto', classNames?.scroll), role: "region", tabIndex: 0, children: _jsxs(TableBase.Root, { className: cn('w-full', classNames?.root), style: style, children: [children, isEmpty && columnCount && (_jsx(TableBase.Body, { className: classNames?.tbody, children: _jsx(TableBase.Row, { className: classNames?.row, children: _jsx(TableBase.Cell, { colSpan: columnCount, className: cn('h-48 text-center'), children: emptyMessage }) }) }))] }) }), footer] }));
6
6
  };
7
7
  const Toolbar = ({ title, totalCount, rightSideContents, className, }) => {
8
8
  if (!title && !rightSideContents)
@@ -13,12 +13,24 @@ export interface IClassNames {
13
13
  row?: string;
14
14
  cell?: string;
15
15
  }
16
+ export interface RowReorderEvent {
17
+ /** 옮긴 행의 id (`getRowId` 결과) */
18
+ activeId: string;
19
+ /** 놓인 자리에 있던 행의 id */
20
+ overId: string;
21
+ /** 옮긴 행의 원본 `data` 배열에서의 위치 */
22
+ oldIndex: number;
23
+ /** 놓인 자리의 원본 `data` 배열에서의 위치 */
24
+ newIndex: number;
25
+ }
16
26
  export interface LDTanstackTableProps<TData, TColumn> extends Omit<HeadlessTableProps<TData, TColumn>, 'children'> {
17
27
  title?: string;
18
28
  rightSideContents?: ReactNode;
19
29
  emptyMessage?: string | ReactNode;
20
30
  classNames?: IClassNames;
31
+ enableRowDragging?: boolean;
32
+ onRowReorder?: (event: RowReorderEvent) => void;
21
33
  }
22
- declare const LDTanstackTable: <TData, TColumn>({ columns, data, rowCount, paginationState, onPageChange, sortingState, enableRowSelection, enableMultiRowSelection, rowSelectionState, getRowId, rightSideContents, title, emptyMessage, classNames, }: LDTanstackTableProps<TData, TColumn>) => import("react/jsx-runtime").JSX.Element;
34
+ declare const LDTanstackTable: <TData, TColumn>({ columns, data, rowCount, paginationState, onPageChange, sortingState, enableRowSelection, enableMultiRowSelection, rowSelectionState, getRowId, rightSideContents, title, emptyMessage, classNames, enableRowDragging, onRowReorder, }: LDTanstackTableProps<TData, TColumn>) => import("react/jsx-runtime").JSX.Element;
23
35
  export default LDTanstackTable;
24
36
  //# sourceMappingURL=LDTanstackTable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LDTanstackTable.d.ts","sourceRoot":"","sources":["../../../src/components/LDTable/LDTanstackTable.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAsB,EACpB,KAAK,kBAAkB,EACxB,MAAM,oCAAoC,CAAC;AAK5C,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAE,SAAQ,IAAI,CAChE,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,EAClC,UAAU,CACX;IACC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,QAAA,MAAM,eAAe,GAAI,KAAK,EAAE,OAAO,EAAE,yMAetC,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,4CAwJtC,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"LDTanstackTable.d.ts","sourceRoot":"","sources":["../../../src/components/LDTable/LDTanstackTable.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAsB,EACpB,KAAK,kBAAkB,EACxB,MAAM,oCAAoC,CAAC;AAW5C,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAE,SAAQ,IAAI,CAChE,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,EAClC,UAAU,CACX;IACC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CACjD;AAED,QAAA,MAAM,eAAe,GAAI,KAAK,EAAE,OAAO,EAAE,0OAiBtC,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,4CAgMtC,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -4,10 +4,36 @@ import { ArrowDown, ArrowUp } from 'lucide-react';
4
4
  import LDPagination from '../../components/LDPagination/LDPagination.js';
5
5
  import HeadlessTable from '../../components/LDTable/HeadlessTable.js';
6
6
  import LDTable from '../../components/LDTable/LDTable.js';
7
+ import { PlainRow, RowDndProvider, RowSortableProvider, SortableRow, } from '../../components/LDTable/TableRowDnd.js';
7
8
  import cn from '../../utils/cn.js';
8
- const LDTanstackTable = ({ columns, data, rowCount, paginationState, onPageChange, sortingState, enableRowSelection, enableMultiRowSelection, rowSelectionState, getRowId, rightSideContents, title, emptyMessage, classNames, }) => {
9
+ const LDTanstackTable = ({ columns, data, rowCount, paginationState, onPageChange, sortingState, enableRowSelection, enableMultiRowSelection, rowSelectionState, getRowId, rightSideContents, title, emptyMessage, classNames, enableRowDragging = false, onRowReorder, }) => {
9
10
  return (_jsx(HeadlessTable, { columns: columns, data: data, rowCount: rowCount, paginationState: paginationState, onPageChange: onPageChange, sortingState: sortingState, enableRowSelection: enableRowSelection, enableMultiRowSelection: enableMultiRowSelection, rowSelectionState: rowSelectionState, getRowId: getRowId, children: ({ headerGroups, rows, isEmpty, tableStyle, visibleColumnCount, currentPage, totalPages, hasPagination, onPageChange: handlePageChange, getHeader, getCell, }) => {
10
- return (_jsxs(LDTable, { title: title, totalCount: rowCount, rightSideContents: rightSideContents, isEmpty: isEmpty, emptyMessage: emptyMessage, columnCount: visibleColumnCount, footer: hasPagination && (_jsx(LDPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, className: classNames?.pagination })), style: tableStyle, classNames: {
11
+ const rowIds = rows.map((row) => row.id);
12
+ const dataIndexByRowId = new Map(rows.map((row) => [row.id, row.index]));
13
+ const handleRowDragEnd = (activeId, overId) => {
14
+ const active = String(activeId);
15
+ const over = String(overId);
16
+ const oldIndex = dataIndexByRowId.get(active);
17
+ const newIndex = dataIndexByRowId.get(over);
18
+ if (oldIndex === undefined || newIndex === undefined)
19
+ return;
20
+ onRowReorder?.({
21
+ activeId: active,
22
+ overId: over,
23
+ oldIndex,
24
+ newIndex,
25
+ });
26
+ };
27
+ const RowComp = enableRowDragging ? SortableRow : PlainRow;
28
+ const bodyRows = rows.map((row) => (_jsx(RowComp, { rowId: row.id, selected: row.getIsSelected(), className: classNames?.row, onClick: () => row.toggleSelected(), children: row.getVisibleCells().map((cell) => {
29
+ const c = getCell(cell);
30
+ return (_jsx(LDTable.Cell, { className: classNames?.cell, children: _jsx("div", { className: cn('flex w-full items-center', c.meta?.headerAlign === 'left'
31
+ ? 'justify-start'
32
+ : c.meta?.headerAlign === 'right'
33
+ ? 'justify-end'
34
+ : 'justify-center'), children: _jsx("span", { className: "min-w-0 truncate", children: c.renderCell() }) }) }, c.id));
35
+ }) }, row.id)));
36
+ const table = (_jsxs(LDTable, { title: title, totalCount: rowCount, rightSideContents: rightSideContents, isEmpty: isEmpty, emptyMessage: emptyMessage, columnCount: visibleColumnCount, footer: hasPagination && (_jsx(LDPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, className: classNames?.pagination })), style: tableStyle, classNames: {
11
37
  ...classNames,
12
38
  root: cn('table-fixed', classNames?.root),
13
39
  }, children: [_jsx(LDTable.Header, { className: classNames?.thead, children: headerGroups.map((hg) => (_jsx(LDTable.HeaderRow, { className: cn('group w-full', classNames?.headRow), children: hg.headers.map((header) => {
@@ -17,14 +43,10 @@ const LDTanstackTable = ({ columns, data, rowCount, paginationState, onPageChang
17
43
  : h.meta?.headerAlign === 'left'
18
44
  ? 'justify-start'
19
45
  : 'justify-center'), children: [_jsx("span", { className: "min-w-0 truncate", children: h.renderHeader() }), h.isSorted === 'asc' && (_jsx(ArrowUp, { className: "size-3 shrink-0" })), h.isSorted === 'desc' && (_jsx(ArrowDown, { className: "size-3 shrink-0" }))] }), h.canResize && (_jsx("div", { onPointerDown: h.resizeHandler, onClick: (e) => e.stopPropagation(), className: cn('absolute top-0 right-0 flex h-full w-5 touch-none justify-end opacity-0 select-none ld-transition group-hover:cursor-col-resize group-hover:opacity-100'), children: _jsx("div", { className: "h-full w-1 bg-neutral200" }) }))] }, h.id));
20
- }) }, hg.id))) }), _jsx(LDTable.Body, { children: rows.map((row) => (_jsx(LDTable.Row, { selected: row.getIsSelected(), className: classNames?.row, onClick: () => row.toggleSelected(), children: row.getVisibleCells().map((cell) => {
21
- const c = getCell(cell);
22
- return (_jsx(LDTable.Cell, { className: classNames?.cell, children: _jsx("div", { className: cn('flex w-full items-center', c.meta?.headerAlign === 'left'
23
- ? 'justify-start'
24
- : c.meta?.headerAlign === 'right'
25
- ? 'justify-end'
26
- : 'justify-center'), children: _jsx("span", { className: "min-w-0 truncate", children: c.renderCell() }) }) }, c.id));
27
- }) }, row.id))) })] }));
46
+ }) }, hg.id))) }), _jsx(LDTable.Body, { children: enableRowDragging ? (_jsx(RowSortableProvider, { rowIds: rowIds, children: bodyRows })) : (bodyRows) })] }));
47
+ if (!enableRowDragging)
48
+ return table;
49
+ return (_jsx(RowDndProvider, { onRowDragEnd: handleRowDragEnd, children: table }));
28
50
  } }));
29
51
  };
30
52
  export default LDTanstackTable;
@@ -15,6 +15,7 @@ interface HeaderRowProps extends HTMLAttributes<HTMLTableRowElement> {
15
15
  interface RowProps extends HTMLAttributes<HTMLTableRowElement> {
16
16
  children?: ReactNode;
17
17
  selected?: boolean;
18
+ ref?: Ref<HTMLTableRowElement>;
18
19
  }
19
20
  interface HeaderCellProps extends ThHTMLAttributes<HTMLTableCellElement> {
20
21
  children?: ReactNode;
@@ -29,7 +30,7 @@ export declare const TableBase: {
29
30
  Header: ({ className, children, ...props }: HeaderProps) => import("react/jsx-runtime").JSX.Element;
30
31
  Body: ({ className, children, ...props }: BodyProps) => import("react/jsx-runtime").JSX.Element;
31
32
  HeaderRow: ({ className, children, ...props }: HeaderRowProps) => import("react/jsx-runtime").JSX.Element;
32
- Row: ({ className, children, selected, ...props }: RowProps) => import("react/jsx-runtime").JSX.Element;
33
+ Row: ({ className, children, selected, ref, ...props }: RowProps) => import("react/jsx-runtime").JSX.Element;
33
34
  HeaderCell: ({ className, children, sortable, sortDirection, ...props }: HeaderCellProps) => import("react/jsx-runtime").JSX.Element;
34
35
  Cell: ({ className, children, ...props }: CellProps) => import("react/jsx-runtime").JSX.Element;
35
36
  };
@@ -1 +1 @@
1
- {"version":3,"file":"TableBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDTable/TableBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,GAAG,EACR,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,OAAO,CAAC;AAKf,UAAU,SAAU,SAAQ,cAAc,CAAC,gBAAgB,CAAC;IAC1D,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAgBD,UAAU,WAAY,SAAQ,cAAc,CAAC,uBAAuB,CAAC;IACnE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,SAAU,SAAQ,cAAc,CAAC,uBAAuB,CAAC;IACjE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,cAAe,SAAQ,cAAc,CAAC,mBAAmB,CAAC;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,QAAS,SAAQ,cAAc,CAAC,mBAAmB,CAAC;IAC5D,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAiBD,UAAU,eAAgB,SAAQ,gBAAgB,CAAC,oBAAoB,CAAC;IACtE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;CACxC;AA8BD,UAAU,SAAU,SAAQ,gBAAgB,CAAC,oBAAoB,CAAC;IAChE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAUD,eAAO,MAAM,SAAS;mDAvHgC,SAAS;gDAkBZ,WAAW;8CAab,SAAS;mDAaJ,cAAc;uDAcV,QAAQ;6EA2B/D,eAAe;8CA0B+B,SAAS;CAgBzD,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"TableBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDTable/TableBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,GAAG,EACR,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,OAAO,CAAC;AAKf,UAAU,SAAU,SAAQ,cAAc,CAAC,gBAAgB,CAAC;IAC1D,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAgBD,UAAU,WAAY,SAAQ,cAAc,CAAC,uBAAuB,CAAC;IACnE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,SAAU,SAAQ,cAAc,CAAC,uBAAuB,CAAC;IACjE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,cAAe,SAAQ,cAAc,CAAC,mBAAmB,CAAC;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,QAAS,SAAQ,cAAc,CAAC,mBAAmB,CAAC;IAC5D,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;CAChC;AAkBD,UAAU,eAAgB,SAAQ,gBAAgB,CAAC,oBAAoB,CAAC;IACtE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;CACxC;AA8BD,UAAU,SAAU,SAAQ,gBAAgB,CAAC,oBAAoB,CAAC;IAChE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAUD,eAAO,MAAM,SAAS;mDAzHgC,SAAS;gDAkBZ,WAAW;8CAab,SAAS;mDAaJ,cAAc;4DAeL,QAAQ;6EA4BpE,eAAe;8CA0B+B,SAAS;CAgBzD,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -12,8 +12,8 @@ const Body = ({ className, children, ...props }) => {
12
12
  const HeaderRow = ({ className, children, ...props }) => {
13
13
  return (_jsx("tr", { role: "row", className: className, ...props, children: children }));
14
14
  };
15
- const Row = ({ className, children, selected, ...props }) => {
16
- return (_jsx("tr", { role: "row", "aria-selected": selected, "data-state": selected ? 'selected' : undefined, className: className, ...props, children: children }));
15
+ const Row = ({ className, children, selected, ref, ...props }) => {
16
+ return (_jsx("tr", { ref: ref, role: "row", "aria-selected": selected, "data-state": selected ? 'selected' : undefined, className: className, ...props, children: children }));
17
17
  };
18
18
  const HeaderCell = ({ className, children, sortable, sortDirection, ...props }) => {
19
19
  return (_jsx("th", { role: "columnheader", "aria-sort": sortDirection === 'asc'
@@ -0,0 +1,26 @@
1
+ import { type UniqueIdentifier } from '@dnd-kit/core';
2
+ import { type ReactNode } from 'react';
3
+ export declare const RowDndProvider: ({ onRowDragEnd, children, }: {
4
+ onRowDragEnd: (activeId: UniqueIdentifier, overId: UniqueIdentifier) => void;
5
+ children: ReactNode;
6
+ }) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const RowSortableProvider: ({ rowIds, children, }: {
8
+ rowIds: UniqueIdentifier[];
9
+ children: ReactNode;
10
+ }) => import("react/jsx-runtime").JSX.Element;
11
+ export interface TableRowProps {
12
+ rowId: string;
13
+ selected?: boolean;
14
+ className?: string;
15
+ onClick?: () => void;
16
+ children: ReactNode;
17
+ }
18
+ /** 드래그가 꺼져 있을 때의 행. `SortableRow`와 prop 모양을 맞춰 교체 가능하게 둔다 */
19
+ export declare const PlainRow: ({ selected, className, onClick, children, }: TableRowProps) => import("react/jsx-runtime").JSX.Element;
20
+ /** 드래그가 켜져 있을 때의 행 */
21
+ export declare const SortableRow: ({ rowId, selected, className, onClick, children, }: TableRowProps) => import("react/jsx-runtime").JSX.Element;
22
+ export declare const LDRowDragHandle: ({ rowId, className, }: {
23
+ rowId: string;
24
+ className?: string;
25
+ }) => import("react/jsx-runtime").JSX.Element;
26
+ //# sourceMappingURL=TableRowDnd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableRowDnd.d.ts","sourceRoot":"","sources":["../../../src/components/LDTable/TableRowDnd.tsx"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,gBAAgB,EAGtB,MAAM,eAAe,CAAC;AAUvB,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,eAAO,MAAM,cAAc,GAAI,6BAG5B;IACD,YAAY,EAAE,CAAC,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7E,QAAQ,EAAE,SAAS,CAAC;CACrB,4CAwBA,CAAC;AAIF,eAAO,MAAM,mBAAmB,GAAI,uBAGjC;IACD,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,QAAQ,EAAE,SAAS,CAAC;CACrB,4CAIA,CAAC;AAIF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,6DAA6D;AAC7D,eAAO,MAAM,QAAQ,GAAI,6CAKtB,aAAa,4CAIf,CAAC;AAEF,sBAAsB;AACtB,eAAO,MAAM,WAAW,GAAI,oDAMzB,aAAa,4CAmBf,CAAC;AAIF,eAAO,MAAM,eAAe,GAAI,uBAG7B;IACD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,4CAoBA,CAAC"}
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { closestCenter, DndContext, KeyboardSensor, MouseSensor, TouchSensor, useSensor, useSensors, } from '@dnd-kit/core';
4
+ import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
5
+ import { SortableContext, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy, } from '@dnd-kit/sortable';
6
+ import { CSS } from '@dnd-kit/utilities';
7
+ import { GripVertical } from 'lucide-react';
8
+ import LDTable from '../../components/LDTable/LDTable.js';
9
+ import cn from '../../utils/cn.js';
10
+ // ── DndContext ──
11
+ export const RowDndProvider = ({ onRowDragEnd, children, }) => {
12
+ const sensors = useSensors(useSensor(MouseSensor), useSensor(TouchSensor), useSensor(KeyboardSensor, {
13
+ coordinateGetter: sortableKeyboardCoordinates,
14
+ }));
15
+ const handleDragEnd = ({ active, over }) => {
16
+ if (!over || active.id === over.id)
17
+ return;
18
+ onRowDragEnd(active.id, over.id);
19
+ };
20
+ return (_jsx(DndContext, { collisionDetection: closestCenter, modifiers: [restrictToVerticalAxis], onDragEnd: handleDragEnd, sensors: sensors, children: children }));
21
+ };
22
+ // ── SortableContext ──
23
+ export const RowSortableProvider = ({ rowIds, children, }) => (_jsx(SortableContext, { items: rowIds, strategy: verticalListSortingStrategy, children: children }));
24
+ /** 드래그가 꺼져 있을 때의 행. `SortableRow`와 prop 모양을 맞춰 교체 가능하게 둔다 */
25
+ export const PlainRow = ({ selected, className, onClick, children, }) => (_jsx(LDTable.Row, { selected: selected, className: className, onClick: onClick, children: children }));
26
+ /** 드래그가 켜져 있을 때의 행 */
27
+ export const SortableRow = ({ rowId, selected, className, onClick, children, }) => {
28
+ const { setNodeRef, transform, transition, isDragging } = useSortable({
29
+ id: rowId,
30
+ });
31
+ return (_jsx(LDTable.Row, { ref: setNodeRef, selected: selected, className: cn(isDragging && 'relative z-10 opacity-80', className), onClick: onClick, style: {
32
+ transform: CSS.Transform.toString(transform),
33
+ transition: isDragging ? 'none' : transition,
34
+ }, children: children }));
35
+ };
36
+ // ── Handle ──
37
+ export const LDRowDragHandle = ({ rowId, className, }) => {
38
+ const { attributes, listeners, isDragging } = useSortable({ id: rowId });
39
+ return (_jsx("button", { type: "button", "aria-label": "\uC21C\uC11C \uBCC0\uACBD", onClick: (e) => e.stopPropagation(), className: cn('flex size-6 touch-none items-center justify-center', 'text-neutral400 ld-transition hover:text-neutral700', isDragging ? 'cursor-grabbing' : 'cursor-grab', className), ...attributes, ...listeners, children: _jsx(GripVertical, { size: 16 }) }));
40
+ };
package/dist/index.css CHANGED
@@ -1675,6 +1675,9 @@
1675
1675
  .w-2 {
1676
1676
  width: calc(var(--spacing) * 2);
1677
1677
  }
1678
+ .w-3 {
1679
+ width: calc(var(--spacing) * 3);
1680
+ }
1678
1681
  .w-4 {
1679
1682
  width: calc(var(--spacing) * 4);
1680
1683
  }
@@ -1834,6 +1837,17 @@
1834
1837
  .border-collapse {
1835
1838
  border-collapse: collapse;
1836
1839
  }
1840
+ .border-separate {
1841
+ border-collapse: separate;
1842
+ }
1843
+ .border-spacing-x-4 {
1844
+ --tw-border-spacing-x: calc(var(--spacing) * 4);
1845
+ border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y);
1846
+ }
1847
+ .border-spacing-y-3 {
1848
+ --tw-border-spacing-y: calc(var(--spacing) * 3);
1849
+ border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y);
1850
+ }
1837
1851
  .animate-bell {
1838
1852
  animation: bell-ring 600ms ease-in-out;
1839
1853
  transform-origin: top center;
@@ -1847,12 +1861,8 @@
1847
1861
  --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);
1848
1862
  translate: var(--tw-translate-x) var(--tw-translate-y);
1849
1863
  }
1850
- .-translate-x-px {
1851
- --tw-translate-x: -1px;
1852
- translate: var(--tw-translate-x) var(--tw-translate-y);
1853
- }
1854
- .translate-x-1 {
1855
- --tw-translate-x: calc(var(--spacing) * 1);
1864
+ .translate-x-1\.5 {
1865
+ --tw-translate-x: calc(var(--spacing) * 1.5);
1856
1866
  translate: var(--tw-translate-x) var(--tw-translate-y);
1857
1867
  }
1858
1868
  .-translate-y-1\/2 {
@@ -1914,6 +1924,12 @@
1914
1924
  .cursor-default {
1915
1925
  cursor: default;
1916
1926
  }
1927
+ .cursor-grab {
1928
+ cursor: grab;
1929
+ }
1930
+ .cursor-grabbing {
1931
+ cursor: grabbing;
1932
+ }
1917
1933
  .cursor-not-allowed {
1918
1934
  cursor: not-allowed;
1919
1935
  }
@@ -1941,6 +1957,9 @@
1941
1957
  .grid-cols-7 {
1942
1958
  grid-template-columns: repeat(7, minmax(0, 1fr));
1943
1959
  }
1960
+ .grid-cols-\[1fr_auto_1fr\] {
1961
+ grid-template-columns: 1fr auto 1fr;
1962
+ }
1944
1963
  .grid-cols-\[64px_repeat\(3\,180px\)\] {
1945
1964
  grid-template-columns: 64px repeat(3,180px);
1946
1965
  }
@@ -2010,9 +2029,6 @@
2010
2029
  .gap-2\.5 {
2011
2030
  gap: calc(var(--spacing) * 2.5);
2012
2031
  }
2013
- .gap-2xl {
2014
- gap: var(--spacing_64);
2015
- }
2016
2032
  .gap-2xs {
2017
2033
  gap: var(--spacing_4);
2018
2034
  }
@@ -2086,6 +2102,9 @@
2086
2102
  .self-stretch {
2087
2103
  align-self: stretch;
2088
2104
  }
2105
+ .justify-self-end {
2106
+ justify-self: flex-end;
2107
+ }
2089
2108
  .truncate {
2090
2109
  overflow: hidden;
2091
2110
  text-overflow: ellipsis;
@@ -3056,6 +3075,9 @@
3056
3075
  .opacity-60 {
3057
3076
  opacity: 60%;
3058
3077
  }
3078
+ .opacity-80 {
3079
+ opacity: 80%;
3080
+ }
3059
3081
  .opacity-100 {
3060
3082
  opacity: 100%;
3061
3083
  }
@@ -3710,6 +3732,13 @@
3710
3732
  }
3711
3733
  }
3712
3734
  }
3735
+ .hover\:text-neutral700 {
3736
+ &:hover {
3737
+ @media (hover: hover) {
3738
+ color: var(--color-neutral700);
3739
+ }
3740
+ }
3741
+ }
3713
3742
  .hover\:text-neutral800 {
3714
3743
  &:hover {
3715
3744
  @media (hover: hover) {
@@ -5636,6 +5665,9 @@
5636
5665
  align-items: flex-start;
5637
5666
  transition: height 200ms ease-out;
5638
5667
  }
5668
+ .ld-carousel--auto-height .ld-carousel__viewport {
5669
+ padding-bottom: 2px;
5670
+ }
5639
5671
  .ld-carousel__nav {
5640
5672
  position: absolute;
5641
5673
  top: 50%;
@@ -5650,7 +5682,7 @@
5650
5682
  width: var(--ld-carousel-nav-size);
5651
5683
  height: var(--ld-carousel-nav-size);
5652
5684
  transition: all 300ms ease-out;
5653
- --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
5685
+ --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
5654
5686
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
5655
5687
  }
5656
5688
  @media (max-width: calc(768px - 1px)) {
@@ -5688,6 +5720,16 @@
5688
5720
  transform: translate(-50%, 50%);
5689
5721
  }
5690
5722
  }
5723
+ @property --tw-border-spacing-x {
5724
+ syntax: "<length>";
5725
+ inherits: false;
5726
+ initial-value: 0;
5727
+ }
5728
+ @property --tw-border-spacing-y {
5729
+ syntax: "<length>";
5730
+ inherits: false;
5731
+ initial-value: 0;
5732
+ }
5691
5733
  @property --tw-translate-x {
5692
5734
  syntax: "*";
5693
5735
  inherits: false;
@@ -5919,6 +5961,8 @@
5919
5961
  @layer properties {
5920
5962
  @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
5921
5963
  *, ::before, ::after, ::backdrop {
5964
+ --tw-border-spacing-x: 0;
5965
+ --tw-border-spacing-y: 0;
5922
5966
  --tw-translate-x: 0;
5923
5967
  --tw-translate-y: 0;
5924
5968
  --tw-translate-z: 0;
package/dist/index.d.ts CHANGED
@@ -64,6 +64,7 @@ export { default as LDSpinner } from './components/LDSpinner/LDSpinner.js';
64
64
  export { default as LDCollapsibleTanstackTable } from './components/LDTable/LDCollapsibleTanstackTable.js';
65
65
  export { default as LDTable } from './components/LDTable/LDTable.js';
66
66
  export { default as LDTanstackTable } from './components/LDTable/LDTanstackTable.js';
67
+ export { LDRowDragHandle } from './components/LDTable/TableRowDnd.js';
67
68
  export { default as LDTabs, type LDTabsColor, type LDTabsContentProps, type LDTabsListProps, type LDTabsPosition, type LDTabsRootProps, type LDTabsShape, type LDTabsSize, type LDTabsTriggerProps, } from './components/LDTabs/LDTabs.js';
68
69
  export { default as LDTeamHistory, type LDTeamHistoryProps, } from './components/LDTeamHistory/LDTeamHistory.js';
69
70
  export { default as LDFormTextarea } from './components/LDTextarea/LDFormTextarea.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -106,6 +106,7 @@ export { default as LDSpinner } from './components/LDSpinner/LDSpinner.js';
106
106
  export { default as LDCollapsibleTanstackTable } from './components/LDTable/LDCollapsibleTanstackTable.js';
107
107
  export { default as LDTable } from './components/LDTable/LDTable.js';
108
108
  export { default as LDTanstackTable } from './components/LDTable/LDTanstackTable.js';
109
+ export { LDRowDragHandle } from './components/LDTable/TableRowDnd.js';
109
110
  // LDTabs
110
111
  export { default as LDTabs, } from './components/LDTabs/LDTabs.js';
111
112
  // LDTeamHistory
@@ -1,3 +1,9 @@
1
+ /**
2
+ * 현재 경로가 해당 링크의 경로와 **정확히** 일치하는지 판별합니다.
3
+ *
4
+ * 접두사(prefix) 비교는 쓰지 않습니다. `startsWith`로 판별하면 `/admin`이
5
+ * `/admin/group`·`/admin-group`까지 활성으로 잡아 여러 메뉴가 동시에 켜집니다.
6
+ */
1
7
  export declare const isActivePath: (pathname: string, href: string) => boolean;
2
8
  /** 숫자를 정수로 내림 후 천 단위 콤마를 붙인 문자열로 변환합니다 (LDChart 툴팁 표시용). */
3
9
  export declare const formatNumberWithComma: (num?: number) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,KAAG,OAG7D,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,GAAI,MAAK,MAAU,WAMpD,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,uBAAuB,GAAI,OAAO,MAAM,WAQpD,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,KAAG,OAC3C,CAAC;AAEpB,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,GAAI,MAAK,MAAU,WAMpD,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,uBAAuB,GAAI,OAAO,MAAM,WAQpD,CAAC"}
@@ -1,8 +1,10 @@
1
- export const isActivePath = (pathname, href) => {
2
- if (href === '/')
3
- return pathname === '/';
4
- return pathname.startsWith(href);
5
- };
1
+ /**
2
+ * 현재 경로가 해당 링크의 경로와 **정확히** 일치하는지 판별합니다.
3
+ *
4
+ * 접두사(prefix) 비교는 쓰지 않습니다. `startsWith`로 판별하면 `/admin`이
5
+ * `/admin/group`·`/admin-group`까지 활성으로 잡아 여러 메뉴가 동시에 켜집니다.
6
+ */
7
+ export const isActivePath = (pathname, href) => pathname === href;
6
8
  /** 숫자를 정수로 내림 후 천 단위 콤마를 붙인 문자열로 변환합니다 (LDChart 툴팁 표시용). */
7
9
  export const formatNumberWithComma = (num = 0) => {
8
10
  if (isNaN(num)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loword/loword-design-system",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "로워드 디자인 시스템 컴포넌트 패키지(Tailwind v4)",
5
5
  "keywords": [
6
6
  "react",
@@ -48,6 +48,10 @@
48
48
  },
49
49
  "license": "MIT",
50
50
  "peerDependencies": {
51
+ "@dnd-kit/core": "^6.3.1",
52
+ "@dnd-kit/modifiers": "^9.0.0",
53
+ "@dnd-kit/sortable": "^10.0.0",
54
+ "@dnd-kit/utilities": "^3.2.2",
51
55
  "@radix-ui/react-accordion": "^1.2.16",
52
56
  "@radix-ui/react-dialog": "^1.1.15",
53
57
  "@radix-ui/react-popover": "^1.1.15",
@@ -88,6 +92,18 @@
88
92
  "next": {
89
93
  "optional": true
90
94
  },
95
+ "@dnd-kit/core": {
96
+ "optional": true
97
+ },
98
+ "@dnd-kit/modifiers": {
99
+ "optional": true
100
+ },
101
+ "@dnd-kit/sortable": {
102
+ "optional": true
103
+ },
104
+ "@dnd-kit/utilities": {
105
+ "optional": true
106
+ },
91
107
  "@radix-ui/react-accordion": {
92
108
  "optional": true
93
109
  },
@@ -186,6 +202,10 @@
186
202
  }
187
203
  },
188
204
  "devDependencies": {
205
+ "@dnd-kit/core": "^6.3.1",
206
+ "@dnd-kit/modifiers": "^9.0.0",
207
+ "@dnd-kit/sortable": "^10.0.0",
208
+ "@dnd-kit/utilities": "^3.2.2",
189
209
  "@eslint/js": "^9.31.0",
190
210
  "@hookform/resolvers": "^5.4.0",
191
211
  "@radix-ui/react-accordion": "^1.2.16",
@@ -30,6 +30,15 @@
30
30
  transition: height 200ms ease-out;
31
31
  }
32
32
 
33
+ /*
34
+ * AutoHeight 가 트랙 높이를 px 로 고정하는데, 측정값이 소수점이면 반올림 과정에서
35
+ * 1px 모자라 카드 아래 테두리가 잘린다. overflow 는 패딩 박스 기준으로 잘리므로
36
+ * 아래쪽에만 여유를 둔다(가로 클리핑에는 영향 없음).
37
+ */
38
+ .ld-carousel--auto-height .ld-carousel__viewport {
39
+ padding-bottom: 2px;
40
+ }
41
+
33
42
  .ld-carousel__nav {
34
43
  position: absolute;
35
44
  top: 50%;
@@ -44,7 +53,7 @@
44
53
  width: var(--ld-carousel-nav-size);
45
54
  height: var(--ld-carousel-nav-size);
46
55
  transition: all 300ms ease-out;
47
- @apply shadow-lg;
56
+ @apply shadow-sm;
48
57
  }
49
58
 
50
59
  @variant mobile {