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