@egjs/vue3-flicking 4.14.1 → 4.16.0-beta.1

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 (40) hide show
  1. package/LICENSE +19 -0
  2. package/declaration/FlickingProps.d.ts +1 -1
  3. package/declaration/VuePanel.d.ts +1 -1
  4. package/declaration/VueRenderer.d.ts +1 -1
  5. package/declaration/types.d.ts +3 -3
  6. package/dev/archive/App.vue +156 -0
  7. package/dev/archive/BasicDemo.vue +171 -0
  8. package/dev/archive/MainApp.vue +73 -0
  9. package/dev/archive/ReactiveDemo.vue +120 -0
  10. package/dev/archive/components/Test.vue +3 -0
  11. package/dev/archive/components/Test2.vue +3 -0
  12. package/dev/archive/demo-common.css +208 -0
  13. package/dev/archive/main.ts +15 -0
  14. package/dev/archive/router.ts +29 -0
  15. package/dev/basic-sample/App.vue +32 -0
  16. package/dev/basic-sample/index.html +15 -0
  17. package/dev/basic-sample/main.ts +13 -0
  18. package/dev/index.html +18 -0
  19. package/dev/plugin-check/App.vue +245 -0
  20. package/dev/plugin-check/index.html +15 -0
  21. package/dev/plugin-check/main.ts +13 -0
  22. package/dev/scratch/App.vue +32 -0
  23. package/dev/scratch/index.html +15 -0
  24. package/dev/scratch/main.ts +13 -0
  25. package/dev/vite-env.d.ts +9 -0
  26. package/dist/flicking.cjs.js +446 -542
  27. package/dist/flicking.cjs.js.map +1 -1
  28. package/dist/flicking.esm.js +450 -541
  29. package/dist/flicking.esm.js.map +1 -1
  30. package/package.json +16 -22
  31. package/src/Flicking.ts +55 -62
  32. package/src/FlickingProps.ts +3 -2
  33. package/src/VueElementProvider.ts +3 -1
  34. package/src/VueRenderer.ts +3 -8
  35. package/src/reactive.ts +1 -2
  36. package/src/types.ts +27 -30
  37. package/vite.config.ts +34 -0
  38. package/vite.dev.config.ts +49 -0
  39. package/public/favicon.ico +0 -0
  40. package/public/index.html +0 -18
package/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2015-present NAVER Corp.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -1,5 +1,5 @@
1
- import { PropType } from "vue";
2
1
  import { FlickingOptions, Plugin, Status } from "@egjs/flicking";
2
+ import { PropType } from "vue";
3
3
  declare const _default: {
4
4
  viewportTag: {
5
5
  type: StringConstructor;
@@ -1,6 +1,6 @@
1
1
  declare const VuePanel: import("vue").DefineComponent<{}, {}, {
2
2
  hide: boolean;
3
- }, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
3
+ }, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
4
4
  declare type VuePanelType = InstanceType<typeof VuePanel>;
5
5
  interface VuePanel extends VuePanelType {
6
6
  }
@@ -10,6 +10,6 @@ declare class VueRenderer extends ExternalRenderer {
10
10
  render(): Promise<void>;
11
11
  forceRenderAllPanels(): Promise<void>;
12
12
  protected _collectPanels(): void;
13
- protected _createPanel(externalComponent: VuePanel, options: PanelOptions): import("@egjs/flicking/declaration/core/panel/Panel").default;
13
+ protected _createPanel(externalComponent: VuePanel, options: PanelOptions): import("@egjs/flicking/dist/core/panel/Panel").default;
14
14
  }
15
15
  export default VueRenderer;
@@ -1,11 +1,11 @@
1
- import { ComponentOptionsMixin, DefineComponent, VNode } from "vue";
2
- import VanillaFlicking, { Plugin, Status, FlickingOptions, FlickingEvents } from "@egjs/flicking";
3
1
  import Component from "@egjs/component";
2
+ import VanillaFlicking, { FlickingEvents, FlickingOptions, Plugin, Status } from "@egjs/flicking";
4
3
  import ListDiffer, { DiffResult } from "@egjs/list-differ";
4
+ import { ComponentOptionsMixin, DefineComponent, VNode } from "vue";
5
5
  import FlickingProps from "./FlickingProps";
6
6
  export interface FlickingData {
7
7
  renderEmitter: Component<{
8
- render: void;
8
+ render: undefined;
9
9
  }>;
10
10
  vanillaFlicking: VanillaFlicking;
11
11
  pluginsDiffer: ListDiffer<Plugin>;
@@ -0,0 +1,156 @@
1
+ <template>
2
+ <article class="demo-container">
3
+ <h1>Default Rendering</h1>
4
+ <Flicking>
5
+ <div class="panel">0</div>
6
+ <div class="panel">1</div>
7
+ <div class="panel">2</div>
8
+ </Flicking>
9
+ <h1>Bound</h1>
10
+ <Flicking :options="{ bound: true }">
11
+ <div class="panel">0</div>
12
+ <div class="panel">1</div>
13
+ <div class="panel">2</div>
14
+ <div class="panel">3</div>
15
+ <div class="panel">4</div>
16
+ <div class="panel">5</div>
17
+ <div class="panel">6</div>
18
+ </Flicking>
19
+ <h1>FreeScroll</h1>
20
+ <Flicking :options="{ moveType: 'freeScroll' }">
21
+ <div class="panel">0</div>
22
+ <div class="panel">1</div>
23
+ <div class="panel">2</div>
24
+ </Flicking>
25
+ <h1>List Rendering</h1>
26
+ <Flicking>
27
+ <Test v-for="item in list0" :key="item" />
28
+ </Flicking>
29
+ <h1>Adding panels</h1>
30
+ <Flicking :options="{ circular: true, renderOnlyVisible: true }">
31
+ <div class="panel" v-for="panel in panels" :key="panel">{{ panel }}</div>
32
+ <Test />
33
+ </Flicking>
34
+ <div>
35
+ <span class="button" @click="() => {
36
+ prepend();
37
+ }">Prepend</span>
38
+ <span class="button" @click="() => {
39
+ append();
40
+ }">Append</span>
41
+ </div>
42
+ <h1>Method call</h1>
43
+ <Flicking ref="flick" :options="{ circular: true }">
44
+ <div class="panel">0</div>
45
+ <div class="panel">1</div>
46
+ <div class="panel">2</div>
47
+ <div class="panel">3</div>
48
+ <div class="panel">4</div>
49
+ <div class="panel">5</div>
50
+ <div class="panel">6</div>
51
+ <div class="panel">7</div>
52
+ <div class="panel">8</div>
53
+ </Flicking>
54
+ <div>
55
+ <span class="button" @click="() => {
56
+ prev();
57
+ }">Prev</span>
58
+ <span class="button" @click="() => {
59
+ next();
60
+ }">Next</span>
61
+ </div>
62
+ <Flicking :plugins="arrow">
63
+ <div class="panel">0</div>
64
+ <div class="panel">1</div>
65
+ <div class="panel">2</div>
66
+ <div class="panel">3</div>
67
+ <div class="panel">4</div>
68
+ <template #viewport>
69
+ <span class="flicking-arrow-prev"></span>
70
+ <span class="flicking-arrow-next"></span>
71
+ </template>
72
+ </Flicking>
73
+ <Flicking :plugins="fade" :options="{ renderOnlyVisible: true }">
74
+ <div class="panel">0</div>
75
+ <div class="panel">1</div>
76
+ <div class="panel">2</div>
77
+ <div class="panel">3</div>
78
+ <div class="panel">4</div>
79
+ </Flicking>
80
+ <Flicking class="flicking flicking0" ref="vFlick" :options="{
81
+ panelsPerView: 5,
82
+ circular: true,
83
+ virtual: {
84
+ panelClass: 'panel',
85
+ renderPanel: (panel) => `Panel ${panel.index}`,
86
+ initialPanelCount: 100
87
+ }
88
+ }"></Flicking>
89
+ <button @click="this.vPrepend">Prepend</button>
90
+ <button @click="this.vAppend">Append</button>
91
+ <Flicking :options="{ panelsPerView: this.panelsPerView }">
92
+ <div class="panel">0</div>
93
+ <div class="panel">1</div>
94
+ <div class="panel">2</div>
95
+ <div class="panel">3</div>
96
+ <div class="panel">4</div>
97
+ </Flicking>
98
+ <button @click="this.changeProp">Change</button>
99
+ </article>
100
+ </template>
101
+
102
+ <script>
103
+ import { Arrow, Fade } from "@dev/plugins";
104
+ import Flicking from "@dev/vue3-flicking";
105
+ import Test from "./components/Test.vue";
106
+ import Test2 from "./components/Test2.vue";
107
+
108
+ export default {
109
+ components: {
110
+ Flicking,
111
+ Test,
112
+ Test2
113
+ },
114
+ data() {
115
+ return {
116
+ panels: [0, 1, 2, 3, 4, 5, 6],
117
+ list0: [0, 1, 2],
118
+ arrow: [new Arrow()],
119
+ fade: [new Fade()],
120
+ panelsPerView: 5
121
+ };
122
+ },
123
+ methods: {
124
+ prepend() {
125
+ this.panels.splice(0, 0, this.panels[0] - 2, this.panels[0] - 1);
126
+ },
127
+ append() {
128
+ const lastEl = this.panels[this.panels.length - 1];
129
+ this.panels.push(lastEl + 1, lastEl + 2);
130
+ },
131
+ prev() {
132
+ this.$refs.flick.prev();
133
+ },
134
+ next() {
135
+ this.$refs.flick.next();
136
+ },
137
+ vPrepend() {
138
+ this.$refs.vFlick.virtual.prepend(100);
139
+ },
140
+ vAppend() {
141
+ this.$refs.vFlick.virtual.append(100);
142
+ },
143
+ changeProp() {
144
+ this.panelsPerView -= 1;
145
+ }
146
+ }
147
+ };
148
+ </script>
149
+
150
+ <style>
151
+ @import './demo-common.css';
152
+ </style>
153
+
154
+ <style scoped>
155
+ /* App.vue 전용 스타일 (필요시 추가) */
156
+ </style>
@@ -0,0 +1,171 @@
1
+ <template>
2
+ <div class="demo-container">
3
+ <h2>Vue3 Composition API Flicking Demo</h2>
4
+
5
+ <!-- 기본 Flicking -->
6
+ <div class="section">
7
+ <h3>기본 Flicking</h3>
8
+ <Flicking ref="flickingRef" :options="flickingOptions">
9
+ <div
10
+ v-for="item in panels"
11
+ :key="item.id"
12
+ class="panel"
13
+ :style="{ backgroundColor: item.color }"
14
+ >
15
+ {{ item.text }}
16
+ </div>
17
+ </Flicking>
18
+ </div>
19
+
20
+ <!-- 컨트롤 버튼들 -->
21
+ <div class="controls">
22
+ <button @click="addPanel" class="btn">패널 추가</button>
23
+ <button @click="removePanel" class="btn">패널 제거</button>
24
+ <button @click="prev" class="btn">이전</button>
25
+ <button @click="next" class="btn">다음</button>
26
+ <button @click="moveTo(2)" class="btn">3번 패널로 이동</button>
27
+ </div>
28
+
29
+ <!-- 현재 상태 표시 -->
30
+ <div class="status">
31
+ <p>총 패널 수: {{ panelCount }}</p>
32
+ <p>현재 인덱스: {{ currentIndex }}</p>
33
+ </div>
34
+
35
+ <!-- 동적 옵션 변경 -->
36
+ <div class="section">
37
+ <h3>옵션 변경</h3>
38
+ <label>
39
+ <input
40
+ type="checkbox"
41
+ v-model="isCircular"
42
+ @change="updateOptions"
43
+ />
44
+ circular
45
+ </label>
46
+ <label>
47
+ <input
48
+ type="checkbox"
49
+ v-model="isBound"
50
+ @change="updateOptions"
51
+ />
52
+ bound
53
+ </label>
54
+ </div>
55
+ </div>
56
+ </template>
57
+
58
+ <script setup>
59
+ import Flicking from "@dev/vue3-flicking";
60
+ import { computed, onMounted, reactive, ref, watch } from "vue";
61
+
62
+ // Flicking 인스턴스 참조
63
+ const flickingRef = ref(null);
64
+
65
+ // 반응형 데이터
66
+ const panels = reactive([
67
+ { id: 1, text: "패널 1", color: "#ff6b6b" },
68
+ { id: 2, text: "패널 2", color: "#4ecdc4" },
69
+ { id: 3, text: "패널 3", color: "#45b7d1" },
70
+ { id: 4, text: "패널 4", color: "#96ceb4" },
71
+ { id: 5, text: "패널 5", color: "#feca57" }
72
+ ]);
73
+
74
+ // Flicking 옵션
75
+ const flickingOptions = reactive({
76
+ circular: false,
77
+ bound: false,
78
+ duration: 500,
79
+ defaultIndex: 0
80
+ });
81
+
82
+ // 상태 변수들
83
+ const isCircular = ref(false);
84
+ const isBound = ref(false);
85
+ const currentIndex = ref(0);
86
+
87
+ // 계산된 속성
88
+ const panelCount = computed(() => panels.length);
89
+
90
+ // 메서드들
91
+ const addPanel = () => {
92
+ const newId = Math.max(...panels.map(p => p.id)) + 1;
93
+ const colors = ["#ff6b6b", "#4ecdc4", "#45b7d1", "#96ceb4", "#feca57", "#ff9ff3", "#54a0ff"];
94
+ const randomColor = colors[Math.floor(Math.random() * colors.length)];
95
+
96
+ panels.push({
97
+ id: newId,
98
+ text: `패널 ${newId}`,
99
+ color: randomColor
100
+ });
101
+ };
102
+
103
+ const removePanel = () => {
104
+ if (panels.length > 1) {
105
+ panels.pop();
106
+ }
107
+ };
108
+
109
+ const prev = () => {
110
+ if (flickingRef.value) {
111
+ flickingRef.value.prev();
112
+ }
113
+ };
114
+
115
+ const next = () => {
116
+ if (flickingRef.value) {
117
+ flickingRef.value.next();
118
+ }
119
+ };
120
+
121
+ const moveTo = index => {
122
+ if (flickingRef.value) {
123
+ flickingRef.value.moveTo(index);
124
+ }
125
+ };
126
+
127
+ const updateOptions = () => {
128
+ flickingOptions.circular = isCircular.value;
129
+ flickingOptions.bound = isBound.value;
130
+ };
131
+
132
+ // 이벤트 리스너
133
+ const onChanged = e => {
134
+ currentIndex.value = flickingRef.value.index;
135
+ };
136
+
137
+ // 라이프사이클 훅
138
+ onMounted(() => {
139
+ if (flickingRef.value) {
140
+ // 이벤트 리스너 등록
141
+ flickingRef.value.on("changed", onChanged);
142
+ }
143
+ });
144
+
145
+ // 감시자
146
+ watch(
147
+ panels,
148
+ newPanels => {
149
+ console.log("패널이 변경되었습니다:", newPanels.length);
150
+ },
151
+ { deep: true }
152
+ );
153
+ </script>
154
+
155
+ <style>
156
+ @import './demo-common.css';
157
+ </style>
158
+
159
+ <style scoped>
160
+ /* BasicDemo 전용 스타일 */
161
+ .demo-container {
162
+ max-width: 800px;
163
+ }
164
+
165
+ .panel {
166
+ width: 200px;
167
+ height: 150px;
168
+ margin-right: 10px;
169
+ font-size: 18px;
170
+ }
171
+ </style>
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <div class="main-app">
3
+ <header class="header">
4
+ <h1>Vue3 Flicking Demo</h1>
5
+ <nav class="navigation">
6
+ <router-link to="/" class="nav-link">Home</router-link>
7
+ <router-link to="/basic" class="nav-link">BasicDemo</router-link>
8
+ <router-link to="/reactive" class="nav-link">ReactiveDemo</router-link>
9
+ </nav>
10
+ </header>
11
+
12
+ <main class="content">
13
+ <router-view></router-view>
14
+ </main>
15
+ </div>
16
+ </template>
17
+
18
+ <script setup>
19
+ // Composition API setup
20
+ </script>
21
+
22
+ <style scoped>
23
+ .main-app {
24
+ font-family: Avenir, Helvetica, Arial, sans-serif;
25
+ -webkit-font-smoothing: antialiased;
26
+ -moz-osx-font-smoothing: grayscale;
27
+ color: #2c3e50;
28
+ max-width: 1200px;
29
+ margin: 0 auto;
30
+ padding: 20px;
31
+ }
32
+
33
+ .header {
34
+ text-align: center;
35
+ margin-bottom: 40px;
36
+ padding-bottom: 20px;
37
+ border-bottom: 2px solid #eee;
38
+ }
39
+
40
+ .header h1 {
41
+ margin-bottom: 20px;
42
+ color: #333;
43
+ }
44
+
45
+ .navigation {
46
+ display: flex;
47
+ justify-content: center;
48
+ gap: 20px;
49
+ flex-wrap: wrap;
50
+ }
51
+
52
+ .nav-link {
53
+ padding: 10px 20px;
54
+ background-color: #007bff;
55
+ color: white;
56
+ text-decoration: none;
57
+ border-radius: 5px;
58
+ transition: background-color 0.3s;
59
+ font-weight: bold;
60
+ }
61
+
62
+ .nav-link:hover {
63
+ background-color: #0056b3;
64
+ }
65
+
66
+ .nav-link.router-link-active {
67
+ background-color: #28a745;
68
+ }
69
+
70
+ .content {
71
+ min-height: 500px;
72
+ }
73
+ </style>
@@ -0,0 +1,120 @@
1
+ <template>
2
+ <div class="demo-container">
3
+ <h2>Reactive API - Pagination Demo</h2>
4
+
5
+ <div class="section">
6
+ <h3>Pagination with Reactive API</h3>
7
+ <Flicking ref="flickingRef" :options="flickingOptions">
8
+ <div
9
+ v-for="item in panels"
10
+ :key="item.id"
11
+ class="panel"
12
+ :style="{ backgroundColor: item.color }"
13
+ >
14
+ {{ item.text }}
15
+ </div>
16
+ </Flicking>
17
+ </div>
18
+
19
+ <div class="progress-container">
20
+ <div class="progress-bar" :style="{ width: progress + '%' }"></div>
21
+ <div class="progress-text">Progress: {{ progress.toFixed(1) }}%</div>
22
+ </div>
23
+
24
+ <div class="controls">
25
+ <button @click="handlePrev" :disabled="isReachStart" class="btn">
26
+ 이전
27
+ </button>
28
+ <button @click="handleNext" :disabled="isReachEnd" class="btn">
29
+ 다음
30
+ </button>
31
+ </div>
32
+
33
+ <div class="pagination">
34
+ <button
35
+ v-for="page in totalPanelCount"
36
+ :key="page"
37
+ :class="{ active: currentPanelIndex + 1 === page }"
38
+ @click="moveTo(page - 1)"
39
+ class="pagination-btn"
40
+ >
41
+ {{ page }}
42
+ </button>
43
+ </div>
44
+
45
+ <div class="status">
46
+ <p>총 패널 수: {{ totalPanelCount }}</p>
47
+ <p>현재 인덱스: {{ currentPanelIndex }}</p>
48
+ <p>진행률: {{ progress.toFixed(1) }}%</p>
49
+ <p>첫 번째 패널: {{ isReachStart ? '도달' : '미도달' }}</p>
50
+ <p>마지막 패널: {{ isReachEnd ? '도달' : '미도달' }}</p>
51
+ </div>
52
+ </div>
53
+ </template>
54
+
55
+ <script setup>
56
+ import Flicking, { useFlickingReactiveAPI } from "@dev/vue3-flicking";
57
+ import { onMounted, reactive, ref } from "vue";
58
+
59
+ // Flicking 인스턴스 참조
60
+ const flickingRef = ref(null);
61
+
62
+ // 반응형 데이터
63
+ const panels = reactive([
64
+ { id: 1, text: "패널 1", color: "#ff6b6b" },
65
+ { id: 2, text: "패널 2", color: "#4ecdc4" },
66
+ { id: 3, text: "패널 3", color: "#45b7d1" },
67
+ { id: 4, text: "패널 4", color: "#96ceb4" },
68
+ { id: 5, text: "패널 5", color: "#feca57" }
69
+ ]);
70
+
71
+ // Flicking 옵션
72
+ const flickingOptions = reactive({
73
+ circular: false,
74
+ bound: false,
75
+ duration: 500,
76
+ defaultIndex: 0
77
+ });
78
+
79
+ // Reactive API 훅 사용
80
+ const { currentPanelIndex, totalPanelCount, isReachStart, isReachEnd, progress, moveTo } =
81
+ useFlickingReactiveAPI(flickingRef);
82
+
83
+ // 메서드들
84
+ const handlePrev = () => {
85
+ if (!isReachStart.value) {
86
+ moveTo(currentPanelIndex.value - 1);
87
+ }
88
+ };
89
+
90
+ const handleNext = () => {
91
+ if (!isReachEnd.value) {
92
+ moveTo(currentPanelIndex.value + 1);
93
+ }
94
+ };
95
+
96
+ // 라이프사이클 훅
97
+ onMounted(() => {
98
+ if (flickingRef.value) {
99
+ console.log("Flicking 인스턴스가 마운트되었습니다");
100
+ }
101
+ });
102
+ </script>
103
+
104
+ <style>
105
+ @import './demo-common.css';
106
+ </style>
107
+
108
+ <style scoped>
109
+ /* ReactiveDemo 전용 스타일 */
110
+ .demo-container {
111
+ max-width: 800px;
112
+ }
113
+
114
+ .panel {
115
+ width: 200px;
116
+ height: 150px;
117
+ margin-right: 10px;
118
+ font-size: 18px;
119
+ }
120
+ </style>
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <div class="panel">TEST Component</div>
3
+ </template>
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <div class="panel">TEST-2</div>
3
+ </template>