SearchOverlay.svelte raw

   1  <script>
   2      import { searchActive } from './stores.js';
   3      import { createEventDispatcher, onMount, tick } from 'svelte';
   4  
   5      const dispatch = createEventDispatcher();
   6  
   7      let searchQuery = "";
   8      let inputEl;
   9  
  10      $: if ($searchActive) {
  11          tick().then(() => {
  12              if (inputEl) inputEl.focus();
  13          });
  14      }
  15  
  16      function close() {
  17          searchActive.set(false);
  18          searchQuery = "";
  19      }
  20  
  21      function handleKeydown(e) {
  22          if (e.key === 'Escape') close();
  23      }
  24  
  25      function handleSubmit() {
  26          if (searchQuery.trim()) {
  27              dispatch('search', searchQuery.trim());
  28          }
  29      }
  30  </script>
  31  
  32  {#if $searchActive}
  33      <div class="search-overlay">
  34          <div class="search-bar">
  35              <svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  36                  <circle cx="11" cy="11" r="8" />
  37                  <path d="M21 21l-4.35-4.35" />
  38              </svg>
  39              <input
  40                  bind:this={inputEl}
  41                  bind:value={searchQuery}
  42                  on:keydown={(e) => { if (e.key === 'Escape') close(); if (e.key === 'Enter') handleSubmit(); }}
  43                  type="text"
  44                  placeholder="Search notes, profiles, channels, publications..."
  45                  class="search-input"
  46              />
  47              <button class="search-close" on:click={close}>x</button>
  48          </div>
  49  
  50          {#if searchQuery.trim().length > 0}
  51              <div class="search-results-panel">
  52                  <div class="search-placeholder">
  53                      Search results will appear here.
  54                  </div>
  55              </div>
  56          {/if}
  57      </div>
  58  {/if}
  59  
  60  <style>
  61      .search-overlay {
  62          position: fixed;
  63          top: 0;
  64          left: 200px;
  65          right: 0;
  66          bottom: 0;
  67          z-index: 500;
  68          display: flex;
  69          flex-direction: column;
  70      }
  71  
  72      .search-bar {
  73          display: flex;
  74          align-items: center;
  75          gap: 0.5em;
  76          height: 3em;
  77          padding: 0 0.75em;
  78          background: var(--header-bg);
  79          border-bottom: 1px solid var(--border-color);
  80      }
  81  
  82      .search-icon {
  83          width: 1.1em;
  84          height: 1.1em;
  85          color: var(--text-muted);
  86          flex-shrink: 0;
  87      }
  88  
  89      .search-input {
  90          flex: 1;
  91          background: none;
  92          border: none;
  93          outline: none;
  94          color: var(--text-color);
  95          font-size: 0.9rem;
  96          padding: 0.4em 0;
  97      }
  98  
  99      .search-input::placeholder {
 100          color: var(--text-muted);
 101      }
 102  
 103      .search-close {
 104          background: none;
 105          border: none;
 106          color: var(--text-muted);
 107          cursor: pointer;
 108          font-size: 1.1rem;
 109          padding: 0.25em 0.4em;
 110          border-radius: 4px;
 111          transition: background 0.15s;
 112      }
 113  
 114      .search-close:hover {
 115          background: var(--button-hover-bg);
 116          color: var(--text-color);
 117      }
 118  
 119      .search-results-panel {
 120          flex: 1;
 121          background: var(--bg-color);
 122          overflow-y: auto;
 123      }
 124  
 125      .search-placeholder {
 126          text-align: center;
 127          padding: 3em 1em;
 128          color: var(--text-muted);
 129          font-size: 0.9rem;
 130      }
 131  
 132      @media (max-width: 1280px) {
 133          .search-overlay {
 134              left: 60px;
 135          }
 136      }
 137  
 138      @media (max-width: 640px) {
 139          .search-overlay {
 140              left: 0;
 141          }
 142      }
 143  </style>
 144