@egjs/flicking 4.12.0-beta.2 → 4.12.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@egjs/flicking",
3
- "version": "4.12.0-beta.2",
3
+ "version": "4.12.0-beta.3",
4
4
  "description": "Everyday 30 million people experience. It's reliable, flexible and extendable carousel.",
5
5
  "main": "dist/flicking.cjs.js",
6
6
  "module": "dist/flicking.esm.js",
@@ -7,7 +7,7 @@ import Flicking, { FlickingOptions } from "./Flicking";
7
7
  import { ChangedEvent, MoveEndEvent, MoveEvent } from "./type/event";
8
8
  import { LiteralUnion, ValueOf } from "./type/internal";
9
9
  import { CLASS, EVENTS, MOVE_DIRECTION } from "./const/external";
10
- import { getElement, toArray } from "./utils";
10
+ import { getDataAttributes, getElement, includes, toArray } from "./utils";
11
11
 
12
12
  /**
13
13
  * @interface
@@ -40,6 +40,7 @@ export interface CrossFlickingOptions {
40
40
  * @property {string | undefined} [panels.html] An `outerHTML` of the panel element<ko>패널 엘리먼트의 `outerHTML`</ko>
41
41
  */
42
42
  export interface VerticalState {
43
+ key: string;
43
44
  start: number;
44
45
  end: number;
45
46
  element: HTMLElement;
@@ -74,7 +75,10 @@ export class CrossFlicking extends Flicking {
74
75
  * @see SnapControl
75
76
  * @see FreeControl
76
77
  */
77
- public get verticalFlicking() { return this._verticalFlicking; }
78
+ public get verticalFlicking() {
79
+ return this._verticalFlicking;
80
+ }
81
+
78
82
  // Internal States
79
83
  /**
80
84
  * Whether Flicking's {@link Flicking#init init()} is called.
@@ -85,7 +89,10 @@ export class CrossFlicking extends Flicking {
85
89
  * @default false
86
90
  * @readonly
87
91
  */
88
- public get verticalState() { return this._verticalState; }
92
+ public get verticalState() {
93
+ return this._verticalState;
94
+ }
95
+
89
96
  // Options Getter
90
97
  /**
91
98
  * Change active panel index on mouse/touch hold while animating.
@@ -111,10 +118,8 @@ export class CrossFlicking extends Flicking {
111
118
  ) {
112
119
  super(root);
113
120
 
114
- const horizontalPanels = toArray(getElement(root).children[0].children) as HTMLElement[];
115
-
116
121
  // Internal states
117
- this._verticalState = this._createVerticalState(horizontalPanels);
122
+ this._verticalState = this._createVerticalState();
118
123
  this._moveDirection = null;
119
124
  this._nextIndex = 0;
120
125
 
@@ -122,7 +127,7 @@ export class CrossFlicking extends Flicking {
122
127
  this._verticalOptions = verticalOptions;
123
128
 
124
129
  // Create core components
125
- this._verticalFlicking = this._createVerticalFlicking(horizontalPanels);
130
+ this._verticalFlicking = this._createVerticalFlicking();
126
131
  }
127
132
 
128
133
  /**
@@ -150,50 +155,105 @@ export class CrossFlicking extends Flicking {
150
155
  });
151
156
  }
152
157
 
153
- private _createVerticalState(panels: HTMLElement[]): VerticalState[] {
158
+ private _createVerticalState(): VerticalState[] {
154
159
  // data-index로 분류하기 전에 임시로 모든 children에 대해 vertical flicking으로 해보자.
155
160
  // panels에 data-attributes가 붙어있을 때와 안 붙어있을 때를 다르게 처리
156
161
  // 붙어있다면 가상의 viewport들을 index 갯수만큼 만들어줘야 한다
157
- let verticalPanels = "";
158
-
159
- const verticalState = panels.reduce(
160
- (state: VerticalState[], panel: HTMLElement) => {
161
- const start = state.length ? +state[state.length - 1].end + 1 : 0;
162
- verticalPanels += panel.innerHTML;
163
- return [
164
- ...state,
165
- {
166
- start,
167
- end: start + panel.children.length - 1,
168
- element: panel
169
- }
170
- ];
171
- },
172
- []
173
- );
174
-
162
+ const cameraEl = this.camera.element;
163
+ const panels = toArray(cameraEl.children) as HTMLElement[];
164
+ let verticalState: VerticalState[];
165
+ let verticalPanels: string = "";
166
+
167
+ // check data attribute exists
168
+ const groupKeys: string[] = [];
169
+ const groupPanels: Record<string, HTMLElement[]> = {};
175
170
  const verticalCamera = document.createElement("div");
176
171
  verticalCamera.classList.add(CLASS.CAMERA);
177
- verticalCamera.innerHTML = verticalPanels;
172
+
178
173
  panels.forEach((panel) => {
179
- [CLASS.VIEWPORT, CLASS.VERTICAL].forEach((className) => {
180
- if (!panel.classList.contains(className)) {
181
- panel.classList.add(className);
182
- }
183
- });
184
- panel.innerHTML = verticalCamera.outerHTML;
174
+ const groupKey = getDataAttributes(panel, "data-flicking-").groupkey;
175
+ if (groupKey && !includes(groupKeys, groupKey)) {
176
+ groupKeys.push(groupKey);
177
+ groupPanels[groupKey] = [panel];
178
+ } else if (groupKey) {
179
+ groupPanels[groupKey].push(panel);
180
+ }
181
+ return groupKey;
185
182
  });
186
183
 
184
+ if (groupKeys.length) {
185
+ panels.forEach(() => this.remove(0));
186
+ verticalState = groupKeys.reduce(
187
+ (state: VerticalState[], key: string) => {
188
+ const start = state.length ? +state[state.length - 1].end + 1 : 0;
189
+ const element = groupPanels[key].reduce(
190
+ (el: HTMLElement, panel: HTMLElement) => {
191
+ verticalPanels += panel.outerHTML;
192
+ el.appendChild(panel);
193
+ return el;
194
+ },
195
+ document.createElement("div")
196
+ );
197
+ return [
198
+ ...state,
199
+ {
200
+ key,
201
+ start,
202
+ end: start + groupPanels[key].length - 1,
203
+ element: element,
204
+ },
205
+ ];
206
+ },
207
+ []
208
+ );
209
+
210
+ verticalCamera.innerHTML = verticalPanels;
211
+ cameraEl.innerHTML = "";
212
+ groupKeys.forEach(() => {
213
+ const panel = document.createElement("div");
214
+ panel.classList.add(CLASS.VIEWPORT, CLASS.VERTICAL);
215
+ panel.innerHTML = verticalCamera.outerHTML;
216
+ this.append(panel);
217
+ });
218
+ } else {
219
+ verticalState = panels.reduce(
220
+ (state: VerticalState[], panel: HTMLElement, i: number) => {
221
+ const start = state.length ? +state[state.length - 1].end + 1 : 0;
222
+ verticalPanels += panel.innerHTML;
223
+ return [
224
+ ...state,
225
+ {
226
+ key: i.toString(),
227
+ start,
228
+ end: start + panel.children.length - 1,
229
+ element: panel,
230
+ },
231
+ ];
232
+ },
233
+ []
234
+ );
235
+
236
+ verticalCamera.innerHTML = verticalPanels;
237
+ panels.forEach((panel) => {
238
+ [CLASS.VIEWPORT, CLASS.VERTICAL].forEach((className) => {
239
+ if (!panel.classList.contains(className)) {
240
+ panel.classList.add(className);
241
+ }
242
+ });
243
+ panel.innerHTML = verticalCamera.outerHTML;
244
+ });
245
+ }
246
+
187
247
  return verticalState;
188
248
  }
189
249
 
190
- private _createVerticalFlicking(panels: HTMLElement[]): Flicking[] {
191
- return panels.map((panel, i) => {
250
+ private _createVerticalFlicking(): Flicking[] {
251
+ return this.camera.children.map((panel, i) => {
192
252
  return new Flicking(panel, {
193
253
  ...this.verticalOptions,
194
254
  horizontal: false,
195
255
  panelsPerView: 1,
196
- defaultIndex: this._verticalState[i].start
256
+ defaultIndex: this._verticalState[i].start,
197
257
  });
198
258
  });
199
259
  }
package/src/utils.ts CHANGED
@@ -349,3 +349,24 @@ export const setPrototypeOf = Object.setPrototypeOf || ((obj, proto) => {
349
349
  obj.__proto__ = proto;
350
350
  return obj;
351
351
  });
352
+
353
+ export const camelize = (str: string): string => {
354
+ return str.replace(/[\s-_]([a-z])/g, (all, letter) => letter.toUpperCase());
355
+ };
356
+
357
+ export const getDataAttributes = (element: HTMLElement, attributePrefix: string): Record<string, string> => {
358
+ const dataAttributes: Record<string, string> = {};
359
+ const attributes = element.attributes;
360
+ const length = attributes.length;
361
+
362
+ for (let i = 0; i < length; ++i) {
363
+ const attribute = attributes[i];
364
+ const { name, value } = attribute;
365
+ if (name.indexOf(attributePrefix) === -1) {
366
+ continue;
367
+ }
368
+ dataAttributes[camelize(name.replace(attributePrefix, ""))] = value;
369
+ }
370
+
371
+ return dataAttributes;
372
+ };