wj-elements 0.3.7 → 0.4.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/dist/base-path.js +16 -2
- package/dist/base-path.js.map +1 -1
- package/dist/{icon-DVyMc4Wv.js → icon-CReYMzAK.js} +2 -2
- package/dist/{icon-DVyMc4Wv.js.map → icon-CReYMzAK.js.map} +1 -1
- package/dist/localize.js +15 -2
- package/dist/localize.js.map +1 -1
- package/dist/packages/localize/localize.d.ts +15 -2
- package/dist/packages/translations/en-gb.d.ts +1 -0
- package/dist/packages/translations/sk-sk.d.ts +1 -0
- package/dist/packages/utils/permissions.d.ts +9 -9
- package/dist/packages/wje-accordion/accordion.element.d.ts +3 -6
- package/dist/packages/wje-accordion-item/accordion-item.element.d.ts +27 -6
- package/dist/packages/wje-animation/animation.element.d.ts +10 -2
- package/dist/packages/wje-aside/aside.element.d.ts +10 -6
- package/dist/packages/wje-avatar/avatar.element.d.ts +19 -11
- package/dist/packages/wje-carousel/carousel.element.d.ts +78 -3
- package/dist/packages/wje-carousel-item/carousel-item.element.d.ts +5 -0
- package/dist/packages/wje-select/select.element.d.ts +7 -0
- package/dist/permissions.js +7 -7
- package/dist/permissions.js.map +1 -1
- package/dist/wje-accordion-item.js +18 -18
- package/dist/wje-accordion-item.js.map +1 -1
- package/dist/wje-accordion.js.map +1 -1
- package/dist/wje-animation.js +1 -1
- package/dist/wje-animation.js.map +1 -1
- package/dist/wje-aside.js +1 -1
- package/dist/wje-aside.js.map +1 -1
- package/dist/wje-avatar.js.map +1 -1
- package/dist/wje-button.js +1 -1
- package/dist/wje-carousel-item.js +19 -1
- package/dist/wje-carousel-item.js.map +1 -1
- package/dist/wje-carousel.js +208 -57
- package/dist/wje-carousel.js.map +1 -1
- package/dist/wje-element.js +4 -4
- package/dist/wje-element.js.map +1 -1
- package/dist/wje-file-upload-item.js +1 -1
- package/dist/wje-icon.js +1 -1
- package/dist/wje-img-comparer.js +1 -1
- package/dist/wje-master.js +5 -3
- package/dist/wje-master.js.map +1 -1
- package/dist/wje-option.js +1 -1
- package/dist/wje-pagination.js +1 -1
- package/dist/wje-select.js +41 -4
- package/dist/wje-select.js.map +1 -1
- package/package.json +4 -3
package/dist/wje-carousel.js
CHANGED
|
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import WJElement from "./wje-element.js";
|
|
5
|
-
const styles = '/*\n[ Carousel ]\n*/\n\n
|
|
5
|
+
const styles = '/*\n[ Carousel ]\n*/\n\n:host {\n display: block;\n width: var(--wje-carousel-width, 100%);\n max-width: 100%;\n box-sizing: border-box;\n}\n\n.native-carousel {\n position: relative;\n width: 100%;\n height: var(--wje-carousel-height, 300px);\n scroll-behavior: smooth;\n box-sizing: border-box;\n}\n\n.slides-wrapper {\n position: relative;\n display: flex;\n align-items: stretch;\n width: 100%;\n height: var(--wje-carousel-height, 300px);\n box-sizing: border-box;\n}\n\n.carousel-slides {\n display: flex;\n flex: 1 1 auto;\n transition: transform 0.5s ease;\n align-items: stretch;\n overflow: auto;\n overscroll-behavior-x: contain;\n scrollbar-width: none;\n -ms-overflow-style: none;\n aspect-ratio: var(--wje-aspect-ratio, 4 / 3);\n scroll-snap-type: x mandatory;\n scroll-padding-inline: var(--wje-spacing-inline, 0);\n overflow-y: hidden;\n padding-inline: var(--wje-spacing-inline, 0);\n gap: var(--wje-carousel-gap, 0.5rem);\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n box-sizing: border-box;\n}\n\n.carousel-slides::-webkit-scrollbar {\n display: none;\n}\n\n::slotted(wje-carousel-item) {\n flex: 0 0 var(--wje-carousel-item-basis, var(--wje-carousel-size));\n width: var(--wje-carousel-item-basis, var(--wje-carousel-size));\n min-width: 0;\n max-width: 100%;\n align-self: stretch;\n height: 100%;\n box-sizing: border-box;\n}\n\n/*NAVIGATION*/\n\n[name="prev"], [name="next"] {\n display: block;\n position: absolute;\n top: 50%;\n border: none;\n cursor: pointer;\n z-index: 2;\n}\n\n[name="prev"] {\n left: -1rem;\n transform: translate(-100%, -50%);\n}\n\n[name="next"] {\n right: -1rem;\n transform: translate(100%, -50%);\n}\n\n/*PAGINATION*/\n\n.pagination {\n position: relative;\n left: 50%;\n transform: translate(-50%, 0);\n display: flex;\n z-index: 2;\n justify-content: center;\n padding-block: 1rem;\n}\n.pagination-item {\n cursor: pointer;\n height: 15px;\n width: 15px;\n margin: 0 2px;\n background-color: var(--wje-color-contrast-4);\n display: inline-block;\n border-radius: 50%;\n}\n.pagination-item.active {\n background-color: var(--wje-color);\n}\n\n/*THUMBNAILS*/\n\n.thumbnails {\n display: flex;\n justify-content: center;\n align-items: center;\n overflow-x: auto;\n gap: 0.5rem;\n padding: 0 0.5rem;\n margin-top: 0.5rem;\n margin-bottom: 0.5rem;\n box-sizing: border-box;\n overflow-y: hidden;\n wje-thumbnail {\n --wje-thumbnail-width: 48px;\n --wje-thumbnail-height: 48px;\n --wje-thumbnail-border-radius: 0;\n cursor: pointer;\n border: 1px solid transparent;\n }\n .active {\n border: 1px solid var(--wje-color-primary-11);\n }\n}\n';
|
|
6
6
|
class Carousel extends WJElement {
|
|
7
7
|
/**
|
|
8
8
|
* Carousel constructor method.
|
|
@@ -58,6 +58,13 @@ class Carousel extends WJElement {
|
|
|
58
58
|
get loop() {
|
|
59
59
|
return this.hasAttribute("loop");
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Continuous loop attribute.
|
|
63
|
+
* @returns {boolean}
|
|
64
|
+
*/
|
|
65
|
+
get continuousLoop() {
|
|
66
|
+
return this.hasAttribute("continuous-loop");
|
|
67
|
+
}
|
|
61
68
|
/**
|
|
62
69
|
* Getter for the CSS stylesheet.
|
|
63
70
|
* @returns {*}
|
|
@@ -70,7 +77,7 @@ class Carousel extends WJElement {
|
|
|
70
77
|
* @returns {string[]}
|
|
71
78
|
*/
|
|
72
79
|
static get observedAttributes() {
|
|
73
|
-
return ["active-slide"];
|
|
80
|
+
return ["active-slide", "slide-per-page", "continuous-loop"];
|
|
74
81
|
}
|
|
75
82
|
/**
|
|
76
83
|
* Sets up the attributes for the Carousel.
|
|
@@ -83,6 +90,14 @@ class Carousel extends WJElement {
|
|
|
83
90
|
if (this.pagination) this.changePagination();
|
|
84
91
|
if (this.thumbnails) this.changeThumbnails();
|
|
85
92
|
}
|
|
93
|
+
if (["slide-per-page", "continuous-loop"].includes(name) && old !== newName && this.slides) {
|
|
94
|
+
this.syncSlideMetrics();
|
|
95
|
+
if (this.loop) {
|
|
96
|
+
this.refresh();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this.goToSlide(this.activeSlide, "auto");
|
|
100
|
+
}
|
|
86
101
|
}
|
|
87
102
|
/**
|
|
88
103
|
* Sets up the attributes for the Carousel.
|
|
@@ -95,6 +110,8 @@ class Carousel extends WJElement {
|
|
|
95
110
|
* Before draw method for the Carousel.
|
|
96
111
|
*/
|
|
97
112
|
beforeDraw() {
|
|
113
|
+
this.syncSlideMetrics();
|
|
114
|
+
this.removeLoopClones();
|
|
98
115
|
this.cloneFirstAndLastItems();
|
|
99
116
|
}
|
|
100
117
|
/**
|
|
@@ -149,31 +166,28 @@ class Carousel extends WJElement {
|
|
|
149
166
|
this.getSlidesWithClones().forEach((slide, i) => {
|
|
150
167
|
this.intersectionObserver.observe(slide);
|
|
151
168
|
});
|
|
152
|
-
this.
|
|
153
|
-
let carouselSize = 100 / +this.slidePerPage;
|
|
154
|
-
this.style.setProperty("--wje-carousel-size", carouselSize + "%");
|
|
169
|
+
this.syncSlideMetrics();
|
|
155
170
|
this.goToSlide(this.activeSlide, "auto");
|
|
156
|
-
requestAnimationFrame(() => requestAnimationFrame(() => this.
|
|
171
|
+
requestAnimationFrame(() => requestAnimationFrame(() => this.syncActiveToSnapStart()));
|
|
157
172
|
this.slides.addEventListener("scrollend", (e) => {
|
|
158
|
-
this.
|
|
173
|
+
this.syncActiveToSnapStart();
|
|
159
174
|
});
|
|
160
175
|
this.syncAria();
|
|
161
176
|
}
|
|
162
177
|
/**
|
|
163
|
-
* Sync `activeSlide` to the slide whose
|
|
178
|
+
* Sync `activeSlide` to the slide whose leading edge is closest to the snap start.
|
|
164
179
|
*/
|
|
165
|
-
|
|
180
|
+
syncActiveToSnapStart() {
|
|
166
181
|
this.getSlides();
|
|
167
182
|
const withClones = this.getSlidesWithClones();
|
|
168
183
|
if (!withClones.length) return;
|
|
169
184
|
const containerRect = this.slides.getBoundingClientRect();
|
|
170
|
-
const
|
|
185
|
+
const snapStartX = containerRect.left + this.getScrollPaddingInlineStart();
|
|
171
186
|
let best = null;
|
|
172
187
|
let bestDist = Infinity;
|
|
173
188
|
withClones.forEach((el) => {
|
|
174
189
|
const r = el.getBoundingClientRect();
|
|
175
|
-
const
|
|
176
|
-
const dist = Math.abs(center - containerCenterX);
|
|
190
|
+
const dist = Math.abs(r.left - snapStartX);
|
|
177
191
|
if (dist < bestDist) {
|
|
178
192
|
bestDist = dist;
|
|
179
193
|
best = el;
|
|
@@ -184,10 +198,42 @@ class Carousel extends WJElement {
|
|
|
184
198
|
if (vIndex === -1) return;
|
|
185
199
|
const logicalIndex = this.getLogicalIndexForVisual(vIndex);
|
|
186
200
|
this.activeSlide = logicalIndex;
|
|
187
|
-
|
|
201
|
+
this.setActiveVisualSlide(vIndex);
|
|
202
|
+
const canonicalVisualIndex = this.getVisualIndexForLogical(logicalIndex);
|
|
203
|
+
if (canonicalVisualIndex !== vIndex) {
|
|
188
204
|
this.goToSlide(logicalIndex, "auto");
|
|
189
205
|
}
|
|
190
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Syncs computed CSS variables derived from `slide-per-page`.
|
|
209
|
+
*/
|
|
210
|
+
syncSlideMetrics() {
|
|
211
|
+
this.slidePerPage = Math.max(parseInt(this.getAttribute("slide-per-page"), 10) || 1, 1);
|
|
212
|
+
const visibleGapCount = Math.max(this.slidePerPage - 1, 0);
|
|
213
|
+
const computedItemSize = `calc((100% - (${visibleGapCount} * var(--wje-carousel-gap, 0.5rem))) / ${this.slidePerPage})`;
|
|
214
|
+
this.style.setProperty("--wje-carousel-slides-per-page", `${this.slidePerPage}`);
|
|
215
|
+
this.style.setProperty("--wje-carousel-visible-gap-count", `${visibleGapCount}`);
|
|
216
|
+
this.style.setProperty("--wje-carousel-size", computedItemSize);
|
|
217
|
+
this.style.setProperty("--wje-carousel-item-basis", "var(--wje-carousel-size)");
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Returns the inline scroll padding used by the snap area.
|
|
221
|
+
* @returns {number}
|
|
222
|
+
*/
|
|
223
|
+
getScrollPaddingInlineStart() {
|
|
224
|
+
if (!this.slides) return 0;
|
|
225
|
+
const styles2 = getComputedStyle(this.slides);
|
|
226
|
+
return parseFloat(styles2.scrollPaddingInlineStart || styles2.scrollPaddingLeft || "0") || 0;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Returns the interaction scroll behavior for UI controls.
|
|
230
|
+
* Continuous multi-slide loops use instant snapping to avoid blank edge states
|
|
231
|
+
* while the browser is still animating a previous smooth scroll.
|
|
232
|
+
* @returns {ScrollBehavior|string}
|
|
233
|
+
*/
|
|
234
|
+
getControlBehavior() {
|
|
235
|
+
return this.continuousLoop && this.slidePerPage > 1 ? "auto" : "smooth";
|
|
236
|
+
}
|
|
191
237
|
/**
|
|
192
238
|
* Sets up the IntersectionObserver for the Carousel.
|
|
193
239
|
*/
|
|
@@ -218,11 +264,10 @@ class Carousel extends WJElement {
|
|
|
218
264
|
goToSlide(index, behavior = "smooth", next = true) {
|
|
219
265
|
const slides = this.getSlides();
|
|
220
266
|
const withClones = this.getSlidesWithClones();
|
|
221
|
-
|
|
222
|
-
const maxIndex = Math.max(slides.length - 1, 0);
|
|
267
|
+
const maxIndex = this.getMaxVisibleStartIndex(slides.length);
|
|
223
268
|
let logical;
|
|
224
269
|
if (this.loop && slides.length > 0) {
|
|
225
|
-
logical = (index
|
|
270
|
+
logical = this.normalizeLoopIndex(index, slides.length);
|
|
226
271
|
} else {
|
|
227
272
|
logical = Math.min(Math.max(index, 0), maxIndex);
|
|
228
273
|
}
|
|
@@ -230,22 +275,25 @@ class Carousel extends WJElement {
|
|
|
230
275
|
const vIndex = this.getVisualIndexForLogical(logical);
|
|
231
276
|
const targetEl = withClones[vIndex];
|
|
232
277
|
if (!targetEl) return;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const containerRect = this.slides.getBoundingClientRect();
|
|
236
|
-
this.slides.scrollTo({
|
|
237
|
-
left: targetRect.left - containerRect.left + this.slides.scrollLeft,
|
|
238
|
-
top: targetRect.top - containerRect.top + this.slides.scrollTop,
|
|
239
|
-
behavior: behavior === "smooth" ? "smooth" : "auto"
|
|
240
|
-
});
|
|
278
|
+
this.setActiveVisualSlide(vIndex);
|
|
279
|
+
this.scrollToVisualIndex(vIndex, behavior);
|
|
241
280
|
if (this.navigation && !this.loop) {
|
|
242
281
|
this.nextButton.removeAttribute("disabled");
|
|
243
282
|
this.prevButton.removeAttribute("disabled");
|
|
244
|
-
if (this.activeSlide ===
|
|
283
|
+
if (this.activeSlide === maxIndex) this.nextButton.setAttribute("disabled", "");
|
|
245
284
|
if (this.activeSlide === 0) this.prevButton.setAttribute("disabled", "");
|
|
246
285
|
}
|
|
247
286
|
this.syncAria();
|
|
248
287
|
}
|
|
288
|
+
/**
|
|
289
|
+
* Sets the active class on the currently targeted visual slide and removes it elsewhere.
|
|
290
|
+
* @param {number} vIndex
|
|
291
|
+
*/
|
|
292
|
+
setActiveVisualSlide(vIndex) {
|
|
293
|
+
this.getSlidesWithClones().forEach((slide, index) => {
|
|
294
|
+
slide.classList.toggle("active", index === vIndex);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
249
297
|
/**
|
|
250
298
|
* Syncs ARIA attributes on the carousel and slides.
|
|
251
299
|
*/
|
|
@@ -273,14 +321,88 @@ class Carousel extends WJElement {
|
|
|
273
321
|
cloneFirstAndLastItems() {
|
|
274
322
|
const items = this.getSlides();
|
|
275
323
|
if (items.length && this.loop) {
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
324
|
+
const cloneCount = this.getLoopCloneCount(items.length);
|
|
325
|
+
const firstOriginal = items[0];
|
|
326
|
+
items.slice(items.length - cloneCount).forEach((item) => {
|
|
327
|
+
const clone = this.createLoopClone(item);
|
|
328
|
+
this.insertBefore(clone, firstOriginal);
|
|
329
|
+
});
|
|
330
|
+
items.slice(0, cloneCount).forEach((item) => {
|
|
331
|
+
const clone = this.createLoopClone(item);
|
|
332
|
+
this.append(clone);
|
|
333
|
+
});
|
|
282
334
|
}
|
|
283
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Creates a sanitized loop clone that does not inherit transient render state
|
|
338
|
+
* such as inline `visibility: hidden` from the source slide.
|
|
339
|
+
* @param {HTMLElement} item
|
|
340
|
+
* @returns {HTMLElement}
|
|
341
|
+
*/
|
|
342
|
+
createLoopClone(item) {
|
|
343
|
+
var _a;
|
|
344
|
+
const clone = item.cloneNode(true);
|
|
345
|
+
clone.classList.add("clone");
|
|
346
|
+
clone.classList.remove("active");
|
|
347
|
+
clone.style.removeProperty("visibility");
|
|
348
|
+
if (!((_a = clone.getAttribute("style")) == null ? void 0 : _a.trim())) {
|
|
349
|
+
clone.removeAttribute("style");
|
|
350
|
+
}
|
|
351
|
+
return clone;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Removes loop clones so they can be rebuilt for the current configuration.
|
|
355
|
+
*/
|
|
356
|
+
removeLoopClones() {
|
|
357
|
+
this.querySelectorAll("wje-carousel-item.clone").forEach((clone) => clone.remove());
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Returns how many slides should be cloned on each side when loop is enabled.
|
|
361
|
+
* @param {number} totalSlides
|
|
362
|
+
* @returns {number}
|
|
363
|
+
*/
|
|
364
|
+
getLoopCloneCount(totalSlides = this.getSlides().length) {
|
|
365
|
+
if (!this.loop || !totalSlides) return 0;
|
|
366
|
+
return this.continuousLoop ? Math.min(this.slidePerPage, totalSlides) : 1;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Scrolls the carousel to a visual slide index.
|
|
370
|
+
* @param {number} vIndex
|
|
371
|
+
* @param {ScrollBehavior|string} behavior
|
|
372
|
+
*/
|
|
373
|
+
scrollToVisualIndex(vIndex, behavior = "smooth") {
|
|
374
|
+
const withClones = this.getSlidesWithClones();
|
|
375
|
+
const firstEl = withClones[0];
|
|
376
|
+
const targetEl = withClones[vIndex];
|
|
377
|
+
if (!firstEl || !targetEl || !this.slides) return;
|
|
378
|
+
const firstRect = firstEl.getBoundingClientRect();
|
|
379
|
+
const targetRect = targetEl.getBoundingClientRect();
|
|
380
|
+
const contentOffsetLeft = targetRect.left - firstRect.left;
|
|
381
|
+
const nextLeft = contentOffsetLeft - this.getScrollPaddingInlineStart();
|
|
382
|
+
const targetLeft = Math.max(nextLeft, 0);
|
|
383
|
+
if (behavior === "smooth") {
|
|
384
|
+
this.slides.scrollTo({
|
|
385
|
+
left: targetLeft,
|
|
386
|
+
top: this.slides.scrollTop,
|
|
387
|
+
behavior: "smooth"
|
|
388
|
+
});
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (this.snapRestoreFrame) {
|
|
392
|
+
cancelAnimationFrame(this.snapRestoreFrame);
|
|
393
|
+
}
|
|
394
|
+
const inlineSnapType = this.slides.style.scrollSnapType;
|
|
395
|
+
this.slides.style.scrollSnapType = "none";
|
|
396
|
+
this.slides.scrollTo({
|
|
397
|
+
left: targetLeft,
|
|
398
|
+
top: this.slides.scrollTop,
|
|
399
|
+
behavior: "auto"
|
|
400
|
+
});
|
|
401
|
+
this.snapRestoreFrame = requestAnimationFrame(() => {
|
|
402
|
+
this.slides.style.scrollSnapType = inlineSnapType;
|
|
403
|
+
this.snapRestoreFrame = null;
|
|
404
|
+
});
|
|
405
|
+
}
|
|
284
406
|
/**
|
|
285
407
|
* Goes to the next slide.
|
|
286
408
|
*/
|
|
@@ -304,11 +426,8 @@ class Carousel extends WJElement {
|
|
|
304
426
|
*/
|
|
305
427
|
changePagination() {
|
|
306
428
|
if (this.pagination) {
|
|
307
|
-
this.removeActiveSlide();
|
|
308
429
|
this.context.querySelectorAll(".pagination-item").forEach((item, i) => {
|
|
309
|
-
|
|
310
|
-
item.classList.add("active");
|
|
311
|
-
}
|
|
430
|
+
item.classList.toggle("active", i === this.activeSlide);
|
|
312
431
|
});
|
|
313
432
|
}
|
|
314
433
|
}
|
|
@@ -317,11 +436,8 @@ class Carousel extends WJElement {
|
|
|
317
436
|
*/
|
|
318
437
|
changeThumbnails() {
|
|
319
438
|
if (this.thumbnails) {
|
|
320
|
-
this.removeActiveSlide();
|
|
321
439
|
this.context.querySelectorAll("wje-thumbnail").forEach((item, i) => {
|
|
322
|
-
|
|
323
|
-
item.classList.add("active");
|
|
324
|
-
}
|
|
440
|
+
item.classList.toggle("active", i === this.activeSlide);
|
|
325
441
|
});
|
|
326
442
|
}
|
|
327
443
|
}
|
|
@@ -337,9 +453,6 @@ class Carousel extends WJElement {
|
|
|
337
453
|
nextButton.setAttribute("slot", "next");
|
|
338
454
|
nextButton.innerHTML = '<wje-icon name="chevron-right" size="large"></wje-icon>';
|
|
339
455
|
nextButton.classList.add("next");
|
|
340
|
-
nextButton.addEventListener("click", (e) => {
|
|
341
|
-
this.nextSlide();
|
|
342
|
-
});
|
|
343
456
|
return nextButton;
|
|
344
457
|
}
|
|
345
458
|
/**
|
|
@@ -354,9 +467,6 @@ class Carousel extends WJElement {
|
|
|
354
467
|
previousButton.setAttribute("slot", "prev");
|
|
355
468
|
previousButton.innerHTML = '<wje-icon name="chevron-left" size="large"></wje-icon>';
|
|
356
469
|
previousButton.classList.add("prev");
|
|
357
|
-
previousButton.addEventListener("click", (e) => {
|
|
358
|
-
this.previousSlide();
|
|
359
|
-
});
|
|
360
470
|
return previousButton;
|
|
361
471
|
}
|
|
362
472
|
/**
|
|
@@ -367,14 +477,13 @@ class Carousel extends WJElement {
|
|
|
367
477
|
const pagination = document.createElement("div");
|
|
368
478
|
pagination.setAttribute("part", "pagination");
|
|
369
479
|
pagination.classList.add("pagination");
|
|
370
|
-
|
|
371
|
-
slides.forEach((slide, i) => {
|
|
480
|
+
this.getPaginationIndexes().forEach((i) => {
|
|
372
481
|
const paginationItem = document.createElement("div");
|
|
373
482
|
paginationItem.classList.add("pagination-item");
|
|
374
483
|
paginationItem.addEventListener("click", (e) => {
|
|
375
484
|
this.removeActiveSlide();
|
|
376
485
|
e.target.classList.add("active");
|
|
377
|
-
this.goToSlide(i);
|
|
486
|
+
this.goToSlide(i, this.getControlBehavior());
|
|
378
487
|
});
|
|
379
488
|
pagination.append(paginationItem);
|
|
380
489
|
});
|
|
@@ -394,7 +503,7 @@ class Carousel extends WJElement {
|
|
|
394
503
|
thumbnail.addEventListener("click", (e) => {
|
|
395
504
|
this.removeActiveSlide();
|
|
396
505
|
e.target.closest("wje-thumbnail").classList.add("active");
|
|
397
|
-
this.goToSlide(i);
|
|
506
|
+
this.goToSlide(i, this.getControlBehavior());
|
|
398
507
|
});
|
|
399
508
|
thumbnails.append(thumbnail);
|
|
400
509
|
});
|
|
@@ -404,13 +513,13 @@ class Carousel extends WJElement {
|
|
|
404
513
|
* Goes to the next slide.
|
|
405
514
|
*/
|
|
406
515
|
nextSlide() {
|
|
407
|
-
this.goToSlide(this.activeSlide + this.
|
|
516
|
+
this.goToSlide(this.activeSlide + 1, this.getControlBehavior());
|
|
408
517
|
}
|
|
409
518
|
/**
|
|
410
519
|
* Goes to the previous slide.
|
|
411
520
|
*/
|
|
412
521
|
previousSlide() {
|
|
413
|
-
this.goToSlide(this.activeSlide - this.
|
|
522
|
+
this.goToSlide(this.activeSlide - 1, this.getControlBehavior());
|
|
414
523
|
}
|
|
415
524
|
/**
|
|
416
525
|
* Goes to the slide.
|
|
@@ -428,16 +537,58 @@ class Carousel extends WJElement {
|
|
|
428
537
|
}
|
|
429
538
|
/** Maps logical index -> visual index (accounts for leading clone when loop=true) */
|
|
430
539
|
getVisualIndexForLogical(index) {
|
|
431
|
-
return this.loop ? index +
|
|
540
|
+
return this.loop ? index + this.getLoopCloneCount() : index;
|
|
432
541
|
}
|
|
433
542
|
/** Maps visual index -> logical index (handles clones at 0 and last when loop=true) */
|
|
434
543
|
getLogicalIndexForVisual(vIndex) {
|
|
435
544
|
const slides = this.getSlides();
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
if (
|
|
439
|
-
if (
|
|
440
|
-
|
|
545
|
+
const maxIndex = this.getMaxVisibleStartIndex(slides.length);
|
|
546
|
+
const cloneCount = this.getLoopCloneCount(slides.length);
|
|
547
|
+
if (!this.loop) return Math.min(Math.max(vIndex, 0), maxIndex);
|
|
548
|
+
if (this.continuousLoop) {
|
|
549
|
+
if (vIndex < cloneCount) return slides.length - cloneCount + vIndex;
|
|
550
|
+
if (vIndex >= cloneCount + slides.length) return vIndex - (cloneCount + slides.length);
|
|
551
|
+
return vIndex - cloneCount;
|
|
552
|
+
}
|
|
553
|
+
if (vIndex < cloneCount) return maxIndex;
|
|
554
|
+
if (vIndex >= cloneCount + slides.length) return 0;
|
|
555
|
+
return Math.min(Math.max(vIndex - cloneCount, 0), maxIndex);
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Returns the maximum logical slide index that can still render a full viewport.
|
|
559
|
+
* @param {number} totalSlides
|
|
560
|
+
* @returns {number}
|
|
561
|
+
*/
|
|
562
|
+
getMaxVisibleStartIndex(totalSlides = this.getSlides().length) {
|
|
563
|
+
const visibleSlides = Math.min(this.slidePerPage, totalSlides);
|
|
564
|
+
return Math.max(totalSlides - visibleSlides, 0);
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Normalizes a logical index for the active loop mode.
|
|
568
|
+
* @param {number} index
|
|
569
|
+
* @param {number} totalSlides
|
|
570
|
+
* @returns {number}
|
|
571
|
+
*/
|
|
572
|
+
normalizeLoopIndex(index, totalSlides = this.getSlides().length) {
|
|
573
|
+
const logicalCount = this.getLoopLogicalCount(totalSlides);
|
|
574
|
+
if (!logicalCount) return 0;
|
|
575
|
+
return (index % logicalCount + logicalCount) % logicalCount;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Returns how many logical positions are reachable for the current loop mode.
|
|
579
|
+
* @param {number} totalSlides
|
|
580
|
+
* @returns {number}
|
|
581
|
+
*/
|
|
582
|
+
getLoopLogicalCount(totalSlides = this.getSlides().length) {
|
|
583
|
+
if (!totalSlides) return 0;
|
|
584
|
+
return this.continuousLoop ? totalSlides : this.getMaxVisibleStartIndex(totalSlides) + 1;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Returns the pagination indexes for the current carousel mode.
|
|
588
|
+
* @returns {number[]}
|
|
589
|
+
*/
|
|
590
|
+
getPaginationIndexes() {
|
|
591
|
+
return Array.from({ length: this.getLoopLogicalCount() }, (_, index) => index);
|
|
441
592
|
}
|
|
442
593
|
/**
|
|
443
594
|
* Goes to the slide.
|
package/dist/wje-carousel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wje-carousel.js","sources":["../packages/wje-carousel/carousel.element.js","../packages/wje-carousel/carousel.js"],"sourcesContent":["import { default as WJElement, event } from '../wje-element/element.js';\nimport styles from './styles/styles.css?inline';\n\n/**\n * @summary Carousel class that extends WJElement.\n * @documentation https://elements.webjet.sk/components/carousel\n * @status stable\n * @augments WJElement\n * @slot - The carousel main content.\n * @cssproperty [--wje-carousel-size=100%] - Size of the carousel component;\n */\nexport default class Carousel extends WJElement {\n /**\n * Carousel constructor method.\n */\n constructor() {\n super();\n\n this.slidePerPage = 1;\n }\n\n /**\n * Active slide attribute.\n * @param value\n */\n set activeSlide(value) {\n this.setAttribute('active-slide', value);\n }\n\n /**\n * Active slide attribute.\n * @returns {number|number}\n */\n get activeSlide() {\n return +this.getAttribute('active-slide') || 0;\n }\n\n /**\n * Pagination attribute.\n * @returns {boolean}\n */\n get pagination() {\n return this.hasAttribute('pagination');\n }\n\n /**\n * Navigation attribute.\n * @returns {boolean}\n */\n get navigation() {\n return this.hasAttribute('navigation');\n }\n\n /**\n * Thumbnails attribute.\n * @returns {boolean}\n */\n get thumbnails() {\n return this.hasAttribute('thumbnails');\n }\n\n /**\n * Loop attribute.\n * @returns {boolean}\n */\n get loop() {\n return this.hasAttribute('loop');\n }\n\n /**\n * Class name for the Carousel.\n * @type {string}\n */\n className = 'Carousel';\n\n /**\n * Getter for the CSS stylesheet.\n * @returns {*}\n */\n static get cssStyleSheet() {\n return styles;\n }\n\n /**\n * Getter for the observed attributes.\n * @returns {string[]}\n */\n static get observedAttributes() {\n return ['active-slide'];\n }\n\n /**\n * Sets up the attributes for the Carousel.\n * @param name\n * @param old\n * @param newName\n */\n attributeChangedCallback(name, old, newName) {\n if (name === 'active-slide') {\n if (this.pagination) this.changePagination();\n\n if (this.thumbnails) this.changeThumbnails();\n }\n }\n\n /**\n * Sets up the attributes for the Carousel.\n */\n setupAttributes() {\n this.isShadowRoot = 'open';\n this.syncAria();\n }\n\n /**\n * Before draw method for the Carousel.\n */\n beforeDraw() {\n this.cloneFirstAndLastItems();\n }\n\n /**\n * Draw method for the Carousel.\n * @returns {DocumentFragment}\n */\n draw() {\n let fragment = document.createDocumentFragment();\n\n let native = document.createElement('div');\n native.classList.add('native-carousel');\n\n let wrapper = document.createElement('div');\n wrapper.classList.add('slides-wrapper');\n\n let slides = document.createElement('div');\n slides.classList.add('carousel-slides');\n\n let slot = document.createElement('slot');\n\n let slotPrev = document.createElement('slot');\n slotPrev.setAttribute('name', 'prev');\n\n let slotNext = document.createElement('slot');\n slotNext.setAttribute('name', 'next');\n\n slides.append(slot);\n native.append(wrapper);\n\n if (this.navigation) {\n let existingPrev = this.querySelector('[slot=\"prev\"]');\n let existingNext = this.querySelector('[slot=\"next\"]');\n\n this.prevButton = existingPrev || this.createPreviousButton();\n this.nextButton = existingNext || this.createNextButton();\n\n if (this.prevButton && !this.prevButton.dataset.wjeCarouselNavBound) {\n this.prevButton.addEventListener('click', () => this.previousSlide());\n this.prevButton.dataset.wjeCarouselNavBound = 'true';\n }\n\n if (this.nextButton && !this.nextButton.dataset.wjeCarouselNavBound) {\n this.nextButton.addEventListener('click', () => this.nextSlide());\n this.nextButton.dataset.wjeCarouselNavBound = 'true';\n }\n\n if (!existingPrev) this.append(this.prevButton);\n if (!existingNext) this.append(this.nextButton);\n\n wrapper.append(slotPrev);\n wrapper.append(slotNext);\n }\n\n wrapper.append(slides);\n\n if (this.pagination) native.append(this.createPagination());\n\n if (this.thumbnails) native.append(this.createThumbnails());\n\n fragment.append(native);\n\n this.slides = slides;\n\n return fragment;\n }\n\n /**\n * After draw method for the Carousel.\n */\n afterDraw() {\n this.setIntersectionObserver();\n this.getSlidesWithClones().forEach((slide, i) => {\n this.intersectionObserver.observe(slide);\n });\n\n this.slidePerPage = this.getAttribute('slide-per-page') || 1;\n let carouselSize = 100 / +this.slidePerPage;\n this.style.setProperty('--wje-carousel-size', carouselSize + '%');\n\n this.goToSlide(this.activeSlide, 'auto');\n\n requestAnimationFrame(() => requestAnimationFrame(() => this.syncActiveToCenter()));\n\n this.slides.addEventListener('scrollend', (e) => {\n this.syncActiveToCenter();\n });\n\n this.syncAria();\n }\n\n /**\n * Sync `activeSlide` to the slide whose center is closest to the container center.\n */\n syncActiveToCenter() {\n const slides = this.getSlides();\n const withClones = this.getSlidesWithClones();\n if (!withClones.length) return;\n\n const containerRect = this.slides.getBoundingClientRect();\n const containerCenterX = containerRect.left + containerRect.width / 2;\n\n let best = null;\n let bestDist = Infinity;\n withClones.forEach((el) => {\n const r = el.getBoundingClientRect();\n const center = r.left + r.width / 2;\n const dist = Math.abs(center - containerCenterX);\n if (dist < bestDist) {\n bestDist = dist;\n best = el;\n }\n });\n\n if (!best) return;\n\n const vIndex = withClones.indexOf(best);\n if (vIndex === -1) return;\n\n const logicalIndex = this.getLogicalIndexForVisual(vIndex);\n this.activeSlide = logicalIndex;\n\n // If we landed on a clone, silently snap to the corresponding real slide\n if (this.loop && (vIndex === 0 || vIndex === withClones.length - 1)) {\n this.goToSlide(logicalIndex, 'auto');\n }\n }\n\n /**\n * Sets up the IntersectionObserver for the Carousel.\n */\n setIntersectionObserver() {\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n this.entriesMap.set(entry.target, entry);\n });\n },\n {\n root: this.context.querySelector('.carousel-slides'),\n threshold: 0.5,\n }\n );\n\n this.entriesMap = new Map();\n this.records = this.intersectionObserver.takeRecords();\n this.records.forEach((entry) => {\n this.entriesMap.set(entry.target, entry);\n });\n }\n\n /**\n * Goes to the slide.\n * @param index\n * @param behavior\n * @param next\n */\n goToSlide(index, behavior = 'smooth', next = true) {\n const slides = this.getSlides();\n const withClones = this.getSlidesWithClones();\n\n // remove active class from all slides (including clones)\n withClones.forEach(slide => slide.classList.remove('active'));\n\n // compute logical index: wrap when loop=true, else clamp\n const maxIndex = Math.max(slides.length - 1, 0);\n let logical;\n if (this.loop && slides.length > 0) {\n logical = ((index % slides.length) + slides.length) % slides.length; // safe modulo\n } else {\n logical = Math.min(Math.max(index, 0), maxIndex);\n }\n this.activeSlide = logical;\n\n // compute visual target considering clones when loop=true\n const vIndex = this.getVisualIndexForLogical(logical);\n const targetEl = withClones[vIndex];\n if (!targetEl) return;\n\n targetEl.classList.add('active');\n\n const targetRect = targetEl.getBoundingClientRect();\n const containerRect = this.slides.getBoundingClientRect();\n\n this.slides.scrollTo({\n left: targetRect.left - containerRect.left + this.slides.scrollLeft,\n top: targetRect.top - containerRect.top + this.slides.scrollTop,\n behavior: behavior === 'smooth' ? 'smooth' : 'auto',\n });\n\n if (this.navigation && !this.loop) {\n this.nextButton.removeAttribute('disabled');\n this.prevButton.removeAttribute('disabled');\n\n if (this.activeSlide === slides.length - 1) this.nextButton.setAttribute('disabled', '');\n if (this.activeSlide === 0) this.prevButton.setAttribute('disabled', '');\n }\n\n this.syncAria();\n }\n\n /**\n * Syncs ARIA attributes on the carousel and slides.\n */\n syncAria() {\n this.setAriaState({\n role: 'region',\n roledescription: 'carousel',\n });\n\n const slides = this.getSlides();\n const total = slides.length;\n slides.forEach((slide, index) => {\n slide.setAttribute('role', 'group');\n slide.setAttribute('aria-roledescription', 'slide');\n slide.setAttribute('aria-label', `Slide ${index + 1} of ${total}`);\n slide.setAttribute('aria-hidden', slide.classList.contains('active') ? 'false' : 'true');\n });\n\n const clones = this.querySelectorAll('.clone');\n clones.forEach((slide) => {\n slide.setAttribute('aria-hidden', 'true');\n });\n }\n\n /**\n * Clones the first and last items.\n */\n cloneFirstAndLastItems() {\n const items = this.getSlides();\n\n if (items.length && this.loop) {\n // Clone first -> append to end\n const firstItemClone = items[0].cloneNode(true);\n firstItemClone.classList.add('clone');\n this.append(firstItemClone);\n\n // Clone last -> insert before the first original item so it becomes the leading clone\n const lastItemClone = items[items.length - 1].cloneNode(true);\n lastItemClone.classList.add('clone');\n this.insertBefore(lastItemClone, items[0]);\n }\n }\n\n /**\n * Goes to the next slide.\n */\n removeActiveSlide() {\n this.getSlidesWithClones().forEach((slide, i) => {\n slide.classList.remove('active');\n });\n\n if (this.pagination) {\n this.context.querySelectorAll('.pagination-item').forEach((item) => {\n item.classList.remove('active');\n });\n }\n\n if (this.thumbnails) {\n this.context.querySelectorAll('wje-thumbnail').forEach((item) => {\n item.classList.remove('active');\n });\n }\n }\n\n /**\n * Goes to the next slide.\n */\n changePagination() {\n if (this.pagination) {\n this.removeActiveSlide();\n this.context.querySelectorAll('.pagination-item').forEach((item, i) => {\n if (i === this.activeSlide) {\n item.classList.add('active');\n }\n });\n }\n }\n\n /**\n * Goes to the next slide.\n */\n changeThumbnails() {\n if (this.thumbnails) {\n this.removeActiveSlide();\n this.context.querySelectorAll('wje-thumbnail').forEach((item, i) => {\n if (i === this.activeSlide) {\n item.classList.add('active');\n }\n });\n }\n }\n\n /**\n * Goes to the next slide.\n * @returns {Element}\n */\n createNextButton() {\n const nextButton = document.createElement('wje-button');\n nextButton.setAttribute('part', 'next-button');\n nextButton.setAttribute('circle', '');\n nextButton.setAttribute('fill', 'link');\n nextButton.setAttribute('slot', 'next');\n nextButton.innerHTML = '<wje-icon name=\"chevron-right\" size=\"large\"></wje-icon>';\n nextButton.classList.add('next');\n nextButton.addEventListener('click', (e) => {\n this.nextSlide();\n });\n\n return nextButton;\n }\n\n /**\n * Goes to the next slide.\n * @returns {Element}\n */\n createPreviousButton() {\n const previousButton = document.createElement('wje-button');\n previousButton.setAttribute('part', 'previous-button');\n previousButton.setAttribute('circle', '');\n previousButton.setAttribute('fill', 'link');\n previousButton.setAttribute('slot', 'prev');\n previousButton.innerHTML = '<wje-icon name=\"chevron-left\" size=\"large\"></wje-icon>';\n previousButton.classList.add('prev');\n previousButton.addEventListener('click', (e) => {\n this.previousSlide();\n });\n\n return previousButton;\n }\n\n /**\n * Goes to the next slide.\n * @returns {Element}\n */\n createPagination() {\n const pagination = document.createElement('div');\n pagination.setAttribute('part', 'pagination');\n pagination.classList.add('pagination');\n\n const slides = this.getSlides();\n slides.forEach((slide, i) => {\n const paginationItem = document.createElement('div');\n paginationItem.classList.add('pagination-item');\n paginationItem.addEventListener('click', (e) => {\n this.removeActiveSlide();\n e.target.classList.add('active');\n this.goToSlide(i);\n });\n pagination.append(paginationItem);\n });\n\n return pagination;\n }\n\n /**\n * Goes to the next slide.\n * @returns {Element}\n */\n createThumbnails() {\n const thumbnails = document.createElement('div');\n thumbnails.classList.add('thumbnails');\n\n const slides = this.getSlides();\n slides.forEach((slide, i) => {\n const thumbnail = document.createElement('wje-thumbnail');\n thumbnail.innerHTML = `<img src=\"${slide.querySelector('wje-img').getAttribute('src')}\"></img>`;\n thumbnail.addEventListener('click', (e) => {\n this.removeActiveSlide();\n e.target.closest('wje-thumbnail').classList.add('active');\n this.goToSlide(i);\n });\n thumbnails.append(thumbnail);\n });\n\n return thumbnails;\n }\n\n /**\n * Goes to the next slide.\n */\n nextSlide() {\n this.goToSlide(this.activeSlide + this.slidePerPage);\n }\n\n /**\n * Goes to the previous slide.\n */\n previousSlide() {\n this.goToSlide(this.activeSlide - this.slidePerPage);\n }\n\n /**\n * Goes to the slide.\n * @returns {Array}\n */\n getSlides() {\n return Array.from(this.querySelectorAll('wje-carousel-item:not(.clone)'));\n }\n\n /**\n * Goes to the slide.\n * @returns {Array}\n */\n getSlidesWithClones() {\n return Array.from(this.querySelectorAll('wje-carousel-item'));\n }\n\n /** Maps logical index -> visual index (accounts for leading clone when loop=true) */\n getVisualIndexForLogical(index) {\n return this.loop ? index + 1 : index;\n }\n\n /** Maps visual index -> logical index (handles clones at 0 and last when loop=true) */\n getLogicalIndexForVisual(vIndex) {\n const slides = this.getSlides();\n const withClones = this.getSlidesWithClones();\n if (!this.loop) return vIndex;\n if (vIndex === 0) return slides.length - 1; // leading clone\n if (vIndex === withClones.length - 1) return 0; // trailing clone\n return vIndex - 1;\n }\n\n /**\n * Goes to the slide.\n * @returns {boolean}\n */\n canGoNext() {\n const el = this.context.querySelector('.carousel-slides');\n return el.scrollLeft < (el.scrollWidth - el.clientWidth);\n }\n\n /**\n * Goes to the slide.\n * @returns {boolean}\n */\n canGoPrevious() {\n const el = this.context.querySelector('.carousel-slides');\n return el.scrollLeft > 0;\n }\n}\n","import { default as WJElement } from '../wje-element/element.js';\nimport Carousel from './carousel.element.js';\n\n// export * from \"./carousel.element.js\";\nexport default Carousel;\n\nWJElement.define('wje-carousel', Carousel);\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wje-carousel.js","sources":["../packages/wje-carousel/carousel.element.js","../packages/wje-carousel/carousel.js"],"sourcesContent":["import { default as WJElement, event } from '../wje-element/element.js';\nimport styles from './styles/styles.css?inline';\n\n/**\n * @summary Carousel class that extends WJElement.\n * @documentation https://elements.webjet.sk/components/carousel\n * @status stable\n * @augments WJElement\n * @slot - The carousel main content.\n * @cssproperty [--wje-carousel-size=100%] - Effective size of one carousel item.\n * @cssproperty [--wje-carousel-gap=0.5rem] - Gap between carousel items.\n */\nexport default class Carousel extends WJElement {\n /**\n * Carousel constructor method.\n */\n constructor() {\n super();\n\n this.slidePerPage = 1;\n }\n\n /**\n * Active slide attribute.\n * @param value\n */\n set activeSlide(value) {\n this.setAttribute('active-slide', value);\n }\n\n /**\n * Active slide attribute.\n * @returns {number|number}\n */\n get activeSlide() {\n return +this.getAttribute('active-slide') || 0;\n }\n\n /**\n * Pagination attribute.\n * @returns {boolean}\n */\n get pagination() {\n return this.hasAttribute('pagination');\n }\n\n /**\n * Navigation attribute.\n * @returns {boolean}\n */\n get navigation() {\n return this.hasAttribute('navigation');\n }\n\n /**\n * Thumbnails attribute.\n * @returns {boolean}\n */\n get thumbnails() {\n return this.hasAttribute('thumbnails');\n }\n\n /**\n * Loop attribute.\n * @returns {boolean}\n */\n get loop() {\n return this.hasAttribute('loop');\n }\n\n /**\n * Continuous loop attribute.\n * @returns {boolean}\n */\n get continuousLoop() {\n return this.hasAttribute('continuous-loop');\n }\n\n /**\n * Class name for the Carousel.\n * @type {string}\n */\n className = 'Carousel';\n\n /**\n * Getter for the CSS stylesheet.\n * @returns {*}\n */\n static get cssStyleSheet() {\n return styles;\n }\n\n /**\n * Getter for the observed attributes.\n * @returns {string[]}\n */\n static get observedAttributes() {\n return ['active-slide', 'slide-per-page', 'continuous-loop'];\n }\n\n /**\n * Sets up the attributes for the Carousel.\n * @param name\n * @param old\n * @param newName\n */\n attributeChangedCallback(name, old, newName) {\n if (name === 'active-slide') {\n if (this.pagination) this.changePagination();\n\n if (this.thumbnails) this.changeThumbnails();\n }\n\n if (['slide-per-page', 'continuous-loop'].includes(name) && old !== newName && this.slides) {\n this.syncSlideMetrics();\n\n if (this.loop) {\n this.refresh();\n return;\n }\n\n this.goToSlide(this.activeSlide, 'auto');\n }\n }\n\n /**\n * Sets up the attributes for the Carousel.\n */\n setupAttributes() {\n this.isShadowRoot = 'open';\n this.syncAria();\n }\n\n /**\n * Before draw method for the Carousel.\n */\n beforeDraw() {\n this.syncSlideMetrics();\n this.removeLoopClones();\n this.cloneFirstAndLastItems();\n }\n\n /**\n * Draw method for the Carousel.\n * @returns {DocumentFragment}\n */\n draw() {\n let fragment = document.createDocumentFragment();\n\n let native = document.createElement('div');\n native.classList.add('native-carousel');\n\n let wrapper = document.createElement('div');\n wrapper.classList.add('slides-wrapper');\n\n let slides = document.createElement('div');\n slides.classList.add('carousel-slides');\n\n let slot = document.createElement('slot');\n\n let slotPrev = document.createElement('slot');\n slotPrev.setAttribute('name', 'prev');\n\n let slotNext = document.createElement('slot');\n slotNext.setAttribute('name', 'next');\n\n slides.append(slot);\n native.append(wrapper);\n\n if (this.navigation) {\n let existingPrev = this.querySelector('[slot=\"prev\"]');\n let existingNext = this.querySelector('[slot=\"next\"]');\n\n this.prevButton = existingPrev || this.createPreviousButton();\n this.nextButton = existingNext || this.createNextButton();\n\n if (this.prevButton && !this.prevButton.dataset.wjeCarouselNavBound) {\n this.prevButton.addEventListener('click', () => this.previousSlide());\n this.prevButton.dataset.wjeCarouselNavBound = 'true';\n }\n\n if (this.nextButton && !this.nextButton.dataset.wjeCarouselNavBound) {\n this.nextButton.addEventListener('click', () => this.nextSlide());\n this.nextButton.dataset.wjeCarouselNavBound = 'true';\n }\n\n if (!existingPrev) this.append(this.prevButton);\n if (!existingNext) this.append(this.nextButton);\n\n wrapper.append(slotPrev);\n wrapper.append(slotNext);\n }\n\n wrapper.append(slides);\n\n if (this.pagination) native.append(this.createPagination());\n\n if (this.thumbnails) native.append(this.createThumbnails());\n\n fragment.append(native);\n\n this.slides = slides;\n\n return fragment;\n }\n\n /**\n * After draw method for the Carousel.\n */\n afterDraw() {\n this.setIntersectionObserver();\n this.getSlidesWithClones().forEach((slide, i) => {\n this.intersectionObserver.observe(slide);\n });\n\n this.syncSlideMetrics();\n\n this.goToSlide(this.activeSlide, 'auto');\n\n requestAnimationFrame(() => requestAnimationFrame(() => this.syncActiveToSnapStart()));\n\n this.slides.addEventListener('scrollend', (e) => {\n this.syncActiveToSnapStart();\n });\n\n this.syncAria();\n }\n\n /**\n * Sync `activeSlide` to the slide whose leading edge is closest to the snap start.\n */\n syncActiveToSnapStart() {\n const slides = this.getSlides();\n const withClones = this.getSlidesWithClones();\n if (!withClones.length) return;\n\n const containerRect = this.slides.getBoundingClientRect();\n const snapStartX = containerRect.left + this.getScrollPaddingInlineStart();\n\n let best = null;\n let bestDist = Infinity;\n withClones.forEach((el) => {\n const r = el.getBoundingClientRect();\n const dist = Math.abs(r.left - snapStartX);\n if (dist < bestDist) {\n bestDist = dist;\n best = el;\n }\n });\n\n if (!best) return;\n\n const vIndex = withClones.indexOf(best);\n if (vIndex === -1) return;\n\n const logicalIndex = this.getLogicalIndexForVisual(vIndex);\n this.activeSlide = logicalIndex;\n this.setActiveVisualSlide(vIndex);\n\n const canonicalVisualIndex = this.getVisualIndexForLogical(logicalIndex);\n if (canonicalVisualIndex !== vIndex) {\n this.goToSlide(logicalIndex, 'auto');\n }\n }\n\n /**\n * Syncs computed CSS variables derived from `slide-per-page`.\n */\n syncSlideMetrics() {\n this.slidePerPage = Math.max(parseInt(this.getAttribute('slide-per-page'), 10) || 1, 1);\n const visibleGapCount = Math.max(this.slidePerPage - 1, 0);\n const computedItemSize = `calc((100% - (${visibleGapCount} * var(--wje-carousel-gap, 0.5rem))) / ${this.slidePerPage})`;\n\n this.style.setProperty('--wje-carousel-slides-per-page', `${this.slidePerPage}`);\n this.style.setProperty('--wje-carousel-visible-gap-count', `${visibleGapCount}`);\n this.style.setProperty('--wje-carousel-size', computedItemSize);\n this.style.setProperty('--wje-carousel-item-basis', 'var(--wje-carousel-size)');\n }\n\n /**\n * Returns the inline scroll padding used by the snap area.\n * @returns {number}\n */\n getScrollPaddingInlineStart() {\n if (!this.slides) return 0;\n\n const styles = getComputedStyle(this.slides);\n return parseFloat(styles.scrollPaddingInlineStart || styles.scrollPaddingLeft || '0') || 0;\n }\n\n /**\n * Returns the interaction scroll behavior for UI controls.\n * Continuous multi-slide loops use instant snapping to avoid blank edge states\n * while the browser is still animating a previous smooth scroll.\n * @returns {ScrollBehavior|string}\n */\n getControlBehavior() {\n return this.continuousLoop && this.slidePerPage > 1 ? 'auto' : 'smooth';\n }\n\n /**\n * Sets up the IntersectionObserver for the Carousel.\n */\n setIntersectionObserver() {\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n this.entriesMap.set(entry.target, entry);\n });\n },\n {\n root: this.context.querySelector('.carousel-slides'),\n threshold: 0.5,\n }\n );\n\n this.entriesMap = new Map();\n this.records = this.intersectionObserver.takeRecords();\n this.records.forEach((entry) => {\n this.entriesMap.set(entry.target, entry);\n });\n }\n\n /**\n * Goes to the slide.\n * @param index\n * @param behavior\n * @param next\n */\n goToSlide(index, behavior = 'smooth', next = true) {\n const slides = this.getSlides();\n const withClones = this.getSlidesWithClones();\n\n // compute logical index: wrap when loop=true, else clamp\n const maxIndex = this.getMaxVisibleStartIndex(slides.length);\n let logical;\n if (this.loop && slides.length > 0) {\n logical = this.normalizeLoopIndex(index, slides.length);\n } else {\n logical = Math.min(Math.max(index, 0), maxIndex);\n }\n this.activeSlide = logical;\n\n // compute visual target considering clones when loop=true\n const vIndex = this.getVisualIndexForLogical(logical);\n const targetEl = withClones[vIndex];\n if (!targetEl) return;\n\n this.setActiveVisualSlide(vIndex);\n this.scrollToVisualIndex(vIndex, behavior);\n\n if (this.navigation && !this.loop) {\n this.nextButton.removeAttribute('disabled');\n this.prevButton.removeAttribute('disabled');\n\n if (this.activeSlide === maxIndex) this.nextButton.setAttribute('disabled', '');\n if (this.activeSlide === 0) this.prevButton.setAttribute('disabled', '');\n }\n\n this.syncAria();\n }\n\n /**\n * Sets the active class on the currently targeted visual slide and removes it elsewhere.\n * @param {number} vIndex\n */\n setActiveVisualSlide(vIndex) {\n this.getSlidesWithClones().forEach((slide, index) => {\n slide.classList.toggle('active', index === vIndex);\n });\n }\n\n /**\n * Syncs ARIA attributes on the carousel and slides.\n */\n syncAria() {\n this.setAriaState({\n role: 'region',\n roledescription: 'carousel',\n });\n\n const slides = this.getSlides();\n const total = slides.length;\n slides.forEach((slide, index) => {\n slide.setAttribute('role', 'group');\n slide.setAttribute('aria-roledescription', 'slide');\n slide.setAttribute('aria-label', `Slide ${index + 1} of ${total}`);\n slide.setAttribute('aria-hidden', slide.classList.contains('active') ? 'false' : 'true');\n });\n\n const clones = this.querySelectorAll('.clone');\n clones.forEach((slide) => {\n slide.setAttribute('aria-hidden', 'true');\n });\n }\n\n /**\n * Clones the first and last items.\n */\n cloneFirstAndLastItems() {\n const items = this.getSlides();\n\n if (items.length && this.loop) {\n const cloneCount = this.getLoopCloneCount(items.length);\n const firstOriginal = items[0];\n\n items.slice(items.length - cloneCount).forEach((item) => {\n const clone = this.createLoopClone(item);\n this.insertBefore(clone, firstOriginal);\n });\n\n items.slice(0, cloneCount).forEach((item) => {\n const clone = this.createLoopClone(item);\n this.append(clone);\n });\n }\n }\n\n /**\n * Creates a sanitized loop clone that does not inherit transient render state\n * such as inline `visibility: hidden` from the source slide.\n * @param {HTMLElement} item\n * @returns {HTMLElement}\n */\n createLoopClone(item) {\n const clone = item.cloneNode(true);\n clone.classList.add('clone');\n clone.classList.remove('active');\n clone.style.removeProperty('visibility');\n\n if (!clone.getAttribute('style')?.trim()) {\n clone.removeAttribute('style');\n }\n\n return clone;\n }\n\n /**\n * Removes loop clones so they can be rebuilt for the current configuration.\n */\n removeLoopClones() {\n this.querySelectorAll('wje-carousel-item.clone').forEach((clone) => clone.remove());\n }\n\n /**\n * Returns how many slides should be cloned on each side when loop is enabled.\n * @param {number} totalSlides\n * @returns {number}\n */\n getLoopCloneCount(totalSlides = this.getSlides().length) {\n if (!this.loop || !totalSlides) return 0;\n\n return this.continuousLoop ? Math.min(this.slidePerPage, totalSlides) : 1;\n }\n\n /**\n * Scrolls the carousel to a visual slide index.\n * @param {number} vIndex\n * @param {ScrollBehavior|string} behavior\n */\n scrollToVisualIndex(vIndex, behavior = 'smooth') {\n const withClones = this.getSlidesWithClones();\n const firstEl = withClones[0];\n const targetEl = withClones[vIndex];\n\n if (!firstEl || !targetEl || !this.slides) return;\n\n const firstRect = firstEl.getBoundingClientRect();\n const targetRect = targetEl.getBoundingClientRect();\n const contentOffsetLeft = targetRect.left - firstRect.left;\n const nextLeft = contentOffsetLeft - this.getScrollPaddingInlineStart();\n const targetLeft = Math.max(nextLeft, 0);\n\n if (behavior === 'smooth') {\n this.slides.scrollTo({\n left: targetLeft,\n top: this.slides.scrollTop,\n behavior: 'smooth',\n });\n return;\n }\n\n if (this.snapRestoreFrame) {\n cancelAnimationFrame(this.snapRestoreFrame);\n }\n\n const inlineSnapType = this.slides.style.scrollSnapType;\n this.slides.style.scrollSnapType = 'none';\n this.slides.scrollTo({\n left: targetLeft,\n top: this.slides.scrollTop,\n behavior: 'auto',\n });\n this.snapRestoreFrame = requestAnimationFrame(() => {\n this.slides.style.scrollSnapType = inlineSnapType;\n this.snapRestoreFrame = null;\n });\n }\n\n /**\n * Goes to the next slide.\n */\n removeActiveSlide() {\n this.getSlidesWithClones().forEach((slide, i) => {\n slide.classList.remove('active');\n });\n\n if (this.pagination) {\n this.context.querySelectorAll('.pagination-item').forEach((item) => {\n item.classList.remove('active');\n });\n }\n\n if (this.thumbnails) {\n this.context.querySelectorAll('wje-thumbnail').forEach((item) => {\n item.classList.remove('active');\n });\n }\n }\n\n /**\n * Goes to the next slide.\n */\n changePagination() {\n if (this.pagination) {\n this.context.querySelectorAll('.pagination-item').forEach((item, i) => {\n item.classList.toggle('active', i === this.activeSlide);\n });\n }\n }\n\n /**\n * Goes to the next slide.\n */\n changeThumbnails() {\n if (this.thumbnails) {\n this.context.querySelectorAll('wje-thumbnail').forEach((item, i) => {\n item.classList.toggle('active', i === this.activeSlide);\n });\n }\n }\n\n /**\n * Goes to the next slide.\n * @returns {Element}\n */\n createNextButton() {\n const nextButton = document.createElement('wje-button');\n nextButton.setAttribute('part', 'next-button');\n nextButton.setAttribute('circle', '');\n nextButton.setAttribute('fill', 'link');\n nextButton.setAttribute('slot', 'next');\n nextButton.innerHTML = '<wje-icon name=\"chevron-right\" size=\"large\"></wje-icon>';\n nextButton.classList.add('next');\n\n return nextButton;\n }\n\n /**\n * Goes to the next slide.\n * @returns {Element}\n */\n createPreviousButton() {\n const previousButton = document.createElement('wje-button');\n previousButton.setAttribute('part', 'previous-button');\n previousButton.setAttribute('circle', '');\n previousButton.setAttribute('fill', 'link');\n previousButton.setAttribute('slot', 'prev');\n previousButton.innerHTML = '<wje-icon name=\"chevron-left\" size=\"large\"></wje-icon>';\n previousButton.classList.add('prev');\n\n return previousButton;\n }\n\n /**\n * Goes to the next slide.\n * @returns {Element}\n */\n createPagination() {\n const pagination = document.createElement('div');\n pagination.setAttribute('part', 'pagination');\n pagination.classList.add('pagination');\n\n this.getPaginationIndexes().forEach((i) => {\n const paginationItem = document.createElement('div');\n paginationItem.classList.add('pagination-item');\n paginationItem.addEventListener('click', (e) => {\n this.removeActiveSlide();\n e.target.classList.add('active');\n this.goToSlide(i, this.getControlBehavior());\n });\n pagination.append(paginationItem);\n });\n\n return pagination;\n }\n\n /**\n * Goes to the next slide.\n * @returns {Element}\n */\n createThumbnails() {\n const thumbnails = document.createElement('div');\n thumbnails.classList.add('thumbnails');\n\n const slides = this.getSlides();\n slides.forEach((slide, i) => {\n const thumbnail = document.createElement('wje-thumbnail');\n thumbnail.innerHTML = `<img src=\"${slide.querySelector('wje-img').getAttribute('src')}\"></img>`;\n thumbnail.addEventListener('click', (e) => {\n this.removeActiveSlide();\n e.target.closest('wje-thumbnail').classList.add('active');\n this.goToSlide(i, this.getControlBehavior());\n });\n thumbnails.append(thumbnail);\n });\n\n return thumbnails;\n }\n\n /**\n * Goes to the next slide.\n */\n nextSlide() {\n this.goToSlide(this.activeSlide + 1, this.getControlBehavior());\n }\n\n /**\n * Goes to the previous slide.\n */\n previousSlide() {\n this.goToSlide(this.activeSlide - 1, this.getControlBehavior());\n }\n\n /**\n * Goes to the slide.\n * @returns {Array}\n */\n getSlides() {\n return Array.from(this.querySelectorAll('wje-carousel-item:not(.clone)'));\n }\n\n /**\n * Goes to the slide.\n * @returns {Array}\n */\n getSlidesWithClones() {\n return Array.from(this.querySelectorAll('wje-carousel-item'));\n }\n\n /** Maps logical index -> visual index (accounts for leading clone when loop=true) */\n getVisualIndexForLogical(index) {\n return this.loop ? index + this.getLoopCloneCount() : index;\n }\n\n /** Maps visual index -> logical index (handles clones at 0 and last when loop=true) */\n getLogicalIndexForVisual(vIndex) {\n const slides = this.getSlides();\n const maxIndex = this.getMaxVisibleStartIndex(slides.length);\n const cloneCount = this.getLoopCloneCount(slides.length);\n if (!this.loop) return Math.min(Math.max(vIndex, 0), maxIndex);\n if (this.continuousLoop) {\n if (vIndex < cloneCount) return slides.length - cloneCount + vIndex;\n if (vIndex >= cloneCount + slides.length) return vIndex - (cloneCount + slides.length);\n return vIndex - cloneCount;\n }\n\n if (vIndex < cloneCount) return maxIndex;\n if (vIndex >= cloneCount + slides.length) return 0;\n return Math.min(Math.max(vIndex - cloneCount, 0), maxIndex);\n }\n\n /**\n * Returns the maximum logical slide index that can still render a full viewport.\n * @param {number} totalSlides\n * @returns {number}\n */\n getMaxVisibleStartIndex(totalSlides = this.getSlides().length) {\n const visibleSlides = Math.min(this.slidePerPage, totalSlides);\n return Math.max(totalSlides - visibleSlides, 0);\n }\n\n /**\n * Normalizes a logical index for the active loop mode.\n * @param {number} index\n * @param {number} totalSlides\n * @returns {number}\n */\n normalizeLoopIndex(index, totalSlides = this.getSlides().length) {\n const logicalCount = this.getLoopLogicalCount(totalSlides);\n if (!logicalCount) return 0;\n\n return ((index % logicalCount) + logicalCount) % logicalCount;\n }\n\n /**\n * Returns how many logical positions are reachable for the current loop mode.\n * @param {number} totalSlides\n * @returns {number}\n */\n getLoopLogicalCount(totalSlides = this.getSlides().length) {\n if (!totalSlides) return 0;\n\n return this.continuousLoop ? totalSlides : this.getMaxVisibleStartIndex(totalSlides) + 1;\n }\n\n /**\n * Returns the pagination indexes for the current carousel mode.\n * @returns {number[]}\n */\n getPaginationIndexes() {\n return Array.from({ length: this.getLoopLogicalCount() }, (_, index) => index);\n }\n\n /**\n * Goes to the slide.\n * @returns {boolean}\n */\n canGoNext() {\n const el = this.context.querySelector('.carousel-slides');\n return el.scrollLeft < (el.scrollWidth - el.clientWidth);\n }\n\n /**\n * Goes to the slide.\n * @returns {boolean}\n */\n canGoPrevious() {\n const el = this.context.querySelector('.carousel-slides');\n return el.scrollLeft > 0;\n }\n}\n","import { default as WJElement } from '../wje-element/element.js';\nimport Carousel from './carousel.element.js';\n\n// export * from \"./carousel.element.js\";\nexport default Carousel;\n\nWJElement.define('wje-carousel', Carousel);\n"],"names":["styles"],"mappings":"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"}
|
package/dist/wje-element.js
CHANGED
|
@@ -574,7 +574,7 @@ const _WJElement = class _WJElement extends HTMLElement {
|
|
|
574
574
|
this.replaceChildren(frag);
|
|
575
575
|
}
|
|
576
576
|
skeletonShownAt = performance.now();
|
|
577
|
-
this.dispatchEvent(new CustomEvent("wj
|
|
577
|
+
this.dispatchEvent(new CustomEvent("wj-skeleton:show", {
|
|
578
578
|
detail: { delay: this.skeletonDelay },
|
|
579
579
|
bubbles: true,
|
|
580
580
|
composed: true
|
|
@@ -599,7 +599,7 @@ const _WJElement = class _WJElement extends HTMLElement {
|
|
|
599
599
|
clearSkeletonTimer();
|
|
600
600
|
if (skeletonShownAt === null) {
|
|
601
601
|
const elapsed = skeletonPlannedAt ? performance.now() - skeletonPlannedAt : 0;
|
|
602
|
-
this.dispatchEvent(new CustomEvent("wj
|
|
602
|
+
this.dispatchEvent(new CustomEvent("wj-skeleton:skip", {
|
|
603
603
|
detail: { reason: "render-finished-fast", elapsedMs: elapsed, delay: this.skeletonDelay },
|
|
604
604
|
bubbles: true,
|
|
605
605
|
composed: true
|
|
@@ -618,7 +618,7 @@ const _WJElement = class _WJElement extends HTMLElement {
|
|
|
618
618
|
this.replaceChildren(nextContext);
|
|
619
619
|
}
|
|
620
620
|
if (skeletonShownAt !== null) {
|
|
621
|
-
this.dispatchEvent(new CustomEvent("wj
|
|
621
|
+
this.dispatchEvent(new CustomEvent("wj-skeleton:hide", {
|
|
622
622
|
detail: {
|
|
623
623
|
reason: "render-finished",
|
|
624
624
|
visibleMs: Math.max(this.skeletonMinDuration, performance.now() - skeletonShownAt),
|
|
@@ -638,7 +638,7 @@ const _WJElement = class _WJElement extends HTMLElement {
|
|
|
638
638
|
renderFinished = true;
|
|
639
639
|
clearSkeletonTimer();
|
|
640
640
|
if (!__privateGet(this, _isRendering)) {
|
|
641
|
-
this.dispatchEvent(new CustomEvent("wj
|
|
641
|
+
this.dispatchEvent(new CustomEvent("wj-skeleton:hide", {
|
|
642
642
|
detail: { reason: "finally" },
|
|
643
643
|
bubbles: true,
|
|
644
644
|
composed: true
|