@kiva/kv-components 3.43.0 → 3.44.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 +22 -0
- package/package.json +2 -2
- package/vue/KvClassicLoanCard.vue +17 -2
- package/vue/KvLoanTag.vue +6 -0
- package/vue/stories/KvClassicLoanCard.stories.js +23 -0
- package/vue/stories/KvLoanTag.stories.js +12 -0
- package/tests/unit/specs/components/KvEditButton.spec.js +0 -71
- package/vue/KvEditButton.vue +0 -105
- package/vue/stories/KvEditButton.stories.js +0 -63
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
|
+
## [3.44.1](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.44.0...@kiva/kv-components@3.44.1) (2023-09-20)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* backpedal kvedit button and use existing components instead ([e751910](https://github.com/kiva/kv-ui-elements/commit/e751910f808f7d4b5861995053015bd20b9c6d5e))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [3.44.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.43.0...@kiva/kv-components@3.44.0) (2023-09-19)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* increase impact visibility for lse loans ([#298](https://github.com/kiva/kv-ui-elements/issues/298)) ([f9dc1e4](https://github.com/kiva/kv-ui-elements/commit/f9dc1e47f25a68f8e3bd745abfc2338b376bd848))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
# [3.43.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.42.0...@kiva/kv-components@3.43.0) (2023-09-15)
|
|
7
29
|
|
|
8
30
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kiva/kv-components",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.44.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"optional": true
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "a6e828c2b6a814b53ec26ada42ec6b97e6932660"
|
|
79
79
|
}
|
|
@@ -231,6 +231,8 @@ import KvLoanTag from './KvLoanTag.vue';
|
|
|
231
231
|
import KvMaterialIcon from './KvMaterialIcon.vue';
|
|
232
232
|
import KvLoadingPlaceholder from './KvLoadingPlaceholder.vue';
|
|
233
233
|
|
|
234
|
+
const LSE_LOAN_KEY = 'N/A';
|
|
235
|
+
|
|
234
236
|
export default {
|
|
235
237
|
name: 'KvClassicLoanCard',
|
|
236
238
|
components: {
|
|
@@ -438,14 +440,25 @@ export default {
|
|
|
438
440
|
singleParents: !!tags.filter((t) => t.toUpperCase() === 'SINGLE PARENT').length,
|
|
439
441
|
};
|
|
440
442
|
|
|
443
|
+
const isLseLoan = this.loan?.partnerName?.toUpperCase().includes(LSE_LOAN_KEY);
|
|
444
|
+
|
|
441
445
|
// P1 Category
|
|
442
446
|
// Exp limited to: Eco-friendly, Refugees and IDPs, Single Parents
|
|
447
|
+
// Tag as first option for LSE loans
|
|
448
|
+
if (isLseLoan && tags.length) {
|
|
449
|
+
const position = Math.floor(Math.random() * tags.length);
|
|
450
|
+
const tag = tags[position];
|
|
451
|
+
callouts.push(tag);
|
|
452
|
+
}
|
|
453
|
+
|
|
443
454
|
if (!this.categoryPageName) {
|
|
444
|
-
if (categories.ecoFriendly
|
|
455
|
+
if (categories.ecoFriendly
|
|
456
|
+
&& !callouts.filter((c) => c.toUpperCase() === categories.ecoFriendly.toUpperCase()).length) {
|
|
445
457
|
callouts.push('Eco-friendly');
|
|
446
458
|
} else if (categories.refugeesIdps) {
|
|
447
459
|
callouts.push('Refugees and IDPs');
|
|
448
|
-
} else if (categories.singleParents
|
|
460
|
+
} else if (categories.singleParents
|
|
461
|
+
&& !callouts.filter((c) => c.toUpperCase() === categories.singleParents.toUpperCase()).length) {
|
|
449
462
|
callouts.push('Single Parent');
|
|
450
463
|
}
|
|
451
464
|
}
|
|
@@ -482,6 +495,8 @@ export default {
|
|
|
482
495
|
}
|
|
483
496
|
}
|
|
484
497
|
|
|
498
|
+
// Only show one callout for LSE loans
|
|
499
|
+
if (isLseLoan && callouts.length > 1) return [callouts.shift()];
|
|
485
500
|
return callouts;
|
|
486
501
|
},
|
|
487
502
|
},
|
package/vue/KvLoanTag.vue
CHANGED
|
@@ -17,6 +17,8 @@ import { differenceInDays, parseISO } from 'date-fns';
|
|
|
17
17
|
import numeral from 'numeral';
|
|
18
18
|
import KvCountdownTimer from './KvCountdownTimer.vue';
|
|
19
19
|
|
|
20
|
+
const LSE_LOAN_KEY = 'N/A';
|
|
21
|
+
|
|
20
22
|
export default {
|
|
21
23
|
name: 'KvLoanTag',
|
|
22
24
|
components: {
|
|
@@ -55,6 +57,10 @@ export default {
|
|
|
55
57
|
return null;
|
|
56
58
|
},
|
|
57
59
|
tagText() {
|
|
60
|
+
const partnerName = this.loan?.partnerName ?? '';
|
|
61
|
+
if (partnerName.toUpperCase().includes(LSE_LOAN_KEY)) {
|
|
62
|
+
return 'High community impact';
|
|
63
|
+
}
|
|
58
64
|
switch (this.variation) {
|
|
59
65
|
case 'almost-funded': return 'Almost funded';
|
|
60
66
|
case 'matched-loan': return `${this.matchRatio + 1}x matching by ${this.loan?.matchingText}`;
|
|
@@ -182,6 +182,29 @@ export const LongCallouts = story({
|
|
|
182
182
|
photoPath,
|
|
183
183
|
});
|
|
184
184
|
|
|
185
|
+
export const LseLoan = story({
|
|
186
|
+
loanId: loan.id,
|
|
187
|
+
loan: {
|
|
188
|
+
...loan,
|
|
189
|
+
loanFundraisingInfo: {
|
|
190
|
+
fundedAmount: '950.00',
|
|
191
|
+
isExpiringSoon: false,
|
|
192
|
+
reservedAmount: '0.00',
|
|
193
|
+
},
|
|
194
|
+
partnerName: 'N/A, direct to Novulis',
|
|
195
|
+
tags: [
|
|
196
|
+
'user_favorite',
|
|
197
|
+
'#Woman-Owned Business',
|
|
198
|
+
'#Animals',
|
|
199
|
+
'#Repeat Borrower',
|
|
200
|
+
'#Supporting Family',
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
kvTrackFunction,
|
|
204
|
+
photoPath,
|
|
205
|
+
showTags: true,
|
|
206
|
+
});
|
|
207
|
+
|
|
185
208
|
export const Bookmarked = story({
|
|
186
209
|
loanId: loan.id,
|
|
187
210
|
loan,
|
|
@@ -53,3 +53,15 @@ export const Matched = story({
|
|
|
53
53
|
},
|
|
54
54
|
kvTrackFunction,
|
|
55
55
|
});
|
|
56
|
+
|
|
57
|
+
export const LseLoan = story({
|
|
58
|
+
loan: {
|
|
59
|
+
matchingText: 'Ebay',
|
|
60
|
+
matchRatio: 1,
|
|
61
|
+
plannedExpirationDate: nextWeek.toISOString(),
|
|
62
|
+
loanAmount: 199,
|
|
63
|
+
loanFundraisingInfo: { fundedAmount: 0, reservedAmount: 0 },
|
|
64
|
+
partnerName: 'N/A, direct to Novulis',
|
|
65
|
+
},
|
|
66
|
+
kvTrackFunction,
|
|
67
|
+
});
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { render, fireEvent } from '@testing-library/vue';
|
|
2
|
-
import { axe } from 'jest-axe';
|
|
3
|
-
import { nextTick } from 'vue';
|
|
4
|
-
import addVueRouter from '../../utils/addVueRouter';
|
|
5
|
-
import KvEditButton from '../../../../vue/KvEditButton.vue';
|
|
6
|
-
|
|
7
|
-
describe('KvEditButton', () => {
|
|
8
|
-
const renderComponent = (options) => render(KvEditButton, addVueRouter(options));
|
|
9
|
-
|
|
10
|
-
it('renders the edit button', () => {
|
|
11
|
-
const { getByRole } = renderComponent();
|
|
12
|
-
getByRole('button', { name: /edit/i });
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('shows the lightbox when the edit button is clicked', async () => {
|
|
16
|
-
const { getByRole } = renderComponent();
|
|
17
|
-
const button = getByRole('button', { name: /edit/i });
|
|
18
|
-
await fireEvent.click(button);
|
|
19
|
-
expect(getByRole('dialog')).toBeVisible();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('closes the lightbox when the close event is emitted', async () => {
|
|
23
|
-
const { getByRole, queryByRole } = renderComponent();
|
|
24
|
-
const button = getByRole('button', { name: /edit/i });
|
|
25
|
-
await fireEvent.click(button);
|
|
26
|
-
await fireEvent.keyUp(document, { key: 'Escape', code: 'Escape' });
|
|
27
|
-
await nextTick();
|
|
28
|
-
expect(queryByRole('dialog')).not.toBeInTheDocument();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('renders a custom title for the lightbox if provided', () => {
|
|
32
|
-
const { getByText } = renderComponent({ props: { title: 'Custom Title' } });
|
|
33
|
-
getByText('Custom Title');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('has no automated accessibility violations', async () => {
|
|
37
|
-
const { container } = renderComponent();
|
|
38
|
-
const results = await axe(container);
|
|
39
|
-
expect(results).toHaveNoViolations();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('renders content in the default slot of the lightbox', async () => {
|
|
43
|
-
const customContent = 'Custom Content for Body';
|
|
44
|
-
const { getByText, getByRole } = renderComponent({
|
|
45
|
-
slots: { default: customContent },
|
|
46
|
-
});
|
|
47
|
-
const button = getByRole('button', { name: /edit/i });
|
|
48
|
-
await fireEvent.click(button);
|
|
49
|
-
expect(getByText(customContent)).toBeVisible();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('renders content in the header slot of the lightbox', async () => {
|
|
53
|
-
const customHeader = 'Custom Header Content';
|
|
54
|
-
const { getByText, getByRole } = renderComponent({
|
|
55
|
-
slots: { header: customHeader },
|
|
56
|
-
});
|
|
57
|
-
const button = getByRole('button', { name: /edit/i });
|
|
58
|
-
await fireEvent.click(button);
|
|
59
|
-
expect(getByText(customHeader)).toBeVisible();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('renders content in the controls slot of the lightbox', async () => {
|
|
63
|
-
const customControls = 'Custom Controls Content';
|
|
64
|
-
const { getByText, getByRole } = renderComponent({
|
|
65
|
-
slots: { controls: customControls },
|
|
66
|
-
});
|
|
67
|
-
const button = getByRole('button', { name: /edit/i });
|
|
68
|
-
await fireEvent.click(button);
|
|
69
|
-
expect(getByText(customControls)).toBeVisible();
|
|
70
|
-
});
|
|
71
|
-
});
|
package/vue/KvEditButton.vue
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<!-- Edit Button -->
|
|
4
|
-
<KvButton
|
|
5
|
-
variant="secondary"
|
|
6
|
-
aria-label="Edit"
|
|
7
|
-
class="tw-w-7 tw-h-10"
|
|
8
|
-
@click="showLightbox"
|
|
9
|
-
>
|
|
10
|
-
<KvMaterialIcon
|
|
11
|
-
class="tw-w-3 tw-h-3"
|
|
12
|
-
:icon="mdiPencil"
|
|
13
|
-
/>
|
|
14
|
-
</KvButton>
|
|
15
|
-
|
|
16
|
-
<!-- Lightbox -->
|
|
17
|
-
<KvLightbox
|
|
18
|
-
:visible="isVisible"
|
|
19
|
-
:title="title"
|
|
20
|
-
:prevent-close="preventClose"
|
|
21
|
-
:variant="variant"
|
|
22
|
-
@lightbox-closed="hideLightbox"
|
|
23
|
-
>
|
|
24
|
-
<template #header>
|
|
25
|
-
<slot name="header"></slot>
|
|
26
|
-
</template>
|
|
27
|
-
|
|
28
|
-
<!-- default slot (body) -->
|
|
29
|
-
<slot></slot>
|
|
30
|
-
|
|
31
|
-
<!-- controls slot -->
|
|
32
|
-
<template #controls>
|
|
33
|
-
<slot
|
|
34
|
-
name="controls"
|
|
35
|
-
:hideLightbox="hideLightbox"
|
|
36
|
-
></slot>
|
|
37
|
-
</template>
|
|
38
|
-
</KvLightbox>
|
|
39
|
-
</div>
|
|
40
|
-
</template>
|
|
41
|
-
|
|
42
|
-
<script>
|
|
43
|
-
import { ref } from 'vue-demi';
|
|
44
|
-
import { mdiPencil } from '@mdi/js';
|
|
45
|
-
import KvButton from './KvButton.vue';
|
|
46
|
-
import KvMaterialIcon from './KvMaterialIcon.vue';
|
|
47
|
-
import KvLightbox from './KvLightbox.vue';
|
|
48
|
-
|
|
49
|
-
export default {
|
|
50
|
-
components: {
|
|
51
|
-
KvButton,
|
|
52
|
-
KvMaterialIcon,
|
|
53
|
-
KvLightbox,
|
|
54
|
-
},
|
|
55
|
-
props: {
|
|
56
|
-
variant: {
|
|
57
|
-
type: String,
|
|
58
|
-
default: 'lightbox',
|
|
59
|
-
validator(value) {
|
|
60
|
-
return ['lightbox', 'alert'].includes(value);
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
/**
|
|
64
|
-
* The title of the dialog which describes the dialog to screenreaders, and if no
|
|
65
|
-
* content is in the `header` slot, will be displayed at the top of the lightbox.
|
|
66
|
-
* */
|
|
67
|
-
title: {
|
|
68
|
-
type: String,
|
|
69
|
-
default: '',
|
|
70
|
-
},
|
|
71
|
-
/**
|
|
72
|
-
* The dialog has no close X button, clicking the screen does not close,
|
|
73
|
-
* pressing ESC does not close.
|
|
74
|
-
* */
|
|
75
|
-
preventClose: {
|
|
76
|
-
type: Boolean,
|
|
77
|
-
default: false,
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
emits: [
|
|
81
|
-
'lightbox-opened',
|
|
82
|
-
'lightbox-closed',
|
|
83
|
-
],
|
|
84
|
-
setup(_, { emit }) {
|
|
85
|
-
const isVisible = ref(false);
|
|
86
|
-
|
|
87
|
-
const showLightbox = () => {
|
|
88
|
-
isVisible.value = true;
|
|
89
|
-
emit('lightbox-opened');
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const hideLightbox = () => {
|
|
93
|
-
isVisible.value = false;
|
|
94
|
-
emit('lightbox-closed');
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
mdiPencil,
|
|
99
|
-
isVisible,
|
|
100
|
-
showLightbox,
|
|
101
|
-
hideLightbox,
|
|
102
|
-
};
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
</script>
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import KvEditButton from '../KvEditButton.vue';
|
|
2
|
-
import KvButton from '../KvButton.vue';
|
|
3
|
-
|
|
4
|
-
export default {
|
|
5
|
-
title: 'KvEditButton',
|
|
6
|
-
component: KvEditButton,
|
|
7
|
-
argTypes: {
|
|
8
|
-
visible: {
|
|
9
|
-
control: 'boolean',
|
|
10
|
-
defaultValue: false,
|
|
11
|
-
},
|
|
12
|
-
title: {
|
|
13
|
-
control: 'text',
|
|
14
|
-
defaultValue: 'Edit',
|
|
15
|
-
},
|
|
16
|
-
variant: {
|
|
17
|
-
control: 'select',
|
|
18
|
-
options: ['lightbox', 'alert'],
|
|
19
|
-
defaultValue: 'lightbox',
|
|
20
|
-
},
|
|
21
|
-
preventClose: {
|
|
22
|
-
control: 'boolean',
|
|
23
|
-
defaultValue: false,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
args: {
|
|
27
|
-
visible: false,
|
|
28
|
-
title: '',
|
|
29
|
-
variant: 'lightbox',
|
|
30
|
-
preventClose: false,
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const DefaultTemplate = (args, { argTypes }) => ({
|
|
35
|
-
props: Object.keys(argTypes),
|
|
36
|
-
components: { KvEditButton, KvButton },
|
|
37
|
-
template: `
|
|
38
|
-
<div>
|
|
39
|
-
<kv-edit-button v-bind="$props">
|
|
40
|
-
<template>This is the content that will appear inside the lightbox when the edit button is clicked.</template>
|
|
41
|
-
<template #header>
|
|
42
|
-
<h3>
|
|
43
|
-
Custom Header
|
|
44
|
-
</h3>
|
|
45
|
-
</template>
|
|
46
|
-
<template #controls="{ hideLightbox }">
|
|
47
|
-
<kv-button variant="ghost" @click="hideLightbox" ref="dontDoItRef">Cancel</kv-button>
|
|
48
|
-
<kv-button variant="danger" @click="hideLightbox" ref="doItRef">Delete</kv-button>
|
|
49
|
-
</template>
|
|
50
|
-
</kv-edit-button>
|
|
51
|
-
</div>
|
|
52
|
-
`,
|
|
53
|
-
data() {
|
|
54
|
-
return {
|
|
55
|
-
isLightboxVisible: args.visible,
|
|
56
|
-
};
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
export const EditButtonWithLightbox = DefaultTemplate.bind({});
|
|
61
|
-
EditButtonWithLightbox.args = {
|
|
62
|
-
title: 'Edit Item Details',
|
|
63
|
-
};
|