feat(theme): add semantic markup to local search dialog (#2325)

pull/1844/head
Joaquín Sánchez 2 years ago committed by GitHub
parent c9a98ac6bb
commit 4ddb96fe50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -241,10 +241,12 @@ async function fetchExcerpt(id: string) {
/* Search input focus */ /* Search input focus */
const searchInput = ref<HTMLInputElement>() const searchInput = ref<HTMLInputElement>()
const disableReset = computed(() => {
function focusSearchInput() { return filterText.value?.length <= 0
})
function focusSearchInput(select = true) {
searchInput.value?.focus() searchInput.value?.focus()
searchInput.value?.select() select && searchInput.value?.select()
} }
onMounted(() => { onMounted(() => {
@ -259,11 +261,11 @@ function onSearchBarClick(event: PointerEvent) {
/* Search keyboard selection */ /* Search keyboard selection */
const selectedIndex = ref(0) const selectedIndex = ref(-1)
const disableMouseOver = ref(false) const disableMouseOver = ref(false)
watch(results, () => { watch(results, (r) => {
selectedIndex.value = 0 selectedIndex.value = r.length ? 0 : -1
scrollToSelectedResult() scrollToSelectedResult()
}) })
@ -360,6 +362,11 @@ onBeforeUnmount(() => {
isLocked.value = false isLocked.value = false
}) })
function resetSearch() {
filterText.value = ''
nextTick().then(() => focusSearchInput(false))
}
function formMarkRegex(terms: Set<string>) { function formMarkRegex(terms: Set<string>) {
return new RegExp( return new RegExp(
[...terms] [...terms]
@ -377,11 +384,20 @@ function formMarkRegex(terms: Set<string>) {
<template> <template>
<Teleport to="body"> <Teleport to="body">
<div ref="el" class="VPLocalSearchBox" aria-modal="true"> <div
ref="el"
role="button"
:aria-owns="results?.length ? 'localsearch-list' : undefined"
aria-expanded="true"
aria-haspopup="listbox"
aria-labelledby="localsearch-label"
class="VPLocalSearchBox"
>
<div class="backdrop" @click="$emit('close')" /> <div class="backdrop" @click="$emit('close')" />
<div class="shell"> <div class="shell">
<div class="search-bar" @pointerup="onSearchBarClick($event)"> <form class="search-bar" @pointerup="onSearchBarClick($event)" @submit.prevent="">
<label :title="placeholder" id="localsearch-label" for="localsearch-input">
<svg <svg
class="search-icon" class="search-icon"
width="18" width="18"
@ -400,11 +416,12 @@ function formMarkRegex(terms: Set<string>) {
<path d="m21 21l-4.35-4.35" /> <path d="m21 21l-4.35-4.35" />
</g> </g>
</svg> </svg>
</label>
<div class="search-actions before"> <div class="search-actions before">
<button <button
class="back-button" class="back-button"
:title="$t('modal.backButtonTitle')" :title="$t('modal.backButtonTitle')"
@click="$emit('close')" @click="selectedIndex > -1 && $emit('close')"
> >
<svg <svg
width="18" width="18"
@ -427,6 +444,8 @@ function formMarkRegex(terms: Set<string>) {
ref="searchInput" ref="searchInput"
v-model="filterText" v-model="filterText"
:placeholder="placeholder" :placeholder="placeholder"
id="localsearch-input"
aria-labelledby="localsearch-label"
class="search-input" class="search-input"
/> />
<div class="search-actions"> <div class="search-actions">
@ -435,7 +454,7 @@ function formMarkRegex(terms: Set<string>) {
class="toggle-layout-button" class="toggle-layout-button"
:class="{ 'detailed-list': showDetailedList }" :class="{ 'detailed-list': showDetailedList }"
:title="$t('modal.displayDetails')" :title="$t('modal.displayDetails')"
@click="showDetailedList = !showDetailedList" @click="selectedIndex > -1 && (showDetailedList = !showDetailedList)"
> >
<svg <svg
width="18" width="18"
@ -456,8 +475,10 @@ function formMarkRegex(terms: Set<string>) {
<button <button
class="clear-button" class="clear-button"
type="reset"
:disabled="disableReset"
:title="$t('modal.resetButtonTitle')" :title="$t('modal.resetButtonTitle')"
@click="filterText = ''" @click="resetSearch"
> >
<svg <svg
width="18" width="18"
@ -476,16 +497,23 @@ function formMarkRegex(terms: Set<string>) {
</svg> </svg>
</button> </button>
</div> </div>
</div> </form>
<div <ul
ref="resultsEl" ref="resultsEl"
:id="results?.length ? 'localsearch-list' : undefined"
:role="results?.length ? 'listbox' : undefined"
:aria-labelledby="results?.length ? 'localsearch-label' : undefined"
class="results" class="results"
@mousemove="disableMouseOver = false" @mousemove="disableMouseOver = false"
> >
<a <li
v-for="(p, index) in results" v-for="(p, index) in results"
:key="p.id" :key="p.id"
role="option"
:aria-selected="selectedIndex === index ? 'true' : 'false'"
>
<a
:href="p.id" :href="p.id"
class="result" class="result"
:class="{ :class="{
@ -526,15 +554,15 @@ function formMarkRegex(terms: Set<string>) {
</div> </div>
</div> </div>
</a> </a>
</li>
<div <li
v-if="filterText && !results.length && enableNoResults" v-if="filterText && !results.length && enableNoResults"
class="no-results" class="no-results"
> >
{{ $t('modal.noResultsText') }} "<strong>{{ filterText }}</strong {{ $t('modal.noResultsText') }} "<strong>{{ filterText }}</strong
>" >"
</div> </li>
</div> </ul>
<div class="search-keyboard-shortcuts"> <div class="search-keyboard-shortcuts">
<span> <span>
@ -692,11 +720,15 @@ function formMarkRegex(terms: Set<string>) {
padding: 8px; padding: 8px;
} }
.search-actions button:hover, .search-actions button:not([disabled]):hover,
.toggle-layout-button.detailed-list { .toggle-layout-button.detailed-list {
color: var(--vp-c-brand); color: var(--vp-c-brand);
} }
.search-actions button.clear-button:disabled {
opacity: 0.37;
}
.search-keyboard-shortcuts { .search-keyboard-shortcuts {
font-size: 0.8rem; font-size: 0.8rem;
opacity: 75%; opacity: 75%;

Loading…
Cancel
Save