@egjs/flicking 4.13.2-beta.1 → 4.14.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.
@@ -3,36 +3,73 @@
3
3
  /**
4
4
  * 프레임워크 컴포넌트를 디버깅할 때 코어 바닐라 로직을 수정하면서 확인할 필요가 있을 때,
5
5
  * 이 스크립트를 이용하면 바닐라 로직 수정사항이 프레임워크 컴포넌트 로컬 데모환경에도 반영된다.
6
- *
6
+ * 다만, 바닐라 로직 수정 이후 리액트 데모에 핫 모듈 리로딩까지는 되지 않는다.
7
+ * 따라서 수정 사항들을 추가적으로 반영해주려면 바닐라를 다시 빌드해야 한다. 링크는 다시 하지 않아도 된다.
8
+ *
7
9
  * 인자로 프레임워크 컴포넌트 패키지의 루트 디렉토리를 제공하면 된다.
10
+ * 인자를 제공하지 않으면 packages 하위의 전체 프레임워크 패키지에 대해 링크를 시도한다.
8
11
  *
9
12
  * 사용 예시: node core-package-link.js react-flicking
13
+ *
14
+ *
15
+ * 개발 흐름:
16
+ * 1. 이 스크립트를 실행
17
+ * 2. 바닐라 로직 수정 후 빌드 수행
18
+ * 3. 프레임워크 컴포넌트의 데모를 실행 (바닐라 로직 변경사항이 반영됨)
19
+ * 4. 바닐라 로직 추가 수정 후 빌드 수행
20
+ * 5. 프레임워크 컴포넌트의 데모를 새로고침 (바닐라 로직 변경사항이 반영됨)
21
+ * - 원래는 새로고침만 하면 되야 하지만 타입 에러가 발생하는 경우가 있어 데모를 중지하고 다시 실행해야 할 수도 있다.
22
+ *
23
+ *
10
24
  */
11
25
 
26
+
27
+
28
+ function run(cmd, cwd = process.cwd()) {
29
+ console.log(`\n▶️ Running: ${cmd} (in ${cwd})`);
30
+ execSync(cmd, { stdio: "inherit", cwd });
31
+ }
32
+
12
33
  const { execSync } = require("child_process");
13
34
  const path = require("path");
14
35
  const fs = require("fs");
15
36
 
37
+ const frameworks = [
38
+ "ngx-flicking",
39
+ "preact-flicking",
40
+ "react-flicking",
41
+ "vue-flicking",
42
+ "vue3-flicking",
43
+ "svelte-flicking",
44
+ ];
45
+
16
46
  const args = process.argv.slice(2);
17
47
  const targetDir = args[0];
18
48
 
19
49
  if (!targetDir) {
20
- console.error("❌ 디렉토리명을 인자로 입력하세요.");
21
- process.exit(1);
22
- }
50
+ console.log(
51
+ "❗️ 디렉토리명을 인자로 입력하지 않았습니다. 전체 프레임워크에 대해 링크를 시도합니다."
52
+ );
53
+ run("npm run build");
54
+ run("npm link");
55
+ frameworks.forEach((target) => {
56
+ const fullPath = path.resolve(process.cwd(), "packages", target);
57
+ if (!fs.existsSync(fullPath)) {
58
+ console.error(`❌ 디렉토리 없음: ${fullPath}`);
59
+ process.exit(1);
60
+ }
61
+ run(`npm link '@egjs/flicking'`, fullPath);
62
+ });
63
+ } else {
64
+ const fullPath = path.resolve(process.cwd(), "packages", targetDir);
65
+ if (!fs.existsSync(fullPath)) {
66
+ console.error(`❌ 디렉토리 없음: ${fullPath}`);
67
+ process.exit(1);
68
+ }
23
69
 
24
- const fullPath = path.resolve(process.cwd(), 'packages', targetDir);
25
- if (!fs.existsSync(fullPath)) {
26
- console.error(`❌ 디렉토리 없음: ${fullPath}`);
27
- process.exit(1);
70
+ run("npm run build");
71
+ run("npm link");
72
+ run(`npm link '@egjs/flicking'`, fullPath);
28
73
  }
29
74
 
30
- function run(cmd, cwd = process.cwd()) {
31
- console.log(`\n▶️ Running: ${cmd} (in ${cwd})`);
32
- execSync(cmd, { stdio: "inherit", cwd });
33
- }
34
75
 
35
- run("npm run build");
36
- run("npm link");
37
- run(`npm link '@egjs/flicking'`, fullPath);
38
- run("npm run build", fullPath);
@@ -0,0 +1,240 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Flicking Basic Demo</title>
7
+ <link rel="stylesheet" href="../../dist/flicking.css" />
8
+ <style>
9
+ #container {
10
+ display: flex;
11
+ flex-direction: column;
12
+ align-items: center;
13
+ }
14
+ #nav-wrapper {
15
+ display: flex;
16
+ align-items: center;
17
+ }
18
+ .flicking-viewport {
19
+ width: 500px;
20
+ height: 300px;
21
+ /* margin: 0 auto; */
22
+ border: 1px solid black;
23
+ }
24
+ .flicking-camera {
25
+ display: flex;
26
+ }
27
+ .flicking-panel {
28
+ align-items: flex-end;
29
+ border-radius: 5px;
30
+ box-sizing: border-box;
31
+ display: flex;
32
+ /* height: 200px; */
33
+ justify-content: flex-start;
34
+ margin-top: 10px;
35
+ margin-bottom: 10px;
36
+ margin-right: 10px;
37
+ position: relative;
38
+ width: 200px;
39
+ background-color: aliceblue;
40
+ justify-content: center;
41
+ align-items: center;
42
+ }
43
+ .navigation-btn {
44
+ text-align: center;
45
+ margin: 0 5px;
46
+ padding: 5px 10px;
47
+ height: 50px;
48
+ }
49
+ #pagination {
50
+ display: flex;
51
+ }
52
+ .pagination-num {
53
+ background-color: beige;
54
+ margin: 5px;
55
+ width: 30px;
56
+ height: 30px;
57
+ text-align: center;
58
+ }
59
+ .pagination-num.active {
60
+ background-color: yellowgreen;
61
+ }
62
+ #scroll-progress-bar {
63
+ width: 600px;
64
+ height: 20px;
65
+ border-radius: 20px;
66
+ background-color: #e0e0e0;
67
+ overflow: hidden;
68
+ }
69
+ #scroll-progress-fill {
70
+ height: 100%;
71
+ width: 0%; /* 초기에는 0% 채워짐 */
72
+ background-color: #2196f3; /* 채워지는 색 */
73
+ transition: width 0.3s ease; /* 부드럽게 변화 */
74
+ }
75
+ </style>
76
+ </head>
77
+ <body>
78
+ <div id="container">
79
+ <div id="nav-wrapper">
80
+ <button class="navigation-btn" id="prev">Previous</button>
81
+ <div class="flicking-viewport">
82
+ <div class="flicking-camera">
83
+ <div class="flicking-panel" style="width: 500px">x0</div>
84
+ <div class="flicking-panel">x1</div>
85
+ <div class="flicking-panel">x2</div>
86
+ <div class="flicking-panel">x3</div>
87
+ <div class="flicking-panel">x4</div>
88
+ </div>
89
+ </div>
90
+ <button class="navigation-btn" id="next">Next</button>
91
+ </div>
92
+ <div id="pagination"></div>
93
+ <div id="scroll-progress-bar">
94
+ <div id="scroll-progress-fill"></div>
95
+ </div>
96
+ </div>
97
+
98
+ <div class="add">
99
+ <button id="prepend">prepend</button>
100
+ <button id="append">append</button>
101
+ <button id="add-random">add random</button>
102
+ </div>
103
+ <div class="remove">
104
+ <button id="remove-first">remove first</button>
105
+ <button id="remove-last">remove last</button>
106
+ <button id="remove-random">remove random</button>
107
+ </div>
108
+
109
+ <script src="../../dist/flicking.pkgd.js"></script>
110
+ <script>
111
+ document.addEventListener("DOMContentLoaded", () => {
112
+ const flicking = new Flicking(".flicking-viewport", {
113
+ renderOnlyVisible: true,
114
+ // circular: true
115
+ // horizontal: false
116
+ // align: 'center',
117
+ defaultIndex: 2,
118
+ });
119
+ const { connectFlickingReactiveAPI } = Flicking;
120
+ const reactiveObj = connectFlickingReactiveAPI(flicking);
121
+ const {
122
+ isReachStart,
123
+ isReachEnd,
124
+ totalPanelCount,
125
+ currentPanelIndex,
126
+ moveTo,
127
+ progress,
128
+ } = reactiveObj;
129
+
130
+ // Navigation buttons
131
+ const prevButton = document.getElementById("prev");
132
+ const nextButton = document.getElementById("next");
133
+
134
+ // 비활성화 여부 초기화
135
+ prevButton.disabled = isReachStart;
136
+ nextButton.disabled = isReachEnd;
137
+
138
+ // 반응형과 엮기
139
+ reactiveObj.subscribe("isReachStart", (nextValue) => {
140
+ prevButton.disabled = nextValue;
141
+ });
142
+ reactiveObj.subscribe("isReachEnd", (nextValue) => {
143
+ nextButton.disabled = nextValue;
144
+ });
145
+
146
+ // 이벤트 리스너 등록
147
+ prevButton.addEventListener("click", () => {
148
+ flicking.prev();
149
+ });
150
+
151
+ nextButton.addEventListener("click", () => {
152
+ flicking.next();
153
+ });
154
+
155
+ // 패널이 동적으로 추가되거나 삭제되었을 때도 잘 동작해야함.
156
+
157
+ let appendNum = 100;
158
+ let prependNum = -1;
159
+
160
+ const appendButton = document.getElementById("append");
161
+ const prependButton = document.getElementById("prepend");
162
+ const addRandomButton = document.getElementById("add-random");
163
+
164
+ const getRandomInt = (min, max) => {
165
+ const minCeiled = Math.ceil(min);
166
+ const maxFloored = Math.floor(max);
167
+ return Math.floor(
168
+ Math.random() * (maxFloored - minCeiled) + minCeiled
169
+ );
170
+ };
171
+ appendButton.addEventListener("click", () => {
172
+ flicking.append(`<div class="flicking-panel">x${appendNum}</div>`);
173
+ appendNum++;
174
+ });
175
+ prependButton.addEventListener("click", () => {
176
+ flicking.prepend(`<div class="flicking-panel">x${prependNum}</div>`);
177
+ prependNum--;
178
+ });
179
+ addRandomButton.addEventListener("click", () => {
180
+ const randomN = getRandomInt(0, flicking.panelCount);
181
+ flicking.insert(
182
+ randomN,
183
+ `<div class="flicking-panel">random ${randomN}</div>`
184
+ );
185
+ });
186
+
187
+ const removeFirstButton = document.getElementById("remove-first");
188
+ const removeLastButton = document.getElementById("remove-last");
189
+ const removeRandomButton = document.getElementById("remove-random");
190
+
191
+ removeFirstButton.addEventListener("click", () => {
192
+ flicking.remove(0);
193
+ });
194
+
195
+ removeLastButton.addEventListener("click", () => {
196
+ flicking.remove(flicking.panelCount - 1);
197
+ });
198
+ removeRandomButton.addEventListener("click", () => {
199
+ const randomN = getRandomInt(0, flicking.panelCount);
200
+ flicking.remove(randomN);
201
+ });
202
+
203
+ const paginationElement = document.getElementById("pagination");
204
+
205
+ const pageNums = Array.from({ length: totalPanelCount }, (_, i) => {
206
+ const div = document.createElement("div");
207
+ div.className = `pagination-num ${
208
+ i === currentPanelIndex ? "active" : ""
209
+ }`;
210
+ div.textContent = `${i}`;
211
+
212
+ div.addEventListener("click", (e) => {
213
+ moveTo(i);
214
+ });
215
+ return div;
216
+ });
217
+
218
+ paginationElement.append(...pageNums);
219
+
220
+ reactiveObj.subscribe("currentPanelIndex", (nextValue) => {
221
+ pageNums.forEach((v, i) => {
222
+ v.classList.remove("active");
223
+ if (i === nextValue) {
224
+ v.classList.add("active");
225
+ }
226
+ });
227
+ });
228
+
229
+ const scrollProgressFillElement = document.getElementById(
230
+ "scroll-progress-fill"
231
+ );
232
+ scrollProgressFillElement.style.width = `${progress}%`;
233
+
234
+ reactiveObj.subscribe("progress", (nextValue) => {
235
+ scrollProgressFillElement.style.width = `${nextValue}%`;
236
+ });
237
+ });
238
+ </script>
239
+ </body>
240
+ </html>
@@ -9,6 +9,7 @@ export * from "./renderer";
9
9
  export * from "./const/external";
10
10
  export * from "./cfc";
11
11
  export * from "./utils";
12
+ export * from "./reactive";
12
13
  export * from "./type/event";
13
14
  export * from "./type/external";
14
15
  export type { FlickingOptions, FlickingEvents, CrossFlickingOptions };
@@ -0,0 +1,25 @@
1
+ import { ReactiveObject, ReactiveSetupAdapter } from "@cfcs/core";
2
+ import Flicking from "../Flicking";
3
+ export declare type FlickingReactiveObject = ReactiveObject<FlickingReactiveState & FlickingReactiveMethod>;
4
+ export interface FlickingReactiveState {
5
+ isReachStart: boolean;
6
+ isReachEnd: boolean;
7
+ totalPanelCount: number;
8
+ currentPanelIndex: number;
9
+ progress: number;
10
+ indexProgress: number;
11
+ }
12
+ export interface FlickingReactiveMethod {
13
+ moveTo: (i: number) => Promise<void>;
14
+ }
15
+ export interface FlickingReactiveData {
16
+ flicking?: Flicking;
17
+ options?: FlickingReactiveAPIOptions;
18
+ }
19
+ export interface FlickingReactiveAPIOptions {
20
+ defaultIndex?: number;
21
+ totalPanelCount?: number;
22
+ }
23
+ declare const flickingReactiveAPIAdapter: ReactiveSetupAdapter<FlickingReactiveObject, FlickingReactiveState, "moveTo", FlickingReactiveData>;
24
+ declare const connectFlickingReactiveAPI: (flicking: Flicking, options?: FlickingReactiveAPIOptions) => ReactiveObject<FlickingReactiveState & FlickingReactiveMethod>;
25
+ export { flickingReactiveAPIAdapter, connectFlickingReactiveAPI };
@@ -4,13 +4,14 @@ name: @egjs/flicking
4
4
  license: MIT
5
5
  author: NAVER Corp.
6
6
  repository: https://github.com/naver/egjs-flicking
7
- version: 4.13.2-beta.1
7
+ version: 4.14.0
8
8
  */
9
9
  'use strict';
10
10
 
11
11
  var Component = require('@egjs/component');
12
12
  var Axes = require('@egjs/axes');
13
13
  var ImReady = require('@egjs/imready');
14
+ var core = require('@cfcs/core');
14
15
 
15
16
  /******************************************************************************
16
17
  Copyright (c) Microsoft Corporation.
@@ -669,7 +670,7 @@ var findIndex = function (array, checker) {
669
670
  }
670
671
  return -1;
671
672
  };
672
- var getProgress = function (pos, prev, next) {
673
+ var getProgress$1 = function (pos, prev, next) {
673
674
  return (pos - prev) / (next - prev);
674
675
  };
675
676
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -4112,7 +4113,7 @@ var Camera = /*#__PURE__*/function () {
4112
4113
  if (prevPosition > panelPos) {
4113
4114
  prevPosition -= rangeDiff;
4114
4115
  }
4115
- return nearestPanel.index - 1 + getProgress(position, prevPosition, panelPos);
4116
+ return nearestPanel.index - 1 + getProgress$1(position, prevPosition, panelPos);
4116
4117
  } else {
4117
4118
  var nextPanel = nearestPanel.next();
4118
4119
  var nextPosition = nextPanel ? nextPanel.position + nextPanel.offset : nextRange + bounceSize[1];
@@ -4120,7 +4121,7 @@ var Camera = /*#__PURE__*/function () {
4120
4121
  if (nextPosition < panelPos) {
4121
4122
  nextPosition += rangeDiff;
4122
4123
  }
4123
- return nearestPanel.index + getProgress(position, panelPos, nextPosition);
4124
+ return nearestPanel.index + getProgress$1(position, panelPos, nextPosition);
4124
4125
  }
4125
4126
  },
4126
4127
  enumerable: false,
@@ -5463,10 +5464,10 @@ var Panel = /*#__PURE__*/function () {
5463
5464
  }
5464
5465
  if (camPos < position) {
5465
5466
  var disappearPosNext = position + (camera.size - camera.alignPosition) + alignPosition;
5466
- return -getProgress(camPos, position, disappearPosNext);
5467
+ return -getProgress$1(camPos, position, disappearPosNext);
5467
5468
  } else {
5468
5469
  var disappearPosPrev = position - (camera.alignPosition + this._size - alignPosition);
5469
- return 1 - getProgress(camPos, disappearPosPrev, position);
5470
+ return 1 - getProgress$1(camPos, disappearPosPrev, position);
5470
5471
  }
5471
5472
  },
5472
5473
  enumerable: false,
@@ -8100,7 +8101,7 @@ var Flicking = /*#__PURE__*/function (_super) {
8100
8101
  * Flicking.VERSION; // ex) 4.0.0
8101
8102
  * ```
8102
8103
  */
8103
- Flicking.VERSION = "4.13.2-beta.1";
8104
+ Flicking.VERSION = "4.14.0";
8104
8105
  return Flicking;
8105
8106
  }(Component);
8106
8107
 
@@ -8656,6 +8657,190 @@ var parseAlign = function (alignVal) {
8656
8657
  }
8657
8658
  };
8658
8659
 
8660
+ // Check if Flicking has reached the first panel
8661
+ var getIsReachStart = function (flicking) {
8662
+ return !flicking.circular && flicking.index === 0;
8663
+ };
8664
+ // Check if Flicking has reached the last panel
8665
+ var getIsReachEnd = function (flicking) {
8666
+ return !flicking.circular && flicking.index === flicking.panelCount - 1;
8667
+ };
8668
+ // Get the total number of panels
8669
+ var getTotalPanelCount = function (flicking) {
8670
+ return flicking.panelCount;
8671
+ };
8672
+ // Get the current active panel index
8673
+ var getCurrentPanelIndex = function (flicking) {
8674
+ return flicking.index;
8675
+ };
8676
+ // Calculate the overall scroll progress percentage based on the current camera position
8677
+ var getProgress = function (flicking) {
8678
+ var cam = flicking.camera;
8679
+ var progressRatio = (cam.position - cam.range.min) / (cam.range.max - cam.range.min);
8680
+ var percent = Math.min(Math.max(progressRatio, 0), 1) * 100;
8681
+ return percent;
8682
+ };
8683
+ // Calculate the progress between panels including decimal values
8684
+ var getIndexProgress = function (flicking) {
8685
+ var cam = flicking.camera;
8686
+ var anchorPoints = cam.anchorPoints;
8687
+ var length = anchorPoints.length;
8688
+ var cameraPosition = cam.position;
8689
+ var isCircular = flicking.circularEnabled;
8690
+ var indexProgress = 0;
8691
+ var _a = cam.range,
8692
+ min = _a.min,
8693
+ max = _a.max;
8694
+ var firstAnchorPoint = anchorPoints[0];
8695
+ var lastAnchorPoint = anchorPoints[length - 1];
8696
+ var distanceLastToFirst = max - lastAnchorPoint.position + (firstAnchorPoint.position - min);
8697
+ anchorPoints.some(function (anchorPoint, index) {
8698
+ var anchorPosition = anchorPoint.position;
8699
+ var nextAnchorPoint = anchorPoints[index + 1];
8700
+ if (index === 0 && cameraPosition <= anchorPosition) {
8701
+ if (isCircular) {
8702
+ indexProgress = (cameraPosition - anchorPosition) / distanceLastToFirst;
8703
+ } else {
8704
+ indexProgress = (cameraPosition - anchorPosition) / anchorPoint.panel.size;
8705
+ }
8706
+ } else if (index === length - 1 && cameraPosition >= anchorPosition) {
8707
+ if (isCircular) {
8708
+ indexProgress = index + (cameraPosition - anchorPosition) / distanceLastToFirst;
8709
+ } else {
8710
+ indexProgress = index + (cameraPosition - anchorPosition) / anchorPoint.panel.size;
8711
+ }
8712
+ } else if (nextAnchorPoint && anchorPosition <= cameraPosition && cameraPosition <= nextAnchorPoint.position) {
8713
+ indexProgress = index + (cameraPosition - anchorPosition) / (nextAnchorPoint.position - anchorPosition);
8714
+ } else {
8715
+ return false;
8716
+ }
8717
+ return true;
8718
+ });
8719
+ return indexProgress;
8720
+ };
8721
+ /**
8722
+ * Internal reactive API adapter for Flicking that manages state and event listeners
8723
+ * This adapter is used internally by framework-specific packages (react-flicking, vue-flicking, etc.)
8724
+ * to provide reactive API support. Users rarely need to use this directly.
8725
+ * @ko Flicking의 상태와 이벤트 리스너를 관리하는 내부 반응형 API 어댑터
8726
+ * 이 어댑터는 react-flicking, vue-flicking 등의 프레임워크별 패키지에서 내부적으로 사용되어
8727
+ * 반응형 API 지원을 제공합니다. 사용자가 직접 사용할 일은 거의 없습니다.
8728
+ * @param onInit - Callback when reactive object is initialized<ko>반응형 객체가 초기화될 때 호출되는 콜백</ko>
8729
+ * @param onDestroy - Callback when reactive object is destroyed<ko>반응형 객체가 파괴될 때 호출되는 콜백</ko>
8730
+ * @param setMethods - Function to set available methods<ko>사용 가능한 메서드를 설정하는 함수</ko>
8731
+ * @returns Reactive object with Flicking state and methods<ko>Flicking 상태와 메서드를 포함한 반응형 객체</ko>
8732
+ */
8733
+ var flickingReactiveAPIAdapter = function (_a) {
8734
+ var _b, _c, _d;
8735
+ var onInit = _a.onInit,
8736
+ onDestroy = _a.onDestroy,
8737
+ setMethods = _a.setMethods,
8738
+ getProps = _a.getProps;
8739
+ var flicking;
8740
+ // Move to a specific panel index
8741
+ var moveTo = function (i) {
8742
+ if (flicking == null) {
8743
+ return Promise.reject(new Error("Flicking instance is not available"));
8744
+ }
8745
+ if (flicking === null || flicking === void 0 ? void 0 : flicking.animating) {
8746
+ return Promise.resolve();
8747
+ }
8748
+ return flicking.moveTo(i);
8749
+ };
8750
+ setMethods(["moveTo"]);
8751
+ var options = getProps().options;
8752
+ // options를 고려하지 않고 초기값을 설정해도 동작에는 아무런 문제가 없으나, 이 시점의 초기값과 컴포넌트 init 단계에서의 초기값이 다르면 화면 리렌더링이 발생할 수 있으므로
8753
+ // 이렇게 미리 옵션을 통해서 예측할 수 있는 부분들은 맞춰둔다.
8754
+ var reactiveObj = core.reactive({
8755
+ isReachStart: (options === null || options === void 0 ? void 0 : options.defaultIndex) ? (options === null || options === void 0 ? void 0 : options.defaultIndex) === 0 : true,
8756
+ isReachEnd: (options === null || options === void 0 ? void 0 : options.totalPanelCount) && (options === null || options === void 0 ? void 0 : options.defaultIndex) ? options.defaultIndex === options.totalPanelCount - 1 : false,
8757
+ totalPanelCount: (_b = options === null || options === void 0 ? void 0 : options.totalPanelCount) !== null && _b !== void 0 ? _b : 0,
8758
+ currentPanelIndex: (_c = options === null || options === void 0 ? void 0 : options.defaultIndex) !== null && _c !== void 0 ? _c : 0,
8759
+ progress: 0,
8760
+ indexProgress: (_d = options === null || options === void 0 ? void 0 : options.defaultIndex) !== null && _d !== void 0 ? _d : 0,
8761
+ moveTo: moveTo
8762
+ });
8763
+ // Update state when panel changes
8764
+ var onChanged = function () {
8765
+ if (flicking === undefined) return;
8766
+ reactiveObj.isReachStart = getIsReachStart(flicking);
8767
+ reactiveObj.isReachEnd = getIsReachEnd(flicking);
8768
+ reactiveObj.currentPanelIndex = getCurrentPanelIndex(flicking);
8769
+ };
8770
+ // Update state when panel count changes
8771
+ var onPanelChange = function () {
8772
+ if (flicking === undefined) return;
8773
+ onChanged();
8774
+ reactiveObj.totalPanelCount = getTotalPanelCount(flicking);
8775
+ };
8776
+ // Update progress when camera moves
8777
+ var onMove = function () {
8778
+ if (flicking === undefined) return;
8779
+ reactiveObj.progress = getProgress(flicking);
8780
+ reactiveObj.indexProgress = getIndexProgress(flicking);
8781
+ };
8782
+ onInit(function (inst, data) {
8783
+ flicking = data.flicking;
8784
+ if (flicking === undefined) return;
8785
+ reactiveObj.isReachStart = getIsReachStart(flicking);
8786
+ reactiveObj.isReachEnd = getIsReachEnd(flicking);
8787
+ reactiveObj.currentPanelIndex = getCurrentPanelIndex(flicking);
8788
+ reactiveObj.progress = getProgress(flicking);
8789
+ reactiveObj.totalPanelCount = getTotalPanelCount(flicking);
8790
+ flicking === null || flicking === void 0 ? void 0 : flicking.on("changed", onChanged);
8791
+ flicking === null || flicking === void 0 ? void 0 : flicking.on("panelChange", onPanelChange);
8792
+ flicking === null || flicking === void 0 ? void 0 : flicking.on("move", onMove);
8793
+ });
8794
+ onDestroy(function () {
8795
+ flicking === null || flicking === void 0 ? void 0 : flicking.off("changed", onChanged);
8796
+ flicking === null || flicking === void 0 ? void 0 : flicking.off("panelChange", onPanelChange);
8797
+ flicking === null || flicking === void 0 ? void 0 : flicking.off("move", onMove);
8798
+ });
8799
+ return reactiveObj;
8800
+ };
8801
+ /**
8802
+ * Connect Flicking instance to reactive API
8803
+ * @ko Flicking 인스턴스를 반응형 API에 연결합니다
8804
+ * @param {Flicking} flicking - Flicking instance to connect<ko>연결할 Flicking 인스턴스</ko>
8805
+ * @param {FlickingReactiveAPIOptions} [options] - Flicking options<ko>Flicking 옵션</ko>
8806
+ * @returns {FlickingReactiveObject} Reactive object with Flicking state and methods<ko>Flicking 상태와 메서드를 포함한 반응형 객체</ko>
8807
+ * @example
8808
+ * ```js
8809
+ * import Flicking, { connectFlickingReactiveAPI } from "@egjs/flicking";
8810
+ *
8811
+ * const flicking = new Flicking("#el");
8812
+ * const reactiveObj = connectFlickingReactiveAPI(flicking);
8813
+ *
8814
+ * // Access reactive state
8815
+ * console.log("Current panel:", reactiveObj.currentPanelIndex);
8816
+ * console.log("Progress:", reactiveObj.progress + "%");
8817
+ * console.log("Is at start:", reactiveObj.isReachStart);
8818
+ * console.log("Is at end:", reactiveObj.isReachEnd);
8819
+ * console.log("Total panels:", reactiveObj.totalPanelCount);
8820
+ * console.log("Index progress:", reactiveObj.indexProgress);
8821
+ *
8822
+ * // Subscribe to state changes
8823
+ * reactiveObj.subscribe("currentPanelIndex", (nextValue) => {
8824
+ * console.log("Panel changed to:", nextValue);
8825
+ * });
8826
+ *
8827
+ * // Use reactive methods
8828
+ * reactiveObj.moveTo(2); // Move to third panel
8829
+ * ```
8830
+ */
8831
+ var connectFlickingReactiveAPI = function (flicking, options) {
8832
+ var obj = core.adaptReactive(flickingReactiveAPIAdapter, function () {
8833
+ return {
8834
+ flicking: flicking,
8835
+ options: options
8836
+ };
8837
+ });
8838
+ obj.mounted();
8839
+ var instance = obj.instance();
8840
+ obj.init();
8841
+ return instance;
8842
+ };
8843
+
8659
8844
  /*
8660
8845
  * Copyright (c) 2015 NAVER Corp.
8661
8846
  * egjs projects are licensed under the MIT license
@@ -8729,7 +8914,7 @@ var modules = {
8729
8914
  find: find,
8730
8915
  findRight: findRight,
8731
8916
  findIndex: findIndex,
8732
- getProgress: getProgress,
8917
+ getProgress: getProgress$1,
8733
8918
  getStyle: getStyle,
8734
8919
  setSize: setSize,
8735
8920
  isBetween: isBetween,
@@ -8738,7 +8923,9 @@ var modules = {
8738
8923
  getElementSize: getElementSize,
8739
8924
  setPrototypeOf: setPrototypeOf,
8740
8925
  camelize: camelize,
8741
- getDataAttributes: getDataAttributes
8926
+ getDataAttributes: getDataAttributes,
8927
+ flickingReactiveAPIAdapter: flickingReactiveAPIAdapter,
8928
+ connectFlickingReactiveAPI: connectFlickingReactiveAPI
8742
8929
  };
8743
8930
 
8744
8931
  /*
@@ -8795,10 +8982,12 @@ exports.checkExistence = checkExistence;
8795
8982
  exports.circulateIndex = circulateIndex;
8796
8983
  exports.circulatePosition = circulatePosition;
8797
8984
  exports.clamp = clamp;
8985
+ exports.connectFlickingReactiveAPI = connectFlickingReactiveAPI;
8798
8986
  exports["default"] = Flicking;
8799
8987
  exports.find = find;
8800
8988
  exports.findIndex = findIndex;
8801
8989
  exports.findRight = findRight;
8990
+ exports.flickingReactiveAPIAdapter = flickingReactiveAPIAdapter;
8802
8991
  exports.getDataAttributes = getDataAttributes;
8803
8992
  exports.getDefaultCameraTransform = getDefaultCameraTransform;
8804
8993
  exports.getDirection = getDirection;
@@ -8806,7 +8995,7 @@ exports.getElement = getElement;
8806
8995
  exports.getElementSize = getElementSize;
8807
8996
  exports.getFlickingAttached = getFlickingAttached;
8808
8997
  exports.getMinusCompensatedIndex = getMinusCompensatedIndex;
8809
- exports.getProgress = getProgress;
8998
+ exports.getProgress = getProgress$1;
8810
8999
  exports.getRenderingPanels = getRenderingPanels;
8811
9000
  exports.getStyle = getStyle;
8812
9001
  exports.includes = includes;