@aurodesignsystem-dev/auro-slideshow 0.0.0-pr21.0 → 0.0.0-pr22.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/demo/api.html +1 -1
- package/demo/api.md +23 -0
- package/demo/auro-slideshow.min.js +275 -131
- package/dist/auro-slideshow-CJw31Ppp.js +109 -0
- package/dist/index.d.ts +14 -6
- package/dist/index.js +1 -1
- package/dist/registered.js +1 -1
- package/package.json +10 -8
- package/dist/auro-slideshow-Cmdb_wIX.js +0 -105
|
@@ -2724,7 +2724,6 @@ let AuroElement$1 = class AuroElement extends i$2 {
|
|
|
2724
2724
|
* @private
|
|
2725
2725
|
*/
|
|
2726
2726
|
wrapper: {
|
|
2727
|
-
type: HTMLElement,
|
|
2728
2727
|
attribute: false,
|
|
2729
2728
|
reflect: false
|
|
2730
2729
|
}
|
|
@@ -3200,13 +3199,23 @@ class AuroButton extends AuroElement$1 {
|
|
|
3200
3199
|
},
|
|
3201
3200
|
|
|
3202
3201
|
/**
|
|
3203
|
-
* Populates `
|
|
3202
|
+
* Populates `tabindex` to define the focusable sequence in keyboard navigation.
|
|
3204
3203
|
*/
|
|
3205
3204
|
tIndex: {
|
|
3206
3205
|
type: String,
|
|
3207
3206
|
reflect: true
|
|
3208
3207
|
},
|
|
3209
3208
|
|
|
3209
|
+
/**
|
|
3210
|
+
* Populates `tabindex` to define the focusable sequence in keyboard navigation.
|
|
3211
|
+
* Must be used with "." to ensure the host element does not retain a reference to the `tabindex` attribute.
|
|
3212
|
+
* Example: `<auro-button .tabindex="${this.disabled ? '-1' : '0'}"></auro-button>`
|
|
3213
|
+
*/
|
|
3214
|
+
tabindex: {
|
|
3215
|
+
type: String,
|
|
3216
|
+
reflect: false
|
|
3217
|
+
},
|
|
3218
|
+
|
|
3210
3219
|
/**
|
|
3211
3220
|
* Sets title attribute. The information is most often shown as a tooltip text when the mouse moves over the element.
|
|
3212
3221
|
*/
|
|
@@ -3358,7 +3367,7 @@ class AuroButton extends AuroElement$1 {
|
|
|
3358
3367
|
part="${part}"
|
|
3359
3368
|
aria-label="${o(this.loading ? this.loadingText : this.currentAriaLabel || undefined)}"
|
|
3360
3369
|
aria-labelledby="${o(this.loading ? undefined : this.currentAriaLabelledBy || undefined)}"
|
|
3361
|
-
|
|
3370
|
+
tabindex="${o(this.tIndex || this.tabindex)}"
|
|
3362
3371
|
?autofocus="${this.autofocus}"
|
|
3363
3372
|
class=${e(classes)}
|
|
3364
3373
|
?disabled="${this.disabled || this.loading}"
|
|
@@ -3394,7 +3403,7 @@ class AuroButton extends AuroElement$1 {
|
|
|
3394
3403
|
}
|
|
3395
3404
|
}
|
|
3396
3405
|
|
|
3397
|
-
var buttonVersion = "
|
|
3406
|
+
var buttonVersion = "11.2.1";
|
|
3398
3407
|
|
|
3399
3408
|
var chevronLeft = {"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" aria-labelledby=\"chevron-left__desc\" class=\"ico_squareLarge\" role=\"img\" style=\"min-width:var(--auro-size-lg, var(--ds-size-300, 1.5rem));height:var(--auro-size-lg, var(--ds-size-300, 1.5rem));fill:currentColor\" viewBox=\"0 0 24 24\" part=\"svg\"><title/><desc id=\"chevron-left__desc\">Directional indicator; left.</desc><path d=\"m14.395 6.345.084.073a.75.75 0 0 1 .072.977l-.072.084-4.47 4.47 4.47 4.47a.75.75 0 0 1 .072.976l-.072.084a.75.75 0 0 1-.977.072l-.084-.072-4.823-4.823a1 1 0 0 1 0-1.415l4.823-4.823a.75.75 0 0 1 .977-.073\"/></svg>"};
|
|
3400
3409
|
|
|
@@ -3799,15 +3808,24 @@ class AuroIcon extends BaseIcon {
|
|
|
3799
3808
|
}
|
|
3800
3809
|
}
|
|
3801
3810
|
|
|
3802
|
-
var iconVersion = "8.0.
|
|
3811
|
+
var iconVersion = "8.0.4";
|
|
3803
3812
|
|
|
3804
|
-
var styleCss = i$5`:host{--border-size: 6px;--border-radius: 24px}.container{display:flex;width:100%;flex-direction:column;align-items:flex-start}.slideshow-wrapper{position:relative;width:100%;
|
|
3813
|
+
var styleCss = i$5`:host{--border-size: 6px;--border-radius: 24px}.container{display:flex;width:100%;flex-direction:column;align-items:flex-start}.slideshow-wrapper{position:relative;display:flex;width:100%;overflow:hidden;align-items:center;justify-content:start;padding:var(--border-size)}.embla{max-width:100%;margin:0;--slide-size: 100%}.embla__container{display:flex}.embla__slide{transform:translateZ(0);min-width:0;flex:0 0 var(--slide-size);border-radius:var(--border-radius);box-sizing:border-box;margin-right:1rem;overflow:hidden}.embla__slide:focus-visible{outline:unset;box-shadow:0 0 0 2px var(--ds-basic-color-border-inverse, #ffffff),0 0 0 var(--border-size) var(--ds-advanced-color-state-focused, #01426a)}.embla__slide:not(.active):not(.in-view){filter:brightness(30%)}.scroll-prev,.scroll-next{position:absolute;display:none;top:50%;transform:translateY(-50%);z-index:10;--ds-auro-button-container-color: var(--ds-advanced-color-state-focused, #01426a);--ds-auro-button-container-image: var(--ds-advanced-color-state-focused, #01426a);color:var(--ds-advanced-color-shared-background, #ffffff)}.scroll-prev:hover,.scroll-next:hover{--ds-auro-button-container-color: var(--ds-advanced-color-button-primary-background-inverse-hover, #ebf3f9)}.scroll-prev{left:8px}.scroll-next{right:8px}.slideshow-wrapper:hover .scroll-prev,.slideshow-wrapper:hover .scroll-next{display:block}.pagination-container{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;width:100%;margin-top:40px;gap:14px}.embla__dots{display:flex;gap:16px}.embla__dot{width:12px;height:12px;border-radius:50%;border:none;background-color:var(--ds-advanced-color-button-primary-background-inactive, #cfe0ef);position:relative;cursor:pointer;transition:all .3s ease-in-out}.embla__dot:hover:not(.embla__dot--selected){background-color:var(--ds-advanced-color-button-primary-background-inactive-hover, #89b2d4)}.embla__dot:before{content:"";width:24px;height:24px;position:absolute;cursor:pointer;top:50%;left:50%;transform:translate(-50%,-50%)}.embla__dot--selected{width:52px;height:12px;border-radius:1.8rem;background-color:var(--ds-advanced-color-button-primary-background, #01426a)}.embla__dot--selected:before{width:64px}.embla__progress{width:52px;height:12px;border-radius:1.8rem;border:none;background-color:var(--ds-advanced-color-button-primary-background-inactive, #cfe0ef);position:relative;overflow:hidden;cursor:pointer;align-self:center;justify-self:center;transition:all .3s ease-in-out}.embla__progress:hover:not(.stopped){background-color:var(--ds-advanced-color-button-primary-background-inactive-hover, #89b2d4)}.embla__progress__bar{border-radius:inherit;background-color:var(--ds-advanced-color-button-primary-background, #01426a);position:absolute;width:100%;top:0;bottom:0;left:-100%;animation-name:autoplay-progress;animation-timing-function:linear;animation-iteration-count:1;animation-play-state:running}.embla__progress--paused .embla__progress__bar{animation-play-state:paused}.stopped{background-color:var(--ds-advanced-color-button-primary-background, #01426a)}@keyframes autoplay-progress{0%{transform:translateZ(0)}to{transform:translate3d(100%,0,0)}}
|
|
3805
3814
|
`;
|
|
3806
3815
|
|
|
3807
3816
|
// Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
|
|
3808
3817
|
// See LICENSE in the project root for license information.
|
|
3809
3818
|
|
|
3810
3819
|
|
|
3820
|
+
/**
|
|
3821
|
+
* The auro-slideshow component is a customizable slideshow that displays a series of slides
|
|
3822
|
+
* with several options such as autoplay, navigation controls, and pagination dots.
|
|
3823
|
+
*
|
|
3824
|
+
* @slot - Default slot for the slides. Each child element will be treated as a slide.
|
|
3825
|
+
* @csspart prev-button - Use to style the previous button control.
|
|
3826
|
+
* @csspart next-button - Use to style the next button control.
|
|
3827
|
+
* @csspart play-pause-button - Use to style the play/pause button control.
|
|
3828
|
+
*/
|
|
3811
3829
|
class AuroSlideshow extends i$2 {
|
|
3812
3830
|
constructor() {
|
|
3813
3831
|
super();
|
|
@@ -3964,6 +3982,14 @@ class AuroSlideshow extends i$2 {
|
|
|
3964
3982
|
return this.shadowRoot.querySelector(".play-pause");
|
|
3965
3983
|
}
|
|
3966
3984
|
|
|
3985
|
+
get _prevBtn() {
|
|
3986
|
+
return this.shadowRoot.querySelector(".scroll-prev");
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3989
|
+
get _nextBtn() {
|
|
3990
|
+
return this.shadowRoot.querySelector(".scroll-next");
|
|
3991
|
+
}
|
|
3992
|
+
|
|
3967
3993
|
get _dotsNode() {
|
|
3968
3994
|
return this.shadowRoot.querySelector(".embla__dots");
|
|
3969
3995
|
}
|
|
@@ -3972,7 +3998,54 @@ class AuroSlideshow extends i$2 {
|
|
|
3972
3998
|
return this.shadowRoot.querySelector(".embla__progress");
|
|
3973
3999
|
}
|
|
3974
4000
|
|
|
3975
|
-
|
|
4001
|
+
// ========== PUBLIC METHODS =================
|
|
4002
|
+
|
|
4003
|
+
/**
|
|
4004
|
+
* Starts the slideshow playback.
|
|
4005
|
+
* @returns {void}
|
|
4006
|
+
*/
|
|
4007
|
+
play() {
|
|
4008
|
+
if (this.autoplay) {
|
|
4009
|
+
this.embla?.plugins()?.autoplay.play();
|
|
4010
|
+
} else if (this.autoScroll) {
|
|
4011
|
+
this.embla?.plugins()?.autoScroll.play();
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
|
|
4015
|
+
/**
|
|
4016
|
+
* Stops the slideshow playback.
|
|
4017
|
+
* @returns {void}
|
|
4018
|
+
*/
|
|
4019
|
+
stop() {
|
|
4020
|
+
if (this.autoplay) {
|
|
4021
|
+
this.embla?.plugins()?.autoplay.stop();
|
|
4022
|
+
} else if (this.autoScroll) {
|
|
4023
|
+
this.embla?.plugins()?.autoScroll.stop();
|
|
4024
|
+
}
|
|
4025
|
+
}
|
|
4026
|
+
|
|
4027
|
+
/**
|
|
4028
|
+
* Scrolls to the previous slide.
|
|
4029
|
+
* @returns {void}
|
|
4030
|
+
*/
|
|
4031
|
+
scrollPrev() {
|
|
4032
|
+
this.embla.scrollPrev();
|
|
4033
|
+
}
|
|
4034
|
+
|
|
4035
|
+
/**
|
|
4036
|
+
* Scrolls to the next slide.
|
|
4037
|
+
* @returns {void}
|
|
4038
|
+
*/
|
|
4039
|
+
scrollNext() {
|
|
4040
|
+
this.embla.scrollNext();
|
|
4041
|
+
}
|
|
4042
|
+
|
|
4043
|
+
// ========== PRIVATE METHODS =================
|
|
4044
|
+
|
|
4045
|
+
/**
|
|
4046
|
+
* @private
|
|
4047
|
+
* Initializes the Embla carousel with the provided options and plugins.
|
|
4048
|
+
*/
|
|
3976
4049
|
initializeEmbla() {
|
|
3977
4050
|
const emblaNode = this.shadowRoot.querySelector(".embla");
|
|
3978
4051
|
const options = { loop: this.loop, align: "start" };
|
|
@@ -3989,6 +4062,7 @@ class AuroSlideshow extends i$2 {
|
|
|
3989
4062
|
playOnInit: this.playOnInit,
|
|
3990
4063
|
delay: this.delay,
|
|
3991
4064
|
stopOnMouseEnter: true,
|
|
4065
|
+
stopOnLastSnap: !this.loop,
|
|
3992
4066
|
};
|
|
3993
4067
|
|
|
3994
4068
|
const autoscrollOptions = {
|
|
@@ -4000,17 +4074,17 @@ class AuroSlideshow extends i$2 {
|
|
|
4000
4074
|
|
|
4001
4075
|
const plugins = [ClassNames(classNamesOptions)];
|
|
4002
4076
|
|
|
4003
|
-
//
|
|
4077
|
+
// Prevent both autoplay and autoScroll from being used simultaneously.
|
|
4004
4078
|
if (this.autoplay && this.autoScroll) {
|
|
4005
4079
|
console.warn(
|
|
4006
|
-
"Autoplay and AutoScroll are not meant to be used together.
|
|
4080
|
+
"Autoplay and AutoScroll are not meant to be used together. AutoScroll has been disabled.",
|
|
4007
4081
|
);
|
|
4008
4082
|
this.autoScroll = false;
|
|
4009
4083
|
}
|
|
4010
4084
|
if (this.autoplay) {
|
|
4011
4085
|
plugins.push(Autoplay(autoplayOptions));
|
|
4012
4086
|
}
|
|
4013
|
-
if (this.autoScroll) {
|
|
4087
|
+
if (this.autoScroll && !this.isTouchDevice()) {
|
|
4014
4088
|
plugins.push(AutoScroll(autoscrollOptions));
|
|
4015
4089
|
}
|
|
4016
4090
|
|
|
@@ -4021,43 +4095,57 @@ class AuroSlideshow extends i$2 {
|
|
|
4021
4095
|
this.addDotBtnsAndClickHandlers(
|
|
4022
4096
|
this.embla,
|
|
4023
4097
|
this._dotsNode,
|
|
4024
|
-
this.
|
|
4098
|
+
this.stopAutoplayOnInteraction,
|
|
4025
4099
|
);
|
|
4026
4100
|
}
|
|
4027
4101
|
|
|
4102
|
+
if (this.navigation && !this.isTouchDevice()) {
|
|
4103
|
+
this.embla
|
|
4104
|
+
.on("select", this.toggleNavBtnsState)
|
|
4105
|
+
.on("init", this.toggleNavBtnsState)
|
|
4106
|
+
.on("reInit", this.toggleNavBtnsState);
|
|
4107
|
+
}
|
|
4108
|
+
|
|
4028
4109
|
if (this.autoplay) {
|
|
4029
|
-
this.addAutoPlayBtnListener(this.embla, this._playBtn);
|
|
4030
4110
|
this.embla
|
|
4031
|
-
.on("autoplay:stop",
|
|
4032
|
-
|
|
4033
|
-
})
|
|
4034
|
-
.on("autoplay:play", () => {
|
|
4035
|
-
this.isPlaying = true;
|
|
4036
|
-
});
|
|
4111
|
+
.on("autoplay:stop", this.togglePlayButtonOnStop)
|
|
4112
|
+
.on("autoplay:play", this.togglePlayButtonOnPlay);
|
|
4037
4113
|
}
|
|
4038
4114
|
|
|
4039
|
-
if (this.autoScroll) {
|
|
4040
|
-
this.addAutoScrollBtnListener(this.embla, this._playBtn);
|
|
4115
|
+
if (this.autoScroll && !this.isTouchDevice()) {
|
|
4041
4116
|
this.embla
|
|
4042
|
-
.on("autoScroll:stop",
|
|
4043
|
-
|
|
4044
|
-
})
|
|
4045
|
-
.on("autoScroll:play", () => {
|
|
4046
|
-
this.isPlaying = true;
|
|
4047
|
-
});
|
|
4117
|
+
.on("autoScroll:stop", this.togglePlayButtonOnStop)
|
|
4118
|
+
.on("autoScroll:play", this.togglePlayButtonOnPlay);
|
|
4048
4119
|
}
|
|
4049
4120
|
}
|
|
4050
4121
|
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4122
|
+
/**
|
|
4123
|
+
* @private
|
|
4124
|
+
* Gets slides from the slot, adds necessary classes and event listeners,
|
|
4125
|
+
* and updates the Embla instance with the new slides.
|
|
4126
|
+
*/
|
|
4127
|
+
updateSlides() {
|
|
4128
|
+
if (this._slot) {
|
|
4129
|
+
this.slides = Array.from(this._slot.assignedElements());
|
|
4130
|
+
|
|
4131
|
+
this.slides.forEach((element, index) => {
|
|
4132
|
+
element.classList.add("embla__slide");
|
|
4133
|
+
element.addEventListener("keydown", this.handleKeydown);
|
|
4134
|
+
if (index === 0) {
|
|
4135
|
+
element.setAttribute("tabindex", "0");
|
|
4136
|
+
} else {
|
|
4137
|
+
element.setAttribute("tabindex", "-1");
|
|
4138
|
+
}
|
|
4139
|
+
});
|
|
4057
4140
|
|
|
4058
|
-
|
|
4141
|
+
// Attach slides to the Embla instance
|
|
4142
|
+
const emblaContainer = this.shadowRoot.querySelector(".embla__container");
|
|
4143
|
+
emblaContainer.replaceChildren(...this.slides);
|
|
4144
|
+
}
|
|
4059
4145
|
}
|
|
4060
4146
|
|
|
4147
|
+
// ========== PRIVATE HELPER METHODS =================
|
|
4148
|
+
|
|
4061
4149
|
/**
|
|
4062
4150
|
* @private
|
|
4063
4151
|
* Toggles the tabindex attribute on the active slide to allow keyboard navigation.
|
|
@@ -4072,130 +4160,137 @@ class AuroSlideshow extends i$2 {
|
|
|
4072
4160
|
|
|
4073
4161
|
/**
|
|
4074
4162
|
* @private
|
|
4075
|
-
*
|
|
4163
|
+
* Toggles the icon and aria-label of the play button to stopped state.
|
|
4076
4164
|
*/
|
|
4077
|
-
|
|
4078
|
-
this.
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
if (this.embla) {
|
|
4082
|
-
this.embla.reInit();
|
|
4083
|
-
}
|
|
4084
|
-
}
|
|
4165
|
+
togglePlayButtonOnStop = () => {
|
|
4166
|
+
this.isPlaying = false;
|
|
4167
|
+
this.playBtnLabel = this.playLabel;
|
|
4168
|
+
};
|
|
4085
4169
|
|
|
4086
4170
|
/**
|
|
4087
4171
|
* @private
|
|
4088
|
-
*
|
|
4089
|
-
* @returns {void}
|
|
4172
|
+
* Toggles the icon and aria-label of the play button to playing state.
|
|
4090
4173
|
*/
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
const activeSlide = this.slides[this.embla.selectedScrollSnap()];
|
|
4095
|
-
activeSlide.focus();
|
|
4096
|
-
}, 200);
|
|
4097
|
-
};
|
|
4098
|
-
if (event.key === "ArrowLeft") {
|
|
4099
|
-
event.preventDefault();
|
|
4100
|
-
this.embla.scrollPrev();
|
|
4101
|
-
focusActiveSlide();
|
|
4102
|
-
} else if (event.key === "ArrowRight") {
|
|
4103
|
-
event.preventDefault();
|
|
4104
|
-
this.embla.scrollNext();
|
|
4105
|
-
focusActiveSlide();
|
|
4106
|
-
}
|
|
4174
|
+
togglePlayButtonOnPlay = () => {
|
|
4175
|
+
this.isPlaying = true;
|
|
4176
|
+
this.playBtnLabel = this.pauseLabel;
|
|
4107
4177
|
};
|
|
4108
4178
|
|
|
4109
|
-
/**
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4179
|
+
/**
|
|
4180
|
+
* @private
|
|
4181
|
+
* Adds and removes disabled attribute if at the beginning or end of the slideshow and loop is off.
|
|
4182
|
+
*/
|
|
4183
|
+
toggleNavBtnsState = () => {
|
|
4184
|
+
if (this.embla.canScrollPrev()) {
|
|
4185
|
+
this._prevBtn.removeAttribute("disabled");
|
|
4186
|
+
} else {
|
|
4187
|
+
this._prevBtn.setAttribute("disabled", "");
|
|
4113
4188
|
}
|
|
4114
4189
|
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
element.setAttribute("tabindex", "0");
|
|
4122
|
-
} else {
|
|
4123
|
-
element.setAttribute("tabindex", "-1");
|
|
4124
|
-
}
|
|
4125
|
-
});
|
|
4126
|
-
|
|
4127
|
-
// Attach slides to the Embla instance
|
|
4128
|
-
const emblaContainer = this.shadowRoot.querySelector(".embla__container");
|
|
4129
|
-
emblaContainer.replaceChildren(...this.slides);
|
|
4130
|
-
}
|
|
4190
|
+
if (this.embla.canScrollNext()) {
|
|
4191
|
+
this._nextBtn.removeAttribute("disabled");
|
|
4192
|
+
} else {
|
|
4193
|
+
this._nextBtn.setAttribute("disabled", "");
|
|
4194
|
+
}
|
|
4195
|
+
};
|
|
4131
4196
|
|
|
4132
4197
|
/**
|
|
4133
4198
|
* @private
|
|
4134
|
-
* Stops autoplay when the user interacts with the navigation
|
|
4199
|
+
* Stops autoplay when the user interacts with the navigation controls or pagination dots.
|
|
4135
4200
|
*/
|
|
4136
|
-
|
|
4201
|
+
stopAutoplayOnInteraction = (emblaApi) => {
|
|
4137
4202
|
const autoplay = emblaApi?.plugins()?.autoplay;
|
|
4138
4203
|
if (!autoplay) return;
|
|
4139
4204
|
|
|
4140
|
-
|
|
4141
|
-
autoplay.options.stopOnInteraction === false
|
|
4142
|
-
? autoplay.reset
|
|
4143
|
-
: autoplay.stop;
|
|
4144
|
-
|
|
4145
|
-
resetOrStop();
|
|
4205
|
+
autoplay.stop();
|
|
4146
4206
|
};
|
|
4147
4207
|
|
|
4148
4208
|
/**
|
|
4149
4209
|
* @private
|
|
4150
|
-
*
|
|
4210
|
+
* Checks to see if the user is on a touch device.
|
|
4211
|
+
* @returns {boolean} True if touch device, false otherwise.
|
|
4151
4212
|
*/
|
|
4152
|
-
|
|
4153
|
-
|
|
4213
|
+
isTouchDevice() {
|
|
4214
|
+
return window.matchMedia("(pointer: coarse)").matches;
|
|
4215
|
+
}
|
|
4154
4216
|
|
|
4155
|
-
|
|
4156
|
-
const control = emblaApi?.plugins()?.[plugin];
|
|
4157
|
-
if (!control) return;
|
|
4217
|
+
// ========== EVENT HANDLERS =================
|
|
4158
4218
|
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4219
|
+
/**
|
|
4220
|
+
* @private
|
|
4221
|
+
* Handles the slot change event to update slides and initialize or reinitialize Embla.
|
|
4222
|
+
* If the slot is empty, it will not initialize Embla.
|
|
4223
|
+
*/
|
|
4224
|
+
handleSlotChange() {
|
|
4225
|
+
this.updateSlides();
|
|
4163
4226
|
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4227
|
+
if (this.embla) {
|
|
4228
|
+
this.embla.reInit();
|
|
4229
|
+
} else {
|
|
4230
|
+
this.initializeEmbla();
|
|
4231
|
+
}
|
|
4167
4232
|
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
this.isPlaying = control.isPlaying();
|
|
4171
|
-
};
|
|
4233
|
+
// add event listener to embla instance to toggle tabindex on active slide whenever slide is changed
|
|
4234
|
+
this.embla.on("select", this.toggleTabIndex);
|
|
4172
4235
|
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
.on(`${plugin}:stop`, togglePlayBtnState)
|
|
4177
|
-
.on("reInit", togglePlayBtnState);
|
|
4236
|
+
// Set isPlaying to true if play is triggered on init
|
|
4237
|
+
this.isPlaying = this.playOnInit;
|
|
4238
|
+
}
|
|
4178
4239
|
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4240
|
+
/**
|
|
4241
|
+
* @private
|
|
4242
|
+
* @param {string} direction - The direction of the navigation ("prev" or "next").
|
|
4243
|
+
* Handles click events on the previous and next buttons.
|
|
4244
|
+
*/
|
|
4245
|
+
handleNavClick(direction) {
|
|
4246
|
+
if (direction === "prev") {
|
|
4247
|
+
this.scrollPrev();
|
|
4248
|
+
}
|
|
4249
|
+
if (direction === "next") {
|
|
4250
|
+
this.scrollNext();
|
|
4251
|
+
}
|
|
4252
|
+
this.stopAutoplayOnInteraction(this.embla);
|
|
4253
|
+
}
|
|
4187
4254
|
|
|
4188
4255
|
/**
|
|
4189
4256
|
* @private
|
|
4190
|
-
*
|
|
4257
|
+
* @param {KeyboardEvent} event - The keydown event triggered by the user.
|
|
4258
|
+
* Allows users to navigate through the slideshow using left/right arrow keys.
|
|
4191
4259
|
*/
|
|
4192
|
-
|
|
4260
|
+
handleKeydown = (event) => {
|
|
4261
|
+
const focusActiveSlide = () => {
|
|
4262
|
+
// Timeout added for UX optimization
|
|
4263
|
+
setTimeout(() => {
|
|
4264
|
+
const activeSlide = this.slides[this.embla.selectedScrollSnap()];
|
|
4265
|
+
activeSlide.focus();
|
|
4266
|
+
}, 200);
|
|
4267
|
+
};
|
|
4268
|
+
if (event.key === "ArrowLeft") {
|
|
4269
|
+
event.preventDefault();
|
|
4270
|
+
this.scrollPrev();
|
|
4271
|
+
focusActiveSlide();
|
|
4272
|
+
} else if (event.key === "ArrowRight") {
|
|
4273
|
+
event.preventDefault();
|
|
4274
|
+
this.scrollNext();
|
|
4275
|
+
focusActiveSlide();
|
|
4276
|
+
}
|
|
4277
|
+
};
|
|
4193
4278
|
|
|
4194
4279
|
/**
|
|
4195
4280
|
* @private
|
|
4196
|
-
*
|
|
4281
|
+
* Handles click events on the play button to toggle autoplay or autoScroll.
|
|
4197
4282
|
*/
|
|
4198
|
-
|
|
4283
|
+
handlePlayClick() {
|
|
4284
|
+
if (this.isPlaying) {
|
|
4285
|
+
this.stop();
|
|
4286
|
+
this.togglePlayButtonOnStop();
|
|
4287
|
+
} else {
|
|
4288
|
+
this.play();
|
|
4289
|
+
this.togglePlayButtonOnPlay();
|
|
4290
|
+
}
|
|
4291
|
+
}
|
|
4292
|
+
|
|
4293
|
+
// ========== DOTS AND PROGRESS BAR METHODS =================
|
|
4199
4294
|
|
|
4200
4295
|
/**
|
|
4201
4296
|
* @private
|
|
@@ -4205,12 +4300,12 @@ class AuroSlideshow extends i$2 {
|
|
|
4205
4300
|
let dotNodes = [];
|
|
4206
4301
|
|
|
4207
4302
|
const addDotBtnsWithClickHandlers = () => {
|
|
4208
|
-
// Create new dot buttons using Lit's render
|
|
4209
4303
|
const dots = emblaApi.scrollSnapList().map((_, index) => {
|
|
4210
4304
|
const button = document.createElement("button");
|
|
4211
4305
|
button.className = "embla__dot";
|
|
4212
4306
|
button.type = "button";
|
|
4213
4307
|
button.tabIndex = -1;
|
|
4308
|
+
button.setAttribute("aria-label", `Go to slide ${index + 1}`); // TODO: localization
|
|
4214
4309
|
button.addEventListener(
|
|
4215
4310
|
"click",
|
|
4216
4311
|
() => {
|
|
@@ -4222,11 +4317,18 @@ class AuroSlideshow extends i$2 {
|
|
|
4222
4317
|
return button;
|
|
4223
4318
|
});
|
|
4224
4319
|
|
|
4225
|
-
// Use a single DOM operation to update dots
|
|
4226
4320
|
dotsNode.replaceChildren(...dots);
|
|
4227
4321
|
dotNodes = dots;
|
|
4228
4322
|
};
|
|
4229
4323
|
|
|
4324
|
+
// 'stopped' class adds fill color to progress dot when not playing
|
|
4325
|
+
const toggleProgressStopped = () => {
|
|
4326
|
+
const selected = emblaApi.selectedScrollSnap();
|
|
4327
|
+
if (dotNodes[selected]) {
|
|
4328
|
+
dotNodes[selected].classList.toggle("stopped", !this.isPlaying);
|
|
4329
|
+
}
|
|
4330
|
+
};
|
|
4331
|
+
|
|
4230
4332
|
const toggleDotBtnsActive = () => {
|
|
4231
4333
|
const previous = emblaApi.previousScrollSnap();
|
|
4232
4334
|
const selected = emblaApi.selectedScrollSnap();
|
|
@@ -4243,9 +4345,16 @@ class AuroSlideshow extends i$2 {
|
|
|
4243
4345
|
if (dotNodes[selected]) {
|
|
4244
4346
|
dotNodes[selected].className = "embla__progress";
|
|
4245
4347
|
dotNodes[selected].replaceChildren(progressBar);
|
|
4348
|
+
if (!this.isPlaying) {
|
|
4349
|
+
dotNodes[selected].classList.add("stopped");
|
|
4350
|
+
}
|
|
4246
4351
|
}
|
|
4247
4352
|
|
|
4248
4353
|
this.addAutoplayProgressListeners(this.embla, this._progressNode);
|
|
4354
|
+
|
|
4355
|
+
emblaApi
|
|
4356
|
+
.on("autoplay:play", toggleProgressStopped) // Removes fill color when autoplay starts
|
|
4357
|
+
.on("autoplay:stop", toggleProgressStopped); // Adds fill color when autoplay stops (temp solution until paused state is implemented)
|
|
4249
4358
|
} else {
|
|
4250
4359
|
if (dotNodes[previous]) {
|
|
4251
4360
|
dotNodes[previous].classList.remove("embla__dot--selected");
|
|
@@ -4270,6 +4379,8 @@ class AuroSlideshow extends i$2 {
|
|
|
4270
4379
|
|
|
4271
4380
|
/**
|
|
4272
4381
|
* @private
|
|
4382
|
+
* Adds autoplay progress listeners to the progress bar.
|
|
4383
|
+
* This function updates the progress bar animation based on the autoplay timer.
|
|
4273
4384
|
*/
|
|
4274
4385
|
addAutoplayProgressListeners = (emblaApi, progressNode) => {
|
|
4275
4386
|
const progressBarNode = progressNode.querySelector(".embla__progress__bar");
|
|
@@ -4318,13 +4429,34 @@ class AuroSlideshow extends i$2 {
|
|
|
4318
4429
|
};
|
|
4319
4430
|
};
|
|
4320
4431
|
|
|
4432
|
+
// ========== LIFECYCLE METHODS =================
|
|
4433
|
+
|
|
4321
4434
|
disconnectedCallback() {
|
|
4322
4435
|
super.disconnectedCallback();
|
|
4323
4436
|
|
|
4324
|
-
this.embla.off("select", this.toggleTabIndex);
|
|
4325
|
-
|
|
4326
4437
|
// Clean up event listeners and Embla instance
|
|
4327
4438
|
if (this.embla) {
|
|
4439
|
+
this.embla.off("select", this.toggleTabIndex);
|
|
4440
|
+
|
|
4441
|
+
if (this.navigation && !this.isTouchDevice()) {
|
|
4442
|
+
this.embla
|
|
4443
|
+
.off("select", this.toggleNavBtnsState)
|
|
4444
|
+
.off("init", this.toggleNavBtnsState)
|
|
4445
|
+
.off("reInit", this.toggleNavBtnsState);
|
|
4446
|
+
}
|
|
4447
|
+
|
|
4448
|
+
if (this.autoplay) {
|
|
4449
|
+
this.embla
|
|
4450
|
+
.off("autoplay:stop", this.togglePlayButtonOnStop)
|
|
4451
|
+
.off("autoplay:play", this.togglePlayButtonOnPlay);
|
|
4452
|
+
}
|
|
4453
|
+
|
|
4454
|
+
if (this.autoScroll && !this.isTouchDevice()) {
|
|
4455
|
+
this.embla
|
|
4456
|
+
.off("autoScroll:stop", this.togglePlayButtonOnStop)
|
|
4457
|
+
.off("autoScroll:play", this.togglePlayButtonOnPlay);
|
|
4458
|
+
}
|
|
4459
|
+
|
|
4328
4460
|
this.embla.destroy();
|
|
4329
4461
|
this.embla = null;
|
|
4330
4462
|
}
|
|
@@ -4336,6 +4468,8 @@ class AuroSlideshow extends i$2 {
|
|
|
4336
4468
|
this.slides = [];
|
|
4337
4469
|
}
|
|
4338
4470
|
|
|
4471
|
+
// ========== RENDER METHODS =================
|
|
4472
|
+
|
|
4339
4473
|
/**
|
|
4340
4474
|
* Internal function to generate the HTML for the icon to use.
|
|
4341
4475
|
* @private
|
|
@@ -4364,7 +4498,8 @@ class AuroSlideshow extends i$2 {
|
|
|
4364
4498
|
shape="circle"
|
|
4365
4499
|
onDark
|
|
4366
4500
|
size="lg"
|
|
4367
|
-
@click=${() => this.
|
|
4501
|
+
@click=${() => this.handleNavClick("prev")}
|
|
4502
|
+
part="prev-button">
|
|
4368
4503
|
${this.generateIconHtml(chevronLeft.svg)}
|
|
4369
4504
|
</${this.buttonTag}>
|
|
4370
4505
|
<${this.buttonTag}
|
|
@@ -4373,7 +4508,8 @@ class AuroSlideshow extends i$2 {
|
|
|
4373
4508
|
shape="circle"
|
|
4374
4509
|
onDark
|
|
4375
4510
|
size="lg"
|
|
4376
|
-
@click=${() => this.
|
|
4511
|
+
@click=${() => this.handleNavClick("next")}
|
|
4512
|
+
part="next-button">
|
|
4377
4513
|
${this.generateIconHtml(chevronRight.svg)}
|
|
4378
4514
|
</${this.buttonTag}>`;
|
|
4379
4515
|
}
|
|
@@ -4385,6 +4521,8 @@ class AuroSlideshow extends i$2 {
|
|
|
4385
4521
|
aria-label="${this.playBtnLabel}"
|
|
4386
4522
|
class="play-pause"
|
|
4387
4523
|
shape="circle"
|
|
4524
|
+
@click=${() => this.handlePlayClick()}
|
|
4525
|
+
part="play-pause-button"
|
|
4388
4526
|
>
|
|
4389
4527
|
${this.generateIconHtml(play.svg, this.isPlaying)}
|
|
4390
4528
|
${this.generateIconHtml(pause.svg, !this.isPlaying)}
|
|
@@ -4401,7 +4539,7 @@ class AuroSlideshow extends i$2 {
|
|
|
4401
4539
|
renderPaginationContainer() {
|
|
4402
4540
|
return u`
|
|
4403
4541
|
<div class="pagination-container">
|
|
4404
|
-
${this.autoplay || this.autoScroll ? this.renderPlayButton() : E}
|
|
4542
|
+
${this.autoplay || (this.autoScroll && !this.isTouchDevice()) ? this.renderPlayButton() : E}
|
|
4405
4543
|
${this.pagination ? u`<div class="embla__dots"></div>` : E}
|
|
4406
4544
|
</div>
|
|
4407
4545
|
`;
|
|
@@ -4411,14 +4549,20 @@ class AuroSlideshow extends i$2 {
|
|
|
4411
4549
|
return u`
|
|
4412
4550
|
<div class="container">
|
|
4413
4551
|
<div class="slideshow-wrapper">
|
|
4414
|
-
${this.navigation ? this.renderNavigationControls() : E}
|
|
4552
|
+
${this.navigation && !this.isTouchDevice() ? this.renderNavigationControls() : E}
|
|
4415
4553
|
<div class="embla">
|
|
4416
4554
|
<div class="embla__container">
|
|
4417
4555
|
<slot @slotchange=${this.handleSlotChange}></slot>
|
|
4418
4556
|
</div>
|
|
4419
4557
|
</div>
|
|
4420
4558
|
</div>
|
|
4421
|
-
${
|
|
4559
|
+
${
|
|
4560
|
+
this.pagination ||
|
|
4561
|
+
this.autoplay ||
|
|
4562
|
+
(this.autoScroll && !this.isTouchDevice())
|
|
4563
|
+
? this.renderPaginationContainer()
|
|
4564
|
+
: E
|
|
4565
|
+
}
|
|
4422
4566
|
</div>
|
|
4423
4567
|
`;
|
|
4424
4568
|
}
|