@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 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.53.0",
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": "f9f7231aa673a793c38ed14e55977ecb1d9dc89b"
78
+ "gitHead": "b29d4c7e40f229ac09c7f68c377741af7d068158"
79
79
  }
@@ -39,6 +39,7 @@ const comments = {
39
39
  parent: '',
40
40
  latest_children: {},
41
41
  children_counts: {},
42
+ is_liked: true,
42
43
  },
43
44
  {
44
45
  created_at: '2024-02-01T20:06:46.651764Z',
@@ -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>
@@ -6,6 +6,7 @@
6
6
  :key="comment.id"
7
7
  :nest-level="1"
8
8
  :comment="comment"
9
+ :is-liked="comment.is_liked"
9
10
  :handle-click="handleClick"
10
11
  />
11
12
  </div>
@@ -21,21 +21,20 @@
21
21
  {{ text }}
22
22
  </p>
23
23
  </div>
24
-
25
- <kv-button
26
- variant="ghost"
27
- class="tw-font-medium"
28
- @click="onClick(REPLY_COMMENT_EVENT)"
29
- >
30
- Reply
31
- </kv-button>
32
- <kv-button
33
- variant="ghost"
34
- class="tw-font-medium"
35
- @click="onClick(LIKE_COMMENT_EVENT)"
36
- >
37
- Like
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: { KvButton },
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 });