@egjs/flicking 4.3.1 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +1 -2
  2. package/declaration/Flicking.d.ts +30 -12
  3. package/declaration/camera/Camera.d.ts +29 -26
  4. package/declaration/camera/index.d.ts +2 -4
  5. package/declaration/camera/mode/BoundCameraMode.d.ts +13 -0
  6. package/declaration/camera/mode/CameraMode.d.ts +19 -0
  7. package/declaration/camera/mode/CircularCameraMode.d.ts +18 -0
  8. package/declaration/camera/mode/LinearCameraMode.d.ts +9 -0
  9. package/declaration/camera/mode/index.d.ts +6 -0
  10. package/declaration/const/error.d.ts +3 -1
  11. package/declaration/const/external.d.ts +9 -0
  12. package/declaration/core/AutoResizer.d.ts +13 -0
  13. package/declaration/core/VirtualManager.d.ts +37 -0
  14. package/declaration/core/index.d.ts +2 -1
  15. package/declaration/core/panel/Panel.d.ts +13 -7
  16. package/declaration/core/panel/VirtualPanel.d.ts +19 -0
  17. package/declaration/core/panel/index.d.ts +4 -4
  18. package/declaration/core/panel/provider/ElementProvider.d.ts +8 -0
  19. package/declaration/core/panel/provider/VanillaElementProvider.d.ts +12 -0
  20. package/declaration/core/panel/provider/VirtualElementProvider.d.ts +15 -0
  21. package/declaration/core/panel/provider/index.d.ts +5 -0
  22. package/declaration/index.d.ts +11 -1
  23. package/declaration/renderer/ExternalRenderer.d.ts +1 -1
  24. package/declaration/renderer/Renderer.d.ts +17 -12
  25. package/declaration/renderer/VanillaRenderer.d.ts +2 -7
  26. package/declaration/renderer/index.d.ts +1 -0
  27. package/declaration/renderer/strategy/NormalRenderingStrategy.d.ts +23 -0
  28. package/declaration/renderer/strategy/RenderingStrategy.d.ts +15 -0
  29. package/declaration/renderer/strategy/VirtualRenderingStrategy.d.ts +17 -0
  30. package/declaration/renderer/strategy/index.d.ts +5 -0
  31. package/declaration/type/external.d.ts +1 -3
  32. package/declaration/utils.d.ts +7 -1
  33. package/dist/flicking.esm.js +2526 -1475
  34. package/dist/flicking.esm.js.map +1 -1
  35. package/dist/flicking.js +2561 -1485
  36. package/dist/flicking.js.map +1 -1
  37. package/dist/flicking.min.js +2 -2
  38. package/dist/flicking.min.js.map +1 -1
  39. package/dist/flicking.pkgd.js +9006 -8312
  40. package/dist/flicking.pkgd.js.map +1 -1
  41. package/dist/flicking.pkgd.min.js +2 -2
  42. package/dist/flicking.pkgd.min.js.map +1 -1
  43. package/package.json +12 -24
  44. package/src/Flicking.ts +172 -45
  45. package/src/camera/Camera.ts +201 -93
  46. package/src/camera/index.ts +3 -7
  47. package/src/camera/{BoundCamera.ts → mode/BoundCameraMode.ts} +46 -43
  48. package/src/camera/mode/CameraMode.ts +77 -0
  49. package/src/camera/mode/CircularCameraMode.ts +171 -0
  50. package/src/camera/mode/LinearCameraMode.ts +23 -0
  51. package/src/camera/mode/index.ts +14 -0
  52. package/src/cfc/sync.ts +10 -5
  53. package/src/const/error.ts +6 -3
  54. package/src/const/external.ts +18 -0
  55. package/src/control/AxesController.ts +11 -6
  56. package/src/control/Control.ts +6 -6
  57. package/src/control/FreeControl.ts +2 -2
  58. package/src/control/SnapControl.ts +3 -3
  59. package/src/control/StrictControl.ts +2 -2
  60. package/src/core/AutoResizer.ts +81 -0
  61. package/src/core/Viewport.ts +4 -4
  62. package/src/core/VirtualManager.ts +188 -0
  63. package/src/core/index.ts +3 -1
  64. package/src/core/panel/Panel.ts +54 -34
  65. package/src/core/panel/VirtualPanel.ts +110 -0
  66. package/src/core/panel/index.ts +5 -7
  67. package/src/core/panel/provider/ElementProvider.ts +14 -0
  68. package/src/core/panel/provider/VanillaElementProvider.ts +45 -0
  69. package/src/core/panel/provider/VirtualElementProvider.ts +48 -0
  70. package/src/core/panel/provider/index.ts +16 -0
  71. package/src/index.ts +12 -1
  72. package/src/index.umd.ts +2 -0
  73. package/src/renderer/ExternalRenderer.ts +7 -7
  74. package/src/renderer/Renderer.ts +106 -65
  75. package/src/renderer/VanillaRenderer.ts +28 -86
  76. package/src/renderer/index.ts +2 -0
  77. package/src/renderer/strategy/NormalRenderingStrategy.ts +106 -0
  78. package/src/renderer/strategy/RenderingStrategy.ts +21 -0
  79. package/src/renderer/strategy/VirtualRenderingStrategy.ts +110 -0
  80. package/src/renderer/strategy/index.ts +17 -0
  81. package/src/utils.ts +36 -2
  82. package/declaration/camera/BoundCamera.d.ts +0 -9
  83. package/declaration/camera/CircularCamera.d.ts +0 -36
  84. package/declaration/camera/LinearCamera.d.ts +0 -5
  85. package/declaration/core/panel/ElementPanel.d.ts +0 -14
  86. package/declaration/core/panel/ExternalPanel.d.ts +0 -9
  87. package/declaration/exports.d.ts +0 -10
  88. package/src/camera/CircularCamera.ts +0 -269
  89. package/src/camera/LinearCamera.ts +0 -35
  90. package/src/core/panel/ElementPanel.ts +0 -52
  91. package/src/core/panel/ExternalPanel.ts +0 -32
  92. package/src/exports.ts +0 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@egjs/flicking",
3
- "version": "4.3.1",
3
+ "version": "4.5.0",
4
4
  "description": "Everyday 30 million people experience. It's reliable, flexible and extendable carousel.",
5
5
  "main": "dist/flicking.js",
6
6
  "module": "dist/flicking.esm.js",
@@ -13,16 +13,16 @@
13
13
  "declaration": "rm -rf declaration && tsc -p tsconfig.declaration.json",
14
14
  "css": "postcss css/*.css --use autoprefixer postcss-clean -d dist/ -m",
15
15
  "printsizes": "print-sizes ./dist --exclude=\\.map",
16
- "test": "karma start",
17
- "test:chrome": "karma start --chrome",
18
- "coverage": "karma start --coverage && print-coveralls --sort=desc",
16
+ "test": "npm run test --prefix test/unit",
17
+ "test:chrome": "npm run test:chrome --prefix test/unit",
18
+ "test:cfc": "npm run test --prefix test/cfc",
19
19
  "lint": "eslint 'src/**/*.ts'",
20
20
  "lint:test": "eslint 'test/unit/**/*.ts'",
21
21
  "jsdoc": "jsdoc -c jsdoc.json",
22
22
  "jsdoc:watch": "npm-watch jsdoc",
23
23
  "docs:build": "jsdoc-to-mdx -c ./jsdoc-to-mdx.json",
24
24
  "docs:version": "node ./config/docs-version-up",
25
- "docs:release": "npm run docs:build && npm run docs:version && cd docs && npm run build && cd ..",
25
+ "docs:release": "npm run docs:build && npm run docs:version && npm run build --prefix docs",
26
26
  "demo:prebuild-version": "cpx 'dist/**/*' docs/build/release/$npm_package_version/dist --clean",
27
27
  "demo:prebuild-latest": "cpx 'dist/**/*' docs/build/release/latest/dist --clean",
28
28
  "demo:deploy": "npm run docs:release && npm run build && npm run demo:prebuild-version && npm run demo:prebuild-latest && gh-pages -d docs/build/ --add --remote upstream",
@@ -69,26 +69,23 @@
69
69
  "egjs"
70
70
  ],
71
71
  "devDependencies": {
72
+ "@babel/preset-env": "^7.16.0",
72
73
  "@daybrush/jsdoc": "^0.3.10",
73
- "@egjs/flicking-plugins": "^4.0.0-beta.1",
74
+ "@egjs/flicking-plugins": "^4.2.2",
74
75
  "@egjs/release-helper": "0.0.3",
75
76
  "@rollup/plugin-babel": "^5.3.0",
76
77
  "@rollup/plugin-commonjs": "^11.1.0",
77
78
  "@rollup/plugin-node-resolve": "^7.1.3",
78
79
  "@rollup/plugin-replace": "^2.4.1",
79
- "@types/chai": "^4.2.15",
80
80
  "@types/fs-extra": "^9.0.11",
81
- "@types/karma-chai": "^0.1.1",
82
- "@types/mocha": "^5.2.5",
83
81
  "@types/node": "^14.14.35",
84
- "@types/sinon": "^7.0.3",
82
+ "@types/resize-observer-browser": "^0.1.6",
85
83
  "@typescript-eslint/eslint-plugin": "^4.18.0",
86
84
  "@typescript-eslint/eslint-plugin-tslint": "^4.18.0",
87
85
  "@typescript-eslint/parser": "^4.18.0",
88
86
  "autoprefixer": "^9.8.5",
89
87
  "babel-loader": "^8.2.2",
90
- "chai": "^4.3.4",
91
- "chalk": "^2.4.2",
88
+ "babel-preset-env": "^1.7.0",
92
89
  "concurrently": "^6.0.0",
93
90
  "core-js": "^3.9.1",
94
91
  "coveralls": "^3.0.2",
@@ -105,15 +102,7 @@
105
102
  "http-serve": "^1.0.1",
106
103
  "husky": "^1.3.1",
107
104
  "jsdoc-to-mdx": "^1.0.5",
108
- "karma": "^3.1.4",
109
- "karma-chai": "^0.1.0",
110
- "karma-chrome-launcher": "^2.2.0",
111
- "karma-mocha": "^1.3.0",
112
- "karma-mocha-reporter": "^2.2.5",
113
- "karma-sinon": "^1.0.5",
114
- "karma-typescript-egjs": "^4.0.0",
115
- "karma-viewport": "^1.0.8",
116
- "mocha": "^5.2.0",
105
+ "karma-typescript-es6-transform": "^5.5.2",
117
106
  "postcss-clean": "^1.2.2",
118
107
  "postcss-cli": "^7.1.1",
119
108
  "print-coveralls": "^1.2.2",
@@ -124,17 +113,16 @@
124
113
  "rollup-plugin-postcss": "^3.1.3",
125
114
  "rollup-plugin-prototype-minify": "^1.1.0",
126
115
  "rollup-plugin-serve": "^1.1.0",
116
+ "rollup-plugin-terser": "^7.0.2",
127
117
  "rollup-plugin-typescript2": "^0.30.0",
128
- "rollup-plugin-uglify": "^6.0.4",
129
118
  "rollup-plugin-visualizer": "^4.2.1",
130
- "sinon": "^7.2.3",
131
119
  "sync-exec": "^0.6.2",
132
120
  "ts-mock-imports": "^1.3.3",
133
121
  "tsconfig-paths-webpack-plugin": "^3.5.1",
134
122
  "tslib": "^2.1.0",
135
123
  "tslint": "^5.12.1",
136
124
  "ttypescript": "^1.5.12",
137
- "typescript": "^4.2.3",
125
+ "typescript": "^3.9.10",
138
126
  "typescript-transform-paths": "^2.2.3"
139
127
  },
140
128
  "dependencies": {
package/src/Flicking.ts CHANGED
@@ -6,11 +6,14 @@ import Component, { ComponentEvent } from "@egjs/component";
6
6
 
7
7
  import FlickingError from "./core/FlickingError";
8
8
  import Viewport from "./core/Viewport";
9
+ import AutoResizer from "./core/AutoResizer";
9
10
  import { Panel } from "./core/panel";
11
+ import { VanillaElementProvider } from "./core/panel/provider";
12
+ import VirtualManager, { VirtualOptions } from "./core/VirtualManager";
10
13
  import { Control, SnapControl, SnapControlOptions, FreeControl, StrictControl, FreeControlOptions, StrictControlOptions } from "./control";
11
- import { BoundCamera, Camera, CircularCamera, LinearCamera } from "./camera";
12
- import { Renderer, VanillaRenderer, ExternalRenderer } from "./renderer";
13
- import { EVENTS, ALIGN, MOVE_TYPE, DIRECTION } from "./const/external";
14
+ import { Camera } from "./camera";
15
+ import { Renderer, VanillaRenderer, ExternalRenderer, RendererOptions, NormalRenderingStrategy, VirtualRenderingStrategy } from "./renderer";
16
+ import { EVENTS, ALIGN, MOVE_TYPE, DIRECTION, CIRCULAR_FALLBACK } from "./const/external";
14
17
  import * as ERROR from "./const/error";
15
18
  import { findIndex, getElement, includes, parseElement } from "./utils";
16
19
  import { HoldStartEvent, HoldEndEvent, MoveStartEvent, SelectEvent, MoveEvent, MoveEndEvent, WillChangeEvent, WillRestoreEvent, NeedPanelEvent, VisibleChangeEvent, ReachEdgeEvent, ReadyEvent, AfterResizeEvent, BeforeResizeEvent, ChangedEvent, RestoredEvent, PanelChangeEvent } from "./type/event";
@@ -49,6 +52,7 @@ export interface FlickingOptions {
49
52
  defaultIndex: number;
50
53
  horizontal: boolean;
51
54
  circular: boolean;
55
+ circularFallback: LiteralUnion<ValueOf<typeof CIRCULAR_FALLBACK>>;
52
56
  bound: boolean;
53
57
  adaptive: boolean;
54
58
  panelsPerView: number;
@@ -72,12 +76,16 @@ export interface FlickingOptions {
72
76
  disableOnInit: boolean;
73
77
  // PERFORMANCE
74
78
  renderOnlyVisible: boolean;
79
+ virtual: VirtualOptions | null;
75
80
  // OTHERS
76
81
  autoInit: boolean;
77
82
  autoResize: boolean;
83
+ useResizeObserver: boolean;
84
+ externalRenderer: ExternalRenderer | null;
85
+ // @deprecated
78
86
  renderExternal: {
79
- renderer: typeof ExternalRenderer;
80
- rendererOptions: {[key: string]: any};
87
+ renderer: new (options: RendererOptions) => ExternalRenderer;
88
+ rendererOptions: RendererOptions;
81
89
  } | null;
82
90
  }
83
91
 
@@ -102,20 +110,24 @@ class Flicking extends Component<FlickingEvents> {
102
110
 
103
111
  // Core components
104
112
  private _viewport: Viewport;
113
+ private _autoResizer: AutoResizer;
105
114
  private _camera: Camera;
106
115
  private _control: Control;
107
116
  private _renderer: Renderer;
117
+ private _virtualManager: VirtualManager;
108
118
 
109
119
  // Options
110
120
  private _align: FlickingOptions["align"];
111
121
  private _defaultIndex: FlickingOptions["defaultIndex"];
112
122
  private _horizontal: FlickingOptions["horizontal"];
113
123
  private _circular: FlickingOptions["circular"];
124
+ private _circularFallback: FlickingOptions["circularFallback"];
114
125
  private _bound: FlickingOptions["bound"];
115
126
  private _adaptive: FlickingOptions["adaptive"];
116
127
  private _panelsPerView: FlickingOptions["panelsPerView"];
117
128
  private _noPanelStyleOverride: FlickingOptions["noPanelStyleOverride"];
118
129
  private _resizeOnContentsReady: FlickingOptions["resizeOnContentsReady"];
130
+ private _virtual: FlickingOptions["virtual"];
119
131
 
120
132
  private _needPanelThreshold: FlickingOptions["needPanelThreshold"];
121
133
  private _preventEventsBeforeInit: FlickingOptions["preventEventsBeforeInit"];
@@ -135,8 +147,10 @@ class Flicking extends Component<FlickingEvents> {
135
147
 
136
148
  private _renderOnlyVisible: FlickingOptions["renderOnlyVisible"];
137
149
 
138
- private _autoResize: FlickingOptions["autoResize"];
139
150
  private _autoInit: FlickingOptions["autoInit"];
151
+ private _autoResize: FlickingOptions["autoResize"];
152
+ private _useResizeObserver: FlickingOptions["useResizeObserver"];
153
+ private _externalRenderer: FlickingOptions["externalRenderer"];
140
154
  private _renderExternal: FlickingOptions["renderExternal"];
141
155
 
142
156
  // Internal State
@@ -206,7 +220,17 @@ class Flicking extends Component<FlickingEvents> {
206
220
  * @default false
207
221
  * @readonly
208
222
  */
209
- public get circularEnabled() { return this._camera.controlParams.circular; }
223
+ public get circularEnabled() { return this._camera.circularEnabled; }
224
+ /**
225
+ * Whether the `virtual` option is enabled.
226
+ * The {@link Flicking#virtual virtual} option can't be enabled when {@link Flicking#panelsPerView panelsPerView} is less or equal than zero.
227
+ * @ko {@link Flicking#virtual virtual} 옵션이 활성화되었는지 여부를 나타내는 멤버 변수.
228
+ * {@link Flicking#virtual virtual} 옵션은 {@link Flicking#panelsPerView panelsPerView} 옵션의 값이 0보다 같거나 작으면 비활성화됩니다.
229
+ * @type {boolean}
230
+ * @default false
231
+ * @readonly
232
+ */
233
+ public get virtualEnabled() { return this._panelsPerView > 0 && this._virtual != null; }
210
234
  /**
211
235
  * Index number of the {@link Flicking#currentPanel currentPanel}
212
236
  * @ko {@link Flicking#currentPanel currentPanel}의 인덱스 번호
@@ -326,6 +350,18 @@ class Flicking extends Component<FlickingEvents> {
326
350
  * @default false
327
351
  */
328
352
  public get circular() { return this._circular; }
353
+ /**
354
+ * Set panel control mode for the case when circular cannot be enabled.
355
+ * "linear" will set the view's range from the top of the first panel to the top of the last panel.
356
+ * "bound" will prevent the view from going out of the first/last panel, so it won't show empty spaces before/after the first/last panel.
357
+ * @ko 순환 모드 사용 불가능시 사용할 패널 조작 범위 설정 방식을 변경합니다.
358
+ * "linear" 사용시 시점이 첫번째 엘리먼트 위에서부터 마지막 엘리먼트 위까지 움직일 수 있도록 설정합니다.
359
+ * "bound" 사용시 시점이 첫번째 엘리먼트와 마지막 엘리먼트의 끝과 끝 사이에서 움직일 수 있도록 설정합니다.
360
+ * @see CIRCULAR_FALLBACK
361
+ * @type {string}
362
+ * @default "linear"
363
+ */
364
+ public get circularFallback() { return this._circularFallback; }
329
365
  /**
330
366
  * Prevent the view(camera element) from going out of the first/last panel, so it won't show empty spaces before/after the first/last panel
331
367
  * Only can be enabled when `circular=false`
@@ -515,12 +551,45 @@ class Flicking extends Component<FlickingEvents> {
515
551
  public get disableOnInit() { return this._disableOnInit; }
516
552
  // PERFORMANCE
517
553
  /**
518
- * Whether to render visible panels only. This can dramatically increase performance when there're many panels.
519
- * @ko 보이는 패널만 렌더링할지 여부를 설정합니다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있습니다.
554
+ * Whether to render visible panels only. This can dramatically increase performance when there're many panels
555
+ * @ko 보이는 패널만 렌더링할지 여부를 설정합니다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있습니다
520
556
  * @type {boolean}
521
557
  * @default false
522
558
  */
523
559
  public get renderOnlyVisible() { return this._renderOnlyVisible; }
560
+ /**
561
+ * By enabling this option, it will reduce memory consumption by restricting the number of DOM elements to `panelsPerView + 1`
562
+ * Must be used with `panelsPerview`.
563
+ * After Flicking's initialized, this property can be used to add/remove the panel count.
564
+ * @ko 이 옵션을 활성화할 경우 패널 엘리먼트의 개수를 `panelsPerView + 1` 개로 고정함으로써, 메모리 사용량을 줄일 수 있습니다.
565
+ * `panelsPerView` 옵션과 함께 사용되어야만 합니다.
566
+ * Flicking 초기화 이후에, 이 프로퍼티는 렌더링하는 패널의 개수를 추가/제거하기 위해 사용될 수 있습니다.
567
+ * @type {VirtualManager}
568
+ * @property {function} renderPanel A rendering function for the panel element's innerHTML<ko>패널 엘리먼트의 innerHTML을 렌더링하는 함수</ko>
569
+ * @property {number} initialPanelCount Initial panel count to render<ko>최초로 렌더링할 패널의 개수</ko>
570
+ * @property {boolean} [cache=false] Whether to cache rendered panel's innerHTML<ko>렌더링된 패널의 innerHTML 정보를 캐시할지 여부</ko>
571
+ * @property {string} [panelClass="flicking-panel"] The class name that will be applied to rendered panel elements<ko>렌더링되는 패널 엘리먼트에 적용될 클래스 이름</ko>
572
+ * @example
573
+ * ```ts
574
+ * import Flicking, { VirtualPanel } from "@egjs/flicking";
575
+ *
576
+ * const flicking = new Flicking("#some_el", {
577
+ * panelsPerView: 3,
578
+ * virtual: {
579
+ * renderPanel: (panel: VirtualPanel, index: number) => `Panel ${index}`,
580
+ * initialPanelCount: 100
581
+ * }
582
+ * });
583
+ *
584
+ * // Add 100 virtual panels (at the end)
585
+ * flicking.virtual.append(100);
586
+ *
587
+ * // Remove 100 virtual panels from 0 to 100
588
+ * flicking.virtual.remove(0, 100);
589
+ * ```
590
+ */
591
+ public get virtual() { return this._virtualManager; }
592
+
524
593
  // OTHERS
525
594
  /**
526
595
  * Call {@link Flicking#init init()} automatically when creating Flicking's instance
@@ -531,22 +600,35 @@ class Flicking extends Component<FlickingEvents> {
531
600
  */
532
601
  public get autoInit() { return this._autoInit; }
533
602
  /**
534
- * Attach Flicking's {@link Flicking#resize resize} method to window's resize event.
535
- * Flicking will automatically call {@link Flicking#resize resize} window size and orientation change.
536
- * @ko Flicking의 {@link Flicking#resize resize} 메소드를 window의 resize 이벤트 핸들러로 등록합니다.
537
- * 설정시 window 창 크기 및 orientation 변경에 의해 자동으로 {@link Flicking#resize resize}를 호출합니다.
603
+ * Whether to automatically call {@link Flicking#resize resize()} when the viewport element(.flicking-viewport)'s size is changed
604
+ * @ko 뷰포트 엘리먼트(.flicking-viewport)의 크기 변경시 {@link Flicking#resize resize()} 메소드를 자동으로 호출할지 여부를 설정합니다
538
605
  * @type {boolean}
539
606
  * @default true
540
607
  */
541
608
  public get autoResize() { return this._autoResize; }
609
+ /**
610
+ * Whether to listen {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}'s event instead of Window's {@link https://developer.mozilla.org/ko/docs/Web/API/Window/resize_event resize} event when using the `autoResize` option
611
+ * @ko autoResize 옵션 사용시 {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ResizeObserver}의 이벤트를 Window객체의 {@link https://developer.mozilla.org/ko/docs/Web/API/Window/resize_event resize} 이벤트 대신 수신할지 여부를 설정합니다
612
+ * @type {boolean}
613
+ * @default true
614
+ */
615
+ public get useResizeObserver() { return this._useResizeObserver; }
542
616
  /**
543
617
  * This is an option for the frameworks(React, Vue, Angular, ...). Don't set it as it's automatically managed by Flicking.
544
618
  * @ko 프레임워크(React, Vue, Angular, ...)에서만 사용하는 옵션으로, 자동으로 설정되므로 따로 사용하실 필요 없습니다!
545
- * @type {boolean}
546
- * @default false
619
+ * @default null
547
620
  * @internal
548
621
  * @readonly
549
622
  */
623
+ public get externalRenderer() { return this._externalRenderer; }
624
+ /**
625
+ * This is an option for the frameworks(React, Vue, Angular, ...). Don't set it as it's automatically managed by Flicking.
626
+ * @ko 프레임워크(React, Vue, Angular, ...)에서만 사용하는 옵션으로, 자동으로 설정되므로 따로 사용하실 필요 없습니다!
627
+ * @default null
628
+ * @internal
629
+ * @readonly
630
+ * @deprecated
631
+ */
550
632
  public get renderExternal() { return this._renderExternal; }
551
633
 
552
634
  // Options Setter
@@ -599,7 +681,23 @@ class Flicking extends Component<FlickingEvents> {
599
681
  // PERFORMANCE
600
682
  public set renderOnlyVisible(val: FlickingOptions["renderOnlyVisible"]) { this._renderOnlyVisible = val; }
601
683
  // OTHERS
602
- public set autoResize(val: FlickingOptions["autoResize"]) { this._autoResize = val; }
684
+ public set autoResize(val: FlickingOptions["autoResize"]) {
685
+ this._autoResize = val;
686
+
687
+ if (val) {
688
+ this._autoResizer.enable();
689
+ } else {
690
+ this._autoResizer.disable();
691
+ }
692
+ }
693
+
694
+ public set useResizeObserver(val: FlickingOptions["useResizeObserver"]) {
695
+ this._useResizeObserver = val;
696
+
697
+ if (this._autoResize) {
698
+ this._autoResizer.enable();
699
+ }
700
+ }
603
701
 
604
702
  /**
605
703
  * @param root A root HTMLElement to initialize Flicking on it. When it's a typeof `string`, it should be a css selector string
@@ -634,6 +732,7 @@ class Flicking extends Component<FlickingEvents> {
634
732
  defaultIndex = 0,
635
733
  horizontal = true,
636
734
  circular = false,
735
+ circularFallback = CIRCULAR_FALLBACK.LINEAR,
637
736
  bound = false,
638
737
  adaptive = false,
639
738
  panelsPerView = -1,
@@ -653,8 +752,11 @@ class Flicking extends Component<FlickingEvents> {
653
752
  preventClickOnDrag = true,
654
753
  disableOnInit = false,
655
754
  renderOnlyVisible = false,
755
+ virtual = null,
656
756
  autoInit = true,
657
757
  autoResize = true,
758
+ useResizeObserver = true,
759
+ externalRenderer = null,
658
760
  renderExternal = null
659
761
  }: Partial<FlickingOptions> = {}) {
660
762
  super();
@@ -668,11 +770,13 @@ class Flicking extends Component<FlickingEvents> {
668
770
  this._defaultIndex = defaultIndex;
669
771
  this._horizontal = horizontal;
670
772
  this._circular = circular;
773
+ this._circularFallback = circularFallback;
671
774
  this._bound = bound;
672
775
  this._adaptive = adaptive;
673
776
  this._panelsPerView = panelsPerView;
674
777
  this._noPanelStyleOverride = noPanelStyleOverride;
675
778
  this._resizeOnContentsReady = resizeOnContentsReady;
779
+ this._virtual = virtual;
676
780
  this._needPanelThreshold = needPanelThreshold;
677
781
  this._preventEventsBeforeInit = preventEventsBeforeInit;
678
782
  this._deceleration = deceleration;
@@ -687,17 +791,19 @@ class Flicking extends Component<FlickingEvents> {
687
791
  this._preventClickOnDrag = preventClickOnDrag;
688
792
  this._disableOnInit = disableOnInit;
689
793
  this._renderOnlyVisible = renderOnlyVisible;
690
- this._autoResize = autoResize;
691
794
  this._autoInit = autoInit;
795
+ this._autoResize = autoResize;
796
+ this._useResizeObserver = useResizeObserver;
797
+ this._externalRenderer = externalRenderer;
692
798
  this._renderExternal = renderExternal;
693
799
 
694
800
  // Create core components
695
801
  this._viewport = new Viewport(getElement(root));
802
+ this._autoResizer = new AutoResizer(this);
696
803
  this._renderer = this._createRenderer();
697
804
  this._camera = this._createCamera();
698
805
  this._control = this._createControl();
699
-
700
- this.resize = this.resize.bind(this);
806
+ this._virtualManager = new VirtualManager(this, virtual);
701
807
 
702
808
  if (this._autoInit) {
703
809
  void this.init();
@@ -718,10 +824,12 @@ class Flicking extends Component<FlickingEvents> {
718
824
  const camera = this._camera;
719
825
  const renderer = this._renderer;
720
826
  const control = this._control;
827
+ const virtualManager = this._virtualManager;
721
828
  const originalTrigger = this.trigger;
722
829
  const preventEventsBeforeInit = this._preventEventsBeforeInit;
723
830
 
724
831
  camera.init(this);
832
+ virtualManager.init();
725
833
  renderer.init(this);
726
834
  control.init(this);
727
835
 
@@ -735,7 +843,7 @@ class Flicking extends Component<FlickingEvents> {
735
843
  await this._moveToInitialPanel();
736
844
 
737
845
  if (this._autoResize) {
738
- window.addEventListener("resize", this.resize);
846
+ this._autoResizer.enable();
739
847
  }
740
848
  if (this._preventClickOnDrag) {
741
849
  control.controller.addPreventClickHandler();
@@ -764,8 +872,8 @@ class Flicking extends Component<FlickingEvents> {
764
872
  */
765
873
  public destroy(): void {
766
874
  this.off();
767
- window.removeEventListener("resize", this.resize);
768
875
 
876
+ this._autoResizer.disable();
769
877
  this._control.destroy();
770
878
  this._camera.destroy();
771
879
  this._renderer.destroy();
@@ -951,7 +1059,7 @@ class Flicking extends Component<FlickingEvents> {
951
1059
  * @param {boolean} [options.includePanelHTML=false] Include panel's `outerHTML` to the returning status<ko>패널의 `outerHTML`을 반환값에 포함시킵니다</ko>
952
1060
  * @param {boolean} [options.visiblePanelsOnly=false] Include only {@link Flicking#visiblePanel visiblePanel}'s HTML. This option is available only when the `includePanelHTML` is true
953
1061
  * <ko>현재 보이는 패널({@link Flicking#visiblePanel visiblePanel})의 HTML만 반환합니다. `includePanelHTML`이 `true`일 경우에만 동작합니다.</ko>
954
- * @return {Partial<Status>} An object with current status value information<ko>현재 상태값 정보를 가진 객체.</ko>
1062
+ * @return {Status} An object with current status value information<ko>현재 상태값 정보를 가진 객체.</ko>
955
1063
  */
956
1064
  public getStatus({
957
1065
  index = true,
@@ -1026,8 +1134,8 @@ class Flicking extends Component<FlickingEvents> {
1026
1134
 
1027
1135
  // Can't add/remove panels on external rendering
1028
1136
  if (panels[0]?.html && !this._renderExternal) {
1029
- renderer.batchRemove({ index: 0, deleteCount: this.panels.length });
1030
- renderer.batchInsert({ index: 0, elements: parseElement(panels.map(panel => panel.html!)) });
1137
+ renderer.batchRemove({ index: 0, deleteCount: this.panels.length, hasDOMInElements: true });
1138
+ renderer.batchInsert({ index: 0, elements: parseElement(panels.map(panel => panel.html!)), hasDOMInElements: true });
1031
1139
  }
1032
1140
 
1033
1141
  if (index) {
@@ -1219,7 +1327,7 @@ class Flicking extends Component<FlickingEvents> {
1219
1327
  throw new FlickingError(ERROR.MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, ERROR.CODE.NOT_ALLOWED_IN_FRAMEWORK);
1220
1328
  }
1221
1329
 
1222
- return this._renderer.batchInsert({ index, elements: parseElement(element) });
1330
+ return this._renderer.batchInsert({ index, elements: parseElement(element), hasDOMInElements: true });
1223
1331
  }
1224
1332
 
1225
1333
  /**
@@ -1236,7 +1344,7 @@ class Flicking extends Component<FlickingEvents> {
1236
1344
  throw new FlickingError(ERROR.MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, ERROR.CODE.NOT_ALLOWED_IN_FRAMEWORK);
1237
1345
  }
1238
1346
 
1239
- return this._renderer.batchRemove({ index, deleteCount });
1347
+ return this._renderer.batchRemove({ index, deleteCount, hasDOMInElements: true });
1240
1348
  }
1241
1349
 
1242
1350
  private _createControl(): Control {
@@ -1266,31 +1374,50 @@ class Flicking extends Component<FlickingEvents> {
1266
1374
  }
1267
1375
 
1268
1376
  private _createCamera(): Camera {
1269
- const cameraOption = { align: this._align };
1270
-
1271
- if (this._circular) {
1272
- if (this._bound) {
1273
- // eslint-disable-next-line no-console
1274
- console.warn("\"circular\" and \"bound\" option cannot be used together, ignoring bound.");
1275
- }
1276
- return new CircularCamera(cameraOption);
1277
- } else if (this._bound) {
1278
- return new BoundCamera(cameraOption);
1279
- } else {
1280
- return new LinearCamera(cameraOption);
1377
+ if (this._circular && this._bound) {
1378
+ // eslint-disable-next-line no-console
1379
+ console.warn("\"circular\" and \"bound\" option cannot be used together, ignoring bound.");
1281
1380
  }
1381
+
1382
+ return new Camera({
1383
+ align: this._align
1384
+ });
1282
1385
  }
1283
1386
 
1284
1387
  private _createRenderer(): Renderer {
1285
- const rendererOptions = {
1286
- align: this._align
1287
- };
1388
+ const externalRenderer = this._externalRenderer;
1389
+ if (this._virtual && this._panelsPerView <= 0) {
1390
+ // eslint-disable-next-line no-console
1391
+ console.warn("\"virtual\" and \"panelsPerView\" option should be used together, ignoring virtual.");
1392
+ }
1288
1393
 
1289
- const renderExternal = this._renderExternal;
1394
+ return externalRenderer
1395
+ ? externalRenderer
1396
+ : this._renderExternal
1397
+ ? this._createExternalRenderer()
1398
+ : this._createVanillaRenderer();
1399
+ }
1400
+
1401
+ private _createExternalRenderer(): ExternalRenderer {
1402
+ const {
1403
+ renderer,
1404
+ rendererOptions
1405
+ } = this._renderExternal!;
1290
1406
 
1291
- return renderExternal
1292
- ? new (renderExternal.renderer as any)({ ...rendererOptions, ...renderExternal.rendererOptions })
1293
- : new VanillaRenderer(rendererOptions);
1407
+ return new (renderer)({ align: this._align, ...rendererOptions });
1408
+ }
1409
+
1410
+ private _createVanillaRenderer(): VanillaRenderer {
1411
+ const virtual = this.virtualEnabled;
1412
+
1413
+ return new VanillaRenderer({
1414
+ align: this._align,
1415
+ strategy: virtual
1416
+ ? new VirtualRenderingStrategy()
1417
+ : new NormalRenderingStrategy({
1418
+ providerCtor: VanillaElementProvider
1419
+ })
1420
+ });
1294
1421
  }
1295
1422
 
1296
1423
  private async _moveToInitialPanel(): Promise<void> {