@iyulab/components 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/assets/icons/arrow-down-up.svg.js +3 -0
- package/dist/assets/icons/code-slash.svg.js +3 -0
- package/dist/assets/icons/download.svg.js +3 -0
- package/dist/assets/icons/sort-alpha-down.svg.js +3 -0
- package/dist/assets/icons/sort-alpha-up.svg.js +3 -0
- package/dist/components/UElement.d.ts +59 -0
- package/dist/components/UElement.js +96 -0
- package/dist/components/{FloatingElement.d.ts → UFloatingElement.d.ts} +4 -4
- package/dist/components/{FloatingElement.js → UFloatingElement.js} +13 -13
- package/dist/components/UJsonElement.d.ts +46 -0
- package/dist/components/UJsonElement.js +93 -0
- package/dist/components/UJsonElement.styles.js +95 -0
- package/dist/components/{ModalElement.d.ts → UModalElement.d.ts} +4 -4
- package/dist/components/{ModalElement.js → UModalElement.js} +8 -8
- package/dist/components/UModalElement.styles.d.ts +1 -0
- package/dist/components/alert/UAlert.component.d.ts +3 -3
- package/dist/components/alert/UAlert.component.js +2 -2
- package/dist/components/button/UButton.component.d.ts +3 -3
- package/dist/components/button/UButton.component.js +2 -2
- package/dist/components/card/UCard.component.d.ts +2 -2
- package/dist/components/card/UCard.component.js +2 -2
- package/dist/components/carousel/UCarousel.component.d.ts +34 -23
- package/dist/components/carousel/UCarousel.component.js +124 -103
- package/dist/components/carousel/UCarousel.styles.js +22 -23
- package/dist/components/dialog/UDialog.component.d.ts +4 -4
- package/dist/components/dialog/UDialog.component.js +2 -2
- package/dist/components/divider/UDivider.component.d.ts +3 -3
- package/dist/components/divider/UDivider.component.js +2 -2
- package/dist/components/drawer/UDrawer.component.d.ts +4 -4
- package/dist/components/drawer/UDrawer.component.js +2 -2
- package/dist/components/form/UForm.component.d.ts +3 -3
- package/dist/components/form/UForm.component.js +2 -2
- package/dist/components/icon/UIcon.component.d.ts +3 -3
- package/dist/components/icon/UIcon.component.js +2 -2
- package/dist/components/input/UInput.component.d.ts +3 -3
- package/dist/components/input/UInput.component.js +2 -2
- package/dist/components/menu/UMenu.component.d.ts +4 -4
- package/dist/components/menu/UMenu.component.js +2 -2
- package/dist/components/menu-item/UMenuItem.component.d.ts +3 -3
- package/dist/components/menu-item/UMenuItem.component.js +2 -2
- package/dist/components/progress-bar/UProgressBar.component.d.ts +3 -3
- package/dist/components/progress-bar/UProgressBar.component.js +2 -2
- package/dist/components/progress-ring/UProgressRing.component.d.ts +3 -3
- package/dist/components/progress-ring/UProgressRing.component.js +2 -2
- package/dist/components/skeleton/USkeleton.component.d.ts +3 -3
- package/dist/components/skeleton/USkeleton.component.js +2 -2
- package/dist/components/spinner/USpinner.component.d.ts +3 -3
- package/dist/components/spinner/USpinner.component.js +2 -2
- package/dist/components/split-panel/USplitPanel.component.d.ts +3 -3
- package/dist/components/split-panel/USplitPanel.component.js +2 -2
- package/dist/components/tag/UTag.component.d.ts +3 -3
- package/dist/components/tag/UTag.component.js +2 -2
- package/dist/components/tooltip/UTooltip.component.d.ts +4 -4
- package/dist/components/tooltip/UTooltip.component.js +2 -2
- package/dist/components/tree/UTree.component.d.ts +3 -3
- package/dist/components/tree/UTree.component.js +2 -2
- package/dist/components/tree-item/UTreeItem.component.d.ts +3 -3
- package/dist/components/tree-item/UTreeItem.component.js +2 -2
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/utilities/IconRegistry.js +16 -1
- package/dist/utilities/elements.d.ts +23 -0
- package/dist/utilities/elements.js +23 -1
- package/dist/utilities/sanitizers.d.ts +35 -0
- package/dist/utilities/sanitizers.js +43 -0
- package/package.json +4 -5
- package/dist/components/BaseElement.d.ts +0 -33
- package/dist/components/BaseElement.js +0 -59
- /package/dist/components/{BaseElement.styles.d.ts → UElement.styles.d.ts} +0 -0
- /package/dist/components/{BaseElement.styles.js → UElement.styles.js} +0 -0
- /package/dist/components/{FloatingElement.styles.d.ts → UFloatingElement.styles.d.ts} +0 -0
- /package/dist/components/{FloatingElement.styles.js → UFloatingElement.styles.js} +0 -0
- /package/dist/components/{ModalElement.styles.d.ts → UJsonElement.styles.d.ts} +0 -0
- /package/dist/components/{ModalElement.styles.js → UModalElement.styles.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
|
-
import {
|
|
3
|
+
import { UElement } from '../UElement.js';
|
|
4
4
|
import { USpinner } from '../spinner/USpinner.component.js';
|
|
5
5
|
import { styles } from './UButton.styles.js';
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
13
13
|
if (result) __defProp(target, key, result);
|
|
14
14
|
return result;
|
|
15
15
|
};
|
|
16
|
-
class UButton extends
|
|
16
|
+
class UButton extends UElement {
|
|
17
17
|
constructor() {
|
|
18
18
|
super(...arguments);
|
|
19
19
|
this.variant = "default";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UElement } from '../UElement.js';
|
|
2
2
|
/**
|
|
3
3
|
* Card 컴포넌트는 콘텐츠를 카드 형태로 표시합니다.
|
|
4
4
|
* @slot - 카드의 메인 콘텐츠를 삽입합니다.
|
|
@@ -6,7 +6,7 @@ import { BaseElement } from '../BaseElement.js';
|
|
|
6
6
|
* @slot footer - 카드 하단의 푸터 영역에 표시할 콘텐츠를 삽입합니다.
|
|
7
7
|
* @slot media - 카드의 미디어 영역에 표시할 이미지, 비디오 등을 삽입합니다.
|
|
8
8
|
*/
|
|
9
|
-
export declare class UCard extends
|
|
9
|
+
export declare class UCard extends UElement {
|
|
10
10
|
static styles: import('lit').CSSResultGroup[];
|
|
11
11
|
/** 카드의 그림자 효과를 제거할지 여부를 설정합니다. */
|
|
12
12
|
shadowless: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
|
-
import {
|
|
3
|
+
import { UElement } from '../UElement.js';
|
|
4
4
|
import { styles } from './UCard.styles.js';
|
|
5
5
|
|
|
6
6
|
var __defProp = Object.defineProperty;
|
|
@@ -12,7 +12,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
12
12
|
if (result) __defProp(target, key, result);
|
|
13
13
|
return result;
|
|
14
14
|
};
|
|
15
|
-
class UCard extends
|
|
15
|
+
class UCard extends UElement {
|
|
16
16
|
constructor() {
|
|
17
17
|
super(...arguments);
|
|
18
18
|
this.shadowless = false;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PropertyValues } from 'lit';
|
|
2
|
-
import {
|
|
2
|
+
import { UElement } from '../UElement.js';
|
|
3
3
|
/**
|
|
4
4
|
* Carousel 컴포넌트는 여러 슬라이드를 회전하며 표시합니다.
|
|
5
5
|
*
|
|
6
6
|
* @slot - 슬라이드로 표시할 콘텐츠. 각 자식 요소가 하나의 슬라이드.
|
|
7
|
-
* @event u-change - 슬라이드 변경 시. detail: {
|
|
7
|
+
* @event u-change - 슬라이드 변경 시. detail: { index: number }
|
|
8
8
|
*
|
|
9
9
|
* @csspart slides - 슬라이드 컨테이너 (aspect-ratio 등 외부 스타일링)
|
|
10
10
|
* @csspart prev-button - 이전 버튼
|
|
@@ -12,21 +12,19 @@ import { BaseElement } from '../BaseElement.js';
|
|
|
12
12
|
* @csspart indicator - 인디케이터 컨테이너
|
|
13
13
|
* @csspart dot - 인디케이터 도트
|
|
14
14
|
*/
|
|
15
|
-
export declare class UCarousel extends
|
|
15
|
+
export declare class UCarousel extends UElement {
|
|
16
16
|
static styles: import('lit').CSSResultGroup[];
|
|
17
|
-
static dependencies: Record<string, typeof
|
|
18
|
-
/** 현재 활성 슬라이드 인덱스 */
|
|
19
|
-
currentIndex: number;
|
|
17
|
+
static dependencies: Record<string, typeof UElement>;
|
|
20
18
|
/** 자동 재생 활성화 */
|
|
21
19
|
autoplay: boolean;
|
|
22
20
|
/** 자동 재생 간격 (ms) */
|
|
23
21
|
autoplayInterval: number;
|
|
22
|
+
/** 처음/끝에서 순환 이동 */
|
|
23
|
+
loop: boolean;
|
|
24
24
|
/** 이전/다음 네비게이션 버튼 표시 */
|
|
25
25
|
navigation: boolean;
|
|
26
26
|
/** 페이지 인디케이터 표시 */
|
|
27
27
|
pagination: boolean;
|
|
28
|
-
/** 처음/끝에서 순환 이동 */
|
|
29
|
-
loop: boolean;
|
|
30
28
|
/** 드래그로 슬라이드 전환 */
|
|
31
29
|
draggable: boolean;
|
|
32
30
|
/** 한 화면에 표시할 슬라이드 수 */
|
|
@@ -35,33 +33,46 @@ export declare class UCarousel extends BaseElement {
|
|
|
35
33
|
slidesPerMove: number;
|
|
36
34
|
/** 슬라이드 간 간격 (px) */
|
|
37
35
|
gap: number;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
private
|
|
44
|
-
|
|
45
|
-
private
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
private
|
|
36
|
+
/** 현재 활성 슬라이드 인덱스 */
|
|
37
|
+
index: number;
|
|
38
|
+
/** 전체 슬라이드 수 */
|
|
39
|
+
private slideCount;
|
|
40
|
+
/** 드래그 중인지 여부 */
|
|
41
|
+
private isDragging;
|
|
42
|
+
/** 드래그 중 이동 보정값 (단위: %) */
|
|
43
|
+
private dragOffset;
|
|
44
|
+
/** 타이머 및 드래그 상태 추적 필드 */
|
|
45
|
+
private autoplayTimer?;
|
|
46
|
+
private dragStartX;
|
|
47
|
+
private dragStartTime;
|
|
48
|
+
private pointerDown;
|
|
49
|
+
/** 한 화면에 표시할 슬라이드 수 (최소 1) */
|
|
50
|
+
private get perView();
|
|
51
|
+
/** 한 번에 이동할 슬라이드 수 (최소 1) */
|
|
52
|
+
private get perMove();
|
|
53
|
+
/** 슬라이드가 이동할 수 있는 최대 index */
|
|
54
|
+
private get maxIndex();
|
|
55
|
+
/** 총 페이지 수 (인디케이터 도트 수) */
|
|
56
|
+
private get pageCount();
|
|
57
|
+
/** 현재 페이지 (인디케이터 도트 활성화에 사용) */
|
|
58
|
+
private get currentPage();
|
|
49
59
|
connectedCallback(): void;
|
|
50
60
|
disconnectedCallback(): void;
|
|
51
61
|
protected willUpdate(changedProperties: PropertyValues): void;
|
|
52
62
|
protected updated(changedProperties: PropertyValues): void;
|
|
53
63
|
render(): import('lit-html').TemplateResult<1>;
|
|
54
64
|
/** 이전 슬라이드로 이동 */
|
|
55
|
-
prev()
|
|
65
|
+
prev: () => void;
|
|
56
66
|
/** 다음 슬라이드로 이동 */
|
|
57
|
-
next()
|
|
67
|
+
next: () => void;
|
|
58
68
|
/** 지정한 인덱스로 이동 */
|
|
59
|
-
goTo(index: number)
|
|
60
|
-
private handleSlotChange;
|
|
69
|
+
goTo: (index: number) => void;
|
|
61
70
|
private startAutoplay;
|
|
62
71
|
private stopAutoplay;
|
|
72
|
+
private handleSlotChange;
|
|
63
73
|
private handleDragStart;
|
|
64
74
|
private handlePointerDown;
|
|
65
75
|
private handlePointerMove;
|
|
66
76
|
private handlePointerUp;
|
|
77
|
+
private handleClickCancel;
|
|
67
78
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
2
|
import { property, state } from 'lit/decorators.js';
|
|
3
|
-
import {
|
|
3
|
+
import { UElement } from '../UElement.js';
|
|
4
4
|
import { UButton } from '../button/UButton.component.js';
|
|
5
5
|
import { UIcon } from '../icon/UIcon.component.js';
|
|
6
6
|
import { styles } from './UCarousel.styles.js';
|
|
@@ -14,56 +14,99 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
14
14
|
if (result) __defProp(target, key, result);
|
|
15
15
|
return result;
|
|
16
16
|
};
|
|
17
|
-
class UCarousel extends
|
|
17
|
+
class UCarousel extends UElement {
|
|
18
18
|
constructor() {
|
|
19
19
|
super(...arguments);
|
|
20
|
-
this.currentIndex = 0;
|
|
21
20
|
this.autoplay = false;
|
|
22
21
|
this.autoplayInterval = 3e3;
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
22
|
+
this.loop = false;
|
|
23
|
+
this.navigation = false;
|
|
24
|
+
this.pagination = false;
|
|
26
25
|
this.draggable = false;
|
|
27
26
|
this.slidesPerView = 1;
|
|
28
27
|
this.slidesPerMove = 1;
|
|
29
28
|
this.gap = 0;
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
29
|
+
this.index = 0;
|
|
30
|
+
this.slideCount = 0;
|
|
31
|
+
this.isDragging = false;
|
|
32
|
+
this.dragOffset = 0;
|
|
33
|
+
this.dragStartX = 0;
|
|
34
|
+
this.dragStartTime = 0;
|
|
35
|
+
this.pointerDown = false;
|
|
36
|
+
/** 이전 슬라이드로 이동 */
|
|
37
|
+
this.prev = () => {
|
|
38
|
+
const target = Math.max(0, this.index - this.perMove);
|
|
39
|
+
if (target !== this.index) {
|
|
40
|
+
this.goTo(target);
|
|
41
|
+
} else if (this.loop) {
|
|
42
|
+
this.goTo(Math.min((this.pageCount - 1) * this.perMove, this.maxIndex));
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/** 다음 슬라이드로 이동 */
|
|
46
|
+
this.next = () => {
|
|
47
|
+
const target = Math.min(this.maxIndex, this.index + this.perMove);
|
|
48
|
+
if (target !== this.index) {
|
|
49
|
+
this.goTo(target);
|
|
50
|
+
} else if (this.loop) {
|
|
51
|
+
this.goTo(0);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/** 지정한 인덱스로 이동 */
|
|
55
|
+
this.goTo = (index) => {
|
|
56
|
+
if (index < 0 || index > this.maxIndex || index === this.index) return;
|
|
57
|
+
this.index = index;
|
|
58
|
+
this.emit("u-change", {
|
|
59
|
+
index: this.index
|
|
60
|
+
});
|
|
61
|
+
if (this.autoplay) this.startAutoplay();
|
|
62
|
+
};
|
|
35
63
|
this.handleDragStart = (e) => {
|
|
36
64
|
e.preventDefault();
|
|
37
65
|
};
|
|
38
66
|
this.handlePointerDown = (e) => {
|
|
39
67
|
if (e.button !== 0) return;
|
|
40
|
-
|
|
41
|
-
this.
|
|
42
|
-
this.
|
|
43
|
-
this.
|
|
44
|
-
this._dragStartTime = Date.now();
|
|
68
|
+
this.pointerDown = true;
|
|
69
|
+
this.dragStartX = e.clientX;
|
|
70
|
+
this.dragOffset = 0;
|
|
71
|
+
this.dragStartTime = Date.now();
|
|
45
72
|
if (this.autoplay) this.stopAutoplay();
|
|
46
|
-
const wrapper = e.currentTarget;
|
|
47
|
-
wrapper.setPointerCapture(e.pointerId);
|
|
48
73
|
};
|
|
49
74
|
this.handlePointerMove = (e) => {
|
|
50
|
-
if (!this.
|
|
75
|
+
if (!this.pointerDown) return;
|
|
51
76
|
const wrapper = e.currentTarget;
|
|
52
|
-
|
|
77
|
+
const offset = (e.clientX - this.dragStartX) / wrapper.offsetWidth * 100;
|
|
78
|
+
if (!this.isDragging && Math.abs(e.clientX - this.dragStartX) > 5) {
|
|
79
|
+
this.isDragging = true;
|
|
80
|
+
wrapper.setPointerCapture(e.pointerId);
|
|
81
|
+
}
|
|
82
|
+
if (this.isDragging) {
|
|
83
|
+
this.dragOffset = offset;
|
|
84
|
+
}
|
|
53
85
|
};
|
|
54
86
|
this.handlePointerUp = (e) => {
|
|
55
|
-
if (!this.
|
|
56
|
-
const elapsed = Date.now() - this.
|
|
57
|
-
const absDrag = Math.abs(this.
|
|
58
|
-
if (absDrag > 20 || absDrag > 5 && elapsed < 300) {
|
|
59
|
-
if (this.
|
|
87
|
+
if (!this.pointerDown) return;
|
|
88
|
+
const elapsed = Date.now() - this.dragStartTime;
|
|
89
|
+
const absDrag = Math.abs(this.dragOffset);
|
|
90
|
+
if (this.isDragging && (absDrag > 20 || absDrag > 5 && elapsed < 300)) {
|
|
91
|
+
if (this.dragOffset < 0) this.next();
|
|
60
92
|
else this.prev();
|
|
93
|
+
this.addEventListener("click", this.handleClickCancel, {
|
|
94
|
+
capture: true,
|
|
95
|
+
once: true
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (this.isDragging) {
|
|
99
|
+
const wrapper = e.currentTarget;
|
|
100
|
+
wrapper.releasePointerCapture(e.pointerId);
|
|
61
101
|
}
|
|
62
|
-
this.
|
|
63
|
-
this.
|
|
102
|
+
this.pointerDown = false;
|
|
103
|
+
this.isDragging = false;
|
|
104
|
+
this.dragOffset = 0;
|
|
64
105
|
if (this.autoplay) this.startAutoplay();
|
|
65
|
-
|
|
66
|
-
|
|
106
|
+
};
|
|
107
|
+
this.handleClickCancel = (e) => {
|
|
108
|
+
e.preventDefault();
|
|
109
|
+
e.stopPropagation();
|
|
67
110
|
};
|
|
68
111
|
}
|
|
69
112
|
static {
|
|
@@ -75,20 +118,25 @@ class UCarousel extends BaseElement {
|
|
|
75
118
|
"u-icon": UIcon
|
|
76
119
|
};
|
|
77
120
|
}
|
|
78
|
-
|
|
121
|
+
/** 한 화면에 표시할 슬라이드 수 (최소 1) */
|
|
122
|
+
get perView() {
|
|
79
123
|
return Math.max(1, this.slidesPerView);
|
|
80
124
|
}
|
|
81
|
-
|
|
125
|
+
/** 한 번에 이동할 슬라이드 수 (최소 1) */
|
|
126
|
+
get perMove() {
|
|
82
127
|
return Math.max(1, this.slidesPerMove);
|
|
83
128
|
}
|
|
84
|
-
|
|
85
|
-
|
|
129
|
+
/** 슬라이드가 이동할 수 있는 최대 index */
|
|
130
|
+
get maxIndex() {
|
|
131
|
+
return Math.max(0, this.slideCount - this.perView);
|
|
86
132
|
}
|
|
87
|
-
|
|
88
|
-
|
|
133
|
+
/** 총 페이지 수 (인디케이터 도트 수) */
|
|
134
|
+
get pageCount() {
|
|
135
|
+
return this.maxIndex <= 0 ? 1 : Math.ceil(this.maxIndex / this.perMove) + 1;
|
|
89
136
|
}
|
|
90
|
-
|
|
91
|
-
|
|
137
|
+
/** 현재 페이지 (인디케이터 도트 활성화에 사용) */
|
|
138
|
+
get currentPage() {
|
|
139
|
+
return this.index >= this.maxIndex ? this.pageCount - 1 : Math.floor(this.index / this.perMove);
|
|
92
140
|
}
|
|
93
141
|
connectedCallback() {
|
|
94
142
|
super.connectedCallback();
|
|
@@ -101,7 +149,7 @@ class UCarousel extends BaseElement {
|
|
|
101
149
|
willUpdate(changedProperties) {
|
|
102
150
|
super.willUpdate(changedProperties);
|
|
103
151
|
if (changedProperties.has("slidesPerView")) {
|
|
104
|
-
this.style.setProperty("--slides-per-view", String(this.
|
|
152
|
+
this.style.setProperty("--slides-per-view", String(this.perView));
|
|
105
153
|
}
|
|
106
154
|
if (changedProperties.has("gap")) {
|
|
107
155
|
this.style.setProperty("--slide-gap", `${this.gap}px`);
|
|
@@ -115,10 +163,10 @@ class UCarousel extends BaseElement {
|
|
|
115
163
|
}
|
|
116
164
|
}
|
|
117
165
|
render() {
|
|
118
|
-
const pct = -(this.
|
|
119
|
-
const gapPx = this.gap > 0 ? -(this.
|
|
166
|
+
const pct = -(this.index * (100 / this.perView)) + this.dragOffset;
|
|
167
|
+
const gapPx = this.gap > 0 ? -(this.index * this.gap / this.perView) : 0;
|
|
120
168
|
const transform = gapPx ? `translateX(calc(${pct}% + ${gapPx}px))` : `translateX(${pct}%)`;
|
|
121
|
-
const style = `transform: ${transform}${this.
|
|
169
|
+
const style = `transform: ${transform}${this.isDragging ? "; transition: none" : ""}`;
|
|
122
170
|
return html`
|
|
123
171
|
<div class="slides-wrapper"
|
|
124
172
|
@dragstart=${this.handleDragStart}
|
|
@@ -131,113 +179,86 @@ class UCarousel extends BaseElement {
|
|
|
131
179
|
</div>
|
|
132
180
|
</div>
|
|
133
181
|
|
|
134
|
-
<u-button part="prev-button" class="nav-button prev"
|
|
135
|
-
?hidden=${!this.navigation}
|
|
136
|
-
?disabled=${!this.loop && this.currentIndex <= 0}
|
|
182
|
+
<u-button part="prev-button" class="nav-button prev"
|
|
183
|
+
?hidden=${!this.navigation || !this.loop && this.index <= 0}
|
|
137
184
|
@click=${this.prev}>
|
|
138
185
|
<u-icon lib="internal" name="chevron-left"></u-icon>
|
|
139
186
|
</u-button>
|
|
140
|
-
<u-button part="next-button" class="nav-button next"
|
|
141
|
-
?hidden=${!this.navigation}
|
|
142
|
-
?disabled=${!this.loop && this.currentIndex >= this._maxIndex}
|
|
187
|
+
<u-button part="next-button" class="nav-button next"
|
|
188
|
+
?hidden=${!this.navigation || !this.loop && this.index >= this.maxIndex}
|
|
143
189
|
@click=${this.next}>
|
|
144
190
|
<u-icon lib="internal" name="chevron-right"></u-icon>
|
|
145
191
|
</u-button>
|
|
146
192
|
|
|
147
193
|
<div part="indicator" class="indicator"
|
|
148
|
-
?hidden=${!this.pagination || !this.
|
|
149
|
-
${Array.from({ length: this.
|
|
150
|
-
<button part="dot"
|
|
151
|
-
|
|
152
|
-
@click=${() => this.goTo(Math.min(i * this.
|
|
194
|
+
?hidden=${!this.pagination || !this.slideCount}>
|
|
195
|
+
${Array.from({ length: this.pageCount }, (_, i) => html`
|
|
196
|
+
<button part="dot" class="dot"
|
|
197
|
+
?active=${i === this.currentPage}
|
|
198
|
+
@click=${() => this.goTo(Math.min(i * this.perMove, this.maxIndex))}>
|
|
153
199
|
</button>
|
|
154
200
|
`)}
|
|
155
201
|
</div>
|
|
156
202
|
`;
|
|
157
203
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
} else if (this.loop) {
|
|
164
|
-
this.goTo(Math.min((this._pageCount - 1) * this._perMove, this._maxIndex));
|
|
165
|
-
}
|
|
204
|
+
startAutoplay() {
|
|
205
|
+
this.stopAutoplay();
|
|
206
|
+
this.autoplayTimer = window.setInterval(() => {
|
|
207
|
+
this.next();
|
|
208
|
+
}, this.autoplayInterval);
|
|
166
209
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
this.goTo(target);
|
|
172
|
-
} else if (this.loop) {
|
|
173
|
-
this.goTo(0);
|
|
210
|
+
stopAutoplay() {
|
|
211
|
+
if (this.autoplayTimer) {
|
|
212
|
+
clearInterval(this.autoplayTimer);
|
|
213
|
+
this.autoplayTimer = void 0;
|
|
174
214
|
}
|
|
175
215
|
}
|
|
176
|
-
/** 지정한 인덱스로 이동 */
|
|
177
|
-
goTo(index) {
|
|
178
|
-
if (index < 0 || index > this._maxIndex || index === this.currentIndex) return;
|
|
179
|
-
this.currentIndex = index;
|
|
180
|
-
this.emit("u-change", {
|
|
181
|
-
currentIndex: this.currentIndex
|
|
182
|
-
});
|
|
183
|
-
if (this.autoplay) this.startAutoplay();
|
|
184
|
-
}
|
|
185
216
|
handleSlotChange(e) {
|
|
186
217
|
const slot = e.target;
|
|
187
|
-
this.
|
|
188
|
-
if (this.
|
|
189
|
-
this.
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
startAutoplay() {
|
|
193
|
-
this.stopAutoplay();
|
|
194
|
-
this._autoplayTimer = window.setInterval(() => this.next(), this.autoplayInterval);
|
|
195
|
-
}
|
|
196
|
-
stopAutoplay() {
|
|
197
|
-
if (this._autoplayTimer) {
|
|
198
|
-
clearInterval(this._autoplayTimer);
|
|
199
|
-
this._autoplayTimer = void 0;
|
|
218
|
+
this.slideCount = slot.assignedElements().length;
|
|
219
|
+
if (this.index >= this.slideCount) {
|
|
220
|
+
this.index = Math.max(0, this.slideCount - 1);
|
|
200
221
|
}
|
|
201
222
|
}
|
|
202
223
|
}
|
|
203
224
|
__decorateClass([
|
|
204
|
-
property({ type:
|
|
205
|
-
], UCarousel.prototype, "currentIndex");
|
|
206
|
-
__decorateClass([
|
|
207
|
-
property({ type: Boolean, reflect: true })
|
|
225
|
+
property({ type: Boolean })
|
|
208
226
|
], UCarousel.prototype, "autoplay");
|
|
209
227
|
__decorateClass([
|
|
210
228
|
property({ type: Number, attribute: "autoplay-interval" })
|
|
211
229
|
], UCarousel.prototype, "autoplayInterval");
|
|
212
230
|
__decorateClass([
|
|
213
|
-
property({ type: Boolean
|
|
231
|
+
property({ type: Boolean })
|
|
232
|
+
], UCarousel.prototype, "loop");
|
|
233
|
+
__decorateClass([
|
|
234
|
+
property({ type: Boolean })
|
|
214
235
|
], UCarousel.prototype, "navigation");
|
|
215
236
|
__decorateClass([
|
|
216
|
-
property({ type: Boolean
|
|
237
|
+
property({ type: Boolean })
|
|
217
238
|
], UCarousel.prototype, "pagination");
|
|
218
|
-
__decorateClass([
|
|
219
|
-
property({ type: Boolean, reflect: true })
|
|
220
|
-
], UCarousel.prototype, "loop");
|
|
221
239
|
__decorateClass([
|
|
222
240
|
property({ type: Boolean, reflect: true })
|
|
223
241
|
], UCarousel.prototype, "draggable");
|
|
224
242
|
__decorateClass([
|
|
225
|
-
property({ type: Number,
|
|
243
|
+
property({ type: Number, attribute: "slides-per-view" })
|
|
226
244
|
], UCarousel.prototype, "slidesPerView");
|
|
227
245
|
__decorateClass([
|
|
228
246
|
property({ type: Number, attribute: "slides-per-move" })
|
|
229
247
|
], UCarousel.prototype, "slidesPerMove");
|
|
230
248
|
__decorateClass([
|
|
231
|
-
property({ type: Number
|
|
249
|
+
property({ type: Number })
|
|
232
250
|
], UCarousel.prototype, "gap");
|
|
251
|
+
__decorateClass([
|
|
252
|
+
property({ type: Number })
|
|
253
|
+
], UCarousel.prototype, "index");
|
|
233
254
|
__decorateClass([
|
|
234
255
|
state()
|
|
235
|
-
], UCarousel.prototype, "
|
|
256
|
+
], UCarousel.prototype, "slideCount");
|
|
236
257
|
__decorateClass([
|
|
237
258
|
state()
|
|
238
|
-
], UCarousel.prototype, "
|
|
259
|
+
], UCarousel.prototype, "isDragging");
|
|
239
260
|
__decorateClass([
|
|
240
261
|
state()
|
|
241
|
-
], UCarousel.prototype, "
|
|
262
|
+
], UCarousel.prototype, "dragOffset");
|
|
242
263
|
|
|
243
264
|
export { UCarousel };
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
2
|
|
|
3
3
|
const styles = css`
|
|
4
|
-
/* ── Host ── */
|
|
5
4
|
:host {
|
|
6
5
|
--slide-gap: 0px;
|
|
7
6
|
--slides-per-view: 1;
|
|
8
7
|
}
|
|
9
8
|
:host {
|
|
10
|
-
display: block;
|
|
11
9
|
position: relative;
|
|
10
|
+
display: block;
|
|
12
11
|
width: 100%;
|
|
13
12
|
overflow: hidden;
|
|
14
|
-
box-sizing: border-box;
|
|
15
13
|
}
|
|
16
|
-
|
|
17
|
-
/* ── Draggable ── */
|
|
18
14
|
:host([draggable]) .slides-wrapper {
|
|
19
15
|
cursor: grab;
|
|
20
16
|
user-select: none;
|
|
@@ -38,6 +34,7 @@ const styles = css`
|
|
|
38
34
|
|
|
39
35
|
.slides {
|
|
40
36
|
display: flex;
|
|
37
|
+
flex-direction: row;
|
|
41
38
|
width: 100%;
|
|
42
39
|
height: 100%;
|
|
43
40
|
gap: var(--slide-gap, 0px);
|
|
@@ -46,12 +43,10 @@ const styles = css`
|
|
|
46
43
|
|
|
47
44
|
::slotted(*) {
|
|
48
45
|
flex: 0 0 calc(
|
|
49
|
-
(100% - (var(--slides-per-view) - 1) * var(--slide-gap, 0px))
|
|
50
|
-
/ var(--slides-per-view)
|
|
46
|
+
(100% - (var(--slides-per-view) - 1) * var(--slide-gap, 0px)) / var(--slides-per-view)
|
|
51
47
|
);
|
|
52
48
|
min-width: 0;
|
|
53
49
|
height: 100%;
|
|
54
|
-
box-sizing: border-box;
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
/* ── Navigation ── */
|
|
@@ -60,34 +55,38 @@ const styles = css`
|
|
|
60
55
|
z-index: 10;
|
|
61
56
|
top: 50%;
|
|
62
57
|
transform: translateY(-50%);
|
|
63
|
-
width: 40px;
|
|
64
|
-
height: 40px;
|
|
65
58
|
display: flex;
|
|
66
59
|
align-items: center;
|
|
67
60
|
justify-content: center;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
opacity: 0.9;
|
|
61
|
+
font-size: 24px;
|
|
62
|
+
color: var(--u-neutral-900);
|
|
63
|
+
border: none;
|
|
64
|
+
background-color: transparent;
|
|
73
65
|
}
|
|
74
66
|
.nav-button:hover {
|
|
75
|
-
opacity:
|
|
76
|
-
|
|
67
|
+
opacity: 0.5;
|
|
68
|
+
transform: scale(1.2) translateY(-40%);
|
|
69
|
+
}
|
|
70
|
+
.nav-button:active {
|
|
71
|
+
opacity: 0.8;
|
|
72
|
+
transform: scale(1.1) translateY(-45%);
|
|
77
73
|
}
|
|
78
74
|
|
|
79
75
|
.nav-button.prev { left: 16px; }
|
|
80
76
|
.nav-button.next { right: 16px; }
|
|
81
77
|
|
|
82
|
-
/* ──
|
|
78
|
+
/* ── Pagination ── */
|
|
83
79
|
.indicator {
|
|
84
80
|
position: absolute;
|
|
85
81
|
z-index: 10;
|
|
86
82
|
bottom: 16px;
|
|
87
83
|
left: 50%;
|
|
88
|
-
transform: translateX(-50%);
|
|
89
84
|
display: flex;
|
|
85
|
+
flex-direction: row;
|
|
86
|
+
align-items: center;
|
|
87
|
+
justify-content: center;
|
|
90
88
|
gap: 8px;
|
|
89
|
+
transform: translateX(-50%);
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
.dot {
|
|
@@ -96,17 +95,17 @@ const styles = css`
|
|
|
96
95
|
padding: 0;
|
|
97
96
|
border: none;
|
|
98
97
|
border-radius: 50%;
|
|
99
|
-
background-color: var(--u-neutral-400
|
|
98
|
+
background-color: var(--u-neutral-400);
|
|
100
99
|
cursor: pointer;
|
|
101
100
|
transition: all 0.2s ease;
|
|
102
101
|
}
|
|
103
102
|
.dot:hover {
|
|
104
|
-
background-color: var(--u-neutral-200
|
|
103
|
+
background-color: var(--u-neutral-200);
|
|
105
104
|
}
|
|
106
|
-
.dot
|
|
107
|
-
background-color: var(--u-neutral-100, rgba(0, 0, 0, 0.8));
|
|
105
|
+
.dot[active] {
|
|
108
106
|
width: 24px;
|
|
109
107
|
border-radius: 5px;
|
|
108
|
+
background-color: var(--u-neutral-100);
|
|
110
109
|
}
|
|
111
110
|
`;
|
|
112
111
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { UElement } from '../UElement.js';
|
|
2
|
+
import { UModalElement } from '../UModalElement.js';
|
|
3
3
|
/**
|
|
4
4
|
* Dialog 컴포넌트는 모달 대화상자를 제공합니다.
|
|
5
5
|
* 오버레이와 함께 화면 중앙에 표시되며, 헤더, 본문, 푸터 영역을 슬롯으로 제공합니다.
|
|
6
6
|
*/
|
|
7
|
-
export declare class UDialog extends
|
|
7
|
+
export declare class UDialog extends UModalElement {
|
|
8
8
|
static styles: import('lit').CSSResultGroup[];
|
|
9
|
-
static dependencies: Record<string, typeof
|
|
9
|
+
static dependencies: Record<string, typeof UElement>;
|
|
10
10
|
/** 헤드리스 모드 여부 */
|
|
11
11
|
headless: boolean;
|
|
12
12
|
/** 타이틀 텍스트 */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
|
-
import {
|
|
3
|
+
import { UModalElement } from '../UModalElement.js';
|
|
4
4
|
import { UIcon } from '../icon/UIcon.component.js';
|
|
5
5
|
import { UButton } from '../button/UButton.component.js';
|
|
6
6
|
import { styles } from './UDialog.styles.js';
|
|
@@ -14,7 +14,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
14
14
|
if (result) __defProp(target, key, result);
|
|
15
15
|
return result;
|
|
16
16
|
};
|
|
17
|
-
class UDialog extends
|
|
17
|
+
class UDialog extends UModalElement {
|
|
18
18
|
constructor() {
|
|
19
19
|
super(...arguments);
|
|
20
20
|
this.headless = false;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UElement } from '../UElement.js';
|
|
2
2
|
/**
|
|
3
3
|
* Divider 컴포넌트는 엘리먼트 사이에 구분선을 제공합니다.
|
|
4
4
|
*/
|
|
5
|
-
export declare class UDivider extends
|
|
5
|
+
export declare class UDivider extends UElement {
|
|
6
6
|
static styles: import('lit').CSSResultGroup[];
|
|
7
|
-
static dependencies: Record<string, typeof
|
|
7
|
+
static dependencies: Record<string, typeof UElement>;
|
|
8
8
|
/** 수직 방향 여부를 설정합니다. (기본값: 수평) */
|
|
9
9
|
vertical: boolean;
|
|
10
10
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { property } from 'lit/decorators.js';
|
|
2
|
-
import {
|
|
2
|
+
import { UElement } from '../UElement.js';
|
|
3
3
|
import { styles } from './UDivider.styles.js';
|
|
4
4
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -11,7 +11,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
11
11
|
if (result) __defProp(target, key, result);
|
|
12
12
|
return result;
|
|
13
13
|
};
|
|
14
|
-
class UDivider extends
|
|
14
|
+
class UDivider extends UElement {
|
|
15
15
|
constructor() {
|
|
16
16
|
super(...arguments);
|
|
17
17
|
this.vertical = false;
|