* fix(search): improve more general usability Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> * fix: revert naming Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> * fix: correct check for enter event on no-match cases Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> * Update quartz/components/scripts/search.inline.ts Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * chore: remove unecessary class for tracking mouse Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --------- Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
This commit is contained in:
parent
444e05ee21
commit
9aa6a18be2
@ -122,6 +122,9 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
|
|||||||
if (preview) {
|
if (preview) {
|
||||||
removeAllChildren(preview)
|
removeAllChildren(preview)
|
||||||
}
|
}
|
||||||
|
if (searchLayout) {
|
||||||
|
searchLayout.style.opacity = "0"
|
||||||
|
}
|
||||||
|
|
||||||
searchType = "basic" // reset search type after closing
|
searchType = "basic" // reset search type after closing
|
||||||
}
|
}
|
||||||
@ -135,6 +138,8 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
|
|||||||
searchBar?.focus()
|
searchBar?.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let currentHover: HTMLInputElement | null = null
|
||||||
|
|
||||||
async function shortcutHandler(e: HTMLElementEventMap["keydown"]) {
|
async function shortcutHandler(e: HTMLElementEventMap["keydown"]) {
|
||||||
if (e.key === "k" && (e.ctrlKey || e.metaKey) && !e.shiftKey) {
|
if (e.key === "k" && (e.ctrlKey || e.metaKey) && !e.shiftKey) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@ -150,51 +155,61 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
|
|||||||
if (searchBar) searchBar.value = "#"
|
if (searchBar) searchBar.value = "#"
|
||||||
}
|
}
|
||||||
|
|
||||||
const resultCards = document.getElementsByClassName("result-card")
|
if (currentHover) {
|
||||||
|
currentHover.classList.remove("focus")
|
||||||
|
}
|
||||||
|
|
||||||
// If search is active, then we will render the first result and display accordingly
|
// If search is active, then we will render the first result and display accordingly
|
||||||
if (!container?.classList.contains("active")) return
|
if (!container?.classList.contains("active")) return
|
||||||
else if (results?.contains(document.activeElement)) {
|
else if (e.key === "Enter") {
|
||||||
const active = document.activeElement as HTMLInputElement
|
// If result has focus, navigate to that one, otherwise pick first result
|
||||||
await displayPreview(active)
|
if (results?.contains(document.activeElement)) {
|
||||||
if (e.key === "Enter") {
|
const active = document.activeElement as HTMLInputElement
|
||||||
|
if (active.classList.contains("no-match")) return
|
||||||
|
await displayPreview(active)
|
||||||
active.click()
|
active.click()
|
||||||
|
} else {
|
||||||
|
const anchor = document.getElementsByClassName("result-card")[0] as HTMLInputElement | null
|
||||||
|
if (!anchor || anchor?.classList.contains("no-match")) return
|
||||||
|
await displayPreview(anchor)
|
||||||
|
anchor.click()
|
||||||
}
|
}
|
||||||
} else {
|
} else if (e.key === "ArrowUp" || (e.shiftKey && e.key === "Tab")) {
|
||||||
const anchor = resultCards[0] as HTMLInputElement | null
|
|
||||||
await displayPreview(anchor)
|
|
||||||
if (e.key === "Enter") {
|
|
||||||
anchor?.click()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.key === "ArrowUp" || (e.shiftKey && e.key === "Tab")) {
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (results?.contains(document.activeElement)) {
|
if (results?.contains(document.activeElement)) {
|
||||||
// If an element in results-container already has focus, focus previous one
|
// If an element in results-container already has focus, focus previous one
|
||||||
const currentResult = document.activeElement as HTMLInputElement | null
|
const currentResult = currentHover
|
||||||
|
? currentHover
|
||||||
|
: (document.activeElement as HTMLInputElement | null)
|
||||||
const prevResult = currentResult?.previousElementSibling as HTMLInputElement | null
|
const prevResult = currentResult?.previousElementSibling as HTMLInputElement | null
|
||||||
currentResult?.classList.remove("focus")
|
currentResult?.classList.remove("focus")
|
||||||
await displayPreview(prevResult)
|
await displayPreview(prevResult)
|
||||||
prevResult?.focus()
|
prevResult?.focus()
|
||||||
|
currentHover = prevResult
|
||||||
}
|
}
|
||||||
} else if (e.key === "ArrowDown" || e.key === "Tab") {
|
} else if (e.key === "ArrowDown" || e.key === "Tab") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
// The results should already been focused, so we need to find the next one.
|
// The results should already been focused, so we need to find the next one.
|
||||||
// The activeElement is the search bar, so we need to find the first result and focus it.
|
// The activeElement is the search bar, so we need to find the first result and focus it.
|
||||||
if (!results?.contains(document.activeElement)) {
|
if (!results?.contains(document.activeElement)) {
|
||||||
const firstResult = resultCards[0] as HTMLInputElement | null
|
const firstResult = currentHover
|
||||||
|
? currentHover
|
||||||
|
: (document.getElementsByClassName("result-card")[0] as HTMLInputElement | null)
|
||||||
const secondResult = firstResult?.nextElementSibling as HTMLInputElement | null
|
const secondResult = firstResult?.nextElementSibling as HTMLInputElement | null
|
||||||
firstResult?.classList.remove("focus")
|
firstResult?.classList.remove("focus")
|
||||||
await displayPreview(secondResult)
|
await displayPreview(secondResult)
|
||||||
secondResult?.focus()
|
secondResult?.focus()
|
||||||
|
currentHover = secondResult
|
||||||
} else {
|
} else {
|
||||||
// If an element in results-container already has focus, focus next one
|
// If an element in results-container already has focus, focus next one
|
||||||
const active = document.activeElement as HTMLInputElement | null
|
const active = currentHover
|
||||||
|
? currentHover
|
||||||
|
: (document.activeElement as HTMLInputElement | null)
|
||||||
active?.classList.remove("focus")
|
active?.classList.remove("focus")
|
||||||
const nextResult = active?.nextElementSibling as HTMLInputElement | null
|
const nextResult = active?.nextElementSibling as HTMLInputElement | null
|
||||||
await displayPreview(nextResult)
|
await displayPreview(nextResult)
|
||||||
nextResult?.focus()
|
nextResult?.focus()
|
||||||
|
currentHover = nextResult
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,15 +297,17 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
|
|||||||
|
|
||||||
async function onMouseEnter(ev: MouseEvent) {
|
async function onMouseEnter(ev: MouseEvent) {
|
||||||
// Actually when we hover, we need to clean all highlights within the result childs
|
// Actually when we hover, we need to clean all highlights within the result childs
|
||||||
|
if (!ev.target) return
|
||||||
for (const el of document.getElementsByClassName(
|
for (const el of document.getElementsByClassName(
|
||||||
"result-card",
|
"result-card",
|
||||||
) as HTMLCollectionOf<HTMLElement>) {
|
) as HTMLCollectionOf<HTMLElement>) {
|
||||||
el.classList.remove("focus")
|
el.classList.remove("focus")
|
||||||
el.blur()
|
el.blur()
|
||||||
}
|
}
|
||||||
const target = ev.target as HTMLAnchorElement
|
const target = ev.target as HTMLInputElement
|
||||||
target.classList.add("focus")
|
|
||||||
await displayPreview(target)
|
await displayPreview(target)
|
||||||
|
currentHover = target
|
||||||
|
currentHover.classList.remove("focus")
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onMouseLeave(ev: MouseEvent) {
|
async function onMouseLeave(ev: MouseEvent) {
|
||||||
@ -320,7 +337,7 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
|
|||||||
|
|
||||||
removeAllChildren(results)
|
removeAllChildren(results)
|
||||||
if (finalResults.length === 0) {
|
if (finalResults.length === 0) {
|
||||||
results.innerHTML = `<a class="result-card">
|
results.innerHTML = `<a class="result-card no-match">
|
||||||
<h3>No results.</h3>
|
<h3>No results.</h3>
|
||||||
<p>Try another search term?</p>
|
<p>Try another search term?</p>
|
||||||
</a>`
|
</a>`
|
||||||
@ -329,8 +346,13 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
|
|||||||
}
|
}
|
||||||
// focus on first result, then also dispatch preview immediately
|
// focus on first result, then also dispatch preview immediately
|
||||||
if (results?.firstElementChild) {
|
if (results?.firstElementChild) {
|
||||||
results?.firstElementChild?.classList.add("focus")
|
const firstChild = results.firstElementChild as HTMLElement
|
||||||
await displayPreview(results?.firstElementChild as HTMLElement)
|
if (firstChild.classList.contains("no-match")) {
|
||||||
|
removeAllChildren(preview as HTMLElement)
|
||||||
|
} else {
|
||||||
|
firstChild.classList.add("focus")
|
||||||
|
await displayPreview(firstChild)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user