|
4 | 4 | import { settingsStore } from '$lib/stores/settings.svelte'; |
5 | 5 | import type { SortOrder } from '$lib/types'; |
6 | 6 | import { withMenuClose } from '$lib/util'; |
| 7 | + import { gamesStore } from '$lib/stores/games.svelte'; |
7 | 8 |
|
8 | 9 | let menuToggleRef: HTMLButtonElement; |
9 | 10 | // svelte-ignore non_reactive_update |
|
84 | 85 |
|
85 | 86 | <svelte:window onclick={handleClickOutside} /> |
86 | 87 |
|
87 | | -<div class="filter-sort-container"> |
88 | | - <button |
89 | | - onclick={() => (activeMenu = !activeMenu)} |
90 | | - class="menu-toggle" |
91 | | - class:active={activeMenu} |
92 | | - bind:this={menuToggleRef} |
93 | | - > |
94 | | - <i class="fa-solid fa-filter"></i> |
95 | | - Filter & Sort |
96 | | - </button> |
97 | | - |
98 | | - {#if activeMenu} |
99 | | - <div |
100 | | - class="secondary-menu" |
101 | | - in:fly={{ y: -10, duration: 200 }} |
102 | | - bind:this={filterSortMenuRef} |
| 88 | +<div class="controls-container"> |
| 89 | + <div class="search-wrapper"> |
| 90 | + <i class="fa-solid fa-search"></i> |
| 91 | + <input |
| 92 | + id="game-search-input" |
| 93 | + type="text" |
| 94 | + placeholder="Search..." |
| 95 | + bind:value={gamesStore.searchQuery} |
| 96 | + /> |
| 97 | + </div> |
| 98 | + <div class="filter-sort-container"> |
| 99 | + <button |
| 100 | + onclick={() => (activeMenu = !activeMenu)} |
| 101 | + class="menu-toggle" |
| 102 | + class:active={activeMenu} |
| 103 | + bind:this={menuToggleRef} |
103 | 104 | > |
104 | | - <h3>Sort By</h3> |
105 | | - <div class="menu-item-with-submenu"> |
106 | | - <button |
107 | | - onclick={() => (showSortMenu = !showSortMenu)} |
108 | | - class="menu-item sort-menu-item-toggle" |
109 | | - > |
110 | | - <i class="fa-solid fa-arrow-down-short-wide"></i> |
111 | | - {currentSortOption.charAt(0).toUpperCase() + |
112 | | - currentSortOption.slice(1).replace('_', ' ')} |
113 | | - <i class="fa-solid fa-chevron-right chevron"></i> |
114 | | - </button> |
115 | | - |
116 | | - {#if showSortMenu} |
117 | | - <div |
118 | | - class="sort-submenu secondary-menu" |
119 | | - in:fly={{ x: 10, duration: 200 }} |
| 105 | + <i class="fa-solid fa-filter"></i> |
| 106 | + Filter & Sort |
| 107 | + </button> |
| 108 | + |
| 109 | + {#if activeMenu} |
| 110 | + <div |
| 111 | + class="secondary-menu" |
| 112 | + in:fly={{ y: -10, duration: 200 }} |
| 113 | + bind:this={filterSortMenuRef} |
| 114 | + > |
| 115 | + <h3>Sort By</h3> |
| 116 | + <div class="menu-item-with-submenu"> |
| 117 | + <button |
| 118 | + onclick={() => (showSortMenu = !showSortMenu)} |
| 119 | + class="menu-item sort-menu-item-toggle" |
120 | 120 | > |
121 | | - <button |
122 | | - onclick={withMenuClose( |
123 | | - () => setSortOrder('title'), |
124 | | - () => (showSortMenu = false), |
125 | | - )} |
126 | | - class="menu-item" |
127 | | - class:active={currentSortOption === 'title'} |
128 | | - > |
129 | | - Title |
130 | | - </button> |
131 | | - <button |
132 | | - onclick={withMenuClose( |
133 | | - () => setSortOrder('last_played'), |
134 | | - () => (showSortMenu = false), |
135 | | - )} |
136 | | - class="menu-item" |
137 | | - class:active={currentSortOption === 'last_played'} |
138 | | - > |
139 | | - Last Played |
140 | | - </button> |
141 | | - <button |
142 | | - onclick={withMenuClose( |
143 | | - () => setSortOrder('playtime'), |
144 | | - () => (showSortMenu = false), |
145 | | - )} |
146 | | - class="menu-item" |
147 | | - class:active={currentSortOption === 'playtime'} |
| 121 | + <i class="fa-solid fa-arrow-down-short-wide"></i> |
| 122 | + {currentSortOption.charAt(0).toUpperCase() + |
| 123 | + currentSortOption.slice(1).replace('_', ' ')} |
| 124 | + <i class="fa-solid fa-chevron-right chevron"></i> |
| 125 | + </button> |
| 126 | + |
| 127 | + {#if showSortMenu} |
| 128 | + <div |
| 129 | + class="sort-submenu secondary-menu" |
| 130 | + in:fly={{ x: 10, duration: 200 }} |
148 | 131 | > |
149 | | - Playtime |
150 | | - </button> |
151 | | - </div> |
152 | | - {/if} |
153 | | - </div> |
| 132 | + <button |
| 133 | + onclick={withMenuClose( |
| 134 | + () => setSortOrder('title'), |
| 135 | + () => (showSortMenu = false), |
| 136 | + )} |
| 137 | + class="menu-item" |
| 138 | + class:active={currentSortOption === 'title'} |
| 139 | + > |
| 140 | + Title |
| 141 | + </button> |
| 142 | + <button |
| 143 | + onclick={withMenuClose( |
| 144 | + () => setSortOrder('last_played'), |
| 145 | + () => (showSortMenu = false), |
| 146 | + )} |
| 147 | + class="menu-item" |
| 148 | + class:active={currentSortOption === 'last_played'} |
| 149 | + > |
| 150 | + Last Played |
| 151 | + </button> |
| 152 | + <button |
| 153 | + onclick={withMenuClose( |
| 154 | + () => setSortOrder('playtime'), |
| 155 | + () => (showSortMenu = false), |
| 156 | + )} |
| 157 | + class="menu-item" |
| 158 | + class:active={currentSortOption === 'playtime'} |
| 159 | + > |
| 160 | + Playtime |
| 161 | + </button> |
| 162 | + </div> |
| 163 | + {/if} |
| 164 | + </div> |
| 165 | + |
| 166 | + <div class="menu-divider"></div> |
154 | 167 |
|
155 | | - <div class="menu-divider"></div> |
156 | | - |
157 | | - <h3>Filter By</h3> |
158 | | - <div class="menu-item-with-submenu"> |
159 | | - <button |
160 | | - onclick={() => (showStatusMenu = !showStatusMenu)} |
161 | | - class="menu-item status-menu-item-toggle" |
162 | | - > |
163 | | - <i class="fa-solid fa-tags"></i> |
164 | | - Status |
165 | | - <i class="fa-solid fa-chevron-right chevron"></i> |
166 | | - </button> |
167 | | - |
168 | | - {#if showStatusMenu} |
169 | | - <div |
170 | | - class="status-submenu secondary-menu" |
171 | | - in:fly={{ x: 10, duration: 200 }} |
| 168 | + <h3>Filter By</h3> |
| 169 | + <div class="menu-item-with-submenu"> |
| 170 | + <button |
| 171 | + onclick={() => (showStatusMenu = !showStatusMenu)} |
| 172 | + class="menu-item status-menu-item-toggle" |
172 | 173 | > |
173 | | - <StatusSelector |
174 | | - categories={settingsStore.selectedCategories} |
175 | | - {toggleStatus} |
176 | | - {clearStatuses} |
177 | | - showUncategorized |
178 | | - /> |
179 | | - </div> |
180 | | - {/if} |
| 174 | + <i class="fa-solid fa-tags"></i> |
| 175 | + Status |
| 176 | + <i class="fa-solid fa-chevron-right chevron"></i> |
| 177 | + </button> |
| 178 | + |
| 179 | + {#if showStatusMenu} |
| 180 | + <div |
| 181 | + class="status-submenu secondary-menu" |
| 182 | + in:fly={{ x: 10, duration: 200 }} |
| 183 | + > |
| 184 | + <StatusSelector |
| 185 | + categories={settingsStore.selectedCategories} |
| 186 | + {toggleStatus} |
| 187 | + {clearStatuses} |
| 188 | + showUncategorized |
| 189 | + /> |
| 190 | + </div> |
| 191 | + {/if} |
| 192 | + </div> |
181 | 193 | </div> |
182 | | - </div> |
183 | | - {/if} |
| 194 | + {/if} |
| 195 | + </div> |
184 | 196 | </div> |
185 | 197 |
|
186 | 198 | <style> |
| 199 | + .controls-container { |
| 200 | + display: flex; |
| 201 | + align-items: center; |
| 202 | + gap: 0.5rem; |
| 203 | + } |
| 204 | +
|
| 205 | + .search-wrapper { |
| 206 | + position: relative; |
| 207 | + } |
| 208 | +
|
| 209 | + .search-wrapper i { |
| 210 | + position: absolute; |
| 211 | + left: 0.75rem; |
| 212 | + top: 50%; |
| 213 | + transform: translateY(-50%); |
| 214 | + color: var(--main-text); |
| 215 | + opacity: 0.6; |
| 216 | + pointer-events: none; |
| 217 | + } |
| 218 | +
|
| 219 | + .search-wrapper input { |
| 220 | + background: var(--accent); |
| 221 | + border: none; |
| 222 | + border-radius: var(--small-radius); |
| 223 | + padding: 0.5rem 0.75rem 0.5rem 2.25rem; |
| 224 | + font-size: 16px; |
| 225 | + color: var(--main-text); |
| 226 | + transition: all 0.3s ease; |
| 227 | + width: 180px; |
| 228 | + height: 40px; |
| 229 | + box-sizing: border-box; |
| 230 | + } |
| 231 | +
|
| 232 | + .search-wrapper input:focus { |
| 233 | + outline: 1px solid var(--secondary); |
| 234 | + background: color-mix(in srgb, var(--accent), var(--main-text) 5%); |
| 235 | + } |
| 236 | +
|
187 | 237 | .filter-sort-container { |
188 | 238 | position: relative; |
189 | 239 | display: inline-block; |
|
202 | 252 | align-items: center; |
203 | 253 | gap: 0.5rem; |
204 | 254 | white-space: nowrap; |
| 255 | + height: 40px; |
| 256 | + box-sizing: border-box; |
205 | 257 | } |
206 | 258 |
|
207 | 259 | .menu-toggle:hover { |
|
0 commit comments