Aaron Pham
2024-11-14 f24a1472765e0752bcf158a3db53a717b8dc2191
quartz/components/scripts/search.inline.ts
@@ -21,6 +21,7 @@
  encode: encoder,
  document: {
    id: "id",
    tag: "tags",
    index: [
      {
        field: "title",
@@ -147,7 +148,7 @@
  const data = await fetchData
  const container = document.getElementById("search-container")
  const sidebar = container?.closest(".sidebar") as HTMLElement
  const searchIcon = document.getElementById("search-icon")
  const searchButton = document.getElementById("search-button")
  const searchBar = document.getElementById("search-bar") as HTMLInputElement | null
  const searchLayout = document.getElementById("search-layout")
  const idDataMap = Object.keys(data) as FullSlug[]
@@ -177,7 +178,7 @@
      searchBar.value = "" // clear the input when we dismiss the search
    }
    if (sidebar) {
      sidebar.style.zIndex = "unset"
      sidebar.style.zIndex = ""
    }
    if (results) {
      removeAllChildren(results)
@@ -190,6 +191,8 @@
    }
    searchType = "basic" // reset search type after closing
    searchButton?.focus()
  }
  function showSearch(searchTypeNew: SearchType) {
@@ -405,11 +408,33 @@
    let searchResults: FlexSearch.SimpleDocumentSearchResultSetUnit[]
    if (searchType === "tags") {
      searchResults = await index.searchAsync({
        query: currentSearchTerm.substring(1),
        limit: numSearchResults,
        index: ["tags"],
      })
      currentSearchTerm = currentSearchTerm.substring(1).trim()
      const separatorIndex = currentSearchTerm.indexOf(" ")
      if (separatorIndex != -1) {
        // search by title and content index and then filter by tag (implemented in flexsearch)
        const tag = currentSearchTerm.substring(0, separatorIndex)
        const query = currentSearchTerm.substring(separatorIndex + 1).trim()
        searchResults = await index.searchAsync({
          query: query,
          // return at least 10000 documents, so it is enough to filter them by tag (implemented in flexsearch)
          limit: Math.max(numSearchResults, 10000),
          index: ["title", "content"],
          tag: tag,
        })
        for (let searchResult of searchResults) {
          searchResult.result = searchResult.result.slice(0, numSearchResults)
        }
        // set search type to basic and remove tag from term for proper highlightning and scroll
        searchType = "basic"
        currentSearchTerm = query
      } else {
        // default search by tags index
        searchResults = await index.searchAsync({
          query: currentSearchTerm,
          limit: numSearchResults,
          index: ["tags"],
        })
      }
    } else if (searchType === "basic") {
      searchResults = await index.searchAsync({
        query: currentSearchTerm,
@@ -435,8 +460,8 @@
  document.addEventListener("keydown", shortcutHandler)
  window.addCleanup(() => document.removeEventListener("keydown", shortcutHandler))
  searchIcon?.addEventListener("click", () => showSearch("basic"))
  window.addCleanup(() => searchIcon?.removeEventListener("click", () => showSearch("basic")))
  searchButton?.addEventListener("click", () => showSearch("basic"))
  window.addCleanup(() => searchButton?.removeEventListener("click", () => showSearch("basic")))
  searchBar?.addEventListener("input", onType)
  window.addCleanup(() => searchBar?.removeEventListener("input", onType))