47 lines
2.3 KiB
Vue
47 lines
2.3 KiB
Vue
<script setup lang="ts">
|
|
const { data: nav } = await useAsyncData('search', () => fetchContentNavigation());
|
|
const input = ref('');
|
|
const pos = ref<DOMRect>();
|
|
|
|
function getPos(e: Event) {
|
|
pos.value = (e.currentTarget as HTMLElement)?.getBoundingClientRect();
|
|
}
|
|
function flatten(val: NavItem[]): NavItem[] {
|
|
return val.flatMap ? val?.flatMap((e: NavItem) => e.children ? flatten(e.children) : e) : val;
|
|
}
|
|
function clear(text: string): string
|
|
{
|
|
return text.toLowerCase().trim().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
|
}
|
|
const navigation = computed(() => {
|
|
return flatten(nav.value ?? []);
|
|
})
|
|
const results = computed(() => {
|
|
return navigation.value?.filter((e) => clear(e.title).includes(clear(input.value))) ?? [];
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="search-view-outer">
|
|
<div class="search-view-container">
|
|
<span class="published-search-icon"></span>
|
|
<input class="search-bar" type="text" placeholder="Recherche" v-model="input" @input="getPos">
|
|
</div>
|
|
</div>
|
|
<Teleport to="body" v-if="input !== ''">
|
|
<div class="search-results" :style="{top: (pos.bottom + 4) + 'px', left: pos.left + 'px', width: pos.width + 'px'}">
|
|
<div class="suggestion-item" v-if="results.length > 0" v-for="result of results" :key="result._path" @mouseenter="(e) => (e.target as HTMLElement).classList.add('is-selected')" @mouseleave="(e) => (e.target as HTMLElement).classList.remove('is-selected')" @mousedown.prevent="navigateTo('/explorer' + result._path); input = ''">
|
|
<div class="suggestion-content">
|
|
<div class="suggestion-title">
|
|
<ProseA :href="result._path">
|
|
{{ result.title.substring(0, clear(result.title).indexOf(clear(input))) }}<span class="suggestion-highlight">{{ result.title.substring(clear(result.title).indexOf(clear(input)), clear(result.title).indexOf(clear(input)) + clear(input).length + 1) }}</span>{{ result.title.substring(clear(result.title).indexOf(clear(input)) + clear(input).length + 1) }}
|
|
</ProseA>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="suggestion-empty" v-else>
|
|
Aucun résultat
|
|
</div>
|
|
</div>
|
|
</Teleport>
|
|
</template> |