|
| 1 | +<template> |
| 2 | + <DocSearch :options="docsearchOptions" /> |
| 3 | +</template> |
| 4 | + |
| 5 | +<script setup lang="ts"> |
| 6 | +import { DocSearch } from '@vuepress/plugin-docsearch/client'; |
| 7 | +import { useDebounceFn, useEventListener } from '@vueuse/core'; |
| 8 | +import { onMounted, onUnmounted, ref } from 'vue'; |
| 9 | +import { useRouter, useRoute } from 'vue-router'; |
| 10 | +
|
| 11 | +const SEARCH_KEY = 'search'; |
| 12 | +const docsearchOptions = ref({}); |
| 13 | +const router = useRouter(); |
| 14 | +const route = useRoute(); |
| 15 | +
|
| 16 | +// Handle initial search query, if one is set |
| 17 | +onMounted(() => { |
| 18 | + const query = new URL(window.location.href).searchParams.get(SEARCH_KEY); |
| 19 | + if (query) { |
| 20 | + docsearchOptions.value.initialQuery = query; |
| 21 | + document.querySelector('.DocSearch-Button').click(); |
| 22 | + } |
| 23 | +}); |
| 24 | +
|
| 25 | +// There's some debounce builtin to docsearch, this mimics that and should |
| 26 | +// help prevent browser history from getting filled with partial queries. |
| 27 | +const inputHandler = useDebounceFn(handleSearchInput, 500); |
| 28 | +useEventListener('input', inputHandler); |
| 29 | +
|
| 30 | +// Update the URL bar when the search input changes. |
| 31 | +function handleSearchInput(event) { |
| 32 | + const searchQuery = event.target.value; |
| 33 | +
|
| 34 | + if (event.target.id !== 'docsearch-input' || !searchQuery) { |
| 35 | + return; |
| 36 | + } |
| 37 | +
|
| 38 | + // If we had already started a search, replace it instead of appending |
| 39 | + const { path, query: routeQuery } = route; |
| 40 | + const replace = routeQuery?.hasOwnProperty(SEARCH_KEY); |
| 41 | + const query = { ...routeQuery }; // NOTE: must copy the query object |
| 42 | + query[SEARCH_KEY] = searchQuery; |
| 43 | +
|
| 44 | + router.push({ path, query: { ...query }, replace }); |
| 45 | +} |
| 46 | +</script> |
0 commit comments