1<template>
2 <div class="flex flex-wrap items-center gap-1.5 pt-1.5">
3 <Popover side="top" align="start">
4 <template #trigger>
5 <Button variant="ghost" class="text-ink-gray-5 -ml-1.5">
6 <template #icon>
7 <ReactionIcon class="size-4" />
8 </template>
9 </Button>
10 </template>
11 <template #default="{ close }">
12 <div class="p-2">
13 <div class="grid grid-cols-6 gap-2">
14 <button
15 v-for="emoji in PRESET_EMOJIS"
16 :key="emoji"
17 class="size-6 flex items-center justify-center rounded-4 hover:bg-surface-gray-2 text-md transition-colors"
18 @click="
19 emit('toggle', emoji);
20 close();
21 "
22 >
23 {{ emoji }}
24 </button>
25 </div>
26 </div>
27 </template>
28 </Popover>
29
30 <Tooltip bare v-for="reaction in reactions" :key="reaction.emoji">
31 <template #content>
32 <div
33 class="bg-surface-gray-10 px-2 py-1 text-center text-p-xs text-ink-base shadow-xl rounded-4"
34 >
35 {{ reaction.users.map((u) => u.full_name).join(", ") }}
36 </div>
37 </template>
38 <button
39 class="flex items-center gap-1 px-2 py-1 rounded-full text-sm transition-colors"
40 :class="
41 reaction.current_user_reacted
42 ? 'bg-surface-blue-2 text-ink-blue-6 hover:bg-surface-blue-3'
43 : 'bg-surface-gray-3 text-ink-gray-6 hover:bg-surface-gray-4'
44 "
45 @click="emit('toggle', reaction.emoji)"
46 >
47 <span>{{ reaction.emoji }}</span>
48 <span class="font-medium">{{ reaction.count }}</span>
49 </button>
50 </Tooltip>
51 </div>
52</template>
53
54<script setup lang="ts">
55import ReactionIcon from "@/components/icons/ReactionIcon.vue";
56import { Button, Popover, Tooltip } from "frappe-ui";
57
58export interface CommentReaction {
59 emoji: string;
60 count: number;
61 users: Array<{ user: string; full_name: string }>;
62 current_user_reacted: boolean;
63}
64
65const PRESET_EMOJIS = ["👍", "👎", "❤️", "🎉", "👀", "✅"];
66
67defineProps<{ reactions: CommentReaction[] }>();
68const emit = defineEmits<{ toggle: [emoji: string] }>();
69</script>
70