@kiva/kv-components 4.5.1 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/components/KvLendCta.vue +151 -13
- package/dist/components/KvVerticalCarousel.vue +63 -17
- package/dist/components/stories/KvCarousel.stories.js +8 -23
- package/dist/components/stories/KvLendCta.stories.js +166 -0
- package/dist/components/stories/KvVerticalCarousel.stories.js +9 -23
- package/dist/utils/carousels.cjs +19 -11
- package/dist/utils/carousels.js +1 -1
- package/dist/utils/{chunk-P6FXCNYP.js → chunk-WLQNGWMC.js} +19 -11
- package/dist/utils/index.cjs +19 -11
- package/dist/utils/index.js +1 -1
- package/package.json +2 -2
- package/utils/carousels.js +31 -11
- package/vue/KvLendCta.vue +151 -13
- package/vue/KvVerticalCarousel.vue +63 -17
- package/vue/stories/KvCarousel.stories.js +8 -23
- package/vue/stories/KvLendCta.stories.js +166 -0
- package/vue/stories/KvVerticalCarousel.stories.js +9 -23
|
@@ -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
|
-
|
|
191
|
-
|
|
192
|
-
};
|
|
193
|
-
},
|
|
190
|
+
data: () => ({
|
|
191
|
+
isAutoplaying: false,
|
|
192
|
+
}),
|
|
194
193
|
mounted() {
|
|
195
|
-
this.$
|
|
196
|
-
this.
|
|
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: {{
|
|
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
|
package/dist/utils/carousels.cjs
CHANGED
|
@@ -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.
|
|
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,
|
package/dist/utils/carousels.js
CHANGED
|
@@ -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.
|
|
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,
|
package/dist/utils/index.cjs
CHANGED
|
@@ -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.
|
|
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,
|
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.7.0",
|
|
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": "
|
|
101
|
+
"gitHead": "714dd64c1fdea169392d23f77b934c131230df99"
|
|
102
102
|
}
|
package/utils/carousels.js
CHANGED
|
@@ -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
|
@@ -54,10 +54,57 @@
|
|
|
54
54
|
>
|
|
55
55
|
<fieldset
|
|
56
56
|
class="tw-w-full tw-flex"
|
|
57
|
+
:class="{'tw-flex-col tw-gap-1 md:tw-flex-row md:tw-justify-between': showPresetAmounts}"
|
|
57
58
|
:disabled="isAdding"
|
|
58
59
|
data-testid="bp-lend-cta-select-and-button"
|
|
59
60
|
>
|
|
60
|
-
<div
|
|
61
|
+
<div
|
|
62
|
+
v-if="showPresetAmounts"
|
|
63
|
+
class="tw-flex tw-gap-1"
|
|
64
|
+
:class="{'tw-flex-wrap md:tw-flex-nowrap': enableHugeAmount}"
|
|
65
|
+
>
|
|
66
|
+
<template v-if="!isLendAmountButton">
|
|
67
|
+
<kv-ui-button
|
|
68
|
+
v-for="option in presetButtonsPrices"
|
|
69
|
+
:key="option"
|
|
70
|
+
variant="secondary"
|
|
71
|
+
class="tw-inline-flex tw-flex-1 preset-option tw-w-8"
|
|
72
|
+
:class="{'selected-option': selectedOption == option }"
|
|
73
|
+
data-testid="bp-lend-cta-lend-button"
|
|
74
|
+
type="submit"
|
|
75
|
+
@click="clickPresetButton(option)"
|
|
76
|
+
>
|
|
77
|
+
${{ option }}
|
|
78
|
+
</kv-ui-button>
|
|
79
|
+
</template>
|
|
80
|
+
<kv-ui-select
|
|
81
|
+
v-if="showFilteredDropdown"
|
|
82
|
+
:id="`LoanAmountDropdown_${loanId}`"
|
|
83
|
+
v-model="selectedDropdownOption"
|
|
84
|
+
class="tw-min-w-12 tw-rounded filtered-dropdown"
|
|
85
|
+
:class="{
|
|
86
|
+
'unselected-dropdown': !selectedDropdown,
|
|
87
|
+
'selected-dropdown': selectedDropdown,
|
|
88
|
+
'tw-w-full': enableHugeAmount
|
|
89
|
+
}"
|
|
90
|
+
aria-label="Lend amount"
|
|
91
|
+
@update:modelValue="trackLendAmountSelection"
|
|
92
|
+
@click.native.stop="clickDropdown"
|
|
93
|
+
>
|
|
94
|
+
<option
|
|
95
|
+
v-for="priceOption in presetDropdownPrices"
|
|
96
|
+
:key="priceOption"
|
|
97
|
+
:value="priceOption"
|
|
98
|
+
>
|
|
99
|
+
{{ priceOption !== 'Other' ? `$${priceOption}` : priceOption }}
|
|
100
|
+
</option>
|
|
101
|
+
</kv-ui-select>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<div
|
|
105
|
+
v-else-if="!showPresetAmounts"
|
|
106
|
+
class="amountDropdownWrapper"
|
|
107
|
+
>
|
|
61
108
|
<kv-ui-select
|
|
62
109
|
v-if="hideShowLendDropdown && !isLessThan25"
|
|
63
110
|
:id="`LoanAmountDropdown_${loanId}`"
|
|
@@ -79,11 +126,17 @@
|
|
|
79
126
|
</div>
|
|
80
127
|
|
|
81
128
|
<!-- Lend button -->
|
|
82
|
-
<div
|
|
129
|
+
<div
|
|
130
|
+
:class="{
|
|
131
|
+
'lendButtonWrapper': hideShowLendDropdown && !showPresetAmounts,
|
|
132
|
+
'tw-hidden': isAdding && showPresetAmounts
|
|
133
|
+
}"
|
|
134
|
+
>
|
|
83
135
|
<kv-ui-button
|
|
84
136
|
v-if="lendButtonVisibility && !isLessThan25"
|
|
85
137
|
key="lendButton"
|
|
86
138
|
class="tw-inline-flex tw-flex-1"
|
|
139
|
+
:class="{'tw-w-full': showPresetAmounts }"
|
|
87
140
|
data-testid="bp-lend-cta-lend-button"
|
|
88
141
|
type="submit"
|
|
89
142
|
>
|
|
@@ -95,6 +148,7 @@
|
|
|
95
148
|
v-else-if="showLendAgain"
|
|
96
149
|
key="lendAgainButton"
|
|
97
150
|
class="lend-again"
|
|
151
|
+
:class="{'tw-w-full': showPresetAmounts }"
|
|
98
152
|
data-testid="bp-lend-cta-lend-again-button"
|
|
99
153
|
type="submit"
|
|
100
154
|
>
|
|
@@ -218,10 +272,19 @@ export default {
|
|
|
218
272
|
type: Function,
|
|
219
273
|
default: undefined,
|
|
220
274
|
},
|
|
275
|
+
showPresetAmounts: {
|
|
276
|
+
type: Boolean,
|
|
277
|
+
default: false,
|
|
278
|
+
},
|
|
279
|
+
kvTrackCategory: {
|
|
280
|
+
type: String,
|
|
281
|
+
default: 'Lending',
|
|
282
|
+
},
|
|
221
283
|
},
|
|
222
284
|
data() {
|
|
223
285
|
return {
|
|
224
286
|
mdiChevronRight,
|
|
287
|
+
defaultAmountOptions: [25, 50, 75],
|
|
225
288
|
selectedOption: getLendCtaSelectedOption(
|
|
226
289
|
this.getCookie,
|
|
227
290
|
this.setCookie,
|
|
@@ -231,6 +294,7 @@ export default {
|
|
|
231
294
|
this.userBalance,
|
|
232
295
|
this.fiveDollarsSelected,
|
|
233
296
|
),
|
|
297
|
+
selectedDropdownOption: 'Other',
|
|
234
298
|
};
|
|
235
299
|
},
|
|
236
300
|
computed: {
|
|
@@ -271,21 +335,49 @@ export default {
|
|
|
271
335
|
this.isVisitor,
|
|
272
336
|
);
|
|
273
337
|
},
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
338
|
+
presetButtonsPrices() {
|
|
339
|
+
const prices = this.prices.slice(0, 3);
|
|
340
|
+
|
|
341
|
+
// Show only one extra option as button
|
|
342
|
+
if (this.prices.length === 4) {
|
|
343
|
+
prices.push(this.prices[3]);
|
|
277
344
|
}
|
|
345
|
+
|
|
346
|
+
return prices;
|
|
347
|
+
},
|
|
348
|
+
presetDropdownPrices() {
|
|
349
|
+
// Hide dropdown if there is only one option
|
|
350
|
+
if (this.prices.length === 4) {
|
|
351
|
+
return [];
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const extraDropdownPrices = this.prices.slice(this.defaultAmountOptions.length);
|
|
355
|
+
extraDropdownPrices.unshift('Other');
|
|
356
|
+
|
|
357
|
+
return extraDropdownPrices;
|
|
358
|
+
},
|
|
359
|
+
loanName() {
|
|
360
|
+
return this.loan?.name ?? '';
|
|
361
|
+
},
|
|
362
|
+
presetAmountCtaButtonText() {
|
|
363
|
+
return this.loan?.borrowerCount > 1 ? 'Support' : `Support ${this.loanName}`;
|
|
364
|
+
},
|
|
365
|
+
defaultCtaButtonText() {
|
|
366
|
+
if (this.showPresetAmounts) return this.presetAmountCtaButtonText;
|
|
367
|
+
return this.primaryButtonText || 'Lend';
|
|
368
|
+
},
|
|
369
|
+
ctaButtonText() {
|
|
278
370
|
switch (this.state) {
|
|
279
371
|
case 'loading':
|
|
280
372
|
return 'Loading...';
|
|
281
373
|
case 'refunded':
|
|
282
374
|
case 'expired':
|
|
283
375
|
default:
|
|
284
|
-
return this.
|
|
376
|
+
return this.defaultCtaButtonText;
|
|
285
377
|
}
|
|
286
378
|
},
|
|
287
379
|
loanInBasketButtonText() {
|
|
288
|
-
return this.secondaryButtonText;
|
|
380
|
+
return this.showPresetAmounts ? 'Continue to basket' : this.secondaryButtonText;
|
|
289
381
|
},
|
|
290
382
|
useFormSubmit() {
|
|
291
383
|
if (this.hideShowLendDropdown
|
|
@@ -347,18 +439,27 @@ export default {
|
|
|
347
439
|
|| this.isAmountBetween25And500(this.unreservedAmount));
|
|
348
440
|
},
|
|
349
441
|
isLendAmountButton() {
|
|
350
|
-
return (this.lendButtonVisibility || this.state === 'lent-to')
|
|
351
|
-
&& this.isAmountLessThan25(this.unreservedAmount);
|
|
442
|
+
return ((this.lendButtonVisibility || this.state === 'lent-to')
|
|
443
|
+
&& this.isAmountLessThan25(this.unreservedAmount));
|
|
352
444
|
},
|
|
353
445
|
isFunded() {
|
|
354
446
|
return this.state === 'funded' || this.state === 'fully-reserved';
|
|
355
447
|
},
|
|
356
448
|
amountToLend() {
|
|
449
|
+
if (this.selectedDropdown) {
|
|
450
|
+
return this.selectedDropdownOption;
|
|
451
|
+
}
|
|
357
452
|
return this.isLessThan25 ? this.unreservedAmount : this.selectedOption;
|
|
358
453
|
},
|
|
359
454
|
showLendAgain() {
|
|
360
455
|
return this.isLentTo && !this.isLessThan25;
|
|
361
456
|
},
|
|
457
|
+
selectedDropdown() {
|
|
458
|
+
return this.selectedDropdownOption !== 'Other';
|
|
459
|
+
},
|
|
460
|
+
showFilteredDropdown() {
|
|
461
|
+
return this.presetDropdownPrices.length > 1;
|
|
462
|
+
},
|
|
362
463
|
},
|
|
363
464
|
watch: {
|
|
364
465
|
unreservedAmount(newValue, previousValue) {
|
|
@@ -371,14 +472,19 @@ export default {
|
|
|
371
472
|
newValue,
|
|
372
473
|
this.userBalance,
|
|
373
474
|
this.fiveDollarsSelected,
|
|
475
|
+
this.showPresetAmounts,
|
|
374
476
|
);
|
|
375
477
|
}
|
|
478
|
+
|
|
479
|
+
if (this.showPresetAmounts) {
|
|
480
|
+
this.selectedOption = 'Other';
|
|
481
|
+
}
|
|
376
482
|
},
|
|
377
483
|
},
|
|
378
484
|
methods: {
|
|
379
485
|
async addToBasket() {
|
|
380
486
|
this.kvTrackFunction(
|
|
381
|
-
|
|
487
|
+
this.kvTrackCategory,
|
|
382
488
|
'Add to basket',
|
|
383
489
|
this.showLendAgain ? 'Lend again' : 'lend-button-click',
|
|
384
490
|
this.loanId,
|
|
@@ -396,8 +502,12 @@ export default {
|
|
|
396
502
|
return unreservedAmount < 500 && unreservedAmount >= 25;
|
|
397
503
|
},
|
|
398
504
|
trackLendAmountSelection(selectedDollarAmount) {
|
|
505
|
+
if (this.showPresetAmounts) {
|
|
506
|
+
this.selectedOption = null;
|
|
507
|
+
}
|
|
508
|
+
|
|
399
509
|
this.kvTrackFunction(
|
|
400
|
-
|
|
510
|
+
this.kvTrackCategory,
|
|
401
511
|
'Modify lend amount',
|
|
402
512
|
selectedDollarAmount,
|
|
403
513
|
this.loanId,
|
|
@@ -405,7 +515,9 @@ export default {
|
|
|
405
515
|
);
|
|
406
516
|
},
|
|
407
517
|
clickDropdown() {
|
|
408
|
-
this.kvTrackFunction(
|
|
518
|
+
this.kvTrackFunction(
|
|
519
|
+
this.kvTrackCategory, 'click-Modify loan amount', 'open dialog', this.loanId, this.loanId,
|
|
520
|
+
);
|
|
409
521
|
},
|
|
410
522
|
clickSecondaryButton(event) {
|
|
411
523
|
if (this.secondaryButtonHandler) {
|
|
@@ -418,9 +530,15 @@ export default {
|
|
|
418
530
|
this.handleCheckout();
|
|
419
531
|
}
|
|
420
532
|
},
|
|
533
|
+
clickPresetButton(selectedDollarAmount) {
|
|
534
|
+
this.kvTrackFunction(
|
|
535
|
+
this.kvTrackCategory, 'Modify lend amount', selectedDollarAmount, this.loanId, this.loanId,
|
|
536
|
+
);
|
|
537
|
+
this.selectedOption = selectedDollarAmount;
|
|
538
|
+
},
|
|
421
539
|
handleCheckout() {
|
|
422
540
|
this.kvTrackFunction(
|
|
423
|
-
|
|
541
|
+
this.kvTrackCategory,
|
|
424
542
|
'click-Continue-to-checkout',
|
|
425
543
|
'Continue to checkout',
|
|
426
544
|
this.loanId,
|
|
@@ -448,4 +566,24 @@ export default {
|
|
|
448
566
|
.lendButtonWrapper >>> span:first-child {
|
|
449
567
|
border-radius: 0 14px 14px 0;
|
|
450
568
|
}
|
|
569
|
+
|
|
570
|
+
.filtered-dropdown >>> select {
|
|
571
|
+
@apply tw-rounded tw-border-2 tw-font-medium tw-cursor-pointer;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.unselected-dropdown >>> select {
|
|
575
|
+
@apply tw-border-gray-400;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.selected-dropdown >>> select {
|
|
579
|
+
@apply tw-border-eco-green-4;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.preset-option >>> span.tw-w-full:first-child {
|
|
583
|
+
@apply tw-border-2 tw-border-gray-400;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.selected-option >>> span.tw-w-full:first-child {
|
|
587
|
+
@apply tw-border-eco-green-4;
|
|
588
|
+
}
|
|
451
589
|
</style>
|