@kiva/kv-components 4.6.0 → 4.7.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 CHANGED
@@ -3,6 +3,28 @@
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.7.1](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@4.7.0...@kiva/kv-components@4.7.1) (2025-01-09)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * preset button was adding to basket because of type ([994a42f](https://github.com/kiva/kv-ui-elements/commit/994a42f36b2065c57994d1903c48ad9a14ad5c69))
12
+
13
+
14
+
15
+
16
+
17
+ # [4.7.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@4.6.0...@kiva/kv-components@4.7.0) (2025-01-09)
18
+
19
+
20
+ ### Features
21
+
22
+ * add autoplay button if autoplay plugin is enabled ([8bebbe5](https://github.com/kiva/kv-ui-elements/commit/8bebbe5945dd4e34c922f9f511a4145564ae005a))
23
+
24
+
25
+
26
+
27
+
6
28
  # [4.6.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@4.5.1...@kiva/kv-components@4.6.0) (2025-01-08)
7
29
 
8
30
 
@@ -71,7 +71,6 @@
71
71
  class="tw-inline-flex tw-flex-1 preset-option tw-w-8"
72
72
  :class="{'selected-option': selectedOption == option }"
73
73
  data-testid="bp-lend-cta-lend-button"
74
- type="submit"
75
74
  @click="clickPresetButton(option)"
76
75
  >
77
76
  ${{ option }}
@@ -29,40 +29,69 @@
29
29
  <!-- Carousel Controls -->
30
30
  <div
31
31
  class="kv-carousel__controls tw-flex
32
- tw-justify-between md:tw-justify-center tw-items-center tw-gap-2
33
- tw-mt-2 tw-w-full"
32
+ tw-items-center tw-gap-2
33
+ tw-mt-2 tw-w-full
34
+ tw-justify-between md:tw-justify-center"
34
35
  >
35
- <button
36
- class="tw-text-primary
36
+ <div
37
+ class="tw-flex tw-gap-2 tw-w-full md:tw-w-auto"
38
+ :class="{'tw-justify-between md:tw-justify-center': !hasAutoplay}"
39
+ >
40
+ <button
41
+ class="tw-text-primary
37
42
  tw-rounded-full
38
43
  tw-border-2 tw-border-primary
39
44
  tw-h-4 tw-w-4
40
45
  tw-flex tw-items-center tw-justify-center
41
46
  disabled:tw-opacity-low disabled:tw-cursor-default"
42
- :disabled="embla && !embla.canScrollPrev()"
43
- @click="handleUserInteraction(previousIndex, 'click-left-arrow')"
44
- >
45
- <kv-material-icon
46
- class="tw-w-4"
47
- :icon="mdiChevronUp"
48
- />
49
- <span class="tw-sr-only">Show previous slide</span>
50
- </button>
47
+ :disabled="embla && !embla.canScrollPrev()"
48
+ @click="handleUserInteraction(previousIndex, 'click-left-arrow')"
49
+ >
50
+ <kv-material-icon
51
+ class="tw-w-4"
52
+ :icon="mdiChevronUp"
53
+ />
54
+ <span class="tw-sr-only">Show previous slide</span>
55
+ </button>
56
+ <button
57
+ class="tw-text-primary
58
+ tw-rounded-full
59
+ tw-border-2 tw-border-primary
60
+ tw-h-4 tw-w-4
61
+ tw-flex tw-items-center tw-justify-center
62
+ disabled:tw-opacity-low disabled:tw-cursor-default"
63
+ :disabled="embla && !embla.canScrollNext()"
64
+ @click="handleUserInteraction(nextIndex, 'click-right-arrow')"
65
+ >
66
+ <kv-material-icon
67
+ class="tw-w-4"
68
+ :icon="mdiChevronDown"
69
+ />
70
+ <span class="tw-sr-only">Show next slide</span>
71
+ </button>
72
+ </div>
73
+
51
74
  <button
75
+ v-if="hasAutoplay"
52
76
  class="tw-text-primary
53
77
  tw-rounded-full
54
78
  tw-border-2 tw-border-primary
55
79
  tw-h-4 tw-w-4
56
80
  tw-flex tw-items-center tw-justify-center
57
81
  disabled:tw-opacity-low disabled:tw-cursor-default"
58
- :disabled="embla && !embla.canScrollNext()"
59
- @click="handleUserInteraction(nextIndex, 'click-right-arrow')"
82
+ @click.native.prevent="toggleAutoPlay()"
60
83
  >
61
84
  <kv-material-icon
85
+ v-if="isAutoplaying"
62
86
  class="tw-w-4"
63
- :icon="mdiChevronDown"
87
+ :icon="mdiPause"
64
88
  />
65
- <span class="tw-sr-only">Show next slide</span>
89
+ <kv-material-icon
90
+ v-else
91
+ class="tw-w-4"
92
+ :icon="mdiPlay"
93
+ />
94
+ <span class="tw-sr-only">Show previous slide</span>
66
95
  </button>
67
96
  </div>
68
97
  </div>
@@ -70,9 +99,15 @@
70
99
 
71
100
  <script>
72
101
  import {
102
+ toRefs,
103
+ } from 'vue-demi';
104
+ import {
105
+ mdiPause,
106
+ mdiPlay,
73
107
  mdiChevronUp,
74
108
  mdiChevronDown,
75
109
  } from '@mdi/js';
110
+ import { computed } from 'vue';
76
111
  import { carouselUtil } from '../utils/carousels';
77
112
  import KvMaterialIcon from './KvMaterialIcon.vue';
78
113
 
@@ -129,6 +164,10 @@ export default {
129
164
  'interact-carousel',
130
165
  ],
131
166
  setup(props, { emit, slots }) {
167
+ const {
168
+ autoplayOptions,
169
+ } = toRefs(props);
170
+
132
171
  const {
133
172
  componentSlotKeys,
134
173
  currentIndex,
@@ -148,7 +187,12 @@ export default {
148
187
  toggleAutoPlay,
149
188
  } = carouselUtil(props, { emit, slots }, { axis: 'y' });
150
189
 
190
+ const hasAutoplay = computed(() => {
191
+ return Object.keys(autoplayOptions.value).length !== 0;
192
+ });
193
+
151
194
  return {
195
+ hasAutoplay,
152
196
  componentSlotKeys,
153
197
  currentIndex,
154
198
  embla,
@@ -156,6 +200,8 @@ export default {
156
200
  handleUserInteraction,
157
201
  isAriaHidden,
158
202
  isAutoplaying,
203
+ mdiPause,
204
+ mdiPlay,
159
205
  mdiChevronDown,
160
206
  mdiChevronUp,
161
207
  nextIndex,
@@ -1,3 +1,4 @@
1
+ import { watch } from 'vue';
1
2
  import KvCarousel from '../KvCarousel.vue';
2
3
  import KvLoadingSpinner from '../KvLoadingSpinner.vue';
3
4
  import KvButton from '../KvButton.vue';
@@ -444,14 +445,12 @@ export const AutoPlayButton = () => ({
444
445
  components: {
445
446
  KvCarousel,
446
447
  },
447
- data() {
448
- return {
449
- isPlaying: false,
450
- };
451
- },
448
+ data: () => ({
449
+ isAutoplaying: false,
450
+ }),
452
451
  mounted() {
453
- this.$nextTick(() => {
454
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
452
+ watch(() => this.$refs?.sampleCarousel?.isAutoplaying, (newValue) => {
453
+ this.isAutoplaying = newValue;
455
454
  });
456
455
  },
457
456
  template: `
@@ -461,34 +460,20 @@ export const AutoPlayButton = () => ({
461
460
  style="max-width: 400px;"
462
461
  :embla-options="{ loop: false }"
463
462
  :autoplay-options="{ playOnInit: true, delay: 3000 }"
464
- @interact-carousel="carouselInteraction"
465
463
  >
466
464
  ${defaultCarouselSlides}
467
465
  </kv-carousel>
468
- <a href="#" @click.native.prevent="toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
466
+ <a href="#" @click.native.prevent="$refs.sampleCarousel.toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
469
467
  <br/>
470
- <p>AutoPlay is: {{ isPlaying ? 'ON' : 'OFF' }}</p>
468
+ <p>AutoPlay is: {{ isAutoplaying ? 'ON' : 'OFF' }}</p>
471
469
  </div>
472
470
  `,
473
- methods: {
474
- toggleAutoPlay() {
475
- this.$refs.sampleCarousel.toggleAutoPlay();
476
- },
477
- carouselInteraction() {
478
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
479
- },
480
- },
481
471
  });
482
472
 
483
473
  export const Fade = () => ({
484
474
  components: {
485
475
  KvCarousel,
486
476
  },
487
- mounted() {
488
- this.$nextTick(() => {
489
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
490
- });
491
- },
492
477
  template: `
493
478
  <div>
494
479
  <kv-carousel
@@ -1,3 +1,4 @@
1
+ import { watch } from 'vue';
1
2
  import KvVerticalCarousel from '../KvVerticalCarousel.vue';
2
3
  import KvButton from '../KvButton.vue';
3
4
 
@@ -186,14 +187,12 @@ export const AutoPlayButton = () => ({
186
187
  components: {
187
188
  KvVerticalCarousel,
188
189
  },
189
- data() {
190
- return {
191
- isPlaying: false,
192
- };
193
- },
190
+ data: () => ({
191
+ isAutoplaying: false,
192
+ }),
194
193
  mounted() {
195
- this.$nextTick(() => {
196
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
194
+ watch(() => this.$refs?.sampleCarousel?.isAutoplaying, (newValue) => {
195
+ this.isAutoplaying = newValue;
197
196
  });
198
197
  },
199
198
  template: `
@@ -203,34 +202,21 @@ export const AutoPlayButton = () => ({
203
202
  style="max-width: 400px;"
204
203
  :embla-options="{ loop: false }"
205
204
  :autoplay-options="{ playOnInit: true, delay: 3000 }"
206
- @interact-carousel="carouselInteraction"
207
205
  >
208
206
  ${defaultCarouselSlides}
209
207
  </kv-vertical-carousel>
210
- <a href="#" @click.native.prevent="toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
208
+ <a href="#" @click.native.prevent="$refs.sampleCarousel.toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
211
209
  <br/>
212
- <p>AutoPlay is: {{ isPlaying ? 'ON' : 'OFF' }}</p>
210
+ <p>AutoPlay is: {{ isAutoplaying ? 'ON' : 'OFF' }}</p>
213
211
  </div>
214
212
  `,
215
- methods: {
216
- toggleAutoPlay() {
217
- this.$refs.sampleCarousel.toggleAutoPlay();
218
- },
219
- carouselInteraction() {
220
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
221
- },
222
- },
223
213
  });
224
214
 
215
+ /** Fade really only works when the carousel displays 1 slide at a time, this story is wonky as expected */
225
216
  export const Fade = () => ({
226
217
  components: {
227
218
  KvVerticalCarousel,
228
219
  },
229
- mounted() {
230
- this.$nextTick(() => {
231
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
232
- });
233
- },
234
220
  template: `
235
221
  <div>
236
222
  <kv-vertical-carousel
@@ -61,6 +61,7 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
61
61
  const rootEl = (0, import_vue_demi.ref)(null);
62
62
  const embla = (0, import_vue_demi.ref)(null);
63
63
  const slides = (0, import_vue_demi.ref)([]);
64
+ const isAutoplaying = (0, import_vue_demi.ref)(false);
64
65
  const startIndex = ((_a = emblaOptions.value) == null ? void 0 : _a.startIndex) ?? 0;
65
66
  const currentIndex = (0, import_vue_demi.ref)(startIndex);
66
67
  const slideIndicatorCount = (0, import_vue_demi.ref)(0);
@@ -86,10 +87,15 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
86
87
  embla.value.scrollTo(index);
87
88
  };
88
89
  const handleUserInteraction = async (index, interactionType) => {
90
+ var _a2, _b;
89
91
  if (index !== null && typeof index !== "undefined") {
90
92
  await (0, import_vue_demi.nextTick)();
91
93
  goToSlide(index);
92
94
  }
95
+ const autoplay = (_b = (_a2 = embla.value) == null ? void 0 : _a2.plugins()) == null ? void 0 : _b.autoplay;
96
+ if (autoplay) {
97
+ autoplay.stop();
98
+ }
93
99
  emit("interact-carousel", interactionType);
94
100
  };
95
101
  const toggleAutoPlay = () => {
@@ -99,14 +105,6 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
99
105
  return;
100
106
  const playOrStop = autoplay.isPlaying() ? autoplay.stop : autoplay.play;
101
107
  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
108
  };
111
109
  const slideIndicatorListLength = () => {
112
110
  const indicator = embla.value ? embla.value.scrollSnapList().length : 0;
@@ -143,7 +141,7 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
143
141
  return false;
144
142
  };
145
143
  (0, import_vue_demi.onMounted)(async () => {
146
- var _a2;
144
+ var _a2, _b, _c;
147
145
  const combinedPluginOptions = [];
148
146
  if (Object.keys(autoplayOptions.value).length !== 0) {
149
147
  combinedPluginOptions.push((0, import_embla_carousel_autoplay.default)(autoplayOptions.value));
@@ -181,11 +179,21 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
181
179
  emit("change", currentIndex);
182
180
  });
183
181
  });
182
+ (_b = embla == null ? void 0 : embla.value) == null ? void 0 : _b.on("autoplay:play", () => {
183
+ console.log("autoplay:play");
184
+ isAutoplaying.value = true;
185
+ });
186
+ (_c = embla == null ? void 0 : embla.value) == null ? void 0 : _c.on("autoplay:stop", () => {
187
+ console.log("autoplay:stop");
188
+ isAutoplaying.value = false;
189
+ });
184
190
  });
185
191
  (0, import_vue_demi.onUnmounted)(async () => {
186
- var _a2, _b;
192
+ var _a2, _b, _c, _d;
187
193
  (_a2 = embla == null ? void 0 : embla.value) == null ? void 0 : _a2.off("select");
188
- (_b = embla == null ? void 0 : embla.value) == null ? void 0 : _b.destroy();
194
+ (_b = embla == null ? void 0 : embla.value) == null ? void 0 : _b.off("autoplay:play");
195
+ (_c = embla == null ? void 0 : embla.value) == null ? void 0 : _c.off("autoplay:stop");
196
+ (_d = embla == null ? void 0 : embla.value) == null ? void 0 : _d.destroy();
189
197
  });
190
198
  return {
191
199
  rootEl,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  carouselUtil
3
- } from "./chunk-P6FXCNYP.js";
3
+ } from "./chunk-WLQNGWMC.js";
4
4
  import "./chunk-HV3AUBFT.js";
5
5
  import "./chunk-YCNMJ4YV.js";
6
6
  export {
@@ -25,6 +25,7 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
25
25
  const rootEl = ref(null);
26
26
  const embla = ref(null);
27
27
  const slides = ref([]);
28
+ const isAutoplaying = ref(false);
28
29
  const startIndex = ((_a = emblaOptions.value) == null ? void 0 : _a.startIndex) ?? 0;
29
30
  const currentIndex = ref(startIndex);
30
31
  const slideIndicatorCount = ref(0);
@@ -50,10 +51,15 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
50
51
  embla.value.scrollTo(index);
51
52
  };
52
53
  const handleUserInteraction = async (index, interactionType) => {
54
+ var _a2, _b;
53
55
  if (index !== null && typeof index !== "undefined") {
54
56
  await nextTick();
55
57
  goToSlide(index);
56
58
  }
59
+ const autoplay = (_b = (_a2 = embla.value) == null ? void 0 : _a2.plugins()) == null ? void 0 : _b.autoplay;
60
+ if (autoplay) {
61
+ autoplay.stop();
62
+ }
57
63
  emit("interact-carousel", interactionType);
58
64
  };
59
65
  const toggleAutoPlay = () => {
@@ -63,14 +69,6 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
63
69
  return;
64
70
  const playOrStop = autoplay.isPlaying() ? autoplay.stop : autoplay.play;
65
71
  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
72
  };
75
73
  const slideIndicatorListLength = () => {
76
74
  const indicator = embla.value ? embla.value.scrollSnapList().length : 0;
@@ -107,7 +105,7 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
107
105
  return false;
108
106
  };
109
107
  onMounted(async () => {
110
- var _a2;
108
+ var _a2, _b, _c;
111
109
  const combinedPluginOptions = [];
112
110
  if (Object.keys(autoplayOptions.value).length !== 0) {
113
111
  combinedPluginOptions.push(Autoplay(autoplayOptions.value));
@@ -145,11 +143,21 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
145
143
  emit("change", currentIndex);
146
144
  });
147
145
  });
146
+ (_b = embla == null ? void 0 : embla.value) == null ? void 0 : _b.on("autoplay:play", () => {
147
+ console.log("autoplay:play");
148
+ isAutoplaying.value = true;
149
+ });
150
+ (_c = embla == null ? void 0 : embla.value) == null ? void 0 : _c.on("autoplay:stop", () => {
151
+ console.log("autoplay:stop");
152
+ isAutoplaying.value = false;
153
+ });
148
154
  });
149
155
  onUnmounted(async () => {
150
- var _a2, _b;
156
+ var _a2, _b, _c, _d;
151
157
  (_a2 = embla == null ? void 0 : embla.value) == null ? void 0 : _a2.off("select");
152
- (_b = embla == null ? void 0 : embla.value) == null ? void 0 : _b.destroy();
158
+ (_b = embla == null ? void 0 : embla.value) == null ? void 0 : _b.off("autoplay:play");
159
+ (_c = embla == null ? void 0 : embla.value) == null ? void 0 : _c.off("autoplay:stop");
160
+ (_d = embla == null ? void 0 : embla.value) == null ? void 0 : _d.destroy();
153
161
  });
154
162
  return {
155
163
  rootEl,
@@ -169,6 +169,7 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
169
169
  const rootEl = (0, import_vue_demi.ref)(null);
170
170
  const embla = (0, import_vue_demi.ref)(null);
171
171
  const slides = (0, import_vue_demi.ref)([]);
172
+ const isAutoplaying = (0, import_vue_demi.ref)(false);
172
173
  const startIndex = ((_a = emblaOptions.value) == null ? void 0 : _a.startIndex) ?? 0;
173
174
  const currentIndex = (0, import_vue_demi.ref)(startIndex);
174
175
  const slideIndicatorCount = (0, import_vue_demi.ref)(0);
@@ -194,10 +195,15 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
194
195
  embla.value.scrollTo(index);
195
196
  };
196
197
  const handleUserInteraction = async (index, interactionType) => {
198
+ var _a2, _b;
197
199
  if (index !== null && typeof index !== "undefined") {
198
200
  await (0, import_vue_demi.nextTick)();
199
201
  goToSlide(index);
200
202
  }
203
+ const autoplay = (_b = (_a2 = embla.value) == null ? void 0 : _a2.plugins()) == null ? void 0 : _b.autoplay;
204
+ if (autoplay) {
205
+ autoplay.stop();
206
+ }
201
207
  emit("interact-carousel", interactionType);
202
208
  };
203
209
  const toggleAutoPlay = () => {
@@ -207,14 +213,6 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
207
213
  return;
208
214
  const playOrStop = autoplay.isPlaying() ? autoplay.stop : autoplay.play;
209
215
  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
216
  };
219
217
  const slideIndicatorListLength = () => {
220
218
  const indicator = embla.value ? embla.value.scrollSnapList().length : 0;
@@ -251,7 +249,7 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
251
249
  return false;
252
250
  };
253
251
  (0, import_vue_demi.onMounted)(async () => {
254
- var _a2;
252
+ var _a2, _b, _c;
255
253
  const combinedPluginOptions = [];
256
254
  if (Object.keys(autoplayOptions.value).length !== 0) {
257
255
  combinedPluginOptions.push((0, import_embla_carousel_autoplay.default)(autoplayOptions.value));
@@ -289,11 +287,21 @@ function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
289
287
  emit("change", currentIndex);
290
288
  });
291
289
  });
290
+ (_b = embla == null ? void 0 : embla.value) == null ? void 0 : _b.on("autoplay:play", () => {
291
+ console.log("autoplay:play");
292
+ isAutoplaying.value = true;
293
+ });
294
+ (_c = embla == null ? void 0 : embla.value) == null ? void 0 : _c.on("autoplay:stop", () => {
295
+ console.log("autoplay:stop");
296
+ isAutoplaying.value = false;
297
+ });
292
298
  });
293
299
  (0, import_vue_demi.onUnmounted)(async () => {
294
- var _a2, _b;
300
+ var _a2, _b, _c, _d;
295
301
  (_a2 = embla == null ? void 0 : embla.value) == null ? void 0 : _a2.off("select");
296
- (_b = embla == null ? void 0 : embla.value) == null ? void 0 : _b.destroy();
302
+ (_b = embla == null ? void 0 : embla.value) == null ? void 0 : _b.off("autoplay:play");
303
+ (_c = embla == null ? void 0 : embla.value) == null ? void 0 : _c.off("autoplay:stop");
304
+ (_d = embla == null ? void 0 : embla.value) == null ? void 0 : _d.destroy();
297
305
  });
298
306
  return {
299
307
  rootEl,
@@ -31,7 +31,7 @@ import {
31
31
  } from "./chunk-3HK4G4NT.js";
32
32
  import {
33
33
  carouselUtil
34
- } from "./chunk-P6FXCNYP.js";
34
+ } from "./chunk-WLQNGWMC.js";
35
35
  import {
36
36
  throttle
37
37
  } from "./chunk-HV3AUBFT.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kiva/kv-components",
3
- "version": "4.6.0",
3
+ "version": "4.7.1",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -98,5 +98,5 @@
98
98
  "peerDependencies": {
99
99
  "vue": ">=3.0.0"
100
100
  },
101
- "gitHead": "4e5a4bbf728bcf6d7c29c291591cf52798230cb0"
101
+ "gitHead": "ee93a71b07a2a0228281ead8f175f152fc533ac8"
102
102
  }
@@ -22,6 +22,8 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
22
22
  const rootEl = ref(null);
23
23
  const embla = ref(null);
24
24
  const slides = ref([]);
25
+ const isAutoplaying = ref(false);
26
+
25
27
  const startIndex = emblaOptions.value?.startIndex ?? 0;
26
28
  const currentIndex = ref(startIndex);
27
29
  // The indicator count may differ from the slide count when multiple slides are in view
@@ -63,6 +65,13 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
63
65
  await nextTick(); // wait for embla.
64
66
  goToSlide(index);
65
67
  }
68
+
69
+ /** Stop autoplay on user interaction */
70
+ const autoplay = embla.value?.plugins()?.autoplay;
71
+ if (autoplay) {
72
+ autoplay.stop();
73
+ }
74
+
66
75
  /**
67
76
  * Fires when the user interacts with the carousel.
68
77
  * Contains the interaction type (swipe-left, click-left-arrow, etc.)
@@ -81,19 +90,8 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
81
90
  if (!autoplay) return;
82
91
  const playOrStop = autoplay.isPlaying() ? autoplay.stop : autoplay.play;
83
92
  playOrStop();
84
- handleUserInteraction(null, 'autoplay');
85
93
  };
86
94
 
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
- };
97
95
  /**
98
96
  * Returns number of slides in the carousel
99
97
  *
@@ -198,10 +196,32 @@ export function carouselUtil(props, { emit, slots }, extraEmblaOptions) {
198
196
  emit('change', currentIndex);
199
197
  });
200
198
  });
199
+
200
+ embla?.value?.on('autoplay:play', () => {
201
+ console.log('autoplay:play');
202
+ /**
203
+ * Fires when autoplay starts
204
+ * @event autoplay-play
205
+ * @type {Event}
206
+ */
207
+ isAutoplaying.value = true;
208
+ });
209
+
210
+ embla?.value?.on('autoplay:stop', () => {
211
+ console.log('autoplay:stop');
212
+ /**
213
+ * Fires when autoplay starts
214
+ * @event autoplay-play
215
+ * @type {Event}
216
+ */
217
+ isAutoplaying.value = false;
218
+ });
201
219
  });
202
220
 
203
221
  onUnmounted(async () => {
204
222
  embla?.value?.off('select');
223
+ embla?.value?.off('autoplay:play');
224
+ embla?.value?.off('autoplay:stop');
205
225
  embla?.value?.destroy();
206
226
  });
207
227
 
package/vue/KvLendCta.vue CHANGED
@@ -71,7 +71,6 @@
71
71
  class="tw-inline-flex tw-flex-1 preset-option tw-w-8"
72
72
  :class="{'selected-option': selectedOption == option }"
73
73
  data-testid="bp-lend-cta-lend-button"
74
- type="submit"
75
74
  @click="clickPresetButton(option)"
76
75
  >
77
76
  ${{ option }}
@@ -29,40 +29,69 @@
29
29
  <!-- Carousel Controls -->
30
30
  <div
31
31
  class="kv-carousel__controls tw-flex
32
- tw-justify-between md:tw-justify-center tw-items-center tw-gap-2
33
- tw-mt-2 tw-w-full"
32
+ tw-items-center tw-gap-2
33
+ tw-mt-2 tw-w-full
34
+ tw-justify-between md:tw-justify-center"
34
35
  >
35
- <button
36
- class="tw-text-primary
36
+ <div
37
+ class="tw-flex tw-gap-2 tw-w-full md:tw-w-auto"
38
+ :class="{'tw-justify-between md:tw-justify-center': !hasAutoplay}"
39
+ >
40
+ <button
41
+ class="tw-text-primary
37
42
  tw-rounded-full
38
43
  tw-border-2 tw-border-primary
39
44
  tw-h-4 tw-w-4
40
45
  tw-flex tw-items-center tw-justify-center
41
46
  disabled:tw-opacity-low disabled:tw-cursor-default"
42
- :disabled="embla && !embla.canScrollPrev()"
43
- @click="handleUserInteraction(previousIndex, 'click-left-arrow')"
44
- >
45
- <kv-material-icon
46
- class="tw-w-4"
47
- :icon="mdiChevronUp"
48
- />
49
- <span class="tw-sr-only">Show previous slide</span>
50
- </button>
47
+ :disabled="embla && !embla.canScrollPrev()"
48
+ @click="handleUserInteraction(previousIndex, 'click-left-arrow')"
49
+ >
50
+ <kv-material-icon
51
+ class="tw-w-4"
52
+ :icon="mdiChevronUp"
53
+ />
54
+ <span class="tw-sr-only">Show previous slide</span>
55
+ </button>
56
+ <button
57
+ class="tw-text-primary
58
+ tw-rounded-full
59
+ tw-border-2 tw-border-primary
60
+ tw-h-4 tw-w-4
61
+ tw-flex tw-items-center tw-justify-center
62
+ disabled:tw-opacity-low disabled:tw-cursor-default"
63
+ :disabled="embla && !embla.canScrollNext()"
64
+ @click="handleUserInteraction(nextIndex, 'click-right-arrow')"
65
+ >
66
+ <kv-material-icon
67
+ class="tw-w-4"
68
+ :icon="mdiChevronDown"
69
+ />
70
+ <span class="tw-sr-only">Show next slide</span>
71
+ </button>
72
+ </div>
73
+
51
74
  <button
75
+ v-if="hasAutoplay"
52
76
  class="tw-text-primary
53
77
  tw-rounded-full
54
78
  tw-border-2 tw-border-primary
55
79
  tw-h-4 tw-w-4
56
80
  tw-flex tw-items-center tw-justify-center
57
81
  disabled:tw-opacity-low disabled:tw-cursor-default"
58
- :disabled="embla && !embla.canScrollNext()"
59
- @click="handleUserInteraction(nextIndex, 'click-right-arrow')"
82
+ @click.native.prevent="toggleAutoPlay()"
60
83
  >
61
84
  <kv-material-icon
85
+ v-if="isAutoplaying"
62
86
  class="tw-w-4"
63
- :icon="mdiChevronDown"
87
+ :icon="mdiPause"
64
88
  />
65
- <span class="tw-sr-only">Show next slide</span>
89
+ <kv-material-icon
90
+ v-else
91
+ class="tw-w-4"
92
+ :icon="mdiPlay"
93
+ />
94
+ <span class="tw-sr-only">Show previous slide</span>
66
95
  </button>
67
96
  </div>
68
97
  </div>
@@ -70,9 +99,15 @@
70
99
 
71
100
  <script>
72
101
  import {
102
+ toRefs,
103
+ } from 'vue-demi';
104
+ import {
105
+ mdiPause,
106
+ mdiPlay,
73
107
  mdiChevronUp,
74
108
  mdiChevronDown,
75
109
  } from '@mdi/js';
110
+ import { computed } from 'vue';
76
111
  import { carouselUtil } from '../utils/carousels';
77
112
  import KvMaterialIcon from './KvMaterialIcon.vue';
78
113
 
@@ -129,6 +164,10 @@ export default {
129
164
  'interact-carousel',
130
165
  ],
131
166
  setup(props, { emit, slots }) {
167
+ const {
168
+ autoplayOptions,
169
+ } = toRefs(props);
170
+
132
171
  const {
133
172
  componentSlotKeys,
134
173
  currentIndex,
@@ -148,7 +187,12 @@ export default {
148
187
  toggleAutoPlay,
149
188
  } = carouselUtil(props, { emit, slots }, { axis: 'y' });
150
189
 
190
+ const hasAutoplay = computed(() => {
191
+ return Object.keys(autoplayOptions.value).length !== 0;
192
+ });
193
+
151
194
  return {
195
+ hasAutoplay,
152
196
  componentSlotKeys,
153
197
  currentIndex,
154
198
  embla,
@@ -156,6 +200,8 @@ export default {
156
200
  handleUserInteraction,
157
201
  isAriaHidden,
158
202
  isAutoplaying,
203
+ mdiPause,
204
+ mdiPlay,
159
205
  mdiChevronDown,
160
206
  mdiChevronUp,
161
207
  nextIndex,
@@ -1,3 +1,4 @@
1
+ import { watch } from 'vue';
1
2
  import KvCarousel from '../KvCarousel.vue';
2
3
  import KvLoadingSpinner from '../KvLoadingSpinner.vue';
3
4
  import KvButton from '../KvButton.vue';
@@ -444,14 +445,12 @@ export const AutoPlayButton = () => ({
444
445
  components: {
445
446
  KvCarousel,
446
447
  },
447
- data() {
448
- return {
449
- isPlaying: false,
450
- };
451
- },
448
+ data: () => ({
449
+ isAutoplaying: false,
450
+ }),
452
451
  mounted() {
453
- this.$nextTick(() => {
454
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
452
+ watch(() => this.$refs?.sampleCarousel?.isAutoplaying, (newValue) => {
453
+ this.isAutoplaying = newValue;
455
454
  });
456
455
  },
457
456
  template: `
@@ -461,34 +460,20 @@ export const AutoPlayButton = () => ({
461
460
  style="max-width: 400px;"
462
461
  :embla-options="{ loop: false }"
463
462
  :autoplay-options="{ playOnInit: true, delay: 3000 }"
464
- @interact-carousel="carouselInteraction"
465
463
  >
466
464
  ${defaultCarouselSlides}
467
465
  </kv-carousel>
468
- <a href="#" @click.native.prevent="toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
466
+ <a href="#" @click.native.prevent="$refs.sampleCarousel.toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
469
467
  <br/>
470
- <p>AutoPlay is: {{ isPlaying ? 'ON' : 'OFF' }}</p>
468
+ <p>AutoPlay is: {{ isAutoplaying ? 'ON' : 'OFF' }}</p>
471
469
  </div>
472
470
  `,
473
- methods: {
474
- toggleAutoPlay() {
475
- this.$refs.sampleCarousel.toggleAutoPlay();
476
- },
477
- carouselInteraction() {
478
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
479
- },
480
- },
481
471
  });
482
472
 
483
473
  export const Fade = () => ({
484
474
  components: {
485
475
  KvCarousel,
486
476
  },
487
- mounted() {
488
- this.$nextTick(() => {
489
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
490
- });
491
- },
492
477
  template: `
493
478
  <div>
494
479
  <kv-carousel
@@ -1,3 +1,4 @@
1
+ import { watch } from 'vue';
1
2
  import KvVerticalCarousel from '../KvVerticalCarousel.vue';
2
3
  import KvButton from '../KvButton.vue';
3
4
 
@@ -186,14 +187,12 @@ export const AutoPlayButton = () => ({
186
187
  components: {
187
188
  KvVerticalCarousel,
188
189
  },
189
- data() {
190
- return {
191
- isPlaying: false,
192
- };
193
- },
190
+ data: () => ({
191
+ isAutoplaying: false,
192
+ }),
194
193
  mounted() {
195
- this.$nextTick(() => {
196
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
194
+ watch(() => this.$refs?.sampleCarousel?.isAutoplaying, (newValue) => {
195
+ this.isAutoplaying = newValue;
197
196
  });
198
197
  },
199
198
  template: `
@@ -203,34 +202,21 @@ export const AutoPlayButton = () => ({
203
202
  style="max-width: 400px;"
204
203
  :embla-options="{ loop: false }"
205
204
  :autoplay-options="{ playOnInit: true, delay: 3000 }"
206
- @interact-carousel="carouselInteraction"
207
205
  >
208
206
  ${defaultCarouselSlides}
209
207
  </kv-vertical-carousel>
210
- <a href="#" @click.native.prevent="toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
208
+ <a href="#" @click.native.prevent="$refs.sampleCarousel.toggleAutoPlay()" role="toggleAutoPlayButton">Toggle AutoPlay</a>
211
209
  <br/>
212
- <p>AutoPlay is: {{ isPlaying ? 'ON' : 'OFF' }}</p>
210
+ <p>AutoPlay is: {{ isAutoplaying ? 'ON' : 'OFF' }}</p>
213
211
  </div>
214
212
  `,
215
- methods: {
216
- toggleAutoPlay() {
217
- this.$refs.sampleCarousel.toggleAutoPlay();
218
- },
219
- carouselInteraction() {
220
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
221
- },
222
- },
223
213
  });
224
214
 
215
+ /** Fade really only works when the carousel displays 1 slide at a time, this story is wonky as expected */
225
216
  export const Fade = () => ({
226
217
  components: {
227
218
  KvVerticalCarousel,
228
219
  },
229
- mounted() {
230
- this.$nextTick(() => {
231
- this.isPlaying = this.$refs.sampleCarousel.isAutoplaying();
232
- });
233
- },
234
220
  template: `
235
221
  <div>
236
222
  <kv-vertical-carousel