@loword/loword-design-system 0.1.1 → 0.1.3
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/README.md +24 -6
- package/dist/components/LDBreadCrumb/LDBreadCrumb.d.ts +8 -4
- package/dist/components/LDBreadCrumb/LDBreadCrumb.d.ts.map +1 -1
- package/dist/components/LDBreadCrumb/LDBreadCrumb.js +4 -3
- package/dist/components/LDCarousel/CarouselBase.d.ts +5 -0
- package/dist/components/LDCarousel/CarouselBase.d.ts.map +1 -1
- package/dist/components/LDCarousel/CarouselBase.js +21 -0
- package/dist/components/LDCarousel/LDCarousel.d.ts +2 -2
- package/dist/components/LDCarousel/LDCarousel.d.ts.map +1 -1
- package/dist/components/LDCarousel/LDCarousel.js +1 -1
- package/dist/components/LDLNB/LDLNB.d.ts +1 -1
- package/dist/components/LDLNB/LDLNB.d.ts.map +1 -1
- package/dist/components/LDLNB/LDLNB.js +2 -1
- package/dist/components/LDTable/LDTable.d.ts.map +1 -1
- package/dist/components/LDTable/LDTable.js +1 -1
- package/dist/index.css +33 -4
- package/package.json +1 -1
- package/src/styles/carousel.css +10 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
- **React 19** / **React DOM 19** (peer dependency)
|
|
13
13
|
- **Tailwind CSS v4** — `theme.css` 경로로 쓸 때만 필요합니다. 완성된 `styles.css`만 쓴다면 없어도 됩니다.
|
|
14
|
-
- **Next.js 15** (optional) — `LDTanstackTable`·`LDCollapsibleTanstackTable
|
|
14
|
+
- **Next.js 15** (optional) — `LDTanstackTable`·`LDCollapsibleTanstackTable`은 내부에서 `next/navigation`을 무조건 호출하므로 Next 환경에서만 돕니다.
|
|
15
15
|
|
|
16
16
|
## 설치
|
|
17
17
|
|
|
@@ -21,7 +21,7 @@ npm install @loword/loword-design-system
|
|
|
21
21
|
pnpm add @loword/loword-design-system
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
Editor·Carousel·Drawer·Table·
|
|
24
|
+
Editor·Carousel·Drawer·Table·Chart·DatePicker 같은 일부 컴포넌트는 뒤에 깔린 라이브러리를 **optional peer dependency**로 둡니다. 해당 컴포넌트를 쓸 때만 같이 설치하면 됩니다 — `@tiptap/*`(Editor), `embla-carousel*`(Carousel), `vaul`(Drawer), `@radix-ui/*`(Accordion/Modal/Popover/Tabs/Tooltip), `@tanstack/react-table`·`next`(Table), `chart.js`·`react-chartjs-2`(Chart), `react-day-picker`·`dayjs`(DatePicker/Calendar), `react-hot-toast`(Toast), `react-daum-postcode`(DaumPostButton).
|
|
25
25
|
|
|
26
26
|
## 설정
|
|
27
27
|
|
|
@@ -81,28 +81,45 @@ import LDButton from '@loword/loword-design-system/components/LDButton/LDButton'
|
|
|
81
81
|
|
|
82
82
|
**레이아웃/표시**: `LDBadge` · `LDAvatar` · `LDDivider` · `LDCallout` · `LDEmpty` · `LDSkeleton` · `LDSpinner` · `LDLoadingDots` · `LDProgressBar` · `LDScrollArea` · `LDAccordion` · `LDTeamHistory`
|
|
83
83
|
|
|
84
|
-
**내비게이션**: `LDBreadCrumb` · `LDMenuBar` · `LDTabs` · `LDSectionNav` · `LDPagination` · `LDLNB`
|
|
84
|
+
**내비게이션**: `LDBreadCrumb` · `LDMenuBar` · `LDTabs` · `LDSectionNav` · `LDPagination` · `LDLNB`
|
|
85
85
|
|
|
86
86
|
**오버레이/피드백**: `LDModal` · `LDModalView` · `LDDrawer` · `LDPopover` · `LDTooltip` · `LDToast` · `LDToaster` · `LDNotification`
|
|
87
87
|
|
|
88
|
-
**콘텐츠/데이터**: `LDEditor` · `LDViewer` · `LDCarousel` · `LDChart` · `LDTable` · `LDTanstackTable` · `LDCollapsibleTanstackTable`
|
|
88
|
+
**콘텐츠/데이터**: `LDEditor` · `LDViewer` · `LDCarousel` · `LDChart` · `LDTable` · `LDTanstackTable` · `LDCollapsibleTanstackTable`
|
|
89
89
|
|
|
90
90
|
**폼 연동**: `LDForm` · `LDNativeForm` · `LDFormField` · `LDFormErrorMessage` · `LDFormInput` · `LDFormTextarea` · `LDFormSelect` · `LDFormMultiSelect` · `LDFormCheckbox` · `LDFormCheckboxGroup` · `LDFormRadioGroup` · `LDFormDatePicker` · `LDFormDateRangePicker` · `LDFormTimePicker` · `LDFormToggleButton` · `LDFormOTPInput` · `LDFormRate`
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
**유틸**: `Show` — 조건부 렌더링 컴포넌트. `when`이 truthy면 `children`, falsy면 `fallback`을 렌더링하고, `children`을 함수로 넘기면 `NonNullable`로 좁혀진 값을 인자로 받습니다.
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
<Show when={user} fallback={<LDSpinner />}>
|
|
96
|
+
{(result) => <span>{result.name}</span>}
|
|
97
|
+
</Show>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
> barrel의 값 export는 `Show` · `openModal`(`LDModal`의 하위호환 별칭) · `TextareaContent` 셋 말고는 전부 `LD` 접두사입니다. 타입 export에는 예외가 조금 더 있습니다.
|
|
93
101
|
|
|
94
102
|
## 빠른 시작 (개발)
|
|
95
103
|
|
|
96
104
|
```bash
|
|
97
105
|
pnpm install # 의존성 설치
|
|
106
|
+
pnpm switch -c <브랜치> # 열려 있는 release/* 위에 작업 브랜치 생성
|
|
98
107
|
pnpm storybook # Storybook 개발 서버 (port 6006)
|
|
99
108
|
pnpm build # 프로덕션 빌드
|
|
100
109
|
pnpm check-types # 타입 체크
|
|
101
110
|
pnpm lint # ESLint (--fix 포함, src + .storybook)
|
|
102
111
|
pnpm prettier # Prettier
|
|
103
112
|
pnpm test # vitest (utils 유닛 + 스토리 브라우저 실행 + a11y)
|
|
113
|
+
pnpm test:coverage # 커버리지 (utils / components 분리 측정)
|
|
114
|
+
pnpm changeset # .changes/{브랜치명}.md 생성
|
|
104
115
|
```
|
|
105
116
|
|
|
117
|
+
## 변경 기록 (기여)
|
|
118
|
+
|
|
119
|
+
코드를 고쳤으면 `pnpm changeset`으로 **`.changes/{브랜치명}.md`** 를 만들어 같은 PR에 포함합니다. 이 디렉토리가 변경 기록의 유일한 원본이고, `docs/CHANGELOG.md`와 `docs/releases/vX.Y.Z.md`는 배포 시점에 여기서 생성되므로 직접 편집하지 않습니다.
|
|
120
|
+
|
|
121
|
+
작업 브랜치는 `main`이 아니라 열려 있는 `release/*`에서 분기하고 PR base도 거기로 잡습니다(`pnpm switch -c <브랜치>`가 자동으로 처리합니다). 모든 PR은 merge commit으로 머지합니다(squash 금지). 자세한 규칙은 [docs/release-process.md](./docs/release-process.md).
|
|
122
|
+
|
|
106
123
|
## 문서
|
|
107
124
|
|
|
108
125
|
- **아키텍처와 상세 가이드**: [docs/architecture.md](./docs/architecture.md)
|
|
@@ -114,7 +131,8 @@ pnpm test # vitest (utils 유닛 + 스토리 브라우저 실행 + a
|
|
|
114
131
|
- **프리셋 스타일 작성 규칙**: [docs/style-conventions.md](./docs/style-conventions.md)
|
|
115
132
|
- **CSS 캐스케이드 레이어**: [docs/css-layers.md](./docs/css-layers.md) — 컴포넌트 스타일이 왜 이기고 지는지, className override가 안 먹을 때의 진단 순서
|
|
116
133
|
- **타입 컨벤션**: [docs/type-conventions.md](./docs/type-conventions.md)
|
|
117
|
-
-
|
|
134
|
+
- **릴리즈/브랜치 운영**: [docs/release-process.md](./docs/release-process.md) — changeset 작성법, `release/*` 브랜치 흐름, 배포 자동화
|
|
135
|
+
- **변경 이력**: [docs/CHANGELOG.md](./docs/CHANGELOG.md) (생성물) · 버전별 릴리즈 노트는 [docs/releases/](./docs/releases/)
|
|
118
136
|
|
|
119
137
|
## 라이선스
|
|
120
138
|
|
|
@@ -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
|
|
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":"
|
|
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:
|
|
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":"AAEA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAmB,EACjB,KAAK,qBAAqB,EAC3B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,gBAAgB,MAAM,sBAAsB,CAAC;AAOpD,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAKf,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,UAAU,CAAC;AAE5D,UAAU,cAAc;IACtB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,UAAU,gBAAgB;IACxB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACnC,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gCAAgC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAGD,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,EAAE,mBAAmB,CAAC;IACjC,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;CACb;AAaD,+CAA+C;AAC/C,eAAO,MAAM,WAAW,2BAAqB,CAAC;
|
|
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,
|
|
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 렌더 엘리먼트 (
|
|
8
|
+
/** MenuItem 렌더 엘리먼트 (기본 `next/link`. 다른 라우터를 쓰면 교체한다) */
|
|
9
9
|
as?: ElementType;
|
|
10
10
|
/** 항목 이동 시 콜백 (라우터 push 등). 모바일에서는 이후 Drawer가 자동으로 닫힘 */
|
|
11
11
|
onNavigate?: (path: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LDLNB.d.ts","sourceRoot":"","sources":["../../../src/components/LDLNB/LDLNB.tsx"],"names":[],"mappings":"
|
|
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,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,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';
|
|
@@ -13,7 +14,7 @@ const MOBILE_QUERY = '(max-width: 767px)';
|
|
|
13
14
|
* Drawer 오버레이(기본 왼쪽, `drawerDirection`으로 조정)로 자동 전환된다.
|
|
14
15
|
* 뷰포트 감지는 내부에서 처리한다.
|
|
15
16
|
*/
|
|
16
|
-
const LDLNB = ({ items, pathname, as, onNavigate, name, email, profileImage, handleLogout, defaultCollapsed = false, size = 400, minWidth = 200, drawerDirection = 'left', triggerClassName, className, children, }) => {
|
|
17
|
+
const LDLNB = ({ items, pathname, as = Link, onNavigate, name, email, profileImage, handleLogout, defaultCollapsed = false, size = 400, minWidth = 200, drawerDirection = 'left', triggerClassName, className, children, }) => {
|
|
17
18
|
const [isMobile, setIsMobile] = useState(false);
|
|
18
19
|
const [open, setOpen] = useState(false);
|
|
19
20
|
useEffect(() => {
|
|
@@ -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;
|
|
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;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;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE;8CAgBlE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;CA5G9C,CAAC;AA4HF,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)
|
package/dist/index.css
CHANGED
|
@@ -1834,6 +1834,17 @@
|
|
|
1834
1834
|
.border-collapse {
|
|
1835
1835
|
border-collapse: collapse;
|
|
1836
1836
|
}
|
|
1837
|
+
.border-separate {
|
|
1838
|
+
border-collapse: separate;
|
|
1839
|
+
}
|
|
1840
|
+
.border-spacing-x-4 {
|
|
1841
|
+
--tw-border-spacing-x: calc(var(--spacing) * 4);
|
|
1842
|
+
border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y);
|
|
1843
|
+
}
|
|
1844
|
+
.border-spacing-y-3 {
|
|
1845
|
+
--tw-border-spacing-y: calc(var(--spacing) * 3);
|
|
1846
|
+
border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y);
|
|
1847
|
+
}
|
|
1837
1848
|
.animate-bell {
|
|
1838
1849
|
animation: bell-ring 600ms ease-in-out;
|
|
1839
1850
|
transform-origin: top center;
|
|
@@ -1941,6 +1952,9 @@
|
|
|
1941
1952
|
.grid-cols-7 {
|
|
1942
1953
|
grid-template-columns: repeat(7, minmax(0, 1fr));
|
|
1943
1954
|
}
|
|
1955
|
+
.grid-cols-\[1fr_auto_1fr\] {
|
|
1956
|
+
grid-template-columns: 1fr auto 1fr;
|
|
1957
|
+
}
|
|
1944
1958
|
.grid-cols-\[64px_repeat\(3\,180px\)\] {
|
|
1945
1959
|
grid-template-columns: 64px repeat(3,180px);
|
|
1946
1960
|
}
|
|
@@ -2010,9 +2024,6 @@
|
|
|
2010
2024
|
.gap-2\.5 {
|
|
2011
2025
|
gap: calc(var(--spacing) * 2.5);
|
|
2012
2026
|
}
|
|
2013
|
-
.gap-2xl {
|
|
2014
|
-
gap: var(--spacing_64);
|
|
2015
|
-
}
|
|
2016
2027
|
.gap-2xs {
|
|
2017
2028
|
gap: var(--spacing_4);
|
|
2018
2029
|
}
|
|
@@ -2086,6 +2097,9 @@
|
|
|
2086
2097
|
.self-stretch {
|
|
2087
2098
|
align-self: stretch;
|
|
2088
2099
|
}
|
|
2100
|
+
.justify-self-end {
|
|
2101
|
+
justify-self: flex-end;
|
|
2102
|
+
}
|
|
2089
2103
|
.truncate {
|
|
2090
2104
|
overflow: hidden;
|
|
2091
2105
|
text-overflow: ellipsis;
|
|
@@ -5636,6 +5650,9 @@
|
|
|
5636
5650
|
align-items: flex-start;
|
|
5637
5651
|
transition: height 200ms ease-out;
|
|
5638
5652
|
}
|
|
5653
|
+
.ld-carousel--auto-height .ld-carousel__viewport {
|
|
5654
|
+
padding-bottom: 2px;
|
|
5655
|
+
}
|
|
5639
5656
|
.ld-carousel__nav {
|
|
5640
5657
|
position: absolute;
|
|
5641
5658
|
top: 50%;
|
|
@@ -5650,7 +5667,7 @@
|
|
|
5650
5667
|
width: var(--ld-carousel-nav-size);
|
|
5651
5668
|
height: var(--ld-carousel-nav-size);
|
|
5652
5669
|
transition: all 300ms ease-out;
|
|
5653
|
-
--tw-shadow: 0
|
|
5670
|
+
--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
5671
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
5655
5672
|
}
|
|
5656
5673
|
@media (max-width: calc(768px - 1px)) {
|
|
@@ -5688,6 +5705,16 @@
|
|
|
5688
5705
|
transform: translate(-50%, 50%);
|
|
5689
5706
|
}
|
|
5690
5707
|
}
|
|
5708
|
+
@property --tw-border-spacing-x {
|
|
5709
|
+
syntax: "<length>";
|
|
5710
|
+
inherits: false;
|
|
5711
|
+
initial-value: 0;
|
|
5712
|
+
}
|
|
5713
|
+
@property --tw-border-spacing-y {
|
|
5714
|
+
syntax: "<length>";
|
|
5715
|
+
inherits: false;
|
|
5716
|
+
initial-value: 0;
|
|
5717
|
+
}
|
|
5691
5718
|
@property --tw-translate-x {
|
|
5692
5719
|
syntax: "*";
|
|
5693
5720
|
inherits: false;
|
|
@@ -5919,6 +5946,8 @@
|
|
|
5919
5946
|
@layer properties {
|
|
5920
5947
|
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
|
|
5921
5948
|
*, ::before, ::after, ::backdrop {
|
|
5949
|
+
--tw-border-spacing-x: 0;
|
|
5950
|
+
--tw-border-spacing-y: 0;
|
|
5922
5951
|
--tw-translate-x: 0;
|
|
5923
5952
|
--tw-translate-y: 0;
|
|
5924
5953
|
--tw-translate-z: 0;
|
package/package.json
CHANGED
package/src/styles/carousel.css
CHANGED
|
@@ -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-
|
|
56
|
+
@apply shadow-sm;
|
|
48
57
|
}
|
|
49
58
|
|
|
50
59
|
@variant mobile {
|