@kiva/kv-components 4.4.0 → 4.5.1
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 +19 -0
- package/dist/components/KvCarousel.vue +20 -0
- package/dist/components/KvVerticalCarousel.vue +20 -0
- package/dist/components/stories/KvCarousel.stories.js +78 -0
- package/dist/components/stories/KvVerticalCarousel.stories.js +78 -0
- package/dist/utils/carousels.cjs +31 -2
- package/dist/utils/carousels.js +1 -1
- package/dist/utils/{chunk-AZPWOFD5.js → chunk-P6FXCNYP.js} +31 -2
- package/dist/utils/index.cjs +31 -2
- package/dist/utils/index.js +1 -1
- package/package.json +5 -3
- package/utils/carousels.js +38 -1
- package/vue/KvCarousel.vue +20 -0
- package/vue/KvVerticalCarousel.vue +20 -0
- package/vue/stories/KvCarousel.stories.js +78 -0
- package/vue/stories/KvVerticalCarousel.stories.js +78 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [4.5.1](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@4.5.0...@kiva/kv-components@4.5.1) (2025-01-04)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @kiva/kv-components
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [4.5.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@4.4.0...@kiva/kv-components@4.5.0) (2025-01-03)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* add autoplay and fade plugin options for carousels ([b85b0c2](https://github.com/kiva/kv-ui-elements/commit/b85b0c20fbff52663c823a984db53fbb41baf0a4))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
# [4.4.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@4.3.3...@kiva/kv-components@4.4.0) (2025-01-02)
|
|
7
26
|
|
|
8
27
|
|
|
@@ -180,6 +180,22 @@ export default {
|
|
|
180
180
|
return {};
|
|
181
181
|
},
|
|
182
182
|
},
|
|
183
|
+
/**
|
|
184
|
+
* Options for the autoplay plugin - // https://www.embla-carousel.com/plugins/autoplay/#options
|
|
185
|
+
* */
|
|
186
|
+
autoplayOptions: {
|
|
187
|
+
type: Object,
|
|
188
|
+
default() {
|
|
189
|
+
return {};
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
/**
|
|
193
|
+
* Enable fade plugin - // https://www.embla-carousel.com/plugins/fade/
|
|
194
|
+
* */
|
|
195
|
+
fadeEnabled: {
|
|
196
|
+
type: Boolean,
|
|
197
|
+
default: false,
|
|
198
|
+
},
|
|
183
199
|
/**
|
|
184
200
|
* The type of logic to implement when deciding how many slides
|
|
185
201
|
* to scroll when pressing the next/prev button
|
|
@@ -233,6 +249,7 @@ export default {
|
|
|
233
249
|
goToSlide,
|
|
234
250
|
handleUserInteraction,
|
|
235
251
|
isAriaHidden,
|
|
252
|
+
isAutoplaying,
|
|
236
253
|
nextIndex,
|
|
237
254
|
onCarouselContainerClick,
|
|
238
255
|
previousIndex,
|
|
@@ -242,6 +259,7 @@ export default {
|
|
|
242
259
|
slideIndicatorCount,
|
|
243
260
|
slideIndicatorListLength,
|
|
244
261
|
slides,
|
|
262
|
+
toggleAutoPlay,
|
|
245
263
|
} = carouselUtil(props, { emit, slots });
|
|
246
264
|
|
|
247
265
|
return {
|
|
@@ -251,6 +269,7 @@ export default {
|
|
|
251
269
|
goToSlide,
|
|
252
270
|
handleUserInteraction,
|
|
253
271
|
isAriaHidden,
|
|
272
|
+
isAutoplaying,
|
|
254
273
|
mdiArrowLeft,
|
|
255
274
|
mdiArrowRight,
|
|
256
275
|
mdiChevronLeft,
|
|
@@ -264,6 +283,7 @@ export default {
|
|
|
264
283
|
slideIndicatorCount,
|
|
265
284
|
slideIndicatorListLength,
|
|
266
285
|
slides,
|
|
286
|
+
toggleAutoPlay,
|
|
267
287
|
};
|
|
268
288
|
},
|
|
269
289
|
};
|
|
@@ -107,6 +107,22 @@ export default {
|
|
|
107
107
|
default: 'auto',
|
|
108
108
|
validator: (value) => ['visible', 'auto'].indexOf(value) !== -1,
|
|
109
109
|
},
|
|
110
|
+
/**
|
|
111
|
+
* Options for the autoplay plugin - // https://www.embla-carousel.com/plugins/autoplay/#options
|
|
112
|
+
* */
|
|
113
|
+
autoplayOptions: {
|
|
114
|
+
type: Object,
|
|
115
|
+
default() {
|
|
116
|
+
return {};
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
/**
|
|
120
|
+
* Enable fade plugin - // https://www.embla-carousel.com/plugins/fade/
|
|
121
|
+
* */
|
|
122
|
+
fadeEnabled: {
|
|
123
|
+
type: Boolean,
|
|
124
|
+
default: false,
|
|
125
|
+
},
|
|
110
126
|
},
|
|
111
127
|
emits: [
|
|
112
128
|
'change',
|
|
@@ -120,6 +136,7 @@ export default {
|
|
|
120
136
|
goToSlide,
|
|
121
137
|
handleUserInteraction,
|
|
122
138
|
isAriaHidden,
|
|
139
|
+
isAutoplaying,
|
|
123
140
|
nextIndex,
|
|
124
141
|
onCarouselContainerClick,
|
|
125
142
|
previousIndex,
|
|
@@ -128,6 +145,7 @@ export default {
|
|
|
128
145
|
rootEl,
|
|
129
146
|
slideIndicatorCount,
|
|
130
147
|
slides,
|
|
148
|
+
toggleAutoPlay,
|
|
131
149
|
} = carouselUtil(props, { emit, slots }, { axis: 'y' });
|
|
132
150
|
|
|
133
151
|
return {
|
|
@@ -137,6 +155,7 @@ export default {
|
|
|
137
155
|
goToSlide,
|
|
138
156
|
handleUserInteraction,
|
|
139
157
|
isAriaHidden,
|
|
158
|
+
isAutoplaying,
|
|
140
159
|
mdiChevronDown,
|
|
141
160
|
mdiChevronUp,
|
|
142
161
|
nextIndex,
|
|
@@ -147,6 +166,7 @@ export default {
|
|
|
147
166
|
rootEl,
|
|
148
167
|
slideIndicatorCount,
|
|
149
168
|
slides,
|
|
169
|
+
toggleAutoPlay,
|
|
150
170
|
};
|
|
151
171
|
},
|
|
152
172
|
};
|
|
@@ -424,3 +424,81 @@ export const ThreeDimensional = () => ({
|
|
|
424
424
|
</kv-carousel>
|
|
425
425
|
`,
|
|
426
426
|
});
|
|
427
|
+
|
|
428
|
+
export const AutoPlayAutomatically = () => ({
|
|
429
|
+
components: {
|
|
430
|
+
KvCarousel,
|
|
431
|
+
},
|
|
432
|
+
template: `
|
|
433
|
+
<kv-carousel
|
|
434
|
+
style="max-width: 400px;"
|
|
435
|
+
:embla-options="{ loop: false }"
|
|
436
|
+
:autoplay-options="{ playOnInit: true, delay: 3000 }"
|
|
437
|
+
>
|
|
438
|
+
${defaultCarouselSlides}
|
|
439
|
+
</kv-carousel>
|
|
440
|
+
`,
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
export const AutoPlayButton = () => ({
|
|
444
|
+
components: {
|
|
445
|
+
KvCarousel,
|
|
446
|
+
},
|
|
447
|
+
data() {
|
|
448
|
+
return {
|
|
449
|
+
isPlaying: false,
|
|
450
|
+
};
|
|
451
|
+
},
|
|
452
|
+
mounted() {
|
|
453
|
+
this.$nextTick(() => {
|
|
454
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
455
|
+
});
|
|
456
|
+
},
|
|
457
|
+
template: `
|
|
458
|
+
<div>
|
|
459
|
+
<kv-carousel
|
|
460
|
+
ref="sampleCarousel"
|
|
461
|
+
style="max-width: 400px;"
|
|
462
|
+
:embla-options="{ loop: false }"
|
|
463
|
+
:autoplay-options="{ playOnInit: true, delay: 3000 }"
|
|
464
|
+
@interact-carousel="carouselInteraction"
|
|
465
|
+
>
|
|
466
|
+
${defaultCarouselSlides}
|
|
467
|
+
</kv-carousel>
|
|
468
|
+
<a href="#" @click.native.prevent="toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
|
|
469
|
+
<br/>
|
|
470
|
+
<p>AutoPlay is: {{ isPlaying ? 'ON' : 'OFF' }}</p>
|
|
471
|
+
</div>
|
|
472
|
+
`,
|
|
473
|
+
methods: {
|
|
474
|
+
toggleAutoPlay() {
|
|
475
|
+
this.$refs.sampleCarousel.toggleAutoPlay();
|
|
476
|
+
},
|
|
477
|
+
carouselInteraction() {
|
|
478
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
export const Fade = () => ({
|
|
484
|
+
components: {
|
|
485
|
+
KvCarousel,
|
|
486
|
+
},
|
|
487
|
+
mounted() {
|
|
488
|
+
this.$nextTick(() => {
|
|
489
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
template: `
|
|
493
|
+
<div>
|
|
494
|
+
<kv-carousel
|
|
495
|
+
ref="sampleCarousel"
|
|
496
|
+
style="max-width: 400px;"
|
|
497
|
+
:embla-options="{ loop: false }"
|
|
498
|
+
:fade-enabled="true"
|
|
499
|
+
>
|
|
500
|
+
${defaultCarouselSlides}
|
|
501
|
+
</kv-carousel>
|
|
502
|
+
</div>
|
|
503
|
+
`,
|
|
504
|
+
});
|
|
@@ -166,3 +166,81 @@ export const CustomStartIndex = () => ({
|
|
|
166
166
|
</kv-vertical-carousel>
|
|
167
167
|
`,
|
|
168
168
|
});
|
|
169
|
+
|
|
170
|
+
export const AutoPlayAutomatically = () => ({
|
|
171
|
+
components: {
|
|
172
|
+
KvVerticalCarousel,
|
|
173
|
+
},
|
|
174
|
+
template: `
|
|
175
|
+
<kv-vertical-carousel
|
|
176
|
+
style="max-width: 400px;"
|
|
177
|
+
:embla-options="{ loop: false }"
|
|
178
|
+
:autoplay-options="{ playOnInit: true, delay: 3000 }"
|
|
179
|
+
>
|
|
180
|
+
${defaultCarouselSlides}
|
|
181
|
+
</kv-vertical-carousel>
|
|
182
|
+
`,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
export const AutoPlayButton = () => ({
|
|
186
|
+
components: {
|
|
187
|
+
KvVerticalCarousel,
|
|
188
|
+
},
|
|
189
|
+
data() {
|
|
190
|
+
return {
|
|
191
|
+
isPlaying: false,
|
|
192
|
+
};
|
|
193
|
+
},
|
|
194
|
+
mounted() {
|
|
195
|
+
this.$nextTick(() => {
|
|
196
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
template: `
|
|
200
|
+
<div>
|
|
201
|
+
<kv-vertical-carousel
|
|
202
|
+
ref="sampleCarousel"
|
|
203
|
+
style="max-width: 400px;"
|
|
204
|
+
:embla-options="{ loop: false }"
|
|
205
|
+
:autoplay-options="{ playOnInit: true, delay: 3000 }"
|
|
206
|
+
@interact-carousel="carouselInteraction"
|
|
207
|
+
>
|
|
208
|
+
${defaultCarouselSlides}
|
|
209
|
+
</kv-vertical-carousel>
|
|
210
|
+
<a href="#" @click.native.prevent="toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
|
|
211
|
+
<br/>
|
|
212
|
+
<p>AutoPlay is: {{ isPlaying ? 'ON' : 'OFF' }}</p>
|
|
213
|
+
</div>
|
|
214
|
+
`,
|
|
215
|
+
methods: {
|
|
216
|
+
toggleAutoPlay() {
|
|
217
|
+
this.$refs.sampleCarousel.toggleAutoPlay();
|
|
218
|
+
},
|
|
219
|
+
carouselInteraction() {
|
|
220
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
export const Fade = () => ({
|
|
226
|
+
components: {
|
|
227
|
+
KvVerticalCarousel,
|
|
228
|
+
},
|
|
229
|
+
mounted() {
|
|
230
|
+
this.$nextTick(() => {
|
|
231
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
template: `
|
|
235
|
+
<div>
|
|
236
|
+
<kv-vertical-carousel
|
|
237
|
+
ref="sampleCarousel"
|
|
238
|
+
style="max-width: 400px;"
|
|
239
|
+
:embla-options="{ loop: false }"
|
|
240
|
+
:fade-enabled="true"
|
|
241
|
+
>
|
|
242
|
+
${defaultCarouselSlides}
|
|
243
|
+
</kv-vertical-carousel>
|
|
244
|
+
</div>
|
|
245
|
+
`,
|
|
246
|
+
});
|
package/dist/utils/carousels.cjs
CHANGED
|
@@ -34,6 +34,8 @@ __export(carousels_exports, {
|
|
|
34
34
|
module.exports = __toCommonJS(carousels_exports);
|
|
35
35
|
var import_vue_demi = require("vue-demi");
|
|
36
36
|
var import_embla_carousel = __toESM(require("embla-carousel"), 1);
|
|
37
|
+
var import_embla_carousel_autoplay = __toESM(require("embla-carousel-autoplay"), 1);
|
|
38
|
+
var import_embla_carousel_fade = __toESM(require("embla-carousel-fade"), 1);
|
|
37
39
|
|
|
38
40
|
// utils/throttle.js
|
|
39
41
|
function throttle(func, timeFrame) {
|
|
@@ -51,6 +53,8 @@ function throttle(func, timeFrame) {
|
|
|
51
53
|
function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
52
54
|
var _a;
|
|
53
55
|
const {
|
|
56
|
+
autoplayOptions,
|
|
57
|
+
fadeEnabled,
|
|
54
58
|
emblaOptions,
|
|
55
59
|
slidesToScroll
|
|
56
60
|
} = (0, import_vue_demi.toRefs)(props);
|
|
@@ -88,6 +92,22 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
88
92
|
}
|
|
89
93
|
emit("interact-carousel", interactionType);
|
|
90
94
|
};
|
|
95
|
+
const toggleAutoPlay = () => {
|
|
96
|
+
var _a2, _b;
|
|
97
|
+
const autoplay = (_b = (_a2 = embla.value) == null ? void 0 : _a2.plugins()) == null ? void 0 : _b.autoplay;
|
|
98
|
+
if (!autoplay)
|
|
99
|
+
return;
|
|
100
|
+
const playOrStop = autoplay.isPlaying() ? autoplay.stop : autoplay.play;
|
|
101
|
+
playOrStop();
|
|
102
|
+
handleUserInteraction(null, "autoplay");
|
|
103
|
+
};
|
|
104
|
+
const isAutoplaying = () => {
|
|
105
|
+
var _a2, _b;
|
|
106
|
+
const autoplay = (_b = (_a2 = embla.value) == null ? void 0 : _a2.plugins()) == null ? void 0 : _b.autoplay;
|
|
107
|
+
if (!autoplay)
|
|
108
|
+
return false;
|
|
109
|
+
return autoplay.isPlaying();
|
|
110
|
+
};
|
|
91
111
|
const slideIndicatorListLength = () => {
|
|
92
112
|
const indicator = embla.value ? embla.value.scrollSnapList().length : 0;
|
|
93
113
|
slideIndicatorCount.value = indicator;
|
|
@@ -124,6 +144,13 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
124
144
|
};
|
|
125
145
|
(0, import_vue_demi.onMounted)(async () => {
|
|
126
146
|
var _a2;
|
|
147
|
+
const combinedPluginOptions = [];
|
|
148
|
+
if (Object.keys(autoplayOptions.value).length !== 0) {
|
|
149
|
+
combinedPluginOptions.push((0, import_embla_carousel_autoplay.default)(autoplayOptions.value));
|
|
150
|
+
}
|
|
151
|
+
if (fadeEnabled.value) {
|
|
152
|
+
combinedPluginOptions.push((0, import_embla_carousel_fade.default)());
|
|
153
|
+
}
|
|
127
154
|
embla.value = (0, import_embla_carousel.default)(rootEl.value, {
|
|
128
155
|
loop: true,
|
|
129
156
|
containScroll: "trimSnaps",
|
|
@@ -131,7 +158,7 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
131
158
|
align: "start",
|
|
132
159
|
...extraEmblaOptions,
|
|
133
160
|
...emblaOptions.value
|
|
134
|
-
});
|
|
161
|
+
}, combinedPluginOptions);
|
|
135
162
|
if (slidesToScroll.value === "visible") {
|
|
136
163
|
reInitVisible();
|
|
137
164
|
embla.value.on(
|
|
@@ -175,7 +202,9 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
175
202
|
reInitVisible,
|
|
176
203
|
onCarouselContainerClick,
|
|
177
204
|
isAriaHidden,
|
|
178
|
-
|
|
205
|
+
isAutoplaying,
|
|
206
|
+
slideIndicatorListLength,
|
|
207
|
+
toggleAutoPlay
|
|
179
208
|
};
|
|
180
209
|
}
|
|
181
210
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/utils/carousels.js
CHANGED
|
@@ -12,9 +12,13 @@ import {
|
|
|
12
12
|
nextTick
|
|
13
13
|
} from "vue-demi";
|
|
14
14
|
import EmblaCarousel from "embla-carousel";
|
|
15
|
+
import Autoplay from "embla-carousel-autoplay";
|
|
16
|
+
import Fade from "embla-carousel-fade";
|
|
15
17
|
function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
16
18
|
var _a;
|
|
17
19
|
const {
|
|
20
|
+
autoplayOptions,
|
|
21
|
+
fadeEnabled,
|
|
18
22
|
emblaOptions,
|
|
19
23
|
slidesToScroll
|
|
20
24
|
} = toRefs(props);
|
|
@@ -52,6 +56,22 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
52
56
|
}
|
|
53
57
|
emit("interact-carousel", interactionType);
|
|
54
58
|
};
|
|
59
|
+
const toggleAutoPlay = () => {
|
|
60
|
+
var _a2, _b;
|
|
61
|
+
const autoplay = (_b = (_a2 = embla.value) == null ? void 0 : _a2.plugins()) == null ? void 0 : _b.autoplay;
|
|
62
|
+
if (!autoplay)
|
|
63
|
+
return;
|
|
64
|
+
const playOrStop = autoplay.isPlaying() ? autoplay.stop : autoplay.play;
|
|
65
|
+
playOrStop();
|
|
66
|
+
handleUserInteraction(null, "autoplay");
|
|
67
|
+
};
|
|
68
|
+
const isAutoplaying = () => {
|
|
69
|
+
var _a2, _b;
|
|
70
|
+
const autoplay = (_b = (_a2 = embla.value) == null ? void 0 : _a2.plugins()) == null ? void 0 : _b.autoplay;
|
|
71
|
+
if (!autoplay)
|
|
72
|
+
return false;
|
|
73
|
+
return autoplay.isPlaying();
|
|
74
|
+
};
|
|
55
75
|
const slideIndicatorListLength = () => {
|
|
56
76
|
const indicator = embla.value ? embla.value.scrollSnapList().length : 0;
|
|
57
77
|
slideIndicatorCount.value = indicator;
|
|
@@ -88,6 +108,13 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
88
108
|
};
|
|
89
109
|
onMounted(async () => {
|
|
90
110
|
var _a2;
|
|
111
|
+
const combinedPluginOptions = [];
|
|
112
|
+
if (Object.keys(autoplayOptions.value).length !== 0) {
|
|
113
|
+
combinedPluginOptions.push(Autoplay(autoplayOptions.value));
|
|
114
|
+
}
|
|
115
|
+
if (fadeEnabled.value) {
|
|
116
|
+
combinedPluginOptions.push(Fade());
|
|
117
|
+
}
|
|
91
118
|
embla.value = EmblaCarousel(rootEl.value, {
|
|
92
119
|
loop: true,
|
|
93
120
|
containScroll: "trimSnaps",
|
|
@@ -95,7 +122,7 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
95
122
|
align: "start",
|
|
96
123
|
...extraEmblaOptions,
|
|
97
124
|
...emblaOptions.value
|
|
98
|
-
});
|
|
125
|
+
}, combinedPluginOptions);
|
|
99
126
|
if (slidesToScroll.value === "visible") {
|
|
100
127
|
reInitVisible();
|
|
101
128
|
embla.value.on(
|
|
@@ -139,7 +166,9 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
139
166
|
reInitVisible,
|
|
140
167
|
onCarouselContainerClick,
|
|
141
168
|
isAriaHidden,
|
|
142
|
-
|
|
169
|
+
isAutoplaying,
|
|
170
|
+
slideIndicatorListLength,
|
|
171
|
+
toggleAutoPlay
|
|
143
172
|
};
|
|
144
173
|
}
|
|
145
174
|
|
package/dist/utils/index.cjs
CHANGED
|
@@ -142,6 +142,8 @@ function useAttrs({ attrs, listeners }, ownEvents = []) {
|
|
|
142
142
|
// utils/carousels.js
|
|
143
143
|
var import_vue_demi = require("vue-demi");
|
|
144
144
|
var import_embla_carousel = __toESM(require("embla-carousel"), 1);
|
|
145
|
+
var import_embla_carousel_autoplay = __toESM(require("embla-carousel-autoplay"), 1);
|
|
146
|
+
var import_embla_carousel_fade = __toESM(require("embla-carousel-fade"), 1);
|
|
145
147
|
|
|
146
148
|
// utils/throttle.js
|
|
147
149
|
function throttle(func, timeFrame) {
|
|
@@ -159,6 +161,8 @@ function throttle(func, timeFrame) {
|
|
|
159
161
|
function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
160
162
|
var _a;
|
|
161
163
|
const {
|
|
164
|
+
autoplayOptions,
|
|
165
|
+
fadeEnabled,
|
|
162
166
|
emblaOptions,
|
|
163
167
|
slidesToScroll
|
|
164
168
|
} = (0, import_vue_demi.toRefs)(props);
|
|
@@ -196,6 +200,22 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
196
200
|
}
|
|
197
201
|
emit("interact-carousel", interactionType);
|
|
198
202
|
};
|
|
203
|
+
const toggleAutoPlay = () => {
|
|
204
|
+
var _a2, _b;
|
|
205
|
+
const autoplay = (_b = (_a2 = embla.value) == null ? void 0 : _a2.plugins()) == null ? void 0 : _b.autoplay;
|
|
206
|
+
if (!autoplay)
|
|
207
|
+
return;
|
|
208
|
+
const playOrStop = autoplay.isPlaying() ? autoplay.stop : autoplay.play;
|
|
209
|
+
playOrStop();
|
|
210
|
+
handleUserInteraction(null, "autoplay");
|
|
211
|
+
};
|
|
212
|
+
const isAutoplaying = () => {
|
|
213
|
+
var _a2, _b;
|
|
214
|
+
const autoplay = (_b = (_a2 = embla.value) == null ? void 0 : _a2.plugins()) == null ? void 0 : _b.autoplay;
|
|
215
|
+
if (!autoplay)
|
|
216
|
+
return false;
|
|
217
|
+
return autoplay.isPlaying();
|
|
218
|
+
};
|
|
199
219
|
const slideIndicatorListLength = () => {
|
|
200
220
|
const indicator = embla.value ? embla.value.scrollSnapList().length : 0;
|
|
201
221
|
slideIndicatorCount.value = indicator;
|
|
@@ -232,6 +252,13 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
232
252
|
};
|
|
233
253
|
(0, import_vue_demi.onMounted)(async () => {
|
|
234
254
|
var _a2;
|
|
255
|
+
const combinedPluginOptions = [];
|
|
256
|
+
if (Object.keys(autoplayOptions.value).length !== 0) {
|
|
257
|
+
combinedPluginOptions.push((0, import_embla_carousel_autoplay.default)(autoplayOptions.value));
|
|
258
|
+
}
|
|
259
|
+
if (fadeEnabled.value) {
|
|
260
|
+
combinedPluginOptions.push((0, import_embla_carousel_fade.default)());
|
|
261
|
+
}
|
|
235
262
|
embla.value = (0, import_embla_carousel.default)(rootEl.value, {
|
|
236
263
|
loop: true,
|
|
237
264
|
containScroll: "trimSnaps",
|
|
@@ -239,7 +266,7 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
239
266
|
align: "start",
|
|
240
267
|
...extraEmblaOptions,
|
|
241
268
|
...emblaOptions.value
|
|
242
|
-
});
|
|
269
|
+
}, combinedPluginOptions);
|
|
243
270
|
if (slidesToScroll.value === "visible") {
|
|
244
271
|
reInitVisible();
|
|
245
272
|
embla.value.on(
|
|
@@ -283,7 +310,9 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
283
310
|
reInitVisible,
|
|
284
311
|
onCarouselContainerClick,
|
|
285
312
|
isAriaHidden,
|
|
286
|
-
|
|
313
|
+
isAutoplaying,
|
|
314
|
+
slideIndicatorListLength,
|
|
315
|
+
toggleAutoPlay
|
|
287
316
|
};
|
|
288
317
|
}
|
|
289
318
|
|
package/dist/utils/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kiva/kv-components",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -64,13 +64,15 @@
|
|
|
64
64
|
"build": "tsup utils/*.js --outDir dist/utils --format cjs,esm --clean && cp -R vue/ dist/components/ && cp -R data/ dist/data/"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@kiva/kv-tokens": "^2.16.
|
|
67
|
+
"@kiva/kv-tokens": "^2.16.1",
|
|
68
68
|
"@mdi/js": "^7.4.47",
|
|
69
69
|
"@vueuse/integrations": "^9.13.0",
|
|
70
70
|
"aria-hidden": "^1.1.3",
|
|
71
71
|
"change-case": "^4.1.2",
|
|
72
72
|
"date-fns": "^2.30.0",
|
|
73
73
|
"embla-carousel": "^8.5.1",
|
|
74
|
+
"embla-carousel-autoplay": "^8.5.1",
|
|
75
|
+
"embla-carousel-fade": "^8.5.1",
|
|
74
76
|
"flag-icons": "^7.2.3",
|
|
75
77
|
"focus-trap": "^6.7.2",
|
|
76
78
|
"moment": "^2.29.4",
|
|
@@ -96,5 +98,5 @@
|
|
|
96
98
|
"peerDependencies": {
|
|
97
99
|
"vue": ">=3.0.0"
|
|
98
100
|
},
|
|
99
|
-
"gitHead": "
|
|
101
|
+
"gitHead": "bcfe3bd0b8f202f7bdd27e47ce013f9c51d69469"
|
|
100
102
|
}
|
package/utils/carousels.js
CHANGED
|
@@ -8,10 +8,14 @@ import {
|
|
|
8
8
|
nextTick,
|
|
9
9
|
} from 'vue-demi';
|
|
10
10
|
import EmblaCarousel from 'embla-carousel';
|
|
11
|
+
import Autoplay from 'embla-carousel-autoplay';
|
|
12
|
+
import Fade from 'embla-carousel-fade';
|
|
11
13
|
import { throttle } from './throttle';
|
|
12
14
|
|
|
13
15
|
export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
14
16
|
const {
|
|
17
|
+
autoplayOptions,
|
|
18
|
+
fadeEnabled,
|
|
15
19
|
emblaOptions,
|
|
16
20
|
slidesToScroll,
|
|
17
21
|
} = toRefs(props);
|
|
@@ -53,6 +57,7 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
53
57
|
const goToSlide = (index) => {
|
|
54
58
|
embla.value.scrollTo(index);
|
|
55
59
|
};
|
|
60
|
+
|
|
56
61
|
const handleUserInteraction = async (index, interactionType) => {
|
|
57
62
|
if (index !== null && typeof index !== 'undefined') {
|
|
58
63
|
await nextTick(); // wait for embla.
|
|
@@ -66,7 +71,29 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
66
71
|
*/
|
|
67
72
|
emit('interact-carousel', interactionType);
|
|
68
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Start/Stop autoplay
|
|
76
|
+
*
|
|
77
|
+
* @public This is a public method
|
|
78
|
+
*/
|
|
79
|
+
const toggleAutoPlay = () => {
|
|
80
|
+
const autoplay = embla.value?.plugins()?.autoplay;
|
|
81
|
+
if (!autoplay) return;
|
|
82
|
+
const playOrStop = autoplay.isPlaying() ? autoplay.stop : autoplay.play;
|
|
83
|
+
playOrStop();
|
|
84
|
+
handleUserInteraction(null, 'autoplay');
|
|
85
|
+
};
|
|
69
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Returns true if the carousel is autoplaying
|
|
89
|
+
*
|
|
90
|
+
* @public This is a public method
|
|
91
|
+
*/
|
|
92
|
+
const isAutoplaying = () => {
|
|
93
|
+
const autoplay = embla.value?.plugins()?.autoplay;
|
|
94
|
+
if (!autoplay) return false;
|
|
95
|
+
return autoplay.isPlaying();
|
|
96
|
+
};
|
|
70
97
|
/**
|
|
71
98
|
* Returns number of slides in the carousel
|
|
72
99
|
*
|
|
@@ -93,6 +120,7 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
93
120
|
});
|
|
94
121
|
}
|
|
95
122
|
};
|
|
123
|
+
|
|
96
124
|
const reInit = () => {
|
|
97
125
|
embla.value.reInit();
|
|
98
126
|
if (slidesToScroll.value === 'visible') {
|
|
@@ -123,6 +151,13 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
123
151
|
};
|
|
124
152
|
|
|
125
153
|
onMounted(async () => {
|
|
154
|
+
const combinedPluginOptions = [];
|
|
155
|
+
if (Object.keys(autoplayOptions.value).length !== 0) {
|
|
156
|
+
combinedPluginOptions.push(Autoplay(autoplayOptions.value));
|
|
157
|
+
}
|
|
158
|
+
if (fadeEnabled.value) {
|
|
159
|
+
combinedPluginOptions.push(Fade());
|
|
160
|
+
}
|
|
126
161
|
embla.value = EmblaCarousel(rootEl.value, {
|
|
127
162
|
loop: true,
|
|
128
163
|
containScroll: 'trimSnaps',
|
|
@@ -130,7 +165,7 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
130
165
|
align: 'start',
|
|
131
166
|
...extraEmblaOptions,
|
|
132
167
|
...emblaOptions.value,
|
|
133
|
-
});
|
|
168
|
+
}, combinedPluginOptions);
|
|
134
169
|
|
|
135
170
|
if (slidesToScroll.value === 'visible') {
|
|
136
171
|
reInitVisible();
|
|
@@ -185,6 +220,8 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
|
|
|
185
220
|
reInitVisible,
|
|
186
221
|
onCarouselContainerClick,
|
|
187
222
|
isAriaHidden,
|
|
223
|
+
isAutoplaying,
|
|
188
224
|
slideIndicatorListLength,
|
|
225
|
+
toggleAutoPlay,
|
|
189
226
|
};
|
|
190
227
|
}
|
package/vue/KvCarousel.vue
CHANGED
|
@@ -180,6 +180,22 @@ export default {
|
|
|
180
180
|
return {};
|
|
181
181
|
},
|
|
182
182
|
},
|
|
183
|
+
/**
|
|
184
|
+
* Options for the autoplay plugin - // https://www.embla-carousel.com/plugins/autoplay/#options
|
|
185
|
+
* */
|
|
186
|
+
autoplayOptions: {
|
|
187
|
+
type: Object,
|
|
188
|
+
default() {
|
|
189
|
+
return {};
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
/**
|
|
193
|
+
* Enable fade plugin - // https://www.embla-carousel.com/plugins/fade/
|
|
194
|
+
* */
|
|
195
|
+
fadeEnabled: {
|
|
196
|
+
type: Boolean,
|
|
197
|
+
default: false,
|
|
198
|
+
},
|
|
183
199
|
/**
|
|
184
200
|
* The type of logic to implement when deciding how many slides
|
|
185
201
|
* to scroll when pressing the next/prev button
|
|
@@ -233,6 +249,7 @@ export default {
|
|
|
233
249
|
goToSlide,
|
|
234
250
|
handleUserInteraction,
|
|
235
251
|
isAriaHidden,
|
|
252
|
+
isAutoplaying,
|
|
236
253
|
nextIndex,
|
|
237
254
|
onCarouselContainerClick,
|
|
238
255
|
previousIndex,
|
|
@@ -242,6 +259,7 @@ export default {
|
|
|
242
259
|
slideIndicatorCount,
|
|
243
260
|
slideIndicatorListLength,
|
|
244
261
|
slides,
|
|
262
|
+
toggleAutoPlay,
|
|
245
263
|
} = carouselUtil(props, { emit, slots });
|
|
246
264
|
|
|
247
265
|
return {
|
|
@@ -251,6 +269,7 @@ export default {
|
|
|
251
269
|
goToSlide,
|
|
252
270
|
handleUserInteraction,
|
|
253
271
|
isAriaHidden,
|
|
272
|
+
isAutoplaying,
|
|
254
273
|
mdiArrowLeft,
|
|
255
274
|
mdiArrowRight,
|
|
256
275
|
mdiChevronLeft,
|
|
@@ -264,6 +283,7 @@ export default {
|
|
|
264
283
|
slideIndicatorCount,
|
|
265
284
|
slideIndicatorListLength,
|
|
266
285
|
slides,
|
|
286
|
+
toggleAutoPlay,
|
|
267
287
|
};
|
|
268
288
|
},
|
|
269
289
|
};
|
|
@@ -107,6 +107,22 @@ export default {
|
|
|
107
107
|
default: 'auto',
|
|
108
108
|
validator: (value) => ['visible', 'auto'].indexOf(value) !== -1,
|
|
109
109
|
},
|
|
110
|
+
/**
|
|
111
|
+
* Options for the autoplay plugin - // https://www.embla-carousel.com/plugins/autoplay/#options
|
|
112
|
+
* */
|
|
113
|
+
autoplayOptions: {
|
|
114
|
+
type: Object,
|
|
115
|
+
default() {
|
|
116
|
+
return {};
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
/**
|
|
120
|
+
* Enable fade plugin - // https://www.embla-carousel.com/plugins/fade/
|
|
121
|
+
* */
|
|
122
|
+
fadeEnabled: {
|
|
123
|
+
type: Boolean,
|
|
124
|
+
default: false,
|
|
125
|
+
},
|
|
110
126
|
},
|
|
111
127
|
emits: [
|
|
112
128
|
'change',
|
|
@@ -120,6 +136,7 @@ export default {
|
|
|
120
136
|
goToSlide,
|
|
121
137
|
handleUserInteraction,
|
|
122
138
|
isAriaHidden,
|
|
139
|
+
isAutoplaying,
|
|
123
140
|
nextIndex,
|
|
124
141
|
onCarouselContainerClick,
|
|
125
142
|
previousIndex,
|
|
@@ -128,6 +145,7 @@ export default {
|
|
|
128
145
|
rootEl,
|
|
129
146
|
slideIndicatorCount,
|
|
130
147
|
slides,
|
|
148
|
+
toggleAutoPlay,
|
|
131
149
|
} = carouselUtil(props, { emit, slots }, { axis: 'y' });
|
|
132
150
|
|
|
133
151
|
return {
|
|
@@ -137,6 +155,7 @@ export default {
|
|
|
137
155
|
goToSlide,
|
|
138
156
|
handleUserInteraction,
|
|
139
157
|
isAriaHidden,
|
|
158
|
+
isAutoplaying,
|
|
140
159
|
mdiChevronDown,
|
|
141
160
|
mdiChevronUp,
|
|
142
161
|
nextIndex,
|
|
@@ -147,6 +166,7 @@ export default {
|
|
|
147
166
|
rootEl,
|
|
148
167
|
slideIndicatorCount,
|
|
149
168
|
slides,
|
|
169
|
+
toggleAutoPlay,
|
|
150
170
|
};
|
|
151
171
|
},
|
|
152
172
|
};
|
|
@@ -424,3 +424,81 @@ export const ThreeDimensional = () => ({
|
|
|
424
424
|
</kv-carousel>
|
|
425
425
|
`,
|
|
426
426
|
});
|
|
427
|
+
|
|
428
|
+
export const AutoPlayAutomatically = () => ({
|
|
429
|
+
components: {
|
|
430
|
+
KvCarousel,
|
|
431
|
+
},
|
|
432
|
+
template: `
|
|
433
|
+
<kv-carousel
|
|
434
|
+
style="max-width: 400px;"
|
|
435
|
+
:embla-options="{ loop: false }"
|
|
436
|
+
:autoplay-options="{ playOnInit: true, delay: 3000 }"
|
|
437
|
+
>
|
|
438
|
+
${defaultCarouselSlides}
|
|
439
|
+
</kv-carousel>
|
|
440
|
+
`,
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
export const AutoPlayButton = () => ({
|
|
444
|
+
components: {
|
|
445
|
+
KvCarousel,
|
|
446
|
+
},
|
|
447
|
+
data() {
|
|
448
|
+
return {
|
|
449
|
+
isPlaying: false,
|
|
450
|
+
};
|
|
451
|
+
},
|
|
452
|
+
mounted() {
|
|
453
|
+
this.$nextTick(() => {
|
|
454
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
455
|
+
});
|
|
456
|
+
},
|
|
457
|
+
template: `
|
|
458
|
+
<div>
|
|
459
|
+
<kv-carousel
|
|
460
|
+
ref="sampleCarousel"
|
|
461
|
+
style="max-width: 400px;"
|
|
462
|
+
:embla-options="{ loop: false }"
|
|
463
|
+
:autoplay-options="{ playOnInit: true, delay: 3000 }"
|
|
464
|
+
@interact-carousel="carouselInteraction"
|
|
465
|
+
>
|
|
466
|
+
${defaultCarouselSlides}
|
|
467
|
+
</kv-carousel>
|
|
468
|
+
<a href="#" @click.native.prevent="toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
|
|
469
|
+
<br/>
|
|
470
|
+
<p>AutoPlay is: {{ isPlaying ? 'ON' : 'OFF' }}</p>
|
|
471
|
+
</div>
|
|
472
|
+
`,
|
|
473
|
+
methods: {
|
|
474
|
+
toggleAutoPlay() {
|
|
475
|
+
this.$refs.sampleCarousel.toggleAutoPlay();
|
|
476
|
+
},
|
|
477
|
+
carouselInteraction() {
|
|
478
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
export const Fade = () => ({
|
|
484
|
+
components: {
|
|
485
|
+
KvCarousel,
|
|
486
|
+
},
|
|
487
|
+
mounted() {
|
|
488
|
+
this.$nextTick(() => {
|
|
489
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
template: `
|
|
493
|
+
<div>
|
|
494
|
+
<kv-carousel
|
|
495
|
+
ref="sampleCarousel"
|
|
496
|
+
style="max-width: 400px;"
|
|
497
|
+
:embla-options="{ loop: false }"
|
|
498
|
+
:fade-enabled="true"
|
|
499
|
+
>
|
|
500
|
+
${defaultCarouselSlides}
|
|
501
|
+
</kv-carousel>
|
|
502
|
+
</div>
|
|
503
|
+
`,
|
|
504
|
+
});
|
|
@@ -166,3 +166,81 @@ export const CustomStartIndex = () => ({
|
|
|
166
166
|
</kv-vertical-carousel>
|
|
167
167
|
`,
|
|
168
168
|
});
|
|
169
|
+
|
|
170
|
+
export const AutoPlayAutomatically = () => ({
|
|
171
|
+
components: {
|
|
172
|
+
KvVerticalCarousel,
|
|
173
|
+
},
|
|
174
|
+
template: `
|
|
175
|
+
<kv-vertical-carousel
|
|
176
|
+
style="max-width: 400px;"
|
|
177
|
+
:embla-options="{ loop: false }"
|
|
178
|
+
:autoplay-options="{ playOnInit: true, delay: 3000 }"
|
|
179
|
+
>
|
|
180
|
+
${defaultCarouselSlides}
|
|
181
|
+
</kv-vertical-carousel>
|
|
182
|
+
`,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
export const AutoPlayButton = () => ({
|
|
186
|
+
components: {
|
|
187
|
+
KvVerticalCarousel,
|
|
188
|
+
},
|
|
189
|
+
data() {
|
|
190
|
+
return {
|
|
191
|
+
isPlaying: false,
|
|
192
|
+
};
|
|
193
|
+
},
|
|
194
|
+
mounted() {
|
|
195
|
+
this.$nextTick(() => {
|
|
196
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
template: `
|
|
200
|
+
<div>
|
|
201
|
+
<kv-vertical-carousel
|
|
202
|
+
ref="sampleCarousel"
|
|
203
|
+
style="max-width: 400px;"
|
|
204
|
+
:embla-options="{ loop: false }"
|
|
205
|
+
:autoplay-options="{ playOnInit: true, delay: 3000 }"
|
|
206
|
+
@interact-carousel="carouselInteraction"
|
|
207
|
+
>
|
|
208
|
+
${defaultCarouselSlides}
|
|
209
|
+
</kv-vertical-carousel>
|
|
210
|
+
<a href="#" @click.native.prevent="toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
|
|
211
|
+
<br/>
|
|
212
|
+
<p>AutoPlay is: {{ isPlaying ? 'ON' : 'OFF' }}</p>
|
|
213
|
+
</div>
|
|
214
|
+
`,
|
|
215
|
+
methods: {
|
|
216
|
+
toggleAutoPlay() {
|
|
217
|
+
this.$refs.sampleCarousel.toggleAutoPlay();
|
|
218
|
+
},
|
|
219
|
+
carouselInteraction() {
|
|
220
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
export const Fade = () => ({
|
|
226
|
+
components: {
|
|
227
|
+
KvVerticalCarousel,
|
|
228
|
+
},
|
|
229
|
+
mounted() {
|
|
230
|
+
this.$nextTick(() => {
|
|
231
|
+
this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
template: `
|
|
235
|
+
<div>
|
|
236
|
+
<kv-vertical-carousel
|
|
237
|
+
ref="sampleCarousel"
|
|
238
|
+
style="max-width: 400px;"
|
|
239
|
+
:embla-options="{ loop: false }"
|
|
240
|
+
:fade-enabled="true"
|
|
241
|
+
>
|
|
242
|
+
${defaultCarouselSlides}
|
|
243
|
+
</kv-vertical-carousel>
|
|
244
|
+
</div>
|
|
245
|
+
`,
|
|
246
|
+
});
|