You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
3.3 KiB
Vue

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useData } from 'vitepress'
import { createTranslate } from 'vitepress/dist/client/theme-default/support/translation'
import { v4 as uuidv4 } from 'uuid'
import { Icon24Search } from '@vkontakte/icons'
const uid = uuidv4()
const { theme } = useData()
const $t = createTranslate(theme.value.search?.options)
withDefaults(defineProps<{
modelValue: string
placeholder: string
backButton?: boolean
}>(), {
backButton: true
})
/* Search input focus */
const searchInput = ref<HTMLInputElement>()
function focusSearchInput() {
searchInput.value?.focus()
// searchInput.value?.select()
}
onMounted(() => {
focusSearchInput()
})
function onSearchBarClick(event: PointerEvent) {
if (event.pointerType === 'mouse') {
focusSearchInput()
}
}
</script>
<template>
<form class="search-bar" @pointerup="onSearchBarClick($event)" @submit.prevent="">
<label :title="placeholder" id="localsearch-label" :for="uid">
<Icon24Search width="18" height="18" fill="currentColor" />
</label>
<div
v-if="backButton"
class="search-actions before"
>
<button
class="back-button"
:title="$t('modal.backButtonTitle')"
@click="$emit('close')"
>
<svg
width="18"
height="18"
viewBox="0 0 24 24"
aria-hidden="true"
>
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 12H5m7 7l-7-7l7-7"
/>
</svg>
</button>
</div>
<input
ref="searchInput"
:id="uid"
:value="modelValue"
:placeholder="placeholder"
class="search-input"
@input="$emit('update:modelValue', ($event.target as HTMLInputElement).value)"
/>
<div class="search-actions">
<button
v-if="modelValue"
class="clear-button"
:title="$t('modal.resetButtonTitle')"
@click="$emit('update:modelValue', '')"
>
<svg width="24" height="24" viewBox="0 0 20 20">
<path d="M10 10l5.09-5.09L10 10l5.09 5.09L10 10zm0 0L4.91 4.91 10 10l-5.09 5.09L10 10z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</button>
</div>
</form>
</template>
<style scoped>
.search-bar {
border: 1px solid var(--vp-c-gray-soft);
border-radius: 8px;
display: flex;
align-items: center;
padding: 6px 8px;
height: 56px;
cursor: text;
background-color: var(--vp-c-bg-elv);
box-shadow: var(--vp-shadow-1);
}
@media (max-width: 767px) {
.search-bar {
padding: 0 8px;
}
}
.search-bar:focus-within {
border-color: var(--vp-c-border);
}
.search-icon {
margin: 8px;
}
@media (max-width: 767px) {
.search-icon {
display: none;
}
}
.search-input {
padding: 6px 12px;
font-size: inherit;
width: 100%;
}
@media (max-width: 767px) {
.search-input {
padding: 6px 4px;
}
}
.search-actions {
display: flex;
gap: 4px;
}
@media (any-pointer: coarse) {
.search-actions {
gap: 8px;
}
}
@media (min-width: 769px) {
.search-actions.before {
display: none;
}
}
.search-actions button {
padding: 8px;
}
.search-actions button:hover {
color: var(--vp-c-brand-1);
}
</style>