feat: optimize dropdown for mobile

This commit is contained in:
Tim
2025-07-21 11:42:31 +08:00
parent bc64e45dc2
commit 9b6a248725
3 changed files with 116 additions and 12 deletions

View File

@@ -1,9 +1,12 @@
<template>
<div class="search-dropdown">
<Dropdown v-model="selected" :fetch-options="fetchResults" remote menu-class="search-menu"
option-class="search-option" :show-search="false">
<Dropdown ref="dropdown" v-model="selected" :fetch-options="fetchResults" remote menu-class="search-menu"
option-class="search-option" :show-search="isMobile" @update:search="keyword = $event" @close="onClose">
<template #display="{ toggle, setSearch }">
<div class="search-input" @click="toggle">
<div v-if="isMobile" class="search-mobile-trigger" @click="toggle">
<i class="fas fa-search"></i>
</div>
<div v-else class="search-input" @click="toggle">
<i class="search-input-icon fas fa-search"></i>
<input class="text-input" v-model="keyword" placeholder="Search" @focus="toggle" @input="setSearch(keyword)" />
</div>
@@ -23,7 +26,8 @@
</template>
<script>
import { ref, watch } from 'vue'
import { ref, watch, onMounted } from 'vue'
import { isMobile } from '../utils/screen'
import { useRouter } from 'vue-router'
import Dropdown from './Dropdown.vue'
import { API_BASE_URL } from '../main'
@@ -32,11 +36,15 @@ import { stripMarkdown } from '../utils/markdown'
export default {
name: 'SearchDropdown',
components: { Dropdown },
setup() {
emits: ['close'],
setup(props, { emit }) {
const router = useRouter()
const keyword = ref('')
const selected = ref(null)
const results = ref([])
const dropdown = ref(null)
const onClose = () => emit('close')
const fetchResults = async (kw) => {
if (!kw) return []
@@ -68,6 +76,12 @@ export default {
comment: 'fas fa-comment'
}
onMounted(() => {
if (isMobile.value && dropdown.value) {
dropdown.value.toggle()
}
})
watch(selected, val => {
if (!val) return
const opt = results.value.find(r => r.id === val)
@@ -85,7 +99,7 @@ export default {
keyword.value = ''
})
return { keyword, selected, fetchResults, highlight, iconMap }
return { keyword, selected, fetchResults, highlight, iconMap, isMobile, dropdown, onClose }
}
}
</script>
@@ -96,6 +110,11 @@ export default {
width: 500px;
}
.search-mobile-trigger {
padding: 10px;
font-size: 18px;
}
.search-input {
padding: 10px;
display: flex;
@@ -118,6 +137,12 @@ export default {
max-width: 600px;
}
@media (max-width: 768px) {
.search-dropdown {
width: 100%;
}
}
.search-option-item {
display: flex;
gap: 10px;