@kiva/kv-components 3.51.0 → 3.52.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 +30 -0
- package/package.json +2 -2
- package/tests/unit/specs/components/KvCommentsAdd.spec.js +74 -0
- package/tests/unit/specs/components/KvCommentsContainer.spec.js +16 -6
- package/vue/KvCommentsAdd.vue +120 -0
- package/vue/KvCommentsContainer.vue +29 -12
- package/vue/stories/KvCommentsAdd.stories.js +32 -0
- package/vue/stories/KvCommentsContainer.stories.js +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,36 @@
|
|
|
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.52.1](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.52.0...@kiva/kv-components@3.52.1) (2024-02-01)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* add back in comments container ([36a8a97](https://github.com/kiva/kv-ui-elements/commit/36a8a979aac47c425e32d87cd13160ad68b913cf))
|
|
12
|
+
* another tweak to how events emitted ([029367a](https://github.com/kiva/kv-ui-elements/commit/029367aeb1f38151a7d36e0a2246b82b14489cb3))
|
|
13
|
+
* minor test fix ([c95c486](https://github.com/kiva/kv-ui-elements/commit/c95c4866d05b2e711e8895868d72ddc6bb5b7a43))
|
|
14
|
+
* remove unneeded comment container ([71365b0](https://github.com/kiva/kv-ui-elements/commit/71365b0f6628d1d280f9fbd2b0adbad8688fd57c))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# [3.52.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.51.0...@kiva/kv-components@3.52.0) (2024-01-31)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* added missing suppression classes ([5d04867](https://github.com/kiva/kv-ui-elements/commit/5d048672f078d2d229372e37b896c9be025457d9))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
* add comments add component ([1bf5fc3](https://github.com/kiva/kv-ui-elements/commit/1bf5fc388fee61a63f49775a15b50728c140a569))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
6
36
|
# [3.51.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.50.0...@kiva/kv-components@3.51.0) (2024-01-25)
|
|
7
37
|
|
|
8
38
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kiva/kv-components",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.52.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": "a1d537c8b354bbba06204c6500440183420eebcb"
|
|
79
79
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { render } from '@testing-library/vue';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import CommentsAdd, { ADD_COMMENT_EVENT } from '../../../../vue/KvCommentsAdd.vue';
|
|
4
|
+
|
|
5
|
+
const renderCommentsAdd = (props = {}) => {
|
|
6
|
+
return render(CommentsAdd, { props });
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
describe('KvCommentsAdd', () => {
|
|
10
|
+
it('should render defaults', () => {
|
|
11
|
+
const { getByPlaceholderText, getByRole } = renderCommentsAdd();
|
|
12
|
+
getByPlaceholderText('Add a comment to this loan...');
|
|
13
|
+
getByRole('button', { name: 'Cancel' });
|
|
14
|
+
getByRole('button', { name: 'Comment' });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should render user info', () => {
|
|
18
|
+
const { getByAltText, getByText } = renderCommentsAdd({
|
|
19
|
+
userImageUrl: 'test.com',
|
|
20
|
+
userDisplayName: 'User',
|
|
21
|
+
});
|
|
22
|
+
getByAltText('Lender');
|
|
23
|
+
getByText('User');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should enable comment button when text entered', async () => {
|
|
27
|
+
const { getByPlaceholderText, getByRole } = renderCommentsAdd();
|
|
28
|
+
const textInput = getByPlaceholderText('Add a comment to this loan...');
|
|
29
|
+
const commentButton = getByRole('button', { name: 'Comment' });
|
|
30
|
+
|
|
31
|
+
expect(commentButton.disabled).toBeTruthy();
|
|
32
|
+
|
|
33
|
+
await userEvent.type(textInput, 'test');
|
|
34
|
+
|
|
35
|
+
expect(commentButton.disabled).toBeFalsy();
|
|
36
|
+
|
|
37
|
+
await userEvent.clear(textInput);
|
|
38
|
+
|
|
39
|
+
expect(commentButton.disabled).toBeTruthy();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should clear text when cancel clicked', async () => {
|
|
43
|
+
const { getByPlaceholderText, getByRole } = renderCommentsAdd();
|
|
44
|
+
const textInput = getByPlaceholderText('Add a comment to this loan...');
|
|
45
|
+
const cancelButton = getByRole('button', { name: 'Cancel' });
|
|
46
|
+
|
|
47
|
+
await userEvent.type(textInput, 'test');
|
|
48
|
+
await userEvent.click(cancelButton);
|
|
49
|
+
|
|
50
|
+
expect(textInput.value).toBe('');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should emit value when comment clicked', async () => {
|
|
54
|
+
const { getByPlaceholderText, getByRole, emitted } = renderCommentsAdd();
|
|
55
|
+
const textInput = getByPlaceholderText('Add a comment to this loan...');
|
|
56
|
+
const commentButton = getByRole('button', { name: 'Comment' });
|
|
57
|
+
const TEST_INPUT = 'test test';
|
|
58
|
+
|
|
59
|
+
await userEvent.type(textInput, TEST_INPUT);
|
|
60
|
+
|
|
61
|
+
await userEvent.click(commentButton);
|
|
62
|
+
|
|
63
|
+
expect(emitted()[ADD_COMMENT_EVENT]).toEqual([[TEST_INPUT]]);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should not emit empty value when comment clicked', async () => {
|
|
67
|
+
const { getByRole, emitted } = renderCommentsAdd();
|
|
68
|
+
const commentButton = getByRole('button', { name: 'Comment' });
|
|
69
|
+
|
|
70
|
+
await userEvent.click(commentButton);
|
|
71
|
+
|
|
72
|
+
expect(emitted()[ADD_COMMENT_EVENT]).toBe(undefined);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import { render } from '@testing-library/vue';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
2
3
|
import Container from '../../../../vue/KvCommentsContainer.vue';
|
|
4
|
+
import { ADD_COMMENT_ID, ADD_COMMENT_EVENT } from '../../../../vue/KvCommentsAdd.vue';
|
|
3
5
|
|
|
4
6
|
const renderContainer = (props = {}) => {
|
|
5
7
|
return render(Container, { props });
|
|
6
8
|
};
|
|
7
9
|
|
|
8
10
|
describe('KvCommentsContainer', () => {
|
|
9
|
-
it('should render
|
|
10
|
-
const
|
|
11
|
-
|
|
11
|
+
it('should render comments add component', async () => {
|
|
12
|
+
const { container } = renderContainer();
|
|
13
|
+
expect(container.querySelectorAll(`#${ADD_COMMENT_ID}`).length).toBe(1);
|
|
12
14
|
});
|
|
13
15
|
|
|
14
|
-
it('should
|
|
15
|
-
const
|
|
16
|
-
|
|
16
|
+
it('should emit comment', async () => {
|
|
17
|
+
const { getByPlaceholderText, getByRole, emitted } = renderContainer();
|
|
18
|
+
const textInput = getByPlaceholderText('Add a comment to this loan...');
|
|
19
|
+
const commentButton = getByRole('button', { name: 'Comment' });
|
|
20
|
+
const TEST_INPUT = 'test test';
|
|
21
|
+
|
|
22
|
+
await userEvent.type(textInput, TEST_INPUT);
|
|
23
|
+
|
|
24
|
+
await userEvent.click(commentButton);
|
|
25
|
+
|
|
26
|
+
expect(emitted()[ADD_COMMENT_EVENT]).toEqual([[TEST_INPUT]]);
|
|
17
27
|
});
|
|
18
28
|
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="tw-flex tw-flex-col">
|
|
3
|
+
<div class="tw-flex tw-flex-col md:tw-flex-row md:tw-items-center tw-gap-0.5 md:tw-gap-1">
|
|
4
|
+
<div class="tw-flex tw-items-center tw-gap-1">
|
|
5
|
+
<img
|
|
6
|
+
v-if="userImageUrl"
|
|
7
|
+
:src="userImageUrl"
|
|
8
|
+
alt="Lender"
|
|
9
|
+
class="
|
|
10
|
+
data-hj-suppress
|
|
11
|
+
tw-inline-block
|
|
12
|
+
tw-w-3.5
|
|
13
|
+
tw-h-3.5
|
|
14
|
+
tw-rounded-full
|
|
15
|
+
tw-overflow-hidden
|
|
16
|
+
tw-object-fill
|
|
17
|
+
"
|
|
18
|
+
>
|
|
19
|
+
<div class="data-hj-suppress tw-font-medium">
|
|
20
|
+
{{ userDisplayName }}
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
<kv-text-input
|
|
24
|
+
:id="ADD_COMMENT_ID"
|
|
25
|
+
v-model="addCommentValue"
|
|
26
|
+
placeholder="Add a comment to this loan..."
|
|
27
|
+
class="data-hj-suppress tw-grow"
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="tw-flex tw-py-0.5 tw-gap-0.5">
|
|
31
|
+
<kv-button
|
|
32
|
+
variant="ghost"
|
|
33
|
+
class="tw-ml-auto"
|
|
34
|
+
@click="cancel"
|
|
35
|
+
>
|
|
36
|
+
Cancel
|
|
37
|
+
</kv-button>
|
|
38
|
+
<kv-button
|
|
39
|
+
variant="ghost"
|
|
40
|
+
:state="commentButtonState"
|
|
41
|
+
@click="comment"
|
|
42
|
+
>
|
|
43
|
+
Comment
|
|
44
|
+
</kv-button>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
|
+
<script>
|
|
50
|
+
import { computed, ref } from 'vue-demi';
|
|
51
|
+
import KvButton from './KvButton.vue';
|
|
52
|
+
import KvTextInput from './KvTextInput.vue';
|
|
53
|
+
|
|
54
|
+
export const ADD_COMMENT_ID = 'add-comment-value';
|
|
55
|
+
export const ADD_COMMENT_EVENT = 'add-comment';
|
|
56
|
+
|
|
57
|
+
export default {
|
|
58
|
+
components: {
|
|
59
|
+
KvButton,
|
|
60
|
+
KvTextInput,
|
|
61
|
+
},
|
|
62
|
+
props: {
|
|
63
|
+
/**
|
|
64
|
+
* The full URL for the user image
|
|
65
|
+
*/
|
|
66
|
+
userImageUrl: {
|
|
67
|
+
type: String,
|
|
68
|
+
default: '',
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* The name to display for the user
|
|
72
|
+
*/
|
|
73
|
+
userDisplayName: {
|
|
74
|
+
type: String,
|
|
75
|
+
default: '',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
emits: [ADD_COMMENT_EVENT],
|
|
79
|
+
setup(_props, { emit }) {
|
|
80
|
+
const addCommentValue = ref('');
|
|
81
|
+
|
|
82
|
+
const commentButtonState = computed(() => (addCommentValue.value ? '' : 'disabled'));
|
|
83
|
+
|
|
84
|
+
const cancel = () => {
|
|
85
|
+
addCommentValue.value = '';
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const comment = () => {
|
|
89
|
+
emit(ADD_COMMENT_EVENT, addCommentValue.value);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
ADD_COMMENT_ID,
|
|
94
|
+
addCommentValue,
|
|
95
|
+
commentButtonState,
|
|
96
|
+
cancel,
|
|
97
|
+
comment,
|
|
98
|
+
};
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
</script>
|
|
102
|
+
|
|
103
|
+
<style lang="postcss" scoped>
|
|
104
|
+
>>> input {
|
|
105
|
+
@apply tw-border-t-0 tw-border-r-0 tw-border-l-0 tw-rounded-none tw-p-0 tw-h-4;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
>>> input:focus {
|
|
109
|
+
@apply tw-border-tertiary;
|
|
110
|
+
box-shadow: none;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
>>> button > span {
|
|
114
|
+
@apply tw-min-h-0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
>>> button > span > span {
|
|
118
|
+
@apply tw-py-0 tw-px-0.5;
|
|
119
|
+
}
|
|
120
|
+
</style>
|
|
@@ -1,28 +1,45 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
v-else
|
|
9
|
-
class="tw-text-desert-rose"
|
|
10
|
-
>
|
|
11
|
-
Activity ID missing
|
|
12
|
-
</p>
|
|
3
|
+
<kv-comments-add
|
|
4
|
+
:user-image-url="userImageUrl"
|
|
5
|
+
:user-display-name="userDisplayName"
|
|
6
|
+
@add-comment="comment"
|
|
7
|
+
/>
|
|
13
8
|
</div>
|
|
14
9
|
</template>
|
|
15
10
|
|
|
16
11
|
<script>
|
|
12
|
+
import KvCommentsAdd from './KvCommentsAdd.vue';
|
|
13
|
+
|
|
14
|
+
export const ADD_COMMENT_EVENT = 'add-comment';
|
|
15
|
+
|
|
17
16
|
export default {
|
|
17
|
+
components: {
|
|
18
|
+
KvCommentsAdd,
|
|
19
|
+
},
|
|
18
20
|
props: {
|
|
19
21
|
/**
|
|
20
|
-
* The
|
|
22
|
+
* The full URL for the user image
|
|
21
23
|
*/
|
|
22
|
-
|
|
24
|
+
userImageUrl: {
|
|
23
25
|
type: String,
|
|
24
26
|
default: '',
|
|
25
27
|
},
|
|
28
|
+
/**
|
|
29
|
+
* The name to display for the user
|
|
30
|
+
*/
|
|
31
|
+
userDisplayName: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: '',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
setup(_props, { emit }) {
|
|
37
|
+
const comment = (commentValue) => {
|
|
38
|
+
emit(ADD_COMMENT_EVENT, commentValue);
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
comment,
|
|
42
|
+
};
|
|
26
43
|
},
|
|
27
44
|
};
|
|
28
45
|
</script>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import KvCommentsAdd from '../KvCommentsAdd.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'KvCommentsAdd',
|
|
5
|
+
component: KvCommentsAdd,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const story = (args) => {
|
|
9
|
+
const template = (templateArgs, { argTypes }) => ({
|
|
10
|
+
props: Object.keys(argTypes),
|
|
11
|
+
components: { KvCommentsAdd },
|
|
12
|
+
setup() { return { args: templateArgs }; },
|
|
13
|
+
template: `
|
|
14
|
+
<div style="max-width: 800px;">
|
|
15
|
+
<KvCommentsAdd v-bind="args" />
|
|
16
|
+
</div>
|
|
17
|
+
`,
|
|
18
|
+
});
|
|
19
|
+
template.args = args;
|
|
20
|
+
return template;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const Default = story({});
|
|
24
|
+
|
|
25
|
+
export const UserName = story({
|
|
26
|
+
userDisplayName: 'User',
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export const UserInfo = story({
|
|
30
|
+
userImageUrl: 'https://via.placeholder.com/50x50',
|
|
31
|
+
userDisplayName: 'User',
|
|
32
|
+
});
|
|
@@ -11,7 +11,9 @@ const story = (args) => {
|
|
|
11
11
|
components: { KvCommentsContainer },
|
|
12
12
|
setup() { return { args: templateArgs }; },
|
|
13
13
|
template: `
|
|
14
|
-
<
|
|
14
|
+
<div style="max-width: 800px;">
|
|
15
|
+
<KvCommentsContainer v-bind="args" />
|
|
16
|
+
</div>
|
|
15
17
|
`,
|
|
16
18
|
});
|
|
17
19
|
template.args = args;
|
|
@@ -19,5 +21,3 @@ const story = (args) => {
|
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
export const Default = story({});
|
|
22
|
-
|
|
23
|
-
export const Activity = story({ activityId: 'asd' });
|