@kiva/kv-components 3.53.0 → 3.54.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 +11 -0
- package/package.json +2 -2
- package/tests/fixtures/mockFeedActivityData.js +1 -0
- package/tests/unit/specs/components/KvCommentsHeartButton.spec.js +32 -0
- package/tests/unit/specs/components/KvCommentsList.spec.js +1 -1
- package/vue/KvButton.vue +5 -5
- package/vue/KvCommentsHeartButton.vue +74 -0
- package/vue/KvCommentsList.vue +1 -0
- package/vue/KvCommentsListItem.vue +29 -17
- package/vue/stories/KvCommentsHeartButton.stories.js +25 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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.54.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.53.0...@kiva/kv-components@3.54.0) (2024-02-28)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* kvcommentsheartbutton added for comments stuff ([#346](https://github.com/kiva/kv-ui-elements/issues/346)) ([57303da](https://github.com/kiva/kv-ui-elements/commit/57303daec80222c199556b296d720462265e53ac))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [3.53.0](https://github.com/kiva/kv-ui-elements/compare/@kiva/kv-components@3.52.1...@kiva/kv-components@3.53.0) (2024-02-26)
|
|
7
18
|
|
|
8
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kiva/kv-components",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.54.0",
|
|
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": "b29d4c7e40f229ac09c7f68c377741af7d068158"
|
|
79
79
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { render } from '@testing-library/vue';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import KvCommentsHeartButton from '../../../../vue/KvCommentsHeartButton.vue';
|
|
4
|
+
|
|
5
|
+
const CLICK_EVENT = 'click';
|
|
6
|
+
|
|
7
|
+
describe('KvCommentsListItem', () => {
|
|
8
|
+
it('should render defaults', () => {
|
|
9
|
+
const { getByRole } = render(KvCommentsHeartButton);
|
|
10
|
+
const likeButton = getByRole('button', { name: 'Like' });
|
|
11
|
+
|
|
12
|
+
expect(likeButton).toBeDefined();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should emit true value when clicked as not liked', async () => {
|
|
16
|
+
const { getByRole, emitted } = render(KvCommentsHeartButton);
|
|
17
|
+
const likeButton = getByRole('button', { name: 'Like' });
|
|
18
|
+
|
|
19
|
+
await userEvent.click(likeButton);
|
|
20
|
+
|
|
21
|
+
expect(emitted()[CLICK_EVENT]).toEqual([[true]]);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should emit false value when clicked as liked', async () => {
|
|
25
|
+
const { getByRole, emitted } = render(KvCommentsHeartButton, { props: { isLiked: true } });
|
|
26
|
+
const likeButton = getByRole('button', { name: 'Like' });
|
|
27
|
+
|
|
28
|
+
await userEvent.click(likeButton);
|
|
29
|
+
|
|
30
|
+
expect(emitted()[CLICK_EVENT]).toEqual([[false]]);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -34,6 +34,6 @@ describe('KvCommentsList', () => {
|
|
|
34
34
|
expect(emitted()[REPLY_COMMENT_EVENT]).toEqual([[{ ...TEST_OBJ, reaction: REPLY_COMMENT_EVENT }]]);
|
|
35
35
|
|
|
36
36
|
await userEvent.click(likeButton);
|
|
37
|
-
expect(emitted()[LIKE_COMMENT_EVENT]).toEqual([[{ ...TEST_OBJ, reaction: LIKE_COMMENT_EVENT }]]);
|
|
37
|
+
expect(emitted()[LIKE_COMMENT_EVENT]).toEqual([[{ ...TEST_OBJ, reaction: LIKE_COMMENT_EVENT, value: true }]]);
|
|
38
38
|
});
|
|
39
39
|
});
|
package/vue/KvButton.vue
CHANGED
|
@@ -53,14 +53,14 @@ export default {
|
|
|
53
53
|
props: {
|
|
54
54
|
/**
|
|
55
55
|
* Use if linking to a Vue route
|
|
56
|
-
|
|
56
|
+
*/
|
|
57
57
|
to: {
|
|
58
58
|
type: [String, Object],
|
|
59
59
|
default: null,
|
|
60
60
|
},
|
|
61
61
|
/**
|
|
62
62
|
* Use if linking to an external link or old-stack page
|
|
63
|
-
|
|
63
|
+
*/
|
|
64
64
|
href: {
|
|
65
65
|
type: String,
|
|
66
66
|
default: null,
|
|
@@ -68,7 +68,7 @@ export default {
|
|
|
68
68
|
/**
|
|
69
69
|
* The behavior of the button when used in an HTML form.
|
|
70
70
|
* `button (default), submit, reset`
|
|
71
|
-
|
|
71
|
+
*/
|
|
72
72
|
type: {
|
|
73
73
|
type: String,
|
|
74
74
|
default: 'button',
|
|
@@ -79,7 +79,7 @@ export default {
|
|
|
79
79
|
/**
|
|
80
80
|
* Appearance of the button
|
|
81
81
|
* `primary (default), secondary, danger, link, ghost`
|
|
82
|
-
|
|
82
|
+
*/
|
|
83
83
|
variant: {
|
|
84
84
|
type: String,
|
|
85
85
|
default: 'primary',
|
|
@@ -90,7 +90,7 @@ export default {
|
|
|
90
90
|
/**
|
|
91
91
|
* State of the button
|
|
92
92
|
* `'' (default), active, disabled, loading`
|
|
93
|
-
|
|
93
|
+
*/
|
|
94
94
|
state: {
|
|
95
95
|
type: String,
|
|
96
96
|
default: '',
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<button
|
|
3
|
+
aria-label="Like"
|
|
4
|
+
@click="changeState"
|
|
5
|
+
>
|
|
6
|
+
<kv-material-icon
|
|
7
|
+
:icon="icon"
|
|
8
|
+
:class="classState"
|
|
9
|
+
/>
|
|
10
|
+
</button>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script>
|
|
14
|
+
import { computed, toRefs } from 'vue-demi';
|
|
15
|
+
import { mdiHeart, mdiHeartOutline } from '@mdi/js';
|
|
16
|
+
import KvMaterialIcon from './KvMaterialIcon.vue';
|
|
17
|
+
|
|
18
|
+
export default {
|
|
19
|
+
name: 'KvCommentsHeartButton',
|
|
20
|
+
components: {
|
|
21
|
+
KvMaterialIcon,
|
|
22
|
+
},
|
|
23
|
+
props: {
|
|
24
|
+
/**
|
|
25
|
+
* Use if small icon is needed
|
|
26
|
+
*/
|
|
27
|
+
isSmall: {
|
|
28
|
+
type: Boolean,
|
|
29
|
+
default: false,
|
|
30
|
+
},
|
|
31
|
+
/**
|
|
32
|
+
* Use if icon is liked
|
|
33
|
+
*/
|
|
34
|
+
isLiked: {
|
|
35
|
+
type: Boolean,
|
|
36
|
+
default: false,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
emits: [
|
|
40
|
+
'click',
|
|
41
|
+
],
|
|
42
|
+
setup(props, { emit }) {
|
|
43
|
+
const {
|
|
44
|
+
isSmall,
|
|
45
|
+
isLiked,
|
|
46
|
+
} = toRefs(props);
|
|
47
|
+
|
|
48
|
+
const icon = computed(() => (isLiked.value ? mdiHeart : mdiHeartOutline));
|
|
49
|
+
|
|
50
|
+
const classState = computed(() => {
|
|
51
|
+
let className = isSmall.value ? 'tw-w-2.5 tw-h-2.5' : 'tw-w-3 tw-h-3';
|
|
52
|
+
className += isLiked.value ? ' filled' : '';
|
|
53
|
+
|
|
54
|
+
return className;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const changeState = () => {
|
|
58
|
+
emit('click', !isLiked.value);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
icon,
|
|
63
|
+
classState,
|
|
64
|
+
changeState,
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
<style scoped>
|
|
71
|
+
.filled >>> svg {
|
|
72
|
+
fill: #F60059;
|
|
73
|
+
}
|
|
74
|
+
</style>
|
package/vue/KvCommentsList.vue
CHANGED
|
@@ -21,21 +21,20 @@
|
|
|
21
21
|
{{ text }}
|
|
22
22
|
</p>
|
|
23
23
|
</div>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</kv-button>
|
|
24
|
+
<div class="tw-flex tw-items-center tw-gap-x-0.5">
|
|
25
|
+
<kv-comments-heart-button
|
|
26
|
+
:is-small="true"
|
|
27
|
+
:is-liked="isLiked"
|
|
28
|
+
@click="onClick(LIKE_COMMENT_EVENT, $event)"
|
|
29
|
+
/>
|
|
30
|
+
<kv-button
|
|
31
|
+
variant="ghost"
|
|
32
|
+
class="tw-font-medium"
|
|
33
|
+
@click="onClick(REPLY_COMMENT_EVENT)"
|
|
34
|
+
>
|
|
35
|
+
Reply
|
|
36
|
+
</kv-button>
|
|
37
|
+
</div>
|
|
39
38
|
<div
|
|
40
39
|
v-if="latestChildren"
|
|
41
40
|
class="tw-my-1"
|
|
@@ -47,6 +46,7 @@
|
|
|
47
46
|
>
|
|
48
47
|
<kv-comments-list-item
|
|
49
48
|
:comment="nested_comment"
|
|
49
|
+
:is-liked="nested_comment.is_liked"
|
|
50
50
|
:nest-level="nestLevel + 1"
|
|
51
51
|
:handle-click="handleClick"
|
|
52
52
|
/>
|
|
@@ -57,13 +57,17 @@
|
|
|
57
57
|
|
|
58
58
|
<script>
|
|
59
59
|
import KvButton from './KvButton.vue';
|
|
60
|
+
import KvCommentsHeartButton from './KvCommentsHeartButton.vue';
|
|
60
61
|
|
|
61
62
|
export const REPLY_COMMENT_EVENT = 'reply-comment';
|
|
62
63
|
export const LIKE_COMMENT_EVENT = 'like-comment';
|
|
63
64
|
|
|
64
65
|
export default {
|
|
65
66
|
name: 'KvCommentsListItem',
|
|
66
|
-
components: {
|
|
67
|
+
components: {
|
|
68
|
+
KvButton,
|
|
69
|
+
KvCommentsHeartButton,
|
|
70
|
+
},
|
|
67
71
|
props: {
|
|
68
72
|
/**
|
|
69
73
|
* Activity comment
|
|
@@ -79,6 +83,13 @@ export default {
|
|
|
79
83
|
type: Number,
|
|
80
84
|
default: 0,
|
|
81
85
|
},
|
|
86
|
+
/**
|
|
87
|
+
* Comment is liked by current user
|
|
88
|
+
*/
|
|
89
|
+
isLiked: {
|
|
90
|
+
type: Boolean,
|
|
91
|
+
default: false,
|
|
92
|
+
},
|
|
82
93
|
/**
|
|
83
94
|
* The function to call when a reaction is clicked
|
|
84
95
|
*/
|
|
@@ -88,12 +99,13 @@ export default {
|
|
|
88
99
|
},
|
|
89
100
|
},
|
|
90
101
|
setup(props) {
|
|
91
|
-
const onClick = (reaction) => {
|
|
102
|
+
const onClick = (reaction, value) => {
|
|
92
103
|
props.handleClick({
|
|
93
104
|
reaction,
|
|
94
105
|
id: props.comment?.id ?? null,
|
|
95
106
|
userId: props.comment?.user_id ?? null,
|
|
96
107
|
isChild: true,
|
|
108
|
+
value,
|
|
97
109
|
});
|
|
98
110
|
};
|
|
99
111
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import KvCommentsHeartButton from '../KvCommentsHeartButton.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'KvCommentsHeartButton',
|
|
5
|
+
component: KvCommentsHeartButton,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const story = (args) => {
|
|
9
|
+
const template = (templateArgs, { argTypes }) => ({
|
|
10
|
+
props: Object.keys(argTypes),
|
|
11
|
+
components: { KvCommentsHeartButton },
|
|
12
|
+
setup() { return { args: templateArgs }; },
|
|
13
|
+
template: `
|
|
14
|
+
<KvCommentsHeartButton v-bind="args" />
|
|
15
|
+
`,
|
|
16
|
+
});
|
|
17
|
+
template.args = args;
|
|
18
|
+
return template;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const Default = story({});
|
|
22
|
+
|
|
23
|
+
export const IsSmall = story({ isSmall: true });
|
|
24
|
+
|
|
25
|
+
export const IsLiked = story({ isLiked: true });
|