doc.yeswiki.pro/node_modules/vitepress/dist/client/theme-default/components/VPAlgoliaSearchBox.vue

101 lines
2.4 KiB
Vue
Raw Normal View History

2023-05-20 19:37:42 +03:00
<script setup lang="ts">
import type { DefaultTheme } from 'vitepress/theme'
import docsearch from '@docsearch/js'
import { onMounted, watch } from 'vue'
import { useRouter, useRoute } from 'vitepress'
import { useData } from '../composables/data'
const props = defineProps<{
algolia: DefaultTheme.AlgoliaSearchOptions
}>()
const router = useRouter()
const route = useRoute()
const { site, localeIndex, lang } = useData()
type DocSearchProps = Parameters<typeof docsearch>[0]
onMounted(update)
watch(localeIndex, update)
function update() {
const options = {
...props.algolia,
...props.algolia.locales?.[localeIndex.value]
}
const rawFacetFilters = options.searchParameters?.facetFilters ?? []
const facetFilters = [
...(Array.isArray(rawFacetFilters)
? rawFacetFilters
: [rawFacetFilters]
).filter((f) => !f.startsWith('lang:')),
`lang:${lang.value}`
]
initialize({
...options,
searchParameters: {
...options.searchParameters,
facetFilters
}
})
}
function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
const options = Object.assign<{}, {}, DocSearchProps>({}, userOptions, {
container: '#docsearch',
navigator: {
navigate({ itemUrl }) {
const { pathname: hitPathname } = new URL(
window.location.origin + itemUrl
)
// router doesn't handle same-page navigation so we use the native
// browser location API for anchor navigation
if (route.path === hitPathname) {
window.location.assign(window.location.origin + itemUrl)
} else {
router.go(itemUrl)
}
}
},
transformItems(items) {
return items.map((item) => {
return Object.assign({}, item, {
url: getRelativePath(item.url)
})
})
},
// @ts-expect-error vue-tsc thinks this should return Vue JSX but it returns the required React one
hitComponent({ hit, children }) {
return {
__v: null,
type: 'a',
ref: undefined,
constructor: undefined,
key: undefined,
props: { href: hit.url, children }
}
}
})
docsearch(options)
}
function getRelativePath(absoluteUrl: string) {
const { pathname, hash } = new URL(absoluteUrl)
return (
pathname.replace(
/\.html$/,
site.value.cleanUrls ? '' : '.html'
) + hash
)
}
</script>
<template>
<div id="docsearch" />
</template>