<template> <div class="driuhtrh"> <div class="query"> <MkInput v-model="q" class="" :placeholder="$ts.search"> <template #prefix><i class="ti ti-search"></i></template> </MkInput> <!-- たくさんあると邪魔 <div class="tags"> <span class="tag _button" v-for="tag in customEmojiTags" :class="{ active: selectedTags.has(tag) }" @click="toggleTag(tag)">{{ tag }}</span> </div> --> </div> <MkFoldableSection v-if="searchEmojis" class="emojis"> <template #header>{{ $ts.searchResult }}</template> <div class="zuvgdzyt"> <XEmoji v-for="emoji in searchEmojis" :key="emoji.name" class="emoji" :emoji="emoji"/> </div> </MkFoldableSection> <MkFoldableSection v-for="category in customEmojiCategories" v-once :key="category" class="emojis"> <template #header>{{ category || $ts.other }}</template> <div class="zuvgdzyt"> <XEmoji v-for="emoji in customEmojis.filter(e => e.category === category)" :key="emoji.name" class="emoji" :emoji="emoji"/> </div> </MkFoldableSection> </div> </template> <script lang="ts" setup> import { defineComponent, computed, watch } from 'vue'; import XEmoji from './emojis.emoji.vue'; import MkButton from '@/components/MkButton.vue'; import MkInput from '@/components/MkInput.vue'; import MkSelect from '@/components/MkSelect.vue'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; import MkTab from '@/components/MkTab.vue'; import * as os from '@/os'; import { getCustomEmojis, getCustomEmojiCategories, getCustomEmojiTags } from '@/custom-emojis'; const customEmojis = await getCustomEmojis(); const customEmojiCategories = await getCustomEmojiCategories(); const customEmojiTags = await getCustomEmojiTags(); let q = $ref(''); let searchEmojis = $ref(null); let selectedTags = $ref(new Set()); function search() { if ((q === '' || q == null) && selectedTags.size === 0) { searchEmojis = null; return; } if (selectedTags.size === 0) { searchEmojis = customEmojis.filter(emoji => emoji.name.includes(q) || emoji.aliases.includes(q)); } else { searchEmojis = customEmojis.filter(emoji => (emoji.name.includes(q) || emoji.aliases.includes(q)) && [...selectedTags].every(t => emoji.aliases.includes(t))); } } function toggleTag(tag) { if (selectedTags.has(tag)) { selectedTags.delete(tag); } else { selectedTags.add(tag); } } watch($$(q), () => { search(); }); watch($$(selectedTags), () => { search(); }, { deep: true }); </script> <style lang="scss" scoped> .driuhtrh { background: var(--bg); > .query { background: var(--bg); padding: 16px; > .tags { > .tag { display: inline-block; margin: 8px 8px 0 0; padding: 4px 8px; font-size: 0.9em; background: var(--accentedBg); border-radius: 5px; &.active { background: var(--accent); color: var(--fgOnAccent); } } } } > .emojis { --x-padding: 0 16px; .zuvgdzyt { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); grid-gap: 12px; margin: 0 var(--margin) var(--margin) var(--margin); } } } </style>