koel/resources/assets/js/components/ui/SearchForm.vue

116 lines
2.3 KiB
Vue
Raw Normal View History

2022-04-15 14:24:30 +00:00
<template>
2022-10-13 15:18:47 +00:00
<form id="searchForm" role="search" @submit.prevent="onSubmit">
<span class="icon">
2022-12-02 16:17:37 +00:00
<icon :icon="faSearch" />
</span>
2022-04-15 14:24:30 +00:00
<input
2022-04-24 20:23:20 +00:00
ref="input"
v-model="q"
2022-04-15 14:24:30 +00:00
:class="{ dirty: q }"
:placeholder="placeholder"
2022-04-15 14:24:30 +00:00
autocorrect="false"
2022-04-24 20:23:20 +00:00
name="q"
required
2022-04-15 14:24:30 +00:00
spellcheck="false"
2022-04-24 20:23:20 +00:00
type="search"
2022-10-13 15:18:47 +00:00
@focus="maybeGoToSearchScreen"
2022-04-24 20:23:20 +00:00
@input="onInput"
2022-04-15 14:24:30 +00:00
>
2022-10-13 15:18:47 +00:00
<button type="submit" title="Search">
2022-12-02 16:17:37 +00:00
<icon :icon="faSearch" />
2022-10-13 15:18:47 +00:00
</button>
</form>
2022-04-15 14:24:30 +00:00
</template>
2022-04-15 17:00:08 +00:00
<script lang="ts" setup>
2022-10-13 15:18:47 +00:00
import isMobile from 'ismobilejs'
import { faSearch } from '@fortawesome/free-solid-svg-icons'
2022-04-15 17:00:08 +00:00
import { ref } from 'vue'
2022-04-15 14:24:30 +00:00
import { debounce } from 'lodash'
2022-11-18 18:44:20 +00:00
import { eventBus } from '@/utils'
import { useRouter } from '@/composables'
2022-10-13 15:18:47 +00:00
const placeholder = isMobile.any ? 'Search' : 'Press F to search'
2022-11-18 18:44:20 +00:00
const { go } = useRouter()
2022-04-15 14:24:30 +00:00
2022-04-24 20:23:20 +00:00
const input = ref<HTMLInputElement>()
2022-04-15 17:00:08 +00:00
const q = ref('')
2022-04-15 14:24:30 +00:00
let onInput = () => {
2022-04-15 17:00:08 +00:00
const _q = q.value.trim()
_q && eventBus.emit('SEARCH_KEYWORDS_CHANGED', _q)
}
if (process.env.NODE_ENV !== 'test') {
onInput = debounce(onInput, 500)
}
2022-04-15 14:24:30 +00:00
2022-10-13 15:18:47 +00:00
const onSubmit = () => {
eventBus.emit('TOGGLE_SIDEBAR')
2022-11-18 18:44:20 +00:00
go('search')
2022-10-13 15:18:47 +00:00
}
2022-11-18 18:44:20 +00:00
const maybeGoToSearchScreen = () => isMobile.any || go('search')
2022-04-15 14:24:30 +00:00
eventBus.on('FOCUS_SEARCH_FIELD', () => {
input.value?.focus()
input.value?.select()
2022-04-15 14:24:30 +00:00
})
</script>
<style lang="scss">
#searchForm {
2022-10-13 15:18:47 +00:00
display: flex;
align-items: stretch;
color: var(--color-text-secondary);
background: rgba(0, 0, 0, .2);
2022-10-13 15:18:47 +00:00
border: 1px solid transparent;
border-radius: 5px;
transition: border .3s ease-in-out, .3s background-color ease-in-out;
2022-10-13 15:18:47 +00:00
overflow: hidden;
padding: 0 0 0 1rem;
gap: .5rem;
.icon {
display: flex;
align-items: center;
opacity: .7;
@media screen and (max-width: 768px) {
display: none;
}
}
2022-04-15 14:24:30 +00:00
2022-10-13 15:18:47 +00:00
button {
display: none;
padding: 0 1.2rem;
2022-10-13 15:18:47 +00:00
background: rgba(255, 255, 255, .05);
border-radius: 0;
@media screen and (max-width: 768px) {
display: block;
}
2022-04-15 14:24:30 +00:00
}
2022-10-13 15:18:47 +00:00
&:focus-within {
border: 1px solid rgba(255, 255, 255, .2);
background: rgba(0, 0, 0, .5);
2022-10-13 15:18:47 +00:00
}
input[type="search"] {
2022-04-15 14:24:30 +00:00
width: 100%;
2022-10-13 15:18:47 +00:00
border-radius: 0;
height: 36px;
color: var(--color-text-primary);
background-color: transparent;
2022-04-15 14:24:30 +00:00
2022-10-13 15:18:47 +00:00
&::placeholder {
color: rgba(255, 255, 255, .5);
2022-04-15 14:24:30 +00:00
}
}
}
</style>