@schukai/monster 4.45.5 → 4.46.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 +11 -0
- package/package.json +1 -1
- package/source/components/accessibility/locale-select.mjs +200 -200
- package/source/components/datatable/datatable.mjs +1283 -1283
- package/source/components/form/login.mjs +117 -20
- package/source/components/form/select.mjs +3012 -3012
- package/source/components/form/style/login.pcss +16 -1
- package/source/components/form/stylesheet/login.mjs +1 -1
- package/source/components/layout/slider.mjs +686 -686
- package/source/components/navigation/site-navigation.mjs +578 -578
- package/source/components/navigation/stylesheet/site-navigation.mjs +13 -6
- package/source/components/navigation/wizard-navigation.mjs +391 -391
- package/source/monster.mjs +1 -1
|
@@ -14,8 +14,8 @@ import { instanceSymbol } from "../../constants.mjs";
|
|
|
14
14
|
import { ATTRIBUTE_PREFIX, ATTRIBUTE_ROLE } from "../../dom/constants.mjs";
|
|
15
15
|
import { CustomElement, getSlottedElements } from "../../dom/customelement.mjs";
|
|
16
16
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
assembleMethodSymbol,
|
|
18
|
+
registerCustomElement,
|
|
19
19
|
} from "../../dom/customelement.mjs";
|
|
20
20
|
import { SliderStyleSheet } from "./stylesheet/slider.mjs";
|
|
21
21
|
import { fireCustomEvent } from "../../dom/events.mjs";
|
|
@@ -83,226 +83,226 @@ const configSymbol = Symbol("config");
|
|
|
83
83
|
* @fires monster-slider-moved - Fired when the slider moves to a new slide.
|
|
84
84
|
*/
|
|
85
85
|
class Slider extends CustomElement {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
86
|
+
/**
|
|
87
|
+
* This method is called by the `instanceof` operator.
|
|
88
|
+
* @return {symbol}
|
|
89
|
+
*/
|
|
90
|
+
static get [instanceSymbol]() {
|
|
91
|
+
return Symbol.for("@schukai/monster/components/layout/slider@@instance");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
*
|
|
96
|
+
* @return {Components.Layout.Slider
|
|
97
|
+
*/
|
|
98
|
+
[assembleMethodSymbol]() {
|
|
99
|
+
super[assembleMethodSymbol]();
|
|
100
|
+
|
|
101
|
+
this[configSymbol] = {
|
|
102
|
+
currentIndex: 0,
|
|
103
|
+
|
|
104
|
+
isDragging: false,
|
|
105
|
+
draggingPos: 0,
|
|
106
|
+
startPos: 0,
|
|
107
|
+
autoPlayInterval: null,
|
|
108
|
+
resizeObserver: null, // Store the observer for later cleanup
|
|
109
|
+
|
|
110
|
+
eventHandler: {
|
|
111
|
+
mouseOverPause: null,
|
|
112
|
+
mouseout: null,
|
|
113
|
+
touchstart: null,
|
|
114
|
+
touchend: null,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// Set the CSS custom property for slide width based on visible slides.
|
|
119
|
+
const slides = this.shadowRoot.querySelector(
|
|
120
|
+
`[${ATTRIBUTE_ROLE}="slider"]`,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const slidesVisible = getVisibleSlidesFromContainerWidth.call(this);
|
|
124
|
+
slides.style.setProperty(
|
|
125
|
+
"--monster-slides-width",
|
|
126
|
+
`${100 / slidesVisible}%`,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
initControlReferences.call(this);
|
|
130
|
+
initEventHandler.call(this);
|
|
131
|
+
initStructure.call(this);
|
|
132
|
+
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Called when the element is removed from the DOM.
|
|
138
|
+
* Cleans up intervals, observers, and event listeners to prevent memory leaks.
|
|
139
|
+
*/
|
|
140
|
+
disconnectedCallback() {
|
|
141
|
+
// Check if super.disconnectedCallback exists and call it
|
|
142
|
+
if (super.disconnectedCallback) {
|
|
143
|
+
super.disconnectedCallback();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.stopAutoPlay(); // Clear interval
|
|
147
|
+
|
|
148
|
+
// Disconnect the ResizeObserver
|
|
149
|
+
if (this[configSymbol]?.resizeObserver) {
|
|
150
|
+
this[configSymbol].resizeObserver.disconnect();
|
|
151
|
+
this[configSymbol].resizeObserver = null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Remove autoplay-related event listeners
|
|
155
|
+
if (this[configSymbol]?.eventHandler) {
|
|
156
|
+
const { mouseOverPause, mouseout, touchstart, touchend } =
|
|
157
|
+
this[configSymbol].eventHandler;
|
|
158
|
+
|
|
159
|
+
if (mouseOverPause) {
|
|
160
|
+
this.removeEventListener("mouseover", mouseOverPause);
|
|
161
|
+
this[configSymbol].eventHandler.mouseOverPause = null;
|
|
162
|
+
}
|
|
163
|
+
if (mouseout) {
|
|
164
|
+
this.removeEventListener("mouseout", mouseout);
|
|
165
|
+
this[configSymbol].eventHandler.mouseout = null;
|
|
166
|
+
}
|
|
167
|
+
if (touchstart) {
|
|
168
|
+
this.removeEventListener("touchstart", touchstart);
|
|
169
|
+
this[configSymbol].eventHandler.touchstart = null;
|
|
170
|
+
}
|
|
171
|
+
if (touchend) {
|
|
172
|
+
this.removeEventListener("touchend", touchend);
|
|
173
|
+
this[configSymbol].eventHandler.touchend = null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
|
180
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
181
|
+
*
|
|
182
|
+
* The individual configuration values can be found in the table.
|
|
183
|
+
*
|
|
184
|
+
* @property {Object} templates Template definitions
|
|
185
|
+
* @property {string} templates.main Main template
|
|
186
|
+
* @property {Object} features Features
|
|
187
|
+
* @property {boolean} features.carousel Carousel feature (infinite looping)
|
|
188
|
+
* @property {boolean} features.autoPlay Auto play feature
|
|
189
|
+
* @property {boolean} features.thumbnails Thumbnails feature
|
|
190
|
+
* @property {boolean} features.drag Drag feature (touch and mouse)
|
|
191
|
+
* @property {Object} slides Slides configuration, an object with breakpoints and the number of slides to show
|
|
192
|
+
* @property {Object} slides.0 Number of slides to show at 0px
|
|
193
|
+
* @property {Object} slides.600 Number of slides to show at 600px @since 3.109.0
|
|
194
|
+
* @property {Object} slides.1200 Number of slides to show at 1200px @since 3.109.0
|
|
195
|
+
* @property {Object} slides.1800 Number of slides to show at 1800px @since 3.109.0
|
|
196
|
+
* @property {Object} carousel Carousel configuration
|
|
197
|
+
* @property {number} carousel.transition Duration (ms) of the carousel 'jump' animation when looping.
|
|
198
|
+
* @property {Object} autoPlay Auto play configuration
|
|
199
|
+
* @property {number} autoPlay.delay Delay in ms between slide transitions
|
|
200
|
+
* @property {number} autoPlay.startDelay Delay in ms before autoplay starts
|
|
201
|
+
* @property {string} autoPlay.direction Direction of the autoplay ("next" or "prev")
|
|
202
|
+
* @property {boolean} autoPlay.mouseOverPause Pause on mouse over
|
|
203
|
+
* @property {boolean} autoPlay.touchPause Pause on touch
|
|
204
|
+
* @property {Object} classes CSS classes
|
|
205
|
+
* @property {boolean} disabled Disabled state
|
|
206
|
+
*/
|
|
207
|
+
get defaults() {
|
|
208
|
+
return Object.assign({}, super.defaults, {
|
|
209
|
+
templates: {
|
|
210
|
+
main: getTemplate(),
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
classes: {},
|
|
214
|
+
disabled: false,
|
|
215
|
+
|
|
216
|
+
features: {
|
|
217
|
+
carousel: true,
|
|
218
|
+
autoPlay: true,
|
|
219
|
+
thumbnails: true,
|
|
220
|
+
drag: true,
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
slides: {
|
|
224
|
+
0: 1,
|
|
225
|
+
600: 2,
|
|
226
|
+
1200: 3,
|
|
227
|
+
1800: 4,
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
carousel: {
|
|
231
|
+
transition: 250,
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
autoPlay: {
|
|
235
|
+
delay: 1500,
|
|
236
|
+
startDelay: 1000,
|
|
237
|
+
direction: "next",
|
|
238
|
+
mouseOverPause: true,
|
|
239
|
+
touchPause: true,
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @return {string}
|
|
246
|
+
*/
|
|
247
|
+
static getTag() {
|
|
248
|
+
return "monster-slider";
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* @return {CSSStyleSheet[]}
|
|
253
|
+
*/
|
|
254
|
+
static getCSSStyleSheet() {
|
|
255
|
+
return [SliderStyleSheet];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Moves the slider to the given index.
|
|
260
|
+
*
|
|
261
|
+
* @param {number} index - The slide index to move to.
|
|
262
|
+
* @return {void}
|
|
263
|
+
*/
|
|
264
|
+
moveTo(index) {
|
|
265
|
+
return moveTo.call(this, index);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Shows the previous slide.
|
|
270
|
+
*
|
|
271
|
+
* @return {void}
|
|
272
|
+
*/
|
|
273
|
+
previous() {
|
|
274
|
+
return prev.call(this);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Shows the next slide.
|
|
279
|
+
*
|
|
280
|
+
* @return {void}
|
|
281
|
+
*/
|
|
282
|
+
next() {
|
|
283
|
+
return next.call(this);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Stops the auto play.
|
|
288
|
+
*
|
|
289
|
+
* @return {void}
|
|
290
|
+
*/
|
|
291
|
+
stopAutoPlay() {
|
|
292
|
+
if (this[configSymbol].autoPlayInterval) {
|
|
293
|
+
clearInterval(this[configSymbol].autoPlayInterval);
|
|
294
|
+
this[configSymbol].autoPlayInterval = null;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Starts the auto play.
|
|
300
|
+
*
|
|
301
|
+
* @return {void}
|
|
302
|
+
*/
|
|
303
|
+
startAutoPlay() {
|
|
304
|
+
initAutoPlay.call(this);
|
|
305
|
+
}
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
/**
|
|
@@ -310,16 +310,16 @@ class Slider extends CustomElement {
|
|
|
310
310
|
* @description Initializes the component structure, thumbnails, and autoplay.
|
|
311
311
|
*/
|
|
312
312
|
function initStructure() {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
313
|
+
if (this.getOption("features.thumbnails")) {
|
|
314
|
+
initThumbnails.call(this);
|
|
315
|
+
}
|
|
316
316
|
|
|
317
|
-
|
|
318
|
-
|
|
317
|
+
// Clones slides if carousel mode is active
|
|
318
|
+
initCarouselClones.call(this);
|
|
319
319
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
320
|
+
if (this.getOption("features.autoPlay")) {
|
|
321
|
+
initAutoPlay.call(this);
|
|
322
|
+
}
|
|
323
323
|
}
|
|
324
324
|
|
|
325
325
|
/**
|
|
@@ -327,43 +327,43 @@ function initStructure() {
|
|
|
327
327
|
* @description Generates the thumbnail navigation elements.
|
|
328
328
|
*/
|
|
329
329
|
function initThumbnails() {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
330
|
+
const self = this;
|
|
331
|
+
const thumbnails = this.shadowRoot.querySelector(
|
|
332
|
+
"[data-monster-role='thumbnails']",
|
|
333
|
+
);
|
|
334
|
+
|
|
335
|
+
// Clear existing thumbnails before regenerating
|
|
336
|
+
while (thumbnails.firstChild) {
|
|
337
|
+
thumbnails.removeChild(thumbnails.firstChild);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const { originSlides } = getSlidesAndTotal.call(this);
|
|
341
|
+
|
|
342
|
+
originSlides.forEach((x, index) => {
|
|
343
|
+
const thumbnail = document.createElement("div");
|
|
344
|
+
thumbnail.classList.add("thumbnail");
|
|
345
|
+
thumbnail.addEventListener("click", () => {
|
|
346
|
+
this.moveTo(index);
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
thumbnails.appendChild(thumbnail);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// Listen for move events to update the active thumbnail
|
|
353
|
+
this.addEventListener("monster-slider-moved", (e) => {
|
|
354
|
+
const index = e.detail.index;
|
|
355
|
+
const thumbnail = thumbnails.children[index];
|
|
356
|
+
|
|
357
|
+
if (!thumbnail) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
Array.from(thumbnails.children).forEach((thumb) => {
|
|
362
|
+
thumb.classList.remove("current");
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
thumbnail.classList.add("current");
|
|
366
|
+
});
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
/**
|
|
@@ -371,110 +371,110 @@ function initThumbnails() {
|
|
|
371
371
|
* @description Initializes the autoplay functionality and its event handlers.
|
|
372
372
|
*/
|
|
373
373
|
function initAutoPlay() {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
374
|
+
const self = this;
|
|
375
|
+
|
|
376
|
+
if (this.getOption("features.autoPlay") === false) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const autoPlay = this.getOption("autoPlay");
|
|
381
|
+
if (!isObject(autoPlay)) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const delay = autoPlay.delay;
|
|
385
|
+
const startDelay = autoPlay.startDelay;
|
|
386
|
+
const direction = autoPlay.direction;
|
|
387
|
+
|
|
388
|
+
function start() {
|
|
389
|
+
// Clear any existing interval before starting a new one
|
|
390
|
+
if (self[configSymbol].autoPlayInterval) {
|
|
391
|
+
clearInterval(self[configSymbol].autoPlayInterval);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
self[configSymbol].autoPlayInterval = setInterval(() => {
|
|
395
|
+
const { totalOriginSlides } = getSlidesAndTotal.call(self);
|
|
396
|
+
|
|
397
|
+
if (direction === "next") {
|
|
398
|
+
// Check if carousel looping is disabled and we're at the end
|
|
399
|
+
if (
|
|
400
|
+
!self.getOption("features.carousel") &&
|
|
401
|
+
self[configSymbol].currentIndex >= totalOriginSlides - 1
|
|
402
|
+
) {
|
|
403
|
+
self[configSymbol].currentIndex = -1;
|
|
404
|
+
}
|
|
405
|
+
self.next();
|
|
406
|
+
} else {
|
|
407
|
+
// Check if carousel looping is disabled and we're at the beginning
|
|
408
|
+
if (
|
|
409
|
+
!self.getOption("features.carousel") &&
|
|
410
|
+
self[configSymbol].currentIndex <= 0
|
|
411
|
+
) {
|
|
412
|
+
self[configSymbol].currentIndex = totalOriginSlides;
|
|
413
|
+
}
|
|
414
|
+
self.previous();
|
|
415
|
+
}
|
|
416
|
+
}, delay);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
setTimeout(() => {
|
|
420
|
+
start();
|
|
421
|
+
}, startDelay);
|
|
422
|
+
|
|
423
|
+
// Add listeners for pause-on-hover
|
|
424
|
+
if (autoPlay.mouseOverPause) {
|
|
425
|
+
if (this[configSymbol].eventHandler.mouseOverPause === null) {
|
|
426
|
+
this[configSymbol].eventHandler.mouseOverPause = () => {
|
|
427
|
+
clearInterval(this[configSymbol].autoPlayInterval);
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
this.addEventListener(
|
|
431
|
+
"mouseover",
|
|
432
|
+
this[configSymbol].eventHandler.mouseOverPause,
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (this[configSymbol].eventHandler.mouseout === null) {
|
|
437
|
+
this[configSymbol].eventHandler.mouseout = () => {
|
|
438
|
+
if (this[configSymbol].isDragging) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
start();
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
this.addEventListener(
|
|
445
|
+
"mouseout",
|
|
446
|
+
this[configSymbol].eventHandler.mouseout,
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Add listeners for pause-on-touch
|
|
452
|
+
if (autoPlay.touchPause) {
|
|
453
|
+
if (this[configSymbol].eventHandler.touchstart === null) {
|
|
454
|
+
this[configSymbol].eventHandler.touchstart = () => {
|
|
455
|
+
clearInterval(this[configSymbol].autoPlayInterval);
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
this.addEventListener(
|
|
459
|
+
"touchstart",
|
|
460
|
+
this[configSymbol].eventHandler.touchstart,
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if (this[configSymbol].eventHandler.touchend === null) {
|
|
465
|
+
this[configSymbol].eventHandler.touchend = () => {
|
|
466
|
+
if (this[configSymbol].isDragging) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
start();
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
this.addEventListener(
|
|
473
|
+
"touchend",
|
|
474
|
+
this[configSymbol].eventHandler.touchend,
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
478
|
}
|
|
479
479
|
|
|
480
480
|
/**
|
|
@@ -483,30 +483,30 @@ function initAutoPlay() {
|
|
|
483
483
|
* @return {number}
|
|
484
484
|
*/
|
|
485
485
|
function getVisibleSlidesFromContainerWidth() {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
486
|
+
const containerWidth = this.shadowRoot.querySelector(
|
|
487
|
+
`[${ATTRIBUTE_ROLE}="slider"]`,
|
|
488
|
+
).offsetWidth;
|
|
489
|
+
const slides = this.getOption("slides");
|
|
490
|
+
let visibleSlides = 1;
|
|
491
|
+
|
|
492
|
+
if (!isObject(slides)) {
|
|
493
|
+
return visibleSlides;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Find the largest breakpoint that is smaller than the current container width
|
|
497
|
+
for (const key in slides) {
|
|
498
|
+
if (containerWidth >= key) {
|
|
499
|
+
visibleSlides = slides[key];
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const { originSlides } = getSlidesAndTotal.call(this);
|
|
504
|
+
// Ensure we don't try to show more slides than are available
|
|
505
|
+
if (visibleSlides > originSlides.length) {
|
|
506
|
+
visibleSlides = originSlides.length; // Fixed: was originSlides.length - 1
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return visibleSlides;
|
|
510
510
|
}
|
|
511
511
|
|
|
512
512
|
/**
|
|
@@ -514,36 +514,36 @@ function getVisibleSlidesFromContainerWidth() {
|
|
|
514
514
|
* @description Clones slides to create the "infinite" loop effect for the carousel.
|
|
515
515
|
*/
|
|
516
516
|
function initCarouselClones() {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
517
|
+
const { slides, totalSlides } = getSlidesAndTotal.call(this);
|
|
518
|
+
const slidesVisible = getVisibleSlidesFromContainerWidth.call(this);
|
|
519
|
+
|
|
520
|
+
// Only clone if there are more slides than are visible
|
|
521
|
+
if (totalSlides > slidesVisible) {
|
|
522
|
+
// Clone slides from the beginning and append them to the end
|
|
523
|
+
let current = slides[0];
|
|
524
|
+
let last = slides[totalSlides - 1];
|
|
525
|
+
for (let i = 0; i < slidesVisible; i++) {
|
|
526
|
+
const clone = current.cloneNode(true);
|
|
527
|
+
clone.setAttribute("data-monster-clone-from", i);
|
|
528
|
+
last.insertAdjacentElement("afterend", clone);
|
|
529
|
+
current = current.nextElementSibling;
|
|
530
|
+
last = clone;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Clone slides from the end and prepend them to the beginning
|
|
534
|
+
current = slides[totalSlides - 1];
|
|
535
|
+
let first = slides[0];
|
|
536
|
+
for (let i = 0; i < slidesVisible; i++) {
|
|
537
|
+
const clone = current.cloneNode(true);
|
|
538
|
+
// Fixed: Index was totalSlides - i, should be totalSlides - 1 - i
|
|
539
|
+
clone.setAttribute("data-monster-clone-from", totalSlides - 1 - i);
|
|
540
|
+
first.insertAdjacentElement("beforebegin", clone);
|
|
541
|
+
current = current.previousElementSibling;
|
|
542
|
+
first = clone;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
moveTo.call(this, 0);
|
|
546
|
+
}
|
|
547
547
|
}
|
|
548
548
|
|
|
549
549
|
/**
|
|
@@ -552,21 +552,21 @@ function initCarouselClones() {
|
|
|
552
552
|
* @return {{slides: HTMLElement[], totalSlides: number, originSlides: HTMLElement[], totalOriginSlides: number}}
|
|
553
553
|
*/
|
|
554
554
|
function getSlidesAndTotal() {
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
555
|
+
// Get only original slides (excluding clones)
|
|
556
|
+
const originSlides = Array.from(
|
|
557
|
+
getSlottedElements.call(
|
|
558
|
+
this,
|
|
559
|
+
":scope:not([data-monster-clone-from])",
|
|
560
|
+
null,
|
|
561
|
+
),
|
|
562
|
+
);
|
|
563
|
+
const totalOriginSlides = originSlides.length;
|
|
564
|
+
|
|
565
|
+
// Get all slides (including clones)
|
|
566
|
+
const slides = Array.from(getSlottedElements.call(this, ":scope", null));
|
|
567
|
+
const totalSlides = slides.length;
|
|
568
|
+
|
|
569
|
+
return { originSlides, totalOriginSlides, slides, totalSlides };
|
|
570
570
|
}
|
|
571
571
|
|
|
572
572
|
/**
|
|
@@ -575,15 +575,15 @@ function getSlidesAndTotal() {
|
|
|
575
575
|
* @return {number}
|
|
576
576
|
*/
|
|
577
577
|
function next() {
|
|
578
|
-
|
|
578
|
+
const nextIndex = this[configSymbol].currentIndex + 1;
|
|
579
579
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
580
|
+
// Use requestAnimationFrame to ensure the move happens in the next frame,
|
|
581
|
+
// allowing CSS transitions to apply correctly.
|
|
582
|
+
getWindow().requestAnimationFrame(() => {
|
|
583
|
+
moveTo.call(this, nextIndex);
|
|
584
|
+
});
|
|
585
585
|
|
|
586
|
-
|
|
586
|
+
return 0;
|
|
587
587
|
}
|
|
588
588
|
|
|
589
589
|
/**
|
|
@@ -592,14 +592,14 @@ function next() {
|
|
|
592
592
|
* @return {number}
|
|
593
593
|
*/
|
|
594
594
|
function prev() {
|
|
595
|
-
|
|
595
|
+
const prevIndex = this[configSymbol].currentIndex - 1;
|
|
596
596
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
597
|
+
// Use requestAnimationFrame for smooth transitions
|
|
598
|
+
getWindow().requestAnimationFrame(() => {
|
|
599
|
+
moveTo.call(this, prevIndex);
|
|
600
|
+
});
|
|
601
601
|
|
|
602
|
-
|
|
602
|
+
return 0;
|
|
603
603
|
}
|
|
604
604
|
|
|
605
605
|
/**
|
|
@@ -609,27 +609,27 @@ function prev() {
|
|
|
609
609
|
* @param {number} index - The target slide index.
|
|
610
610
|
*/
|
|
611
611
|
function setMoveProperties(slides, index) {
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
612
|
+
// Remove 'current' class from all slides
|
|
613
|
+
slides.forEach((slide) => {
|
|
614
|
+
slide.classList.remove("current");
|
|
615
|
+
});
|
|
616
616
|
|
|
617
|
-
|
|
618
|
-
|
|
617
|
+
let offset = -(index * 100);
|
|
618
|
+
const slidesVisible = getVisibleSlidesFromContainerWidth.call(this);
|
|
619
619
|
|
|
620
|
-
|
|
620
|
+
offset = offset / slidesVisible;
|
|
621
621
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
622
|
+
if (offset !== 0) {
|
|
623
|
+
offset += "%";
|
|
624
|
+
}
|
|
625
625
|
|
|
626
|
-
|
|
627
|
-
|
|
626
|
+
this[sliderElementSymbol].style.transform =
|
|
627
|
+
`translateX(calc(${offset} + ${this[configSymbol].draggingPos}px))`;
|
|
628
628
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
629
|
+
if (slides[index]) {
|
|
630
|
+
slides[index].classList.add("current");
|
|
631
|
+
}
|
|
632
|
+
this[configSymbol].lastOffset = offset;
|
|
633
633
|
}
|
|
634
634
|
|
|
635
635
|
/**
|
|
@@ -640,87 +640,87 @@ function setMoveProperties(slides, index) {
|
|
|
640
640
|
* @fires monster-slider-moved
|
|
641
641
|
*/
|
|
642
642
|
function moveTo(index, animation) {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
643
|
+
const { slides, totalSlides, originSlides, totalOriginSlides } =
|
|
644
|
+
getSlidesAndTotal.call(this);
|
|
645
|
+
|
|
646
|
+
// Remove/add 'animate' class to enable/disable CSS transitions
|
|
647
|
+
if (animation === false) {
|
|
648
|
+
this[sliderElementSymbol].classList.remove("animate");
|
|
649
|
+
} else {
|
|
650
|
+
this[sliderElementSymbol].classList.add("animate");
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Handle carousel looping logic
|
|
654
|
+
if (this.getOption("features.carousel") === true) {
|
|
655
|
+
if (index < 0) {
|
|
656
|
+
index = -1; // Will trigger the "jump" to the end
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
if (index > totalOriginSlides) {
|
|
660
|
+
index = totalOriginSlides; // Will trigger the "jump" to the start
|
|
661
|
+
}
|
|
662
|
+
} else {
|
|
663
|
+
// Handle non-carousel boundary logic
|
|
664
|
+
if (index < 0) {
|
|
665
|
+
index = 0;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
if (index >= totalOriginSlides) {
|
|
669
|
+
index = totalOriginSlides - 1;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
if (!isInteger(index)) {
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
const visibleSlides = getVisibleSlidesFromContainerWidth.call(this);
|
|
678
|
+
|
|
679
|
+
// Hide controls if all original slides are visible
|
|
680
|
+
if (totalOriginSlides <= visibleSlides) {
|
|
681
|
+
this[prevElementSymbol].classList.add("hidden");
|
|
682
|
+
this[nextElementSymbol].classList.add("hidden");
|
|
683
|
+
this[thumbnailElementSymbol].classList.add("hidden");
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
this[prevElementSymbol].classList.remove("hidden");
|
|
687
|
+
this[nextElementSymbol].classList.remove("hidden");
|
|
688
|
+
this[thumbnailElementSymbol].classList.remove("hidden");
|
|
689
|
+
|
|
690
|
+
// Calculate the actual index in the 'slides' array (which includes clones)
|
|
691
|
+
let slidesIndex = index + visibleSlides;
|
|
692
|
+
this[configSymbol].currentIndex = index;
|
|
693
|
+
|
|
694
|
+
if (slidesIndex < 0) {
|
|
695
|
+
// We are at the "pre-cloned" slides, set index to the end
|
|
696
|
+
slidesIndex = totalSlides - 1 - visibleSlides;
|
|
697
|
+
this[configSymbol].currentIndex = totalOriginSlides - 1;
|
|
698
|
+
} else if (index > totalOriginSlides) {
|
|
699
|
+
// We are at the "post-cloned" slides, set index to the start
|
|
700
|
+
slidesIndex = 0;
|
|
701
|
+
this[configSymbol].currentIndex = 0;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
setMoveProperties.call(this, slides, slidesIndex);
|
|
705
|
+
|
|
706
|
+
// Handle the "jump" back to the start/end for seamless looping
|
|
707
|
+
if (index === totalOriginSlides) {
|
|
708
|
+
setTimeout(() => {
|
|
709
|
+
getWindow().requestAnimationFrame(() => {
|
|
710
|
+
moveTo.call(this, 0, false); // Jump to first slide without animation
|
|
711
|
+
});
|
|
712
|
+
}, this.getOption("carousel.transition"));
|
|
713
|
+
} else if (index === -1) {
|
|
714
|
+
setTimeout(() => {
|
|
715
|
+
getWindow().requestAnimationFrame(() => {
|
|
716
|
+
moveTo.call(this, totalOriginSlides - 1, false); // Jump to last slide without animation
|
|
717
|
+
});
|
|
718
|
+
}, this.getOption("carousel.transition"));
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
fireCustomEvent(this, "monster-slider-moved", {
|
|
722
|
+
index: this[configSymbol].currentIndex, // Fire with the "real" index
|
|
723
|
+
});
|
|
724
724
|
}
|
|
725
725
|
|
|
726
726
|
/**
|
|
@@ -730,73 +730,73 @@ function moveTo(index, animation) {
|
|
|
730
730
|
* @fires monster-slider-resized
|
|
731
731
|
*/
|
|
732
732
|
function initEventHandler() {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
733
|
+
const self = this;
|
|
734
|
+
|
|
735
|
+
const nextElements = this[nextElementSymbol];
|
|
736
|
+
if (nextElements) {
|
|
737
|
+
nextElements.addEventListener("click", () => {
|
|
738
|
+
self.next();
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
const prevElements = this[prevElementSymbol];
|
|
743
|
+
if (prevElements) {
|
|
744
|
+
prevElements.addEventListener("click", () => {
|
|
745
|
+
self.previous();
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// Initialize drag-to-move event listeners
|
|
750
|
+
if (this.getOption("features.drag")) {
|
|
751
|
+
this[sliderElementSymbol].addEventListener("mousedown", (e) =>
|
|
752
|
+
startDragging.call(this, e, "mouse"),
|
|
753
|
+
);
|
|
754
|
+
|
|
755
|
+
this[sliderElementSymbol].addEventListener("touchstart", (e) =>
|
|
756
|
+
startDragging.call(this, e, "touch"),
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
const initialSize = {
|
|
761
|
+
width: this[sliderElementSymbol]?.offsetWidth || 0,
|
|
762
|
+
height: this[sliderElementSymbol]?.offsetHeight || 0,
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
// Observe slider size changes to update layout
|
|
766
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
767
|
+
for (let entry of entries) {
|
|
768
|
+
const { width, height } = entry.contentRect;
|
|
769
|
+
if (width !== initialSize.width || height !== initialSize.height) {
|
|
770
|
+
self.stopAutoPlay();
|
|
771
|
+
|
|
772
|
+
// Re-init thumbnails if layout changes
|
|
773
|
+
if (this.getOption("features.thumbnails")) {
|
|
774
|
+
initThumbnails.call(this);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// Recalculate visible slides and update CSS property
|
|
778
|
+
const slidesVisible = getVisibleSlidesFromContainerWidth.call(this);
|
|
779
|
+
this[sliderElementSymbol].style.setProperty(
|
|
780
|
+
"--monster-slides-width",
|
|
781
|
+
`${100 / slidesVisible}%`,
|
|
782
|
+
);
|
|
783
|
+
|
|
784
|
+
// Move to start without animation
|
|
785
|
+
moveTo.call(self, 0, false);
|
|
786
|
+
self.startAutoPlay();
|
|
787
|
+
|
|
788
|
+
fireCustomEvent(self, "monster-slider-resized", {
|
|
789
|
+
width: width,
|
|
790
|
+
height: height,
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
resizeObserver.observe(this[sliderElementSymbol]);
|
|
797
|
+
this[configSymbol].resizeObserver = resizeObserver; // Store for cleanup
|
|
798
|
+
|
|
799
|
+
return this;
|
|
800
800
|
}
|
|
801
801
|
|
|
802
802
|
/**
|
|
@@ -806,51 +806,51 @@ function initEventHandler() {
|
|
|
806
806
|
* @param {string} type - The event type ("mouse" or "touch").
|
|
807
807
|
*/
|
|
808
808
|
function startDragging(e, type) {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
809
|
+
const { slides } = getSlidesAndTotal.call(this);
|
|
810
|
+
|
|
811
|
+
// Get the width of a single slide for calculating drag distance
|
|
812
|
+
const widthOfSlider = slides[this[configSymbol].currentIndex]?.offsetWidth;
|
|
813
|
+
|
|
814
|
+
// Set dragging state and initial position
|
|
815
|
+
this[configSymbol].isDragging = true;
|
|
816
|
+
this[configSymbol].startPos = getPositionX(e, type);
|
|
817
|
+
this[sliderElementSymbol].classList.add("grabbing");
|
|
818
|
+
// Disable transitions during drag for smooth movement
|
|
819
|
+
this[sliderElementSymbol].style.transitionProperty = "none";
|
|
820
|
+
|
|
821
|
+
const callbackMousemove = (x) => {
|
|
822
|
+
dragging.call(this, x, type);
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
const callbackMouseUp = () => {
|
|
826
|
+
const endEvent = type === "mouse" ? "mouseup" : "touchend";
|
|
827
|
+
const moveEvent = type === "mouse" ? "mousemove" : "touchmove";
|
|
828
|
+
|
|
829
|
+
// Clean up global event listeners
|
|
830
|
+
document.body.removeEventListener(endEvent, callbackMouseUp);
|
|
831
|
+
document.body.removeEventListener(moveEvent, callbackMousemove);
|
|
832
|
+
|
|
833
|
+
this[configSymbol].isDragging = false;
|
|
834
|
+
this[configSymbol].startPos = 0;
|
|
835
|
+
this[sliderElementSymbol].classList.remove("grabbing");
|
|
836
|
+
this[sliderElementSymbol].style.transitionProperty = ""; // Re-enable transitions
|
|
837
|
+
|
|
838
|
+
const lastPos = this[configSymbol].draggingPos;
|
|
839
|
+
this[configSymbol].draggingPos = 0;
|
|
840
|
+
|
|
841
|
+
// Calculate how many slides were "swiped" and move to the new index
|
|
842
|
+
let newIndex = this[configSymbol].currentIndex;
|
|
843
|
+
const shift = lastPos / widthOfSlider;
|
|
844
|
+
const shiftIndex = Math.round(shift);
|
|
845
|
+
|
|
846
|
+
newIndex += shiftIndex * -1;
|
|
847
|
+
this.moveTo(newIndex);
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
document.body.addEventListener("mouseup", callbackMouseUp);
|
|
851
|
+
document.body.addEventListener("mousemove", callbackMousemove);
|
|
852
|
+
document.body.addEventListener("touchend", callbackMouseUp);
|
|
853
|
+
document.body.addEventListener("touchmove", callbackMousemove);
|
|
854
854
|
}
|
|
855
855
|
|
|
856
856
|
/**
|
|
@@ -861,7 +861,7 @@ function startDragging(e, type) {
|
|
|
861
861
|
* @return {number} The clientX position.
|
|
862
862
|
*/
|
|
863
863
|
function getPositionX(e, type) {
|
|
864
|
-
|
|
864
|
+
return type === "mouse" ? e.pageX : e.touches[0].clientX;
|
|
865
865
|
}
|
|
866
866
|
|
|
867
867
|
/**
|
|
@@ -871,13 +871,13 @@ function getPositionX(e, type) {
|
|
|
871
871
|
* @param {string} type - The event type ("mouse" or "touch").
|
|
872
872
|
*/
|
|
873
873
|
function dragging(e, type) {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
874
|
+
if (!this[configSymbol].isDragging) return;
|
|
875
|
+
this[configSymbol].draggingPos =
|
|
876
|
+
getPositionX(e, type) - this[configSymbol].startPos;
|
|
877
877
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
878
|
+
// Update position based on drag delta
|
|
879
|
+
this[sliderElementSymbol].style.transform =
|
|
880
|
+
`translateX(calc(${this[configSymbol].lastOffset} + ${this[configSymbol].draggingPos}px))`;
|
|
881
881
|
}
|
|
882
882
|
|
|
883
883
|
/**
|
|
@@ -886,25 +886,25 @@ function dragging(e, type) {
|
|
|
886
886
|
* @return {void}
|
|
887
887
|
*/
|
|
888
888
|
function initControlReferences() {
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
889
|
+
this[controlElementSymbol] = this.shadowRoot.querySelector(
|
|
890
|
+
`[${ATTRIBUTE_ROLE}="control"]`,
|
|
891
|
+
);
|
|
892
892
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
893
|
+
this[sliderElementSymbol] = this.shadowRoot.querySelector(
|
|
894
|
+
`[${ATTRIBUTE_ROLE}="slider"]`,
|
|
895
|
+
);
|
|
896
896
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
897
|
+
this[prevElementSymbol] = this.shadowRoot.querySelector(
|
|
898
|
+
`[${ATTRIBUTE_ROLE}="prev"]`,
|
|
899
|
+
);
|
|
900
900
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
901
|
+
this[nextElementSymbol] = this.shadowRoot.querySelector(
|
|
902
|
+
`[${ATTRIBUTE_ROLE}="next"]`,
|
|
903
|
+
);
|
|
904
904
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
905
|
+
this[thumbnailElementSymbol] = this.shadowRoot.querySelector(
|
|
906
|
+
`[${ATTRIBUTE_ROLE}="thumbnails"]`,
|
|
907
|
+
);
|
|
908
908
|
}
|
|
909
909
|
|
|
910
910
|
/**
|
|
@@ -913,8 +913,8 @@ function initControlReferences() {
|
|
|
913
913
|
* @return {string}
|
|
914
914
|
*/
|
|
915
915
|
function getTemplate() {
|
|
916
|
-
|
|
917
|
-
|
|
916
|
+
// language=HTML
|
|
917
|
+
return `
|
|
918
918
|
<div data-monster-role="control" part="control">
|
|
919
919
|
<div class="prev" data-monster-role="prev" part="prev">
|
|
920
920
|
<slot name="prev"></slot>
|