tutorialkit icon indicating copy to clipboard operation
tutorialkit copied to clipboard

SearchBar

Open noam-honig opened this issue 1 year ago • 9 comments

Is your feature request related to a problem?

It'll be great to have a searchbar, so that users can search the tutorial and find relevant chapters for their search

Describe the solution you'd like.

.

Describe alternatives you've considered.

.

Additional context

No response

noam-honig avatar Aug 16 '24 07:08 noam-honig

Would VitePress-like algolia search work here? https://vitepress.dev/

So the search should be run against lesson markdown files, right? And maybe the titles of chapters and parts.

AriPerkkio avatar Aug 16 '24 07:08 AriPerkkio

Yes - the search should run against lessons and titles

As for algolia - I don't know - on our vitepres site (https://remult.dev) we use the basic vitepress search functionality.

noam-honig avatar Aug 16 '24 07:08 noam-honig

Svelte tutorial has something similar: https://learn.svelte.dev

AriPerkkio avatar Aug 16 '24 15:08 AriPerkkio

We discussed this with @Nemikolh and decided to try adding similar search as Starlight has: https://starlight.astro.build/guides/site-search/. It's using Pagefind, that allows users to perform the search against static files. Services like algolia would require third party servers which is not something we would like at this point.

AriPerkkio avatar Aug 19 '24 15:08 AriPerkkio

@AriPerkkio I agree with the approach - it sounds great

noam-honig avatar Aug 19 '24 20:08 noam-honig

@AriPerkkio is there a way to add search, like the one that exists on the TutorialKit website?

image

If you point me in the right direction of where the code that defines that ui element is, I can try and do it myself / contribute

noam-honig avatar Oct 25 '24 21:10 noam-honig

Ok - spent 3 hours stumbling across astro and frontend skills that I don't have, ended up with something working.

npm i pagefind 
npm i -D @pagefind/default-ui shx

Changed the build script in package json to build the index and copy the index files to public for search during dev:

"build": "astro check && astro build && pagefind --site dist && shx cp -r dist/pagefind ../public/",

Added a Search.astro file in components:

---

---

<button
  id="search-button"
  aria-label="Search"
  class="flex items-center text-2xl text-tk-elements-topBar-iconButton-iconColor hover:text-tk-elements-topBar-iconButton-iconColorHover transition-theme bg-tk-elements-topBar-iconButton-backgroundColor hover:bg-tk-elements-topBar-iconButton-backgroundColorHover p-1 rounded-md"
  ><div class="i-ri:search-fill w-1em h-1em"></div>
</button>

<dialog id="search-dialog">
  <div id="search-container"></div>
</dialog>
<link href="/pagefind/pagefind-ui.css" rel="stylesheet" />
<script>
  //@ts-ignore
  import { PagefindUI } from '@pagefind/default-ui'

  function initializeSearch() {
    const button = document.getElementById('search-button')
    const dialog = document.getElementById('search-dialog')
    const searchContainer = document.getElementById('search-container')
    let pagefindUI: any = null

    if (button && dialog && searchContainer) {
      button.addEventListener('click', () => {
        //@ts-ignore
        dialog.showModal()

        if (!pagefindUI) {
          searchContainer.innerHTML = ''
          pagefindUI = new PagefindUI({
            element: '#search-container',
            showImages: false,
            translations: {
              placeholder: 'Search documentation...',
            },
          })
        }
      })

      dialog.addEventListener('click', (event) => {
        if (event.target === dialog) {
          //@ts-ignore
          dialog.close()
          if (pagefindUI) {
            pagefindUI = null
            searchContainer.innerHTML = ''
          }
        }
      })
    }
  }

  // Run the initialization function when the script loads
  initializeSearch()

  // Re-run the initialization on Astro page changes
  document.addEventListener('astro:page-load', initializeSearch)
</script>

<style>
  #search-button {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
  }

  #search-dialog {
    position: fixed;

    padding: 2rem;
    border-radius: 0.5rem;
    border: none;
    box-shadow: 0 0 1rem rgba(0, 0, 0, 0.5);
  }

  #search-dialog::backdrop {
    background-color: rgba(0, 0, 0, 0.9);
  }

  /* Add styles for Pagefind UI */
  :global(.pagefind-ui) {
    --pagefind-ui-scale: 0.8;
    --pagefind-ui-primary: #034ad8;
    --pagefind-ui-text: #000000;
    --pagefind-ui-background: #ffffff;
    --pagefind-ui-border: #eeeeee;
    --pagefind-ui-tag: #eeeeee;
    --pagefind-ui-border-width: 2px;
    --pagefind-ui-border-radius: 8px;
    --pagefind-ui-image-border-radius: 8px;
    --pagefind-ui-image-box-ratio: 3 / 2;
    --pagefind-ui-font: 'Inter', system, -apple-system, '.SFNSText-Regular',
      'San Francisco', 'Roboto', 'Segoe UI', 'Helvetica Neue', 'Lucida Grande',
      sans-serif;
  }
</style>

And then added it to my custom TopBar.astro

It works - its ok for my limited UI skills, and the search is pretty cool.

I'm sure you guys can do a much better job - would love to use that when you do

noam-honig avatar Oct 25 '24 23:10 noam-honig

You can see it in action now at: https://learn.remult.dev/

noam-honig avatar Oct 28 '24 16:10 noam-honig

Looks great, thanks for sharing @noam-honig! I think we can use some of this when adding built-in search support into TutorialKit.

AriPerkkio avatar Oct 28 '24 17:10 AriPerkkio